--- a/widget/src/Makefile.in
+++ b/widget/src/Makefile.in
@@ -65,17 +65,19 @@ endif
# Don't build the DSO under the 'build' directory as windows does.
#
# The DSOs get built in the toolkit dir itself. Do this so that
# multiple implementations of widget can be built on the same
# source tree.
#
ifdef MOZ_ENABLE_GTK2
DIRS += gtk2
+ifdef MOZ_X11
DIRS += gtkxtbin
endif
+endif
ifdef MOZ_ENABLE_PHOTON
DIRS += photon
endif
include $(topsrcdir)/config/rules.mk
--- a/widget/src/gtk2/Makefile.in
+++ b/widget/src/gtk2/Makefile.in
@@ -58,27 +58,30 @@ REQUIRES = xpcom \
string \
gfx \
pref \
dom \
docshell \
necko \
uconv \
intl \
- gtkxtbin \
imglib2 \
view \
content \
layout \
util \
locale \
thebes \
cairo \
$(NULL)
+ifdef MOZ_X11
+REQUIRES += gtkxtbin
+endif
+
ifeq ($(MOZ_ENABLE_GLITZ),1)
REQUIRES += glitz glitzglx
endif
CSRCS = \
mozcontainer.c \
mozdrawingarea.c \
keysym2ucs.c \
@@ -93,61 +96,70 @@ CPPSRCS = \
nsWindow.cpp \
nsAppShell.cpp \
nsWidgetFactory.cpp \
nsToolkit.cpp \
nsBidiKeyboard.cpp \
nsCommonWidget.cpp \
nsLookAndFeel.cpp \
nsGtkKeyUtils.cpp \
- nsClipboard.cpp \
- nsDragService.cpp \
nsFilePicker.cpp \
nsSound.cpp \
nsNativeKeyBindings.cpp \
nsScreenGtk.cpp \
nsScreenManagerGtk.cpp \
nsImageToPixbuf.cpp \
nsAccessibilityHelper.cpp \
$(NULL)
ifdef NS_OSSO
CPPSRCS += nsIdleServiceOSSO.cpp
else
+ifdef MOZ_X11
CPPSRCS += nsIdleServiceGTK.cpp
endif
+endif
ifdef NS_PRINTING
CPPSRCS += \
nsDeviceContextSpecG.cpp \
nsPrintOptionsGTK.cpp \
nsPrintDialogGTK.cpp \
nsPrintSettingsGTK.cpp \
$(NULL)
endif
+ifdef MOZ_X11
+CPPSRCS += nsClipboard.cpp \
+ nsDragService.cpp \
+ $(NULL)
+endif
+
# build our subdirs, too
ifdef ACCESSIBILITY
REQUIRES += accessibility
endif
SHARED_LIBRARY_LIBS = ../xpwidgets/libxpwidgets_s.a
EXTRA_DSO_LDOPTS += \
$(MOZ_COMPONENT_LIBS) \
-lgkgfx \
- -lgtkxtbin \
$(MOZ_STARTUP_NOTIFICATION_LIBS) \
$(XLDFLAGS) \
$(XLIBS) \
$(MOZ_GTK2_LIBS) \
-lthebes \
$(LCMS_LIBS) \
$(NULL)
+ifdef MOZ_X11
+EXTRA_DSO_LDOPTS += -lgtkxtbin
+endif
+
EXPORTS = \
nsGTKToolkit.h \
nsIImageToPixbuf.h \
mozdrawingarea.h \
mozcontainer.h \
$(NULL)
ifdef NATIVE_THEME_SUPPORT
--- a/widget/src/gtk2/keysym2ucs.h
+++ b/widget/src/gtk2/keysym2ucs.h
@@ -40,17 +40,21 @@
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/*
* This module converts keysym values into the corresponding ISO 10646-1
* (UCS, Unicode) values.
*/
+#ifdef MOZ_X11
#include <X11/X.h>
+#else
+#define KeySym unsigned int
+#endif /* MOZ_X11 */
#ifdef __cplusplus
extern "C" {
#endif
long keysym2ucs(KeySym keysym);
#ifdef __cplusplus
--- a/widget/src/gtk2/nsBidiKeyboard.cpp
+++ b/widget/src/gtk2/nsBidiKeyboard.cpp
@@ -48,18 +48,25 @@ static PRLibrary *gtklib = nsnull;
typedef gboolean (PR_CALLBACK *GdkKeymapHaveBidiLayoutsType)(GdkKeymap *keymap);
static GdkKeymapHaveBidiLayoutsType GdkKeymapHaveBidiLayouts = nsnull;
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");
SetHaveBidiKeyboards();
}
nsBidiKeyboard::~nsBidiKeyboard()
--- a/widget/src/gtk2/nsGtkKeyUtils.cpp
+++ b/widget/src/gtk2/nsGtkKeyUtils.cpp
@@ -34,17 +34,19 @@
* 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 ***** */
#include <gdk/gdkkeysyms.h>
#include <gdk/gdkevents.h>
+#ifdef MOZ_X11
#include <gdk/gdkx.h>
+#endif /* MOZ_X11 */
#include "nsGUIEvent.h"
#include "keysym2ucs.h"
struct nsKeyConverter {
int vkCode; // Platform independent key code
int keysym; // GDK keysym key code
};
@@ -149,18 +151,20 @@ struct nsKeyConverter nsKeycodes[] = {
{ NS_VK_7, GDK_ampersand },
{ NS_VK_8, GDK_asterisk },
{ NS_VK_9, GDK_parenleft },
{ NS_VK_0, GDK_parenright },
{ NS_VK_SUBTRACT, GDK_underscore },
{ 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[] = {
{NS_VK_ESCAPE, GDK_F11 }, //bug 57262, Sun Stop key generates F11 keysym
{NS_VK_F1, GDK_Help }, //Mapping Help key to F1
{NS_VK_F11, 0x1005ff10 }, //Sun F11 key generates SunF36(0x1005ff10) keysym
{NS_VK_F12, 0x1005ff11 }, //Sun F12 key generates SunF37(0x1005ff11) keysym
{NS_VK_PAGE_UP, GDK_F29 }, //KP_Prior
@@ -188,24 +192,26 @@ GdkKeyCodeToDOMKeyCode(int aKeysym)
// numbers
if (aKeysym >= GDK_0 && aKeysym <= GDK_9)
return aKeysym - GDK_0 + NS_VK_0;
// keypad numbers
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);
for (i = 0; i < length; i++) {
if (nsSunKeycodes[i].keysym == aKeysym)
return(nsSunKeycodes[i].vkCode);
}
}
+#endif /* MOZ_X11 */
// misc other things
length = sizeof(nsKeycodes) / sizeof(struct nsKeyConverter);
for (i = 0; i < length; i++) {
if (nsKeycodes[i].keysym == aKeysym)
return(nsKeycodes[i].vkCode);
}
--- a/widget/src/gtk2/nsNativeThemeGTK.cpp
+++ b/widget/src/gtk2/nsNativeThemeGTK.cpp
@@ -57,26 +57,25 @@
#include "nsGfxCIID.h"
#include "nsTransform2D.h"
#include "nsIMenuFrame.h"
#include "prlink.h"
#include "nsIDOMHTMLInputElement.h"
#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)
{
return (aWidgetType == NS_THEME_CHECKBOX || aWidgetType == NS_THEME_CHECKBOX_SMALL);
}
static inline bool IsRadioWidgetType(PRUint8 aWidgetType)
{
@@ -611,87 +610,51 @@ nsNativeThemeGTK::GetGtkWidgetAndState(P
break;
default:
return PR_FALSE;
}
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;
gint mFlags;
GtkTextDirection mDirection;
GdkWindow* mWindow;
const GdkRectangle& mGDKRect;
const GdkRectangle& mGDKClip;
};
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;
gdk_rect.y += offsetY;
GdkRectangle gdk_clip = mGDKClip;
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;
+ NS_ASSERTION(numClipRects == 0, "We don't support clipping!!!");
+ moz_gtk_widget_paint(mGTKWidgetType, drawable, &gdk_rect, &gdk_clip,
+ &mState, mFlags, mDirection);
- // 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);
-
- g_object_unref(G_OBJECT(gdkPixmap));
return NS_OK;
}
static PRBool
GetExtraSizeForWidget(PRUint8 aWidgetType, nsIntMargin* aExtra)
{
*aExtra = nsIntMargin(0,0,0,0);
// Allow an extra one pixel above and below the thumb for certain
@@ -799,49 +762,46 @@ nsNativeThemeGTK::DrawWidgetBackground(n
ThemeRenderer renderer(state, gtkWidgetType, flags, direction,
gdk_rect, gdk_clip);
// We require the use of the default screen and visual
// because I'm afraid that otherwise the GTK theme may explode.
// 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) {
// Rects are in device coords.
ctx->IdentityMatrix();
}
ctx->Translate(rect.pos + gfxPoint(drawingRect.x, drawingRect.y));
NS_ASSERTION(!IsWidgetTypeDisabled(mDisabledWidgetTypes, aWidgetType),
"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");
SetWidgetTypeDisabled(mDisabledWidgetTypes, aWidgetType);
// force refresh of the window, because the widget was not
// successfully drawn it must be redrawn using the default look
RefreshWidgetWindow(aFrame);
} else {
--- a/widget/src/gtk2/nsScreenGtk.cpp
+++ b/widget/src/gtk2/nsScreenGtk.cpp
@@ -33,19 +33,22 @@
* 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 ***** */
#include "nsScreenGtk.h"
+#include <gdk/gdk.h>
+#ifdef MOZ_X11
#include <gdk/gdkx.h>
+#include <X11/Xatom.h>
+#endif
#include <gtk/gtk.h>
-#include <X11/Xatom.h>
nsScreenGtk :: nsScreenGtk ( )
: mScreenNum(0),
mRect(0, 0, 0, 0),
mAvailRect(0, 0, 0, 0)
{
}
@@ -108,16 +111,17 @@ void
nsScreenGtk :: Init (GdkWindow *aRootWindow)
{
// We listen for configure events on the root window to pick up
// changes to this rect. We could listen for "size_changed" signals
// on the default screen to do this, except that doesn't work with
// 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
// XXX do we care about _NET_WM_STRUT_PARTIAL? That will
// add much more complexity to the code here (our screen
// could have a non-rectangular shape), but should
// lead to greater accuracy.
@@ -171,20 +175,23 @@ nsScreenGtk :: Init (GdkWindow *aRootWin
NS_WARNING("Invalid bounds");
continue;
}
mAvailRect.IntersectRect(mAvailRect, workarea);
}
}
g_free (workareas);
+#endif
}
+#ifdef MOZ_X11
void
nsScreenGtk :: Init (XineramaScreenInfo *aScreenInfo)
{
nsRect xineRect(aScreenInfo->x_org, aScreenInfo->y_org,
aScreenInfo->width, aScreenInfo->height);
mScreenNum = aScreenInfo->screen_number;
mAvailRect = mRect = xineRect;
}
+#endif
--- a/widget/src/gtk2/nsScreenGtk.h
+++ b/widget/src/gtk2/nsScreenGtk.h
@@ -36,40 +36,44 @@
* ***** END LICENSE BLOCK ***** */
#ifndef nsScreenGtk_h___
#define nsScreenGtk_h___
#include "nsIScreen.h"
#include "nsRect.h"
#include "gdk/gdk.h"
+#ifdef MOZ_X11
#include <X11/Xlib.h>
// from Xinerama.h
typedef struct {
int screen_number;
short x_org;
short y_org;
short width;
short height;
} XineramaScreenInfo;
+#endif /* MOZ_X11 */
//------------------------------------------------------------------------
class nsScreenGtk : public nsIScreen
{
public:
nsScreenGtk();
~nsScreenGtk();
NS_DECL_ISUPPORTS
NS_DECL_NSISCREEN
void Init(GdkWindow *aRootWindow);
+#ifdef MOZ_X11
void Init(XineramaScreenInfo *aScreenInfo);
+#endif /* MOZ_X11 */
private:
PRUint32 mScreenNum;
nsRect mRect; // in pixels, not twips
nsRect mAvailRect; // in pixels, not twips
};
#endif // nsScreenGtk_h___
--- a/widget/src/gtk2/nsScreenManagerGtk.cpp
+++ b/widget/src/gtk2/nsScreenManagerGtk.cpp
@@ -38,31 +38,39 @@
* ***** END LICENSE BLOCK ***** */
#include "nsScreenManagerGtk.h"
#include "nsScreenGtk.h"
#include "nsIComponentManager.h"
#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)
{
+ nsScreenManagerGtk *manager = static_cast<nsScreenManagerGtk*>(aClosure);
+#ifdef MOZ_X11
XEvent *xevent = static_cast<XEvent*>(aGdkXEvent);
- nsScreenManagerGtk *manager = static_cast<nsScreenManagerGtk*>(aClosure);
// See comments in nsScreenGtk::Init below.
switch (xevent->type) {
case ConfigureNotify:
manager->Init();
break;
case PropertyNotify:
{
@@ -70,16 +78,34 @@ root_window_event_filter(GdkXEvent *aGdk
if (propertyEvent->atom == manager->NetWorkareaAtom()) {
manager->Init();
}
}
break;
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;
}
nsScreenManagerGtk :: nsScreenManagerGtk ( )
: mXineramalib(nsnull)
, mRootWindow(nsnull)
{
@@ -92,19 +118,21 @@ nsScreenManagerGtk :: nsScreenManagerGtk
nsScreenManagerGtk :: ~nsScreenManagerGtk()
{
if (mRootWindow) {
gdk_window_remove_filter(mRootWindow, root_window_event_filter, this);
g_object_unref(mRootWindow);
mRootWindow = nsnull;
}
+#ifdef MOZ_X11
if (mXineramalib && mXineramalib != SCREEN_MANAGER_LIBRARY_LOAD_FAILED) {
PR_UnloadLibrary(mXineramalib);
}
+#endif
}
// addref, release, QI
NS_IMPL_ISUPPORTS1(nsScreenManagerGtk, nsIScreenManager)
// this function will make sure that everything has been initialized.
@@ -123,25 +151,28 @@ nsScreenManagerGtk :: EnsureInit()
// GDK_STRUCTURE_MASK ==> StructureNotifyMask, for ConfigureNotify
// GDK_PROPERTY_CHANGE_MASK ==> PropertyChangeMask, for PropertyNotify
gdk_window_set_events(mRootWindow,
GdkEventMask(gdk_window_get_events(mRootWindow) |
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();
}
nsresult
nsScreenManagerGtk :: Init()
{
+#ifdef MOZ_X11
XineramaScreenInfo *screenInfo = NULL;
int numScreens;
if (!mXineramalib) {
mXineramalib = PR_LoadLibrary("libXinerama.so.1");
if (!mXineramalib) {
mXineramalib = SCREEN_MANAGER_LIBRARY_LOAD_FAILED;
}
@@ -157,29 +188,31 @@ nsScreenManagerGtk :: Init()
if (_XnrmIsActive && _XnrmQueryScreens &&
_XnrmIsActive(GDK_DISPLAY())) {
screenInfo = _XnrmQueryScreens(GDK_DISPLAY(), &numScreens);
}
}
// screenInfo == NULL if either Xinerama couldn't be loaded or
// isn't running on the current display
if (!screenInfo || numScreens == 1) {
+ numScreens = 1;
+#endif
nsRefPtr<nsScreenGtk> screen;
- numScreens = 1;
if (mCachedScreenArray.Count() > 0) {
screen = static_cast<nsScreenGtk*>(mCachedScreenArray[0]);
} else {
screen = new nsScreenGtk();
if (!screen || !mCachedScreenArray.AppendObject(screen)) {
return NS_ERROR_OUT_OF_MEMORY;
}
}
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
// then nsScreenGTK() defaults to the screen width + height
else {
#ifdef DEBUG
printf("Xinerama superpowers activated for %d screens!\n", numScreens);
#endif
@@ -201,16 +234,17 @@ nsScreenManagerGtk :: Init()
// Remove any screens that are no longer present.
while (mCachedScreenArray.Count() > numScreens) {
mCachedScreenArray.RemoveObjectAt(mCachedScreenArray.Count() - 1);
}
if (screenInfo) {
XFree(screenInfo);
}
+#endif
return NS_OK;
}
//
// ScreenForRect
//
--- a/widget/src/gtk2/nsScreenManagerGtk.h
+++ b/widget/src/gtk2/nsScreenManagerGtk.h
@@ -40,40 +40,46 @@
#define nsScreenManagerGtk_h___
#include "nsIScreenManager.h"
#include "nsIScreen.h"
#include "nsCOMPtr.h"
#include "nsCOMArray.h"
#include "prlink.h"
#include "gdk/gdk.h"
+#ifdef MOZ_X11
#include <X11/Xlib.h>
+#endif
//------------------------------------------------------------------------
class nsScreenManagerGtk : public nsIScreenManager
{
public:
nsScreenManagerGtk ( );
virtual ~nsScreenManagerGtk();
NS_DECL_ISUPPORTS
NS_DECL_NSISCREENMANAGER
+#ifdef MOZ_X11
Atom NetWorkareaAtom() { return mNetWorkareaAtom; }
+#endif
// For internal use, or reinitialization from change notification.
nsresult Init();
private:
nsresult EnsureInit();
// Cached screen array. Its length is the number of screens we have.
nsCOMArray<nsIScreen> mCachedScreenArray;
PRLibrary *mXineramalib;
GdkWindow *mRootWindow;
+#ifdef MOZ_X11
Atom mNetWorkareaAtom;
+#endif
};
#endif // nsScreenManagerGtk_h___
--- a/widget/src/gtk2/nsWidgetFactory.cpp
+++ b/widget/src/gtk2/nsWidgetFactory.cpp
@@ -220,28 +220,30 @@ static const nsModuleComponentInfo compo
{ "Gtk2 Sound",
NS_SOUND_CID,
"@mozilla.org/sound;1",
nsSoundConstructor },
{ "Transferable",
NS_TRANSFERABLE_CID,
"@mozilla.org/widget/transferable;1",
nsTransferableConstructor },
+#ifdef MOZ_X11
{ "Gtk Clipboard",
NS_CLIPBOARD_CID,
"@mozilla.org/widget/clipboard;1",
nsClipboardConstructor },
{ "Clipboard Helper",
NS_CLIPBOARDHELPER_CID,
"@mozilla.org/widget/clipboardhelper;1",
nsClipboardHelperConstructor },
{ "Gtk Drag Service",
NS_DRAGSERVICE_CID,
"@mozilla.org/widget/dragservice;1",
nsDragServiceConstructor },
+#endif
{ "HTML Format Converter",
NS_HTMLFORMATCONVERTER_CID,
"@mozilla.org/widget/htmlformatconverter;1",
nsHTMLFormatConverterConstructor },
{ "Gtk2 Bidi Keyboard",
NS_BIDIKEYBOARD_CID,
"@mozilla.org/widget/bidikeyboard;1",
nsBidiKeyboardConstructor },
--- a/widget/src/gtk2/nsWindow.cpp
+++ b/widget/src/gtk2/nsWindow.cpp
@@ -52,29 +52,30 @@
#include "nsWidgetsCID.h"
#include "nsIDragService.h"
#include "nsIDragSessionGTK.h"
#include "nsGtkKeyUtils.h"
#include "nsGtkCursors.h"
#include <gtk/gtkwindow.h>
+#ifdef MOZ_X11
#include <gdk/gdkx.h>
+#include <X11/XF86keysym.h>
+#include "gtk2xtbin.h"
+#endif /* MOZ_X11 */
#include <gdk/gdkkeysyms.h>
-#include <X11/XF86keysym.h>
#include "nsWidgetAtoms.h"
#ifdef MOZ_ENABLE_STARTUP_NOTIFICATION
#define SN_API_NOT_YET_FROZEN
#include <startup-notification-1.0/libsn/sn.h>
#endif
-#include "gtk2xtbin.h"
-
#include "nsIPrefService.h"
#include "nsIPrefBranch.h"
#include "nsIServiceManager.h"
#include "nsIStringBundle.h"
#include "nsGfxCIID.h"
#ifdef ACCESSIBILITY
#include "nsIAccessibleRole.h"
@@ -103,20 +104,39 @@ static const char sAccessibilityKey [] =
#include "gfxIImageFrame.h"
#include "nsGfxCIID.h"
#include "nsIImage.h"
#include "nsImageToPixbuf.h"
#include "nsIInterfaceRequestorUtils.h"
#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"
#endif
/* For PrepareNativeWidget */
static NS_DEFINE_IID(kDeviceContextCID, NS_DEVICE_CONTEXT_CID);
@@ -179,22 +199,24 @@ static gboolean window_state_event_cb
static void theme_changed_cb (GtkSettings *settings,
GParamSpec *pspec,
nsWindow *data);
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 */
static gboolean drag_motion_event_cb (GtkWidget *aWidget,
GdkDragContext *aDragContext,
gint aX,
gint aY,
@@ -215,20 +237,22 @@ static void drag_data_received_event_
gint aX,
gint aY,
GtkSelectionData *aSelectionData,
guint aInfo,
guint32 aTime,
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);
// this is the last window that had a drag event happen on it.
nsWindow *nsWindow::mLastDragMotionWindow = NULL;
PRBool nsWindow::sIsDraggingOutOf = PR_FALSE;
@@ -318,17 +342,19 @@ nsWindow::nsWindow()
mContainerBlockFocus = PR_FALSE;
mIsVisible = PR_FALSE;
mRetryPointerGrab = PR_FALSE;
mRetryKeyboardGrab = PR_FALSE;
mActivatePending = PR_FALSE;
mTransientParent = nsnull;
mWindowType = eWindowType_child;
mSizeState = nsSizeMode_Normal;
+#ifdef MOZ_X11
mOldFocusWindow = 0;
+#endif /* MOZ_X11 */
mPluginType = PluginType_NONE;
if (!gGlobalsInitialized) {
gGlobalsInitialized = PR_TRUE;
// It's OK if either of these fail, but it may not be one day.
initialize_prefs();
}
@@ -352,28 +378,46 @@ nsWindow::nsWindow()
mRootAccessible = nsnull;
#endif
mIsTransparent = PR_FALSE;
mTransparencyBitmap = nsnull;
mTransparencyBitmapWidth = 0;
mTransparencyBitmapHeight = 0;
+
+#ifdef MOZ_DFB
+ mDFBCursorX = 0;
+ mDFBCursorY = 0;
+
+ mDFBCursorCount = 0;
+
+ mDFB = NULL;
+ mDFBLayer = NULL;
+#endif
}
nsWindow::~nsWindow()
{
LOG(("nsWindow::~nsWindow() [%p]\n", (void *)this));
if (mLastDragMotionWindow == this) {
mLastDragMotionWindow = NULL;
}
delete[] mTransparencyBitmap;
mTransparencyBitmap = nsnull;
+#ifdef MOZ_DFB
+ if (mDFBLayer)
+ mDFBLayer->Release( mDFBLayer );
+
+ if (mDFB)
+ mDFB->Release( mDFB );
+#endif
+
Destroy();
}
/* static */ void
nsWindow::ReleaseGlobals()
{
for (PRUint32 i = 0; i < NS_ARRAY_LENGTH(gCursorCache); ++i) {
if (gCursorCache[i]) {
@@ -453,20 +497,22 @@ nsWindow::Destroy(void)
#endif
// make sure that we remove ourself as the focus window
if (gFocusWindow == this) {
LOGFOCUS(("automatically losing focus...\n"));
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));
mWindowGroup = nsnull;
}
// Destroy thebes surface now. Badness can happen if we destroy
// the surface after its X Window.
@@ -1223,16 +1269,23 @@ nsWindow::SetColorMap(nsColorMap *aColor
NS_IMETHODIMP
nsWindow::Scroll(PRInt32 aDx,
PRInt32 aDy,
nsRect *aClipRect)
{
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
for (nsIWidget* kid = mFirstChild; kid; kid = kid->GetNextSibling()) {
nsRect bounds;
kid->GetBounds(bounds);
bounds.x += aDx;
bounds.y += aDy;
@@ -1276,17 +1329,21 @@ nsWindow::GetNativeData(PRUint32 aDataTy
break;
}
case NS_NATIVE_PLUGIN_PORT:
return SetupPluginPort();
break;
case NS_NATIVE_DISPLAY:
+#ifdef MOZ_X11
return GDK_DISPLAY();
+#else
+ return nsnull;
+#endif /* MOZ_X11 */
break;
case NS_NATIVE_GRAPHIC: {
NS_ASSERTION(nsnull != mToolkit, "NULL toolkit, unable to get a GC");
return (void *)static_cast<nsGTKToolkit *>(mToolkit)->GetSharedGC();
break;
}
@@ -1554,16 +1611,17 @@ nsWindow::LoseFocus(void)
// Paint flashing code
#define CAPS_LOCK_IS_ON \
(gdk_keyboard_get_modifiers() & GDK_LOCK_MASK)
#define WANT_PAINT_FLASHING \
(debug_WantPaintFlashing() && CAPS_LOCK_IS_ON)
+#ifdef MOZ_X11
static void
gdk_window_flash(GdkWindow * aGdkWindow,
unsigned int aTimes,
unsigned int aInterval, // Milliseconds
GdkRegion * aRegion)
{
gint x;
gint y;
@@ -1613,16 +1671,17 @@ gdk_window_flash(GdkWindow * aGdkWind
PR_Sleep(PR_MillisecondsToInterval(aInterval));
}
gdk_gc_destroy(gc);
gdk_region_offset(aRegion, -x, -y);
}
+#endif /* MOZ_X11 */
#endif // DEBUG
gboolean
nsWindow::OnExposeEvent(GtkWidget *aWidget, GdkEventExpose *aEvent)
{
if (mIsDestroyed) {
LOG(("Expose event on destroyed window [%p] window %p\n",
(void *)this, (void *)aEvent->window));
@@ -1656,16 +1715,38 @@ nsWindow::OnExposeEvent(GtkWidget *aWidg
GdkRectangle *r;
GdkRectangle *r_end = rects + nrects;
for (r = rects; r < r_end; ++r) {
updateRegion->Union(r->x, r->y, r->width, r->height);
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);
return FALSE;
}
PRBool translucent;
GetHasTransparentBackground(translucent);
@@ -1703,23 +1784,27 @@ nsWindow::OnExposeEvent(GtkWidget *aWidg
#else // MOZ_ENABLE_GLITZ
// Instead of just doing PushGroup we're going to do a little dance
// to ensure that GDK creates the pixmap, so it doesn't go all
// XGetGeometry on us in gdk_pixmap_foreign_new_for_display when we
// paint native themes
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());
if (bufferPixmapSurface && bufferPixmapSurface->CairoStatus()) {
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()->
CreateRenderingContextInstance(*getter_AddRefs(newRC));
if (NS_FAILED(rv)) {
bufferPixmapSurface = nsnull;
} else {
rv = newRC->Init(GetDeviceContext(), bufferPixmapSurface);
@@ -1739,26 +1824,29 @@ nsWindow::OnExposeEvent(GtkWidget *aWidg
// cairo inflates the update region, etc. So don't paint flash
// for cairo.
#ifdef DEBUG
if (WANT_PAINT_FLASHING && aEvent->window)
gdk_window_flash(aEvent->window, 1, 100, aEvent->region);
#endif
#endif
+#endif // MOZ_X11
+
nsPaintEvent event(PR_TRUE, NS_PAINT, this);
event.refPoint.x = aEvent->area.x;
event.refPoint.y = aEvent->area.y;
event.rect = nsnull;
event.region = updateRegion;
event.renderingContext = rc;
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)) {
if (status != nsEventStatus_eIgnore) {
if (translucent) {
nsRefPtr<gfxPattern> pattern = ctx->PopGroup();
ctx->SetOperator(gfxContext::OPERATOR_SOURCE);
ctx->SetPattern(pattern);
@@ -1804,16 +1892,21 @@ nsWindow::OnExposeEvent(GtkWidget *aWidg
}
if (bufferPixmap) {
g_object_unref(G_OBJECT(bufferPixmap));
}
ctx->Restore();
}
+#endif // MOZ_X11
+
+#ifdef MOZ_DFB
+ ctx->Restore();
+#endif
g_free(rects);
// check the return value!
return TRUE;
}
gboolean
@@ -1944,54 +2037,128 @@ nsWindow::OnLeaveNotifyEvent(GtkWidget *
? nsMouseEvent::eTopLevel : nsMouseEvent::eChild;
LOG(("OnLeaveNotify: %p\n", (void *)this));
nsEventStatus status;
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)
{
// 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;
// see if we can compress this event
// XXXldb Why skip every other motion event when we have multiple,
// but not more than that?
+ PRPackedBool synthEvent = PR_FALSE;
+#ifdef MOZ_X11
XEvent xevent;
- PRPackedBool synthEvent = PR_FALSE;
+
while (XCheckWindowEvent(GDK_WINDOW_XDISPLAY(aEvent->window),
GDK_WINDOW_XWINDOW(aEvent->window),
ButtonMotionMask, &xevent)) {
synthEvent = PR_TRUE;
}
// if plugins still keeps the focus, get it back
if (gPluginFocusWindow && gPluginFocusWindow != this) {
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);
event.isShift = (xevent.xmotion.state & GDK_SHIFT_MASK)
? PR_TRUE : PR_FALSE;
event.isControl = (xevent.xmotion.state & GDK_CONTROL_MASK)
? PR_TRUE : PR_FALSE;
event.isAlt = (xevent.xmotion.state & GDK_MOD1_MASK)
? 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()
if (aEvent->window == mDrawingarea->inner_window) {
event.refPoint.x = nscoord(aEvent->x);
event.refPoint.y = nscoord(aEvent->y);
} else {
nsRect windowRect;
@@ -2009,16 +2176,17 @@ nsWindow::OnMotionNotifyEvent(GtkWidget
? PR_TRUE : PR_FALSE;
event.time = aEvent->time;
}
nsEventStatus status;
DispatchEvent(&event, status);
}
+#endif
void
nsWindow::InitButtonEvent(nsMouseEvent &aEvent,
GdkEventButton *aGdkEvent)
{
// XXX see OnScrollEvent()
if (aGdkEvent->window == mDrawingarea->inner_window) {
aEvent.refPoint.x = nscoord(aGdkEvent->x);
@@ -2210,21 +2378,23 @@ nsWindow::OnContainerFocusInEvent(GtkWid
LOGFOCUS(("Events sent from focus in event [%p]\n", (void *)this));
}
void
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.
if (!gFocusWindow)
return;
GdkWindow *tmpWindow;
tmpWindow = (GdkWindow *)gFocusWindow->GetNativeData(NS_NATIVE_WINDOW);
@@ -2373,16 +2543,17 @@ nsWindow::OnKeyPressEvent(GtkWidget *aWi
|| aEvent->keyval == GDK_Control_R
|| aEvent->keyval == GDK_Alt_L
|| aEvent->keyval == GDK_Alt_R
|| aEvent->keyval == GDK_Meta_L
|| aEvent->keyval == GDK_Meta_R) {
return TRUE;
}
+#ifdef MOZ_X11
// Look for specialized app-command keys
switch (aEvent->keyval) {
case XF86XK_Back:
return DispatchCommandEvent(nsWidgetAtoms::Back);
case XF86XK_Forward:
return DispatchCommandEvent(nsWidgetAtoms::Forward);
case XF86XK_Refresh:
return DispatchCommandEvent(nsWidgetAtoms::Reload);
@@ -2390,16 +2561,17 @@ nsWindow::OnKeyPressEvent(GtkWidget *aWi
return DispatchCommandEvent(nsWidgetAtoms::Stop);
case XF86XK_Search:
return DispatchCommandEvent(nsWidgetAtoms::Search);
case XF86XK_Favorites:
return DispatchCommandEvent(nsWidgetAtoms::Bookmarks);
case XF86XK_HomePage:
return DispatchCommandEvent(nsWidgetAtoms::Home);
}
+#endif /* MOZ_X11 */
nsKeyEvent event(PR_TRUE, NS_KEY_PRESS, this);
InitKeyEvent(event, aEvent);
if (isKeyDownCancelled) {
// If prevent default set for onkeydown, do the same for onkeypress
event.flags |= NS_EVENT_FLAG_NO_DEFAULT;
}
event.charCode = nsConvertCharCodeToUnicode(aEvent);
@@ -3245,18 +3417,23 @@ nsWindow::NativeCreate(nsIWidget
}
}
break;
default:
break;
}
// 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
g_object_set_data(G_OBJECT(mDrawingarea->clip_window), "nsWindow",
this);
g_object_set_data(G_OBJECT(mDrawingarea->inner_window), "nsWindow",
this);
@@ -3390,25 +3567,42 @@ nsWindow::NativeCreate(nsIWidget
}
}
if (sAccessibilityEnabled) {
LOG(("nsWindow:: Create Toplevel Accessibility\n"));
CreateRootAccessible();
}
#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;
}
NS_IMETHODIMP
nsWindow::SetWindowClass(const nsAString &xulWinType)
{
if (!mShell)
return NS_ERROR_FAILURE;
+#ifdef MOZ_X11
nsXPIDLString brandName;
GetBrandName(brandName);
XClassHint *class_hint = XAllocClassHint();
if (!class_hint)
return NS_ERROR_OUT_OF_MEMORY;
const char *role = NULL;
class_hint->res_name = ToNewCString(xulWinType);
@@ -3442,16 +3636,49 @@ nsWindow::SetWindowClass(const nsAString
// Can't use gtk_window_set_wmclass() for this; it prints
// a warning & refuses to make the change.
XSetClassHint(GDK_DISPLAY(),
GDK_WINDOW_XWINDOW(GTK_WIDGET(mShell)->window),
class_hint);
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;
}
void
nsWindow::NativeResize(PRInt32 aWidth, PRInt32 aHeight, PRBool aRepaint)
{
LOG(("nsWindow::NativeResize [%p] %d %d\n", (void *)this,
aWidth, aHeight));
@@ -3965,30 +4192,32 @@ nsWindow::SetupPluginPort(void)
return nsnull;
if (GDK_WINDOW_OBJECT(mDrawingarea->inner_window)->destroyed == TRUE)
return nsnull;
// 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),
&xattrs);
XSelectInput (GDK_DISPLAY (),
GDK_WINDOW_XWINDOW(mDrawingarea->inner_window),
xattrs.your_event_mask |
SubstructureNotifyMask);
gdk_window_add_filter(mDrawingarea->inner_window,
plugin_window_filter_func,
this);
XSync(GDK_DISPLAY(), False);
+#endif /* MOZ_X11 */
return (void *)GDK_WINDOW_XWINDOW(mDrawingarea->inner_window);
}
nsresult
nsWindow::SetWindowIconList(const nsCStringArray &aIconList)
{
GList *list = NULL;
@@ -4022,16 +4251,17 @@ nsWindow::SetDefaultIcon(void)
}
void
nsWindow::SetPluginType(PluginType aPluginType)
{
mPluginType = aPluginType;
}
+#ifdef MOZ_X11
void
nsWindow::SetNonXEmbedPluginFocus()
{
if (gPluginFocusWindow == this || mPluginType!=PluginType_NONXEMBED) {
return;
}
if (gPluginFocusWindow) {
@@ -4116,16 +4346,17 @@ nsWindow::LoseNonXEmbedPluginFocus()
gdk_error_trap_pop();
}
gPluginFocusWindow = NULL;
mOldFocusWindow = 0;
gdk_window_remove_filter(NULL, plugin_client_message_filter, this);
LOGFOCUS(("nsWindow::LoseNonXEmbedPluginFocus end\n"));
}
+#endif /* MOZ_X11 */
gint
nsWindow::ConvertBorderStyles(nsBorderStyle aStyle)
{
gint w = 0;
if (aStyle == eBorderStyle_default)
@@ -4199,17 +4430,21 @@ nsWindow::HideWindowChrome(PRBool aShoul
if (wasVisible)
gdk_window_show(mShell->window);
// For some window managers, adding or removing window decorations
// requires unmapping and remapping our toplevel window. Go ahead
// 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;
}
PRBool
check_for_rollup(GdkWindow *aWindow, gdouble aMouseX, gdouble aMouseY,
PRBool aIsWheel)
{
@@ -4707,16 +4942,17 @@ focus_out_event_cb(GtkWidget *widget, Gd
if (!window)
return FALSE;
window->OnContainerFocusOutEvent(widget, event);
return FALSE;
}
+#ifdef MOZ_X11
/* static */
GdkFilterReturn
plugin_window_filter_func(GdkXEvent *gdk_xevent, GdkEvent *event, gpointer data)
{
GtkWidget *widget;
GdkWindow *plugin_window;
gpointer user_data;
XEvent *xevent;
@@ -4805,16 +5041,17 @@ plugin_client_message_filter(GdkXEvent *
if ((Atom) xevent->xclient.data.l[0] ==
gdk_x11_get_xatom_by_name("WM_TAKE_FOCUS")) {
// block it from gtk2.0 focus proxy
return_val = GDK_FILTER_REMOVE;
}
return return_val;
}
+#endif /* MOZ_X11 */
/* static */
gboolean
key_press_event_cb(GtkWidget *widget, GdkEventKey *event)
{
LOG(("key_press_event_cb\n"));
// find the window with focus and dispatch this event to that widget
nsWindow *window = get_window_for_gtk_widget(widget);
@@ -5191,16 +5428,17 @@ gdk_keyboard_get_modifiers()
{
GdkModifierType m = (GdkModifierType) 0;
gdk_window_get_pointer(NULL, NULL, NULL, &m);
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
gdk_keyboard_get_modmap_masks(Display* aDisplay,
PRUint32* aCapsLockMask,
PRUint32* aNumLockMask,
PRUint32* aScrollLockMask)
{
@@ -5248,16 +5486,17 @@ gdk_keyboard_get_modmap_masks(Display*
}
}
}
XFreeModifiermap(xmodmap);
XFree(xkeymap);
return PR_TRUE;
}
+#endif /* MOZ_X11 */
#ifdef ACCESSIBILITY
/**
* void
* nsWindow::CreateRootAccessible
*
* request to create the nsIAccessible Object for the toplevel window
**/
@@ -5905,16 +6144,18 @@ nsWindow::CancelIMEComposition()
return NS_OK;
}
NS_IMETHODIMP
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(
GDK_WINDOW_XDISPLAY(mDrawingarea->inner_window),
&capsLockMask, &numLockMask, &scrollLockMask);
if (!foundMasks)
return NS_ERROR_NOT_IMPLEMENTED;
@@ -5924,16 +6165,19 @@ nsWindow::GetToggledKeyState(PRUint32 aK
case NS_VK_NUM_LOCK: mask = numLockMask; break;
case NS_VK_SCROLL_LOCK: mask = scrollLockMask; break;
}
if (mask == 0)
return NS_ERROR_NOT_IMPLEMENTED;
*aLEDState = (modifiers & mask) != 0;
return NS_OK;
+#else
+ return NS_ERROR_NOT_IMPLEMENTED;
+#endif /* MOZ_X11 */
}
/* static */
void
IM_preedit_changed_cb(GtkIMContext *aContext,
nsWindow *aWindow)
{
gchar *preedit_string;
@@ -6202,105 +6446,65 @@ IM_get_input_context(nsWindow *aWindow)
return data->mContext;
if (data->mEnabled == nsIWidget::IME_STATUS_PASSWORD)
return data->mSimpleContext;
return data->mDummyContext;
}
#endif
+#ifdef MOZ_X11
/* static */ already_AddRefed<gfxASurface>
nsWindow::GetSurfaceForGdkDrawable(GdkDrawable* aDrawable,
const nsSize& aSize)
{
GdkVisual* visual = gdk_drawable_get_visual(aDrawable);
Visual* xVisual = gdk_x11_visual_get_xvisual(visual);
Display* xDisplay = gdk_x11_drawable_get_xdisplay(aDrawable);
Drawable xDrawable = gdk_x11_drawable_get_xid(aDrawable);
gfxASurface* result = new gfxXlibSurface(xDisplay, xDrawable, xVisual,
gfxIntSize(aSize.width, aSize.height));
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;
-
- if (!mThebesSurface) {
- GdkDrawable* d;
- gint x_offset, y_offset;
- gdk_window_get_internal_paint_info(mDrawingarea->inner_window,
- &d, &x_offset, &y_offset);
-
- 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);
+ 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);
+
+ mThebesSurface = new gfxXlibSurface
+ (GDK_WINDOW_XDISPLAY(d),
+ GDK_WINDOW_XWINDOW(d),
+ GDK_VISUAL_XVISUAL(gdk_drawable_get_visual(d)),
+ gfxIntSize(width, height));
#endif
- }
-
- if (mThebesSurface) {
- mThebesSurface->SetDeviceOffset(gfxPoint(-x_offset, -y_offset));
- }
+#ifdef MOZ_DFB
+ mThebesSurface = new gfxDirectFBSurface(gdk_directfb_surface_lookup(d));
+#endif
+
+ // 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;
}
NS_IMETHODIMP
nsWindow::BeginResizeDrag(nsGUIEvent* aEvent, PRInt32 aHorizontal, PRInt32 aVertical)
{
--- a/widget/src/gtk2/nsWindow.h
+++ b/widget/src/gtk2/nsWindow.h
@@ -51,17 +51,23 @@
#include "nsIDragService.h"
#include "nsITimer.h"
#include "nsWidgetAtoms.h"
#include "gfxASurface.h"
#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
#include "nsIAccessNode.h"
#include "nsIAccessible.h"
#endif
#ifdef USE_XIM
@@ -251,22 +257,26 @@ 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);
+#ifdef MOZ_X11
Window mOldFocusWindow;
+#endif /* MOZ_X11 */
static guint32 mLastButtonPressTime;
static guint32 mLastButtonReleaseTime;
NS_IMETHOD BeginResizeDrag (nsGUIEvent* aEvent, PRInt32 aHorizontal, PRInt32 aVertical);
#ifdef USE_XIM
void IMEInitData (void);
@@ -397,16 +407,24 @@ private:
PRInt32 mSizeState;
PluginType mPluginType;
PRInt32 mTransparencyBitmapWidth;
PRInt32 mTransparencyBitmapHeight;
nsRefPtr<gfxASurface> mThebesSurface;
+#ifdef MOZ_DFB
+ int mDFBCursorX;
+ int mDFBCursorY;
+ PRUint32 mDFBCursorCount;
+ IDirectFB *mDFB;
+ IDirectFBDisplayLayer *mDFBLayer;
+#endif
+
#ifdef ACCESSIBILITY
nsCOMPtr<nsIAccessible> mRootAccessible;
void CreateRootAccessible();
void GetRootAccessible(nsIAccessible** aAccessible);
void DispatchActivateEvent(void);
void DispatchDeactivateEvent(void);
NS_IMETHOD_(PRBool) DispatchAccessibleEvent(nsIAccessible** aAccessible);
#endif