[dfb,422221] Gtk/DirectFB: widget changes

This commit is contained in:
Vladimir Vukicevic 2008-08-06 13:48:55 -07:00
parent d5014f52b1
commit 6ff7f8ecb8
13 changed files with 404 additions and 138 deletions

View File

@ -70,8 +70,10 @@ endif
#
ifdef MOZ_ENABLE_GTK2
DIRS += gtk2
ifdef MOZ_X11
DIRS += gtkxtbin
endif
endif
ifdef MOZ_ENABLE_PHOTON
DIRS += photon

View File

@ -63,7 +63,6 @@ REQUIRES = xpcom \
necko \
uconv \
intl \
gtkxtbin \
imglib2 \
view \
content \
@ -74,6 +73,10 @@ REQUIRES = xpcom \
cairo \
$(NULL)
ifdef MOZ_X11
REQUIRES += gtkxtbin
endif
ifeq ($(MOZ_ENABLE_GLITZ),1)
REQUIRES += glitz glitzglx
endif
@ -98,8 +101,6 @@ CPPSRCS = \
nsCommonWidget.cpp \
nsLookAndFeel.cpp \
nsGtkKeyUtils.cpp \
nsClipboard.cpp \
nsDragService.cpp \
nsFilePicker.cpp \
nsSound.cpp \
nsNativeKeyBindings.cpp \
@ -112,8 +113,10 @@ CPPSRCS = \
ifdef NS_OSSO
CPPSRCS += nsIdleServiceOSSO.cpp
else
ifdef MOZ_X11
CPPSRCS += nsIdleServiceGTK.cpp
endif
endif
ifdef NS_PRINTING
CPPSRCS += \
@ -124,6 +127,12 @@ CPPSRCS += \
$(NULL)
endif
ifdef MOZ_X11
CPPSRCS += nsClipboard.cpp \
nsDragService.cpp \
$(NULL)
endif
# build our subdirs, too
ifdef ACCESSIBILITY
REQUIRES += accessibility
@ -134,7 +143,6 @@ SHARED_LIBRARY_LIBS = ../xpwidgets/libxpwidgets_s.a
EXTRA_DSO_LDOPTS += \
$(MOZ_COMPONENT_LIBS) \
-lgkgfx \
-lgtkxtbin \
$(MOZ_STARTUP_NOTIFICATION_LIBS) \
$(XLDFLAGS) \
$(XLIBS) \
@ -143,6 +151,10 @@ EXTRA_DSO_LDOPTS += \
$(LCMS_LIBS) \
$(NULL)
ifdef MOZ_X11
EXTRA_DSO_LDOPTS += -lgtkxtbin
endif
EXPORTS = \
nsGTKToolkit.h \
nsIImageToPixbuf.h \

View File

@ -45,7 +45,11 @@
* (UCS, Unicode) values.
*/
#ifdef MOZ_X11
#include <X11/X.h>
#else
#define KeySym unsigned int
#endif /* MOZ_X11 */
#ifdef __cplusplus
extern "C" {

View File

@ -53,8 +53,15 @@ NS_IMPL_ISUPPORTS1(nsBidiKeyboard, nsIBidiKeyboard)
nsBidiKeyboard::nsBidiKeyboard()
{
#if defined(MOZ_X11)
if (!gtklib)
gtklib = PR_LoadLibrary("libgtk-x11-2.0.so.0");
#elif defined(MOZ_DFB)
if (!gtklib)
gtklib = PR_LoadLibrary("libgtk-directfb-2.0.so.0");
#else
return;
#endif
if (gtklib && !GdkKeymapHaveBidiLayouts)
GdkKeymapHaveBidiLayouts = (GdkKeymapHaveBidiLayoutsType) PR_FindFunctionSymbol(gtklib, "gdk_keymap_have_bidi_layouts");

View File

@ -39,7 +39,9 @@
#include <gdk/gdkkeysyms.h>
#include <gdk/gdkevents.h>
#ifdef MOZ_X11
#include <gdk/gdkx.h>
#endif /* MOZ_X11 */
#include "nsGUIEvent.h"
#include "keysym2ucs.h"
@ -154,8 +156,10 @@ struct nsKeyConverter nsKeycodes[] = {
{ NS_VK_EQUALS, GDK_plus }
};
#ifdef MOZ_X11
#define IS_XSUN_XSERVER(dpy) \
(strstr(XServerVendor(dpy), "Sun Microsystems") != NULL)
#endif /* MOZ_X11 */
// map Sun Keyboard special keysyms on to NS_VK keys
struct nsKeyConverter nsSunKeycodes[] = {
@ -193,6 +197,7 @@ GdkKeyCodeToDOMKeyCode(int aKeysym)
if (aKeysym >= GDK_KP_0 && aKeysym <= GDK_KP_9)
return aKeysym - GDK_KP_0 + NS_VK_NUMPAD0;
#ifdef MOZ_X11
// map Sun Keyboard special keysyms
if (IS_XSUN_XSERVER(GDK_DISPLAY())) {
length = sizeof(nsSunKeycodes) / sizeof(struct nsKeyConverter);
@ -201,6 +206,7 @@ GdkKeyCodeToDOMKeyCode(int aKeysym)
return(nsSunKeycodes[i].vkCode);
}
}
#endif /* MOZ_X11 */
// misc other things
length = sizeof(nsKeycodes) / sizeof(struct nsKeyConverter);

View File

@ -62,16 +62,15 @@
#include "nsWidgetAtoms.h"
#include <gdk/gdkprivate.h>
#include <gdk/gdkx.h>
#include <gtk/gtk.h>
#include "gfxContext.h"
#include "gfxPlatformGtk.h"
#include "gfxXlibNativeRenderer.h"
#include "gfxGdkNativeRenderer.h"
NS_IMPL_ISUPPORTS2(nsNativeThemeGTK, nsITheme, nsIObserver)
static int gLastXError;
static int gLastGdkError;
static inline bool IsCheckboxWidgetType(PRUint8 aWidgetType)
{
@ -616,22 +615,15 @@ nsNativeThemeGTK::GetGtkWidgetAndState(PRUint8 aWidgetType, nsIFrame* aFrame,
return PR_TRUE;
}
static int
NativeThemeErrorHandler(Display* dpy, XErrorEvent* error) {
gLastXError = error->error_code;
return 0;
}
class ThemeRenderer : public gfxXlibNativeRenderer {
class ThemeRenderer : public gfxGdkNativeRenderer {
public:
ThemeRenderer(GtkWidgetState aState, GtkThemeWidgetType aGTKWidgetType,
gint aFlags, GtkTextDirection aDirection,
const GdkRectangle& aGDKRect, const GdkRectangle& aGDKClip)
: mState(aState), mGTKWidgetType(aGTKWidgetType), mFlags(aFlags),
mDirection(aDirection), mGDKRect(aGDKRect), mGDKClip(aGDKClip) {}
nsresult NativeDraw(Screen* screen, Drawable drawable, Visual* visual,
Colormap colormap, short offsetX, short offsetY,
XRectangle* clipRects, PRUint32 numClipRects);
nsresult NativeDraw(GdkDrawable * drawable, short offsetX, short offsetY,
GdkRectangle * clipRects, PRUint32 numClipRects);
private:
GtkWidgetState mState;
GtkThemeWidgetType mGTKWidgetType;
@ -643,9 +635,8 @@ private:
};
nsresult
ThemeRenderer::NativeDraw(Screen* screen, Drawable drawable, Visual* visual,
Colormap colormap, short offsetX, short offsetY,
XRectangle* clipRects, PRUint32 numClipRects)
ThemeRenderer::NativeDraw(GdkDrawable * drawable, short offsetX,
short offsetY, GdkRectangle * clipRects, PRUint32 numClipRects)
{
GdkRectangle gdk_rect = mGDKRect;
gdk_rect.x += offsetX;
@ -655,38 +646,10 @@ ThemeRenderer::NativeDraw(Screen* screen, Drawable drawable, Visual* visual,
gdk_clip.x += offsetX;
gdk_clip.y += offsetY;
GdkDisplay* gdkDpy = gdk_x11_lookup_xdisplay(DisplayOfScreen(screen));
if (!gdkDpy)
return NS_ERROR_FAILURE;
GdkPixmap* gdkPixmap = gdk_pixmap_lookup_for_display(gdkDpy, drawable);
if (gdkPixmap) {
g_object_ref(G_OBJECT(gdkPixmap));
} else {
// XXX gtk+-2.10 has gdk_pixmap_foreign_new_for_screen which would not
// use XGetGeometry.
gdkPixmap = gdk_pixmap_foreign_new_for_display(gdkDpy, drawable);
if (!gdkPixmap)
return NS_ERROR_FAILURE;
// We requested that gfxXlibNativeRenderer give us the default screen
GdkScreen* gdkScreen = gdk_display_get_default_screen(gdkDpy);
NS_ASSERTION(screen == GDK_SCREEN_XSCREEN(gdkScreen),
"'screen' should be the default Screen");
// GDK requires a GdkColormap to be set on the GdkPixmap.
GdkVisual* gdkVisual =
gdk_x11_screen_lookup_visual(gdkScreen, visual->visualid);
GdkColormap* gdkColormap =
gdk_x11_colormap_foreign_new(gdkVisual, colormap);
gdk_drawable_set_colormap(gdkPixmap, gdkColormap);
g_object_unref(G_OBJECT(gdkColormap));
}
NS_ASSERTION(numClipRects == 0, "We don't support clipping!!!");
moz_gtk_widget_paint(mGTKWidgetType, gdkPixmap, &gdk_rect, &gdk_clip, &mState,
mFlags, mDirection);
moz_gtk_widget_paint(mGTKWidgetType, drawable, &gdk_rect, &gdk_clip,
&mState, mFlags, mDirection);
g_object_unref(G_OBJECT(gdkPixmap));
return NS_OK;
}
@ -804,8 +767,8 @@ nsNativeThemeGTK::DrawWidgetBackground(nsIRenderingContext* aContext,
// Some themes (e.g. Clearlooks) just don't clip properly to any
// clip rect we provide, so we cannot advertise support for clipping within
// the widget bounds.
PRUint32 rendererFlags = gfxXlibNativeRenderer::DRAW_SUPPORTS_OFFSET;
PRUint32 rendererFlags = gfxGdkNativeRenderer::DRAW_SUPPORTS_OFFSET;
// translate everything so (0,0) is the top left of the drawingRect
gfxContextAutoSaveRestore autoSR(ctx);
if (snapXY) {
@ -818,25 +781,22 @@ nsNativeThemeGTK::DrawWidgetBackground(nsIRenderingContext* aContext,
"Trying to render an unsafe widget!");
PRBool safeState = IsWidgetStateSafe(mSafeWidgetStates, aWidgetType, &state);
XErrorHandler oldHandler = nsnull;
if (!safeState) {
gLastXError = 0;
oldHandler = XSetErrorHandler(NativeThemeErrorHandler);
gLastGdkError = 0;
gdk_error_trap_push ();
}
renderer.Draw(gdk_x11_get_default_xdisplay(), ctx,
drawingRect.width, drawingRect.height,
rendererFlags, nsnull);
renderer.Draw(ctx, drawingRect.width, drawingRect.height, rendererFlags, nsnull);
if (!safeState) {
gdk_flush();
XSetErrorHandler(oldHandler);
gLastGdkError = gdk_error_trap_pop ();
if (gLastXError) {
if (gLastGdkError) {
#ifdef DEBUG
printf("GTK theme failed for widget type %d, error was %d, state was "
"[active=%d,focused=%d,inHover=%d,disabled=%d]\n",
aWidgetType, gLastXError, state.active, state.focused,
aWidgetType, gLastGdkError, state.active, state.focused,
state.inHover, state.disabled);
#endif
NS_WARNING("GTK theme failed; disabling unsafe widget");

View File

@ -38,9 +38,12 @@
#include "nsScreenGtk.h"
#include <gdk/gdk.h>
#ifdef MOZ_X11
#include <gdk/gdkx.h>
#include <gtk/gtk.h>
#include <X11/Xatom.h>
#endif
#include <gtk/gtk.h>
nsScreenGtk :: nsScreenGtk ( )
: mScreenNum(0),
@ -113,6 +116,7 @@ nsScreenGtk :: Init (GdkWindow *aRootWindow)
// versions of GDK predating the GdkScreen object. See bug 256646.
mAvailRect = mRect = nsRect(0, 0, gdk_screen_width(), gdk_screen_height());
#ifdef MOZ_X11
// We need to account for the taskbar, etc in the available rect.
// See http://freedesktop.org/Standards/wm-spec/index.html#id2767771
@ -176,8 +180,10 @@ nsScreenGtk :: Init (GdkWindow *aRootWindow)
}
}
g_free (workareas);
#endif
}
#ifdef MOZ_X11
void
nsScreenGtk :: Init (XineramaScreenInfo *aScreenInfo)
{
@ -188,3 +194,4 @@ nsScreenGtk :: Init (XineramaScreenInfo *aScreenInfo)
mAvailRect = mRect = xineRect;
}
#endif

View File

@ -41,6 +41,7 @@
#include "nsIScreen.h"
#include "nsRect.h"
#include "gdk/gdk.h"
#ifdef MOZ_X11
#include <X11/Xlib.h>
// from Xinerama.h
@ -51,6 +52,7 @@ typedef struct {
short width;
short height;
} XineramaScreenInfo;
#endif /* MOZ_X11 */
//------------------------------------------------------------------------
@ -64,7 +66,9 @@ public:
NS_DECL_NSISCREEN
void Init(GdkWindow *aRootWindow);
#ifdef MOZ_X11
void Init(XineramaScreenInfo *aScreenInfo);
#endif /* MOZ_X11 */
private:
PRUint32 mScreenNum;

View File

@ -43,21 +43,29 @@
#include "nsRect.h"
#include "nsAutoPtr.h"
#include <gdk/gdkx.h>
#include <gtk/gtk.h>
#define SCREEN_MANAGER_LIBRARY_LOAD_FAILED ((PRLibrary*)1)
#ifdef MOZ_DFB
#include <directfb.h>
#endif
#ifdef MOZ_X11
#include <gdk/gdkx.h>
// prototypes from Xinerama.h
typedef Bool (*_XnrmIsActive_fn)(Display *dpy);
typedef XineramaScreenInfo* (*_XnrmQueryScreens_fn)(Display *dpy, int *number);
#endif
#include <gtk/gtk.h>
static GdkFilterReturn
root_window_event_filter(GdkXEvent *aGdkXEvent, GdkEvent *aGdkEvent,
gpointer aClosure)
{
XEvent *xevent = static_cast<XEvent*>(aGdkXEvent);
nsScreenManagerGtk *manager = static_cast<nsScreenManagerGtk*>(aClosure);
#ifdef MOZ_X11
XEvent *xevent = static_cast<XEvent*>(aGdkXEvent);
// See comments in nsScreenGtk::Init below.
switch (xevent->type) {
@ -75,6 +83,24 @@ root_window_event_filter(GdkXEvent *aGdkXEvent, GdkEvent *aGdkEvent,
default:
break;
}
#endif
#ifdef MOZ_DFB
DFBWindowEvent * dfbEvent = static_cast<DFBWindowEvent *> (aGdkXEvent);
switch (dfbEvent->type)
{
case DWET_POSITION :
case DWET_SIZE :
manager->Init();
break;
/* TODO: Need to find out PropertyNotify equivalent in
* DFB.. */
default :
break;
}
#endif
return GDK_FILTER_CONTINUE;
}
@ -97,9 +123,11 @@ nsScreenManagerGtk :: ~nsScreenManagerGtk()
mRootWindow = nsnull;
}
#ifdef MOZ_X11
if (mXineramalib && mXineramalib != SCREEN_MANAGER_LIBRARY_LOAD_FAILED) {
PR_UnloadLibrary(mXineramalib);
}
#endif
}
@ -128,8 +156,10 @@ nsScreenManagerGtk :: EnsureInit()
GDK_STRUCTURE_MASK |
GDK_PROPERTY_CHANGE_MASK));
gdk_window_add_filter(mRootWindow, root_window_event_filter, this);
#ifdef MOZ_X11
mNetWorkareaAtom =
XInternAtom(GDK_WINDOW_XDISPLAY(mRootWindow), "_NET_WORKAREA", False);
#endif
return Init();
}
@ -137,6 +167,7 @@ nsScreenManagerGtk :: EnsureInit()
nsresult
nsScreenManagerGtk :: Init()
{
#ifdef MOZ_X11
XineramaScreenInfo *screenInfo = NULL;
int numScreens;
@ -162,8 +193,9 @@ nsScreenManagerGtk :: Init()
// screenInfo == NULL if either Xinerama couldn't be loaded or
// isn't running on the current display
if (!screenInfo || numScreens == 1) {
nsRefPtr<nsScreenGtk> screen;
numScreens = 1;
#endif
nsRefPtr<nsScreenGtk> screen;
if (mCachedScreenArray.Count() > 0) {
screen = static_cast<nsScreenGtk*>(mCachedScreenArray[0]);
@ -175,6 +207,7 @@ nsScreenManagerGtk :: Init()
}
screen->Init(mRootWindow);
#ifdef MOZ_X11
}
// If Xinerama is enabled and there's more than one screen, fill
// in the info for all of the screens. If that's not the case
@ -206,6 +239,7 @@ nsScreenManagerGtk :: Init()
if (screenInfo) {
XFree(screenInfo);
}
#endif
return NS_OK;
}

View File

@ -45,7 +45,9 @@
#include "nsCOMArray.h"
#include "prlink.h"
#include "gdk/gdk.h"
#ifdef MOZ_X11
#include <X11/Xlib.h>
#endif
//------------------------------------------------------------------------
@ -58,7 +60,9 @@ public:
NS_DECL_ISUPPORTS
NS_DECL_NSISCREENMANAGER
#ifdef MOZ_X11
Atom NetWorkareaAtom() { return mNetWorkareaAtom; }
#endif
// For internal use, or reinitialization from change notification.
nsresult Init();
@ -73,7 +77,9 @@ private:
PRLibrary *mXineramalib;
GdkWindow *mRootWindow;
#ifdef MOZ_X11
Atom mNetWorkareaAtom;
#endif
};
#endif // nsScreenManagerGtk_h___

View File

@ -225,6 +225,7 @@ static const nsModuleComponentInfo components[] =
NS_TRANSFERABLE_CID,
"@mozilla.org/widget/transferable;1",
nsTransferableConstructor },
#ifdef MOZ_X11
{ "Gtk Clipboard",
NS_CLIPBOARD_CID,
"@mozilla.org/widget/clipboard;1",
@ -237,6 +238,7 @@ static const nsModuleComponentInfo components[] =
NS_DRAGSERVICE_CID,
"@mozilla.org/widget/dragservice;1",
nsDragServiceConstructor },
#endif
{ "HTML Format Converter",
NS_HTMLFORMATCONVERTER_CID,
"@mozilla.org/widget/htmlformatconverter;1",

View File

@ -57,9 +57,12 @@
#include "nsGtkCursors.h"
#include <gtk/gtkwindow.h>
#ifdef MOZ_X11
#include <gdk/gdkx.h>
#include <gdk/gdkkeysyms.h>
#include <X11/XF86keysym.h>
#include "gtk2xtbin.h"
#endif /* MOZ_X11 */
#include <gdk/gdkkeysyms.h>
#include "nsWidgetAtoms.h"
@ -68,8 +71,6 @@
#include <startup-notification-1.0/libsn/sn.h>
#endif
#include "gtk2xtbin.h"
#include "nsIPrefService.h"
#include "nsIPrefBranch.h"
#include "nsIServiceManager.h"
@ -108,10 +109,29 @@ static const char sAccessibilityKey [] = "config.use_system_prefs.accessibility"
#include "nsAutoPtr.h"
#include "gfxPlatformGtk.h"
#include "gfxXlibSurface.h"
#include "gfxContext.h"
#include "gfxImageSurface.h"
#ifdef MOZ_X11
#include "gfxXlibSurface.h"
#endif
#ifdef MOZ_DFB
extern "C" {
#ifdef MOZ_DIRECT_DEBUG
#define DIRECT_ENABLE_DEBUG
#endif
#include <direct/debug.h>
D_DEBUG_DOMAIN( ns_Window, "nsWindow", "nsWindow" );
}
#include "gfxDirectFBSurface.h"
#define GDK_WINDOW_XWINDOW(_win) _win
#else
#define D_DEBUG_AT(x,y...) do {} while (0)
#endif
#ifdef MOZ_ENABLE_GLITZ
#include "gfxGlitzSurface.h"
#include "glitz-glx.h"
@ -184,12 +204,14 @@ static nsWindow* GetFirstNSWindowForGDKWindow (GdkWindow *aGdkWindow);
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#ifdef MOZ_X11
static GdkFilterReturn plugin_window_filter_func (GdkXEvent *gdk_xevent,
GdkEvent *event,
gpointer data);
static GdkFilterReturn plugin_client_message_filter (GdkXEvent *xevent,
GdkEvent *event,
gpointer data);
#endif /* MOZ_X11 */
#ifdef __cplusplus
}
#endif /* __cplusplus */
@ -220,10 +242,12 @@ static void drag_data_received_event_cb(GtkWidget *aWidget,
gpointer aData);
static GdkModifierType gdk_keyboard_get_modifiers();
#ifdef MOZ_X11
static PRBool gdk_keyboard_get_modmap_masks(Display* aDisplay,
PRUint32* aCapsLockMask,
PRUint32* aNumLockMask,
PRUint32* aScrollLockMask);
#endif /* MOZ_X11 */
/* initialization static functions */
static nsresult initialize_prefs (void);
@ -323,7 +347,9 @@ nsWindow::nsWindow()
mTransientParent = nsnull;
mWindowType = eWindowType_child;
mSizeState = nsSizeMode_Normal;
#ifdef MOZ_X11
mOldFocusWindow = 0;
#endif /* MOZ_X11 */
mPluginType = PluginType_NONE;
if (!gGlobalsInitialized) {
@ -357,6 +383,16 @@ nsWindow::nsWindow()
mTransparencyBitmapWidth = 0;
mTransparencyBitmapHeight = 0;
#ifdef MOZ_DFB
mDFBCursorX = 0;
mDFBCursorY = 0;
mDFBCursorCount = 0;
mDFB = NULL;
mDFBLayer = NULL;
#endif
}
nsWindow::~nsWindow()
@ -369,6 +405,14 @@ nsWindow::~nsWindow()
delete[] mTransparencyBitmap;
mTransparencyBitmap = nsnull;
#ifdef MOZ_DFB
if (mDFBLayer)
mDFBLayer->Release( mDFBLayer );
if (mDFB)
mDFB->Release( mDFB );
#endif
Destroy();
}
@ -458,10 +502,12 @@ nsWindow::Destroy(void)
gFocusWindow = nsnull;
}
#ifdef MOZ_X11
// make sure that we remove ourself as the plugin focus window
if (gPluginFocusWindow == this) {
gPluginFocusWindow->LoseNonXEmbedPluginFocus();
}
#endif /* MOZ_X11 */
if (mWindowGroup) {
g_object_unref(G_OBJECT(mWindowGroup));
@ -1228,6 +1274,13 @@ nsWindow::Scroll(PRInt32 aDx,
if (!mDrawingarea)
return NS_OK;
D_DEBUG_AT( ns_Window, "%s( %4d,%4d )\n", __FUNCTION__, aDx, aDy );
if (aClipRect) {
D_DEBUG_AT( ns_Window, " -> aClipRect: %4d,%4d-%4dx%4d\n",
aClipRect->x, aClipRect->y, aClipRect->width, aClipRect->height );
}
moz_drawingarea_scroll(mDrawingarea, aDx, aDy);
// Update bounds on our child windows
@ -1281,7 +1334,11 @@ nsWindow::GetNativeData(PRUint32 aDataType)
break;
case NS_NATIVE_DISPLAY:
#ifdef MOZ_X11
return GDK_DISPLAY();
#else
return nsnull;
#endif /* MOZ_X11 */
break;
case NS_NATIVE_GRAPHIC: {
@ -1559,6 +1616,7 @@ nsWindow::LoseFocus(void)
#define WANT_PAINT_FLASHING \
(debug_WantPaintFlashing() && CAPS_LOCK_IS_ON)
#ifdef MOZ_X11
static void
gdk_window_flash(GdkWindow * aGdkWindow,
unsigned int aTimes,
@ -1618,6 +1676,7 @@ gdk_window_flash(GdkWindow * aGdkWindow,
gdk_region_offset(aRegion, -x, -y);
}
#endif /* MOZ_X11 */
#endif // DEBUG
gboolean
@ -1661,6 +1720,28 @@ nsWindow::OnExposeEvent(GtkWidget *aWidget, GdkEventExpose *aEvent)
LOGDRAW(("\t%d %d %d %d\n", r->x, r->y, r->width, r->height));
}
#ifdef MOZ_DFB
nsCOMPtr<nsIRenderingContext> rc = getter_AddRefs(GetRenderingContext());
if (NS_UNLIKELY(!rc)) {
g_free(rects);
return FALSE;
}
// do double-buffering and clipping here
nsRefPtr<gfxContext> ctx = rc->ThebesContext();
gfxPlatformGtk::GetPlatform()->SetGdkDrawable(ctx->OriginalSurface(), GDK_DRAWABLE(mDrawingarea->inner_window));
// clip to the update region
ctx->Save();
ctx->NewPath();
for (r = rects; r < r_end; ++r) {
ctx->Rectangle(gfxRect(r->x, r->y, r->width, r->height));
}
ctx->Clip();
#endif
#ifdef MOZ_X11
nsCOMPtr<nsIRenderingContext> rc = getter_AddRefs(GetRenderingContext());
if (NS_UNLIKELY(!rc)) {
g_free(rects);
@ -1708,6 +1789,7 @@ nsWindow::OnExposeEvent(GtkWidget *aWidget, GdkEventExpose *aEvent)
GdkDrawable* d = GDK_DRAWABLE(mDrawingarea->inner_window);
gint depth = gdk_drawable_get_depth(d);
bufferPixmap = gdk_pixmap_new(d, boundsRect.width, boundsRect.height, depth);
if (bufferPixmap) {
bufferPixmapSurface = GetSurfaceForGdkDrawable(GDK_DRAWABLE(bufferPixmap),
boundsRect.Size());
@ -1715,6 +1797,9 @@ nsWindow::OnExposeEvent(GtkWidget *aWidget, GdkEventExpose *aEvent)
bufferPixmapSurface = nsnull;
}
if (bufferPixmapSurface) {
gfxPlatformGtk::GetPlatform()->SetGdkDrawable(
static_cast<gfxASurface *>(bufferPixmapSurface),
GDK_DRAWABLE(bufferPixmap));
bufferPixmapSurface->SetDeviceOffset(gfxPoint(-boundsRect.x, -boundsRect.y));
nsCOMPtr<nsIRenderingContext> newRC;
nsresult rv = GetDeviceContext()->
@ -1744,6 +1829,8 @@ nsWindow::OnExposeEvent(GtkWidget *aWidget, GdkEventExpose *aEvent)
#endif
#endif
#endif // MOZ_X11
nsPaintEvent event(PR_TRUE, NS_PAINT, this);
event.refPoint.x = aEvent->area.x;
event.refPoint.y = aEvent->area.y;
@ -1754,6 +1841,7 @@ nsWindow::OnExposeEvent(GtkWidget *aWidget, GdkEventExpose *aEvent)
nsEventStatus status;
DispatchEvent(&event, status);
#ifdef MOZ_X11
// DispatchEvent can Destroy us (bug 378273), avoid doing any paint
// operations below if that happened - it will lead to XError and exit().
if (NS_LIKELY(!mIsDestroyed)) {
@ -1809,6 +1897,11 @@ nsWindow::OnExposeEvent(GtkWidget *aWidget, GdkEventExpose *aEvent)
ctx->Restore();
}
#endif // MOZ_X11
#ifdef MOZ_DFB
ctx->Restore();
#endif
g_free(rects);
@ -1949,6 +2042,63 @@ nsWindow::OnLeaveNotifyEvent(GtkWidget *aWidget, GdkEventCrossing *aEvent)
DispatchEvent(&event, status);
}
#ifdef MOZ_DFB
void
nsWindow::OnMotionNotifyEvent(GtkWidget *aWidget, GdkEventMotion *aEvent)
{
int cursorX = (int) aEvent->x_root;
int cursorY = (int) aEvent->y_root;
D_DEBUG_AT( ns_Window, "%s( %4d,%4d - [%d] )\n", __FUNCTION__, cursorX, cursorY, mDFBCursorCount );
D_ASSUME( mDFBLayer != NULL );
if (mDFBLayer)
mDFBLayer->GetCursorPosition( mDFBLayer, &cursorX, &cursorY );
mDFBCursorCount++;
#if D_DEBUG_ENABLED
if (cursorX != (int) aEvent->x_root || cursorY != (int) aEvent->y_root)
D_DEBUG_AT( ns_Window, " -> forward to %4d,%4d\n", cursorX, cursorY );
#endif
if (cursorX == mDFBCursorX && cursorY == mDFBCursorY) {
D_DEBUG_AT( ns_Window, " -> dropping %4d,%4d\n", cursorX, cursorY );
/* drop zero motion */
return;
}
mDFBCursorX = cursorX;
mDFBCursorY = cursorY;
// when we receive this, it must be that the gtk dragging is over,
// it is dropped either in or out of mozilla, clear the flag
sIsDraggingOutOf = PR_FALSE;
nsMouseEvent event(PR_TRUE, NS_MOUSE_MOVE, this, nsMouseEvent::eReal);
nsRect windowRect;
ScreenToWidget(nsRect(nscoord(cursorX), nscoord(cursorY), 1, 1), windowRect);
event.refPoint.x = windowRect.x;
event.refPoint.y = windowRect.y;
event.isShift = (aEvent->state & GDK_SHIFT_MASK)
? PR_TRUE : PR_FALSE;
event.isControl = (aEvent->state & GDK_CONTROL_MASK)
? PR_TRUE : PR_FALSE;
event.isAlt = (aEvent->state & GDK_MOD1_MASK)
? PR_TRUE : PR_FALSE;
event.time = aEvent->time;
nsEventStatus status;
DispatchEvent(&event, status);
}
#else
void
nsWindow::OnMotionNotifyEvent(GtkWidget *aWidget, GdkEventMotion *aEvent)
{
@ -1959,8 +2109,10 @@ nsWindow::OnMotionNotifyEvent(GtkWidget *aWidget, GdkEventMotion *aEvent)
// see if we can compress this event
// XXXldb Why skip every other motion event when we have multiple,
// but not more than that?
XEvent xevent;
PRPackedBool synthEvent = PR_FALSE;
#ifdef MOZ_X11
XEvent xevent;
while (XCheckWindowEvent(GDK_WINDOW_XDISPLAY(aEvent->window),
GDK_WINDOW_XWINDOW(aEvent->window),
ButtonMotionMask, &xevent)) {
@ -1972,10 +2124,12 @@ nsWindow::OnMotionNotifyEvent(GtkWidget *aWidget, GdkEventMotion *aEvent)
nsRefPtr<nsWindow> kungFuDeathGrip = gPluginFocusWindow;
gPluginFocusWindow->LoseNonXEmbedPluginFocus();
}
#endif /* MOZ_X11 */
nsMouseEvent event(PR_TRUE, NS_MOUSE_MOVE, this, nsMouseEvent::eReal);
if (synthEvent) {
#ifdef MOZ_X11
event.refPoint.x = nscoord(xevent.xmotion.x);
event.refPoint.y = nscoord(xevent.xmotion.y);
@ -1987,6 +2141,19 @@ nsWindow::OnMotionNotifyEvent(GtkWidget *aWidget, GdkEventMotion *aEvent)
? PR_TRUE : PR_FALSE;
event.time = xevent.xmotion.time;
#else
event.refPoint.x = nscoord(aEvent->x);
event.refPoint.y = nscoord(aEvent->y);
event.isShift = (aEvent->state & GDK_SHIFT_MASK)
? PR_TRUE : PR_FALSE;
event.isControl = (aEvent->state & GDK_CONTROL_MASK)
? PR_TRUE : PR_FALSE;
event.isAlt = (aEvent->state & GDK_MOD1_MASK)
? PR_TRUE : PR_FALSE;
event.time = aEvent->time;
#endif /* MOZ_X11 */
}
else {
// XXX see OnScrollEvent()
@ -2014,6 +2181,7 @@ nsWindow::OnMotionNotifyEvent(GtkWidget *aWidget, GdkEventMotion *aEvent)
nsEventStatus status;
DispatchEvent(&event, status);
}
#endif
void
nsWindow::InitButtonEvent(nsMouseEvent &aEvent,
@ -2215,11 +2383,13 @@ nsWindow::OnContainerFocusOutEvent(GtkWidget *aWidget, GdkEventFocus *aEvent)
{
LOGFOCUS(("OnContainerFocusOutEvent [%p]\n", (void *)this));
#ifdef MOZ_X11
// plugin lose focus
if (gPluginFocusWindow) {
nsRefPtr<nsWindow> kungFuDeathGrip = gPluginFocusWindow;
gPluginFocusWindow->LoseNonXEmbedPluginFocus();
}
#endif /* MOZ_X11 */
// Figure out if the focus widget is the child of this window. If
// it is, send a focus out and deactivate event for it.
@ -2378,6 +2548,7 @@ nsWindow::OnKeyPressEvent(GtkWidget *aWidget, GdkEventKey *aEvent)
return TRUE;
}
#ifdef MOZ_X11
// Look for specialized app-command keys
switch (aEvent->keyval) {
case XF86XK_Back:
@ -2395,6 +2566,7 @@ nsWindow::OnKeyPressEvent(GtkWidget *aWidget, GdkEventKey *aEvent)
case XF86XK_HomePage:
return DispatchCommandEvent(nsWidgetAtoms::Home);
}
#endif /* MOZ_X11 */
nsKeyEvent event(PR_TRUE, NS_KEY_PRESS, this);
InitKeyEvent(event, aEvent);
@ -3250,8 +3422,13 @@ nsWindow::NativeCreate(nsIWidget *aParent,
}
// Disable the double buffer because it will make the caret crazy
// For bug#153805 (Gtk2 double buffer makes carets misbehave)
// DirectFB's expose code depends on gtk double buffering
// XXX - I think this bug is probably dead, we can just use gtk's
// double-buffering everywhere
#ifdef MOZ_X11
if (mContainer)
gtk_widget_set_double_buffered (GTK_WIDGET(mContainer),FALSE);
#endif
// label the drawing area with this object so we can find our way
// home
@ -3395,6 +3572,22 @@ nsWindow::NativeCreate(nsIWidget *aParent,
}
#endif
#ifdef MOZ_DFB
if (!mDFB) {
DirectFBCreate( &mDFB );
D_ASSUME( mDFB != NULL );
if (mDFB)
mDFB->GetDisplayLayer( mDFB, DLID_PRIMARY, &mDFBLayer );
D_ASSUME( mDFBLayer != NULL );
if (mDFBLayer)
mDFBLayer->GetCursorPosition( mDFBLayer, &mDFBCursorX, &mDFBCursorY );
}
#endif
return NS_OK;
}
@ -3404,6 +3597,7 @@ nsWindow::SetWindowClass(const nsAString &xulWinType)
if (!mShell)
return NS_ERROR_FAILURE;
#ifdef MOZ_X11
nsXPIDLString brandName;
GetBrandName(brandName);
@ -3447,6 +3641,39 @@ nsWindow::SetWindowClass(const nsAString &xulWinType)
nsMemory::Free(class_hint->res_class);
nsMemory::Free(class_hint->res_name);
XFree(class_hint);
#else /* MOZ_X11 */
char *res_name;
res_name = ToNewCString(xulWinType);
if (!res_name)
return NS_ERROR_OUT_OF_MEMORY;
printf("WARN: res_name = '%s'\n", res_name);
const char *role = NULL;
// Parse res_name into a name and role. Characters other than
// [A-Za-z0-9_-] are converted to '_'. Anything after the first
// colon is assigned to role; if there's no colon, assign the
// whole thing to both role and res_name.
for (char *c = res_name; *c; c++) {
if (':' == *c) {
*c = 0;
role = c + 1;
}
else if (!isascii(*c) || (!isalnum(*c) && ('_' != *c) && ('-' != *c)))
*c = '_';
}
res_name[0] = toupper(res_name[0]);
if (!role) role = res_name;
gdk_window_set_role(GTK_WIDGET(mShell)->window, role);
nsMemory::Free(res_name);
#endif /* MOZ_X11 */
return NS_OK;
}
@ -3970,6 +4197,7 @@ nsWindow::SetupPluginPort(void)
// we have to flush the X queue here so that any plugins that
// might be running on separate X connections will be able to use
// this window in case it was just created
#ifdef MOZ_X11
XWindowAttributes xattrs;
XGetWindowAttributes(GDK_DISPLAY (),
GDK_WINDOW_XWINDOW(mDrawingarea->inner_window),
@ -3984,6 +4212,7 @@ nsWindow::SetupPluginPort(void)
this);
XSync(GDK_DISPLAY(), False);
#endif /* MOZ_X11 */
return (void *)GDK_WINDOW_XWINDOW(mDrawingarea->inner_window);
}
@ -4027,6 +4256,7 @@ nsWindow::SetPluginType(PluginType aPluginType)
mPluginType = aPluginType;
}
#ifdef MOZ_X11
void
nsWindow::SetNonXEmbedPluginFocus()
{
@ -4121,6 +4351,7 @@ nsWindow::LoseNonXEmbedPluginFocus()
LOGFOCUS(("nsWindow::LoseNonXEmbedPluginFocus end\n"));
}
#endif /* MOZ_X11 */
gint
@ -4204,7 +4435,11 @@ nsWindow::HideWindowChrome(PRBool aShouldHide)
// and flush the queue here so that we don't end up with a BadWindow
// error later when this happens (when the persistence timer fires
// and GetWindowPos is called)
#ifdef MOZ_X11
XSync(GDK_DISPLAY(), False);
#else
gdk_flush ();
#endif /* MOZ_X11 */
return NS_OK;
}
@ -4712,6 +4947,7 @@ focus_out_event_cb(GtkWidget *widget, GdkEventFocus *event)
return FALSE;
}
#ifdef MOZ_X11
/* static */
GdkFilterReturn
plugin_window_filter_func(GdkXEvent *gdk_xevent, GdkEvent *event, gpointer data)
@ -4810,6 +5046,7 @@ plugin_client_message_filter(GdkXEvent *gdk_xevent,
return return_val;
}
#endif /* MOZ_X11 */
/* static */
gboolean
@ -5196,6 +5433,7 @@ gdk_keyboard_get_modifiers()
return m;
}
#ifdef MOZ_X11
// Get the modifier masks for GDK_Caps_Lock, GDK_Num_Lock and GDK_Scroll_Lock.
// Return PR_TRUE on success, PR_FALSE on error.
static PRBool
@ -5253,6 +5491,7 @@ gdk_keyboard_get_modmap_masks(Display* aDisplay,
XFree(xkeymap);
return PR_TRUE;
}
#endif /* MOZ_X11 */
#ifdef ACCESSIBILITY
/**
@ -5910,6 +6149,8 @@ nsWindow::GetToggledKeyState(PRUint32 aKeyCode, PRBool* aLEDState)
{
NS_ENSURE_ARG_POINTER(aLEDState);
#ifdef MOZ_X11
GdkModifierType modifiers = gdk_keyboard_get_modifiers();
PRUint32 capsLockMask, numLockMask, scrollLockMask;
PRBool foundMasks = gdk_keyboard_get_modmap_masks(
@ -5929,6 +6170,9 @@ nsWindow::GetToggledKeyState(PRUint32 aKeyCode, PRBool* aLEDState)
*aLEDState = (modifiers & mask) != 0;
return NS_OK;
#else
return NS_ERROR_NOT_IMPLEMENTED;
#endif /* MOZ_X11 */
}
/* static */
@ -6207,6 +6451,7 @@ IM_get_input_context(nsWindow *aWindow)
#endif
#ifdef MOZ_X11
/* static */ already_AddRefed<gfxASurface>
nsWindow::GetSurfaceForGdkDrawable(GdkDrawable* aDrawable,
const nsSize& aSize)
@ -6221,81 +6466,40 @@ nsWindow::GetSurfaceForGdkDrawable(GdkDrawable* aDrawable,
NS_IF_ADDREF(result);
return result;
}
#endif
// return the gfxASurface for rendering to this widget
gfxASurface*
nsWindow::GetThebesSurface()
{
// XXXvlad always create a new thebes surface for now,
// because the old clip doesn't get cleared otherwise.
// we should fix this at some point, and just reset
// the clip.
mThebesSurface = nsnull;
GdkDrawable* d;
gint x_offset, y_offset;
gdk_window_get_internal_paint_info(mDrawingarea->inner_window,
&d, &x_offset, &y_offset);
if (!mThebesSurface) {
GdkDrawable* d;
gint x_offset, y_offset;
gdk_window_get_internal_paint_info(mDrawingarea->inner_window,
&d, &x_offset, &y_offset);
#ifdef MOZ_X11
gint width, height;
gdk_drawable_get_size(d, &width, &height);
// Owen Taylor says this is the right thing to do!
width = PR_MIN(32767, width);
height = PR_MIN(32767, height);
gint width, height;
gdk_drawable_get_size(d, &width, &height);
// Owen Taylor says this is the right thing to do!
width = PR_MIN(32767, width);
height = PR_MIN(32767, height);
if (!gfxPlatform::UseGlitz()) {
mThebesSurface = new gfxXlibSurface
(GDK_WINDOW_XDISPLAY(d),
GDK_WINDOW_XWINDOW(d),
GDK_VISUAL_XVISUAL(gdk_drawable_get_visual(d)),
gfxIntSize(width, height));
// if the surface creation is reporting an error, then
// we don't have a surface to give back
if (mThebesSurface && mThebesSurface->CairoStatus() != 0)
mThebesSurface = nsnull;
} else {
#ifdef MOZ_ENABLE_GLITZ
glitz_surface_t *gsurf;
glitz_drawable_t *gdraw;
glitz_drawable_format_t *gdformat = glitz_glx_find_window_format (GDK_DISPLAY(),
gdk_x11_get_default_screen(),
0, NULL, 0);
if (!gdformat)
NS_ERROR("Failed to find glitz drawable format");
Display* dpy = GDK_WINDOW_XDISPLAY(d);
Window wnd = GDK_WINDOW_XWINDOW(d);
gdraw =
glitz_glx_create_drawable_for_window (dpy,
DefaultScreen(dpy),
gdformat,
wnd,
width,
height);
glitz_format_t *gformat =
glitz_find_standard_format (gdraw, GLITZ_STANDARD_RGB24);
gsurf =
glitz_surface_create (gdraw,
gformat,
width,
height,
0,
NULL);
glitz_surface_attach (gsurf, gdraw, GLITZ_DRAWABLE_BUFFER_FRONT_COLOR);
//fprintf (stderr, "## nsThebesDrawingSurface::Init Glitz DRAWABLE %p (DC: %p)\n", aWidget, aDC);
mThebesSurface = new gfxGlitzSurface (gdraw, gsurf, PR_TRUE);
mThebesSurface = new gfxXlibSurface
(GDK_WINDOW_XDISPLAY(d),
GDK_WINDOW_XWINDOW(d),
GDK_VISUAL_XVISUAL(gdk_drawable_get_visual(d)),
gfxIntSize(width, height));
#endif
#ifdef MOZ_DFB
mThebesSurface = new gfxDirectFBSurface(gdk_directfb_surface_lookup(d));
#endif
}
if (mThebesSurface) {
mThebesSurface->SetDeviceOffset(gfxPoint(-x_offset, -y_offset));
}
// if the surface creation is reporting an error, then
// we don't have a surface to give back
if (mThebesSurface && mThebesSurface->CairoStatus() != 0) {
mThebesSurface = nsnull;
} else {
mThebesSurface->SetDeviceOffset(gfxPoint(-x_offset, -y_offset));
}
return mThebesSurface;

View File

@ -56,7 +56,13 @@
#include <gtk/gtk.h>
#ifdef MOZ_DFB
#include <gdk/gdkdirectfb.h>
#endif /* MOZ_DFB */
#ifdef MOZ_X11
#include <gdk/gdkx.h>
#endif /* MOZ_X11 */
#include <gtk/gtkwindow.h>
#ifdef ACCESSIBILITY
@ -256,12 +262,16 @@ public:
};
void SetPluginType(PluginType aPluginType);
#ifdef MOZ_X11
void SetNonXEmbedPluginFocus(void);
void LoseNonXEmbedPluginFocus(void);
#endif /* MOZ_X11 */
void ThemeChanged(void);
#ifdef MOZ_X11
Window mOldFocusWindow;
#endif /* MOZ_X11 */
static guint32 mLastButtonPressTime;
static guint32 mLastButtonReleaseTime;
@ -402,6 +412,14 @@ private:
nsRefPtr<gfxASurface> mThebesSurface;
#ifdef MOZ_DFB
int mDFBCursorX;
int mDFBCursorY;
PRUint32 mDFBCursorCount;
IDirectFB *mDFB;
IDirectFBDisplayLayer *mDFBLayer;
#endif
#ifdef ACCESSIBILITY
nsCOMPtr<nsIAccessible> mRootAccessible;
void CreateRootAccessible();