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