2 * $Xorg: handler.c,v 1.4 2001/02/09 02:05:29 xorgcvs Exp $
4 Copyright 1989, 1998 The Open Group
6 Permission to use, copy, modify, distribute, and sell this software and its
7 documentation for any purpose is hereby granted without fee, provided that
8 the above copyright notice appear in all copies and that both that
9 copyright notice and this permission notice appear in supporting
12 The above copyright notice and this permission notice shall be included in
13 all copies or substantial portions of the Software.
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
19 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 Except as contained in this notice, the name of The Open Group shall not be
23 used in advertising or otherwise to promote the sale, use or other dealings
24 in this Software without prior written authorization from The Open Group.
27 /* $XFree86: xc/programs/editres/handler.c,v 1.7tsi Exp $ */
29 #include <X11/Intrinsic.h>
30 #include <X11/StringDefs.h>
32 #include <X11/Xaw/Cardinals.h>
33 #include <X11/Xaw/List.h>
34 #include <X11/Xaw/Panner.h>
35 #include <X11/Xaw/Toggle.h>
36 #include <X11/Xfuncs.h>
37 #include <X11/Xos.h> /* for W_OK def */
45 * Local function definitions.
47 static char * GetResourceName ( ResourceBoxInfo * res_box );
48 static void _AppendResourceString ( Widget w, XtPointer res_box_ptr,
49 XtPointer filename_ptr );
50 static void _SetResourcesFile ( Widget w, XtPointer junk,
51 XtPointer filename_ptr );
52 static void ObtainResource ( XtPointer node_ptr );
53 static void CreateSetValuesCommand ( WNode * node, XtPointer info_ptr );
54 static void SetOnlyMatchingWidgets ( WNode * node, XtPointer info_ptr );
56 /* Function Name: Quit
57 * Description: This function prints a message to stdout.
58 * Arguments: w - ** UNUSED **
59 * call_data - ** UNUSED **
60 * client_data - ** UNUSED **
66 Quit(Widget w, XtPointer client_data, XtPointer call_data)
68 XtDestroyApplicationContext(XtWidgetToApplicationContext(w));
72 /* Function Name: SendTree
73 * Description: This function initiates the client communication.
74 * by getting the resource tree.
75 * Arguments: w - the widget that made the selection.
76 * value - a boolean value stored as a pointer.
77 * if True then get a new client, otherwise
78 * refresh the current client.
79 * call_data - ** UNUSED **
85 SendTree(Widget w, XtPointer value, XtPointer call_data)
87 if ((Boolean)(long) value)
88 global_client.window = None;
90 if (!XtIsWidget(w)) /* Make sure that we use a "Real" widget here. */
93 _XEditResResetStream(&(global_client.stream)); /* an empty message. */
95 SetCommand(w, LocalSendWidgetTree, NULL);
98 /* Function Name: FindWidget
99 * Description: Maps a widget in the client to one in the currently
100 * displayed widget tree.
101 * Arguments: w - the widget that invoked this action.
102 * call_data, client_data ** UNUSED **
108 FindWidget(Widget w, XtPointer client_data, XtPointer call_data)
111 _FindWidget(XtParent(w)); /* Use parent since it is a "real"
112 widget not a rect_obj. */
115 /* Function Name: InitSetValues
116 * Description: This function pops up the setvalues dialog
117 * Arguments: w - the widget caused this action.
118 * call_data - ** UNUSED **
119 * client_data - ** UNUSED **
125 InitSetValues(Widget w, XtPointer client_data, XtPointer call_data)
127 if (!XtIsWidget(w)) /* Make sure that we use a "Real" widget here. */
130 PopupSetValues(w, NULL);
133 /* Function Name: TreeSelect
134 * Description: Selects all widgets.
135 * Arguments: w - the widget caused this action.
136 * call_data - ** UNUSED **
137 * client_data - The type of thing to select.
143 TreeSelect(Widget w, XtPointer client_data, XtPointer call_data)
145 SelectTypes type = (SelectTypes) (unsigned long) client_data;
147 _TreeSelect(global_tree_info, type);
150 /* Function Name: TreeRelabel
151 * Description: Relabels a tree to the type specified.
152 * Arguments: w - the widget caused this action.
153 * call_data - ** UNUSED **
154 * client_data - the type of label to assign to each node.
160 TreeRelabel(Widget w, XtPointer client_data, XtPointer call_data)
162 LabelTypes type = (LabelTypes) (unsigned long) client_data;
164 _TreeRelabel(global_tree_info, type);
167 /* Function Name: PannerCallback
168 * Description: called when the panner has moved.
169 * Arguments: panner - the panner widget.
170 * closure - *** NOT USED ***.
171 * report_ptr - the panner record.
177 PannerCallback(Widget w, XtPointer closure, XtPointer report_ptr)
180 XawPannerReport *report = (XawPannerReport *) report_ptr;
182 if (global_tree_info == NULL)
185 XtSetArg (args[0], XtNx, -report->slider_x);
186 XtSetArg (args[1], XtNy, -report->slider_y);
188 XtSetValues(global_tree_info->tree_widget, args, TWO);
191 /* Function Name: PortholeCallback
192 * Description: called when the porthole or its child has
194 * Arguments: porthole - the porthole widget.
195 * panner_ptr - the panner widget.
196 * report_ptr - the porthole record.
202 PortholeCallback(Widget w, XtPointer panner_ptr, XtPointer report_ptr)
206 XawPannerReport *report = (XawPannerReport *) report_ptr;
207 Widget panner = (Widget) panner_ptr;
209 XtSetArg (args[n], XtNsliderX, report->slider_x); n++;
210 XtSetArg (args[n], XtNsliderY, report->slider_y); n++;
211 if (report->changed != (XawPRSliderX | XawPRSliderY)) {
212 XtSetArg (args[n], XtNsliderWidth, report->slider_width); n++;
213 XtSetArg (args[n], XtNsliderHeight, report->slider_height); n++;
214 XtSetArg (args[n], XtNcanvasWidth, report->canvas_width); n++;
215 XtSetArg (args[n], XtNcanvasHeight, report->canvas_height); n++;
217 XtSetValues (panner, args, n);
220 /* Function Name: FlashActiveWidgets
221 * Description: called to flass all active widgets in the display.
222 * Arguments: *** NOT USED ***
228 FlashActiveWidgets(Widget w, XtPointer junk, XtPointer garbage)
230 _FlashActiveWidgets(global_tree_info);
233 /* Function Name: GetResourceList
234 * Description: Gets the resources lists of all active widgets.
235 * Arguments: ** NOT USED **
241 GetResourceList(Widget w, XtPointer junk, XtPointer garbage)
244 ProtocolStream * stream = &(global_client.stream);
246 if (global_tree_info == NULL) {
247 SetMessage(global_screen_data.info_label,
252 if (global_tree_info->num_nodes != 1) {
253 SetMessage(global_screen_data.info_label,
258 node = global_tree_info->active_nodes[0];
259 if (node->resources != NULL) {
260 char * errors = NULL;
261 CreateResourceBox(node, &errors);
262 if (errors != NULL) {
263 SetMessage(global_screen_data.info_label, errors);
270 * No resoruces, fetch them from the client.
273 _XEditResResetStream(stream);
274 _XEditResPut16(stream, (unsigned short) 1);
275 InsertWidgetFromNode(stream, node);
276 SetCommand(global_tree_info->tree_widget, LocalGetResources, NULL);
279 /* Function Name: DumpTreeToFile
280 * Description: Dumps all widgets in the tree to a file.
281 * Arguments: w - the widget that activated this callback.
282 * junk, garbage - ** NOT USED **.
288 DumpTreeToFile(Widget w, XtPointer junk, XtPointer garbage)
290 _PopupFileDialog(XtParent(w), "Enter the filename:", "",
291 _DumpTreeToFile, (XtPointer) global_tree_info);
294 /************************************************************
296 * Callbacks for the Resource Box.
298 ************************************************************/
301 /* Function Name: AnyChosen
302 * Description: Callback that is called when the "any" widget
304 * Arguments: w - the "any" widget that activated this callback.
305 * any_info_ptr - pointer to struct containing
306 * dot and star widgets to lock.
307 * state_ptr - state of the any toggle.
313 AnyChosen(Widget w, XtPointer any_info_ptr, XtPointer state_ptr)
315 AnyInfo * any_info = (AnyInfo *) any_info_ptr;
316 Boolean state = (Boolean)(long) state_ptr;
321 if (any_info->left_count == 0) {
322 XtSetSensitive(any_info->left_dot, FALSE);
323 XtSetSensitive(any_info->left_star, FALSE);
325 XtSetArg(args[0], XtNstate, TRUE);
326 XtSetValues(any_info->left_star, args, ONE);
329 if ((any_info->right_count == NULL)||(*any_info->right_count == 0)) {
330 XtSetSensitive(any_info->right_dot, FALSE);
331 XtSetSensitive(any_info->right_star, FALSE);
333 XtSetArg(args[0], XtNstate, TRUE);
334 XtSetValues(any_info->right_star, args, ONE);
336 any_info->left_count++;
338 if (any_info->right_count != NULL)
339 (*any_info->right_count)++;
341 else { /* state == 0 */
342 if (any_info->left_count > 0)
343 any_info->left_count--;
344 if ((any_info->right_count != NULL)&&(*any_info->right_count > 0))
345 (*any_info->right_count)--;
347 if (any_info->left_count == 0) {
348 XtSetSensitive(any_info->left_dot, TRUE);
349 XtSetSensitive(any_info->left_star, TRUE);
351 XtSetArg(args[0], XtNstate, TRUE);
352 XtSetValues(any_info->left_dot, args, ONE);
355 if ((any_info->right_count == NULL)||(*any_info->right_count == 0)) {
356 XtSetSensitive(any_info->right_dot, TRUE);
357 XtSetSensitive(any_info->right_star, TRUE);
359 XtSetArg(args[0], XtNstate, TRUE);
360 XtSetValues(any_info->right_dot, args, ONE);
363 SetResourceString(NULL, (XtPointer) any_info->node, NULL);
364 ActivateResourceWidgets(NULL, (XtPointer) any_info->node, NULL);
367 /* Function Name: GetResourceName
368 * Description: Gets the name of the current resource.
369 * Arguments: res_box - the resource box.
370 * Returns: the name of the currently selected resource.
375 GetResourceName(ResourceBoxInfo *res_box)
377 XawListReturnStruct * list_info;
380 list_info = XawListShowCurrent(res_box->norm_list);
381 if ((list_info->list_index == XAW_LIST_NONE) &&
382 (res_box->cons_list != NULL)) {
383 list_info = XawListShowCurrent(res_box->cons_list);
386 if (list_info->list_index == XAW_LIST_NONE)
389 result = list_info->string;
395 /* Function Name: ActivateWidgetsAndSetResourceString
396 * Description: Sets the new resources string, then
397 * activates all widgets that match this resource,
398 * Arguments: w - the widget that activated this.
399 * node_ptr - the node that owns this resource box.
400 * call_data - passed on to other callbacks.
403 * NOTE: I cannot just have two callback routines, since I care which
404 * order that these are executed in, sigh...
408 ActivateWidgetsAndSetResourceString(Widget w,
409 XtPointer node_ptr, XtPointer call_data)
411 SetResourceString(w, node_ptr, call_data);
412 ActivateResourceWidgets(w, node_ptr, call_data);
415 /* Function Name: SetResourceString
416 * Description: Sets the resource label to correspond to the currently
418 * Arguments: w - The widget that invoked this callback, or NULL.
419 * node_ptr - pointer to widget node contating this res box.
420 * call_data - The call data for the action that invoked
426 SetResourceString(Widget w, XtPointer node_ptr, XtPointer junk)
428 static char * malloc_string; /* These are both inited to zero. */
429 static Cardinal malloc_size;
431 WNode * node = (WNode *) node_ptr;
432 ResourceBoxInfo * res_box = node->resources->res_box;
433 char * temp, buf[BUFSIZ * 10]; /* here's hoping it's big enough. */
434 NameInfo * name_node = res_box->name_info;
438 if ((w != NULL) && XtIsSubclass(w, toggleWidgetClass)) {
440 * Only set resources when toggles are activated, not when they are
443 if (!((Boolean)(long) junk))
447 buf[0] = '\0'; /* clear out string. */
450 * Get the widget name/class info.
453 if ((temp = (char *) XawToggleGetCurrent(name_node->sep_leader)) != NULL)
456 for ( ; name_node->next != NULL ; name_node = name_node->next) {
457 temp = (char *) XawToggleGetCurrent(name_node->name_leader);
458 if ( (temp != NULL) && !streq(temp, ANY_RADIO_DATA) ) {
460 temp = (char *) XawToggleGetCurrent(name_node->next->sep_leader);
468 strcat(buf, GetResourceName(res_box));
469 len = strlen(buf) + 2; /* Leave space for ':' and '\0' */
472 XtSetArg(args[0], XtNstring, &temp);
473 XtGetValues(res_box->value_wid, args, ONE);
477 if (len > malloc_size) {
478 malloc_string = XtRealloc(malloc_string, sizeof(char) * len);
482 strcpy(malloc_string, buf);
483 strcat(malloc_string, ":");
485 strcat(malloc_string, temp);
488 XtSetArg(args[0], XtNlabel, malloc_string);
489 XtSetValues(res_box->res_label, args, ONE);
492 /* Function Name: ResourceListCallback
493 * Description: Callback functions for the resource lists. This
494 * routine is essentialy called by the list widgets
495 * Notify action. If action EnableGetVal has been
496 * invoked, ResourceListCallback will perform a
497 * GetValues protocol request.
498 * Arguments: list - the list widget that we are dealing with.
499 * node_ptr - pointer to widget node contating this res box.
504 extern Boolean do_get_values;
507 ResourceListCallback(Widget list, XtPointer node_ptr, XtPointer junk)
510 WNode * node = (WNode *) node_ptr;
511 ResourceBoxInfo * res_box = node->resources->res_box;
513 if (list == res_box->norm_list)
514 o_list = res_box->cons_list;
516 o_list = res_box->norm_list;
519 XawListUnhighlight(o_list);
521 SetResourceString(list, node_ptr, junk);
523 /* get the resource value from the application */
524 if (global_effective_protocol_version >=
525 PROTOCOL_VERSION_ONE_POINT_ONE && do_get_values) {
526 ObtainResource(node_ptr);
527 do_get_values = False;
531 /* Function Name: PopdownResBox
532 * Description: Pops down the resource box.
533 * Arguments: w - UNUSED
534 * shell_ptr - pointer to the shell to pop down.
541 PopdownResBox(Widget w, XtPointer shell_ptr, XtPointer junk)
543 Widget shell = (Widget) shell_ptr;
546 XtDestroyWidget(shell);
551 _AppendResourceString(Widget w, XtPointer res_box_ptr, XtPointer filename_ptr)
555 char buf[BUFSIZ], * resource_string, *filename = (char *) filename_ptr;
556 ResourceBoxInfo * res_box = (ResourceBoxInfo *) res_box_ptr;
559 if (filename != NULL) {
560 if (global_resources.allocated_save_resources_file)
561 XtFree(global_resources.save_resources_file);
563 global_resources.allocated_save_resources_file = TRUE;
565 global_resources.save_resources_file = XtNewString(filename);
568 if ((fp = fopen(global_resources.save_resources_file, "a+")) == NULL) {
569 sprintf(buf, "Unable to open this file for writing, would %s",
570 "you like To try again?");
571 _PopupFileDialog(global_toplevel ,buf,
572 global_resources.save_resources_file,
573 _AppendResourceString, res_box_ptr);
577 XtSetArg(args[0], XtNlabel, &resource_string);
578 XtGetValues(res_box->res_label, args, ONE);
580 XtSetArg(args[0], XtNstring, &value_ptr);
581 XtGetValues(res_box->value_wid, args, ONE);
583 fprintf(fp, "%s %s\n", resource_string, value_ptr);
588 /* Function Name: SaveResource
589 * Description: Save the current resource to your resource file
590 * Arguments: w - any widget in the application.
591 * res_box_ptr - the resource box info.
598 SaveResource(Widget w, XtPointer res_box_ptr, XtPointer junk)
601 * If there is no filename the ask for one, otherwise just save to
605 if (streq(global_resources.save_resources_file, ""))
606 _PopupFileDialog(XtParent(w), "Enter file to dump resources into:",
607 global_resources.save_resources_file,
608 _AppendResourceString, res_box_ptr);
610 _AppendResourceString(w, res_box_ptr, NULL);
613 /* Function Name: _SetResourcesFile
614 * Description: Sets the filename of the file to save the resources to.
615 * Arguments: w - UNUSED
617 * filename_ptr - a pointer to the filename;
623 _SetResourcesFile(Widget w, XtPointer junk, XtPointer filename_ptr)
625 char *filename = (char *) filename_ptr;
627 if (global_resources.allocated_save_resources_file)
628 XtFree(global_resources.save_resources_file);
630 global_resources.allocated_save_resources_file = TRUE;
632 global_resources.save_resources_file = XtNewString(filename);
635 /* Function Name: SetFile
636 * Description: Changes the current save file
637 * Arguments: w - UNUSED.
638 * res_box_ptr - UNUSED.
645 SetFile(Widget w, XtPointer junk, XtPointer garbage)
648 * If there is no filename the ask for one, otherwise just save to
652 _PopupFileDialog(XtParent(w), "Enter file to dump resources into:",
653 global_resources.save_resources_file,
654 _SetResourcesFile, NULL);
657 /* Function Name: ApplyResource
658 * Description: Apply the current resource to the running application.
659 * Arguments: w - any widget in the application.
660 * node_ptr - a pointer to the node containing
661 * the current resouce box.
668 ApplyResource(Widget w, XtPointer node_ptr, XtPointer junk)
670 ProtocolStream * stream = &(global_client.stream);
671 ApplyResourcesInfo info;
672 WNode * node = (WNode *) node_ptr;
674 unsigned short size, i;
678 info.name = GetResourceName(node->resources->res_box);
679 info.class = "IGNORE_ME"; /* Not currently used. */
680 info.stream = stream;
683 XtSetArg(args[0], XtNlabel, &value);
684 XtGetValues(node->resources->res_box->res_label, args, ONE);
686 info.database = NULL;
687 XrmPutLineResource(&(info.database), value);
690 _XEditResResetStream(stream);
691 _XEditResPutString8(stream, info.name); /* Insert name */
692 _XEditResPutString8(stream, XtRString); /* insert type */
698 value = GetResourceValueForSetValues(node, &size);
699 _XEditResPut16(stream, size);
700 for (i = 0; i < size; i++)
701 _XEditResPut8(stream, value[i]);
703 len = stream->current - stream->top;
706 * Insert the widget count, overriden later.
709 _XEditResPut16(stream, 0);
711 ExecuteOverAllNodes(node->tree_info->top_node,
712 CreateSetValuesCommand, (XtPointer) &info);
714 if (info.count > 0) {
715 *(stream->top + len++) = info.count >> XER_NBBY; /* Set the correct */
716 *(stream->top + len) = info.count; /* count. */
718 SetCommand(node->tree_info->tree_widget, LocalSetValues, NULL);
721 SetMessage(global_screen_data.info_label,
724 XrmDestroyDatabase(info.database);
727 /* Function Name: ObtainResource
728 * Description: Obtain the current resource from the running application.
729 * Arguments: node_ptr - a pointer to the node containing
730 * the current resouce box.
736 ObtainResource(XtPointer node_ptr)
738 ProtocolStream * stream = &(global_client.stream);
739 ObtainResourcesInfo info;
740 WNode * node = (WNode *) node_ptr;
744 info.name = GetResourceName(node->resources->res_box);
745 info.class = "IGNORE_ME"; /* Not currently used. */
746 info.stream = stream;
749 XtSetArg(args[0], XtNlabel, &value);
750 XtGetValues(node->resources->res_box->res_label, args, ONE);
752 info.database = NULL;
753 XrmPutLineResource(&(info.database), value);
755 _XEditResResetStream(stream);
756 _XEditResPutString8(stream, info.name); /* insert name */
759 * Insert the widget count, always 1
762 _XEditResPut16(stream, 1);
764 /*CreateGetValuesCommand(node, (XtPointer)&info); Inserts widget */
767 InsertWidgetFromNode(stream, node);
769 SetCommand(node->tree_info->tree_widget, LocalGetValues, NULL);
772 /* Function Name: CreateSetValuesCommand
773 * Description: Creates the SetValues command if this widget
774 * matches the resource string in the database.
775 * Arguments: node - the current node.
776 * info_ptr - the pointer to the apply info.
781 CreateSetValuesCommand(WNode *node, XtPointer info_ptr)
783 ApplyResourcesInfo * info = (ApplyResourcesInfo *) info_ptr;
784 XrmNameList name_quarks;
785 XrmClassList class_quarks;
786 char ** names, **classes;
788 GetNamesAndClasses(node, &names, &classes);
789 name_quarks = (XrmNameList) Quarkify(names, info->name);
790 class_quarks = (XrmNameList) Quarkify(classes, info->class);
792 if (CheckDatabase(info->database, name_quarks, class_quarks)) {
793 InsertWidgetFromNode(info->stream, node);
797 XtFree((char *)names);
798 XtFree((char *)classes);
799 XtFree((char *)name_quarks);
800 XtFree((char *)class_quarks);
803 /* Function Name: CreateGetValuesCommand
804 * Description: Creates the GetValues command.
805 * Arguments: node - the current node.
806 * info_ptr - the pointer to the apply info.
813 CreateGetValuesCommand(WNode *node, XtPointer info_ptr)
815 ApplyResourcesInfo * info = (ApplyResourcesInfo *) info_ptr;
816 XrmNameList name_quarks;
817 XrmClassList class_quarks;
818 char ** names, **classes;
820 GetNamesAndClasses(node, &names, &classes);
821 name_quarks = (XrmNameList) Quarkify(names, info->name);
822 class_quarks = (XrmNameList) Quarkify(classes, info->class);
824 if (CheckDatabase(info->database, name_quarks, class_quarks)) {
825 InsertWidgetFromNode(info->stream, node);
829 XtFree((char *)names);
830 XtFree((char *)classes);
831 XtFree((char *)name_quarks);
832 XtFree((char *)class_quarks);
837 /* Function Name: ActivateResourceWidgets
838 * Description: Activates all widgets that match this resource.
839 * Arguments: w - UNUSED.
840 * node_ptr - the node that owns this resource box.
847 ActivateResourceWidgets(Widget w, XtPointer node_ptr, XtPointer junk)
849 WNode * node = (WNode *) node_ptr;
850 ApplyResourcesInfo info;
854 info.name = GetResourceName(node->resources->res_box);
855 info.class = "IGNORE_ME"; /* Not currently used. */
864 XtSetArg(args[0], XtNlabel, &line);
865 XtGetValues(node->resources->res_box->res_label, args, ONE);
867 info.database = NULL;
868 XrmPutLineResource(&(info.database), line);
871 ExecuteOverAllNodes(node->tree_info->top_node,
872 SetOnlyMatchingWidgets, (XtPointer) &info);
874 XrmDestroyDatabase(info.database);
877 /* Function Name: SetOnlyMatchingWidgets
878 * Description: Activates all widgets in the tree that match this
879 * resource specifiction.
880 * Arguments: node - the current node.
881 * info_ptr - the pointer to the apply info.
886 SetOnlyMatchingWidgets(WNode *node, XtPointer info_ptr)
888 ApplyResourcesInfo * info = (ApplyResourcesInfo *) info_ptr;
889 XrmNameList name_quarks;
890 XrmClassList class_quarks;
891 char ** names, **classes;
895 GetNamesAndClasses(node, &names, &classes);
896 name_quarks = (XrmNameList) Quarkify(names, info->name);
897 class_quarks = (XrmNameList) Quarkify(classes, info->class);
899 state = CheckDatabase(info->database, name_quarks, class_quarks);
901 XtSetArg(args[0], XtNstate, state);
902 XtSetValues(node->widget, args, ONE);
903 TreeToggle(node->widget, (XtPointer) node, (XtPointer)(long) state);
905 XtFree((char *)names);
906 XtFree((char *)classes);
907 XtFree((char *)name_quarks);
908 XtFree((char *)class_quarks);