+2003-11-16 Jan Dj\e,Ad\e(Brv <jan.h.d@swipnet.se>
+
+ * xfns.c (x_window_to_frame, x_any_window_to_frame)
+ (x_non_menubar_window_to_frame, x_menubar_window_to_frame)
+ (x_top_window_to_frame): Add Display* argument to xg_win_to_widget.
+ (x_create_bitmap_mask, xg_set_icon, create_frame_xic)
+ (xic_set_statusarea, x_window, gif_load): Formatting adjustments.
+
+ * xterm.h (struct x_display_info): New field xg_cursor for GTK.
+
+ * xterm.c: Add Display * to x_window_to_scroll_bar declaration.
+ (XTmouse_position, handle_one_xevent): Pass Display* to
+ x_window_to_scroll_bar.
+ (x_window_to_scroll_bar): Take a Display* argument.
+ Check that display for frame is equal to Display* argument.
+ (event_handler_gdk): current_dpyinfo removed. Get dpyinfo from
+ x_display_info_for_display instead. Use Display in xev instead
+ of GDK_DISPLAY.
+ (x_dispatch_event): Call x_display_info_for_display.
+ (XTread_socket): Move GTK part out of loop. current_dpyinfo removed.
+ (x_connection_closed): Call xg_display_close for GTK.
+ (x_term_init): Call xg_display_open for additional displays.
+ Initiate dpyinfo->xg_cursor with call to xg_create_default_cursor
+ for GTK.
+
+ * xmenu.c (single_menu_item, mouse_position_for_popup)
+ (x_activate_menubar): Formatting adjustments.
+
+ * xdisp.c (update_tool_bar, redisplay_tool_bar): Formatting
+ adjustments.
+
+ * gtkutil.c (xg_get_gdk_display, xg_set_screen, xg_display_open)
+ (xg_display_close, xg_create_default_cursor)
+ (xg_get_gdk_pixmap_and_mask): New functions for multiple display
+ handling.
+ (xg_left_ptr_cursor): Removed.
+ (xg_set_cursor): cursor changed to GdkCursor*. Do not create
+ cursor here.
+ (xg_win_to_widget): Take Display* argument, call
+ gdk_xid_table_lookup_for_display.
+ (xg_create_frame_widgets, xg_get_file_name, create_menus)
+ (xg_create_widget, xg_modify_menubar_widgets): Call xg_set_screen.
+ (xg_create_widget, xg_create_scroll_bar): Use xg_cursor
+ in FRAME_X_DISPLAY_INFO.
+ (xg_get_scroll_id_for_window): Take Display* argument.
+ (update_frame_tool_bar): Call xg_get_gdk_pixmap_and_mask.
+ (xg_initialize): xg_left_ptr_cursor removed.
+
+ * gtkutil.h: xg_get_scroll_id_for_window, xg_win_to_widget takes
+ Display* argument also. Declare xg_display_open,
+ xg_display_close, xg_create_default_cursor.
+
2003-11-14 Jan Dj\e,Ad\e(Brv <jan.h.d@swipnet.se>
* xterm.c (x_detect_focus_change): Do not change focus frame for
#include "coding.h"
#include <gdk/gdkkeysyms.h>
+
#define FRAME_TOTAL_PIXEL_HEIGHT(f) \
(FRAME_PIXEL_HEIGHT (f) + FRAME_MENUBAR_HEIGHT (f) + FRAME_TOOLBAR_HEIGHT (f))
+\f
+/***********************************************************************
+ Display handling functions
+ ***********************************************************************/
+
+#ifdef HAVE_GTK_MULTIDISPLAY
+
+/* Return the GdkDisplay that corresponds to the X display DPY. */
+static GdkDisplay *
+xg_get_gdk_display (dpy)
+ Display *dpy;
+{
+ return gdk_x11_lookup_xdisplay (dpy);
+}
+
+/* When the GTK widget W is to be created on a display for F that
+ is not the default display, set the display for W.
+ W can be a GtkMenu or a GtkWindow widget. */
+static void
+xg_set_screen (w, f)
+ GtkWidget *w;
+ FRAME_PTR f;
+{
+ if (FRAME_X_DISPLAY (f) != GDK_DISPLAY ())
+ {
+ GdkDisplay *gdpy = gdk_x11_lookup_xdisplay (FRAME_X_DISPLAY (f));
+ GdkScreen *gscreen = gdk_display_get_default_screen (gdpy);
+
+ if (GTK_IS_MENU (w))
+ gtk_menu_set_screen (GTK_MENU (w), gscreen);
+ else
+ gtk_window_set_screen (GTK_WINDOW (w), gscreen);
+ }
+}
+
+
+#else /* not HAVE_GTK_MULTIDISPLAY */
+
+/* Make some defines so we can use the GTK 2.2 functions when
+ compiling with GTK 2.0. */
+#define xg_set_screen(w, f)
+#define gdk_xid_table_lookup_for_display(dpy, w) gdk_xid_table_lookup (w)
+#define gdk_pixmap_foreign_new_for_display(dpy, p) gdk_pixmap_foreign_new (p)
+#define gdk_cursor_new_for_display(dpy, c) gdk_cursor_new (c)
+#define gdk_x11_lookup_xdisplay(dpy) 0
+#define GdkDisplay void
+
+#endif /* not HAVE_GTK_MULTIDISPLAY */
+
+/* Open a display named by DISPLAY_NAME. The display is returned in *DPY.
+ *DPY is set to NULL if the display can't be opened.
+
+ Returns non-zero if display could be opened, zero if display could not
+ be opened, and less than zero if the GTK version doesn't support
+ multipe displays. */
+int
+xg_display_open (display_name, dpy)
+ char *display_name;
+ Display **dpy;
+{
+#ifdef HAVE_GTK_MULTIDISPLAY
+ GdkDisplay *gdpy;
+
+ gdpy = gdk_display_open (display_name);
+ *dpy = gdpy ? GDK_DISPLAY_XDISPLAY (gdpy) : NULL;
+
+ return gdpy != NULL;
+
+#else /* not HAVE_GTK_MULTIDISPLAY */
+
+ return -1;
+#endif /* not HAVE_GTK_MULTIDISPLAY */
+}
+
+
+void
+xg_display_close (Display *dpy)
+{
+#ifdef HAVE_GTK_MULTIDISPLAY
+ GdkDisplay *gdpy = gdk_x11_lookup_xdisplay (dpy);
+
+ /* GTK 2.2 has a bug that makes gdk_display_close crash (bug
+ http://bugzilla.gnome.org/show_bug.cgi?id=85715). This way
+ we can continue running, but there will be memory leaks. */
+
+#if GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION < 4
+
+ /* If this is the default display, we must change it before calling
+ dispose, otherwise it will crash. */
+ if (gdk_display_get_default () == gdpy)
+ {
+ struct x_display_info *dpyinfo;
+ Display *new_dpy = 0;
+ GdkDisplay *gdpy_new;
+
+ /* Find another display. */
+ for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next)
+ if (dpyinfo->display != dpy)
+ {
+ new_dpy = dpyinfo->display;
+ break;
+ }
+
+ if (! new_dpy) return; /* Emacs will exit anyway. */
+
+ gdpy_new = gdk_x11_lookup_xdisplay (new_dpy);
+ gdk_display_manager_set_default_display (gdk_display_manager_get (),
+ gdpy_new);
+ }
+
+ g_object_run_dispose (G_OBJECT (gdpy));
+
+#else
+ /* I hope this will be fixed in GTK 2.4. It is what bug 85715 says. */
+ gdk_display_close (gdpy);
+#endif
+#endif /* HAVE_GTK_MULTIDISPLAY */
+}
\f
/***********************************************************************
NULL if no timer is started. */
static struct atimer *xg_timer;
-/* The cursor used for scroll bars and popup menus.
- We only have one cursor for all scroll bars and all popup menus. */
-static GdkCursor *xg_left_ptr_cursor;
-
/* The next two variables and functions are taken from lwlib. */
static widget_value *widget_value_free_list;
}
}
-/* Set *CURSOR on W and all widgets W contain. We must do like this
- for scroll bars and menu because they create widgets internally,
- and it is those widgets that are visible.
- If *CURSOR is NULL, create a GDK_LEFT_PTR cursor and set *CURSOR to
- the created cursor. */
-void
+/* Create and return the cursor to be used for popup menus and
+ scroll bars on display DPY. */
+GdkCursor *
+xg_create_default_cursor (dpy)
+ Display *dpy;
+{
+ GdkDisplay *gdpy = gdk_x11_lookup_xdisplay (dpy);
+ return gdk_cursor_new_for_display (gdpy, GDK_LEFT_PTR);
+}
+
+/* For the image defined in IMG, make and return a GdkPixmap for
+ the pixmap in *GPIX, and a GdkBitmap for the mask in *GMASK.
+ If IMG has no mask, *GMASK is set to NULL.
+ The image is defined on the display where frame F is. */
+static void
+xg_get_gdk_pixmap_and_mask (f, img, gpix, gmask)
+ FRAME_PTR f;
+ struct image *img;
+ GdkPixmap **gpix;
+ GdkBitmap **gmask;
+{
+ GdkDisplay *gdpy = gdk_x11_lookup_xdisplay (FRAME_X_DISPLAY (f));
+
+ *gpix = gdk_pixmap_foreign_new_for_display (gdpy, img->pixmap);
+ *gmask = img->mask ?
+ (GdkBitmap*) gdk_pixmap_foreign_new_for_display (gdpy, img->mask)
+ : 0;
+}
+
+
+/* Set CURSOR on W and all widgets W contain. We must do like this
+ for scroll bars and menu because they create widgets internally,
+ and it is those widgets that are visible. */
+static void
xg_set_cursor (w, cursor)
GtkWidget *w;
- GdkCursor **cursor;
+ GdkCursor *cursor;
{
GList *children = gdk_window_peek_children (w->window);
- /* Create the cursor unless already created. */
- if (! *cursor)
- *cursor = gdk_cursor_new (GDK_LEFT_PTR);
-
- gdk_window_set_cursor (w->window, *cursor);
+ gdk_window_set_cursor (w->window, cursor);
/* The scroll bar widget has more than one GDK window (had to look at
the source to figure this out), and there is no way to set cursor
Ditto for menus. */
for ( ; children; children = g_list_next (children))
- gdk_window_set_cursor (GDK_WINDOW (children->data), *cursor);
+ gdk_window_set_cursor (GDK_WINDOW (children->data), cursor);
}
/* Timer function called when a timeout occurs for xg_timer.
cancel_mouse_face (f);
}
-/* Convert an X Window WSESC to its corresponding GtkWidget.
+/* Convert an X Window WSESC on display DPY to its corresponding GtkWidget.
Must be done like this, because GtkWidget:s can have "hidden"
X Window that aren't accessible.
Return 0 if no widget match WDESC. */
GtkWidget *
-xg_win_to_widget (wdesc)
+xg_win_to_widget (dpy, wdesc)
+ Display *dpy;
Window wdesc;
{
gpointer gdkwin;
GtkWidget *gwdesc = 0;
BLOCK_INPUT;
- gdkwin = gdk_xid_table_lookup (wdesc);
+
+ gdkwin = gdk_xid_table_lookup_for_display (gdk_x11_lookup_xdisplay (dpy),
+ wdesc);
if (gdkwin)
{
GdkEvent event;
Return TRUE to tell GTK that this expose event has been fully handeled
and that GTK shall do nothing more with it. */
static gboolean
-xg_fixed_handle_expose(GtkWidget *widget,
- GdkEventExpose *event,
- gpointer user_data)
+xg_fixed_handle_expose (GtkWidget *widget,
+ GdkEventExpose *event,
+ gpointer user_data)
{
GList *iter;
BLOCK_INPUT;
wtop = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ xg_set_screen (wtop, f);
+
wvbox = gtk_vbox_new (FALSE, 0);
wfixed = gtk_fixed_new (); /* Must have this to place scroll bars */
gtk_fixed_set_has_window (GTK_FIXED (wfixed), TRUE);
- gtk_widget_set_size_request (wfixed, FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f));
+ gtk_widget_set_size_request (wfixed, FRAME_PIXEL_WIDTH (f),
+ FRAME_PIXEL_HEIGHT (f));
gtk_container_add (GTK_CONTAINER (wtop), wvbox);
gtk_box_pack_end (GTK_BOX (wvbox), wfixed, TRUE, TRUE, 0);
filewin = gtk_file_selection_new (prompt);
filesel = GTK_FILE_SELECTION (filewin);
+ xg_set_screen (filewin, f);
+
gtk_widget_set_name (filewin, "emacs-filedialog");
gtk_window_set_transient_for (GTK_WINDOW (filewin),
if (! topmenu)
{
- if (! menu_bar_p) wmenu = gtk_menu_new ();
+ if (! menu_bar_p)
+ {
+ wmenu = gtk_menu_new ();
+ xg_set_screen (wmenu, f);
+ }
else wmenu = gtk_menu_bar_new ();
/* Put cl_data on the top menu for easier access. */
if (strcmp (type, "dialog") == 0)
{
w = create_dialog (val, select_cb, deactivate_cb);
+ xg_set_screen (w, f);
gtk_window_set_transient_for (GTK_WINDOW (w),
GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)));
gtk_window_set_destroy_with_parent (GTK_WINDOW (w), TRUE);
-
- if (w)
- gtk_widget_set_name (w, "emacs-dialog");
+ gtk_widget_set_name (w, "emacs-dialog");
}
else if (menu_bar_p || pop_up_p)
{
{
/* Must realize so the GdkWindow inside the widget is created. */
gtk_widget_realize (w);
- xg_set_cursor (w, &xg_left_ptr_cursor);
+ xg_set_cursor (w, FRAME_X_DISPLAY_INFO (f)->xg_cursor);
}
}
else
a new menu bar item, it has no sub menu yet. So we set the
newly created sub menu under witem. */
if (newsub != sub)
- gtk_menu_item_set_submenu (witem, newsub);
+ {
+ xg_set_screen (newsub, f);
+ gtk_menu_item_set_submenu (witem, newsub);
+ }
}
}
return 0;
}
-/* Return the scrollbar id for X Window WID.
+/* Return the scrollbar id for X Window WID on display DPY.
Return -1 if WID not in id_to_widget. */
int
-xg_get_scroll_id_for_window (wid)
+xg_get_scroll_id_for_window (dpy, wid)
+ Display *dpy;
Window wid;
{
int idx;
GtkWidget *w;
- w = xg_win_to_widget (wid);
+ w = xg_win_to_widget (dpy, wid);
if (w)
{
wscroll, -1, -1);
/* Set the cursor to an arrow. */
- xg_set_cursor (wscroll, &xg_left_ptr_cursor);
+ xg_set_cursor (wscroll, FRAME_X_DISPLAY_INFO (f)->xg_cursor);
SET_SCROLL_BAR_X_WINDOW (bar, scroll_id);
}
event->area.x -= width > event->area.width ? width-event->area.width : 0;
event->area.y -= height > event->area.height ? height-event->area.height : 0;
- event->area.x = max(0, event->area.x);
- event->area.y = max(0, event->area.y);
+ event->area.x = max (0, event->area.x);
+ event->area.y = max (0, event->area.y);
event->area.width = max (width, event->area.width);
event->area.height = max (height, event->area.height);
GdkEventExpose *event;
gpointer client_data;
{
- update_frame_tool_bar((FRAME_PTR)client_data);
+ update_frame_tool_bar ((FRAME_PTR) client_data);
return FALSE;
}
if (! wicon)
{
- GdkPixmap *gpix = gdk_pixmap_foreign_new (img->pixmap);
- GdkBitmap *gmask = img->mask ?
- (GdkBitmap*) gdk_pixmap_foreign_new (img->mask) : 0;
+ GdkPixmap *gpix;
+ GdkBitmap *gmask;
+ GtkWidget *w;
- GtkWidget *w = gtk_image_new_from_pixmap (gpix, gmask);
+ xg_get_gdk_pixmap_and_mask (f, img, &gpix, &gmask);
+ w = gtk_image_new_from_pixmap (gpix, gmask);
gtk_toolbar_append_item (GTK_TOOLBAR (x->toolbar_widget),
0, 0, 0,
w,
if (old_img != img->pixmap)
{
- GdkPixmap *gpix = gdk_pixmap_foreign_new (img->pixmap);
- GdkBitmap *gmask = img->mask ?
- (GdkBitmap*) gdk_pixmap_foreign_new (img->mask) : 0;
+ GdkPixmap *gpix;
+ GdkBitmap *gmask;
+ xg_get_gdk_pixmap_and_mask (f, img, &gpix, &gmask);
gtk_image_set_from_pixmap (wimage, gpix, gmask);
}
xg_initialize ()
{
xg_ignore_gtk_scrollbar = 0;
- xg_left_ptr_cursor = 0;
xg_detached_menus = 0;
xg_menu_cb_list.prev = xg_menu_cb_list.next =
xg_menu_item_cb_list.prev = xg_menu_item_cb_list.next = 0;
extern int xg_have_tear_offs P_ ((void));
-extern int xg_get_scroll_id_for_window P_ ((Window wid));
+extern int xg_get_scroll_id_for_window P_ ((Display *dpy, Window wid));
extern void xg_create_scroll_bar P_ ((FRAME_PTR f,
struct scroll_bar *bar,
int pixelheight));
extern void xg_frame_cleared P_ ((FRAME_PTR f));
extern void xg_frame_set_char_size P_ ((FRAME_PTR f, int cols, int rows));
-extern GtkWidget * xg_win_to_widget P_ ((Window));
+extern GtkWidget * xg_win_to_widget P_ ((Display *dpy, Window wdesc));
+
+extern int xg_display_open P_ ((char *display_name, Display **dpy));
+extern void xg_display_close P_ ((Display *dpy));
+extern GdkCursor * xg_create_default_cursor P_ ((Display *dpy));
+
extern int xg_create_frame_widgets P_ ((FRAME_PTR f));
extern void x_wm_set_size_hint P_ ((FRAME_PTR f,
long flags,
int save_match_data;
{
#ifdef USE_GTK
- int do_update = FRAME_EXTERNAL_TOOL_BAR(f);
+ int do_update = FRAME_EXTERNAL_TOOL_BAR (f);
#else
int do_update = WINDOWP (f->tool_bar_window)
&& WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)) > 0;
int change_height_p = 0;
#ifdef USE_GTK
- if (FRAME_EXTERNAL_TOOL_BAR(f))
+ if (FRAME_EXTERNAL_TOOL_BAR (f))
update_frame_tool_bar (f);
return 0;
#endif
#ifdef USE_GTK
if (f->output_data.x->edit_widget)
{
- GtkWidget *gwdesc = xg_win_to_widget (wdesc);
+ GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
struct x_output *x = f->output_data.x;
if (gwdesc != 0 && gwdesc == x->edit_widget)
return f;
else if (x->widget)
{
#ifdef USE_GTK
- GtkWidget *gwdesc = xg_win_to_widget (wdesc);
+ GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
if (gwdesc != 0
&& (gwdesc == x->widget
|| gwdesc == x->edit_widget
else if (x->widget)
{
#ifdef USE_GTK
- GtkWidget *gwdesc = xg_win_to_widget (wdesc);
+ GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
if (gwdesc != 0
&& (gwdesc == x->widget
|| gwdesc == x->edit_widget
#ifdef USE_GTK
if (x->menubar_widget)
{
- GtkWidget *gwdesc = xg_win_to_widget (wdesc);
+ GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
int found = 0;
BLOCK_INPUT;
{
/* This frame matches if the window is its topmost widget. */
#ifdef USE_GTK
- GtkWidget *gwdesc = xg_win_to_widget (wdesc);
+ GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
if (gwdesc == x->widget)
return f;
#else
It's nicer with some borders in this context */
int
-x_create_bitmap_mask(f, id)
+x_create_bitmap_mask (f, id)
struct frame *f;
int id;
{
if (!(id > 0))
return -1;
- pixmap = x_bitmap_pixmap(f, id);
- width = x_bitmap_width(f, id);
- height = x_bitmap_height(f, id);
+ pixmap = x_bitmap_pixmap (f, id);
+ width = x_bitmap_width (f, id);
+ height = x_bitmap_height (f, id);
BLOCK_INPUT;
ximg = XGetImage (FRAME_X_DISPLAY (f), pixmap, 0, 0, width, height,
UNBLOCK_INPUT;
if (!result)
{
- XDestroyImage(ximg);
+ XDestroyImage (ximg);
return -1;
}
dpyinfo->bitmaps[id - 1].mask = mask;
XDestroyImage (ximg);
- x_destroy_x_image(mask_img);
+ x_destroy_x_image (mask_img);
return 0;
}
may be any format that GdkPixbuf knows about, i.e. not just bitmaps. */
int
-xg_set_icon(f, file)
+xg_set_icon (f, file)
FRAME_PTR f;
Lisp_Object file;
{
xic = XCreateIC (xim,
XNInputStyle, xic_style,
- XNClientWindow, FRAME_X_WINDOW(f),
- XNFocusWindow, FRAME_X_WINDOW(f),
+ XNClientWindow, FRAME_X_WINDOW (f),
+ XNFocusWindow, FRAME_X_WINDOW (f),
XNStatusAttributes, status_attr,
XNPreeditAttributes, preedit_attr,
NULL);
XFree (needed);
attr = XVaCreateNestedList (0, XNArea, &area, NULL);
- XSetICValues(xic, XNStatusAttributes, attr, NULL);
+ XSetICValues (xic, XNStatusAttributes, attr, NULL);
XFree (attr);
}
{
/* XIM server might require some X events. */
unsigned long fevent = NoEventMask;
- XGetICValues(FRAME_XIC (f), XNFilterEvents, &fevent, NULL);
+ XGetICValues (FRAME_XIC (f), XNFilterEvents, &fevent, NULL);
attributes.event_mask |= fevent;
}
#endif /* HAVE_X_I18N */
{
/* XIM server might require some X events. */
unsigned long fevent = NoEventMask;
- XGetICValues(FRAME_XIC (f), XNFilterEvents, &fevent, NULL);
+ XGetICValues (FRAME_XIC (f), XNFilterEvents, &fevent, NULL);
if (fevent != NoEventMask)
{
{
/* XIM server might require some X events. */
unsigned long fevent = NoEventMask;
- XGetICValues(FRAME_XIC (f), XNFilterEvents, &fevent, NULL);
+ XGetICValues (FRAME_XIC (f), XNFilterEvents, &fevent, NULL);
attributes.event_mask |= fevent;
attribute_mask = CWEventMask;
XChangeWindowAttributes (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
memsrc.len = SBYTES (specified_data);
memsrc.index = 0;
- gif = DGifOpen(&memsrc, gif_read_from_memory);
+ gif = DGifOpen (&memsrc, gif_read_from_memory);
if (!gif)
{
image_error ("Cannot open memory source `%s'", img->spec, Qnil);
#endif /* not HAVE_BOXES */
#if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
- if (!NILP(map))
+ if (!NILP (map))
/* Indicate visually that this is a submenu. */
item_string = concat2 (item_string, build_string (" >"));
#endif
the scroll bar or the edit window. Fx_popup_menu needs to be
sure it is the edit window. */
static void
-mouse_position_for_popup(f, x, y)
+mouse_position_for_popup (f, x, y)
FRAME_PTR f;
int *x;
int *y;
return;
#ifdef USE_GTK
- if (! xg_win_to_widget (f->output_data.x->saved_menu_event->xany.window))
+ if (! xg_win_to_widget (FRAME_X_DISPLAY (f),
+ f->output_data.x->saved_menu_event->xany.window))
return;
#endif
static void x_update_begin P_ ((struct frame *));
static void x_update_window_begin P_ ((struct window *));
static void x_after_update_window_line P_ ((struct glyph_row *));
-static struct scroll_bar *x_window_to_scroll_bar P_ ((Window));
+static struct scroll_bar *x_window_to_scroll_bar P_ ((Display *, Window));
static void x_scroll_bar_report_motion P_ ((struct frame **, Lisp_Object *,
enum scroll_bar_part *,
Lisp_Object *, Lisp_Object *,
/* If not, is it one of our scroll bars? */
if (! f1)
{
- struct scroll_bar *bar = x_window_to_scroll_bar (win);
+ struct scroll_bar *bar;
+
+ bar = x_window_to_scroll_bar (FRAME_X_DISPLAY (*fp), win);
if (bar)
{
/* Scroll bar support. */
-/* Given an X window ID, find the struct scroll_bar which manages it.
+/* Given an X window ID and a DISPLAY, find the struct scroll_bar which
+ manages it.
This can be called in GC, so we have to make sure to strip off mark
bits. */
static struct scroll_bar *
-x_window_to_scroll_bar (window_id)
+x_window_to_scroll_bar (display, window_id)
+ Display *display;
Window window_id;
{
Lisp_Object tail;
#ifdef USE_GTK
- window_id = (Window) xg_get_scroll_id_for_window (window_id);
+ window_id = (Window) xg_get_scroll_id_for_window (display, window_id);
#endif /* USE_GTK */
for (tail = Vframe_list;
if (! GC_FRAMEP (frame))
abort ();
+ if (FRAME_X_DISPLAY (XFRAME (frame)) != display)
+ continue;
+
/* Scan this frame's scroll bar list for a scroll bar with the
right window ID. */
condemned = FRAME_CONDEMNED_SCROLL_BARS (XFRAME (frame));
#endif
#ifdef USE_GTK
-static struct x_display_info *current_dpyinfo;
static struct input_event **current_bufp;
static int *current_numcharsp;
static int current_count;
GdkEvent *ev;
gpointer data;
{
- XEvent *xev = (XEvent*)gxev;
+ XEvent *xev = (XEvent *) gxev;
if (current_numcharsp)
{
+ struct x_display_info *dpyinfo;
+
+ dpyinfo = x_display_info_for_display (xev->xany.display);
+
#ifdef HAVE_X_I18N
/* Filter events for the current X input method.
GTK calls XFilterEvent but not for key press and release,
so we do it here. */
if (xev->type == KeyPress || xev->type == KeyRelease)
- if (x_filter_event (current_dpyinfo, xev))
+ if (dpyinfo && x_filter_event (dpyinfo, xev))
return GDK_FILTER_REMOVE;
#endif
- current_count += handle_one_xevent (current_dpyinfo,
- xev,
- current_bufp,
- current_numcharsp,
- ¤t_finish);
+
+ if (! dpyinfo)
+ current_finish = X_EVENT_NORMAL;
+ else
+ current_count += handle_one_xevent (dpyinfo,
+ xev,
+ current_bufp,
+ current_numcharsp,
+ ¤t_finish);
}
else
- current_finish = x_dispatch_event (xev, GDK_DISPLAY ());
+ current_finish = x_dispatch_event (xev, xev->xany.display);
if (current_finish == X_EVENT_GOTO_OUT || current_finish == X_EVENT_DROP)
return GDK_FILTER_REMOVE;
/* Dispatch event to the widget. */
goto OTHER;
#else /* not USE_TOOLKIT_SCROLL_BARS */
- bar = x_window_to_scroll_bar (event.xexpose.window);
+ bar = x_window_to_scroll_bar (event.xexpose.display,
+ event.xexpose.window);
if (bar)
x_scroll_bar_expose (bar, &event);
/* Window will be selected only when it is not selected now and
last mouse movement event was not in it. Minibuffer window
will be selected iff it is active. */
- if (WINDOWP(window)
+ if (WINDOWP (window)
&& !EQ (window, last_window)
&& !EQ (window, selected_window)
&& numchars > 0)
{
#ifndef USE_TOOLKIT_SCROLL_BARS
struct scroll_bar *bar
- = x_window_to_scroll_bar (event.xmotion.window);
+ = x_window_to_scroll_bar (event.xmotion.display,
+ event.xmotion.window);
if (bar)
x_scroll_bar_note_movement (bar, &event);
else
{
struct scroll_bar *bar
- = x_window_to_scroll_bar (event.xbutton.window);
+ = x_window_to_scroll_bar (event.xbutton.display,
+ event.xbutton.window);
#ifdef USE_TOOLKIT_SCROLL_BARS
/* Make the "Ctrl-Mouse-2 splits window" work for toolkit
EVENT_INIT (*bufpp);
bufpp = bufp;
- for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next)
- if (dpyinfo->display == display)
- break;
+ dpyinfo = x_display_info_for_display (display);
if (dpyinfo)
{
UNBLOCK_INPUT;
#endif
-#ifdef USE_GTK
- /* For GTK we must use the GTK event loop. But XEvents gets passed
- to our filter function above, and then to the big event switch.
- We use a bunch of globals to communicate with our filter function,
- that is kind of ugly, but it works. */
- current_dpyinfo = dpyinfo;
-
- while (gtk_events_pending ())
- {
- current_count = count;
- current_numcharsp = &numchars;
- current_bufp = &bufp;
-
- gtk_main_iteration ();
-
- count = current_count;
- current_bufp = 0;
- current_numcharsp = 0;
-
- if (current_finish == X_EVENT_GOTO_OUT)
- goto out;
- }
-
-#else /* not USE_GTK */
+#ifndef USE_GTK
while (XPending (dpyinfo->display))
{
int finish;
if (finish == X_EVENT_GOTO_OUT)
goto out;
}
-#endif /* USE_GTK */
+#endif /* not USE_GTK */
+ }
+
+#ifdef USE_GTK
+
+ /* For GTK we must use the GTK event loop. But XEvents gets passed
+ to our filter function above, and then to the big event switch.
+ We use a bunch of globals to communicate with our filter function,
+ that is kind of ugly, but it works.
+
+ There is no way to do one display at the time, GTK just does events
+ from all displays. */
+
+ while (gtk_events_pending ())
+ {
+ current_count = count;
+ current_numcharsp = &numchars;
+ current_bufp = &bufp;
+
+ gtk_main_iteration ();
+
+ count = current_count;
+ current_bufp = 0;
+ current_numcharsp = 0;
+
+ if (current_finish == X_EVENT_GOTO_OUT)
+ break;
}
+#endif /* USE_GTK */
out:;
if (STRINGP (file))
{
#ifdef USE_GTK
- /* Use gtk_window_set_icon_from_file() if available,
+ /* Use gtk_window_set_icon_from_file () if available,
It's not restricted to bitmaps */
- if (xg_set_icon(f, file))
+ if (xg_set_icon (f, file))
return 0;
#endif /* USE_GTK */
bitmap_id = x_create_bitmap_from_file (f, file);
- x_create_bitmap_mask(f, bitmap_id);
+ x_create_bitmap_mask (f, bitmap_id);
}
else
{
FRAME_X_DISPLAY_INFO (f)->icon_bitmap_id
= x_create_bitmap_from_data (f, gnu_bits,
gnu_width, gnu_height);
- x_create_bitmap_mask(f, FRAME_X_DISPLAY_INFO (f)->icon_bitmap_id);
+ x_create_bitmap_mask (f, FRAME_X_DISPLAY_INFO (f)->icon_bitmap_id);
}
/* The first time we create the GNU bitmap and mask,
}
#endif
+#ifdef USE_GTK
+ if (dpyinfo)
+ xg_display_close (dpyinfo->display);
+#endif
+
/* Indicate that this display is dead. */
if (dpyinfo)
dpyinfo->display = 0;
char **argv2 = argv;
GdkAtom atom;
- /* GTK 2.0 can only handle one display, GTK 2.2 can handle more
- than one, but this remains to be implemented. */
- if (x_initialized > 1)
- error ("Sorry, the GTK port can only handle one display.");
- ++x_initialized;
-
- for (argc = 0; argc < NUM_ARGV; ++argc)
- argv[argc] = 0;
+ if (x_initialized++ > 1)
+ {
+ /* Opening another display. If xg_display_open returns less
+ than zero, we are probably on GTK 2.0, which can only handle
+ one display. GTK 2.2 or later can handle more than one. */
+ if (xg_display_open (SDATA (display_name), &dpy) < 0)
+ error ("Sorry, this version of GTK can only handle one display");
+ }
+ else
+ {
+ for (argc = 0; argc < NUM_ARGV; ++argc)
+ argv[argc] = 0;
- argc = 0;
- argv[argc++] = initial_argv[0];
+ argc = 0;
+ argv[argc++] = initial_argv[0];
- if (! NILP (display_name))
- {
- argv[argc++] = "--display";
- argv[argc++] = SDATA (display_name);
- }
+ if (! NILP (display_name))
+ {
+ argv[argc++] = "--display";
+ argv[argc++] = SDATA (display_name);
+ }
- argv[argc++] = "--name";
- argv[argc++] = resource_name;
+ argv[argc++] = "--name";
+ argv[argc++] = resource_name;
#ifdef HAVE_X11R5
- XSetLocaleModifiers ("");
+ XSetLocaleModifiers ("");
#endif
- gtk_init (&argc, &argv2);
+ gtk_init (&argc, &argv2);
- /* gtk_init does set_locale. We must fix locale after calling it. */
- fixup_locale ();
- xg_initialize ();
+ /* gtk_init does set_locale. We must fix locale after calling it. */
+ fixup_locale ();
+ xg_initialize ();
- dpy = GDK_DISPLAY ();
+ dpy = GDK_DISPLAY ();
- /* NULL window -> events for all windows go to our function */
- gdk_window_add_filter (NULL, event_handler_gdk, NULL);
+ /* NULL window -> events for all windows go to our function */
+ gdk_window_add_filter (NULL, event_handler_gdk, NULL);
- /* Load our own gtkrc if it exists. */
- {
- struct gcpro gcpro1, gcpro2;
- char *file = "~/.emacs.d/gtkrc";
- Lisp_Object s, abs_file;
+ /* Load our own gtkrc if it exists. */
+ {
+ struct gcpro gcpro1, gcpro2;
+ char *file = "~/.emacs.d/gtkrc";
+ Lisp_Object s, abs_file;
- GCPRO2 (s, abs_file);
- s = make_string (file, strlen (file));
- abs_file = Fexpand_file_name(s, Qnil);
+ GCPRO2 (s, abs_file);
+ s = make_string (file, strlen (file));
+ abs_file = Fexpand_file_name (s, Qnil);
- if (! NILP (abs_file) && !NILP (Ffile_readable_p (abs_file)))
- gtk_rc_parse (SDATA (abs_file));
+ if (! NILP (abs_file) && !NILP (Ffile_readable_p (abs_file)))
+ gtk_rc_parse (SDATA (abs_file));
- UNGCPRO;
- }
+ UNGCPRO;
+ }
- XSetErrorHandler (x_error_handler);
- XSetIOErrorHandler (x_io_error_quitter);
+ XSetErrorHandler (x_error_handler);
+ XSetIOErrorHandler (x_io_error_quitter);
+ }
}
#else /* not USE_GTK */
#ifdef USE_X_TOOLKIT
x_find_modifier_meanings (dpyinfo);
/* Get the scroll bar cursor. */
+#ifdef USE_GTK
+ /* We must create a GTK cursor, it is required for GTK widgets. */
+ dpyinfo->xg_cursor = xg_create_default_cursor (dpyinfo->display);
+#endif /* USE_GTK */
+
dpyinfo->vertical_scroll_bar_cursor
= XCreateFontCursor (dpyinfo->display, XC_sb_v_double_arrow);
/* The cursor to use for vertical scroll bars. */
Cursor vertical_scroll_bar_cursor;
+#ifdef USE_GTK
+ /* The GDK cursor for scroll bars and popup menus. */
+ GdkCursor *xg_cursor;
+#endif
+
/* X Resource data base */
XrmDatabase xrdb;