+1999-11-10 XEmacs Build Bot <builds@cvs.xemacs.org>
+
+ * XEmacs 21.2.20 is released
+
+1999-09-09 Andy Piper <andy@xemacs.org>
+
+ * xlwtabs.c: updated tabs widget from Ed Falk.
+ * xlwtabs.h: ditto.
+ * xlwtabsP.h: ditto.
+
+1999-09-22 Martin Buchholz <martin@xemacs.org>
+
+ * lwlib-internal.h:
+ * lwlib-utils.h:
+ Move declaration of destroy_all_children from lwlib-internal.h to
+ lwlib-utils.h, where it belongs.
+
+1999-09-21 Andy Piper <andy@xemacs.org>
+
+ * lwlib-Xm.c (xm_update_label): don't clobber pixmap type labels
+ with text.
+
+1999-09-22 Martin Buchholz <martin@xemacs.org>
+
+ * xlwtabs.c: Fix C++ compilability.
+
+1999-09-18 Andy Piper <andy@xemacs.org>
+
+ * xlwtabs.c: Put in tabs sync because clipping should fix useability
+ problems.
+
+1999-09-13 Andy Piper <andy@xemacs.org>
+
+ * xlwtabs.c: Back out tabs sync because of reported useability
+ problems.
+
+1999-09-09 Andy Piper <andy@xemacs.org>
+
+ * xlwtabs.c: updated tabs widget from Ed Falk.
+ * xlwtabs.h: ditto.
+ * xlwtabsP.h: ditto.
+ * xlwgcs.c: ditto.
+ * xlwgcs.h: ditto.
+
+1999-09-03 Martin Buchholz <martin@xemacs.org>
+
+ * xlwgauge.c: Ansify.
+ Include <stdlib.h> to get prototype for atoi().
+ (GaugeSelect): Call GaugeExpose with the right number of args.
+ (GaugeLoseSel): Call GaugeExpose with the right number of args.
+ (GaugeConvert): This is a XtConvertSelectionProc,
+ so 5th parameter must be of type XtPointer, not XPointer.
+ (GaugeGetValue): This is a XtTimerCallbackProc,
+ so 2nd parameter must be of type XtIntervalId *, not XtIntervalId.
+
+
+1999-09-01 Martin Buchholz <martin@xemacs.org>
+
+ * lwlib.c (free_widget_value_contents): Use proper type for cast.
+
+ * xlwradio.c: Use function prototypes everywhere.
+ * xlwcheckbox.c:
+ * xlwradio.c:
+ * xlwradioP.h: Move declarations of non-static functions defined
+ in xlwradio.c into xlwradioP.h.
+
+1999-09-02 Andy Piper <andy@xemacs.org>
+
+ * xlwgcs.c: include xmu.h
+
+1999-09-01 Andy Piper <andy@xemacs.org>
+
+ * xlwgauge.c: rearrange headers yet again.
+ * xlwcheckbox.c: ditto.
+ * xlwradio.c: ditto.
+ * xlwtabs.c: ditto.
+
+1999-09-01 Andy Piper <andy@xemacs.org>
+
+ * xlwgauge.c: use xmu.h
+ * xlwcheckbox.c: ditto.
+ * xlwradio.c: ditto.
+
+1999-08-31 Andy Piper <andy@xemacs.org>
+
+ * xlwtabs.c:
+ * xlwgcs.c:
+ * xlwradio.c:
+ * xlwcheckbox.c:
+ * xlwgauge.c: Fix for losing systems without Xmu.
+
+1999-08-31 Andy Piper <andy@xemacs.org>
+
+ * lwlib-Xm.c (xm_update_one_widget): fix for AIX compiler lossage.
+
+1999-08-30 Andy Piper <andy@xemacs.org>
+
+ * lwlib.c (free_widget_value_contents): be more precise about
+ freeing user defined args.
+
+ * lwlib-Xaw.c (xaw_update_one_widget): make sure we use val not
+ its contents for hierarchies one deep.
+
+1999-08-29 Andy Piper <andy@xemacs.org>
+
+ * xlwtabs.c: temporary fixes pending a new release.
+ * xlwtabsP.h: ditto.
+
+ * lwlib-Xm.c (xm_update_one_widget): update user defined args.
+ (xm_create_label): set args after creation as well as before.
+
+ * lwlib-Xlw.c (xlw_create_tab_control): orient tabs horizontally.
+ (xlw_update_tab_control): actually update the children rather than
+ the parent.
+
+ * lwlib-Xaw.c (xaw_update_one_widget): update user defined args.
+ (xaw_create_label): set args after creation as well as before.
+
+1999-08-23 Andy Piper <andy@xemacs.org>
+
+ * lwlib-Xm.c (xm_update_label): don't concatenate value to itself.
+
+ * lwlib-Xm.c (xm_create_label_field): new function for creating labels.
+ (xm_creation_table): use it.
+
+ * lwlib-Xaw.c (xaw_create_label_field): new function for creating labels.
+ (xaw_creation_table): use it.
+
+1999-08-16 Andy Piper <andy@xemacs.org>
+
+ * lwlib.h: declare free_widget_value_tree.
+
+ * lwlib.c (free_widget_value_tree): make non-static.
+
+ * lwlib-Xm.c (xm_update_label): free val_string when updating.
+
+1999-08-04 Andy Piper <andy@xemacs.org>
+
+ * lwlib-Xm.c (mark_dead_instance_destroyed): change so that its
+ defined for widgets.
+ (xm_nosel_callback): ditto.
+
+ * xlwtabsP.h: sync with 1.5.
+
+ * xlwtabs.c: sync with 1.18.
+
+1999-07-28 Andy Piper <andy@xemacs.org>
+
+ * xlwtabs.c: new lucid tabs widget from Ed Falk.
+ * xlwtabs.h: ditto.
+ * xlwtabsP.h: ditto.
+ * xlwgcs.c: GC manipulation for tab widgets.
+ * xlwgcs.h: ditto.
+
+ * xlwgauge.c: new athena gauge widget from Ed Falk.
+ * xlwgauge.h: ditto.
+ * xlwgaugeP.h: ditto.
+
+ * xlwradio.c: new athena radio widget from Ed Falk.
+ * xlwradio.h: ditto.
+ * xlwradioP.h: ditto.
+
+ * xlwcheckbox.c: new athena checkbox widget from Ed Falk.
+ * xlwcheckbox.h: ditto.
+ * xlwcheckboxP.h: ditto.
+
+ * lwlib-utils.c (destroy_all_children): moved from lwlib-Xm.c.
+
+ * lwlib-internal.h: declare destroy_all_children.
+
+ * lwlib-config.c: add widget checks.
+
+ * lwlib-Xm.h: declare xm_create_label;
+
+ * lwlib-Xm.c (destroy_all_children): move to lwlib-utils.c.
+ (xm_update_label): enable for widgets.
+ (xm_update_one_widget): ditto.
+ (xm_create_button): rename in line with lwlib-Xaw.c
+ (xm_create_progress): ditto.
+ (xm_create_text_field): ditto.
+ (xm_create_combo_box): ditto.
+ (xm_create_label): new function.
+ (xm_creation_table): rename widget creation functions.
+ (xm_destroy_instance): enable for widgets.
+ (xm_generic_callback): ditto.
+ (xm_generic_callback): ditto.
+
+ * lwlib-Xlw.c (xlw_tab_control_callback): new function. a special
+ callback that calls the correct function depending on what tab is
+ selected.
+ (xlw_create_tab_control): new function.
+ (build_tabs_in_widget): new function. puts tabs in a tab widget,
+ uses Xaw or Xm depending on how XEmacs was compiled.
+ (xlw_update_tab_control): update the resources for each
+ tab. optionally rebuild the contents of the tab widget.
+ (xlw_creation_table): add tab widget creation function.
+ (lw_lucid_widget_p): add tab widget.
+ (xlw_update_one_widget): ditto.
+
+ * lwlib-Xaw.h: declare xaw_create_label;
+
+ * lwlib-Xaw.c (lw_xaw_widget_p): add widgets classes.
+ (xaw_update_one_widget): ditto.
+ (xaw_update_one_value): add code from the Xm version.
+ (xaw_generic_callback): add Xm hack for setting command
+ states. beef up lookup of call data.
+ (xaw_create_button): new function.
+ (xaw_create_label): new function for use by tab widget.
+ (xaw_create_progress): new function.
+ (xaw_create_text_field): new function.
+ (xaw_creation_table): add new widget type creation functions.
+
+ * Makefile.in.in: add dependencies for new lw widgets.
+
1999-07-30 XEmacs Build Bot <builds@cvs.xemacs.org>
* XEmacs 21.2.19 is released
## Following correct as of 19980312
-lwlib-Xaw.o: $(CONFIG_H) lwlib-Xaw.h lwlib-internal.h lwlib.h xlwmenu.h
-lwlib-Xlw.o: $(CONFIG_H) lwlib-Xlw.h lwlib-internal.h lwlib.h xlwmenu.h xlwscrollbar.h
+lwlib-Xaw.o: $(CONFIG_H) lwlib-Xaw.h lwlib-internal.h lwlib.h xlwmenu.h xlwradio.h \
+xlwgauge.h xlwcheckbox.h
+lwlib-Xlw.o: $(CONFIG_H) lwlib-Xlw.h lwlib-internal.h lwlib.h xlwmenu.h xlwscrollbar.h \
+xlwtabs.h xlwgcs.h
lwlib-Xm.o: $(CONFIG_H) lwlib-Xm.h lwlib-internal.h lwlib-utils.h lwlib.h xlwmenu.h
lwlib-config.o: $(CONFIG_H) lwlib.h xlwmenu.h
lwlib-utils.o: $(CONFIG_H) lwlib-utils.h
lwlib.o: $(CONFIG_H) lwlib-Xaw.h lwlib-Xlw.h lwlib-Xm.h lwlib-internal.h lwlib-utils.h lwlib.h xlwmenu.h
xlwmenu.o: $(CONFIG_H) lwlib.h xlwmenu.h xlwmenuP.h
xlwscrollbar.o: $(CONFIG_H) xlwscrollbar.h xlwscrollbarP.h
+xlwtabs.o: $(CONFIG_H) xlwtabs.h xlwtabsP.h
+xlwradio.o: $(CONFIG_H) xlwradio.h xlwradioP.h
+xlwcheckbox.o: $(CONFIG_H) xlwcheckbox.h xlwcheckboxP.h
+xlwgauge.o: $(CONFIG_H) xlwgauge.h xlwgaugeP.h
+xlwgcs.o: $(CONFIG_H) xlwgcs.h
#include <X11/Xaw/Command.h>
#include <X11/Xaw/Label.h>
#endif
-
+#ifdef LWLIB_WIDGETS_ATHENA
+#include <X11/Xaw/Toggle.h>
+#include "xlwradio.h"
+#include "xlwcheckbox.h"
+#include "xlwgauge.h"
+#ifndef NEED_MOTIF
+#include <X11/Xaw/AsciiText.h>
+#endif
+#endif
#include <X11/Xatom.h>
static void xaw_generic_callback (Widget, XtPointer, XtPointer);
#ifdef LWLIB_DIALOGS_ATHENA
|| XtIsSubclass (widget, dialogWidgetClass)
#endif
+#ifdef LWLIB_WIDGETS_ATHENA
+ || XtIsSubclass (widget, labelWidgetClass)
+ || XtIsSubclass (widget, toggleWidgetClass)
+ || XtIsSubclass (widget, gaugeWidgetClass)
+#if 0
+ || XtIsSubclass (widget, textWidgetClass)
+#endif
+#endif
);
}
xaw_update_one_widget (widget_instance *instance, Widget widget,
widget_value *val, Boolean deep_p)
{
+ if (val->nargs)
+ XtSetValues (widget, val->args, val->nargs);
+
if (0)
;
#ifdef LWLIB_SCROLLBARS_ATHENA
XtSetArg (al [0], XtNlabel, val->contents->value);
XtSetValues (widget, al, 1);
}
+#endif /* LWLIB_DIALOGS_ATHENA */
+#ifdef LWLIB_WIDGETS_ATHENA
+ else if (XtClass (widget) == labelWidgetClass)
+ {
+ Arg al [1];
+ XtSetArg (al [0], XtNlabel, val->value);
+ XtSetValues (widget, al, 1);
+ }
+#endif /* LWLIB_WIDGETS_ATHENA */
+#if defined (LWLIB_DIALOGS_ATHENA) || defined (LWLIB_WIDGETS_ATHENA)
else if (XtIsSubclass (widget, commandWidgetClass))
{
Dimension bw = 0;
XtRemoveAllCallbacks (widget, XtNcallback);
XtAddCallback (widget, XtNcallback, xaw_generic_callback, instance);
+#ifdef LWLIB_WIDGETS_ATHENA
+ /* set the selected state */
+ if (XtIsSubclass (widget, toggleWidgetClass))
+ {
+ XtSetArg (al [0], XtNstate, val->selected);
+ XtSetValues (widget, al, 1);
+ }
+#endif /* LWLIB_WIDGETS_ATHENA */
}
#endif /* LWLIB_DIALOGS_ATHENA */
}
xaw_update_one_value (widget_instance *instance, Widget widget,
widget_value *val)
{
- /* This function is not used by the scrollbars and those are the only
- Athena widget implemented at the moment so do nothing. */
- return;
+#ifdef LWLIB_WIDGETS_ATHENA
+ widget_value *old_wv;
+
+ /* copy the call_data slot into the "return" widget_value */
+ for (old_wv = instance->info->val->contents; old_wv; old_wv = old_wv->next)
+ if (!strcmp (val->name, old_wv->name))
+ {
+ val->call_data = old_wv->call_data;
+ break;
+ }
+
+ if (XtIsSubclass (widget, toggleWidgetClass))
+ {
+ Arg al [1];
+ XtSetArg (al [0], XtNstate, &val->selected);
+ XtGetValues (widget, al, 1);
+ val->edited = True;
+ }
+#ifndef NEED_MOTIF
+ else if (XtIsSubclass (widget, asciiTextWidgetClass))
+ {
+ Arg al [1];
+ if (val->value)
+ free (val->value);
+ XtSetArg (al [0], XtNstring, &val->value);
+ XtGetValues (widget, al, 1);
+ val->edited = True;
+ }
+#endif
+#endif /* LWLIB_WIDGETS_ATHENA */
}
void
Widget instance_widget;
LWLIB_ID id;
XtPointer user_data;
+#ifdef LWLIB_WIDGETS_ATHENA
+ /* We want the selected status to change only when we decide it
+ should change. Yuck but correct. */
+ if (XtIsSubclass (widget, toggleWidgetClass))
+ {
+ Boolean check;
+ Arg al [1];
+
+ XtSetArg (al [0], XtNstate, &check);
+ XtGetValues (widget, al, 1);
+ XtSetArg (al [0], XtNstate, !check);
+ XtSetValues (widget, al, 1);
+ }
+#endif /* LWLIB_WIDGETS_ATHENA */
lw_internal_update_other_instances (widget, closure, call_data);
if (! instance)
#else
/* Damn! Athena doesn't give us a way to hang our own data on the
buttons, so we have to go find it... I guess this assumes that
- all instances of a button have the same call data. */
+ all instances of a button have the same call data.
+
+ ... Which is a totally bogus assumption --andyp */
{
- widget_value *val = instance->info->val->contents;
- char *name = XtName (widget);
- while (val)
+ widget_value *val = instance->info->val;
+ /* If the widget is a buffer/gutter widget then we already have
+ the one we are looking for, so don't try and descend the widget
+ tree. */
+ if (val->contents)
{
- if (val->name && !strcmp (val->name, name))
- break;
- val = val->next;
+ char *name = XtName (widget);
+ val = val->contents;
+ while (val)
+ {
+ if (val->name && !strcmp (val->name, name))
+ break;
+ val = val->next;
+ }
+ if (! val) abort ();
}
- if (! val) abort ();
user_data = val->call_data;
}
#endif
}
#endif /* LWLIB_SCROLLBARS_ATHENA */
+#ifdef LWLIB_WIDGETS_ATHENA
+/* glyph widgets */
+static Widget
+xaw_create_button (widget_instance *instance)
+{
+ Arg al[20];
+ int ac = 0;
+ Widget button = 0;
+ widget_value* val = instance->info->val;
+
+ XtSetArg (al [ac], XtNsensitive, val->enabled); ac++;
+ XtSetArg (al [ac], XtNmappedWhenManaged, FALSE); ac++;
+ XtSetArg (al [ac], XtNjustify, XtJustifyCenter); ac++;
+ /* The highlight doesn't appear to be dynamically set which makes it
+ look ugly. I think this may be a LessTif bug but for now we just
+ get rid of it. */
+ XtSetArg (al [ac], XtNhighlightThickness, (Dimension)0);ac++;
+
+ /* add any args the user supplied for creation time */
+ lw_add_value_args_to_args (val, al, &ac);
+
+ if (!val->call_data)
+ button = XtCreateManagedWidget (val->name, labelWidgetClass,
+ instance->parent, al, ac);
+
+ else
+ {
+ if (val->type == TOGGLE_TYPE || val->type == RADIO_TYPE)
+ {
+ XtSetArg (al [ac], XtNstate, val->selected); ac++;
+ button = XtCreateManagedWidget
+ (val->name,
+ val->type == TOGGLE_TYPE ? checkboxWidgetClass : radioWidgetClass,
+ instance->parent, al, ac);
+ }
+ else
+ {
+ button = XtCreateManagedWidget (val->name, commandWidgetClass,
+ instance->parent, al, ac);
+ }
+ XtRemoveAllCallbacks (button, XtNcallback);
+ XtAddCallback (button, XtNcallback, xaw_generic_callback, (XtPointer)instance);
+ }
+
+ XtManageChild (button);
+
+ return button;
+}
+
+static Widget
+xaw_create_label_field (widget_instance *instance)
+{
+ return xaw_create_label (instance->parent, instance->info->val);
+}
+
+Widget
+xaw_create_label (Widget parent, widget_value* val)
+{
+ Arg al[20];
+ int ac = 0;
+ Widget label = 0;
+
+ XtSetArg (al [ac], XtNsensitive, val->enabled); ac++;
+ XtSetArg (al [ac], XtNmappedWhenManaged, FALSE); ac++;
+ XtSetArg (al [ac], XtNjustify, XtJustifyCenter); ac++;
+
+ /* add any args the user supplied for creation time */
+ lw_add_value_args_to_args (val, al, &ac);
+
+ label = XtCreateManagedWidget (val->name, labelWidgetClass,
+ parent, al, ac);
+
+ /* Do it again for arguments that have no effect until the widget is realized. */
+ ac = 0;
+ lw_add_value_args_to_args (val, al, &ac);
+ XtSetValues (label, al, ac);
+
+ return label;
+}
+
+static Widget
+xaw_create_progress (widget_instance *instance)
+{
+ Arg al[20];
+ int ac = 0;
+ Widget scale = 0;
+ widget_value* val = instance->info->val;
+
+ if (!val->call_data)
+ {
+ XtSetArg (al [ac], XtNsensitive, False); ac++;
+ }
+ else
+ {
+ XtSetArg (al [ac], XtNsensitive, val->enabled); ac++;
+ }
+ XtSetArg (al [ac], XtNmappedWhenManaged, FALSE); ac++;
+ XtSetArg (al [ac], XtNorientation, XtorientHorizontal); ac++;
+ XtSetArg (al [ac], XtNhighlightThickness, (Dimension)0);ac++;
+ XtSetArg (al [ac], XtNntics, (Cardinal)10);ac++;
+
+ /* add any args the user supplied for creation time */
+ lw_add_value_args_to_args (val, al, &ac);
+
+ scale = XtCreateManagedWidget (val->name, gaugeWidgetClass,
+ instance->parent, al, ac);
+ /* add the callback */
+ if (val->call_data)
+ XtAddCallback (scale, XtNgetValue, xaw_generic_callback, (XtPointer)instance);
+
+ XtManageChild (scale);
+
+ return scale;
+}
+
+#ifndef NEED_MOTIF
+static Widget
+xaw_create_text_field (widget_instance *instance)
+{
+ Arg al[20];
+ int ac = 0;
+ Widget text = 0;
+ widget_value* val = instance->info->val;
+
+ XtSetArg (al [ac], XtNsensitive, val->enabled && val->call_data); ac++;
+ XtSetArg (al [ac], XtNmappedWhenManaged, FALSE); ac++;
+ XtSetArg (al [ac], XtNhighlightThickness, (Dimension)0); ac++;
+ XtSetArg (al [ac], XtNtype, XawAsciiString); ac++;
+ XtSetArg (al [ac], XtNeditType, XawtextEdit); ac++;
+
+ /* add any args the user supplied for creation time */
+ lw_add_value_args_to_args (val, al, &ac);
+
+ text = XtCreateManagedWidget (val->name, asciiTextWidgetClass,
+ instance->parent, al, ac);
+ XtManageChild (text);
+
+ return text;
+}
+#endif
+#endif /* LWLIB_WIDGETS_ATHENA */
+
widget_creation_entry
xaw_creation_table [] =
{
#ifdef LWLIB_SCROLLBARS_ATHENA
- {"vertical-scrollbar", xaw_create_vertical_scrollbar},
- {"horizontal-scrollbar", xaw_create_horizontal_scrollbar},
+ {"vertical-scrollbar", xaw_create_vertical_scrollbar },
+ {"horizontal-scrollbar", xaw_create_horizontal_scrollbar },
+#endif
+#ifdef LWLIB_WIDGETS_ATHENA
+ {"button", xaw_create_button },
+ { "label", xaw_create_label_field },
+#ifndef NEED_MOTIF
+ {"text-field", xaw_create_text_field },
+#endif
+ {"progress", xaw_create_progress },
#endif
{NULL, NULL}
};
+
Widget
xaw_create_dialog (widget_instance* instance);
+Widget
+xaw_create_label (Widget parent, widget_value* val);
+
Boolean
lw_xaw_widget_p (Widget widget);
#include <config.h>
#include <stdlib.h> /* for abort () */
+#include <stdio.h> /* for abort () */
#include <limits.h>
#include "lwlib-Xlw.h"
+#include "lwlib-utils.h"
#include <X11/StringDefs.h>
#include <X11/IntrinsicP.h>
#include <X11/ObjectP.h>
#include <X11/CompositeP.h>
#include <X11/Shell.h>
+#ifdef HAVE_WIDGETS
+#include "../src/EmacsManager.h"
+#endif
#ifdef LWLIB_MENUBARS_LUCID
#include "xlwmenu.h"
#endif
#ifdef LWLIB_SCROLLBARS_LUCID
#include "xlwscrollbar.h"
#endif
+#ifdef LWLIB_TABS_LUCID
+#ifdef NEED_MOTIF
+#include "lwlib-Xm.h"
+#endif
+#ifdef NEED_ATHENA
+#include "lwlib-Xaw.h"
+#endif
+#include "../src/xmu.h"
+#include "xlwtabs.h"
+#endif
\f
#endif /* LWLIB_SCROLLBARS_LUCID */
+#ifdef LWLIB_TABS_LUCID
+/* tab control
+
+ lwlib is such an incredible hairy crock. I just cannot believe
+ it! There are random dependencies between functions, there is a
+ total lack of genericity, even though it initially appears to be
+ generic. It should all be junked and begun again. Building tabs are
+ an example - in theory we should be able to reuse a lot of the
+ general stuff because we want to put labels of whatever toolkit we
+ are using in the tab. Instead we have to hack it by hand. */
+static void
+xlw_tab_control_callback (Widget w, XtPointer client_data, XtPointer call_data)
+{
+ /* call data is the topmost widget */
+ widget_instance* instance = (widget_instance*)client_data;
+ Widget top = (Widget)call_data;
+ char *name = XtName (top);
+ widget_value* widget_val;
+ XtPointer widget_arg;
+ LWLIB_ID id;
+ lw_callback post_activate_cb;
+
+ if (w->core.being_destroyed)
+ return;
+
+ /* Grab these values before running any functions, in case running
+ the selection_cb causes the widget to be destroyed. */
+ id = instance->info->id;
+ post_activate_cb = instance->info->post_activate_cb;
+
+ /* search for the widget_val for the selected tab */
+ for (widget_val = instance->info->val->contents; widget_val;
+ widget_val = widget_val->next)
+ {
+ if (!strcmp (widget_val->name, name))
+ break;
+ }
+
+ widget_arg = widget_val ? widget_val->call_data : NULL;
+
+ if (instance->info->selection_cb &&
+ widget_val &&
+ widget_val->enabled &&
+ !widget_val->contents)
+ instance->info->selection_cb (w, id, widget_arg);
+
+ if (post_activate_cb)
+ post_activate_cb (w, id, widget_arg);
+}
+
+static Widget
+xlw_create_tab_control (widget_instance *instance)
+{
+ Arg al[20];
+ int ac = 0;
+ Widget tab = 0;
+ widget_value* val = instance->info->val;
+
+ XtSetArg (al [ac], XtNsensitive, val->enabled); ac++;
+ XtSetArg (al [ac], XtNmappedWhenManaged, FALSE); ac++;
+ XtSetArg (al [ac], XtNorientation, XtorientHorizontal); ac++;
+ XtSetArg (al [ac], XtNresizable, False); ac++;
+
+ /* add any args the user supplied for creation time */
+ lw_add_value_args_to_args (val, al, &ac);
+
+ tab = XtCreateManagedWidget (val->name, tabsWidgetClass,
+ instance->parent, al, ac);
+ XtRemoveAllCallbacks (tab, XtNcallback);
+ XtAddCallback (tab, XtNcallback, xlw_tab_control_callback, (XtPointer)instance);
+
+ XtManageChild (tab);
+
+ return tab;
+}
+
+static void build_tabs_in_widget (widget_instance* instance, Widget widget,
+ widget_value* val)
+{
+ widget_value* cur = val;
+ for (cur = val; cur; cur = cur->next)
+ {
+ if (cur->value)
+ {
+#ifdef LWLIB_WIDGETS_MOTIF
+ xm_create_label (widget, cur);
+#else
+ xaw_create_label (widget, cur);
+#endif
+ }
+ cur->change = NO_CHANGE;
+ }
+}
+
+static void
+xlw_update_tab_control (widget_instance* instance, Widget widget, widget_value* val)
+{
+ Widget* children;
+ unsigned int num_children;
+ int i;
+ widget_value *cur = 0;
+
+ XtRemoveAllCallbacks (widget, XtNcallback);
+ XtAddCallback (widget, XtNcallback, xlw_tab_control_callback, (XtPointer)instance);
+
+ if (val->change == STRUCTURAL_CHANGE
+ ||
+ (val->contents && val->contents->change == STRUCTURAL_CHANGE))
+ {
+ destroy_all_children (widget);
+ build_tabs_in_widget (instance, widget, val->contents);
+ }
+
+ children = XtCompositeChildren (widget, &num_children);
+ if (children)
+ {
+ for (i = 0, cur = val->contents; i < num_children; i++)
+ {
+ if (!cur)
+ abort ();
+ if (children [i]->core.being_destroyed
+ || strcmp (XtName (children [i]), cur->name))
+ continue;
+#ifdef NEED_MOTIF
+ if (lw_motif_widget_p (children [i]))
+ xm_update_one_widget (instance, children [i], cur, False);
+#endif
+#ifdef NEED_ATHENA
+ if (lw_xaw_widget_p (children [i]))
+ xaw_update_one_widget (instance, children [i], cur, False);
+#endif
+ cur = cur->next;
+ }
+ XtFree ((char *) children);
+ }
+ if (cur)
+ abort ();
+}
+#endif /* LWLIB_TABS_LUCID */
+
+#ifdef HAVE_WIDGETS
+static Widget
+xlw_create_clip_window (widget_instance *instance)
+{
+ Arg al[20];
+ int ac = 0;
+ Widget clip = 0;
+ widget_value* val = instance->info->val;
+
+ XtSetArg (al [ac], XtNmappedWhenManaged, FALSE); ac++;
+ XtSetArg (al [ac], XtNsensitive, TRUE); ac++;
+ /* add any args the user supplied for creation time */
+ lw_add_value_args_to_args (val, al, &ac);
+
+ /* Create a clip window to contain the subwidget. Incredibly the
+ XEmacs manager seems to be the most appropriate widget for
+ this. Nothing else is simple enough and yet does what is
+ required. */
+ clip = XtCreateManagedWidget (val->name,
+ emacsManagerWidgetClass,
+ instance->parent, al, ac);
+
+ return clip;
+}
+#endif
+
widget_creation_entry
xlw_creation_table [] =
{
{"vertical-scrollbar", xlw_create_vertical_scrollbar},
{"horizontal-scrollbar", xlw_create_horizontal_scrollbar},
#endif
+#ifdef LWLIB_TABS_LUCID
+ {"tab-control", xlw_create_tab_control},
+#endif
+#ifdef HAVE_WIDGETS
+ {"clip-window", xlw_create_clip_window},
+#endif
{NULL, NULL}
};
if (the_class == xlwScrollBarWidgetClass)
return True;
#endif
+#ifdef LWLIB_TABS_LUCID
+ if (the_class == tabsWidgetClass)
+ return True;
+#endif
#ifdef LWLIB_MENUBARS_LUCID
if (the_class == overrideShellWidgetClass)
return
xlw_update_one_widget (widget_instance* instance, Widget widget,
widget_value* val, Boolean deep_p)
{
- WidgetClass class;
-
- class = XtClass (widget);
+ WidgetClass class = XtClass (widget);
if (0)
;
xlw_update_scrollbar (instance, widget, val);
}
#endif
+#ifdef LWLIB_TABS_LUCID
+ else if (class == tabsWidgetClass)
+ {
+ xlw_update_tab_control (instance, widget, val);
+ }
+#endif
}
void
#include <Xm/Separator.h>
#include <Xm/DialogS.h>
#include <Xm/Form.h>
+#ifdef LWLIB_WIDGETS_MOTIF
#include <Xm/Scale.h>
#if XmVERSION > 1
-#include <Xm/ComboBox.h>
+#include <Xm/ComboBoxP.h>
+#endif
#endif
#ifdef LWLIB_MENUBARS_MOTIF
XtPointer);
static void xm_pop_down_callback (Widget, XtPointer, XtPointer);
static void xm_generic_callback (Widget, XtPointer, XtPointer);
-#ifdef LWLIB_DIALOGS_MOTIF
+static void mark_dead_instance_destroyed (Widget widget, XtPointer closure,
+ XtPointer call_data);
+#if defined (LWLIB_DIALOGS_MOTIF) || defined (LWLIB_WIDGETS_MOTIF)
static void xm_nosel_callback (Widget, XtPointer, XtPointer);
#endif
#ifdef LWLIB_SCROLLBARS_MOTIF
return result;
}
-#ifdef LWLIB_MENUBARS_MOTIF
-
-static void
-destroy_all_children (Widget widget)
-{
- Widget* children;
- unsigned int number;
- int i;
-
- children = XtCompositeChildren (widget, &number);
- if (children)
- {
- /* Unmanage all children and destroy them. They will only be
- * really destroyed when we get out of DispatchEvent. */
- for (i = 0; i < number; i++)
- {
- Widget child = children [i];
- if (!child->core.being_destroyed)
- {
- XtUnmanageChild (child);
- XtDestroyWidget (child);
- }
- }
- XtFree ((char *) children);
- }
-}
-
-#endif /* LWLIB_MENUBARS_MOTIF */
-
\f
#ifdef LWLIB_DIALOGS_MOTIF
#endif /* LWLIB_DIALOGS_MOTIF */
-#if defined (LWLIB_DIALOGS_MOTIF) || defined (LWLIB_MENUBARS_MOTIF)
+#if defined (LWLIB_DIALOGS_MOTIF) || defined (LWLIB_MENUBARS_MOTIF) || defined (LWLIB_WIDGETS_MOTIF)
/* update the label of anything subclass of a label */
static void
XmString name_string = NULL;
Arg al [20];
int ac = 0;
+ int type;
+
+ /* Don't clobber pixmap types. */
+ XtSetArg (al [0], XmNlabelType, &type);
+ XtGetValues (widget, al, 1);
+
+ if (type == XmPIXMAP)
+ return;
if (val->value)
{
char *res_name = NULL;
res_name = resource_string (widget, val->name);
+ /* Concatenating the value with itself seems just plain daft. */
if (!res_name)
- res_name = val->name;
-
- name_string =
- XmStringCreateLtoR (res_name, XmSTRING_DEFAULT_CHARSET);
-
- value_name = XtMalloc (strlen (val->value) + 2);
- *value_name = 0;
- strcat (value_name, " ");
- strcat (value_name, val->value);
-
- val_string =
- XmStringCreateLtoR (value_name, XmSTRING_DEFAULT_CHARSET);
-
- built_string =
- XmStringConcat (name_string, val_string);
-
- XtFree (value_name);
+ {
+ built_string =
+ XmStringCreateLtoR (val->value, XmSTRING_DEFAULT_CHARSET);
+ }
+ else
+ {
+ name_string =
+ XmStringCreateLtoR (res_name, XmSTRING_DEFAULT_CHARSET);
+
+ value_name = XtMalloc (strlen (val->value) + 2);
+ *value_name = 0;
+ strcat (value_name, " ");
+ strcat (value_name, val->value);
+
+ val_string =
+ XmStringCreateLtoR (value_name, XmSTRING_DEFAULT_CHARSET);
+
+ built_string =
+ XmStringConcat (name_string, val_string);
+
+ XtFree (value_name);
+ }
}
XtSetArg (al [ac], XmNlabelString, built_string); ac++;
if (name_string)
XmStringFree (name_string);
+
+ if (val_string)
+ XmStringFree (val_string);
}
#endif /* defined (LWLIB_DIALOGS_MOTIF) || defined (LWLIB_MENUBARS_MOTIF) */
instance);
XtSetArg (al [0], XmNset, val->selected);
XtSetArg (al [1], XmNalignment, XmALIGNMENT_BEGINNING);
- XtSetValues (widget, al, 2);
+ XtSetValues (widget, al, 1);
}
static void
}
}
+#if defined (LWLIB_WIDGETS_MOTIF) && XmVERSION > 1
+/* update of combo box */
+static void
+xm_update_combo_box (widget_instance* instance, Widget widget, widget_value* val)
+{
+ widget_value* cur;
+ int i;
+ XtRemoveAllCallbacks (widget, XmNselectionCallback);
+ XtAddCallback (widget, XmNselectionCallback, xm_generic_callback,
+ instance);
+ for (cur = val->contents, i = 0; cur; cur = cur->next)
+ if (cur->value)
+ {
+ XmString xmstr = XmStringCreate (cur->value, XmSTRING_DEFAULT_CHARSET);
+ i += 1;
+ XmListAddItem (CB_List (widget), xmstr, 0);
+ if (cur->selected)
+ XmListSelectPos (CB_List (widget), i, False);
+ XmStringFree (xmstr);
+ }
+}
+#endif
+
#ifdef LWLIB_MENUBARS_MOTIF
\f/* update a popup menu, pulldown menu or a menubar */
widget_value* val, Boolean deep_p)
{
WidgetClass class;
- Arg al [2];
+ Arg al [20];
+ int ac = 0;
/* Mark as not edited */
val->edited = False;
/* Common to all widget types */
- XtSetArg (al [0], XmNsensitive, val->enabled);
- XtSetArg (al [1], XmNuserData, val->call_data);
- XtSetValues (widget, al, 2);
+ XtSetArg (al [ac], XmNsensitive, val->enabled); ac++;
+ XtSetArg (al [ac], XmNuserData, val->call_data); ac++;
+ lw_add_value_args_to_args (val, al, &ac);
-#if defined (LWLIB_DIALOGS_MOTIF) || defined (LWLIB_MENUBARS_MOTIF)
+ XtSetValues (widget, al, ac);
+
+#if defined (LWLIB_DIALOGS_MOTIF) || defined (LWLIB_MENUBARS_MOTIF) || defined (LWLIB_WIDGETS_MOTIF)
/* Common to all label like widgets */
if (XtIsSubclass (widget, xmLabelWidgetClass))
xm_update_label (instance, widget, val);
-#endif /* defined (LWLIB_DIALOGS_MOTIF) || defined (LWLIB_MENUBARS_MOTIF) */
-
+#endif
class = XtClass (widget);
/* Class specific things */
if (class == xmPushButtonWidgetClass ||
{
xm_update_list (instance, widget, val);
}
+#if defined (LWLIB_WIDGETS_MOTIF) && XmVERSION > 1
+ else if (class == xmComboBoxWidgetClass)
+ {
+ xm_update_combo_box (instance, widget, val);
+ }
+#endif
#ifdef LWLIB_SCROLLBARS_MOTIF
else if (class == xmScrollBarWidgetClass)
{
val->edited = True;
}
}
- else if (class == xmListWidgetClass)
+ else if (class == xmListWidgetClass
+#if defined (LWLIB_WIDGETS_MOTIF) && XmVERSION > 1
+ || class == xmComboBoxWidgetClass
+#endif
+ )
{
int pos_cnt;
int* pos_list;
- if (XmListGetSelectedPos (widget, &pos_list, &pos_cnt))
+ Widget list = widget;
+#if defined (LWLIB_WIDGETS_MOTIF) && XmVERSION > 1
+ if (class == xmComboBoxWidgetClass)
+ list = CB_List (widget);
+#endif
+ if (XmListGetSelectedPos (list, &pos_list, &pos_cnt))
{
int i;
widget_value* cur;
}
static void
-mark_dead_instance_destroyed (Widget widget, XtPointer closure,
- XtPointer call_data)
-{
- destroyed_instance* instance = (destroyed_instance*)closure;
- instance->widget = NULL;
-}
-
-static void
recenter_widget (Widget widget)
{
Widget parent = XtParent (widget);
#endif /* LWLIB_SCROLLBARS_MOTIF */
+#ifdef LWLIB_WIDGETS_MOTIF
/* glyph widgets */
static Widget
-make_button (widget_instance *instance)
+xm_create_button (widget_instance *instance)
{
Arg al[20];
int ac = 0;
}
static Widget
-make_progress (widget_instance *instance)
+xm_create_progress (widget_instance *instance)
{
Arg al[20];
int ac = 0;
Widget scale = 0;
widget_value* val = instance->info->val;
- XtSetArg (al [ac], XmNsensitive, val->enabled); ac++;
+ if (!val->call_data)
+ {
+ XtSetArg (al [ac], XmNsensitive, False); ac++;
+ }
+ else
+ {
+ XtSetArg (al [ac], XmNsensitive, val->enabled); ac++;
+ }
XtSetArg (al [ac], XmNalignment, XmALIGNMENT_BEGINNING); ac++;
XtSetArg (al [ac], XmNuserData, val->call_data); ac++;
XtSetArg (al [ac], XmNmappedWhenManaged, FALSE); ac++;
look ugly. I think this may be a LessTif bug but for now we just
get rid of it. */
XtSetArg (al [ac], XmNhighlightThickness, (Dimension)0);ac++;
- if (!val->call_data)
- XtSetArg (al [ac], XmNsensitive, False); ac++;
-
/* add any args the user supplied for creation time */
lw_add_value_args_to_args (val, al, &ac);
}
static Widget
-make_text_field (widget_instance *instance)
+xm_create_text_field (widget_instance *instance)
{
Arg al[20];
int ac = 0;
return text;
}
+static Widget
+xm_create_label_field (widget_instance *instance)
+{
+ return xm_create_label (instance->parent, instance->info->val);
+}
+
+Widget
+xm_create_label (Widget parent, widget_value* val)
+{
+ Arg al[20];
+ int ac = 0;
+ Widget label = 0;
+
+ XtSetArg (al [ac], XmNsensitive, val->enabled); ac++;
+ XtSetArg (al [ac], XmNalignment, XmALIGNMENT_BEGINNING); ac++;
+ XtSetArg (al [ac], XmNmappedWhenManaged, FALSE); ac++;
+ /* The highlight doesn't appear to be dynamically set which makes it
+ look ugly. I think this may be a LessTif bug but for now we just
+ get rid of it. */
+ XtSetArg (al [ac], XmNhighlightThickness, (Dimension)0);ac++;
+
+ /* add any args the user supplied for creation time */
+ lw_add_value_args_to_args (val, al, &ac);
+
+ label = XmCreateLabel (parent, val->name, al, ac);
+
+ XtManageChild (label);
+
+ /* Do it again for arguments that have no effect until the widget is realized. */
+ ac = 0;
+ lw_add_value_args_to_args (val, al, &ac);
+ XtSetValues (label, al, ac);
+
+ return label;
+}
+
#if XmVERSION > 1
static Widget
-make_combo_box (widget_instance *instance)
+xm_create_combo_box (widget_instance *instance)
{
Arg al[20];
int ac = 0;
/* add any args the user supplied for creation time */
lw_add_value_args_to_args (val, al, &ac);
- combo = XmCreateComboBox (instance->parent, val->name, al, ac);
+ combo = XmCreateDropDownComboBox (instance->parent, val->name, al, ac);
if (val->call_data)
XtAddCallback (combo, XmNselectionCallback, xm_generic_callback,
(XtPointer)instance);
return combo;
}
#endif
+#endif /* LWLIB_WIDGETS_MOTIF */
\f
/* Table of functions to create widgets */
{"vertical-scrollbar", make_vertical_scrollbar},
{"horizontal-scrollbar", make_horizontal_scrollbar},
#endif
- {"button", make_button},
- {"progress", make_progress},
- {"text-field", make_text_field},
+#ifdef LWLIB_WIDGETS_MOTIF
+ {"button", xm_create_button},
+ {"progress", xm_create_progress},
+ {"text-field", xm_create_text_field},
+ {"label", xm_create_label_field},
#if XmVERSION > 1
- {"combo-box", make_combo_box},
+ {"combo-box", xm_create_combo_box},
+#endif
#endif
{NULL, NULL}
};
void
xm_destroy_instance (widget_instance* instance)
{
-#ifdef LWLIB_DIALOGS_MOTIF
+#if defined (LWLIB_DIALOGS_MOTIF) || defined (LWLIB_WIDGETS_MOTIF)
/* It appears that this is used only for dialog boxes. */
Widget widget = instance->widget;
/* recycle the dialog boxes */
XtDestroyWidget (instance->widget);
}
-#endif /* LWLIB_DIALOGS_MOTIF */
+#endif /* LWLIB_DIALOGS_MOTIF || LWLIB_WIDGETS_MOTIF */
}
\f/* popup utility */
static void
xm_generic_callback (Widget widget, XtPointer closure, XtPointer call_data)
{
-#if (defined (LWLIB_MENUBARS_MOTIF) || defined (LWLIB_DIALOGS_MOTIF))
+#if (defined (LWLIB_MENUBARS_MOTIF) || defined (LWLIB_DIALOGS_MOTIF) || defined (LWLIB_WIDGETS_MOTIF))
/* We want the selected status to change only when we decide it
should change. Yuck but correct. */
if (XtClass (widget) == xmToggleButtonWidgetClass
do_call (widget, closure, post_activate);
}
-#ifdef LWLIB_DIALOGS_MOTIF
-
-static void
-xm_nosel_callback (Widget widget, XtPointer closure, XtPointer call_data)
-{
- /* This callback is only called when a dialog box is dismissed with the wm's
- destroy button (WM_DELETE_WINDOW.) We want the dialog box to be destroyed
- in that case, not just unmapped, so that it releases its keyboard grabs.
- But there are problems with running our callbacks while the widget is in
- the process of being destroyed, so we set XmNdeleteResponse to XmUNMAP
- instead of XmDESTROY and then destroy it ourself after having run the
- callback.
- */
- do_call (widget, closure, no_selection);
- XtDestroyWidget (widget);
-}
-
-#endif
-
#ifdef LWLIB_MENUBARS_MOTIF
static void
}
#endif /* LWLIB_SCROLLBARS_MOTIF */
+#if defined (LWLIB_DIALOGS_MOTIF) || defined (LWLIB_WIDGETS_MOTIF)
+static void
+mark_dead_instance_destroyed (Widget widget, XtPointer closure,
+ XtPointer call_data)
+{
+ destroyed_instance* instance = (destroyed_instance*)closure;
+ instance->widget = NULL;
+}
+
+static void
+xm_nosel_callback (Widget widget, XtPointer closure, XtPointer call_data)
+{
+ /* This callback is only called when a dialog box is dismissed with the wm's
+ destroy button (WM_DELETE_WINDOW.) We want the dialog box to be destroyed
+ in that case, not just unmapped, so that it releases its keyboard grabs.
+ But there are problems with running our callbacks while the widget is in
+ the process of being destroyed, so we set XmNdeleteResponse to XmUNMAP
+ instead of XmDESTROY and then destroy it ourself after having run the
+ callback.
+ */
+ do_call (widget, closure, no_selection);
+ XtDestroyWidget (widget);
+}
+#endif
+
\f
/* set the keyboard focus */
void
Widget
xm_create_dialog (widget_instance* instance);
+Widget
+xm_create_label (Widget parent, widget_value* val);
+
Boolean
lw_motif_widget_p (Widget widget);
int lwlib_does_not_support_dialogs;
# endif
#endif
+
+#ifdef LWLIB_WIDGETS_MOTIF
+int lwlib_widgets_motif;
+#else
+# ifdef LWLIB_WIDGETS_ATHENA
+int lwlib_widgets_athena;
+# else
+int lwlib_does_not_support_widgets;
+# endif
+#endif
#include <X11/ObjectP.h>
#include "lwlib-utils.h"
+void
+destroy_all_children (Widget widget)
+{
+ Widget* children;
+ unsigned int number;
+ int i;
+
+ children = XtCompositeChildren (widget, &number);
+ if (children)
+ {
+ /* Unmanage all children and destroy them. They will only be
+ * really destroyed when we get out of DispatchEvent. */
+ for (i = 0; i < number; i++)
+ {
+ Widget child = children [i];
+ if (!child->core.being_destroyed)
+ {
+ XtUnmanageChild (child);
+ XtDestroyWidget (child);
+ }
+ }
+ XtFree ((char *) children);
+ }
+}
+
/* Redisplay the contents of the widget, without first clearing it. */
void
XtNoClearRefreshWidget (Widget widget)
#ifndef _LWLIB_UTILS_H_
#define _LWLIB_UTILS_H_
+void destroy_all_children (Widget widget);
void XtNoClearRefreshWidget (Widget);
typedef void (*XtApplyToWidgetsProc) (Widget, XtPointer);
widget_value_free_list = wv;
}
-static void free_widget_value_tree (widget_value *wv);
-
static void
free_widget_value_contents (widget_value *wv)
{
free_widget_value_tree (wv->contents);
wv->contents = (widget_value *) 0xDEADBEEF;
}
- if (wv->args && wv->free_args)
+ if (wv->args && wv->nargs)
{
- free (wv->args);
- wv->args = (void *) 0xDEADBEEF;
+ if (wv->free_args)
+ free (wv->args);
+ wv->args = (ArgList) 0xDEADBEEF;
wv->nargs = 0;
+ wv->free_args = 0;
}
if (wv->next)
{
}
}
-static void
+void
free_widget_value_tree (widget_value *wv)
{
if (!wv)
*offset += wv->nargs;
}
}
+
/* do this for the other toolkits too */
#endif /* LWLIB_MENUBARS_LUCID */
+#if defined (LWLIB_TABS_LUCID)
+#include "xlwtabs.h"
+#endif
+
void lw_register_widget (CONST char* type, CONST char* name, LWLIB_ID id,
widget_value* val, lw_callback pre_activate_cb,
lw_callback selection_cb,
widget_value *malloc_widget_value (void);
void free_widget_value (widget_value *);
+void free_widget_value_tree (widget_value *wv);
widget_value *replace_widget_value_tree (widget_value*, widget_value*);
void lw_popup_menu (Widget, XEvent *);
+1999-11-10 XEmacs Build Bot <builds@cvs.xemacs.org>
+
+ * XEmacs 21.2.20 is released
+
+1999-08-30 Robert Pluim <rpluim@bigfoot.com>
+
+ * xemacs/packages.texi (Using Packages): Added description of
+ package-get-package-provider.
+
+1999-07-27 Charles G Waldman <cgw@fnal.gov>
+
+ * xemacs-faq.texi (Q5.0.6): Describe `shell-multiple-shells'
+
+1999-08-01 Adrian Aichner <aichner@ecf.teradyne.com>
+
+ * xemacs/programs.texi (Balanced Editing): Remove broken
+ line-break.
+
+ * xemacs-faq.texi (Q1.0.6): Provide correct location in XEmacs
+ menus.
+ (Q1.4.1): ditto.
+ (Q1.4.3): ditto.
+ (Q2.0.5): Hyphenate words.
+
+ * info.texi (Add): Fix one typo.
+
+1999-08-23 Stephane Epardaud <stephane@lunatech.com>
+
+ * internals/internals.texi (Garbage Collection - Step by Step):
+ just added some dots to shut up compile warnings.
+
+1999-08-19 Matthias Neubauer <neubauer@informatik.uni-tuebingen.de>
+
+ * internals/internals.texi (Garbage Collection - Step by Step):
+ new section in chapter Allocation of Objects in XEmacs Lisp.
+
+1999-07-28 Andy Piper <andy@xemacs.org>
+
+ * internals.texi (Glyphs): add some glyph documentation.
+
1999-07-30 XEmacs Build Bot <builds@cvs.xemacs.org>
* XEmacs 21.2.19 is released
@setfilename ../info/info.info
@settitle Info 1.0
@comment %**end of header
-@comment $Id: info.texi,v 1.4 1997/07/10 21:58:11 karl Exp $
+@comment $Id: info.texi,v 1.4 1998/06/30 06:35:28 steve Exp $
@dircategory Texinfo documentation system
@direntry
Usually, the way to create the nodes is with Texinfo @pxref{Top,, Overview of
Texinfo, texinfo, Texinfo: The GNU Documentation Format}); this has the
advantage that you can also make a printed manual from them. However,
-if hyou want to edit an Info file, here is how.
+if you want to edit an Info file, here is how.
The new node can live in an existing documentation file, or in a new
one. It must have a @key{^_} character before it (invisible to the
@titlepage
@title XEmacs Internals Manual
-@subtitle Version 1.2, October 1998
+@subtitle Version 1.3, August 1999
@author Ben Wing
@author Martin Buchholz
@author Hrvoje Niksic
+@author Matthias Neubauer
@page
@vskip 0pt plus 1fill
Copyright @copyright{} 1994, 1995 Board of Trustees, University of Illinois.
@sp 2
-Version 1.2 @*
-October 1998.@*
+Version 1.3 @*
+August 1999.@*
Permission is granted to make and distribute verbatim copies of this
manual provided the copyright notice and this permission notice are
* Consoles; Devices; Frames; Windows::
* The Redisplay Mechanism::
* Extents::
-* Faces and Glyphs::
+* Faces::
+* Glyphs::
* Specifiers::
* Menus::
* Subprocesses::
* Introduction to Allocation::
* Garbage Collection::
* GCPROing::
+* Garbage Collection - Step by Step::
* Integers and Characters::
* Allocation from Frob Blocks::
* lrecords::
* Mathematics of Extent Ordering:: A rigorous foundation.
* Extent Fragments:: Cached information useful for redisplay.
-Faces and Glyphs
+Faces
+
+Glyphs
Specifiers
* Introduction to Allocation::
* Garbage Collection::
* GCPROing::
+* Garbage Collection - Step by Step::
* Integers and Characters::
* Allocation from Frob Blocks::
* lrecords::
it obviates the need for @code{GCPRO}ing, and allows garbage collection
to happen at any point at all, such as during object allocation.
+@node Garbage Collection - Step by Step
+@section Garbage Collection - Step by Step
+@cindex garbage collection step by step
+
+@menu
+* Invocation::
+* garbage_collect_1::
+* mark_object::
+* gc_sweep::
+* sweep_lcrecords_1::
+* compact_string_chars::
+* sweep_strings::
+* sweep_bit_vectors_1::
+@end menu
+
+@node Invocation
+@subsection Invocation
+@cindex garbage collection, invocation
+
+The first thing that anyone should know about garbage collection is:
+when and how the garbage collector is invoked. One might think that this
+could happen every time new memory is allocated, e.g. new objects are
+created, but this is @emph{not} the case. Instead, we have the following
+situation:
+
+The entry point of any process of garbage collection is an invocation
+of the function @code{garbage_collect_1} in file @code{alloc.c}. The
+invocation can occur @emph{explicitly} by calling the function
+@code{Fgarbage_collect} (in addition this function provides information
+about the freed memory), or can occur @emph{implicitly} in four different
+situations:
+@enumerate
+@item
+In function @code{main_1} in file @code{emacs.c}. This function is called
+at each startup of xemacs. The garbage collection is invoked after all
+initial creations are completed, but only if a special internal error
+checking-constant @code{ERROR_CHECK_GC} is defined.
+@item
+In function @code{disksave_object_finalization} in file
+@code{alloc.c}. The only purpose of this function is to clear the
+objects from memory which need not be stored with xemacs when we dump out
+an executable. This is only done by @code{Fdump_emacs} or by
+@code{Fdump_emacs_data} respectively (both in @code{emacs.c}). The
+actual clearing is accomplished by making these objects unreachable and
+starting a garbage collection. The function is only used while building
+xemacs.
+@item
+In function @code{Feval / eval} in file @code{eval.c}. Each time the
+well known and often used function eval is called to evaluate a form,
+one of the first things that could happen, is a potential call of
+@code{garbage_collect_1}. There exist three global variables,
+@code{consing_since_gc} (counts the created cons-cells since the last
+garbage collection), @code{gc_cons_threshold} (a specified threshold
+after which a garbage collection occurs) and @code{always_gc}. If
+@code{always_gc} is set or if the threshold is exceeded, the garbage
+collection will start.
+@item
+In function @code{Ffuncall / funcall} in file @code{eval.c}. This
+function evaluates calls of elisp functions and works according to
+@code{Feval}.
+@end enumerate
+
+The upshot is that garbage collection can basically occur everywhere
+@code{Feval}, respectively @code{Ffuncall}, is used - either directly or
+through another function. Since calls to these two functions are
+hidden in various other functions, many calls to
+@code{garabge_collect_1} are not obviously foreseeable, and therefore
+unexpected. Instances where they are used that are worth remembering are
+various elisp commands, as for example @code{or},
+@code{and}, @code{if}, @code{cond}, @code{while}, @code{setq}, etc.,
+miscellaneous @code{gui_item_...} functions, everything related to
+@code{eval} (@code{Feval_buffer}, @code{call0}, ...) and inside
+@code{Fsignal}. The latter is used to handle signals, as for example the
+ones raised by every @code{QUITE}-macro triggered after pressing Ctrl-g.
+
+@node garbage_collect_1
+@subsection @code{garbage_collect_1}
+@cindex @code{garbage_collect_1}
+
+We can now describe exactly what happens after the invocation takes
+place.
+@enumerate
+@item
+There are several cases in which the garbage collector is left immediately:
+when we are already garbage collecting (@code{gc_in_progress}), when
+the garbage collection is somehow forbidden
+(@code{gc_currently_forbidden}), when we are currently displaying something
+(@code{in_display}) or when we are preparing for the armageddon of the
+whole system (@code{preparing_for_armageddon}).
+@item
+Next the correct frame in which to put
+all the output occurring during garbage collecting is determined. In
+order to be able to restore the old display's state after displaying the
+message, some data about the current cursor position has to be
+saved. The variables @code{pre_gc_curser} and @code{cursor_changed} take
+care of that.
+@item
+The state of @code{gc_currently_forbidden} must be restored after
+the garbage collection, no matter what happens during the process. We
+accomplish this by @code{record_unwind_protect}ing the suitable function
+@code{restore_gc_inhibit} together with the current value of
+@code{gc_currently_forbidden}.
+@item
+If we are concurrently running an interactive xemacs session, the next step
+is simply to show the garbage collector's cursor/message.
+@item
+The following steps are the intrinsic steps of the garbage collector,
+therefore @code{gc_in_progress} is set.
+@item
+For debugging purposes, it is possible to copy the current C stack
+frame. However, this seems to be a currently unused feature.
+@item
+Before actually starting to go over all live objects, references to
+objects that are no longer used are pruned. We only have to do this for events
+(@code{clear_event_resource}) and for specifiers
+(@code{cleanup_specifiers}).
+@item
+Now the mark phase begins and marks all accessible elements. In order to
+start from
+all slots that serve as roots of accessibility, the function
+@code{mark_object} is called for each root individually to go out from
+there to mark all reachable objects. All roots that are traversed are
+shown in their processed order:
+@itemize @bullet
+@item
+all constant symbols and static variables that are registered via
+@code{staticpro}@ in the array @code{staticvec}.
+@xref{Adding Global Lisp Variables}.
+@item
+all Lisp objects that are created in C functions and that must be
+protected from freeing them. They are registered in the global
+list @code{gcprolist}.
+@xref{GCPROing}.
+@item
+all local variables (i.e. their name fields @code{symbol} and old
+values @code{old_values}) that are bound during the evaluation by the Lisp
+engine. They are stored in @code{specbinding} structs pushed on a stack
+called @code{specpdl}.
+@xref{Dynamic Binding; The specbinding Stack; Unwind-Protects}.
+@item
+all catch blocks that the Lisp engine encounters during the evaluation
+cause the creation of structs @code{catchtag} inserted in the list
+@code{catchlist}. Their tag (@code{tag}) and value (@code{val} fields
+are freshly created objects and therefore have to be marked.
+@xref{Catch and Throw}.
+@item
+every function application pushes new structs @code{backtrace}
+on the call stack of the Lisp engine (@code{backtrace_list}). The unique
+parts that have to be marked are the fields for each function
+(@code{function}) and all their arguments (@code{args}).
+@xref{Evaluation}.
+@item
+all objects that are used by the redisplay engine that must not be freed
+are marked by a special function called @code{mark_redisplay} (in
+@code{redisplay.c}).
+@item
+all objects created for profiling purposes are allocated by C functions
+instead of using the lisp allocation mechanisms. In order to receive the
+right ones during the sweep phase, they also have to be marked
+manually. That is done by the function @code{mark_profiling_info}
+@end itemize
+@item
+Hash tables in Xemacs belong to a kind of special objects that
+make use of a concept often called 'weak pointers'.
+To make a long story short, these kind of pointers are not followed
+during the estimation of the live objects during garbage collection.
+Any object referenced only by weak pointers is collected
+anyway, and the reference to it is cleared. In hash tables there are
+different usage patterns of them, manifesting in different types of hash
+tables, namely 'non-weak', 'weak', 'key-weak' and 'value-weak'
+(internally also 'key-car-weak' and 'value-car-weak') hash tables, each
+clearing entries depending on different conditions. More information can
+be found in the documentation to the function @code{make-hash-table}.
+
+Because there are complicated dependency rules about when and what to
+mark while processing weak hash tables, the standard @code{marker}
+method is only active if it is marking non-weak hash tables. As soon as
+a weak component is in the table, the hash table entries are ignored
+while marking. Instead their marking is done each separately by the
+function @code{finish_marking_weak_hash_tables}. This function iterates
+over each hash table entry @code{hentries} for each weak hash table in
+@code{Vall_weak_hash_tables}. Depending on the type of a table, the
+appropriate action is performed.
+If a table is acting as @code{HASH_TABLE_KEY_WEAK}, and a key already marked,
+everything reachable from the @code{value} component is marked. If it is
+acting as a @code{HASH_TABLE_VALUE_WEAK} and the value component is
+already marked, the marking starts beginning only from the
+@code{key} component.
+If it is a @code{HASH_TABLE_KEY_CAR_WEAK} and the car
+of the key entry is already marked, we mark both the @code{key} and
+@code{value} components.
+Finally, if the table is of the type @code{HASH_TABLE_VALUE_CAR_WEAK}
+and the car of the value components is already marked, again both the
+@code{key} and the @code{value} components get marked.
+
+Again, there are lists with comparable properties called weak
+lists. There exist different peculiarities of their types called
+@code{simple}, @code{assoc}, @code{key-assoc} and
+@code{value-assoc}. You can find further details about them in the
+description to the function @code{make-weak-list}. The scheme of their
+marking is similar: all weak lists are listed in @code{Qall_weak_lists},
+therefore we iterate over them. The marking is advanced until we hit an
+already marked pair. Then we know that during a former run all
+the rest has been marked completely. Again, depending on the special
+type of the weak list, our jobs differ. If it is a @code{WEAK_LIST_SIMPLE}
+and the elem is marked, we mark the @code{cons} part. If it is a
+@code{WEAK_LIST_ASSOC} and not a pair or a pair with both marked car and
+cdr, we mark the @code{cons} and the @code{elem}. If it is a
+@code{WEAK_LIST_KEY_ASSOC} and not a pair or a pair with a marked car of
+the elem, we mark the @code{cons} and the @code{elem}. Finally, if it is
+a @code{WEAK_LIST_VALUE_ASSOC} and not a pair or a pair with a marked
+cdr of the elem, we mark both the @code{cons} and the @code{elem}.
+
+Since, by marking objects in reach from weak hash tables and weak lists,
+other objects could get marked, this perhaps implies further marking of
+other weak objects, both finishing functions are redone as long as
+yet unmarked objects get freshly marked.
+
+@item
+After completing the special marking for the weak hash tables and for the weak
+lists, all entries that point to objects that are going to be swept in
+the further process are useless, and therefore have to be removed from
+the table or the list.
+
+The function @code{prune_weak_hash_tables} does the job for weak hash
+tables. Totally unmarked hash tables are removed from the list
+@code{Vall_weak_hash_tables}. The other ones are treated more carefully
+by scanning over all entries and removing one as soon as one of
+the components @code{key} and @code{value} is unmarked.
+
+The same idea applies to the weak lists. It is accomplished by
+@code{prune_weak_lists}: An unmarked list is pruned from
+@code{Vall_weak_lists} immediately. A marked list is treated more
+carefully by going over it and removing just the unmarked pairs.
+
+@item
+The function @code{prune_specifiers} checks all listed specifiers held
+in @code{Vall_speficiers} and removes the ones from the lists that are
+unmarked.
+
+@item
+All syntax tables are stored in a list called
+@code{Vall_syntax_tables}. The function @code{prune_syntax_tables} walks
+through it and unlinks the tables that are unmarked.
+
+@item
+Next, we will attack the complete sweeping - the function
+@code{gc_sweep} which holds the predominance.
+@item
+First, all the variables with respect to garbage collection are
+reset. @code{consing_since_gc} - the counter of the created cells since
+the last garbage collection - is set back to 0, and
+@code{gc_in_progress} is not @code{true} anymore.
+@item
+In case the session is interactive, the displayed cursor and message are
+removed again.
+@item
+The state of @code{gc_inhibit} is restored to the former value by
+unwinding the stack.
+@item
+A small memory reserve is always held back that can be reached by
+@code{breathing_space}. If nothing more is left, we create a new reserve
+and exit.
+@end enumerate
+
+@node mark_object
+@subsection @code{mark_object}
+@cindex @code{mark_object}
+
+The first thing that is checked while marking an object is whether the
+object is a real Lisp object @code{Lisp_Type_Record} or just an integer
+or a character. Integers and characters are the only two types that are
+stored directly - without another level of indirection, and therefore they
+don´t have to be marked and collected.
+@xref{How Lisp Objects Are Represented in C}.
+
+The second case is the one we have to handle. It is the one when we are
+dealing with a pointer to a Lisp object. But, there exist also three
+possibilities, that prevent us from doing anything while marking: The
+object is read only which prevents it from being garbage collected,
+i.e. marked (@code{C_READONLY_RECORD_HEADER}). The object in question is
+already marked, and need not be marked for the second time (checked by
+@code{MARKED_RECORD_HEADER_P}). If it is a special, unmarkable object
+(@code{UNMARKABLE_RECORD_HEADER_P}, apparently, these are objects that
+sit in some CONST space, and can therefore not be marked, see
+@code{this_one_is_unmarkable} in @code{alloc.c}).
+
+Now, the actual marking is feasible. We do so by once using the macro
+@code{MARK_RECORD_HEADER} to mark the object itself (actually the
+special flag in the lrecord header), and calling its special marker
+"method" @code{marker} if available. The marker method marks every
+other object that is in reach from our current object. Note, that these
+marker methods should not call @code{mark_object} recursively, but
+instead should return the next object from where further marking has to
+be performed.
+
+In case another object was returned, as mentioned before, we reiterate
+the whole @code{mark_object} process beginning with this next object.
+
+@node gc_sweep
+@subsection @code{gc_sweep}
+@cindex @code{gc_sweep}
+
+The job of this function is to free all unmarked records from memory. As
+we know, there are different types of objects implemented and managed, and
+consequently different ways to free them from memory.
+@xref{Introduction to Allocation}.
+
+We start with all objects stored through @code{lcrecords}. All
+bulkier objects are allocated and handled using that scheme of
+@code{lcrecords}. Each object is @code{malloc}ed separately
+instead of placing it in one of the contiguous frob blocks. All types
+that are currently stored
+using @code{lcrecords}´s @code{alloc_lcrecord} and
+@code{make_lcrecord_list} are the types: vectors, buffers,
+char-table, char-table-entry, console, weak-list, database, device,
+ldap, hash-table, command-builder, extent-auxiliary, extent-info, face,
+coding-system, frame, image-instance, glyph, popup-data, gui-item,
+keymap, charset, color_instance, font_instance, opaque, opaque-list,
+process, range-table, specifier, symbol-value-buffer-local,
+symbol-value-lisp-magic, symbol-value-varalias, toolbar-button,
+tooltalk-message, tooltalk-pattern, window, and window-configuration. We
+take care of them in the fist place
+in order to be able to handle and to finalize items stored in them more
+easily. The function @code{sweep_lcrecords_1} as described below is
+doing the whole job for us.
+For a description about the internals: @xref{lrecords}.
+
+Our next candidates are the other objects that behave quite differently
+than everything else: the strings. They consists of two parts, a
+fixed-size portion (@code{struct Lisp_string}) holding the string's
+length, its property list and a pointer to the second part, and the
+actual string data, which is stored in string-chars blocks comparable to
+frob blocks. In this block, the data is not only freed, but also a
+compression of holes is made, i.e. all strings are relocated together.
+@xref{String}. This compacting phase is performed by the function
+@code{compact_string_chars}, the actual sweeping by the function
+@code{sweep_strings} is described below.
+
+After that, the other types are swept step by step using functions
+@code{sweep_conses}, @code{sweep_bit_vectors_1},
+@code{sweep_compiled_functions}, @code{sweep_floats},
+@code{sweep_symbols}, @code{sweep_extents}, @code{sweep_markers} and
+@code{sweep_extents}. They are the fixed-size types cons, floats,
+compiled-functions, symbol, marker, extent, and event stored in
+so-called "frob blocks", and therefore we can basically do the same on
+every type objects, using the same macros, especially defined only to
+handle everything with respect to fixed-size blocks. The only fixed-size
+type that is not handled here are the fixed-size portion of strings,
+because we took special care of them earlier.
+
+The only big exceptions are bit vectors stored differently and
+therefore treated differently by the function @code{sweep_bit_vectors_1}
+described later.
+
+At first, we need some brief information about how
+these fixed-size types are managed in general, in order to understand
+how the sweeping is done. They have all a fixed size, and are therefore
+stored in big blocks of memory - allocated at once - that can hold a
+certain amount of objects of one type. The macro
+@code{DECLARE_FIXED_TYPE_ALLOC} creates the suitable structures for
+every type. More precisely, we have the block struct
+(holding a pointer to the previous block @code{prev} and the
+objects in @code{block[]}), a pointer to current block
+(@code{current_..._block)}) and its last index
+(@code{current_..._block_index}), and a pointer to the free list that
+will be created. Also a macro @code{FIXED_TYPE_FROM_BLOCK} plus some
+related macros exists that are used to obtain a new object, either from
+the free list @code{ALLOCATE_FIXED_TYPE_1} if there is an unused object
+of that type stored or by allocating a completely new block using
+@code{ALLOCATE_FIXED_TYPE_FROM_BLOCK}.
+
+The rest works as follows: all of them define a
+macro @code{UNMARK_...} that is used to unmark the object. They define a
+macro @code{ADDITIONAL_FREE_...} that defines additional work that has
+to be done when converting an object from in use to not in use (so far,
+only markers use it in order to unchain them). Then, they all call
+the macro @code{SWEEP_FIXED_TYPE_BLOCK} instantiated with their type name
+and their struct name.
+
+This call in particular does the following: we go over all blocks
+starting with the current moving towards the oldest.
+For each block, we look at every object in it. If the object already
+freed (checked with @code{FREE_STRUCT_P} using the first pointer of the
+object), or if it is
+set to read only (@code{C_READONLY_RECORD_HEADER_P}, nothing must be
+done. If it is unmarked (checked with @code{MARKED_RECORD_HEADER_P}), it
+is put in the free list and set free (using the macro
+@code{FREE_FIXED_TYPE}, otherwise it stays in the block, but is unmarked
+(by @code{UNMARK_...}). While going through one block, we note if the
+whole block is empty. If so, the whole block is freed (using
+@code{xfree}) and the free list state is set to the state it had before
+handling this block.
+
+@node sweep_lcrecords_1
+@subsection @code{sweep_lcrecords_1}
+@cindex @code{sweep_lcrecords_1}
+
+After nullifying the complete lcrecord statistics, we go over all
+lcrecords two separate times. They are all chained together in a list with
+a head called @code{all_lcrecords}.
+
+The first loop calls for each object its @code{finalizer} method, but only
+in the case that it is not read only
+(@code{C_READONLY_RECORD_HEADER_P)}, it is not already marked
+(@code{MARKED_RECORD_HEADER_P}), it is not already in a free list (list of
+freed objects, field @code{free}) and finally it owns a finalizer
+method.
+
+The second loop actually frees the appropriate objects again by iterating
+through the whole list. In case an object is read only or marked, it
+has to persist, otherwise it is manually freed by calling
+@code{xfree}. During this loop, the lcrecord statistics are kept up to
+date by calling @code{tick_lcrecord_stats} with the right arguments,
+
+@node compact_string_chars
+@subsection @code{compact_string_chars}
+@cindex @code{compact_string_chars}
+
+The purpose of this function is to compact all the data parts of the
+strings that are held in so-called @code{string_chars_block}, i.e. the
+strings that do not exceed a certain maximal length.
+
+The procedure with which this is done is as follows. We are keeping two
+positions in the @code{string_chars_block}s using two pointer/integer
+pairs, namely @code{from_sb}/@code{from_pos} and
+@code{to_sb}/@code{to_pos}. They stand for the actual positions, from
+where to where, to copy the actually handled string.
+
+While going over all chained @code{string_char_block}s and their held
+strings, staring at @code{first_string_chars_block}, both pointers
+are advanced and eventually a string is copied from @code{from_sb} to
+@code{to_sb}, depending on the status of the pointed at strings.
+
+More precisely, we can distinguish between the following actions.
+@itemize @bullet
+@item
+The string at @code{from_sb}'s position could be marked as free, which
+is indicated by an invalid pointer to the pointer that should point back
+to the fixed size string object, and which is checked by
+@code{FREE_STRUCT_P}. In this case, the @code{from_sb}/@code{from_pos}
+is advanced to the next string, and nothing has to be copied.
+@item
+Also, if a string object itself is unmarked, nothing has to be
+copied. We likewise advance the @code{from_sb}/@code{from_pos}
+pair as described above.
+@item
+In all other cases, we have a marked string at hand. The string data
+must be moved from the from-position to the to-position. In case
+there is not enough space in the actual @code{to_sb}-block, we advance
+this pointer to the beginning of the next block before copying. In case the
+from and to positions are different, we perform the
+actual copying using the library function @code{memmove}.
+@end itemize
+
+After compacting, the pointer to the current
+@code{string_chars_block}, sitting in @code{current_string_chars_block},
+is reset on the last block to which we moved a string,
+i.e. @code{to_block}, and all remaining blocks (we know that they just
+carry garbage) are explicitly @code{xfree}d.
+
+@node sweep_strings
+@subsection @code{sweep_strings}
+@cindex @code{sweep_strings}
+
+The sweeping for the fixed sized string objects is essentially exactly
+the same as it is for all other fixed size types. As before, the freeing
+into the suitable free list is done by using the macro
+@code{SWEEP_FIXED_SIZE_BLOCK} after defining the right macros
+@code{UNMARK_string} and @code{ADDITIONAL_FREE_string}. These two
+definitions are a little bit special compared to the ones used
+for the other fixed size types.
+
+@code{UNMARK_string} is defined the same way except some additional code
+used for updating the bookkeeping information.
+
+For strings, @code{ADDITIONAL_FREE_string} has to do something in
+addition: in case, the string was not allocated in a
+@code{string_chars_block} because it exceeded the maximal length, and
+therefore it was @code{malloc}ed separately, we know also @code{xfree}
+it explicitly.
+
+@node sweep_bit_vectors_1
+@subsection @code{sweep_bit_vectors_1}
+@cindex @code{sweep_bit_vectors_1}
+
+Bit vectors are also one of the rare types that are @code{malloc}ed
+individually. Consequently, while sweeping, all further needless
+bit vectors must be freed by hand. This is done, as one might imagine,
+the expected way: since they are all registered in a list called
+@code{all_bit_vectors}, all elements of that list are traversed,
+all unmarked bit vectors are unlinked by calling @code{xfree} and all of
+them become unmarked.
+In addition, the bookkeeping information used for garbage
+collector's output purposes is updated.
+
@node Integers and Characters
@section Integers and Characters
@menu
* Critical Redisplay Sections::
* Line Start Cache::
+* Redisplay Piece by Piece::
@end menu
@node Critical Redisplay Sections
In case you're wondering, the Second Golden Rule of Redisplay is not
applicable.
-@node Extents, Faces and Glyphs, The Redisplay Mechanism, Top
+@node Redisplay Piece by Piece
+@section Redisplay Piece by Piece
+@cindex Redisplay Piece by Piece
+
+As you can begin to see redisplay is complex and also not well
+documented. Chuck no longer works on XEmacs so this section is my take
+on the workings of redisplay.
+
+Redisplay happens in three phases:
+
+@enumerate
+@item
+Determine desired display in area that needs redisplay.
+Implemented by @code{redisplay.c}
+@item
+Compare desired display with current display
+Implemented by @code{redisplay-output.c}
+@item
+Output changes Implemented by @code{redisplay-output.c},
+@code{redisplay-x.c}, @code{redisplay-msw.c} and @code{redisplay-tty.c}
+@end enumerate
+
+Steps 1 and 2 are device-independant and relatively complex. Step 3 is
+mostly device-dependent.
+
+Determining the desired display
+
+Display attributes are stored in @code{display_line} structures. Each
+@code{display_line} consists of a set of @code{display_block}'s and each
+@code{display_block} contains a number of @code{rune}'s. Generally
+dynarr's of @code{display_line}'s are held by each window representing
+the current display and the desired display.
+
+The @code{display_line} structures are tighly tied to buffers which
+presents a problem for redisplay as this connection is bogus for the
+modeline. Hence the @code{display_line} generation routines are
+duplicated for generating the modeline. This means that the modeline
+display code has many bugs that the standard redisplay code does not.
+
+The guts of @code{display_line} generation are in
+@code{create_text_block}, which creates a single display line for the
+desired locale. This incrementally parses the characters on the current
+line and generates redisplay structures for each.
+
+Gutter redisplay is different. Because the data to display is stored in
+a string we cannot use @code{create_text_block}. Instead we use
+@code{create_text_string_block} which performs the same function as
+@code{create_text_block} but for strings. Many of the complexities of
+@code{create_text_block} to do with cursor handling and selective
+display have been removed.
+
+@node Extents, Faces, The Redisplay Mechanism, Top
@chapter Extents
@menu
stack-of-extents code, which does the heavy-duty algorithmic work of
determining which extents overly a particular position.
-@node Faces and Glyphs, Specifiers, Extents, Top
-@chapter Faces and Glyphs
+@node Faces, Glyphs, Extents, Top
+@chapter Faces
Not yet documented.
-@node Specifiers, Menus, Faces and Glyphs, Top
+@node Glyphs, Specifiers, Faces, Top
+@chapter Glyphs
+
+Glyphs are graphical elements that can be displayed in XEmacs buffers or
+gutters. We use the term graphical element here in the broadest possible
+sense since glyphs can be as mundane as text to as arcane as a native
+tab widget.
+
+In XEmacs, glyphs represent the uninstantiated state of graphical
+elements, i.e. they hold all the information necessary to produce an
+image on-screen but the image does not exist at this stage.
+
+Glyphs are lazily instantiated by calling one of the glyph
+functions. This usually occurs within redisplay when
+@code{Fglyph_height} is called. Instantiation causes an image-instance
+to be created and cached. This cache is on a device basis for all glyphs
+except glyph-widgets, and on a window basis for glyph widgets. The
+caching is done by @code{image_instantiate} and is necessary because it
+is generally possible to display an image-instance in multiple
+domains. For instance if we create a Pixmap, we can actually display
+this on multiple windows - even though we only need a single Pixmap
+instance to do this. If caching wasn't done then it would be necessary
+to create image-instances for every displayable occurrance of a glyph -
+and every usage - and this would be extremely memory and cpu intensive.
+
+Widget-glyphs (a.k.a native widgets) are not cached in this way. This is
+because widget-glyph image-instances on screen are toolkit windows, and
+thus cannot be reused in multiple XEmacs domains. Thus widget-glyphs are
+cached on a window basis.
+
+Any action on a glyph first consults the cache before actually
+instantiating a widget.
+
+@section Widget-Glyphs in the MS-WIndows Environment
+
+To Do
+
+@section Widget-Glyphs in the X Environment
+
+Widget-glyphs under X make heavy use of lwlib for manipulating the
+native toolkit objects. This is primarily so that different toolkits can
+be supported for widget-glyphs, just as they are supported for features
+such as menubars etc.
+
+Lwlib is extremely poorly documented and quite hairy so here is my
+understanding of what goes on.
+
+Lwlib maintains a set of widget_instances which mirror the hierarchical
+state of Xt widgets. I think this is so that widgets can be updated and
+manipulated generically by the lwlib library. For instance
+update_one_widget_instance can cope with multiple types of widget and
+multiple types of toolkit. Each element in the widget hierarchy is updated
+from its corresponding widget_instance by walking the widget_instance
+tree recursively.
+
+This has desirable properties such as lw_modify_all_widgets which is
+called from glyphs-x.c and updates all the properties of a widget
+without having to know what the widget is or what toolkit it is from.
+Unfortunately this also has hairy properrties such as making the lwlib
+code quite complex. And of course lwlib has to know at some level what
+the widget is and how to set its properties.
+
+@node Specifiers, Menus, Glyphs, Top
@chapter Specifiers
Not yet documented.
(without the @code{:} character), as well as the additional keyword
@code{data}, which specifies the initial hash table contents.
-@defun make-hash-table &key @code{:size} @code{:test} @code{:type} @code{:rehash-size} @code{:rehash-threshold}
+@defun make-hash-table &key @code{test} @code{size} @code{rehash-size} @code{rehash-threshold} @code{weakness}
This function returns a new empty hash table object.
-Keyword @code{:size} specifies the number of keys likely to be inserted.
-This number of entries can be inserted without enlarging the hash table.
-
Keyword @code{:test} can be @code{eq}, @code{eql} (default) or @code{equal}.
Comparison between keys is done using this function.
If speed is important, consider using @code{eq}.
When storing strings in the hash table, you will likely need to use @code{equal}.
-Keyword @code{:type} can be @code{non-weak} (default), @code{weak},
-@code{key-weak} or @code{value-weak}.
+Keyword @code{:size} specifies the number of keys likely to be inserted.
+This number of entries can be inserted without enlarging the hash table.
+
+Keyword @code{:rehash-size} must be a float greater than 1.0, and specifies
+the factor by which to increase the size of the hash table when enlarging.
+
+Keyword @code{:rehash-threshold} must be a float between 0.0 and 1.0,
+and specifies the load factor of the hash table which triggers enlarging.
+
+Keyword @code{:weakness} can be @code{nil} (default), @code{t},
+@code{key} or @code{value}.
A weak hash table is one whose pointers do not count as GC referents:
for any key-value pair in the hash table, if the only remaining pointer
unmarked outside of weak hash tables. The pair will remain in the
hash table if the value is pointed to by something other than a weak
hash table, even if the key is not.
-
-Keyword @code{:rehash-size} must be a float greater than 1.0, and specifies
-the factor by which to increase the size of the hash table when enlarging.
-
-Keyword @code{:rehash-threshold} must be a float between 0.0 and 1.0,
-and specifies the load factor of the hash table which triggers enlarging.
@end defun
@defun copy-hash-table hash-table
This function returns the number of entries in @var{hash-table}.
@end defun
-@defun hash-table-size hash-table
-This function returns the current number of slots in @var{hash-table},
-whether occupied or not.
-@end defun
-
-@defun hash-table-type hash-table
-This function returns the type of @var{hash-table}.
-This can be one of @code{non-weak}, @code{weak}, @code{key-weak} or
-@code{value-weak}.
-@end defun
-
@defun hash-table-test hash-table
This function returns the test function of @var{hash-table}.
This can be one of @code{eq}, @code{eql} or @code{equal}.
@end defun
+@defun hash-table-size hash-table
+This function returns the current number of slots in @var{hash-table},
+whether occupied or not.
+@end defun
+
@defun hash-table-rehash-size hash-table
This function returns the current rehash size of @var{hash-table}.
This is a float greater than 1.0; the factor by which @var{hash-table}
@var{hash-table}, beyond which the @var{hash-table} is enlarged by rehashing.
@end defun
+@defun hash-table-weakness hash-table
+This function returns the weakness of @var{hash-table}.
+This can be one of @code{nil}, @code{t}, @code{key} or @code{value}.
+@end defun
+
@node Working With Hash Tables
@section Working With Hash Tables
processed by @var{function}.
@end defun
+
@node Weak Hash Tables
@section Weak Hash Tables
@cindex hash table, weak
Also see @ref{Weak Lists}.
-Weak hash tables are created by specifying the @code{:type} keyword to
+Weak hash tables are created by specifying the @code{:weakness} keyword to
@code{make-hash-table}.
@finalout
@titlepage
@title XEmacs FAQ
-@subtitle Frequently asked questions about XEmacs @* Last Modified: $Date: 1999/03/04 15:48:25 $
+@subtitle Frequently asked questions about XEmacs @* Last Modified: $Date: 1999/09/26 19:46:47 $
@sp 1
@author Tony Rossini <arossini@@stat.sc.edu>
@author Ben Wing <wing@@666.com>
@unnumberedsubsec Q1.0.6: Where can I get help?
Probably the easiest way, if everything is installed, is to use info, by
-pressing @kbd{C-h i}, or selecting @code{Emacs Info} from the Help Menu.
+pressing @kbd{C-h i}, or selecting @code{Manuals->Info} from the Help Menu.
Also, @kbd{M-x apropos} will look for commands for you.
home directory and rename it @file{.emacs}. Then edit it to suit.
Starting with 19.14, you may bring the @file{sample.emacs} into an
-XEmacs buffer by selecting @samp{Help->Sample .emacs} from the menubar.
-To determine the location of the @file{etc} directory type the command
-@kbd{C-h v data-directory @key{RET}}.
+XEmacs buffer by selecting @samp{Help->Samples->Sample .emacs} from the
+menubar. To determine the location of the @file{etc} directory type the
+command @kbd{C-h v data-directory @key{RET}}.
@node Q1.4.2, Q1.4.3, Q1.4.1, Introduction
@unnumberedsubsec Q1.4.2: Can I use the same @file{.emacs} with the other Emacs?
@node Q1.4.3, Q1.4.4, Q1.4.2, Introduction
@unnumberedsubsec Q1.4.3: Any good tutorials around?
-There's the XEmacs tutorial available from the Help Menu, or by typing
-@kbd{C-h t}. To check whether it's available in a non-english language,
-type @kbd{C-u C-h t TAB}, type the first letters of your preferred
-language, then type @key{RET}.
+There's the XEmacs tutorial available from the Help Menu under
+@samp{Basics->Tutorials}, or by typing @kbd{C-h t}. To check whether
+it's available in a non-english language, type @kbd{C-u C-h t TAB}, type
+the first letters of your preferred language, then type @key{RET}.
There's an Emacs Lisp tutorial at
No. The name @dfn{XEmacs} is unfortunate in the sense that it is
@strong{not} an X Window System-only version of Emacs. Starting with
-19.14 XEmacs has full color support on a color capable character
+19.14 XEmacs has full color support on a color-capable character
terminal.
@node Q2.0.6, Q2.0.7, Q2.0.5, Installation
rename-uniquely} to rename the @code{*shell*} buffer instead of @kbd{M-x
rename-buffer}.
+Alternately, you can set the variable @code{shell-multiple-shells}.
+If the value of this variable is non-nil, each time shell mode is invoked,
+a new shell is made
+
@node Q5.0.7, Q5.0.8, Q5.0.6, Miscellaneous
@unnumberedsubsec Q5.0.7: Telnet from shell filters too much
@item -vanilla
This is equivalent to @samp{-q -no-site-file -no-early-packages}.
+@item -user-init-file @var{file}
+Load @var{file} as your Emacs init file instead of @file{~/.emacs}.
+
+@item -user-init-directory @var{directory}
+Use @var{directory} as the location of your early package hierarchies
+and the various user-specific initialization files.
+
@item -user @var{user}
@itemx -u @var{user}
-Load @var{user}'s Emacs init file @file{~@var{user}/.emacs} instead of
-your own.
+Equivalent to
+@samp{-user-init-file ~@var{user}/.emacs -user-init-directory ~@var{user}/.xemacs}.
@end table
When you start Emacs, it normally loads the file @file{.emacs} in your
home directory. This file, if it exists, should contain Lisp code. It
is called your initialization file or @dfn{init file}. Use the command
-line switches @samp{-q} and @samp{-u} to tell Emacs whether to load an
-init file (@pxref{Entering Emacs}).
-
-@vindex init-file-user
-When the @file{.emacs} file is read, the variable @code{init-file-user}
-says which user's init file it is. The value may be the null string or a
-string containing a user's name. If the value is a null string, it means
-that the init file was taken from the user that originally logged in.
-
-In all cases, @code{(concat "~" init-file-user "/")} evaluates to the
-directory name of the directory where the @file{.emacs} file was looked
-for.
+line switch @samp{-q} to tell Emacs whether to load an
+init file (@pxref{Entering Emacs}). Use the command line switch
+@samp{-user-init-file} (@pxref{Command Switches}) to tell Emacs to load
+a different file instead of @file{~/.emacs}.
+
+When the @file{.emacs} file is read, the variable @code{user-init-file}
+says which init file was loaded.
At some sites there is a @dfn{default init file}, which is the
library named @file{default.el}, found via the standard search path for
idea to install all packages and not interfere with the wishes of your
users.
+If you can't find which package provides the feature you require, try
+using the @code{package-get-package-provider} function. Eg., if you know
+that you need @code{thingatpt}, type:
+
+@example
+M-x package-get-package-provider RET thingatpt
+@end example
+
+which will return something like (fsf-compat "1.06"). You can the use
+one of the methods above for installing the package you want.
+
@subsection XEmacs and Installing Packages
Normally, packages are installed over the network, using EFS
@findex insert-parentheses
@findex move-over-close-and-reindent
The commands @kbd{M-(} (@code{insert-parentheses}) and @kbd{M-)}
-(@code{move-over-close-@*and-reindent}) are designed to facilitate a style of
+(@code{move-over-close-and-reindent}) are designed to facilitate a style of
editing which keeps parentheses balanced at all times. @kbd{M-(} inserts a
pair of parentheses, either together as in @samp{()}, or, if given an
argument, around the next several sexps, and leaves point after the open
all: $(MODNAME).ell
+distclean: clean
+
clean:
rm -f $(MODNAME).ell $(OBJS) base64_i.o base64_i.c
all: $(MODNAME).ell
+distclean: clean
+
clean:
rm -f $(MODNAME).ell $(OBJS) eldap_i.o eldap_i.c
all: $(MODNAME).ell
+distclean: clean
+
clean:
rm -f $(MODNAME).ell $(OBJS) sample_i.o sample_i.c
all: $(MODNAME).ell
+distclean: clean
+
clean:
rm -f $(MODNAME).ell $(OBJS) zlib_i.o zlib_i.c
+1999-11-10 XEmacs Build Bot <builds@cvs.xemacs.org>
+
+ * XEmacs 21.2.20 is released
+
+1999-10-07 Norbert Koch <n.koch@eai-delta.de>
+
+ * xemacs.mak: Ignore return code of 'del' calls. Use a make
+ variable for 'del'.
+
+1999-09-26 Adrian Aichner <aichner@ecf.teradyne.com>
+
+ * xemacs.mak (all): Update $(LISP)/auto-autoloads.elc? and
+ $(LISP)/custom-load.el using XEmacs itself, like xemacs-packages
+ do.
+ ($(LISP)\auto-autoloads.el): Add new rule.
+ ($(LISP)\custom-load.el): Ditto.
+
+1999-08-04 Andy Piper <andy@xemacs.org>
+
+ * xemacs.mak (HAVE_WIDGETS): add define to appropriate places.
+
+1999-07-26 Adrian Aichner <aichner@ecf.teradyne.com>
+
+ * xemacs.mak ($(MANDIR)\lispref\lispref.texi): Replace bad
+ dependency.
+
1999-07-30 XEmacs Build Bot <builds@cvs.xemacs.org>
* XEmacs 21.2.19 is released
NT=$(XEMACS)\nt
OUTDIR=$(NT)\obj
+# Define a variable for the 'del' command to use
+DEL=-del
+
# Program name and version
!include "..\version.sh"
!if !defined(HAVE_NATIVE_SOUND)
HAVE_NATIVE_SOUND=1
!endif
+!if !defined(HAVE_WIDGETS)
+HAVE_WIDGETS=1
+!endif
!if !defined(DEBUG_XEMACS)
DEBUG_XEMACS=0
!endif
MSW_DIALOG_SRC=$(XEMACS)\src\dialog.c $(XEMACS)\src\dialog-msw.c
MSW_DIALOG_OBJ=$(OUTDIR)\dialog.obj $(OUTDIR)\dialog-msw.obj
!endif
+!if $(HAVE_WIDGETS)
+MSW_DEFINES=$(MSW_DEFINES) -DHAVE_WIDGETS
+!endif
!if $(HAVE_NATIVE_SOUND)
MSW_DEFINES=$(MSW_DEFINES) -DHAVE_NATIVE_SOUND
!endif
!if $(DEBUG_XEMACS)
@dir /b/s $(OUTDIR)\*.sbr > bscmake.tmp
bscmake -nologo -o$(TEMACS_BROWSE) @bscmake.tmp
- @del bscmake.tmp
+ @$(DEL) bscmake.tmp
!endif
link.exe @<<
$(TEMACS_LFLAGS) $(TEMACS_OBJS) $(TEMACS_LIBS)
$(MANDIR)\xemacs\text.texi \
$(MANDIR)\xemacs\trouble.texi \
$(MANDIR)\xemacs\undo.texi \
- $(MANDIR)\xemacs\windows.texi \
+ $(MANDIR)\xemacs\windows.texi
$(INFODIR)\lispref.info: $(MANDIR)\lispref\lispref.texi
$(MANDIR)\lispref\hash-tables.texi \
$(MANDIR)\lispref\help.texi \
$(MANDIR)\lispref\hooks.texi \
- $(MANDIR)\lispref\index.texi \
+ $(MANDIR)\lispref\index.perm \
+ $(MANDIR)\lispref\index.unperm \
$(MANDIR)\lispref\internationalization.texi \
$(MANDIR)\lispref\intro.texi \
$(MANDIR)\lispref\keymaps.texi \
$(MANDIR)\lispref\windows.texi \
$(MANDIR)\lispref\x-windows.texi \
$(MANDIR)\lispref\index.unperm \
- $(MANDIR)\lispref\index.perm \
+ $(MANDIR)\lispref\index.perm
$(INFODIR)\new-users-guide.info: $(MANDIR)\new-users-guide\new-users-guide.texi
$(MANDIR)\new-users-guide\edit.texi \
$(MANDIR)\new-users-guide\modes.texi \
$(MANDIR)\new-users-guide\xmenu.texi \
- $(MANDIR)\new-users-guide\enter.texi \
+ $(MANDIR)\new-users-guide\enter.texi
$(INFODIR)\internals.info: $(MANDIR)\internals\internals.texi
$(MANDIR)\internals\internals.texi: \
$(MANDIR)\internals\index.unperm \
- $(MANDIR)\internals\index.perm \
+ $(MANDIR)\internals\index.perm
info: $(INFO_FILES)
LOADPATH=$(LISP)
$(DOC): $(LIB_SRC)\make-docfile.exe
- -del $(DOC)
+ $(DEL) $(DOC)
$(TEMACS) -batch -l $(TEMACS_DIR)\..\lisp\make-docfile.el -- -o $(DOC) -i $(XEMACS)\site-packages
$(LIB_SRC)\make-docfile.exe -a $(DOC) -d $(TEMACS_SRC) $(DOC_SRC1)
$(LIB_SRC)\make-docfile.exe -a $(DOC) -d $(TEMACS_SRC) $(DOC_SRC2)
#------------------------------------------------------------------------------
# use this rule to build the complete system
-all: $(XEMACS)\Installation $(OUTDIR)\nul $(LASTFILE) $(LWLIB) $(LIB_SRC_TOOLS) $(RUNEMACS) \
- $(TEMACS) update-elc $(DOC) dump-xemacs info
+all: $(XEMACS)\Installation $(OUTDIR)\nul $(LASTFILE) $(LWLIB) \
+ $(LIB_SRC_TOOLS) $(RUNEMACS) $(TEMACS) update-elc $(DOC) dump-xemacs \
+ $(LISP)/auto-autoloads.el $(LISP)/custom-load.el info
temacs: $(TEMACS)
@echo PlaceHolder > PlaceHolder
@xcopy /q PROBLEMS "$(INSTALL_DIR)\"
@xcopy /q PlaceHolder "$(INSTALL_DIR)\lock\"
- @del "$(INSTALL_DIR)\lock\PlaceHolder"
+ @$(DEL) "$(INSTALL_DIR)\lock\PlaceHolder"
@xcopy /q $(LIB_SRC)\*.exe "$(INSTALL_DIR)\$(EMACS_CONFIGURATION)\"
@copy $(LIB_SRC)\DOC "$(INSTALL_DIR)\$(EMACS_CONFIGURATION)"
@copy $(CONFIG_VALUES) "$(INSTALL_DIR)\$(EMACS_CONFIGURATION)"
@xcopy /e /q $(XEMACS)\lisp "$(INSTALL_DIR)\lisp\"
@echo Making skeleton package tree in $(PACKAGE_PREFIX) ...
@xcopy /q PlaceHolder "$(PACKAGE_PREFIX)\site-packages\"
- @del "$(PACKAGE_PREFIX)\site-packages\PlaceHolder"
+ @$(DEL) "$(PACKAGE_PREFIX)\site-packages\PlaceHolder"
@xcopy /q PlaceHolder "$(PACKAGE_PREFIX)\mule-packages\"
- @del "$(PACKAGE_PREFIX)\mule-packages\PlaceHolder"
+ @$(DEL) "$(PACKAGE_PREFIX)\mule-packages\PlaceHolder"
@xcopy /q PlaceHolder "$(PACKAGE_PREFIX)\xemacs-packages\"
- @del "$(PACKAGE_PREFIX)\xemacs-packages\PlaceHolder"
- @del PlaceHolder
+ @$(DEL) "$(PACKAGE_PREFIX)\xemacs-packages\PlaceHolder"
+ @$(DEL) PlaceHolder
distclean:
- del *.bak
- del *.orig
- del *.rej
- del *.tmp
- del $(XEMACS)\Installation
+ $(DEL) *.bak
+ $(DEL) *.orig
+ $(DEL) *.rej
+ $(DEL) *.tmp
+ $(DEL) $(XEMACS)\Installation
cd $(OUTDIR)
- del *.lib
- del *.obj
- del *.pdb
- del *.res
- del *.sbr
+ $(DEL) *.lib
+ $(DEL) *.obj
+ $(DEL) *.pdb
+ $(DEL) *.res
+ $(DEL) *.sbr
cd $(XEMACS)\$(TEMACS_DIR)
- del config.h
- del paths.h
- del Emacs.ad.h
- del *.bak
- del *.orig
- del *.rej
- del *.exe
- del *.map
- del *.bsc
- del *.pdb
+ $(DEL) config.h
+ $(DEL) paths.h
+ $(DEL) Emacs.ad.h
+ $(DEL) *.bak
+ $(DEL) *.orig
+ $(DEL) *.rej
+ $(DEL) *.exe
+ $(DEL) *.map
+ $(DEL) *.bsc
+ $(DEL) *.pdb
cd $(LIB_SRC)
- del DOC
- del *.bak
- del *.orig
- del *.rej
- del *.exe
- del *.obj
- del *.pdb
- del *.res
- del $(CONFIG_VALUES)
+ $(DEL) DOC
+ $(DEL) *.bak
+ $(DEL) *.orig
+ $(DEL) *.rej
+ $(DEL) *.exe
+ $(DEL) *.obj
+ $(DEL) *.pdb
+ $(DEL) *.res
+ $(DEL) $(CONFIG_VALUES)
cd $(LISP)
- -del /s /q *.bak *.elc *.orig *.rej
+ $(DEL) /s /q *.bak *.elc *.orig *.rej
cd $(INFODIR)
- del *.info* $(MANDIR)\internals\index.texi $(MANDIR)\lispref\index.texi
+ $(DEL) *.info* $(MANDIR)\internals\index.texi $(MANDIR)\lispref\index.texi
depend:
mkdepend -f xemacs.mak -p$(OUTDIR)\ -o.obj -w9999 -- $(TEMACS_CPP_FLAGS) -- $(DOC_SRC1) $(DOC_SRC2) $(DOC_SRC3) $(DOC_SRC4) $(DOC_SRC5) $(DOC_SRC6) $(DOC_SRC7) $(DOC_SRC8) $(DOC_SRC9) $(LASTFILE_SRC)\lastfile.c $(LIB_SRC)\make-docfile.c $(LIB_SRC)\run.c
!if $(HAVE_DIALOGS)
Compiling in support for dialogs.
!endif
+!if $(HAVE_WIDGETS)
+ Compiling in support for widgets.
+!endif
!if $(HAVE_NATIVE_SOUND)
Compiling in support for native sounds.
!endif
@type $(XEMACS)\Installation
@echo --------------------------------------------------------------------
+# Update auto-autoloads.el and custom-load.el similar to what
+# XEmacs.rules does for xemacs-packages.
+VANILLA=-vanilla
+FORCE:
+$(LISP)\auto-autoloads.el: FORCE
+ $(PROGNAME) $(VANILLA) -batch \
+ -l autoload -f batch-update-directory $(LISP)
+ $(PROGNAME) $(VANILLA) -batch \
+ -f batch-byte-compile $@
+ @$(DEL) $(LISP)\auto-autoloads.el~
+
+$(LISP)\custom-load.el: FORCE
+ $(PROGNAME) $(VANILLA) -batch -l cus-dep \
+ -f Custom-make-dependencies $(LISP)
+
# DO NOT DELETE THIS LINE -- make depend depends on it.
xemacs
SATISFIED
update-elc.stamp
+*.so.*
\ No newline at end of file
* faces.h (FACE_CACHEL_FONT): Use `MIN_LEADING_BYTE' instead of
128.
+1999-11-10 XEmacs Build Bot <builds@cvs.xemacs.org>
+
+ * XEmacs 21.2.20 is released
+
+1999-11-04 Martin Buchholz <martin@xemacs.org>
+
+ * mule-ccl.c (ccl_driver): Warning suppression
+
+1999-11-01 SL Baur <steve@miho.m17n.org>
+
+ * emacs.c (main_1): Guard call to reinit_vars_of_debug when not
+ building a debugged XEmacs.
+
+1999-10-28 Andreas Jaeger <aj@suse.de>
+
+ * src/emacs.c (main_1): Don't set the malloc hooks if using
+ DOUG_LEA_MALLOC.
+
+1999-10-30 Olivier Galibert <galibert@pobox.com>
+
+ * alloc.c (pdump_dump_rtables): Don't forget to dump the last
+ registered type.
+ (pdump): Ditto.
+
+1999-10-25 Olivier Galibert <galibert@pobox.com>
+
+ * emacs.c (main_1): Call reinit_vars_of_scrollbar_x.
+
+ * symsinit.h: Declare reinit_vars_of_scrollbar_x.
+
+1999-10-25 Martin Buchholz <martin@xemacs.org>
+
+ * redisplay.h (CLASS_RESET_CHANGED_FLAGS):
+ (GLOBAL_RESET_CHANGED_FLAGS):
+ (CLASS_REDISPLAY_FLAGS_CHANGEDP):
+ (RESET_CHANGED_SET_FLAGS):
+ Fix C++ compile errors/warnings.
+ These macros were just a tad too clever.
+
+ * process-unix.c (unix_open_network_stream):
+ * objects-x.c (allocate_nearest_color):
+ * mule-charset.c (vars_of_mule_charset):
+ * fileio.c (Ffile_truename):
+ * file-coding.c (vars_of_file_coding):
+ Fix compile errors/warnings.
+
+ * alloc.c (xstrdup): Use fact that memcpy returns its first arg.
+ (allocate_lisp_storage): Simplify.
+
+1999-10-24 Olivier Galibert <galibert@pobox.com>
+
+ * conslots.h: Add defines with first and last slot names.
+ * bufslots.h: Add defines with first and last slot names.
+
+ * buffer.c (common_init_complex_vars_of_buffer): Renamed from
+ reinit_complex_vars_of_buffer
+ (reinit_complex_vars_of_buffer): Reset the slots to the dumped
+ value.
+ (complex_vars_of_buffer): Dump the slots values.
+
+ * console.c (common_init_complex_vars_of_console): Renamed from
+ reinit_complex_vars_of_console
+ (reinit_complex_vars_of_console): Reset the slots to the dumped
+ value.
+ (complex_vars_of_console): Dump the slots values.
+
+ * alloc.c: Rename reloc_table to pdump_reloc_table, rt_list to
+ pdump_rt_list and move them at the beginning of the file.
+ (gc_sweep): Unmark pdumped objects after the sweep phase.
+ (pdump_dump_rtables): Change a bare 256 to
+ last_lrecord_type_index_assigned. Add a separator between the
+ adresses or lrecords and the ones of C structs in the dump file.
+ (pdump_load): Cope with the new separator and the renamings. Stop
+ looking for the hash tables list after it has been found (duh!).
+
+1999-10-24 Robert Bihlmeyer <robbe@orcus.priv.at>
+
+ * sound.c: support HAVE_ESD_SOUND
+
+ * miscplay.c:
+ * miscplay.h:
+ * linuxplay.c: Move large part of linuxplay to generalized file
+ miscplay. Make it platform independent.
+
+ * esd.c: New file
+
+1999-10-24 Adrian Aichner <aichner@ecf.teradyne.com>
+
+ * lisp.h (Dynarr_declare): Fix boo-boo.
+
+1999-10-24 Olivier Galibert <galibert@pobox.com>
+
+ * process-unix.c (allocate_pty): Fix HAVE_GETPT.
+ * process.h: Ditto.
+
+1999-10-24 Jan Vroonhof <vroonhof@math.ethz.ch>
+
+ * redisplay.c (start_with_line_at_pixpos): Remove assert(cur_elt
+ >=0). Handle the cur_elt == 0 case.
+
+1999-10-24 Jan Vroonhof <vroonhof@math.ethz.ch>
+
+ * unexelf.c: Merge Martin's c++ fixes back in
+
+1999-10-20 Jan Vroonhof <vroonhof@math.ethz.ch>
+
+ * unexelf.c (unexec): Only copy the global offset
+ table from memory on sgi machines.
+
+1999-08-13 Alexandre Oliva <oliva@dcc.unicamp.br>, Vin Shelton <acs@xemacs.org>
+
+ * unexelf.c: Enable GNU/Linux/alpha to build with gcc 2.95 by
+ adding support for an sbss section. Get IRIX 5.2 to build using
+ unexelf.c.
+
+ * m/iris4d.h: Use unexelf.o for unexec.
+
+ * m/iris5d.h: Use unexelf.o for unexec.
+
+1999-10-24 Jan Vroonhof <vroonhof@math.ethz.ch>
+
+ * unexelf.c: Revert to 21.1 version
+
+1999-08-28 Jan Vroonhof <vroonhof@math.ethz.ch>
+
+ * window.c (Fwindow_truncated_p): New function.
+
+1999-08-25 Jonathan Marten <jonathan.marten@uk.sun.com>
+
+ * window.c (window_truncation_on): Always return 0 for minibuffer
+ windows, to enable auto scrolling.
+
+1999-10-24 Neal Becker <nbecker@fred.net>
+ * process.h: Unix98 PTY support
+
+1999-10-17 Jan Vroonhof <vroonhof@math.ethz.ch>
+
+ * fileio.c (Ffile_truename): Do proper mule decoding on
+ the argument to xrealpath()
+
+1999-08-19 Stephen Tse <stephent@sfu.ca>
+
+ * process-unix.c (unix_open_network_stream): Add udp network
+ support; rename variable Qtcpip to Qtcp, parameter family to
+ protocol for consistency with Qudp.
+
+ * process-nt.c (nt_open_network_stream): Rename variable Qtcpip to
+ Qtcp, parameter family to protocol for consistency with Qudp.
+
+ * process.c (global_variables): Add a new variable Qudp for udp
+ network support; rename variable Qtcpip to Qtcp for consistency
+ with Qudp.
+ (Fopen_network_stream_internal): Rename parameter FAMILY to
+ PROTOCOL for consistency; fix a minor typo and add an explanation
+ in docstring for udp programming.
+ (Fopen_multicast_group_internal): Fix a minor typo in docstring.
+ (syms_of_process): Add a new variable Qudp for udp network
+ support; rename variable Qtcpip to Qtcp for consistency with Qudp.
+
+ * process.h (extern_variables): Add a new variable Qudp for udp
+ network support; rename variable Qtcpip to Qtcp for consistency
+ with Qudp.
+
+ * procimpl.h: Add a new variable Qudp for udp network support;
+ rename variable Qtcpip to Qtcp for consistency with Qudp.
+ (struct process_methods): Rename parameter family to protocol.
+
+
+1999-10-24 Olivier Galibert <galibert@pobox.com>
+
+ * alloc.c (pdump_make_hash): Divide pointers by 8 for a better hash.
+
+1999-10-23 Olivier Galibert <galibert@pobox.com>
+
+ * lrecord.h (struct lrecord_header): Removed dumped flags.
+
+ * dynarr.c: Use DUMPEDP instead of dumped flag.
+
+ * lisp.h (DUMPEDP): Added. Removed dumped flag from dynarr.
+
+ * alloc.c: Removed hash_next linked list pointer.
+
+ * *.c *.h: Removed markobj and mark_object parameters, removed GC_
+ and XGC macros.
+
+1999-10-14 Andy Piper <andy@xemacs.org>
+
+ * redisplay-x.c (x_output_shadows): fix dodgy maths for border
+ calculations.
+
+ * gutter.c (output_gutter): be more accurate about the area to be
+ cleared since X seems to manage to do the clear after drawing the
+ border.
+
+ * redisplay.h (RESET_CHANGED_FLAGS): new macro for setting
+ redisplay flags as a group.
+ (RESET_CHANGED_SET_FLAGS): ditto.
+ (CLASS_RESET_CHANGED_FLAGS): ditto.
+ (GLOBAL_RESET_CHANGED_FLAGS): ditto.
+ (REDISPLAY_FLAGS_CHANGEDP): new macro for testing redisplay flags
+ as a group.
+ (CLASS_REDISPLAY_FLAGS_CHANGEDP): ditto.
+ (GLOBAL_REDISPLAY_FLAGS_CHANGEDP): ditto.
+
+ * redisplay.c (redisplay_frame): use CLASS_RESET_CHANGED_FLAGS
+ instead of setting flags individually.
+ (redisplay_device): ditto CLASS_REDISPLAY_FLAGS_CHANGEDP.
+ (redisplay_device): ditto.
+ (redisplay_device): ditto CLASS_RESET_CHANGED_FLAGS.
+ (redisplay_without_hooks): ditto GLOBAL_REDISPLAY_FLAGS_CHANGEDP.
+ (redisplay_without_hooks): ditto CLASS_REDISPLAY_FLAGS_CHANGEDP.
+ (redisplay_without_hooks): ditto.
+ (redisplay_without_hooks): ditto GLOBAL_RESET_CHANGED_FLAGS.
+
+ * redisplay-x.c (x_output_string): unmap subwindows in the area.
+ (x_output_blank): ditto.
+
+ * redisplay-output.c (redisplay_output_display_block): don't unmap
+ subwindows in case layout optimization can avoid it.
+ (redisplay_output_subwindow): unmap subwindows in the area.
+ (redisplay_output_layout): optimize the output of layouts - only
+ output glyphs that have changed if nothing else of redisplay
+ significance has occurred.
+ (redisplay_output_pixmap): change args to
+ redisplay_clear_clipped_region.
+ (redisplay_clear_clipped_region): allow the clipped region to be
+ cleared of all subwindows except the one passed in.
+
+ * redisplay-msw.c (mswindows_output_blank): unmap subwindows in
+ the area.
+ (mswindows_output_cursor): ditto.
+ (mswindows_output_string): ditto.
+
+ * gutter.c (calculate_gutter_size): if the window buffer is nil
+ then don't continue.
+ (update_frame_gutters): be more lenient about when we actually
+ update the gutter. Layout optimization makes this
+ non-costly. Cache redisplay flags that we want to temporarily
+ ignore.
+
+ * glyphs.c (Fglyph_animated_timeout_handler): handle image
+ specific timeouts rather than iterating over the instance cache.
+ (glyph_animated_timeout_mapper): deleted.
+ (add_glyph_animated_timeout): use a weak list to hold onto the
+ image so that it can be GC'ed.
+ (disable_glyph_animated_timeout): disable a specific timeout.
+ (vars_of_glyphs): disable-animated-pixmaps is a new boolean for
+ controlling whether pixmaps are animated or not.
+
+ * glyphs-msw.c (mswindows_finalize_image_instance): make sure the
+ image timeout gets disabled when the image gets freed.
+
+ * glyphs-eimage.c (gif_instantiate): remove meaningless
+ comment. Cope with timeouts specified in the gif extension block.
+
+ * event-msw.c (vars_of_event_mswindows): new variable
+ mswindows-meta-activates-menu.
+ (mswindows_wnd_proc): only goto defproc with VK_MENU if the user
+ wants it.
+
+ * glyphs-x.c (x_finalize_image_instance): delete mask first so
+ that we can compare with image.
+
+1999-10-14 Jonathan Harris <jhar@tardis.ed.ac.uk>
+
+ * event-msw.c (mswindows_key_to_emacs_keysym):
+ Recognise keypad keys as different from normal keys.
+
+1999-10-14 Didier Verna <didier@xemacs.org>
+
+ * glyphs-x.c (x_finalize_image_instance): avoid freeing null pixmaps.
+
+1999-10-10 Olivier Galibert <galibert@pobox.com>
+
+ * symbols.c (init_symbols_once_early): dump Vquit_flag.
+
+ * symsinit.h: Updated.
+
+ * ntproc.c (vars_of_ntproc): Use defsymbol.
+
+ * emacs.c (main_1): Updated reinit calls.
+
+ * lisp.h: Removed Fpurecopy and pure_put declarations.
+ * fns.c: Removed pure_put.
+
+ * eval.c (Fdefvar): pure_put -> Fput
+ (Fdefconst): Ditto.
+ * frame-x.c (init_x_prop_symbols): Ditto.
+ * symbols.c (deferror): Ditto.
+
+ * alloc.c (Fmake_byte_code): Remove Fpurecopy call.
+ * buffer.c (vars_of_buffer): Ditto.
+ * bytecode.c (Ffetch_bytecode): Ditto.
+ (optimize_compiled_function): Ditto.
+ * emacs.c (vars_of_emacs): Ditto.
+ * emodules.c (vars_of_module): Ditto.
+ * eval.c (define_function): Ditto.
+ (Fautoload): Ditto.
+ * frame.c (vars_of_frame): Ditto.
+ * intl.c (Fset_domain): Ditto.
+ * lread.c (load_force_doc_string_unwind): Ditto.
+ * menubar.c (vars_of_menubar): Ditto.
+ * minibuf.c (reinit_complex_vars_of_minibuf): Ditto.
+
+ * debug.c (reinit_vars_of_debug): Extracted.
+ * device-x.c (reinit_vars_of_device_x): Ditto.
+ * emodules.c (reinit_vars_of_module): Ditto.
+ * font-lock.c (reinit_vars_of_font_lock): Ditto.
+ * glyphs-widget.c (reinit_vars_of_glyphs_widget): Ditto.
+ * glyphs.c (reinit_vars_of_glyphs): Ditto.
+ * gui-x.c (reinit_vars_of_gui_x): Ditto.
+ * insdel.c (reinit_vars_of_insdel): Ditto.
+ * menubar-x.c (reinit_vars_of_menubar_x): Ditto.
+ * minibuf.c (reinit_complex_vars_of_minibuf): Ditto.
+ * mule-wnnfns.c (reinit_vars_of_mule_wnn): Ditto.
+ * print.c (reinit_vars_of_print): Ditto.
+ * redisplay.c (reinit_vars_of_redisplay): Ditto.
+ * select-x.c (reinit_vars_of_xselect): Ditto.
+ * undo.c (reinit_vars_of_undo): Ditto.
+
+1999-10-10 Olivier Galibert <galibert@pobox.com>
+
+ * symsinit.h: Updated declarations, see other ChangeLog entries.
+
+ * redisplay.c (init_redisplay): Ensure proper reinitialisation.
+
+ * lrecord.h (XD_DYNARR_DESC): Introduce XD_INT_RESET and use it.
+
+ * glyphs.c: Add the ii_keyword_entry and related descriptions.
+ Fix the image_instantiator_methods one.
+
+ * file-coding.c: Plonk all data that needs to be dumped in a
+ dynamically allocated structure.
+
+ * extents.c (reinit_vars_of_extents): Extracted from
+ vars_of_extents.
+
+ * event-stream.c (vars_of_event_stream): Don't staticpro when
+ pdump_wire is enough.
+
+ * event-msw.c (reinit_vars_of_event_mswindows): Extracted from
+ vars_of_event_mswindows.
+
+ * event-Xt.c (reinit_vars_of_event_Xt): Extracted from
+ vars_of_event_Xt.
+
+ * eval.c (vars_of_eval): Don't staticpro when pdump_wire is enough.
+
+ * emacs.c (main_1): Added some reinit calls.
+
+ * device-x.c (reinit_console_type_create_device_x): Extracted from
+ console_type_create_device_x.
+
+ * console.h: Declare the console_type_entry_dynarr description.
+
+ * console.c: Unstatic the console_type_entry_dynarr description.
+
+ * alloc.c: Removed some dubious comments. Handle XD_INT_RESET.
+
+1999-10-07 Olivier Galibert <galibert@pobox.com>
+
+ * symsinit.h: Updated declarations, see other ChangeLog entries.
+
+ * minibuf.c (reinit_complex_vars_of_minibuf): Extracted from
+ complex_vars_of_minibuf.
+
+ * lrecord.h: Removed XD_PARENT_INDIRECT (unused and
+ unimplemented), added XD_LO_LINK.
+
+ * lisp.h (pdump_wire_list): Add declaration.
+
+ * glyphs.h (INITIALIZE_DEVICE_IIFORMAT): Fix bug found by Andy.
+ (INITIALIZE_IMAGE_INSTANTIATOR_FORMAT): Fix stupid bug.
+ (REINITIALIZE_IMAGE_INSTANTIATOR_FORMAT): Remove, useless once the
+ stupid bug fixed.
+
+ * glyphs.c (reinit_image_instantiator_format_create): Remove.
+
+ * glyphs-x.c (reinit_image_instantiator_format_create_glyphs_x):
+ Remove.
+
+ * glyphs-widget.c
+ (reinit_image_instantiator_format_create_glyphs_widget): Remove.
+
+ * glyphs-msw.c
+ (reinit_image_instantiator_format_create_glyphs_mswindows):
+ Remove.
+
+ * glyphs-eimage.c
+ (reinit_image_instantiator_format_create_glyphs_eimage): Remove.
+
+ * frame.c (Fmake_frame): Don't reset the face cache when using the
+ stream device.
+
+ * file-coding.c: Dumped the_codesys_prop_dynarr and added all
+ relevant descriptions.
+
+ * events.c (reinit_vars_of_events): Extracted from vars_of_events.
+
+ * eval.c: The subr is _not_ a lcrecord.
+
+ * emacs.c (main_1): Call vars_of_specifier early before any
+ specifier creation (e.g in vars_of_glyphs, at least). Remove the
+ useless reinit_image_instantiator_format*. Add
+ reinit_vars_of_events and reinit_complex_vars_of_minibuf. Add
+ calls to lstream_type_create* and process_type_create*.
+
+ * elhash.c: Dump Vall_weak_hash_tables correctly.
+
+ * data.c: Dump Vall_weak_lists correctly.
+
+ * console.c: Fix description.
+
+ * console-stream.c (init_console_stream): Do initializations
+ correctly in the pdump case.
+
+ * chartab.c: Fix description. Dump Vall_syntax_tables correctly.
+ (Fcopy_char_table): Link into Vall_syntax_tables.
+
+ * alloc.c (pdump_wire_list): Added.
+ (Fgarbage_collect): Fix loop in stats couting missing the last
+ lrecord type.
+ (pdump_register_sub): Added XD_LO_LINK.
+ (pdump_dump_data): Ditto. Fixed XD_LO_RESET_NIL forgttting the
+ counter.
+ (pdump_reloc_one): Ditto.
+ (pdump_scan_by_alignement): Use last_lrecord_type_index_assigned
+ instead of 256.
+ (pdump_dump_wired): Added lists.
+ (pdump): Use last_lrecord_type_index_assigned instead of 256.
+ Dump last_lrecord_type_index_assigned value. Fix minor bugs.
+
+1999-10-07 Andy Piper <andy@xemacs.org>
+
+ * glyphs-msw.c (mswindows_finalize_image_instance): zero out
+ bitmap slices.
+
+ * glyphs-x.c (x_finalize_image_instance): fix FMW problem.
+
+1999-10-06 Andy Piper <andy@xemacs.org>
+
+ * elhash.c (resize_hash_table): Correct reference to lrecord_header.
+
+1999-10-06 Damon Lipparelli <lipp@primus.com>
+
+ * elhash.h: forward declare Lisp_Hash_Table.
+
+1999-10-06 Andy Piper <andy@xemacs.org>
+
+ * glyphs.c (Fset_image_instance_property): mark glyphs as dirty
+ after setting an image instance property.
+
+1999-10-05 Andy Piper <andy@xemacs.org>
+
+ * gutter.c (update_frame_gutters): output gutters if
+ windows_changed is set. This is the only way of catching changes
+ in selected window which obviously can affect the specifiers.
+
+ * redisplay.c: new state flags, subwindows_state_changed and
+ subwindows_state_changed set.
+ (redisplay_window): use them.
+ (redisplay_device): ditto.
+ (redisplay_without_hooks): ditto.
+ (redisplay_frame): ditto. Reset subwindow cachels if
+ subwindows_changed is set.
+ (redisplay_window): call mark_glyph_cachels_as_clean after
+ redisplaying.
+
+ * redisplay-x.c (x_output_x_pixmap): select correct
+ pixmap image for display depending on the currently selected
+ slice.
+
+ * redisplay-output.c (compare_runes): check dirtiness when
+ checking RUNE_DGLYPH runes.
+ (compare_display_blocks): relax invalidation of display blocks
+ since we can now detect whether individual glyphs have changed or
+ not.
+
+ * redisplay-msw.c (mswindows_output_dibitmap): select correct
+ bitmap image for display depending on the currently selected
+ slice.
+
+ * glyphs.h (struct Lisp_Image_Instance): add a dirty flag.
+ (IMAGE_INSTANCE_DIRTYP): new macro.
+ (XIMAGE_INSTANCE_DIRTYP): ditto.
+ (MARK_IMAGE_INSTANCE_CHANGED): ditto.
+ (GLYPH_DIRTYP): ditto.
+ (XGLYPH_DIRTYP): ditto.
+ (MARK_GLYPH_CHANGED): ditto.
+ (GLYPH_CACHEL_DIRTYP): ditto.
+ (struct glyph_cachel): add a dirty flag.
+
+ * glyphs.c (update_frame_subwindows): Don't update on
+ glyphs_changed.
+ (glyph_animated_timeout_mapper): new function. Map over the
+ instance cache lookinng for animated images to update.
+ (Fglyph_animated_timeout_handler): new function. Lisp callback for
+ handling animated image timeout events.
+ (disable_glyph_animated_timeout): new function. Add the animated
+ image timeout.
+ (disable_glyph_animated_timeout): new function. Remove the
+ animated image timeout.
+ (syms_of_glyphs): initialize Qglyph_animated_timeout_handler and
+ friends.
+ (vars_of_glyphs): initialize Vglyph_animated_ticker.
+ (image_instance_equal): add the currently displayed slice.
+ (image_instance_hash): ditto.
+ (allocate_glyph): initialize dirty flag.
+ (glyph_width): rename glyph -> glyph_or_image.
+ (glyph_height_internal): ditto.
+ (glyph_dirty_p): new function. Determine whether the image
+ instance in the domain and/or glyph is dirty.
+ (set_glyph_dirty_p): set the dirtiness.
+ (update_glyph_cachel_data): take dirtiness into account. Pass the
+ image instance we are interested in to glyph_width and friends.
+ (get_glyph_cachel_index): make non-static. Always call
+ update_glyph_cachel_data.
+ (mark_glyph_cachels_as_not_updated): meaningless formatting
+ change.
+ (mark_glyph_cachels_as_clean): new function. Clean dirtiness from
+ glyph cachels.
+
+ * glyphs-x.h (struct x_image_instance_data): change
+ pixmap to a list of pixmaps.
+ (IMAGE_INSTANCE_X_PIXMAP_SLICE): new macro.
+ (IMAGE_INSTANCE_X_PIXMAP_SLICES): ditto.
+ (XIMAGE_INSTANCE_X_PIXMAP_SLICE): ditto.
+ (XIMAGE_INSTANCE_X_PIXMAP_SLICES): ditto.
+
+ * glyphs-x.c (x_finalize_image_instance): make sure multi pixmap
+ images get deleted properly.
+ (init_image_instance_from_x_image): add slices paramater and use
+ it to initialize x_image_instance_data correctly.
+ (image_instance_add_x_image): new function. Add new pixmaps to our
+ set of instantiated pixmaps for an image. Used by animated images.
+ (x_init_image_instance_from_eimage): add a slices
+ parameter. Instantiate all images from the eimage.
+ (x_xpm_instantiate): update use of
+ init_image_instance_from_x_image.
+ (init_image_instance_from_xbm_inline): ditto.
+ (x_initialize_pixmap_image_instance): add slices paramater and use
+ it to allocate x_image_instance_data correctly.
+
+ * glyphs-msw.h (struct mswindows_image_instance_data): change
+ bitmap to a list of bitmaps.
+ (IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICE): new macro.
+ (IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICES): ditto.
+ (XIMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICE): ditto.
+ (XIMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICES): ditto.
+
+ * glyphs-msw.c (init_image_instance_from_dibitmap): add slices
+ paramater and use it to initialize mswindows_image_instance_data
+ correctly.
+ (image_instance_add_dibitmap): new function. Add new bitmaps to
+ our set of instantiated bitmaps for an image. Used by animated
+ images.
+ (mswindows_init_image_instance_from_eimage): add a slices
+ parameter. Instantiate all images from the eimage.
+ (mswindows_xpm_instantiate): update use of
+ init_image_instance_from_dibitmap.
+ (bmp_instantiate): ditto.
+ (init_image_instance_from_xbm_inline): ditto.
+ (mswindows_finalize_image_instance): make sure all the bitmap
+ slices get deleted.
+ (mswindows_initialize_dibitmap_image_instance): add slices
+ paramater and use it to allocate mswindows_image_instance_data
+ correctly.
+
+ * glyphs-eimage.c (jpeg_instantiate): give extra paramter to
+ init_image_instance_from_eimage.
+ (png_instantiate): ditto.
+ (tiff_instantiate): ditto.
+ (gif_instantiate): allocate bitmaps for all gif slices not just
+ the first one.
+
+ * device.h (struct device): add subwindows_state_changed flag.
+ (MARK_DEVICE_SUBWINDOWS_STATE_CHANGED): new macro.
+ (MARK_DEVICE_FRAMES_GLYPHS_CHANGED): ditto.
+
+ * console.h (struct console_methods): add a slice parameter to
+ init_image_instance_from_eimage_method.
+
+ * redisplay.c (create_string_text_block): Allow buffer to be nil
+ without crashing.
+
+1999-09-24 Andy Piper <andy@xemacs.org>
+
+ * glyphs-x.c: only include gui-x.h if we are building with
+ widgets.
+
+ * gui-x.c (vars_of_gui_x): only set popup_up_p if we have popups.
+
+1999-09-28 Lee Kindness <lkindness@csl.co.uk>
+
+ * objects-x.c (allocate_nearest_color): will return 0 (failure)
+ when the colormap is full and the color it has computed to be the
+ 'nearest' has been allocated read/write.
+
+1999-10-02 Olivier Galibert <galibert@pobox.com>
+
+ * search.c (reinit_vars_of_search): Reinit the search cache
+ correctly.
+
+ * elhash.h: Make the description visible. Declare
+ resize_hash_table.
+
+ * elhash.c (resize_hash_table): Extracted from enlarge_hash_table
+ to generalize the hash table reorganization.
+ (reorganize_hash_table): Added.
+ (enlarge_hash_table): Uses resize_has_table.
+
+ * casetab.c (complex_vars_of_casetab): staticpro the mule mirror
+ tables.
+
+ * alloc.c: Add correct management of blocks of structures.
+ Reorganize hash tables at reload since the hash values can change
+ with the pointers.
+
+1999-10-01 Olivier Galibert <galibert@pobox.com>
+
+ * lisp.h: Add pdump_wire declaration
+
+ * elhash.c (vars_of_elhash): Wire Vall_weak_hash_tables.
+ * symbols.c (init_symbols_once_early): Wire Qnil and Qunbound.
+
+ * alloc.c (pdump_wire): Added..
+ (pdump_load): Support it.
+ (pdump): Support it
+
+ * glyphs-msw.c
+ (reinit_image_instantiator_format_create_glyphs_mswindows): Fix
+ macro calls.
+
+1999-09-28 Olivier Galibert <galibert@pobox.com>
+
+ * symsinit.h: Added lots of prototypes.
+
+ * symeval.h: Added defsymbol_nodump declaration.
+
+ * symbols.c (find_symbol_value): Lame attempt at making the
+ startup go further.
+ (defsymbol_nodump): Added.
+
+ * mule-charset.c: Collapsed global lisp objects arrays in one
+ dumpable structure.
+
+ * lrecord.h: Added some flags.
+
+ * lisp.h: Added dumped flag to dynarrs. Added dumpstruct
+ declaration.
+
+ * glyphs.h (INITIALIZE_IMAGE_INSTANTIATOR_FORMAT_NO_SYM): Don't
+ staticpro dynamic variables.
+
+ * glyphs.c (reinit_specifier_type_create_image): Added.
+ (image_instantiator_format_create): Dump image instantiator format
+ dynarr.
+ (reinit_image_instantiator_format_create): Added.
+
+ * emacs.c (main_1): Added reinits calls.
+
+ * dynarr.c: Protect dumped dynarrays from going berzek in free or
+ realloc.
+
+ * specifier.h (INITIALIZE_SPECIFIER_TYPE): Don't staticpro dynamic
+ variables.
+ * specifier.c (specifier_type_create): Dump the specifier type
+ dynarr.
+ (reinit_specifier_type_create): Added.
+ * console.h (INITIALIZE_CONSOLE_TYPE): Don't staticpro dynamic
+ variables.
+ * console.c (console_type_create): Dump the console type dynarr.
+ (reinit_vars_of_console): Extracted from vars_of_console.
+ (reinit_complex_vars_of_console): Extracted from
+ complex_vars_of_console
+ * window.c (reinit_vars_of_window): Extracted from vars_of_window.
+ * toolbar.c (reinit_specifier_type_create_toolbar): Added.
+ * search.c (reinit_vars_of_search): Extracted from vars_of_search.
+ * objects.c (reinit_specifier_type_create_objects): Added.
+ (reinit_vars_of_objects): Extracted from vars_of_objects.
+ * lstream.c (reinit_vars_of_lstream): Extracted from
+ vars_of_lstream.
+ * lread.c (reinit_vars_of_lread): Extracted from vars_of_lread.
+ * gutter.c (reinit_specifier_type_create_gutter): Added.
+ * glyphs-x.c (reinit_image_instantiator_format_create_glyphs_x):
+ Added.
+ * glyphs-widget.c
+ (reinit_image_instantiator_format_create_glyphs_widget): Added
+ * glyphs-msw.c
+ (reinit_image_instantiator_format_create_glyphs_mswindows): Added.
+ * glyphs-eimage.c
+ (reinit_image_instantiator_format_create_glyphs_eimage): Added.
+ * event-stream.c (reinit_vars_of_event_stream): Extracted from
+ vars_of_event_stream
+ * eval.c (reinit_vars_of_eval): Extracted from vars_of_eval.
+ * device.c (reinit_vars_of_device): Extracted from vars_of_device.
+ * console-x.c (reinit_console_type_create_x): Added.
+ * console-tty.c (reinit_console_type_create_tty): Added
+ * console-stream.c (reinit_console_type_create_stream): Added.
+ (init_console_stream): If PDUMP, always reinitialise basic
+ devices.
+ * console-msw.c (reinit_console_type_create_mswindows): Added.
+ * buffer.c (reinit_vars_of_buffer): Extracted from
+ init_vars_of_buffer.
+ (reinit_complex_vars_of_buffer): Extracted from
+ complex_vars_of_buffer
+
+ * alloc.c: Further with the portable dumping, the revenge.
+ (dumpstruct): Added.
+ (reinit_alloc_once_early): Extracted from init_alloc_once_early.
+
+ * specifier.c (sizeof_specifier): Correct size computation.
+ (make_specifier_internal): Ditto.
+
+1999-09-27 Olivier Galibert <galibert@pobox.com>
+
+ * alloc.c: Further with the portable dumping.
+
+1999-09-27 Martin Buchholz <martin@xemacs.org>
+
+ * glyphs-x.c (update_widget_face): Remove bogus cast
+
+ * data.c (sign_extent_lisp):
+ * data.c (check_int_range):
+ * data.c (Faref):
+ * data.c (Faset):
+ * data.c (number_char_or_marker_to_int):
+ * data.c (number_char_or_marker_to_double):
+ * data.c (Frem):
+ * data.c (Fmod):
+ * extents.c (print_extent_1):
+ * fns.c (print_bit_vector):
+ * fns.c (Flength):
+ * fns.c (Fsafe_length):
+ * fns.c (copy_list):
+ * fns.c (Fsubseq):
+ * fns.c (Felt):
+ * fns.c (Flast):
+ * fns.c (Fnbutlast):
+ * insdel.h:
+ * marker.c (print_marker):
+ * syntax.h:
+ * bytecode.c (bytecode_arithcompare):
+ * bytecode.c (bytecode_arithop):
+ * lisp.h:
+ * lisp.h (EXTERNAL_LIST_LOOP_DELETE_IF):
+ * lisp.h (TRUE_LIST_P):
+ * lisp.h (CHECK_TRUE_LIST):
+ * lisp.h (bit_vector_length):
+ * lisp.h (GCPRO4): Make consistent.
+ * lisp.h (NGCPRO4): Make consistent.
+ * lisp.h (NNGCPRO4): Make consistent.
+ * alloc.c (Fmake_list):
+ * alloc.c (Fmake_string):
+ Use proper 64-bit types, e.g. EMACS_INT or size_t instead of int.
+ This should make all arithmetic 64-bit clean.
+
+ Use %ld with (long) casts in print statements of types with sizes
+ possibly larger than int.
+
+ Following functions had mismatched prototypes!!:
+ do_marker_adjustment(), fixup_internal_substring(), scan_lists(),
+ char_quoted(), make_string_from_buffer(),
+ make_string_from_buffer_no_extents()
+
+ The types of Bufpos, Bytind, Memind, Bytecount, Charcount,
+ Extcount are all now EMACS_INT. I hope to see the day when I can
+ create a buffer with more than INT_MAX characters, without having
+ XEmacs slow down to a crawl. I also hope to be able to create a
+ list with more than INT_MAX cons cells.
+
+ * redisplay.c (decode_mode_spec):
+ The %p and %P specs in the mode line were not correct for buffers
+ larger than MAX_INT/100! The %p spec was off by .5% even for
+ small buffers!
+
+1999-09-27 Martin Buchholz <martin@xemacs.org>
+
+ * cmdloop.c (num_input_keys):
+ * print.c (debug_temp):
+ * emacs.c (Vinfo_directory):
+ Delete unused variables
+
+ * console-x.h (x_interline_space): Mark as unimplemented.
+ * redisplay-x.c (x_interline_space): Mark as unimplemented.
+
+ * event-Xt.c (pending_timeouts):
+ * linuxplay.c (linuxplay_sndbuf):
+ * profile.c (QS*):
+ * search.c (searchbufs):
+ * specifier.c (specifier_type_entry_dynarr):
+ * undo.c (pending_boundary):
+ * event-stream.c (the_low_level_timeout_blocktype):
+ * extents.c (gap_array_marker_freelist):
+ * extents.c (extent_list_marker_freelist):
+ * print.c (being_printed):
+ * print.c (alternate_do_pointer):
+ * alloc.c (first_string_chars_block):
+ * alloc.c (current_string_chars_block):
+ * emacs.c (initial_argv):
+ * emacs.c (initial_argc):
+ * eval.c (lisp_eval_depth):
+ * free-hook.c (pointer_table):
+ * free-hook.c (free_queue):
+ * free-hook.c (current_free):
+ * free-hook.c (strict_free_check):
+ * redisplay.c (formatted_string_emchar_dynarr):
+ * redisplay.c (formatted_string_display_line):
+ * redisplay.c (formatted_string_extent_dynarr):
+ * redisplay.c (formatted_string_extent_start_dynarr):
+ * redisplay.c (formatted_string_extent_end_dynarr):
+ * redisplay.c (updating_line_start_cache):
+ * redisplay.c (last_display_warning_tick):
+ * redisplay.c (display_warning_tick):
+ * redisplay.c (internal_cache):
+ * window.c (Vwindow_configuration_free_list):
+ Make static.
+
+ * redisplay.c (Vinitial_window_system): Make CONST.
+
+1999-09-24 Martin Buchholz <martin@xemacs.org>
+
+ * redisplay-tty.c (term_get_fkeys_1): Minor aesthetic improvements.
+
+ * doprnt.c (get_doprnt_args): Use int, not short, with va_arg.
+
+1999-09-24 Andy Piper <andy@xemacs.org>
+
+ * redisplay-output.c (output_display_line): only clear the borders
+ if we are not displaying the gutter.
+
+1999-09-24 Jan Vroonhof <vroonhof@math.ethz.ch>
+
+ * frame-x.c (x_any_window_to_frame): Let Xt find the widget and
+ then use x_any_widget_or_parent_to_frame().
+ (x_find_frame_for_window): remove special cases.
+
+1999-09-24 Andy Piper <andy@xemacs.org>
+
+ * scrollbar-x.c (x_window_is_scrollbar): deleted.
+ * scrollbar-x.h: ditto.
+
+1999-09-23 Martin Buchholz <martin@xemacs.org>
+
+ * alloc.c (this_marks_a_marked_record): Remove.
+
+ * buffer.c (mark_buffer):
+ * buffer.c (nuke_all_buffer_slots):
+ * console.c (mark_console):
+ * console.c (nuke_all_console_slots):
+ * frame.c (mark_frame):
+ * frame.c (nuke_all_frame_slots):
+ Treat MARKED_SLOT() macros consistently.
+
+ * device.h (error_check_device_type):
+ * faces.c (face_getprop):
+ * fileio.c (DRIVE_LETTER):
+ * filelock.c (lock_file_1):
+ * frame-x.c (x_create_widgets):
+ * frame.h (error_check_frame_type):
+ * keymap.c (print_keymap):
+ * keymap.c (Fkey_description):
+ * keymap.c (where_is_recursive_mapper):
+ * mule-charset.h (CHARSET_LEADING_BYTE):
+ * objects-msw.c (mswindows_color_instance_hash):
+ * objects.c (color_instance_equal):
+ * objects.h (struct color_specifier):
+ * objects.h (struct font_specifier):
+ * objects.h (struct face_boolean_specifier):
+ * opaque.h (get_opaque_ptr):
+ * opaque.h (set_opaque_ptr):
+ * process-unix.c (set_socket_nonblocking_maybe):
+ * specifier.h (SPECIFIER_TYPE_P):
+ * symbols.c (store_symval_forwarding):
+ * syssignal.h (EMACS_KILLPG):
+ * terminfo.c (emacs_tparam):
+ * glyphs.c (glyph_putprop):
+ * glyphs.c (glyph_remprop):
+ * glyphs.c (Fimage_instance_subwindow_id):
+ * window.c (mark_window):
+ * window.c (mark_window_config):
+ * window.c (Fset_window_configuration):
+ * window.c (save_window_save):
+ * eval.c (Fuser_variable_p):
+ * eval.c (Fcommand_execute):
+ * eval.c (Feval):
+ * eval.c (Ffuncall):
+ * lisp.h (XPNTR):
+ * lisp.h (INT_OR_FLOATP):
+ * lisp.h (GC_INT_OR_FLOATP):
+ * lisp.h (XFLOATINT):
+ * lisp.h (IS_ANY_SEP):
+ * mule-ccl.c (Fccl_execute):
+ * mule-ccl.c (Fccl_execute_on_string):
+ * redisplay-x.c (x_output_string):
+ Remove redundant extra parentheses.
+
+1999-09-22 Martin Buchholz <martin@xemacs.org>
+
+ * chartab.c (word_boundary_p): Add prototype for warning avoidance.
+ * eval.c (PRIMITIVE_FUNCALL): ANSIfy
+ * free-hook.c (fun_ptr): ANSIfy
+ * getloadavg.c: Remove declaration for errno.
+ * gui.c (allocate_gui_item): ANSIfy
+ * gui.h (allocate_gui_item): ANSIfy
+ * mule-ccl.c (resolve_symbol_ccl_program): Make static
+ * realpath.c: Remove K&R support.
+ * redisplay-x.c (x_output_display_block): Don't shadow previous local
+ * glyphs-widget.c (layout_instantiate): Don't shadow previous local
+ * gutter.c (get_gutter_coords): Make static.
+ * lread.c (locate_file_map_suffixes): Make static.
+ * ralloc.c (relinquish): ANSIfy
+ * redisplay.c:
+ * lisp.h:
+ Move prototypes from redisplay.c to lisp.h
+
+1999-09-22 Martin Buchholz <martin@xemacs.org>
+
+ * glyphs-x.c (x_widget_set_property):
+ - Remove unnecessary initialization.
+ - Use char*, not Bufbyte *, with GET_C_STRING_OS_DATA_ALLOCA
+ * glyphs-x.c (x_widget_instantiate):
+ - Use char*, not Bufbyte *, with GET_C_STRING_OS_DATA_ALLOCA
+ * unexelf.c (unexec):
+ Add cast for C++ compilability.
+ * redisplay.h:
+ Fix a typo.
+ * ralloc.c (r_alloc_reinit):
+ SET_FUN_PTR was broken wrt ANSI aliasing!
+ To compensate, use __typeof__ when using gcc, else live with
+ possible (but rare) warnings.
+ * ralloc.c (init_ralloc):
+ Ditto
+ * ralloc.c: Use the real dlmalloc prototype for __morecore.
+ * lread.c (locate_file_map_suffixes):
+ * input-method-xlib.c (XIM_init_frame):
+ - Xlib functions should use XPointer, not XtPointer.
+ * input-method-xlib.c (XIM_delete_frame):
+ - Xlib functions should use XPointer, not XtPointer.
+ * input-method-xlib.c (IMDestroyCallback):
+ - Simplify.
+ - XFRAME (obj) can never be NULL, so don't test for it.
+ * gutter.h:
+ Add GUTTER_POS_LOOP for iterating over all gutter_pos'es
+ * gutter.c (SET_GUTTER_WAS_VISIBLE_FLAG):
+ Run c-backslash-region on macro body.
+ * gutter.c (gutter_was_visible):
+ Remove redundant parens - this is not a macro.
+ * gutter.c (redraw_exposed_gutters):
+ Use GUTTER_POS_LOOP.
+ * gutter.c (gutter_specs_changed):
+ Use GUTTER_POS_LOOP.
+ * gutter.c (gutter_geometry_changed_in_window):
+ Use GUTTER_POS_LOOP.
+ * gutter.c (update_frame_gutters):
+ Use GUTTER_POS_LOOP.
+ * gutter.c (init_frame_gutters):
+ Use GUTTER_POS_LOOP.
+ * file-coding.c (determine_real_coding_system):
+ Fix C++ compile error.
+ * emodules.c (find_make_module):
+ Cast return value from xrealloc
+ * emacs.c (Fkill_emacs):
+ Use __typeof__, when available.
+ * emacs.c (voodoo_free_hook):
+ Use __typeof__, when available.
+ (Unfortunately, the type of __free_hook is glibc-version-dependent)
+ * dired.c (user_cache): Use Bufbyte *, not char *
+ * dired.c (Fuser_name_all_completions): Ditto.
+
+1999-09-22 Andy Piper <andy@xemacs.org>
+
+ * redisplay.c (redisplay_frame): reset the gutter display lines
+ when we reset the subwindows.
+
+ * gutter.c (reset_gutter_display_lines): new function.
+
+ * window.c (Flast_nonminibuf_window): new function equivalent to
+ FRAME_LAST_NONMINIBUF_WINDOW ().
+ (syms_of_window): declare it.
+
+ * redisplay.c (create_string_text_block): don't add bogus eol
+ markers to gutter display lines.
+
+ * glyphs.c (reset_subwindow_cachels): make sure we unmap
+ subwindows using unmap_subwindow so that expose events get
+ registered correctly.
+
+ * window.c (window_scroll): use Vwindow_pixel_scroll_increment to
+ determine how much to scroll the window.
+ (vars_of_window): Vwindow_pixel_scroll_increment is a new
+ variable.
+
+1999-09-20 Robert Pluim <rpluim@nortelnetworks.com>
+
+ * glyphs-x.c (update_widget_face): Guard fontList declaration for
+ non-motif uses.
+
+1999-09-20 Andy Piper <andy@xemacs.org>
+
+ * glyphs-msw.c (mswindows_update_subwindow): update faces.
+
+1999-09-19 Andy Piper <andy@xemacs.org>
+
+ * glyphs.c (update_frame_subwindows): update if faces have
+ changed.
+
+ * glyphs-x.c (x_widget_instantiate): create the clip widget using
+ lwlib rather than directly.
+ (x_finalize_image_instance): delete the clip widget using lwlib.
+ (x_update_subwindow): update widget faces.
+ (update_widget_face): new function for updating the face
+ properties of a widget.
+ (x_widget_set_property): update widget faces.
+
+ * lwlib-Xlw.c (xlw_create_clip_window): new function. We need to
+ manage the clip widgets using lwlib so that we can delete them in
+ a safe manner.
+
+1999-09-16 Martin Buchholz <martin@xemacs.org>
+
+ * lisp-union.h:
+ * lisp-disunion.h:
+ Define new, potentially faster INT arithmetic macros
+ INT_PLUS, INT_MINUS, INT_PLUS1, INT_MINUS1
+ * bytecode.c (execute_optimized_function):
+ Use new macros.
+ Fix metering code
+ * bytecode.c (bytecode_negate):
+ Optimize for integer case.
+
+1999-08-29 Andreas Jaeger <aj@arthur.rhein-neckar.de>
+
+ * m/mips.h: Support for mips-linux: Add !linux around places
+ that are not valid for linux, define TEXT_START, DATA_START,
+ DATA_SEG_BITS.
+
+1999-09-16 Andy Piper <andy@xemacs.org>
+
+ * redisplay-output.c (redisplay_output_subwindow): clip subwindows
+ that don't completely fit on-screen rather than just unmapping
+ them.
+
+ * glyphs.h: change signature of map_subwindow.
+
+ * glyphs.c (map_subwindow): add display_glyph_area to the
+ signature. make sure the mapped area saved in the subwindow_cachel
+ reflects this.
+ (Fforce_subwindow_map): make a no-op. I don't think this does
+ anything useful.
+
+ * glyphs-x.h (struct x_subwindow_data): save the Display rather
+ than the Screen. Add a clipwindow and clipwidget handle.
+ (IMAGE_INSTANCE_X_CLIPWINDOW): new accessor.
+ (IMAGE_INSTANCE_X_CLIPWIDGET): ditto.
+ (XIMAGE_INSTANCE_X_CLIPWIDGET): ditto.
+ (XIMAGE_INSTANCE_X_CLIPWINDOW): ditto.
+
+ * glyphs-x.c (x_finalize_image_instance): destroy the clipwidget
+ as well as the widget itself.
+ (x_unmap_subwindow): unmap the clipwindow and clipwidget rather
+ than the widgets and subwindows themselves. move the widget inside
+ the clipwidget.
+ (x_subwindow_instantiate): hold onto the Display rather than the
+ Screen. allocate a clipwindow to put the subwindow inside.
+ (x_resize_subwindow): use saved Display directly.
+ (x_widget_instantiate): allocate a clipwidget of type EmacsManager
+ to put widgets inside.
+
+ * glyphs-widget.c: remove group stuff.
+
+ * glyphs-msw.h (struct mswindows_subwindow_data): new structure to
+ hold the clipwindow.
+ (IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW): new accessor.
+ (XIMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW): ditto.
+
+ * glyphs-msw.c: remove group stuff.
+ (mswindows_finalize_image_instance): destroy clipwindow as well as
+ the widget itself.
+ (mswindows_unmap_subwindow): unmap the clipwindow rather than the
+ widget.
+ (mswindows_map_subwindow): ditto. move the widget within the
+ clipwindow.
+ (mswindows_subwindow_instantiate): allocate and initialize
+ mswindows_subwindow_data. allocate a clipwindow with the subwindow
+ as a child.
+ (mswindows_widget_instantiate): ditto.
+ (mswindows_control_wnd_proc): new function that allows us to
+ propagate events from the widget to the main windows control loop.
+
+ * device-msw.c (mswindows_init_device): register new widget clip window
+ class.
+
+ * console.h (struct console_methods): add display_glyph_area to
+ map_window.
+
+ * console-msw.h: declare new window class and wnd proc for
+ widgets.
+
+1999-09-14 Martin Buchholz <martin@xemacs.org>
+
+ * general.c:
+ * eldap.c:
+ Move symbols used only by eldap.c into eldap.c as statics.
+
+1999-09-09 Martin Buchholz <martin@xemacs.org>
+
+ * window.c (syms_of_window):
+ * symbols.c (syms_of_symbols):
+ * redisplay.c (syms_of_redisplay):
+ * print.c (syms_of_print):
+ * lisp.h:
+ * intl.c (syms_of_intl):
+ * general.c (syms_of_general):
+ * frame.c (syms_of_frame):
+ * fileio.c (syms_of_fileio):
+ * file-coding.h:
+ * file-coding.c (syms_of_file_coding):
+ * extents.c (syms_of_extents):
+ * event-stream.c (syms_of_event_stream):
+ * event-stream.c (Fnext_event):
+ * device.c (syms_of_device):
+ * data.c (syms_of_data):
+ * casetab.c (syms_of_casetab):
+ * casetab.c (check_case_table):
+ * callint.c (syms_of_callint):
+ * buffer.c (syms_of_buffer):
+ Delete unused C symbols:
+ Qbuffer_file_name, Qbuffer_undo_list, Quser_variable_p,
+ Qcurrent_prefix_arg, Qtranslate_table, Qkeywordp,
+ Qnumber_or_marker_p, Qcons, Qkeyword, Qignore, Qdelete_device,
+ Qcommand_execute, Qglyph_invisible,
+ Qbuffer_file_coding_system, Qfile_name_handler_alist,
+ Qframe_x_p, Qframe_tty_p, Qblack, Qkeyboard, Qmenubar, Qpath,
+ Qvector, Qwhite, Qcase, Qdomain, Qalternate_debugging_output,
+ Qprint_escape_newlines, Qprint_readably, Qfloat_output_format,
+ Qwindow_scroll_functions, Qfboundp, Qscroll_up, Qscroll_down
+
+ Rename symbols as required by the CHECK_RECORD macro:
+ - Qcase_table_p to Qcase_tablep
+ - Qcoding_system_p to Qcoding_systemp
+
+ * debug.h:
+ * debug.c (syms_of_debug):
+ Make debug.c's internal Lisp_Objects static.
+
+ * events.c (vars_of_events):
+ * events.c (syms_of_events):
+ Use regular old defsymbol instead of KEYSYM + staticpro().
+
+ * select-x.c (CHECK_CUTBUFFER):
+ Rewrite in accordance with coding standards.
+
+ * keymap.c (syms_of_keymap):
+ Use SPC in the same way as RET, TAB, etc.
+
+1999-08-27 Jan Vroonhof <vroonhof@math.ethz.ch>
+
+ * xemacs-20/src/menubar-x.c (make_dummy_xbutton_event): Don't add
+ offset twice if HAVE_WMCOMMAND is defined.
+
+1999-09-13 Mike McEwan <mike@lotusland.demon.co.uk>
+
+ * redisplay-x.c (x_output_vertical_divider): make sure
+ shadow_thickness is positive.
+
+1999-09-10 Julian Back <jback@rudd.compulink.co.uk>
+
+ * process-nt.c (nt_create_process): fixup to cope with
+ Vprocess_environment.
+
+1999-09-02 Andy Piper <andy@xemacs.org>
+
+ * redisplay-output.c (redisplay_output_layout): call output
+ routines with clear_clip false. output layout borders with text
+ correctly.
+
+ * redisplay-msw.c (mswindows_output_blank): call output routines
+ with clear_clip true.
+ (mswindows_output_string): ditto.
+ (mswindows_output_display_block): ditto.
+
+ * redisplay-x.c (x_output_display_block): call output routines
+ with clear_clip true.
+
+ * redisplay.h: fix output routines for clear_clip parameter.
+
+ * redisplay-output.c (redisplay_output_layout): cope with glyphs
+ in the border.
+
+ * glyphs-widget.c (layout_instantiate): deal with border glyphs.
+ (check_valid_glyph_or_instantiator): renamed from
+ check_valid_glyph_or_image.
+ (check_valid_border): allow glyphs or their instantiators.
+ (check_valid_glyph_or_instantiator_list): renamed from
+ check_valid_glyph_or_image_list,
+ (glyph_instantiator_to_glyph): new function. make sure a glyph is
+ a glyph and not an instantiator.
+ (substitute_keyword_value): new function. replace a keyword value
+ with a new one.
+
+1999-09-01 Andy Piper <andy@xemacs.org>
+
+ * glyphs.c (string_set_property): new function to set the data of
+ a string.
+ (image_instantiator_format_create): use it.
+
+1999-09-07 Hrvoje Niksic <hniksic@srce.hr>
+
+ * fns.c (Fmapc): Rename back to Fmapc_internal.
+
+1999-07-30 Gleb Arshinov <gleb@cs.stanford.edu>
+
+ * ntheap.h: CONST (semantically constant) name field of file_data
+ struct
+
+ * unexnt.c (open_output_file): match function definition with
+ function declaration
+
+ * editfns.c: #include "sysfile.h" for getcwd() prototype
+
+ * gif_io.c: #include "sysfile.h" for close() prototype
+
+1999-09-02 Martin Buchholz <martin@xemacs.org>
+
+ * elhash.c:
+ * elhash.h:
+ Change the :type keyword to :weakness, for compatibility with the
+ GNU Emacs 20.5 hash table implementation.
+ Keep (but don't document) the :type keyword for compatibility.
+ Obsolete function hash-table-type
+ General cleanup.
+ Define function sxhash for compatibility with Common Lisp and GNU Emacs.
+
+1999-09-01 Martin Buchholz <martin@xemacs.org>
+
+ * floatfns.c (arith_error):
+ * floatfns.c (range_error):
+ * floatfns.c (range_error2):
+ * floatfns.c (domain_error):
+ * floatfns.c (domain_error2):
+ * lrecord.h (LRECORDP):
+ * console-x.h (X_ERROR_OCCURRED):
+ * console-x.h (HANDLING_X_ERROR):
+ * chartab.c (CATEGORYP):
+ * buffer.h (XCHAR_OR_CHAR_INT):
+ Remove redundant and confusing parentheses.
+
+ * redisplay-output.c (redisplay_clear_to_window_end):
+ Remove redundant initialization.
+
+ * redisplay.h:
+ * redisplay-msw.c:
+ * redisplay-x.c:
+ Move declarations of bevel_modeline() into redisplay.h.
+
+1999-08-30 Olivier Galibert <galibert@pobox.com>
+
+ * lisp.h: Add staticpro_nodump for undumped staticpro-ing.
+ * alloc.c: Add staticpro_nodump for undumped staticpro-ing. Add
+ alignment information for dumped data. Enhance
+ descriptions. Phase out Vterminal_* variables while
+ dumping.
+ * lrecord.h: Add chained descriptions and automagically-reset
+ lisp_objects to the description system.
+
+ * console-stream.h: Declare the Vterminal_* variables.
+
+ * buffer.c: Don't dump Vbuffer_alist, Vbuffer_defaults and
+ Vbuffer_local_symbols.
+ * console.c: Don't dump Vconsole_list, Vconsole_defaults and
+ Vconsole_local_symbols.
+ * eval.c: Don't dump Qunbound_suspended_errors_tag.
+ * lread.c: Don't dump Vread_buffer_stream.
+ * lstream.c: Don't dump Vlstream_free_list[].
+ * search.c: Don't dump last_thing_searched.
+ * window.c: Don't dump minibuf_window and
+ Vwindow_configuration_free_list[].
+
+ * faces.c: Add face description.
+ * fns.c: Add bit_vector description.
+ * glyphs.c: Add image specifier description.
+ * objects.c: Add color, face and face boolean specifiers descriptions.
+ * opaque.c: Add opaque description. Don't dump Vopaque_ptr_free_list.
+ * rangetab.c: Add range table description.
+ * specifier.c: Add specifier and specifier methods description.
+ * specifier.h: Add specifier extra description support.
+
+ * symbols.c: Fix symbol_value_buffer_local_description.
+
+ * gdbinit (Lisp): Add opaque_ptr, remove opaque_list.
+
+1999-09-02 Hrvoje Niksic <hniksic@srce.hr>
+
+ * extents.c (extent_remprop): Get extent's plist address
+ correctly.
+
+1999-08-31 Andy Piper <andy@xemacs.org>
+
+ * xmu.h: define Xmu/Converters.h things.
+
+1999-08-31 Andy Piper <andy@xemacs.org>
+
+ * opaque.c (equal_opaque_ptr): define.
+ (hash_opaque_ptr): define.
+
+ * xmu.h: define Xmu/Misc.h things.
+
1999-08-17 MORIOKA Tomohiko <tomo@etl.go.jp>
* file-coding.c (determine_real_coding_system): Treat `coding:'
(decode_coding_ucs4): Use `counter'.
(decode_coding_utf8): Likewise.
+1999-08-31 Andy Piper <andy@xemacs.org>
+
+ * redisplay-output.c (redisplay_normalize_glyph_area): make sure
+ the clip offset doesn't exceed the height we have available to
+ show.
+
+ * window.h (struct window): add top_yoffset and left_xoffset for
+ pixel scrolling.
+ (WINDOW_TEXT_TOP_CLIP): new macro.
+
+ * window.c (window_scroll): add behaviour for pixel-scrolling of
+ tall lines.
+
+ * redisplay.h (struct display_line): add top_clip.
+ (DISPLAY_LINE_HEIGHT): adjust for top_clip.
+ (DISPLAY_LINE_YPOS): ditto.
+
+ * redisplay.c (position_redisplay_data_type): add
+ start_col_xoffset to prepare for pixel-based h-scrolling.
+ (WINDOW_SCROLLED): new macro.
+ (next_tab_position): use it.
+ (add_glyph_rune): use new hscoll vars.
+ (create_text_block): ditto.
+ (generate_displayable_area): adjust off-by-one error.
+ (regenerate_window): take top_clip into account.
+ (regenerate_window_extents_only_changed): ditto.
+ (regenerate_window_incrementally): ditto.
+
+ * redisplay-x.c (x_output_display_block): use DISPLAY_LINE_YPOS,
+ DISPLAY_LINE_HEIGHT and DISPLAY_LINE_YEND macros.
+ (x_output_string): ditto.
+ (x_output_blank): ditto.
+ (x_output_hline): ditto.
+ (x_output_eol_cursor): ditto.
+
+ * redisplay-output.c (output_display_line): allow for
+ top_clip. use DISPLAY_LINE_YPOS, DISPLAY_LINE_HEIGHT and
+ DISPLAY_LINE_YEND macros.
+ (redisplay_output_layout): output strings in layouts correctly.
+ (redisplay_clear_clipped_region): allow for top_clip.
+ (redisplay_calculate_display_boxes): ditto.
+
+ * redisplay-msw.c (mswindows_output_blank): use DISPLAY_LINE_YPOS,
+ DISPLAY_LINE_HEIGHT and DISPLAY_LINE_YEND macros.
+ (mswindows_output_cursor): ditto.
+ (mswindows_output_string): ditto.
+ (mswindows_redraw_exposed_window): ditto.
+ (mswindows_output_display_block): ditto.
+
+ * gutter.c: new specifier type gutter-size.
+ (gutter_size_validate): validate gutter-size specifier.
+ (Fgutter_size_specifier_p): predicate for gutter-size.
+ (Fredisplay_gutter_area): allow the gutter area to be redisplayed
+ under user contol, like Fredisplay_echo_area.
+ (syms_of_gutter): add new functions.
+ (specifier_type_create_gutter): add new specifier.
+ (specifier_vars_of_gutter): change specifier types of *-height to
+ gutter-size.
+
+ * glyphs.c (glyph_width): make work with image instances.
+
+ * console.h (struct console_methods): change api of output_string.
+
+ * glyphs-x.c (x_map_subwindow): move before mapping as reported by
+ Stephen J. Turnbull <turnbull@sk.tsukuba.ac.jp>
+
+1999-08-30 Andy Piper <andy@xemacs.org>
+
+ * glyphs-x.c (x_finalize_image_instance): X_MASK -> PIXMAP_MASK
+ for assignment.
+ (init_image_instance_from_x_image): ditto.
+ (x_xpm_instantiate): ditto.
+ (x_colorize_image_instance): ditto. Reported by Richard Cognot
+ <cognot@ensg.u-nancy.fr>
+
+1999-08-29 Andy Piper <andy@xemacs.org>
+
+ * glyphs-x.c (x_widget_instantiate): move font initialisation so
+ that it doesn't get saved in the user defined args.
+ (x_tab_control_instantiate): Set the fg color of the tab's
+ children.
+ (x_tab_control_set_property): ditto.
+
+1999-08-27 Damon Lipparelli <lipp@primus.com>
+
+ * events.h (XTIMEOUT): must preface Lisp_Timeout with ``struct''
+ (XSETTIMEOUT): fixup typo
+
+1999-08-11 Jan Vroonhof <vroonhof@math.ethz.ch>
+
+ * syntax.c (scan_words): Unified Mule and Non-mule scanning.
+ Word boundary search looks back instead of forward so that it
+ doesn't peek over the limit.
+
+1999-08-20 Olivier Galibert <galibert@pobox.com>
+
+ * config.h.in: Add PDUMP define.
+ * emacs.c (Fdump_emacs): Hackish, call pdump() if configured in.
+
+ * lrecord.h: Enhance description system.
+ * alloc.c: Fix vector and string description. Add portable
+ dumper enumeration fonctions.
+
+ * symbols.c: Fix symbols description. Add symbol_value_forward
+ description.
+ * eval.c: Add subr description.
+ * elhash.c (CLEAR_HENTRY): Clean value pointer too. Fix hash
+ table description.
+ (remhash_1): CLEAR_HENTRY evaluates the parameter two times now.
+
+1999-08-20 Olivier Galibert <galibert@pobox.com>
+
+ * opaque.c: Kill opaque lists, make Lisp_Opaque_Ptr a lrecord of
+ its own.
+ * opaque.h: Ditto.
+
+ * eval.c (eval_in_buffer_trapping_errors):
+ (run_hook_trapping_errors):
+ (safe_run_hook_trapping_errors):
+ (call0_trapping_errors):
+ (call1_trapping_errors):
+ (call2_trapping_errors): OPAQUEP -> OPAQUE_PTRP. make_opaque_ptr
+ now takes a non-const void *.
+
+1999-08-20 Olivier Galibert <galibert@pobox.com>
+
+ * opaque.c: Remove make_opaque_long.
+
+ * opaque.h: Remove everything opaque_long related.
+
+ * eval.c (vars_of_eval): Make Qunbound_suspended_errors_tag an
+ opaque_ptr.
+
+ * emacs.c (main_1): Remove make_opaque_long from comment.
+
+1999-08-20 Olivier Galibert <galibert@pobox.com>
+
+ * event-stream.c (mark_timeout):
+ (print_timeout):
+ (event_stream_generate_wakeup):
+ (event_stream_resignal_wakeup):
+ (event_stream_disable_wakeup):
+ (event_stream_wakeup_pending_p):
+ (vars_of_event_stream): Lisp_Timeout is now a lrecord.
+
+ * events.h (struct Lisp_Timeout): Added.
+
+1999-08-24 Andy Piper <andy@xemacs.org>
+
+ * console-x.h: declare new pixmap signatures.
+
+1999-08-23 Andy Piper <andy@xemacs.org>
+
+ * glyphs-x.c (x_update_subwindow): make sure the widget size is
+ maintained after an update.
+
+ * event-Xt.c (emacs_Xt_handle_magic_event): use
+ find_matching_subwindow to check whether the exposure is totally
+ inside a subwindow, if it is then ignore it.
+
+ * glyphs.c (find_matching_subwindow): new function.
+
+ * toolbar-x.c (x_draw_blank_toolbar_button): use new
+ x_output_shadows signature.
+ (x_output_toolbar_button): use new x_output_x_pixmap signature.
+
+ * redisplay.h (struct display_box): new structure.
+ (struct display_glyph_area): ditto.
+ declare new display_box functions.
+
+ * redisplay-x.c (x_output_pixmap): update for new display
+ box stuff.
+ (x_bevel_area): update to allow multiple edge styles and border
+ segments.
+ (x_output_display_block): update for new display_box stuff and
+ signatures.
+ (x_clear_region): ditto.
+ (x_output_x_pixmap): ditto. adjust offsets rather than clip.
+ (console_type_create_redisplay_x): declare new console methods.
+ (x_output_vertical_divider): update for new bevel_area signature.
+ (x_output_shadows): update to allow selective drawing of edges.
+
+ * redisplay-tty.c (tty_output_display_block): do nothing for
+ layouts.
+
+ * redisplay-output.c (redisplay_output_subwindow): convert to use
+ display_box structure, this allows us to put subwindows anywhere
+ with any offset, useful for layout glyphs.
+ (redisplay_output_layout): new function. output a layout and its
+ sub-glyphs.
+ (redisplay_output_pixmap): new modular function combining generic
+ parts of the X and mswindows versions. convert to use display_box
+ structures.
+ (redisplay_clear_clipped_region): new function. clear the area a
+ glyph is going into.
+ (redisplay_normalize_glyph_area): new function. calculate the
+ bounds of a display_glyph_area given a display_box.
+ (redisplay_normalize_display_box): new function. shrink a
+ display_box to enclose a display_glyph_area.
+ (redisplay_display_boxes_in_window_p): check whether the input
+ display_box and display_glyph_area are actually in a window.
+ (redisplay_calculate_display_boxes): calculate display boxes based
+ on conventional display_line metrics.
+ (bevel_modeline): update for new bevel_area signature.
+
+ * redisplay-msw.c (mswindows_output_blank): update for new
+ display_box stuff.
+ (mswindows_output_string): ditto.
+ (mswindows_output_dibitmap): ditto.
+ (mswindows_output_dibitmap_region): ditto.
+ (mswindows_output_pixmap): ditto.
+ (mswindows_bevel_area): update to allow multiple edge styles and
+ border segments.
+ (mswindows_output_display_block): update for new display_box stuff
+ and signatures.
+ (mswindows_clear_region): ditto.
+ (console_type_create_redisplay_mswindows): declare new console methods.
+
+ * lisp.h (edge_style): new enum.
+ declare display_box and display_glyph_area.
+
+ * gutter.c (output_gutter): update for new bevel_area signature.
+
+ * glyphs.h (image_instance_type): add layout.
+ (IMAGE_LAYOUT_MASK): ditto.
+ (LAYOUT_IMAGE_INSTANCEP): new macro.
+ (CHECK_LAYOUT_IMAGE_INSTANCE): ditto.
+ (struct Lisp_Image_Instance): add offsets for layout and the
+ layout type itself. move mask here also.
+ (IMAGE_INSTANCE_LAYOUT_CHILDREN): new macro.
+ (IMAGE_INSTANCE_LAYOUT_BORDER): ditto.
+ (XIMAGE_INSTANCE_LAYOUT_CHILDREN): ditto.
+ (XIMAGE_INSTANCE_LAYOUT_BORDER): ditto.
+
+ * glyphs.c (mark_image_instance): update for layouts.
+ (print_image_instance): ditto.
+ (image_instance_equal): ditto.
+ (image_instance_hash): ditto.
+ (allocate_image_instance): initialise offsets for layout.
+ (decode_image_instance_type): update for layouts.
+ (encode_image_instance_type): ditto.
+ (Fimage_instance_height): ditto.
+ (Fimage_instance_width): ditto.
+ (allocate_glyph): ditto.
+ (glyph_width): allow image instances as an argument. update for layouts.
+ (glyph_height_internal): ditto.
+ (syms_of_glyphs): add layout symbols.
+
+ * glyphs-x.h (struct x_image_instance_data): remove mask entry.
+ (IMAGE_INSTANCE_X_MASK): update.
+
+ * glyphs-x.c (x_label_instantiate): new function. instantiate a
+ label.
+ (image_instantiator_format_create_glyphs_x): initialise new layout
+ glyph type.
+
+ * glyphs-widget.c: new layout type.
+ (check_valid_orientation): new keyword checker for layouts.
+ (check_valid_justification): ditto.
+ (check_valid_border): ditto.
+ (check_valid_glyph_or_image_list): ditto.
+ (layout_possible_dest_types): new function for layout glyph type.
+ (layout_normalize): ditto.
+ (layout_instantiate): ditto.
+ (syms_of_glyphs_widget): new keywords for layout.
+ (image_instantiator_format_create_glyphs_widget): initialise the
+ layout glyph type.
+
+ * glyphs-msw.h (struct mswindows_image_instance_data): remove mask
+ argument.
+ (IMAGE_INSTANCE_MSWINDOWS_MASK): update.
+
+ * glyphs-msw.c: declare layout format.
+ (image_instantiator_format_create_glyphs_mswindows): initialise it.
+
+ * general.c: new symbols for layouts.
+
+ * console.h (struct console_methods): new console methods for
+ outputting pixmaps and strings.
+
+1999-08-23 Didier Verna <verna@inf.enst.fr>
+
+ * sound.c: revert the renaming of `bell_volume' to `Vbell_volume'
+ and `bell_inhibit_time' to `Vbell_inhibit_time'.
+
+1999-08-18 Andy Piper <andy@xemacs.org>
+
+ * redisplay-output.c (redisplay_output_subwindow): disable
+ clipping attempt.
+
+1999-08-17 Andy Piper <andy@xemacs.org>
+
+ * gutter.c (redraw_exposed_gutter): handle degenerate case of no
+ area to expose or no gutter to display.
+
+1999-08-16 Charles G Waldman <cgw@fnal.gov>
+
+ * sound.c: rename `bell_volume' to `Vbell_volume' and
+ `bell_inhibit_time' to `Vbell_inhibit_time'.
+
+1999-08-13 Charles G Waldman <cgw@fnal.gov>
+
+ * sound.c: (bell-inhibit-time): New variable.
+ (ding): Use it.
+ (sound-alist): Fix docstring.
+
+1999-08-17 Andy Piper <andy@xemacs.org>
+
+ * gui-x.c (button_item_to_widget_value): xstrdup name so that
+ deleting it is ok.
+
+1999-08-16 Jeff Miller <jmiller@smart.net>
+
+ * syntax.c (scan_words): make compile.
+
+1999-08-16 Andy Piper <andy@xemacs.org>
+
+ * redisplay-output.c (redisplay_output_subwindow): try and be more
+ relaxed about clipping possibilities.
+
+ * glyphs-x.c (x_tab_control_set_property): free_widget_value_tree
+ rather than just the widget_value.
+ (x_update_subwindow): ditto.
+ (x_widget_instantiate): ditto.
+
+ * gutter.c (output_gutter): shrink current display lines if
+ required.
+
+1999-08-15 Andy Piper <andy@xemacs.org>
+
+ * redisplay.h: declare free_display_lines.
+
+ * redisplay.c (free_display_lines): make non-static.
+
+ * gutter.c (free_frame_gutters): use free_display_lines instead of
+ Dynarr_free.
+ (calculate_gutter_size): ditto.
+
+1999-08-12 Jan Vroonhof <vroonhof@math.ethz.ch>
+
+ * eval.c (run_hook_with_args_in_buffer): GCPRO globals.
+
+1999-08-14 Andy Piper <andy@xemacs.org>
+
+ * glyphs.c (update_subwindow_cachel): make it less brittle.
+
+1999-08-04 Mike Woolley <mike@bulsara.com>
+
+ * scrollbar-msw.c (mswindows_handle_mousewheel_event): Fixed
+ problem in wheelmouse code occurring when the horizontal scrollbar
+ is enabled but not visible.
+
+1999-08-08 Andy Piper <andyp@beasys.com>
+
+ * toolbar-msw.c (mswindows_redraw_frame_toolbars): new function.
+ (console_type_create_toolbar_mswindows): use it.
+
+ * glyphs.c (Fset_image_instance_property): fiddly reorganisation.
+
+ * redisplay-output.c (redisplay_output_display_block): unmap
+ subwindows in the block area before outputting the block.
+
+ * event-msw.c (mswindows_wnd_proc): check the update rect before
+ painting and disable expose registration while painting.
+
+ * glyphs.c (register_ignored_expose): check
+ hold_ignored_expose_registration before registering expose events.
+
+ * redisplay.c (redisplay_frame): reset the subwindow cache before
+ displaying the gutter.
+
+ * glyphs-msw.c (mswindows_map_subwindow): move the window before
+ mapping.
+
+ * gutter.c (update_frame_gutters): check for glyphs_changed as if
+ it is the subwindow cache will have been reset.
+
+1999-08-06 Andy Piper <andyp@beasys.com>
+
+ * gui-x.c (button_item_to_widget_value): cope with strings.
+
+ * glyphs.h: declare global widget functions.
+ (IIFORMAT_HAS_SHARED_DEVMETHOD): new macro.
+
+ * glyphs-x.c (x_combo_box_instantiate): do generic initialization
+ here. remove dead code.
+ (image_instantiator_format_create_glyphs_x): enable combo boxes
+ for Motif 2.0.
+
+ * glyphs-widget.c (widget_instantiate_1): make non-static.
+ (tree_view_instantiate): renamed from combo_box_instantiate.
+ (image_instantiator_format_create_glyphs_widget): use new/changed methods.
+
+ * glyphs-msw.c (mswindows_combo_box_instantiate): do generic
+ initialization here.
+
+ * lwlib-Xm.c (xm_update_combo_box): new function.
+ (xm_update_one_widget): call it.
+ (xm_update_one_value): deal with combo boxes as well as lists.
+ (xm_create_combo_box): create a drop-down combo box.
+
+ * toolbar-msw.c (mswindows_output_toolbar): call
+ mswindows_move_toolbar.
+
+1999-08-05 Andy Piper <andyp@beasys.com>
+
+ * window.c (Fcurrent_pixel_column): new function. use display
+ lines to calculate pixel position of point.
+ * window.c (syms_of_window): declare it.
+
+1999-08-05 Andy Piper <andy@xemacs.org>
+
+ * glyphs.c (check_for_ignored_expose): ignore exposures wholly
+ contained in our ignore list.
+
+ * buffer.c (Frecord_buffer): add call to record-buffer-hook.
+ (syms_of_buffer): declare record-buffer-hook.
+
+ * s/mingw32.h: define mousewheel things.
+
+1999-08-04 Mike Woolley <mike@bulsara.com>
+
+ * windowsnt.h (_WIN32_WINNT): enable for win95
+
+ * s/cygwin32.h: define mousewheel things.
+
+ * scrollbar-msw.h: declare mousewheel handler.
+
+ * scrollbar-msw.c (mswindows_handle_mousewheel_event): new function.
+
+1999-08-04 Andy Piper <andy@xemacs.org>
+
+ * gui-x.c (gui_items_to_widget_values): remove unused variable.
+ (gui_items_to_widget_values_1): ditto.
+
+ * gui-x.h: unconditionally define since it is used everywhere.
+
+1999-08-04 Andy Piper <andy@xemacs.org>
+
+ * glyphs-x.c (x_finalize_image_instance): only free pixels if we
+ have that type of image.
+
+1999-07-30 Andy Piper <andy@xemacs.org>
+
+ * redisplay-output.c (redisplay_unmap_subwindows): add comparison
+ subwindow to not unmap if required.
+ (redisplay_unmap_subwindows_maybe): comparison is Qnil.
+ (redisplay_unmap_subwindows_except_us): new function.
+ (redisplay_output_subwindow): use it to unmap windows in the area
+ we are displaying into.
+
+ * glyphs.c (update_subwindow_cachel_data): always update as we
+ only ever get called when an update is required.
+ (update_subwindow_cachel): new function. sync a subwindow with its
+ cachel.
+ (Fresize_subwindow): use it.
+ (register_ignored_expose): make sure we set the tail correctly.
+
+1999-07-28 Andy Piper <andy@xemacs.org>
+
+ * redisplay-output.c (redisplay_clear_bottom_of_window): remove
+ unneeded device.
+
+ * gutter.c (redraw_exposed_gutter): unmap subwindows from the
+ whole gutter.
+
+ * gui.h: declare parse_gui_item_tree_list and
+ parse_gui_item_tree_children.
+
+ * gui.c (parse_gui_item_tree_item): new function for parsing item
+ lists into gui-item trees.
+ (parse_gui_item_tree_children): ditto.
+ (parse_gui_item_tree_list): ditto.
+
+ * gui-x.h: declare gui_items_to_widget_values.
+
+ * gui-x.c (gui_items_to_widget_values_1): new function for
+ recursively parsing gui-items into widget_values.
+ (gui_item_children_to_widget_values): ditto.
+ (gui_items_to_widget_values): ditto.
+ (sanity_check_lwlib): add widgets macrolets.
+
+ * glyphs.h (IMAGE_INSTANCE_WIDGET_ITEMS): rename from *ITEM.
+ (XIMAGE_INSTANCE_WIDGET_ITEMS): ditto.
+ (IMAGE_INSTANCE_WIDGET_ITEM): rename from *SINGLE_ITEM.
+ (XIMAGE_INSTANCE_WIDGET_ITEM): ditto.
+ (struct expose_ignore): new structure for storing ignorable expose
+ events.
+
+ * glyphs.c (valid_image_instantiator_format_p): fix so that using
+ a console-type as a locale works.
+ (mark_image_instance): ITEM->ITEMS.
+ (image_instance_equal): ditto.
+ (image_instance_hash): ditto.
+ (struct expose_ignore_blocktype): new blocktype.
+ (check_for_ignored_expose): new function. checks frame exposure
+ list for events to ignore.
+ (register_ignored_expose): new function. registers an expose event
+ as ignorable.
+ (unmap_subwindow): register the expose event as ignorable.
+ (vars_of_glyphs): initialise the exposure blocktype.
+
+ * glyphs-x.c (x_finalize_image_instance): use lw_destroy_widget.
+ (x_update_subwindow): modify all widgets using widget_value tree
+ rather than just a single widget value.
+ (x_widget_instantiate): LWLIB_USES_MOTIF -> LWLIB_WIDGETS_MOTIF.
+ make sure widgets don't resize themselves.
+ (x_tab_control_instantiate): new function. use lwlib tab functions.
+ (x_tab_control_set_property): new function.
+ (image_instantiator_format_create_glyphs_x): add tab_control.
+
+ * glyphs-widget.c (widget_text_to_pixel_conversion): calculate
+ slightly more sensibly.
+ (initialize_widget_image_instance): ITEM->ITEMS.
+ (widget_instantiate_1): parse gui items generically into the ITEMS
+ entry.
+
+ * glyphs-msw.c (mswindows_update_subwindow): replace
+ SINGLE_ITEM->ITEM.
+ (mswindows_register_widget_instance): ditto.
+ (add_tree_item): modify to use new pre-initialised gui-item
+ structure.
+ (add_tab_item): ditto.
+ (mswindows_tab_control_instantiate): ditto.
+ (mswindows_tab_control_set_property): ditto.
+ (image_instantiator_format_create_glyphs_mswindows): predicate
+ existance of widgets on HAVE_WIDGETS.
+
+ * frame.h (struct frame): add subwindow_exposures variables.
+
+ * frame.c (allocate_frame_core): reset subwindow_exposures links.
+
+ * event-msw.c (mswindows_wnd_proc): check for ignored
+ expose events before redrawing.
+
+ * event-Xt.c (emacs_Xt_handle_magic_event): check for ignored
+ expose events before redrawing.
+
+1999-07-30 SL Baur <steve@xemacs.org>
+
+ * scrollbar-x.c: should include EmacsFrame.h.
+ From Jeff Miller <jmiller@smart.net>
+
1999-07-30 XEmacs Build Bot <builds@cvs.xemacs.org>
* XEmacs 21.2.19 is released
1999-07-27 Jeff Miller <jmiller@smart.net>
- * add a "#ifdef HAVE_MENUBARS" wrapper to gui.c around
+ * add a "#ifdef HAVE_MENUBARS" wrapper to gui.c around
menubar_show_keybindings.
1999-07-23 SL Baur <steve@miho>
* event-Xt.c (handle_focus_event_1): Re-enable Motif/XIM to get
focus the event (XIM_focus_event).
- (emacs_Xt_handle_magic_event): No side effect on Motif/XIM because
+ (emacs_Xt_handle_magic_event): No side effect on Motif/XIM because
XIM_SetGeometry does nothing in input_method_motif.c, but re-unify
the interface for future use (XIM_SetGeometry).
- * redisplay-x.c (x_output_string): Re-enable Motif/XIM to set spot
+ * redisplay-x.c (x_output_string): Re-enable Motif/XIM to set spot
location (XIM_SetSpotLocation).
(x_output_eol_cursor): Ditto.
* redisplay-x.c (redisplay_clear_to_window_end): moved to
redisplay.c
-
+
* redisplay-msw.c (redisplay_clear_to_window_end): deleted.
* gutter.c: new file - implements gutters. All new functions are
1999-07-03 Gunnar Evermann <ge204@eng.cam.ac.uk>
- * tooltalk.c (init_tooltalk): save signal actions for SIGQUIT,
- SIGINT and SIGCHLD before calling tt_open and restore the
- afterwards. This fixes e.g. the zombie subprocesses on Solaris
+ * tooltalk.c (init_tooltalk): save signal actions for SIGQUIT,
+ SIGINT and SIGCHLD before calling tt_open and restore the
+ afterwards. This fixes e.g. the zombie subprocesses on Solaris
1999-07-06 SL Baur <steve@xemacs.org>
1998-12-11 Martin Buchholz <martin@xemacs.org>
- * event-msw.c (mswindows_cancel_dispatch_event):
- Gratuitous code prettification
+ * event-msw.c (mswindows_cancel_dispatch_event):
+ Gratuitous code prettification
1998-12-07 Hrvoje Niksic <hniksic@srce.hr>
1998-08-07 Matt Stupple <matts@tibco.com>
- * ntproc.c: don't wait on char_consumed at thread entry.
+ * ntproc.c: don't wait on char_consumed at thread entry.
Additionally, to get the 'process' marked as finished, ensure
that the CHILD_ACTIVE macro returns false, so before exiting
close char_avail and set it to NULL, and close other handles
1998-05-14 Damon Lipparelli <lipp@primus.com>
- * winslots.h: close comment
+ * winslots.h: close comment
1998-05-16 Kirill M. Katsnelson <kkm@kis.ru>
Added lcrecord lists for 19.14.
slb: Lots of work on the purification and dump time code.
Synched Doug Lea malloc support from Emacs 20.2.
- og: Killed the purespace.
+ og: Killed the purespace. Portable dumper.
*/
#include <config.h>
#include "specifier.h"
#include "sysfile.h"
#include "window.h"
+#include "console-stream.h"
#ifdef DOUG_LEA_MALLOC
#include <malloc.h>
#endif
+#ifdef HAVE_MMAP
+#include <unistd.h>
+#include <sys/mman.h>
+#endif
+
+#ifdef PDUMP
+typedef struct
+{
+ const struct lrecord_description *desc;
+ int count;
+} pdump_reloc_table;
+
+static char *pdump_rt_list = 0;
+#endif
+
EXFUN (Fgarbage_collect, 0);
/* Return the true size of a struct with a variable-length array field. */
int
c_readonly (Lisp_Object obj)
{
- return POINTER_TYPE_P (XGCTYPE (obj)) && C_READONLY (obj);
+ return POINTER_TYPE_P (XTYPE (obj)) && C_READONLY (obj);
}
int
lisp_readonly (Lisp_Object obj)
{
- return POINTER_TYPE_P (XGCTYPE (obj)) && LISP_READONLY (obj);
+ return POINTER_TYPE_P (XTYPE (obj)) && LISP_READONLY (obj);
}
\f
void *val = xmalloc (len);
if (val == 0) return 0;
- memcpy (val, str, len);
- return (char *) val;
+ return (char *) memcpy (val, str, len);
}
#ifdef NEED_STRDUP
static void *
allocate_lisp_storage (size_t size)
{
- void *p = xmalloc (size);
- return p;
+ return xmalloc (size);
}
}
}
-
-/* This must not be called -- it just serves as for EQ test
- * If lheader->implementation->finalizer is this_marks_a_marked_record,
- * then lrecord has been marked by the GC sweeper
- * header->implementation is put back to its correct value by
- * sweep_records */
-void
-this_marks_a_marked_record (void *dummy0, int dummy1)
-{
- abort ();
-}
-
/* Semi-kludge -- lrecord_symbol_value_forward objects get stuck
in CONST space and you get SEGV's if you attempt to mark them.
This sits in lheader->implementation->marker. */
Lisp_Object
-this_one_is_unmarkable (Lisp_Object obj, void (*markobj) (Lisp_Object))
+this_one_is_unmarkable (Lisp_Object obj)
{
abort ();
return Qnil;
}
-/* XGCTYPE for records */
-int
-gc_record_type_p (Lisp_Object frob, CONST struct lrecord_implementation *type)
-{
- CONST struct lrecord_implementation *imp;
-
- if (XGCTYPE (frob) != Lisp_Type_Record)
- return 0;
-
- imp = XRECORD_LHEADER_IMPLEMENTATION (frob);
- return imp == type;
-}
-
\f
/************************************************************************/
/* Debugger support */
#define MINIMUM_ALLOWED_FIXED_TYPE_CELLS_cons 2000
static Lisp_Object
-mark_cons (Lisp_Object obj, void (*markobj) (Lisp_Object))
+mark_cons (Lisp_Object obj)
{
- if (GC_NILP (XCDR (obj)))
+ if (NILP (XCDR (obj)))
return XCAR (obj);
- markobj (XCAR (obj));
+ mark_object (XCAR (obj));
return XCDR (obj);
}
{
Lisp_Object val = Qnil;
- int size = XINT (length);
+ size_t size = XINT (length);
- while (size-- > 0)
+ while (size--)
val = Fcons (init, val);
return val;
}
/************************************************************************/
static Lisp_Object
-mark_vector (Lisp_Object obj, void (*markobj) (Lisp_Object))
+mark_vector (Lisp_Object obj)
{
Lisp_Vector *ptr = XVECTOR (obj);
int len = vector_length (ptr);
int i;
for (i = 0; i < len - 1; i++)
- markobj (ptr->contents[i]);
+ mark_object (ptr->contents[i]);
return (len > 0) ? ptr->contents[len - 1] : Qnil;
}
static const struct lrecord_description vector_description[] = {
{ XD_LONG, offsetof(struct Lisp_Vector, size) },
- { XD_LISP_OBJECT, offsetof(struct Lisp_Vector, contents), XD_INDIRECT(0) }
+ { XD_LISP_OBJECT, offsetof(struct Lisp_Vector, contents), XD_INDIRECT(0, 0) },
+ { XD_END }
};
DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION("vector", vector,
f->constants = constants;
CHECK_NATNUM (stack_depth);
- f->stack_depth = XINT (stack_depth);
+ f->stack_depth = XINT (stack_depth);
#ifdef COMPILED_FUNCTION_ANNOTATION_HACK
if (!NILP (Vcurrent_compiled_function_annotation))
struct gcpro gcpro1;
GCPRO1 (fun); /* don't let fun get reaped */
Vload_file_name_internal_the_purecopy =
- Fpurecopy (Ffile_name_nondirectory (Vload_file_name_internal));
+ Ffile_name_nondirectory (Vload_file_name_internal);
f->annotated = Vload_file_name_internal_the_purecopy;
UNGCPRO;
}
#define MINIMUM_ALLOWED_FIXED_TYPE_CELLS_string 1000
static Lisp_Object
-mark_string (Lisp_Object obj, void (*markobj) (Lisp_Object))
+mark_string (Lisp_Object obj)
{
struct Lisp_String *ptr = XSTRING (obj);
- if (GC_CONSP (ptr->plist) && GC_EXTENT_INFOP (XCAR (ptr->plist)))
+ if (CONSP (ptr->plist) && EXTENT_INFOP (XCAR (ptr->plist)))
flush_cached_extent_info (XCAR (ptr->plist));
return ptr->plist;
}
}
static const struct lrecord_description string_description[] = {
- { XD_STRING_DATA, offsetof(Lisp_String, data) },
- { XD_LISP_OBJECT, offsetof(Lisp_String, plist), 1 },
+ { XD_BYTECOUNT, offsetof(Lisp_String, size) },
+ { XD_OPAQUE_DATA_PTR, offsetof(Lisp_String, data), XD_INDIRECT(0, 1) },
+ { XD_LISP_OBJECT, offsetof(Lisp_String, plist), 1 },
{ XD_END }
};
unsigned char string_chars[STRING_CHARS_BLOCK_SIZE];
};
-struct string_chars_block *first_string_chars_block;
-struct string_chars_block *current_string_chars_block;
+static struct string_chars_block *first_string_chars_block;
+static struct string_chars_block *current_string_chars_block;
/* If SIZE is the length of a string, this returns how many bytes
* the string occupies in string_chars_block->string_chars
memset (XSTRING_DATA (val), XCHAR (init), XSTRING_LENGTH (val));
else
{
- int i;
+ size_t i;
Bufbyte *ptr = XSTRING_DATA (val);
for (i = XINT (length); i; i--)
It works like this:
1) Create an lcrecord-list object using make_lcrecord_list().
- This is often done at initialization. Remember to staticpro
+ This is often done at initialization. Remember to staticpro_nodump
this object! The arguments to make_lcrecord_list() are the
same as would be passed to alloc_lcrecord().
2) Instead of calling alloc_lcrecord(), call allocate_managed_lcrecord()
*/
static Lisp_Object
-mark_lcrecord_list (Lisp_Object obj, void (*markobj) (Lisp_Object))
+mark_lcrecord_list (Lisp_Object obj)
{
struct lcrecord_list *list = XLCRECORD_LIST (obj);
Lisp_Object chain = list->free;
/* 415 used Mly 29-Jun-93 */
/* 1327 used slb 28-Feb-98 */
+/* 1328 used og 03-Oct-99 (moving slowly, heh?) */
#ifdef HAVE_SHLIB
#define NSTATICS 4000
#else
staticvec[staticidx++] = varaddress;
}
+/* Not "static" because of linker lossage on some systems */
+Lisp_Object *staticvec_nodump[200]
+ /* Force it into data space! */
+ = {0};
+static int staticidx_nodump;
+
+/* Put an entry in staticvec_nodump, pointing at the variable whose address is given
+ */
+void
+staticpro_nodump (Lisp_Object *varaddress)
+{
+ if (staticidx_nodump >= countof (staticvec_nodump))
+ /* #### This is now a dubious abort() since this routine may be called */
+ /* by Lisp attempting to load a DLL. */
+ abort ();
+ staticvec_nodump[staticidx_nodump++] = varaddress;
+}
+
+/* Not "static" because of linker lossage on some systems */
+struct {
+ void *data;
+ const struct struct_description *desc;
+} dumpstructvec[200];
+
+static int dumpstructidx;
+
+/* Put an entry in dumpstructvec, pointing at the variable whose address is given
+ */
+void
+dumpstruct (void *varaddress, const struct struct_description *desc)
+{
+ if (dumpstructidx >= countof (dumpstructvec))
+ abort ();
+ dumpstructvec[dumpstructidx].data = varaddress;
+ dumpstructvec[dumpstructidx].desc = desc;
+ dumpstructidx++;
+}
+
+Lisp_Object *pdump_wirevec[50];
+static int pdump_wireidx;
+
+/* Put an entry in pdump_wirevec, pointing at the variable whose address is given
+ */
+void
+pdump_wire (Lisp_Object *varaddress)
+{
+ if (pdump_wireidx >= countof (pdump_wirevec))
+ abort ();
+ pdump_wirevec[pdump_wireidx++] = varaddress;
+}
+
+
+Lisp_Object *pdump_wirevec_list[50];
+static int pdump_wireidx_list;
+
+/* Put an entry in pdump_wirevec_list, pointing at the variable whose address is given
+ */
+void
+pdump_wire_list (Lisp_Object *varaddress)
+{
+ if (pdump_wireidx_list >= countof (pdump_wirevec_list))
+ abort ();
+ pdump_wirevec_list[pdump_wireidx_list++] = varaddress;
+}
+
\f
/* Mark reference to a Lisp_Object. If the object referred to has not been
seen yet, recursively mark all the references contained in it. */
-static void
+void
mark_object (Lisp_Object obj)
{
tail_recurse:
#ifdef ERROR_CHECK_GC
- assert (! (GC_EQ (obj, Qnull_pointer)));
+ assert (! (EQ (obj, Qnull_pointer)));
#endif
/* Checks we used to perform */
/* if (EQ (obj, Qnull_pointer)) return; */
/* if (!POINTER_TYPE_P (XGCTYPE (obj))) return; */
/* if (PURIFIED (XPNTR (obj))) return; */
- if (XGCTYPE (obj) == Lisp_Type_Record)
+ if (XTYPE (obj) == Lisp_Type_Record)
{
struct lrecord_header *lheader = XRECORD_LHEADER (obj);
#if defined (ERROR_CHECK_GC)
#endif
if (implementation->marker)
{
- obj = implementation->marker (obj, mark_object);
- if (!GC_NILP (obj)) goto tail_recurse;
+ obj = implementation->marker (obj);
+ if (!NILP (obj)) goto tail_recurse;
}
}
}
/* Perhaps this will catch freeing an already-freed marker. */
Lisp_Object temmy;
XSETMARKER (temmy, ptr);
- assert (GC_MARKERP (temmy));
+ assert (MARKERP (temmy));
#endif /* ERROR_CHECK_GC */
#ifndef ALLOC_NO_POOLS
/* I hate duplicating all this crap! */
-static int
+int
marked_p (Lisp_Object obj)
{
#ifdef ERROR_CHECK_GC
- assert (! (GC_EQ (obj, Qnull_pointer)));
+ assert (! (EQ (obj, Qnull_pointer)));
#endif
/* Checks we used to perform. */
/* if (EQ (obj, Qnull_pointer)) return 1; */
/* if (!POINTER_TYPE_P (XGCTYPE (obj))) return 1; */
/* if (PURIFIED (XPNTR (obj))) return 1; */
- if (XGCTYPE (obj) == Lisp_Type_Record)
+ if (XTYPE (obj) == Lisp_Type_Record)
{
struct lrecord_header *lheader = XRECORD_LHEADER (obj);
#if defined (ERROR_CHECK_GC)
sweep_events ();
+#ifdef PDUMP
+ /* Unmark all dumped objects */
+ {
+ int i;
+ char *p = pdump_rt_list;
+ if(p)
+ for(;;)
+ {
+ pdump_reloc_table *rt = (pdump_reloc_table *)p;
+ p += sizeof (pdump_reloc_table);
+ if (rt->desc) {
+ for (i=0; i<rt->count; i++)
+ {
+ UNMARK_RECORD_HEADER ((struct lrecord_header *)(*(EMACS_INT *)p));
+ p += sizeof (EMACS_INT);
+ }
+ } else
+ break;
+ }
+ }
+#endif
}
\f
/* Clearing for disksave. */
int i;
for (i = 0; i < staticidx; i++)
mark_object (*(staticvec[i]));
+ for (i = 0; i < staticidx_nodump; i++)
+ mark_object (*(staticvec_nodump[i]));
}
{ /* GCPRO() */
}
}
- mark_redisplay (mark_object);
- mark_profiling_info (mark_object);
+ mark_redisplay ();
+ mark_profiling_info ();
/* OK, now do the after-mark stuff. This is for things that
are only marked when something else is marked (e.g. weak hash tables).
weak hash table, the former one might get marked. So we have to
iterate until nothing more gets marked. */
- while (finish_marking_weak_hash_tables (marked_p, mark_object) > 0 ||
- finish_marking_weak_lists (marked_p, mark_object) > 0)
+ while (finish_marking_weak_hash_tables () > 0 ||
+ finish_marking_weak_lists () > 0)
;
/* And prune (this needs to be called after everything else has been
marked and before we do any sweeping). */
/* #### this is somewhat ad-hoc and should probably be an object
method */
- prune_weak_hash_tables (marked_p);
- prune_weak_lists (marked_p);
- prune_specifiers (marked_p);
- prune_syntax_tables (marked_p);
+ prune_weak_hash_tables ();
+ prune_weak_lists ();
+ prune_specifiers ();
+ prune_syntax_tables ();
gc_sweep ();
garbage_collect_1 ();
- for (i = 0; i < last_lrecord_type_index_assigned; i++)
+ for (i = 0; i <= last_lrecord_type_index_assigned; i++)
{
if (lcrecord_stats[i].bytes_in_use != 0
|| lcrecord_stats[i].bytes_freed != 0
\f
/* Initialization */
void
-init_alloc_once_early (void)
+reinit_alloc_once_early (void)
{
- int iii;
-
- last_lrecord_type_index_assigned = -1;
- for (iii = 0; iii < countof (lrecord_implementations_table); iii++)
- {
- lrecord_implementations_table[iii] = 0;
- }
-
- /*
- * All the staticly
- * defined subr lrecords were initialized with lheader->type == 0.
- * See subr_lheader_initializer in lisp.h. Force type index 0 to be
- * assigned to lrecord_subr so that those predefined indexes match
- * reality.
- */
- lrecord_type_index (&lrecord_subr);
- assert (*(lrecord_subr.lrecord_type_index) == 0);
- /*
- * The same is true for symbol_value_forward objects, except the
- * type is 1.
- */
- lrecord_type_index (&lrecord_symbol_value_forward);
- assert (*(lrecord_symbol_value_forward.lrecord_type_index) == 1);
-
gc_generation_number[0] = 0;
/* purify_flag 1 is correct even if CANNOT_DUMP.
* loadup.el will set to nil at end. */
init_event_alloc ();
ignore_malloc_warnings = 0;
- staticidx = 0;
+
+ staticidx_nodump = 0;
+ dumpstructidx = 0;
+ pdump_wireidx = 0;
+
consing_since_gc = 0;
#if 1
gc_cons_threshold = 500000; /* XEmacs change */
#endif /* ERROR_CHECK_TYPECHECK */
}
+void
+init_alloc_once_early (void)
+{
+ int iii;
+
+ reinit_alloc_once_early ();
+
+ last_lrecord_type_index_assigned = -1;
+ for (iii = 0; iii < countof (lrecord_implementations_table); iii++)
+ {
+ lrecord_implementations_table[iii] = 0;
+ }
+
+ /*
+ * All the staticly
+ * defined subr lrecords were initialized with lheader->type == 0.
+ * See subr_lheader_initializer in lisp.h. Force type index 0 to be
+ * assigned to lrecord_subr so that those predefined indexes match
+ * reality.
+ */
+ lrecord_type_index (&lrecord_subr);
+ assert (*(lrecord_subr.lrecord_type_index) == 0);
+ /*
+ * The same is true for symbol_value_forward objects, except the
+ * type is 1.
+ */
+ lrecord_type_index (&lrecord_symbol_value_forward);
+ assert (*(lrecord_symbol_value_forward.lrecord_type_index) == 1);
+
+ staticidx = 0;
+}
+
int pure_bytes_used = 0;
void
image instance) in the domain of the selected frame, the mouse pointer
will change instead of this message being printed.
*/ );
- Vgc_message = make_string_nocopy ((CONST Bufbyte *) gc_default_message,
- countof (gc_default_message) - 1);
+ Vgc_message = build_string (gc_default_message);
DEFVAR_LISP ("gc-pointer-glyph", &Vgc_pointer_glyph /*
Pointer glyph used to indicate that a garbage collection is in progress.
{
Vgc_pointer_glyph = Fmake_glyph_internal (Qpointer);
}
+
+
+#ifdef PDUMP
+
+/* The structure of the file
+ *
+ * 0 - header
+ * 256 - dumped objects
+ * stab_offset - nb_staticpro*(Lisp_Object *) from staticvec
+ * - nb_staticpro*(relocated Lisp_Object) pointed to by staticpro
+ * - nb_structdmp*pair(void *, adr) for pointers to structures
+ * - lrecord_implementations_table[]
+ * - relocation table
+ * - wired variable address/value couples with the count preceding the list
+ */
+typedef struct
+{
+ char signature[8];
+ EMACS_UINT stab_offset;
+ EMACS_UINT reloc_address;
+ int nb_staticpro;
+ int nb_structdmp;
+ int last_type;
+} dump_header;
+
+char *pdump_start, *pdump_end;
+
+static const unsigned char align_table[256] =
+{
+ 8, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
+ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
+ 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
+ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
+ 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
+ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
+ 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
+ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
+ 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
+ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
+ 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
+ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
+ 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
+ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
+ 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
+ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
+};
+
+typedef struct pdump_entry_list_elmt
+{
+ struct pdump_entry_list_elmt *next;
+ const void *obj;
+ size_t size;
+ int count;
+ int is_lrecord;
+ EMACS_INT save_offset;
+} pdump_entry_list_elmt;
+
+typedef struct
+{
+ pdump_entry_list_elmt *first;
+ int align;
+ int count;
+} pdump_entry_list;
+
+typedef struct pdump_struct_list_elmt
+{
+ pdump_entry_list list;
+ const struct struct_description *sdesc;
+} pdump_struct_list_elmt;
+
+typedef struct
+{
+ pdump_struct_list_elmt *list;
+ int count;
+ int size;
+} pdump_struct_list;
+
+static pdump_entry_list pdump_object_table[256];
+static pdump_entry_list pdump_opaque_data_list;
+static pdump_struct_list pdump_struct_table;
+static pdump_entry_list_elmt *pdump_qnil;
+
+static int pdump_alert_undump_object[256];
+
+static unsigned long cur_offset;
+static size_t max_size;
+static int pdump_fd;
+static void *pdump_buf;
+
+#define PDUMP_HASHSIZE 200001
+
+static pdump_entry_list_elmt **pdump_hash;
+
+/* Since most pointers are eight bytes aligned, the >>3 allows for a better hash */
+static int
+pdump_make_hash (const void *obj)
+{
+ return ((unsigned long)(obj)>>3) % PDUMP_HASHSIZE;
+}
+
+static pdump_entry_list_elmt *
+pdump_get_entry (const void *obj)
+{
+ int pos = pdump_make_hash(obj);
+ pdump_entry_list_elmt *e;
+ while ((e = pdump_hash[pos]) != 0)
+ {
+ if (e->obj == obj)
+ return e;
+
+ pos++;
+ if (pos == PDUMP_HASHSIZE)
+ pos = 0;
+ }
+ return 0;
+}
+
+static void
+pdump_add_entry (pdump_entry_list *list, const void *obj, size_t size, int count, int is_lrecord)
+{
+ pdump_entry_list_elmt *e;
+ int align;
+ int pos = pdump_make_hash (obj);
+
+ while ((e = pdump_hash[pos]) != 0)
+ {
+ if (e->obj == obj)
+ return;
+
+ pos++;
+ if (pos == PDUMP_HASHSIZE)
+ pos = 0;
+ }
+
+ e = malloc (sizeof (pdump_entry_list_elmt));
+
+ e->next = list->first;
+ e->obj = obj;
+ e->size = size;
+ e->count = count;
+ e->is_lrecord = is_lrecord;
+ list->first = e;
+
+ list->count += count;
+ pdump_hash[pos] = e;
+
+ align = align_table[size & 255];
+ if (align<2 && is_lrecord)
+ align = 2;
+
+ if(align < list->align)
+ list->align = align;
+}
+
+static pdump_entry_list *
+pdump_get_entry_list(const struct struct_description *sdesc)
+{
+ int i;
+ for(i=0; i<pdump_struct_table.count; i++)
+ if (pdump_struct_table.list[i].sdesc == sdesc)
+ return &pdump_struct_table.list[i].list;
+
+ if (pdump_struct_table.size <= pdump_struct_table.count)
+ {
+ if (pdump_struct_table.size == -1)
+ pdump_struct_table.size = 10;
+ else
+ pdump_struct_table.size = pdump_struct_table.size * 2;
+ pdump_struct_table.list = xrealloc (pdump_struct_table.list,
+ pdump_struct_table.size*sizeof (pdump_struct_list_elmt));
+ }
+ pdump_struct_table.list[pdump_struct_table.count].list.first = 0;
+ pdump_struct_table.list[pdump_struct_table.count].list.align = 8;
+ pdump_struct_table.list[pdump_struct_table.count].list.count = 0;
+ pdump_struct_table.list[pdump_struct_table.count].sdesc = sdesc;
+
+ return &pdump_struct_table.list[pdump_struct_table.count++].list;
+}
+
+static struct {
+ Lisp_Object obj;
+ int position;
+ int offset;
+} backtrace[65536];
+
+static int depth;
+
+static void pdump_backtrace (void)
+{
+ int i;
+ fprintf (stderr, "pdump backtrace :\n");
+ for (i=0;i<depth;i++)
+ {
+ if (!backtrace[i].obj)
+ fprintf (stderr, " - ind. (%d, %d)\n", backtrace[i].position, backtrace[i].offset);
+ else
+ {
+ fprintf (stderr, " - %s (%d, %d)\n",
+ XRECORD_LHEADER_IMPLEMENTATION (backtrace[i].obj)->name,
+ backtrace[i].position,
+ backtrace[i].offset);
+ }
+ }
+}
+
+static void pdump_register_object (Lisp_Object obj);
+static void pdump_register_struct (const void *data, const struct struct_description *sdesc, int count);
+
+static EMACS_INT
+pdump_get_indirect_count (EMACS_INT code, const struct lrecord_description *idesc, const void *idata)
+{
+ EMACS_INT count;
+ const void *irdata;
+
+ int line = XD_INDIRECT_VAL (code);
+ int delta = XD_INDIRECT_DELTA (code);
+
+ irdata = ((char *)idata) + idesc[line].offset;
+ switch (idesc[line].type) {
+ case XD_SIZE_T:
+ count = *(size_t *)irdata;
+ break;
+ case XD_INT:
+ count = *(int *)irdata;
+ break;
+ case XD_LONG:
+ count = *(long *)irdata;
+ break;
+ case XD_BYTECOUNT:
+ count = *(Bytecount *)irdata;
+ break;
+ default:
+ fprintf (stderr, "Unsupported count type : %d (line = %d, code=%ld)\n", idesc[line].type, line, (long)code);
+ pdump_backtrace ();
+ abort ();
+ }
+ count += delta;
+ return count;
+}
+
+static void
+pdump_register_sub (const void *data, const struct lrecord_description *desc, int me)
+{
+ int pos;
+ const void *rdata;
+
+ restart:
+ for (pos = 0; desc[pos].type != XD_END; pos++)
+ {
+ backtrace[me].position = pos;
+ backtrace[me].offset = desc[pos].offset;
+
+ rdata = ((const char *)data) + desc[pos].offset;
+ switch(desc[pos].type)
+ {
+ case XD_SPECIFIER_END:
+ pos = 0;
+ desc = ((const struct Lisp_Specifier *)data)->methods->extra_description;
+ goto restart;
+ case XD_SIZE_T:
+ case XD_INT:
+ case XD_LONG:
+ case XD_BYTECOUNT:
+ case XD_LO_RESET_NIL:
+ case XD_INT_RESET:
+ case XD_LO_LINK:
+ break;
+ case XD_OPAQUE_DATA_PTR:
+ {
+ EMACS_INT count = desc[pos].data1;
+ if (XD_IS_INDIRECT(count))
+ count = pdump_get_indirect_count (count, desc, data);
+
+ pdump_add_entry (&pdump_opaque_data_list,
+ *(void **)rdata,
+ count,
+ 1,
+ 0);
+ break;
+ }
+ case XD_C_STRING:
+ {
+ const char *str = *(const char **)rdata;
+ if (str)
+ pdump_add_entry (&pdump_opaque_data_list, str, strlen (str)+1, 1, 0);
+ break;
+ }
+ case XD_DOC_STRING:
+ {
+ const char *str = *(const char **)rdata;
+ if ((EMACS_INT)str > 0)
+ pdump_add_entry (&pdump_opaque_data_list, str, strlen (str)+1, 1, 0);
+ break;
+ }
+ case XD_LISP_OBJECT:
+ {
+ EMACS_INT count = desc[pos].data1;
+ int i;
+ if (XD_IS_INDIRECT (count))
+ count = pdump_get_indirect_count (count, desc, data);
+
+ for(i=0;i<count;i++) {
+ const Lisp_Object *pobj = ((const Lisp_Object *)rdata) + i;
+ Lisp_Object dobj = *pobj;
+
+ backtrace[me].offset = (const char *)pobj - (const char *)data;
+ pdump_register_object (dobj);
+ }
+ break;
+ }
+ case XD_STRUCT_PTR:
+ {
+ EMACS_INT count = desc[pos].data1;
+ const struct struct_description *sdesc = desc[pos].data2;
+ const char *dobj = *(const char **)rdata;
+ if (dobj) {
+ if (XD_IS_INDIRECT (count))
+ count = pdump_get_indirect_count (count, desc, data);
+
+ pdump_register_struct (dobj, sdesc, count);
+ }
+ break;
+ }
+ default:
+ fprintf (stderr, "Unsupported dump type : %d\n", desc[pos].type);
+ pdump_backtrace ();
+ abort ();
+ };
+ }
+}
+
+static void
+pdump_register_object (Lisp_Object obj)
+{
+ if (!obj ||
+ !POINTER_TYPE_P (XTYPE (obj)) ||
+ pdump_get_entry (XRECORD_LHEADER (obj)))
+ return;
+
+ if (XRECORD_LHEADER_IMPLEMENTATION (obj)->description)
+ {
+ int me = depth++;
+ if (me>65536)
+ {
+ fprintf (stderr, "Backtrace overflow, loop ?\n");
+ abort ();
+ }
+ backtrace[me].obj = obj;
+ backtrace[me].position = 0;
+ backtrace[me].offset = 0;
+
+ pdump_add_entry (pdump_object_table + XRECORD_LHEADER (obj)->type,
+ XRECORD_LHEADER (obj),
+ XRECORD_LHEADER_IMPLEMENTATION (obj)->static_size ?
+ XRECORD_LHEADER_IMPLEMENTATION (obj)->static_size :
+ XRECORD_LHEADER_IMPLEMENTATION (obj)->size_in_bytes_method (XRECORD_LHEADER (obj)),
+ 1,
+ 1);
+ pdump_register_sub (XRECORD_LHEADER (obj),
+ XRECORD_LHEADER_IMPLEMENTATION (obj)->description,
+ me);
+ --depth;
+ }
+ else
+ {
+ pdump_alert_undump_object[XRECORD_LHEADER (obj)->type]++;
+ fprintf (stderr, "Undumpable object type : %s\n", XRECORD_LHEADER_IMPLEMENTATION (obj)->name);
+ pdump_backtrace ();
+ }
+}
+
+static void
+pdump_register_struct (const void *data, const struct struct_description *sdesc, int count)
+{
+ if (data && !pdump_get_entry (data))
+ {
+ int me = depth++;
+ int i;
+ if (me>65536)
+ {
+ fprintf (stderr, "Backtrace overflow, loop ?\n");
+ abort ();
+ }
+ backtrace[me].obj = 0;
+ backtrace[me].position = 0;
+ backtrace[me].offset = 0;
+
+ pdump_add_entry (pdump_get_entry_list (sdesc),
+ data,
+ sdesc->size,
+ count,
+ 0);
+ for (i=0; i<count; i++)
+ {
+ pdump_register_sub (((char *)data) + sdesc->size*i,
+ sdesc->description,
+ me);
+ }
+ --depth;
+ }
+}
+
+static void
+pdump_dump_data (pdump_entry_list_elmt *elmt, const struct lrecord_description *desc)
+{
+ size_t size = elmt->size;
+ int count = elmt->count;
+ if (desc)
+ {
+ int pos, i;
+ void *rdata;
+ memcpy (pdump_buf, elmt->obj, size*count);
+
+ for (i=0; i<count; i++)
+ {
+ char *cur = ((char *)pdump_buf) + i*size;
+ restart:
+ for (pos = 0; desc[pos].type != XD_END; pos++)
+ {
+ rdata = cur + desc[pos].offset;
+ switch (desc[pos].type)
+ {
+ case XD_SPECIFIER_END:
+ pos = 0;
+ desc = ((const struct Lisp_Specifier *)(elmt->obj))->methods->extra_description;
+ goto restart;
+ case XD_SIZE_T:
+ case XD_INT:
+ case XD_LONG:
+ case XD_BYTECOUNT:
+ break;
+ case XD_LO_RESET_NIL:
+ {
+ EMACS_INT count = desc[pos].data1;
+ int i;
+ if (XD_IS_INDIRECT (count))
+ count = pdump_get_indirect_count (count, desc, elmt->obj);
+ for (i=0; i<count; i++)
+ ((EMACS_INT *)rdata)[i] = pdump_qnil->save_offset;
+ break;
+ }
+ case XD_INT_RESET:
+ {
+ EMACS_INT val = desc[pos].data1;
+ if (XD_IS_INDIRECT (val))
+ val = pdump_get_indirect_count (val, desc, elmt->obj);
+ *(int *)rdata = val;
+ break;
+ }
+ case XD_OPAQUE_DATA_PTR:
+ case XD_C_STRING:
+ case XD_STRUCT_PTR:
+ {
+ void *ptr = *(void **)rdata;
+ if (ptr)
+ *(EMACS_INT *)rdata = pdump_get_entry (ptr)->save_offset;
+ break;
+ }
+ case XD_LO_LINK:
+ {
+ Lisp_Object obj = *(Lisp_Object *)rdata;
+ pdump_entry_list_elmt *elmt1;
+ for(;;)
+ {
+ elmt1 = pdump_get_entry (XRECORD_LHEADER(obj));
+ if (elmt1)
+ break;
+ obj = *(Lisp_Object *)(desc[pos].offset + (char *)(XRECORD_LHEADER (obj)));
+ }
+ *(EMACS_INT *)rdata = elmt1->save_offset;
+ break;
+ }
+ case XD_LISP_OBJECT:
+ {
+ EMACS_INT count = desc[pos].data1;
+ int i;
+ if (XD_IS_INDIRECT (count))
+ count = pdump_get_indirect_count (count, desc, elmt->obj);
+
+ for(i=0; i<count; i++)
+ {
+ Lisp_Object *pobj = ((Lisp_Object *)rdata) + i;
+ Lisp_Object dobj = *pobj;
+ if (dobj && POINTER_TYPE_P (XTYPE (dobj)))
+ *pobj = pdump_get_entry (XRECORD_LHEADER (dobj))->save_offset;
+ }
+ break;
+ }
+ case XD_DOC_STRING:
+ {
+ EMACS_INT str = *(EMACS_INT *)rdata;
+ if (str > 0)
+ *(EMACS_INT *)rdata = pdump_get_entry ((void *)str)->save_offset;
+ break;
+ }
+ default:
+ fprintf (stderr, "Unsupported dump type : %d\n", desc[pos].type);
+ abort ();
+ };
+ }
+ }
+ }
+ write (pdump_fd, desc ? pdump_buf : elmt->obj, size*count);
+ if (elmt->is_lrecord && ((size*count) & 3))
+ write (pdump_fd, "\0\0\0", 4-((size*count) & 3));
+}
+
+static void
+pdump_reloc_one (void *data, EMACS_INT delta, const struct lrecord_description *desc)
+{
+ int pos;
+ void *rdata;
+
+ restart:
+ for (pos = 0; desc[pos].type != XD_END; pos++)
+ {
+ rdata = ((char *)data) + desc[pos].offset;
+ switch (desc[pos].type) {
+ case XD_SPECIFIER_END:
+ pos = 0;
+ desc = ((const struct Lisp_Specifier *)data)->methods->extra_description;
+ goto restart;
+ case XD_SIZE_T:
+ case XD_INT:
+ case XD_LONG:
+ case XD_BYTECOUNT:
+ case XD_INT_RESET:
+ break;
+ case XD_OPAQUE_DATA_PTR:
+ case XD_C_STRING:
+ case XD_STRUCT_PTR:
+ case XD_LO_LINK:
+ {
+ EMACS_INT ptr = *(EMACS_INT *)rdata;
+ if (ptr)
+ *(EMACS_INT *)rdata = ptr+delta;
+ break;
+ }
+ case XD_LISP_OBJECT:
+ case XD_LO_RESET_NIL:
+ {
+ EMACS_INT count = desc[pos].data1;
+ int i;
+ if (XD_IS_INDIRECT (count))
+ count = pdump_get_indirect_count (count, desc, data);
+
+ for (i=0; i<count; i++)
+ {
+ Lisp_Object *pobj = ((Lisp_Object *)rdata) + i;
+ Lisp_Object dobj = *pobj;
+ if (dobj && POINTER_TYPE_P (XTYPE (dobj)))
+ *pobj = dobj + delta;
+ }
+ break;
+ }
+ case XD_DOC_STRING:
+ {
+ EMACS_INT str = *(EMACS_INT *)rdata;
+ if (str > 0)
+ *(EMACS_INT *)rdata = str + delta;
+ break;
+ }
+ default:
+ fprintf (stderr, "Unsupported dump type : %d\n", desc[pos].type);
+ abort ();
+ };
+ }
+}
+
+static void
+pdump_allocate_offset (pdump_entry_list_elmt *elmt, const struct lrecord_description *desc)
+{
+ size_t size = (elmt->is_lrecord ? (elmt->size + 3) & ~3 : elmt->size)*elmt->count;
+ elmt->save_offset = cur_offset;
+ if (size>max_size)
+ max_size = size;
+ cur_offset += size;
+}
+
+static void
+pdump_scan_by_alignement (void (*f)(pdump_entry_list_elmt *, const struct lrecord_description *))
+{
+ int align, i;
+ const struct lrecord_description *idesc;
+ pdump_entry_list_elmt *elmt;
+ for (align=8; align>=0; align--)
+ {
+ for (i=0; i<=last_lrecord_type_index_assigned; i++)
+ if (pdump_object_table[i].align == align)
+ {
+ elmt = pdump_object_table[i].first;
+ if (!elmt)
+ continue;
+ idesc = lrecord_implementations_table[i]->description;
+ while (elmt)
+ {
+ f (elmt, idesc);
+ elmt = elmt->next;
+ }
+ }
+
+ for (i=0; i<pdump_struct_table.count; i++)
+ if (pdump_struct_table.list[i].list.align == align) {
+ elmt = pdump_struct_table.list[i].list.first;
+ idesc = pdump_struct_table.list[i].sdesc->description;
+ while (elmt)
+ {
+ f (elmt, idesc);
+ elmt = elmt->next;
+ }
+ }
+
+ elmt = pdump_opaque_data_list.first;
+ while (elmt)
+ {
+ if (align_table[elmt->size & 255] == align)
+ f (elmt, 0);
+ elmt = elmt->next;
+ }
+ }
+}
+
+static void
+pdump_dump_staticvec (void)
+{
+ Lisp_Object *reloc = malloc (staticidx*sizeof (Lisp_Object));
+ int i;
+ write (pdump_fd, staticvec, staticidx*sizeof (Lisp_Object *));
+
+ for(i=0; i<staticidx; i++)
+ {
+ Lisp_Object obj = *staticvec[i];
+ if (obj && POINTER_TYPE_P (XTYPE (obj)))
+ reloc[i] = pdump_get_entry (XRECORD_LHEADER (obj))->save_offset;
+ else
+ reloc[i] = obj;
+ }
+ write (pdump_fd, reloc, staticidx*sizeof (Lisp_Object));
+ free (reloc);
+}
+
+static void
+pdump_dump_structvec (void)
+{
+ int i;
+ for (i=0; i<dumpstructidx; i++)
+ {
+ EMACS_INT adr;
+ write (pdump_fd, &(dumpstructvec[i].data), sizeof (void *));
+ adr = pdump_get_entry (*(void **)(dumpstructvec[i].data))->save_offset;
+ write (pdump_fd, &adr, sizeof (adr));
+ }
+}
+
+static void
+pdump_dump_itable (void)
+{
+ write (pdump_fd, lrecord_implementations_table, sizeof (lrecord_implementations_table));
+}
+
+static void
+pdump_dump_rtables (void)
+{
+ int i, j;
+ pdump_entry_list_elmt *elmt;
+ pdump_reloc_table rt;
+
+ for (i=0; i<=last_lrecord_type_index_assigned; i++)
+ {
+ elmt = pdump_object_table[i].first;
+ if(!elmt)
+ continue;
+ rt.desc = lrecord_implementations_table[i]->description;
+ rt.count = pdump_object_table[i].count;
+ write (pdump_fd, &rt, sizeof (rt));
+ while (elmt)
+ {
+ EMACS_INT rdata = pdump_get_entry (XRECORD_LHEADER (elmt->obj))->save_offset;
+ write (pdump_fd, &rdata, sizeof (rdata));
+ elmt = elmt->next;
+ }
+ }
+
+ rt.desc = 0;
+ rt.count = 0;
+ write (pdump_fd, &rt, sizeof (rt));
+
+ for (i=0; i<pdump_struct_table.count; i++)
+ {
+ elmt = pdump_struct_table.list[i].list.first;
+ rt.desc = pdump_struct_table.list[i].sdesc->description;
+ rt.count = pdump_struct_table.list[i].list.count;
+ write (pdump_fd, &rt, sizeof (rt));
+ while (elmt)
+ {
+ EMACS_INT rdata = pdump_get_entry (XRECORD_LHEADER (elmt->obj))->save_offset;
+ for (j=0; j<elmt->count; j++) {
+ write (pdump_fd, &rdata, sizeof (rdata));
+ rdata += elmt->size;
+ }
+ elmt = elmt->next;
+ }
+ }
+ rt.desc = 0;
+ rt.count = 0;
+ write (pdump_fd, &rt, sizeof (rt));
+}
+
+static void
+pdump_dump_wired (void)
+{
+ EMACS_INT count = pdump_wireidx + pdump_wireidx_list;
+ int i;
+
+ write (pdump_fd, &count, sizeof (count));
+
+ for (i=0; i<pdump_wireidx; i++)
+ {
+ Lisp_Object obj = pdump_get_entry (XRECORD_LHEADER (*(pdump_wirevec[i])))->save_offset;
+ write (pdump_fd, &pdump_wirevec[i], sizeof (pdump_wirevec[i]));
+ write (pdump_fd, &obj, sizeof (obj));
+ }
+
+ for (i=0; i<pdump_wireidx_list; i++)
+ {
+ Lisp_Object obj = *(pdump_wirevec_list[i]);
+ pdump_entry_list_elmt *elmt;
+ EMACS_INT res;
+
+ for(;;)
+ {
+ const struct lrecord_description *desc;
+ int pos;
+ elmt = pdump_get_entry (XRECORD_LHEADER (obj));
+ if (elmt)
+ break;
+ desc = XRECORD_LHEADER_IMPLEMENTATION (obj)->description;
+ for (pos = 0; desc[pos].type != XD_LO_LINK; pos++)
+ if (desc[pos].type == XD_END)
+ abort ();
+
+ obj = *(Lisp_Object *)(desc[pos].offset + (char *)(XRECORD_LHEADER (obj)));
+ }
+ res = elmt->save_offset;
+
+ write (pdump_fd, &pdump_wirevec_list[i], sizeof (pdump_wirevec_list[i]));
+ write (pdump_fd, &res, sizeof (res));
+ }
+}
+
+void
+pdump (void)
+{
+ int i;
+ Lisp_Object t_console, t_device, t_frame;
+ int none;
+ dump_header hd;
+
+ /* These appear in a DEFVAR_LISP, which does a staticpro() */
+ t_console = Vterminal_console;
+ t_frame = Vterminal_frame;
+ t_device = Vterminal_device;
+
+ Vterminal_console = Qnil;
+ Vterminal_frame = Qnil;
+ Vterminal_device = Qnil;
+
+ pdump_hash = malloc (PDUMP_HASHSIZE*sizeof (pdump_entry_list_elmt *));
+ memset (pdump_hash, 0, PDUMP_HASHSIZE*sizeof (pdump_entry_list_elmt *));
+
+ for (i=0; i<=last_lrecord_type_index_assigned; i++)
+ {
+ pdump_object_table[i].first = 0;
+ pdump_object_table[i].align = 8;
+ pdump_object_table[i].count = 0;
+ pdump_alert_undump_object[i] = 0;
+ }
+ pdump_struct_table.count = 0;
+ pdump_struct_table.size = -1;
+
+ pdump_opaque_data_list.first = 0;
+ pdump_opaque_data_list.align = 8;
+ pdump_opaque_data_list.count = 0;
+ depth = 0;
+
+ for (i=0; i<staticidx; i++)
+ pdump_register_object (*staticvec[i]);
+ for (i=0; i<pdump_wireidx; i++)
+ pdump_register_object (*pdump_wirevec[i]);
+
+ none = 1;
+ for(i=0;i<=last_lrecord_type_index_assigned;i++)
+ if (pdump_alert_undump_object[i])
+ {
+ if (none)
+ printf ("Undumpable types list :\n");
+ none = 0;
+ printf (" - %s (%d)\n", lrecord_implementations_table[i]->name, pdump_alert_undump_object[i]);
+ }
+ if (!none)
+ return;
+
+ for (i=0; i<dumpstructidx; i++)
+ pdump_register_struct (*(void **)(dumpstructvec[i].data), dumpstructvec[i].desc, 1);
+
+ memcpy (hd.signature, "XEmacsDP", 8);
+ hd.reloc_address = 0;
+ hd.nb_staticpro = staticidx;
+ hd.nb_structdmp = dumpstructidx;
+ hd.last_type = last_lrecord_type_index_assigned;
+
+ cur_offset = 256;
+ max_size = 0;
+
+ pdump_scan_by_alignement (pdump_allocate_offset);
+ pdump_qnil = pdump_get_entry (XRECORD_LHEADER (Qnil));
+
+ pdump_buf = malloc (max_size);
+ pdump_fd = open ("xemacs.dmp", O_WRONLY|O_CREAT|O_TRUNC, 0666);
+ hd.stab_offset = (cur_offset + 3) & ~3;
+
+ write (pdump_fd, &hd, sizeof (hd));
+ lseek (pdump_fd, 256, SEEK_SET);
+
+ pdump_scan_by_alignement (pdump_dump_data);
+
+ lseek (pdump_fd, hd.stab_offset, SEEK_SET);
+
+ pdump_dump_staticvec ();
+ pdump_dump_structvec ();
+ pdump_dump_itable ();
+ pdump_dump_rtables ();
+ pdump_dump_wired ();
+
+ close (pdump_fd);
+ free (pdump_buf);
+
+ free (pdump_hash);
+
+ Vterminal_console = t_console;
+ Vterminal_frame = t_frame;
+ Vterminal_device = t_device;
+}
+
+int
+pdump_load (void)
+{
+ size_t length;
+ int i;
+ char *p;
+ EMACS_INT delta;
+ EMACS_INT count;
+
+ pdump_start = pdump_end = 0;
+
+ pdump_fd = open ("xemacs.dmp", O_RDONLY);
+ if (pdump_fd<0)
+ return 0;
+
+ length = lseek (pdump_fd, 0, SEEK_END);
+ lseek (pdump_fd, 0, SEEK_SET);
+
+#ifdef HAVE_MMAP
+ pdump_start = mmap (0, length, PROT_READ|PROT_WRITE, MAP_PRIVATE, pdump_fd, 0);
+ if (pdump_start == MAP_FAILED)
+ pdump_start = 0;
+#endif
+
+ if (!pdump_start)
+ {
+ pdump_start = (void *)((((unsigned long)(malloc(length+255))) + 255) & ~255);
+ read(pdump_fd, pdump_start, length);
+ }
+
+ close (pdump_fd);
+
+ pdump_end = pdump_start + length;
+
+ staticidx = ((dump_header *)(pdump_start))->nb_staticpro;
+ last_lrecord_type_index_assigned = ((dump_header *)(pdump_start))->last_type;
+ delta = ((EMACS_INT)pdump_start) - ((dump_header *)pdump_start)->reloc_address;
+ p = pdump_start + ((dump_header *)pdump_start)->stab_offset;
+
+ /* Put back the staticvec in place */
+ memcpy (staticvec, p, staticidx*sizeof (Lisp_Object *));
+ p += staticidx*sizeof (Lisp_Object *);
+ for (i=0; i<staticidx; i++)
+ {
+ Lisp_Object obj = *(Lisp_Object *)p;
+ p += sizeof (Lisp_Object);
+ if (obj && POINTER_TYPE_P (XTYPE (obj)))
+ obj += delta;
+ *staticvec[i] = obj;
+ }
+
+ /* Put back the dumpstructs */
+ for (i=0; i<((dump_header *)pdump_start)->nb_structdmp; i++)
+ {
+ void **adr = *(void **)p;
+ p += sizeof (void *);
+ *adr = (void *)((*(EMACS_INT *)p) + delta);
+ p += sizeof (EMACS_INT);
+ }
+
+ /* Put back the lrecord_implementations_table */
+ memcpy (lrecord_implementations_table, p, sizeof (lrecord_implementations_table));
+ p += sizeof (lrecord_implementations_table);
+
+ /* Give back their numbers to the lrecord implementations */
+ for (i=0; i<sizeof(lrecord_implementations_table)/sizeof(lrecord_implementations_table[0]); i++)
+ if (lrecord_implementations_table[i])
+ {
+ *(lrecord_implementations_table[i]->lrecord_type_index) = i;
+ last_lrecord_type_index_assigned = i;
+ }
+
+ /* Do the relocations */
+ pdump_rt_list = p;
+ count = 2;
+ for(;;)
+ {
+ pdump_reloc_table *rt = (pdump_reloc_table *)p;
+ p += sizeof (pdump_reloc_table);
+ if (rt->desc) {
+ for (i=0; i<rt->count; i++)
+ {
+ EMACS_INT adr = delta + *(EMACS_INT *)p;
+ *(EMACS_INT *)p = adr;
+ pdump_reloc_one ((void *)adr, delta, rt->desc);
+ p += sizeof (EMACS_INT);
+ }
+ } else
+ if(!(--count))
+ break;
+ }
+
+ /* Put the pdump_wire variables in place */
+ count = *(EMACS_INT *)p;
+ p += sizeof(EMACS_INT);
+
+ for (i=0; i<count; i++)
+ {
+ Lisp_Object *var, obj;
+ var = *(Lisp_Object **)p;
+ p += sizeof (Lisp_Object *);
+
+ obj = *(Lisp_Object *)p;
+ p += sizeof (Lisp_Object);
+
+ if (obj && POINTER_TYPE_P (XTYPE (obj)))
+ obj += delta;
+ *var = obj;
+ }
+
+ /* Final cleanups */
+ /* reorganize hash tables */
+ p = pdump_rt_list;
+ for(;;)
+ {
+ pdump_reloc_table *rt = (pdump_reloc_table *)p;
+ p += sizeof (pdump_reloc_table);
+ if (!rt->desc)
+ break;
+ if (rt->desc == hash_table_description)
+ {
+ for (i=0; i<rt->count; i++)
+ {
+ struct Lisp_Hash_Table *ht = XHASH_TABLE (*(EMACS_INT *)p);
+ reorganize_hash_table (ht);
+ p += sizeof (EMACS_INT);
+ }
+ break;
+ } else
+ p += sizeof (EMACS_INT)*rt->count;
+ }
+ return 1;
+}
+
+#endif
Setting the default value also goes through the alist of buffers
and stores into each buffer that does not say it has a local value. */
Lisp_Object Vbuffer_defaults;
+static void *buffer_defaults_saved_slots;
/* This structure marks which slots in a buffer have corresponding
default values in Vbuffer_defaults.
/* This structure holds the names of symbols whose values may be
buffer-local. It is indexed and accessed in the same way as the above. */
static Lisp_Object Vbuffer_local_symbols;
+static void *buffer_local_symbols_saved_slots;
/* Alist of all buffer names vs the buffers. */
/* This used to be a variable, but is no longer,
Lisp_Object Qdefault_directory;
Lisp_Object Qkill_buffer_hook;
-Lisp_Object Qbuffer_file_name, Qbuffer_undo_list;
+Lisp_Object Qrecord_buffer_hook;
Lisp_Object Qrename_auto_save_file;
}
static Lisp_Object
-mark_buffer (Lisp_Object obj, void (*markobj) (Lisp_Object))
+mark_buffer (Lisp_Object obj)
{
struct buffer *buf = XBUFFER (obj);
undo_threshold,
undo_high_threshold);
-#define MARKED_SLOT(x) ((void) (markobj (buf->x)));
+#define MARKED_SLOT(x) mark_object (buf->x)
#include "bufslots.h"
#undef MARKED_SLOT
- markobj (buf->extent_info);
+ mark_object (buf->extent_info);
if (buf->text)
- markobj (buf->text->line_number_cache);
+ mark_object (buf->text->line_number_cache);
/* Don't mark normally through the children slot.
(Actually, in this case, it doesn't matter.) */
XCDR (prev) = XCDR (XCDR (prev));
XCDR (lynk) = f->buffer_alist;
f->buffer_alist = lynk;
+
+ va_run_hook_with_args (Qrecord_buffer_hook, 1, buffer);
+
return Qnil;
}
defsymbol (&Qmode_class, "mode-class");
defsymbol (&Qrename_auto_save_file, "rename-auto-save-file");
defsymbol (&Qkill_buffer_hook, "kill-buffer-hook");
+ defsymbol (&Qrecord_buffer_hook, "record-buffer-hook");
defsymbol (&Qpermanent_local, "permanent-local");
defsymbol (&Qfirst_change_hook, "first-change-hook");
defsymbol (&Qbefore_change_function, "before-change-function");
defsymbol (&Qafter_change_function, "after-change-function");
- defsymbol (&Qbuffer_file_name, "buffer-file-name");
- defsymbol (&Qbuffer_undo_list, "buffer-undo-list");
defsymbol (&Qdefault_directory, "default-directory");
defsymbol (&Qget_file_buffer, "get-file-buffer");
"Attempt to modify a protected field", Qerror);
}
+void
+reinit_vars_of_buffer (void)
+{
+ staticpro_nodump (&Vbuffer_alist);
+ Vbuffer_alist = Qnil;
+ current_buffer = 0;
+}
+
/* initialize the buffer routines */
void
vars_of_buffer (void)
{
/* This function can GC */
+ reinit_vars_of_buffer ();
+
staticpro (&QSFundamental);
staticpro (&QSscratch);
- staticpro (&Vbuffer_alist);
- QSFundamental = Fpurecopy (build_string ("Fundamental"));
- QSscratch = Fpurecopy (build_string (DEFER_GETTEXT ("*scratch*")));
-
- Vbuffer_alist = Qnil;
- current_buffer = 0;
+ QSFundamental = build_string ("Fundamental");
+ QSscratch = build_string (DEFER_GETTEXT ("*scratch*"));
DEFVAR_LISP ("change-major-mode-hook", &Vchange_major_mode_hook /*
List of hooks to be run before killing local variables in a buffer.
b->indirect_children = Qnil;
b->own_text.line_number_cache = Qnil;
-#define MARKED_SLOT(x) b->x = (zap);
+#define MARKED_SLOT(x) b->x = zap
#include "bufslots.h"
#undef MARKED_SLOT
}
-void
-complex_vars_of_buffer (void)
+static void
+common_init_complex_vars_of_buffer (void)
{
/* Make sure all markable slots in buffer_defaults
are initialized reasonably, so mark_buffer won't choke. */
struct buffer *defs = alloc_lcrecord_type (struct buffer, &lrecord_buffer);
struct buffer *syms = alloc_lcrecord_type (struct buffer, &lrecord_buffer);
- staticpro (&Vbuffer_defaults);
- staticpro (&Vbuffer_local_symbols);
+ staticpro_nodump (&Vbuffer_defaults);
+ staticpro_nodump (&Vbuffer_local_symbols);
XSETBUFFER (Vbuffer_defaults, defs);
XSETBUFFER (Vbuffer_local_symbols, syms);
buffer_local_flags.buffer_file_coding_system = make_int (1<<14);
#endif
- /* #### Warning: 1<<28 is the largest number currently allowable
+ /* #### Warning: 1<<31 is the largest number currently allowable
due to the XINT() handling of this value. With some
rearrangement you can get 3 more bits. */
}
+}
+
+#define BUFFER_SLOTS_SIZE (offsetof (struct buffer, BUFFER_SLOTS_LAST_NAME) - offsetof (struct buffer, BUFFER_SLOTS_FIRST_NAME) + sizeof (Lisp_Object))
+#define BUFFER_SLOTS_COUNT (BUFFER_SLOTS_SIZE / sizeof (Lisp_Object))
+
+void
+reinit_complex_vars_of_buffer (void)
+{
+ struct buffer *defs, *syms;
+
+ common_init_complex_vars_of_buffer ();
+
+ defs = XBUFFER (Vbuffer_defaults);
+ syms = XBUFFER (Vbuffer_local_symbols);
+ memcpy (&defs->BUFFER_SLOTS_FIRST_NAME,
+ buffer_defaults_saved_slots,
+ BUFFER_SLOTS_SIZE);
+ memcpy (&syms->BUFFER_SLOTS_FIRST_NAME,
+ buffer_local_symbols_saved_slots,
+ BUFFER_SLOTS_SIZE);
+}
+
+
+static const struct lrecord_description buffer_slots_description_1[] = {
+ { XD_LISP_OBJECT, 0, BUFFER_SLOTS_COUNT },
+ { XD_END }
+};
+
+static const struct struct_description buffer_slots_description = {
+ BUFFER_SLOTS_SIZE,
+ buffer_slots_description_1
+};
+
+void
+complex_vars_of_buffer (void)
+{
+ struct buffer *defs, *syms;
+
+ common_init_complex_vars_of_buffer ();
+ defs = XBUFFER (Vbuffer_defaults);
+ syms = XBUFFER (Vbuffer_local_symbols);
+ buffer_defaults_saved_slots = &defs->BUFFER_SLOTS_FIRST_NAME;
+ buffer_local_symbols_saved_slots = &syms->BUFFER_SLOTS_FIRST_NAME;
+ dumpstruct (&buffer_defaults_saved_slots, &buffer_slots_description);
+ dumpstruct (&buffer_local_symbols_saved_slots, &buffer_slots_description);
+
DEFVAR_BUFFER_DEFAULTS ("default-modeline-format", modeline_format /*
Default value of `modeline-format' for buffers that don't override it.
This is the same as (default-value 'modeline-format).
#define XBUFFER(x) XRECORD (x, buffer, struct buffer)
#define XSETBUFFER(x, p) XSETRECORD (x, p, buffer)
#define BUFFERP(x) RECORDP (x, buffer)
-#define GC_BUFFERP(x) GC_RECORDP (x, buffer)
#define CHECK_BUFFER(x) CHECK_RECORD (x, buffer)
#define CONCHECK_BUFFER(x) CONCHECK_RECORD (x, buffer)
#else
-#define XCHAR_OR_CHAR_INT(obj) (CHARP ((obj)) ? XCHAR ((obj)) : XINT ((obj)))
+#define XCHAR_OR_CHAR_INT(obj) (CHARP (obj) ? XCHAR (obj) : XINT (obj))
#endif
definition. In the garbage collector this file is included after
defining MARKED_SLOT(x) to be mark_object(buffer->x). */
+#ifndef BUFFER_SLOTS_FIRST_NAME
+#define BUFFER_SLOTS_FIRST_NAME name
+#endif
+
/* The name of this buffer. */
MARKED_SLOT (name);
/* A hash table that maps from a "generic extent" (an extent in
`modeline-format') into a buffer-specific extent. */
MARKED_SLOT (modeline_extent_table);
+
+#ifndef BUFFER_SLOTS_LAST_NAME
+#define BUFFER_SLOTS_LAST_NAME modeline_extent_table
+#endif
+
#if 0 /* FSFmacs */
/* This is silly and stupid */
/* These are so we don't have to recompile everything
Lisp_Object Vbyte_code_meter, Qbyte_code_meter;
int byte_metering_on;
-#define METER_2(code1, code2) \
- XINT (XVECTOR_DATA (XVECTOR_DATA (Vbyte_code_meter)[(code1)])[(code2)])
-
-#define METER_1(code) METER_2 (0, (code))
-
-#define METER_CODE(last_code, this_code) do { \
- if (byte_metering_on) \
- { \
- if (METER_1 (this_code) != ((1<<VALBITS)-1)) \
- METER_1 (this_code)++; \
- if (last_code \
- && METER_2 (last_code, this_code) != ((1<<VALBITS)-1)) \
- METER_2 (last_code, this_code)++; \
- } \
-} while (0)
+static void
+meter_code (Opcode prev_opcode, Opcode this_opcode)
+{
+ if (byte_metering_on)
+ {
+ Lisp_Object *p = XVECTOR_DATA (XVECTOR_DATA (Vbyte_code_meter)[this_opcode]);
+ p[0] = INT_PLUS1 (p[0]);
+ if (prev_opcode)
+ p[prev_opcode] = INT_PLUS1 (p[prev_opcode]);
+ }
+}
#endif /* BYTE_CODE_METER */
{
retry:
+ if (INTP (obj)) return make_int (- XINT (obj));
#ifdef LISP_FLOAT_TYPE
if (FLOATP (obj)) return make_float (- XFLOAT_DATA (obj));
#endif
if (CHARP (obj)) return make_int (- ((int) XCHAR (obj)));
if (MARKERP (obj)) return make_int (- ((int) marker_position (obj)));
- if (INTP (obj)) return make_int (- XINT (obj));
obj = wrong_type_argument (Qnumber_char_or_marker_p, obj);
goto retry;
#ifdef LISP_FLOAT_TYPE
{
- int ival1, ival2;
+ EMACS_INT ival1, ival2;
if (INTP (obj1)) ival1 = XINT (obj1);
else if (CHARP (obj1)) ival1 = XCHAR (obj1);
}
#else /* !LISP_FLOAT_TYPE */
{
- int ival1, ival2;
+ EMACS_INT ival1, ival2;
if (INTP (obj1)) ival1 = XINT (obj1);
else if (CHARP (obj1)) ival1 = XCHAR (obj1);
bytecode_arithop (Lisp_Object obj1, Lisp_Object obj2, Opcode opcode)
{
#ifdef LISP_FLOAT_TYPE
- int ival1, ival2;
+ EMACS_INT ival1, ival2;
int float_p;
retry:
return make_float (dval1);
}
#else /* !LISP_FLOAT_TYPE */
- int ival1, ival2;
+ EMACS_INT ival1, ival2;
retry:
#ifdef BYTE_CODE_METER
prev_opcode = this_opcode;
this_opcode = opcode;
- METER_CODE (prev_opcode, this_opcode);
+ meter_code (prev_opcode, this_opcode);
#endif
switch (opcode)
opcode == Bunbind+6 ? READ_UINT_1 : READ_UINT_2));
break;
+
case Bgoto:
JUMP;
break;
}
case Bsub1:
- TOP = INTP (TOP) ? make_int (XINT (TOP) - 1) : Fsub1 (TOP);
+ TOP = INTP (TOP) ? INT_MINUS1 (TOP) : Fsub1 (TOP);
break;
case Badd1:
- TOP = INTP (TOP) ? make_int (XINT (TOP) + 1) : Fadd1 (TOP);
+ TOP = INTP (TOP) ? INT_PLUS1 (TOP) : Fadd1 (TOP);
break;
Lisp_Object arg2 = POP;
Lisp_Object arg1 = TOP;
TOP = INTP (arg1) && INTP (arg2) ?
- make_int (XINT (arg1) + XINT (arg2)) :
+ INT_PLUS (arg1, arg2) :
bytecode_arithop (arg1, arg2, opcode);
break;
}
Lisp_Object arg2 = POP;
Lisp_Object arg1 = TOP;
TOP = INTP (arg1) && INTP (arg2) ?
- make_int (XINT (arg1) - XINT (arg2)) :
+ INT_MINUS (arg1, arg2) :
bytecode_arithop (arg1, arg2, opcode);
break;
}
break;
}
-
case Bset:
{
Lisp_Object arg = POP;
program, &program_length, &varbind_count);
f->specpdl_depth = XINT (Flength (f->arglist)) + varbind_count;
f->instructions =
- Fpurecopy (make_opaque (program_length * sizeof (Opbyte),
- (CONST void *) program));
+ make_opaque (program_length * sizeof (Opbyte),
+ (CONST void *) program);
}
assert (OPAQUEP (f->instructions));
static Lisp_Object
-mark_compiled_function (Lisp_Object obj, void (*markobj) (Lisp_Object))
+mark_compiled_function (Lisp_Object obj)
{
Lisp_Compiled_Function *f = XCOMPILED_FUNCTION (obj);
- markobj (f->instructions);
- markobj (f->arglist);
- markobj (f->doc_and_interactive);
+ mark_object (f->instructions);
+ mark_object (f->arglist);
+ mark_object (f->doc_and_interactive);
#ifdef COMPILED_FUNCTION_ANNOTATION_HACK
- markobj (f->annotated);
+ mark_object (f->annotated);
#endif
/* tail-recurse on constants */
return f->constants;
/* v18 or v19 bytecode file. Need to Ebolify. */
if (f->flags.ebolified && VECTORP (XCDR (tem)))
ebolify_bytecode_constants (XCDR (tem));
- /* VERY IMPORTANT to purecopy here!!!!!
- See load_force_doc_string_unwind. */
- f->instructions = Fpurecopy (XCAR (tem));
- f->constants = Fpurecopy (XCDR (tem));
+ f->instructions = XCAR (tem);
+ f->constants = XCDR (tem);
return function;
}
abort ();
Lisp_Compiled_Function)
#define XSETCOMPILED_FUNCTION(x, p) XSETRECORD (x, p, compiled_function)
#define COMPILED_FUNCTIONP(x) RECORDP (x, compiled_function)
-#define GC_COMPILED_FUNCTIONP(x) GC_RECORDP (x, compiled_function)
#define CHECK_COMPILED_FUNCTION(x) CHECK_RECORD (x, compiled_function)
#define CONCHECK_COMPILED_FUNCTION(x) CONCHECK_RECORD (x, compiled_function)
Lisp_Object Qlet, QletX, Qsave_excursion;
-Lisp_Object Qcurrent_prefix_arg;
-
-Lisp_Object Quser_variable_p;
Lisp_Object Qread_from_minibuffer;
Lisp_Object Qread_file_name;
Lisp_Object Qread_directory_name;
defsymbol (&Qevents_to_keys, "events-to-keys");
defsymbol (&Qcommand_debug_status, "command-debug-status");
defsymbol (&Qenable_recursive_minibuffers, "enable-recursive-minibuffers");
- defsymbol (&Quser_variable_p, "user-variable-p");
- defsymbol (&Qcurrent_prefix_arg, "current-prefix-arg");
defsymbol (&Qlet, "let");
defsymbol (&QletX, "let*");
#include "buffer.h"
#include "opaque.h"
-Lisp_Object Qcase_table_p;
+Lisp_Object Qcase_tablep;
Lisp_Object Vascii_downcase_table, Vascii_upcase_table;
Lisp_Object Vascii_canon_table, Vascii_eqv_table;
#ifdef MULE
Lisp_Object Vmirror_ascii_downcase_table, Vmirror_ascii_upcase_table;
Lisp_Object Vmirror_ascii_canon_table, Vmirror_ascii_eqv_table;
#endif
-Lisp_Object Qtranslate_table;
static void compute_trt_inverse (Lisp_Object trt, Lisp_Object inverse);
REGISTER Lisp_Object tem;
while (tem = Fcase_table_p (obj), NILP (tem))
- obj = wrong_type_argument (Qcase_table_p, obj);
+ obj = wrong_type_argument (Qcase_tablep, obj);
return (obj);
}
void
syms_of_casetab (void)
{
- defsymbol (&Qcase_table_p, "case-table-p");
- defsymbol (&Qtranslate_table, "translate-table");
+ defsymbol (&Qcase_tablep, "case-table-p");
DEFSUBR (Fcase_table_p);
DEFSUBR (Fcurrent_case_table);
staticpro (&Vascii_canon_table);
staticpro (&Vascii_eqv_table);
+#ifdef MULE
+ staticpro (&Vmirror_ascii_downcase_table);
+ staticpro (&Vmirror_ascii_upcase_table);
+ staticpro (&Vmirror_ascii_canon_table);
+ staticpro (&Vmirror_ascii_eqv_table);
+#endif
+
tem = MAKE_TRT_TABLE ();
Vascii_downcase_table = tem;
Vascii_canon_table = tem;
#ifdef MULE
static Lisp_Object
-mark_char_table_entry (Lisp_Object obj, void (*markobj) (Lisp_Object))
+mark_char_table_entry (Lisp_Object obj)
{
struct Lisp_Char_Table_Entry *cte = XCHAR_TABLE_ENTRY (obj);
int i;
for (i = 0; i < 96; i++)
{
- markobj (cte->level2[i]);
+ mark_object (cte->level2[i]);
}
return Qnil;
}
#endif /* MULE */
static Lisp_Object
-mark_char_table (Lisp_Object obj, void (*markobj) (Lisp_Object))
+mark_char_table (Lisp_Object obj)
{
struct Lisp_Char_Table *ct = XCHAR_TABLE (obj);
int i;
for (i = 0; i < NUM_ASCII_CHARS; i++)
- markobj (ct->ascii[i]);
+ mark_object (ct->ascii[i]);
#ifdef MULE
for (i = 0; i < NUM_LEADING_BYTES; i++)
- markobj (ct->level1[i]);
+ mark_object (ct->level1[i]);
#endif
return ct->mirror_table;
}
and prune_weak_hash_tables(). */
void
-prune_syntax_tables (int (*obj_marked_p) (Lisp_Object))
+prune_syntax_tables (void)
{
Lisp_Object rest, prev = Qnil;
for (rest = Vall_syntax_tables;
- !GC_NILP (rest);
+ !NILP (rest);
rest = XCHAR_TABLE (rest)->next_table)
{
- if (! obj_marked_p (rest))
+ if (! marked_p (rest))
{
/* This table is garbage. Remove it from the list. */
- if (GC_NILP (prev))
+ if (NILP (prev))
Vall_syntax_tables = XCHAR_TABLE (rest)->next_table;
else
XCHAR_TABLE (prev)->next_table =
#ifdef MULE
{ XD_LISP_OBJECT, offsetof(struct Lisp_Char_Table, level1), NUM_LEADING_BYTES },
#endif
+ { XD_LISP_OBJECT, offsetof(struct Lisp_Char_Table, mirror_table), 1 },
+ { XD_LO_LINK, offsetof(struct Lisp_Char_Table, next_table) },
{ XD_END }
};
ctnew->mirror_table = Fcopy_char_table (ct->mirror_table);
else
ctnew->mirror_table = ct->mirror_table;
+ ctnew->next_table = Qnil;
XSETCHAR_TABLE (obj, ctnew);
+ if (ctnew->type == CHAR_TABLE_TYPE_SYNTAX)
+ {
+ ctnew->next_table = Vall_syntax_tables;
+ Vall_syntax_tables = obj;
+ }
return obj;
}
#define CATEGORYP(x) \
- (CHARP ((x)) && XCHAR ((x)) >= 0x20 && XCHAR ((x)) <= 0x7E)
+ (CHARP (x) && XCHAR (x) >= 0x20 && XCHAR (x) <= 0x7E)
#define CATEGORY_SET(c) \
(get_char_table(c, XCHAR_TABLE(current_buffer->category_table)))
Use the macro WORD_BOUNDARY_P instead of calling this function
directly. */
+int word_boundary_p (Emchar c1, Emchar c2);
int
word_boundary_p (Emchar c1, Emchar c2)
{
{
/* DO NOT staticpro this. It works just like Vweak_hash_tables. */
Vall_syntax_tables = Qnil;
+ pdump_wire_list (&Vall_syntax_tables);
}
void
XRECORD (x, char_table_entry, struct Lisp_Char_Table_Entry)
#define XSETCHAR_TABLE_ENTRY(x, p) XSETRECORD (x, p, char_table_entry)
#define CHAR_TABLE_ENTRYP(x) RECORDP (x, char_table_entry)
-#define GC_CHAR_TABLE_ENTRYP(x) GC_RECORDP (x, char_table_entry)
/* #define CHECK_CHAR_TABLE_ENTRY(x) CHECK_RECORD (x, char_table_entry)
char table entries should never escape to Lisp */
XRECORD (x, char_table, struct Lisp_Char_Table)
#define XSETCHAR_TABLE(x, p) XSETRECORD (x, p, char_table)
#define CHAR_TABLEP(x) RECORDP (x, char_table)
-#define GC_CHAR_TABLEP(x) GC_RECORDP (x, char_table)
#define CHECK_CHAR_TABLE(x) CHECK_RECORD (x, char_table)
#define CONCHECK_CHAR_TABLE(x) CONCHECK_RECORD (x, char_table)
int (*fn) (struct chartab_range *range,
Lisp_Object val, void *arg),
void *arg);
-void prune_syntax_tables (int (*obj_marked_p) (Lisp_Object));
+void prune_syntax_tables (void);
EXFUN (Fcopy_char_table, 1);
EXFUN (Fmake_char_table, 1);
/* Current depth in recursive edits. */
int command_loop_level;
-/* Total number of times command_loop has read a key sequence. */
-int num_input_keys;
-
#ifndef LISP_COMMAND_LOOP
/* Form to evaluate (if non-nil) when Emacs is started. */
Lisp_Object Vtop_level;
#undef HAVE_GETTIMEOFDAY
#undef HAVE_GETWD
#undef HAVE_GETCWD
+#undef HAVE_GETPT
#undef HAVE_LOGB
#undef HAVE_LRAND48
#undef HAVE_MATHERR
#undef HAVE_SIGPROCMASK
#undef HAVE_SIGSETJMP
#undef HAVE_SNPRINTF
+#undef HAVE_STPCPY
#undef HAVE_STRCASECMP
#undef HAVE_STRERROR
#undef HAVE_TZSET
#undef LWLIB_DIALOGS_MOTIF
#undef LWLIB_DIALOGS_ATHENA
#undef LWLIB_DIALOGS_ATHENA3D
+#undef LWLIB_TABS_LUCID
+#undef LWLIB_WIDGETS_MOTIF
+#undef LWLIB_WIDGETS_ATHENA
/* Other things that can be disabled by configure. */
#undef HAVE_MENUBARS
#undef HAVE_SCROLLBARS
#undef HAVE_DIALOGS
#undef HAVE_TOOLBARS
+#undef HAVE_WIDGETS
#if defined (HAVE_MENUBARS) || defined (HAVE_DIALOGS)
#undef INFODIR_USER_DEFINED
#undef INFOPATH_USER_DEFINED
+#undef PDUMP
+
#endif /* _SRC_CONFIG_H_ */
definition. In the garbage collector this file is included after
defining MARKED_SLOT(x) to be mark_object(console->x). */
+#ifndef CONSOLE_SLOTS_FIRST_NAME
+#define CONSOLE_SLOTS_FIRST_NAME name
+#endif
+
/* Name of this console, for resourcing and printing purposes.
If not explicitly given, it's initialized in a console-specific
manner. */
Initialized by the terminal-specific lisp files. */
MARKED_SLOT (function_key_map);
+#ifndef CONSOLE_SLOTS_LAST_NAME
+#define CONSOLE_SLOTS_LAST_NAME function_key_map
+#endif
}
void
+reinit_console_type_create_mswindows (void)
+{
+ REINITIALIZE_CONSOLE_TYPE (mswindows);
+}
+
+void
vars_of_console_mswindows (void)
{
Fprovide (Qmswindows);
#endif
#include <windows.h>
#include <ddeml.h> /* DDE management library */
-#if !defined (__CYGWIN32__) && !defined(__MINGW32__)
+#if !defined(__CYGWIN32__) && !defined(__MINGW32__)
#include <shellapi.h> /* FileManager/Explorer drag and drop */
#include <commctrl.h>
#endif
/* The name of the main window class */
#define XEMACS_CLASS "XEmacs"
+#define XEMACS_CONTROL_CLASS "XEmacsControl"
/*
* Console
/* win32 "Windows" procedure */
LRESULT WINAPI mswindows_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam,
LPARAM lParam);
+LRESULT WINAPI mswindows_control_wnd_proc (HWND hwnd,
+ UINT msg, WPARAM wParam,
+ LPARAM lParam);
void mswindows_redraw_exposed_area (struct frame *f, int x, int y,
int width, int height);
}
void
+reinit_console_type_create_stream (void)
+{
+ REINITIALIZE_CONSOLE_TYPE (stream);
+}
+
+void
vars_of_console_stream (void)
{
DEFVAR_LISP ("terminal-console", &Vterminal_console /*
staticpro (&Vstdio_str);
}
+#ifndef PDUMP
void
init_console_stream (void)
{
event_stream_select_console (XCONSOLE (Vterminal_console));
}
}
+
+#else
+
+void
+init_console_stream (void)
+{
+ /* This function can GC */
+ Vterminal_device = Fmake_device (Qstream, Qnil, Qnil);
+ Vterminal_console = Fdevice_console (Vterminal_device);
+ Vterminal_frame = Fmake_frame (Qnil, Vterminal_device);
+ minibuf_window = XFRAME (Vterminal_frame)->minibuffer_window;
+ if (initialized)
+ {
+ stream_init_console (XCONSOLE (Vterminal_console), Qnil);
+ if (noninteractive)
+ event_stream_select_console (XCONSOLE (Vterminal_console));
+ }
+}
+#endif
#define CONSOLE_STREAM_DATA(con) CONSOLE_TYPE_DATA (con, stream)
+extern Lisp_Object Vterminal_console, Vterminal_frame, Vterminal_device;
+
Lisp_Object stream_semi_canonicalize_console_connection(Lisp_Object,
Error_behavior);
Lisp_Object stream_canonicalize_console_connection(Lisp_Object,
}
static void
-tty_mark_console (struct console *con, void (*markobj) (Lisp_Object))
+tty_mark_console (struct console *con)
{
struct tty_console *tty_con = CONSOLE_TTY_DATA (con);
- markobj (tty_con->terminal_type);
- markobj (tty_con->instream);
- markobj (tty_con->outstream);
+ mark_object (tty_con->terminal_type);
+ mark_object (tty_con->instream);
+ mark_object (tty_con->outstream);
}
static int
}
void
+reinit_console_type_create_tty (void)
+{
+ REINITIALIZE_CONSOLE_TYPE (tty);
+}
+
+void
image_instantiator_format_create_glyphs_tty (void)
{
IIFORMAT_VALID_CONSOLE (tty, nothing);
CONSOLE_HAS_METHOD (x, initially_selected_for_input);
}
+
+void
+reinit_console_type_create_x (void)
+{
+ REINITIALIZE_CONSOLE_TYPE (x);
+}
extern Lisp_Object Vdefault_x_device;
/* Number of pixels below each line. */
-extern int x_interline_space;
+extern int x_interline_space; /* #### implement me */
extern int x_selection_timeout;
int cursor, int cursor_start, int cursor_width,
int cursor_height);
void x_output_x_pixmap (struct frame *f, struct Lisp_Image_Instance *p,
- int x, int y, int clip_x, int clip_y,
- int clip_width, int clip_height, int width,
- int height, int pixmap_offset,
+ int x, int y, int xoffset, int yoffset,
+ int width, int height,
unsigned long fg, unsigned long bg,
GC override_gc);
void x_output_shadows (struct frame *f, int x, int y, int width,
int height, GC top_shadow_gc,
GC bottom_shadow_gc, GC background_gc,
- int shadow_thickness);
+ int shadow_thickness, int edges);
void x_generate_shadow_pixels (struct frame *f,
unsigned long *top_shadow,
unsigned long *bottom_shadow,
void x_init_modifier_mapping (struct device *d);
#define X_ERROR_OCCURRED(dpy, body) \
- (expect_x_error ((dpy)), (body), x_error_occurred_p (dpy))
+ (expect_x_error (dpy), body, x_error_occurred_p (dpy))
#define HANDLING_X_ERROR(dpy, body) \
- ( expect_x_error ((dpy)), (body), signal_if_x_error ((dpy), 0))
+ (expect_x_error (dpy), body, signal_if_x_error (dpy, 0))
void Initialize_Locale (void);
list of consoles and stores into each console that does not say
it has a local value. */
Lisp_Object Vconsole_defaults;
+static void *console_defaults_saved_slots;
/* This structure marks which slots in a console have corresponding
default values in console_defaults.
consoles.
If a slot is -1, then there is a DEFVAR_CONSOLE_LOCAL for it
- as well as a default value which is used to initialize newly-created
+ as well as a default value which is used to initialize newly-created
consoles and as a reset-value when local-vars are killed.
If a slot is -2, there is no DEFVAR_CONSOLE_LOCAL for it.
/* This structure holds the names of symbols whose values may be
console-local. It is indexed and accessed in the same way as the above. */
static Lisp_Object Vconsole_local_symbols;
+static void *console_local_symbols_saved_slots;
DEFINE_CONSOLE_TYPE (dead);
\f
static Lisp_Object
-mark_console (Lisp_Object obj, void (*markobj) (Lisp_Object))
+mark_console (Lisp_Object obj)
{
struct console *con = XCONSOLE (obj);
-#define MARKED_SLOT(x) ((void) (markobj (con->x)));
+#define MARKED_SLOT(x) mark_object (con->x)
#include "conslots.h"
#undef MARKED_SLOT
/* Can be zero for Vconsole_defaults, Vconsole_local_symbols */
if (con->conmeths)
{
- markobj (con->conmeths->symbol);
- MAYBE_CONMETH (con, mark_console, (con, markobj));
+ mark_object (con->conmeths->symbol);
+ MAYBE_CONMETH (con, mark_console, (con));
}
return Qnil;
defsymbol (&Qsuspend_resume_hook, "suspend-resume-hook");
}
+static const struct lrecord_description cte_description_1[] = {
+ { XD_LISP_OBJECT, offsetof(console_type_entry, symbol), 1 },
+ { XD_STRUCT_PTR, offsetof(console_type_entry, meths), 1, &console_methods_description },
+ { XD_END }
+};
+
+static const struct struct_description cte_description = {
+ sizeof(console_type_entry),
+ cte_description_1
+};
+
+static const struct lrecord_description cted_description_1[] = {
+ XD_DYNARR_DESC(console_type_entry_dynarr, &cte_description),
+ { XD_END }
+};
+
+const struct struct_description cted_description = {
+ sizeof(console_type_entry_dynarr),
+ cted_description_1
+};
+
+static const struct lrecord_description console_methods_description_1[] = {
+ { XD_LISP_OBJECT, offsetof(struct console_methods, symbol), 2 },
+ { XD_LISP_OBJECT, offsetof(struct console_methods, image_conversion_list), 1 },
+ { XD_END }
+};
+
+const struct struct_description console_methods_description = {
+ sizeof(struct console_methods),
+ console_methods_description_1
+};
+
+
void
console_type_create (void)
{
the_console_type_entry_dynarr = Dynarr_new (console_type_entry);
+ dumpstruct(&the_console_type_entry_dynarr, &cted_description);
Vconsole_type_list = Qnil;
staticpro (&Vconsole_type_list);
}
void
+reinit_vars_of_console (void)
+{
+ staticpro_nodump (&Vconsole_list);
+ Vconsole_list = Qnil;
+ staticpro_nodump (&Vselected_console);
+ Vselected_console = Qnil;
+}
+
+void
vars_of_console (void)
{
+ reinit_vars_of_console ();
+
DEFVAR_LISP ("create-console-hook", &Vcreate_console_hook /*
Function or functions to call when a console is created.
One argument, the newly-created console.
*/ );
Vdelete_console_hook = Qnil;
- staticpro (&Vconsole_list);
- Vconsole_list = Qnil;
- staticpro (&Vselected_console);
- Vselected_console = Qnil;
-
#ifdef HAVE_WINDOW_SYSTEM
Fprovide (intern ("window-system"));
#endif
{
zero_lcrecord (con);
-#define MARKED_SLOT(x) con->x = (zap);
+#define MARKED_SLOT(x) con->x = zap
#include "conslots.h"
#undef MARKED_SLOT
}
-void
-complex_vars_of_console (void)
+static void
+common_init_complex_vars_of_console (void)
{
/* Make sure all markable slots in console_defaults
are initialized reasonably, so mark_console won't choke.
struct console *defs = alloc_lcrecord_type (struct console, &lrecord_console);
struct console *syms = alloc_lcrecord_type (struct console, &lrecord_console);
- staticpro (&Vconsole_defaults);
- staticpro (&Vconsole_local_symbols);
+ staticpro_nodump (&Vconsole_defaults);
+ staticpro_nodump (&Vconsole_local_symbols);
XSETCONSOLE (Vconsole_defaults, defs);
XSETCONSOLE (Vconsole_local_symbols, syms);
currently allowable due to the XINT() handling of this value.
With some rearrangement you can get 4 more bits. */
}
+}
+
+
+#define CONSOLE_SLOTS_SIZE (offsetof (struct console, CONSOLE_SLOTS_LAST_NAME) - offsetof (struct console, CONSOLE_SLOTS_FIRST_NAME) + sizeof (Lisp_Object))
+#define CONSOLE_SLOTS_COUNT (CONSOLE_SLOTS_SIZE / sizeof (Lisp_Object))
+
+void
+reinit_complex_vars_of_console (void)
+{
+ struct console *defs, *syms;
+
+ common_init_complex_vars_of_console ();
+
+ defs = XCONSOLE (Vconsole_defaults);
+ syms = XCONSOLE (Vconsole_local_symbols);
+ memcpy (&defs->CONSOLE_SLOTS_FIRST_NAME,
+ console_defaults_saved_slots,
+ CONSOLE_SLOTS_SIZE);
+ memcpy (&syms->CONSOLE_SLOTS_FIRST_NAME,
+ console_local_symbols_saved_slots,
+ CONSOLE_SLOTS_SIZE);
+}
+
+
+static const struct lrecord_description console_slots_description_1[] = {
+ { XD_LISP_OBJECT, 0, CONSOLE_SLOTS_COUNT },
+ { XD_END }
+};
+
+static const struct struct_description console_slots_description = {
+ CONSOLE_SLOTS_SIZE,
+ console_slots_description_1
+};
+
+void
+complex_vars_of_console (void)
+{
+ struct console *defs, *syms;
+
+ common_init_complex_vars_of_console ();
+
+ defs = XCONSOLE (Vconsole_defaults);
+ syms = XCONSOLE (Vconsole_local_symbols);
+ console_defaults_saved_slots = &defs->CONSOLE_SLOTS_FIRST_NAME;
+ console_local_symbols_saved_slots = &syms->CONSOLE_SLOTS_FIRST_NAME;
+ dumpstruct (&console_defaults_saved_slots, &console_slots_description);
+ dumpstruct (&console_local_symbols_saved_slots, &console_slots_description);
DEFVAR_CONSOLE_DEFAULTS ("default-function-key-map", function_key_map /*
Default value of `function-key-map' for consoles that don't override it.
DM_slow_device, DM_security
};
+extern const struct struct_description cted_description;
+extern const struct struct_description console_methods_description;
+
struct console_methods
{
CONST char *name; /* Used by print_console, print_device, print_frame */
/* console methods */
void (*init_console_method) (struct console *, Lisp_Object props);
- void (*mark_console_method) (struct console *, void (*)(Lisp_Object));
+ void (*mark_console_method) (struct console *);
int (*initially_selected_for_input_method) (struct console *);
void (*delete_console_method) (struct console *);
Lisp_Object (*semi_canonicalize_console_connection_method)
void (*init_device_method) (struct device *, Lisp_Object props);
void (*finish_init_device_method) (struct device *, Lisp_Object props);
void (*delete_device_method) (struct device *);
- void (*mark_device_method) (struct device *, void (*)(Lisp_Object));
+ void (*mark_device_method) (struct device *);
void (*asynch_device_change_method) (void);
Lisp_Object (*device_system_metrics_method) (struct device *, enum device_metrics);
unsigned int (*device_implementation_flags_method) (void);
void (*init_frame_3_method) (struct frame *);
void (*after_init_frame_method) (struct frame *, int first_on_device,
int first_on_console);
- void (*mark_frame_method) (struct frame *, void (*)(Lisp_Object));
+ void (*mark_frame_method) (struct frame *);
void (*delete_frame_method) (struct frame *);
void (*focus_on_frame_method) (struct frame *);
void (*raise_frame_method) (struct frame *);
int duration);
void (*frame_redraw_cursor_method) (struct frame *f);
void (*set_final_cursor_coords_method) (struct frame *, int, int);
- void (*bevel_area_method) (struct window *, face_index, int, int, int, int, int);
-
+ void (*bevel_area_method) (struct window *, face_index, int, int, int, int, int,
+ int, enum edge_style);
+ void (*output_pixmap_method) (struct window *w, Lisp_Object image_instance,
+ struct display_box *db, struct display_glyph_area *dga,
+ face_index findex, int cursor_start, int cursor_width,
+ int cursor_height, int offset_bitmap);
+ void (*output_string_method) (struct window *w, struct display_line *dl,
+ Emchar_dynarr *buf, int xpos, int xoffset,
+ int start_pixpos, int width, face_index findex,
+ int cursor, int cursor_start, int cursor_width,
+ int cursor_height);
/* color methods */
int (*initialize_color_instance_method) (struct Lisp_Color_Instance *,
Lisp_Object name,
Lisp_Object device,
Error_behavior errb);
- void (*mark_color_instance_method) (struct Lisp_Color_Instance *,
- void (*)(Lisp_Object));
+ void (*mark_color_instance_method) (struct Lisp_Color_Instance *);
void (*print_color_instance_method) (struct Lisp_Color_Instance *,
Lisp_Object printcharfun,
int escapeflag);
Lisp_Object name,
Lisp_Object device,
Error_behavior errb);
- void (*mark_font_instance_method) (struct Lisp_Font_Instance *,
- void (*)(Lisp_Object));
+ void (*mark_font_instance_method) (struct Lisp_Font_Instance *);
void (*print_font_instance_method) (struct Lisp_Font_Instance *,
Lisp_Object printcharfun,
int escapeflag);
Bytecount length);
/* image methods */
- void (*mark_image_instance_method) (struct Lisp_Image_Instance *,
- void (*)(Lisp_Object));
+ void (*mark_image_instance_method) (struct Lisp_Image_Instance *);
void (*print_image_instance_method) (struct Lisp_Image_Instance *,
Lisp_Object printcharfun,
int escapeflag);
void (*finalize_image_instance_method) (struct Lisp_Image_Instance *);
void (*unmap_subwindow_method) (struct Lisp_Image_Instance *);
- void (*map_subwindow_method) (struct Lisp_Image_Instance *, int x, int y);
+ void (*map_subwindow_method) (struct Lisp_Image_Instance *, int x, int y,
+ struct display_glyph_area* dga);
void (*resize_subwindow_method) (struct Lisp_Image_Instance *, int w, int h);
void (*update_subwindow_method) (struct Lisp_Image_Instance *);
int (*image_instance_equal_method) (struct Lisp_Image_Instance *,
int depth);
void (*init_image_instance_from_eimage_method) (struct Lisp_Image_Instance *ii,
int width, int height,
+ int slices,
unsigned char *eimage,
int dest_mask,
Lisp_Object instantiator,
type##_console_methods = xnew_and_zero (struct console_methods); \
type##_console_methods->name = obj_name; \
type##_console_methods->symbol = Q##type; \
- defsymbol (&type##_console_methods->predicate_symbol, pred_sym); \
+ defsymbol_nodump (&type##_console_methods->predicate_symbol, pred_sym); \
add_entry_to_console_type_list (Q##type, type##_console_methods); \
type##_console_methods->image_conversion_list = Qnil; \
- staticpro (&type##_console_methods->image_conversion_list); \
+ staticpro_nodump (&type##_console_methods->image_conversion_list); \
+ dumpstruct (&type##_console_methods, &console_methods_description); \
} while (0)
+#define REINITIALIZE_CONSOLE_TYPE(type) do { \
+ staticpro_nodump (&type##_console_methods->predicate_symbol); \
+ staticpro_nodump (&type##_console_methods->image_conversion_list); \
+} while (0)
+
+
/* Declare that console-type TYPE has method M; used in
initialization routines */
#define CONSOLE_HAS_METHOD(type, m) \
#define XCONSOLE(x) XRECORD (x, console, struct console)
#define XSETCONSOLE(x, p) XSETRECORD (x, p, console)
#define CONSOLEP(x) RECORDP (x, console)
-#define GC_CONSOLEP(x) GC_RECORDP (x, console)
#define CHECK_CONSOLE(x) CHECK_RECORD (x, console)
#define CONCHECK_CONSOLE(x) CONCHECK_RECORD (x, console)
Lisp_Object Qarith_error, Qrange_error, Qdomain_error;
Lisp_Object Qsingularity_error, Qoverflow_error, Qunderflow_error;
Lisp_Object Qbeginning_of_buffer, Qend_of_buffer, Qbuffer_read_only;
-Lisp_Object Qintegerp, Qnatnump, Qsymbolp, Qkeywordp;
+Lisp_Object Qintegerp, Qnatnump, Qsymbolp;
Lisp_Object Qlistp, Qtrue_list_p, Qweak_listp;
Lisp_Object Qconsp, Qsubrp;
Lisp_Object Qcharacterp, Qstringp, Qarrayp, Qsequencep, Qvectorp;
Lisp_Object Qchar_or_string_p, Qmarkerp, Qinteger_or_marker_p, Qbufferp;
Lisp_Object Qinteger_or_char_p, Qinteger_char_or_marker_p;
-Lisp_Object Qnumberp, Qnumber_or_marker_p, Qnumber_char_or_marker_p;
-Lisp_Object Qbit_vectorp, Qbitp, Qcons, Qkeyword, Qcdr, Qignore;
+Lisp_Object Qnumberp, Qnumber_char_or_marker_p;
+Lisp_Object Qbit_vectorp, Qbitp, Qcdr;
Lisp_Object Qfloatp;
}
void
-check_int_range (int val, int min, int max)
+check_int_range (EMACS_INT val, EMACS_INT min, EMACS_INT max)
{
if (val < min || val > max)
args_out_of_range_3 (make_int (val), make_int (min), make_int (max));
/* On a few machines, XINT can only be done by calling this. */
/* XEmacs: only used by m/convex.h */
-int sign_extend_lisp_int (EMACS_INT num);
-int
+EMACS_INT sign_extend_lisp_int (EMACS_INT num);
+EMACS_INT
sign_extend_lisp_int (EMACS_INT num)
{
if (num & (1L << (VALBITS - 1)))
if (!CONSP (conscell))
conscell = wrong_type_argument (Qconsp, conscell);
- CHECK_LISP_WRITEABLE (conscell);
XCAR (conscell) = newcar;
return newcar;
}
if (!CONSP (conscell))
conscell = wrong_type_argument (Qconsp, conscell);
- CHECK_LISP_WRITEABLE (conscell);
XCDR (conscell) = newcdr;
return newcdr;
}
*/
(array, index_))
{
- int idx;
+ EMACS_INT idx;
retry:
*/
(array, index_, newval))
{
- int idx;
+ EMACS_INT idx;
retry:
if (idx < 0) goto range_error;
- CHECK_LISP_WRITEABLE (array);
-
if (VECTORP (array))
{
if (idx >= XVECTOR_LENGTH (array)) goto range_error;
}
}
-static int
+static EMACS_INT
integer_char_or_marker_to_int (Lisp_Object obj)
{
retry:
*/
(num1, num2))
{
- int ival1 = integer_char_or_marker_to_int (num1);
- int ival2 = integer_char_or_marker_to_int (num2);
+ EMACS_INT ival1 = integer_char_or_marker_to_int (num1);
+ EMACS_INT ival2 = integer_char_or_marker_to_int (num2);
if (ival2 == 0)
Fsignal (Qarith_error, Qnil);
}
#endif /* LISP_FLOAT_TYPE */
{
- int ival;
+ EMACS_INT ival;
if (iod2.c.ival == 0) goto divide_by_zero;
ival = iod1.c.ival % iod2.c.ival;
static Lisp_Object encode_weak_list_type (enum weak_list_type type);
static Lisp_Object
-mark_weak_list (Lisp_Object obj, void (*markobj) (Lisp_Object))
+mark_weak_list (Lisp_Object obj)
{
return Qnil; /* nichts ist gemarkt */
}
static const struct lrecord_description weak_list_description[] = {
{ XD_LISP_OBJECT, offsetof(struct weak_list, list), 1 },
- { XD_LISP_OBJECT, offsetof(struct weak_list, next_weak), 1 },
+ { XD_LO_LINK, offsetof(struct weak_list, next_weak) },
{ XD_END }
};
*/
int
-finish_marking_weak_lists (int (*obj_marked_p) (Lisp_Object),
- void (*markobj) (Lisp_Object))
+finish_marking_weak_lists (void)
{
Lisp_Object rest;
int did_mark = 0;
for (rest = Vall_weak_lists;
- !GC_NILP (rest);
+ !NILP (rest);
rest = XWEAK_LIST (rest)->next_weak)
{
Lisp_Object rest2;
enum weak_list_type type = XWEAK_LIST (rest)->type;
- if (! obj_marked_p (rest))
+ if (! marked_p (rest))
/* The weak list is probably garbage. Ignore it. */
continue;
/* We need to be trickier since we're inside of GC;
use CONSP instead of !NILP in case of user-visible
imperfect lists */
- GC_CONSP (rest2);
+ CONSP (rest2);
rest2 = XCDR (rest2))
{
Lisp_Object elem;
(either because of an external pointer or because of
a previous call to this function), and likewise for all
the rest of the elements in the list, so we can stop now. */
- if (obj_marked_p (rest2))
+ if (marked_p (rest2))
break;
elem = XCAR (rest2);
switch (type)
{
case WEAK_LIST_SIMPLE:
- if (obj_marked_p (elem))
+ if (marked_p (elem))
need_to_mark_cons = 1;
break;
case WEAK_LIST_ASSOC:
- if (!GC_CONSP (elem))
+ if (!CONSP (elem))
{
/* just leave bogus elements there */
need_to_mark_cons = 1;
need_to_mark_elem = 1;
}
- else if (obj_marked_p (XCAR (elem)) &&
- obj_marked_p (XCDR (elem)))
+ else if (marked_p (XCAR (elem)) &&
+ marked_p (XCDR (elem)))
{
need_to_mark_cons = 1;
/* We still need to mark elem, because it's
break;
case WEAK_LIST_KEY_ASSOC:
- if (!GC_CONSP (elem))
+ if (!CONSP (elem))
{
/* just leave bogus elements there */
need_to_mark_cons = 1;
need_to_mark_elem = 1;
}
- else if (obj_marked_p (XCAR (elem)))
+ else if (marked_p (XCAR (elem)))
{
need_to_mark_cons = 1;
/* We still need to mark elem and XCDR (elem);
break;
case WEAK_LIST_VALUE_ASSOC:
- if (!GC_CONSP (elem))
+ if (!CONSP (elem))
{
/* just leave bogus elements there */
need_to_mark_cons = 1;
need_to_mark_elem = 1;
}
- else if (obj_marked_p (XCDR (elem)))
+ else if (marked_p (XCDR (elem)))
{
need_to_mark_cons = 1;
/* We still need to mark elem and XCAR (elem);
abort ();
}
- if (need_to_mark_elem && ! obj_marked_p (elem))
+ if (need_to_mark_elem && ! marked_p (elem))
{
- markobj (elem);
+ mark_object (elem);
did_mark = 1;
}
/* We also need to mark the cons that holds the elem or
- assoc-pair. We do *not* want to call (markobj) here
+ assoc-pair. We do *not* want to call (mark_object) here
because that will mark the entire list; we just want to
mark the cons itself.
*/
if (need_to_mark_cons)
{
- struct Lisp_Cons *ptr = XCONS (rest2);
- if (!CONS_MARKED_P (ptr))
+ Lisp_Cons *c = XCONS (rest2);
+ if (!CONS_MARKED_P (c))
{
- MARK_CONS (ptr);
+ MARK_CONS (c);
did_mark = 1;
}
}
/* In case of imperfect list, need to mark the final cons
because we're not removing it */
- if (!GC_NILP (rest2) && ! obj_marked_p (rest2))
+ if (!NILP (rest2) && ! marked_p (rest2))
{
- markobj (rest2);
+ mark_object (rest2);
did_mark = 1;
}
}
}
void
-prune_weak_lists (int (*obj_marked_p) (Lisp_Object))
+prune_weak_lists (void)
{
Lisp_Object rest, prev = Qnil;
for (rest = Vall_weak_lists;
- !GC_NILP (rest);
+ !NILP (rest);
rest = XWEAK_LIST (rest)->next_weak)
{
- if (! (obj_marked_p (rest)))
+ if (! (marked_p (rest)))
{
/* This weak list itself is garbage. Remove it from the list. */
- if (GC_NILP (prev))
+ if (NILP (prev))
Vall_weak_lists = XWEAK_LIST (rest)->next_weak;
else
XWEAK_LIST (prev)->next_weak =
/* We need to be trickier since we're inside of GC;
use CONSP instead of !NILP in case of user-visible
imperfect lists */
- GC_CONSP (rest2);)
+ CONSP (rest2);)
{
/* It suffices to check the cons for marking,
regardless of the type of weak list:
have been marked in finish_marking_weak_lists().
-- otherwise, it's not marked and should disappear.
*/
- if (! obj_marked_p (rest2))
+ if (! marked_p (rest2))
{
/* bye bye :-( */
- if (GC_NILP (prev2))
+ if (NILP (prev2))
XWEAK_LIST (rest)->list = XCDR (rest2);
else
XCDR (prev2) = XCDR (rest2);
if (go_tortoise)
tortoise = XCDR (tortoise);
go_tortoise = !go_tortoise;
- if (GC_EQ (rest2, tortoise))
+ if (EQ (rest2, tortoise))
break;
}
}
void
syms_of_data (void)
{
- defsymbol (&Qcons, "cons");
- defsymbol (&Qkeyword, "keyword");
defsymbol (&Qquote, "quote");
defsymbol (&Qlambda, "lambda");
- defsymbol (&Qignore, "ignore");
defsymbol (&Qlistp, "listp");
defsymbol (&Qtrue_list_p, "true-list-p");
defsymbol (&Qconsp, "consp");
defsymbol (&Qsubrp, "subrp");
defsymbol (&Qsymbolp, "symbolp");
- defsymbol (&Qkeywordp, "keywordp");
defsymbol (&Qintegerp, "integerp");
defsymbol (&Qcharacterp, "characterp");
defsymbol (&Qnatnump, "natnump");
defsymbol (&Qinteger_or_char_p, "integer-or-char-p");
defsymbol (&Qinteger_char_or_marker_p, "integer-char-or-marker-p");
defsymbol (&Qnumberp, "numberp");
- defsymbol (&Qnumber_or_marker_p, "number-or-marker-p");
defsymbol (&Qnumber_char_or_marker_p, "number-char-or-marker-p");
defsymbol (&Qcdr, "cdr");
defsymbol (&Qweak_listp, "weak-list-p");
{
/* This must not be staticpro'd */
Vall_weak_lists = Qnil;
+ pdump_wire_list (&Vall_weak_lists);
#ifdef DEBUG_XEMACS
DEFVAR_BOOL ("debug-issue-ebola-notices", &debug_issue_ebola_notices /*
}
static Lisp_Object
-mark_database (Lisp_Object obj, void (*markobj) (Lisp_Object))
+mark_database (Lisp_Object obj)
{
Lisp_Database *db = XDATABASE (obj);
-
- markobj (db->fname);
- return Qnil;
+ return db->fname;
}
static void
* 4. Add a FROB line for it in xemacs_debug_loop.
*/
-Lisp_Object Qredisplay, Qbuffers, Qfaces;
-Lisp_Object Qwindows, Qframes, Qdevices;
+static Lisp_Object Qredisplay, Qbuffers, Qfaces, Qwindows, Qframes, Qdevices;
struct debug_classes active_debug_classes;
defsymbol (&Qwindows, "windows");
defsymbol (&Qframes, "frames");
defsymbol (&Qdevices, "devices");
- /* defsymbol (&Qbyte_code, "byte-code"); in bytecode.c */
DEFSUBR (Fadd_debug_class_to_check);
DEFSUBR (Fdelete_debug_class_to_check);
}
void
-vars_of_debug (void)
+reinit_vars_of_debug (void)
{
/* If you need to have any classes active early on in startup, then
the flags should be set here.
to emacs.c. */
xemacs_debug_loop (INIT, Qnil, Qnil);
}
+
+void
+vars_of_debug (void)
+{
+ reinit_vars_of_debug ();
+}
unsigned int types_of_byte_code;
};
-extern Lisp_Object Qbuffers, Qdevices, Qfaces, Qframes, Qredisplay, Qwindows;
-
extern struct debug_classes active_debug_classes;
#define DASSERT(class, desired_type, action, assertion) do \
menubar-x.o: $(LISP_H) $(LWLIB_SRCDIR)/lwlib.h EmacsFrame.h buffer.h bufslots.h commands.h conslots.h console-x.h console.h device.h events.h frame.h frameslots.h glyphs.h gui-x.h gui.h lisp-disunion.h lisp-union.h lrecord.h mule-charset.h opaque.h redisplay.h scrollbar.h specifier.h symeval.h symsinit.h systime.h toolbar.h window.h winslots.h xintrinsic.h
objects-x.o: $(LISP_H) buffer.h bufslots.h conslots.h console-x.h console.h device.h insdel.h lisp-disunion.h lisp-union.h lrecord.h mule-charset.h objects-x.h objects.h specifier.h symeval.h symsinit.h xintrinsic.h
redisplay-x.o: $(LISP_H) $(LWLIB_SRCDIR)/lwlib.h EmacsFrame.h EmacsFrameP.h buffer.h bufslots.h conslots.h console-x.h console.h debug.h device.h faces.h file-coding.h frame.h frameslots.h glyphs-x.h glyphs.h gui.h gutter.h lisp-disunion.h lisp-union.h lrecord.h mule-ccl.h mule-charset.h objects-x.h objects.h redisplay.h scrollbar.h specifier.h symeval.h symsinit.h sysdep.h sysproc.h systime.h toolbar.h window.h winslots.h xgccache.h xintrinsic.h xintrinsicp.h xmprimitivep.h
-scrollbar-x.o: $(LISP_H) $(LWLIB_SRCDIR)/lwlib.h conslots.h console-x.h console.h device.h frame.h frameslots.h glyphs-x.h glyphs.h gui-x.h gui.h lisp-disunion.h lisp-union.h lrecord.h redisplay.h scrollbar-x.h scrollbar.h specifier.h symeval.h symsinit.h toolbar.h window.h winslots.h xintrinsic.h
+scrollbar-x.o: $(LISP_H) $(LWLIB_SRCDIR)/lwlib.h EmacsFrame.h conslots.h console-x.h console.h device.h frame.h frameslots.h glyphs-x.h glyphs.h gui-x.h gui.h lisp-disunion.h lisp-union.h lrecord.h redisplay.h scrollbar-x.h scrollbar.h specifier.h symeval.h symsinit.h toolbar.h window.h winslots.h xintrinsic.h
select-x.o: $(LISP_H) buffer.h bufslots.h conslots.h console-x.h console.h device.h frame.h frameslots.h glyphs.h gui.h lisp-disunion.h lisp-union.h lrecord.h mule-charset.h objects-x.h objects.h opaque.h redisplay.h scrollbar.h select.h specifier.h symeval.h symsinit.h systime.h toolbar.h xintrinsic.h
toolbar-x.o: $(LISP_H) $(LWLIB_SRCDIR)/lwlib.h EmacsFrame.h EmacsFrameP.h buffer.h bufslots.h conslots.h console-x.h console.h device.h faces.h frame.h frameslots.h glyphs-x.h glyphs.h gui.h lisp-disunion.h lisp-union.h lrecord.h mule-charset.h objects-x.h objects.h redisplay.h scrollbar.h specifier.h symeval.h symsinit.h toolbar.h window.h winslots.h xintrinsic.h xintrinsicp.h xmprimitivep.h
#endif
#ifdef MULE
mule-canna.o: $(LISP_H) buffer.h bufslots.h file-coding.h lisp-disunion.h lisp-union.h lrecord.h mule-charset.h symeval.h symsinit.h
mule-ccl.o: $(LISP_H) buffer.h bufslots.h file-coding.h lisp-disunion.h lisp-union.h lrecord.h mule-ccl.h mule-charset.h symeval.h symsinit.h
-mule-charset.o: $(LISP_H) buffer.h bufslots.h chartab.h conslots.h console.h device.h elhash.h faces.h lisp-disunion.h lisp-union.h lrecord.h lstream.h mule-charset.h symeval.h symsinit.h
+mule-charset.o: $(LISP_H) buffer.h bufslots.h chartab.h conslots.h console.h device.h elhash.h faces.h lisp-disunion.h lisp-union.h lrecord.h lstream.h mule-ccl.h mule-charset.h symeval.h symsinit.h
mule-mcpath.o: $(LISP_H) buffer.h bufslots.h lisp-disunion.h lisp-union.h lrecord.h mule-charset.h symeval.h symsinit.h sysfile.h
mule-wnnfns.o: $(LISP_H) buffer.h bufslots.h lisp-disunion.h lisp-union.h lrecord.h mule-charset.h redisplay.h scrollbar.h symeval.h symsinit.h sysdep.h window.h winslots.h
mule.o: $(LISP_H) lisp-disunion.h lisp-union.h lrecord.h regex.h symeval.h symsinit.h
gif_io.o: gifrlib.h
glyphs-eimage.o: $(LISP_H) buffer.h bufslots.h conslots.h console.h device.h faces.h file-coding.h frame.h frameslots.h gifrlib.h glyphs.h gui.h lisp-disunion.h lisp-union.h lrecord.h lstream.h mule-charset.h objects.h opaque.h redisplay.h scrollbar.h specifier.h symeval.h symsinit.h sysfile.h toolbar.h
glyphs-widget.o: $(LISP_H) buffer.h bufslots.h bytecode.h conslots.h console.h device.h faces.h frame.h frameslots.h glyphs.h gui.h insdel.h lisp-disunion.h lisp-union.h lrecord.h lstream.h mule-charset.h objects.h opaque.h redisplay.h scrollbar.h specifier.h symeval.h symsinit.h toolbar.h window.h winslots.h
-glyphs.o: $(LISP_H) buffer.h bufslots.h chartab.h conslots.h console.h device.h elhash.h faces.h frame.h frameslots.h glyphs.h gui.h insdel.h lisp-disunion.h lisp-union.h lrecord.h mule-charset.h objects.h opaque.h rangetab.h redisplay.h scrollbar.h specifier.h symeval.h symsinit.h toolbar.h window.h winslots.h
+glyphs.o: $(LISP_H) blocktype.h buffer.h bufslots.h chartab.h conslots.h console.h device.h elhash.h faces.h frame.h frameslots.h glyphs.h gui.h insdel.h lisp-disunion.h lisp-union.h lrecord.h mule-charset.h objects.h opaque.h rangetab.h redisplay.h scrollbar.h specifier.h symeval.h symsinit.h toolbar.h window.h winslots.h
gmalloc.o: config.h getpagesize.h
gpmevent.o: $(LISP_H) conslots.h console-tty.h console.h device.h events-mod.h events.h gpmevent.h lisp-disunion.h lisp-union.h lrecord.h symeval.h symsinit.h sysdep.h syssignal.h systime.h systty.h
gui.o: $(LISP_H) bytecode.h elhash.h gui.h lisp-disunion.h lisp-union.h lrecord.h symeval.h symsinit.h
redisplay-tty.o: $(LISP_H) buffer.h bufslots.h conslots.h console-tty.h console.h device.h events.h faces.h frame.h frameslots.h glyphs.h gui.h lisp-disunion.h lisp-union.h lrecord.h lstream.h mule-charset.h objects-tty.h objects.h redisplay.h scrollbar.h specifier.h symeval.h symsinit.h sysdep.h syssignal.h systime.h systty.h toolbar.h window.h winslots.h
redisplay.o: $(LISP_H) buffer.h bufslots.h commands.h conslots.h console-tty.h console.h debug.h device.h elhash.h extents.h faces.h file-coding.h frame.h frameslots.h glyphs.h gui.h gutter.h insdel.h line-number.h lisp-disunion.h lisp-union.h lrecord.h menubar.h mule-charset.h objects.h process.h redisplay.h scrollbar.h specifier.h symeval.h symsinit.h syssignal.h systty.h toolbar.h window.h winslots.h
regex.o: $(LISP_H) buffer.h bufslots.h chartab.h lisp-disunion.h lisp-union.h lrecord.h mule-charset.h regex.h symeval.h symsinit.h syntax.h
-scrollbar.o: $(LISP_H) buffer.h bufslots.h commands.h conslots.h console.h device.h frame.h frameslots.h glyphs.h gui.h lisp-disunion.h lisp-union.h lrecord.h mule-charset.h redisplay.h scrollbar.h specifier.h symeval.h symsinit.h toolbar.h window.h winslots.h
+scrollbar.o: $(LISP_H) buffer.h bufslots.h commands.h conslots.h console.h device.h frame.h frameslots.h glyphs.h gui.h gutter.h lisp-disunion.h lisp-union.h lrecord.h mule-charset.h redisplay.h scrollbar.h specifier.h symeval.h symsinit.h toolbar.h window.h winslots.h
search.o: $(LISP_H) buffer.h bufslots.h chartab.h insdel.h lisp-disunion.h lisp-union.h lrecord.h mule-charset.h opaque.h regex.h symeval.h symsinit.h syntax.h
select.o: $(LISP_H) buffer.h bufslots.h conslots.h console.h device.h frame.h frameslots.h glyphs.h gui.h lisp-disunion.h lisp-union.h lrecord.h mule-charset.h objects.h opaque.h redisplay.h scrollbar.h select.h specifier.h symeval.h symsinit.h toolbar.h
sgiplay.o: $(LISP_H) libst.h lisp-disunion.h lisp-union.h lrecord.h symeval.h symsinit.h
wc.lpfnWndProc = (WNDPROC) mswindows_wnd_proc;
wc.cbClsExtra = 0;
wc.cbWndExtra = MSWINDOWS_WINDOW_EXTRA_BYTES;
- wc.hInstance = NULL; /* ? */
+ /* This must match whatever is passed to CreateWIndowEx, NULL is ok
+ for this. */
+ wc.hInstance = NULL;
wc.hIcon = LoadIcon (GetModuleHandle(NULL), XEMACS_CLASS);
wc.hCursor = LoadCursor (NULL, IDC_ARROW);
/* Background brush is only used during sizing, when XEmacs cannot
wc.hIconSm = LoadImage (GetModuleHandle (NULL), XEMACS_CLASS,
IMAGE_ICON, 16, 16, 0);
RegisterClassEx (&wc);
+
+#ifdef HAVE_WIDGETS
+ xzero (wc);
+ /* Register the main window class */
+ wc.cbSize = sizeof (WNDCLASSEX);
+ wc.lpfnWndProc = (WNDPROC) mswindows_control_wnd_proc;
+ wc.lpszClassName = XEMACS_CONTROL_CLASS;
+ wc.hInstance = NULL;
+ RegisterClassEx (&wc);
+#endif
+
#ifdef HAVE_TOOLBARS
InitCommonControls ();
#endif
}
static void
-x_mark_device (struct device *d, void (*markobj) (Lisp_Object))
+x_mark_device (struct device *d)
{
- markobj (DEVICE_X_WM_COMMAND_FRAME (d));
- markobj (DEVICE_X_DATA (d)->x_keysym_map_hash_table);
+ mark_object (DEVICE_X_WM_COMMAND_FRAME (d));
+ mark_object (DEVICE_X_DATA (d)->x_keysym_map_hash_table);
}
\f
}
void
+reinit_console_type_create_device_x (void)
+{
+ /* Initialize variables to speed up X resource interactions */
+ CONST char *valid_resource_chars =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
+ while (*valid_resource_chars)
+ valid_resource_char_p[(unsigned int) (*valid_resource_chars++)] = 1;
+
+ name_char_dynarr = Dynarr_new (char);
+ class_char_dynarr = Dynarr_new (char);
+}
+
+void
console_type_create_device_x (void)
{
+ reinit_console_type_create_device_x ();
CONSOLE_HAS_METHOD (x, init_device);
CONSOLE_HAS_METHOD (x, finish_init_device);
CONSOLE_HAS_METHOD (x, mark_device);
CONSOLE_HAS_METHOD (x, delete_device);
CONSOLE_HAS_METHOD (x, device_system_metrics);
+}
- {
- /* Initialize variables to speed up X resource interactions */
- CONST char *valid_resource_chars =
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
- while (*valid_resource_chars)
- valid_resource_char_p[(unsigned int) (*valid_resource_chars++)] = 1;
-
- name_char_dynarr = Dynarr_new (char);
- class_char_dynarr = Dynarr_new (char);
- }
+void
+reinit_vars_of_device_x (void)
+{
+ error_expected = 0;
+ error_occurred = 0;
+
+ in_resource_setting = 0;
}
void
vars_of_device_x (void)
{
+ reinit_vars_of_device_x ();
+
DEFVAR_LISP ("x-emacs-application-class", &Vx_emacs_application_class /*
The X application class of the XEmacs process.
This controls, among other things, the name of the `app-defaults' file
staticpro (&Vdefault_x_device);
Vdefault_x_device = Qnil;
-
- error_expected = 0;
- error_occurred = 0;
-
- in_resource_setting = 0;
}
Qslow_device, Qsecurity;
Lisp_Object Qdevicep, Qdevice_live_p;
-Lisp_Object Qdelete_device;
Lisp_Object Qcreate_device_hook;
Lisp_Object Qdelete_device_hook;
Lisp_Object Vdevice_class_list;
\f
static Lisp_Object
-mark_device (Lisp_Object obj, void (*markobj) (Lisp_Object))
+mark_device (Lisp_Object obj)
{
struct device *d = XDEVICE (obj);
- markobj (d->name);
- markobj (d->connection);
- markobj (d->canon_connection);
- markobj (d->console);
- markobj (d->selected_frame);
- markobj (d->frame_with_focus_real);
- markobj (d->frame_with_focus_for_hooks);
- markobj (d->frame_that_ought_to_have_focus);
- markobj (d->device_class);
- markobj (d->user_defined_tags);
- markobj (d->pixel_to_glyph_cache.obj1);
- markobj (d->pixel_to_glyph_cache.obj2);
-
- markobj (d->color_instance_cache);
- markobj (d->font_instance_cache);
+ mark_object (d->name);
+ mark_object (d->connection);
+ mark_object (d->canon_connection);
+ mark_object (d->console);
+ mark_object (d->selected_frame);
+ mark_object (d->frame_with_focus_real);
+ mark_object (d->frame_with_focus_for_hooks);
+ mark_object (d->frame_that_ought_to_have_focus);
+ mark_object (d->device_class);
+ mark_object (d->user_defined_tags);
+ mark_object (d->pixel_to_glyph_cache.obj1);
+ mark_object (d->pixel_to_glyph_cache.obj2);
+
+ mark_object (d->color_instance_cache);
+ mark_object (d->font_instance_cache);
#ifdef MULE
- markobj (d->charset_font_cache);
+ mark_object (d->charset_font_cache);
#endif
- markobj (d->image_instance_cache);
+ mark_object (d->image_instance_cache);
if (d->devmeths)
{
- markobj (d->devmeths->symbol);
- MAYBE_DEVMETH (d, mark_device, (d, markobj));
+ mark_object (d->devmeths->symbol);
+ MAYBE_DEVMETH (d, mark_device, (d));
}
return (d->frame_list);
defsymbol (&Qdevicep, "devicep");
defsymbol (&Qdevice_live_p, "device-live-p");
- defsymbol (&Qdelete_device, "delete-device");
defsymbol (&Qcreate_device_hook, "create-device-hook");
defsymbol (&Qdelete_device_hook, "delete-device-hook");
}
void
+reinit_vars_of_device (void)
+{
+ staticpro_nodump (&Vdefault_device);
+ Vdefault_device = Qnil;
+ asynch_device_change_pending = 0;
+}
+
+void
vars_of_device (void)
{
+ reinit_vars_of_device ();
+
DEFVAR_LISP ("create-device-hook", &Vcreate_device_hook /*
Function or functions to call when a device is created.
One argument, the newly-created device.
*/ );
Vdelete_device_hook = Qnil;
- staticpro (&Vdefault_device);
- Vdefault_device = Qnil;
-
- asynch_device_change_pending = 0;
-
Vdevice_class_list = list3 (Qcolor, Qgrayscale, Qmono);
staticpro (&Vdevice_class_list);
unsigned int frame_changed :1;
unsigned int glyphs_changed :1;
unsigned int subwindows_changed :1;
+ unsigned int subwindows_state_changed :1;
unsigned int icon_changed :1;
unsigned int menubar_changed :1;
unsigned int modeline_changed :1;
#define XDEVICE(x) XRECORD (x, device, struct device)
#define XSETDEVICE(x, p) XSETRECORD (x, p, device)
#define DEVICEP(x) RECORDP (x, device)
-#define GC_DEVICEP(x) GC_RECORDP (x, device)
#define CHECK_DEVICE(x) CHECK_RECORD (x, device)
#define CONCHECK_DEVICE(x) CONCHECK_RECORD (x, device)
return d;
}
# define DEVICE_TYPE_DATA(d, type) \
- ((struct type##_device *) (error_check_device_type (d, Q##type))->device_data)
+ ((struct type##_device *) error_check_device_type (d, Q##type)->device_data)
#else
# define DEVICE_TYPE_DATA(d, type) \
((struct type##_device *) (d)->device_data)
#define MARK_DEVICE_SUBWINDOWS_CHANGED(d) \
((void) (subwindows_changed = (d)->subwindows_changed = 1))
+#define MARK_DEVICE_SUBWINDOWS_STATE_CHANGED(d) \
+ ((void) (subwindows_state_changed = (d)->subwindows_state_changed = 1))
+
#define MARK_DEVICE_TOOLBARS_CHANGED(d) \
((void) (toolbar_changed = (d)->toolbar_changed = 1))
MARK_DEVICE_FACES_CHANGED (mdffc_d); \
} while (0)
+#define MARK_DEVICE_FRAMES_GLYPHS_CHANGED(d) do { \
+ struct device *mdffc_d = (d); \
+ Lisp_Object frmcons; \
+ DEVICE_FRAME_LOOP (frmcons, mdffc_d) \
+ XFRAME (XCAR (frmcons))->glyphs_changed = 1; \
+ MARK_DEVICE_GLYPHS_CHANGED (mdffc_d); \
+} while (0)
+
#define MARK_DEVICE_FRAME_CHANGED(d) \
((void) (frame_changed = (d)->frame_changed = 1))
}
struct user_cache {
- char **data;
+ Bufbyte **data;
int length;
int size;
EMACS_TIME last_rebuild_time;
Bufbyte *pwuser;
QUIT;
DO_REALLOC (user_cache.data, user_cache.size,
- user_cache.length + 1, char *);
+ user_cache.length + 1, Bufbyte *);
GET_C_CHARPTR_INT_DATA_ALLOCA (pwd->pw_name, FORMAT_OS, pwuser);
- user_cache.data[user_cache.length++] = xstrdup (pwuser);
+ user_cache.data[user_cache.length++] =
+ (Bufbyte *) xstrdup ((char *) pwuser);
}
endpwent ();
speed_up_interrupts ();
if (strchr (int_converters, ch))
{
if (spec->h_flag)
- arg.i = va_arg (vargs, short);
+ arg.i = va_arg (vargs, int /* short */);
else if (spec->l_flag)
arg.l = va_arg (vargs, long);
else
else if (strchr (unsigned_int_converters, ch))
{
if (spec->h_flag)
- arg.ui = va_arg (vargs, unsigned short);
+ arg.ui = va_arg (vargs, unsigned int /* unsigned short */);
else if (spec->l_flag)
arg.ul = va_arg (vargs, unsigned long);
else
int Dynarr_min_size = 1;
+static void
+Dynarr_realloc (Dynarr *dy, int new_size)
+{
+ if (DUMPEDP (dy->base))
+ {
+ void *new_base = malloc (new_size);
+ memcpy (new_base, dy->base, dy->max > new_size ? new_size : dy->max);
+ dy->base = new_base;
+ }
+ else
+ dy->base = xrealloc (dy->base, new_size);
+}
+
void *
Dynarr_newf (int elsize)
{
/* Don't do anything if the array is already big enough. */
if (newsize > dy->max)
{
- dy->base = xrealloc (dy->base, newsize*dy->elsize);
+ Dynarr_realloc (dy, newsize*dy->elsize);
dy->max = newsize;
}
}
{
Dynarr *dy = (Dynarr *) d;
- if (dy->base)
+ if (dy->base && !DUMPEDP (dy->base))
xfree (dy->base);
- xfree (dy);
+ if(!DUMPEDP (dy))
+ xfree (dy);
}
#ifdef MEMORY_USAGE_STATS
#include "systime.h"
#include "sysdep.h"
#include "syspwd.h"
+#include "sysfile.h" /* for getcwd */
/* Some static data, and a function to initialize it for each run */
Lisp_Object Qldapp;
/* ldap-open plist keywords */
-extern Lisp_Object Qport, Qauth, Qbinddn, Qpasswd, Qderef, Qtimelimit,
- Qsizelimit;
+static Lisp_Object Qport, Qauth, Qbinddn, Qpasswd, Qderef, Qtimelimit, Qsizelimit;
/* Search scope limits */
-extern Lisp_Object Qbase, Qonelevel, Qsubtree;
+static Lisp_Object Qbase, Qonelevel, Qsubtree;
/* Authentication methods */
-extern Lisp_Object Qkrbv41, Qkrbv42;
+static Lisp_Object Qkrbv41, Qkrbv42;
/* Deref policy */
-extern Lisp_Object Qnever, Qalways, Qfind;
+static Lisp_Object Qnever, Qalways, Qfind;
\f
/************************************************************************/
/* Utility Functions */
}
static Lisp_Object
-mark_ldap (Lisp_Object obj, void (*markobj) (Lisp_Object))
+mark_ldap (Lisp_Object obj)
{
return XLDAP (obj)->host;
}
syms_of_eldap (void)
{
defsymbol (&Qldapp, "ldapp");
+ defsymbol (&Qport, "port");
+ defsymbol (&Qauth, "auth");
+ defsymbol (&Qbinddn, "binddn");
+ defsymbol (&Qpasswd, "passwd");
+ defsymbol (&Qderef, "deref");
+ defsymbol (&Qtimelimit, "timelimit");
+ defsymbol (&Qsizelimit, "sizelimit");
+ defsymbol (&Qbase, "base");
+ defsymbol (&Qonelevel, "onelevel");
+ defsymbol (&Qsubtree, "subtree");
+ defsymbol (&Qkrbv41, "krbv41");
+ defsymbol (&Qkrbv42, "krbv42");
+ defsymbol (&Qnever, "never");
+ defsymbol (&Qalways, "always");
+ defsymbol (&Qfind, "find");
+
DEFSUBR (Fldapp);
DEFSUBR (Fldap_host);
DEFSUBR (Fldap_status);
#define XLDAP(x) XRECORD (x, ldap, struct Lisp_LDAP)
#define XSETLDAP(x, p) XSETRECORD (x, p, ldap)
#define LDAPP(x) RECORDP (x, ldap)
-#define GC_LDAPP(x) GC_RECORDP (x, ldap)
#define CHECK_LDAP(x) CHECK_RECORD (x, ldap)
#define CONCHECK_LDAP(x) CONCHECK_RECORD (x, ldap)
#include "bytecode.h"
#include "elhash.h"
-Lisp_Object Qhash_tablep, Qhashtable, Qhash_table;
-Lisp_Object Qweak, Qkey_weak, Qvalue_weak, Qnon_weak;
+Lisp_Object Qhash_tablep;
+static Lisp_Object Qhashtable, Qhash_table;
+static Lisp_Object Qweakness, Qvalue;
static Lisp_Object Vall_weak_hash_tables;
static Lisp_Object Qrehash_size, Qrehash_threshold;
-static Lisp_Object Q_size, Q_test, Q_type, Q_rehash_size, Q_rehash_threshold;
+static Lisp_Object Q_size, Q_test, Q_weakness, Q_rehash_size, Q_rehash_threshold;
+
+/* obsolete as of 19990901 in xemacs-21.2 */
+static Lisp_Object Qweak, Qkey_weak, Qvalue_weak, Qnon_weak, Q_type;
typedef struct hentry
{
hash_table_hash_function_t hash_function;
hash_table_test_function_t test_function;
hentry *hentries;
- enum hash_table_type type; /* whether and how this hash table is weak */
+ enum hash_table_weakness weakness;
Lisp_Object next_weak; /* Used to chain together all of the weak
hash tables. Don't mark through this. */
};
typedef struct Lisp_Hash_Table Lisp_Hash_Table;
#define HENTRY_CLEAR_P(hentry) ((*(EMACS_UINT*)(&((hentry)->key))) == 0)
-#define CLEAR_HENTRY(hentry) ((*(EMACS_UINT*)(&((hentry)->key))) = 0)
+#define CLEAR_HENTRY(hentry) \
+ ((*(EMACS_UINT*)(&((hentry)->key))) = 0, \
+ (*(EMACS_UINT*)(&((hentry)->value))) = 0)
#define HASH_TABLE_DEFAULT_SIZE 16
#define HASH_TABLE_DEFAULT_REHASH_SIZE 1.3
\f
static Lisp_Object
-mark_hash_table (Lisp_Object obj, void (*markobj) (Lisp_Object))
+mark_hash_table (Lisp_Object obj)
{
Lisp_Hash_Table *ht = XHASH_TABLE (obj);
/* If the hash table is weak, we don't want to mark the keys and
values (we scan over them after everything else has been marked,
and mark or remove them as necessary). */
- if (ht->type == HASH_TABLE_NON_WEAK)
+ if (ht->weakness == HASH_TABLE_NON_WEAK)
{
hentry *e, *sentinel;
for (e = ht->hentries, sentinel = e + ht->size; e < sentinel; e++)
if (!HENTRY_CLEAR_P (e))
{
- markobj (e->key);
- markobj (e->value);
+ mark_object (e->key);
+ mark_object (e->value);
}
}
return Qnil;
}
\f
/* Equality of hash tables. Two hash tables are equal when they are of
- the same type and test function, they have the same number of
+ the same weakness and test function, they have the same number of
elements, and for each key in the hash table, the values are `equal'.
This is similar to Common Lisp `equalp' of hash tables, with the
hentry *e, *sentinel;
if ((ht1->test_function != ht2->test_function) ||
- (ht1->type != ht2->type) ||
+ (ht1->weakness != ht2->weakness) ||
(ht1->count != ht2->count))
return 0;
#s(hash-table size 2 data (key1 value1 key2 value2))
- The supported keywords are `type' (non-weak (or nil), weak,
- key-weak and value-weak), `test' (eql (or nil), eq or equal),
- `size' (a natnum or nil) and `data' (a list).
+ The supported hash table structure keywords and their values are:
+ `test' (eql (or nil), eq or equal)
+ `size' (a natnum or nil)
+ `rehash-size' (a float)
+ `rehash-threshold' (a float)
+ `weakness' (nil, t, key or value)
+ `data' (a list)
If `print-readably' is non-nil, then a simpler syntax is used; for
instance:
write_c_string (print_readably ? "#s(hash-table" : "#<hash-table",
printcharfun);
- if (ht->type != HASH_TABLE_NON_WEAK)
- {
- sprintf (buf, " type %s",
- (ht->type == HASH_TABLE_WEAK ? "weak" :
- ht->type == HASH_TABLE_KEY_WEAK ? "key-weak" :
- ht->type == HASH_TABLE_VALUE_WEAK ? "value-weak" :
- "you-d-better-not-see-this"));
- write_c_string (buf, printcharfun);
- }
-
/* These checks have a kludgy look to them, but they are safe.
Due to nature of hashing, you cannot use arbitrary
test functions anyway. */
write_c_string (buf, printcharfun);
}
+ if (ht->weakness != HASH_TABLE_NON_WEAK)
+ {
+ sprintf (buf, " weakness %s",
+ (ht->weakness == HASH_TABLE_WEAK ? "t" :
+ ht->weakness == HASH_TABLE_KEY_WEAK ? "key" :
+ ht->weakness == HASH_TABLE_VALUE_WEAK ? "value" :
+ "you-d-better-not-see-this"));
+ write_c_string (buf, printcharfun);
+ }
+
if (ht->count)
print_hash_table_data (ht, printcharfun);
hentry_description_1
};
-static const struct lrecord_description hash_table_description[] = {
+const struct lrecord_description hash_table_description[] = {
{ XD_SIZE_T, offsetof(Lisp_Hash_Table, size) },
- { XD_STRUCT_PTR, offsetof(Lisp_Hash_Table, hentries), XD_INDIRECT(0), &hentry_description },
+ { XD_STRUCT_PTR, offsetof(Lisp_Hash_Table, hentries), XD_INDIRECT(0, 1), &hentry_description },
+ { XD_LO_LINK, offsetof(Lisp_Hash_Table, next_weak) },
{ XD_END }
};
}
Lisp_Object
-make_general_lisp_hash_table (size_t size,
- enum hash_table_type type,
- enum hash_table_test test,
- double rehash_size,
- double rehash_threshold)
+make_general_lisp_hash_table (enum hash_table_test test,
+ size_t size,
+ double rehash_size,
+ double rehash_threshold,
+ enum hash_table_weakness weakness)
{
Lisp_Object hash_table;
Lisp_Hash_Table *ht = alloc_lcrecord_type (Lisp_Hash_Table, &lrecord_hash_table);
- ht->type = type;
ht->rehash_size = rehash_size;
ht->rehash_threshold = rehash_threshold;
+ ht->weakness = weakness;
switch (test)
{
XSETHASH_TABLE (hash_table, ht);
- if (type == HASH_TABLE_NON_WEAK)
+ if (weakness == HASH_TABLE_NON_WEAK)
ht->next_weak = Qunbound;
else
ht->next_weak = Vall_weak_hash_tables, Vall_weak_hash_tables = hash_table;
Lisp_Object
make_lisp_hash_table (size_t size,
- enum hash_table_type type,
+ enum hash_table_weakness weakness,
enum hash_table_test test)
{
- return make_general_lisp_hash_table (size, type, test,
- HASH_TABLE_DEFAULT_REHASH_SIZE, -1.0);
+ return make_general_lisp_hash_table
+ (test, size, HASH_TABLE_DEFAULT_REHASH_SIZE, -1.0, weakness);
}
/* Pretty reading of hash tables.
}
static int
-hash_table_type_validate (Lisp_Object keyword, Lisp_Object value,
- Error_behavior errb)
+hash_table_weakness_validate (Lisp_Object keyword, Lisp_Object value,
+ Error_behavior errb)
{
if (EQ (value, Qnil)) return 1;
+ if (EQ (value, Qt)) return 1;
+ if (EQ (value, Qkey)) return 1;
+ if (EQ (value, Qvalue)) return 1;
+
+ /* Following values are obsolete as of 19990901 in xemacs-21.2 */
if (EQ (value, Qnon_weak)) return 1;
if (EQ (value, Qweak)) return 1;
if (EQ (value, Qkey_weak)) return 1;
if (EQ (value, Qvalue_weak)) return 1;
- maybe_signal_simple_error ("Invalid hash table type",
+ maybe_signal_simple_error ("Invalid hash table weakness",
value, Qhash_table, errb);
return 0;
}
-static enum hash_table_type
-decode_hash_table_type (Lisp_Object obj)
+static enum hash_table_weakness
+decode_hash_table_weakness (Lisp_Object obj)
{
if (EQ (obj, Qnil)) return HASH_TABLE_NON_WEAK;
+ if (EQ (obj, Qt)) return HASH_TABLE_WEAK;
+ if (EQ (obj, Qkey)) return HASH_TABLE_KEY_WEAK;
+ if (EQ (obj, Qvalue)) return HASH_TABLE_VALUE_WEAK;
+
+ /* Following values are obsolete as of 19990901 in xemacs-21.2 */
if (EQ (obj, Qnon_weak)) return HASH_TABLE_NON_WEAK;
if (EQ (obj, Qweak)) return HASH_TABLE_WEAK;
if (EQ (obj, Qkey_weak)) return HASH_TABLE_KEY_WEAK;
if (EQ (obj, Qvalue_weak)) return HASH_TABLE_VALUE_WEAK;
- signal_simple_error ("Invalid hash table type", obj);
+ signal_simple_error ("Invalid hash table weakness", obj);
return HASH_TABLE_NON_WEAK; /* not reached */
}
static int
hash_table_rehash_size_validate (Lisp_Object keyword, Lisp_Object value,
- Error_behavior errb)
+ Error_behavior errb)
{
if (!FLOATP (value))
{
{
Lisp_Object hash_table;
Lisp_Object test = Qnil;
- Lisp_Object type = Qnil;
Lisp_Object size = Qnil;
- Lisp_Object data = Qnil;
Lisp_Object rehash_size = Qnil;
Lisp_Object rehash_threshold = Qnil;
+ Lisp_Object weakness = Qnil;
+ Lisp_Object data = Qnil;
while (!NILP (plist))
{
value = XCAR (plist); plist = XCDR (plist);
if (EQ (key, Qtest)) test = value;
- else if (EQ (key, Qtype)) type = value;
else if (EQ (key, Qsize)) size = value;
- else if (EQ (key, Qdata)) data = value;
else if (EQ (key, Qrehash_size)) rehash_size = value;
else if (EQ (key, Qrehash_threshold)) rehash_threshold = value;
+ else if (EQ (key, Qweakness)) weakness = value;
+ else if (EQ (key, Qdata)) data = value;
+ else if (EQ (key, Qtype))/*obsolete*/ weakness = value;
else
abort ();
}
/* Create the hash table. */
hash_table = make_general_lisp_hash_table
- (decode_hash_table_size (size),
- decode_hash_table_type (type),
- decode_hash_table_test (test),
+ (decode_hash_table_test (test),
+ decode_hash_table_size (size),
decode_hash_table_rehash_size (rehash_size),
- decode_hash_table_rehash_threshold (rehash_threshold));
+ decode_hash_table_rehash_threshold (rehash_threshold),
+ decode_hash_table_weakness (weakness));
/* I'm not sure whether this can GC, but better safe than sorry. */
{
struct structure_type *st;
st = define_structure_type (structure_name, 0, hash_table_instantiate);
- define_structure_type_keyword (st, Qsize, hash_table_size_validate);
define_structure_type_keyword (st, Qtest, hash_table_test_validate);
- define_structure_type_keyword (st, Qtype, hash_table_type_validate);
- define_structure_type_keyword (st, Qdata, hash_table_data_validate);
+ define_structure_type_keyword (st, Qsize, hash_table_size_validate);
define_structure_type_keyword (st, Qrehash_size, hash_table_rehash_size_validate);
define_structure_type_keyword (st, Qrehash_threshold, hash_table_rehash_threshold_validate);
+ define_structure_type_keyword (st, Qweakness, hash_table_weakness_validate);
+ define_structure_type_keyword (st, Qdata, hash_table_data_validate);
+
+ /* obsolete as of 19990901 in xemacs-21.2 */
+ define_structure_type_keyword (st, Qtype, hash_table_weakness_validate);
}
/* Create a built-in Lisp structure type named `hash-table'.
We make #s(hashtable ...) equivalent to #s(hash-table ...),
- for backward comptabibility.
+ for backward compatibility.
This is called from emacs.c. */
void
structure_type_create_hash_table (void)
DEFUN ("make-hash-table", Fmake_hash_table, 0, MANY, 0, /*
Return a new empty hash table object.
Use Common Lisp style keywords to specify hash table properties.
- (make-hash-table &key :size :test :type :rehash-size :rehash-threshold)
-
-Keyword :size specifies the number of keys likely to be inserted.
-This number of entries can be inserted without enlarging the hash table.
+ (make-hash-table &key test size rehash-size rehash-threshold weakness)
Keyword :test can be `eq', `eql' (default) or `equal'.
Comparison between keys is done using this function.
If speed is important, consider using `eq'.
When storing strings in the hash table, you will likely need to use `equal'.
-Keyword :type can be `non-weak' (default), `weak', `key-weak' or `value-weak'.
+Keyword :size specifies the number of keys likely to be inserted.
+This number of entries can be inserted without enlarging the hash table.
+
+Keyword :rehash-size must be a float greater than 1.0, and specifies
+the factor by which to increase the size of the hash table when enlarging.
+
+Keyword :rehash-threshold must be a float between 0.0 and 1.0,
+and specifies the load factor of the hash table which triggers enlarging.
+
+Non-standard keyword :weakness can be `nil' (default), `t', `key' or `value'.
A weak hash table is one whose pointers do not count as GC referents:
for any key-value pair in the hash table, if the only remaining pointer
unmarked outside of weak hash tables. The pair will remain in the
hash table if the value is pointed to by something other than a weak
hash table, even if the key is not.
-
-Keyword :rehash-size must be a float greater than 1.0, and specifies
-the factor by which to increase the size of the hash table when enlarging.
-
-Keyword :rehash-threshold must be a float between 0.0 and 1.0,
-and specifies the load factor of the hash table which triggers enlarging.
-
*/
(int nargs, Lisp_Object *args))
{
- int j = 0;
- Lisp_Object size = Qnil;
- Lisp_Object type = Qnil;
+ int i = 0;
Lisp_Object test = Qnil;
+ Lisp_Object size = Qnil;
Lisp_Object rehash_size = Qnil;
Lisp_Object rehash_threshold = Qnil;
+ Lisp_Object weakness = Qnil;
- while (j < nargs)
+ while (i + 1 < nargs)
{
- Lisp_Object keyword, value;
-
- keyword = args[j++];
- if (!KEYWORDP (keyword))
- signal_simple_error ("Invalid hash table property keyword", keyword);
- if (j == nargs)
- signal_simple_error ("Hash table property requires a value", keyword);
-
- value = args[j++];
+ Lisp_Object keyword = args[i++];
+ Lisp_Object value = args[i++];
- if (EQ (keyword, Q_size)) size = value;
- else if (EQ (keyword, Q_type)) type = value;
- else if (EQ (keyword, Q_test)) test = value;
+ if (EQ (keyword, Q_test)) test = value;
+ else if (EQ (keyword, Q_size)) size = value;
else if (EQ (keyword, Q_rehash_size)) rehash_size = value;
else if (EQ (keyword, Q_rehash_threshold)) rehash_threshold = value;
+ else if (EQ (keyword, Q_weakness)) weakness = value;
+ else if (EQ (keyword, Q_type))/*obsolete*/ weakness = value;
else signal_simple_error ("Invalid hash table property keyword", keyword);
}
+ if (i < nargs)
+ signal_simple_error ("Hash table property requires a value", args[i]);
+
#define VALIDATE_VAR(var) \
if (!NILP (var)) hash_table_##var##_validate (Q##var, var, ERROR_ME);
- VALIDATE_VAR (size);
- VALIDATE_VAR (type);
VALIDATE_VAR (test);
+ VALIDATE_VAR (size);
VALIDATE_VAR (rehash_size);
VALIDATE_VAR (rehash_threshold);
+ VALIDATE_VAR (weakness);
return make_general_lisp_hash_table
- (decode_hash_table_size (size),
- decode_hash_table_type (type),
- decode_hash_table_test (test),
+ (decode_hash_table_test (test),
+ decode_hash_table_size (size),
decode_hash_table_rehash_size (rehash_size),
- decode_hash_table_rehash_threshold (rehash_threshold));
+ decode_hash_table_rehash_threshold (rehash_threshold),
+ decode_hash_table_weakness (weakness));
}
DEFUN ("copy-hash-table", Fcopy_hash_table, 1, 1, 0, /*
}
static void
-enlarge_hash_table (Lisp_Hash_Table *ht)
+resize_hash_table (Lisp_Hash_Table *ht, size_t new_size)
{
hentry *old_entries, *new_entries, *old_sentinel, *new_sentinel, *e;
- size_t old_size, new_size;
+ size_t old_size;
old_size = ht->size;
- new_size = ht->size =
- hash_table_size ((size_t) ((double) old_size * ht->rehash_size));
+ ht->size = new_size;
old_entries = ht->hentries;
*probe = *e;
}
- xfree (old_entries);
+ if (!DUMPEDP (old_entries))
+ xfree (old_entries);
+}
+
+void
+reorganize_hash_table (Lisp_Hash_Table *ht)
+{
+ resize_hash_table (ht, ht->size);
+}
+
+static void
+enlarge_hash_table (Lisp_Hash_Table *ht)
+{
+ size_t new_size =
+ hash_table_size ((size_t) ((double) ht->size * ht->rehash_size));
+ resize_hash_table (ht, new_size);
}
static hentry *
remhash_1 (Lisp_Hash_Table *ht, hentry *entries, hentry *probe)
{
size_t size = ht->size;
- CLEAR_HENTRY (probe++);
+ CLEAR_HENTRY (probe);
+ probe++;
ht->count--;
LINEAR_PROBING_LOOP (probe, entries, size)
return make_int (xhash_table (hash_table)->count);
}
-DEFUN ("hash-table-size", Fhash_table_size, 1, 1, 0, /*
-Return the size of HASH-TABLE.
-This is the current number of slots in HASH-TABLE, whether occupied or not.
-*/
- (hash_table))
-{
- return make_int (xhash_table (hash_table)->size);
-}
-
-DEFUN ("hash-table-type", Fhash_table_type, 1, 1, 0, /*
-Return the type of HASH-TABLE.
-This can be one of `non-weak', `weak', `key-weak' or `value-weak'.
-*/
- (hash_table))
-{
- switch (xhash_table (hash_table)->type)
- {
- case HASH_TABLE_WEAK: return Qweak;
- case HASH_TABLE_KEY_WEAK: return Qkey_weak;
- case HASH_TABLE_VALUE_WEAK: return Qvalue_weak;
- default: return Qnon_weak;
- }
-}
-
DEFUN ("hash-table-test", Fhash_table_test, 1, 1, 0, /*
Return the test function of HASH-TABLE.
This can be one of `eq', `eql' or `equal'.
Qeq);
}
+DEFUN ("hash-table-size", Fhash_table_size, 1, 1, 0, /*
+Return the size of HASH-TABLE.
+This is the current number of slots in HASH-TABLE, whether occupied or not.
+*/
+ (hash_table))
+{
+ return make_int (xhash_table (hash_table)->size);
+}
+
DEFUN ("hash-table-rehash-size", Fhash_table_rehash_size, 1, 1, 0, /*
Return the current rehash size of HASH-TABLE.
This is a float greater than 1.0; the factor by which HASH-TABLE
return make_float (hash_table_rehash_threshold (xhash_table (hash_table)));
}
+DEFUN ("hash-table-weakness", Fhash_table_weakness, 1, 1, 0, /*
+Return the weakness of HASH-TABLE.
+This can be one of `nil', `t', `key' or `value'.
+*/
+ (hash_table))
+{
+ switch (xhash_table (hash_table)->weakness)
+ {
+ case HASH_TABLE_WEAK: return Qt;
+ case HASH_TABLE_KEY_WEAK: return Qkey;
+ case HASH_TABLE_VALUE_WEAK: return Qvalue;
+ default: return Qnil;
+ }
+}
+
+/* obsolete as of 19990901 in xemacs-21.2 */
+DEFUN ("hash-table-type", Fhash_table_type, 1, 1, 0, /*
+Return the type of HASH-TABLE.
+This can be one of `non-weak', `weak', `key-weak' or `value-weak'.
+*/
+ (hash_table))
+{
+ switch (xhash_table (hash_table)->weakness)
+ {
+ case HASH_TABLE_WEAK: return Qweak;
+ case HASH_TABLE_KEY_WEAK: return Qkey_weak;
+ case HASH_TABLE_VALUE_WEAK: return Qvalue_weak;
+ default: return Qnon_weak;
+ }
+}
+
/************************************************************************/
/* Mapping Functions */
/************************************************************************/
/* Complete the marking for semi-weak hash tables. */
int
-finish_marking_weak_hash_tables (int (*obj_marked_p) (Lisp_Object),
- void (*markobj) (Lisp_Object))
+finish_marking_weak_hash_tables (void)
{
Lisp_Object hash_table;
int did_mark = 0;
for (hash_table = Vall_weak_hash_tables;
- !GC_NILP (hash_table);
+ !NILP (hash_table);
hash_table = XHASH_TABLE (hash_table)->next_weak)
{
CONST Lisp_Hash_Table *ht = XHASH_TABLE (hash_table);
CONST hentry *e = ht->hentries;
CONST hentry *sentinel = e + ht->size;
- if (! obj_marked_p (hash_table))
+ if (! marked_p (hash_table))
/* The hash table is probably garbage. Ignore it. */
continue;
half-marked, we may need to mark the other half if we're
keeping this pair. */
#define MARK_OBJ(obj) \
-do { if (!obj_marked_p (obj)) markobj (obj), did_mark = 1; } while (0)
+do { if (!marked_p (obj)) mark_object (obj), did_mark = 1; } while (0)
- switch (ht->type)
+ switch (ht->weakness)
{
case HASH_TABLE_KEY_WEAK:
for (; e < sentinel; e++)
if (!HENTRY_CLEAR_P (e))
- if (obj_marked_p (e->key))
+ if (marked_p (e->key))
MARK_OBJ (e->value);
break;
case HASH_TABLE_VALUE_WEAK:
for (; e < sentinel; e++)
if (!HENTRY_CLEAR_P (e))
- if (obj_marked_p (e->value))
+ if (marked_p (e->value))
MARK_OBJ (e->key);
break;
case HASH_TABLE_KEY_CAR_WEAK:
for (; e < sentinel; e++)
if (!HENTRY_CLEAR_P (e))
- if (!CONSP (e->key) || obj_marked_p (XCAR (e->key)))
+ if (!CONSP (e->key) || marked_p (XCAR (e->key)))
{
MARK_OBJ (e->key);
MARK_OBJ (e->value);
case HASH_TABLE_VALUE_CAR_WEAK:
for (; e < sentinel; e++)
if (!HENTRY_CLEAR_P (e))
- if (!CONSP (e->value) || obj_marked_p (XCAR (e->value)))
+ if (!CONSP (e->value) || marked_p (XCAR (e->value)))
{
MARK_OBJ (e->key);
MARK_OBJ (e->value);
}
void
-prune_weak_hash_tables (int (*obj_marked_p) (Lisp_Object))
+prune_weak_hash_tables (void)
{
Lisp_Object hash_table, prev = Qnil;
for (hash_table = Vall_weak_hash_tables;
- !GC_NILP (hash_table);
+ !NILP (hash_table);
hash_table = XHASH_TABLE (hash_table)->next_weak)
{
- if (! obj_marked_p (hash_table))
+ if (! marked_p (hash_table))
{
/* This hash table itself is garbage. Remove it from the list. */
- if (GC_NILP (prev))
+ if (NILP (prev))
Vall_weak_hash_tables = XHASH_TABLE (hash_table)->next_weak;
else
XHASH_TABLE (prev)->next_weak = XHASH_TABLE (hash_table)->next_weak;
{
/* Now, scan over all the pairs. Remove all of the pairs
in which the key or value, or both, is unmarked
- (depending on the type of weak hash table). */
+ (depending on the weakness of the hash table). */
Lisp_Hash_Table *ht = XHASH_TABLE (hash_table);
hentry *entries = ht->hentries;
hentry *sentinel = entries + ht->size;
if (!HENTRY_CLEAR_P (e))
{
again:
- if (!obj_marked_p (e->key) || !obj_marked_p (e->value))
+ if (!marked_p (e->key) || !marked_p (e->value))
{
remhash_1 (ht, entries, e);
if (!HENTRY_CLEAR_P (e))
return LISP_HASH (obj);
}
+DEFUN ("sxhash", Fsxhash, 1, 1, 0, /*
+Return a hash value for OBJECT.
+(equal obj1 obj2) implies (= (sxhash obj1) (sxhash obj2)).
+*/
+ (object))
+{
+ return make_int (internal_hash (object, 0));
+}
+
#if 0
xxDEFUN ("internal-hash-value", Finternal_hash_value, 1, 1, 0, /*
Hash value of OBJECT. For debugging.
DEFSUBR (Fclrhash);
DEFSUBR (Fmaphash);
DEFSUBR (Fhash_table_count);
+ DEFSUBR (Fhash_table_test);
DEFSUBR (Fhash_table_size);
DEFSUBR (Fhash_table_rehash_size);
DEFSUBR (Fhash_table_rehash_threshold);
- DEFSUBR (Fhash_table_type);
- DEFSUBR (Fhash_table_test);
+ DEFSUBR (Fhash_table_weakness);
+ DEFSUBR (Fhash_table_type); /* obsolete */
+ DEFSUBR (Fsxhash);
#if 0
DEFSUBR (Finternal_hash_value);
#endif
defsymbol (&Qhash_tablep, "hash-table-p");
defsymbol (&Qhash_table, "hash-table");
defsymbol (&Qhashtable, "hashtable");
- defsymbol (&Qweak, "weak");
- defsymbol (&Qkey_weak, "key-weak");
- defsymbol (&Qvalue_weak, "value-weak");
- defsymbol (&Qnon_weak, "non-weak");
+ defsymbol (&Qweakness, "weakness");
+ defsymbol (&Qvalue, "value");
defsymbol (&Qrehash_size, "rehash-size");
defsymbol (&Qrehash_threshold, "rehash-threshold");
- defkeyword (&Q_size, ":size");
+ defsymbol (&Qweak, "weak"); /* obsolete */
+ defsymbol (&Qkey_weak, "key-weak"); /* obsolete */
+ defsymbol (&Qvalue_weak, "value-weak"); /* obsolete */
+ defsymbol (&Qnon_weak, "non-weak"); /* obsolete */
+
defkeyword (&Q_test, ":test");
- defkeyword (&Q_type, ":type");
+ defkeyword (&Q_size, ":size");
defkeyword (&Q_rehash_size, ":rehash-size");
defkeyword (&Q_rehash_threshold, ":rehash-threshold");
+ defkeyword (&Q_weakness, ":weakness");
+ defkeyword (&Q_type, ":type"); /* obsolete */
}
void
{
/* This must NOT be staticpro'd */
Vall_weak_hash_tables = Qnil;
+ pdump_wire_list (&Vall_weak_hash_tables);
}
#define XHASH_TABLE(x) XRECORD (x, hash_table, struct Lisp_Hash_Table)
#define XSETHASH_TABLE(x, p) XSETRECORD (x, p, hash_table)
#define HASH_TABLEP(x) RECORDP (x, hash_table)
-#define GC_HASH_TABLEP(x) GC_RECORDP (x, hash_table)
#define CHECK_HASH_TABLE(x) CHECK_RECORD (x, hash_table)
#define CONCHECK_HASH_TABLE(x) CONCHECK_RECORD (x, hash_table)
-enum hash_table_type
+enum hash_table_weakness
{
HASH_TABLE_NON_WEAK,
HASH_TABLE_KEY_WEAK,
HASH_TABLE_EQUAL
};
+extern const struct lrecord_description hash_table_description[];
+
EXFUN (Fcopy_hash_table, 1);
EXFUN (Fhash_table_count, 1);
EXFUN (Fgethash, 3);
typedef int (*maphash_function_t) (Lisp_Object key, Lisp_Object value,
void* extra_arg);
+struct Lisp_Hash_Table;
-Lisp_Object make_general_lisp_hash_table (size_t size,
- enum hash_table_type type,
- enum hash_table_test test,
+Lisp_Object make_general_lisp_hash_table (enum hash_table_test test,
+ size_t size,
+ double rehash_size,
double rehash_threshold,
- double rehash_size);
+ enum hash_table_weakness weakness);
Lisp_Object make_lisp_hash_table (size_t size,
- enum hash_table_type type,
+ enum hash_table_weakness weakness,
enum hash_table_test test);
void elisp_maphash (maphash_function_t function,
void elisp_map_remhash (maphash_function_t predicate,
Lisp_Object hash_table, void *extra_arg);
-int finish_marking_weak_hash_tables (int (*obj_marked_p) (Lisp_Object),
- void (*markobj) (Lisp_Object));
-void prune_weak_hash_tables (int (*obj_marked_p) (Lisp_Object));
+int finish_marking_weak_hash_tables (void);
+void prune_weak_hash_tables (void);
+
+void reorganize_hash_table (struct Lisp_Hash_Table *ht);
#endif /* _XEMACS_ELHASH_H_ */
Lisp_Object Vdoc_directory, Vconfigure_doc_directory;
Lisp_Object Vconfigure_lock_directory;
Lisp_Object Vdata_directory_list;
-Lisp_Object Vinfo_directory, Vconfigure_info_directory;
+Lisp_Object Vconfigure_info_directory;
Lisp_Object Vsite_directory, Vconfigure_site_directory;
Lisp_Object Vconfigure_info_path;
Lisp_Object Vinternal_error_checking;
int debug_paths;
/* Save argv and argc. */
-char **initial_argv;
-int initial_argc;
+static char **initial_argv;
+static int initial_argc;
static void sort_args (int argc, char **argv);
extern int malloc_cookie;
#endif
-#if !defined(SYSTEM_MALLOC) && !defined(HAVE_LIBMCHECK)
+#if (!defined (SYSTEM_MALLOC) && !defined (HAVE_LIBMCHECK) \
+ && !defined (DOUG_LEA_MALLOC))
/* Make sure that any libraries we link against haven't installed a
hook for a gmalloc of a potentially incompatible version. */
/* If we're using libmcheck, the hooks have already been initialized, */
__malloc_hook = NULL;
__realloc_hook = NULL;
__free_hook = NULL;
-#endif /* not SYSTEM_MALLOC */
+#endif /* not SYSTEM_MALLOC or HAVE_LIBMCHECK or DOUG_LEA_MALLOC */
noninteractive = 0;
We try to do things in an order that minimizes the non-obvious
dependencies between functions. */
+#ifdef PDUMP
+ initialized = restart || pdump_load ();
+#endif
+
if (!initialized)
{
/* Initialize things so that new Lisp objects
staticpro()
Fprovide(symbol)
intern()
- pure_put()
+ Fput()
xmalloc()
defsymbol(), if it's absolutely necessary and you're sure that
the symbol isn't referenced anywhere else in the initialization
Any of the object-creating functions on alloc.c: e.g.
make_pure_*()
- Fpurecopy()
make_string()
build_string()
make_vector()
Fcons()
listN()
make_opaque_ptr()
- make_opaque_long()
perhaps a few others.
*/
/* Now allow Fprovide() statements to be made. */
init_provide_once ();
+ /* Do that before any specifier creation (esp. vars_of_glyphs()) */
+ vars_of_specifier ();
+
vars_of_abbrev ();
vars_of_alloc ();
#ifdef HAVE_X_WINDOWS
vars_of_search ();
vars_of_select ();
vars_of_sound ();
- vars_of_specifier ();
vars_of_symbols ();
vars_of_syntax ();
#ifdef HAVE_TOOLBARS
garbage_collect_1 ();
}
#endif
+#ifdef PDUMP
+ } else if (!restart) {
+ reinit_alloc_once_early ();
+ reinit_opaque_once_early ();
+
+ reinit_console_type_create_stream ();
+#ifdef HAVE_TTY
+ reinit_console_type_create_tty ();
+#endif
+#ifdef HAVE_X_WINDOWS
+ reinit_console_type_create_x ();
+ reinit_console_type_create_device_x ();
+#endif
+#ifdef HAVE_MS_WINDOWS
+ reinit_console_type_create_mswindows ();
+#endif
+
+ reinit_specifier_type_create ();
+ reinit_specifier_type_create_image ();
+ reinit_specifier_type_create_gutter ();
+ reinit_specifier_type_create_objects ();
+#ifdef HAVE_TOOLBARS
+ reinit_specifier_type_create_toolbar ();
+#endif
+
+ structure_type_create ();
+
+ structure_type_create_chartab ();
+ structure_type_create_faces ();
+ structure_type_create_rangetab ();
+ structure_type_create_hash_table ();
+
+ lstream_type_create ();
+#ifdef FILE_CODING
+ lstream_type_create_file_coding ();
+#endif
+#if defined (HAVE_MS_WINDOWS) && !defined(HAVE_MSG_SELECT)
+ lstream_type_create_mswindows_selectable ();
+#endif
+#ifdef HAVE_UNIX_PROCESSES
+ process_type_create_unix ();
+#endif
+#ifdef HAVE_WIN32_PROCESSES
+ process_type_create_nt ();
+#endif
+
+ reinit_vars_of_buffer ();
+ reinit_vars_of_console ();
+#ifdef DEBUG_XEMACS
+ reinit_vars_of_debug ();
+#endif
+ reinit_vars_of_device ();
+ reinit_vars_of_eval ();
+#ifdef HAVE_X_WINDOWS
+ reinit_vars_of_event_Xt ();
+#endif
+#if defined(HAVE_TTY) && (defined (DEBUG_TTY_EVENT_STREAM) || !defined (HAVE_X_WINDOWS))
+ reinit_vars_of_event_tty ();
+#endif
+#ifdef HAVE_MS_WINDOWS
+ reinit_vars_of_event_mswindows ();
+#endif
+ reinit_vars_of_event_stream ();
+ reinit_vars_of_events ();
+ reinit_vars_of_extents ();
+ reinit_vars_of_font_lock ();
+ reinit_vars_of_glyphs ();
+ reinit_vars_of_glyphs_widget ();
+ reinit_vars_of_insdel ();
+ reinit_vars_of_lread ();
+ reinit_vars_of_lstream ();
+ reinit_vars_of_minibuf ();
+ reinit_vars_of_module ();
+ reinit_vars_of_objects ();
+ reinit_vars_of_print ();
+ reinit_vars_of_redisplay ();
+ reinit_vars_of_search ();
+ reinit_vars_of_scrollbar_x ();
+ reinit_vars_of_undo ();
+ reinit_vars_of_window ();
+
+#ifdef HAVE_MS_WINDOWS
+ reinit_vars_of_frame_mswindows ();
+#endif
+
+#ifdef HAVE_X_WINDOWS
+ reinit_vars_of_device_x ();
+#ifdef HAVE_MENUBARS
+ reinit_vars_of_menubar_x ();
+#endif
+ reinit_vars_of_xselect ();
+#if defined (HAVE_MENUBARS) || defined (HAVE_SCROLLBARS) || defined (HAVE_DIALOGS) || defined (HAVE_TOOLBARS)
+ reinit_vars_of_gui_x ();
+#endif
+#endif
+
+#if defined(MULE) && defined(HAVE_WNN)
+ reinit_vars_of_mule_wnn ();
+#endif
+
+ reinit_complex_vars_of_buffer ();
+ reinit_complex_vars_of_console ();
+ reinit_complex_vars_of_minibuf ();
+#endif
}
+
/* CONGRATULATIONS!!! We have successfully initialized the Lisp
engine. */
{
/* Disable all calls to free() when XEmacs is exiting and it doesn't */
/* matter. */
- __free_hook = voodoo_free_hook;
-}
+ __free_hook =
+#ifdef __GNUC__ /* prototype of __free_hook varies with glibc version */
+ (__typeof__ (__free_hook))
#endif
+ voodoo_free_hook;
+}
+#endif /* GNU_MALLOC */
DEFUN ("kill-emacs", Fkill_emacs, 0, 1, "P", /*
Exit the XEmacs job and kill it. Ask for confirmation, without argument.
UNGCPRO;
- shut_down_emacs (0, ((STRINGP (arg)) ? arg : Qnil));
+ shut_down_emacs (0, STRINGP (arg) ? arg : Qnil);
#if defined(GNU_MALLOC)
- __free_hook = voodoo_free_hook;
+ __free_hook =
+#ifdef __GNUC__ /* prototype of __free_hook varies with glibc version */
+ (__typeof__ (__free_hook))
+#endif
+ voodoo_free_hook;
#endif
- exit ((INTP (arg)) ? XINT (arg) : 0);
+ exit (INTP (arg) ? XINT (arg) : 0);
/* NOTREACHED */
return Qnil; /* I'm sick of the compiler warning */
}
/* Now try to determine the actual path to the executable,
to try to make the backtrace-determination process as foolproof
as possible. */
- if (GC_STRINGP (Vinvocation_name))
+ if (STRINGP (Vinvocation_name))
name = (char *) XSTRING_DATA (Vinvocation_name);
else
name = "xemacs";
- if (GC_STRINGP (Vinvocation_directory))
+ if (STRINGP (Vinvocation_directory))
dir = (char *) XSTRING_DATA (Vinvocation_directory);
if (!dir || dir[0] != '/')
stderr_out ("`which %s`", name);
symname_ext = 0;
garbage_collect_1 ();
+
+#ifdef PDUMP
+ pdump ();
+#else
+
#ifdef DOUG_LEA_MALLOC
malloc_state_ptr = malloc_get_state ();
#endif
#ifdef DOUG_LEA_MALLOC
free (malloc_state_ptr);
#endif
+#endif /* not PDUMP */
}
#endif /* not MSDOS and EMX */
DEFVAR_LISP ("system-configuration", &Vsystem_configuration /*
String naming the configuration XEmacs was built for.
*/ );
- Vsystem_configuration = Fpurecopy (build_string (EMACS_CONFIGURATION));
+ Vsystem_configuration = build_string (EMACS_CONFIGURATION);
#ifndef EMACS_CONFIG_OPTIONS
# define EMACS_CONFIG_OPTIONS "UNKNOWN"
DEFVAR_LISP ("system-configuration-options", &Vsystem_configuration_options /*
String containing the configuration options XEmacs was built with.
*/ );
- Vsystem_configuration_options = Fpurecopy (build_string
- (EMACS_CONFIG_OPTIONS));
+ Vsystem_configuration_options = build_string (EMACS_CONFIG_OPTIONS);
DEFVAR_LISP ("emacs-major-version", &Vemacs_major_version /*
Major version number of this version of Emacs, as an integer.
#ifndef XEMACS_CODENAME
#define XEMACS_CODENAME "Noname"
#endif
- Vxemacs_codename = Fpurecopy (build_string (XEMACS_CODENAME));
+ Vxemacs_codename = build_string (XEMACS_CODENAME);
DEFVAR_BOOL ("noninteractive", &noninteractive1 /*
Non-nil means XEmacs is running without interactive terminal.
Vinternal_error_checking = Fcons (intern ("bufpos"),
Vinternal_error_checking);
#endif
- Vinternal_error_checking = Fpurecopy (Vinternal_error_checking);
DEFVAR_LISP ("path-separator", &Vpath_separator /*
The directory separator in search paths, as a string.
#endif
}
-#ifdef __sgi
+#if defined(__sgi) && !defined(PDUMP)
/* This is so tremendously ugly I'd puke. But then, it works.
* The target is to override the static constructor from the
* libiflPNG.so library which is maskerading as libz, and
if (modules == (emodules_list *)0)
modules = (emodules_list *)xmalloc (sizeof(emodules_list));
modnum++;
- modules = xrealloc (modules, modnum * sizeof(emodules_list));
+ modules = (emodules_list *) xrealloc (modules, modnum * sizeof(emodules_list));
fs = modnum - 1;
memset (&modules[fs], 0, sizeof(emodules_list));
}
void
+reinit_vars_of_module (void)
+{
+ emodules_depth = 0;
+ modules = (emodules_list *)0;
+ modnum = 0;
+}
+
+void
vars_of_module (void)
{
+ reinit_vars_of_module ();
+
DEFVAR_LISP ("module-version", &Vmodule_version /*
Emacs dynamic loading mechanism version, as a string.
the dynamic loading technology used in Emacs, if required. It is not
a given that this value will be the same as the Emacs version number.
*/ );
- Vmodule_version = Fpurecopy (build_string (EMODULES_VERSION));
+ Vmodule_version = build_string (EMODULES_VERSION);
DEFVAR_BOOL ("load-modules-quietly", &load_modules_quietly /*
*Set to t if module loading is to be silent.
staticpro (&Vmodule_extensions);
load_modules_quietly = 0;
- emodules_depth = 0;
- modules = (emodules_list *)0;
- modnum = 0;
Vmodule_load_path = Qnil;
Fprovide (intern ("modules"));
}
a SUBR with more than 8 arguments, use max_args == MANY.
See the DEFUN macro in lisp.h) */
#define PRIMITIVE_FUNCALL(rv, fn, av, ac) do { \
- void (*PF_fn)() = (void (*)()) (fn); \
+ void (*PF_fn)(void) = (void (*)(void)) fn; \
Lisp_Object *PF_av = (av); \
switch (ac) \
{ \
int max_specpdl_size;
/* Depth in Lisp evaluations and function calls. */
-int lisp_eval_depth;
+static int lisp_eval_depth;
/* Maximum allowed depth in Lisp evaluations and function calls. */
int max_lisp_eval_depth;
write_c_string (trailer, printcharfun);
}
-DEFINE_LRECORD_IMPLEMENTATION ("subr", subr,
- this_one_is_unmarkable, print_subr, 0, 0, 0, 0,
- Lisp_Subr);
+static const struct lrecord_description subr_description[] = {
+ { XD_DOC_STRING, offsetof(Lisp_Subr, doc) },
+ { XD_END }
+};
+
+DEFINE_BASIC_LRECORD_IMPLEMENTATION ("subr", subr,
+ this_one_is_unmarkable, print_subr, 0, 0, 0,
+ subr_description,
+ Lisp_Subr);
\f
/************************************************************************/
/* Entering the debugger */
static Lisp_Object
define_function (Lisp_Object name, Lisp_Object defn)
{
- if (purify_flag)
- defn = Fpurecopy (defn);
Ffset (name, defn);
LOADHIST_ATTACH (name);
return name;
if (!NILP (args = XCDR (args)))
{
Lisp_Object doc = XCAR (args);
-#if 0 /* FSFmacs */
- /* #### We should probably do this but it might be dangerous */
- if (purify_flag)
- doc = Fpurecopy (doc);
Fput (sym, Qvariable_documentation, doc);
-#else
- pure_put (sym, Qvariable_documentation, doc);
-#endif
if (!NILP (args = XCDR (args)))
error ("too many arguments");
}
#ifdef I18N3
if (!NILP (Vfile_domain))
- pure_put (sym, Qvariable_domain, Vfile_domain);
+ Fput (sym, Qvariable_domain, Vfile_domain);
#endif
LOADHIST_ATTACH (sym);
if (!NILP (args = XCDR (args)))
{
Lisp_Object doc = XCAR (args);
-#if 0 /* FSFmacs */
- /* #### We should probably do this but it might be dangerous */
- if (purify_flag)
- doc = Fpurecopy (doc);
Fput (sym, Qvariable_documentation, doc);
-#else
- pure_put (sym, Qvariable_documentation, doc);
-#endif
if (!NILP (args = XCDR (args)))
error ("too many arguments");
}
#ifdef I18N3
if (!NILP (Vfile_domain))
- pure_put (sym, Qvariable_domain, Vfile_domain);
+ Fput (sym, Qvariable_domain, Vfile_domain);
#endif
LOADHIST_ATTACH (sym);
return
((INTP (documentation) && XINT (documentation) < 0) ||
- ((STRINGP (documentation)) &&
+ (STRINGP (documentation) &&
(string_byte (XSTRING (documentation), 0) == '*')) ||
/* If (STRING . INTEGER), a negative integer means a user variable. */
{
Fsignal (Qwrong_type_argument,
Fcons (Qcommandp,
- ((EQ (cmd, final))
+ (EQ (cmd, final)
? list1 (cmd)
: list2 (cmd, final))));
return Qnil;
/* Attempt to avoid consing identical (string=) pure strings. */
file = Fsymbol_name (Fintern (file, Qnil));
}
-
- return Ffset (function,
- Fpurecopy (Fcons (Qautoload, list4 (file,
- docstring,
- interactive,
- type))));
+
+ return Ffset (function, Fcons (Qautoload, list4 (file,
+ docstring,
+ interactive,
+ type)));
}
Lisp_Object
if (max_args == UNEVALLED) /* Optimize for the common case */
{
backtrace.evalargs = 0;
- val = (((Lisp_Object (*) (Lisp_Object)) (subr_function (subr)))
+ val = (((Lisp_Object (*) (Lisp_Object)) subr_function (subr))
(original_args));
}
else if (nargs <= max_args)
backtrace.args = args;
backtrace.nargs = nargs;
- val = (((Lisp_Object (*) (int, Lisp_Object *)) (subr_function (subr)))
+ val = (((Lisp_Object (*) (int, Lisp_Object *)) subr_function (subr))
(nargs, args));
UNGCPRO;
}
else if (max_args == MANY)
{
- val = ((Lisp_Object (*) (int, Lisp_Object *)) (subr_function (subr)))
+ val = ((Lisp_Object (*) (int, Lisp_Object *)) subr_function (subr))
(fun_nargs, fun_args);
}
else if (max_args == UNEVALLED) /* Can't funcall a special form */
}
else
{
- struct gcpro gcpro1, gcpro2;
- GCPRO2 (sym, val);
+ struct gcpro gcpro1, gcpro2, gcpro3;
+ Lisp_Object globals = Qnil;
+ GCPRO3 (sym, val, globals);
for (;
CONSP (val) && ((cond == RUN_HOOKS_TO_COMPLETION)
{
/* t indicates this hook has a local binding;
it means to run the global binding too. */
- Lisp_Object globals = Fdefault_value (sym);
+ globals = Fdefault_value (sym);
if ((! CONSP (globals) || EQ (XCAR (globals), Qlambda)) &&
! NILP (globals))
/* gc_currently_forbidden = 1; Currently no reason to do this; */
cons = noseeum_cons (buffer, form);
- opaque = (warning_string ? make_opaque_ptr (warning_string) : Qnil);
+ opaque = (warning_string ? make_opaque_ptr ((void *)warning_string) : Qnil);
GCPRO2 (cons, opaque);
/* Qerror not Qt, so you can get a backtrace */
tem = condition_case_1 (Qerror,
catch_them_squirmers_eval_in_buffer, cons,
caught_a_squirmer, opaque);
free_cons (XCONS (cons));
- if (OPAQUEP (opaque))
+ if (OPAQUE_PTRP (opaque))
free_opaque_ptr (opaque);
UNGCPRO;
speccount = specpdl_depth();
specbind (Qinhibit_quit, Qt);
- opaque = (warning_string ? make_opaque_ptr (warning_string) : Qnil);
+ opaque = (warning_string ? make_opaque_ptr ((void *)warning_string) : Qnil);
GCPRO1 (opaque);
/* Qerror not Qt, so you can get a backtrace */
tem = condition_case_1 (Qerror,
catch_them_squirmers_run_hook, hook_symbol,
caught_a_squirmer, opaque);
- if (OPAQUEP (opaque))
+ if (OPAQUE_PTRP (opaque))
free_opaque_ptr (opaque);
UNGCPRO;
specbind (Qinhibit_quit, Qt);
cons = noseeum_cons (hook_symbol,
- warning_string ? make_opaque_ptr (warning_string)
+ warning_string ? make_opaque_ptr ((void *)warning_string)
: Qnil);
GCPRO1 (cons);
/* Qerror not Qt, so you can get a backtrace */
allow_quit_safe_run_hook_caught_a_squirmer :
safe_run_hook_caught_a_squirmer,
cons);
- if (OPAQUEP (XCDR (cons)))
+ if (OPAQUE_PTRP (XCDR (cons)))
free_opaque_ptr (XCDR (cons));
free_cons (XCONS (cons));
UNGCPRO;
specbind (Qinhibit_quit, Qt);
/* gc_currently_forbidden = 1; Currently no reason to do this; */
- opaque = (warning_string ? make_opaque_ptr (warning_string) : Qnil);
+ opaque = (warning_string ? make_opaque_ptr ((void *)warning_string) : Qnil);
/* Qerror not Qt, so you can get a backtrace */
tem = condition_case_1 (Qerror,
catch_them_squirmers_call0, function,
caught_a_squirmer, opaque);
- if (OPAQUEP (opaque))
+ if (OPAQUE_PTRP (opaque))
free_opaque_ptr (opaque);
UNGCPRO;
/* gc_currently_forbidden = 1; Currently no reason to do this; */
cons = noseeum_cons (function, object);
- opaque = (warning_string ? make_opaque_ptr (warning_string) : Qnil);
+ opaque = (warning_string ? make_opaque_ptr ((void *)warning_string) : Qnil);
/* Qerror not Qt, so you can get a backtrace */
tem = condition_case_1 (Qerror,
catch_them_squirmers_call1, cons,
caught_a_squirmer, opaque);
- if (OPAQUEP (opaque))
+ if (OPAQUE_PTRP (opaque))
free_opaque_ptr (opaque);
free_cons (XCONS (cons));
UNGCPRO;
/* gc_currently_forbidden = 1; Currently no reason to do this; */
cons = list3 (function, object1, object2);
- opaque = (warning_string ? make_opaque_ptr (warning_string) : Qnil);
+ opaque = (warning_string ? make_opaque_ptr ((void *)warning_string) : Qnil);
/* Qerror not Qt, so you can get a backtrace */
tem = condition_case_1 (Qerror,
catch_them_squirmers_call2, cons,
caught_a_squirmer, opaque);
- if (OPAQUEP (opaque))
+ if (OPAQUE_PTRP (opaque))
free_opaque_ptr (opaque);
free_list (cons);
UNGCPRO;
}
void
+reinit_vars_of_eval (void)
+{
+ preparing_for_armageddon = 0;
+ in_warnings = 0;
+ Qunbound_suspended_errors_tag = make_opaque_ptr (&Qunbound_suspended_errors_tag);
+ staticpro_nodump (&Qunbound_suspended_errors_tag);
+
+ specpdl_size = 50;
+ specpdl = xnew_array (struct specbinding, specpdl_size);
+ /* XEmacs change: increase these values. */
+ max_specpdl_size = 3000;
+ max_lisp_eval_depth = 500;
+#if 0 /* no longer used */
+ throw_level = 0;
+#endif
+}
+
+void
vars_of_eval (void)
{
+ reinit_vars_of_eval ();
+
DEFVAR_INT ("max-specpdl-size", &max_specpdl_size /*
Limit on number of Lisp variable bindings & unwind-protects before error.
*/ );
*/ );
Vdebugger = Qnil;
- preparing_for_armageddon = 0;
-
staticpro (&Vpending_warnings);
Vpending_warnings = Qnil;
- Vpending_warnings_tail = Qnil; /* no need to protect this */
-
- in_warnings = 0;
+ pdump_wire (&Vpending_warnings_tail);
+ Vpending_warnings_tail = Qnil;
staticpro (&Vautoload_queue);
Vautoload_queue = Qnil;
staticpro (&Vcurrent_error_state);
Vcurrent_error_state = Qnil; /* errors as normal */
- Qunbound_suspended_errors_tag = make_opaque_long (0);
- staticpro (&Qunbound_suspended_errors_tag);
-
- specpdl_size = 50;
- specpdl_depth_counter = 0;
- specpdl = xnew_array (struct specbinding, specpdl_size);
- /* XEmacs change: increase these values. */
- max_specpdl_size = 3000;
- max_lisp_eval_depth = 500;
-#if 0 /* no longer used */
- throw_level = 0;
-#endif
-
reinit_eval ();
}
break;
case Expose:
- x_redraw_exposed_area (f, event->xexpose.x, event->xexpose.y,
- event->xexpose.width, event->xexpose.height);
+ if (!check_for_ignored_expose (f, event->xexpose.x, event->xexpose.y,
+ event->xexpose.width, event->xexpose.height)
+ &&
+ !find_matching_subwindow (f, event->xexpose.x, event->xexpose.y,
+ event->xexpose.width, event->xexpose.height))
+ x_redraw_exposed_area (f, event->xexpose.x, event->xexpose.y,
+ event->xexpose.width, event->xexpose.height);
break;
case GraphicsExpose: /* This occurs when an XCopyArea's source area was
/* Xt interval id's might not fit into an int (they're pointers, as it
happens), so we need to provide a conversion list. */
-struct Xt_timeout
+static struct Xt_timeout
{
int id;
XtIntervalId interval_id;
struct Xt_timeout *next;
} *pending_timeouts, *completed_timeouts;
-struct Xt_timeout_blocktype
+static struct Xt_timeout_blocktype
{
Blocktype_declare (struct Xt_timeout);
} *the_Xt_timeout_blocktype;
}
void
-vars_of_event_Xt (void)
+reinit_vars_of_event_Xt (void)
{
- dispatch_event_queue = Qnil;
- staticpro (&dispatch_event_queue);
- dispatch_event_queue_tail = Qnil;
-
- /* this function only makes safe calls */
- init_what_input_once ();
-
Xt_event_stream = xnew (struct event_stream);
Xt_event_stream->event_pending_p = emacs_Xt_event_pending_p;
Xt_event_stream->next_event_cb = emacs_Xt_next_event;
Xt_event_stream->create_stream_pair_cb = emacs_Xt_create_stream_pair;
Xt_event_stream->delete_stream_pair_cb = emacs_Xt_delete_stream_pair;
+ the_Xt_timeout_blocktype = Blocktype_new (struct Xt_timeout_blocktype);
+
+ last_quit_check_signal_tick_count = 0;
+
+ /* this function only makes safe calls */
+ init_what_input_once ();
+}
+
+void
+vars_of_event_Xt (void)
+{
+ reinit_vars_of_event_Xt ();
+
+ dispatch_event_queue = Qnil;
+ staticpro (&dispatch_event_queue);
+ dispatch_event_queue_tail = Qnil;
+ pdump_wire (&dispatch_event_queue_tail);
+
DEFVAR_BOOL ("modifier-keys-are-sticky", &modifier_keys_are_sticky /*
*Non-nil makes modifier keys sticky.
This means that you can release the modifier key before pressing down
*/ );
x_debug_events = 0;
#endif
-
- the_Xt_timeout_blocktype = Blocktype_new (struct Xt_timeout_blocktype);
-
- last_quit_check_signal_tick_count = 0;
}
/* This mess is a hack that patches the shell widget to treat visual inheritance
static Lisp_Object mswindows_find_frame (HWND hwnd);
static Lisp_Object mswindows_find_console (HWND hwnd);
-static Lisp_Object mswindows_key_to_emacs_keysym(int mswindows_key, int mods);
+static Lisp_Object mswindows_key_to_emacs_keysym (int mswindows_key, int mods,
+ int extendedp);
static int mswindows_modifier_state (BYTE* keymap, int has_AltGr);
static void mswindows_set_chord_timer (HWND hwnd);
static int mswindows_button2_near_enough (POINTS p1, POINTS p2);
/* These are Lisp integers; see DEFVARS in this file for description. */
int mswindows_dynamic_frame_resize;
+int mswindows_meta_activates_menu;
int mswindows_num_mouse_buttons;
int mswindows_mouse_button_max_skew_x;
int mswindows_mouse_button_max_skew_y;
BYTE keymap[256];
int has_AltGr = mswindows_current_layout_has_AltGr ();
int mods;
+ int extendedp = lParam & 0x1000000;
Lisp_Object keysym;
GetKeyboardState (keymap);
mods = mswindows_modifier_state (keymap, has_AltGr);
- /* Handle those keys for which TranslateMessage won't generate a WM_CHAR */
- if (!NILP (keysym = mswindows_key_to_emacs_keysym(wParam, mods)))
+ /* Handle non-printables */
+ if (!NILP (keysym = mswindows_key_to_emacs_keysym (wParam, mods,
+ extendedp)))
mswindows_enqueue_keypress_event (hwnd, keysym, mods);
- else
+ else /* Normal keys & modifiers */
{
int quit_ch = CONSOLE_QUIT_CHAR (XCONSOLE (mswindows_find_console (hwnd)));
BYTE keymap_orig[256];
* to loosely track Left and Right modifiers on behalf of the OS,
* without screwing up Windows NT which tracks them properly. */
if (wParam == VK_CONTROL)
- keymap [(lParam & 0x1000000) ? VK_RCONTROL : VK_LCONTROL] |= 0x80;
+ keymap [extendedp ? VK_RCONTROL : VK_LCONTROL] |= 0x80;
else if (wParam == VK_MENU)
- keymap [(lParam & 0x1000000) ? VK_RMENU : VK_LMENU] |= 0x80;
+ keymap [extendedp ? VK_RMENU : VK_LMENU] |= 0x80;
memcpy (keymap_orig, keymap, 256);
} /* else */
}
/* F10 causes menu activation by default. We do not want this */
- if (wParam != VK_F10)
+ if (wParam != VK_F10 && (mswindows_meta_activates_menu || wParam != VK_MENU))
goto defproc;
break;
case WM_PAINT:
{
- PAINTSTRUCT paintStruct;
-
- frame = XFRAME (mswindows_find_frame (hwnd));
+ /* According to the docs we need to check GetUpdateRect() before
+ actually doing a WM_PAINT */
+ if (GetUpdateRect (hwnd, NULL, FALSE))
+ {
+ PAINTSTRUCT paintStruct;
+ int x, y, width, height;
+
+ frame = XFRAME (mswindows_find_frame (hwnd));
+
+ BeginPaint (hwnd, &paintStruct);
+ x = paintStruct.rcPaint.left;
+ y = paintStruct.rcPaint.top;
+ width = paintStruct.rcPaint.right - paintStruct.rcPaint.left;
+ height = paintStruct.rcPaint.bottom - paintStruct.rcPaint.top;
+ /* Normally we want to ignore expose events when child
+ windows are unmapped, however once we are in the guts of
+ WM_PAINT we need to make sure that we don't register
+ unmaps then because they will not actually occur. */
+ if (!check_for_ignored_expose (frame, x, y, width, height))
+ {
+ hold_ignored_expose_registration = 1;
+ mswindows_redraw_exposed_area (frame, x, y, width, height);
+ hold_ignored_expose_registration = 0;
+ }
- BeginPaint (hwnd, &paintStruct);
- mswindows_redraw_exposed_area (frame,
- paintStruct.rcPaint.left, paintStruct.rcPaint.top,
- paintStruct.rcPaint.right, paintStruct.rcPaint.bottom);
- EndPaint (hwnd, &paintStruct);
+ EndPaint (hwnd, &paintStruct);
+ }
+ else
+ goto defproc;
}
break;
UNGCPRO;
break;
}
+
+ case WM_MOUSEWHEEL:
+ {
+ int keys = LOWORD (wParam); /* Modifier key flags */
+ int delta = (short) HIWORD (wParam); /* Wheel rotation amount */
+ struct gcpro gcpro1, gcpro2;
+
+ if (mswindows_handle_mousewheel_event (mswindows_find_frame (hwnd), keys, delta))
+ {
+ GCPRO2 (emacs_event, fobj);
+ mswindows_pump_outstanding_events (); /* Can GC */
+ UNGCPRO;
+ }
+ else
+ goto defproc;
+ break;
+ }
#endif
#ifdef HAVE_MENUBARS
* Only returns non-Qnil for keys that don't generate WM_CHAR messages
* or whose ASCII codes (like space) xemacs doesn't like.
* Virtual key values are defined in winresrc.h
- * XXX I'm not sure that KEYSYM("name") is the best thing to use here.
*/
-Lisp_Object mswindows_key_to_emacs_keysym(int mswindows_key, int mods)
+Lisp_Object mswindows_key_to_emacs_keysym (int mswindows_key, int mods,
+ int extendedp)
{
- switch (mswindows_key)
- {
- /* First the predefined ones */
- case VK_BACK: return QKbackspace;
- case VK_TAB: return QKtab;
- case '\n': return QKlinefeed; /* No VK_LINEFEED in winresrc.h */
- case VK_RETURN: return QKreturn;
- case VK_ESCAPE: return QKescape;
- case VK_SPACE: return QKspace;
- case VK_DELETE: return QKdelete;
-
- /* The rest */
- case VK_CLEAR: return KEYSYM ("clear"); /* Should do ^L ? */
- case VK_PRIOR: return KEYSYM ("prior");
- case VK_NEXT: return KEYSYM ("next");
- case VK_END: return KEYSYM ("end");
- case VK_HOME: return KEYSYM ("home");
- case VK_LEFT: return KEYSYM ("left");
- case VK_UP: return KEYSYM ("up");
- case VK_RIGHT: return KEYSYM ("right");
- case VK_DOWN: return KEYSYM ("down");
- case VK_SELECT: return KEYSYM ("select");
- case VK_PRINT: return KEYSYM ("print");
- case VK_EXECUTE: return KEYSYM ("execute");
- case VK_SNAPSHOT: return KEYSYM ("print");
- case VK_INSERT: return KEYSYM ("insert");
- case VK_HELP: return KEYSYM ("help");
-#if 0 /* XXX What are these supposed to do? */
- case VK_LWIN return KEYSYM ("");
- case VK_RWIN return KEYSYM ("");
+ if (extendedp) /* Keys not present on a 82 key keyboard */
+ {
+ switch (mswindows_key)
+ {
+ case VK_RETURN: return KEYSYM ("kp-enter");
+ case VK_PRIOR: return KEYSYM ("prior");
+ case VK_NEXT: return KEYSYM ("next");
+ case VK_END: return KEYSYM ("end");
+ case VK_HOME: return KEYSYM ("home");
+ case VK_LEFT: return KEYSYM ("left");
+ case VK_UP: return KEYSYM ("up");
+ case VK_RIGHT: return KEYSYM ("right");
+ case VK_DOWN: return KEYSYM ("down");
+ case VK_INSERT: return KEYSYM ("insert");
+ case VK_DELETE: return QKdelete;
+ }
+ }
+ else
+ {
+ switch (mswindows_key)
+ {
+ case VK_BACK: return QKbackspace;
+ case VK_TAB: return QKtab;
+ case '\n': return QKlinefeed;
+ case VK_CLEAR: return KEYSYM ("clear");
+ case VK_RETURN: return QKreturn;
+ case VK_ESCAPE: return QKescape;
+ case VK_SPACE: return QKspace;
+ case VK_PRIOR: return KEYSYM ("kp-prior");
+ case VK_NEXT: return KEYSYM ("kp-next");
+ case VK_END: return KEYSYM ("kp-end");
+ case VK_HOME: return KEYSYM ("kp-home");
+ case VK_LEFT: return KEYSYM ("kp-left");
+ case VK_UP: return KEYSYM ("kp-up");
+ case VK_RIGHT: return KEYSYM ("kp-right");
+ case VK_DOWN: return KEYSYM ("kp-down");
+ case VK_SELECT: return KEYSYM ("select");
+ case VK_PRINT: return KEYSYM ("print");
+ case VK_EXECUTE: return KEYSYM ("execute");
+ case VK_SNAPSHOT: return KEYSYM ("print");
+ case VK_INSERT: return KEYSYM ("kp-insert");
+ case VK_DELETE: return KEYSYM ("kp-delete");
+ case VK_HELP: return KEYSYM ("help");
+#if 0 /* FSF Emacs allows these to return configurable syms/mods */
+ case VK_LWIN return KEYSYM ("");
+ case VK_RWIN return KEYSYM ("");
#endif
- case VK_APPS: return KEYSYM ("menu");
- case VK_F1: return KEYSYM ("f1");
- case VK_F2: return KEYSYM ("f2");
- case VK_F3: return KEYSYM ("f3");
- case VK_F4: return KEYSYM ("f4");
- case VK_F5: return KEYSYM ("f5");
- case VK_F6: return KEYSYM ("f6");
- case VK_F7: return KEYSYM ("f7");
- case VK_F8: return KEYSYM ("f8");
- case VK_F9: return KEYSYM ("f9");
- case VK_F10: return KEYSYM ("f10");
- case VK_F11: return KEYSYM ("f11");
- case VK_F12: return KEYSYM ("f12");
- case VK_F13: return KEYSYM ("f13");
- case VK_F14: return KEYSYM ("f14");
- case VK_F15: return KEYSYM ("f15");
- case VK_F16: return KEYSYM ("f16");
- case VK_F17: return KEYSYM ("f17");
- case VK_F18: return KEYSYM ("f18");
- case VK_F19: return KEYSYM ("f19");
- case VK_F20: return KEYSYM ("f20");
- case VK_F21: return KEYSYM ("f21");
- case VK_F22: return KEYSYM ("f22");
- case VK_F23: return KEYSYM ("f23");
- case VK_F24: return KEYSYM ("f24");
- }
+ case VK_APPS: return KEYSYM ("menu");
+ case VK_NUMPAD0: return KEYSYM ("kp-0");
+ case VK_NUMPAD1: return KEYSYM ("kp-1");
+ case VK_NUMPAD2: return KEYSYM ("kp-2");
+ case VK_NUMPAD3: return KEYSYM ("kp-3");
+ case VK_NUMPAD4: return KEYSYM ("kp-4");
+ case VK_NUMPAD5: return KEYSYM ("kp-5");
+ case VK_NUMPAD6: return KEYSYM ("kp-6");
+ case VK_NUMPAD7: return KEYSYM ("kp-7");
+ case VK_NUMPAD8: return KEYSYM ("kp-8");
+ case VK_NUMPAD9: return KEYSYM ("kp-9");
+ case VK_MULTIPLY: return KEYSYM ("kp-multiply");
+ case VK_ADD: return KEYSYM ("kp-add");
+ case VK_SEPARATOR: return KEYSYM ("kp-separator");
+ case VK_SUBTRACT: return KEYSYM ("kp-subtract");
+ case VK_DECIMAL: return KEYSYM ("kp-decimal");
+ case VK_DIVIDE: return KEYSYM ("kp-divide");
+ case VK_F1: return KEYSYM ("f1");
+ case VK_F2: return KEYSYM ("f2");
+ case VK_F3: return KEYSYM ("f3");
+ case VK_F4: return KEYSYM ("f4");
+ case VK_F5: return KEYSYM ("f5");
+ case VK_F6: return KEYSYM ("f6");
+ case VK_F7: return KEYSYM ("f7");
+ case VK_F8: return KEYSYM ("f8");
+ case VK_F9: return KEYSYM ("f9");
+ case VK_F10: return KEYSYM ("f10");
+ case VK_F11: return KEYSYM ("f11");
+ case VK_F12: return KEYSYM ("f12");
+ case VK_F13: return KEYSYM ("f13");
+ case VK_F14: return KEYSYM ("f14");
+ case VK_F15: return KEYSYM ("f15");
+ case VK_F16: return KEYSYM ("f16");
+ case VK_F17: return KEYSYM ("f17");
+ case VK_F18: return KEYSYM ("f18");
+ case VK_F19: return KEYSYM ("f19");
+ case VK_F20: return KEYSYM ("f20");
+ case VK_F21: return KEYSYM ("f21");
+ case VK_F22: return KEYSYM ("f22");
+ case VK_F23: return KEYSYM ("f23");
+ case VK_F24: return KEYSYM ("f24");
+ }
+ }
return Qnil;
}
/************************************************************************/
/* initialization */
/************************************************************************/
-
+
void
-vars_of_event_mswindows (void)
+reinit_vars_of_event_mswindows (void)
{
- mswindows_u_dispatch_event_queue = Qnil;
- staticpro (&mswindows_u_dispatch_event_queue);
- mswindows_u_dispatch_event_queue_tail = Qnil;
-
- mswindows_s_dispatch_event_queue = Qnil;
- staticpro (&mswindows_s_dispatch_event_queue);
- mswindows_s_dispatch_event_queue_tail = Qnil;
-
- mswindows_error_caught_in_modal_loop = Qnil;
- staticpro (&mswindows_error_caught_in_modal_loop);
mswindows_in_modal_loop = 0;
mswindows_pending_timers_count = 0;
mswindows_event_stream->create_stream_pair_cb = emacs_mswindows_create_stream_pair;
mswindows_event_stream->delete_stream_pair_cb = emacs_mswindows_delete_stream_pair;
#endif
+}
+
+void
+vars_of_event_mswindows (void)
+{
+ reinit_vars_of_event_mswindows ();
+
+ mswindows_u_dispatch_event_queue = Qnil;
+ staticpro (&mswindows_u_dispatch_event_queue);
+ mswindows_u_dispatch_event_queue_tail = Qnil;
+ pdump_wire (&mswindows_u_dispatch_event_queue_tail);
+
+ mswindows_s_dispatch_event_queue = Qnil;
+ staticpro (&mswindows_s_dispatch_event_queue);
+ mswindows_s_dispatch_event_queue_tail = Qnil;
+ pdump_wire (&mswindows_u_dispatch_event_queue_tail);
+
+ mswindows_error_caught_in_modal_loop = Qnil;
+ staticpro (&mswindows_error_caught_in_modal_loop);
+
+ DEFVAR_BOOL ("mswindows-meta-activates-menu", &mswindows_meta_activates_menu /*
+*Controls whether pressing and releasing the Meta (Alt) key should
+activate the menubar.
+Default is t.
+*/ );
DEFVAR_BOOL ("mswindows-dynamic-frame-resize", &mswindows_dynamic_frame_resize /*
*Controls redrawing frame contents during mouse-drag or keyboard resize
mswindows_mouse_button_max_skew_x = 0;
mswindows_mouse_button_max_skew_y = 0;
mswindows_mouse_button_tolerance = 0;
+ mswindows_meta_activates_menu = 1;
}
void
#include "keymap.h"
#include "lstream.h"
#include "macros.h" /* for defining_keyboard_macro */
-#include "opaque.h"
#include "process.h"
#include "window.h"
Lisp_Object Qundefined_keystroke_sequence;
-Lisp_Object Qcommand_execute;
-
Lisp_Object Qcommand_event_p;
/* Hooks to run before and after each command. */
#define CHECK_COMMAND_BUILDER(x) CHECK_RECORD (x, command_builder)
static Lisp_Object
-mark_command_builder (Lisp_Object obj, void (*markobj) (Lisp_Object))
+mark_command_builder (Lisp_Object obj)
{
struct command_builder *builder = XCOMMAND_BUILDER (obj);
- markobj (builder->prefix_events);
- markobj (builder->current_events);
- markobj (builder->most_current_event);
- markobj (builder->last_non_munged_event);
- markobj (builder->munge_me[0].first_mungeable_event);
- markobj (builder->munge_me[1].first_mungeable_event);
+ mark_object (builder->prefix_events);
+ mark_object (builder->current_events);
+ mark_object (builder->most_current_event);
+ mark_object (builder->last_non_munged_event);
+ mark_object (builder->munge_me[0].first_mungeable_event);
+ mark_object (builder->munge_me[1].first_mungeable_event);
return builder->console;
}
used to indicate an absence of a timer. */
static int low_level_timeout_id_tick;
-struct low_level_timeout_blocktype
+static struct low_level_timeout_blocktype
{
Blocktype_declare (struct low_level_timeout);
} *the_low_level_timeout_blocktype;
static int timeout_id_tick;
-/* Since timeout structures contain Lisp_Objects, they need to be GC'd
- properly. The opaque data type provides a convenient way of doing
- this without having to create a new Lisp object, since we can
- provide our own mark function. */
-
-struct timeout
-{
- int id; /* Id we use to identify the timeout over its lifetime */
- int interval_id; /* Id for this particular interval; this may
- be different each time the timeout is
- signalled.*/
- Lisp_Object function, object; /* Function and object associated
- with timeout. */
- EMACS_TIME next_signal_time; /* Absolute time when the timeout
- is next going to be signalled. */
- unsigned int resignal_msecs; /* How far after the next timeout
- should the one after that
- occur? */
-};
-
static Lisp_Object pending_timeout_list, pending_async_timeout_list;
static Lisp_Object Vtimeout_free_list;
static Lisp_Object
-mark_timeout (Lisp_Object obj, void (*markobj) (Lisp_Object))
+mark_timeout (Lisp_Object obj)
{
- struct timeout *tm = (struct timeout *) XOPAQUE_DATA (obj);
- markobj (tm->function);
+ struct Lisp_Timeout *tm = XTIMEOUT (obj);
+ mark_object (tm->function);
return tm->object;
}
+/* Should never, ever be called. (except by an external debugger) */
+static void
+print_timeout (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
+{
+ CONST struct Lisp_Timeout *t = XTIMEOUT (obj);
+ char buf[64];
+
+ sprintf (buf, "#<INTERNAL OBJECT (XEmacs bug?) (timeout) 0x%lx>",
+ (unsigned long) t);
+ write_c_string (buf, printcharfun);
+}
+
+static const struct lrecord_description timeout_description[] = {
+ { XD_LISP_OBJECT, offsetof(struct Lisp_Timeout, function), 2 },
+ { XD_END }
+};
+
+DEFINE_LRECORD_IMPLEMENTATION ("timeout", timeout,
+ mark_timeout, print_timeout,
+ 0, 0, 0, timeout_description, struct Lisp_Timeout);
+
/* Generate a timeout and return its ID. */
int
Lisp_Object function, Lisp_Object object,
int async_p)
{
- Lisp_Object op = allocate_managed_opaque (Vtimeout_free_list, 0);
- struct timeout *timeout = (struct timeout *) XOPAQUE_DATA (op);
+ Lisp_Object op = allocate_managed_lcrecord (Vtimeout_free_list);
+ struct Lisp_Timeout *timeout = XTIMEOUT (op);
EMACS_TIME current_time;
EMACS_TIME interval;
Lisp_Object *function, Lisp_Object *object)
{
Lisp_Object op = Qnil, rest;
- struct timeout *timeout;
+ struct Lisp_Timeout *timeout;
Lisp_Object *timeout_list;
struct gcpro gcpro1;
int id;
/* Find the timeout on the list of pending ones. */
LIST_LOOP (rest, *timeout_list)
{
- timeout = (struct timeout *) XOPAQUE_DATA (XCAR (rest));
+ timeout = XTIMEOUT (XCAR (rest));
if (timeout->interval_id == interval_id)
break;
}
assert (!NILP (rest));
op = XCAR (rest);
- timeout = (struct timeout *) XOPAQUE_DATA (op);
+ timeout = XTIMEOUT (op);
/* We make sure to snarf the data out of the timeout object before
- we free it with free_managed_opaque(). */
+ we free it with free_managed_lcrecord(). */
id = timeout->id;
*function = timeout->function;
*object = timeout->object;
*timeout_list = noseeum_cons (op, *timeout_list);
}
else
- free_managed_opaque (Vtimeout_free_list, op);
+ free_managed_lcrecord (Vtimeout_free_list, op);
UNGCPRO;
return id;
void
event_stream_disable_wakeup (int id, int async_p)
{
- struct timeout *timeout = 0;
+ struct Lisp_Timeout *timeout = 0;
Lisp_Object rest;
Lisp_Object *timeout_list;
/* Find the timeout on the list of pending ones, if it's still there. */
LIST_LOOP (rest, *timeout_list)
{
- timeout = (struct timeout *) XOPAQUE_DATA (XCAR (rest));
+ timeout = XTIMEOUT (XCAR (rest));
if (timeout->id == id)
break;
}
event_stream_remove_async_timeout (timeout->interval_id);
else
event_stream_remove_timeout (timeout->interval_id);
- free_managed_opaque (Vtimeout_free_list, op);
+ free_managed_lcrecord (Vtimeout_free_list, op);
}
}
static int
event_stream_wakeup_pending_p (int id, int async_p)
{
- struct timeout *timeout;
+ struct Lisp_Timeout *timeout;
Lisp_Object rest;
Lisp_Object timeout_list;
int found = 0;
/* Find the element on the list of pending ones, if it's still there. */
LIST_LOOP (rest, timeout_list)
{
- timeout = (struct timeout *) XOPAQUE_DATA (XCAR (rest));
+ timeout = XTIMEOUT (XCAR (rest));
if (timeout->id == id)
{
found = 1;
deferror (&Qundefined_keystroke_sequence, "undefined-keystroke-sequence",
"Undefined keystroke sequence", Qerror);
- defsymbol (&Qcommand_execute, "command-execute");
DEFSUBR (Frecent_keys);
DEFSUBR (Frecent_keys_ring_size);
}
void
-vars_of_event_stream (void)
+reinit_vars_of_event_stream (void)
{
recent_keys_ring_index = 0;
recent_keys_ring_size = 100;
+ num_input_chars = 0;
+ Vtimeout_free_list = make_lcrecord_list (sizeof (struct Lisp_Timeout),
+ &lrecord_timeout);
+ staticpro_nodump (&Vtimeout_free_list);
+ the_low_level_timeout_blocktype =
+ Blocktype_new (struct low_level_timeout_blocktype);
+ something_happened = 0;
+ recursive_sit_for = Qnil;
+}
+
+void
+vars_of_event_stream (void)
+{
+ reinit_vars_of_event_stream ();
Vrecent_keys_ring = Qnil;
staticpro (&Vrecent_keys_ring);
Vthis_command_keys = Qnil;
staticpro (&Vthis_command_keys);
Vthis_command_keys_tail = Qnil;
-
- num_input_chars = 0;
+ pdump_wire (&Vthis_command_keys_tail);
command_event_queue = Qnil;
staticpro (&command_event_queue);
command_event_queue_tail = Qnil;
+ pdump_wire (&command_event_queue_tail);
Vlast_selected_frame = Qnil;
staticpro (&Vlast_selected_frame);
pending_async_timeout_list = Qnil;
staticpro (&pending_async_timeout_list);
- Vtimeout_free_list = make_opaque_list (sizeof (struct timeout),
- mark_timeout);
- staticpro (&Vtimeout_free_list);
-
- the_low_level_timeout_blocktype =
- Blocktype_new (struct low_level_timeout_blocktype);
-
- something_happened = 0;
-
last_point_position_buffer = Qnil;
staticpro (&last_point_position_buffer);
- recursive_sit_for = Qnil;
-
DEFVAR_LISP ("echo-keystrokes", &Vecho_keystrokes /*
*Nonzero means echo unfinished commands after this many seconds of pause.
*/ );
/************************************************************************/
void
-vars_of_event_tty (void)
+reinit_vars_of_event_tty (void)
{
tty_event_stream = xnew (struct event_stream);
}
void
+vars_of_event_tty (void)
+{
+ reinit_vars_of_event_tty ();
+}
+
+void
init_event_tty_late (void)
{
event_stream = tty_event_stream;
}
static Lisp_Object
-mark_event (Lisp_Object obj, void (*markobj) (Lisp_Object))
+mark_event (Lisp_Object obj)
{
struct Lisp_Event *event = XEVENT (obj);
switch (event->event_type)
{
case key_press_event:
- markobj (event->event.key.keysym);
+ mark_object (event->event.key.keysym);
break;
case process_event:
- markobj (event->event.process.process);
+ mark_object (event->event.process.process);
break;
case timeout_event:
- markobj (event->event.timeout.function);
- markobj (event->event.timeout.object);
+ mark_object (event->event.timeout.function);
+ mark_object (event->event.timeout.object);
break;
case eval_event:
case misc_user_event:
- markobj (event->event.eval.function);
- markobj (event->event.eval.object);
+ mark_object (event->event.eval.function);
+ mark_object (event->event.eval.object);
break;
case magic_eval_event:
- markobj (event->event.magic_eval.object);
+ mark_object (event->event.magic_eval.object);
break;
case button_press_event:
case button_release_event:
default:
abort ();
}
- markobj (event->channel);
+ mark_object (event->channel);
return event->next;
}
defsymbol (&Qbutton_release, "button-release");
defsymbol (&Qmisc_user, "misc-user");
defsymbol (&Qascii_character, "ascii-character");
+
+ defsymbol (&QKbackspace, "backspace");
+ defsymbol (&QKtab, "tab");
+ defsymbol (&QKlinefeed, "linefeed");
+ defsymbol (&QKreturn, "return");
+ defsymbol (&QKescape, "escape");
+ defsymbol (&QKspace, "space");
+ defsymbol (&QKdelete, "delete");
+}
+
+
+void
+reinit_vars_of_events (void)
+{
+ Vevent_resource = Qnil;
}
void
vars_of_events (void)
{
+ reinit_vars_of_events ();
+
DEFVAR_LISP ("character-set-property", &Vcharacter_set_property /*
A symbol used to look up the 8-bit character of a keysym.
To convert a keysym symbol to an 8-bit code, as when that key is
variable.
*/ );
Vcharacter_set_property = Qnil;
-
- Vevent_resource = Qnil;
-
- QKbackspace = KEYSYM ("backspace");
- QKtab = KEYSYM ("tab");
- QKlinefeed = KEYSYM ("linefeed");
- QKreturn = KEYSYM ("return");
- QKescape = KEYSYM ("escape");
- QKspace = KEYSYM ("space");
- QKdelete = KEYSYM ("delete");
-
- staticpro (&QKbackspace);
- staticpro (&QKtab);
- staticpro (&QKlinefeed);
- staticpro (&QKreturn);
- staticpro (&QKescape);
- staticpro (&QKspace);
- staticpro (&QKdelete);
}
#endif
};
+struct Lisp_Timeout
+{
+ struct lcrecord_header header;
+ int id; /* Id we use to identify the timeout over its lifetime */
+ int interval_id; /* Id for this particular interval; this may
+ be different each time the timeout is
+ signalled.*/
+ Lisp_Object function, object; /* Function and object associated
+ with timeout. */
+ EMACS_TIME next_signal_time; /* Absolute time when the timeout
+ is next going to be signalled. */
+ unsigned int resignal_msecs; /* How far after the next timeout
+ should the one after that
+ occur? */
+};
+
+DECLARE_LRECORD (timeout, struct Lisp_Timeout);
+#define XTIMEOUT(x) XRECORD (x, timeout, struct Lisp_Timeout)
+#define XSETTIMEOUT(x, p) XSETRECORD (x, p, timeout)
+#define TIMEOUTP(x) RECORDP (x, timeout)
+#define CHECK_TIMEOUT(x) CHECK_RECORD (x, timeout)
+#define CONCHECK_TIMEOUT(x) CONCHECK_RECORD (x, timeout)
+
struct Lisp_Event
{
/* header->next (aka XEVENT_NEXT ()) is used as follows:
#define XEVENT(x) XRECORD (x, event, struct Lisp_Event)
#define XSETEVENT(x, p) XSETRECORD (x, p, event)
#define EVENTP(x) RECORDP (x, event)
-#define GC_EVENTP(x) GC_RECORDP (x, event)
#define CHECK_EVENT(x) CHECK_RECORD (x, event)
#define CONCHECK_EVENT(x) CONCHECK_RECORD (x, event)
Gap_Array_Marker *markers;
} Gap_Array;
-Gap_Array_Marker *gap_array_marker_freelist;
+static Gap_Array_Marker *gap_array_marker_freelist;
/* Convert a "memory position" (i.e. taking the gap into account) into
the address of the element at (i.e. after) that position. "Memory
Extent_List_Marker *markers;
} Extent_List;
-Extent_List_Marker *extent_list_marker_freelist;
+static Extent_List_Marker *extent_list_marker_freelist;
#define EXTENT_LESS_VALS(e,st,nd) ((extent_start (e) < (st)) || \
((extent_start (e) == (st)) && \
Lisp_Object Qwhitespace;
/* Qtext defined in general.c */
-/* partially used in redisplay */
-Lisp_Object Qglyph_invisible;
-
Lisp_Object Qcopy_function;
Lisp_Object Qpaste_function;
/************************************************************************/
static Lisp_Object
-mark_extent_auxiliary (Lisp_Object obj, void (*markobj) (Lisp_Object))
+mark_extent_auxiliary (Lisp_Object obj)
{
struct extent_auxiliary *data = XEXTENT_AUXILIARY (obj);
- markobj (data->begin_glyph);
- markobj (data->end_glyph);
- markobj (data->invisible);
- markobj (data->children);
- markobj (data->read_only);
- markobj (data->mouse_face);
- markobj (data->initial_redisplay_function);
- markobj (data->before_change_functions);
- markobj (data->after_change_functions);
+ mark_object (data->begin_glyph);
+ mark_object (data->end_glyph);
+ mark_object (data->invisible);
+ mark_object (data->children);
+ mark_object (data->read_only);
+ mark_object (data->mouse_face);
+ mark_object (data->initial_redisplay_function);
+ mark_object (data->before_change_functions);
+ mark_object (data->after_change_functions);
return data->parent;
}
static void soe_invalidate (Lisp_Object obj);
static Lisp_Object
-mark_extent_info (Lisp_Object obj, void (*markobj) (Lisp_Object))
+mark_extent_info (Lisp_Object obj)
{
struct extent_info *data = (struct extent_info *) XEXTENT_INFO (obj);
int i;
Lisp_Object exobj;
XSETEXTENT (exobj, extent);
- markobj (exobj);
+ mark_object (exobj);
}
}
extent objects. They are similar to the functions for other
lrecord objects. allocate_extent() is in alloc.c, not here. */
-static Lisp_Object mark_extent (Lisp_Object, void (*) (Lisp_Object));
+static Lisp_Object mark_extent (Lisp_Object);
static int extent_equal (Lisp_Object, Lisp_Object, int depth);
static unsigned long extent_hash (Lisp_Object obj, int depth);
static void print_extent (Lisp_Object obj, Lisp_Object printcharfun,
struct extent);
static Lisp_Object
-mark_extent (Lisp_Object obj, void (*markobj) (Lisp_Object))
+mark_extent (Lisp_Object obj)
{
struct extent *extent = XEXTENT (obj);
- markobj (extent_object (extent));
- markobj (extent_no_chase_normal_field (extent, face));
+ mark_object (extent_object (extent));
+ mark_object (extent_no_chase_normal_field (extent, face));
return extent->plist;
}
if (extent_detached_p (ext))
strcpy (bp, "detached");
else
- {
- Bufpos from = XINT (Fextent_start_position (obj));
- Bufpos to = XINT (Fextent_end_position (obj));
- sprintf (bp, "%d, %d", from, to);
- }
+ sprintf (bp, "%ld, %ld",
+ (long) XINT (Fextent_start_position (obj)),
+ (long) XINT (Fextent_end_position (obj)));
bp += strlen (bp);
*bp++ = (extent_end_open_p (anc) ? ')': ']');
if (!NILP (extent_end_glyph (anc))) *bp++ = '*';
return -1;
}
- return external_remprop (&ext->plist, prop, 0, ERROR_ME);
+ return external_remprop (extent_plist_addr (ext), prop, 0, ERROR_ME);
}
static Lisp_Object
defsymbol (&Qwhitespace, "whitespace");
/* Qtext defined in general.c */
- defsymbol (&Qglyph_invisible, "glyph-invisible");
-
defsymbol (&Qpaste_function, "paste-function");
defsymbol (&Qcopy_function, "copy-function");
}
void
+reinit_vars_of_extents (void)
+{
+ extent_auxiliary_defaults.begin_glyph = Qnil;
+ extent_auxiliary_defaults.end_glyph = Qnil;
+ extent_auxiliary_defaults.parent = Qnil;
+ extent_auxiliary_defaults.children = Qnil;
+ extent_auxiliary_defaults.priority = 0;
+ extent_auxiliary_defaults.invisible = Qnil;
+ extent_auxiliary_defaults.read_only = Qnil;
+ extent_auxiliary_defaults.mouse_face = Qnil;
+ extent_auxiliary_defaults.initial_redisplay_function = Qnil;
+ extent_auxiliary_defaults.before_change_functions = Qnil;
+ extent_auxiliary_defaults.after_change_functions = Qnil;
+}
+
+void
vars_of_extents (void)
{
+ reinit_vars_of_extents ();
+
DEFVAR_INT ("mouse-highlight-priority", &mouse_highlight_priority /*
The priority to use for the mouse-highlighting pseudo-extent
that is used to highlight extents with the `mouse-face' attribute set.
Vextent_face_reusable_list = Fcons (Qnil, Qnil);
staticpro (&Vextent_face_reusable_list);
-
- extent_auxiliary_defaults.begin_glyph = Qnil;
- extent_auxiliary_defaults.end_glyph = Qnil;
- extent_auxiliary_defaults.parent = Qnil;
- extent_auxiliary_defaults.children = Qnil;
- extent_auxiliary_defaults.priority = 0;
- extent_auxiliary_defaults.invisible = Qnil;
- extent_auxiliary_defaults.read_only = Qnil;
- extent_auxiliary_defaults.mouse_face = Qnil;
- extent_auxiliary_defaults.initial_redisplay_function = Qnil;
- extent_auxiliary_defaults.before_change_functions = Qnil;
- extent_auxiliary_defaults.after_change_functions = Qnil;
}
void
#define XEXTENT(x) XRECORD (x, extent, struct extent)
#define XSETEXTENT(x, p) XSETRECORD (x, p, extent)
#define EXTENTP(x) RECORDP (x, extent)
-#define GC_EXTENTP(x) GC_RECORDP (x, extent)
#define CHECK_EXTENT(x) CHECK_RECORD (x, extent)
#define CONCHECK_EXTENT(x) CONCHECK_RECORD (x, extent)
XRECORD (x, extent_auxiliary, struct extent_auxiliary)
#define XSETEXTENT_AUXILIARY(x, p) XSETRECORD (x, p, extent_auxiliary)
#define EXTENT_AUXILIARYP(x) RECORDP (x, extent_auxiliary)
-#define GC_EXTENT_AUXILIARYP(x) GC_RECORDP (x, extent_auxiliary)
#define CHECK_EXTENT_AUXILIARY(x) CHECK_RECORD (x, extent_auxiliary)
#define CONCHECK_EXTENT_AUXILIARY(x) CONCHECK_RECORD (x, extent_auxiliary)
#define XEXTENT_INFO(x) XRECORD (x, extent_info, struct extent_info)
#define XSETEXTENT_INFO(x, p) XSETRECORD (x, p, extent_info)
#define EXTENT_INFOP(x) RECORDP (x, extent_info)
-#define GC_EXTENT_INFOP(x) GC_RECORDP (x, extent_info)
#define CHECK_EXTENT_INFO(x) CHECK_RECORD (x, extent_info)
#define CONCHECK_EXTENT_INFO(x) CONCHECK_RECORD (x, extent_info)
\f
static Lisp_Object
-mark_face (Lisp_Object obj, void (*markobj) (Lisp_Object))
+mark_face (Lisp_Object obj)
{
struct Lisp_Face *face = XFACE (obj);
- markobj (face->name);
- markobj (face->doc_string);
+ mark_object (face->name);
+ mark_object (face->doc_string);
- markobj (face->foreground);
- markobj (face->background);
- markobj (face->font);
- markobj (face->display_table);
- markobj (face->background_pixmap);
- markobj (face->underline);
- markobj (face->strikethru);
- markobj (face->highlight);
- markobj (face->dim);
- markobj (face->blinking);
- markobj (face->reverse);
+ mark_object (face->foreground);
+ mark_object (face->background);
+ mark_object (face->font);
+ mark_object (face->display_table);
+ mark_object (face->background_pixmap);
+ mark_object (face->underline);
+ mark_object (face->strikethru);
+ mark_object (face->highlight);
+ mark_object (face->dim);
+ mark_object (face->blinking);
+ mark_object (face->reverse);
- markobj (face->charsets_warned_about);
+ mark_object (face->charsets_warned_about);
return face->plist;
}
struct Lisp_Face *f = XFACE (obj);
return
- ((EQ (prop, Qforeground)) ? f->foreground :
- (EQ (prop, Qbackground)) ? f->background :
- (EQ (prop, Qfont)) ? f->font :
- (EQ (prop, Qdisplay_table)) ? f->display_table :
- (EQ (prop, Qbackground_pixmap)) ? f->background_pixmap :
- (EQ (prop, Qunderline)) ? f->underline :
- (EQ (prop, Qstrikethru)) ? f->strikethru :
- (EQ (prop, Qhighlight)) ? f->highlight :
- (EQ (prop, Qdim)) ? f->dim :
- (EQ (prop, Qblinking)) ? f->blinking :
- (EQ (prop, Qreverse)) ? f->reverse :
- (EQ (prop, Qdoc_string)) ? f->doc_string :
+ (EQ (prop, Qforeground) ? f->foreground :
+ EQ (prop, Qbackground) ? f->background :
+ EQ (prop, Qfont) ? f->font :
+ EQ (prop, Qdisplay_table) ? f->display_table :
+ EQ (prop, Qbackground_pixmap) ? f->background_pixmap :
+ EQ (prop, Qunderline) ? f->underline :
+ EQ (prop, Qstrikethru) ? f->strikethru :
+ EQ (prop, Qhighlight) ? f->highlight :
+ EQ (prop, Qdim) ? f->dim :
+ EQ (prop, Qblinking) ? f->blinking :
+ EQ (prop, Qreverse) ? f->reverse :
+ EQ (prop, Qdoc_string) ? f->doc_string :
external_plist_get (&f->plist, prop, 0, ERROR_ME));
}
return result;
}
+static const struct lrecord_description face_description[] = {
+ { XD_LISP_OBJECT, offsetof(struct Lisp_Face, name), 2 },
+ { XD_LISP_OBJECT, offsetof(struct Lisp_Face, foreground), 13 },
+ { XD_END }
+};
+
DEFINE_LRECORD_IMPLEMENTATION_WITH_PROPS ("face", face,
mark_face, print_face, 0, face_equal,
- face_hash, 0, face_getprop,
+ face_hash, face_description, face_getprop,
face_putprop, face_remprop,
face_plist, struct Lisp_Face);
\f
/* mark for GC a dynarr of face cachels. */
void
-mark_face_cachels (face_cachel_dynarr *elements,
- void (*markobj) (Lisp_Object))
+mark_face_cachels (face_cachel_dynarr *elements)
{
int elt;
for (i = 0; i < NUM_LEADING_BYTES; i++)
if (!NILP (cachel->font[i]) && !UNBOUNDP (cachel->font[i]))
- markobj (cachel->font[i]);
+ mark_object (cachel->font[i]);
}
- markobj (cachel->face);
- markobj (cachel->foreground);
- markobj (cachel->background);
- markobj (cachel->display_table);
- markobj (cachel->background_pixmap);
+ mark_object (cachel->face);
+ mark_object (cachel->foreground);
+ mark_object (cachel->background);
+ mark_object (cachel->display_table);
+ mark_object (cachel->background_pixmap);
}
}
#define XFACE(x) XRECORD (x, face, struct Lisp_Face)
#define XSETFACE(x, p) XSETRECORD (x, p, face)
#define FACEP(x) RECORDP (x, face)
-#define GC_FACEP(x) GC_RECORDP (x, face)
#define CHECK_FACE(x) CHECK_RECORD (x, face)
Lisp_Object ensure_face_cachel_contains_charset (struct face_cachel *cachel,
void face_cachel_charset_font_metric_info (struct face_cachel *cachel,
unsigned char *charsets,
struct font_metric_info *fm);
-void mark_face_cachels (face_cachel_dynarr *elements,
- void (*markobj) (Lisp_Object));
+void mark_face_cachels (face_cachel_dynarr *elements);
void mark_face_cachels_as_clean (struct window *w);
void mark_face_cachels_as_not_updated (struct window *w);
void reset_face_cachel (struct face_cachel *inst);
#endif
#include "file-coding.h"
-Lisp_Object Qbuffer_file_coding_system, Qcoding_system_error;
+Lisp_Object Qcoding_system_error;
Lisp_Object Vkeyboard_coding_system;
Lisp_Object Vterminal_coding_system;
/* Table of symbols identifying each coding category. */
Lisp_Object coding_category_symbol[CODING_CATEGORY_LAST + 1];
-/* Coding system currently associated with each coding category. */
-Lisp_Object coding_category_system[CODING_CATEGORY_LAST + 1];
-/* Table of all coding categories in decreasing order of priority.
- This describes a permutation of the possible coding categories. */
-int coding_category_by_priority[CODING_CATEGORY_LAST + 1];
-Lisp_Object Qcoding_system_p;
+struct file_coding_dump {
+ /* Coding system currently associated with each coding category. */
+ Lisp_Object coding_category_system[CODING_CATEGORY_LAST + 1];
+
+ /* Table of all coding categories in decreasing order of priority.
+ This describes a permutation of the possible coding categories. */
+ int coding_category_by_priority[CODING_CATEGORY_LAST + 1];
+
+ Lisp_Object ucs_to_mule_table[65536];
+} *fcd;
+
+static const struct lrecord_description fcd_description_1[] = {
+ { XD_LISP_OBJECT, offsetof(struct file_coding_dump, coding_category_system), CODING_CATEGORY_LAST + 1 },
+ { XD_LISP_OBJECT, offsetof(struct file_coding_dump, ucs_to_mule_table), 65536 },
+ { XD_END }
+};
+
+static const struct struct_description fcd_description = {
+ sizeof(struct file_coding_dump),
+ fcd_description_1
+};
+
+Lisp_Object mule_to_ucs_table;
+
+Lisp_Object Qcoding_systemp;
Lisp_Object Qraw_text, Qno_conversion, Qccl, Qiso2022;
/* Qinternal in general.c */
Dynarr_declare (codesys_prop);
} codesys_prop_dynarr;
+static const struct lrecord_description codesys_prop_description_1[] = {
+ { XD_LISP_OBJECT, offsetof(codesys_prop, sym), 1 },
+ { XD_END }
+};
+
+static const struct struct_description codesys_prop_description = {
+ sizeof(codesys_prop),
+ codesys_prop_description_1
+};
+
+static const struct lrecord_description codesys_prop_dynarr_description_1[] = {
+ XD_DYNARR_DESC(codesys_prop_dynarr, &codesys_prop_description),
+ { XD_END }
+};
+
+static const struct struct_description codesys_prop_dynarr_description = {
+ sizeof(codesys_prop_dynarr),
+ codesys_prop_dynarr_description_1
+};
+
codesys_prop_dynarr *the_codesys_prop_dynarr;
enum codesys_prop_enum
/* Coding system functions */
/************************************************************************/
-static Lisp_Object mark_coding_system (Lisp_Object, void (*) (Lisp_Object));
+static Lisp_Object mark_coding_system (Lisp_Object);
static void print_coding_system (Lisp_Object, Lisp_Object, int);
static void finalize_coding_system (void *header, int for_disksave);
struct Lisp_Coding_System);
static Lisp_Object
-mark_coding_system (Lisp_Object obj, void (*markobj) (Lisp_Object))
+mark_coding_system (Lisp_Object obj)
{
Lisp_Coding_System *codesys = XCODING_SYSTEM (obj);
- markobj (CODING_SYSTEM_NAME (codesys));
- markobj (CODING_SYSTEM_DOC_STRING (codesys));
- markobj (CODING_SYSTEM_MNEMONIC (codesys));
- markobj (CODING_SYSTEM_EOL_LF (codesys));
- markobj (CODING_SYSTEM_EOL_CRLF (codesys));
- markobj (CODING_SYSTEM_EOL_CR (codesys));
+ mark_object (CODING_SYSTEM_NAME (codesys));
+ mark_object (CODING_SYSTEM_DOC_STRING (codesys));
+ mark_object (CODING_SYSTEM_MNEMONIC (codesys));
+ mark_object (CODING_SYSTEM_EOL_LF (codesys));
+ mark_object (CODING_SYSTEM_EOL_CRLF (codesys));
+ mark_object (CODING_SYSTEM_EOL_CR (codesys));
switch (CODING_SYSTEM_TYPE (codesys))
{
int i;
case CODESYS_ISO2022:
for (i = 0; i < 4; i++)
- markobj (CODING_SYSTEM_ISO2022_INITIAL_CHARSET (codesys, i));
+ mark_object (CODING_SYSTEM_ISO2022_INITIAL_CHARSET (codesys, i));
if (codesys->iso2022.input_conv)
{
for (i = 0; i < Dynarr_length (codesys->iso2022.input_conv); i++)
{
struct charset_conversion_spec *ccs =
Dynarr_atp (codesys->iso2022.input_conv, i);
- markobj (ccs->from_charset);
- markobj (ccs->to_charset);
+ mark_object (ccs->from_charset);
+ mark_object (ccs->to_charset);
}
}
if (codesys->iso2022.output_conv)
{
struct charset_conversion_spec *ccs =
Dynarr_atp (codesys->iso2022.output_conv, i);
- markobj (ccs->from_charset);
- markobj (ccs->to_charset);
+ mark_object (ccs->from_charset);
+ mark_object (ccs->to_charset);
}
}
break;
case CODESYS_CCL:
- markobj (CODING_SYSTEM_CCL_DECODE (codesys));
- markobj (CODING_SYSTEM_CCL_ENCODE (codesys));
+ mark_object (CODING_SYSTEM_CCL_DECODE (codesys));
+ mark_object (CODING_SYSTEM_CCL_ENCODE (codesys));
break;
#endif /* MULE */
default:
break;
}
- markobj (CODING_SYSTEM_PRE_WRITE_CONVERSION (codesys));
+ mark_object (CODING_SYSTEM_PRE_WRITE_CONVERSION (codesys));
return CODING_SYSTEM_POST_READ_CONVERSION (codesys);
}
order. */
for (j = 0; j <= CODING_CATEGORY_LAST; j++)
{
- int cat = coding_category_by_priority[j];
+ int cat = fcd->coding_category_by_priority[j];
if (category_to_priority[cat] < 0)
category_to_priority[cat] = i++;
}
constructed. */
for (i = 0; i <= CODING_CATEGORY_LAST; i++)
- coding_category_by_priority[category_to_priority[i]] = i;
+ fcd->coding_category_by_priority[category_to_priority[i]] = i;
/* Phew! That was confusing. */
return Qnil;
Lisp_Object list = Qnil;
for (i = CODING_CATEGORY_LAST; i >= 0; i--)
- list = Fcons (coding_category_symbol[coding_category_by_priority[i]],
+ list = Fcons (coding_category_symbol[fcd->coding_category_by_priority[i]],
list);
return list;
}
int cat = decode_coding_category (coding_category);
coding_system = Fget_coding_system (coding_system);
- coding_category_system[cat] = coding_system;
+ fcd->coding_category_system[cat] = coding_system;
return Qnil;
}
(coding_category))
{
int cat = decode_coding_category (coding_category);
- Lisp_Object sys = coding_category_system[cat];
+ Lisp_Object sys = fcd->coding_category_system[cat];
if (!NILP (sys))
return XCODING_SYSTEM_NAME (sys);
the first one that is allowed. */
for (i = 0; i <= CODING_CATEGORY_LAST; i++)
{
- cat = coding_category_by_priority[i];
+ cat = fcd->coding_category_by_priority[i];
if ((mask & (1 << cat)) &&
- !NILP (coding_category_system[cat]))
+ !NILP (fcd->coding_category_system[cat]))
break;
}
if (cat >= 0)
- return coding_category_system[cat];
+ return fcd->coding_category_system[cat];
else
return Fget_coding_system (Qraw_text);
}
}
*np = 0;
coding_system
- = Ffind_coding_system (intern (coding_system_name));
+ = Ffind_coding_system (intern ((char *) coding_system_name));
break;
}
}
#endif
for (i = CODING_CATEGORY_LAST; i >= 0; i--)
{
- int sys = coding_category_by_priority[i];
+ int sys = fcd->coding_category_by_priority[i];
if (decst.mask & (1 << sys))
{
- Lisp_Object codesys = coding_category_system[sys];
+ Lisp_Object codesys = fcd->coding_category_system[sys];
if (!NILP (codesys))
codesys = subsidiary_coding_system (codesys, decst.eol_type);
val = Fcons (codesys, val);
static int decoding_flusher (Lstream *stream);
static int decoding_closer (Lstream *stream);
-static Lisp_Object decoding_marker (Lisp_Object stream,
- void (*markobj) (Lisp_Object));
+static Lisp_Object decoding_marker (Lisp_Object stream);
DEFINE_LSTREAM_IMPLEMENTATION ("decoding", lstream_decoding,
sizeof (struct decoding_stream));
static Lisp_Object
-decoding_marker (Lisp_Object stream, void (*markobj) (Lisp_Object))
+decoding_marker (Lisp_Object stream)
{
Lstream *str = DECODING_STREAM_DATA (XLSTREAM (stream))->other_end;
Lisp_Object str_obj;
and automatically marked. */
XSETLSTREAM (str_obj, str);
- markobj (str_obj);
+ mark_object (str_obj);
if (str->imp->marker)
- return (str->imp->marker) (str_obj, markobj);
+ return (str->imp->marker) (str_obj);
else
return Qnil;
}
static int encoding_flusher (Lstream *stream);
static int encoding_closer (Lstream *stream);
-static Lisp_Object encoding_marker (Lisp_Object stream,
- void (*markobj) (Lisp_Object));
+static Lisp_Object encoding_marker (Lisp_Object stream);
DEFINE_LSTREAM_IMPLEMENTATION ("encoding", lstream_encoding,
sizeof (struct encoding_stream));
static Lisp_Object
-encoding_marker (Lisp_Object stream, void (*markobj) (Lisp_Object))
+encoding_marker (Lisp_Object stream)
{
Lstream *str = ENCODING_STREAM_DATA (XLSTREAM (stream))->other_end;
Lisp_Object str_obj;
and automatically marked. */
XSETLSTREAM (str_obj, str);
- markobj (str_obj);
+ mark_object (str_obj);
if (str->imp->marker)
- return (str->imp->marker) (str_obj, markobj);
+ return (str->imp->marker) (str_obj);
else
return Qnil;
}
/* */
/************************************************************************/
-Lisp_Object ucs_to_mule_table[65536];
-Lisp_Object mule_to_ucs_table;
DEFUN ("set-ucs-char", Fset_ucs_char, 2, 2, 0, /*
Map UCS-4 code CODE to Mule character CHARACTER.
CHECK_INT (code);
c = XINT (code);
- if (c < sizeof (ucs_to_mule_table))
+ if (c < sizeof (fcd->ucs_to_mule_table))
{
- ucs_to_mule_table[c] = character;
+ fcd->ucs_to_mule_table[c] = character;
return Qt;
}
else
static Lisp_Object
ucs_to_char (unsigned long code)
{
- if (code < sizeof (ucs_to_mule_table))
+ if (code < sizeof (fcd->ucs_to_mule_table))
{
- return ucs_to_mule_table[code];
+ return fcd->ucs_to_mule_table[code];
}
else if ((0xe00000 <= code) && (code <= 0xe00000 + 94 * 94 * 14))
{
void
syms_of_file_coding (void)
{
- defsymbol (&Qbuffer_file_coding_system, "buffer-file-coding-system");
deferror (&Qcoding_system_error, "coding-system-error",
"Coding-system error", Qio_error);
DEFSUBR (Fset_char_ucs);
DEFSUBR (Fchar_ucs);
#endif /* MULE */
- defsymbol (&Qcoding_system_p, "coding-system-p");
+ defsymbol (&Qcoding_systemp, "coding-system-p");
defsymbol (&Qno_conversion, "no-conversion");
defsymbol (&Qraw_text, "raw-text");
#ifdef MULE
{
int i;
+ fcd = xnew (struct file_coding_dump);
+ dumpstruct (&fcd, &fcd_description);
+
/* Initialize to something reasonable ... */
for (i = 0; i <= CODING_CATEGORY_LAST; i++)
{
- coding_category_system[i] = Qnil;
- coding_category_by_priority[i] = i;
+ fcd->coding_category_system[i] = Qnil;
+ fcd->coding_category_by_priority[i] = i;
}
Fprovide (intern ("file-coding"));
make_lisp_hash_table (50, HASH_TABLE_NON_WEAK, HASH_TABLE_EQ);
the_codesys_prop_dynarr = Dynarr_new (codesys_prop);
+ dumpstruct (&the_codesys_prop_dynarr, &codesys_prop_dynarr_description);
#define DEFINE_CODESYS_PROP(Prop_Type, Sym) do \
{ \
Fdefine_coding_system_alias (Qno_conversion, Qraw_text);
/* Need this for bootstrapping */
- coding_category_system[CODING_CATEGORY_NO_CONVERSION] =
+ fcd->coding_category_system[CODING_CATEGORY_NO_CONVERSION] =
Fget_coding_system (Qraw_text);
#ifdef MULE
unsigned int i;
for (i = 0; i < 65536; i++)
- ucs_to_mule_table[i] = Qnil;
+ fcd->ucs_to_mule_table[i] = Qnil;
}
staticpro (&mule_to_ucs_table);
mule_to_ucs_table = Fmake_char_table(Qgeneric);
#define XCODING_SYSTEM(x) XRECORD (x, coding_system, struct Lisp_Coding_System)
#define XSETCODING_SYSTEM(x, p) XSETRECORD (x, p, coding_system)
#define CODING_SYSTEMP(x) RECORDP (x, coding_system)
-#define GC_CODING_SYSTEMP(x) GC_RECORDP (x, coding_system)
#define CHECK_CODING_SYSTEM(x) CHECK_RECORD (x, coding_system)
#define CONCHECK_CODING_SYSTEM(x) CONCHECK_RECORD (x, coding_system)
EXFUN (Fsubsidiary_coding_system, 2);
extern Lisp_Object Qucs4, Qutf8;
-extern Lisp_Object Qbig5, Qbuffer_file_coding_system, Qccl, Qcharset_g0;
+extern Lisp_Object Qbig5, Qccl, Qcharset_g0;
extern Lisp_Object Qcharset_g1, Qcharset_g2, Qcharset_g3, Qcoding_system_error;
-extern Lisp_Object Qcoding_system_p, Qcr, Qcrlf, Qctext, Qdecode, Qencode;
+extern Lisp_Object Qcoding_systemp, Qcr, Qcrlf, Qctext, Qdecode, Qencode;
extern Lisp_Object Qeol_cr, Qeol_crlf, Qeol_lf, Qeol_type, Qescape_quoted;
extern Lisp_Object Qforce_g0_on_output, Qforce_g1_on_output;
extern Lisp_Object Qforce_g2_on_output, Qforce_g3_on_output;
/* Need to lower-case the drive letter, or else expanded
filenames will sometimes compare inequal, because
`expand-file-name' doesn't always down-case the drive letter. */
-#define DRIVE_LETTER(x) (tolower (x))
+#define DRIVE_LETTER(x) tolower (x)
#endif /* WINDOWSNT */
int lisp_to_time (Lisp_Object, time_t *);
int disable_auto_save_when_buffer_shrinks;
-Lisp_Object Qfile_name_handler_alist;
-
Lisp_Object Vdirectory_sep_char;
/* These variables describe handlers that have "already" had a chance
{
char resolved_path[MAXPATHLEN];
- char path[MAXPATHLEN];
- char *p = path;
- int elen = XSTRING_LENGTH (expanded_name);
+ Extbyte *path;
+ Extbyte *p;
+ Extcount elen = XSTRING_LENGTH (expanded_name);
- if (elen >= countof (path))
+ GET_STRING_FILENAME_DATA_ALLOCA (expanded_name,path,elen);
+ p = path;
+ if (elen > MAXPATHLEN)
goto toolong;
-
- memcpy (path, XSTRING_DATA (expanded_name), elen + 1);
- /* memset (resolved_path, 0, sizeof (resolved_path)); */
-
+
/* Try doing it all at once. */
- /* !!#### Does realpath() Mule-encapsulate? */
- if (!xrealpath (path, resolved_path))
+ /* !! Does realpath() Mule-encapsulate?
+ Answer: Nope! So we do it above */
+ if (!xrealpath ((char *) path, resolved_path))
{
/* Didn't resolve it -- have to do it one component at a time. */
/* "realpath" is a typically useless, stupid un*x piece of crap.
partial result returned. What a piece of junk. */
for (;;)
{
- p = (char *) memchr (p + 1, '/', elen - (p + 1 - path));
+ p = (Extbyte *) memchr (p + 1, '/', elen - (p + 1 - path));
if (p)
*p = 0;
/* memset (resolved_path, 0, sizeof (resolved_path)); */
- if (xrealpath (path, resolved_path))
+ if (xrealpath ((char *) path, resolved_path))
{
if (p)
*p = '/';
Fcopy_file (filename, newname,
/* We have already prompted if it was an integer,
so don't have copy-file prompt again. */
- ((NILP (ok_if_already_exists)) ? Qnil : Qt),
+ (NILP (ok_if_already_exists) ? Qnil : Qt),
Qt);
Fdelete_file (filename);
}
run_hook (Qauto_save_hook);
- if (GC_STRINGP (Vauto_save_list_file_name))
+ if (STRINGP (Vauto_save_list_file_name))
listfile = condition_case_1 (Qt,
auto_save_expand_name,
Vauto_save_list_file_name,
for (do_handled_files = 0; do_handled_files < 2; do_handled_files++)
{
for (tail = Vbuffer_alist;
- GC_CONSP (tail);
+ CONSP (tail);
tail = XCDR (tail))
{
buf = XCDR (XCAR (tail));
b = XBUFFER (buf);
- if (!GC_NILP (current_only)
+ if (!NILP (current_only)
&& b != current_buffer)
continue;
/* Check for auto save enabled
and file changed since last auto save
and file changed since last real save. */
- if (GC_STRINGP (b->auto_save_file_name)
+ if (STRINGP (b->auto_save_file_name)
&& BUF_SAVE_MODIFF (b) < BUF_MODIFF (b)
&& b->auto_save_modified < BUF_MODIFF (b)
/* -1 means we've turned off autosaving for a while--see below. */
continue;
}
set_buffer_internal (b);
- if (!auto_saved && GC_NILP (no_message))
+ if (!auto_saved && NILP (no_message))
{
static CONST unsigned char *msg
= (CONST unsigned char *) "Auto-saving...";
/* Open the auto-save list file, if necessary.
We only do this now so that the file only exists
if we actually auto-saved any files. */
- if (!auto_saved && GC_STRINGP (listfile) && listdesc < 0)
+ if (!auto_saved && STRINGP (listfile) && listdesc < 0)
{
listdesc = open ((char *) XSTRING_DATA (listfile),
O_WRONLY | O_TRUNC | O_CREAT | OPEN_BINARY,
one because nothing needed to be auto-saved. Do this afterwards
rather than before in case we get a crash attempting to autosave
(in that case we'd still want the old one around). */
- if (listdesc < 0 && !auto_saved && GC_STRINGP (listfile))
+ if (listdesc < 0 && !auto_saved && STRINGP (listfile))
unlink ((char *) XSTRING_DATA (listfile));
/* Show "...done" only if the echo area would otherwise be empty. */
defsymbol (&Qset_visited_file_modtime, "set-visited-file-modtime");
defsymbol (&Qcar_less_than_car, "car-less-than-car"); /* Vomitous! */
- defsymbol (&Qfile_name_handler_alist, "file-name-handler-alist");
defsymbol (&Qauto_save_hook, "auto-save-hook");
defsymbol (&Qauto_save_error, "auto-save-error");
defsymbol (&Qauto_saving, "auto-saving");
char *lock_info_str;
if (STRINGP (Fuser_login_name (Qnil)))
- user_name = (char *)XSTRING_DATA((Fuser_login_name (Qnil)));
+ user_name = (char *) XSTRING_DATA (Fuser_login_name (Qnil));
else
user_name = "";
if (STRINGP (Fsystem_name ()))
- host_name = (char *)XSTRING_DATA((Fsystem_name ()));
+ host_name = (char *) XSTRING_DATA (Fsystem_name ());
else
host_name = "";
lock_info_str = (char *)alloca (strlen (user_name) + strlen (host_name)
#define arith_error(op,arg) \
- Fsignal (Qarith_error, list2 (build_string ((op)), (arg)))
+ Fsignal (Qarith_error, list2 (build_string (op), arg))
#define range_error(op,arg) \
- Fsignal (Qrange_error, list2 (build_string ((op)), (arg)))
+ Fsignal (Qrange_error, list2 (build_string (op), arg))
#define range_error2(op,a1,a2) \
- Fsignal (Qrange_error, list3 (build_string ((op)), (a1), (a2)))
+ Fsignal (Qrange_error, list3 (build_string (op), a1, a2))
#define domain_error(op,arg) \
- Fsignal (Qdomain_error, list2 (build_string ((op)), (arg)))
+ Fsignal (Qdomain_error, list2 (build_string (op), arg))
#define domain_error2(op,a1,a2) \
- Fsignal (Qdomain_error, list3 (build_string ((op)), (a1), (a2)))
+ Fsignal (Qdomain_error, list3 (build_string (op), a1, a2))
/* Convert float to Lisp Integer if it fits, else signal a range
\f
static Lisp_Object
-mark_float (Lisp_Object obj, void (*markobj) (Lisp_Object))
+mark_float (Lisp_Object obj)
{
return Qnil;
}
static int internal_old_equal (Lisp_Object, Lisp_Object, int);
static Lisp_Object
-mark_bit_vector (Lisp_Object obj, void (*markobj) (Lisp_Object))
+mark_bit_vector (Lisp_Object obj)
{
return Qnil;
}
static void
print_bit_vector (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
{
- int i;
+ size_t i;
struct Lisp_Bit_Vector *v = XBIT_VECTOR (obj);
- int len = bit_vector_length (v);
- int last = len;
+ size_t len = bit_vector_length (v);
+ size_t last = len;
if (INTP (Vprint_length))
last = min (len, XINT (Vprint_length));
sizeof (long)));
}
+static const struct lrecord_description bit_vector_description[] = {
+ { XD_LISP_OBJECT, offsetof(Lisp_Bit_Vector, next), 1 },
+ { XD_END }
+};
+
+
DEFINE_BASIC_LRECORD_IMPLEMENTATION ("bit-vector", bit_vector,
mark_bit_vector, print_bit_vector, 0,
- bit_vector_equal, bit_vector_hash, 0,
+ bit_vector_equal, bit_vector_hash,
+ bit_vector_description,
struct Lisp_Bit_Vector);
\f
DEFUN ("identity", Fidentity, 1, 1, 0, /*
return make_int (XSTRING_CHAR_LENGTH (sequence));
else if (CONSP (sequence))
{
- int len;
+ size_t len;
GET_EXTERNAL_LIST_LENGTH (sequence, len);
return make_int (len);
}
(list))
{
Lisp_Object hare, tortoise;
- int len;
+ size_t len;
for (hare = tortoise = list, len = 0;
CONSP (hare) && (! EQ (hare, tortoise) || len == 0);
Lisp_Object list_copy = Fcons (XCAR (list), XCDR (list));
Lisp_Object last = list_copy;
Lisp_Object hare, tortoise;
- int len;
+ size_t len;
for (tortoise = hare = XCDR (list), len = 1;
CONSP (hare);
*/
(seq, from, to))
{
- int len, f, t;
+ EMACS_INT len, f, t;
if (STRINGP (seq))
return Fsubstring (seq, from, to);
if (VECTORP (seq))
{
Lisp_Object result = make_vector (t - f, Qnil);
- int i;
+ EMACS_INT i;
Lisp_Object *in_elts = XVECTOR_DATA (seq);
Lisp_Object *out_elts = XVECTOR_DATA (result);
if (LISTP (seq))
{
Lisp_Object result = Qnil;
- int i;
+ EMACS_INT i;
seq = Fnthcdr (make_int (f), seq);
/* bit vector */
{
Lisp_Object result = make_bit_vector (t - f, Qzero);
- int i;
+ EMACS_INT i;
for (i = f; i < t; i++)
set_bit_vector_bit (XBIT_VECTOR (result), i - f,
*/
(n, list))
{
- REGISTER int i;
+ REGISTER size_t i;
REGISTER Lisp_Object tail = list;
CHECK_NATNUM (n);
for (i = XINT (n); i; i--)
#ifdef LOSING_BYTECODE
else if (COMPILED_FUNCTIONP (sequence))
{
- int idx = XINT (n);
+ EMACS_INT idx = XINT (n);
if (idx < 0)
{
lose:
*/
(list, n))
{
- int int_n, count;
+ EMACS_INT int_n, count;
Lisp_Object retval, tortoise, hare;
CHECK_LIST (list);
*/
(list, n))
{
- int int_n;
+ EMACS_INT int_n;
CHECK_LIST (list);
return value;
}
-void
-pure_put (Lisp_Object sym, Lisp_Object prop, Lisp_Object val)
-{
- Fput (sym, prop, Fpurecopy (val));
-}
-
DEFUN ("remprop", Fremprop, 2, 2, 0, /*
Remove from OBJECT's property list the property PROPNAME and its
value. OBJECT can be a symbol, face, extent, or string. Returns
return result;
}
-DEFUN ("mapc", Fmapc, 2, 2, 0, /*
+DEFUN ("mapc-internal", Fmapc_internal, 2, 2, 0, /*
Apply FUNCTION to each element of SEQUENCE.
SEQUENCE may be a list, a vector, a bit vector, or a string.
This function is like `mapcar' but does not accumulate the results,
which is more efficient if you do not use the results.
+
+The difference between this and `mapc' is that `mapc' supports all
+the spiffy Common Lisp arguments. You should normally use `mapc'.
*/
(fn, seq))
{
DEFSUBR (Fnconc);
DEFSUBR (Fmapcar);
DEFSUBR (Fmapvector);
- DEFSUBR (Fmapc);
+ DEFSUBR (Fmapc_internal);
DEFSUBR (Fmapconcat);
DEFSUBR (Fload_average);
DEFSUBR (Ffeaturep);
}
void
-vars_of_font_lock (void)
+reinit_vars_of_font_lock (void)
{
xzero (context_cache);
xzero (bol_context_cache);
}
+
+void
+vars_of_font_lock (void)
+{
+ reinit_vars_of_font_lock ();
+}
}
static void
-mswindows_mark_frame (struct frame *f, void (*markobj) (Lisp_Object))
+mswindows_mark_frame (struct frame *f)
{
- markobj (FRAME_MSWINDOWS_MENU_HASH_TABLE (f));
+ mark_object (FRAME_MSWINDOWS_MENU_HASH_TABLE (f));
#ifdef HAVE_TOOLBARS
- markobj (FRAME_MSWINDOWS_TOOLBAR_HASH_TABLE (f));
+ mark_object (FRAME_MSWINDOWS_TOOLBAR_HASH_TABLE (f));
#endif
- markobj (FRAME_MSWINDOWS_WIDGET_HASH_TABLE (f));
+ mark_object (FRAME_MSWINDOWS_WIDGET_HASH_TABLE (f));
}
static void
}
void
-vars_of_frame_mswindows (void)
+reinit_vars_of_frame_mswindows (void)
{
/* Needn't staticpro -- see comment above. */
Vmswindows_frame_being_created = Qnil;
+}
+
+void
+vars_of_frame_mswindows (void)
+{
+ reinit_vars_of_frame_mswindows ();
DEFVAR_LISP ("mswindows-use-system-frame-size-defaults", &Vmswindows_use_system_frame_size_defaults /*
Controls whether to use system or XEmacs defaults for frame size.
struct frame *
x_any_window_to_frame (struct device *d, Window wdesc)
{
- Lisp_Object tail, frame;
- struct frame *f;
-
+ Widget w;
assert (DEVICE_X_P (d));
+ w = XtWindowToWidget (DEVICE_X_DISPLAY (d), wdesc);
+
+ if (!w)
+ return 0;
+
+ /* We used to map over all frames here and then map over all widgets
+ belonging to that frame. However it turns out that this was very fragile
+ as it requires our display stuctures to be in sync _and_ that the
+ loop is told about every new widget somebody adds. Therefore we
+ now let Xt find it for us (which does a bottom-up search which
+ could even be faster) */
+ return x_any_widget_or_parent_to_frame (d, w);
+}
+
+static struct frame *
+x_find_frame_for_window (struct device *d, Window wdesc)
+{
+ Lisp_Object tail, frame;
+ struct frame *f;
/* This function was previously written to accept only a window argument
(and to loop over all devices looking for a matching window), but
that is incorrect because window ID's are not unique across displays. */
for (tail = DEVICE_FRAME_LIST (d); CONSP (tail); tail = XCDR (tail))
{
- int i;
-
frame = XCAR (tail);
f = XFRAME (frame);
/* This frame matches if the window is any of its widgets. */
would incorrectly get sucked away by Emacs if this function matched
on psheet widgets. */
- for (i = 0; i < FRAME_X_NUM_TOP_WIDGETS (f); i++)
- {
- Widget wid = FRAME_X_TOP_WIDGETS (f)[i];
- if (wid && XtIsManaged (wid) && wdesc == XtWindow (wid))
- return f;
- }
-
-#ifdef HAVE_SCROLLBARS
- /* Match if the window is one of this frame's scrollbars. */
- if (x_window_is_scrollbar (f, wdesc))
- return f;
-#endif
+ /* Note: that this called only from
+ x_any_widget_or_parent_to_frame it is unnecessary to iterate
+ over the top level widgets. */
+
+ /* Note: we use to special case scrollbars but this turns out to be a bad idea
+ because
+ 1. We sometimes get events for _unmapped_ scrollbars and our
+ callers don't want us to fail.
+ 2. Starting with the 21.2 widget stuff there are now loads of
+ widgets to check and it is easy to forget adding them in a loop here.
+ See x_any_window_to_frame
+ 3. We pick up all widgets now anyway. */
}
return 0;
{
while (widget)
{
- struct frame *f = x_any_window_to_frame (d, XtWindow (widget));
+ struct frame *f = x_find_frame_for_window (d, XtWindow (widget));
if (f)
return f;
widget = XtParent (widget);
init_x_prop_symbols (void)
{
#define def(sym, rsrc) \
- pure_put (sym, Qx_resource_name, build_string (rsrc))
+ Fput (sym, Qx_resource_name, build_string (rsrc))
#define defi(sym,rsrc) \
- def (sym, rsrc); pure_put (sym, Qintegerp, Qt)
+ def (sym, rsrc); Fput (sym, Qintegerp, Qt)
#if 0 /* this interferes with things. #### fix this right */
def (Qminibuffer, XtNminibuffer);
char *string;
CHECK_STRING (lisp_window_id);
- string = (char *) (XSTRING_DATA (lisp_window_id));
+ string = (char *) XSTRING_DATA (lisp_window_id);
if (string[0] == '0' && (string[1] == 'x' || string[1] == 'X'))
sscanf (string+2, "%lxu", &window_id);
#if 0
}
static void
-x_mark_frame (struct frame *f, void (*markobj) (Lisp_Object))
+x_mark_frame (struct frame *f)
{
- markobj (FRAME_X_ICON_PIXMAP (f));
- markobj (FRAME_X_ICON_PIXMAP_MASK (f));
+ mark_object (FRAME_X_ICON_PIXMAP (f));
+ mark_object (FRAME_X_ICON_PIXMAP_MASK (f));
}
static void
Lisp_Object Qborder_width;
Lisp_Object Qframep, Qframe_live_p;
-Lisp_Object Qframe_x_p, Qframe_tty_p;
Lisp_Object Qdelete_frame;
Lisp_Object Qframe_title_format, Vframe_title_format;
\f
static Lisp_Object
-mark_frame (Lisp_Object obj, void (*markobj) (Lisp_Object))
+mark_frame (Lisp_Object obj)
{
struct frame *f = XFRAME (obj);
-#define MARKED_SLOT(x) ((void) (markobj (f->x)));
+#define MARKED_SLOT(x) mark_object (f->x)
#include "frameslots.h"
- mark_subwindow_cachels (f->subwindow_cachels, markobj);
+ mark_subwindow_cachels (f->subwindow_cachels);
if (FRAME_LIVE_P (f)) /* device is nil for a dead frame */
- MAYBE_FRAMEMETH (f, mark_frame, (f, markobj));
+ MAYBE_FRAMEMETH (f, mark_frame, (f));
return Qnil;
}
static void
nuke_all_frame_slots (struct frame *f)
{
-#define MARKED_SLOT(x) f->x = Qnil;
+#define MARKED_SLOT(x) f->x = Qnil
#include "frameslots.h"
}
/* cache of subwindows visible on frame */
f->subwindow_cachels = Dynarr_new (subwindow_cachel);
+ /* associated exposure ignore list */
+ f->subwindow_exposures = 0;
+ f->subwindow_exposures_tail = 0;
+
/* Choose a buffer for the frame's root window. */
XWINDOW (root_window)->buffer = Qt;
{
update_frame_window_mirror (f);
- if (initialized)
+ if (initialized && !DEVICE_STREAM_P (d))
{
if (!NILP (f->minibuffer_window))
reset_face_cachels (XWINDOW (f->minibuffer_window));
defsymbol (&Qframep, "framep");
defsymbol (&Qframe_live_p, "frame-live-p");
- defsymbol (&Qframe_x_p, "frame-x-p");
- defsymbol (&Qframe_tty_p, "frame-tty-p");
defsymbol (&Qdelete_frame, "delete-frame");
defsymbol (&Qsynchronize_minibuffers, "synchronize-minibuffers");
defsymbol (&Qbuffer_predicate, "buffer-predicate");
This is the same format as `modeline-format' with the exception that
%- is ignored.
*/ );
- Vframe_title_format = Fpurecopy (build_string ("%S: %b"));
+ Vframe_title_format = build_string ("%S: %b");
DEFVAR_LISP ("frame-icon-title-format", &Vframe_icon_title_format /*
Controls the title of the icon corresponding to the selected frame.
See also the variable `frame-title-format'.
*/ );
- Vframe_icon_title_format = Fpurecopy (build_string ("%b"));
+ Vframe_icon_title_format = build_string ("%b");
DEFVAR_LISP ("default-frame-name", &Vdefault_frame_name /*
The default name to assign to newly-created frames.
This must be a string.
*/ );
#ifndef INFODOCK
- Vdefault_frame_name = Fpurecopy (build_string ("emacs"));
+ Vdefault_frame_name = build_string ("emacs");
#else
- Vdefault_frame_name = Fpurecopy (build_string ("InfoDock"));
+ Vdefault_frame_name = build_string ("InfoDock");
#endif
DEFVAR_LISP ("default-frame-plist", &Vdefault_frame_plist /*
/* subwindow cache elements for this frame */
subwindow_cachel_dynarr *subwindow_cachels;
+ struct expose_ignore* subwindow_exposures;
+ struct expose_ignore* subwindow_exposures_tail;
+
#ifdef HAVE_SCROLLBARS
/* frame-local scrollbar information. See scrollbar.c. */
int scrollbar_y_offset;
unsigned int faces_changed :1;
unsigned int frame_changed :1;
unsigned int subwindows_changed :1;
+ unsigned int subwindows_state_changed :1;
unsigned int glyphs_changed :1;
unsigned int icon_changed :1;
unsigned int menubar_changed :1;
#define XFRAME(x) XRECORD (x, frame, struct frame)
#define XSETFRAME(x, p) XSETRECORD (x, p, frame)
#define FRAMEP(x) RECORDP (x, frame)
-#define GC_FRAMEP(x) GC_RECORDP (x, frame)
#define CHECK_FRAME(x) CHECK_RECORD (x, frame)
#define CONCHECK_FRAME(x) CONCHECK_RECORD (x, frame)
return f;
}
# define FRAME_TYPE_DATA(f, type) \
- ((struct type##_frame *) (error_check_frame_type (f, Q##type))->frame_data)
+ ((struct type##_frame *) error_check_frame_type (f, Q##type)->frame_data)
#else
# define FRAME_TYPE_DATA(f, type) \
((struct type##_frame *) (f)->frame_data)
subwindows_changed = 1; \
} while (0)
+#define MARK_FRAME_SUBWINDOWS_STATE_CHANGED(f) do { \
+ struct frame *mfgc_f = (f); \
+ mfgc_f->subwindows_state_changed = 1; \
+ mfgc_f->modiff++; \
+ if (!NILP (mfgc_f->device)) \
+ { \
+ struct device *mfgc_d = XDEVICE (mfgc_f->device); \
+ MARK_DEVICE_SUBWINDOWS_STATE_CHANGED (mfgc_d); \
+ } \
+ else \
+ subwindows_state_changed = 1; \
+} while (0)
+
#define MARK_FRAME_TOOLBARS_CHANGED(f) do { \
struct frame *mftc_f = (f); \
mftc_f->toolbar_changed = 1; \
/* System function prototypes don't belong in C source files */
/* extern void free (void *); */
-struct hash_table *pointer_table;
+static struct hash_table *pointer_table;
extern void (*__free_hook) (void *);
extern void *(*__malloc_hook) (size_t);
static void *check_malloc (size_t);
-typedef void (*fun_ptr) ();
+typedef void (*fun_ptr) (void);
/* free_queue is not too useful without backtrace logging */
#define FREE_QUEUE_LIMIT 1
unsigned long length;
} free_queue_entry;
-free_queue_entry free_queue[FREE_QUEUE_LIMIT];
+static free_queue_entry free_queue[FREE_QUEUE_LIMIT];
-int current_free;
+static int current_free;
-int strict_free_check;
+static int strict_free_check;
static void
check_free (void *ptr)
if $imp == &lrecord_opaque
pstruct Lisp_Opaque
else
- if $imp == &lrecord_opaque_list
- pstruct Lisp_Opaque_List
+ if $imp == &lrecord_opaque_ptr
+ pstruct Lisp_Opaque_Ptr
else
if $imp == &lrecord_popup_data
pstruct popup_data
Lisp_Object Qactually_requested;
Lisp_Object Qafter;
Lisp_Object Qall;
-Lisp_Object Qalways;
Lisp_Object Qand;
Lisp_Object Qassoc;
Lisp_Object Qat;
-Lisp_Object Qauth;
Lisp_Object Qautodetect;
Lisp_Object Qbad_variable;
-Lisp_Object Qbase;
Lisp_Object Qbefore;
Lisp_Object Qbinary;
-Lisp_Object Qbinddn;
Lisp_Object Qbitmap;
-Lisp_Object Qblack;
Lisp_Object Qboolean;
Lisp_Object Qbottom;
Lisp_Object Qbuffer;
Lisp_Object Qbutton;
-Lisp_Object Qcase;
+Lisp_Object Qcenter;
Lisp_Object Qcategory;
Lisp_Object Qchannel;
Lisp_Object Qchar;
Lisp_Object Qdefault;
Lisp_Object Qdelete;
Lisp_Object Qdelq;
-Lisp_Object Qderef;
Lisp_Object Qdevice;
Lisp_Object Qdimension;
Lisp_Object Qdisplay;
Lisp_Object Qeval;
Lisp_Object Qextents;
Lisp_Object Qface;
-Lisp_Object Qfind;
Lisp_Object Qfont;
Lisp_Object Qframe;
Lisp_Object Qfunction;
Lisp_Object Qgutter;
Lisp_Object Qheight;
Lisp_Object Qhighlight;
+Lisp_Object Qhorizontal;
Lisp_Object Qicon;
Lisp_Object Qid;
Lisp_Object Qimage;
Lisp_Object Qinternal;
Lisp_Object Qkey;
Lisp_Object Qkey_assoc;
-Lisp_Object Qkeyboard;
Lisp_Object Qkeymap;
-Lisp_Object Qkrbv41;
-Lisp_Object Qkrbv42;
Lisp_Object Qleft;
Lisp_Object Qlist;
Lisp_Object Qmagic;
Lisp_Object Qmarkers;
Lisp_Object Qmax;
Lisp_Object Qmemory;
-Lisp_Object Qmenubar;
Lisp_Object Qmessage;
Lisp_Object Qminus;
Lisp_Object Qmodifiers;
Lisp_Object Qmotion;
Lisp_Object Qmswindows;
Lisp_Object Qname;
-Lisp_Object Qnever;
Lisp_Object Qnone;
Lisp_Object Qnot;
Lisp_Object Qnothing;
Lisp_Object Qold_delq;
Lisp_Object Qold_rassoc;
Lisp_Object Qold_rassq;
-Lisp_Object Qonelevel;
Lisp_Object Qonly;
Lisp_Object Qor;
Lisp_Object Qother;
-Lisp_Object Qpasswd;
-Lisp_Object Qpath;
Lisp_Object Qpointer;
Lisp_Object Qpopup;
-Lisp_Object Qport;
Lisp_Object Qprint;
Lisp_Object Qprocess;
Lisp_Object Qprovide;
Lisp_Object Qsignal;
Lisp_Object Qsimple;
Lisp_Object Qsize;
-Lisp_Object Qsizelimit;
Lisp_Object Qspace;
Lisp_Object Qspecifier;
Lisp_Object Qstream;
Lisp_Object Qstring;
-Lisp_Object Qsubtree;
Lisp_Object Qsymbol;
Lisp_Object Qsyntax;
Lisp_Object Qtest;
Lisp_Object Qtext;
-Lisp_Object Qtimelimit;
Lisp_Object Qtimeout;
Lisp_Object Qtimestamp;
Lisp_Object Qtoolbar;
Lisp_Object Qundefined;
Lisp_Object Qunimplemented;
Lisp_Object Qvalue_assoc;
-Lisp_Object Qvector;
+Lisp_Object Qvertical;
Lisp_Object Qwarning;
-Lisp_Object Qwhite;
Lisp_Object Qwidth;
Lisp_Object Qwidget;
Lisp_Object Qwindow;
defsymbol (&Qactually_requested, "actually-requested");
defsymbol (&Qafter, "after");
defsymbol (&Qall, "all");
- defsymbol (&Qalways, "always");
defsymbol (&Qand, "and");
defsymbol (&Qassoc, "assoc");
defsymbol (&Qat, "at");
- defsymbol (&Qauth, "auth");
defsymbol (&Qautodetect, "autodetect");
defsymbol (&Qbad_variable, "bad-variable");
- defsymbol (&Qbase, "base");
defsymbol (&Qbefore, "before");
defsymbol (&Qbinary, "binary");
- defsymbol (&Qbinddn, "binddn");
defsymbol (&Qbitmap, "bitmap");
- defsymbol (&Qblack, "black");
defsymbol (&Qboolean, "boolean");
defsymbol (&Qbottom, "bottom");
defsymbol (&Qbuffer, "buffer");
defsymbol (&Qbutton, "button");
- defsymbol (&Qcase, "case");
defsymbol (&Qcategory, "category");
+ defsymbol (&Qcenter, "center");
defsymbol (&Qchannel, "channel");
defsymbol (&Qchar, "char");
defsymbol (&Qcharacter, "character");
defsymbol (&Qdefault, "default");
defsymbol (&Qdelete, "delete");
defsymbol (&Qdelq, "delq");
- defsymbol (&Qderef, "deref");
defsymbol (&Qdevice, "device");
defsymbol (&Qdimension, "dimension");
defsymbol (&Qdisplay, "display");
defsymbol (&Qeval, "eval");
defsymbol (&Qextents, "extents");
defsymbol (&Qface, "face");
- defsymbol (&Qfind, "find");
defsymbol (&Qfont, "font");
defsymbol (&Qframe, "frame");
defsymbol (&Qfunction, "function");
defsymbol (&Qgutter, "gutter");
defsymbol (&Qheight, "height");
defsymbol (&Qhighlight, "highlight");
+ defsymbol (&Qhorizontal, "horizontal");
defsymbol (&Qicon, "icon");
defsymbol (&Qid, "id");
defsymbol (&Qimage, "image");
defsymbol (&Qinternal, "internal");
defsymbol (&Qkey, "key");
defsymbol (&Qkey_assoc, "key-assoc");
- defsymbol (&Qkeyboard, "keyboard");
defsymbol (&Qkeymap, "keymap");
- defsymbol (&Qkrbv41, "krbv41");
- defsymbol (&Qkrbv42, "krbv42");
defsymbol (&Qleft, "left");
defsymbol (&Qlist, "list");
defsymbol (&Qmagic, "magic");
defsymbol (&Qmarkers, "markers");
defsymbol (&Qmax, "max");
defsymbol (&Qmemory, "memory");
- defsymbol (&Qmenubar, "menubar");
defsymbol (&Qmessage, "message");
defsymbol (&Qminus, "-");
defsymbol (&Qmodifiers, "modifiers");
defsymbol (&Qmotion, "motion");
defsymbol (&Qmswindows, "mswindows");
defsymbol (&Qname, "name");
- defsymbol (&Qnever, "never");
defsymbol (&Qnone, "none");
defsymbol (&Qnot, "not");
defsymbol (&Qnothing, "nothing");
defsymbol (&Qold_delq, "old-delq");
defsymbol (&Qold_rassoc, "old-rassoc");
defsymbol (&Qold_rassq, "old-rassq");
- defsymbol (&Qonelevel, "onelevel");
defsymbol (&Qonly, "only");
defsymbol (&Qor, "or");
defsymbol (&Qother, "other");
- defsymbol (&Qpasswd, "passwd");
- defsymbol (&Qpath, "path");
defsymbol (&Qpointer, "pointer");
defsymbol (&Qpopup, "popup");
- defsymbol (&Qport, "port");
defsymbol (&Qprint, "print");
defsymbol (&Qprocess, "process");
defsymbol (&Qprovide, "provide");
defsymbol (&Qsignal, "signal");
defsymbol (&Qsimple, "simple");
defsymbol (&Qsize, "size");
- defsymbol (&Qsizelimit, "sizelimit");
defsymbol (&Qspace, "space");
defsymbol (&Qspecifier, "specifier");
defsymbol (&Qstream, "stream");
defsymbol (&Qstring, "string");
- defsymbol (&Qsubtree, "subtree");
defsymbol (&Qsymbol, "symbol");
defsymbol (&Qsyntax, "syntax");
defsymbol (&Qtest, "test");
defsymbol (&Qtext, "text");
- defsymbol (&Qtimelimit, "timelimit");
defsymbol (&Qtimeout, "timeout");
defsymbol (&Qtimestamp, "timestamp");
defsymbol (&Qtoolbar, "toolbar");
defsymbol (&Qundefined, "undefined");
defsymbol (&Qunimplemented, "unimplemented");
defsymbol (&Qvalue_assoc, "value-assoc");
- defsymbol (&Qvector, "vector");
+ defsymbol (&Qvertical, "vertical");
defsymbol (&Qwarning, "warning");
- defsymbol (&Qwhite, "white");
defsymbol (&Qwidth, "width");
defsymbol (&Qwidget, "widget");
defsymbol (&Qwindow, "window");
#include <errno.h>
-#ifndef errno
-extern int errno;
-#endif
-
#ifndef HAVE_GETLOADAVG
/* The existing Emacs configuration files define a macro called
#include <string.h>
#include <unistd.h>
#include "gifrlib.h"
+#include "sysfile.h"
/******************************************************************************
* Set up the GifFileType structure for use. This must be called first in any *
/* now instantiate */
MAYBE_DEVMETH (XDEVICE (ii->device),
init_image_instance_from_eimage,
- (ii, cinfo.output_width, cinfo.output_height,
+ (ii, cinfo.output_width, cinfo.output_height, 1,
unwind.eimage, dest_mask,
instantiator, domain));
DGifSlurp (unwind.giffile);
}
- /* 3. Now create the EImage */
+ /* 3. Now create the EImage(s) */
{
ColorMapObject *cmo = unwind.giffile->SColorMap;
- int i, j, row, pass, interlace;
+ int i, j, row, pass, interlace, slice;
unsigned char *eip;
/* interlaced gifs have rows in this order:
0, 8, 16, ..., 4, 12, 20, ..., 2, 6, 10, ..., 1, 3, 5, ... */
height = unwind.giffile->SHeight;
width = unwind.giffile->SWidth;
- unwind.eimage = (unsigned char*) xmalloc (width * height * 3);
+ unwind.eimage = (unsigned char*)
+ xmalloc (width * height * 3 * unwind.giffile->ImageCount);
if (!unwind.eimage)
signal_image_error("Unable to allocate enough memory for image", instantiator);
/* write the data in EImage format (8bit RGB triples) */
- /* Note: We just use the first image in the file and ignore the rest.
- We check here that that image covers the full "screen" size.
- I don't know whether that's always the case.
- -dkindred@cs.cmu.edu */
- if (unwind.giffile->SavedImages[0].ImageDesc.Height != height
- || unwind.giffile->SavedImages[0].ImageDesc.Width != width
- || unwind.giffile->SavedImages[0].ImageDesc.Left != 0
- || unwind.giffile->SavedImages[0].ImageDesc.Top != 0)
- signal_image_error ("First image in GIF file is not full size",
- instantiator);
-
- interlace = unwind.giffile->SavedImages[0].ImageDesc.Interlace;
- pass = 0;
- row = interlace ? InterlacedOffset[pass] : 0;
- eip = unwind.eimage;
- for (i = 0; i < height; i++)
+ for (slice = 0; slice < unwind.giffile->ImageCount; slice++)
{
- if (interlace)
- if (row >= height) {
- row = InterlacedOffset[++pass];
- while (row >= height)
- row = InterlacedOffset[++pass];
- }
- eip = unwind.eimage + (row * width * 3);
- for (j = 0; j < width; j++)
+ /* We check here that that the current image covers the full "screen" size. */
+ if (unwind.giffile->SavedImages[slice].ImageDesc.Height != height
+ || unwind.giffile->SavedImages[slice].ImageDesc.Width != width
+ || unwind.giffile->SavedImages[slice].ImageDesc.Left != 0
+ || unwind.giffile->SavedImages[slice].ImageDesc.Top != 0)
+ signal_image_error ("Image in GIF file is not full size",
+ instantiator);
+
+ interlace = unwind.giffile->SavedImages[slice].ImageDesc.Interlace;
+ pass = 0;
+ row = interlace ? InterlacedOffset[pass] : 0;
+ eip = unwind.eimage + (width * height * 3 * slice);
+ for (i = 0; i < height; i++)
{
- unsigned char pixel = unwind.giffile->SavedImages[0].RasterBits[(i * width) + j];
- *eip++ = cmo->Colors[pixel].Red;
- *eip++ = cmo->Colors[pixel].Green;
- *eip++ = cmo->Colors[pixel].Blue;
+ if (interlace)
+ if (row >= height) {
+ row = InterlacedOffset[++pass];
+ while (row >= height)
+ row = InterlacedOffset[++pass];
+ }
+ eip = unwind.eimage + (width * height * 3 * slice) + (row * width * 3);
+ for (j = 0; j < width; j++)
+ {
+ unsigned char pixel =
+ unwind.giffile->SavedImages[slice].RasterBits[(i * width) + j];
+ *eip++ = cmo->Colors[pixel].Red;
+ *eip++ = cmo->Colors[pixel].Green;
+ *eip++ = cmo->Colors[pixel].Blue;
+ }
+ row += interlace ? InterlacedJumps[pass] : 1;
}
- row += interlace ? InterlacedJumps[pass] : 1;
}
+
+ /* now instantiate */
+ MAYBE_DEVMETH (XDEVICE (ii->device),
+ init_image_instance_from_eimage,
+ (ii, width, height, unwind.giffile->ImageCount, unwind.eimage, dest_mask,
+ instantiator, domain));
}
- /* now instantiate */
- MAYBE_DEVMETH (XDEVICE (ii->device),
- init_image_instance_from_eimage,
- (ii, width, height, unwind.eimage, dest_mask,
- instantiator, domain));
+ /* We read the gif successfully. If we have more than one slice then
+ animate the gif. */
+ if (unwind.giffile->ImageCount > 1)
+ {
+ /* See if there is a timeout value. In theory there could be one
+ for every image - but that makes the implementation way to
+ complicated for now so we just take the first. */
+ unsigned short timeout = 0;
+ Lisp_Object tid;
+
+ if (unwind.giffile->SavedImages[0].Function == GRAPHICS_EXT_FUNC_CODE
+ &&
+ unwind.giffile->SavedImages[0].ExtensionBlockCount)
+ {
+ timeout = (unsigned short)
+ ((unwind.giffile->SavedImages[0].ExtensionBlocks[0].Bytes[2] << 8) +
+ unwind.giffile-> SavedImages[0].ExtensionBlocks[0].Bytes[1]) * 10;
+ }
+
+ /* Too short a timeout will crucify us performance-wise. */
+ tid = add_glyph_animated_timeout (timeout > 10 ? timeout : 10, image_instance);
+
+ if (!NILP (tid))
+ IMAGE_INSTANCE_PIXMAP_TIMEOUT (ii) = XINT (tid);
+ }
+
unbind_to (speccount, Qnil);
}
/* now instantiate */
MAYBE_DEVMETH (XDEVICE (ii->device),
init_image_instance_from_eimage,
- (ii, width, height, unwind.eimage, dest_mask,
+ (ii, width, height, 1, unwind.eimage, dest_mask,
instantiator, domain));
/* This will clean up everything else. */
/* now instantiate */
MAYBE_DEVMETH (XDEVICE (ii->device),
init_image_instance_from_eimage,
- (ii, width, height, unwind.eimage, dest_mask,
+ (ii, width, height, 1, unwind.eimage, dest_mask,
instantiator, domain));
unbind_to (speccount, Qnil);
/* mswindows-specific glyph objects.
- Copyright (C) 1998, 99 Andy Piper.
+ Copyright (C) 1998, 1999 Andy Piper.
This file is part of XEmacs.
DECLARE_IMAGE_INSTANTIATOR_FORMAT (string);
DECLARE_IMAGE_INSTANTIATOR_FORMAT (formatted_string);
DECLARE_IMAGE_INSTANTIATOR_FORMAT (inherit);
+DECLARE_IMAGE_INSTANTIATOR_FORMAT (layout);
#ifdef HAVE_JPEG
DECLARE_IMAGE_INSTANTIATOR_FORMAT (jpeg);
#endif
#endif
DEFINE_DEVICE_IIFORMAT (mswindows, button);
DEFINE_DEVICE_IIFORMAT (mswindows, edit_field);
-#if 0
-DEFINE_DEVICE_IIFORMAT (mswindows, group);
-#endif
DEFINE_DEVICE_IIFORMAT (mswindows, subwindow);
DEFINE_DEVICE_IIFORMAT (mswindows, widget);
DEFINE_DEVICE_IIFORMAT (mswindows, label);
static void
mswindows_initialize_dibitmap_image_instance (struct Lisp_Image_Instance *ii,
- enum image_instance_type type);
+ int slices,
+ enum image_instance_type type);
static void
mswindows_initialize_image_instance_mask (struct Lisp_Image_Instance* image,
struct frame* f);
COLORREF mswindows_string_to_color (CONST char *name);
-void check_valid_item_list_1 (Lisp_Object items);
#define BPLINE(width) ((int)(~3UL & (unsigned long)((width) +3)))
int dest_mask,
void *bmp_data,
int bmp_bits,
+ int slices,
Lisp_Object instantiator,
int x_hot, int y_hot,
int create_mask)
/* copy in the actual bitmap */
memcpy (bmp_buf, bmp_data, bmp_bits);
- mswindows_initialize_dibitmap_image_instance (ii, type);
+ mswindows_initialize_dibitmap_image_instance (ii, slices, type);
IMAGE_INSTANCE_PIXMAP_FILENAME (ii) =
find_keyword_in_vector (instantiator, Q_file);
+ /* Fixup a set of bitmaps. */
IMAGE_INSTANCE_MSWINDOWS_BITMAP (ii) = bitmap;
+
IMAGE_INSTANCE_MSWINDOWS_MASK (ii) = NULL;
IMAGE_INSTANCE_PIXMAP_WIDTH (ii) = bmp_info->bmiHeader.biWidth;
IMAGE_INSTANCE_PIXMAP_HEIGHT (ii) = bmp_info->bmiHeader.biHeight;
}
static void
+image_instance_add_dibitmap (struct Lisp_Image_Instance *ii,
+ BITMAPINFO *bmp_info,
+ void *bmp_data,
+ int bmp_bits,
+ int slice,
+ Lisp_Object instantiator)
+{
+ Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
+ struct device *d = XDEVICE (device);
+ struct frame *f = XFRAME (DEVICE_SELECTED_FRAME (d));
+ void* bmp_buf=0;
+ HDC hdc = FRAME_MSWINDOWS_CDC (f);
+ HBITMAP bitmap = CreateDIBSection (hdc,
+ bmp_info,
+ DIB_RGB_COLORS,
+ &bmp_buf,
+ 0,0);
+
+ if (!bitmap || !bmp_buf)
+ signal_simple_error ("Unable to create bitmap", instantiator);
+
+ /* copy in the actual bitmap */
+ memcpy (bmp_buf, bmp_data, bmp_bits);
+ IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICE (ii, slice) = bitmap;
+}
+
+static void
mswindows_init_image_instance_from_eimage (struct Lisp_Image_Instance *ii,
int width, int height,
+ int slices,
unsigned char *eimage,
int dest_mask,
Lisp_Object instantiator,
unsigned char* bmp_data;
int bmp_bits;
COLORREF bkcolor;
+ int slice;
if (!DEVICE_MSWINDOWS_P (XDEVICE (device)))
signal_simple_error ("Not an mswindows device", device);
bkcolor = COLOR_INSTANCE_MSWINDOWS_COLOR
(XCOLOR_INSTANCE (FACE_BACKGROUND (Vdefault_face, domain)));
- /* build a bitmap from the eimage */
- if (!(bmp_info=convert_EImage_to_DIBitmap (device, width, height, eimage,
- &bmp_bits, &bmp_data)))
+ for (slice = 0; slice < slices; slice++)
{
- signal_simple_error ("EImage to DIBitmap conversion failed",
- instantiator);
- }
-
- /* Now create the pixmap and set up the image instance */
- init_image_instance_from_dibitmap (ii, bmp_info, dest_mask,
- bmp_data, bmp_bits, instantiator,
- 0, 0, 0);
+ /* build a bitmap from the eimage */
+ if (!(bmp_info=convert_EImage_to_DIBitmap (device, width, height,
+ eimage + (width * height * 3 * slice),
+ &bmp_bits, &bmp_data)))
+ {
+ signal_simple_error ("EImage to DIBitmap conversion failed",
+ instantiator);
+ }
- xfree (bmp_info);
- xfree (bmp_data);
+ /* Now create the pixmap and set up the image instance */
+ if (slice == 0)
+ init_image_instance_from_dibitmap (ii, bmp_info, dest_mask,
+ bmp_data, bmp_bits, slices, instantiator,
+ 0, 0, 0);
+ else
+ image_instance_add_dibitmap (ii, bmp_info, bmp_data, bmp_bits, slice,
+ instantiator);
+
+ xfree (bmp_info);
+ xfree (bmp_data);
+ }
}
static void set_mono_pixel ( unsigned char* bits,
/* Now create the pixmap and set up the image instance */
init_image_instance_from_dibitmap (ii, bmp_info, dest_mask,
- bmp_data, bmp_bits, instantiator,
+ bmp_data, bmp_bits, 1, instantiator,
x_hot, y_hot, transp);
xfree (bmp_info);
/* Now create the pixmap and set up the image instance */
init_image_instance_from_dibitmap (ii, bmp_info, dest_mask,
- bmp_data, bmp_bits, instantiator,
+ bmp_data, bmp_bits, 1, instantiator,
0, 0, 0);
}
if (hinst)
FreeLibrary (hinst);
- mswindows_initialize_dibitmap_image_instance (ii, iitype);
+ mswindows_initialize_dibitmap_image_instance (ii, 1, iitype);
IMAGE_INSTANCE_PIXMAP_FILENAME (ii) = file;
IMAGE_INSTANCE_PIXMAP_WIDTH (ii) =
IMAGE_MONO_PIXMAP_MASK | IMAGE_COLOR_PIXMAP_MASK
| IMAGE_POINTER_MASK);
- mswindows_initialize_dibitmap_image_instance (ii, type);
+ mswindows_initialize_dibitmap_image_instance (ii, 1, type);
IMAGE_INSTANCE_PIXMAP_FILENAME (ii) =
find_keyword_in_vector (instantiator, Q_file);
}
}
+#ifdef DEBUG_WIDGETS
+extern int debug_widget_instances;
+#endif
+
static void
mswindows_finalize_image_instance (struct Lisp_Image_Instance *p)
{
||
IMAGE_INSTANCE_TYPE (p) == IMAGE_SUBWINDOW)
{
+#ifdef DEBUG_WIDGETS
+ debug_widget_instances--;
+ stderr_out ("widget destroyed, %d left\n", debug_widget_instances);
+#endif
if (IMAGE_INSTANCE_SUBWINDOW_ID (p))
- DestroyWindow (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p));
- IMAGE_INSTANCE_SUBWINDOW_ID (p) = 0;
+ {
+ DestroyWindow (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p));
+ DestroyWindow (IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (p));
+ IMAGE_INSTANCE_SUBWINDOW_ID (p) = 0;
+ }
}
else if (p->data)
{
- if (IMAGE_INSTANCE_MSWINDOWS_BITMAP (p))
- DeleteObject (IMAGE_INSTANCE_MSWINDOWS_BITMAP (p));
- IMAGE_INSTANCE_MSWINDOWS_BITMAP (p) = 0;
+ int i;
+ if (IMAGE_INSTANCE_PIXMAP_TIMEOUT (p))
+ disable_glyph_animated_timeout (IMAGE_INSTANCE_PIXMAP_TIMEOUT (p));
+
+ if (IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICES (p))
+ {
+ for (i = 0; i < IMAGE_INSTANCE_PIXMAP_MAXSLICE (p); i++)
+ {
+ if (IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICE (p, i))
+ DeleteObject (IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICE (p, i));
+ IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICE (p, i) = 0;
+ }
+ xfree (IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICES (p));
+ IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICES (p) = 0;
+ }
if (IMAGE_INSTANCE_MSWINDOWS_MASK (p))
DeleteObject (IMAGE_INSTANCE_MSWINDOWS_MASK (p));
IMAGE_INSTANCE_MSWINDOWS_MASK (p) = 0;
{
if (IMAGE_INSTANCE_SUBWINDOW_ID (p))
{
- SetWindowPos (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p),
+ SetWindowPos (IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (p),
NULL,
0, 0, 0, 0,
- SWP_HIDEWINDOW | SWP_NOMOVE | SWP_NOSIZE
- | SWP_NOCOPYBITS | SWP_NOSENDCHANGING);
+ SWP_HIDEWINDOW | SWP_NOMOVE | SWP_NOSIZE
+ | SWP_NOSENDCHANGING);
}
}
/* map the subwindow. This is used by redisplay via
redisplay_output_subwindow */
static void
-mswindows_map_subwindow (struct Lisp_Image_Instance *p, int x, int y)
+mswindows_map_subwindow (struct Lisp_Image_Instance *p, int x, int y,
+ struct display_glyph_area* dga)
{
- /* ShowWindow (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p), SW_SHOW);*/
- SetWindowPos (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p),
+ /* move the window before mapping it ... */
+ SetWindowPos (IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (p),
NULL,
- x, y, 0, 0,
- SWP_NOZORDER | SWP_SHOWWINDOW | SWP_NOSIZE
+ x, y, dga->width, dga->height,
+ SWP_NOZORDER
| SWP_NOCOPYBITS | SWP_NOSENDCHANGING);
+ /* ... adjust the child ... */
+ SetWindowPos (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p),
+ NULL,
+ -dga->xoffset, -dga->yoffset, 0, 0,
+ SWP_NOZORDER | SWP_NOSIZE
+ | SWP_NOCOPYBITS | SWP_NOSENDCHANGING);
+ /* ... now map it - we are not allowed to move it at the same time. */
+ SetWindowPos (IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (p),
+ NULL,
+ 0, 0, 0, 0,
+ SWP_NOZORDER | SWP_NOSIZE | SWP_NOMOVE
+ | SWP_SHOWWINDOW | SWP_NOCOPYBITS
+ | SWP_NOSENDCHANGING);
}
/* resize the subwindow instance */
static void
mswindows_resize_subwindow (struct Lisp_Image_Instance* ii, int w, int h)
{
+ /* Set the size of the control .... */
SetWindowPos (WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii),
NULL,
0, 0, w, h,
/* buttons checked or otherwise */
if ( EQ (IMAGE_INSTANCE_WIDGET_TYPE (p), Qbutton))
{
- if (gui_item_selected_p (IMAGE_INSTANCE_WIDGET_SINGLE_ITEM (p)))
+ if (gui_item_selected_p (IMAGE_INSTANCE_WIDGET_ITEM (p)))
SendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p),
BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
else
SendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p),
BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);
}
+
+ /* set the widget font from the widget face */
+ SendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p),
+ WM_SETFONT,
+ (WPARAM)FONT_INSTANCE_MSWINDOWS_HFONT
+ (XFONT_INSTANCE (widget_face_font_info
+ (IMAGE_INSTANCE_SUBWINDOW_FRAME (p),
+ IMAGE_INSTANCE_WIDGET_FACE (p),
+ 0, 0))),
+ MAKELPARAM (TRUE, 0));
}
}
static int
mswindows_register_widget_instance (Lisp_Object instance, Lisp_Object domain)
{
- return mswindows_register_gui_item (XIMAGE_INSTANCE_WIDGET_SINGLE_ITEM (instance),
+ return mswindows_register_gui_item (XIMAGE_INSTANCE_WIDGET_ITEM (instance),
domain);
}
/* have to set the type this late in case there is no device
instantiation for a widget */
IMAGE_INSTANCE_TYPE (ii) = IMAGE_SUBWINDOW;
+ /* Allocate space for the clip window */
+ ii->data = xnew_and_zero (struct mswindows_subwindow_data);
+
+ if ((IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (ii)
+ = CreateWindowEx(
+ 0, /* EX flags */
+ XEMACS_CONTROL_CLASS,
+ 0, /* text */
+ WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_CHILD,
+ 0, /* starting x position */
+ 0, /* starting y position */
+ IMAGE_INSTANCE_WIDGET_WIDTH (ii),
+ IMAGE_INSTANCE_WIDGET_HEIGHT (ii),
+ /* parent window */
+ FRAME_MSWINDOWS_HANDLE (XFRAME (frame)),
+ NULL, /* No menu */
+ NULL, /* must be null for this class */
+ NULL)) == NULL)
+ signal_simple_error ("window creation failed with code",
+ make_int (GetLastError()));
wnd = CreateWindow( "STATIC",
"",
0, /* starting y position */
IMAGE_INSTANCE_WIDGET_WIDTH (ii),
IMAGE_INSTANCE_WIDGET_HEIGHT (ii),
- FRAME_MSWINDOWS_HANDLE (XFRAME (frame)), /* parent window */
+ IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (ii),
0,
(HINSTANCE)
GetWindowLong (FRAME_MSWINDOWS_HANDLE (XFRAME (frame)),
static void
mswindows_initialize_dibitmap_image_instance (struct Lisp_Image_Instance *ii,
+ int slices,
enum image_instance_type type)
{
ii->data = xnew_and_zero (struct mswindows_image_instance_data);
IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (ii) = Qnil;
IMAGE_INSTANCE_PIXMAP_FG (ii) = Qnil;
IMAGE_INSTANCE_PIXMAP_BG (ii) = Qnil;
+ IMAGE_INSTANCE_PIXMAP_MAXSLICE (ii) = slices;
+ IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICES (ii) =
+ xnew_array_and_zero (HBITMAP, slices);
}
\f
+#ifdef HAVE_WIDGETS
+
/************************************************************************/
/* widgets */
/************************************************************************/
int dest_mask, Lisp_Object domain,
CONST char* class, int flags, int exflags)
{
+ /* this function can call lisp */
struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
-#if 0
- struct Lisp_Image_Instance *groupii = 0;
- Lisp_Object group = find_keyword_in_vector (instantiator, Q_group);
-#endif
Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii), style;
struct device* d = XDEVICE (device);
Lisp_Object frame = FW_FRAME (domain);
if (!DEVICE_MSWINDOWS_P (d))
signal_simple_error ("Not an mswindows device", device);
-#if 0
- /* if the user specified another glyph as a group pick up the
- instance in our domain. */
- if (!NILP (group))
- {
- if (SYMBOLP (group))
- group = XSYMBOL (group)->value;
- group = glyph_image_instance (group, domain, ERROR_ME, 1);
- groupii = XIMAGE_INSTANCE (group);
- }
-#endif
+
if (!gui_item_active_p (gui))
flags |= WS_DISABLED;
if (!NILP (IMAGE_INSTANCE_WIDGET_TEXT (ii)))
GET_C_STRING_OS_DATA_ALLOCA (IMAGE_INSTANCE_WIDGET_TEXT (ii), nm);
- wnd = CreateWindowEx(
- exflags /* | WS_EX_NOPARENTNOTIFY*/,
- class,
- nm,
- flags | WS_CHILD,
- 0, /* starting x position */
- 0, /* starting y position */
- IMAGE_INSTANCE_WIDGET_WIDTH (ii),
- IMAGE_INSTANCE_WIDGET_HEIGHT (ii),
- /* parent window */
- FRAME_MSWINDOWS_HANDLE (XFRAME (frame)),
- (HMENU)id, /* No menu */
- (HINSTANCE)
- GetWindowLong (FRAME_MSWINDOWS_HANDLE (XFRAME (frame)),
- GWL_HINSTANCE),
- NULL);
+ /* allocate space for the clip window and then allocate the clip window */
+ ii->data = xnew_and_zero (struct mswindows_subwindow_data);
+
+ if ((IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (ii)
+ = CreateWindowEx(
+ 0, /* EX flags */
+ XEMACS_CONTROL_CLASS,
+ 0, /* text */
+ WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_CHILD,
+ 0, /* starting x position */
+ 0, /* starting y position */
+ IMAGE_INSTANCE_WIDGET_WIDTH (ii),
+ IMAGE_INSTANCE_WIDGET_HEIGHT (ii),
+ /* parent window */
+ FRAME_MSWINDOWS_HANDLE (XFRAME (frame)),
+ (HMENU)id, /* No menu */
+ NULL, /* must be null for this class */
+ NULL)) == NULL)
+ signal_simple_error ("window creation failed with code",
+ make_int (GetLastError()));
+
+ if ((wnd = CreateWindowEx(
+ exflags /* | WS_EX_NOPARENTNOTIFY*/,
+ class,
+ nm,
+ flags | WS_CHILD | WS_VISIBLE,
+ 0, /* starting x position */
+ 0, /* starting y position */
+ IMAGE_INSTANCE_WIDGET_WIDTH (ii),
+ IMAGE_INSTANCE_WIDGET_HEIGHT (ii),
+ /* parent window */
+ IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (ii),
+ (HMENU)id, /* No menu */
+ (HINSTANCE)
+ GetWindowLong
+ (FRAME_MSWINDOWS_HANDLE (XFRAME (frame)),
+ GWL_HINSTANCE),
+ NULL)) == NULL)
+ signal_simple_error ("window creation failed with code",
+ make_int (GetLastError()));
IMAGE_INSTANCE_SUBWINDOW_ID (ii) = wnd;
SetWindowLong (wnd, GWL_USERDATA, (LONG)LISP_TO_VOID(image_instance));
Lisp_Object pointer_fg, Lisp_Object pointer_bg,
int dest_mask, Lisp_Object domain)
{
+ /* this function can call lisp */
struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
HWND wnd;
int flags = BS_NOTIFY;
/* instantiate a tree view widget */
static HTREEITEM add_tree_item (Lisp_Object image_instance,
- HWND wnd, HTREEITEM parent, Lisp_Object entry,
+ HWND wnd, HTREEITEM parent, Lisp_Object item,
int children, Lisp_Object domain)
{
TV_INSERTSTRUCT tvitem;
tvitem.item.mask = TVIF_TEXT | TVIF_CHILDREN;
tvitem.item.cChildren = children;
- if (VECTORP (entry))
- {
- /* we always maintain the real gui item at the head of the
- list. We have to put them in the list in the first place
- because the whole model assumes that the glyph instances have
- references to all the associated data. If we didn't do this
- GC would bite us badly. */
- Lisp_Object gui = gui_parse_item_keywords_no_errors (entry);
- if (CONSP (XIMAGE_INSTANCE_WIDGET_ITEM (image_instance)))
- {
- Lisp_Object rest =
- Fcons (gui, XCDR (XIMAGE_INSTANCE_WIDGET_ITEM (image_instance)));
- Fsetcdr (XIMAGE_INSTANCE_WIDGET_ITEM (image_instance), rest);
- }
- else
- {
- XIMAGE_INSTANCE_WIDGET_ITEM (image_instance) =
- Fcons (XIMAGE_INSTANCE_WIDGET_ITEM (image_instance), gui);
- }
-
- tvitem.item.lParam = mswindows_register_gui_item (gui, domain);
+ if (GUI_ITEMP (item))
+ {
+ tvitem.item.lParam = mswindows_register_gui_item (item, domain);
tvitem.item.mask |= TVIF_PARAM;
- GET_C_STRING_OS_DATA_ALLOCA (XGUI_ITEM (gui)->name,
+ GET_C_STRING_OS_DATA_ALLOCA (XGUI_ITEM (item)->name,
tvitem.item.pszText);
}
else
- GET_C_STRING_OS_DATA_ALLOCA (entry, tvitem.item.pszText);
+ GET_C_STRING_OS_DATA_ALLOCA (item, tvitem.item.pszText);
tvitem.item.cchTextMax = strlen (tvitem.item.pszText);
if ((ret = (HTREEITEM)SendMessage (wnd, TVM_INSERTITEM,
0, (LPARAM)&tvitem)) == 0)
- signal_simple_error ("error adding tree view entry", entry);
+ signal_simple_error ("error adding tree view entry", item);
return ret;
}
wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
/* define a root */
- parent = add_tree_item (image_instance,
- wnd, NULL, IMAGE_INSTANCE_WIDGET_TEXT (ii), TRUE,
- domain);
+ parent = add_tree_item (image_instance, wnd, NULL,
+ XCAR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)),
+ TRUE, domain);
/* recursively add items to the tree view */
- LIST_LOOP (rest, Fplist_get (IMAGE_INSTANCE_WIDGET_PROPS (ii), Q_items, Qnil))
+ /* add items to the tab */
+ LIST_LOOP (rest, XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)))
{
if (LISTP (XCAR (rest)))
add_tree_item_list (image_instance, wnd, parent, XCAR (rest), domain);
/* instantiate a tab control */
static TC_ITEM* add_tab_item (Lisp_Object image_instance,
- HWND wnd, Lisp_Object entry,
+ HWND wnd, Lisp_Object item,
Lisp_Object domain, int index)
{
TC_ITEM tvitem, *ret;
tvitem.mask = TCIF_TEXT;
- if (VECTORP (entry))
- {
- /* we always maintain the real gui item at the head of the
- list. We have to put them in the list in the first place
- because the whole model assumes that the glyph instances have
- references to all the associated data. If we didn't do this
- GC would bite us badly. */
- Lisp_Object gui = gui_parse_item_keywords_no_errors (entry);
- if (CONSP (XIMAGE_INSTANCE_WIDGET_ITEM (image_instance)))
- {
- Lisp_Object rest =
- Fcons (gui, XCDR (XIMAGE_INSTANCE_WIDGET_ITEM (image_instance)));
- Fsetcdr (XIMAGE_INSTANCE_WIDGET_ITEM (image_instance), rest);
- }
- else
- {
- XIMAGE_INSTANCE_WIDGET_ITEM (image_instance) =
- Fcons (XIMAGE_INSTANCE_WIDGET_ITEM (image_instance), gui);
- }
-
- tvitem.lParam = mswindows_register_gui_item (gui, domain);
+ if (GUI_ITEMP (item))
+ {
+ tvitem.lParam = mswindows_register_gui_item (item, domain);
tvitem.mask |= TCIF_PARAM;
- GET_C_STRING_OS_DATA_ALLOCA (XGUI_ITEM (gui)->name,
+ GET_C_STRING_OS_DATA_ALLOCA (XGUI_ITEM (item)->name,
tvitem.pszText);
}
else
- GET_C_STRING_OS_DATA_ALLOCA (entry, tvitem.pszText);
+ {
+ CHECK_STRING (item);
+ GET_C_STRING_OS_DATA_ALLOCA (item, tvitem.pszText);
+ }
tvitem.cchTextMax = strlen (tvitem.pszText);
if ((ret = (TC_ITEM*)SendMessage (wnd, TCM_INSERTITEM,
index, (LPARAM)&tvitem)) < 0)
- signal_simple_error ("error adding tab entry", entry);
+ signal_simple_error ("error adding tab entry", item);
return ret;
}
wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
/* add items to the tab */
- LIST_LOOP (rest, Fplist_get (IMAGE_INSTANCE_WIDGET_PROPS (ii), Q_items, Qnil))
+ LIST_LOOP (rest, XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)))
{
add_tab_item (image_instance, wnd, XCAR (rest), domain, index);
index++;
/* delete the pre-existing items */
SendMessage (wnd, TCM_DELETEALLITEMS, 0, 0);
+ IMAGE_INSTANCE_WIDGET_ITEMS (ii) =
+ Fcons (XCAR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)),
+ parse_gui_item_tree_children (val));
+
/* add items to the tab */
- LIST_LOOP (rest, val)
+ LIST_LOOP (rest, XCDR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)))
{
add_tab_item (image_instance, wnd, XCAR (rest),
IMAGE_INSTANCE_SUBWINDOW_FRAME (ii), index);
0, WS_EX_STATICEDGE);
}
-#if 0
-/* instantiate a static control possible for putting other things in */
-static void
-mswindows_group_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
- Lisp_Object pointer_fg, Lisp_Object pointer_bg,
- int dest_mask, Lisp_Object domain)
-{
- mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
- pointer_bg, dest_mask, domain, "BUTTON",
- WS_GROUP | BS_GROUPBOX | WS_BORDER,
- WS_EX_CLIENTEDGE );
-}
-#endif
-
/* instantiate a scrollbar control */
static void
mswindows_scrollbar_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
HANDLE wnd;
Lisp_Object rest;
+ Lisp_Object data = Fplist_get (find_keyword_in_vector (instantiator, Q_properties),
+ Q_items, Qnil);
+ int len;
+ GET_LIST_LENGTH (data, len);
/* Maybe ought to generalise this more but it may be very windows
specific. In windows the window height of a combo box is the
before creating the window and then reset it to a single line
after the window is created so that redisplay does the right
thing. */
+ widget_instantiate_1 (image_instance, instantiator, pointer_fg,
+ pointer_bg, dest_mask, domain, len + 1, 0, 0);
+
mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
pointer_bg, dest_mask, domain, "COMBOBOX",
WS_BORDER | WS_TABSTOP | CBS_DROPDOWN
return Qunbound;
}
+LRESULT WINAPI
+mswindows_control_wnd_proc (HWND hwnd, UINT message,
+ WPARAM wParam, LPARAM lParam)
+{
+ switch (message)
+ {
+ case WM_NOTIFY:
+ case WM_COMMAND:
+ case WM_CTLCOLORBTN:
+ case WM_CTLCOLORLISTBOX:
+ case WM_CTLCOLOREDIT:
+ case WM_CTLCOLORSTATIC:
+ case WM_CTLCOLORSCROLLBAR:
+
+ return mswindows_wnd_proc (GetParent (hwnd), message, wParam, lParam);
+ default:
+ return DefWindowProc (hwnd, message, wParam, lParam);
+ }
+}
+
+#endif /* HAVE_WIDGETS */
+
\f
/************************************************************************/
/* initialization */
{
IIFORMAT_VALID_CONSOLE (mswindows, nothing);
IIFORMAT_VALID_CONSOLE (mswindows, string);
+ IIFORMAT_VALID_CONSOLE (mswindows, layout);
IIFORMAT_VALID_CONSOLE (mswindows, formatted_string);
IIFORMAT_VALID_CONSOLE (mswindows, inherit);
/* image-instantiator types */
#ifdef HAVE_GIF
IIFORMAT_VALID_CONSOLE (mswindows, gif);
#endif
+#ifdef HAVE_WIDGETS
/* button widget */
INITIALIZE_DEVICE_IIFORMAT (mswindows, button);
IIFORMAT_HAS_DEVMETHOD (mswindows, button, property);
INITIALIZE_DEVICE_IIFORMAT (mswindows, widget);
IIFORMAT_HAS_DEVMETHOD (mswindows, widget, property);
IIFORMAT_HAS_DEVMETHOD (mswindows, widget, set_property);
-#if 0
- INITIALIZE_DEVICE_IIFORMAT (mswindows, group);
- IIFORMAT_HAS_DEVMETHOD (mswindows, group, instantiate);
-#endif
+
/* label */
INITIALIZE_DEVICE_IIFORMAT (mswindows, label);
IIFORMAT_HAS_DEVMETHOD (mswindows, label, instantiate);
INITIALIZE_DEVICE_IIFORMAT (mswindows, tab_control);
IIFORMAT_HAS_DEVMETHOD (mswindows, tab_control, instantiate);
IIFORMAT_HAS_DEVMETHOD (mswindows, tab_control, set_property);
-
+#endif
/* windows bitmap format */
INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (bmp, "bmp");
IIFORMAT_HAS_METHOD (bmp, validate);
struct mswindows_image_instance_data
{
- HBITMAP bitmap;
- HBITMAP mask;
+ HBITMAP* bitmaps;
HICON icon;
};
((struct mswindows_image_instance_data *) (i)->data)
#define IMAGE_INSTANCE_MSWINDOWS_BITMAP(i) \
- (MSWINDOWS_IMAGE_INSTANCE_DATA (i)->bitmap)
+ (MSWINDOWS_IMAGE_INSTANCE_DATA (i)->bitmaps[0])
+#define IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICE(i,slice) \
+ (MSWINDOWS_IMAGE_INSTANCE_DATA (i)->bitmaps[slice])
+#define IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICES(i) \
+ (MSWINDOWS_IMAGE_INSTANCE_DATA (i)->bitmaps)
#define IMAGE_INSTANCE_MSWINDOWS_MASK(i) \
- (MSWINDOWS_IMAGE_INSTANCE_DATA (i)->mask)
+ (HBITMAP)(IMAGE_INSTANCE_PIXMAP_MASK (i))
#define IMAGE_INSTANCE_MSWINDOWS_ICON(i) \
(MSWINDOWS_IMAGE_INSTANCE_DATA (i)->icon)
#define XIMAGE_INSTANCE_MSWINDOWS_BITMAP(i) \
IMAGE_INSTANCE_MSWINDOWS_BITMAP (XIMAGE_INSTANCE (i))
+#define XIMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICE(i,slice) \
+ IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICE (XIMAGE_INSTANCE (i,slice))
+#define XIMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICES(i) \
+ IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICES (XIMAGE_INSTANCE (i))
#define XIMAGE_INSTANCE_MSWINDOWS_MASK(i) \
IMAGE_INSTANCE_MSWINDOWS_MASK (XIMAGE_INSTANCE (i))
#define XIMAGE_INSTANCE_MSWINDOWS_ICON(i) \
#define XWIDGET_INSTANCE_MSWINDOWS_HANDLE(i) \
WIDGET_INSTANCE_MSWINDOWS_HANDLE (XIMAGE_INSTANCE (i))
+struct mswindows_subwindow_data
+{
+ HWND clip_window;
+};
+
+#define MSWINDOWS_SUBWINDOW_DATA(i) \
+((struct mswindows_subwindow_data *) (i)->data)
+
+#define IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW(i) \
+ (MSWINDOWS_SUBWINDOW_DATA (i)->clip_window)
+
+#define XIMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW(i) \
+ IMAGE_INSTANCE_MSWINDOWS_CLIPWINDOW (XIMAGE_INSTANCE (i))
+
#endif /* HAVE_MS_WINDOWS */
#endif /* _XEMACS_GLYPHS_MSW_H_ */
/* Widget-specific glyph objects.
- Copyright (C) 1998 Andy Piper
+ Copyright (C) 1998, 1999 Andy Piper.
This file is part of XEmacs.
DEFINE_IMAGE_INSTANTIATOR_FORMAT (scrollbar);
Lisp_Object Qscrollbar;
DEFINE_IMAGE_INSTANTIATOR_FORMAT (widget);
-#if 0
-DEFINE_IMAGE_INSTANTIATOR_FORMAT (group);
-Lisp_Object Qgroup;
-#endif
DEFINE_IMAGE_INSTANTIATOR_FORMAT (label);
Lisp_Object Qlabel;
DEFINE_IMAGE_INSTANTIATOR_FORMAT (progress_gauge);
Lisp_Object Qtree_view;
DEFINE_IMAGE_INSTANTIATOR_FORMAT (tab_control);
Lisp_Object Qtab_control;
+DEFINE_IMAGE_INSTANTIATOR_FORMAT (layout);
+Lisp_Object Qlayout;
Lisp_Object Q_descriptor, Q_height, Q_width, Q_properties, Q_items;
-Lisp_Object Q_image, Q_text, Q_percent;
+Lisp_Object Q_image, Q_text, Q_percent, Q_orientation, Q_justify, Q_border;
+Lisp_Object Qetched_in, Qetched_out, Qbevel_in, Qbevel_out;
-#define WIDGET_BORDER_HEIGHT 2
+#define WIDGET_BORDER_HEIGHT 4
#define WIDGET_BORDER_WIDTH 4
+#ifdef DEBUG_WIDGETS
+int debug_widget_instances;
+#endif
+
/* TODO:
- more complex controls.
- tooltips for controls.
int ch=0, cw=0;
widget_face_font_info (domain, face, &ch, &cw);
if (height)
- *height = th * (ch + 2 * WIDGET_BORDER_HEIGHT);
+ *height = th * ch + 2 * WIDGET_BORDER_HEIGHT;
if (width)
*width = tw * cw + 2 * WIDGET_BORDER_WIDTH;
}
}
static void
-check_valid_glyph_or_image (Lisp_Object data)
+check_valid_glyph_or_instantiator (Lisp_Object data)
{
Lisp_Object glyph = data;
if (SYMBOLP (data))
if (IMAGE_INSTANCEP (glyph))
CHECK_IMAGE_INSTANCE (glyph);
- else if (!CONSP (glyph))
+ else if (!CONSP (glyph) && !VECTORP (glyph))
CHECK_BUFFER_GLYPH (glyph);
}
static void
+check_valid_orientation (Lisp_Object data)
+{
+ if (!EQ (data, Qhorizontal)
+ &&
+ !EQ (data, Qvertical))
+ signal_simple_error ("unknown orientation for layout", data);
+}
+
+static void
+check_valid_justification (Lisp_Object data)
+{
+ if (!EQ (data, Qleft) && !EQ (data, Qright) && !EQ (data, Qcenter))
+ signal_simple_error ("unknown justification for layout", data);
+}
+
+static void
+check_valid_border (Lisp_Object data)
+{
+ if (!EQ (data, Qt) && !EQ (data, Qetched_in) && !EQ (data, Qetched_out)
+ && !EQ (data, Qbevel_in) && !EQ (data, Qbevel_out)
+ && !GLYPHP (data) && !VECTORP (data))
+ signal_simple_error ("unknown border style for layout", data);
+}
+
+static void
check_valid_anything (Lisp_Object data)
{
}
check_valid_item_list_1 (items);
}
+static void
+check_valid_glyph_or_instantiator_list (Lisp_Object data)
+{
+ Lisp_Object rest;
+
+ CHECK_LIST (data);
+ EXTERNAL_LIST_LOOP (rest, data)
+ {
+ check_valid_glyph_or_instantiator (XCAR (rest));
+ }
+}
+
+static Lisp_Object
+glyph_instantiator_to_glyph (Lisp_Object sym)
+{
+ /* This function calls lisp. */
+ Lisp_Object glyph = sym;
+ struct gcpro gcpro1;
+
+ GCPRO1 (glyph);
+ /* if we have a symbol get at the actual data */
+ if (SYMBOLP (glyph))
+ glyph = XSYMBOL (glyph)->value;
+
+ if (CONSP (glyph))
+ glyph = Feval (glyph);
+
+ /* Be really helpful to the user. */
+ if (VECTORP (glyph))
+ {
+ glyph = call1 (intern ("make-glyph"), glyph);
+ }
+
+ /* substitute the new glyph */
+ RETURN_UNGCPRO (glyph);
+}
+
+static void
+substitute_keyword_value (Lisp_Object inst, Lisp_Object key, Lisp_Object val)
+{
+ int i;
+ /* substitute the new glyph */
+ for (i = 0; i < XVECTOR_LENGTH (inst); i++)
+ {
+ if (EQ (key, XVECTOR_DATA (inst)[i]))
+ {
+ XVECTOR_DATA (inst)[i+1] = val;
+ break;
+ }
+ }
+}
+
/* wire widget property invocations to specific widgets ... The
problem we are solving here is that when instantiators get converted
to instances they lose some type information (they just become
same reasons we normalize file to data. */
if (!NILP (glyph))
{
- int i;
- struct gcpro gcpro1;
- if (SYMBOLP (glyph))
- glyph = XSYMBOL (glyph)->value;
- GCPRO1 (glyph);
-
- if (CONSP (glyph))
- glyph = Feval (glyph);
- /* substitute the new glyph */
- for (i = 0; i < XVECTOR_LENGTH (inst); i++)
- {
- if (EQ (Q_image, XVECTOR_DATA (inst)[i]))
- {
- XVECTOR_DATA (inst)[i+1] = glyph;
- break;
- }
- }
- UNGCPRO;
+ substitute_keyword_value (inst, Q_image, glyph_instantiator_to_glyph (glyph));
}
+
return inst;
}
IMAGE_INSTANCE_WIDGET_TYPE (ii) = type;
IMAGE_INSTANCE_WIDGET_PROPS (ii) = Qnil;
IMAGE_INSTANCE_WIDGET_FACE (ii) = Vwidget_face;
- IMAGE_INSTANCE_WIDGET_ITEM (ii) = allocate_gui_item ();
+ IMAGE_INSTANCE_WIDGET_ITEMS (ii) = allocate_gui_item ();
}
/* Instantiate a button widget. Unfortunately instantiated widgets are
want to display it in and BitBlt it. So image instances can have a
many-to-one relationship with things you see, whereas widgets can
only be one-to-one (i.e. per frame) */
-static void
+void
widget_instantiate_1 (Lisp_Object image_instance, Lisp_Object instantiator,
Lisp_Object pointer_fg, Lisp_Object pointer_bg,
int dest_mask, Lisp_Object domain, int default_textheight,
Lisp_Object pixheight = find_keyword_in_vector (instantiator, Q_pixel_height);
Lisp_Object desc = find_keyword_in_vector (instantiator, Q_descriptor);
Lisp_Object glyph = find_keyword_in_vector (instantiator, Q_image);
+ Lisp_Object props = find_keyword_in_vector (instantiator, Q_properties);
int pw=0, ph=0, tw=0, th=0;
/* this just does pixel type sizing */
IMAGE_INSTANCE_WIDGET_FACE (ii) = Fget_face (face);
/* data items for some widgets */
- IMAGE_INSTANCE_WIDGET_PROPS (ii) =
- find_keyword_in_vector (instantiator, Q_properties);
+ IMAGE_INSTANCE_WIDGET_PROPS (ii) = props;
/* retrieve the gui item information. This is easy if we have been
provided with a vector, more difficult if we have just been given
if (STRINGP (desc) || NILP (desc))
{
/* big cheat - we rely on the fact that a gui item looks like an instantiator */
- IMAGE_INSTANCE_WIDGET_ITEM (ii) =
+ IMAGE_INSTANCE_WIDGET_ITEMS (ii) =
gui_parse_item_keywords_no_errors (instantiator);
IMAGE_INSTANCE_WIDGET_TEXT (ii) = desc;
}
else
- IMAGE_INSTANCE_WIDGET_ITEM (ii) =
+ IMAGE_INSTANCE_WIDGET_ITEMS (ii) =
gui_parse_item_keywords_no_errors (desc);
+ /* parse more gui items out of the properties */
+ if (!NILP (props))
+ {
+ Lisp_Object items = Fplist_get (props, Q_items, Qnil);
+ if (!NILP (items))
+ IMAGE_INSTANCE_WIDGET_ITEMS (ii) =
+ Fcons (IMAGE_INSTANCE_WIDGET_ITEMS (ii),
+ parse_gui_item_tree_children (items));
+ }
+
/* normalize size information */
if (!NILP (width))
tw = XINT (width);
IMAGE_INSTANCE_SUBWINDOW_WIDTH (ii) = pw;
IMAGE_INSTANCE_SUBWINDOW_HEIGHT (ii) = ph;
+#ifdef DEBUG_WIDGETS
+ debug_widget_instances++;
+ stderr_out ("instantiated ");
+ debug_print (instantiator);
+ stderr_out ("%d widgets instantiated\n", debug_widget_instances);
+#endif
}
static void
pointer_bg, dest_mask, domain, 1, 0, 0);
}
-/* combo-box generic instantiation - get he heigh right */
+/* tree-view generic instantiation - get the height right */
static void
-combo_box_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
- Lisp_Object pointer_fg, Lisp_Object pointer_bg,
- int dest_mask, Lisp_Object domain)
+tree_view_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
+ Lisp_Object pointer_fg, Lisp_Object pointer_bg,
+ int dest_mask, Lisp_Object domain)
{
Lisp_Object data = Fplist_get (find_keyword_in_vector (instantiator, Q_properties),
Q_items, Qnil);
}
\f
+/*****************************************************************************
+ * widget layout *
+ *****************************************************************************/
+static int
+layout_possible_dest_types (void)
+{
+ return IMAGE_LAYOUT_MASK;
+}
+
+/* we need to convert things like glyphs to images, eval expressions
+ etc.*/
+static Lisp_Object
+layout_normalize (Lisp_Object inst, Lisp_Object console_type)
+{
+ /* This function can call lisp */
+ Lisp_Object items = find_keyword_in_vector (inst, Q_items);
+ Lisp_Object border = find_keyword_in_vector (inst, Q_border);
+ /* we need to eval glyph if its an expression, we do this for the
+ same reasons we normalize file to data. */
+ if (!NILP (items))
+ {
+ Lisp_Object rest;
+ LIST_LOOP (rest, items)
+ {
+ /* substitute the new glyph */
+ Fsetcar (rest, glyph_instantiator_to_glyph (XCAR (rest)));
+ }
+ }
+ /* normalize the border spec. */
+ if (VECTORP (border) || CONSP (border))
+ {
+ substitute_keyword_value (inst, Q_border, glyph_instantiator_to_glyph (border));
+ }
+ return inst;
+}
+
+/* Instantiate a layout widget. */
+static void
+layout_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
+ Lisp_Object pointer_fg, Lisp_Object pointer_bg,
+ int dest_mask, Lisp_Object domain)
+{
+ struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
+ Lisp_Object rest, device = IMAGE_INSTANCE_DEVICE (ii);
+ Lisp_Object frame = FW_FRAME (domain);
+ Lisp_Object items = find_keyword_in_vector (instantiator, Q_items);
+ Lisp_Object width = find_keyword_in_vector (instantiator, Q_pixel_width);
+ Lisp_Object height = find_keyword_in_vector (instantiator, Q_pixel_height);
+ Lisp_Object orient = find_keyword_in_vector (instantiator, Q_orientation);
+ Lisp_Object justify = find_keyword_in_vector (instantiator, Q_justify);
+ Lisp_Object border = find_keyword_in_vector (instantiator, Q_border);
+ Lisp_Object children = Qnil;
+ int pw = 0, ph = 0, x, y, maxph = 0, maxpw = 0, nitems = 0,
+ horiz_spacing, vert_spacing, ph_adjust = 0;
+
+ if (NILP (frame))
+ signal_simple_error ("No selected frame", device);
+
+ if (!(dest_mask & IMAGE_LAYOUT_MASK))
+ incompatible_image_types (instantiator, dest_mask, IMAGE_LAYOUT_MASK);
+
+ if (NILP (orient))
+ orient = Qvertical;
+
+ if (EQ (border, Qt))
+ border = Qetched_in;
+
+ ii->data = 0;
+ IMAGE_INSTANCE_TYPE (ii) = IMAGE_LAYOUT;
+ IMAGE_INSTANCE_SUBWINDOW_ID (ii) = 0;
+ IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (ii) = 0;
+ IMAGE_INSTANCE_SUBWINDOW_FRAME (ii) = frame;
+ IMAGE_INSTANCE_LAYOUT_BORDER (ii) = border;
+
+ /* normalize size information */
+ if (!NILP (width))
+ pw = XINT (width);
+ if (!NILP (height))
+ ph = XINT (height);
+
+ /* flip through the items to work out how much stuff we have to display */
+ LIST_LOOP (rest, items)
+ {
+ Lisp_Object glyph = XCAR (rest);
+ int gheight = glyph_height (glyph, Qnil, DEFAULT_INDEX, domain);
+ int gwidth = glyph_width (glyph, Qnil, DEFAULT_INDEX, domain);
+ nitems ++;
+ if (EQ (orient, Qhorizontal))
+ {
+ maxph = max (maxph, gheight);
+ maxpw += gwidth;
+ }
+ else if (EQ (orient, Qvertical))
+ {
+ maxpw = max (maxpw, gwidth);
+ maxph += gheight;
+ }
+ }
+
+ /* work out spacing between items and bounds of the layout */
+ if (!pw)
+ {
+ /* No user provided width so we just do default spacing. */
+ horiz_spacing = WIDGET_BORDER_WIDTH * 2;
+ if (EQ (orient, Qhorizontal))
+ pw = maxpw + (nitems + 1) * horiz_spacing;
+ else
+ pw = maxpw + 2 * horiz_spacing;
+ }
+ else if (pw < maxpw)
+ /* The user wants a smaller space than the largest item, so we
+ just provide default spacing and will let the output routines
+ clip.. */
+ horiz_spacing = WIDGET_BORDER_WIDTH * 2;
+ else if (EQ (orient, Qhorizontal))
+ /* We have a larger area to display in so distribute the space
+ evenly. */
+ horiz_spacing = (pw - maxpw) / (nitems + 1);
+ else
+ horiz_spacing = (pw - maxpw) / 2;
+
+ /* Do the border now so that we can adjust the layout. */
+ if (GLYPHP (border))
+ {
+ /* We are going to be sneaky here and add the border text as
+ just another child, the layout and output routines don't know
+ this and will just display at the offsets we prescribe. */
+ Lisp_Object bglyph = glyph_image_instance (border, domain, ERROR_ME, 1);
+
+ children = Fcons (bglyph, children);
+ XIMAGE_INSTANCE_XOFFSET (bglyph) = 10; /* Really, what should this be? */
+ XIMAGE_INSTANCE_YOFFSET (bglyph) = 0;
+
+ ph_adjust = (glyph_height (border, Qnil, DEFAULT_INDEX, domain) / 2);
+ IMAGE_INSTANCE_LAYOUT_BORDER (ii) = make_int (ph_adjust);
+ }
+
+ /* Work out vertical spacings. */
+ if (!ph)
+ {
+ vert_spacing = WIDGET_BORDER_HEIGHT * 2;
+ if (EQ (orient, Qvertical))
+ ph = maxph + (nitems + 1) * vert_spacing + ph_adjust;
+ else
+ ph = maxph + 2 * vert_spacing + ph_adjust;
+ }
+ else if (ph < maxph)
+ vert_spacing = WIDGET_BORDER_HEIGHT * 2;
+ else if (EQ (orient, Qvertical))
+ vert_spacing = (ph - (maxph + ph_adjust)) / (nitems + 1);
+ else
+ vert_spacing = (ph - (maxph + ph_adjust)) / 2;
+
+ y = vert_spacing + ph_adjust;
+ x = horiz_spacing;
+
+ /* Now flip through putting items where we want them, paying
+ attention to justification. */
+ LIST_LOOP (rest, items)
+ {
+ /* make sure the image is instantiated */
+ Lisp_Object glyph = XCAR (rest);
+ Lisp_Object gii = glyph_image_instance (glyph, domain, ERROR_ME, 1);
+ int gwidth = glyph_width (glyph, Qnil, DEFAULT_INDEX, domain);
+ int gheight = glyph_height (glyph, Qnil, DEFAULT_INDEX, domain);
+
+ children = Fcons (gii, children);
+
+ if (EQ (orient, Qhorizontal))
+ {
+ if (EQ (justify, Qright))
+ y = ph - (gheight + vert_spacing);
+ else if (EQ (justify, Qcenter))
+ y = (ph - gheight) / 2;
+ }
+ else if (EQ (orient, Qvertical))
+ {
+ if (EQ (justify, Qright))
+ x = pw - (gwidth + horiz_spacing);
+ else if (EQ (justify, Qcenter))
+ x = (pw - gwidth) / 2;
+ }
+
+ XIMAGE_INSTANCE_XOFFSET (gii) = x;
+ XIMAGE_INSTANCE_YOFFSET (gii) = y;
+
+ if (EQ (orient, Qhorizontal))
+ {
+ x += (gwidth + horiz_spacing);
+ }
+ else if (EQ (orient, Qvertical))
+ {
+ y += (gheight + vert_spacing);
+ }
+ }
+
+ IMAGE_INSTANCE_LAYOUT_CHILDREN (ii) = children;
+ assert (pw && ph);
+ IMAGE_INSTANCE_SUBWINDOW_WIDTH (ii) = pw;
+ IMAGE_INSTANCE_SUBWINDOW_HEIGHT (ii) = ph;
+}
+
+\f
/************************************************************************/
/* initialization */
/************************************************************************/
defkeyword (&Q_image, ":image");
defkeyword (&Q_percent, ":percent");
defkeyword (&Q_text, ":text");
+ defkeyword (&Q_orientation, ":orientation");
+ defkeyword (&Q_justify, ":justify");
+ defkeyword (&Q_border, ":border");
+
+ defsymbol (&Qetched_in, "etched-in");
+ defsymbol (&Qetched_out, "etched-out");
+ defsymbol (&Qbevel_in, "bevel-in");
+ defsymbol (&Qbevel_out, "bevel-out");
}
void
IIFORMAT_HAS_SHARED_METHOD (button, possible_dest_types, widget);
IIFORMAT_HAS_SHARED_METHOD (button, instantiate, widget);
IIFORMAT_HAS_SHARED_METHOD (button, normalize, widget);
- IIFORMAT_VALID_KEYWORD (button, Q_image, check_valid_glyph_or_image);
+ IIFORMAT_VALID_KEYWORD (button,
+ Q_image, check_valid_glyph_or_instantiator);
VALID_WIDGET_KEYWORDS (button);
VALID_GUI_KEYWORDS (button);
INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (combo_box, "combo-box");
IIFORMAT_HAS_METHOD (combo_box, validate);
IIFORMAT_HAS_SHARED_METHOD (combo_box, possible_dest_types, widget);
- IIFORMAT_HAS_METHOD (combo_box, instantiate);
VALID_GUI_KEYWORDS (combo_box);
IIFORMAT_VALID_KEYWORD (combo_box, Q_width, check_valid_int);
INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (progress_gauge, "progress-gauge");
IIFORMAT_HAS_SHARED_METHOD (progress_gauge, validate, widget);
IIFORMAT_HAS_SHARED_METHOD (progress_gauge, possible_dest_types, widget);
- IIFORMAT_HAS_SHARED_METHOD (progress_gauge, instantiate, combo_box);
+ IIFORMAT_HAS_SHARED_METHOD (progress_gauge, instantiate, widget);
VALID_WIDGET_KEYWORDS (progress_gauge);
VALID_GUI_KEYWORDS (progress_gauge);
INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (tree_view, "tree-view");
IIFORMAT_HAS_SHARED_METHOD (tree_view, validate, combo_box);
IIFORMAT_HAS_SHARED_METHOD (tree_view, possible_dest_types, widget);
- IIFORMAT_HAS_SHARED_METHOD (tree_view, instantiate, combo_box);
+ IIFORMAT_HAS_METHOD (tree_view, instantiate);
VALID_WIDGET_KEYWORDS (tree_view);
VALID_GUI_KEYWORDS (tree_view);
IIFORMAT_VALID_KEYWORD (tree_view, Q_properties, check_valid_item_list);
VALID_WIDGET_KEYWORDS (label);
IIFORMAT_VALID_KEYWORD (label, Q_descriptor, check_valid_string);
-#if 0
- /* group */
- INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (group, "group");
- IIFORMAT_HAS_SHARED_METHOD (group, possible_dest_types, widget);
- IIFORMAT_HAS_METHOD (group, instantiate);
-
- IIFORMAT_VALID_KEYWORD (group, Q_width, check_valid_int);
- IIFORMAT_VALID_KEYWORD (group, Q_height, check_valid_int);
- IIFORMAT_VALID_KEYWORD (group, Q_pixel_width, check_valid_int);
- IIFORMAT_VALID_KEYWORD (group, Q_pixel_height, check_valid_int);
- IIFORMAT_VALID_KEYWORD (group, Q_face, check_valid_face);
- IIFORMAT_VALID_KEYWORD (group, Q_background, check_valid_string);
- IIFORMAT_VALID_KEYWORD (group, Q_descriptor, check_valid_string);
+ /* layout */
+ INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (layout, "layout");
+ IIFORMAT_HAS_METHOD (layout, possible_dest_types);
+ IIFORMAT_HAS_METHOD (layout, instantiate);
+ IIFORMAT_HAS_METHOD (layout, normalize);
+ IIFORMAT_VALID_KEYWORD (layout, Q_pixel_width, check_valid_int);
+ IIFORMAT_VALID_KEYWORD (layout, Q_pixel_height, check_valid_int);
+ IIFORMAT_VALID_KEYWORD (layout, Q_orientation, check_valid_orientation);
+ IIFORMAT_VALID_KEYWORD (layout, Q_justify, check_valid_justification);
+ IIFORMAT_VALID_KEYWORD (layout, Q_border, check_valid_border);
+ IIFORMAT_VALID_KEYWORD (layout, Q_items,
+ check_valid_glyph_or_instantiator_list);
+}
+
+void
+reinit_vars_of_glyphs_widget (void)
+{
+#ifdef DEBUG_WIDGETS
+ debug_widget_instances = 0;
#endif
}
void
vars_of_glyphs_widget (void)
{
+ reinit_vars_of_glyphs_widget ();
}
Many changes for color work and optimizations by Jareth Hein for 21.0
Switch of GIF/JPEG/PNG to new EImage intermediate code by Jareth Hein for 21.0
TIFF code by Jareth Hein for 21.0
- GIF/JPEG/PNG/TIFF code moved to new glyph-eimage.c for 21.0
+ GIF/JPEG/PNG/TIFF code moved to new glyph-eimage.c by Andy Piper for 21.0
+ Subwindow and Widget support by Andy Piper for 21.2
TODO:
Convert images.el to C and stick it in here?
#include "console-x.h"
#include "glyphs-x.h"
#include "objects-x.h"
+#ifdef HAVE_WIDGETS
#include "gui-x.h"
+#endif
#include "xmu.h"
#include "buffer.h"
#include "file-coding.h"
#endif
-#ifdef LWLIB_USES_MOTIF
+#ifdef LWLIB_WIDGETS_MOTIF
#include <Xm/Xm.h>
#endif
#include <X11/IntrinsicP.h>
DECLARE_IMAGE_INSTANTIATOR_FORMAT (string);
DECLARE_IMAGE_INSTANTIATOR_FORMAT (formatted_string);
DECLARE_IMAGE_INSTANTIATOR_FORMAT (inherit);
+DECLARE_IMAGE_INSTANTIATOR_FORMAT (layout);
#ifdef HAVE_JPEG
DECLARE_IMAGE_INSTANTIATOR_FORMAT (jpeg);
#endif
DEFINE_IMAGE_INSTANTIATOR_FORMAT (autodetect);
+#ifdef HAVE_WIDGETS
DEFINE_DEVICE_IIFORMAT (x, widget);
DEFINE_DEVICE_IIFORMAT (x, button);
DEFINE_DEVICE_IIFORMAT (x, progress_gauge);
DEFINE_DEVICE_IIFORMAT (x, edit_field);
+#if defined (LWLIB_WIDGETS_MOTIF) && XmVERSION > 1
DEFINE_DEVICE_IIFORMAT (x, combo_box);
+#endif
+DEFINE_DEVICE_IIFORMAT (x, tab_control);
+DEFINE_DEVICE_IIFORMAT (x, label);
+#endif
static void cursor_font_instantiate (Lisp_Object image_instance,
Lisp_Object instantiator,
int dest_mask,
Lisp_Object domain);
+#ifdef HAVE_WIDGETS
+static void
+update_widget_face (struct Lisp_Image_Instance* ii, Lisp_Object domain);
+#endif
+
#include "bitmaps.h"
\f
}
}
+#ifdef DEBUG_WIDGETS
+extern int debug_widget_instances;
+#endif
+
static void
x_finalize_image_instance (struct Lisp_Image_Instance *p)
{
{
if (IMAGE_INSTANCE_SUBWINDOW_ID (p))
{
- XtUnmanageChild (IMAGE_INSTANCE_X_WIDGET_ID (p));
- XtDestroyWidget (IMAGE_INSTANCE_X_WIDGET_ID (p));
+#ifdef DEBUG_WIDGETS
+ debug_widget_instances--;
+ stderr_out ("widget destroyed, %d left\n", debug_widget_instances);
+#endif
+ lw_destroy_widget (IMAGE_INSTANCE_X_WIDGET_ID (p));
+ lw_destroy_widget (IMAGE_INSTANCE_X_CLIPWIDGET (p));
IMAGE_INSTANCE_SUBWINDOW_ID (p) = 0;
}
}
}
else
{
- if (IMAGE_INSTANCE_X_PIXMAP (p))
- XFreePixmap (dpy, IMAGE_INSTANCE_X_PIXMAP (p));
+ int i;
+ if (IMAGE_INSTANCE_PIXMAP_TIMEOUT (p))
+ disable_glyph_animated_timeout (IMAGE_INSTANCE_PIXMAP_TIMEOUT (p));
+
if (IMAGE_INSTANCE_X_MASK (p) &&
IMAGE_INSTANCE_X_MASK (p) != IMAGE_INSTANCE_X_PIXMAP (p))
XFreePixmap (dpy, IMAGE_INSTANCE_X_MASK (p));
- IMAGE_INSTANCE_X_PIXMAP (p) = 0;
- IMAGE_INSTANCE_X_MASK (p) = 0;
+ IMAGE_INSTANCE_PIXMAP_MASK (p) = 0;
+ if (IMAGE_INSTANCE_X_PIXMAP_SLICES (p))
+ {
+ for (i = 0; i < IMAGE_INSTANCE_PIXMAP_MAXSLICE (p); i++)
+ if (IMAGE_INSTANCE_X_PIXMAP_SLICE (p,i))
+ {
+ XFreePixmap (dpy, IMAGE_INSTANCE_X_PIXMAP_SLICE (p,i));
+ IMAGE_INSTANCE_X_PIXMAP_SLICE (p, i) = 0;
+ }
+ xfree (IMAGE_INSTANCE_X_PIXMAP_SLICES (p));
+ IMAGE_INSTANCE_X_PIXMAP_SLICES (p) = 0;
+ }
+
if (IMAGE_INSTANCE_X_CURSOR (p))
{
XFreeCursor (dpy, IMAGE_INSTANCE_X_CURSOR (p));
}
}
}
- if (IMAGE_INSTANCE_X_PIXELS (p))
+ /* You can sometimes have pixels without a live device. I forget
+ why, but that's why we free them here if we have a pixmap type
+ image instance. It probably means that we might also get a memory
+ leak with widgets. */
+ if (IMAGE_INSTANCE_TYPE (p) != IMAGE_WIDGET
+ && IMAGE_INSTANCE_TYPE (p) != IMAGE_SUBWINDOW
+ && IMAGE_INSTANCE_X_PIXELS (p))
{
xfree (IMAGE_INSTANCE_X_PIXELS (p));
IMAGE_INSTANCE_X_PIXELS (p) = 0;
static void
x_initialize_pixmap_image_instance (struct Lisp_Image_Instance *ii,
+ int slices,
enum image_instance_type type)
{
ii->data = xnew_and_zero (struct x_image_instance_data);
+ IMAGE_INSTANCE_PIXMAP_MAXSLICE (ii) = slices;
+ IMAGE_INSTANCE_X_PIXMAP_SLICES (ii) =
+ xnew_array_and_zero (Pixmap, slices);
IMAGE_INSTANCE_TYPE (ii) = type;
IMAGE_INSTANCE_PIXMAP_FILENAME (ii) = Qnil;
IMAGE_INSTANCE_PIXMAP_MASK_FILENAME (ii) = Qnil;
Colormap cmap,
unsigned long *pixels,
int npixels,
+ int slices,
Lisp_Object instantiator)
{
Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
XFreeGC (dpy, gc);
- x_initialize_pixmap_image_instance (ii, IMAGE_COLOR_PIXMAP);
+ x_initialize_pixmap_image_instance (ii, slices, IMAGE_COLOR_PIXMAP);
IMAGE_INSTANCE_PIXMAP_FILENAME (ii) =
find_keyword_in_vector (instantiator, Q_file);
+ /* Fixup a set of pixmaps. */
IMAGE_INSTANCE_X_PIXMAP (ii) = pixmap;
- IMAGE_INSTANCE_X_MASK (ii) = 0;
+
+ IMAGE_INSTANCE_PIXMAP_MASK (ii) = 0;
IMAGE_INSTANCE_PIXMAP_WIDTH (ii) = ximage->width;
IMAGE_INSTANCE_PIXMAP_HEIGHT (ii) = ximage->height;
IMAGE_INSTANCE_PIXMAP_DEPTH (ii) = ximage->depth;
}
static void
+image_instance_add_x_image (struct Lisp_Image_Instance *ii,
+ XImage *ximage,
+ int slice,
+ Lisp_Object instantiator)
+{
+ Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
+ Display *dpy;
+ GC gc;
+ Drawable d;
+ Pixmap pixmap;
+
+ dpy = DEVICE_X_DISPLAY (XDEVICE (device));
+ d = XtWindow(DEVICE_XT_APP_SHELL (XDEVICE (device)));
+
+ pixmap = XCreatePixmap (dpy, d, ximage->width,
+ ximage->height, ximage->depth);
+ if (!pixmap)
+ signal_simple_error ("Unable to create pixmap", instantiator);
+
+ gc = XCreateGC (dpy, pixmap, 0, NULL);
+ if (!gc)
+ {
+ XFreePixmap (dpy, pixmap);
+ signal_simple_error ("Unable to create GC", instantiator);
+ }
+
+ XPutImage (dpy, pixmap, gc, ximage, 0, 0, 0, 0,
+ ximage->width, ximage->height);
+
+ XFreeGC (dpy, gc);
+
+ IMAGE_INSTANCE_X_PIXMAP_SLICE (ii, slice) = pixmap;
+}
+
+static void
x_init_image_instance_from_eimage (struct Lisp_Image_Instance *ii,
int width, int height,
+ int slices,
unsigned char *eimage,
int dest_mask,
Lisp_Object instantiator,
Colormap cmap = DEVICE_X_COLORMAP (XDEVICE(device));
unsigned long *pixtbl = NULL;
int npixels = 0;
+ int slice;
XImage* ximage;
- ximage = convert_EImage_to_XImage (device, width, height, eimage,
- &pixtbl, &npixels);
- if (!ximage)
+ for (slice = 0; slice < slices; slice++)
{
- if (pixtbl) xfree (pixtbl);
- signal_image_error("EImage to XImage conversion failed", instantiator);
- }
+ ximage = convert_EImage_to_XImage (device, width, height,
+ eimage + (width * height * 3 * slice),
+ &pixtbl, &npixels);
+ if (!ximage)
+ {
+ if (pixtbl) xfree (pixtbl);
+ signal_image_error("EImage to XImage conversion failed", instantiator);
+ }
- /* Now create the pixmap and set up the image instance */
- init_image_instance_from_x_image (ii, ximage, dest_mask,
- cmap, pixtbl, npixels,
- instantiator);
+ /* Now create the pixmap and set up the image instance */
+ if (slice == 0)
+ init_image_instance_from_x_image (ii, ximage, dest_mask,
+ cmap, pixtbl, npixels, slices,
+ instantiator);
+ else
+ image_instance_add_x_image (ii, ximage, slice, instantiator);
- if (ximage)
- {
- if (ximage->data)
- {
- xfree (ximage->data);
- ximage->data = 0;
- }
- XDestroyImage (ximage);
+ if (ximage)
+ {
+ if (ximage->data)
+ {
+ xfree (ximage->data);
+ ximage->data = 0;
+ }
+ XDestroyImage (ximage);
+ ximage = 0;
+ }
}
}
IMAGE_MONO_PIXMAP_MASK | IMAGE_COLOR_PIXMAP_MASK
| IMAGE_POINTER_MASK);
- x_initialize_pixmap_image_instance (ii, type);
+ x_initialize_pixmap_image_instance (ii, 1, type);
IMAGE_INSTANCE_PIXMAP_WIDTH (ii) = width;
IMAGE_INSTANCE_PIXMAP_HEIGHT (ii) = height;
IMAGE_INSTANCE_PIXMAP_FILENAME (ii) =
visual = DEVICE_X_VISUAL (XDEVICE(device));
#endif
- x_initialize_pixmap_image_instance (ii, type);
+ x_initialize_pixmap_image_instance (ii, 1, type);
assert (!NILP (data));
pixels = NULL;
IMAGE_INSTANCE_X_PIXMAP (ii) = pixmap;
- IMAGE_INSTANCE_X_MASK (ii) = mask;
+ IMAGE_INSTANCE_PIXMAP_MASK (ii) = (void*)mask;
IMAGE_INSTANCE_X_COLORMAP (ii) = cmap;
IMAGE_INSTANCE_X_PIXELS (ii) = pixels;
IMAGE_INSTANCE_X_NPIXELS (ii) = npixels;
/* #### call XQueryTextExtents() and check_pointer_sizes() here. */
- x_initialize_pixmap_image_instance (ii, IMAGE_POINTER);
+ x_initialize_pixmap_image_instance (ii, 1, IMAGE_POINTER);
IMAGE_INSTANCE_X_CURSOR (ii) =
XCreateGlyphCursor (dpy, source, mask, source_char, mask_char,
&fg, &bg);
if ((i = XmuCursorNameToIndex (name_ext)) == -1)
signal_simple_error ("Unrecognized cursor-font name", data);
- x_initialize_pixmap_image_instance (ii, IMAGE_POINTER);
+ x_initialize_pixmap_image_instance (ii, 1, IMAGE_POINTER);
IMAGE_INSTANCE_X_CURSOR (ii) = XCreateFontCursor (dpy, i);
foreground = find_keyword_in_vector (instantiator, Q_foreground);
if (NILP (foreground))
IMAGE_INSTANCE_TYPE (p) = IMAGE_COLOR_PIXMAP;
/* Make sure there aren't two pointers to the same mask, causing
it to get freed twice. */
- IMAGE_INSTANCE_X_MASK (p) = 0;
+ IMAGE_INSTANCE_PIXMAP_MASK (p) = 0;
break;
default:
if (IMAGE_INSTANCE_TYPE (p) == IMAGE_SUBWINDOW)
{
XUnmapWindow
- (DisplayOfScreen (IMAGE_INSTANCE_X_SUBWINDOW_SCREEN (p)),
- IMAGE_INSTANCE_X_SUBWINDOW_ID (p));
+ (IMAGE_INSTANCE_X_SUBWINDOW_DISPLAY (p),
+ IMAGE_INSTANCE_X_CLIPWINDOW (p));
}
else /* must be a widget */
{
- XtUnmapWidget (IMAGE_INSTANCE_X_WIDGET_ID (p));
+ XtUnmapWidget (IMAGE_INSTANCE_X_CLIPWIDGET (p));
}
}
/* map the subwindow. This is used by redisplay via
redisplay_output_subwindow */
static void
-x_map_subwindow (struct Lisp_Image_Instance *p, int x, int y)
+x_map_subwindow (struct Lisp_Image_Instance *p, int x, int y,
+ struct display_glyph_area* dga)
{
if (IMAGE_INSTANCE_TYPE (p) == IMAGE_SUBWINDOW)
{
Window subwindow = IMAGE_INSTANCE_X_SUBWINDOW_ID (p);
- Screen* screen = IMAGE_INSTANCE_X_SUBWINDOW_SCREEN (p);
- XMapWindow (DisplayOfScreen (screen), subwindow);
- XMoveWindow (DisplayOfScreen (screen), subwindow, x, y);
+ XMoveResizeWindow (IMAGE_INSTANCE_X_SUBWINDOW_DISPLAY (p),
+ IMAGE_INSTANCE_X_CLIPWINDOW (p),
+ x, y, dga->width, dga->height);
+ XMoveWindow (IMAGE_INSTANCE_X_SUBWINDOW_DISPLAY (p),
+ subwindow, -dga->xoffset, -dga->yoffset);
+ XMapWindow (IMAGE_INSTANCE_X_SUBWINDOW_DISPLAY (p),
+ IMAGE_INSTANCE_X_CLIPWINDOW (p));
}
else /* must be a widget */
{
- XtMoveWidget (IMAGE_INSTANCE_X_WIDGET_ID (p),
- x + IMAGE_INSTANCE_X_WIDGET_XOFFSET (p),
- y + IMAGE_INSTANCE_X_WIDGET_YOFFSET (p));
- XtMapWidget (IMAGE_INSTANCE_X_WIDGET_ID (p));
+ XtConfigureWidget (IMAGE_INSTANCE_X_CLIPWIDGET (p),
+ x + IMAGE_INSTANCE_X_WIDGET_XOFFSET (p),
+ y + IMAGE_INSTANCE_X_WIDGET_YOFFSET (p),
+ dga->width, dga->height, 0);
+ XtMoveWidget (IMAGE_INSTANCE_X_WIDGET_ID (p),
+ -dga->xoffset, -dga->yoffset);
+ XtMapWidget (IMAGE_INSTANCE_X_CLIPWIDGET (p));
}
}
static void
x_update_subwindow (struct Lisp_Image_Instance *p)
{
+#ifdef HAVE_WIDGETS
if (IMAGE_INSTANCE_TYPE (p) == IMAGE_WIDGET)
{
- widget_value* wv = xmalloc_widget_value ();
- button_item_to_widget_value (IMAGE_INSTANCE_WIDGET_SINGLE_ITEM (p),
- wv, 1, 1);
+ Arg al[5];
+ widget_value* wv = gui_items_to_widget_values
+ (IMAGE_INSTANCE_WIDGET_ITEMS (p));
+
+ /* This seems ugly, but I'm not sure what else to do. */
+ if (EQ (IMAGE_INSTANCE_WIDGET_TYPE (p), Qtab_control))
+ {
+ widget_value* cur = 0;
+ /* Give each child label the correct foreground color. */
+ Lisp_Object pixel = FACE_FOREGROUND
+ (IMAGE_INSTANCE_WIDGET_FACE (p),
+ IMAGE_INSTANCE_SUBWINDOW_FRAME (p));
+ XColor fcolor = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (pixel));
+ XtSetArg (al [0], XtNtabForeground, fcolor.pixel);
+
+ for (cur = wv->contents; cur; cur = cur->next)
+ {
+ if (cur->value)
+ {
+ cur->nargs = 1;
+ cur->args = al;
+ }
+ }
+ }
+
+ /* now modify the widget */
lw_modify_all_widgets (IMAGE_INSTANCE_X_WIDGET_LWID (p),
- wv, 1);
+ wv, True);
+ free_widget_value_tree (wv);
+ /* update the colors and font */
+ update_widget_face (p, IMAGE_INSTANCE_SUBWINDOW_FRAME (p));
+ /* We have to do this otherwise Motif will unceremoniously
+ resize us when the label gets set. */
+ XtSetArg (al [0], XtNwidth, IMAGE_INSTANCE_WIDGET_WIDTH (p));
+ XtSetArg (al [1], XtNheight, IMAGE_INSTANCE_WIDGET_HEIGHT (p));
+ XtSetValues (IMAGE_INSTANCE_X_WIDGET_ID (p), al, 2);
}
+#endif
}
/* instantiate and x type subwindow */
ii->data = xnew_and_zero (struct x_subwindow_data);
IMAGE_INSTANCE_X_SUBWINDOW_PARENT (ii) = pw;
- IMAGE_INSTANCE_X_SUBWINDOW_SCREEN (ii) = xs;
+ IMAGE_INSTANCE_X_SUBWINDOW_DISPLAY (ii) = DisplayOfScreen (xs);
xswa.backing_store = Always;
valueMask |= CWBackingStore;
xswa.colormap = DefaultColormapOfScreen (xs);
valueMask |= CWColormap;
- win = XCreateWindow (dpy, pw, 0, 0, w, h, 0, CopyFromParent,
+ /* Create a window for clipping */
+ IMAGE_INSTANCE_X_CLIPWINDOW (ii) =
+ XCreateWindow (dpy, pw, 0, 0, w, h, 0, CopyFromParent,
+ InputOutput, CopyFromParent, valueMask,
+ &xswa);
+
+ /* Now put the subwindow inside the clip window. */
+ win = XCreateWindow (dpy, IMAGE_INSTANCE_X_CLIPWINDOW (ii),
+ 0, 0, w, h, 0, CopyFromParent,
InputOutput, CopyFromParent, valueMask,
&xswa);
{
if (IMAGE_INSTANCE_TYPE (ii) == IMAGE_SUBWINDOW)
{
- XResizeWindow (DisplayOfScreen (IMAGE_INSTANCE_X_SUBWINDOW_SCREEN (ii)),
+ XResizeWindow (IMAGE_INSTANCE_X_SUBWINDOW_DISPLAY (ii),
IMAGE_INSTANCE_X_SUBWINDOW_ID (ii),
w, h);
}
else /* must be a widget */
{
Arg al[2];
+
+ if (!XtIsRealized (IMAGE_INSTANCE_X_WIDGET_ID (ii)))
+ {
+ Lisp_Object sw;
+ XSETIMAGE_INSTANCE (sw, ii);
+ signal_simple_error ("XEmacs bug: subwindow is not realized", sw);
+ }
+
XtSetArg (al [0], XtNwidth, (Dimension)w);
XtSetArg (al [1], XtNheight, (Dimension)h);
XtSetValues (IMAGE_INSTANCE_X_WIDGET_ID (ii), al, 2);
}
}
+\f
+#ifdef HAVE_WIDGETS
+
/************************************************************************/
/* widgets */
/************************************************************************/
static void
+update_widget_face (struct Lisp_Image_Instance* ii, Lisp_Object domain)
+{
+ Arg al[3];
+#ifdef LWLIB_WIDGETS_MOTIF
+ XmFontList fontList;
+#endif
+
+ Lisp_Object pixel = FACE_FOREGROUND
+ (IMAGE_INSTANCE_WIDGET_FACE (ii),
+ IMAGE_INSTANCE_SUBWINDOW_FRAME (ii));
+ XColor fcolor = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (pixel));
+ XColor bcolor;
+
+ pixel = FACE_BACKGROUND
+ (IMAGE_INSTANCE_WIDGET_FACE (ii),
+ IMAGE_INSTANCE_SUBWINDOW_FRAME (ii));
+ bcolor = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (pixel));
+
+ XtSetArg (al [0], XtNbackground, bcolor.pixel);
+ XtSetArg (al [1], XtNforeground, fcolor.pixel);
+
+#ifdef LWLIB_WIDGETS_MOTIF
+ fontList = XmFontListCreate
+ (FONT_INSTANCE_X_FONT
+ (XFONT_INSTANCE (widget_face_font_info
+ (domain, IMAGE_INSTANCE_WIDGET_FACE (ii),
+ 0, 0))), XmSTRING_DEFAULT_CHARSET);
+ XtSetArg (al [2], XmNfontList, fontList );
+#else
+ XtSetArg (al [2], XtNfont, (void*)FONT_INSTANCE_X_FONT
+ (XFONT_INSTANCE (widget_face_font_info
+ (domain,
+ IMAGE_INSTANCE_WIDGET_FACE (ii),
+ 0, 0))));
+#endif
+ XtSetValues (IMAGE_INSTANCE_X_WIDGET_ID (ii), al, 3);
+#ifdef LWLIB_WIDGETS_MOTIF
+ XmFontListFree (fontList);
+#endif
+}
+
+static void
x_widget_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
Lisp_Object pointer_fg, Lisp_Object pointer_bg,
int dest_mask, Lisp_Object domain,
struct device* d = XDEVICE (device);
Lisp_Object frame = FW_FRAME (domain);
struct frame* f = XFRAME (frame);
- XColor fcolor, bcolor;
- Extbyte* nm=0;
+ char* nm=0;
Widget wid;
Arg al [32];
int ac = 0;
int id = new_lwlib_id ();
-#ifdef LWLIB_USES_MOTIF
- XmFontList fontList;
-#endif
+ widget_value* clip_wv;
+ XColor fcolor, bcolor;
if (!DEVICE_X_P (d))
- signal_simple_error ("Not an mswindows device", device);
+ signal_simple_error ("Not an X device", device);
/* have to set the type this late in case there is no device
instantiation for a widget. But we can go ahead and do it without
ii->data = xnew_and_zero (struct x_subwindow_data);
+ /* Create a clip window to contain the subwidget. Incredibly the
+ XEmacs manager seems to be the most appropriate widget for
+ this. Nothing else is simple enough and yet does what is
+ required. */
+ clip_wv = xmalloc_widget_value ();
+
+ XtSetArg (al [ac], XtNresize, False); ac++;
+ XtSetArg (al [ac], XtNwidth,
+ (Dimension)IMAGE_INSTANCE_SUBWINDOW_WIDTH (ii)); ac++;
+ XtSetArg (al [ac], XtNheight,
+ (Dimension)IMAGE_INSTANCE_SUBWINDOW_HEIGHT (ii)); ac++;
+
+ clip_wv->enabled = True;
+ clip_wv->nargs = ac;
+ clip_wv->args = al;
+ clip_wv->name = xstrdup ("clip-window");
+ clip_wv->value = xstrdup ("clip-window");
+
+ IMAGE_INSTANCE_X_CLIPWIDGET (ii)
+ = lw_create_widget ("clip-window", "clip-window", new_lwlib_id (),
+ clip_wv, FRAME_X_CONTAINER_WIDGET (f),
+ False, 0, 0, 0);
+
+ free_widget_value_tree (clip_wv);
+
/* copy any args we were given */
+ ac = 0;
+
if (wv->nargs)
lw_add_value_args_to_args (wv, al, &ac);
- /* add our own arguments */
+ /* Fixup the colors. We have to do this *before* the widget gets
+ created so that Motif will fix up the shadow colors
+ correctly. Once the widget is created Motif won't do this
+ anymore...*/
pixel = FACE_FOREGROUND
(IMAGE_INSTANCE_WIDGET_FACE (ii),
IMAGE_INSTANCE_SUBWINDOW_FRAME (ii));
fcolor = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (pixel));
+
pixel = FACE_BACKGROUND
(IMAGE_INSTANCE_WIDGET_FACE (ii),
IMAGE_INSTANCE_SUBWINDOW_FRAME (ii));
XtSetArg (al [ac], XtNbackground, bcolor.pixel); ac++;
XtSetArg (al [ac], XtNforeground, fcolor.pixel); ac++;
-#ifdef LWLIB_USES_MOTIF
- fontList = XmFontListCreate
- ((void*)FONT_INSTANCE_X_FONT
- (XFONT_INSTANCE (widget_face_font_info
- (domain, IMAGE_INSTANCE_WIDGET_FACE (ii),
- 0, 0))), XmSTRING_DEFAULT_CHARSET);
- XtSetArg (al [ac], XmNfontList, fontList ); ac++;
-#else
- XtSetArg (al [ac], XtNfont, (void*)FONT_INSTANCE_X_FONT
- (XFONT_INSTANCE (widget_face_font_info
- (domain,
- IMAGE_INSTANCE_WIDGET_FACE (ii),
- 0, 0)))); ac++;
-#endif
+ /* we cannot allow widgets to resize themselves */
+ XtSetArg (al [ac], XtNresize, False); ac++;
+ XtSetArg (al [ac], XtNwidth,
+ (Dimension)IMAGE_INSTANCE_SUBWINDOW_WIDTH (ii)); ac++;
+ XtSetArg (al [ac], XtNheight,
+ (Dimension)IMAGE_INSTANCE_SUBWINDOW_HEIGHT (ii)); ac++;
wv->nargs = ac;
wv->args = al;
-
- wid = lw_create_widget (type, wv->name, id, wv, FRAME_X_CONTAINER_WIDGET (f),
+
+ wid = lw_create_widget (type, wv->name, id, wv, IMAGE_INSTANCE_X_CLIPWIDGET (ii),
False, 0, popup_selection_callback, 0);
+ IMAGE_INSTANCE_SUBWINDOW_ID (ii) = (void*)wid;
IMAGE_INSTANCE_X_WIDGET_LWID (ii) = id;
-#ifdef LWLIB_USES_MOTIF
- XmFontListFree (fontList);
-#endif
- /* because the EmacsManager is the widgets parent we have to
- offset the redisplay of the widget by the amount the text
- widget is inside the manager. */
+
+ /* update the font. */
+ update_widget_face (ii, domain);
+
+ /* Resize the widget here so that the values do not get copied by
+ lwlib. */
ac = 0;
XtSetArg (al [ac], XtNwidth,
(Dimension)IMAGE_INSTANCE_SUBWINDOW_WIDTH (ii)); ac++;
XtSetArg (al [ac], XtNheight,
(Dimension)IMAGE_INSTANCE_SUBWINDOW_HEIGHT (ii)); ac++;
- XtSetValues (wid, al, ac);
- /* finally get offsets in the frame */
+ XtSetValues (IMAGE_INSTANCE_X_WIDGET_ID (ii), al, ac);
+ /* because the EmacsManager is the widgets parent we have to
+ offset the redisplay of the widget by the amount the text
+ widget is inside the manager. */
ac = 0;
XtSetArg (al [ac], XtNx, &IMAGE_INSTANCE_X_WIDGET_XOFFSET (ii)); ac++;
XtSetArg (al [ac], XtNy, &IMAGE_INSTANCE_X_WIDGET_YOFFSET (ii)); ac++;
XtGetValues (FRAME_X_TEXT_WIDGET (f), al, ac);
- IMAGE_INSTANCE_SUBWINDOW_ID (ii) = (void*)wid;
+ XtMapWidget (wid);
- free_widget_value (wv);
+ free_widget_value_tree (wv);
}
static Lisp_Object
if (EQ (prop, Q_text))
{
- Extbyte* str=0;
+ char* str;
widget_value* wv = lw_get_all_values (IMAGE_INSTANCE_X_WIDGET_LWID (ii));
CHECK_STRING (val);
GET_C_STRING_OS_DATA_ALLOCA (val, str);
lw_modify_all_widgets (IMAGE_INSTANCE_X_WIDGET_LWID (ii), wv, False);
return Qt;
}
+ /* Modify the face properties of the widget */
+ if (EQ (prop, Q_face))
+ {
+ update_widget_face (ii, IMAGE_INSTANCE_SUBWINDOW_FRAME (ii));
+ return Qt;
+ }
return Qunbound;
}
{
Arg al [2];
int ac =0;
-#ifdef LWLIB_USES_MOTIF
+#ifdef LWLIB_WIDGETS_MOTIF
XtSetArg (al [ac], XmNlabelType, XmPIXMAP); ac++;
XtSetArg (al [ac], XmNlabelPixmap, XIMAGE_INSTANCE_X_PIXMAP (glyph));ac++;
#else
pointer_bg, dest_mask, domain, "text-field", wv);
}
+#if defined (LWLIB_WIDGETS_MOTIF) && XmVERSION > 1
/* instantiate a combo control */
static void
x_combo_box_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
int dest_mask, Lisp_Object domain)
{
struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
- Lisp_Object rest;
- Lisp_Object gui = IMAGE_INSTANCE_WIDGET_ITEM (ii);
- widget_value* wv = xmalloc_widget_value ();
+ widget_value * wv = 0;
+ /* This is not done generically because of sizing problems under
+ mswindows. */
+ widget_instantiate_1 (image_instance, instantiator, pointer_fg,
+ pointer_bg, dest_mask, domain, 1, 0, 0);
- button_item_to_widget_value (gui, wv, 1, 1);
+ wv = gui_items_to_widget_values (IMAGE_INSTANCE_WIDGET_ITEMS (ii));
x_widget_instantiate (image_instance, instantiator, pointer_fg,
pointer_bg, dest_mask, domain, "combo-box", wv);
- /* add items to the combo box */
- LIST_LOOP (rest, Fplist_get (IMAGE_INSTANCE_WIDGET_PROPS (ii), Q_items, Qnil))
- {
-#if 0
- Extbyte* str;
- XmString xmstr;
- GET_C_STRING_OS_DATA_ALLOCA (XCAR (rest), str);
- xmstr = XmStringCreate (str, XmSTRING_DEFAULT_CHARSET);
- XmListAddItem (IMAGE_INSTANCE_X_WIDGET_ID (ii), xmstr, 0);
- XmStringFree (xmstr);
+}
#endif
+
+static void
+x_tab_control_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
+ Lisp_Object pointer_fg, Lisp_Object pointer_bg,
+ int dest_mask, Lisp_Object domain)
+{
+ struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
+ Arg al [1];
+ XColor fcolor;
+ Lisp_Object pixel;
+ widget_value* cur;
+
+ widget_value * wv =
+ gui_items_to_widget_values (IMAGE_INSTANCE_WIDGET_ITEMS (ii));
+
+ /* Give each child label the correct foreground color. */
+ pixel = FACE_FOREGROUND
+ (IMAGE_INSTANCE_WIDGET_FACE (ii),
+ IMAGE_INSTANCE_SUBWINDOW_FRAME (ii));
+ fcolor = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (pixel));
+ XtSetArg (al [0], XtNtabForeground, fcolor.pixel);
+
+ for (cur = wv->contents; cur; cur = cur->next)
+ {
+ if (cur->value)
+ {
+ cur->nargs = 1;
+ cur->args = al;
+ }
}
+
+ x_widget_instantiate (image_instance, instantiator, pointer_fg,
+ pointer_bg, dest_mask, domain, "tab-control", wv);
+}
+
+/* set the properties of a tab control */
+static Lisp_Object
+x_tab_control_set_property (Lisp_Object image_instance, Lisp_Object prop,
+ Lisp_Object val)
+{
+ struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
+
+ if (EQ (prop, Q_items))
+ {
+ widget_value * wv = 0, *cur;
+ Arg al [1];
+ XColor fcolor;
+ Lisp_Object pixel;
+
+ check_valid_item_list_1 (val);
+
+ IMAGE_INSTANCE_WIDGET_ITEMS (ii) =
+ Fcons (XCAR (IMAGE_INSTANCE_WIDGET_ITEMS (ii)),
+ parse_gui_item_tree_children (val));
+
+ wv = gui_items_to_widget_values (IMAGE_INSTANCE_WIDGET_ITEMS (ii));
+
+ /* Give each child label the correct foreground color. */
+ pixel = FACE_FOREGROUND
+ (IMAGE_INSTANCE_WIDGET_FACE (ii),
+ IMAGE_INSTANCE_SUBWINDOW_FRAME (ii));
+ fcolor = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (pixel));
+ XtSetArg (al [0], XtNtabForeground, fcolor.pixel);
+
+ for (cur = wv->contents; cur; cur = cur->next)
+ {
+ if (cur->value)
+ {
+ cur->nargs = 1;
+ cur->args = al;
+ }
+ }
+
+ lw_modify_all_widgets (IMAGE_INSTANCE_X_WIDGET_LWID (ii), wv, True);
+
+ free_widget_value_tree (wv);
+ return Qt;
+ }
+
+ return Qunbound;
+}
+
+/* instantiate a static control possible for putting other things in */
+static void
+x_label_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
+ Lisp_Object pointer_fg, Lisp_Object pointer_bg,
+ int dest_mask, Lisp_Object domain)
+{
+ struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
+ Lisp_Object gui = IMAGE_INSTANCE_WIDGET_ITEM (ii);
+ widget_value* wv = xmalloc_widget_value ();
+
+ button_item_to_widget_value (gui, wv, 1, 1);
+
+ x_widget_instantiate (image_instance, instantiator, pointer_fg,
+ pointer_bg, dest_mask, domain, "button", wv);
}
+#endif /* HAVE_WIDGETS */
\f
/************************************************************************/
{
IIFORMAT_VALID_CONSOLE (x, nothing);
IIFORMAT_VALID_CONSOLE (x, string);
+ IIFORMAT_VALID_CONSOLE (x, layout);
IIFORMAT_VALID_CONSOLE (x, formatted_string);
IIFORMAT_VALID_CONSOLE (x, inherit);
#ifdef HAVE_XPM
INITIALIZE_DEVICE_IIFORMAT (x, subwindow);
IIFORMAT_HAS_DEVMETHOD (x, subwindow, instantiate);
-#ifdef LWLIB_USES_MOTIF
+#ifdef HAVE_WIDGETS
/* button widget */
INITIALIZE_DEVICE_IIFORMAT (x, button);
IIFORMAT_HAS_DEVMETHOD (x, button, property);
/* text field */
INITIALIZE_DEVICE_IIFORMAT (x, edit_field);
IIFORMAT_HAS_DEVMETHOD (x, edit_field, instantiate);
-#if 0 /* XmVERSION > 1*/
+#if defined (LWLIB_WIDGETS_MOTIF) && XmVERSION > 1
/* combo box */
INITIALIZE_DEVICE_IIFORMAT (x, combo_box);
IIFORMAT_HAS_DEVMETHOD (x, combo_box, instantiate);
+ IIFORMAT_HAS_SHARED_DEVMETHOD (x, combo_box, set_property, tab_control);
#endif
+ /* tab control widget */
+ INITIALIZE_DEVICE_IIFORMAT (x, tab_control);
+ IIFORMAT_HAS_DEVMETHOD (x, tab_control, instantiate);
+ IIFORMAT_HAS_DEVMETHOD (x, tab_control, set_property);
+ /* label */
+ INITIALIZE_DEVICE_IIFORMAT (x, label);
+ IIFORMAT_HAS_DEVMETHOD (x, label, instantiate);
#endif
INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (cursor_font, "cursor-font");
IIFORMAT_VALID_CONSOLE (x, cursor_font);
struct x_image_instance_data
{
- Pixmap pixmap;
- Pixmap mask;
+ Pixmap* pixmaps;
Cursor cursor;
/* If depth>0, then that means that other colors were allocated when
#define X_IMAGE_INSTANCE_DATA(i) ((struct x_image_instance_data *) (i)->data)
-#define IMAGE_INSTANCE_X_PIXMAP(i) (X_IMAGE_INSTANCE_DATA (i)->pixmap)
-#define IMAGE_INSTANCE_X_MASK(i) (X_IMAGE_INSTANCE_DATA (i)->mask)
+#define IMAGE_INSTANCE_X_PIXMAP(i) (X_IMAGE_INSTANCE_DATA (i)->pixmaps[0])
+#define IMAGE_INSTANCE_X_PIXMAP_SLICE(i,slice) \
+ (X_IMAGE_INSTANCE_DATA (i)->pixmaps[slice])
+#define IMAGE_INSTANCE_X_PIXMAP_SLICES(i) \
+ (X_IMAGE_INSTANCE_DATA (i)->pixmaps)
+#define IMAGE_INSTANCE_X_MASK(i) \
+ (Pixmap)(IMAGE_INSTANCE_PIXMAP_MASK (i))
#define IMAGE_INSTANCE_X_CURSOR(i) (X_IMAGE_INSTANCE_DATA (i)->cursor)
#define IMAGE_INSTANCE_X_COLORMAP(i) (X_IMAGE_INSTANCE_DATA (i)->colormap)
#define IMAGE_INSTANCE_X_PIXELS(i) (X_IMAGE_INSTANCE_DATA (i)->pixels)
#define XIMAGE_INSTANCE_X_PIXMAP(i) \
IMAGE_INSTANCE_X_PIXMAP (XIMAGE_INSTANCE (i))
+#define XIMAGE_INSTANCE_X_PIXMAP_SLICES(i) \
+ IMAGE_INSTANCE_X_PIXMAP_SLICES (XIMAGE_INSTANCE (i))
+#define XIMAGE_INSTANCE_X_PIXMAP_SLICE(i) \
+ IMAGE_INSTANCE_X_PIXMAP_SLICE (XIMAGE_INSTANCE (i))
#define XIMAGE_INSTANCE_X_MASK(i) \
IMAGE_INSTANCE_X_MASK (XIMAGE_INSTANCE (i))
#define XIMAGE_INSTANCE_X_CURSOR(i) \
{
struct
{
- Screen *xscreen;
+ Display *display;
Window parent_window;
+ Window clip_window;
} sub;
struct
{
+ Widget clip_window;
Position x_offset;
Position y_offset;
LWLIB_ID id;
#define X_SUBWINDOW_INSTANCE_DATA(i) ((struct x_subwindow_data *) (i)->data)
-#define IMAGE_INSTANCE_X_SUBWINDOW_SCREEN(i) \
- (X_SUBWINDOW_INSTANCE_DATA (i)->data.sub.xscreen)
+#define IMAGE_INSTANCE_X_SUBWINDOW_DISPLAY(i) \
+ (X_SUBWINDOW_INSTANCE_DATA (i)->data.sub.display)
#define IMAGE_INSTANCE_X_SUBWINDOW_PARENT(i) \
(X_SUBWINDOW_INSTANCE_DATA (i)->data.sub.parent_window)
+#define IMAGE_INSTANCE_X_CLIPWINDOW(i) \
+ (X_SUBWINDOW_INSTANCE_DATA (i)->data.sub.clip_window)
#define IMAGE_INSTANCE_X_WIDGET_XOFFSET(i) \
(X_SUBWINDOW_INSTANCE_DATA (i)->data.wid.x_offset)
#define IMAGE_INSTANCE_X_WIDGET_YOFFSET(i) \
(X_SUBWINDOW_INSTANCE_DATA (i)->data.wid.y_offset)
#define IMAGE_INSTANCE_X_WIDGET_LWID(i) \
(X_SUBWINDOW_INSTANCE_DATA (i)->data.wid.id)
+#define IMAGE_INSTANCE_X_CLIPWIDGET(i) \
+ (X_SUBWINDOW_INSTANCE_DATA (i)->data.wid.clip_window)
#define XIMAGE_INSTANCE_X_SUBWINDOW_PARENT(i) \
IMAGE_INSTANCE_X_SUBWINDOW_PARENT (XIMAGE_INSTANCE (i))
-#define XIMAGE_INSTANCE_X_SUBWINDOW_SCREEN(i) \
- IMAGE_INSTANCE_X_SUBWINDOW_SCREEN (XIMAGE_INSTANCE (i))
+#define XIMAGE_INSTANCE_X_SUBWINDOW_DISPLAY(i) \
+ IMAGE_INSTANCE_X_SUBWINDOW_DISPLAY (XIMAGE_INSTANCE (i))
#define XIMAGE_INSTANCE_X_WIDGET_XOFFSET(i) \
IMAGE_INSTANCE_X_WIDGET_XOFFSET (XIMAGE_INSTANCE (i))
#define XIMAGE_INSTANCE_X_WIDGET_YOFFSET(i) \
IMAGE_INSTANCE_X_WIDGET_YOFFSET (XIMAGE_INSTANCE (i))
#define XIMAGE_INSTANCE_X_WIDGET_LWID(i) \
IMAGE_INSTANCE_X_WIDGET_LWID (XIMAGE_INSTANCE (i))
+#define XIMAGE_INSTANCE_X_CLIPWIDGET(i) \
+ IMAGE_INSTANCE_X_CLIPWIDGET (XIMAGE_INSTANCE (i))
+#define XIMAGE_INSTANCE_X_CLIPWINDOW(i) \
+ IMAGE_INSTANCE_X_CLIPWINDOW (XIMAGE_INSTANCE (i))
#define IMAGE_INSTANCE_X_SUBWINDOW_ID(i) \
((Window) IMAGE_INSTANCE_SUBWINDOW_ID (i))
#define IMAGE_INSTANCE_X_WIDGET_ID(i) \
Copyright (C) 1995 Tinker Systems
Copyright (C) 1995, 1996 Ben Wing
Copyright (C) 1995 Sun Microsystems
- Copyright (C) 1998 Andy Piper
+ Copyright (C) 1998, 1999 Andy Piper
This file is part of XEmacs.
/* Synched up with: Not in FSF. */
-/* Written by Ben Wing and Chuck Thompson */
+/* Written by Ben Wing and Chuck Thompson. */
#include <config.h>
#include "lisp.h"
#include "frame.h"
#include "chartab.h"
#include "rangetab.h"
+#include "blocktype.h"
#ifdef HAVE_XPM
#include <X11/xpm.h>
Lisp_Object Qcolor_pixmap_image_instance_p;
Lisp_Object Qpointer_image_instance_p;
Lisp_Object Qsubwindow_image_instance_p;
+Lisp_Object Qlayout_image_instance_p;
Lisp_Object Qwidget_image_instance_p;
Lisp_Object Qconst_glyph_variable;
Lisp_Object Qmono_pixmap, Qcolor_pixmap, Qsubwindow;
Lisp_Object Vimage_instance_type_list;
Lisp_Object Vglyph_type_list;
+int disable_animated_pixmaps;
+
DEFINE_IMAGE_INSTANTIATOR_FORMAT (nothing);
DEFINE_IMAGE_INSTANTIATOR_FORMAT (inherit);
DEFINE_IMAGE_INSTANTIATOR_FORMAT (string);
DEFINE_IMAGE_INSTANTIATOR_FORMAT (formatted_string);
DEFINE_IMAGE_INSTANTIATOR_FORMAT (subwindow);
+DEFINE_IMAGE_INSTANTIATOR_FORMAT (text);
#ifdef HAVE_WINDOW_SYSTEM
DEFINE_IMAGE_INSTANTIATOR_FORMAT (xbm);
static void glyph_property_was_changed (Lisp_Object glyph,
Lisp_Object property,
Lisp_Object locale);
+static void register_ignored_expose (struct frame* f, int x, int y, int width, int height);
+/* Unfortunately windows and X are different. In windows BeginPaint()
+ will prevent WM_PAINT messages being generated so it is unnecessary
+ to register exposures as they will not occur. Under X they will
+ always occur. */
+int hold_ignored_expose_registration;
+
EXFUN (Fimage_instance_type, 1);
EXFUN (Fglyph_type, 1);
int i;
struct image_instantiator_methods* meths =
decode_image_instantiator_format (format, ERROR_ME_NOT);
- struct console* console = decode_console (locale);
- Lisp_Object contype = console ? CONSOLE_TYPE (console) : locale;
+ Lisp_Object contype = Qnil;
+ /* mess with the locale */
+ if (!NILP (locale) && SYMBOLP (locale))
+ contype = locale;
+ else
+ {
+ struct console* console = decode_console (locale);
+ contype = console ? CONSOLE_TYPE (console) : locale;
+ }
/* nothing is valid in all locales */
if (EQ (format, Qnothing))
return 1;
/* reject unknown formats */
- else if (!console || !meths)
+ else if (NILP (contype) || !meths)
return 0;
for (i = 0; i < Dynarr_length (meths->consoles); i++)
Lisp_Object Qimage_instancep;
static Lisp_Object
-mark_image_instance (Lisp_Object obj, void (*markobj) (Lisp_Object))
+mark_image_instance (Lisp_Object obj)
{
struct Lisp_Image_Instance *i = XIMAGE_INSTANCE (obj);
- markobj (i->name);
+ mark_object (i->name);
switch (IMAGE_INSTANCE_TYPE (i))
{
case IMAGE_TEXT:
- markobj (IMAGE_INSTANCE_TEXT_STRING (i));
+ mark_object (IMAGE_INSTANCE_TEXT_STRING (i));
break;
case IMAGE_MONO_PIXMAP:
case IMAGE_COLOR_PIXMAP:
- markobj (IMAGE_INSTANCE_PIXMAP_FILENAME (i));
- markobj (IMAGE_INSTANCE_PIXMAP_MASK_FILENAME (i));
- markobj (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (i));
- markobj (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (i));
- markobj (IMAGE_INSTANCE_PIXMAP_FG (i));
- markobj (IMAGE_INSTANCE_PIXMAP_BG (i));
+ mark_object (IMAGE_INSTANCE_PIXMAP_FILENAME (i));
+ mark_object (IMAGE_INSTANCE_PIXMAP_MASK_FILENAME (i));
+ mark_object (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (i));
+ mark_object (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (i));
+ mark_object (IMAGE_INSTANCE_PIXMAP_FG (i));
+ mark_object (IMAGE_INSTANCE_PIXMAP_BG (i));
break;
case IMAGE_WIDGET:
- markobj (IMAGE_INSTANCE_WIDGET_TYPE (i));
- markobj (IMAGE_INSTANCE_WIDGET_PROPS (i));
- markobj (IMAGE_INSTANCE_WIDGET_FACE (i));
- markobj (IMAGE_INSTANCE_WIDGET_ITEM (i));
+ mark_object (IMAGE_INSTANCE_WIDGET_TYPE (i));
+ mark_object (IMAGE_INSTANCE_WIDGET_PROPS (i));
+ mark_object (IMAGE_INSTANCE_WIDGET_FACE (i));
+ mark_object (IMAGE_INSTANCE_WIDGET_ITEMS (i));
case IMAGE_SUBWINDOW:
- markobj (IMAGE_INSTANCE_SUBWINDOW_FRAME (i));
+ mark_object (IMAGE_INSTANCE_SUBWINDOW_FRAME (i));
+ break;
+
+ case IMAGE_LAYOUT:
+ mark_object (IMAGE_INSTANCE_LAYOUT_CHILDREN (i));
+ mark_object (IMAGE_INSTANCE_LAYOUT_BORDER (i));
+ mark_object (IMAGE_INSTANCE_SUBWINDOW_FRAME (i));
break;
default:
break;
}
- MAYBE_DEVMETH (XDEVICE (i->device), mark_image_instance, (i, markobj));
+ MAYBE_DEVMETH (XDEVICE (i->device), mark_image_instance, (i));
return i->device;
}
print_internal (IMAGE_INSTANCE_WIDGET_TEXT (ii), printcharfun, 0);
case IMAGE_SUBWINDOW:
+ case IMAGE_LAYOUT:
sprintf (buf, " %dx%d", IMAGE_INSTANCE_SUBWINDOW_WIDTH (ii),
IMAGE_INSTANCE_SUBWINDOW_HEIGHT (ii));
write_c_string (buf, printcharfun);
||
IMAGE_INSTANCE_TYPE (i) == IMAGE_SUBWINDOW)
{
- MARK_FRAME_GLYPHS_CHANGED
+ MARK_FRAME_SUBWINDOWS_CHANGED
(XFRAME (IMAGE_INSTANCE_SUBWINDOW_FRAME (i)));
}
IMAGE_INSTANCE_PIXMAP_HEIGHT (i2) &&
IMAGE_INSTANCE_PIXMAP_DEPTH (i1) ==
IMAGE_INSTANCE_PIXMAP_DEPTH (i2) &&
+ IMAGE_INSTANCE_PIXMAP_SLICE (i1) ==
+ IMAGE_INSTANCE_PIXMAP_SLICE (i2) &&
EQ (IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (i1),
IMAGE_INSTANCE_PIXMAP_HOTSPOT_X (i2)) &&
EQ (IMAGE_INSTANCE_PIXMAP_HOTSPOT_Y (i1),
case IMAGE_WIDGET:
if (!(EQ (IMAGE_INSTANCE_WIDGET_TYPE (i1),
IMAGE_INSTANCE_WIDGET_TYPE (i2))
- && internal_equal (IMAGE_INSTANCE_WIDGET_ITEM (i1),
- IMAGE_INSTANCE_WIDGET_ITEM (i2),
+ && internal_equal (IMAGE_INSTANCE_WIDGET_ITEMS (i1),
+ IMAGE_INSTANCE_WIDGET_ITEMS (i2),
depth + 1)
&& internal_equal (IMAGE_INSTANCE_WIDGET_PROPS (i1),
IMAGE_INSTANCE_WIDGET_PROPS (i2),
depth + 1)
))
return 0;
+ case IMAGE_LAYOUT:
+ if (IMAGE_INSTANCE_TYPE (i1) == IMAGE_LAYOUT
+ &&
+ !(EQ (IMAGE_INSTANCE_LAYOUT_BORDER (i1),
+ IMAGE_INSTANCE_LAYOUT_BORDER (i2))
+ &&
+ internal_equal (IMAGE_INSTANCE_LAYOUT_CHILDREN (i1),
+ IMAGE_INSTANCE_LAYOUT_CHILDREN (i2),
+ depth + 1)))
+ return 0;
case IMAGE_SUBWINDOW:
if (!(IMAGE_INSTANCE_SUBWINDOW_WIDTH (i1) ==
IMAGE_INSTANCE_SUBWINDOW_WIDTH (i2) &&
case IMAGE_MONO_PIXMAP:
case IMAGE_COLOR_PIXMAP:
case IMAGE_POINTER:
- hash = HASH5 (hash, IMAGE_INSTANCE_PIXMAP_WIDTH (i),
+ hash = HASH6 (hash, IMAGE_INSTANCE_PIXMAP_WIDTH (i),
IMAGE_INSTANCE_PIXMAP_HEIGHT (i),
IMAGE_INSTANCE_PIXMAP_DEPTH (i),
+ IMAGE_INSTANCE_PIXMAP_SLICE (i),
internal_hash (IMAGE_INSTANCE_PIXMAP_FILENAME (i),
depth + 1));
break;
hash = HASH4 (hash,
internal_hash (IMAGE_INSTANCE_WIDGET_TYPE (i), depth + 1),
internal_hash (IMAGE_INSTANCE_WIDGET_PROPS (i), depth + 1),
- internal_hash (IMAGE_INSTANCE_WIDGET_ITEM (i), depth + 1));
+ internal_hash (IMAGE_INSTANCE_WIDGET_ITEMS (i), depth + 1));
+ case IMAGE_LAYOUT:
+ if (IMAGE_INSTANCE_TYPE (i) == IMAGE_LAYOUT)
+ hash = HASH3 (hash,
+ internal_hash (IMAGE_INSTANCE_LAYOUT_BORDER (i), depth + 1),
+ internal_hash (IMAGE_INSTANCE_LAYOUT_CHILDREN (i),
+ depth + 1));
case IMAGE_SUBWINDOW:
hash = HASH4 (hash, IMAGE_INSTANCE_SUBWINDOW_WIDTH (i),
IMAGE_INSTANCE_SUBWINDOW_HEIGHT (i),
lp->device = device;
lp->type = IMAGE_NOTHING;
lp->name = Qnil;
+ lp->x_offset = 0;
+ lp->y_offset = 0;
XSETIMAGE_INSTANCE (val, lp);
return val;
}
if (EQ (type, Qpointer)) return IMAGE_POINTER;
if (EQ (type, Qsubwindow)) return IMAGE_SUBWINDOW;
if (EQ (type, Qwidget)) return IMAGE_WIDGET;
+ if (EQ (type, Qlayout)) return IMAGE_LAYOUT;
maybe_signal_simple_error ("Invalid image-instance type", type,
Qimage, errb);
case IMAGE_POINTER: return Qpointer;
case IMAGE_SUBWINDOW: return Qsubwindow;
case IMAGE_WIDGET: return Qwidget;
+ case IMAGE_LAYOUT: return Qlayout;
default:
abort ();
}
{
/* This depends on the fact that enums are assigned consecutive
integers starting at 0. (Remember that IMAGE_UNKNOWN is the
- first enum.) I'm fairly sure this behavior in ANSI-mandated,
+ first enum.) I'm fairly sure this behavior is ANSI-mandated,
so there should be no portability problems here. */
return (1 << ((int) (type) - 1));
}
'subwindow
A child window that is treated as an image. This allows (e.g.)
another program to be responsible for drawing into the window.
- Not currently implemented.
+'widget
+ A child window that contains a window-system widget, e.g. a push
+ button.
The DEST-TYPES list is unordered. If multiple destination types
are possible for a given instantiator, the "most natural" type
NO-ERROR controls what happens when the image cannot be generated.
If nil, an error message is generated. If t, no messages are
generated and this function returns nil. If anything else, a warning
-message is generated and this function returns nil.
+message is generated and this function returns nil.
*/
(data, device, dest_types, no_error))
{
!UNBOUNDP (ret =
IIFORMAT_METH (meths, set_property, (image_instance, prop, val))))
{
- return ret;
+ val = ret;
}
- /* ... then format specific methods ... */
- meths = decode_device_ii_format (Qnil, type, ERROR_ME_NOT);
- if (meths && HAS_IIFORMAT_METH_P (meths, set_property)
- &&
- !UNBOUNDP (ret =
- IIFORMAT_METH (meths, set_property, (image_instance, prop, val))))
+ else
{
- return ret;
+ /* ... then format specific methods ... */
+ meths = decode_device_ii_format (Qnil, type, ERROR_ME_NOT);
+ if (meths && HAS_IIFORMAT_METH_P (meths, set_property)
+ &&
+ !UNBOUNDP (ret =
+ IIFORMAT_METH (meths, set_property, (image_instance, prop, val))))
+ {
+ val = ret;
+ }
+ else
+ {
+ val = Qnil;
+ }
}
+ /* Make sure the image instance gets redisplayed. */
+ MARK_IMAGE_INSTANCE_CHANGED (ii);
+ MARK_SUBWINDOWS_STATE_CHANGED;
+ MARK_GLYPHS_CHANGED;
+
return val;
}
case IMAGE_SUBWINDOW:
case IMAGE_WIDGET:
+ case IMAGE_LAYOUT:
return make_int (XIMAGE_INSTANCE_SUBWINDOW_HEIGHT (image_instance));
default:
case IMAGE_SUBWINDOW:
case IMAGE_WIDGET:
+ case IMAGE_LAYOUT:
return make_int (XIMAGE_INSTANCE_SUBWINDOW_WIDTH (image_instance));
default:
incompatible_image_types (instantiator, dest_mask, IMAGE_TEXT_MASK);
}
+/* set the properties of a string */
+static Lisp_Object
+text_set_property (Lisp_Object image_instance, Lisp_Object prop,
+ Lisp_Object val)
+{
+ struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
+
+ if (EQ (prop, Q_data))
+ {
+ CHECK_STRING (val);
+ IMAGE_INSTANCE_TEXT_STRING (ii) = val;
+
+ return Qt;
+ }
+ return Qunbound;
+}
+
\f
/****************************************************************************
* formatted-string *
}
static void
-image_mark (Lisp_Object obj, void (*markobj) (Lisp_Object))
+image_mark (Lisp_Object obj)
{
struct Lisp_Specifier *image = XIMAGE_SPECIFIER (obj);
- markobj (IMAGE_SPECIFIER_ATTACHEE (image));
- markobj (IMAGE_SPECIFIER_ATTACHEE_PROPERTY (image));
+ mark_object (IMAGE_SPECIFIER_ATTACHEE (image));
+ mark_object (IMAGE_SPECIFIER_ATTACHEE_PROPERTY (image));
}
static Lisp_Object
Currently can only be instanced as `pointer', although this should
probably be fixed.)
'subwindow
- (An embedded X window; not currently implemented.)
-'widget
- (A widget control, for instance text field or radio button.)
+ (An embedded windowing system window.)
+'edit-field
+ (A text editing widget glyph.)
+'button
+ (A button widget glyph; either a push button, radio button or toggle button.)
+'tab-control
+ (A tab widget glyph; a series of user selectable tabs.)
+'progress-gauge
+ (A sliding widget glyph, for showing progress.)
+'combo-box
+ (A drop list of selectable items in a widget glyph, for editing text.)
+'label
+ (A static, text-only, widget glyph; for displaying text.)
+'tree-view
+ (A folding widget glyph.)
'autodetect
(XEmacs tries to guess what format the data is in. If X support
exists, the data string will be checked to see if it names a filename.
object). If this is not specified, the contents of `xpm-color-symbols'
are used to generate the alist.)
:face
- (Only for `inherit'. This specifies the face to inherit from.)
+ (Only for `inherit'. This specifies the face to inherit from.
+ For widget glyphs this also specifies the face to use for
+ display. It defaults to gui-element-face.)
+
+Keywords accepted as menu item specs are also accepted by widget
+glyphs. These are `:selected', `:active', `:suffix', `:keys',
+`:style', `:filter', `:config', `:included', `:key-sequence',
+`:accelerator', `:label' and `:callback'.
If instead of a vector, the instantiator is a string, it will be
converted into a vector by looking it up according to the specs in the
****************************************************************************/
static Lisp_Object
-mark_glyph (Lisp_Object obj, void (*markobj) (Lisp_Object))
+mark_glyph (Lisp_Object obj)
{
struct Lisp_Glyph *glyph = XGLYPH (obj);
- markobj (glyph->image);
- markobj (glyph->contrib_p);
- markobj (glyph->baseline);
- markobj (glyph->face);
+ mark_object (glyph->image);
+ mark_object (glyph->contrib_p);
+ mark_object (glyph->baseline);
+ mark_object (glyph->face);
return glyph->plist;
}
static int
glyph_putprop (Lisp_Object obj, Lisp_Object prop, Lisp_Object value)
{
- if ((EQ (prop, Qimage)) ||
- (EQ (prop, Qcontrib_p)) ||
- (EQ (prop, Qbaseline)))
+ if (EQ (prop, Qimage) ||
+ EQ (prop, Qcontrib_p) ||
+ EQ (prop, Qbaseline))
return 0;
if (EQ (prop, Qface))
static int
glyph_remprop (Lisp_Object obj, Lisp_Object prop)
{
- if ((EQ (prop, Qimage)) ||
- (EQ (prop, Qcontrib_p)) ||
- (EQ (prop, Qbaseline)))
+ if (EQ (prop, Qimage) ||
+ EQ (prop, Qcontrib_p) ||
+ EQ (prop, Qbaseline))
return -1;
if (EQ (prop, Qface))
g->type = type;
g->image = Fmake_specifier (Qimage); /* This function can GC */
+ g->dirty = 0;
switch (g->type)
{
case GLYPH_BUFFER:
XIMAGE_SPECIFIER_ALLOWED (g->image) =
IMAGE_NOTHING_MASK | IMAGE_TEXT_MASK
| IMAGE_MONO_PIXMAP_MASK | IMAGE_COLOR_PIXMAP_MASK
- | IMAGE_SUBWINDOW_MASK | IMAGE_WIDGET_MASK;
+ | IMAGE_SUBWINDOW_MASK | IMAGE_WIDGET_MASK
+ | IMAGE_LAYOUT_MASK;
break;
case GLYPH_POINTER:
XIMAGE_SPECIFIER_ALLOWED (g->image) =
the given FACE, unless a face is defined by the glyph itself.
****************************************************************************/
unsigned short
-glyph_width (Lisp_Object glyph, Lisp_Object frame_face,
+glyph_width (Lisp_Object glyph_or_image, Lisp_Object frame_face,
face_index window_findex, Lisp_Object window)
{
- Lisp_Object instance;
+ Lisp_Object instance = glyph_or_image;
Lisp_Object frame = XWINDOW (window)->frame;
/* #### We somehow need to distinguish between the user causing this
error condition and a bug causing it. */
- if (!GLYPHP (glyph))
- return 0;
- else
- instance = glyph_image_instance (glyph, window, ERROR_ME_NOT, 1);
+ if (GLYPHP (glyph_or_image))
+ instance = glyph_image_instance (glyph_or_image, window, ERROR_ME_NOT, 1);
if (!IMAGE_INSTANCEP (instance))
return 0;
case IMAGE_TEXT:
{
Lisp_Object str = XIMAGE_INSTANCE_TEXT_STRING (instance);
- Lisp_Object private_face = XGLYPH_FACE(glyph);
+ Lisp_Object private_face = Qnil;
+
+ if (GLYPHP (glyph_or_image))
+ private_face = XGLYPH_FACE(glyph_or_image);
if (!NILP (private_face))
return redisplay_frame_text_width_string (XFRAME (frame),
case IMAGE_SUBWINDOW:
case IMAGE_WIDGET:
+ case IMAGE_LAYOUT:
return XIMAGE_INSTANCE_SUBWINDOW_WIDTH (instance);
default:
}
static unsigned short
-glyph_height_internal (Lisp_Object glyph, Lisp_Object frame_face,
+glyph_height_internal (Lisp_Object glyph_or_image, Lisp_Object frame_face,
face_index window_findex, Lisp_Object window,
int function)
{
- Lisp_Object instance;
+ Lisp_Object instance = glyph_or_image;
Lisp_Object frame = XWINDOW (window)->frame;
- if (!GLYPHP (glyph))
- return 0;
- else
- instance = glyph_image_instance (glyph, window, ERROR_ME_NOT, 1);
+ if (GLYPHP (glyph_or_image))
+ instance = glyph_image_instance (glyph_or_image, window, ERROR_ME_NOT, 1);
if (!IMAGE_INSTANCEP (instance))
return 0;
case IMAGE_SUBWINDOW:
case IMAGE_WIDGET:
+ case IMAGE_LAYOUT:
/* #### Ugh ugh ugh -- temporary crap */
if (function == RETURN_ASCENT || function == RETURN_HEIGHT)
return XIMAGE_INSTANCE_SUBWINDOW_HEIGHT (instance);
#undef RETURN_DESCENT
#undef RETURN_HEIGHT
+static unsigned int
+glyph_dirty_p (Lisp_Object glyph_or_image, Lisp_Object window)
+{
+ Lisp_Object instance = glyph_or_image;
+
+ if (GLYPHP (glyph_or_image))
+ instance = glyph_image_instance (glyph_or_image, window, ERROR_ME_NOT, 1);
+
+ return XIMAGE_INSTANCE_DIRTYP (instance);
+}
+
+static void
+set_glyph_dirty_p (Lisp_Object glyph_or_image, Lisp_Object window, int dirty)
+{
+ Lisp_Object instance = glyph_or_image;
+
+ if (!NILP (glyph_or_image))
+ {
+ if (GLYPHP (glyph_or_image))
+ {
+ instance = glyph_image_instance (glyph_or_image, window,
+ ERROR_ME_NOT, 1);
+ XGLYPH_DIRTYP (glyph_or_image) = dirty;
+ }
+
+ XIMAGE_INSTANCE_DIRTYP (instance) = dirty;
+ }
+}
+
/* #### do we need to cache this info to speed things up? */
Lisp_Object
/*
#### All of this is 95% copied from face cachels.
Consider consolidating.
- #### We need to add a dirty flag to the glyphs.
*/
void
-mark_glyph_cachels (glyph_cachel_dynarr *elements,
- void (*markobj) (Lisp_Object))
+mark_glyph_cachels (glyph_cachel_dynarr *elements)
{
int elt;
for (elt = 0; elt < Dynarr_length (elements); elt++)
{
struct glyph_cachel *cachel = Dynarr_atp (elements, elt);
- markobj (cachel->glyph);
+ mark_object (cachel->glyph);
}
}
update_glyph_cachel_data (struct window *w, Lisp_Object glyph,
struct glyph_cachel *cachel)
{
- /* #### This should be || !cachel->updated */
- if (NILP (cachel->glyph) || !EQ (cachel->glyph, glyph))
+ if (!cachel->updated || NILP (cachel->glyph) || !EQ (cachel->glyph, glyph)
+ || XGLYPH_DIRTYP (cachel->glyph))
{
- Lisp_Object window;
+ Lisp_Object window, instance;
XSETWINDOW (window, w);
- /* #### This could be sped up if we redid things to grab the glyph
- instantiation and passed it to the size functions. */
cachel->glyph = glyph;
- cachel->width = glyph_width (glyph, Qnil, DEFAULT_INDEX, window);
- cachel->ascent = glyph_ascent (glyph, Qnil, DEFAULT_INDEX, window);
- cachel->descent = glyph_descent (glyph, Qnil, DEFAULT_INDEX, window);
+ /* Speed things up slightly by grabbing the glyph instantiation
+ and passing it to the size functions. */
+ instance = glyph_image_instance (glyph, window, ERROR_ME_NOT, 1);
+ cachel->dirty = XGLYPH_DIRTYP (glyph) = glyph_dirty_p (glyph, window);
+ cachel->width = glyph_width (instance, Qnil, DEFAULT_INDEX, window);
+ cachel->ascent = glyph_ascent (instance, Qnil, DEFAULT_INDEX, window);
+ cachel->descent = glyph_descent (instance, Qnil, DEFAULT_INDEX, window);
}
cachel->updated = 1;
Dynarr_add (w->glyph_cachels, new_cachel);
}
-static glyph_index
+glyph_index
get_glyph_cachel_index (struct window *w, Lisp_Object glyph)
{
int elt;
if (EQ (cachel->glyph, glyph) && !NILP (glyph))
{
- if (!cachel->updated)
- update_glyph_cachel_data (w, glyph, cachel);
+ update_glyph_cachel_data (w, glyph, cachel);
return elt;
}
}
#undef FROB
for (elt = 0; elt < Dynarr_length (w->glyph_cachels); elt++)
- Dynarr_atp (w->glyph_cachels, elt)->updated = 0;
+ {
+ Dynarr_atp (w->glyph_cachels, elt)->updated = 0;
+ }
+}
+
+/* Unset the dirty bit on all the glyph cachels that have it. */
+void
+mark_glyph_cachels_as_clean (struct window* w)
+{
+ int elt;
+ Lisp_Object window;
+ XSETWINDOW (window, w);
+ for (elt = 0; elt < Dynarr_length (w->glyph_cachels); elt++)
+ {
+ struct glyph_cachel *cachel = Dynarr_atp (w->glyph_cachels, elt);
+ cachel->dirty = 0;
+ set_glyph_dirty_p (cachel->glyph, window, 0);
+ }
}
#ifdef MEMORY_USAGE_STATS
obscuring an area that we want to clear. We need to be able to flip
through this quickly so a hashtable is not suitable hence the
subwindow_cachels. The question is should we just not mark
- instances in the subwindow_cachelsnor should we try and invalidate
+ instances in the subwindow_cachels or should we try and invalidate
the cache at suitable points in redisplay? If we don't invalidate
the cache it will fill up with crud that will only get removed when
the frame is deleted. So invalidation is good, the question is when
MARK_SUBWINDOWS_CHANGED when a subwindow gets deleted. */
void
-mark_subwindow_cachels (subwindow_cachel_dynarr *elements,
- void (*markobj) (Lisp_Object))
+mark_subwindow_cachels (subwindow_cachel_dynarr *elements)
{
int elt;
for (elt = 0; elt < Dynarr_length (elements); elt++)
{
struct subwindow_cachel *cachel = Dynarr_atp (elements, elt);
- markobj (cachel->subwindow);
+ mark_object (cachel->subwindow);
}
}
update_subwindow_cachel_data (struct frame *f, Lisp_Object subwindow,
struct subwindow_cachel *cachel)
{
- if (NILP (cachel->subwindow) || !EQ (cachel->subwindow, subwindow))
- {
- cachel->subwindow = subwindow;
- cachel->width = XIMAGE_INSTANCE_SUBWINDOW_WIDTH (subwindow);
- cachel->height = XIMAGE_INSTANCE_SUBWINDOW_HEIGHT (subwindow);
- }
-
+ cachel->subwindow = subwindow;
+ cachel->width = XIMAGE_INSTANCE_SUBWINDOW_WIDTH (subwindow);
+ cachel->height = XIMAGE_INSTANCE_SUBWINDOW_HEIGHT (subwindow);
cachel->updated = 1;
}
return elt;
}
+static void
+update_subwindow_cachel (Lisp_Object subwindow)
+{
+ struct frame* f;
+ int elt;
+
+ if (NILP (subwindow))
+ return;
+
+ f = XFRAME ( XIMAGE_INSTANCE_SUBWINDOW_FRAME (subwindow));
+
+ for (elt = 0; elt < Dynarr_length (f->subwindow_cachels); elt++)
+ {
+ struct subwindow_cachel *cachel =
+ Dynarr_atp (f->subwindow_cachels, elt);
+
+ if (EQ (cachel->subwindow, subwindow) && !NILP (subwindow))
+ {
+ update_subwindow_cachel_data (f, subwindow, cachel);
+ }
+ }
+}
+
/* redisplay in general assumes that drawing something will erase
what was there before. unfortunately this does not apply to
subwindows that need to be specifically unmapped in order to
if (!NILP (cachel->subwindow) && cachel->being_displayed)
{
- struct Lisp_Image_Instance* ii = XIMAGE_INSTANCE (cachel->subwindow);
- MAYBE_DEVMETH (XDEVICE (f->device), unmap_subwindow, (ii));
+ cachel->updated = 1;
+ /* #### This is not optimal as update_subwindow will search
+ the cachels for ourselves as well. We could easily optimize. */
+ unmap_subwindow (cachel->subwindow);
}
}
Dynarr_reset (f->subwindow_cachels);
Dynarr_atp (f->subwindow_cachels, elt)->updated = 0;
}
+
+
+/*****************************************************************************
+ * subwindow exposure ignorance *
+ *****************************************************************************/
+/* when we unmap subwindows the associated window system will generate
+ expose events. This we do not want as redisplay already copes with
+ the repainting necessary. Worse, we can get in an endless cycle of
+ redisplay if we are not careful. Thus we keep a per-frame list of
+ expose events that are going to come and ignore them as
+ required. */
+
+struct expose_ignore_blocktype
+{
+ Blocktype_declare (struct expose_ignore);
+} *the_expose_ignore_blocktype;
+
+int
+check_for_ignored_expose (struct frame* f, int x, int y, int width, int height)
+{
+ struct expose_ignore *ei, *prev;
+ /* the ignore list is FIFO so we should generally get a match with
+ the first element in the list */
+ for (ei = f->subwindow_exposures, prev = 0; ei; ei = ei->next)
+ {
+ /* Checking for exact matches just isn't good enough as we
+ mighte get exposures for partially obscure subwindows, thus
+ we have to check for overlaps. Being conservative we will
+ check for exposures wholly contained by the subwindow, this
+ might give us what we want.*/
+ if (ei->x <= x && ei->y <= y
+ && ei->x + ei->width >= x + width
+ && ei->y + ei->height >= y + height)
+ {
+#ifdef DEBUG_WIDGETS
+ stderr_out ("ignored %d+%d, %dx%d for exposure %d+%d, %dx%d\n",
+ x, y, width, height, ei->x, ei->y, ei->width, ei->height);
+#endif
+ if (!prev)
+ f->subwindow_exposures = ei->next;
+ else
+ prev->next = ei->next;
+
+ if (ei == f->subwindow_exposures_tail)
+ f->subwindow_exposures_tail = prev;
+
+ Blocktype_free (the_expose_ignore_blocktype, ei);
+ return 1;
+ }
+ prev = ei;
+ }
+ return 0;
+}
+
+static void
+register_ignored_expose (struct frame* f, int x, int y, int width, int height)
+{
+ if (!hold_ignored_expose_registration)
+ {
+ struct expose_ignore *ei;
+
+ ei = Blocktype_alloc (the_expose_ignore_blocktype);
+
+ ei->next = NULL;
+ ei->x = x;
+ ei->y = y;
+ ei->width = width;
+ ei->height = height;
+
+ /* we have to add the exposure to the end of the list, since we
+ want to check the oldest events first. for speed we keep a record
+ of the end so that we can add right to it. */
+ if (f->subwindow_exposures_tail)
+ {
+ f->subwindow_exposures_tail->next = ei;
+ }
+ if (!f->subwindow_exposures)
+ {
+ f->subwindow_exposures = ei;
+ }
+ f->subwindow_exposures_tail = ei;
+ }
+}
+
+/****************************************************************************
+ find_matching_subwindow
+
+ See if there is a subwindow that completely encloses the requested
+ area.
+ ****************************************************************************/
+int find_matching_subwindow (struct frame* f, int x, int y, int width, int height)
+{
+ int elt;
+
+ for (elt = 0; elt < Dynarr_length (f->subwindow_cachels); elt++)
+ {
+ struct subwindow_cachel *cachel =
+ Dynarr_atp (f->subwindow_cachels, elt);
+
+ if (cachel->being_displayed
+ &&
+ cachel->x <= x && cachel->y <= y
+ &&
+ cachel->x + cachel->width >= x + width
+ &&
+ cachel->y + cachel->height >= y + height)
+ {
+ return 1;
+ }
+ }
+ return 0;
+}
+
\f
/*****************************************************************************
* subwindow functions *
{
int elt;
- if (f->subwindows_changed || f->glyphs_changed)
+ if (f->subwindows_changed || f->subwindows_state_changed || f->faces_changed)
for (elt = 0; elt < Dynarr_length (f->subwindow_cachels); elt++)
{
struct subwindow_cachel *cachel =
||
NILP (IMAGE_INSTANCE_SUBWINDOW_FRAME (ii)))
return;
-
+#ifdef DEBUG_WIDGETS
+ stderr_out ("unmapping subwindow %d\n", IMAGE_INSTANCE_SUBWINDOW_ID (ii));
+#endif
f = XFRAME (IMAGE_INSTANCE_SUBWINDOW_FRAME (ii));
elt = get_subwindow_cachel_index (f, subwindow);
cachel = Dynarr_atp (f->subwindow_cachels, elt);
+ /* make sure we don't get expose events */
+ register_ignored_expose (f, cachel->x, cachel->y, cachel->width, cachel->height);
cachel->x = -1;
cachel->y = -1;
cachel->being_displayed = 0;
}
/* show a subwindow in its frame */
-void map_subwindow (Lisp_Object subwindow, int x, int y)
+void map_subwindow (Lisp_Object subwindow, int x, int y,
+ struct display_glyph_area *dga)
{
struct Lisp_Image_Instance* ii = XIMAGE_INSTANCE (subwindow);
int elt;
NILP (IMAGE_INSTANCE_SUBWINDOW_FRAME (ii)))
return;
+#ifdef DEBUG_WIDGETS
+ stderr_out ("mapping subwindow %d, %dx%d@%d+%d\n",
+ IMAGE_INSTANCE_SUBWINDOW_ID (ii),
+ dga->width, dga->height, x, y);
+#endif
f = XFRAME (IMAGE_INSTANCE_SUBWINDOW_FRAME (ii));
IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (ii) = 1;
elt = get_subwindow_cachel_index (f, subwindow);
cachel = Dynarr_atp (f->subwindow_cachels, elt);
cachel->x = x;
cachel->y = y;
+ cachel->width = dga->width;
+ cachel->height = dga->height;
cachel->being_displayed = 1;
- MAYBE_DEVMETH (XDEVICE (ii->device), map_subwindow, (ii, x, y));
+ MAYBE_DEVMETH (XDEVICE (ii->device), map_subwindow, (ii, x, y, dga));
}
static int
ii->data = 0;
IMAGE_INSTANCE_SUBWINDOW_ID (ii) = 0;
- IMAGE_INSTANCE_SUBWINDOW_FRAME (ii) = Qnil;
IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (ii) = 0;
IMAGE_INSTANCE_SUBWINDOW_FRAME (ii) = frame;
(subwindow))
{
CHECK_SUBWINDOW_IMAGE_INSTANCE (subwindow);
- return make_int ((int) (XIMAGE_INSTANCE_SUBWINDOW_ID (subwindow)));
+ return make_int ((int) XIMAGE_INSTANCE_SUBWINDOW_ID (subwindow));
}
DEFUN ("resize-subwindow", Fresize_subwindow, 1, 3, 0, /*
XIMAGE_INSTANCE_SUBWINDOW_HEIGHT (subwindow) = newh;
XIMAGE_INSTANCE_SUBWINDOW_WIDTH (subwindow) = neww;
+ /* need to update the cachels as redisplay will not do this */
+ update_subwindow_cachel (subwindow);
+
return subwindow;
}
(subwindow))
{
CHECK_SUBWINDOW_IMAGE_INSTANCE (subwindow);
-
+#if 0
map_subwindow (subwindow, 0, 0);
-
+#endif
return subwindow;
}
abort ();
}
}
+
+/*****************************************************************************
+ * timeouts for animated glyphs *
+ *****************************************************************************/
+static Lisp_Object Qglyph_animated_timeout_handler;
+
+DEFUN ("glyph-animated-timeout-handler", Fglyph_animated_timeout_handler, 1, 1, 0, /*
+Callback function for updating animated images.
+Don't use this.
+*/
+ (arg))
+{
+ CHECK_WEAK_LIST (arg);
+
+ if (!NILP (XWEAK_LIST_LIST (arg)) && !NILP (XCAR (XWEAK_LIST_LIST (arg))))
+ {
+ Lisp_Object value = XCAR (XWEAK_LIST_LIST (arg));
+
+ if (IMAGE_INSTANCEP (value))
+ {
+ struct Lisp_Image_Instance* ii = XIMAGE_INSTANCE (value);
+
+ if (COLOR_PIXMAP_IMAGE_INSTANCEP (value)
+ &&
+ IMAGE_INSTANCE_PIXMAP_MAXSLICE (ii) > 1
+ &&
+ !disable_animated_pixmaps)
+ {
+ /* Increment the index of the image slice we are currently
+ viewing. */
+ IMAGE_INSTANCE_PIXMAP_SLICE (ii) =
+ (IMAGE_INSTANCE_PIXMAP_SLICE (ii) + 1)
+ % IMAGE_INSTANCE_PIXMAP_MAXSLICE (ii);
+ /* We might need to kick redisplay at this point - but we
+ also might not. */
+ MARK_DEVICE_FRAMES_GLYPHS_CHANGED
+ (XDEVICE (IMAGE_INSTANCE_DEVICE (ii)));
+ IMAGE_INSTANCE_DIRTYP (ii) = 1;
+ }
+ }
+ }
+ return Qnil;
+}
+
+Lisp_Object add_glyph_animated_timeout (EMACS_INT tickms, Lisp_Object image)
+{
+ Lisp_Object ret = Qnil;
+
+ if (tickms > 0 && IMAGE_INSTANCEP (image))
+ {
+ double ms = ((double)tickms) / 1000.0;
+ struct gcpro gcpro1;
+ Lisp_Object holder = make_weak_list (WEAK_LIST_SIMPLE);
+
+ GCPRO1 (holder);
+ XWEAK_LIST_LIST (holder) = Fcons (image, Qnil);
+
+ ret = Fadd_timeout (make_float (ms),
+ Qglyph_animated_timeout_handler,
+ holder, make_float (ms));
+
+ UNGCPRO;
+ }
+ return ret;
+}
+
+void disable_glyph_animated_timeout (int i)
+{
+ Lisp_Object id;
+ XSETINT (id, i);
+
+ Fdisable_timeout (id);
+}
+
\f
/*****************************************************************************
* initialization *
defsymbol (&Qpointer_image_instance_p, "pointer-image-instance-p");
defsymbol (&Qwidget_image_instance_p, "widget-image-instance-p");
defsymbol (&Qsubwindow_image_instance_p, "subwindow-image-instance-p");
+ defsymbol (&Qlayout_image_instance_p, "layout-image-instance-p");
DEFSUBR (Fmake_image_instance);
DEFSUBR (Fimage_instance_p);
/* Qbuffer defined in general.c. */
/* Qpointer defined above */
+ /* Unfortunately, timeout handlers must be lisp functions. This is
+ for animated glyphs. */
+ defsymbol (&Qglyph_animated_timeout_handler,
+ "glyph-animated-timeout-handler");
+ DEFSUBR (Fglyph_animated_timeout_handler);
+
/* Errors */
deferror (&Qimage_conversion_error,
"image-conversion-error",
}
+static const struct lrecord_description image_specifier_description[] = {
+ { XD_LISP_OBJECT, specifier_data_offset + offsetof(struct image_specifier, attachee), 2 },
+ { XD_END }
+};
+
void
specifier_type_create_image (void)
{
}
void
+reinit_specifier_type_create_image (void)
+{
+ REINITIALIZE_SPECIFIER_TYPE (image);
+}
+
+
+static const struct lrecord_description iike_description_1[] = {
+ { XD_LISP_OBJECT, offsetof(ii_keyword_entry, keyword), 1 },
+ { XD_END }
+};
+
+static const struct struct_description iike_description = {
+ sizeof(ii_keyword_entry),
+ iike_description_1
+};
+
+static const struct lrecord_description iiked_description_1[] = {
+ XD_DYNARR_DESC(ii_keyword_entry_dynarr, &iike_description),
+ { XD_END }
+};
+
+static const struct struct_description iiked_description = {
+ sizeof(ii_keyword_entry_dynarr),
+ iiked_description_1
+};
+
+static const struct lrecord_description iife_description_1[] = {
+ { XD_LISP_OBJECT, offsetof(image_instantiator_format_entry, symbol), 2 },
+ { XD_STRUCT_PTR, offsetof(image_instantiator_format_entry, meths), 1, &iim_description },
+ { XD_END }
+};
+
+static const struct struct_description iife_description = {
+ sizeof(image_instantiator_format_entry),
+ iife_description_1
+};
+
+static const struct lrecord_description iifed_description_1[] = {
+ XD_DYNARR_DESC(image_instantiator_format_entry_dynarr, &iife_description),
+ { XD_END }
+};
+
+static const struct struct_description iifed_description = {
+ sizeof(image_instantiator_format_entry_dynarr),
+ iifed_description_1
+};
+
+static const struct lrecord_description iim_description_1[] = {
+ { XD_LISP_OBJECT, offsetof(struct image_instantiator_methods, symbol), 2 },
+ { XD_STRUCT_PTR, offsetof(struct image_instantiator_methods, keywords), 1, &iiked_description },
+ { XD_STRUCT_PTR, offsetof(struct image_instantiator_methods, consoles), 1, &cted_description },
+ { XD_END }
+};
+
+const struct struct_description iim_description = {
+ sizeof(struct image_instantiator_methods),
+ iim_description_1
+};
+
+void
image_instantiator_format_create (void)
{
/* image instantiators */
Vimage_instantiator_format_list = Qnil;
staticpro (&Vimage_instantiator_format_list);
+ dumpstruct (&the_image_instantiator_format_entry_dynarr, &iifed_description);
+
INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (nothing, "nothing");
IIFORMAT_HAS_METHOD (nothing, possible_dest_types);
IIFORMAT_HAS_METHOD (string, instantiate);
IIFORMAT_VALID_KEYWORD (string, Q_data, check_valid_string);
+ /* Do this so we can set strings. */
+ INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (text, "text");
+ IIFORMAT_HAS_METHOD (text, set_property);
INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (formatted_string, "formatted-string");
}
void
+reinit_vars_of_glyphs (void)
+{
+ the_expose_ignore_blocktype =
+ Blocktype_new (struct expose_ignore_blocktype);
+
+ hold_ignored_expose_registration = 0;
+}
+
+
+void
vars_of_glyphs (void)
{
+ reinit_vars_of_glyphs ();
+
Vthe_nothing_vector = vector1 (Qnothing);
staticpro (&Vthe_nothing_vector);
#ifdef HAVE_XFACE
Fprovide (Qxface);
#endif
+
+ DEFVAR_BOOL ("disable-animated-pixmaps", &disable_animated_pixmaps /*
+Whether animated pixmaps should be animated.
+Default is t.
+*/);
+ disable_animated_pixmaps = 0;
}
void
inherit mono-pixmap
autodetect mono-pixmap, color-pixmap, pointer, text
button widget
- edit widget
- combo widget
+ edit-field widget
+ combo -box widget
+ progress-gauge widget
+ tab-control widget
+ tree-view widget
scrollbar widget
static widget
*/
Dynarr_declare (ii_keyword_entry);
} ii_keyword_entry_dynarr;
+extern const struct struct_description iim_description;
+
struct image_instantiator_methods
{
Lisp_Object symbol;
Dynarr_new (console_type_entry); \
add_entry_to_image_instantiator_format_list \
(Q##format, format##_image_instantiator_methods); \
+ dumpstruct (&format##_image_instantiator_methods, \
+ &iim_description); \
} while (0)
#define INITIALIZE_IMAGE_INSTANTIATOR_FORMAT(format, obj_name) \
do { \
defsymbol (&Q##format, obj_name); \
- INITIALIZE_IMAGE_INSTANTIATOR_FORMAT_NO_SYM(format, obj_name); \
+ INITIALIZE_IMAGE_INSTANTIATOR_FORMAT_NO_SYM(format, obj_name);\
} while (0)
/* Declare that image-instantiator format FORMAT has method M; used in
DECLARE_IMAGE_INSTANTIATOR_FORMAT(format); \
struct image_instantiator_methods *type##_##format##_image_instantiator_methods
-#define INITIALIZE_DEVICE_IIFORMAT(type, format) \
-do { \
- type##_##format##_image_instantiator_methods = \
- xnew_and_zero (struct image_instantiator_methods); \
+#define INITIALIZE_DEVICE_IIFORMAT(type, format) \
+do { \
+ type##_##format##_image_instantiator_methods = \
+ xnew_and_zero (struct image_instantiator_methods); \
type##_##format##_image_instantiator_methods->symbol = Q##format; \
type##_##format##_image_instantiator_methods->device = Q##type; \
type##_##format##_image_instantiator_methods->keywords = \
- Dynarr_new (ii_keyword_entry); \
- add_entry_to_device_ii_format_list \
+ Dynarr_new (ii_keyword_entry); \
+ add_entry_to_device_ii_format_list \
(Q##type, Q##format, type##_##format##_image_instantiator_methods); \
- IIFORMAT_VALID_CONSOLE(type,format); \
+ IIFORMAT_VALID_CONSOLE(type,format); \
+ dumpstruct (&type##_##format##_image_instantiator_methods, \
+ &iim_description); \
} while (0)
/* Declare that image-instantiator format FORMAT has method M; used in
initialization routines */
#define IIFORMAT_HAS_DEVMETHOD(type, format, m) \
(type##_##format##_image_instantiator_methods->m##_method = type##_##format##_##m)
+#define IIFORMAT_HAS_SHARED_DEVMETHOD(type, format, m, fromformat) \
+ (type##_##format##_image_instantiator_methods->m##_method = type##_##fromformat##_##m)
struct image_instantiator_methods *
decode_device_ii_format (Lisp_Object device, Lisp_Object format,
void check_valid_int (Lisp_Object data);
void check_valid_face (Lisp_Object data);
void check_valid_vector (Lisp_Object data);
+void check_valid_item_list_1 (Lisp_Object items);
void initialize_subwindow_image_instance (struct Lisp_Image_Instance*);
void subwindow_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
Lisp_Object pointer_fg, Lisp_Object pointer_bg,
int dest_mask, Lisp_Object domain);
+void widget_instantiate_1 (Lisp_Object image_instance, Lisp_Object instantiator,
+ Lisp_Object pointer_fg, Lisp_Object pointer_bg,
+ int dest_mask, Lisp_Object domain, int default_textheight,
+ int default_pixheight, int default_textwidth);
DECLARE_DOESNT_RETURN (incompatible_image_types (Lisp_Object instantiator,
int given_dest_mask,
XRECORD (x, image_instance, struct Lisp_Image_Instance)
#define XSETIMAGE_INSTANCE(x, p) XSETRECORD (x, p, image_instance)
#define IMAGE_INSTANCEP(x) RECORDP (x, image_instance)
-#define GC_IMAGE_INSTANCEP(x) GC_RECORDP (x, image_instance)
#define CHECK_IMAGE_INSTANCE(x) CHECK_RECORD (x, image_instance)
#define CONCHECK_IMAGE_INSTANCE(x) CONCHECK_RECORD (x, image_instance)
IMAGE_COLOR_PIXMAP,
IMAGE_POINTER,
IMAGE_SUBWINDOW,
- IMAGE_WIDGET
+ IMAGE_WIDGET,
+ IMAGE_LAYOUT
};
#define IMAGE_NOTHING_MASK (1 << 0)
#define IMAGE_POINTER_MASK (1 << 4)
#define IMAGE_SUBWINDOW_MASK (1 << 5)
#define IMAGE_WIDGET_MASK (1 << 6)
+#define IMAGE_LAYOUT_MASK (1 << 7)
#define IMAGE_INSTANCE_TYPE_P(ii, type) \
(IMAGE_INSTANCEP (ii) && XIMAGE_INSTANCE_TYPE (ii) == type)
IMAGE_INSTANCE_TYPE_P (ii, IMAGE_SUBWINDOW)
#define WIDGET_IMAGE_INSTANCEP(ii) \
IMAGE_INSTANCE_TYPE_P (ii, IMAGE_WIDGET)
+#define LAYOUT_IMAGE_INSTANCEP(ii) \
+ IMAGE_INSTANCE_TYPE_P (ii, IMAGE_LAYOUT)
-#define CHECK_NOTHING_IMAGE_INSTANCE(x) do { \
- CHECK_IMAGE_INSTANCE (x); \
+#define CHECK_NOTHING_IMAGE_INSTANCE(x) do { \
+ CHECK_IMAGE_INSTANCE (x); \
if (!NOTHING_IMAGE_INSTANCEP (x)) \
x = wrong_type_argument (Qnothing_image_instance_p, (x)); \
} while (0)
-#define CHECK_TEXT_IMAGE_INSTANCE(x) do { \
- CHECK_IMAGE_INSTANCE (x); \
+#define CHECK_TEXT_IMAGE_INSTANCE(x) do { \
+ CHECK_IMAGE_INSTANCE (x); \
if (!TEXT_IMAGE_INSTANCEP (x)) \
x = wrong_type_argument (Qtext_image_instance_p, (x)); \
} while (0)
x = wrong_type_argument (Qmono_pixmap_image_instance_p, (x)); \
} while (0)
-#define CHECK_COLOR_PIXMAP_IMAGE_INSTANCE(x) do { \
- CHECK_IMAGE_INSTANCE (x); \
+#define CHECK_COLOR_PIXMAP_IMAGE_INSTANCE(x) do { \
+ CHECK_IMAGE_INSTANCE (x); \
if (!COLOR_PIXMAP_IMAGE_INSTANCEP (x)) \
x = wrong_type_argument (Qcolor_pixmap_image_instance_p, (x)); \
} while (0)
-#define CHECK_POINTER_IMAGE_INSTANCE(x) do { \
- CHECK_IMAGE_INSTANCE (x); \
+#define CHECK_POINTER_IMAGE_INSTANCE(x) do { \
+ CHECK_IMAGE_INSTANCE (x); \
if (!POINTER_IMAGE_INSTANCEP (x)) \
x = wrong_type_argument (Qpointer_image_instance_p, (x)); \
} while (0)
-#define CHECK_SUBWINDOW_IMAGE_INSTANCE(x) do { \
+#define CHECK_SUBWINDOW_IMAGE_INSTANCE(x) do { \
CHECK_IMAGE_INSTANCE (x); \
if (!SUBWINDOW_IMAGE_INSTANCEP (x) \
&& !WIDGET_IMAGE_INSTANCEP (x)) \
x = wrong_type_argument (Qsubwindow_image_instance_p, (x)); \
} while (0)
-#define CHECK_WIDGET_IMAGE_INSTANCE(x) do { \
- CHECK_IMAGE_INSTANCE (x); \
+#define CHECK_WIDGET_IMAGE_INSTANCE(x) do { \
+ CHECK_IMAGE_INSTANCE (x); \
if (!WIDGET_IMAGE_INSTANCEP (x)) \
x = wrong_type_argument (Qwidget_image_instance_p, (x)); \
} while (0)
+#define CHECK_LAYOUT_IMAGE_INSTANCE(x) do { \
+ CHECK_IMAGE_INSTANCE (x); \
+ if (!LAYOUT_IMAGE_INSTANCEP (x)) \
+ x = wrong_type_argument (Qlayout_image_instance_p, (x)); \
+} while (0)
+
struct Lisp_Image_Instance
{
struct lcrecord_header header;
Lisp_Object device;
Lisp_Object name;
enum image_instance_type type;
+ int x_offset, y_offset; /* for layout purposes */
+ unsigned int dirty : 1;
union
{
struct
struct
{
int width, height, depth;
+ int slice, maxslice, timeout;
Lisp_Object hotspot_x, hotspot_y; /* integer or Qnil */
Lisp_Object filename; /* string or Qnil */
Lisp_Object mask_filename; /* string or Qnil */
or a pointer */
Lisp_Object auxdata; /* list or Qnil: any additional data
to be seen from lisp */
+ void* mask; /* mask that can be seen from all windowing systems */
} pixmap; /* used for pointers as well */
struct
{
Lisp_Object frame;
unsigned int width, height;
void* subwindow; /* specific devices can use this as necessary */
- int being_displayed; /* used to detect when needs to be unmapped */
- struct
+ unsigned int being_displayed : 1; /* used to detect when needs to be unmapped */
+ union
{
- Lisp_Object face; /* foreground and background colors */
- Lisp_Object type;
- Lisp_Object props; /* properties */
- Lisp_Object gui_item; /* a list of gui_items */
- } widget; /* widgets are subwindows */
+ struct
+ {
+ Lisp_Object face; /* foreground and background colors */
+ Lisp_Object type;
+ Lisp_Object props; /* properties */
+ Lisp_Object gui_item; /* a list of gui_items */
+ } widget; /* widgets are subwindows */
+ struct
+ {
+ Lisp_Object children; /* managed children */
+ Lisp_Object border; /* Style of enclosing border or text. */
+ } layout;
+ } s;
} subwindow;
} u;
#define IMAGE_INSTANCE_DEVICE(i) ((i)->device)
#define IMAGE_INSTANCE_NAME(i) ((i)->name)
#define IMAGE_INSTANCE_TYPE(i) ((i)->type)
+#define IMAGE_INSTANCE_XOFFSET(i) ((i)->x_offset)
+#define IMAGE_INSTANCE_YOFFSET(i) ((i)->y_offset)
#define IMAGE_INSTANCE_PIXMAP_TYPE_P(i) \
((IMAGE_INSTANCE_TYPE (i) == IMAGE_MONO_PIXMAP) \
|| (IMAGE_INSTANCE_TYPE (i) == IMAGE_COLOR_PIXMAP))
+#define IMAGE_INSTANCE_DIRTYP(i) ((i)->dirty)
#define IMAGE_INSTANCE_TEXT_STRING(i) ((i)->u.text.string)
#define IMAGE_INSTANCE_PIXMAP_FG(i) ((i)->u.pixmap.fg)
#define IMAGE_INSTANCE_PIXMAP_BG(i) ((i)->u.pixmap.bg)
#define IMAGE_INSTANCE_PIXMAP_AUXDATA(i) ((i)->u.pixmap.auxdata)
+#define IMAGE_INSTANCE_PIXMAP_MASK(i) ((i)->u.pixmap.mask)
+#define IMAGE_INSTANCE_PIXMAP_SLICE(i) ((i)->u.pixmap.slice)
+#define IMAGE_INSTANCE_PIXMAP_MAXSLICE(i) ((i)->u.pixmap.maxslice)
+#define IMAGE_INSTANCE_PIXMAP_TIMEOUT(i) ((i)->u.pixmap.timeout)
#define IMAGE_INSTANCE_SUBWINDOW_WIDTH(i) ((i)->u.subwindow.width)
#define IMAGE_INSTANCE_SUBWINDOW_HEIGHT(i) ((i)->u.subwindow.height)
IMAGE_INSTANCE_SUBWINDOW_WIDTH(i)
#define IMAGE_INSTANCE_WIDGET_HEIGHT(i) \
IMAGE_INSTANCE_SUBWINDOW_HEIGHT(i)
-#define IMAGE_INSTANCE_WIDGET_TYPE(i) ((i)->u.subwindow.widget.type)
-#define IMAGE_INSTANCE_WIDGET_PROPS(i) ((i)->u.subwindow.widget.props)
-#define IMAGE_INSTANCE_WIDGET_FACE(i) ((i)->u.subwindow.widget.face)
-#define IMAGE_INSTANCE_WIDGET_ITEM(i) ((i)->u.subwindow.widget.gui_item)
-#define IMAGE_INSTANCE_WIDGET_SINGLE_ITEM(i) \
-(CONSP (IMAGE_INSTANCE_WIDGET_ITEM (i)) ? \
-XCAR (IMAGE_INSTANCE_WIDGET_ITEM (i)) : \
- IMAGE_INSTANCE_WIDGET_ITEM (i))
+#define IMAGE_INSTANCE_WIDGET_TYPE(i) ((i)->u.subwindow.s.widget.type)
+#define IMAGE_INSTANCE_WIDGET_PROPS(i) ((i)->u.subwindow.s.widget.props)
+#define IMAGE_INSTANCE_WIDGET_FACE(i) ((i)->u.subwindow.s.widget.face)
+#define IMAGE_INSTANCE_WIDGET_ITEMS(i) ((i)->u.subwindow.s.widget.gui_item)
+#define IMAGE_INSTANCE_WIDGET_ITEM(i) \
+(CONSP (IMAGE_INSTANCE_WIDGET_ITEMS (i)) ? \
+XCAR (IMAGE_INSTANCE_WIDGET_ITEMS (i)) : \
+ IMAGE_INSTANCE_WIDGET_ITEMS (i))
#define IMAGE_INSTANCE_WIDGET_TEXT(i) XGUI_ITEM (IMAGE_INSTANCE_WIDGET_ITEM (i))->name
+#define IMAGE_INSTANCE_LAYOUT_CHILDREN(i) ((i)->u.subwindow.s.layout.children)
+#define IMAGE_INSTANCE_LAYOUT_BORDER(i) ((i)->u.subwindow.s.layout.border)
+
#define XIMAGE_INSTANCE_DEVICE(i) \
IMAGE_INSTANCE_DEVICE (XIMAGE_INSTANCE (i))
#define XIMAGE_INSTANCE_NAME(i) \
IMAGE_INSTANCE_NAME (XIMAGE_INSTANCE (i))
#define XIMAGE_INSTANCE_TYPE(i) \
IMAGE_INSTANCE_TYPE (XIMAGE_INSTANCE (i))
+#define XIMAGE_INSTANCE_XOFFSET(i) \
+ IMAGE_INSTANCE_XOFFSET (XIMAGE_INSTANCE (i))
+#define XIMAGE_INSTANCE_YOFFSET(i) \
+ IMAGE_INSTANCE_YOFFSET (XIMAGE_INSTANCE (i))
+#define XIMAGE_INSTANCE_DIRTYP(i) \
+ IMAGE_INSTANCE_DIRTYP (XIMAGE_INSTANCE (i))
#define XIMAGE_INSTANCE_TEXT_STRING(i) \
IMAGE_INSTANCE_TEXT_STRING (XIMAGE_INSTANCE (i))
IMAGE_INSTANCE_PIXMAP_FG (XIMAGE_INSTANCE (i))
#define XIMAGE_INSTANCE_PIXMAP_BG(i) \
IMAGE_INSTANCE_PIXMAP_BG (XIMAGE_INSTANCE (i))
+#define XIMAGE_INSTANCE_PIXMAP_MASK(i) \
+ IMAGE_INSTANCE_PIXMAP_MASK (XIMAGE_INSTANCE (i))
+#define XIMAGE_INSTANCE_PIXMAP_SLICE(i) \
+ IMAGE_INSTANCE_PIXMAP_SLICE (XIMAGE_INSTANCE (i))
+#define XIMAGE_INSTANCE_PIXMAP_MAXSLICE(i) \
+ IMAGE_INSTANCE_PIXMAP_MAXSLICE (XIMAGE_INSTANCE (i))
+#define XIMAGE_INSTANCE_PIXMAP_TIMEOUT(i) \
+ IMAGE_INSTANCE_PIXMAP_TIMEOUT (XIMAGE_INSTANCE (i))
#define XIMAGE_INSTANCE_WIDGET_WIDTH(i) \
IMAGE_INSTANCE_WIDGET_WIDTH (XIMAGE_INSTANCE (i))
IMAGE_INSTANCE_WIDGET_FACE (XIMAGE_INSTANCE (i))
#define XIMAGE_INSTANCE_WIDGET_ITEM(i) \
IMAGE_INSTANCE_WIDGET_ITEM (XIMAGE_INSTANCE (i))
-#define XIMAGE_INSTANCE_WIDGET_SINGLE_ITEM(i) \
- IMAGE_INSTANCE_WIDGET_SINGLE_ITEM (XIMAGE_INSTANCE (i))
+#define XIMAGE_INSTANCE_WIDGET_ITEMS(i) \
+ IMAGE_INSTANCE_WIDGET_ITEMS (XIMAGE_INSTANCE (i))
#define XIMAGE_INSTANCE_WIDGET_TEXT(i) \
IMAGE_INSTANCE_WIDGET_TEXT (XIMAGE_INSTANCE (i))
+#define XIMAGE_INSTANCE_LAYOUT_CHILDREN(i) \
+ IMAGE_INSTANCE_LAYOUT_CHILDREN (XIMAGE_INSTANCE (i))
+#define XIMAGE_INSTANCE_LAYOUT_BORDER(i) \
+ IMAGE_INSTANCE_LAYOUT_BORDER (XIMAGE_INSTANCE (i))
+
#define XIMAGE_INSTANCE_SUBWINDOW_WIDTH(i) \
IMAGE_INSTANCE_SUBWINDOW_WIDTH (XIMAGE_INSTANCE (i))
#define XIMAGE_INSTANCE_SUBWINDOW_HEIGHT(i) \
#define XIMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP(i) \
IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (XIMAGE_INSTANCE (i))
+#define MARK_IMAGE_INSTANCE_CHANGED(i) \
+ (IMAGE_INSTANCE_DIRTYP (i) = 1);
+
#ifdef HAVE_XPM
Lisp_Object evaluate_xpm_color_symbols (void);
Lisp_Object pixmap_to_lisp_data (Lisp_Object name, int ok_if_data_invalid);
Lisp_Object baseline; /* percent above baseline */
Lisp_Object face; /* if non-nil, face to use when displaying */
-
+
Lisp_Object plist;
void (*after_change) (Lisp_Object glyph, Lisp_Object property,
Lisp_Object locale);
+
+ unsigned int dirty : 1; /* So that we can selectively
+ redisplay changed glyphs. */
};
DECLARE_LRECORD (glyph, struct Lisp_Glyph);
#define XGLYPH(x) XRECORD (x, glyph, struct Lisp_Glyph)
#define XSETGLYPH(x, p) XSETRECORD (x, p, glyph)
#define GLYPHP(x) RECORDP (x, glyph)
-#define GC_GLYPHP(x) GC_RECORDP (x, glyph)
#define CHECK_GLYPH(x) CHECK_RECORD (x, glyph)
#define CONCHECK_GLYPH(x) CONCHECK_RECORD (x, glyph)
#define GLYPH_CONTRIB_P(g) ((g)->contrib_p)
#define GLYPH_BASELINE(g) ((g)->baseline)
#define GLYPH_FACE(g) ((g)->face)
+#define GLYPH_DIRTYP(g) ((g)->dirty)
#define XGLYPH_TYPE(g) GLYPH_TYPE (XGLYPH (g))
#define XGLYPH_IMAGE(g) GLYPH_IMAGE (XGLYPH (g))
#define XGLYPH_CONTRIB_P(g) GLYPH_CONTRIB_P (XGLYPH (g))
#define XGLYPH_BASELINE(g) GLYPH_BASELINE (XGLYPH (g))
#define XGLYPH_FACE(g) GLYPH_FACE (XGLYPH (g))
+#define XGLYPH_DIRTYP(g) GLYPH_DIRTYP (XGLYPH (g))
+
+#define MARK_GLYPH_CHANGED(g) (GLYPH_DIRTYP (g) = 1);
-extern Lisp_Object Qxpm, Qxface;
+extern Lisp_Object Qxpm, Qxface, Qetched_in, Qetched_out, Qbevel_in, Qbevel_out;
extern Lisp_Object Q_data, Q_file, Q_color_symbols, Qconst_glyph_variable;
extern Lisp_Object Qxbm, Qedit_field, Qgroup, Qlabel, Qcombo_box, Qscrollbar;
-extern Lisp_Object Qtree_view, Qtab_control, Qprogress_gauge;
+extern Lisp_Object Qtree_view, Qtab_control, Qprogress_gauge, Q_border;
extern Lisp_Object Q_mask_file, Q_mask_data, Q_hotspot_x, Q_hotspot_y;
extern Lisp_Object Q_foreground, Q_background, Q_face, Q_descriptor, Q_group;
extern Lisp_Object Q_width, Q_height, Q_pixel_width, Q_pixel_height, Q_text;
extern Lisp_Object Q_items, Q_properties, Q_image, Q_percent, Qimage_conversion_error;
+extern Lisp_Object Q_orientation;
extern Lisp_Object Vcontinuation_glyph, Vcontrol_arrow_glyph, Vhscroll_glyph;
extern Lisp_Object Vinvisible_text_glyph, Voctal_escape_glyph, Vtruncation_glyph;
extern Lisp_Object Vxemacs_logo;
void widget_text_to_pixel_conversion (Lisp_Object domain, Lisp_Object face,
int th, int tw,
int* height, int* width);
+Lisp_Object add_glyph_animated_timeout (EMACS_INT tickms, Lisp_Object device);
+void disable_glyph_animated_timeout (int i);
/************************************************************************/
/* Glyph Cachels */
{
Lisp_Object glyph;
+ unsigned int dirty :1; /* I'm copying faces here. I'm not
+ sure why we need two dirty
+ flags. Maybe because an image
+ instance can be dirty and so we
+ need to frob this in the same way
+ as other image instance properties. */
unsigned int updated :1;
+
unsigned short width;
unsigned short ascent;
unsigned short descent;
Dynarr_atp (window->glyph_cachels, index)->ascent
#define GLYPH_CACHEL_DESCENT(window, index) \
Dynarr_atp (window->glyph_cachels, index)->descent
+#define GLYPH_CACHEL_DIRTYP(window, index) \
+ Dynarr_atp (window->glyph_cachels, index)->dirty
-void mark_glyph_cachels (glyph_cachel_dynarr *elements,
- void (*markobj) (Lisp_Object));
+void mark_glyph_cachels (glyph_cachel_dynarr *elements);
void mark_glyph_cachels_as_not_updated (struct window *w);
+void mark_glyph_cachels_as_clean (struct window *w);
void reset_glyph_cachels (struct window *w);
+glyph_index get_glyph_cachel_index (struct window *w, Lisp_Object glyph);
#ifdef MEMORY_USAGE_STATS
int compute_glyph_cachel_usage (glyph_cachel_dynarr *glyph_cachels,
Lisp_Object subwindow;
int x, y;
int width, height;
- int being_displayed;
- int updated;
+ unsigned int being_displayed : 1;
+ unsigned int updated : 1;
};
typedef struct
Dynarr_declare (subwindow_cachel);
} subwindow_cachel_dynarr;
-void mark_subwindow_cachels (subwindow_cachel_dynarr *elements,
- void (*markobj) (Lisp_Object));
+void mark_subwindow_cachels (subwindow_cachel_dynarr *elements);
void mark_subwindow_cachels_as_not_updated (struct frame *f);
void reset_subwindow_cachels (struct frame *f);
void unmap_subwindow (Lisp_Object subwindow);
-void map_subwindow (Lisp_Object subwindow, int x, int y);
+void map_subwindow (Lisp_Object subwindow, int x, int y,
+ struct display_glyph_area *dga);
void update_frame_subwindows (struct frame *f);
+int find_matching_subwindow (struct frame* f, int x, int y, int width, int height);
+
+struct expose_ignore
+{
+ int x;
+ int y;
+ int width;
+ int height;
+ struct expose_ignore *next;
+};
+
+int check_for_ignored_expose (struct frame* f, int x, int y, int width, int height);
+extern int hold_ignored_expose_registration;
#endif /* _XEMACS_GLYPHS_H_ */
if (NILP (data) || UNBOUNDP (data))
return Qnil;
- MARK_SUBWINDOWS_CHANGED;
+ MARK_SUBWINDOWS_STATE_CHANGED;
/* Ok, this is our one. Enqueue it. */
get_gui_callback (data, &fn, &arg);
XSETFRAME (frame, f);
}
\f
-struct mark_widget_value_closure
-{
- void (*markobj) (Lisp_Object);
-};
-
static int
mark_widget_value_mapper (widget_value *val, void *closure)
{
Lisp_Object markee;
-
- struct mark_widget_value_closure *cl =
- (struct mark_widget_value_closure *) closure;
if (val->call_data)
{
VOID_TO_LISP (markee, val->call_data);
- (cl->markobj) (markee);
+ mark_object (markee);
}
if (val->accel)
{
VOID_TO_LISP (markee, val->accel);
- (cl->markobj) (markee);
+ mark_object (markee);
}
return 0;
}
static Lisp_Object
-mark_popup_data (Lisp_Object obj, void (*markobj) (Lisp_Object))
+mark_popup_data (Lisp_Object obj)
{
struct popup_data *data = (struct popup_data *) XPOPUP_DATA (obj);
call-data */
if (data->id)
- {
- struct mark_widget_value_closure closure;
-
- closure.markobj = markobj;
- lw_map_widget_values (data->id, mark_widget_value_mapper, &closure);
- }
+ lw_map_widget_values (data->id, mark_widget_value_mapper, 0);
return data->last_menubar_buffer;
}
}
else
{
- MARK_SUBWINDOWS_CHANGED;
+ MARK_SUBWINDOWS_STATE_CHANGED;
get_gui_callback (data, &fn, &arg);
}
/* !!#### This function has not been Mule-ized */
/* This function cannot GC because gc_currently_forbidden is set when
it's called */
- struct Lisp_Gui_Item* pgui = XGUI_ITEM (gui_item);
+ struct Lisp_Gui_Item* pgui = 0;
+
+ /* degenerate case */
+ if (STRINGP (gui_item))
+ {
+ wv->type = TEXT_TYPE;
+ wv->name = (char *) XSTRING_DATA (gui_item);
+ wv->name = xstrdup (wv->name);
+ return 1;
+ }
+ else if (!GUI_ITEMP (gui_item))
+ signal_simple_error("need a string or a gui_item here", gui_item);
+
+ pgui = XGUI_ITEM (gui_item);
if (!NILP (pgui->filter))
signal_simple_error(":filter keyword not permitted on leaf nodes", gui_item);
CHECK_STRING (pgui->name);
wv->name = (char *) XSTRING_DATA (pgui->name);
+ wv->name = xstrdup (wv->name);
wv->accel = LISP_TO_VOID (gui_item_accelerator (gui_item));
if (!NILP (pgui->suffix))
return 1;
}
+/* parse tree's of gui items into widget_value hierarchies */
+static void gui_item_children_to_widget_values (Lisp_Object items, widget_value* parent);
+
+static widget_value *
+gui_items_to_widget_values_1 (Lisp_Object items, widget_value* parent,
+ widget_value* prev)
+{
+ widget_value* wv = 0;
+
+ assert ((parent || prev) && !(parent && prev));
+ /* now walk the tree creating widget_values as appropriate */
+ if (!CONSP (items))
+ {
+ wv = xmalloc_widget_value();
+ if (parent)
+ parent->contents = wv;
+ else
+ prev->next = wv;
+ if (!button_item_to_widget_value (items, wv, 0, 1))
+ {
+ free_widget_value (wv);
+ if (parent)
+ parent->contents = 0;
+ else
+ prev->next = 0;
+ }
+ else
+ {
+ wv->value = xstrdup (wv->name); /* what a mess... */
+ }
+ }
+ else
+ {
+ /* first one is the parent */
+ if (CONSP (XCAR (items)))
+ signal_simple_error ("parent item must not be a list", XCAR (items));
+
+ if (parent)
+ wv = gui_items_to_widget_values_1 (XCAR (items), parent, 0);
+ else
+ wv = gui_items_to_widget_values_1 (XCAR (items), 0, prev);
+ /* the rest are the children */
+ gui_item_children_to_widget_values (XCDR (items), wv);
+ }
+ return wv;
+}
+
+static void
+gui_item_children_to_widget_values (Lisp_Object items, widget_value* parent)
+{
+ widget_value* wv = 0, *prev = 0;
+ Lisp_Object rest;
+ CHECK_CONS (items);
+
+ /* first one is master */
+ prev = gui_items_to_widget_values_1 (XCAR (items), parent, 0);
+ /* the rest are the children */
+ LIST_LOOP (rest, XCDR (items))
+ {
+ Lisp_Object tab = XCAR (rest);
+ wv = gui_items_to_widget_values_1 (tab, 0, prev);
+ prev = wv;
+ }
+}
+
+widget_value *
+gui_items_to_widget_values (Lisp_Object items)
+{
+ /* !!#### This function has not been Mule-ized */
+ /* This function can GC */
+ widget_value *control = 0, *tmp = 0;
+ int count = specpdl_depth ();
+ Lisp_Object wv_closure;
+
+ if (NILP (items))
+ signal_simple_error ("must have some items", items);
+
+ /* Inhibit GC during this conversion. The reasons for this are
+ the same as in menu_item_descriptor_to_widget_value(); see
+ the large comment above that function. */
+ record_unwind_protect (restore_gc_inhibit,
+ make_int (gc_currently_forbidden));
+ gc_currently_forbidden = 1;
+
+ /* Also make sure that we free the partially-created widget_value
+ tree on Lisp error. */
+ control = xmalloc_widget_value();
+ wv_closure = make_opaque_ptr (control);
+ record_unwind_protect (widget_value_unwind, wv_closure);
+
+ gui_items_to_widget_values_1 (items, control, 0);
+
+ /* mess about getting the data we really want */
+ tmp = control;
+ control = control->contents;
+ tmp->next = 0;
+ tmp->contents = 0;
+ free_widget_value (tmp);
+
+ /* No more need to free the half-filled-in structures. */
+ set_opaque_ptr (wv_closure, 0);
+ unbind_to (count, Qnil);
+
+ return control;
+}
/* This is a kludge to make sure emacs can only link against a version of
lwlib that was compiled in the right way. Emacs references symbols which
#elif defined (HAVE_DIALOGS)
MACROLET (lwlib_dialogs_athena);
#endif
+#ifdef LWLIB_WIDGETS_MOTIF
+ MACROLET (lwlib_widgets_motif);
+#elif defined (HAVE_WIDGETS)
+ MACROLET (lwlib_widgets_athena);
+#endif
#undef MACROLET
}
}
void
-vars_of_gui_x (void)
+reinit_vars_of_gui_x (void)
{
lwlib_id_tick = (1<<16); /* start big, to not conflict with Energize */
-
+#ifdef HAVE_POPUPS
popup_up_p = 0;
+#endif
+
+ /* this makes only safe calls as in emacs.c */
+ sanity_check_lwlib ();
+}
+
+void
+vars_of_gui_x (void)
+{
+ reinit_vars_of_gui_x ();
Vpopup_callbacks = Qnil;
staticpro (&Vpopup_callbacks);
*/ );
#endif
Fset (Qmenu_no_selection_hook, Qnil);
-
- /* this makes only safe calls as in emacs.c */
- sanity_check_lwlib ();
}
LWLIB_ID new_lwlib_id (void);
-#ifdef HAVE_POPUPS
-
/* Each frame has one of these, and they are also contained in
Vpopup_callbacks.
It doesn't really need to be an lrecord (it's not lisp-accessible)
#define XPOPUP_DATA(x) XRECORD (x, popup_data, struct popup_data)
#define XSETPOPUP_DATA(x, p) XSETRECORD (x, p, popup_data)
#define POPUP_DATAP(x) RECORDP (x, popup_data)
-#define GC_POPUP_DATAP(x) GC_RECORDP (x, popup_data)
#define CHECK_POPUP_DATA(x) CHECK_RECORD (x, popup_data)
void gcpro_popup_callbacks (LWLIB_ID id);
XtPointer client_data);
int button_item_to_widget_value (Lisp_Object desc, widget_value *wv,
int allow_text_field_p, int no_keys_p);
+widget_value * gui_items_to_widget_values (Lisp_Object items);
Lisp_Object menu_name_to_accelerator (char *name);
char *menu_separator_style (CONST char *s);
Lisp_Object widget_value_unwind (Lisp_Object closure);
-#endif /* HAVE_POPUPS */
-
#endif /* _XEMACS_XLWLIB_H_ */
Lisp_Object Q_accelerator, Q_label, Q_callback;
Lisp_Object Qtoggle, Qradio;
+static Lisp_Object parse_gui_item_tree_list (Lisp_Object list);
+
#ifdef HAVE_POPUPS
/* count of menus/dboxes currently up */
}
Lisp_Object
-allocate_gui_item ()
+allocate_gui_item (void)
{
struct Lisp_Gui_Item *lp =
alloc_lcrecord_type (struct Lisp_Gui_Item, &lrecord_gui_item);
gui_item_display_flush_left (Lisp_Object gui_item,
char* buf, Bytecount buf_len)
{
+ /* This function can call lisp */
char *p = buf;
Bytecount len;
struct Lisp_Gui_Item* pgui_item = XGUI_ITEM (gui_item);
#endif /* HAVE_WINDOW_SYSTEM */
static Lisp_Object
-mark_gui_item (Lisp_Object obj, void (*markobj) (Lisp_Object))
+mark_gui_item (Lisp_Object obj)
{
struct Lisp_Gui_Item *p = XGUI_ITEM (obj);
- markobj (p->name);
- markobj (p->callback);
- markobj (p->config);
- markobj (p->suffix);
- markobj (p->active);
- markobj (p->included);
- markobj (p->config);
- markobj (p->filter);
- markobj (p->style);
- markobj (p->selected);
- markobj (p->keys);
- markobj (p->accelerator);
+ mark_object (p->name);
+ mark_object (p->callback);
+ mark_object (p->config);
+ mark_object (p->suffix);
+ mark_object (p->active);
+ mark_object (p->included);
+ mark_object (p->config);
+ mark_object (p->filter);
+ mark_object (p->style);
+ mark_object (p->selected);
+ mark_object (p->keys);
+ mark_object (p->accelerator);
return Qnil;
}
write_c_string (buf, printcharfun);
}
+/* parse a glyph descriptor into a tree of gui items.
+
+ The gui_item slot of an image instance can be a single item or an
+ arbitrarily nested hierarchy of item lists. */
+
+static Lisp_Object parse_gui_item_tree_item (Lisp_Object entry)
+{
+ Lisp_Object ret = entry;
+ if (VECTORP (entry))
+ {
+ ret = gui_parse_item_keywords_no_errors (entry);
+ }
+ else if (STRINGP (entry))
+ {
+ CHECK_STRING (entry);
+ }
+ else
+ signal_simple_error ("item must be a vector or a string", entry);
+
+ return ret;
+}
+
+Lisp_Object parse_gui_item_tree_children (Lisp_Object list)
+{
+ Lisp_Object rest, ret = Qnil;
+ CHECK_CONS (list);
+ /* recursively add items to the tree view */
+ LIST_LOOP (rest, list)
+ {
+ Lisp_Object sub;
+ if (CONSP (XCAR (rest)))
+ sub = parse_gui_item_tree_list (XCAR (rest));
+ else
+ sub = parse_gui_item_tree_item (XCAR (rest));
+
+ ret = Fcons (sub, ret);
+ }
+ /* make the order the same as the items we have parsed */
+ return Fnreverse (ret);
+}
+
+static Lisp_Object parse_gui_item_tree_list (Lisp_Object list)
+{
+ Lisp_Object ret;
+ CHECK_CONS (list);
+ /* first one can never be a list */
+ ret = parse_gui_item_tree_item (XCAR (list));
+ return Fcons (ret, parse_gui_item_tree_children (XCDR (list)));
+}
+
DEFINE_LRECORD_IMPLEMENTATION ("gui-item", gui_item,
mark_gui_item, print_gui_item,
0, gui_item_equal,
XRECORD (x, gui_item, struct Lisp_Gui_Item)
#define XSETGUI_ITEM(x, p) XSETRECORD (x, p, gui_item)
#define GUI_ITEMP(x) RECORDP (x, gui_item)
-#define GC_GUI_ITEMP(x) GC_RECORDP (x, gui_item)
#define CHECK_GUI_ITEM(x) CHECK_RECORD (x, gui_item)
#define CONCHECK_GUI_ITEM(x) CONCHECK_RECORD (x, gui_item)
unsigned int gui_item_display_flush_right (Lisp_Object gui_item,
char* buf, Bytecount buf_len);
-Lisp_Object allocate_gui_item ();
+Lisp_Object allocate_gui_item (void);
void gui_item_init (Lisp_Object gui_item);
+Lisp_Object parse_gui_item_tree_children (Lisp_Object list);
/* this is mswindows biased but reasonably safe I think */
#define GUI_ITEM_ID_SLOTS 8
/* Synched up with: Not in FSF. */
-/* Specifers ripped-off from toolbar.c */
+/* written by Andy Piper <andy@xemacs.org> with specifiers partially
+ ripped-off from toolbar.c */
#include <config.h>
#include "lisp.h"
Lisp_Object Vdefault_gutter_position;
-#define SET_GUTTER_WAS_VISIBLE_FLAG(frame, pos, flag) \
- do { \
- switch (pos) \
- { \
- case TOP_GUTTER: \
- (frame)->top_gutter_was_visible = flag; \
- break; \
- case BOTTOM_GUTTER: \
- (frame)->bottom_gutter_was_visible = flag; \
- break; \
- case LEFT_GUTTER: \
- (frame)->left_gutter_was_visible = flag; \
- break; \
- case RIGHT_GUTTER: \
- (frame)->right_gutter_was_visible = flag; \
- break; \
- default: \
- abort (); \
- } \
+Lisp_Object Qgutter_size;
+
+#define SET_GUTTER_WAS_VISIBLE_FLAG(frame, pos, flag) \
+ do { \
+ switch (pos) \
+ { \
+ case TOP_GUTTER: \
+ (frame)->top_gutter_was_visible = flag; \
+ break; \
+ case BOTTOM_GUTTER: \
+ (frame)->bottom_gutter_was_visible = flag; \
+ break; \
+ case LEFT_GUTTER: \
+ (frame)->left_gutter_was_visible = flag; \
+ break; \
+ case RIGHT_GUTTER: \
+ (frame)->right_gutter_was_visible = flag; \
+ break; \
+ default: \
+ abort (); \
+ } \
} while (0)
static int gutter_was_visible (struct frame* frame, enum gutter_pos pos)
switch (pos)
{
case TOP_GUTTER:
- return (frame)->top_gutter_was_visible;
+ return frame->top_gutter_was_visible;
case BOTTOM_GUTTER:
- return (frame)->bottom_gutter_was_visible;
+ return frame->bottom_gutter_was_visible;
case LEFT_GUTTER:
- return (frame)->left_gutter_was_visible;
+ return frame->left_gutter_was_visible;
case RIGHT_GUTTER:
- return (frame)->right_gutter_was_visible;
+ return frame->right_gutter_was_visible;
default:
abort ();
}
use this for calculating the gutter positions we run into trouble
if it is not the window nearest the gutter. Instead we predetermine
the nearest window and then use that.*/
-void
+static void
get_gutter_coords (struct frame *f, enum gutter_pos pos, int *x, int *y,
int *width, int *height)
{
face_index findex = get_builtin_face_cache_index (w, Vgui_element_face);
display_line_dynarr* ddla, *cdla;
struct display_line *dl;
+ int cdla_len;
if (!f->current_display_lines)
f->current_display_lines = Dynarr_new (display_line);
if (!f->desired_display_lines)
f->desired_display_lines = Dynarr_new (display_line);
-
+
ddla = f->desired_display_lines;
cdla = f->current_display_lines;
+ cdla_len = Dynarr_length (cdla);
XSETFRAME (frame, f);
get_gutter_coords (f, pos, &x, &y, &width, &height);
- /* clear out what we want to cover */
/* generate some display lines */
generate_displayable_area (w, WINDOW_GUTTER (w, pos),
x + border_width, y + border_width,
output_display_line (w, cdla, ddla, line, -1, -1);
}
+ /* If the number of display lines has shrunk, adjust. */
+ if (cdla_len > Dynarr_length (ddla))
+ {
+ Dynarr_length (cdla) = Dynarr_length (ddla);
+ }
+
/* grab coordinates of last line and blank after it. */
dl = Dynarr_atp (ddla, Dynarr_length (ddla) - 1);
ypos = dl->ypos + dl->descent - dl->clip;
redisplay_clear_region (window, findex, x + border_width , ypos,
- width - 2 * border_width, height - (ypos - y));
-
+ width - 2 * border_width, height - (ypos - y) - border_width);
/* bevel the gutter area if so desired */
if (border_width != 0)
{
MAYBE_DEVMETH (d, bevel_area,
- (w, findex, x, y, width, height, border_width));
+ (w, findex, x, y, width, height, border_width,
+ EDGE_ALL, EDGE_BEVEL_OUT));
}
}
/* sizing gutters is a pain so we try and help the user by detemining
- what height will accomodate all lines. This is useless on left and
+ what height will accommodate all lines. This is useless on left and
right gutters as we always have a maximal number of lines. */
static Lisp_Object
calculate_gutter_size (struct window *w, enum gutter_pos pos)
/* degenerate case */
if (NILP (WINDOW_GUTTER (w, pos))
||
- !FRAME_VISIBLE_P (f))
+ !FRAME_VISIBLE_P (f)
+ ||
+ NILP (w->buffer))
return Qnil;
ddla = Dynarr_new (display_line);
{
dl = Dynarr_atp (ddla, Dynarr_length (ddla) - 1);
ypos = dl->ypos + dl->descent - dl->clip;
- Dynarr_free (ddla);
+ free_display_lines (ddla);
return make_int (ypos);
}
else
{
- Dynarr_free (ddla);
+ free_display_lines (ddla);
return Qnil;
}
}
void
update_frame_gutters (struct frame *f)
{
- if (f->gutter_changed || f->frame_changed || f->clear)
+ if (f->gutter_changed || f->clear ||
+ f->glyphs_changed || f->subwindows_changed ||
+ f->windows_changed || f->windows_structure_changed ||
+ f->extents_changed || f->faces_changed)
{
- int pos;
- /* and output */
+ enum gutter_pos pos;
+
+ /* We don't actually care about these when outputting the gutter
+ so locally disable them. */
+ int local_clip_changed = f->clip_changed;
+ int local_buffers_changed = f->buffers_changed;
+ f->clip_changed = 0;
+ f->buffers_changed = 0;
- for (pos = 0; pos < 4; pos++)
+ /* and output */
+ GUTTER_POS_LOOP (pos)
{
if (FRAME_GUTTER_VISIBLE (f, pos))
- output_gutter (f, pos);
+ output_gutter (f, pos);
else if (gutter_was_visible (f, pos))
clear_gutter (f, pos);
}
-
+ f->clip_changed = local_clip_changed;
+ f->buffers_changed = local_buffers_changed;
+ f->gutter_changed = 0;
}
- f->gutter_changed = 0;
+}
+
+void
+reset_gutter_display_lines (struct frame* f)
+{
+ if (f->current_display_lines)
+ Dynarr_reset (f->current_display_lines);
}
static void
int width, int height)
{
int g_x, g_y, g_width, g_height;
- int newx, newy;
get_gutter_coords (f, pos, &g_x, &g_y, &g_width, &g_height);
- if (((y + height) < g_y) || (y > (g_y + g_height)))
+ if (((y + height) < g_y) || (y > (g_y + g_height)) || !height || !width || !g_height || !g_width)
return;
if (((x + width) < g_x) || (x > (g_x + g_width)))
return;
/* #### optimize this - redrawing the whole gutter for every expose
is very expensive. We reset the current display lines because if
they're being exposed they are no longer current. */
- if (f->current_display_lines)
- Dynarr_reset (f->current_display_lines);
- /* we have to do this in-case there were subwindows where we are
- redrawing, unfortunately sometimes this also generates expose
- events resulting in an endless cycle of redsplay. */
- newx = max (x, g_x);
- newy = max (y, g_y);
- width = min (x + width - newx, g_x + g_width - newx);
- height = min (y + height - newy, g_y + g_height - newy);
- redisplay_unmap_subwindows_maybe (f, newx, newy, width, height);
+ reset_gutter_display_lines (f);
/* Even if none of the gutter is in the area, the blank region at
the very least must be because the first thing we did is verify
redraw_exposed_gutters (struct frame *f, int x, int y, int width,
int height)
{
- int pos;
- for (pos = 0; pos < 4; pos++)
- {
- if (FRAME_GUTTER_VISIBLE (f, pos))
- redraw_exposed_gutter (f, pos, x, y, width, height);
- }
+ enum gutter_pos pos;
+ GUTTER_POS_LOOP (pos)
+ {
+ if (FRAME_GUTTER_VISIBLE (f, pos))
+ redraw_exposed_gutter (f, pos, x, y, width, height);
+ }
}
void
free_frame_gutters (struct frame *f)
{
if (f->current_display_lines)
- Dynarr_free (f->current_display_lines);
+ {
+ free_display_lines (f->current_display_lines);
+ f->current_display_lines = 0;
+ }
if (f->desired_display_lines)
- Dynarr_free (f->desired_display_lines);
+ {
+ free_display_lines (f->desired_display_lines);
+ f->desired_display_lines = 0;
+ }
}
static enum gutter_pos
gutter_specs_changed (Lisp_Object specifier, struct window *w,
Lisp_Object oldval)
{
- int pos;
- for (pos = 0; pos< 4; pos++)
+ enum gutter_pos pos;
+ GUTTER_POS_LOOP (pos)
{
w->real_gutter_size[pos] = w->gutter_size[pos];
if (EQ (w->real_gutter_size[pos], Qautodetect)
gutter_geometry_changed_in_window (Lisp_Object specifier, struct window *w,
Lisp_Object oldval)
{
- int pos;
- for (pos = 0; pos< 4; pos++)
+ enum gutter_pos pos;
+ GUTTER_POS_LOOP (pos)
{
w->real_gutter_size[pos] = w->gutter_size[pos];
if (EQ (w->real_gutter_size[pos], Qautodetect)
recompute_overlaying_specifier (Vgutter_visible_p);
}
+
+DECLARE_SPECIFIER_TYPE (gutter_size);
+#define GUTTER_SIZE_SPECIFIERP(x) SPECIFIER_TYPEP (x, gutter_size)
+DEFINE_SPECIFIER_TYPE (gutter_size);
+
+static void
+gutter_size_validate (Lisp_Object instantiator)
+{
+ if (NILP (instantiator))
+ return;
+
+ if (!INTP (instantiator) && !EQ (instantiator, Qautodetect))
+ signal_simple_error ("Gutter size must be an integer or 'autodetect", instantiator);
+}
+
+DEFUN ("gutter-size-specifier-p", Fgutter_size_specifier_p, 1, 1, 0, /*
+Return non-nil if OBJECT is a gutter-size specifier.
+*/
+ (object))
+{
+ return GUTTER_SIZE_SPECIFIERP (object) ? Qt : Qnil;
+}
+
+DEFUN ("redisplay-gutter-area", Fredisplay_gutter_area, 0, 0, 0, /*
+Ensure that all gutters are correctly showing their gutter specifier.
+*/
+ ())
+{
+ Lisp_Object devcons, concons;
+
+ DEVICE_LOOP_NO_BREAK (devcons, concons)
+ {
+ struct device *d = XDEVICE (XCAR (devcons));
+ Lisp_Object frmcons;
+
+ DEVICE_FRAME_LOOP (frmcons, d)
+ {
+ struct frame *f = XFRAME (XCAR (frmcons));
+
+ if (FRAME_REPAINT_P (f))
+ {
+ update_frame_gutters (f);
+ }
+ }
+
+ /* We now call the output_end routine for tty frames. We delay
+ doing so in order to avoid cursor flicker. So much for 100%
+ encapsulation. */
+ if (DEVICE_TTY_P (d))
+ DEVMETH (d, output_end, (d));
+ }
+
+ return Qnil;
+}
+
void
init_frame_gutters (struct frame *f)
{
- int pos;
+ enum gutter_pos pos;
struct window* w = XWINDOW (FRAME_LAST_NONMINIBUF_WINDOW (f));
/* We are here as far in frame creation so cached specifiers are
already recomputed, and possibly modified by resource
initialization. We need to recalculate autodetected gutters. */
- for (pos = 0; pos< 4; pos++)
+ GUTTER_POS_LOOP (pos)
{
w->real_gutter_size[pos] = w->gutter_size[pos];
if (EQ (w->gutter_size[pos], Qautodetect)
syms_of_gutter (void)
{
DEFSUBR (Fgutter_specifier_p);
+ DEFSUBR (Fgutter_size_specifier_p);
DEFSUBR (Fset_default_gutter_position);
DEFSUBR (Fdefault_gutter_position);
DEFSUBR (Fgutter_pixel_height);
DEFSUBR (Fgutter_pixel_width);
+ DEFSUBR (Fredisplay_gutter_area);
+
+ defsymbol (&Qgutter_size, "gutter-size");
}
void
SPECIFIER_HAS_METHOD (gutter, validate);
SPECIFIER_HAS_METHOD (gutter, after_change);
+
+ INITIALIZE_SPECIFIER_TYPE (gutter_size, "gutter-size", "gutter-size-specifier-p");
+
+ SPECIFIER_HAS_METHOD (gutter_size, validate);
+}
+
+void
+reinit_specifier_type_create_gutter (void)
+{
+ REINITIALIZE_SPECIFIER_TYPE (gutter);
+ REINITIALIZE_SPECIFIER_TYPE (gutter_size);
}
void
calculated to be large enough to hold the contents of the gutter. This
is the default.
*/ );
- Vdefault_gutter_height = Fmake_specifier (Qgeneric);
+ Vdefault_gutter_height = Fmake_specifier (Qgutter_size);
set_specifier_caching (Vdefault_gutter_height,
slot_offset (struct window,
default_gutter_height),
See `default-gutter-height' for more information.
*/ );
- Vgutter_size[TOP_GUTTER] = Fmake_specifier (Qgeneric);
+ Vgutter_size[TOP_GUTTER] = Fmake_specifier (Qgutter_size);
set_specifier_caching (Vgutter_size[TOP_GUTTER],
slot_offset (struct window,
gutter_size[TOP_GUTTER]),
See `default-gutter-height' for more information.
*/ );
- Vgutter_size[BOTTOM_GUTTER] = Fmake_specifier (Qgeneric);
+ Vgutter_size[BOTTOM_GUTTER] = Fmake_specifier (Qgutter_size);
set_specifier_caching (Vgutter_size[BOTTOM_GUTTER],
slot_offset (struct window,
gutter_size[BOTTOM_GUTTER]),
enum gutter_pos
{
- TOP_GUTTER,
- BOTTOM_GUTTER,
- LEFT_GUTTER,
- RIGHT_GUTTER
+ TOP_GUTTER = 0,
+ BOTTOM_GUTTER = 1,
+ LEFT_GUTTER = 2,
+ RIGHT_GUTTER = 3
};
+/* Iterate over all possible gutter positions */
+#define GUTTER_POS_LOOP(var) \
+for (var = (enum gutter_pos) 0; var < 4; var = (enum gutter_pos) (var + 1))
+
extern Lisp_Object Qgutter;
extern Lisp_Object Vgutter_size[4];
void free_frame_gutters (struct frame *f);
void redraw_exposed_gutters (struct frame *f, int x, int y, int width,
int height);
+void reset_gutter_display_lines (struct frame* f);
#define WINDOW_GUTTER_BORDER_WIDTH(w, pos) \
(NILP ((w)->gutter_border_width[pos]) ? 0 : XINT ((w)->gutter_border_width[pos]))
static void
IMDestroyCallback (XIM im, XPointer client_data, XPointer call_data)
{
- struct frame *f = (struct frame *)client_data;
- struct device *d = XDEVICE (FRAME_DEVICE ((struct frame *)client_data));
- Lisp_Object frame_list = DEVICE_FRAME_LIST (XDEVICE (FRAME_DEVICE (f)));
+ struct frame *f = (struct frame *) client_data;
+ struct device *d = XDEVICE (FRAME_DEVICE (f));
Lisp_Object tail;
- struct frame *target_frame = NULL;
- LIST_LOOP (tail, frame_list)
+ DEVICE_FRAME_LOOP (tail, d)
{
- if (target_frame = XFRAME (XCAR (tail)))
+ struct frame *target_frame = XFRAME (XCAR (tail));
+ if (FRAME_X_XIC (target_frame))
{
- if ( FRAME_X_XIC(target_frame) )
- {
- XDestroyIC (FRAME_X_XIC(target_frame));
- FRAME_X_XIC (target_frame) = NULL;
- }
+ XDestroyIC (FRAME_X_XIC (target_frame));
+ FRAME_X_XIC (target_frame) = NULL;
}
}
static void
IMInstantiateCallback (Display *dpy, XPointer client_data, XPointer call_data)
{
- struct frame *f = (struct frame *)client_data;
- struct device *d = XDEVICE (FRAME_DEVICE ((struct frame *)client_data));
+ struct frame *f = (struct frame *) client_data;
+ struct device *d = XDEVICE (FRAME_DEVICE (f));
XIM xim;
- Widget w = FRAME_X_TEXT_WIDGET ((struct frame *)client_data);
+ Widget w = FRAME_X_TEXT_WIDGET (f);
Window win = XtWindow (w);
XRectangle p_area = {0,0,1,1}, s_area = {0,0,1,1};
XPoint spot = {0,0};
/* destroy callback for im */
ximcallback.callback = IMDestroyCallback;
- ximcallback.client_data = (XPointer)f;
+ ximcallback.client_data = (XPointer) f;
XSetIMValues (xim, XNDestroyCallback, &ximcallback, NULL);
}
else
static void
XIM_delete_frame (Widget w, XtPointer client_data, XtPointer call_data)
{
- struct frame *f = (struct frame *)client_data;
- struct device *d = XDEVICE (FRAME_DEVICE ((struct frame *)client_data));
+ struct frame *f = (struct frame *) client_data;
+ struct device *d = XDEVICE (FRAME_DEVICE (f));
Display *dpy = DEVICE_X_DISPLAY (d);
XUnregisterIMInstantiateCallback (dpy, NULL, NULL, NULL,
- IMInstantiateCallback, (XtPointer)f);
+ IMInstantiateCallback, (XPointer) f);
- if ( FRAME_X_XIC (f) )
+ if (FRAME_X_XIC (f))
{
- XDestroyIC (FRAME_X_XIC(f));
+ XDestroyIC (FRAME_X_XIC (f));
FRAME_X_XIC (f) = NULL;
}
return;
struct device *d = XDEVICE (FRAME_DEVICE (f));
XRegisterIMInstantiateCallback (DEVICE_X_DISPLAY (d), NULL, NULL, NULL,
- IMInstantiateCallback, (XtPointer)f);
+ IMInstantiateCallback, (XPointer) f);
#if 0
if ( FRAME_X_XIC (f) )
/************************************************************************/
void
-vars_of_insdel (void)
+reinit_vars_of_insdel (void)
{
int i;
}
void
+vars_of_insdel (void)
+{
+ reinit_vars_of_insdel ();
+}
+
+void
init_buffer_text (struct buffer *b)
{
if (!b->base_buffer)
/************************************************************************/
Memind do_marker_adjustment (Memind mpos, Memind from,
- Memind to, int amount);
+ Memind to, Bytecount amount);
void fixup_internal_substring (CONST Bufbyte *nonreloc,
Lisp_Object reloc,
- int offset, int *len);
+ Bytecount offset, Bytecount *len);
/* In font-lock.c */
void font_lock_maybe_update_syntactic_caches (struct buffer *buf,
#endif /* I18N4 */
-Lisp_Object Qdomain;
Lisp_Object Qdefer_gettext;
DEFUN ("ignore-defer-gettext", Fignore_defer_gettext, 1, 1, 0, /*
{
CHECK_STRING (domain_name);
if (load_in_progress)
- {
-#ifdef I18N3
- Vfile_domain = Fpurecopy (domain_name);
- return Vfile_domain;
-#else
- return (domain_name);
-#endif
- }
+ return (domain_name);
else
return Qnil;
}
void
syms_of_intl (void)
{
- defsymbol (&Qdomain, "domain");
-
/* defer-gettext is defined as a symbol because when it is used in menu
specification strings, it is not evaluated as a function by
menu_item_descriptor_to_widget_value(). */
/************************************************************************/
static Lisp_Object
-mark_keymap (Lisp_Object obj, void (*markobj) (Lisp_Object))
+mark_keymap (Lisp_Object obj)
{
Lisp_Keymap *keymap = XKEYMAP (obj);
- markobj (keymap->parents);
- markobj (keymap->prompt);
- markobj (keymap->inverse_table);
- markobj (keymap->sub_maps_cache);
- markobj (keymap->default_binding);
- markobj (keymap->name);
+ mark_object (keymap->parents);
+ mark_object (keymap->prompt);
+ mark_object (keymap->inverse_table);
+ mark_object (keymap->sub_maps_cache);
+ mark_object (keymap->default_binding);
+ mark_object (keymap->name);
return keymap->table;
}
print_internal (keymap->name, printcharfun, 1);
/* #### Yuck! This is no way to form plural! --hniksic */
sprintf (buf, "%s%d entr%s 0x%x>",
- ((NILP (keymap->name)) ? "" : " "),
+ (NILP (keymap->name) ? "" : " "),
size,
((size == 1) ? "y" : "ies"),
keymap->header.uid);
*keysym = QKescape;
else if (EQ (*keysym, QDEL))
*keysym = QKdelete;
+ else if (EQ (*keysym, QSPC))
+ *keysym = QKspace;
else if (EQ (*keysym, QBS))
*keysym = QKbackspace;
/* Emacs compatibility */
for (i = 0; i < size; i++)
{
Lisp_Object s2 = Fsingle_key_description
- (((STRINGP (keys))
- ? make_char (string_char (XSTRING (keys), i))
- : XVECTOR_DATA (keys)[i]));
+ (STRINGP (keys)
+ ? make_char (string_char (XSTRING (keys), i))
+ : XVECTOR_DATA (keys)[i]);
if (i == 0)
string = s2;
for (;;) /* loop over all keys that match */
{
- Lisp_Object k = ((CONSP (keys)) ? XCAR (keys) : keys);
+ Lisp_Object k = CONSP (keys) ? XCAR (keys) : keys;
int i;
so_far [keys_count].keysym = k;
defsymbol (&QRET, "RET");
defsymbol (&QESC, "ESC");
defsymbol (&QDEL, "DEL");
+ defsymbol (&QSPC, "SPC");
defsymbol (&QBS, "BS");
}
staticpro (&Vcurrent_global_map);
- Vsingle_space_string = make_string_nocopy ((CONST Bufbyte *) " ", 1);
+ Vsingle_space_string = make_string ((CONST Bufbyte *) " ", 1);
staticpro (&Vsingle_space_string);
}
#define XKEYMAP(x) XRECORD (x, keymap, struct Lisp_Keymap)
#define XSETKEYMAP(x, p) XSETRECORD (x, p, keymap)
#define KEYMAPP(x) RECORDP (x, keymap)
-#define GC_KEYMAPP(x) GC_RECORDP (x, keymap)
#define CHECK_KEYMAP(x) CHECK_RECORD (x, keymap)
#define CONCHECK_KEYMAP(x) CONCHECK_RECORD (x, keymap)
/* Use a global buffer as scratch-pad for possible conversions of the
sampling format */
-unsigned char linuxplay_sndbuf[SNDBUFSZ];
+static unsigned char linuxplay_sndbuf[SNDBUFSZ];
static int mix_fd;
static int audio_vol;
XUINT The value bits of a Lisp_Object storing an integer, unsigned
INTP Non-zero if this Lisp_Object an integer?
Qzero Lisp Integer 0
- EQ Non-zero if two Lisp_Objects are identical
- GC_EQ Version of EQ used during garbage collection */
+ EQ Non-zero if two Lisp_Objects are identical */
+
typedef EMACS_INT Lisp_Object;
#define XTYPE(x) ((enum Lisp_Type) (((EMACS_UINT)(x)) & ~VALMASK))
#define XPNTRVAL(x) (x) /* This depends on Lisp_Type_Record == 0 */
#define XCHARVAL(x) ((x) >> GCBITS)
-#define GC_EQ(x,y) EQ (x,y)
#define XREALINT(x) ((x) >> INT_GCBITS)
#define XUINT(x) ((EMACS_UINT)(x) >> INT_GCBITS)
#define INTP(x) ((EMACS_UINT)(x) & Lisp_Type_Int_Bit)
+#define INT_PLUS(x,y) ((x)+(y)-Lisp_Type_Int_Bit)
+#define INT_MINUS(x,y) ((x)-(y)+Lisp_Type_Int_Bit)
+#define INT_PLUS1(x) INT_PLUS (x, make_int (1))
+#define INT_MINUS1(x) INT_MINUS (x, make_int (1))
#define Qzero make_int (0)
#define Qnull_pointer ((Lisp_Object) 0)
-#define XGCTYPE(x) XTYPE(x)
#define EQ(x,y) ((x) == (y))
#define XSETINT(var, value) ((void) ((var) = make_int (value)))
#define XSETCHAR(var, value) ((void) ((var) = make_char (value)))
#define XREALINT(x) ((x).s.val)
#define XUINT(x) ((x).u.val)
#define XTYPE(x) ((x).gu.type)
-#define XGCTYPE(x) XTYPE (x)
#define EQ(x,y) ((x).v == (y).v)
#define INTP(x) ((x).s.bits)
-#define GC_EQ(x,y) EQ (x, y)
+#define INT_PLUS(x,y) make_int (XINT (x) + XINT (y))
+#define INT_MINUS(x,y) make_int (XINT (x) - XINT (y))
+#define INT_PLUS1(x) make_int (XINT (x) + 1)
+#define INT_MINUS1(x) make_int (XINT (x) - 1)
/* Convert between a (void *) and a Lisp_Object, as when the
Lisp_Object is passed to a toolkit callback function */
/*#define REGISTER register*/
/*#endif*/
+
+/* EMACS_INT is the underlying integral type into which a Lisp_Object must fit.
+ In particular, it must be large enough to contain a pointer.
+ config.h can override this, e.g. to use `long long' for bigger lisp ints. */
+
+#ifndef SIZEOF_EMACS_INT
+# define SIZEOF_EMACS_INT SIZEOF_VOID_P
+#endif
+
+#ifndef EMACS_INT
+# if SIZEOF_EMACS_INT == SIZEOF_LONG
+# define EMACS_INT long
+# elif SIZEOF_EMACS_INT == SIZEOF_INT
+# define EMACS_INT int
+# elif SIZEOF_EMACS_INT == SIZEOF_LONG_LONG
+# define EMACS_INT long long
+# else
+# error Unable to determine suitable type for EMACS_INT
+# endif
+#endif
+
+#ifndef EMACS_UINT
+# define EMACS_UINT unsigned EMACS_INT
+#endif
+
+#define BITS_PER_EMACS_INT (SIZEOF_EMACS_INT * BITS_PER_CHAR)
+
\f
/************************************************************************/
/* typedefs */
buffer.h (where they rightfully belong) to avoid syntax errors
in function prototypes. */
-typedef int Bufpos;
-typedef int Bytind;
-typedef int Memind;
+typedef EMACS_INT Bufpos;
+typedef EMACS_INT Bytind;
+typedef EMACS_INT Memind;
/* Counts of bytes or chars */
-typedef int Bytecount;
-typedef int Charcount;
+typedef EMACS_INT Bytecount;
+typedef EMACS_INT Charcount;
/* Length in bytes of a string in external format */
-typedef int Extcount;
+typedef EMACS_INT Extcount;
typedef struct lstream Lstream;
struct Lisp_Gui_Item;
typedef struct Lisp_Gui_Item Lisp_Gui_Item;
struct display_line;
+struct display_glyph_area;
+struct display_box;
struct redisplay_info;
struct window_mirror;
struct scrollbar_instance;
};
#endif
+enum edge_style
+{
+ EDGE_ETCHED_IN,
+ EDGE_ETCHED_OUT,
+ EDGE_BEVEL_IN,
+ EDGE_BEVEL_OUT
+};
+
#ifndef ERROR_CHECK_TYPECHECK
typedef enum error_behavior
#define POINTER_TYPE_P(type) ((type) == Lisp_Type_Record)
-/* EMACS_INT is the underlying integral type into which a Lisp_Object must fit.
- In particular, it must be large enough to contain a pointer.
- config.h can override this, e.g. to use `long long' for bigger lisp ints. */
-
-#ifndef SIZEOF_EMACS_INT
-# define SIZEOF_EMACS_INT SIZEOF_VOID_P
-#endif
-
-#ifndef EMACS_INT
-# if SIZEOF_EMACS_INT == SIZEOF_LONG
-# define EMACS_INT long
-# elif SIZEOF_EMACS_INT == SIZEOF_INT
-# define EMACS_INT int
-# elif SIZEOF_EMACS_INT == SIZEOF_LONG_LONG
-# define EMACS_INT long long
-# else
-# error Unable to determine suitable type for EMACS_INT
-# endif
-#endif
-
-#ifndef EMACS_UINT
-# define EMACS_UINT unsigned EMACS_INT
-#endif
-
-#define BITS_PER_EMACS_INT (SIZEOF_EMACS_INT * BITS_PER_CHAR)
-
/* Overridden by m/next.h */
#ifndef ASSERT_VALID_POINTER
# define ASSERT_VALID_POINTER(pnt) (assert ((((EMACS_UINT) pnt) & 3) == 0))
# include "lisp-disunion.h"
#endif /* !USE_UNION_TYPE */
-#define XPNTR(x) ((void *) (XPNTRVAL(x)))
+#define XPNTR(x) ((void *) XPNTRVAL(x))
/* WARNING WARNING WARNING. You must ensure on your own that proper
GC protection is provided for the elements in this array. */
/* Close your eyes now lest you vomit or spontaneously combust ... */
#define HACKEQ_UNSAFE(obj1, obj2) \
- (EQ (obj1, obj2) || (!POINTER_TYPE_P (XGCTYPE (obj1)) \
- && !POINTER_TYPE_P (XGCTYPE (obj2)) \
+ (EQ (obj1, obj2) || (!POINTER_TYPE_P (XTYPE (obj1)) \
+ && !POINTER_TYPE_P (XTYPE (obj2)) \
&& XCHAR_OR_INT (obj1) == XCHAR_OR_INT (obj2)))
#ifdef DEBUG_XEMACS
to mean "no such value". */
#define UNBOUNDP(val) EQ (val, Qunbound)
-#define GC_UNBOUNDP(val) GC_EQ (val, Qunbound)
/*********** cons ***********/
#define XCONS(x) XRECORD (x, cons, Lisp_Cons)
#define XSETCONS(x, p) XSETRECORD (x, p, cons)
#define CONSP(x) RECORDP (x, cons)
-#define GC_CONSP(x) GC_RECORDP (x, cons)
#define CHECK_CONS(x) CHECK_RECORD (x, cons)
#define CONCHECK_CONS(x) CONCHECK_RECORD (x, cons)
extern Lisp_Object Qnil;
#define NILP(x) EQ (x, Qnil)
-#define GC_NILP(x) GC_EQ (x, Qnil)
#define XCAR(a) (XCONS (a)->car)
#define XCDR(a) (XCONS (a)->cdr)
#define LISTP(x) (CONSP(x) || NILP(x))
#define EXTERNAL_LIST_LOOP_DELETE_IF(elt, list, condition) do { \
Lisp_Object prev_tail_##list = Qnil; \
Lisp_Object tail_##list; \
- int len_##list; \
+ EMACS_INT len_##list; \
EXTERNAL_LIST_LOOP_4 (elt, list, tail_##list, len_##list) \
{ \
if (condition) \
#define EXTERNAL_LIST_LOOP_1(list) \
Lisp_Object ELL1_elt, ELL1_hare, ELL1_tortoise; \
-int ELL1_len; \
-EXTERNAL_LIST_LOOP_6(ELL1_elt, list, ELL1_len, ELL1_hare, \
- ELL1_tortoise, CIRCULAR_LIST_SUSPICION_LENGTH)
+EMACS_INT ELL1_len; \
+EXTERNAL_LIST_LOOP_6 (ELL1_elt, list, ELL1_len, ELL1_hare, \
+ ELL1_tortoise, CIRCULAR_LIST_SUSPICION_LENGTH)
#define EXTERNAL_LIST_LOOP_2(elt, list) \
Lisp_Object hare_##elt, tortoise_##elt; \
-int len_##elt; \
-EXTERNAL_LIST_LOOP_6(elt, list, len_##elt, hare_##elt, \
- tortoise_##elt, CIRCULAR_LIST_SUSPICION_LENGTH)
+EMACS_INT len_##elt; \
+EXTERNAL_LIST_LOOP_6 (elt, list, len_##elt, hare_##elt, \
+ tortoise_##elt, CIRCULAR_LIST_SUSPICION_LENGTH)
#define EXTERNAL_LIST_LOOP_3(elt, list, tail) \
Lisp_Object tortoise_##elt; \
-int len_##elt; \
-EXTERNAL_LIST_LOOP_6(elt, list, len_##elt, tail, \
- tortoise_##elt, CIRCULAR_LIST_SUSPICION_LENGTH)
+EMACS_INT len_##elt; \
+EXTERNAL_LIST_LOOP_6 (elt, list, len_##elt, tail, \
+ tortoise_##elt, CIRCULAR_LIST_SUSPICION_LENGTH)
#define EXTERNAL_LIST_LOOP_4(elt, list, tail, len) \
Lisp_Object tortoise_##elt; \
-EXTERNAL_LIST_LOOP_6(elt, list, len, tail, \
- tortoise_##elt, CIRCULAR_LIST_SUSPICION_LENGTH)
+EXTERNAL_LIST_LOOP_6 (elt, list, len, tail, \
+ tortoise_##elt, CIRCULAR_LIST_SUSPICION_LENGTH)
#define EXTERNAL_LIST_LOOP_6(elt, list, len, hare, \
/* Optimized and safe macros for looping over external alists. */
-#define EXTERNAL_ALIST_LOOP_4(elt, elt_car, elt_cdr, list) \
-Lisp_Object hare_##elt, tortoise_##elt; \
-int len_##elt; \
-EXTERNAL_ALIST_LOOP_8 (elt, elt_car, elt_cdr, list, \
- len_##elt, hare_##elt, tortoise_##elt, \
+#define EXTERNAL_ALIST_LOOP_4(elt, elt_car, elt_cdr, list) \
+Lisp_Object hare_##elt, tortoise_##elt; \
+EMACS_INT len_##elt; \
+EXTERNAL_ALIST_LOOP_8 (elt, elt_car, elt_cdr, list, \
+ len_##elt, hare_##elt, tortoise_##elt, \
CIRCULAR_LIST_SUSPICION_LENGTH)
#define EXTERNAL_ALIST_LOOP_5(elt, elt_car, elt_cdr, list, tail) \
Lisp_Object tortoise_##elt; \
-int len_##elt; \
-EXTERNAL_ALIST_LOOP_8(elt, elt_car, elt_cdr, list, \
- len_##elt, tail, tortoise_##elt, \
- CIRCULAR_LIST_SUSPICION_LENGTH)
+EMACS_INT len_##elt; \
+EXTERNAL_ALIST_LOOP_8 (elt, elt_car, elt_cdr, list, \
+ len_##elt, tail, tortoise_##elt, \
+ CIRCULAR_LIST_SUSPICION_LENGTH) \
#define EXTERNAL_ALIST_LOOP_6(elt, elt_car, elt_cdr, list, tail, len) \
Lisp_Object tortoise_##elt; \
-EXTERNAL_ALIST_LOOP_8(elt, elt_car, elt_cdr, list, \
- len, tail, tortoise_##elt, \
- CIRCULAR_LIST_SUSPICION_LENGTH)
+EXTERNAL_ALIST_LOOP_8 (elt, elt_car, elt_cdr, list, \
+ len, tail, tortoise_##elt, \
+ CIRCULAR_LIST_SUSPICION_LENGTH)
#define EXTERNAL_ALIST_LOOP_8(elt, elt_car, elt_cdr, list, len, hare, \
tortoise, suspicion_length) \
-EXTERNAL_LIST_LOOP_6(elt, list, len, hare, tortoise, suspicion_length) \
+EXTERNAL_LIST_LOOP_6 (elt, list, len, hare, tortoise, suspicion_length) \
if (CONSP (elt) ? (elt_car = XCAR (elt), elt_cdr = XCDR (elt), 0) :1) \
continue; \
else
/* Optimized and safe macros for looping over external property lists. */
#define EXTERNAL_PROPERTY_LIST_LOOP_3(key, value, list) \
Lisp_Object key, value, hare_##key, tortoise_##key; \
-int len_##key; \
-EXTERNAL_PROPERTY_LIST_LOOP_7(key, value, list, len_##key, hare_##key,\
+EMACS_INT len_##key; \
+EXTERNAL_PROPERTY_LIST_LOOP_7 (key, value, list, len_##key, hare_##key, \
tortoise_##key, CIRCULAR_LIST_SUSPICION_LENGTH)
#define EXTERNAL_PROPERTY_LIST_LOOP_4(key, value, list, tail) \
Lisp_Object key, value, tail, tortoise_##key; \
-int len_##key; \
-EXTERNAL_PROPERTY_LIST_LOOP_7(key, value, list, len_##key, tail, \
+EMACS_INT len_##key; \
+EXTERNAL_PROPERTY_LIST_LOOP_7 (key, value, list, len_##key, tail, \
tortoise_##key, CIRCULAR_LIST_SUSPICION_LENGTH)
#define EXTERNAL_PROPERTY_LIST_LOOP_5(key, value, list, tail, len) \
Lisp_Object key, value, tail, tortoise_##key; \
-int len; \
-EXTERNAL_PROPERTY_LIST_LOOP_7(key, value, list, len, tail, \
+EMACS_INT len; \
+EXTERNAL_PROPERTY_LIST_LOOP_7 (key, value, list, len, tail, \
tortoise_##key, CIRCULAR_LIST_SUSPICION_LENGTH)
TRUE_LIST_P (Lisp_Object object)
{
Lisp_Object hare, tortoise;
- int len;
+ EMACS_INT len;
for (hare = tortoise = object, len = 0;
CONSP (hare);
#define CHECK_TRUE_LIST(list) do { \
Lisp_Object CTL_list = (list); \
Lisp_Object CTL_hare, CTL_tortoise; \
- int CTL_len; \
+ EMACS_INT CTL_len; \
\
for (CTL_hare = CTL_tortoise = CTL_list, CTL_len = 0; \
CONSP (CTL_hare); \
#define XSTRING(x) XRECORD (x, string, Lisp_String)
#define XSETSTRING(x, p) XSETRECORD (x, p, string)
#define STRINGP(x) RECORDP (x, string)
-#define GC_STRINGP(x) GC_RECORDP (x, string)
#define CHECK_STRING(x) CHECK_RECORD (x, string)
#define CONCHECK_STRING(x) CONCHECK_RECORD (x, string)
#define XVECTOR(x) XRECORD (x, vector, Lisp_Vector)
#define XSETVECTOR(x, p) XSETRECORD (x, p, vector)
#define VECTORP(x) RECORDP (x, vector)
-#define GC_VECTORP(x) GC_RECORDP (x, vector)
#define CHECK_VECTOR(x) CHECK_RECORD (x, vector)
#define CONCHECK_VECTOR(x) CONCHECK_RECORD (x, vector)
#define XBIT_VECTOR(x) XRECORD (x, bit_vector, Lisp_Bit_Vector)
#define XSETBIT_VECTOR(x, p) XSETRECORD (x, p, bit_vector)
#define BIT_VECTORP(x) RECORDP (x, bit_vector)
-#define GC_BIT_VECTORP(x) GC_RECORDP (x, bit_vector)
#define CHECK_BIT_VECTOR(x) CHECK_RECORD (x, bit_vector)
#define CONCHECK_BIT_VECTOR(x) CONCHECK_RECORD (x, bit_vector)
#define BITP(x) (INTP (x) && (XINT (x) == 0 || XINT (x) == 1))
-#define GC_BITP(x) (GC_INTP (x) && (XINT (x) == 0 || XINT (x) == 1))
#define CHECK_BIT(x) do { \
if (!BITP (x)) \
#define bit_vector_length(v) ((v)->size)
#define bit_vector_next(v) ((v)->next)
-INLINE int bit_vector_bit (Lisp_Bit_Vector *v, int i);
+INLINE int bit_vector_bit (Lisp_Bit_Vector *v, size_t n);
INLINE int
-bit_vector_bit (Lisp_Bit_Vector *v, int i)
+bit_vector_bit (Lisp_Bit_Vector *v, size_t n)
{
- unsigned int ui = (unsigned int) i;
-
- return (((v)->bits[ui >> LONGBITS_LOG2] >> (ui & (LONGBITS_POWER_OF_2 - 1)))
+ return ((v->bits[n >> LONGBITS_LOG2] >> (n & (LONGBITS_POWER_OF_2 - 1)))
& 1);
}
-INLINE void set_bit_vector_bit (Lisp_Bit_Vector *v, int i, int value);
+INLINE void set_bit_vector_bit (Lisp_Bit_Vector *v, size_t n, int value);
INLINE void
-set_bit_vector_bit (Lisp_Bit_Vector *v, int i, int value)
+set_bit_vector_bit (Lisp_Bit_Vector *v, size_t n, int value)
{
- unsigned int ui = (unsigned int) i;
if (value)
- (v)->bits[ui >> LONGBITS_LOG2] |= (1UL << (ui & (LONGBITS_POWER_OF_2 - 1)));
+ v->bits[n >> LONGBITS_LOG2] |= (1UL << (n & (LONGBITS_POWER_OF_2 - 1)));
else
- (v)->bits[ui >> LONGBITS_LOG2] &= ~(1UL << (ui & (LONGBITS_POWER_OF_2 - 1)));
+ v->bits[n >> LONGBITS_LOG2] &= ~(1UL << (n & (LONGBITS_POWER_OF_2 - 1)));
}
/* Number of longs required to hold LEN bits */
#define XSYMBOL(x) XRECORD (x, symbol, Lisp_Symbol)
#define XSETSYMBOL(x, p) XSETRECORD (x, p, symbol)
#define SYMBOLP(x) RECORDP (x, symbol)
-#define GC_SYMBOLP(x) GC_RECORDP (x, symbol)
#define CHECK_SYMBOL(x) CHECK_RECORD (x, symbol)
#define CONCHECK_SYMBOL(x) CONCHECK_RECORD (x, symbol)
#define XSUBR(x) XRECORD (x, subr, Lisp_Subr)
#define XSETSUBR(x, p) XSETRECORD (x, p, subr)
#define SUBRP(x) RECORDP (x, subr)
-#define GC_SUBRP(x) GC_RECORDP (x, subr)
#define CHECK_SUBR(x) CHECK_RECORD (x, subr)
#define CONCHECK_SUBR(x) CONCHECK_RECORD (x, subr)
#define XMARKER(x) XRECORD (x, marker, Lisp_Marker)
#define XSETMARKER(x, p) XSETRECORD (x, p, marker)
#define MARKERP(x) RECORDP (x, marker)
-#define GC_MARKERP(x) GC_RECORDP (x, marker)
#define CHECK_MARKER(x) CHECK_RECORD (x, marker)
#define CONCHECK_MARKER(x) CONCHECK_RECORD (x, marker)
/*********** char ***********/
#define CHARP(x) (XTYPE (x) == Lisp_Type_Char)
-#define GC_CHARP(x) (XGCTYPE (x) == Lisp_Type_Char)
#ifdef ERROR_CHECK_TYPECHECK
#define XFLOAT(x) XRECORD (x, float, Lisp_Float)
#define XSETFLOAT(x, p) XSETRECORD (x, p, float)
#define FLOATP(x) RECORDP (x, float)
-#define GC_FLOATP(x) GC_RECORDP (x, float)
#define CHECK_FLOAT(x) CHECK_RECORD (x, float)
#define CONCHECK_FLOAT(x) CONCHECK_RECORD (x, float)
} while (0)
# define INT_OR_FLOATP(x) (INTP (x) || FLOATP (x))
-# define GC_INT_OR_FLOATP(x) (GC_INTP (x) || GC_FLOATP (x))
#else /* not LISP_FLOAT_TYPE */
#define XFLOAT(x) --- error! No float support. ---
#define XSETFLOAT(x, p) --- error! No float support. ---
#define FLOATP(x) 0
-#define GC_FLOATP(x) 0
#define CHECK_FLOAT(x) --- error! No float support. ---
#define CONCHECK_FLOAT(x) --- error! No float support. ---
#define XFLOATINT(n) XINT(n)
#define CHECK_INT_OR_FLOAT CHECK_INT
#define CONCHECK_INT_OR_FLOAT CONCHECK_INT
-#define INT_OR_FLOATP(x) (INTP (x))
-# define GC_INT_OR_FLOATP(x) (GC_INTP (x))
+#define INT_OR_FLOATP(x) INTP (x)
#endif /* not LISP_FLOAT_TYPE */
/*********** int ***********/
-#define GC_INTP(x) INTP (x)
-
#define ZEROP(x) EQ (x, Qzero)
-#define GC_ZEROP(x) GC_EQ (x, Qzero)
#ifdef ERROR_CHECK_TYPECHECK
} while (0)
#define NATNUMP(x) (INTP (x) && XINT (x) >= 0)
-#define GC_NATNUMP(x) (GC_INTP (x) && XINT (x) >= 0)
#define CHECK_NATNUM(x) do { \
if (!NATNUMP (x)) \
#define XWEAK_LIST(x) XRECORD (x, weak_list, struct weak_list)
#define XSETWEAK_LIST(x, p) XSETRECORD (x, p, weak_list)
#define WEAK_LISTP(x) RECORDP (x, weak_list)
-#define GC_WEAK_LISTP(x) GC_RECORDP (x, weak_list)
#define CHECK_WEAK_LIST(x) CHECK_RECORD (x, weak_list)
#define CONCHECK_WEAK_LIST(x) CONCHECK_RECORD (x, weak_list)
Lisp_Object make_weak_list (enum weak_list_type type);
/* The following two are only called by the garbage collector */
-int finish_marking_weak_lists (int (*obj_marked_p) (Lisp_Object),
- void (*markobj) (Lisp_Object));
-void prune_weak_lists (int (*obj_marked_p) (Lisp_Object));
+int finish_marking_weak_lists (void);
+void prune_weak_lists (void);
/*********** lcrecord lists ***********/
#define XLCRECORD_LIST(x) XRECORD (x, lcrecord_list, struct lcrecord_list)
#define XSETLCRECORD_LIST(x, p) XSETRECORD (x, p, lcrecord_list)
#define LCRECORD_LISTP(x) RECORDP (x, lcrecord_list)
-#define GC_LCRECORD_LISTP(x) GC_RECORDP (x, lcrecord_list)
/* #define CHECK_LCRECORD_LIST(x) CHECK_RECORD (x, lcrecord_list)
Lcrecord lists should never escape to the Lisp level, so
functions should not be doing this. */
gcpro4.next = &gcpro3, gcpro4.var = &var4, gcpro4.nvars = 1, \
gcprolist = &gcpro4 ))
-#define GCPRO5(var1, var2, var3, var4, var5) \
- ((void) ( \
+#define GCPRO5(var1, var2, var3, var4, var5) ((void) ( \
gcpro1.next = gcprolist, gcpro1.var = &var1, gcpro1.nvars = 1, \
gcpro2.next = &gcpro1, gcpro2.var = &var2, gcpro2.nvars = 1, \
gcpro3.next = &gcpro2, gcpro3.var = &var3, gcpro3.nvars = 1, \
ngcpro4.next = &ngcpro3, ngcpro4.var = &var4, ngcpro4.nvars = 1, \
gcprolist = &ngcpro4 ))
-#define NGCPRO5(var1, var2, var3, var4, var5) \
- ((void) ( \
+#define NGCPRO5(var1, var2, var3, var4, var5) ((void) ( \
ngcpro1.next = gcprolist, ngcpro1.var = &var1, ngcpro1.nvars = 1, \
ngcpro2.next = &ngcpro1, ngcpro2.var = &var2, ngcpro2.nvars = 1, \
ngcpro3.next = &ngcpro2, ngcpro3.var = &var3, ngcpro3.nvars = 1, \
nngcpro4.next = &nngcpro3, nngcpro4.var = &var4, nngcpro4.nvars = 1, \
gcprolist = &nngcpro4 ))
-#define NNGCPRO5(var1, var2, var3, var4, var5) \
- ((void) ( \
+#define NNGCPRO5(var1, var2, var3, var4, var5) ((void) ( \
nngcpro1.next = gcprolist, nngcpro1.var = &var1, nngcpro1.nvars = 1, \
nngcpro2.next = &nngcpro1, nngcpro2.var = &var2, nngcpro2.nvars = 1, \
nngcpro3.next = &nngcpro2, nngcpro3.var = &var3, nngcpro3.nvars = 1, \
/* Call staticpro (&var) to protect static variable `var'. */
void staticpro (Lisp_Object *);
+/* Call staticpro_nodump (&var) to protect static variable `var'. */
+/* var will not be saved at dump time */
+void staticpro_nodump (Lisp_Object *);
+
+/* Call dumpstruct(&var, &desc) to dump the structure pointed to by `var'. */
+void dumpstruct (void *, const struct struct_description *);
+
+/* Call pdump_wire(&var) to ensure that var is properly updated after pdump. */
+void pdump_wire (Lisp_Object *);
+
+/* Call pdump_wire(&var) to ensure that var is properly updated after
+ pdump. var must point to a linked list of objects out of which
+ some may not be dumped */
+void pdump_wire_list (Lisp_Object *);
+
/* Nonzero means Emacs has already been initialized.
Used during startup to detect startup of dumped Emacs. */
extern int initialized;
#endif
#endif
#ifndef IS_ANY_SEP
-#define IS_ANY_SEP(c) (IS_DIRECTORY_SEP (c))
+#define IS_ANY_SEP(c) IS_DIRECTORY_SEP (c)
#endif
#ifdef HAVE_INTTYPES_H
void mark_conses_in_list (Lisp_Object);
void free_marker (Lisp_Marker *);
int object_dead_p (Lisp_Object);
+void mark_object (Lisp_Object obj);
+int marked_p (Lisp_Object obj);
#ifdef MEMORY_USAGE_STATS
size_t malloced_storage_size (void *, size_t, struct overhead_stats *);
size_t fixed_type_block_overhead (size_t);
#endif
+#ifdef PDUMP
+void pdump (void);
+int pdump_load (void);
+
+extern char *pdump_start, *pdump_end;
+#define DUMPEDP(adr) ((((char *)(adr)) < pdump_end) && (((char *)(adr)) >= pdump_start))
+#else
+#define DUMPEDP(adr) 0
+#endif
/* Defined in buffer.c */
Lisp_Object make_buffer (struct buffer *);
Lisp_Object));
Lisp_Object wrong_type_argument (Lisp_Object, Lisp_Object);
DECLARE_DOESNT_RETURN (dead_wrong_type_argument (Lisp_Object, Lisp_Object));
-void check_int_range (int, int, int);
+void check_int_range (EMACS_INT, EMACS_INT, EMACS_INT);
enum arith_comparison {
arith_equal,
Bufpos bufpos_clip_to_bounds (Bufpos, Bufpos, Bufpos);
Bytind bytind_clip_to_bounds (Bytind, Bytind, Bytind);
void buffer_insert1 (struct buffer *, Lisp_Object);
-Lisp_Object make_string_from_buffer (struct buffer *, int, int);
-Lisp_Object make_string_from_buffer_no_extents (struct buffer *, int, int);
+Lisp_Object make_string_from_buffer (struct buffer *, Bufpos, Charcount);
+Lisp_Object make_string_from_buffer_no_extents (struct buffer *, Bufpos, Charcount);
Lisp_Object save_excursion_save (void);
Lisp_Object save_restriction_save (void);
Lisp_Object save_excursion_restore (Lisp_Object);
Lisp_Object remassq_no_quit (Lisp_Object, Lisp_Object);
Lisp_Object remrassq_no_quit (Lisp_Object, Lisp_Object);
-void pure_put (Lisp_Object, Lisp_Object, Lisp_Object);
int plists_differ (Lisp_Object, Lisp_Object, int, int, int);
Lisp_Object internal_plist_get (Lisp_Object, Lisp_Object);
void internal_plist_put (Lisp_Object *, Lisp_Object, Lisp_Object);
/* Defined in indent.c */
int bi_spaces_at_point (struct buffer *, Bytind);
int column_at_point (struct buffer *, Bufpos, int);
+int string_column_at_point (struct Lisp_String *, Bufpos, int);
int current_column (struct buffer *);
void invalidate_current_column (void);
Bufpos vmotion (struct window *, Bufpos, int, int *);
void internal_object_printer (Lisp_Object, Lisp_Object, int);
/* Defined in profile.c */
-void mark_profiling_info (void (*) (Lisp_Object));
+void mark_profiling_info (void);
void profile_increase_call_count (Lisp_Object);
extern int profiling_active;
extern int profiling_redisplay_flag;
Bufpos find_next_newline (struct buffer *, Bufpos, int);
Bufpos find_next_newline_no_quit (struct buffer *, Bufpos, int);
Bytind bi_find_next_newline_no_quit (struct buffer *, Bytind, int);
+Bytind bi_find_next_emchar_in_string (struct Lisp_String*, Emchar, Bytind, EMACS_INT);
Bufpos find_before_next_newline (struct buffer *, Bufpos, Bufpos, int);
struct re_pattern_buffer *compile_pattern (Lisp_Object, struct re_registers *,
char *, int, Error_behavior);
Lisp_Object follow_past_lisp_magic);
/* Defined in syntax.c */
-int scan_words (struct buffer *, int, int);
+Bufpos scan_words (struct buffer *, Bufpos, int);
/* Defined in undo.c */
Lisp_Object truncate_undo_list (Lisp_Object, int, int);
EXFUN (Fprocess_status, 1);
EXFUN (Fprogn, UNEVALLED);
EXFUN (Fprovide, 1);
-EXFUN (Fpurecopy, 1);
EXFUN (Fput, 3);
EXFUN (Fput_range_table, 4);
EXFUN (Fput_text_property, 5);
extern Lisp_Object Qarith_error, Qarrayp, Qassoc, Qat, Qautodetect, Qautoload;
extern Lisp_Object Qbackground, Qbackground_pixmap, Qbad_variable, Qbefore;
extern Lisp_Object Qbeginning_of_buffer, Qbig5, Qbinary, Qbitmap, Qbitp, Qblinking;
-extern Lisp_Object Qboolean, Qbottom, Qbuffer, Qbuffer_file_coding_system;
+extern Lisp_Object Qboolean, Qbottom, Qbuffer;
extern Lisp_Object Qbuffer_glyph_p, Qbuffer_live_p, Qbuffer_read_only, Qbutton;
extern Lisp_Object Qbyte_code, Qcall_interactively, Qcategory;
extern Lisp_Object Qcategory_designator_p, Qcategory_table_value_p, Qccl, Qcdr;
extern Lisp_Object Qchannel, Qchar, Qchar_or_string_p, Qcharacter, Qcharacterp;
extern Lisp_Object Qchars, Qcharset_g0, Qcharset_g1, Qcharset_g2, Qcharset_g3;
-extern Lisp_Object Qcircular_list, Qcircular_property_list;
-extern Lisp_Object Qcoding_system_error, Qcoding_system_p;
+extern Lisp_Object Qcenter, Qcircular_list, Qcircular_property_list;
+extern Lisp_Object Qcoding_system_error;
extern Lisp_Object Qcolor, Qcolor_pixmap_image_instance_p;
extern Lisp_Object Qcolumns, Qcommand, Qcommandp, Qcompletion_ignore_case;
extern Lisp_Object Qconsole, Qconsole_live_p, Qconst_specifier, Qcr, Qcritical;
extern Lisp_Object Qfont, Qforce_g0_on_output, Qforce_g1_on_output;
extern Lisp_Object Qforce_g2_on_output, Qforce_g3_on_output, Qforeground;
extern Lisp_Object Qformat, Qframe, Qframe_live_p, Qfunction, Qgap_overhead;
-extern Lisp_Object Qgeneric, Qgeometry, Qglobal, Qheight, Qhighlight, Qicon;
+extern Lisp_Object Qgeneric, Qgeometry, Qglobal, Qheight, Qhighlight, Qhorizontal, Qicon;
extern Lisp_Object Qicon_glyph_p, Qid, Qidentity, Qimage, Qinfo, Qinherit;
extern Lisp_Object Qinhibit_quit, Qinhibit_read_only;
extern Lisp_Object Qinput_charset_conversion, Qinteger;
extern Lisp_Object Qinteger_char_or_marker_p, Qinteger_or_char_p;
extern Lisp_Object Qinteger_or_marker_p, Qintegerp, Qinteractive, Qinternal;
extern Lisp_Object Qinvalid_function, Qinvalid_read_syntax, Qio_error;
-extern Lisp_Object Qiso2022, Qkey, Qkey_assoc, Qkeymap, Qlambda, Qleft, Qlf;
+extern Lisp_Object Qiso2022, Qkey, Qkey_assoc, Qkeymap, Qlambda, Qlayout, Qleft, Qlf;
extern Lisp_Object Qlist, Qlistp, Qload, Qlock_shift, Qmacro, Qmagic;
extern Lisp_Object Qmalformed_list, Qmalformed_property_list;
extern Lisp_Object Qmalloc_overhead, Qmark, Qmarkers;
extern Lisp_Object Qno_ascii_cntl, Qno_ascii_eol, Qno_catch;
extern Lisp_Object Qno_conversion, Qno_iso6429, Qnone, Qnot, Qnothing;
extern Lisp_Object Qnothing_image_instance_p, Qnotice;
-extern Lisp_Object Qnumber_char_or_marker_p, Qnumber_or_marker_p, Qnumberp;
+extern Lisp_Object Qnumber_char_or_marker_p, Qnumberp;
extern Lisp_Object Qobject, Qold_assoc, Qold_delete, Qold_delq, Qold_rassoc;
extern Lisp_Object Qold_rassq, Qonly, Qor, Qother, Qoutput_charset_conversion;
-extern Lisp_Object Qoverflow_error, Qpath, Qpoint, Qpointer, Qpointer_glyph_p;
+extern Lisp_Object Qoverflow_error, Qpoint, Qpointer, Qpointer_glyph_p;
extern Lisp_Object Qpointer_image_instance_p, Qpost_read_conversion;
extern Lisp_Object Qpre_write_conversion, Qprint, Qprint_length;
extern Lisp_Object Qprint_string_length, Qprocess, Qprogn, Qprovide, Qquit;
extern Lisp_Object Qunbound, Qundecided, Qundefined, Qunderflow_error;
extern Lisp_Object Qunderline, Qunimplemented, Quser_files_and_directories;
extern Lisp_Object Qvalue_assoc, Qvalues;
-extern Lisp_Object Qvariable_documentation, Qvariable_domain, Qvector;
+extern Lisp_Object Qvariable_documentation, Qvariable_domain, Qvertical;
extern Lisp_Object Qvoid_function, Qvoid_variable, Qwarning, Qwidth, Qwidget, Qwindow;
extern Lisp_Object Qwindow_live_p, Qwindow_system, Qwrong_number_of_arguments;
extern Lisp_Object Qwrong_type_argument, Qx, Qy, Qyes_or_no_p;
Lisp_Object list = Vload_force_doc_string_list;
Lisp_Object tail;
int fd = XINT (XCAR (Vload_descriptor_list));
- /* NOTE: If purify_flag is true, we're in-place modifying objects that
- may be in purespace (and if not, they will be). Therefore, we have
- to be VERY careful to make sure that all objects that we create
- are purecopied -- objects in purespace are not marked for GC, and
- if we leave any impure objects inside of pure ones, we're really
- screwed. */
GCPRO1 (list);
/* restore the old value first just in case an error occurs. */
ivan = Fread (juan);
if (!CONSP (ivan))
signal_simple_error ("invalid lazy-loaded byte code", ivan);
- /* Remember to purecopy; see above. */
- XCOMPILED_FUNCTION (john)->instructions = Fpurecopy (XCAR (ivan));
+ XCOMPILED_FUNCTION (john)->instructions = XCAR (ivan);
/* v18 or v19 bytecode file. Need to Ebolify. */
if (XCOMPILED_FUNCTION (john)->flags.ebolified
&& VECTORP (XCDR (ivan)))
ebolify_bytecode_constants (XCDR (ivan));
- XCOMPILED_FUNCTION (john)->constants = Fpurecopy (XCDR (ivan));
+ XCOMPILED_FUNCTION (john)->constants = XCDR (ivan);
NUNGCPRO;
}
doc = compiled_function_documentation (XCOMPILED_FUNCTION (john));
/* Map FUN over SUFFIXES, as described above. FUN will be called with a
char * containing the current file name, and ARG. Mapping stops when
FUN returns non-zero. */
-void
+static void
locate_file_map_suffixes (Lisp_Object filename, Lisp_Object suffixes,
int (*fun) (char *, void *),
void *arg)
else
{
/* Case c) */
- CONST char *nsuffix = XSTRING_DATA (suffixes);
+ CONST char *nsuffix = (CONST char *) XSTRING_DATA (suffixes);
while (1)
{
sym = Fmake_symbol ( make_string ((Bufbyte *) read_ptr, len));
else
{
- /* intern will purecopy pname if necessary */
Lisp_Object name = make_string ((Bufbyte *) read_ptr, len);
sym = Fintern (name, Qnil);
}
i++, p++)
{
struct Lisp_Cons *otem = XCONS (tem);
-#if 0 /* FSFmacs defun hack */
- if (read_pure)
- tem = Fpurecopy (Fcar (tem));
- else
-#endif
- tem = Fcar (tem);
+ tem = Fcar (tem);
*p = tem;
tem = otem->cdr;
free_cons (otem);
}
void
+reinit_vars_of_lread (void)
+{
+ Vread_buffer_stream = Qnil;
+ staticpro_nodump (&Vread_buffer_stream);
+}
+
+void
vars_of_lread (void)
{
+ reinit_vars_of_lread ();
+
DEFVAR_LISP ("values", &Vvalues /*
List of values of all expressions which were read, evaluated and printed.
Order is reverse chronological.
with values saved when the image is dumped. */
staticpro (&Vload_descriptor_list);
- Vread_buffer_stream = Qnil;
- staticpro (&Vread_buffer_stream);
-
/* Initialized in init_lread. */
staticpro (&Vload_force_doc_string_list);
};
/* see alloc.c for an explanation */
-Lisp_Object this_one_is_unmarkable (Lisp_Object obj,
- void (*markobj) (Lisp_Object));
+Lisp_Object this_one_is_unmarkable (Lisp_Object obj);
struct lrecord_implementation
{
recursion, so the object returned should preferably be the one
with the deepest level of Lisp_Object pointers. This function
can be NULL, meaning no GC marking is necessary. */
- Lisp_Object (*marker) (Lisp_Object, void (*mark_object) (Lisp_Object));
+ Lisp_Object (*marker) (Lisp_Object);
/* This can be NULL if the object is an lcrecord; the
default_object_printer() in print.c will be used. */
void (*printer) (Lisp_Object, Lisp_Object printcharfun, int escapeflag);
structure. Following values are parameters, their presence, type
and number is type-dependant.
- The description ends with a "XD_END" record.
+ The description ends with a "XD_END" or "XD_SPECIFIER_END" record.
Some example descriptions :
static const struct lrecord_description cons_description[] = {
Which means "two lisp objects starting at the 'car' element"
static const struct lrecord_description string_description[] = {
- { XD_STRING_DATA, offsetof(Lisp_String, data) },
- { XD_LISP_OBJECT, offsetof(Lisp_String, plist), 1 },
+ { XD_BYTECOUNT, offsetof(Lisp_String, size) },
+ { XD_OPAQUE_DATA_PTR, offsetof(Lisp_String, data), XD_INDIRECT(0, 1) },
+ { XD_LISP_OBJECT, offsetof(Lisp_String, plist), 1 },
{ XD_END }
};
- "A string data pointer at 'data', one lisp object at 'plist'"
+ "A pointer to string data at 'data', the size of the pointed array being the value
+ of the size variable plus 1, and one lisp object at 'plist'"
The existing types :
XD_LISP_OBJECT
Lisp objects. The third element is the count. This is also the type to use
for pointers to other lrecords.
- XD_STRING_DATA
- Pointer to string data.
+ XD_LO_RESET_NIL
+ Lisp objects which will be reset to Qnil when dumping. Useful for cleaning
+ up caches.
+ XD_LO_LINK
+ Link in a linked list of objects of the same type.
+
XD_OPAQUE_PTR
Pointer to undumpable data. Must be NULL when dumping.
Pointer to dumpable opaque data. Parameter is the size of the data.
Pointed data must be relocatable without changes.
+ XD_C_STRING
+ Pointer to a C string.
+
+ XD_DOC_STRING
+ Pointer to a doc string (C string if positive, opaque value if negative)
+
+ XD_INT_RESET
+ An integer which will be reset to a given value in the dump file.
+
+
XD_SIZE_T
size_t value. Used for counts.
XD_LONG
long value. Used for counts.
+ XD_BYTECOUNT
+ bytecount value. Used for counts.
+
XD_END
Special type indicating the end of the array.
+ XD_SPECIFIER_END
+ Special type indicating the end of the array for a specifier. Extra
+ description is going to be fetched from the specifier methods.
- Special macros:
- XD_INDIRECT(line)
- Usable where a "count" or "size" is requested. Gives the value of the element
- which is at line number 'line' in the description (count starts at zero).
- XD_PARENT_INDIRECT(line)
- Same as XD_INDIRECT but the element number refers to the parent structure.
- Usable only in struct descriptions.
+ Special macros:
+ XD_INDIRECT(line, delta)
+ Usable where a "count" or "size" is requested. Gives the value of
+ the element which is at line number 'line' in the description (count
+ starts at zero) and adds delta to it.
*/
enum lrecord_description_type {
XD_LISP_OBJECT,
- XD_STRING_DATA,
+ XD_LO_RESET_NIL,
+ XD_LO_LINK,
XD_OPAQUE_PTR,
XD_STRUCT_PTR,
XD_OPAQUE_DATA_PTR,
+ XD_C_STRING,
+ XD_DOC_STRING,
+ XD_INT_RESET,
XD_SIZE_T,
XD_INT,
XD_LONG,
- XD_END
+ XD_BYTECOUNT,
+ XD_END,
+ XD_SPECIFIER_END
};
struct lrecord_description {
const struct lrecord_description *description;
};
-#define XD_INDIRECT(count) (-1-(count))
-#define XD_PARENT_INDIRECT(count) (-1000-(count))
+#define XD_INDIRECT(val, delta) (-1-((val)|(delta<<8)))
+
+#define XD_IS_INDIRECT(code) (code<0)
+#define XD_INDIRECT_VAL(code) ((-1-code) & 255)
+#define XD_INDIRECT_DELTA(code) (((-1-code)>>8) & 255)
#define XD_DYNARR_DESC(base_type, sub_desc) \
- { XD_STRUCT_PTR, offsetof(base_type, base), XD_INDIRECT(1), sub_desc }, \
- { XD_INT, offsetof(base_type, max) }
+ { XD_STRUCT_PTR, offsetof(base_type, base), XD_INDIRECT(1, 0), sub_desc }, \
+ { XD_INT, offsetof(base_type, cur) }, \
+ { XD_INT_RESET, offsetof(base_type, max), XD_INDIRECT(1, 0) }
/* Declaring the following structures as const puts them in the
text (read-only) segment, which makes debugging inconvenient
getprop, putprop, remprop, props, size, sizer, \
&(lrecord_##c_name##_lrecord_type_index), basic_p } \
-#define LRECORDP(a) (XTYPE ((a)) == Lisp_Type_Record)
+#define LRECORDP(a) (XTYPE (a) == Lisp_Type_Record)
#define XRECORD_LHEADER(a) ((struct lrecord_header *) XPNTR (a))
#define RECORD_TYPEP(x, ty) \
INLINE structtype * \
error_check_##c_name (Lisp_Object obj) \
{ \
- assert (RECORD_TYPEP (obj, &lrecord_##c_name) || \
- MARKED_RECORD_P (obj)); \
+ assert (RECORD_TYPEP (obj, &lrecord_##c_name)); \
return (structtype *) XPNTR (obj); \
} \
extern Lisp_Object Q##c_name##p
INLINE structtype * \
error_check_##c_name (Lisp_Object obj) \
{ \
- assert (XGCTYPE (obj) == type_enum); \
+ assert (XTYPE (obj) == type_enum); \
return (structtype *) XPNTR (obj); \
} \
extern Lisp_Object Q##c_name##p
# define XSETRECORD(var, p, c_name) do \
{ \
XSETOBJ (var, Lisp_Type_Record, p); \
- assert (RECORD_TYPEP (var, &lrecord_##c_name) || \
- MARKED_RECORD_P (var)); \
+ assert (RECORD_TYPEP (var, &lrecord_##c_name)); \
} while (0)
#else /* not ERROR_CHECK_TYPECHECK */
#endif /* not ERROR_CHECK_TYPECHECK */
#define RECORDP(x, c_name) RECORD_TYPEP (x, &lrecord_##c_name)
-#define GC_RECORDP(x, c_name) gc_record_type_p (x, &lrecord_##c_name)
/* Note: we now have two different kinds of type-checking macros.
The "old" kind has now been renamed CONCHECK_foo. The reason for
#define alloc_lcrecord_type(type, lrecord_implementation) \
((type *) alloc_lcrecord (sizeof (type), lrecord_implementation))
-int gc_record_type_p (Lisp_Object frob,
- CONST struct lrecord_implementation *type);
-
/* Copy the data from one lcrecord structure into another, but don't
overwrite the header information. */
#define MAX_READ_SIZE 512
static Lisp_Object
-mark_lstream (Lisp_Object obj, void (*markobj) (Lisp_Object))
+mark_lstream (Lisp_Object obj)
{
Lstream *lstr = XLSTREAM (obj);
- return lstr->imp->marker ? (lstr->imp->marker) (obj, markobj) : Qnil;
+ return lstr->imp->marker ? (lstr->imp->marker) (obj) : Qnil;
}
static void
}
static Lisp_Object
-lisp_string_marker (Lisp_Object stream, void (*markobj) (Lisp_Object))
+lisp_string_marker (Lisp_Object stream)
{
struct lisp_string_stream *str = LISP_STRING_STREAM_DATA (XLSTREAM (stream));
return str->obj;
}
static Lisp_Object
-lisp_buffer_marker (Lisp_Object stream, void (*markobj) (Lisp_Object))
+lisp_buffer_marker (Lisp_Object stream)
{
struct lisp_buffer_stream *str =
LISP_BUFFER_STREAM_DATA (XLSTREAM (stream));
- markobj (str->start);
- markobj (str->end);
+ mark_object (str->start);
+ mark_object (str->end);
return str->buffer;
}
}
void
-vars_of_lstream (void)
+reinit_vars_of_lstream (void)
{
int i;
for (i = 0; i < countof (Vlstream_free_list); i++)
{
Vlstream_free_list[i] = Qnil;
- staticpro (&Vlstream_free_list[i]);
+ staticpro_nodump (&Vlstream_free_list[i]);
}
}
+
+void
+vars_of_lstream (void)
+{
+ reinit_vars_of_lstream ();
+}
int (*closer) (Lstream *stream);
/* Mark this object for garbage collection. Same semantics as
a standard Lisp_Object marker. This function can be NULL. */
- Lisp_Object (*marker) (Lisp_Object lstream, void (*markfun) (Lisp_Object));
+ Lisp_Object (*marker) (Lisp_Object lstream);
} Lstream_implementation;
#define DEFINE_LSTREAM_IMPLEMENTATION(name,c_name,size) \
#ifdef USG5_4
#undef UNEXEC
-/* FSF renames this file to unexsgi.o */
-#define UNEXEC "unexelfsgi.o"
+#define UNEXEC "unexelf.o"
#else
#define UNEXEC "unexmips.o"
#endif
#ifdef UNEXEC
#undef UNEXEC
#endif
-/* FSF renames this file to unexsgi.o */
-#define UNEXEC "unexelfsgi.o"
+#define UNEXEC "unexelf.o"
#define TEXT_START 0x400000
#define LOAD_AVE_CVT(x) (int) (((double) (x)) * 100.0 / 256.0)
+#ifndef linux
/* CDC EP/IX 1.4.3 uses /unix */
#undef KERNEL_FILE
#define KERNEL_FILE "/unix"
+#endif /* ! linux */
/* Define CANNOT_DUMP on machines where unexec does not work.
Then the function dump-emacs will not be defined
/* This machine requires completely different unexec code
which lives in a separate file. Specify the file name. */
+#ifndef linux
#define UNEXEC "unexmips.o"
-
+#endif /* !linux */
/* Describe layout of the address space in an executing process. */
+#ifdef linux
+#define TEXT_START 0x00400000
+#define DATA_START 0x10000000
+#define DATA_SEG_BITS 0x10000000
+#else /* !linux */
#define TEXT_START 0x400000
#define DATA_START 0x800000
+#endif /* linux */
/* Alter some of the options used when linking. */
-#ifndef NEWSOS5
+#if !defined(NEWSOS5) && !defined(linux)
#ifdef BSD
/* DECstations don't have this library. */
#define C_DEBUG_SWITCH "-O -g3"
#endif /* not BSD */
-#endif /* not NEWSOS5 */
+#endif /* !NEWSOS5 && !linux */
\f
-#ifndef NEWSOS5
+#if !defined(NEWSOS5) && !defined(linux)
#ifdef USG
/* Don't try to use SIGIO even though it is defined. */
#define TERMINFO
#undef MAIL_USE_FLOCK /* Someone should check this. */
#endif /* BSD */
-#endif /* not NEWSOS5 */
+#endif /* !NEWSOS5 && !linux */
#include "buffer.h"
static Lisp_Object
-mark_marker (Lisp_Object obj, void (*markobj) (Lisp_Object))
+mark_marker (Lisp_Object obj)
{
struct Lisp_Marker *marker = XMARKER (obj);
Lisp_Object buf;
write_c_string (GETTEXT ("in no buffer"), printcharfun);
else
{
- sprintf (buf, "at %d in ", marker_position (obj));
+ sprintf (buf, "at %ld in ", (long) marker_position (obj));
write_c_string (buf, printcharfun);
print_internal (marker->buffer->name, printcharfun, 0);
}
if (eev)
{
Position shellx, shelly, framex, framey;
- Widget shell = XtParent (daddy);
Arg al [2];
btn->time = eev->timestamp;
btn->button = eev->event.button.button;
btn->subwindow = (Window) NULL;
btn->x = eev->event.button.x;
btn->y = eev->event.button.y;
- XtSetArg (al [0], XtNx, &shellx);
- XtSetArg (al [1], XtNy, &shelly);
- XtGetValues (shell, al, 2);
+ shellx = shelly = 0;
+#ifndef HAVE_WMCOMMAND
+ {
+ Widget shell = XtParent (daddy);
+
+ XtSetArg (al [0], XtNx, &shellx);
+ XtSetArg (al [1], XtNy, &shelly);
+ XtGetValues (shell, al, 2);
+ }
+#endif
XtSetArg (al [0], XtNx, &framex);
XtSetArg (al [1], XtNy, &framey);
XtGetValues (daddy, al, 2);
}
void
-vars_of_menubar_x (void)
+reinit_vars_of_menubar_x (void)
{
last_popup_menu_selection_callback_id = (LWLIB_ID) -1;
+}
+
+void
+vars_of_menubar_x (void)
+{
+ reinit_vars_of_menubar_x ();
#if defined (LWLIB_MENUBARS_LUCID)
Fprovide (intern ("lucid-menubars"));
Fcons (Fvector (3, &menu_item[0]),
Qnil)),
Qnil);
- Vblank_menubar = Fpurecopy (Vblank_menubar);
staticpro (&Vblank_menubar);
}
}
void
-vars_of_minibuf (void)
+reinit_vars_of_minibuf (void)
{
minibuf_level = 0;
+}
+
+void
+vars_of_minibuf (void)
+{
+ reinit_vars_of_minibuf ();
staticpro (&Vminibuf_prompt);
Vminibuf_prompt = Qnil;
}
void
-complex_vars_of_minibuf (void)
+reinit_complex_vars_of_minibuf (void)
{
/* This function can GC */
#ifdef I18N3
#endif
Vminibuffer_zero
= Fget_buffer_create
- (Fpurecopy (build_string (DEFER_GETTEXT (" *Minibuf-0*"))));
+ (build_string (DEFER_GETTEXT (" *Minibuf-0*")));
Vecho_area_buffer
= Fget_buffer_create
- (Fpurecopy (build_string (DEFER_GETTEXT (" *Echo Area*"))));
+ (build_string (DEFER_GETTEXT (" *Echo Area*")));
+}
+
+void
+complex_vars_of_minibuf (void)
+{
+ reinit_complex_vars_of_minibuf ();
}
int i, j, op;
int stack_idx = ccl->stack_idx;
/* Instruction counter of the current CCL code. */
- int this_ic;
+ int this_ic = 0;
if (ic >= ccl->eof_ic)
ic = CCL_HEADER_MAIN;
function converts symbols of code conversion maps and character
translation tables embeded in the CCL code into their ID numbers. */
-Lisp_Object
+static Lisp_Object
resolve_symbol_ccl_program (Lisp_Object ccl)
{
int i, veclen;
int i;
Lisp_Object ccl_id;
- if ((SYMBOLP (ccl_prog)) &&
- (!NILP (ccl_id = Fget (ccl_prog, Qccl_program_idx, Qnil))))
+ if (SYMBOLP (ccl_prog) &&
+ !NILP (ccl_id = Fget (ccl_prog, Qccl_program_idx, Qnil)))
{
ccl_prog = XVECTOR_DATA (Vccl_program_table)[XUINT (ccl_id)];
CHECK_LIST (ccl_prog);
struct gcpro gcpro1, gcpro2, gcpro3;
Lisp_Object ccl_id;
- if ((SYMBOLP (ccl_prog)) &&
- (!NILP (ccl_id = Fget (ccl_prog, Qccl_program_idx, Qnil))))
+ if (SYMBOLP (ccl_prog) &&
+ !NILP (ccl_id = Fget (ccl_prog, Qccl_program_idx, Qnil)))
{
ccl_prog = XVECTOR (Vccl_program_table)->contents[XUINT (ccl_id)];
CHECK_LIST (ccl_prog);
#endif /* ENABLE_COMPOSITE_CHARS */
-/* Table of charsets indexed by leading byte. */
-Lisp_Object charset_by_leading_byte[NUM_LEADING_BYTES];
+struct charset_lookup *chlook;
-/* Table of charsets indexed by type/final-byte/direction. */
-Lisp_Object charset_by_attributes[4][128][2];
+static const struct lrecord_description charset_lookup_description_1[] = {
+ { XD_LISP_OBJECT, offsetof(struct charset_lookup, charset_by_leading_byte), 128+4*128*2 },
+ { XD_END }
+};
+
+static const struct struct_description charset_lookup_description = {
+ sizeof(struct charset_lookup),
+ charset_lookup_description_1
+};
/* Table of number of bytes in the string representation of a character
indexed by the first byte of that representation.
/************************************************************************/
static Lisp_Object
-mark_charset (Lisp_Object obj, void (*markobj) (Lisp_Object))
+mark_charset (Lisp_Object obj)
{
struct Lisp_Charset *cs = XCHARSET (obj);
- markobj (cs->short_name);
- markobj (cs->long_name);
- markobj (cs->doc_string);
- markobj (cs->registry);
- markobj (cs->ccl_program);
+ mark_object (cs->short_name);
+ mark_object (cs->long_name);
+ mark_object (cs->doc_string);
+ mark_object (cs->registry);
+ mark_object (cs->ccl_program);
return cs->name;
}
/* some charsets do not have final characters. This includes
ASCII, Control-1, Composite, and the two faux private
charsets. */
- assert (NILP (charset_by_attributes[type][final][direction]));
- charset_by_attributes[type][final][direction] = obj;
+ assert (NILP (chlook->charset_by_attributes[type][final][direction]));
+ chlook->charset_by_attributes[type][final][direction] = obj;
}
- assert (NILP (charset_by_leading_byte[id - MIN_LEADING_BYTE]));
- charset_by_leading_byte[id - MIN_LEADING_BYTE] = obj;
+ assert (NILP (chlook->charset_by_leading_byte[id - 128]));
+ chlook->charset_by_leading_byte[id - 128] = obj;
if (id < 0xA0)
/* official leading byte */
rep_bytes_by_first_byte[id] = rep_bytes;
{
int i, j, k;
+ chlook = xnew (struct charset_lookup);
+ dumpstruct (&chlook, &charset_lookup_description);
+
/* Table of charsets indexed by leading byte. */
- for (i = 0; i < countof (charset_by_leading_byte); i++)
- charset_by_leading_byte[i] = Qnil;
+ for (i = 0; i < countof (chlook->charset_by_leading_byte); i++)
+ chlook->charset_by_leading_byte[i] = Qnil;
/* Table of charsets indexed by type/final-byte/direction. */
- for (i = 0; i < countof (charset_by_attributes); i++)
- for (j = 0; j < countof (charset_by_attributes[0]); j++)
- for (k = 0; k < countof (charset_by_attributes[0][0]); k++)
- charset_by_attributes[i][j][k] = Qnil;
+ for (i = 0; i < countof (chlook->charset_by_attributes); i++)
+ for (j = 0; j < countof (chlook->charset_by_attributes[0]); j++)
+ for (k = 0; k < countof (chlook->charset_by_attributes[0][0]); k++)
+ chlook->charset_by_attributes[i][j][k] = Qnil;
next_allocated_1_byte_leading_byte = MIN_LEADING_BYTE_PRIVATE_1;
next_allocated_2_byte_leading_byte = MIN_LEADING_BYTE_PRIVATE_2;
/* Predefined character sets. We store them into variables for
ease of access. */
+ staticpro (&Vcharset_ascii);
Vcharset_ascii =
make_charset (LEADING_BYTE_ASCII, Qascii, 1,
CHARSET_TYPE_94, 1, 0, 'B',
build_string ("ASCII)"),
build_string ("ASCII (ISO646 IRV)"),
build_string ("\\(iso8859-[0-9]*\\|-ascii\\)"));
+ staticpro (&Vcharset_control_1);
Vcharset_control_1 =
make_charset (LEADING_BYTE_CONTROL_1, Qcontrol_1, 2,
CHARSET_TYPE_94, 1, 1, 0,
build_string ("Control characters"),
build_string ("Control characters 128-191"),
build_string (""));
+ staticpro (&Vcharset_latin_iso8859_1);
Vcharset_latin_iso8859_1 =
make_charset (LEADING_BYTE_LATIN_ISO8859_1, Qlatin_iso8859_1, 2,
CHARSET_TYPE_96, 1, 1, 'A',
build_string ("ISO8859-1 (Latin-1)"),
build_string ("ISO8859-1 (Latin-1)"),
build_string ("iso8859-1"));
+ staticpro (&Vcharset_latin_iso8859_2);
Vcharset_latin_iso8859_2 =
make_charset (LEADING_BYTE_LATIN_ISO8859_2, Qlatin_iso8859_2, 2,
CHARSET_TYPE_96, 1, 1, 'B',
build_string ("ISO8859-2 (Latin-2)"),
build_string ("ISO8859-2 (Latin-2)"),
build_string ("iso8859-2"));
+ staticpro (&Vcharset_latin_iso8859_3);
Vcharset_latin_iso8859_3 =
make_charset (LEADING_BYTE_LATIN_ISO8859_3, Qlatin_iso8859_3, 2,
CHARSET_TYPE_96, 1, 1, 'C',
build_string ("ISO8859-3 (Latin-3)"),
build_string ("ISO8859-3 (Latin-3)"),
build_string ("iso8859-3"));
+ staticpro (&Vcharset_latin_iso8859_4);
Vcharset_latin_iso8859_4 =
make_charset (LEADING_BYTE_LATIN_ISO8859_4, Qlatin_iso8859_4, 2,
CHARSET_TYPE_96, 1, 1, 'D',
build_string ("ISO8859-4 (Latin-4)"),
build_string ("ISO8859-4 (Latin-4)"),
build_string ("iso8859-4"));
+ staticpro (&Vcharset_thai_tis620);
Vcharset_thai_tis620 =
make_charset (LEADING_BYTE_THAI_TIS620, Qthai_tis620, 2,
CHARSET_TYPE_96, 1, 1, 'T',
build_string ("TIS620 (Thai)"),
build_string ("TIS620.2529 (Thai)"),
build_string ("tis620"));
+ staticpro (&Vcharset_greek_iso8859_7);
Vcharset_greek_iso8859_7 =
make_charset (LEADING_BYTE_GREEK_ISO8859_7, Qgreek_iso8859_7, 2,
CHARSET_TYPE_96, 1, 1, 'F',
build_string ("ISO8859-7 (Greek)"),
build_string ("ISO8859-7 (Greek)"),
build_string ("iso8859-7"));
+ staticpro (&Vcharset_arabic_iso8859_6);
Vcharset_arabic_iso8859_6 =
make_charset (LEADING_BYTE_ARABIC_ISO8859_6, Qarabic_iso8859_6, 2,
CHARSET_TYPE_96, 1, 1, 'G',
build_string ("ISO8859-6 (Arabic)"),
build_string ("ISO8859-6 (Arabic)"),
build_string ("iso8859-6"));
+ staticpro (&Vcharset_hebrew_iso8859_8);
Vcharset_hebrew_iso8859_8 =
make_charset (LEADING_BYTE_HEBREW_ISO8859_8, Qhebrew_iso8859_8, 2,
CHARSET_TYPE_96, 1, 1, 'H',
build_string ("ISO8859-8 (Hebrew)"),
build_string ("ISO8859-8 (Hebrew)"),
build_string ("iso8859-8"));
+ staticpro (&Vcharset_katakana_jisx0201);
Vcharset_katakana_jisx0201 =
make_charset (LEADING_BYTE_KATAKANA_JISX0201, Qkatakana_jisx0201, 2,
CHARSET_TYPE_94, 1, 1, 'I',
build_string ("JISX0201.1976 (Japanese Kana)"),
build_string ("JISX0201.1976 Japanese Kana"),
build_string ("jisx0201.1976"));
+ staticpro (&Vcharset_latin_jisx0201);
Vcharset_latin_jisx0201 =
make_charset (LEADING_BYTE_LATIN_JISX0201, Qlatin_jisx0201, 2,
CHARSET_TYPE_94, 1, 0, 'J',
build_string ("JISX0201.1976 (Japanese Roman)"),
build_string ("JISX0201.1976 Japanese Roman"),
build_string ("jisx0201.1976"));
+ staticpro (&Vcharset_cyrillic_iso8859_5);
Vcharset_cyrillic_iso8859_5 =
make_charset (LEADING_BYTE_CYRILLIC_ISO8859_5, Qcyrillic_iso8859_5, 2,
CHARSET_TYPE_96, 1, 1, 'L',
build_string ("ISO8859-5 (Cyrillic)"),
build_string ("ISO8859-5 (Cyrillic)"),
build_string ("iso8859-5"));
+ staticpro (&Vcharset_latin_iso8859_9);
Vcharset_latin_iso8859_9 =
make_charset (LEADING_BYTE_LATIN_ISO8859_9, Qlatin_iso8859_9, 2,
CHARSET_TYPE_96, 1, 1, 'M',
build_string ("ISO8859-9 (Latin-5)"),
build_string ("ISO8859-9 (Latin-5)"),
build_string ("iso8859-9"));
+ staticpro (&Vcharset_japanese_jisx0208_1978);
Vcharset_japanese_jisx0208_1978 =
make_charset (LEADING_BYTE_JAPANESE_JISX0208_1978, Qjapanese_jisx0208_1978, 3,
CHARSET_TYPE_94X94, 2, 0, '@',
build_string
("JISX0208.1978 Japanese Kanji (so called \"old JIS\")"),
build_string ("\\(jisx0208\\|jisc6226\\)\\.1978"));
+ staticpro (&Vcharset_chinese_gb2312);
Vcharset_chinese_gb2312 =
make_charset (LEADING_BYTE_CHINESE_GB2312, Qchinese_gb2312, 3,
CHARSET_TYPE_94X94, 2, 0, 'A',
build_string ("GB2312)"),
build_string ("GB2312 Chinese simplified"),
build_string ("gb2312"));
+ staticpro (&Vcharset_japanese_jisx0208);
Vcharset_japanese_jisx0208 =
make_charset (LEADING_BYTE_JAPANESE_JISX0208, Qjapanese_jisx0208, 3,
CHARSET_TYPE_94X94, 2, 0, 'B',
build_string ("JISX0208.1983/1990 (Japanese)"),
build_string ("JISX0208.1983/1990 Japanese Kanji"),
build_string ("jisx0208.19\\(83\\|90\\)"));
+ staticpro (&Vcharset_korean_ksc5601);
Vcharset_korean_ksc5601 =
make_charset (LEADING_BYTE_KOREAN_KSC5601, Qkorean_ksc5601, 3,
CHARSET_TYPE_94X94, 2, 0, 'C',
build_string ("KSC5601 (Korean"),
build_string ("KSC5601 Korean Hangul and Hanja"),
build_string ("ksc5601"));
+ staticpro (&Vcharset_japanese_jisx0212);
Vcharset_japanese_jisx0212 =
make_charset (LEADING_BYTE_JAPANESE_JISX0212, Qjapanese_jisx0212, 3,
CHARSET_TYPE_94X94, 2, 0, 'D',
build_string ("jisx0212"));
#define CHINESE_CNS_PLANE_RE(n) "cns11643[.-]\\(.*[.-]\\)?" n "$"
+ staticpro (&Vcharset_chinese_cns11643_1);
Vcharset_chinese_cns11643_1 =
make_charset (LEADING_BYTE_CHINESE_CNS11643_1, Qchinese_cns11643_1, 3,
CHARSET_TYPE_94X94, 2, 0, 'G',
build_string
("CNS 11643 Plane 1 Chinese traditional"),
build_string (CHINESE_CNS_PLANE_RE("1")));
+ staticpro (&Vcharset_chinese_cns11643_2);
Vcharset_chinese_cns11643_2 =
make_charset (LEADING_BYTE_CHINESE_CNS11643_2, Qchinese_cns11643_2, 3,
CHARSET_TYPE_94X94, 2, 0, 'H',
build_string
("CNS 11643 Plane 2 Chinese traditional"),
build_string (CHINESE_CNS_PLANE_RE("2")));
+ staticpro (&Vcharset_chinese_big5_1);
Vcharset_chinese_big5_1 =
make_charset (LEADING_BYTE_CHINESE_BIG5_1, Qchinese_big5_1, 3,
CHARSET_TYPE_94X94, 2, 0, '0',
build_string
("Big5 Level-1 Chinese traditional"),
build_string ("big5"));
+ staticpro (&Vcharset_chinese_big5_2);
Vcharset_chinese_big5_2 =
make_charset (LEADING_BYTE_CHINESE_BIG5_2, Qchinese_big5_2, 3,
CHARSET_TYPE_94X94, 2, 0, '1',
/* #### For simplicity, we put composite chars into a 96x96 charset.
This is going to lead to problems because you can run out of
room, esp. as we don't yet recycle numbers. */
+ staticpro (&Vcharset_composite);
Vcharset_composite =
make_charset (LEADING_BYTE_COMPOSITE, Qcomposite, 3,
CHARSET_TYPE_96X96, 2, 0, 0,
build_string ("Composite characters"),
build_string (""));
+ /* #### not dumped properly */
composite_char_row_next = 32;
composite_char_col_next = 32;
#define XCHARSET(x) XRECORD (x, charset, struct Lisp_Charset)
#define XSETCHARSET(x, p) XSETRECORD (x, p, charset)
#define CHARSETP(x) RECORDP (x, charset)
-#define GC_CHARSETP(x) GC_RECORDP (x, charset)
#define CHECK_CHARSET(x) CHECK_RECORD (x, charset)
#define CONCHECK_CHARSET(x) CONCHECK_RECORD (x, charset)
/* Leading byte and id have been regrouped. -- OG */
#define CHARSET_ID(cs) ((cs)->id)
-#define CHARSET_LEADING_BYTE(cs) ((Bufbyte)(CHARSET_ID(cs)))
+#define CHARSET_LEADING_BYTE(cs) ((Bufbyte) CHARSET_ID(cs))
#define CHARSET_NAME(cs) ((cs)->name)
#define CHARSET_SHORT_NAME(cs) ((cs)->short_name)
#define CHARSET_LONG_NAME(cs) ((cs)->long_name)
#define XCHARSET_REVERSE_DIRECTION_CHARSET(cs) \
CHARSET_REVERSE_DIRECTION_CHARSET (XCHARSET (cs))
-/* Table of charsets indexed by (leading byte - 128). */
-extern Lisp_Object charset_by_leading_byte[NUM_LEADING_BYTES];
+struct charset_lookup {
+ /* Table of charsets indexed by leading byte. */
+ Lisp_Object charset_by_leading_byte[128];
+
+ /* Table of charsets indexed by type/final-byte/direction. */
+ Lisp_Object charset_by_attributes[4][128][2];
+};
-/* Table of charsets indexed by type/final-byte/direction. */
-extern Lisp_Object charset_by_attributes[4][128][2];
+extern struct charset_lookup *chlook;
/* Table of number of bytes in the string representation of a character
indexed by the first byte of that representation.
{
assert (lb >= MIN_LEADING_BYTE &&
lb < (MIN_LEADING_BYTE + NUM_LEADING_BYTES));
- return charset_by_leading_byte[lb - MIN_LEADING_BYTE];
+ return chlook->charset_by_leading_byte[lb - MIN_LEADING_BYTE];
}
#else
#define CHARSET_BY_LEADING_BYTE(lb) \
- (charset_by_leading_byte[(lb) - MIN_LEADING_BYTE])
+ (chlook->charset_by_leading_byte[(lb) - MIN_LEADING_BYTE])
#endif
#define CHARSET_BY_ATTRIBUTES(type, final, dir) \
- (charset_by_attributes[type][final][dir])
+ (chlook->charset_by_attributes[type][final][dir])
#ifdef ERROR_CHECK_TYPECHECK
}
void
-vars_of_mule_wnn (void)
+reinit_vars_of_mule_wnn (void)
{
int i;
+ for (i = 0; i < NSERVER; i++)
+ {
+ wnnfns_buf[i] = (struct wnn_buf *) 0;
+ wnnfns_env_norm[i] = (struct wnn_env *) 0;
+ wnnfns_env_rev[i] = (struct wnn_env *) 0;
+ }
+}
+
+void
+vars_of_mule_wnn (void)
+{
+ reinit_vars_of_mule_wnn ();
+
DEFVAR_INT ("lb-sisheng", &lb_sisheng /*
Leading character for Sisheng.
*/ );
Vwnn_uniq_level = Qwnn_uniq;
- for (i = 0; i < NSERVER; i++)
- {
- wnnfns_buf[i] = (struct wnn_buf *) 0;
- wnnfns_env_norm[i] = (struct wnn_env *) 0;
- wnnfns_env_rev[i] = (struct wnn_env *) 0;
- }
-
Fprovide(intern("wnn"));
}
/* Useful routines for manipulating memory-mapped files. */
typedef struct file_data {
- char *name;
+ CONST char *name;
unsigned long size;
HANDLE file;
HANDLE file_mapping;
void
vars_of_ntproc (void)
{
- Qhigh = intern ("high");
- Qlow = intern ("low");
+ defsymbol (&Qhigh, "high");
+ defsymbol (&Qlow, "low");
DEFVAR_LISP ("win32-quote-process-args", &Vwin32_quote_process_args /*
Non-nil enables quoting of process arguments to ensure correct parsing.
#if 0
static void
-mswindows_mark_color_instance (struct Lisp_Color_Instance *c,
- void (*markobj) (Lisp_Object))
+mswindows_mark_color_instance (struct Lisp_Color_Instance *c)
{
}
#endif
static unsigned long
mswindows_color_instance_hash (struct Lisp_Color_Instance *c, int depth)
{
- return (unsigned long)(COLOR_INSTANCE_MSWINDOWS_COLOR(c));
+ return (unsigned long) COLOR_INSTANCE_MSWINDOWS_COLOR(c);
}
static Lisp_Object
#if 0
static void
-mswindows_mark_font_instance (struct Lisp_Font_Instance *f,
- void (*markobj) (Lisp_Object))
+mswindows_mark_font_instance (struct Lisp_Font_Instance *f)
{
}
#endif
}
static void
-tty_mark_color_instance (struct Lisp_Color_Instance *c,
- void (*markobj) (Lisp_Object))
+tty_mark_color_instance (struct Lisp_Color_Instance *c)
{
- markobj (COLOR_INSTANCE_TTY_SYMBOL (c));
+ mark_object (COLOR_INSTANCE_TTY_SYMBOL (c));
}
static void
}
static void
-tty_mark_font_instance (struct Lisp_Font_Instance *f,
- void (*markobj) (Lisp_Object))
+tty_mark_font_instance (struct Lisp_Font_Instance *f)
{
- markobj (FONT_INSTANCE_TTY_CHARSET (f));
+ mark_object (FONT_INSTANCE_TTY_CHARSET (f));
}
static void
#include <config.h>
#include "lisp.h"
+#include <limits.h>
#include "console-x.h"
#include "objects-x.h"
/* Replacement for XAllocColor() that tries to return the nearest
available color if the colormap is full. Original was from FSFmacs,
- but rewritten by Jareth Hein <jareth@camelot-soft.com> 97/11/25 */
+ but rewritten by Jareth Hein <jareth@camelot-soft.com> 97/11/25
+ Modified by Lee Kindness <lkindness@csl.co.uk> 31/08/99 to handle previous
+ total failure which was due to a read/write colorcell being the nearest
+ match - tries the next nearest...
-/* Return value is 1 for normal success, 2 for nearest color success,
- 3 for Non-deallocable sucess, and 0 for absolute failure (shouldn't
- happen?) */
+ Return value is 1 for normal success, 2 for nearest color success,
+ 3 for Non-deallocable sucess. */
int
allocate_nearest_color (Display *display, Colormap colormap, Visual *visual,
XColor *color_def)
}
else
{
+ XColor *cells = NULL;
+ /* JH: I can't believe there's no way to go backwards from a
+ colormap ID and get its visual and number of entries, but X
+ apparently isn't built that way... */
+ int no_cells = visual->map_entries;
+ status = 0;
+
if (XAllocColor (display, colormap, color_def) != 0)
status = 1;
- else
+ else while( status != 2 )
{
/* If we got to this point, the colormap is full, so we're
going to try and get the next closest color. The algorithm used
is a least-squares matching, which is what X uses for closest
color matching with StaticColor visuals. */
- XColor *cells;
- /* JH: I can't believe there's no way to go backwards from a
- colormap ID and get its visual and number of entries, but X
- apparently isn't built that way... */
- int no_cells = visual->map_entries;
int nearest;
long nearest_delta, trial_delta;
int x;
- cells = alloca_array (XColor, no_cells);
+ if( cells == NULL )
+ {
+ cells = alloca_array (XColor, no_cells);
+ for (x = 0; x < no_cells; x++)
+ cells[x].pixel = x;
- for (x = 0; x < no_cells; x++)
- cells[x].pixel = x;
+ /* read the current colormap */
+ XQueryColors (display, colormap, cells, no_cells);
+ }
- /* read the current colormap */
- XQueryColors (display, colormap, cells, no_cells);
nearest = 0;
/* I'm assuming CSE so I'm not going to condense this. */
nearest_delta = ((((color_def->red >> 8) - (cells[0].red >> 8))
+
(((color_def->blue >> 8) - (cells[x].blue >> 8))
* ((color_def->blue >> 8) - (cells[x].blue >> 8))));
- if (trial_delta < nearest_delta)
+
+ /* less? Ignore cells marked as previously failing */
+ if( (trial_delta < nearest_delta) &&
+ (cells[x].pixel != ULONG_MAX) )
{
nearest = x;
nearest_delta = trial_delta;
color_def->red = cells[nearest].red;
color_def->green = cells[nearest].green;
color_def->blue = cells[nearest].blue;
- if (XAllocColor (display, colormap, color_def) != 0) {
- status = 2;
- } else {
- status = 0; /* JH: how does this happen??? DOES this happen??? */
- fprintf(stderr,"allocate_nearest_color returned 0!!!\n");
- }
+ if (XAllocColor (display, colormap, color_def) != 0)
+ status = 2;
+ else
+ /* LSK: Either the colour map has changed since
+ * we read it, or the colour is allocated
+ * read/write... Mark this cmap entry so it's
+ * ignored in the next iteration.
+ */
+ cells[nearest].pixel = ULONG_MAX;
}
}
return status;
x_parse_nearest_color (struct device *d, XColor *color, Bufbyte *name,
Bytecount len, Error_behavior errb)
{
- Display *dpy;
- Colormap cmap;
- Visual *visual;
+ Display *dpy = DEVICE_X_DISPLAY (d);
+ Colormap cmap = DEVICE_X_COLORMAP (d);
+ Visual *visual = DEVICE_X_VISUAL (d);
int result;
- dpy = DEVICE_X_DISPLAY (d);
- cmap = DEVICE_X_COLORMAP(d);
- visual = DEVICE_X_VISUAL (d);
-
xzero (*color);
{
CONST Extbyte *extname;
}
static void
-x_mark_font_instance (struct Lisp_Font_Instance *f,
- void (*markobj) (Lisp_Object))
+x_mark_font_instance (struct Lisp_Font_Instance *f)
{
- markobj (FONT_INSTANCE_X_TRUENAME (f));
+ mark_object (FONT_INSTANCE_X_TRUENAME (f));
}
static void
Lisp_Object Qcolor_instancep;
static Lisp_Object
-mark_color_instance (Lisp_Object obj, void (*markobj) (Lisp_Object))
+mark_color_instance (Lisp_Object obj)
{
struct Lisp_Color_Instance *c = XCOLOR_INSTANCE (obj);
- markobj (c->name);
+ mark_object (c->name);
if (!NILP (c->device)) /* Vthe_null_color_instance */
- MAYBE_DEVMETH (XDEVICE (c->device), mark_color_instance, (c, markobj));
+ MAYBE_DEVMETH (XDEVICE (c->device), mark_color_instance, (c));
return c->device;
}
struct Lisp_Color_Instance *c2 = XCOLOR_INSTANCE (obj2);
return (c1 == c2) ||
- ((EQ (c1->device, c2->device)) &&
+ (EQ (c1->device, c2->device) &&
DEVICEP (c1->device) &&
HAS_DEVMETH_P (XDEVICE (c1->device), color_instance_equal) &&
DEVMETH (XDEVICE (c1->device), color_instance_equal, (c1, c2, depth)));
Error_behavior errb);
static Lisp_Object
-mark_font_instance (Lisp_Object obj, void (*markobj) (Lisp_Object))
+mark_font_instance (Lisp_Object obj)
{
struct Lisp_Font_Instance *f = XFONT_INSTANCE (obj);
- markobj (f->name);
+ mark_object (f->name);
if (!NILP (f->device)) /* Vthe_null_font_instance */
- MAYBE_DEVMETH (XDEVICE (f->device), mark_font_instance, (f, markobj));
+ MAYBE_DEVMETH (XDEVICE (f->device), mark_font_instance, (f));
return f->device;
}
}
static void
-color_mark (Lisp_Object obj, void (*markobj) (Lisp_Object))
+color_mark (Lisp_Object obj)
{
struct Lisp_Specifier *color = XCOLOR_SPECIFIER (obj);
- markobj (COLOR_SPECIFIER_FACE (color));
- markobj (COLOR_SPECIFIER_FACE_PROPERTY (color));
+ mark_object (COLOR_SPECIFIER_FACE (color));
+ mark_object (COLOR_SPECIFIER_FACE_PROPERTY (color));
}
/* No equal or hash methods; ignore the face the color is based off
}
static void
-font_mark (Lisp_Object obj, void (*markobj) (Lisp_Object))
+font_mark (Lisp_Object obj)
{
struct Lisp_Specifier *font = XFONT_SPECIFIER (obj);
- markobj (FONT_SPECIFIER_FACE (font));
- markobj (FONT_SPECIFIER_FACE_PROPERTY (font));
+ mark_object (FONT_SPECIFIER_FACE (font));
+ mark_object (FONT_SPECIFIER_FACE_PROPERTY (font));
}
/* No equal or hash methods; ignore the face the font is based off
}
static void
-face_boolean_mark (Lisp_Object obj, void (*markobj) (Lisp_Object))
+face_boolean_mark (Lisp_Object obj)
{
struct Lisp_Specifier *face_boolean = XFACE_BOOLEAN_SPECIFIER (obj);
- markobj (FACE_BOOLEAN_SPECIFIER_FACE (face_boolean));
- markobj (FACE_BOOLEAN_SPECIFIER_FACE_PROPERTY (face_boolean));
+ mark_object (FACE_BOOLEAN_SPECIFIER_FACE (face_boolean));
+ mark_object (FACE_BOOLEAN_SPECIFIER_FACE_PROPERTY (face_boolean));
}
/* No equal or hash methods; ignore the face the face-boolean is based off
defsymbol (&Qface_boolean, "face-boolean");
}
+static const struct lrecord_description color_specifier_description[] = {
+ { XD_LISP_OBJECT, specifier_data_offset + offsetof(struct color_specifier, face), 2 },
+ { XD_END }
+};
+
+static const struct lrecord_description font_specifier_description[] = {
+ { XD_LISP_OBJECT, specifier_data_offset + offsetof(struct font_specifier, face), 2 },
+ { XD_END }
+};
+
+static const struct lrecord_description face_boolean_specifier_description[] = {
+ { XD_LISP_OBJECT, specifier_data_offset + offsetof(struct face_boolean_specifier, face), 2 },
+ { XD_END }
+};
+
void
specifier_type_create_objects (void)
{
}
void
-vars_of_objects (void)
+reinit_specifier_type_create_objects (void)
{
- staticpro (&Vthe_null_color_instance);
+ REINITIALIZE_SPECIFIER_TYPE (color);
+ REINITIALIZE_SPECIFIER_TYPE (font);
+ REINITIALIZE_SPECIFIER_TYPE (face_boolean);
+}
+
+void
+reinit_vars_of_objects (void)
+{
+ staticpro_nodump (&Vthe_null_color_instance);
{
struct Lisp_Color_Instance *c =
alloc_lcrecord_type (struct Lisp_Color_Instance, &lrecord_color_instance);
XSETCOLOR_INSTANCE (Vthe_null_color_instance, c);
}
- staticpro (&Vthe_null_font_instance);
+ staticpro_nodump (&Vthe_null_font_instance);
{
struct Lisp_Font_Instance *f =
alloc_lcrecord_type (struct Lisp_Font_Instance, &lrecord_font_instance);
XSETFONT_INSTANCE (Vthe_null_font_instance, f);
}
}
+
+void
+vars_of_objects (void)
+{
+ reinit_vars_of_objects ();
+}
Lisp_Object face_property; /* property of that face */
};
-#define COLOR_SPECIFIER_DATA(g) (SPECIFIER_TYPE_DATA (g, color))
+#define COLOR_SPECIFIER_DATA(g) SPECIFIER_TYPE_DATA (g, color)
#define COLOR_SPECIFIER_FACE(g) (COLOR_SPECIFIER_DATA (g)->face)
#define COLOR_SPECIFIER_FACE_PROPERTY(g) \
(COLOR_SPECIFIER_DATA (g)->face_property)
Lisp_Object face_property; /* property of that face */
};
-#define FONT_SPECIFIER_DATA(g) (SPECIFIER_TYPE_DATA (g, font))
+#define FONT_SPECIFIER_DATA(g) SPECIFIER_TYPE_DATA (g, font)
#define FONT_SPECIFIER_FACE(g) (FONT_SPECIFIER_DATA (g)->face)
#define FONT_SPECIFIER_FACE_PROPERTY(g) \
(FONT_SPECIFIER_DATA (g)->face_property)
Lisp_Object face_property; /* property of that face */
};
-#define FACE_BOOLEAN_SPECIFIER_DATA(g) (SPECIFIER_TYPE_DATA (g, face_boolean))
+#define FACE_BOOLEAN_SPECIFIER_DATA(g) SPECIFIER_TYPE_DATA (g, face_boolean)
#define FACE_BOOLEAN_SPECIFIER_FACE(g) (FACE_BOOLEAN_SPECIFIER_DATA (g)->face)
#define FACE_BOOLEAN_SPECIFIER_FACE_PROPERTY(g) \
(FACE_BOOLEAN_SPECIFIER_DATA (g)->face_property)
XRECORD (x, color_instance, struct Lisp_Color_Instance)
#define XSETCOLOR_INSTANCE(x, p) XSETRECORD (x, p, color_instance)
#define COLOR_INSTANCEP(x) RECORDP (x, color_instance)
-#define GC_COLOR_INSTANCEP(x) GC_RECORDP (x, color_instance)
#define CHECK_COLOR_INSTANCE(x) CHECK_RECORD (x, color_instance)
#define CONCHECK_COLOR_INSTANCE(x) CONCHECK_RECORD (x, color_instance)
#define XFONT_INSTANCE(x) XRECORD (x, font_instance, struct Lisp_Font_Instance)
#define XSETFONT_INSTANCE(x, p) XSETRECORD (x, p, font_instance)
#define FONT_INSTANCEP(x) RECORDP (x, font_instance)
-#define GC_FONT_INSTANCEP(x) GC_RECORDP (x, font_instance)
#define CHECK_FONT_INSTANCE(x) CHECK_RECORD (x, font_instance)
#define CONCHECK_FONT_INSTANCE(x) CONCHECK_RECORD (x, font_instance)
OPAQUE OBJECTS SHOULD NEVER ESCAPE TO THE LISP LEVEL. Some code
depends on this. As such, opaque objects are a generalization
of the Qunbound marker.
-
- "Opaque lists" are used to keep track of lots of opaque objects
- of a particular size so that they can be efficiently "freed" and
- re-used again without actually entering the Lisp allocation system
- (and consequently doing a malloc()).
*/
#include <config.h>
#include "lisp.h"
#include "opaque.h"
-Lisp_Object Qopaquep;
-
-static int in_opaque_list_marking;
-
-/* Holds freed opaque objects created with make_opaque_ptr().
- We do this quite often so it's a noticeable win if we don't
- create GC junk. */
Lisp_Object Vopaque_ptr_free_list;
-static Lisp_Object
-mark_opaque (Lisp_Object obj, void (*markobj) (Lisp_Object))
-{
- Lisp_Opaque *p = XOPAQUE (obj);
- /* Egcs 1.1.1 sometimes crashes on INTP (p->size_or_chain) */
- Lisp_Object size_or_chain = p->size_or_chain;
-#ifdef ERROR_CHECK_GC
- if (!in_opaque_list_marking)
- /* size is non-int for objects on an opaque free list. We sure
- as hell better not be marking any of these objects unless
- we're marking an opaque list. */
- assert (GC_INTP (size_or_chain));
- else
- /* marking an opaque on the free list doesn't do any recursive
- markings, so we better not have non-freed opaques on a free
- list. */
- assert (!GC_INTP (size_or_chain));
-#endif
- if (GC_INTP (size_or_chain) && OPAQUE_MARKFUN (p))
- return OPAQUE_MARKFUN (p) (obj, markobj);
- else
- return size_or_chain;
-}
-
/* Should never, ever be called. (except by an external debugger) */
static void
print_opaque (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
{
CONST Lisp_Opaque *p = XOPAQUE (obj);
- /* Egcs 1.1.1 sometimes crashes on INTP (p->size_or_chain) */
- Lisp_Object size_or_chain = p->size_or_chain;
char buf[200];
- char size_buf[50];
-
- if (INTP (size_or_chain))
- sprintf (size_buf, "size=%lu", (unsigned long) OPAQUE_SIZE (p));
- else
- sprintf (size_buf, "freed");
- sprintf (buf, "#<INTERNAL OBJECT (XEmacs bug?) (opaque, %s) 0x%lx>",
- size_buf, (unsigned long) p);
+ sprintf (buf, "#<INTERNAL OBJECT (XEmacs bug?) (opaque, size=%lu) 0x%lx>",
+ (long)(p->size), (unsigned long) p);
write_c_string (buf, printcharfun);
}
sizeof_opaque (CONST void *header)
{
CONST Lisp_Opaque *p = (CONST Lisp_Opaque *) header;
- /* Egcs 1.1.1 sometimes crashes on INTP (p->size_or_chain) */
- Lisp_Object size_or_chain = p->size_or_chain;
- return offsetof (Lisp_Opaque, data)
- + (GC_INTP (size_or_chain) ? XINT (size_or_chain) : 0);
+ return offsetof (Lisp_Opaque, data) + p->size;
}
/* Return an opaque object of size SIZE.
{
Lisp_Opaque *p = (Lisp_Opaque *)
alloc_lcrecord (offsetof (Lisp_Opaque, data) + size, &lrecord_opaque);
- p->markfun = 0;
- p->size_or_chain = make_int (size);
+ p->size = size;
if (data == OPAQUE_CLEAR)
memset (p->data, '\0', size);
static int
equal_opaque (Lisp_Object obj1, Lisp_Object obj2, int depth)
{
-#ifdef DEBUG_XEMACS
- {
- /* Egcs 1.1.1 sometimes crashes on INTP (p->size_or_chain) */
- Lisp_Object size_or_chain_1 = XOPAQUE (obj1)->size_or_chain;
- Lisp_Object size_or_chain_2 = XOPAQUE (obj2)->size_or_chain;
- assert (INTP (size_or_chain_1));
- assert (INTP (size_or_chain_2));
- assert (!XOPAQUE_MARKFUN (obj1) && !XOPAQUE_MARKFUN (obj2));
- }
-#endif
- {
- size_t size;
- return ((size = XOPAQUE_SIZE (obj1)) == XOPAQUE_SIZE (obj2) &&
- !memcmp (XOPAQUE_DATA (obj1), XOPAQUE_DATA (obj2), size));
- }
+ size_t size;
+ return ((size = XOPAQUE_SIZE (obj1)) == XOPAQUE_SIZE (obj2) &&
+ !memcmp (XOPAQUE_DATA (obj1), XOPAQUE_DATA (obj2), size));
}
/* This will not work correctly for opaques with subobjects! */
static unsigned long
hash_opaque (Lisp_Object obj, int depth)
{
-#ifdef DEBUG_XEMACS
- {
- /* Egcs 1.1.1 sometimes crashes on INTP (p->size_or_chain) */
- Lisp_Object size_or_chain = XOPAQUE (obj)->size_or_chain;
- assert (INTP (size_or_chain));
- assert (!XOPAQUE_MARKFUN (obj));
- }
-#endif
if (XOPAQUE_SIZE (obj) == sizeof (unsigned long))
return *((unsigned long *) XOPAQUE_DATA (obj));
else
return memory_hash (XOPAQUE_DATA (obj), XOPAQUE_SIZE (obj));
}
+static const struct lrecord_description opaque_description[] = {
+ { XD_END }
+};
+
DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION ("opaque", opaque,
- mark_opaque, print_opaque, 0,
- equal_opaque, hash_opaque, 0,
+ 0, print_opaque, 0,
+ equal_opaque, hash_opaque,
+ opaque_description,
sizeof_opaque, Lisp_Opaque);
-static Lisp_Object
-mark_opaque_list (Lisp_Object obj, void (*markobj) (Lisp_Object))
-{
- in_opaque_list_marking++;
- markobj (XOPAQUE_LIST (obj)->free);
- in_opaque_list_marking--;
- return Qnil;
-}
+/* stuff to handle opaque pointers */
-Lisp_Object
-make_opaque_list (size_t size,
- Lisp_Object (*markfun) (Lisp_Object obj,
- void (*markobj) (Lisp_Object)))
+/* Should never, ever be called. (except by an external debugger) */
+static void
+print_opaque_ptr (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
{
- Lisp_Object val;
- Lisp_Opaque_List *p =
- alloc_lcrecord_type (Lisp_Opaque_List, &lrecord_opaque_list);
+ CONST Lisp_Opaque_Ptr *p = XOPAQUE_PTR (obj);
+ char buf[200];
- p->markfun = markfun;
- p->size = size;
- p->free = Qnil;
- XSETOPAQUE_LIST (val, p);
- return val;
+ sprintf (buf, "#<INTERNAL OBJECT (XEmacs bug?) (opaque_ptr, adr=0x%lx) 0x%lx>",
+ (long)(p->ptr), (unsigned long) p);
+ write_c_string (buf, printcharfun);
}
-DEFINE_LRECORD_IMPLEMENTATION ("opaque-list", opaque_list,
- mark_opaque_list, internal_object_printer,
- 0, 0, 0, 0, Lisp_Opaque_List);
-
-Lisp_Object
-allocate_managed_opaque (Lisp_Object opaque_list, CONST void *data)
+static int
+equal_opaque_ptr (Lisp_Object obj1, Lisp_Object obj2, int depth)
{
- Lisp_Opaque_List *li = XOPAQUE_LIST (opaque_list);
- Lisp_Object val;
-
- if (!NILP (li->free))
- {
- val = li->free;
- li->free = XOPAQUE (val)->size_or_chain;
-#ifdef ERROR_CHECK_GC
- assert (NILP (li->free) || OPAQUEP (li->free));
-#endif
- XOPAQUE (val)->size_or_chain = make_int (li->size);
- if (data)
- memcpy (XOPAQUE (val)->data, data, li->size);
- else
- memset (XOPAQUE (val)->data, 0, li->size);
- }
- else
- val = make_opaque (li->size, data);
- XOPAQUE (val)->markfun = li->markfun;
- return val;
+ return (XOPAQUE_PTR (obj1)->ptr == XOPAQUE_PTR (obj2)->ptr);
}
-void
-free_managed_opaque (Lisp_Object opaque_list, Lisp_Object opaque)
+static unsigned long
+hash_opaque_ptr (Lisp_Object obj, int depth)
{
- Lisp_Opaque_List *li = XOPAQUE_LIST (opaque_list);
-
-#ifdef ERROR_CHECK_GC
- {
- /* Egcs 1.1.1 sometimes crashes on INTP (p->size_or_chain) */
- Lisp_Object size_or_chain = XOPAQUE (opaque)->size_or_chain;
- assert (INTP (size_or_chain));
- }
-#endif
- XOPAQUE (opaque)->size_or_chain = li->free;
- li->free = opaque;
+ return (unsigned long) XOPAQUE_PTR (obj)->ptr;
}
-/* stuff to handle opaque pointers */
+DEFINE_LRECORD_IMPLEMENTATION ("opaque_ptr", opaque_ptr,
+ 0, print_opaque_ptr, 0,
+ equal_opaque_ptr, hash_opaque_ptr, 0,
+ Lisp_Opaque_Ptr);
Lisp_Object
-make_opaque_ptr (CONST void *val)
+make_opaque_ptr (void *val)
{
- return allocate_managed_opaque (Vopaque_ptr_free_list,
- (CONST void *) &val);
+ Lisp_Object res = allocate_managed_lcrecord(Vopaque_ptr_free_list);
+ set_opaque_ptr (res, val);
+ return res;
}
/* Be very very careful with this. Same admonitions as with
void
free_opaque_ptr (Lisp_Object ptr)
{
- free_managed_opaque (Vopaque_ptr_free_list, ptr);
+ free_managed_lcrecord (Vopaque_ptr_free_list, ptr);
}
-Lisp_Object
-make_opaque_long (long val)
+void
+reinit_opaque_once_early (void)
{
- return make_opaque (sizeof (val), (void *) &val);
+ Vopaque_ptr_free_list = make_lcrecord_list (sizeof (Lisp_Opaque_Ptr), &lrecord_opaque_ptr);
+ staticpro_nodump (&Vopaque_ptr_free_list);
}
void
init_opaque_once_early (void)
{
- Vopaque_ptr_free_list = make_opaque_list (sizeof (void *), 0);
- staticpro (&Vopaque_ptr_free_list);
+ reinit_opaque_once_early ();
}
typedef struct Lisp_Opaque
{
struct lcrecord_header header;
- Lisp_Object (*markfun) (Lisp_Object obj, void (*markobj) (Lisp_Object));
- /* An integral size for non-freed objects, an opaque or nil for
- freed objects. */
- Lisp_Object size_or_chain;
+ size_t size;
max_align_t data[1];
} Lisp_Opaque;
-typedef struct Lisp_Opaque_List
-{
- struct lcrecord_header header;
- /* `markfun' allows you to put lisp objects inside of opaque objects
- without having to create a new object type. */
- Lisp_Object (*markfun) (Lisp_Object obj, void (*markobj) (Lisp_Object));
- Lisp_Object free;
- size_t size;
-} Lisp_Opaque_List;
-
DECLARE_LRECORD (opaque, Lisp_Opaque);
#define XOPAQUE(x) XRECORD (x, opaque, Lisp_Opaque)
#define XSETOPAQUE(x, p) XSETRECORD (x, p, opaque)
#define OPAQUEP(x) RECORDP (x, opaque)
-#define GC_OPAQUEP(x) GC_RECORDP (x, opaque)
/* #define CHECK_OPAQUE(x) CHECK_RECORD (x, opaque)
Opaque pointers should never escape to the Lisp level, so
functions should not be doing this. */
-DECLARE_LRECORD (opaque_list, Lisp_Opaque_List);
-#define XOPAQUE_LIST(x) XRECORD (x, opaque_list, Lisp_Opaque_List)
-#define XSETOPAQUE_LIST(x, p) XSETRECORD (x, p, opaque_list)
-#define OPAQUE_LISTP(x) RECORDP (x, opaque_list)
-#define GC_OPAQUE_LISTP(x) GC_RECORDP (x, opaque_list)
-/* #define CHECK_OPAQUE_LIST(x) CHECK_RECORD (x, opaque_list)
- Opaque lists should never escape to the Lisp level, so
- functions should not be doing this. */
-
/* Alternative DATA arguments to make_opaque */
#define OPAQUE_CLEAR ((CONST void *) 0)
#define OPAQUE_UNINIT ((CONST void *) -1)
-Lisp_Object make_opaque (size_t size, CONST void *data);
-Lisp_Object make_opaque_ptr (CONST void *val);
-Lisp_Object make_opaque_long (long val);
-void free_opaque_ptr (Lisp_Object ptr);
-
-#define OPAQUE_SIZE(op) XINT ((op)->size_or_chain)
+#define OPAQUE_SIZE(op) ((op)->size)
#define OPAQUE_DATA(op) ((void *) ((op)->data))
#define OPAQUE_MARKFUN(op) ((op)->markfun)
#define XOPAQUE_SIZE(op) OPAQUE_SIZE (XOPAQUE (op))
#define XOPAQUE_DATA(op) OPAQUE_DATA (XOPAQUE (op))
#define XOPAQUE_MARKFUN(op) OPAQUE_MARKFUN (XOPAQUE (op))
-#define get_opaque_ptr(op) (* (void **) XOPAQUE_DATA (op))
-#define set_opaque_ptr(op, ptr) (get_opaque_ptr (op) = (void *) ptr)
-#define get_opaque_long(op) (* (long *) XOPAQUE_DATA (op))
-#define set_opaque_long(op, ptr) (get_opaque_long (op) = ptr)
-#define set_opaque_markfun(op, fun) (XOPAQUE_MARKFUN (op) = fun)
-
-Lisp_Object make_opaque_list (size_t size,
- Lisp_Object (*markfun)
- (Lisp_Object obj,
- void (*markobj) (Lisp_Object)));
-Lisp_Object allocate_managed_opaque (Lisp_Object opaque_list,
- CONST void *data);
-void free_managed_opaque (Lisp_Object opaque_list, Lisp_Object opaque);
+Lisp_Object make_opaque (size_t size, CONST void *data);
+
+typedef struct Lisp_Opaque_Ptr
+{
+ struct lcrecord_header header;
+ void *ptr;
+} Lisp_Opaque_Ptr;
+
+DECLARE_LRECORD (opaque_ptr, Lisp_Opaque_Ptr);
+#define XOPAQUE_PTR(x) XRECORD (x, opaque_ptr, Lisp_Opaque_Ptr)
+#define XSETOPAQUE_PTR(x, p) XSETRECORD (x, p, opaque_ptr)
+#define OPAQUE_PTRP(x) RECORDP (x, opaque_ptr)
+
+Lisp_Object make_opaque_ptr (void *val);
+void free_opaque_ptr (Lisp_Object ptr);
+
+#define get_opaque_ptr(op) (XOPAQUE_PTR (op)->ptr)
+#define set_opaque_ptr(op, ptr_) (XOPAQUE_PTR (op)->ptr = (ptr_))
#endif /* _XEMACS_OPAQUE_H_ */
/* The subroutine object for external-debugging-output is kept here
for the convenience of the debugger. */
Lisp_Object Qexternal_debugging_output;
-Lisp_Object Qalternate_debugging_output;
/* Avoid actual stack overflow in print. */
static int print_depth;
/* Detect most circularities to print finite output. */
#define PRINT_CIRCLE 200
-Lisp_Object being_printed[PRINT_CIRCLE];
+static Lisp_Object being_printed[PRINT_CIRCLE];
/* Maximum length of list or vector to print in full; noninteger means
effectively infinity */
Lisp_Object Vprint_gensym;
Lisp_Object Vprint_gensym_alist;
-Lisp_Object Qprint_escape_newlines;
-Lisp_Object Qprint_readably;
-
Lisp_Object Qdisplay_error;
Lisp_Object Qprint_message_label;
#ifdef LISP_FLOAT_TYPE
Lisp_Object Vfloat_output_format;
-Lisp_Object Qfloat_output_format;
/*
* This buffer should be at least as large as the max string size of the
getting rid of this function altogether? Does anything actually
*use* it? --hniksic */
-int alternate_do_pointer;
-char alternate_do_string[5000];
+static int alternate_do_pointer;
+static char alternate_do_string[5000];
DEFUN ("alternate-debugging-output", Falternate_debugging_output, 1, 1, 0, /*
Append CHARACTER to the array `alternate_do_string'.
/* Debugging kludge -- unbuffered */
static int debug_print_length = 50;
static int debug_print_level = 15;
-Lisp_Object debug_temp;
static void
debug_print_no_newline (Lisp_Object debug_print_obj)
void
syms_of_print (void)
{
- defsymbol (&Qprint_escape_newlines, "print-escape-newlines");
- defsymbol (&Qprint_readably, "print-readably");
-
defsymbol (&Qstandard_output, "standard-output");
-#ifdef LISP_FLOAT_TYPE
- defsymbol (&Qfloat_output_format, "float-output-format");
-#endif
-
defsymbol (&Qprint_length, "print-length");
defsymbol (&Qprint_string_length, "print-string-length");
DEFSUBR (Fterpri);
DEFSUBR (Fwrite_char);
DEFSUBR (Falternate_debugging_output);
- defsymbol (&Qalternate_debugging_output, "alternate-debugging-output");
DEFSUBR (Fexternal_debugging_output);
DEFSUBR (Fopen_termscript);
defsymbol (&Qexternal_debugging_output, "external-debugging-output");
}
void
-vars_of_print (void)
+reinit_vars_of_print (void)
{
alternate_do_pointer = 0;
+}
+
+void
+vars_of_print (void)
+{
+ reinit_vars_of_print ();
DEFVAR_LISP ("standard-output", &Vstandard_output /*
Output stream `print' uses by default for outputting a character.
* must signal an error instead.
*/
-/* #### This function completely ignores Vprocess_environment */
-
static void
signal_cannot_launch (Lisp_Object image_file, DWORD err)
{
HANDLE hmyshove, hmyslurp, hprocin, hprocout;
LPTSTR command_line;
BOOL do_io, windowed;
+ char *proc_env;
/* Find out whether the application is windowed or not */
{
UNGCPRO; /* args_or_ret */
}
+ /* Set `proc_env' to a nul-separated array of the strings in
+ Vprocess_environment terminated by 2 nuls. */
+
+ {
+ extern int compare_env (const char **strp1, const char **strp2);
+ char **env;
+ REGISTER Lisp_Object tem;
+ REGISTER char **new_env;
+ REGISTER int new_length = 0, i, new_space;
+ char *penv;
+
+ for (tem = Vprocess_environment;
+ (CONSP (tem)
+ && STRINGP (XCAR (tem)));
+ tem = XCDR (tem))
+ new_length++;
+
+ /* new_length + 1 to include terminating 0. */
+ env = new_env = alloca_array (char *, new_length + 1);
+
+ /* Copy the Vprocess_environment strings into new_env. */
+ for (tem = Vprocess_environment;
+ (CONSP (tem)
+ && STRINGP (XCAR (tem)));
+ tem = XCDR (tem))
+ {
+ char **ep = env;
+ char *string = (char *) XSTRING_DATA (XCAR (tem));
+ /* See if this string duplicates any string already in the env.
+ If so, don't put it in.
+ When an env var has multiple definitions,
+ we keep the definition that comes first in process-environment. */
+ for (; ep != new_env; ep++)
+ {
+ char *p = *ep, *q = string;
+ while (1)
+ {
+ if (*q == 0)
+ /* The string is malformed; might as well drop it. */
+ goto duplicate;
+ if (*q != *p)
+ break;
+ if (*q == '=')
+ goto duplicate;
+ p++, q++;
+ }
+ }
+ *new_env++ = string;
+ duplicate: ;
+ }
+ *new_env = 0;
+
+ /* Sort the environment variables */
+ new_length = new_env - env;
+ qsort (env, new_length, sizeof (char *), compare_env);
+
+ /* Work out how much space to allocate */
+ new_space = 0;
+ for (i = 0; i < new_length; i++)
+ {
+ new_space += strlen(env[i]) + 1;
+ }
+ new_space++;
+
+ /* Allocate space and copy variables into it */
+ penv = proc_env = alloca(new_space);
+ for (i = 0; i < new_length; i++)
+ {
+ strcpy(penv, env[i]);
+ penv += strlen(env[i]) + 1;
+ }
+ *penv = 0;
+ }
+
/* Create process */
{
STARTUPINFO si;
err = (CreateProcess (NULL, command_line, NULL, NULL, TRUE,
CREATE_NEW_CONSOLE | CREATE_NEW_PROCESS_GROUP
| CREATE_SUSPENDED,
- NULL, (char *) XSTRING_DATA (cur_dir), &si, &pi)
+ proc_env, (char *) XSTRING_DATA (cur_dir), &si, &pi)
? 0 : GetLastError ());
if (do_io)
static void
nt_open_network_stream (Lisp_Object name, Lisp_Object host, Lisp_Object service,
- Lisp_Object family, void** vinfd, void** voutfd)
+ Lisp_Object protocol, void** vinfd, void** voutfd)
{
struct sockaddr_in address;
SOCKET s;
CHECK_STRING (host);
- if (!EQ (family, Qtcpip))
- error ("Unsupported protocol family \"%s\"",
- string_data (symbol_name (XSYMBOL (family))));
+ if (!EQ (protocol, Qtcp))
+ error ("Unsupported protocol \"%s\"",
+ string_data (symbol_name (XSYMBOL (protocol))));
if (INTP (service))
port = htons ((unsigned short) XINT (service));
end of the ptys. */
int failed_count = 0;
#endif
- int i;
int fd;
+#ifndef HAVE_GETPT
+ int i;
int c;
+#endif
#ifdef PTY_ITERATION
PTY_ITERATION
#else
sprintf (pty_name, "/dev/tty%c%x", c, i);
#endif /* no PTY_TTY_NAME_SPRINTF */
-#ifndef UNIPLUS
+#if !defined(UNIPLUS) && !defined(HAVE_GETPT)
if (access (pty_name, 6) != 0)
{
close (fd);
else
continue;
}
- else if ((INTP (tail_port)) && (htons ((unsigned short) XINT (tail_port)) == port))
+ else if (INTP (tail_port) && (htons ((unsigned short) XINT (tail_port)) == port))
break;
}
*/
static void
-unix_mark_process_data (struct Lisp_Process *proc,
- void (*markobj) (Lisp_Object))
+unix_mark_process_data (struct Lisp_Process *proc)
{
- markobj (UNIX_DATA(proc)->tty_name);
+ mark_object (UNIX_DATA(proc)->tty_name);
}
/*
static void
unix_open_network_stream (Lisp_Object name, Lisp_Object host, Lisp_Object service,
- Lisp_Object family, void** vinfd, void** voutfd)
+ Lisp_Object protocol, void** vinfd, void** voutfd)
{
struct sockaddr_in address;
- int s, inch, outch;
+ int inch;
+ int outch;
+ volatile int s;
volatile int port;
volatile int retry = 0;
int retval;
CHECK_STRING (host);
- if (!EQ (family, Qtcpip))
- error ("Unsupported protocol family \"%s\"",
- string_data (symbol_name (XSYMBOL (family))));
+ if (!EQ (protocol, Qtcp) && !EQ (protocol, Qudp))
+ error ("Unsupported protocol \"%s\"",
+ string_data (symbol_name (XSYMBOL (protocol))));
if (INTP (service))
port = htons ((unsigned short) XINT (service));
{
struct servent *svc_info;
CHECK_STRING (service);
- svc_info = getservbyname ((char *) XSTRING_DATA (service), "tcp");
+
+ if (EQ (protocol, Qtcp))
+ svc_info = getservbyname ((char *) XSTRING_DATA (service), "tcp");
+ else /* EQ (protocol, Qudp) */
+ svc_info = getservbyname ((char *) XSTRING_DATA (service), "udp");
+
if (svc_info == 0)
error ("Unknown service \"%s\"", XSTRING_DATA (service));
port = svc_info->s_port;
get_internet_address (host, &address, ERROR_ME);
address.sin_port = port;
- s = socket (address.sin_family, SOCK_STREAM, 0);
+ if (EQ (protocol, Qtcp))
+ s = socket (address.sin_family, SOCK_STREAM, 0);
+ else /* EQ (protocol, Qudp) */
+ s = socket (address.sin_family, SOCK_DGRAM, 0);
+
if (s < 0)
report_file_error ("error creating socket", list1 (name));
/* Qrun => Qopen, Qexit => Qclosed for "network connection" processes */
Lisp_Object Qopen, Qclosed;
/* Protocol families */
-Lisp_Object Qtcpip;
+Lisp_Object Qtcp, Qudp;
#ifdef HAVE_MULTICAST
Lisp_Object Qmulticast; /* Will be used for occasional warnings */
\f
static Lisp_Object
-mark_process (Lisp_Object obj, void (*markobj) (Lisp_Object))
+mark_process (Lisp_Object obj)
{
struct Lisp_Process *proc = XPROCESS (obj);
- MAYBE_PROCMETH (mark_process_data, (proc, markobj));
- markobj (proc->name);
- markobj (proc->command);
- markobj (proc->filter);
- markobj (proc->sentinel);
- markobj (proc->buffer);
- markobj (proc->mark);
- markobj (proc->pid);
- markobj (proc->pipe_instream);
- markobj (proc->pipe_outstream);
+ MAYBE_PROCMETH (mark_process_data, (proc));
+ mark_object (proc->name);
+ mark_object (proc->command);
+ mark_object (proc->filter);
+ mark_object (proc->sentinel);
+ mark_object (proc->buffer);
+ mark_object (proc->mark);
+ mark_object (proc->pid);
+ mark_object (proc->pipe_instream);
+ mark_object (proc->pipe_outstream);
#ifdef FILE_CODING
- markobj (proc->coding_instream);
- markobj (proc->coding_outstream);
+ mark_object (proc->coding_instream);
+ mark_object (proc->coding_outstream);
#endif
return proc->status_symbol;
}
int
network_connection_p (Lisp_Object process)
{
- return GC_CONSP (XPROCESS (process)->pid);
+ return CONSP (XPROCESS (process)->pid);
}
#endif
{
Lisp_Object tail;
- if (GC_PROCESSP (name))
+ if (PROCESSP (name))
return name;
if (!gc_in_progress)
of a signal or crash. */
CHECK_STRING (name);
- for (tail = Vprocess_list; GC_CONSP (tail); tail = XCDR (tail))
+ for (tail = Vprocess_list; CONSP (tail); tail = XCDR (tail))
{
Lisp_Object proc = XCAR (tail);
QUIT;
{
Lisp_Object buf, tail, proc;
- if (GC_NILP (name)) return Qnil;
+ if (NILP (name)) return Qnil;
buf = Fget_buffer (name);
- if (GC_NILP (buf)) return Qnil;
+ if (NILP (buf)) return Qnil;
- for (tail = Vprocess_list; GC_CONSP (tail); tail = XCDR (tail))
+ for (tail = Vprocess_list; CONSP (tail); tail = XCDR (tail))
{
/* jwz: do not quit here - it isn't necessary, as there is no way for
Vprocess_list to get circular or overwhelmingly long, and this
function is called from layout_mode_element under redisplay. */
/* QUIT; */
proc = XCAR (tail);
- if (GC_PROCESSP (proc) && EQ (XPROCESS (proc)->buffer, buf))
+ if (PROCESSP (proc) && EQ (XPROCESS (proc)->buffer, buf))
return proc;
}
return Qnil;
/* This may be called during a GC from process_send_signal() from
kill_buffer_processes() if emacs decides to abort(). */
- if (GC_PROCESSP (name))
+ if (PROCESSP (name))
return name;
- if (GC_STRINGP (name))
+ if (STRINGP (name))
{
obj = Fget_process (name);
- if (GC_NILP (obj))
+ if (NILP (obj))
obj = Fget_buffer (name);
- if (GC_NILP (obj))
+ if (NILP (obj))
error ("Process %s does not exist", XSTRING_DATA (name));
}
- else if (GC_NILP (name))
+ else if (NILP (name))
obj = Fcurrent_buffer ();
else
obj = name;
/* Now obj should be either a buffer object or a process object.
*/
- if (GC_BUFFERP (obj))
+ if (BUFFERP (obj))
{
proc = Fget_buffer_process (obj);
- if (GC_NILP (proc))
+ if (NILP (proc))
error ("Buffer %s has no process", XSTRING_DATA (XBUFFER(obj)->name));
}
else
DEFUN ("open-network-stream-internal", Fopen_network_stream_internal, 4, 5, 0, /*
Open a TCP connection for a service to a host.
-Returns a subprocess-object to represent the connection.
+Return a subprocess-object to represent the connection.
Input and output work as for subprocesses; `delete-process' closes it.
NAME is name for process. It is modified if necessary to make it unique.
Third arg is name of the host to connect to, or its IP address.
Fourth arg SERVICE is name of the service desired, or an integer
specifying a port number to connect to.
-Fifth argument FAMILY is a protocol family. When omitted, 'tcp/ip
-\(Internet protocol family TCP/IP) is assumed.
+Fifth argument PROTOCOL is a network protocol. Currently 'tcp
+ (Transmission Control Protocol) and 'udp (User Datagram Protocol) are
+ supported. When omitted, 'tcp is assumed.
+
+Ouput via `process-send-string' and input via buffer or filter (see
+`set-process-filter') are stream-oriented. That means UDP datagrams are
+not guaranteed to be sent and received in discrete packets. (But small
+datagrams around 500 bytes that are not truncated by `process-send-string'
+are usually fine.) Note further that UDP protocol does not guard against
+lost packets.
*/
- (name, buffer, host, service, family))
+ (name, buffer, host, service, protocol))
{
/* !!#### This function has not been Mule-ized */
/* This function can GC */
struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, ngcpro1;
void *inch, *outch;
- GCPRO5 (name, buffer, host, service, family);
+ GCPRO5 (name, buffer, host, service, protocol);
CHECK_STRING (name);
- if (NILP(family))
- family = Qtcpip;
+ if (NILP(protocol))
+ protocol = Qtcp;
else
- CHECK_SYMBOL (family);
+ CHECK_SYMBOL (protocol);
/* Since this code is inside HAVE_SOCKETS, existence of
open_network_stream is mandatory */
- PROCMETH (open_network_stream, (name, host, service, family,
+ PROCMETH (open_network_stream, (name, host, service, protocol,
&inch, &outch));
if (!NILP (buffer))
DEFUN ("open-multicast-group-internal", Fopen_multicast_group_internal, 5, 5, 0, /*
Open a multicast connection on the specified dest/port/ttl.
-Returns a subprocess-object to represent the connection.
+Return a subprocess-object to represent the connection.
Input and output work as for subprocesses; `delete-process' closes it.
NAME is name for process. It is modified if necessary to make it unique.
if (nonrelocatable)
lstream =
make_fixed_buffer_input_stream (nonrelocatable + start, len);
- else if (GC_BUFFERP (relocatable))
+ else if (BUFFERP (relocatable))
lstream = make_lisp_buffer_input_stream (XBUFFER (relocatable),
start, start + len, 0);
else
{
Lisp_Object tail;
- for (tail = Vprocess_list; GC_CONSP (tail);
+ for (tail = Vprocess_list; CONSP (tail);
tail = XCDR (tail))
{
Lisp_Object proc = XCAR (tail);
- if (GC_PROCESSP (proc)
- && (GC_NILP (buffer) || GC_EQ (XPROCESS (proc)->buffer, buffer)))
+ if (PROCESSP (proc)
+ && (NILP (buffer) || EQ (XPROCESS (proc)->buffer, buffer)))
{
if (network_connection_p (proc))
Fdelete_process (proc);
defsymbol (&Qopen, "open");
defsymbol (&Qclosed, "closed");
- defsymbol (&Qtcpip, "tcp/ip");
+ defsymbol (&Qtcp, "tcp");
+ defsymbol (&Qudp, "udp");
#ifdef HAVE_MULTICAST
defsymbol(&Qmulticast, "multicast"); /* Used for occasional warnings */
#define XPROCESS(x) XRECORD (x, process, struct Lisp_Process)
#define XSETPROCESS(x, p) XSETRECORD (x, p, process)
#define PROCESSP(x) RECORDP (x, process)
-#define GC_PROCESSP(x) GC_RECORDP (x, process)
#define CHECK_PROCESS(x) CHECK_RECORD (x, process)
#define PROCESS_LIVE_P(x) (!NILP (XPROCESS(x)->pipe_instream))
#define network_connection_p(x) 0
#endif
-extern Lisp_Object Qclosed, Qmulticast, Qopen, Qrun, Qstop, Qtcpip;
+extern Lisp_Object Qclosed, Qmulticast, Qopen, Qrun, Qstop, Qtcp, Qudp;
extern Lisp_Object Vprocess_connection_type, Vprocess_list;
/* Report all recent events of a change in process status
#endif /* emacs */
+#ifdef HAVE_GETPT
+#define PTY_ITERATION
+#define PTY_OPEN \
+ if ((fd = getpt()) < 0 || grantpt (fd) < 0 || unlockpt (fd) < 0) \
+ return -1;
+#define PTY_NAME_SPRINTF
+#define PTY_TTY_NAME_SPRINTF strcpy (pty_name, ptsname (fd));
+#endif
+
#endif /* _XEMACS_PROCESS_H_ */
struct process_methods
{
- void (*mark_process_data) (struct Lisp_Process *proc,
- void (*markobj) (Lisp_Object));
+ void (*mark_process_data) (struct Lisp_Process *proc);
void (*print_process_data) (struct Lisp_Process *proc,
Lisp_Object printcharfun);
void (*finalize_process_data) (struct Lisp_Process *proc, int for_disksave);
int (*tooltalk_connection_p) (struct Lisp_Process *p);
#ifdef HAVE_SOCKETS
void (*open_network_stream) (Lisp_Object name, Lisp_Object host,
- Lisp_Object service, Lisp_Object family,
+ Lisp_Object service, Lisp_Object protocol,
void** vinfd, void** voutfd);
#ifdef HAVE_MULTICAST
void (*open_multicast_group) (Lisp_Object name, Lisp_Object dest,
/* Random externs from process.c */
extern Lisp_Object Qrun, Qstop, Qopen, Qclosed;
-extern Lisp_Object Qtcpip;
+extern Lisp_Object Qtcp, Qudp;
extern Lisp_Object Vprocess_connection_type;
extern Lisp_Object Vprocess_list;
even be useful to provide a way to turn on only one profiling
mechanism, but I haven't done so yet. --hniksic */
-struct hash_table *big_profile_table;
+static struct hash_table *big_profile_table;
Lisp_Object Vcall_count_profile_table;
int default_profiling_interval;
and is not set the whole time we're in redisplay. */
int profiling_redisplay_flag;
-Lisp_Object QSin_redisplay;
-Lisp_Object QSin_garbage_collection;
-Lisp_Object QSprocessing_events_at_top_level;
-Lisp_Object QSunknown;
+static Lisp_Object QSin_redisplay;
+static Lisp_Object QSin_garbage_collection;
+static Lisp_Object QSprocessing_events_at_top_level;
+static Lisp_Object QSunknown;
/* We use inside_profiling to prevent the handler from writing to
the table while another routine is operating on it. We also set
{
fun = *backtrace_list->function;
- if (!GC_SYMBOLP (fun) &&
- !GC_COMPILED_FUNCTIONP (fun) &&
- !GC_SUBRP (fun))
+ if (!SYMBOLP (fun) &&
+ !COMPILED_FUNCTIONP (fun) &&
+ !SUBRP (fun))
fun = QSunknown;
}
else
return closure.accum;
}
-struct mark_profiling_info_closure
-{
- void (*markfun) (Lisp_Object);
-};
-
static int
mark_profiling_info_maphash (CONST void *void_key,
void *void_val,
Lisp_Object key;
CVOID_TO_LISP (key, void_key);
- (((struct mark_profiling_info_closure *) void_closure)->markfun) (key);
+ mark_object (key);
return 0;
}
void
-mark_profiling_info (void (*markfun) (Lisp_Object))
+mark_profiling_info (void)
{
- /* This function does not GC (if markfun doesn't) */
- struct mark_profiling_info_closure closure;
-
- closure.markfun = markfun;
+ /* This function does not GC */
if (big_profile_table)
{
inside_profiling = 1;
- maphash (mark_profiling_info_maphash, big_profile_table, &closure);
+ maphash (mark_profiling_info_maphash, big_profile_table, 0);
inside_profiling = 0;
}
}
/* Declarations for working with the malloc, ralloc, and system breaks. */
/* Function to set the real break value. */
-static POINTER (*real_morecore) (long size);
+static POINTER (*real_morecore) (ptrdiff_t size);
/* The break value, as seen by malloc (). */
static POINTER virtual_break_value;
If SIZE is more than a page, return the space to the system. */
static void
-relinquish ()
+relinquish (void)
{
register heap_ptr h;
int excess = 0;
__morecore hook values - in particular, __default_morecore in the
GNU malloc package. */
-POINTER r_alloc_sbrk (long size);
+POINTER r_alloc_sbrk (ptrdiff_t size);
POINTER
-r_alloc_sbrk (long size)
+r_alloc_sbrk (ptrdiff_t size)
{
register bloc_ptr b;
POINTER address;
void r_alloc_thaw (void);
void
-r_alloc_thaw ()
+r_alloc_thaw (void)
{
if (! r_alloc_initialized)
/* The hook `malloc' uses for the function which gets more space
from the system. */
#ifndef DOUG_LEA_MALLOC
-extern POINTER (*__morecore) (long size);
+extern POINTER (*__morecore) (ptrdiff_t size);
#endif
/* Initialize various things for memory allocation. */
-#define SET_FUN_PTR(fun_ptr, fun_val) \
- (*((void **) (&fun_ptr)) = ((void *) (fun_val)))
-
void
init_ralloc (void)
{
return;
r_alloc_initialized = 1;
- SET_FUN_PTR (real_morecore, __morecore);
- SET_FUN_PTR (__morecore, r_alloc_sbrk);
+ real_morecore = (POINTER (*) (ptrdiff_t)) __morecore;
+ __morecore =
+#ifdef __GNUC__
+ (__typeof__ (__morecore))
+#endif
+ r_alloc_sbrk;
first_heap = last_heap = &heap_base;
first_heap->next = first_heap->prev = NIL_HEAP;
Emacs. This is needed when using Doug Lea's malloc from GNU libc. */
void r_alloc_reinit (void);
void
-r_alloc_reinit ()
+r_alloc_reinit (void)
{
/* Only do this if the hook has been reset, so that we don't get an
infinite loop, in case Emacs was linked statically. */
- if ( ((void*) __morecore) != (void *) (r_alloc_sbrk))
+ if ( (POINTER (*) (ptrdiff_t)) __morecore != r_alloc_sbrk)
{
- SET_FUN_PTR (real_morecore, __morecore);
- SET_FUN_PTR (__morecore, r_alloc_sbrk);
+ real_morecore = (POINTER (*) (ptrdiff_t)) __morecore;
+ __morecore =
+#ifdef __GNUC__
+ (__typeof__ (__morecore))
+#endif
+ r_alloc_sbrk;
}
}
#if 0
#ifdef DEBUG
void
-r_alloc_check ()
+r_alloc_check (void)
{
int found = 0;
heap_ptr h, ph = 0;
is not hard but just requires moving that stuff out of that file. */
static Lisp_Object
-mark_range_table (Lisp_Object obj, void (*markobj) (Lisp_Object))
+mark_range_table (Lisp_Object obj)
{
struct Lisp_Range_Table *rt = XRANGE_TABLE (obj);
int i;
for (i = 0; i < Dynarr_length (rt->entries); i++)
- markobj (Dynarr_at (rt->entries, i).val);
+ mark_object (Dynarr_at (rt->entries, i).val);
return Qnil;
}
return hash;
}
+static const struct lrecord_description rte_description_1[] = {
+ { XD_LISP_OBJECT, offsetof(range_table_entry, val), 1 },
+ { XD_END }
+};
+
+static const struct struct_description rte_description = {
+ sizeof(range_table_entry),
+ rte_description_1
+};
+
+static const struct lrecord_description rted_description_1[] = {
+ XD_DYNARR_DESC(range_table_entry_dynarr, &rte_description),
+ { XD_END }
+};
+
+static const struct struct_description rted_description = {
+ sizeof(range_table_entry_dynarr),
+ rted_description_1
+};
+
+static const struct lrecord_description range_table_description[] = {
+ { XD_STRUCT_PTR, offsetof(struct Lisp_Range_Table, entries), 1, &rted_description },
+ { XD_END }
+};
+
DEFINE_LRECORD_IMPLEMENTATION ("range-table", range_table,
mark_range_table, print_range_table, 0,
- range_table_equal, range_table_hash, 0,
+ range_table_equal, range_table_hash,
+ range_table_description,
struct Lisp_Range_Table);
\f
/************************************************************************/
XRECORD (x, range_table, struct Lisp_Range_Table)
#define XSETRANGE_TABLE(x, p) XSETRECORD (x, p, range_table)
#define RANGE_TABLEP(x) RECORDP (x, range_table)
-#define GC_RANGE_TABLEP(x) GC_RECORDP (x, range_table)
#define CHECK_RANGE_TABLE(x) CHECK_RECORD (x, range_table)
#endif
/* Synched up with: Not in FSF. */
-#ifdef HAVE_CONFIG_H
#include <config.h>
-#endif
#include <sys/types.h>
-#if defined(HAVE_UNISTD_H) || defined(STDC_HEADERS)
-#include <unistd.h>
-#endif
#include <stdio.h>
#include <string.h>
+#include <errno.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
#ifdef _POSIX_VERSION
#include <limits.h> /* for PATH_MAX */
#else
#include <sys/param.h> /* for MAXPATHLEN */
#endif
-#include <errno.h>
-#ifndef STDC_HEADERS
-extern int errno;
-#endif
#ifdef WINDOWSNT
#include <direct.h>
#define MAX_READLINKS 32
-#ifdef __STDC__
-char *xrealpath(const char *path, char resolved_path [])
-#else
-char *xrealpath(path, resolved_path)
-const char *path;
-char resolved_path [];
-#endif
+char *
+xrealpath (const char *path, char resolved_path [])
{
char copy_path[PATH_MAX];
char *new_path = resolved_path;
int y, int width, int height);
static void mswindows_output_dibitmap (struct frame *f,
struct Lisp_Image_Instance *p,
- int x, int y,
- int clip_x, int clip_y,
- int clip_width, int clip_height,
- int width, int height,
- int pixmap_offset,
- int offset_bitmap);
-static void mswindows_output_pixmap (struct window *w, struct display_line *dl,
- Lisp_Object image_instance, int xpos,
- int xoffset, int start_pixpos, int width,
- face_index findex, int cursor_start,
- int cursor_width, int cursor_height,
- int offset_bitmap);
-void bevel_modeline (struct window *w, struct display_line *dl);
+ struct display_box* db,
+ struct display_glyph_area* dga);
typedef struct textual_run
{
of its face.
****************************************************************************/
static void
-mswindows_output_blank (struct window *w, struct display_line *dl, struct rune *rb, int start_pixpos)
+mswindows_output_blank (struct window *w, struct display_line *dl,
+ struct rune *rb, int start_pixpos)
{
struct frame *f = XFRAME (w->frame);
- RECT rect = { rb->xpos, dl->ypos-dl->ascent,
- rb->xpos+rb->width, dl->ypos+dl->descent-dl->clip };
+ RECT rect = { rb->xpos, DISPLAY_LINE_YPOS (dl),
+ rb->xpos+rb->width,
+ DISPLAY_LINE_YEND (dl) };
struct face_cachel *cachel = WINDOW_FACE_CACHEL (w, rb->findex);
Lisp_Object bg_pmap = WINDOW_FACE_CACHEL_BACKGROUND_PIXMAP (w, rb->findex);
+ /* Unmap all subwindows in the area we are going to blank. */
+ redisplay_unmap_subwindows_maybe (f, rb->xpos, DISPLAY_LINE_YPOS (dl),
+ rb->width, DISPLAY_LINE_HEIGHT (dl));
+
if (!IMAGE_INSTANCEP (bg_pmap)
|| !IMAGE_INSTANCE_PIXMAP_TYPE_P (XIMAGE_INSTANCE (bg_pmap)))
bg_pmap = Qnil;
if (!NILP(bg_pmap))
{
+ struct display_box db;
+ struct display_glyph_area dga;
+ redisplay_calculate_display_boxes (dl, rb->xpos,
+ /*rb->object.dglyph.xoffset*/ 0,
+ start_pixpos, rb->width,
+ &db, &dga);
/* blank the background in the appropriate color */
mswindows_update_dc (FRAME_MSWINDOWS_DC (f), Qnil, cachel->foreground,
cachel->background, Qnil);
-
- mswindows_output_pixmap (w, dl, bg_pmap,
- rb->xpos, 0 /*rb->object.dglyph.xoffset*/,
- start_pixpos, rb->width, rb->findex,
+ redisplay_output_pixmap (w, bg_pmap, &db, &dga, rb->findex,
0, 0, 0, TRUE);
}
else
char *p_char = NULL;
int n_char = 0;
RECT rect = { xpos,
- dl->ypos - dl->ascent,
+ DISPLAY_LINE_YPOS (dl),
xpos + width,
- dl->ypos + dl->descent - dl->clip};
+ DISPLAY_LINE_YEND (dl) };
Lisp_Object bar = symbol_value_in_buffer (Qbar_cursor,
WINDOW_BUFFER (w));
int bar_p = image_p || !NILP (bar);
int cursor_p = !NILP (w->text_cursor_visible_p);
int real_char_p = ch != 0;
+ /* Unmap all subwindows in the area we are going to blank. */
+ redisplay_unmap_subwindows_maybe (f, xpos, DISPLAY_LINE_YPOS (dl),
+ width, DISPLAY_LINE_HEIGHT (dl));
+
if (real_char_p)
{
/* Use the font from the underlying character */
****************************************************************************/
void
mswindows_output_string (struct window *w, struct display_line *dl,
- Emchar_dynarr *buf, int xpos, int xoffset, int clip_start,
- int width, face_index findex)
+ Emchar_dynarr *buf, int xpos, int xoffset, int clip_start,
+ int width, face_index findex,
+ int cursor, int cursor_start, int cursor_width,
+ int cursor_height)
{
struct frame *f = XFRAME (w->frame);
/* struct device *d = XDEVICE (f->device);*/
/* sort out the destination rectangle */
height = DISPLAY_LINE_HEIGHT (dl);
rect.left = clip_start;
- rect.top = dl->ypos - dl->ascent;
+ rect.top = DISPLAY_LINE_YPOS (dl);
rect.right = clip_end;
- rect.bottom = height + dl->ypos - dl->ascent;
+ rect.bottom = rect.top + height;
+
+ /* make sure the area we are about to display is subwindow free. */
+ redisplay_unmap_subwindows_maybe (f, clip_start, DISPLAY_LINE_YPOS (dl),
+ clip_end - clip_start, DISPLAY_LINE_HEIGHT (dl));
/* output the background pixmap if there is one */
bg_pmap = cachel->background_pixmap;
if (!NILP(bg_pmap))
{
+ struct display_box db;
+ struct display_glyph_area dga;
+ redisplay_calculate_display_boxes (dl, xpos + xoffset, 0,
+ clip_start, width, &db, &dga);
/* blank the background in the appropriate color */
mswindows_update_dc (hdc, Qnil, cachel->foreground,
cachel->background, Qnil);
-
- mswindows_output_pixmap (w, dl, bg_pmap,
- xpos, xoffset,
- clip_start, width, findex,
+ redisplay_output_pixmap (w, bg_pmap, &db, &dga, findex,
0, 0, 0, TRUE);
/* output pixmap calls this so we have to recall to get correct
references */
this_width = mswindows_text_width_single_run (hdc, cachel, runs + i);
/* cope with fonts taller than lines */
- if ((int) fi->height < (int) (height + dl->clip))
+ if ((int) fi->height < (int) (height + dl->clip + dl->top_clip))
{
int clear_start = max (xpos, clip_start);
int clear_end = min (xpos + this_width, clip_end);
{
redisplay_clear_region (window, findex, clear_start,
- dl->ypos - dl->ascent,
+ DISPLAY_LINE_YPOS (dl),
clear_end - clear_start,
height);
/* output pixmap calls this so we have to recall to get correct
static void
mswindows_output_dibitmap (struct frame *f, struct Lisp_Image_Instance *p,
- int x, int y,
- int clip_x, int clip_y,
- int clip_width, int clip_height,
- int width, int height, int pixmap_offset,
- int offset_bitmap)
+ struct display_box* db,
+ struct display_glyph_area* dga)
{
HDC hdc = FRAME_MSWINDOWS_DC (f);
HGDIOBJ old=NULL;
COLORREF bgcolor = GetBkColor (hdc);
- int need_clipping = (clip_x || clip_y);
- int yoffset=0;
- int xoffset=0;
-
- /* do we need to offset the pixmap vertically? this is necessary
- for background pixmaps. */
- if (offset_bitmap)
- {
- yoffset = y % IMAGE_INSTANCE_PIXMAP_HEIGHT (p);
- xoffset = x % IMAGE_INSTANCE_PIXMAP_WIDTH (p);
- /* the width is handled by mswindows_output_pixmap_region */
- }
-
- if (need_clipping)
- {
- }
/* first blt the mask */
if (IMAGE_INSTANCE_MSWINDOWS_MASK (p))
SetDIBColorTable (FRAME_MSWINDOWS_CDC (f), 1, 1, &col);
BitBlt (hdc,
- x,y,
- width, height,
+ db->xpos, db->ypos,
+ dga->width, dga->height,
FRAME_MSWINDOWS_CDC (f),
- xoffset,yoffset,
+ dga->xoffset, dga->yoffset,
SRCCOPY);
SelectObject (FRAME_MSWINDOWS_CDC (f), old);
}
- /* now blt the bitmap itself. */
+ /* Now blt the bitmap itself, or one of its slices. */
old = SelectObject (FRAME_MSWINDOWS_CDC (f),
- IMAGE_INSTANCE_MSWINDOWS_BITMAP (p));
+ IMAGE_INSTANCE_MSWINDOWS_BITMAP_SLICE
+ (p, IMAGE_INSTANCE_PIXMAP_SLICE (p)));
BitBlt (hdc,
- x,y,
- width, height,
+ db->xpos, db->ypos,
+ dga->width, dga->height,
FRAME_MSWINDOWS_CDC (f),
- xoffset, yoffset,
+ dga->xoffset, dga->yoffset,
IMAGE_INSTANCE_MSWINDOWS_MASK (p) ? SRCINVERT : SRCCOPY);
SelectObject (FRAME_MSWINDOWS_CDC (f),old);
-
- if (need_clipping)
- {
- }
}
-/*
- * X gc's have this nice property that setting the bg pixmap will
+/* X gc's have this nice property that setting the bg pixmap will
* output it offset relative to the window. Windows doesn't have this
- * feature so we have to emulate this by outputting multiple pixmaps
- */
+ * feature so we have to emulate this by outputting multiple pixmaps.
+ * This is only used for background pixmaps. Normal pixmaps are
+ * outputted once and are scrollable */
static void
mswindows_output_dibitmap_region (struct frame *f,
struct Lisp_Image_Instance *p,
- int x, int y,
- int clip_x, int clip_y,
- int clip_width, int clip_height,
- int width, int height, int pixmap_offset,
- int offset_bitmap)
+ struct display_box *db,
+ struct display_glyph_area *dga)
{
- int pwidth = min (width, IMAGE_INSTANCE_PIXMAP_WIDTH (p));
- int pheight = min (height, IMAGE_INSTANCE_PIXMAP_HEIGHT (p));
+ struct display_box xdb = { db->xpos, db->ypos, db->width, db->height };
+ struct display_glyph_area xdga
+ = { 0, 0, IMAGE_INSTANCE_PIXMAP_WIDTH (p),
+ IMAGE_INSTANCE_PIXMAP_HEIGHT (p) };
int pxoffset = 0, pyoffset = 0;
+ if (dga)
+ {
+ xdga.width = dga->width;
+ xdga.height = dga->height;
+ }
+ else if (!redisplay_normalize_glyph_area (&xdb, &xdga))
+ return;
+
/* when doing a bg pixmap do a partial pixmap first so that we
blt whole pixmaps thereafter */
+ xdga.height = min (xdga.height, IMAGE_INSTANCE_PIXMAP_HEIGHT (p) -
+ db->ypos % IMAGE_INSTANCE_PIXMAP_HEIGHT (p));
- if (offset_bitmap)
- {
- pheight = min (pheight, IMAGE_INSTANCE_PIXMAP_HEIGHT (p) -
- y % IMAGE_INSTANCE_PIXMAP_HEIGHT (p));
- }
-
- while (pheight > 0)
+ while (xdga.height > 0)
{
- if (offset_bitmap)
- {
- pwidth = min (min (width, IMAGE_INSTANCE_PIXMAP_WIDTH (p)),
+ xdga.width = min (min (db->width, IMAGE_INSTANCE_PIXMAP_WIDTH (p)),
IMAGE_INSTANCE_PIXMAP_WIDTH (p) -
- x % IMAGE_INSTANCE_PIXMAP_WIDTH (p));
- pxoffset = 0;
- }
- while (pwidth > 0)
+ db->xpos % IMAGE_INSTANCE_PIXMAP_WIDTH (p));
+ pxoffset = 0;
+ while (xdga.width > 0)
{
- mswindows_output_dibitmap (f, p,
- x + pxoffset, y + pyoffset,
- clip_x, clip_y,
- clip_width, clip_height,
- pwidth, pheight, pixmap_offset,
- offset_bitmap);
- pxoffset += pwidth;
- pwidth = min ((width-pxoffset),
- IMAGE_INSTANCE_PIXMAP_WIDTH (p));
+ xdb.xpos = db->xpos + pxoffset;
+ xdb.ypos = db->ypos + pyoffset;
+ /* do we need to offset the pixmap vertically? this is necessary
+ for background pixmaps. */
+ xdga.yoffset = xdb.ypos % IMAGE_INSTANCE_PIXMAP_HEIGHT (p);
+ xdga.xoffset = xdb.xpos % IMAGE_INSTANCE_PIXMAP_WIDTH (p);
+ /* the width is handled by mswindows_output_pixmap_region */
+ mswindows_output_dibitmap (f, p, &xdb, &xdga);
+ pxoffset += xdga.width;
+ xdga.width = min ((db->width - pxoffset),
+ IMAGE_INSTANCE_PIXMAP_WIDTH (p));
}
- pyoffset += pheight;
- pheight = min ((height-pyoffset),
- IMAGE_INSTANCE_PIXMAP_HEIGHT (p));
+ pyoffset += xdga.height;
+ xdga.height = min ((db->height - pyoffset),
+ IMAGE_INSTANCE_PIXMAP_HEIGHT (p));
}
}
+/* Output a pixmap at the desired location.
+ DB normalized display_box.
+ DGA normalized display_glyph_area. */
static void
-mswindows_output_pixmap (struct window *w, struct display_line *dl,
- Lisp_Object image_instance, int xpos, int xoffset,
- int start_pixpos, int width, face_index findex,
- int cursor_start, int cursor_width, int cursor_height,
- int offset_bitmap)
+mswindows_output_pixmap (struct window *w, Lisp_Object image_instance,
+ struct display_box *db, struct display_glyph_area *dga,
+ face_index findex, int cursor_start, int cursor_width,
+ int cursor_height, int bg_pixmap)
{
struct frame *f = XFRAME (w->frame);
HDC hdc = FRAME_MSWINDOWS_DC (f);
struct Lisp_Image_Instance *p = XIMAGE_INSTANCE (image_instance);
Lisp_Object window;
- int lheight = DISPLAY_LINE_HEIGHT (dl);
- int pheight = ((int) IMAGE_INSTANCE_PIXMAP_HEIGHT (p) > lheight ? lheight :
- IMAGE_INSTANCE_PIXMAP_HEIGHT (p));
- int clip_x, clip_y, clip_width, clip_height;
-
- /* The pixmap_offset is used to center the pixmap on lines which are
- shorter than it is. This results in odd effects when scrolling
- pixmaps off of the bottom. Let's try not using it. */
-#if 0
- int pixmap_offset = (int) (IMAGE_INSTANCE_PIXMAP_HEIGHT (p) - lheight) / 2;
-#else
- int pixmap_offset = 0;
-#endif
-
XSETWINDOW (window, w);
- if ((start_pixpos >= 0 && start_pixpos > xpos) || xoffset)
- {
- if (start_pixpos > xpos && start_pixpos > xpos + width)
- return;
-
- clip_x = xoffset;
- clip_width = width;
- if (start_pixpos > xpos)
- {
- clip_x += (start_pixpos - xpos);
- clip_width -= (start_pixpos - xpos);
- }
- }
- else
- {
- clip_x = 0;
- clip_width = 0;
- }
-
- /* Place markers for possible future functionality (clipping the top
- half instead of the bottom half; think pixel scrolling). */
- clip_y = 0;
- clip_height = pheight;
-
- /* Clear the area the pixmap is going into. The pixmap itself will
- always take care of the full width. We don't want to clear where
- it is going to go in order to avoid flicker. So, all we have to
- take care of is any area above or below the pixmap. */
- /* #### We take a shortcut for now. We know that since we have
- pixmap_offset hardwired to 0 that the pixmap is against the top
- edge so all we have to worry about is below it. */
- /* #### Unless the pixmap has a mask in which case we have to clear
- the whole damn thing since we can't yet clear just the area not
- included in the mask. */
- if (((int) (dl->ypos - dl->ascent + pheight) <
- (int) (dl->ypos + dl->descent - dl->clip))
- || IMAGE_INSTANCE_MSWINDOWS_MASK (p))
- {
- int clear_x, clear_y, clear_width, clear_height;
-
- if (IMAGE_INSTANCE_MSWINDOWS_MASK (p))
- {
- clear_y = dl->ypos - dl->ascent;
- clear_height = lheight;
- }
- else
- {
- clear_y = dl->ypos - dl->ascent + pheight;
- clear_height = lheight - pheight;
- }
-
- if (start_pixpos >= 0 && start_pixpos > xpos)
- {
- clear_x = start_pixpos;
- clear_width = xpos + width - start_pixpos;
- }
- else
- {
- clear_x = xpos;
- clear_width = width;
- }
-
- if (!offset_bitmap) /* i.e. not a bg pixmap */
- redisplay_clear_region (window, findex, clear_x, clear_y,
- clear_width, clear_height);
- }
-
/* Output the pixmap. Have to do this as many times as is required
to fill the given area */
mswindows_update_dc (hdc, Qnil,
WINDOW_FACE_CACHEL_FOREGROUND (w, findex),
WINDOW_FACE_CACHEL_BACKGROUND (w, findex), Qnil);
- mswindows_output_dibitmap_region (f, p, xpos - xoffset,
- dl->ypos - dl->ascent,
- clip_x, clip_y, clip_width, clip_height,
- width + xoffset, pheight, pixmap_offset,
- offset_bitmap);
+ if (bg_pixmap)
+ mswindows_output_dibitmap_region (f, p, db, dga);
+ else
+ mswindows_output_dibitmap (f, p, db, dga);
}
#ifdef HAVE_SCROLLBARS
for (line = 0; line < Dynarr_length (cdla); line++)
{
struct display_line *cdl = Dynarr_atp (cdla, line);
- int top_y = cdl->ypos - cdl->ascent;
- int bottom_y = cdl->ypos + cdl->descent;
- if (bottom_y >= rect_draw.top)
+ if (DISPLAY_LINE_YPOS (cdl) + DISPLAY_LINE_HEIGHT (cdl)
+ >= rect_draw.top)
{
- if (top_y > rect_draw.bottom)
+ if (DISPLAY_LINE_YPOS (cdl) > rect_draw.bottom)
{
if (line == 0)
continue;
****************************************************************************/
static void
mswindows_bevel_area (struct window *w, face_index findex, int x, int y,
- int width, int height, int shadow_thickness)
+ int width, int height, int thickness,
+ int edges, enum edge_style style)
{
struct frame *f = XFRAME (w->frame);
UINT edge;
+ UINT border = 0;
- if (shadow_thickness < -1)
- edge = EDGE_SUNKEN;
- else if (shadow_thickness < 0)
- edge = BDR_SUNKENINNER;
- else if (shadow_thickness == 1)
- edge = BDR_RAISEDINNER;
- else
- edge = EDGE_RAISED;
+ if (style == EDGE_ETCHED_IN)
+ edge = EDGE_ETCHED;
+ else if (style == EDGE_ETCHED_OUT)
+ edge = EDGE_BUMP;
+ else if (style == EDGE_BEVEL_IN)
+ {
+ if (thickness == 1)
+ edge = BDR_SUNKENINNER;
+ else
+ edge = EDGE_SUNKEN;
+ }
+ else /* EDGE_BEVEL_OUT */
+ {
+ if (thickness == 1)
+ edge = BDR_RAISEDINNER;
+ else
+ edge = EDGE_RAISED;
+ }
- if (shadow_thickness < 0)
- shadow_thickness = -shadow_thickness;
+ if (edges & EDGE_TOP)
+ border |= BF_TOP;
+ if (edges & EDGE_LEFT)
+ border |= BF_LEFT;
+ if (edges & EDGE_BOTTOM)
+ border |= BF_BOTTOM;
+ if (edges & EDGE_RIGHT)
+ border |= BF_RIGHT;
{
RECT rect = { x, y, x + width, y + height };
Lisp_Object color = WINDOW_FACE_CACHEL_BACKGROUND (w, findex);
mswindows_update_dc (FRAME_MSWINDOWS_DC (f), Qnil, Qnil, color, Qnil);
- DrawEdge (FRAME_MSWINDOWS_DC (f), &rect, edge, BF_RECT);
+ DrawEdge (FRAME_MSWINDOWS_DC (f), &rect, edge, border);
}
}
if (Dynarr_length (buf))
{
mswindows_output_string (w, dl, buf, xpos, 0, start_pixpos, width,
- findex);
+ findex, 0, 0, 0, 0);
xpos = rb->xpos;
width = 0;
}
else if (rb->object.chr.ch == '\n')
{
/* Clear in case a cursor was formerly here. */
- int height = DISPLAY_LINE_HEIGHT (dl);
-
- redisplay_clear_region (window, findex, xpos, dl->ypos - dl->ascent,
- rb->width, height);
+ redisplay_clear_region (window, findex, xpos,
+ DISPLAY_LINE_YPOS (dl),
+ rb->width, DISPLAY_LINE_HEIGHT (dl));
elt++;
}
}
else if (rb->type == RUNE_DGLYPH)
{
Lisp_Object instance;
+ struct display_box db;
+ struct display_glyph_area dga;
+ redisplay_calculate_display_boxes (dl, rb->xpos, rb->object.dglyph.xoffset,
+ start_pixpos, rb->width,
+ &db, &dga);
XSETWINDOW (window, w);
instance = glyph_image_instance (rb->object.dglyph.glyph,
else /* #### redisplay-x passes -1 as the width: why ? */
mswindows_output_string (w, dl, buf, xpos,
rb->object.dglyph.xoffset,
- start_pixpos, rb->width, findex);
+ start_pixpos, rb->width, findex,
+ 0, 0, 0, 0);
Dynarr_reset (buf);
}
break;
case IMAGE_MONO_PIXMAP:
case IMAGE_COLOR_PIXMAP:
- mswindows_output_pixmap (w, dl, instance, xpos,
- rb->object.dglyph.xoffset, start_pixpos,
- rb->width, findex, cursor_start,
- cursor_width, cursor_height, 0);
+ redisplay_output_pixmap (w, instance, &db, &dga, findex,
+ cursor_start, cursor_width,
+ cursor_height, 0);
if (rb->cursor_type == CURSOR_ON)
mswindows_output_cursor (w, dl, xpos, cursor_width,
findex, 0, 1);
case IMAGE_SUBWINDOW:
case IMAGE_WIDGET:
- redisplay_output_subwindow (w, dl, instance, xpos,
- rb->object.dglyph.xoffset, start_pixpos,
- rb->width, findex, cursor_start,
- cursor_width, cursor_height);
+ redisplay_output_subwindow (w, instance, &db, &dga, findex,
+ cursor_start, cursor_width,
+ cursor_height);
+ if (rb->cursor_type == CURSOR_ON)
+ mswindows_output_cursor (w, dl, xpos, cursor_width,
+ findex, 0, 1);
+ break;
+
+ case IMAGE_LAYOUT:
+ redisplay_output_layout (w, instance, &db, &dga, findex,
+ cursor_start, cursor_width,
+ cursor_height);
if (rb->cursor_type == CURSOR_ON)
mswindows_output_cursor (w, dl, xpos, cursor_width,
findex, 0, 1);
}
if (Dynarr_length (buf))
- mswindows_output_string (w, dl, buf, xpos, 0, start_pixpos, width, findex);
+ mswindows_output_string (w, dl, buf, xpos, 0, start_pixpos, width, findex,
+ 0, 0, 0, 0);
if (dl->modeline
&& !EQ (Qzero, w->modeline_shadow_thickness)
if (!NILP (background_pixmap))
{
+ struct display_box db = { x, y, width, height };
mswindows_update_dc (FRAME_MSWINDOWS_DC (f),
Qnil, fcolor, bcolor, background_pixmap);
-
mswindows_output_dibitmap_region
- ( f, XIMAGE_INSTANCE (background_pixmap),
- x, y, 0, 0, 0, 0, width, height, 0, TRUE);
+ ( f, XIMAGE_INSTANCE (background_pixmap), &db, 0);
}
else
{
CONSOLE_HAS_METHOD (mswindows, flash);
CONSOLE_HAS_METHOD (mswindows, ring_bell);
CONSOLE_HAS_METHOD (mswindows, bevel_area);
+ CONSOLE_HAS_METHOD (mswindows, output_string);
+ CONSOLE_HAS_METHOD (mswindows, output_pixmap);
}
Copyright (C) 1994, 1995 Board of Trustees, University of Illinois.
Copyright (C) 1995, 1996 Ben Wing.
Copyright (C) 1996 Chuck Thompson.
+ Copyright (C) 1999 Andy Piper.
This file is part of XEmacs.
/* Author: Chuck Thompson */
+/* Heavily hacked for modularity, gutter and subwindow support by Andy
+ Piper. */
+
#include <config.h>
#include "lisp.h"
int block, int start, int end, int start_pixpos,
int cursor_start, int cursor_width,
int cursor_height);
+static void redisplay_normalize_display_box (struct display_box* dest,
+ struct display_glyph_area* src);
+static int redisplay_display_boxes_in_window_p (struct window* w,
+ struct display_box* db,
+ struct display_glyph_area* dga);
+static void redisplay_clear_clipped_region (Lisp_Object locale, face_index findex,
+ struct display_box* dest,
+ struct display_glyph_area* glyphsrc,
+ int fullheight_p, Lisp_Object);
/*****************************************************************************
sync_rune_structs
else if (crb->type == RUNE_CHAR &&
(crb->object.chr.ch != drb->object.chr.ch))
return 0;
- else if (crb->type == RUNE_DGLYPH &&
- (!EQ (crb->object.dglyph.glyph, drb->object.dglyph.glyph) ||
- !EQ (crb->object.dglyph.extent, drb->object.dglyph.extent) ||
- crb->object.dglyph.xoffset != drb->object.dglyph.xoffset))
- return 0;
else if (crb->type == RUNE_HLINE &&
(crb->object.hline.thickness != drb->object.hline.thickness ||
crb->object.hline.yoffset != drb->object.hline.yoffset))
return 0;
+ else if (crb->type == RUNE_DGLYPH &&
+ (!EQ (crb->object.dglyph.glyph, drb->object.dglyph.glyph) ||
+ !EQ (crb->object.dglyph.extent, drb->object.dglyph.extent) ||
+ crb->object.dglyph.xoffset != drb->object.dglyph.xoffset))
+ return 0;
+ /* Only check dirtiness if we know something has changed. */
+ else if (crb->type == RUNE_DGLYPH &&
+ XFRAME (w->frame)->glyphs_changed)
+ {
+ glyph_index gindex = get_glyph_cachel_index (w, drb->object.dglyph.glyph);
+ /* Although doing the cachel lookup for every comparison is
+ very expensive.we have to do it to make sure the cache is
+ up-to-date. */
+ if (GLYPH_CACHEL_DIRTYP (w, gindex))
+ return 0;
+ else
+ return 1;
+ }
else
return 1;
}
force = 1;
if (f->windows_structure_changed ||
+ /* #### Why is this so? We have face cachels so that we don't
+ have to recalculate all the display blocks when faces
+ change. I have fixed this for glyphs and am inclined to think
+ that faces should "Just Work", but I'm not feeling brave
+ today. Maybe its because the face cachels represent merged
+ faces rather than simply instantiations in a particular
+ domain. */
f->faces_changed ||
- f->glyphs_changed ||
cdl->ypos != ddl->ypos ||
cdl->ascent != ddl->ascent ||
cdl->descent != ddl->descent ||
(cdl && (cdl->ypos != ddl->ypos ||
cdl->ascent != ddl->ascent ||
cdl->descent != ddl->descent ||
+ cdl->top_clip != ddl->top_clip ||
cdl->clip != ddl->clip)))
{
int x, y, width, height;
must_sync = 1;
x = start_pixpos;
- y = ddl->ypos - ddl->ascent;
+ y = DISPLAY_LINE_YPOS (ddl);
width = min (next_start_pixpos, block_end) - x;
- height = ddl->ascent + ddl->descent - ddl->clip;
+ height = DISPLAY_LINE_HEIGHT (ddl);
if (x < ddl->bounds.left_in)
{
region or if it was a block of a different type, then
output the entire ddb. Otherwise, compare cdb and
ddb and output only the changed region. */
- if (!force && cdb && ddb->type == cdb->type && b == old_b)
+ if (!force && cdb && ddb->type == cdb->type
+ /* If there was no buffer being display before the
+ compare anyway as we might be outputting a gutter. */
+ &&
+ (b == old_b || !old_b))
{
must_sync |= compare_display_blocks (w, cdl, ddl, old_block,
block, start_pixpos,
if (f->windows_structure_changed || f->faces_changed || clear_border
|| f->clear)
{
- int y = ddl->ypos - ddl->ascent;
- int height = ddl->ascent + ddl->descent - ddl->clip;
+ int y = DISPLAY_LINE_YPOS (ddl);
+ int height = DISPLAY_LINE_HEIGHT (ddl);
- if (ddl->modeline)
+ /* If we are in the gutter then we musn't clear the borders. */
+ if (y >= WINDOW_TEXT_TOP (w) && (y + height) <= WINDOW_TEXT_BOTTOM (w))
{
- y -= MODELINE_SHADOW_THICKNESS (w);
- height += (2 * MODELINE_SHADOW_THICKNESS (w));
+ if (ddl->modeline)
+ {
+ y -= MODELINE_SHADOW_THICKNESS (w);
+ height += (2 * MODELINE_SHADOW_THICKNESS (w));
+ }
+
+ if (window_is_leftmost (w))
+ clear_left_border (w, y, height);
+ if (window_is_rightmost (w))
+ clear_right_border (w, y, height);
}
-
- if (window_is_leftmost (w))
- clear_left_border (w, y, height);
- if (window_is_rightmost (w))
- clear_right_border (w, y, height);
}
if (cdla)
{
struct frame *f = XFRAME (w->frame);
struct device *d = XDEVICE (f->device);
+ struct display_block *db = Dynarr_atp (dl->display_blocks, block);
+ rune_dynarr *rba = db->runes;
+ struct rune *rb;
+ int xpos, width;
+ rb = Dynarr_atp (rba, start);
+
+ if (!rb)
+ /* Nothing to do so don't do anything. */
+ return;
+
+ xpos = max (start_pixpos, rb->xpos);
+ if (end < 0)
+ end = Dynarr_length (rba);
+
+ rb = Dynarr_atp (rba, end - 1);
+ width = rb->xpos + rb->width - xpos;
+ /* now actually output the block. */
DEVMETH (d, output_display_block, (w, dl, block, start,
end, start_pixpos,
cursor_start, cursor_width,
cursor_height));
}
-
+
/****************************************************************************
redisplay_unmap_subwindows
Remove subwindows from the area in the box defined by the given
parameters.
****************************************************************************/
-static void redisplay_unmap_subwindows (struct frame* f, int x, int y, int width, int height)
+static void redisplay_unmap_subwindows (struct frame* f, int x, int y, int width, int height,
+ Lisp_Object ignored_window)
{
int elt;
&&
cachel->x + cachel->width > x && cachel->x < x + width
&&
- cachel->y + cachel->height > y && cachel->y < y + height)
+ cachel->y + cachel->height > y && cachel->y < y + height
+ &&
+ !EQ (cachel->subwindow, ignored_window))
{
unmap_subwindow (cachel->subwindow);
}
{
if (Dynarr_length (FRAME_SUBWINDOW_CACHE (f)))
{
- redisplay_unmap_subwindows (f, x, y, width, height);
+ redisplay_unmap_subwindows (f, x, y, width, height, Qnil);
+ }
+}
+
+static void redisplay_unmap_subwindows_except_us (struct frame* f, int x, int y, int width,
+ int height, Lisp_Object subwindow)
+{
+ if (Dynarr_length (FRAME_SUBWINDOW_CACHE (f)))
+ {
+ redisplay_unmap_subwindows (f, x, y, width, height, subwindow);
}
}
/****************************************************************************
redisplay_output_subwindow
-
output a subwindow. This code borrows heavily from the pixmap stuff,
although is much simpler not needing to account for partial
pixmaps, backgrounds etc.
****************************************************************************/
void
-redisplay_output_subwindow (struct window *w, struct display_line *dl,
- Lisp_Object image_instance, int xpos, int xoffset,
- int start_pixpos, int width, face_index findex,
- int cursor_start, int cursor_width, int cursor_height)
+redisplay_output_subwindow (struct window *w,
+ Lisp_Object image_instance,
+ struct display_box* db, struct display_glyph_area* dga,
+ face_index findex, int cursor_start, int cursor_width,
+ int cursor_height)
{
struct Lisp_Image_Instance *p = XIMAGE_INSTANCE (image_instance);
Lisp_Object window;
+ struct display_glyph_area sdga;
+
+ dga->height = IMAGE_INSTANCE_SUBWINDOW_HEIGHT (p);
+ dga->width = IMAGE_INSTANCE_SUBWINDOW_WIDTH (p);
- int lheight = dl->ascent + dl->descent - dl->clip;
- int pheight = ((int) IMAGE_INSTANCE_SUBWINDOW_HEIGHT (p) > lheight ? lheight :
- IMAGE_INSTANCE_SUBWINDOW_HEIGHT (p));
+ /* This makes the glyph area fit into the display area. */
+ if (!redisplay_normalize_glyph_area (db, dga))
+ return;
XSETWINDOW (window, w);
- /* Clear the area the subwindow is going into. The subwindow itself
- will always take care of the full width. We don't want to clear
- where it is going to go in order to avoid flicker. So, all we
- have to take care of is any area above or below the subwindow. Of
- course this is rubbish if the subwindow has transparent areas
- (for instance with frames). */
- /* #### We take a shortcut for now. We know that since we have
- subwindow_offset hardwired to 0 that the subwindow is against the top
- edge so all we have to worry about is below it. */
- if ((int) (dl->ypos - dl->ascent + pheight) <
- (int) (dl->ypos + dl->descent - dl->clip))
+ /* Clear the area the subwindow is going into. */
+ redisplay_clear_clipped_region (window, findex,
+ db, dga, 0, image_instance);
+
+ /* This shrinks the display box to exactly enclose the glyph
+ area. */
+ redisplay_normalize_display_box (db, dga);
+
+ /* if we can't view the whole window we can't view any of it. We
+ have to be careful here since we may be being asked to display
+ part of a subwindow, the rest of which is on-screen as well. We
+ need to allow this case and map the entire subwindow. We also
+ need to be careful since the subwindow could be outside the
+ window in the gutter or modeline - we also need to allow these
+ cases.*/
+ sdga.xoffset = -dga->xoffset;
+ sdga.yoffset = -dga->yoffset;
+ sdga.height = IMAGE_INSTANCE_SUBWINDOW_HEIGHT (p);
+ sdga.width = IMAGE_INSTANCE_SUBWINDOW_WIDTH (p);
+
+ if (redisplay_display_boxes_in_window_p (w, db, &sdga) < 0)
+ {
+ map_subwindow (image_instance, db->xpos, db->ypos, dga);
+ }
+ else
{
- int clear_x, clear_width;
+ sdga.xoffset = sdga.yoffset = 0;
+ map_subwindow (image_instance, db->xpos - dga->xoffset,
+ db->ypos - dga->yoffset, &sdga);
+ }
+}
+
+/****************************************************************************
+ redisplay_output_layout
+
+ Output a widget hierarchy. This can safely call itself recursively.
+ ****************************************************************************/
+void
+redisplay_output_layout (struct window *w,
+ Lisp_Object image_instance,
+ struct display_box* db, struct display_glyph_area* dga,
+ face_index findex, int cursor_start, int cursor_width,
+ int cursor_height)
+{
+ struct Lisp_Image_Instance *p = XIMAGE_INSTANCE (image_instance);
+ Lisp_Object window, rest;
+ Emchar_dynarr *buf = Dynarr_new (Emchar);
+ struct frame *f = XFRAME (w->frame);
+ struct device *d = XDEVICE (f->device);
+ int layout_height, layout_width;
+ /* We bogusly don't take f->extents_changed and f->glyphs_changed
+ into account. This is because if we do we always redisplay the
+ entire layout. So far I have seen no ill effects to we'll see. */
+ int frame_changed = (f->buffers_changed ||
+ f->clip_changed ||
+ f->faces_changed ||
+ f->frame_changed ||
+ f->modeline_changed ||
+ f->subwindows_changed ||
+ f->windows_changed ||
+ f->windows_structure_changed);
- int clear_y = dl->ypos - dl->ascent + pheight;
- int clear_height = lheight - pheight;
+ XSETWINDOW (window, w);
- if (start_pixpos >= 0 && start_pixpos > xpos)
+ layout_height = glyph_height (image_instance, Qnil, findex, window);
+ layout_width = glyph_width (image_instance, Qnil, findex, window);
+
+ dga->height = layout_height;
+ dga->width = layout_width;
+
+ /* This makes the glyph area fit into the display area. */
+ if (!redisplay_normalize_glyph_area (db, dga))
+ return;
+
+ /* Highly dodgy optimization. We want to only output the whole
+ layout if we really have to. */
+ if (frame_changed || IMAGE_INSTANCE_DIRTYP (p))
+ {
+ /* First clear the area we are drawing into. This is the easiest
+ thing to do since we have many gaps that we have to make sure are
+ filled in. */
+ redisplay_clear_clipped_region (window, findex, db, dga, 1, Qnil);
+
+ /* Output a border if required */
+ if (!NILP (IMAGE_INSTANCE_LAYOUT_BORDER (p)))
{
- clear_x = start_pixpos;
- clear_width = xpos + width - start_pixpos;
+ int edges = 0;
+ enum edge_style style;
+ int ypos = db->ypos;
+ int height = dga->height;
+
+ if (dga->xoffset >= 0)
+ edges |= EDGE_LEFT;
+ if (dga->width - dga->xoffset == layout_width)
+ edges |= EDGE_RIGHT;
+ if (dga->yoffset >= 0)
+ edges |= EDGE_TOP;
+ if (dga->height - dga->yoffset == layout_height)
+ edges |= EDGE_BOTTOM;
+
+ if (EQ (IMAGE_INSTANCE_LAYOUT_BORDER (p), Qetched_in))
+ style = EDGE_ETCHED_IN;
+ else if (EQ (IMAGE_INSTANCE_LAYOUT_BORDER (p), Qetched_out))
+ style = EDGE_ETCHED_OUT;
+ else if (EQ (IMAGE_INSTANCE_LAYOUT_BORDER (p), Qbevel_in))
+ style = EDGE_BEVEL_IN;
+ else if (INTP (IMAGE_INSTANCE_LAYOUT_BORDER (p)))
+ {
+ style = EDGE_ETCHED_IN;
+ if (edges & EDGE_TOP)
+ {
+ ypos += XINT (IMAGE_INSTANCE_LAYOUT_BORDER (p));
+ height -= XINT (IMAGE_INSTANCE_LAYOUT_BORDER (p));
+ }
+ }
+ else
+ style = EDGE_BEVEL_OUT;
+
+ MAYBE_DEVMETH (d, bevel_area,
+ (w, findex, db->xpos,
+ ypos,
+ dga->width, height, 2, edges, style));
}
- else
+ }
+
+ /* This shrinks the display box to exactly enclose the glyph
+ area. */
+ redisplay_normalize_display_box (db, dga);
+
+ /* Flip through the widgets in the layout displaying as necessary */
+ LIST_LOOP (rest, IMAGE_INSTANCE_LAYOUT_CHILDREN (p))
+ {
+ Lisp_Object child = XCAR (rest);
+
+ struct display_box cdb;
+ /* For losing HP-UX */
+ cdb.xpos = db->xpos;
+ cdb.ypos = db->ypos;
+ cdb.width = db->width;
+ cdb.height = db->height;
+
+ /* First determine if the image is visible at all */
+ if (IMAGE_INSTANCEP (child))
{
- clear_x = xpos;
- clear_width = width;
+ struct Lisp_Image_Instance* childii = XIMAGE_INSTANCE (child);
+ /* The enclosing layout offsets are +ve at this point */
+ struct display_glyph_area cdga;
+ cdga.xoffset = IMAGE_INSTANCE_XOFFSET (childii) - dga->xoffset;
+ cdga.yoffset = IMAGE_INSTANCE_YOFFSET (childii) - dga->yoffset;
+ cdga.width = glyph_width (child, Qnil, findex, window);
+ cdga.height = glyph_height (child, Qnil, findex, window);
+
+ /* Although normalization is done by the output routines
+ we have to do it here so that they don't try and
+ clear all of db. This is true below also. */
+ if (redisplay_normalize_glyph_area (&cdb, &cdga))
+ {
+ redisplay_normalize_display_box (&cdb, &cdga);
+ /* Since the display boxes will now be totally in the
+ window if they are visible at all we can now check this easily. */
+ if (cdb.xpos < db->xpos || cdb.ypos < db->ypos
+ || cdb.xpos + cdb.width > db->xpos + db->width
+ || cdb.ypos + cdb.height > db->ypos + db->height)
+ continue;
+ /* We have to invert the offset here as normalization
+ will have made them positive which the output
+ routines will treat as a truely +ve offset. */
+ cdga.xoffset = -cdga.xoffset;
+ cdga.yoffset = -cdga.yoffset;
+
+ switch (IMAGE_INSTANCE_TYPE (childii))
+ {
+ case IMAGE_TEXT:
+ {
+ /* #### This is well hacked and could use some
+ generalisation.*/
+ if (redisplay_normalize_glyph_area (&cdb, &cdga)
+ &&
+ (frame_changed || IMAGE_INSTANCE_DIRTYP (childii)))
+ {
+ struct display_line dl; /* this is fake */
+ Lisp_Object string =
+ IMAGE_INSTANCE_TEXT_STRING (childii);
+ convert_bufbyte_string_into_emchar_dynarr
+ (XSTRING_DATA (string), XSTRING_LENGTH (string), buf);
+
+ redisplay_normalize_display_box (&cdb, &cdga);
+ /* Offsets are now +ve again so be careful
+ when fixing up the display line. */
+ xzero (dl);
+ /* Munge boxes into display lines. */
+ dl.ypos = (cdb.ypos - cdga.yoffset)
+ + glyph_ascent (child, Qnil, findex, window);
+ dl.ascent = glyph_ascent (child, Qnil, findex, window);
+ dl.descent = glyph_descent (child, Qnil, findex, window);
+ dl.top_clip = cdga.yoffset;
+ dl.clip = (dl.ypos + dl.descent) - (cdb.ypos + cdb.height);
+ /* output_string doesn't understand offsets in
+ the same way as other routines - we have to
+ add the offset to the width so that we
+ output the full string. */
+ MAYBE_DEVMETH (d, output_string, (w, &dl, buf, cdb.xpos,
+ cdga.xoffset, cdb.xpos,
+ cdga.width + cdga.xoffset,
+ findex, 0, 0, 0, 0));
+ Dynarr_reset (buf);
+ }
+ }
+ break;
+
+ case IMAGE_MONO_PIXMAP:
+ case IMAGE_COLOR_PIXMAP:
+ if (frame_changed || IMAGE_INSTANCE_DIRTYP (childii))
+ redisplay_output_pixmap (w, child, &cdb, &cdga, findex,
+ 0, 0, 0, 0);
+ break;
+
+ case IMAGE_WIDGET:
+ case IMAGE_SUBWINDOW:
+ if (frame_changed || IMAGE_INSTANCE_DIRTYP (childii))
+ redisplay_output_subwindow (w, child, &cdb, &cdga, findex,
+ 0, 0, 0);
+ break;
+
+ case IMAGE_LAYOUT:
+ redisplay_output_layout (w, child, &cdb, &cdga, findex,
+ 0, 0, 0);
+ break;
+
+ case IMAGE_NOTHING:
+ /* nothing is as nothing does */
+ break;
+
+ case IMAGE_POINTER:
+ default:
+ abort ();
+ }
+ }
}
-
- redisplay_clear_region (window, findex, clear_x, clear_y,
- clear_width, clear_height);
}
-#if 0
- redisplay_clear_region (window, findex, xpos - xoffset, dl->ypos - dl->ascent,
- width, lheight);
-#endif
- /* if we can't view the whole window we can't view any of it */
- if (IMAGE_INSTANCE_SUBWINDOW_HEIGHT (p) > lheight
- ||
- IMAGE_INSTANCE_SUBWINDOW_WIDTH (p) > width)
+ Dynarr_free (buf);
+}
+
+/****************************************************************************
+ redisplay_output_pixmap
+
+
+ output a pixmap.
+ ****************************************************************************/
+void
+redisplay_output_pixmap (struct window *w,
+ Lisp_Object image_instance,
+ struct display_box* db, struct display_glyph_area* dga,
+ face_index findex, int cursor_start, int cursor_width,
+ int cursor_height, int offset_bitmap)
+{
+ struct frame *f = XFRAME (w->frame);
+ struct device *d = XDEVICE (f->device);
+ struct Lisp_Image_Instance *p = XIMAGE_INSTANCE (image_instance);
+ Lisp_Object window;
+ XSETWINDOW (window, w);
+
+ dga->height = IMAGE_INSTANCE_PIXMAP_HEIGHT (p);
+ dga->width = IMAGE_INSTANCE_PIXMAP_WIDTH (p);
+
+ /* This makes the glyph area fit into the display area. */
+ if (!redisplay_normalize_glyph_area (db, dga))
+ return;
+
+ /* Clear the area the pixmap is going into. The pixmap itself will
+ always take care of the full width. We don't want to clear where
+ it is going to go in order to avoid flicker. So, all we have to
+ take care of is any area above or below the pixmap. If the pixmap
+ has a mask in which case we have to clear the whole damn thing
+ since we can't yet clear just the area not included in the
+ mask. */
+ if (!offset_bitmap)
{
- redisplay_clear_region (window, findex, xpos - xoffset, dl->ypos - dl->ascent,
- width, lheight);
- unmap_subwindow (image_instance);
+ redisplay_clear_clipped_region (window, findex,
+ db, dga,
+ (int)IMAGE_INSTANCE_PIXMAP_MASK (p),
+ Qnil);
+
+ /* This shrinks the display box to exactly enclose the glyph
+ area. */
+ redisplay_normalize_display_box (db, dga);
}
- else
- map_subwindow (image_instance, xpos - xoffset, dl->ypos - dl->ascent);
+ assert (db->xpos >= 0 && db->ypos >= 0);
+
+ MAYBE_DEVMETH (d, output_pixmap, (w, image_instance,
+ db, dga,
+ findex, cursor_start,
+ cursor_width, cursor_height,
+ offset_bitmap));
}
/****************************************************************************
d = XDEVICE (f->device);
/* if we have subwindows in the region we have to unmap them */
- if (Dynarr_length (FRAME_SUBWINDOW_CACHE (f)))
- {
- redisplay_unmap_subwindows (f, x, y, width, height);
- }
+ redisplay_unmap_subwindows_maybe (f, x, y, width, height);
/* #### This isn't quite right for when this function is called
from the toolbar code. */
(locale, d, f, findex, x, y, width, height, fcolor, bcolor, background_pixmap));
}
+/****************************************************************************
+ redisplay_clear_clipped_region
+
+ Clear the area in the dest display_box not covered by the src
+ display_glyph_area using the given face. This is a common occurance
+ for images shorter than the display line. Clipping can be played
+ around with by altering these. glyphsrc should be normalized.
+ ****************************************************************************/
+static void
+redisplay_clear_clipped_region (Lisp_Object window, face_index findex,
+ struct display_box* dest, struct display_glyph_area* glyphsrc,
+ int fullheight_p, Lisp_Object ignored_subwindow)
+{
+ /* assume dest->xpos >= 0 */
+ int clear_x;
+ struct frame* f = XFRAME (XWINDOW (window)->frame);
+
+ if (glyphsrc->xoffset > 0)
+ {
+ clear_x = dest->xpos + glyphsrc->xoffset;
+ }
+ else
+ {
+ clear_x = dest->xpos;
+ }
+
+ /* If we need the whole height cleared then just do it. */
+ if (fullheight_p)
+ {
+ redisplay_clear_region (window, findex, clear_x, dest->ypos,
+ glyphsrc->width, dest->height);
+ }
+ else
+ {
+ int yoffset = (glyphsrc->yoffset > 0 ? glyphsrc->yoffset : 0);
+
+ /* We need to make sure that subwindows are unmapped from the
+ whole area. */
+ redisplay_unmap_subwindows_except_us (f, clear_x, dest->ypos,
+ glyphsrc->width, dest->height,
+ ignored_subwindow);
+ /* first the top box */
+ if (yoffset > 0)
+ {
+ redisplay_clear_region (window, findex, clear_x, dest->ypos,
+ glyphsrc->width, yoffset);
+
+ }
+ /* Then the bottom box */
+ if (yoffset + glyphsrc->height < dest->height)
+ {
+ redisplay_clear_region (window, findex, clear_x,
+ dest->ypos + yoffset + glyphsrc->height,
+ glyphsrc->width,
+ dest->height - (yoffset + glyphsrc->height));
+
+ }
+ }
+}
+
+/*****************************************************************************
+ redisplay_normalize_glyph_area
+ redisplay_normalize_display_box
+
+ Calculate the visible box for displaying src in dest.
+ ****************************************************************************/
+int
+redisplay_normalize_glyph_area (struct display_box* dest,
+ struct display_glyph_area* glyphsrc)
+{
+ if (dest->xpos + glyphsrc->xoffset > dest->xpos + dest->width
+ ||
+ dest->ypos + glyphsrc->yoffset > dest->ypos + dest->height
+ ||
+ -glyphsrc->xoffset >= glyphsrc->width
+ ||
+ -glyphsrc->yoffset >= glyphsrc->height)
+ {
+ /* It's all clipped out */
+ return 0;
+ }
+
+ /* Horizontal offsets. This works because xoffset can be -ve as well as +ve */
+ if (dest->xpos + glyphsrc->xoffset + glyphsrc->width > dest->xpos + dest->width)
+ {
+ if (glyphsrc->xoffset > 0)
+ glyphsrc->width = dest->width - glyphsrc->xoffset;
+ else
+ glyphsrc->width = dest->width;
+ }
+
+ if (glyphsrc->xoffset < 0)
+ glyphsrc->width += glyphsrc->xoffset;
+
+ /* Vertical offsets. This works because yoffset can be -ve as well as +ve */
+ if (dest->ypos + glyphsrc->yoffset + glyphsrc->height > dest->ypos + dest->height)
+ {
+ if (glyphsrc->yoffset > 0)
+ glyphsrc->height = dest->height - glyphsrc->yoffset;
+ else
+ glyphsrc->height = dest->height;
+ }
+
+ if (glyphsrc->yoffset < 0)
+ glyphsrc->height += glyphsrc->yoffset;
+
+ return 1;
+}
+
+static void
+redisplay_normalize_display_box (struct display_box* dest,
+ struct display_glyph_area* glyphsrc)
+{
+ /* Adjust the destination area. At the end of this the destination
+ area will exactly enclose the glyph area. The only remaining
+ adjustment will be offsets into the glyph area. */
+
+ /* Horizontal adjustment. */
+ if (glyphsrc->xoffset > 0)
+ {
+ dest->xpos += glyphsrc->xoffset;
+ dest->width -= glyphsrc->xoffset;
+ glyphsrc->xoffset = 0;
+ }
+ else
+ glyphsrc->xoffset = -glyphsrc->xoffset;
+
+ if (glyphsrc->width < dest->width)
+ dest->width = glyphsrc->width;
+
+ /* Vertical adjustment. */
+ if (glyphsrc->yoffset > 0)
+ {
+ dest->ypos += glyphsrc->yoffset;
+ dest->height -= glyphsrc->yoffset;
+ glyphsrc->yoffset = 0;
+ }
+ else
+ glyphsrc->yoffset = -glyphsrc->yoffset;
+
+ if (glyphsrc->height < dest->height)
+ dest->height = glyphsrc->height;
+}
+
+/*****************************************************************************
+ redisplay_display_boxes_in_window_p
+
+ Determine whether the require display_glyph_area is completely inside
+ the window. 0 means the display_box is not in the window. 1 means the
+ display_box and the display_glyph_area are in the window. -1 means
+ the display_box is in the window but the display_glyph_area is not.
+ ****************************************************************************/
+static int
+redisplay_display_boxes_in_window_p (struct window* w,
+ struct display_box* db,
+ struct display_glyph_area* dga)
+{
+ int left = WINDOW_TEXT_LEFT (w);
+ int right = WINDOW_TEXT_RIGHT (w);
+ int top = WINDOW_TEXT_TOP (w);
+ int bottom = WINDOW_TEXT_BOTTOM (w);
+
+ if (db->xpos < left || db->ypos < top
+ || db->xpos + db->width > right
+ || db->ypos + db->height > bottom)
+ /* We are not displaying in a window at all */
+ return 0;
+
+ if (db->xpos + dga->xoffset >= left
+ &&
+ db->ypos + dga->yoffset >= top
+ &&
+ db->xpos + dga->xoffset + dga->width <= right
+ &&
+ db->ypos + dga->yoffset + dga->height <= bottom)
+ return 1;
+
+ return -1;
+}
+
+/*****************************************************************************
+ redisplay_calculate_display_boxes
+
+ Convert from rune/display_line co-ordinates to display_box
+ co-ordinates.
+ ****************************************************************************/
+int
+redisplay_calculate_display_boxes (struct display_line *dl, int xpos,
+ int xoffset, int start_pixpos, int width,
+ struct display_box* dest,
+ struct display_glyph_area* src)
+{
+ dest->xpos = xpos;
+ dest->ypos = DISPLAY_LINE_YPOS (dl);
+ dest->width = width;
+ dest->height = DISPLAY_LINE_HEIGHT (dl);
+
+ src->xoffset = -xoffset;
+ src->yoffset = -dl->top_clip;
+ src->width = 0;
+ src->height = 0;
+
+ if (start_pixpos >=0 && start_pixpos > xpos)
+ {
+ /* Oops, we're asking for a start outside of the displayable
+ area. */
+ if (start_pixpos > xpos + width)
+ return 0;
+ dest->xpos = start_pixpos;
+ dest->width -= (start_pixpos - xpos);
+ /* Offsets are -ve when we want to clip pixels off the displayed
+ glyph. */
+ src->xoffset -= (start_pixpos - xpos);
+ }
+
+ return 1;
+}
+
/*****************************************************************************
redisplay_clear_top_of_window
if (height)
{
- struct frame *f = XFRAME (w->frame);
Lisp_Object window;
int bflag = 0 ; /* (window_needs_vertical_divider (w) ? 0 : 1);*/
layout_bounds bounds;
int min_start, int max_end)
{
struct frame *f = XFRAME (w->frame);
- struct device *d = XDEVICE (f->device);
int ypos1, ypos2;
int ddla_len = Dynarr_length (ddla);
struct device *d = XDEVICE (f->device);
int x, y, width, height;
int shadow_thickness = MODELINE_SHADOW_THICKNESS (w);
+ enum edge_style style;
x = WINDOW_MODELINE_LEFT (w);
width = WINDOW_MODELINE_RIGHT (w) - x;
height = dl->ascent + dl->descent + 2 * shadow_thickness;
if (XINT (w->modeline_shadow_thickness) < 0)
- shadow_thickness = - shadow_thickness;
+ {
+ style = EDGE_BEVEL_IN;
+ }
+ else
+ {
+ style = EDGE_BEVEL_OUT;
+ }
MAYBE_DEVMETH (d, bevel_area,
- (w, MODELINE_INDEX, x, y, width, height, shadow_thickness));
+ (w, MODELINE_INDEX, x, y, width, height, shadow_thickness,
+ EDGE_ALL, style));
}
case IMAGE_COLOR_PIXMAP:
case IMAGE_SUBWINDOW:
case IMAGE_WIDGET:
+ case IMAGE_LAYOUT:
/* just do nothing here */
break;
static void
tty_clear_region (Lisp_Object window, struct device* d, struct frame * f,
face_index findex, int x, int y,
- int width, int height, Lisp_Object fcolor, Lisp_Object bcolor,
+ int width, int height, Lisp_Object fcolor, Lisp_Object bcolor,
Lisp_Object background_pixmap)
{
struct console *c = XCONSOLE (FRAME_CONSOLE (f));
{
Lisp_Object dev = CONSOLE_SELECTED_DEVICE (c);
- if (!GC_NILP (dev))
+ if (!NILP (dev))
{
Lisp_Object frm = DEVICE_SELECTED_FRAME (XDEVICE (dev));
- if (!GC_NILP (frm))
+ if (!NILP (frm))
{
struct frame *f = XFRAME (frm);
\f
struct fkey_table
{
- CONST char *cap, *name;
+ CONST char *cap;
+ CONST char *name;
};
/* Termcap capability names that correspond directly to X keysyms.
describes F10, whereas othertimes it describes F0 and "k;" describes F10.
We will attempt to politely accommodate both systems by testing for
"k;", and if it is present, assuming that "k0" denotes F0, otherwise F10.
- */
+ */
{
- char *k_semi = tgetstr ("k;", address);
- char *k0 = tgetstr ("k0", address);
- CONST char *k0_name = "f10";
+ CONST char *k_semi = tgetstr ("k;", address);
+ CONST char *k0 = tgetstr ("k0", address);
if (k_semi)
- {
- Fdefine_key (function_key_map, build_ext_string (k_semi, FORMAT_BINARY),
- vector1 (intern ("f10")));
- k0_name = "f0";
- }
+ Fdefine_key (function_key_map, build_ext_string (k_semi, FORMAT_BINARY),
+ vector1 (intern ("f10")));
if (k0)
Fdefine_key (function_key_map, build_ext_string (k0, FORMAT_BINARY),
- vector1 (intern (k0_name)));
+ vector1 (intern (k_semi ? "f0" : "f10")));
}
/* Set up cookies for numbered function keys above f10. */
}
}
}
- }
+ }
/*
* Various mappings to try and get a better fit.
*/
- {
-#define CONDITIONAL_REASSIGN(cap1, cap2, sym) \
- if (!tgetstr (cap1, address)) \
- { \
- char *sequence = tgetstr (cap2, address); \
- if (sequence) \
- Fdefine_key (function_key_map, \
- build_ext_string (sequence, FORMAT_BINARY), \
- vector1 (intern (sym))); \
- }
+#define CONDITIONAL_REASSIGN(cap1, cap2, keyname) \
+ if (!tgetstr (cap1, address)) \
+ { \
+ char *sequence = tgetstr (cap2, address); \
+ if (sequence) \
+ Fdefine_key (function_key_map, \
+ build_ext_string (sequence, FORMAT_BINARY), \
+ vector1 (intern (keyname))); \
+ }
- /* if there's no key_next keycap, map key_npage to `next' keysym */
- CONDITIONAL_REASSIGN ("%5", "kN", "next");
- /* if there's no key_prev keycap, map key_ppage to `previous' keysym */
- CONDITIONAL_REASSIGN ("%8", "kP", "prior");
- /* if there's no key_dc keycap, map key_ic to `insert' keysym */
- CONDITIONAL_REASSIGN ("kD", "kI", "insert");
-
- /* IBM has their own non-standard dialect of terminfo.
- If the standard name isn't found, try the IBM name. */
- CONDITIONAL_REASSIGN ("kB", "KO", "backtab");
- CONDITIONAL_REASSIGN ("@4", "kJ", "execute"); /* actually "action" */
- CONDITIONAL_REASSIGN ("@4", "kc", "execute"); /* actually "command" */
- CONDITIONAL_REASSIGN ("%7", "ki", "menu");
- CONDITIONAL_REASSIGN ("@7", "kw", "end");
- CONDITIONAL_REASSIGN ("F1", "k<", "f11");
- CONDITIONAL_REASSIGN ("F2", "k>", "f12");
- CONDITIONAL_REASSIGN ("%1", "kq", "help");
- CONDITIONAL_REASSIGN ("*6", "kU", "select");
+ /* if there's no key_next keycap, map key_npage to `next' keysym */
+ CONDITIONAL_REASSIGN ("%5", "kN", "next");
+ /* if there's no key_prev keycap, map key_ppage to `previous' keysym */
+ CONDITIONAL_REASSIGN ("%8", "kP", "prior");
+ /* if there's no key_dc keycap, map key_ic to `insert' keysym */
+ CONDITIONAL_REASSIGN ("kD", "kI", "insert");
+
+ /* IBM has their own non-standard dialect of terminfo.
+ If the standard name isn't found, try the IBM name. */
+ CONDITIONAL_REASSIGN ("kB", "KO", "backtab");
+ CONDITIONAL_REASSIGN ("@4", "kJ", "execute"); /* actually "action" */
+ CONDITIONAL_REASSIGN ("@4", "kc", "execute"); /* actually "command" */
+ CONDITIONAL_REASSIGN ("%7", "ki", "menu");
+ CONDITIONAL_REASSIGN ("@7", "kw", "end");
+ CONDITIONAL_REASSIGN ("F1", "k<", "f11");
+ CONDITIONAL_REASSIGN ("F2", "k>", "f12");
+ CONDITIONAL_REASSIGN ("%1", "kq", "help");
+ CONDITIONAL_REASSIGN ("*6", "kU", "select");
#undef CONDITIONAL_REASSIGN
- }
return Qnil;
}
#endif
/* Number of pixels below each line. */
-/* #### implement me */
-int x_interline_space;
+int x_interline_space; /* #### implement me */
#define EOL_CURSOR_WIDTH 5
-static void x_output_pixmap (struct window *w, struct display_line *dl,
- Lisp_Object image_instance, int xpos,
- int xoffset,
- int start_pixpos, int width, face_index findex,
- int cursor_start, int cursor_width,
- int cursor_height);
static void x_output_vertical_divider (struct window *w, int clear);
static void x_output_blank (struct window *w, struct display_line *dl,
struct rune *rb, int start_pixpos,
int xpos, face_index findex);
static void x_clear_frame (struct frame *f);
static void x_clear_frame_windows (Lisp_Object window);
-void bevel_modeline (struct window *w, struct display_line *dl);
/* Note: We do not use the Xmb*() functions and XFontSets.
else if (rb->object.chr.ch == '\n')
{
/* Clear in case a cursor was formerly here. */
- int height = dl->ascent + dl->descent - dl->clip;
-
- redisplay_clear_region (window, findex, xpos, dl->ypos - dl->ascent,
- rb->width, height);
+ redisplay_clear_region (window, findex, xpos,
+ DISPLAY_LINE_YPOS (dl),
+ rb->width,
+ DISPLAY_LINE_HEIGHT (dl));
elt++;
}
}
else if (rb->type == RUNE_DGLYPH)
{
Lisp_Object instance;
+ struct display_box dbox;
+ struct display_glyph_area dga;
+ redisplay_calculate_display_boxes (dl, rb->xpos, rb->object.dglyph.xoffset,
+ start_pixpos, rb->width,
+ &dbox, &dga);
XSETWINDOW (window, w);
instance = glyph_image_instance (rb->object.dglyph.glyph,
case IMAGE_MONO_PIXMAP:
case IMAGE_COLOR_PIXMAP:
- x_output_pixmap (w, dl, instance, xpos,
- rb->object.dglyph.xoffset, start_pixpos,
- rb->width, findex, cursor_start,
- cursor_width, cursor_height);
+ redisplay_output_pixmap (w, instance, &dbox, &dga, findex,
+ cursor_start, cursor_width,
+ cursor_height, 0);
break;
- case IMAGE_POINTER:
- abort ();
-
case IMAGE_WIDGET:
case IMAGE_SUBWINDOW:
- redisplay_output_subwindow (w, dl, instance, xpos,
- rb->object.dglyph.xoffset, start_pixpos,
- rb->width, findex, cursor_start,
- cursor_width, cursor_height);
+ redisplay_output_subwindow (w, instance, &dbox, &dga, findex,
+ cursor_start, cursor_width,
+ cursor_height);
+ break;
+
+ case IMAGE_LAYOUT:
+ redisplay_output_layout (w, instance, &dbox, &dga, findex,
+ cursor_start, cursor_width,
+ cursor_height);
+ break;
case IMAGE_NOTHING:
/* nothing is as nothing does */
break;
+ case IMAGE_POINTER:
default:
abort ();
}
static void
x_bevel_area (struct window *w, face_index findex,
int x, int y, int width, int height,
- int shadow_thickness)
+ int shadow_thickness, int edges, enum edge_style style)
{
struct frame *f = XFRAME (w->frame);
struct device *d = XDEVICE (f->device);
int flip_gcs = 0;
unsigned long mask;
+ assert (shadow_thickness >=0);
memset (&gcv, ~0, sizeof (XGCValues));
tmp_pixel = WINDOW_FACE_CACHEL_BACKGROUND (w, findex);
gcv.foreground = background_pixel;
background_gc = gc_cache_lookup (DEVICE_X_GC_CACHE (d), &gcv, mask);
- /* possibly revert the GC's in case the shadow thickness is < 0.
- This will give a depressed look to the divider */
- if (shadow_thickness < 0)
+ /* possibly revert the GC's This will give a depressed look to the
+ divider */
+ if (style == EDGE_ETCHED_IN || style == EDGE_BEVEL_IN)
{
GC temp;
temp = top_shadow_gc;
top_shadow_gc = bottom_shadow_gc;
bottom_shadow_gc = temp;
-
- /* better avoid a Bad Address XLib error ;-) */
- shadow_thickness = - shadow_thickness;
}
+ if (style == EDGE_ETCHED_IN || style == EDGE_ETCHED_OUT)
+ shadow_thickness /= 2;
+
/* Draw the shadows around the divider line */
x_output_shadows (f, x, y, width, height,
top_shadow_gc, bottom_shadow_gc,
- background_gc, shadow_thickness);
+ background_gc, shadow_thickness, edges);
+
+ if (style == EDGE_ETCHED_IN || style == EDGE_ETCHED_OUT)
+ {
+ /* Draw the shadows around the divider line */
+ x_output_shadows (f, x + shadow_thickness, y + shadow_thickness,
+ width - 2*shadow_thickness, height - 2*shadow_thickness,
+ bottom_shadow_gc, top_shadow_gc,
+ background_gc, shadow_thickness, edges);
+ }
}
/*****************************************************************************
if (width < 0)
width = x_text_width (f, cachel, Dynarr_atp (buf, 0), Dynarr_length (buf));
- height = dl->ascent + dl->descent - dl->clip;
+ height = DISPLAY_LINE_HEIGHT (dl);
/* Regularize the variables passed in. */
xpos -= xoffset;
+ /* make sure the area we are about to display is subwindow free. */
+ redisplay_unmap_subwindows_maybe (f, clip_start, DISPLAY_LINE_YPOS (dl),
+ clip_end - clip_start, DISPLAY_LINE_HEIGHT (dl));
+
nruns = separate_textual_runs (text_storage, runs, Dynarr_atp (buf, 0),
Dynarr_length (buf));
if (bgc)
XFillRectangle (dpy, x_win, bgc, clip_start,
- dl->ypos - dl->ascent, clip_end - clip_start,
+ DISPLAY_LINE_YPOS (dl), clip_end - clip_start,
height);
for (i = 0; i < nruns; i++)
the given font. It is possible that a font is being displayed
on a line taller than it is, so this would cause us to fail to
clear some areas. */
- if ((int) fi->height < (int) (height + dl->clip))
+ if ((int) fi->height < (int) (height + dl->clip + dl->top_clip))
{
int clear_start = max (xpos, clip_start);
int clear_end = min (xpos + this_width, clip_end);
ypos1_string = dl->ypos - fi->ascent;
ypos2_string = dl->ypos + fi->descent;
- ypos1_line = dl->ypos - dl->ascent;
- ypos2_line = dl->ypos + dl->descent - dl->clip;
+ ypos1_line = DISPLAY_LINE_YPOS (dl);
+ ypos2_line = ypos1_line + DISPLAY_LINE_HEIGHT (dl);
/* Make sure we don't clear below the real bottom of the
line. */
else
{
redisplay_clear_region (window, findex, clear_start,
- dl->ypos - dl->ascent, clear_end - clear_start,
+ DISPLAY_LINE_YPOS (dl), clear_end - clear_start,
height);
}
}
clip_box[0].width = clip_end - clip_start;
clip_box[0].height = height;
- XSetClipRectangles (dpy, gc, clip_start, dl->ypos - dl->ascent,
+ XSetClipRectangles (dpy, gc, clip_start, DISPLAY_LINE_YPOS (dl),
clip_box, 1, Unsorted);
}
clip_box[0].width = cursor_width;
clip_box[0].height = height;
- XSetClipRectangles (dpy, cgc, cursor_start, dl->ypos - dl->ascent,
+ XSetClipRectangles (dpy, cgc, cursor_start, DISPLAY_LINE_YPOS (dl),
clip_box, 1, Unsorted);
if (runs[i].dimension == 1)
tmp_y = dl->ypos - bogusly_obtained_ascent_value;
tmp_height = cursor_height;
- if (tmp_y + tmp_height > (int) (dl->ypos - dl->ascent + height))
+ if (tmp_y + tmp_height > (int) (DISPLAY_LINE_YPOS(dl) + height))
{
- tmp_y = dl->ypos - dl->ascent + height - tmp_height;
- if (tmp_y < (int) (dl->ypos - dl->ascent))
- tmp_y = dl->ypos - dl->ascent;
- tmp_height = dl->ypos - dl->ascent + height - tmp_y;
+ tmp_y = DISPLAY_LINE_YPOS (dl) + height - tmp_height;
+ if (tmp_y < (int) DISPLAY_LINE_YPOS (dl))
+ tmp_y = DISPLAY_LINE_YPOS (dl);
+ tmp_height = DISPLAY_LINE_YPOS (dl) + height - tmp_y;
}
if (need_clipping)
void
x_output_x_pixmap (struct frame *f, struct Lisp_Image_Instance *p, int x,
- int y, int clip_x, int clip_y, int clip_width,
- int clip_height, int width, int height, int pixmap_offset,
- unsigned long fg, unsigned long bg, GC override_gc)
+ int y, int xoffset, int yoffset,
+ int width, int height, unsigned long fg, unsigned long bg,
+ GC override_gc)
{
struct device *d = XDEVICE (f->device);
Display *dpy = DEVICE_X_DISPLAY (d);
GC gc;
XGCValues gcv;
unsigned long pixmap_mask;
- int need_clipping = (clip_x || clip_y);
if (!override_gc)
{
{
gcv.function = GXcopy;
gcv.clip_mask = IMAGE_INSTANCE_X_MASK (p);
- gcv.clip_x_origin = x;
- gcv.clip_y_origin = y - pixmap_offset;
+ gcv.clip_x_origin = x - xoffset;
+ gcv.clip_y_origin = y - yoffset;
pixmap_mask |= (GCFunction | GCClipMask | GCClipXOrigin |
GCClipYOrigin);
- /* Can't set a clip rectangle below because we already have a mask.
- We could conceivably create a new clipmask by zeroing out
- everything outside the clip region. Is it worth it?
+ /* Can't set a clip rectangle because we already have a mask.
Is it possible to get an equivalent effect by changing the
args to XCopyArea below rather than messing with a clip box?
- - dkindred@cs.cmu.edu */
- need_clipping = 0;
+ - dkindred@cs.cmu.edu
+ Yes. We don't clip at all now - andy@xemacs.org
+ */
}
gc = gc_cache_lookup (DEVICE_X_GC_CACHE (d), &gcv, pixmap_mask);
/* override_gc might have a mask already--we don't want to nuke it.
Maybe we can insist that override_gc have no mask, or use
one of the suggestions above. */
- need_clipping = 0;
- }
-
- if (need_clipping)
- {
- XRectangle clip_box[1];
-
- clip_box[0].x = clip_x;
- clip_box[0].y = clip_y;
- clip_box[0].width = clip_width;
- clip_box[0].height = clip_height;
-
- XSetClipRectangles (dpy, gc, x, y, clip_box, 1, Unsorted);
}
/* depth of 0 means it's a bitmap, not a pixmap, and we should use
pixel values, instead of symbolic of fg/bg. */
if (IMAGE_INSTANCE_PIXMAP_DEPTH (p) > 0)
{
- XCopyArea (dpy, IMAGE_INSTANCE_X_PIXMAP (p), x_win, gc, 0,
- pixmap_offset, width,
+ XCopyArea (dpy,
+ IMAGE_INSTANCE_X_PIXMAP_SLICE
+ (p, IMAGE_INSTANCE_PIXMAP_SLICE (p)), x_win, gc, xoffset,
+ yoffset, width,
height, x, y);
}
else
{
- XCopyPlane (dpy, IMAGE_INSTANCE_X_PIXMAP (p), x_win, gc, 0,
- (pixmap_offset < 0
- ? 0
- : pixmap_offset),
- width, height, x,
- (pixmap_offset < 0
- ? y - pixmap_offset
- : y),
- 1L);
- }
-
- if (need_clipping)
- {
- XSetClipMask (dpy, gc, None);
- XSetClipOrigin (dpy, gc, 0, 0);
+ XCopyPlane (dpy, IMAGE_INSTANCE_X_PIXMAP_SLICE
+ (p, IMAGE_INSTANCE_PIXMAP_SLICE (p)), x_win, gc,
+ xoffset, yoffset, width, height, x, y, 1L);
}
}
static void
-x_output_pixmap (struct window *w, struct display_line *dl,
- Lisp_Object image_instance, int xpos, int xoffset,
- int start_pixpos, int width, face_index findex,
- int cursor_start, int cursor_width, int cursor_height)
+x_output_pixmap (struct window *w, Lisp_Object image_instance,
+ struct display_box *db, struct display_glyph_area *dga,
+ face_index findex, int cursor_start, int cursor_width,
+ int cursor_height, int bg_pixmap)
{
struct frame *f = XFRAME (w->frame);
struct device *d = XDEVICE (f->device);
struct Lisp_Image_Instance *p = XIMAGE_INSTANCE (image_instance);
- Lisp_Object window;
Display *dpy = DEVICE_X_DISPLAY (d);
Window x_win = XtWindow (FRAME_X_TEXT_WIDGET (f));
- int lheight = dl->ascent + dl->descent - dl->clip;
- int pheight = ((int) IMAGE_INSTANCE_PIXMAP_HEIGHT (p) > lheight ? lheight :
- IMAGE_INSTANCE_PIXMAP_HEIGHT (p));
- int pwidth = min (width + xoffset, (int) IMAGE_INSTANCE_PIXMAP_WIDTH (p));
- int clip_x, clip_y, clip_width, clip_height;
-
- /* The pixmap_offset is used to center the pixmap on lines which are
- shorter than it is. This results in odd effects when scrolling
- pixmaps off of the bottom. Let's try not using it. */
-#if 0
- int pixmap_offset = (int) (IMAGE_INSTANCE_PIXMAP_HEIGHT (p) - lheight) / 2;
-#else
- int pixmap_offset = 0;
-#endif
-
- XSETWINDOW (window, w);
-
- if ((start_pixpos >= 0 && start_pixpos > xpos) || xoffset)
- {
- if (start_pixpos > xpos && start_pixpos > xpos + width)
- return;
-
- clip_x = xoffset;
- clip_width = width;
- if (start_pixpos > xpos)
- {
- clip_x += (start_pixpos - xpos);
- clip_width -= (start_pixpos - xpos);
- }
- }
- else
- {
- clip_x = 0;
- clip_width = 0;
- }
-
- /* Place markers for possible future functionality (clipping the top
- half instead of the bottom half; think pixel scrolling). */
- clip_y = 0;
- clip_height = pheight;
-
- /* Clear the area the pixmap is going into. The pixmap itself will
- always take care of the full width. We don't want to clear where
- it is going to go in order to avoid flicker. So, all we have to
- take care of is any area above or below the pixmap. */
- /* #### We take a shortcut for now. We know that since we have
- pixmap_offset hardwired to 0 that the pixmap is against the top
- edge so all we have to worry about is below it. */
- /* #### Unless the pixmap has a mask in which case we have to clear
- the whole damn thing since we can't yet clear just the area not
- included in the mask. */
- if (((int) (dl->ypos - dl->ascent + pheight) <
- (int) (dl->ypos + dl->descent - dl->clip))
- || IMAGE_INSTANCE_X_MASK (p))
- {
- int clear_x, clear_y, clear_width, clear_height;
-
- if (IMAGE_INSTANCE_X_MASK (p))
- {
- clear_y = dl->ypos - dl->ascent;
- clear_height = lheight;
- }
- else
- {
- clear_y = dl->ypos - dl->ascent + pheight;
- clear_height = lheight - pheight;
- }
-
- if (start_pixpos >= 0 && start_pixpos > xpos)
- {
- clear_x = start_pixpos;
- clear_width = xpos + width - start_pixpos;
- }
- else
- {
- clear_x = xpos;
- clear_width = width;
- }
-
- redisplay_clear_region (window, findex, clear_x, clear_y,
- clear_width, clear_height);
- }
-
+
/* Output the pixmap. */
{
Lisp_Object tmp_pixel;
tmp_pixel = WINDOW_FACE_CACHEL_BACKGROUND (w, findex);
tmp_bcolor = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (tmp_pixel));
- x_output_x_pixmap (f, p, xpos - xoffset, dl->ypos - dl->ascent, clip_x,
- clip_y, clip_width, clip_height,
- pwidth, pheight, pixmap_offset,
+ x_output_x_pixmap (f, p, db->xpos, db->ypos,
+ dga->xoffset, dga->yoffset,
+ dga->width, dga->height,
tmp_fcolor.pixel, tmp_bcolor.pixel, 0);
}
/* Draw a cursor over top of the pixmap. */
- if (cursor_width && cursor_height && (cursor_start >= xpos)
+ if (cursor_width && cursor_height && (cursor_start >= db->xpos)
&& !NILP (w->text_cursor_visible_p)
- && (cursor_start < xpos + pwidth))
+ && (cursor_start < db->xpos + dga->width))
{
GC gc;
int focus = EQ (w->frame, DEVICE_FRAME_WITH_FOCUS_REAL (d));
- int y = dl->ypos - dl->ascent;
struct face_cachel *cursor_cachel =
WINDOW_FACE_CACHEL (w,
get_builtin_face_cache_index
gc = x_get_gc (d, Qnil, cursor_cachel->background, Qnil, Qnil, Qnil);
- if (cursor_width > xpos + pwidth - cursor_start)
- cursor_width = xpos + pwidth - cursor_start;
+ if (cursor_width > db->xpos + dga->width - cursor_start)
+ cursor_width = db->xpos + dga->width - cursor_start;
if (focus)
{
- XFillRectangle (dpy, x_win, gc, cursor_start, y, cursor_width,
+ XFillRectangle (dpy, x_win, gc, cursor_start, db->ypos, cursor_width,
cursor_height);
}
else
{
- XDrawRectangle (dpy, x_win, gc, cursor_start, y, cursor_width,
+ XDrawRectangle (dpy, x_win, gc, cursor_start, db->ypos, cursor_width,
cursor_height);
}
}
XColor tmp_color;
XGCValues gcv;
GC background_gc;
+ enum edge_style style;
unsigned long mask;
int x, y1, y2, width, shadow_thickness, spacing, line_width;
x + spacing + shadow_thickness, y1,
line_width, y2 - y1);
+ if (shadow_thickness < 0)
+ {
+ shadow_thickness = -shadow_thickness;
+ style = EDGE_BEVEL_IN;
+ }
+ else
+ {
+ style = EDGE_BEVEL_OUT;
+ }
+
/* Draw the shadows around the divider line */
x_bevel_area (w, div_face, x + spacing, y1,
width - 2 * spacing, y2 - y1,
- shadow_thickness);
+ shadow_thickness, EDGE_ALL, style);
}
/*****************************************************************************
buffer);
int x = rb->xpos;
- int y = dl->ypos - dl->ascent;
+ int y = DISPLAY_LINE_YPOS (dl);
int width = rb->width;
- int height = dl->ascent + dl->descent - dl->clip;
+ int height = DISPLAY_LINE_HEIGHT (dl);
+
+ /* Unmap all subwindows in the area we are going to blank. */
+ redisplay_unmap_subwindows_maybe (f, x, y, width, height);
if (start_pixpos > x)
{
int x = rb->xpos;
int width = rb->width;
- int height = dl->ascent + dl->descent - dl->clip;
+ int height = DISPLAY_LINE_HEIGHT (dl);
int ypos1, ypos2, ypos3, ypos4;
- ypos1 = dl->ypos - dl->ascent;
+ ypos1 = DISPLAY_LINE_YPOS (dl);
ypos2 = ypos1 + rb->object.hline.yoffset;
ypos3 = ypos2 + rb->object.hline.thickness;
ypos4 = dl->ypos + dl->descent - dl->clip;
void
x_output_shadows (struct frame *f, int x, int y, int width, int height,
GC top_shadow_gc, GC bottom_shadow_gc, GC background_gc,
- int shadow_thickness)
+ int shadow_thickness, int edges)
{
struct device *d = XDEVICE (f->device);
for (elt = 0; elt < shadow_thickness; elt++)
{
int seg1 = elt;
- int seg2 = elt + shadow_thickness;
-
- top_shadow[seg1].x1 = x;
- top_shadow[seg1].x2 = x + width - elt - 1;
- top_shadow[seg1].y1 = top_shadow[seg1].y2 = y + elt;
-
- top_shadow[seg2].x1 = top_shadow[seg2].x2 = x + elt;
- top_shadow[seg2].y1 = y + shadow_thickness;
- top_shadow[seg2].y2 = y + height - elt - 1;
+ int seg2 = (edges & EDGE_TOP) ? elt + shadow_thickness : elt;
+ int bot_seg2 = (edges & EDGE_BOTTOM) ? elt + shadow_thickness : elt;
- bottom_shadow[seg1].x1 = x + elt + 1;
- bottom_shadow[seg1].x2 = x + width - 1;
- bottom_shadow[seg1].y1 = bottom_shadow[seg1].y2 = y + height - elt - 1;
-
- bottom_shadow[seg2].x1 = bottom_shadow[seg2].x2 = x + width - elt - 1;
- bottom_shadow[seg2].y1 = y + elt + 1;
- bottom_shadow[seg2].y2 = y + height - shadow_thickness;
+ if (edges & EDGE_TOP)
+ {
+ top_shadow[seg1].x1 = x + elt;
+ top_shadow[seg1].x2 = x + width - elt - 1;
+ top_shadow[seg1].y1 = top_shadow[seg1].y2 = y + elt;
+ }
+ if (edges & EDGE_LEFT)
+ {
+ top_shadow[seg2].x1 = top_shadow[seg2].x2 = x + elt;
+ top_shadow[seg2].y1 = y + elt;
+ top_shadow[seg2].y2 = y + height - elt - 1;
+ }
+ if (edges & EDGE_BOTTOM)
+ {
+ bottom_shadow[seg1].x1 = x + elt;
+ bottom_shadow[seg1].x2 = x + width - elt - 1;
+ bottom_shadow[seg1].y1 = bottom_shadow[seg1].y2 = y + height - elt - 1;
+ }
+ if (edges & EDGE_RIGHT)
+ {
+ bottom_shadow[bot_seg2].x1 = bottom_shadow[bot_seg2].x2 = x + width - elt - 1;
+ bottom_shadow[bot_seg2].y1 = y + elt;
+ bottom_shadow[bot_seg2].y2 = y + height - elt - 1;
+ }
}
- XDrawSegments (dpy, x_win, top_shadow_gc, top_shadow, shadow_thickness * 2);
+ XDrawSegments (dpy, x_win, top_shadow_gc, top_shadow,
+ ((edges & EDGE_TOP) ? shadow_thickness : 0)
+ + ((edges & EDGE_LEFT) ? shadow_thickness : 0));
XDrawSegments (dpy, x_win, bottom_shadow_gc, bottom_shadow,
- shadow_thickness * 2);
+ ((edges & EDGE_BOTTOM) ? shadow_thickness : 0)
+ + ((edges & EDGE_RIGHT) ? shadow_thickness : 0));
}
/*****************************************************************************
WINDOW_BUFFER (w));
int x = xpos;
- int y = dl->ypos - dl->ascent;
+ int y = DISPLAY_LINE_YPOS (dl);
int width = EOL_CURSOR_WIDTH;
- int height = dl->ascent + dl->descent - dl->clip;
+ int height = DISPLAY_LINE_HEIGHT (dl);
int cursor_height, cursor_y;
int defheight, defascent;
CONSOLE_HAS_METHOD (x, flash);
CONSOLE_HAS_METHOD (x, ring_bell);
CONSOLE_HAS_METHOD (x, bevel_area);
+ CONSOLE_HAS_METHOD (x, output_string);
+ CONSOLE_HAS_METHOD (x, output_pixmap);
}
(those off the left side of the screen) need
to be skipped before anything is displayed. */
Bytind bi_start_col_enabled;
+ int start_col_xoffset; /* Number of pixels that still need to
+ be skipped. This is used for
+ horizontal scrolling of glyphs, where we want
+ to be able to scroll over part of the glyph. */
int hscroll_glyph_width_adjust; /* how much the width of the hscroll
glyph differs from space_width (w).
int pos_type, int allow_cursor,
struct glyph_cachel *cachel);
static Bytind create_text_block (struct window *w, struct display_line *dl,
- Bytind bi_start_pos, int start_col,
- prop_block_dynarr **prop,
+ Bytind bi_start_pos, prop_block_dynarr **prop,
int type);
static int create_overlay_glyph_block (struct window *w,
struct display_line *dl);
static void update_line_start_cache (struct window *w, Bufpos from, Bufpos to,
Bufpos point, int no_regen);
static int point_visible (struct window *w, Bufpos point, int type);
-extern Bytind bi_find_next_emchar_in_string (struct Lisp_String* str, Emchar target,
- Bytind st, EMACS_INT count);
-extern int string_column_at_point (struct Lisp_String* s, Bufpos init_pos, int tab_width);
/* This used to be 10 but 30 seems to give much better performance. */
#define INIT_MAX_PREEMPTS 30
/* Used by generate_formatted_string. Global because they get used so
much that the dynamic allocation time adds up. */
-Emchar_dynarr *formatted_string_emchar_dynarr;
-struct display_line formatted_string_display_line;
+static Emchar_dynarr *formatted_string_emchar_dynarr;
+static struct display_line formatted_string_display_line;
/* We store the extents that we need to generate in a Dynarr and then
frob them all on at the end of generating the string. We do it
this way rather than adding them as we generate the string because
(to avoid having to resize the string multiple times), and we don't
want to go around adding extents to a string when the extents might
stretch off the end of the string. */
-EXTENT_dynarr *formatted_string_extent_dynarr;
-Bytecount_dynarr *formatted_string_extent_start_dynarr;
-Bytecount_dynarr *formatted_string_extent_end_dynarr;
+static EXTENT_dynarr *formatted_string_extent_dynarr;
+static Bytecount_dynarr *formatted_string_extent_start_dynarr;
+static Bytecount_dynarr *formatted_string_extent_end_dynarr;
/* #### probably temporary */
int horizontal_clip;
/* Set if currently inside update_line_start_cache. */
-int updating_line_start_cache;
+static int updating_line_start_cache;
/* Nonzero means reading single-character input with prompt
so put cursor on minibuffer after the prompt. */
int subwindows_changed;
int subwindows_changed_set;
+/* non-zero if any displayed subwindow is in need of updating
+ somewhere. */
+int subwindows_state_changed;
+int subwindows_state_changed_set;
+
/* This variable is 1 if the icon has to be updated.
It is set to 1 when `frame-icon-glyph' changes. */
int icon_changed;
Lisp_Object Voverlay_arrow_string;
Lisp_Object Vwindow_size_change_functions;
-Lisp_Object Qwindow_scroll_functions, Vwindow_scroll_functions;
+Lisp_Object Vwindow_scroll_functions;
Lisp_Object Qredisplay_end_trigger_functions, Vredisplay_end_trigger_functions;
#define INHIBIT_REDISPLAY_HOOKS /* #### Until we've thought about
Lisp_Object Qpre_redisplay_hook, Qpost_redisplay_hook;
#endif /* INHIBIT_REDISPLAY_HOOKS */
-int last_display_warning_tick, display_warning_tick;
+static int last_display_warning_tick, display_warning_tick;
Lisp_Object Qdisplay_warning_buffer;
int inhibit_warning_display;
Lisp_Object Vtext_cursor_visible_p;
int column_number_start_at_one;
+
+#define WINDOW_SCROLLED(w) \
+(w->hscroll > 0 || w->left_xoffset)
+
\f
/***************************************************************************/
/* */
int pix_tab_width = tab_pix_width (w);
/* Adjust n_pos for any hscrolling which has happened. */
- if (w->hscroll > 1)
- n_pos -= space_width (w) * (w->hscroll - 1);
+ if (WINDOW_SCROLLED (w))
+ n_pos -= space_width (w) * (w->hscroll - 1) + w->left_xoffset;
while (n_pos <= start_pixpos)
n_pos += pix_tab_width;
static Bufpos
generate_display_line (struct window *w, struct display_line *dl, int bounds,
- Bufpos start_pos, int start_col,
- prop_block_dynarr **prop,
+ Bufpos start_pos, prop_block_dynarr **prop,
int type)
{
Bufpos ret_bufpos;
/* #### urk urk urk!!! Chuck fix this shit! */
Bytind hacked_up_bytind =
create_text_block (w, dl, bufpos_to_bytind (b, start_pos),
- start_col, prop, type);
+ prop, type);
if (hacked_up_bytind > BI_BUF_ZV (b))
ret_bufpos = BUF_ZV (b) + 1;
else
if (!width)
return NULL;
- if (data->start_col)
+ if (data->start_col || data->start_col_xoffset)
{
prop_block_dynarr *retval;
int glyph_char_width = width / space_width (w);
static Bytind
create_text_block (struct window *w, struct display_line *dl,
- Bytind bi_start_pos, int start_col,
- prop_block_dynarr **prop,
+ Bytind bi_start_pos, prop_block_dynarr **prop,
int type)
{
struct frame *f = XFRAME (w->frame);
data.cursor_x = -1;
data.start_col = w->hscroll;
+ data.start_col_xoffset = w->left_xoffset;
data.bi_start_col_enabled = (w->hscroll ? bi_start_pos : 0);
data.hscroll_glyph_width_adjust = 0;
data.blank_width = DEVMETH (d, eol_cursor_width, ());
data.findex = DEFAULT_INDEX;
data.start_col = 0;
+ data.start_col_xoffset = 0;
data.bi_start_col_enabled = 0;
add_emchar_rune (&data);
int prop_width = 0;
if (data.start_col > 1)
- tab_start_pixpos -= (space_width (w) * (data.start_col - 1));
+ tab_start_pixpos -= (space_width (w) * (data.start_col - 1))
+ + data.start_col_xoffset;
next_tab_start =
next_tab_position (w, tab_start_pixpos,
data.blank_width = DEVMETH (d, eol_cursor_width, ());
data.findex = DEFAULT_INDEX;
data.start_col = 0;
+ data.start_col_xoffset = 0;
data.bi_start_col_enabled = 0;
data.max_pixpos += data.blank_width;
struct frame *f = XFRAME (w->frame);
/* Note that a lot of the buffer controlled stuff has been left in
because you might well want to make use of it (selective display
- etc), its just the buffer text that we do not use. */
- struct buffer *b = XBUFFER (w->buffer);
+ etc), its just the buffer text that we do not use. However, it
+ seems to be possible for buffer to be nil sometimes so protect
+ against this case. */
+ struct buffer *b = BUFFERP (w->buffer) ? XBUFFER (w->buffer) : 0;
struct device *d = XDEVICE (f->device);
struct Lisp_String* s = XSTRING (disp_string);
pos_data data;
- int truncate_win = window_truncation_on (w);
+ int truncate_win = b ? window_truncation_on (w) : 0;
int end_glyph_width = 0;
/* we're going to ditch selective display for static text, its an
Since more than one display table is possible, you have
great flexibility in mapping ranges of characters. */
- Emchar printable_min = (CHAR_OR_CHAR_INTP (b->ctl_arrow)
+ Emchar printable_min = b ? (CHAR_OR_CHAR_INTP (b->ctl_arrow)
? XCHAR_OR_CHAR_INT (b->ctl_arrow)
: ((EQ (b->ctl_arrow, Qt) || EQ (b->ctl_arrow, Qnil))
- ? 255 : 160));
+ ? 255 : 160)) : 255;
Lisp_Object face_dt, window_dt;
}
else if (data.bi_bufpos == bi_string_zv)
{
- /* We need to add a marker to the end of the line since there is no
- newline character in order for the cursor to get drawn. We label
- it as a newline so that it gets handled correctly by the
- whitespace routines below. */
-
- data.ch = '\n';
- data.blank_width = DEVMETH (d, eol_cursor_width, ());
- data.findex = default_face;
- data.start_col = 0;
- data.bi_start_col_enabled = 0;
-
- data.max_pixpos += data.blank_width;
- add_emchar_rune (&data);
- data.max_pixpos -= data.blank_width;
-
- /* #### urk! Chuck, this shit is bad news. Going around
- manipulating invalid positions is guaranteed to result in
- trouble sooner or later. */
- data.bi_bufpos = bi_string_zv + 1;
+ /* create_text_block () adds a bogus \n marker here which screws
+ up subwindow display. Since we never have a cursor in the
+ gutter we can safely ignore it. */
}
-
/* Calculate left whitespace boundary. */
{
int elt = 0;
dl->end_bufpos = buffer_or_string_bytind_to_bufpos (disp_string, data.bi_bufpos) - 1;
if (truncate_win)
data.dl->num_chars =
- string_column_at_point (s, dl->end_bufpos, XINT (b->tab_width));
+ string_column_at_point (s, dl->end_bufpos, b ? XINT (b->tab_width) : 8);
else
/* This doesn't correctly take into account tabs and control
characters but if the window isn't being truncated then this
Bufpos ret_bufpos;
/* you must set bounds before calling this. */
-
+
/* Reset what this line is using. */
if (dl->display_blocks)
Dynarr_reset (dl->display_blocks);
if (NILP (disp_string))
return;
- s_zv = XSTRING_CHAR_LENGTH (disp_string) - 1;
+ s_zv = XSTRING_CHAR_LENGTH (disp_string);
bounds.left_out = xpos;
bounds.right_out = xpos + width;
struct buffer *b = XBUFFER (w->buffer);
int ypos = WINDOW_TEXT_TOP (w);
int yend; /* set farther down */
+ int yclip = WINDOW_TEXT_TOP_CLIP (w);
prop_block_dynarr *prop;
layout_bounds bounds;
dlp->bounds = bounds;
dlp->offset = 0;
- start_pos = generate_display_line (w, dlp, 1, start_pos,
- w->hscroll, &prop, type);
- dlp->ypos = ypos + dlp->ascent;
+ start_pos = generate_display_line (w, dlp, 1, start_pos, &prop, type);
+
+ if (yclip > dlp->ascent)
+ {
+ /* this should never happen, but if it does just display the
+ whole line */
+ yclip = 0;
+ }
+
+ dlp->ypos = (ypos + dlp->ascent) - yclip;
ypos = dlp->ypos + dlp->descent;
+ /* See if we've been asked to start midway through a line, for
+ partial display line scrolling. */
+ if (yclip)
+ {
+ dlp->top_clip = yclip;
+ yclip = 0;
+ }
+ else
+ dlp->top_clip = 0;
+
if (ypos > yend)
{
int visible_height = dlp->ascent + dlp->descent;
dlp->clip = (ypos - yend);
- visible_height -= dlp->clip;
+ /* Although this seems strange we could have a single very
+ tall line visible for which we need to account for both
+ the top clip and the bottom clip. */
+ visible_height -= (dlp->clip + dlp->top_clip);
if (visible_height < VERTICAL_CLIP (w, 1))
{
return 0;
new_start = generate_display_line (w, ddl, 0, ddl->bufpos + ddl->offset,
- w->hscroll, &prop, DESIRED_DISP);
+ &prop, DESIRED_DISP);
ddl->offset = 0;
/* #### If there is propagated stuff the fail. We could
if (cdl->ypos != ddl->ypos
|| cdl->ascent != ddl->ascent
|| cdl->descent != ddl->descent
+ || cdl->top_clip != ddl->top_clip
|| (cdl->cursor_elt != -1 && ddl->cursor_elt == -1)
|| (cdl->cursor_elt == -1 && ddl->cursor_elt != -1)
|| old_start != ddl->bufpos
return 0;
new_start = generate_display_line (w, ddl, 0, ddl->bufpos + ddl->offset,
- w->hscroll, &prop, DESIRED_DISP);
+ &prop, DESIRED_DISP);
ddl->offset = 0;
/* If there is propagated stuff then it is pretty much a
if (cdl->ypos != ddl->ypos
|| cdl->ascent != ddl->ascent
|| cdl->descent != ddl->descent
+ || cdl->top_clip != ddl->top_clip
|| (cdl->cursor_elt != -1 && ddl->cursor_elt == -1)
|| (cdl->cursor_elt == -1 && ddl->cursor_elt != -1))
{
else
mark_face_cachels_as_not_updated (w);
- /* Ditto the glyph cache elements. */
+ /* Ditto the glyph cache elements, although we do *not* invalidate
+ the cache purely because glyphs have changed - this is now
+ handled by the dirty flag.*/
if ((!echo_active && b != window_display_buffer (w))
- || !Dynarr_length (w->glyph_cachels)
- || f->glyphs_changed)
+ || !Dynarr_length (w->glyph_cachels))
reset_glyph_cachels (w);
else
mark_glyph_cachels_as_not_updated (w);
&& !f->faces_changed
&& !f->glyphs_changed
&& !f->subwindows_changed
+ && !f->subwindows_state_changed
&& !f->point_changed
&& !f->windows_structure_changed)
{
&& !f->faces_changed
&& !f->glyphs_changed
&& !f->subwindows_changed
+ && !f->subwindows_state_changed
&& !f->windows_structure_changed)
{
if (point_visible (w, pointm, CURRENT_DISP)
&& !f->faces_changed
&& !f->glyphs_changed
&& !f->subwindows_changed
+ && !f->subwindows_state_changed
&& !f->windows_structure_changed
&& !f->frame_changed
&& !truncation_changed
somewhere else once tty updates occur on a per-frame basis. */
mark_face_cachels_as_clean (w);
+ /* The glyph cachels only get dirty if someone changed something. */
+ if (glyphs_changed)
+ mark_glyph_cachels_as_clean (w);
+
w->windows_changed = 0;
}
being handled. */
update_frame_menubars (f);
#endif /* HAVE_MENUBARS */
- update_frame_gutters (f);
/* widgets are similar to menus in that they can call lisp to
determine activation etc. Therefore update them before we get
into redisplay. This is primarily for connected widgets such as
update_frame_toolbars (f);
#endif /* HAVE_TOOLBARS */
+ /* If we clear the frame we have to force its contents to be redrawn. */
+ if (f->clear)
+ f->frame_changed = 1;
+
+ /* invalidate the subwindow cache. We use subwindows_changed here to
+ cause subwindows to get instantiated. This is because
+ subwindows_state_changed is less strict - dealing with things
+ like the clicked state of button. We have to do this before
+ redisplaying the gutters as subwindows get unmapped in the
+ process.*/
+ if (!Dynarr_length (f->subwindow_cachels)
+ || f->subwindows_changed
+ || f->frame_changed)
+ {
+ reset_subwindow_cachels (f);
+ /* we have to do this so the gutter gets regenerated. */
+ reset_gutter_display_lines (f);
+ }
+ else
+ mark_subwindow_cachels_as_not_updated (f);
+ /* We can now update the gutters, safe in the knowledge that our
+ efforts won't get undone. */
+ update_frame_gutters (f);
+
hold_frame_size_changes ();
/* ----------------- BEGIN CRITICAL REDISPLAY SECTION ---------------- */
#### If a frame-size change does occur we should probably
actually be preempting redisplay. */
- /* If we clear the frame we have to force its contents to be redrawn. */
- if (f->clear)
- f->frame_changed = 1;
-
/* Erase the frame before outputting its contents. */
if (f->clear)
{
DEVMETH (d, clear_frame, (f));
}
- /* invalidate the subwindow cache. we are going to reuse the glyphs
- flag here to cause subwindows to get instantiated. This is
- because subwindows changed is less strict - dealing with things
- like the clicked state of button. */
- if (!Dynarr_length (f->subwindow_cachels)
- || f->glyphs_changed
- || f->frame_changed)
- reset_subwindow_cachels (f);
- else
- mark_subwindow_cachels_as_not_updated (f);
-
/* Do the selected window first. */
redisplay_window (FRAME_SELECTED_WINDOW (f), 0);
update_frame_title (f);
- f->buffers_changed = 0;
- f->clip_changed = 0;
- f->extents_changed = 0;
- f->faces_changed = 0;
- f->frame_changed = 0;
- f->glyphs_changed = 0;
- f->subwindows_changed = 0;
- f->icon_changed = 0;
- f->menubar_changed = 0;
- f->modeline_changed = 0;
- f->point_changed = 0;
- f->toolbar_changed = 0;
- f->gutter_changed = 0;
- f->windows_changed = 0;
- f->windows_structure_changed = 0;
+ CLASS_RESET_CHANGED_FLAGS (f);
f->window_face_cache_reset = 0;
f->echo_area_garbaged = 0;
-
f->clear = 0;
if (!f->size_change_pending)
if (FRAME_REPAINT_P (f))
{
- if (f->buffers_changed || f->clip_changed || f->extents_changed ||
- f->faces_changed || f->frame_changed || f->menubar_changed ||
- f->modeline_changed || f->point_changed || f->size_changed ||
- f->toolbar_changed || f->windows_changed || f->size_slipped ||
- f->windows_structure_changed || f->glyphs_changed ||
- f->subwindows_changed || f->gutter_changed)
+ if (CLASS_REDISPLAY_FLAGS_CHANGEDP(f))
{
preempted = redisplay_frame (f, 0);
}
if (FRAME_REPAINT_P (f))
{
- if (f->buffers_changed || f->clip_changed || f->extents_changed ||
- f->faces_changed || f->frame_changed || f->menubar_changed ||
- f->modeline_changed || f->point_changed || f->size_changed ||
- f->toolbar_changed || f->windows_changed ||
- f->windows_structure_changed || f->gutter_changed ||
- f->glyphs_changed || f->subwindows_changed)
+ if (CLASS_REDISPLAY_FLAGS_CHANGEDP(f)
+ || f->size_changed)
{
preempted = redisplay_frame (f, 0);
}
/* If we get here then we redisplayed all of our frames without
getting preempted so mark ourselves as clean. */
- d->buffers_changed = 0;
- d->clip_changed = 0;
- d->extents_changed = 0;
- d->faces_changed = 0;
- d->frame_changed = 0;
- d->glyphs_changed = 0;
- d->subwindows_changed = 0;
- d->icon_changed = 0;
- d->menubar_changed = 0;
- d->modeline_changed = 0;
- d->point_changed = 0;
- d->toolbar_changed = 0;
- d->gutter_changed = 0;
- d->windows_changed = 0;
- d->windows_structure_changed = 0;
+ CLASS_RESET_CHANGED_FLAGS (d);
if (!size_change_failed)
d->size_changed = 0;
if (asynch_device_change_pending)
handle_asynch_device_change ();
- if (!buffers_changed && !clip_changed && !extents_changed &&
- !faces_changed && !frame_changed && !icon_changed &&
- !menubar_changed && !modeline_changed && !point_changed &&
- !size_changed && !toolbar_changed && !windows_changed &&
- !glyphs_changed && !subwindows_changed &&
- !gutter_changed && !windows_structure_changed &&
- !disable_preemption && preemption_count < max_preempts)
+ if (!GLOBAL_REDISPLAY_FLAGS_CHANGEDP &&
+ !size_changed && !disable_preemption && preemption_count < max_preempts)
goto done;
DEVICE_LOOP_NO_BREAK (devcons, concons)
struct device *d = XDEVICE (XCAR (devcons));
int preempted;
- if (d->buffers_changed || d->clip_changed || d->extents_changed ||
- d->faces_changed || d->frame_changed || d->icon_changed ||
- d->menubar_changed || d->modeline_changed || d->point_changed ||
- d->size_changed || d->toolbar_changed || d->windows_changed ||
- d->windows_structure_changed || d->gutter_changed ||
- d->glyphs_changed || d->subwindows_changed)
+ if (CLASS_REDISPLAY_FLAGS_CHANGEDP (d)
+ || d->size_changed)
{
preempted = redisplay_device (d);
preemption_count = 0;
/* Mark redisplay as accurate */
- buffers_changed = 0;
- clip_changed = 0;
- extents_changed = 0;
- frame_changed = 0;
- glyphs_changed = 0;
- subwindows_changed = 0;
- icon_changed = 0;
- menubar_changed = 0;
- modeline_changed = 0;
- point_changed = 0;
- toolbar_changed = 0;
- gutter_changed = 0;
- windows_changed = 0;
- windows_structure_changed = 0;
+ GLOBAL_RESET_CHANGED_FLAGS;
RESET_CHANGED_SET_FLAGS;
if (faces_changed)
case 'p':
{
Bufpos pos = marker_position (w->start[type]);
- Charcount total = BUF_ZV (b) - BUF_BEGV (b);
/* This had better be while the desired lines are being done. */
if (w->window_end_pos[type] <= BUF_Z (b) - BUF_ZV (b))
/* This hard limit is ok since the string it will hold has a
fixed maximum length of 3. But just to be safe... */
char buf[10];
+ Charcount chars = pos - BUF_BEGV (b);
+ Charcount total = BUF_ZV (b) - BUF_BEGV (b);
- total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
+ /* Avoid overflow on big buffers */
+ int percent = total > LONG_MAX/200 ?
+ (chars + total/200) / (total / 100) :
+ (chars * 100 + total/2) / total;
/* We can't normally display a 3-digit number, so get us a
2-digit number that is close. */
- if (total == 100)
- total = 99;
+ if (percent == 100)
+ percent = 99;
- sprintf (buf, "%2d%%", total);
+ sprintf (buf, "%d%%", percent);
Dynarr_add_many (mode_spec_bufbyte_string, (Bufbyte *) buf,
strlen (buf));
{
Bufpos toppos = marker_position (w->start[type]);
Bufpos botpos = BUF_Z (b) - w->window_end_pos[type];
- Charcount total = BUF_ZV (b) - BUF_BEGV (b);
/* botpos is only accurate as of the last redisplay, so we can
only treat it as a hint. In particular, after erase-buffer,
/* This hard limit is ok since the string it will hold has a
fixed maximum length of around 6. But just to be safe... */
char buf[10];
+ Charcount chars = botpos - BUF_BEGV (b);
+ Charcount total = BUF_ZV (b) - BUF_BEGV (b);
- total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
+ /* Avoid overflow on big buffers */
+ int percent = total > LONG_MAX/200 ?
+ (chars + total/200) / (total / 100) :
+ (chars * 100 + total/2) / max (total, 1);
/* We can't normally display a 3-digit number, so get us a
2-digit number that is close. */
- if (total == 100)
- total = 99;
+ if (percent == 100)
+ percent = 99;
if (toppos <= BUF_BEGV (b))
- sprintf (buf, "Top%2d%%", total);
+ sprintf (buf, "Top%d%%", percent);
else
- sprintf (buf, "%2d%%", total);
+ sprintf (buf, "%d%%", percent);
Dynarr_add_many (mode_spec_bufbyte_string, (Bufbyte *) buf,
strlen (buf));
/* Given an array of display lines, free them and all data structures
contained within them. */
-static void
+void
free_display_lines (display_line_dynarr *dla)
{
int line;
\f
static void
-mark_glyph_block_dynarr (glyph_block_dynarr *gba, void (*markobj) (Lisp_Object))
+mark_glyph_block_dynarr (glyph_block_dynarr *gba)
{
if (gba)
{
for (; gb < gb_last; gb++)
{
if (!NILP (gb->glyph))
- markobj (gb->glyph);
+ mark_object (gb->glyph);
if (!NILP (gb->extent))
- markobj (gb->extent);
+ mark_object (gb->extent);
}
}
}
static void
-mark_redisplay_structs (display_line_dynarr *dla, void (*markobj) (Lisp_Object))
+mark_redisplay_structs (display_line_dynarr *dla)
{
display_line *dl = Dynarr_atp (dla, 0);
display_line *dl_last = Dynarr_atp (dla, Dynarr_length (dla));
if (r->type == RUNE_DGLYPH)
{
if (!NILP (r->object.dglyph.glyph))
- markobj (r->object.dglyph.glyph);
+ mark_object (r->object.dglyph.glyph);
if (!NILP (r->object.dglyph.extent))
- markobj (r->object.dglyph.extent);
+ mark_object (r->object.dglyph.extent);
}
}
}
- mark_glyph_block_dynarr (dl->left_glyphs, markobj);
- mark_glyph_block_dynarr (dl->right_glyphs, markobj);
+ mark_glyph_block_dynarr (dl->left_glyphs);
+ mark_glyph_block_dynarr (dl->right_glyphs);
}
}
static void
-mark_window_mirror (struct window_mirror *mir, void (*markobj)(Lisp_Object))
+mark_window_mirror (struct window_mirror *mir)
{
- mark_redisplay_structs (mir->current_display_lines, markobj);
- mark_redisplay_structs (mir->desired_display_lines, markobj);
+ mark_redisplay_structs (mir->current_display_lines);
+ mark_redisplay_structs (mir->desired_display_lines);
if (mir->next)
- mark_window_mirror (mir->next, markobj);
+ mark_window_mirror (mir->next);
if (mir->hchild)
- mark_window_mirror (mir->hchild, markobj);
+ mark_window_mirror (mir->hchild);
else if (mir->vchild)
- mark_window_mirror (mir->vchild, markobj);
+ mark_window_mirror (mir->vchild);
}
void
-mark_redisplay (void (*markobj)(Lisp_Object))
+mark_redisplay (void)
{
Lisp_Object frmcons, devcons, concons;
{
struct frame *f = XFRAME (XCAR (frmcons));
update_frame_window_mirror (f);
- mark_window_mirror (f->root_mirror, markobj);
+ mark_window_mirror (f->root_mirror);
}
}
\f
/* This will get used quite a bit so we don't want to be constantly
allocating and freeing it. */
-line_start_cache_dynarr *internal_cache;
+static line_start_cache_dynarr *internal_cache;
/* Makes internal_cache represent the TYPE display structs and only
the TYPE display structs. */
}
cur_elt--;
- if (cur_elt < 0)
+ while (cur_elt < 0)
{
Bufpos from, to;
int win_char_height;
update_line_start_cache (w, from, to, point, 0);
cur_elt = point_in_line_start_cache (w, cur_pos, 2) - 1;
- assert (cur_elt >= 0);
+ assert (cur_elt >= -1);
+ /* This used to be cur_elt>=0 under the assumption that if
+ point is in the top line and not at BUF_BEGV, then
+ setting the window_start to a newline before the start of
+ the first line will always cause scrolling.
+
+ However in my (jv) opinion this is wrong. That new line
+ can be hidden in various ways: invisible extents, an
+ explicit window-start not at a newline character etc.
+ The existence of those are indeed known to create crashes
+ on that assert. So we have no option but to continue the
+ search if we found point at the top of the line_start_cache
+ again. */
+ cur_pos = Dynarr_atp (w->line_start_cache,0)->start;
}
prev_pos = cur_pos;
}
return 0;
}
+/* This is called if the built-in glyphs have their properties
+ changed. */
void
redisplay_glyph_changed (Lisp_Object glyph, Lisp_Object property,
Lisp_Object locale)
preemption_count = 0;
max_preempts = INIT_MAX_PREEMPTS;
+#ifndef PDUMP
if (!initialized)
+#endif
{
cmotion_display_lines = Dynarr_new (display_line);
mode_spec_bufbyte_string = Dynarr_new (Bufbyte);
#endif /* INHIBIT_REDISPLAY_HOOKS */
defsymbol (&Qdisplay_warning_buffer, "display-warning-buffer");
defsymbol (&Qbar_cursor, "bar-cursor");
- defsymbol (&Qwindow_scroll_functions, "window-scroll-functions");
defsymbol (&Qredisplay_end_trigger_functions,
"redisplay-end-trigger-functions");
}
void
+reinit_vars_of_redisplay (void)
+{
+ updating_line_start_cache = 0;
+}
+
+void
vars_of_redisplay (void)
{
+ reinit_vars_of_redisplay ();
+
#if 0
staticpro (&last_arrow_position);
staticpro (&last_arrow_string);
last_arrow_string = Qnil;
#endif /* 0 */
- updating_line_start_cache = 0;
-
/* #### Probably temporary */
DEFVAR_INT ("redisplay-cache-adjustment", &cache_adjustment /*
\(Temporary) Setting this will impact the performance of the internal
Vwindow_system = Qnil;
/* #### Temporary shit until window-system is eliminated. */
- DEFVAR_LISP ("initial-window-system", &Vinitial_window_system /*
+ DEFVAR_CONST_LISP ("initial-window-system", &Vinitial_window_system /*
DON'T TOUCH
*/ );
Vinitial_window_system = Qnil;
/* HLINE */
struct
{
- int thickness; /* how thick to make hline */
- int yoffset; /* how far down from top of line to put top */
+ short thickness; /* how thick to make hline */
+ short yoffset; /* how far down from top of line to put top */
} hline;
} object; /* actual rune object */
};
pixel-row itself, I think. */
unsigned short clip; /* amount of bottom of line to clip
in pixels.*/
+ unsigned short top_clip; /* amount of top of line to clip
+ in pixels.*/
Bufpos bufpos; /* first buffer position on line */
Bufpos end_bufpos; /* last buffer position on line */
Charcount offset; /* adjustment to bufpos vals */
};
#define DISPLAY_LINE_HEIGHT(dl) \
-(dl->ascent + dl->descent - dl->clip)
+(dl->ascent + dl->descent - (dl->clip + dl->top_clip))
#define DISPLAY_LINE_YPOS(dl) \
-(dl->ypos - dl->ascent)
+(dl->ypos - (dl->ascent - dl->top_clip))
+#define DISPLAY_LINE_YEND(dl) \
+((dl->ypos + dl->descent) - dl->clip)
typedef struct
{
Dynarr_declare (display_line);
} display_line_dynarr;
+/* The following two structures are used to represent an area to
+displayed and where to display it. Using these two structures all
+combinations of clipping and position can be accommodated. */
+
+/* This represents an area to be displayed into. */
+typedef struct display_box display_box;
+struct display_box
+{
+ int xpos; /* absolute horizontal position of area */
+ int ypos; /* absolute vertical position of area */
+ int width, height;
+};
+
+/* This represents the area from a glyph to be displayed. */
+typedef struct display_glyph_area display_glyph_area;
+struct display_glyph_area
+{
+ int xoffset; /* horizontal offset of the glyph, +ve means
+ display the glyph with x offset by xoffset,
+ -ve means display starting xoffset into the
+ glyph. */
+ int yoffset; /* vertical offset of the glyph, +ve means
+ display the glyph with y offset by yoffset,
+ -ve means display starting xoffset into the
+ glyph. */
+ int width, height; /* width and height of glyph to display. */
+};
+
/* It could be argued that the following two structs belong in
extents.h, but they're only used by redisplay and it simplifies
the header files to put them here. */
unsigned int invisible_ellipses_already_displayed:1;
};
+#define EDGE_TOP 1
+#define EDGE_LEFT 2
+#define EDGE_BOTTOM 4
+#define EDGE_RIGHT 8
+#define EDGE_ALL (EDGE_TOP | EDGE_LEFT | EDGE_BOTTOM | EDGE_RIGHT)
+
\f
/*************************************************************************/
/* change flags */
extern int subwindows_changed;
extern int subwindows_changed_set;
+/* True if any displayed subwindow is in need of updating
+ somewhere. */
+extern int subwindows_state_changed;
+extern int subwindows_state_changed_set;
+
/* True if an icon is in need of updating somewhere. */
extern int icon_changed;
extern int icon_changed_set;
#define MARK_GUTTER_CHANGED MARK_TYPE_CHANGED (gutter)
#define MARK_GLYPHS_CHANGED MARK_TYPE_CHANGED (glyphs)
#define MARK_SUBWINDOWS_CHANGED MARK_TYPE_CHANGED (subwindows)
+#define MARK_SUBWINDOWS_STATE_CHANGED MARK_TYPE_CHANGED (subwindows_state)
+
+
+#define CLASS_RESET_CHANGED_FLAGS(p) do { \
+ (p)->buffers_changed = 0; \
+ (p)->clip_changed = 0; \
+ (p)->extents_changed = 0; \
+ (p)->faces_changed = 0; \
+ (p)->frame_changed = 0; \
+ (p)->icon_changed = 0; \
+ (p)->menubar_changed = 0; \
+ (p)->modeline_changed = 0; \
+ (p)->point_changed = 0; \
+ (p)->toolbar_changed = 0; \
+ (p)->gutter_changed = 0; \
+ (p)->glyphs_changed = 0; \
+ (p)->subwindows_changed = 0; \
+ (p)->subwindows_state_changed = 0; \
+ (p)->windows_changed = 0; \
+ (p)->windows_structure_changed = 0; \
+} while (0)
+
+#define GLOBAL_RESET_CHANGED_FLAGS do { \
+ buffers_changed = 0; \
+ clip_changed = 0; \
+ extents_changed = 0; \
+ faces_changed = 0; \
+ frame_changed = 0; \
+ icon_changed = 0; \
+ menubar_changed = 0; \
+ modeline_changed = 0; \
+ point_changed = 0; \
+ toolbar_changed = 0; \
+ gutter_changed = 0; \
+ glyphs_changed = 0; \
+ subwindows_changed = 0; \
+ subwindows_state_changed = 0; \
+ windows_changed = 0; \
+ windows_structure_changed = 0; \
+} while (0)
+
+#define CLASS_REDISPLAY_FLAGS_CHANGEDP(p) \
+ ( (p)->buffers_changed || \
+ (p)->clip_changed || \
+ (p)->extents_changed || \
+ (p)->faces_changed || \
+ (p)->frame_changed || \
+ (p)->icon_changed || \
+ (p)->menubar_changed || \
+ (p)->modeline_changed || \
+ (p)->point_changed || \
+ (p)->toolbar_changed || \
+ (p)->gutter_changed || \
+ (p)->glyphs_changed || \
+ (p)->subwindows_changed || \
+ (p)->subwindows_state_changed || \
+ (p)->windows_changed || \
+ (p)->windows_structure_changed )
+
+#define GLOBAL_REDISPLAY_FLAGS_CHANGEDP \
+ ( buffers_changed || \
+ clip_changed || \
+ extents_changed || \
+ faces_changed || \
+ frame_changed || \
+ icon_changed || \
+ menubar_changed || \
+ modeline_changed || \
+ point_changed || \
+ toolbar_changed || \
+ gutter_changed || \
+ glyphs_changed || \
+ subwindows_changed || \
+ subwindows_state_changed || \
+ windows_changed || \
+ windows_structure_changed )
+
/* Anytime a console, device or frame is added or deleted we need to reset
these flags. */
-#define RESET_CHANGED_SET_FLAGS \
- do { \
- buffers_changed_set = 0; \
- clip_changed_set = 0; \
- extents_changed_set = 0; \
- icon_changed_set = 0; \
- menubar_changed_set = 0; \
- modeline_changed_set = 0; \
- point_changed_set = 0; \
- toolbar_changed_set = 0; \
- gutter_changed_set = 0; \
- glyphs_changed_set = 0; \
- subwindows_changed_set = 0; \
- } while (0)
+#define RESET_CHANGED_SET_FLAGS do { \
+ buffers_changed_set = 0; \
+ clip_changed_set = 0; \
+ extents_changed_set = 0; \
+ icon_changed_set = 0; \
+ menubar_changed_set = 0; \
+ modeline_changed_set = 0; \
+ point_changed_set = 0; \
+ toolbar_changed_set = 0; \
+ gutter_changed_set = 0; \
+ glyphs_changed_set = 0; \
+ subwindows_changed_set = 0; \
+ subwindows_state_changed_set = 0; \
+} while (0)
\f
/*************************************************************************/
int window_half_pixpos (struct window *w);
void redisplay_echo_area (void);
void free_display_structs (struct window_mirror *mir);
+void free_display_lines (display_line_dynarr *dla);
Bufbyte *generate_formatted_string (struct window *w, Lisp_Object format_str,
Lisp_Object result_str, face_index findex,
int type);
Lisp_Object *obj1, Lisp_Object *obj2);
void glyph_to_pixel_translation (struct window *w, int char_x,
int char_y, int *pix_x, int *pix_y);
-void mark_redisplay (void (*) (Lisp_Object));
+void mark_redisplay (void);
int point_in_line_start_cache (struct window *w, Bufpos point,
int min_past);
int point_would_be_visible (struct window *w, Bufpos startp,
int get_next_display_block (layout_bounds bounds,
display_block_dynarr *dba, int start_pos,
int *next_start);
-void redisplay_output_subwindow (struct window *w, struct display_line *dl,
- Lisp_Object image_instance, int xpos,
- int xoffset, int start_pixpos, int width,
- face_index findex, int cursor_start,
- int cursor_width, int cursor_height);
+void redisplay_output_layout (struct window *w,
+ Lisp_Object image_instance,
+ struct display_box* db, struct display_glyph_area* dga,
+ face_index findex, int cursor_start, int cursor_width,
+ int cursor_height);
+void redisplay_output_subwindow (struct window *w,
+ Lisp_Object image_instance,
+ struct display_box* db, struct display_glyph_area* dga,
+ face_index findex, int cursor_start, int cursor_width,
+ int cursor_height);
void redisplay_unmap_subwindows_maybe (struct frame* f, int x, int y, int width, int height);
+void redisplay_output_pixmap (struct window *w,
+ Lisp_Object image_instance,
+ struct display_box* db, struct display_glyph_area* dga,
+ face_index findex, int cursor_start, int cursor_width,
+ int cursor_height, int offset_bitmap);
+int redisplay_calculate_display_boxes (struct display_line *dl, int xpos,
+ int xoffset, int start_pixpos, int width,
+ struct display_box* dest,
+ struct display_glyph_area* src);
+int redisplay_normalize_glyph_area (struct display_box* dest,
+ struct display_glyph_area* glyphsrc);
void redisplay_clear_to_window_end (struct window *w, int ypos1, int ypos2);
void redisplay_clear_region (Lisp_Object window, face_index findex, int x,
int y, int width, int height);
void redisplay_update_line (struct window *w, int first_line,
int last_line, int update_values);
void redisplay_output_window (struct window *w);
+void bevel_modeline (struct window *w, struct display_line *dl);
int redisplay_move_cursor (struct window *w, Bufpos new_point,
int no_output_end);
void redisplay_redraw_cursor (struct frame *f, int run_begin_end_meths);
#endif
#endif
+#ifndef SPI_GETWHEELSCROLLLINES
+#define SPI_GETWHEELSCROLLLINES 104
+#endif
+#ifndef WHEEL_PAGESCROLL
+#define WHEEL_PAGESCROLL (UINT_MAX)
+#endif
+#ifndef WHEEL_DELTA
+#define WHEEL_DELTA 120
+#endif
+#ifndef WM_MOUSEWHEEL
+#define WM_MOUSEWHEEL 0x20A
+#endif
+
#define PBS_SMOOTH 0x01
#ifdef HAVE_MS_WINDOWS
#define SHGFI_EXETYPE 0x2000
#define NSIG 23
+#ifndef SPI_GETWHEELSCROLLLINES
+#define SPI_GETWHEELSCROLLLINES 104
+#endif
+#ifndef WHEEL_PAGESCROLL
+#define WHEEL_PAGESCROLL (UINT_MAX)
+#endif
+#ifndef WHEEL_DELTA
+#define WHEEL_DELTA 120
+#endif
+#ifndef WM_MOUSEWHEEL
+#define WM_MOUSEWHEEL 0x20A
+#endif
+
/* translate NT world unexec stuff to our a.out definitions */
#define strnicmp strncasecmp
#pragma data_seg("xdata")
#pragma bss_seg("xdata")
#endif
+
+#ifdef HAVE_SCROLLBARS
+/* Ensure the NT 4 mouse definitions in winuser.h are available */
+ #ifndef _WIN32_WINNT
+ #define _WIN32_WINNT 0x0400
+ #endif
+#endif
/* Synched up with: Not in FSF. */
#include <config.h>
+#include <limits.h>
#include "lisp.h"
#include "console-msw.h"
}
}
+static int
+can_scroll(struct scrollbar_instance* scrollbar)
+{
+ return scrollbar != NULL
+ && IsWindowVisible (SCROLLBAR_MSW_HANDLE (scrollbar))
+ && IsWindowEnabled (SCROLLBAR_MSW_HANDLE (scrollbar));
+}
+
+int
+mswindows_handle_mousewheel_event (Lisp_Object frame, int keys, int delta)
+{
+ int hasVertBar, hasHorzBar; /* Indicates prescence of scroll bars */
+ unsigned wheelScrollLines = 0; /* Number of lines per wheel notch */
+
+ /* Find the currently selected window */
+ Lisp_Object win = FRAME_SELECTED_WINDOW (XFRAME (frame));
+ struct window* w = XWINDOW (win);
+ struct window_mirror* mirror = find_window_mirror (w);
+
+ /* Check that there is something to scroll */
+ hasVertBar = can_scroll (mirror->scrollbar_vertical_instance);
+ hasHorzBar = can_scroll (mirror->scrollbar_horizontal_instance);
+ if (!hasVertBar && !hasHorzBar)
+ return FALSE;
+
+ /* No support for panning and zooming, so ignore */
+ if (keys & (MK_SHIFT | MK_CONTROL))
+ return FALSE;
+
+ /* Get the number of lines per wheel delta */
+ SystemParametersInfo (SPI_GETWHEELSCROLLLINES, 0, &wheelScrollLines, 0);
+
+ /* Calculate the amount to scroll */
+ if (wheelScrollLines == WHEEL_PAGESCROLL)
+ {
+ /* Scroll by a page */
+ Lisp_Object function;
+ if (hasVertBar)
+ function = delta > 0 ? Qscrollbar_page_up : Qscrollbar_page_down;
+ else
+ function = delta > 0 ? Qscrollbar_page_left : Qscrollbar_page_right;
+ mswindows_enqueue_misc_user_event (frame, function, Fcons (win, Qnil));
+ }
+ else /* Scroll by a number of lines */
+ {
+ /* Calc the number of lines to scroll */
+ int toScroll = MulDiv (delta, wheelScrollLines, WHEEL_DELTA);
+
+ /* Do the scroll */
+ Lisp_Object function;
+ if (hasVertBar)
+ function = delta > 0 ? Qscrollbar_line_up : Qscrollbar_line_down;
+ else
+ function = delta > 0 ? Qscrollbar_char_left : Qscrollbar_char_right;
+ if (toScroll < 0)
+ toScroll = -toScroll;
+ while (toScroll--)
+ mswindows_enqueue_misc_user_event (frame, function, win);
+ }
+
+ return TRUE;
+}
+
#ifdef MEMORY_USAGE_STATS
static int
*/
void mswindows_handle_scrollbar_event (HWND hwnd, int code, int pos);
+int mswindows_handle_mousewheel_event (Lisp_Object frame, int keys, int delta);
#endif /* HAVE_MS_WINDOWS and HAVE_SCROLLBARS */
#endif /* _XEMACS_SCROLLBAR_MSW_H_ */
#include "lisp.h"
#include "console-x.h"
+#include "EmacsFrame.h"
#include "glyphs-x.h"
#include "gui-x.h"
#include "scrollbar-x.h"
0, (Window) NULL);
}
-/* Called directly from x_any_window_to_frame in frame-x.c */
-EMACS_INT
-x_window_is_scrollbar (struct frame *f, Window win)
-{
- if (!FRAME_X_P (f))
- return 0;
-
- if (f->mirror_dirty)
- update_frame_window_mirror (f);
- return (EMACS_INT) x_scrollbar_loop (X_WINDOW_IS_SCROLLBAR, f->root_window,
- f->root_mirror, 0, win);
-}
-
/* Make sure that all scrollbars on frame are up-to-date. Called
directly from x_set_frame_properties in frame-x.c*/
void
}
void
+reinit_vars_of_scrollbar_x (void)
+{
+ stupid_vertical_scrollbar_drag_hack = 1;
+}
+
+void
vars_of_scrollbar_x (void)
{
+ reinit_vars_of_scrollbar_x ();
+
#if defined (LWLIB_SCROLLBARS_LUCID)
Fprovide (intern ("lucid-scrollbars"));
#elif defined (LWLIB_SCROLLBARS_MOTIF)
#elif defined (LWLIB_SCROLLBARS_ATHENA)
Fprovide (intern ("athena-scrollbars"));
#endif
- stupid_vertical_scrollbar_drag_hack = 1;
}
void x_update_frame_scrollbars (struct frame *f);
void x_set_scrollbar_pointer (struct frame *f, Lisp_Object cursor);
-EMACS_INT x_window_is_scrollbar (struct frame *f, Window win);
#endif /* HAVE_X_WINDOWS and HAVE_SCROLLBARS */
#endif /* _XEMACS_SCROLLBAR_H_ */
};
/* The instances of that struct. */
-struct regexp_cache searchbufs[REGEXP_CACHE_SIZE];
+static struct regexp_cache searchbufs[REGEXP_CACHE_SIZE];
/* The head of the linked list; points to the most recently used buffer. */
-struct regexp_cache *searchbuf_head;
+static struct regexp_cache *searchbuf_head;
/* Every call to re_match, etc., must pass &search_regs as the regs
}
void
-vars_of_search (void)
+reinit_vars_of_search (void)
{
- REGISTER int i;
+ int i;
+
+ last_thing_searched = Qnil;
+ staticpro_nodump (&last_thing_searched);
for (i = 0; i < REGEXP_CACHE_SIZE; ++i)
{
searchbufs[i].buf.buffer = (unsigned char *) xmalloc (100);
searchbufs[i].buf.fastmap = searchbufs[i].fastmap;
searchbufs[i].regexp = Qnil;
- staticpro (&searchbufs[i].regexp);
+ staticpro_nodump (&searchbufs[i].regexp);
searchbufs[i].next = (i == REGEXP_CACHE_SIZE-1 ? 0 : &searchbufs[i+1]);
}
searchbuf_head = &searchbufs[0];
+}
- last_thing_searched = Qnil;
- staticpro (&last_thing_searched);
+void
+vars_of_search (void)
+{
+ reinit_vars_of_search ();
DEFVAR_LISP ("forward-word-regexp", &Vforward_word_regexp /*
*Regular expression to be used in `forward-word'.
cut_buffers_initialized = 1;
}
-#define CHECK_CUTBUFFER(symbol) \
- { CHECK_SYMBOL (symbol); \
- if (!EQ((symbol),QCUT_BUFFER0) && !EQ((symbol),QCUT_BUFFER1) && \
- !EQ((symbol),QCUT_BUFFER2) && !EQ((symbol),QCUT_BUFFER3) && \
- !EQ((symbol),QCUT_BUFFER4) && !EQ((symbol),QCUT_BUFFER5) && \
- !EQ((symbol),QCUT_BUFFER6) && !EQ((symbol),QCUT_BUFFER7)) \
- signal_error (Qerror, list2 (build_string ("Doesn't name a cutbuffer"), \
- (symbol))); \
- }
+#define CHECK_CUTBUFFER(symbol) do { \
+ CHECK_SYMBOL (symbol); \
+ if (! (EQ (symbol, QCUT_BUFFER0) || \
+ EQ (symbol, QCUT_BUFFER1) || \
+ EQ (symbol, QCUT_BUFFER2) || \
+ EQ (symbol, QCUT_BUFFER3) || \
+ EQ (symbol, QCUT_BUFFER4) || \
+ EQ (symbol, QCUT_BUFFER5) || \
+ EQ (symbol, QCUT_BUFFER6) || \
+ EQ (symbol, QCUT_BUFFER7))) \
+ signal_simple_error ("Doesn't name a cutbuffer", symbol); \
+} while (0)
DEFUN ("x-get-cutbuffer-internal", Fx_get_cutbuffer_internal, 1, 1, 0, /*
Return the value of the named CUTBUFFER (typically CUT_BUFFER0).
}
void
-vars_of_xselect (void)
+reinit_vars_of_xselect (void)
{
-#ifdef CUT_BUFFER_SUPPORT
- cut_buffers_initialized = 0;
- Fprovide (intern ("cut-buffer"));
-#endif
-
reading_selection_reply = 0;
reading_which_selection = 0;
selection_reply_timed_out = 0;
for_whom_the_bell_tolls = 0;
prop_location_tick = 0;
+}
+
+void
+vars_of_xselect (void)
+{
+ reinit_vars_of_xselect ();
+
+#ifdef CUT_BUFFER_SUPPORT
+ cut_buffers_initialized = 0;
+ Fprovide (intern ("cut-buffer"));
+#endif
DEFVAR_LISP ("x-sent-selection-hooks", &Vx_sent_selection_hooks /*
A function or functions to be called after we have responded to some
Hacked on quite a bit by various others. */
#include <config.h>
+#include <time.h>
#include "lisp.h"
#include "buffer.h"
#endif
int bell_volume;
+int bell_inhibit_time;
Lisp_Object Vsound_alist;
Lisp_Object Vsynchronous_sounds;
Lisp_Object Vnative_sound_only_on_console;
*/
(arg, sound, device))
{
- struct device *d = decode_device (device);
+ static time_t last_bell_time = (time_t) 0;
+ static struct device *last_bell_device = (struct device*) 0;
+ time_t now;
+ struct device *d = decode_device (device);
XSETDEVICE (device, d);
+ now = time (0);
- /* #### This is utterly disgusting, and is probably a remnant from
- legacy code that used `ding'+`message' to signal error instead
- calling `error'. As a result, there is no way to beep from Lisp
- directly, without also invoking this aspect. Maybe we should
- define a `ring-bell' function that simply beeps on the console,
- which `ding' should invoke? --hniksic */
if (NILP (arg) && !NILP (Vexecuting_macro))
/* Stop executing a keyboard macro. */
error ("Keyboard macro terminated by a command ringing the bell");
+
+ if (d == last_bell_device && now-last_bell_time < bell_inhibit_time)
+ return Qnil;
else if (visible_bell && DEVMETH (d, flash, (d)))
;
else
Fplay_sound (sound, Qnil, device);
-
- return Qnil;
+
+ last_bell_time = now;
+ last_bell_device = d;
+ return Qnil;
}
DEFUN ("wait-for-sounds", Fwait_for_sounds, 0, 1, 0, /*
*How loud to be, from 0 to 100.
*/ );
bell_volume = 50;
+
+ DEFVAR_INT ("bell-inhibit-time", &bell_inhibit_time /*
+*Don't ring the bell on the same device more than once within this many seconds.
+*/ );
+ bell_inhibit_time = 0;
DEFVAR_LISP ("sound-alist", &Vsound_alist /*
An alist associating names with sounds.
load-sound-file.
Caveats:
- - You can only play audio data if running on the console screen of a
- Sun SparcStation, SGI, or HP9000s700.
+ - XEmacs must be built with sound support for your system. Not all
+ systems support sound.
- The pitch, duration, and volume options are available everywhere, but
many X servers ignore the `pitch' option.
Dynarr_declare (specifier_type_entry);
} specifier_type_entry_dynarr;
-specifier_type_entry_dynarr *the_specifier_type_entry_dynarr;
+static specifier_type_entry_dynarr *the_specifier_type_entry_dynarr;
+
+static const struct lrecord_description ste_description_1[] = {
+ { XD_LISP_OBJECT, offsetof(specifier_type_entry, symbol), 1 },
+ { XD_STRUCT_PTR, offsetof(specifier_type_entry, meths), 1, &specifier_methods_description },
+ { XD_END }
+};
+
+static const struct struct_description ste_description = {
+ sizeof(specifier_type_entry),
+ ste_description_1
+};
+
+static const struct lrecord_description sted_description_1[] = {
+ XD_DYNARR_DESC(specifier_type_entry_dynarr, &ste_description),
+ { XD_END }
+};
+
+static const struct struct_description sted_description = {
+ sizeof(specifier_type_entry_dynarr),
+ sted_description_1
+};
static Lisp_Object Vspecifier_type_list;
}
static Lisp_Object
-mark_specifier (Lisp_Object obj, void (*markobj) (Lisp_Object))
+mark_specifier (Lisp_Object obj)
{
struct Lisp_Specifier *specifier = XSPECIFIER (obj);
- markobj (specifier->global_specs);
- markobj (specifier->device_specs);
- markobj (specifier->frame_specs);
- markobj (specifier->window_specs);
- markobj (specifier->buffer_specs);
- markobj (specifier->magic_parent);
- markobj (specifier->fallback);
+ mark_object (specifier->global_specs);
+ mark_object (specifier->device_specs);
+ mark_object (specifier->frame_specs);
+ mark_object (specifier->window_specs);
+ mark_object (specifier->buffer_specs);
+ mark_object (specifier->magic_parent);
+ mark_object (specifier->fallback);
if (!GHOST_SPECIFIER_P (XSPECIFIER (obj)))
- MAYBE_SPECMETH (specifier, mark, (obj, markobj));
+ MAYBE_SPECMETH (specifier, mark, (obj));
return Qnil;
}
*/
void
-prune_specifiers (int (*obj_marked_p) (Lisp_Object))
+prune_specifiers (void)
{
Lisp_Object rest, prev = Qnil;
for (rest = Vall_specifiers;
- !GC_NILP (rest);
+ !NILP (rest);
rest = XSPECIFIER (rest)->next_specifier)
{
- if (! obj_marked_p (rest))
+ if (! marked_p (rest))
{
struct Lisp_Specifier* sp = XSPECIFIER (rest);
/* A bit of assertion that we're removing both parts of the
magic one altogether */
- assert (!GC_MAGIC_SPECIFIER_P(sp)
- || (GC_BODILY_SPECIFIER_P(sp) && obj_marked_p (sp->fallback))
- || (GC_GHOST_SPECIFIER_P(sp) && obj_marked_p (sp->magic_parent)));
+ assert (!MAGIC_SPECIFIER_P(sp)
+ || (BODILY_SPECIFIER_P(sp) && marked_p (sp->fallback))
+ || (GHOST_SPECIFIER_P(sp) && marked_p (sp->magic_parent)));
/* This specifier is garbage. Remove it from the list. */
- if (GC_NILP (prev))
+ if (NILP (prev))
Vall_specifiers = sp->next_specifier;
else
XSPECIFIER (prev)->next_specifier = sp->next_specifier;
{
struct Lisp_Specifier *sp = (struct Lisp_Specifier *) header;
/* don't be snafued by the disksave finalization. */
- if (!for_disksave && !GC_GHOST_SPECIFIER_P(sp) && sp->caching)
+ if (!for_disksave && !GHOST_SPECIFIER_P(sp) && sp->caching)
{
xfree (sp->caching);
sp->caching = 0;
sizeof_specifier (CONST void *header)
{
if (GHOST_SPECIFIER_P ((struct Lisp_Specifier *) header))
- return sizeof (struct Lisp_Specifier);
+ return offsetof (struct Lisp_Specifier, data);
else
{
CONST struct Lisp_Specifier *p = (CONST struct Lisp_Specifier *) header;
- return sizeof (*p) + p->methods->extra_data_size - 1;
+ return offsetof (struct Lisp_Specifier, data) + p->methods->extra_data_size;
}
}
+static const struct lrecord_description specifier_methods_description_1[] = {
+ { XD_LISP_OBJECT, offsetof(struct specifier_methods, predicate_symbol), 1 },
+ { XD_END }
+};
+
+const struct struct_description specifier_methods_description = {
+ sizeof(struct specifier_methods),
+ specifier_methods_description_1
+};
+
+static const struct lrecord_description specifier_caching_description_1[] = {
+ { XD_END }
+};
+
+static const struct struct_description specifier_caching_description = {
+ sizeof(struct specifier_caching),
+ specifier_caching_description_1
+};
+
+static const struct lrecord_description specifier_description[] = {
+ { XD_STRUCT_PTR, offsetof(struct Lisp_Specifier, methods), 1, &specifier_methods_description },
+ { XD_LO_LINK, offsetof(struct Lisp_Specifier, next_specifier) },
+ { XD_LISP_OBJECT, offsetof(struct Lisp_Specifier, global_specs), 5 },
+ { XD_STRUCT_PTR, offsetof(struct Lisp_Specifier, caching), 1, &specifier_caching_description },
+ { XD_LISP_OBJECT, offsetof(struct Lisp_Specifier, magic_parent), 2 },
+ { XD_SPECIFIER_END }
+};
+
+const struct lrecord_description specifier_empty_extra_description[] = {
+ { XD_END }
+};
+
DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION ("specifier", specifier,
mark_specifier, print_specifier,
finalize_specifier,
- specifier_equal, specifier_hash, 0,
+ specifier_equal, specifier_hash,
+ specifier_description,
sizeof_specifier,
struct Lisp_Specifier);
\f
{
Lisp_Object specifier;
struct Lisp_Specifier *sp = (struct Lisp_Specifier *)
- alloc_lcrecord (sizeof (struct Lisp_Specifier) +
- data_size - 1, &lrecord_specifier);
+ alloc_lcrecord (offsetof (struct Lisp_Specifier, data) +
+ data_size, &lrecord_specifier);
sp->methods = spec_meths;
sp->global_specs = Qnil;
specifier_type_create (void)
{
the_specifier_type_entry_dynarr = Dynarr_new (specifier_type_entry);
+ dumpstruct (&the_specifier_type_entry_dynarr, &sted_description);
Vspecifier_type_list = Qnil;
staticpro (&Vspecifier_type_list);
}
void
+reinit_specifier_type_create (void)
+{
+ REINITIALIZE_SPECIFIER_TYPE (generic);
+ REINITIALIZE_SPECIFIER_TYPE (integer);
+ REINITIALIZE_SPECIFIER_TYPE (natnum);
+ REINITIALIZE_SPECIFIER_TYPE (boolean);
+ REINITIALIZE_SPECIFIER_TYPE (display_table);
+}
+
+void
vars_of_specifier (void)
{
Vcached_specifiers = Qnil;
/* Do NOT mark through this, or specifiers will never be GC'd.
This is the same deal as for weak hash tables. */
Vall_specifiers = Qnil;
+ pdump_wire_list (&Vall_specifiers);
Vuser_defined_tags = Qnil;
staticpro (&Vuser_defined_tags);
same time.
*/
+extern const struct struct_description specifier_methods_description;
+
struct specifier_methods
{
CONST char *name;
/* Mark method: Mark any lisp object within specifier data
structure. Not required if no specifier data are Lisp_Objects. */
- void (*mark_method) (Lisp_Object specifier, void (*markobj) (Lisp_Object));
+ void (*mark_method) (Lisp_Object specifier);
/* Equal method: Compare two specifiers. This is called after
ensuring that the two specifiers are of the same type, and have
void (*after_change_method) (Lisp_Object specifier,
Lisp_Object locale);
+ const struct lrecord_description *extra_description;
int extra_data_size;
};
#define XSPECIFIER(x) XRECORD (x, specifier, struct Lisp_Specifier)
#define XSETSPECIFIER(x, p) XSETRECORD (x, p, specifier)
#define SPECIFIERP(x) RECORDP (x, specifier)
-#define GC_SPECIFIERP(x) GC_RECORDP (x, specifier)
#define CHECK_SPECIFIER(x) CHECK_RECORD (x, specifier)
#define CONCHECK_SPECIFIER(x) CONCHECK_RECORD (x, specifier)
/***** Defining new specifier types *****/
+#define specifier_data_offset (offsetof(struct Lisp_Specifier, data))
+extern const struct lrecord_description specifier_empty_extra_description[];
+
#ifdef ERROR_CHECK_TYPECHECK
#define DECLARE_SPECIFIER_TYPE(type) \
extern struct specifier_methods * type##_specifier_methods; \
struct specifier_methods * type##_specifier_methods
#define INITIALIZE_SPECIFIER_TYPE(type, obj_name, pred_sym) do { \
- type##_specifier_methods = xnew_and_zero (struct specifier_methods); \
- type##_specifier_methods->name = obj_name; \
- defsymbol (&type##_specifier_methods->predicate_symbol, pred_sym); \
- add_entry_to_specifier_type_list (Q##type, type##_specifier_methods); \
+ type##_specifier_methods = xnew_and_zero (struct specifier_methods); \
+ type##_specifier_methods->name = obj_name; \
+ type##_specifier_methods->extra_description = \
+ specifier_empty_extra_description; \
+ defsymbol_nodump (&type##_specifier_methods->predicate_symbol, pred_sym); \
+ add_entry_to_specifier_type_list (Q##type, type##_specifier_methods); \
+ dumpstruct (&type##_specifier_methods, &specifier_methods_description); \
+} while (0)
+
+#define REINITIALIZE_SPECIFIER_TYPE(type) do { \
+ staticpro_nodump (&type##_specifier_methods->predicate_symbol); \
} while (0)
#define INITIALIZE_SPECIFIER_TYPE_WITH_DATA(type, obj_name, pred_sym) \
INITIALIZE_SPECIFIER_TYPE (type, obj_name, pred_sym); \
type##_specifier_methods->extra_data_size = \
sizeof (struct type##_specifier); \
+ type##_specifier_methods->extra_description = \
+ type##_specifier_description; \
} while (0)
/* Declare that specifier-type TYPE has method METH; used in
((sp)->methods == type##_specifier_methods)
/* Any of the two of the magic spec */
-#define MAGIC_SPECIFIER_P(sp) \
- (!NILP((sp)->magic_parent))
+#define MAGIC_SPECIFIER_P(sp) (!NILP((sp)->magic_parent))
/* Normal part of the magic specifier */
-#define BODILY_SPECIFIER_P(sp) \
- (EQ ((sp)->magic_parent, Qt))
+#define BODILY_SPECIFIER_P(sp) EQ ((sp)->magic_parent, Qt)
/* Ghost part of the magic specifier */
-#define GHOST_SPECIFIER_P(sp) \
- (SPECIFIERP((sp)->magic_parent))
-/* The same three, when used in GC */
-#define GC_MAGIC_SPECIFIER_P(sp) \
- (!GC_NILP((sp)->magic_parent))
-#define GC_BODILY_SPECIFIER_P(sp) \
- (GC_EQ ((sp)->magic_parent, Qt))
-#define GC_GHOST_SPECIFIER_P(sp) \
- (GC_SPECIFIERP((sp)->magic_parent))
-
-#define GHOST_SPECIFIER(sp) \
- (XSPECIFIER ((sp)->fallback))
+#define GHOST_SPECIFIER_P(sp) SPECIFIERP((sp)->magic_parent)
+
+#define GHOST_SPECIFIER(sp) XSPECIFIER ((sp)->fallback)
#ifdef ERROR_CHECK_TYPECHECK
# define SPECIFIER_TYPE_DATA(sp, type) \
int unlock_ghost_specifiers_protected (void);
void cleanup_specifiers (void);
-void prune_specifiers (int (*obj_marked_p) (Lisp_Object));
+void prune_specifiers (void);
void setup_device_initial_specifier_tags (struct device *d);
void kill_specifier_buffer_locals (Lisp_Object buffer);
Lisp_Object Qget_value, Qset_value, Qbound_predicate, Qmake_unbound;
Lisp_Object Qlocal_predicate, Qmake_local;
-Lisp_Object Qboundp, Qfboundp, Qglobally_boundp, Qmakunbound;
+Lisp_Object Qboundp, Qglobally_boundp, Qmakunbound;
Lisp_Object Qsymbol_value, Qset, Qdefault_boundp, Qdefault_value;
Lisp_Object Qset_default, Qsetq_default;
Lisp_Object Qmake_variable_buffer_local, Qmake_local_variable;
\f
static Lisp_Object
-mark_symbol (Lisp_Object obj, void (*markobj) (Lisp_Object))
+mark_symbol (Lisp_Object obj)
{
struct Lisp_Symbol *sym = XSYMBOL (obj);
Lisp_Object pname;
- markobj (sym->value);
- markobj (sym->function);
+ mark_object (sym->value);
+ mark_object (sym->function);
XSETSTRING (pname, sym->name);
- markobj (pname);
+ mark_object (pname);
if (!symbol_next (sym))
return sym->plist;
else
{
- markobj (sym->plist);
+ mark_object (sym->plist);
/* Mark the rest of the symbols in the obarray hash-chain */
sym = symbol_next (sym);
XSETSYMBOL (obj, sym);
}
static const struct lrecord_description symbol_description[] = {
- { XD_LISP_OBJECT, offsetof(struct Lisp_Symbol, next), 5 }
+ { XD_LISP_OBJECT, offsetof(struct Lisp_Symbol, next), 5 },
+ { XD_END }
};
DEFINE_BASIC_LRECORD_IMPLEMENTATION ("symbol", symbol,
symbol to operate on. */
static Lisp_Object
-mark_symbol_value_buffer_local (Lisp_Object obj,
- void (*markobj) (Lisp_Object))
+mark_symbol_value_buffer_local (Lisp_Object obj)
{
struct symbol_value_buffer_local *bfwd;
#endif
bfwd = XSYMBOL_VALUE_BUFFER_LOCAL (obj);
- markobj (bfwd->default_value);
- markobj (bfwd->current_value);
- markobj (bfwd->current_buffer);
+ mark_object (bfwd->default_value);
+ mark_object (bfwd->current_value);
+ mark_object (bfwd->current_buffer);
return bfwd->current_alist_element;
}
static Lisp_Object
-mark_symbol_value_lisp_magic (Lisp_Object obj,
- void (*markobj) (Lisp_Object))
+mark_symbol_value_lisp_magic (Lisp_Object obj)
{
struct symbol_value_lisp_magic *bfwd;
int i;
bfwd = XSYMBOL_VALUE_LISP_MAGIC (obj);
for (i = 0; i < MAGIC_HANDLER_MAX; i++)
{
- markobj (bfwd->handler[i]);
- markobj (bfwd->harg[i]);
+ mark_object (bfwd->handler[i]);
+ mark_object (bfwd->harg[i]);
}
return bfwd->shadowed;
}
static Lisp_Object
-mark_symbol_value_varalias (Lisp_Object obj,
- void (*markobj) (Lisp_Object))
+mark_symbol_value_varalias (Lisp_Object obj)
{
struct symbol_value_varalias *bfwd;
assert (XSYMBOL_VALUE_MAGIC_TYPE (obj) == SYMVAL_VARALIAS);
bfwd = XSYMBOL_VALUE_VARALIAS (obj);
- markobj (bfwd->shadowed);
+ mark_object (bfwd->shadowed);
return bfwd->aliasee;
}
write_c_string (buf, printcharfun);
}
+static const struct lrecord_description symbol_value_forward_description[] = {
+ { XD_END }
+};
+
static const struct lrecord_description symbol_value_buffer_local_description[] = {
- { XD_LISP_OBJECT, offsetof(struct symbol_value_buffer_local, default_value), 4 },
+ { XD_LISP_OBJECT, offsetof(struct symbol_value_buffer_local, default_value), 1 },
+ { XD_LO_RESET_NIL, offsetof(struct symbol_value_buffer_local, current_value), 3 },
{ XD_END }
};
DEFINE_LRECORD_IMPLEMENTATION ("symbol-value-forward",
symbol_value_forward,
this_one_is_unmarkable,
- print_symbol_value_magic, 0, 0, 0, 0,
+ print_symbol_value_magic, 0, 0, 0,
+ symbol_value_forward_description,
struct symbol_value_forward);
DEFINE_LRECORD_IMPLEMENTATION ("symbol-value-buffer-local",
if (magicfun)
magicfun (sym, &newval, Qnil, 0);
*((int *) symbol_value_forward_forward (fwd))
- = ((NILP (newval)) ? 0 : 1);
+ = !NILP (newval);
return;
case SYMVAL_OBJECT_FORWARD:
/* This can also get called while we're preparing to shutdown.
#### What should really happen in that case? Should we
actually fix things so we can't get here in that case? */
+#ifndef PDUMP
assert (!initialized || preparing_for_armageddon);
+#endif
con = 0;
}
/* This can also get called while we're preparing to shutdown.
#### What should really happen in that case? Should we
actually fix things so we can't get here in that case? */
+#ifndef PDUMP
assert (!initialized || preparing_for_armageddon);
+#endif
con = 0;
}
defsymbol (&Qt, "t");
XSYMBOL (Qt)->value = Qt; /* Veritas aetera */
Vquit_flag = Qnil;
+
+ pdump_wire (&Qnil);
+ pdump_wire (&Qunbound);
+ pdump_wire (&Vquit_flag);
+}
+
+void
+defsymbol_nodump (Lisp_Object *location, CONST char *name)
+{
+ *location = Fintern (make_string_nocopy ((CONST Bufbyte *) name,
+ strlen (name)),
+ Qnil);
+ staticpro_nodump (location);
}
void
assert (SYMBOLP (inherits_from));
conds = Fget (inherits_from, Qerror_conditions, Qnil);
- pure_put (*symbol, Qerror_conditions, Fcons (*symbol, conds));
+ Fput (*symbol, Qerror_conditions, Fcons (*symbol, conds));
/* NOT build_translated_string (). This function is called at load time
and the string needs to get translated at run time. (This happens
in the function (display-error) in cmdloop.el.) */
- pure_put (*symbol, Qerror_message, build_string (messuhhj));
+ Fput (*symbol, Qerror_message, build_string (messuhhj));
}
void
defsymbol (&Qmake_local, "make-local");
defsymbol (&Qboundp, "boundp");
- defsymbol (&Qfboundp, "fboundp");
defsymbol (&Qglobally_boundp, "globally-boundp");
defsymbol (&Qmakunbound, "makunbound");
defsymbol (&Qsymbol_value, "symbol-value");
#define DEFSUBR_MACRO(Fname) defsubr_macro (&S##Fname)
void defsymbol (Lisp_Object *location, CONST char *name);
+void defsymbol_nodump (Lisp_Object *location, CONST char *name);
void defkeyword (Lisp_Object *location, CONST char *name);
void init_ralloc (void);
void init_signals_very_early (void);
-/* Early Lisp-engine initialization (dump-time only). */
+/* Early Lisp-engine initialization (dump-time for init, run-time for reinit). */
void init_alloc_once_early (void);
+void reinit_alloc_once_early (void);
void init_symbols_once_early (void);
void init_errors_once_early (void);
+void reinit_opaque_once_early (void);
void init_opaque_once_early (void);
/* Declare the built-in symbols and primitives (dump-time only). */
void syms_of_xselect (void);
void syms_of_eldap (void);
-/* Initialize the console types (dump-time only). */
+/* Initialize the console types (dump-time but for reinit_). */
void console_type_create (void);
void console_type_create_stream (void);
+void reinit_console_type_create_stream (void);
void console_type_create_tty (void);
+void reinit_console_type_create_tty (void);
void console_type_create_device_tty (void);
void console_type_create_frame_tty (void);
void console_type_create_objects_tty (void);
void console_type_create_redisplay_tty (void);
void console_type_create_x (void);
+void reinit_console_type_create_x (void);
void console_type_create_device_x (void);
+void reinit_console_type_create_device_x (void);
void console_type_create_frame_x (void);
void console_type_create_glyphs_x (void);
void console_type_create_menubar_x (void);
void console_type_create_toolbar_x (void);
void console_type_create_dialog_x (void);
void console_type_create_mswindows (void);
+void reinit_console_type_create_mswindows (void);
void console_type_create_device_mswindows (void);
void console_type_create_frame_mswindows (void);
void console_type_create_menubar_mswindows (void);
/* Initialize the specifier types (dump-time only). */
void specifier_type_create (void);
+void reinit_specifier_type_create (void);
void specifier_type_create_image (void);
+void reinit_specifier_type_create_image (void);
void specifier_type_create_gutter (void);
+void reinit_specifier_type_create_gutter (void);
void specifier_type_create_objects (void);
+void reinit_specifier_type_create_objects (void);
void specifier_type_create_toolbar (void);
+void reinit_specifier_type_create_toolbar (void);
/* Initialize the structure types (dump-time only). */
void init_provide_once (void);
-/* Initialize most variables (dump-time only). */
+/* Initialize most variables (dump-time for vars_, run-time for reinit_vars). */
void vars_of_abbrev (void);
void vars_of_alloc (void);
void vars_of_balloon_x (void);
void vars_of_buffer (void);
+void reinit_vars_of_buffer (void);
void vars_of_bytecode (void);
void vars_of_callint (void);
void vars_of_callproc (void);
void vars_of_cmdloop (void);
void vars_of_cmds (void);
void vars_of_console (void);
+void reinit_vars_of_console (void);
void vars_of_console_stream (void);
void vars_of_console_mswindows (void);
void vars_of_console_tty (void);
void vars_of_data (void);
void vars_of_database (void);
void vars_of_debug (void);
+void reinit_vars_of_debug (void);
void vars_of_device (void);
+void reinit_vars_of_device (void);
void vars_of_device_mswindows (void);
void vars_of_device_x (void);
+void reinit_vars_of_device_x (void);
void vars_of_dialog (void);
void vars_of_dialog_x (void);
void vars_of_dialog_mswindows (void);
void vars_of_elhash (void);
void vars_of_emacs (void);
void vars_of_eval (void);
+void reinit_vars_of_eval (void);
void vars_of_event_stream (void);
+void reinit_vars_of_event_stream (void);
void vars_of_event_tty (void);
+void reinit_vars_of_event_tty (void);
void vars_of_event_mswindows (void);
+void reinit_vars_of_event_mswindows (void);
void vars_of_event_Xt (void);
+void reinit_vars_of_event_Xt (void);
void vars_of_events (void);
+void reinit_vars_of_events (void);
void vars_of_extents (void);
+void reinit_vars_of_extents (void);
void vars_of_faces (void);
void vars_of_fileio (void);
void vars_of_filelock (void);
void vars_of_floatfns (void);
void vars_of_font_lock (void);
+void reinit_vars_of_font_lock (void);
void vars_of_frame_tty (void);
void vars_of_frame_mswindows (void);
void vars_of_frame_x (void);
void vars_of_glyphs_x (void);
void vars_of_glyphs_eimage (void);
void vars_of_glyphs_widget (void);
+void reinit_vars_of_glyphs_widget (void);
void vars_of_glyphs_mswindows (void);
void vars_of_glyphs (void);
+void reinit_vars_of_glyphs (void);
void vars_of_gui_x (void);
+void reinit_vars_of_gui_x (void);
void vars_of_gui (void);
void vars_of_gutter (void);
void vars_of_input_method_motif (void);
void vars_of_input_method_xlib (void);
void vars_of_indent (void);
void vars_of_insdel (void);
+void reinit_vars_of_insdel (void);
void vars_of_intl (void);
void vars_of_keymap (void);
void vars_of_lread (void);
+void reinit_vars_of_lread (void);
void vars_of_lstream (void);
+void reinit_vars_of_lstream (void);
void vars_of_macros (void);
void vars_of_md5 (void);
void vars_of_menubar_x (void);
+void reinit_vars_of_menubar_x (void);
void vars_of_menubar (void);
void vars_of_menubar_mswindows (void);
void vars_of_minibuf (void);
+void reinit_vars_of_minibuf (void);
void vars_of_module (void);
+void reinit_vars_of_module (void);
void vars_of_mule (void);
void vars_of_mule_canna (void);
void vars_of_mule_ccl(void);
void vars_of_mule_wnn (void);
void vars_of_ntproc (void);
void vars_of_objects (void);
+void reinit_vars_of_objects (void);
void vars_of_objects_tty (void);
void vars_of_objects_mswindows (void);
void vars_of_objects_x (void);
void vars_of_print (void);
+void reinit_vars_of_print (void);
void vars_of_process (void);
void vars_of_process_nt (void);
void vars_of_process_unix (void);
void vars_of_profile (void);
void vars_of_ralloc (void);
void vars_of_redisplay (void);
+void reinit_vars_of_redisplay (void);
void vars_of_scrollbar_x (void);
+void reinit_vars_of_scrollbar_x (void);
void vars_of_scrollbar (void);
void vars_of_scrollbar_mswindows (void);
void vars_of_search (void);
+void reinit_vars_of_search (void);
void vars_of_select (void);
void vars_of_select_mswindows (void);
void vars_of_sound (void);
void vars_of_toolbar (void);
void vars_of_tooltalk (void);
void vars_of_undo (void);
+void reinit_vars_of_undo (void);
void vars_of_window (void);
+void reinit_vars_of_window (void);
void vars_of_xselect (void);
+void reinit_vars_of_xselect (void);
void vars_of_eldap (void);
/* Initialize specifier variables (dump-time only). */
void specifier_vars_of_window (void);
/* Initialize variables with complex dependencies
- on other variables (dump-time only). */
+ on other variables (dump-time for complex_vars_, run-time for reinit_). */
void complex_vars_of_regex (void);
void complex_vars_of_search (void);
void complex_vars_of_syntax (void);
void complex_vars_of_chartab (void);
void complex_vars_of_buffer (void);
+void reinit_complex_vars_of_buffer (void);
void complex_vars_of_console (void);
+void reinit_complex_vars_of_console (void);
void complex_vars_of_emacs (void);
void complex_vars_of_minibuf (void);
+void reinit_complex_vars_of_minibuf (void);
void complex_vars_of_callproc (void);
-void complex_vars_of_filelock (void);
void complex_vars_of_keymap (void);
/* Reset the Lisp engine (run-time only). */
}
\f
+
#ifdef MULE
/* Return 1 if there is a word boundary between two word-constituent
characters C1 and C2 if they appear in this order, else return 0.
&& word_boundary_p (c1, c2))
extern int word_boundary_p (Emchar c1, Emchar c2);
-#else
-static int
-word_constituent_p (struct buffer *buf, Bufpos pos,
- struct Lisp_Char_Table *tab)
-{
- enum syntaxcode code = SYNTAX_UNSAFE (tab, BUF_FETCH_CHAR (buf, pos));
- return ((words_include_escapes &&
- (code == Sescape || code == Scharquote))
- || (code == Sword));
-}
#endif
/* Return the position across COUNT words from FROM.
{
Bufpos limit = count > 0 ? BUF_ZV (buf) : BUF_BEGV (buf);
struct Lisp_Char_Table *mirrortab = XCHAR_TABLE (buf->mirror_syntax_table);
-#ifdef MULE
Emchar ch0, ch1;
enum syntaxcode code;
-#endif
+ /* #### is it really worth it to hand expand both cases? JV */
while (count > 0)
{
QUIT;
{
if (from == limit)
return 0;
-#ifdef MULE
+
ch0 = BUF_FETCH_CHAR (buf, from);
code = SYNTAX_UNSAFE (mirrortab, ch0);
-#else
- if (word_constituent_p (buf, from, mirrortab))
- break;
-#endif
- from++;
-#ifdef MULE
+
if (words_include_escapes
&& (code == Sescape || code == Scharquote))
break;
if (code == Sword)
break;
-#endif
+
+ from++;
}
QUIT;
- while ((from != limit)
-#ifndef MULE
- && word_constituent_p (buf, from, mirrortab)
-#endif
- )
+ while (from != limit)
{
-#ifdef MULE
ch1 = BUF_FETCH_CHAR (buf, from);
code = SYNTAX_UNSAFE (mirrortab, ch1);
if (!(words_include_escapes
&& (code == Sescape || code == Scharquote)))
- if (code != Sword || WORD_BOUNDARY_P (ch0, ch1))
+ if (code != Sword
+#ifdef MULE
+ || WORD_BOUNDARY_P (ch0, ch1)
+#endif
+ )
break;
+#ifdef MULE
ch0 = ch1;
-#endif
+#endif
from++;
}
count--;
{
if (from == limit)
return 0;
-#ifndef MULE
- if (word_constituent_p (buf, from - 1, mirrortab))
- break;
-#endif
- from--;
-#ifdef MULE
+
ch1 = BUF_FETCH_CHAR (buf, from - 1);
code = SYNTAX_UNSAFE (mirrortab, ch1);
if (words_include_escapes
break;
if (code == Sword)
break;
-#endif
+
+ from--;
}
QUIT;
- while ((from != limit)
-#ifndef MULE
- && word_constituent_p (buf, from - 1, mirrortab)
-#endif
- )
+ while (from != limit)
{
-#ifdef MULE
ch0 = BUF_FETCH_CHAR (buf, from - 1);
code = SYNTAX_UNSAFE (mirrortab, ch0);
if (!(words_include_escapes
&& (code == Sescape || code == Scharquote)))
- if (code != Sword || WORD_BOUNDARY_P (ch0, ch1))
+ if (code != Sword
+#ifdef MULE
+ || WORD_BOUNDARY_P (ch0, ch1)
+#endif
+ )
break;
+#ifdef MULE
ch1 = ch0;
#endif
from--;
extern CONST unsigned char syntax_code_spec[];
-Lisp_Object scan_lists (struct buffer *buf, int from, int count,
+Lisp_Object scan_lists (struct buffer *buf, Bufpos from, int count,
int depth, int sexpflag, int no_error);
-int char_quoted (struct buffer *buf, int pos);
+int char_quoted (struct buffer *buf, Bufpos pos);
/* NOTE: This does not refer to the mirror table, but to the
syntax table itself. */
#define EMACS_KILLPG(gid, signo) killpg (gid, signo)
#else
#ifdef WINDOWSNT
-#define EMACS_KILLPG(gid, signo) (kill (gid, signo))
+#define EMACS_KILLPG(gid, signo) kill (gid, signo)
#else
#define EMACS_KILLPG(gid, signo) kill (-(gid), signo)
#endif
temp = (char *) tparm (string, arg1, arg2, arg3, arg4, arg5, arg6, arg7,
arg8, arg9);
if (outstring == 0)
- outstring = ((char *) (xmalloc ((strlen (temp)) + 1)));
+ outstring = (char *) xmalloc (strlen (temp) + 1);
strcpy (outstring, temp);
return outstring;
}
#define MSWINDOWS_BLANK_SIZE 5
#define MSWINDOWS_MINIMUM_TOOLBAR_SIZE 8
+static void
+mswindows_move_toolbar (struct frame *f, enum toolbar_pos pos);
+
#define SET_TOOLBAR_WAS_VISIBLE_FLAG(frame, pos, flag) \
do { \
switch (pos) \
/* now display the window */
ShowWindow (toolbarwnd, SW_SHOW);
+ /* no idea why this is necessary but initial display will not
+ happen otherwise. */
+ mswindows_move_toolbar (f, pos);
if (button_tbl) xfree (button_tbl);
}
static void
+mswindows_redraw_frame_toolbars (struct frame *f)
+{
+ mswindows_redraw_exposed_toolbars (f, 0, 0, FRAME_PIXWIDTH (f),
+ FRAME_PIXHEIGHT (f));
+}
+
+static void
mswindows_initialize_frame_toolbars (struct frame *f)
{
CONSOLE_HAS_METHOD (mswindows, initialize_frame_toolbars);
CONSOLE_HAS_METHOD (mswindows, free_frame_toolbars);
CONSOLE_HAS_METHOD (mswindows, redraw_exposed_toolbars);
+ CONSOLE_HAS_METHOD (mswindows, redraw_frame_toolbars);
}
/* Draw the outline. */
x_output_shadows (f, sx, sy, swidth, sheight, top_shadow_gc,
- bottom_shadow_gc, background_gc, shadow_thickness);
+ bottom_shadow_gc, background_gc, shadow_thickness,
+ EDGE_ALL);
/* Blank the middle. */
XFillRectangle (dpy, x_win, background_gc, sx + shadow_thickness,
x_output_shadows (f, tb->x + x_adj, tb->y + y_adj,
tb->width + width_adj, tb->height + height_adj,
top_shadow_gc,
- bottom_shadow_gc, background_gc, shadow_thickness);
+ bottom_shadow_gc, background_gc, shadow_thickness,
+ EDGE_ALL);
/* Clear the pixmap area. */
XFillRectangle (dpy, x_win, background_gc, tb->x + x_adj + shadow_thickness,
}
x_output_x_pixmap (f, XIMAGE_INSTANCE (instance), tb->x + x_offset,
- tb->y + y_offset, 0, 0, 0, 0, width, height,
- 0, 0, 0, background_gc);
+ tb->y + y_offset, 0, 0, width, height,
+ 0, 0, background_gc);
}
else if (IMAGE_INSTANCE_TYPE (p) == IMAGE_TEXT)
{
\f
static Lisp_Object
-mark_toolbar_button (Lisp_Object obj, void (*markobj) (Lisp_Object))
+mark_toolbar_button (Lisp_Object obj)
{
struct toolbar_button *data = XTOOLBAR_BUTTON (obj);
- markobj (data->next);
- markobj (data->frame);
- markobj (data->up_glyph);
- markobj (data->down_glyph);
- markobj (data->disabled_glyph);
- markobj (data->cap_up_glyph);
- markobj (data->cap_down_glyph);
- markobj (data->cap_disabled_glyph);
- markobj (data->callback);
- markobj (data->enabled_p);
+ mark_object (data->next);
+ mark_object (data->frame);
+ mark_object (data->up_glyph);
+ mark_object (data->down_glyph);
+ mark_object (data->disabled_glyph);
+ mark_object (data->cap_up_glyph);
+ mark_object (data->cap_down_glyph);
+ mark_object (data->cap_disabled_glyph);
+ mark_object (data->callback);
+ mark_object (data->enabled_p);
return data->help_string;
}
}
void
+reinit_specifier_type_create_toolbar (void)
+{
+ REINITIALIZE_SPECIFIER_TYPE (toolbar);
+}
+
+void
specifier_vars_of_toolbar (void)
{
Lisp_Object fb;
#define XTOOLBAR_BUTTON(x) XRECORD (x, toolbar_button, struct toolbar_button)
#define XSETTOOLBAR_BUTTON(x, p) XSETRECORD (x, p, toolbar_button)
#define TOOLBAR_BUTTONP(x) RECORDP (x, toolbar_button)
-#define GC_TOOLBAR_BUTTONP(x) GC_RECORDP (x, toolbar_button)
#define CHECK_TOOLBAR_BUTTON(x) CHECK_RECORD (x, toolbar_button)
#define CONCHECK_TOOLBAR_BUTTON(x) CONCHECK_RECORD (x, toolbar_button)
};
static Lisp_Object
-mark_tooltalk_message (Lisp_Object obj, void (*markobj) (Lisp_Object))
+mark_tooltalk_message (Lisp_Object obj)
{
- markobj (XTOOLTALK_MESSAGE (obj)->callback);
+ mark_object (XTOOLTALK_MESSAGE (obj)->callback);
return XTOOLTALK_MESSAGE (obj)->plist_sym;
}
};
static Lisp_Object
-mark_tooltalk_pattern (Lisp_Object obj, void (*markobj) (Lisp_Object))
+mark_tooltalk_pattern (Lisp_Object obj)
{
- markobj (XTOOLTALK_PATTERN (obj)->callback);
+ mark_object (XTOOLTALK_PATTERN (obj)->callback);
return XTOOLTALK_PATTERN (obj)->plist_sym;
}
#define XTOOLTALK_MESSAGE(x) XRECORD (x, tooltalk_message, struct Lisp_Tooltalk_Message)
#define XSETTOOLTALK_MESSAGE(x, p) XSETRECORD (x, p, tooltalk_message)
#define TOOLTALK_MESSAGEP(x) RECORDP (x, tooltalk_message)
-#define GC_TOOLTALK_MESSAGEP(x) GC_RECORDP (x, tooltalk_message)
#define CHECK_TOOLTALK_MESSAGE(x) CHECK_RECORD (x, tooltalk_message)
struct Lisp_Tooltalk_Pattern;
#define XTOOLTALK_PATTERN(x) XRECORD (x, tooltalk_pattern, struct Lisp_Tooltalk_Pattern)
#define XSETTOOLTALK_PATTERN(x, p) XSETRECORD (x, p, tooltalk_pattern)
#define TOOLTALK_PATTERNP(x) RECORDP (x, tooltalk_pattern)
-#define GC_TOOLTALK_PATTERNP(x) GC_RECORDP (x, tooltalk_pattern)
#define CHECK_TOOLTALK_PATTERN(x) CHECK_RECORD (x, tooltalk_pattern)
#define TOOLTALK_MESSAGE_KEY 100
which will be added to the list at the end of the command.
This ensures we can't run out of space while trying to make
an undo-boundary. */
-Lisp_Object pending_boundary;
+static Lisp_Object pending_boundary;
static void
undo_boundary (struct buffer *b)
}
void
-vars_of_undo (void)
+reinit_vars_of_undo (void)
{
inside_undo = 0;
+}
+
+void
+vars_of_undo (void)
+{
+ reinit_vars_of_undo ();
+
pending_boundary = Qnil;
staticpro (&pending_boundary);
last_undo_buffer = Qnil;
the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-/* Synched up with: FSF 20.2. */
+/* Synched up with: FSF 20.4. */
/*
* unexec.c - Convert a running program into an a.out file.
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
+#if !defined (__NetBSD__) && !defined (__OpenBSD__)
#include <elf.h>
+#endif
#include <sys/mman.h>
+#if defined (__sony_news) && defined (_SYSTYPE_SYSV)
+#include <sys/elf_mips.h>
+#include <sym.h>
+#endif /* __sony_news && _SYSTYPE_SYSV */
+#ifdef __sgi
+#include <sym.h> /* for HDRR declaration */
+#endif /* __sgi */
+
+#if defined (__alpha__) && !defined (__NetBSD__) && !defined (__OpenBSD__)
+/* Declare COFF debugging symbol table. This used to be in
+ /usr/include/sym.h, but this file is no longer included in Red Hat
+ 5.0 and presumably in any other glibc 2.x based distribution. */
+typedef struct {
+ short magic;
+ short vstamp;
+ int ilineMax;
+ int idnMax;
+ int ipdMax;
+ int isymMax;
+ int ioptMax;
+ int iauxMax;
+ int issMax;
+ int issExtMax;
+ int ifdMax;
+ int crfd;
+ int iextMax;
+ long cbLine;
+ long cbLineOffset;
+ long cbDnOffset;
+ long cbPdOffset;
+ long cbSymOffset;
+ long cbOptOffset;
+ long cbAuxOffset;
+ long cbSsOffset;
+ long cbSsExtOffset;
+ long cbFdOffset;
+ long cbRfdOffset;
+ long cbExtOffset;
+} HDRR, *pHDRR;
+#define cbHDRR sizeof(HDRR)
+#define hdrNil ((pHDRR)0)
+#endif
+
+#ifdef __NetBSD__
+/*
+ * NetBSD does not have normal-looking user-land ELF support.
+ */
+# ifdef __alpha__
+# define ELFSIZE 64
+# else
+# define ELFSIZE 32
+# endif
+# include <sys/exec_elf.h>
+
+# define PT_LOAD Elf_pt_load
+# define SHT_SYMTAB Elf_sht_symtab
+# define SHT_DYNSYM Elf_sht_dynsym
+# define SHT_NULL Elf_sht_null
+# define SHT_NOBITS Elf_sht_nobits
+# define SHT_REL Elf_sht_rel
+# define SHT_RELA Elf_sht_rela
+
+# define SHN_UNDEF Elf_eshn_undefined
+# define SHN_ABS Elf_eshn_absolute
+# define SHN_COMMON Elf_eshn_common
+
+/*
+ * The magic of picking the right size types is handled by the ELFSIZE
+ * definition above.
+ */
+# ifdef __STDC__
+# define ElfW(type) Elf_##type
+# else
+# define ElfW(type) Elf_/**/type
+# endif
+
+# ifdef __alpha__
+# include <sys/exec_ecoff.h>
+# define HDRR struct ecoff_symhdr
+# define pHDRR HDRR *
+# endif
+#endif /* __NetBSD__ */
-#if __GLIBC__ - 0 >= 2
+#ifdef __OpenBSD__
+# include <sys/exec_elf.h>
+#endif
+
+#if __GNU_LIBRARY__ - 0 >= 6
# include <link.h> /* get ElfW etc */
#endif
/* Round X up to a multiple of Y. */
-static int
-round_up (int x, int y)
+static ElfW(Addr)
+round_up (ElfW(Addr) x, ElfW(Addr) y)
{
int rem = x % y;
if (rem == 0)
ElfW(Off) new_data2_offset;
ElfW(Addr) new_data2_addr;
- int n, nn, old_bss_index, old_data_index;
+ int n, nn, old_bss_index, old_data_index, new_data2_index;
+ int old_sbss_index, old_mdebug_index;
struct stat stat_buf;
/* Open the old file & map it into the address space. */
if (fstat (old_file, &stat_buf) == -1)
fatal ("Can't fstat (%s): errno %d\n", old_name, errno);
- old_base = mmap (0, stat_buf.st_size, PROT_READ, MAP_SHARED, old_file, 0);
+ old_base = (caddr_t) mmap (0, stat_buf.st_size, PROT_READ, MAP_SHARED, old_file, 0);
if (old_base == (caddr_t) -1)
fatal ("Can't mmap (%s): errno %d\n", old_name, errno);
if (old_bss_index == old_file_h->e_shnum)
fatal ("Can't find .bss in %s.\n", old_name, 0);
- old_bss_addr = OLD_SECTION_H (old_bss_index).sh_addr;
- old_bss_size = OLD_SECTION_H (old_bss_index).sh_size;
+ for (old_sbss_index = 1; old_sbss_index < (int) old_file_h->e_shnum;
+ old_sbss_index++)
+ {
+#ifdef DEBUG
+ fprintf (stderr, "Looking for .sbss - found %s\n",
+ old_section_names + OLD_SECTION_H (old_sbss_index).sh_name);
+#endif
+ if (!strcmp (old_section_names + OLD_SECTION_H (old_sbss_index).sh_name,
+ ".sbss"))
+ break;
+ }
+ if (old_sbss_index == old_file_h->e_shnum)
+ {
+ old_sbss_index = -1;
+ old_bss_addr = OLD_SECTION_H(old_bss_index).sh_addr;
+ old_bss_size = OLD_SECTION_H(old_bss_index).sh_size;
+ new_data2_offset = OLD_SECTION_H(old_bss_index).sh_offset;
+ new_data2_index = old_bss_index;
+ }
+ else
+ {
+ old_bss_addr = OLD_SECTION_H(old_sbss_index).sh_addr;
+ old_bss_size = OLD_SECTION_H(old_bss_index).sh_size
+ + OLD_SECTION_H(old_sbss_index).sh_size;
+ new_data2_offset = OLD_SECTION_H(old_sbss_index).sh_offset;
+ new_data2_index = old_sbss_index;
+ }
+
+ for (old_mdebug_index = 1; old_mdebug_index < (int) old_file_h->e_shnum;
+ old_mdebug_index++)
+ {
+#ifdef DEBUG
+ fprintf (stderr, "Looking for .mdebug - found %s\n",
+ old_section_names + OLD_SECTION_H (old_mdebug_index).sh_name);
+#endif
+ if (!strcmp (old_section_names + OLD_SECTION_H (old_mdebug_index).sh_name,
+ ".mdebug"))
+ break;
+ }
+ if (old_mdebug_index == old_file_h->e_shnum)
+ old_mdebug_index = 0;
+
#if defined (emacs) || !defined (DEBUG)
new_bss_addr = (ElfW(Addr)) sbrk (0);
#else
#endif
new_data2_addr = old_bss_addr;
new_data2_size = new_bss_addr - old_bss_addr;
- new_data2_offset = OLD_SECTION_H (old_bss_index).sh_offset;
#ifdef DEBUG
fprintf (stderr, "old_bss_index %d\n", old_bss_index);
if (ftruncate (new_file, new_file_size))
fatal ("Can't ftruncate (%s): errno %d\n", new_name, errno);
+ new_base = (caddr_t) mmap (0, new_file_size, PROT_READ | PROT_WRITE,
#ifdef UNEXEC_USE_MAP_PRIVATE
- new_base = mmap (0, new_file_size, PROT_READ | PROT_WRITE, MAP_PRIVATE,
- new_file, 0);
+ MAP_PRIVATE,
#else
- new_base = mmap (0, new_file_size, PROT_READ | PROT_WRITE, MAP_SHARED,
- new_file, 0);
+ MAP_SHARED,
#endif
+ new_file, 0);
if (new_base == (caddr_t) -1)
fatal ("Can't mmap (%s): errno %d\n", new_name, errno);
if ((OLD_SECTION_H (old_bss_index)).sh_addralign > alignment)
alignment = OLD_SECTION_H (old_bss_index).sh_addralign;
-#ifndef __mips /* ifndef added by jwz at suggestion of
- r02kar@x4u2.desy.de (Karsten Kuenne) to avoid
- "Program segment above .bss" when dumping.
- */
- if (NEW_PROGRAM_H (n).p_vaddr + NEW_PROGRAM_H (n).p_filesz > old_bss_addr)
- fatal ("Program segment above .bss in %s\n", old_name, 0);
-#endif /* __mips */
+#ifdef __mips
+ /* According to r02kar@x4u2.desy.de (Karsten Kuenne)
+ and oliva@gnu.org (Alexandre Oliva), on IRIX 5.2, we
+ always get "Program segment above .bss" when dumping
+ when the executable doesn't have an sbss section. */
+ if (old_sbss_index != -1)
+#endif /* __mips */
+ if (NEW_PROGRAM_H (n).p_vaddr + NEW_PROGRAM_H (n).p_filesz
+ > (old_sbss_index == -1
+ ? old_bss_addr
+ : round_up (old_bss_addr, alignment)))
+ fatal ("Program segment above .bss in %s\n", old_name, 0);
if (NEW_PROGRAM_H (n).p_type == PT_LOAD
- && (round_up ((int) ((NEW_PROGRAM_H (n)).p_vaddr
- + (NEW_PROGRAM_H (n)).p_filesz),
+ && (round_up ((NEW_PROGRAM_H (n)).p_vaddr
+ + (NEW_PROGRAM_H (n)).p_filesz,
alignment)
- == round_up ((int) old_bss_addr, alignment)))
+ == round_up (old_bss_addr, alignment)))
break;
}
if (n < 0)
fatal ("Couldn't find segment next to .bss in %s\n", old_name, 0);
+ /* Make sure that the size includes any padding before the old .bss
+ section. */
NEW_PROGRAM_H (n).p_filesz = new_bss_addr - NEW_PROGRAM_H (n).p_vaddr;
NEW_PROGRAM_H (n).p_memsz = NEW_PROGRAM_H (n).p_filesz;
for (n = 1, nn = 1; n < (int) old_file_h->e_shnum; n++, nn++)
{
caddr_t src;
- /* If it is bss section, insert the new data2 section before it. */
- if (n == old_bss_index)
+ /* If it is (s)bss section, insert the new data2 section before it. */
+ /* new_data2_index is the index of either old_sbss or old_bss, that was
+ chosen as a section for new_data2. */
+ if (n == new_data2_index)
{
/* Steal the data section header for this data2 section. */
memcpy (&NEW_SECTION_H (nn), &OLD_SECTION_H (old_data_index),
/* Now copy over what we have in the memory now. */
memcpy (NEW_SECTION_H (nn).sh_offset + new_base,
(caddr_t) OLD_SECTION_H (n).sh_addr,
- /* #### mrb: should be old_bss_size instead? */
new_data2_size);
nn++;
}
memcpy (&NEW_SECTION_H (nn), &OLD_SECTION_H (n),
old_file_h->e_shentsize);
-
- /* The new bss section's size is zero, and its file offset and virtual
- address should be off by NEW_DATA2_SIZE. */
- if (n == old_bss_index)
+
+ if (n == old_bss_index
+ /* The new bss and sbss section's size is zero, and its file offset
+ and virtual address should be off by NEW_DATA2_SIZE. */
+ || n == old_sbss_index
+ )
{
- /* NN should be `old_bss_index + 1' at this point. */
- NEW_SECTION_H (nn).sh_offset += new_data2_size;
- NEW_SECTION_H (nn).sh_addr += new_data2_size;
+ /* NN should be `old_s?bss_index + 1' at this point. */
+ NEW_SECTION_H (nn).sh_offset =
+ NEW_SECTION_H (new_data2_index).sh_offset + new_data2_size;
+ NEW_SECTION_H (nn).sh_addr =
+ NEW_SECTION_H (new_data2_index).sh_addr + new_data2_size;
/* Let the new bss section address alignment be the same as the
section address alignment followed the old bss section, so
this section will be placed in exactly the same place. */
>= OLD_SECTION_H (old_bss_index-1).sh_offset)
NEW_SECTION_H (nn).sh_offset += new_data2_size;
#else
- if (NEW_SECTION_H (nn).sh_offset >= new_data2_offset)
+ if (round_up (NEW_SECTION_H (nn).sh_offset,
+ OLD_SECTION_H (old_bss_index).sh_addralign)
+ >= new_data2_offset)
NEW_SECTION_H (nn).sh_offset += new_data2_size;
#endif
/* Any section that was originally placed after the section
/* Write out the sections. .data and .data1 (and data2, called
".data" in the strings table) get copied from the current process
instead of the old file. */
-#ifdef __powerpc__
- /* The PowerPC has additional 'data' segments which need to be saved */
- if (!strcmp (old_section_names + NEW_SECTION_H (n).sh_name, ".data") ||
- !strcmp (old_section_names + NEW_SECTION_H (n).sh_name, ".data1") ||
- !strcmp (old_section_names + NEW_SECTION_H (n).sh_name, ".sdata") ||
- !strcmp (old_section_names + NEW_SECTION_H (n).sh_name, ".sdata1"))
-#else
if (!strcmp (old_section_names + NEW_SECTION_H (n).sh_name, ".data")
|| !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name),
- ".data1"))
+ ".sdata")
+ /* Taking these sections from the current process, breaks
+ Linux in a subtle way. Binaries only run on the
+ architecture (e.g. i586 vs i686) of the dumping machine */
+#ifdef __sgi
+ || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name),
+ ".lit4")
+ || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name),
+ ".lit8")
+ || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name),
+ ".got")
#endif
+ || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name),
+ ".sdata1")
+ || !strcmp ((old_section_names + NEW_SECTION_H (n).sh_name),
+ ".data1"))
src = (caddr_t) OLD_SECTION_H (n).sh_addr;
else
src = old_base + OLD_SECTION_H (n).sh_offset;
memcpy (NEW_SECTION_H (nn).sh_offset + new_base, src,
NEW_SECTION_H (nn).sh_size);
+#ifdef __alpha__
+ /* Update Alpha COFF symbol table: */
+ if (strcmp (old_section_names + OLD_SECTION_H (n).sh_name, ".mdebug")
+ == 0)
+ {
+ pHDRR symhdr = (pHDRR) (NEW_SECTION_H (nn).sh_offset + new_base);
+
+ symhdr->cbLineOffset += new_data2_size;
+ symhdr->cbDnOffset += new_data2_size;
+ symhdr->cbPdOffset += new_data2_size;
+ symhdr->cbSymOffset += new_data2_size;
+ symhdr->cbOptOffset += new_data2_size;
+ symhdr->cbAuxOffset += new_data2_size;
+ symhdr->cbSsOffset += new_data2_size;
+ symhdr->cbSsExtOffset += new_data2_size;
+ symhdr->cbFdOffset += new_data2_size;
+ symhdr->cbRfdOffset += new_data2_size;
+ symhdr->cbExtOffset += new_data2_size;
+ }
+#endif /* __alpha__ */
+
+#if defined (__sony_news) && defined (_SYSTYPE_SYSV)
+ if (NEW_SECTION_H (nn).sh_type == SHT_MIPS_DEBUG && old_mdebug_index)
+ {
+ int diff = NEW_SECTION_H(nn).sh_offset
+ - OLD_SECTION_H(old_mdebug_index).sh_offset;
+ HDRR *phdr = (HDRR *)(NEW_SECTION_H (nn).sh_offset + new_base);
+
+ if (diff)
+ {
+ phdr->cbLineOffset += diff;
+ phdr->cbDnOffset += diff;
+ phdr->cbPdOffset += diff;
+ phdr->cbSymOffset += diff;
+ phdr->cbOptOffset += diff;
+ phdr->cbAuxOffset += diff;
+ phdr->cbSsOffset += diff;
+ phdr->cbSsExtOffset += diff;
+ phdr->cbFdOffset += diff;
+ phdr->cbRfdOffset += diff;
+ phdr->cbExtOffset += diff;
+ }
+ }
+#endif /* __sony_news && _SYSTYPE_SYSV */
+
+#ifdef __sgi
+ /* Adjust the HDRR offsets in .mdebug and copy the
+ line data if it's in its usual 'hole' in the object.
+ Makes the new file debuggable with dbx.
+ patches up two problems: the absolute file offsets
+ in the HDRR record of .mdebug (see /usr/include/syms.h), and
+ the ld bug that gets the line table in a hole in the
+ elf file rather than in the .mdebug section proper.
+ David Anderson. davea@sgi.com Jan 16,1994. */
+ if (n == old_mdebug_index)
+ {
+#define MDEBUGADJUST(__ct,__fileaddr) \
+ if (n_phdrr->__ct > 0) \
+ { \
+ n_phdrr->__fileaddr += movement; \
+ }
+
+ HDRR * o_phdrr = (HDRR *)((byte *)old_base + OLD_SECTION_H (n).sh_offset);
+ HDRR * n_phdrr = (HDRR *)((byte *)new_base + NEW_SECTION_H (nn).sh_offset);
+ unsigned movement = new_data2_size;
+
+ MDEBUGADJUST (idnMax, cbDnOffset);
+ MDEBUGADJUST (ipdMax, cbPdOffset);
+ MDEBUGADJUST (isymMax, cbSymOffset);
+ MDEBUGADJUST (ioptMax, cbOptOffset);
+ MDEBUGADJUST (iauxMax, cbAuxOffset);
+ MDEBUGADJUST (issMax, cbSsOffset);
+ MDEBUGADJUST (issExtMax, cbSsExtOffset);
+ MDEBUGADJUST (ifdMax, cbFdOffset);
+ MDEBUGADJUST (crfd, cbRfdOffset);
+ MDEBUGADJUST (iextMax, cbExtOffset);
+ /* The Line Section, being possible off in a hole of the object,
+ requires special handling. */
+ if (n_phdrr->cbLine > 0)
+ {
+ if (o_phdrr->cbLineOffset > (OLD_SECTION_H (n).sh_offset
+ + OLD_SECTION_H (n).sh_size))
+ {
+ /* line data is in a hole in elf. do special copy and adjust
+ for this ld mistake.
+ */
+ n_phdrr->cbLineOffset += movement;
+
+ memcpy (n_phdrr->cbLineOffset + new_base,
+ o_phdrr->cbLineOffset + old_base, n_phdrr->cbLine);
+ }
+ else
+ {
+ /* somehow line data is in .mdebug as it is supposed to be. */
+ MDEBUGADJUST (cbLine, cbLineOffset);
+ }
+ }
+ }
+#endif /* __sgi */
+
/* If it is the symbol table, its st_shndx field needs to be patched. */
if (NEW_SECTION_H (nn).sh_type == SHT_SYMTAB
|| NEW_SECTION_H (nn).sh_type == SHT_DYNSYM)
be no harm in that provided that r_offset is always the first
member. */
nn = section.sh_info;
-#ifdef __powerpc__
- /* The PowerPC has additional 'data' segments which need to be saved */
- if (!strcmp (old_section_names + NEW_SECTION_H (n).sh_name, ".data") ||
- !strcmp (old_section_names + NEW_SECTION_H (n).sh_name, ".data1") ||
- !strcmp (old_section_names + NEW_SECTION_H (n).sh_name, ".sdata") ||
- !strcmp (old_section_names + NEW_SECTION_H (n).sh_name, ".sdata1"))
-#else
if (!strcmp (old_section_names + NEW_SECTION_H (nn).sh_name, ".data")
|| !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name),
- ".data1"))
+ ".sdata")
+#ifdef __sgi
+ || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name),
+ ".lit4")
+ || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name),
+ ".lit8")
+ || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name),
+ ".got")
#endif
+ || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name),
+ ".sdata1")
+ || !strcmp ((old_section_names + NEW_SECTION_H (nn).sh_name),
+ ".data1"))
{
ElfW(Addr) offset = NEW_SECTION_H (nn).sh_addr -
NEW_SECTION_H (nn).sh_offset;
reloc += section.sh_entsize)
{
ElfW(Addr) addr = ((ElfW(Rel) *) reloc)->r_offset - offset;
+#ifdef __alpha__
+ /* The Alpha ELF binutils currently have a bug that
+ sometimes results in relocs that contain all
+ zeroes. Work around this for now... */
+ if (((ElfW(Rel) *) reloc)->r_offset == 0)
+ continue;
+#endif
memcpy (new_base + addr, old_base + addr, sizeof(ElfW(Addr)));
}
}
int
-open_output_file (file_data *p_file, char *filename, unsigned long size)
+open_output_file (file_data *p_file, CONST char *filename, unsigned long size)
{
HANDLE file;
HANDLE file_mapping;
#include "gutter.h"
Lisp_Object Qwindowp, Qwindow_live_p, Qwindow_configurationp;
-Lisp_Object Qscroll_up, Qscroll_down, Qdisplay_buffer;
+Lisp_Object Qdisplay_buffer;
#ifdef MEMORY_USAGE_STATS
Lisp_Object Qface_cache, Qglyph_cache, Qline_start_cache, Qother_redisplay;
/* Spacing between outer egde of divider border and window edge */
Lisp_Object Vvertical_divider_spacing;
+/* How much to scroll by per-line. */
+Lisp_Object Vwindow_pixel_scroll_increment;
+
/* Scroll if point lands on the bottom line and that line is partially
clipped. */
int scroll_on_clipped_lines;
int next_screen_context_lines;
/* List of freed window configurations with 1 - 10 windows. */
-Lisp_Object Vwindow_configuration_free_list[10];
+static Lisp_Object Vwindow_configuration_free_list[10];
#define SET_LAST_MODIFIED(w, cache_too) \
do { \
\f
#define MARK_DISP_VARIABLE(field) \
- markobj (window->field[CURRENT_DISP]); \
- markobj (window->field[DESIRED_DISP]); \
- markobj (window->field[CMOTION_DISP]);
+ mark_object (window->field[CURRENT_DISP]); \
+ mark_object (window->field[DESIRED_DISP]); \
+ mark_object (window->field[CMOTION_DISP]);
static Lisp_Object
-mark_window (Lisp_Object obj, void (*markobj) (Lisp_Object))
+mark_window (Lisp_Object obj)
{
struct window *window = XWINDOW (obj);
- markobj (window->frame);
- markobj (window->mini_p);
- markobj (window->next);
- markobj (window->prev);
- markobj (window->hchild);
- markobj (window->vchild);
- markobj (window->parent);
- markobj (window->buffer);
+ mark_object (window->frame);
+ mark_object (window->mini_p);
+ mark_object (window->next);
+ mark_object (window->prev);
+ mark_object (window->hchild);
+ mark_object (window->vchild);
+ mark_object (window->parent);
+ mark_object (window->buffer);
MARK_DISP_VARIABLE (start);
MARK_DISP_VARIABLE (pointm);
- markobj (window->sb_point); /* #### move to scrollbar.c? */
- markobj (window->use_time);
+ mark_object (window->sb_point); /* #### move to scrollbar.c? */
+ mark_object (window->use_time);
MARK_DISP_VARIABLE (last_modified);
MARK_DISP_VARIABLE (last_point);
MARK_DISP_VARIABLE (last_start);
MARK_DISP_VARIABLE (last_facechange);
- markobj (window->line_cache_last_updated);
- markobj (window->redisplay_end_trigger);
- markobj (window->subwindow_instance_cache);
+ mark_object (window->line_cache_last_updated);
+ mark_object (window->redisplay_end_trigger);
+ mark_object (window->subwindow_instance_cache);
- mark_face_cachels (window->face_cachels, markobj);
- mark_glyph_cachels (window->glyph_cachels, markobj);
+ mark_face_cachels (window->face_cachels);
+ mark_glyph_cachels (window->glyph_cachels);
-#define WINDOW_SLOT(slot, compare) ((void) (markobj (window->slot)))
+#define WINDOW_SLOT(slot, compare) mark_object (window->slot)
#include "winslots.h"
return Qnil;
int
window_truncation_on (struct window *w)
{
+ /* Minibuffer windows are never truncated.
+ ### is this the right way ? */
+ if (MINI_WINDOW_P (w))
+ return 0;
+
/* Horizontally scrolled windows are truncated. */
if (w->hscroll)
return 1;
return 0;
}
+DEFUN ("window-truncated-p", Fwindow_truncated_p, 0, 1, 0, /*
+Returns Non-Nil iff the window is truncated.
+*/
+ (window))
+{
+ struct window *w = decode_window (window);
+
+ return window_truncation_on (w) ? Qt : Qnil;
+}
+
+
static int
have_undivided_common_edge (struct window *w_right, void *closure)
{
}
}
+DEFUN ("last-nonminibuf-window", Flast_nonminibuf_window, 0, 1, 0, /*
+Return the last selected window that is not a minibuffer window.
+If the optional argument CON-DEV-OR-FRAME is specified and is a frame,
+return the last non-minibuffer window used by that frame. If
+CON-DEV-OR-FRAME is a device, then the selected frame on that device
+will be used. If CON-DEV-OR-FRAME is a console, the selected frame on
+that console's selected device will be used. Otherwise, the selected
+frame is used.
+*/
+ (con_dev_or_frame))
+{
+ if (NILP (con_dev_or_frame) && NILP (Fselected_device (Qnil)))
+ return Qnil; /* happens at startup */
+
+ {
+ struct frame *f = decode_frame_or_selected (con_dev_or_frame);
+ return FRAME_LAST_NONMINIBUF_WINDOW (f);
+ }
+}
+
DEFUN ("minibuffer-window", Fminibuffer_window, 0, 1, 0, /*
Return the window used now for minibuffers.
If the optional argument CON-DEV-OR-FRAME is specified and is a frame, return
\f
-/* Scroll contents of window WINDOW up N lines. */
+/* Scroll contents of window WINDOW up N lines. If N < (top line height /
+ average line height) then we just adjust the top clip. */
void
window_scroll (Lisp_Object window, Lisp_Object n, int direction,
Error_behavior errb)
int selected = EQ (window, Fselected_window (Qnil));
int value = 0;
Lisp_Object point, tem;
+ display_line_dynarr *dla;
+ int fheight, fwidth, modeline = 0;
+ struct display_line* dl;
if (selected)
point = make_int (BUF_PT (b));
window, Qnil);
Fset_marker (w->start[CURRENT_DISP], point, w->buffer);
w->start_at_line_beg = beginning_of_line_p (b, XINT (point));
+ WINDOW_TEXT_TOP_CLIP (w) = 0;
MARK_WINDOWS_CHANGED (w);
}
{
return;
}
- else if (value > 0)
- {
- int vtarget;
- Bufpos startp, old_start;
- old_start = marker_position (w->start[CURRENT_DISP]);
- startp = vmotion (w, old_start, value, &vtarget);
+ /* Determine parameters to test for partial line scrolling with. */
+ dla = window_display_lines (w, CURRENT_DISP);
+
+ if (INTP (Vwindow_pixel_scroll_increment))
+ fheight = XINT (Vwindow_pixel_scroll_increment);
+ else if (!NILP (Vwindow_pixel_scroll_increment));
+ default_face_height_and_width (window, &fheight, &fwidth);
+
+ if (Dynarr_length (dla) >= 1)
+ modeline = Dynarr_atp (dla, 0)->modeline;
- if (vtarget < value &&
- (w->window_end_pos[CURRENT_DISP] == -1
- || (BUF_Z (b) - w->window_end_pos[CURRENT_DISP] > BUF_ZV (b))))
+ dl = Dynarr_atp (dla, modeline);
+
+ if (value > 0)
+ {
+ /* Go for partial display line scrolling. This just means bumping
+ the clip by a reasonable amount and redisplaying, everything else
+ remains unchanged. */
+ if (!NILP (Vwindow_pixel_scroll_increment)
+ &&
+ Dynarr_length (dla) >= (1 + modeline)
+ &&
+ (dl->ascent - dl->top_clip) - fheight * value > 0)
{
- maybe_signal_error (Qend_of_buffer, Qnil, Qwindow, errb);
- return;
+ WINDOW_TEXT_TOP_CLIP (w) += value * fheight;
+ MARK_WINDOWS_CHANGED (w);
}
else
{
- set_marker_restricted (w->start[CURRENT_DISP], make_int (startp),
- w->buffer);
- w->force_start = 1;
- w->start_at_line_beg = beginning_of_line_p (b, startp);
- MARK_WINDOWS_CHANGED (w);
+ int vtarget;
+ Bufpos startp, old_start;
+
+ if (WINDOW_TEXT_TOP_CLIP (w))
+ {
+ WINDOW_TEXT_TOP_CLIP (w) = 0;
+ MARK_WINDOWS_CHANGED (w);
+ }
- if (!point_would_be_visible (w, startp, XINT (point)))
+ old_start = marker_position (w->start[CURRENT_DISP]);
+ startp = vmotion (w, old_start, value, &vtarget);
+
+ if (vtarget < value &&
+ (w->window_end_pos[CURRENT_DISP] == -1
+ || (BUF_Z (b) - w->window_end_pos[CURRENT_DISP] > BUF_ZV (b))))
{
- if (selected)
- BUF_SET_PT (b, startp);
- else
- set_marker_restricted (w->pointm[CURRENT_DISP],
- make_int (startp),
- w->buffer);
+ maybe_signal_error (Qend_of_buffer, Qnil, Qwindow, errb);
+ return;
+ }
+ else
+ {
+ set_marker_restricted (w->start[CURRENT_DISP], make_int (startp),
+ w->buffer);
+ w->force_start = 1;
+ w->start_at_line_beg = beginning_of_line_p (b, startp);
+ MARK_WINDOWS_CHANGED (w);
+
+ if (!point_would_be_visible (w, startp, XINT (point)))
+ {
+ if (selected)
+ BUF_SET_PT (b, startp);
+ else
+ set_marker_restricted (w->pointm[CURRENT_DISP],
+ make_int (startp),
+ w->buffer);
+ }
}
}
}
else if (value < 0)
{
- int vtarget;
- Bufpos startp, old_start;
-
- old_start = marker_position (w->start[CURRENT_DISP]);
- startp = vmotion (w, old_start, value, &vtarget);
-
- if (vtarget > value
- && marker_position (w->start[CURRENT_DISP]) == BUF_BEGV (b))
+ /* Go for partial display line scrolling. This just means bumping
+ the clip by a reasonable amount and redisplaying, everything else
+ remains unchanged. */
+ if (!NILP (Vwindow_pixel_scroll_increment)
+ &&
+ Dynarr_length (dla) >= (1 + modeline)
+ &&
+ (dl->ascent - dl->top_clip) - fheight * value <
+ (dl->ascent + dl->descent - dl->clip)
+ &&
+ WINDOW_TEXT_TOP_CLIP (w) + value * fheight > 0)
{
- maybe_signal_error (Qbeginning_of_buffer, Qnil, Qwindow, errb);
- return;
+ WINDOW_TEXT_TOP_CLIP (w) += value * fheight;
+ MARK_WINDOWS_CHANGED (w);
}
else
{
- set_marker_restricted (w->start[CURRENT_DISP], make_int (startp),
- w->buffer);
- w->force_start = 1;
- w->start_at_line_beg = beginning_of_line_p (b, startp);
- MARK_WINDOWS_CHANGED (w);
-
- if (!point_would_be_visible (w, startp, XINT (point)))
+ int vtarget;
+ Bufpos startp, old_start;
+
+ if (WINDOW_TEXT_TOP_CLIP (w))
{
- Bufpos new_point;
-
- if (MINI_WINDOW_P (w))
- new_point = startp;
- else
- new_point = start_of_last_line (w, startp);
-
- if (selected)
- BUF_SET_PT (b, new_point);
- else
- set_marker_restricted (w->pointm[CURRENT_DISP],
- make_int (new_point),
- w->buffer);
+ WINDOW_TEXT_TOP_CLIP (w) = 0;
+ MARK_WINDOWS_CHANGED (w);
+ }
+
+ old_start = marker_position (w->start[CURRENT_DISP]);
+ startp = vmotion (w, old_start, value, &vtarget);
+
+ if (vtarget > value
+ && marker_position (w->start[CURRENT_DISP]) == BUF_BEGV (b))
+ {
+ maybe_signal_error (Qbeginning_of_buffer, Qnil, Qwindow, errb);
+ return;
+ }
+ else
+ {
+ set_marker_restricted (w->start[CURRENT_DISP], make_int (startp),
+ w->buffer);
+ w->force_start = 1;
+ w->start_at_line_beg = beginning_of_line_p (b, startp);
+ MARK_WINDOWS_CHANGED (w);
+
+ if (!point_would_be_visible (w, startp, XINT (point)))
+ {
+ Bufpos new_point;
+
+ if (MINI_WINDOW_P (w))
+ new_point = startp;
+ else
+ new_point = start_of_last_line (w, startp);
+
+ if (selected)
+ BUF_SET_PT (b, new_point);
+ else
+ set_marker_restricted (w->pointm[CURRENT_DISP],
+ make_int (new_point),
+ w->buffer);
+ }
}
}
}
else /* value == 0 && direction == -1 */
{
+ if (WINDOW_TEXT_TOP_CLIP (w))
+ {
+ WINDOW_TEXT_TOP_CLIP (w) = 0;
+ MARK_WINDOWS_CHANGED (w);
+ }
if (marker_position (w->start[CURRENT_DISP]) == BUF_BEGV (b))
{
maybe_signal_error (Qbeginning_of_buffer, Qnil, Qwindow, errb);
}
}
}
-
}
\f
DEFUN ("scroll-up", Fscroll_up, 0, 1, "_P", /*
#define CHECK_WINDOW_CONFIGURATION(x) CHECK_RECORD (x, window_configuration)
static Lisp_Object
-mark_window_config (Lisp_Object obj, void (*markobj) (Lisp_Object))
+mark_window_config (Lisp_Object obj)
{
struct window_config *config = XWINDOW_CONFIGURATION (obj);
int i;
- markobj (config->current_window);
- markobj (config->current_buffer);
- markobj (config->minibuffer_scroll_window);
- markobj (config->root_window);
+ mark_object (config->current_window);
+ mark_object (config->current_buffer);
+ mark_object (config->minibuffer_scroll_window);
+ mark_object (config->root_window);
for (i = 0; i < config->saved_windows_count; i++)
{
struct saved_window *s = SAVED_WINDOW_N (config, i);
- markobj (s->window);
- markobj (s->buffer);
- markobj (s->start);
- markobj (s->pointm);
- markobj (s->sb_point);
- markobj (s->mark);
+ mark_object (s->window);
+ mark_object (s->buffer);
+ mark_object (s->start);
+ mark_object (s->pointm);
+ mark_object (s->sb_point);
+ mark_object (s->mark);
#if 0
/* #### This looked like this. I do not see why specifier cached
values should not be marked, as such specifiers as toolbars
might have GC-able instances. Freed configs are not marked,
aren't they? -- kkm */
- markobj (s->dedicated);
+ mark_object (s->dedicated);
#else
-#define WINDOW_SLOT(slot, compare) ((void) (markobj (s->slot)))
+#define WINDOW_SLOT(slot, compare) mark_object (s->slot)
#include "winslots.h"
#endif
}
SET_LAST_FACECHANGE (w);
w->config_mark = 0;
-#define WINDOW_SLOT(slot, compare) w->slot = p->slot;
+#define WINDOW_SLOT(slot, compare) w->slot = p->slot
#include "winslots.h"
/* Reinstall the saved buffer and pointers into it. */
p->hscroll = w->hscroll;
p->modeline_hscroll = w->modeline_hscroll;
-#define WINDOW_SLOT(slot, compare) p->slot = w->slot;
+#define WINDOW_SLOT(slot, compare) p->slot = w->slot
#include "winslots.h"
if (!NILP (w->buffer))
return unbind_to (speccount, val);
}
+DEFUN ("current-pixel-column", Fcurrent_pixel_column, 0, 2, 0, /*
+Return the horizontal pixel position of POS in window.
+Beginning of line is column 0. This is calculated using the redisplay
+display tables. If WINDOW is nil, the current window is assumed.
+If POS is nil, point is assumed. Note that POS must be visible for
+a non-nil result to be returned.
+*/
+ (window, pos))
+{
+ struct window* w = decode_window (window);
+ display_line_dynarr *dla = window_display_lines (w, CURRENT_DISP);
+
+ struct display_line *dl = 0;
+ struct display_block *db = 0;
+ struct rune* rb = 0;
+ int y = w->last_point_y[CURRENT_DISP];
+ int x = w->last_point_x[CURRENT_DISP];
+
+ if (MINI_WINDOW_P (w))
+ return Qnil;
+
+ if (y<0 || x<0 || y >= Dynarr_length (dla) || !NILP (pos))
+ {
+ int first_line, i;
+ Bufpos point;
+
+ if (NILP (pos))
+ pos = Fwindow_point (window);
+
+ CHECK_INT (pos);
+ point = XINT (pos);
+
+ if (Dynarr_length (dla) && Dynarr_atp (dla, 0)->modeline)
+ first_line = 1;
+ else
+ first_line = 0;
+
+ for (i = first_line; i < Dynarr_length (dla); i++)
+ {
+ dl = Dynarr_atp (dla, i);
+ /* find the vertical location first */
+ if (point >= dl->bufpos && point <= dl->end_bufpos)
+ {
+ db = get_display_block_from_line (dl, TEXT);
+ for (i = 0; i < Dynarr_length (db->runes); i++)
+ {
+ rb = Dynarr_atp (db->runes, i);
+ if (point <= rb->bufpos)
+ goto found_bufpos;
+ }
+ return Qnil;
+ }
+ }
+ return Qnil;
+ found_bufpos:
+ ;
+ }
+ else
+ {
+ /* optimised case */
+ dl = Dynarr_atp (dla, y);
+ db = get_display_block_from_line (dl, TEXT);
+
+ if (x >= Dynarr_length (db->runes))
+ return Qnil;
+
+ rb = Dynarr_atp (db->runes, x);
+ }
+
+ return make_int (rb->xpos - WINDOW_LEFT (w));
+}
+
\f
#ifdef DEBUG_XEMACS
/* This is short and simple in elisp, but... it was written to debug
defsymbol (&Qwindowp, "windowp");
defsymbol (&Qwindow_live_p, "window-live-p");
defsymbol (&Qwindow_configurationp, "window-configuration-p");
- defsymbol (&Qscroll_up, "scroll-up");
- defsymbol (&Qscroll_down, "scroll-down");
defsymbol (&Qtemp_buffer_show_hook, "temp-buffer-show-hook");
defsymbol (&Qdisplay_buffer, "display-buffer");
#endif
DEFSUBR (Fselected_window);
+ DEFSUBR (Flast_nonminibuf_window);
DEFSUBR (Fminibuffer_window);
DEFSUBR (Fwindow_minibuffer_p);
DEFSUBR (Fwindowp);
DEFSUBR (Fwindow_previous_child);
DEFSUBR (Fwindow_parent);
DEFSUBR (Fwindow_lowest_p);
+ DEFSUBR (Fwindow_truncated_p);
DEFSUBR (Fwindow_highest_p);
DEFSUBR (Fwindow_leftmost_p);
DEFSUBR (Fwindow_rightmost_p);
DEFSUBR (Fset_window_configuration);
DEFSUBR (Fcurrent_window_configuration);
DEFSUBR (Fsave_window_excursion);
+ DEFSUBR (Fcurrent_pixel_column);
}
void
-vars_of_window (void)
+reinit_vars_of_window (void)
{
+ int i;
/* Make sure all windows get marked */
minibuf_window = Qnil;
- staticpro (&minibuf_window);
+ staticpro_nodump (&minibuf_window);
+
+ for (i = 0; i < countof (Vwindow_configuration_free_list); i++)
+ {
+ Vwindow_configuration_free_list[i] =
+ make_lcrecord_list (sizeof_window_config_for_n_windows (i + 1),
+ &lrecord_window_configuration);
+ staticpro_nodump (&Vwindow_configuration_free_list[i]);
+ }
+}
+
+void
+vars_of_window (void)
+{
+ reinit_vars_of_window ();
DEFVAR_BOOL ("scroll-on-clipped-lines", &scroll_on_clipped_lines /*
*Non-nil means to scroll if point lands on a line which is clipped.
*/ );
Vother_window_scroll_buffer = Qnil;
+ DEFVAR_LISP ("window-pixel-scroll-increment", &Vwindow_pixel_scroll_increment /*
+*Number of pixels to scroll by per requested line.
+If nil then normal line scrolling occurs regardless of line height.
+If t then scrolling is done in increments equal to the height of the default face.
+*/ );
+ Vwindow_pixel_scroll_increment = Qt;
+
DEFVAR_INT ("next-screen-context-lines", &next_screen_context_lines /*
*Number of lines of continuity when scrolling by screenfuls.
*/ );
*Delete any window less than this wide.
*/ );
window_min_width = 10;
-
- {
- int i;
-
- for (i = 0; i < countof (Vwindow_configuration_free_list); i++)
- {
- Vwindow_configuration_free_list[i] =
- make_lcrecord_list (sizeof_window_config_for_n_windows (i + 1),
- &lrecord_window_configuration);
- staticpro (&Vwindow_configuration_free_list[i]);
- }
- }
}
void
int hscroll;
/* Idem for the window's modeline */
int modeline_hscroll;
+ /* Amount to clip off the top line for pixel-based scrolling. Point
+ will remain constant but this will be incremented to
+ incrementally shift lines up. */
+ int top_yoffset;
+ /* Amount to clip off the left of the lines for pixel-based
+ scrolling. Hscroll will remain constant but this will be
+ incremented to incrementally shift lines left.*/
+ int left_xoffset;
/* Number saying how recently window was selected */
Lisp_Object use_time;
/* text.modified of displayed buffer as of last time display completed */
#define XWINDOW(x) XRECORD (x, window, struct window)
#define XSETWINDOW(x, p) XSETRECORD (x, p, window)
#define WINDOWP(x) RECORDP (x, window)
-#define GC_WINDOWP(x) GC_RECORDP (x, window)
#define CHECK_WINDOW(x) CHECK_RECORD (x, window)
#define CONCHECK_WINDOW(x) CONCHECK_RECORD (x, window)
/* XEmacs window size and positioning macros. */
#define WINDOW_TOP(w) ((w)->pixel_top)
#define WINDOW_TEXT_TOP(w) (WINDOW_TOP (w) + window_top_gutter_height (w))
+#define WINDOW_TEXT_TOP_CLIP(w) ((w)->top_yoffset)
#define WINDOW_BOTTOM(w) ((w)->pixel_top + (w)->pixel_height)
#define WINDOW_TEXT_BOTTOM(w) (WINDOW_BOTTOM (w) - window_bottom_gutter_height (w))
#define WINDOW_LEFT(w) ((w)->pixel_left)
# include <X11/Xmu/CurUtil.h>
# include <X11/Xmu/Drawing.h>
# include <X11/Xmu/Error.h>
+# include <X11/Xmu/Misc.h>
/* Do the EDITRES protocol if running X11R5 (or later) version */
#if (XtSpecificationRelease >= 5)
int XmuPrintDefaultErrorMessage (Display *dpy, XErrorEvent *event, FILE *fp);
void XmuCopyISOLatin1Lowered (char *, CONST char *);
+#define Max(x, y) (((x) > (y)) ? (x) : (y))
+#define Min(x, y) (((x) < (y)) ? (x) : (y))
+#define AssignMax(x, y) {if ((y) > (x)) x = (y);}
+#define AssignMin(x, y) {if ((y) < (x)) x = (y);}
+typedef enum {XtorientHorizontal, XtorientVertical} XtOrientation;
+
#endif
+1999-11-10 XEmacs Build Bot <builds@cvs.xemacs.org>
+
+ * XEmacs 21.2.20 is released
+
1999-07-30 XEmacs Build Bot <builds@cvs.xemacs.org>
* XEmacs 21.2.19 is released
(require 'test-harness))))
;; Test all combinations of make-hash-table keywords
-(dolist (type '(non-weak weak key-weak value-weak))
- (dolist (test '(eq eql equal))
- (dolist (size '(0 1 100))
- (dolist (rehash-size '(1.1 9.9))
- (dolist (rehash-threshold '(0.2 .9))
+(dolist (test '(eq eql equal))
+ (dolist (size '(0 1 100))
+ (dolist (rehash-size '(1.1 9.9))
+ (dolist (rehash-threshold '(0.2 .9))
+ (dolist (weakness '(nil t key value))
(dolist (data '(() (1 2) (1 2 3 4)))
- (let ((ht (make-hash-table :test test
- :type type
- :size size
- :rehash-size rehash-size
- :rehash-threshold rehash-threshold)))
+ (let ((ht (make-hash-table
+ :test test
+ :size size
+ :rehash-size rehash-size
+ :rehash-threshold rehash-threshold
+ :weakness weakness)))
(Assert (equal ht (car (let ((print-readably t))
(read-from-string (prin1-to-string ht))))))
(Assert (eq test (hash-table-test ht)))
- (Assert (eq type (hash-table-type ht)))
(Assert (<= size (hash-table-size ht)))
(Assert (eql rehash-size (hash-table-rehash-size ht)))
- (Assert (eql rehash-threshold (hash-table-rehash-threshold ht))))))))))
+ (Assert (eql rehash-threshold (hash-table-rehash-threshold ht)))
+ (Assert (eq weakness (hash-table-weakness ht))))))))))
-(loop for (fun type) in '((make-hashtable non-weak)
- (make-weak-hashtable weak)
- (make-key-weak-hashtable key-weak)
- (make-value-weak-hashtable value-weak))
- do (Assert (eq type (hash-table-type (funcall fun 10)))))
+(loop for (fun weakness) in '((make-hashtable nil)
+ (make-weak-hashtable t)
+ (make-key-weak-hashtable key)
+ (make-value-weak-hashtable value))
+ do (Assert (eq weakness (hash-table-weakness (funcall fun 10)))))
+
+(loop for (type weakness) in '((non-weak nil)
+ (weak t)
+ (key-weak key)
+ (value-weak value))
+ do (Assert (equal (make-hash-table :type type)
+ (make-hash-table :weakness weakness))))
+
+(Assert (not (equal (make-hash-table :weakness nil)
+ (make-hash-table :weakness t))))
(let ((ht (make-hash-table :size 20 :rehash-threshold .75 :test 'eq))
(size 80))
(Assert (eq 'eq (hash-table-test ht)))
(Assert (eq 'non-weak (hash-table-type ht)))
(Assert (eq 'non-weak (hashtable-type ht)))
+ (Assert (eq 'nil (hash-table-weakness ht)))
(dotimes (j size)
(puthash j (- j) ht)
(Assert (eq (gethash j ht) (- j)))
))
;; Test that weak hash-tables are properly handled
-(loop for (type expected-count expected-k-sum expected-v-sum) in
- '((non-weak 6 38 25)
- (weak 3 6 9)
- (key-weak 4 38 9)
- (value-weak 4 6 25))
+(loop for (weakness expected-count expected-k-sum expected-v-sum) in
+ '((nil 6 38 25)
+ (t 3 6 9)
+ (key 4 38 9)
+ (value 4 6 25))
do
- (let* ((ht (make-hash-table :type type))
+ (let* ((ht (make-hash-table :weakness weakness))
(my-obj (cons ht ht)))
(garbage-collect)
(puthash my-obj 1 ht)
(Assert (= v-sum k-sum))))
;;; Test reading and printing of hash-table objects
-(let ((h1 #s(hashtable type weak rehash-size 3.0 rehash-threshold .2 test eq data (1 2 3 4)))
- (h2 #s(hash-table type weak rehash-size 3.0 rehash-threshold .2 test eq data (1 2 3 4)))
- (h3 (make-hash-table :type 'weak :rehash-size 3.0 :rehash-threshold .2 :test 'eq)))
+(let ((h1 #s(hashtable weakness t rehash-size 3.0 rehash-threshold .2 test eq data (1 2 3 4)))
+ (h2 #s(hash-table weakness t rehash-size 3.0 rehash-threshold .2 test eq data (1 2 3 4)))
+ (h3 (make-hash-table :weakness t :rehash-size 3.0 :rehash-threshold .2 :test 'eq)))
(Assert (equal h1 h2))
(Assert (not (equal h1 h3)))
(puthash 1 2 h3)
(clrhash h2)
(Assert (equal h1 h2))
)
+
+;;; Test sxhash
+(Assert (= (sxhash "foo") (sxhash "foo")))
+(Assert (= (sxhash '(1 2 3)) (sxhash '(1 2 3))))
(Assert (= (+ 1.0 1) 2.0))
(Assert (= (+ 1.0 1 1) 3.0))
(Assert (= (+ 1 1 1.0) 3.0))
+(Assert (eq (1+ most-positive-fixnum) most-negative-fixnum))
+(Assert (eq (+ most-positive-fixnum 1) most-negative-fixnum))
;; Test `-'
(Check-Error wrong-number-of-arguments (-))
(Assert (= (- 1.5 1) .5))
(Assert (= (- 1 1.5) (- .5)))
+(Assert (eq (1- most-negative-fixnum) most-positive-fixnum))
+(Assert (eq (- most-negative-fixnum 1) most-positive-fixnum))
+
;; Test `/'
;; Test division by zero errors
-(setq str "Hello There")
(set-extent-begin-glyph
- (make-extent 0 0 str)
- (make-glyph [xpm :file "../etc/xemacs-icon.xpm"]))
+ (make-extent (point) (point))
+ (setq im (make-glyph [xpm :file "xemacs-icon.xpm"])))
(defun foo ()
- (interactive)
- (ding))
-; (setq ok-select (not ok-select)))
+ (interactive)
+ (setq ok-select (not ok-select)))
+
+(defun fee () (interactive) (message "hello"))
;; button in a group
(setq ok-select nil)
(set-extent-begin-glyph
(make-extent (point) (point))
- (make-glyph [button :descriptor ["ok " (setq ok-select t)
- :style radio :selected ok-select]]))
+ (setq radio-button1
+ (make-glyph
+ [button :descriptor ["ok " (setq ok-select t)
+ :style radio :selected ok-select]])))
;; button in a group
(set-extent-begin-glyph
(make-extent (point) (point))
- (make-glyph [button :descriptor ["ok" (setq ok-select nil) :style radio
- :selected (not ok-select)]]))
+ (setq radio-button2
+ (make-glyph
+ [button :descriptor ["ok" (setq ok-select nil) :style radio
+ :selected (not ok-select)]])))
;; toggle button
(set-extent-begin-glyph
(make-extent (point) (point))
:selected (not ok-select)]])))
(set-extent-begin-glyph
(make-extent (point) (point))
- (make-glyph [button :descriptor ["ok" :style toggle
- :callback
- (setq ok-select (not ok-select))
- :selected ok-select]]))
+ (setq toggle-button
+ (make-glyph [button :descriptor ["ok" :style toggle
+ :callback
+ (setq ok-select (not ok-select))
+ :selected ok-select]])))
;; normal pushbutton
(set-extent-begin-glyph
(make-extent (point) (point))
- (setq pbutton (make-glyph
- [button :width 10 :height 2
- :face modeline-mousable
- :descriptor "ok" :callback foo
- :selected t])))
+ (setq push-button
+ (make-glyph [button :width 10 :height 2
+ :face modeline-mousable
+ :descriptor "ok" :callback foo
+ :selected t])))
;; tree view
(set-extent-begin-glyph
(make-extent (point) (point))
(make-extent (point) (point))
(setq tab (make-glyph
[tab-control :descriptor "My Tab"
- :face default
+ :face highlight
:properties (:items (["One" foo]
- ["Two" foo]
+ ["Two" fee]
["Three" foo]))])))
;; progress gauge
(make-glyph
[button :face modeline-mousable
:descriptor "ok" :callback foo
- :image (make-glyph
- [xpm :file "../etc/xemacs-icon.xpm"])]))
+ :image [xpm :file "../etc/xemacs-icon.xpm"]]))
;; normal pushbutton
(set-extent-begin-glyph
;; edit box
(set-extent-begin-glyph
(make-extent (point) (point))
- (setq hedit (make-glyph [edit-field :pixel-width 50 :pixel-height 30
- :face bold-italic
- :descriptor ["Hello"]])))
+ (setq edit-field (make-glyph [edit-field :pixel-width 50 :pixel-height 30
+ :face bold-italic
+ :descriptor ["Hello"]])))
;; combo box
(set-extent-begin-glyph
(make-extent (point) (point))
- (setq hcombo (make-glyph
- [combo-box :width 10 :height 3 :descriptor ["Hello"]
- :properties (:items ("One" "Two" "Three"))])))
+ (setq combo-box (make-glyph
+ [combo-box :width 10 :descriptor ["Hello"]
+ :properties (:items ("One" "Two" "Three"))])))
+
+;; label
+(set-extent-begin-glyph
+ (make-extent (point) (point))
+ (setq label (make-glyph [label :pixel-width 150 :descriptor "Hello"])))
-;; line
+;; string
(set-extent-begin-glyph
(make-extent (point) (point))
- (make-glyph [label :pixel-width 150 :descriptor "Hello"]))
+ (setq str (make-glyph [string :data "Hello There"])))
;; scrollbar
;(set-extent-begin-glyph
(setq sw (make-glyph [subwindow :pixel-width 50 :pixel-height 70]))
(set-extent-begin-glyph (make-extent (point) (point)) sw)
+;; layout
+(setq layout
+ (make-glyph
+ [layout :pixel-width 200 :pixel-height 250
+ :orientation vertical
+ :justify left
+ :border [string :data "Hello There Mrs"]
+ :items ([layout :orientation horizontal
+ :items (radio-button1 radio-button2)]
+ edit-field toggle-button label str)]))
+(set-glyph-face layout 'gui-element)
+(set-extent-begin-glyph
+ (make-extent (point) (point)) layout)
+