aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJan Djärv <[email protected]>2003-11-16 16:05:24 +0000
committerJan Djärv <[email protected]>2003-11-16 16:05:24 +0000
commit810f2256ba03de93679ae73c02512f0da0fd1c7b (patch)
tree7d140900a63b082cbfb00d296c3b5eb30e398080 /src
parent0bdd0f79978c5f7e6a94cde0e5fc94040de3ca66 (diff)
Implement multiple display handling for GTK.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog52
-rw-r--r--src/gtkutil.c244
-rw-r--r--src/gtkutil.h9
-rw-r--r--src/xdisp.c4
-rw-r--r--src/xfns.c38
-rw-r--r--src/xmenu.c7
-rw-r--r--src/xterm.c212
-rw-r--r--src/xterm.h5
8 files changed, 411 insertions, 160 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 41aa2cd35f..23ccec9571 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,55 @@
+2003-11-16 Jan Dj,Ad(Brv <[email protected]>
+
+ * 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,Ad(Brv <[email protected]>
* xterm.c (x_detect_focus_change): Do not change focus frame for
diff --git a/src/gtkutil.c b/src/gtkutil.c
index b37e69481b..4fc3351ab7 100644
--- a/src/gtkutil.c
+++ b/src/gtkutil.c
@@ -36,9 +36,128 @@ Boston, MA 02111-1307, USA. */
#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))
+
+/***********************************************************************
+ 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 */
+}
/***********************************************************************
@@ -48,10 +167,6 @@ Boston, MA 02111-1307, USA. */
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;
@@ -103,24 +218,48 @@ free_widget_value (wv)
}
}
-/* 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
@@ -128,7 +267,7 @@ xg_set_cursor (w, 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.
@@ -381,20 +520,23 @@ xg_frame_set_char_size (f, cols, rows)
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;
@@ -429,9 +571,9 @@ xg_pix_to_gcolor (w, pixel, c)
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;
@@ -483,6 +625,8 @@ xg_create_frame_widgets (f)
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 */
@@ -512,7 +656,8 @@ xg_create_frame_widgets (f)
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);
@@ -963,6 +1108,8 @@ xg_get_file_name (f, prompt, default_filename, mustmatch_p)
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),
@@ -1500,7 +1647,11 @@ create_menus (data, f, select_cb, deactivate_cb, highlight_cb,
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. */
@@ -1618,12 +1769,11 @@ xg_create_widget (type, name, f, val,
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)
{
@@ -1645,7 +1795,7 @@ xg_create_widget (type, name, f, val,
{
/* 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
@@ -2261,7 +2411,10 @@ xg_modify_menubar_widgets (menubar, f, val, deep_p,
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);
+ }
}
}
@@ -2417,16 +2570,17 @@ xg_get_widget_from_map (idx)
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)
{
@@ -2533,7 +2687,7 @@ xg_create_scroll_bar (f, bar, scroll_callback, scroll_bar_name)
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);
}
@@ -2952,8 +3106,8 @@ xg_tool_bar_item_expose_callback (w, event, client_data)
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);
@@ -2975,7 +3129,7 @@ xg_tool_bar_expose_callback (w, event, client_data)
GdkEventExpose *event;
gpointer client_data;
{
- update_frame_tool_bar((FRAME_PTR)client_data);
+ update_frame_tool_bar ((FRAME_PTR) client_data);
return FALSE;
}
@@ -3108,11 +3262,12 @@ update_frame_tool_bar (f)
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,
@@ -3170,10 +3325,10 @@ update_frame_tool_bar (f)
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);
}
@@ -3241,7 +3396,6 @@ void
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;
diff --git a/src/gtkutil.h b/src/gtkutil.h
index 5864a334ed..b31ec8c2a1 100644
--- a/src/gtkutil.h
+++ b/src/gtkutil.h
@@ -152,7 +152,7 @@ extern int xg_update_frame_menubar P_ ((FRAME_PTR f));
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,
@@ -184,7 +184,12 @@ extern void xg_resize_widgets P_ ((FRAME_PTR f,
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,
diff --git a/src/xdisp.c b/src/xdisp.c
index e1b1332325..8b026fefa9 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -8142,7 +8142,7 @@ update_tool_bar (f, save_match_data)
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;
@@ -8539,7 +8539,7 @@ redisplay_tool_bar (f)
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
diff --git a/src/xfns.c b/src/xfns.c
index e4742b1d36..cd50cbbc91 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -308,7 +308,7 @@ x_window_to_frame (dpyinfo, wdesc)
#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;
@@ -352,7 +352,7 @@ x_any_window_to_frame (dpyinfo, wdesc)
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
@@ -404,7 +404,7 @@ x_non_menubar_window_to_frame (dpyinfo, wdesc)
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
@@ -448,7 +448,7 @@ x_menubar_window_to_frame (dpyinfo, wdesc)
#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;
@@ -494,7 +494,7 @@ x_top_window_to_frame (dpyinfo, wdesc)
{
/* 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
@@ -762,7 +762,7 @@ static void x_destroy_x_image P_ ((XImage *ximg));
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;
{
@@ -780,9 +780,9 @@ x_create_bitmap_mask(f, 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,
@@ -799,7 +799,7 @@ x_create_bitmap_mask(f, id)
UNBLOCK_INPUT;
if (!result)
{
- XDestroyImage(ximg);
+ XDestroyImage (ximg);
return -1;
}
@@ -838,7 +838,7 @@ x_create_bitmap_mask(f, id)
dpyinfo->bitmaps[id - 1].mask = mask;
XDestroyImage (ximg);
- x_destroy_x_image(mask_img);
+ x_destroy_x_image (mask_img);
return 0;
}
@@ -1106,7 +1106,7 @@ static Lisp_Object x_find_image_file P_ ((Lisp_Object file));
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;
{
@@ -2458,8 +2458,8 @@ create_frame_xic (f)
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);
@@ -2550,7 +2550,7 @@ xic_set_statusarea (f)
XFree (needed);
attr = XVaCreateNestedList (0, XNArea, &area, NULL);
- XSetICValues(xic, XNStatusAttributes, attr, NULL);
+ XSetICValues (xic, XNStatusAttributes, attr, NULL);
XFree (attr);
}
@@ -2793,7 +2793,7 @@ x_window (f, window_prompting, minibuffer_only)
{
/* 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 */
@@ -2847,7 +2847,7 @@ if (use_xim)
{
/* 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)
{
@@ -2911,7 +2911,7 @@ x_window (f)
{
/* 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),
@@ -9166,7 +9166,7 @@ gif_load (f, img)
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);
diff --git a/src/xmenu.c b/src/xmenu.c
index 14f7485759..3e99a1c506 100644
--- a/src/xmenu.c
+++ b/src/xmenu.c
@@ -610,7 +610,7 @@ single_menu_item (key, item, dummy, skp_v)
#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
@@ -696,7 +696,7 @@ list_of_items (pane)
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;
@@ -1217,7 +1217,8 @@ x_activate_menubar (f)
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
diff --git a/src/xterm.c b/src/xterm.c
index 85beb00eb5..a5f6c959ce 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -357,7 +357,7 @@ static void x_flush P_ ((struct frame *f));
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 *,
@@ -3777,7 +3777,9 @@ XTmouse_position (fp, insist, bar_window, part, x, y, time)
/* 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)
{
@@ -3848,18 +3850,20 @@ XTmouse_position (fp, insist, bar_window, part, x, y, time)
/* 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;
@@ -3873,6 +3877,9 @@ x_window_to_scroll_bar (window_id)
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));
@@ -5669,7 +5676,6 @@ x_filter_event (dpyinfo, event)
#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;
@@ -5684,26 +5690,34 @@ event_handler_gdk (gxev, ev, data)
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,
- &current_finish);
+
+ if (! dpyinfo)
+ current_finish = X_EVENT_NORMAL;
+ else
+ current_count += handle_one_xevent (dpyinfo,
+ xev,
+ current_bufp,
+ current_numcharsp,
+ &current_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;
@@ -6043,7 +6057,8 @@ handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish)
/* 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);
@@ -6669,7 +6684,7 @@ handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish)
/* 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)
@@ -6688,7 +6703,8 @@ handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish)
{
#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);
@@ -6851,7 +6867,8 @@ handle_one_xevent (dpyinfo, eventp, bufp_r, numcharsp, finish)
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
@@ -7012,9 +7029,7 @@ x_dispatch_event (event, display)
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)
{
@@ -7116,30 +7131,7 @@ XTread_socket (sd, bufp, numchars, expected)
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;
@@ -7162,8 +7154,35 @@ XTread_socket (sd, bufp, numchars, expected)
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:;
@@ -7482,13 +7501,13 @@ x_bitmap_icon (f, file)
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
{
@@ -7498,7 +7517,7 @@ x_bitmap_icon (f, file)
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,
@@ -7767,6 +7786,11 @@ x_connection_closed (dpy, error_message)
}
#endif
+#ifdef USE_GTK
+ if (dpyinfo)
+ xg_display_close (dpyinfo->display);
+#endif
+
/* Indicate that this display is dead. */
if (dpyinfo)
dpyinfo->display = 0;
@@ -10211,60 +10235,65 @@ x_term_init (display_name, xrm_option, resource_name)
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
@@ -10385,6 +10414,11 @@ x_term_init (display_name, xrm_option, resource_name)
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);
diff --git a/src/xterm.h b/src/xterm.h
index fbd268abda..104f5f8d76 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -189,6 +189,11 @@ struct x_display_info
/* 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;