1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3 * windowless.cpp: Windowsless Surface subclass
6 * Moonlight List (moonlight-list@lists.ximian.com)
8 * Copyright 2007 Novell, Inc. (http://www.novell.com)
10 * See the LICENSE file included with the distribution for details.
16 #include "windowless.h"
18 #define Visual _XxVisual
19 #define Region _XxRegion
30 MoonWindowless::MoonWindowless (int width
, int height
, PluginInstance
*plugin
)
31 : MoonWindow (width
, height
)
33 this->deployment
= Deployment::GetCurrent ();
34 this->plugin
= plugin
;
40 MoonWindowless::UpdateWindowInfo ()
42 // It appears opera doesn't do a good job of keeping the NPWindow members valid
43 // between SetWindow calls so we have to work around this by copying the members
44 // we need. This is really ugly.
46 NPWindow
*window
= plugin
->GetWindow();
47 NPSetWindowCallbackStruct
*ws_info
= (NPSetWindowCallbackStruct
*)window
->ws_info
;
48 visualid
= ws_info
->visual
? visualid
= ws_info
->visual
->visualid
: 0;
54 MoonWindowless::Resize (int width
, int height
)
56 bool emit_resize
= false;
60 if (this->width
!= width
|| this->height
!= height
) {
62 this->height
= height
;
67 surface
->HandleUIWindowAllocation (emit_resize
);
71 MoonWindowless::SetCursor (MouseCursor cursor
)
73 #if (NP_VERSION_MINOR >= NPVERS_HAS_WINDOWLESS_CURSORS)
76 case MouseCursorDefault
:
77 npcursor
= NPCursorAuto
;
79 case MouseCursorArrow
:
80 npcursor
= NPCursorPointer
;
83 npcursor
= NPCursorWait
;
85 case MouseCursorIBeam
:
86 npcursor
= NPCursorText
;
88 case MouseCursorStylus
:
89 npcursor
= NPCursorPointer
; // XXX ugh...
91 case MouseCursorEraser
:
92 npcursor
= NPCursorPointer
; // XXX ugh...
95 // Silverlight display no cursor if the enumeration value is invalid (e.g. -1)
97 npcursor
= NPCursorNone
;
101 NPN_SetValue (plugin
->GetInstance(), NPPVcursor
, (void*)npcursor
);
106 MoonWindowless::Invalidate (Rect r
)
110 // Mozilla gets seriously confused about invalidations
111 // outside the windowless bounds.
112 r
= r
.Intersection (Rect (0, 0, GetWidth(), GetHeight())).RoundOut ();
114 nprect
.left
= (uint16_t)r
.x
;
115 nprect
.top
= (uint16_t)r
.y
;
116 nprect
.right
= (uint16_t)(r
.x
+ r
.width
);
117 nprect
.bottom
= (uint16_t)(r
.y
+ r
.height
);
119 NPN_InvalidateRect (plugin
->GetInstance(), &nprect
);
123 MoonWindowless::ProcessUpdates ()
125 //NPN_ForceRedraw (plugin->GetInstance());
129 MoonWindowless::HandleEvent (XEvent
*event
)
131 XEvent
*xev
= (XEvent
*)event
;
132 gboolean handled
= FALSE
;
134 Deployment::SetCurrent (deployment
);
137 case GraphicsExpose
: {
138 GdkDrawable
*drawable
= gdk_pixmap_foreign_new ((GdkNativeWindow
)xev
->xgraphicsexpose
.drawable
);
140 drawable
= gdk_window_foreign_new ((GdkNativeWindow
)xev
->xgraphicsexpose
.drawable
);
144 GdkVisual
*visual
= gdkx_visual_get (visualid
);
147 GdkEventExpose expose
;
149 expose
.type
= GDK_EXPOSE
;
150 expose
.window
= NULL
;
151 expose
.send_event
= FALSE
;
152 expose
.area
= Rect (xev
->xgraphicsexpose
.x
,
153 xev
->xgraphicsexpose
.y
,
154 xev
->xgraphicsexpose
.width
,
155 xev
->xgraphicsexpose
.height
).ToGdkRectangle ();
157 expose
.region
= gdk_region_rectangle (&expose
.area
);
159 expose
.area
.x
= expose
.area
.y
= 0;
161 surface
->PaintToDrawable (drawable
, visual
, &expose
, x
, y
, GetTransparent(), false);
164 gdk_region_destroy (expose
.region
);
166 d(printf ("no gdk visual\n"));
169 g_object_unref (drawable
);
171 d(printf ("no gdk drawable\n"));
176 GdkEventMotion motion
;
178 motion
.type
= GDK_MOTION_NOTIFY
;
179 motion
.window
= NULL
;
180 motion
.send_event
= xev
->xmotion
.send_event
;
181 motion
.x
= xev
->xmotion
.x
;
182 motion
.y
= xev
->xmotion
.y
;
184 motion
.state
= xev
->xmotion
.state
;
185 motion
.is_hint
= xev
->xmotion
.is_hint
;
186 motion
.device
= NULL
; // XXX
187 motion
.x_root
= xev
->xmotion
.x_root
;
188 motion
.y_root
= xev
->xmotion
.y_root
;
190 handled
= surface
->HandleUIMotion (&motion
);
194 case ButtonRelease
: {
195 GdkEventButton button
;
197 button
.type
= xev
->type
== ButtonPress
? GDK_BUTTON_PRESS
: GDK_BUTTON_RELEASE
;
198 button
.window
= NULL
;
199 button
.send_event
= xev
->xbutton
.send_event
;
200 button
.time
= xev
->xbutton
.time
;
201 button
.x
= xev
->xbutton
.x
;
202 button
.y
= xev
->xbutton
.y
;
203 button
.x_root
= xev
->xbutton
.x_root
;
204 button
.y_root
= xev
->xbutton
.y_root
;
205 button
.state
= xev
->xbutton
.state
;
206 button
.button
= xev
->xbutton
.button
;
209 if (xev
->type
== ButtonPress
)
210 handled
= PluginInstance::plugin_button_press_callback (NULL
, &button
, plugin
);
212 if (xev
->type
== ButtonPress
)
213 handled
= surface
->HandleUIButtonPress (&button
);
215 handled
= surface
->HandleUIButtonRelease (&button
);
221 // make sure everything is initialized correctly (structure members vary with gdk version)
222 GdkEventKey
*key
= (GdkEventKey
*) gdk_event_new (xev
->type
== KeyPress
? GDK_KEY_PRESS
: GDK_KEY_RELEASE
);
223 // gtk_im_context_xim_filter_keypress will dereference the NULL window leading to a SEGSIGV
224 key
->window
= GetGdkWindow ();
225 key
->send_event
= xev
->xkey
.send_event
;
226 key
->time
= xev
->xkey
.time
;
227 key
->state
= xev
->xkey
.state
;
228 key
->hardware_keycode
= xev
->xkey
.keycode
;
230 gint effective_group
;
232 gdk_keymap_translate_keyboard_state (gdk_keymap_get_default (),
234 (GdkModifierType
)xev
->xkey
.state
, // XXX
241 key
->group
= (guint8
)effective_group
;
243 if (xev
->type
== KeyPress
)
244 handled
= surface
->HandleUIKeyPress (key
);
246 handled
= surface
->HandleUIKeyRelease (key
);
248 gdk_event_free ((GdkEvent
*) key
);
253 GdkEventCrossing crossing
;
255 crossing
.type
= xev
->type
== EnterNotify
? GDK_ENTER_NOTIFY
: GDK_LEAVE_NOTIFY
;
256 crossing
.window
= crossing
.subwindow
= NULL
;
257 crossing
.send_event
= xev
->xcrossing
.send_event
;
258 crossing
.time
= xev
->xcrossing
.time
;
259 crossing
.x
= xev
->xcrossing
.x
;
260 crossing
.y
= xev
->xcrossing
.y
;
261 crossing
.x_root
= xev
->xcrossing
.x_root
;
262 crossing
.y_root
= xev
->xcrossing
.y_root
;
263 // crossing.mode = (GdkCrossingMode)xev->xcrossing.mode; // XXX
264 crossing
.mode
= GDK_CROSSING_NORMAL
;
265 crossing
.detail
= (GdkNotifyType
)xev
->xcrossing
.detail
; // XXX
266 crossing
.focus
= xev
->xcrossing
.focus
;
267 crossing
.state
= xev
->xcrossing
.state
;
269 surface
->HandleUICrossing (&crossing
);
273 surface
->HandleUIFocusIn (NULL
);
278 surface
->HandleUIFocusOut (NULL
);
282 d(printf ("Unhandled Xlib event %d\n", xev
->type
));
290 MoonWindowless::Show ()
292 // nothing needed here
296 MoonWindowless::Hide ()
298 // nothing needed here
302 MoonWindowless::EnableEvents (bool first
)
304 // nothing needed here, NPAPI pushes events through
309 MoonWindowless::DisableEvents ()
311 // nothing needed here, NPAPI pushes events through
316 MoonWindowless::GrabFocus ()
318 // we can't grab focus - the browser handles that.
322 MoonWindowless::HasFocus ()
324 // XXX maybe we should track the focus in/out events?
329 MoonWindowless::SetSurface (Surface
*s
)
331 MoonWindow::SetSurface (s
);
332 s
->HandleUIWindowAvailable ();
336 MoonWindowless::GetGdkWindow ()
338 GdkNativeWindow window
;
339 NPN_GetValue (plugin
->GetInstance(), NPNVnetscapeWindow
, (void*)&window
);
340 GdkWindow
*gdk
= gdk_window_foreign_new (window
);