1/***********************************************************
2
3Copyright 1987, 1988, 1994, 1998  The Open Group
4
5Permission to use, copy, modify, distribute, and sell this software and its
6documentation for any purpose is hereby granted without fee, provided that
7the above copyright notice appear in all copies and that both that
8copyright notice and this permission notice appear in supporting
9documentation.
10
11The above copyright notice and this permission notice shall be included in
12all copies or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
17OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
21Except as contained in this notice, the name of The Open Group shall not be
22used in advertising or otherwise to promote the sale, use or other dealings
23in this Software without prior written authorization from The Open Group.
24
25
26Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts.
27
28                        All Rights Reserved
29
30Permission to use, copy, modify, and distribute this software and its
31documentation for any purpose and without fee is hereby granted,
32provided that the above copyright notice appear in all copies and that
33both that copyright notice and this permission notice appear in
34supporting documentation, and that the name of Digital not be
35used in advertising or publicity pertaining to distribution of the
36software without specific, written prior permission.
37
38DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
39ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
40DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
41ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
42WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
43ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
44SOFTWARE.
45
46******************************************************************/
47
48/*
49 * This is a copy of Xt/Vendor.c with an additional ClassInitialize
50 * procedure to register Xmu resource type converters, and all the
51 * monkey business associated with input methods...
52 *
53 */
54
55/* Make sure all wm properties can make it out of the resource manager */
56
57#ifdef HAVE_CONFIG_H
58#include <config.h>
59#endif
60#include <stdio.h>
61#include <X11/IntrinsicP.h>
62#include <X11/StringDefs.h>
63#include <X11/ShellP.h>
64#include <X11/VendorP.h>
65#include <X11/Xmu/Converters.h>
66#include <X11/Xmu/Atoms.h>
67#include <X11/Xmu/Editres.h>
68#include <X11/Xmu/ExtAgent.h>
69
70/* The following two headers are for the input method. */
71
72#include <X11/Xaw/VendorEP.h>
73#include <X11/Xaw/XawImP.h>
74
75/*
76 * Class Methods
77 */
78static void XawVendorShellChangeManaged(Widget);
79static Boolean XawCvtCompoundTextToString(Display*, XrmValuePtr, Cardinal*,
80					  XrmValue*, XrmValue*, XtPointer*);
81static void XawVendorShellClassInitialize(void);
82static XtGeometryResult XawVendorShellGeometryManager(Widget,
83						      XtWidgetGeometry*,
84						      XtWidgetGeometry*);
85static void XawVendorShellExtClassInitialize(void);
86static void XawVendorShellExtDestroy(Widget);
87static void XawVendorShellExtInitialize(Widget, Widget, ArgList, Cardinal*);
88void XawVendorShellExtResize(Widget);
89static Boolean XawVendorShellExtSetValues(Widget, Widget, Widget,
90					  ArgList, Cardinal*);
91static void XawVendorShellClassPartInit(WidgetClass);
92static void XawVendorShellInitialize(Widget, Widget, ArgList, Cardinal*);
93static void XawVendorShellRealize(Widget, Mask*, XSetWindowAttributes*);
94static Boolean XawVendorShellSetValues(Widget, Widget, Widget,
95				       ArgList, Cardinal*);
96
97/*
98 * External
99 */
100void XawVendorStructureNotifyHandler(Widget, XtPointer, XEvent*, Boolean*);
101
102static XtResource resources[] = {
103  {XtNinput, XtCInput, XtRBool, sizeof(Bool),
104		XtOffsetOf(VendorShellRec, wm.wm_hints.input),
105		XtRImmediate, (XtPointer)True}
106};
107
108/***************************************************************************
109 *
110 * Vendor shell class record
111 *
112 ***************************************************************************/
113
114#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__APPLE__)
115/* to fix the EditRes problem because of wrong linker semantics */
116extern WidgetClass vendorShellWidgetClass; /* from Xt/Vendor.c */
117extern VendorShellClassRec _XawVendorShellClassRec;
118extern void _XawFixupVendorShell();
119
120#if defined(__APPLE__)
121__attribute__((constructor))
122static void __VendorShellHack(void)
123{
124    vendorShellWidgetClass = (WidgetClass)(&_XawVendorShellClassRec);
125    _XawFixupVendorShell();
126}
127#else
128int __stdcall
129DllMain(unsigned long mod_handle, unsigned long flag, void *routine)
130{
131  switch (flag)
132    {
133    case 1: /* DLL_PROCESS_ATTACH - process attach */
134      vendorShellWidgetClass = (WidgetClass)(&_XawVendorShellClassRec);
135      _XawFixupVendorShell();
136      break;
137    case 0: /* DLL_PROCESS_DETACH - process detach */
138      break;
139    }
140  return 1;
141}
142#endif
143
144#define vendorShellClassRec _XawVendorShellClassRec
145
146#endif
147
148static CompositeClassExtensionRec vendorCompositeExt = {
149    /* next_extension     */	NULL,
150    /* record_type        */    NULLQUARK,
151    /* version            */    XtCompositeExtensionVersion,
152    /* record_size        */    sizeof (CompositeClassExtensionRec),
153    /* accepts_objects    */    TRUE,
154    /* allows_change_managed_set */ FALSE
155};
156
157#define SuperClass (&wmShellClassRec)
158externaldef(vendorshellclassrec) VendorShellClassRec vendorShellClassRec = {
159  {
160    /* superclass	  */	(WidgetClass)SuperClass,
161    /* class_name	  */	"VendorShell",
162    /* size		  */	sizeof(VendorShellRec),
163    /* class_initialize	  */	XawVendorShellClassInitialize,
164    /* class_part_init	  */	XawVendorShellClassPartInit,
165    /* Class init'ed ?	  */	FALSE,
166    /* initialize         */	XawVendorShellInitialize,
167    /* initialize_hook	  */	NULL,
168    /* realize		  */	XawVendorShellRealize,
169    /* actions		  */	NULL,
170    /* num_actions	  */	0,
171    /* resources	  */	resources,
172    /* resource_count	  */	XtNumber(resources),
173    /* xrm_class	  */	NULLQUARK,
174    /* compress_motion	  */	FALSE,
175    /* compress_exposure  */	TRUE,
176    /* compress_enterleave*/	FALSE,
177    /* visible_interest	  */	FALSE,
178    /* destroy		  */	NULL,
179    /* resize		  */	XawVendorShellExtResize,
180    /* expose		  */	NULL,
181    /* set_values	  */	XawVendorShellSetValues,
182    /* set_values_hook	  */	NULL,
183    /* set_values_almost  */	XtInheritSetValuesAlmost,
184    /* get_values_hook	  */	NULL,
185    /* accept_focus	  */	NULL,
186    /* intrinsics version */	XtVersion,
187    /* callback offsets	  */	NULL,
188    /* tm_table		  */	NULL,
189    /* query_geometry	  */	NULL,
190    /* display_accelerator*/	NULL,
191    /* extension	  */	NULL
192  },{
193    /* geometry_manager	  */	XawVendorShellGeometryManager,
194    /* change_managed	  */	XawVendorShellChangeManaged,
195    /* insert_child	  */	XtInheritInsertChild,
196    /* delete_child	  */	XtInheritDeleteChild,
197    /* extension	  */	(XtPointer) &vendorCompositeExt
198  },{
199    /* extension	  */	NULL
200  },{
201    /* extension	  */	NULL
202  },{
203    /* extension	  */	NULL
204  }
205};
206
207#if !defined(__APPLE__)
208externaldef(vendorshellwidgetclass) WidgetClass vendorShellWidgetClass =
209	(WidgetClass) (&vendorShellClassRec);
210#endif
211
212/***************************************************************************
213 *
214 * The following section is for the Vendor shell Extension class record
215 *
216 ***************************************************************************/
217
218static XtResource ext_resources[] = {
219  {XtNinputMethod, XtCInputMethod, XtRString, sizeof(String),
220		XtOffsetOf(XawVendorShellExtRec, vendor_ext.im.input_method),
221		XtRString, (XtPointer)NULL},
222  {XtNpreeditType, XtCPreeditType, XtRString, sizeof(String),
223		XtOffsetOf(XawVendorShellExtRec, vendor_ext.im.preedit_type),
224		XtRString, (XtPointer)"OverTheSpot,OffTheSpot,Root"},
225  {XtNopenIm, XtCOpenIm, XtRBoolean, sizeof(Boolean),
226		XtOffsetOf(XawVendorShellExtRec, vendor_ext.im.open_im),
227		XtRImmediate, (XtPointer)TRUE},
228  {XtNsharedIc, XtCSharedIc, XtRBoolean, sizeof(Boolean),
229		XtOffsetOf(XawVendorShellExtRec, vendor_ext.ic.shared_ic),
230		XtRImmediate, (XtPointer)FALSE}
231};
232
233externaldef(vendorshellextclassrec) XawVendorShellExtClassRec
234       xawvendorShellExtClassRec = {
235  {
236    /* superclass	  */	(WidgetClass)&objectClassRec,
237    /* class_name	  */	"VendorShellExt",
238    /* size		  */	sizeof(XawVendorShellExtRec),
239    /* class_initialize	  */	XawVendorShellExtClassInitialize,
240    /* class_part_initialize*/	NULL,
241    /* Class init'ed ?	  */	FALSE,
242    /* initialize	  */	XawVendorShellExtInitialize,
243    /* initialize_hook	  */	NULL,
244    /* pad		  */	NULL,
245    /* pad		  */	NULL,
246    /* pad		  */	0,
247    /* resources	  */	ext_resources,
248    /* resource_count	  */	XtNumber(ext_resources),
249    /* xrm_class	  */	NULLQUARK,
250    /* pad		  */	FALSE,
251    /* pad		  */	FALSE,
252    /* pad		  */	FALSE,
253    /* pad		  */	FALSE,
254    /* destroy		  */	XawVendorShellExtDestroy,
255    /* pad		  */	NULL,
256    /* pad		  */	NULL,
257    /* set_values	  */	XawVendorShellExtSetValues,
258    /* set_values_hook	  */	NULL,
259    /* pad		  */	NULL,
260    /* get_values_hook	  */	NULL,
261    /* pad		  */	NULL,
262    /* version		  */	XtVersion,
263    /* callback_offsets	  */	NULL,
264    /* pad		  */	NULL,
265    /* pad		  */	NULL,
266    /* pad		  */	NULL,
267    /* extension	  */	NULL
268  },{
269    /* extension	  */	NULL
270  }
271};
272
273externaldef(xawvendorshellwidgetclass) WidgetClass
274     xawvendorShellExtWidgetClass = (WidgetClass) (&xawvendorShellExtClassRec);
275
276
277/*ARGSUSED*/
278static Boolean
279XawCvtCompoundTextToString(Display *dpy, XrmValuePtr args _X_UNUSED, Cardinal *num_args _X_UNUSED,
280			   XrmValue *fromVal, XrmValue *toVal,
281			   XtPointer *cvt_data _X_UNUSED)
282{
283    char **list;
284    int count;
285    static char *mbs = NULL;
286    int len;
287    XTextProperty prop = {
288	.value = (unsigned char *)fromVal->addr,
289	.encoding = XA_COMPOUND_TEXT(dpy),
290	.format = 8,
291	.nitems = fromVal->size
292    };
293
294    if(XmbTextPropertyToTextList(dpy, &prop, &list, &count) < Success) {
295	XtAppWarningMsg(XtDisplayToApplicationContext(dpy),
296	"converter", "XmbTextPropertyToTextList", "XawError",
297	"conversion from CT to MB failed.", NULL, NULL);
298	return False;
299    }
300    len = (int)strlen(*list);
301    toVal->size = (unsigned)len;
302    mbs = XtRealloc(mbs, (Cardinal)(len + 1)); /* keep buffer because no one call free :( */
303    strcpy(mbs, *list);
304    XFreeStringList(list);
305    toVal->addr = (XtPointer)mbs;
306    return True;
307}
308
309static void
310XawVendorShellClassInitialize(void)
311{
312    static XtConvertArgRec screenConvertArg[] = {
313        {XtWidgetBaseOffset, (XtPointer) XtOffsetOf(WidgetRec, core.screen),
314	     sizeof(Screen *)}
315    };
316
317    XtAddConverter(XtRString, XtRCursor, XmuCvtStringToCursor,
318		   screenConvertArg, XtNumber(screenConvertArg));
319
320    XtAddConverter(XtRString, XtRBitmap, XmuCvtStringToBitmap,
321		   screenConvertArg, XtNumber(screenConvertArg));
322
323    XtSetTypeConverter("CompoundText", XtRString, XawCvtCompoundTextToString,
324			NULL, 0, XtCacheNone, NULL);
325}
326
327static void
328XawVendorShellClassPartInit(WidgetClass cclass)
329{
330    CompositeClassExtension ext;
331    VendorShellWidgetClass vsclass = (VendorShellWidgetClass)cclass;
332
333    if (((CompositeClassExtension)
334	  XtGetClassExtension (cclass,
335			       XtOffsetOf(CompositeClassRec,
336					  composite_class.extension),
337			       NULLQUARK, 1L, (Cardinal) 0)) == NULL) {
338	ext = (CompositeClassExtension) XtNew (CompositeClassExtensionRec);
339	if (ext != NULL) {
340	    ext->next_extension = vsclass->composite_class.extension;
341	    ext->record_type = NULLQUARK;
342	    ext->version = XtCompositeExtensionVersion;
343	    ext->record_size = sizeof (CompositeClassExtensionRec);
344	    ext->accepts_objects = TRUE;
345	    ext->allows_change_managed_set = FALSE;
346	    vsclass->composite_class.extension = (XtPointer) ext;
347	}
348    }
349}
350
351#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__APPLE__)
352/* shared libraries on these platforms have the wrong semantics */
353/* symbols do not get resolved external to the shared library */
354void _XawFixupVendorShell()
355{
356    transientShellWidgetClass->core_class.superclass =
357        (WidgetClass) &vendorShellClassRec;
358    topLevelShellWidgetClass->core_class.superclass =
359        (WidgetClass) &vendorShellClassRec;
360}
361#endif
362
363/* ARGSUSED */
364static void
365XawVendorShellInitialize(Widget req _X_UNUSED, Widget cnew,
366			 ArgList args, Cardinal *num_args)
367{
368    XtAddEventHandler(cnew, (EventMask) 0, TRUE, _XEditResCheckMessages, NULL);
369    XtAddEventHandler(cnew, (EventMask) 0, TRUE, XmuRegisterExternalAgent, NULL);
370    XtCreateWidget("shellext", xawvendorShellExtWidgetClass,
371		   cnew, args, *num_args);
372}
373
374/* ARGSUSED */
375static Boolean
376XawVendorShellSetValues(Widget old _X_UNUSED, Widget ref _X_UNUSED, Widget cnew _X_UNUSED,
377			ArgList args _X_UNUSED, Cardinal *num_args _X_UNUSED)
378{
379	return FALSE;
380}
381
382static void
383XawVendorShellRealize(Widget wid, Mask *vmask, XSetWindowAttributes *attr)
384{
385	WidgetClass super = wmShellWidgetClass;
386
387	/* Make my superclass do all the dirty work */
388
389	(*super->core_class.realize) (wid, vmask, attr);
390	_XawImRealize(wid);
391}
392
393
394static void
395XawVendorShellExtClassInitialize(void)
396{
397}
398
399/* ARGSUSED */
400static void
401XawVendorShellExtInitialize(Widget req _X_UNUSED, Widget cnew,
402			    ArgList args _X_UNUSED, Cardinal *num_args _X_UNUSED)
403{
404    _XawImInitialize(cnew->core.parent, cnew);
405}
406
407/* ARGSUSED */
408static void
409XawVendorShellExtDestroy(Widget w)
410{
411    _XawImDestroy( w->core.parent, w );
412}
413
414/* ARGSUSED */
415static Boolean
416XawVendorShellExtSetValues(Widget old _X_UNUSED, Widget ref _X_UNUSED, Widget cnew _X_UNUSED,
417			   ArgList args _X_UNUSED, Cardinal *num_args _X_UNUSED)
418{
419	return FALSE;
420}
421
422void
423XawVendorShellExtResize(Widget w)
424{
425	ShellWidget sw = (ShellWidget) w;
426	Widget childwid;
427	Cardinal i;
428	int core_height;
429
430	_XawImResizeVendorShell( w );
431	core_height = _XawImGetShellHeight( w );
432	for( i = 0; i < sw->composite.num_children; i++ ) {
433	    if( XtIsManaged( sw->composite.children[ i ] ) ) {
434		childwid = sw->composite.children[ i ];
435		XtResizeWidget( childwid,
436			       (Dimension)sw->core.width,
437			       (Dimension)core_height,
438			       childwid->core.border_width );
439	    }
440	}
441}
442
443/*ARGSUSED*/
444void
445XawVendorStructureNotifyHandler(Widget w, XtPointer closure _X_UNUSED, XEvent *event _X_UNUSED,
446				Boolean *continue_to_dispatch _X_UNUSED)
447{
448  XawVendorShellExtResize(w);
449}
450
451/*ARGSUSED*/
452static XtGeometryResult
453XawVendorShellGeometryManager(Widget wid, XtWidgetGeometry *request,
454			      XtWidgetGeometry *reply _X_UNUSED)
455{
456	ShellWidget shell = (ShellWidget)(wid->core.parent);
457	XtWidgetGeometry my_request;
458
459	if(shell->shell.allow_shell_resize == FALSE && XtIsRealized(wid))
460		return(XtGeometryNo);
461
462	if (request->request_mode & (CWX | CWY))
463	    return(XtGeometryNo);
464
465	/* %%% worry about XtCWQueryOnly */
466	my_request.request_mode = 0;
467	if (request->request_mode & CWWidth) {
468	    my_request.width = request->width;
469	    my_request.request_mode |= CWWidth;
470	}
471	if (request->request_mode & CWHeight) {
472	    my_request.height = (Dimension)(request->height
473			      + _XawImGetImAreaHeight( wid ));
474	    my_request.request_mode |= CWHeight;
475	}
476	if (request->request_mode & CWBorderWidth) {
477	    my_request.border_width = request->border_width;
478	    my_request.request_mode |= CWBorderWidth;
479	}
480	if (XtMakeGeometryRequest((Widget)shell, &my_request, NULL)
481		== XtGeometryYes) {
482	    /* assert: if (request->request_mode & CWWidth) then
483	     * 		  shell->core.width == request->width
484	     * assert: if (request->request_mode & CWHeight) then
485	     * 		  shell->core.height == request->height
486	     *
487	     * so, whatever the WM sized us to (if the Shell requested
488	     * only one of the two) is now the correct child size
489	     */
490
491	    wid->core.width = shell->core.width;
492	    wid->core.height = shell->core.height;
493	    if (request->request_mode & CWBorderWidth) {
494		wid->core.x = wid->core.y = (Position)(-request->border_width);
495	    }
496	    _XawImCallVendorShellExtResize(wid);
497	    return XtGeometryYes;
498	} else return XtGeometryNo;
499}
500
501static void
502XawVendorShellChangeManaged(Widget wid)
503{
504	ShellWidget w = (ShellWidget) wid;
505	Widget* childP;
506	int i;
507
508	(*SuperClass->composite_class.change_managed)(wid);
509	for (i = (int)w->composite.num_children, childP = w->composite.children;
510	     i; i--, childP++) {
511	    if (XtIsManaged(*childP)) {
512		XtSetKeyboardFocus(wid, *childP);
513		break;
514	    }
515	}
516}
517