• No results found

Sun en randapparatuur

N/A
N/A
Protected

Academic year: 2021

Share "Sun en randapparatuur"

Copied!
11
0
0

Bezig met laden.... (Bekijk nu de volledige tekst)

Hele tekst

(1)

Sun en randapparatuur

Citation for published version (APA):

van Koeveringe, G. J. (1988). Sun en randapparatuur. (IPO-Rapport; Vol. 670). Instituut voor Perceptie Onderzoek (IPO).

Document status and date: Gepubliceerd: 02/09/1988

Document Version:

Uitgevers PDF, ook bekend als Version of Record

Please check the document version of this publication:

• A submitted manuscript is the version of the article upon submission and before peer-review. There can be important differences between the submitted version and the official published version of record. People interested in the research are advised to contact the author for the final version of the publication, or visit the DOI to the publisher's website.

• The final author version and the galley proof are versions of the publication after peer review.

• The final published version features the final layout of the paper including the volume, issue and page numbers.

Link to publication

General rights

Copyright and moral rights for the publications made accessible in the public portal are retained by the authors and/or other copyright owners and it is a condition of accessing publications that users recognise and abide by the legal requirements associated with these rights. • Users may download and print one copy of any publication from the public portal for the purpose of private study or research. • You may not further distribute the material or use it for any profit-making activity or commercial gain

• You may freely distribute the URL identifying the publication in the public portal.

If the publication is distributed under the terms of Article 25fa of the Dutch Copyright Act, indicated by the “Taverne” license above, please follow below link for the End User Agreement:

www.tue.nl/taverne Take down policy

If you believe that this document breaches copyright please contact us at: openaccess@tue.nl

providing details and we will investigate your claim.

(2)

Instituut voor Perceptie Onderzoek Postbus 513, 5600 MB EINDHOVEN Rapport no. 670 Sun en randapparatuur G.J. van Koeveringe GJvK/gjvk 88 02.09.1988

(3)

Sun en randapparatuur 1 Inleiding

Invoer bij een Sun werkstation vindt gewoonlijk plaats met Sun-toetsenbord en -muis. Wil men op een andere manier invoer plegen, bijvoorbeeld met een mechanische muis dan zullen er ingrepen moeten plaatsvinden.

De meest voor de hand liggende aansluiting op een Sun-werkstation om als invoerplaats te gebruiken is een seriele poort. Hiermee is kommunikatie

volgens RS232 mogelijk. In het algemeen verstuurt een randapparaat geen data volgens RS232. Er zal dus een hardware-aanpassing (interface) nodig zijn. De programmatuur die op de Sun draait leest normaal invoer van Sun-toetsen-bord en Sun-muis. We zullen moeten bewerkstelligen dat in plaats hiervan data van seriele poorten wordt gelezen. Hiervoor zijn dus software-aanpas-singen nodig.

Dit dokumentje beschrijft hard- en software aanpassingen voor het aansluiten van een Philips TTX-toetsenbord en een Genious PC-mouse. Met name de soft-ware-aanpassingen kunnen echter ook voor andere toepassingen nuttig zijn. 2 Software-aanpassingen

2.1 Ingrijpen in keyboard- en mousedrivers

In het UNIX-operating system, dat ook op de Sun draait, vindt kommunikatie met de buitenwereld plaats via de /dev directory. Elke file in deze

directory stelt een in- of uitvoerapparaat of pseudo-apparaat voor. Twee files zijn hier voor ons van belang: /dev/kbd en /dev/mouse. Bepaalde onderdelen van het operating system ("kernel"), de zogenaamde "device drivers" stellen dan een karakter van toetsenbord of muis beschikbaar.

Een mogelijkheid om van een ander apparaat te lezen is als volgt. Lokaliseer de device-driver en wijzig dit programma zodat het ook van een seriele poort kan lezen. Een read van /dev/kbd levert dan een karakter van Sun-toetsenbord ofwel ekstern toetsenbord. Beide invoerapparaten zijn gelijktijdig aktief. Deze aanpak lijkt de mooiste, omdat alle gebruikersprogramma's niet essen-tieel gewijzigd hoeven worden. De nadelen zijn echter ook niet mis:

- Wijzigen van de device-drivers vereist een zeer grondige kennis van de Sun en UNIX. De Sun-manuals zijn hierbij nauwelijks van nut. Bovendien moet de sourcefile van keyboard- en mousedriver beschikbaar ziJn.

- De seriele poorten zijn permanent gereserveerd voor ekstern toetsenbord en muis. Wil men dit voorkomen dan moeten voorzieningen worden getroffen om externe invoer buiten bedrijf te stellen via bijvoorbeeld speciale invo er-kodes.

2.2 Twee extra device-drivers

De /dev directory kan ook worden uitgebreid met twee files die het eksterne toetsenbord respektievelijk muis voorstellen. Er moeten dan twee device-drivers geschreven worden. Ingrijpen in bestaande device-drivers is niet nodig. Diverse programma's bieden de mogelijkheid bij het opstarten een ander appa-raat dan standaard als invoerappaappa-raat aan te wijzen.

Door het kommando suntools -k /dev/ttx

bijvoorbeeld wordt het apparaat "ttx" (dat is het Philips TTX-toetsenbord) als toetsenbord-invoer voor suntools gekozen. Op dezelfde manier kiest suntools -m /dev/gen

(4)

-2-soortgelijke opties.

Het bovenstaande is de werkwijze die in de Sun-manual "Writing Device

Drivers for the Sun Workstation" aangehouden wordt. In tegenstelling tot het ingrijpen in bestaande drivers verkrijgt men aldus een systeem dat "volgens de regels" werkt. Zolang men maar programmatuur draait die een keuzemoge-lijkheid biedt wat betreft de te gebruiken invoerapparatuur is deze werk-wijze een aanvaardbare oplossing.

De nadelen zijn echter:

- Sun-manuals zijn niet de beste en daarom is het schrijven van een device-driver geen sinekure.

- Het is in suntools, shelltool e.d. niet mogelijk om op elk willekeurig mo-ment van invoerapparaat te wisselen. Dit kan namelijk alleen bij het op-starten. Is men dus in suntools bezig met het TTX-toetsenbord en wenst men terug te gaan naar het Sun-toetsenbord dan is een "exit suntools'' nodig. Daarna dient suntools opnieuw opgestart te worden.

- Het verschijnen van een file in de /dev directory impliceert de aanwezig-heid van het desbetreffende apparaat. Dit wordt door "attach" en "probe" routines gekontroleerd (zie "Writing Device Drivers for the Sun

Workstation", appendix B), in het bijzonder bij een boot van het UNIX operating system. Dus als de seriele poorten vrij moeten zijn voor andere toepassingen zal een werkstation opnieuw opgestart moeten worden met een andere UNIX-kernel.

2.3 Aanpassen van applikatie-programma's

Het is niet doenlijk gebleken bovenstaande varianten te realiseren. Ondanks kontakten met de importeur van de Sun-apparatuur is de systeemprogrammatuur zo ondoorzichtig gebleven dat het niet verantwoord was hierin te gaan rom-melen.

Uiteindelijk is de volgende oplossing gekozen: Als er invoer "van buiten'' nodig is dient een applikatieprogramma eksplisiet van een seriele poort te lezen en het benodigde interface-werk ("device-driving") zelf te doen. In de taal C moet een read als argument een file-descriptor (0, 1, 2, ... ) hebben. 0, 1 en 2 zijn standaard in/outputfiles, 3 en hoger zijn te kiezen. Een vrije fd wordt aan een seriele poort gekoppeld als volgt:

fd = open("/dev/ttya", O_RDONLY)

Dit is voor poort a; poort b heet /dev/ttyb. O_RDONLY betekent lezen (in-voer). Als fd na afloop de wwarde -1 heeft is het openen mislukt. Dit is bijvoorbeeld het geval als de poort al in gebruik is zoals voor een login-proces ten behoeve van een terminal. Zie verder /etc/ttys ("UNIX Interface Reference Manual", blz 617).

Bij suksesvol openen (fd => 3) moet er nog een ioctl (I/O control) uitge-voerd worden. Deklareer daartoe een structure van het type sgttyb, zeg info, en ken daaraan de volgende waarden toe:

info.sg_ispeed = B1200; info.sg_ospeed = B1200; info.sg_erase = 0;

info.sg_kill = O;

info.sg_flags = RAW;

voor de Genious mouse en info.sg_ispeed = B9600; info.sg_ospeed = B9600; info.sg_erase = O;

info.sg_kill = 0;

(5)

voor het TTX-toetsenbord.

De verschillende elementen van de sgttyb structure staan beschreven in tty ( 4) ( "UNIX Interface Reference Manual", blz. 4 95) . Met name ispeed, ospeed en flags zijn van belang. De tags ispeed en ospeed bepalen de bit-snelheid (1200 baud bij Genious mouse en 9600 baud bij TTX-toetsenbord). De toekenning info.sg_flags = RAW stelt de interface op "ruwe" verwerking in: elk gelezen byte komt meteen beschikbaar als het gelezen is. Er worden dom -weg 8 bits zonder verdere bewerkingen doorgegeven.

Voor "gewone" C-programma's, die volgens het "wait-for-input" principe wer-ken, is hiermee de kous af. Na ontvangst van een byte van buiten kan deze

geinterpreteerd worden met vertaaltabellen etc.

Programma's die in de SunView omgeving draaien werken echter volgens het notifier-principe. Dit wordt uitgelegd in de "SunView Programmer's Guide"

(blz. 20).

In het kort komt het erop neer dat alleen de notifier invoer leest. Het ge-bruikersprogramma verkeert in essentie in een eindeloze lus ("window_main_ loop", zie "SunView Programmer's Guide", blz. 34) die van tijd tot tijd door de notifier wordt onderbroken als er een "event'' aan de hand is.

Standaard events zijn bijvoorbeeld muisbeweging, toetsenbordaanslag, cursor verlaat window, funktietoets ingedrukt. De moeilijkheid bestaat er nu uit de verzameling events uit te breiden met gebeurtenissen als: Genious mouse be-weegt, shift op TTX ingedrukt etc.

Het blijkt dat er onder de enorme hoeveelheid procedures in SunView er enke-le geschikt zijn om invoer van buiten te enke-lezen.

De funktie

notify_set_input_func(client, input_func, fd)

maakt het mogelijk een invoerapparaat, gekoppeld aan fd, te registreren bij de notifier (details zie "SunView Programmer's Guide", blz. 252). Als het apparaat invoer aanbiedt zal de notifier hierop reageren door de input func, geschreven door de gebruiker, aan te roepen.

In input_func moeten dan events gefabriceerd worden door de gebruiker, die met de funktie

win_post_event(client, event, when_hint)

"op de bus" gedaan worden. Win_post_event staat beschreven op blz. 25 van de "SunView System Programmer's Guide". Client en when_hint zijn details; event dient men in te vullen volgens de regels in hoofdstuk 6 van de "SunView Programmer's Guide".

Op het ontvangen van het event reageert de notifier vervolgens met het aan-roepen van een event_func, geschreven door de gebruiker. Dit is analoog aan hetgeen in hoofdstuk 6 van de "SunView Programmer's Guide" met standaard events gebeurt. De event_func dient vooraf nog geregistreerd te worden bij de notifier met de funktie

win_register(client, pw, event func, destroy_func, flags).

Zie hiervoor blz. 21 van de "SunView System Programmer's Guide".

Bovenstaand gebeuren lijkt nodeloos ingewikkeld, maar biedt het voordeel dat

het "low-level" werk, het feitelijke "device-driving", gescheiden is van de event-struktuur, een van de aantrekkelijke kanten van de SunView program -meeromgeving. De input_funcs kan men per apparaat schrijven en in een bib-liotheek opnemen voor later gebruik. De event funcs daarentegen worden per toepassing geschreven.

(6)

-4-2.4.1 gmmuis.c

Het programma grnmuis.c kreeert een window ter grootte van het scherm met daarin een canvas. Poort a of b (in te geven door de gebruiker) wordt ge-opend en ingesteld volgens het voorgaande. Het inputmask van het canvas is zodanig ingesteld dat maar 4 events worden doorgelaten: MOVE, L, Men R. Dit zijn eigengemaakte eventcodes (1001 t/m 1004). De input_func "grn_mouse" en

de event_func "mijnproc" worden bij de notifier geregistreerd.

De globale variabelen hor, verten knopoud houden respektievelijk kursorpo-sitie en knoptoestand van de muis bij.

De funktie gm_mouse zet gelezen bytes van de muis om in events. De bytes die

door de muis verstuurd worden staan beschreven in "Optical Mouse Technical Manual". Dit is het manual van de Sun-muis; het protocol is precies hetzelde als van de Genious mouse.

Als er een knopje op de muis van toestand verandert worden er korresponderde events gemaakt. De macro's event_set_id, event_set_up en event_set_down staan beschreven in hoofdstuk 6 van de "SunView Programmer's Guide". De funktie

win_setmouseposition(windowfd, x, y)

laat de kursor daadwerkelijk over het scherm bewegen en genereert bovendien standaard events als LOC_MOVE en dergelijke (zie "SunView System

Programmer's Guide", blz. 41). Deze worden echter niet doorgelaten door het inputmask van ons canvas. We genereren daarom zelf nog een MOVE-event.

Mijnproc zet events om in eenvoudige akties. Bij het bewegen van de muis worden er bij de bewegende kursor koordinaten afgedrukt op het scherm. In-drukken van het linker knopje veegt het scherm schoon. Het middelste knopje doet de bel weerklinken. Het rechter knopje beeindigd het programma.

Voor het TTX-toetsenbord kan een soortgelijk programma geschreven worden. 2.4.2 Andere programma's

Leespoort.c drukt bytes in hex en binair af die door een seriele poort gele-zen zijn. Poortnummer (a of b) en baudrate kunnen opgegeven worden. Het draait zonder SunView-omgeving.

3 Hardware-aspekten 3.1 Genious mouse

De Genious mouse is voorzien van een CMOS processor en kan in principe uit de RS232 poort op de Sun gevoed worden. Bij meting echter blijkt uit de

Sun-poort geen 5 Volt te komen maar iets minder. De muis weigert dan dienst. Apart voeden is noodzakelijk. Bijgevoegd is een aansluitschema.

Het aanwezige eksemplaar van de muis vertoont gebreken. Ten eerste is het aansluitsnoer vervangen. Er zat namelijk een breuk in. Ernstiger is dat de

wieltjes die in het inwendige ronddraaien vervormd zijn. Dit heeft onnauw-keurig positioneren tot gevolg.

3.2 TTX-toetsenbord

Het stageverslag van Bart Kramer beschrijft een interface die het TTL-uit-gangssignaal van het TTX-toetsenbord omzet in RS232 signalen. Deze interface is nu netjes in een kastje ondergebracht en werkt goed.

Bart heeft ook ingrepen in het TTX-toetsenbord gedaan. Shift en Select zou-den geen output produceren en daarom zijn deze parallel gezet aan niet

ge-bruikte toetsen. Het manual is op dit punt verwarrend.

Het blijkt dat Shift en Select op zichzelf geen output genereren, maar wel indien ingedrukt samen met een andere toets. Er wordt dan eerst een

(7)

status-byte verzonden, waarin een bit aangeeft of Shift of Select is ingedrukt. Daarna volgt een databyte dat een lower-case karakter voorstelt.

Bij de Select-funktie (knopje tussen de kursortoetsen) is dit meestal onge-wenst. Men kan dit wijzigen door een andere PROM te plaatsen. Minder subtiel is het doorkrassen van printsporen en solderen van draadbrugjes, zoals Bart had gedaan. Momenteel verkeert het toetsenbord weer in originele staat. De beschrijving van het statusbyte op blz. 3-11 van het TTX-manual is onjuist, dit moet als volgt zijn:

7 0

STATUS BYTE 1 ? R T C

s

M L bit 7 1 1 status byte

bit 6 ? unknown

bit 5 R repeat key active bit 4 T select key closed bit 3 C code key closed bit 2

s

shift key closed bit 1 M multiple key closure bit 0 L loek key closed

(8)

#include <stdio.h> #include <string.h> #include <sys/file.h> #include <fcntl.h> #include <sgtty.h> #include <sys/ttydev.h> #include <suntool/sunview.h> #include <suntool/canvas.h>

-6-#define HEIGHT 900 /* Hoogte scherm (pixels) #define WIDTH 1152 /* Breedte scherm (pixels) #define MOVE 1001 /* Eigengemaakte event code

#define L 1002 /* Linker muisknopje */

#define M 1003 /* Middelste muisknopje

#define R 1004 /* Rechter muisknopje

short hor, vert; unsigned char knopoud;

Notify_value gm_mouse(), mijnproc(); Pixwin *pw;

int rootfd; main(argc, argv) int argc;

char *argv [];

{ Window frame, canvas;

int framefd, poortfd; char poortnaam[20], poort; struct sgttyb info;

struct screen rootscreen; int my_client_object;

int *me= &my_client_object; if (argc == 2) poort= *argv[l];

else */ */ *! */ voor muisbeweging

printf("Aan welke poort hangt de muis (a of b) ? "); scanf("%1s", &poort);

strcpy(poortnaam, "/dev/tty"); strncat(poortnaam, &poort, 1); poortfd = open(poortnaam, O_RDONLY);

if (poortfd == -1) {perror(argv[O]); exit(l); }; info.sg_ispeed = B1200;

info.sg_ospeed = B1200; info.sg_erase = O; info.sg_kill = 0; info.sg_flags = RAW;

ioctl(poortfd, TIOCSETP, &info); /* zie tty(4) */ frame= window_create(O, FRAME,

FRAME SHOW_LABEL, FALSE,

WIN_HEIGHT, HEIGHT, WIN_WIDTH, WIDTH,

WIN_X, 0, WIN_Y, 0,

0) ;

canvas window_create(frame, CANVAS,

WIN_CONSUME_PICK EVENT, WIN_NO_EVENTS, WIN_CONSUME_KBD_EVENT, WIN_NO_EVENTS, 0);

*/

window set(canvas, WIN_CONSUME_PICK_EVENTS, MOVE, L, M, R, 0); framefd = (int) window_get(frame, WIN_FD);

win_screenget(framefd, &rootscreen);

rootfd = open(rootscreen.scr_rootname, O_RDONLY); notify_set_input_func(me, gm_mouse, poortfd); pw = (Pixwin*) window_get(canvas, WIN_PIXWIN); win register(me, pw, mijnproc, 0, PW RETAIN);

hor-= WIDTH/2; vert = HEIGHT/2; /* Cursor in midden scherm*/ knopoud = Ox87; /* Geen knopjes ingedrukt*/

window main loop(frame);

exit(O);

(9)

gm_mouse(client, fd) int *client;

int fd;

#define SYNC BYTE OxBO /* Geldig sync-byte heeft eerste bit hoog*/

#define SYNC-BYTE MASKER OxfB /* Afstrippen van de knopjestoestand (laatste drie bits) */

#define L MASKER Ox04 #define M MASKER Ox02 #define R MASKER OxOl

/* 3e bit van rechts*/ /* 2e bit van rechts*/ /* le bit van rechts*/ unsigned char bytel;

char byte2, byte3, byte4, byteS; int lknop, mknop, rknop;

struct timezone *tp, *tzp; Event event;

read(fd, &bytel, l);

if ((bytel & SYNC_BYTE_MASKER) == SYNC_BYTE) { read(fd, &byte2, l); hor= hor+ byte2;

read(fd, &byte3, l); vert - vert - byte3; read(fd, &byte4, l); hor= hor+ byte4; read(fd, &bytes, l); vert = vert - bytes; if (hor< 0) hor= O;

if (hor> WIDTH) hor - WIDTH; if (vert < 0) vert = 0;

if (vert > HEIGHT) vert - HEIGHT; event_set_x(&event, hor);

event_set_y(&event, vert);

gettimeofday(&event.ie_time, tzp); if (bytel != knopoud)

{ lknop (int) (knopoud & L_MASKER) - (int) (bytel & L_MASKER); rnknop = (int) (knopoud & M_MASKER) - (int) (bytel & M_MASKER); rknop = (int) (knopoud & R_MASKER) - (int) (bytel & R_MASKER); if (lknop == -4) {event set_id(&event, L);event set up(&event);

win__post_event(client, &event, NOTIFY_SAFE);}

if (lknop == 4) {event_set_id(&event, L);event_set_down(&event); win__post_event(client, &event, NOTIFY_SAFE) ;}

if (rnknop == -2) {event_set_id(&event, M);event_set_up(&event); win__post_event(client, &event, NOTIFY_SAFE);}

if (rnknop

-=

2) {event_set_id(&event, M);event_set_down(&event); win__post_event(client, &event, NOTIFY_SAFE);}

if (rknop == -1) {event_set_id(&event, R);event_set_up(&event); win__post_event(client, &event, NOTIFY_SAFE);}

if (rknop == 1) {event_set_id(&event, R);event_set_down(&event); win__post_event(client, &event, NOTIFY_SAFE);}

knopoud = bytel;

i f ( (byte2 != 0) 11 (byte3 != 0) 11 (byte4 ! = 0) 11 (bytes ! = 0) ) { win_setmouseposition(rootfd, hor, vert);

event_set_id(&event, MOVE); /* rest al ingevuld*/ &event, NOTIFY_SAFE);

win_post_event(client, return(NOTIFY_DONE);

else return(NOTIFY_IGNORED);

Notify_value

mijnproc(client, event, arg, when) Notify_client client;

Event *event; Notify_arg arg;

Notify_event_type when;

{ char s[20];

statie struct timeval tijdje switch (event_id(event))

{O, 5000);

case MOVE: sprintf(s, "%d, %d", event_x(event), event_y(event));

pw_text(pw, event_x(event) + 20, event_y(event), PIX_SRC, NULL, s); break;

(10)

return;

-8-pw_writebackground(pw, 0, 0, WIDTH, HEIGHT, PIX_SRC); break;

case M: if (event_is_down(event)) win_bell(rootfd, tijdje, pw); break;

case R: if (event_is_down(event)) exit(0); break;

(11)

iinclude <stdio.h> iinclude <string.h> iinclude <sys/file.h> iinclude <fcntl.h> iinclude <sgtty.h> iinclude <sys/ttydev.h> char *bin(), *malloc(); main(argc, argv)

int argc; char *argv[];

int fd, i;

char poort, poortnaam[20]; unsigned char byte;

float baudrate; double atof () ;

statie float baudtabel[] =

{0, 50, 75, 110, 134.5, 150, 200, 300, 600, 1200, 1800, 2400, 4800, 9600, 19200}; struct sgttyb info;

i f (argc -= 3)

{ poort= *argv[l];

baudrate= atof(argv[2]); else

printf ("Poort (a of b): "); scanf ("%ls", &poort); printf ("Baudrate: "); scanf ("%f", &baudrate);

strcpy(poortnaam, "/dev/tty"); strncat(poortnaam, &poort, l); fd = open(poortnaam, O_RDONLY);

i f (fd == -1) {perror(argv[0]); exit(l);}

printf("fd: %d flags: %x\n", fd, fcntl(fd, F_GETFL));

i = 0; while(baudrate != baudtabel[i]) info.sg_ispeed = i; info.sg_ospeed = i; info.sg_erase = 0; info.sg_kill = 0; info.sg_flags = RAW;

ioctl(fd, TIOCSETP, &info);

i - i+l;

/* zie tty(4) */

printf("Baudrate is %f baud\n", baudtabel[i]); while ( 1 == 1)

{ read(fd, &byte, l);

printf("%02x %s\n", byte, bin(8, byte));

char *bin(lengte, dec) /* decimaal naar binair*/ int lengte;

unsigned char dec;

{ char *woord malloc(sizeof(char)); int

for {

rest, i;

(i = l; i <= lengte; i = i + 1) rest= dec % 2; dec= dec/ 2; if (rest== 0) *(woord+ lengte

else *(woord+ lengte -*(woord+lengte) = '\0'; return (woord); - i) i) = = , 0'; , 1' ; /* zie fen tl (2) * /

Referenties

GERELATEERDE DOCUMENTEN

Wanneer men probeert om bij kleine fluctuaties in te grijpen, (door bijvoorbeeld bij een iets te lage waarde te proberen de waarde van het proces te verhogen) dan zal het middel

In de loop van de zomer zijn de delegaties van P. en D'66 opnieuw een aantal keren bijeen geweest. Kort na de verkiezingen heeft het H. gewend met het verzoek op korte

BELANGRIJKE winst aam stemmen uit het zich nu ook in partij-politiek op- zicht emanciperende katholieke volksdeel en uit de aanwas aan jonge kiezers; verlies aan de

Vandaag de dag worden ouders met hoge verwachtingen geconfronteerd: de ideale baan vinden, evenwichtig samenwonen, voorbeeldige kinderen hebben die de beste zijn

Vele vluchtelingen vonden nog geen onderdak, ten- ten blijken niet bestand tegen de stortbuien, kinderen kampen met bronchitis en longontste- king en er dreigt

Maar Kirsten leeft alleen maar door, omdat er zo goed voor haar wordt gezorgd?. Ze ligt op een speciale matras die haar houvast

Investeren in aangepast werk dus, inzetten op maat- regelen die het mogelijk maken de eigen loopbaan vorm te geven (het aanmoedigen van tijdskrediet, landingsbanen), het

De vraag van het begin – ‘wat moeten wij doen?’ – vat ik in dit artikel op als het in- nerlijke moeten dat patiënten en hun naas- ten kunnen ervaren in een grenssituatie,