/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* vim:expandtab:shiftwidth=4:tabstop=4: */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is mozilla.org code. * * The Initial Developer of the Original Code is Christopher Blizzard * . Portions created by the Initial Developer * are Copyright (C) 2001 the Initial Developer. All Rights Reserved. * * Contributor(s): * Masayuki Nakano * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ #ifndef __nsWindow_h__ #define __nsWindow_h__ #include "mozilla/ipc/SharedMemorySysV.h" #include "nsAutoPtr.h" #include "mozcontainer.h" #include "nsWeakReference.h" #include "nsIDragService.h" #include "nsITimer.h" #include "nsGkAtoms.h" #include "gfxASurface.h" #include "nsBaseWidget.h" #include "nsGUIEvent.h" #include #include #ifdef MOZ_X11 #include #endif /* MOZ_X11 */ #ifdef ACCESSIBILITY #include "nsAccessible.h" #endif #include "nsGtkIMModule.h" #ifdef MOZ_LOGGING // make sure that logging is enabled before including prlog.h #define FORCE_PR_LOG #include "prlog.h" #include "nsTArray.h" extern PRLogModuleInfo *gWidgetLog; extern PRLogModuleInfo *gWidgetFocusLog; extern PRLogModuleInfo *gWidgetDragLog; extern PRLogModuleInfo *gWidgetDrawLog; #define LOG(args) PR_LOG(gWidgetLog, 4, args) #define LOGFOCUS(args) PR_LOG(gWidgetFocusLog, 4, args) #define LOGDRAG(args) PR_LOG(gWidgetDragLog, 4, args) #define LOGDRAW(args) PR_LOG(gWidgetDrawLog, 4, args) #else #define LOG(args) #define LOGFOCUS(args) #define LOGDRAG(args) #define LOGDRAW(args) #endif /* MOZ_LOGGING */ #if defined(MOZ_X11) && defined(MOZ_HAVE_SHAREDMEMORYSYSV) # define MOZ_HAVE_SHMIMAGE class nsShmImage; #endif class nsWindow : public nsBaseWidget, public nsSupportsWeakReference { public: nsWindow(); virtual ~nsWindow(); static void ReleaseGlobals(); NS_DECL_ISUPPORTS_INHERITED void CommonCreate(nsIWidget *aParent, bool aListenForResizes); // event handling code void InitKeyEvent(nsKeyEvent &aEvent, GdkEventKey *aGdkEvent); void DispatchActivateEvent(void); void DispatchDeactivateEvent(void); void DispatchResizeEvent(nsIntRect &aRect, nsEventStatus &aStatus); virtual nsresult DispatchEvent(nsGUIEvent *aEvent, nsEventStatus &aStatus); // called when we are destroyed void OnDestroy(void); // called to check and see if a widget's dimensions are sane bool AreBoundsSane(void); // nsIWidget NS_IMETHOD Create(nsIWidget *aParent, nsNativeWidget aNativeParent, const nsIntRect &aRect, EVENT_CALLBACK aHandleEventFunction, nsDeviceContext *aContext, nsWidgetInitData *aInitData); NS_IMETHOD Destroy(void); virtual nsIWidget *GetParent(); virtual float GetDPI(); virtual nsresult SetParent(nsIWidget* aNewParent); NS_IMETHOD SetModal(bool aModal); NS_IMETHOD IsVisible(bool & aState); NS_IMETHOD ConstrainPosition(bool aAllowSlop, PRInt32 *aX, PRInt32 *aY); NS_IMETHOD Move(PRInt32 aX, PRInt32 aY); NS_IMETHOD Show (bool aState); NS_IMETHOD Resize (PRInt32 aWidth, PRInt32 aHeight, bool aRepaint); NS_IMETHOD Resize (PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight, bool aRepaint); NS_IMETHOD IsEnabled (bool *aState); NS_IMETHOD PlaceBehind(nsTopLevelWidgetZPlacement aPlacement, nsIWidget *aWidget, bool aActivate); NS_IMETHOD SetZIndex(PRInt32 aZIndex); NS_IMETHOD SetSizeMode(PRInt32 aMode); NS_IMETHOD Enable(bool aState); NS_IMETHOD SetFocus(bool aRaise = false); NS_IMETHOD GetScreenBounds(nsIntRect &aRect); NS_IMETHOD GetClientBounds(nsIntRect &aRect); virtual nsIntPoint GetClientOffset(); NS_IMETHOD SetForegroundColor(const nscolor &aColor); NS_IMETHOD SetBackgroundColor(const nscolor &aColor); NS_IMETHOD SetCursor(nsCursor aCursor); NS_IMETHOD SetCursor(imgIContainer* aCursor, PRUint32 aHotspotX, PRUint32 aHotspotY); NS_IMETHOD Invalidate(const nsIntRect &aRect); virtual void* GetNativeData(PRUint32 aDataType); NS_IMETHOD SetTitle(const nsAString& aTitle); NS_IMETHOD SetIcon(const nsAString& aIconSpec); NS_IMETHOD SetWindowClass(const nsAString& xulWinType); virtual nsIntPoint WidgetToScreenOffset(); NS_IMETHOD EnableDragDrop(bool aEnable); NS_IMETHOD CaptureMouse(bool aCapture); NS_IMETHOD CaptureRollupEvents(nsIRollupListener *aListener, bool aDoCapture, bool aConsumeRollupEvent); NS_IMETHOD GetAttention(PRInt32 aCycleCount); virtual bool HasPendingInputEvent(); NS_IMETHOD MakeFullScreen(bool aFullScreen); NS_IMETHOD HideWindowChrome(bool aShouldHide); /** * GetCurrentEventTime guesses a timestamp for the most recent user input * event (when the event is not available). This is intended for pointer * grab or focus requests, for example. */ static guint32 GetCurrentEventTime(); // utility method, -1 if no change should be made, otherwise returns a // value that can be passed to gdk_window_set_decorations gint ConvertBorderStyles(nsBorderStyle aStyle); // event callbacks #if defined(MOZ_WIDGET_GTK2) gboolean OnExposeEvent(GdkEventExpose *aEvent); #else gboolean OnExposeEvent(cairo_t *cr); #endif gboolean OnConfigureEvent(GtkWidget *aWidget, GdkEventConfigure *aEvent); void OnContainerUnrealize(GtkWidget *aWidget); void OnSizeAllocate(GtkWidget *aWidget, GtkAllocation *aAllocation); void OnDeleteEvent(GtkWidget *aWidget, GdkEventAny *aEvent); void OnEnterNotifyEvent(GtkWidget *aWidget, GdkEventCrossing *aEvent); void OnLeaveNotifyEvent(GtkWidget *aWidget, GdkEventCrossing *aEvent); void OnMotionNotifyEvent(GtkWidget *aWidget, GdkEventMotion *aEvent); void OnButtonPressEvent(GtkWidget *aWidget, GdkEventButton *aEvent); void OnButtonReleaseEvent(GtkWidget *aWidget, GdkEventButton *aEvent); void OnContainerFocusInEvent(GtkWidget *aWidget, GdkEventFocus *aEvent); void OnContainerFocusOutEvent(GtkWidget *aWidget, GdkEventFocus *aEvent); gboolean OnKeyPressEvent(GtkWidget *aWidget, GdkEventKey *aEvent); gboolean OnKeyReleaseEvent(GtkWidget *aWidget, GdkEventKey *aEvent); void OnScrollEvent(GtkWidget *aWidget, GdkEventScroll *aEvent); void OnVisibilityNotifyEvent(GtkWidget *aWidget, GdkEventVisibility *aEvent); void OnWindowStateEvent(GtkWidget *aWidget, GdkEventWindowState *aEvent); gboolean OnDragMotionEvent(GtkWidget *aWidget, GdkDragContext *aDragContext, gint aX, gint aY, guint aTime, gpointer aData); void OnDragLeaveEvent(GtkWidget * aWidget, GdkDragContext *aDragContext, guint aTime, gpointer aData); gboolean OnDragDropEvent(GtkWidget *aWidget, GdkDragContext *aDragContext, gint aX, gint aY, guint aTime, gpointer aData); void OnDragDataReceivedEvent(GtkWidget *aWidget, GdkDragContext *aDragContext, gint aX, gint aY, GtkSelectionData*aSelectionData, guint aInfo, guint aTime, gpointer aData); void OnDragLeave(void); void OnDragEnter(nscoord aX, nscoord aY); private: void NativeResize(PRInt32 aWidth, PRInt32 aHeight, bool aRepaint); void NativeResize(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight, bool aRepaint); void NativeShow (bool aAction); void SetHasMappedToplevel(bool aState); nsIntSize GetSafeWindowSize(nsIntSize aSize); void EnsureGrabs (void); void GrabPointer (guint32 aTime); void ReleaseGrabs (void); public: enum PluginType { PluginType_NONE = 0, /* do not have any plugin */ PluginType_XEMBED, /* the plugin support xembed */ PluginType_NONXEMBED /* the plugin does not support xembed */ }; void SetPluginType(PluginType aPluginType); #ifdef MOZ_X11 void SetNonXEmbedPluginFocus(void); void LoseNonXEmbedPluginFocus(void); #endif /* MOZ_X11 */ void ThemeChanged(void); void CheckNeedDragLeaveEnter(nsWindow* aInnerMostWidget, nsIDragService* aDragService, GdkDragContext *aDragContext, nscoord aX, nscoord aY); #ifdef MOZ_X11 Window mOldFocusWindow; #endif /* MOZ_X11 */ static guint32 sLastButtonPressTime; static guint32 sLastButtonReleaseTime; NS_IMETHOD BeginResizeDrag(nsGUIEvent* aEvent, PRInt32 aHorizontal, PRInt32 aVertical); NS_IMETHOD BeginMoveDrag(nsMouseEvent* aEvent); MozContainer* GetMozContainer() { return mContainer; } GdkWindow* GetGdkWindow() { return mGdkWindow; } bool IsDestroyed() { return mIsDestroyed; } // If this dispatched the keydown event actually, this returns TRUE, // otherwise, FALSE. bool DispatchKeyDownEvent(GdkEventKey *aEvent, bool *aIsCancelled); NS_IMETHOD ResetInputState(); NS_IMETHOD_(void) SetInputContext(const InputContext& aContext, const InputContextAction& aAction); NS_IMETHOD_(InputContext) GetInputContext(); NS_IMETHOD CancelIMEComposition(); NS_IMETHOD OnIMEFocusChange(bool aFocus); NS_IMETHOD GetToggledKeyState(PRUint32 aKeyCode, bool* aLEDState); void ResizeTransparencyBitmap(PRInt32 aNewWidth, PRInt32 aNewHeight); void ApplyTransparencyBitmap(); virtual void SetTransparencyMode(nsTransparencyMode aMode); virtual nsTransparencyMode GetTransparencyMode(); virtual nsresult ConfigureChildren(const nsTArray& aConfigurations); nsresult UpdateTranslucentWindowAlphaInternal(const nsIntRect& aRect, PRUint8* aAlphas, PRInt32 aStride); #if defined(MOZ_WIDGET_GTK2) gfxASurface *GetThebesSurface(); static already_AddRefed GetSurfaceForGdkDrawable(GdkDrawable* aDrawable, const nsIntSize& aSize); #else gfxASurface *GetThebesSurface(cairo_t *cr); #endif NS_IMETHOD ReparentNativeWidget(nsIWidget* aNewParent); protected: // Helper for SetParent and ReparentNativeWidget. void ReparentNativeWidgetInternal(nsIWidget* aNewParent, GtkWidget* aNewContainer, GdkWindow* aNewParentWindow, GtkWidget* aOldContainer); nsCOMPtr mParent; // Is this a toplevel window? bool mIsTopLevel; // Has this widget been destroyed yet? bool mIsDestroyed; // This is a flag that tracks if we need to resize a widget or // window when we show it. bool mNeedsResize; // This is a flag that tracks if we need to move a widget or // window when we show it. bool mNeedsMove; // Should we send resize events on all resizes? bool mListenForResizes; // This flag tracks if we're hidden or shown. bool mIsShown; bool mNeedsShow; // is this widget enabled? bool mEnabled; // has the native window for this been created yet? bool mCreated; private: void DestroyChildWindows(); void GetToplevelWidget(GtkWidget **aWidget); GtkWidget *GetMozContainerWidget(); nsWindow *GetContainerWindow(); void SetUrgencyHint(GtkWidget *top_window, bool state); void *SetupPluginPort(void); void SetDefaultIcon(void); void InitButtonEvent(nsMouseEvent &aEvent, GdkEventButton *aGdkEvent); bool DispatchCommandEvent(nsIAtom* aCommand); bool DispatchContentCommandEvent(PRInt32 aMsg); void SetWindowClipRegion(const nsTArray& aRects, bool aIntersectWithExisting); bool GetDragInfo(nsMouseEvent* aMouseEvent, GdkWindow** aWindow, gint* aButton, gint* aRootX, gint* aRootY); void ClearCachedResources(); GtkWidget *mShell; MozContainer *mContainer; GdkWindow *mGdkWindow; GtkWindowGroup *mWindowGroup; PRUint32 mHasMappedToplevel : 1, mIsFullyObscured : 1, mRetryPointerGrab : 1; GtkWindow *mTransientParent; PRInt32 mSizeState; PluginType mPluginType; PRInt32 mTransparencyBitmapWidth; PRInt32 mTransparencyBitmapHeight; #ifdef MOZ_HAVE_SHMIMAGE // If we're using xshm rendering, mThebesSurface wraps mShmImage nsRefPtr mShmImage; #endif nsRefPtr mThebesSurface; #ifdef ACCESSIBILITY nsRefPtr mRootAccessible; /** * Request to create the accessible for this window if it is top level. */ void CreateRootAccessible(); /** * Generate the NS_GETACCESSIBLE event to get accessible for this window * and return it. */ nsAccessible *DispatchAccessibleEvent(); /** * Dispatch accessible event for the top level window accessible. * * @param aEventType [in] the accessible event type to dispatch */ void DispatchEventToRootAccessible(PRUint32 aEventType); /** * Dispatch accessible window activate event for the top level window * accessible. */ void DispatchActivateEventAccessible(); /** * Dispatch accessible window deactivate event for the top level window * accessible. */ void DispatchDeactivateEventAccessible(); /** * Dispatch accessible window maximize event for the top level window * accessible. */ void DispatchMaximizeEventAccessible(); /** * Dispatch accessible window minize event for the top level window * accessible. */ void DispatchMinimizeEventAccessible(); /** * Dispatch accessible window restore event for the top level window * accessible. */ void DispatchRestoreEventAccessible(); #endif // The cursor cache static GdkCursor *gsGtkCursorCache[eCursorCount]; // Transparency bool mIsTransparent; // This bitmap tracks which pixels are transparent. We don't support // full translucency at this time; each pixel is either fully opaque // or fully transparent. gchar* mTransparencyBitmap; // all of our DND stuff // this is the last window that had a drag event happen on it. static nsWindow *sLastDragMotionWindow; void InitDragEvent (nsDragEvent &aEvent); void UpdateDragStatus (GdkDragContext *aDragContext, nsIDragService *aDragService); nsCOMPtr mDragLeaveTimer; float mLastMotionPressure; // Remember the last sizemode so that we can restore it when // leaving fullscreen nsSizeMode mLastSizeMode; static bool sIsDraggingOutOf; // drag in progress static bool DragInProgress(void); void FireDragLeaveTimer (void); static void DragLeaveTimerCallback (nsITimer *aTimer, void *aClosure); void DispatchMissedButtonReleases(GdkEventCrossing *aGdkEvent); /** * |mIMModule| takes all IME related stuff. * * This is owned by the top-level nsWindow or the topmost child * nsWindow embedded in a non-Gecko widget. * * The instance is created when the top level widget is created. And when * the widget is destroyed, it's released. All child windows refer its * ancestor widget's instance. So, one set of IM contexts is created for * all windows in a hierarchy. If the children are released after the top * level window is released, the children still have a valid pointer, * however, IME doesn't work at that time. */ nsRefPtr mIMModule; }; class nsChildWindow : public nsWindow { public: nsChildWindow(); ~nsChildWindow(); }; #endif /* __nsWindow_h__ */