#include "../xt/xt.h"
#include <Xm/Xm.h>

SYMDESCR Reason_Syms[] = {
    { "none",                   XmCR_NONE },
    { "help",                   XmCR_HELP },
    { "value-changed",          XmCR_VALUE_CHANGED },
    { "increment",              XmCR_INCREMENT },
    { "decrement",              XmCR_DECREMENT },
    { "page-increment",         XmCR_PAGE_INCREMENT },
    { "page-decrement",         XmCR_PAGE_DECREMENT },
    { "to-top",                 XmCR_TO_TOP },
    { "to-bottom",              XmCR_TO_BOTTOM },
    { "drag",                   XmCR_DRAG },
    { "activate",               XmCR_ACTIVATE },
    { "arm",                    XmCR_ARM },
    { "disarm",                 XmCR_DISARM },
    { "map",                    XmCR_MAP },
    { "unmap",                  XmCR_UNMAP },
    { "focus",                  XmCR_FOCUS },
    { "losing-focus",           XmCR_LOSING_FOCUS },
    { "modifying-text-value",   XmCR_MODIFYING_TEXT_VALUE },

   { "moving-insert-cursor",   XmCR_MOVING_INSERT_CURSOR },
    { "execute",                XmCR_EXECUTE },
    { "single-select",          XmCR_SINGLE_SELECT },
    { "multiple-select",        XmCR_MULTIPLE_SELECT },
    { "extended-select",        XmCR_EXTENDED_SELECT },
    { "browse-select",          XmCR_BROWSE_SELECT },
    { "default-action",         XmCR_DEFAULT_ACTION },
    { "clipboard-data-request", XmCR_CLIPBOARD_DATA_REQUEST },
    { "clipboard-data-delete",  XmCR_CLIPBOARD_DATA_DELETE },
    { "cascading",              XmCR_CASCADING },
    { "ok",                     XmCR_OK },
    { "cancel",                 XmCR_CANCEL },
    { "apply",                  XmCR_APPLY },
    { "no-match",               XmCR_NO_MATCH },
    { "command-entered",        XmCR_COMMAND_ENTERED },
    { "command-changed",        XmCR_COMMAND_CHANGED },
    { "expose",                 XmCR_EXPOSE },
    { "resize",                 XmCR_RESIZE },
    { "input",                  XmCR_INPUT },
    { 0, 0 }
};

Object Get_Any_CB (p) XmAnyCallbackStruct *p; {
    Object args = Null, ret = Null;
    GC_Node2;

    GC_Link2 (ret, args);
    if (p->event) {
        args = Get_Event_Args (p->event);
        ret = Copy_List (args);
        Destroy_Event_Args (args);
    }
    ret = Cons (Bits_To_Symbols ((unsigned long)p->reason, 0, Reason_Syms),
	      ret);
    GC_Unlink;
    return ret;
}

Object Get_Selection_CB (p) XmSelectionBoxCallbackStruct *p; {
    Object ret, s;
    char *text;
    GC_Node2;

    if (!XmStringGetLtoR (p->value, XmSTRING_DEFAULT_CHARSET, &text))
	text = "";
    ret = s = Make_String (text, strlen (text));
    GC_Link2 (ret, s);
    ret = Cons (ret, Null);
    s = Get_Any_CB ((XmAnyCallbackStruct *)p);
    ret = Cons (Cdr (s), ret);
    ret = Cons (Car (s), ret);
    GC_Unlink;
    return ret;
}

static XtArgVal Scheme_To_String_Table (x) Object x; {
    Object t;
    char *s;
    XmString *tab;
    int i = 0;
    Declare_C_Strings;

    tab = (XmString *)XtMalloc (P_Length (x) * sizeof (XmString));
    /* tab is never freed since the converter must return a new address
     * each time it is called.
     */
    for (t = x; TYPE(t) == T_Pair; t = Cdr (t)) {
	Make_C_String (Car (t), s);
	tab[i++] = XmStringCreate (s, XmSTRING_DEFAULT_CHARSET);
    }
    Dispose_C_Strings;
    return (XtArgVal)tab;
}

static Object P_Update_Display (w) Object w; {
   Check_Widget (w);
    XmUpdateDisplay (WIDGET(w)->widget);
    return Void;
}

static Object S_KeySym (x) XtArgVal x; {
   return Make_Char ((int)x);
}

static XtArgVal C_KeySym (x) Object x; {
   Check_Type (x, T_Character); return (XtArgVal)CHAR(x);
}

static Object S_HorizontalPosition (x) XtArgVal x; {
   return Make_Integer ((Position)x);
}

static Object S_VerticalPosition (x) XtArgVal x; {
   return Make_Integer ((Position)x);
}

static Object S_HorizontalDimension (x) XtArgVal x; {
   return Make_Integer ((Position)x);
}

static Object S_VerticalDimension (x) XtArgVal x; {
   return Make_Integer ((Position)x);
}

static XtArgVal C_HorizontalPosition (x) Object x; {
   return (XtArgVal)Get_Integer (x);
}

static XtArgVal C_VerticalPosition (x) Object x; {
   return (XtArgVal)Get_Integer (x);
}

static XtArgVal C_HorizontalDimension (x) Object x; {
   return (XtArgVal)Get_Integer (x);
}

static XtArgVal C_VerticalDimension (x) Object x; {
   return (XtArgVal)Get_Integer (x);
}

static Object S_ShellHorizPos (x) XtArgVal x; {
   return Make_Integer ((Position)x);
}

static Object S_ShellVertPos (x) XtArgVal x; {
   return Make_Integer ((Position)x);
}

static Object S_ShellHorizDim (x) XtArgVal x; {
   return Make_Integer ((Position)x);
}

static Object S_ShellVertDim (x) XtArgVal x; {
   return Make_Integer ((Position)x);
}

static XtArgVal C_ShellHorizPos (x) Object x; {
   return (XtArgVal)Get_Integer (x);
}

static XtArgVal C_ShellVertPos (x) Object x; {
   return (XtArgVal)Get_Integer (x);
}

static XtArgVal C_ShellHorizDim (x) Object x; {
   return (XtArgVal)Get_Integer (x);
}

static XtArgVal C_ShellVertDim (x) Object x; {
   return (XtArgVal)Get_Integer (x);
}

static Object S_HorizontalScrollBar (x) XtArgVal x; {
   return Make_Widget_Foreign ((Widget)x);
}

static Object S_VerticalScrollBar (x) XtArgVal x; {
   return Make_Widget_Foreign ((Widget)x);
}

static Object S_WorkWindow (x) XtArgVal x; {
   return Make_Widget_Foreign ((Widget)x);
}

static Object S_CommandWindow (x) XtArgVal x; {
   return Make_Widget_Foreign ((Widget)x);
}

static Object S_MenuBar (x) XtArgVal x; {
   return Make_Widget_Foreign ((Widget)x);
}

static Object S_SubMenuId (x) XtArgVal x; {
   return Make_Widget_Foreign ((Widget)x);
}

static Object S_MenuHistory (x) XtArgVal x; {
   return Make_Widget_Foreign ((Widget)x);
}

static Object S_MenuHelpWidget (x) XtArgVal x; {
   return Make_Widget_Foreign ((Widget)x);
}

static Object S_BottomWidget (x) XtArgVal x; {
   return Make_Widget_Foreign ((Widget)x);
}

static Object S_LeftWidget (x) XtArgVal x; {
   return Make_Widget_Foreign ((Widget)x);
}

static Object S_RightWidget (x) XtArgVal x; {
   return Make_Widget_Foreign ((Widget)x);
}

static Object S_TopWidget (x) XtArgVal x; {
   return Make_Widget_Foreign ((Widget)x);
}

static XtArgVal C_HorizontalScrollBar (x) Object x; {
   extern WidgetClass xmScrollBarWidgetClass;
    Check_Widget_Class (x, xmScrollBarWidgetClass);
    return (XtArgVal)WIDGET(x)->widget;
}

static XtArgVal C_VerticalScrollBar (x) Object x; {
   extern WidgetClass xmScrollBarWidgetClass;
    Check_Widget_Class (x, xmScrollBarWidgetClass);
    return (XtArgVal)WIDGET(x)->widget;
}

static XtArgVal C_WorkWindow (x) Object x; {
   Check_Widget (x); return (XtArgVal)WIDGET(x)->widget;
}

static XtArgVal C_CommandWindow (x) Object x; {
   Check_Widget (x); return (XtArgVal)WIDGET(x)->widget;
}

static XtArgVal C_MenuBar (x) Object x; {
   Check_Widget (x); return (XtArgVal)WIDGET(x)->widget;
}

static XtArgVal C_SubMenuId (x) Object x; {
   Check_Widget (x); return (XtArgVal)WIDGET(x)->widget;
}

static XtArgVal C_MenuHistory (x) Object x; {
   Check_Widget (x); return (XtArgVal)WIDGET(x)->widget;
}

static XtArgVal C_MenuHelpWidget (x) Object x; {
   Check_Widget (x); return (XtArgVal)WIDGET(x)->widget;
}

static XtArgVal C_BottomWidget (x) Object x; {
   Check_Widget (x); return (XtArgVal)WIDGET(x)->widget;
}

static XtArgVal C_LeftWidget (x) Object x; {
   Check_Widget (x); return (XtArgVal)WIDGET(x)->widget;
}

static XtArgVal C_RightWidget (x) Object x; {
   Check_Widget (x); return (XtArgVal)WIDGET(x)->widget;
}

static XtArgVal C_TopWidget (x) Object x; {
   Check_Widget (x); return (XtArgVal)WIDGET(x)->widget;
}

static Object S_ApplyCallback (x) XtArgVal x; {
   return Get_Selection_CB ((XmSelectionBoxCallbackStruct *)x);
}

static Object S_CancelCallback (x) XtArgVal x; {
   return Get_Selection_CB ((XmSelectionBoxCallbackStruct *)x);
}

static Object S_NoMatchCallback (x) XtArgVal x; {
   return Get_Selection_CB ((XmSelectionBoxCallbackStruct *)x);
}

static Object S_OkCallback (x) XtArgVal x; {
   return Get_Selection_CB ((XmSelectionBoxCallbackStruct *)x);
}

static Object S_HelpCallback (x) XtArgVal x; {
   return Get_Any_CB ((XmAnyCallbackStruct *)x);
}

static Object S_ActivateCallback (x) XtArgVal x; {
   return Get_Any_CB ((XmAnyCallbackStruct *)x);
}

static Object S_ArmCallback (x) XtArgVal x; {
   return Get_Any_CB ((XmAnyCallbackStruct *)x);
}

static Object S_DisarmCallback (x) XtArgVal x; {
   return Get_Any_CB ((XmAnyCallbackStruct *)x);
}

static Object S_CascadingCallback (x) XtArgVal x; {
   return Get_Any_CB ((XmAnyCallbackStruct *)x);
}

static Object S_ExposeCallback (x) XtArgVal x; {
   return Get_Any_CB ((XmAnyCallbackStruct *)x);
}

static Object S_InputCallback (x) XtArgVal x; {
   return Get_Any_CB ((XmAnyCallbackStruct *)x);
}

static Object S_ResizeCallback (x) XtArgVal x; {
   return Get_Any_CB ((XmAnyCallbackStruct *)x);
}

static Object S_XmString (x) XtArgVal x; {
   char *text;
    if (!XmStringGetLtoR ((XmString)x, XmSTRING_DEFAULT_CHARSET, &text))
	text = "";
    return Make_String (text, strlen (text));
}

static XtArgVal C_XmString (x) Object x; {
   char *s;
    Object ret;
    Declare_C_Strings;
    Make_C_String (x, s);
    ret = (XtArgVal)XmStringCreateLtoR (s, XmSTRING_DEFAULT_CHARSET);
    Dispose_C_Strings;
    return ret;
}

static XtArgVal C_XmStringTable (x) Object x; {
   return Scheme_To_String_Table (x);
}

init_support () {
    XtResourceList r = 0;
    Define_Class ("manager", xmManagerWidgetClass, r, 0);
    Define_Class ("primitive", xmPrimitiveWidgetClass, r, 0);
    Define_Primitive (P_Update_Display, "update-display", 1, 1, EVAL);
    Define_Converter_To_C ("XmStringTable", C_XmStringTable);
    Define_Converter_To_C ("XmString", C_XmString);
    Define_Converter_To_Scheme ("XmString", S_XmString);
    Define_Converter_To_Scheme ("resizeCallback", S_ResizeCallback);
    Define_Converter_To_Scheme ("inputCallback", S_InputCallback);
    Define_Converter_To_Scheme ("exposeCallback", S_ExposeCallback);
    Define_Converter_To_Scheme ("cascadingCallback", S_CascadingCallback);
    Define_Converter_To_Scheme ("disarmCallback", S_DisarmCallback);
    Define_Converter_To_Scheme ("armCallback", S_ArmCallback);
    Define_Converter_To_Scheme ("activateCallback", S_ActivateCallback);
    Define_Converter_To_Scheme ("helpCallback", S_HelpCallback);
    Define_Converter_To_Scheme ("okCallback", S_OkCallback);
    Define_Converter_To_Scheme ("noMatchCallback", S_NoMatchCallback);
    Define_Converter_To_Scheme ("cancelCallback", S_CancelCallback);
    Define_Converter_To_Scheme ("applyCallback", S_ApplyCallback);
    Define_Converter_To_C ("topWidget", C_TopWidget);
    Define_Converter_To_C ("rightWidget", C_RightWidget);
    Define_Converter_To_C ("leftWidget", C_LeftWidget);
    Define_Converter_To_C ("bottomWidget", C_BottomWidget);
    Define_Converter_To_C ("menuHelpWidget", C_MenuHelpWidget);
    Define_Converter_To_C ("menuHistory", C_MenuHistory);
    Define_Converter_To_C ("subMenuId", C_SubMenuId);
    Define_Converter_To_C ("menuBar", C_MenuBar);
    Define_Converter_To_C ("commandWindow", C_CommandWindow);
    Define_Converter_To_C ("workWindow", C_WorkWindow);
    Define_Converter_To_C ("verticalScrollBar", C_VerticalScrollBar);
    Define_Converter_To_C ("horizontalScrollBar", C_HorizontalScrollBar);
    Define_Converter_To_Scheme ("topWidget", S_TopWidget);
    Define_Converter_To_Scheme ("rightWidget", S_RightWidget);
    Define_Converter_To_Scheme ("leftWidget", S_LeftWidget);
    Define_Converter_To_Scheme ("bottomWidget", S_BottomWidget);
    Define_Converter_To_Scheme ("menuHelpWidget", S_MenuHelpWidget);
    Define_Converter_To_Scheme ("menuHistory", S_MenuHistory);
    Define_Converter_To_Scheme ("subMenuId", S_SubMenuId);
    Define_Converter_To_Scheme ("menuBar", S_MenuBar);
    Define_Converter_To_Scheme ("commandWindow", S_CommandWindow);
    Define_Converter_To_Scheme ("workWindow", S_WorkWindow);
    Define_Converter_To_Scheme ("verticalScrollBar", S_VerticalScrollBar);
    Define_Converter_To_Scheme ("horizontalScrollBar", S_HorizontalScrollBar);
    Define_Converter_To_C ("ShellVertDim", C_ShellVertDim);
    Define_Converter_To_C ("ShellHorizDim", C_ShellHorizDim);
    Define_Converter_To_C ("ShellVertPos", C_ShellVertPos);
    Define_Converter_To_C ("ShellHorizPos", C_ShellHorizPos);
    Define_Converter_To_Scheme ("ShellVertDim", S_ShellVertDim);
    Define_Converter_To_Scheme ("ShellHorizDim", S_ShellHorizDim);
    Define_Converter_To_Scheme ("ShellVertPos", S_ShellVertPos);
    Define_Converter_To_Scheme ("ShellHorizPos", S_ShellHorizPos);
    Define_Converter_To_C ("VerticalDimension", C_VerticalDimension);
    Define_Converter_To_C ("HorizontalDimension", C_HorizontalDimension);
    Define_Converter_To_C ("VerticalPosition", C_VerticalPosition);
    Define_Converter_To_C ("HorizontalPosition", C_HorizontalPosition);
    Define_Converter_To_Scheme ("VerticalDimension", S_VerticalDimension);
    Define_Converter_To_Scheme ("HorizontalDimension", S_HorizontalDimension);
    Define_Converter_To_Scheme ("VerticalPosition", S_VerticalPosition);
    Define_Converter_To_Scheme ("HorizontalPosition", S_HorizontalPosition);
    Define_Converter_To_C ("KeySym", C_KeySym);
    Define_Converter_To_Scheme ("KeySym", S_KeySym);
}
