Bug 635134 - Adds X11 run-time check for Gtk3 backend. r=karlt

--HG--
extra : rebase_source : 18486b689a7ff1560830e63900af1d60348ccabb
This commit is contained in:
Martin Stransky 2015-03-05 03:56:00 +01:00
parent c230b69ed6
commit d15abcbc8c
9 changed files with 181 additions and 143 deletions

View File

@ -63,7 +63,8 @@ gfxPlatformGtk::gfxPlatformGtk()
if (!sFontconfigUtils)
sFontconfigUtils = gfxFontconfigUtils::GetFontconfigUtils();
#ifdef MOZ_X11
sUseXRender = mozilla::Preferences::GetBool("gfx.xrender.enabled");
sUseXRender = (GDK_IS_X11_DISPLAY(gdk_display_get_default())) ?
mozilla::Preferences::GetBool("gfx.xrender.enabled") : false;
#endif
uint32_t canvasMask = BackendTypeBit(BackendType::CAIRO) | BackendTypeBit(BackendType::SKIA);
@ -276,11 +277,15 @@ gfxPlatformGtk::GetPlatformCMSOutputProfile(void *&mem, size_t &size)
size = 0;
#ifdef MOZ_X11
GdkDisplay *display = gdk_display_get_default();
if (!GDK_IS_X11_DISPLAY(display))
return;
const char EDID1_ATOM_NAME[] = "XFree86_DDC_EDID1_RAWDATA";
const char ICC_PROFILE_ATOM_NAME[] = "_ICC_PROFILE";
Atom edidAtom, iccAtom;
Display *dpy = GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
Display *dpy = GDK_DISPLAY_XDISPLAY(display);
// In xpcshell tests, we never initialize X and hence don't have a Display.
// In this case, there's no output colour management to be done, so we just
// return with nullptr.

View File

@ -3610,35 +3610,6 @@ XREMain::XRE_mainStartup(bool* aExitFlag)
}
}
#endif /* MOZ_WIDGET_GTK */
#ifdef MOZ_ENABLE_XREMOTE
// handle --remote now that xpcom is fired up
bool newInstance;
{
char *e = PR_GetEnv("MOZ_NO_REMOTE");
mDisableRemote = (e && *e);
if (mDisableRemote) {
newInstance = true;
} else {
e = PR_GetEnv("MOZ_NEW_INSTANCE");
newInstance = (e && *e);
}
}
if (!newInstance) {
// Try to remote the entire command line. If this fails, start up normally.
const char* desktopStartupIDPtr =
mDesktopStartupID.IsEmpty() ? nullptr : mDesktopStartupID.get();
RemoteResult rr = RemoteCommandLine(desktopStartupIDPtr);
if (rr == REMOTE_FOUND) {
*aExitFlag = true;
return 0;
}
else if (rr == REMOTE_ARG_BAD)
return 1;
}
#endif
#ifdef MOZ_X11
// Init X11 in thread-safe mode. Must be called prior to the first call to XOpenDisplay
// (called inside gdk_display_open). This is a requirement for off main tread compositing.
@ -3661,14 +3632,47 @@ XREMain::XRE_mainStartup(bool* aExitFlag)
}
#endif
#if defined(MOZ_WIDGET_GTK)
mGdkDisplay = gdk_display_open(display_name);
if (!mGdkDisplay) {
PR_fprintf(PR_STDERR, "Error: cannot open display: %s\n", display_name);
return 1;
{
mGdkDisplay = gdk_display_open(display_name);
if (!mGdkDisplay) {
PR_fprintf(PR_STDERR, "Error: cannot open display: %s\n", display_name);
return 1;
}
gdk_display_manager_set_default_display (gdk_display_manager_get(),
mGdkDisplay);
if (!GDK_IS_X11_DISPLAY(mGdkDisplay))
mDisableRemote = true;
}
gdk_display_manager_set_default_display (gdk_display_manager_get(),
mGdkDisplay);
#endif
#ifdef MOZ_ENABLE_XREMOTE
// handle --remote now that xpcom is fired up
bool newInstance;
{
char *e = PR_GetEnv("MOZ_NO_REMOTE");
mDisableRemote = (mDisableRemote || (e && *e));
if (mDisableRemote) {
newInstance = true;
} else {
e = PR_GetEnv("MOZ_NEW_INSTANCE");
newInstance = (e && *e);
}
}
if (!newInstance) {
// Try to remote the entire command line. If this fails, start up normally.
const char* desktopStartupIDPtr =
mDesktopStartupID.IsEmpty() ? nullptr : mDesktopStartupID.get();
RemoteResult rr = RemoteCommandLine(desktopStartupIDPtr);
if (rr == REMOTE_FOUND) {
*aExitFlag = true;
return 0;
}
else if (rr == REMOTE_ARG_BAD)
return 1;
}
#endif
#if defined(MOZ_WIDGET_GTK)
// g_set_application_name () is only defined in glib2.2 and higher.
_g_set_application_name_fn _g_set_application_name =
(_g_set_application_name_fn)FindFunction("g_set_application_name");

View File

@ -22,4 +22,9 @@ gdk_x11_window_get_xid(GdkWindow *window)
{
return(GDK_WINDOW_XWINDOW(window));
}
#ifndef GDK_IS_X11_DISPLAY
#define GDK_IS_X11_DISPLAY(a) (true)
#endif
#endif /* GDKX_WRAPPER_H */

View File

@ -53,6 +53,8 @@ STUB(gdk_property_get)
STUB(gdk_screen_get_default)
STUB(gdk_screen_get_display)
STUB(gdk_screen_get_font_options)
STUB(gdk_screen_get_height)
STUB(gdk_screen_get_height_mm)
STUB(gdk_screen_get_number)
STUB(gdk_screen_get_resolution)
STUB(gdk_screen_get_rgba_visual)
@ -490,6 +492,7 @@ STUB(gdk_error_trap_pop_ignored)
STUB(gdk_event_get_source_device)
STUB(gdk_window_get_type)
STUB(gdk_x11_window_get_xid)
STUB(gdk_x11_display_get_type)
STUB(gtk_cairo_should_draw_window)
STUB(gtk_cairo_transform_to_window)
STUB(gtk_combo_box_text_append)

View File

@ -911,52 +911,54 @@ RetrievalContext::Wait()
return data;
}
Display *xDisplay = GDK_DISPLAY_XDISPLAY(gdk_display_get_default()) ;
checkEventContext context;
context.cbWidget = nullptr;
context.selAtom = gdk_x11_atom_to_xatom(gdk_atom_intern("GDK_SELECTION",
FALSE));
GdkDisplay *gdkDisplay = gdk_display_get_default();
if (GDK_IS_X11_DISPLAY(gdkDisplay)) {
Display *xDisplay = GDK_DISPLAY_XDISPLAY(gdkDisplay);
checkEventContext context;
context.cbWidget = nullptr;
context.selAtom = gdk_x11_atom_to_xatom(gdk_atom_intern("GDK_SELECTION",
FALSE));
// Send X events which are relevant to the ongoing selection retrieval
// to the clipboard widget. Wait until either the operation completes, or
// we hit our timeout. All other X events remain queued.
// Send X events which are relevant to the ongoing selection retrieval
// to the clipboard widget. Wait until either the operation completes, or
// we hit our timeout. All other X events remain queued.
int select_result;
int select_result;
int cnumber = ConnectionNumber(xDisplay);
fd_set select_set;
FD_ZERO(&select_set);
FD_SET(cnumber, &select_set);
++cnumber;
TimeStamp start = TimeStamp::Now();
int cnumber = ConnectionNumber(xDisplay);
fd_set select_set;
FD_ZERO(&select_set);
FD_SET(cnumber, &select_set);
++cnumber;
TimeStamp start = TimeStamp::Now();
do {
XEvent xevent;
do {
XEvent xevent;
while (XCheckIfEvent(xDisplay, &xevent, checkEventProc,
(XPointer) &context)) {
while (XCheckIfEvent(xDisplay, &xevent, checkEventProc,
(XPointer) &context)) {
if (xevent.xany.type == SelectionNotify)
DispatchSelectionNotifyEvent(context.cbWidget, &xevent);
else
DispatchPropertyNotifyEvent(context.cbWidget, &xevent);
if (xevent.xany.type == SelectionNotify)
DispatchSelectionNotifyEvent(context.cbWidget, &xevent);
else
DispatchPropertyNotifyEvent(context.cbWidget, &xevent);
if (mState == COMPLETED) {
void *data = mData;
mData = nullptr;
return data;
if (mState == COMPLETED) {
void *data = mData;
mData = nullptr;
return data;
}
}
}
TimeStamp now = TimeStamp::Now();
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = std::max<int32_t>(0,
kClipboardTimeout - (now - start).ToMicroseconds());
select_result = select(cnumber, &select_set, nullptr, nullptr, &tv);
} while (select_result == 1 ||
(select_result == -1 && errno == EINTR));
TimeStamp now = TimeStamp::Now();
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = std::max<int32_t>(0,
kClipboardTimeout - (now - start).ToMicroseconds());
select_result = select(cnumber, &select_set, nullptr, nullptr, &tv);
} while (select_result == 1 ||
(select_result == -1 && errno == EINTR));
}
#ifdef DEBUG_CLIPBOARD
printf("exceeded clipboard timeout\n");
#endif

View File

@ -175,7 +175,8 @@ KeymapWrapper::KeymapWrapper() :
g_object_weak_ref(G_OBJECT(mGdkKeymap),
(GWeakNotify)OnDestroyKeymap, this);
InitXKBExtension();
if (GDK_IS_X11_DISPLAY(gdk_display_get_default()))
InitXKBExtension();
Init();
}
@ -195,7 +196,8 @@ KeymapWrapper::Init()
mModifierKeys.Clear();
memset(mModifierMasks, 0, sizeof(mModifierMasks));
InitBySystemSettings();
if (GDK_IS_X11_DISPLAY(gdk_display_get_default()))
InitBySystemSettings();
gdk_window_add_filter(nullptr, FilterEvents, this);
@ -897,9 +899,10 @@ KeymapWrapper::InitKeyEvent(WidgetKeyboardEvent& aKeyEvent,
// state. It means if there're some pending modifier key press or
// key release events, the result isn't what we want.
guint modifierState = aGdkKeyEvent->state;
if (aGdkKeyEvent->is_modifier) {
GdkDisplay* gdkDisplay = gdk_display_get_default();
if (aGdkKeyEvent->is_modifier && GDK_IS_X11_DISPLAY(gdkDisplay)) {
Display* display =
gdk_x11_display_get_xdisplay(gdk_display_get_default());
gdk_x11_display_get_xdisplay(gdkDisplay);
if (XEventsQueued(display, QueuedAfterReading)) {
XEvent nextEvent;
XPeekEvent(display, &nextEvent);

View File

@ -34,6 +34,9 @@ NS_IMPL_ISUPPORTS_INHERITED0(nsIdleServiceGTK, nsIdleService)
static void Initialize()
{
if (!GDK_IS_X11_DISPLAY(gdk_display_get_default()))
return;
// This will leak - See comments in ~nsIdleServiceGTK().
PRLibrary* xsslib = PR_LoadLibrary("libXss.so.1");
if (!xsslib) // ouch.
@ -136,4 +139,3 @@ nsIdleServiceGTK::UsePollMode()
{
return sInitialized;
}

View File

@ -53,6 +53,7 @@ root_window_event_filter(GdkXEvent *aGdkXEvent, GdkEvent *aGdkEvent,
nsScreenManagerGtk :: nsScreenManagerGtk ( )
: mXineramalib(nullptr)
, mRootWindow(nullptr)
, mNetWorkareaAtom(0)
{
// nothing else to do. I guess we could cache a bunch of information
// here, but we want to ask the device at runtime in case anything
@ -100,8 +101,9 @@ nsScreenManagerGtk :: EnsureInit()
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);
if (GDK_IS_X11_DISPLAY(gdk_display_get_default()))
mNetWorkareaAtom =
XInternAtom(GDK_WINDOW_XDISPLAY(mRootWindow), "_NET_WORKAREA", False);
#endif
return Init();
@ -114,7 +116,9 @@ nsScreenManagerGtk :: Init()
XineramaScreenInfo *screenInfo = nullptr;
int numScreens;
if (!mXineramalib) {
bool useXinerama = GDK_IS_X11_DISPLAY(gdk_display_get_default());
if (useXinerama && !mXineramalib) {
mXineramalib = PR_LoadLibrary("libXinerama.so.1");
if (!mXineramalib) {
mXineramalib = SCREEN_MANAGER_LIBRARY_LOAD_FAILED;

View File

@ -728,14 +728,13 @@ nsWindow::GetParent(void)
float
nsWindow::GetDPI()
{
Display *dpy = GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
int defaultScreen = DefaultScreen(dpy);
double heightInches = DisplayHeightMM(dpy, defaultScreen)/MM_PER_INCH_FLOAT;
GdkScreen *screen = gdk_display_get_default_screen(gdk_display_get_default());
double heightInches = gdk_screen_get_height_mm(screen)/MM_PER_INCH_FLOAT;
if (heightInches < 0.25) {
// Something's broken, but we'd better not crash.
return 96.0f;
}
return float(DisplayHeight(dpy, defaultScreen)/heightInches);
return float(gdk_screen_get_height(screen)/heightInches);
}
double
@ -1942,22 +1941,25 @@ nsWindow::HasPendingInputEvent()
bool haveEvent;
#ifdef MOZ_X11
XEvent ev;
Display *display = GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
haveEvent =
XCheckMaskEvent(display,
KeyPressMask | KeyReleaseMask | ButtonPressMask |
ButtonReleaseMask | EnterWindowMask | LeaveWindowMask |
PointerMotionMask | PointerMotionHintMask |
Button1MotionMask | Button2MotionMask |
Button3MotionMask | Button4MotionMask |
Button5MotionMask | ButtonMotionMask | KeymapStateMask |
VisibilityChangeMask | StructureNotifyMask |
ResizeRedirectMask | SubstructureNotifyMask |
SubstructureRedirectMask | FocusChangeMask |
PropertyChangeMask | ColormapChangeMask |
OwnerGrabButtonMask, &ev);
if (haveEvent) {
XPutBackEvent(display, &ev);
GdkDisplay* gdkDisplay = gdk_display_get_default();
if (GDK_IS_X11_DISPLAY(gdkDisplay)) {
Display *display = GDK_DISPLAY_XDISPLAY(gdkDisplay);
haveEvent =
XCheckMaskEvent(display,
KeyPressMask | KeyReleaseMask | ButtonPressMask |
ButtonReleaseMask | EnterWindowMask | LeaveWindowMask |
PointerMotionMask | PointerMotionHintMask |
Button1MotionMask | Button2MotionMask |
Button3MotionMask | Button4MotionMask |
Button5MotionMask | ButtonMotionMask | KeymapStateMask |
VisibilityChangeMask | StructureNotifyMask |
ResizeRedirectMask | SubstructureNotifyMask |
SubstructureRedirectMask | FocusChangeMask |
PropertyChangeMask | ColormapChangeMask |
OwnerGrabButtonMask, &ev);
if (haveEvent) {
XPutBackEvent(display, &ev);
}
}
#else
haveEvent = false;
@ -2598,23 +2600,26 @@ nsWindow::OnMotionNotifyEvent(GdkEventMotion *aEvent)
#ifdef MOZ_X11
XEvent xevent;
while (XPending (GDK_WINDOW_XDISPLAY(aEvent->window))) {
XEvent peeked;
XPeekEvent (GDK_WINDOW_XDISPLAY(aEvent->window), &peeked);
if (peeked.xany.window != gdk_x11_window_get_xid(aEvent->window)
|| peeked.type != MotionNotify)
break;
bool isX11Display = GDK_IS_X11_DISPLAY(gdk_display_get_default());
if (isX11Display) {
while (XPending (GDK_WINDOW_XDISPLAY(aEvent->window))) {
XEvent peeked;
XPeekEvent (GDK_WINDOW_XDISPLAY(aEvent->window), &peeked);
if (peeked.xany.window != gdk_x11_window_get_xid(aEvent->window)
|| peeked.type != MotionNotify)
break;
synthEvent = true;
XNextEvent (GDK_WINDOW_XDISPLAY(aEvent->window), &xevent);
}
synthEvent = true;
XNextEvent (GDK_WINDOW_XDISPLAY(aEvent->window), &xevent);
}
#if (MOZ_WIDGET_GTK == 2)
// if plugins still keeps the focus, get it back
if (gPluginFocusWindow && gPluginFocusWindow != this) {
nsRefPtr<nsWindow> kungFuDeathGrip = gPluginFocusWindow;
gPluginFocusWindow->LoseNonXEmbedPluginFocus();
}
// if plugins still keeps the focus, get it back
if (gPluginFocusWindow && gPluginFocusWindow != this) {
nsRefPtr<nsWindow> kungFuDeathGrip = gPluginFocusWindow;
gPluginFocusWindow->LoseNonXEmbedPluginFocus();
}
#endif /* MOZ_WIDGET_GTK2 */
}
#endif /* MOZ_X11 */
WidgetMouseEvent event(true, NS_MOUSE_MOVE, this, WidgetMouseEvent::eReal);
@ -3928,20 +3933,23 @@ nsWindow::SetWindowClass(const nsAString &xulWinType)
gdk_window_set_role(shellWindow, role);
#ifdef MOZ_X11
XClassHint *class_hint = XAllocClassHint();
if (!class_hint) {
nsMemory::Free(res_name);
return NS_ERROR_OUT_OF_MEMORY;
}
class_hint->res_name = res_name;
class_hint->res_class = const_cast<char*>(res_class);
GdkDisplay *display = gdk_display_get_default();
if (GDK_IS_X11_DISPLAY(display)) {
XClassHint *class_hint = XAllocClassHint();
if (!class_hint) {
nsMemory::Free(res_name);
return NS_ERROR_OUT_OF_MEMORY;
}
class_hint->res_name = res_name;
class_hint->res_class = const_cast<char*>(res_class);
// Can't use gtk_window_set_wmclass() for this; it prints
// a warning & refuses to make the change.
XSetClassHint(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()),
gdk_x11_window_get_xid(shellWindow),
class_hint);
XFree(class_hint);
// Can't use gtk_window_set_wmclass() for this; it prints
// a warning & refuses to make the change.
XSetClassHint(GDK_DISPLAY_XDISPLAY(display),
gdk_x11_window_get_xid(shellWindow),
class_hint);
XFree(class_hint);
}
#endif /* MOZ_X11 */
nsMemory::Free(res_name);
@ -5658,20 +5666,22 @@ key_press_event_cb(GtkWidget *widget, GdkEventKey *event)
// are generated only when the key is physically released.
#define NS_GDKEVENT_MATCH_MASK 0x1FFF /* GDK_SHIFT_MASK .. GDK_BUTTON5_MASK */
GdkDisplay* gdkDisplay = gtk_widget_get_display(widget);
Display* dpy = GDK_DISPLAY_XDISPLAY(gdkDisplay);
while (XPending(dpy)) {
XEvent next_event;
XPeekEvent(dpy, &next_event);
GdkWindow* nextGdkWindow =
gdk_x11_window_lookup_for_display(gdkDisplay, next_event.xany.window);
if (nextGdkWindow != event->window ||
next_event.type != KeyPress ||
next_event.xkey.keycode != event->hardware_keycode ||
next_event.xkey.state != (event->state & NS_GDKEVENT_MATCH_MASK)) {
break;
if (GDK_IS_X11_DISPLAY(gdkDisplay)) {
Display* dpy = GDK_DISPLAY_XDISPLAY(gdkDisplay);
while (XPending(dpy)) {
XEvent next_event;
XPeekEvent(dpy, &next_event);
GdkWindow* nextGdkWindow =
gdk_x11_window_lookup_for_display(gdkDisplay, next_event.xany.window);
if (nextGdkWindow != event->window ||
next_event.type != KeyPress ||
next_event.xkey.keycode != event->hardware_keycode ||
next_event.xkey.state != (event->state & NS_GDKEVENT_MATCH_MASK)) {
break;
}
XNextEvent(dpy, &next_event);
event->time = next_event.xkey.time;
}
XNextEvent(dpy, &next_event);
event->time = next_event.xkey.time;
}
#endif