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->plugin
= plugin
;
39 MoonWindowless::UpdateWindowInfo ()
41 // It appears opera doesn't do a good job of keeping the NPWindow members valid
42 // between SetWindow calls so we have to work around this by copying the members
43 // we need. This is really ugly.
45 NPWindow
*window
= plugin
->GetWindow();
46 NPSetWindowCallbackStruct
*ws_info
= (NPSetWindowCallbackStruct
*)window
->ws_info
;
47 visualid
= ws_info
->visual
? visualid
= ws_info
->visual
->visualid
: 0;
53 MoonWindowless::Resize (int width
, int height
)
55 bool emit_resize
= false;
59 if (this->width
!= width
|| this->height
!= height
) {
61 this->height
= height
;
66 surface
->HandleUIWindowAllocation (emit_resize
);
70 MoonWindowless::SetCursor (MouseCursor cursor
)
72 #if (NP_VERSION_MINOR >= NPVERS_HAS_WINDOWLESS_CURSORS)
75 case MouseCursorDefault
:
76 npcursor
= NPCursorAuto
;
78 case MouseCursorArrow
:
79 npcursor
= NPCursorPointer
;
82 npcursor
= NPCursorWait
;
84 case MouseCursorIBeam
:
85 npcursor
= NPCursorText
;
87 case MouseCursorStylus
:
88 npcursor
= NPCursorPointer
; // XXX ugh...
90 case MouseCursorEraser
:
91 npcursor
= NPCursorPointer
; // XXX ugh...
94 // Silverlight display no cursor if the enumeration value is invalid (e.g. -1)
96 npcursor
= NPCursorNone
;
100 NPN_SetValue (plugin
->GetInstance(), NPPVcursor
, (void*)npcursor
);
105 MoonWindowless::Invalidate (Rect r
)
109 // Mozilla gets seriously confused about invalidations
110 // outside the windowless bounds.
111 r
= r
.Intersection (Rect (0, 0, GetWidth(), GetHeight())).RoundOut ();
113 nprect
.left
= (uint16_t)r
.x
;
114 nprect
.top
= (uint16_t)r
.y
;
115 nprect
.right
= (uint16_t)(r
.x
+ r
.width
);
116 nprect
.bottom
= (uint16_t)(r
.y
+ r
.height
);
118 NPN_InvalidateRect (plugin
->GetInstance(), &nprect
);
122 MoonWindowless::ProcessUpdates ()
124 //NPN_ForceRedraw (plugin->GetInstance());
128 MoonWindowless::HandleEvent (XEvent
*event
)
130 XEvent
*xev
= (XEvent
*)event
;
131 gboolean handled
= FALSE
;
133 SetCurrentDeployment ();
136 case GraphicsExpose
: {
137 GdkDrawable
*drawable
= gdk_pixmap_foreign_new ((GdkNativeWindow
)xev
->xgraphicsexpose
.drawable
);
139 drawable
= gdk_window_foreign_new ((GdkNativeWindow
)xev
->xgraphicsexpose
.drawable
);
143 GdkVisual
*visual
= gdkx_visual_get (visualid
);
146 GdkEventExpose expose
;
148 expose
.type
= GDK_EXPOSE
;
149 expose
.window
= NULL
;
150 expose
.send_event
= FALSE
;
151 expose
.area
= Rect (xev
->xgraphicsexpose
.x
,
152 xev
->xgraphicsexpose
.y
,
153 xev
->xgraphicsexpose
.width
,
154 xev
->xgraphicsexpose
.height
).ToGdkRectangle ();
156 expose
.region
= gdk_region_rectangle (&expose
.area
);
158 expose
.area
.x
= expose
.area
.y
= 0;
160 surface
->PaintToDrawable (drawable
, visual
, &expose
, x
, y
, GetTransparent(), false);
163 gdk_region_destroy (expose
.region
);
165 d(printf ("no gdk visual\n"));
168 g_object_unref (drawable
);
170 d(printf ("no gdk drawable\n"));
175 GdkEventMotion motion
;
177 motion
.type
= GDK_MOTION_NOTIFY
;
178 motion
.window
= NULL
;
179 motion
.send_event
= xev
->xmotion
.send_event
;
180 motion
.x
= xev
->xmotion
.x
;
181 motion
.y
= xev
->xmotion
.y
;
183 motion
.state
= xev
->xmotion
.state
;
184 motion
.is_hint
= xev
->xmotion
.is_hint
;
185 motion
.device
= NULL
; // XXX
186 motion
.x_root
= xev
->xmotion
.x_root
;
187 motion
.y_root
= xev
->xmotion
.y_root
;
189 handled
= surface
->HandleUIMotion (&motion
);
193 case ButtonRelease
: {
194 GdkEventButton button
;
196 button
.type
= xev
->type
== ButtonPress
? GDK_BUTTON_PRESS
: GDK_BUTTON_RELEASE
;
197 button
.window
= NULL
;
198 button
.send_event
= xev
->xbutton
.send_event
;
199 button
.time
= xev
->xbutton
.time
;
200 button
.x
= xev
->xbutton
.x
;
201 button
.y
= xev
->xbutton
.y
;
202 button
.x_root
= xev
->xbutton
.x_root
;
203 button
.y_root
= xev
->xbutton
.y_root
;
204 button
.state
= xev
->xbutton
.state
;
205 button
.button
= xev
->xbutton
.button
;
208 if (xev
->type
== ButtonPress
)
209 handled
= PluginInstance::plugin_button_press_callback (NULL
, &button
, plugin
);
211 if (xev
->type
== ButtonPress
)
212 handled
= surface
->HandleUIButtonPress (&button
);
214 handled
= surface
->HandleUIButtonRelease (&button
);
220 // make sure everything is initialized correctly (structure members vary with gdk version)
221 GdkEventKey
*key
= (GdkEventKey
*) gdk_event_new (xev
->type
== KeyPress
? GDK_KEY_PRESS
: GDK_KEY_RELEASE
);
222 // gtk_im_context_xim_filter_keypress will dereference the NULL window leading to a SEGSIGV
223 key
->window
= GetGdkWindow ();
224 key
->send_event
= xev
->xkey
.send_event
;
225 key
->time
= xev
->xkey
.time
;
226 key
->state
= xev
->xkey
.state
;
227 key
->hardware_keycode
= xev
->xkey
.keycode
;
229 gint effective_group
;
231 gdk_keymap_translate_keyboard_state (gdk_keymap_get_default (),
233 (GdkModifierType
)xev
->xkey
.state
, // XXX
240 key
->group
= (guint8
)effective_group
;
242 if (xev
->type
== KeyPress
)
243 handled
= surface
->HandleUIKeyPress (key
);
245 handled
= surface
->HandleUIKeyRelease (key
);
247 gdk_event_free ((GdkEvent
*) key
);
252 GdkEventCrossing crossing
;
254 crossing
.type
= xev
->type
== EnterNotify
? GDK_ENTER_NOTIFY
: GDK_LEAVE_NOTIFY
;
255 crossing
.window
= crossing
.subwindow
= NULL
;
256 crossing
.send_event
= xev
->xcrossing
.send_event
;
257 crossing
.time
= xev
->xcrossing
.time
;
258 crossing
.x
= xev
->xcrossing
.x
;
259 crossing
.y
= xev
->xcrossing
.y
;
260 crossing
.x_root
= xev
->xcrossing
.x_root
;
261 crossing
.y_root
= xev
->xcrossing
.y_root
;
262 // crossing.mode = (GdkCrossingMode)xev->xcrossing.mode; // XXX
263 crossing
.mode
= GDK_CROSSING_NORMAL
;
264 crossing
.detail
= (GdkNotifyType
)xev
->xcrossing
.detail
; // XXX
265 crossing
.focus
= xev
->xcrossing
.focus
;
266 crossing
.state
= xev
->xcrossing
.state
;
268 surface
->HandleUICrossing (&crossing
);
272 surface
->HandleUIFocusIn (NULL
);
277 surface
->HandleUIFocusOut (NULL
);
281 d(printf ("Unhandled Xlib event %d\n", xev
->type
));
289 MoonWindowless::Show ()
291 // nothing needed here
295 MoonWindowless::Hide ()
297 // nothing needed here
301 MoonWindowless::EnableEvents (bool first
)
303 // nothing needed here, NPAPI pushes events through
308 MoonWindowless::DisableEvents ()
310 // nothing needed here, NPAPI pushes events through
315 MoonWindowless::GrabFocus ()
317 // we can't grab focus - the browser handles that.
321 MoonWindowless::HasFocus ()
323 // XXX maybe we should track the focus in/out events?
328 MoonWindowless::SetSurface (Surface
*s
)
330 MoonWindow::SetSurface (s
);
331 s
->HandleUIWindowAvailable ();
335 MoonWindowless::GetGdkWindow ()
337 GdkNativeWindow window
;
338 NPN_GetValue (plugin
->GetInstance(), NPNVnetscapeWindow
, (void*)&window
);
339 GdkWindow
*gdk
= gdk_window_foreign_new (window
);