File: | EditresCom.c |
Location: | line 971, column 1 |
Description: | Address of stack memory associated with local variable 'count' is still referred to by the global variable 'globals' upon returning to the caller. This will be a dangling reference |
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 | */ | |||
26 | ||||
27 | /* | |||
28 | * Author: Chris D. Peterson, Dave Sternlicht, MIT X Consortium | |||
29 | */ | |||
30 | ||||
31 | #ifdef HAVE_CONFIG_H1 | |||
32 | #include <config.h> | |||
33 | #endif | |||
34 | #include <X11/IntrinsicP.h> /* To get into the composite and core widget | |||
35 | structures. */ | |||
36 | #include <X11/ObjectP.h> /* For XtIs<Classname> macros. */ | |||
37 | #include <X11/StringDefs.h> /* for XtRString. */ | |||
38 | #include <X11/ShellP.h> /* for Application Shell Widget class. */ | |||
39 | ||||
40 | #include <X11/Xatom.h> | |||
41 | #include <X11/Xos.h> /* for strcpy declaration */ | |||
42 | #include <X11/Xfuncs.h> | |||
43 | #include <X11/Xmu/EditresP.h> | |||
44 | #include <X11/Xmd.h> | |||
45 | #include <X11/Xmu/CharSet.h> | |||
46 | #include <X11/Xmu/SysUtil.h> | |||
47 | #include <stdio.h> | |||
48 | #include <stdlib.h> | |||
49 | #include <string.h> | |||
50 | ||||
51 | #define _XEditResPutBool_XEditResPut8 _XEditResPut8 | |||
52 | #define _XEditResPutResourceType_XEditResPut8 _XEditResPut8 | |||
53 | ||||
54 | /* | |||
55 | * Types | |||
56 | */ | |||
57 | typedef enum { | |||
58 | BlockNone, | |||
59 | BlockSetValues, | |||
60 | BlockAll | |||
61 | } EditresBlock; | |||
62 | ||||
63 | typedef struct _SetValuesEvent { | |||
64 | EditresCommand type; /* first field must be type */ | |||
65 | WidgetInfo *widgets; | |||
66 | unsigned short num_entries; /* number of set values requests */ | |||
67 | char *name; | |||
68 | char *res_type; | |||
69 | XtPointer value; | |||
70 | unsigned short value_len; | |||
71 | } SetValuesEvent; | |||
72 | ||||
73 | typedef struct _SVErrorInfo { | |||
74 | SetValuesEvent *event; | |||
75 | ProtocolStream *stream; | |||
76 | unsigned short *count; | |||
77 | WidgetInfo *entry; | |||
78 | } SVErrorInfo; | |||
79 | ||||
80 | typedef struct _GetValuesEvent { | |||
81 | EditresCommand type; /* first field must be type */ | |||
82 | WidgetInfo *widgets; | |||
83 | unsigned short num_entries; /* number of get values requests */ | |||
84 | char *name; | |||
85 | } GetValuesEvent; | |||
86 | ||||
87 | typedef struct _FindChildEvent { | |||
88 | EditresCommand type; /* first field must be type */ | |||
89 | WidgetInfo *widgets; | |||
90 | short x, y; | |||
91 | } FindChildEvent; | |||
92 | ||||
93 | typedef struct _GenericGetEvent { | |||
94 | EditresCommand type; /* first field must be type */ | |||
95 | WidgetInfo *widgets; | |||
96 | unsigned short num_entries; /* number of set values requests */ | |||
97 | } GenericGetEvent, GetResEvent, GetGeomEvent; | |||
98 | ||||
99 | /* | |||
100 | * Common to all events | |||
101 | */ | |||
102 | typedef struct _AnyEvent { | |||
103 | EditresCommand type; /* first field must be type */ | |||
104 | WidgetInfo *widgets; | |||
105 | } AnyEvent; | |||
106 | ||||
107 | /* | |||
108 | * The event union | |||
109 | */ | |||
110 | typedef union _EditresEvent { | |||
111 | AnyEvent any_event; | |||
112 | SetValuesEvent set_values_event; | |||
113 | GetResEvent get_resources_event; | |||
114 | GetGeomEvent get_geometry_event; | |||
115 | FindChildEvent find_child_event; | |||
116 | } EditresEvent; | |||
117 | ||||
118 | typedef struct _Globals { | |||
119 | EditresBlock block; | |||
120 | SVErrorInfo error_info; | |||
121 | ProtocolStream stream; | |||
122 | ProtocolStream *command_stream; /* command stream */ | |||
123 | #if defined(LONG64) || defined(WORD64) | |||
124 | unsigned long base_address; | |||
125 | #endif | |||
126 | } Globals; | |||
127 | ||||
128 | #define CURRENT_PROTOCOL_VERSION5L 5L | |||
129 | ||||
130 | #define streq(a,b)(strcmp((a), (b)) == 0) (strcmp((a), (b)) == 0) | |||
131 | ||||
132 | /* | |||
133 | * Prototypes | |||
134 | */ | |||
135 | static Widget _FindChild(Widget, int, int); | |||
136 | static void _XEditresGetStringValues(Widget, Arg*, int); | |||
137 | static XtPointer BuildReturnPacket(ResIdent, EditResError, ProtocolStream*); | |||
138 | static void CommandDone(Widget, Atom*, Atom*); | |||
139 | static Boolean ConvertReturnCommand(Widget, Atom*, Atom*, Atom*, XtPointer*, | |||
140 | unsigned long*, int*); | |||
141 | static Boolean CvtStringToBlock(Display*, XrmValue*, Cardinal*, | |||
142 | XrmValue*, XrmValue*, XtPointer*); | |||
143 | static EditresEvent *BuildEvent(Widget, Atom, XtPointer, ResIdent, | |||
144 | unsigned long); | |||
145 | static _Xconstconst char *DoFindChild(Widget, EditresEvent*, ProtocolStream*); | |||
146 | static _Xconstconst char *DoGetGeometry(Widget, EditresEvent*, ProtocolStream*); | |||
147 | static _Xconstconst char *DoGetResources(Widget, EditresEvent*, ProtocolStream*); | |||
148 | static _Xconstconst char *DoSetValues(Widget, EditresEvent*, ProtocolStream*); | |||
149 | static void DumpChildren(Widget, ProtocolStream*, unsigned short*); | |||
150 | static _Xconstconst char *DumpValues(Widget, EditresEvent*, ProtocolStream*); | |||
151 | static _Xconstconst char *DumpWidgets(Widget, EditresEvent*, ProtocolStream*); | |||
152 | static void ExecuteCommand(Widget, Atom, ResIdent, EditresEvent*); | |||
153 | static void ExecuteGetGeometry(Widget, ProtocolStream*); | |||
154 | static void ExecuteGetResources(Widget w, ProtocolStream *stream); | |||
155 | static void ExecuteSetValues(Widget, SetValuesEvent*, WidgetInfo*, | |||
156 | ProtocolStream*, unsigned short*); | |||
157 | static void FreeEvent(EditresEvent*); | |||
158 | static void GetCommand(Widget w, XtPointer, Atom*, Atom*, XtPointer, | |||
159 | unsigned long*, int*); | |||
160 | static void HandleToolkitErrors(String, String, String, String, | |||
161 | String*, Cardinal*); | |||
162 | static void InsertWidget(ProtocolStream*, Widget); | |||
163 | static Boolint IsChild(Widget, Widget, Widget); | |||
164 | static Boolint isApplicationShell(Widget); | |||
165 | static void LoadResources(Widget); | |||
166 | static Boolint PositionInChild(Widget, int, int); | |||
167 | static int qcmp_widget_list(register _Xconstconst void*, register _Xconstconst void*); | |||
168 | static void SendCommand(Widget, Atom, ResIdent, EditResError, | |||
169 | ProtocolStream*); | |||
170 | static void SendFailure(Widget, Atom, ResIdent, _Xconstconst char*); | |||
171 | static _Xconstconst char *VerifyWidget(Widget, WidgetInfo*); | |||
172 | ||||
173 | /* | |||
174 | * External | |||
175 | */ | |||
176 | void _XEditResCheckMessages(Widget, XtPointer, XEvent*, Boolean*); | |||
177 | ||||
178 | /* | |||
179 | * Initialization | |||
180 | */ | |||
181 | static Atom res_editor_command, res_editor_protocol, client_value; | |||
182 | static Globals globals; | |||
183 | ||||
184 | /************************************************************ | |||
185 | * Resource Editor Communication Code | |||
186 | ************************************************************/ | |||
187 | /* | |||
188 | * Function: | |||
189 | * _XEditResCheckMessages | |||
190 | * | |||
191 | * Parameters: | |||
192 | * data - unused | |||
193 | * event - The X Event that triggered this handler | |||
194 | * cont - unused | |||
195 | * | |||
196 | * Description: | |||
197 | * This callback routine is set on all shell widgets, and checks to | |||
198 | * see if a client message event has come from the resource editor. | |||
199 | */ | |||
200 | /*ARGSUSED*/ | |||
201 | void | |||
202 | _XEditResCheckMessages(Widget w, XtPointer data, XEvent *event, Boolean *cont) | |||
203 | { | |||
204 | Time time; | |||
205 | ResIdent ident; | |||
206 | static Boolean first_time = False0; | |||
207 | static Atom res_editor, res_comm; | |||
208 | Display *dpy; | |||
209 | ||||
210 | if (event->type == ClientMessage33) | |||
211 | { | |||
212 | XClientMessageEvent * c_event = (XClientMessageEvent *)event; | |||
213 | dpy = XtDisplay(w)(((w)->core.screen)->display); | |||
214 | ||||
215 | if (!first_time) | |||
216 | { | |||
217 | Atom atoms[4]; | |||
218 | static _Xconstconst char *names[] = { | |||
219 | EDITRES_NAME"Editres", EDITRES_COMMAND_ATOM"EditresCommand", | |||
220 | EDITRES_PROTOCOL_ATOM"EditresProtocol", EDITRES_CLIENT_VALUE"EditresClientVal" | |||
221 | }; | |||
222 | ||||
223 | first_time = True1; | |||
224 | XInternAtoms(dpy, (char **) names, 4, False0, atoms); | |||
225 | res_editor = atoms[0]; | |||
226 | res_editor_command = atoms[1]; | |||
227 | res_editor_protocol = atoms[2]; | |||
228 | /* Used in later procedures */ | |||
229 | client_value = atoms[3]; | |||
230 | LoadResources(w); | |||
231 | } | |||
232 | ||||
233 | if ((c_event->message_type != res_editor) | |||
234 | || (c_event->format != EDITRES_SEND_EVENT_FORMAT32)) | |||
235 | return; | |||
236 | ||||
237 | time = c_event->data.l[0]; | |||
238 | res_comm = c_event->data.l[1]; | |||
239 | ident = (ResIdent) c_event->data.l[2]; | |||
240 | if (c_event->data.l[3] != CURRENT_PROTOCOL_VERSION5L) | |||
241 | { | |||
242 | _XEditResResetStream(&globals.stream); | |||
243 | _XEditResPut8(&globals.stream, | |||
244 | (unsigned int) CURRENT_PROTOCOL_VERSION5L); | |||
245 | SendCommand(w, res_comm, ident, ProtocolMismatch, &globals.stream); | |||
246 | return; | |||
247 | } | |||
248 | ||||
249 | XtGetSelectionValue(w, res_comm, res_editor_command, | |||
250 | GetCommand, (XtPointer)(long)ident, time); | |||
251 | } | |||
252 | } | |||
253 | ||||
254 | /* | |||
255 | * Function: | |||
256 | * BuildEvent | |||
257 | * | |||
258 | * Parameters: | |||
259 | * w - widget to own selection, in case of error | |||
260 | * sel - selection to send error message beck in | |||
261 | * data - the data for the request | |||
262 | * ident - the id number we are looking for | |||
263 | * length - length of request | |||
264 | * | |||
265 | * Description: | |||
266 | * Takes the info out the protocol stream an constructs | |||
267 | * the proper event structure. | |||
268 | * | |||
269 | * Returns: | |||
270 | * the event, or NULL | |||
271 | */ | |||
272 | #if defined(ERROR_MESSAGE"Client: Improperly formatted protocol request") | |||
273 | #undef ERROR_MESSAGE"Client: Improperly formatted protocol request" | |||
274 | #endif | |||
275 | #define ERROR_MESSAGE"Client: Improperly formatted protocol request" "Client: Improperly formatted protocol request" | |||
276 | static EditresEvent * | |||
277 | BuildEvent(Widget w, Atom sel, XtPointer data, ResIdent ident, | |||
278 | unsigned long length) | |||
279 | { | |||
280 | EditresEvent *event; | |||
281 | ProtocolStream alloc_stream, *stream; | |||
282 | unsigned char temp; | |||
283 | register unsigned int i; | |||
284 | ||||
285 | stream = &alloc_stream; | |||
286 | stream->current = stream->top = (unsigned char *)data; | |||
287 | stream->size = HEADER_SIZE6; /* size of header */ | |||
288 | ||||
289 | /* | |||
290 | * Retrieve the Header | |||
291 | */ | |||
292 | if (length < HEADER_SIZE6) | |||
293 | { | |||
294 | SendFailure(w, sel, ident, ERROR_MESSAGE"Client: Improperly formatted protocol request"); | |||
295 | return (NULL((void*)0)); | |||
296 | } | |||
297 | ||||
298 | (void)_XEditResGet8(stream, &temp); | |||
299 | if (temp != ident) /* Id's don't match, ignore request */ | |||
300 | return (NULL((void*)0)); | |||
301 | ||||
302 | event = (EditresEvent *)XtCalloc(sizeof(EditresEvent), 1); | |||
303 | ||||
304 | (void)_XEditResGet8(stream, &temp); | |||
305 | event->any_event.type = (EditresCommand)temp; | |||
306 | (void)_XEditResGet32(stream, &stream->size); | |||
307 | stream->top = stream->current; /* reset stream to top of value */ | |||
308 | ||||
309 | /* | |||
310 | * Now retrieve the data segment | |||
311 | */ | |||
312 | switch(event->any_event.type) | |||
313 | { | |||
314 | case SendWidgetTree: | |||
315 | break; /* no additional info */ | |||
316 | case SetValues: | |||
317 | { | |||
318 | SetValuesEvent *sv_event = (SetValuesEvent *)event; | |||
319 | ||||
320 | if (!(_XEditResGetString8(stream, &sv_event->name) | |||
321 | && _XEditResGetString8(stream, &sv_event->res_type))) | |||
322 | goto done; | |||
323 | ||||
324 | /* | |||
325 | * Since we need the value length, we have to pull the | |||
326 | * value out by hand | |||
327 | */ | |||
328 | if (!_XEditResGet16(stream, &sv_event->value_len)) | |||
329 | goto done; | |||
330 | ||||
331 | sv_event->value = XtMalloc(sizeof(char) * (sv_event->value_len + 1)); | |||
332 | ||||
333 | for (i = 0; i < sv_event->value_len; i++) | |||
334 | if (!_XEditResGet8(stream, (unsigned char *)sv_event->value + i)) | |||
335 | goto done; | |||
336 | ||||
337 | ((char*)sv_event->value)[i] = '\0'; | |||
338 | ||||
339 | if (!_XEditResGet16(stream, &sv_event->num_entries)) | |||
340 | goto done; | |||
341 | ||||
342 | sv_event->widgets = (WidgetInfo *) | |||
343 | XtCalloc(sizeof(WidgetInfo), sv_event->num_entries); | |||
344 | ||||
345 | for (i = 0; i < sv_event->num_entries; i++) | |||
346 | if (!_XEditResGetWidgetInfo(stream, sv_event->widgets + i)) | |||
347 | goto done; | |||
348 | } | |||
349 | break; | |||
350 | case FindChild: | |||
351 | { | |||
352 | FindChildEvent *find_event = (FindChildEvent *)event; | |||
353 | ||||
354 | find_event->widgets = (WidgetInfo *)XtCalloc(sizeof(WidgetInfo), 1); | |||
355 | ||||
356 | if (!(_XEditResGetWidgetInfo(stream, find_event->widgets) | |||
357 | && _XEditResGetSigned16(stream, &find_event->x) | |||
358 | && _XEditResGetSigned16(stream, &find_event->y))) | |||
359 | goto done; | |||
360 | } | |||
361 | break; | |||
362 | case GetGeometry: | |||
363 | case GetResources: | |||
364 | { | |||
365 | GenericGetEvent *get_event = (GenericGetEvent *)event; | |||
366 | ||||
367 | if (!_XEditResGet16(stream, &get_event->num_entries)) | |||
368 | goto done; | |||
369 | ||||
370 | get_event->widgets = (WidgetInfo *) | |||
371 | XtCalloc(sizeof(WidgetInfo), get_event->num_entries); | |||
372 | ||||
373 | for (i = 0; i < get_event->num_entries; i++) | |||
374 | if (!_XEditResGetWidgetInfo(stream, get_event->widgets + i)) | |||
375 | goto done; | |||
376 | } | |||
377 | break; | |||
378 | case GetValues: | |||
379 | { | |||
380 | GetValuesEvent *gv_event = (GetValuesEvent *)event; | |||
381 | ||||
382 | _XEditResGetString8(stream, &gv_event->name); | |||
383 | _XEditResGet16(stream, &gv_event->num_entries); | |||
384 | gv_event->widgets = (WidgetInfo *) | |||
385 | XtCalloc(sizeof(WidgetInfo), gv_event->num_entries); | |||
386 | _XEditResGetWidgetInfo(stream, gv_event->widgets); | |||
387 | } | |||
388 | break; | |||
389 | default: | |||
390 | { | |||
391 | char buf[BUFSIZ1024]; | |||
392 | ||||
393 | XmuSnprintf(buf, sizeof(buf), | |||
394 | "Unknown Protocol request %d.", event->any_event.type); | |||
395 | SendFailure(w, sel, ident, buf); | |||
396 | FreeEvent(event); | |||
397 | return (NULL((void*)0)); | |||
398 | } | |||
399 | } | |||
400 | ||||
401 | return (event); | |||
402 | ||||
403 | done: | |||
404 | SendFailure(w, sel, ident, ERROR_MESSAGE"Client: Improperly formatted protocol request"); | |||
405 | FreeEvent(event); | |||
406 | return (NULL((void*)0)); | |||
407 | } | |||
408 | ||||
409 | /* | |||
410 | * Function: | |||
411 | * FreeEvent | |||
412 | * | |||
413 | * Parameters: | |||
414 | * event - event to free | |||
415 | * | |||
416 | * Description: | |||
417 | * Frees the event structure and any other pieces in it that need freeing. | |||
418 | */ | |||
419 | static void | |||
420 | FreeEvent(EditresEvent *event) | |||
421 | { | |||
422 | if (event->any_event.widgets != NULL((void*)0)) | |||
423 | { | |||
424 | XtFree((char *)event->any_event.widgets->ids); | |||
425 | XtFree((char *)event->any_event.widgets); | |||
426 | } | |||
427 | ||||
428 | if (event->any_event.type == SetValues) | |||
429 | { | |||
430 | XtFree(event->set_values_event.name); | |||
431 | XtFree(event->set_values_event.res_type); | |||
432 | } | |||
433 | ||||
434 | XtFree((char *)event); | |||
435 | } | |||
436 | ||||
437 | /* | |||
438 | * Function: | |||
439 | * GetCommand | |||
440 | * | |||
441 | * Parameters: | |||
442 | * (See Xt XtConvertSelectionProc) | |||
443 | * data - contains the ident number for the command | |||
444 | * | |||
445 | * Description: | |||
446 | * Gets the Command out of the selection asserted by the resource manager. | |||
447 | */ | |||
448 | /*ARGSUSED*/ | |||
449 | static void | |||
450 | GetCommand(Widget w, XtPointer data, Atom *selection, Atom *type, | |||
451 | XtPointer value, unsigned long *length, int *format) | |||
452 | { | |||
453 | ResIdent ident = (ResIdent)(long)data; | |||
454 | EditresEvent *event; | |||
455 | ||||
456 | if (*type != res_editor_protocol || *format != EDITRES_FORMAT8) | |||
457 | return; | |||
458 | ||||
459 | if ((event = BuildEvent(w, *selection, value, ident, *length)) != NULL((void*)0)) | |||
460 | { | |||
461 | ExecuteCommand(w, *selection, ident, event); | |||
462 | FreeEvent(event); | |||
463 | } | |||
464 | } | |||
465 | ||||
466 | /* | |||
467 | * Function: | |||
468 | * ExecuteCommand | |||
469 | * | |||
470 | * Parameters: | |||
471 | * w - widget | |||
472 | * command - the command to execute | |||
473 | * value - the associated with the command | |||
474 | * | |||
475 | * Description: | |||
476 | * Executes a command string received from the resource editor. | |||
477 | */ | |||
478 | /*ARGSUSED*/ | |||
479 | static void | |||
480 | ExecuteCommand(Widget w, Atom sel, ResIdent ident, EditresEvent *event) | |||
481 | { | |||
482 | _Xconstconst char *(*func)(Widget, EditresEvent*, ProtocolStream*); | |||
483 | _Xconstconst char *str; | |||
484 | ||||
485 | if (globals.block == BlockAll) | |||
486 | { | |||
487 | SendFailure(w, sel, ident, | |||
488 | "This client has blocked all Editres commands."); | |||
489 | return; | |||
490 | } | |||
491 | else if (globals.block == BlockSetValues | |||
492 | && event->any_event.type == SetValues) | |||
493 | { | |||
494 | SendFailure(w, sel, ident, | |||
495 | "This client has blocked all SetValues requests."); | |||
496 | return; | |||
497 | } | |||
498 | ||||
499 | switch(event->any_event.type) | |||
500 | { | |||
501 | case SendWidgetTree: | |||
502 | #if defined(LONG64) || defined(WORD64) | |||
503 | globals.base_address = (unsigned long)w & 0xFFFFFFFF00000000; | |||
504 | #endif | |||
505 | func = DumpWidgets; | |||
506 | break; | |||
507 | case SetValues: | |||
508 | func = DoSetValues; | |||
509 | break; | |||
510 | case FindChild: | |||
511 | func = DoFindChild; | |||
512 | break; | |||
513 | case GetGeometry: | |||
514 | func = DoGetGeometry; | |||
515 | break; | |||
516 | case GetResources: | |||
517 | func = DoGetResources; | |||
518 | break; | |||
519 | case GetValues: | |||
520 | func = DumpValues; | |||
521 | break; | |||
522 | default: | |||
523 | { | |||
524 | char buf[BUFSIZ1024]; | |||
525 | ||||
526 | XmuSnprintf(buf, sizeof(buf), | |||
527 | "Unknown Protocol request %d.",event->any_event.type); | |||
528 | SendFailure(w, sel, ident, buf); | |||
529 | return; | |||
530 | } | |||
531 | } | |||
532 | ||||
533 | _XEditResResetStream(&globals.stream); | |||
534 | if ((str = (*func)(w, event, &globals.stream)) == NULL((void*)0)) | |||
535 | SendCommand(w, sel, ident, PartialSuccess, &globals.stream); | |||
536 | else | |||
537 | SendFailure(w, sel, ident, str); | |||
538 | } | |||
539 | ||||
540 | /* | |||
541 | * Function: | |||
542 | * ConvertReturnCommand | |||
543 | * | |||
544 | * Parameters: | |||
545 | * w - the widget that owns the selection | |||
546 | * selection - selection to convert | |||
547 | * target - target type for this selection | |||
548 | * type_ret - type of the selection | |||
549 | * value_ret - selection value | |||
550 | * length_ret - lenght of this selection | |||
551 | * format_ret - the format the selection is in | |||
552 | * | |||
553 | * Description: | |||
554 | * Converts a selection | |||
555 | * | |||
556 | * Returns: | |||
557 | * True if conversion was sucessful | |||
558 | */ | |||
559 | /*ARGSUSED*/ | |||
560 | static Boolean | |||
561 | ConvertReturnCommand(Widget w, Atom *selection, Atom *target, Atom *type_ret, | |||
562 | XtPointer *value_ret, unsigned long *length_ret, | |||
563 | int *format_ret) | |||
564 | { | |||
565 | /* | |||
566 | * I assume the intrinsics give me the correct selection back | |||
567 | */ | |||
568 | if ((*target != client_value)) | |||
569 | return (False0); | |||
570 | ||||
571 | *type_ret = res_editor_protocol; | |||
572 | *value_ret = (XtPointer)globals.command_stream->real_top; | |||
573 | *length_ret = globals.command_stream->size + HEADER_SIZE6; | |||
574 | *format_ret = EDITRES_FORMAT8; | |||
575 | ||||
576 | return (True1); | |||
577 | } | |||
578 | ||||
579 | /* | |||
580 | * Function: | |||
581 | * CommandDone | |||
582 | * | |||
583 | * Parameters: | |||
584 | * widget - unused | |||
585 | * selection - unused | |||
586 | * target - unused | |||
587 | * | |||
588 | * Description: | |||
589 | * done with the selection | |||
590 | */ | |||
591 | /*ARGSUSED*/ | |||
592 | static void | |||
593 | CommandDone(Widget widget, Atom *selection, Atom *target) | |||
594 | { | |||
595 | /* Keep the toolkit from automaticaly freeing the selection value */ | |||
596 | } | |||
597 | ||||
598 | /* | |||
599 | * Function: | |||
600 | * SendFailure | |||
601 | * | |||
602 | * Paramters: | |||
603 | * w - widget to own the selection | |||
604 | * sel - selection to assert | |||
605 | * ident - identifier | |||
606 | * str - error message | |||
607 | * | |||
608 | * Description: | |||
609 | * Sends a failure message | |||
610 | */ | |||
611 | static void | |||
612 | SendFailure(Widget w, Atom sel, ResIdent ident, _Xconstconst char *str) | |||
613 | { | |||
614 | _XEditResResetStream(&globals.stream); | |||
615 | _XEditResPutString8(&globals.stream, str); | |||
616 | SendCommand(w, sel, ident, Failure, &globals.stream); | |||
617 | } | |||
618 | ||||
619 | /* | |||
620 | * Function: | |||
621 | * BuildReturnPacket | |||
622 | * | |||
623 | * Parameters: | |||
624 | * ident - identifier | |||
625 | * command - command code | |||
626 | * stream - protocol stream | |||
627 | * Description: | |||
628 | * Builds a return packet, given the data to send | |||
629 | * | |||
630 | * Returns: | |||
631 | * packet to send | |||
632 | */ | |||
633 | static XtPointer | |||
634 | BuildReturnPacket(ResIdent ident, EditResError error, ProtocolStream *stream) | |||
635 | { | |||
636 | long old_alloc, old_size; | |||
637 | unsigned char *old_current; | |||
638 | ||||
639 | /* | |||
640 | * We have cleverly keep enough space at the top of the header | |||
641 | * for the return protocol stream, so all we have to do is | |||
642 | * fill in the space | |||
643 | */ | |||
644 | /* | |||
645 | * Fool the insert routines into putting the header in the right | |||
646 | * place while being damn sure not to realloc (that would be very bad.) | |||
647 | */ | |||
648 | old_current = stream->current; | |||
649 | old_alloc = stream->alloc; | |||
650 | old_size = stream->size; | |||
651 | ||||
652 | stream->current = stream->real_top; | |||
653 | stream->alloc = stream->size + (2 * HEADER_SIZE6); | |||
654 | ||||
655 | _XEditResPut8(stream, ident); | |||
656 | _XEditResPut8(stream, (unsigned char)error); | |||
657 | _XEditResPut32(stream, old_size); | |||
658 | ||||
659 | stream->alloc = old_alloc; | |||
660 | stream->current = old_current; | |||
661 | stream->size = old_size; | |||
662 | ||||
663 | return ((XtPointer)stream->real_top); | |||
664 | } | |||
665 | ||||
666 | /* | |||
667 | * Function: | |||
668 | * SendCommand | |||
669 | * Parameters: | |||
670 | * w - widget to own the selection | |||
671 | * sel - selection to assert | |||
672 | * ident - identifier | |||
673 | * command - command code | |||
674 | * stream - protocol stream | |||
675 | * | |||
676 | * Description: | |||
677 | * Builds a return command line | |||
678 | */ | |||
679 | static void | |||
680 | SendCommand(Widget w, Atom sel, ResIdent ident, EditResError error, | |||
681 | ProtocolStream *stream) | |||
682 | { | |||
683 | BuildReturnPacket(ident, error, stream); | |||
684 | globals.command_stream = stream; | |||
685 | ||||
686 | /* | |||
687 | * I REALLY want to own the selection. Since this was not triggered | |||
688 | * by a user action, and I am the only one using this atom it is safe to | |||
689 | * use CurrentTime | |||
690 | */ | |||
691 | XtOwnSelection(w, sel, CurrentTime0L, ConvertReturnCommand, NULL((void*)0), CommandDone); | |||
692 | } | |||
693 | ||||
694 | /************************************************************ | |||
695 | * Generic Utility Functions | |||
696 | ************************************************************/ | |||
697 | static int | |||
698 | qcmp_widget_list(register _Xconstconst void *left, register _Xconstconst void *right) | |||
699 | { | |||
700 | return (char *)*(Widget **)left - (char *)*(Widget **)right; | |||
701 | } | |||
702 | ||||
703 | /* | |||
704 | * Function: | |||
705 | * FindChildren | |||
706 | * | |||
707 | * Parameters: | |||
708 | * parent - parent widget | |||
709 | * children - list of children | |||
710 | * normal - return normal children | |||
711 | * popup - return popup children | |||
712 | * extra - return extra children | |||
713 | * | |||
714 | * Description: | |||
715 | * Retuns all children (popup, normal and otherwise) of this widget | |||
716 | * | |||
717 | * Returns: | |||
718 | * number of children | |||
719 | */ | |||
720 | static int | |||
721 | FindChildren(Widget parent, Widget **children, Boolint normal, Boolint popup, | |||
722 | Boolint extra) | |||
723 | { | |||
724 | CompositeWidget cw = (CompositeWidget)parent; | |||
725 | Cardinal i, num_children, current = 0; | |||
726 | Widget *extra_widgets = NULL((void*)0); | |||
727 | Cardinal num_extra = 0; | |||
728 | ||||
729 | num_children = 0; | |||
730 | ||||
731 | if (XtIsWidget(parent)(((Object)(parent))->object.widget_class->core_class.class_inited & 0x04) && popup) | |||
732 | num_children += parent->core.num_popups; | |||
733 | ||||
734 | if (XtIsComposite(parent)(((Object)(parent))->object.widget_class->core_class.class_inited & 0x08) && normal) | |||
735 | num_children += cw->composite.num_children; | |||
736 | ||||
737 | if (XtIsWidget(parent)(((Object)(parent))->object.widget_class->core_class.class_inited & 0x04) && extra) | |||
738 | { | |||
739 | XtResourceList norm_list, cons_list; | |||
740 | Cardinal num_norm, num_cons; | |||
741 | Arg args[1]; | |||
742 | Widget widget; | |||
743 | ||||
744 | XtGetResourceList(XtClass(parent)((parent)->core.widget_class), &norm_list, &num_norm); | |||
745 | ||||
746 | if (XtParent(parent)((parent)->core.parent) != NULL((void*)0)) | |||
747 | XtGetConstraintResourceList(XtClass(XtParent(parent))((((parent)->core.parent))->core.widget_class), | |||
748 | &cons_list, &num_cons); | |||
749 | else | |||
750 | num_cons = 0; | |||
751 | ||||
752 | extra_widgets = (Widget *)XtMalloc(sizeof(Widget)); | |||
753 | for (i = 0; i < num_norm; i++) | |||
754 | if (strcmp(norm_list[i].resource_type, XtRWidget((char*)&XtStrings[1865])) == 0) | |||
755 | { | |||
756 | widget = NULL((void*)0); | |||
757 | XtSetArg(args[0], norm_list[i].resource_name, &widget)((void)( (args[0]).name = (norm_list[i].resource_name), (args [0]).value = (XtArgVal)(&widget) )); | |||
758 | XtGetValues(parent, args, 1); | |||
759 | if (widget && XtParent(widget)((widget)->core.parent) == parent) | |||
760 | { | |||
761 | ++num_extra; | |||
762 | extra_widgets = (Widget *) XtRealloc( | |||
763 | (char *)extra_widgets, num_extra * sizeof(Widget)); | |||
764 | extra_widgets[num_extra - 1] = widget; | |||
765 | } | |||
766 | } | |||
767 | for (i = 0; i < num_cons; i++) | |||
768 | if (strcmp(cons_list[i].resource_type, XtRWidget((char*)&XtStrings[1865])) == 0) | |||
769 | { | |||
770 | widget = NULL((void*)0); | |||
771 | XtSetArg(args[0], cons_list[i].resource_name, &widget)((void)( (args[0]).name = (cons_list[i].resource_name), (args [0]).value = (XtArgVal)(&widget) )); | |||
772 | XtGetValues(parent, args, 1); | |||
773 | if (widget && XtParent(widget)((widget)->core.parent) == parent) | |||
774 | { | |||
775 | ++num_extra; | |||
776 | extra_widgets = (Widget *) XtRealloc( | |||
777 | (char *)extra_widgets, num_extra * sizeof(Widget)); | |||
778 | extra_widgets[num_extra - 1] = widget; | |||
779 | } | |||
780 | } | |||
781 | if (num_norm) | |||
782 | XtFree((char *)norm_list); | |||
783 | if (num_cons) | |||
784 | XtFree((char *)cons_list); | |||
785 | } | |||
786 | ||||
787 | if ((num_children + num_extra) == 0) | |||
788 | { | |||
789 | *children = NULL((void*)0); | |||
790 | return (0); | |||
791 | } | |||
792 | ||||
793 | *children = (Widget *)XtMalloc(sizeof(Widget) * (num_children + num_extra)); | |||
794 | ||||
795 | if (XtIsComposite(parent)(((Object)(parent))->object.widget_class->core_class.class_inited & 0x08) && normal) | |||
796 | for (i = 0; i < cw->composite.num_children; i++, current++) | |||
797 | (*children)[current] = cw->composite.children[i]; | |||
798 | ||||
799 | if (XtIsWidget(parent)(((Object)(parent))->object.widget_class->core_class.class_inited & 0x04) && popup) | |||
800 | for (i = 0; i < parent->core.num_popups; i++, current++) | |||
801 | (*children)[current] = parent->core.popup_list[i]; | |||
802 | ||||
803 | if (num_extra) | |||
804 | /* Check for dups */ | |||
805 | { | |||
806 | Cardinal j, old_num_extra = num_extra; | |||
807 | ||||
808 | qsort(extra_widgets, num_extra, sizeof(Widget), qcmp_widget_list); | |||
809 | for (i = 0; i < num_extra - 1; i++) | |||
810 | while (i < num_extra - 1 && | |||
811 | extra_widgets[i] == extra_widgets[i + 1]) | |||
812 | { | |||
813 | memmove(&extra_widgets[i], &extra_widgets[i + 1],__builtin___memmove_chk (&extra_widgets[i], &extra_widgets [i + 1], (num_extra - i) * sizeof(Widget), __builtin_object_size (&extra_widgets[i], 0)) | |||
814 | (num_extra - i) * sizeof(Widget))__builtin___memmove_chk (&extra_widgets[i], &extra_widgets [i + 1], (num_extra - i) * sizeof(Widget), __builtin_object_size (&extra_widgets[i], 0)); | |||
815 | --num_extra; | |||
816 | } | |||
817 | ||||
818 | for (i = 0; i < num_children; i++) | |||
819 | for (j = 0; j < num_extra; j++) | |||
820 | if ((*children)[i] == extra_widgets[j]) | |||
821 | { | |||
822 | if ((j + 1) < num_extra) | |||
823 | memmove(&extra_widgets[j], &extra_widgets[j + 1],__builtin___memmove_chk (&extra_widgets[j], &extra_widgets [j + 1], (num_extra - j) * sizeof(Widget), __builtin_object_size (&extra_widgets[j], 0)) | |||
824 | (num_extra - j) * sizeof(Widget))__builtin___memmove_chk (&extra_widgets[j], &extra_widgets [j + 1], (num_extra - j) * sizeof(Widget), __builtin_object_size (&extra_widgets[j], 0)); | |||
825 | --num_extra; | |||
826 | } | |||
827 | ||||
828 | if (old_num_extra != num_extra) | |||
829 | *children = (Widget *)XtRealloc((char *)*children, sizeof(Widget) | |||
830 | * (num_children + num_extra)); | |||
831 | ||||
832 | if (num_extra) | |||
833 | memcpy(&(*children)[num_children], extra_widgets,__builtin___memcpy_chk (&(*children)[num_children], extra_widgets , sizeof(Widget) * num_extra, __builtin_object_size (&(*children )[num_children], 0)) | |||
834 | sizeof(Widget) * num_extra)__builtin___memcpy_chk (&(*children)[num_children], extra_widgets , sizeof(Widget) * num_extra, __builtin_object_size (&(*children )[num_children], 0)); | |||
835 | } | |||
836 | if (extra_widgets) | |||
837 | XtFree((char *)extra_widgets); | |||
838 | if (num_children + num_extra == 0) | |||
839 | { | |||
840 | XtFree((char *)*children); | |||
841 | *children = NULL((void*)0); | |||
842 | } | |||
843 | ||||
844 | return (num_children + num_extra); | |||
845 | } | |||
846 | ||||
847 | /* | |||
848 | * Function: | |||
849 | * IsChild | |||
850 | * | |||
851 | * parameters: | |||
852 | * top - top of the tree | |||
853 | * parent - parent widget | |||
854 | * child - child widget | |||
855 | * | |||
856 | * Description: | |||
857 | * Check to see of child is a child of parent | |||
858 | */ | |||
859 | static Boolint | |||
860 | IsChild(Widget top, Widget parent, Widget child) | |||
861 | { | |||
862 | int i, num_children; | |||
863 | Widget *children; | |||
864 | ||||
865 | if (parent == NULL((void*)0)) | |||
866 | return (top == child); | |||
867 | ||||
868 | num_children = FindChildren(parent, &children, True1, True1, True1); | |||
869 | ||||
870 | for (i = 0; i < num_children; i++) | |||
871 | if (children[i] == child) | |||
872 | { | |||
873 | XtFree((char *)children); | |||
874 | return (True1); | |||
875 | } | |||
876 | ||||
877 | XtFree((char *)children); | |||
878 | return (False0); | |||
879 | } | |||
880 | ||||
881 | /* | |||
882 | * Function: | |||
883 | * VerifyWidget | |||
884 | * | |||
885 | * Parameters: | |||
886 | * w - any widget in the tree | |||
887 | * info - info about the widget to verify | |||
888 | * | |||
889 | * Description: | |||
890 | * Makes sure all the widgets still exist | |||
891 | */ | |||
892 | static _Xconstconst char * | |||
893 | VerifyWidget(Widget w, WidgetInfo *info) | |||
894 | { | |||
895 | Widget top; | |||
896 | register int count; | |||
897 | register Widget parent; | |||
898 | register unsigned long *child; | |||
899 | ||||
900 | for (top = w; XtParent(top)((top)->core.parent) != NULL((void*)0); top = XtParent(top)((top)->core.parent)) | |||
901 | ; | |||
902 | ||||
903 | parent = NULL((void*)0); | |||
904 | child = info->ids; | |||
905 | count = 0; | |||
906 | ||||
907 | while (True1) | |||
908 | { | |||
909 | if (!IsChild(top, parent, (Widget) *child)) | |||
910 | return ("This widget no longer exists in the client."); | |||
911 | ||||
912 | if (++count == info->num_widgets) | |||
913 | break; | |||
914 | ||||
915 | parent = (Widget)*child++; | |||
916 | } | |||
917 | ||||
918 | info->real_widget = (Widget)*child; | |||
919 | ||||
920 | return (NULL((void*)0)); | |||
921 | } | |||
922 | ||||
923 | /************************************************************ | |||
924 | * Code to Perform SetValues operations | |||
925 | ************************************************************/ | |||
926 | /* | |||
927 | * Function: | |||
928 | * DoSetValues | |||
929 | * | |||
930 | * Parameters: | |||
931 | * w - a widget in the tree | |||
932 | * event - event that caused this action | |||
933 | * stream - protocol stream to add | |||
934 | * | |||
935 | * Description: | |||
936 | * Performs the setvalues requested | |||
937 | * | |||
938 | * Returns: | |||
939 | * NULL | |||
940 | */ | |||
941 | static _Xconstconst char * | |||
942 | DoSetValues(Widget w, EditresEvent *event, ProtocolStream *stream) | |||
943 | { | |||
944 | _Xconstconst char *str; | |||
945 | register unsigned i; | |||
946 | unsigned short count = 0; | |||
947 | SetValuesEvent *sv_event = (SetValuesEvent *)event; | |||
948 | ||||
949 | _XEditResPut16(stream, count); /* insert 0, will be overwritten later */ | |||
950 | ||||
951 | for (i = 0; i < sv_event->num_entries; i++) | |||
| ||||
952 | { | |||
953 | if ((str = VerifyWidget(w, &sv_event->widgets[i])) != NULL((void*)0)) | |||
954 | { | |||
955 | _XEditResPutWidgetInfo(stream, &sv_event->widgets[i]); | |||
956 | _XEditResPutString8(stream, str); | |||
957 | count++; | |||
958 | } | |||
959 | else | |||
960 | ExecuteSetValues(sv_event->widgets[i].real_widget, | |||
961 | sv_event, sv_event->widgets + i, stream, &count); | |||
962 | } | |||
963 | ||||
964 | /* | |||
965 | * Overwrite the first 2 bytes with the real count. | |||
966 | */ | |||
967 | *(stream->top) = count >> XER_NBBY8; | |||
968 | *(stream->top + 1) = count; | |||
969 | ||||
970 | return (NULL((void*)0)); | |||
971 | } | |||
| ||||
972 | ||||
973 | /* | |||
974 | * Function: | |||
975 | * HandleToolkitErrors | |||
976 | * | |||
977 | * Parameters: | |||
978 | * name - name of the error | |||
979 | * type - type of the error | |||
980 | * class - class of the error | |||
981 | * msg - the default message | |||
982 | * params - the extra parameters for this message | |||
983 | * num_params - "" | |||
984 | * | |||
985 | * Description: Handles X Toolkit Errors. | |||
986 | */ | |||
987 | /* ARGSUSED */ | |||
988 | static void | |||
989 | HandleToolkitErrors(String name, String type, String class, String msg, | |||
990 | String *params, Cardinal *num_params) | |||
991 | { | |||
992 | SVErrorInfo *info = &globals.error_info; | |||
993 | char buf[BUFSIZ1024]; | |||
994 | ||||
995 | if (streq(name, "unknownType")(strcmp((name), ("unknownType")) == 0)) | |||
996 | XmuSnprintf(buf, sizeof(buf), | |||
997 | "The `%s' resource is not used by this widget.", | |||
998 | info->event->name); | |||
999 | else if (streq(name, "noColormap")(strcmp((name), ("noColormap")) == 0)) | |||
1000 | XmuSnprintf(buf, sizeof(buf), msg, params[0]); | |||
1001 | else if (streq(name, "conversionFailed")(strcmp((name), ("conversionFailed")) == 0) || streq(name, "conversionError")(strcmp((name), ("conversionError")) == 0)) | |||
1002 | { | |||
1003 | if (streq((String)info->event->value, XtRString)(strcmp(((String)info->event->value), (((char*)&XtStrings [1797]))) == 0)) | |||
1004 | XmuSnprintf(buf, sizeof(buf), | |||
1005 | "Could not convert the string '%s' for the `%s' " | |||
1006 | "resource.", (String)info->event->value, | |||
1007 | info->event->name); | |||
1008 | else | |||
1009 | XmuSnprintf(buf, sizeof(buf), | |||
1010 | "Could not convert the `%s' resource.", | |||
1011 | info->event->name); | |||
1012 | } | |||
1013 | else | |||
1014 | XmuSnprintf(buf, sizeof(buf), | |||
1015 | "Name: %s, Type: %s, Class: %s, Msg: %s", | |||
1016 | name, type, class, msg); | |||
1017 | ||||
1018 | /* | |||
1019 | * Insert this info into the protocol stream, and update the count | |||
1020 | */ | |||
1021 | (*(info->count))++; | |||
1022 | _XEditResPutWidgetInfo(info->stream, info->entry); | |||
1023 | _XEditResPutString8(info->stream, buf); | |||
1024 | } | |||
1025 | ||||
1026 | /* | |||
1027 | * Function: | |||
1028 | * ExecuteSetValues | |||
1029 | * | |||
1030 | * Parameters: | |||
1031 | * w - widget to perform the set_values on | |||
1032 | * sv_event - set values event | |||
1033 | * sv_info - set_value info | |||
1034 | *. | |||
1035 | * Description: | |||
1036 | * Performs a setvalues for a given command | |||
1037 | */ | |||
1038 | static void | |||
1039 | ExecuteSetValues(Widget w, SetValuesEvent *sv_event, WidgetInfo *entry, | |||
1040 | ProtocolStream *stream, unsigned short *count) | |||
1041 | { | |||
1042 | XtErrorMsgHandler old; | |||
1043 | SVErrorInfo *info = &globals.error_info; | |||
1044 | ||||
1045 | info->event = sv_event; /* No data can be passed to */ | |||
1046 | info->stream = stream; /* an error handler, so we */ | |||
1047 | info->count = count; /* have to use a global */ | |||
1048 | info->entry = entry; | |||
1049 | ||||
1050 | old = XtAppSetWarningMsgHandler(XtWidgetToApplicationContext(w), | |||
1051 | HandleToolkitErrors); | |||
1052 | ||||
1053 | XtVaSetValues(w, XtVaTypedArg"XtVaTypedArg", | |||
1054 | sv_event->name, sv_event->res_type, | |||
1055 | sv_event->value, sv_event->value_len, | |||
1056 | NULL((void*)0)); | |||
1057 | ||||
1058 | (void)XtAppSetWarningMsgHandler(XtWidgetToApplicationContext(w), old); | |||
1059 | } | |||
1060 | ||||
1061 | /************************************************************ | |||
1062 | * Code for Creating and dumping widget tree. | |||
1063 | ************************************************************/ | |||
1064 | /* Function: | |||
1065 | * DumpWidgets | |||
1066 | * | |||
1067 | * Parameters: | |||
1068 | * w - a widget in the tree | |||
1069 | * event - event that caused this action | |||
1070 | * stream - protocol stream to add | |||
1071 | * | |||
1072 | * Description: | |||
1073 | * Given a widget it builds a protocol packet containing the entire | |||
1074 | * widget heirarchy. | |||
1075 | * | |||
1076 | * Returns: | |||
1077 | * NULL | |||
1078 | */ | |||
1079 | #define TOOLKIT_TYPE("Xt") ("Xt") | |||
1080 | /*ARGSUSED*/ | |||
1081 | static _Xconstconst char * | |||
1082 | DumpWidgets(Widget w, EditresEvent *event, ProtocolStream *stream) | |||
1083 | { | |||
1084 | unsigned short count = 0; | |||
1085 | ||||
1086 | /* Find Tree's root */ | |||
1087 | for (; XtParent(w)((w)->core.parent) != NULL((void*)0); w = XtParent(w)((w)->core.parent)) | |||
1088 | ; | |||
1089 | ||||
1090 | /* | |||
1091 | * hold space for count, overwritten later | |||
1092 | */ | |||
1093 | _XEditResPut16(stream, (unsigned int)0); | |||
1094 | ||||
1095 | DumpChildren(w, stream, &count); | |||
1096 | ||||
1097 | /* | |||
1098 | * write out toolkit type | |||
1099 | */ | |||
1100 | _XEditResPutString8(stream, TOOLKIT_TYPE("Xt")); | |||
1101 | ||||
1102 | /* | |||
1103 | * Overwrite the first 2 bytes with the real count | |||
1104 | */ | |||
1105 | *(stream->top) = count >> XER_NBBY8; | |||
1106 | *(stream->top + 1) = count; | |||
1107 | ||||
1108 | return (NULL((void*)0)); | |||
1109 | } | |||
1110 | ||||
1111 | /* | |||
1112 | * Function: | |||
1113 | * DumpChildren | |||
1114 | * | |||
1115 | * Parameters: | |||
1116 | * w - widget to dump | |||
1117 | * stream - stream to dump to | |||
1118 | * count - number of dumps we have performed | |||
1119 | * | |||
1120 | * Description: | |||
1121 | * Adds a child's name to the list. | |||
1122 | */ | |||
1123 | /* This is a trick/kludge. To make shared libraries happier (linking | |||
1124 | * against Xmu but not linking against Xt, and apparently even work | |||
1125 | * as we desire on SVR4, we need to avoid an explicit data reference | |||
1126 | * to applicationShellWidgetClass. XtIsTopLevelShell is known | |||
1127 | * (implementation dependent assumption!) to use a bit flag. So we | |||
1128 | * go that far. Then, we test whether it is an applicationShellWidget | |||
1129 | * class by looking for an explicit class name. Seems pretty safe. | |||
1130 | */ | |||
1131 | static Boolint | |||
1132 | isApplicationShell(Widget w) | |||
1133 | { | |||
1134 | register WidgetClass c; | |||
1135 | ||||
1136 | if (!XtIsTopLevelShell(w)(((Object)(w))->object.widget_class->core_class.class_inited & 0x80)) | |||
1137 | return (False0); | |||
1138 | for (c = XtClass(w)((w)->core.widget_class); c; c = c->core_class.superclass) | |||
1139 | if (strcmp(c->core_class.class_name, "ApplicationShell") == 0) | |||
1140 | return (True1); | |||
1141 | ||||
1142 | return (False0); | |||
1143 | } | |||
1144 | ||||
1145 | static void | |||
1146 | DumpChildren(Widget w, ProtocolStream *stream, unsigned short *count) | |||
1147 | { | |||
1148 | int i, num_children; | |||
1149 | Widget *children; | |||
1150 | unsigned long window; | |||
1151 | char *c_class; | |||
1152 | ||||
1153 | (*count)++; | |||
1154 | ||||
1155 | InsertWidget(stream, w); /* Insert the widget into the stream */ | |||
1156 | ||||
1157 | _XEditResPutString8(stream, XtName(w)); /* Insert name */ | |||
1158 | ||||
1159 | if (isApplicationShell(w)) | |||
1160 | c_class = ((ApplicationShellWidget)w)->application.class; | |||
1161 | else | |||
1162 | c_class = XtClass(w)((w)->core.widget_class)->core_class.class_name; | |||
1163 | ||||
1164 | _XEditResPutString8(stream, c_class); /* Insert class */ | |||
1165 | ||||
1166 | if (XtIsWidget(w)(((Object)(w))->object.widget_class->core_class.class_inited & 0x04)) | |||
1167 | if (XtIsRealized(w)(XtWindowOfObject(w) != 0L)) | |||
1168 | window = XtWindow(w)((w)->core.window); | |||
1169 | else | |||
1170 | window = EDITRES_IS_UNREALIZED0; | |||
1171 | else | |||
1172 | window = EDITRES_IS_OBJECT2; | |||
1173 | ||||
1174 | _XEditResPut32(stream, window); /* Insert window id */ | |||
1175 | ||||
1176 | /* | |||
1177 | * Find children and recurse | |||
1178 | */ | |||
1179 | num_children = FindChildren(w, &children, True1, True1, True1); | |||
1180 | for (i = 0; i < num_children; i++) | |||
1181 | DumpChildren(children[i], stream, count); | |||
1182 | ||||
1183 | XtFree((char *)children); | |||
1184 | } | |||
1185 | ||||
1186 | /************************************************************ | |||
1187 | * Code for getting the geometry of widgets | |||
1188 | ************************************************************/ | |||
1189 | /* | |||
1190 | * Function: | |||
1191 | * DoGetGeometry | |||
1192 | * | |||
1193 | * Parameters: | |||
1194 | * w - widget in the tree | |||
1195 | * event - event that caused this action | |||
1196 | * stream - protocol stream to add | |||
1197 | * | |||
1198 | * Description: | |||
1199 | * Retrieves the Geometry of each specified widget. | |||
1200 | * | |||
1201 | * Returns: | |||
1202 | * NULL | |||
1203 | */ | |||
1204 | static _Xconstconst char * | |||
1205 | DoGetGeometry(Widget w, EditresEvent *event, ProtocolStream *stream) | |||
1206 | { | |||
1207 | unsigned i; | |||
1208 | _Xconstconst char *str; | |||
1209 | GetGeomEvent *geom_event = (GetGeomEvent *)event; | |||
1210 | ||||
1211 | _XEditResPut16(stream, geom_event->num_entries); | |||
1212 | ||||
1213 | for (i = 0; i < geom_event->num_entries; i++) | |||
1214 | { | |||
1215 | /* | |||
1216 | * Send out the widget id | |||
1217 | */ | |||
1218 | _XEditResPutWidgetInfo(stream, &geom_event->widgets[i]); | |||
1219 | ||||
1220 | if ((str = VerifyWidget(w, &geom_event->widgets[i])) != NULL((void*)0)) | |||
1221 | { | |||
1222 | _XEditResPutBool_XEditResPut8(stream, True1); /* an error occured */ | |||
1223 | _XEditResPutString8(stream, str); /* set message */ | |||
1224 | } | |||
1225 | else | |||
1226 | ExecuteGetGeometry(geom_event->widgets[i].real_widget, stream); | |||
1227 | } | |||
1228 | ||||
1229 | return (NULL((void*)0)); | |||
1230 | } | |||
1231 | ||||
1232 | /* | |||
1233 | * Function: | |||
1234 | * ExecuteGetGeometry | |||
1235 | * | |||
1236 | * Parameters: | |||
1237 | * w - widget to get geometry | |||
1238 | * stream - stream to append to | |||
1239 | * | |||
1240 | * Description: | |||
1241 | * Gets the geometry for each widget specified. | |||
1242 | * | |||
1243 | * Returns: | |||
1244 | * True if no error occured. | |||
1245 | */ | |||
1246 | static void | |||
1247 | ExecuteGetGeometry(Widget w, ProtocolStream *stream) | |||
1248 | { | |||
1249 | int i; | |||
1250 | Boolean mapped_when_man; | |||
1251 | Dimension width, height, border_width; | |||
1252 | Arg args[8]; | |||
1253 | Cardinal num_args = 0; | |||
1254 | Position x, y; | |||
1255 | ||||
1256 | if (!XtIsRectObj(w)(((Object)(w))->object.widget_class->core_class.class_inited & 0x02) || (XtIsWidget(w)(((Object)(w))->object.widget_class->core_class.class_inited & 0x04) && !XtIsRealized(w)(XtWindowOfObject(w) != 0L))) | |||
1257 | { | |||
1258 | _XEditResPutBool_XEditResPut8(stream, False0); /* no error */ | |||
1259 | _XEditResPutBool_XEditResPut8(stream, False0); /* not visable */ | |||
1260 | for (i = 0; i < 5; i++) /* fill in extra space with 0's */ | |||
1261 | _XEditResPut16(stream, 0); | |||
1262 | return; | |||
1263 | } | |||
1264 | ||||
1265 | XtSetArg(args[num_args], XtNwidth, &width)((void)( (args[num_args]).name = (((char*)&XtStrings[872] )), (args[num_args]).value = (XtArgVal)(&width) )); num_args++; | |||
1266 | XtSetArg(args[num_args], XtNheight, &height)((void)( (args[num_args]).name = (((char*)&XtStrings[234] )), (args[num_args]).value = (XtArgVal)(&height) )); num_args++; | |||
1267 | XtSetArg(args[num_args], XtNborderWidth, &border_width)((void)( (args[num_args]).name = (((char*)&XtStrings[124] )), (args[num_args]).value = (XtArgVal)(&border_width) )); num_args++; | |||
1268 | XtSetArg(args[num_args], XtNmappedWhenManaged, &mapped_when_man)((void)( (args[num_args]).name = (((char*)&XtStrings[453] )), (args[num_args]).value = (XtArgVal)(&mapped_when_man) )); | |||
1269 | num_args++; | |||
1270 | XtGetValues(w, args, num_args); | |||
1271 | ||||
1272 | if (!(XtIsManaged(w) && mapped_when_man) && XtIsWidget(w)(((Object)(w))->object.widget_class->core_class.class_inited & 0x04)) | |||
1273 | { | |||
1274 | XWindowAttributes attrs; | |||
1275 | ||||
1276 | /* | |||
1277 | * The toolkit does not maintain mapping state, we have | |||
1278 | * to go to the server | |||
1279 | */ | |||
1280 | if (XGetWindowAttributes(XtDisplay(w)(((w)->core.screen)->display), XtWindow(w)((w)->core.window), &attrs) != 0) | |||
1281 | { | |||
1282 | if (attrs.map_state != IsViewable2) | |||
1283 | { | |||
1284 | _XEditResPutBool_XEditResPut8(stream, False0); /* no error */ | |||
1285 | _XEditResPutBool_XEditResPut8(stream, False0); /* not visable */ | |||
1286 | for (i = 0; i < 5; i++) /* fill in extra space with 0's */ | |||
1287 | _XEditResPut16(stream, 0); | |||
1288 | return; | |||
1289 | } | |||
1290 | } | |||
1291 | else | |||
1292 | { | |||
1293 | _XEditResPut8(stream, True1); /* Error occured. */ | |||
1294 | _XEditResPutString8(stream, "XGetWindowAttributes failed."); | |||
1295 | return; | |||
1296 | } | |||
1297 | } | |||
1298 | ||||
1299 | XtTranslateCoords(w, -((int) border_width), -((int) border_width), &x, &y); | |||
1300 | ||||
1301 | _XEditResPutBool_XEditResPut8(stream, False0); /* no error */ | |||
1302 | _XEditResPutBool_XEditResPut8(stream, True1); /* Visable */ | |||
1303 | _XEditResPut16(stream, x); | |||
1304 | _XEditResPut16(stream, y); | |||
1305 | _XEditResPut16(stream, width); | |||
1306 | _XEditResPut16(stream, height); | |||
1307 | _XEditResPut16(stream, border_width); | |||
1308 | } | |||
1309 | ||||
1310 | /************************************************************ | |||
1311 | * Code for executing FindChild | |||
1312 | ************************************************************/ | |||
1313 | /* | |||
1314 | * Function: | |||
1315 | * PositionInChild | |||
1316 | * | |||
1317 | * Parameters: | |||
1318 | * child - child widget to check | |||
1319 | * x - location of point to check in the parent's coord space | |||
1320 | * y - "" | |||
1321 | * | |||
1322 | * Description: | |||
1323 | * Returns true if this location is in the child. | |||
1324 | */ | |||
1325 | static Boolint | |||
1326 | PositionInChild(Widget child, int x, int y) | |||
1327 | { | |||
1328 | Arg args[6]; | |||
1329 | Cardinal num; | |||
1330 | Dimension width, height, border_width; | |||
1331 | Position child_x, child_y; | |||
1332 | Boolean mapped_when_managed; | |||
1333 | ||||
1334 | if (!XtIsRectObj(child)(((Object)(child))->object.widget_class->core_class.class_inited & 0x02)) /* we must at least be a rect obj */ | |||
1335 | return (False0); | |||
1336 | ||||
1337 | num = 0; | |||
1338 | XtSetArg(args[num], XtNmappedWhenManaged, &mapped_when_managed)((void)( (args[num]).name = (((char*)&XtStrings[453])), ( args[num]).value = (XtArgVal)(&mapped_when_managed) )); num++; | |||
1339 | XtSetArg(args[num], XtNwidth, &width)((void)( (args[num]).name = (((char*)&XtStrings[872])), ( args[num]).value = (XtArgVal)(&width) )); num++; | |||
1340 | XtSetArg(args[num], XtNheight, &height)((void)( (args[num]).name = (((char*)&XtStrings[234])), ( args[num]).value = (XtArgVal)(&height) )); num++; | |||
1341 | XtSetArg(args[num], XtNx, &child_x)((void)( (args[num]).name = (((char*)&XtStrings[885])), ( args[num]).value = (XtArgVal)(&child_x) )); num++; | |||
1342 | XtSetArg(args[num], XtNy, &child_y)((void)( (args[num]).name = (((char*)&XtStrings[887])), ( args[num]).value = (XtArgVal)(&child_y) )); num++; | |||
1343 | XtSetArg(args[num], XtNborderWidth, &border_width)((void)( (args[num]).name = (((char*)&XtStrings[124])), ( args[num]).value = (XtArgVal)(&border_width) )); num++; | |||
1344 | XtGetValues(child, args, num); | |||
1345 | ||||
1346 | /* | |||
1347 | * The only way we will know of the widget is mapped is to see if | |||
1348 | * mapped when managed is True and this is a managed child. Otherwise | |||
1349 | * we will have to ask the server if this window is mapped | |||
1350 | */ | |||
1351 | if (XtIsWidget(child)(((Object)(child))->object.widget_class->core_class.class_inited & 0x04) && !(mapped_when_managed && XtIsManaged(child))) | |||
1352 | { | |||
1353 | XWindowAttributes attrs; | |||
1354 | ||||
1355 | if (XGetWindowAttributes(XtDisplay(child)(((child)->core.screen)->display), XtWindow(child)((child)->core.window), &attrs) | |||
1356 | && attrs.map_state != IsViewable2) | |||
1357 | return (False0); | |||
1358 | } | |||
1359 | ||||
1360 | return ((x >= child_x) | |||
1361 | && (x <= (child_x + (Position)width + 2 * (Position)border_width)) | |||
1362 | && (y >= child_y) | |||
1363 | && (y <= (child_y + (Position)height + 2 * (Position)border_width))); | |||
1364 | } | |||
1365 | ||||
1366 | /* | |||
1367 | * Function: | |||
1368 | * _FindChild | |||
1369 | * | |||
1370 | * Parameters: | |||
1371 | * parent - widget that is known to contain the point specified | |||
1372 | * x - point in coordinates relative to the widget specified | |||
1373 | * y - "" | |||
1374 | * | |||
1375 | * Description: | |||
1376 | * Finds the child that actually contains the point shown. | |||
1377 | */ | |||
1378 | static Widget | |||
1379 | _FindChild(Widget parent, int x, int y) | |||
1380 | { | |||
1381 | Widget *children; | |||
1382 | int i = FindChildren(parent, &children, True1, False0, True1); | |||
1383 | ||||
1384 | while (i > 0) | |||
1385 | { | |||
1386 | i--; | |||
1387 | ||||
1388 | if (PositionInChild(children[i], x, y)) | |||
1389 | { | |||
1390 | Widget child = children[i]; | |||
1391 | ||||
1392 | XtFree((char *)children); | |||
1393 | return (_FindChild(child, x - child->core.x, y - child->core.y)); | |||
1394 | } | |||
1395 | } | |||
1396 | ||||
1397 | XtFree((char *)children); | |||
1398 | ||||
1399 | return (parent); | |||
1400 | } | |||
1401 | ||||
1402 | /* | |||
1403 | * Function: | |||
1404 | * DoFindChild | |||
1405 | * | |||
1406 | * Parameters: | |||
1407 | * w - widget in the tree | |||
1408 | * event - event that caused this action | |||
1409 | * stream - protocol stream to add | |||
1410 | * Description: | |||
1411 | * Finds the child that contains the location specified. | |||
1412 | * | |||
1413 | * Returns: | |||
1414 | * An allocated error message if something went horribly wrong and | |||
1415 | * no set values were performed, else NULL. | |||
1416 | */ | |||
1417 | static _Xconstconst char * | |||
1418 | DoFindChild(Widget w, EditresEvent *event, ProtocolStream *stream) | |||
1419 | { | |||
1420 | _Xconstconst char *str; | |||
1421 | Widget parent, child; | |||
1422 | Position parent_x, parent_y; | |||
1423 | FindChildEvent *find_event = (FindChildEvent *)event; | |||
1424 | ||||
1425 | if ((str = VerifyWidget(w, find_event->widgets)) != NULL((void*)0)) | |||
1426 | return (str); | |||
1427 | ||||
1428 | parent = find_event->widgets->real_widget; | |||
1429 | ||||
1430 | XtTranslateCoords(parent, (Position) 0, (Position) 0, | |||
1431 | &parent_x, &parent_y); | |||
1432 | ||||
1433 | child = _FindChild(parent, find_event->x - (int) parent_x, | |||
1434 | find_event->y - (int) parent_y); | |||
1435 | ||||
1436 | InsertWidget(stream, child); | |||
1437 | ||||
1438 | return (NULL((void*)0)); | |||
1439 | } | |||
1440 | ||||
1441 | /************************************************************ | |||
1442 | * Procedures for performing GetResources | |||
1443 | ************************************************************/ | |||
1444 | /* | |||
1445 | * Function: | |||
1446 | * DoGetResources | |||
1447 | * | |||
1448 | * Parameters: | |||
1449 | * w - widget in the tree | |||
1450 | * event - event that caused this action | |||
1451 | * stream - protocol stream to add | |||
1452 | * | |||
1453 | * Description: | |||
1454 | * Gets the Resources associated with the widgets passed. | |||
1455 | * | |||
1456 | * Returns: | |||
1457 | * NULL | |||
1458 | */ | |||
1459 | static _Xconstconst char * | |||
1460 | DoGetResources(Widget w, EditresEvent *event, ProtocolStream *stream) | |||
1461 | { | |||
1462 | unsigned int i; | |||
1463 | _Xconstconst char *str; | |||
1464 | GetResEvent *res_event = (GetResEvent *)event; | |||
1465 | ||||
1466 | _XEditResPut16(stream, res_event->num_entries); /* number of replys */ | |||
1467 | ||||
1468 | for (i = 0; i < res_event->num_entries; i++) | |||
1469 | { | |||
1470 | /* | |||
1471 | * Send out the widget id | |||
1472 | */ | |||
1473 | _XEditResPutWidgetInfo(stream, &res_event->widgets[i]); | |||
1474 | if ((str = VerifyWidget(w, &res_event->widgets[i])) != NULL((void*)0)) | |||
1475 | { | |||
1476 | _XEditResPutBool_XEditResPut8(stream, True1); /* an error occured */ | |||
1477 | _XEditResPutString8(stream, str); /* set message */ | |||
1478 | } | |||
1479 | else | |||
1480 | { | |||
1481 | _XEditResPutBool_XEditResPut8(stream, False0); /* no error occured */ | |||
1482 | ExecuteGetResources(res_event->widgets[i].real_widget, stream); | |||
1483 | } | |||
1484 | } | |||
1485 | ||||
1486 | return (NULL((void*)0)); | |||
1487 | } | |||
1488 | ||||
1489 | /* Function: | |||
1490 | * ExecuteGetResources | |||
1491 | * | |||
1492 | * Parameters: | |||
1493 | * w - widget to get resources on | |||
1494 | * stream - protocol stream | |||
1495 | * | |||
1496 | * Description: | |||
1497 | * Gets the resources for any individual widget | |||
1498 | */ | |||
1499 | static void | |||
1500 | ExecuteGetResources(Widget w, ProtocolStream *stream) | |||
1501 | { | |||
1502 | XtResourceList norm_list, cons_list; | |||
1503 | Cardinal num_norm, num_cons; | |||
1504 | register Cardinal i; | |||
1505 | ||||
1506 | /* | |||
1507 | * Get Normal Resources | |||
1508 | */ | |||
1509 | XtGetResourceList(XtClass(w)((w)->core.widget_class), &norm_list, &num_norm); | |||
1510 | ||||
1511 | if (XtParent(w)((w)->core.parent) != NULL((void*)0)) | |||
1512 | XtGetConstraintResourceList(XtClass(XtParent(w))((((w)->core.parent))->core.widget_class), &cons_list,&num_cons); | |||
1513 | else | |||
1514 | num_cons = 0; | |||
1515 | ||||
1516 | _XEditResPut16(stream, num_norm + num_cons); /* how many resources */ | |||
1517 | ||||
1518 | /* | |||
1519 | * Insert all the normal resources | |||
1520 | */ | |||
1521 | for (i = 0; i < num_norm; i++) | |||
1522 | { | |||
1523 | _XEditResPutResourceType_XEditResPut8(stream, NormalResource); | |||
1524 | _XEditResPutString8(stream, norm_list[i].resource_name); | |||
1525 | _XEditResPutString8(stream, norm_list[i].resource_class); | |||
1526 | _XEditResPutString8(stream, norm_list[i].resource_type); | |||
1527 | } | |||
1528 | XtFree((char *)norm_list); | |||
1529 | ||||
1530 | /* | |||
1531 | * Insert all the constraint resources | |||
1532 | */ | |||
1533 | if (num_cons > 0) | |||
1534 | { | |||
1535 | for (i = 0; i < num_cons; i++) | |||
1536 | { | |||
1537 | _XEditResPutResourceType_XEditResPut8(stream, ConstraintResource); | |||
1538 | _XEditResPutString8(stream, cons_list[i].resource_name); | |||
1539 | _XEditResPutString8(stream, cons_list[i].resource_class); | |||
1540 | _XEditResPutString8(stream, cons_list[i].resource_type); | |||
1541 | } | |||
1542 | XtFree((char *)cons_list); | |||
1543 | } | |||
1544 | } | |||
1545 | ||||
1546 | /* | |||
1547 | * Function: | |||
1548 | * DumpValues | |||
1549 | * | |||
1550 | * Parameters: | |||
1551 | * event - event that caused this action | |||
1552 | * stream - protocol stream to add | |||
1553 | * | |||
1554 | * Description: | |||
1555 | * Returns resource values to the resource editor. | |||
1556 | * | |||
1557 | * Returns: | |||
1558 | * NULL | |||
1559 | */ | |||
1560 | /*ARGSUSED*/ | |||
1561 | static _Xconstconst char * | |||
1562 | DumpValues(Widget w, EditresEvent* event, ProtocolStream* stream) | |||
1563 | { | |||
1564 | _Xconstconst char *str; | |||
1565 | Arg warg[1]; | |||
1566 | _Xconstconst _XtStringchar* res_value = NULL((void*)0); | |||
1567 | GetValuesEvent *gv_event = (GetValuesEvent *)event; | |||
1568 | ||||
1569 | /* put the count in the stream */ | |||
1570 | _XEditResPut16(stream, (unsigned int)1); | |||
1571 | ||||
1572 | /* | |||
1573 | * Get the resource of the widget asked for by the | |||
1574 | * resource editor and insert it into the stream | |||
1575 | */ | |||
1576 | XtSetArg(warg[0], gv_event->name, &res_value)((void)( (warg[0]).name = (gv_event->name), (warg[0]).value = (XtArgVal)(&res_value) )); | |||
1577 | ||||
1578 | if ((str = VerifyWidget(w, &gv_event->widgets[0])) != NULL((void*)0)) | |||
1579 | _XEditResPutString8(stream, str); | |||
1580 | else | |||
1581 | { | |||
1582 | _XEditresGetStringValues(gv_event->widgets[0].real_widget, warg, 1); | |||
1583 | if (!res_value) | |||
1584 | res_value = "NoValue"; | |||
1585 | _XEditResPutString8(stream, res_value); | |||
1586 | } | |||
1587 | ||||
1588 | return (NULL((void*)0)); | |||
1589 | } | |||
1590 | ||||
1591 | /************************************************************ | |||
1592 | * Code for inserting values into the protocol stream | |||
1593 | ************************************************************/ | |||
1594 | /* | |||
1595 | * Function: | |||
1596 | * InsertWidget | |||
1597 | * | |||
1598 | * Parameters: | |||
1599 | * stream - protocol stream | |||
1600 | * w - widget to insert | |||
1601 | * | |||
1602 | * Description: | |||
1603 | * Inserts the full parent hierarchy of this widget into the protocol | |||
1604 | * stream as a widget list. | |||
1605 | */ | |||
1606 | static void | |||
1607 | InsertWidget(ProtocolStream *stream, Widget w) | |||
1608 | { | |||
1609 | Widget temp; | |||
1610 | unsigned long *widget_list; | |||
1611 | register int i, num_widgets; | |||
1612 | ||||
1613 | for (temp = w, i = 0; temp != NULL((void*)0); temp = XtParent(temp)((temp)->core.parent), i++) | |||
1614 | ; | |||
1615 | ||||
1616 | num_widgets = i; | |||
1617 | widget_list = (unsigned long *)XtMalloc(sizeof(unsigned long) * num_widgets); | |||
1618 | ||||
1619 | /* | |||
1620 | * Put the widgets into the list | |||
1621 | * make sure that they are inserted in the list from parent -> child | |||
1622 | */ | |||
1623 | for (i--, temp = w; temp != NULL((void*)0); temp = XtParent(temp)((temp)->core.parent), i--) | |||
1624 | widget_list[i] = (unsigned long)temp; | |||
1625 | ||||
1626 | _XEditResPut16(stream, num_widgets); /* insert number of widgets */ | |||
1627 | for (i = 0; i < num_widgets; i++) /* insert Widgets themselves */ | |||
1628 | _XEditResPut32(stream, widget_list[i]); | |||
1629 | ||||
1630 | XtFree((char *)widget_list); | |||
1631 | } | |||
1632 | ||||
1633 | /************************************************************ | |||
1634 | * All of the following routines are public | |||
1635 | ************************************************************/ | |||
1636 | /* | |||
1637 | * Function: | |||
1638 | * _XEditResPutString8 | |||
1639 | * | |||
1640 | * Parameters: | |||
1641 | * stream - stream to insert string into | |||
1642 | * str - string to insert | |||
1643 | * | |||
1644 | * Description: | |||
1645 | * Inserts a string into the protocol stream. | |||
1646 | */ | |||
1647 | void | |||
1648 | _XEditResPutString8(ProtocolStream *stream, _Xconstconst char *str) | |||
1649 | { | |||
1650 | int i, len = strlen(str); | |||
1651 | ||||
1652 | _XEditResPut16(stream, len); | |||
1653 | for (i = 0; i < len; i++, str++) | |||
1654 | _XEditResPut8(stream, *str); | |||
1655 | } | |||
1656 | ||||
1657 | /* | |||
1658 | * Function: | |||
1659 | * _XEditResPut8 | |||
1660 | * | |||
1661 | * Parameters: | |||
1662 | * stream - stream to insert string into | |||
1663 | * value - value to insert | |||
1664 | * | |||
1665 | * Description: | |||
1666 | * Inserts an 8 bit integer into the protocol stream. | |||
1667 | */ | |||
1668 | void | |||
1669 | _XEditResPut8(ProtocolStream *stream, unsigned int value) | |||
1670 | { | |||
1671 | unsigned char temp; | |||
1672 | ||||
1673 | if (stream->size >= stream->alloc) | |||
1674 | { | |||
1675 | stream->alloc += 100; | |||
1676 | stream->real_top = (unsigned char *) | |||
1677 | XtRealloc((char *)stream->real_top, stream->alloc + HEADER_SIZE6); | |||
1678 | stream->top = stream->real_top + HEADER_SIZE6; | |||
1679 | stream->current = stream->top + stream->size; | |||
1680 | } | |||
1681 | ||||
1682 | temp = (unsigned char) (value & BYTE_MASK255); | |||
1683 | *((stream->current)++) = temp; | |||
1684 | (stream->size)++; | |||
1685 | } | |||
1686 | ||||
1687 | /* | |||
1688 | * Function: | |||
1689 | * _XEditResPut16 | |||
1690 | * | |||
1691 | * Arguments: | |||
1692 | * stream - stream to insert string into | |||
1693 | * value - value to insert | |||
1694 | * | |||
1695 | * Description: | |||
1696 | * Inserts a 16 bit integer into the protocol stream. | |||
1697 | */ | |||
1698 | void | |||
1699 | _XEditResPut16(ProtocolStream *stream, unsigned int value) | |||
1700 | { | |||
1701 | _XEditResPut8(stream, (value >> XER_NBBY8) & BYTE_MASK255); | |||
1702 | _XEditResPut8(stream, value & BYTE_MASK255); | |||
1703 | } | |||
1704 | ||||
1705 | /* | |||
1706 | * Function: | |||
1707 | * _XEditResPut32 | |||
1708 | * | |||
1709 | * Arguments: | |||
1710 | * stream - stream to insert string into | |||
1711 | * value - value to insert | |||
1712 | * | |||
1713 | * Description: | |||
1714 | * Inserts a 32 bit integer into the protocol stream. | |||
1715 | */ | |||
1716 | void | |||
1717 | _XEditResPut32(ProtocolStream *stream, unsigned long value) | |||
1718 | { | |||
1719 | int i; | |||
1720 | ||||
1721 | for (i = 3; i >= 0; i--) | |||
1722 | _XEditResPut8(stream, (value >> (XER_NBBY8 * i)) & BYTE_MASK255); | |||
1723 | } | |||
1724 | ||||
1725 | /* | |||
1726 | * Function: | |||
1727 | * _XEditResPutWidgetInfo | |||
1728 | * | |||
1729 | * Parameters: | |||
1730 | * stream - stream to insert widget info into | |||
1731 | * info - info to insert | |||
1732 | * | |||
1733 | * Description: | |||
1734 | * Inserts the widget info into the protocol stream. | |||
1735 | */ | |||
1736 | void | |||
1737 | _XEditResPutWidgetInfo(ProtocolStream *stream, WidgetInfo *info) | |||
1738 | { | |||
1739 | unsigned int i; | |||
1740 | ||||
1741 | _XEditResPut16(stream, info->num_widgets); | |||
1742 | for (i = 0; i < info->num_widgets; i++) | |||
1743 | _XEditResPut32(stream, info->ids[i]); | |||
1744 | } | |||
1745 | ||||
1746 | /************************************************************ | |||
1747 | * Code for retrieving values from the protocol stream | |||
1748 | ************************************************************/ | |||
1749 | /* | |||
1750 | * Function: | |||
1751 | * _XEditResResetStream | |||
1752 | * | |||
1753 | * Parameters: | |||
1754 | * stream - stream to reset | |||
1755 | * | |||
1756 | * Description: | |||
1757 | * Resets the protocol stream. | |||
1758 | */ | |||
1759 | void | |||
1760 | _XEditResResetStream(ProtocolStream *stream) | |||
1761 | { | |||
1762 | stream->current = stream->top; | |||
1763 | stream->size = 0; | |||
1764 | if (stream->real_top == NULL((void*)0)) | |||
1765 | { | |||
1766 | stream->real_top = (unsigned char *) | |||
1767 | XtRealloc((char *)stream->real_top, stream->alloc + HEADER_SIZE6); | |||
1768 | stream->top = stream->real_top + HEADER_SIZE6; | |||
1769 | stream->current = stream->top + stream->size; | |||
1770 | } | |||
1771 | } | |||
1772 | ||||
1773 | /* | |||
1774 | * NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE | |||
1775 | * | |||
1776 | * The only modified field if the "current" field | |||
1777 | * | |||
1778 | * The only fields that must be set correctly are the "current", "top" | |||
1779 | * and "size" fields. | |||
1780 | */ | |||
1781 | /* | |||
1782 | * Function: | |||
1783 | * _XEditResGetg8 | |||
1784 | * | |||
1785 | * Parameters: | |||
1786 | * stream - protocol stream | |||
1787 | * value - a pointer to value to return | |||
1788 | * | |||
1789 | * Description: | |||
1790 | * Retrieves an unsigned 8 bit value from the protocol stream. | |||
1791 | * | |||
1792 | * Returns: | |||
1793 | * True if sucessful | |||
1794 | */ | |||
1795 | Boolint | |||
1796 | _XEditResGet8(ProtocolStream *stream, unsigned char *value) | |||
1797 | { | |||
1798 | if (stream->size < (unsigned long)(stream->current - stream->top)) | |||
1799 | return (False0); | |||
1800 | ||||
1801 | *value = *((stream->current)++); | |||
1802 | return (True1); | |||
1803 | } | |||
1804 | ||||
1805 | /* | |||
1806 | * Function: | |||
1807 | * _XEditResGet16 | |||
1808 | * | |||
1809 | * Parameters: | |||
1810 | * stream - protocol stream | |||
1811 | * value - pointer to return value | |||
1812 | * | |||
1813 | * Description: | |||
1814 | * Retrieves an unsigned 16 bit value from the protocol stream. | |||
1815 | * | |||
1816 | * Returns: | |||
1817 | * True if sucessful | |||
1818 | */ | |||
1819 | Boolint | |||
1820 | _XEditResGet16(ProtocolStream *stream, unsigned short *value) | |||
1821 | { | |||
1822 | unsigned char temp1, temp2; | |||
1823 | ||||
1824 | if (!(_XEditResGet8(stream, &temp1) && _XEditResGet8(stream, &temp2))) | |||
1825 | return (False0); | |||
1826 | ||||
1827 | *value = ((unsigned short)temp1 << XER_NBBY8) + (unsigned short)temp2; | |||
1828 | return (True1); | |||
1829 | } | |||
1830 | ||||
1831 | /* | |||
1832 | * Function: | |||
1833 | * _XEditResGetSigned16 | |||
1834 | * | |||
1835 | * Parameters: | |||
1836 | * stream - protocol stream | |||
1837 | * value - pointer to return value | |||
1838 | * | |||
1839 | * Description: | |||
1840 | * Retrieves an signed 16 bit value from the protocol stream. | |||
1841 | * | |||
1842 | * Returns: | |||
1843 | * True if sucessful | |||
1844 | */ | |||
1845 | Boolint | |||
1846 | _XEditResGetSigned16(ProtocolStream *stream, short *value) | |||
1847 | { | |||
1848 | unsigned char temp1, temp2; | |||
1849 | ||||
1850 | if (!(_XEditResGet8(stream, &temp1) && _XEditResGet8(stream, &temp2))) | |||
1851 | return (False0); | |||
1852 | ||||
1853 | if (temp1 & (1 << (XER_NBBY8 - 1))) /* If the sign bit is active */ | |||
1854 | { | |||
1855 | *value = -1; /* store all 1's */ | |||
1856 | *value &= (temp1 << XER_NBBY8); /* Now and in the MSB */ | |||
1857 | *value &= temp2; /* and LSB */ | |||
1858 | } | |||
1859 | else | |||
1860 | *value = ((unsigned short)temp1 << XER_NBBY8) + (unsigned short)temp2; | |||
1861 | ||||
1862 | return (True1); | |||
1863 | } | |||
1864 | ||||
1865 | /* | |||
1866 | * Function: | |||
1867 | * _XEditResGet32 | |||
1868 | * | |||
1869 | * Parameters: | |||
1870 | * stream - protocol stream | |||
1871 | * value - pointer to return value | |||
1872 | * | |||
1873 | * Description: | |||
1874 | * Retrieves an unsigned 32 bit value from the protocol stream. | |||
1875 | * | |||
1876 | * Returns: | |||
1877 | * True if sucessful | |||
1878 | */ | |||
1879 | Boolint | |||
1880 | _XEditResGet32(ProtocolStream *stream, unsigned long *value) | |||
1881 | { | |||
1882 | unsigned short temp1, temp2; | |||
1883 | ||||
1884 | if (!(_XEditResGet16(stream, &temp1) && _XEditResGet16(stream, &temp2))) | |||
1885 | return (False0); | |||
1886 | ||||
1887 | *value = ((unsigned short)temp1 << (XER_NBBY8 * 2)) + (unsigned short)temp2; | |||
1888 | return (True1); | |||
1889 | } | |||
1890 | ||||
1891 | /* Function: | |||
1892 | * _XEditResGetString8 | |||
1893 | * | |||
1894 | * Parameters: | |||
1895 | * stream - protocol stream | |||
1896 | * str - string to retrieve | |||
1897 | * | |||
1898 | * Description: | |||
1899 | * Retrieves an 8 bit string value from the protocol stream. | |||
1900 | * | |||
1901 | * Returns: | |||
1902 | * True if retrieval was successful | |||
1903 | */ | |||
1904 | Boolint | |||
1905 | _XEditResGetString8(ProtocolStream *stream, char **str) | |||
1906 | { | |||
1907 | unsigned short len; | |||
1908 | register unsigned i; | |||
1909 | ||||
1910 | if (!_XEditResGet16(stream, &len)) | |||
1911 | return (False0); | |||
1912 | ||||
1913 | *str = XtMalloc(sizeof(char) * (len + 1)); | |||
1914 | ||||
1915 | for (i = 0; i < len; i++) | |||
1916 | { | |||
1917 | if (!_XEditResGet8(stream, (unsigned char *)*str + i)) | |||
1918 | { | |||
1919 | XtFree(*str); | |||
1920 | *str = NULL((void*)0); | |||
1921 | return (False0); | |||
1922 | } | |||
1923 | } | |||
1924 | (*str)[i] = '\0'; | |||
1925 | ||||
1926 | return (True1); | |||
1927 | } | |||
1928 | ||||
1929 | /* | |||
1930 | * Function: | |||
1931 | * _XEditResGetWidgetInfo | |||
1932 | * | |||
1933 | * Parameters: | |||
1934 | * stream - protocol stream | |||
1935 | * info - widget info struct to store into | |||
1936 | * | |||
1937 | * Description: | |||
1938 | * Retrieves the list of widgets that follow and stores them in the | |||
1939 | * widget info structure provided. | |||
1940 | * | |||
1941 | * Returns: | |||
1942 | * True if retrieval was successful | |||
1943 | */ | |||
1944 | Boolint | |||
1945 | _XEditResGetWidgetInfo(ProtocolStream *stream, WidgetInfo *info) | |||
1946 | { | |||
1947 | unsigned int i; | |||
1948 | ||||
1949 | if (!_XEditResGet16(stream, &info->num_widgets)) | |||
1950 | return (False0); | |||
1951 | ||||
1952 | info->ids = (unsigned long *)XtMalloc(sizeof(long) * info->num_widgets); | |||
1953 | ||||
1954 | for (i = 0; i < info->num_widgets; i++) | |||
1955 | { | |||
1956 | if (!_XEditResGet32(stream, info->ids + i)) | |||
1957 | { | |||
1958 | XtFree((char *)info->ids); | |||
1959 | info->ids = NULL((void*)0); | |||
1960 | return (False0); | |||
1961 | } | |||
1962 | #if defined(LONG64) || defined(WORD64) | |||
1963 | info->ids[i] |= globals.base_address; | |||
1964 | #endif | |||
1965 | } | |||
1966 | return (True1); | |||
1967 | } | |||
1968 | ||||
1969 | /************************************************************ | |||
1970 | * Code for Loading the EditresBlock resource | |||
1971 | ************************************************************/ | |||
1972 | /* | |||
1973 | * Function: | |||
1974 | * CvStringToBlock | |||
1975 | * | |||
1976 | * Parameters: | |||
1977 | * dpy - display | |||
1978 | * args - unused | |||
1979 | * num_args - unused | |||
1980 | * from_val - value to convert | |||
1981 | * to_val - where to store | |||
1982 | * converter_data - unused | |||
1983 | * | |||
1984 | * Description: | |||
1985 | * Converts a string to an editres block value. | |||
1986 | * | |||
1987 | * Returns: | |||
1988 | * True if conversion was sucessful | |||
1989 | */ | |||
1990 | /*ARGSUSED*/ | |||
1991 | static Boolean | |||
1992 | CvtStringToBlock(Display *dpy, XrmValue *args, Cardinal *num_args, | |||
1993 | XrmValue *from_val, XrmValue *to_val, | |||
1994 | XtPointer *converter_data) | |||
1995 | { | |||
1996 | char ptr[16]; | |||
1997 | static EditresBlock block; | |||
1998 | ||||
1999 | XmuNCopyISOLatin1Lowered(ptr, from_val->addr, sizeof(ptr)); | |||
2000 | ||||
2001 | if (streq(ptr, "none")(strcmp((ptr), ("none")) == 0)) | |||
2002 | block = BlockNone; | |||
2003 | else if (streq(ptr, "setvalues")(strcmp((ptr), ("setvalues")) == 0)) | |||
2004 | block = BlockSetValues; | |||
2005 | else if (streq(ptr, "all")(strcmp((ptr), ("all")) == 0)) | |||
2006 | block = BlockAll; | |||
2007 | else | |||
2008 | { | |||
2009 | Cardinal num_params = 1; | |||
2010 | String params[1]; | |||
2011 | ||||
2012 | params[0] = from_val->addr; | |||
2013 | XtAppWarningMsg(XtDisplayToApplicationContext(dpy), | |||
2014 | "CvtStringToBlock", "unknownValue", "EditresError", | |||
2015 | "Could not convert string \"%s\" to EditresBlock.", | |||
2016 | params, &num_params); | |||
2017 | return FALSE0; | |||
2018 | } | |||
2019 | ||||
2020 | if (to_val->addr != NULL((void*)0)) | |||
2021 | { | |||
2022 | if (to_val->size < sizeof(EditresBlock)) | |||
2023 | { | |||
2024 | to_val->size = sizeof(EditresBlock); | |||
2025 | return FALSE0; | |||
2026 | } | |||
2027 | *(EditresBlock *)(to_val->addr) = block; | |||
2028 | } | |||
2029 | else | |||
2030 | to_val->addr = (XtPointer)block; | |||
2031 | ||||
2032 | to_val->size = sizeof(EditresBlock); | |||
2033 | return TRUE1; | |||
2034 | } | |||
2035 | ||||
2036 | #define XtREditresBlock"EditresBlock" "EditresBlock" | |||
2037 | /* | |||
2038 | * Function: | |||
2039 | * LoadResources | |||
2040 | * | |||
2041 | * Parameters: | |||
2042 | * w - any widget in the tree | |||
2043 | * | |||
2044 | * Description: | |||
2045 | * Loads a global resource the determines of this application should | |||
2046 | * allow Editres requests. | |||
2047 | */ | |||
2048 | static void | |||
2049 | LoadResources(Widget w) | |||
2050 | { | |||
2051 | static XtResource resources[] = { | |||
2052 | {"editresBlock", "EditresBlock", XtREditresBlock"EditresBlock", sizeof(EditresBlock), | |||
2053 | XtOffsetOf(Globals, block)__builtin_offsetof(Globals, block), XtRImmediate((char*)&XtStrings[1695]), (XtPointer)BlockNone} | |||
2054 | }; | |||
2055 | ||||
2056 | for (; XtParent(w)((w)->core.parent) != NULL((void*)0); w = XtParent(w)((w)->core.parent)) | |||
2057 | ; | |||
2058 | ||||
2059 | XtAppSetTypeConverter(XtWidgetToApplicationContext(w), | |||
2060 | XtRString((char*)&XtStrings[1797]), XtREditresBlock"EditresBlock", CvtStringToBlock, | |||
2061 | NULL((void*)0), 0, XtCacheAll0x002, NULL((void*)0)); | |||
2062 | ||||
2063 | XtGetApplicationResources(w, (XtPointer)&globals, resources, | |||
2064 | XtNumber(resources)((Cardinal) (sizeof(resources) / sizeof(resources[0]))), NULL((void*)0), 0); | |||
2065 | } | |||
2066 | ||||
2067 | /* | |||
2068 | * Function: | |||
2069 | * _XEditresGetStringValues | |||
2070 | * | |||
2071 | * Parameters: | |||
2072 | * w - widget | |||
2073 | * warg - where to store result | |||
2074 | * numargs - unused | |||
2075 | */ | |||
2076 | /*ARGSUSED*/ | |||
2077 | static void | |||
2078 | _XEditresGetStringValues(Widget w, Arg *warg, int numargs) | |||
2079 | { | |||
2080 | static char buffer[32]; | |||
2081 | XtResourceList res_list; | |||
2082 | Cardinal num_res; | |||
2083 | XtResource *res = NULL((void*)0); | |||
2084 | long value; | |||
2085 | Cardinal i; | |||
2086 | char *string = ""; | |||
2087 | Arg args[1]; | |||
2088 | XrmValue to, from; | |||
2089 | ||||
2090 | /* | |||
2091 | * Look for the resource | |||
2092 | */ | |||
2093 | XtGetResourceList(XtClass(w)((w)->core.widget_class), &res_list, &num_res); | |||
2094 | for (i = 0; i < num_res; i++) | |||
2095 | if (strcmp(res_list[i].resource_name, warg->name) == 0) | |||
2096 | { | |||
2097 | res = &res_list[i]; | |||
2098 | break; | |||
2099 | } | |||
2100 | ||||
2101 | if (res == NULL((void*)0) && XtParent(w)((w)->core.parent) != NULL((void*)0)) | |||
2102 | { | |||
2103 | XtFree((char *)res_list); | |||
2104 | XtGetConstraintResourceList(XtClass(XtParent(w))((((w)->core.parent))->core.widget_class), &res_list, &num_res); | |||
2105 | for (i = 0; i < num_res; i++) | |||
2106 | if (strcmp(res_list[i].resource_name, warg->name) == 0) | |||
2107 | { | |||
2108 | res = &res_list[i]; | |||
2109 | break; | |||
2110 | } | |||
2111 | } | |||
2112 | ||||
2113 | if (res == NULL((void*)0)) | |||
2114 | { | |||
2115 | /* Couldn't find resource */ | |||
2116 | ||||
2117 | XtFree((char *)res_list); | |||
2118 | *(XtPointer *)warg->value = NULL((void*)0); | |||
2119 | return; | |||
2120 | } | |||
2121 | ||||
2122 | /* try to get the value in the proper size */ | |||
2123 | switch (res->resource_size) | |||
2124 | { | |||
2125 | #ifdef LONG64 | |||
2126 | long v8; | |||
2127 | #endif | |||
2128 | int v4; | |||
2129 | short v2; | |||
2130 | char v1; | |||
2131 | ||||
2132 | case 1: | |||
2133 | XtSetArg(args[0], res->resource_name, &v1)((void)( (args[0]).name = (res->resource_name), (args[0]). value = (XtArgVal)(&v1) )); | |||
2134 | XtGetValues(w, args, 1); | |||
2135 | value = (int)v1; | |||
2136 | break; | |||
2137 | case 2: | |||
2138 | XtSetArg(args[0], res->resource_name, &v2)((void)( (args[0]).name = (res->resource_name), (args[0]). value = (XtArgVal)(&v2) )); | |||
2139 | XtGetValues(w, args, 1); | |||
2140 | value = (int)v2; | |||
2141 | break; | |||
2142 | case 4: | |||
2143 | XtSetArg(args[0], res->resource_name, &v4)((void)( (args[0]).name = (res->resource_name), (args[0]). value = (XtArgVal)(&v4) )); | |||
2144 | XtGetValues(w, args, 1); | |||
2145 | value = (int)v4; | |||
2146 | break; | |||
2147 | #ifdef LONG64 | |||
2148 | case 8: | |||
2149 | XtSetArg(args[0], res->resource_name, &v8)((void)( (args[0]).name = (res->resource_name), (args[0]). value = (XtArgVal)(&v8) )); | |||
2150 | XtGetValues(w, args, 1); | |||
2151 | value = (long)v8; | |||
2152 | break; | |||
2153 | #endif | |||
2154 | default: | |||
2155 | fprintf(stderr__stderrp, "_XEditresGetStringValues: bad size %d\n", | |||
2156 | res->resource_size); | |||
2157 | string = "bad size"; | |||
2158 | *(char **)(warg->value) = string; | |||
2159 | XtFree((char *)res_list); | |||
2160 | return; | |||
2161 | } | |||
2162 | ||||
2163 | /* | |||
2164 | * If the resource is already String, no conversion needed | |||
2165 | */ | |||
2166 | if (strcmp(XtRString((char*)&XtStrings[1797]), res->resource_type) == 0) | |||
2167 | { | |||
2168 | if (value == 0) | |||
2169 | string = "(null)"; | |||
2170 | else | |||
2171 | string = (char *)value; | |||
2172 | } | |||
2173 | else | |||
2174 | { | |||
2175 | from.size = res->resource_size; | |||
2176 | from.addr = (XPointer)&value; | |||
2177 | to.addr = NULL((void*)0); | |||
2178 | to.size = 0; | |||
2179 | ||||
2180 | if (XtConvertAndStore(w,res->resource_type, &from, XtRString((char*)&XtStrings[1797]), &to)) | |||
2181 | string = to.addr; | |||
2182 | else | |||
2183 | { | |||
2184 | string = buffer; | |||
2185 | /* | |||
2186 | * Conversion failed, fall back to representing it as integer | |||
2187 | */ | |||
2188 | switch (res->resource_size) | |||
2189 | { | |||
2190 | case sizeof(char): | |||
2191 | XmuSnprintf(buffer, sizeof(buffer), "%d", (int)(value & 0xff)); | |||
2192 | break; | |||
2193 | case sizeof(short): | |||
2194 | XmuSnprintf(buffer, sizeof(buffer), "%d", (int)(value & 0xffff)); | |||
2195 | break; | |||
2196 | case sizeof(int): | |||
2197 | XmuSnprintf(buffer, sizeof(buffer), "0x%08x", (int)value); | |||
2198 | break; | |||
2199 | #ifdef LONG64 | |||
2200 | case sizeof(long): | |||
2201 | XmuSnprintf(buffer, sizeof(buffer), "0x%016lx", value); | |||
2202 | break; | |||
2203 | #endif | |||
2204 | } | |||
2205 | } | |||
2206 | } | |||
2207 | ||||
2208 | if (string == NULL((void*)0)) | |||
2209 | string = ""; | |||
2210 | ||||
2211 | *(char **)(warg->value) = string; | |||
2212 | XtFree((char *)res_list); | |||
2213 | } |