#include <unistd.h>
#endif
+#ifdef USE_GTK
+#include "gtkutil.h"
+#endif
+
#ifdef USE_LUCID
extern int xlwmenu_window_p P_ ((Widget w, Window window));
extern void xlwmenu_redisplay P_ ((Widget));
#endif
-#ifdef USE_X_TOOLKIT
+#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
extern void free_frame_menubar P_ ((struct frame *));
extern struct frame *x_menubar_window_to_frame P_ ((struct x_display_info *,
int));
+#endif
+#ifdef USE_X_TOOLKIT
#if (XtSpecificationRelease >= 5) && !defined(NO_EDITRES)
#define HACK_EDITRES
extern void _XEditResCheckMessages ();
#endif /* USE_X_TOOLKIT */
-#ifndef USE_X_TOOLKIT
+#if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
#define x_any_window_to_frame x_window_to_frame
#define x_top_window_to_frame x_window_to_frame
#endif
unsigned long *));
static void x_check_fullscreen P_ ((struct frame *));
static void x_check_fullscreen_move P_ ((struct frame *));
+static int handle_one_xevent P_ ((struct x_display_info *,
+ XEvent *,
+ struct input_event **,
+ int *,
+ int *));
+
/* Flush display of frame F, or of all frames if F is null. */
height = s->height - 2 * box_line_vwidth;
+
/* Fill background with face under the image. Do it only if row is
taller than image or if image has a clip mask to reduce
flickering. */
struct buffer *b;
/* When a menu is active, don't highlight because this looks odd. */
-#ifdef USE_X_TOOLKIT
+#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
if (popup_activated ())
return;
#endif
x_process_timeouts (timer)
struct atimer *timer;
{
- if (toolkit_scroll_bar_interaction || popup_activated_flag)
+ if (toolkit_scroll_bar_interaction || popup_activated ())
{
BLOCK_INPUT;
while (XtAppPending (Xt_app_con) & XtIMTimer)
int, int, int));
-/* Id of action hook installed for scroll bars. */
-
-static XtActionHookId action_hook_id;
-
/* Lisp window being scrolled. Set when starting to interact with
a toolkit scroll bar, reset to nil when ending the interaction. */
/* Whether this is an Xaw with arrow-scrollbars. This should imply
that movements of 1/20 of the screen size are mapped to up/down. */
+#ifndef USE_GTK
+/* Id of action hook installed for scroll bars. */
+
+static XtActionHookId action_hook_id;
+
static Boolean xaw3d_arrow_scroll;
/* Whether the drag scrolling maintains the mouse at the top of the
toolkit_scroll_bar_interaction = 0;
}
}
+#endif /* not USE_GTK */
/* A vector of windows used for communication between
x_send_scroll_bar_event and x_scroll_bar_to_input_event. */
ievent->kind = SCROLL_BAR_CLICK_EVENT;
ievent->frame_or_window = window;
ievent->arg = Qnil;
+#ifdef USE_GTK
+ ievent->timestamp = CurrentTime;
+#else
ievent->timestamp = XtLastTimestampProcessed (FRAME_X_DISPLAY (f));
+#endif
ievent->part = ev->data.l[1];
ievent->code = ev->data.l[2];
ievent->x = make_number ((int) ev->data.l[3]);
}
-#else /* !USE_MOTIF, i.e. Xaw. */
+#else /* !USE_MOTIF, i.e. Xaw or GTK */
+#ifdef USE_GTK
+/* Scroll bar callback for Gtk scroll bars. WIDGET is the scroll
+ bar adjustment widget. DATA is a pointer to the scroll_bar structure. */
+
+static void
+xg_scroll_callback (widget, data)
+ GtkWidget *widget;
+ gpointer data;
+{
+ struct scroll_bar *bar = (struct scroll_bar *) data;
+ gdouble previous;
+ gdouble position;
+ gdouble *p;
+ int diff;
+
+ int part = -1, whole = 0, portion = 0;
+ GtkAdjustment *adj = GTK_ADJUSTMENT (widget);
+
+ if (xg_ignore_gtk_scrollbar) return;
+
+ position = gtk_adjustment_get_value (adj);
+
+ p = g_object_get_data (G_OBJECT (widget), XG_LAST_SB_DATA);
+ if (! p)
+ {
+ p = (gdouble*) xmalloc (sizeof (gdouble));
+ *p = XG_SB_MIN;
+ g_object_set_data (G_OBJECT (widget), XG_LAST_SB_DATA, p);
+ }
+
+ previous = *p;
+ *p = position;
+ diff = (int) (position - previous);
+
+ if (diff == (int) adj->step_increment)
+ {
+ part = scroll_bar_down_arrow;
+ bar->dragging = Qnil;
+ }
+ else if (-diff == (int) adj->step_increment)
+ {
+ part = scroll_bar_up_arrow;
+ bar->dragging = Qnil;
+ }
+ else if (diff == (int) adj->page_increment)
+ {
+ part = scroll_bar_below_handle;
+ bar->dragging = Qnil;
+ }
+ else if (-diff == (int) adj->page_increment)
+ {
+ part = scroll_bar_above_handle;
+ bar->dragging = Qnil;
+ }
+ else
+ {
+ part = scroll_bar_handle;
+ whole = adj->upper - adj->page_size;
+ portion = min (position, whole);
+ bar->dragging = make_number (portion);
+ }
+
+ if (part >= 0)
+ {
+ xg_ignore_next_thumb = 1;
+ window_being_scrolled = bar->window;
+ last_scroll_bar_part = part;
+ x_send_scroll_bar_event (bar->window, part, portion, whole);
+ }
+}
+
+#else /* not USE_GTK */
/* Xaw scroll bar callback. Invoked when the thumb is dragged.
WIDGET is the scroll bar widget. CLIENT_DATA is a pointer to the
x_send_scroll_bar_event (bar->window, part, position, height);
}
-
+#endif /* not USE_GTK */
#endif /* not USE_MOTIF */
+#define SCROLL_BAR_NAME "verticalScrollBar"
/* Create the widget for scroll bar BAR on frame F. Record the widget
and X window of the scroll bar in BAR. */
+#ifdef USE_GTK
+static void
+x_create_toolkit_scroll_bar (f, bar)
+ struct frame *f;
+ struct scroll_bar *bar;
+{
+ char *scroll_bar_name = SCROLL_BAR_NAME;
+
+ BLOCK_INPUT;
+ xg_create_scroll_bar (f, bar, G_CALLBACK (xg_scroll_callback),
+ scroll_bar_name);
+ UNBLOCK_INPUT;
+}
+
+#else /* not USE_GTK */
+
static void
x_create_toolkit_scroll_bar (f, bar)
struct frame *f;
Widget widget;
Arg av[20];
int ac = 0;
- char *scroll_bar_name = "verticalScrollBar";
+ char *scroll_bar_name = SCROLL_BAR_NAME;
unsigned long pixel;
BLOCK_INPUT;
UNBLOCK_INPUT;
}
+#endif /* not USE_GTK */
/* Set the thumb size and position of scroll bar BAR. We are currently
displaying PORTION out of a whole WHOLE, and our position POSITION. */
+#ifdef USE_GTK
+static void
+x_set_toolkit_scroll_bar_thumb (bar, portion, position, whole)
+ struct scroll_bar *bar;
+ int portion, position, whole;
+{
+ xg_set_toolkit_scroll_bar_thumb (bar, portion, position, whole);
+}
+
+#else /* not USE_GTK */
static void
x_set_toolkit_scroll_bar_thumb (bar, portion, position, whole)
struct scroll_bar *bar;
UNBLOCK_INPUT;
}
+#endif /* not USE_GTK */
#endif /* USE_TOOLKIT_SCROLL_BARS */
/* Map the window/widget. */
#ifdef USE_TOOLKIT_SCROLL_BARS
{
+#ifdef USE_GTK
+ xg_update_scrollbar_pos (f,
+ SCROLL_BAR_X_WINDOW (bar),
+ top,
+ left + VERTICAL_SCROLL_BAR_WIDTH_TRIM,
+ width - VERTICAL_SCROLL_BAR_WIDTH_TRIM * 2,
+ max (height, 1));
+ xg_show_scroll_bar (SCROLL_BAR_X_WINDOW (bar));
+#else /* not USE_GTK */
Widget scroll_bar = SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar);
XtConfigureWidget (scroll_bar,
left + VERTICAL_SCROLL_BAR_WIDTH_TRIM,
width - VERTICAL_SCROLL_BAR_WIDTH_TRIM * 2,
max (height, 1), 0);
XtMapWidget (scroll_bar);
+#endif /* not USE_GTK */
}
#else /* not USE_TOOLKIT_SCROLL_BARS */
XMapRaised (FRAME_X_DISPLAY (f), SCROLL_BAR_X_WINDOW (bar));
BLOCK_INPUT;
#ifdef USE_TOOLKIT_SCROLL_BARS
+#ifdef USE_GTK
+ xg_remove_scroll_bar (f, SCROLL_BAR_X_WINDOW (bar));
+#else /* not USE_GTK */
XtDestroyWidget (SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar));
+#endif /* not USE_GTK */
#else
XDestroyWindow (FRAME_X_DISPLAY (f), SCROLL_BAR_X_WINDOW (bar));
#endif
#ifdef USE_TOOLKIT_SCROLL_BARS
+#ifdef USE_GTK
+ if (mask)
+ xg_update_scrollbar_pos (f,
+ SCROLL_BAR_X_WINDOW (bar),
+ top,
+ sb_left + VERTICAL_SCROLL_BAR_WIDTH_TRIM,
+ sb_width - VERTICAL_SCROLL_BAR_WIDTH_TRIM * 2,
+ max (height, 1));
+#else /* not USE_GTK */
+
/* Since toolkit scroll bars are smaller than the space reserved
- for them on the frame, we have to clear "under" them. */
+ for them on the frame, we have to clear "under" them. */
if (width > 0 && height > 0)
- x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
- left, top, width, height, False);
-
+ x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
+ left, top, width, height, False);
/* Move/size the scroll bar widget. */
if (mask)
- XtConfigureWidget (SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar),
- sb_left + VERTICAL_SCROLL_BAR_WIDTH_TRIM,
- top,
- sb_width - VERTICAL_SCROLL_BAR_WIDTH_TRIM * 2,
- max (height, 1), 0);
+ XtConfigureWidget (SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar),
+ sb_left + VERTICAL_SCROLL_BAR_WIDTH_TRIM,
+ top,
+ sb_width - VERTICAL_SCROLL_BAR_WIDTH_TRIM * 2,
+ max (height, 1), 0);
+#endif /* not USE_GTK */
#else /* not USE_TOOLKIT_SCROLL_BARS */
/* Clear areas not covered by the scroll bar because of
X_EVENT_DROP
};
+/* Filter events for the current X input method.
+ DPYINFO is the display this event is for.
+ EVENT is the X event to filter.
+
+ Returns non-zero if the event was filtered, caller shall not process
+ this event further.
+ Returns zero if event is wasn't filtered. */
+
+#ifdef HAVE_X_I18N
+static int
+x_filter_event (dpyinfo, event)
+ struct x_display_info *dpyinfo;
+ XEvent *event;
+{
+ /* XFilterEvent returns non-zero if the input method has
+ consumed the event. We pass the frame's X window to
+ XFilterEvent because that's the one for which the IC
+ was created. */
+
+ struct frame *f1 = x_any_window_to_frame (dpyinfo,
+ event->xclient.window);
+
+ return XFilterEvent (event, f1 ? FRAME_X_WINDOW (f1) : None);
+}
+#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;
+static int current_finish;
+
+/* This is the filter function invoked by the GTK event loop.
+ It is invoked before the XEvent is translated to a GdkEvent,
+ so we have a chanse to act on the event before GTK. */
+static GdkFilterReturn
+event_handler_gdk (gxev, ev, data)
+ GdkXEvent *gxev;
+ GdkEvent *ev;
+ gpointer data;
+{
+ XEvent *xev = (XEvent*)gxev;
+
+ if (current_numcharsp)
+ {
+#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))
+ return GDK_FILTER_REMOVE;
+#endif
+ current_count += handle_one_xevent (current_dpyinfo,
+ xev,
+ current_bufp,
+ current_numcharsp,
+ ¤t_finish);
+ }
+ else
+ current_finish = x_dispatch_event (xev, GDK_DISPLAY ());
+
+ if (current_finish == X_EVENT_GOTO_OUT || current_finish == X_EVENT_DROP)
+ return GDK_FILTER_REMOVE;
+
+ return GDK_FILTER_CONTINUE;
+}
+#endif /* USE_GTK */
+
+
/* Handles the XEvent EVENT on display DPYINFO.
-
+
*FINISH is X_EVENT_GOTO_OUT if caller should stop reading events.
*FINISH is zero if caller should continue reading events.
*FINISH is X_EVENT_DROP if event should not be passed to the toolkit.
case KeyPress:
+#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
/* Dispatch KeyPress events when in menu. */
- if (popup_activated_flag)
+ if (popup_activated ())
goto OTHER;
+#endif
+
f = x_any_window_to_frame (dpyinfo, event.xkey.window);
if (!dpyinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight))
if (f)
{
#ifndef USE_X_TOOLKIT
+#ifdef USE_GTK
+ xg_resize_widgets (f, event.xconfigure.width,
+ event.xconfigure.height);
+#else /* not USE_GTK */
/* If there is a pending resize for fullscreen, don't
do this one, the right one will come later.
The toolkit version doesn't seem to need this, but we
SET_FRAME_GARBAGED (f);
cancel_mouse_face (f);
}
+#endif /* not USE_GTK */
#endif
f->output_data.x->pixel_width = event.xconfigure.width;
f->output_data.x->pixel_height = event.xconfigure.height;
+#ifdef USE_GTK
+ /* GTK creates windows but doesn't map them.
+ Only get real positions and check fullscreen when mapped. */
+ if (FRAME_GTK_OUTER_WIDGET (f)
+ && GTK_WIDGET_MAPPED (FRAME_GTK_OUTER_WIDGET (f)))
+ {
+#endif
/* What we have now is the position of Emacs's own window.
Convert that to the position of the window manager window. */
x_real_positions (f, &f->output_data.x->left_pos,
&f->output_data.x->top_pos);
- x_check_fullscreen_move(f);
+ x_check_fullscreen_move (f);
if (f->output_data.x->want_fullscreen & FULLSCREEN_WAIT)
f->output_data.x->want_fullscreen &=
~(FULLSCREEN_WAIT|FULLSCREEN_BOTH);
+#ifdef USE_GTK
+ }
+#endif
#ifdef HAVE_X_I18N
if (FRAME_XIC (f) && (FRAME_XIC_STYLE (f) & XIMStatusArea))
xic_set_statusarea (f);
}
goto OTHER;
- case ButtonPress:
case ButtonRelease:
+ case ButtonPress:
{
/* If we decide we want to generate an event to be seen
by the rest of Emacs, we put it here. */
if (!tool_bar_p)
if (!dpyinfo->x_focus_frame
|| f == dpyinfo->x_focus_frame)
- construct_mouse_click (&emacs_event, &event, f);
+ {
+#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
+ if (! popup_activated ())
+#endif
+ construct_mouse_click (&emacs_event, &event, f);
+ }
}
else
{
last_tool_bar_item = -1;
}
else
- {
- dpyinfo->grabbed &= ~(1 << event.xbutton.button);
- }
+ dpyinfo->grabbed &= ~(1 << event.xbutton.button);
if (numchars >= 1 && emacs_event.kind != NO_EVENT)
{
numchars--;
}
-#ifdef USE_X_TOOLKIT
+#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
f = x_menubar_window_to_frame (dpyinfo, event.xbutton.window);
/* For a down-event in the menu bar,
don't pass it to Xt right now.
Instead, save it away
and we will pass it to Xt from kbd_buffer_get_event.
That way, we can run some Lisp code first. */
- if (f && event.type == ButtonPress
+ if (
+#ifdef USE_GTK
+ ! popup_activated ()
+ &&
+#endif
+ f && event.type == ButtonPress
/* Verify the event is really within the menu bar
and not just sent to it due to grabbing. */
&& event.xbutton.x >= 0
{
SET_SAVED_BUTTON_EVENT;
XSETFRAME (last_mouse_press_frame, f);
+#ifdef USE_GTK
+ *finish = X_EVENT_DROP;
+#endif
}
else if (event.type == ButtonPress)
{
#endif /* USE_MOTIF */
else
goto OTHER;
-#endif /* USE_X_TOOLKIT */
+#endif /* USE_X_TOOLKIT || USE_GTK */
}
break;
*bufp_r = bufp;
*numcharsp = numchars;
*eventp = event;
-
+
return count;
}
/* Handles the XEvent EVENT on display DISPLAY.
This is used for event loops outside the normal event handling,
- i.e. looping while a popup menu or a dialog is posted. */
-void
+ i.e. looping while a popup menu or a dialog is posted.
+
+ Returns the value handle_one_xevent sets in the finish argument. */
+int
x_dispatch_event (event, display)
XEvent *event;
Display *display;
struct input_event bufp[10];
struct input_event *bufpp = bufp;
int numchars = 10;
- int finish;
-
+ int finish = X_EVENT_NORMAL;
+
for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next)
if (dpyinfo->display == display)
break;
-
+
if (dpyinfo)
{
int i, events;
for (i = 0; i < events; ++i)
kbd_buffer_store_event (&bufp[i]);
}
+
+ return finish;
}
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 ())
+ {
+ static int nr = 0;
+ 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 */
while (XPending (dpyinfo->display))
{
int finish;
-
+
XNextEvent (dpyinfo->display, &event);
#ifdef HAVE_X_I18N
- {
- /* Filter events for the current X input method.
- XFilterEvent returns non-zero if the input method has
- consumed the event. We pass the frame's X window to
- XFilterEvent because that's the one for which the IC
- was created. */
- struct frame *f1 = x_any_window_to_frame (dpyinfo,
- event.xclient.window);
- if (XFilterEvent (&event, f1 ? FRAME_X_WINDOW (f1) : None))
- break;
- }
+ /* Filter events for the current X input method. */
+ if (x_filter_event (dpyinfo, &event))
+ break;
#endif
event_found = 1;
if (finish == X_EVENT_GOTO_OUT)
goto out;
}
+#endif /* USE_GTK */
}
out:;
text.encoding = XA_STRING;
text.format = 8;
text.nitems = strlen (icon_name);
-#ifdef USE_X_TOOLKIT
- XSetWMIconName (FRAME_X_DISPLAY (f), XtWindow (f->output_data.x->widget),
- &text);
-#else /* not USE_X_TOOLKIT */
- XSetWMIconName (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), &text);
-#endif /* not USE_X_TOOLKIT */
+ XSetWMIconName (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), &text);
}
#else /* not HAVE_X11R4 */
- XSetIconName (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), icon_name);
+ XSetIconName (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), icon_name);
#endif /* not HAVE_X11R4 */
if (f->output_data.x->icon_bitmap > 0)
};
/* XIM instantiate callback function, which is called whenever an XIM
- server is available. DISPLAY is teh display of the XIM.
+ server is available. DISPLAY is the display of the XIM.
CLIENT_DATA contains a pointer to an xim_inst_t structure created
when the callback was registered. */
if (! ((flags & XNegative) || (flags & YNegative)))
return;
-#ifdef USE_X_TOOLKIT
- this_window = XtWindow (f->output_data.x->widget);
-#else
- this_window = FRAME_X_WINDOW (f);
-#endif
+ this_window = FRAME_OUTER_WINDOW (f);
/* Find the position of the outside upper-left corner of
the inner window, with respect to the outer window.
}
#endif
-#ifdef USE_X_TOOLKIT
- XMoveWindow (FRAME_X_DISPLAY (f), XtWindow (f->output_data.x->widget),
- modified_left, modified_top);
-#else /* not USE_X_TOOLKIT */
- XMoveWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
- modified_left, modified_top);
-#endif /* not USE_X_TOOLKIT */
+ XMoveWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
+ modified_left, modified_top);
UNBLOCK_INPUT;
}
{
BLOCK_INPUT;
-#ifdef USE_X_TOOLKIT
+#ifdef USE_GTK
+ if (FRAME_GTK_WIDGET (f))
+ xg_frame_set_char_size (f, cols, rows);
+ else
+ x_set_window_size_1 (f, change_gravity, cols, rows);
+#elif USE_X_TOOLKIT
if (f->output_data.x->widget != NULL)
{
if (f->async_visible)
{
BLOCK_INPUT;
-#ifdef USE_X_TOOLKIT
- XRaiseWindow (FRAME_X_DISPLAY (f), XtWindow (f->output_data.x->widget));
-#else /* not USE_X_TOOLKIT */
- XRaiseWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
-#endif /* not USE_X_TOOLKIT */
+ XRaiseWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f));
XFlush (FRAME_X_DISPLAY (f));
UNBLOCK_INPUT;
}
if (f->async_visible)
{
BLOCK_INPUT;
-#ifdef USE_X_TOOLKIT
- XLowerWindow (FRAME_X_DISPLAY (f), XtWindow (f->output_data.x->widget));
-#else /* not USE_X_TOOLKIT */
- XLowerWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
-#endif /* not USE_X_TOOLKIT */
+ XLowerWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f));
XFlush (FRAME_X_DISPLAY (f));
UNBLOCK_INPUT;
}
/* This was XtPopup, but that did nothing for an iconified frame. */
XtMapWidget (f->output_data.x->widget);
#else /* not USE_X_TOOLKIT */
+#ifdef USE_GTK
+ gtk_widget_show_all (FRAME_GTK_OUTER_WIDGET (f));
+ gtk_window_deiconify (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)));
+#else
XMapRaised (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
+#endif /* not USE_GTK */
#endif /* not USE_X_TOOLKIT */
#if 0 /* This seems to bring back scroll bars in the wrong places
if the window configuration has changed. They seem
{
Window window;
-#ifdef USE_X_TOOLKIT
/* Use the frame's outermost window, not the one we normally draw on. */
- window = XtWindow (f->output_data.x->widget);
-#else /* not USE_X_TOOLKIT */
- window = FRAME_X_WINDOW (f);
-#endif /* not USE_X_TOOLKIT */
+ window = FRAME_OUTER_WINDOW (f);
/* Don't keep the highlight on an invisible frame. */
if (FRAME_X_DISPLAY_INFO (f)->x_highlight_frame == f)
by hand again (they have already done that once for this window.) */
x_wm_set_size_hint (f, (long) 0, 1);
+#ifdef USE_GTK
+ if (FRAME_GTK_OUTER_WIDGET (f))
+ {
+ gtk_widget_hide (FRAME_GTK_OUTER_WIDGET (f));
+ goto out;
+ }
+#endif
+
#ifdef HAVE_X11R4
if (! XWithdrawWindow (FRAME_X_DISPLAY (f), window,
XUnmapWindow (FRAME_X_DISPLAY (f), window);
#endif /* ! defined (HAVE_X11R4) */
+ out:
/* We can't distinguish this from iconification
just by the event that we get from the server.
So we can't win using the usual strategy of letting
if (!NILP (type))
x_bitmap_icon (f, type);
+#ifdef USE_GTK
+ if (FRAME_GTK_OUTER_WIDGET (f))
+ {
+ if (! FRAME_VISIBLE_P (f))
+ gtk_widget_show_all (FRAME_GTK_OUTER_WIDGET (f));
+
+ gtk_window_iconify (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)));
+ f->iconified = 1;
+ f->visible = 1;
+ f->async_iconified = 1;
+ f->async_visible = 0;
+ UNBLOCK_INPUT;
+ return;
+ }
+#endif
+
#ifdef USE_X_TOOLKIT
if (! FRAME_VISIBLE_P (f))
free_frame_menubar (f);
#else /* !USE_X_TOOLKIT */
+
+#ifdef USE_GTK
+ /* In the GTK version, tooltips are normal X
+ frames. We must check and free both types. */
+ if (FRAME_GTK_OUTER_WIDGET (f))
+ {
+ gtk_widget_destroy (FRAME_GTK_OUTER_WIDGET (f));
+ FRAME_X_WINDOW (f) = 0; /* Set to avoid XDestroyWindow below */
+ FRAME_GTK_OUTER_WIDGET (f) = 0;
+ }
+#endif /* USE_GTK */
+
if (FRAME_X_WINDOW (f))
XDestroyWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
#endif /* !USE_X_TOOLKIT */
FLAGS is the flags word to use--or 0 meaning preserve the flags
that the window now has.
If USER_POSITION is nonzero, we set the USPosition
- flag (this is useful when FLAGS is 0). */
+ flag (this is useful when FLAGS is 0).
+ The GTK version is in gtkutils.c */
+#ifndef USE_GTK
void
x_wm_set_size_hint (f, flags, user_position)
struct frame *f;
Arg al[2];
int ac = 0;
Dimension widget_width, widget_height;
- Window window = XtWindow (f->output_data.x->widget);
-#else /* not USE_X_TOOLKIT */
- Window window = FRAME_X_WINDOW (f);
-#endif /* not USE_X_TOOLKIT */
+#endif
+
+ Window window = FRAME_OUTER_WINDOW (f);
/* Setting PMaxSize caused various problems. */
size_hints.flags = PResizeInc | PMinSize /* | PMaxSize */;
XSetNormalHints (FRAME_X_DISPLAY (f), window, &size_hints);
#endif
}
+#endif /* not USE_GTK */
/* Used for IconicState or NormalState */
Pixmap icon_pixmap;
#ifndef USE_X_TOOLKIT
- Window window = FRAME_X_WINDOW (f);
+ Window window = FRAME_OUTER_WINDOW (f);
#endif
if (pixmap_id > 0)
struct frame *f;
int icon_x, icon_y;
{
-#ifdef USE_X_TOOLKIT
- Window window = XtWindow (f->output_data.x->widget);
-#else
- Window window = FRAME_X_WINDOW (f);
-#endif
+ Window window = FRAME_OUTER_WINDOW (f);
f->output_data.x->wm_hints.flags |= IconPositionHint;
f->output_data.x->wm_hints.icon_x = icon_x;
x_initialized = 1;
}
+#ifdef USE_GTK
+ {
+#define NUM_ARGV 10
+ int argc;
+ char *argv[NUM_ARGV];
+ 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)
+ return 0;
+
+ x_initialized++;
+
+ for (argc = 0; argc < NUM_ARGV; ++argc)
+ argv[argc] = 0;
+
+ argc = 0;
+ argv[argc++] = initial_argv[0];
+
+ if (! NILP (display_name))
+ {
+ argv[argc++] = "--display";
+ argv[argc++] = SDATA (display_name);
+ }
+
+ argv[argc++] = "--name";
+ argv[argc++] = resource_name;
+
+#ifdef HAVE_X11R5
+ XSetLocaleModifiers ("");
+#endif
+
+ gtk_init (&argc, &argv2);
+
+ /* gtk_init does set_locale. We must fix locale after calling it. */
+ fixup_locale ();
+ xg_initialize ();
+
+ dpy = GDK_DISPLAY ();
+
+ /* 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;
+
+ GCPRO2 (str, abs_file);
+ s = make_string (file, strlen (file));
+ abs_file = Fexpand_file_name(s, Qnil);
+
+ if (! NILP (abs_file) && Ffile_readable_p (abs_file))
+ gtk_rc_parse (SDATA (abs_file));
+
+ UNGCPRO;
+ }
+
+ XSetErrorHandler (x_error_handler);
+ XSetIOErrorHandler (x_io_error_quitter);
+ }
+#else /* not USE_GTK */
#ifdef USE_X_TOOLKIT
/* weiner@footloose.sps.mot.com reports that this causes
errors with X11R5:
#endif
dpy = XOpenDisplay (SDATA (display_name));
#endif /* not USE_X_TOOLKIT */
+#endif /* not USE_GTK*/
/* Detect failure. */
if (dpy == 0)
#endif
#ifdef USE_TOOLKIT_SCROLL_BARS
+#ifndef USE_GTK
xaw3d_arrow_scroll = False;
xaw3d_pick_top = True;
+#endif
#endif
/* Note that there is no real way portable across R3/R4 to get the
Vx_toolkit_scroll_bars = intern ("motif");
#elif defined HAVE_XAW3D
Vx_toolkit_scroll_bars = intern ("xaw3d");
+#elif USE_GTK
+ Vx_toolkit_scroll_bars = intern ("gtk");
#else
Vx_toolkit_scroll_bars = intern ("xaw");
#endif