1
/* $XConsortium: RegEdit.c /main/5 1995/07/15 20:44:04 drk $ */
3
* @OPENGROUP_COPYRIGHT@
5
* Copyright (c) 1990, 1991, 1992, 1993 Open Software Foundation, Inc.
6
* Copyright (c) 1996, 1997, 1998, 1999, 2000 The Open Group
7
* ALL RIGHTS RESERVED (MOTIF). See the file named COPYRIGHT.MOTIF for
8
* the full copyright text.
10
* This software is subject to an open license. It may only be
11
* used on, with or for operating systems which are themselves open
12
* source systems. You must contact The Open Group for a license
13
* allowing distribution and sublicensing of this software on, with,
14
* or for operating systems which are not Open Source programs.
16
* See http://www.opengroup.org/openmotif/license for full
17
* details of the license agreement. Any use, reproduction, or
18
* distribution of the program constitutes recipient's acceptance of
21
* EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS
22
* PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
23
* KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
24
* WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY
25
* OR FITNESS FOR A PARTICULAR PURPOSE
27
* EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT
28
* NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT,
29
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30
* DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED
31
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
33
* ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE
34
* EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE
35
* POSSIBILITY OF SUCH DAMAGES.
43
#include <X11/ShellP.h>
48
/* static forward. move from global in the original Editres code */
49
static void _XEditResCheckMessages();
50
static void _XEditResPutString8();
51
static void _XEditResPut8();
52
static void _XEditResPut16();
53
static void _XEditResPut32();
54
static void _XEditResPutWidgetInfo();
55
static void _XEditResResetStream();
56
static Boolean _XEditResGet8();
57
static Boolean _XEditResGet16();
58
static Boolean _XEditResGetSigned16();
59
static Boolean _XEditResGet32();
60
static Boolean _XEditResGetString8();
61
static Boolean _XEditResGetWidgetInfo();
63
/* the only entry point here */
65
XmdRegisterEditres(Widget toplevel)
67
XtAddEventHandler(toplevel, (EventMask) 0, TRUE,
68
_XEditResCheckMessages, NULL);
72
/************************************************************
74
* Dump the content of the R5 lib/Xmu/EditresCom.c module.
75
* just move global as static.
77
************************************************************/
79
#define _XEditResPutBool _XEditResPut8
80
#define _XEditResPutResourceType _XEditResPut8
82
/************************************************************
84
* Local structure definitions.
86
************************************************************/
88
typedef enum { BlockNone, BlockSetValues, BlockAll } EditresBlock;
90
typedef struct _SetValuesEvent {
91
EditresCommand type; /* first field must be type. */
93
unsigned short num_entries; /* number of set values requests. */
97
unsigned short value_len;
100
typedef struct _SVErrorInfo {
101
SetValuesEvent * event;
102
ProtocolStream * stream;
103
unsigned short * count;
107
typedef struct _FindChildEvent {
108
EditresCommand type; /* first field must be type. */
109
WidgetInfo * widgets;
113
typedef struct _GenericGetEvent {
114
EditresCommand type; /* first field must be type. */
115
WidgetInfo * widgets;
116
unsigned short num_entries; /* number of set values requests. */
117
} GenericGetEvent, GetResEvent, GetGeomEvent;
120
* Things that are common to all events.
123
typedef struct _AnyEvent {
124
EditresCommand type; /* first field must be type. */
125
WidgetInfo * widgets;
132
typedef union _EditresEvent {
134
SetValuesEvent set_values_event;
135
GetResEvent get_resources_event;
136
GetGeomEvent get_geometry_event;
137
FindChildEvent find_child_event;
140
typedef struct _Globals {
142
SVErrorInfo error_info;
143
ProtocolStream stream;
144
ProtocolStream * command_stream; /* command stream. */
147
#define CURRENT_PROTOCOL_VERSION 4L
149
#define streq(a,b) (strcmp( (a), (b) ) == 0)
151
static Atom res_editor_command, res_editor_protocol, client_value;
153
static Globals globals;
155
static void SendFailure(), SendCommand(), InsertWidget(), ExecuteCommand();
156
static void FreeEvent(), ExecuteSetValues(), ExecuteGetGeometry();
157
static void ExecuteGetResources();
159
static void GetCommand();
160
static void LoadResources();
161
static Boolean IsChild();
162
static void DumpChildren();
163
static char *DumpWidgets(), *DoSetValues(), *DoFindChild();
164
static char *DoGetGeometry(), *DoGetResources();
166
/************************************************************
168
* Resource Editor Communication Code
170
************************************************************/
172
/* Function Name: _XEditResCheckMessages
173
* Description: This callback routine is set on all shell widgets,
174
* and checks to see if a client message event
175
* has come from the resource editor.
176
* Arguments: w - the shell widget.
177
* data - *** UNUSED ***
178
* event - The X Event that triggered this handler.
179
* cont - *** UNUSED ***.
185
_XEditResCheckMessages(w, data, event, cont)
193
static Boolean first_time = FALSE;
194
static Atom res_editor, res_comm;
197
if (event->type == ClientMessage) {
198
XClientMessageEvent * c_event = (XClientMessageEvent *) event;
203
res_editor = XInternAtom(dpy, EDITRES_NAME, False);
204
res_editor_command = XInternAtom(dpy, EDITRES_COMMAND_ATOM, False);
205
res_editor_protocol = XInternAtom(dpy, EDITRES_PROTOCOL_ATOM,
208
/* Used in later procedures. */
209
client_value = XInternAtom(dpy, EDITRES_CLIENT_VALUE, False);
213
if ((c_event->message_type != res_editor) ||
214
(c_event->format != EDITRES_SEND_EVENT_FORMAT))
217
time = c_event->data.l[0];
218
res_comm = c_event->data.l[1];
219
ident = (ResIdent) c_event->data.l[2];
220
if (c_event->data.l[3] != CURRENT_PROTOCOL_VERSION) {
221
_XEditResResetStream(&globals.stream);
222
_XEditResPut8(&globals.stream, CURRENT_PROTOCOL_VERSION);
223
SendCommand(w, res_comm, ident, ProtocolMismatch, &globals.stream);
227
XtGetSelectionValue(w, res_comm, res_editor_command,
228
GetCommand, (XtPointer) (long) ident, time);
232
/* Function Name: BuildEvent
233
* Description: Takes the info out the protocol stream an constructs
234
* the proper event structure.
235
* Arguments: w - widget to own selection, in case of error.
236
* sel - selection to send error message beck in.
237
* data - the data for the request.
238
* ident - the id number we are looking for.
239
* length - length of request.
240
* Returns: the event, or NULL.
243
#define ERROR_MESSAGE ("Client: Improperly formatted protocol request")
245
static EditresEvent *
246
BuildEvent(w, sel, data, ident, length)
251
unsigned long length;
253
EditresEvent * event;
254
ProtocolStream alloc_stream, *stream;
256
register unsigned int i;
258
stream = &alloc_stream; /* easier to think of it this way... */
260
stream->current = stream->top = (unsigned char *) data;
261
stream->size = HEADER_SIZE; /* size of header. */
264
* Retrieve the Header.
267
if (length < HEADER_SIZE) {
268
SendFailure(w, sel, ident, Failure, ERROR_MESSAGE);
272
(void) _XEditResGet8(stream, &temp);
273
if (temp != ident) /* Id's don't match, ignore request. */
276
event = (EditresEvent *) XtCalloc(sizeof(EditresEvent), 1);
278
(void) _XEditResGet8(stream, &temp);
279
event->any_event.type = (EditresCommand) temp;
280
(void) _XEditResGet32(stream, &(stream->size));
281
stream->top = stream->current; /* reset stream to top of value.*/
284
* Now retrieve the data segment.
287
switch(event->any_event.type) {
289
break; /* no additional info */
292
SetValuesEvent * sv_event = (SetValuesEvent *) event;
294
if ( !(_XEditResGetString8(stream, &(sv_event->name)) &&
295
_XEditResGetString8(stream, &(sv_event->res_type))))
301
* Since we need the value length, we have to pull the
305
if (!_XEditResGet16(stream, &(sv_event->value_len)))
308
sv_event->value = XtMalloc(sizeof(char) *
309
(sv_event->value_len + 1));
311
for (i = 0; i < sv_event->value_len; i++) {
312
if (!_XEditResGet8(stream,
313
(unsigned char *) sv_event->value + i))
318
((char*)sv_event->value)[i] = '\0'; /* NULL terminate that sucker. */
320
if (!_XEditResGet16(stream, &(sv_event->num_entries)))
323
sv_event->widgets = (WidgetInfo *)
324
XtCalloc(sizeof(WidgetInfo), sv_event->num_entries);
326
for (i = 0; i < sv_event->num_entries; i++) {
327
if (!_XEditResGetWidgetInfo(stream, sv_event->widgets + i))
334
FindChildEvent * find_event = (FindChildEvent *) event;
336
find_event->widgets = (WidgetInfo *)
337
XtCalloc(sizeof(WidgetInfo), 1);
339
if (!(_XEditResGetWidgetInfo(stream, find_event->widgets) &&
340
_XEditResGetSigned16(stream, &(find_event->x)) &&
341
_XEditResGetSigned16(stream, &(find_event->y))))
351
GenericGetEvent * get_event = (GenericGetEvent *) event;
353
if (!_XEditResGet16(stream, &(get_event->num_entries)))
356
get_event->widgets = (WidgetInfo *)
357
XtCalloc(sizeof(WidgetInfo), get_event->num_entries);
358
for (i = 0; i < get_event->num_entries; i++) {
359
if (!_XEditResGetWidgetInfo(stream, get_event->widgets + i))
368
sprintf(buf, "Unknown Protocol request %d.",event->any_event.type);
369
SendFailure(w, sel, ident, buf);
377
SendFailure(w, sel, ident, ERROR_MESSAGE);
382
/* Function Name: FreeEvent
383
* Description: Frees the event structure and any other pieces
384
* in it that need freeing.
385
* Arguments: event - the event to free.
391
EditresEvent * event;
393
if (event->any_event.widgets != NULL) {
394
XtFree((char *)event->any_event.widgets->ids);
395
XtFree((char *)event->any_event.widgets);
398
if (event->any_event.type == SetValues) {
399
XtFree(event->set_values_event.name); /* XtFree does not free if */
400
XtFree(event->set_values_event.res_type); /* value is NULL. */
403
XtFree((char *)event);
406
/* Function Name: GetCommand
407
* Description: Gets the Command out of the selection asserted by the
409
* Arguments: (See Xt XtConvertSelectionProc)
410
* data - contains the ident number for the command.
416
GetCommand(w, data, selection, type, value, length, format)
418
XtPointer data, value;
419
Atom *selection, *type;
420
unsigned long *length;
423
ResIdent ident = (ResIdent) (long) data;
424
EditresEvent * event;
426
if ( (*type != res_editor_protocol) || (*format != EDITRES_FORMAT) )
429
if ((event = BuildEvent(w, *selection, value, ident, *length)) != NULL) {
430
ExecuteCommand(w, *selection, ident, event);
435
/* Function Name: ExecuteCommand
436
* Description: Executes a command string received from the
438
* Arguments: w - a widget.
439
* command - the command to execute.
440
* value - the associated with the command.
448
ExecuteCommand(w, sel, ident, event)
452
EditresEvent * event;
457
if (globals.block == BlockAll) {
458
SendFailure(w, sel, ident,
459
"This client has blocked all Editres commands.");
462
else if ((globals.block == BlockSetValues) &&
463
(event->any_event.type == SetValues)) {
464
SendFailure(w, sel, ident,
465
"This client has blocked all SetValues requests.");
469
switch(event->any_event.type) {
480
func = DoGetGeometry;
483
func = DoGetResources;
488
sprintf(buf,"Unknown Protocol request %d.",event->any_event.type);
489
SendFailure(w, sel, ident, buf);
494
_XEditResResetStream(&globals.stream);
495
if ((str = (*func)(w, event, &globals.stream)) == NULL)
496
SendCommand(w, sel, ident, PartialSuccess, &globals.stream);
498
SendFailure(w, sel, ident, str);
503
/* Function Name: ConvertReturnCommand
504
* Description: Converts a selection.
505
* Arguments: w - the widget that owns the selection.
506
* selection - selection to convert.
507
* target - target type for this selection.
508
* type_ret - type of the selection.
509
* value_ret - selection value;
510
* length_ret - lenght of this selection.
511
* format_ret - the format the selection is in.
512
* Returns: True if conversion was sucessful.
517
ConvertReturnCommand(w, selection, target,
518
type_ret, value_ret, length_ret, format_ret)
520
Atom * selection, * target, * type_ret;
521
XtPointer *value_ret;
522
unsigned long * length_ret;
526
* I assume the intrinsics give me the correct selection back.
529
if ((*target != client_value))
532
*type_ret = res_editor_protocol;
533
*value_ret = (XtPointer) globals.command_stream->real_top;
534
*length_ret = globals.command_stream->size + HEADER_SIZE;
535
*format_ret = EDITRES_FORMAT;
540
/* Function Name: CommandDone
541
* Description: done with the selection.
542
* Arguments: *** UNUSED ***
548
CommandDone(widget, selection, target)
553
/* Keep the toolkit from automaticaly freeing the selection value */
556
/* Function Name: SendFailure
557
* Description: Sends a failure message.
558
* Arguments: w - the widget to own the selection.
559
* sel - the selection to assert.
560
* ident - the identifier.
561
* str - the error message.
566
SendFailure(w, sel, ident, str)
572
_XEditResResetStream(&globals.stream);
573
_XEditResPutString8(&globals.stream, str);
574
SendCommand(w, sel, ident, Failure, &globals.stream);
577
/* Function Name: BuildReturnPacket
578
* Description: Builds a return packet, given the data to send.
579
* Arguments: ident - the identifier.
580
* command - the command code.
581
* stream - the protocol stream.
582
* Returns: packet - the packet to send.
586
BuildReturnPacket(ident, command, stream)
588
EditresCommand command;
589
ProtocolStream * stream;
591
long old_alloc, old_size;
592
unsigned char * old_current;
595
* We have cleverly keep enough space at the top of the header
596
* for the return protocol stream, so all we have to do is
601
* Fool the insert routines into putting the header in the right
602
* place while being damn sure not to realloc (that would be very bad.
605
old_current = stream->current;
606
old_alloc = stream->alloc;
607
old_size = stream->size;
609
stream->current = stream->real_top;
610
stream->alloc = stream->size + (2 * HEADER_SIZE);
612
_XEditResPut8(stream, ident);
613
_XEditResPut8(stream, (unsigned char) command);
614
_XEditResPut32(stream, old_size);
616
stream->alloc = old_alloc;
617
stream->current = old_current;
618
stream->size = old_size;
620
return((XtPointer) stream->real_top);
623
/* Function Name: SendCommand
624
* Description: Builds a return command line.
625
* Arguments: w - the widget to own the selection.
626
* sel - the selection to assert.
627
* ident - the identifier.
628
* command - the command code.
629
* stream - the protocol stream.
634
SendCommand(w, sel, ident, command, stream)
638
EditresCommand command;
639
ProtocolStream * stream;
641
BuildReturnPacket(ident, command, stream);
642
globals.command_stream = stream;
645
* I REALLY want to own the selection. Since this was not triggered
646
* by a user action, and I am the only one using this atom it is safe to
650
XtOwnSelection(w, sel, CurrentTime,
651
ConvertReturnCommand, NULL, CommandDone);
654
/************************************************************
656
* Generic Utility Functions.
658
************************************************************/
660
/* Function Name: FindChildren
661
* Description: Retuns all children (popup, normal and otherwise)
663
* Arguments: parent - the parent widget.
664
* children - the list of children.
665
* normal - return normal children.
666
* popup - return popup children.
667
* Returns: the number of children.
671
FindChildren(parent, children, normal, popup)
672
Widget parent, **children;
673
Boolean normal, popup;
675
CompositeWidget cw = (CompositeWidget) parent;
676
int i, num_children, current = 0;
680
if (XtIsWidget(parent) && popup)
681
num_children += parent->core.num_popups;
683
if (XtIsComposite(parent) && normal)
684
num_children += cw->composite.num_children;
686
if (num_children == 0) {
691
*children =(Widget*) XtMalloc((Cardinal) sizeof(Widget) * num_children);
693
if (XtIsComposite(parent) && normal)
694
for (i = 0; i < cw->composite.num_children; i++,current++)
695
(*children)[current] = cw->composite.children[i];
697
if (XtIsWidget(parent) && popup)
698
for ( i = 0; i < parent->core.num_popups; i++, current++)
699
(*children)[current] = parent->core.popup_list[i];
701
return(num_children);
704
/* Function Name: IsChild
705
* Description: check to see of child is a child of parent.
706
* Arguments: top - the top of the tree.
707
* parent - the parent widget.
713
IsChild(top, parent, child)
714
Widget top, parent, child;
720
return(top == child);
722
num_children = FindChildren(parent, &children, TRUE, TRUE);
724
for (i = 0; i < num_children; i++) {
725
if (children[i] == child) {
726
XtFree((char *)children);
731
XtFree((char *)children);
735
/* Function Name: VerifyWidget
736
* Description: Makes sure all the widgets still exist.
737
* Arguments: w - any widget in the tree.
738
* info - the info about the widget to verify.
739
* Returns: an error message or NULL.
743
VerifyWidget(w, info)
750
register Widget parent;
751
register unsigned long * child;
753
for (top = w; XtParent(top) != NULL; top = XtParent(top)) {}
760
if (!IsChild(top, parent, (Widget) *child))
761
return(XtNewString("This widget no longer exists in the client."));
763
if (++count == info->num_widgets)
766
parent = (Widget) *child++;
769
info->real_widget = (Widget) *child;
773
/************************************************************
775
* Code to Perform SetValues operations.
777
************************************************************/
780
/* Function Name: DoSetValues
781
* Description: performs the setvalues requested.
782
* Arguments: w - a widget in the tree.
783
* event - the event that caused this action.
784
* stream - the protocol stream to add.
789
DoSetValues(w, event, stream)
791
EditresEvent * event;
792
ProtocolStream * stream;
796
unsigned short count = 0;
797
SetValuesEvent * sv_event = (SetValuesEvent *) event;
799
_XEditResPut16(stream, count); /* insert 0, will be overwritten later. */
801
for (i = 0 ; i < sv_event->num_entries; i++) {
802
if ((str = VerifyWidget(w, &(sv_event->widgets[i]))) != NULL) {
803
_XEditResPutWidgetInfo(stream, &(sv_event->widgets[i]));
804
_XEditResPutString8(stream, str);
809
ExecuteSetValues(sv_event->widgets[i].real_widget,
810
sv_event, sv_event->widgets + i, stream, &count);
814
* Overwrite the first 2 bytes with the real count.
817
*(stream->top) = count >> XER_NBBY;
818
*(stream->top + 1) = count;
822
/* Function Name: HandleToolkitErrors
823
* Description: Handles X Toolkit Errors.
824
* Arguments: name - name of the error.
825
* type - type of the error.
826
* class - class of the error.
827
* msg - the default message.
828
* params, num_params - the extra parameters for this message.
834
HandleToolkitErrors(name, type, class, msg, params, num_params)
835
String name, type, class, msg, *params;
836
Cardinal * num_params;
838
SVErrorInfo * info = &globals.error_info;
841
if ( streq(name, "unknownType") )
842
sprintf(buf, "The `%s' resource is not used by this widget.",
844
else if ( streq(name, "noColormap") )
845
sprintf(buf, msg, params[0]);
846
else if (streq(name, "conversionFailed") || streq(name, "conversionError"))
848
if (streq(info->event->value, XtRString))
850
"Could not convert the string '%s' for the `%s' resource.",
851
(char*)info->event->value, info->event->name);
853
sprintf(buf, "Could not convert the `%s' resource.",
857
sprintf(buf, "Name: %s, Type: %s, Class: %s, Msg: %s",
858
name, type, class, msg);
861
* Insert this info into the protocol stream, and update the count.
865
_XEditResPutWidgetInfo(info->stream, info->entry);
866
_XEditResPutString8(info->stream, buf);
869
/* Function Name: ExecuteSetValues
870
* Description: Performs a setvalues for a given command.
871
* Arguments: w - the widget to perform the set_values on.
872
* sv_event - the set values event.
873
* sv_info - the set_value info.
878
ExecuteSetValues(w, sv_event, entry, stream, count)
880
SetValuesEvent * sv_event;
882
ProtocolStream * stream;
883
unsigned short * count;
885
XtErrorMsgHandler old;
887
SVErrorInfo * info = &globals.error_info;
888
info->event = sv_event; /* No data can be passed to */
889
info->stream = stream; /* an error handler, so we */
890
info->count = count; /* have to use a global, YUCK... */
893
old = XtAppSetWarningMsgHandler(XtWidgetToApplicationContext(w),
894
HandleToolkitErrors);
896
XtVaSetValues(w, XtVaTypedArg,
897
sv_event->name, sv_event->res_type,
898
sv_event->value, sv_event->value_len,
901
(void)XtAppSetWarningMsgHandler(XtWidgetToApplicationContext(w), old);
905
/************************************************************
907
* Code for Creating and dumping widget tree.
909
************************************************************/
911
/* Function Name: DumpWidgets
912
* Description: Given a widget it builds a protocol packet
913
* containing the entire widget heirarchy.
914
* Arguments: w - a widget in the tree.
915
* event - the event that caused this action.
916
* stream - the protocol stream to add.
922
DumpWidgets(w, event, stream)
924
EditresEvent * event; /* UNUSED */
925
ProtocolStream * stream;
927
unsigned short count = 0;
929
/* Find Tree's root. */
930
for ( ; XtParent(w) != NULL; w = XtParent(w)) {}
933
* hold space for count, overwritten later.
936
_XEditResPut16(stream, (unsigned int) 0);
938
DumpChildren(w, stream, &count);
941
* Overwrite the first 2 bytes with the real count.
944
*(stream->top) = count >> XER_NBBY;
945
*(stream->top + 1) = count;
949
/* Function Name: DumpChildren
950
* Description: Adds a child's name to the list.
951
* Arguments: w - the widget to dump.
952
* stream - the stream to dump to.
953
* count - number of dumps we have performed.
957
/* This is a trick/kludge. To make shared libraries happier (linking
958
* against Xmu but not linking against Xt, and apparently even work
959
* as we desire on SVR4, we need to avoid an explicit data reference
960
* to applicationShellWidgetClass. XtIsTopLevelShell is known
961
* (implementation dependent assumption!) to use a bit flag. So we
962
* go that far. Then, we test whether it is an applicationShellWidget
963
* class by looking for an explicit class name. Seems pretty safe.
965
static Bool isApplicationShell(w)
968
register WidgetClass c;
970
if (!XtIsTopLevelShell(w))
972
for (c = XtClass(w); c; c = c->core_class.superclass) {
973
if (!strcmp(c->core_class.class_name, "ApplicationShell"))
980
DumpChildren(w, stream, count)
982
ProtocolStream * stream;
983
unsigned short *count;
987
unsigned long window;
992
InsertWidget(stream, w); /* Insert the widget into the stream. */
994
_XEditResPutString8(stream, XtName(w)); /* Insert name */
996
if (isApplicationShell(w))
997
class = ((ApplicationShellWidget) w)->application.class;
999
class = XtClass(w)->core_class.class_name;
1001
_XEditResPutString8(stream, class); /* Insert class */
1004
if (XtIsRealized(w))
1005
window = XtWindow(w);
1007
window = EDITRES_IS_UNREALIZED;
1009
window = EDITRES_IS_OBJECT;
1011
_XEditResPut32(stream, window); /* Insert window id. */
1014
* Find children and recurse.
1017
num_children = FindChildren(w, &children, TRUE, TRUE);
1018
for (i = 0; i < num_children; i++)
1019
DumpChildren(children[i], stream, count);
1021
XtFree((char *)children);
1024
/************************************************************
1026
* Code for getting the geometry of widgets.
1028
************************************************************/
1030
/* Function Name: DoGetGeometry
1031
* Description: retrieves the Geometry of each specified widget.
1032
* Arguments: w - a widget in the tree.
1033
* event - the event that caused this action.
1034
* stream - the protocol stream to add.
1039
DoGetGeometry(w, event, stream)
1041
EditresEvent * event;
1042
ProtocolStream * stream;
1046
GetGeomEvent * geom_event = (GetGeomEvent *) event;
1048
_XEditResPut16(stream, geom_event->num_entries);
1050
for (i = 0 ; i < geom_event->num_entries; i++) {
1053
* Send out the widget id.
1056
_XEditResPutWidgetInfo(stream, &(geom_event->widgets[i]));
1057
if ((str = VerifyWidget(w, &(geom_event->widgets[i]))) != NULL) {
1058
_XEditResPutBool(stream, True); /* an error occured. */
1059
_XEditResPutString8(stream, str); /* set message. */
1063
ExecuteGetGeometry(geom_event->widgets[i].real_widget, stream);
1068
/* Function Name: ExecuteGetGeometry
1069
* Description: Gets the geometry for each widget specified.
1070
* Arguments: w - the widget to get geom on.
1071
* stream - stream to append to.
1072
* Returns: True if no error occured.
1076
ExecuteGetGeometry(w, stream)
1078
ProtocolStream * stream;
1081
Boolean mapped_when_man;
1082
Dimension width, height, border_width;
1084
Cardinal num_args = 0;
1087
if ( !XtIsRectObj(w) || (XtIsWidget(w) && !XtIsRealized(w)) ) {
1088
_XEditResPutBool(stream, False); /* no error. */
1089
_XEditResPutBool(stream, False); /* not visable. */
1090
for (i = 0; i < 5; i++) /* fill in extra space with 0's. */
1091
_XEditResPut16(stream, 0);
1095
XtSetArg(args[num_args], XtNwidth, &width); num_args++;
1096
XtSetArg(args[num_args], XtNheight, &height); num_args++;
1097
XtSetArg(args[num_args], XtNborderWidth, &border_width); num_args++;
1098
XtSetArg(args[num_args], XtNmappedWhenManaged, &mapped_when_man);
1100
XtGetValues(w, args, num_args);
1102
if (!(XtIsManaged(w) && mapped_when_man) && XtIsWidget(w)) {
1103
XWindowAttributes attrs;
1106
* The toolkit does not maintain mapping state, we have
1107
* to go to the server.
1110
if (XGetWindowAttributes(XtDisplay(w), XtWindow(w), &attrs) != 0) {
1111
if (attrs.map_state != IsViewable) {
1112
_XEditResPutBool(stream, False); /* no error. */
1113
_XEditResPutBool(stream, False); /* not visable. */
1114
for (i = 0; i < 5; i++) /* fill in extra space with 0's. */
1115
_XEditResPut16(stream, 0);
1120
_XEditResPut8(stream, True); /* Error occured. */
1121
_XEditResPutString8(stream, "XGetWindowAttributes failed.");
1126
XtTranslateCoords(w, -((int) border_width), -((int) border_width), &x, &y);
1128
_XEditResPutBool(stream, False); /* no error. */
1129
_XEditResPutBool(stream, True); /* Visable. */
1130
_XEditResPut16(stream, x);
1131
_XEditResPut16(stream, y);
1132
_XEditResPut16(stream, width);
1133
_XEditResPut16(stream, height);
1134
_XEditResPut16(stream, border_width);
1137
/************************************************************
1139
* Code for executing FindChild.
1141
************************************************************/
1143
/* Function Name: PositionInChild
1144
* Description: returns true if this location is in the child.
1145
* Arguments: child - the child widget to check.
1146
* x, y - location of point to check in the parent's
1148
* Returns: TRUE if the position is in this child.
1152
PositionInChild(child, x, y)
1158
Dimension width, height, border_width;
1159
Position child_x, child_y;
1160
Boolean mapped_when_managed;
1162
if (!XtIsRectObj(child)) /* we must at least be a rect obj. */
1166
XtSetArg(args[num], XtNmappedWhenManaged, &mapped_when_managed); num++;
1167
XtSetArg(args[num], XtNwidth, &width); num++;
1168
XtSetArg(args[num], XtNheight, &height); num++;
1169
XtSetArg(args[num], XtNx, &child_x); num++;
1170
XtSetArg(args[num], XtNy, &child_y); num++;
1171
XtSetArg(args[num], XtNborderWidth, &border_width); num++;
1172
XtGetValues(child, args, num);
1175
* The only way we will know of the widget is mapped is to see if
1176
* mapped when managed is True and this is a managed child. Otherwise
1177
* we will have to ask the server if this window is mapped.
1180
if (XtIsWidget(child) && !(mapped_when_managed && XtIsManaged(child)) ) {
1181
XWindowAttributes attrs;
1183
if (XGetWindowAttributes(XtDisplay(child),
1184
XtWindow(child), &attrs) != 0) {
1187
else if (attrs.map_state != IsViewable)
1191
return (x >= child_x) &&
1192
(x <= (child_x + (Position)width + 2 * (Position)border_width)) &&
1194
(y <= (child_y + (Position)height + 2 * (Position)border_width));
1197
/* Function Name: _FindChild
1198
* Description: Finds the child that actually contatians the point shown.
1199
* Arguments: parent - a widget that is known to contain the point
1201
* x, y - The point in coordinates relative to the
1207
_FindChild(parent, x, y)
1212
int i = FindChildren(parent, &children, TRUE, FALSE);
1217
if (PositionInChild(children[i], x, y)) {
1218
Widget child = children[i];
1220
XtFree((char *)children);
1221
return(_FindChild(child, x - child->core.x, y - child->core.y));
1225
XtFree((char *)children);
1229
/* Function Name: DoFindChild
1230
* Description: finds the child that contains the location specified.
1231
* Arguments: w - a widget in the tree.
1232
* event - the event that caused this action.
1233
* stream - the protocol stream to add.
1234
* Returns: an allocated error message if something went horribly
1235
* wrong and no set values were performed, else NULL.
1239
DoFindChild(w, event, stream)
1241
EditresEvent * event;
1242
ProtocolStream * stream;
1245
Widget parent, child;
1246
Position parent_x, parent_y;
1247
FindChildEvent * find_event = (FindChildEvent *) event;
1249
if ((str = VerifyWidget(w, find_event->widgets)) != NULL)
1252
parent = find_event->widgets->real_widget;
1254
XtTranslateCoords(parent, (Position) 0, (Position) 0,
1255
&parent_x, &parent_y);
1257
child = _FindChild(parent, find_event->x - (int) parent_x,
1258
find_event->y - (int) parent_y);
1260
InsertWidget(stream, child);
1264
/************************************************************
1266
* Procedures for performing GetResources.
1268
************************************************************/
1270
/* Function Name: DoGetResources
1271
* Description: Gets the Resources associated with the widgets passed.
1272
* Arguments: w - a widget in the tree.
1273
* event - the event that caused this action.
1274
* stream - the protocol stream to add.
1279
DoGetResources(w, event, stream)
1281
EditresEvent * event;
1282
ProtocolStream * stream;
1286
GetResEvent * res_event = (GetResEvent *) event;
1288
_XEditResPut16(stream, res_event->num_entries); /* number of replys */
1290
for (i = 0 ; i < res_event->num_entries; i++) {
1292
* Send out the widget id.
1294
_XEditResPutWidgetInfo(stream, &(res_event->widgets[i]));
1295
if ((str = VerifyWidget(w, &(res_event->widgets[i]))) != NULL) {
1296
_XEditResPutBool(stream, True); /* an error occured. */
1297
_XEditResPutString8(stream, str); /* set message. */
1301
_XEditResPutBool(stream, False); /* no error occured. */
1302
ExecuteGetResources(res_event->widgets[i].real_widget,
1309
/* Function Name: ExecuteGetResources.
1310
* Description: Gets the resources for any individual widget.
1311
* Arguments: w - the widget to get resources on.
1312
* stream - the protocol stream.
1317
ExecuteGetResources(w, stream)
1319
ProtocolStream * stream;
1321
XtResourceList norm_list, cons_list;
1322
Cardinal num_norm, num_cons;
1326
* Get Normal Resources.
1329
XtGetResourceList(XtClass(w), &norm_list, &num_norm);
1331
if (XtParent(w) != NULL)
1332
XtGetConstraintResourceList(XtClass(XtParent(w)),&cons_list,&num_cons);
1336
_XEditResPut16(stream, num_norm + num_cons); /* how many resources. */
1339
* Insert all the normal resources.
1342
for ( i = 0; i < (int) num_norm; i++) {
1343
_XEditResPutResourceType(stream, NormalResource);
1344
_XEditResPutString8(stream, norm_list[i].resource_name);
1345
_XEditResPutString8(stream, norm_list[i].resource_class);
1346
_XEditResPutString8(stream, norm_list[i].resource_type);
1348
XtFree((char *) norm_list);
1351
* Insert all the constraint resources.
1355
for ( i = 0; i < (int) num_cons; i++) {
1356
_XEditResPutResourceType(stream, ConstraintResource);
1357
_XEditResPutString8(stream, cons_list[i].resource_name);
1358
_XEditResPutString8(stream, cons_list[i].resource_class);
1359
_XEditResPutString8(stream, cons_list[i].resource_type);
1361
XtFree((char *) cons_list);
1365
/************************************************************
1367
* Code for inserting values into the protocol stream.
1369
************************************************************/
1371
/* Function Name: InsertWidget
1372
* Description: Inserts the full parent heirarchy of this
1373
* widget into the protocol stream as a widget list.
1374
* Arguments: stream - the protocol stream.
1375
* w - the widget to insert.
1380
InsertWidget(stream, w)
1381
ProtocolStream * stream;
1385
unsigned long * widget_list;
1386
register int i, num_widgets;
1388
for (temp = w, i = 0; temp != 0; temp = XtParent(temp), i++) {}
1391
widget_list = (unsigned long *)
1392
XtMalloc(sizeof(unsigned long) * num_widgets);
1395
* Put the widgets into the list.
1396
* make sure that they are inserted in the list from parent -> child.
1399
for (i--, temp = w; temp != NULL; temp = XtParent(temp), i--)
1400
widget_list[i] = (unsigned long) temp;
1402
_XEditResPut16(stream, num_widgets); /* insert number of widgets. */
1403
for (i = 0; i < num_widgets; i++) /* insert Widgets themselves. */
1404
_XEditResPut32(stream, widget_list[i]);
1406
XtFree((char *)widget_list);
1409
/************************************************************
1411
* All of the following routines are public.
1413
************************************************************/
1415
/* Function Name: _XEditResPutString8
1416
* Description: Inserts a string into the protocol stream.
1417
* Arguments: stream - stream to insert string into.
1418
* str - string to insert.
1423
_XEditResPutString8(stream, str)
1424
ProtocolStream * stream;
1427
int i, len = strlen(str);
1429
_XEditResPut16(stream, len);
1430
for (i = 0 ; i < len ; i++, str++)
1431
_XEditResPut8(stream, *str);
1434
/* Function Name: _XEditResPut8
1435
* Description: Inserts an 8 bit integer into the protocol stream.
1436
* Arguments: stream - stream to insert string into.
1437
* value - value to insert.
1442
_XEditResPut8(stream, value)
1443
ProtocolStream * stream;
1448
if (stream->size >= stream->alloc) {
1449
stream->alloc += 100;
1450
stream->real_top = (unsigned char *) XtRealloc(
1451
(char *)stream->real_top,
1452
stream->alloc + HEADER_SIZE);
1453
stream->top = stream->real_top + HEADER_SIZE;
1454
stream->current = stream->top + stream->size;
1457
temp = (unsigned char) (value & BYTE_MASK);
1458
*((stream->current)++) = temp;
1462
/* Function Name: _XEditResPut16
1463
* Description: Inserts a 16 bit integer into the protocol stream.
1464
* Arguments: stream - stream to insert string into.
1465
* value - value to insert.
1470
_XEditResPut16(stream, value)
1471
ProtocolStream * stream;
1474
_XEditResPut8(stream, (value >> XER_NBBY) & BYTE_MASK);
1475
_XEditResPut8(stream, value & BYTE_MASK);
1478
/* Function Name: _XEditResPut32
1479
* Description: Inserts a 32 bit integer into the protocol stream.
1480
* Arguments: stream - stream to insert string into.
1481
* value - value to insert.
1486
_XEditResPut32(stream, value)
1487
ProtocolStream * stream;
1488
unsigned long value;
1492
for (i = 3; i >= 0; i--)
1493
_XEditResPut8(stream, (value >> (XER_NBBY*i)) & BYTE_MASK);
1496
/* Function Name: _XEditResPutWidgetInfo
1497
* Description: Inserts the widget info into the protocol stream.
1498
* Arguments: stream - stream to insert widget info into.
1499
* info - info to insert.
1504
_XEditResPutWidgetInfo(stream, info)
1505
ProtocolStream * stream;
1510
_XEditResPut16(stream, info->num_widgets);
1511
for (i = 0; i < info->num_widgets; i++)
1512
_XEditResPut32(stream, info->ids[i]);
1515
/************************************************************
1517
* Code for retrieving values from the protocol stream.
1519
************************************************************/
1521
/* Function Name: _XEditResResetStream
1522
* Description: resets the protocol stream
1523
* Arguments: stream - the stream to reset.
1528
_XEditResResetStream(stream)
1529
ProtocolStream * stream;
1531
stream->current = stream->top;
1533
if (stream->real_top == NULL) {
1534
stream->real_top = (unsigned char *) XtRealloc(
1535
(char *)stream->real_top,
1536
stream->alloc + HEADER_SIZE);
1537
stream->top = stream->real_top + HEADER_SIZE;
1538
stream->current = stream->top + stream->size;
1543
* NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE
1545
* The only modified field if the "current" field.
1547
* The only fields that must be set correctly are the "current", "top"
1548
* and "size" fields.
1551
/* Function Name: _XEditResGetg8
1552
* Description: Retrieves an unsigned 8 bit value
1553
* from the protocol stream.
1554
* Arguments: stream.
1555
* val - a pointer to value to return.
1556
* Returns: TRUE if sucessful.
1560
_XEditResGet8(stream, val)
1561
ProtocolStream * stream;
1562
unsigned char * val;
1564
if (stream->size < (stream->current - stream->top))
1567
*val = *((stream->current)++);
1571
/* Function Name: _XEditResGet16
1572
* Description: Retrieves an unsigned 16 bit value
1573
* from the protocol stream.
1574
* Arguments: stream.
1575
* val - a pointer to value to return.
1576
* Returns: TRUE if sucessful.
1580
_XEditResGet16(stream, val)
1581
ProtocolStream * stream;
1582
unsigned short * val;
1584
unsigned char temp1, temp2;
1586
if ( !(_XEditResGet8(stream, &temp1) && _XEditResGet8(stream, &temp2)) )
1589
*val = (((unsigned short) temp1 << XER_NBBY) + ((unsigned short) temp2));
1593
/* Function Name: _XEditResGetSigned16
1594
* Description: Retrieves an signed 16 bit value from the protocol stream.
1595
* Arguments: stream.
1596
* val - a pointer to value to return.
1597
* Returns: TRUE if sucessful.
1601
_XEditResGetSigned16(stream, val)
1602
ProtocolStream * stream;
1605
unsigned char temp1, temp2;
1607
if ( !(_XEditResGet8(stream, &temp1) && _XEditResGet8(stream, &temp2)) )
1610
if (temp1 & (1 << (XER_NBBY - 1))) { /* If the sign bit is active. */
1611
*val = -1; /* store all 1's */
1612
*val &= (temp1 << XER_NBBY); /* Now and in the MSB */
1613
*val &= temp2; /* and LSB */
1616
*val = (((unsigned short) temp1 << XER_NBBY) + ((unsigned short) temp2));
1621
/* Function Name: _XEditResGet32
1622
* Description: Retrieves an unsigned 32 bit value
1623
* from the protocol stream.
1624
* Arguments: stream.
1625
* val - a pointer to value to return.
1626
* Returns: TRUE if sucessful.
1630
_XEditResGet32(stream, val)
1631
ProtocolStream * stream;
1632
unsigned long * val;
1634
unsigned short temp1, temp2;
1636
if ( !(_XEditResGet16(stream, &temp1) && _XEditResGet16(stream, &temp2)) )
1639
*val = (((unsigned short) temp1 << (XER_NBBY * 2)) +
1640
((unsigned short) temp2));
1644
/* Function Name: _XEditResGetString8
1645
* Description: Retrieves an 8 bit string value from the protocol stream.
1646
* Arguments: stream - the protocol stream
1647
* str - the string to retrieve.
1648
* Returns: True if retrieval was successful.
1652
_XEditResGetString8(stream, str)
1653
ProtocolStream * stream;
1657
register unsigned i;
1659
if (!_XEditResGet16(stream, &len)) {
1663
*str = XtMalloc(sizeof(char) * (len + 1));
1665
for (i = 0; i < len; i++) {
1666
if (!_XEditResGet8(stream, (unsigned char *) *str + i)) {
1672
(*str)[i] = '\0'; /* NULL terminate that sucker. */
1676
/* Function Name: _XEditResGetWidgetInfo
1677
* Description: Retrieves the list of widgets that follow and stores
1678
* them in the widget info structure provided.
1679
* Arguments: stream - the protocol stream
1680
* info - the widget info struct to store into.
1681
* Returns: True if retrieval was successful.
1685
_XEditResGetWidgetInfo(stream, info)
1686
ProtocolStream * stream;
1691
if (!_XEditResGet16(stream, &(info->num_widgets)))
1694
info->ids = (unsigned long *) XtMalloc(sizeof(long) * (info->num_widgets));
1696
for (i = 0; i < info->num_widgets; i++) {
1697
if (!_XEditResGet32(stream, info->ids + i)) {
1698
XtFree((char *)info->ids);
1706
/************************************************************
1708
* Code for Loading the EditresBlock resource.
1710
************************************************************/
1712
/* Function Name: CvStringToBlock
1713
* Description: Converts a string to an editres block value.
1714
* Arguments: dpy - the display.
1715
* args, num_args - **UNUSED **
1716
* from_val, to_val - value to convert, and where to put result
1717
* converter_data - ** UNUSED **
1718
* Returns: TRUE if conversion was sucessful.
1723
CvtStringToBlock(dpy, args, num_args, from_val, to_val, converter_data)
1726
Cardinal * num_args;
1727
XrmValue * from_val, * to_val;
1728
XtPointer * converter_data;
1731
static EditresBlock block;
1733
/* XmuCopyISOLatin1Lowered(ptr, from_val->addr);*/
1736
if (streq(ptr, "none"))
1738
else if (streq(ptr, "setvalues"))
1739
block = BlockSetValues;
1740
else if (streq(ptr, "all"))
1743
Cardinal num_params = 1;
1746
params[0] = from_val->addr;
1747
XtAppWarningMsg(XtDisplayToApplicationContext(dpy),
1748
"CvtStringToBlock", "unknownValue", "EditresError",
1749
"Could not convert string \"%s\" to EditresBlock.",
1750
params, &num_params);
1754
if (to_val->addr != NULL) {
1755
if (to_val->size < sizeof(EditresBlock)) {
1756
to_val->size = sizeof(EditresBlock);
1759
*(EditresBlock *)(to_val->addr) = block;
1762
to_val->addr = (XtPointer) block;
1764
to_val->size = sizeof(EditresBlock);
1768
#define XtREditresBlock ("EditresBlock")
1770
/* Function Name: LoadResources
1771
* Description: Loads a global resource the determines of this
1772
* application should allow Editres requests.
1773
* Arguments: w - any widget in the tree.
1781
static XtResource resources[] = {
1782
{"editresBlock", "EditresBlock", XtREditresBlock, sizeof(EditresBlock),
1783
XtOffsetOf(Globals, block), XtRImmediate, (XtPointer) BlockNone}
1786
for (; XtParent(w) != NULL; w = XtParent(w)) {}
1788
XtAppSetTypeConverter(XtWidgetToApplicationContext(w),
1789
XtRString, XtREditresBlock, CvtStringToBlock,
1790
NULL, (Cardinal) 0, XtCacheAll, NULL);
1792
XtGetApplicationResources( w, (caddr_t) &globals, resources,
1793
XtNumber(resources), NULL, (Cardinal) 0);