home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / oper_sys / emerald / emrldsys.lha / Kernel / X / XInterface.c
Encoding:
C/C++ Source or Header  |  1990-08-17  |  10.9 KB  |  455 lines

  1. #ifdef INCLUDE_X_WINDOWS
  2. #include "Kernel/h/system.h"
  3. #include "Kernel/h/macros.h"
  4. #include "Kernel/h/assert.h"
  5.  
  6. #include <sys/file.h>
  7. #include <sys/time.h>
  8. #include <errno.h>
  9.  
  10. #include "Kernel/h/stdTypes.h"
  11. #include "Kernel/h/ecTypes.h"
  12. #include "Kernel/h/emTypes.h"
  13. #include "Kernel/h/builtins.h"
  14. #include "Kernel/h/kmdTypes.h"
  15. #include "Kernel/h/emeraldTypes.h"
  16. #include "Kernel/h/kEvents.h"
  17. #include "Kernel/h/sigio.h"
  18. #undef True
  19. #include <X11/Xlib.h>
  20. #include <X11/Xutil.h>
  21.  
  22. static Display *display;
  23. static EmBitChunk *waitingEvent;
  24. static SSPtr   waitingProcess;
  25. extern SSPtr   preemptRunning();
  26. XWMHints xwmh={
  27.     (InputHint|StateHint),
  28.     False,
  29.     NormalState,
  30.     0,
  31.     0,
  32.     0,0,
  33.     0,
  34.     0
  35.   };
  36.  
  37. /* shumei -s */
  38. static  unsigned long black,white;
  39. /* shumei -e */
  40.  
  41. int XSIGIOOccurred(), XSockDead(), XEventHandler();
  42.  
  43. void *XCreateDisplay(es)
  44. EmString *es;
  45. {
  46.   char *s;
  47.  
  48.   s = malloc(es->sizeInBytes + 1);
  49.   (void) strncpy(s, es->data, es->sizeInBytes);
  50.   display = XOpenDisplay(s);
  51.   if (display == NULL) {
  52.     KMDTrace("X", 1, "Cannot initialize display\n");
  53.     return;
  54.   } 
  55.   if (fcntl(display->fd, F_SETFL, FASYNC ) < 0) {
  56.     perror("XCreateDisplay: first fcntl");
  57.   };
  58.   if (fcntl(display->fd, F_SETOWN, getpid()) < 0) {
  59.     perror("XCreateDisplay: second fcntl");
  60.   };
  61.  
  62.   SISetSockHandler(display->fd, SIREAD, (SIHandlerPtr) XSIGIOOccurred);
  63.   SISetSockHandler(display->fd, SIEXCEPT, (SIHandlerPtr) XSockDead);
  64.   SIEnsureSIGIO();
  65.  
  66.   black = BlackPixel(display,DefaultScreen(display));
  67.   white = WhitePixel(display,DefaultScreen(display));
  68. }
  69.  
  70. int XSIGIOOccurred(fKind, fSock)
  71. int     fKind, fSock;
  72. {
  73.   SIRemoveSockHandler(fSock, SIREAD);
  74.   HoldSigs();
  75.   QueueTask(XEventHandler, (char *) fSock);
  76.   ReleaseSigs();
  77.   return 0; /* procedure ought to be void */
  78. }
  79.  
  80.  
  81. /**********************************************************************/
  82. int XSockDead(fSock)
  83. int             fSock;
  84. {
  85.     KMDTrace("X", 3, "Socket #%d died.\n", fSock);
  86.     display = NULL;
  87. }
  88.  
  89. /**********************************************************************/
  90. /*      XEventHandler
  91. /**********************************************************************/
  92. int XEventHandler(fSock)
  93. int              fSock;
  94. /* The socket has become available for input, read the event */
  95. {
  96.     SSPtr                           theProcess;
  97.  
  98.     KMDTrace("X", 3, "Events on socket %d\n", fSock);
  99.  
  100.     /* Attempt to read */
  101.     if (XPending(display) <= 0) {
  102.       /* Must have been XError events */
  103.       KMDTrace("X", 5, "XNextEvent found no events\n");
  104.       SISetSockHandler(display->fd, SIREAD, (SIHandlerPtr) XSIGIOOccurred);
  105.       return;
  106.     }
  107.     XNextEvent(display, (XEvent *)waitingEvent->data);
  108.     KMDTrace("X", 5, "XNextEvent returned\n");
  109.     KMDTrace("X", 5, "event = (%d %d %d %d %d)\n", 
  110.       *(0 + (int *)waitingEvent->data),
  111.       *(1 + (int *)waitingEvent->data),
  112.       *(2 + (int *)waitingEvent->data),
  113.       *(3 + (int *)waitingEvent->data),
  114.       *(4 + (int *)waitingEvent->data));
  115.     theProcess                  = waitingProcess;
  116.     theProcess->resultBrand     = DataBrand;
  117.     theProcess->regs.arg1       = 1;
  118.     waitingProcess              = (SSPtr) NULL;
  119.     waitingEvent                = NULL;
  120.     schedule(theProcess);
  121. }
  122.  
  123. /**********************************************************************/
  124. /*      EMXReadEvent                                                    */
  125. /**********************************************************************/
  126.  
  127. /*Kernel Call */
  128. void EMXReadEvent(fEvent)
  129. GODP            fEvent;
  130. {
  131.   int                             sock, i, count, length;
  132.   EmBitChunk                     *event;
  133.   SSPtr                           theProcess;
  134.   AbConPtr                        eventAbCon, OIDOIDOIDToAbCon();
  135.   
  136.   theProcess = preemptRunning();
  137.  
  138.   KMDTrace("X", 4, "EMXReadEvent in %s\n", PPSSPlace(theProcess));
  139.  
  140.   if (fEvent == (GODP) EMNIL) {
  141.     KMDTrace("X", 2, "Event is NIL in EMXReadEvent.\n");
  142.     fail(theProcess);
  143.     return;
  144.   }
  145.  
  146.   if (!fEvent->tag.isResident) {
  147.     KMDTrace("X", 2, "Event is non-resident.\n");
  148.     eventAbCon = OIDOIDOIDToAbCon(
  149.       fEvent->dataPtr->myCodePtr->ownAbstractType,
  150.       OIDOfBuiltin(B_INSTAT, ANYINDEX),
  151.       fEvent->dataPtr->myCodePtr->ownOID);
  152.     unavail(theProcess, fEvent, eventAbCon);
  153.     return;
  154.   }
  155.  
  156.   if (fEvent->tag.global) {
  157.     event = (EmBitChunk *) fEvent->dataPtr;
  158.   } else event = (EmBitChunk *) fEvent;
  159.  
  160.   /* Check for other readers */
  161.   if (NonNULL(waitingProcess)) {
  162.     KMDTrace("X", 2, "Read socket busy.\n");
  163.     fail(theProcess);
  164.     return;
  165.   }
  166.   
  167.   /* Check the size of the bitchunk */
  168.   if (event->sizeInBytes < sizeof(XEvent)) {
  169.     KMDTrace("X", 2, "Read attempt with too small BitChunk %d should be %d.\n",
  170.       event->sizeInBytes, sizeof(XEvent));
  171.     fail(theProcess);
  172.     return;
  173.   }
  174.     
  175.   /* Check for a display */
  176.   if (!display) {
  177.     KMDTrace("X", 1, "Read attempt with no display (= nil).\n");
  178.     fail(theProcess);
  179.     return;
  180.   }
  181.  
  182.   /* Attempt to read */
  183.   if (XPending(display) <= 0) {
  184.     KMDTrace("X", 3, "EMXReadEvent blocking %s at %s\n",
  185.       PPPOID(theProcess->processOID), PPSSPlace(theProcess));
  186.     waitingEvent         = event;
  187.     waitingProcess       = theProcess;
  188.     theProcess->status.rs   = SSReadIOWait;
  189.     KMDTrace("LineNumber", 3, "%s blocking on X read in %s\n",
  190.       PPPOID(theProcess->processOID), PPSSPlace(theProcess));
  191.     SISetSockHandler(display->fd, SIREAD, (SIHandlerPtr) XSIGIOOccurred);
  192.     return;
  193.   }
  194.   XNextEvent(display, (XEvent *)event->data);
  195.   theProcess->resultBrand = DataBrand;
  196.   theProcess->regs.arg1 = 0;
  197.   schedule(theProcess);
  198. }
  199.  
  200. /* Change from here on */
  201.  
  202. int EMXCreateWindow(pos, size, name)
  203. int pos, size;
  204. EmString *name;
  205. {
  206.   Window window;
  207.   XSizeHints xsh; 
  208.   char *myname;
  209.   myname = calloc(1, name->sizeInBytes+1);
  210.   strncpy(myname, name->data, name->sizeInBytes);
  211.  
  212.   if (display == NULL) {
  213.     KMDTrace("X", 1, "Create window called with no display\n");
  214.     return(-1);
  215.   }
  216.   xsh.x = pos >> 16;
  217.   xsh.y = pos & 0xffff;
  218.   xsh.width = size >> 16;
  219.   xsh.height = size & 0xffff;
  220.   xsh.flags = (USPosition|USSize); 
  221.  
  222.   KMDTrace("X", 3, "Create window at (%d, %d) size (%d, %d)\n",
  223.     xsh.x, xsh.y, xsh.width, xsh.height);
  224.   window = XCreateSimpleWindow(display, DefaultRootWindow(display), xsh.x, xsh.y, xsh.width, xsh.height, 1,black,white); 
  225.   KMDTrace("X", 3, "XCreateWindow returns %d\n", window);
  226. /* norm, i am not sure the parameter: None should be argv, 0 should be argc 
  227.    but it works for right now */
  228.   XSetStandardProperties(display,window,myname,myname,None,NULL,0,&xsh);
  229. /*
  230.   XSetWHints(display,window,&xwhm);
  231. */
  232.   XMapWindow(display,window);
  233.   return(window);
  234. }
  235.  
  236.  
  237. /*-----------------------------------------------------------------------
  238.  * FUCTION : EMXSelectInput
  239.  *           To requests X server report the events associated with the event
  240.  *           Mask
  241.  * Jyhlin Chang Jul 15,1988
  242.  *-----------------------------------------------------------------------*/
  243.  
  244. void EMXSelectInput(w, event_mask)
  245.   Window w;
  246.   unsigned long event_mask;
  247. {
  248.   XSelectInput(display, w, event_mask);
  249.  
  250. }/*EMXSelectInput*/
  251.  
  252.  
  253.  
  254. GC EMXInitGc(win)
  255. Window win;
  256. {
  257.   XGCValues gcvalues;
  258.   GC gc;
  259.   char *font;
  260.   XFontStruct *fontstruct;
  261.  
  262.   gcvalues.foreground = black; 
  263.   gcvalues.background = white; 
  264.   gcvalues.line_width =  0;
  265.   font = "9x15";
  266.   if ((fontstruct = XLoadQueryFont(display , font)) == NULL) {
  267.     fprintf(stderr, "%s: display %s doesn't know font %s\n",
  268.         "ha,wrong", DisplayString(display), font);
  269.     exit(1);
  270.     }
  271.   gcvalues.font = fontstruct->fid;
  272.   gc = XCreateGC(display,win,(GCLineWidth|GCFont|GCForeground|GCBackground),
  273.        &gcvalues);
  274.   return (gc);
  275. }
  276.  
  277. EMXSetWidth(gc, win,width )
  278. GC gc;
  279. Window  win;
  280. int width;
  281. {
  282.   XGCValues gcvalues;
  283.  
  284.   gcvalues.line_width =  width;
  285.   XChangeGC(display,gc,GCLineWidth,&gcvalues);
  286.  
  287. EMXSetFont(gc,win,font)
  288. GC gc;
  289. Window win;
  290. EmString  *font; 
  291. {
  292.   XGCValues gcv;
  293.   XFontStruct *fontstruct;
  294.   char *blotto = calloc(1, font->sizeInBytes + 1);
  295.   strncpy(blotto, font->data, font->sizeInBytes); 
  296.     if ((fontstruct = XLoadQueryFont(display , blotto)) == NULL) {
  297.     fprintf(stderr, "%s: display %s doesn't know font %s\n",
  298.         "ha,wrong", DisplayString(display), blotto);
  299.     exit(1);
  300.     }
  301.     gcv.font = fontstruct->fid;
  302. /*
  303.     gcv.foreground = black;
  304.     gcv.background = white;
  305.     gc = XCreateGC(display,win,(GCFont|GCForeground|GCBackground), &gcv);
  306. */
  307.     XChangeGC(display,gc,GCFont, &gcv);
  308. }
  309.  
  310. void EMXLine(win, p1, p2,gc)
  311. Window win;
  312. int  p1, p2;
  313. GC gc;
  314. {
  315.   int x1, y1, x2, y2;
  316.   x1 = p1 >> 16;
  317.   y1 = p1 & 0xffff;
  318.   x2 = p2 >> 16;
  319.   y2 = p2 & 0xffff;
  320.   KMDTrace("X", 3, "X Line on window %d from (%d, %d) to (%d, %d)\n",
  321.     win, x1, y1, x2, y2);
  322.   XDrawLine(display,win,gc,x1, y1, x2, y2);
  323.   KMDTrace("X", 3, "XLine done\n");
  324. }
  325.  
  326. void EMXString(win, string, x, y, gc )
  327. Window win;
  328. EmString *string; 
  329. int x,y;
  330. GC gc;
  331. {
  332.     KMDTrace("X", 3, "XString begin %s\n",string);
  333.     XDrawString(display, win, gc, x, y, string->data, string->sizeInBytes);
  334.     XFlush(display);
  335.     KMDTrace("X", 3, "XString done\n");
  336. }
  337. void EMXConfigureWindow(win, p, s)
  338. int win, p, s;
  339. {
  340.   int x, y, w, h;
  341.   x = p >> 16;
  342.   y = p & 0xffff;
  343.   w = s >> 16;
  344.   h = s & 0xffff;
  345.   KMDTrace("X", 3, "X ConfigureWindow on window %d (%d, %d) (%d, %d)\n",
  346.     win, x, y, w, h);
  347.   XConfigureWindow(win, x, y, w, h);
  348.   KMDTrace("X", 3, "XConfigureWindow done\n");
  349. }
  350.  
  351. void EMXFlush()
  352. {
  353.   KMDTrace("X", 3, "X Flush called\n");
  354.   XFlush(display);
  355.   KMDTrace("X", 3, "X Flush done\n");
  356. }
  357.  
  358. int sync_write(fd, b, l)
  359. int fd, l;
  360. char *b;
  361. {
  362.   int write_stat, nTimes = 0;
  363.   while ((write_stat = write(fd, b, l)) < 0 && errno == EWOULDBLOCK) {
  364.     nTimes ++;
  365.     /* wait a while */
  366.   }
  367.   if (nTimes > 0) KMDTrace("X", 1, "Sync_write had to wait %d times\n");
  368.   return(write_stat);
  369. }
  370.  
  371. int sync_writev(fd, iov, l)
  372. int fd, l;
  373. struct iovec *iov;
  374. {
  375.   int write_stat, nTimes = 0;
  376.   while ((write_stat = write(fd, iov, l)) < 0 && errno == EWOULDBLOCK) {
  377.     nTimes ++;
  378.     /* wait a while */
  379.   }
  380.   if (nTimes > 0) KMDTrace("X", 1, "Sync_writev had to wait %d times\n");
  381.   return(write_stat);
  382. }
  383.  
  384. EMXRaiseWindow(w) 
  385. Window w;
  386. {
  387.   XRaiseWindow(display,w);
  388. }
  389.  
  390.  
  391. EMXLowerWindow(w)
  392. Window w;
  393. {
  394.   XLowerWindow(display,w);
  395. }
  396.  
  397.  
  398. EMXUnmapWindow(w)
  399. Window w;
  400. {
  401.   XUnmapWindow(display,w);
  402. }
  403.  
  404. EMXResizeWindow(w,x,y)
  405. Window w;
  406. int x,y;
  407. {
  408.   XResizeWindow(display,w,x,y);
  409. }
  410.  
  411. EMXMoveWindow(w,x,y)
  412. Window w;
  413. int x,y;
  414. {
  415.   XMoveWindow(display,w,x,y);
  416. }
  417.  
  418. EMXCloseWindow(w)
  419. Window w;
  420. {
  421.   XDestroyWindow(display,w);
  422. }
  423.  
  424. void XInit()
  425. {
  426.   EmString es;
  427.   DebugMsg(1, "XInit\n");
  428.   es.sizeInBytes = 0;
  429.   XCreateDisplay(&es);
  430.   KMDSetTrace(X);
  431.   KMDSetProcedure(EMXInitGc);
  432.   KMDSetProcedure(EMXSetFont);
  433.   KMDSetProcedure(EMXSetWidth);
  434.   KMDSetProcedure(EMXLine);
  435.   KMDSetProcedure(EMXString);
  436.   KMDSetProcedure(EMXCreateWindow);
  437.   KMDSetProcedure(EMXUnmapWindow);
  438.   KMDSetProcedure(EMXCloseWindow);
  439.   KMDSetProcedure(EMXMoveWindow);
  440.   KMDSetProcedure(EMXResizeWindow);
  441.   KMDSetProcedure(EMXConfigureWindow);
  442.   KMDSetProcedure(EMXRaiseWindow);
  443.   KMDSetProcedure(EMXLowerWindow);
  444.   KMDSetProcedure(EMXFlush);
  445.   KMDSetProcedure(EMXReadEvent);
  446.  
  447.   KMDSetProcedure(EMXSelectInput);
  448. }
  449.  
  450. #else
  451. void XInit()
  452. {}
  453. #endif
  454.