home *** CD-ROM | disk | FTP | other *** search
/ PC Shareware 1999 March / PCShareware-3-99.iso / IMPLE / DJGPP.RAR / DJGPP2 / XLIB-SR0.ZIP / SRC / XLIBEMU / INTERNAL.C < prev    next >
C/C++ Source or Header  |  1994-02-20  |  13KB  |  590 lines

  1. /* $Id: internal.c 1.4 1994/02/20 19:49:38 ulrich Exp $ */
  2. /* 
  3.  * internal.c
  4.  *
  5.  * Internal window handling functions for Xlibemu.
  6.  */
  7.  
  8. #include "Xlibemu.h"
  9. #include <stdio.h>
  10.  
  11. extern GrContext _WScreenContext;
  12.  
  13. void
  14. _WDummyFilledBox ()
  15. {
  16. }
  17.  
  18. void
  19. _WContextFilledBox (int x1, int y1, int x2, int y2, GrContext *src)
  20. {
  21.   int x, y, width, height;
  22.  
  23.   width = src->gc_xmax + 1;
  24.   height = src->gc_ymax + 1;
  25.  
  26.   for (y = y1; y < y2; y += height)
  27.     {
  28.       for (x = x1; x < x2; x += width)
  29.     {
  30.       GrBitBlt (NULL, x, y, src, 0, 0, width-1, height-1, GrWRITE);
  31.     }
  32.     }
  33. }
  34.  
  35. Window
  36. _WMaskEventWindow (Window w, unsigned long mask)
  37. {
  38.   while (w) 
  39.     {
  40.       if (w->event_mask & mask) 
  41.     return w;
  42.       if (w->do_not_propagate_mask & mask) 
  43.     return None;
  44.       w = w->parent;
  45.     }
  46.   return None;
  47. }
  48.  
  49.  
  50. int
  51. _WRectIntersect (BoxPtr r1, BoxPtr r2, BoxPtr rr)
  52. {
  53.   rr->x1 = MAX(r1->x1, r2->x1);
  54.   rr->y1 = MAX(r1->y1, r2->y1);
  55.   rr->x2 = MIN(r1->x2, r2->x2);
  56.   rr->y2 = MIN(r1->y2, r2->y2);
  57.  
  58.   return (rr->x1 >= rr->x2 || rr->y1 >= rr->y2) ? False : True;
  59. }
  60.  
  61. /*
  62.  * Return the x and y screen coordinates of the top-left pixel
  63.  * just inside the window's border.
  64.  */
  65.  
  66. void
  67. _WGetWindowOrigin (Window window, int *x_root, int *y_root)
  68. {
  69.   int x, y;
  70.   
  71.   x = 0;
  72.   y = 0;
  73.   
  74.   for (; window != None; window = window->parent)
  75.     {
  76.       x += window->x + window->border_width;
  77.       y += window->y + window->border_width;
  78.     }
  79.   *x_root = x;
  80.   *y_root = y;
  81. }
  82.  
  83. void
  84. _WGetWindowPort (Window window, BoxPtr port)
  85. {
  86.   int x1, y1;
  87.   _WGetWindowOrigin (window, &x1, &y1);
  88.   port->x1 = x1;
  89.   port->y1 = y1;
  90.   port->x2 = x1 + window->width;
  91.   port->y2 = y1 + window->height;
  92. }
  93.  
  94. void
  95. _WGetBorderPort (Window    window, BoxPtr port)
  96. {
  97.   int x1, y1;
  98.   _WGetWindowOrigin (window, &x1, &y1);
  99.   port->x1 = x1 - window->border_width;
  100.   port->y1 = y1 - window->border_width;
  101.   port->x2 = x1 + window->width + window->border_width;
  102.   port->y2 = y1 + window->height + window->border_width;
  103. }
  104.  
  105. /*
  106.  * Clip the window port by all parent window ports.
  107.  * Return value:
  108.  *    1 if port is not empty
  109.  *    0 otherwise.
  110.  */
  111. int
  112. _WClipPortByParents (Window window, BoxPtr port)
  113. {
  114.   *port = window->window_port;
  115.   while ((window = window->parent) != NULL) {
  116.     if (_WRectIntersect (&window->window_port, port, port) == 0)
  117.       return 0;
  118.   }
  119.   return 1;
  120. }
  121.  
  122. /*
  123.  * Clip the window border port by all parent window ports.
  124.  * Return value:
  125.  *    1 if port is not empty
  126.  *    0 otherwise.
  127.  */
  128. int
  129. _WClipBorderByParents (Window window, BoxPtr port)
  130. {
  131.   *port = window->border_port;
  132.   while ((window = window->parent) != NULL) {
  133.     if (_WRectIntersect (&window->window_port, port, port) == 0)
  134.       return 0;
  135.   }
  136.   return 1;
  137. }
  138.  
  139. Window
  140. _WPointToWindow (Display *dpy, int x, int y)
  141. {
  142.   Window window, parent;
  143.  
  144.   window = DefaultRootWindow (dpy);
  145.   parent = NULL;
  146.  
  147.   while (window != None) {
  148.     if (window->mapped != 0 &&
  149.     INBOX(window->window_port, x, y)) {
  150.       parent = window;
  151.       window = window->top_child;
  152.       continue;
  153.     }
  154.     window = window->lower_sibling;
  155.   }
  156.   return parent;
  157. }
  158.  
  159. Window
  160. _WPointToWindowBorder (Display *dpy, int x, int y)
  161. {
  162.   Window window, parent;
  163.  
  164.   window = DefaultRootWindow (dpy);
  165.   parent = NULL;
  166.  
  167.   while (window != None) {
  168.     if (window->mapped != 0 &&
  169.     INBOX(window->border_port, x, y)) {
  170.       parent = window;
  171.       window = window->top_child;
  172.       continue;
  173.     }
  174.     window = window->lower_sibling;
  175.   }
  176.   return parent;
  177. }
  178.  
  179. Cursor
  180. _WGetWindowCursor (Window window)
  181. {
  182.   while (window != NULL && window->cursor == NULL) {
  183.     window = window->parent;
  184.   }
  185.   return (window == NULL) ? None : window->cursor;
  186. }
  187.  
  188. void
  189. _WSetViewable (Window parent, Bool viewable)
  190. {
  191.   Window window;
  192.  
  193.   for (window = parent->bottom_child;
  194.        window != None;
  195.        window = window->upper_sibling) {
  196.     window->viewable = viewable ? window->mapped : False;
  197.     _WSetViewable (window, window->viewable);
  198.   }
  199. }
  200.  
  201. void
  202. _WSetMapping (Window parent, Bool mapped)
  203. {
  204.   Window window;
  205.  
  206.   for (window = parent->bottom_child;
  207.        window != None;
  208.        window = window->upper_sibling) {
  209.     window->mapped = mapped;
  210.     _WSetMapping (window, mapped);
  211.   }
  212. }
  213.  
  214. /*
  215.  * Draw visible parts of windows background and border.
  216.  */
  217.  
  218. void
  219. _WDrawWindowBorder (Display *dpy, Window w, BoxPtr rect, Bool exposures)
  220. {
  221.   BoxRec bp;
  222.   int bw;
  223.   void (*fillBox)();
  224.   long fillArg;
  225.  
  226.   if ((bw = w->border_width) == 0)
  227.     return;
  228.  
  229.   if (! _WRectIntersect (rect, &w->border_port, &bp))
  230.     return;
  231.  
  232.   fillBox = w->border.fillBox;
  233.   fillArg = w->border.fillArg;
  234.  
  235.   _WDrawScreenContext ((Drawable) w);
  236.   _WDrawRegion (fillBox, bp.x1, bp.y1, bp.x2-1, bp.y1+bw-1, fillArg);
  237.   _WDrawRegion (fillBox, bp.x1, bp.y2-bw, bp.x2-1, bp.y2-1, fillArg);
  238.   _WDrawRegion (fillBox, bp.x1, bp.y1+bw, bp.x1+bw-1, bp.y2-1-bw, fillArg);
  239.   _WDrawRegion (fillBox, bp.x2-bw, bp.y1+bw, bp.x2-1, bp.y2-1-bw, fillArg);
  240. }
  241.  
  242. void
  243. _WDrawWindowBackground (Display *dpy, Window w, BoxPtr p, Bool exposures)
  244. {
  245.   BoxRec port;
  246.  
  247.   if (! _WRectIntersect (&w->window_port, p, &port))
  248.     return;
  249.   if (! XRectInRegion (w->visible_region,
  250.                port.x1, port.y1,
  251.                port.x2 - port.x1, port.y2 - port.y1))
  252.     return;
  253.  
  254.   _WDrawScreenContext ((Drawable) w);
  255.   _WDrawRegion (w->background.fillBox,
  256.         port.x1, port.y1, port.x2 - 1, port.y2 - 1,
  257.         w->background.fillArg);
  258.  
  259.   if (exposures == True && w->event_mask & ExposureMask) {
  260.     XEvent xe;
  261.     xe.xexpose.type = Expose;
  262.     xe.xexpose.send_event = 0;
  263.     xe.xexpose.display = dpy;
  264.     xe.xexpose.window = w;
  265.     xe.xexpose.x = port.x1 - w->window_port.x1;
  266.     xe.xexpose.y = port.y1 - w->window_port.y1;
  267.     xe.xexpose.width = port.x2 - port.x1;
  268.     xe.xexpose.height = port.y2 - port.y1;
  269.     xe.xexpose.count = 0;
  270.     _WDispatchEvent (&xe);
  271.   }
  272. }
  273.  
  274. void
  275. _WDrawWindow (Display* dpy, Window window, BoxPtr rect, Bool exposures)
  276. {
  277.   if (window->viewable == 0 || window->class != InputOutput)
  278.     return;
  279.  
  280.   _WDrawWindowBorder (dpy, window, rect, exposures);
  281.   _WDrawWindowBackground (dpy, window, rect, exposures);
  282. }
  283.  
  284. void
  285. _WDrawSubwindows (Display *dpy, Window window, BoxPtr rect, Bool exposures)
  286. {
  287.   Window child;
  288.  
  289.   for (child = window->bottom_child;
  290.        child != None;
  291.        child = child->upper_sibling) {
  292.     if (! child->viewable) continue;
  293.     _WDrawWindow (dpy, child, rect, exposures);
  294.     _WDrawSubwindows (dpy, child, rect, exposures);
  295.   }
  296. }
  297.  
  298. /* draw window background region and expose optional */
  299.  
  300. void
  301. _WDrawWindowBackgroundRegion (Display *dpy, Window w, Region rgn, Bool exposures)
  302. {
  303.   int i, x1, y1, x2, y2;
  304.   BoxPtr pbox;
  305.  
  306.   _WDrawScreenContext ((Drawable) w);
  307.  
  308.   pbox = rgn->rects;
  309.   for (i = rgn->numRects; --i >= 0; pbox++) {
  310.     x1 = pbox->x1;
  311.     y1 = pbox->y1;
  312.     x2 = pbox->x2;
  313.     y2 = pbox->y2;
  314.     _WDrawRegion (w->background.fillBox, x1, y1, x2 - 1, y2 - 1,
  315.           w->background.fillArg);
  316.     if (exposures == True && w->event_mask & ExposureMask) {
  317.       XEvent xe;
  318.       xe.xexpose.type = Expose;
  319.       xe.xexpose.send_event = 0;
  320.       xe.xexpose.display = dpy;
  321.       xe.xexpose.window = w;
  322.       xe.xexpose.x = x1 - w->window_port.x1;
  323.       xe.xexpose.y = y1 - w->window_port.y1;
  324.       xe.xexpose.width = x2 - x1;
  325.       xe.xexpose.height = y2 - y1;
  326.       xe.xexpose.count = i;
  327.       _WDispatchEvent (&xe);
  328.     }
  329.   }
  330. }
  331.  
  332. void
  333. _WDrawSiblingsBelow (Display *dpy, Window window, Bool exposures)
  334. {
  335.   Window sibling;
  336.  
  337.   for (sibling = window;
  338.        sibling = sibling->lower_sibling;) {
  339. #if 0
  340.     if (! EXTENTCHECK(&window->border_port, &sibling->border_port))
  341.       continue;
  342. #endif
  343.     _WDrawWindow (dpy, sibling, &window->border_port, exposures);
  344.     _WDrawSubwindows (dpy, sibling, &window->border_port, exposures);
  345.   }
  346. }
  347.  
  348. void
  349. _WSetVisibleSubwindows (Window window)
  350. {
  351.   Window child;
  352.  
  353.   for (child = window->bottom_child;
  354.        child != None;
  355.        child = child->upper_sibling) {
  356.     _WSetVisibleRegion (child);
  357.     _WSetVisibleSubwindows (child);
  358.   }
  359. }
  360.  
  361. void
  362. _WSetVisibleSubwindowsInBox (Window window, BoxPtr pbox)
  363. {
  364.   Window child;
  365.  
  366.   for (child = window->bottom_child;
  367.        child != None;
  368.        child = child->upper_sibling) {
  369.     if (! EXTENTCHECK(pbox, &child->border_port)) continue;
  370.     _WSetVisibleRegion (child);
  371.     _WSetVisibleSubwindows (child);
  372.   }
  373. }
  374.  
  375. /*
  376.  * Window size or position has changed.
  377.  * Recreate Graphics context, recompute window and border port.
  378.  */
  379.  
  380.  
  381. void
  382. _WNewWindowContext (Window window)
  383. {
  384.   Window child;
  385.  
  386.   for (child = window->top_child;
  387.        child != NULL;
  388.        child = child->lower_sibling) {
  389.     _WNewWindowContext (child);
  390.   }
  391.   _WGetWindowPort (window, &window->window_port);
  392.   _WGetBorderPort (window, &window->border_port);
  393.  
  394.   if (window->context)
  395.     GrDestroyContext (window->context);
  396.   window->context =
  397.     GrCreateSubContext (window->window_port.x1,
  398.             window->window_port.y1,
  399.             window->window_port.x2 - 1,
  400.             window->window_port.y2 - 1,
  401.             &_WScreenContext, NULL);
  402. }
  403.  
  404. void
  405. _WUnmapSubwindows (Window parent)
  406. {
  407.   Window window;
  408.   
  409.   for (window = parent->top_child;
  410.        window != NULL;
  411.        window = window->lower_sibling) {
  412.     window->mapped = 0;
  413.     _WUnmapSubwindows (window);
  414.   }
  415. }
  416.  
  417. void
  418. _WDefineCursor (Cursor new_cursor)
  419. {
  420.   if (new_cursor == None || new_cursor == _Cursor) return;
  421.   _Cursor = new_cursor;
  422.   _WMouseSetCursor (_Cursor);
  423. }
  424.  
  425. /*
  426.  * Recompute the visible region (includes border) of window.
  427.  * Set visibility depending on region.
  428.  * Region coordinates are screen absolute.
  429.  */
  430.  
  431. int
  432. _WSetVisibleRegion (Window window)
  433. {
  434.   REGION temp;
  435.   Region region;
  436.   Window child, parent, sibling;
  437.   BoxRec port, port1;
  438.  
  439.   region = window->visible_region;
  440.   EMPTY_REGION(region);
  441.  
  442.   if (window->viewable == 0)
  443.     return 0;
  444.  
  445.   if (! _WClipBorderByParents (window, &port))
  446.     goto set_visibility;
  447.  
  448.   temp.rects = &temp.extents;
  449.   temp.numRects = 1;
  450.   temp.extents = port;
  451.   temp.size = 1;
  452.   XUnionRegion (region, &temp, region);
  453.  
  454.   for (child = window->top_child;
  455.        child != None;
  456.        child = child->lower_sibling) {
  457.     if (! child->viewable || child->class != InputOutput)
  458.       continue;
  459.     /*
  460.      * Child window may only overlap parent's drawing area
  461.      */
  462.     if (! _WRectIntersect (&window->window_port,
  463.                &child->border_port,
  464.                &port1))
  465.       continue;
  466.     if (! _WRectIntersect (&port, &port1, &temp.extents))
  467.       continue;
  468. /***
  469.     if (! EXTENTCHECK(&child->border_port, &port)) continue;
  470.     temp.extents = child->border_port;
  471. ***/
  472.     XSubtractRegion (region, &temp, region);
  473.   }
  474.  
  475.   for (parent = window;
  476.        parent != None;
  477.        parent = parent->parent) {
  478.     for (sibling = parent;
  479.      sibling = sibling->upper_sibling;) {
  480.       if (! sibling->viewable || sibling->class != InputOutput)
  481.     continue;
  482.       if (! EXTENTCHECK(&sibling->border_port, &port))
  483.     continue;
  484.       temp.extents = sibling->border_port;
  485.       XSubtractRegion (region, &temp, region);
  486.       if (region->numRects == 0) goto set_visibility;
  487.     }
  488.   }
  489.  set_visibility:
  490.   switch (region->numRects) {
  491.   case 0:
  492.     window->visibility = VisibilityFullyObscured;
  493.     break;
  494.   case 1:
  495.     window->visibility = VisibilityUnobscured;
  496.     break;
  497.   default:
  498.     window->visibility = VisibilityPartiallyObscured;
  499.     break;
  500.   }
  501.   return REGION_NOT_EMPTY(region);
  502. }
  503.  
  504. int
  505. _WInvalidateRectangle (Window w, BoxPtr pRect)
  506. {
  507.   REGION region;
  508.  
  509.   if (w->visible_region == NULL)
  510.     _WSetVisibleRegion (w);
  511.  
  512.   region.rects = ®ion.extents;
  513.   region.numRects = 1;
  514.   region.extents = *pRect;
  515.   region.size = 1;
  516.   XSubtractRegion (w->visible_region, ®ion, w->visible_region);
  517.  
  518.   return REGION_NOT_EMPTY(w->visible_region);
  519. }
  520.  
  521. int
  522. _WInvalidateParent (Window w)
  523. {
  524.   BoxRec port;
  525.   Window sibling;
  526.  
  527.   if (! _WClipBorderByParents (w, &port))
  528.     return 0;
  529.  
  530.   _WInvalidateRectangle (w->parent, &port);
  531. #if 0
  532.   for (sibling = w;
  533.        sibling = sibling->lower_sibling;) {
  534.     if (! EXTENTCHECK(&port, &sibling->border_port)) continue;
  535.     _WInvalidateRectangle (sibling, &port);
  536.   }
  537. #endif
  538.   return 0;
  539. }
  540.  
  541.  
  542. /* Convert current rawclock time to milliseconds */
  543.  
  544. Time _WCurrentTime()
  545. {
  546.   extern long rawclock();
  547.  
  548.   return rawclock() * 54.931;
  549. }
  550.  
  551. /* Convert rawclock time to milliseconds */
  552.  
  553. Time _WConvertTime(long event_time)
  554. {
  555.   return event_time * 54.931;
  556. }
  557.  
  558.  
  559. /* Return True if A is an inferior of B */
  560.  
  561. Bool
  562. _WIsInferior (Window a, Window b)
  563. {
  564.   while (b != None) {
  565.     if (b->parent == a)
  566.       return True;
  567.     b = b->parent;
  568.   }
  569.   return False;
  570. }
  571.  
  572. /* Return True if W is the focus window or an inferior of
  573.  * the focus window */
  574.  
  575. Bool
  576. _WIsFocus (Window root, Window w)
  577. {
  578.   if (_Focus.window == None)
  579.     return False;
  580.   if (_Focus.window == (Window) PointerRoot) {
  581.     if (_WIsInferior (root, w) || w == root)
  582.       return True;
  583.   }
  584.   else {
  585.     if (_WIsInferior (_Focus.window, w) || w == _Focus.window)
  586.       return True;  
  587.   }
  588.   return False;
  589. }
  590.