15dfecf96Smrg/*
25dfecf96Smrg * Copyright (c) 2001 by The XFree86 Project, Inc.
35dfecf96Smrg *
45dfecf96Smrg * Permission is hereby granted, free of charge, to any person obtaining a
55dfecf96Smrg * copy of this software and associated documentation files (the "Software"),
65dfecf96Smrg * to deal in the Software without restriction, including without limitation
75dfecf96Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
85dfecf96Smrg * and/or sell copies of the Software, and to permit persons to whom the
95dfecf96Smrg * Software is furnished to do so, subject to the following conditions:
105dfecf96Smrg *
115dfecf96Smrg * The above copyright notice and this permission notice shall be included in
125dfecf96Smrg * all copies or substantial portions of the Software.
135dfecf96Smrg *
145dfecf96Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
155dfecf96Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
165dfecf96Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
175dfecf96Smrg * THE XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
185dfecf96Smrg * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
195dfecf96Smrg * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
205dfecf96Smrg * SOFTWARE.
215dfecf96Smrg *
225dfecf96Smrg * Except as contained in this notice, the name of the XFree86 Project shall
235dfecf96Smrg * not be used in advertising or otherwise to promote the sale, use or other
245dfecf96Smrg * dealings in this Software without prior written authorization from the
255dfecf96Smrg * XFree86 Project.
265dfecf96Smrg *
275dfecf96Smrg * Author: Paulo César Pereira de Andrade
285dfecf96Smrg */
295dfecf96Smrg
305dfecf96Smrg/* $XFree86: xc/programs/xedit/lisp/modules/xt.c,v 1.20tsi Exp $ */
315dfecf96Smrg
325dfecf96Smrg#include <stdlib.h>
335dfecf96Smrg#include <stdio.h>
345dfecf96Smrg#include <string.h>
355dfecf96Smrg#include <X11/Intrinsic.h>
365dfecf96Smrg#include <X11/StringDefs.h>
375dfecf96Smrg#include <X11/Shell.h>
385dfecf96Smrg#include "lisp/internal.h"
395dfecf96Smrg#include "lisp/private.h"
405dfecf96Smrg
415dfecf96Smrg/*
425dfecf96Smrg * Types
435dfecf96Smrg */
445dfecf96Smrgtypedef struct {
455dfecf96Smrg    XrmQuark qname;
465dfecf96Smrg    XrmQuark qtype;
475dfecf96Smrg    Cardinal size;
485dfecf96Smrg} ResourceInfo;
495dfecf96Smrg
505dfecf96Smrgtypedef struct {
515dfecf96Smrg    WidgetClass widget_class;
525dfecf96Smrg    ResourceInfo **resources;
535dfecf96Smrg    Cardinal num_resources;
545dfecf96Smrg    Cardinal num_cons_resources;
555dfecf96Smrg} ResourceList;
565dfecf96Smrg
575dfecf96Smrgtypedef struct {
585dfecf96Smrg    Arg *args;
595dfecf96Smrg    Cardinal num_args;
605dfecf96Smrg} Resources;
615dfecf96Smrg
625dfecf96Smrgtypedef struct {
635dfecf96Smrg    LispObj *data;
645dfecf96Smrg    /* data is => (list* widget callback argument) */
655dfecf96Smrg} CallbackArgs;
665dfecf96Smrg
675dfecf96Smrg/*
685dfecf96Smrg * Prototypes
695dfecf96Smrg */
705dfecf96Smrgint xtLoadModule(void);
715dfecf96Smrgvoid LispXtCleanupCallback(Widget, XtPointer, XtPointer);
725dfecf96Smrg
735dfecf96Smrgvoid LispXtCallback(Widget, XtPointer, XtPointer);
745dfecf96Smrgvoid LispXtInputCallback(XtPointer, int*, XtInputId*);
755dfecf96Smrg
765dfecf96Smrg/* a hack... */
775dfecf96SmrgLispObj *Lisp_XtCoerceToWidgetList(LispBuiltin*);
785dfecf96Smrg
795dfecf96SmrgLispObj *Lisp_XtAddCallback(LispBuiltin*);
805dfecf96SmrgLispObj *Lisp_XtAppInitialize(LispBuiltin*);
815dfecf96SmrgLispObj *Lisp_XtAppMainLoop(LispBuiltin*);
825dfecf96SmrgLispObj *Lisp_XtAppAddInput(LispBuiltin*);
835dfecf96SmrgLispObj *Lisp_XtAppPending(LispBuiltin*);
845dfecf96SmrgLispObj *Lisp_XtAppProcessEvent(LispBuiltin*);
855dfecf96SmrgLispObj *Lisp_XtCreateWidget(LispBuiltin*);
865dfecf96SmrgLispObj *Lisp_XtCreateManagedWidget(LispBuiltin*);
875dfecf96SmrgLispObj *Lisp_XtCreatePopupShell(LispBuiltin*);
885dfecf96SmrgLispObj *Lisp_XtDestroyWidget(LispBuiltin*);
895dfecf96SmrgLispObj *Lisp_XtGetKeyboardFocusWidget(LispBuiltin*);
905dfecf96SmrgLispObj *Lisp_XtGetValues(LispBuiltin*);
915dfecf96SmrgLispObj *Lisp_XtManageChild(LispBuiltin*);
925dfecf96SmrgLispObj *Lisp_XtUnmanageChild(LispBuiltin*);
935dfecf96SmrgLispObj *Lisp_XtSetMappedWhenManaged(LispBuiltin*);
945dfecf96SmrgLispObj *Lisp_XtMapWidget(LispBuiltin*);
955dfecf96SmrgLispObj *Lisp_XtName(LispBuiltin*);
965dfecf96SmrgLispObj *Lisp_XtParent(LispBuiltin*);
975dfecf96SmrgLispObj *Lisp_XtUnmapWidget(LispBuiltin*);
985dfecf96SmrgLispObj *Lisp_XtPopup(LispBuiltin*);
995dfecf96SmrgLispObj *Lisp_XtPopdown(LispBuiltin*);
1005dfecf96SmrgLispObj *Lisp_XtIsRealized(LispBuiltin*);
1015dfecf96SmrgLispObj *Lisp_XtRealizeWidget(LispBuiltin*);
1025dfecf96SmrgLispObj *Lisp_XtUnrealizeWidget(LispBuiltin*);
1035dfecf96SmrgLispObj *Lisp_XtRemoveInput(LispBuiltin*);
1045dfecf96SmrgLispObj *Lisp_XtSetSensitive(LispBuiltin*);
1055dfecf96SmrgLispObj *Lisp_XtSetValues(LispBuiltin*);
1065dfecf96SmrgLispObj *Lisp_XtWidgetToApplicationContext(LispBuiltin*);
1075dfecf96SmrgLispObj *Lisp_XtDisplay(LispBuiltin*);
1085dfecf96SmrgLispObj *Lisp_XtDisplayOfObject(LispBuiltin*);
1095dfecf96SmrgLispObj *Lisp_XtScreen(LispBuiltin*);
1105dfecf96SmrgLispObj *Lisp_XtScreenOfObject(LispBuiltin*);
1115dfecf96SmrgLispObj *Lisp_XtSetKeyboardFocus(LispBuiltin*);
1125dfecf96SmrgLispObj *Lisp_XtWindow(LispBuiltin*);
1135dfecf96SmrgLispObj *Lisp_XtWindowOfObject(LispBuiltin*);
1145dfecf96SmrgLispObj *Lisp_XtAddGrab(LispBuiltin*);
1155dfecf96SmrgLispObj *Lisp_XtRemoveGrab(LispBuiltin*);
1165dfecf96SmrgLispObj *Lisp_XtAppGetExitFlag(LispBuiltin*);
1175dfecf96SmrgLispObj *Lisp_XtAppSetExitFlag(LispBuiltin*);
1185dfecf96Smrg
1195dfecf96SmrgLispObj *LispXtCreateWidget(LispBuiltin*, int);
1205dfecf96Smrg
1215dfecf96Smrgstatic Resources *LispConvertResources(LispObj*, Widget,
1225dfecf96Smrg				       ResourceList*, ResourceList*);
1235dfecf96Smrgstatic void LispFreeResources(Resources*);
1245dfecf96Smrg
1255dfecf96Smrgstatic int bcmp_action_resource(_Xconst void*, _Xconst void*);
1265dfecf96Smrgstatic ResourceInfo *GetResourceInfo(char*, ResourceList*, ResourceList*);
1275dfecf96Smrgstatic ResourceList *GetResourceList(WidgetClass);
1285dfecf96Smrgstatic int bcmp_action_resource_list(_Xconst void*, _Xconst void*);
1295dfecf96Smrgstatic ResourceList *FindResourceList(WidgetClass);
1305dfecf96Smrgstatic int qcmp_action_resource_list(_Xconst void*, _Xconst void*);
1315dfecf96Smrgstatic ResourceList *CreateResourceList(WidgetClass);
1325dfecf96Smrgstatic int qcmp_action_resource(_Xconst void*, _Xconst void*);
1335dfecf96Smrgstatic void BindResourceList(ResourceList*);
1345dfecf96Smrg
1355dfecf96Smrgstatic void PopdownAction(Widget, XEvent*, String*, Cardinal*);
1365dfecf96Smrgstatic void QuitAction(Widget, XEvent*, String*, Cardinal*);
1375dfecf96Smrg
1385dfecf96Smrg/*
1395dfecf96Smrg * Initialization
1405dfecf96Smrg */
1415dfecf96Smrgstatic LispBuiltin lispbuiltins[] = {
1425dfecf96Smrg    {LispFunction, Lisp_XtCoerceToWidgetList, "xt-coerce-to-widget-list number opaque"},
1435dfecf96Smrg
1445dfecf96Smrg    {LispFunction, Lisp_XtAddGrab, "xt-add-grab widget exclusive spring-loaded"},
1455dfecf96Smrg    {LispFunction, Lisp_XtAddCallback, "xt-add-callback widget callback-name callback &optional client-data"},
1465dfecf96Smrg    {LispFunction, Lisp_XtAppAddInput, "xt-app-add-input app-context fileno condition function &optional client-data"},
1475dfecf96Smrg    {LispFunction, Lisp_XtAppInitialize, "xt-app-initialize app-context-return application-class &optional options fallback-resources"},
1485dfecf96Smrg    {LispFunction, Lisp_XtAppPending, "xt-app-pending app-context"},
1495dfecf96Smrg    {LispFunction, Lisp_XtAppMainLoop, "xt-app-main-loop app-context"},
1505dfecf96Smrg    {LispFunction, Lisp_XtAppProcessEvent, "xt-app-process-event app-context &optional mask"},
1515dfecf96Smrg    {LispFunction, Lisp_XtAppGetExitFlag, "xt-app-get-exit-flag app-context"},
1525dfecf96Smrg    {LispFunction, Lisp_XtAppSetExitFlag, "xt-app-set-exit-flag app-context"},
1535dfecf96Smrg    {LispFunction, Lisp_XtCreateManagedWidget, "xt-create-managed-widget name widget-class parent &optional arguments"},
1545dfecf96Smrg    {LispFunction, Lisp_XtCreateWidget, "xt-create-widget name widget-class parent &optional arguments"},
1555dfecf96Smrg    {LispFunction, Lisp_XtCreatePopupShell, "xt-create-popup-shell name widget-class parent &optional arguments"},
1565dfecf96Smrg    {LispFunction, Lisp_XtDestroyWidget, "xt-destroy-widget widget"},
1575dfecf96Smrg    {LispFunction, Lisp_XtGetKeyboardFocusWidget, "xt-get-keyboard-focus-widget widget"},
1585dfecf96Smrg    {LispFunction, Lisp_XtGetValues, "xt-get-values widget arguments"},
1595dfecf96Smrg    {LispFunction, Lisp_XtManageChild, "xt-manage-child widget"},
1605dfecf96Smrg    {LispFunction, Lisp_XtName, "xt-name widget"},
1615dfecf96Smrg    {LispFunction, Lisp_XtUnmanageChild, "xt-unmanage-child widget"},
1625dfecf96Smrg    {LispFunction, Lisp_XtMapWidget, "xt-map-widget widget"},
1635dfecf96Smrg    {LispFunction, Lisp_XtUnmapWidget, "xt-unmap-widget widget"},
1645dfecf96Smrg    {LispFunction, Lisp_XtSetMappedWhenManaged, "xt-set-mapped-when-managed widget map-when-managed"},
1655dfecf96Smrg    {LispFunction, Lisp_XtParent, "xt-parent widget"},
1665dfecf96Smrg    {LispFunction, Lisp_XtPopup, "xt-popup widget grab-kind"},
1675dfecf96Smrg    {LispFunction, Lisp_XtPopdown, "xt-popdown widget"},
1685dfecf96Smrg    {LispFunction, Lisp_XtIsRealized, "xt-is-realized widget"},
1695dfecf96Smrg    {LispFunction, Lisp_XtRealizeWidget, "xt-realize-widget widget"},
1705dfecf96Smrg    {LispFunction, Lisp_XtUnrealizeWidget, "xt-unrealize-widget widget"},
1715dfecf96Smrg    {LispFunction, Lisp_XtRemoveInput, "xt-remove-input input"},
1725dfecf96Smrg    {LispFunction, Lisp_XtRemoveGrab, "xt-remove-grab widget"},
1735dfecf96Smrg    {LispFunction, Lisp_XtSetKeyboardFocus, "xt-set-keyboard-focus widget descendant"},
1745dfecf96Smrg    {LispFunction, Lisp_XtSetSensitive, "xt-set-sensitive widget sensitive"},
1755dfecf96Smrg    {LispFunction, Lisp_XtSetValues, "xt-set-values widget arguments"},
1765dfecf96Smrg    {LispFunction, Lisp_XtWidgetToApplicationContext, "xt-widget-to-application-context widget"},
1775dfecf96Smrg    {LispFunction, Lisp_XtDisplay, "xt-display widget"},
1785dfecf96Smrg    {LispFunction, Lisp_XtDisplayOfObject, "xt-display-of-object object"},
1795dfecf96Smrg    {LispFunction, Lisp_XtScreen, "xt-screen widget"},
1805dfecf96Smrg    {LispFunction, Lisp_XtScreenOfObject, "xt-screen-of-object object"},
1815dfecf96Smrg    {LispFunction, Lisp_XtWindow, "xt-window widget"},
1825dfecf96Smrg    {LispFunction, Lisp_XtWindowOfObject, "xt-window-of-object object"},
1835dfecf96Smrg};
1845dfecf96Smrg
1855dfecf96SmrgLispModuleData xtLispModuleData = {
1865dfecf96Smrg    LISP_MODULE_VERSION,
1875dfecf96Smrg    xtLoadModule,
1885dfecf96Smrg};
1895dfecf96Smrg
1905dfecf96Smrgstatic ResourceList **resource_list;
1915dfecf96Smrgstatic Cardinal num_resource_list;
1925dfecf96Smrg
1935dfecf96Smrgstatic Atom delete_window;
1945dfecf96Smrgstatic int xtAppContext_t, xtWidget_t, xtWidgetClass_t, xtWidgetList_t,
1955dfecf96Smrg	   xtInputId_t, xtDisplay_t, xtScreen_t, xtWindow_t;
1965dfecf96Smrg
1975dfecf96Smrgstatic XtActionsRec actions[] = {
1985dfecf96Smrg    {"xt-popdown",	PopdownAction},
1995dfecf96Smrg    {"xt-quit",		QuitAction},
2005dfecf96Smrg};
2015dfecf96Smrg
2025dfecf96Smrgstatic XrmQuark qCardinal, qInt, qString, qWidget, qFloat;
2035dfecf96Smrg
2045dfecf96Smrgstatic CallbackArgs **input_list;
2055dfecf96Smrgstatic Cardinal num_input_list, size_input_list;
2065dfecf96Smrg
2075dfecf96Smrg/*
2085dfecf96Smrg * Implementation
2095dfecf96Smrg */
2105dfecf96Smrgint
2115dfecf96SmrgxtLoadModule(void)
2125dfecf96Smrg{
2135dfecf96Smrg    int i;
2145dfecf96Smrg    char *fname = "XT-LOAD-MODULE";
2155dfecf96Smrg
2165dfecf96Smrg    xtAppContext_t = LispRegisterOpaqueType("XtAppContext");
2175dfecf96Smrg    xtWidget_t = LispRegisterOpaqueType("Widget");
2185dfecf96Smrg    xtWidgetClass_t = LispRegisterOpaqueType("WidgetClass");
2195dfecf96Smrg    xtWidgetList_t = LispRegisterOpaqueType("WidgetList");
2205dfecf96Smrg    xtInputId_t = LispRegisterOpaqueType("XtInputId");
2215dfecf96Smrg    xtDisplay_t = LispRegisterOpaqueType("Display*");
2225dfecf96Smrg    xtScreen_t = LispRegisterOpaqueType("Screen*");
2235dfecf96Smrg    xtWindow_t = LispRegisterOpaqueType("Window");
2245dfecf96Smrg
2255dfecf96Smrg    LispExecute("(DEFSTRUCT XT-WIDGET-LIST NUM-CHILDREN CHILDREN)\n");
2265dfecf96Smrg
2275dfecf96Smrg    GCDisable();
2285dfecf96Smrg    (void)LispSetVariable(ATOM2("CORE-WIDGET-CLASS"),
2295dfecf96Smrg			  OPAQUE(coreWidgetClass, xtWidgetClass_t),
2305dfecf96Smrg			  fname, 0);
2315dfecf96Smrg    (void)LispSetVariable(ATOM2("COMPOSITE-WIDGET-CLASS"),
2325dfecf96Smrg			  OPAQUE(compositeWidgetClass, xtWidgetClass_t),
2335dfecf96Smrg			  fname, 0);
2345dfecf96Smrg    (void)LispSetVariable(ATOM2("CONSTRAINT-WIDGET-CLASS"),
2355dfecf96Smrg			  OPAQUE(constraintWidgetClass, xtWidgetClass_t),
2365dfecf96Smrg			  fname, 0);
2375dfecf96Smrg    (void)LispSetVariable(ATOM2("TRANSIENT-SHELL-WIDGET-CLASS"),
2385dfecf96Smrg			  OPAQUE(transientShellWidgetClass, xtWidgetClass_t),
2395dfecf96Smrg			  fname, 0);
2405dfecf96Smrg
2415dfecf96Smrg    /* parameters for XtPopup */
2425dfecf96Smrg    (void)LispSetVariable(ATOM2("XT-GRAB-EXCLUSIVE"),
2435dfecf96Smrg			  INTEGER(XtGrabExclusive), fname, 0);
2445dfecf96Smrg    (void)LispSetVariable(ATOM2("XT-GRAB-NONE"),
2455dfecf96Smrg			  INTEGER(XtGrabNone), fname, 0);
2465dfecf96Smrg    (void)LispSetVariable(ATOM2("XT-GRAB-NONE-EXCLUSIVE"),
2475dfecf96Smrg			  INTEGER(XtGrabNonexclusive), fname, 0);
2485dfecf96Smrg
2495dfecf96Smrg    /* parameters for XtAppProcessEvent */
2505dfecf96Smrg    (void)LispSetVariable(ATOM2("XT-IM-XEVENT"),
2515dfecf96Smrg			  INTEGER(XtIMXEvent), fname, 0);
2525dfecf96Smrg    (void)LispSetVariable(ATOM2("XT-IM-TIMER"),
2535dfecf96Smrg			  INTEGER(XtIMTimer), fname, 0);
2545dfecf96Smrg    (void)LispSetVariable(ATOM2("XT-IM-ALTERNATE-INPUT"),
2555dfecf96Smrg			  INTEGER(XtIMAlternateInput), fname, 0);
2565dfecf96Smrg    (void)LispSetVariable(ATOM2("XT-IM-SIGNAL"),
2575dfecf96Smrg			  INTEGER(XtIMSignal), fname, 0);
2585dfecf96Smrg    (void)LispSetVariable(ATOM2("XT-IM-ALL"),
2595dfecf96Smrg			  INTEGER(XtIMAll), fname, 0);
2605dfecf96Smrg
2615dfecf96Smrg    /* parameters for XtAppAddInput */
2625dfecf96Smrg    (void)LispSetVariable(ATOM2("XT-INPUT-READ-MASK"),
2635dfecf96Smrg			  INTEGER(XtInputReadMask), fname, 0);
2645dfecf96Smrg    (void)LispSetVariable(ATOM2("XT-INPUT-WRITE-MASK"),
2655dfecf96Smrg			  INTEGER(XtInputWriteMask), fname, 0);
2665dfecf96Smrg    (void)LispSetVariable(ATOM2("XT-INPUT-EXCEPT-MASK"),
2675dfecf96Smrg			  INTEGER(XtInputExceptMask), fname, 0);
2685dfecf96Smrg    GCEnable();
2695dfecf96Smrg
2705dfecf96Smrg    qCardinal = XrmPermStringToQuark(XtRCardinal);
2715dfecf96Smrg    qInt = XrmPermStringToQuark(XtRInt);
2725dfecf96Smrg    qString = XrmPermStringToQuark(XtRString);
2735dfecf96Smrg    qWidget = XrmPermStringToQuark(XtRWidget);
2745dfecf96Smrg    qFloat = XrmPermStringToQuark(XtRFloat);
2755dfecf96Smrg
2765dfecf96Smrg    for (i = 0; i < sizeof(lispbuiltins) / sizeof(lispbuiltins[0]); i++)
2775dfecf96Smrg	LispAddBuiltinFunction(&lispbuiltins[i]);
2785dfecf96Smrg
2795dfecf96Smrg    return (1);
2805dfecf96Smrg}
2815dfecf96Smrg
2825dfecf96Smrgvoid
2835dfecf96SmrgLispXtCallback(Widget w, XtPointer user_data, XtPointer call_data)
2845dfecf96Smrg{
2855dfecf96Smrg    CallbackArgs *args = (CallbackArgs*)user_data;
2865dfecf96Smrg    LispObj *code, *ocod = COD;
2875dfecf96Smrg
2885dfecf96Smrg    GCDisable();
2895dfecf96Smrg		/* callback name */	   /* reall caller */
2905dfecf96Smrg    code = CONS(CDR(CDR(args->data)), CONS(OPAQUE(w, xtWidget_t),
2915dfecf96Smrg		CONS(CAR(CDR(args->data)), CONS(OPAQUE(call_data, 0), NIL))));
2925dfecf96Smrg		     /* user arguments */
2935dfecf96Smrg    COD = CONS(code, COD);
2945dfecf96Smrg    GCEnable();
2955dfecf96Smrg
2965dfecf96Smrg    (void)EVAL(code);
2975dfecf96Smrg    COD = ocod;
2985dfecf96Smrg}
2995dfecf96Smrg
3005dfecf96Smrg
3015dfecf96Smrgvoid
3025dfecf96SmrgLispXtCleanupCallback(Widget w, XtPointer user_data, XtPointer call_data)
3035dfecf96Smrg{
3045dfecf96Smrg    CallbackArgs *args = (CallbackArgs*)user_data;
3055dfecf96Smrg
3065dfecf96Smrg    UPROTECT(CAR(args->data), args->data);
3075dfecf96Smrg    XtFree((XtPointer)args);
3085dfecf96Smrg}
3095dfecf96Smrg
3105dfecf96Smrgvoid
3115dfecf96SmrgLispXtInputCallback(XtPointer closure, int *source, XtInputId *id)
3125dfecf96Smrg{
3135dfecf96Smrg    CallbackArgs *args = (CallbackArgs*)closure;
3145dfecf96Smrg    LispObj *code, *ocod = COD;
3155dfecf96Smrg
3165dfecf96Smrg    GCDisable();
3175dfecf96Smrg		/* callback name */	  /* user arguments */
3185dfecf96Smrg    code = CONS(CDR(CDR(args->data)), CONS(CAR(CDR(args->data)),
3195dfecf96Smrg		CONS(INTEGER(*source), CONS(CAR(args->data), NIL))));
3205dfecf96Smrg		     /* input source */	   /* input id */
3215dfecf96Smrg    COD = CONS(code, COD);
3225dfecf96Smrg    GCEnable();
3235dfecf96Smrg
3245dfecf96Smrg    (void)EVAL(code);
3255dfecf96Smrg    COD = ocod;
3265dfecf96Smrg}
3275dfecf96Smrg
3285dfecf96SmrgLispObj *
3295dfecf96SmrgLisp_XtCoerceToWidgetList(LispBuiltin *builtin)
3305dfecf96Smrg/*
3315dfecf96Smrg xt-coerce-to-widget-list number opaque
3325dfecf96Smrg */
3335dfecf96Smrg{
3345dfecf96Smrg    int i;
3355dfecf96Smrg    WidgetList children;
3365dfecf96Smrg    Cardinal num_children;
3375dfecf96Smrg    LispObj *cons, *widget_list, *result;
3385dfecf96Smrg
3395dfecf96Smrg    LispObj *onumber, *opaque;
3405dfecf96Smrg
3415dfecf96Smrg    opaque = ARGUMENT(1);
3425dfecf96Smrg    onumber = ARGUMENT(0);
3435dfecf96Smrg
3445dfecf96Smrg    CHECK_INDEX(onumber);
3455dfecf96Smrg    num_children = FIXNUM_VALUE(onumber);
3465dfecf96Smrg
3475dfecf96Smrg    if (!CHECKO(opaque, xtWidgetList_t))
3485dfecf96Smrg	LispDestroy("%s: cannot convert %s to WidgetList",
3495dfecf96Smrg		    STRFUN(builtin), STROBJ(opaque));
3505dfecf96Smrg    children = (WidgetList)(opaque->data.opaque.data);
3515dfecf96Smrg
3525dfecf96Smrg    GCDisable();
3535dfecf96Smrg    widget_list = cons = NIL;
3545dfecf96Smrg    for (i = 0; i < num_children; i++) {
3555dfecf96Smrg	result = CONS(OPAQUE(children[i], xtWidget_t), NIL);
3565dfecf96Smrg	if (widget_list == NIL)
3575dfecf96Smrg	    widget_list = cons = result;
3585dfecf96Smrg	else {
3595dfecf96Smrg	    RPLACD(cons, result);
3605dfecf96Smrg	    cons = CDR(cons);
3615dfecf96Smrg	}
3625dfecf96Smrg    }
3635dfecf96Smrg
3645dfecf96Smrg    result = APPLY(ATOM("MAKE-XT-WIDGET-LIST"),
3655dfecf96Smrg		   CONS(KEYWORD("NUM-CHILDREN"),
3665dfecf96Smrg			CONS(INTEGER(num_children),
3675dfecf96Smrg			     CONS(KEYWORD("CHILDREN"),
3685dfecf96Smrg				  CONS(widget_list, NIL)))));
3695dfecf96Smrg    GCEnable();
3705dfecf96Smrg
3715dfecf96Smrg    return (result);
3725dfecf96Smrg}
3735dfecf96Smrg
3745dfecf96SmrgLispObj *
3755dfecf96SmrgLisp_XtAddCallback(LispBuiltin *builtin)
3765dfecf96Smrg/*
3775dfecf96Smrg xt-add-callback widget callback-name callback &optional client-data
3785dfecf96Smrg */
3795dfecf96Smrg{
3805dfecf96Smrg    CallbackArgs *arguments;
3815dfecf96Smrg    LispObj *data;
3825dfecf96Smrg
3835dfecf96Smrg    LispObj *widget, *callback_name, *callback, *client_data;
3845dfecf96Smrg
3855dfecf96Smrg    client_data = ARGUMENT(3);
3865dfecf96Smrg    callback = ARGUMENT(2);
3875dfecf96Smrg    callback_name = ARGUMENT(1);
3885dfecf96Smrg    widget = ARGUMENT(0);
3895dfecf96Smrg
3905dfecf96Smrg    if (!CHECKO(widget, xtWidget_t))
3915dfecf96Smrg	LispDestroy("%s: cannot convert %s to Widget",
3925dfecf96Smrg		    STRFUN(builtin), STROBJ(widget));
3935dfecf96Smrg
3945dfecf96Smrg    CHECK_STRING(callback_name);
3955dfecf96Smrg    if (!SYMBOLP(callback) && callback->type != LispLambda_t)
3965dfecf96Smrg	LispDestroy("%s: %s cannot be used as a callback",
3975dfecf96Smrg		    STRFUN(builtin), STROBJ(callback));
3985dfecf96Smrg
3995dfecf96Smrg    if (client_data == UNSPEC)
4005dfecf96Smrg	client_data = NIL;
4015dfecf96Smrg
4025dfecf96Smrg    data = CONS(widget, CONS(client_data, callback));
4035dfecf96Smrg    PROTECT(widget, data);
4045dfecf96Smrg
4055dfecf96Smrg    arguments = XtNew(CallbackArgs);
4065dfecf96Smrg    arguments->data = data;
4075dfecf96Smrg
4085dfecf96Smrg    XtAddCallback((Widget)(widget->data.opaque.data), THESTR(callback_name),
4095dfecf96Smrg		  LispXtCallback, (XtPointer)arguments);
4105dfecf96Smrg    XtAddCallback((Widget)(widget->data.opaque.data), XtNdestroyCallback,
4115dfecf96Smrg		  LispXtCleanupCallback, (XtPointer)arguments);
4125dfecf96Smrg
4135dfecf96Smrg    return (client_data);
4145dfecf96Smrg}
4155dfecf96Smrg
4165dfecf96SmrgLispObj *
4175dfecf96SmrgLisp_XtAppAddInput(LispBuiltin *builtin)
4185dfecf96Smrg/*
4195dfecf96Smrg  xt-app-add-input app-context fileno condition function &optional client-data
4205dfecf96Smrg */
4215dfecf96Smrg{
4225dfecf96Smrg    LispObj *data, *input;
4235dfecf96Smrg    XtAppContext appcon;
4245dfecf96Smrg    int source, condition;
4255dfecf96Smrg    CallbackArgs *arguments;
4265dfecf96Smrg    XtInputId id;
4275dfecf96Smrg
4285dfecf96Smrg    LispObj *app_context, *fileno, *ocondition, *function, *client_data;
4295dfecf96Smrg
4305dfecf96Smrg    client_data = ARGUMENT(4);
4315dfecf96Smrg    function = ARGUMENT(3);
4325dfecf96Smrg    ocondition = ARGUMENT(2);
4335dfecf96Smrg    fileno = ARGUMENT(1);
4345dfecf96Smrg    app_context = ARGUMENT(0);
4355dfecf96Smrg
4365dfecf96Smrg    if (!CHECKO(app_context, xtAppContext_t))
4375dfecf96Smrg	LispDestroy("%s: cannot convert %s to XtAppContext",
4385dfecf96Smrg		    STRFUN(builtin), STROBJ(app_context));
4395dfecf96Smrg    appcon = (XtAppContext)(app_context->data.opaque.data);
4405dfecf96Smrg
4415dfecf96Smrg    CHECK_LONGINT(fileno);
4425dfecf96Smrg    source = LONGINT_VALUE(fileno);
4435dfecf96Smrg
4445dfecf96Smrg    CHECK_FIXNUM(ocondition);
4455dfecf96Smrg    condition = FIXNUM_VALUE(ocondition);
4465dfecf96Smrg
4475dfecf96Smrg    if (!SYMBOLP(function) && function->type != LispLambda_t)
4485dfecf96Smrg	LispDestroy("%s: %s cannot be used as a callback",
4495dfecf96Smrg		    STRFUN(builtin), STROBJ(function));
4505dfecf96Smrg
4515dfecf96Smrg    /* client data optional */
4525dfecf96Smrg    if (client_data == UNSPEC)
4535dfecf96Smrg	client_data = NIL;
4545dfecf96Smrg
4555dfecf96Smrg    data = CONS(NIL, CONS(client_data, function));
4565dfecf96Smrg
4575dfecf96Smrg    arguments = XtNew(CallbackArgs);
4585dfecf96Smrg    arguments->data = data;
4595dfecf96Smrg
4605dfecf96Smrg    id = XtAppAddInput(appcon, source, (XtPointer)condition,
4615dfecf96Smrg		       LispXtInputCallback, (XtPointer)arguments);
4625dfecf96Smrg    GCDisable();
4635dfecf96Smrg    input = OPAQUE(id, xtInputId_t);
4645dfecf96Smrg    GCEnable();
4655dfecf96Smrg    RPLACA(data, input);
4665dfecf96Smrg    PROTECT(input, data);
4675dfecf96Smrg
4685dfecf96Smrg    if (num_input_list + 1 >= size_input_list) {
4695dfecf96Smrg	++size_input_list;
4705dfecf96Smrg	input_list = (CallbackArgs**)
4715dfecf96Smrg	    XtRealloc((XtPointer)input_list,
4725dfecf96Smrg		      sizeof(CallbackArgs*) * size_input_list);
4735dfecf96Smrg    }
4745dfecf96Smrg    input_list[num_input_list++] = arguments;
4755dfecf96Smrg
4765dfecf96Smrg    return (input);
4775dfecf96Smrg}
4785dfecf96Smrg
4795dfecf96SmrgLispObj *
4805dfecf96SmrgLisp_XtRemoveInput(LispBuiltin *builtin)
4815dfecf96Smrg/*
4825dfecf96Smrg xt-remove-input input
4835dfecf96Smrg */
4845dfecf96Smrg{
4855dfecf96Smrg    int i;
4865dfecf96Smrg    XtInputId id;
4875dfecf96Smrg    CallbackArgs *args;
4885dfecf96Smrg
4895dfecf96Smrg    LispObj *input;
4905dfecf96Smrg
4915dfecf96Smrg    input = ARGUMENT(0);
4925dfecf96Smrg
4935dfecf96Smrg    if (!CHECKO(input, xtInputId_t))
4945dfecf96Smrg	LispDestroy("%s: cannot convert %s to XtInputId",
4955dfecf96Smrg		    STRFUN(builtin), STROBJ(input));
4965dfecf96Smrg
4975dfecf96Smrg    id = (XtInputId)(input->data.opaque.data);
4985dfecf96Smrg    for (i = 0; i < num_input_list; i++) {
4995dfecf96Smrg	args = input_list[i];
5005dfecf96Smrg	if (id == (XtInputId)(CAR(args->data)->data.opaque.data)) {
5015dfecf96Smrg	    UPROTECT(CAR(args->data), args->data);
5025dfecf96Smrg	    XtFree((XtPointer)args);
5035dfecf96Smrg
5045dfecf96Smrg	    if (i + 1 < num_input_list)
5055dfecf96Smrg		memmove(input_list + i, input_list + i + 1,
5065dfecf96Smrg			sizeof(CallbackArgs*) * (num_input_list - i - 1));
5075dfecf96Smrg	    --num_input_list;
5085dfecf96Smrg
5095dfecf96Smrg	    XtRemoveInput(id);
5105dfecf96Smrg
5115dfecf96Smrg	    return (T);
5125dfecf96Smrg	}
5135dfecf96Smrg    }
5145dfecf96Smrg
5155dfecf96Smrg    return (NIL);
5165dfecf96Smrg}
5175dfecf96Smrg
5185dfecf96SmrgLispObj *
5195dfecf96SmrgLisp_XtAppInitialize(LispBuiltin *builtin)
5205dfecf96Smrg/*
5215dfecf96Smrg xt-app-initialize app-context-return application-class &optional options fallback-resources
5225dfecf96Smrg */
5235dfecf96Smrg{
5245dfecf96Smrg    XtAppContext appcon;
5255dfecf96Smrg    Widget shell;
5265dfecf96Smrg    int zero = 0;
5275dfecf96Smrg    Resources *resources = NULL;
5285dfecf96Smrg    String *fallback = NULL;
5295dfecf96Smrg
5305dfecf96Smrg    LispObj *app_context_return, *application_class,
5315dfecf96Smrg	    *options, *fallback_resources;
5325dfecf96Smrg
5335dfecf96Smrg    fallback_resources = ARGUMENT(3);
5345dfecf96Smrg    options = ARGUMENT(2);
5355dfecf96Smrg    application_class = ARGUMENT(1);
5365dfecf96Smrg    app_context_return = ARGUMENT(0);
5375dfecf96Smrg
5385dfecf96Smrg    CHECK_SYMBOL(app_context_return);
5395dfecf96Smrg    CHECK_STRING(application_class);
5405dfecf96Smrg    CHECK_LIST(options);
5415dfecf96Smrg
5425dfecf96Smrg    /* check fallback resources, if given */
5435dfecf96Smrg    if (fallback_resources != UNSPEC) {
5445dfecf96Smrg	LispObj *string;
5455dfecf96Smrg	int count;
5465dfecf96Smrg
5475dfecf96Smrg	CHECK_CONS(fallback_resources);
5485dfecf96Smrg	for (string = fallback_resources, count = 0; CONSP(string);
5495dfecf96Smrg	     string = CDR(string), count++)
5505dfecf96Smrg	    CHECK_STRING(CAR(string));
5515dfecf96Smrg
5525dfecf96Smrg	/* fallback resources was correctly specified */
5535dfecf96Smrg	fallback = LispMalloc(sizeof(String) * (count + 1));
5545dfecf96Smrg	for (string = fallback_resources, count = 0; CONSP(string);
5555dfecf96Smrg	     string = CDR(string), count++)
5565dfecf96Smrg	    fallback[count] = THESTR(CAR(string));
5575dfecf96Smrg	fallback[count] = NULL;
5585dfecf96Smrg    }
5595dfecf96Smrg
5605dfecf96Smrg    shell = XtAppInitialize(&appcon, THESTR(application_class), NULL,
5615dfecf96Smrg			    0, &zero, NULL, fallback, NULL, 0);
5625dfecf96Smrg    if (fallback)
5635dfecf96Smrg	LispFree(fallback);
5645dfecf96Smrg    (void)LispSetVariable(app_context_return,
5655dfecf96Smrg			  OPAQUE(appcon, xtAppContext_t),
5665dfecf96Smrg			  STRFUN(builtin), 0);
5675dfecf96Smrg
5685dfecf96Smrg    XtAppAddActions(appcon, actions, XtNumber(actions));
5695dfecf96Smrg
5705dfecf96Smrg    if (options != UNSPEC) {
5715dfecf96Smrg	resources = LispConvertResources(options, shell,
5725dfecf96Smrg					 GetResourceList(XtClass(shell)),
5735dfecf96Smrg					 NULL);
5745dfecf96Smrg	if (resources) {
5755dfecf96Smrg	    XtSetValues(shell, resources->args, resources->num_args);
5765dfecf96Smrg	    LispFreeResources(resources);
5775dfecf96Smrg	}
5785dfecf96Smrg    }
5795dfecf96Smrg
5805dfecf96Smrg    return (OPAQUE(shell, xtWidget_t));
5815dfecf96Smrg}
5825dfecf96Smrg
5835dfecf96SmrgLispObj *
5845dfecf96SmrgLisp_XtAppMainLoop(LispBuiltin *builtin)
5855dfecf96Smrg/*
5865dfecf96Smrg xt-app-main-loop app-context
5875dfecf96Smrg */
5885dfecf96Smrg{
5895dfecf96Smrg    LispObj *app_context;
5905dfecf96Smrg
5915dfecf96Smrg    app_context = ARGUMENT(0);
5925dfecf96Smrg
5935dfecf96Smrg    if (!CHECKO(app_context, xtAppContext_t))
5945dfecf96Smrg	LispDestroy("%s: cannot convert %s to XtAppContext",
5955dfecf96Smrg		    STRFUN(builtin), STROBJ(app_context));
5965dfecf96Smrg
5975dfecf96Smrg    XtAppMainLoop((XtAppContext)(app_context->data.opaque.data));
5985dfecf96Smrg
5995dfecf96Smrg    return (NIL);
6005dfecf96Smrg}
6015dfecf96Smrg
6025dfecf96SmrgLispObj *
6035dfecf96SmrgLisp_XtAppPending(LispBuiltin *builtin)
6045dfecf96Smrg/*
6055dfecf96Smrg xt-app-pending app-context
6065dfecf96Smrg */
6075dfecf96Smrg{
6085dfecf96Smrg    LispObj *app_context;
6095dfecf96Smrg
6105dfecf96Smrg    app_context = ARGUMENT(0);
6115dfecf96Smrg
6125dfecf96Smrg    if (!CHECKO(app_context, xtAppContext_t))
6135dfecf96Smrg	LispDestroy("%s: cannot convert %s to XtAppContext",
6145dfecf96Smrg		    STRFUN(builtin), STROBJ(app_context));
6155dfecf96Smrg
6165dfecf96Smrg    return (INTEGER(
6175dfecf96Smrg	    XtAppPending((XtAppContext)(app_context->data.opaque.data))));
6185dfecf96Smrg}
6195dfecf96Smrg
6205dfecf96SmrgLispObj *
6215dfecf96SmrgLisp_XtAppProcessEvent(LispBuiltin *builtin)
6225dfecf96Smrg/*
6235dfecf96Smrg xt-app-process-event app-context &optional mask
6245dfecf96Smrg */
6255dfecf96Smrg{
6265dfecf96Smrg    XtInputMask mask;
6275dfecf96Smrg    XtAppContext appcon;
6285dfecf96Smrg
6295dfecf96Smrg    LispObj *app_context, *omask;
6305dfecf96Smrg
6315dfecf96Smrg    omask = ARGUMENT(1);
6325dfecf96Smrg    app_context = ARGUMENT(0);
6335dfecf96Smrg
6345dfecf96Smrg    if (!CHECKO(app_context, xtAppContext_t))
6355dfecf96Smrg	LispDestroy("%s: cannot convert %s to XtAppContext",
6365dfecf96Smrg		    STRFUN(builtin), STROBJ(app_context));
6375dfecf96Smrg
6385dfecf96Smrg    appcon = (XtAppContext)(app_context->data.opaque.data);
6395dfecf96Smrg    if (omask == UNSPEC)
6405dfecf96Smrg	mask = XtIMAll;
6415dfecf96Smrg    else {
6425dfecf96Smrg	CHECK_FIXNUM(omask);
6435dfecf96Smrg	mask = FIXNUM_VALUE(omask);
6445dfecf96Smrg    }
6455dfecf96Smrg
6465dfecf96Smrg    if (mask != (mask & XtIMAll))
6475dfecf96Smrg	LispDestroy("%s: %ld does not fit in XtInputMask %ld",
6485dfecf96Smrg		    STRFUN(builtin), (long)mask, (long)XtIMAll);
6495dfecf96Smrg
6505dfecf96Smrg    if (mask)
6515dfecf96Smrg	XtAppProcessEvent(appcon, mask);
6525dfecf96Smrg
6535dfecf96Smrg    return (omask == NIL ? FIXNUM(mask) : omask);
6545dfecf96Smrg}
6555dfecf96Smrg
6565dfecf96SmrgLispObj *
6575dfecf96SmrgLisp_XtRealizeWidget(LispBuiltin *builtin)
6585dfecf96Smrg/*
6595dfecf96Smrg xt-realize-widget widget
6605dfecf96Smrg */
6615dfecf96Smrg{
6625dfecf96Smrg    Widget widget;
6635dfecf96Smrg
6645dfecf96Smrg    LispObj *owidget;
6655dfecf96Smrg
6665dfecf96Smrg    owidget = ARGUMENT(0);
6675dfecf96Smrg
6685dfecf96Smrg    if (!CHECKO(owidget, xtWidget_t))
6695dfecf96Smrg	LispDestroy("%s: cannot convert %s to Widget",
6705dfecf96Smrg		    STRFUN(builtin), STROBJ(owidget));
6715dfecf96Smrg    widget = (Widget)(owidget->data.opaque.data);
6725dfecf96Smrg    XtRealizeWidget(widget);
6735dfecf96Smrg
6745dfecf96Smrg    if (XtIsSubclass(widget, shellWidgetClass)) {
6755dfecf96Smrg	if (!delete_window)
6765dfecf96Smrg	    delete_window = XInternAtom(XtDisplay(widget),
6775dfecf96Smrg					"WM_DELETE_WINDOW", False);
6785dfecf96Smrg	(void)XSetWMProtocols(XtDisplay(widget), XtWindow(widget),
6795dfecf96Smrg			      &delete_window, 1);
6805dfecf96Smrg    }
6815dfecf96Smrg
6825dfecf96Smrg    return (owidget);
6835dfecf96Smrg}
6845dfecf96Smrg
6855dfecf96SmrgLispObj *
6865dfecf96SmrgLisp_XtUnrealizeWidget(LispBuiltin *builtin)
6875dfecf96Smrg/*
6885dfecf96Smrg xt-unrealize-widget widget
6895dfecf96Smrg */
6905dfecf96Smrg{
6915dfecf96Smrg    LispObj *widget;
6925dfecf96Smrg
6935dfecf96Smrg    widget = ARGUMENT(0);
6945dfecf96Smrg
6955dfecf96Smrg    if (!CHECKO(widget, xtWidget_t))
6965dfecf96Smrg	LispDestroy("%s: cannot convert %s to Widget",
6975dfecf96Smrg		    STRFUN(builtin), STROBJ(widget));
6985dfecf96Smrg
6995dfecf96Smrg    XtUnrealizeWidget((Widget)(widget->data.opaque.data));
7005dfecf96Smrg
7015dfecf96Smrg    return (widget);
7025dfecf96Smrg}
7035dfecf96Smrg
7045dfecf96SmrgLispObj *
7055dfecf96SmrgLisp_XtIsRealized(LispBuiltin *builtin)
7065dfecf96Smrg/*
7075dfecf96Smrg xt-is-realized widget
7085dfecf96Smrg */
7095dfecf96Smrg{
7105dfecf96Smrg    LispObj *widget;
7115dfecf96Smrg
7125dfecf96Smrg    widget = ARGUMENT(0);
7135dfecf96Smrg
7145dfecf96Smrg    if (!CHECKO(widget, xtWidget_t))
7155dfecf96Smrg	LispDestroy("%s: cannot convert %s to Widget",
7165dfecf96Smrg		    STRFUN(builtin), STROBJ(widget));
7175dfecf96Smrg
7185dfecf96Smrg    return (XtIsRealized((Widget)(widget->data.opaque.data)) ? T : NIL);
7195dfecf96Smrg}
7205dfecf96Smrg
7215dfecf96SmrgLispObj *
7225dfecf96SmrgLisp_XtDestroyWidget(LispBuiltin *builtin)
7235dfecf96Smrg/*
7245dfecf96Smrg xt-destroy-widget widget
7255dfecf96Smrg */
7265dfecf96Smrg{
7275dfecf96Smrg    LispObj *widget;
7285dfecf96Smrg
7295dfecf96Smrg    widget = ARGUMENT(0);
7305dfecf96Smrg
7315dfecf96Smrg    if (!CHECKO(widget, xtWidget_t))
7325dfecf96Smrg	LispDestroy("%s: cannot convert %s to Widget",
7335dfecf96Smrg		    STRFUN(builtin), STROBJ(widget));
7345dfecf96Smrg
7355dfecf96Smrg    XtDestroyWidget((Widget)(widget->data.opaque.data));
7365dfecf96Smrg
7375dfecf96Smrg    return (NIL);
7385dfecf96Smrg}
7395dfecf96Smrg
7405dfecf96Smrg#define UNMANAGED	0
7415dfecf96Smrg#define MANAGED		1
7425dfecf96Smrg#define SHELL		2
7435dfecf96SmrgLispObj *
7445dfecf96SmrgLisp_XtCreateWidget(LispBuiltin *builtin)
7455dfecf96Smrg/*
7465dfecf96Smrg xt-create-widget name widget-class parent &optional arguments
7475dfecf96Smrg */
7485dfecf96Smrg{
7495dfecf96Smrg    return (LispXtCreateWidget(builtin, UNMANAGED));
7505dfecf96Smrg}
7515dfecf96Smrg
7525dfecf96SmrgLispObj *
7535dfecf96SmrgLisp_XtCreateManagedWidget(LispBuiltin *builtin)
7545dfecf96Smrg/*
7555dfecf96Smrg xt-create-managed-widget name widget-class parent &optional arguments
7565dfecf96Smrg */
7575dfecf96Smrg{
7585dfecf96Smrg    return (LispXtCreateWidget(builtin, MANAGED));
7595dfecf96Smrg}
7605dfecf96Smrg
7615dfecf96SmrgLispObj *
7625dfecf96SmrgLisp_XtCreatePopupShell(LispBuiltin *builtin)
7635dfecf96Smrg/*
7645dfecf96Smrg xt-create-popup-shell name widget-class parent &optional arguments
7655dfecf96Smrg */
7665dfecf96Smrg{
7675dfecf96Smrg    return (LispXtCreateWidget(builtin, SHELL));
7685dfecf96Smrg}
7695dfecf96Smrg
7705dfecf96SmrgLispObj *
7715dfecf96SmrgLispXtCreateWidget(LispBuiltin *builtin, int options)
7725dfecf96Smrg/*
7735dfecf96Smrg xt-create-widget name widget-class parent &optional arguments
7745dfecf96Smrg xt-create-managed-widget name widget-class parent &optional arguments
7755dfecf96Smrg xt-create-popup-shell name widget-class parent &optional arguments
7765dfecf96Smrg */
7775dfecf96Smrg{
7785dfecf96Smrg    char *name;
7795dfecf96Smrg    WidgetClass widget_class;
7805dfecf96Smrg    Widget widget, parent;
7815dfecf96Smrg    Resources *resources = NULL;
7825dfecf96Smrg
7835dfecf96Smrg    LispObj *oname, *owidget_class, *oparent, *arguments;
7845dfecf96Smrg
7855dfecf96Smrg    arguments = ARGUMENT(3);
7865dfecf96Smrg    oparent = ARGUMENT(2);
7875dfecf96Smrg    owidget_class = ARGUMENT(1);
7885dfecf96Smrg    oname = ARGUMENT(0);
7895dfecf96Smrg
7905dfecf96Smrg    CHECK_STRING(oname);
7915dfecf96Smrg    name = THESTR(oname);
7925dfecf96Smrg
7935dfecf96Smrg    if (!CHECKO(owidget_class, xtWidgetClass_t))
7945dfecf96Smrg	LispDestroy("%s: cannot convert %s to WidgetClass",
7955dfecf96Smrg		    STRFUN(builtin), STROBJ(owidget_class));
7965dfecf96Smrg    widget_class = (WidgetClass)(owidget_class->data.opaque.data);
7975dfecf96Smrg
7985dfecf96Smrg    if (!CHECKO(oparent, xtWidget_t))
7995dfecf96Smrg	LispDestroy("%s: cannot convert %s to Widget",
8005dfecf96Smrg		    STRFUN(builtin), STROBJ(oparent));
8015dfecf96Smrg    parent = (Widget)(oparent->data.opaque.data);
8025dfecf96Smrg
8035dfecf96Smrg    if (arguments == UNSPEC)
8045dfecf96Smrg	arguments = NIL;
8055dfecf96Smrg    CHECK_LIST(arguments);
8065dfecf96Smrg
8075dfecf96Smrg    if (options == SHELL)
8085dfecf96Smrg	widget = XtCreatePopupShell(name, widget_class, parent, NULL, 0);
8095dfecf96Smrg    else
8105dfecf96Smrg	widget = XtCreateWidget(name, widget_class, parent, NULL, 0);
8115dfecf96Smrg
8125dfecf96Smrg    if (arguments == NIL)
8135dfecf96Smrg	resources = NULL;
8145dfecf96Smrg    else {
8155dfecf96Smrg	resources = LispConvertResources(arguments, widget,
8165dfecf96Smrg					 GetResourceList(widget_class),
8175dfecf96Smrg					 GetResourceList(XtClass(parent)));
8185dfecf96Smrg	XtSetValues(widget, resources->args, resources->num_args);
8195dfecf96Smrg    }
8205dfecf96Smrg    if (options == MANAGED)
8215dfecf96Smrg	XtManageChild(widget);
8225dfecf96Smrg    if (resources)
8235dfecf96Smrg	LispFreeResources(resources);
8245dfecf96Smrg
8255dfecf96Smrg    return (OPAQUE(widget, xtWidget_t));
8265dfecf96Smrg}
8275dfecf96Smrg
8285dfecf96SmrgLispObj *
8295dfecf96SmrgLisp_XtGetKeyboardFocusWidget(LispBuiltin *builtin)
8305dfecf96Smrg/*
8315dfecf96Smrg xt-get-keyboard-focus-widget widget
8325dfecf96Smrg */
8335dfecf96Smrg{
8345dfecf96Smrg    LispObj *widget;
8355dfecf96Smrg
8365dfecf96Smrg    widget = ARGUMENT(0);
8375dfecf96Smrg
8385dfecf96Smrg    if (!CHECKO(widget, xtWidget_t))
8395dfecf96Smrg	LispDestroy("%s: cannot convert %s to Widget",
8405dfecf96Smrg		    STRFUN(builtin), STROBJ(widget));
8415dfecf96Smrg    return (OPAQUE(XtGetKeyboardFocusWidget((Widget)(widget->data.opaque.data)),
8425dfecf96Smrg		   xtWidget_t));
8435dfecf96Smrg}
8445dfecf96Smrg
8455dfecf96SmrgLispObj *
8465dfecf96SmrgLisp_XtGetValues(LispBuiltin *builtin)
8475dfecf96Smrg/*
8485dfecf96Smrg xt-get-values widget arguments
8495dfecf96Smrg */
8505dfecf96Smrg{
8515dfecf96Smrg    Arg args[1];
8525dfecf96Smrg    Widget widget;
8535dfecf96Smrg    ResourceList *rlist, *plist;
8545dfecf96Smrg    ResourceInfo *resource;
8555dfecf96Smrg    LispObj *list, *object = NIL, *result, *cons = NIL;
8565dfecf96Smrg    char c1;
8575dfecf96Smrg    short c2;
8585dfecf96Smrg    int c4;
8595dfecf96Smrg#ifdef LONG64
8605dfecf96Smrg    long c8;
8615dfecf96Smrg#endif
8625dfecf96Smrg
8635dfecf96Smrg    LispObj *owidget, *arguments;
8645dfecf96Smrg
8655dfecf96Smrg    arguments = ARGUMENT(1);
8665dfecf96Smrg    owidget = ARGUMENT(0);
8675dfecf96Smrg
8685dfecf96Smrg    if (arguments == NIL)
8695dfecf96Smrg	return (NIL);
8705dfecf96Smrg
8715dfecf96Smrg    if (!CHECKO(owidget, xtWidget_t))
8725dfecf96Smrg	LispDestroy("%s: cannot convert %s to Widget",
8735dfecf96Smrg		    STRFUN(builtin), STROBJ(owidget));
8745dfecf96Smrg    widget = (Widget)(owidget->data.opaque.data);
8755dfecf96Smrg    CHECK_CONS(arguments);
8765dfecf96Smrg
8775dfecf96Smrg    rlist = GetResourceList(XtClass(widget));
8785dfecf96Smrg    plist =  XtParent(widget) ?
8795dfecf96Smrg	     GetResourceList(XtClass(XtParent(widget))) : NULL;
8805dfecf96Smrg
8815dfecf96Smrg    GCDisable();
8825dfecf96Smrg    result = NIL;
8835dfecf96Smrg    for (list = arguments; CONSP(list); list = CDR(list)) {
8845dfecf96Smrg	CHECK_STRING(CAR(list));
8855dfecf96Smrg	if ((resource = GetResourceInfo(THESTR(CAR(list)), rlist, plist))
8865dfecf96Smrg	     == NULL) {
8875dfecf96Smrg	    int i;
8885dfecf96Smrg	    Widget child;
8895dfecf96Smrg
8905dfecf96Smrg	    for (i = 0; i < rlist->num_resources; i++) {
8915dfecf96Smrg		if (rlist->resources[i]->qtype == qWidget) {
8925dfecf96Smrg		    XtSetArg(args[0],
8935dfecf96Smrg			     XrmQuarkToString(rlist->resources[i]->qname),
8945dfecf96Smrg			     &child);
8955dfecf96Smrg		    XtGetValues(widget, args, 1);
8965dfecf96Smrg		    if (child && XtParent(child) == widget) {
8975dfecf96Smrg			resource =
8985dfecf96Smrg			    GetResourceInfo(THESTR(CAR(list)),
8995dfecf96Smrg					    GetResourceList(XtClass(child)),
9005dfecf96Smrg					    NULL);
9015dfecf96Smrg			if (resource)
9025dfecf96Smrg			    break;
9035dfecf96Smrg		    }
9045dfecf96Smrg		}
9055dfecf96Smrg	    }
9065dfecf96Smrg	    if (resource == NULL) {
9075dfecf96Smrg		LispMessage("%s: resource %s not available",
9085dfecf96Smrg			    STRFUN(builtin), THESTR(CAR(list)));
9095dfecf96Smrg		continue;
9105dfecf96Smrg	    }
9115dfecf96Smrg	}
9125dfecf96Smrg	switch (resource->size) {
9135dfecf96Smrg	    case 1:
9145dfecf96Smrg		XtSetArg(args[0], THESTR(CAR(list)), &c1);
9155dfecf96Smrg		break;
9165dfecf96Smrg	    case 2:
9175dfecf96Smrg		XtSetArg(args[0], THESTR(CAR(list)), &c2);
9185dfecf96Smrg		break;
9195dfecf96Smrg	    case 4:
9205dfecf96Smrg		XtSetArg(args[0], THESTR(CAR(list)), &c4);
9215dfecf96Smrg		break;
9225dfecf96Smrg#ifdef LONG64
9235dfecf96Smrg	    case 1:
9245dfecf96Smrg		XtSetArg(args[0], THESTR(CAR(list)), &c8);
9255dfecf96Smrg		break;
9265dfecf96Smrg#endif
9275dfecf96Smrg	}
9285dfecf96Smrg	XtGetValues(widget, args, 1);
9295dfecf96Smrg
9305dfecf96Smrg	/* special resources */
9315dfecf96Smrg	if (resource->qtype == qString) {
9325dfecf96Smrg#ifdef LONG64
9335dfecf96Smrg	    object = CONS(CAR(list), STRING((char*)c8));
9345dfecf96Smrg#else
9355dfecf96Smrg	    object = CONS(CAR(list), STRING((char*)c4));
9365dfecf96Smrg#endif
9375dfecf96Smrg	}
9385dfecf96Smrg	else if (resource->qtype == qCardinal || resource->qtype == qInt) {
9395dfecf96Smrg#ifdef LONG64
9405dfecf96Smrg	    if (sizeof(int) == 8)
9415dfecf96Smrg		object = CONS(CAR(list), INTEGER(c8));
9425dfecf96Smrg	    else
9435dfecf96Smrg#endif
9445dfecf96Smrg	    object = CONS(CAR(list), INTEGER(c4));
9455dfecf96Smrg	}
9465dfecf96Smrg	else {
9475dfecf96Smrg	    switch (resource->size) {
9485dfecf96Smrg		case 1:
9495dfecf96Smrg		    object = CONS(CAR(list), OPAQUE(c1, 0));
9505dfecf96Smrg		    break;
9515dfecf96Smrg		case 2:
9525dfecf96Smrg		    object = CONS(CAR(list), OPAQUE(c2, 0));
9535dfecf96Smrg		    break;
9545dfecf96Smrg		case 4:
9555dfecf96Smrg		    object = CONS(CAR(list), OPAQUE(c4, 0));
9565dfecf96Smrg		    break;
9575dfecf96Smrg#ifdef LONG64
9585dfecf96Smrg		case 8:
9595dfecf96Smrg		    object = CONS(CAR(list), OPAQUE(c8, 0));
9605dfecf96Smrg		    break;
9615dfecf96Smrg#endif
9625dfecf96Smrg	    }
9635dfecf96Smrg	}
9645dfecf96Smrg
9655dfecf96Smrg	if (result == NIL)
9665dfecf96Smrg	    result = cons = CONS(object, NIL);
9675dfecf96Smrg	else {
9685dfecf96Smrg	    RPLACD(cons, CONS(object, NIL));
9695dfecf96Smrg	    cons = CDR(cons);
9705dfecf96Smrg	}
9715dfecf96Smrg    }
9725dfecf96Smrg    GCEnable();
9735dfecf96Smrg
9745dfecf96Smrg    return (result);
9755dfecf96Smrg}
9765dfecf96Smrg
9775dfecf96SmrgLispObj *
9785dfecf96SmrgLisp_XtManageChild(LispBuiltin *builtin)
9795dfecf96Smrg/*
9805dfecf96Smrg xt-manage-child widget
9815dfecf96Smrg */
9825dfecf96Smrg{
9835dfecf96Smrg    LispObj *widget;
9845dfecf96Smrg
9855dfecf96Smrg    widget = ARGUMENT(0);
9865dfecf96Smrg
9875dfecf96Smrg    if (!CHECKO(widget, xtWidget_t))
9885dfecf96Smrg	LispDestroy("%s: cannot convert %s to Widget",
9895dfecf96Smrg		    STRFUN(builtin), STROBJ(widget));
9905dfecf96Smrg    XtManageChild((Widget)(widget->data.opaque.data));
9915dfecf96Smrg
9925dfecf96Smrg    return (widget);
9935dfecf96Smrg}
9945dfecf96Smrg
9955dfecf96SmrgLispObj *
9965dfecf96SmrgLisp_XtUnmanageChild(LispBuiltin *builtin)
9975dfecf96Smrg/*
9985dfecf96Smrg xt-unmanage-child widget
9995dfecf96Smrg */
10005dfecf96Smrg{
10015dfecf96Smrg    LispObj *widget;
10025dfecf96Smrg
10035dfecf96Smrg    widget = ARGUMENT(0);
10045dfecf96Smrg
10055dfecf96Smrg    if (!CHECKO(widget, xtWidget_t))
10065dfecf96Smrg	LispDestroy("%s: cannot convert %s to Widget",
10075dfecf96Smrg		    STRFUN(builtin), STROBJ(widget));
10085dfecf96Smrg    XtUnmanageChild((Widget)(widget->data.opaque.data));
10095dfecf96Smrg
10105dfecf96Smrg    return (widget);
10115dfecf96Smrg}
10125dfecf96Smrg
10135dfecf96SmrgLispObj *
10145dfecf96SmrgLisp_XtMapWidget(LispBuiltin *builtin)
10155dfecf96Smrg/*
10165dfecf96Smrg xt-map-widget widget
10175dfecf96Smrg */
10185dfecf96Smrg{
10195dfecf96Smrg    LispObj *widget;
10205dfecf96Smrg
10215dfecf96Smrg    widget = ARGUMENT(0);
10225dfecf96Smrg
10235dfecf96Smrg    if (!CHECKO(widget, xtWidget_t))
10245dfecf96Smrg	LispDestroy("%s: cannot convert %s to Widget",
10255dfecf96Smrg		    STRFUN(builtin), STROBJ(widget));
10265dfecf96Smrg    XtMapWidget((Widget)(widget->data.opaque.data));
10275dfecf96Smrg
10285dfecf96Smrg    return (widget);
10295dfecf96Smrg}
10305dfecf96Smrg
10315dfecf96SmrgLispObj *
10325dfecf96SmrgLisp_XtUnmapWidget(LispBuiltin *builtin)
10335dfecf96Smrg/*
10345dfecf96Smrg xt-unmap-widget widget
10355dfecf96Smrg */
10365dfecf96Smrg{
10375dfecf96Smrg    LispObj *widget;
10385dfecf96Smrg
10395dfecf96Smrg    widget = ARGUMENT(0);
10405dfecf96Smrg
10415dfecf96Smrg    if (!CHECKO(widget, xtWidget_t))
10425dfecf96Smrg	LispDestroy("%s: cannot convert %s to Widget",
10435dfecf96Smrg		    STRFUN(builtin), STROBJ(widget));
10445dfecf96Smrg    XtUnmapWidget((Widget)(widget->data.opaque.data));
10455dfecf96Smrg
10465dfecf96Smrg    return (widget);
10475dfecf96Smrg}
10485dfecf96Smrg
10495dfecf96SmrgLispObj *
10505dfecf96SmrgLisp_XtSetMappedWhenManaged(LispBuiltin *builtin)
10515dfecf96Smrg/*
10525dfecf96Smrg xt-set-mapped-when-managed widget map-when-managed
10535dfecf96Smrg */
10545dfecf96Smrg{
10555dfecf96Smrg    LispObj *widget, *map_when_managed;
10565dfecf96Smrg
10575dfecf96Smrg    map_when_managed = ARGUMENT(1);
10585dfecf96Smrg    widget = ARGUMENT(0);
10595dfecf96Smrg
10605dfecf96Smrg    if (!CHECKO(widget, xtWidget_t))
10615dfecf96Smrg	LispDestroy("%s: cannot convert %s to Widget",
10625dfecf96Smrg		    STRFUN(builtin), STROBJ(widget));
10635dfecf96Smrg
10645dfecf96Smrg    XtSetMappedWhenManaged((Widget)(widget->data.opaque.data),
10655dfecf96Smrg			   map_when_managed != NIL);
10665dfecf96Smrg
10675dfecf96Smrg    return (map_when_managed);
10685dfecf96Smrg}
10695dfecf96Smrg
10705dfecf96SmrgLispObj *
10715dfecf96SmrgLisp_XtPopup(LispBuiltin *builtin)
10725dfecf96Smrg/*
10735dfecf96Smrg xt-popup widget grab-kind
10745dfecf96Smrg */
10755dfecf96Smrg{
10765dfecf96Smrg    XtGrabKind kind;
10775dfecf96Smrg
10785dfecf96Smrg    LispObj *widget, *grab_kind;
10795dfecf96Smrg
10805dfecf96Smrg    grab_kind = ARGUMENT(1);
10815dfecf96Smrg    widget = ARGUMENT(0);
10825dfecf96Smrg
10835dfecf96Smrg    if (!CHECKO(widget, xtWidget_t))
10845dfecf96Smrg	LispDestroy("%s: cannot convert %s to Widget",
10855dfecf96Smrg		    STRFUN(builtin), STROBJ(widget));
10865dfecf96Smrg    CHECK_INDEX(grab_kind);
10875dfecf96Smrg    kind = (XtGrabKind)FIXNUM_VALUE(grab_kind);
10885dfecf96Smrg    if (kind != XtGrabExclusive && kind != XtGrabNone &&
10895dfecf96Smrg	kind != XtGrabNonexclusive)
10905dfecf96Smrg	LispDestroy("%s: %d does not fit in XtGrabKind",
10915dfecf96Smrg		    STRFUN(builtin), kind);
10925dfecf96Smrg    XtPopup((Widget)(widget->data.opaque.data), kind);
10935dfecf96Smrg
10945dfecf96Smrg    return (grab_kind);
10955dfecf96Smrg}
10965dfecf96Smrg
10975dfecf96SmrgLispObj *
10985dfecf96SmrgLisp_XtPopdown(LispBuiltin *builtin)
10995dfecf96Smrg/*
11005dfecf96Smrg xt-popdown widget
11015dfecf96Smrg */
11025dfecf96Smrg{
11035dfecf96Smrg    LispObj *widget;
11045dfecf96Smrg
11055dfecf96Smrg    widget = ARGUMENT(0);
11065dfecf96Smrg
11075dfecf96Smrg    if (!CHECKO(widget, xtWidget_t))
11085dfecf96Smrg	LispDestroy("%s: cannot convert %s to Widget",
11095dfecf96Smrg		    STRFUN(builtin), STROBJ(widget));
11105dfecf96Smrg    XtPopdown((Widget)(widget->data.opaque.data));
11115dfecf96Smrg
11125dfecf96Smrg    return (widget);
11135dfecf96Smrg}
11145dfecf96Smrg
11155dfecf96SmrgLispObj *
11165dfecf96SmrgLisp_XtSetKeyboardFocus(LispBuiltin *builtin)
11175dfecf96Smrg/*
11185dfecf96Smrg xt-set-keyboard-focus widget descendant
11195dfecf96Smrg */
11205dfecf96Smrg{
11215dfecf96Smrg    LispObj *widget, *descendant;
11225dfecf96Smrg
11235dfecf96Smrg    descendant = ARGUMENT(1);
11245dfecf96Smrg    widget = ARGUMENT(0);
11255dfecf96Smrg
11265dfecf96Smrg    if (!CHECKO(widget, xtWidget_t))
11275dfecf96Smrg	LispDestroy("%s: cannot convert %s to Widget",
11285dfecf96Smrg		    STRFUN(builtin), STROBJ(widget));
11295dfecf96Smrg    if (!CHECKO(descendant, xtWidget_t))
11305dfecf96Smrg	LispDestroy("%s: cannot convert %s to Widget",
11315dfecf96Smrg		    STRFUN(builtin), STROBJ(descendant));
11325dfecf96Smrg    XtSetKeyboardFocus((Widget)(widget->data.opaque.data),
11335dfecf96Smrg		       (Widget)(descendant->data.opaque.data));
11345dfecf96Smrg
11355dfecf96Smrg    return (widget);
11365dfecf96Smrg}
11375dfecf96Smrg
11385dfecf96SmrgLispObj *
11395dfecf96SmrgLisp_XtSetSensitive(LispBuiltin *builtin)
11405dfecf96Smrg/*
11415dfecf96Smrg xt-set-sensitive widget sensitive
11425dfecf96Smrg */
11435dfecf96Smrg{
11445dfecf96Smrg    LispObj *widget, *sensitive;
11455dfecf96Smrg
11465dfecf96Smrg    sensitive = ARGUMENT(1);
11475dfecf96Smrg    widget = ARGUMENT(0);
11485dfecf96Smrg
11495dfecf96Smrg    if (!CHECKO(widget, xtWidget_t))
11505dfecf96Smrg	LispDestroy("%s: cannot convert %s to Widget",
11515dfecf96Smrg		    STRFUN(builtin), STROBJ(widget));
11525dfecf96Smrg    XtSetSensitive((Widget)(widget->data.opaque.data), sensitive != NIL);
11535dfecf96Smrg
11545dfecf96Smrg    return (sensitive);
11555dfecf96Smrg}
11565dfecf96Smrg
11575dfecf96SmrgLispObj *
11585dfecf96SmrgLisp_XtSetValues(LispBuiltin *builtin)
11595dfecf96Smrg/*
11605dfecf96Smrg xt-set-values widget arguments
11615dfecf96Smrg */
11625dfecf96Smrg{
11635dfecf96Smrg    Widget widget;
11645dfecf96Smrg    Resources *resources;
11655dfecf96Smrg
11665dfecf96Smrg    LispObj *owidget, *arguments;
11675dfecf96Smrg
11685dfecf96Smrg    arguments = ARGUMENT(1);
11695dfecf96Smrg    owidget = ARGUMENT(0);
11705dfecf96Smrg
11715dfecf96Smrg    if (arguments == NIL)
11725dfecf96Smrg	return (owidget);
11735dfecf96Smrg
11745dfecf96Smrg    if (!CHECKO(owidget, xtWidget_t))
11755dfecf96Smrg	LispDestroy("%s: cannot convert %s to Widget",
11765dfecf96Smrg		    STRFUN(builtin), STROBJ(owidget));
11775dfecf96Smrg    widget = (Widget)(owidget->data.opaque.data);
11785dfecf96Smrg    CHECK_CONS(arguments);
11795dfecf96Smrg    resources = LispConvertResources(arguments, widget,
11805dfecf96Smrg				     GetResourceList(XtClass(widget)),
11815dfecf96Smrg				     XtParent(widget) ?
11825dfecf96Smrg					GetResourceList(XtClass(XtParent(widget))) :
11835dfecf96Smrg					NULL);
11845dfecf96Smrg    XtSetValues(widget, resources->args, resources->num_args);
11855dfecf96Smrg    LispFreeResources(resources);
11865dfecf96Smrg
11875dfecf96Smrg    return (owidget);
11885dfecf96Smrg}
11895dfecf96Smrg
11905dfecf96SmrgLispObj *
11915dfecf96SmrgLisp_XtWidgetToApplicationContext(LispBuiltin *builtin)
11925dfecf96Smrg/*
11935dfecf96Smrg xt-widget-to-application-context widget
11945dfecf96Smrg */
11955dfecf96Smrg{
11965dfecf96Smrg    Widget widget;
11975dfecf96Smrg    XtAppContext appcon;
11985dfecf96Smrg
11995dfecf96Smrg    LispObj *owidget;
12005dfecf96Smrg
12015dfecf96Smrg    owidget = ARGUMENT(0);
12025dfecf96Smrg
12035dfecf96Smrg    if (!CHECKO(owidget, xtWidget_t))
12045dfecf96Smrg	LispDestroy("%s: cannot convert %s to Widget",
12055dfecf96Smrg		    STRFUN(builtin), STROBJ(owidget));
12065dfecf96Smrg    widget = (Widget)(owidget->data.opaque.data);
12075dfecf96Smrg    appcon = XtWidgetToApplicationContext(widget);
12085dfecf96Smrg
12095dfecf96Smrg    return (OPAQUE(appcon, xtAppContext_t));
12105dfecf96Smrg}
12115dfecf96Smrg
12125dfecf96SmrgLispObj *
12135dfecf96SmrgLisp_XtDisplay(LispBuiltin *builtin)
12145dfecf96Smrg/*
12155dfecf96Smrg xt-display widget
12165dfecf96Smrg */
12175dfecf96Smrg{
12185dfecf96Smrg    Widget widget;
12195dfecf96Smrg    Display *display;
12205dfecf96Smrg
12215dfecf96Smrg    LispObj *owidget;
12225dfecf96Smrg
12235dfecf96Smrg    owidget = ARGUMENT(0);
12245dfecf96Smrg
12255dfecf96Smrg    if (!CHECKO(owidget, xtWidget_t))
12265dfecf96Smrg	LispDestroy("%s: cannot convert %s to Widget",
12275dfecf96Smrg		    STRFUN(builtin), STROBJ(owidget));
12285dfecf96Smrg    widget = (Widget)(owidget->data.opaque.data);
12295dfecf96Smrg    display = XtDisplay(widget);
12305dfecf96Smrg
12315dfecf96Smrg    return (OPAQUE(display, xtDisplay_t));
12325dfecf96Smrg}
12335dfecf96Smrg
12345dfecf96SmrgLispObj *
12355dfecf96SmrgLisp_XtDisplayOfObject(LispBuiltin *builtin)
12365dfecf96Smrg/*
12375dfecf96Smrg xt-display-of-object object
12385dfecf96Smrg */
12395dfecf96Smrg{
12405dfecf96Smrg    Widget widget;
12415dfecf96Smrg    Display *display;
12425dfecf96Smrg
12435dfecf96Smrg    LispObj *object;
12445dfecf96Smrg
12455dfecf96Smrg    object = ARGUMENT(0);
12465dfecf96Smrg
12475dfecf96Smrg    if (!CHECKO(object, xtWidget_t))
12485dfecf96Smrg	LispDestroy("%s: cannot convert %s to Widget",
12495dfecf96Smrg		    STRFUN(builtin), STROBJ(object));
12505dfecf96Smrg    widget = (Widget)(object->data.opaque.data);
12515dfecf96Smrg    display = XtDisplayOfObject(widget);
12525dfecf96Smrg
12535dfecf96Smrg    return (OPAQUE(display, xtDisplay_t));
12545dfecf96Smrg}
12555dfecf96Smrg
12565dfecf96SmrgLispObj *
12575dfecf96SmrgLisp_XtScreen(LispBuiltin *builtin)
12585dfecf96Smrg/*
12595dfecf96Smrg xt-screen widget
12605dfecf96Smrg */
12615dfecf96Smrg{
12625dfecf96Smrg    Widget widget;
12635dfecf96Smrg    Screen *screen;
12645dfecf96Smrg
12655dfecf96Smrg    LispObj *owidget;
12665dfecf96Smrg
12675dfecf96Smrg    owidget = ARGUMENT(0);
12685dfecf96Smrg
12695dfecf96Smrg    if (!CHECKO(owidget, xtWidget_t))
12705dfecf96Smrg	LispDestroy("%s: cannot convert %s to Widget",
12715dfecf96Smrg		    STRFUN(builtin), STROBJ(owidget));
12725dfecf96Smrg    widget = (Widget)(owidget->data.opaque.data);
12735dfecf96Smrg    screen = XtScreen(widget);
12745dfecf96Smrg
12755dfecf96Smrg    return (OPAQUE(screen, xtScreen_t));
12765dfecf96Smrg}
12775dfecf96Smrg
12785dfecf96SmrgLispObj *
12795dfecf96SmrgLisp_XtScreenOfObject(LispBuiltin *builtin)
12805dfecf96Smrg/*
12815dfecf96Smrg xt-screen-of-object object
12825dfecf96Smrg */
12835dfecf96Smrg{
12845dfecf96Smrg    Widget widget;
12855dfecf96Smrg    Screen *screen;
12865dfecf96Smrg
12875dfecf96Smrg    LispObj *object;
12885dfecf96Smrg
12895dfecf96Smrg    object = ARGUMENT(0);
12905dfecf96Smrg
12915dfecf96Smrg    if (!CHECKO(object, xtWidget_t))
12925dfecf96Smrg	LispDestroy("%s: cannot convert %s to Widget",
12935dfecf96Smrg		    STRFUN(builtin), STROBJ(object));
12945dfecf96Smrg    widget = (Widget)(object->data.opaque.data);
12955dfecf96Smrg    screen = XtScreenOfObject(widget);
12965dfecf96Smrg
12975dfecf96Smrg    return (OPAQUE(screen, xtScreen_t));
12985dfecf96Smrg}
12995dfecf96Smrg
13005dfecf96SmrgLispObj *
13015dfecf96SmrgLisp_XtWindow(LispBuiltin *builtin)
13025dfecf96Smrg/*
13035dfecf96Smrg xt-window widget
13045dfecf96Smrg */
13055dfecf96Smrg{
13065dfecf96Smrg    Widget widget;
13075dfecf96Smrg    Window window;
13085dfecf96Smrg
13095dfecf96Smrg    LispObj *owidget;
13105dfecf96Smrg
13115dfecf96Smrg    owidget = ARGUMENT(0);
13125dfecf96Smrg
13135dfecf96Smrg    if (!CHECKO(owidget, xtWidget_t))
13145dfecf96Smrg	LispDestroy("%s: cannot convert %s to Widget",
13155dfecf96Smrg		    STRFUN(builtin), STROBJ(owidget));
13165dfecf96Smrg    widget = (Widget)(owidget->data.opaque.data);
13175dfecf96Smrg    window = XtWindow(widget);
13185dfecf96Smrg
13195dfecf96Smrg    return (OPAQUE(window, xtWindow_t));
13205dfecf96Smrg}
13215dfecf96Smrg
13225dfecf96SmrgLispObj *
13235dfecf96SmrgLisp_XtWindowOfObject(LispBuiltin *builtin)
13245dfecf96Smrg/*
13255dfecf96Smrg xt-window-of-object widget
13265dfecf96Smrg */
13275dfecf96Smrg{
13285dfecf96Smrg    Widget widget;
13295dfecf96Smrg    Window window;
13305dfecf96Smrg
13315dfecf96Smrg    LispObj *object;
13325dfecf96Smrg
13335dfecf96Smrg    object = ARGUMENT(0);
13345dfecf96Smrg
13355dfecf96Smrg    if (!CHECKO(object, xtWidget_t))
13365dfecf96Smrg	LispDestroy("%s: cannot convert %s to Widget",
13375dfecf96Smrg		    STRFUN(builtin), STROBJ(object));
13385dfecf96Smrg    widget = (Widget)(object->data.opaque.data);
13395dfecf96Smrg    window = XtWindowOfObject(widget);
13405dfecf96Smrg
13415dfecf96Smrg    return (OPAQUE(window, xtWindow_t));
13425dfecf96Smrg}
13435dfecf96Smrg
13445dfecf96SmrgLispObj *
13455dfecf96SmrgLisp_XtAddGrab(LispBuiltin *builtin)
13465dfecf96Smrg/*
13475dfecf96Smrg xt-add-grab widget exclusive spring-loaded
13485dfecf96Smrg */
13495dfecf96Smrg{
13505dfecf96Smrg    Widget widget;
13515dfecf96Smrg    Bool exclusive, spring_loaded;
13525dfecf96Smrg
13535dfecf96Smrg    LispObj *owidget, *oexclusive, *ospring_loaded;
13545dfecf96Smrg
13555dfecf96Smrg    ospring_loaded = ARGUMENT(2);
13565dfecf96Smrg    oexclusive = ARGUMENT(1);
13575dfecf96Smrg    owidget = ARGUMENT(0);
13585dfecf96Smrg
13595dfecf96Smrg    if (!CHECKO(owidget, xtWidget_t))
13605dfecf96Smrg	LispDestroy("%s: cannot convert %s to Widget",
13615dfecf96Smrg		    STRFUN(builtin), STROBJ(owidget));
13625dfecf96Smrg    widget = (Widget)(owidget->data.opaque.data);
13635dfecf96Smrg    exclusive = oexclusive != NIL;
13645dfecf96Smrg    spring_loaded = ospring_loaded != NIL;
13655dfecf96Smrg
13665dfecf96Smrg    XtAddGrab(widget, exclusive, spring_loaded);
13675dfecf96Smrg
13685dfecf96Smrg    return (T);
13695dfecf96Smrg}
13705dfecf96Smrg
13715dfecf96SmrgLispObj *
13725dfecf96SmrgLisp_XtRemoveGrab(LispBuiltin *builtin)
13735dfecf96Smrg/*
13745dfecf96Smrg xt-remove-grab widget
13755dfecf96Smrg */
13765dfecf96Smrg{
13775dfecf96Smrg    LispObj *widget;
13785dfecf96Smrg
13795dfecf96Smrg    widget = ARGUMENT(0);
13805dfecf96Smrg
13815dfecf96Smrg    if (!CHECKO(widget, xtWidget_t))
13825dfecf96Smrg	LispDestroy("%s: cannot convert %s to Widget",
13835dfecf96Smrg		    STRFUN(builtin), STROBJ(widget));
13845dfecf96Smrg
13855dfecf96Smrg    XtRemoveGrab((Widget)(widget->data.opaque.data));
13865dfecf96Smrg
13875dfecf96Smrg    return (NIL);
13885dfecf96Smrg}
13895dfecf96Smrg
13905dfecf96SmrgLispObj *
13915dfecf96SmrgLisp_XtName(LispBuiltin *builtin)
13925dfecf96Smrg/*
13935dfecf96Smrg xt-name widget
13945dfecf96Smrg */
13955dfecf96Smrg{
13965dfecf96Smrg    LispObj *widget;
13975dfecf96Smrg
13985dfecf96Smrg    widget = ARGUMENT(0);
13995dfecf96Smrg
14005dfecf96Smrg    if (!CHECKO(widget, xtWidget_t))
14015dfecf96Smrg	LispDestroy("%s: cannot convert %s to Widget",
14025dfecf96Smrg		    STRFUN(builtin), STROBJ(widget));
14035dfecf96Smrg
14045dfecf96Smrg    return (STRING(XtName((Widget)(widget->data.opaque.data))));
14055dfecf96Smrg}
14065dfecf96Smrg
14075dfecf96SmrgLispObj *
14085dfecf96SmrgLisp_XtParent(LispBuiltin *builtin)
14095dfecf96Smrg/*
14105dfecf96Smrg xt-parent widget
14115dfecf96Smrg */
14125dfecf96Smrg{
14135dfecf96Smrg    LispObj *widget;
14145dfecf96Smrg
14155dfecf96Smrg    widget = ARGUMENT(0);
14165dfecf96Smrg
14175dfecf96Smrg    if (!CHECKO(widget, xtWidget_t))
14185dfecf96Smrg	LispDestroy("%s: cannot convert %s to Widget",
14195dfecf96Smrg		    STRFUN(builtin), STROBJ(widget));
14205dfecf96Smrg
14215dfecf96Smrg    return (OPAQUE(XtParent((Widget)widget->data.opaque.data), xtWidget_t));
14225dfecf96Smrg}
14235dfecf96Smrg
14245dfecf96SmrgLispObj *
14255dfecf96SmrgLisp_XtAppGetExitFlag(LispBuiltin *builtin)
14265dfecf96Smrg/*
14275dfecf96Smrg xt-app-get-exit-flag app-context
14285dfecf96Smrg */
14295dfecf96Smrg{
14305dfecf96Smrg    LispObj *app_context;
14315dfecf96Smrg
14325dfecf96Smrg    app_context = ARGUMENT(0);
14335dfecf96Smrg
14345dfecf96Smrg    if (!CHECKO(app_context, xtAppContext_t))
14355dfecf96Smrg	LispDestroy("%s: cannot convert %s to XtAppContext",
14365dfecf96Smrg		    STRFUN(builtin), STROBJ(app_context));
14375dfecf96Smrg
14385dfecf96Smrg    return (XtAppGetExitFlag((XtAppContext)(app_context->data.opaque.data)) ?
14395dfecf96Smrg	    T : NIL);
14405dfecf96Smrg}
14415dfecf96Smrg
14425dfecf96SmrgLispObj *
14435dfecf96SmrgLisp_XtAppSetExitFlag(LispBuiltin *builtin)
14445dfecf96Smrg/*
14455dfecf96Smrg xt-app-get-exit-flag app-context
14465dfecf96Smrg */
14475dfecf96Smrg{
14485dfecf96Smrg    LispObj *app_context;
14495dfecf96Smrg
14505dfecf96Smrg    app_context = ARGUMENT(0);
14515dfecf96Smrg
14525dfecf96Smrg    if (!CHECKO(app_context, xtAppContext_t))
14535dfecf96Smrg	LispDestroy("%s: cannot convert %s to XtAppContext",
14545dfecf96Smrg		    STRFUN(builtin), STROBJ(app_context));
14555dfecf96Smrg
14565dfecf96Smrg    XtAppSetExitFlag((XtAppContext)(app_context->data.opaque.data));
14575dfecf96Smrg
14585dfecf96Smrg    return (T);
14595dfecf96Smrg}
14605dfecf96Smrg
14615dfecf96Smrgstatic Resources *
14625dfecf96SmrgLispConvertResources(LispObj *list, Widget widget,
14635dfecf96Smrg		     ResourceList *rlist, ResourceList *plist)
14645dfecf96Smrg{
14655dfecf96Smrg    char c1;
14665dfecf96Smrg    short c2;
14675dfecf96Smrg    int c4;
14685dfecf96Smrg#ifdef LONG64
14695dfecf96Smrg    long c8;
14705dfecf96Smrg#endif
14715dfecf96Smrg    XrmValue from, to;
14725dfecf96Smrg    LispObj *arg, *val;
14735dfecf96Smrg    ResourceInfo *resource;
14745dfecf96Smrg    char *fname = "XT-CONVERT-RESOURCES";
14755dfecf96Smrg    Resources *resources = (Resources*)XtCalloc(1, sizeof(Resources));
14765dfecf96Smrg
14775dfecf96Smrg    for (; CONSP(list); list = CDR(list)) {
14785dfecf96Smrg	if (!CONSP(CAR(list))) {
14795dfecf96Smrg	    XtFree((XtPointer)resources);
14805dfecf96Smrg	    LispDestroy("%s: %s is not a cons", fname, STROBJ(CAR(list)));
14815dfecf96Smrg	}
14825dfecf96Smrg	arg = CAR(CAR(list));
14835dfecf96Smrg	val = CDR(CAR(list));
14845dfecf96Smrg
14855dfecf96Smrg	if (!STRINGP(arg)) {
14865dfecf96Smrg	    XtFree((XtPointer)resources);
14875dfecf96Smrg	    LispDestroy("%s: %s is not a string", fname, STROBJ(arg));
14885dfecf96Smrg	}
14895dfecf96Smrg
14905dfecf96Smrg	if ((resource = GetResourceInfo(THESTR(arg), rlist, plist)) == NULL) {
14915dfecf96Smrg	    int i;
14925dfecf96Smrg	    Arg args[1];
14935dfecf96Smrg	    Widget child;
14945dfecf96Smrg
14955dfecf96Smrg	    for (i = 0; i < rlist->num_resources; i++) {
14965dfecf96Smrg		if (rlist->resources[i]->qtype == qWidget) {
14975dfecf96Smrg		    XtSetArg(args[0],
14985dfecf96Smrg			     XrmQuarkToString(rlist->resources[i]->qname),
14995dfecf96Smrg			     &child);
15005dfecf96Smrg		    XtGetValues(widget, args, 1);
15015dfecf96Smrg		    if (child && XtParent(child) == widget) {
15025dfecf96Smrg			resource =
15035dfecf96Smrg			    GetResourceInfo(THESTR(arg),
15045dfecf96Smrg					    GetResourceList(XtClass(child)),
15055dfecf96Smrg					    NULL);
15065dfecf96Smrg			if (resource)
15075dfecf96Smrg			    break;
15085dfecf96Smrg		    }
15095dfecf96Smrg		}
15105dfecf96Smrg	    }
15115dfecf96Smrg	    if (resource == NULL) {
15125dfecf96Smrg		LispMessage("%s: resource %s not available",
15135dfecf96Smrg			    fname, THESTR(arg));
15145dfecf96Smrg		continue;
15155dfecf96Smrg	    }
15165dfecf96Smrg	}
15175dfecf96Smrg
15185dfecf96Smrg	if (LONGINTP(val) || DFLOATP(val) || OPAQUEP(val)) {
15195dfecf96Smrg	    resources->args = (Arg*)
15205dfecf96Smrg		XtRealloc((XtPointer)resources->args,
15215dfecf96Smrg			  sizeof(Arg) * (resources->num_args + 1));
15225dfecf96Smrg	    if (!OPAQUEP(val)) {
15235dfecf96Smrg		float fvalue;
15245dfecf96Smrg
15255dfecf96Smrg		if (DFLOATP(val))
15265dfecf96Smrg		    fvalue = DFLOAT_VALUE(val);
15275dfecf96Smrg		else
15285dfecf96Smrg		    fvalue = LONGINT_VALUE(val);
15295dfecf96Smrg		if (resource->qtype == qFloat) {
15305dfecf96Smrg		    XtSetArg(resources->args[resources->num_args],
15315dfecf96Smrg			     XrmQuarkToString(resource->qname), fvalue);
15325dfecf96Smrg		}
15335dfecf96Smrg		else
15345dfecf96Smrg		    XtSetArg(resources->args[resources->num_args],
15355dfecf96Smrg			     XrmQuarkToString(resource->qname),
15365dfecf96Smrg			     (int)fvalue);
15375dfecf96Smrg	    }
15385dfecf96Smrg	    else
15395dfecf96Smrg		XtSetArg(resources->args[resources->num_args],
15405dfecf96Smrg			 XrmQuarkToString(resource->qname), val->data.opaque.data);
15415dfecf96Smrg	    ++resources->num_args;
15425dfecf96Smrg	    continue;
15435dfecf96Smrg	}
15445dfecf96Smrg	else if (val == NIL) {
15455dfecf96Smrg	    /* XXX assume it is a pointer or a boolean */
15465dfecf96Smrg#ifdef DEBUG
15475dfecf96Smrg	    LispWarning("%s: assuming %s is a pointer or boolean",
15485dfecf96Smrg			fname, XrmQuarkToString(resource->qname));
15495dfecf96Smrg#endif
15505dfecf96Smrg	    resources->args = (Arg*)
15515dfecf96Smrg		XtRealloc((XtPointer)resources->args,
15525dfecf96Smrg			  sizeof(Arg) * (resources->num_args + 1));
15535dfecf96Smrg	    XtSetArg(resources->args[resources->num_args],
15545dfecf96Smrg		     XrmQuarkToString(resource->qname), NULL);
15555dfecf96Smrg	    ++resources->num_args;
15565dfecf96Smrg	    continue;
15575dfecf96Smrg	}
15585dfecf96Smrg	else if (val == T) {
15595dfecf96Smrg	    /* XXX assume it is a boolean */
15605dfecf96Smrg#ifdef DEBUG
15615dfecf96Smrg	    LispWarning("%s: assuming %s is a boolean",
15625dfecf96Smrg			fname, XrmQuarkToString(resource->qname));
15635dfecf96Smrg#endif
15645dfecf96Smrg	    resources->args = (Arg*)
15655dfecf96Smrg		XtRealloc((XtPointer)resources->args,
15665dfecf96Smrg			  sizeof(Arg) * (resources->num_args + 1));
15675dfecf96Smrg	    XtSetArg(resources->args[resources->num_args],
15685dfecf96Smrg		     XrmQuarkToString(resource->qname), True);
15695dfecf96Smrg	    ++resources->num_args;
15705dfecf96Smrg	    continue;
15715dfecf96Smrg	}
15725dfecf96Smrg	else if (!STRINGP(val)) {
15735dfecf96Smrg	    XtFree((XtPointer)resources);
15745dfecf96Smrg	    LispDestroy("%s: resource value must be string, number or opaque, not %s",
15755dfecf96Smrg			fname, STROBJ(val));
15765dfecf96Smrg	}
15775dfecf96Smrg
15785dfecf96Smrg	from.size = val == NIL ? 1 : strlen(THESTR(val)) + 1;
15795dfecf96Smrg	from.addr = val == NIL ? "" : THESTR(val);
15805dfecf96Smrg	switch (to.size = resource->size) {
15815dfecf96Smrg	    case 1:
15825dfecf96Smrg		to.addr = (XtPointer)&c1;
15835dfecf96Smrg		break;
15845dfecf96Smrg	    case 2:
15855dfecf96Smrg		to.addr = (XtPointer)&c2;
15865dfecf96Smrg		break;
15875dfecf96Smrg	    case 4:
15885dfecf96Smrg		to.addr = (XtPointer)&c4;
15895dfecf96Smrg		break;
15905dfecf96Smrg#ifdef LONG64
15915dfecf96Smrg	    case 8:
15925dfecf96Smrg		to.addr = (XtPointer)&c8;
15935dfecf96Smrg		break;
15945dfecf96Smrg#endif
15955dfecf96Smrg	    default:
15965dfecf96Smrg		LispWarning("%s: bad resource size %d for %s",
15975dfecf96Smrg			    fname, to.size, THESTR(arg));
15985dfecf96Smrg		continue;
15995dfecf96Smrg	}
16005dfecf96Smrg
16015dfecf96Smrg	if (qString == resource->qtype)
16025dfecf96Smrg#ifdef LONG64
16035dfecf96Smrg	    c8 = (long)from.addr;
16045dfecf96Smrg#else
16055dfecf96Smrg	    c4 = (long)from.addr;
16065dfecf96Smrg#endif
16075dfecf96Smrg	else if (!XtConvertAndStore(widget, XtRString, &from,
16085dfecf96Smrg				    XrmQuarkToString(resource->qtype), &to))
16095dfecf96Smrg	    /* The type converter already have printed an error message */
16105dfecf96Smrg	    continue;
16115dfecf96Smrg
16125dfecf96Smrg	resources->args = (Arg*)
16135dfecf96Smrg	    XtRealloc((XtPointer)resources->args,
16145dfecf96Smrg		      sizeof(Arg) * (resources->num_args + 1));
16155dfecf96Smrg	switch (to.size) {
16165dfecf96Smrg	    case 1:
16175dfecf96Smrg		XtSetArg(resources->args[resources->num_args],
16185dfecf96Smrg			 XrmQuarkToString(resource->qname), c1);
16195dfecf96Smrg		break;
16205dfecf96Smrg	    case 2:
16215dfecf96Smrg		XtSetArg(resources->args[resources->num_args],
16225dfecf96Smrg			 XrmQuarkToString(resource->qname), c2);
16235dfecf96Smrg		break;
16245dfecf96Smrg	    case 4:
16255dfecf96Smrg		XtSetArg(resources->args[resources->num_args],
16265dfecf96Smrg			 XrmQuarkToString(resource->qname), c4);
16275dfecf96Smrg		break;
16285dfecf96Smrg#ifdef LONG64
16295dfecf96Smrg	    case 8:
16305dfecf96Smrg		XtSetArg(resources->args[resources->num_args],
16315dfecf96Smrg			 XrmQuarkToString(resource->qname), c8);
16325dfecf96Smrg		break;
16335dfecf96Smrg#endif
16345dfecf96Smrg	}
16355dfecf96Smrg	++resources->num_args;
16365dfecf96Smrg    }
16375dfecf96Smrg
16385dfecf96Smrg    return (resources);
16395dfecf96Smrg}
16405dfecf96Smrg
16415dfecf96Smrgstatic void
16425dfecf96SmrgLispFreeResources(Resources *resources)
16435dfecf96Smrg{
16445dfecf96Smrg    if (resources) {
16455dfecf96Smrg	XtFree((XtPointer)resources->args);
16465dfecf96Smrg	XtFree((XtPointer)resources);
16475dfecf96Smrg    }
16485dfecf96Smrg}
16495dfecf96Smrg
16505dfecf96Smrgstatic int
16515dfecf96Smrgbcmp_action_resource(_Xconst void *string, _Xconst void *resource)
16525dfecf96Smrg{
16535dfecf96Smrg    return (strcmp((String)string,
16545dfecf96Smrg		   XrmQuarkToString((*(ResourceInfo**)resource)->qname)));
16555dfecf96Smrg}
16565dfecf96Smrg
16575dfecf96Smrgstatic ResourceInfo *
16585dfecf96SmrgGetResourceInfo(char *name, ResourceList *rlist, ResourceList *plist)
16595dfecf96Smrg{
16605dfecf96Smrg    ResourceInfo **resource = NULL;
16615dfecf96Smrg
16625dfecf96Smrg    if (rlist->resources)
16635dfecf96Smrg	resource = (ResourceInfo**)
16645dfecf96Smrg	    bsearch(name, rlist->resources, rlist->num_resources,
16655dfecf96Smrg		    sizeof(ResourceInfo*), bcmp_action_resource);
16665dfecf96Smrg
16675dfecf96Smrg    if (resource == NULL && plist) {
16685dfecf96Smrg	resource = (ResourceInfo**)
16695dfecf96Smrg	  bsearch(name, &plist->resources[plist->num_resources],
16705dfecf96Smrg		  plist->num_cons_resources, sizeof(ResourceInfo*),
16715dfecf96Smrg		  bcmp_action_resource);
16725dfecf96Smrg    }
16735dfecf96Smrg
16745dfecf96Smrg    return (resource ? *resource : NULL);
16755dfecf96Smrg}
16765dfecf96Smrg
16775dfecf96Smrgstatic ResourceList *
16785dfecf96SmrgGetResourceList(WidgetClass wc)
16795dfecf96Smrg{
16805dfecf96Smrg    ResourceList *list;
16815dfecf96Smrg
16825dfecf96Smrg    if ((list = FindResourceList(wc)) == NULL)
16835dfecf96Smrg	list = CreateResourceList(wc);
16845dfecf96Smrg
16855dfecf96Smrg    return (list);
16865dfecf96Smrg}
16875dfecf96Smrg
16885dfecf96Smrgstatic int
16895dfecf96Smrgbcmp_action_resource_list(_Xconst void *wc, _Xconst void *list)
16905dfecf96Smrg{
16915dfecf96Smrg    return ((char*)wc - (char*)((*(ResourceList**)list)->widget_class));
16925dfecf96Smrg}
16935dfecf96Smrg
16945dfecf96Smrgstatic ResourceList *
16955dfecf96SmrgFindResourceList(WidgetClass wc)
16965dfecf96Smrg{
16975dfecf96Smrg    ResourceList **list;
16985dfecf96Smrg
16995dfecf96Smrg    if (!resource_list)
17005dfecf96Smrg	return (NULL);
17015dfecf96Smrg
17025dfecf96Smrg    list = (ResourceList**)
17035dfecf96Smrg	bsearch(wc, resource_list, num_resource_list,
17045dfecf96Smrg		sizeof(ResourceList*),  bcmp_action_resource_list);
17055dfecf96Smrg
17065dfecf96Smrg    return (list ? *list : NULL);
17075dfecf96Smrg}
17085dfecf96Smrg
17095dfecf96Smrgstatic int
17105dfecf96Smrgqcmp_action_resource_list(_Xconst void *left, _Xconst void *right)
17115dfecf96Smrg{
17125dfecf96Smrg    return ((char*)((*(ResourceList**)left)->widget_class) -
17135dfecf96Smrg	    (char*)((*(ResourceList**)right)->widget_class));
17145dfecf96Smrg}
17155dfecf96Smrg
17165dfecf96Smrgstatic ResourceList *
17175dfecf96SmrgCreateResourceList(WidgetClass wc)
17185dfecf96Smrg{
17195dfecf96Smrg    ResourceList *list;
17205dfecf96Smrg
17215dfecf96Smrg    list = (ResourceList*)XtMalloc(sizeof(ResourceList));
17225dfecf96Smrg    list->widget_class = wc;
17235dfecf96Smrg    list->num_resources = list->num_cons_resources = 0;
17245dfecf96Smrg    list->resources = NULL;
17255dfecf96Smrg
17265dfecf96Smrg    resource_list = (ResourceList**)
17275dfecf96Smrg	XtRealloc((XtPointer)resource_list, sizeof(ResourceList*) *
17285dfecf96Smrg		  (num_resource_list + 1));
17295dfecf96Smrg    resource_list[num_resource_list++] = list;
17305dfecf96Smrg    qsort(resource_list, num_resource_list, sizeof(ResourceList*),
17315dfecf96Smrg	  qcmp_action_resource_list);
17325dfecf96Smrg    BindResourceList(list);
17335dfecf96Smrg
17345dfecf96Smrg    return (list);
17355dfecf96Smrg}
17365dfecf96Smrg
17375dfecf96Smrgstatic int
17385dfecf96Smrgqcmp_action_resource(_Xconst void *left, _Xconst void *right)
17395dfecf96Smrg{
17405dfecf96Smrg    return (strcmp(XrmQuarkToString((*(ResourceInfo**)left)->qname),
17415dfecf96Smrg		   XrmQuarkToString((*(ResourceInfo**)right)->qname)));
17425dfecf96Smrg}
17435dfecf96Smrg
17445dfecf96Smrgstatic void
17455dfecf96SmrgBindResourceList(ResourceList *list)
17465dfecf96Smrg{
17475dfecf96Smrg    XtResourceList xt_list, cons_list;
17485dfecf96Smrg    Cardinal i, num_xt, num_cons;
17495dfecf96Smrg
17505dfecf96Smrg    XtGetResourceList(list->widget_class, &xt_list, &num_xt);
17515dfecf96Smrg    XtGetConstraintResourceList(list->widget_class, &cons_list, &num_cons);
17525dfecf96Smrg    list->num_resources = num_xt;
17535dfecf96Smrg    list->num_cons_resources = num_cons;
17545dfecf96Smrg
17555dfecf96Smrg    list->resources = (ResourceInfo**)
17565dfecf96Smrg	XtMalloc(sizeof(ResourceInfo*) * (num_xt + num_cons));
17575dfecf96Smrg
17585dfecf96Smrg    for (i = 0; i < num_xt; i++) {
17595dfecf96Smrg	list->resources[i] = (ResourceInfo*)XtMalloc(sizeof(ResourceInfo));
17605dfecf96Smrg	list->resources[i]->qname =
17615dfecf96Smrg	    XrmPermStringToQuark(xt_list[i].resource_name);
17625dfecf96Smrg	list->resources[i]->qtype =
17635dfecf96Smrg	    XrmPermStringToQuark(xt_list[i].resource_type);
17645dfecf96Smrg	list->resources[i]->size = xt_list[i].resource_size;
17655dfecf96Smrg    }
17665dfecf96Smrg
17675dfecf96Smrg    for (; i < num_xt + num_cons; i++) {
17685dfecf96Smrg	list->resources[i] = (ResourceInfo*)XtMalloc(sizeof(ResourceInfo));
17695dfecf96Smrg	list->resources[i]->qname =
17705dfecf96Smrg	    XrmPermStringToQuark(cons_list[i - num_xt].resource_name);
17715dfecf96Smrg	list->resources[i]->qtype =
17725dfecf96Smrg	    XrmPermStringToQuark(cons_list[i - num_xt].resource_type);
17735dfecf96Smrg	list->resources[i]->size = cons_list[i - num_xt].resource_size;
17745dfecf96Smrg    }
17755dfecf96Smrg
17765dfecf96Smrg    XtFree((XtPointer)xt_list);
17775dfecf96Smrg    if (cons_list)
17785dfecf96Smrg	XtFree((XtPointer)cons_list);
17795dfecf96Smrg
17805dfecf96Smrg    qsort(list->resources, list->num_resources, sizeof(ResourceInfo*),
17815dfecf96Smrg	  qcmp_action_resource);
17825dfecf96Smrg    if (num_cons)
17835dfecf96Smrg	qsort(&list->resources[num_xt], list->num_cons_resources,
17845dfecf96Smrg	      sizeof(ResourceInfo*), qcmp_action_resource);
17855dfecf96Smrg}
17865dfecf96Smrg
17875dfecf96Smrg/*ARGSUSED*/
17885dfecf96Smrgstatic void
17895dfecf96SmrgPopdownAction(Widget w, XEvent *event, String *params, Cardinal *num_params)
17905dfecf96Smrg{
17915dfecf96Smrg    XtPopdown(w);
17925dfecf96Smrg}
17935dfecf96Smrg
17945dfecf96Smrg/*ARGSUSED*/
17955dfecf96Smrgstatic void
17965dfecf96SmrgQuitAction(Widget w, XEvent *event, String *params, Cardinal *num_params)
17975dfecf96Smrg{
17985dfecf96Smrg    XtAppSetExitFlag(XtWidgetToApplicationContext(w));
17995dfecf96Smrg}
1800