Home | History | Annotate | Line # | Download | only in dist
      1 /*
      2  *
      3 Copyright 1989, 1998  The Open Group
      4 
      5 Permission to use, copy, modify, distribute, and sell this software and its
      6 documentation for any purpose is hereby granted without fee, provided that
      7 the above copyright notice appear in all copies and that both that
      8 copyright notice and this permission notice appear in supporting
      9 documentation.
     10 
     11 The above copyright notice and this permission notice shall be included in
     12 all copies or substantial portions of the Software.
     13 
     14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
     17 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
     18 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
     19 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     20 
     21 Except as contained in this notice, the name of The Open Group shall not be
     22 used in advertising or otherwise to promote the sale, use or other dealings
     23 in this Software without prior written authorization from The Open Group.
     24  *
     25  * Author:  Chris D. Peterson, MIT X Consortium
     26  */
     27 
     28 #ifdef HAVE_CONFIG_H
     29 # include "config.h"
     30 #endif
     31 
     32 #include <X11/Intrinsic.h>
     33 #include <X11/StringDefs.h>
     34 #include <X11/Shell.h>
     35 #include <stdio.h>
     36 
     37 #include <X11/Xaw/Cardinals.h>
     38 
     39 #include "editresP.h"
     40 
     41 /*
     42  * Local function definitions
     43  */
     44 static void AddToFlashList ( TreeInfo * tree_info, GetGeomInfo * geom_info,
     45 			     char ** errors );
     46 static void _AddToFlashList ( TreeInfo * tree_info, char ** errors,
     47 			      WNode * node, int x, int y, unsigned int width,
     48 			      unsigned int height );
     49 static void CreateFlashWidget ( TreeInfo * tree_info, int x, int y,
     50 				unsigned int width, unsigned int height );
     51 static void FlashWidgets ( TreeInfo * tree_info );
     52 static void FlashWidgetsOn ( XtPointer info_ptr, XtIntervalId * id );
     53 static void FlashWidgetsOff ( XtPointer info_ptr, XtIntervalId * id );
     54 static void FlashWidgetsCleanup ( XtPointer info_ptr, XtIntervalId * id );
     55 
     56 /*	Function Name: _FindWidget
     57  *	Description: Finds a widget in the tree and shows it to the user.
     58  *	Arguments: w - any widget in the application.
     59  *	Returns: none.
     60  */
     61 
     62 void
     63 _FindWidget(Widget w)
     64 {
     65     char msg[BUFSIZ];
     66     WNode * node;
     67     Window win;
     68     int x, y;			/* location of event in root coordinates. */
     69 
     70     snprintf(msg, sizeof(msg), res_labels[14]);
     71 
     72     SetMessage(global_screen_data.info_label, msg);
     73 
     74     if ( (win = GetClientWindow(w, &x, &y)) != None) {
     75 	node = FindWidgetFromWindow(global_tree_info, win);
     76 	if (node != NULL) {
     77 	    ProtocolStream * stream = &(global_client.stream);
     78 
     79 	    _XEditResResetStream(stream);
     80 	    InsertWidgetFromNode(stream, node);
     81 	    _XEditResPut16(stream, (short) x);
     82 	    _XEditResPut16(stream, (short) y);
     83 	    SetCommand(w, LocalFindChild, NULL);
     84 	    return;
     85 	}
     86     }
     87 
     88     SetMessage(global_screen_data.info_label,
     89       res_labels[15]);
     90 }
     91 
     92 
     93 /*	Function Name: DisplayChild
     94  *	Description: Displays the child node returned by the client
     95  *	Arguments: event - the event from the client.
     96  *	Returns: none.
     97  */
     98 
     99 void
    100 DisplayChild(Event *event)
    101 {
    102     FindChildEvent * find_event = (FindChildEvent *) event;
    103     WNode * node;
    104     char msg[BUFSIZ];
    105 
    106     node = FindNode(global_tree_info->top_node, find_event->widgets.ids,
    107 		    find_event->widgets.num_widgets);
    108 
    109     if (node == NULL) {
    110 	snprintf(msg, sizeof(msg), res_labels[13]);
    111 	SetMessage(global_screen_data.info_label, msg);
    112 	return;
    113     }
    114 
    115     SetAndCenterTreeNode(node);
    116 
    117     node = node->tree_info->top_node;
    118 
    119     snprintf(msg, sizeof(msg), res_labels[12], node->name, node->class);
    120     SetMessage(global_screen_data.info_label, msg);
    121 
    122     _FlashActiveWidgets(global_tree_info);
    123 }
    124 
    125 /*	Function Name: _FlashActiveWidgets
    126  *	Description: Highlights all active widgets in the tree.
    127  *	Arguments: tree_info - information about the current tree.
    128  *	Returns: none.
    129  */
    130 
    131 void
    132 _FlashActiveWidgets(TreeInfo *tree_info)
    133 {
    134     Cardinal i;
    135     ProtocolStream * stream = &(global_client.stream);
    136 
    137     if (tree_info == NULL) {
    138 	SetMessage(global_screen_data.info_label,
    139 		   res_labels[17]);
    140 	return;
    141     }
    142 
    143     if (tree_info->num_nodes == 0) {
    144 	SetMessage(global_screen_data.info_label,res_labels[18]);
    145 	return;
    146     }
    147 
    148     _XEditResResetStream(stream);
    149     /*
    150      * Insert the number of widgets.
    151      */
    152     _XEditResPut16(stream, (unsigned short) tree_info->num_nodes);
    153 
    154     for (i = 0; i < tree_info->num_nodes; i++)
    155 	InsertWidgetFromNode(stream, global_tree_info->active_nodes[i]);
    156 
    157     SetCommand(tree_info->tree_widget, LocalFlashWidget, NULL);
    158 }
    159 
    160 /*	Function Name: HandleFlashWidget
    161  *	Description: Is called when client has returned geometry of all widget
    162  *                   to flash.
    163  *	Arguments: event - the event containing the client info.
    164  *	Returns: none.
    165  */
    166 
    167 char *
    168 HandleFlashWidget(Event *event)
    169 {
    170     GetGeomEvent * geom_event = (GetGeomEvent *) event;
    171     char * errors = NULL;
    172     int i;
    173 
    174     for (i = 0; i < (int)geom_event->num_entries; i++)
    175 	AddToFlashList(global_tree_info, geom_event->info + i, &errors);
    176 
    177     FlashWidgets(global_tree_info);
    178 
    179     return(errors);
    180 }
    181 
    182 /*	Function Name: AddWidgetToFlashList
    183  *	Description: Adds a widget to the list of widget to flash.
    184  *	Arguments: tree_info - info about this tree.
    185  *                 geom_info - the info from the client about this widget.
    186  *                 errors - a string containing the errors.
    187  *	Returns: none
    188  */
    189 
    190 static void
    191 AddToFlashList(TreeInfo *tree_info, GetGeomInfo *geom_info, char **errors)
    192 {
    193     WNode * node;
    194     char buf[BUFSIZ];
    195 
    196     node = FindNode(tree_info->top_node,
    197 		    geom_info->widgets.ids, geom_info->widgets.num_widgets);
    198 
    199     if (node == NULL) {
    200 	snprintf(buf, sizeof(buf),
    201                  "Editres Internal Error: Unable to FindNode.\n");
    202 	AddString(errors, buf);
    203 	return;
    204     }
    205 
    206     if (geom_info->error) {
    207 	AddString(errors, geom_info->message);
    208 	return;
    209     }
    210 
    211     if (!geom_info->visible) {
    212 	snprintf(buf, sizeof(buf), "%s(0x%lx) - This widget is not mapped\n",
    213 		node->name, node->id);
    214 	AddString(errors, buf);
    215 	return;
    216     }
    217 
    218     _AddToFlashList(tree_info, errors, node,
    219 		    geom_info->x, geom_info->y,
    220 		    geom_info->width + geom_info->border_width,
    221 		    geom_info->height + geom_info->border_width);
    222 }
    223 
    224 /*	Function Name: _AddToFlashList
    225  *	Description: adds the window to the current client's flash list.
    226  *	Arguments: errors - a string to stuff any errors encountered.
    227  *                 node - the node associated with this object.
    228  *                 x, y - location of the flash widget in root coords.
    229  *                 width, height - size of the flash widget.
    230  *	Returns: none.
    231  */
    232 
    233 static void
    234 _AddToFlashList(TreeInfo *tree_info, char **errors, WNode *node,
    235 		int x, int y, unsigned int width, unsigned int height)
    236 {
    237     Display * dpy = XtDisplay(tree_info->tree_widget);
    238     Window window = (Window) node->window;
    239     XWindowAttributes attrs;
    240 
    241     if (window == EDITRES_IS_OBJECT)
    242 	window = node->parent->window;
    243 
    244     if (window == EDITRES_IS_UNREALIZED) {
    245 	char buf[BUFSIZ];
    246 
    247 	if (node->window == EDITRES_IS_OBJECT)
    248 	    snprintf(buf, sizeof(buf),
    249                      "%s(0x%lx) - This object's parent is unrealized\n",
    250                      node->name, node->id);
    251 	else
    252 	    snprintf(buf, sizeof(buf),
    253                      "%s(0x%lx) - This widget is unrealized\n",
    254                      node->name, node->id);
    255 
    256 	AddString(errors, buf);
    257 	return;
    258     }
    259 
    260     global_error_code = NO_ERROR;                 /* Reset Error code. */
    261     global_old_error_handler = XSetErrorHandler(HandleXErrors);
    262     global_serial_num = NextRequest(dpy);
    263 
    264     XGetWindowAttributes(dpy, window, &attrs);
    265 
    266     XSync(dpy, FALSE);
    267     XSetErrorHandler(global_old_error_handler);
    268     if (global_error_code == NO_WINDOW) {
    269 	char buf[BUFSIZ];
    270 
    271 	snprintf(buf, sizeof(buf),
    272                  "%s(0x%lx) - This widget's window no longer exists.\n",
    273                  node->name, node->id);
    274 	AddString(errors, buf);
    275 	return;
    276     }
    277 
    278     if (attrs.map_state != IsViewable) {
    279 	char buf[BUFSIZ];
    280 
    281 	snprintf(buf, sizeof(buf), "%s(0x%lx) - This widget is not mapped.\n",
    282                  node->name, node->id);
    283 	AddString(errors, buf);
    284 	return;
    285     }
    286 
    287     CreateFlashWidget(tree_info, x, y, width, height);
    288 }
    289 
    290 /*	Function Name: CreateFlashWidget
    291  *	Description: Creates a widget of the size specified that
    292  *                   will flash on the display, and adds it to the list
    293  *                   of widgets to flash.
    294  *	Arguments: tree_info - the tree information structure.
    295  *                 x,y,width, height - size and location of the flash widget.
    296  *	Returns: none.
    297  */
    298 
    299 #define MORE_FLASH_WIDGETS 5
    300 
    301 static void
    302 CreateFlashWidget(TreeInfo *tree_info, int x, int y,
    303 		  unsigned int width, unsigned int height)
    304 {
    305     Widget shell;
    306     Arg args[3];
    307     Cardinal num = 0;
    308     Dimension bw;
    309 
    310     XtSetArg(args[num], XtNx, x); num++;
    311     XtSetArg(args[num], XtNy, y); num++;
    312     XtSetArg(args[num], XtNbackground, global_resources.flash_color); num++;
    313 
    314     shell = XtCreatePopupShell("flash", overrideShellWidgetClass,
    315 			       tree_info->tree_widget, args, num);
    316 
    317     num = 0;
    318     XtSetArg(args[num], XtNborderWidth, &bw); num++;
    319     XtGetValues(shell, args, num);
    320 
    321     bw *= 2;
    322 
    323     num = 0;
    324     XtSetArg(args[num], XtNwidth, (width - bw)); num++;
    325     XtSetArg(args[num], XtNheight, (height - bw)); num++;
    326     XtSetValues(shell, args, num);
    327 
    328     if (tree_info->num_flash_widgets + 1 > tree_info->alloc_flash_widgets) {
    329 	tree_info->alloc_flash_widgets += MORE_FLASH_WIDGETS;
    330 	tree_info->flash_widgets =
    331 	    (Widget *) XtRealloc((char *)tree_info->flash_widgets,
    332 			      sizeof(Widget) * tree_info->alloc_flash_widgets);
    333     }
    334 
    335     tree_info->flash_widgets[tree_info->num_flash_widgets] = shell;
    336     tree_info->num_flash_widgets++;
    337 }
    338 
    339 /*	Function Name: FlashWidgets
    340  *	Description: Starts the widgets flashing.
    341  *	Arguments: tree_info - the info about the tree (contains flash list)
    342  *	Returns: none
    343  */
    344 
    345 static void
    346 FlashWidgets(TreeInfo *tree_info)
    347 {
    348     int i;
    349     unsigned long wait, half_flash;
    350     XtAppContext ac = XtWidgetToApplicationContext(tree_info->tree_widget);
    351 
    352     if (tree_info->flash_widgets == NULL) /* no widgets to flash. */
    353 	return;
    354 
    355     wait = half_flash = global_resources.flash_time/2;
    356     for (i = 1; i < global_resources.num_flashes; i++) {
    357 	XtAppAddTimeOut(ac, wait, FlashWidgetsOff,(XtPointer)tree_info);
    358 	wait += half_flash;
    359 	XtAppAddTimeOut(ac, wait, FlashWidgetsOn,(XtPointer)tree_info);
    360 	wait += half_flash;
    361     }
    362 
    363     wait += half_flash;
    364     XtAppAddTimeOut(ac, wait, FlashWidgetsCleanup, (XtPointer)tree_info);
    365 
    366     FlashWidgetsOn((XtPointer) tree_info, (XtIntervalId *) NULL);
    367 }
    368 
    369 /*	Function Name: FlashWidgetsOn
    370  *	Description: Turns on all the Flash Widgets.
    371  *	Arguments: info_ptr - pointer to the tree info.
    372  *                 id - *** UNUSED ***.
    373  *	Returns: none
    374  */
    375 
    376 /* ARGSUSED */
    377 static void
    378 FlashWidgetsOn(XtPointer info_ptr, XtIntervalId *id)
    379 {
    380 
    381     Cardinal i;
    382     TreeInfo * tree_info = (TreeInfo *) info_ptr;
    383 
    384     for (i = 0; i < tree_info->num_flash_widgets; i++) {
    385 	XtRealizeWidget(tree_info->flash_widgets[i]);
    386 	XMapRaised(XtDisplay(tree_info->flash_widgets[i]),
    387 		   XtWindow(tree_info->flash_widgets[i]));
    388     }
    389 }
    390 
    391 /*	Function Name: FlashWidgetsOff
    392  *	Description: Turns off all the Flash Widgets.
    393  *	Arguments: info_ptr - pointer to the tree info.
    394  *                 id - *** UNUSED ***.
    395  *	Returns: none
    396  */
    397 
    398 /* ARGSUSED */
    399 static void
    400 FlashWidgetsOff(XtPointer info_ptr, XtIntervalId *id)
    401 {
    402     Cardinal i;
    403     TreeInfo * tree_info = (TreeInfo *) info_ptr;
    404 
    405     for (i = 0; i < tree_info->num_flash_widgets; i++)
    406 	XtUnmapWidget(tree_info->flash_widgets[i]);
    407 }
    408 
    409 /*	Function Name: FlashWidgetsCleanup
    410  *	Description: Destroys all the Flash Widgets.
    411  *	Arguments: info_ptr - pointer to the tree info.
    412  *                 id - *** UNUSED ***.
    413  *	Returns: none
    414  */
    415 
    416 /* ARGSUSED */
    417 static void
    418 FlashWidgetsCleanup(XtPointer info_ptr, XtIntervalId *id)
    419 {
    420     Cardinal i;
    421     TreeInfo * tree_info = (TreeInfo *) info_ptr;
    422 
    423 /*
    424  * Unmap 'em first for consistency.
    425  */
    426 
    427     for (i = 0; i < tree_info->num_flash_widgets; i++)
    428 	XtUnmapWidget(tree_info->flash_widgets[i]);
    429 
    430     XFlush(XtDisplay(tree_info->tree_widget));
    431 
    432     for (i = 0; i < tree_info->num_flash_widgets; i++)
    433 	XtDestroyWidget(tree_info->flash_widgets[i]);
    434 
    435     XtFree((char *)tree_info->flash_widgets);
    436     tree_info->flash_widgets = NULL;
    437     tree_info->num_flash_widgets = tree_info->alloc_flash_widgets = 0;
    438 }
    439