~ubuntu-branches/debian/jessie/eso-midas/jessie

« back to all changes in this revision

Viewing changes to gui/GraphLib/libsrc/uimxR5/src/UxMethod.c

  • Committer: Package Import Robot
  • Author(s): Ole Streicher
  • Date: 2014-04-22 14:44:58 UTC
  • Revision ID: package-import@ubuntu.com-20140422144458-okiwi1assxkkiz39
Tags: upstream-13.09pl1.2+dfsg
ImportĀ upstreamĀ versionĀ 13.09pl1.2+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*---------------------------------------------------------------------
 
2
 * $Date: 2009-08-18 15:23:20 $             $Revision: 1.2 $
 
3
 *---------------------------------------------------------------------
 
4
 * 
 
5
 *
 
6
 *             Copyright (c) 1992, Visual Edge Software Ltd.
 
7
 *
 
8
 * ALL  RIGHTS  RESERVED.  Permission  to  use,  copy,  modify,  and
 
9
 * distribute  this  software  and its documentation for any purpose
 
10
 * and  without  fee  is  hereby  granted,  provided  that the above
 
11
 * copyright  notice  appear  in  all  copies  and  that  both  that
 
12
 * copyright  notice and this permission notice appear in supporting
 
13
 * documentation,  and that  the name of Visual Edge Software not be
 
14
 * used  in advertising  or publicity  pertaining to distribution of
 
15
 * the software without specific, written prior permission. The year
 
16
 * included in the notice is the year of the creation of the work.
 
17
 *-------------------------------------------------------------------*/
 
18
/*
 
19
.VERSION
 
20
 090818         last modif
 
21
*/
 
22
 
 
23
/*------------------------------------------------------------------------
 
24
 * Method registration and dispatch for swidget interfaces.
 
25
 * This version supports the default macros and generated code,
 
26
 * using a simple (and fast) table lookup approach.
 
27
 *------------------------------------------------------------------------*/
 
28
 
 
29
#ifdef XT_CODE
 
30
#       include "UxXt.h"
 
31
#else /* XT_CODE */
 
32
#       include "UxLib.h"
 
33
#       include "method.h"
 
34
#endif /* XT_CODE */
 
35
 
 
36
 
 
37
#ifdef DESIGN_TIME
 
38
#include "veos.h"
 
39
#include "swidget.h"
 
40
#endif
 
41
 
 
42
extern int UxStrEqual();
 
43
 
 
44
 
 
45
/* Global environment variable supplied for the user's convenience */
 
46
Environment UxEnv = {NO_EXCEPTION};
 
47
 
 
48
static char **Names;            /* All method names as registered */
 
49
static int   NameLen = 0;       /* Gross length of names array  */      
 
50
static int   NumNames = 0;      /* Num Elements in names array  */
 
51
 
 
52
static void  ***MethodTable;    /* All method pointers          */
 
53
static int   *BaseTable;        /* Base class id's by class id. */
 
54
static int   NumClasses = 0;    /* Active width of method table */
 
55
static int   *MethodCounts;     /* Height by row in method table */
 
56
 
 
57
#ifdef _NO_PROTO
 
58
static int UndefinedMethod ();
 
59
#else /* _NO_PROTO */
 
60
static int UndefinedMethod (void);
 
61
#endif /* _NO_PROTO */
 
62
 
 
63
#ifdef XT_CODE
 
64
static  XContext        xcontext_mid = 0;
 
65
#endif /* XT_CODE */
 
66
 
 
67
/*------------------------------------------------------------------------
 
68
 * NAME: UxMethodLookup
 
69
 * INPUT:       swidget sw;     -- a swidget, usually an interface swidget
 
70
 *              int     mid;    -- a method id from UxMethodRegister
 
71
 * RETURNS:     Pointer to method function for this method.
 
72
 * DESCRIPTION:
 
73
 *      This is the heart of virtual method lookup.
 
74
 *      The design-time routing functions and runtime macros
 
75
 *      use this function to fnd the implementation of a method.
 
76
 *      The return value is the actual function pointer
 
77
 *      for the implementation of the method associated with `sw's 
 
78
 *      interface class.
 
79
 *      
 
80
 * LAST REV:    Feb 93  fix3910         Add support for subclassing.
 
81
 *------------------------------------------------------------------------*/
 
82
 
 
83
#ifdef _NO_PROTO
 
84
void* UxMethodLookup(sw, mid, mname) 
 
85
        swidget sw;
 
86
        int     mid;
 
87
        char    * mname;
 
88
#else /* _NO_PROTO */
 
89
void* UxMethodLookup(swidget sw, int mid, char  *mname)
 
90
#endif /* _NO_PROTO */
 
91
{
 
92
        int cid = UxGetClassCode(sw);
 
93
 
 
94
        if (mid < 0) {
 
95
                mid = UxMessageIndex(mname);
 
96
                if (mid < 0) {
 
97
                        return 0;
 
98
                }
 
99
        } 
 
100
 
 
101
        /*-----------------------------------------------------------
 
102
         * The method may be registered on this class or a base class.
 
103
         *-----------------------------------------------------------*/
 
104
 
 
105
        while (cid > -1 && cid < NumClasses)
 
106
        {
 
107
                if (mid < MethodCounts[cid] && MethodTable[cid][mid]) 
 
108
                {
 
109
                        return MethodTable[cid][mid];
 
110
                }
 
111
                cid = BaseTable[cid];
 
112
        }
 
113
#ifndef DESIGN_TIME
 
114
        return (void *) UndefinedMethod;
 
115
#else 
 
116
        return 0;
 
117
#endif 
 
118
}
 
119
 
 
120
/*------------------------------------------------------------------------
 
121
 * NAME: UxNewClassId 
 
122
 * RETURNS:     a unique integer each time called.
 
123
 * DESCRIPTION:
 
124
 *      This is to get a unique id for each interface class registered.
 
125
 *      The result is used for calls to UxMethodRegister, and
 
126
 *      is associated with each instance of the interface class:
 
127
 *      it is returned by UxGetClassId(sw) for each interface swidget sw
 
128
 *      that is an instance of the interface it represents.
 
129
 *
 
130
 *      We have no subclassing.  When it comes, parent class id's
 
131
 *      will be supplied in this call, and used to initialize the 
 
132
 *      classes' method table with its parent's versions.
 
133
 *
 
134
 * LAST REV:    Feb 93  fix3910         Add support for subclassing.
 
135
 *------------------------------------------------------------------------*/
 
136
 
 
137
#ifdef _NO_PROTO
 
138
int UxNewClassId()
 
139
#else /* _NO_PROTO */
 
140
int UxNewClassId(void)
 
141
#endif /* _NO_PROTO */
 
142
{
 
143
        static int   GrossClasses = 0;  /* Gross width of method table  */
 
144
 
 
145
        int cid = NumClasses++;
 
146
 
 
147
        if (GrossClasses < NumClasses)
 
148
        {
 
149
                if (GrossClasses) {
 
150
                        MethodTable = (void***) 
 
151
                                UxRealloc(MethodTable, 
 
152
                                       (GrossClasses += 10) * sizeof(void**));
 
153
                        MethodCounts = (int*) 
 
154
                                UxRealloc(MethodCounts,
 
155
                                          (GrossClasses * sizeof(int)));
 
156
                        BaseTable = (int*) 
 
157
                                UxRealloc(BaseTable,
 
158
                                          GrossClasses * sizeof(int));
 
159
                } else {
 
160
                        MethodTable = (void***) UxCalloc((GrossClasses += 10), 
 
161
                                                         sizeof(void**));
 
162
                        MethodCounts = (int*) UxCalloc(GrossClasses, 
 
163
                                                       sizeof(int));
 
164
                        BaseTable = (int*) UxCalloc(GrossClasses, 
 
165
                                                       sizeof(int));
 
166
                }
 
167
        }
 
168
        MethodTable[cid]   = (void**) UxCalloc(NumNames, sizeof(void*));
 
169
        MethodCounts[cid]  = NumNames;
 
170
        BaseTable[cid]  = -1;
 
171
 
 
172
        return cid;
 
173
}
 
174
 
 
175
/*------------------------------------------------------------------------
 
176
 * NAME: UxNewSubclassId (super)
 
177
 *      <register a new class as a subclass of an existing class> 
 
178
 * INPUT:       super class id
 
179
 * RETURNS:     new class id of a subclass of the superclass.
 
180
 *
 
181
 * LAST REV:    Feb 93  fix3910         Add support for subclassing.
 
182
 *------------------------------------------------------------------------*/
 
183
 
 
184
#ifdef _NO_PROTO
 
185
int     UxNewSubclassId(super)
 
186
        int super;
 
187
#else /* _NO_PROTO */
 
188
int     UxNewSubclassId( int super)
 
189
#endif /* _NO_PROTO */
 
190
{
 
191
        int cid = UxNewClassId();
 
192
        BaseTable[cid] = super;
 
193
        return cid;
 
194
}
 
195
 
 
196
/*------------------------------------------------------------------------
 
197
 * NAME:        UxMessageIndex 
 
198
 * INPUT:       char* name; -- name of a method being registered.
 
199
 * RETURNS:     A unique id number for this name.
 
200
 * DESCRIPTION:
 
201
 *      Assigns a unique integer to a message name.  
 
202
 *      Must return the same id for all calls with the same name.
 
203
 *
 
204
 *      This is used while rgistering methods at startup time.
 
205
 *      The result is used when method calls are made
 
206
 *      (see UxMethodLookup).  If a very large number of method names
 
207
 *      are being used, initialization could be speeded up by making
 
208
 *      this function faster (by sorting or hashing the names).
 
209
 *
 
210
 * LAST REV:    June 92 fix3574         Created.
 
211
 *------------------------------------------------------------------------*/
 
212
#ifdef _NO_PROTO
 
213
int UxMessageIndex (name)
 
214
        char* name;
 
215
#else /* _NO_PROTO */
 
216
int UxMessageIndex ( char* name)
 
217
#endif /* _NO_PROTO */
 
218
{
 
219
        int mid;
 
220
 
 
221
        for (mid = 0 ; mid < NumNames; mid++)
 
222
        {
 
223
                if (UxStrEqual(Names[mid], name)) {
 
224
                        return mid;
 
225
                }
 
226
        }
 
227
        if (mid >= NameLen) {
 
228
                if (NameLen == 0) {
 
229
                        Names = (char**) UxMalloc((NameLen=64)*sizeof(char*));
 
230
                } else {
 
231
                        Names = (char**) UxRealloc(Names, 
 
232
                                                   (NameLen*=2)*sizeof(char*));
 
233
                }
 
234
        }
 
235
 
 
236
        Names[NumNames] = (char*) UxMalloc(strlen(name)+1);
 
237
        strcpy(Names[NumNames], name);
 
238
        return NumNames++;
 
239
}
 
240
 
 
241
/*------------------------------------------------------------------------
 
242
 * NAME: MethodTableSpace 
 
243
 * INPUT:
 
244
 *              int cid;        -- class id from UxNewClassId ()
 
245
 *              int mid;        -- method id  from UxMessageIndex ()
 
246
 * DESCRIPTION:
 
247
 *
 
248
 *  Enlarges the method table for the given cid,
 
249
 *  so that it is at least big enough to register a method
 
250
 *  for the given message index.  We also add a little more space
 
251
 *  (two more cells), but not a lot: there's one of these
 
252
 *  arrays for each class, so we don't want them growing too large.
 
253
 *
 
254
 * LAST REV:    Feb 93  fix3910         Add support for subclassing.
 
255
 *------------------------------------------------------------------------*/
 
256
 
 
257
#ifdef _NO_PROTO
 
258
static void MethodTableSpace (cid, mid)
 
259
        int cid;
 
260
        int mid;
 
261
#else /* _NO_PROTO */
 
262
static void MethodTableSpace (int cid, int mid)
 
263
#endif /* _NO_PROTO */
 
264
{
 
265
        int old_cnt = MethodCounts[cid];
 
266
        int i;
 
267
 
 
268
        if (old_cnt < mid+1)
 
269
        {
 
270
                MethodTable[cid] = (void**) UxRealloc(MethodTable[cid],
 
271
                                                     (mid + 2) * sizeof(void*));
 
272
                for (i = old_cnt; i < mid+2; i++)
 
273
                {
 
274
                        MethodTable[cid][i] = 0;
 
275
                }
 
276
                MethodCounts[cid] = mid + 2;
 
277
        }
 
278
}
 
279
 
 
280
/*------------------------------------------------------------------------
 
281
 * NAME: UxMethodRegister
 
282
 * INPUT:       int     cid;            -- a class code from UxNewClassId()
 
283
 *              char    *name;          -- a method name
 
284
 *              void    (*function) (); -- implementation of the method
 
285
 *                                         for the identified class.
 
286
 *
 
287
 * RETURNS:     An identifier code for the given method name
 
288
 *              to be used in subsequent calls to UxMethodLookup.
 
289
 *              All calls to this function with the same method name
 
290
 *              return the same index.
 
291
 *
 
292
 * DESCRIPTION:
 
293
 *      Called during interface class initialization for each method
 
294
 *      implemented by the class.  
 
295
 *      It builds the method lookup table for the class. 
 
296
 *
 
297
 * LAST REV:    June 92 fix3574         Created.
 
298
 *------------------------------------------------------------------------*/
 
299
 
 
300
#ifdef _NO_PROTO
 
301
int UxMethodRegister(cid, name, function)
 
302
        int     cid;
 
303
        char    *name;
 
304
        void    (*function) ();
 
305
#else /* _NO_PROTO */
 
306
int UxMethodRegister(int cid, char *name, void  (*function) ())
 
307
#endif /* _NO_PROTO */
 
308
{
 
309
        int mid = UxMessageIndex (name);
 
310
 
 
311
        MethodTableSpace(cid, mid);
 
312
        MethodTable[cid][mid] = (void *) function;
 
313
 
 
314
        return mid;
 
315
}
 
316
 
 
317
/*------------------------------------------------------------------------
 
318
 * NAME:  UxGetClassCode
 
319
 *
 
320
 * INPUT:       some swidget
 
321
 * RETURNS:             its ifClassCode, or that of its nearest container
 
322
 *                      that has a class code.
 
323
 * DESCRIPTION:
 
324
 *
 
325
 *      This makes calling methods a little more flexible.
 
326
 *      Class codes are assigned to top-level swidgets in interfaces,
 
327
 *      when their delarations are initialized. 
 
328
 *
 
329
 * LAST REV:
 
330
 *------------------------------------------------------------------------*/
 
331
 
 
332
#ifdef _NO_PROTO
 
333
int     UxGetClassCode(sw)
 
334
        swidget sw;
 
335
#else /* _NO_PROTO */
 
336
int     UxGetClassCode(swidget sw)
 
337
#endif /* _NO_PROTO */
 
338
{
 
339
        while (sw && UxGetIfClassCode(sw) < 0) {
 
340
                sw = UxGetParent(sw);
 
341
        }
 
342
 
 
343
        if (sw)
 
344
                return UxGetIfClassCode(sw);
 
345
 
 
346
        return -1;
 
347
}
 
348
 
 
349
/******************************************************************************
 
350
NAME:           UxPutClassCode( wgt, id )
 
351
 
 
352
INPUT:          Widget  wgt             - Widget
 
353
                int     id;             - Id od method
 
354
 
 
355
RETURN:         int                     UX_ERROR / UX_NO_ERROR
 
356
 
 
357
DESCRIPTION:    Uses the X Context manager to store the given id 
 
358
                in a memory location that is indexed by the given widget id.
 
359
 
 
360
EXT REFERENCES: UxTopLevel, xcontext_mid
 
361
EXT EFFECTS:    xcontext_mid
 
362
 
 
363
CREATION:       Visual Edge Software            January 9 1993
 
364
-----------------------------------------------------------------------------*/
 
365
#ifdef XT_CODE
 
366
#ifdef _NO_PROTO
 
367
int     UxPutClassCode( wgt, id)
 
368
        Widget          wgt;
 
369
        int             id;
 
370
#else
 
371
int     UxPutClassCode( Widget wgt, int id)
 
372
#endif /* _NO_PROTO */
 
373
{
 
374
        int             status;
 
375
 
 
376
        if ( xcontext_mid == 0 )
 
377
                xcontext_mid = XUniqueContext();
 
378
 
 
379
        if ( wgt == NULL )
 
380
                return ( UX_ERROR );
 
381
 
 
382
        status = XSaveContext( XtDisplay( UxTopLevel ), 
 
383
                               (Window) wgt, 
 
384
                               xcontext_mid, 
 
385
                               (XtPointer) id );
 
386
        if ( status != 0 )
 
387
                return ( UX_ERROR );
 
388
 
 
389
        XtAddCallback (wgt, XmNdestroyCallback, 
 
390
                UxDeleteContextCB, (XtPointer) xcontext_mid);
 
391
 
 
392
        return ( UX_NO_ERROR );
 
393
}
 
394
#endif /* XT_CODE */
 
395
 
 
396
/******************************************************************************
 
397
NAME:           UxGetIfClassCode( wgt )
 
398
 
 
399
INPUT:          Widget  wgt             - widget
 
400
 
 
401
RETURN:         caddr_t                 - the context pointer
 
402
 
 
403
DESCRIPTION:    Uses the X Context manager to find the method id 
 
404
                stored in a memory location indexed by the given widget id.
 
405
 
 
406
EXT REFERENCES: UxTopLevel, xcontext_mid
 
407
 
 
408
CREATION:       Visual Edge Software            January 9 1993
 
409
-----------------------------------------------------------------------------*/
 
410
#ifdef XT_CODE
 
411
#ifdef _NO_PROTO
 
412
int             UxGetIfClassCode( wgt )
 
413
                Widget  wgt;
 
414
#else
 
415
int             UxGetIfClassCode( Widget wgt )
 
416
#endif /* _NO_PROTO */
 
417
{
 
418
        int             status;
 
419
        XtPointer       id;
 
420
 
 
421
        if ( wgt == NULL )
 
422
                return -1;
 
423
 
 
424
        status = XFindContext( XtDisplay( UxTopLevel ), 
 
425
                               (Window) wgt, 
 
426
                               xcontext_mid, 
 
427
                               (XtPointer) &id );
 
428
 
 
429
        if ( status != 0 )
 
430
                return  -1;
 
431
 
 
432
        return ( (int) id);
 
433
}
 
434
#endif /* XT_CODE */
 
435
 
 
436
/*------------------------------------------------------------------------
 
437
 * UxChildSite (this)
 
438
 * INPUT:       swidget inst - user-defined component
 
439
 * Gets the designatedChildSite by composing a call to the childSite
 
440
 * method and calling that method. If the childSite is an intance,
 
441
 * we recur by calling the childSite's childSite method and so on...
 
442
 * LAST REV:    March 1993      3988    - don't recur when childSite==this
 
443
 *------------------------------------------------------------------------*/
 
444
#ifdef _NO_PROTO
 
445
swidget UxChildSite (inst)
 
446
        swidget inst;
 
447
#else /* _NO_PROTO */
 
448
swidget UxChildSite (swidget inst)
 
449
#endif /* _NO_PROTO */
 
450
{
 
451
        /*-----------------------------------------------------
 
452
         * Index of "childSite" in low-level method dispatcher.
 
453
         *-----------------------------------------------------*/
 
454
        static int      ChildSiteMID = -1;
 
455
 
 
456
        swidget childSite       = NULL;
 
457
#ifdef _NO_PROTO
 
458
        void    (*childSiteMethod) () ;
 
459
#else
 
460
        void    (*childSiteMethod) (swidget, Environment *);
 
461
#endif
 
462
 
 
463
        if (ChildSiteMID == -1) {
 
464
                ChildSiteMID = UxMessageIndex("childSite");
 
465
        }
 
466
        if (! inst) {
 
467
                return childSite;
 
468
        }
 
469
 
 
470
        childSiteMethod = (void (*) ()) 
 
471
                          UxMethodLookup (inst, ChildSiteMID, "childSite");
 
472
        if (childSiteMethod) {
 
473
                childSite = ((swidget(*)())childSiteMethod) (inst, &UxEnv);
 
474
                if (childSite && childSite != inst) 
 
475
                {
 
476
                        swidget nested = UxChildSite(childSite);
 
477
                        if (nested) {
 
478
                                childSite = nested;
 
479
                        }
 
480
                }
 
481
        }
 
482
        if (!childSite) {
 
483
                childSite = inst;
 
484
        }
 
485
        return childSite;
 
486
}
 
487
 
 
488
/*------------------------------------------------------------------------
 
489
 * NAME: UxReclassifyCID (cid, super)
 
490
 *      <redefine a subclass as being derived from a new base.>
 
491
 * INPUT:       sub class id
 
492
 *              super class id
 
493
 *
 
494
 * LAST REV:    3988 Mar 93     Created.
 
495
 *------------------------------------------------------------------------*/
 
496
#ifdef DESIGN_TIME
 
497
 
 
498
#ifdef _NO_PROTO
 
499
void    UxReclassifyCID(cid, super)
 
500
        int cid;
 
501
        int super;
 
502
#else /* _NO_PROTO */
 
503
void    UxReclassifyCID(int cid, int super)
 
504
#endif /* _NO_PROTO */
 
505
{
 
506
        if (cid == super) {
 
507
                UxInternalError(__FILE__, __LINE__, "Cid == Super Cid");
 
508
        }
 
509
        BaseTable[cid] = super;
 
510
}
 
511
#endif  /* DESIGN_TIME */
 
512
/*------------------------------------------------------------------------
 
513
 * NAME: UxInheritedMethodLookup
 
514
 * INPUT:       swidget sw;     -- a swidget, usually an interface swidget
 
515
 *              int     mid;    -- a method id from UxMethodRegister
 
516
 * RETURNS:     Pointer to method function for this method.
 
517
 * DESCRIPTION:
 
518
 *      Like UxMethodLookup, but starts searching at the first
 
519
 *      base class of the given sw, not at its own class.
 
520
 *      
 
521
 * LAST REV:    3988 March 93 Created.
 
522
 *------------------------------------------------------------------------*/
 
523
#ifdef DESIGN_TIME
 
524
 
 
525
#ifdef _NO_PROTO
 
526
void*   UxInheritedMethodLookup (sw, mid, mname)
 
527
        swidget sw;
 
528
        int     mid;
 
529
        char    * mname;
 
530
#else /* _NO_PROTO */
 
531
void*   UxInheritedMethodLookup (swidget sw, int mid, char *mname)
 
532
#endif /* _NO_PROTO */
 
533
{
 
534
        int cid = UxGetClassCode(sw);
 
535
 
 
536
        if (cid < 0 ||  cid > NumClasses) {
 
537
                return 0;
 
538
        }
 
539
 
 
540
        if (mid < 0) {
 
541
                mid = UxMessageIndex(mname);
 
542
                if (mid < 0) {
 
543
                        return 0;
 
544
                }
 
545
        } 
 
546
 
 
547
        cid = BaseTable[cid];
 
548
        while (cid > -1 && cid < NumClasses)
 
549
        {
 
550
                if (mid < MethodCounts[cid] && MethodTable[cid][mid]) {
 
551
                        return MethodTable[cid][mid];
 
552
                }
 
553
                cid = BaseTable[cid];
 
554
        }
 
555
        return 0;
 
556
}
 
557
#endif  /* DESIGN_TIME */
 
558
 
 
559
#ifndef DESIGN_TIME
 
560
/*------------------------------------------------------------------------
 
561
 * NAME: UndefinedMethod
 
562
 * INPUT:       
 
563
 * RETURNS:     always 0.
 
564
 * DESCRIPTION: Function used as a return value of UxMethodLookup
 
565
 *              in case the method lookup fails.
 
566
 *      
 
567
 * LAST REV:    April 8 1993
 
568
 *------------------------------------------------------------------------*/
 
569
 
 
570
#ifdef _NO_PROTO
 
571
static int UndefinedMethod ()
 
572
#else /* _NO_PROTO */
 
573
static int UndefinedMethod (void)
 
574
#endif /* _NO_PROTO */
 
575
{
 
576
        return 0;
 
577
}
 
578
#endif /* DESIGN_TIME */