Merge remote-tracking branch 'origin2/master'

This commit is contained in:
Adam Richter 2019-06-29 04:44:05 -07:00
commit d80b07a2ee
54 changed files with 1391 additions and 162 deletions

View file

@ -50,6 +50,7 @@ libXmu-devel,\
libXpm-devel,\
libXrender-devel,\
libXtst-devel,\
libxcb-composite-devel,\
libxcb-ewmh-devel,\
libxcb-icccm-devel,\
libxcb-image-devel,\

View file

@ -203,8 +203,14 @@ ProcXIPassiveGrabDevice(ClientPtr client)
&param, XI2, &mask);
break;
case XIGrabtypeKeycode:
status = GrabKey(client, dev, mod_dev, stuff->detail,
&param, XI2, &mask);
/* XI2 allows 32-bit keycodes but thanks to XKB we can never
* implement this. Just return an error for all keycodes that
* cannot work anyway */
if (stuff->detail > 255)
status = XIAlreadyGrabbed;
else
status = GrabKey(client, dev, mod_dev, stuff->detail,
&param, XI2, &mask);
break;
case XIGrabtypeEnter:
case XIGrabtypeFocusIn:

View file

@ -474,7 +474,7 @@ config_udev_odev_setup_attribs(struct udev_device *udev_device, const char *path
config_odev_probe_proc_ptr probe_callback)
{
struct OdevAttributes *attribs = config_odev_allocate_attributes();
const char *value;
const char *value, *str;
attribs->path = XNFstrdup(path);
attribs->syspath = XNFstrdup(syspath);
@ -482,8 +482,8 @@ config_udev_odev_setup_attribs(struct udev_device *udev_device, const char *path
attribs->minor = minor;
value = udev_device_get_property_value(udev_device, "ID_PATH");
if (value && !strncmp(value, "pci-", 4)) {
attribs->busid = XNFstrdup(value);
if (value && (str = strstr(value, "pci-"))) {
attribs->busid = XNFstrdup(str);
attribs->busid[3] = ':';
}

View file

@ -159,7 +159,8 @@ dnl Checks for library functions.
AC_CHECK_FUNCS([backtrace geteuid getuid issetugid getresuid \
getdtablesize getifaddrs getpeereid getpeerucred getprogname getzoneid \
mmap posix_fallocate seteuid shmctl64 strncasecmp vasprintf vsnprintf \
walkcontext setitimer poll epoll_create1 mkostemp memfd_create])
walkcontext setitimer poll epoll_create1 mkostemp memfd_create \
sigprocmask])
AC_CONFIG_LIBOBJ_DIR([os])
AC_REPLACE_FUNCS([reallocarray strcasecmp strcasestr strlcat strlcpy strndup\
timingsafe_memcmp])
@ -753,7 +754,7 @@ DAMAGEPROTO="damageproto >= 1.1"
XCMISCPROTO="xcmiscproto >= 1.2.0"
BIGREQSPROTO="bigreqsproto >= 1.1.0"
XTRANS="xtrans >= 1.3.5"
PRESENTPROTO="presentproto >= 1.1"
PRESENTPROTO="presentproto >= 1.2"
dnl List of libraries that require a specific version
LIBAPPLEWM="applewm >= 1.4"
@ -791,6 +792,11 @@ if test "x$HAVE_RECURSIVE_MUTEX" = "xyes" ; then
THREAD_DEFAULT=yes
fi
case $host_os in
mingw*) THREAD_DEFAULT=no ;;
*)
esac
AC_ARG_ENABLE(input-thread, AS_HELP_STRING([--enable-input-thread],
[Enable input threads]),
[INPUTTHREAD=$enableval], [INPUTTHREAD=$THREAD_DEFAULT])
@ -2075,7 +2081,7 @@ if test "x$XWIN" = xyes; then
AC_DEFINE_UNQUOTED(__VENDORDWEBSUPPORT__, ["$VENDOR_WEB"], [Vendor web address for support])
AC_CHECK_TOOL(WINDRES, windres)
PKG_CHECK_MODULES([XWINMODULES],[x11 xdmcp xau xfixes x11-xcb xcb-aux xcb-image xcb-ewmh xcb-icccm])
PKG_CHECK_MODULES([XWINMODULES],[x11 xau xdmcp xfixes x11-xcb xcb-aux xcb-composite xcb-image xcb-ewmh xcb-icccm])
if test "x$WINDOWSDRI" = xauto; then
PKG_CHECK_EXISTS([windowsdriproto], [WINDOWSDRI=yes], [WINDOWSDRI=no])

View file

@ -62,7 +62,7 @@ TODO: Solaris.
TODO: *BSD.
Windows-dependent code assumes at least NT 5.1.
Windows-dependent code assumes at least NT 6.0.
OSX support is generally limited to the most recent version. Currently
that means 10.5.

View file

@ -99,7 +99,7 @@ glamor_set_pixmap_type(PixmapPtr pixmap, glamor_pixmap_type_t type)
glamor_init_pixmap_private_small(pixmap, pixmap_priv);
}
_X_EXPORT void
_X_EXPORT Bool
glamor_set_pixmap_texture(PixmapPtr pixmap, unsigned int tex)
{
ScreenPtr screen = pixmap->drawable.pScreen;
@ -121,10 +121,12 @@ glamor_set_pixmap_texture(PixmapPtr pixmap, unsigned int tex)
if (fbo == NULL) {
ErrorF("XXX fail to create fbo.\n");
return;
return FALSE;
}
glamor_pixmap_attach_fbo(pixmap, fbo);
return TRUE;
}
uint32_t

View file

@ -110,7 +110,7 @@ extern _X_EXPORT Bool glamor_close_screen(ScreenPtr screen);
extern _X_EXPORT uint32_t glamor_get_pixmap_texture(PixmapPtr pixmap);
extern _X_EXPORT void glamor_set_pixmap_texture(PixmapPtr pixmap,
extern _X_EXPORT Bool glamor_set_pixmap_texture(PixmapPtr pixmap,
unsigned int tex);
extern _X_EXPORT void glamor_set_pixmap_type(PixmapPtr pixmap,

View file

@ -367,8 +367,8 @@ glamor_make_pixmap_exportable(PixmapPtr pixmap, Bool modifiers_ok)
return TRUE;
}
struct gbm_bo *
glamor_gbm_bo_from_pixmap(ScreenPtr screen, PixmapPtr pixmap)
static struct gbm_bo *
glamor_gbm_bo_from_pixmap_internal(ScreenPtr screen, PixmapPtr pixmap)
{
struct glamor_egl_screen_private *glamor_egl =
glamor_egl_get_screen_private(xf86ScreenToScrn(screen));
@ -382,6 +382,15 @@ glamor_gbm_bo_from_pixmap(ScreenPtr screen, PixmapPtr pixmap)
pixmap_priv->image, 0);
}
struct gbm_bo *
glamor_gbm_bo_from_pixmap(ScreenPtr screen, PixmapPtr pixmap)
{
if (!glamor_make_pixmap_exportable(pixmap, TRUE))
return NULL;
return glamor_gbm_bo_from_pixmap_internal(screen, pixmap);
}
int
glamor_egl_fds_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, int *fds,
uint32_t *strides, uint32_t *offsets,
@ -397,7 +406,7 @@ glamor_egl_fds_from_pixmap(ScreenPtr screen, PixmapPtr pixmap, int *fds,
if (!glamor_make_pixmap_exportable(pixmap, TRUE))
return 0;
bo = glamor_gbm_bo_from_pixmap(screen, pixmap);
bo = glamor_gbm_bo_from_pixmap_internal(screen, pixmap);
if (!bo)
return 0;
@ -435,7 +444,7 @@ glamor_egl_fd_from_pixmap(ScreenPtr screen, PixmapPtr pixmap,
if (!glamor_make_pixmap_exportable(pixmap, FALSE))
return -1;
bo = glamor_gbm_bo_from_pixmap(screen, pixmap);
bo = glamor_gbm_bo_from_pixmap_internal(screen, pixmap);
if (!bo)
return -1;
@ -464,7 +473,7 @@ glamor_egl_fd_name_from_pixmap(ScreenPtr screen,
if (!glamor_make_pixmap_exportable(pixmap, FALSE))
goto failure;
bo = glamor_gbm_bo_from_pixmap(screen, pixmap);
bo = glamor_gbm_bo_from_pixmap_internal(screen, pixmap);
if (!bo)
goto failure;

View file

@ -158,7 +158,7 @@ glamor_set_solid(PixmapPtr pixmap,
return FALSE;
}
}
glamor_set_color(pixmap, gc->fgPixel, uniform);
glamor_set_color(pixmap, pixel, uniform);
return TRUE;
}

View file

@ -765,7 +765,7 @@ __glXDisp_WaitGL(__GLXclientState * cl, GLbyte * pc)
glFinish();
}
if (glxc && glxc->drawPriv->waitGL)
if (glxc && glxc->drawPriv && glxc->drawPriv->waitGL)
(*glxc->drawPriv->waitGL) (glxc->drawPriv);
return Success;
@ -789,7 +789,7 @@ __glXDisp_WaitX(__GLXclientState * cl, GLbyte * pc)
return error;
}
if (glxc && glxc->drawPriv->waitX)
if (glxc && glxc->drawPriv && glxc->drawPriv->waitX)
(*glxc->drawPriv->waitX) (glxc->drawPriv);
return Success;

View file

@ -468,15 +468,24 @@ void GlxDispatchReset(void)
int GlxDispatchRequest(ClientPtr client)
{
REQUEST(xReq);
int result;
if (GlxExtensionEntry->base == 0)
return BadRequest;
GlxSetRequestClient(client);
if (stuff->data < OPCODE_ARRAY_LEN) {
if (dispatchFuncs[stuff->data] == NULL) {
// Try to find a dispatch stub.
dispatchFuncs[stuff->data] = GetVendorDispatchFunc(stuff->data, 0);
}
return dispatchFuncs[stuff->data](client);
result = dispatchFuncs[stuff->data](client);
} else {
return dispatch_GLXSingle(client);
result = dispatch_GLXSingle(client);
}
GlxSetRequestClient(NULL);
return result;
}

View file

@ -139,8 +139,17 @@ GlxGetClientData(ClientPtr client)
{
GlxClientPriv *cl = xglvGetClientPrivate(client);
if (cl == NULL) {
cl = calloc(1, sizeof(GlxClientPriv));
cl = calloc(1, sizeof(GlxClientPriv)
+ screenInfo.numScreens * sizeof(GlxServerVendor *));
if (cl != NULL) {
int i;
cl->vendors = (GlxServerVendor **) (cl + 1);
for (i=0; i<screenInfo.numScreens; i++)
{
cl->vendors[i] = GlxGetVendorForScreen(NULL, screenInfo.screens[i]);
}
xglvSetClientPrivate(client, cl);
}
}
@ -295,8 +304,8 @@ GlxFreeServerImports(GlxServerImports *imports)
}
_X_EXPORT const GlxServerExports glxServer = {
.majorVersion = 0,
.minorVersion = 0,
.majorVersion = GLXSERVER_VENDOR_ABI_MAJOR_VERSION,
.minorVersion = GLXSERVER_VENDOR_ABI_MINOR_VERSION,
.extensionInitCallback = &vndInitCallbackListPtr,
@ -315,6 +324,7 @@ _X_EXPORT const GlxServerExports glxServer = {
.getContextTagPrivate = GlxGetContextTagPrivate,
.getVendorForScreen = GlxGetVendorForScreen,
.forwardRequest = GlxForwardRequest,
.setClientScreenVendor = GlxSetClientScreenVendor,
};
const GlxServerExports *

View file

@ -57,6 +57,11 @@ typedef struct GlxContextTagInfoRec {
typedef struct GlxClientPrivRec {
GlxContextTagInfo *contextTags;
unsigned int contextTagCount;
/**
* The vendor handles for each screen.
*/
GlxServerVendor **vendors;
} GlxClientPriv;
extern int GlxErrorBase;
@ -90,11 +95,19 @@ Bool GlxAddXIDMap(XID id, GlxServerVendor *vendor);
GlxServerVendor * GlxGetXIDMap(XID id);
void GlxRemoveXIDMap(XID id);
/**
* Records the client that sent the current request. This is needed in
* GlxGetXIDMap to know which client's (screen -> vendor) mapping to use for a
* regular X window.
*/
void GlxSetRequestClient(ClientPtr client);
GlxContextTagInfo *GlxAllocContextTag(ClientPtr client, GlxServerVendor *vendor);
GlxContextTagInfo *GlxLookupContextTag(ClientPtr client, GLXContextTag tag);
void GlxFreeContextTag(GlxContextTagInfo *tagInfo);
Bool GlxSetScreenVendor(ScreenPtr screen, GlxServerVendor *vendor);
Bool GlxSetClientScreenVendor(ClientPtr client, ScreenPtr screen, GlxServerVendor *vendor);
GlxScreenPriv *GlxGetScreen(ScreenPtr pScreen);
GlxServerVendor *GlxGetVendorForScreen(ClientPtr client, ScreenPtr screen);

View file

@ -33,6 +33,13 @@
#include "vndservervendor.h"
static ClientPtr requestClient = NULL;
void GlxSetRequestClient(ClientPtr client)
{
requestClient = client;
}
static GlxServerVendor *LookupXIDMapResource(XID id)
{
void *ptr = NULL;
@ -59,10 +66,7 @@ GlxServerVendor *GlxGetXIDMap(XID id)
DixGetAttrAccess);
if (rv == Success && ptr != NULL) {
DrawablePtr draw = (DrawablePtr) ptr;
GlxScreenPriv *screenPriv = GlxGetScreen(draw->pScreen);
if (screenPriv != NULL) {
vendor = screenPriv->vendor;
}
vendor = GlxGetVendorForScreen(requestClient, draw->pScreen);
}
}
return vendor;
@ -185,12 +189,44 @@ Bool GlxSetScreenVendor(ScreenPtr screen, GlxServerVendor *vendor)
return TRUE;
}
Bool GlxSetClientScreenVendor(ClientPtr client, ScreenPtr screen, GlxServerVendor *vendor)
{
GlxClientPriv *cl;
if (screen == NULL || screen->isGPU) {
return FALSE;
}
cl = GlxGetClientData(client);
if (cl == NULL) {
return FALSE;
}
if (vendor != NULL) {
cl->vendors[screen->myNum] = vendor;
} else {
cl->vendors[screen->myNum] = GlxGetVendorForScreen(NULL, screen);
}
return TRUE;
}
GlxServerVendor *GlxGetVendorForScreen(ClientPtr client, ScreenPtr screen)
{
GlxScreenPriv *priv = GlxGetScreen(screen);
if (priv != NULL) {
return priv->vendor;
// Note that the client won't be sending GPU screen numbers, so we don't
// need per-client mappings for them.
if (client != NULL && !screen->isGPU) {
GlxClientPriv *cl = GlxGetClientData(client);
if (cl != NULL) {
return cl->vendors[screen->myNum];
} else {
return NULL;
}
} else {
return NULL;
GlxScreenPriv *priv = GlxGetScreen(screen);
if (priv != NULL) {
return priv->vendor;
} else {
return NULL;
}
}
}

View file

@ -116,16 +116,36 @@ hwDisableIO(void)
static Bool
hwEnableIO(void)
{
if (ioperm(0, 1024, 1) || iopl(3)) {
ErrorF("xf86EnableIOPorts: failed to set IOPL for I/O (%s)\n",
short i;
size_t n=0;
int begin, end;
char *buf=NULL, target[4];
FILE *fp;
if (ioperm(0, 1024, 1)) {
ErrorF("xf86EnableIO: failed to enable I/O ports 0000-03ff (%s)\n",
strerror(errno));
return FALSE;
}
#if !defined(__alpha__)
/* XXX: this is actually not trapping anything because of iopl(3)
* above */
ioperm(0x40, 4, 0); /* trap access to the timer chip */
ioperm(0x60, 4, 0); /* trap access to the keyboard controller */
/* trap access to the keyboard controller(s) and timer chip(s) */
fp = fopen("/proc/ioports", "r");
while (getline(&buf, &n, fp) != -1) {
if ((strstr(buf, "keyboard") != NULL) || (strstr(buf, "timer") != NULL)) {
for (i=0; i<4; i++)
target[i] = buf[i+2];
begin = atoi(target);
for (i=0; i<4; i++)
target[i] = buf[i+7];
end = atoi(target);
ioperm(begin, end-begin+1, 0);
}
}
free(buf);
fclose(fp);
#endif
return TRUE;

View file

@ -22,6 +22,10 @@ Xwayland_SOURCES = \
$(top_srcdir)/mi/miinitext.c
if GLX
Xwayland_SOURCES += \
xwayland-glx.c
Xwayland_CFLAGS += \
-I$(top_srcdir)/glx
GLXVND_LIB = $(top_builddir)/glx/libglxvnd.la
endif

View file

@ -54,6 +54,9 @@ xwayland_glamor = []
eglstream_srcs = []
if build_glamor
srcs += 'xwayland-glamor.c'
if build_glx
srcs += 'xwayland-glx.c'
endif
if gbm_dep.found()
srcs += 'xwayland-glamor-gbm.c'
endif
@ -80,10 +83,15 @@ if build_glamor
xwayland_glamor += glamor
endif
wayland_inc = [ inc, ]
if build_glx
wayland_inc += glx_inc
endif
executable(
'Xwayland',
srcs,
include_directories: inc,
include_directories: wayland_inc,
dependencies: [
common_dep,
xwayland_dep,

View file

@ -188,6 +188,8 @@ xwl_tablet_tool_set_cursor(struct xwl_tablet_tool *xwl_tablet_tool)
zwp_tablet_tool_v2_set_cursor(xwl_tablet_tool->tool,
xwl_tablet_tool->proximity_in_serial,
NULL, 0, 0);
clear_cursor_frame_callback(xwl_cursor);
xwl_cursor->needs_update = FALSE;
return;
}

View file

@ -169,6 +169,8 @@ xwl_glamor_gbm_create_pixmap_for_bo(ScreenPtr screen, struct gbm_bo *bo,
xwl_screen->egl_context,
EGL_NATIVE_PIXMAP_KHR,
xwl_pixmap->bo, NULL);
if (xwl_pixmap->image == EGL_NO_IMAGE_KHR)
goto error;
glGenTextures(1, &xwl_pixmap->texture);
glBindTexture(GL_TEXTURE_2D, xwl_pixmap->texture);
@ -176,14 +178,27 @@ xwl_glamor_gbm_create_pixmap_for_bo(ScreenPtr screen, struct gbm_bo *bo,
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, xwl_pixmap->image);
if (eglGetError() != EGL_SUCCESS)
goto error;
glBindTexture(GL_TEXTURE_2D, 0);
if (!glamor_set_pixmap_texture(pixmap, xwl_pixmap->texture))
goto error;
glamor_set_pixmap_type(pixmap, GLAMOR_TEXTURE_DRM);
xwl_pixmap_set_private(pixmap, xwl_pixmap);
glamor_set_pixmap_texture(pixmap, xwl_pixmap->texture);
glamor_set_pixmap_type(pixmap, GLAMOR_TEXTURE_DRM);
return pixmap;
error:
if (xwl_pixmap->image != EGL_NO_IMAGE_KHR)
eglDestroyImageKHR(xwl_screen->egl_display, xwl_pixmap->image);
if (pixmap)
glamor_destroy_pixmap(pixmap);
free(xwl_pixmap);
return NULL;
}
static PixmapPtr
@ -194,6 +209,7 @@ xwl_glamor_gbm_create_pixmap(ScreenPtr screen,
struct xwl_screen *xwl_screen = xwl_screen_get(screen);
struct xwl_gbm_private *xwl_gbm = xwl_gbm_get(xwl_screen);
struct gbm_bo *bo;
PixmapPtr pixmap = NULL;
if (width > 0 && height > 0 && depth >= 15 &&
(hint == 0 ||
@ -219,10 +235,16 @@ xwl_glamor_gbm_create_pixmap(ScreenPtr screen,
}
if (bo)
return xwl_glamor_gbm_create_pixmap_for_bo(screen, bo, depth);
pixmap = xwl_glamor_gbm_create_pixmap_for_bo(screen, bo, depth);
if (!pixmap)
gbm_bo_destroy(bo);
}
return glamor_create_pixmap(screen, width, height, depth, hint);
if (!pixmap)
pixmap = glamor_create_pixmap(screen, width, height, depth, hint);
return pixmap;
}
static Bool

View file

@ -30,6 +30,9 @@
#include <glamor.h>
#include <glamor_context.h>
#ifdef GLXEXT
#include "glx_extinit.h"
#endif
static void
glamor_egl_make_current(struct glamor_context *glamor_ctx)
@ -264,5 +267,9 @@ xwl_glamor_init(struct xwl_screen *xwl_screen)
ErrorF("Failed to initialize glamor Xv extension\n");
#endif
#ifdef GLXEXT
GlxPushProvider(&glamor_provider);
#endif
return TRUE;
}

367
hw/xwayland/xwayland-glx.c Normal file
View file

@ -0,0 +1,367 @@
/*
* Copyright © 2019 Red Hat, Inc.
*
* 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 (including the next
* paragraph) 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 AUTHORS OR COPYRIGHT HOLDERS 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.
*
* Authors:
* Adam Jackson <ajax@redhat.com>
*/
/*
* Sets up GLX capabilities based on the EGL capabilities of the glamor
* renderer for the screen. Without this you will get whatever swrast
* can do, which often does not include things like multisample visuals.
*/
#include <xwayland-config.h>
#include "xwayland.h"
#define MESA_EGL_NO_X11_HEADERS
// #include <EGL/egl.h>
#include <epoxy/egl.h>
#include "glxserver.h"
#include "glxutil.h"
#include "compint.h"
#include <X11/extensions/composite.h>
#include "glamor_context.h"
#include "glamor.h"
/* Can't get these from <GL/glx.h> since it pulls in client headers */
#define GLX_RGBA_BIT 0x00000001
#define GLX_WINDOW_BIT 0x00000001
#define GLX_PIXMAP_BIT 0x00000002
#define GLX_PBUFFER_BIT 0x00000004
#define GLX_NONE 0x8000
#define GLX_SLOW_CONFIG 0x8001
#define GLX_TRUE_COLOR 0x8002
#define GLX_DIRECT_COLOR 0x8003
#define GLX_NON_CONFORMANT_CONFIG 0x800D
#define GLX_DONT_CARE 0xFFFFFFFF
#define GLX_RGBA_FLOAT_BIT_ARB 0x00000004
#define GLX_SWAP_UNDEFINED_OML 0x8063
struct egl_config {
__GLXconfig base;
EGLConfig config;
};
struct egl_screen {
__GLXscreen base;
EGLDisplay display;
EGLConfig *configs;
};
static void
egl_screen_destroy(__GLXscreen *_screen)
{
struct egl_screen *screen = (struct egl_screen *)_screen;
/* XXX do we leak the fbconfig list? */
free(screen->configs);
__glXScreenDestroy(_screen);
free(_screen);
}
static void
egl_drawable_destroy(__GLXdrawable *draw)
{
free(draw);
}
static GLboolean
egl_drawable_swap_buffers(ClientPtr client, __GLXdrawable *draw)
{
return GL_FALSE;
}
static void
egl_drawable_copy_sub_buffer(__GLXdrawable *draw, int x, int y, int w, int h)
{
}
static void
egl_drawable_wait_x(__GLXdrawable *draw)
{
glamor_block_handler(draw->pDraw->pScreen);
}
static void
egl_drawable_wait_gl(__GLXdrawable *draw)
{
}
static __GLXdrawable *
egl_create_glx_drawable(ClientPtr client, __GLXscreen *screen,
DrawablePtr draw, XID drawid, int type,
XID glxdrawid, __GLXconfig *modes)
{
__GLXdrawable *ret;
ret = calloc(1, sizeof *ret);
if (!ret)
return NULL;
if (!__glXDrawableInit(ret, screen, draw, type, glxdrawid, modes)) {
free(ret);
return NULL;
}
ret->destroy = egl_drawable_destroy;
ret->swapBuffers = egl_drawable_swap_buffers;
ret->copySubBuffer = egl_drawable_copy_sub_buffer;
ret->waitX = egl_drawable_wait_x;
ret->waitGL = egl_drawable_wait_gl;
return ret;
}
/*
* TODO:
*
* - figure out sRGB
* - bindToTextureTargets is suspicious
* - better channel mask setup
* - drawable type masks is suspicious
*/
static struct egl_config *
translate_eglconfig(struct egl_screen *screen, EGLConfig hc,
struct egl_config *chain, Bool direct_color,
Bool double_buffer)
{
EGLint value;
struct egl_config *c = calloc(1, sizeof *c);
if (!c)
return chain;
/* constants. changing these requires (at least) new EGL extensions */
c->base.stereoMode = GL_FALSE;
c->base.numAuxBuffers = 0;
c->base.level = 0;
c->base.transparentAlpha = 0;
c->base.transparentIndex = 0;
c->base.transparentPixel = GLX_NONE;
c->base.visualSelectGroup = 0;
c->base.indexBits = 0;
c->base.optimalPbufferWidth = 0;
c->base.optimalPbufferHeight = 0;
c->base.bindToMipmapTexture = 0;
c->base.bindToTextureTargets = GLX_DONT_CARE;
c->base.sRGBCapable = 0;
c->base.swapMethod = GLX_SWAP_UNDEFINED_OML;
/* this is... suspect */
c->base.drawableType = GLX_WINDOW_BIT | GLX_PIXMAP_BIT | GLX_PBUFFER_BIT;
/* hmm */
c->base.bindToTextureRgb = GL_TRUE;
c->base.bindToTextureRgba = GL_TRUE;
/*
* glx conformance failure: there's no such thing as accumulation
* buffers in EGL. they should be emulable with shaders and fbos,
* but i'm pretty sure nobody's using this feature since it's
* entirely software. note that glx conformance merely requires
* that an accum buffer _exist_, not a minimum bitness.
*/
c->base.accumRedBits = 0;
c->base.accumGreenBits = 0;
c->base.accumBlueBits = 0;
c->base.accumAlphaBits = 0;
/* parametric state */
if (direct_color)
c->base.visualType = GLX_DIRECT_COLOR;
else
c->base.visualType = GLX_TRUE_COLOR;
if (double_buffer)
c->base.doubleBufferMode = GL_TRUE;
else
c->base.doubleBufferMode = GL_FALSE;
/* direct-mapped state */
#define GET(attr, slot) \
eglGetConfigAttrib(screen->display, hc, attr, &c->base.slot)
GET(EGL_RED_SIZE, redBits);
GET(EGL_GREEN_SIZE, greenBits);
GET(EGL_BLUE_SIZE, blueBits);
GET(EGL_ALPHA_SIZE, alphaBits);
GET(EGL_BUFFER_SIZE, rgbBits);
GET(EGL_DEPTH_SIZE, depthBits);
GET(EGL_STENCIL_SIZE, stencilBits);
GET(EGL_TRANSPARENT_RED_VALUE, transparentRed);
GET(EGL_TRANSPARENT_GREEN_VALUE, transparentGreen);
GET(EGL_TRANSPARENT_BLUE_VALUE, transparentBlue);
GET(EGL_SAMPLE_BUFFERS, sampleBuffers);
GET(EGL_SAMPLES, samples);
if (c->base.renderType & GLX_PBUFFER_BIT) {
GET(EGL_MAX_PBUFFER_WIDTH, maxPbufferWidth);
GET(EGL_MAX_PBUFFER_HEIGHT, maxPbufferHeight);
GET(EGL_MAX_PBUFFER_PIXELS, maxPbufferPixels);
}
#undef GET
/* derived state: config caveats */
eglGetConfigAttrib(screen->display, hc, EGL_CONFIG_CAVEAT, &value);
if (value == EGL_NONE)
c->base.visualRating = GLX_NONE;
else if (value == EGL_SLOW_CONFIG)
c->base.visualRating = GLX_SLOW_CONFIG;
else if (value == EGL_NON_CONFORMANT_CONFIG)
c->base.visualRating = GLX_NON_CONFORMANT_CONFIG;
/* else panic */
/* derived state: float configs */
c->base.renderType = GLX_RGBA_BIT;
if (eglGetConfigAttrib(screen->display, hc, EGL_COLOR_COMPONENT_TYPE_EXT,
&value) == EGL_TRUE) {
if (value == EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT) {
c->base.renderType = GLX_RGBA_FLOAT_BIT_ARB;
}
/* else panic */
}
/* map to the backend's config */
c->config = hc;
/*
* XXX do something less ugly
*/
if (c->base.renderType == GLX_RGBA_BIT) {
if (c->base.redBits == 5 &&
(c->base.rgbBits == 15 || c->base.rgbBits == 16)) {
c->base.blueMask = 0x0000001f;
if (c->base.alphaBits) {
c->base.greenMask = 0x000003e0;
c->base.redMask = 0x00007c00;
c->base.alphaMask = 0x00008000;
} else {
c->base.greenMask = 0x000007e0;
c->base.redMask = 0x0000f800;
c->base.alphaMask = 0x00000000;
}
}
else if (c->base.redBits == 8 &&
(c->base.rgbBits == 24 || c->base.rgbBits == 32)) {
c->base.blueMask = 0x000000ff;
c->base.greenMask = 0x0000ff00;
c->base.redMask = 0x00ff0000;
if (c->base.alphaBits)
/* assume all remaining bits are alpha */
c->base.alphaMask = 0xff000000;
}
else if (c->base.redBits == 10 &&
(c->base.rgbBits == 30 || c->base.rgbBits == 32)) {
c->base.blueMask = 0x000003ff;
c->base.greenMask = 0x000ffc00;
c->base.redMask = 0x3ff00000;
if (c->base.alphaBits)
/* assume all remaining bits are alpha */
c->base.alphaMask = 0xc000000;
}
}
c->base.next = chain ? &chain->base : NULL;
return c;
}
static __GLXconfig *
egl_mirror_configs(ScreenPtr pScreen, struct egl_screen *screen)
{
int i, j, k, nconfigs;
struct egl_config *c = NULL;
EGLConfig *host_configs = NULL;
Bool offon[] = { FALSE, TRUE };
eglGetConfigs(screen->display, NULL, 0, &nconfigs);
if (!(host_configs = calloc(nconfigs, sizeof *host_configs)))
return NULL;
eglGetConfigs(screen->display, host_configs, nconfigs, &nconfigs);
/* We walk the EGL configs backwards to make building the
* ->next chain easier.
*/
for (i = nconfigs - 1; i > 0; i--)
for (j = 0; j < 2; j++) /* direct_color */
for (k = 0; k < 2; k++) /* direct_color */
c = translate_eglconfig(screen, host_configs[i], c,
/* direct_color */ offon[j],
/* double_buffer */ offon[k]
);
screen->configs = host_configs;
return c ? &c->base : NULL;
}
static __GLXscreen *
egl_screen_probe(ScreenPtr pScreen)
{
struct egl_screen *screen;
struct xwl_screen *xwl_screen = xwl_screen_get(pScreen);
__GLXscreen *base;
if (enableIndirectGLX)
return NULL; /* not implemented */
if (!(screen = calloc(1, sizeof *screen)))
return NULL;
base = &screen->base;
base->destroy = egl_screen_destroy;
base->createDrawable = egl_create_glx_drawable;
/* base.swapInterval = NULL; */
screen->display = xwl_screen->glamor_ctx->display;
__glXInitExtensionEnableBits(screen->base.glx_enable_bits);
__glXEnableExtension(base->glx_enable_bits, "GLX_ARB_context_flush_control");
__glXEnableExtension(base->glx_enable_bits, "GLX_ARB_create_context");
__glXEnableExtension(base->glx_enable_bits, "GLX_ARB_create_context_no_error");
__glXEnableExtension(base->glx_enable_bits, "GLX_ARB_create_context_profile");
__glXEnableExtension(base->glx_enable_bits, "GLX_ARB_create_context_robustness");
__glXEnableExtension(base->glx_enable_bits, "GLX_ARB_fbconfig_float");
__glXEnableExtension(base->glx_enable_bits, "GLX_EXT_create_context_es2_profile");
__glXEnableExtension(base->glx_enable_bits, "GLX_EXT_create_context_es_profile");
__glXEnableExtension(base->glx_enable_bits, "GLX_EXT_fbconfig_packed_float");
__glXEnableExtension(base->glx_enable_bits, "GLX_EXT_framebuffer_sRGB");
__glXEnableExtension(base->glx_enable_bits, "GLX_EXT_no_config_context");
__glXEnableExtension(base->glx_enable_bits, "GLX_EXT_texture_from_pixmap");
__glXEnableExtension(base->glx_enable_bits, "GLX_MESA_copy_sub_buffer");
// __glXEnableExtension(base->glx_enable_bits, "GLX_SGI_swap_control");
base->fbconfigs = egl_mirror_configs(pScreen, screen);
if (!base->fbconfigs) {
free(screen);
return NULL;
}
__glXScreenInit(base, pScreen);
__glXsetGetProcAddress(eglGetProcAddress);
return base;
}
__GLXprovider glamor_provider = {
egl_screen_probe,
"glamor",
NULL
};

View file

@ -2661,6 +2661,7 @@ xwl_pointer_warp_emulator_maybe_lock(struct xwl_pointer_warp_emulator *warp_emul
*/
if (pointer_grab &&
!pointer_grab->ownerEvents &&
sprite &&
XYToWindow(sprite, x, y) != xwl_seat->focus_window->window)
return;

View file

@ -98,7 +98,8 @@ 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");
ErrorF("-listenfd fd add give fd as a listen socket\n");
ErrorF("-listen fd deprecated, use \"-listenfd\" instead\n");
ErrorF("-eglstream use eglstream backend for nvidia GPUs\n");
}
@ -106,6 +107,17 @@ static int wm_fd = -1;
static int listen_fds[5] = { -1, -1, -1, -1, -1 };
static int listen_fd_count = 0;
static void
xwl_add_listen_fd(int argc, char *argv[], int i)
{
NoListenAll = TRUE;
if (listen_fd_count == ARRAY_SIZE(listen_fds))
FatalError("Too many -listen arguments given, max is %zu\n",
ARRAY_SIZE(listen_fds));
listen_fds[listen_fd_count++] = atoi(argv[i + 1]);
}
int
ddxProcessArgument(int argc, char *argv[], int i)
{
@ -115,12 +127,20 @@ ddxProcessArgument(int argc, char *argv[], int i)
else if (strcmp(argv[i], "-listen") == 0) {
CHECK_FOR_REQUIRED_ARGUMENTS(1);
NoListenAll = TRUE;
if (listen_fd_count == ARRAY_SIZE(listen_fds))
FatalError("Too many -listen arguments given, max is %zu\n",
ARRAY_SIZE(listen_fds));
/* Not an FD */
if (!isdigit(*argv[i + 1]))
return 0;
listen_fds[listen_fd_count++] = atoi(argv[i + 1]);
LogMessage(X_WARNING, "Option \"-listen\" for file descriptors is deprecated\n"
"Please use \"-listenfd\" instead.\n");
xwl_add_listen_fd (argc, argv, i);
return 2;
}
else if (strcmp(argv[i], "-listenfd") == 0) {
CHECK_FOR_REQUIRED_ARGUMENTS(1);
xwl_add_listen_fd (argc, argv, i);
return 2;
}
else if (strcmp(argv[i], "-wm") == 0) {

View file

@ -485,4 +485,9 @@ static inline void xwl_glamor_init_eglstream(struct xwl_screen *xwl_screen)
}
#endif
#ifdef GLXEXT
#include "glx_extinit.h"
extern __GLXprovider glamor_provider;
#endif
#endif

View file

@ -716,6 +716,13 @@ winUseMsg(void)
"\tthe updated region when num_boxes, or more, are in the\n"
"\tupdated region.\n");
ErrorF("-[no]compositealpha\n"
"\tX windows with per-pixel alpha are composited into the Windows desktop.\n");
ErrorF("-[no]compositewm\n"
"\tUse the Composite extension to keep a bitmap image of each top-level\n"
"\tX window, so window contents which are occluded show correctly in\n"
"\ttask bar and task switcher previews.\n");
#ifdef XWIN_XF86CONFIG
ErrorF("-config\n" "\tSpecify a configuration file.\n");
@ -798,7 +805,7 @@ winUseMsg(void)
"\tSpecify an optional refresh rate to use in fullscreen mode\n"
"\twith a DirectDraw engine.\n");
ErrorF("-resize=none|scrollbars|randr"
ErrorF("-resize=none|scrollbars|randr\n"
"\tIn windowed mode, [don't] allow resizing of the window. 'scrollbars'\n"
"\tmode gives the window scrollbars as needed, 'randr' mode uses the RANR\n"
"\textension to resize the X screen. 'randr' is the default.\n");
@ -974,8 +981,7 @@ InitOutput(ScreenInfo * pScreenInfo, int argc, char *argv[])
for (iMonitor = 1; ; iMonitor++)
{
struct GetMonitorInfoData data;
QueryMonitor(iMonitor, &data);
if (data.bMonitorSpecifiedExists)
if (QueryMonitor(iMonitor, &data))
{
MONITORINFO mi;
mi.cbSize = sizeof(MONITORINFO);

View file

@ -27,7 +27,7 @@ SRCS_MULTIWINDOW = \
winmultiwindowwndproc.c \
propertystore.h \
winSetAppUserModelID.c
MULTIWINDOW_SYS_LIBS = -lshlwapi -lole32
MULTIWINDOW_SYS_LIBS = -lshlwapi -lole32 -ldwmapi
SRCS_RANDR = \
winrandr.c

View file

@ -170,6 +170,21 @@ on its own is equivalent to \fB\-resize=randr\fP
Add the host name to the window title for X applications which are running
on remote hosts, when that information is available and it's useful to do so.
The default is enabled.
.TP 8
.B \-[no]compositewm
Use Composite extension redirection to maintain a bitmap image of each top-level
X window, so window contents which are occluded show correctly in task bar and
task switcher previews.
The default is enabled.
.TP 8
.B \-[no]compositealpha
X windows with per-pixel alpha are composited into the \fIWindows\fP desktop
(i.e. a \fIWindows\fP window can be seen through any transparency in an X window
placed over it).
This option has no effect on Windows 8 and 8.1.
This option has no effect if \fB-compositewm\fP is disabled.
The default is disabled.
.SH OPTIONS CONTROLLING WINDOWS INTEGRATION
.TP 8
@ -206,6 +221,7 @@ The default is enabled.
.TP 8
.B \-swcursor
Disable the usage of the \fIWindows\fP cursor and use the X11 software cursor instead.
This option is ignored if \fB-compositewm\fP is also enabled.
.TP 8
.B \-[no]trayicon
Do not create a tray icon. Default is to create one

View file

@ -44,7 +44,7 @@ srcs_windows += [
'propertystore.h',
'winSetAppUserModelID.c',
]
xwin_sys_libs += ['-lshlwapi', '-lole32']
xwin_sys_libs += ['-lshlwapi', '-lole32', '-ldwmapi']
srcs_windows += [
'winrandr.c',
@ -137,6 +137,7 @@ xwin_dep = [
dependency('xcb-image'),
dependency('xcb-ewmh'),
dependency('xcb-icccm'),
dependency('xcb-composite'),
]
executable(

View file

@ -268,6 +268,8 @@ typedef Bool (*winFinishScreenInitProcPtr) (int, ScreenPtr, int, char **);
typedef Bool (*winBltExposedRegionsProcPtr) (ScreenPtr);
typedef Bool (*winBltExposedWindowRegionProcPtr) (ScreenPtr, WindowPtr);
typedef Bool (*winActivateAppProcPtr) (ScreenPtr);
typedef Bool (*winRedrawScreenProcPtr) (ScreenPtr pScreen);
@ -294,11 +296,10 @@ typedef Bool (*winCreateScreenResourcesProc) (ScreenPtr);
*/
typedef struct {
HDC hdcSelected;
HBITMAP hBitmap;
BYTE *pbBits;
DWORD dwScanlineBytes;
void *pbBits;
BITMAPINFOHEADER *pbmih;
BOOL owned;
} winPrivPixmapRec, *winPrivPixmapPtr;
/*
@ -389,6 +390,7 @@ typedef struct {
Bool fDecoration;
Bool fRootless;
Bool fMultiWindow;
Bool fCompositeWM;
Bool fMultiMonitorOverride;
Bool fMultipleMonitors;
Bool fLessPointer;
@ -479,6 +481,7 @@ typedef struct _winPrivScreenRec {
winCreateBoundingWindowProcPtr pwinCreateBoundingWindow;
winFinishScreenInitProcPtr pwinFinishScreenInit;
winBltExposedRegionsProcPtr pwinBltExposedRegions;
winBltExposedWindowRegionProcPtr pwinBltExposedWindowRegion;
winActivateAppProcPtr pwinActivateApp;
winRedrawScreenProcPtr pwinRedrawScreen;
winRealizeInstalledPaletteProcPtr pwinRealizeInstalledPalette;
@ -507,6 +510,7 @@ typedef struct _winPrivScreenRec {
ResizeWindowProcPtr ResizeWindow;
MoveWindowProcPtr MoveWindow;
SetShapeProcPtr SetShape;
ModifyPixmapHeaderProcPtr ModifyPixmapHeader;
winCursorRec cursor;
@ -942,6 +946,19 @@ void
winCopyWindowMultiWindow(WindowPtr pWin, DDXPointRec oldpt,
RegionPtr oldRegion);
PixmapPtr
winCreatePixmapMultiwindow(ScreenPtr pScreen, int width, int height, int depth,
unsigned usage_hint);
Bool
winDestroyPixmapMultiwindow(PixmapPtr pPixmap);
Bool
winModifyPixmapHeaderMultiwindow(PixmapPtr pPixmap,
int width,
int height,
int depth,
int bitsPerPixel, int devKind, void *pPixData);
XID
winGetWindowID(WindowPtr pWin);

View file

@ -59,6 +59,7 @@ HWND g_hDlgAbout = NULL;
const char *g_pszQueryHost = NULL;
Bool g_fXdmcpEnabled = FALSE;
Bool g_fAuthEnabled = FALSE;
Bool g_fCompositeAlpha = FALSE;
HICON g_hIconX = NULL;
HICON g_hSmallIconX = NULL;

View file

@ -50,6 +50,7 @@ extern Bool g_fLogInited;
extern Bool g_fAuthEnabled;
extern Bool g_fXdmcpEnabled;
extern Bool g_fCompositeAlpha;
extern Bool g_fNoHelpMessageBox;
extern Bool g_fNativeGl;

View file

@ -191,8 +191,8 @@
#define KEY_BSlash2 /* \ _ 0xcb */ 203
#define KEY_Mute /* Audio Mute */ 152
#define KEY_AudioLower /* Audio Lower */ 168
#define KEY_AudioRaise /* Audio Raise */ 166
#define KEY_AudioLower /* Audio Lower */ 166
#define KEY_AudioRaise /* Audio Raise */ 168
#define KEY_NEXTSONG /* Media next */ 145
#define KEY_PLAYPAUSE /* Media play/pause toggle */ 154

View file

@ -65,6 +65,7 @@ WinKBLayoutRec winKBLayouts[] = {
{0x0000040b, -1, "pc105", "fi", NULL, NULL, "Finnish"},
{0x0000040c, -1, "pc105", "fr", NULL, NULL, "French (Standard)"},
{0x0000080c, -1, "pc105", "be", NULL, NULL, "French (Belgian)"},
{0x0001080c, -1, "pc105", "be", NULL, NULL, "Belgian (Comma)"},
{0x00000c0c, -1, "pc105", "ca", "fr-legacy", NULL,
"French (Canada, Legacy)"},
{0x0000100c, -1, "pc105", "ch", "fr", NULL, "French (Switzerland)"},
@ -82,6 +83,7 @@ WinKBLayoutRec winKBLayouts[] = {
{0x00000416, -1, "pc105", "br", NULL, NULL, "Portuguese (Brazil,ABNT)"},
{0x00010416, -1, "abnt2", "br", NULL, NULL, "Portuguese (Brazil,ABNT2)"},
{0x00000816, -1, "pc105", "pt", NULL, NULL, "Portuguese (Portugal)"},
{0x00000419, -1, "pc105", "ru", NULL, NULL, "Russian"},
{0x0000041a, -1, "pc105", "hr", NULL, NULL, "Croatian"},
{0x0000041d, -1, "pc105", "se", NULL, NULL, "Swedish (Sweden)"},
{0x0000041f, -1, "pc105", "tr", NULL, NULL, "Turkish (Q)"},

View file

@ -39,7 +39,7 @@ from The Open Group.
*/
static
wBOOL CALLBACK
WINBOOL CALLBACK
getMonitorInfo(HMONITOR hMonitor, HDC hdc, LPRECT rect, LPARAM _data)
{
struct GetMonitorInfoData *data = (struct GetMonitorInfoData *) _data;
@ -70,5 +70,5 @@ QueryMonitor(int i, struct GetMonitorInfoData *data)
/* query information */
EnumDisplayMonitors(NULL, NULL, getMonitorInfo, (LPARAM) data);
return TRUE;
return data->bMonitorSpecifiedExists;
}

View file

@ -960,3 +960,259 @@ winAdjustXWindow(WindowPtr pWin, HWND hwnd)
#undef WIDTH
#undef HEIGHT
}
/*
Helper function for creating a DIB to back a pixmap
*/
static HBITMAP winCreateDIB(ScreenPtr pScreen, int width, int height, int bpp, void **ppvBits, BITMAPINFOHEADER **ppbmih)
{
winScreenPriv(pScreen);
BITMAPV4HEADER *pbmih = NULL;
HBITMAP hBitmap = NULL;
/* Allocate bitmap info header */
pbmih = malloc(sizeof(BITMAPV4HEADER) + 256 * sizeof(RGBQUAD));
if (pbmih == NULL) {
ErrorF("winCreateDIB: malloc() failed\n");
return NULL;
}
memset(pbmih, 0, sizeof(BITMAPV4HEADER) + 256 * sizeof(RGBQUAD));
/* Describe bitmap to be created */
pbmih->bV4Size = sizeof(BITMAPV4HEADER);
pbmih->bV4Width = width;
pbmih->bV4Height = -height; /* top-down bitmap */
pbmih->bV4Planes = 1;
pbmih->bV4BitCount = bpp;
if (bpp == 1) {
RGBQUAD *bmiColors = (RGBQUAD *)((char *)pbmih + sizeof(BITMAPV4HEADER));
pbmih->bV4V4Compression = BI_RGB;
bmiColors[1].rgbBlue = 255;
bmiColors[1].rgbGreen = 255;
bmiColors[1].rgbRed = 255;
}
else if (bpp == 8) {
pbmih->bV4V4Compression = BI_RGB;
pbmih->bV4ClrUsed = 0;
}
else if (bpp == 16) {
pbmih->bV4V4Compression = BI_RGB;
pbmih->bV4ClrUsed = 0;
}
else if (bpp == 32) {
pbmih->bV4V4Compression = BI_BITFIELDS;
pbmih->bV4RedMask = pScreenPriv->dwRedMask;
pbmih->bV4GreenMask = pScreenPriv->dwGreenMask;
pbmih->bV4BlueMask = pScreenPriv->dwBlueMask;
pbmih->bV4AlphaMask = 0;
}
else {
ErrorF("winCreateDIB: %d bpp unhandled\n", bpp);
}
/* Create a DIB with a bit pointer */
hBitmap = CreateDIBSection(NULL,
(BITMAPINFO *) pbmih,
DIB_RGB_COLORS, ppvBits, NULL, 0);
if (hBitmap == NULL) {
ErrorF("winCreateDIB: CreateDIBSection() failed\n");
return NULL;
}
/* Store the address of the BMIH in the ppbmih parameter */
*ppbmih = (BITMAPINFOHEADER *)pbmih;
winDebug("winCreateDIB: HBITMAP %p pBMIH %p pBits %p\n", hBitmap, pbmih, *ppvBits);
return hBitmap;
}
/*
* CreatePixmap - See Porting Layer Definition
*/
PixmapPtr
winCreatePixmapMultiwindow(ScreenPtr pScreen, int width, int height, int depth,
unsigned usage_hint)
{
winPrivPixmapPtr pPixmapPriv = NULL;
PixmapPtr pPixmap = NULL;
int bpp, paddedwidth;
/* allocate Pixmap header and privates */
pPixmap = AllocatePixmap(pScreen, 0);
if (!pPixmap)
return NullPixmap;
bpp = BitsPerPixel(depth);
/*
DIBs have 4-byte aligned rows
paddedwidth is the width in bytes, padded to align
i.e. round up the number of bits used by a row so it is a multiple of 32,
then convert to bytes
*/
paddedwidth = (((bpp * width) + 31) & ~31)/8;
/* setup Pixmap header */
pPixmap->drawable.type = DRAWABLE_PIXMAP;
pPixmap->drawable.class = 0;
pPixmap->drawable.pScreen = pScreen;
pPixmap->drawable.depth = depth;
pPixmap->drawable.bitsPerPixel = bpp;
pPixmap->drawable.id = 0;
pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
pPixmap->drawable.x = 0;
pPixmap->drawable.y = 0;
pPixmap->drawable.width = width;
pPixmap->drawable.height = height;
pPixmap->devKind = paddedwidth;
pPixmap->refcnt = 1;
pPixmap->devPrivate.ptr = NULL; // later set to pbBits
pPixmap->master_pixmap = NULL;
#ifdef COMPOSITE
pPixmap->screen_x = 0;
pPixmap->screen_y = 0;
#endif
pPixmap->usage_hint = usage_hint;
/* Check for zero width or height pixmaps */
if (width == 0 || height == 0) {
/* DIBs with a dimension of 0 aren't permitted, so don't try to allocate
a DIB, just set fields and return */
return pPixmap;
}
/* Initialize pixmap privates */
pPixmapPriv = winGetPixmapPriv(pPixmap);
pPixmapPriv->hBitmap = NULL;
pPixmapPriv->pbBits = NULL;
pPixmapPriv->pbmih = NULL;
/* Create a DIB for the pixmap */
pPixmapPriv->hBitmap = winCreateDIB(pScreen, width, height, bpp, &pPixmapPriv->pbBits, &pPixmapPriv->pbmih);
pPixmapPriv->owned = TRUE;
winDebug("winCreatePixmap: pPixmap %p HBITMAP %p pBMIH %p pBits %p\n", pPixmap, pPixmapPriv->hBitmap, pPixmapPriv->pbmih, pPixmapPriv->pbBits);
/* XXX: so why do we need this in privates ??? */
pPixmap->devPrivate.ptr = pPixmapPriv->pbBits;
return pPixmap;
}
/*
* DestroyPixmap - See Porting Layer Definition
*/
Bool
winDestroyPixmapMultiwindow(PixmapPtr pPixmap)
{
winPrivPixmapPtr pPixmapPriv = NULL;
/* Bail early if there is not a pixmap to destroy */
if (pPixmap == NULL) {
return TRUE;
}
/* Decrement reference count, return if nonzero */
--pPixmap->refcnt;
if (pPixmap->refcnt != 0)
return TRUE;
winDebug("winDestroyPixmap: pPixmap %p\n", pPixmap);
/* Get a handle to the pixmap privates */
pPixmapPriv = winGetPixmapPriv(pPixmap);
/* Nothing to do if we don't own the DIB */
if (!pPixmapPriv->owned)
return TRUE;
/* Free GDI bitmap */
if (pPixmapPriv->hBitmap)
DeleteObject(pPixmapPriv->hBitmap);
/* Free the bitmap info header memory */
free(pPixmapPriv->pbmih);
pPixmapPriv->pbmih = NULL;
/* Free the pixmap memory */
free(pPixmap);
pPixmap = NULL;
return TRUE;
}
/*
* ModifyPixmapHeader - See Porting Layer Definition
*/
Bool
winModifyPixmapHeaderMultiwindow(PixmapPtr pPixmap,
int width,
int height,
int depth,
int bitsPerPixel, int devKind, void *pPixData)
{
int i;
winPrivPixmapPtr pPixmapPriv = winGetPixmapPriv(pPixmap);
Bool fResult;
/* reinitialize everything */
pPixmap->drawable.depth = depth;
pPixmap->drawable.bitsPerPixel = bitsPerPixel;
pPixmap->drawable.id = 0;
pPixmap->drawable.x = 0;
pPixmap->drawable.y = 0;
pPixmap->drawable.width = width;
pPixmap->drawable.height = height;
pPixmap->devKind = devKind;
pPixmap->refcnt = 1;
pPixmap->devPrivate.ptr = pPixData;
pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
/*
This can be used for some out-of-order initialization on the screen
pixmap, which is the only case we can properly support.
*/
/* Look for which screen this pixmap corresponds to */
for (i = 0; i < screenInfo.numScreens; i++) {
ScreenPtr pScreen = screenInfo.screens[i];
winScreenPriv(pScreen);
winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
if (pScreenInfo->pfb == pPixData)
{
/* and initialize pixmap privates from screen privates */
pPixmapPriv->hBitmap = pScreenPriv->hbmpShadow;
pPixmapPriv->pbBits = pScreenInfo->pfb;
pPixmapPriv->pbmih = pScreenPriv->pbmih;
/* mark these not to get released by DestroyPixmap */
pPixmapPriv->owned = FALSE;
return TRUE;
}
}
/* Otherwise, since creating a DIBSection from arbitrary memory is not
* possible, fallback to normal. If needed, we can create a DIBSection with
* a copy of the bits later (see comment about a potential slow-path in
* winBltExposedWindowRegionShadowGDI()). */
pPixmapPriv->hBitmap = 0;
pPixmapPriv->pbBits = 0;
pPixmapPriv->pbmih = 0;
pPixmapPriv->owned = FALSE;
winDebug("winModifyPixmapHeaderMultiwindow: falling back\n");
{
ScreenPtr pScreen = pPixmap->drawable.pScreen;
winScreenPriv(pScreen);
WIN_UNWRAP(ModifyPixmapHeader);
fResult = (*pScreen->ModifyPixmapHeader) (pPixmap, width, height, depth, bitsPerPixel, devKind, pPixData);
WIN_WRAP(ModifyPixmapHeader, winModifyPixmapHeaderMultiwindow);
}
return fResult;
}

View file

@ -49,6 +49,7 @@
#include <xcb/xcb_icccm.h>
#include <xcb/xcb_ewmh.h>
#include <xcb/xcb_aux.h>
#include <xcb/composite.h>
#include <X11/Xwindows.h>
@ -116,6 +117,7 @@ typedef struct _WMInfo {
xcb_atom_t atmUtf8String;
xcb_atom_t atmNetWmName;
xcb_ewmh_connection_t ewmh;
Bool fCompositeWM;
} WMInfoRec, *WMInfoPtr;
typedef struct _WMProcArgRec {
@ -1038,6 +1040,8 @@ winMultiWindowXMsgProc(void *pArg)
xcb_atom_t atmWindowState, atmMotifWmHints, atmWindowType, atmNormalHints;
int iReturn;
xcb_auth_info_t *auth_info;
xcb_screen_t *root_screen;
xcb_window_t root_window_id;
winDebug("winMultiWindowXMsgProc - Hello\n");
@ -1110,11 +1114,11 @@ winMultiWindowXMsgProc(void *pArg)
pthread_exit(NULL);
}
{
/* Get root window id */
xcb_screen_t *root_screen = xcb_aux_get_screen(pProcArg->conn, pProcArg->dwScreen);
xcb_window_t root_window_id = root_screen->root;
/* Get root window id */
root_screen = xcb_aux_get_screen(pProcArg->conn, pProcArg->dwScreen);
root_window_id = root_screen->root;
{
/* Set WM_ICON_SIZE property indicating desired icon sizes */
typedef struct {
uint32_t min_width, min_height;
@ -1152,6 +1156,41 @@ winMultiWindowXMsgProc(void *pArg)
*/
intern_atom(pProcArg->conn, "WM_STATE");
/*
Enable Composite extension and redirect subwindows of the root window
*/
if (pProcArg->pWMInfo->fCompositeWM) {
const char *extension_name = "Composite";
xcb_query_extension_cookie_t cookie;
xcb_query_extension_reply_t *reply;
cookie = xcb_query_extension(pProcArg->conn, strlen(extension_name), extension_name);
reply = xcb_query_extension_reply(pProcArg->conn, cookie, NULL);
if (reply && (reply->present)) {
xcb_composite_redirect_subwindows(pProcArg->conn,
root_window_id,
XCB_COMPOSITE_REDIRECT_AUTOMATIC);
/*
We use automatic updating of the root window for two
reasons:
1) redirected window contents are mirrored to the root
window so that the root window draws correctly when shown.
2) updating the root window causes damage against the
shadow framebuffer, which ultimately causes WM_PAINT to be
sent to the affected window(s) to cause the damage regions
to be redrawn.
*/
ErrorF("Using Composite redirection\n");
free(reply);
}
}
/* Loop until we explicitly break out */
while (1) {
xcb_generic_event_t *event;
@ -1351,7 +1390,7 @@ winInitWM(void **ppWMInfo,
pthread_t * ptWMProc,
pthread_t * ptXMsgProc,
pthread_mutex_t * ppmServerStarted,
int dwScreen, HWND hwndScreen)
int dwScreen, HWND hwndScreen, Bool compositeWM)
{
WMProcArgPtr pArg = malloc(sizeof(WMProcArgRec));
WMInfoPtr pWMInfo = malloc(sizeof(WMInfoRec));
@ -1373,6 +1412,7 @@ winInitWM(void **ppWMInfo,
/* Set a return pointer to the Window Manager info structure */
*ppWMInfo = pWMInfo;
pWMInfo->fCompositeWM = compositeWM;
/* Setup the argument structure for the thread function */
pArg->dwScreen = dwScreen;

View file

@ -35,12 +35,18 @@
#ifdef HAVE_XWIN_CONFIG_H
#include <xwin-config.h>
#endif
#include "win.h"
#include "dixevents.h"
#include "winmultiwindowclass.h"
#include "winprefs.h"
#include "winmsg.h"
#include "inputstr.h"
#include <dwmapi.h>
#ifndef WM_DWMCOMPOSITIONCHANGED
#define WM_DWMCOMPOSITIONCHANGED 0x031e
#endif
extern void winUpdateWindowPosition(HWND hWnd, HWND * zstyle);
@ -294,6 +300,113 @@ winStartMousePolling(winPrivScreenPtr s_pScreenPriv)
MOUSE_POLLING_INTERVAL, NULL);
}
/* Undocumented */
typedef struct _ACCENTPOLICY
{
ULONG AccentState;
ULONG AccentFlags;
ULONG GradientColor;
ULONG AnimationId;
} ACCENTPOLICY;
#define ACCENT_ENABLE_BLURBEHIND 3
typedef struct _WINCOMPATTR
{
DWORD attribute;
PVOID pData;
ULONG dataSize;
} WINCOMPATTR;
#define WCA_ACCENT_POLICY 19
typedef WINBOOL WINAPI (*PFNSETWINDOWCOMPOSITIONATTRIBUTE)(HWND, WINCOMPATTR *);
static void
CheckForAlpha(HWND hWnd, WindowPtr pWin, winScreenInfo *pScreenInfo)
{
/* Check (once) which API we should use */
static Bool doOnce = TRUE;
static PFNSETWINDOWCOMPOSITIONATTRIBUTE pSetWindowCompositionAttribute = NULL;
static Bool useDwmEnableBlurBehindWindow = FALSE;
if (doOnce)
{
OSVERSIONINFOEX osvi = {0};
osvi.dwOSVersionInfoSize = sizeof(osvi);
GetVersionEx((LPOSVERSIONINFO)&osvi);
/* SetWindowCompositionAttribute() exists on Windows 7 and later,
but doesn't work for this purpose, so first check for Windows 10
or later */
if (osvi.dwMajorVersion >= 10)
{
HMODULE hUser32 = GetModuleHandle("user32");
if (hUser32)
pSetWindowCompositionAttribute = (PFNSETWINDOWCOMPOSITIONATTRIBUTE) GetProcAddress(hUser32, "SetWindowCompositionAttribute");
winDebug("SetWindowCompositionAttribute %s\n", pSetWindowCompositionAttribute ? "found" : "not found");
}
/* On Windows 7 and Windows Vista, use DwmEnableBlurBehindWindow() */
else if ((osvi.dwMajorVersion == 6) && (osvi.dwMinorVersion <= 1))
{
useDwmEnableBlurBehindWindow = TRUE;
}
/* On Windows 8 and Windows 8.1, using the alpha channel on those
seems near impossible, so we don't do anything. */
doOnce = FALSE;
}
/* alpha-channel use is wanted */
if (!g_fCompositeAlpha || !pScreenInfo->fCompositeWM)
return;
/* Image has alpha ... */
if (pWin->drawable.depth != 32)
return;
/* ... and we can do something useful with it? */
if (pSetWindowCompositionAttribute)
{
WINBOOL rc;
/* Use the (undocumented) SetWindowCompositionAttribute, if
available, to turn on alpha channel use on Windows 10. */
ACCENTPOLICY policy = { ACCENT_ENABLE_BLURBEHIND, 0, 0, 0 } ;
WINCOMPATTR data = { WCA_ACCENT_POLICY, &policy, sizeof(ACCENTPOLICY) };
/* This turns on DWM looking at the alpha-channel of this window */
winDebug("enabling alpha for XID %08x hWnd %p, using SetWindowCompositionAttribute()\n", (unsigned int)pWin->drawable.id, hWnd);
rc = pSetWindowCompositionAttribute(hWnd, &data);
if (!rc)
ErrorF("SetWindowCompositionAttribute failed: %d\n", (int)GetLastError());
}
else if (useDwmEnableBlurBehindWindow)
{
HRESULT rc;
WINBOOL enabled;
rc = DwmIsCompositionEnabled(&enabled);
if ((rc == S_OK) && enabled)
{
/* Use DwmEnableBlurBehindWindow, to turn on alpha channel
use on Windows Vista and Windows 7 */
DWM_BLURBEHIND bbh;
bbh.dwFlags = DWM_BB_ENABLE | DWM_BB_BLURREGION | DWM_BB_TRANSITIONONMAXIMIZED;
bbh.fEnable = TRUE;
bbh.hRgnBlur = NULL;
bbh.fTransitionOnMaximized = TRUE; /* What does this do ??? */
/* This terribly-named function actually controls if DWM
looks at the alpha channel of this window */
winDebug("enabling alpha for XID %08x hWnd %p, using DwmEnableBlurBehindWindow()\n", (unsigned int)pWin->drawable.id, hWnd);
rc = DwmEnableBlurBehindWindow(hWnd, &bbh);
if (rc != S_OK)
ErrorF("DwmEnableBlurBehindWindow failed: %x, %d\n", (int)rc, (int)GetLastError());
}
}
}
/*
* winTopLevelWindowProc - Window procedure for all top-level Windows windows.
*/
@ -302,7 +415,6 @@ LRESULT CALLBACK
winTopLevelWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
POINT ptMouse;
HDC hdcUpdate;
PAINTSTRUCT ps;
WindowPtr pWin = NULL;
winPrivWinPtr pWinPriv = NULL;
@ -323,6 +435,20 @@ winTopLevelWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
lParam);
#endif
/*
If this is WM_CREATE, set up the Windows window properties which point to
X window information, before we populate local convenience variables...
*/
if (message == WM_CREATE) {
SetProp(hwnd,
WIN_WINDOW_PROP,
(HANDLE) ((LPCREATESTRUCT) lParam)->lpCreateParams);
SetProp(hwnd,
WIN_WID_PROP,
(HANDLE) (INT_PTR)winGetWindowID(((LPCREATESTRUCT) lParam)->
lpCreateParams));
}
/* Check if the Windows window property for our X window pointer is valid */
if ((pWin = GetProp(hwnd, WIN_WINDOW_PROP)) != NULL) {
/* Our X window pointer is valid */
@ -383,18 +509,6 @@ winTopLevelWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
/* Branch on message type */
switch (message) {
case WM_CREATE:
/* */
SetProp(hwnd,
WIN_WINDOW_PROP,
(HANDLE) ((LPCREATESTRUCT) lParam)->lpCreateParams);
/* */
SetProp(hwnd,
WIN_WID_PROP,
(HANDLE) (INT_PTR) winGetWindowID(((LPCREATESTRUCT) lParam)->
lpCreateParams));
/*
* Make X windows' Z orders sync with Windows windows because
* there can be AlwaysOnTop windows overlapped on the window
@ -415,6 +529,8 @@ winTopLevelWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR) XMING_SIGNATURE);
CheckForAlpha(hwnd, pWin, s_pScreenInfo);
return 0;
case WM_INIT_SYS_MENU:
@ -457,18 +573,9 @@ winTopLevelWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
case WM_PAINT:
/* Only paint if our window handle is valid */
if (hwndScreen == NULL)
if (hwnd == NULL)
break;
/* BeginPaint gives us an hdc that clips to the invalidated region */
hdcUpdate = BeginPaint(hwnd, &ps);
/* Avoid the BitBlt's if the PAINTSTRUCT is bogus */
if (ps.rcPaint.right == 0 && ps.rcPaint.bottom == 0 &&
ps.rcPaint.left == 0 && ps.rcPaint.top == 0) {
EndPaint(hwnd, &ps);
return 0;
}
#ifdef XWIN_GLX_WINDOWS
if (pWinPriv->fWglUsed) {
/*
@ -478,36 +585,16 @@ winTopLevelWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
XXX: For now, just leave it alone, but ideally we want to send an expose event to
the window so it really redraws the affected region...
*/
BeginPaint(hwnd, &ps);
ValidateRect(hwnd, &(ps.rcPaint));
EndPaint(hwnd, &ps);
}
else
#endif
/* Try to copy from the shadow buffer */
if (!BitBlt(hdcUpdate,
ps.rcPaint.left, ps.rcPaint.top,
ps.rcPaint.right - ps.rcPaint.left,
ps.rcPaint.bottom - ps.rcPaint.top,
s_pScreenPriv->hdcShadow,
ps.rcPaint.left + pWin->drawable.x,
ps.rcPaint.top + pWin->drawable.y, SRCCOPY)) {
LPVOID lpMsgBuf;
/* Call the engine dependent repainter */
if (*s_pScreenPriv->pwinBltExposedWindowRegion)
(*s_pScreenPriv->pwinBltExposedWindowRegion) (s_pScreen, pWin);
/* Display a fancy error message */
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf, 0, NULL);
ErrorF("winTopLevelWindowProc - BitBlt failed: %s\n",
(LPSTR) lpMsgBuf);
LocalFree(lpMsgBuf);
}
/* EndPaint frees the DC */
EndPaint(hwnd, &ps);
return 0;
case WM_MOUSEMOVE:
@ -1142,6 +1229,12 @@ winTopLevelWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
}
break;
case WM_DWMCOMPOSITIONCHANGED:
/* This message is only sent on Vista/W7 */
CheckForAlpha(hwnd, pWin, s_pScreenInfo);
return 0;
default:
break;
}

View file

@ -128,6 +128,7 @@ winInitializeScreenDefaults(void)
defaultScreenInfo.fDecoration = TRUE;
defaultScreenInfo.fRootless = FALSE;
defaultScreenInfo.fMultiWindow = FALSE;
defaultScreenInfo.fCompositeWM = TRUE;
defaultScreenInfo.fMultiMonitorOverride = FALSE;
defaultScreenInfo.fMultipleMonitors = FALSE;
defaultScreenInfo.fLessPointer = FALSE;
@ -308,11 +309,7 @@ ddxProcessArgument(int argc, char *argv[], int i)
if (i + 2 < argc && 1 == sscanf(argv[i + 2], "@%d", (int *) &iMonitor)) {
struct GetMonitorInfoData data;
if (!QueryMonitor(iMonitor, &data)) {
ErrorF
("ddxProcessArgument - screen - Querying monitors failed\n");
}
else if (data.bMonitorSpecifiedExists == TRUE) {
if (QueryMonitor(iMonitor, &data)) {
winErrorFVerb(2,
"ddxProcessArgument - screen - Found Valid ``@Monitor'' = %d arg\n",
iMonitor);
@ -333,8 +330,7 @@ ddxProcessArgument(int argc, char *argv[], int i)
ErrorF
("ddxProcessArgument - screen - Invalid monitor number %d\n",
iMonitor);
UseMsg();
exit(0);
exit(1);
return 0;
}
}
@ -365,11 +361,7 @@ ddxProcessArgument(int argc, char *argv[], int i)
(int *) &iMonitor)) {
struct GetMonitorInfoData data;
if (!QueryMonitor(iMonitor, &data)) {
ErrorF
("ddxProcessArgument - screen - Querying monitors failed\n");
}
else if (data.bMonitorSpecifiedExists == TRUE) {
if (QueryMonitor(iMonitor, &data)) {
g_ScreenInfo[nScreenNum].iMonitor = iMonitor;
g_ScreenInfo[nScreenNum].hMonitor = data.monitorHandle;
g_ScreenInfo[nScreenNum].dwInitialX +=
@ -382,11 +374,9 @@ ddxProcessArgument(int argc, char *argv[], int i)
ErrorF
("ddxProcessArgument - screen - Invalid monitor number %d\n",
iMonitor);
UseMsg();
exit(0);
exit(1);
return 0;
}
}
}
@ -394,11 +384,7 @@ ddxProcessArgument(int argc, char *argv[], int i)
else if (1 == sscanf(argv[i + 2], "%*dx%*d@%d", (int *) &iMonitor)) {
struct GetMonitorInfoData data;
if (!QueryMonitor(iMonitor, &data)) {
ErrorF
("ddxProcessArgument - screen - Querying monitors failed\n");
}
else if (data.bMonitorSpecifiedExists == TRUE) {
if (QueryMonitor(iMonitor, &data)) {
winErrorFVerb(2,
"ddxProcessArgument - screen - Found Valid ``@Monitor'' = %d arg\n",
iMonitor);
@ -413,11 +399,9 @@ ddxProcessArgument(int argc, char *argv[], int i)
ErrorF
("ddxProcessArgument - screen - Invalid monitor number %d\n",
iMonitor);
UseMsg();
exit(0);
exit(1);
return 0;
}
}
}
else if (i + 3 < argc && 1 == sscanf(argv[i + 2], "%d", (int *) &iWidth)
@ -571,6 +555,44 @@ ddxProcessArgument(int argc, char *argv[], int i)
return 1;
}
/*
* Look for the '-compositewm' argument
*/
if (IS_OPTION("-compositewm")) {
screenInfoPtr->fCompositeWM = TRUE;
/* Indicate that we have processed this argument */
return 1;
}
/*
* Look for the '-nocompositewm' argument
*/
if (IS_OPTION("-nocompositewm")) {
screenInfoPtr->fCompositeWM = FALSE;
/* Indicate that we have processed this argument */
return 1;
}
/*
* Look for the '-compositealpha' argument
*/
if (IS_OPTION("-compositealpha")) {
g_fCompositeAlpha = TRUE;
/* Indicate that we have processed this argument */
return 1;
}
/*
* Look for the '-nocompositealpha' argument
*/
if (IS_OPTION("-nocompositealpha")) {
g_fCompositeAlpha = FALSE;
/* Indicate that we have processed this argument */
return 1;
}
/*
* Look for the '-multiplemonitors' argument
*/

View file

@ -42,17 +42,17 @@
static Bool
winRandRGetInfo(ScreenPtr pScreen, Rotation * pRotations)
{
rrScrPrivPtr pRRScrPriv;
RROutputPtr output;
pRRScrPriv = rrGetScrPriv(pScreen);
output = pRRScrPriv->outputs[0];
winDebug("winRandRGetInfo ()\n");
/* Don't support rotations */
*pRotations = RR_Rotate_0;
return TRUE;
}
static void
winRandRUpdateMode(ScreenPtr pScreen, RROutputPtr output)
{
/* Delete previous mode */
if (output->modes[0])
{
@ -83,8 +83,6 @@ winRandRGetInfo(ScreenPtr pScreen, Rotation * pRotations)
mode = RRModeGet(&modeInfo, name);
output->crtc->mode = mode;
}
return TRUE;
}
/*
@ -95,6 +93,7 @@ winDoRandRScreenSetSize(ScreenPtr pScreen,
CARD16 width,
CARD16 height, CARD32 mmWidth, CARD32 mmHeight)
{
rrScrPrivPtr pRRScrPriv;
winScreenPriv(pScreen);
winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
WindowPtr pRoot = pScreen->root;
@ -136,6 +135,10 @@ winDoRandRScreenSetSize(ScreenPtr pScreen,
// and arrange for it to be repainted
pScreen->PaintWindow(pRoot, &pRoot->borderClip, PW_BACKGROUND);
// Set mode to current display size
pRRScrPriv = rrGetScrPriv(pScreen);
winRandRUpdateMode(pScreen, pRRScrPriv->primaryOutput);
/* Indicate that a screen size change took place */
RRScreenSizeNotify(pScreen);
}
@ -270,6 +273,24 @@ winRandRInit(ScreenPtr pScreen)
/* Ensure we have space for exactly one mode */
output->modes = malloc(sizeof(RRModePtr));
output->modes[0] = NULL;
/* Set mode to current display size */
winRandRUpdateMode(pScreen, output);
/* Make up some physical dimensions */
output->mmWidth = (pScreen->width * 25.4)/monitorResolution;
output->mmHeight = (pScreen->height * 25.4)/monitorResolution;
/* Allocate and make up a (fixed, linear) gamma ramp */
{
int i;
RRCrtcGammaSetSize(crtc, 256);
for (i = 0; i < crtc->gammaSize; i++) {
crtc->gammaRed[i] = i << 8;
crtc->gammaBlue[i] = i << 8;
crtc->gammaGreen[i] = i << 8;
}
}
}
/*

View file

@ -258,6 +258,11 @@ winFinishScreenInitFB(int i, ScreenPtr pScreen, int argc, char **argv)
return FALSE;
}
if ((pScreenInfo->dwBPP == 8) && (pScreenInfo->fCompositeWM)) {
ErrorF("-compositewm disabled due to 8bpp depth\n");
pScreenInfo->fCompositeWM = FALSE;
}
/* Apparently we need this for the render extension */
miSetPixmapDepths();
@ -417,6 +422,7 @@ winFinishScreenInitFB(int i, ScreenPtr pScreen, int argc, char **argv)
WRAP(MoveWindow);
WRAP(CopyWindow);
WRAP(SetShape);
WRAP(ModifyPixmapHeader);
/* Assign multi-window window procedures to be top level procedures */
pScreen->CreateWindow = winCreateWindowMultiWindow;
@ -432,6 +438,12 @@ winFinishScreenInitFB(int i, ScreenPtr pScreen, int argc, char **argv)
pScreen->CopyWindow = winCopyWindowMultiWindow;
pScreen->SetShape = winSetShapeMultiWindow;
if (pScreenInfo->fCompositeWM) {
pScreen->CreatePixmap = winCreatePixmapMultiwindow;
pScreen->DestroyPixmap = winDestroyPixmapMultiwindow;
pScreen->ModifyPixmapHeader = winModifyPixmapHeaderMultiwindow;
}
/* Undefine the WRAP macro, as it is not needed elsewhere */
#undef WRAP
}
@ -471,7 +483,8 @@ winFinishScreenInitFB(int i, ScreenPtr pScreen, int argc, char **argv)
&pScreenPriv->ptXMsgProc,
&pScreenPriv->pmServerStarted,
pScreenInfo->dwScreen,
(HWND) &pScreenPriv->hwndScreen)) {
(HWND) &pScreenPriv->hwndScreen,
pScreenInfo->fCompositeWM)) {
ErrorF("winFinishScreenInitFB - winInitWM () failed.\n");
return FALSE;
}

View file

@ -1201,6 +1201,7 @@ winSetEngineFunctionsShadowDDNL(ScreenPtr pScreen)
pScreenPriv->pwinCreateBoundingWindow = winCreateBoundingWindowWindowed;
pScreenPriv->pwinFinishScreenInit = winFinishScreenInitFB;
pScreenPriv->pwinBltExposedRegions = winBltExposedRegionsShadowDDNL;
pScreenPriv->pwinBltExposedWindowRegion = NULL;
pScreenPriv->pwinActivateApp = winActivateAppShadowDDNL;
pScreenPriv->pwinRedrawScreen = winRedrawScreenShadowDDNL;
pScreenPriv->pwinRealizeInstalledPalette

View file

@ -59,6 +59,9 @@ static Bool
static Bool
winBltExposedRegionsShadowGDI(ScreenPtr pScreen);
static Bool
winBltExposedWindowRegionShadowGDI(ScreenPtr pScreen, WindowPtr pWin);
static Bool
winActivateAppShadowGDI(ScreenPtr pScreen);
@ -750,6 +753,12 @@ winBltExposedRegionsShadowGDI(ScreenPtr pScreen)
/* BeginPaint gives us an hdc that clips to the invalidated region */
hdcUpdate = BeginPaint(pScreenPriv->hwndScreen, &ps);
/* Avoid the BitBlt if the PAINTSTRUCT region is bogus */
if (ps.rcPaint.right == 0 && ps.rcPaint.bottom == 0 &&
ps.rcPaint.left == 0 && ps.rcPaint.top == 0) {
EndPaint(pScreenPriv->hwndScreen, &ps);
return 0;
}
/* Realize the palette, if we have one */
if (pScreenPriv->pcmapInstalled != NULL) {
@ -759,11 +768,30 @@ winBltExposedRegionsShadowGDI(ScreenPtr pScreen)
RealizePalette(hdcUpdate);
}
/* Our BitBlt will be clipped to the invalidated region */
BitBlt(hdcUpdate,
0, 0,
pScreenInfo->dwWidth, pScreenInfo->dwHeight,
pScreenPriv->hdcShadow, 0, 0, SRCCOPY);
/* Try to copy from the shadow buffer to the invalidated region */
if (!BitBlt(hdcUpdate,
ps.rcPaint.left, ps.rcPaint.top,
ps.rcPaint.right - ps.rcPaint.left,
ps.rcPaint.bottom - ps.rcPaint.top,
pScreenPriv->hdcShadow,
ps.rcPaint.left,
ps.rcPaint.top,
SRCCOPY)) {
LPVOID lpMsgBuf;
/* Display an error message */
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf, 0, NULL);
ErrorF("winBltExposedRegionsShadowGDI - BitBlt failed: %s\n",
(LPSTR) lpMsgBuf);
LocalFree(lpMsgBuf);
}
/* EndPaint frees the DC */
EndPaint(pScreenPriv->hwndScreen, &ps);
@ -776,6 +804,128 @@ winBltExposedRegionsShadowGDI(ScreenPtr pScreen)
return TRUE;
}
/*
* Blt exposed region to the given HWND
*/
static Bool
winBltExposedWindowRegionShadowGDI(ScreenPtr pScreen, WindowPtr pWin)
{
winScreenPriv(pScreen);
winPrivWinPtr pWinPriv = winGetWindowPriv(pWin);
HWND hWnd = pWinPriv->hWnd;
HDC hdcUpdate;
PAINTSTRUCT ps;
hdcUpdate = BeginPaint(hWnd, &ps);
/* Avoid the BitBlt if the PAINTSTRUCT region is bogus */
if (ps.rcPaint.right == 0 && ps.rcPaint.bottom == 0 &&
ps.rcPaint.left == 0 && ps.rcPaint.top == 0) {
EndPaint(hWnd, &ps);
return 0;
}
#ifdef COMPOSITE
if (pWin->redirectDraw != RedirectDrawNone) {
HBITMAP hBitmap;
HDC hdcPixmap;
PixmapPtr pPixmap = (*pScreen->GetWindowPixmap) (pWin);
winPrivPixmapPtr pPixmapPriv = winGetPixmapPriv(pPixmap);
/* window pixmap format is the same as the screen pixmap */
assert(pPixmap->drawable.bitsPerPixel > 8);
/* Get the window bitmap from the pixmap */
hBitmap = pPixmapPriv->hBitmap;
/* XXX: There may be a need for a slow-path here: If hBitmap is NULL
(because we couldn't back the pixmap with a Windows DIB), we should
fall-back to creating a Windows DIB from the pixmap, then deleting it
after the BitBlt (as this this code did before the fast-path was
added). */
if (!hBitmap) {
ErrorF("winBltExposedWindowRegionShadowGDI - slow path unimplemented\n");
}
/* Select the window bitmap into a screen-compatible DC */
hdcPixmap = CreateCompatibleDC(pScreenPriv->hdcScreen);
SelectObject(hdcPixmap, hBitmap);
/* Blt from the window bitmap to the invalidated region */
if (!BitBlt(hdcUpdate,
ps.rcPaint.left, ps.rcPaint.top,
ps.rcPaint.right - ps.rcPaint.left,
ps.rcPaint.bottom - ps.rcPaint.top,
hdcPixmap,
ps.rcPaint.left + pWin->borderWidth,
ps.rcPaint.top + pWin->borderWidth,
SRCCOPY))
ErrorF("winBltExposedWindowRegionShadowGDI - BitBlt failed: 0x%08x\n",
GetLastError());
/* Release DC */
DeleteDC(hdcPixmap);
}
else
#endif
{
/* Try to copy from the shadow buffer to the invalidated region */
if (!BitBlt(hdcUpdate,
ps.rcPaint.left, ps.rcPaint.top,
ps.rcPaint.right - ps.rcPaint.left,
ps.rcPaint.bottom - ps.rcPaint.top,
pScreenPriv->hdcShadow,
ps.rcPaint.left + pWin->drawable.x,
ps.rcPaint.top + pWin->drawable.y,
SRCCOPY)) {
LPVOID lpMsgBuf;
/* Display an error message */
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf, 0, NULL);
ErrorF("winBltExposedWindowRegionShadowGDI - BitBlt failed: %s\n",
(LPSTR) lpMsgBuf);
LocalFree(lpMsgBuf);
}
}
/* If part of the invalidated region is outside the window (which can happen
if the native window is being re-sized), fill that area with black */
if (ps.rcPaint.right > ps.rcPaint.left + pWin->drawable.width) {
BitBlt(hdcUpdate,
ps.rcPaint.left + pWin->drawable.width,
ps.rcPaint.top,
ps.rcPaint.right - (ps.rcPaint.left + pWin->drawable.width),
ps.rcPaint.bottom - ps.rcPaint.top,
NULL,
0, 0,
BLACKNESS);
}
if (ps.rcPaint.bottom > ps.rcPaint.top + pWin->drawable.height) {
BitBlt(hdcUpdate,
ps.rcPaint.left,
ps.rcPaint.top + pWin->drawable.height,
ps.rcPaint.right - ps.rcPaint.left,
ps.rcPaint.bottom - (ps.rcPaint.top + pWin->drawable.height),
NULL,
0, 0,
BLACKNESS);
}
/* EndPaint frees the DC */
EndPaint(hWnd, &ps);
return TRUE;
}
/*
* Do any engine-specific appliation-activation processing
*/
@ -1119,6 +1269,7 @@ winSetEngineFunctionsShadowGDI(ScreenPtr pScreen)
pScreenPriv->pwinCreateBoundingWindow = winCreateBoundingWindowWindowed;
pScreenPriv->pwinFinishScreenInit = winFinishScreenInitFB;
pScreenPriv->pwinBltExposedRegions = winBltExposedRegionsShadowGDI;
pScreenPriv->pwinBltExposedWindowRegion = winBltExposedWindowRegionShadowGDI;
pScreenPriv->pwinActivateApp = winActivateAppShadowGDI;
pScreenPriv->pwinRedrawScreen = winRedrawScreenShadowGDI;
pScreenPriv->pwinRealizeInstalledPalette =

View file

@ -155,6 +155,14 @@ winValidateArgs(void)
"-scrollbars, -resize, -nodecoration, or -lesspointer.\n");
return FALSE;
}
/* Ignore -swcursor if -multiwindow -compositewm is requested */
if (g_ScreenInfo[i].fMultiWindow && g_ScreenInfo[i].fCompositeWM) {
if (g_fSoftwareCursor) {
g_fSoftwareCursor = FALSE;
winMsg(X_WARNING, "Ignoring -swcursor due to -compositewm\n");
}
}
}
winDebug("winValidateArgs - Returning.\n");

View file

@ -144,7 +144,7 @@ winInitWM(void **ppWMInfo,
pthread_t * ptWMProc,
pthread_t * ptXMsgProc,
pthread_mutex_t * ppmServerStarted,
int dwScreen, HWND hwndScreen);
int dwScreen, HWND hwndScreen, Bool compositeWM);
void
winDeinitMultiWindowWM(void);

View file

@ -238,7 +238,6 @@ winWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
struct GetMonitorInfoData data;
if (QueryMonitor(s_pScreenInfo->iMonitor, &data)) {
if (data.bMonitorSpecifiedExists == TRUE) {
dwWidth = data.monitorWidth;
dwHeight = data.monitorHeight;
/*
@ -250,7 +249,6 @@ winWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
ErrorF("Monitor number %d no longer exists!\n",
s_pScreenInfo->iMonitor);
}
}
}
/*

View file

@ -512,4 +512,7 @@
/* Have <sys/sysmacros.h> header */
#undef HAVE_SYS_SYSMACROS_H
/* Have sigprocmask */
#undef HAVE_SIGPROCMASK
#endif /* _DIX_CONFIG_H_ */

View file

@ -75,7 +75,7 @@
* will still work.
*/
#define GLXSERVER_VENDOR_ABI_MAJOR_VERSION 0
#define GLXSERVER_VENDOR_ABI_MINOR_VERSION 0
#define GLXSERVER_VENDOR_ABI_MINOR_VERSION 1
#if defined(__cplusplus)
extern "C" {
@ -236,6 +236,17 @@ typedef struct GlxServerExportsRec {
* \param client The client.
*/
int (* forwardRequest) (GlxServerVendor *vendor, ClientPtr client);
/**
* Sets the vendor library to use for a screen for a specific client.
*
* This function changes which vendor should handle GLX requests for a
* screen. Unlike \c setScreenVendor, this function can be called at any
* time, and only applies to requests from a single client.
*
* This function is available in GLXVND version 0.1 or later.
*/
Bool (* setClientScreenVendor) (ClientPtr client, ScreenPtr screen, GlxServerVendor *vendor);
} GlxServerExports;
extern _X_EXPORT const GlxServerExports glxServer;

View file

@ -60,6 +60,9 @@ else
if not enable_input_thread and get_option('input_thread') == 'true'
error('Input thread enabled and PTHREAD_MUTEX_RECURSIVE not found')
endif
if host_machine.system() == 'windows' and get_option('input_thread') == 'auto'
enable_input_thread = false
endif
endif
conf_data.set('HAVE_INPUTTHREAD', enable_input_thread)
@ -152,6 +155,7 @@ conf_data.set('HAVE_SETEUID', cc.has_function('seteuid'))
conf_data.set('HAVE_SETITIMER', cc.has_function('setitimer'))
conf_data.set('HAVE_SHMCTL64', cc.has_function('shmctl64'))
conf_data.set('HAVE_SIGACTION', cc.has_function('sigaction'))
conf_data.set('HAVE_SIGPROCMASK', cc.has_function('sigprocmask'))
conf_data.set('HAVE_STRCASECMP', cc.has_function('strcasecmp'))
conf_data.set('HAVE_STRCASESTR', cc.has_function('strcasestr'))
conf_data.set('HAVE_STRLCAT', cc.has_function('strlcat', dependencies: libbsd_dep))

View file

@ -721,6 +721,10 @@ os_move_fd(int fd);
#include <signal.h>
#if defined(WIN32) && !defined(__CYGWIN__)
typedef _sigset_t sigset_t;
#endif
extern _X_EXPORT int
xthread_sigmask(int how, const sigset_t *set, sigset_t *oldest);

View file

@ -62,6 +62,10 @@ SOFTWARE.
#include <X11/Xmd.h>
#include "servermd.h"
#ifdef __MINGW32__
#define ffs __builtin_ffs
#endif
/* MICOPYAREA -- public entry for the CopyArea request
* For each rectangle in the source region
* get the pixels with GetSpans

View file

@ -558,7 +558,11 @@ extern int InputThreadUnregisterDev(int fd)
int xthread_sigmask(int how, const sigset_t *set, sigset_t *oldset)
{
#ifdef HAVE_SIGPROCMASK
return sigprocmask(how, set, oldset);
#else
return 0;
#endif
}
#endif

View file

@ -1281,7 +1281,7 @@ SmartScheduleInit(void)
#endif
}
#ifdef SIG_BLOCK
#ifdef HAVE_SIGPROCMASK
static sigset_t PreviousSignalMask;
static int BlockedSignalCount;
#endif
@ -1289,7 +1289,7 @@ static int BlockedSignalCount;
void
OsBlockSignals(void)
{
#ifdef SIG_BLOCK
#ifdef HAVE_SIGPROCMASK
if (BlockedSignalCount++ == 0) {
sigset_t set;
@ -1311,7 +1311,7 @@ OsBlockSignals(void)
void
OsReleaseSignals(void)
{
#ifdef SIG_BLOCK
#ifdef HAVE_SIGPROCMASK
if (--BlockedSignalCount == 0) {
xthread_sigmask(SIG_SETMASK, &PreviousSignalMask, 0);
}
@ -1321,7 +1321,7 @@ OsReleaseSignals(void)
void
OsResetSignals(void)
{
#ifdef SIG_BLOCK
#ifdef HAVE_SIGPROCMASK
while (BlockedSignalCount > 0)
OsReleaseSignals();
input_force_unlock();

View file

@ -84,6 +84,10 @@
#include <string.h> /* string functions */
#include "xserver_poll.h"
#if defined(WIN32) && !defined(__CYGWIN__)
#include <X11/Xwinsock.h>
#endif
/*---------------------------------------------------------------------------*\
Macros
\*---------------------------------------------------------------------------*/

View file

@ -22,7 +22,7 @@ libxserver_present = static_library('libxserver_present',
include_directories: inc,
dependencies: [
common_dep,
dependency('presentproto', version: '>= 1.1')
dependency('presentproto', version: '>= 1.2')
],
c_args: '-DHAVE_XORG_CONFIG_H'
)