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.
24 #include "gtkprivate.h"
25 #include "gtkxembed.h"
29 typedef struct _GtkXEmbedMessage GtkXEmbedMessage;
31 struct _GtkXEmbedMessage
40 static GSList *current_messages;
44 * _gtk_xembed_push_message:
47 * Adds a client message to the stack of current XEMBED events.
50 _gtk_xembed_push_message (XEvent *xevent)
52 GtkXEmbedMessage *message = g_slice_new (GtkXEmbedMessage);
54 message->time = xevent->xclient.data.l[0];
55 message->message = xevent->xclient.data.l[1];
56 message->detail = xevent->xclient.data.l[2];
57 message->data1 = xevent->xclient.data.l[3];
58 message->data2 = xevent->xclient.data.l[4];
60 current_messages = g_slist_prepend (current_messages, message);
64 * _gtk_xembed_pop_message:
66 * Removes an event added with _gtk_xembed_push_message()
69 _gtk_xembed_pop_message (void)
71 GtkXEmbedMessage *message = current_messages->data;
72 current_messages = g_slist_delete_link (current_messages, current_messages);
73 g_slice_free (GtkXEmbedMessage, message);
77 * _gtk_xembed_set_focus_wrapped:
79 * Sets a flag indicating that the current focus sequence wrapped
80 * around to the beginning of the ultimate toplevel.
83 _gtk_xembed_set_focus_wrapped (void)
85 GtkXEmbedMessage *message;
87 g_return_if_fail (current_messages != NULL);
88 message = current_messages->data;
89 g_return_if_fail (message->message == XEMBED_FOCUS_PREV || message->message == XEMBED_FOCUS_NEXT);
91 message->data1 |= XEMBED_FOCUS_WRAPAROUND;
95 * _gtk_xembed_get_focus_wrapped:
97 * Gets whether the current focus sequence has wrapped around
98 * to the beginning of the ultimate toplevel.
100 * Return value: %TRUE if the focus sequence has wrapped around.
103 _gtk_xembed_get_focus_wrapped (void)
105 GtkXEmbedMessage *message;
107 g_return_val_if_fail (current_messages != NULL, FALSE);
108 message = current_messages->data;
110 return (message->data1 & XEMBED_FOCUS_WRAPAROUND) != 0;
114 gtk_xembed_get_time (void)
116 if (current_messages)
118 GtkXEmbedMessage *message = current_messages->data;
119 return message->time;
122 return gtk_get_current_event_time ();
126 * _gtk_xembed_send_message:
127 * @recipient: (allow-none): window to which to send the window, or %NULL
128 * in which case nothing will be sent
129 * @message: type of message
130 * @detail: detail field of message
131 * @data1: data1 field of message
132 * @data2: data2 field of message
134 * Sends a generic XEMBED message to a particular window.
137 _gtk_xembed_send_message (GdkWindow *recipient,
138 XEmbedMessageType message,
144 XClientMessageEvent xclient;
149 g_return_if_fail (GDK_IS_WINDOW (recipient));
151 display = gdk_window_get_display (recipient);
152 GTK_NOTE (PLUGSOCKET,
153 g_message ("Sending %s", _gtk_xembed_message_name (message)));
155 memset (&xclient, 0, sizeof (xclient));
156 xclient.window = GDK_WINDOW_XID (recipient);
157 xclient.type = ClientMessage;
158 xclient.message_type = gdk_x11_get_xatom_by_name_for_display (display, "_XEMBED");
160 xclient.data.l[0] = gtk_xembed_get_time ();
161 xclient.data.l[1] = message;
162 xclient.data.l[2] = detail;
163 xclient.data.l[3] = data1;
164 xclient.data.l[4] = data2;
166 gdk_error_trap_push ();
167 XSendEvent (GDK_WINDOW_XDISPLAY(recipient),
168 GDK_WINDOW_XID (recipient),
169 False, NoEventMask, (XEvent *)&xclient);
170 gdk_error_trap_pop_ignored ();
174 * _gtk_xembed_send_focus_message:
175 * @recipient: (allow-none): window to which to send the window, or %NULL
176 * in which case nothing will be sent
177 * @message: type of message
178 * @detail: detail field of message
180 * Sends a XEMBED message for moving the focus along the focus
181 * chain to a window. The flags field that these messages share
182 * will be correctly filled in.
185 _gtk_xembed_send_focus_message (GdkWindow *recipient,
186 XEmbedMessageType message,
194 g_return_if_fail (GDK_IS_WINDOW (recipient));
195 g_return_if_fail (message == XEMBED_FOCUS_IN ||
196 message == XEMBED_FOCUS_NEXT ||
197 message == XEMBED_FOCUS_PREV);
199 if (current_messages)
201 GtkXEmbedMessage *message = current_messages->data;
202 switch (message->message)
204 case XEMBED_FOCUS_IN:
205 case XEMBED_FOCUS_NEXT:
206 case XEMBED_FOCUS_PREV:
207 flags = message->data1 & XEMBED_FOCUS_WRAPAROUND;
214 _gtk_xembed_send_message (recipient, message, detail, flags, 0);
218 _gtk_xembed_message_name (XEmbedMessageType message)
224 #define CASE(x) case XEMBED_##x: return "XEMBED_"#x
225 CASE (EMBEDDED_NOTIFY);
226 CASE (WINDOW_ACTIVATE);
227 CASE (WINDOW_DEACTIVATE);
228 CASE (REQUEST_FOCUS);
238 CASE (GTK_UNGRAB_KEY);
241 snprintf (unk, 24, "UNKNOWN(%d)", message);