home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1999 March / PCWK3A99.iso / Linux / DDD331 / DDD-3_1_.000 / DDD-3_1_ / ddd-3.1.1 / ddd / Swallower.C < prev    next >
Encoding:
C/C++ Source or Header  |  1998-11-12  |  11.1 KB  |  428 lines

  1. // $Id: Swallower.C,v 1.5 1998/11/12 14:00:05 zeller Exp $ -*- C++ -*-
  2. // Swallower Widget - swallow a user application
  3.  
  4. // Copyright (C) 1998 Technische Universitaet Braunschweig, Germany.
  5. // Written by Andreas Zeller <zeller@ips.cs.tu-bs.de>.
  6. // 
  7. // This file is part of DDD.
  8. // 
  9. // DDD is free software; you can redistribute it and/or
  10. // modify it under the terms of the GNU General Public
  11. // License as published by the Free Software Foundation; either
  12. // version 2 of the License, or (at your option) any later version.
  13. // 
  14. // DDD is distributed in the hope that it will be useful,
  15. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  17. // See the GNU General Public License for more details.
  18. // 
  19. // You should have received a copy of the GNU General Public
  20. // License along with DDD -- see the file COPYING.
  21. // If not, write to the Free Software Foundation, Inc.,
  22. // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  23. // 
  24. // DDD is the data display debugger.
  25. // For details, see the DDD World-Wide-Web page, 
  26. // `http://www.cs.tu-bs.de/softech/ddd/',
  27. // or send a mail to the DDD developers <ddd@ips.cs.tu-bs.de>.
  28.  
  29. char Swallower_rcsid[] = 
  30.     "$Id: Swallower.C,v 1.5 1998/11/12 14:00:05 zeller Exp $";
  31.  
  32. #ifdef __GNUG__
  33. #pragma implementation
  34. #endif
  35.  
  36. #include "Swallower.h"
  37. #include "SwallowerP.h"
  38.  
  39. #include <X11/Xlib.h>
  40. #include "assert.h"
  41. #include "XErrorB.h"
  42.  
  43.  
  44. // Resources
  45.  
  46. static XtResource resources[] = {
  47. #define offset(field) XtOffsetOf(SwallowerRec, swallower.field)
  48.     // {name, class, type, size, offset, default_type, default_addr}
  49.     { XtNwindow, XtCWindow, XtRPointer, sizeof(Window),
  50.     offset(window), XtRImmediate, XtPointer(None) },
  51.     { XtNwindowGoneCallback, XtCCallback, XtRCallback, sizeof(XtPointer),
  52.     offset(windowGoneProc), XtRCallback, XtPointer(0) },
  53.     { XtNwindowCreatedCallback, XtCCallback, XtRCallback, sizeof(XtPointer),
  54.     offset(windowCreatedProc), XtRCallback, XtPointer(0) },
  55. #undef offset
  56. };
  57.  
  58.  
  59.  
  60. // Method function declarations
  61.  
  62. static void ClassInitialize();
  63.  
  64. static void Initialize(Widget request, 
  65.                Widget w, 
  66.                ArgList args,
  67.                Cardinal *num_args);
  68.  
  69. static void Realize(Widget w, 
  70.             XtValueMask *value_mask,
  71.             XSetWindowAttributes *attributes);
  72.  
  73. static Boolean SetValues(Widget old, 
  74.              Widget request, 
  75.              Widget new_w,
  76.              ArgList args, 
  77.              Cardinal *num_args);
  78.  
  79. static void Resize(Widget w);
  80.  
  81. static void Destroy(Widget w);
  82.  
  83. static void CheckIfWindowHasGone(Widget w, XtPointer, XEvent *, Boolean *);
  84.  
  85.  
  86. // Class record initialization
  87.  
  88. SwallowerClassRec swallowerClassRec = {
  89.   {     /* core fields */
  90.     /* superclass               */  (WidgetClass) &coreClassRec,
  91.     /* class_name               */  "Swallower",
  92.     /* widget_size              */  sizeof(SwallowerRec),
  93.     /* class_initialize         */  ClassInitialize,
  94.     /* class_part_initialize    */  NULL,
  95.     /* class_inited             */  False,
  96.     /* initialize               */  Initialize,
  97.     /* initialize_hook          */  NULL,
  98.     /* realize                  */  Realize,
  99.     /* actions                  */  NULL,
  100.     /* num_actions              */  0,
  101.     /* resources                */  resources,
  102.     /* num_resources            */  XtNumber(resources),
  103.     /* xrm_class                */  NULLQUARK,
  104.     /* compress_motion          */  True,
  105.     /* compress_exposure        */  True,
  106.     /* compress_enterleave      */  True,
  107.     /* visible_interest         */  False,
  108.     /* destroy                  */  Destroy,
  109.     /* resize                   */  Resize,
  110.     /* expose                   */  NULL,
  111.     /* set_values               */  SetValues,
  112.     /* set_values_hook          */  NULL,
  113.     /* set_values_almost        */  XtInheritSetValuesAlmost,
  114.     /* get_values_hook          */  NULL,
  115.     /* accept_focus             */  NULL,
  116.     /* version                  */  XtVersion,
  117.     /* callback_private         */  NULL,
  118.     /* tm_table                 */  NULL,
  119.     /* query_geometry           */  XtInheritQueryGeometry,
  120.     /* display_accelerator      */  XtInheritDisplayAccelerator,
  121.     /* extension                */  NULL,
  122.   },
  123.   {    /* Swallower fields */
  124.     /* extension                */ NULL,
  125.   },
  126. };
  127.  
  128. WidgetClass swallowerWidgetClass = (WidgetClass)&swallowerClassRec;
  129.  
  130.  
  131. static void ClassInitialize() {}
  132.  
  133. static SwallowerWidget all_swallowers = 0;
  134.  
  135. void SwallowerCheckEvents()
  136. {
  137.     if (all_swallowers == 0)
  138.     return;
  139.  
  140.     Widget w = Widget(all_swallowers);
  141.  
  142.     Window root = RootWindowOfScreen(XtScreen(w));
  143.  
  144.     XEvent event;
  145.     while (XCheckWindowEvent(XtDisplay(w), root, 
  146.                  SubstructureNotifyMask, &event))
  147.     {
  148.     if (event.type == CreateNotify)
  149.     {
  150.         SwallowerInfo info;
  151.         info.window = event.xcreatewindow.window;
  152.         info.event  = &event;
  153.  
  154.         SwallowerWidget loop = all_swallowers;
  155.         while (loop != 0)
  156.         {
  157.         XtCallCallbacks(Widget(loop), XtNwindowCreatedCallback, 
  158.                 XtPointer(&info));
  159.         loop = loop->swallower.next;
  160.         }
  161.  
  162.         // We don't dispatch this event, since root has no
  163.         // associated widget.  Hence, XtWindowToWidget may return
  164.         // NULL, which some toolkits (especially LessTif) don't
  165.         // check for.
  166.     }
  167.     }
  168. }
  169.  
  170. static void Initialize(Widget /* request */,
  171.                Widget w, 
  172.                ArgList /* args */,
  173.                Cardinal * /* num_args */)
  174. {
  175.     const SwallowerWidget _w = SwallowerWidget(w);
  176.     const Window window = _w->swallower.window;
  177.     SwallowerWidget& next = _w->swallower.next;
  178.  
  179.     if (window != None && (w->core.width <= 1 || w->core.height <= 1))
  180.     {
  181.     // Query current width or height
  182.     XWindowAttributes attr;
  183.     XGetWindowAttributes(XtDisplay(w), window, &attr);
  184.  
  185.     if (w->core.width == 0)
  186.         w->core.width = attr.width;
  187.     if (w->core.height == 0)
  188.         w->core.height = attr.height;
  189.     }
  190.  
  191.     // Get notified if any windows are created
  192.     Window root = RootWindowOfScreen(XtScreen(w));
  193.     XSelectInput(XtDisplay(w), root, SubstructureNotifyMask);
  194.  
  195.     // Register
  196.     next = all_swallowers;
  197.     all_swallowers = _w;
  198. }
  199.  
  200. static void WindowHasGone(Widget w, XEvent *event)
  201. {
  202.     const SwallowerWidget _w = SwallowerWidget(w);
  203.     Window& window = _w->swallower.window;
  204.  
  205.     // Our child has gone
  206.     SwallowerInfo info;
  207.     info.window = window;
  208.     info.event  = event;
  209.  
  210.     // Mark as `gone'
  211.     window = None;
  212.  
  213.     // No further need to check for events
  214.     XtRemoveEventHandler(w, SubstructureNotifyMask, False, 
  215.              CheckIfWindowHasGone, XtPointer(w));
  216.  
  217.     // Call the callbacks
  218.     XtCallCallbacks(w, XtNwindowGoneCallback, XtPointer(&info));
  219. }
  220.  
  221. static void WindowHasGone(Widget w, const XErrorEvent *event)
  222. {
  223.     WindowHasGone(w, (XEvent *)event);
  224. }
  225.  
  226. static void CheckIfWindowHasGone(Widget w, XtPointer, XEvent *event, Boolean *)
  227. {
  228.     const SwallowerWidget _w = SwallowerWidget(w);
  229.     Window& window = _w->swallower.window;
  230.  
  231.     if (event->type == ReparentNotify && event->xreparent.window == window ||
  232.     event->type == DestroyNotify && event->xdestroywindow.window == window)
  233.     {
  234.     // Our child has gone
  235.     WindowHasGone(w, event);
  236.     }
  237. }
  238.  
  239. static void Swallow(Widget w)
  240. {
  241.     const SwallowerWidget _w = SwallowerWidget(w);
  242.     Window& window = _w->swallower.window;
  243.  
  244.     if (window == None || !XtIsRealized(w))
  245.     return;
  246.  
  247.     XErrorBlocker blocker(XtDisplay(w));
  248.  
  249. #if 0
  250.     XSync(XtDisplay(w), False);
  251.     SwallowerCheckEvents();
  252. #endif
  253.  
  254.     XUnmapWindow(XtDisplay(w), window);
  255.  
  256.     XResizeWindow(XtDisplay(w), window, w->core.width, w->core.height);
  257.     XSetWindowBorderWidth(XtDisplay(w), window, 0);
  258.  
  259.     XReparentWindow(XtDisplay(w), window, XtWindow(w), 0, 0);
  260.  
  261.     XMapWindow(XtDisplay(w), window);
  262.  
  263.     if (blocker.error_occurred())
  264.     WindowHasGone(w, &blocker.error_event());
  265.  
  266.     if (window != None)
  267.     {
  268.     // Check for events
  269.     XtAddEventHandler(w, SubstructureNotifyMask, False, 
  270.               CheckIfWindowHasGone, XtPointer(w));
  271.     }
  272. }
  273.  
  274. static void Spitout(Widget w)
  275. {
  276.     const SwallowerWidget _w = SwallowerWidget(w);
  277.     Window& window = _w->swallower.window;
  278.  
  279.     if (window == None || !XtIsRealized(w))
  280.     return;
  281.  
  282.     XErrorBlocker blocker(XtDisplay(w));
  283.  
  284. #if 0
  285.     XSync(XtDisplay(w), False);
  286.     SwallowerCheckEvents();
  287. #endif
  288.  
  289.     Window root = RootWindowOfScreen(XtScreen(w));
  290.  
  291.     XUnmapWindow(XtDisplay(w), window);
  292.  
  293.     XReparentWindow(XtDisplay(w), window, root, 0, 0);
  294.  
  295.     XMapWindow(XtDisplay(w), window);
  296.  
  297.     // No further need to check for events
  298.     XtRemoveEventHandler(w, SubstructureNotifyMask, False, 
  299.              CheckIfWindowHasGone, XtPointer(w));
  300.  
  301.     // Mark window as `unused'
  302.     window = None;
  303. }
  304.  
  305. static void Realize(Widget w, 
  306.             XtValueMask *value_mask,
  307.             XSetWindowAttributes *attributes)
  308. {
  309.     const SwallowerWidget _w = SwallowerWidget(w);
  310.     Window& window = _w->swallower.window;
  311.  
  312.     XErrorBlocker blocker(XtDisplay(w));
  313.  
  314.     if (window != None && (w->core.width <= 1 || w->core.height <= 1))
  315.     {
  316.     // Query current width or height
  317.     XWindowAttributes attr;
  318.     XGetWindowAttributes(XtDisplay(w), window, &attr);
  319.  
  320.     XtMakeResizeRequest(w, attr.width, attr.height, 0, 0);
  321.     }
  322.  
  323.     if (blocker.error_occurred())
  324.     WindowHasGone(w, &blocker.error_event());
  325.  
  326.     if (window == None)
  327.     {
  328.     String arg = XtName(w);
  329.     Cardinal nargs = 1;
  330.     XtAppErrorMsg(XtWidgetToApplicationContext(w),
  331.         "missingWindow", "Swallower Realize",
  332.         "XtToolkitError",
  333.         "Widget %s has no window to swallow", &arg, &nargs);
  334.     }
  335.  
  336.     // Call superclass realize method
  337.     swallowerClassRec.core_class.superclass->
  338.     core_class.realize(w, value_mask, attributes);
  339.  
  340.     Swallow(w);
  341. }
  342.  
  343. static Boolean SetValues(Widget old, 
  344.              Widget /* request */, 
  345.              Widget new_w,
  346.              ArgList /* args */, 
  347.              Cardinal * /* num_args */)
  348. {
  349.     SwallowerWidget before = SwallowerWidget(old);
  350.     SwallowerWidget after  = SwallowerWidget(new_w);
  351.  
  352.     if (before->swallower.window != None &&
  353.     before->swallower.window != after->swallower.window)
  354.     {
  355.     Spitout(old);
  356.     }
  357.  
  358.     if (after->swallower.window != None &&
  359.     before->swallower.window != after->swallower.window)
  360.     {
  361.     Swallow(new_w);
  362.     }
  363.  
  364.     return False;        // No redisplay (yet)
  365. }
  366.  
  367. // Resize: resize child as well
  368. static void Resize(Widget w)
  369. {
  370.     const SwallowerWidget _w = SwallowerWidget(w);
  371.     Window& window = _w->swallower.window;
  372.  
  373.     if (window != None)
  374.     {
  375.     XErrorBlocker blocker(XtDisplay(w));
  376.  
  377.     XResizeWindow(XtDisplay(w), window, w->core.width, w->core.height);
  378.  
  379.     if (blocker.error_occurred())
  380.         WindowHasGone(w, &blocker.error_event());
  381.     }
  382. }
  383.  
  384. // Destroy widget
  385. static void Destroy(Widget w)
  386. {
  387.     const SwallowerWidget _w = SwallowerWidget(w);
  388.     const SwallowerWidget next = _w->swallower.next;
  389.  
  390. #if 0
  391.     // If we still have a swallowed window, spit it out
  392.     Spitout(w);
  393. #endif
  394.  
  395.     // Unregister
  396.     SwallowerWidget loop = all_swallowers;
  397.     SwallowerWidget prev = 0;
  398.     while (loop != 0 && loop != _w)
  399.     {
  400.     prev = loop;
  401.     loop = loop->swallower.next;
  402.     }
  403.  
  404.     if (loop == 0)
  405.     {
  406.     String arg = XtName(w);
  407.     Cardinal nargs = 1;
  408.     XtAppWarningMsg(XtWidgetToApplicationContext(w),
  409.         "missingWidget", "Swallower Destroy",
  410.         "XtToolkitError",
  411.         "Widget %s is not registered", &arg, &nargs);
  412.     }
  413.  
  414.     if (loop == _w)
  415.     {
  416.     if (prev == 0)
  417.     {
  418.         assert(all_swallowers == _w);
  419.         all_swallowers = next;
  420.     }
  421.     else
  422.     {
  423.         assert(prev->swallower.next == _w);
  424.         prev->swallower.next = next;
  425.     }
  426.     }
  427. }
  428.