/* Substantially rewritten for XEmacs. */
+/* 7-8-00 !!#### This file needs definite Mule review. */
+
#include <config.h>
#include "lisp.h"
#include "faces.h"
#include "frame.h"
#include "window.h"
+#include "gutter.h"
#ifdef HAVE_DRAGNDROP
#include "dragdrop.h"
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 structures 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);
void
x_wm_mark_shell_size_user_specified (Widget wmshell)
{
- if (! XtIsWMShell (wmshell)) abort ();
+ if (! XtIsWMShell (wmshell)) ABORT ();
EmacsShellSetSizeUserSpecified (wmshell);
}
void
x_wm_mark_shell_position_user_specified (Widget wmshell)
{
- if (! XtIsWMShell (wmshell)) abort ();
+ if (! XtIsWMShell (wmshell)) ABORT ();
EmacsShellSetPositionUserSpecified (wmshell);
}
void
x_wm_set_shell_iconic_p (Widget shell, int iconic_p)
{
- if (! XtIsWMShell (shell)) abort ();
+ if (! XtIsWMShell (shell)) ABORT ();
/* Because of questionable logic in Shell.c, this sequence can't work:
Arg al [2];
if (!XtIsWMShell (wmshell))
- abort ();
+ ABORT ();
if (cw <= 0 || ch <= 0)
- abort ();
+ ABORT ();
XtSetArg (al [0], XtNwidthInc, cw);
XtSetArg (al [1], XtNheightInc, ch);
Arg al [2];
if (!XtIsWMShell (wmshell))
- abort ();
+ ABORT ();
#ifdef DEBUG_GEOMETRY_MANAGEMENT
/* See comment in EmacsShell.c */
printf ("x_wm_set_variable_size: %d %d\n", width, height);
int need_delete = 1;
int need_focus = 1;
- if (!XtIsWMShell (widget))
- abort ();
+ assert (XtIsWMShell (widget));
{
Atom type, *atoms = 0;
XClassHint classhint;
if (!XtIsWMShell (shell))
- abort ();
+ ABORT ();
XtGetApplicationNameAndClass (dpy, &app_name, &app_class);
classhint.res_name = frame_name;
XSetClassHint (dpy, XtWindow (shell), &classhint);
}
-#ifndef HAVE_SESSION
+#ifndef HAVE_WMCOMMAND
static void
x_wm_maybe_store_wm_command (struct frame *f)
{
struct device *d = XDEVICE (FRAME_DEVICE (f));
if (!XtIsWMShell (w))
- abort ();
+ ABORT ();
if (NILP (DEVICE_X_WM_COMMAND_FRAME (d)))
{
}
}
-#endif /* !HAVE_SESSION */
+#endif /* !HAVE_WMCOMMAND */
static int
x_frame_iconified_p (struct frame *f)
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);
for (ptr = value; *ptr; ptr++)
if (!BYTE_ASCII_P (*ptr))
{
- CONST char * tmp;
+ const char * tmp;
encoding = DEVICE_XATOM_COMPOUND_TEXT (XDEVICE (FRAME_DEVICE (f)));
- GET_C_CHARPTR_EXT_CTEXT_DATA_ALLOCA ((CONST char *) value, tmp);
+ C_STRING_TO_EXTERNAL (value, tmp, Qctext);
new_XtValue = (String) tmp;
break;
}
#endif /* MULE */
- /* ### Caching is device-independent - belongs in update_frame_title. */
+ /* #### Caching is device-independent - belongs in update_frame_title. */
Xt_GET_VALUE (FRAME_X_SHELL_WIDGET (f), Xt_resource_name, &old_XtValue);
if (!old_XtValue || strcmp (new_XtValue, old_XtValue))
{
if (STRINGP (prop))
{
- CONST char *extprop;
+ const char *extprop;
if (XSTRING_LENGTH (prop) == 0)
continue;
- GET_C_STRING_CTEXT_DATA_ALLOCA (prop, extprop);
+ LISP_STRING_TO_EXTERNAL (prop, extprop, Qctext);
if (STRINGP (val))
{
- CONST Extbyte *extval;
+ const Extbyte *extval;
Extcount extvallen;
- GET_STRING_CTEXT_DATA_ALLOCA (val, extval, extvallen);
+ TO_EXTERNAL_FORMAT (LISP_STRING, val,
+ ALLOCA, (extval, extvallen),
+ Qctext);
XtVaSetValues (w, XtVaTypedArg, extprop,
XtRString, extval, extvallen + 1,
(XtArgVal) NULL);
{
for (i = 0; i < dragData->numItems; i++)
{
- XtFree(dragData->data.buffers[i].bp);
+ XtFree((char *) dragData->data.buffers[i].bp);
if (dragData->data.buffers[i].name)
XtFree(dragData->data.buffers[i].name);
}
unsigned int modifier = 0, state = 0;
char *Ctext;
int numItems = 0, textlen = 0, pos = 0;
- struct Lisp_Event *lisp_event = XEVENT(event);
+ Lisp_Event *lisp_event = XEVENT (event);
Lisp_Object item = Qnil;
struct gcpro gcpro1;
x_event.xbutton.y_root = lisp_event->event.button.y;
}
modifier = lisp_event->event.button.modifiers;
- if (modifier & MOD_SHIFT) state |= ShiftMask;
- if (modifier & MOD_CONTROL) state |= ControlMask;
- if (modifier & MOD_META) state |= xd->MetaMask;
- if (modifier & MOD_SUPER) state |= xd->SuperMask;
- if (modifier & MOD_HYPER) state |= xd->HyperMask;
- if (modifier & MOD_ALT) state |= xd->AltMask;
+ if (modifier & XEMACS_MOD_SHIFT) state |= ShiftMask;
+ if (modifier & XEMACS_MOD_CONTROL) state |= ControlMask;
+ if (modifier & XEMACS_MOD_META) state |= xd->MetaMask;
+ if (modifier & XEMACS_MOD_SUPER) state |= xd->SuperMask;
+ if (modifier & XEMACS_MOD_HYPER) state |= xd->HyperMask;
+ if (modifier & XEMACS_MOD_ALT) state |= xd->AltMask;
state |= Button1Mask << (lisp_event->event.button.button-1);
x_event.xbutton.state = state;
numItems++;
item = XCDR (item);
}
-
+
if (numItems)
{
/*
*/
Ctext = (char *)xmalloc (textlen+1);
Ctext[0] = 0;
-
+
item = dragdata;
while (!NILP (item))
{
Ctext=NULL;
break;
}
- strcpy (Ctext+pos, (CONST char *)XSTRING_DATA (XCAR (item)));
+ strcpy (Ctext+pos, (const char *)XSTRING_DATA (XCAR (item)));
pos += XSTRING_LENGTH (XCAR (item)) + 1;
item = XCDR (item);
}
Ctext[pos] = 0;
-
+
dnd_convert_cb_rec[0].callback = x_cde_convert_callback;
dnd_convert_cb_rec[0].closure = (XtPointer) Ctext;
dnd_convert_cb_rec[1].callback = NULL;
dnd_convert_cb_rec[1].closure = NULL;
-
+
dnd_destroy_cb_rec[0].callback = x_cde_destroy_callback;
dnd_destroy_cb_rec[0].closure = (XtPointer) Ctext;
dnd_destroy_cb_rec[1].callback = NULL;
}
UNGCPRO;
-
+
return numItems?Qt:Qnil;
}
{
filePath = transferInfo->dropData->data.files[ii];
hurl = dnd_url_hexify_string ((char *)filePath, "file:");
- /* ### Mule-izing required */
+ /* #### Mule-izing required */
l_data = Fcons (make_string ((Bufbyte* )hurl,
strlen (hurl)),
l_data);
/* what, if the data is no text, and how can I tell it? */
l_data = Fcons ( list3 ( list1 ( make_string ((Bufbyte *)"text/plain", 10) ),
make_string ((Bufbyte *)"8bit", 4),
- make_string ((Bufbyte *)transferInfo->dropData->data.buffers[ii].bp,
+ make_string ((Bufbyte *)transferInfo->dropData->data.buffers[ii].bp,
transferInfo->dropData->data.buffers[ii].size) ),
l_data );
}
enqueue=0;
/* The Problem: no button and mods from CDE... */
- if (enqueue)
+ if (enqueue)
enqueue_misc_user_event_pos ( frame, Qdragdrop_drop_dispatch,
Fcons (l_type, l_data),
0 /* this is the button */,
char *dnd_data = NULL;
unsigned long dnd_len = 0;
int dnd_typ = DndText, dnd_dealloc = 0;
- struct Lisp_Event *lisp_event = XEVENT(event);
+ Lisp_Event *lisp_event = XEVENT (event);
/* only drag if this is really a press */
if (EVENT_TYPE(lisp_event) != button_press_event)
}
len = XSTRING_LENGTH (XCAR (run)) + 1;
dnd_data = (char *) xrealloc (dnd_data, dnd_len + len);
- strcpy (dnd_data + dnd_len - 1, (CONST char *)XSTRING_DATA (XCAR (run)));
+ strcpy (dnd_data + dnd_len - 1, (const char *)XSTRING_DATA (XCAR (run)));
dnd_len += len;
run = XCDR (run);
}
if (!STRINGP (data))
return Qnil;
- /* and whats with MULE data ??? */
+ /* and what's with MULE data ??? */
dnd_data = (char *)XSTRING_DATA (data);
dnd_len = XSTRING_LENGTH (data) + 1; /* the zero */
}
- /*
- * not so cross hack that converts a emacs event back to a XEvent
- */
+ /* not so gross hack that converts an emacs event back to a XEvent */
x_event.xbutton.type = ButtonPress;
x_event.xbutton.send_event = False;
}
modifier = lisp_event->event.button.modifiers;
- if (modifier & MOD_SHIFT) state |= ShiftMask;
- if (modifier & MOD_CONTROL) state |= ControlMask;
- if (modifier & MOD_META) state |= xd->MetaMask;
- if (modifier & MOD_SUPER) state |= xd->SuperMask;
- if (modifier & MOD_HYPER) state |= xd->HyperMask;
- if (modifier & MOD_ALT) state |= xd->AltMask;
+ if (modifier & XEMACS_MOD_SHIFT) state |= ShiftMask;
+ if (modifier & XEMACS_MOD_CONTROL) state |= ControlMask;
+ if (modifier & XEMACS_MOD_META) state |= xd->MetaMask;
+ if (modifier & XEMACS_MOD_SUPER) state |= xd->SuperMask;
+ if (modifier & XEMACS_MOD_HYPER) state |= xd->HyperMask;
+ if (modifier & XEMACS_MOD_ALT) state |= xd->AltMask;
state |= Button1Mask << (lisp_event->event.button.button-1);
x_event.xbutton.state = state;
{
struct window *win = XWINDOW (f->root_window);
- WINDOW_LEFT (win) = FRAME_LEFT_BORDER_END (f);
- WINDOW_TOP (win) = FRAME_TOP_BORDER_END (f);
+ WINDOW_LEFT (win) = FRAME_LEFT_BORDER_END (f)
+ + FRAME_LEFT_GUTTER_BOUNDS (f);
+ WINDOW_TOP (win) = FRAME_TOP_BORDER_END (f)
+ + FRAME_TOP_GUTTER_BOUNDS (f);
if (!NILP (f->minibuffer_window))
{
win = XWINDOW (f->minibuffer_window);
- WINDOW_LEFT (win) = FRAME_LEFT_BORDER_END (f);
+ WINDOW_LEFT (win) = FRAME_LEFT_BORDER_END (f)
+ + FRAME_LEFT_GUTTER_BOUNDS (f);
}
}
/* OK, we're a top-level shell. */
if (!XtIsWMShell (wmshell))
- abort ();
+ ABORT ();
/* If the EmacsFrame doesn't have a geometry but the shell does,
treat that as the geometry of the frame.
#endif
/* finally the text area */
- XtConfigureWidget (text, text_x, text_y,
- width - 2*textbord,
- height - text_y - 2*textbord,
- textbord);
+ {
+ Dimension nw = width - 2*textbord;
+ Dimension nh = height - text_y - 2*textbord;
+
+ if (nh != f->pixheight || nw != f->pixwidth)
+ MARK_FRAME_SIZE_SLIPPED (f);
+ XtConfigureWidget (text, text_x, text_y, nw, nh, textbord);
+ }
}
static void
#ifdef EXTERNAL_WIDGET
Window window_id = 0;
#endif
- CONST char *name;
+ const char *name;
Arg al [25];
int ac = 0;
Widget text, container, shell;
#endif
if (STRINGP (f->name))
- GET_C_STRING_CTEXT_DATA_ALLOCA (f->name, name);
+ LISP_STRING_TO_EXTERNAL (f->name, name, Qctext);
else
name = "emacs";
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
XtSetArg (al[ac], XtNinput, True); ac++;
XtSetArg (al[ac], XtNminWidthCells, 10); ac++;
XtSetArg (al[ac], XtNminHeightCells, 1); ac++;
- XtSetArg (al[ac], XtNvisual, visual); ac++;
- XtSetArg (al[ac], XtNdepth, depth); ac++;
- XtSetArg (al[ac], XtNcolormap, cmap); ac++;
+ XtSetArg (al[ac], XtNvisual, visual); ac++;
+ XtSetArg (al[ac], XtNdepth, depth); ac++;
+ XtSetArg (al[ac], XtNcolormap, cmap); ac++;
}
if (!NILP (parent))
though, the failure to call the popup callbacks resulted in XEmacs
not accepting any input. Bizarre but true. Stupid but true.
- So, in case there are any other gotches floating out there along
+ So, in case there are any other gotchas floating out there along
the same lines I've duplicated the majority of XtPopup here. It
assumes no grabs and that the widget is not already popped up, both
valid assumptions for the one place this is called from. */
Xt_SET_VALUE (widget, XtNmappedWhenManaged, True);
}
-#ifdef HAVE_CDE
-/* Does this have to be non-automatic? */
-/* hack frame to respond to dnd messages */
-static XtCallbackRec dnd_transfer_cb_rec[2];
-#endif /* HAVE_CDE */
-
/* create the windows for the specified frame and display them.
Note that the widgets have already been created, and any
necessary geometry calculations have already been done. */
/* tell the window manager about us. */
x_wm_store_class_hints (shell_widget, XtName (frame_widget));
-#ifndef HAVE_SESSION
+#ifndef HAVE_WMCOMMAND
x_wm_maybe_store_wm_command (f);
-#endif /* HAVE_SESSION */
+#endif /* HAVE_WMCOMMAND */
x_wm_hack_wm_protocols (shell_widget);
}
#ifdef HACK_EDITRES
/* Allow XEmacs to respond to EditRes requests. See the O'Reilly Xt */
- /* Instrinsics Programming Manual, Motif Edition, Aug 1993, Sect 14.14, */
+ /* Intrinsics Programming Manual, Motif Edition, Aug 1993, Sect 14.14, */
/* pp. 483-493. */
XtAddEventHandler (shell_widget, /* the shell widget in question */
(EventMask) NoEventMask,/* OR with existing mask */
#ifdef HAVE_CDE
{
+ XtCallbackRec dnd_transfer_cb_rec[2];
+
dnd_transfer_cb_rec[0].callback = x_cde_transfer_callback;
dnd_transfer_cb_rec[0].closure = (XtPointer) f;
dnd_transfer_cb_rec[1].callback = NULL;
DtDND_FILENAME_TRANSFER | DtDND_BUFFER_TRANSFER,
XmDROP_COPY, dnd_transfer_cb_rec,
DtNtextIsBuffer, True,
- DtNregisterChildren, True,
+ DtNregisterChildren, True,
DtNpreserveRegistration, False,
NULL);
}
* will update the frame title anyway, so nothing is lost.
* JV:
* It turns out it gives problems with FVWMs name based mapping.
- * We'll just need to be carefull in the modeline specs.
+ * We'll just need to be careful in the modeline specs.
*/
- update_frame_title (f);
+ update_frame_title (f);
}
static void
}
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
}
}
+static void
+x_enable_frame (struct frame *f)
+{
+ XtSetSensitive (FRAME_X_SHELL_WIDGET (f), True);
+}
+
+static void
+x_disable_frame (struct frame *f)
+{
+ XtSetSensitive (FRAME_X_SHELL_WIDGET (f), False);
+}
+
/* Change from withdrawn state to mapped state. */
static void
x_make_frame_visible (struct frame *f)
XFlush (XtDisplay (shell_widget)); /* hey, I'd like to DEBUG this... */
}
-/* Destroy the X window of frame S. */
+/* Destroy the X window of frame F. */
static void
x_delete_frame (struct frame *f)
{
- Widget w = FRAME_X_SHELL_WIDGET (f);
- Display *dpy = XtDisplay (w);
+ Display *dpy;
-#ifndef HAVE_SESSION
+#ifndef HAVE_WMCOMMAND
if (FRAME_X_TOP_LEVEL_FRAME_P (f))
x_wm_maybe_move_wm_command (f);
-#endif /* HAVE_SESSION */
+#endif /* HAVE_WMCOMMAND */
+
+#ifdef HAVE_CDE
+ DtDndDropUnregister (FRAME_X_TEXT_WIDGET (f));
+#endif /* HAVE_CDE */
+
+ assert (FRAME_X_SHELL_WIDGET (f) != 0);
+ dpy = XtDisplay (FRAME_X_SHELL_WIDGET (f));
#ifdef EXTERNAL_WIDGET
expect_x_error (dpy);
window-to-widget hierarchy maintained by Xt, we have to call
XtUnrealizeWidget() here. Xt can really suck. */
if (f->being_deleted)
- XtUnrealizeWidget (w);
- XtDestroyWidget (w);
+ XtUnrealizeWidget (FRAME_X_SHELL_WIDGET (f));
+ XtDestroyWidget (FRAME_X_SHELL_WIDGET (f));
x_error_occurred_p (dpy);
#else
- XtDestroyWidget (w);
- XFlush (dpy); /* make sure the windows are really gone! */
+ XtDestroyWidget (FRAME_X_SHELL_WIDGET (f));
+ /* make sure the windows are really gone! */
+ /* #### Is this REALLY necessary? */
+ XFlush (dpy);
#endif /* EXTERNAL_WIDGET */
+ FRAME_X_SHELL_WIDGET (f) = 0;
+
if (FRAME_X_GEOM_FREE_ME_PLEASE (f))
- xfree (FRAME_X_GEOM_FREE_ME_PLEASE (f));
- xfree (f->frame_data);
- f->frame_data = 0;
+ {
+ xfree (FRAME_X_GEOM_FREE_ME_PLEASE (f));
+ FRAME_X_GEOM_FREE_ME_PLEASE (f) = 0;
+ }
+
+ if (f->frame_data)
+ {
+ xfree (f->frame_data);
+ f->frame_data = 0;
+ }
}
static void
x_update_frame_external_traits (struct frame* frm, Lisp_Object name)
{
- Arg av[10];
+ Arg al[10];
int ac = 0;
- Lisp_Object frame = Qnil;
+ Lisp_Object frame;
XSETFRAME(frame, frm);
if (!EQ (color, Vthe_null_color_instance))
{
fgc = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (color));
- XtSetArg (av[ac], XtNforeground, (void *) fgc.pixel); ac++;
+ XtSetArg (al[ac], XtNforeground, (void *) fgc.pixel); ac++;
}
}
else if (EQ (name, Qbackground))
if (!EQ (color, Vthe_null_color_instance))
{
bgc = COLOR_INSTANCE_X_COLOR (XCOLOR_INSTANCE (color));
- XtSetArg (av[ac], XtNbackground, (void *) bgc.pixel); ac++;
+ XtSetArg (al[ac], XtNbackground, (void *) bgc.pixel); ac++;
}
/* Really crappy way to force the modeline shadows to be
Lisp_Object font = FACE_FONT (Vdefault_face, frame, Vcharset_ascii);
if (!EQ (font, Vthe_null_font_instance))
- XtSetArg (av[ac], XtNfont,
- (void *) FONT_INSTANCE_X_FONT (XFONT_INSTANCE (font)));
- ac++;
+ {
+ XtSetArg (al[ac], XtNfont,
+ (void *) FONT_INSTANCE_X_FONT (XFONT_INSTANCE (font)));
+ ac++;
+ }
}
else
- abort ();
+ ABORT ();
- XtSetValues (FRAME_X_TEXT_WIDGET (frm), av, ac);
+ XtSetValues (FRAME_X_TEXT_WIDGET (frm), al, ac);
#ifdef HAVE_TOOLBARS
/* Setting the background clears the entire frame area
CONSOLE_HAS_METHOD (x, set_mouse_position);
CONSOLE_HAS_METHOD (x, raise_frame);
CONSOLE_HAS_METHOD (x, lower_frame);
+ CONSOLE_HAS_METHOD (x, enable_frame);
+ CONSOLE_HAS_METHOD (x, disable_frame);
CONSOLE_HAS_METHOD (x, make_frame_visible);
CONSOLE_HAS_METHOD (x, make_frame_invisible);
CONSOLE_HAS_METHOD (x, iconify_frame);