~ubuntu-branches/ubuntu/quantal/openmotif/quantal

« back to all changes in this revision

Viewing changes to demos/lib/Xmd/RegEdit.c

  • Committer: Bazaar Package Importer
  • Author(s): Stefan Bauer
  • Date: 2010-06-23 12:12:31 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20100623121231-u89gxdp51sg9wjj2
Tags: 2.3.0-1
* New Maintainer (Closes: #379258) 
* Acknowledge NMU changes
* New upstream release (Closes: #494375)
* Get rid of security patches as they are already part of new upstream
  release (00-xpmvuln.openmotif.patch, 342092-CVE-2005-3964.patch)
* Bump Standards to 3.8.4
* Added {misc:Depends} to make the package lintian cleaner
* Fix weak-library-dev-dependency by adding ${binary:Version}) for the
  -dev Package of openmotif
* Let package depend on autotools-dev to use newer autotools-helper-files
* Work around an autoconf-bug (Gentoo-Bug #1475)
* Added Client-side anti-aliased fonts support via XFT
* Added UTF-8 and UTF8_STRING atom support
* Ability to show text and pixmaps in Label, LabelGadget and all
  derived widgets
* Support of PNG/JPEG image formats in the same way as XPM is supported
* Increase FILE_OFFSET_BITS to 64 to show files >2GB in file-selector
  Idea taken from Magne Oestlyngen (Closes: #288537)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $XConsortium: RegEdit.c /main/5 1995/07/15 20:44:04 drk $ */
 
2
/*
 
3
 * @OPENGROUP_COPYRIGHT@
 
4
 * COPYRIGHT NOTICE
 
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.
 
9
 * 
 
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.
 
15
 * 
 
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
 
19
 * this agreement.
 
20
 * 
 
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
 
26
 * 
 
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.
 
36
 * 
 
37
 */
 
38
/*
 
39
 * HISTORY
 
40
 */
 
41
#include <stdio.h>
 
42
#include <Xm/XmP.h>             
 
43
#include <X11/ShellP.h>         
 
44
#include "RegEdit.h"
 
45
#include "RegEditI.h"
 
46
 
 
47
 
 
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();
 
62
 
 
63
/* the only entry point here */
 
64
void 
 
65
XmdRegisterEditres(Widget toplevel)
 
66
{
 
67
    XtAddEventHandler(toplevel, (EventMask) 0, TRUE, 
 
68
                      _XEditResCheckMessages, NULL);
 
69
}
 
70
 
 
71
 
 
72
/************************************************************
 
73
 *
 
74
 * Dump the content of the R5 lib/Xmu/EditresCom.c module.
 
75
 *  just move global as static.
 
76
 *
 
77
 ************************************************************/
 
78
 
 
79
#define _XEditResPutBool _XEditResPut8  
 
80
#define _XEditResPutResourceType _XEditResPut8
 
81
 
 
82
/************************************************************
 
83
 *
 
84
 * Local structure definitions.
 
85
 *
 
86
 ************************************************************/
 
87
 
 
88
typedef enum { BlockNone, BlockSetValues, BlockAll } EditresBlock;
 
89
 
 
90
typedef struct _SetValuesEvent {
 
91
    EditresCommand type;        /* first field must be type. */
 
92
    WidgetInfo * widgets;
 
93
    unsigned short num_entries;         /* number of set values requests. */
 
94
    char * name;
 
95
    char * res_type;
 
96
    XtPointer value;
 
97
    unsigned short value_len;
 
98
} SetValuesEvent;
 
99
 
 
100
typedef struct _SVErrorInfo {
 
101
    SetValuesEvent * event;
 
102
    ProtocolStream * stream;
 
103
    unsigned short * count;
 
104
    WidgetInfo * entry;
 
105
} SVErrorInfo;
 
106
 
 
107
typedef struct _FindChildEvent {
 
108
    EditresCommand type;        /* first field must be type. */
 
109
    WidgetInfo * widgets;
 
110
    short x, y;
 
111
} FindChildEvent;
 
112
 
 
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;
 
118
 
 
119
/*
 
120
 * Things that are common to all events.
 
121
 */
 
122
 
 
123
typedef struct _AnyEvent {
 
124
    EditresCommand type;        /* first field must be type. */
 
125
    WidgetInfo * widgets;
 
126
} AnyEvent;
 
127
 
 
128
/*
 
129
 * The event union.
 
130
 */
 
131
 
 
132
typedef union _EditresEvent {
 
133
    AnyEvent any_event;
 
134
    SetValuesEvent set_values_event;
 
135
    GetResEvent get_resources_event;
 
136
    GetGeomEvent get_geometry_event;
 
137
    FindChildEvent find_child_event;
 
138
} EditresEvent;
 
139
 
 
140
typedef struct _Globals {
 
141
    EditresBlock block;
 
142
    SVErrorInfo error_info;
 
143
    ProtocolStream stream;
 
144
    ProtocolStream * command_stream; /* command stream. */
 
145
} Globals;
 
146
 
 
147
#define CURRENT_PROTOCOL_VERSION 4L
 
148
 
 
149
#define streq(a,b) (strcmp( (a), (b) ) == 0)
 
150
 
 
151
static Atom res_editor_command, res_editor_protocol, client_value;
 
152
 
 
153
static Globals globals;
 
154
 
 
155
static void SendFailure(), SendCommand(), InsertWidget(), ExecuteCommand();
 
156
static void FreeEvent(), ExecuteSetValues(), ExecuteGetGeometry();
 
157
static void ExecuteGetResources();
 
158
 
 
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();
 
165
 
 
166
/************************************************************
 
167
 *
 
168
 * Resource Editor Communication Code
 
169
 *
 
170
 ************************************************************/
 
171
 
 
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 ***.
 
180
 *      Returns: none.
 
181
 */
 
182
 
 
183
/* ARGSUSED */
 
184
static void
 
185
_XEditResCheckMessages(w, data, event, cont)
 
186
Widget w;
 
187
XtPointer data;
 
188
XEvent *event;
 
189
Boolean *cont;
 
190
{
 
191
    Time time;
 
192
    ResIdent ident;
 
193
    static Boolean first_time = FALSE;
 
194
    static Atom res_editor, res_comm;
 
195
    Display * dpy;
 
196
 
 
197
    if (event->type == ClientMessage) {
 
198
        XClientMessageEvent * c_event = (XClientMessageEvent *) event;
 
199
        dpy = XtDisplay(w);
 
200
 
 
201
        if (!first_time) {
 
202
            first_time = TRUE;
 
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,
 
206
                                              False);
 
207
 
 
208
            /* Used in later procedures. */
 
209
            client_value = XInternAtom(dpy, EDITRES_CLIENT_VALUE, False);
 
210
            LoadResources(w);
 
211
        }
 
212
 
 
213
        if ((c_event->message_type != res_editor) ||
 
214
            (c_event->format != EDITRES_SEND_EVENT_FORMAT))
 
215
            return;
 
216
 
 
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);
 
224
            return;
 
225
        }
 
226
 
 
227
        XtGetSelectionValue(w, res_comm, res_editor_command,
 
228
                            GetCommand, (XtPointer) (long) ident, time);
 
229
    }
 
230
}
 
231
 
 
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.
 
241
 */
 
242
 
 
243
#define ERROR_MESSAGE ("Client: Improperly formatted protocol request")
 
244
 
 
245
static EditresEvent *
 
246
BuildEvent(w, sel, data, ident, length)
 
247
Widget w;
 
248
Atom sel;
 
249
XtPointer data;
 
250
ResIdent ident;
 
251
unsigned long length;
 
252
{
 
253
    EditresEvent * event;
 
254
    ProtocolStream alloc_stream, *stream;
 
255
    unsigned char temp;
 
256
    register unsigned int i;
 
257
 
 
258
    stream = &alloc_stream;     /* easier to think of it this way... */
 
259
 
 
260
    stream->current = stream->top = (unsigned char *) data;
 
261
    stream->size = HEADER_SIZE;         /* size of header. */
 
262
 
 
263
    /*
 
264
     * Retrieve the Header.
 
265
     */
 
266
 
 
267
    if (length < HEADER_SIZE) {
 
268
        SendFailure(w, sel, ident, Failure, ERROR_MESSAGE);
 
269
        return(NULL);
 
270
    }
 
271
 
 
272
    (void) _XEditResGet8(stream, &temp);
 
273
    if (temp != ident)          /* Id's don't match, ignore request. */
 
274
        return(NULL);           
 
275
 
 
276
    event = (EditresEvent *) XtCalloc(sizeof(EditresEvent), 1);
 
277
 
 
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.*/
 
282
        
 
283
    /*
 
284
     * Now retrieve the data segment.
 
285
     */
 
286
    
 
287
    switch(event->any_event.type) {
 
288
    case SendWidgetTree:
 
289
        break;                  /* no additional info */
 
290
    case SetValues:
 
291
        {
 
292
            SetValuesEvent * sv_event = (SetValuesEvent *) event;
 
293
            
 
294
            if ( !(_XEditResGetString8(stream, &(sv_event->name)) &&
 
295
                   _XEditResGetString8(stream, &(sv_event->res_type))))
 
296
            {
 
297
                goto done;
 
298
            }
 
299
 
 
300
            /*
 
301
             * Since we need the value length, we have to pull the
 
302
             * value out by hand.
 
303
             */
 
304
 
 
305
            if (!_XEditResGet16(stream, &(sv_event->value_len)))
 
306
                goto done;
 
307
 
 
308
            sv_event->value = XtMalloc(sizeof(char) * 
 
309
                                       (sv_event->value_len + 1));
 
310
 
 
311
            for (i = 0; i < sv_event->value_len; i++) {
 
312
                if (!_XEditResGet8(stream, 
 
313
                                   (unsigned char *) sv_event->value + i)) 
 
314
                {
 
315
                    goto done;
 
316
                }
 
317
            }
 
318
            ((char*)sv_event->value)[i] = '\0'; /* NULL terminate that sucker. */
 
319
 
 
320
            if (!_XEditResGet16(stream, &(sv_event->num_entries)))
 
321
                goto done;
 
322
 
 
323
            sv_event->widgets = (WidgetInfo *)
 
324
                XtCalloc(sizeof(WidgetInfo), sv_event->num_entries);
 
325
            
 
326
            for (i = 0; i < sv_event->num_entries; i++) {
 
327
                if (!_XEditResGetWidgetInfo(stream, sv_event->widgets + i))
 
328
                    goto done;
 
329
            }
 
330
        }
 
331
        break;
 
332
    case FindChild:
 
333
        {
 
334
            FindChildEvent * find_event = (FindChildEvent *) event;
 
335
            
 
336
            find_event->widgets = (WidgetInfo *) 
 
337
                                  XtCalloc(sizeof(WidgetInfo), 1);
 
338
 
 
339
            if (!(_XEditResGetWidgetInfo(stream, find_event->widgets) &&
 
340
                  _XEditResGetSigned16(stream, &(find_event->x)) &&
 
341
                  _XEditResGetSigned16(stream, &(find_event->y))))
 
342
            {
 
343
                goto done;
 
344
            }                                   
 
345
 
 
346
        }
 
347
        break;
 
348
    case GetGeometry:
 
349
    case GetResources:
 
350
        {
 
351
            GenericGetEvent * get_event = (GenericGetEvent *) event;
 
352
            
 
353
            if (!_XEditResGet16(stream, &(get_event->num_entries)))
 
354
                goto done;
 
355
                
 
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)) 
 
360
                    goto done;
 
361
            }
 
362
        }
 
363
        break;
 
364
    default:
 
365
        {
 
366
            char buf[BUFSIZ];
 
367
            
 
368
            sprintf(buf, "Unknown Protocol request %d.",event->any_event.type);
 
369
            SendFailure(w, sel, ident, buf);
 
370
            return(NULL);
 
371
        }
 
372
    }
 
373
    return(event);
 
374
 
 
375
 done:
 
376
 
 
377
    SendFailure(w, sel, ident, ERROR_MESSAGE);
 
378
    FreeEvent(event);
 
379
    return(NULL);
 
380
}    
 
381
 
 
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.
 
386
 *      Returns: none.
 
387
 */
 
388
 
 
389
static void
 
390
FreeEvent(event)
 
391
EditresEvent * event;
 
392
{
 
393
    if (event->any_event.widgets != NULL) {
 
394
        XtFree((char *)event->any_event.widgets->ids);
 
395
        XtFree((char *)event->any_event.widgets);
 
396
    }
 
397
 
 
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. */
 
401
    }
 
402
        
 
403
    XtFree((char *)event);
 
404
}
 
405
 
 
406
/*      Function Name: GetCommand
 
407
 *      Description: Gets the Command out of the selection asserted by the
 
408
 *                   resource manager.
 
409
 *      Arguments: (See Xt XtConvertSelectionProc)
 
410
 *                 data - contains the ident number for the command.
 
411
 *      Returns: none.
 
412
 */
 
413
 
 
414
/* ARGSUSED */
 
415
static void
 
416
GetCommand(w, data, selection, type, value, length, format)
 
417
Widget w;
 
418
XtPointer data, value;
 
419
Atom *selection, *type;
 
420
unsigned long *length;
 
421
int * format;
 
422
{
 
423
    ResIdent ident = (ResIdent) (long) data;
 
424
    EditresEvent * event;
 
425
 
 
426
    if ( (*type != res_editor_protocol) || (*format != EDITRES_FORMAT) )
 
427
        return;
 
428
 
 
429
    if ((event = BuildEvent(w, *selection, value, ident, *length)) != NULL) {
 
430
        ExecuteCommand(w, *selection, ident, event);
 
431
        FreeEvent(event);
 
432
    }
 
433
}
 
434
 
 
435
/*      Function Name: ExecuteCommand
 
436
 *      Description: Executes a command string received from the 
 
437
 *                   resource editor.
 
438
 *      Arguments: w       - a widget.
 
439
 *                 command - the command to execute.
 
440
 *                 value - the associated with the command.
 
441
 *      Returns: none.
 
442
 *
 
443
 * NOTES:  munges str
 
444
 */
 
445
 
 
446
/* ARGSUSED */    
 
447
static void
 
448
ExecuteCommand(w, sel, ident, event)
 
449
Widget w;
 
450
Atom sel;
 
451
ResIdent ident;
 
452
EditresEvent * event;
 
453
{
 
454
    char * (*func)();
 
455
    char * str;
 
456
 
 
457
    if (globals.block == BlockAll) {
 
458
        SendFailure(w, sel, ident, 
 
459
                    "This client has blocked all Editres commands.");
 
460
        return;
 
461
    }
 
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.");
 
466
        return;
 
467
    }
 
468
 
 
469
    switch(event->any_event.type) {
 
470
    case SendWidgetTree:
 
471
        func = DumpWidgets;
 
472
        break;
 
473
    case SetValues:
 
474
        func = DoSetValues;
 
475
        break;
 
476
    case FindChild:
 
477
        func = DoFindChild;
 
478
        break;
 
479
    case GetGeometry:
 
480
        func = DoGetGeometry;
 
481
        break;
 
482
    case GetResources:
 
483
        func = DoGetResources;
 
484
        break;
 
485
    default: 
 
486
        {
 
487
            char buf[BUFSIZ];
 
488
            sprintf(buf,"Unknown Protocol request %d.",event->any_event.type);
 
489
            SendFailure(w, sel, ident, buf);
 
490
            return;
 
491
        }
 
492
    }
 
493
 
 
494
    _XEditResResetStream(&globals.stream);
 
495
    if ((str = (*func)(w, event, &globals.stream)) == NULL)
 
496
        SendCommand(w, sel, ident, PartialSuccess, &globals.stream);
 
497
    else {
 
498
        SendFailure(w, sel, ident, str);
 
499
        XtFree(str);
 
500
    }
 
501
}
 
502
 
 
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.
 
513
 */
 
514
    
 
515
/* ARGSUSED */
 
516
static Boolean
 
517
ConvertReturnCommand(w, selection, target,
 
518
                     type_ret, value_ret, length_ret, format_ret)
 
519
Widget w;
 
520
Atom * selection, * target, * type_ret;
 
521
XtPointer *value_ret;
 
522
unsigned long * length_ret;
 
523
int * format_ret;
 
524
{
 
525
    /*
 
526
     * I assume the intrinsics give me the correct selection back.
 
527
     */
 
528
 
 
529
    if ((*target != client_value))
 
530
        return(FALSE);
 
531
 
 
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;
 
536
 
 
537
    return(TRUE);
 
538
}
 
539
 
 
540
/*      Function Name: CommandDone
 
541
 *      Description: done with the selection.
 
542
 *      Arguments: *** UNUSED ***
 
543
 *      Returns: none.
 
544
 */
 
545
 
 
546
/* ARGSUSED */
 
547
static void
 
548
CommandDone(widget, selection, target)
 
549
Widget widget;
 
550
Atom *selection;
 
551
Atom *target;    
 
552
{
 
553
    /* Keep the toolkit from automaticaly freeing the selection value */
 
554
}
 
555
 
 
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.
 
562
 *      Returns: none.
 
563
 */
 
564
 
 
565
static void
 
566
SendFailure(w, sel, ident, str) 
 
567
Widget w;
 
568
Atom sel;
 
569
ResIdent ident;
 
570
char * str;
 
571
{
 
572
    _XEditResResetStream(&globals.stream);
 
573
    _XEditResPutString8(&globals.stream, str);
 
574
    SendCommand(w, sel, ident, Failure, &globals.stream);
 
575
}
 
576
 
 
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.
 
583
 */
 
584
 
 
585
static XtPointer
 
586
BuildReturnPacket(ident, command, stream)
 
587
ResIdent ident;
 
588
EditresCommand command;
 
589
ProtocolStream * stream;
 
590
{
 
591
    long old_alloc, old_size;
 
592
    unsigned char * old_current;
 
593
    
 
594
    /*
 
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
 
597
     * fill in the space.
 
598
     */
 
599
 
 
600
    /* 
 
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.
 
603
     */
 
604
    
 
605
    old_current = stream->current;
 
606
    old_alloc = stream->alloc;
 
607
    old_size = stream->size;
 
608
 
 
609
    stream->current = stream->real_top;
 
610
    stream->alloc = stream->size + (2 * HEADER_SIZE);   
 
611
    
 
612
    _XEditResPut8(stream, ident);
 
613
    _XEditResPut8(stream, (unsigned char) command);
 
614
    _XEditResPut32(stream, old_size);
 
615
 
 
616
    stream->alloc = old_alloc;
 
617
    stream->current = old_current;
 
618
    stream->size = old_size;
 
619
    
 
620
    return((XtPointer) stream->real_top);
 
621
}    
 
622
 
 
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.
 
630
 *      Returns: none.
 
631
 */
 
632
 
 
633
static void
 
634
SendCommand(w, sel, ident, command, stream)
 
635
Widget w;
 
636
Atom sel;
 
637
ResIdent ident;
 
638
EditresCommand command;
 
639
ProtocolStream * stream;
 
640
{
 
641
    BuildReturnPacket(ident, command, stream);
 
642
    globals.command_stream = stream;    
 
643
 
 
644
/*
 
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
 
647
 * use CurrentTime.
 
648
 */
 
649
 
 
650
    XtOwnSelection(w, sel, CurrentTime,
 
651
                   ConvertReturnCommand, NULL, CommandDone);
 
652
}
 
653
 
 
654
/************************************************************
 
655
 *
 
656
 * Generic Utility Functions.
 
657
 *
 
658
 ************************************************************/
 
659
 
 
660
/*      Function Name: FindChildren
 
661
 *      Description: Retuns all children (popup, normal and otherwise)
 
662
 *                   of this widget
 
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.
 
668
 */
 
669
 
 
670
static int
 
671
FindChildren(parent, children, normal, popup)
 
672
Widget parent, **children;
 
673
Boolean normal, popup;
 
674
{
 
675
    CompositeWidget cw = (CompositeWidget) parent;
 
676
    int i, num_children, current = 0;
 
677
    
 
678
    num_children = 0;
 
679
 
 
680
    if (XtIsWidget(parent) && popup)
 
681
        num_children += parent->core.num_popups;
 
682
        
 
683
    if (XtIsComposite(parent) && normal) 
 
684
        num_children += cw->composite.num_children; 
 
685
 
 
686
    if (num_children == 0) {    
 
687
        *children = NULL; 
 
688
        return(0);
 
689
    }
 
690
 
 
691
    *children =(Widget*) XtMalloc((Cardinal) sizeof(Widget) * num_children);
 
692
 
 
693
    if (XtIsComposite(parent) && normal)
 
694
        for (i = 0; i < cw->composite.num_children; i++,current++) 
 
695
            (*children)[current] = cw->composite.children[i]; 
 
696
 
 
697
    if (XtIsWidget(parent) && popup)
 
698
        for ( i = 0; i < parent->core.num_popups; i++, current++) 
 
699
            (*children)[current] = parent->core.popup_list[i];
 
700
 
 
701
    return(num_children);
 
702
}
 
703
                
 
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.
 
708
 *                 child - the child.
 
709
 *      Returns: none.
 
710
 */
 
711
 
 
712
static Boolean
 
713
IsChild(top, parent, child)
 
714
Widget top, parent, child;
 
715
{
 
716
    int i, num_children;
 
717
    Widget * children;
 
718
 
 
719
    if (parent == NULL)
 
720
        return(top == child);
 
721
 
 
722
    num_children = FindChildren(parent, &children, TRUE, TRUE);
 
723
 
 
724
    for (i = 0; i < num_children; i++) {
 
725
        if (children[i] == child) {
 
726
            XtFree((char *)children);
 
727
            return(TRUE);
 
728
        }
 
729
    }
 
730
 
 
731
    XtFree((char *)children);
 
732
    return(FALSE);
 
733
}
 
734
 
 
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.
 
740
 */
 
741
 
 
742
static char * 
 
743
VerifyWidget(w, info)
 
744
Widget w;
 
745
WidgetInfo *info;
 
746
{
 
747
    Widget top;
 
748
 
 
749
    register int count;
 
750
    register Widget parent;
 
751
    register unsigned long * child;
 
752
 
 
753
    for (top = w; XtParent(top) != NULL; top = XtParent(top)) {}
 
754
 
 
755
    parent = NULL;
 
756
    child = info->ids;
 
757
    count = 0;
 
758
 
 
759
    while (TRUE) {
 
760
        if (!IsChild(top, parent, (Widget) *child)) 
 
761
            return(XtNewString("This widget no longer exists in the client."));
 
762
 
 
763
        if (++count == info->num_widgets)
 
764
            break;
 
765
 
 
766
        parent = (Widget) *child++;
 
767
    }
 
768
 
 
769
    info->real_widget = (Widget) *child;
 
770
    return(NULL);
 
771
}
 
772
 
 
773
/************************************************************
 
774
 *
 
775
 * Code to Perform SetValues operations.
 
776
 *
 
777
 ************************************************************/
 
778
 
 
779
 
 
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.
 
785
 *      Returns: NULL.
 
786
 */
 
787
 
 
788
static char *
 
789
DoSetValues(w, event, stream)
 
790
Widget w;
 
791
EditresEvent * event;
 
792
ProtocolStream * stream;
 
793
{
 
794
    char * str;
 
795
    register unsigned i;
 
796
    unsigned short count = 0;
 
797
    SetValuesEvent * sv_event = (SetValuesEvent *) event;
 
798
    
 
799
    _XEditResPut16(stream, count); /* insert 0, will be overwritten later. */
 
800
 
 
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);
 
805
            XtFree(str);
 
806
            count++;
 
807
        }
 
808
        else 
 
809
            ExecuteSetValues(sv_event->widgets[i].real_widget, 
 
810
                             sv_event, sv_event->widgets + i, stream, &count);
 
811
    }
 
812
 
 
813
    /*
 
814
     * Overwrite the first 2 bytes with the real count.
 
815
     */
 
816
 
 
817
    *(stream->top) = count >> XER_NBBY;
 
818
    *(stream->top + 1) = count;
 
819
    return(NULL);
 
820
}
 
821
 
 
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.
 
829
 *      Returns: none.
 
830
 */
 
831
 
 
832
/* ARGSUSED */
 
833
static void
 
834
HandleToolkitErrors(name, type, class, msg, params, num_params)
 
835
String name, type, class, msg, *params;
 
836
Cardinal * num_params;
 
837
{
 
838
    SVErrorInfo * info = &globals.error_info;   
 
839
    char buf[BUFSIZ];
 
840
 
 
841
    if ( streq(name, "unknownType") ) 
 
842
        sprintf(buf, "The `%s' resource is not used by this widget.", 
 
843
                info->event->name); 
 
844
    else if ( streq(name, "noColormap") ) 
 
845
        sprintf(buf, msg, params[0]);
 
846
    else if (streq(name, "conversionFailed") || streq(name, "conversionError"))
 
847
    {
 
848
        if (streq(info->event->value, XtRString))
 
849
            sprintf(buf, 
 
850
                    "Could not convert the string '%s' for the `%s' resource.",
 
851
                    (char*)info->event->value, info->event->name);   
 
852
        else
 
853
            sprintf(buf, "Could not convert the `%s' resource.",
 
854
                    info->event->name);
 
855
    }
 
856
    else 
 
857
        sprintf(buf, "Name: %s, Type: %s, Class: %s, Msg: %s",
 
858
                name, type, class, msg);
 
859
 
 
860
    /*
 
861
     * Insert this info into the protocol stream, and update the count.
 
862
     */ 
 
863
 
 
864
    (*(info->count))++;
 
865
    _XEditResPutWidgetInfo(info->stream, info->entry);
 
866
    _XEditResPutString8(info->stream, buf);
 
867
}
 
868
 
 
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.
 
874
 *      Returns: none.
 
875
 */
 
876
 
 
877
static void
 
878
ExecuteSetValues(w, sv_event, entry, stream, count)
 
879
Widget w;
 
880
SetValuesEvent * sv_event;
 
881
WidgetInfo * entry;
 
882
ProtocolStream * stream;
 
883
unsigned short * count;
 
884
{
 
885
    XtErrorMsgHandler old;
 
886
    
 
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... */
 
891
    info->entry = entry;
 
892
 
 
893
    old = XtAppSetWarningMsgHandler(XtWidgetToApplicationContext(w),
 
894
                                    HandleToolkitErrors);
 
895
 
 
896
    XtVaSetValues(w, XtVaTypedArg,
 
897
                  sv_event->name, sv_event->res_type,
 
898
                  sv_event->value, sv_event->value_len,
 
899
                  NULL);
 
900
 
 
901
    (void)XtAppSetWarningMsgHandler(XtWidgetToApplicationContext(w), old);
 
902
}
 
903
 
 
904
 
 
905
/************************************************************
 
906
 *
 
907
 * Code for Creating and dumping widget tree.
 
908
 *
 
909
 ************************************************************/
 
910
 
 
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.
 
917
 *      Returns: NULL
 
918
 */
 
919
 
 
920
/* ARGSUSED */
 
921
static char * 
 
922
DumpWidgets(w, event, stream)
 
923
Widget w;
 
924
EditresEvent * event;           /* UNUSED */
 
925
ProtocolStream * stream;
 
926
{
 
927
    unsigned short count = 0;
 
928
        
 
929
    /* Find Tree's root. */
 
930
    for ( ; XtParent(w) != NULL; w = XtParent(w)) {}
 
931
    
 
932
    /*
 
933
     * hold space for count, overwritten later. 
 
934
     */
 
935
 
 
936
    _XEditResPut16(stream, (unsigned int) 0);
 
937
 
 
938
    DumpChildren(w, stream, &count);
 
939
 
 
940
    /*
 
941
     * Overwrite the first 2 bytes with the real count.
 
942
     */
 
943
 
 
944
    *(stream->top) = count >> XER_NBBY;
 
945
    *(stream->top + 1) = count;
 
946
    return(NULL);
 
947
}
 
948
 
 
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.
 
954
 *      Returns: none.
 
955
 */
 
956
 
 
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.
 
964
 */
 
965
static Bool isApplicationShell(w)
 
966
    Widget w;
 
967
{
 
968
    register WidgetClass c;
 
969
 
 
970
    if (!XtIsTopLevelShell(w))
 
971
        return False;
 
972
    for (c = XtClass(w); c; c = c->core_class.superclass) {
 
973
        if (!strcmp(c->core_class.class_name, "ApplicationShell"))
 
974
            return True;
 
975
    }
 
976
    return False;
 
977
}
 
978
 
 
979
static void
 
980
DumpChildren(w, stream, count)
 
981
Widget w;
 
982
ProtocolStream * stream;
 
983
unsigned short *count;
 
984
{
 
985
    int i, num_children;
 
986
    Widget *children;
 
987
    unsigned long window;
 
988
    char * class;
 
989
 
 
990
    (*count)++;
 
991
        
 
992
    InsertWidget(stream, w);       /* Insert the widget into the stream. */
 
993
 
 
994
    _XEditResPutString8(stream, XtName(w)); /* Insert name */
 
995
 
 
996
    if (isApplicationShell(w))
 
997
        class = ((ApplicationShellWidget) w)->application.class;
 
998
    else
 
999
        class = XtClass(w)->core_class.class_name;
 
1000
 
 
1001
    _XEditResPutString8(stream, class); /* Insert class */
 
1002
 
 
1003
     if (XtIsWidget(w))
 
1004
         if (XtIsRealized(w))
 
1005
            window = XtWindow(w);
 
1006
        else
 
1007
            window = EDITRES_IS_UNREALIZED;
 
1008
     else
 
1009
         window = EDITRES_IS_OBJECT;
 
1010
 
 
1011
    _XEditResPut32(stream, window); /* Insert window id. */
 
1012
 
 
1013
    /*
 
1014
     * Find children and recurse.
 
1015
     */
 
1016
 
 
1017
    num_children = FindChildren(w, &children, TRUE, TRUE);
 
1018
    for (i = 0; i < num_children; i++) 
 
1019
        DumpChildren(children[i], stream, count);
 
1020
 
 
1021
    XtFree((char *)children);
 
1022
}
 
1023
 
 
1024
/************************************************************
 
1025
 *
 
1026
 * Code for getting the geometry of widgets.
 
1027
 *
 
1028
 ************************************************************/
 
1029
 
 
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.
 
1035
 *      Returns: NULL
 
1036
 */
 
1037
 
 
1038
static char *
 
1039
DoGetGeometry(w, event, stream)
 
1040
Widget w;
 
1041
EditresEvent * event;
 
1042
ProtocolStream * stream;
 
1043
{
 
1044
    unsigned i;
 
1045
    char * str;
 
1046
    GetGeomEvent * geom_event = (GetGeomEvent *) event;
 
1047
    
 
1048
    _XEditResPut16(stream, geom_event->num_entries);
 
1049
 
 
1050
    for (i = 0 ; i < geom_event->num_entries; i++) {
 
1051
 
 
1052
        /* 
 
1053
         * Send out the widget id. 
 
1054
         */
 
1055
 
 
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. */
 
1060
            XtFree(str);
 
1061
        }
 
1062
        else 
 
1063
            ExecuteGetGeometry(geom_event->widgets[i].real_widget, stream);
 
1064
    }
 
1065
    return(NULL);
 
1066
}
 
1067
 
 
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.
 
1073
 */
 
1074
 
 
1075
static void
 
1076
ExecuteGetGeometry(w, stream)
 
1077
Widget w;
 
1078
ProtocolStream * stream;
 
1079
{
 
1080
    int i;
 
1081
    Boolean mapped_when_man;
 
1082
    Dimension width, height, border_width;
 
1083
    Arg args[8];
 
1084
    Cardinal num_args = 0;
 
1085
    Position x, y;
 
1086
    
 
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);
 
1092
        return;
 
1093
    }
 
1094
 
 
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);
 
1099
    num_args++;
 
1100
    XtGetValues(w, args, num_args);
 
1101
 
 
1102
    if (!(XtIsManaged(w) && mapped_when_man) && XtIsWidget(w)) {
 
1103
        XWindowAttributes attrs;
 
1104
        
 
1105
        /* 
 
1106
         * The toolkit does not maintain mapping state, we have
 
1107
         * to go to the server.
 
1108
         */
 
1109
        
 
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);
 
1116
                return;
 
1117
            }
 
1118
        }
 
1119
        else {
 
1120
            _XEditResPut8(stream, True); /* Error occured. */
 
1121
            _XEditResPutString8(stream, "XGetWindowAttributes failed.");
 
1122
            return;
 
1123
        }
 
1124
    }
 
1125
 
 
1126
    XtTranslateCoords(w, -((int) border_width), -((int) border_width), &x, &y);
 
1127
 
 
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);
 
1135
}
 
1136
 
 
1137
/************************************************************
 
1138
 *
 
1139
 * Code for executing FindChild.
 
1140
 *
 
1141
 ************************************************************/
 
1142
 
 
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
 
1147
 *                        coord space.
 
1148
 *      Returns: TRUE if the position is in this child.
 
1149
 */
 
1150
 
 
1151
static Boolean
 
1152
PositionInChild(child, x, y)
 
1153
Widget child;
 
1154
int x, y;
 
1155
{
 
1156
    Arg args[6];
 
1157
    Cardinal num;
 
1158
    Dimension width, height, border_width;
 
1159
    Position child_x, child_y;
 
1160
    Boolean mapped_when_managed;
 
1161
 
 
1162
    if (!XtIsRectObj(child))    /* we must at least be a rect obj. */
 
1163
        return(FALSE);
 
1164
 
 
1165
    num = 0;
 
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);
 
1173
 
 
1174
    /*
 
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.
 
1178
     */
 
1179
 
 
1180
    if (XtIsWidget(child) && !(mapped_when_managed && XtIsManaged(child)) ) {
 
1181
        XWindowAttributes attrs;
 
1182
 
 
1183
        if (XGetWindowAttributes(XtDisplay(child), 
 
1184
                                 XtWindow(child), &attrs) != 0) {
 
1185
            /* oops */
 
1186
        }
 
1187
        else if (attrs.map_state != IsViewable)
 
1188
            return(FALSE);
 
1189
    }
 
1190
 
 
1191
    return (x >= child_x) &&
 
1192
           (x <= (child_x + (Position)width + 2 * (Position)border_width)) &&
 
1193
           (y >= child_y) &&
 
1194
           (y <= (child_y + (Position)height + 2 * (Position)border_width));
 
1195
}
 
1196
 
 
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
 
1200
 *                          specified.
 
1201
 *                 x, y - The point in coordinates relative to the 
 
1202
 *                        widget specified.
 
1203
 *      Returns: none.
 
1204
 */
 
1205
 
 
1206
static Widget 
 
1207
_FindChild(parent, x, y)
 
1208
Widget parent;
 
1209
int x, y;
 
1210
{
 
1211
    Widget * children;
 
1212
    int i = FindChildren(parent, &children, TRUE, FALSE);
 
1213
 
 
1214
    while (i > 0) {
 
1215
        i--;
 
1216
 
 
1217
        if (PositionInChild(children[i], x, y)) {
 
1218
            Widget child = children[i];
 
1219
            
 
1220
            XtFree((char *)children);
 
1221
            return(_FindChild(child, x - child->core.x, y - child->core.y));
 
1222
        }
 
1223
    }
 
1224
 
 
1225
    XtFree((char *)children);
 
1226
    return(parent);
 
1227
}
 
1228
 
 
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.
 
1236
 */
 
1237
 
 
1238
static char *
 
1239
DoFindChild(w, event, stream)
 
1240
Widget w;
 
1241
EditresEvent * event;
 
1242
ProtocolStream * stream;
 
1243
{
 
1244
    char * str;
 
1245
    Widget parent, child;
 
1246
    Position parent_x, parent_y;
 
1247
    FindChildEvent * find_event = (FindChildEvent *) event;
 
1248
    
 
1249
    if ((str = VerifyWidget(w, find_event->widgets)) != NULL) 
 
1250
        return(str);
 
1251
 
 
1252
    parent = find_event->widgets->real_widget;
 
1253
 
 
1254
    XtTranslateCoords(parent, (Position) 0, (Position) 0,
 
1255
                      &parent_x, &parent_y);
 
1256
    
 
1257
    child = _FindChild(parent, find_event->x - (int) parent_x,
 
1258
                       find_event->y - (int) parent_y);
 
1259
 
 
1260
    InsertWidget(stream, child);
 
1261
    return(NULL);
 
1262
}
 
1263
 
 
1264
/************************************************************
 
1265
 *
 
1266
 * Procedures for performing GetResources.
 
1267
 *
 
1268
 ************************************************************/
 
1269
 
 
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.
 
1275
 *      Returns: NULL
 
1276
 */
 
1277
 
 
1278
static char *
 
1279
DoGetResources(w, event, stream)
 
1280
Widget w;
 
1281
EditresEvent * event;
 
1282
ProtocolStream * stream;
 
1283
{
 
1284
    unsigned int i;
 
1285
    char * str;
 
1286
    GetResEvent * res_event = (GetResEvent *) event;
 
1287
    
 
1288
    _XEditResPut16(stream, res_event->num_entries); /* number of replys */
 
1289
 
 
1290
    for (i = 0 ; i < res_event->num_entries; i++) {
 
1291
        /* 
 
1292
         * Send out the widget id. 
 
1293
         */
 
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. */
 
1298
            XtFree(str);
 
1299
        }
 
1300
        else {
 
1301
            _XEditResPutBool(stream, False); /* no error occured. */
 
1302
            ExecuteGetResources(res_event->widgets[i].real_widget,
 
1303
                                stream);
 
1304
        }
 
1305
    }
 
1306
    return(NULL);
 
1307
}
 
1308
 
 
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.
 
1313
 *      Returns: none.
 
1314
 */
 
1315
 
 
1316
static void
 
1317
ExecuteGetResources(w, stream)
 
1318
Widget w;
 
1319
ProtocolStream * stream;
 
1320
{
 
1321
    XtResourceList norm_list, cons_list;
 
1322
    Cardinal num_norm, num_cons;
 
1323
    register int i;
 
1324
 
 
1325
    /* 
 
1326
     * Get Normal Resources. 
 
1327
     */
 
1328
 
 
1329
    XtGetResourceList(XtClass(w), &norm_list, &num_norm);
 
1330
 
 
1331
    if (XtParent(w) != NULL) 
 
1332
        XtGetConstraintResourceList(XtClass(XtParent(w)),&cons_list,&num_cons);
 
1333
    else
 
1334
        num_cons = 0;
 
1335
 
 
1336
    _XEditResPut16(stream, num_norm + num_cons); /* how many resources. */
 
1337
    
 
1338
    /*
 
1339
     * Insert all the normal resources.
 
1340
     */
 
1341
 
 
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);
 
1347
    }
 
1348
    XtFree((char *) norm_list);
 
1349
 
 
1350
    /*
 
1351
     * Insert all the constraint resources.
 
1352
     */
 
1353
 
 
1354
    if (num_cons > 0) {
 
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);
 
1360
        }
 
1361
        XtFree((char *) cons_list);
 
1362
    }
 
1363
}
 
1364
 
 
1365
/************************************************************
 
1366
 *
 
1367
 * Code for inserting values into the protocol stream.
 
1368
 *
 
1369
 ************************************************************/
 
1370
 
 
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.
 
1376
 *      Returns: none
 
1377
 */
 
1378
 
 
1379
static void
 
1380
InsertWidget(stream, w)
 
1381
ProtocolStream * stream;
 
1382
Widget w;
 
1383
{
 
1384
    Widget temp;
 
1385
    unsigned long * widget_list;
 
1386
    register int i, num_widgets;
 
1387
 
 
1388
    for (temp = w, i = 0; temp != 0; temp = XtParent(temp), i++) {}
 
1389
 
 
1390
    num_widgets = i;
 
1391
    widget_list = (unsigned long *) 
 
1392
                        XtMalloc(sizeof(unsigned long) * num_widgets);
 
1393
 
 
1394
    /*
 
1395
     * Put the widgets into the list.
 
1396
     * make sure that they are inserted in the list from parent -> child.
 
1397
     */
 
1398
 
 
1399
    for (i--, temp = w; temp != NULL; temp = XtParent(temp), i--) 
 
1400
        widget_list[i] = (unsigned long) temp;
 
1401
        
 
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]);
 
1405
    
 
1406
    XtFree((char *)widget_list);
 
1407
}
 
1408
 
 
1409
/************************************************************
 
1410
 *
 
1411
 * All of the following routines are public.
 
1412
 *
 
1413
 ************************************************************/
 
1414
 
 
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.
 
1419
 *      Returns: none.
 
1420
 */
 
1421
 
 
1422
static void
 
1423
_XEditResPutString8(stream, str)
 
1424
ProtocolStream * stream;
 
1425
char * str;
 
1426
{
 
1427
    int i, len = strlen(str);
 
1428
 
 
1429
    _XEditResPut16(stream, len);
 
1430
    for (i = 0 ; i < len ; i++, str++)
 
1431
        _XEditResPut8(stream, *str);
 
1432
}
 
1433
 
 
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.
 
1438
 *      Returns: none
 
1439
 */
 
1440
 
 
1441
static void
 
1442
_XEditResPut8(stream, value)
 
1443
ProtocolStream * stream;
 
1444
unsigned int value;
 
1445
{
 
1446
    unsigned char temp;
 
1447
 
 
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;
 
1455
    }
 
1456
 
 
1457
    temp = (unsigned char) (value & BYTE_MASK);
 
1458
    *((stream->current)++) = temp;
 
1459
    (stream->size)++;
 
1460
}
 
1461
 
 
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.
 
1466
 *      Returns: void
 
1467
 */
 
1468
 
 
1469
static void
 
1470
_XEditResPut16(stream, value)
 
1471
ProtocolStream * stream;
 
1472
unsigned int value;
 
1473
{
 
1474
    _XEditResPut8(stream, (value >> XER_NBBY) & BYTE_MASK);
 
1475
    _XEditResPut8(stream, value & BYTE_MASK);
 
1476
}
 
1477
 
 
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.
 
1482
 *      Returns: void
 
1483
 */
 
1484
 
 
1485
static void
 
1486
_XEditResPut32(stream, value)
 
1487
ProtocolStream * stream;
 
1488
unsigned long value;
 
1489
{
 
1490
    int i;
 
1491
 
 
1492
    for (i = 3; i >= 0; i--) 
 
1493
        _XEditResPut8(stream, (value >> (XER_NBBY*i)) & BYTE_MASK);
 
1494
}
 
1495
 
 
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.
 
1500
 *      Returns: none
 
1501
 */
 
1502
 
 
1503
static void
 
1504
_XEditResPutWidgetInfo(stream, info)
 
1505
ProtocolStream * stream;
 
1506
WidgetInfo * info;
 
1507
{
 
1508
    unsigned int i;
 
1509
 
 
1510
    _XEditResPut16(stream, info->num_widgets);
 
1511
    for (i = 0; i < info->num_widgets; i++) 
 
1512
        _XEditResPut32(stream, info->ids[i]);
 
1513
}
 
1514
 
 
1515
/************************************************************
 
1516
 *
 
1517
 * Code for retrieving values from the protocol stream.
 
1518
 *
 
1519
 ************************************************************/
 
1520
    
 
1521
/*      Function Name: _XEditResResetStream
 
1522
 *      Description: resets the protocol stream
 
1523
 *      Arguments: stream - the stream to reset.
 
1524
 *      Returns: none.
 
1525
 */
 
1526
 
 
1527
static void
 
1528
_XEditResResetStream(stream)
 
1529
ProtocolStream * stream;
 
1530
{
 
1531
    stream->current = stream->top;
 
1532
    stream->size = 0;
 
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;
 
1539
    }
 
1540
}
 
1541
 
 
1542
/*
 
1543
 * NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE 
 
1544
 *
 
1545
 * The only modified field if the "current" field.
 
1546
 *
 
1547
 * The only fields that must be set correctly are the "current", "top"
 
1548
 * and "size" fields.
 
1549
 */
 
1550
 
 
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.
 
1557
 */
 
1558
 
 
1559
static Boolean
 
1560
_XEditResGet8(stream, val)
 
1561
ProtocolStream * stream;
 
1562
unsigned char * val;
 
1563
{
 
1564
    if (stream->size < (stream->current - stream->top)) 
 
1565
        return(FALSE);
 
1566
 
 
1567
    *val = *((stream->current)++);
 
1568
    return(TRUE);
 
1569
}
 
1570
 
 
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.
 
1577
 */
 
1578
 
 
1579
static Boolean
 
1580
_XEditResGet16(stream, val)
 
1581
ProtocolStream * stream;
 
1582
unsigned short * val;
 
1583
{
 
1584
    unsigned char temp1, temp2;
 
1585
 
 
1586
    if ( !(_XEditResGet8(stream, &temp1) && _XEditResGet8(stream, &temp2)) )
 
1587
        return(FALSE);
 
1588
    
 
1589
    *val = (((unsigned short) temp1 << XER_NBBY) + ((unsigned short) temp2));
 
1590
    return(TRUE);
 
1591
}
 
1592
 
 
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.
 
1598
 */
 
1599
 
 
1600
static Boolean
 
1601
_XEditResGetSigned16(stream, val)
 
1602
ProtocolStream * stream;
 
1603
short * val;
 
1604
{
 
1605
    unsigned char temp1, temp2;
 
1606
 
 
1607
    if ( !(_XEditResGet8(stream, &temp1) && _XEditResGet8(stream, &temp2)) )
 
1608
        return(FALSE);
 
1609
    
 
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 */
 
1614
    }
 
1615
    else 
 
1616
        *val = (((unsigned short) temp1 << XER_NBBY) + ((unsigned short) temp2));
 
1617
 
 
1618
    return(TRUE);
 
1619
}
 
1620
 
 
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.
 
1627
 */
 
1628
 
 
1629
static Boolean
 
1630
_XEditResGet32(stream, val)
 
1631
ProtocolStream * stream;
 
1632
unsigned long * val;
 
1633
{
 
1634
    unsigned short temp1, temp2;
 
1635
 
 
1636
    if ( !(_XEditResGet16(stream, &temp1) && _XEditResGet16(stream, &temp2)) )
 
1637
        return(FALSE);
 
1638
    
 
1639
    *val = (((unsigned short) temp1 << (XER_NBBY * 2)) + 
 
1640
            ((unsigned short) temp2));
 
1641
    return(TRUE);
 
1642
}
 
1643
 
 
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.
 
1649
 */
 
1650
 
 
1651
static Boolean
 
1652
_XEditResGetString8(stream, str)
 
1653
ProtocolStream * stream;
 
1654
char ** str;
 
1655
{
 
1656
    unsigned short len;
 
1657
    register unsigned i;
 
1658
 
 
1659
    if (!_XEditResGet16(stream, &len)) {
 
1660
        return(FALSE);
 
1661
    }
 
1662
 
 
1663
    *str = XtMalloc(sizeof(char) * (len + 1));
 
1664
 
 
1665
    for (i = 0; i < len; i++) {
 
1666
        if (!_XEditResGet8(stream, (unsigned char *) *str + i)) {
 
1667
            XtFree(*str);
 
1668
            *str = NULL;
 
1669
            return(FALSE);
 
1670
        }
 
1671
    }
 
1672
    (*str)[i] = '\0';           /* NULL terminate that sucker. */
 
1673
    return(TRUE);
 
1674
}
 
1675
 
 
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.
 
1682
 */
 
1683
 
 
1684
static Boolean
 
1685
_XEditResGetWidgetInfo(stream, info)
 
1686
ProtocolStream * stream;
 
1687
WidgetInfo * info;
 
1688
{
 
1689
    unsigned int i;
 
1690
 
 
1691
    if (!_XEditResGet16(stream, &(info->num_widgets))) 
 
1692
        return(FALSE);
 
1693
 
 
1694
    info->ids = (unsigned long *) XtMalloc(sizeof(long) * (info->num_widgets));
 
1695
 
 
1696
    for (i = 0; i < info->num_widgets; i++) {
 
1697
        if (!_XEditResGet32(stream, info->ids + i)) {
 
1698
            XtFree((char *)info->ids);
 
1699
            info->ids = NULL;
 
1700
            return(FALSE);
 
1701
        }
 
1702
    }
 
1703
    return(TRUE);
 
1704
}
 
1705
            
 
1706
/************************************************************
 
1707
 *
 
1708
 * Code for Loading the EditresBlock resource.
 
1709
 *
 
1710
 ************************************************************/
 
1711
 
 
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.
 
1719
 */
 
1720
 
 
1721
/* ARGSUSED */
 
1722
static Boolean
 
1723
CvtStringToBlock(dpy, args, num_args, from_val, to_val, converter_data)
 
1724
Display * dpy;
 
1725
XrmValue * args;
 
1726
Cardinal * num_args;
 
1727
XrmValue * from_val, * to_val;
 
1728
XtPointer * converter_data;
 
1729
{
 
1730
    char ptr[BUFSIZ];
 
1731
    static EditresBlock block;
 
1732
 
 
1733
/*    XmuCopyISOLatin1Lowered(ptr, from_val->addr);*/
 
1734
    
 
1735
 
 
1736
    if (streq(ptr, "none")) 
 
1737
        block = BlockNone;
 
1738
    else if (streq(ptr, "setvalues")) 
 
1739
        block = BlockSetValues;
 
1740
    else if (streq(ptr, "all")) 
 
1741
        block = BlockAll;
 
1742
    else {
 
1743
        Cardinal num_params = 1;
 
1744
        String params[1];
 
1745
 
 
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);
 
1751
        return(FALSE);
 
1752
    }
 
1753
 
 
1754
    if (to_val->addr != NULL) {
 
1755
        if (to_val->size < sizeof(EditresBlock)) {
 
1756
            to_val->size = sizeof(EditresBlock);
 
1757
            return(FALSE);
 
1758
        }
 
1759
        *(EditresBlock *)(to_val->addr) = block;
 
1760
    }
 
1761
    else 
 
1762
        to_val->addr = (XtPointer) block;
 
1763
 
 
1764
    to_val->size = sizeof(EditresBlock);
 
1765
    return(TRUE);
 
1766
}
 
1767
    
 
1768
#define XtREditresBlock ("EditresBlock")
 
1769
 
 
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.
 
1774
 *      Returns: none.
 
1775
 */
 
1776
 
 
1777
static void
 
1778
LoadResources(w)
 
1779
Widget w;
 
1780
{
 
1781
    static XtResource resources[] = {
 
1782
        {"editresBlock", "EditresBlock", XtREditresBlock, sizeof(EditresBlock),
 
1783
         XtOffsetOf(Globals, block), XtRImmediate, (XtPointer) BlockNone}
 
1784
    };
 
1785
 
 
1786
    for (; XtParent(w) != NULL; w = XtParent(w)) {} 
 
1787
 
 
1788
    XtAppSetTypeConverter(XtWidgetToApplicationContext(w),
 
1789
                          XtRString, XtREditresBlock, CvtStringToBlock,
 
1790
                          NULL, (Cardinal) 0, XtCacheAll, NULL);
 
1791
 
 
1792
    XtGetApplicationResources( w, (caddr_t) &globals, resources,
 
1793
                              XtNumber(resources), NULL, (Cardinal) 0);
 
1794
}
 
1795
 
 
1796