1 /* GTK - The GIMP Toolkit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3 * Copyright (C) 2005 Novell, 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 Free
17 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 /* By Tor Lillqvist <tml@novell.com> 2005 */
23 * Modified by the GTK+ Team and others 1997-2005. See the AUTHORS
24 * file for a list of people on the GTK+ Team. See the ChangeLog
25 * files for a list of changes. These files are distributed with
26 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
32 #include "gtkwindow.h"
34 #include "gtkprivate.h"
35 #include "gtksocket.h"
36 #include "gtksocketprivate.h"
38 #include "win32/gdkwin32.h"
40 #include "gtkwin32embed.h"
44 _gtk_socket_windowing_get_id (GtkSocket *socket)
46 g_return_val_if_fail (GTK_IS_SOCKET (socket), 0);
47 g_return_val_if_fail (GTK_WIDGET_ANCHORED (socket), 0);
49 if (!gtk_widget_get_realized (socket))
50 gtk_widget_realize (GTK_WIDGET (socket));
52 return (GdkNativeWindow) GDK_WINDOW_HWND (GTK_WIDGET (socket)->window);
56 _gtk_socket_windowing_realize_window (GtkSocket *socket)
58 /* XXX Anything needed? */
62 _gtk_socket_windowing_end_embedding_toplevel (GtkSocket *socket)
64 gtk_window_remove_embedded_xid (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (socket))),
65 GDK_WINDOW_HWND (socket->plug_window));
69 _gtk_socket_windowing_size_request (GtkSocket *socket)
73 socket->request_width = 1;
74 socket->request_height = 1;
76 mmi.ptMaxSize.x = mmi.ptMaxSize.y = 16000; /* ??? */
77 mmi.ptMinTrackSize.x = mmi.ptMinTrackSize.y = 1;
78 mmi.ptMaxTrackSize.x = mmi.ptMaxTrackSize.y = 16000; /* ??? */
79 mmi.ptMaxPosition.x = mmi.ptMaxPosition.y = 0;
81 if (SendMessage (GDK_WINDOW_HWND (socket->plug_window), WM_GETMINMAXINFO,
82 0, (LPARAM) &mmi) == 0)
84 socket->request_width = mmi.ptMinTrackSize.x;
85 socket->request_height = mmi.ptMinTrackSize.y;
87 socket->have_size = TRUE;
91 _gtk_socket_windowing_send_key_event (GtkSocket *socket,
93 gboolean mask_key_presses)
95 PostMessage (GDK_WINDOW_HWND (socket->plug_window),
96 (gdk_event->type == GDK_KEY_PRESS ? WM_KEYDOWN : WM_KEYUP),
97 gdk_event->key.hardware_keycode, 0);
101 _gtk_socket_windowing_focus_change (GtkSocket *socket,
105 _gtk_win32_embed_send_focus_message (socket->plug_window,
106 GTK_WIN32_EMBED_FOCUS_IN,
107 GTK_WIN32_EMBED_FOCUS_CURRENT);
109 _gtk_win32_embed_send (socket->plug_window,
110 GTK_WIN32_EMBED_FOCUS_OUT,
115 _gtk_socket_windowing_update_active (GtkSocket *socket,
118 _gtk_win32_embed_send (socket->plug_window,
119 (active ? GTK_WIN32_EMBED_WINDOW_ACTIVATE : GTK_WIN32_EMBED_WINDOW_DEACTIVATE),
124 _gtk_socket_windowing_update_modality (GtkSocket *socket,
127 _gtk_win32_embed_send (socket->plug_window,
128 (modality ? GTK_WIN32_EMBED_MODALITY_ON : GTK_WIN32_EMBED_MODALITY_OFF),
133 _gtk_socket_windowing_focus (GtkSocket *socket,
134 GtkDirectionType direction)
142 case GTK_DIR_TAB_BACKWARD:
143 detail = GTK_WIN32_EMBED_FOCUS_LAST;
147 case GTK_DIR_TAB_FORWARD:
148 detail = GTK_WIN32_EMBED_FOCUS_FIRST;
152 _gtk_win32_embed_send_focus_message (socket->plug_window,
153 GTK_WIN32_EMBED_FOCUS_IN,
158 _gtk_socket_windowing_send_configure_event (GtkSocket *socket)
160 /* XXX Nothing needed? */
164 _gtk_socket_windowing_select_plug_window_input (GtkSocket *socket)
166 /* XXX Nothing needed? */
170 _gtk_socket_windowing_embed_get_info (GtkSocket *socket)
172 socket->is_mapped = TRUE; /* XXX ? */
176 _gtk_socket_windowing_embed_notify (GtkSocket *socket)
178 /* XXX Nothing needed? */
182 _gtk_socket_windowing_embed_get_focus_wrapped (void)
184 return _gtk_win32_embed_get_focus_wrapped ();
188 _gtk_socket_windowing_embed_set_focus_wrapped (void)
190 _gtk_win32_embed_set_focus_wrapped ();
194 _gtk_socket_windowing_filter_func (GdkXEvent *gdk_xevent,
201 GdkFilterReturn return_val;
203 socket = GTK_SOCKET (data);
205 return_val = GDK_FILTER_CONTINUE;
207 if (socket->plug_widget)
210 widget = GTK_WIDGET (socket);
211 msg = (MSG *) gdk_xevent;
213 switch (msg->message)
216 if (msg->message == _gtk_win32_embed_message_type (GTK_WIN32_EMBED_PARENT_NOTIFY))
218 GTK_NOTE (PLUGSOCKET, g_printerr ("GtkSocket: PARENT_NOTIFY received window=%p version=%d\n",
219 (gpointer) msg->wParam, (int) msg->lParam));
220 /* If we some day different protocols deployed need to add
221 * some more elaborate version handshake
223 if (msg->lParam != GTK_WIN32_EMBED_PROTOCOL_VERSION)
224 g_warning ("GTK Win32 embedding protocol version mismatch, "
225 "client uses version %d, we understand version %d",
226 (int) msg->lParam, GTK_WIN32_EMBED_PROTOCOL_VERSION);
227 if (!socket->plug_window)
229 _gtk_socket_add_window (socket, (GdkNativeWindow) msg->wParam, FALSE);
231 if (socket->plug_window)
232 GTK_NOTE (PLUGSOCKET, g_printerr ("GtkSocket: window created"));
234 return_val = GDK_FILTER_REMOVE;
237 else if (msg->message == _gtk_win32_embed_message_type (GTK_WIN32_EMBED_EVENT_PLUG_MAPPED))
239 gboolean was_mapped = socket->is_mapped;
240 gboolean is_mapped = msg->wParam != 0;
242 GTK_NOTE (PLUGSOCKET, g_printerr ("GtkSocket: PLUG_MAPPED received is_mapped:%d\n", is_mapped));
243 if (was_mapped != is_mapped)
246 _gtk_socket_handle_map_request (socket);
249 gdk_window_show (socket->plug_window);
250 _gtk_socket_unmap_notify (socket);
253 return_val = GDK_FILTER_REMOVE;
255 else if (msg->message == _gtk_win32_embed_message_type (GTK_WIN32_EMBED_PLUG_RESIZED))
257 GTK_NOTE (PLUGSOCKET, g_printerr ("GtkSocket: PLUG_RESIZED received\n"));
258 socket->have_size = FALSE;
259 gtk_widget_queue_resize (widget);
260 return_val = GDK_FILTER_REMOVE;
262 else if (msg->message == _gtk_win32_embed_message_type (GTK_WIN32_EMBED_REQUEST_FOCUS))
264 GTK_NOTE (PLUGSOCKET, g_printerr ("GtkSocket: REQUEST_FOCUS received\n"));
265 _gtk_win32_embed_push_message (msg);
266 _gtk_socket_claim_focus (socket, TRUE);
267 _gtk_win32_embed_pop_message ();
268 return_val = GDK_FILTER_REMOVE;
270 else if (msg->message == _gtk_win32_embed_message_type (GTK_WIN32_EMBED_FOCUS_NEXT))
272 GTK_NOTE (PLUGSOCKET, g_printerr ("GtkSocket: FOCUS_NEXT received\n"));
273 _gtk_win32_embed_push_message (msg);
274 _gtk_socket_advance_toplevel_focus (socket, GTK_DIR_TAB_FORWARD);
275 _gtk_win32_embed_pop_message ();
276 return_val = GDK_FILTER_REMOVE;
278 else if (msg->message == _gtk_win32_embed_message_type (GTK_WIN32_EMBED_FOCUS_PREV))
280 GTK_NOTE (PLUGSOCKET, g_printerr ("GtkSocket: FOCUS_PREV received\n"));
281 _gtk_win32_embed_push_message (msg);
282 _gtk_socket_advance_toplevel_focus (socket, GTK_DIR_TAB_BACKWARD);
283 _gtk_win32_embed_pop_message ();
284 return_val = GDK_FILTER_REMOVE;
286 else if (msg->message == _gtk_win32_embed_message_type (GTK_WIN32_EMBED_GRAB_KEY))
288 GTK_NOTE (PLUGSOCKET, g_printerr ("GtkSocket: GRAB_KEY received\n"));
289 _gtk_win32_embed_push_message (msg);
290 _gtk_socket_add_grabbed_key (socket, msg->wParam, msg->lParam);
291 _gtk_win32_embed_pop_message ();
292 return_val = GDK_FILTER_REMOVE;
294 else if (msg->message == _gtk_win32_embed_message_type (GTK_WIN32_EMBED_UNGRAB_KEY))
296 GTK_NOTE (PLUGSOCKET, g_printerr ("GtkSocket: UNGRAB_KEY received\n"));
297 _gtk_win32_embed_push_message (msg);
298 _gtk_socket_remove_grabbed_key (socket, msg->wParam, msg->lParam);
299 _gtk_win32_embed_pop_message ();
300 return_val = GDK_FILTER_REMOVE;