diff options
Diffstat (limited to 'xorg-server/hw')
41 files changed, 2728 insertions, 77 deletions
diff --git a/xorg-server/hw/Makefile.am b/xorg-server/hw/Makefile.am index 6c2cc6bd4..19895dc77 100644 --- a/xorg-server/hw/Makefile.am +++ b/xorg-server/hw/Makefile.am @@ -26,6 +26,10 @@ if XQUARTZ XQUARTZ_SUBDIRS = xquartz endif +if XWAYLAND +XWAYLAND_SUBDIRS = xwayland +endif + SUBDIRS = \ $(XORG_SUBDIRS) \ $(XWIN_SUBDIRS) \ @@ -33,9 +37,10 @@ SUBDIRS = \ $(XNEST_SUBDIRS) \ $(DMX_SUBDIRS) \ $(KDRIVE_SUBDIRS) \ - $(XQUARTZ_SUBDIRS) + $(XQUARTZ_SUBDIRS) \ + $(XWAYLAND_SUBDIRS) -DIST_SUBDIRS = dmx xfree86 vfb xnest xwin xquartz kdrive +DIST_SUBDIRS = dmx xfree86 vfb xnest xwin xquartz kdrive xwayland relink: $(AM_V_at)for i in $(SUBDIRS) ; do $(MAKE) -C $$i relink || exit 1 ; done diff --git a/xorg-server/hw/dmx/Makefile.am b/xorg-server/hw/dmx/Makefile.am index a05af139e..eef84cb66 100644 --- a/xorg-server/hw/dmx/Makefile.am +++ b/xorg-server/hw/dmx/Makefile.am @@ -65,7 +65,6 @@ Xdmx_SOURCES = dmx.c \ dmxwindow.c \ dmxwindow.h \ $(top_srcdir)/mi/miinitext.c \ - $(top_srcdir)/fb/fbcmap_mi.c \ $(GLX_SRCS) diff --git a/xorg-server/hw/kdrive/ephyr/ephyr_glamor_glx.c b/xorg-server/hw/kdrive/ephyr/ephyr_glamor_glx.c index 9903cc772..eaf565496 100644 --- a/xorg-server/hw/kdrive/ephyr/ephyr_glamor_glx.c +++ b/xorg-server/hw/kdrive/ephyr/ephyr_glamor_glx.c @@ -313,7 +313,6 @@ ephyr_glamor_get_visual(void) GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, GLX_DOUBLEBUFFER, 1, - GLX_VISUAL_ID, DefaultVisual(dpy, DefaultScreen(dpy)), None }; int event_base = 0, error_base = 0, nelements; diff --git a/xorg-server/hw/kdrive/ephyr/hostx.c b/xorg-server/hw/kdrive/ephyr/hostx.c index 4f48770a6..435919e0a 100644 --- a/xorg-server/hw/kdrive/ephyr/hostx.c +++ b/xorg-server/hw/kdrive/ephyr/hostx.c @@ -734,13 +734,16 @@ hostx_screen_init(KdScreenInfo *screen, scrpriv->win_width = width; scrpriv->win_height = height; +#ifdef GLAMOR if (ephyr_glamor) { *bytes_per_line = 0; *bits_per_pixel = 0; ephyr_glamor_set_window_size(scrpriv->glamor, scrpriv->win_width, scrpriv->win_height); return NULL; - } else if (host_depth_matches_server(scrpriv)) { + } else +#endif + if (host_depth_matches_server(scrpriv)) { *bytes_per_line = scrpriv->ximg->stride; *bits_per_pixel = scrpriv->ximg->bpp; diff --git a/xorg-server/hw/kdrive/src/Makefile.am b/xorg-server/hw/kdrive/src/Makefile.am index 5799ddbdb..d69f0dd99 100644 --- a/xorg-server/hw/kdrive/src/Makefile.am +++ b/xorg-server/hw/kdrive/src/Makefile.am @@ -4,7 +4,7 @@ AM_CPPFLAGS = \ AM_CFLAGS = -DHAVE_DIX_CONFIG_H -noinst_LTLIBRARIES = libkdrive.la libkdrivestubs.la +noinst_LTLIBRARIES = libkdrive.la if XV KDRIVE_XV_SOURCES = \ @@ -23,6 +23,3 @@ libkdrive_la_SOURCES = \ kshadow.c \ $(KDRIVE_XV_SOURCES) \ $(top_srcdir)/mi/miinitext.c - -libkdrivestubs_la_SOURCES = \ - $(top_srcdir)/fb/fbcmap_mi.c diff --git a/xorg-server/hw/vfb/Makefile.am b/xorg-server/hw/vfb/Makefile.am index 9f4992c8b..f0f9fee47 100644 --- a/xorg-server/hw/vfb/Makefile.am +++ b/xorg-server/hw/vfb/Makefile.am @@ -1,7 +1,6 @@ SUBDIRS = man bin_PROGRAMS = Xvfb -noinst_LIBRARIES = libfbcmap.a AM_CFLAGS = -DHAVE_DIX_CONFIG_H \ $(XVFBMODULES_CFLAGS) \ @@ -9,20 +8,16 @@ AM_CFLAGS = -DHAVE_DIX_CONFIG_H \ SRCS = InitInput.c \ InitOutput.c \ - $(top_srcdir)/Xext/dpmsstubs.c \ - $(top_srcdir)/Xi/stubs.c \ $(top_srcdir)/mi/miinitext.c -libfbcmap_a_CFLAGS = $(AM_CFLAGS) -libfbcmap_a_SOURCES = $(top_srcdir)/fb/fbcmap_mi.c - Xvfb_SOURCES = $(SRCS) XVFB_LIBS = \ @XVFB_LIBS@ \ - libfbcmap.a \ $(MAIN_LIB) \ - $(XSERVER_LIBS) + $(XSERVER_LIBS) \ + $(top_builddir)/Xext/libXextdpmsstubs.la \ + $(top_builddir)/Xi/libXistubs.la Xvfb_LDADD = $(XVFB_LIBS) $(XVFB_SYS_LIBS) $(XSERVER_SYS_LIBS) Xvfb_DEPENDENCIES = $(XVFB_LIBS) diff --git a/xorg-server/hw/xfree86/.gitignore b/xorg-server/hw/xfree86/.gitignore index 997a94efe..fb6830b2c 100644 --- a/xorg-server/hw/xfree86/.gitignore +++ b/xorg-server/hw/xfree86/.gitignore @@ -1,4 +1,5 @@ Xorg +Xorg.sh xorg.conf.example sdksyms.c sdksyms.dep diff --git a/xorg-server/hw/xfree86/Makefile.am b/xorg-server/hw/xfree86/Makefile.am index 18fa99b08..c5992c372 100644 --- a/xorg-server/hw/xfree86/Makefile.am +++ b/xorg-server/hw/xfree86/Makefile.am @@ -89,7 +89,7 @@ endif BUILT_SOURCES = xorg.conf.example DISTCLEANFILES = xorg.conf.example -EXTRA_DIST = xorgconf.cpp Xorg.sh.in +EXTRA_DIST = xorgconf.cpp # Without logdir, X will post an error on the terminal and will not start install-data-local: @@ -105,6 +105,7 @@ if INSTALL_SETUID chmod u+s $(DESTDIR)$(bindir)/Xorg endif if SUID_WRAPPER + $(MKDIR_P) $(DESTDIR)$(SUID_WRAPPER_DIR) mv $(DESTDIR)$(bindir)/Xorg $(DESTDIR)$(SUID_WRAPPER_DIR)/Xorg.bin ${INSTALL} -m 755 Xorg.sh $(DESTDIR)$(bindir)/Xorg -chown root $(DESTDIR)$(SUID_WRAPPER_DIR)/Xorg.wrap && chmod u+s $(DESTDIR)$(SUID_WRAPPER_DIR)/Xorg.wrap diff --git a/xorg-server/hw/xfree86/common/xf86Events.c b/xorg-server/hw/xfree86/common/xf86Events.c index 06af73903..35a673d15 100644 --- a/xorg-server/hw/xfree86/common/xf86Events.c +++ b/xorg-server/hw/xfree86/common/xf86Events.c @@ -56,6 +56,7 @@ #include <X11/X.h> #include <X11/Xpoll.h> #include <X11/Xproto.h> +#include <X11/Xatom.h> #include "misc.h" #include "compiler.h" #include "xf86.h" @@ -431,6 +432,29 @@ xf86EnableInputDeviceForVTSwitch(InputInfoPtr pInfo) pInfo->flags &= ~XI86_DEVICE_DISABLED; } +/* + * xf86UpdateHasVTProperty -- + * Update a flag property on the root window to say whether the server VT + * is currently the active one as some clients need to know this. + */ +static void +xf86UpdateHasVTProperty(Bool hasVT) +{ + Atom property_name; + int32_t value = hasVT ? 1 : 0; + int i; + + property_name = MakeAtom(HAS_VT_ATOM_NAME, sizeof(HAS_VT_ATOM_NAME) - 1, + FALSE); + if (property_name == BAD_RESOURCE) + FatalError("Failed to retrieve \"HAS_VT\" atom\n"); + for (i = 0; i < xf86NumScreens; i++) { + ChangeWindowProperty(xf86ScrnToScreen(xf86Screens[i])->root, + property_name, XA_INTEGER, 32, + PropModeReplace, 1, &value, TRUE); + } +} + void xf86VTLeave(void) { @@ -490,6 +514,8 @@ xf86VTLeave(void) if (xorgHWAccess) xf86DisableIO(); + xf86UpdateHasVTProperty(FALSE); + return; switch_failed: @@ -574,6 +600,8 @@ xf86VTEnter(void) xf86platformVTProbe(); #endif + xf86UpdateHasVTProperty(TRUE); + OsReleaseSIGIO(); } diff --git a/xorg-server/hw/xfree86/common/xf86Globals.c b/xorg-server/hw/xfree86/common/xf86Globals.c index 7df7a80c4..984c39bca 100644 --- a/xorg-server/hw/xfree86/common/xf86Globals.c +++ b/xorg-server/hw/xfree86/common/xf86Globals.c @@ -143,7 +143,7 @@ const char *xf86ConfigFile = NULL; const char *xf86ConfigDir = NULL; const char *xf86ModulePath = DEFAULT_MODULE_PATH; MessageType xf86ModPathFrom = X_DEFAULT; -const char *xf86LogFile = DEFAULT_LOGPREFIX; +const char *xf86LogFile = DEFAULT_LOGDIR "/" DEFAULT_LOGPREFIX; MessageType xf86LogFileFrom = X_DEFAULT; Bool xf86LogFileWasOpened = FALSE; serverLayoutRec xf86ConfigLayout = { NULL, }; diff --git a/xorg-server/hw/xfree86/common/xf86Helper.c b/xorg-server/hw/xfree86/common/xf86Helper.c index 12a877159..e2b32a074 100644 --- a/xorg-server/hw/xfree86/common/xf86Helper.c +++ b/xorg-server/hw/xfree86/common/xf86Helper.c @@ -1217,16 +1217,45 @@ xf86ErrorF(const char *format, ...) va_end(ap); } +/* Note temporarily modifies the passed in buffer! */ +static void xf86_mkdir_p(char *path) +{ + char *sep = path; + + while ((sep = strchr(sep + 1, '/'))) { + *sep = 0; + (void)mkdir(path, 0777); + *sep = '/'; + } + (void)mkdir(path, 0777); +} + void xf86LogInit(void) { - char *lf = NULL; + char *env, *lf = NULL; + char buf[PATH_MAX]; #define LOGSUFFIX ".log" #define LOGOLDSUFFIX ".old" /* Get the log file name */ if (xf86LogFileFrom == X_DEFAULT) { + /* When not running as root, we won't be able to write to /var/log */ + if (geteuid() != 0) { + if ((env = getenv("XDG_DATA_HOME"))) + snprintf(buf, sizeof(buf), "%s/%s", env, + DEFAULT_XDG_DATA_HOME_LOGDIR); + else if ((env = getenv("HOME"))) + snprintf(buf, sizeof(buf), "%s/%s/%s", env, + DEFAULT_XDG_DATA_HOME, DEFAULT_XDG_DATA_HOME_LOGDIR); + + if (env) { + xf86_mkdir_p(buf); + strlcat(buf, "/" DEFAULT_LOGPREFIX, sizeof(buf)); + xf86LogFile = buf; + } + } /* Append the display number and ".log" */ if (asprintf(&lf, "%s%%s" LOGSUFFIX, xf86LogFile) == -1) FatalError("Cannot allocate space for the log file name\n"); diff --git a/xorg-server/hw/xfree86/common/xf86Init.c b/xorg-server/hw/xfree86/common/xf86Init.c index 4579ff591..5a45004f5 100644 --- a/xorg-server/hw/xfree86/common/xf86Init.c +++ b/xorg-server/hw/xfree86/common/xf86Init.c @@ -387,6 +387,11 @@ InstallSignalHandlers(void) } } +/* The memory storing the initial value of the XFree86_has_VT root window + * property. This has to remain available until server start-up, so we just + * use a global. */ +static CARD32 HasVTValue = 1; + /* * InitOutput -- * Initialize screenInfo for all actually accessible framebuffers. @@ -731,7 +736,9 @@ InitOutput(ScreenInfo * pScreenInfo, int argc, char **argv) if (xf86Info.vtno >= 0) { #define VT_ATOM_NAME "XFree86_VT" Atom VTAtom = -1; + Atom HasVTAtom = -1; CARD32 *VT = NULL; + CARD32 *HasVT = &HasVTValue; int ret; /* This memory needs to stay available until the screen has been @@ -744,6 +751,8 @@ InitOutput(ScreenInfo * pScreenInfo, int argc, char **argv) *VT = xf86Info.vtno; VTAtom = MakeAtom(VT_ATOM_NAME, sizeof(VT_ATOM_NAME) - 1, TRUE); + HasVTAtom = MakeAtom(HAS_VT_ATOM_NAME, + sizeof(HAS_VT_ATOM_NAME) - 1, TRUE); for (i = 0, ret = Success; i < xf86NumScreens && ret == Success; i++) { @@ -751,9 +760,14 @@ InitOutput(ScreenInfo * pScreenInfo, int argc, char **argv) xf86RegisterRootWindowProperty(xf86Screens[i]->scrnIndex, VTAtom, XA_INTEGER, 32, 1, VT); + if (ret == Success) + ret = xf86RegisterRootWindowProperty(xf86Screens[i] + ->scrnIndex, + HasVTAtom, XA_INTEGER, + 32, 1, HasVT); if (ret != Success) xf86DrvMsg(xf86Screens[i]->scrnIndex, X_WARNING, - "Failed to register VT property\n"); + "Failed to register VT properties\n"); } } diff --git a/xorg-server/hw/xfree86/common/xf86Module.h b/xorg-server/hw/xfree86/common/xf86Module.h index e8c24f26c..62ac95d5a 100644 --- a/xorg-server/hw/xfree86/common/xf86Module.h +++ b/xorg-server/hw/xfree86/common/xf86Module.h @@ -80,7 +80,7 @@ typedef enum { * mask is 0xFFFF0000. */ #define ABI_ANSIC_VERSION SET_ABI_VERSION(0, 4) -#define ABI_VIDEODRV_VERSION SET_ABI_VERSION(16, 0) +#define ABI_VIDEODRV_VERSION SET_ABI_VERSION(17, 0) #define ABI_XINPUT_VERSION SET_ABI_VERSION(21, 0) #define ABI_EXTENSION_VERSION SET_ABI_VERSION(8, 0) #define ABI_FONT_VERSION SET_ABI_VERSION(0, 6) diff --git a/xorg-server/hw/xfree86/common/xf86Privstr.h b/xorg-server/hw/xfree86/common/xf86Privstr.h index f7a9c9f1c..410ef17ac 100644 --- a/xorg-server/hw/xfree86/common/xf86Privstr.h +++ b/xorg-server/hw/xfree86/common/xf86Privstr.h @@ -163,4 +163,8 @@ typedef struct _RootWinProp { #define WSCONS 32 #endif +/* Root window property to tell clients whether our VT is currently active. + * Name chosen to match the "XFree86_VT" property. */ +#define HAS_VT_ATOM_NAME "XFree86_has_VT" + #endif /* _XF86PRIVSTR_H */ diff --git a/xorg-server/hw/xfree86/dixmods/Makefile.am b/xorg-server/hw/xfree86/dixmods/Makefile.am index 3c43640ec..dd076e421 100644 --- a/xorg-server/hw/xfree86/dixmods/Makefile.am +++ b/xorg-server/hw/xfree86/dixmods/Makefile.am @@ -19,12 +19,12 @@ AM_CPPFLAGS = @XORG_INCS@ \ libfb_la_LDFLAGS = -module -avoid-version $(LD_NO_UNDEFINED_FLAG) libfb_la_LIBADD = $(top_builddir)/fb/libfb.la -libfb_la_SOURCES = $(top_builddir)/fb/fbcmap_mi.c fbmodule.c +libfb_la_SOURCES = fbmodule.c libfb_la_CFLAGS = $(AM_CFLAGS) libwfb_la_LDFLAGS = -module -avoid-version $(LD_NO_UNDEFINED_FLAG) libwfb_la_LIBADD = $(top_builddir)/fb/libwfb.la -libwfb_la_SOURCES = $(top_builddir)/fb/fbcmap_mi.c fbmodule.c +libwfb_la_SOURCES = fbmodule.c libwfb_la_CFLAGS = $(AM_CFLAGS) -DFB_ACCESS_WRAPPER libglx_la_LDFLAGS = -module -avoid-version $(LD_NO_UNDEFINED_FLAG) diff --git a/xorg-server/hw/xfree86/man/Xorg.man b/xorg-server/hw/xfree86/man/Xorg.man index 0cd5a1068..3ff6aef89 100644 --- a/xorg-server/hw/xfree86/man/Xorg.man +++ b/xorg-server/hw/xfree86/man/Xorg.man @@ -301,9 +301,11 @@ Use the file called .I filename as the .B Xorg -server log file. The default log file is +server log file. The default log file when running as root is .BI __logdir__/Xorg. n .log -on most platforms, where +and for non root it is +.BI $XDG_DATA_HOME/xorg/Xorg. n .log +where .I n is the display number of the .B Xorg diff --git a/xorg-server/hw/xfree86/man/xorg.conf.man b/xorg-server/hw/xfree86/man/xorg.conf.man index 85f9f2ee1..6d2652e84 100644 --- a/xorg-server/hw/xfree86/man/xorg.conf.man +++ b/xorg-server/hw/xfree86/man/xorg.conf.man @@ -442,11 +442,15 @@ __modulepath__ .TP 7 .BI "LogFile \*q" path \*q sets the name of the Xorg server log file. -The default log file name is +The default log file name when running as root is .PP .RS 11 .RI __logdir__/Xorg. <n> .log .RE +and for non root it is +.RS 11 +.RI $XDG_DATA_HOME/xorg/Xorg. <n> .log +.RE .PP .RS 7 where diff --git a/xorg-server/hw/xfree86/modes/xf86Crtc.h b/xorg-server/hw/xfree86/modes/xf86Crtc.h index c127d78af..5407deb0e 100644 --- a/xorg-server/hw/xfree86/modes/xf86Crtc.h +++ b/xorg-server/hw/xfree86/modes/xf86Crtc.h @@ -186,13 +186,13 @@ typedef struct _xf86CrtcFuncs { /** * Load monochrome image */ - void + Bool (*load_cursor_image) (xf86CrtcPtr crtc, CARD8 *image); /** * Load ARGB image */ - void + Bool (*load_cursor_argb) (xf86CrtcPtr crtc, CARD32 *image); /** diff --git a/xorg-server/hw/xfree86/modes/xf86Cursors.c b/xorg-server/hw/xfree86/modes/xf86Cursors.c index 2b0db3492..10ef6f6d4 100644 --- a/xorg-server/hw/xfree86/modes/xf86Cursors.c +++ b/xorg-server/hw/xfree86/modes/xf86Cursors.c @@ -211,7 +211,7 @@ set_bit(CARD8 *image, xf86CursorInfoPtr cursor_info, int x, int y, Bool mask) /* * Load a two color cursor into a driver that supports only ARGB cursors */ -static void +static Bool xf86_crtc_convert_cursor_to_argb(xf86CrtcPtr crtc, unsigned char *src) { ScrnInfoPtr scrn = crtc->scrn; @@ -244,7 +244,7 @@ xf86_crtc_convert_cursor_to_argb(xf86CrtcPtr crtc, unsigned char *src) bits = 0; cursor_image[y * cursor_info->MaxWidth + x] = bits; } - crtc->funcs->load_cursor_argb(crtc, cursor_image); + return crtc->funcs->load_cursor_argb(crtc, cursor_image); } /* @@ -415,7 +415,7 @@ xf86_set_cursor_position(ScrnInfoPtr scrn, int x, int y) /* * Load a two-color cursor into a crtc, performing rotation as needed */ -static void +static Bool xf86_crtc_load_cursor_image(xf86CrtcPtr crtc, CARD8 *src) { ScrnInfoPtr scrn = crtc->scrn; @@ -450,13 +450,13 @@ xf86_crtc_load_cursor_image(xf86CrtcPtr crtc, CARD8 *src) set_bit(cursor_image, cursor_info, x, y, TRUE); } } - crtc->funcs->load_cursor_image(crtc, cursor_image); + return crtc->funcs->load_cursor_image(crtc, cursor_image); } /* * Load a cursor image into all active CRTCs */ -static void +static Bool xf86_load_cursor_image(ScrnInfoPtr scrn, unsigned char *src) { xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); @@ -466,12 +466,17 @@ xf86_load_cursor_image(ScrnInfoPtr scrn, unsigned char *src) xf86CrtcPtr crtc = xf86_config->crtc[c]; if (crtc->enabled) { - if (crtc->funcs->load_cursor_image) - xf86_crtc_load_cursor_image(crtc, src); - else if (crtc->funcs->load_cursor_argb) - xf86_crtc_convert_cursor_to_argb(crtc, src); + if (crtc->funcs->load_cursor_image) { + if (!xf86_crtc_load_cursor_image(crtc, src)) + return FALSE; + } else if (crtc->funcs->load_cursor_argb) { + if (!xf86_crtc_convert_cursor_to_argb(crtc, src)) + return FALSE; + } else + return FALSE; } } + return TRUE; } static Bool @@ -516,7 +521,7 @@ xf86_use_hw_cursor_argb(ScreenPtr screen, CursorPtr cursor) return TRUE; } -static void +static Bool xf86_crtc_load_cursor_argb(xf86CrtcPtr crtc, CursorPtr cursor) { ScrnInfoPtr scrn = crtc->scrn; @@ -544,10 +549,10 @@ xf86_crtc_load_cursor_argb(xf86CrtcPtr crtc, CursorPtr cursor) cursor_image[y * image_width + x] = bits; } - crtc->funcs->load_cursor_argb(crtc, cursor_image); + return crtc->funcs->load_cursor_argb(crtc, cursor_image); } -static void +static Bool xf86_load_cursor_argb(ScrnInfoPtr scrn, CursorPtr cursor) { xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); @@ -557,8 +562,10 @@ xf86_load_cursor_argb(ScrnInfoPtr scrn, CursorPtr cursor) xf86CrtcPtr crtc = xf86_config->crtc[c]; if (crtc->enabled) - xf86_crtc_load_cursor_argb(crtc, cursor); + if (!xf86_crtc_load_cursor_argb(crtc, cursor)) + return FALSE; } + return TRUE; } Bool @@ -608,6 +615,8 @@ xf86_cursors_init(ScreenPtr screen, int max_width, int max_height, int flags) * Called when anything on the screen is reconfigured. * * Reloads cursor images as needed, then adjusts cursor positions + * @note We assume that all hardware cursors to be loaded have already been + * found to be usable by the hardware. */ void diff --git a/xorg-server/hw/xfree86/os-support/linux/systemd-logind.c b/xorg-server/hw/xfree86/os-support/linux/systemd-logind.c index 62858b062..ed670a88c 100644 --- a/xorg-server/hw/xfree86/os-support/linux/systemd-logind.c +++ b/xorg-server/hw/xfree86/os-support/linux/systemd-logind.c @@ -310,10 +310,31 @@ message_filter(DBusConnection * connection, DBusMessage * message, void *data) dbus_int32_t major, minor; char *pause_str; - if (strcmp(dbus_message_get_path(message), info->session) != 0) + dbus_error_init(&error); + + if (dbus_message_is_signal(message, + "org.freedesktop.DBus", "NameOwnerChanged")) { + char *name, *old_owner, *new_owner; + + dbus_message_get_args(message, &error, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_STRING, &old_owner, + DBUS_TYPE_STRING, &new_owner, DBUS_TYPE_INVALID); + if (dbus_error_is_set(&error)) { + LogMessage(X_ERROR, "systemd-logind: NameOwnerChanged: %s\n", + error.message); + dbus_error_free(&error); + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } + + if (name && strcmp(name, "org.freedesktop.login1") == 0) + FatalError("systemd-logind disappeared (stopped/restarted?)\n"); + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } - dbus_error_init(&error); + if (strcmp(dbus_message_get_path(message), info->session) != 0) + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; if (dbus_message_is_signal(message, "org.freedesktop.login1.Session", "PauseDevice")) { @@ -472,6 +493,15 @@ connect_hook(DBusConnection *connection, void *data) goto cleanup; } + dbus_bus_add_match(connection, + "type='signal',sender='org.freedesktop.DBus',interface='org.freedesktop.DBus',member='NameOwnerChanged',path='/org/freedesktop/DBus'", + &error); + if (dbus_error_is_set(&error)) { + LogMessage(X_ERROR, "systemd-logind: could not add match: %s\n", + error.message); + goto cleanup; + } + /* * HdG: This is not useful with systemd <= 208 since the signal only * contains invalidated property names there, rather than property, val diff --git a/xorg-server/hw/xfree86/parser/DRI.c b/xorg-server/hw/xfree86/parser/DRI.c index ad053f746..6be32d7ea 100644 --- a/xorg-server/hw/xfree86/parser/DRI.c +++ b/xorg-server/hw/xfree86/parser/DRI.c @@ -31,6 +31,7 @@ #include <xorg-config.h> #endif +#include "os.h" #include "xf86Parser.h" #include "xf86tokens.h" #include "Configint.h" diff --git a/xorg-server/hw/xfree86/parser/Extensions.c b/xorg-server/hw/xfree86/parser/Extensions.c index b5ba72e5f..a6fcb56f0 100644 --- a/xorg-server/hw/xfree86/parser/Extensions.c +++ b/xorg-server/hw/xfree86/parser/Extensions.c @@ -35,6 +35,7 @@ #include <xorg-config.h> #endif +#include "os.h" #include "xf86Parser.h" #include "xf86tokens.h" #include "Configint.h" diff --git a/xorg-server/hw/xfree86/ramdac/IBM.c b/xorg-server/hw/xfree86/ramdac/IBM.c index bc716231a..872d3d4e7 100644 --- a/xorg-server/hw/xfree86/ramdac/IBM.c +++ b/xorg-server/hw/xfree86/ramdac/IBM.c @@ -570,7 +570,7 @@ IBMramdac640SetCursorColors(ScrnInfoPtr pScrn, int bg, int fg) (*ramdacPtr->WriteData) (pScrn, bg); } -static void +static Bool IBMramdac526LoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src) { RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn); @@ -582,9 +582,10 @@ IBMramdac526LoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src) */ for (i = 0; i < 1024; i++) (*ramdacPtr->WriteDAC) (pScrn, IBMRGB_curs_array + i, 0x00, (*src++)); + return TRUE; } -static void +static Bool IBMramdac640LoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src) { RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn); @@ -596,6 +597,7 @@ IBMramdac640LoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src) */ for (i = 0; i < 1024; i++) (*ramdacPtr->WriteDAC) (pScrn, RGB640_CURS_WRITE + i, 0x00, (*src++)); + return TRUE; } static Bool diff --git a/xorg-server/hw/xfree86/ramdac/TI.c b/xorg-server/hw/xfree86/ramdac/TI.c index 393b774d4..7d4e0d796 100644 --- a/xorg-server/hw/xfree86/ramdac/TI.c +++ b/xorg-server/hw/xfree86/ramdac/TI.c @@ -642,7 +642,7 @@ TIramdacSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg) (*ramdacPtr->WriteDAC) (pScrn, TIDAC_CURS_COLOR, 0, (fg & 0x000000ff)); } -static void +static Bool TIramdacLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src) { RamDacRecPtr ramdacPtr = RAMDACSCRPTR(pScrn); @@ -657,6 +657,7 @@ TIramdacLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src) /* NOT_DONE: might need a delay here */ (*ramdacPtr->WriteDAC) (pScrn, TIDAC_CURS_RAM_DATA, 0, *(src++)); } + return TRUE; } static Bool diff --git a/xorg-server/hw/xfree86/ramdac/xf86Cursor.c b/xorg-server/hw/xfree86/ramdac/xf86Cursor.c index 860704e1c..fac682210 100644 --- a/xorg-server/hw/xfree86/ramdac/xf86Cursor.c +++ b/xorg-server/hw/xfree86/ramdac/xf86Cursor.c @@ -352,12 +352,13 @@ xf86CursorSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCurs, (*ScreenPriv->spriteFuncs->SetCursor) (pDev, pScreen, NullCursor, x, y); - xf86SetCursor(pScreen, cursor, x, y); - ScreenPriv->SWCursor = FALSE; - ScreenPriv->isUp = TRUE; + if (xf86SetCursor(pScreen, cursor, x, y)) { + ScreenPriv->SWCursor = FALSE; + ScreenPriv->isUp = TRUE; - miPointerSetWaitForUpdate(pScreen, !infoPtr->pScrn->silkenMouse); - return; + miPointerSetWaitForUpdate(pScreen, !infoPtr->pScrn->silkenMouse); + return; + } } miPointerSetWaitForUpdate(pScreen, TRUE); diff --git a/xorg-server/hw/xfree86/ramdac/xf86Cursor.h b/xorg-server/hw/xfree86/ramdac/xf86Cursor.h index 5658e7b30..1ecbdcd8d 100644 --- a/xorg-server/hw/xfree86/ramdac/xf86Cursor.h +++ b/xorg-server/hw/xfree86/ramdac/xf86Cursor.h @@ -12,7 +12,7 @@ typedef struct _xf86CursorInfoRec { int MaxHeight; void (*SetCursorColors) (ScrnInfoPtr pScrn, int bg, int fg); void (*SetCursorPosition) (ScrnInfoPtr pScrn, int x, int y); - void (*LoadCursorImage) (ScrnInfoPtr pScrn, unsigned char *bits); + Bool (*LoadCursorImage) (ScrnInfoPtr pScrn, unsigned char *bits); void (*HideCursor) (ScrnInfoPtr pScrn); void (*ShowCursor) (ScrnInfoPtr pScrn); unsigned char *(*RealizeCursor) (struct _xf86CursorInfoRec *, CursorPtr); @@ -20,7 +20,7 @@ typedef struct _xf86CursorInfoRec { #ifdef ARGB_CURSOR Bool (*UseHWCursorARGB) (ScreenPtr, CursorPtr); - void (*LoadCursorARGB) (ScrnInfoPtr, CursorPtr); + Bool (*LoadCursorARGB) (ScrnInfoPtr, CursorPtr); #endif } xf86CursorInfoRec, *xf86CursorInfoPtr; diff --git a/xorg-server/hw/xfree86/ramdac/xf86CursorPriv.h b/xorg-server/hw/xfree86/ramdac/xf86CursorPriv.h index a5d2aabc3..f34c1c7fc 100644 --- a/xorg-server/hw/xfree86/ramdac/xf86CursorPriv.h +++ b/xorg-server/hw/xfree86/ramdac/xf86CursorPriv.h @@ -37,7 +37,7 @@ typedef struct { void *transparentData; } xf86CursorScreenRec, *xf86CursorScreenPtr; -void xf86SetCursor(ScreenPtr pScreen, CursorPtr pCurs, int x, int y); +Bool xf86SetCursor(ScreenPtr pScreen, CursorPtr pCurs, int x, int y); void xf86SetTransparentCursor(ScreenPtr pScreen); void xf86MoveCursor(ScreenPtr pScreen, int x, int y); void xf86RecolorCursor(ScreenPtr pScreen, CursorPtr pCurs, Bool displayed); diff --git a/xorg-server/hw/xfree86/ramdac/xf86HWCurs.c b/xorg-server/hw/xfree86/ramdac/xf86HWCurs.c index 3b69698db..0b5caa20a 100644 --- a/xorg-server/hw/xfree86/ramdac/xf86HWCurs.c +++ b/xorg-server/hw/xfree86/ramdac/xf86HWCurs.c @@ -119,7 +119,7 @@ xf86InitHardwareCursor(ScreenPtr pScreen, xf86CursorInfoPtr infoPtr) return TRUE; } -void +Bool xf86SetCursor(ScreenPtr pScreen, CursorPtr pCurs, int x, int y) { xf86CursorScreenPtr ScreenPriv = @@ -130,7 +130,7 @@ xf86SetCursor(ScreenPtr pScreen, CursorPtr pCurs, int x, int y) if (pCurs == NullCursor) { (*infoPtr->HideCursor) (infoPtr->pScrn); - return; + return TRUE; } bits = @@ -152,18 +152,21 @@ xf86SetCursor(ScreenPtr pScreen, CursorPtr pCurs, int x, int y) (*infoPtr->HideCursor) (infoPtr->pScrn); #ifdef ARGB_CURSOR - if (pCurs->bits->argb && infoPtr->LoadCursorARGB) - (*infoPtr->LoadCursorARGB) (infoPtr->pScrn, pCurs); - else + if (pCurs->bits->argb && infoPtr->LoadCursorARGB) { + if (!(*infoPtr->LoadCursorARGB) (infoPtr->pScrn, pCurs)) + return FALSE; + } else #endif if (bits) - (*infoPtr->LoadCursorImage) (infoPtr->pScrn, bits); + if (!(*infoPtr->LoadCursorImage) (infoPtr->pScrn, bits)) + return FALSE; xf86RecolorCursor(pScreen, pCurs, 1); (*infoPtr->SetCursorPosition) (infoPtr->pScrn, x, y); (*infoPtr->ShowCursor) (infoPtr->pScrn); + return TRUE; } void diff --git a/xorg-server/hw/xnest/Makefile.am b/xorg-server/hw/xnest/Makefile.am index 3c099cd6b..eb550c0f7 100644 --- a/xorg-server/hw/xnest/Makefile.am +++ b/xorg-server/hw/xnest/Makefile.am @@ -1,7 +1,6 @@ SUBDIRS = man bin_PROGRAMS = Xnest -noinst_LIBRARIES = libfbcmap.a AM_CFLAGS = -DHAVE_XNEST_CONFIG_H \ $(DIX_CFLAGS) \ @@ -42,16 +41,12 @@ SRCS = Args.c \ XNPixmap.h \ XNWindow.h \ xnest-config.h \ - $(top_srcdir)/Xext/dpmsstubs.c \ - $(top_srcdir)/Xi/stubs.c \ $(top_srcdir)/mi/miinitext.c -libfbcmap_a_SOURCES = $(top_srcdir)/fb/fbcmap_mi.c -libfbcmap_a_CFLAGS = $(AM_CFLAGS) - XNEST_LIBS = \ @XNEST_LIBS@ \ - libfbcmap.a + $(top_builddir)/Xext/libXextdpmsstubs.la \ + $(top_builddir)/Xi/libXistubs.la Xnest_SOURCES = $(SRCS) diff --git a/xorg-server/hw/xquartz/Makefile.am b/xorg-server/hw/xquartz/Makefile.am index 2ca953cf9..4da896d76 100644 --- a/xorg-server/hw/xquartz/Makefile.am +++ b/xorg-server/hw/xquartz/Makefile.am @@ -20,7 +20,6 @@ SUBDIRS = bundle . $(GL_DIR) xpr pbproxy mach-startup man DIST_SUBDIRS = bundle . GL xpr pbproxy mach-startup man libXquartz_la_SOURCES = \ - $(top_srcdir)/fb/fbcmap_mi.c \ $(top_srcdir)/mi/miinitext.c \ X11Application.m \ X11Controller.m \ diff --git a/xorg-server/hw/xquartz/X11Controller.m b/xorg-server/hw/xquartz/X11Controller.m index 5445c6f3a..022e83258 100644 --- a/xorg-server/hw/xquartz/X11Controller.m +++ b/xorg-server/hw/xquartz/X11Controller.m @@ -942,9 +942,8 @@ extern char *bundle_id_prefix; /* shutdown the X server, it will exit () for us. */ DarwinSendDDXEvent(kXquartzQuit, 0); - /* In case it doesn't, exit anyway after a while. */ - remain = 10000000; - while ((remain = usleep(remain)) > 0) ; + /* In case it doesn't, exit anyway after 5s. */ + [NSThread sleepForTimeInterval:5.0]; exit(1); } diff --git a/xorg-server/hw/xwayland/.gitignore b/xorg-server/hw/xwayland/.gitignore new file mode 100644 index 000000000..c54ba2de9 --- /dev/null +++ b/xorg-server/hw/xwayland/.gitignore @@ -0,0 +1,3 @@ +Xwayland +drm-client-protocol.h +drm-protocol.c diff --git a/xorg-server/hw/xwayland/Makefile.am b/xorg-server/hw/xwayland/Makefile.am new file mode 100644 index 000000000..36e6127df --- /dev/null +++ b/xorg-server/hw/xwayland/Makefile.am @@ -0,0 +1,30 @@ +bin_PROGRAMS = Xwayland + +Xwayland_CFLAGS = \ + -I$(top_srcdir)/dri3 \ + -DHAVE_DIX_CONFIG_H \ + $(XWAYLANDMODULES_CFLAGS) \ + $(DIX_CFLAGS) + +Xwayland_SOURCES = \ + xwayland.c \ + xwayland-input.c \ + xwayland-cursor.c \ + xwayland-shm.c \ + xwayland-output.c \ + xwayland-cvt.c \ + xwayland.h \ + $(top_srcdir)/Xext/dpmsstubs.c \ + $(top_srcdir)/Xi/stubs.c \ + $(top_srcdir)/mi/miinitext.c + +Xwayland_LDADD = \ + $(XWAYLAND_LIBS) \ + $(XWAYLAND_SYS_LIBS) \ + $(XSERVER_SYS_LIBS) +Xwayland_DEPENDENCIES = $(XWAYLAND_LIBS) +Xwayland_LDFLAGS = $(LD_EXPORT_SYMBOLS_FLAG) + + +relink: + $(AM_V_at)rm -f Xwayland$(EXEEXT) && $(MAKE) Xwayland$(EXEEXT) diff --git a/xorg-server/hw/xwayland/xwayland-cursor.c b/xorg-server/hw/xwayland/xwayland-cursor.c new file mode 100644 index 000000000..5a9d1fe70 --- /dev/null +++ b/xorg-server/hw/xwayland/xwayland-cursor.c @@ -0,0 +1,193 @@ +/* + * Copyright © 2014 Intel Corporation + * Copyright © 2011 Kristian Høgsberg + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without + * fee, provided that the above copyright notice appear in all copies + * and that both that copyright notice and this permission notice + * appear in supporting documentation, and that the name of the + * copyright holders not be used in advertising or publicity + * pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied + * warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +#include "xwayland.h" + +#include <mipointer.h> + +static DevPrivateKeyRec xwl_cursor_private_key; + +static void +expand_source_and_mask(CursorPtr cursor, CARD32 *data) +{ + CARD32 *p, d, fg, bg; + CursorBitsPtr bits = cursor->bits; + int x, y, stride, i, bit; + + p = data; + fg = ((cursor->foreRed & 0xff00) << 8) | + (cursor->foreGreen & 0xff00) | (cursor->foreGreen >> 8); + bg = ((cursor->backRed & 0xff00) << 8) | + (cursor->backGreen & 0xff00) | (cursor->backGreen >> 8); + stride = (bits->width / 8 + 3) & ~3; + for (y = 0; y < bits->height; y++) + for (x = 0; x < bits->width; x++) { + i = y * stride + x / 8; + bit = 1 << (x & 7); + if (bits->source[i] & bit) + d = fg; + else + d = bg; + if (bits->mask[i] & bit) + d |= 0xff000000; + else + d = 0x00000000; + + *p++ = d; + } +} + +static Bool +xwl_realize_cursor(DeviceIntPtr device, ScreenPtr screen, CursorPtr cursor) +{ + PixmapPtr pixmap; + + pixmap = xwl_shm_create_pixmap(screen, cursor->bits->width, + cursor->bits->height, 32, 0); + dixSetPrivate(&cursor->devPrivates, &xwl_cursor_private_key, pixmap); + + return TRUE; +} + +static Bool +xwl_unrealize_cursor(DeviceIntPtr device, ScreenPtr screen, CursorPtr cursor) +{ + PixmapPtr pixmap; + + pixmap = dixGetPrivate(&cursor->devPrivates, &xwl_cursor_private_key); + + return xwl_shm_destroy_pixmap(pixmap); +} + +void +xwl_seat_set_cursor(struct xwl_seat *xwl_seat) +{ + PixmapPtr pixmap; + CursorPtr cursor; + int stride; + + if (!xwl_seat->wl_pointer) + return; + + if (!xwl_seat->x_cursor) { + wl_pointer_set_cursor(xwl_seat->wl_pointer, + xwl_seat->pointer_enter_serial, NULL, 0, 0); + return; + } + + cursor = xwl_seat->x_cursor; + pixmap = dixGetPrivate(&cursor->devPrivates, &xwl_cursor_private_key); + stride = cursor->bits->width * 4; + if (cursor->bits->argb) + memcpy(pixmap->devPrivate.ptr, + cursor->bits->argb, cursor->bits->height * stride); + else + expand_source_and_mask(cursor, pixmap->devPrivate.ptr); + + wl_pointer_set_cursor(xwl_seat->wl_pointer, + xwl_seat->pointer_enter_serial, + xwl_seat->cursor, + xwl_seat->x_cursor->bits->xhot, + xwl_seat->x_cursor->bits->yhot); + wl_surface_attach(xwl_seat->cursor, + xwl_shm_pixmap_get_wl_buffer(pixmap), 0, 0); + wl_surface_damage(xwl_seat->cursor, 0, 0, + xwl_seat->x_cursor->bits->width, + xwl_seat->x_cursor->bits->height); + wl_surface_commit(xwl_seat->cursor); +} + +static void +xwl_set_cursor(DeviceIntPtr device, + ScreenPtr screen, CursorPtr cursor, int x, int y) +{ + struct xwl_seat *xwl_seat; + + xwl_seat = device->public.devicePrivate; + if (xwl_seat == NULL) + return; + + xwl_seat->x_cursor = cursor; + xwl_seat_set_cursor(xwl_seat); +} + +static void +xwl_move_cursor(DeviceIntPtr device, ScreenPtr screen, int x, int y) +{ +} + +static Bool +xwl_device_cursor_initialize(DeviceIntPtr device, ScreenPtr screen) +{ + return TRUE; +} + +static void +xwl_device_cursor_cleanup(DeviceIntPtr device, ScreenPtr screen) +{ +} + +static miPointerSpriteFuncRec xwl_pointer_sprite_funcs = { + xwl_realize_cursor, + xwl_unrealize_cursor, + xwl_set_cursor, + xwl_move_cursor, + xwl_device_cursor_initialize, + xwl_device_cursor_cleanup +}; + +static Bool +xwl_cursor_off_screen(ScreenPtr *ppScreen, int *x, int *y) +{ + return FALSE; +} + +static void +xwl_cross_screen(ScreenPtr pScreen, Bool entering) +{ +} + +static void +xwl_pointer_warp_cursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) +{ +} + +static miPointerScreenFuncRec xwl_pointer_screen_funcs = { + xwl_cursor_off_screen, + xwl_cross_screen, + xwl_pointer_warp_cursor +}; + +Bool +xwl_screen_init_cursor(struct xwl_screen *xwl_screen) +{ + if (!dixRegisterPrivateKey(&xwl_cursor_private_key, PRIVATE_CURSOR_BITS, 0)) + return FALSE; + + return miPointerInitialize(xwl_screen->screen, + &xwl_pointer_sprite_funcs, + &xwl_pointer_screen_funcs, TRUE); +} diff --git a/xorg-server/hw/xwayland/xwayland-cvt.c b/xorg-server/hw/xwayland/xwayland-cvt.c new file mode 100644 index 000000000..35665597f --- /dev/null +++ b/xorg-server/hw/xwayland/xwayland-cvt.c @@ -0,0 +1,304 @@ +/* Copied from hw/xfree86/modes/xf86cvt.c into xwayland DDX and + * changed to generate an RRMode */ + +/* + * Copyright 2005-2006 Luc Verhaegen. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * The reason for having this function in a file of its own is + * so that ../utils/cvt/cvt can link to it, and that xf86CVTMode + * code is shared directly. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include <string.h> +#include <randrstr.h> +#include "xwayland.h" + +/* + * Generate a CVT standard mode from HDisplay, VDisplay and VRefresh. + * + * These calculations are stolen from the CVT calculation spreadsheet written + * by Graham Loveridge. He seems to be claiming no copyright and there seems to + * be no license attached to this. He apparently just wants to see his name + * mentioned. + * + * This file can be found at http://www.vesa.org/Public/CVT/CVTd6r1.xls + * + * Comments and structure corresponds to the comments and structure of the xls. + * This should ease importing of future changes to the standard (not very + * likely though). + * + * About margins; i'm sure that they are to be the bit between HDisplay and + * HBlankStart, HBlankEnd and HTotal, VDisplay and VBlankStart, VBlankEnd and + * VTotal, where the overscan colour is shown. FB seems to call _all_ blanking + * outside sync "margin" for some reason. Since we prefer seeing proper + * blanking instead of the overscan colour, and since the Crtc* values will + * probably get altered after us, we will disable margins altogether. With + * these calculations, Margins will plainly expand H/VDisplay, and we don't + * want that. -- libv + * + */ +RRModePtr +xwayland_cvt(int HDisplay, int VDisplay, float VRefresh, Bool Reduced, + Bool Interlaced) +{ + /* 1) top/bottom margin size (% of height) - default: 1.8 */ +#define CVT_MARGIN_PERCENTAGE 1.8 + + /* 2) character cell horizontal granularity (pixels) - default 8 */ +#define CVT_H_GRANULARITY 8 + + /* 4) Minimum vertical porch (lines) - default 3 */ +#define CVT_MIN_V_PORCH 3 + + /* 4) Minimum number of vertical back porch lines - default 6 */ +#define CVT_MIN_V_BPORCH 6 + + /* Pixel Clock step (kHz) */ +#define CVT_CLOCK_STEP 250 + + Bool Margins = FALSE; + float VFieldRate, HPeriod; + int HDisplayRnd, HMargin; + int VDisplayRnd, VMargin, VSync; + float Interlace; /* Please rename this */ + char name[128]; + xRRModeInfo modeinfo; + + memset(&modeinfo, 0, sizeof modeinfo); + + /* CVT default is 60.0Hz */ + if (!VRefresh) + VRefresh = 60.0; + + /* 1. Required field rate */ + if (Interlaced) + VFieldRate = VRefresh * 2; + else + VFieldRate = VRefresh; + + /* 2. Horizontal pixels */ + HDisplayRnd = HDisplay - (HDisplay % CVT_H_GRANULARITY); + + /* 3. Determine left and right borders */ + if (Margins) { + /* right margin is actually exactly the same as left */ + HMargin = (((float) HDisplayRnd) * CVT_MARGIN_PERCENTAGE / 100.0); + HMargin -= HMargin % CVT_H_GRANULARITY; + } + else + HMargin = 0; + + /* 4. Find total active pixels */ + modeinfo.width = HDisplayRnd + 2 * HMargin; + + /* 5. Find number of lines per field */ + if (Interlaced) + VDisplayRnd = VDisplay / 2; + else + VDisplayRnd = VDisplay; + + /* 6. Find top and bottom margins */ + /* nope. */ + if (Margins) + /* top and bottom margins are equal again. */ + VMargin = (((float) VDisplayRnd) * CVT_MARGIN_PERCENTAGE / 100.0); + else + VMargin = 0; + + modeinfo.height = VDisplay + 2 * VMargin; + + /* 7. Interlace */ + if (Interlaced) + Interlace = 0.5; + else + Interlace = 0.0; + + /* Determine VSync Width from aspect ratio */ + if (!(VDisplay % 3) && ((VDisplay * 4 / 3) == HDisplay)) + VSync = 4; + else if (!(VDisplay % 9) && ((VDisplay * 16 / 9) == HDisplay)) + VSync = 5; + else if (!(VDisplay % 10) && ((VDisplay * 16 / 10) == HDisplay)) + VSync = 6; + else if (!(VDisplay % 4) && ((VDisplay * 5 / 4) == HDisplay)) + VSync = 7; + else if (!(VDisplay % 9) && ((VDisplay * 15 / 9) == HDisplay)) + VSync = 7; + else /* Custom */ + VSync = 10; + + if (!Reduced) { /* simplified GTF calculation */ + + /* 4) Minimum time of vertical sync + back porch interval (µs) + * default 550.0 */ +#define CVT_MIN_VSYNC_BP 550.0 + + /* 3) Nominal HSync width (% of line period) - default 8 */ +#define CVT_HSYNC_PERCENTAGE 8 + + float HBlankPercentage; + int VSyncAndBackPorch, VBackPorch; + int HBlank; + + /* 8. Estimated Horizontal period */ + HPeriod = ((float) (1000000.0 / VFieldRate - CVT_MIN_VSYNC_BP)) / + (VDisplayRnd + 2 * VMargin + CVT_MIN_V_PORCH + Interlace); + + /* 9. Find number of lines in sync + backporch */ + if (((int) (CVT_MIN_VSYNC_BP / HPeriod) + 1) < + (VSync + CVT_MIN_V_PORCH)) + VSyncAndBackPorch = VSync + CVT_MIN_V_PORCH; + else + VSyncAndBackPorch = (int) (CVT_MIN_VSYNC_BP / HPeriod) + 1; + + /* 10. Find number of lines in back porch */ + VBackPorch = VSyncAndBackPorch - VSync; + (void) VBackPorch; + + /* 11. Find total number of lines in vertical field */ + modeinfo.vTotal = + VDisplayRnd + 2 * VMargin + VSyncAndBackPorch + Interlace + + CVT_MIN_V_PORCH; + + /* 5) Definition of Horizontal blanking time limitation */ + /* Gradient (%/kHz) - default 600 */ +#define CVT_M_FACTOR 600 + + /* Offset (%) - default 40 */ +#define CVT_C_FACTOR 40 + + /* Blanking time scaling factor - default 128 */ +#define CVT_K_FACTOR 128 + + /* Scaling factor weighting - default 20 */ +#define CVT_J_FACTOR 20 + +#define CVT_M_PRIME CVT_M_FACTOR * CVT_K_FACTOR / 256 +#define CVT_C_PRIME (CVT_C_FACTOR - CVT_J_FACTOR) * CVT_K_FACTOR / 256 + \ + CVT_J_FACTOR + + /* 12. Find ideal blanking duty cycle from formula */ + HBlankPercentage = CVT_C_PRIME - CVT_M_PRIME * HPeriod / 1000.0; + + /* 13. Blanking time */ + if (HBlankPercentage < 20) + HBlankPercentage = 20; + + HBlank = modeinfo.width * HBlankPercentage / (100.0 - HBlankPercentage); + HBlank -= HBlank % (2 * CVT_H_GRANULARITY); + + /* 14. Find total number of pixels in a line. */ + modeinfo.hTotal = modeinfo.width + HBlank; + + /* Fill in HSync values */ + modeinfo.hSyncEnd = modeinfo.width + HBlank / 2; + + modeinfo.hSyncStart = modeinfo.hSyncEnd - + (modeinfo.hTotal * CVT_HSYNC_PERCENTAGE) / 100; + modeinfo.hSyncStart += CVT_H_GRANULARITY - + modeinfo.hSyncStart % CVT_H_GRANULARITY; + + /* Fill in VSync values */ + modeinfo.vSyncStart = modeinfo.height + CVT_MIN_V_PORCH; + modeinfo.vSyncEnd = modeinfo.vSyncStart + VSync; + + } + else { /* Reduced blanking */ + /* Minimum vertical blanking interval time (µs) - default 460 */ +#define CVT_RB_MIN_VBLANK 460.0 + + /* Fixed number of clocks for horizontal sync */ +#define CVT_RB_H_SYNC 32.0 + + /* Fixed number of clocks for horizontal blanking */ +#define CVT_RB_H_BLANK 160.0 + + /* Fixed number of lines for vertical front porch - default 3 */ +#define CVT_RB_VFPORCH 3 + + int VBILines; + + /* 8. Estimate Horizontal period. */ + HPeriod = ((float) (1000000.0 / VFieldRate - CVT_RB_MIN_VBLANK)) / + (VDisplayRnd + 2 * VMargin); + + /* 9. Find number of lines in vertical blanking */ + VBILines = ((float) CVT_RB_MIN_VBLANK) / HPeriod + 1; + + /* 10. Check if vertical blanking is sufficient */ + if (VBILines < (CVT_RB_VFPORCH + VSync + CVT_MIN_V_BPORCH)) + VBILines = CVT_RB_VFPORCH + VSync + CVT_MIN_V_BPORCH; + + /* 11. Find total number of lines in vertical field */ + modeinfo.vTotal = VDisplayRnd + 2 * VMargin + Interlace + VBILines; + + /* 12. Find total number of pixels in a line */ + modeinfo.hTotal = modeinfo.width + CVT_RB_H_BLANK; + + /* Fill in HSync values */ + modeinfo.hSyncEnd = modeinfo.width + CVT_RB_H_BLANK / 2; + modeinfo.hSyncStart = modeinfo.hSyncEnd - CVT_RB_H_SYNC; + + /* Fill in VSync values */ + modeinfo.vSyncStart = modeinfo.height + CVT_RB_VFPORCH; + modeinfo.vSyncEnd = modeinfo.vSyncStart + VSync; + } + + /* 15/13. Find pixel clock frequency (kHz for xf86) */ + modeinfo.dotClock = modeinfo.hTotal * 1000.0 / HPeriod; + modeinfo.dotClock -= modeinfo.dotClock % CVT_CLOCK_STEP; + modeinfo.dotClock *= 1000.0; +#if 0 + /* 16/14. Find actual Horizontal Frequency (kHz) */ + modeinfo.hSync = ((float) modeinfo.dotClock) / ((float) modeinfo.hTotal); +#endif + +#if 0 + /* 17/15. Find actual Field rate */ + modeinfo.vRefresh = (1000.0 * ((float) modeinfo.dotClock)) / + ((float) (modeinfo.hTotal * modeinfo.vTotal)); +#endif + + /* 18/16. Find actual vertical frame frequency */ + /* ignore - just set the mode flag for interlaced */ + if (Interlaced) + modeinfo.vTotal *= 2; + + if (Reduced) + modeinfo.modeFlags |= RR_HSyncPositive | RR_VSyncNegative; + else + modeinfo.modeFlags |= RR_HSyncNegative | RR_VSyncPositive; + + if (Interlaced) + modeinfo.modeFlags |= RR_Interlace; + + snprintf(name, sizeof name, "%dx%d@%.1fHz", + modeinfo.width, modeinfo.height, VRefresh); + modeinfo.nameLength = strlen(name); + + return RRModeGet(&modeinfo, name); +} diff --git a/xorg-server/hw/xwayland/xwayland-input.c b/xorg-server/hw/xwayland/xwayland-input.c new file mode 100644 index 000000000..990cb82d8 --- /dev/null +++ b/xorg-server/hw/xwayland/xwayland-input.c @@ -0,0 +1,666 @@ +/* + * Copyright © 2014 Intel Corporation + * Copyright © 2008 Kristian Høgsberg + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without + * fee, provided that the above copyright notice appear in all copies + * and that both that copyright notice and this permission notice + * appear in supporting documentation, and that the name of the + * copyright holders not be used in advertising or publicity + * pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied + * warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +#include "xwayland.h" + +#include <linux/input.h> + +#include <sys/mman.h> +#include <xkbsrv.h> +#include <xserver-properties.h> +#include <inpututils.h> + +static void +xwl_pointer_control(DeviceIntPtr device, PtrCtrl *ctrl) +{ + /* Nothing to do, dix handles all settings */ +} + +static int +xwl_pointer_proc(DeviceIntPtr device, int what) +{ +#define NBUTTONS 10 +#define NAXES 2 + BYTE map[NBUTTONS + 1]; + int i = 0; + Atom btn_labels[NBUTTONS] = { 0 }; + Atom axes_labels[NAXES] = { 0 }; + + switch (what) { + case DEVICE_INIT: + device->public.on = FALSE; + + for (i = 1; i <= NBUTTONS; i++) + map[i] = i; + + btn_labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT); + btn_labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE); + btn_labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT); + btn_labels[3] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_UP); + btn_labels[4] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_DOWN); + btn_labels[5] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_LEFT); + btn_labels[6] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_RIGHT); + /* don't know about the rest */ + + axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_X); + axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_Y); + + if (!InitValuatorClassDeviceStruct(device, 2, btn_labels, + GetMotionHistorySize(), Absolute)) + return BadValue; + + /* Valuators */ + InitValuatorAxisStruct(device, 0, axes_labels[0], + 0, 0xFFFF, 10000, 0, 10000, Absolute); + InitValuatorAxisStruct(device, 1, axes_labels[1], + 0, 0xFFFF, 10000, 0, 10000, Absolute); + + if (!InitPtrFeedbackClassDeviceStruct(device, xwl_pointer_control)) + return BadValue; + + if (!InitButtonClassDeviceStruct(device, 3, btn_labels, map)) + return BadValue; + + return Success; + + case DEVICE_ON: + device->public.on = TRUE; + return Success; + + case DEVICE_OFF: + case DEVICE_CLOSE: + device->public.on = FALSE; + return Success; + } + + return BadMatch; + +#undef NBUTTONS +#undef NAXES +} + +static void +xwl_keyboard_control(DeviceIntPtr device, KeybdCtrl *ctrl) +{ +} + +static int +xwl_keyboard_proc(DeviceIntPtr device, int what) +{ + struct xwl_seat *xwl_seat = device->public.devicePrivate; + int len; + + switch (what) { + case DEVICE_INIT: + device->public.on = FALSE; + if (xwl_seat->keymap) + len = strnlen(xwl_seat->keymap, xwl_seat->keymap_size); + else + len = 0; + if (!InitKeyboardDeviceStructFromString(device, xwl_seat->keymap, + len, + NULL, xwl_keyboard_control)) + return BadValue; + + return Success; + case DEVICE_ON: + device->public.on = TRUE; + return Success; + + case DEVICE_OFF: + case DEVICE_CLOSE: + device->public.on = FALSE; + return Success; + } + + return BadMatch; +} + +static void +pointer_handle_enter(void *data, struct wl_pointer *pointer, + uint32_t serial, struct wl_surface *surface, + wl_fixed_t sx_w, wl_fixed_t sy_w) +{ + struct xwl_seat *xwl_seat = data; + DeviceIntPtr dev = xwl_seat->pointer; + int i; + int sx = wl_fixed_to_int(sx_w); + int sy = wl_fixed_to_int(sy_w); + ScreenPtr pScreen = xwl_seat->xwl_screen->screen; + ValuatorMask mask; + + xwl_seat->xwl_screen->serial = serial; + xwl_seat->pointer_enter_serial = serial; + + xwl_seat->focus_window = wl_surface_get_user_data(surface); + + (*pScreen->SetCursorPosition) (dev, pScreen, sx, sy, TRUE); + CheckMotion(NULL, GetMaster(dev, MASTER_POINTER)); + + /* Ideally, X clients shouldn't see these button releases. When + * the pointer leaves a window with buttons down, it means that + * the wayland compositor has grabbed the pointer. The button + * release event is consumed by whatever grab in the compositor + * and won't be sent to clients (the X server is a client). + * However, we need to reset X's idea of which buttons are up and + * down, and they're all up (by definition) when the pointer + * enters a window. We should figure out a way to swallow these + * events, perhaps using an X grab whenever the pointer is not in + * any X window, but for now just send the events. */ + valuator_mask_zero(&mask); + for (i = 0; i < dev->button->numButtons; i++) + if (BitIsOn(dev->button->down, i)) + QueuePointerEvents(xwl_seat->pointer, ButtonRelease, i, 0, &mask); +} + +static void +pointer_handle_leave(void *data, struct wl_pointer *pointer, + uint32_t serial, struct wl_surface *surface) +{ + struct xwl_seat *xwl_seat = data; + DeviceIntPtr dev = xwl_seat->pointer; + + xwl_seat->xwl_screen->serial = serial; + + xwl_seat->focus_window = NULL; + CheckMotion(NULL, GetMaster(dev, MASTER_POINTER)); +} + +static void +pointer_handle_motion(void *data, struct wl_pointer *pointer, + uint32_t time, wl_fixed_t sx_w, wl_fixed_t sy_w) +{ + struct xwl_seat *xwl_seat = data; + int32_t dx, dy; + int sx = wl_fixed_to_int(sx_w); + int sy = wl_fixed_to_int(sy_w); + ValuatorMask mask; + + if (!xwl_seat->focus_window) + return; + + dx = xwl_seat->focus_window->window->drawable.x; + dy = xwl_seat->focus_window->window->drawable.y; + + valuator_mask_zero(&mask); + valuator_mask_set(&mask, 0, dx + sx); + valuator_mask_set(&mask, 1, dy + sy); + + QueuePointerEvents(xwl_seat->pointer, MotionNotify, 0, + POINTER_ABSOLUTE | POINTER_SCREEN, &mask); +} + +static void +pointer_handle_button(void *data, struct wl_pointer *pointer, uint32_t serial, + uint32_t time, uint32_t button, uint32_t state) +{ + struct xwl_seat *xwl_seat = data; + int index; + ValuatorMask mask; + + xwl_seat->xwl_screen->serial = serial; + + switch (button) { + case BTN_MIDDLE: + index = 2; + break; + case BTN_RIGHT: + index = 3; + break; + default: + index = button - BTN_LEFT + 1; + break; + } + + valuator_mask_zero(&mask); + QueuePointerEvents(xwl_seat->pointer, + state ? ButtonPress : ButtonRelease, index, 0, &mask); +} + +static void +pointer_handle_axis(void *data, struct wl_pointer *pointer, + uint32_t time, uint32_t axis, wl_fixed_t value) +{ + struct xwl_seat *xwl_seat = data; + int index, count; + int i, val; + const int divisor = 10; + ValuatorMask mask; + + if (time - xwl_seat->scroll_time > 2000) { + xwl_seat->vertical_scroll = 0; + xwl_seat->horizontal_scroll = 0; + } + xwl_seat->scroll_time = time; + + /* FIXME: Need to do proper smooth scrolling here! */ + switch (axis) { + case WL_POINTER_AXIS_VERTICAL_SCROLL: + xwl_seat->vertical_scroll += value / divisor; + val = wl_fixed_to_int(xwl_seat->vertical_scroll); + xwl_seat->vertical_scroll -= wl_fixed_from_int(val); + + if (val <= -1) + index = 4; + else if (val >= 1) + index = 5; + else + return; + break; + case WL_POINTER_AXIS_HORIZONTAL_SCROLL: + xwl_seat->horizontal_scroll += value / divisor; + val = wl_fixed_to_int(xwl_seat->horizontal_scroll); + xwl_seat->horizontal_scroll -= wl_fixed_from_int(val); + + if (val <= -1) + index = 6; + else if (val >= 1) + index = 7; + else + return; + break; + default: + return; + } + + valuator_mask_zero(&mask); + + count = abs(val); + for (i = 0; i < count; i++) { + QueuePointerEvents(xwl_seat->pointer, ButtonPress, index, 0, &mask); + QueuePointerEvents(xwl_seat->pointer, ButtonRelease, index, 0, &mask); + } +} + +static const struct wl_pointer_listener pointer_listener = { + pointer_handle_enter, + pointer_handle_leave, + pointer_handle_motion, + pointer_handle_button, + pointer_handle_axis, +}; + +static void +keyboard_handle_key(void *data, struct wl_keyboard *keyboard, uint32_t serial, + uint32_t time, uint32_t key, uint32_t state) +{ + struct xwl_seat *xwl_seat = data; + uint32_t *k, *end; + ValuatorMask mask; + + xwl_seat->xwl_screen->serial = serial; + + end = (uint32_t *) ((char *) xwl_seat->keys.data + xwl_seat->keys.size); + for (k = xwl_seat->keys.data; k < end; k++) { + if (*k == key) + *k = *--end; + } + xwl_seat->keys.size = (char *) end - (char *) xwl_seat->keys.data; + if (state) { + k = wl_array_add(&xwl_seat->keys, sizeof *k); + *k = key; + } + + valuator_mask_zero(&mask); + QueueKeyboardEvents(xwl_seat->keyboard, + state ? KeyPress : KeyRelease, key + 8, &mask); +} + +static void +keyboard_handle_keymap(void *data, struct wl_keyboard *keyboard, + uint32_t format, int fd, uint32_t size) +{ + struct xwl_seat *xwl_seat = data; + DeviceIntPtr master; + XkbDescPtr xkb; + XkbChangesRec changes = { 0 }; + + if (xwl_seat->keymap) + munmap(xwl_seat->keymap, xwl_seat->keymap_size); + + xwl_seat->keymap_size = size; + xwl_seat->keymap = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0); + if (xwl_seat->keymap == MAP_FAILED) { + xwl_seat->keymap_size = 0; + xwl_seat->keymap = NULL; + goto out; + } + + xkb = XkbCompileKeymapFromString(xwl_seat->keyboard, xwl_seat->keymap, + strnlen(xwl_seat->keymap, + xwl_seat->keymap_size)); + if (!xkb) + goto out; + + XkbUpdateDescActions(xkb, xkb->min_key_code, XkbNumKeys(xkb), &changes); + + if (xwl_seat->keyboard->key) + /* Keep the current controls */ + XkbCopyControls(xkb, xwl_seat->keyboard->key->xkbInfo->desc); + + XkbDeviceApplyKeymap(xwl_seat->keyboard, xkb); + + master = GetMaster(xwl_seat->keyboard, MASTER_KEYBOARD); + if (master && master->lastSlave == xwl_seat->keyboard) + XkbDeviceApplyKeymap(master, xkb); + + XkbFreeKeyboard(xkb, XkbAllComponentsMask, TRUE); + + out: + close(fd); +} + +static void +keyboard_handle_enter(void *data, struct wl_keyboard *keyboard, + uint32_t serial, + struct wl_surface *surface, struct wl_array *keys) +{ + struct xwl_seat *xwl_seat = data; + ValuatorMask mask; + uint32_t *k; + + xwl_seat->xwl_screen->serial = serial; + xwl_seat->keyboard_focus = surface; + + wl_array_copy(&xwl_seat->keys, keys); + valuator_mask_zero(&mask); + wl_array_for_each(k, &xwl_seat->keys) + QueueKeyboardEvents(xwl_seat->keyboard, KeyPress, *k + 8, &mask); +} + +static void +keyboard_handle_leave(void *data, struct wl_keyboard *keyboard, + uint32_t serial, struct wl_surface *surface) +{ + struct xwl_seat *xwl_seat = data; + ValuatorMask mask; + uint32_t *k; + + xwl_seat->xwl_screen->serial = serial; + + valuator_mask_zero(&mask); + wl_array_for_each(k, &xwl_seat->keys) + QueueKeyboardEvents(xwl_seat->keyboard, KeyRelease, *k + 8, &mask); + + xwl_seat->keyboard_focus = NULL; +} + +static void +keyboard_handle_modifiers(void *data, struct wl_keyboard *keyboard, + uint32_t serial, uint32_t mods_depressed, + uint32_t mods_latched, uint32_t mods_locked, + uint32_t group) +{ + struct xwl_seat *xwl_seat = data; + DeviceIntPtr dev; + XkbStateRec old_state, *new_state; + xkbStateNotify sn; + CARD16 changed; + + /* We don't need any of this while we have keyboard focus since + the regular key event processing already takes care of setting + our internal state correctly. */ + if (xwl_seat->keyboard_focus) + return; + + for (dev = inputInfo.devices; dev; dev = dev->next) { + if (dev != xwl_seat->keyboard && + dev != GetMaster(xwl_seat->keyboard, MASTER_KEYBOARD)) + continue; + + old_state = dev->key->xkbInfo->state; + new_state = &dev->key->xkbInfo->state; + + new_state->locked_group = group & XkbAllGroupsMask; + new_state->locked_mods = mods_locked & XkbAllModifiersMask; + XkbLatchModifiers(dev, XkbAllModifiersMask, + mods_latched & XkbAllModifiersMask); + + XkbComputeDerivedState(dev->key->xkbInfo); + + changed = XkbStateChangedFlags(&old_state, new_state); + if (!changed) + continue; + + sn.keycode = 0; + sn.eventType = 0; + sn.requestMajor = XkbReqCode; + sn.requestMinor = X_kbLatchLockState; /* close enough */ + sn.changed = changed; + XkbSendStateNotify(dev, &sn); + } +} + +static const struct wl_keyboard_listener keyboard_listener = { + keyboard_handle_keymap, + keyboard_handle_enter, + keyboard_handle_leave, + keyboard_handle_key, + keyboard_handle_modifiers, +}; + +static DeviceIntPtr +add_device(struct xwl_seat *xwl_seat, + const char *driver, DeviceProc device_proc) +{ + DeviceIntPtr dev = NULL; + static Atom type_atom; + char name[32]; + + dev = AddInputDevice(serverClient, device_proc, TRUE); + if (dev == NULL) + return NULL; + + if (type_atom == None) + type_atom = MakeAtom(driver, strlen(driver), TRUE); + snprintf(name, sizeof name, "%s:%d", driver, xwl_seat->id); + AssignTypeAndName(dev, type_atom, name); + dev->public.devicePrivate = xwl_seat; + dev->type = SLAVE; + dev->spriteInfo->spriteOwner = FALSE; + + return dev; +} + +static void +seat_handle_capabilities(void *data, struct wl_seat *seat, + enum wl_seat_capability caps) +{ + struct xwl_seat *xwl_seat = data; + + if (caps & WL_SEAT_CAPABILITY_POINTER && xwl_seat->pointer == NULL) { + xwl_seat->wl_pointer = wl_seat_get_pointer(seat); + wl_pointer_add_listener(xwl_seat->wl_pointer, + &pointer_listener, xwl_seat); + xwl_seat_set_cursor(xwl_seat); + xwl_seat->pointer = + add_device(xwl_seat, "xwayland-pointer", xwl_pointer_proc); + } + else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && xwl_seat->pointer) { + wl_pointer_release(xwl_seat->wl_pointer); + RemoveDevice(xwl_seat->pointer, FALSE); + xwl_seat->pointer = NULL; + } + + if (caps & WL_SEAT_CAPABILITY_KEYBOARD && xwl_seat->keyboard == NULL) { + xwl_seat->wl_keyboard = wl_seat_get_keyboard(seat); + wl_keyboard_add_listener(xwl_seat->wl_keyboard, + &keyboard_listener, xwl_seat); + xwl_seat->keyboard = + add_device(xwl_seat, "xwayland-keyboard", xwl_keyboard_proc); + } + else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && xwl_seat->keyboard) { + wl_keyboard_release(xwl_seat->wl_keyboard); + RemoveDevice(xwl_seat->keyboard, FALSE); + xwl_seat->keyboard = NULL; + } + + xwl_seat->xwl_screen->expecting_event--; + /* FIXME: Touch ... */ +} + +static void +seat_handle_name(void *data, struct wl_seat *seat, + const char *name) +{ + +} + +static const struct wl_seat_listener seat_listener = { + seat_handle_capabilities, + seat_handle_name +}; + +static void +create_input_device(struct xwl_screen *xwl_screen, uint32_t id) +{ + struct xwl_seat *xwl_seat; + + xwl_seat = calloc(sizeof *xwl_seat, 1); + if (xwl_seat == NULL) { + ErrorF("create_input ENOMEM"); + return; + } + + xwl_seat->xwl_screen = xwl_screen; + xorg_list_add(&xwl_seat->link, &xwl_screen->seat_list); + + xwl_seat->seat = + wl_registry_bind(xwl_screen->registry, id, &wl_seat_interface, 3); + xwl_seat->id = id; + + xwl_seat->cursor = wl_compositor_create_surface(xwl_screen->compositor); + wl_seat_add_listener(xwl_seat->seat, &seat_listener, xwl_seat); + wl_array_init(&xwl_seat->keys); +} + +void +xwl_seat_destroy(struct xwl_seat *xwl_seat) +{ + RemoveDevice(xwl_seat->pointer, FALSE); + RemoveDevice(xwl_seat->keyboard, FALSE); + wl_seat_destroy(xwl_seat->seat); + wl_surface_destroy(xwl_seat->cursor); + wl_array_release(&xwl_seat->keys); + free(xwl_seat); +} + +static void +input_handler(void *data, struct wl_registry *registry, uint32_t id, + const char *interface, uint32_t version) +{ + struct xwl_screen *xwl_screen = data; + + if (strcmp(interface, "wl_seat") == 0 && version >= 3) { + create_input_device(xwl_screen, id); + xwl_screen->expecting_event++; + } +} + +static void +global_remove(void *data, struct wl_registry *registry, uint32_t name) +{ +} + +static const struct wl_registry_listener input_listener = { + input_handler, + global_remove, +}; + +Bool +LegalModifier(unsigned int key, DeviceIntPtr pDev) +{ + return TRUE; +} + +void +ProcessInputEvents(void) +{ + mieqProcessInputEvents(); +} + +void +DDXRingBell(int volume, int pitch, int duration) +{ +} + +static WindowPtr +xwl_xy_to_window(ScreenPtr screen, SpritePtr sprite, int x, int y) +{ + struct xwl_seat *xwl_seat = NULL; + DeviceIntPtr device; + + for (device = inputInfo.devices; device; device = device->next) { + if (device->deviceProc == xwl_pointer_proc && + device->spriteInfo->sprite == sprite) { + xwl_seat = device->public.devicePrivate; + break; + } + } + + if (xwl_seat == NULL) { + /* XTEST device */ + sprite->spriteTraceGood = 1; + return sprite->spriteTrace[0]; + } + + if (xwl_seat->focus_window) { + sprite->spriteTraceGood = 2; + sprite->spriteTrace[1] = xwl_seat->focus_window->window; + return miSpriteTrace(sprite, x, y); + } + else { + sprite->spriteTraceGood = 1; + return sprite->spriteTrace[0]; + } +} + +void +InitInput(int argc, char *argv[]) +{ + ScreenPtr pScreen = screenInfo.screens[0]; + struct xwl_screen *xwl_screen = xwl_screen_get(pScreen); + + mieqInit(); + + xwl_screen->input_registry = wl_display_get_registry(xwl_screen->display); + wl_registry_add_listener(xwl_screen->input_registry, &input_listener, + xwl_screen); + + xwl_screen->XYToWindow = pScreen->XYToWindow; + pScreen->XYToWindow = xwl_xy_to_window; + + xwl_screen->expecting_event = 0; + wl_display_roundtrip(xwl_screen->display); + while (xwl_screen->expecting_event) + wl_display_roundtrip(xwl_screen->display); +} + +void +CloseInput(void) +{ + mieqFini(); +} diff --git a/xorg-server/hw/xwayland/xwayland-output.c b/xorg-server/hw/xwayland/xwayland-output.c new file mode 100644 index 000000000..778914c61 --- /dev/null +++ b/xorg-server/hw/xwayland/xwayland-output.c @@ -0,0 +1,226 @@ +/* + * Copyright © 2011-2014 Intel Corporation + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without + * fee, provided that the above copyright notice appear in all copies + * and that both that copyright notice and this permission notice + * appear in supporting documentation, and that the name of the + * copyright holders not be used in advertising or publicity + * pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied + * warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#endif + +#include "xwayland.h" +#include <randrstr.h> + +static Rotation +wl_transform_to_xrandr(enum wl_output_transform transform) +{ + switch (transform) { + default: + case WL_OUTPUT_TRANSFORM_NORMAL: + return RR_Rotate_0; + case WL_OUTPUT_TRANSFORM_90: + return RR_Rotate_90; + case WL_OUTPUT_TRANSFORM_180: + return RR_Rotate_180; + case WL_OUTPUT_TRANSFORM_270: + return RR_Rotate_270; + case WL_OUTPUT_TRANSFORM_FLIPPED: + return RR_Reflect_X | RR_Rotate_0; + case WL_OUTPUT_TRANSFORM_FLIPPED_90: + return RR_Reflect_X | RR_Rotate_90; + case WL_OUTPUT_TRANSFORM_FLIPPED_180: + return RR_Reflect_X | RR_Rotate_180; + case WL_OUTPUT_TRANSFORM_FLIPPED_270: + return RR_Reflect_X | RR_Rotate_270; + } +} + +static int +wl_subpixel_to_xrandr(int subpixel) +{ + switch (subpixel) { + default: + case WL_OUTPUT_SUBPIXEL_UNKNOWN: + return SubPixelUnknown; + case WL_OUTPUT_SUBPIXEL_NONE: + return SubPixelNone; + case WL_OUTPUT_SUBPIXEL_HORIZONTAL_RGB: + return SubPixelHorizontalRGB; + case WL_OUTPUT_SUBPIXEL_HORIZONTAL_BGR: + return SubPixelHorizontalBGR; + case WL_OUTPUT_SUBPIXEL_VERTICAL_RGB: + return SubPixelVerticalRGB; + case WL_OUTPUT_SUBPIXEL_VERTICAL_BGR: + return SubPixelVerticalBGR; + } +} + +static void +output_handle_geometry(void *data, struct wl_output *wl_output, int x, int y, + int physical_width, int physical_height, int subpixel, + const char *make, const char *model, int transform) +{ + struct xwl_output *xwl_output = data; + + RROutputSetPhysicalSize(xwl_output->randr_output, + physical_width, physical_height); + RROutputSetSubpixelOrder(xwl_output->randr_output, + wl_subpixel_to_xrandr(subpixel)); + xwl_output->x = x; + xwl_output->y = y; + + xwl_output->rotation = wl_transform_to_xrandr(transform); +} + +static void +output_handle_mode(void *data, struct wl_output *wl_output, uint32_t flags, + int width, int height, int refresh) +{ + struct xwl_output *xwl_output = data; + RRModePtr randr_mode; + + if (!(flags & WL_OUTPUT_MODE_CURRENT)) + return; + + xwl_output->width = width; + xwl_output->height = height; + + randr_mode = xwayland_cvt(width, height, refresh / 1000.0, 0, 0); + + RROutputSetModes(xwl_output->randr_output, &randr_mode, 1, 1); + + RRCrtcNotify(xwl_output->randr_crtc, randr_mode, + xwl_output->x, xwl_output->y, + xwl_output->rotation, NULL, 1, &xwl_output->randr_output); +} + +static void +output_handle_done(void *data, struct wl_output *wl_output) +{ + struct xwl_output *xwl_output = data; + struct xwl_screen *xwl_screen = xwl_output->xwl_screen; + int width, height; + + xorg_list_append(&xwl_output->link, &xwl_screen->output_list); + + width = 0; + height = 0; + xorg_list_for_each_entry(xwl_output, &xwl_screen->output_list, link) { + if (width < xwl_output->x + xwl_output->width) + width = xwl_output->x + xwl_output->width; + if (height < xwl_output->y + xwl_output->height) + height = xwl_output->y + xwl_output->height; + } + + xwl_screen->width = width; + xwl_screen->height = height; + RRScreenSizeNotify(xwl_screen->screen); + + xwl_screen->expecting_event--; +} + +static void +output_handle_scale(void *data, struct wl_output *wl_output, int32_t factor) +{ +} + +static const struct wl_output_listener output_listener = { + output_handle_geometry, + output_handle_mode, + output_handle_done, + output_handle_scale +}; + +struct xwl_output * +xwl_output_create(struct xwl_screen *xwl_screen, uint32_t id) +{ + struct xwl_output *xwl_output; + static int serial; + char name[256]; + + xwl_output = calloc(sizeof *xwl_output, 1); + if (xwl_output == NULL) { + ErrorF("create_output ENOMEM"); + return NULL; + } + + xwl_output->output = wl_registry_bind(xwl_screen->registry, id, + &wl_output_interface, 2); + wl_output_add_listener(xwl_output->output, &output_listener, xwl_output); + + if (snprintf(name, sizeof name, "XWAYLAND%d", serial++) < 0) { + ErrorF("create_output ENOMEM"); + free(xwl_output); + return NULL; + } + + xwl_output->xwl_screen = xwl_screen; + xwl_output->randr_crtc = RRCrtcCreate(xwl_screen->screen, xwl_output); + xwl_output->randr_output = RROutputCreate(xwl_screen->screen, name, + strlen(name), xwl_output); + RRCrtcGammaSetSize(xwl_output->randr_crtc, 256); + RROutputSetCrtcs(xwl_output->randr_output, &xwl_output->randr_crtc, 1); + RROutputSetConnection(xwl_output->randr_output, RR_Connected); + + return xwl_output; +} + +void +xwl_output_destroy(struct xwl_output *xwl_output) +{ + wl_output_destroy(xwl_output->output); + RRCrtcDestroy(xwl_output->randr_crtc); + RROutputDestroy(xwl_output->randr_output); + free(xwl_output); +} + +static Bool +xwl_randr_get_info(ScreenPtr pScreen, Rotation * rotations) +{ + *rotations = 0; + + return TRUE; +} + +static Bool +xwl_randr_set_config(ScreenPtr pScreen, + Rotation rotation, int rate, RRScreenSizePtr pSize) +{ + return FALSE; +} + +Bool +xwl_screen_init_output(struct xwl_screen *xwl_screen) +{ + rrScrPrivPtr rp; + + if (!RRScreenInit(xwl_screen->screen)) + return FALSE; + + RRScreenSetSizeRange(xwl_screen->screen, 320, 200, 8192, 8192); + + rp = rrGetScrPriv(xwl_screen->screen); + rp->rrGetInfo = xwl_randr_get_info; + rp->rrSetConfig = xwl_randr_set_config; + + return TRUE; +} diff --git a/xorg-server/hw/xwayland/xwayland-shm.c b/xorg-server/hw/xwayland/xwayland-shm.c new file mode 100644 index 000000000..2d0ce3eb6 --- /dev/null +++ b/xorg-server/hw/xwayland/xwayland-shm.c @@ -0,0 +1,292 @@ +/* + * Copyright © 2014 Intel Corporation + * Copyright © 2012 Collabora, Ltd. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without + * fee, provided that the above copyright notice appear in all copies + * and that both that copyright notice and this permission notice + * appear in supporting documentation, and that the name of the + * copyright holders not be used in advertising or publicity + * pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied + * warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +#include "xwayland.h" + +#include <sys/mman.h> +#include <sys/types.h> +#include <unistd.h> +#include <fcntl.h> +#include <errno.h> +#include <string.h> +#include <stdlib.h> + +struct xwl_pixmap { + struct wl_buffer *buffer; + int fd; + void *data; + size_t size; +}; + +#ifndef HAVE_MKOSTEMP +static int +set_cloexec_or_close(int fd) +{ + long flags; + + if (fd == -1) + return -1; + + flags = fcntl(fd, F_GETFD); + if (flags == -1) + goto err; + + if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1) + goto err; + + return fd; + + err: + close(fd); + return -1; +} +#endif + +static int +create_tmpfile_cloexec(char *tmpname) +{ + int fd; + +#ifdef HAVE_MKOSTEMP + fd = mkostemp(tmpname, O_CLOEXEC); + if (fd >= 0) + unlink(tmpname); +#else + fd = mkstemp(tmpname); + if (fd >= 0) { + fd = set_cloexec_or_close(fd); + unlink(tmpname); + } +#endif + + return fd; +} + +/* + * Create a new, unique, anonymous file of the given size, and + * return the file descriptor for it. The file descriptor is set + * CLOEXEC. The file is immediately suitable for mmap()'ing + * the given size at offset zero. + * + * The file should not have a permanent backing store like a disk, + * but may have if XDG_RUNTIME_DIR is not properly implemented in OS. + * + * The file name is deleted from the file system. + * + * The file is suitable for buffer sharing between processes by + * transmitting the file descriptor over Unix sockets using the + * SCM_RIGHTS methods. + * + * If the C library implements posix_fallocate(), it is used to + * guarantee that disk space is available for the file at the + * given size. If disk space is insufficent, errno is set to ENOSPC. + * If posix_fallocate() is not supported, program may receive + * SIGBUS on accessing mmap()'ed file contents instead. + */ +static int +os_create_anonymous_file(off_t size) +{ + static const char template[] = "/weston-shared-XXXXXX"; + const char *path; + char *name; + int fd; + int ret; + + path = getenv("XDG_RUNTIME_DIR"); + if (!path) { + errno = ENOENT; + return -1; + } + + name = malloc(strlen(path) + sizeof(template)); + if (!name) + return -1; + + strcpy(name, path); + strcat(name, template); + + fd = create_tmpfile_cloexec(name); + + free(name); + + if (fd < 0) + return -1; + +#ifdef HAVE_POSIX_FALLOCATE + ret = posix_fallocate(fd, 0, size); + if (ret != 0) { + close(fd); + errno = ret; + return -1; + } +#else + ret = ftruncate(fd, size); + if (ret < 0) { + close(fd); + return -1; + } +#endif + + return fd; +} + +static uint32_t +shm_format_for_depth(int depth) +{ + switch (depth) { + case 32: + return WL_SHM_FORMAT_ARGB8888; + case 24: + default: + return WL_SHM_FORMAT_XRGB8888; +#ifdef WL_SHM_FORMAT_RGB565 + case 16: + /* XXX: Check run-time protocol version too */ + return WL_SHM_FORMAT_RGB565; +#endif + } +} + +PixmapPtr +xwl_shm_create_pixmap(ScreenPtr screen, + int width, int height, int depth, unsigned int hint) +{ + PixmapPtr pixmap; + struct xwl_pixmap *xwl_pixmap; + size_t size, stride; + + if (hint == CREATE_PIXMAP_USAGE_GLYPH_PICTURE || + (width == 0 && height == 0) || depth < 15) + return fbCreatePixmap(screen, width, height, depth, hint); + + pixmap = fbCreatePixmap(screen, 0, 0, depth, hint); + if (!pixmap) + return NULL; + + xwl_pixmap = malloc(sizeof *xwl_pixmap); + if (xwl_pixmap == NULL) + goto err_destroy_pixmap; + + stride = PixmapBytePad(width, depth); + size = stride * height; + xwl_pixmap->buffer = NULL; + xwl_pixmap->size = size; + xwl_pixmap->fd = os_create_anonymous_file(size); + if (xwl_pixmap->fd < 0) + goto err_free_xwl_pixmap; + + xwl_pixmap->data = mmap(NULL, size, PROT_READ | PROT_WRITE, + MAP_SHARED, xwl_pixmap->fd, 0); + if (xwl_pixmap->data == MAP_FAILED) + goto err_close_fd; + + if (!(*screen->ModifyPixmapHeader) (pixmap, width, height, depth, + BitsPerPixel(depth), + stride, xwl_pixmap->data)) + goto err_munmap; + + xwl_pixmap_set_private(pixmap, xwl_pixmap); + + return pixmap; + + err_munmap: + munmap(xwl_pixmap->data, size); + err_close_fd: + close(xwl_pixmap->fd); + err_free_xwl_pixmap: + free(xwl_pixmap); + err_destroy_pixmap: + fbDestroyPixmap(pixmap); + + return NULL; +} + +Bool +xwl_shm_destroy_pixmap(PixmapPtr pixmap) +{ + struct xwl_pixmap *xwl_pixmap = xwl_pixmap_get(pixmap); + + if (xwl_pixmap && pixmap->refcnt == 1) { + if (xwl_pixmap->buffer) + wl_buffer_destroy(xwl_pixmap->buffer); + munmap(xwl_pixmap->data, xwl_pixmap->size); + close(xwl_pixmap->fd); + free(xwl_pixmap); + } + + return fbDestroyPixmap(pixmap); +} + +struct wl_buffer * +xwl_shm_pixmap_get_wl_buffer(PixmapPtr pixmap) +{ + struct xwl_screen *xwl_screen = xwl_screen_get(pixmap->drawable.pScreen); + struct xwl_pixmap *xwl_pixmap = xwl_pixmap_get(pixmap); + struct wl_shm_pool *pool; + uint32_t format; + + if (xwl_pixmap->buffer) + return xwl_pixmap->buffer; + + pool = wl_shm_create_pool(xwl_screen->shm, + xwl_pixmap->fd, xwl_pixmap->size); + + format = shm_format_for_depth(pixmap->drawable.depth); + xwl_pixmap->buffer = wl_shm_pool_create_buffer(pool, 0, + pixmap->drawable.width, + pixmap->drawable.height, + pixmap->devKind, format); + + wl_shm_pool_destroy(pool); + + return xwl_pixmap->buffer; +} + +Bool +xwl_shm_create_screen_resources(ScreenPtr screen) +{ + struct xwl_screen *xwl_screen = xwl_screen_get(screen); + int ret; + + screen->CreateScreenResources = xwl_screen->CreateScreenResources; + ret = (*screen->CreateScreenResources) (screen); + xwl_screen->CreateScreenResources = screen->CreateScreenResources; + screen->CreateScreenResources = xwl_shm_create_screen_resources; + + if (!ret) + return ret; + + if (xwl_screen->rootless) + screen->devPrivate = + fbCreatePixmap(screen, 0, 0, screen->rootDepth, 0); + else + screen->devPrivate = + xwl_shm_create_pixmap(screen, screen->width, screen->height, + screen->rootDepth, + CREATE_PIXMAP_USAGE_BACKING_PIXMAP); + + return screen->devPrivate != NULL; +} diff --git a/xorg-server/hw/xwayland/xwayland.c b/xorg-server/hw/xwayland/xwayland.c new file mode 100644 index 000000000..c2c6481af --- /dev/null +++ b/xorg-server/hw/xwayland/xwayland.c @@ -0,0 +1,652 @@ +/* + * Copyright © 2011-2014 Intel Corporation + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without + * fee, provided that the above copyright notice appear in all copies + * and that both that copyright notice and this permission notice + * appear in supporting documentation, and that the name of the + * copyright holders not be used in advertising or publicity + * pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied + * warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +#include "xwayland.h" + +#include <stdio.h> + +#include <selection.h> +#include <micmap.h> +#include <misyncshm.h> +#include <compositeext.h> +#include <glx_extinit.h> + +void +ddxGiveUp(enum ExitCode error) +{ +} + +void +AbortDDX(enum ExitCode error) +{ + ddxGiveUp(error); +} + +void +OsVendorInit(void) +{ +} + +void +OsVendorFatalError(const char *f, va_list args) +{ +} + +#if defined(DDXBEFORERESET) +void +ddxBeforeReset(void) +{ + return; +} +#endif + +void +ddxUseMsg(void) +{ + ErrorF("-rootless run rootless, requires wm support\n"); + ErrorF("-wm fd create X client for wm on given fd\n"); + ErrorF("-listen fd add give fd as a listen socket\n"); +} + +int +ddxProcessArgument(int argc, char *argv[], int i) +{ + if (strcmp(argv[i], "-rootless") == 0) { + return 1; + } + else if (strcmp(argv[i], "-listen") == 0) { + NoListenAll = TRUE; + return 2; + } + else if (strcmp(argv[i], "-wm") == 0) { + return 2; + } + else if (strcmp(argv[i], "-shm") == 0) { + return 1; + } + + return 0; +} + +static DevPrivateKeyRec xwl_window_private_key; +static DevPrivateKeyRec xwl_screen_private_key; +static DevPrivateKeyRec xwl_pixmap_private_key; + +struct xwl_screen * +xwl_screen_get(ScreenPtr screen) +{ + return dixLookupPrivate(&screen->devPrivates, &xwl_screen_private_key); +} + +static Bool +xwl_close_screen(ScreenPtr screen) +{ + struct xwl_screen *xwl_screen = xwl_screen_get(screen); + struct xwl_output *xwl_output, *next_xwl_output; + struct xwl_seat *xwl_seat, *next_xwl_seat; + + xorg_list_for_each_entry_safe(xwl_output, next_xwl_output, + &xwl_screen->output_list, link) + xwl_output_destroy(xwl_output); + + xorg_list_for_each_entry_safe(xwl_seat, next_xwl_seat, + &xwl_screen->seat_list, link) + xwl_seat_destroy(xwl_seat); + + wl_display_disconnect(xwl_screen->display); + + screen->CloseScreen = xwl_screen->CloseScreen; + free(xwl_screen); + + return screen->CloseScreen(screen); +} + +static void +damage_report(DamagePtr pDamage, RegionPtr pRegion, void *data) +{ + struct xwl_window *xwl_window = data; + struct xwl_screen *xwl_screen = xwl_window->xwl_screen; + + xorg_list_add(&xwl_window->link_damage, &xwl_screen->damage_window_list); +} + +static void +damage_destroy(DamagePtr pDamage, void *data) +{ +} + +static void +shell_surface_ping(void *data, + struct wl_shell_surface *shell_surface, uint32_t serial) +{ + wl_shell_surface_pong(shell_surface, serial); +} + +static void +shell_surface_configure(void *data, + struct wl_shell_surface *wl_shell_surface, + uint32_t edges, int32_t width, int32_t height) +{ +} + +static void +shell_surface_popup_done(void *data, struct wl_shell_surface *wl_shell_surface) +{ +} + +static const struct wl_shell_surface_listener shell_surface_listener = { + shell_surface_ping, + shell_surface_configure, + shell_surface_popup_done +}; + +void +xwl_pixmap_set_private(PixmapPtr pixmap, struct xwl_pixmap *xwl_pixmap) +{ + dixSetPrivate(&pixmap->devPrivates, &xwl_pixmap_private_key, xwl_pixmap); +} + +struct xwl_pixmap * +xwl_pixmap_get(PixmapPtr pixmap) +{ + return dixLookupPrivate(&pixmap->devPrivates, &xwl_pixmap_private_key); +} + +static void +send_surface_id_event(struct xwl_window *xwl_window) +{ + static const char atom_name[] = "WL_SURFACE_ID"; + static Atom type_atom; + DeviceIntPtr dev; + xEvent e; + + if (type_atom == None) + type_atom = MakeAtom(atom_name, strlen(atom_name), TRUE); + + e.u.u.type = ClientMessage; + e.u.u.detail = 32; + e.u.clientMessage.window = xwl_window->window->drawable.id; + e.u.clientMessage.u.l.type = type_atom; + e.u.clientMessage.u.l.longs0 = + wl_proxy_get_id((struct wl_proxy *) xwl_window->surface); + e.u.clientMessage.u.l.longs1 = 0; + e.u.clientMessage.u.l.longs2 = 0; + e.u.clientMessage.u.l.longs3 = 0; + e.u.clientMessage.u.l.longs4 = 0; + + dev = PickPointer(serverClient); + DeliverEventsToWindow(dev, xwl_window->xwl_screen->screen->root, + &e, 1, SubstructureRedirectMask, NullGrab); +} + +static Bool +xwl_realize_window(WindowPtr window) +{ + ScreenPtr screen = window->drawable.pScreen; + struct xwl_screen *xwl_screen; + struct xwl_window *xwl_window; + struct wl_region *region; + Bool ret; + + xwl_screen = xwl_screen_get(screen); + + screen->RealizeWindow = xwl_screen->RealizeWindow; + ret = (*screen->RealizeWindow) (window); + xwl_screen->RealizeWindow = screen->RealizeWindow; + screen->RealizeWindow = xwl_realize_window; + + if (xwl_screen->rootless && !window->parent) { + ErrorF("Clearing root clip\n"); + RegionNull(&window->clipList); + RegionNull(&window->borderClip); + RegionNull(&window->winSize); + } + + if (xwl_screen->rootless) { + if (window->redirectDraw != RedirectDrawManual) + return ret; + } + else { + if (window->parent) + return ret; + } + + xwl_window = calloc(sizeof *xwl_window, 1); + xwl_window->xwl_screen = xwl_screen; + xwl_window->window = window; + xwl_window->surface = wl_compositor_create_surface(xwl_screen->compositor); + if (xwl_window->surface == NULL) { + ErrorF("wl_display_create_surface failed\n"); + return FALSE; + } + + if (!xwl_screen->rootless) { + xwl_window->shell_surface = + wl_shell_get_shell_surface(xwl_screen->shell, xwl_window->surface); + wl_shell_surface_add_listener(xwl_window->shell_surface, + &shell_surface_listener, xwl_window); + + wl_shell_surface_set_toplevel(xwl_window->shell_surface); + + region = wl_compositor_create_region(xwl_screen->compositor); + wl_region_add(region, 0, 0, + window->drawable.width, window->drawable.height); + wl_surface_set_opaque_region(xwl_window->surface, region); + wl_region_destroy(region); + } + + wl_display_flush(xwl_screen->display); + + send_surface_id_event(xwl_window); + + wl_surface_set_user_data(xwl_window->surface, xwl_window); + + dixSetPrivate(&window->devPrivates, &xwl_window_private_key, xwl_window); + + xwl_window->damage = + DamageCreate(damage_report, damage_destroy, DamageReportNonEmpty, + FALSE, screen, xwl_window); + DamageRegister(&window->drawable, xwl_window->damage); + DamageSetReportAfterOp(xwl_window->damage, TRUE); + + xorg_list_init(&xwl_window->link_damage); + + return ret; +} + +static Bool +xwl_unrealize_window(WindowPtr window) +{ + ScreenPtr screen = window->drawable.pScreen; + struct xwl_screen *xwl_screen; + struct xwl_window *xwl_window; + struct xwl_seat *xwl_seat; + Bool ret; + + xwl_screen = xwl_screen_get(screen); + + xorg_list_for_each_entry(xwl_seat, &xwl_screen->seat_list, link) { + if (!xwl_seat->focus_window) + continue; + if (xwl_seat->focus_window->window == window) + xwl_seat->focus_window = NULL; + } + + screen->UnrealizeWindow = xwl_screen->UnrealizeWindow; + ret = (*screen->UnrealizeWindow) (window); + xwl_screen->UnrealizeWindow = screen->UnrealizeWindow; + screen->UnrealizeWindow = xwl_unrealize_window; + + xwl_window = + dixLookupPrivate(&window->devPrivates, &xwl_window_private_key); + if (!xwl_window) + return ret; + + wl_surface_destroy(xwl_window->surface); + if (RegionNotEmpty(DamageRegion(xwl_window->damage))) + xorg_list_del(&xwl_window->link_damage); + DamageUnregister(xwl_window->damage); + DamageDestroy(xwl_window->damage); + free(xwl_window); + dixSetPrivate(&window->devPrivates, &xwl_window_private_key, NULL); + + return ret; +} + +static Bool +xwl_save_screen(ScreenPtr pScreen, int on) +{ + return TRUE; +} + +static void +xwl_screen_post_damage(struct xwl_screen *xwl_screen) +{ + struct xwl_window *xwl_window; + RegionPtr region; + BoxPtr box; + int count, i; + struct wl_buffer *buffer; + PixmapPtr pixmap; + + xorg_list_for_each_entry(xwl_window, &xwl_screen->damage_window_list, + link_damage) { + region = DamageRegion(xwl_window->damage); + count = RegionNumRects(region); + + pixmap = (*xwl_screen->screen->GetWindowPixmap) (xwl_window->window); + + buffer = xwl_shm_pixmap_get_wl_buffer(pixmap); + wl_surface_attach(xwl_window->surface, buffer, 0, 0); + for (i = 0; i < count; i++) { + box = &RegionRects(region)[i]; + wl_surface_damage(xwl_window->surface, + box->x1, box->y1, + box->x2 - box->x1, box->y2 - box->y1); + } + wl_surface_commit(xwl_window->surface); + DamageEmpty(xwl_window->damage); + } + + xorg_list_init(&xwl_screen->damage_window_list); +} + +static void +registry_global(void *data, struct wl_registry *registry, uint32_t id, + const char *interface, uint32_t version) +{ + struct xwl_screen *xwl_screen = data; + + if (strcmp(interface, "wl_compositor") == 0) { + xwl_screen->compositor = + wl_registry_bind(registry, id, &wl_compositor_interface, 1); + } + else if (strcmp(interface, "wl_shm") == 0) { + xwl_screen->shm = wl_registry_bind(registry, id, &wl_shm_interface, 1); + } + else if (strcmp(interface, "wl_shell") == 0) { + xwl_screen->shell = + wl_registry_bind(registry, id, &wl_shell_interface, 1); + } + else if (strcmp(interface, "wl_output") == 0 && version >= 2) { + xwl_output_create(xwl_screen, id); + xwl_screen->expecting_event++; + } +} + +static void +global_remove(void *data, struct wl_registry *registry, uint32_t name) +{ + /* Nothing to do here, wl_compositor and wl_shm should not be removed */ +} + +static const struct wl_registry_listener registry_listener = { + registry_global, + global_remove +}; + +static void +wakeup_handler(void *data, int err, void *read_mask) +{ + struct xwl_screen *xwl_screen = data; + int ret; + + if (err < 0) + return; + + if (!FD_ISSET(xwl_screen->wayland_fd, (fd_set *) read_mask)) + return; + + ret = wl_display_read_events(xwl_screen->display); + if (ret == -1) + FatalError("failed to dispatch Wayland events: %s\n", strerror(errno)); + + xwl_screen->prepare_read = 0; + + ret = wl_display_dispatch_pending(xwl_screen->display); + if (ret == -1) + FatalError("failed to dispatch Wayland events: %s\n", strerror(errno)); +} + +static void +block_handler(void *data, struct timeval **tv, void *read_mask) +{ + struct xwl_screen *xwl_screen = data; + int ret; + + xwl_screen_post_damage(xwl_screen); + + while (xwl_screen->prepare_read == 0 && + wl_display_prepare_read(xwl_screen->display) == -1) { + ret = wl_display_dispatch_pending(xwl_screen->display); + if (ret == -1) + FatalError("failed to dispatch Wayland events: %s\n", + strerror(errno)); + } + + xwl_screen->prepare_read = 1; + + ret = wl_display_flush(xwl_screen->display); + if (ret == -1) + FatalError("failed to write to XWayland fd: %s\n", strerror(errno)); +} + +static CARD32 +add_client_fd(OsTimerPtr timer, CARD32 time, void *arg) +{ + struct xwl_screen *xwl_screen = arg; + + if (!AddClientOnOpenFD(xwl_screen->wm_fd)) + FatalError("Failed to add wm client\n"); + + TimerFree(timer); + + return 0; +} + +static void +listen_on_fds(struct xwl_screen *xwl_screen) +{ + int i; + + for (i = 0; i < xwl_screen->listen_fd_count; i++) + ListenOnOpenFD(xwl_screen->listen_fds[i], TRUE); +} + +static void +wm_selection_callback(CallbackListPtr *p, void *data, void *arg) +{ + SelectionInfoRec *info = arg; + struct xwl_screen *xwl_screen = data; + static const char atom_name[] = "WM_S0"; + static Atom atom_wm_s0; + + if (atom_wm_s0 == None) + atom_wm_s0 = MakeAtom(atom_name, strlen(atom_name), TRUE); + if (info->selection->selection != atom_wm_s0 || + info->kind != SelectionSetOwner) + return; + + listen_on_fds(xwl_screen); + + DeleteCallback(&SelectionCallback, wm_selection_callback, xwl_screen); +} + +static Bool +xwl_screen_init(ScreenPtr pScreen, int argc, char **argv) +{ + struct xwl_screen *xwl_screen; + Pixel red_mask, blue_mask, green_mask; + int ret, bpc, green_bpc, i; + + xwl_screen = calloc(sizeof *xwl_screen, 1); + xwl_screen->wm_fd = -1; + if (xwl_screen == NULL) + return FALSE; + + if (!dixRegisterPrivateKey(&xwl_screen_private_key, PRIVATE_SCREEN, 0)) + return FALSE; + if (!dixRegisterPrivateKey(&xwl_window_private_key, PRIVATE_WINDOW, 0)) + return FALSE; + if (!dixRegisterPrivateKey(&xwl_pixmap_private_key, PRIVATE_PIXMAP, 0)) + return FALSE; + + dixSetPrivate(&pScreen->devPrivates, &xwl_screen_private_key, xwl_screen); + xwl_screen->screen = pScreen; + + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "-rootless") == 0) { + xwl_screen->rootless = 1; + } + else if (strcmp(argv[i], "-wm") == 0) { + xwl_screen->wm_fd = atoi(argv[i + 1]); + i++; + TimerSet(NULL, 0, 1, add_client_fd, xwl_screen); + } + else if (strcmp(argv[i], "-listen") == 0) { + if (xwl_screen->listen_fd_count == + ARRAY_SIZE(xwl_screen->listen_fds)) + FatalError("Too many -listen arguments given, max is %ld\n", + ARRAY_SIZE(xwl_screen->listen_fds)); + + xwl_screen->listen_fds[xwl_screen->listen_fd_count++] = + atoi(argv[i + 1]); + i++; + } + } + + if (xwl_screen->listen_fd_count > 0) { + if (xwl_screen->wm_fd >= 0) + AddCallback(&SelectionCallback, wm_selection_callback, xwl_screen); + else + listen_on_fds(xwl_screen); + } + + xorg_list_init(&xwl_screen->output_list); + xorg_list_init(&xwl_screen->seat_list); + xorg_list_init(&xwl_screen->damage_window_list); + xwl_screen->depth = 24; + + xwl_screen->display = wl_display_connect(NULL); + if (xwl_screen->display == NULL) { + ErrorF("could not connect to wayland server\n"); + return FALSE; + } + + if (!xwl_screen_init_output(xwl_screen)) + return FALSE; + + xwl_screen->expecting_event = 0; + xwl_screen->registry = wl_display_get_registry(xwl_screen->display); + wl_registry_add_listener(xwl_screen->registry, + ®istry_listener, xwl_screen); + ret = wl_display_roundtrip(xwl_screen->display); + if (ret == -1) { + ErrorF("could not connect to wayland server\n"); + return FALSE; + } + + while (xwl_screen->expecting_event > 0) + wl_display_roundtrip(xwl_screen->display); + + bpc = xwl_screen->depth / 3; + green_bpc = xwl_screen->depth - 2 * bpc; + blue_mask = (1 << bpc) - 1; + green_mask = ((1 << green_bpc) - 1) << bpc; + red_mask = blue_mask << (green_bpc + bpc); + + miSetVisualTypesAndMasks(xwl_screen->depth, + ((1 << TrueColor) | (1 << DirectColor)), + green_bpc, TrueColor, + red_mask, green_mask, blue_mask); + + miSetPixmapDepths(); + + ret = fbScreenInit(pScreen, NULL, + xwl_screen->width, xwl_screen->height, + 96, 96, 0, + BitsPerPixel(xwl_screen->depth)); + if (!ret) + return FALSE; + + fbPictureInit(pScreen, 0, 0); + + if (!miSyncShmScreenInit(pScreen)) + return FALSE; + + xwl_screen->wayland_fd = wl_display_get_fd(xwl_screen->display); + AddGeneralSocket(xwl_screen->wayland_fd); + RegisterBlockAndWakeupHandlers(block_handler, wakeup_handler, xwl_screen); + + pScreen->SaveScreen = xwl_save_screen; + + pScreen->blackPixel = 0; + pScreen->whitePixel = 1; + + ret = fbCreateDefColormap(pScreen); + + if (!xwl_screen_init_cursor(xwl_screen)) + return FALSE; + + xwl_screen->CreateScreenResources = pScreen->CreateScreenResources; + pScreen->CreateScreenResources = xwl_shm_create_screen_resources; + pScreen->CreatePixmap = xwl_shm_create_pixmap; + pScreen->DestroyPixmap = xwl_shm_destroy_pixmap; + + xwl_screen->RealizeWindow = pScreen->RealizeWindow; + pScreen->RealizeWindow = xwl_realize_window; + + xwl_screen->UnrealizeWindow = pScreen->UnrealizeWindow; + pScreen->UnrealizeWindow = xwl_unrealize_window; + + xwl_screen->CloseScreen = pScreen->CloseScreen; + pScreen->CloseScreen = xwl_close_screen; + + return ret; +} + +static void _X_ATTRIBUTE_PRINTF(1, 0) +xwl_log_handler(const char *format, va_list args) +{ + char msg[256]; + + vsnprintf(msg, sizeof msg, format, args); + FatalError("%s", msg); +} + +static const ExtensionModule glx_extension[] = { + { GlxExtensionInit, "GLX", &noGlxExtension }, +}; + +void +InitOutput(ScreenInfo * screen_info, int argc, char **argv) +{ + int depths[] = { 1, 4, 8, 15, 16, 24, 32 }; + int bpp[] = { 1, 8, 8, 16, 16, 32, 32 }; + int i; + + for (i = 0; i < ARRAY_SIZE(depths); i++) { + screen_info->formats[i].depth = depths[i]; + screen_info->formats[i].bitsPerPixel = bpp[i]; + screen_info->formats[i].scanlinePad = BITMAP_SCANLINE_PAD; + } + + screen_info->imageByteOrder = IMAGE_BYTE_ORDER; + screen_info->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT; + screen_info->bitmapScanlinePad = BITMAP_SCANLINE_PAD; + screen_info->bitmapBitOrder = BITMAP_BIT_ORDER; + screen_info->numPixmapFormats = ARRAY_SIZE(depths); + + LoadExtensionList(glx_extension, ARRAY_SIZE(glx_extension), FALSE); + + /* Cast away warning from missing printf annotation for + * wl_log_func_t. Wayland 1.5 will have the annotation, so we can + * remove the cast and require that when it's released. */ + wl_log_set_handler_client((void *) xwl_log_handler); + + if (AddScreen(xwl_screen_init, argc, argv) == -1) { + FatalError("Couldn't add screen\n"); + } +} diff --git a/xorg-server/hw/xwayland/xwayland.h b/xorg-server/hw/xwayland/xwayland.h new file mode 100644 index 000000000..8157e71ff --- /dev/null +++ b/xorg-server/hw/xwayland/xwayland.h @@ -0,0 +1,164 @@ +/* + * Copyright © 2014 Intel Corporation + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without + * fee, provided that the above copyright notice appear in all copies + * and that both that copyright notice and this permission notice + * appear in supporting documentation, and that the name of the + * copyright holders not be used in advertising or publicity + * pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied + * warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +#ifndef XWAYLAND_H +#define XWAYLAND_H + +#include <dix-config.h> +#include <xorg-server.h> + +#include <stdio.h> +#include <unistd.h> +#include <errno.h> + +#include <wayland-client.h> + +#include <X11/X.h> + +#include <fb.h> +#include <input.h> +#include <dix.h> +#include <randrstr.h> +#include <exevents.h> + +struct xwl_screen { + int width; + int height; + int depth; + ScreenPtr screen; + WindowPtr pointer_limbo_window; + int expecting_event; + + int wm_fd; + int listen_fds[5]; + int listen_fd_count; + int rootless; + + CreateScreenResourcesProcPtr CreateScreenResources; + CloseScreenProcPtr CloseScreen; + CreateWindowProcPtr CreateWindow; + DestroyWindowProcPtr DestroyWindow; + RealizeWindowProcPtr RealizeWindow; + UnrealizeWindowProcPtr UnrealizeWindow; + XYToWindowProcPtr XYToWindow; + + struct xorg_list output_list; + struct xorg_list seat_list; + struct xorg_list damage_window_list; + + int wayland_fd; + struct wl_display *display; + struct wl_registry *registry; + struct wl_registry *input_registry; + struct wl_compositor *compositor; + struct wl_shm *shm; + struct wl_shell *shell; + + uint32_t serial; + +#define XWL_FORMAT_ARGB8888 (1 << 0) +#define XWL_FORMAT_XRGB8888 (1 << 1) +#define XWL_FORMAT_RGB565 (1 << 2) + + int prepare_read; +}; + +struct xwl_window { + struct xwl_screen *xwl_screen; + struct wl_surface *surface; + struct wl_shell_surface *shell_surface; + WindowPtr window; + DamagePtr damage; + struct xorg_list link_damage; +}; + +#define MODIFIER_META 0x01 + +struct xwl_seat { + DeviceIntPtr pointer; + DeviceIntPtr keyboard; + struct xwl_screen *xwl_screen; + struct wl_seat *seat; + struct wl_pointer *wl_pointer; + struct wl_keyboard *wl_keyboard; + struct wl_array keys; + struct wl_surface *cursor; + struct xwl_window *focus_window; + uint32_t id; + uint32_t pointer_enter_serial; + struct xorg_list link; + CursorPtr x_cursor; + + wl_fixed_t horizontal_scroll; + wl_fixed_t vertical_scroll; + uint32_t scroll_time; + + size_t keymap_size; + char *keymap; + struct wl_surface *keyboard_focus; +}; + +struct xwl_output { + struct xorg_list link; + struct wl_output *output; + struct xwl_screen *xwl_screen; + RROutputPtr randr_output; + RRCrtcPtr randr_crtc; + int32_t x, y, width, height; + Rotation rotation; +}; + +struct xwl_pixmap; + +Bool xwl_screen_init_cursor(struct xwl_screen *xwl_screen); + +struct xwl_screen *xwl_screen_get(ScreenPtr screen); + +void xwl_seat_set_cursor(struct xwl_seat *xwl_seat); + +void xwl_seat_destroy(struct xwl_seat *xwl_seat); + +Bool xwl_screen_init_output(struct xwl_screen *xwl_screen); + +struct xwl_output *xwl_output_create(struct xwl_screen *xwl_screen, + uint32_t id); + +void xwl_output_destroy(struct xwl_output *xwl_output); + +RRModePtr xwayland_cvt(int HDisplay, int VDisplay, + float VRefresh, Bool Reduced, Bool Interlaced); + +void xwl_pixmap_set_private(PixmapPtr pixmap, struct xwl_pixmap *xwl_pixmap); +struct xwl_pixmap *xwl_pixmap_get(PixmapPtr pixmap); + + +Bool xwl_shm_create_screen_resources(ScreenPtr screen); +PixmapPtr xwl_shm_create_pixmap(ScreenPtr screen, int width, int height, + int depth, unsigned int hint); +Bool xwl_shm_destroy_pixmap(PixmapPtr pixmap); +struct wl_buffer *xwl_shm_pixmap_get_wl_buffer(PixmapPtr pixmap); + + +#endif diff --git a/xorg-server/hw/xwin/Makefile.am b/xorg-server/hw/xwin/Makefile.am index 7f0eaf097..cf42cfd2d 100644 --- a/xorg-server/hw/xwin/Makefile.am +++ b/xorg-server/hw/xwin/Makefile.am @@ -127,10 +127,7 @@ SRCS = InitInput.c \ winresource.h \ winwindow.h \ XWin.rc \ - $(top_srcdir)/Xext/dpmsstubs.c \ - $(top_srcdir)/Xi/stubs.c \ $(top_srcdir)/mi/miinitext.c \ - $(top_srcdir)/fb/fbcmap_mi.c \ $(SRCS_CLIPBOARD) \ $(SRCS_MULTIWINDOW) \ $(SRCS_MULTIWINDOWEXTWM) \ @@ -153,12 +150,14 @@ XWin_SOURCES = $(SRCS) AM_CPPFLAGS = -I$(top_srcdir)/miext/rootless XWIN_SYS_LIBS += -ldxguid -XWIN_LIBS += $(top_builddir)/pseudoramiX/libPseudoramiX.la - +XWIN_LIBS += $(top_builddir)/pseudoramiX/libPseudoramiX.la \ + $(top_builddir)/Xext/libXextdpmsstubs.la \ + $(top_builddir)/Xi/libXistubs.la XWin_DEPENDENCIES = $(MULTIWINDOWEXTWM_LIBS) $(XWIN_GLX_LIBS) $(XWIN_LIBS) $(XSERVER_LIBS) XWin_LDADD = $(MULTIWINDOW_LIBS) $(MULTIWINDOWEXTWM_LIBS) $(XWIN_GLX_LIBS) $(XWIN_GLX_LINK_FLAGS) $(XWIN_LIBS) $(MAIN_LIB) $(XSERVER_LIBS) $(XSERVER_SYS_LIBS) $(XWIN_SYS_LIBS) XWin_LDFLAGS = -mwindows -static -Wl,--disable-stdcall-fixup + .rc.o: $(AM_V_GEN)$(WINDRES) --use-temp-file -i $< --input-format=rc -o $@ -O coff -I $(top_builddir)/include |