~ubuntu-branches/ubuntu/gutsy/vnc4/gutsy

« back to all changes in this revision

Viewing changes to unix/xc/programs/editres/utils.c

  • Committer: Bazaar Package Importer
  • Author(s): Ola Lundqvist
  • Date: 2006-05-15 20:35:17 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20060515203517-l4lre1ku942mn26k
Tags: 4.1.1+X4.3.0-10
* Correction of critical security issue. Thanks to Martin Kogler
  <e9925248@student.tuwien.ac.at> that informed me about the issue,
  and provided the patch.
  This flaw was originally found by Steve Wiseman of intelliadmin.com.
* Applied patch from Javier Kohen <jkohen@users.sourceforge.net> that
  inform the user that only 8 first characters of the password will
  actually be used when typing more than 8 characters, closes:
  #355619.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * $Xorg: utils.c,v 1.4 2001/02/09 02:05:30 xorgcvs Exp $
 
3
 *
 
4
Copyright 1989, 1998  The Open Group
 
5
 
 
6
Permission to use, copy, modify, distribute, and sell this software and its
 
7
documentation for any purpose is hereby granted without fee, provided that
 
8
the above copyright notice appear in all copies and that both that
 
9
copyright notice and this permission notice appear in supporting
 
10
documentation.
 
11
 
 
12
The above copyright notice and this permission notice shall be included in
 
13
all copies or substantial portions of the Software.
 
14
 
 
15
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
16
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
17
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
 
18
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
 
19
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 
20
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
21
 
 
22
Except as contained in this notice, the name of The Open Group shall not be
 
23
used in advertising or otherwise to promote the sale, use or other dealings
 
24
in this Software without prior written authorization from The Open Group.
 
25
 */
 
26
/* $XFree86: xc/programs/editres/utils.c,v 1.6 2001/12/14 20:00:43 dawes Exp $ */
 
27
 
 
28
#include <X11/Intrinsic.h>
 
29
#include <X11/Xutil.h>
 
30
#include <X11/Xos.h>
 
31
#include <X11/Shell.h>
 
32
#include <X11/StringDefs.h>
 
33
 
 
34
#include <X11/Xaw/Cardinals.h>
 
35
#include <X11/Xaw/Dialog.h>
 
36
 
 
37
#include <stdio.h>
 
38
#include <stdlib.h>
 
39
#include <X11/Xmu/Error.h>
 
40
 
 
41
#include "editresP.h"
 
42
 
 
43
static WNode * FindWidgetFromWindowGivenNode ( WNode * node, Window win );
 
44
static WidgetResources * ParseResources ( GetResourcesInfo * info, 
 
45
                                          char **error );
 
46
static int CompareResourceEntries ( const void *e1, 
 
47
                                    const void *e2 );
 
48
static void AddResource ( ResourceInfo * res_info, 
 
49
                          WidgetResourceInfo * resource );
 
50
static void FreeResources ( WidgetResources * resources );
 
51
 
 
52
 
 
53
/*      Function Name: SetMessage(w, str)
 
54
 *      Description: shows the message to the user.
 
55
 *      Arguments: w - a label widget to show the message in.
 
56
 *                 str - the string to show.
 
57
 *      Returns: none.
 
58
 */
 
59
 
 
60
void
 
61
SetMessage(w, str)
 
62
Widget w;
 
63
char * str;
 
64
{
 
65
    Arg args[1];
 
66
 
 
67
    XtSetArg(args[0], XtNlabel, str);
 
68
    XtSetValues(w, args, ONE);
 
69
}
 
70
 
 
71
/*      Function Name: GetAllStrings
 
72
 *      Description: Returns a list of strings that have been borken up by
 
73
 *                   the character specified.
 
74
 *      Arguments: in - the string to parse.
 
75
 *                 sep - the separator character.
 
76
 *                 out - the strings to send out.
 
77
 *                 num - the number of strings in out.
 
78
 *      Returns: none
 
79
 */
 
80
 
 
81
void
 
82
GetAllStrings(char *in, char sep, char ***out, int *num)
 
83
{
 
84
    int size, i;
 
85
    char * ptr;
 
86
 
 
87
    if (*in == sep)             /* jump over first char if it is the sep. */
 
88
        in++;
 
89
 
 
90
    /*
 
91
     * count the number of strings.
 
92
     */
 
93
 
 
94
    for (*num = 1, ptr = in; (ptr = strchr(ptr, sep)) != NULL; (*num)++)
 
95
        ptr++;
 
96
 
 
97
/*
 
98
 * Create Enough space for pointers and string.
 
99
 */
 
100
 
 
101
    size = (sizeof(char *) * *num) + (sizeof(char) * (strlen(in) + 1));
 
102
    *out = (char **) XtMalloc( (Cardinal) size);
 
103
 
 
104
    ptr = (char *) (*out + *num);
 
105
    strcpy(ptr, in);
 
106
 
 
107
/*
 
108
 * Change all `sep' characters to '\0' and stuff the pointer into
 
109
 * the next pointer slot.
 
110
 */
 
111
 
 
112
    i = 1;
 
113
    (*out)[0] = ptr;
 
114
    while (TRUE) {
 
115
        if ((ptr = strchr(ptr, sep)) == NULL)
 
116
            break;
 
117
 
 
118
        *ptr++ = '\0';
 
119
        (*out)[i++] = ptr;
 
120
    }
 
121
 
 
122
/*
 
123
 * If last string is empty then strip it off.
 
124
 */
 
125
 
 
126
    if ( *((*out)[i - 1]) == '\0' )
 
127
        (*num)--;
 
128
}
 
129
 
 
130
/*      Function Name: AddString
 
131
 *      Description: Mallocs and strcats the string onto the end of
 
132
 *                   the given string.
 
133
 *      Arguments: str - string to add on to.
 
134
 *                 add - string to add.
 
135
 *      Returns: none.
 
136
 */
 
137
 
 
138
void
 
139
AddString(str, add)
 
140
char ** str, *add;
 
141
{
 
142
    int len_str, len_add;
 
143
    char * ptr;
 
144
 
 
145
    len_str = ((*str) ? strlen(*str) : 0);
 
146
    len_add = strlen(add);
 
147
 
 
148
    *str = XtRealloc(*str, sizeof(char) * (len_str + len_add + 1));
 
149
    ptr = *str + len_str;
 
150
    strcpy(ptr, add);
 
151
}
 
152
 
 
153
/*      Function Name: FindNode
 
154
 *      Description: Finds a node give the top node, and a node id number.
 
155
 *      Arguments: top_node - the top node.
 
156
 *                 id - the node id.
 
157
 *      Returns: node.
 
158
 */
 
159
 
 
160
WNode *
 
161
FindNode(top_node, ids, number)
 
162
WNode *top_node;
 
163
unsigned long * ids;
 
164
Cardinal number;
 
165
{
 
166
    int i, j;
 
167
    WNode *node;
 
168
 
 
169
    if (top_node == NULL)
 
170
        return(NULL);
 
171
 
 
172
    if (ids[0] != top_node->id)
 
173
        return(NULL);
 
174
 
 
175
    for (node = top_node, i = 1 ; i < number; i++) {
 
176
        Boolean found_it = FALSE;
 
177
 
 
178
        for (j = 0; j < node->num_children; j++) {
 
179
            if (node->children[j]->id == ids[i]) {
 
180
                node = node->children[j];
 
181
                found_it = TRUE;
 
182
                break;
 
183
            }
 
184
        }
 
185
        if (!found_it)
 
186
            return(NULL);
 
187
    }       
 
188
    return(node);
 
189
}
 
190
 
 
191
/*      Function Name: FindWidgetFromWindow
 
192
 *      Description: finds a widget in the current tree given its window id.
 
193
 *      Arguments: tree_info - information about this tree.
 
194
 *                 win - window to search for.
 
195
 *      Returns: node - the node corrosponding to this widget.
 
196
 */
 
197
 
 
198
WNode * 
 
199
FindWidgetFromWindow(tree_info, win)
 
200
TreeInfo * tree_info;
 
201
Window win;
 
202
{
 
203
    if (tree_info == NULL)
 
204
        return(NULL);
 
205
 
 
206
    return(FindWidgetFromWindowGivenNode(tree_info->top_node, win));
 
207
}
 
208
 
 
209
/*      Function Name: FindWidgetFromWindowGivenNode
 
210
 *      Description: finds a widget in the current tree given its window id.
 
211
 *      Arguments: node - current node.
 
212
 *                 win - window to search for.
 
213
 *      Returns: node - the node corrosponding to this widget.
 
214
 */
 
215
 
 
216
static WNode *
 
217
FindWidgetFromWindowGivenNode(node, win)
 
218
WNode * node;
 
219
Window win;
 
220
{
 
221
    int i;
 
222
    WNode * ret_node;
 
223
 
 
224
    if (node->window == win)
 
225
        return(node);
 
226
 
 
227
    for (i = 0; i < node->num_children; i++) {
 
228
        ret_node = FindWidgetFromWindowGivenNode(node->children[i], win);
 
229
        if (ret_node != NULL)
 
230
            return(ret_node);
 
231
    }
 
232
    return(NULL);
 
233
}
 
234
 
 
235
/*      Function Name: HandleXErrors
 
236
 *      Description: Handles error codes from the server.
 
237
 *      Arguments: display - the display.
 
238
 *                 error - error information.
 
239
 *      Returns: none.
 
240
 */
 
241
 
 
242
/* ARGSUSED */
 
243
int
 
244
HandleXErrors(display, error)
 
245
Display * display;
 
246
XErrorEvent * error;
 
247
{
 
248
    if (error->serial != global_serial_num) {
 
249
        (*global_old_error_handler) (display, error);
 
250
        return(0);
 
251
    }
 
252
 
 
253
    if (error->error_code == BadWindow)
 
254
        global_error_code = NO_WINDOW;    
 
255
    else {
 
256
        if (XmuPrintDefaultErrorMessage(display, error, stderr) != 0)
 
257
            exit(1);
 
258
    }
 
259
    return(0);
 
260
}
 
261
 
 
262
/*      Function Name: _DumpTreeToFile
 
263
 *      Description: Dumps the widget tree to a file
 
264
 *      Arguments: w - a random widget in the application on the
 
265
 *                     currently active display
 
266
 *                 tree_ptr - pointer to the widget tree info.
 
267
 *                 filename - name of the file.
 
268
 *      Returns: none.
 
269
 */
 
270
 
 
271
/* ARGSUSED */
 
272
 
 
273
void
 
274
_DumpTreeToFile(w, tree_ptr, filename)
 
275
Widget w;
 
276
XtPointer tree_ptr;
 
277
XtPointer filename;
 
278
{
 
279
    TreeInfo * tree_info = (TreeInfo *) tree_ptr;
 
280
    FILE * fp; 
 
281
 
 
282
    if (tree_info == NULL) {
 
283
        SetMessage(global_screen_data.info_label,
 
284
                   res_labels[17]);
 
285
        return;
 
286
    }
 
287
 
 
288
    if ( (fp = fopen((char *)filename, "w")) == NULL ) {
 
289
        char buf[BUFSIZ];
 
290
 
 
291
        sprintf(buf, res_labels[24], (char *)filename);
 
292
        SetMessage(global_screen_data.info_label, buf);
 
293
        return;
 
294
    }
 
295
 
 
296
    PerformTreeToFileDump(tree_info->top_node, 0, fp);
 
297
    fclose(fp);
 
298
}
 
299
 
 
300
/************************************************************
 
301
 * 
 
302
 * The file dialog boxes are handled with this code.
 
303
 *
 
304
 * It automatically calls the function specified when the
 
305
 * user selects okay, or hits <CR>.
 
306
 *
 
307
 * A translation is required in the app-defaults file.
 
308
 *
 
309
 ************************************************************/
 
310
 
 
311
/*      Function Name: _PopupFileDialog
 
312
 *      Description: Puts up a dialog box to get the filename.
 
313
 *      Arguments: str - message.
 
314
 *                 default_value - the default value of the filename;
 
315
 *                 func - function to call when filename has been entered.
 
316
 *                 data - generic data to pass to func.
 
317
 *      Returns: none
 
318
 */
 
319
 
 
320
static XContext file_dialog_context = None;
 
321
 
 
322
typedef struct _FileDialogInfo {
 
323
    XtCallbackProc func;
 
324
    XtPointer data;
 
325
} FileDialogInfo;
 
326
 
 
327
void
 
328
_PopupFileDialog(w, str, default_value, func, data)
 
329
Widget w;
 
330
String str, default_value;
 
331
XtCallbackProc func;
 
332
XtPointer data;
 
333
{
 
334
    FileDialogInfo * file_info;
 
335
    Widget shell, dialog;
 
336
    Arg args[2];
 
337
    Cardinal num_args;
 
338
 
 
339
    if (file_dialog_context == None)
 
340
        file_dialog_context = XUniqueContext();
 
341
 
 
342
    shell = XtCreatePopupShell("fileDialog", transientShellWidgetClass, w,
 
343
                               NULL, ZERO);
 
344
 
 
345
    num_args = 0;
 
346
    XtSetArg(args[num_args], XtNlabel, str); num_args++;
 
347
    XtSetArg(args[num_args], XtNvalue, default_value); num_args++;
 
348
    dialog = XtCreateManagedWidget("dialog", dialogWidgetClass, 
 
349
                                   shell, args, num_args);
 
350
 
 
351
    file_info = XtNew(FileDialogInfo);
 
352
 
 
353
    file_info->func = func;
 
354
    file_info->data = data;
 
355
 
 
356
    if  (XSaveContext(XtDisplay(dialog), (Window) dialog, file_dialog_context, 
 
357
                      (XPointer) file_info) != 0) {
 
358
        SetMessage(global_screen_data.info_label,
 
359
            "Error while trying to save Context\nAborting file dialog popup.");
 
360
        XtDestroyWidget(shell);
 
361
        return;
 
362
    }
 
363
 
 
364
    XawDialogAddButton(dialog, "okay", _PopdownFileDialog, (XtPointer) TRUE);
 
365
    XawDialogAddButton(dialog, "cancel", _PopdownFileDialog,(XtPointer) FALSE);
 
366
 
 
367
    PopupCentered(NULL, shell, XtGrabNone);
 
368
}
 
369
 
 
370
/*      Function Name: PopupCentered
 
371
 *      Description: Pops up the window specified under the location passed
 
372
 *                   in the event, or under the cursor.
 
373
 *      Arguments: event - the event that we should use.
 
374
 *                 w - widget to popup.
 
375
 *                 mode - mode to pop it up in.
 
376
 *      Returns: none
 
377
 */
 
378
 
 
379
void
 
380
PopupCentered(event, w, mode)
 
381
XEvent * event;
 
382
Widget w;
 
383
XtGrabKind mode;
 
384
{
 
385
    Boolean get_from_cursor = FALSE;
 
386
    Arg args[3];
 
387
    Cardinal num_args;
 
388
    Dimension width, height, b_width;
 
389
    int x, y, max_x, max_y;
 
390
 
 
391
    XtRealizeWidget(w);
 
392
 
 
393
    if (event == NULL)
 
394
        get_from_cursor = TRUE;
 
395
    else {
 
396
        switch (event->type) {
 
397
        case ButtonPress:
 
398
        case ButtonRelease:
 
399
            x = event->xbutton.x_root;
 
400
            y = event->xbutton.y_root;
 
401
            break;
 
402
        case KeyPress:
 
403
        case KeyRelease:
 
404
            x = event->xkey.x_root;
 
405
            y = event->xkey.y_root;
 
406
            break;
 
407
        default:
 
408
            get_from_cursor = TRUE;
 
409
            break;
 
410
        }
 
411
    }
 
412
 
 
413
    if (get_from_cursor) {
 
414
        Window root, child;
 
415
        int win_x, win_y;
 
416
        unsigned int mask;
 
417
        
 
418
        XQueryPointer(XtDisplay(w), XtWindow(w),
 
419
                      &root, &child, &x, &y, &win_x, &win_y, &mask);
 
420
    }
 
421
 
 
422
    num_args = 0;
 
423
    XtSetArg(args[num_args], XtNwidth, &width); num_args++;
 
424
    XtSetArg(args[num_args], XtNheight, &height); num_args++;
 
425
    XtSetArg(args[num_args], XtNborderWidth, &b_width); num_args++;
 
426
    XtGetValues(w, args, num_args);
 
427
 
 
428
    width += 2 * b_width;
 
429
    height += 2 * b_width;
 
430
 
 
431
    x -= ((int) width/2);
 
432
    if (x < 0) 
 
433
        x = 0;
 
434
    if ( x > (max_x = (int) (XtScreen(w)->width - width)) )
 
435
        x = max_x;
 
436
 
 
437
    y -= ( (Position) height/2 );
 
438
    if (y < 0) 
 
439
        y = 0;
 
440
    if ( y > (max_y = (int) (XtScreen(w)->height - height)) )
 
441
        y = max_y;
 
442
  
 
443
    num_args = 0;
 
444
    XtSetArg(args[num_args], XtNx, x); num_args++;
 
445
    XtSetArg(args[num_args], XtNy, y); num_args++;
 
446
    XtSetValues(w, args, num_args);
 
447
 
 
448
    XtPopup(w, mode);
 
449
}
 
450
 
 
451
/*      Function Name: _PopdownFileDialog
 
452
 *      Description: Destroys the file dialog, and calls the correct function.
 
453
 *      Arguments:  w - a child of the dialog widget.
 
454
 *                  client_data - TRUE if command was sucessful.
 
455
 *                  junk - ** UNUSED **.
 
456
 *      Returns: none.
 
457
 */
 
458
 
 
459
/* ARGSUSED */
 
460
 
 
461
void 
 
462
_PopdownFileDialog(w, client_data, junk)
 
463
Widget w;
 
464
XtPointer client_data, junk;
 
465
{
 
466
    Widget dialog = XtParent(w);
 
467
    XPointer file_info_ptr;
 
468
    FileDialogInfo * file_info;
 
469
 
 
470
    if (XFindContext(XtDisplay(dialog), (Window) dialog, file_dialog_context,
 
471
                     &file_info_ptr) == XCNOENT) {
 
472
        SetMessage(global_screen_data.info_label,       
 
473
                   "Error while trying to find Context\nAborting...");  
 
474
    }
 
475
 
 
476
    (void) XDeleteContext(XtDisplay(dialog), (Window)dialog, 
 
477
                          file_dialog_context);
 
478
 
 
479
    file_info = (FileDialogInfo *) file_info_ptr;
 
480
 
 
481
    if ( ((Boolean)(long) client_data) == TRUE ) {
 
482
        String filename = XawDialogGetValueString(dialog);
 
483
 
 
484
        (*file_info->func)(w, file_info->data, filename); /* call handler */
 
485
    }
 
486
 
 
487
    XtFree( (XtPointer) file_info); /* Free data. */
 
488
 
 
489
    XtPopdown(XtParent(dialog));
 
490
    XtDestroyWidget(XtParent(dialog)); /* Remove file dialog. */
 
491
}
 
492
 
 
493
/************************************************************
 
494
 *
 
495
 * Functions for dealing with the Resource Box.
 
496
 *
 
497
 ************************************************************/
 
498
 
 
499
/*    Function Name: GetNamesAndClasses
 
500
 *    Description: Gets a list of names and classes for this widget.
 
501
 *    Arguments: node - this widget's node.
 
502
 *                 names, classes - list of names and classes. ** RETURNED **
 
503
 *    Returns: none.
 
504
 */
 
505
 
 
506
void
 
507
GetNamesAndClasses(node, names, classes)
 
508
WNode * node;
 
509
char *** names, ***classes;
 
510
{
 
511
    int i, total_widgets;
 
512
    WNode * temp = node;
 
513
 
 
514
    for (total_widgets = 1 ; temp->parent != NULL ;
 
515
       total_widgets++, temp = temp->parent) {}
 
516
 
 
517
    *names = (char **) XtMalloc(sizeof(char *) * (total_widgets + 1));
 
518
    *classes = (char **) XtMalloc(sizeof(char *) * (total_widgets + 1));
 
519
 
 
520
    (*names)[total_widgets] = (*classes)[total_widgets] = NULL;
 
521
 
 
522
    for ( i = (total_widgets - 1); i >= 0 ; node = node->parent, i--) {
 
523
      (*names)[i] = node->name;
 
524
      (*classes)[i] = node->class;
 
525
    }
 
526
}
 
527
 
 
528
/*      Function Name: HandleGetResources
 
529
 *      Description: Gets the resources.
 
530
 *      Arguments: event - the information from the client.
 
531
 *      Returns: an error message to display.
 
532
 */
 
533
 
 
534
char *
 
535
HandleGetResources(event)
 
536
Event * event;
 
537
{
 
538
    GetResourcesEvent * get_event = (GetResourcesEvent *) event;
 
539
    char buf[BUFSIZ], * errors = NULL;
 
540
    int i;
 
541
    WNode * node;
 
542
 
 
543
    for (i = 0; i < (int)get_event->num_entries; i++) {
 
544
        node = FindNode(global_tree_info->top_node,
 
545
                        get_event->info[i].widgets.ids, 
 
546
                        get_event->info[i].widgets.num_widgets);
 
547
 
 
548
        if (node == NULL) {
 
549
            sprintf(buf, res_labels[16]);
 
550
            AddString(&errors, buf); 
 
551
            continue;   
 
552
        }
 
553
 
 
554
        if (node->resources != NULL) 
 
555
            FreeResources(node->resources);
 
556
 
 
557
        if (!get_event->info[i].error) {
 
558
            node->resources = ParseResources(get_event->info + i, &errors);
 
559
            CreateResourceBox(node, &errors);
 
560
        }
 
561
        else {
 
562
            AddString(&errors, get_event->info[i].message);
 
563
            AddString(&errors, "\n");
 
564
        }
 
565
    }
 
566
 
 
567
    return(errors);
 
568
}
 
569
 
 
570
/*      Function Name: CreateResourceBox
 
571
 *      Description: Creates a resource box for the widget specified.
 
572
 *      Arguments: node - the node of the widget in question.
 
573
 *                 errors - an error string.
 
574
 *      Returns: none.
 
575
 */
 
576
 
 
577
void
 
578
CreateResourceBox(node, errors)
 
579
WNode * node;
 
580
char ** errors;
 
581
{
 
582
    WidgetResources * resources = node->resources;
 
583
    char ** names, ** cons_names;
 
584
    int i;
 
585
 
 
586
    if (global_resource_box_up) {
 
587
        AddString(errors, res_labels[34]);
 
588
        return;
 
589
    }
 
590
    else
 
591
        global_resource_box_up = TRUE;
 
592
 
 
593
    if (resources->num_normal > 0) {
 
594
        names = (char **) XtMalloc(sizeof(char *) *
 
595
                                   (resources->num_normal + 1));
 
596
        for (i = 0 ; i < resources->num_normal ; i++) 
 
597
            names[i] = resources->normal[i].name;
 
598
        names[i] = NULL;
 
599
    }
 
600
    else
 
601
        names = NULL;
 
602
 
 
603
    if (resources->num_constraint > 0) {
 
604
        cons_names = (char **) XtMalloc(sizeof(char *) *
 
605
                                        (resources->num_constraint + 1));
 
606
        
 
607
        for (i = 0 ; i < resources->num_constraint ; i++) 
 
608
            cons_names[i] = resources->constraint[i].name;
 
609
        cons_names[i] = NULL;
 
610
    }
 
611
    else
 
612
        cons_names = NULL;
 
613
 
 
614
    CreateResourceBoxWidgets(node, names, cons_names);
 
615
}
 
616
 
 
617
/*      Function Name: ParseResources
 
618
 *      Description: Parses the resource values returned from the client
 
619
 *                   into a resources structure.
 
620
 *      Arguments: info - info about a widget's resources.
 
621
 *                 error - where to place error info.
 
622
 *      Returns: The resource information.
 
623
 */
 
624
 
 
625
static WidgetResources * 
 
626
ParseResources(info, error)
 
627
GetResourcesInfo * info;
 
628
char **error;
 
629
{
 
630
    WidgetResources * resources;
 
631
    WidgetResourceInfo * normal;
 
632
    int i;
 
633
 
 
634
    resources = (WidgetResources *) XtMalloc(sizeof(WidgetResources)); 
 
635
    
 
636
    /*
 
637
     * Allocate enough space for both the normal and constraint resources,
 
638
     * then add the normal resources from the top, and the constraint resources
 
639
     * from the bottom.  This assures that enough memory is allocated, and
 
640
     * that there is no overlap.
 
641
     */
 
642
 
 
643
    resources->normal = (WidgetResourceInfo *) 
 
644
                    XtMalloc(sizeof(WidgetResourceInfo) * info->num_resources);
 
645
 
 
646
    normal = resources->normal;
 
647
    resources->constraint = resources->normal + info->num_resources - 1;
 
648
 
 
649
    resources->num_constraint = resources->num_normal = 0;
 
650
 
 
651
    for (i = 0; i < (int)info->num_resources; i++) {
 
652
        switch((int) info->res_info[i].res_type) {
 
653
        case NormalResource:
 
654
            resources->num_normal++;
 
655
            AddResource(info->res_info + i, normal++);      
 
656
            break;
 
657
        case ConstraintResource:
 
658
            resources->num_constraint++;
 
659
            AddResource(info->res_info + i, resources->constraint--);
 
660
            break;
 
661
        default:
 
662
            {
 
663
                char buf[BUFSIZ];
 
664
                sprintf(buf, "Unknown resource type %d\n", 
 
665
                        info->res_info[i].res_type);
 
666
                AddString(error, buf);
 
667
            }
 
668
            break;
 
669
        }
 
670
    }
 
671
 
 
672
    /*
 
673
     * Sort the resources alphabetically. 
 
674
     */
 
675
 
 
676
    qsort(resources->normal, resources->num_normal,
 
677
          sizeof(WidgetResourceInfo), CompareResourceEntries);
 
678
 
 
679
    if (resources->num_constraint > 0) {
 
680
        resources->constraint++;
 
681
        qsort(resources->constraint, resources->num_constraint,
 
682
              sizeof(WidgetResourceInfo), CompareResourceEntries);
 
683
    }
 
684
    else
 
685
        resources->constraint = NULL;
 
686
 
 
687
    return(resources);
 
688
}
 
689
 
 
690
/*      Function Name: CompareResourceEntries
 
691
 *      Description: Compares two resource entries.
 
692
 *      Arguments: e1, e2 - the entries to compare.
 
693
 *      Returns: an integer >, < or = 0.
 
694
 */
 
695
 
 
696
static int 
 
697
CompareResourceEntries(e1, e2) 
 
698
const void *e1, *e2;
 
699
{
 
700
    return (strcmp(((WidgetResourceInfo *)e1)->name, 
 
701
                   ((WidgetResourceInfo *)e2)->name));
 
702
}
 
703
 
 
704
/*      Function Name: AddResource
 
705
 *      Description: Parses the resource string a stuffs in individual
 
706
 *                   parts into the resource info struct.
 
707
 *      Arguments: res_info - the resource info from the event.
 
708
 *                 resource - location to stuff the resource into.
 
709
 *      Returns: none.
 
710
 */
 
711
 
 
712
static void
 
713
AddResource(res_info, resource) 
 
714
ResourceInfo * res_info;
 
715
WidgetResourceInfo * resource;
 
716
{
 
717
    resource->name = res_info->name;
 
718
    res_info->name = NULL;      /* Keeps it from being deallocated. */
 
719
    resource->class = res_info->class;
 
720
    res_info->class = NULL;     /* Keeps it from being deallocated. */
 
721
    resource->type = res_info->type;
 
722
    res_info->type = NULL;      /* Keeps it from being deallocated. */
 
723
}
 
724
 
 
725
 
 
726
/*      Function Name: FreeResources
 
727
 *      Description: frees the resource inforation.
 
728
 *      Arguments: resources.
 
729
 *      Returns: none.
 
730
 */
 
731
 
 
732
static void
 
733
FreeResources(resources) 
 
734
WidgetResources * resources;
 
735
{
 
736
    int i;
 
737
 
 
738
    if (resources->num_normal > 0) {
 
739
        for (i = 0; i < resources->num_normal; i++) {
 
740
            XtFree(resources->normal[i].name);
 
741
            XtFree(resources->normal[i].class);
 
742
            XtFree(resources->normal[i].type);
 
743
        }
 
744
        XFree((char *)resources->normal);
 
745
    }
 
746
 
 
747
    if (resources->num_constraint > 0) {
 
748
        for (i = 0; i < resources->num_constraint; i++) {
 
749
            XtFree(resources->constraint[i].name);
 
750
            XtFree(resources->constraint[i].class);
 
751
            XtFree(resources->constraint[i].type);
 
752
        }
 
753
        XFree((char *)resources->constraint);
 
754
    }
 
755
 
 
756
    XFree((char *)resources);
 
757
}
 
758
        
 
759
 
 
760
/*      Function Name: CheckDatabase
 
761
 *      Description: Checks to see if the node is in the database.
 
762
 *      Arguments: db - the db to check
 
763
 *                 names, clases - names and clases, represented as quarks.
 
764
 *      Returns: True if this entry is found.
 
765
 */
 
766
 
 
767
Boolean
 
768
CheckDatabase(db, names, classes)
 
769
XrmDatabase db;
 
770
XrmQuarkList names, classes;
 
771
{
 
772
    XrmRepresentation junk;
 
773
    XrmValue garbage;
 
774
 
 
775
    return(XrmQGetResource(db, names, classes, &junk, &garbage));
 
776
}
 
777
 
 
778
/*      Function Name: Quarkify
 
779
 *      Description: Quarkifies the string list specifed.
 
780
 *      Arguments: list - list of strings to quarkify
 
781
 *                 ptr - an additional string to quarkify.
 
782
 *      Returns: none.
 
783
 */
 
784
 
 
785
XrmQuarkList
 
786
Quarkify(list, ptr)
 
787
char ** list;
 
788
char * ptr;
 
789
{
 
790
    int i;
 
791
    char ** tlist;
 
792
    XrmQuarkList quarks, tquarks;
 
793
 
 
794
    for (i = 0, tlist = list; *tlist != NULL; tlist++, i++) {}
 
795
    if (ptr != NULL)
 
796
        i++;
 
797
    i++;                        /* leave space for NULLQUARK */
 
798
 
 
799
    quarks = (XrmQuarkList) XtMalloc(sizeof(XrmQuark) * i);
 
800
 
 
801
    for (tlist = list, tquarks = quarks; *tlist != NULL; tlist++, tquarks++) 
 
802
        *tquarks = XrmStringToQuark(*tlist);
 
803
 
 
804
    if (ptr != NULL) 
 
805
        *tquarks++ = XrmStringToQuark(ptr);
 
806
        
 
807
    *tquarks = NULLQUARK;
 
808
    return(quarks);
 
809
}
 
810
 
 
811
/*      Function Name: ExecuteOverAllNodes
 
812
 *      Description: Executes the given function over all nodes.
 
813
 *      Arguments: top_node - top node of the tree.
 
814
 *                 func - the function to execute.
 
815
 *                 data - a data pointer to pass to the function.
 
816
 *      Returns: none
 
817
 */
 
818
 
 
819
void
 
820
ExecuteOverAllNodes(top_node, func, data)
 
821
WNode * top_node;
 
822
void (*func)(WNode *, XtPointer);
 
823
XtPointer data;
 
824
{
 
825
    int i;
 
826
 
 
827
    (*func)(top_node, data);
 
828
 
 
829
    for (i = 0; i < top_node->num_children; i++) 
 
830
        ExecuteOverAllNodes(top_node->children[i], func, data);
 
831
}
 
832
 
 
833
/*      Function Name: InsertWidgetFromNode
 
834
 *      Description: Inserts the widget info for this widget represented
 
835
 *                   by this node.
 
836
 *      Arguments: stream - the stream to insert it info into.
 
837
 *                 none - the widget node to insert.
 
838
 *      Returns: none
 
839
 */
 
840
 
 
841
void
 
842
InsertWidgetFromNode(stream, node)
 
843
ProtocolStream * stream;
 
844
WNode * node;
 
845
{
 
846
    WNode *temp;
 
847
    unsigned long * widget_list;
 
848
    register int i, num_widgets;
 
849
 
 
850
    for (temp = node, i = 0; temp != 0; temp = temp->parent, i++) {}
 
851
 
 
852
    num_widgets = i;
 
853
    widget_list = (unsigned long *) 
 
854
                  XtMalloc(sizeof(unsigned long) * num_widgets);
 
855
 
 
856
    /*
 
857
     * Put the widgets into the list.
 
858
     * Make sure that they are inserted in the list from parent -> child.
 
859
     */
 
860
 
 
861
    for (i--, temp = node; temp != 0; temp = temp->parent, i--) 
 
862
        widget_list[i] = temp->id;
 
863
        
 
864
    _XEditResPut16(stream, num_widgets);        /* insert number of widgets. */
 
865
    for (i = 0; i < num_widgets; i++)   /* insert Widgets themselves. */
 
866
        _XEditResPut32(stream, widget_list[i]);
 
867
    
 
868
    XtFree((char *)widget_list);
 
869
}
 
870
 
 
871
/*      Function Name: GetFailureMesssage
 
872
 *      Description: returns the message returned from a failed request.
 
873
 *      Arguments: stream - the protocol stream containing the message.
 
874
 *      Returns: message to show.
 
875
 */
 
876
 
 
877
char * 
 
878
GetFailureMessage(stream)
 
879
ProtocolStream * stream;
 
880
{
 
881
    char * return_str;
 
882
 
 
883
    if (_XEditResGetString8(stream, &return_str)) 
 
884
        return(return_str);
 
885
 
 
886
    return(XtNewString(res_labels[35]));
 
887
}
 
888
 
 
889
/*      Function Name: ProtocolFailure
 
890
 *      Description: Gets the version of the protocol the client is
 
891
 *                   willing to speak.
 
892
 *      Arguments: stream - the protocol stream containing the message.
 
893
 *      Returns: message to show.
 
894
 */
 
895
 
 
896
char * 
 
897
ProtocolFailure(stream)
 
898
ProtocolStream * stream;
 
899
{
 
900
    char buf[BUFSIZ];
 
901
    unsigned char version;
 
902
    char* old_version_string;
 
903
 
 
904
    if (!_XEditResGet8(stream, &version)) 
 
905
        return(XtNewString(res_labels[35]));
 
906
 
 
907
    switch ((int)version) {
 
908
    case PROTOCOL_VERSION_ONE_POINT_ZERO: old_version_string = "1.0"; break;
 
909
    default: old_version_string = "1.0";
 
910
    }
 
911
    
 
912
    sprintf(buf, res_labels[36], 
 
913
            CURRENT_PROTOCOL_VERSION_STRING, old_version_string);
 
914
    return(XtNewString(buf));
 
915
}
 
916