Link with C++ linker
[oweals/cde.git] / cde / programs / dtcreate / UxXt.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 static char sccsid[] = "@(#)96  1.4  com/config/UxXt.c, aic, aic324, 9317324f 5/12/93 15:40:01";
24 /*
25  *  COMPONENT_NAME: AIC           AIXwindows Interface Composer
26  *
27  *  ORIGINS: 58
28  *
29  *
30  *                   Copyright IBM Corporation 1991, 1993
31  *
32  *                         All Rights Reserved
33  *
34  *   Permission to use, copy, modify, and distribute this software and its
35  *   documentation for any purpose and without fee is hereby granted,
36  *   provided that the above copyright notice appear in all copies and that
37  *   both that copyright notice and this permission notice appear in
38  *   supporting documentation, and that the name of IBM not be
39  *   used in advertising or publicity pertaining to distribution of the
40  *   software without specific, written prior permission.
41  *
42  *   IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
43  *   ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
44  *   PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR
45  *   CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
46  *   USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
47  *   OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
48  *   OR PERFORMANCE OF THIS SOFTWARE.
49 */
50 /*---------------------------------------------------------------------
51  * $XConsortium: UxXt.c /main/4 1995/11/01 16:08:57 rswiston $
52  *---------------------------------------------------------------------
53  *
54  *
55  *             Copyright (c) 1991, Visual Edge Software Ltd.
56  *
57  * ALL  RIGHTS  RESERVED.  Permission  to  use,  copy,  modify,  and
58  * distribute  this  software  and its documentation for any purpose
59  * and  without  fee  is  hereby  granted,  provided  that the above
60  * copyright  notice  appear  in  all  copies  and  that  both  that
61  * copyright  notice and this permission notice appear in supporting
62  * documentation,  and that  the name of Visual Edge Software not be
63  * used  in advertising  or publicity  pertaining to distribution of
64  * the software without specific, written prior permission. The year
65  * included in the notice is the year of the creation of the work.
66  *-------------------------------------------------------------------*/
67  /*------------------------------------------------------------------------
68  *                              UxXt.c
69  *-----------------------------------------------------------------------*/
70
71 #include <stdio.h>
72 #include <stdlib.h>
73
74 #include <X11/Intrinsic.h>
75 #include <X11/Shell.h>
76 #include <X11/StringDefs.h>
77 #include <X11/Xutil.h>
78 #include <X11/X.h>
79 #include <X11/Xmd.h>
80 #include <X11/Xlib.h>
81 #include <Xm/Xm.h>
82 #include <Xm/DialogS.h>
83
84 #ifdef UIL_CODE
85 #include <Mrm/MrmPublic.h>
86 #endif /* UIL_CODE */
87
88 #include "UxXt.h"
89
90 static  XContext        xcontext_id = 0;
91
92 /******************************************************************************
93 NAME:           GetTrueToplevel( wgt )
94
95 INPUT:          Widget  wgt             - the top user-created widget
96
97 RETURN:         Widget                  - the shell widget
98
99 DESCRIPTION:    Returns the true toplevel of that interface.
100                 This is needed for implicit shells where the widget passed to
101                 one of the Ux functions is not always the shell.
102
103 CREATION:       Visual Edge Software            April 6 1991
104 -----------------------------------------------------------------------------*/
105 Widget  GetTrueToplevel( Widget wgt )
106 {
107         while (wgt && !XtIsShell(wgt))
108         {
109                 wgt = XtParent(wgt);
110         }
111         return wgt;
112 }
113
114 /******************************************************************************
115 NAME:           handle_dialog_child( wgt, manage_func )
116
117 INPUT:          Widget  wgt                     - the dialogShellWidget
118                 void    (*manage_func)()        - either XtManageChild
119                                                   or XtUnmanageChild
120
121 RETURN:         int                             - UX_NO_ERROR if successfull
122                                                   UX_ERROR otherwise
123
124 DESCRIPTION:    Handles the popping up or popping down of dialog shells
125                 by managing or unmanaging their children.
126
127 CREATION:       Visual Edge Software            Sept 19/91
128 -----------------------------------------------------------------------------*/
129 static  int     handle_dialog_child( Widget wgt, void (*manage_func)(Widget) )
130 {
131         int     i, num_children;
132         Widget  *children;
133         int     error_flag = UX_ERROR;
134
135         XtVaGetValues( wgt,
136                        XmNnumChildren, &num_children,
137                        XmNchildren, &children,
138                        NULL );
139
140         /*-----------------------------------------------------
141          * We manage/unmanage the first rectObj child in the list.
142          * Note that the check for rectObjClass is necessary since
143          * some implementations of Motif add protocol children to
144          * the dialogShell. Additionally, when the LANG is set to
145          * Japanese, a widget of class Core is created. This widget
146          * should not be managed. We'll skip it.
147          *-----------------------------------------------------*/
148
149         for (i = 0; i < num_children; i++)
150         {
151                 if ( XtIsSubclass( children[i], rectObjClass )  &&
152                         (XtClass (children[i]) != coreWidgetClass))
153                 {
154                         (*manage_func)(children[i]);
155                         error_flag = UX_NO_ERROR;
156                         break;
157                 }
158         }
159
160         return ( error_flag );
161 }
162
163 /******************************************************************************
164 NAME:           popup_dialog( wgt, grab_flag )
165
166 INPUT:          Widget          wgt             - dialogShell to pop up
167                 XtGrabKind      grab_flag       - the grab flag
168
169 RETURN:         void
170
171 DESCRIPTION:    Pops up a dialogShell.
172
173 CREATION:       Visual Edge Software            Sept 19/91
174 -----------------------------------------------------------------------------*/
175 static  void    popup_dialog( Widget wgt, XtGrabKind grab_flag )
176 {
177         if ( handle_dialog_child( wgt, XtManageChild ) == UX_ERROR )
178                 XtPopup( wgt, grab_flag );
179 }
180
181 /******************************************************************************
182 NAME:           UxPopupInterface( wgt, grab_flag )
183
184 INPUT:          Widget          wgt             - Widget to popup
185                 XtGrabKind      grab_flag       - grab flag
186
187 RETURN:         int                     UX_ERROR or UX_NO_ERROR
188
189 DESCRIPTION:    Popups up an interface. The widget should be a toplevel widget.
190                 Note that special handling is required for dialogShells since
191                 those are popped up by managing their children if they have
192                 some.
193                 The grab_flag could be any of:
194                                 no_grab (XtGrabNone)
195                                 nonexclusive_grab (XtGrabNonexclusive)
196                                 exclusive_grab (XtGrabExclusive)
197
198 CREATION:       Visual Edge Software            April 6 1991
199 -----------------------------------------------------------------------------*/
200 int     UxPopupInterface( Widget wgt, XtGrabKind grab_flag )
201 {
202         if (!(wgt = GetTrueToplevel(wgt)))
203                 return ( UX_ERROR );
204
205         if ( XtIsSubclass( wgt, xmDialogShellWidgetClass ) )
206         {
207                 popup_dialog( wgt, grab_flag );
208         }
209         else
210         {
211                 XtPopup( wgt, grab_flag );
212         }
213
214         return ( UX_NO_ERROR );
215 }
216
217 /******************************************************************************
218 NAME:           popdown_dialog( wgt )
219
220 INPUT:          Widget  wgt             - dialogShell to popdown
221
222 RETURN:         void
223
224 DESCRIPTION:    Pops down a dialogShell.
225
226 CREATION:       Visual Edge Software            Sept 19/91
227 -----------------------------------------------------------------------------*/
228 static  void    popdown_dialog( Widget wgt )
229 {
230         if ( handle_dialog_child( wgt, XtUnmanageChild ) == UX_ERROR )
231                 XtPopdown( wgt );
232 }
233
234 /******************************************************************************
235 NAME:           UxPopdownInterface( wgt )
236
237 INPUT:          Widget  wgt             - Widget to popdown
238
239 RETURN:         int                     UX_ERROR / UX_NO_ERROR
240
241 DESCRIPTION:    Pops down an interface. The widget should be a toplevel widget.
242                 Note that special handling is required for dialogShells since
243                 those are popped down by unmanaging their children if they have
244                 some.
245
246 CREATION:       Visual Edge Software            April 6 1991
247 -----------------------------------------------------------------------------*/
248 int     UxPopdownInterface( Widget wgt )
249 {
250         if (!(wgt = GetTrueToplevel(wgt)))
251                 return ( UX_ERROR );
252
253         if ( XtIsSubclass( wgt, xmDialogShellWidgetClass ) )
254         {
255                 popdown_dialog( wgt );
256         }
257         else
258         {
259                 XtPopdown( wgt );
260         }
261
262         return ( UX_NO_ERROR );
263 }
264
265 /******************************************************************************
266 NAME:           UxDeleteContextCB( wgt, client_data, call_data )
267
268 INPUT:          Widget          wgt             - widget causing the callback
269                 XtPointer       client_data     - not used
270                 XtPointer       call_data       - not used
271
272 RETURN:         void
273
274 DESCRIPTION:    Deletes the X context entry.
275
276 EXT REFERENCES: UxTopLevel, xcontext_id
277
278 CREATION:       Visual Edge Software            April 6 1991
279 -----------------------------------------------------------------------------*/
280 void    UxDeleteContextCB( Widget wgt, XtPointer client_data,
281                                                 XtPointer _call_data )
282 {
283         XtPointer       call_data = _call_data;
284
285         (void) XDeleteContext( XtDisplay( UxTopLevel ),
286                                (Window) wgt,
287                                (XContext) client_data );
288 }
289
290 /******************************************************************************
291 NAME:           UxPutContext( wgt, context )
292
293 INPUT:          Widget  wgt             - Widget
294                 XtPointer context       - context pointer
295
296 RETURN:         int                     UX_ERROR / UX_NO_ERROR
297
298 DESCRIPTION:    Uses the X Context manager to store the given context pointer
299                 in a memory location that is indexed by the given widget id.
300                 Also adds a destroyCallback to delete that context when the
301                 widget is destroyed.
302
303 EXT REFERENCES: UxTopLevel, xcontext_id
304 EXT EFFECTS:    xcontext_id
305
306 CREATION:       Visual Edge Software            April 6 1991
307 -----------------------------------------------------------------------------*/
308 int     UxPutContext( Widget wgt, caddr_t context )
309 {
310         int             status;
311
312         if ( xcontext_id == 0 )
313                 xcontext_id = XUniqueContext();
314
315         if ( wgt == NULL )
316                 return ( UX_ERROR );
317
318         status = XSaveContext( XtDisplay( UxTopLevel ),
319                                (Window) wgt,
320                                xcontext_id,
321                                (char *) context );
322         if ( status != 0 )
323                 return ( UX_ERROR );
324
325         XtAddCallback (wgt, XmNdestroyCallback,
326                         UxDeleteContextCB, (XtPointer) xcontext_id);
327
328         return ( UX_NO_ERROR );
329 }
330
331 /******************************************************************************
332 NAME:           UxGetContext( wgt )
333
334 INPUT:          Widget  wgt             - widget
335
336 RETURN:         caddr_t                 - the context pointer
337
338 DESCRIPTION:    Uses the X Context manager to find the context pointer
339                 stored in a memory location indexed by the given widget id.
340
341 EXT REFERENCES: UxTopLevel, xcontext_id
342
343 CREATION:       Visual Edge Software            April 6 1991
344 -----------------------------------------------------------------------------*/
345 caddr_t         UxGetContext( Widget wgt )
346 {
347         int             status;
348         caddr_t         context;
349
350         if ( wgt == NULL )
351                 return ( (caddr_t) NULL );
352
353         status = XFindContext( XtDisplay( UxTopLevel ),
354                                (Window) wgt,
355                                xcontext_id,
356                                &context );
357
358         if ( status != 0 )
359                 return  ( (caddr_t) NULL );
360
361         return ( context );
362 }
363
364 /******************************************************************************
365 NAME:           DelayedFreeData ( client_data, id )
366
367 INPUT:          XtPointer       client_data     - pointer to be freed
368                 XtIntervalId    *id;
369
370 RETURN:         void
371
372 DESCRIPTION:    This XtTimerCallbackProc function simply frees the client data.
373
374 CREATION:       Visual Edge Software            April 30 1993
375 -----------------------------------------------------------------------------*/
376 static  void    DelayedFreeData( XtPointer client_data, XtIntervalId *_id)
377 {
378         XtIntervalId    *id = _id;
379
380         if (client_data != NULL) {
381                 XtFree((char *) client_data);
382         }
383 }
384 /******************************************************************************
385 NAME:           UxDestroyContextCB ( wgt, client_data, call_data )
386
387 INPUT:          Widget          wgt             - widget
388                 XtPointer       client_data     - pointer to be freed
389                 XtPointer       call_data       - not used
390
391 RETURN:         void
392
393 DESCRIPTION:    This callback function registers a timeout to free the
394                 context structure. This mechanism is used to ensure that
395                 user's destroyCallbacks are executed before we free the
396                 context structure.
397
398 CREATION:       Visual Edge Software            April 6 1991
399 -----------------------------------------------------------------------------*/
400 void    UxDestroyContextCB( Widget _wgt, XtPointer client_data,
401                                 XtPointer _call_data )
402 {
403         Widget          wgt = _wgt;
404         XtPointer       call_data = _call_data;
405
406         if (client_data != NULL) {
407                 XtAppAddTimeOut(UxAppContext, 0,
408                                 DelayedFreeData, client_data);
409         }
410 }
411
412 /******************************************************************************
413 NAME:           UxConvertFontList( fontlist_str )
414
415 INPUT:          char    *fontlist_str           - string form of fontlist
416
417 RETURN:         XmFontList                      - fontlist
418
419 DESCRIPTION:    Converts a fontlist from the resource-file string format
420                 to the XmFontList type expected in C code.
421                 The conversion is done by a call to the built-in Motif convertor
422                 and the return value points into Xt's resource cache
423                 and so the return value should NOT be XmFontListFree'd.
424
425 CREATION:       Visual Edge Software            June 17 1992
426 -----------------------------------------------------------------------------*/
427 XmFontList    UxConvertFontList( char *fontlist_str )
428 {
429         XrmValue        from, to;
430         XmFontList      fontlist = NULL;
431         Boolean         status;
432
433         from.size = strlen( fontlist_str ) + 1;
434         from.addr = fontlist_str;
435
436         to.size = sizeof(XmFontList);
437         to.addr = (caddr_t) &fontlist;
438
439         status = XtConvertAndStore( UxTopLevel,
440                                     XmRString, &from,
441                                     XmRFontList, &to );
442
443         return ( fontlist );
444 }
445
446 /******************************************************************************
447 NAME:           static ConvertPixmap( file_name, depth )
448
449 INPUT:          char    *file_name              - Pixmap file name
450                 int     depth                   - 0 for no depth specified
451
452 RETURN:         Pixmap
453
454 DESCRIPTION:    If the depth argument is 0 , then call XmGetPixmap (no depth
455                 argument). Otherwise, call XmGetPixmapByDepth (with depth as
456                 specified by the argument).
457                 Since there is no way of knowing how long the Pixmaps will be
458                 used, they are never destroyed. This is not a serious problem
459                 since XmGetPixmap does not regenerate existing Pixmaps.
460                 It simply keeps a reference count for the number of times a
461                 Pixmap is returned.
462
463 CREATION:       Visual Edge Software            March 31, 1993
464 -----------------------------------------------------------------------------*/
465 static Pixmap    ConvertPixmap( char *file_name, int depth )
466 {
467         XrmValue fg_from, fg_to, bg_from, bg_to;
468         Pixel fg, bg;
469
470         fg_from.size = strlen(XtDefaultForeground);
471         fg_from.addr = XtDefaultForeground;
472         fg_to.addr = (XPointer)&fg;
473         bg_from.size = strlen(XtDefaultBackground);
474         bg_from.addr = XtDefaultBackground;
475         bg_to.addr = (XPointer)&bg;
476         if (!XtConvertAndStore
477              (UxTopLevel, XtRString, &bg_from, XtRPixel, &bg_to)
478             || !XtConvertAndStore
479                 (UxTopLevel, XtRString, &fg_from, XtRPixel, &fg_to)
480             || (fg == bg)) {
481                 fg = WhitePixelOfScreen(XtScreen(UxTopLevel));
482                 bg = BlackPixelOfScreen(XtScreen(UxTopLevel));
483                 }
484         if (depth)
485                 return (XmGetPixmapByDepth
486                         (XtScreen(UxTopLevel), file_name, fg, bg, depth));
487
488         else
489                 return (XmGetPixmap(XtScreen(UxTopLevel), file_name, fg, bg));
490 }
491
492 /******************************************************************************
493 NAME:           UxConvertPixmap( file_name )
494
495 INPUT:          char    *file_name              - pixmap file name
496
497 RETURN:         Pixmap                          - Pixmap
498
499 DESCRIPTION:    Call ConvertPixmap with depth 0 (Pixmap)
500
501 CREATION:       Visual Edge Software            March 31, 1993
502 -----------------------------------------------------------------------------*/
503 Pixmap    UxConvertPixmap( char *file_name )
504 {
505         return (ConvertPixmap(file_name, 0));
506 }
507
508 /*------------------------------------------------------------------------
509  * NAME:        UxNewContext
510  *      <Allocate a context structure>
511  * INPUT:       size    -- of the desired structure
512  *              isSubclass      -- nonzero if the requester is a subclass,
513  *                                 requiring that the result also be
514  *                                 returned for the base.
515  * RETURNS:     Pointer to a data area of (at least) the desired size.
516  *------------------------------------------------------------------------*/
517 void*   UxNewContext (size_t size, int isSubclass)
518 {
519         static void* LastSubclassResult = 0;
520         static int   LastResultSize = 0;
521
522         void * result;
523
524         if (LastSubclassResult) {
525                 result = LastSubclassResult;
526         } else {
527                 result = XtMalloc(size);
528         }
529
530         if (isSubclass) {
531                 LastSubclassResult = result;
532                 if (LastResultSize  < size) {
533                         LastResultSize   = size;
534                 }
535         } else {
536                 LastSubclassResult = 0;
537                 LastResultSize     = 0;
538         }
539
540         return (result);
541 }
542 /**  end of file ***/