1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /* vim:expandtab:shiftwidth=4:tabstop=4:
3 : */
4 : /* ***** BEGIN LICENSE BLOCK *****
5 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6 : *
7 : * The contents of this file are subject to the Mozilla Public License Version
8 : * 1.1 (the "License"); you may not use this file except in compliance with
9 : * the License. You may obtain a copy of the License at
10 : * http://www.mozilla.org/MPL/
11 : *
12 : * Software distributed under the License is distributed on an "AS IS" basis,
13 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14 : * for the specific language governing rights and limitations under the
15 : * License.
16 : *
17 : * The Original Code is mozilla.org code.
18 : *
19 : * The Initial Developer of the Original Code is Christopher Blizzard
20 : * <blizzard@mozilla.org>. Portions created by the Initial Developer
21 : * are Copyright (C) 2001 the Initial Developer. All Rights Reserved.
22 : *
23 : * Contributor(s):
24 : * Masayuki Nakano <masayuki@d-toybox.com>
25 : *
26 : * Alternatively, the contents of this file may be used under the terms of
27 : * either the GNU General Public License Version 2 or later (the "GPL"), or
28 : * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 : * in which case the provisions of the GPL or the LGPL are applicable instead
30 : * of those above. If you wish to allow use of your version of this file only
31 : * under the terms of either the GPL or the LGPL, and not to allow others to
32 : * use your version of this file under the terms of the MPL, indicate your
33 : * decision by deleting the provisions above and replace them with the notice
34 : * and other provisions required by the GPL or the LGPL. If you do not delete
35 : * the provisions above, a recipient may use your version of this file under
36 : * the terms of any one of the MPL, the GPL or the LGPL.
37 : *
38 : * ***** END LICENSE BLOCK ***** */
39 :
40 : #ifndef __nsWindow_h__
41 : #define __nsWindow_h__
42 :
43 : #include "mozilla/ipc/SharedMemorySysV.h"
44 :
45 : #include "nsAutoPtr.h"
46 :
47 : #include "mozcontainer.h"
48 : #include "nsWeakReference.h"
49 :
50 : #include "nsIDragService.h"
51 : #include "nsITimer.h"
52 : #include "nsGkAtoms.h"
53 :
54 : #include "gfxASurface.h"
55 :
56 : #include "nsBaseWidget.h"
57 : #include "nsGUIEvent.h"
58 : #include <gdk/gdk.h>
59 : #include <gtk/gtk.h>
60 :
61 : #ifdef MOZ_X11
62 : #include <gdk/gdkx.h>
63 : #endif /* MOZ_X11 */
64 :
65 : #ifdef ACCESSIBILITY
66 : #include "nsAccessible.h"
67 : #endif
68 :
69 : #include "nsGtkIMModule.h"
70 :
71 : #ifdef MOZ_LOGGING
72 :
73 : // make sure that logging is enabled before including prlog.h
74 : #define FORCE_PR_LOG
75 :
76 : #include "prlog.h"
77 : #include "nsTArray.h"
78 :
79 : extern PRLogModuleInfo *gWidgetLog;
80 : extern PRLogModuleInfo *gWidgetFocusLog;
81 : extern PRLogModuleInfo *gWidgetDragLog;
82 : extern PRLogModuleInfo *gWidgetDrawLog;
83 :
84 : #define LOG(args) PR_LOG(gWidgetLog, 4, args)
85 : #define LOGFOCUS(args) PR_LOG(gWidgetFocusLog, 4, args)
86 : #define LOGDRAG(args) PR_LOG(gWidgetDragLog, 4, args)
87 : #define LOGDRAW(args) PR_LOG(gWidgetDrawLog, 4, args)
88 :
89 : #else
90 :
91 : #define LOG(args)
92 : #define LOGFOCUS(args)
93 : #define LOGDRAG(args)
94 : #define LOGDRAW(args)
95 :
96 : #endif /* MOZ_LOGGING */
97 :
98 : #if defined(MOZ_X11) && defined(MOZ_HAVE_SHAREDMEMORYSYSV)
99 : # define MOZ_HAVE_SHMIMAGE
100 :
101 : class nsShmImage;
102 : #endif
103 :
104 : class nsWindow : public nsBaseWidget, public nsSupportsWeakReference
105 : {
106 : public:
107 : nsWindow();
108 : virtual ~nsWindow();
109 :
110 : static void ReleaseGlobals();
111 :
112 : NS_DECL_ISUPPORTS_INHERITED
113 :
114 : void CommonCreate(nsIWidget *aParent, bool aListenForResizes);
115 :
116 : // event handling code
117 : void DispatchActivateEvent(void);
118 : void DispatchDeactivateEvent(void);
119 : void DispatchResizeEvent(nsIntRect &aRect, nsEventStatus &aStatus);
120 :
121 : virtual nsresult DispatchEvent(nsGUIEvent *aEvent, nsEventStatus &aStatus);
122 :
123 : // called when we are destroyed
124 : void OnDestroy(void);
125 :
126 : // called to check and see if a widget's dimensions are sane
127 : bool AreBoundsSane(void);
128 :
129 : // nsIWidget
130 : NS_IMETHOD Create(nsIWidget *aParent,
131 : nsNativeWidget aNativeParent,
132 : const nsIntRect &aRect,
133 : EVENT_CALLBACK aHandleEventFunction,
134 : nsDeviceContext *aContext,
135 : nsWidgetInitData *aInitData);
136 : NS_IMETHOD Destroy(void);
137 : virtual nsIWidget *GetParent();
138 : virtual float GetDPI();
139 : virtual nsresult SetParent(nsIWidget* aNewParent);
140 : NS_IMETHOD SetModal(bool aModal);
141 : NS_IMETHOD IsVisible(bool & aState);
142 : NS_IMETHOD ConstrainPosition(bool aAllowSlop,
143 : PRInt32 *aX,
144 : PRInt32 *aY);
145 : NS_IMETHOD Move(PRInt32 aX,
146 : PRInt32 aY);
147 : NS_IMETHOD Show (bool aState);
148 : NS_IMETHOD Resize (PRInt32 aWidth,
149 : PRInt32 aHeight,
150 : bool aRepaint);
151 : NS_IMETHOD Resize (PRInt32 aX,
152 : PRInt32 aY,
153 : PRInt32 aWidth,
154 : PRInt32 aHeight,
155 : bool aRepaint);
156 : NS_IMETHOD IsEnabled (bool *aState);
157 :
158 :
159 : NS_IMETHOD PlaceBehind(nsTopLevelWidgetZPlacement aPlacement,
160 : nsIWidget *aWidget,
161 : bool aActivate);
162 : NS_IMETHOD SetZIndex(PRInt32 aZIndex);
163 : NS_IMETHOD SetSizeMode(PRInt32 aMode);
164 : NS_IMETHOD Enable(bool aState);
165 : NS_IMETHOD SetFocus(bool aRaise = false);
166 : NS_IMETHOD GetScreenBounds(nsIntRect &aRect);
167 : NS_IMETHOD GetClientBounds(nsIntRect &aRect);
168 : virtual nsIntPoint GetClientOffset();
169 : NS_IMETHOD SetForegroundColor(const nscolor &aColor);
170 : NS_IMETHOD SetBackgroundColor(const nscolor &aColor);
171 : NS_IMETHOD SetCursor(nsCursor aCursor);
172 : NS_IMETHOD SetCursor(imgIContainer* aCursor,
173 : PRUint32 aHotspotX, PRUint32 aHotspotY);
174 : NS_IMETHOD Invalidate(const nsIntRect &aRect);
175 : virtual void* GetNativeData(PRUint32 aDataType);
176 : NS_IMETHOD SetTitle(const nsAString& aTitle);
177 : NS_IMETHOD SetIcon(const nsAString& aIconSpec);
178 : NS_IMETHOD SetWindowClass(const nsAString& xulWinType);
179 : virtual nsIntPoint WidgetToScreenOffset();
180 : NS_IMETHOD EnableDragDrop(bool aEnable);
181 : NS_IMETHOD CaptureMouse(bool aCapture);
182 : NS_IMETHOD CaptureRollupEvents(nsIRollupListener *aListener,
183 : bool aDoCapture,
184 : bool aConsumeRollupEvent);
185 : NS_IMETHOD GetAttention(PRInt32 aCycleCount);
186 :
187 : virtual bool HasPendingInputEvent();
188 :
189 : NS_IMETHOD MakeFullScreen(bool aFullScreen);
190 : NS_IMETHOD HideWindowChrome(bool aShouldHide);
191 :
192 : /**
193 : * GetLastUserInputTime returns a timestamp for the most recent user input
194 : * event. This is intended for pointer grab requests (including drags).
195 : */
196 : static guint32 GetLastUserInputTime();
197 :
198 : // utility method, -1 if no change should be made, otherwise returns a
199 : // value that can be passed to gdk_window_set_decorations
200 : gint ConvertBorderStyles(nsBorderStyle aStyle);
201 :
202 : // event callbacks
203 : #if defined(MOZ_WIDGET_GTK2)
204 : gboolean OnExposeEvent(GdkEventExpose *aEvent);
205 : #else
206 : gboolean OnExposeEvent(cairo_t *cr);
207 : #endif
208 : gboolean OnConfigureEvent(GtkWidget *aWidget,
209 : GdkEventConfigure *aEvent);
210 : void OnContainerUnrealize(GtkWidget *aWidget);
211 : void OnSizeAllocate(GtkWidget *aWidget,
212 : GtkAllocation *aAllocation);
213 : void OnDeleteEvent(GtkWidget *aWidget,
214 : GdkEventAny *aEvent);
215 : void OnEnterNotifyEvent(GtkWidget *aWidget,
216 : GdkEventCrossing *aEvent);
217 : void OnLeaveNotifyEvent(GtkWidget *aWidget,
218 : GdkEventCrossing *aEvent);
219 : void OnMotionNotifyEvent(GtkWidget *aWidget,
220 : GdkEventMotion *aEvent);
221 : void OnButtonPressEvent(GtkWidget *aWidget,
222 : GdkEventButton *aEvent);
223 : void OnButtonReleaseEvent(GtkWidget *aWidget,
224 : GdkEventButton *aEvent);
225 : void OnContainerFocusInEvent(GtkWidget *aWidget,
226 : GdkEventFocus *aEvent);
227 : void OnContainerFocusOutEvent(GtkWidget *aWidget,
228 : GdkEventFocus *aEvent);
229 : gboolean OnKeyPressEvent(GtkWidget *aWidget,
230 : GdkEventKey *aEvent);
231 : gboolean OnKeyReleaseEvent(GtkWidget *aWidget,
232 : GdkEventKey *aEvent);
233 : void OnScrollEvent(GtkWidget *aWidget,
234 : GdkEventScroll *aEvent);
235 : void OnVisibilityNotifyEvent(GtkWidget *aWidget,
236 : GdkEventVisibility *aEvent);
237 : void OnWindowStateEvent(GtkWidget *aWidget,
238 : GdkEventWindowState *aEvent);
239 : gboolean OnDragMotionEvent(GtkWidget *aWidget,
240 : GdkDragContext *aDragContext,
241 : gint aX,
242 : gint aY,
243 : guint aTime,
244 : gpointer aData);
245 : void OnDragLeaveEvent(GtkWidget * aWidget,
246 : GdkDragContext *aDragContext,
247 : guint aTime,
248 : gpointer aData);
249 : gboolean OnDragDropEvent(GtkWidget *aWidget,
250 : GdkDragContext *aDragContext,
251 : gint aX,
252 : gint aY,
253 : guint aTime,
254 : gpointer aData);
255 : void OnDragDataReceivedEvent(GtkWidget *aWidget,
256 : GdkDragContext *aDragContext,
257 : gint aX,
258 : gint aY,
259 : GtkSelectionData*aSelectionData,
260 : guint aInfo,
261 : guint aTime,
262 : gpointer aData);
263 : void OnDragLeave(void);
264 : void OnDragEnter(nscoord aX, nscoord aY);
265 :
266 : private:
267 : void NativeResize(PRInt32 aWidth,
268 : PRInt32 aHeight,
269 : bool aRepaint);
270 :
271 : void NativeResize(PRInt32 aX,
272 : PRInt32 aY,
273 : PRInt32 aWidth,
274 : PRInt32 aHeight,
275 : bool aRepaint);
276 :
277 : void NativeShow (bool aAction);
278 : void SetHasMappedToplevel(bool aState);
279 : nsIntSize GetSafeWindowSize(nsIntSize aSize);
280 :
281 : void EnsureGrabs (void);
282 : void GrabPointer (guint32 aTime);
283 : void ReleaseGrabs (void);
284 :
285 : public:
286 : enum PluginType {
287 : PluginType_NONE = 0, /* do not have any plugin */
288 : PluginType_XEMBED, /* the plugin support xembed */
289 : PluginType_NONXEMBED /* the plugin does not support xembed */
290 : };
291 :
292 : void SetPluginType(PluginType aPluginType);
293 : #ifdef MOZ_X11
294 : void SetNonXEmbedPluginFocus(void);
295 : void LoseNonXEmbedPluginFocus(void);
296 : #endif /* MOZ_X11 */
297 :
298 : void ThemeChanged(void);
299 :
300 : void CheckNeedDragLeaveEnter(nsWindow* aInnerMostWidget,
301 : nsIDragService* aDragService,
302 : GdkDragContext *aDragContext,
303 : nscoord aX, nscoord aY);
304 :
305 : #ifdef MOZ_X11
306 : Window mOldFocusWindow;
307 : #endif /* MOZ_X11 */
308 :
309 : static guint32 sLastButtonPressTime;
310 : static guint32 sLastButtonReleaseTime;
311 :
312 : NS_IMETHOD BeginResizeDrag(nsGUIEvent* aEvent, PRInt32 aHorizontal, PRInt32 aVertical);
313 : NS_IMETHOD BeginMoveDrag(nsMouseEvent* aEvent);
314 :
315 0 : MozContainer* GetMozContainer() { return mContainer; }
316 0 : GdkWindow* GetGdkWindow() { return mGdkWindow; }
317 0 : bool IsDestroyed() { return mIsDestroyed; }
318 :
319 : // If this dispatched the keydown event actually, this returns TRUE,
320 : // otherwise, FALSE.
321 : bool DispatchKeyDownEvent(GdkEventKey *aEvent,
322 : bool *aIsCancelled);
323 :
324 : NS_IMETHOD ResetInputState();
325 : NS_IMETHOD_(void) SetInputContext(const InputContext& aContext,
326 : const InputContextAction& aAction);
327 : NS_IMETHOD_(InputContext) GetInputContext();
328 : NS_IMETHOD CancelIMEComposition();
329 : NS_IMETHOD OnIMEFocusChange(bool aFocus);
330 : NS_IMETHOD GetToggledKeyState(PRUint32 aKeyCode, bool* aLEDState);
331 :
332 : void ResizeTransparencyBitmap(PRInt32 aNewWidth, PRInt32 aNewHeight);
333 : void ApplyTransparencyBitmap();
334 : virtual void SetTransparencyMode(nsTransparencyMode aMode);
335 : virtual nsTransparencyMode GetTransparencyMode();
336 : virtual nsresult ConfigureChildren(const nsTArray<Configuration>& aConfigurations);
337 : nsresult UpdateTranslucentWindowAlphaInternal(const nsIntRect& aRect,
338 : PRUint8* aAlphas, PRInt32 aStride);
339 :
340 : #if defined(MOZ_WIDGET_GTK2)
341 : gfxASurface *GetThebesSurface();
342 :
343 : static already_AddRefed<gfxASurface> GetSurfaceForGdkDrawable(GdkDrawable* aDrawable,
344 : const nsIntSize& aSize);
345 : #else
346 : gfxASurface *GetThebesSurface(cairo_t *cr);
347 : #endif
348 : NS_IMETHOD ReparentNativeWidget(nsIWidget* aNewParent);
349 :
350 : protected:
351 : // Helper for SetParent and ReparentNativeWidget.
352 : void ReparentNativeWidgetInternal(nsIWidget* aNewParent,
353 : GtkWidget* aNewContainer,
354 : GdkWindow* aNewParentWindow,
355 : GtkWidget* aOldContainer);
356 : nsCOMPtr<nsIWidget> mParent;
357 : // Is this a toplevel window?
358 : bool mIsTopLevel;
359 : // Has this widget been destroyed yet?
360 : bool mIsDestroyed;
361 :
362 : // This is a flag that tracks if we need to resize a widget or
363 : // window when we show it.
364 : bool mNeedsResize;
365 : // This is a flag that tracks if we need to move a widget or
366 : // window when we show it.
367 : bool mNeedsMove;
368 : // Should we send resize events on all resizes?
369 : bool mListenForResizes;
370 : // This flag tracks if we're hidden or shown.
371 : bool mIsShown;
372 : bool mNeedsShow;
373 : // is this widget enabled?
374 : bool mEnabled;
375 : // has the native window for this been created yet?
376 : bool mCreated;
377 :
378 : private:
379 : void DestroyChildWindows();
380 : void GetToplevelWidget(GtkWidget **aWidget);
381 : GtkWidget *GetMozContainerWidget();
382 : nsWindow *GetContainerWindow();
383 : void SetUrgencyHint(GtkWidget *top_window, bool state);
384 : void *SetupPluginPort(void);
385 : void SetDefaultIcon(void);
386 : void InitButtonEvent(nsMouseEvent &aEvent, GdkEventButton *aGdkEvent);
387 : bool DispatchCommandEvent(nsIAtom* aCommand);
388 : bool DispatchContentCommandEvent(PRInt32 aMsg);
389 : void SetWindowClipRegion(const nsTArray<nsIntRect>& aRects,
390 : bool aIntersectWithExisting);
391 : bool GetDragInfo(nsMouseEvent* aMouseEvent,
392 : GdkWindow** aWindow, gint* aButton,
393 : gint* aRootX, gint* aRootY);
394 : void ClearCachedResources();
395 :
396 : GtkWidget *mShell;
397 : MozContainer *mContainer;
398 : GdkWindow *mGdkWindow;
399 :
400 : GtkWindowGroup *mWindowGroup;
401 :
402 : PRUint32 mHasMappedToplevel : 1,
403 : mIsFullyObscured : 1,
404 : mRetryPointerGrab : 1;
405 : GtkWindow *mTransientParent;
406 : PRInt32 mSizeState;
407 : PluginType mPluginType;
408 :
409 : PRInt32 mTransparencyBitmapWidth;
410 : PRInt32 mTransparencyBitmapHeight;
411 :
412 : #ifdef MOZ_HAVE_SHMIMAGE
413 : // If we're using xshm rendering, mThebesSurface wraps mShmImage
414 : nsRefPtr<nsShmImage> mShmImage;
415 : #endif
416 : nsRefPtr<gfxASurface> mThebesSurface;
417 :
418 : #ifdef ACCESSIBILITY
419 : nsRefPtr<nsAccessible> mRootAccessible;
420 :
421 : /**
422 : * Request to create the accessible for this window if it is top level.
423 : */
424 : void CreateRootAccessible();
425 :
426 : /**
427 : * Generate the NS_GETACCESSIBLE event to get accessible for this window
428 : * and return it.
429 : */
430 : nsAccessible *DispatchAccessibleEvent();
431 :
432 : /**
433 : * Dispatch accessible event for the top level window accessible.
434 : *
435 : * @param aEventType [in] the accessible event type to dispatch
436 : */
437 : void DispatchEventToRootAccessible(PRUint32 aEventType);
438 :
439 : /**
440 : * Dispatch accessible window activate event for the top level window
441 : * accessible.
442 : */
443 : void DispatchActivateEventAccessible();
444 :
445 : /**
446 : * Dispatch accessible window deactivate event for the top level window
447 : * accessible.
448 : */
449 : void DispatchDeactivateEventAccessible();
450 :
451 : /**
452 : * Dispatch accessible window maximize event for the top level window
453 : * accessible.
454 : */
455 : void DispatchMaximizeEventAccessible();
456 :
457 : /**
458 : * Dispatch accessible window minize event for the top level window
459 : * accessible.
460 : */
461 : void DispatchMinimizeEventAccessible();
462 :
463 : /**
464 : * Dispatch accessible window restore event for the top level window
465 : * accessible.
466 : */
467 : void DispatchRestoreEventAccessible();
468 : #endif
469 :
470 : // The cursor cache
471 : static GdkCursor *gsGtkCursorCache[eCursorCount];
472 :
473 : // Transparency
474 : bool mIsTransparent;
475 : // This bitmap tracks which pixels are transparent. We don't support
476 : // full translucency at this time; each pixel is either fully opaque
477 : // or fully transparent.
478 : gchar* mTransparencyBitmap;
479 :
480 : // all of our DND stuff
481 : // this is the last window that had a drag event happen on it.
482 : static nsWindow *sLastDragMotionWindow;
483 : void InitDragEvent (nsDragEvent &aEvent);
484 : void UpdateDragStatus (GdkDragContext *aDragContext,
485 : nsIDragService *aDragService);
486 :
487 : nsCOMPtr<nsITimer> mDragLeaveTimer;
488 : float mLastMotionPressure;
489 :
490 : // Remember the last sizemode so that we can restore it when
491 : // leaving fullscreen
492 : nsSizeMode mLastSizeMode;
493 :
494 : static bool sIsDraggingOutOf;
495 : // drag in progress
496 : static bool DragInProgress(void);
497 :
498 : void FireDragLeaveTimer (void);
499 : static void DragLeaveTimerCallback (nsITimer *aTimer, void *aClosure);
500 :
501 : void DispatchMissedButtonReleases(GdkEventCrossing *aGdkEvent);
502 :
503 : /**
504 : * |mIMModule| takes all IME related stuff.
505 : *
506 : * This is owned by the top-level nsWindow or the topmost child
507 : * nsWindow embedded in a non-Gecko widget.
508 : *
509 : * The instance is created when the top level widget is created. And when
510 : * the widget is destroyed, it's released. All child windows refer its
511 : * ancestor widget's instance. So, one set of IM contexts is created for
512 : * all windows in a hierarchy. If the children are released after the top
513 : * level window is released, the children still have a valid pointer,
514 : * however, IME doesn't work at that time.
515 : */
516 : nsRefPtr<nsGtkIMModule> mIMModule;
517 : };
518 :
519 : class nsChildWindow : public nsWindow {
520 : public:
521 : nsChildWindow();
522 : ~nsChildWindow();
523 : };
524 :
525 : #endif /* __nsWindow_h__ */
|