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"
39 #include "win32/gdkwin32.h"
41 #include "gtkwin32embed.h"
42 #include "gtkwidgetprivate.h"
45 _gtk_socket_windowing_get_id (GtkSocket *socket)
47 g_return_val_if_fail (GTK_IS_SOCKET (socket), 0);
48 g_return_val_if_fail (_gtk_widget_get_anchored (GTK_WIDGET (socket)), 0);
50 if (!gtk_widget_get_realized (GTK_WIDGET (socket)))
51 gtk_widget_realize (GTK_WIDGET (socket));
53 return (GdkNativeWindow) GDK_WINDOW_HWND (gtk_widget_get_window (GTK_WIDGET (socket)));
57 _gtk_socket_windowing_realize_window (GtkSocket *socket)
59 /* XXX Anything needed? */
63 _gtk_socket_windowing_end_embedding_toplevel (GtkSocket *socket)
65 gtk_window_remove_embedded_xid (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (socket))),
66 GDK_WINDOW_HWND (socket->plug_window));
70 _gtk_socket_windowing_size_request (GtkSocket *socket)
74 socket->request_width = 1;
75 socket->request_height = 1;
77 mmi.ptMaxSize.x = mmi.ptMaxSize.y = 16000; /* ??? */
78 mmi.ptMinTrackSize.x = mmi.ptMinTrackSize.y = 1;
79 mmi.ptMaxTrackSize.x = mmi.ptMaxTrackSize.y = 16000; /* ??? */
80 mmi.ptMaxPosition.x = mmi.ptMaxPosition.y = 0;
82 if (SendMessage (GDK_WINDOW_HWND (socket->plug_window), WM_GETMINMAXINFO,
83 0, (LPARAM) &mmi) == 0)
85 socket->request_width = mmi.ptMinTrackSize.x;
86 socket->request_height = mmi.ptMinTrackSize.y;
88 socket->have_size = TRUE;
92 _gtk_socket_windowing_send_key_event (GtkSocket *socket,
94 gboolean mask_key_presses)
96 PostMessage (GDK_WINDOW_HWND (socket->plug_window),
97 (gdk_event->type == GDK_KEY_PRESS ? WM_KEYDOWN : WM_KEYUP),
98 gdk_event->key.hardware_keycode, 0);
102 _gtk_socket_windowing_focus_change (GtkSocket *socket,
106 _gtk_win32_embed_send_focus_message (socket->plug_window,
107 GTK_WIN32_EMBED_FOCUS_IN,
108 GTK_WIN32_EMBED_FOCUS_CURRENT);
110 _gtk_win32_embed_send (socket->plug_window,
111 GTK_WIN32_EMBED_FOCUS_OUT,
116 _gtk_socket_windowing_update_active (GtkSocket *socket,
119 _gtk_win32_embed_send (socket->plug_window,
120 (active ? GTK_WIN32_EMBED_WINDOW_ACTIVATE : GTK_WIN32_EMBED_WINDOW_DEACTIVATE),
125 _gtk_socket_windowing_update_modality (GtkSocket *socket,
128 _gtk_win32_embed_send (socket->plug_window,
129 (modality ? GTK_WIN32_EMBED_MODALITY_ON : GTK_WIN32_EMBED_MODALITY_OFF),
134 _gtk_socket_windowing_focus (GtkSocket *socket,
135 GtkDirectionType direction)
143 case GTK_DIR_TAB_BACKWARD:
144 detail = GTK_WIN32_EMBED_FOCUS_LAST;
148 case GTK_DIR_TAB_FORWARD:
149 detail = GTK_WIN32_EMBED_FOCUS_FIRST;
153 _gtk_win32_embed_send_focus_message (socket->plug_window,
154 GTK_WIN32_EMBED_FOCUS_IN,
159 _gtk_socket_windowing_send_configure_event (GtkSocket *socket)
161 /* XXX Nothing needed? */
165 _gtk_socket_windowing_select_plug_window_input (GtkSocket *socket)
167 /* XXX Nothing needed? */
171 _gtk_socket_windowing_embed_get_info (GtkSocket *socket)
173 socket->is_mapped = TRUE; /* XXX ? */
177 _gtk_socket_windowing_embed_notify (GtkSocket *socket)
179 /* XXX Nothing needed? */
183 _gtk_socket_windowing_embed_get_focus_wrapped (void)
185 return _gtk_win32_embed_get_focus_wrapped ();
189 _gtk_socket_windowing_embed_set_focus_wrapped (void)
191 _gtk_win32_embed_set_focus_wrapped ();
195 _gtk_socket_windowing_filter_func (GdkXEvent *gdk_xevent,
202 GdkFilterReturn return_val;
204 socket = GTK_SOCKET (data);
206 return_val = GDK_FILTER_CONTINUE;
208 if (socket->plug_widget)
211 widget = GTK_WIDGET (socket);
212 msg = (MSG *) gdk_xevent;
214 switch (msg->message)
217 if (msg->message == _gtk_win32_embed_message_type (GTK_WIN32_EMBED_PARENT_NOTIFY))
219 GTK_NOTE (PLUGSOCKET, g_printerr ("GtkSocket: PARENT_NOTIFY received window=%p version=%d\n",
220 (gpointer) msg->wParam, (int) msg->lParam));
221 /* If we some day different protocols deployed need to add
222 * some more elaborate version handshake
224 if (msg->lParam != GTK_WIN32_EMBED_PROTOCOL_VERSION)
225 g_warning ("GTK Win32 embedding protocol version mismatch, "
226 "client uses version %d, we understand version %d",
227 (int) msg->lParam, GTK_WIN32_EMBED_PROTOCOL_VERSION);
228 if (!socket->plug_window)
230 _gtk_socket_add_window (socket, (GdkNativeWindow) msg->wParam, FALSE);
232 if (socket->plug_window)
233 GTK_NOTE (PLUGSOCKET, g_printerr ("GtkSocket: window created"));
235 return_val = GDK_FILTER_REMOVE;
238 else if (msg->message == _gtk_win32_embed_message_type (GTK_WIN32_EMBED_EVENT_PLUG_MAPPED))
240 gboolean was_mapped = socket->is_mapped;
241 gboolean is_mapped = msg->wParam != 0;
243 GTK_NOTE (PLUGSOCKET, g_printerr ("GtkSocket: PLUG_MAPPED received is_mapped:%d\n", is_mapped));
244 if (was_mapped != is_mapped)
247 _gtk_socket_handle_map_request (socket);
250 gdk_window_show (socket->plug_window);
251 _gtk_socket_unmap_notify (socket);
254 return_val = GDK_FILTER_REMOVE;
256 else if (msg->message == _gtk_win32_embed_message_type (GTK_WIN32_EMBED_PLUG_RESIZED))
258 GTK_NOTE (PLUGSOCKET, g_printerr ("GtkSocket: PLUG_RESIZED received\n"));
259 socket->have_size = FALSE;
260 gtk_widget_queue_resize (widget);
261 return_val = GDK_FILTER_REMOVE;
263 else if (msg->message == _gtk_win32_embed_message_type (GTK_WIN32_EMBED_REQUEST_FOCUS))
265 GTK_NOTE (PLUGSOCKET, g_printerr ("GtkSocket: REQUEST_FOCUS received\n"));
266 _gtk_win32_embed_push_message (msg);
267 _gtk_socket_claim_focus (socket, TRUE);
268 _gtk_win32_embed_pop_message ();
269 return_val = GDK_FILTER_REMOVE;
271 else if (msg->message == _gtk_win32_embed_message_type (GTK_WIN32_EMBED_FOCUS_NEXT))
273 GTK_NOTE (PLUGSOCKET, g_printerr ("GtkSocket: FOCUS_NEXT received\n"));
274 _gtk_win32_embed_push_message (msg);
275 _gtk_socket_advance_toplevel_focus (socket, GTK_DIR_TAB_FORWARD);
276 _gtk_win32_embed_pop_message ();
277 return_val = GDK_FILTER_REMOVE;
279 else if (msg->message == _gtk_win32_embed_message_type (GTK_WIN32_EMBED_FOCUS_PREV))
281 GTK_NOTE (PLUGSOCKET, g_printerr ("GtkSocket: FOCUS_PREV received\n"));
282 _gtk_win32_embed_push_message (msg);
283 _gtk_socket_advance_toplevel_focus (socket, GTK_DIR_TAB_BACKWARD);
284 _gtk_win32_embed_pop_message ();
285 return_val = GDK_FILTER_REMOVE;
287 else if (msg->message == _gtk_win32_embed_message_type (GTK_WIN32_EMBED_GRAB_KEY))
289 GTK_NOTE (PLUGSOCKET, g_printerr ("GtkSocket: GRAB_KEY received\n"));
290 _gtk_win32_embed_push_message (msg);
291 _gtk_socket_add_grabbed_key (socket, msg->wParam, msg->lParam);
292 _gtk_win32_embed_pop_message ();
293 return_val = GDK_FILTER_REMOVE;
295 else if (msg->message == _gtk_win32_embed_message_type (GTK_WIN32_EMBED_UNGRAB_KEY))
297 GTK_NOTE (PLUGSOCKET, g_printerr ("GtkSocket: UNGRAB_KEY received\n"));
298 _gtk_win32_embed_push_message (msg);
299 _gtk_socket_remove_grabbed_key (socket, msg->wParam, msg->lParam);
300 _gtk_win32_embed_pop_message ();
301 return_val = GDK_FILTER_REMOVE;