home *** CD-ROM | disk | FTP | other *** search
- /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- *
- * The contents of this file are subject to the Netscape Public License
- * Version 1.0 (the "NPL"); you may not use this file except in
- * compliance with the NPL. You may obtain a copy of the NPL at
- * http://www.mozilla.org/NPL/
- *
- * Software distributed under the NPL is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
- * for the specific language governing rights and limitations under the
- * NPL.
- *
- * The Initial Developer of this code under the NPL is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1998 Netscape Communications Corporation. All Rights
- * Reserved.
- */
- /*
- forms.c --- creating and displaying forms widgets
- Created: Jamie Zawinski <jwz@netscape.com>, 21-Jul-94.
- Whacked into a completely new form: Chris Toshok <toshok@netscape.com>, 29-Oct-1997.
- */
-
-
- #include "mozilla.h"
- #include "xfe.h"
- #include "fonts.h"
- #include "felocale.h"
- #include "xpform.h"
- #include "layers.h"
-
- #include <plevent.h> /* for mocha */
- #include <prtypes.h>
- #include <libevent.h>
-
- #include <libi18n.h>
- #include "intl_csi.h"
- #include "fonts.h"
- #ifndef NO_WEB_FONTS
- #include "nf.h"
- #include "Mnfrc.h"
- #include "Mnfrf.h"
- #endif
-
- #include "DtWidgets/ComboBoxP.h"
-
- #include <Xfe/XfeP.h> /* for xfe widgets and utilities */
-
- /* XXX */
- /* #define NO_NEW_DEFAULT_SIZES 1 */
-
- /* for XP_GetString() */
- #include <xpgetstr.h>
- extern int XFE_ERROR_OPENING_FILE;
-
- /* Kludge around conflicts between Motif and xp_core.h... */
- #undef Bool
- #define Bool char
-
- /* #define FORMS_ARE_FONTIFIED */
- /* #define FORMS_ARE_COLORED */
-
-
- /* Kludge kludge kludge, should be in resources... */
- #define fe_FORM_LEFT_MARGIN 0
- #define fe_FORM_RIGHT_MARGIN 0
- #define fe_FORM_TOP_MARGIN 4
- #define fe_FORM_BOTTOM_MARGIN 4
-
- static void fe_form_file_browse_cb (Widget, XtPointer, XtPointer);
- static void fe_activate_submit_cb (Widget, XtPointer, XtPointer);
- static void fe_submit_form_cb (Widget, XtPointer, XtPointer);
- static void fe_reset_form_cb (Widget, XtPointer, XtPointer);
- static void fe_radio_form_cb (Widget, XtPointer, XtPointer);
- static void fe_check_form_cb (Widget, XtPointer, XtPointer);
- static void fe_button_form_cb (Widget, XtPointer, XtPointer);
- static void fe_combo_form_cb(Widget, XtPointer, XtPointer);
- static void fe_got_focus_cb (Widget, XtPointer, XtPointer);
- static void fe_list_form_cb (Widget, XtPointer, XtPointer);
- static void fe_lost_focus_cb (Widget, XtPointer, XtPointer);
- static void fe_mocha_focus_notify_eh (Widget w,
- XtPointer closure,
- XEvent *ev,
- Boolean *cont);
-
- static void fe_key_handler(Widget w, XtPointer client_data, XEvent * xevent, Boolean * bcontinue);
- static void fe_complete_js_event(JSEvent *js_event, XEvent *x_event, XP_Bool do_geometry);
-
- #ifdef DEBUG
- static char * private_precondition_format = "debug: precondition violation at %s:%d\n";
- static char * private_check_format = "debug: check violation at %s:%d\n";
- #endif
-
- typedef struct fe_form_vtable FEFormVtable;
- typedef struct fe_form_data FEFormData;
-
- struct fe_form_vtable
- {
- void (*create_widget_func)(FEFormData *, LO_FormElementStruct *);
- void (*get_size_func)(FEFormData *, LO_FormElementStruct *);
- void (*element_is_submit_func)(FEFormData *, LO_FormElementStruct *);
- void (*display_element_func)(FEFormData *, LO_FormElementStruct *);
- void (*get_element_value)(FEFormData *, LO_FormElementStruct *, XP_Bool);
- void (*free_element_func)(FEFormData *, LO_FormElementData *);
- void (*reset_element)(FEFormData *, LO_FormElementStruct *);
- void (*select_element_func)(FEFormData *, LO_FormElementStruct *);
- void (*change_element_func)(FEFormData *, LO_FormElementStruct *);
- void (*focus_element_func)(FEFormData *, LO_FormElementStruct *);
- void (*lost_focus_func)(FEFormData *);
- };
-
- struct fe_form_data {
- FEFormVtable vtbl;
- LO_FormElementStruct *form;
- Widget widget;
- MWContext *context;
- };
-
- typedef struct {
- FEFormData form_data;
-
- Widget rowcolumn;
- Widget browse_button;
- Widget file_widget;
- } FEFileFormData;
-
- typedef struct {
- FEFormData form_data;
-
- Widget text_widget; /* form_data.widget is the scrolled window. */
- } FETextAreaFormData;
-
- typedef struct {
- FEFormData form_data;
-
- Widget list_widget; /* form_data.widget is the scrolled window. */
- int nkids;
- char *selected_p;
- } FESelectMultFormData;
-
- typedef FESelectMultFormData FESelectOneFormData;
-
- static FEFormData* alloc_form_data(int32 type);
-
- static void text_create_widget(FEFormData *, LO_FormElementStruct *);
- static void text_display(FEFormData *, LO_FormElementStruct *);
- static void text_get_value(FEFormData *, LO_FormElementStruct *, XP_Bool);
- static void text_reset(FEFormData *, LO_FormElementStruct *);
- static void text_change(FEFormData *, LO_FormElementStruct *);
- static void text_focus(FEFormData *, LO_FormElementStruct *);
- static void text_lost_focus(FEFormData *);
- static void text_select(FEFormData *, LO_FormElementStruct *);
-
- static void file_create_widget(FEFormData *, LO_FormElementStruct *);
- static void file_get_value(FEFormData *, LO_FormElementStruct *, XP_Bool);
- static void file_free(FEFormData *, LO_FormElementData *);
-
- static void button_create_widget(FEFormData *, LO_FormElementStruct *);
-
- static void checkbox_create_widget(FEFormData *, LO_FormElementStruct *);
- static void checkbox_get_value(FEFormData *, LO_FormElementStruct *, XP_Bool);
- static void checkbox_change(FEFormData *, LO_FormElementStruct *);
-
- static void select_create_widget(FEFormData *, LO_FormElementStruct *);
- static void select_get_value(FEFormData *, LO_FormElementStruct *, XP_Bool);
- static void select_free(FEFormData *, LO_FormElementData *);
- static void select_reset(FEFormData *, LO_FormElementStruct *);
- static void select_change(FEFormData *, LO_FormElementStruct *);
-
- static void textarea_create_widget(FEFormData *, LO_FormElementStruct *);
- static void textarea_display(FEFormData *, LO_FormElementStruct *);
- static void textarea_get_value(FEFormData *, LO_FormElementStruct *, XP_Bool);
- static void textarea_reset(FEFormData *, LO_FormElementStruct *);
- static void textarea_lost_focus(FEFormData *);
-
- static void form_element_display(FEFormData *, LO_FormElementStruct *);
- static void form_element_get_size(FEFormData *, LO_FormElementStruct *);
- static void form_element_is_submit(FEFormData *, LO_FormElementStruct *);
- static void form_element_get_value(FEFormData *, LO_FormElementStruct *,
- XP_Bool);
- static void form_element_free(FEFormData *, LO_FormElementData *);
-
-
- /* doubles as both the text and password vtable */
- static FEFormVtable text_form_vtable = {
- text_create_widget,
- form_element_get_size,
- form_element_is_submit,
- text_display,
- text_get_value,
- form_element_free,
- text_reset,
- text_select,
- text_change,
- text_focus,
- text_lost_focus
- };
-
- static FEFormVtable file_form_vtable = {
- file_create_widget,
- form_element_get_size,
- form_element_is_submit,
- text_display,
- file_get_value,
- file_free,
- text_reset,
- text_select,
- text_change,
- text_focus,
- text_lost_focus
- };
-
- static FEFormVtable button_form_vtable = {
- button_create_widget,
- form_element_get_size,
- NULL,
- form_element_display,
- form_element_get_value,
- form_element_free,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL
- };
-
- static FEFormVtable checkbox_form_vtable = {
- checkbox_create_widget,
- form_element_get_size,
- NULL,
- form_element_display,
- checkbox_get_value,
- form_element_free,
- NULL,
- NULL,
- checkbox_change,
- NULL,
- NULL
- };
-
- static FEFormVtable selectone_form_vtable = {
- select_create_widget,
- form_element_get_size,
- NULL,
- form_element_display,
- select_get_value,
- select_free,
- select_reset,
- NULL,
- select_change,
- NULL,
- NULL
- };
-
- static FEFormVtable selectmult_form_vtable = {
- select_create_widget,
- form_element_get_size,
- NULL,
- form_element_display,
- select_get_value,
- select_free,
- select_reset,
- NULL,
- select_change,
- NULL,
- NULL
- };
-
- static FEFormVtable textarea_form_vtable = {
- textarea_create_widget,
- form_element_get_size,
- NULL,
- textarea_display,
- textarea_get_value,
- form_element_free,
- textarea_reset,
- text_select,
- text_change,
- text_focus,
- textarea_lost_focus
- };
-
- /*
- ** Why are these next two functions in this file?
- */
-
- /*
- * Raise the window to the top of the view order
- */
- void
- FE_RaiseWindow(MWContext *context)
- {
- #ifdef DEBUG_username
- printf ("RaiseWindow: context 0x%x\n", context);
- #endif
- XtRealizeWidget (CONTEXT_WIDGET (context));
- XtManageChild (CONTEXT_WIDGET (context));
- /* XXX Uniconify the window if it was iconified */
- XMapRaised(XtDisplay(CONTEXT_WIDGET(context)),
- XtWindow(CONTEXT_WIDGET(context)));
- XtPopup(CONTEXT_WIDGET(context),XtGrabNone);
- }
-
- /*
- * Lower the window to the bottom of the view order
- */
- void
- FE_LowerWindow(MWContext *context)
- {
- #ifdef DEBUG_username
- printf ("LowerWindow: context 0x%x\n", context);
- #endif
- if (!XtIsRealized(CONTEXT_WIDGET(context)))
- return;
-
- XLowerWindow(XtDisplay(CONTEXT_WIDGET(context)),
- XtWindow(CONTEXT_WIDGET(context)));
- }
-
- static void
- fe_font_list_metrics(MWContext *context, LO_FormElementStruct *form,
- XmFontList font_list, int *ascentp, int *descentp)
- {
- fe_Font font;
- LO_TextAttr *text = XP_GetFormTextAttr(form);
-
- font = fe_LoadFontFromFace(context,text, &text->charset,
- text->font_face,
- text->size, text->fontmask);
- if (!font)
- {
- *ascentp = 14;
- *descentp = 3;
- return;
- }
- FE_FONT_EXTENTS(text->charset, font, ascentp, descentp);
- }
-
- static void
- fe_FontlistAndXmStringForFormElement(MWContext *context,
- int32 form_type,
- char *string,
- LO_TextAttr *text_attr,
- XmString *xmstring,
- XmFontList *fontlist)
- {
- Widget parent = CONTEXT_DATA(context)->drawing_area;
- XP_Bool use_UnicodePseudoFont;
- fe_Font fe_font;
- XmFontType type = 0; /* keep purify happy */
- XmFontListEntry flentry;
- int mask = text_attr->fontmask;
- XmFontList unicodePseudo_font_list = NULL;
- XmFontList locale_font_list = NULL;
-
- use_UnicodePseudoFont = IS_UNICODE_CSID(text_attr->charset);
-
- #ifdef DEBUG_username
- printf ("fe_FontlistAndXmStringForFormElement(%s)\n", string);
- #endif
-
- switch (form_type)
- {
- case FORM_TYPE_FILE:
- case FORM_TYPE_TEXT:
- case FORM_TYPE_PASSWORD:
- case FORM_TYPE_TEXTAREA:
- case FORM_TYPE_READONLY:
- /* Make sure text fields are non-bold, non-italic, fixed. */
- mask &= (~ (LO_FONT_BOLD|LO_FONT_ITALIC));
- mask |= LO_FONT_FIXED;
- use_UnicodePseudoFont = FALSE; /* XmText doesn't use XmString */
- break;
- default:
- break;
- }
-
- /*
- * Get the font info
- */
- if (use_UnicodePseudoFont)
- {
- fe_font = fe_LoadUnicodeFont(NULL, "", 0, text_attr->size, mask,
- 0, 0, 0, XtDisplay(parent));
-
- *fontlist = unicodePseudo_font_list;
- }
- else
- {
- fe_font = fe_GetFontOrFontSetFromFace(context, NULL,
- text_attr->font_face,
- text_attr->size,
- mask, &type);
- if (!fe_font)
- return;
- flentry = XmFontListEntryCreate(XmFONTLIST_DEFAULT_TAG, type, fe_font);
- if (!flentry)
- return;
- locale_font_list = XmFontListAppendEntry(NULL, flentry);
- if (!locale_font_list)
- return;
- XmFontListEntryFree(&flentry);
-
- if (xmstring)
- *xmstring = NULL;
-
- *fontlist = locale_font_list;
- }
-
- if (string && xmstring)
- *xmstring = fe_ConvertToXmString((unsigned char*)string,
- text_attr->charset,
- fe_font,
- type,
- fontlist);
- }
-
- static void
- set_form_colors(FEFormData *fed,
- LO_Color *lo_fg,
- LO_Color *lo_bg)
- {
- Widget parent = CONTEXT_DATA (fed->context)->drawing_area;
- Pixel fg, bg;
-
- fg = fe_GetPixel (fed->context, lo_fg->red, lo_fg->green, lo_fg->blue);
- bg = fe_GetPixel (fed->context, lo_bg->red, lo_bg->green, lo_bg->blue);
-
- if (fg == bg)
- {
- /* the foreground and background are the same. Try to
- choose something that will make things readable
- (if a little ugly) */
-
- XmGetColors(XtScreen(parent),
- XfeColormap(parent),
- bg,
- &fg, NULL, NULL, NULL);
- }
-
- XtVaSetValues(fed->widget,
- XmNforeground, fg,
- XmNbackground, bg,
- NULL);
- }
-
- static void
- get_form_colors(FEFormData *fed,
- LO_Color *lo_fg,
- LO_Color *lo_bg,
- Pixel *fg_r, Pixel *bg_r)
- {
- Widget parent = CONTEXT_DATA (fed->context)->drawing_area;
- Pixel fg, bg;
-
- fg = fe_GetPixel (fed->context, lo_fg->red, lo_fg->green, lo_fg->blue);
- bg = fe_GetPixel (fed->context, lo_bg->red, lo_bg->green, lo_bg->blue);
-
- if (fg == bg)
- {
- /* the foreground and background are the same. Try to
- choose something that will make things readable
- (if a little ugly) */
-
- XmGetColors(XtScreen(parent),
- XfeColormap(parent),
- bg,
- &fg, NULL, NULL, NULL);
- }
-
- *fg_r = fg;
- *bg_r = bg;
- }
-
- /* Motif likes to complain when there are binary characters in
- text strings.
- */
- void
- fe_forms_clean_text (MWContext *context,
- int charset,
- char *text,
- Boolean newlines_too_p)
- {
- unsigned char *t = (unsigned char *) text;
- for (; *t; t++)
- {
- unsigned char c = *t;
- if ((newlines_too_p && (c == '\n' || c == '\r')) ||
- (c < ' ' && c != '\t' && c != '\n' && c != '\r') ||
- (c == 0x7f) ||
- ((INTL_CharSetType(charset) == SINGLEBYTE) &&
- (0x7f <= c) && (c <= 0xa0)))
- *t = ' ';
- }
- }
-
- static void fe_HackTextTranslations_addCallbacks(Widget widget)
- {
- #if 0
- /* make sure it gets added only once */
- XtRemoveCallback(widget,
- XmNmodifyVerifyCallback,
- fe_textModifyVerifyCallback,
- NULL);
- XtRemoveCallback(widget,
- XmNmotionVerifyCallback,
- fe_textMotionVerifyCallback,
- NULL);
- #endif
- XtAddCallback(widget,
- XmNmotionVerifyCallback,
- fe_textMotionVerifyCallback,
- NULL);
- XtAddCallback(widget,
- XmNmodifyVerifyCallback,
- fe_textModifyVerifyCallback,
- NULL);
- XtVaSetValues(widget,
- XmNverifyBell,False,
- NULL);
- }
-
- /*
- * A list key event handler.
- * This will search for a key in the XmList and shift the location cursor
- * to a match.
- */
- static void
- fe_list_find_eh(Widget widget, XtPointer closure, XEvent* event,
- Boolean* continue_to_dispatch)
- {
- MWContext *context = (MWContext *) closure;
- Boolean usedEvent_p = False;
-
- Modifiers mods;
- KeySym k;
- char *s;
- int i;
- int index; /* index is 1 based */
- XmString *items;
- int nitems;
-
- #define MILLI_500_SECS 500
- #define _LIST_MAX_CHARS 100
- static char input[_LIST_MAX_CHARS] = {0};
- static Time prev_time;
- static Widget w = 0;
- static Boolean is_prev_found = False;
-
- if (!context || !event) return;
-
- fe_UserActivity (context);
-
- if (event->type == KeyPress) {
- if (!(k = XtGetActionKeysym (event, &mods))) return;
- if (!(s = XKeysymToString (k))) return;
- if (!s || !*s || s[1]) return; /* no or more than 1 char */
- if (!isprint(*s)) return; /* unprintable */
-
- if ((widget == w) && (event->xkey.time - prev_time < MILLI_500_SECS)) {
- /* Continue search */
- if (is_prev_found) strcat(input, s);
- else return;
- }
- else {
- /* Fresh search */
- is_prev_found = False;
- strcpy(input, s);
- }
- w = widget;
- prev_time = event->xkey.time;
- index = XmListGetKbdItemPos(widget);
- if (!index) return; /* List is empty */
-
- /* Wrap search for input[] in List */
- i = index;
- i = (i == nitems) ? 1 : i+1; /* Increment i */
- XtVaGetValues(widget, XmNitems, &items, XmNitemCount, &nitems, 0);
- while (i != index) {
- if (!XmStringGetLtoR(items[i-1], XmSTRING_DEFAULT_CHARSET, &s))
- continue;
- if (!strncmp(s, input, strlen(input))) {
- /* Found */
- XP_FREE(s);
- XmListSetKbdItemPos(widget, i);
- is_prev_found = True;
- break;
- }
- XP_FREE(s);
- i = (i == nitems) ? 1 : i+1; /* Increment i */
- }
- usedEvent_p = True;
- }
-
- if (usedEvent_p) *continue_to_dispatch = False;
- }
-
- /*
- **
- ** VTABLE for "superclass", form_element.
- **
- */
- static void
- form_element_display(FEFormData *fed,
- LO_FormElementStruct *form)
- {
- MWContext *context = fed->context;
- Arg av[10];
- int ac;
- uint16 attrmask = XP_GetFormEleAttrmask(form);
- Position x;
- Position y;
-
- x = (form->x + form->x_offset
- - CONTEXT_DATA (context)->document_x);
- y = (form->y + form->y_offset
- - CONTEXT_DATA (context)->document_y);
- x += fe_FORM_LEFT_MARGIN;
- y += fe_FORM_TOP_MARGIN;
-
- if (!XtIsManaged(fed->widget))
- {
- Dimension bw = 0;
- Dimension width = form->width;
- Dimension height = form->height;
-
- XtVaGetValues (fed->widget, XmNborderWidth, &bw, 0);
- /* Since I told layout that width was width+bw+bw (for its sizing and
- positioning purposes), subtract it out again when setting the size of
- the text area. X thinks the borders are outside the WxH rectangle,
- not inside, but thinks that the borders are below and to the right of
- the X,Y origin, instead of up and to the left as you would expect
- given the WxH behavior!!
- */
- width -= (bw * 2);
- height -= (bw * 2);
- /* x += bw; */
- /* y += bw;*/
-
- width -= fe_FORM_LEFT_MARGIN + fe_FORM_RIGHT_MARGIN;
- height -= fe_FORM_TOP_MARGIN + fe_FORM_BOTTOM_MARGIN;
-
- /*
- * Move to 0 before moving to where we want so it ends up
- * where we want.
- */
- ac = 0;
- XtSetArg (av [ac], XmNx, 0); ac++;
- XtSetArg (av [ac], XmNy, 0); ac++;
- XtSetValues (fed->widget, av, ac);
-
-
- #ifdef DEBUG_username
- printf ("DisplayFormElement: width = %d; height = %d\n", width, height);
- #endif
-
- ac = 0;
- XtSetArg (av [ac], XmNx, (Position)x); ac++;
- XtSetArg (av [ac], XmNy, (Position)y); ac++;
- XtSetArg (av [ac], XmNwidth, (Dimension)width); ac++;
- XtSetArg (av [ac], XmNheight, (Dimension)height); ac++;
- XtSetValues (fed->widget, av, ac);
-
- XtSetMappedWhenManaged(fed->widget,
- !(attrmask & LO_ELE_INVISIBLE));
-
- XtManageChild (fed->widget);
- }
- else
- {
- XtSetMappedWhenManaged(fed->widget,
- !(attrmask & LO_ELE_INVISIBLE));
-
- XtMoveWidget(fed->widget, x, y);
- }
- }
-
- static void
- form_element_get_size(FEFormData *fed,
- LO_FormElementStruct *form)
- {
- MWContext *context = fed->context;
- Dimension width = 0;
- Dimension height = 0;
- Dimension bw = 0;
- Dimension st = 0;
- Dimension ht = 0;
- Dimension margin_height = 0;
- Dimension bottom = 0;
- int ascent, descent;
- XmFontList font_list;
- LO_FormElementData *form_data = XP_GetFormElementData(form);
- int32 form_type = XP_FormGetType(form_data);
- Widget element_widget;
-
- if (form_type == FORM_TYPE_FILE)
- element_widget = ((FEFileFormData*)fed)->rowcolumn;
- else
- element_widget = fed->widget;
-
- font_list = 0;
- XtVaGetValues (element_widget, XmNfontList, &font_list, 0);
-
- fe_HackTranslations (context, element_widget);
-
- fe_font_list_metrics (context, form, font_list, &ascent, &descent);
-
- XtRealizeWidget(element_widget);
-
- if (fe_globalData.fe_guffaw_scroll == 1)
- {
- XSetWindowAttributes attr;
- unsigned long valuemask;
-
- valuemask = CWBitGravity | CWWinGravity;
- attr.win_gravity = StaticGravity;
- attr.bit_gravity = StaticGravity;
- XChangeWindowAttributes (XtDisplay (element_widget),
- XtWindow (element_widget),
- valuemask, &attr);
- }
-
- XtVaGetValues (element_widget,
- XmNwidth, &width,
- XmNheight, &height,
- XmNborderWidth, &bw,
- XmNshadowThickness, &st,
- XmNhighlightThickness, &ht,
- XmNmarginHeight, &margin_height,
- XmNmarginBottom, &bottom,
- 0);
-
- #ifdef DEBUG_username
- printf ("form before: width = %d; height = %d\n", width, height);
- #endif
- width += fe_FORM_LEFT_MARGIN + fe_FORM_RIGHT_MARGIN;
- height += fe_FORM_TOP_MARGIN + fe_FORM_BOTTOM_MARGIN;
-
- /* The WxH doesn't take into account the border width; so add that in
- for layout's benefit. We subtract it again later. */
- width += (bw * 2);
- height += (bw * 2);
- #ifdef DEBUG_username
- printf ("form after: width = %d; height = %d\n", width, height);
- #endif
- form->width = width;
- form->height = height;
-
- /* Yeah. Uh huh. */
- if (form_type == FORM_TYPE_RADIO ||
- form_type == FORM_TYPE_CHECKBOX)
- {
- bottom = 0;
- descent = bw;
- }
-
- form->baseline = height - (bottom + margin_height + st + bw + ht + descent
- + fe_FORM_BOTTOM_MARGIN);
- }
-
- static void
- form_element_is_submit(FEFormData *fed,
- LO_FormElementStruct *form)
- {
- XtRemoveCallback (fed->widget,
- XmNactivateCallback, fe_activate_submit_cb, fed);
-
- XtAddCallback (fed->widget,
- XmNactivateCallback, fe_activate_submit_cb, fed);
-
- if (fe_globalData.terminal_text_translations)
- XtOverrideTranslations (fed->widget,
- fe_globalData.terminal_text_translations);
- }
-
- static void
- form_element_get_value(FEFormData *fed,
- LO_FormElementStruct *form,
- XP_Bool delete_p)
- {
- if (delete_p)
- {
- XtDestroyWidget(fed->widget);
- fed->widget = 0;
- }
- }
-
- static void
- form_element_free(FEFormData *fed,
- LO_FormElementData *form)
- {
- if (fed->widget)
- XtDestroyWidget(fed->widget);
-
- fed->widget = 0;
-
- XP_FREE(fed);
- }
-
- /*
- **
- ** VTABLE for Text like form elements (TEXT, TEXTAREA, and FILE)
- **
- */
- static void
- text_create_widget(FEFormData *fed,
- LO_FormElementStruct *form)
- {
- MWContext *context = fed->context;
- Widget parent;
- int16 charset;
- LO_FormElementData *form_data;
- int32 form_type;
- int32 text_size;
- int32 max_size;
- int columns;
- char *tmp_text = 0;
- char *text;
- unsigned char *loc;
- XmFontList font_list;
- Arg av [50];
- int ac;
- LO_TextAttr *text_attr;
-
- parent = CONTEXT_DATA (context)->drawing_area;
- form_data = XP_GetFormElementData(form);
- form_type = XP_FormGetType(form_data);
- text_size = XP_FormTextGetSize(form_data);
- max_size = XP_FormTextGetMaxSize(form_data);
- text_attr = XP_GetFormTextAttr(form);
- text = (char*)XP_FormGetDefaultText(form_data);
- charset = text_attr->charset;
-
- /* from bstell: in multibyte (asian) locales, characters tend to be twice
- as wide as in non-multibyte locales. To make things look correct,
- we divide the column number in half in those cases. */
- columns = ((fe_LocaleCharSetID & MULTIBYTE) ?
- (text_size + 1) / 2 : text_size);
-
- /* the default size for text fields is 20 columns.
- XX Shouldn't the backend just fill it in with 20? */
- if (columns == 0) columns = 20;
-
-
- if (!text) text = "";
-
- if (max_size > 0 && (int) XP_STRLEN (text) >= max_size) {
- tmp_text = XP_STRDUP (text);
- tmp_text [max_size] = '\0';
- text = tmp_text;
- }
-
- fe_forms_clean_text (context, charset, text, True);
-
- fe_FontlistAndXmStringForFormElement(context,
- form_type,
- text,
- text_attr,
- NULL,
- &font_list);
- if (!font_list)
- return;
-
- ac = 0;
- /* Ok, let's try using the fixed font for text areas only. */
- /*#ifdef FORMS_ARE_FONTIFIED*/
- XtSetArg (av [ac], XmNfontList, font_list); ac++;
- /*#endif*/
- XtSetArg (av [ac], XmNcolumns, columns); ac++;
-
- if (form_type == FORM_TYPE_READONLY)
- {
- XtSetArg (av [ac], XmNeditable, False); ac++;
- XtSetArg (av [ac], XmNcursorPositionVisible, False); ac++;
- }
-
- if (max_size > 0)
- {
- XtSetArg (av [ac], XmNmaxLength, max_size); ac++;
- }
-
- fed->widget = fe_CreateTextField (parent, "textForm", av, ac);
-
- /*#ifdef FORMS_ARE_COLORED*/
- if (form_type == FORM_TYPE_READONLY)
- set_form_colors(fed, &text_attr->fg, &text_attr->bg);
- /*#endif*/
-
- /* Install in javascript form elemement text field translation */
- fe_HackFormTextTranslations(fed->widget);
-
- XtAddCallback(fed->widget, XmNlosingFocusCallback,
- fe_lost_focus_cb, fed);
- XtAddCallback(fed->widget, XmNfocusCallback, fe_got_focus_cb, fed);
-
-
- /* This is changed later for self-submitting fields. */
- if (fe_globalData.nonterminal_text_translations)
- XtOverrideTranslations (fed->widget, fe_globalData.
- nonterminal_text_translations);
-
- if (form_type == FORM_TYPE_PASSWORD)
- {
- fe_SetupPasswdText (fed->widget, (max_size > 0 ? max_size : 1024));
- fe_MarkPasswdTextAsFormElement(fed->widget);
- }
-
- /* Must be after passwd setup. */
- XtVaSetValues (fed->widget, XmNcursorPosition, 0, 0);
- loc = fe_ConvertToLocaleEncoding (charset, (unsigned char *)text);
- /* Add verify callbacks to implement JS key events */
- fe_HackTextTranslations_addCallbacks(fed->widget);
- /*
- * I don't know whether it is SGI or some version of Motif,but
- * doing a XtVaSetValues() here will execute the
- * valueChangedCallback but ignore its changes.
- * XmTextFieldSetString() works as expected.
- */
- XmTextFieldSetString (fed->widget, loc);
- if (((char *) loc) != text) {
- XP_FREE (loc);
- }
- if (tmp_text) XP_FREE (tmp_text);
- }
-
- static void
- text_display(FEFormData *fed,
- LO_FormElementStruct *form)
- {
- MWContext *context = fed->context;
- Widget widget_to_manage;
- uint16 attrmask = XP_GetFormEleAttrmask(form);
- LO_FormElementData *form_data = XP_GetFormElementData(form);
- Position x;
- Position y;
- Arg av[10];
- int ac = 0;
- unsigned char *loc = 0;
- char *current_text = (char*)XP_FormGetCurrentText(form_data);
- int32 max_size = XP_FormTextGetMaxSize(form_data);
- int32 form_type = XP_FormGetType(form_data);
- LO_TextAttr *text_attr = XP_GetFormTextAttr(form);
- uint16 charset = text_attr->charset;
-
- x = (form->x + form->x_offset
- - CONTEXT_DATA (context)->document_x);
- y = (form->y + form->y_offset
- - CONTEXT_DATA (context)->document_y);
- x += fe_FORM_LEFT_MARGIN;
- y += fe_FORM_TOP_MARGIN;
-
- if (form_type == FORM_TYPE_FILE)
- widget_to_manage = ((FEFileFormData*)fed)->rowcolumn;
- else
- widget_to_manage = fed->widget;
-
- if (!XtIsManaged(widget_to_manage))
- {
- Dimension bw = 0;
- Dimension width = form->width;
- Dimension height = form->height;
-
- XtVaGetValues (widget_to_manage, XmNborderWidth, &bw, 0);
- /* Since I told layout that width was width+bw+bw (for its sizing and
- positioning purposes), subtract it out again when setting the size of
- the text area. X thinks the borders are outside the WxH rectangle,
- not inside, but thinks that the borders are below and to the right of
- the X,Y origin, instead of up and to the left as you would expect
- given the WxH behavior!!
- */
- width -= (bw * 2);
- height -= (bw * 2);
- /* x += bw; */
- /* y += bw;*/
-
- width -= fe_FORM_LEFT_MARGIN + fe_FORM_RIGHT_MARGIN;
- height -= fe_FORM_TOP_MARGIN + fe_FORM_BOTTOM_MARGIN;
-
- if (max_size > 0)
- {
- XtSetArg (av [ac], XmNmaxLength, max_size); ac++;
- }
-
- if (form_type == FORM_TYPE_TEXT) {
- if (current_text) {
- loc = fe_ConvertToLocaleEncoding (charset,
- (unsigned char *)current_text);
- XtSetArg (av[ac], XmNvalue, loc); ac++;
- }
- }
-
- if (ac)
- XtSetValues(widget_to_manage, av, ac);
-
- ac = 0;
- XtSetArg (av [ac], XmNx, x); ac++;
- XtSetArg (av [ac], XmNy, y); ac++;
- XtSetArg (av [ac], XmNwidth, width); ac++;
- XtSetArg (av [ac], XmNheight, height); ac++;
- XtSetValues (widget_to_manage, av, ac);
-
- XtSetMappedWhenManaged(widget_to_manage,
- !(attrmask & LO_ELE_INVISIBLE));
-
- XtManageChild(widget_to_manage);
- }
- else
- {
- XtSetMappedWhenManaged(widget_to_manage,
- !(attrmask & LO_ELE_INVISIBLE));
-
- XtMoveWidget(widget_to_manage, x, y);
- }
- }
-
- static void
- text_get_value(FEFormData *fed,
- LO_FormElementStruct *form,
- XP_Bool delete_p)
- {
- MWContext *context = fed->context;
- INTL_CharSetInfo c = LO_GetDocumentCharacterSetInfo(context);
- LO_FormElementData *form_data = XP_GetFormElementData(form);
- char *text = 0;
- int32 form_type;
- PA_Block new_current;
- PA_Block cur_current;
- PA_Block default_txt;
-
- form_type = XP_FormGetType(form_data);
-
- if (form_type == FORM_TYPE_TEXT)
- {
- /* gross, since for password type form elements, we get back a malloc'ed
- area of memory, and for text form elements, we get XtMalloc'ed. */
- char *non_motif_text = NULL;
- XtVaGetValues (fed->widget, XmNvalue, &text, 0);
- if (text != NULL)
- {
- non_motif_text = XP_STRDUP(text);
- XtFree(text);
- }
- text = non_motif_text;
- }
- else if (form_type == FORM_TYPE_PASSWORD)
- text = fe_GetPasswdText (fed->widget);
-
- cur_current = XP_FormGetCurrentText(form_data);
- default_txt = XP_FormGetDefaultText(form_data);
-
- if (cur_current && cur_current != default_txt)
- free ((char*)cur_current);
-
- new_current = (PA_Block)fe_ConvertFromLocaleEncoding(INTL_GetCSIWinCSID(c),
- (unsigned char *)text);
-
- XP_FormSetCurrentText(form_data, new_current);
-
- if ((char*)new_current != text)
- free (text);
-
- form_element_get_value(fed, form, delete_p);
- }
-
- static void
- text_reset(FEFormData *fed,
- LO_FormElementStruct *form)
- {
- LO_FormElementData *form_data = XP_GetFormElementData(form);
- char *default_text = (char*)XP_FormGetDefaultText(form_data);
- LO_TextAttr *text_attr = XP_GetFormTextAttr(form);
- char *tmp_text = 0;
- unsigned char *loc;
- int16 charset = text_attr->charset;
- Widget w = fed->widget;
- int32 max_size = XP_FormTextGetMaxSize(form_data);
- int32 form_type;
-
- form_type = XP_FormGetType(form_data);
-
- if (!default_text) default_text = "";
-
- if (max_size > 0 && (int) XP_STRLEN (default_text) >= max_size)
- {
- tmp_text = XP_STRDUP (default_text);
- tmp_text [max_size] = '\0';
- default_text = tmp_text;
- }
-
- fe_forms_clean_text (fed->context, charset, default_text, True);
-
- XtVaSetValues (w, XmNcursorPosition, 0, 0);
-
- loc = fe_ConvertToLocaleEncoding (charset, (unsigned char*)default_text);
- /*
- * I don't know whether it is SGI or some version of Motif,
- * but doing a XtVaSetValues() here will execute the
- * valueChangedCallback but ignore its changes.
- * XmTextFieldSetString() works as expected.
- */
- XmTextFieldSetString (w, loc);
- if (((char *) loc) != default_text)
- {
- XP_FREE (loc);
- }
-
- if (tmp_text) XP_FREE (tmp_text);
- }
-
- static void
- text_change(FEFormData *fed,
- LO_FormElementStruct *form)
- {
- LO_FormElementData *form_data = XP_GetFormElementData(form);
- int32 form_type = XP_FormGetType(form_data);
- char *text = (char*)XP_FormGetCurrentText(form_data);
- LO_TextAttr *text_attr = XP_GetFormTextAttr(form);
- unsigned char *loc;
- int16 charset = text_attr->charset;
-
- if (!text) text = (char*)XP_FormGetDefaultText(form_data);
- loc = fe_ConvertToLocaleEncoding(charset, (unsigned char*)text);
-
- if (form_type == FORM_TYPE_TEXTAREA)
- XmTextSetString(fed->widget, loc);
- else
- XmTextFieldSetString(fed->widget, loc);
-
- if (((char *) loc) != text)
- {
- XP_FREE (loc);
- }
- }
-
- static void
- text_select(FEFormData *fed,
- LO_FormElementStruct *form)
- {
- XmTextSetSelection (fed->widget, 0,
- XmTextGetMaxLength (fed->widget), CurrentTime);
- }
-
- static void
- text_focus(FEFormData *fed,
- LO_FormElementStruct *form)
- {
- XmProcessTraversal(fed->widget, XmTRAVERSE_CURRENT);
- }
-
- static void
- text_lost_focus(FEFormData *fed)
- {
- LO_FormElementData *form_data;
- char *text;
- XP_Bool text_changed = False;
- int32 form_type;
- PA_Block current_text;
- JSEvent *event;
-
- form_data = XP_GetFormElementData(fed->form);
- form_type = XP_FormGetType(form_data);
-
- if (form_type == FORM_TYPE_READONLY) return;
-
- current_text = XP_FormGetCurrentText(form_data);
-
- if (form_type == FORM_TYPE_PASSWORD)
- text = fe_GetPasswdText (fed->widget);
- else
- XtVaGetValues (fed->widget, XmNvalue, &text, 0);
-
- if (!current_text || XP_STRCMP((char*)current_text, text))
- text_changed = True;
-
- if (((char*) current_text) != text) {
- XtFree (text);
- }
-
- /* if the text has changed, call get_element_value to copy it into the form
- element, and send a CHANGE event to the javascript thread. */
- if (text_changed)
- {
- (*fed->vtbl.get_element_value)(fed, fed->form, FALSE);
-
- event = XP_NEW_ZAP(JSEvent);
-
- event->type = EVENT_CHANGE;
-
- ET_SendEvent (fed->context, (LO_Element *) fed->form, event,
- NULL, NULL);
- }
- }
-
- /*
- **
- ** VTABLE for the FILE form element.
- **
- */
- static void
- file_create_widget(FEFormData *fed,
- LO_FormElementStruct *form)
- {
- FEFileFormData *filefed = (FEFileFormData*)fed;
- MWContext *context = fed->context;
- Widget parent;
- int16 charset;
- LO_FormElementData *form_data;
- int32 form_type;
- int32 text_size;
- int32 max_size;
- int columns;
- char *tmp_text = 0;
- char *text;
- unsigned char *loc;
- XmFontList font_list;
- Arg av [50];
- int ac;
- LO_TextAttr *text_attr;
- Pixel fg, bg;
-
- parent = CONTEXT_DATA (context)->drawing_area;
- form_data = XP_GetFormElementData(form);
- form_type = XP_FormGetType(form_data);
- text_size = XP_FormTextGetSize(form_data);
- max_size = XP_FormTextGetMaxSize(form_data);
- text_attr = XP_GetFormTextAttr(form);
- text = (char*)XP_FormGetDefaultText(form_data);
- charset = text_attr->charset;
-
- /* from bstell: in multibyte (asian) locales, characters tend to be twice
- as wide as in non-multibyte locales. To make things look correct,
- we divide the column number in half in those cases. */
- columns = ((fe_LocaleCharSetID & MULTIBYTE) ?
- (text_size + 1) / 2 : text_size);
-
- /* the default size for text fields is 20 columns.
- XX Shouldn't the backend just fill it in with 20? */
- if (columns == 0) columns = 20;
-
-
- if (!text) text = "";
-
- if (max_size > 0 && (int) XP_STRLEN (text) >= max_size) {
- tmp_text = XP_STRDUP (text);
- tmp_text [max_size] = '\0';
- text = tmp_text;
- }
-
- fe_forms_clean_text (context, charset, text, True);
-
- fe_FontlistAndXmStringForFormElement(context,
- form_type,
- text,
- text_attr,
- NULL,
- &font_list);
- if (!font_list)
- return;
-
- get_form_colors(fed, &text_attr->fg, &text_attr->bg, &fg, &bg);
-
- /* Create a RowColumn widget to handle both the text and its
- associated browseButton */
- ac = 0;
- XtSetArg (av [ac], XmNpacking, XmPACK_TIGHT); ac++;
- XtSetArg (av [ac], XmNorientation, XmHORIZONTAL); ac++;
- XtSetArg (av [ac], XmNnumColumns, 2); ac++;
- XtSetArg (av [ac], XmNspacing, 5); ac++;
- XtSetArg (av [ac], XmNmarginWidth, 0); ac++;
- XtSetArg (av [ac], XmNmarginHeight, 0); ac++;
- filefed->rowcolumn = XmCreateRowColumn(parent, "formRowCol", av, ac);
-
- ac = 0;
- /* Ok, let's try using the fixed font for text areas only. */
- /*#ifdef FORMS_ARE_FONTIFIED*/
- XtSetArg (av [ac], XmNfontList, font_list); ac++;
- /*#endif*/
- XtSetArg (av [ac], XmNcolumns, columns); ac++;
-
- if (max_size > 0)
- {
- XtSetArg (av [ac], XmNmaxLength, max_size); ac++;
- }
-
- #ifdef FORMS_ARE_COLORED
- XtSetArg (av [ac], XmNforeground, fg); ac++;
- XtSetArg (av [ac], XmNbackground, bg); ac++;
- #endif
-
- fed->widget = fe_CreateTextField (filefed->rowcolumn, "textForm", av, ac);
-
- /* Install in javascript form elemement text field translation */
- fe_HackFormTextTranslations(fed->widget);
-
- XtAddCallback(fed->widget, XmNlosingFocusCallback,
- fe_lost_focus_cb, fed);
- XtAddCallback(fed->widget, XmNfocusCallback, fe_got_focus_cb, fed);
-
-
- XtManageChild(fed->widget);
-
- ac = 0;
- XtSetArg (av [ac], XmNfontList, font_list); ac++;
- XtSetArg (av [ac], XmNforeground, fg); ac++;
- XtSetArg (av [ac], XmNbackground, bg); ac++;
- filefed->browse_button = XmCreatePushButton (filefed->rowcolumn,
- "formFileBrowseButton",
- av, ac);
- XtAddCallback(filefed->browse_button, XmNactivateCallback,
- fe_form_file_browse_cb, fed);
- XtManageChild(filefed->browse_button);
-
- /* This is changed later for self-submitting fields. */
- if (fe_globalData.nonterminal_text_translations)
- XtOverrideTranslations (fed->widget, fe_globalData.
- nonterminal_text_translations);
-
- XtVaSetValues (fed->widget, XmNcursorPosition, 0, 0);
- loc = fe_ConvertToLocaleEncoding (charset, (unsigned char *)text);
- /* Add verify callbacks to implement JS key events */
- fe_HackTextTranslations_addCallbacks(fed->widget);
- /*
- * I don't know whether it is SGI or some version of Motif
- * but doing a XtVaSetValues() here will execute the
- * valueChangedCallback but ignore its changes.
- * XmTextFieldSetString() works as expected.
- */
- XmTextFieldSetString (fed->widget, loc);
- if (((char *) loc) != text) {
- XP_FREE (loc);
- }
- if (tmp_text) XP_FREE (tmp_text);
- }
-
- static void
- file_get_value(FEFormData *fed,
- LO_FormElementStruct *form,
- XP_Bool delete_p)
- {
- FEFileFormData *filefed = (FEFileFormData*)fed;
-
- text_get_value(fed, form, delete_p);
-
- /* if delete_p is true, then form_element_get_value will have destroyed
- fed->widget (our text field.) We need to finish the job here. */
- if (delete_p)
- {
- XtDestroyWidget(filefed->rowcolumn);
-
- filefed->rowcolumn = 0;
- }
- }
-
- static void
- file_free(FEFormData *fed,
- LO_FormElementData *form)
- {
- FEFileFormData *filefed = (FEFileFormData*)fed;
-
- if (filefed->rowcolumn)
- XtDestroyWidget(filefed->rowcolumn);
-
- filefed->rowcolumn = 0;
- fed->widget = 0;
-
- XP_FREE(fed);
- }
-
- /*
- **
- ** VTABLE for Text like button elements (BUTTON, RESET, SUBMIT).
- **
- */
- static void
- button_create_widget(FEFormData *fed,
- LO_FormElementStruct *form)
- {
- MWContext *context = fed->context;
- LO_FormElementData *form_data;
- Widget parent;
- int32 form_type;
- unsigned char *string;
- char *name;
- LO_TextAttr *text_attr;
- XmFontList font_list = NULL;
- XmString xmstring = NULL;
- Arg av [50];
- int ac;
-
- text_attr = XP_GetFormTextAttr(form);
- parent = CONTEXT_DATA (context)->drawing_area;
- form_data = XP_GetFormElementData(form);
- form_type = XP_FormGetType(form_data);
- string = (unsigned char*)XP_FormGetValue(form_data);
- name = (form_type == FORM_TYPE_SUBMIT
- ? "formSubmitButton"
- : (form_type == FORM_TYPE_RESET
- ? "formResetButton"
- : "formButton"));
-
- fe_FontlistAndXmStringForFormElement(context,
- form_type,
- (char*)string,
- text_attr,
- &xmstring,
- &font_list);
-
- #ifdef DEBUG_username
- if (xmstring == NULL) printf ("xmstring is NULL\n");
- #endif
-
- ac = 0;
-
- if (xmstring)
- {
- XtSetArg (av [ac], XmNlabelString, xmstring); ac++;
- }
- /*#ifdef FORMS_ARE_FONTIFIED*/
- if (font_list)
- {
- XtSetArg (av [ac], XmNfontList, font_list); ac++;
- }
- /*#endif*/
- /* Ok, buttons are always text-colored, because OptionMenu buttons
- must be, and making buttons be a different color looks
- inconsistent.
- */
- if (form_type == FORM_TYPE_SUBMIT)
- {
- XtSetArg (av [ac], XmNshowAsDefault, 1); ac++;
- }
-
- fed->widget = XmCreatePushButton (parent, name, av, ac);
-
- if (xmstring)
- XmStringFree (xmstring);
-
- /*#ifdef FORMS_ARE_COLORED*/
- set_form_colors(fed, &text_attr->fg, &text_attr->bg);
- /*#endif*/
-
- #ifndef NO_NEW_DEFAULT_SIZES
- /* added so the security people (or anyone needing an HTML area with
- form elements in it) could specify a wider default width than
- what motif computes based on the font */
- if (form->width > 0
- || form->height > 0)
- {
- Dimension width;
- Dimension height;
- Dimension bw;
-
- XtVaGetValues(fed->widget,
- XmNheight, &height,
- XmNwidth, &width,
- XmNborderWidth, &bw,
- NULL);
-
- /* take into account our padding */
- width += fe_FORM_LEFT_MARGIN + fe_FORM_RIGHT_MARGIN;
- height += fe_FORM_TOP_MARGIN + fe_FORM_BOTTOM_MARGIN;
- width += (bw * 2);
- height += (bw * 2);
-
- if (form->width > width)
- width = form->width;
- if (form->height > height)
- height = form->height;
-
- XtVaSetValues(fed->widget,
- XmNheight, height,
- XmNwidth, width,
- NULL);
- }
- #endif
-
- switch (form_type)
- {
- case FORM_TYPE_SUBMIT:
- XtAddCallback (fed->widget,
- XmNactivateCallback, fe_submit_form_cb, fed);
- break;
- case FORM_TYPE_RESET:
- XtAddCallback (fed->widget,
- XmNactivateCallback, fe_reset_form_cb, fed);
- break;
- case FORM_TYPE_BUTTON:
- XtAddCallback (fed->widget,
- XmNactivateCallback, fe_button_form_cb, fed);
- break;
- }
- }
-
- /*
- **
- ** Vtable routines for the radio and checkbox form elements.
- **
- */
- static void
- checkbox_create_widget(FEFormData *fed,
- LO_FormElementStruct *form)
- {
- MWContext *context = fed->context;
- Widget parent = CONTEXT_DATA (context)->drawing_area;
- LO_FormElementData *form_data;
- int32 form_type;
- XmString xmstring;
- int margin = 2; /* leave some slack... */
- int size;
- int descent;
- XmFontList locale_font_list = NULL;
- Arg av[10];
- int ac;
- LO_TextAttr *text_attr;
-
- form_data = XP_GetFormElementData(form);
- form_type = XP_FormGetType(form_data);
-
- text_attr = XP_GetFormTextAttr(form);
-
- fe_font_list_metrics (context, form, locale_font_list, &size, &descent);
- size += (margin * 2);
-
- XP_FormSetElementToggled(form_data,
- XP_FormGetDefaultToggled(form_data));
-
- ac = 0;
- xmstring = XmStringCreate (" ", XmFONTLIST_DEFAULT_TAG);
- /* These always use our font list, for proper sizing. */
- XtSetArg (av [ac], XmNfontList, locale_font_list); ac++;
- XtSetArg (av [ac], XmNwidth, size); ac++;
- XtSetArg (av [ac], XmNheight, size); ac++;
- XtSetArg (av [ac], XmNresize, False); ac++;
- XtSetArg (av [ac], XmNspacing, 2); ac++;
- XtSetArg (av [ac], XmNlabelString, xmstring); ac++;
- XtSetArg (av [ac], XmNvisibleWhenOff, True); ac++;
- XtSetArg (av [ac], XmNset, XP_FormGetDefaultToggled(form_data)); ac++;
- XtSetArg (av [ac], XmNindicatorType,
- (form_type == FORM_TYPE_RADIO
- ? XmONE_OF_MANY : XmN_OF_MANY)); ac++;
-
- fed->widget = XmCreateToggleButton (parent, "toggleForm", av, ac);
-
- /* These must always be the prevailing color of the text,
- or they look silly. */
- #ifdef FORMS_ARE_COLORED
- set_form_colors(fed, &text_attr->fg, &text_attr->bg);
- #endif
-
- if (form_type == FORM_TYPE_RADIO)
- XtAddCallback (fed->widget, XmNvalueChangedCallback,
- fe_radio_form_cb, fed);
- else
- XtAddCallback (fed->widget, XmNvalueChangedCallback,
- fe_check_form_cb, fed);
-
- XmStringFree (xmstring);
- }
-
- static void
- checkbox_get_value(FEFormData *fed,
- LO_FormElementStruct *form,
- XP_Bool delete_p)
- {
- LO_FormElementData *form_data = XP_GetFormElementData(form);
- Boolean set = False;
-
- XtVaGetValues(fed->widget, XmNset, &set, NULL);
-
- XP_FormSetElementToggled(form_data, set);
-
- form_element_get_value(fed, form, delete_p);
- }
-
- static void
- checkbox_change(FEFormData *fed,
- LO_FormElementStruct *form)
- {
- LO_FormElementData *form_data = XP_GetFormElementData(form);
- int32 form_type = XP_FormGetType(form_data);
- XP_Bool toggled = XP_FormGetElementToggled(form_data);
-
- switch (form_type)
- {
- case FORM_TYPE_RADIO:
- if (toggled) LO_FormRadioSet (fed->context, form);
- /* SPECIAL: If this was the only radio button in the radio group,
- LO_FormRadioSet() will turn it back ON again if Mocha tried to
- turn it OFF. We want to let mocha be able to turn ON/OFF
- radio buttons. So we are going to override that and let mocha
- have its way.
- */
- XFE_SetFormElementToggle(fed->context, form, toggled);
- break;
- case FORM_TYPE_CHECKBOX:
- XtVaSetValues (fed->widget, XmNset, toggled, 0);
- break;
- }
- }
-
- /*
- **
- ** Vtable entries for FORM_TYPE_SELECT_MULT
- **
- */
-
- static void
- select_create_widget(FEFormData *fed,
- LO_FormElementStruct *form)
- {
- FESelectMultFormData *sel_fed = (FESelectMultFormData*)fed;
- MWContext *context = fed->context;
- Widget parent = CONTEXT_DATA(context)->drawing_area;
- LO_FormElementData *form_data = XP_GetFormElementData(form);
- int32 form_type = XP_FormGetType(form_data);
- LO_TextAttr *text_attr;
- int nitems = XP_FormSelectGetOptionsCount(form_data);
- int vlines;
- XmString *items = NULL;
- char *selected_p = NULL;
- int i;
- Arg av[30];
- int ac;
- XmFontList font_list = NULL;
-
- text_attr = XP_GetFormTextAttr(form);
-
- vlines = XP_FormSelectGetSize(form_data);
-
- if (vlines <= 0) vlines = nitems;
-
- if (nitems > 0) {
- items = (XmString *) malloc (sizeof (XmString) * nitems);
- selected_p = (char *) calloc (nitems, sizeof (char));
- }
-
- for (i = 0; i < nitems; i++)
- {
- lo_FormElementOptionData *d2 =
- XP_FormSelectGetOption(form_data, i);
-
- fe_FontlistAndXmStringForFormElement(context,
- form_type,
- (d2->text_value
- ? (char *) d2->text_value
- : "---\?\?\?---"),
- text_attr,
- &items[i],
- &font_list);
-
- selected_p [i] = !!d2->def_selected;
- d2->selected = d2->def_selected;
- }
-
- ac = 0;
- /* #ifdef FORMS_ARE_FONTIFIED */
- XtSetArg (av [ac], XmNfontList, font_list); ac++;
- /* #endif */
- XtSetArg (av [ac], XmNspacing, 0); ac++;
-
- if (nitems) {
- XtSetArg (av [ac], XmNitems, items); ac++;
- XtSetArg (av [ac], XmNitemCount, nitems); ac++;
- }
-
- if (form_type == FORM_TYPE_SELECT_MULT)
- {
- XtSetArg (av [ac], XmNvisibleItemCount, vlines); ac++;
- XtSetArg (av [ac], XmNlistSizePolicy, XmRESIZE_IF_POSSIBLE); ac++;
- XtSetArg (av [ac], XmNselectionPolicy,
- (XP_FormSelectGetMultiple(form_data)
- ? XmMULTIPLE_SELECT
- : XmSINGLE_SELECT)); ac++;
- XtSetArg(av[ac], XmNx, -15000); ac++;
- }
- else /* FORM_TYPE_SELECT_ONE */
- {
- Visual *v = 0;
- Colormap cmap = 0;
- Cardinal depth = 0;
-
- fe_getVisualOfContext (context, &v, &cmap, &depth);
-
- XtSetArg (av [ac], XmNshadowThickness, 1); ac++;
- XtSetArg (av [ac], XmNarrowType, XmMOTIF); ac++;
- XtSetArg (av [ac], XmNtype, XmDROP_DOWN_LIST_BOX); ac++;
- XtSetArg (av [ac], XmNvisual, v); ac++;
- XtSetArg (av [ac], XmNcolormap, cmap); ac++;
- XtSetArg (av [ac], XmNdepth, depth); ac++;
- }
-
- if (form_type == FORM_TYPE_SELECT_MULT)
- {
- sel_fed->list_widget = XmCreateScrolledList (parent, "list", av, ac);
- fed->widget = XtParent(sel_fed->list_widget);
- /*
- * We need this Unmanage because otherwise XtIsManaged on the
- * parent fails later. It seems XmCreateScrolledList() creates
- * an unmanaged list with a managed scrolled window parent.
- * How stupid.
- */
- XtUnmanageChild (fed->widget);
- XtManageChild (sel_fed->list_widget);
- }
- else /* FORM_TYPE_SELECT_ONE */
- {
- /* we also need to set the fontlist explicitly on the label, for
- some reason... */
- Widget label;
-
- fed->widget = DtCreateComboBox(parent, "list", av, ac);
- XtVaGetValues(fed->widget,
- XmNlist, &sel_fed->list_widget,
- NULL);
-
- label = ((DtComboBoxWidget)fed->widget)->combo_box.label;
-
- ac = 0;
- /* #ifdef FORMS_ARE_FONTIFIED */
- XtSetArg (av [ac], XmNfontList, font_list); ac++;
- XtSetValues(label, av, ac);
- }
-
- #ifdef FORMS_ARE_COLORED
- set_form_colors(fed, &text_attr->fg, &text_attr->bg);
- #endif
-
- #ifndef NO_NEW_DEFAULT_SIZES
- /* added so the security people (or anyone needing an HTML area with
- form elements in it) could specify a wider default width (or higher
- default height) than what motif computes based on the font */
- if (form->width > 0)
- {
- Dimension width;
- Dimension height;
- Dimension bw;
-
- XtVaGetValues(sel_fed->list_widget,
- XmNwidth, &width,
- XmNheight, &height,
- XmNborderWidth, &bw,
- NULL);
-
- /* take into account our padding */
- width += fe_FORM_LEFT_MARGIN + fe_FORM_RIGHT_MARGIN;
- height += fe_FORM_TOP_MARGIN + fe_FORM_BOTTOM_MARGIN;
- width += (bw * 2);
- height += (bw * 2);
-
- if (form->width > width)
- width = form->width;
-
- if (form->height > height)
- height = form->height;
-
- XtVaSetValues(sel_fed->list_widget,
- XmNwidth, width,
- XmNheight, height,
- NULL);
- }
- #endif
-
- for (i = 0; i < nitems; i++)
- if (selected_p[i])
- if (form_type == FORM_TYPE_SELECT_MULT)
- XmListSelectPos(sel_fed->list_widget, i+1, False);
- else /* FORM_TYPE_SELECT_ONE */
- DtComboBoxSelectItem(fed->widget, items[i]);
-
- if (form_type == FORM_TYPE_SELECT_MULT)
- {
- XtAddCallback (sel_fed->list_widget,
- XmNdefaultActionCallback, fe_list_form_cb, fed);
- XtAddCallback (sel_fed->list_widget,
- XmNsingleSelectionCallback, fe_list_form_cb, fed);
- XtAddCallback (sel_fed->list_widget,
- XmNmultipleSelectionCallback, fe_list_form_cb, fed);
- XtAddCallback (sel_fed->list_widget,
- XmNextendedSelectionCallback, fe_list_form_cb, fed);
- XtInsertEventHandler(sel_fed->list_widget,
- KeyPressMask, False,
- fe_list_find_eh, context, XtListHead);
- XtAddEventHandler(sel_fed->list_widget,
- FocusChangeMask, FALSE,
- (XtEventHandler)fe_mocha_focus_notify_eh,
- fed);
- }
- else
- {
- XtAddCallback(fed->widget,
- XmNselectionCallback, fe_combo_form_cb, sel_fed);
- }
-
- sel_fed->nkids = nitems;
- sel_fed->selected_p = selected_p;
- }
-
- static void
- select_get_value(FEFormData *fed,
- LO_FormElementStruct *form,
- XP_Bool delete_p)
- {
- FESelectMultFormData *sel_fed = (FESelectMultFormData*)fed;
- LO_FormElementData *form_data = XP_GetFormElementData(form);
- int i;
-
- for (i = 0; i < sel_fed->nkids; i ++)
- {
- lo_FormElementOptionData *option_data =
- XP_FormSelectGetOption(form_data, i);
-
- XP_FormOptionSetSelected(option_data,
- sel_fed->selected_p[i]);
- }
-
- form_element_get_value(fed, form, delete_p);
- }
-
- static void
- select_free(FEFormData *fed,
- LO_FormElementData *form_data)
- {
- FESelectMultFormData *sel_fed = (FESelectMultFormData*)fed;
-
- if (sel_fed->selected_p)
- free(sel_fed->selected_p);
-
- form_element_free(fed, form_data);
- }
-
- static void
- select_reset(FEFormData *fed,
- LO_FormElementStruct *form)
- {
- FESelectMultFormData *sel_fed = (FESelectMultFormData*)fed;
- LO_FormElementData *form_data = XP_GetFormElementData(form);
- int32 form_type = XP_FormGetType(form_data);
- int nitems = XP_FormSelectGetOptionsCount(form_data);
- int i;
- XmString *items;
-
- XtVaGetValues(sel_fed->list_widget, XmNitems, &items, NULL);
-
- for (i = 0; i < nitems; i++)
- {
- lo_FormElementOptionData *option = XP_FormSelectGetOption(form_data, i);
- XP_Bool selected;
-
- XP_FormOptionSetSelected(option, XP_FormOptionGetDefaultSelected(option));
-
- selected = XP_FormOptionGetSelected(option);
- if (selected) {
- /* Highlight the item at pos i+1 if it is not already */
- if (!sel_fed->selected_p[i])
- if (form_type == FORM_TYPE_SELECT_MULT)
- XmListSelectPos(sel_fed->list_widget, i+1, False);
- else /* FORM_TYPE_SELECT_ONE */
- DtComboBoxSelectItem(fed->widget, items[i]);
- }
- else
- XmListDeselectPos(sel_fed->list_widget, i+1);
- sel_fed->selected_p [i] = selected;
- }
- }
-
- static void
- select_change(FEFormData *fed,
- LO_FormElementStruct *form)
- {
- FESelectMultFormData *sel_fed = (FESelectMultFormData*)fed;
- LO_FormElementData *form_data = XP_GetFormElementData(form);
- int32 form_type = XP_FormGetType(form_data);
- fe_Font fe_font;
- LO_TextAttr *text_attr;
- uint16 mask;
- XmString *new_items;
- char* new_selected_p;
- int nitems;
- int i;
- int16 charset;
- XmFontList unicodePseudo_font_list = NULL;
- XP_Bool item_selected = FALSE;
-
- nitems = XP_FormSelectGetOptionsCount(form_data);
- text_attr = XP_GetFormTextAttr(form);
- mask = text_attr->fontmask;
- charset = text_attr->charset;
-
- fe_font = fe_LoadUnicodeFont(NULL, "", 0, text_attr->size, mask, 0, 0, 0,
- XtDisplay(CONTEXT_WIDGET(fed->context)));
-
- if (nitems > 0)
- {
- new_items = (XmString *) malloc (sizeof (XmString) * nitems);
- new_selected_p = (char *) calloc (nitems, sizeof (char));
- }
-
- #ifdef DEBUG_username
- printf ("nitems = %d\n", nitems);
- #endif
-
- for (i = 0; i < nitems; i ++)
- {
- char *str;
- lo_FormElementOptionData *option_data =
- XP_FormSelectGetOption(form_data, i);
-
- str = (option_data->text_value
- ? ((*((char *) option_data->text_value))
- ? ((char *) option_data->text_value)
- : " ")
- : "---\?\?\?---");
-
- new_items [i] = fe_ConvertToXmString(str, charset, fe_font,
- XmFONT_IS_FONT,
- &unicodePseudo_font_list);
- new_selected_p [i] = !!XP_FormOptionGetSelected(option_data);
-
- #ifdef DEBUG_username
- printf ("items[%d] = %s\n", i, str);
- #endif
- }
-
- XmListDeselectAllItems(sel_fed->list_widget);
-
- XtVaSetValues(sel_fed->list_widget,
- XmNitems, new_items,
- XmNitemCount, nitems,
- NULL);
-
- for (i = 0; i < nitems; i++)
- if (new_selected_p[i])
- if (form_type == FORM_TYPE_SELECT_MULT)
- XmListSelectPos(sel_fed->list_widget, i+1, False);
- else /* FORM_TYPE_SELECT_ONE */
- {
- DtComboBoxSelectItem(fed->widget, new_items[i]);
- item_selected = TRUE;
- }
-
- if (sel_fed->selected_p)
- free(sel_fed->selected_p);
-
- sel_fed->selected_p = new_selected_p;
- sel_fed->nkids = nitems;
- }
-
- /*
- **
- ** Vtable entries for FORM_TYPE_TEXTAREA
- **
- */
-
- static void
- textarea_create_widget(FEFormData *fed,
- LO_FormElementStruct *form)
- {
- FETextAreaFormData *ta_fed = (FETextAreaFormData*)fed;
- MWContext *context = fed->context;
- Widget parent;
- int16 charset;
- LO_FormElementData *form_data;
- int32 form_type;
- int32 rows, cols;
- char *text;
- unsigned char *loc;
- XmFontList locale_font_list;
- Arg av [50];
- int ac;
- LO_TextAttr *text_attr;
-
- parent = CONTEXT_DATA (context)->drawing_area;
- form_data = XP_GetFormElementData(form);
- form_type = XP_FormGetType(form_data);
- text_attr = XP_GetFormTextAttr(form);
- text = (char*)XP_FormGetDefaultText(form_data);
- charset = text_attr->charset;
-
- XP_FormTextAreaGetDimensions(form_data,
- &rows, &cols);
-
-
- /* the default size for text fields is 20 columns.
- XX Shouldn't the backend just fill it in with 20? */
- if (cols == 0) cols = 20;
-
- if (!text) text = "";
-
- fe_forms_clean_text (context, charset, text, False);
- loc = fe_ConvertToLocaleEncoding (charset, text);
-
- fe_FontlistAndXmStringForFormElement(context,
- form_type,
- loc,
- text_attr,
- NULL,
- &locale_font_list);
- if (!locale_font_list)
- return;
-
- ac = 0;
-
- XtSetArg (av[ac], XmNscrollingPolicy, XmAUTOMATIC); ac++;
- XtSetArg (av[ac], XmNvisualPolicy, XmCONSTANT); ac++;
- XtSetArg (av[ac], XmNscrollBarDisplayPolicy, XmSTATIC); ac++;
-
- XtSetArg (av[ac], XmNvalue, loc); ac++;
- XtSetArg (av[ac], XmNcursorPosition, 0); ac++;
- /* from bstell: in multibyte (asian) locales, characters tend to be twice
- as wide as in non-multibyte locales. To make things look correct,
- we divide the column number in half in those cases. */
- XtSetArg (av[ac], XmNcolumns, ((fe_LocaleCharSetID & MULTIBYTE) ?
- (cols + 1) / 2 : cols)); ac++;
- XtSetArg (av[ac], XmNrows, rows); ac++;
- /*
- * Gotta love Motif. No matter what wordWrap is set to, if
- * there is a horizontal scrollbar present it won't wrap.
- * Of course the documentation mentions this nowhere.
- * "Use the source Luke!"
- */
- if (XP_FormTextAreaGetAutowrap(form_data) != TEXTAREA_WRAP_OFF)
- {
- XtSetArg (av[ac], XmNscrollHorizontal, FALSE); ac++;
- XtSetArg (av[ac], XmNwordWrap, TRUE); ac++;
- }
- XtSetArg (av[ac], XmNeditMode, XmMULTI_LINE_EDIT); ac++;
- /* Ok, let's try using the fixed font for text areas only. */
- /*#ifdef FORMS_ARE_FONTIFIED*/
- XtSetArg (av[ac], XmNfontList, locale_font_list); ac++;
- /*#endif*/
- XtSetArg(av[ac], XmNx, -15000); ac++;
- ta_fed->text_widget = XmCreateScrolledText (parent, "formText", av, ac);
- ta_fed->form_data.widget = XtParent(ta_fed->text_widget);
-
- /* The scroller must have the prevailing color of the text,
- or it looks funny.*/
- #ifdef FORMS_ARE_COLORED
- set_form_colors(fed, &text_attr->fg, &text_attr->bg);
- #endif
-
- if (((char *) loc) != text)
- {
- XP_FREE (loc);
- }
-
- XtAddCallback(ta_fed->text_widget, XmNlosingFocusCallback,
- fe_lost_focus_cb, fed);
- XtAddCallback(ta_fed->text_widget, XmNfocusCallback, fe_got_focus_cb, fed);
- XtAddEventHandler(ta_fed->text_widget,
- KeyPressMask | KeyReleaseMask,
- FALSE, /* don't care about nonmaskable events */
- fe_key_handler,
- ta_fed);
-
- /* Add verify callbacks to implement JS key events */
- fe_HackTextTranslations_addCallbacks(ta_fed->text_widget);
-
- XtUnmanageChild (ta_fed->form_data.widget);
- XtManageChild (ta_fed->text_widget);
- }
-
- static void
- textarea_display(FEFormData *fed,
- LO_FormElementStruct *form)
- {
- form_element_display(fed, form);
- }
-
- static void
- textarea_get_value(FEFormData *fed,
- LO_FormElementStruct *form,
- XP_Bool delete_p)
- {
- MWContext *context = fed->context;
- LO_FormElementData *form_data = XP_GetFormElementData(form);
- FETextAreaFormData *ta_fed = (FETextAreaFormData*)fed;
- INTL_CharSetInfo c = LO_GetDocumentCharacterSetInfo(context);
- char *text = 0;
- int32 cols;
- PA_Block current_text, new_current_text;
- PA_Block default_text;
-
- XP_FormTextAreaGetDimensions(form_data, NULL, &cols);
-
- XtVaGetValues (ta_fed->text_widget, XmNvalue, &text, 0);
- if (! text) return;
- if (XP_FormTextAreaGetAutowrap(form_data) == TEXTAREA_WRAP_HARD) {
- char *tmp = XP_WordWrap(fe_LocaleCharSetID, text, cols, 0);
- if (text) XtFree(text);
- if (!tmp) return;
- text = tmp;
- }
-
- current_text = XP_FormGetCurrentText(form_data);
- default_text = XP_FormGetDefaultText(form_data);
-
- if (current_text && current_text != default_text)
- free (current_text);
-
- new_current_text =
- (PA_Block)fe_ConvertFromLocaleEncoding (INTL_GetCSIWinCSID(c),
- (unsigned char *) text);
-
- XP_FormSetCurrentText(form_data, new_current_text);
-
- if (((char *) new_current_text) != text) {
- free (text);
- }
-
- form_element_get_value(fed, form, delete_p);
- }
-
- static void
- textarea_reset(FEFormData *fed,
- LO_FormElementStruct *form)
- {
- LO_FormElementData *form_data = XP_GetFormElementData(form);
- FETextAreaFormData *ta_fed = (FETextAreaFormData*)fed;
- char *default_text = (char*)XP_FormGetDefaultText(form_data);
- LO_TextAttr *text_attr = XP_GetFormTextAttr(form);
- int16 charset = text_attr->charset;
- unsigned char *loc;
-
- fe_forms_clean_text (fed->context, charset, default_text, False);
-
- XtVaSetValues (ta_fed->text_widget, XmNcursorPosition, 0, 0);
-
- loc = fe_ConvertToLocaleEncoding (charset, (unsigned char*)default_text);
-
- XtVaSetValues (ta_fed->text_widget, XmNvalue, loc, 0);
-
- if (((char *) loc) != default_text)
- {
- XP_FREE (loc);
- }
- }
-
- static void
- textarea_lost_focus(FEFormData *fed)
- {
- FETextAreaFormData *ta_fed = (FETextAreaFormData*)fed;
- LO_FormElementData *form_data;
- char *text;
- XP_Bool text_changed = False;
- PA_Block current_text;
- JSEvent *event;
-
- form_data = XP_GetFormElementData(fed->form);
-
- current_text = XP_FormGetCurrentText(form_data);
-
- XtVaGetValues (ta_fed->text_widget, XmNvalue, &text, 0);
-
- if (!current_text || XP_STRCMP((char*)current_text, text))
- text_changed = True;
-
- if (((char*) current_text) != text) {
- XtFree (text);
- }
-
- /* if the text has changed, call get_element_value to copy it into the form
- element, and send a CHANGE event to the javascript thread. */
- if (text_changed)
- {
- (*fed->vtbl.get_element_value)(fed, fed->form, FALSE);
-
- event = XP_NEW_ZAP(JSEvent);
-
- event->type = EVENT_CHANGE;
-
- ET_SendEvent (fed->context, (LO_Element *) fed->form, event,
- NULL, NULL);
- }
- }
-
- static FEFormData *
- alloc_form_data(int32 form_type)
- {
- FEFormData *data;
-
- switch (form_type)
- {
- case FORM_TYPE_TEXT:
- case FORM_TYPE_PASSWORD:
- case FORM_TYPE_READONLY:
- data = (FEFormData*)XP_NEW_ZAP(FEFormData);
- data->vtbl = text_form_vtable;
- return data;
-
- case FORM_TYPE_FILE:
- data = (FEFormData*)XP_NEW_ZAP(FEFileFormData);
- data->vtbl = file_form_vtable;
- return data;
-
- case FORM_TYPE_SUBMIT:
- case FORM_TYPE_RESET:
- case FORM_TYPE_BUTTON:
- data = (FEFormData*)XP_NEW_ZAP(FEFormData);
- data->vtbl = button_form_vtable;
- return data;
-
- case FORM_TYPE_RADIO:
- case FORM_TYPE_CHECKBOX:
- data = (FEFormData*)XP_NEW_ZAP(FEFormData);
- data->vtbl = checkbox_form_vtable;
- return data;
-
- case FORM_TYPE_SELECT_ONE:
- data = (FEFormData*)XP_NEW_ZAP(FESelectOneFormData);
- data->vtbl = selectone_form_vtable;
- return data;
-
- case FORM_TYPE_TEXTAREA:
- data = (FEFormData*)XP_NEW_ZAP(FETextAreaFormData);
- data->vtbl = textarea_form_vtable;
- return data;
-
- case FORM_TYPE_SELECT_MULT:
- data = (FEFormData*)XP_NEW_ZAP(FESelectMultFormData);
- data->vtbl = selectmult_form_vtable;
- return data;
-
- case FORM_TYPE_HIDDEN:
- case FORM_TYPE_JOT:
- case FORM_TYPE_ISINDEX:
- case FORM_TYPE_IMAGE:
- case FORM_TYPE_KEYGEN:
- case FORM_TYPE_OBJECT:
- default:
- XP_ASSERT(0);
- return NULL;
- }
- }
-
- /*
- ** This method can be called more than once for the same front end form element.
- **
- ** In those cases we don't reallocate the FEData*, and also don't recreate the widget,
- ** but we do set the form and context pointers in FEData, and we call the get_size
- ** method.
- **
- ** The two cases I know of where layout calls this function more than once are:
- ** when laying out a table with form elements in it -- layout moves our fe data
- ** over to the new LO_FormElementStruct, but we have to sync up our pointer to
- ** the new.
- ** when reloading a page with frames in it. In this case, the context is different,
- ** so need to always set that as well.
- **
- ** Also, layout could have told us to delete the widget without freeing our FEData*
- ** (this happens with delete_p is TRUE in XFE_GetFormElementValue.) In this case,
- ** we need to recreate the widget.
- **
- ** yuck.
- */
- void
- XFE_GetFormElementInfo(MWContext *context,
- LO_FormElementStruct *form)
- {
- LO_FormElementData *form_data = XP_GetFormElementData(form);
- FEFormData *fed;
-
- #ifdef DEBUG_username
- printf ("XFE_GetFormElementInfo\n");
- #endif
-
- if (!form_data)
- return;
-
- fed = (FEFormData*)XP_FormGetFEData(form_data);
- if (!fed)
- {
- int32 form_type = XP_FormGetType(form_data);
-
- fed = alloc_form_data(form_type);
-
- XP_ASSERT(fed);
- if (!fed) return;
-
- XP_FormSetFEData(form_data, fed);
- }
-
- fed->form = form;
- fed->context = context;
-
- if (!fed->widget)
- {
- XP_ASSERT(fed->vtbl.create_widget_func);
-
- (*fed->vtbl.create_widget_func)(fed, form);
- }
-
- XP_ASSERT(fed->vtbl.get_size_func);
-
- (*fed->vtbl.get_size_func)(fed, form);
- }
-
- void
- XFE_DisplayFormElement(MWContext *context, int iLocation,
- LO_FormElementStruct *form)
- {
- LO_FormElementData *form_data = XP_GetFormElementData(form);
- FEFormData *fed;
-
- #ifdef DEBUG_username
- printf ("XFE_DisplayFormElement\n");
- #endif
-
- if (!form_data)
- return;
-
- fed = (FEFormData*)XP_FormGetFEData(form_data);
-
- XP_ASSERT(fed);
- if (!fed) return;
-
- if (fed->vtbl.display_element_func)
- (*fed->vtbl.display_element_func)(fed, form);
- }
-
- void
- XFE_FormTextIsSubmit (MWContext *context, LO_FormElementStruct *form)
- {
- LO_FormElementData *form_data = XP_GetFormElementData(form);
- FEFormData *fed;
-
- if (!form_data)
- return;
-
- fed = (FEFormData*)XP_FormGetFEData(form_data);
-
- XP_ASSERT(fed);
- if (!fed) return;
-
- if (fed->vtbl.element_is_submit_func)
- (*fed->vtbl.element_is_submit_func)(fed, form);
- }
-
- void
- XFE_GetFormElementValue (MWContext *context, LO_FormElementStruct *form,
- XP_Bool delete_p)
- {
- LO_FormElementData *form_data = XP_GetFormElementData(form);
- FEFormData *fed;
-
- #ifdef DEBUG_username
- printf ("XFE_GetFormElementValue (delete_p = %d)\n", delete_p);
- #endif
-
- if (!form_data)
- return;
-
- fed = (FEFormData*)XP_FormGetFEData(form_data);
-
- XP_ASSERT(fed);
- if (!fed) return;
-
- if (fed->vtbl.get_element_value)
- (*fed->vtbl.get_element_value)(fed, form, delete_p);
- }
-
- void
- FE_FreeFormElement(MWContext *context,
- LO_FormElementData *form_data)
- {
- FEFormData *fed;
-
- #ifdef DEBUG_username
- printf ("XFE_FreeFormElement. \n");
- #endif
-
- if (!form_data)
- return;
-
- fed = (FEFormData*)XP_FormGetFEData(form_data);
-
- /* this assert gets tripped by HIDDEN form elements, since we have no
- FE data associated with them. */
- /*XP_ASSERT(fed);*/
- if (!fed) return;
-
- if (fed->vtbl.free_element_func)
- (*fed->vtbl.free_element_func)(fed, form_data);
-
- /* clear out the FE data, so we don't try anything funny from now on. */
- XP_FormSetFEData(form_data, NULL);
- }
-
- void
- FE_FocusInputElement(MWContext *context,
- LO_Element *element)
- {
- if (element)
- {
- LO_FormElementData *form_data =
- XP_GetFormElementData((LO_FormElementStruct*)element);
- FEFormData* fed;
-
- if (!form_data)
- return;
-
- fed = (FEFormData*)XP_FormGetFEData(form_data);
-
- if (fed->vtbl.focus_element_func)
- (*fed->vtbl.focus_element_func)(fed, (LO_FormElementStruct*)element);
- }
- else
- {
- JSEvent *event;
-
- if (context->is_grid_cell)
- fe_SetGridFocus (context);
- XmProcessTraversal (CONTEXT_WIDGET(context), XmTRAVERSE_CURRENT);
- FE_RaiseWindow(context);
-
- event = XP_NEW_ZAP(JSEvent);
- event->type = EVENT_FOCUS;
- ET_SendEvent (context, element, event, NULL, NULL);
- }
- }
-
- /*
- * Force input to be defocused from an element in the given window.
- * It's ok if the input didn't have input focus.
- */
- void
- FE_BlurInputElement(MWContext *context, LO_Element *element)
- {
- /* Just blow away focus */
- TRACEMSG(("XFE_BlurInputElement: element->type = %d\n"));
-
- if (!context) return;
-
- /* I was told by brendan that this is unnecessary - ramiro */
- #if 0
- if (form == NULL || form->element_data == NULL) {
- #ifdef DEBUG_spence
- printf ("BlurInputElement: form is invalid\n");
- #endif
- return;
- }
- #endif
-
- fe_NeutralizeFocus (context);
-
- if (!element) {
- FE_LowerWindow(context);
-
- fe_MochaBlurNotify(context, element);
- }
- }
-
- void
- FE_SelectInputElement(MWContext *context, LO_Element *element)
- {
- LO_FormElementStruct *form = (LO_FormElementStruct*)element;
- LO_FormElementData *form_data = XP_GetFormElementData(form);
- FEFormData *fed;
-
- if (!form_data)
- return;
-
- fed = (FEFormData*)XP_FormGetFEData(form_data);
-
- XP_ASSERT(fed);
- if (!fed) return;
-
- if (fed->vtbl.select_element_func)
- (*fed->vtbl.select_element_func)(fed, form);
- }
-
- void
- FE_ChangeInputElement(MWContext *context,
- LO_Element *element)
- {
- LO_FormElementStruct *form = (LO_FormElementStruct*)element;
- LO_FormElementData *form_data = XP_GetFormElementData(form);
- FEFormData *fed;
- int32 type;
-
- if (!form_data)
- return;
-
- fed = (FEFormData*)XP_FormGetFEData(form_data);
- type = XP_FormGetType(form_data);
-
- /* this assert gets tripped by HIDDEN form elements, since we have no
- FE data associated with them. */
- /*XP_ASSERT(fed);*/
- if (!fed) return;
-
- if (fed->vtbl.change_element_func)
- {
- LO_LockLayout();
-
- (*fed->vtbl.change_element_func)(fed, form);
-
- LO_UnlockLayout();
- }
- }
-
- /*
- ** Tell the FE that a form is being submitted without a UI gesture indicating
- ** that fact, i.e., in a Mocha-automated fashion ("document.myform.submit()").
- ** The FE is responsible for emulating whatever happens when the user hits the
- ** submit button, or auto-submits by typing Enter in a single-field form.
- */
- void
- FE_SubmitInputElement(MWContext *context, LO_Element *element)
- {
- LO_FormSubmitData *submit;
- URL_Struct *url;
- History_entry *he = NULL;
-
- TRACEMSG(("XFE_SubmitInputElement: element->type = %d\n"));
- if (!context) return;
-
- if (element == NULL) {
- #ifdef DEBUG_username
- printf ("SubmitInputElement: form is invalid\n");
- #endif
- return;
- }
-
- submit = LO_SubmitForm (context, (LO_FormElementStruct *) element);
- if (!submit)
- return;
-
- /* Create the URL to load */
- url = NET_CreateURLStruct((char *)submit->action, NET_DONT_RELOAD);
-
- /* ... add the form data */
- NET_AddLOSubmitDataToURLStruct(submit, url);
-
- /* referrer field if there is one */
- he = SHIST_GetCurrent (&context->hist);
- url->referer = fe_GetURLForReferral(he);
-
- fe_GetURL (context, url, FALSE);
- LO_FreeSubmitData (submit);
- }
-
- /*
- * Emulate a button or HREF anchor click for element.
- */
- void
- FE_ClickInputElement(MWContext *context, LO_Element *xref)
- {
- LO_FormElementStruct *form = (LO_FormElementStruct *) xref;
- LO_FormElementData *form_data;
- FEFormData *fed;
-
- if (!form)
- return;
-
- form_data = XP_GetFormElementData(form);
- if (!form_data)
- return;
-
- fed = XP_FormGetFEData(form_data);
-
- switch (xref->type) {
- case LO_FORM_ELE:
- {
- XmPushButtonCallbackStruct cb;
- cb.reason = XmCR_ACTIVATE;
- cb.event = 0;
- cb.click_count = 1;
- XtCallCallbacks (fed->widget, XmNactivateCallback, &cb);
- }
- break;
- case LO_IMAGE:
- case LO_TEXT:
- {
- CL_Event layer_event;
- fe_EventStruct fe_event;
- XEvent event;
-
- event.type = ButtonPress;
- event.xbutton.time = XtLastTimestampProcessed (XtDisplay(CONTEXT_WIDGET (context)));
- /* We only fill in the fields that we need. */
- #ifdef LAYERS_FULL_FE_EVENT
- fe_event.event = &event;
- #else
- fe_event_stuff(context,&fe_event,&event,0,0,FE_INVALID_MOUSE_ACTION);
- layer_event.fe_event_size = sizeof(fe_event);
- #endif
- layer_event.fe_event = (void*)&fe_event;
- layer_event.x = xref->lo_image.x;
- layer_event.y = xref->lo_image.y;
- (void) fe_HandleHREF (context, xref, False, False, &layer_event, 0);
- }
- break;
- }
- }
-
- static void
- fe_form_file_browse_cb (Widget widget, XtPointer closure, XtPointer call_data)
- {
- FEFormData *fed = (FEFormData*) closure;
- char *filename;
- XmString xm_title = 0;
- char *title = 0;
-
- XtVaGetValues (widget, XmNlabelString, &xm_title, 0);
- if (xm_title)
- XmStringGetLtoR (xm_title,
- XmFONTLIST_DEFAULT_TAG, &title); /* title - XtMalloc*/
- XmStringFree(xm_title);
-
- filename = fe_ReadFileName( fed->context, title, 0, FALSE, 0);
- XtFree(title);
-
- if (filename) {
- XP_StatStruct st;
- char buf [2048];
- if (stat(filename, &st) < 0)
- {
- /* Error: Cant stat */
- PR_snprintf (buf, sizeof (buf),
- XP_GetString(XFE_ERROR_OPENING_FILE), filename);
- FE_Alert(fed->context, buf);
- }
- else
- {
- /* The file was found. Stick the name into the text field. */
- XmTextFieldSetString (fed->widget, filename);
-
- /* resync up the backend with the current value in the text field. */
- XFE_GetFormElementValue(fed->context, fed->form, False);
- }
-
- XP_FREE(filename);
- }
- }
-
- /* This happens for self submiting forms. */
- static void
- fe_activate_submit_cb (Widget widget, XtPointer closure, XtPointer call_data)
- {
- FEFormData *fed = (FEFormData*)closure;
-
- /* Move focus out of the current focus widget. This will make any OnChange
- * calls to mocha.
- */
- fe_NeutralizeFocus(fed->context);
-
- fe_submit_form_cb(widget, closure, call_data);
- }
-
- static void
- fe_mocha_focus_notify_eh (Widget w,
- XtPointer closure,
- XEvent *ev,
- Boolean *cont)
- {
- FEFormData *fed = (FEFormData *) closure;
- MWContext *context = (MWContext *) fed->context;
-
- TRACEMSG (("fe_focus_notify_eh\n"));
- switch (ev->type) {
- case FocusIn:
- TRACEMSG (("focus in\n"));
- fe_MochaFocusNotify(context, (LO_Element*)fed->form);
- break;
- case FocusOut:
- TRACEMSG (("focus out\n"));
- fe_MochaBlurNotify(context, (LO_Element*)fed->form);
- break;
- }
- }
-
- static void
- fe_mocha_submit_form_cb (MWContext *context, LO_Element *element, int32 event,
- void *closure, ETEventStatus status)
- {
- LO_FormSubmitData *data;
- URL_Struct *url;
-
- if (status != EVENT_OK)
- return;
-
- data = LO_SubmitForm (context, (LO_FormElementStruct *) element);
- if (! data) return;
- url = NET_CreateURLStruct ((char *) data->action, FALSE);
-
- /* Add the referer to the URL. */
- {
- History_entry *he = SHIST_GetCurrent (&context->hist);
- if (url->referer)
- free (url->referer);
- url->referer = fe_GetURLForReferral(he);
- }
-
- NET_AddLOSubmitDataToURLStruct (data, url);
-
- fe_GetURL (context, url, FALSE);
- LO_FreeSubmitData (data);
- }
-
-
- static void
- fe_mocha_submit_click_form_cb(MWContext *context, LO_Element *element,
- int32 event, void *closure,
- ETEventStatus status)
- {
- FEFormData *fed = (FEFormData *) closure;
-
- if (status != EVENT_OK)
- return;
-
- /* Load the element value before telling mocha about the submit.
- * This needs to be done if we came here not because of the user
- * clicking on the submit button, like hitting RETURN on a text field.
- */
- XFE_GetFormElementValue(fed->context, fed->form, False);
-
- {
- JSEvent *event = XP_NEW_ZAP(JSEvent);
-
- event->type = EVENT_SUBMIT;
-
- ET_SendEvent (fed->context, (LO_Element *) fed->form, event,
- fe_mocha_submit_form_cb, NULL);
- }
- }
-
- static void
- fe_submit_form_cb (Widget widget, XtPointer closure, XtPointer call_data)
- /*
- * description:
- * This function was registered as an XmNactivateCallback for
- * a Motif PushButton widget created in XFE_GetFormElementInfo().
- *
- * preconditions:
- * widget != 0 && closure != 0 && call_data != 0
- *
- * returns:
- * not applicable
- *
- **********************************************************************/
- {
- FEFormData *fed = (FEFormData *) closure;
- /*LO_FormSubmitData *data;*/
- /*URL_Struct *url;*/
-
- #ifdef DEBUG
- /* check preconditions in debug mode */
- if (widget == 0 || closure == 0 || call_data == 0) {
- fprintf(stderr, private_precondition_format, __FILE__, __LINE__);
- fflush(stderr);
- }
- #endif
-
-
- {
- XEvent *x_event;
- JSEvent *js_event;
- XP_Bool do_geometry = FALSE;
-
- /*
- * The Motif documentation for XmPushButton informs that call_data
- * is a pointer to XmPushButtonCallbackStruct, declared in Xm/Xm.h.
- */
- x_event = ((XmPushButtonCallbackStruct*)call_data)->event;
- js_event = XP_NEW_ZAP(JSEvent);
-
- js_event->type = EVENT_CLICK;
- fe_complete_js_event(js_event, x_event, do_geometry);
-
- /* Lord Whorfin says: send me a click, dammit! */
- ET_SendEvent (fed->context, (LO_Element *) fed->form, js_event,
- fe_mocha_submit_click_form_cb, closure);
- }
- }
-
- static void
- fe_mocha_button_form_cb (MWContext *context, LO_Element *element, int32 event,
- void *closure, ETEventStatus status)
- {
- if (status != EVENT_OK)
- return;
-
- XFE_GetFormElementValue (context, (LO_FormElementStruct *) element, False);
- }
-
-
-
- /**********************************************************************
- */
-
- static void
- fe_button_form_cb (Widget widget, /* in: a non-NULL valid widget */
- XtPointer closure, /* in: registered by us in XtAddCallback() */
- XtPointer call_data) /* in: from Xt */
-
- /*
- * description:
- * Called when a form button is clicked.
- * This function was registered as an XmNactivateCallback for
- * a Motif PushButton widget created in XFE_GetFormElementInfo().
- *
- * preconditions:
- * widget != 0 && closure != 0 && call_data != 0
- *
- * returns:
- * not applicable
- *
- **********************************************************************/
- {
- FEFormData *form_data = (FEFormData *) closure;
- XEvent *x_event; /* X Windows event structure */
- JSEvent *js_event; /* Javascript event */
- XP_Bool do_geometry = FALSE;
-
- #ifdef DEBUG
- /* check preconditions in debug mode */
- if (widget == 0 || closure == 0 || call_data == 0) {
- fprintf(stderr, private_precondition_format, __FILE__, __LINE__);
- fflush(stderr);
- }
- #endif
- /*
- * The Motif documentation for XmPushButton informs that call_data
- * is a pointer to XmPushButtonCallbackStruct, declared in Xm/Xm.h.
- */
- x_event = ((XmPushButtonCallbackStruct*)call_data)->event;
- js_event = XP_NEW_ZAP(JSEvent);
-
- js_event->type = EVENT_CLICK;
- fe_complete_js_event(js_event, x_event, do_geometry);
- ET_SendEvent (form_data->context,
- (LO_Element *) form_data->form,
- js_event,
- fe_mocha_button_form_cb,
- NULL);
- }
-
- static void
- fe_mocha_reset_form_cb (MWContext *context, LO_Element *element, int32 event,
- void *closure, ETEventStatus status)
- {
- if (status != EVENT_OK)
- return;
-
- LO_ResetForm (context, (LO_FormElementStruct *) element);
- }
-
- /**********************************************************************
- */
-
- static void
- fe_reset_form_cb (Widget widget, XtPointer closure, XtPointer call_data)
-
- /*
- * description:
- * This function was registered as an XmNactivateCallback for
- * a Motif PushButton widget created in XFE_GetFormElementInfo().
- *
- * preconditions:
- * widget != 0 && closure != 0 && call_data != 0
- *
- * returns:
- * not applicable
- *
- **********************************************************************/
- {
- FEFormData *fed = (FEFormData *) closure;
-
- #ifdef DEBUG
- /* check preconditions in debug mode */
- if (widget == 0 || closure == 0 || call_data == 0) {
- fprintf(stderr, private_precondition_format, __FILE__, __LINE__);
- fflush(stderr);
- }
- #endif
-
- {
- XEvent *x_event;
- JSEvent *js_event;
- XP_Bool do_geometry = FALSE;
-
- /*
- * The Motif documentation for XmPushButton informs that call_data
- * is a pointer to XmPushButtonCallbackStruct, declared in Xm/Xm.h.
- */
- x_event = ((XmPushButtonCallbackStruct*)call_data)->event;
- js_event = XP_NEW_ZAP(JSEvent);
-
- js_event->type = EVENT_CLICK;
- fe_complete_js_event(js_event, x_event, do_geometry);
-
- ET_SendEvent (fed->context, (LO_Element *) fed->form, js_event,
- fe_mocha_reset_form_cb, NULL);
- }
- }
-
-
- static void
- fe_got_focus_cb (Widget widget, XtPointer closure, XtPointer call_data)
- {
- FEFormData *fed = (FEFormData *) closure;
- JSEvent *event;
-
- TRACEMSG(("fe_got_focus_c:\n"));
-
- event = XP_NEW_ZAP(JSEvent);
- event->type = EVENT_FOCUS;
-
- ET_SendEvent (fed->context, (LO_Element *) fed->form, event, NULL, NULL);
- }
-
- static void
- fe_lost_focus_cb (Widget widget, XtPointer closure, XtPointer call_data)
- {
- FEFormData *fed = (FEFormData *) closure;
-
- if (!fed) return;
-
- if (fed->vtbl.lost_focus_func)
- (*fed->vtbl.lost_focus_func)(fed);
-
- /* always send a blur event. */
- fe_MochaBlurNotify(fed->context, (LO_Element*)fed->form);
- }
-
- static void
- fe_complete_js_event(JSEvent *js_event, /* inout */
- XEvent *x_event, /* in */
- XP_Bool do_geometry) /* in */
-
- /*
- * description:
- * Updates js_event fields from an X event.
- * Consolidates common code inside various callback
- * functions within this module.
- *
- * preconditions:
- * js_event != 0 && x_event != 0
- * The js_event must already have an assigned type.
- *
- * returns:
- * not applicable
- *
- ****************************************/
- {
- unsigned int state_of_buttons_and_modifiers = 0;
-
- #ifdef DEBUG
- /* check preconditions in debug mode */
- if (js_event == 0 || x_event == 0 || js_event->type == 0) {
- fprintf(stderr, private_precondition_format, __FILE__, __LINE__);
- fflush(stderr);
- }
- #endif
-
- state_of_buttons_and_modifiers = x_event->xbutton.state;
-
- switch(js_event->type) {
- case EVENT_CLICK:
- #ifdef DEBUG_rodt
- /* check in debug mode */
- /* Expect to be processing ButtonRelease */
- if (x_event->type != ButtonRelease) {
- fprintf(stderr, private_check_format, __FILE__, __LINE__);
- fflush(stderr);
- }
- #endif
- {
- unsigned int button;
-
- button = x_event->xbutton.button;
-
- /*
- * MOUSE BUTTON
- *
- * Only verified that left button is 1. 2 should be
- * middle button and 3 should be right button.
- */
- js_event->which = button;
-
- }
- break;
- case EVENT_KEYDOWN:
- case EVENT_KEYUP:
- case EVENT_KEYPRESS:
- #ifdef DEBUG
- /* check in debug mode */
- /* Expect to be processing KeyPress or KeyRelease */
- if (x_event->type != KeyPress && x_event->type != KeyRelease) {
- fprintf(stderr, private_check_format, __FILE__, __LINE__);
- fflush(stderr);
- }
- #endif
- {
- int buffer_length;
- char buffer[32];
- KeySym keysym;
- XComposeStatus * compose_status;
-
- /*
- * DETERMINE ASCII VALUE OF KEY PRESSED FOR JAVASCRIPT
- *
- * The following code needs to be checked on corner cases.
- *
- */
-
- /*
- * Ignore compose status.
- * This may need to be changed.
- */
- compose_status = 0;
-
- /*
- * The XEvent structure is converted to a keysym as well as a
- * string (possibly more than one character) which represents
- * the keysym.
- *
- */
- buffer_length = XLookupString(&(x_event->xkey),
- buffer,
- 31,
- &keysym,
- compose_status);
- if (buffer_length == 1)
- {
- js_event->which = buffer[0];
- }
- else
- {
- /*
- * Force all other cases to return a zero to
- * expose bugs which indicate that this code needs
- * to be modified.
- */
- js_event->which = 0;
- }
-
- if (do_geometry) {
- js_event->x = x_event->xkey.x;
- js_event->y = x_event->xkey.y;
- js_event->screenx = x_event->xkey.x_root;
- js_event->screeny = x_event->xkey.y_root;
- }
- }
- break;
- }
-
- /*
- * ASSIGN MODIFIERS
- */
- if (state_of_buttons_and_modifiers) {
- /*
- * MODIFIER KEYS (ALT, CONTROL, SHIFT, META)
- * EVENT_xxx_MASK's are from ns/include/libevent.h
- */
- if (state_of_buttons_and_modifiers & ControlMask)
- js_event->modifiers |= EVENT_CONTROL_MASK;
- if (state_of_buttons_and_modifiers & ShiftMask)
- js_event->modifiers |= EVENT_SHIFT_MASK;
-
- /*
- * Only verified meta on Solaris 2.5 dtwm (mwm workalike)
- */
- if (state_of_buttons_and_modifiers & Mod4Mask)
- js_event->modifiers |= EVENT_META_MASK;
- }
- }
-
- static void
- fe_key_handler(Widget widget, /* in */
- XtPointer closure, /* in */
- XEvent * x_event, /* in */
- Boolean * bcontinue) /* out */
-
- /*
- * description:
- * Handles XEvents of type KeyPress and KeyRelease in order
- * to pass these along to JavaScript. JavaScript recognizes
- * three key events:
- * EVENT_KEYDOWN corresponds to the X Event KeyPress
- * EVENT_KEYUP corresponds to the X Event KeyRelease
- * EVENT_KEYPRESS corresponds to the X Event KeyPress followed by KeyRelease
- *
- * Do not confuse EVENT_KEYPRESS with the X Event KeyPress!
- *
- * returns:
- * Not applicable. Note that currently bcontinue is not modified.
- *
- * end:
- ****************************************/
- {
- FEFormData *form_data;
- JSEvent *js_event = 0; /* Javascript event */
- static int32 previous_js_event_type = 0;
- static int32 previous_js_event_which = 0;
-
-
- #ifdef DEBUG
- /* check preconditions in debug mode */
- if (widget == 0 || closure == 0 || x_event == 0 || bcontinue == 0) {
- fprintf(stderr, private_precondition_format, __FILE__, __LINE__);
- fflush(stderr);
- }
- #endif
-
- form_data = (FEFormData *) closure;
-
- if (x_event->type == KeyPress) {
- js_event = XP_NEW_ZAP(JSEvent);
- js_event->type = EVENT_KEYDOWN;
- }
- else if (x_event->type == KeyRelease) {
- js_event = XP_NEW_ZAP(JSEvent);
- js_event->type = EVENT_KEYUP;
- }
-
- /*
- * Do further work only on KeyPress and KeyRelease
- */
- if (js_event) {
- XP_Bool do_geometry = TRUE;
-
- fe_complete_js_event(js_event, x_event, do_geometry);
-
- /*
- * SYNTHESIZE AND SEND EVENT_KEYPRESS
- */
- if (previous_js_event_type == EVENT_KEYDOWN
- && js_event->type == EVENT_KEYUP
- && previous_js_event_which == js_event->which)
- {
- JSEvent *synthesized_js_event;
-
- synthesized_js_event = XP_NEW_ZAP(JSEvent);
- XP_MEMCPY(synthesized_js_event, js_event, sizeof(JSEvent));
- synthesized_js_event->type = EVENT_KEYPRESS;
- ET_SendEvent(form_data->context,
- (LO_Element *) form_data->form,
- synthesized_js_event,
- NULL,
- NULL);
- }
-
- /*
- * SEND EVENT_KEYDOWN/UP
- */
- previous_js_event_type = js_event->type;
- previous_js_event_which = js_event->which;
- ET_SendEvent(form_data->context,
- (LO_Element *) form_data->form,
- js_event,
- NULL,
- NULL);
- }
- }
-
- static void
- fe_mocha_radio_form_cb (MWContext *context, LO_Element *element,
- int32 event, void *closure, ETEventStatus status)
- {
- XmToggleButtonCallbackStruct *cb = (XmToggleButtonCallbackStruct *)closure;
- LO_FormElementStruct *save;
-
- if (status == EVENT_OK) {
- if (cb->set)
- save = LO_FormRadioSet (context, (LO_FormElementStruct *) element);
- /* it's possible for save to be null here. it's a legal
- return value from LO_FormRadioSet
- */
- if (cb->set && save && save != (LO_FormElementStruct *) element)
- {
- XFE_SetFormElementToggle (context, save, TRUE);
- LO_FormRadioSet (context, save);
- }
-
- XFE_GetFormElementValue (context, (LO_FormElementStruct *) element, False);
- }
- XP_FREE (cb);
- }
-
- /**********************************************************************
- */
-
- static void
- fe_radio_form_cb (Widget widget, XtPointer closure, XtPointer call_data)
-
- /*
- * description:
- * This function was registered as an XmNvalueChangedCallback for
- * a Motif ToggleButton widget created in XFE_GetFormElementInfo().
- *
- * preconditions:
- * widget != 0 && closure != 0 && call_data != 0
- *
- * returns:
- * not applicable
- *
- **********************************************************************/
- {
- FEFormData *fed = (FEFormData *) closure;
- XmToggleButtonCallbackStruct *cb = (XmToggleButtonCallbackStruct *)call_data;
- LO_FormElementStruct *save;
-
- #ifdef DEBUG
- /* check preconditions in debug mode */
- if (widget == 0 || closure == 0 || call_data == 0) {
- fprintf(stderr, private_precondition_format, __FILE__, __LINE__);
- fflush(stderr);
- }
- #endif
-
- if (cb->set)
- save = LO_FormRadioSet (fed->context, fed->form);
- else
- /* Don't allow the user to ever toggle a button off - exactly one
- must be selected at all times. */
- XtVaSetValues (widget, XmNset, True, 0);
-
- XFE_GetFormElementValue (fed->context, fed->form, False);
-
- {
- XEvent *x_event;
- JSEvent *js_event;
- XP_Bool do_geometry = FALSE;
- XmToggleButtonCallbackStruct *cb_closure;
-
- cb_closure = XP_NEW_ZAP (XmToggleButtonCallbackStruct);
- XP_MEMCPY (cb_closure, cb, sizeof (XmToggleButtonCallbackStruct));
-
- x_event = cb_closure->event;
- js_event = XP_NEW_ZAP(JSEvent);
- js_event->type = EVENT_CLICK;
- fe_complete_js_event(js_event, x_event, do_geometry);
-
- ET_SendEvent (fed->context, (LO_Element *) fed->form, js_event,
- fe_mocha_radio_form_cb, cb_closure);
- }
- }
-
- static void
- fe_check_form_cb (Widget widget, XtPointer closure, XtPointer call_data)
-
- /*
- * description:
- * This function was registered as an XmNvalueChangedCallback for
- * a Motif ToggleButton widget created in XFE_GetFormElementInfo().
- *
- * preconditions:
- * widget != 0 && closure != 0 && call_data != 0
- *
- * returns:
- * not applicable
- *
- **********************************************************************/
- {
- FEFormData *form_data = (FEFormData *) closure;
- XEvent *x_event; /* X Windows event structure */
- JSEvent *js_event;
- XP_Bool do_geometry = FALSE;
- lo_FormElementToggleData *data;
- Bool save;
-
- #ifdef DEBUG
- /* check preconditions in debug mode */
- if (widget == 0 || closure == 0 || call_data == 0) {
- fprintf(stderr, private_precondition_format, __FILE__, __LINE__);
- fflush(stderr);
- }
- #endif
-
- data = &form_data->form->element_data->ele_toggle;
- save = data->toggled;
-
- XFE_GetFormElementValue (form_data->context, form_data->form, False);
-
- /*
- * The Motif documentation for XmToggleButton informs that call_data
- * is a pointer to XmToggleButtonCallbackStruct, declared in Xm/Xm.h.
- */
- x_event = ((XmToggleButtonCallbackStruct*)call_data)->event;
- js_event = XP_NEW_ZAP(JSEvent);
- js_event->type = EVENT_CLICK;
- fe_complete_js_event(js_event, x_event, do_geometry);
-
- ET_SendEvent (form_data->context,
- (LO_Element *) form_data->form,
- js_event,
- NULL,
- NULL);
- }
-
- static void
- fe_combo_form_cb(Widget widget, XtPointer closure, XtPointer call_data)
- {
- FESelectOneFormData *sel_fed = (FESelectOneFormData *) closure;
- DtComboBoxCallbackStruct *cb = (DtComboBoxCallbackStruct *) call_data;
- LO_FormElementData *form_data;
- lo_FormElementOptionData *option_data;
- int i;
-
- form_data = XP_GetFormElementData(sel_fed->form_data.form);
-
- for (i = 0; i < sel_fed->nkids; i++)
- {
- option_data = XP_FormSelectGetOption(form_data,
- i);
-
- /* combo boxes start the item ordering at 0, not 1. */
- sel_fed->selected_p [i] = (i == cb->item_position);
-
- XP_FormOptionSetSelected(option_data, sel_fed->selected_p[i]);
- }
- {
- JSEvent *event = XP_NEW_ZAP(JSEvent);
-
- event->type = EVENT_CHANGE;
-
- ET_SendEvent (sel_fed->form_data.context,
- (LO_Element *) sel_fed->form_data.form,
- event,
- NULL, NULL);
- }
- }
-
- static void
- fe_list_form_cb (Widget widget, XtPointer closure, XtPointer call_data)
- {
- FESelectMultFormData *sel_fed = (FESelectMultFormData *) closure;
- XmListCallbackStruct *cb = (XmListCallbackStruct *) call_data;
- LO_FormElementData *form_data;
- lo_FormElementOptionData *option_data;
- int i, j;
-
- form_data = XP_GetFormElementData(sel_fed->form_data.form);
-
- switch (cb->reason)
- {
- case XmCR_SINGLE_SELECT:
- case XmCR_BROWSE_SELECT:
- for (i = 0; i < sel_fed->nkids; i++)
- {
- option_data = XP_FormSelectGetOption(form_data,
- i);
-
- /* Note that the item_position starts at 1, not 0!!!! */
- sel_fed->selected_p [i] = (cb->selected_item_count &&
- i == (cb->item_position - 1));
-
- XP_FormOptionSetSelected(option_data, sel_fed->selected_p[i]);
- }
- break;
- case XmCR_MULTIPLE_SELECT:
- case XmCR_EXTENDED_SELECT:
- for (i = 0; i < sel_fed->nkids; i++)
- {
- /*
- **
- ** toshok -- this is extremely gross and inefficient. must
- ** revisit it. XXXXX
- **
- */
- option_data = XP_FormSelectGetOption(form_data,
- i);
-
- sel_fed->selected_p [i] = 0;
- XP_FormOptionSetSelected(option_data, sel_fed->selected_p[i]);
-
- for (j = 0; j < cb->selected_item_count; j++)
- if (i == (cb->selected_item_positions [j] - 1))
- {
- sel_fed->selected_p [i] = 1;
- XP_FormOptionSetSelected(option_data, sel_fed->selected_p[i]);
- }
- }
- break;
- case XmCR_DEFAULT_ACTION:
- break;
- default:
- assert (0);
- return;
- }
-
- {
- JSEvent *event = XP_NEW_ZAP(JSEvent);
-
- event->type = EVENT_CHANGE;
-
- ET_SendEvent (sel_fed->form_data.context,
- (LO_Element *) sel_fed->form_data.form,
- event,
- NULL, NULL);
- }
- }
-
-
- void
- XFE_ResetFormElement (MWContext *context, LO_FormElementStruct *form)
- {
- LO_FormElementData *form_data = XP_GetFormElementData(form);
- FEFormData *fed = (FEFormData*)XP_FormGetFEData(form_data);
-
- XP_ASSERT(fed);
- if (!fed) return;
-
- if (fed->vtbl.reset_element)
- (*fed->vtbl.reset_element)(fed, form);
- }
-
- /* don't *really* need a vtable entry for this one... or maybe we do. */
- void
- XFE_SetFormElementToggle (MWContext *context, LO_FormElementStruct *form,
- XP_Bool state)
- {
- LO_FormElementData *form_data = XP_GetFormElementData(form);
- FEFormData *fed;
- int32 form_type;
-
- if (form_data == NULL) {
- #ifdef DEBUG_username
- printf ("forms.c:%d; form_data == NULL\n", __LINE__);
- #endif
- return;
- }
-
- fed = (FEFormData*)XP_FormGetFEData(form_data);
- form_type = XP_FormGetType(form_data);
-
- XP_ASSERT(form_type == FORM_TYPE_CHECKBOX ||
- form_type == FORM_TYPE_RADIO);
- if (form_type != FORM_TYPE_CHECKBOX
- && form_type != FORM_TYPE_RADIO)
- return;
-
- XtVaSetValues (fed->widget, XmNset, state, 0);
- }
-
- void
- fe_SetFormsGravity (MWContext *context, int gravity)
- {
- Widget *kids;
- Widget area;
- Cardinal nkids = 0;
- XSetWindowAttributes attr;
- unsigned long valuemask;
-
-
- XtVaGetValues (CONTEXT_DATA (context)->drawing_area,
- XmNchildren, &kids, XmNnumChildren, &nkids,
- 0);
-
- valuemask = CWBitGravity | CWWinGravity;
- attr.win_gravity = gravity;
- attr.bit_gravity = gravity;
- area = CONTEXT_DATA (context)->drawing_area;
- XChangeWindowAttributes (XtDisplay(area), XtWindow(area), valuemask, &attr);
- while (nkids--)
- {
- if (XtIsManaged (kids[nkids]))
- XChangeWindowAttributes (XtDisplay(kids[nkids]), XtWindow(kids[nkids]),
- valuemask, &attr);
- }
- }
-
- void
- fe_ScrollForms (MWContext *context, int x_off, int y_off)
- {
- Widget *kids;
- Cardinal nkids = 0;
-
- if (x_off == 0 && y_off == 0)
- return;
-
- XtVaGetValues (CONTEXT_DATA (context)->drawing_area,
- XmNchildren, &kids, XmNnumChildren, &nkids,
- 0);
- while (nkids--)
- XtMoveWidget (kids [nkids],
- _XfeX(kids [nkids]) + x_off,
- _XfeY(kids [nkids]) + y_off);
- }
-
-
- void
- fe_GravityCorrectForms (MWContext *context, int x_off, int y_off)
- {
- Widget *kids;
- Cardinal nkids = 0;
-
- if (x_off == 0 && y_off == 0)
- return;
-
- XtVaGetValues (CONTEXT_DATA (context)->drawing_area,
- XmNchildren, &kids, XmNnumChildren, &nkids,
- 0);
-
- while (nkids--)
- {
- if (XtIsManaged (kids[nkids]))
- {
- _XfeX(kids[nkids]) = _XfeX(kids[nkids]) + x_off;
- _XfeY(kids[nkids]) = _XfeY(kids[nkids]) + y_off;
- }
- }
- }
-
-