home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / x / xtici.zip / xtici / widgets / VShell.c < prev    next >
C/C++ Source or Header  |  1991-08-28  |  16KB  |  529 lines

  1. /***********************************************************
  2. Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
  3. and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
  4.  
  5.                         All Rights Reserved
  6.  
  7. Permission to use, copy, modify, and distribute this software and its
  8. documentation for any purpose and without fee is hereby granted,
  9. provided that the above copyright notice appear in all copies and that
  10. both that copyright notice and this permission notice appear in
  11. supporting documentation, and that the names of Digital or MIT not be
  12. used in advertising or publicity pertaining to distribution of the
  13. software without specific, written prior permission.
  14.  
  15. DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  16. ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  17. DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  18. ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  19. WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  20. ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  21. SOFTWARE.
  22.  
  23. ******************************************************************/
  24.  
  25. /*
  26.  * Code and supporting documentation (c) Copyright 1990 1991 Tektronix, Inc.
  27.  *     All Rights Reserved
  28.  * 
  29.  * This file is a component of an X Window System client which uses the Xcms 
  30.  * Color Management System.  TekColor is a trademark of Tektronix, Inc.  The
  31.  * TekColor Editor is the subject of U.S. and foreign patents pending.  The
  32.  * term "TekHVC" designates a particular color space that is the subject of
  33.  * U.S. Patent No. 4,985,853 (equivalent foreign patents pending).
  34.  * Permission is hereby granted to use, copy, modify, sell, and otherwise
  35.  * distribute this software and its documentation for the X Window System
  36.  * environment, for any purpose and without fee, provided that:
  37.  * 
  38.  * 1.    The code and documentation are only used to implement a 
  39.  *      TekColor Editor in an X Window System environment; and
  40.  * 2.    This copyright and permission notice is reproduced in all copies
  41.  *     of the code and in supporting documentation.
  42.  * 
  43.  * Permission is granted to modify this code as required to allow it to
  44.  * be compiled on any host computer, provided that the functionality of
  45.  * the TekColor Editor is not modified in any way.  A description of any 
  46.  * modifications must be sent to Tektronix, Inc.  Contact 
  47.  * Tektronix Inc., P.O. Box 1000, Mail Station 60-850, 
  48.  * Network Displays Division Engineering, Wilsonville, OR 97070.
  49.  * 
  50.  * Tektronix makes no representation about the suitability of this software
  51.  * for any purpose.  It is provided "as is" and with all faults.
  52.  * 
  53.  * TEKTRONIX DISCLAIMS ALL WARRANTIES APPLICABLE TO THIS SOFTWARE,
  54.  * INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
  55.  * PARTICULAR PURPOSE.  IN NO EVENT SHALL TEKTRONIX BE LIABLE FOR ANY
  56.  * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
  57.  * RESULTING FROM LOSS OF USE, DATA, OR PROFITS, WHETHER IN AN ACTION OF
  58.  * CONTRACT, NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  59.  * CONNECTION WITH THE USE OR THE PERFORMANCE OF THIS SOFTWARE.
  60.  * 
  61.  *    NAME
  62.  *        VShell.c - implementation for visualShell widget
  63.  *
  64.  *    DESCRIPTION
  65.  *
  66.  *    HISTORY
  67.  *        
  68.  *    HISTORY END
  69.  */
  70.  
  71. #ifndef LINT
  72. static char *copy_notice = "Copyright 1991 Tektronix, Inc.";
  73. #ifdef RCS_ID
  74. static char *rcsid=  "$Header: VShell.c,v 1.2 91/08/22 11:37:14 adamsc Exp $";
  75. #endif RCS_ID
  76. #endif LINT
  77.  
  78. #include <X11/Xatom.h>
  79. #include <X11/IntrinsicP.h>
  80. #include <X11/StringDefs.h>
  81. #include "VShellP.h"
  82.  
  83. /*
  84.  *  Visual Shell -
  85.  *    This subclass of an application shell allows a visual to be specified
  86.  *    for the window of the widget.  It is sufficient to subclass a shell,
  87.  *    because all other widgets CopyFromParent, which is what is desired.
  88.  *    While we are at it, we might as well correct the R3 bug that ignores
  89.  *    the colormap resource.
  90.  *
  91.  *    This widget will probably not be necessary in R4, but who knows.
  92.  *
  93.  *    The Shell widget is the model for this widget.
  94.  */
  95.  
  96. static XtResource resources[] = {
  97. #define offset(field) XtOffset(VisualShellWidget, visual.field)
  98.     /* {name, class, type, size, offset, default_type, default_addr}, */
  99.     { XtNvisual, XtCVisual, XtRVisual, sizeof(Visual *),
  100.       offset(vis), XtRImmediate, CopyFromParent  } 
  101. #undef offset
  102. };
  103.  
  104. /* No new actions for this shell */
  105.  
  106. static void ClassInit();
  107. static void Realize();
  108. #ifdef LATER
  109. static void Resize();
  110. #endif
  111.  
  112. VisualShellClassRec visualShellClassRec = {
  113.   { /* core fields */
  114.     /* superclass        */    (WidgetClass) &applicationShellClassRec,
  115.     /* class_name        */    "VisualShell",
  116.     /* widget_size        */    sizeof(VisualShellRec),
  117.     /* class_initialize        */    ClassInit,
  118.     /* class_part_initialize    */    NULL,
  119.     /* class_inited        */    FALSE,
  120.     /* initialize        */    NULL,
  121.     /* initialize_hook        */    NULL,
  122.     /* realize            */    XtInheritRealize,
  123.     /* actions            */    NULL,
  124.     /* num_actions        */    0,
  125.     /* resources        */    resources,
  126.     /* num_resources        */    XtNumber(resources),
  127.     /* xrm_class        */    NULLQUARK,
  128.     /* compress_motion        */    TRUE,
  129.     /* compress_exposure    */    TRUE,
  130.     /* compress_enterleave    */    TRUE,
  131.     /* visible_interest        */    FALSE,
  132.     /* destroy            */    NULL,
  133.     /* resize            */    XtInheritResize /* Resize */,
  134.     /* expose            */    XtInheritExpose,
  135.     /* set_values        */    NULL,
  136.     /* set_values_hook        */    NULL,
  137.     /* set_values_almost    */    XtInheritSetValuesAlmost,
  138.     /* get_values_hook        */    NULL,
  139.     /* accept_focus        */    NULL,
  140.     /* version            */    XtVersion,
  141.     /* callback_private        */    NULL,
  142.     /* tm_table            */    NULL,
  143.     /* query_geometry        */    XtInheritQueryGeometry,
  144.     /* display_accelerator    */    XtInheritDisplayAccelerator,
  145.     /* extension        */    NULL
  146.   },
  147.   { /* composite fields        */
  148.     /* geometry_manager        */    XtInheritGeometryManager,
  149.     /* change_managed        */    XtInheritChangeManaged,
  150.     /* insert_child        */    XtInheritInsertChild,
  151.     /* delete_child        */    XtInheritDeleteChild,
  152.     /* extension        */    NULL
  153.   },
  154.   { /* shell fields        */
  155.     /* extension        */    NULL
  156.   },
  157.   { /* WM shell fields        */
  158.     /* extension        */    NULL
  159.   },
  160.   { /* vendor shell fields    */
  161.     /* extension        */    NULL
  162.   },
  163.   { /* topLevel shell fields    */
  164.     /* extension        */    NULL
  165.   },
  166.   { /* application shell fields    */
  167.     /* extension        */    NULL
  168.   },
  169.   { /* visual shell fields */
  170.     /* extension        */    NULL
  171.   }
  172. };
  173.  
  174. WidgetClass visualShellWidgetClass = (WidgetClass)&visualShellClassRec;
  175.  
  176.  
  177. static void SetWindowGroups();
  178. static void SetProperties();
  179.  
  180.  
  181. /*
  182.  * Override the realize procedure for all shell widgets.
  183.  *
  184.  * It would be nice to call the superclass realization routine after we
  185.  * put in our differences, unfortunately it contains a call to
  186.  * XCreateWindow with a hard-coded CopyFromParent visual value.
  187.  *
  188.  * So this horrendous hack is implemented which allows the rest of the
  189.  * shell hierarchy realize procedures to be inherited.
  190.  */
  191. static void ClassInit()
  192. {
  193.     WidgetClass super = (WidgetClass)vendorShellWidgetClass;
  194.  
  195.     /* 
  196.      * All the widget class inheritance has been done by this point,
  197.      * so redo realize inheritance.  Need to inherit the vendor behavior,
  198.      * but override Shell (and WMShell) behavior.
  199.      * I told you it was a hack !!!
  200.      */
  201.     /* Skip vendor shell */
  202.     super = super->core_class.superclass; 
  203.     while (strcmp(super->core_class.class_name, "Shell")) {
  204.     super->core_class.realize = Realize;
  205.     super = super->core_class.superclass; 
  206.     }
  207.     /* Replace shell realize proc also */
  208.     super->core_class.realize = Realize;
  209. }
  210.  
  211. /*
  212.  * This is pretty much a copy of the code from the Shell widget realize
  213.  * procedure, with the exception that colormaps are added to the mask
  214.  * and the visual is not hardcoded.
  215.  */
  216. static void Realize(wid, pmask, attr)
  217. ShellWidget wid;
  218. Mask *pmask;
  219. XSetWindowAttributes *attr;
  220. {
  221.     VisualShellWidget w = (VisualShellWidget)wid;
  222.     Mask mask = *pmask;
  223.     Visual *v;
  224.  
  225.     /* attempt to inherit child's pixmap to avoid screen flash */
  226.     if (w->core.background_pixmap == XtUnspecifiedPixmap) {
  227.     if (w->composite.num_children != 0) {
  228.         Widget child;
  229.         int i;
  230.         for (i = 0; i < w->composite.num_children; i++) {
  231.         child = (Widget)w->composite.children[i];
  232.         if (XtIsManaged(child))
  233.             break;
  234.         }
  235.         if (child->core.background_pixmap != XtUnspecifiedPixmap) {
  236.         mask &= ~CWBackPixel;
  237.         mask |= CWBackPixmap;
  238.         attr->background_pixmap = child->core.background_pixmap;
  239.         } else {
  240.         attr->background_pixel = child->core.background_pixel;
  241.         }
  242.     } else {
  243.         mask |= CWBackPixel;
  244.         mask &= CWBackPixmap;
  245.         attr->background_pixel = w->core.background_pixel;
  246.     }
  247.     } else {
  248.     mask &= ~CWBackPixel;
  249.     mask |= CWBackPixmap;
  250.     attr->background_pixmap = w->core.background_pixmap;
  251.     }
  252.  
  253.     if (w->shell.save_under) {
  254.     mask |= CWSaveUnder;
  255.     attr->save_under = True;
  256.     }
  257.     if (w->shell.override_redirect) {
  258.     mask |= CWOverrideRedirect;
  259.     attr->override_redirect = True;
  260.     }
  261.  
  262.     /* I don't particularly like this behaviour, but it what is expected
  263.     of a shell widget */
  264.     if (w->core.width == 0 || w->core.height == 0) {
  265.     Cardinal count = 1;
  266.     XtErrorMsg("invalidDimension", "shellRealize", "XtToolkitError",
  267.             "Shell widget %s has zero width and/or height",
  268.             &w->core.name, &count);
  269.     }
  270.  
  271.     /* If we can change the visual, better make sure colormap can change */
  272.     /* This should be done by the intrinsics, but is not (R3) */
  273.     if (w->core.colormap != CopyFromParent) {
  274.     mask |= CWColormap;
  275.     attr->colormap = w->core.colormap;
  276.     }
  277.  
  278.     if (IsVisualShell((Widget)w))
  279.     v = w->visual.vis;
  280.     else
  281.     v = CopyFromParent;
  282.  
  283.     /* Finally, the one line that justifies existance of this class */
  284.     w->core.window = XCreateWindow(XtDisplay(w), w->core.screen->root,
  285.         w->core.x, w->core.y, w->core.width, w->core.height,
  286.         w->core.border_width, w->core.depth,
  287.         InputOutput, v, mask, attr);
  288.  
  289.     if (wid->core.num_popups != 0 && w->core.parent == NULL) {
  290.     SetWindowGroups((Widget)w, w->core.window);
  291.     }
  292.     SetProperties((ApplicationShellWidget)w);
  293. }
  294. #ifdef LATER
  295. static void Resize(widget)
  296. Widget widget;
  297. {
  298.     register ShellWidget sw = (ShellWidget)widget;
  299.     Widget childwid;
  300.     Dimension width, height;
  301.     int i;
  302.  
  303.     /*
  304.      * you can get into problems if a bw setvalues is done and you're
  305.      * still size zero and unrealized |||
  306.      */
  307.     if (!XtIsRealized(widget)) return;
  308.  
  309.     width = sw->core.width;
  310.     height = sw->core.height;
  311.     if (width > ((int) ((XcmsFloat) height * 1.85)))
  312.     width = ((XcmsFloat) height) * 1.85;
  313.     else
  314.     height = ((XcmsFloat) width) / 1.85;
  315.     for(i = 0; i < sw->composite.num_children; i++) {
  316.     if(sw->composite.children[i]->core.managed) {
  317.         childwid = sw->composite.children[i];
  318.         XtResizeWidget(childwid, width, height,
  319.                childwid->core.border_width);
  320.     }
  321.     }
  322. }
  323. #endif /* LATER */
  324.  
  325. static void SetWindowGroups(w, window)
  326. Widget w;
  327. Window window;
  328. {
  329.     int i;
  330.     Arg arg;
  331.     WMShellWidget pop;
  332.  
  333.     XtSetArg(arg, XtNwindowGroup, window);
  334.  
  335.     for (i = 0; i < w->core.num_popups; i++) {
  336.     pop = (WMShellWidget)w->core.popup_list[i]; /* may not be WMShell */
  337.     if (pop->core.num_popups != 0)
  338.         SetWindowGroups((Widget)pop, window);
  339.     if (XtIsSubclass((Widget)pop, wmShellWidgetClass) /* check here */
  340.         && pop->wm.wm_hints.window_group == None)
  341.         XtSetValues((Widget)pop, &arg, 1);
  342.     }
  343. }
  344.  
  345. #define BIGSIZE ((Dimension) 32123)
  346. #define SMALLSIZE ((Dimension) 1)
  347.  
  348. static void SetProperties(w)
  349.     ApplicationShellWidget w;        /* not guaranteed; check class first */
  350. {
  351.     Window win = XtWindow(w);
  352.     ApplicationShellWidget wid;
  353.     Display *dpy = XtDisplay(w);
  354.     static unsigned char *hostname;
  355.     static Boolean gothost = False;
  356.     XWMHints *hintp;
  357.     XSizeHints *sizep;
  358.     XClassHint classhint;
  359.  
  360.     if (!gothost) {
  361.     char hostbuf[1000];
  362.     gethostname(hostbuf, sizeof(hostbuf));
  363.     hostname = (unsigned char *)XtNewString(hostbuf);
  364.     gothost = True;
  365.     }
  366.  
  367.     if (XtIsSubclass((Widget)w, wmShellWidgetClass) &&
  368.     !w->shell.override_redirect) {
  369.     Widget parent = w->core.parent;
  370.     if (parent) {
  371.         while (parent->core.parent)
  372.         parent = parent->core.parent;
  373.     }
  374.  
  375.     XStoreName(dpy, win, w->wm.title);
  376.  
  377.     hintp = &w->wm.wm_hints;
  378.     hintp->flags |= StateHint | InputHint;
  379.     if (hintp->icon_x != -1 || hintp->icon_y != -1)
  380.         hintp->flags |= IconPositionHint;
  381.     if (hintp->icon_pixmap != NULL)
  382.         hintp->flags |= IconPixmapHint;
  383.     if (hintp->icon_mask != NULL)
  384.         hintp->flags |= IconMaskHint;
  385.     if (hintp->icon_window != NULL)
  386.         hintp->flags |= IconWindowHint;
  387.     if (hintp->window_group == None) {
  388.         if (parent) {
  389.         hintp->window_group = XtWindow(parent);
  390.         hintp->flags |= WindowGroupHint;
  391.         }
  392.     } else
  393.         hintp->flags |= WindowGroupHint;
  394.  
  395.     if (XtIsSubclass((Widget)w, topLevelShellWidgetClass)) {
  396.         XSetIconName(dpy, win, w->topLevel.icon_name);
  397.         if (w->topLevel.iconic)
  398.         hintp->initial_state = IconicState;
  399.     }
  400.  
  401.     XSetWMHints(dpy, win, hintp);
  402.  
  403.     sizep = (XSizeHints *)&w->wm.size_hints;
  404.     sizep->x = w->core.x;
  405.     sizep->y = w->core.y;
  406.     sizep->width = w->core.width;
  407.     sizep->height = w->core.height;
  408.     sizep->flags |= PSize | PPosition;
  409.     if (sizep->min_aspect.x != -1 || sizep->min_aspect.y != -1
  410.         || sizep->max_aspect.x != -1 || sizep->max_aspect.y != -1)
  411.         sizep->flags |= PAspect;
  412.     if (sizep->width_inc != -1 || sizep->height_inc != -1)
  413.         sizep->flags |= PResizeInc;
  414.     if (sizep->max_width != -1 || sizep->max_height != -1) {
  415.         sizep->flags |= PMaxSize;
  416.         if (sizep->max_width == -1)
  417.         sizep->max_width = BIGSIZE;
  418.         if (sizep->max_height == -1)
  419.         sizep->max_height = BIGSIZE;
  420.     }
  421.     if (sizep->min_width != -1 || sizep->min_height != -1) {
  422.         sizep->flags |= PMinSize;
  423.         if (sizep->min_width == -1)
  424.         sizep->min_width = SMALLSIZE;
  425.         if (sizep->min_height == -1)
  426.         sizep->min_height = SMALLSIZE;
  427.     }
  428.  
  429.     XSetNormalHints(dpy, win, sizep);
  430.  
  431.     if (w->wm.transient)
  432.         XSetTransientForHint(dpy, win, hintp->window_group);
  433.  
  434.     classhint.res_name = w->core.name;
  435.     /* get class from top of widget tree */
  436.     if (parent)
  437.         wid = (ApplicationShellWidget)parent;
  438.     else
  439.         wid = w;
  440.     if (XtIsSubclass((Widget)wid, applicationShellWidgetClass))
  441.         classhint.res_class = wid->application.class;
  442.     else
  443.         classhint.res_class = XtClass(wid)->core_class.class_name;
  444.  
  445.     XSetClassHint(dpy, win, &classhint);
  446.  
  447.     /* SetHostName(dpy, win, hostname); */
  448.     XChangeProperty(dpy, win, XA_WM_CLIENT_MACHINE, XA_STRING, 8,
  449.             PropModeReplace, hostname, strlen((char *)hostname));
  450.     }
  451.  
  452.     if (XtIsSubclass((Widget)w, applicationShellWidgetClass) 
  453.         && w->application.argc != -1)
  454.     XSetCommand(dpy, win, w->application.argv, w->application.argc);
  455. }
  456.  
  457. /****************************************************************************
  458.  *
  459.  * This routine will attempt to get the visualShell widget associated with
  460.  * the widget passed. 
  461.  *
  462.  ****************************************************************************/
  463. Widget GetVisualShellWidget (wid) 
  464. VisualShellWidget wid;
  465. {
  466.     if (!wid || IsVisualShell((Widget)wid))
  467.     return ((Widget)wid);
  468.     return (GetVisualShellWidget ((VisualShellWidget)XtParent((Widget)wid)));
  469. }
  470.  
  471.  
  472. /****************************************************************************
  473.  *
  474.  * This routine will attempt to get the visual class from the window of a
  475.  * widget.  
  476.  *
  477.  * Return -1 on failure and visual class on success.
  478.  *
  479.  ****************************************************************************/
  480. int GetVisualClass(widget)
  481. Widget widget;
  482. {
  483.     Display *dpy;
  484.     Window win;
  485.     XWindowAttributes watt;
  486.  
  487.     if (!widget || 
  488.     !(dpy = XtDisplayOfObject(widget)) || 
  489.     !(win = XtWindow(widget))) {
  490.     return (-1);
  491.     }
  492.     if (!XGetWindowAttributes(dpy, win, &watt)) {
  493.     return (-1);
  494.     }
  495.     if (watt.visual->class == CopyFromParent) {
  496.     return (GetVisualClass (XtParent(widget)));
  497.     }
  498.     return (watt.visual->class);
  499. }
  500.  
  501.  
  502. /****************************************************************************
  503.  *
  504.  * This routine will determine the maximum number of colors displayable
  505.  * on the window of a widget.
  506.  *
  507.  * Returns -1 on failure or a number greater than or equal to one on success.
  508.  *
  509.  ****************************************************************************/
  510. int GetColormapSize (widget)
  511. Widget widget;
  512. {
  513.     Display *dpy;
  514.     Window win;
  515.     XWindowAttributes watt;
  516.  
  517.     if (!widget || 
  518.     !(dpy = XtDisplayOfObject(widget)) ||
  519.     !(win = XtWindow(widget))) {
  520.     return (-1);
  521.     }
  522.  
  523.     if (!XGetWindowAttributes(dpy, win, &watt)) {
  524.     return (-1);
  525.     }
  526.  
  527.     return (1 << watt.depth);
  528. }
  529.