/* X11suHelper.c -- helper process for magic on X windows which signals the * parent (magic) whenever there is input available. */ #include #include #include /* * Portability stuff */ #if (defined(MIPSEB) && defined(SYSTYPE_BSD43)) || ibm032 # define SIG_RETURNS_INT #endif /* Some machines have signal handlers returning an int, while other machines * have it returning a void. If you have a machine that requires ints put * it in the list of machines in misc/magic.h. */ #ifdef SIG_RETURNS_INT #define sigRetVal int #else #define sigRetVal void #endif /* * Main program */ int readPipe,writePipe; /* pipe file descriptor to magic process */ int parentID; /* process id of parent */ Display *grXdpy; KeySym UpArrow, DnArrow, LtArrow, RtArrow; /* keysym values */ enum { UP_ARROW = 'P'-64, DN_ARROW = 'N'-64, LT_ARROW = 'B'-64, RT_ARROW = 'F'-64 }; sigRetVal MapWindow(); main (argc, argv) int argc; char **argv; { XEvent xevent; #ifdef macII set42sig(); #endif if (argc <= 1) { fprintf(stderr, "%s: expecting two file-descriptor numbers.\n\ \t(This program should be run only by magic itself.)\n", argv[0]); exit(1); } sscanf(argv[1], "%d %d", &readPipe,&writePipe); grXdpy = XOpenDisplay(0); if (grXdpy == (Display *) 0) { fprintf(stderr,"%s: XOpenDisplay failed.\n", argv[0]); exit(1); } UpArrow= XStringToKeysym ("Up"); DnArrow= XStringToKeysym ("Down"); LtArrow= XStringToKeysym ("Left"); RtArrow= XStringToKeysym ("Right"); parentID = getppid(); signal(SIGINT,SIG_IGN); signal(SIGQUIT,SIG_IGN); signal(SIGTERM,MapWindow); #ifdef SIGTSTP signal(SIGTSTP,SIG_IGN); #endif #ifdef SIGCONT signal(SIGCONT,SIG_IGN); #endif while (1) { XNextEvent(grXdpy, &xevent); if (isString(xevent) ==0) { write(writePipe, &xevent, sizeof(XEvent)); #ifndef USE_IO_PROBE kill(parentID, SIGIO); #endif } } } isString (event) XEvent event; { if (event.type == KeyPress) { XKeyPressedEvent *KeyPressedEvent = (XKeyPressedEvent *) &event; char inChar[10],c,*p; int nbytes; KeySym keysym; nbytes = XLookupString(KeyPressedEvent,inChar,sizeof(inChar), &keysym,NULL); if (keysym == UpArrow || keysym == DnArrow || keysym == LtArrow || keysym == RtArrow) { if (keysym == UpArrow) c = UP_ARROW; else if (keysym == DnArrow) c = DN_ARROW; else if (keysym == LtArrow) c = LT_ARROW; else if (keysym == RtArrow) c = RT_ARROW; write (writePipe, &event, sizeof(XEvent)); write (writePipe, &c, sizeof(char)); } else { p = inChar; while (nbytes--) { if ( (c = *p++) == 3) { kill(parentID, SIGINT); } else { write(writePipe, &event, sizeof(XEvent)); write(writePipe, &c, sizeof(char)); #ifndef USE_IO_PROBE kill(parentID, SIGIO); #endif } } } return 1; } else return 0; } sigRetVal MapWindow() { Window window; if ( read(readPipe, (char *)&window, sizeof(Window)) == sizeof(Window)) { XSelectInput(grXdpy, window, KeyPressMask|ButtonPressMask| ButtonReleaseMask|ExposureMask| StructureNotifyMask| OwnerGrabButtonMask); XSync(grXdpy,1); #ifdef SYSV /* Note: HAS NOT BEEN TESTED. Just a "good guess" based upon some mods * to a similar driver which was tested. 1/19/89, Livermore. */ signal(SIGTERM, MapWindow); #endif } else fprintf(stderr,"xhelper: read on pipe failed\n"); }