]> Pileus Git - ~andy/gtk/blob - gtk/gtksocket-win32.c
gtkwocket-win32.c Added missing include to avoid C4013
[~andy/gtk] / gtk / gtksocket-win32.c
1 /* GTK - The GIMP Toolkit
2  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3  * Copyright (C) 2005 Novell, Inc.
4  *
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.
9  *
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.
14  *
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.
18  */
19
20 /* By Tor Lillqvist <tml@novell.com> 2005 */
21
22 /*
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/. 
27  */
28
29 #include "config.h"
30 #include <string.h>
31
32 #include "gtkwindow.h"
33 #include "gtkplug.h"
34 #include "gtkprivate.h"
35 #include "gtksocket.h"
36 #include "gtksocketprivate.h"
37 #include "gtkdebug.h"
38
39 #include "win32/gdkwin32.h"
40
41 #include "gtkwin32embed.h"
42 #include "gtkwidgetprivate.h"
43
44 GdkNativeWindow
45 _gtk_socket_windowing_get_id (GtkSocket *socket)
46 {
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);
49
50   if (!gtk_widget_get_realized (GTK_WIDGET (socket)))
51     gtk_widget_realize (GTK_WIDGET (socket));
52
53   return (GdkNativeWindow) GDK_WINDOW_HWND (gtk_widget_get_window (GTK_WIDGET (socket)));
54 }
55
56 void
57 _gtk_socket_windowing_realize_window (GtkSocket *socket)
58 {
59   /* XXX Anything needed? */
60 }
61
62 void
63 _gtk_socket_windowing_end_embedding_toplevel (GtkSocket *socket)
64 {
65   gtk_window_remove_embedded_xid (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (socket))),
66                                   GDK_WINDOW_HWND (socket->plug_window));
67 }
68
69 void
70 _gtk_socket_windowing_size_request (GtkSocket *socket)
71 {
72   MINMAXINFO mmi;
73
74   socket->request_width = 1;
75   socket->request_height = 1;
76   
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;
81
82   if (SendMessage (GDK_WINDOW_HWND (socket->plug_window), WM_GETMINMAXINFO,
83                    0, (LPARAM) &mmi) == 0)
84     {
85       socket->request_width = mmi.ptMinTrackSize.x;
86       socket->request_height = mmi.ptMinTrackSize.y;
87     }
88   socket->have_size = TRUE;
89 }
90
91 void
92 _gtk_socket_windowing_send_key_event (GtkSocket *socket,
93                                       GdkEvent  *gdk_event,
94                                       gboolean   mask_key_presses)
95 {
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);
99 }
100
101 void
102 _gtk_socket_windowing_focus_change (GtkSocket *socket,
103                                     gboolean   focus_in)
104 {
105   if (focus_in)
106     _gtk_win32_embed_send_focus_message (socket->plug_window,
107                                          GTK_WIN32_EMBED_FOCUS_IN,
108                                          GTK_WIN32_EMBED_FOCUS_CURRENT);
109   else
110     _gtk_win32_embed_send (socket->plug_window,
111                            GTK_WIN32_EMBED_FOCUS_OUT,
112                            0, 0);
113 }
114
115 void
116 _gtk_socket_windowing_update_active (GtkSocket *socket,
117                                      gboolean   active)
118 {
119   _gtk_win32_embed_send (socket->plug_window,
120                          (active ? GTK_WIN32_EMBED_WINDOW_ACTIVATE : GTK_WIN32_EMBED_WINDOW_DEACTIVATE),
121                          0, 0);
122 }
123
124 void
125 _gtk_socket_windowing_update_modality (GtkSocket *socket,
126                                        gboolean   modality)
127 {
128   _gtk_win32_embed_send (socket->plug_window,
129                          (modality ? GTK_WIN32_EMBED_MODALITY_ON : GTK_WIN32_EMBED_MODALITY_OFF),
130                          0, 0);
131 }
132
133 void
134 _gtk_socket_windowing_focus (GtkSocket       *socket,
135                              GtkDirectionType direction)
136 {
137   int detail = -1;
138
139   switch (direction)
140     {
141     case GTK_DIR_UP:
142     case GTK_DIR_LEFT:
143     case GTK_DIR_TAB_BACKWARD:
144       detail = GTK_WIN32_EMBED_FOCUS_LAST;
145       break;
146     case GTK_DIR_DOWN:
147     case GTK_DIR_RIGHT:
148     case GTK_DIR_TAB_FORWARD:
149       detail = GTK_WIN32_EMBED_FOCUS_FIRST;
150       break;
151     }
152   
153   _gtk_win32_embed_send_focus_message (socket->plug_window,
154                                        GTK_WIN32_EMBED_FOCUS_IN,
155                                        detail);
156 }
157
158 void
159 _gtk_socket_windowing_send_configure_event (GtkSocket *socket)
160 {
161   /* XXX Nothing needed? */
162 }
163
164 void
165 _gtk_socket_windowing_select_plug_window_input (GtkSocket *socket)
166 {
167   /* XXX Nothing needed? */
168 }
169
170 void
171 _gtk_socket_windowing_embed_get_info (GtkSocket *socket)
172 {
173   socket->is_mapped = TRUE;     /* XXX ? */
174 }
175
176 void
177 _gtk_socket_windowing_embed_notify (GtkSocket *socket)
178 {
179   /* XXX Nothing needed? */
180 }
181
182 gboolean
183 _gtk_socket_windowing_embed_get_focus_wrapped (void)
184 {
185   return _gtk_win32_embed_get_focus_wrapped ();
186 }
187
188 void
189 _gtk_socket_windowing_embed_set_focus_wrapped (void)
190 {
191   _gtk_win32_embed_set_focus_wrapped ();
192 }
193
194 GdkFilterReturn
195 _gtk_socket_windowing_filter_func (GdkXEvent *gdk_xevent,
196                                    GdkEvent  *event,
197                                    gpointer   data)
198 {
199   GtkSocket *socket;
200   GtkWidget *widget;
201   MSG *msg;
202   GdkFilterReturn return_val;
203
204   socket = GTK_SOCKET (data);
205
206   return_val = GDK_FILTER_CONTINUE;
207
208   if (socket->plug_widget)
209     return return_val;
210
211   widget = GTK_WIDGET (socket);
212   msg = (MSG *) gdk_xevent;
213
214   switch (msg->message)
215     {
216     default:
217       if (msg->message == _gtk_win32_embed_message_type (GTK_WIN32_EMBED_PARENT_NOTIFY))
218         {
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
223            */
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)
229             {
230               _gtk_socket_add_window (socket, (GdkNativeWindow) msg->wParam, FALSE);
231               
232               if (socket->plug_window)
233                 GTK_NOTE (PLUGSOCKET, g_printerr ("GtkSocket: window created"));
234               
235               return_val = GDK_FILTER_REMOVE;
236             }
237         }
238       else if (msg->message == _gtk_win32_embed_message_type (GTK_WIN32_EMBED_EVENT_PLUG_MAPPED))
239         {
240           gboolean was_mapped = socket->is_mapped;
241           gboolean is_mapped = msg->wParam != 0;
242
243           GTK_NOTE (PLUGSOCKET, g_printerr ("GtkSocket: PLUG_MAPPED received is_mapped:%d\n", is_mapped));
244           if (was_mapped != is_mapped)
245             {
246               if (is_mapped)
247                 _gtk_socket_handle_map_request (socket);
248               else
249                 {
250                   gdk_window_show (socket->plug_window);
251                   _gtk_socket_unmap_notify (socket);
252                 }
253             }
254           return_val = GDK_FILTER_REMOVE;
255         }
256       else if (msg->message == _gtk_win32_embed_message_type (GTK_WIN32_EMBED_PLUG_RESIZED))
257         {
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;
262         }
263       else if (msg->message == _gtk_win32_embed_message_type (GTK_WIN32_EMBED_REQUEST_FOCUS))
264         {
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;
270         }
271       else if (msg->message == _gtk_win32_embed_message_type (GTK_WIN32_EMBED_FOCUS_NEXT))
272         {
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;
278         }
279       else if (msg->message == _gtk_win32_embed_message_type (GTK_WIN32_EMBED_FOCUS_PREV))
280         {
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;
286         }
287       else if (msg->message == _gtk_win32_embed_message_type (GTK_WIN32_EMBED_GRAB_KEY))
288         {
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;
294         }
295       else if (msg->message == _gtk_win32_embed_message_type (GTK_WIN32_EMBED_UNGRAB_KEY))
296         {
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;
302         }
303       break;
304     }
305
306   return return_val;
307 }
308