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"
43 _gtk_socket_windowing_get_id (GtkSocket *socket)
45 g_return_val_if_fail (GTK_IS_SOCKET (socket), 0);
46 g_return_val_if_fail (GTK_WIDGET_ANCHORED (socket), 0);
48 if (!gtk_widget_get_realized (GTK_WIDGET (socket)))
49 gtk_widget_realize (GTK_WIDGET (socket));
51 return (GdkNativeWindow) GDK_WINDOW_HWND (gtk_widget_get_window (GTK_WIDGET (socket)));
55 _gtk_socket_windowing_realize_window (GtkSocket *socket)
57 /* XXX Anything needed? */
61 _gtk_socket_windowing_end_embedding_toplevel (GtkSocket *socket)
63 gtk_window_remove_embedded_xid (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (socket))),
64 GDK_WINDOW_HWND (socket->plug_window));
68 _gtk_socket_windowing_size_request (GtkSocket *socket)
72 socket->request_width = 1;
73 socket->request_height = 1;
75 mmi.ptMaxSize.x = mmi.ptMaxSize.y = 16000; /* ??? */
76 mmi.ptMinTrackSize.x = mmi.ptMinTrackSize.y = 1;
77 mmi.ptMaxTrackSize.x = mmi.ptMaxTrackSize.y = 16000; /* ??? */
78 mmi.ptMaxPosition.x = mmi.ptMaxPosition.y = 0;
80 if (SendMessage (GDK_WINDOW_HWND (socket->plug_window), WM_GETMINMAXINFO,
81 0, (LPARAM) &mmi) == 0)
83 socket->request_width = mmi.ptMinTrackSize.x;
84 socket->request_height = mmi.ptMinTrackSize.y;
86 socket->have_size = TRUE;
90 _gtk_socket_windowing_send_key_event (GtkSocket *socket,
92 gboolean mask_key_presses)
94 PostMessage (GDK_WINDOW_HWND (socket->plug_window),
95 (gdk_event->type == GDK_KEY_PRESS ? WM_KEYDOWN : WM_KEYUP),
96 gdk_event->key.hardware_keycode, 0);
100 _gtk_socket_windowing_focus_change (GtkSocket *socket,
104 _gtk_win32_embed_send_focus_message (socket->plug_window,
105 GTK_WIN32_EMBED_FOCUS_IN,
106 GTK_WIN32_EMBED_FOCUS_CURRENT);
108 _gtk_win32_embed_send (socket->plug_window,
109 GTK_WIN32_EMBED_FOCUS_OUT,
114 _gtk_socket_windowing_update_active (GtkSocket *socket,
117 _gtk_win32_embed_send (socket->plug_window,
118 (active ? GTK_WIN32_EMBED_WINDOW_ACTIVATE : GTK_WIN32_EMBED_WINDOW_DEACTIVATE),
123 _gtk_socket_windowing_update_modality (GtkSocket *socket,
126 _gtk_win32_embed_send (socket->plug_window,
127 (modality ? GTK_WIN32_EMBED_MODALITY_ON : GTK_WIN32_EMBED_MODALITY_OFF),
132 _gtk_socket_windowing_focus (GtkSocket *socket,
133 GtkDirectionType direction)
141 case GTK_DIR_TAB_BACKWARD:
142 detail = GTK_WIN32_EMBED_FOCUS_LAST;
146 case GTK_DIR_TAB_FORWARD:
147 detail = GTK_WIN32_EMBED_FOCUS_FIRST;
151 _gtk_win32_embed_send_focus_message (socket->plug_window,
152 GTK_WIN32_EMBED_FOCUS_IN,
157 _gtk_socket_windowing_send_configure_event (GtkSocket *socket)
159 /* XXX Nothing needed? */
163 _gtk_socket_windowing_select_plug_window_input (GtkSocket *socket)
165 /* XXX Nothing needed? */
169 _gtk_socket_windowing_embed_get_info (GtkSocket *socket)
171 socket->is_mapped = TRUE; /* XXX ? */
175 _gtk_socket_windowing_embed_notify (GtkSocket *socket)
177 /* XXX Nothing needed? */
181 _gtk_socket_windowing_embed_get_focus_wrapped (void)
183 return _gtk_win32_embed_get_focus_wrapped ();
187 _gtk_socket_windowing_embed_set_focus_wrapped (void)
189 _gtk_win32_embed_set_focus_wrapped ();
193 _gtk_socket_windowing_filter_func (GdkXEvent *gdk_xevent,
200 GdkFilterReturn return_val;
202 socket = GTK_SOCKET (data);
204 return_val = GDK_FILTER_CONTINUE;
206 if (socket->plug_widget)
209 widget = GTK_WIDGET (socket);
210 msg = (MSG *) gdk_xevent;
212 switch (msg->message)
215 if (msg->message == _gtk_win32_embed_message_type (GTK_WIN32_EMBED_PARENT_NOTIFY))
217 GTK_NOTE (PLUGSOCKET, g_printerr ("GtkSocket: PARENT_NOTIFY received window=%p version=%d\n",
218 (gpointer) msg->wParam, (int) msg->lParam));
219 /* If we some day different protocols deployed need to add
220 * some more elaborate version handshake
222 if (msg->lParam != GTK_WIN32_EMBED_PROTOCOL_VERSION)
223 g_warning ("GTK Win32 embedding protocol version mismatch, "
224 "client uses version %d, we understand version %d",
225 (int) msg->lParam, GTK_WIN32_EMBED_PROTOCOL_VERSION);
226 if (!socket->plug_window)
228 _gtk_socket_add_window (socket, (GdkNativeWindow) msg->wParam, FALSE);
230 if (socket->plug_window)
231 GTK_NOTE (PLUGSOCKET, g_printerr ("GtkSocket: window created"));
233 return_val = GDK_FILTER_REMOVE;
236 else if (msg->message == _gtk_win32_embed_message_type (GTK_WIN32_EMBED_EVENT_PLUG_MAPPED))
238 gboolean was_mapped = socket->is_mapped;
239 gboolean is_mapped = msg->wParam != 0;
241 GTK_NOTE (PLUGSOCKET, g_printerr ("GtkSocket: PLUG_MAPPED received is_mapped:%d\n", is_mapped));
242 if (was_mapped != is_mapped)
245 _gtk_socket_handle_map_request (socket);
248 gdk_window_show (socket->plug_window);
249 _gtk_socket_unmap_notify (socket);
252 return_val = GDK_FILTER_REMOVE;
254 else if (msg->message == _gtk_win32_embed_message_type (GTK_WIN32_EMBED_PLUG_RESIZED))
256 GTK_NOTE (PLUGSOCKET, g_printerr ("GtkSocket: PLUG_RESIZED received\n"));
257 socket->have_size = FALSE;
258 gtk_widget_queue_resize (widget);
259 return_val = GDK_FILTER_REMOVE;
261 else if (msg->message == _gtk_win32_embed_message_type (GTK_WIN32_EMBED_REQUEST_FOCUS))
263 GTK_NOTE (PLUGSOCKET, g_printerr ("GtkSocket: REQUEST_FOCUS received\n"));
264 _gtk_win32_embed_push_message (msg);
265 _gtk_socket_claim_focus (socket, TRUE);
266 _gtk_win32_embed_pop_message ();
267 return_val = GDK_FILTER_REMOVE;
269 else if (msg->message == _gtk_win32_embed_message_type (GTK_WIN32_EMBED_FOCUS_NEXT))
271 GTK_NOTE (PLUGSOCKET, g_printerr ("GtkSocket: FOCUS_NEXT received\n"));
272 _gtk_win32_embed_push_message (msg);
273 _gtk_socket_advance_toplevel_focus (socket, GTK_DIR_TAB_FORWARD);
274 _gtk_win32_embed_pop_message ();
275 return_val = GDK_FILTER_REMOVE;
277 else if (msg->message == _gtk_win32_embed_message_type (GTK_WIN32_EMBED_FOCUS_PREV))
279 GTK_NOTE (PLUGSOCKET, g_printerr ("GtkSocket: FOCUS_PREV received\n"));
280 _gtk_win32_embed_push_message (msg);
281 _gtk_socket_advance_toplevel_focus (socket, GTK_DIR_TAB_BACKWARD);
282 _gtk_win32_embed_pop_message ();
283 return_val = GDK_FILTER_REMOVE;
285 else if (msg->message == _gtk_win32_embed_message_type (GTK_WIN32_EMBED_GRAB_KEY))
287 GTK_NOTE (PLUGSOCKET, g_printerr ("GtkSocket: GRAB_KEY received\n"));
288 _gtk_win32_embed_push_message (msg);
289 _gtk_socket_add_grabbed_key (socket, msg->wParam, msg->lParam);
290 _gtk_win32_embed_pop_message ();
291 return_val = GDK_FILTER_REMOVE;
293 else if (msg->message == _gtk_win32_embed_message_type (GTK_WIN32_EMBED_UNGRAB_KEY))
295 GTK_NOTE (PLUGSOCKET, g_printerr ("GtkSocket: UNGRAB_KEY received\n"));
296 _gtk_win32_embed_push_message (msg);
297 _gtk_socket_remove_grabbed_key (socket, msg->wParam, msg->lParam);
298 _gtk_win32_embed_pop_message ();
299 return_val = GDK_FILTER_REMOVE;