]> Pileus Git - ~andy/gtk/blob - gtk/gtksocket-win32.c
accellabel: Remove gtk_widget_is_drawable() check from draw vfunc
[~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
38 #include "win32/gdkwin32.h"
39
40 #include "gtkwin32embed.h"
41
42 GdkNativeWindow
43 _gtk_socket_windowing_get_id (GtkSocket *socket)
44 {
45   g_return_val_if_fail (GTK_IS_SOCKET (socket), 0);
46   g_return_val_if_fail (GTK_WIDGET_ANCHORED (socket), 0);
47
48   if (!gtk_widget_get_realized (GTK_WIDGET (socket)))
49     gtk_widget_realize (GTK_WIDGET (socket));
50
51   return (GdkNativeWindow) GDK_WINDOW_HWND (gtk_widget_get_window (GTK_WIDGET (socket)));
52 }
53
54 void
55 _gtk_socket_windowing_realize_window (GtkSocket *socket)
56 {
57   /* XXX Anything needed? */
58 }
59
60 void
61 _gtk_socket_windowing_end_embedding_toplevel (GtkSocket *socket)
62 {
63   gtk_window_remove_embedded_xid (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (socket))),
64                                   GDK_WINDOW_HWND (socket->plug_window));
65 }
66
67 void
68 _gtk_socket_windowing_size_request (GtkSocket *socket)
69 {
70   MINMAXINFO mmi;
71
72   socket->request_width = 1;
73   socket->request_height = 1;
74   
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;
79
80   if (SendMessage (GDK_WINDOW_HWND (socket->plug_window), WM_GETMINMAXINFO,
81                    0, (LPARAM) &mmi) == 0)
82     {
83       socket->request_width = mmi.ptMinTrackSize.x;
84       socket->request_height = mmi.ptMinTrackSize.y;
85     }
86   socket->have_size = TRUE;
87 }
88
89 void
90 _gtk_socket_windowing_send_key_event (GtkSocket *socket,
91                                       GdkEvent  *gdk_event,
92                                       gboolean   mask_key_presses)
93 {
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);
97 }
98
99 void
100 _gtk_socket_windowing_focus_change (GtkSocket *socket,
101                                     gboolean   focus_in)
102 {
103   if (focus_in)
104     _gtk_win32_embed_send_focus_message (socket->plug_window,
105                                          GTK_WIN32_EMBED_FOCUS_IN,
106                                          GTK_WIN32_EMBED_FOCUS_CURRENT);
107   else
108     _gtk_win32_embed_send (socket->plug_window,
109                            GTK_WIN32_EMBED_FOCUS_OUT,
110                            0, 0);
111 }
112
113 void
114 _gtk_socket_windowing_update_active (GtkSocket *socket,
115                                      gboolean   active)
116 {
117   _gtk_win32_embed_send (socket->plug_window,
118                          (active ? GTK_WIN32_EMBED_WINDOW_ACTIVATE : GTK_WIN32_EMBED_WINDOW_DEACTIVATE),
119                          0, 0);
120 }
121
122 void
123 _gtk_socket_windowing_update_modality (GtkSocket *socket,
124                                        gboolean   modality)
125 {
126   _gtk_win32_embed_send (socket->plug_window,
127                          (modality ? GTK_WIN32_EMBED_MODALITY_ON : GTK_WIN32_EMBED_MODALITY_OFF),
128                          0, 0);
129 }
130
131 void
132 _gtk_socket_windowing_focus (GtkSocket       *socket,
133                              GtkDirectionType direction)
134 {
135   int detail = -1;
136
137   switch (direction)
138     {
139     case GTK_DIR_UP:
140     case GTK_DIR_LEFT:
141     case GTK_DIR_TAB_BACKWARD:
142       detail = GTK_WIN32_EMBED_FOCUS_LAST;
143       break;
144     case GTK_DIR_DOWN:
145     case GTK_DIR_RIGHT:
146     case GTK_DIR_TAB_FORWARD:
147       detail = GTK_WIN32_EMBED_FOCUS_FIRST;
148       break;
149     }
150   
151   _gtk_win32_embed_send_focus_message (socket->plug_window,
152                                        GTK_WIN32_EMBED_FOCUS_IN,
153                                        detail);
154 }
155
156 void
157 _gtk_socket_windowing_send_configure_event (GtkSocket *socket)
158 {
159   /* XXX Nothing needed? */
160 }
161
162 void
163 _gtk_socket_windowing_select_plug_window_input (GtkSocket *socket)
164 {
165   /* XXX Nothing needed? */
166 }
167
168 void
169 _gtk_socket_windowing_embed_get_info (GtkSocket *socket)
170 {
171   socket->is_mapped = TRUE;     /* XXX ? */
172 }
173
174 void
175 _gtk_socket_windowing_embed_notify (GtkSocket *socket)
176 {
177   /* XXX Nothing needed? */
178 }
179
180 gboolean
181 _gtk_socket_windowing_embed_get_focus_wrapped (void)
182 {
183   return _gtk_win32_embed_get_focus_wrapped ();
184 }
185
186 void
187 _gtk_socket_windowing_embed_set_focus_wrapped (void)
188 {
189   _gtk_win32_embed_set_focus_wrapped ();
190 }
191
192 GdkFilterReturn
193 _gtk_socket_windowing_filter_func (GdkXEvent *gdk_xevent,
194                                    GdkEvent  *event,
195                                    gpointer   data)
196 {
197   GtkSocket *socket;
198   GtkWidget *widget;
199   MSG *msg;
200   GdkFilterReturn return_val;
201
202   socket = GTK_SOCKET (data);
203
204   return_val = GDK_FILTER_CONTINUE;
205
206   if (socket->plug_widget)
207     return return_val;
208
209   widget = GTK_WIDGET (socket);
210   msg = (MSG *) gdk_xevent;
211
212   switch (msg->message)
213     {
214     default:
215       if (msg->message == _gtk_win32_embed_message_type (GTK_WIN32_EMBED_PARENT_NOTIFY))
216         {
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
221            */
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)
227             {
228               _gtk_socket_add_window (socket, (GdkNativeWindow) msg->wParam, FALSE);
229               
230               if (socket->plug_window)
231                 GTK_NOTE (PLUGSOCKET, g_printerr ("GtkSocket: window created"));
232               
233               return_val = GDK_FILTER_REMOVE;
234             }
235         }
236       else if (msg->message == _gtk_win32_embed_message_type (GTK_WIN32_EMBED_EVENT_PLUG_MAPPED))
237         {
238           gboolean was_mapped = socket->is_mapped;
239           gboolean is_mapped = msg->wParam != 0;
240
241           GTK_NOTE (PLUGSOCKET, g_printerr ("GtkSocket: PLUG_MAPPED received is_mapped:%d\n", is_mapped));
242           if (was_mapped != is_mapped)
243             {
244               if (is_mapped)
245                 _gtk_socket_handle_map_request (socket);
246               else
247                 {
248                   gdk_window_show (socket->plug_window);
249                   _gtk_socket_unmap_notify (socket);
250                 }
251             }
252           return_val = GDK_FILTER_REMOVE;
253         }
254       else if (msg->message == _gtk_win32_embed_message_type (GTK_WIN32_EMBED_PLUG_RESIZED))
255         {
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;
260         }
261       else if (msg->message == _gtk_win32_embed_message_type (GTK_WIN32_EMBED_REQUEST_FOCUS))
262         {
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;
268         }
269       else if (msg->message == _gtk_win32_embed_message_type (GTK_WIN32_EMBED_FOCUS_NEXT))
270         {
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;
276         }
277       else if (msg->message == _gtk_win32_embed_message_type (GTK_WIN32_EMBED_FOCUS_PREV))
278         {
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;
284         }
285       else if (msg->message == _gtk_win32_embed_message_type (GTK_WIN32_EMBED_GRAB_KEY))
286         {
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;
292         }
293       else if (msg->message == _gtk_win32_embed_message_type (GTK_WIN32_EMBED_UNGRAB_KEY))
294         {
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;
300         }
301       break;
302     }
303
304   return return_val;
305 }
306