1 /* GTK - The GIMP Toolkit
2 * gtkxembed.c: Utilities for the XEMBED protocol
3 * Copyright (C) 2001, 2003, Red Hat, Inc.
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
22 #include "gtkprivate.h"
23 #include "gtkxembed.h"
25 typedef struct _GtkXEmbedMessage GtkXEmbedMessage;
27 struct _GtkXEmbedMessage
36 static GSList *current_messages;
40 * _gtk_xembed_push_message:
43 * Adds a client message to the stack of current XEMBED events.
46 _gtk_xembed_push_message (XEvent *xevent)
48 GtkXEmbedMessage *message = g_new (GtkXEmbedMessage, 1);
50 message->time = xevent->xclient.data.l[0];
51 message->message = xevent->xclient.data.l[1];
52 message->detail = xevent->xclient.data.l[2];
53 message->data1 = xevent->xclient.data.l[3];
54 message->data2 = xevent->xclient.data.l[4];
56 current_messages = g_slist_prepend (current_messages, message);
60 * _gtk_xembed_pop_message:
62 * Removes an event added with _gtk_xembed_push_message()
65 _gtk_xembed_pop_message (void)
67 GtkXEmbedMessage *message = current_messages->data;
68 current_messages = g_slist_delete_link (current_messages, current_messages);
74 * _gtk_xembed_set_focus_wrapped:
76 * Sets a flag indicating that the current focus sequence wrapped
77 * around to the beginning of the ultimate toplevel.
80 _gtk_xembed_set_focus_wrapped (void)
82 GtkXEmbedMessage *message;
84 g_return_if_fail (current_messages != NULL);
85 message = current_messages->data;
86 g_return_if_fail (message->message == XEMBED_FOCUS_PREV || message->message == XEMBED_FOCUS_NEXT);
88 message->data1 |= XEMBED_FOCUS_WRAPAROUND;
92 * _gtk_xembed_get_focus_wrapped:
94 * Gets whether the current focus sequence has wrapped around
95 * to the beginning of the ultimate toplevel.
97 * Return value: %TRUE if the focus sequence has wrapped around.
100 _gtk_xembed_get_focus_wrapped (void)
102 GtkXEmbedMessage *message;
104 g_return_val_if_fail (current_messages != NULL, FALSE);
105 message = current_messages->data;
107 return (message->data1 & XEMBED_FOCUS_WRAPAROUND) != 0;
111 gtk_xembed_get_time (void)
113 if (current_messages)
115 GtkXEmbedMessage *message = current_messages->data;
116 return message->time;
119 return gtk_get_current_event_time ();
123 * _gtk_xembed_send_message:
124 * @recipient: window to which to send the window, or %NULL
125 * in which case nothing wil be sent
126 * @message: type of message
127 * @detail: detail field of message
128 * @data1: data1 field of message
129 * @data2: data2 field of message
131 * Sends a generic XEMBED message to a particular window.
134 _gtk_xembed_send_message (GdkWindow *recipient,
135 XEmbedMessageType message,
146 g_return_if_fail (GDK_IS_WINDOW (recipient));
148 display = gdk_drawable_get_display (recipient);
149 GTK_NOTE (PLUGSOCKET,
150 g_message ("Sending XEMBED message of type %d", message));
152 xevent.xclient.window = GDK_WINDOW_XWINDOW (recipient);
153 xevent.xclient.type = ClientMessage;
154 xevent.xclient.message_type = gdk_x11_get_xatom_by_name_for_display (display, "_XEMBED");
155 xevent.xclient.format = 32;
156 xevent.xclient.data.l[0] = gtk_xembed_get_time ();
157 xevent.xclient.data.l[1] = message;
158 xevent.xclient.data.l[2] = detail;
159 xevent.xclient.data.l[3] = data1;
160 xevent.xclient.data.l[4] = data2;
162 gdk_error_trap_push ();
163 XSendEvent (GDK_WINDOW_XDISPLAY(recipient),
164 GDK_WINDOW_XWINDOW (recipient),
165 False, NoEventMask, &xevent);
166 gdk_display_sync (display);
167 gdk_error_trap_pop ();
171 * _gtk_xembed_send_focus_message:
172 * @recipient: window to which to send the window, or %NULL
173 * in which case nothing wil be sent
174 * @message: type of message
175 * @detail: detail field of message
177 * Sends a XEMBED message for moving the focus along the focus
178 * chain to a window. The flags field that these messages share
179 * will be correctly filled in.
182 _gtk_xembed_send_focus_message (GdkWindow *recipient,
183 XEmbedMessageType message,
188 g_return_if_fail (GDK_IS_WINDOW (recipient));
189 g_return_if_fail (message == XEMBED_FOCUS_IN ||
190 message == XEMBED_FOCUS_NEXT ||
191 message == XEMBED_FOCUS_PREV);
193 if (current_messages)
195 GtkXEmbedMessage *message = current_messages->data;
196 switch (message->message)
198 case XEMBED_FOCUS_IN:
199 case XEMBED_FOCUS_NEXT:
200 case XEMBED_FOCUS_PREV:
201 flags = message->data1 & XEMBED_FOCUS_WRAPAROUND;
208 _gtk_xembed_send_message (recipient, message, detail, flags, 0);