aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/hw
diff options
context:
space:
mode:
authormarha <marha@users.sourceforge.net>2015-02-22 21:39:56 +0100
committermarha <marha@users.sourceforge.net>2015-02-22 21:39:56 +0100
commit462f18c7b25fe3e467f837647d07ab0a78aa8d2b (patch)
treefc8013c0a1bac05a1945846c1697e973f4c35013 /xorg-server/hw
parent36f711ee12b6dd5184198abed3aa551efb585587 (diff)
downloadvcxsrv-462f18c7b25fe3e467f837647d07ab0a78aa8d2b.tar.gz
vcxsrv-462f18c7b25fe3e467f837647d07ab0a78aa8d2b.tar.bz2
vcxsrv-462f18c7b25fe3e467f837647d07ab0a78aa8d2b.zip
Merged origin/release (checked in because wanted to merge new stuff)
Diffstat (limited to 'xorg-server/hw')
-rw-r--r--xorg-server/hw/dmx/config/dmxparse.h3
-rw-r--r--xorg-server/hw/dmx/config/dmxprint.c20
-rw-r--r--xorg-server/hw/dmx/dmx.c1
-rw-r--r--xorg-server/hw/dmx/dmxcb.c3
-rw-r--r--xorg-server/hw/dmx/dmxfont.h2
-rw-r--r--xorg-server/hw/dmx/dmxgc.c4
-rw-r--r--xorg-server/hw/dmx/dmxgc.h4
-rw-r--r--xorg-server/hw/dmx/dmxinit.c42
-rw-r--r--xorg-server/hw/dmx/dmxpict.c1
-rw-r--r--xorg-server/hw/dmx/dmxprop.c6
-rw-r--r--xorg-server/hw/dmx/dmxscrinit.c1
-rw-r--r--xorg-server/hw/dmx/dmxwindow.c4
-rw-r--r--xorg-server/hw/dmx/glxProxy/compsize.h7
-rw-r--r--xorg-server/hw/dmx/glxProxy/g_disptab.h21
-rw-r--r--xorg-server/hw/dmx/glxProxy/glxcmds.c7
-rw-r--r--xorg-server/hw/dmx/glxProxy/glxcmds.h6
-rw-r--r--xorg-server/hw/dmx/glxProxy/glxcmdsswap.c2
-rw-r--r--xorg-server/hw/dmx/glxProxy/glxext.h1
-rw-r--r--xorg-server/hw/dmx/glxProxy/glxscreens.c6
-rw-r--r--xorg-server/hw/dmx/glxProxy/glxscreens.h2
-rw-r--r--xorg-server/hw/dmx/glxProxy/glxserver.h8
-rw-r--r--xorg-server/hw/dmx/glxProxy/glxsingle.c6
-rw-r--r--xorg-server/hw/dmx/glxProxy/glxsingle.h4
-rw-r--r--xorg-server/hw/dmx/glxProxy/glxswap.c4
-rw-r--r--xorg-server/hw/dmx/glxProxy/glxvendor.c6
-rw-r--r--xorg-server/hw/dmx/input/dmxinputinit.c10
-rw-r--r--xorg-server/hw/kdrive/ephyr/ephyr.c10
-rw-r--r--xorg-server/hw/kdrive/ephyr/ephyr.h1
-rwxr-xr-xxorg-server/hw/kdrive/ephyr/hostx.c11
-rw-r--r--xorg-server/hw/kdrive/ephyr/hostx.h2
-rw-r--r--xorg-server/hw/xfree86/Makefile.am2
-rw-r--r--xorg-server/hw/xfree86/Xorg.sh.in4
-rw-r--r--xorg-server/hw/xfree86/common/xf86AutoConfig.c1
-rw-r--r--xorg-server/hw/xfree86/dri2/dri2.c9
-rw-r--r--xorg-server/hw/xfree86/dri2/dri2ext.c3
-rw-r--r--xorg-server/hw/xfree86/drivers/modesetting/Makefile.am3
-rw-r--r--xorg-server/hw/xfree86/drivers/modesetting/dri2.c2
-rw-r--r--xorg-server/hw/xfree86/drivers/modesetting/driver.c106
-rw-r--r--xorg-server/hw/xfree86/drivers/modesetting/driver.h15
-rw-r--r--xorg-server/hw/xfree86/drivers/modesetting/drmmode_display.c487
-rw-r--r--xorg-server/hw/xfree86/drivers/modesetting/drmmode_display.h37
-rw-r--r--xorg-server/hw/xfree86/drivers/modesetting/dumb_bo.c134
-rw-r--r--xorg-server/hw/xfree86/drivers/modesetting/dumb_bo.h45
-rw-r--r--xorg-server/hw/xfree86/drivers/modesetting/present.c228
-rw-r--r--xorg-server/hw/xfree86/drivers/modesetting/vblank.c37
-rw-r--r--xorg-server/hw/xfree86/man/Xorg.wrap.man2
-rw-r--r--xorg-server/hw/xfree86/os-support/solaris/sun_init.c33
-rw-r--r--xorg-server/hw/xfree86/os-support/xf86_OSlib.h5
-rw-r--r--xorg-server/hw/xfree86/xorg-wrapper.c10
-rw-r--r--xorg-server/hw/xnest/Keyboard.c9
-rw-r--r--xorg-server/hw/xwayland/Makefile.am1
-rw-r--r--xorg-server/hw/xwayland/xwayland-glamor.c6
-rw-r--r--xorg-server/hw/xwayland/xwayland-input.c7
-rw-r--r--xorg-server/hw/xwayland/xwayland.c2
-rwxr-xr-xxorg-server/hw/xwin/InitOutput.c4
-rw-r--r--xorg-server/hw/xwin/XWin.rc1
-rw-r--r--xorg-server/hw/xwin/man/XWin.man6
-rwxr-xr-xxorg-server/hw/xwin/winclipboard/internal.h38
-rwxr-xr-xxorg-server/hw/xwin/winclipboard/thread.c124
-rw-r--r--xorg-server/hw/xwin/winclipboard/winclipboard.h4
-rwxr-xr-xxorg-server/hw/xwin/winclipboard/wndproc.c245
-rwxr-xr-xxorg-server/hw/xwin/winclipboard/xevents.c426
-rw-r--r--xorg-server/hw/xwin/winclipboard/xwinclip.c7
-rw-r--r--xorg-server/hw/xwin/winclipboard/xwinclip.man3
-rwxr-xr-x[-rw-r--r--]xorg-server/hw/xwin/winclipboardwrappers.c7
-rwxr-xr-x[-rw-r--r--]xorg-server/hw/xwin/winprocarg.c27
-rw-r--r--xorg-server/hw/xwin/winresource.h1
-rw-r--r--xorg-server/hw/xwin/wintrayicon.c19
-rwxr-xr-xxorg-server/hw/xwin/winwndproc.c6
69 files changed, 1614 insertions, 697 deletions
diff --git a/xorg-server/hw/dmx/config/dmxparse.h b/xorg-server/hw/dmx/config/dmxparse.h
index 7d31b6309..cc2f0eb71 100644
--- a/xorg-server/hw/dmx/config/dmxparse.h
+++ b/xorg-server/hw/dmx/config/dmxparse.h
@@ -38,6 +38,7 @@
#define _DMXPARSE_H_
#include <stdio.h> /* For FILE */
+#include <X11/Xfuncproto.h> /* For _X_ATTRIBUTE_PRINTF */
/** Stores tokens not stored in other structures (e.g., keywords and ;) */
typedef struct _DMXConfigToken {
@@ -203,7 +204,7 @@ extern int yylex(void);
extern int yydebug;
extern void yyerror(const char *message);
-extern void dmxConfigLog(const char *format, ...);
+extern void dmxConfigLog(const char *format, ...) _X_ATTRIBUTE_PRINTF(1,0);
extern void *dmxConfigAlloc(unsigned long bytes);
extern void *dmxConfigRealloc(void *orig,
unsigned long orig_bytes, unsigned long bytes);
diff --git a/xorg-server/hw/dmx/config/dmxprint.c b/xorg-server/hw/dmx/config/dmxprint.c
index 9dec52b5c..c80e830e4 100644
--- a/xorg-server/hw/dmx/config/dmxprint.c
+++ b/xorg-server/hw/dmx/config/dmxprint.c
@@ -130,7 +130,7 @@ dmxConfigPopState(void)
dmxConfigNewline();
}
-static void
+static void _X_ATTRIBUTE_PRINTF(4, 5)
dmxConfigOutput(int addSpace, int doNewline, const char *comment,
const char *format, ...)
{
@@ -261,32 +261,20 @@ dmxConfigPrintString(DMXConfigStringPtr p, int quote)
static int
dmxConfigPrintPair(DMXConfigPairPtr p, int addSpace)
{
- const char *format = NULL;
-
if (!p)
return 0;
- switch (p->token) {
- case T_ORIGIN:
- format = "@%dx%d";
- break;
- case T_DIMENSION:
- format = "%dx%d";
- break;
- case T_OFFSET:
- format = "%c%d%c%d";
- break;
- }
if (p->token == T_OFFSET) {
if (!p->comment && !p->x && !p->y && p->xsign >= 0 && p->ysign >= 0)
return 0;
- dmxConfigOutput(addSpace, 0, p->comment, format,
+ dmxConfigOutput(addSpace, 0, p->comment, "%c%d%c%d",
p->xsign < 0 ? '-' : '+', p->x,
p->ysign < 0 ? '-' : '+', p->y);
}
else {
if (!p->comment && !p->x && !p->y)
return 0;
- dmxConfigOutput(addSpace, 0, p->comment, format, p->x, p->y);
+ dmxConfigOutput(addSpace, 0, p->comment, "%s%dx%d",
+ (p->token == T_ORIGIN) ? "@" : "", p->x, p->y);
}
return 1;
}
diff --git a/xorg-server/hw/dmx/dmx.c b/xorg-server/hw/dmx/dmx.c
index 99e970cb9..2988df33a 100644
--- a/xorg-server/hw/dmx/dmx.c
+++ b/xorg-server/hw/dmx/dmx.c
@@ -55,6 +55,7 @@
#include "extinit.h"
#include "opaque.h"
+#include "dmx.h"
#include "dmxextension.h"
#include <X11/extensions/dmxproto.h>
#include <X11/extensions/dmx.h>
diff --git a/xorg-server/hw/dmx/dmxcb.c b/xorg-server/hw/dmx/dmxcb.c
index 86015f395..cca5702ee 100644
--- a/xorg-server/hw/dmx/dmxcb.c
+++ b/xorg-server/hw/dmx/dmxcb.c
@@ -47,9 +47,6 @@ extern int connBlockScreenStart;
#ifdef PANORAMIX
#include "panoramiXsrv.h"
-extern int PanoramiXPixWidth;
-extern int PanoramiXPixHeight;
-extern int PanoramiXNumScreens;
#endif
int dmxGlobalWidth, dmxGlobalHeight;
diff --git a/xorg-server/hw/dmx/dmxfont.h b/xorg-server/hw/dmx/dmxfont.h
index 8575ca953..66c663377 100644
--- a/xorg-server/hw/dmx/dmxfont.h
+++ b/xorg-server/hw/dmx/dmxfont.h
@@ -54,6 +54,4 @@ extern Bool dmxUnrealizeFont(ScreenPtr pScreen, FontPtr pFont);
extern Bool dmxBELoadFont(ScreenPtr pScreen, FontPtr pFont);
extern Bool dmxBEFreeFont(ScreenPtr pScreen, FontPtr pFont);
-extern int dmxFontPrivateIndex;
-
#endif /* DMXFONT_H */
diff --git a/xorg-server/hw/dmx/dmxgc.c b/xorg-server/hw/dmx/dmxgc.c
index 234316797..ec15d27aa 100644
--- a/xorg-server/hw/dmx/dmxgc.c
+++ b/xorg-server/hw/dmx/dmxgc.c
@@ -49,7 +49,7 @@
#include "pixmapstr.h"
#include "migc.h"
-static GCFuncs dmxGCFuncs = {
+static const GCFuncs dmxGCFuncs = {
dmxValidateGC,
dmxChangeGC,
dmxCopyGC,
@@ -59,7 +59,7 @@ static GCFuncs dmxGCFuncs = {
dmxCopyClip,
};
-static GCOps dmxGCOps = {
+static const GCOps dmxGCOps = {
dmxFillSpans,
dmxSetSpans,
dmxPutImage,
diff --git a/xorg-server/hw/dmx/dmxgc.h b/xorg-server/hw/dmx/dmxgc.h
index c8ecb53a0..c5c6b7732 100644
--- a/xorg-server/hw/dmx/dmxgc.h
+++ b/xorg-server/hw/dmx/dmxgc.h
@@ -41,8 +41,8 @@
/** GC private area. */
typedef struct _dmxGCPriv {
- GCOps *ops;
- GCFuncs *funcs;
+ const GCOps *ops;
+ const GCFuncs *funcs;
XlibGC gc;
Bool msc;
} dmxGCPrivRec, *dmxGCPrivPtr;
diff --git a/xorg-server/hw/dmx/dmxinit.c b/xorg-server/hw/dmx/dmxinit.c
index c782a9bff..2d3b2e9e0 100644
--- a/xorg-server/hw/dmx/dmxinit.c
+++ b/xorg-server/hw/dmx/dmxinit.c
@@ -164,23 +164,23 @@ dmxErrorHandler(Display * dpy, XErrorEvent * ev)
switch (ev->error_code) {
case BadValue:
dmxLog(dmxWarning, " Value: 0x%x\n",
- ev->resourceid);
+ (unsigned int) ev->resourceid);
break;
case BadAtom:
dmxLog(dmxWarning, " AtomID: 0x%x\n",
- ev->resourceid);
+ (unsigned int) ev->resourceid);
break;
default:
dmxLog(dmxWarning, " ResourceID: 0x%x\n",
- ev->resourceid);
+ (unsigned int) ev->resourceid);
break;
}
/* Provide serial number information */
dmxLog(dmxWarning, " Failed serial number: %d\n",
- ev->serial);
+ (unsigned int) ev->serial);
dmxLog(dmxWarning, " Current serial number: %d\n",
- dpy->request);
+ (unsigned int) dpy->request);
return 0;
}
@@ -634,7 +634,7 @@ InitOutput(ScreenInfo * pScreenInfo, int argc, char *argv[])
if (major > 0 && minor > 0)
year += 2000;
- dmxLog(dmxInfo, "Generation: %d\n", dmxGeneration);
+ dmxLog(dmxInfo, "Generation: %lu\n", dmxGeneration);
dmxLog(dmxInfo, "DMX version: %d.%d.%02d%02d%02d (%s)\n",
major, minor, year, month, day, VENDOR_STRING);
@@ -762,7 +762,6 @@ InitOutput(ScreenInfo * pScreenInfo, int argc, char *argv[])
dmxGlxVisualPrivate **configprivs = NULL;
int nconfigs = 0;
int (*oldErrorHandler) (Display *, XErrorEvent *);
- int i;
/* Catch errors if when using an older GLX w/o FBconfigs */
oldErrorHandler = XSetErrorHandler(dmxNOPErrorHandler);
@@ -797,28 +796,29 @@ InitOutput(ScreenInfo * pScreenInfo, int argc, char *argv[])
configprivs = malloc(nconfigs * sizeof(dmxGlxVisualPrivate *));
if (configs != NULL && configprivs != NULL) {
+ int j;
/* Initialize our private info for each visual
* (currently only x_visual_depth and x_visual_class)
*/
- for (i = 0; i < nconfigs; i++) {
+ for (j = 0; j < nconfigs; j++) {
- configprivs[i] = (dmxGlxVisualPrivate *)
+ configprivs[j] = (dmxGlxVisualPrivate *)
malloc(sizeof(dmxGlxVisualPrivate));
- configprivs[i]->x_visual_depth = 0;
- configprivs[i]->x_visual_class = 0;
+ configprivs[j]->x_visual_depth = 0;
+ configprivs[j]->x_visual_class = 0;
/* Find the visual depth */
- if (configs[i].vid > 0) {
- int j;
-
- for (j = 0; j < dmxScreen->beNumVisuals; j++) {
- if (dmxScreen->beVisuals[j].visualid ==
- configs[i].vid) {
- configprivs[i]->x_visual_depth =
- dmxScreen->beVisuals[j].depth;
- configprivs[i]->x_visual_class =
- dmxScreen->beVisuals[j].class;
+ if (configs[j].vid > 0) {
+ int k;
+
+ for (k = 0; k < dmxScreen->beNumVisuals; k++) {
+ if (dmxScreen->beVisuals[k].visualid ==
+ configs[j].vid) {
+ configprivs[j]->x_visual_depth =
+ dmxScreen->beVisuals[k].depth;
+ configprivs[j]->x_visual_class =
+ dmxScreen->beVisuals[k].class;
break;
}
}
diff --git a/xorg-server/hw/dmx/dmxpict.c b/xorg-server/hw/dmx/dmxpict.c
index 64d0ae150..aaca178b9 100644
--- a/xorg-server/hw/dmx/dmxpict.c
+++ b/xorg-server/hw/dmx/dmxpict.c
@@ -57,7 +57,6 @@
#include "mipict.h"
#include "fbpict.h"
-extern int RenderErrBase;
extern int (*ProcRenderVector[RenderNumberRequests]) (ClientPtr);
static int (*dmxSaveRenderVector[RenderNumberRequests]) (ClientPtr);
diff --git a/xorg-server/hw/dmx/dmxprop.c b/xorg-server/hw/dmx/dmxprop.c
index 4be2dbd4c..5e306d286 100644
--- a/xorg-server/hw/dmx/dmxprop.c
+++ b/xorg-server/hw/dmx/dmxprop.c
@@ -220,7 +220,7 @@ dmxPropertyCheckOtherWindows(DMXScreenInfo * dmxScreen, Atom atom)
if (XGetTextProperty(dpy, win, &tp, atom) && tp.nitems) {
dmxLog(dmxDebug, "On %s/%lu: %s\n",
- dmxScreen->name, win, tp.value);
+ dmxScreen->name, (unsigned long) win, tp.value);
if (!strncmp((char *) tp.value, (char *) id,
strlen((char *) id))) {
int idx;
@@ -360,8 +360,8 @@ dmxPropertyWindow(DMXScreenInfo * dmxScreen)
dmxScreen->next = (other->next ? other->next : other);
other->next = (tmp ? tmp : dmxScreen);
dmxLog(dmxDebug, "%d/%s/%lu and %d/%s/%lu are on the same backend\n",
- dmxScreen->index, dmxScreen->name, dmxScreen->scrnWin,
- other->index, other->name, other->scrnWin);
+ dmxScreen->index, dmxScreen->name, (unsigned long) dmxScreen->scrnWin,
+ other->index, other->name, (unsigned long) other->scrnWin);
}
snprintf(buf, sizeof(buf), ".%d,%lu", dmxScreen->index,
diff --git a/xorg-server/hw/dmx/dmxscrinit.c b/xorg-server/hw/dmx/dmxscrinit.c
index 963d3a9de..097418d05 100644
--- a/xorg-server/hw/dmx/dmxscrinit.c
+++ b/xorg-server/hw/dmx/dmxscrinit.c
@@ -80,7 +80,6 @@ dmxBEScreenInit(ScreenPtr pScreen)
{
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
XSetWindowAttributes attribs;
- XGCValues gcvals;
unsigned long mask;
int i, j;
diff --git a/xorg-server/hw/dmx/dmxwindow.c b/xorg-server/hw/dmx/dmxwindow.c
index c75373534..c157e1099 100644
--- a/xorg-server/hw/dmx/dmxwindow.c
+++ b/xorg-server/hw/dmx/dmxwindow.c
@@ -857,13 +857,9 @@ dmxResizeWindow(WindowPtr pWindow, int x, int y,
ScreenPtr pScreen = pWindow->drawable.pScreen;
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow);
- dmxWinPrivPtr pSibPriv;
unsigned int m;
XWindowChanges c;
- if (pSib)
- pSibPriv = DMX_GET_WINDOW_PRIV(pSib);
-
DMX_UNWRAP(ResizeWindow, dmxScreen, pScreen);
#if 1
if (pScreen->ResizeWindow)
diff --git a/xorg-server/hw/dmx/glxProxy/compsize.h b/xorg-server/hw/dmx/glxProxy/compsize.h
index 360966233..5e759b0a0 100644
--- a/xorg-server/hw/dmx/glxProxy/compsize.h
+++ b/xorg-server/hw/dmx/glxProxy/compsize.h
@@ -48,4 +48,11 @@ extern GLint __glTexGeniv_size(GLenum e);
extern GLint __glTexParameterfv_size(GLenum e);
extern GLint __glTexParameteriv_size(GLenum e);
+extern GLint __glCallLists_size(GLsizei n, GLenum type);
+extern GLint __glDrawPixels_size(GLenum format, GLenum type, GLsizei w, GLsizei h);
+extern GLint __glBitmap_size(GLsizei w, GLsizei h);
+extern GLint __glTexImage1D_size(GLenum format, GLenum type, GLsizei w);
+extern GLint __glTexImage2D_size(GLenum format, GLenum type, GLsizei w, GLsizei h);
+extern GLint __glTexImage3D_size(GLenum format, GLenum type, GLsizei w, GLsizei h, GLsizei d);
+
#endif /* !__compsize_h__ */
diff --git a/xorg-server/hw/dmx/glxProxy/g_disptab.h b/xorg-server/hw/dmx/glxProxy/g_disptab.h
index 530338798..783f87a54 100644
--- a/xorg-server/hw/dmx/glxProxy/g_disptab.h
+++ b/xorg-server/hw/dmx/glxProxy/g_disptab.h
@@ -655,7 +655,6 @@ extern void __glXDispSwap_CopyConvolutionFilter2D(GLbyte *);
extern void __glXDispSwap_SeparableFilter2D(GLbyte *);
extern void __glXDispSwap_TexImage3D(GLbyte *);
extern void __glXDispSwap_TexSubImage3D(GLbyte *);
-extern void __glXDispSwap_DrawArrays(GLbyte *);
extern void __glXDispSwap_PrioritizeTextures(GLbyte *);
extern void __glXDispSwap_CopyTexImage1D(GLbyte *);
extern void __glXDispSwap_CopyTexImage2D(GLbyte *);
@@ -663,6 +662,26 @@ extern void __glXDispSwap_CopyTexSubImage1D(GLbyte *);
extern void __glXDispSwap_CopyTexSubImage2D(GLbyte *);
extern void __glXDispSwap_CopyTexSubImage3D(GLbyte *);
+extern void __glXDispSwap_BindTexture(GLbyte *);
+extern void __glXDispSwap_BlendColor(GLbyte *);
+extern void __glXDispSwap_BlendEquation(GLbyte *);
+extern void __glXDispSwap_ColorTable(GLbyte *);
+extern void __glXDispSwap_ColorTableParameterfv(GLbyte *);
+extern void __glXDispSwap_ColorTableParameteriv(GLbyte *);
+extern void __glXDispSwap_CopyColorTable(GLbyte *);
+extern void __glXDispSwap_ConvolutionParameterf(GLbyte *);
+extern void __glXDispSwap_ConvolutionParameteri(GLbyte *);
+extern void __glXDispSwap_Histogram(GLbyte *);
+extern void __glXDispSwap_Minmax(GLbyte *);
+extern void __glXDispSwap_ResetHistogram(GLbyte *);
+extern void __glXDispSwap_ResetMinmax(GLbyte *);
+
+extern int __glXSwapCreateContextWithConfigSGIX(__GLXclientState *, GLbyte *);
+extern int __glXSwapBindSwapBarrierSGIX(__GLXclientState *, GLbyte *);
+extern int __glXSwapJoinSwapGroupSGIX(__GLXclientState *, GLbyte *);
+extern int __glXSwapQueryMaxSwapBarriersSGIX(__GLXclientState *, GLbyte *);
+extern int __glXSwapMakeCurrentReadSGI(__GLXclientState *, GLbyte *);
+
#define __GLX_MIN_GLXCMD_OPCODE 1
#define __GLX_MAX_GLXCMD_OPCODE 20
#define __GLX_MIN_RENDER_OPCODE 1
diff --git a/xorg-server/hw/dmx/glxProxy/glxcmds.c b/xorg-server/hw/dmx/glxProxy/glxcmds.c
index fb4d5acce..4c500c93d 100644
--- a/xorg-server/hw/dmx/glxProxy/glxcmds.c
+++ b/xorg-server/hw/dmx/glxProxy/glxcmds.c
@@ -61,7 +61,6 @@
extern __GLXFBConfig **__glXFBConfigs;
extern int __glXNumFBConfigs;
-extern int glxIsExtensionSupported(char *ext);
extern int __glXGetFBConfigsSGIX(__GLXclientState * cl, GLbyte * pc);
#define BE_TO_CLIENT_ERROR(x) \
@@ -3394,11 +3393,11 @@ __glXCreatePbuffer(__GLXclientState * cl, GLbyte * pc)
/* Send attributes */
if (attr != NULL) {
- CARD32 *pc = (CARD32 *) (be_req + 1);
+ CARD32 *pca = (CARD32 *) (be_req + 1);
while (numAttribs-- > 0) {
- *pc++ = *attr++; /* token */
- *pc++ = *attr++; /* value */
+ *pca++ = *attr++; /* token */
+ *pca++ = *attr++; /* value */
}
}
diff --git a/xorg-server/hw/dmx/glxProxy/glxcmds.h b/xorg-server/hw/dmx/glxProxy/glxcmds.h
index b0745927e..689e33485 100644
--- a/xorg-server/hw/dmx/glxProxy/glxcmds.h
+++ b/xorg-server/hw/dmx/glxProxy/glxcmds.h
@@ -33,5 +33,11 @@ extern int __glXCreateContextWithConfigSGIX(__GLXclientState * cl, GLbyte * pc);
extern int __glXJoinSwapGroupSGIX(__GLXclientState * cl, GLbyte * pc);
extern int __glXMakeCurrentReadSGI(__GLXclientState * cl, GLbyte * pc);
extern int __glXQueryMaxSwapBarriersSGIX(__GLXclientState * cl, GLbyte * pc);
+extern int __glXDoSwapBuffers(__GLXclientState * cl, XID drawId,
+ GLXContextTag tag);
+
+extern Display *GetBackEndDisplay(__GLXclientState * cl, int s);
+extern int GetCurrentBackEndTag(__GLXclientState * cl, GLXContextTag tag,
+ int s);
#endif /* !__GLX_cmds_h__ */
diff --git a/xorg-server/hw/dmx/glxProxy/glxcmdsswap.c b/xorg-server/hw/dmx/glxProxy/glxcmdsswap.c
index ab3e7edc1..600a6e1cb 100644
--- a/xorg-server/hw/dmx/glxProxy/glxcmdsswap.c
+++ b/xorg-server/hw/dmx/glxProxy/glxcmdsswap.c
@@ -39,8 +39,6 @@
#include "glxext.h"
#include "glxvendor.h"
-extern int glxIsExtensionSupported(char *ext);
-
int __glXSwapGetFBConfigsSGIX(__GLXclientState * cl, GLbyte * pc);
/************************************************************************/
diff --git a/xorg-server/hw/dmx/glxProxy/glxext.h b/xorg-server/hw/dmx/glxProxy/glxext.h
index 47cec15cf..b96ebc1f4 100644
--- a/xorg-server/hw/dmx/glxProxy/glxext.h
+++ b/xorg-server/hw/dmx/glxProxy/glxext.h
@@ -53,6 +53,7 @@ extern void __glXFlushContextCache(void);
extern void __glXFreeGLXWindow(__glXWindow * pGlxWindow);
extern void __glXFreeGLXPixmap(__GLXpixmap * pGlxPixmap);
+extern void __glXFreeGLXPbuffer(__glXPbuffer * pGlxPbuffer);
extern void __glXNoSuchRenderOpcode(GLbyte *);
extern int __glXNoSuchSingleOpcode(__GLXclientState *, GLbyte *);
diff --git a/xorg-server/hw/dmx/glxProxy/glxscreens.c b/xorg-server/hw/dmx/glxProxy/glxscreens.c
index 138afedf2..15bb1e862 100644
--- a/xorg-server/hw/dmx/glxProxy/glxscreens.c
+++ b/xorg-server/hw/dmx/glxProxy/glxscreens.c
@@ -65,8 +65,6 @@ static void
CalcServerVersionAndExtensions(void)
{
int s;
- xGLXQueryVersionReq *req;
- xGLXQueryVersionReply reply;
char **be_extensions;
char *ext;
char *denied_extensions;
@@ -80,6 +78,8 @@ CalcServerVersionAndExtensions(void)
for (s = 0; s < __glXNumActiveScreens; s++) {
DMXScreenInfo *dmxScreen = &dmxScreens[s];
Display *dpy = dmxScreen->beDisplay;
+ xGLXQueryVersionReq *req;
+ xGLXQueryVersionReply reply;
/* Send the glXQueryVersion request */
LockDisplay(dpy);
@@ -335,7 +335,7 @@ __glXGetServerString(unsigned int name)
}
int
-glxIsExtensionSupported(char *ext)
+glxIsExtensionSupported(const char *ext)
{
return (strstr(ExtensionsString, ext) != NULL);
}
diff --git a/xorg-server/hw/dmx/glxProxy/glxscreens.h b/xorg-server/hw/dmx/glxProxy/glxscreens.h
index a9fe2a9db..bb7477bc7 100644
--- a/xorg-server/hw/dmx/glxProxy/glxscreens.h
+++ b/xorg-server/hw/dmx/glxProxy/glxscreens.h
@@ -50,4 +50,6 @@ extern void __glXScreenReset(void);
extern char *__glXGetServerString(unsigned int name);
+extern int glxIsExtensionSupported(const char *ext);
+
#endif /* !__GLX_screens_h__ */
diff --git a/xorg-server/hw/dmx/glxProxy/glxserver.h b/xorg-server/hw/dmx/glxProxy/glxserver.h
index 754ad30a0..7aa5ad2f2 100644
--- a/xorg-server/hw/dmx/glxProxy/glxserver.h
+++ b/xorg-server/hw/dmx/glxProxy/glxserver.h
@@ -149,9 +149,7 @@ extern __GLXclientState *__glXClients[];
typedef void (*__GLXdispatchRenderProcPtr) (GLbyte *);
typedef int (*__GLXdispatchSingleProcPtr) (__GLXclientState *, GLbyte *);
typedef int (*__GLXdispatchVendorPrivProcPtr) (__GLXclientState *, GLbyte *);
-extern __GLXdispatchSingleProcPtr __glXSingleTable[];
extern __GLXdispatchVendorPrivProcPtr __glXVendorPrivTable_EXT[];
-extern __GLXdispatchSingleProcPtr __glXSwapSingleTable[];
extern __GLXdispatchVendorPrivProcPtr __glXSwapVendorPrivTable_EXT[];
extern __GLXdispatchRenderProcPtr __glXSwapRenderTable[];
@@ -193,9 +191,6 @@ extern RESTYPE __glXPbufferRes;
extern char *__glXcombine_strings(const char *, const char *);
-extern void __glXDisp_DrawArrays(GLbyte *);
-extern void __glXDispSwap_DrawArrays(GLbyte *);
-
/*
** Routines for sending swapped replies.
*/
@@ -287,9 +282,6 @@ extern int __glXConvolutionParameterfvSize(GLenum pname);
extern int __glXColorTableParameterfvSize(GLenum pname);
extern int __glXColorTableParameterivSize(GLenum pname);
-extern void __glXFreeGLXWindow(__glXWindow * pGlxWindow);
-extern void __glXFreeGLXPbuffer(__glXPbuffer * pGlxPbuffer);
-
extern int __glXVersionMajor;
extern int __glXVersionMinor;
diff --git a/xorg-server/hw/dmx/glxProxy/glxsingle.c b/xorg-server/hw/dmx/glxProxy/glxsingle.c
index 034497315..79d426bbf 100644
--- a/xorg-server/hw/dmx/glxProxy/glxsingle.c
+++ b/xorg-server/hw/dmx/glxProxy/glxsingle.c
@@ -45,6 +45,8 @@
/* #include "g_disptab_EXT.h" */
#include "unpack.h"
#include "glxutil.h"
+#include "glxcmds.h"
+#include "glxsingle.h"
#include "GL/glxproto.h"
@@ -81,10 +83,6 @@
#define X_GLXSingle 0 /* needed by GetReqExtra */
-extern Display *GetBackEndDisplay(__GLXclientState * cl, int s);
-extern int GetCurrentBackEndTag(__GLXclientState * cl, GLXContextTag tag,
- int s);
-
static int swap_vec_element_size = 0;
static void
diff --git a/xorg-server/hw/dmx/glxProxy/glxsingle.h b/xorg-server/hw/dmx/glxProxy/glxsingle.h
index 32a9d4921..6126177fa 100644
--- a/xorg-server/hw/dmx/glxProxy/glxsingle.h
+++ b/xorg-server/hw/dmx/glxProxy/glxsingle.h
@@ -47,8 +47,4 @@ extern int __glXForwardAllWithReplySwapsv(__GLXclientState * cl, GLbyte * pc);
extern int __glXForwardAllWithReplySwapiv(__GLXclientState * cl, GLbyte * pc);
extern int __glXForwardAllWithReplySwapdv(__GLXclientState * cl, GLbyte * pc);
-extern int __glXDisp_ReadPixels(__GLXclientState * cl, GLbyte * pc);
-extern int __glXDispSwap_GetTexImage(__GLXclientState * cl, GLbyte * pc);
-extern int __glXDispSwap_GetColorTable(__GLXclientState * cl, GLbyte * pc);
-
#endif
diff --git a/xorg-server/hw/dmx/glxProxy/glxswap.c b/xorg-server/hw/dmx/glxProxy/glxswap.c
index 5f565010d..bc18e5518 100644
--- a/xorg-server/hw/dmx/glxProxy/glxswap.c
+++ b/xorg-server/hw/dmx/glxProxy/glxswap.c
@@ -39,9 +39,7 @@
#include "dmxwindow.h"
#include "glxserver.h"
#include "glxswap.h"
-
-extern int __glXDoSwapBuffers(__GLXclientState * cl, XID drawId,
- GLXContextTag tag);
+#include "glxcmds.h"
typedef struct _SwapGroup *SwapGroupPtr;
diff --git a/xorg-server/hw/dmx/glxProxy/glxvendor.c b/xorg-server/hw/dmx/glxProxy/glxvendor.c
index fc8aff0cc..52d70eb70 100644
--- a/xorg-server/hw/dmx/glxProxy/glxvendor.c
+++ b/xorg-server/hw/dmx/glxProxy/glxvendor.c
@@ -44,6 +44,8 @@
/* #include "g_disptab_EXT.h" */
#include "unpack.h"
#include "glxutil.h"
+#include "glxcmds.h"
+#include "glxvendor.h"
#include "GL/glxproto.h"
@@ -78,10 +80,6 @@
dpy->request++
#endif
-extern Display *GetBackEndDisplay(__GLXclientState * cl, int s);
-extern int GetCurrentBackEndTag(__GLXclientState * cl, GLXContextTag tag,
- int s);
-
static int swap_vec_element_size = 0;
static void
diff --git a/xorg-server/hw/dmx/input/dmxinputinit.c b/xorg-server/hw/dmx/input/dmxinputinit.c
index abb6a8551..56a39df8c 100644
--- a/xorg-server/hw/dmx/input/dmxinputinit.c
+++ b/xorg-server/hw/dmx/input/dmxinputinit.c
@@ -874,17 +874,17 @@ dmxInputScanForExtensions(DMXInputInfo * dmxInput, int doXI)
{
XExtensionVersion *ext;
XDeviceInfo *devices;
- Display *display;
+ Display *dsp;
int num;
int i, j;
XextErrorHandler handler;
- if (!(display = XOpenDisplay(dmxInput->name)))
+ if (!(dsp = XOpenDisplay(dmxInput->name)))
return;
/* Print out information about the XInput Extension. */
handler = XSetExtensionErrorHandler(dmxInputExtensionErrorHandler);
- ext = XGetExtensionVersion(display, INAME);
+ ext = XGetExtensionVersion(dsp, INAME);
XSetExtensionErrorHandler(handler);
if (!ext || ext == (XExtensionVersion *) NoSuchExtension) {
@@ -894,7 +894,7 @@ dmxInputScanForExtensions(DMXInputInfo * dmxInput, int doXI)
dmxLogInput(dmxInput, "Locating devices on %s (%s version %d.%d)\n",
dmxInput->name, INAME,
ext->major_version, ext->minor_version);
- devices = XListInputDevices(display, &num);
+ devices = XListInputDevices(dsp, &num);
XFree(ext);
ext = NULL;
@@ -956,7 +956,7 @@ dmxInputScanForExtensions(DMXInputInfo * dmxInput, int doXI)
}
XFreeDeviceList(devices);
}
- XCloseDisplay(display);
+ XCloseDisplay(dsp);
}
/** Re-initialize all the devices described in \a dmxInput. Called from
diff --git a/xorg-server/hw/kdrive/ephyr/ephyr.c b/xorg-server/hw/kdrive/ephyr/ephyr.c
index e879faff5..0be94b4d0 100644
--- a/xorg-server/hw/kdrive/ephyr/ephyr.c
+++ b/xorg-server/hw/kdrive/ephyr/ephyr.c
@@ -809,7 +809,11 @@ ephyrUpdateModifierState(unsigned int state)
for (key = 0; key < MAP_LENGTH; key++)
if (keyc->xkbInfo->desc->map->modmap[key] & mask) {
- if (key_is_down(pDev, key, KEY_PROCESSED))
+ if (mask == XCB_MOD_MASK_LOCK) {
+ KdEnqueueKeyboardEvent(ephyrKbd, key, FALSE);
+ KdEnqueueKeyboardEvent(ephyrKbd, key, TRUE);
+ }
+ else if (key_is_down(pDev, key, KEY_PROCESSED))
KdEnqueueKeyboardEvent(ephyrKbd, key, TRUE);
if (--count == 0)
@@ -823,6 +827,8 @@ ephyrUpdateModifierState(unsigned int state)
for (key = 0; key < MAP_LENGTH; key++)
if (keyc->xkbInfo->desc->map->modmap[key] & mask) {
KdEnqueueKeyboardEvent(ephyrKbd, key, FALSE);
+ if (mask == XCB_MOD_MASK_LOCK)
+ KdEnqueueKeyboardEvent(ephyrKbd, key, TRUE);
break;
}
}
@@ -1303,7 +1309,7 @@ ephyrPutColors(ScreenPtr pScreen, int n, xColorItem * pdefs)
if (p > max)
max = p;
- hostx_set_cmap_entry(p,
+ hostx_set_cmap_entry(pScreen, p,
pdefs->red >> 8,
pdefs->green >> 8, pdefs->blue >> 8);
pdefs++;
diff --git a/xorg-server/hw/kdrive/ephyr/ephyr.h b/xorg-server/hw/kdrive/ephyr/ephyr.h
index 01045e104..9a9fe2a79 100644
--- a/xorg-server/hw/kdrive/ephyr/ephyr.h
+++ b/xorg-server/hw/kdrive/ephyr/ephyr.h
@@ -85,6 +85,7 @@ typedef struct _ephyrScrPriv {
KdScreenInfo *screen;
int mynum; /* Screen number */
+ unsigned long cmap[256];
/**
* Per-screen Xlib-using state for glamor (private to
diff --git a/xorg-server/hw/kdrive/ephyr/hostx.c b/xorg-server/hw/kdrive/ephyr/hostx.c
index 7a3338f11..0baf35929 100755
--- a/xorg-server/hw/kdrive/ephyr/hostx.c
+++ b/xorg-server/hw/kdrive/ephyr/hostx.c
@@ -84,8 +84,6 @@ struct EphyrHostXVars {
KdScreenInfo **screens;
long damage_debug_msec;
-
- unsigned long cmap[256];
};
/* memset ( missing> ) instead of below */
@@ -761,9 +759,12 @@ hostx_calculate_color_shift(unsigned long mask)
}
void
-hostx_set_cmap_entry(unsigned char idx,
+hostx_set_cmap_entry(ScreenPtr pScreen, unsigned char idx,
unsigned char r, unsigned char g, unsigned char b)
{
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ EphyrScrPriv *scrpriv = screen->driver;
/* need to calculate the shifts for RGB because server could be BGR. */
/* XXX Not sure if this is correct for 8 on 16, but this works for 8 on 24.*/
static int rshift, bshift, gshift = 0;
@@ -775,7 +776,7 @@ hostx_set_cmap_entry(unsigned char idx,
gshift = hostx_calculate_color_shift(HostX.visual->green_mask);
bshift = hostx_calculate_color_shift(HostX.visual->blue_mask);
}
- HostX.cmap[idx] = ((r << rshift) & HostX.visual->red_mask) |
+ scrpriv->cmap[idx] = ((r << rshift) & HostX.visual->red_mask) |
((g << gshift) & HostX.visual->green_mask) |
((b << bshift) & HostX.visual->blue_mask);
}
@@ -1035,7 +1036,7 @@ hostx_paint_rect(KdScreenInfo *screen,
unsigned char pixel =
*(unsigned char *) (scrpriv->fb_data + idx);
xcb_image_put_pixel(scrpriv->ximg, x, y,
- HostX.cmap[pixel]);
+ scrpriv->cmap[pixel]);
break;
}
default:
diff --git a/xorg-server/hw/kdrive/ephyr/hostx.h b/xorg-server/hw/kdrive/ephyr/hostx.h
index 1e81747cc..679dfd3ad 100644
--- a/xorg-server/hw/kdrive/ephyr/hostx.h
+++ b/xorg-server/hw/kdrive/ephyr/hostx.h
@@ -145,7 +145,7 @@ hostx_get_visual_masks(KdScreenInfo *screen,
CARD32 *rmsk, CARD32 *gmsk, CARD32 *bmsk);
void
-hostx_set_cmap_entry(unsigned char idx,
+hostx_set_cmap_entry(ScreenPtr pScreen, unsigned char idx,
unsigned char r, unsigned char g, unsigned char b);
void *hostx_screen_init(KdScreenInfo *screen,
diff --git a/xorg-server/hw/xfree86/Makefile.am b/xorg-server/hw/xfree86/Makefile.am
index d46bf0a86..27f2cc6cb 100644
--- a/xorg-server/hw/xfree86/Makefile.am
+++ b/xorg-server/hw/xfree86/Makefile.am
@@ -106,7 +106,7 @@ if INSTALL_SETUID
endif
if SUID_WRAPPER
$(MKDIR_P) $(DESTDIR)$(SUID_WRAPPER_DIR)
- mv $(DESTDIR)$(bindir)/Xorg $(DESTDIR)$(SUID_WRAPPER_DIR)/Xorg.bin
+ mv $(DESTDIR)$(bindir)/Xorg $(DESTDIR)$(SUID_WRAPPER_DIR)/Xorg
${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
endif
diff --git a/xorg-server/hw/xfree86/Xorg.sh.in b/xorg-server/hw/xfree86/Xorg.sh.in
index cef4859c8..481413523 100644
--- a/xorg-server/hw/xfree86/Xorg.sh.in
+++ b/xorg-server/hw/xfree86/Xorg.sh.in
@@ -1,11 +1,11 @@
#!/bin/sh
#
-# Execute Xorg.wrap if it exists otherwise execute Xorg.bin directly.
+# Execute Xorg.wrap if it exists otherwise execute Xorg directly.
# This allows distros to put the suid wrapper in a separate package.
basedir=@SUID_WRAPPER_DIR@
if [ -x "$basedir"/Xorg.wrap ]; then
exec "$basedir"/Xorg.wrap "$@"
else
- exec "$basedir"/Xorg.bin "$@"
+ exec "$basedir"/Xorg "$@"
fi
diff --git a/xorg-server/hw/xfree86/common/xf86AutoConfig.c b/xorg-server/hw/xfree86/common/xf86AutoConfig.c
index 03dad150a..1450afbfc 100644
--- a/xorg-server/hw/xfree86/common/xf86AutoConfig.c
+++ b/xorg-server/hw/xfree86/common/xf86AutoConfig.c
@@ -208,7 +208,6 @@ listPossibleVideoDrivers(char *matches[], int nmatches)
if (xf86Info.consoleFd >= 0 && (i < (nmatches - 1))) {
struct vis_identifier visid;
const char *cp;
- extern char xf86SolarisFbDev[PATH_MAX];
int iret;
SYSCALL(iret = ioctl(xf86Info.consoleFd, VIS_GETIDENTIFIER, &visid));
diff --git a/xorg-server/hw/xfree86/dri2/dri2.c b/xorg-server/hw/xfree86/dri2/dri2.c
index c8fcd6220..0c038b3d1 100644
--- a/xorg-server/hw/xfree86/dri2/dri2.c
+++ b/xorg-server/hw/xfree86/dri2/dri2.c
@@ -156,6 +156,9 @@ GetScreenPrime(ScreenPtr master, int prime_id)
DRI2ScreenPtr ds;
ds = DRI2GetScreen(slave);
+ if (ds == NULL)
+ continue;
+
if (ds->prime_id == prime_id)
return slave;
}
@@ -1573,15 +1576,15 @@ DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info)
if (info->version == 3 || info->numDrivers == 0) {
/* Driver too old: use the old-style driverName field */
- ds->numDrivers = 1;
- ds->driverNames = malloc(sizeof(*ds->driverNames));
+ ds->numDrivers = info->driverName ? 1 : 2;
+ ds->driverNames = malloc(ds->numDrivers * sizeof(*ds->driverNames));
if (!ds->driverNames)
goto err_out;
if (info->driverName) {
ds->driverNames[0] = info->driverName;
} else {
- ds->driverNames[0] = dri2_probe_driver_name(pScreen, info);
+ ds->driverNames[0] = ds->driverNames[1] = dri2_probe_driver_name(pScreen, info);
if (!ds->driverNames[0])
return FALSE;
}
diff --git a/xorg-server/hw/xfree86/dri2/dri2ext.c b/xorg-server/hw/xfree86/dri2/dri2ext.c
index ffd66fad6..221ec530b 100644
--- a/xorg-server/hw/xfree86/dri2/dri2ext.c
+++ b/xorg-server/hw/xfree86/dri2/dri2ext.c
@@ -270,6 +270,9 @@ ProcDRI2GetBuffers(ClientPtr client)
unsigned int *attachments;
REQUEST_FIXED_SIZE(xDRI2GetBuffersReq, stuff->count * 4);
+ if (stuff->count > (INT_MAX / 4))
+ return BadLength;
+
if (!validDrawable(client, stuff->drawable, DixReadAccess | DixWriteAccess,
&pDrawable, &status))
return status;
diff --git a/xorg-server/hw/xfree86/drivers/modesetting/Makefile.am b/xorg-server/hw/xfree86/drivers/modesetting/Makefile.am
index 5b08600c1..82c4f2f32 100644
--- a/xorg-server/hw/xfree86/drivers/modesetting/Makefile.am
+++ b/xorg-server/hw/xfree86/drivers/modesetting/Makefile.am
@@ -48,6 +48,9 @@ modesetting_drv_la_SOURCES = \
driver.h \
drmmode_display.c \
drmmode_display.h \
+ dumb_bo.c \
+ dumb_bo.h \
+ present.c \
vblank.c \
$(NULL)
diff --git a/xorg-server/hw/xfree86/drivers/modesetting/dri2.c b/xorg-server/hw/xfree86/drivers/modesetting/dri2.c
index 6c88060b0..63cb0659d 100644
--- a/xorg-server/hw/xfree86/drivers/modesetting/dri2.c
+++ b/xorg-server/hw/xfree86/drivers/modesetting/dri2.c
@@ -43,8 +43,6 @@
#include "dri2.h"
#ifdef GLAMOR
-#define GLAMOR_FOR_XORG 1
-#include "glamor.h"
enum ms_dri2_frame_event_type {
MS_DRI2_QUEUE_SWAP,
diff --git a/xorg-server/hw/xfree86/drivers/modesetting/driver.c b/xorg-server/hw/xfree86/drivers/modesetting/driver.c
index 592f2469b..d52517d1a 100644
--- a/xorg-server/hw/xfree86/drivers/modesetting/driver.c
+++ b/xorg-server/hw/xfree86/drivers/modesetting/driver.c
@@ -61,11 +61,6 @@
#include "driver.h"
-#ifdef GLAMOR
-#define GLAMOR_FOR_XORG 1
-#include "glamor.h"
-#endif
-
static void AdjustFrame(ScrnInfoPtr pScrn, int x, int y);
static Bool CloseScreen(ScreenPtr pScreen);
static Bool EnterVT(ScrnInfoPtr pScrn);
@@ -453,11 +448,12 @@ dispatch_dirty_region(ScrnInfoPtr scrn,
modesettingPtr ms = modesettingPTR(scrn);
RegionPtr dirty = DamageRegion(damage);
unsigned num_cliprects = REGION_NUM_RECTS(dirty);
+ int ret = 0;
if (num_cliprects) {
drmModeClip *clip = malloc(num_cliprects * sizeof(drmModeClip));
BoxPtr rect = REGION_RECTS(dirty);
- int i, ret;
+ int i;
if (!clip)
return -ENOMEM;
@@ -474,12 +470,8 @@ dispatch_dirty_region(ScrnInfoPtr scrn,
ret = drmModeDirtyFB(ms->fd, fb_id, clip, num_cliprects);
free(clip);
DamageEmpty(damage);
- if (ret) {
- if (ret == -EINVAL)
- return ret;
- }
}
- return 0;
+ return ret;
}
static void
@@ -546,6 +538,7 @@ msBlockHandler(ScreenPtr pScreen, void *pTimeout, void *pReadmask)
pScreen->BlockHandler = ms->BlockHandler;
pScreen->BlockHandler(pScreen, pTimeout, pReadmask);
+ ms->BlockHandler = pScreen->BlockHandler;
pScreen->BlockHandler = msBlockHandler;
if (pScreen->isGPU)
dispatch_slave_dirty(pScreen);
@@ -593,7 +586,7 @@ try_enable_glamor(ScrnInfoPtr pScrn)
Bool do_glamor = (!accel_method_str ||
strcmp(accel_method_str, "glamor") == 0);
- ms->glamor = FALSE;
+ ms->drmmode.glamor = FALSE;
#ifdef GLAMOR
if (!do_glamor) {
@@ -604,7 +597,7 @@ try_enable_glamor(ScrnInfoPtr pScrn)
if (xf86LoadSubModule(pScrn, GLAMOR_EGL_MODULE_NAME)) {
if (glamor_egl_init(pScrn, ms->fd)) {
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "glamor initialized\n");
- ms->glamor = TRUE;
+ ms->drmmode.glamor = TRUE;
} else {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"glamor initialization failed\n");
@@ -788,7 +781,7 @@ PreInit(ScrnInfoPtr pScrn, int flags)
try_enable_glamor(pScrn);
- if (ms->glamor) {
+ if (ms->drmmode.glamor) {
xf86LoadSubModule(pScrn, "dri2");
} else {
Bool prefer_shadow = TRUE;
@@ -861,7 +854,7 @@ msShadowWindow(ScreenPtr screen, CARD32 row, CARD32 offset, int mode,
stride = (pScrn->displayWidth * pScrn->bitsPerPixel) / 8;
*size = stride;
- return ((uint8_t *) ms->drmmode.front_bo->ptr + row * stride + offset);
+ return ((uint8_t *) ms->drmmode.front_bo.dumb->ptr + row * stride + offset);
}
static void
@@ -877,7 +870,8 @@ CreateScreenResources(ScreenPtr pScreen)
modesettingPtr ms = modesettingPTR(pScrn);
PixmapPtr rootPixmap;
Bool ret;
- void *pixels;
+ void *pixels = NULL;
+ int err;
pScreen->CreateScreenResources = ms->createScreenResources;
ret = pScreen->CreateScreenResources(pScreen);
@@ -886,27 +880,19 @@ CreateScreenResources(ScreenPtr pScreen)
if (!drmmode_set_desired_modes(pScrn, &ms->drmmode))
return FALSE;
-#ifdef GLAMOR
- if (ms->glamor) {
- if (!glamor_egl_create_textured_screen_ext(pScreen,
- ms->drmmode.front_bo->handle,
- pScrn->displayWidth *
- pScrn->bitsPerPixel / 8,
- NULL)) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "glamor_egl_create_textured_screen_ext() failed\n");
- return FALSE;
- }
- }
-#endif
+ if (!drmmode_glamor_handle_new_screen_pixmap(&ms->drmmode))
+ return FALSE;
drmmode_uevent_init(pScrn, &ms->drmmode);
if (!ms->drmmode.sw_cursor)
drmmode_map_cursor_bos(pScrn, &ms->drmmode);
- pixels = drmmode_map_front_bo(&ms->drmmode);
- if (!pixels)
- return FALSE;
+
+ if (!ms->drmmode.gbm) {
+ pixels = drmmode_map_front_bo(&ms->drmmode);
+ if (!pixels)
+ return FALSE;
+ }
rootPixmap = pScreen->GetScreenPixmap(pScreen);
@@ -922,18 +908,22 @@ CreateScreenResources(ScreenPtr pScreen)
return FALSE;
}
- ms->damage = DamageCreate(NULL, NULL, DamageReportNone, TRUE,
- pScreen, rootPixmap);
+ err = drmModeDirtyFB(ms->fd, ms->drmmode.fb_id, NULL, 0);
- if (ms->damage) {
- DamageRegister(&rootPixmap->drawable, ms->damage);
- ms->dirty_enabled = TRUE;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Damage tracking initialized\n");
- }
- else {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Failed to create screen damage record\n");
- return FALSE;
+ if (err != -EINVAL && err != -ENOSYS) {
+ ms->damage = DamageCreate(NULL, NULL, DamageReportNone, TRUE,
+ pScreen, rootPixmap);
+
+ if (ms->damage) {
+ DamageRegister(&rootPixmap->drawable, ms->damage);
+ ms->dirty_enabled = TRUE;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Damage tracking initialized\n");
+ }
+ else {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Failed to create screen damage record\n");
+ return FALSE;
+ }
}
return ret;
}
@@ -996,6 +986,11 @@ ScreenInit(ScreenPtr pScreen, int argc, char **argv)
if (!SetMaster(pScrn))
return FALSE;
+#ifdef GLAMOR_HAS_GBM
+ if (ms->drmmode.glamor)
+ ms->drmmode.gbm = glamor_egl_get_gbm_device(pScreen);
+#endif
+
/* HW dependent - FIXME */
pScrn->displayWidth = pScrn->virtualX;
if (!drmmode_create_initial_bos(pScrn, &ms->drmmode))
@@ -1053,7 +1048,7 @@ ScreenInit(ScreenPtr pScreen, int argc, char **argv)
fbPictureInit(pScreen, NULL, 0);
#ifdef GLAMOR
- if (ms->glamor) {
+ if (ms->drmmode.glamor) {
if (!glamor_init(pScreen,
GLAMOR_USE_EGL_SCREEN |
GLAMOR_USE_SCREEN |
@@ -1083,6 +1078,7 @@ ScreenInit(ScreenPtr pScreen, int argc, char **argv)
if (!ms->drmmode.sw_cursor)
xf86_cursors_init(pScreen, ms->cursor_width, ms->cursor_height,
HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64 |
+ HARDWARE_CURSOR_UPDATE_UNHIDDEN |
HARDWARE_CURSOR_ARGB);
/* Must force it before EnterVT, so we are in control of VT and
@@ -1106,6 +1102,19 @@ ScreenInit(ScreenPtr pScreen, int argc, char **argv)
xf86DPMSInit(pScreen, xf86DPMSSet, 0);
+#ifdef GLAMOR
+ if (ms->drmmode.glamor) {
+ XF86VideoAdaptorPtr glamor_adaptor;
+
+ glamor_adaptor = glamor_xv_init(pScreen, 16);
+ if (glamor_adaptor != NULL)
+ xf86XVScreenInit(pScreen, &glamor_adaptor, 1);
+ else
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Failed to initialize XV support.\n");
+ }
+#endif
+
if (serverGeneration == 1)
xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
@@ -1116,11 +1125,16 @@ ScreenInit(ScreenPtr pScreen, int argc, char **argv)
}
#ifdef GLAMOR
- if (ms->glamor) {
+ if (ms->drmmode.glamor) {
if (!ms_dri2_screen_init(pScreen)) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"Failed to initialize the DRI2 extension.\n");
}
+
+ if (!ms_present_screen_init(pScreen)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Failed to initialize the Present extension.\n");
+ }
}
#endif
@@ -1190,7 +1204,7 @@ CloseScreen(ScreenPtr pScreen)
modesettingPtr ms = modesettingPTR(pScrn);
#ifdef GLAMOR
- if (ms->glamor) {
+ if (ms->drmmode.glamor) {
ms_dri2_close_screen(pScreen);
}
#endif
diff --git a/xorg-server/hw/xfree86/drivers/modesetting/driver.h b/xorg-server/hw/xfree86/drivers/modesetting/driver.h
index 9eda1c4da..3decc3eea 100644
--- a/xorg-server/hw/xfree86/drivers/modesetting/driver.h
+++ b/xorg-server/hw/xfree86/drivers/modesetting/driver.h
@@ -33,6 +33,14 @@
#include <xf86Crtc.h>
#include <damage.h>
+#ifdef GLAMOR
+#define GLAMOR_FOR_XORG 1
+#include "glamor.h"
+#ifdef GLAMOR_HAS_GBM
+#include <gbm.h>
+#endif
+#endif
+
#include "drmmode_display.h"
#define DRV_ERROR(msg) xf86DrvMsg(pScrn->scrnIndex, X_ERROR, msg);
@@ -97,7 +105,6 @@ typedef struct _modesettingRec {
Bool dirty_enabled;
uint32_t cursor_width, cursor_height;
- Bool glamor;
} modesettingRec, *modesettingPtr;
#define modesettingPTR(p) ((modesettingPtr)((p)->driverPrivate))
@@ -107,6 +114,10 @@ uint32_t ms_drm_queue_alloc(xf86CrtcPtr crtc,
ms_drm_handler_proc handler,
ms_drm_abort_proc abort);
+void ms_drm_abort(ScrnInfoPtr scrn,
+ Bool (*match)(void *data, void *match_data),
+ void *match_data);
+
xf86CrtcPtr ms_dri2_crtc_covering_drawable(DrawablePtr pDraw);
xf86CrtcPtr ms_covering_crtc(ScrnInfoPtr scrn, BoxPtr box,
xf86CrtcPtr desired, BoxPtr crtc_box_ret);
@@ -122,3 +133,5 @@ void ms_dri2_close_screen(ScreenPtr screen);
Bool ms_vblank_screen_init(ScreenPtr screen);
void ms_vblank_close_screen(ScreenPtr screen);
+
+Bool ms_present_screen_init(ScreenPtr screen);
diff --git a/xorg-server/hw/xfree86/drivers/modesetting/drmmode_display.c b/xorg-server/hw/xfree86/drivers/modesetting/drmmode_display.c
index ef9009e98..1ea799b3a 100644
--- a/xorg-server/hw/xfree86/drivers/modesetting/drmmode_display.c
+++ b/xorg-server/hw/xfree86/drivers/modesetting/drmmode_display.c
@@ -33,6 +33,7 @@
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <unistd.h>
+#include "dumb_bo.h"
#include "xf86str.h"
#include "X11/Xatom.h"
#include "micmap.h"
@@ -49,112 +50,95 @@
#include "driver.h"
-static struct dumb_bo *
-dumb_bo_create(int fd,
- const unsigned width, const unsigned height, const unsigned bpp)
-{
- struct drm_mode_create_dumb arg;
- struct dumb_bo *bo;
- int ret;
-
- bo = calloc(1, sizeof(*bo));
- if (!bo)
- return NULL;
-
- memset(&arg, 0, sizeof(arg));
- arg.width = width;
- arg.height = height;
- arg.bpp = bpp;
-
- ret = drmIoctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &arg);
- if (ret)
- goto err_free;
-
- bo->handle = arg.handle;
- bo->size = arg.size;
- bo->pitch = arg.pitch;
-
- return bo;
- err_free:
- free(bo);
- return NULL;
-}
-
static int
-dumb_bo_map(int fd, struct dumb_bo *bo)
+drmmode_bo_destroy(drmmode_ptr drmmode, drmmode_bo *bo)
{
- struct drm_mode_map_dumb arg;
int ret;
- void *map;
- if (bo->ptr) {
- bo->map_count++;
- return 0;
+#ifdef GLAMOR_HAS_GBM
+ if (bo->gbm) {
+ gbm_bo_destroy(bo->gbm);
+ bo->gbm = NULL;
}
+#endif
- memset(&arg, 0, sizeof(arg));
- arg.handle = bo->handle;
-
- ret = drmIoctl(fd, DRM_IOCTL_MODE_MAP_DUMB, &arg);
- if (ret)
- return ret;
-
- map = mmap(0, bo->size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, arg.offset);
- if (map == MAP_FAILED)
- return -errno;
+ if (bo->dumb) {
+ ret = dumb_bo_destroy(drmmode->fd, bo->dumb);
+ if (ret == 0)
+ bo->dumb = NULL;
+ }
- bo->ptr = map;
return 0;
}
-#if 0
-static int
-dumb_bo_unmap(int fd, struct dumb_bo *bo)
+static uint32_t
+drmmode_bo_get_pitch(drmmode_bo *bo)
{
- bo->map_count--;
- return 0;
-}
+#ifdef GLAMOR_HAS_GBM
+ if (bo->gbm)
+ return gbm_bo_get_stride(bo->gbm);
#endif
-int
-dumb_bo_destroy(int fd, struct dumb_bo *bo)
+ return bo->dumb->pitch;
+}
+
+static Bool
+drmmode_bo_has_bo(drmmode_bo *bo)
{
- struct drm_mode_destroy_dumb arg;
- int ret;
+#ifdef GLAMOR_HAS_GBM
+ if (bo->gbm)
+ return TRUE;
+#endif
- if (bo->ptr) {
- munmap(bo->ptr, bo->size);
- bo->ptr = NULL;
- }
+ return bo->dumb != NULL;
+}
- memset(&arg, 0, sizeof(arg));
- arg.handle = bo->handle;
- ret = drmIoctl(fd, DRM_IOCTL_MODE_DESTROY_DUMB, &arg);
- if (ret)
- return -errno;
+uint32_t
+drmmode_bo_get_handle(drmmode_bo *bo)
+{
+#ifdef GLAMOR_HAS_GBM
+ if (bo->gbm)
+ return gbm_bo_get_handle(bo->gbm).u32;
+#endif
- free(bo);
- return 0;
+ return bo->dumb->handle;
}
-struct dumb_bo *
-dumb_get_bo_from_fd(int fd, int handle, int pitch, int size)
+static void *
+drmmode_bo_map(drmmode_ptr drmmode, drmmode_bo *bo)
{
- struct dumb_bo *bo;
int ret;
- bo = calloc(1, sizeof(*bo));
- if (!bo)
+#ifdef GLAMOR_HAS_GBM
+ if (bo->gbm)
return NULL;
+#endif
- ret = drmPrimeFDToHandle(fd, handle, &bo->handle);
- if (ret) {
- free(bo);
+ if (bo->dumb->ptr)
+ return bo->dumb->ptr;
+
+ ret = dumb_bo_map(drmmode->fd, bo->dumb);
+ if (ret)
return NULL;
+
+ return bo->dumb->ptr;
+}
+
+static Bool
+drmmode_create_bo(drmmode_ptr drmmode, drmmode_bo *bo,
+ unsigned width, unsigned height, unsigned bpp)
+{
+#ifdef GLAMOR_HAS_GBM
+ if (drmmode->glamor) {
+ bo->gbm = gbm_bo_create(drmmode->gbm, width, height,
+ GBM_FORMAT_ARGB8888,
+ GBM_BO_USE_RENDERING | GBM_BO_USE_SCANOUT);
+ return bo->gbm != NULL;
}
- bo->pitch = pitch;
- bo->size = size;
- return bo;
+#endif
+
+ bo->dumb = dumb_bo_create(drmmode->fd, width, height, bpp);
+ return bo->dumb != NULL;
}
Bool
@@ -232,18 +216,8 @@ drmmode_ConvertToKMode(ScrnInfoPtr scrn,
static void
drmmode_crtc_dpms(xf86CrtcPtr crtc, int mode)
{
-#if 0
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
-
-// drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
-// drmmode_ptr drmmode = drmmode_crtc->drmmode;
-
- /* bonghits in the randr 1.2 - uses dpms to disable crtc - bad buzz */
- if (mode == DPMSModeOff) {
-// drmModeSetCrtc(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id,
-// 0, 0, 0, NULL, 0, NULL);
- }
-#endif
+ drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+ drmmode_crtc->dpms_mode = mode;
}
#if 0
@@ -315,8 +289,9 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
ret = drmModeAddFB(drmmode->fd,
pScrn->virtualX, height,
pScrn->depth, pScrn->bitsPerPixel,
- drmmode->front_bo->pitch,
- drmmode->front_bo->handle, &drmmode->fb_id);
+ drmmode_bo_get_pitch(&drmmode->front_bo),
+ drmmode_bo_get_handle(&drmmode->front_bo),
+ &drmmode->fb_id);
if (ret < 0) {
ErrorF("failed to add fb %d\n", ret);
return FALSE;
@@ -385,6 +360,9 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
if (crtc->scrn->pScreen)
xf86CrtcSetScreenSubpixelOrder(crtc->scrn->pScreen);
+
+ crtc->funcs->dpms(crtc, DPMSModeOn);
+
/* go through all the outputs and force DPMS them back on? */
for (i = 0; i < xf86_config->num_output; i++) {
xf86OutputPtr output = xf86_config->output[i];
@@ -432,25 +410,32 @@ drmmode_set_cursor_position(xf86CrtcPtr crtc, int x, int y)
}
static void
-drmmode_load_cursor_argb(xf86CrtcPtr crtc, CARD32 *image)
+drmmode_set_cursor(xf86CrtcPtr crtc)
{
- modesettingPtr ms = modesettingPTR(crtc->scrn);
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
- int i;
- uint32_t *ptr;
+ drmmode_ptr drmmode = drmmode_crtc->drmmode;
uint32_t handle = drmmode_crtc->cursor_bo->handle;
+ modesettingPtr ms = modesettingPTR(crtc->scrn);
+ static Bool use_set_cursor2 = TRUE;
int ret;
- /* cursor should be mapped already */
- ptr = (uint32_t *) (drmmode_crtc->cursor_bo->ptr);
+ if (use_set_cursor2) {
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
+ CursorPtr cursor = xf86_config->cursor;
- for (i = 0; i < ms->cursor_width * ms->cursor_height; i++)
- ptr[i] = image[i]; // cpu_to_le32(image[i]);
+ ret =
+ drmModeSetCursor2(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id,
+ handle, ms->cursor_width, ms->cursor_height,
+ cursor->bits->xhot, cursor->bits->yhot);
+ if (ret == -EINVAL)
+ use_set_cursor2 = FALSE;
+ else
+ return;
+ }
+
+ ret = drmModeSetCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, handle,
+ ms->cursor_width, ms->cursor_height);
- ret =
- drmModeSetCursor(drmmode_crtc->drmmode->fd,
- drmmode_crtc->mode_crtc->crtc_id, handle,
- ms->cursor_width, ms->cursor_height);
if (ret) {
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
xf86CursorInfoPtr cursor_info = xf86_config->cursor_info;
@@ -462,46 +447,44 @@ drmmode_load_cursor_argb(xf86CrtcPtr crtc, CARD32 *image)
}
static void
-drmmode_hide_cursor(xf86CrtcPtr crtc)
+drmmode_load_cursor_argb(xf86CrtcPtr crtc, CARD32 *image)
{
modesettingPtr ms = modesettingPTR(crtc->scrn);
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
- drmmode_ptr drmmode = drmmode_crtc->drmmode;
+ int i;
+ uint32_t *ptr;
- drmModeSetCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, 0,
- ms->cursor_width, ms->cursor_height);
+ /* cursor should be mapped already */
+ ptr = (uint32_t *) (drmmode_crtc->cursor_bo->ptr);
+
+ for (i = 0; i < ms->cursor_width * ms->cursor_height; i++)
+ ptr[i] = image[i]; // cpu_to_le32(image[i]);
+ if (drmmode_crtc->cursor_up)
+ drmmode_set_cursor(crtc);
}
static void
-drmmode_show_cursor(xf86CrtcPtr crtc)
+drmmode_hide_cursor(xf86CrtcPtr crtc)
{
modesettingPtr ms = modesettingPTR(crtc->scrn);
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
drmmode_ptr drmmode = drmmode_crtc->drmmode;
- uint32_t handle = drmmode_crtc->cursor_bo->handle;
- static Bool use_set_cursor2 = TRUE;
-
- if (use_set_cursor2) {
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
- CursorPtr cursor = xf86_config->cursor;
- int ret;
-
- ret =
- drmModeSetCursor2(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id,
- handle, ms->cursor_width, ms->cursor_height,
- cursor->bits->xhot, cursor->bits->yhot);
- if (ret == -EINVAL)
- use_set_cursor2 = FALSE;
- else
- return;
- }
- drmModeSetCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, handle,
+ drmmode_crtc->cursor_up = FALSE;
+ drmModeSetCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, 0,
ms->cursor_width, ms->cursor_height);
}
static void
+drmmode_show_cursor(xf86CrtcPtr crtc)
+{
+ drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+ drmmode_crtc->cursor_up = TRUE;
+ drmmode_set_cursor(crtc);
+}
+
+static void
drmmode_crtc_gamma_set(xf86CrtcPtr crtc, uint16_t * red, uint16_t * green,
uint16_t * blue, int size)
{
@@ -557,13 +540,122 @@ drmmode_set_scanout_pixmap(xf86CrtcPtr crtc, PixmapPtr ppix)
static void *
drmmode_shadow_allocate(xf86CrtcPtr crtc, int width, int height)
{
- return NULL;
+ drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+ drmmode_ptr drmmode = drmmode_crtc->drmmode;
+ int ret;
+
+ if (!drmmode_create_bo(drmmode, &drmmode_crtc->rotate_bo,
+ width, height, crtc->scrn->bitsPerPixel)) {
+ xf86DrvMsg(crtc->scrn->scrnIndex, X_ERROR,
+ "Couldn't allocate shadow memory for rotated CRTC\n");
+ return NULL;
+ }
+
+ ret = drmModeAddFB(drmmode->fd, width, height, crtc->scrn->depth,
+ crtc->scrn->bitsPerPixel,
+ drmmode_bo_get_pitch(&drmmode_crtc->rotate_bo),
+ drmmode_bo_get_handle(&drmmode_crtc->rotate_bo),
+ &drmmode_crtc->rotate_fb_id);
+
+ if (ret) {
+ ErrorF("failed to add rotate fb\n");
+ drmmode_bo_destroy(drmmode, &drmmode_crtc->rotate_bo);
+ return NULL;
+ }
+
+#ifdef GLAMOR_HAS_GBM
+ if (drmmode->gbm)
+ return drmmode_crtc->rotate_bo.gbm;
+#endif
+ return drmmode_crtc->rotate_bo.dumb;
}
static PixmapPtr
+drmmode_create_pixmap_header(ScreenPtr pScreen, int width, int height,
+ int depth, int bitsPerPixel, int devKind,
+ void *pPixData)
+{
+ PixmapPtr pixmap;
+
+ /* width and height of 0 means don't allocate any pixmap data */
+ pixmap = (*pScreen->CreatePixmap)(pScreen, 0, 0, depth, 0);
+
+ if (pixmap) {
+ if ((*pScreen->ModifyPixmapHeader)(pixmap, width, height, depth,
+ bitsPerPixel, devKind, pPixData))
+ return pixmap;
+ (*pScreen->DestroyPixmap)(pixmap);
+ }
+ return NullPixmap;
+}
+
+static Bool
+drmmode_set_pixmap_bo(drmmode_ptr drmmode, PixmapPtr pixmap, drmmode_bo *bo);
+
+static PixmapPtr
drmmode_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height)
{
- return NULL;
+ ScrnInfoPtr scrn = crtc->scrn;
+ drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+ drmmode_ptr drmmode = drmmode_crtc->drmmode;
+ uint32_t rotate_pitch;
+ PixmapPtr rotate_pixmap;
+ void *pPixData = NULL;
+
+ if (!data) {
+ data = drmmode_shadow_allocate(crtc, width, height);
+ if (!data) {
+ xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+ "Couldn't allocate shadow pixmap for rotated CRTC\n");
+ return NULL;
+ }
+ }
+
+ if (!drmmode_bo_has_bo(&drmmode_crtc->rotate_bo)) {
+ xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+ "Couldn't allocate shadow pixmap for rotated CRTC\n");
+ return NULL;
+ }
+
+ pPixData = drmmode_bo_map(drmmode, &drmmode_crtc->rotate_bo);
+ rotate_pitch = drmmode_bo_get_pitch(&drmmode_crtc->rotate_bo),
+
+ rotate_pixmap = drmmode_create_pixmap_header(scrn->pScreen,
+ width, height,
+ scrn->depth,
+ scrn->bitsPerPixel,
+ rotate_pitch,
+ pPixData);
+
+ if (rotate_pixmap == NULL) {
+ xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+ "Couldn't allocate shadow pixmap for rotated CRTC\n");
+ return NULL;
+ }
+
+ drmmode_set_pixmap_bo(drmmode, rotate_pixmap, &drmmode_crtc->rotate_bo);
+
+ return rotate_pixmap;
+}
+
+static void
+drmmode_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data)
+{
+ drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+ drmmode_ptr drmmode = drmmode_crtc->drmmode;
+
+ if (rotate_pixmap) {
+ drmmode_set_pixmap_bo(drmmode, rotate_pixmap, NULL);
+ rotate_pixmap->drawable.pScreen->DestroyPixmap(rotate_pixmap);
+ }
+
+ if (data) {
+ drmModeRmFB(drmmode->fd, drmmode_crtc->rotate_fb_id);
+ drmmode_crtc->rotate_fb_id = 0;
+
+ drmmode_bo_destroy(drmmode, &drmmode_crtc->rotate_bo);
+ memset(&drmmode_crtc->rotate_bo, 0, sizeof drmmode_crtc->rotate_bo);
+ }
}
static const xf86CrtcFuncsRec drmmode_crtc_funcs = {
@@ -580,6 +672,7 @@ static const xf86CrtcFuncsRec drmmode_crtc_funcs = {
.set_scanout_pixmap = drmmode_set_scanout_pixmap,
.shadow_allocate = drmmode_shadow_allocate,
.shadow_create = drmmode_shadow_create,
+ .shadow_destroy = drmmode_shadow_destroy,
};
static uint32_t
@@ -1019,8 +1112,7 @@ static const char *const output_names[] = {
};
static void
-drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num,
- int *num_dvi, int *num_hdmi)
+drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num)
{
xf86OutputPtr output;
drmModeConnectorPtr koutput;
@@ -1173,6 +1265,57 @@ drmmode_clones_init(ScrnInfoPtr scrn, drmmode_ptr drmmode)
}
static Bool
+drmmode_set_pixmap_bo(drmmode_ptr drmmode, PixmapPtr pixmap, drmmode_bo *bo)
+{
+#ifdef GLAMOR
+ ScrnInfoPtr scrn = drmmode->scrn;
+
+ if (!drmmode->glamor)
+ return TRUE;
+
+ if (bo == NULL) {
+ glamor_egl_destroy_textured_pixmap(pixmap);
+ return TRUE;
+ }
+
+#ifdef GLAMOR_HAS_GBM
+ if (!glamor_egl_create_textured_pixmap_from_gbm_bo(pixmap, bo->gbm)) {
+ xf86DrvMsg(scrn->scrnIndex, X_ERROR, "Failed");
+ return FALSE;
+ }
+#else
+ if (!glamor_egl_create_textured_pixmap(pixmap,
+ drmmode_bo_get_handle(&drmmode->front_bo),
+ scrn->displayWidth *
+ scrn->bitsPerPixel / 8)) {
+ xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+ "glamor_egl_create_textured_pixmap() failed\n");
+ return FALSE;
+ }
+#endif
+#endif
+
+ return TRUE;
+}
+
+Bool
+drmmode_glamor_handle_new_screen_pixmap(drmmode_ptr drmmode)
+{
+ ScreenPtr screen = xf86ScrnToScreen(drmmode->scrn);
+ PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen);
+
+ if (!drmmode_set_pixmap_bo(drmmode, screen_pixmap, &drmmode->front_bo))
+ return FALSE;
+
+#ifdef GLAMOR
+ if (drmmode->glamor)
+ glamor_set_screen_pixmap(screen_pixmap, NULL);
+#endif
+
+ return TRUE;
+}
+
+static Bool
drmmode_xf86crtc_resize(ScrnInfoPtr scrn, int width, int height)
{
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
@@ -1180,14 +1323,14 @@ drmmode_xf86crtc_resize(ScrnInfoPtr scrn, int width, int height)
drmmode_crtc_private_ptr
drmmode_crtc = xf86_config->crtc[0]->driver_private;
drmmode_ptr drmmode = drmmode_crtc->drmmode;
- struct dumb_bo *old_front = NULL;
+ drmmode_bo old_front;
Bool ret;
ScreenPtr screen = xf86ScrnToScreen(scrn);
uint32_t old_fb_id;
int i, pitch, old_width, old_height, old_pitch;
int cpp = (scrn->bitsPerPixel + 7) / 8;
PixmapPtr ppix = screen->GetScreenPixmap(screen);
- void *new_pixels;
+ void *new_pixels = NULL;
if (scrn->virtualX == width && scrn->virtualY == height)
return TRUE;
@@ -1202,16 +1345,15 @@ drmmode_xf86crtc_resize(ScrnInfoPtr scrn, int width, int height)
old_width = scrn->virtualX;
old_height = scrn->virtualY;
- old_pitch = drmmode->front_bo->pitch;
+ old_pitch = drmmode_bo_get_pitch(&drmmode->front_bo);
old_fb_id = drmmode->fb_id;
old_front = drmmode->front_bo;
- drmmode->front_bo =
- dumb_bo_create(drmmode->fd, width, height, scrn->bitsPerPixel);
- if (!drmmode->front_bo)
+ if (!drmmode_create_bo(drmmode, &drmmode->front_bo,
+ width, height, scrn->bitsPerPixel))
goto fail;
- pitch = drmmode->front_bo->pitch;
+ pitch = drmmode_bo_get_pitch(&drmmode->front_bo);
scrn->virtualX = width;
scrn->virtualY = height;
@@ -1219,30 +1361,32 @@ drmmode_xf86crtc_resize(ScrnInfoPtr scrn, int width, int height)
ret = drmModeAddFB(drmmode->fd, width, height, scrn->depth,
scrn->bitsPerPixel, pitch,
- drmmode->front_bo->handle, &drmmode->fb_id);
+ drmmode_bo_get_handle(&drmmode->front_bo),
+ &drmmode->fb_id);
if (ret)
goto fail;
- new_pixels = drmmode_map_front_bo(drmmode);
- if (!new_pixels)
- goto fail;
+ if (!drmmode->gbm) {
+ new_pixels = drmmode_map_front_bo(drmmode);
+ if (!new_pixels)
+ goto fail;
+ }
- if (!drmmode->shadow_enable)
- screen->ModifyPixmapHeader(ppix, width, height, -1, -1,
- pitch, new_pixels);
- else {
- void *new_shadow;
+ if (drmmode->shadow_enable) {
uint32_t size = scrn->displayWidth * scrn->virtualY *
((scrn->bitsPerPixel + 7) >> 3);
- new_shadow = calloc(1, size);
- if (new_shadow == NULL)
+ new_pixels = calloc(1, size);
+ if (new_pixels == NULL)
goto fail;
free(drmmode->shadow_fb);
- drmmode->shadow_fb = new_shadow;
- screen->ModifyPixmapHeader(ppix, width, height, -1, -1,
- pitch, drmmode->shadow_fb);
+ drmmode->shadow_fb = new_pixels;
}
+ screen->ModifyPixmapHeader(ppix, width, height, -1, -1, pitch, new_pixels);
+
+ if (!drmmode_glamor_handle_new_screen_pixmap(drmmode))
+ goto fail;
+
for (i = 0; i < xf86_config->num_crtc; i++) {
xf86CrtcPtr crtc = xf86_config->crtc[i];
@@ -1255,14 +1399,13 @@ drmmode_xf86crtc_resize(ScrnInfoPtr scrn, int width, int height)
if (old_fb_id) {
drmModeRmFB(drmmode->fd, old_fb_id);
- dumb_bo_destroy(drmmode->fd, old_front);
+ drmmode_bo_destroy(drmmode, &old_front);
}
return TRUE;
fail:
- if (drmmode->front_bo)
- dumb_bo_destroy(drmmode->fd, drmmode->front_bo);
+ drmmode_bo_destroy(drmmode, &drmmode->front_bo);
drmmode->front_bo = old_front;
scrn->virtualX = old_width;
scrn->virtualY = old_height;
@@ -1279,7 +1422,7 @@ static const xf86CrtcConfigFuncsRec drmmode_xf86crtc_config_funcs = {
Bool
drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp)
{
- int i, num_dvi = 0, num_hdmi = 0;
+ int i;
int ret;
uint64_t value = 0;
@@ -1307,7 +1450,7 @@ drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp)
drmmode_crtc_init(pScrn, drmmode, i);
for (i = 0; i < drmmode->mode_res->count_connectors; i++)
- drmmode_output_init(pScrn, drmmode, i, &num_dvi, &num_hdmi);
+ drmmode_output_init(pScrn, drmmode, i);
/* workout clones */
drmmode_clones_init(pScrn, drmmode);
@@ -1468,7 +1611,7 @@ drmmode_setup_colormap(ScreenPtr pScreen, ScrnInfoPtr pScrn)
return TRUE;
}
-#ifdef HAVE_UDEV
+#ifdef CONFIG_UDEV_KMS
static void
drmmode_handle_uevents(int fd, void *closure)
{
@@ -1488,7 +1631,7 @@ drmmode_handle_uevents(int fd, void *closure)
void
drmmode_uevent_init(ScrnInfoPtr scrn, drmmode_ptr drmmode)
{
-#ifdef HAVE_UDEV
+#ifdef CONFIG_UDEV_KMS
struct udev *u;
struct udev_monitor *mon;
@@ -1521,7 +1664,7 @@ drmmode_uevent_init(ScrnInfoPtr scrn, drmmode_ptr drmmode)
void
drmmode_uevent_fini(ScrnInfoPtr scrn, drmmode_ptr drmmode)
{
-#ifdef HAVE_UDEV
+#ifdef CONFIG_UDEV_KMS
if (drmmode->uevent_handler) {
struct udev *u = udev_monitor_get_udev(drmmode->uevent_monitor);
@@ -1548,10 +1691,9 @@ drmmode_create_initial_bos(ScrnInfoPtr pScrn, drmmode_ptr drmmode)
width = pScrn->virtualX;
height = pScrn->virtualY;
- drmmode->front_bo = dumb_bo_create(drmmode->fd, width, height, bpp);
- if (!drmmode->front_bo)
+ if (!drmmode_create_bo(drmmode, &drmmode->front_bo, width, height, bpp))
return FALSE;
- pScrn->displayWidth = drmmode->front_bo->pitch / cpp;
+ pScrn->displayWidth = drmmode_bo_get_pitch(&drmmode->front_bo) / cpp;
width = ms->cursor_width;
height = ms->cursor_height;
@@ -1569,17 +1711,7 @@ drmmode_create_initial_bos(ScrnInfoPtr pScrn, drmmode_ptr drmmode)
void *
drmmode_map_front_bo(drmmode_ptr drmmode)
{
- int ret;
-
- if (drmmode->front_bo->ptr)
- return drmmode->front_bo->ptr;
-
- ret = dumb_bo_map(drmmode->fd, drmmode->front_bo);
- if (ret)
- return NULL;
-
- return drmmode->front_bo->ptr;
-
+ return drmmode_bo_map(drmmode, &drmmode->front_bo);
}
void *
@@ -1625,8 +1757,7 @@ drmmode_free_bos(ScrnInfoPtr pScrn, drmmode_ptr drmmode)
drmmode->fb_id = 0;
}
- dumb_bo_destroy(drmmode->fd, drmmode->front_bo);
- drmmode->front_bo = NULL;
+ drmmode_bo_destroy(drmmode, &drmmode->front_bo);
for (i = 0; i < xf86_config->num_crtc; i++) {
xf86CrtcPtr crtc = xf86_config->crtc[i];
diff --git a/xorg-server/hw/xfree86/drivers/modesetting/drmmode_display.h b/xorg-server/hw/xfree86/drivers/modesetting/drmmode_display.h
index 987608c55..3a8959ac3 100644
--- a/xorg-server/hw/xfree86/drivers/modesetting/drmmode_display.h
+++ b/xorg-server/hw/xfree86/drivers/modesetting/drmmode_display.h
@@ -28,17 +28,20 @@
#define DRMMODE_DISPLAY_H
#include "xf86drmMode.h"
-#ifdef HAVE_UDEV
+#ifdef CONFIG_UDEV_KMS
#include "libudev.h"
#endif
-struct dumb_bo {
- uint32_t handle;
- uint32_t size;
- void *ptr;
- int map_count;
- uint32_t pitch;
-};
+#include "dumb_bo.h"
+
+struct gbm_device;
+
+typedef struct {
+ struct dumb_bo *dumb;
+#ifdef GLAMOR_HAS_GBM
+ struct gbm_bo *gbm;
+#endif
+} drmmode_bo;
typedef struct {
int fd;
@@ -48,14 +51,18 @@ typedef struct {
drmModeFBPtr mode_fb;
int cpp;
ScrnInfoPtr scrn;
-#ifdef HAVE_UDEV
+
+ struct gbm_device *gbm;
+
+#ifdef CONFIG_UDEV_KMS
struct udev_monitor *uevent_monitor;
InputHandlerProc uevent_handler;
#endif
drmEventContext event_context;
- struct dumb_bo *front_bo;
+ drmmode_bo front_bo;
Bool sw_cursor;
+ Bool glamor;
Bool shadow_enable;
void *shadow_fb;
@@ -79,11 +86,15 @@ typedef struct {
drmmode_ptr drmmode;
drmModeCrtcPtr mode_crtc;
uint32_t vblank_pipe;
+ int dpms_mode;
struct dumb_bo *cursor_bo;
- unsigned rotate_fb_id;
+ Bool cursor_up;
uint16_t lut_r[256], lut_g[256], lut_b[256];
DamagePtr slave_damage;
+ drmmode_bo rotate_bo;
+ unsigned rotate_fb_id;
+
/**
* @{ MSC (vblank count) handling for the PRESENT extension.
*
@@ -128,6 +139,8 @@ extern DevPrivateKeyRec msPixmapPrivateKeyRec;
#define msGetPixmapPriv(drmmode, p) ((msPixmapPrivPtr)dixGetPrivateAddr(&(p)->devPrivates, &(drmmode)->pixmapPrivateKeyRec))
+uint32_t drmmode_bo_get_handle(drmmode_bo *bo);
+Bool drmmode_glamor_handle_new_screen_pixmap(drmmode_ptr drmmode);
void *drmmode_map_slave_bo(drmmode_ptr drmmode, msPixmapPrivPtr ppriv);
Bool drmmode_SetSlaveBO(PixmapPtr ppix,
drmmode_ptr drmmode,
@@ -147,8 +160,6 @@ Bool drmmode_map_cursor_bos(ScrnInfoPtr pScrn, drmmode_ptr drmmode);
void drmmode_free_bos(ScrnInfoPtr pScrn, drmmode_ptr drmmode);
void drmmode_get_default_bpp(ScrnInfoPtr pScrn, drmmode_ptr drmmmode,
int *depth, int *bpp);
-struct dumb_bo *dumb_get_bo_from_fd(int drm_fd, int fd, int pitch, int size);
-int dumb_bo_destroy(int fd, struct dumb_bo *bo);
#ifndef DRM_CAP_DUMB_PREFERRED_DEPTH
diff --git a/xorg-server/hw/xfree86/drivers/modesetting/dumb_bo.c b/xorg-server/hw/xfree86/drivers/modesetting/dumb_bo.c
new file mode 100644
index 000000000..58d420e07
--- /dev/null
+++ b/xorg-server/hw/xfree86/drivers/modesetting/dumb_bo.c
@@ -0,0 +1,134 @@
+/*
+ * Copyright © 2007 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:
+ * Dave Airlie <airlied@redhat.com>
+ *
+ */
+
+#include "dumb_bo.h"
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <xf86drm.h>
+
+struct dumb_bo *
+dumb_bo_create(int fd,
+ const unsigned width, const unsigned height, const unsigned bpp)
+{
+ struct drm_mode_create_dumb arg;
+ struct dumb_bo *bo;
+ int ret;
+
+ bo = calloc(1, sizeof(*bo));
+ if (!bo)
+ return NULL;
+
+ memset(&arg, 0, sizeof(arg));
+ arg.width = width;
+ arg.height = height;
+ arg.bpp = bpp;
+
+ ret = drmIoctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &arg);
+ if (ret)
+ goto err_free;
+
+ bo->handle = arg.handle;
+ bo->size = arg.size;
+ bo->pitch = arg.pitch;
+
+ return bo;
+ err_free:
+ free(bo);
+ return NULL;
+}
+
+int
+dumb_bo_map(int fd, struct dumb_bo *bo)
+{
+ struct drm_mode_map_dumb arg;
+ int ret;
+ void *map;
+
+ if (bo->ptr) {
+ return 0;
+ }
+
+ memset(&arg, 0, sizeof(arg));
+ arg.handle = bo->handle;
+
+ ret = drmIoctl(fd, DRM_IOCTL_MODE_MAP_DUMB, &arg);
+ if (ret)
+ return ret;
+
+ map = mmap(0, bo->size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, arg.offset);
+ if (map == MAP_FAILED)
+ return -errno;
+
+ bo->ptr = map;
+ return 0;
+}
+
+int
+dumb_bo_destroy(int fd, struct dumb_bo *bo)
+{
+ struct drm_mode_destroy_dumb arg;
+ int ret;
+
+ if (bo->ptr) {
+ munmap(bo->ptr, bo->size);
+ bo->ptr = NULL;
+ }
+
+ memset(&arg, 0, sizeof(arg));
+ arg.handle = bo->handle;
+ ret = drmIoctl(fd, DRM_IOCTL_MODE_DESTROY_DUMB, &arg);
+ if (ret)
+ return -errno;
+
+ free(bo);
+ return 0;
+}
+
+struct dumb_bo *
+dumb_get_bo_from_fd(int fd, int handle, int pitch, int size)
+{
+ struct dumb_bo *bo;
+ int ret;
+
+ bo = calloc(1, sizeof(*bo));
+ if (!bo)
+ return NULL;
+
+ ret = drmPrimeFDToHandle(fd, handle, &bo->handle);
+ if (ret) {
+ free(bo);
+ return NULL;
+ }
+ bo->pitch = pitch;
+ bo->size = size;
+ return bo;
+}
diff --git a/xorg-server/hw/xfree86/drivers/modesetting/dumb_bo.h b/xorg-server/hw/xfree86/drivers/modesetting/dumb_bo.h
new file mode 100644
index 000000000..9235e61e2
--- /dev/null
+++ b/xorg-server/hw/xfree86/drivers/modesetting/dumb_bo.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright © 2007 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:
+ * Dave Airlie <airlied@redhat.com>
+ *
+ */
+#ifndef DUMB_BO_H
+#define DUMB_BO_H
+
+#include <stdint.h>
+
+struct dumb_bo {
+ uint32_t handle;
+ uint32_t size;
+ void *ptr;
+ uint32_t pitch;
+};
+
+struct dumb_bo *dumb_bo_create(int fd, const unsigned width,
+ const unsigned height, const unsigned bpp);
+int dumb_bo_map(int fd, struct dumb_bo *bo);
+int dumb_bo_destroy(int fd, struct dumb_bo *bo);
+struct dumb_bo *dumb_get_bo_from_fd(int fd, int handle, int pitch, int size);
+
+#endif
diff --git a/xorg-server/hw/xfree86/drivers/modesetting/present.c b/xorg-server/hw/xfree86/drivers/modesetting/present.c
new file mode 100644
index 000000000..359e11316
--- /dev/null
+++ b/xorg-server/hw/xfree86/drivers/modesetting/present.c
@@ -0,0 +1,228 @@
+/*
+ * 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.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include "dix-config.h"
+#endif
+
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <poll.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <time.h>
+
+#include <xf86.h>
+#include <xf86Crtc.h>
+#include <xf86drm.h>
+#include <xf86str.h>
+#include <present.h>
+
+#include "driver.h"
+
+#if 0
+#define DebugPresent(x) ErrorF x
+#else
+#define DebugPresent(x)
+#endif
+
+struct ms_present_vblank_event {
+ uint64_t event_id;
+};
+
+static RRCrtcPtr
+ms_present_get_crtc(WindowPtr window)
+{
+ xf86CrtcPtr xf86_crtc = ms_dri2_crtc_covering_drawable(&window->drawable);
+ return xf86_crtc ? xf86_crtc->randr_crtc : NULL;
+}
+
+static int
+ms_present_get_ust_msc(RRCrtcPtr crtc, CARD64 *ust, CARD64 *msc)
+{
+ xf86CrtcPtr xf86_crtc = crtc->devPrivate;
+
+ return ms_get_crtc_ust_msc(xf86_crtc, ust, msc);
+}
+
+/*
+ * Flush the DRM event queue when full; makes space for new events.
+ */
+static Bool
+ms_flush_drm_events(ScreenPtr screen)
+{
+ ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+ modesettingPtr ms = modesettingPTR(scrn);
+
+ struct pollfd p = { .fd = ms->fd, .events = POLLIN };
+ int r;
+
+ do {
+ r = poll(&p, 1, 0);
+ } while (r == -1 && (errno == EINTR || errno == EAGAIN));
+
+ if (r <= 0)
+ return TRUE;
+
+ return drmHandleEvent(ms->fd, &ms->event_context) >= 0;
+}
+
+/*
+ * Called when the queued vblank event has occurred
+ */
+static void
+ms_present_vblank_handler(uint64_t msc, uint64_t usec, void *data)
+{
+ struct ms_present_vblank_event *event = data;
+
+ DebugPresent(("\t\tmh %lld msc %llu\n",
+ (long long) event->event_id, (long long) msc));
+
+ present_event_notify(event->event_id, usec, msc);
+ free(event);
+}
+
+/*
+ * Called when the queued vblank is aborted
+ */
+static void
+ms_present_vblank_abort(void *data)
+{
+ struct ms_present_vblank_event *event = data;
+
+ DebugPresent(("\t\tma %lld\n", (long long) event->event_id));
+
+ free(event);
+}
+
+/*
+ * Queue an event to report back to the Present extension when the specified
+ * MSC has past
+ */
+static int
+ms_present_queue_vblank(RRCrtcPtr crtc,
+ uint64_t event_id,
+ uint64_t msc)
+{
+ xf86CrtcPtr xf86_crtc = crtc->devPrivate;
+ ScreenPtr screen = crtc->pScreen;
+ ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+ modesettingPtr ms = modesettingPTR(scrn);
+ drmmode_crtc_private_ptr drmmode_crtc = xf86_crtc->driver_private;
+ struct ms_present_vblank_event *event;
+ drmVBlank vbl;
+ int ret;
+ uint32_t seq;
+
+ event = calloc(sizeof(struct ms_present_vblank_event), 1);
+ if (!event)
+ return BadAlloc;
+ event->event_id = event_id;
+ seq = ms_drm_queue_alloc(xf86_crtc, event,
+ ms_present_vblank_handler,
+ ms_present_vblank_abort);
+ if (!seq) {
+ free(event);
+ return BadAlloc;
+ }
+
+ vbl.request.type =
+ DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT | drmmode_crtc->vblank_pipe;
+ vbl.request.sequence = ms_crtc_msc_to_kernel_msc(xf86_crtc, msc);
+ vbl.request.signal = seq;
+ for (;;) {
+ ret = drmWaitVBlank(ms->fd, &vbl);
+ if (!ret)
+ break;
+ if (errno != EBUSY || !ms_flush_drm_events(screen))
+ return BadAlloc;
+ }
+ DebugPresent(("\t\tmq %lld seq %u msc %llu (hw msc %u)\n",
+ (long long) event_id, seq, (long long) msc,
+ vbl.request.sequence));
+ return Success;
+}
+
+static Bool
+ms_present_event_match(void *data, void *match_data)
+{
+ struct ms_present_vblank_event *event = data;
+ uint64_t *match = match_data;
+
+ return *match == event->event_id;
+}
+
+/*
+ * Remove a pending vblank event from the DRM queue so that it is not reported
+ * to the extension
+ */
+static void
+ms_present_abort_vblank(RRCrtcPtr crtc, uint64_t event_id, uint64_t msc)
+{
+ ScreenPtr screen = crtc->pScreen;
+ ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+
+ ms_drm_abort(scrn, ms_present_event_match, &event_id);
+}
+
+/*
+ * Flush our batch buffer when requested by the Present extension.
+ */
+static void
+ms_present_flush(WindowPtr window)
+{
+#ifdef GLAMOR
+ ScreenPtr screen = window->drawable.pScreen;
+ ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
+ modesettingPtr ms = modesettingPTR(scrn);
+
+ if (ms->drmmode.glamor)
+ glamor_block_handler(screen);
+#endif
+}
+
+static present_screen_info_rec ms_present_screen_info = {
+ .version = PRESENT_SCREEN_INFO_VERSION,
+
+ .get_crtc = ms_present_get_crtc,
+ .get_ust_msc = ms_present_get_ust_msc,
+ .queue_vblank = ms_present_queue_vblank,
+ .abort_vblank = ms_present_abort_vblank,
+ .flush = ms_present_flush,
+
+ .capabilities = PresentCapabilityNone,
+ .check_flip = 0,
+ .flip = 0,
+ .unflip = 0,
+};
+
+Bool
+ms_present_screen_init(ScreenPtr screen)
+{
+ return present_screen_init(screen, &ms_present_screen_info);
+}
diff --git a/xorg-server/hw/xfree86/drivers/modesetting/vblank.c b/xorg-server/hw/xfree86/drivers/modesetting/vblank.c
index 5031ef8ff..a342662a7 100644
--- a/xorg-server/hw/xfree86/drivers/modesetting/vblank.c
+++ b/xorg-server/hw/xfree86/drivers/modesetting/vblank.c
@@ -88,6 +88,14 @@ static int ms_box_area(BoxPtr box)
return (int)(box->x2 - box->x1) * (int)(box->y2 - box->y1);
}
+static Bool
+ms_crtc_on(xf86CrtcPtr crtc)
+{
+ drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+
+ return crtc->enabled && drmmode_crtc->dpms_mode == DPMSModeOn;
+}
+
/*
* Return the crtc covering 'box'. If two crtcs cover a portion of
* 'box', then prefer 'desired'. If 'desired' is NULL, then prefer the crtc
@@ -114,7 +122,7 @@ ms_covering_crtc(ScrnInfoPtr scrn,
crtc = xf86_config->crtc[c];
/* If the CRTC is off, treat it as not covering */
- if (!crtc->enabled)
+ if (!ms_crtc_on(crtc))
continue;
ms_crtc_box(crtc, &crtc_box);
@@ -139,20 +147,13 @@ ms_dri2_crtc_covering_drawable(DrawablePtr pDraw)
ScreenPtr pScreen = pDraw->pScreen;
ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
BoxRec box, crtcbox;
- xf86CrtcPtr crtc;
box.x1 = pDraw->x;
box.y1 = pDraw->y;
box.x2 = box.x1 + pDraw->width;
box.y2 = box.y1 + pDraw->height;
- crtc = ms_covering_crtc(pScrn, &box, NULL, &crtcbox);
-
- /* Make sure the CRTC is valid and this is the real front buffer */
- if (crtc != NULL && !crtc->rotatedData)
- return crtc;
-
- return NULL;
+ return ms_covering_crtc(pScrn, &box, NULL, &crtcbox);
}
static Bool
@@ -323,6 +324,24 @@ ms_drm_abort_scrn(ScrnInfoPtr scrn)
}
/*
+ * Externally usable abort function that uses a callback to match a single
+ * queued entry to abort
+ */
+void
+ms_drm_abort(ScrnInfoPtr scrn, Bool (*match)(void *data, void *match_data),
+ void *match_data)
+{
+ struct ms_drm_queue *q;
+
+ xorg_list_for_each_entry(q, &ms_drm_queue, list) {
+ if (match(q->data, match_data)) {
+ ms_drm_abort_one(q);
+ break;
+ }
+ }
+}
+
+/*
* General DRM kernel handler. Looks for the matching sequence number in the
* drm event queue and calls the handler for it.
*/
diff --git a/xorg-server/hw/xfree86/man/Xorg.wrap.man b/xorg-server/hw/xfree86/man/Xorg.wrap.man
index 58937c74b..11090f1f4 100644
--- a/xorg-server/hw/xfree86/man/Xorg.wrap.man
+++ b/xorg-server/hw/xfree86/man/Xorg.wrap.man
@@ -33,7 +33,7 @@ Xorg.wrap \- Xorg X server binary wrapper
The Xorg X server may need root rights to function properly. To start the
Xorg X server with these rights your system is using a suid root wrapper
installed as __suid_wrapper_dir__/Xorg.wrap which will execute the real
-X server which is installed as __suid_wrapper_dir__/Xorg.bin .
+X server which is installed as __suid_wrapper_dir__/Xorg.
.PP
By default Xorg.wrap will autodetect if root rights are necessary, and
if not it will drop its elevated rights before starting the real X server.
diff --git a/xorg-server/hw/xfree86/os-support/solaris/sun_init.c b/xorg-server/hw/xfree86/os-support/solaris/sun_init.c
index 16fc1b739..cc50f36c4 100644
--- a/xorg-server/hw/xfree86/os-support/solaris/sun_init.c
+++ b/xorg-server/hw/xfree86/os-support/solaris/sun_init.c
@@ -46,15 +46,12 @@
#define SOL_CONSOLE_DEV "/dev/console"
static Bool KeepTty = FALSE;
-static Bool Protect0 = FALSE;
static Bool UseConsole = FALSE;
#ifdef HAS_USL_VTS
static int VTnum = -1;
static int xf86StartVT = -1;
static int vtEnabled = 0;
-extern void xf86VTAcquire(int);
-extern void xf86VTRelease(int);
#endif
/* Device to open as xf86Info.consoleFd */
@@ -97,27 +94,6 @@ xf86OpenConsole(void)
if (geteuid() != 0)
FatalError("xf86OpenConsole: Server must be suid root\n");
- /* Protect page 0 to help find NULL dereferencing */
- /* mprotect() doesn't seem to work */
- if (Protect0) {
- int fd = -1;
-
- if ((fd = open("/dev/zero", O_RDONLY, 0)) < 0) {
- xf86Msg(X_WARNING,
- "xf86OpenConsole: cannot open /dev/zero (%s)\n",
- strerror(errno));
- }
- else {
- if (mmap(0, 0x1000, PROT_NONE,
- MAP_FIXED | MAP_SHARED, fd, 0) == MAP_FAILED)
- xf86Msg(X_WARNING,
- "xf86OpenConsole: failed to protect page 0 (%s)\n",
- strerror(errno));
-
- close(fd);
- }
- }
-
#ifdef HAS_USL_VTS
/*
@@ -371,15 +347,6 @@ xf86ProcessArgument(int argc, char **argv, int i)
}
/*
- * Undocumented flag to protect page 0 from read/write to help catch NULL
- * pointer dereferences. This is purely a debugging flag.
- */
- if (!strcmp(argv[i], "-protect0")) {
- Protect0 = TRUE;
- return 1;
- }
-
- /*
* Use /dev/console as the console device.
*/
if (!strcmp(argv[i], "-C")) {
diff --git a/xorg-server/hw/xfree86/os-support/xf86_OSlib.h b/xorg-server/hw/xfree86/os-support/xf86_OSlib.h
index 3a83f348f..6190fe6a0 100644
--- a/xorg-server/hw/xfree86/os-support/xf86_OSlib.h
+++ b/xorg-server/hw/xfree86/os-support/xf86_OSlib.h
@@ -134,10 +134,15 @@
#endif
#include <sys/kd.h>
#include <sys/vt.h>
+
+extern _X_HIDDEN void xf86VTAcquire(int);
+extern _X_HIDDEN void xf86VTRelease(int);
#endif
#if defined(sun)
#include <sys/fbio.h>
+extern _X_HIDDEN char xf86SolarisFbDev[PATH_MAX];
+
#include <sys/kbd.h>
#include <sys/kbio.h>
diff --git a/xorg-server/hw/xfree86/xorg-wrapper.c b/xorg-server/hw/xfree86/xorg-wrapper.c
index 4ea47331b..22e97ad5d 100644
--- a/xorg-server/hw/xfree86/xorg-wrapper.c
+++ b/xorg-server/hw/xfree86/xorg-wrapper.c
@@ -255,18 +255,18 @@ int main(int argc, char *argv[])
}
}
- snprintf(buf, sizeof(buf), "%s/Xorg.bin", SUID_WRAPPER_DIR);
+ snprintf(buf, sizeof(buf), "%s/Xorg", SUID_WRAPPER_DIR);
/* Check if the server is executable by our real uid */
if (access(buf, X_OK) != 0) {
- fprintf(stderr, "%s: Missing execute permissions for %s/Xorg.bin: %s\n",
- progname, SUID_WRAPPER_DIR, strerror(errno));
+ fprintf(stderr, "%s: Missing execute permissions for %s: %s\n",
+ progname, buf, strerror(errno));
exit(1);
}
argv[0] = buf;
(void) execv(argv[0], argv);
- fprintf(stderr, "%s: Failed to execute %s/Xorg.bin: %s\n",
- progname, SUID_WRAPPER_DIR, strerror(errno));
+ fprintf(stderr, "%s: Failed to execute %s: %s\n",
+ progname, buf, strerror(errno));
exit(1);
}
diff --git a/xorg-server/hw/xnest/Keyboard.c b/xorg-server/hw/xnest/Keyboard.c
index 2cf16246b..ee3f68e3f 100644
--- a/xorg-server/hw/xnest/Keyboard.c
+++ b/xorg-server/hw/xnest/Keyboard.c
@@ -18,6 +18,7 @@ is" without express or implied warranty.
#include <X11/X.h>
#include <X11/Xproto.h>
+#include <xcb/xcb_keysyms.h>
#include <X11/keysym.h>
#include "screenint.h"
#include "inputstr.h"
@@ -247,7 +248,11 @@ xnestUpdateModifierState(unsigned int state)
for (key = 0; key < MAP_LENGTH; key++)
if (keyc->xkbInfo->desc->map->modmap[key] & mask) {
- if (key_is_down(pDev, key, KEY_PROCESSED))
+ if (mask == XCB_MOD_MASK_LOCK) {
+ xnestQueueKeyEvent(KeyPress, key);
+ xnestQueueKeyEvent(KeyRelease, key);
+ }
+ else if (key_is_down(pDev, key, KEY_PROCESSED))
xnestQueueKeyEvent(KeyRelease, key);
if (--count == 0)
@@ -261,6 +266,8 @@ xnestUpdateModifierState(unsigned int state)
for (key = 0; key < MAP_LENGTH; key++)
if (keyc->xkbInfo->desc->map->modmap[key] & mask) {
xnestQueueKeyEvent(KeyPress, key);
+ if (mask == XCB_MOD_MASK_LOCK)
+ xnestQueueKeyEvent(KeyRelease, key);
break;
}
}
diff --git a/xorg-server/hw/xwayland/Makefile.am b/xorg-server/hw/xwayland/Makefile.am
index 4e0e1bb00..994554088 100644
--- a/xorg-server/hw/xwayland/Makefile.am
+++ b/xorg-server/hw/xwayland/Makefile.am
@@ -26,7 +26,6 @@ Xwayland_LDADD = \
$(XWAYLAND_LIBS) \
$(XWAYLAND_SYS_LIBS) \
$(XSERVER_SYS_LIBS)
-Xwayland_DEPENDENCIES = $(XWAYLAND_LIBS)
Xwayland_LDFLAGS = $(LD_EXPORT_SYMBOLS_FLAG)
diff --git a/xorg-server/hw/xwayland/xwayland-glamor.c b/xorg-server/hw/xwayland/xwayland-glamor.c
index 4be883fa3..dd8551840 100644
--- a/xorg-server/hw/xwayland/xwayland-glamor.c
+++ b/xorg-server/hw/xwayland/xwayland-glamor.c
@@ -137,6 +137,9 @@ xwl_glamor_create_pixmap_for_bo(ScreenPtr screen, struct gbm_bo *bo, int depth)
glGenTextures(1, &xwl_pixmap->texture);
glBindTexture(GL_TEXTURE_2D, xwl_pixmap->texture);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, xwl_pixmap->image);
glBindTexture(GL_TEXTURE_2D, 0);
@@ -398,9 +401,8 @@ xwl_screen_init_glamor(struct xwl_screen *xwl_screen,
}
void
-glamor_egl_destroy_textured_pixmap(PixmapPtr pixmap)
+glamor_egl_destroy_pixmap_image(PixmapPtr pixmap)
{
- glamor_destroy_textured_pixmap(pixmap);
}
int
diff --git a/xorg-server/hw/xwayland/xwayland-input.c b/xorg-server/hw/xwayland/xwayland-input.c
index b8c543ce4..5e204189f 100644
--- a/xorg-server/hw/xwayland/xwayland-input.c
+++ b/xorg-server/hw/xwayland/xwayland-input.c
@@ -233,6 +233,9 @@ pointer_handle_button(void *data, struct wl_pointer *pointer, uint32_t serial,
xwl_seat->xwl_screen->serial = serial;
switch (button) {
+ case BTN_LEFT:
+ index = 1;
+ break;
case BTN_MIDDLE:
index = 2;
break;
@@ -240,7 +243,9 @@ pointer_handle_button(void *data, struct wl_pointer *pointer, uint32_t serial,
index = 3;
break;
default:
- index = button - BTN_LEFT + 1;
+ /* Skip indexes 4-7: they are used for vertical and horizontal scroll.
+ The rest of the buttons go in order: BTN_SIDE becomes 8, etc. */
+ index = 8 + button - BTN_SIDE;
break;
}
diff --git a/xorg-server/hw/xwayland/xwayland.c b/xorg-server/hw/xwayland/xwayland.c
index 37d6d8270..7e8d667d6 100644
--- a/xorg-server/hw/xwayland/xwayland.c
+++ b/xorg-server/hw/xwayland/xwayland.c
@@ -513,9 +513,9 @@ xwl_screen_init(ScreenPtr pScreen, int argc, char **argv)
int ret, bpc, green_bpc, i;
xwl_screen = calloc(sizeof *xwl_screen, 1);
- xwl_screen->wm_fd = -1;
if (xwl_screen == NULL)
return FALSE;
+ xwl_screen->wm_fd = -1;
if (!dixRegisterPrivateKey(&xwl_screen_private_key, PRIVATE_SCREEN, 0))
return FALSE;
diff --git a/xorg-server/hw/xwin/InitOutput.c b/xorg-server/hw/xwin/InitOutput.c
index 4e099d294..fe4755c03 100755
--- a/xorg-server/hw/xwin/InitOutput.c
+++ b/xorg-server/hw/xwin/InitOutput.c
@@ -814,6 +814,10 @@ winUseMsg(void)
#ifdef XWIN_CLIPBOARD
ErrorF("-nounicodeclipboard\n"
"\tDo not use Unicode clipboard even if on a NT-based platform.\n");
+
+ ErrorF("-[no]primary\n"
+ "\tWhen clipboard integration is enabled, map the X11 PRIMARY selection\n"
+ "\tto the Windows clipboard. Default is enabled.\n");
#endif
ErrorF("-refresh rate_in_Hz\n"
diff --git a/xorg-server/hw/xwin/XWin.rc b/xorg-server/hw/xwin/XWin.rc
index f94f5f995..4ff795027 100644
--- a/xorg-server/hw/xwin/XWin.rc
+++ b/xorg-server/hw/xwin/XWin.rc
@@ -138,6 +138,7 @@ BEGIN
POPUP "TRAYICON_MENU"
BEGIN
MENUITEM "&Hide Root Window", ID_APP_HIDE_ROOT
+ MENUITEM "Clipboard may use &PRIMARY selection", ID_APP_MONITOR_PRIMARY
MENUITEM "&About...", ID_APP_ABOUT
MENUITEM SEPARATOR
MENUITEM "E&xit...", ID_APP_EXIT
diff --git a/xorg-server/hw/xwin/man/XWin.man b/xorg-server/hw/xwin/man/XWin.man
index a043ac281..15a57db02 100644
--- a/xorg-server/hw/xwin/man/XWin.man
+++ b/xorg-server/hw/xwin/man/XWin.man
@@ -174,7 +174,7 @@ on remote hosts, when that information is available and it's useful to do so.
.SH OPTIONS CONTROLLING WINDOWS INTEGRATION
.TP 8
.B \-[no]clipboard
-Enables [disables] the integration between the Cygwin/X clipboard and
+Enables [disables] the integration between the X11 clipboard and
\fIWindows\fP clipboard. The default is enabled.
.TP 8
.B "\-emulate3buttons [\fItimeout\fP]"
@@ -200,6 +200,10 @@ prevents the \fIWindows\fP mouse cursor from being drawn on top of the X
cursor.
This parameter has no effect unless \fB-swcursor\fP is also specified.
.TP 8
+.B \-[no]primary
+Clipboard integration may [will not] use the PRIMARY selection.
+The default is enabled.
+.TP 8
.B \-swcursor
Disable the usage of the \fIWindows\fP cursor and use the X11 software cursor instead.
.TP 8
diff --git a/xorg-server/hw/xwin/winclipboard/internal.h b/xorg-server/hw/xwin/winclipboard/internal.h
index 55c7771af..73a330fc6 100755
--- a/xorg-server/hw/xwin/winclipboard/internal.h
+++ b/xorg-server/hw/xwin/winclipboard/internal.h
@@ -62,11 +62,13 @@ typedef int pid_t;
#include "winmsg.h"
#define WIN_XEVENTS_SUCCESS 0
-#define WIN_XEVENTS_CONVERT 2
-#define WIN_XEVENTS_NOTIFY 3
+#define WIN_XEVENTS_FAILED 1
+#define WIN_XEVENTS_NOTIFY_DATA 3
+#define WIN_XEVENTS_NOTIFY_TARGETS 4
#define WIN_LOCAL_PROPERTY "CYGX_CUT_BUFFER"
#define WM_WM_REINIT (WM_USER + 200)
+#define WM_WM_QUIT (WM_USER + 201)
/*
* References to external symbols
@@ -95,6 +97,15 @@ void
*/
+typedef struct
+{
+ Atom atomClipboard;
+ Atom atomLocalProperty;
+ Atom atomUTF8String;
+ Atom atomCompoundText;
+ Atom atomTargets;
+} ClipboardAtoms;
+
/*
* winclipboardwndproc.c
*/
@@ -104,12 +115,33 @@ Bool winClipboardFlushWindowsMessageQueue(HWND hwnd);
LRESULT CALLBACK
winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
+typedef struct
+{
+ Display *pClipboardDisplay;
+ Window iClipboardWindow;
+ ClipboardAtoms *atoms;
+} ClipboardWindowCreationParams;
+
/*
* winclipboardxevents.c
*/
+typedef struct
+{
+ Bool fUseUnicode;
+ Atom *targetList;
+} ClipboardConversionData;
+
int
winClipboardFlushXEvents(HWND hwnd,
- int iWindow, Display * pDisplay, Bool fUnicodeSupport, Bool ClipboardOpened);
+ Window iWindow, Display * pDisplay, ClipboardConversionData *data, ClipboardAtoms *atom);
+
+
+Atom
+winClipboardGetLastOwnedSelectionAtom(ClipboardAtoms *atoms);
+
+void
+winClipboardInitMonitoredSelections(void);
+
#endif
diff --git a/xorg-server/hw/xwin/winclipboard/thread.c b/xorg-server/hw/xwin/winclipboard/thread.c
index 5dee3040e..42edad89c 100755
--- a/xorg-server/hw/xwin/winclipboard/thread.c
+++ b/xorg-server/hw/xwin/winclipboard/thread.c
@@ -35,16 +35,26 @@
#else
#define HAS_WINSOCK 1
#endif
+
+/*
+ * Including any server header might define the macro _XSERVER64 on 64 bit machines.
+ * That macro must _NOT_ be defined for Xlib client code, otherwise bad things happen.
+ * So let's undef that macro if necessary.
+ */
+#ifdef _XSERVER64
+#undef _XSERVER64
+#endif
+
#include <sys/types.h>
#include <signal.h>
#include <pthread.h>
-#include "winclipboard.h"
#include "windisplay.h"
#ifdef __CYGWIN__
#include <errno.h>
#endif
#include "misc.h"
#include "winmsg.h"
+#include "winclipboard.h"
#include "internal.h"
/* Clipboard module constants */
@@ -90,7 +100,7 @@ Bool g_fUseUnicode = FALSE;
*/
static HWND
-winClipboardCreateMessagingWindow(void);
+winClipboardCreateMessagingWindow(Display *pDisplay, Window iWindow, ClipboardAtoms *atoms);
static int
winClipboardErrorHandler(Display * pDisplay, XErrorEvent * pErr);
@@ -107,7 +117,7 @@ winClipboardThreadExit(void *arg);
Bool
winClipboardProc(Bool fUseUnicode, char *szDisplay)
{
- Atom atomClipboard;
+ ClipboardAtoms atoms;
int iReturn;
HWND hwnd = NULL;
int iConnectionNumber = 0;
@@ -125,6 +135,7 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay)
int iSelectError;
pthread_cleanup_push(&winClipboardThreadExit, NULL);
+ ClipboardConversionData data;
winDebug ("winClipboardProc - Hello\n");
@@ -191,12 +202,15 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay)
iMaxDescriptor = iConnectionNumber + 1;
#endif
- /* Create atom */
- atomClipboard = XInternAtom(pDisplay, "CLIPBOARD", False);
- XInternAtom (pDisplay, WIN_LOCAL_PROPERTY, False);
- XInternAtom (pDisplay, "UTF8_STRING", False);
- XInternAtom (pDisplay, "COMPOUND_TEXT", False);
- XInternAtom (pDisplay, "TARGETS", False);
+ if (!XFixesQueryExtension(pDisplay, &xfixes_event_base, &xfixes_error_base))
+ ErrorF ("winClipboardProc - XFixes extension not present\n");
+
+ /* Create atoms */
+ atoms.atomClipboard = XInternAtom(pDisplay, "CLIPBOARD", False);
+ atoms.atomLocalProperty = XInternAtom (pDisplay, "CYGX_CUT_BUFFER", False);
+ atoms.atomUTF8String = XInternAtom (pDisplay, "UTF8_STRING", False);
+ atoms.atomCompoundText = XInternAtom (pDisplay, "COMPOUND_TEXT", False);
+ atoms.atomTargets = XInternAtom (pDisplay, "TARGETS", False);
/* Create a messaging window */
iWindow = XCreateSimpleWindow(pDisplay,
@@ -218,6 +232,20 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay)
ErrorF("winClipboardProc - XSelectInput generated BadWindow "
"on messaging window\n");
+ XFixesSelectSelectionInput (pDisplay,
+ iWindow,
+ XA_PRIMARY,
+ XFixesSetSelectionOwnerNotifyMask |
+ XFixesSelectionWindowDestroyNotifyMask |
+ XFixesSelectionClientCloseNotifyMask);
+
+ XFixesSelectSelectionInput (pDisplay,
+ iWindow,
+ atoms.atomClipboard,
+ XFixesSetSelectionOwnerNotifyMask |
+ XFixesSelectionWindowDestroyNotifyMask |
+ XFixesSelectionClientCloseNotifyMask);
+
/* Save the window in the screen privates */
g_iClipboardWindow = iWindow;
@@ -248,28 +276,28 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay)
}
}
- /* Pre-flush X events */
- /*
- * NOTE: Apparently you'll freeze if you don't do this,
- * because there may be events in local data structures
- * already.
- */
- //winClipboardFlushXEvents(hwnd, iWindow, pDisplay, fUseUnicode);
-
- /* Pre-flush Windows messages */
- winDebug ("Start flushing \n");
- if (!winClipboardFlushWindowsMessageQueue(hwnd))
- {
- ErrorF ("winClipboardFlushWindowsMessageQueue - returned 0\n");
- goto thread_errorexit;
- }
-
+ data.fUseUnicode = fUseUnicode;
winDebug ("winClipboardProc - Started\n");
/* Signal that the clipboard client has started */
g_fClipboardStarted = TRUE;
- /* Loop for X events */
+ /* Loop for events */
while (1) {
+
+ /* Process X events */
+ winClipboardFlushXEvents(hwnd,
+ iWindow, pDisplay, &data, &atoms);
+
+ /* Process Windows messages */
+ if (!winClipboardFlushWindowsMessageQueue(hwnd)) {
+ ErrorF("winClipboardProc - winClipboardFlushWindowsMessageQueue trapped "
+ "WM_QUIT message, exiting main loop.\n");
+ break;
+ }
+
+ /* We need to ensure that all pending requests are sent */
+ XFlush(pDisplay);
+
/* Setup the file descriptor set */
/*
* NOTE: You have to do this before every call to select
@@ -316,13 +344,10 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay)
break;
}
- /* Branch on which descriptor became active */
-// if (FD_ISSET (iConnectionNumber, &fdsRead)) {
-// Also do it when no read since winClipboardFlushXEvents
-// is sending the output.
- /* Process X events */
- winClipboardFlushXEvents(hwnd, iWindow, pDisplay, fUseUnicode, FALSE);
-// }
+ if (FD_ISSET(iConnectionNumber, &fdsRead)) {
+ winDebug
+ ("winClipboardProc - X connection ready, pumping X event queue\n");
+ }
#ifdef HAS_DEVWINDOWS
/* Check for Windows event ready */
@@ -331,14 +356,16 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay)
if (1)
#endif
{
- /* Process Windows messages */
- if (!winClipboardFlushWindowsMessageQueue(hwnd)) {
- ErrorF("winClipboardProc - "
- "winClipboardFlushWindowsMessageQueue trapped "
- "WM_QUIT message, exiting main loop.\n");
- break;
- }
+ winDebug
+ ("winClipboardProc - /dev/windows ready, pumping Windows message queue\n");
}
+
+#ifdef HAS_DEVWINDOWS
+ if (!(FD_ISSET(iConnectionNumber, &fdsRead)) &&
+ !(FD_ISSET(fdMessageQueue, &fdsRead))) {
+ winDebug("winClipboardProc - Spurious wake, select() returned %d\n", iReturn);
+ }
+#endif
}
/* Close our X window */
@@ -360,8 +387,11 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay)
#if 0
/*
- * FIXME: XCloseDisplay hangs if we call it, as of 2004/03/26. The
- * XSync and XSelectInput calls did not help.
+ * FIXME: XCloseDisplay hangs if we call it
+ *
+ * XCloseDisplay() calls XSync(), so any outstanding errors are reported.
+ * If we are built into the server, this can deadlock if the server is
+ * in the process of exiting and waiting for this thread to exit.
*/
/* Discard any remaining events */
@@ -407,9 +437,10 @@ commonexit:
*/
HWND
-winClipboardCreateMessagingWindow(void)
+winClipboardCreateMessagingWindow(Display *pDisplay, Window iWindow, ClipboardAtoms *atoms)
{
WNDCLASSEX wc;
+ ClipboardWindowCreationParams cwcp;
HWND hwnd;
/* Setup our window class */
@@ -427,6 +458,11 @@ winClipboardCreateMessagingWindow(void)
wc.hIconSm = 0;
RegisterClassEx(&wc);
+ /* Information to be passed to WM_CREATE */
+ cwcp.pClipboardDisplay = pDisplay;
+ cwcp.iClipboardWindow = iWindow;
+ cwcp.atoms = atoms;
+
/* Create the window */
hwnd = CreateWindowExA(0, /* Extended styles */
WIN_CLIPBOARD_WINDOW_CLASS, /* Class name */
@@ -439,7 +475,7 @@ winClipboardCreateMessagingWindow(void)
(HWND) NULL, /* No parent or owner window */
(HMENU) NULL, /* No menu */
GetModuleHandle(NULL), /* Instance handle */
- NULL); /* Creation data */
+ &cwcp); /* Creation data */
assert(hwnd != NULL);
/* I'm not sure, but we may need to call this to start message processing */
diff --git a/xorg-server/hw/xwin/winclipboard/winclipboard.h b/xorg-server/hw/xwin/winclipboard/winclipboard.h
index 7b172739a..d7d8efa15 100644
--- a/xorg-server/hw/xwin/winclipboard/winclipboard.h
+++ b/xorg-server/hw/xwin/winclipboard/winclipboard.h
@@ -27,6 +27,10 @@
#ifndef WINCLIPBOARD_H
#define WINCLIPBOARD_H
+#include <x11/Xdefs.h>
+
void winFixClipboardChain (int Removed);
+extern Bool fPrimarySelection;
+
#endif
diff --git a/xorg-server/hw/xwin/winclipboard/wndproc.c b/xorg-server/hw/xwin/winclipboard/wndproc.c
index f5f931f74..d522e1f30 100755
--- a/xorg-server/hw/xwin/winclipboard/wndproc.c
+++ b/xorg-server/hw/xwin/winclipboard/wndproc.c
@@ -45,6 +45,7 @@
#include <sys/types.h>
#include <sys/time.h>
+#include <limits.h>
#include "winclipboard.h"
#include "misc.h"
#include "winmsg.h"
@@ -76,24 +77,15 @@ extern Bool g_fClipboardPrimary;
static int
winProcessXEventsTimeout(HWND hwnd, int iWindow, Display * pDisplay,
- Bool fUseUnicode, int iTimeoutSec)
+ ClipboardConversionData *data, ClipboardAtoms *atoms, int iTimeoutSec)
{
int iConnNumber;
struct timeval tv;
int iReturn;
DWORD dwStopTime = GetTickCount() + iTimeoutSec * 1000;
- /* Make sure the output messages are sent before waiting on a response. */
- iReturn = winClipboardFlushXEvents (hwnd,
- iWindow,
- pDisplay,
- fUseUnicode,
- TRUE);
- if (WIN_XEVENTS_NOTIFY == iReturn)
- {
- /* Bail out if notify processed */
- return iReturn;
- }
+ winDebug("winProcessXEventsTimeout () - pumping X events for %d seconds\n",
+ iTimeoutSec);
/* Get our connection number */
iConnNumber = ConnectionNumber(pDisplay);
@@ -103,6 +95,19 @@ winProcessXEventsTimeout(HWND hwnd, int iWindow, Display * pDisplay,
fd_set fdsRead;
long remainingTime;
+ /* Process X events */
+ iReturn = winClipboardFlushXEvents(hwnd, iWindow, pDisplay, data, atoms);
+
+ winDebug("winProcessXEventsTimeout () - winClipboardFlushXEvents returned %d\n", iReturn);
+
+ if ((WIN_XEVENTS_NOTIFY_DATA == iReturn) || (WIN_XEVENTS_NOTIFY_TARGETS == iReturn) || (WIN_XEVENTS_FAILED == iReturn)) {
+ /* Bail out */
+ return iReturn;
+ }
+
+ /* We need to ensure that all pending requests are sent */
+ XFlush(pDisplay);
+
/* Setup the file descriptor set */
FD_ZERO(&fdsRead);
FD_SET(iConnNumber, &fdsRead);
@@ -130,24 +135,8 @@ winProcessXEventsTimeout(HWND hwnd, int iWindow, Display * pDisplay,
break;
}
- /* Branch on which descriptor became active */
- if (FD_ISSET(iConnNumber, &fdsRead)) {
- /* Process X events */
- /* Exit when we see that server is shutting down */
- iReturn = winClipboardFlushXEvents(hwnd,
- iWindow, pDisplay, fUseUnicode, TRUE);
-
- winDebug
- ("winProcessXEventsTimeout () - winClipboardFlushXEvents returned %d\n",
- iReturn);
-
- if (WIN_XEVENTS_NOTIFY == iReturn) {
- /* Bail out if notify processed */
- return iReturn;
- }
- }
- else {
- winDebug("winProcessXEventsTimeout - Spurious wake\n");
+ if (!FD_ISSET(iConnNumber, &fdsRead)) {
+ winDebug("winProcessXEventsTimeout - Spurious wake, select() returned %d\n", iReturn);
}
}
@@ -162,6 +151,7 @@ LRESULT CALLBACK
winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static HWND s_hwndNextViewer;
+ static Bool fRunning;
/* Branch on message type */
switch (message) {
@@ -174,6 +164,13 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
s_hwndNextViewer = NULL;
g_hwndClipboard = NULL;
+ }
+ return 0;
+
+ case WM_WM_QUIT:
+ {
+ winDebug("winClipboardWindowProc - WM_WM_QUIT\n");
+ fRunning = FALSE;
PostQuitMessage(0);
}
return 0;
@@ -185,6 +182,7 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
winDebug("winClipboardWindowProc - WM_CREATE\n");
+ fRunning = TRUE;
/* Add ourselves to the clipboard viewer chain */
s_hwndNextViewer = SetClipboardViewer (hwnd);
#ifdef _DEBUG
@@ -300,6 +298,10 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
return 0;
}
+ /* Bail when shutting down */
+ if (!fRunning)
+ return 0;
+
/*
* Do not take ownership of the X11 selections when something
* other than CF_TEXT or CF_UNICODETEXT has been copied
@@ -406,92 +408,153 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
winDebug("winClipboardWindowProc - WM_DESTROYCLIPBOARD - Ignored.\n");
return 0;
- case WM_RENDERFORMAT:
case WM_RENDERALLFORMATS:
+ winDebug("winClipboardWindowProc - WM_RENDERALLFORMATS - Hello.\n");
+
+ /*
+ WM_RENDERALLFORMATS is sent as we are shutting down, to render the
+ clipboard so it's contents remains available to other applications.
+
+ Unfortunately, this can't work without major changes. The server is
+ already waiting for us to stop, so we can't ask for the rendering of
+ clipboard text now.
+ */
+
+ return 0;
+
+ case WM_RENDERFORMAT:
{
int iReturn;
Display *pDisplay = g_pClipboardDisplay;
Window iWindow = g_iClipboardWindow;
Bool fConvertToUnicode;
+ Bool pasted = FALSE;
+ Atom selection;
+ ClipboardConversionData data;
+ int best_target = 0;
- winDebug("winClipboardWindowProc - WM_RENDER*FORMAT - Hello.\n");
+ winDebug("winClipboardWindowProc - WM_RENDERFORMAT %d - Hello.\n",
+ wParam);
/* Flag whether to convert to Unicode or not */
- if (message == WM_RENDERALLFORMATS)
- fConvertToUnicode = FALSE;
- else
- fConvertToUnicode = (CF_UNICODETEXT == wParam);
+ fConvertToUnicode = (CF_UNICODETEXT == wParam);
- /* Request the selection contents */
- iReturn = XConvertSelection(pDisplay,
- g_atomLastOwnedSelection,
- XInternAtom(pDisplay,
- "COMPOUND_TEXT", False),
- XInternAtom(pDisplay,
- WIN_LOCAL_PROPERTY, False),
- iWindow, CurrentTime);
- if (iReturn == BadAtom || iReturn == BadWindow) {
- ErrorF ("winClipboardWindowProc - WM_RENDER*FORMAT - "
- "XConvertSelection () failed\n");
- break;
+ selection = winClipboardGetLastOwnedSelectionAtom(atoms);
+ if (selection == None) {
+ ErrorF("winClipboardWindowProc - no monitored selection is owned\n");
+ goto fake_paste;
}
- /* Special handling for WM_RENDERALLFORMATS */
- if (message == WM_RENDERALLFORMATS) {
- /* We must open and empty the clipboard */
- if (!OpenClipboard(hwnd)) {
- ErrorF ("winClipboardWindowProc - WM_RENDER*FORMATS - "
- "OpenClipboard () failed: %08x\n",
- GetLastError());
- break;
- }
+ winDebug("winClipboardWindowProc - requesting targets for selection from owner\n");
- if (!EmptyClipboard()) {
- ErrorF ("winClipboardWindowProc - WM_RENDER*FORMATS - "
- "EmptyClipboard () failed: %08x\n",
- GetLastError());
- CloseClipboard ();
- break;
- }
+ /* Request the selection's supported conversion targets */
+ XConvertSelection(pDisplay,
+ selection,
+ atoms->atomTargets,
+ atoms->atomLocalProperty,
+ iWindow, CurrentTime);
+
+ /* Process X events */
+ data.fUseUnicode = fConvertToUnicode;
+ iReturn = winProcessXEventsTimeout(hwnd,
+ iWindow,
+ pDisplay,
+ &data,
+ atoms,
+ WIN_POLL_TIMEOUT);
+
+ if (WIN_XEVENTS_NOTIFY_TARGETS != iReturn) {
+ ErrorF
+ ("winClipboardWindowProc - timed out waiting for WIN_XEVENTS_NOTIFY_TARGETS\n");
+ goto fake_paste;
+ }
+
+ /* Choose the most preferred target */
+ {
+ struct target_priority
+ {
+ Atom target;
+ unsigned int priority;
+ };
+
+ struct target_priority target_priority_table[] =
+ {
+ { atoms->atomCompoundText, 0 },
+#ifdef X_HAVE_UTF8_STRING
+ { atoms->atomUTF8String, 1 },
+#endif
+ { XA_STRING, 2 },
+ };
+
+ int best_priority = INT_MAX;
+
+ int i,j;
+ for (i = 0 ; data.targetList[i] != 0; i++)
+ {
+ for (j = 0; j < sizeof(target_priority_table)/sizeof(struct target_priority); j ++)
+ {
+ if ((data.targetList[i] == target_priority_table[j].target) &&
+ (target_priority_table[j].priority < best_priority))
+ {
+ best_target = target_priority_table[j].target;
+ best_priority = target_priority_table[j].priority;
+ }
+ }
+ }
}
- /* Process the SelectionNotify event */
+ free(data.targetList);
+ data.targetList = 0;
+
+ winDebug("winClipboardWindowProc - best target is %d\n", best_target);
+
+ /* No useful targets found */
+ if (best_target == 0)
+ goto fake_paste;
+
+ winDebug("winClipboardWindowProc - requesting selection from owner\n");
+
+ /* Request the selection contents */
+ XConvertSelection(pDisplay,
+ selection,
+ best_target,
+ atoms->atomLocalProperty,
+ iWindow, CurrentTime);
+
+ /* Process X events */
iReturn = winProcessXEventsTimeout(hwnd,
iWindow,
pDisplay,
- fConvertToUnicode, WIN_POLL_TIMEOUT);
+ &data,
+ atoms,
+ WIN_POLL_TIMEOUT);
/*
- * The last call to winProcessXEventsTimeout
- * from above had better have seen a notify event, or else we
- * are dealing with a buggy or old X11 app. In these cases we
- * have to paste some fake data to the Win32 clipboard to
- * satisfy the requirement that we write something to it.
+ * winProcessXEventsTimeout had better have seen a notify event,
+ * or else we are dealing with a buggy or old X11 app.
*/
- if (WIN_XEVENTS_NOTIFY != iReturn) {
- ErrorF("winClipboardWindowProc - winProcessXEventsTimeout should have returned WIN_XEVENTS_NOTIFY was %d\n",iReturn);
- /* Paste no data, to satisfy required call to SetClipboardData */
- SetClipboardData(CF_UNICODETEXT, NULL);
- SetClipboardData(CF_TEXT, NULL);
-
+ if (WIN_XEVENTS_NOTIFY_DATA != iReturn) {
ErrorF
- ("winClipboardWindowProc - timed out waiting for WIN_XEVENTS_NOTIFY\n");
+ ("winClipboardWindowProc - timed out waiting for WIN_XEVENTS_NOTIFY_DATA\n");
}
-
- /* Special handling for WM_RENDERALLFORMATS */
- if (message == WM_RENDERALLFORMATS) {
- /* We must close the clipboard */
-
- if (!CloseClipboard()) {
- ErrorF (
- "winClipboardWindowProc - WM_RENDERALLFORMATS - "
- "CloseClipboard () failed: %08x\n",
- GetLastError());
- break;
- }
+ else {
+ pasted = TRUE;
}
- winDebug("winClipboardWindowProc - WM_RENDER*FORMAT - Returning.\n");
+ /*
+ * If we couldn't get the data from the X clipboard, we
+ * have to paste some fake data to the Win32 clipboard to
+ * satisfy the requirement that we write something to it.
+ */
+ fake_paste:
+ if (!pasted)
+ {
+ /* Paste no data, to satisfy required call to SetClipboardData */
+ SetClipboardData(CF_UNICODETEXT, NULL);
+ SetClipboardData(CF_TEXT, NULL);
+ }
+
+ winDebug("winClipboardWindowProc - WM_RENDERFORMAT - Returning.\n");
return 0;
}
}
diff --git a/xorg-server/hw/xwin/winclipboard/xevents.c b/xorg-server/hw/xwin/winclipboard/xevents.c
index cfbf0121e..640efeb4e 100755
--- a/xorg-server/hw/xwin/winclipboard/xevents.c
+++ b/xorg-server/hw/xwin/winclipboard/xevents.c
@@ -36,10 +36,158 @@
#include "winclipboard.h"
#include "misc.h"
#include "winmsg.h"
-#include "internal.h"
+/*
+ * Including any server header might define the macro _XSERVER64 on 64 bit machines.
+ * That macro must _NOT_ be defined for Xlib client code, otherwise bad things happen.
+ * So let's undef that macro if necessary.
+ */
+#ifdef _XSERVER64
+#undef _XSERVER64
+#endif
+
+#include <limits.h>
#include <unistd.h>
+#include <wchar.h>
+#include <X11/Xutil.h>
+#include <X11/Xatom.h>
+//#include <X11/extensions/Xfixes.h>
+
+#include "winclipboard.h"
+#include "internal.h"
+
+/*
+ * Constants
+ */
+
+#define CLIP_NUM_SELECTIONS 2
+#define CLIP_OWN_NONE -1
+#define CLIP_OWN_PRIMARY 0
+#define CLIP_OWN_CLIPBOARD 1
+
+/*
+ * Global variables
+ */
+
+extern int xfixes_event_base;
+Bool fPrimarySelection = TRUE;
+
+extern Bool g_fClipboardPrimary;
+
+/*
+ * Local variables
+ */
+
+static Window s_iOwners[CLIP_NUM_SELECTIONS] = { None, None };
+static const char *szSelectionNames[CLIP_NUM_SELECTIONS] =
+ { "PRIMARY", "CLIPBOARD" };
+
+static unsigned int lastOwnedSelectionIndex = CLIP_OWN_NONE;
+
+static void
+MonitorSelection(XFixesSelectionNotifyEvent * e, unsigned int i)
+{
+ /* Look for owned -> not owned transition */
+ if (None == e->owner && None != s_iOwners[i]) {
+ unsigned int other_index;
+
+ winDebug("MonitorSelection - %s - Going from owned to not owned.\n",
+ szSelectionNames[i]);
+
+ /* If this selection is not owned, the other monitored selection must be the most
+ recently owned, if it is owned at all */
+ if (i == CLIP_OWN_PRIMARY)
+ other_index = CLIP_OWN_CLIPBOARD;
+ if (i == CLIP_OWN_CLIPBOARD)
+ other_index = CLIP_OWN_PRIMARY;
+ if (None != s_iOwners[other_index])
+ lastOwnedSelectionIndex = other_index;
+ else
+ lastOwnedSelectionIndex = CLIP_OWN_NONE;
+ }
+
+ /* Save last owned selection */
+ if (None != e->owner) {
+ lastOwnedSelectionIndex = i;
+ }
-extern Bool g_fClipboardPrimary;
+ /* Save new selection owner or None */
+ s_iOwners[i] = e->owner;
+ winDebug("MonitorSelection - %s - Now owned by XID %x\n",
+ szSelectionNames[i], e->owner);
+}
+
+Atom
+winClipboardGetLastOwnedSelectionAtom(ClipboardAtoms *atoms)
+{
+ if (lastOwnedSelectionIndex == CLIP_OWN_NONE)
+ return None;
+
+ if (lastOwnedSelectionIndex == CLIP_OWN_PRIMARY)
+ return XA_PRIMARY;
+
+ if (lastOwnedSelectionIndex == CLIP_OWN_CLIPBOARD)
+ return atoms->atomClipboard;
+
+ return None;
+}
+
+
+void
+winClipboardInitMonitoredSelections(void)
+{
+ /* Initialize static variables */
+ int i;
+ for (i = 0; i < CLIP_NUM_SELECTIONS; ++i)
+ s_iOwners[i] = None;
+
+ lastOwnedSelectionIndex = CLIP_OWN_NONE;
+}
+
+static int
+winClipboardSelectionNotifyTargets(HWND hwnd, Window iWindow, Display *pDisplay, ClipboardConversionData *data, ClipboardAtoms *atoms)
+{
+ Atom type;
+ int format;
+ unsigned long nitems;
+ unsigned long after;
+ Atom *prop;
+
+ /* Retrieve the selection data and delete the property */
+ int iReturn = XGetWindowProperty(pDisplay,
+ iWindow,
+ atoms->atomLocalProperty,
+ 0,
+ INT_MAX,
+ True,
+ AnyPropertyType,
+ &type,
+ &format,
+ &nitems,
+ &after,
+ (unsigned char **)&prop);
+ if (iReturn != Success) {
+ ErrorF("winClipboardFlushXEvents - SelectionNotify - "
+ "XGetWindowProperty () failed, aborting: %d\n", iReturn);
+ } else {
+ int i;
+ data->targetList = malloc((nitems+1)*sizeof(Atom));
+
+ for (i = 0; i < nitems; i++)
+ {
+ Atom atom = prop[i];
+ char *pszAtomName = XGetAtomName(pDisplay, atom);
+ data->targetList[i] = atom;
+ winDebug("winClipboardFlushXEvents - SelectionNotify - target[%d] %d = %s\n", i, atom, pszAtomName);
+ XFree(pszAtomName);
+ }
+
+ data->targetList[nitems] = 0;
+
+ XFree(prop);
+ }
+
+ return WIN_XEVENTS_NOTIFY_TARGETS;
+}
/*
* Process any pending X events
@@ -47,21 +195,13 @@ extern Bool g_fClipboardPrimary;
int
winClipboardFlushXEvents(HWND hwnd,
- int iWindow, Display * pDisplay, Bool fUseUnicode, Bool ClipboardOpened)
+ Window iWindow, Display * pDisplay, ClipboardConversionData *data, ClipboardAtoms *atoms)
{
- static Atom atomLocalProperty;
- static Atom atomCompoundText;
- static Atom atomUTF8String;
- static Atom atomTargets;
- static int generation;
-
- if (generation != serverGeneration) {
- generation = serverGeneration;
- atomLocalProperty = XInternAtom(pDisplay, WIN_LOCAL_PROPERTY, False);
- atomUTF8String = XInternAtom(pDisplay, "UTF8_STRING", False);
- atomCompoundText = XInternAtom(pDisplay, "COMPOUND_TEXT", False);
- atomTargets = XInternAtom(pDisplay, "TARGETS", False);
- }
+ Atom atomClipboard = atoms->atomClipboard;
+ Atom atomLocalProperty = atoms->atomLocalProperty;
+ Atom atomUTF8String = atoms->atomUTF8String;
+ Atom atomCompoundText = atoms->atomCompoundText;
+ Atom atomTargets = atoms->atomTargets;
/* Process all pending events */
while (XPending(pDisplay)) {
@@ -74,15 +214,11 @@ winClipboardFlushXEvents(HWND hwnd,
int iReturn;
HGLOBAL hGlobal = NULL;
XICCEncodingStyle xiccesStyle;
- int iConvertDataLen = 0;
char *pszConvertData = NULL;
char *pszTextList[2] = { NULL };
int iCount;
char **ppszTextList = NULL;
wchar_t *pwszUnicodeStr = NULL;
- int iUnicodeLen = 0;
- int iReturnDataLen = 0;
- int i;
Bool fAbort = FALSE;
Bool fCloseClipboard = FALSE;
Bool fSetClipboardData = TRUE;
@@ -90,8 +226,6 @@ winClipboardFlushXEvents(HWND hwnd,
/* Get the next event - will not block because one is ready */
XNextEvent(pDisplay, &event);
- winDebug ("Received event type %d\n",event.type);
-
/* Branch on the event type */
switch (event.type) {
/*
@@ -111,8 +245,6 @@ winClipboardFlushXEvents(HWND hwnd,
winDebug("SelectionRequest - Target atom name %s\n", pszAtomName);
XFree(pszAtomName);
pszAtomName = NULL;
- winDebug ("SelectionRequest - owner %d\n", event.xselectionrequest.owner);
- winDebug ("SelectionRequest - requestor %d\n", event.xselectionrequest.requestor);
}
#endif
@@ -182,8 +314,7 @@ winClipboardFlushXEvents(HWND hwnd,
if (!OpenClipboard (hwnd))
{
ErrorF ("winClipboardFlushXEvents - SelectionRequest - "
- "OpenClipboard () failed: %08lx\n",
- GetLastError ());
+ "OpenClipboard () failed: %08lx\n", GetLastError());
/* Abort */
fAbort = TRUE;
@@ -195,7 +326,7 @@ winClipboardFlushXEvents(HWND hwnd,
}
/* Check that clipboard format is available */
- if (fUseUnicode && !IsClipboardFormatAvailable(CF_UNICODETEXT)) {
+ if (data->fUseUnicode && !IsClipboardFormatAvailable(CF_UNICODETEXT)) {
static int count; /* Hack to stop acroread spamming the log */
static HWND lasthwnd; /* I've not seen any other client get here repeatedly? */
@@ -212,7 +343,7 @@ winClipboardFlushXEvents(HWND hwnd,
fAbort = TRUE;
goto winClipboardFlushXEvents_SelectionRequest_Done;
}
- else if (!fUseUnicode && !IsClipboardFormatAvailable(CF_TEXT)) {
+ else if (!data->fUseUnicode && !IsClipboardFormatAvailable(CF_TEXT)) {
ErrorF("winClipboardFlushXEvents - CF_TEXT is not "
"available from Win32 clipboard. Aborting.\n");
@@ -234,7 +365,7 @@ winClipboardFlushXEvents(HWND hwnd,
xiccesStyle = XStringStyle;
/* Get a pointer to the clipboard text, in desired format */
- if (fUseUnicode) {
+ if (data->fUseUnicode) {
/* Retrieve clipboard data */
hGlobal = GetClipboardData(CF_UNICODETEXT);
}
@@ -243,17 +374,17 @@ winClipboardFlushXEvents(HWND hwnd,
hGlobal = GetClipboardData(CF_TEXT);
}
if (!hGlobal) {
- if (GetLastError()==ERROR_CLIPBOARD_NOT_OPEN && ClipboardOpened)
- {
- ErrorF("We should not have received a SelectionRequest????\n"
- "The owner is the clipboard, but in reality it was"
- "an X window\n");
- /* Set the owner to None */
- if (g_fClipboardPrimary) XSetSelectionOwner (pDisplay, XA_PRIMARY, None, CurrentTime);
- XSetSelectionOwner (pDisplay, XInternAtom (pDisplay, "CLIPBOARD", False), None, CurrentTime);
- }
- ErrorF ("winClipboardFlushXEvents - SelectionRequest - "
- "GetClipboardData () failed: %08lx\n", GetLastError());
+ if (GetLastError()==ERROR_CLIPBOARD_NOT_OPEN && ClipboardOpened)
+ {
+ ErrorF("We should not have received a SelectionRequest????\n"
+ "The owner is the clipboard, but in reality it was"
+ "an X window\n");
+ /* Set the owner to None */
+ if (g_fClipboardPrimary) XSetSelectionOwner (pDisplay, XA_PRIMARY, None, CurrentTime);
+ XSetSelectionOwner (pDisplay, XInternAtom (pDisplay, "CLIPBOARD", False), None, CurrentTime);
+ }
+ ErrorF ("winClipboardFlushXEvents - SelectionRequest - "
+ "GetClipboardData () failed: %08lx\n", GetLastError());
/* Abort */
fAbort = TRUE;
@@ -262,8 +393,8 @@ winClipboardFlushXEvents(HWND hwnd,
pszGlobalData = (char *) GlobalLock(hGlobal);
/* Convert the Unicode string to UTF8 (MBCS) */
- if (fUseUnicode) {
- iConvertDataLen = WideCharToMultiByte(CP_UTF8,
+ if (data->fUseUnicode) {
+ int iConvertDataLen = WideCharToMultiByte(CP_UTF8,
0,
(LPCWSTR) pszGlobalData,
-1, NULL, 0, NULL, NULL);
@@ -278,7 +409,6 @@ winClipboardFlushXEvents(HWND hwnd,
}
else {
pszConvertData = strdup(pszGlobalData);
- iConvertDataLen = strlen(pszConvertData) + 1;
}
/* Convert DOS string to UNIX string */
@@ -293,7 +423,7 @@ winClipboardFlushXEvents(HWND hwnd,
xtpText.nitems = 0;
/* Create the text property from the text list */
- if (fUseUnicode) {
+ if (data->fUseUnicode) {
#ifdef X_HAVE_UTF8_STRING
iReturn = Xutf8TextListToTextProperty(pDisplay,
pszTextList,
@@ -340,11 +470,11 @@ winClipboardFlushXEvents(HWND hwnd,
/* Release the clipboard data */
GlobalUnlock(hGlobal);
pszGlobalData = NULL;
- if (fCloseClipboard)
- {
- fCloseClipboard = FALSE;
- CloseClipboard ();
- }
+ if (fCloseClipboard)
+ {
+ fCloseClipboard = FALSE;
+ CloseClipboard ();
+ }
/* Clean up */
XFree(xtpText.value);
xtpText.value = NULL;
@@ -423,6 +553,7 @@ winClipboardFlushXEvents(HWND hwnd,
/*
* SelectionNotify
*/
+
case SelectionNotify:
#ifdef _DEBUG
winDebug("winClipboardFlushXEvents - SelectionNotify\n");
@@ -435,82 +566,37 @@ winClipboardFlushXEvents(HWND hwnd,
winDebug
("winClipboardFlushXEvents - SelectionNotify - ATOM: %s\n",
pszAtomName);
- winDebug ("SelectionNotify - requestor %d\n", event.xselectionrequest.requestor);
XFree(pszAtomName);
}
#endif
/*
- * Request conversion of UTF8 and CompoundText targets.
- */
- if (event.xselection.property == None) {
- if (event.xselection.target == XA_STRING) {
- winDebug("winClipboardFlushXEvents - SelectionNotify - "
- "XA_STRING\n");
+ SelectionNotify with property of None indicates either:
- return WIN_XEVENTS_CONVERT;
- }
- else if (event.xselection.target == atomUTF8String) {
- winDebug("winClipboardFlushXEvents - SelectionNotify - "
- "Requesting conversion of UTF8 target.\n");
-
- XConvertSelection(pDisplay,
- event.xselection.selection,
- XA_STRING,
- atomLocalProperty, iWindow, CurrentTime);
-
- /* Process the ConvertSelection event */
- XFlush(pDisplay);
- return WIN_XEVENTS_CONVERT;
- }
-#ifdef X_HAVE_UTF8_STRING
- else if (event.xselection.target == atomCompoundText) {
- winDebug("winClipboardFlushXEvents - SelectionNotify - "
- "Requesting conversion of CompoundText target.\n");
-
- XConvertSelection(pDisplay,
- event.xselection.selection,
- atomUTF8String,
- atomLocalProperty, iWindow, CurrentTime);
-
- /* Process the ConvertSelection event */
- XFlush(pDisplay);
- return WIN_XEVENTS_CONVERT;
- }
-#endif
- else {
+ (i) Generated by the X server if no owner for the specified selection exists
+ (perhaps it's disappeared on us mid-transaction), or
+ (ii) Sent by the selection owner when the requested selection conversion could
+ not be performed or server errors prevented the conversion data being returned
+ */
+ if (event.xselection.property == None) {
ErrorF("winClipboardFlushXEvents - SelectionNotify - "
- "Unknown format. Cannot request conversion, "
- "aborting.\n");
- break;
+ "Conversion to format %d refused.\n",
+ event.xselection.target);
+ return WIN_XEVENTS_FAILED;
}
- }
- /* Retrieve the size of the stored data */
- iReturn = XGetWindowProperty(pDisplay, iWindow, atomLocalProperty, 0, 0, /* Don't get data, just size */
- False,
- AnyPropertyType,
- &xtpText.encoding,
- &xtpText.format,
- &xtpText.nitems,
- &ulReturnBytesLeft, &xtpText.value);
- if (iReturn != Success) {
- ErrorF("winClipboardFlushXEvents - SelectionNotify - "
- "XGetWindowProperty () failed, aborting: %d\n", iReturn);
- break;
+ if (event.xselection.target == atomTargets) {
+ return winClipboardSelectionNotifyTargets(hwnd, iWindow, pDisplay, data, atoms);
}
- winDebug("SelectionNotify - returned data %d left %d\n",
- xtpText.nitems, ulReturnBytesLeft);
-
- /* Request the selection data */
+ /* Retrieve the selection data and delete the property */
iReturn = XGetWindowProperty(pDisplay,
iWindow,
atomLocalProperty,
0,
- ulReturnBytesLeft,
- False,
+ INT_MAX,
+ True,
AnyPropertyType,
&xtpText.encoding,
&xtpText.format,
@@ -519,7 +605,7 @@ winClipboardFlushXEvents(HWND hwnd,
if (iReturn != Success) {
ErrorF("winClipboardFlushXEvents - SelectionNotify - "
"XGetWindowProperty () failed, aborting: %d\n", iReturn);
- break;
+ goto winClipboardFlushXEvents_SelectionNotify_Done;
}
#ifdef WINDBG
@@ -535,7 +621,7 @@ winClipboardFlushXEvents(HWND hwnd,
}
#endif
- if (fUseUnicode) {
+ if (data->fUseUnicode) {
#ifdef X_HAVE_UTF8_STRING
/* Convert the text property to a text list */
iReturn = Xutf8TextPropertyToTextList(pDisplay,
@@ -551,7 +637,8 @@ winClipboardFlushXEvents(HWND hwnd,
if (iReturn == Success || iReturn > 0) {
/* Conversion succeeded or some unconvertible characters */
if (ppszTextList != NULL) {
- iReturnDataLen = 0;
+ int i;
+ int iReturnDataLen = 0;
for (i = 0; i < iCount; i++) {
iReturnDataLen += strlen(ppszTextList[i]);
}
@@ -600,14 +687,14 @@ winClipboardFlushXEvents(HWND hwnd,
/* Convert the X clipboard string to DOS format */
winClipboardUNIXtoDOS((unsigned char **)&pszReturnData, strlen(pszReturnData));
- if (fUseUnicode) {
+ if (data->fUseUnicode) {
/* Find out how much space needed to convert MBCS to Unicode */
- iUnicodeLen = MultiByteToWideChar(CP_UTF8,
+ int iUnicodeLen = MultiByteToWideChar(CP_UTF8,
0,
pszReturnData, -1, NULL, 0);
- /* Allocate memory for the Unicode string */
- pwszUnicodeStr = malloc(sizeof(wchar_t) * (iUnicodeLen + 1));
+ /* NOTE: iUnicodeLen includes space for null terminator */
+ pwszUnicodeStr = malloc(sizeof(wchar_t) * iUnicodeLen);
if (!pwszUnicodeStr) {
ErrorF("winClipboardFlushXEvents - SelectionNotify "
"malloc failed for pwszUnicodeStr, aborting.\n");
@@ -625,9 +712,10 @@ winClipboardFlushXEvents(HWND hwnd,
/* Allocate global memory for the X clipboard data */
hGlobal = GlobalAlloc(GMEM_MOVEABLE,
- sizeof(wchar_t) * (iUnicodeLen + 1));
+ sizeof(wchar_t) * iUnicodeLen);
}
else {
+ int iConvertDataLen = 0;
pszConvertData = strdup(pszReturnData);
iConvertDataLen = strlen(pszConvertData) + 1;
@@ -659,9 +747,8 @@ winClipboardFlushXEvents(HWND hwnd,
}
/* Copy the returned string into the global memory */
- if (fUseUnicode) {
- memcpy(pszGlobalData,
- pwszUnicodeStr, sizeof(wchar_t) * (iUnicodeLen + 1));
+ if (data->fUseUnicode) {
+ wcscpy((wchar_t *)pszGlobalData, pwszUnicodeStr);
free(pwszUnicodeStr);
pwszUnicodeStr = NULL;
}
@@ -676,7 +763,7 @@ winClipboardFlushXEvents(HWND hwnd,
pszGlobalData = NULL;
/* Push the selection data to the Windows clipboard */
- if (fUseUnicode)
+ if (data->fUseUnicode)
SetClipboardData(CF_UNICODETEXT, hGlobal);
else
SetClipboardData(CF_TEXT, hGlobal);
@@ -706,39 +793,92 @@ winClipboardFlushXEvents(HWND hwnd,
SetClipboardData(CF_UNICODETEXT, NULL);
SetClipboardData(CF_TEXT, NULL);
}
- return WIN_XEVENTS_NOTIFY;
+ return WIN_XEVENTS_NOTIFY_DATA;
- /*
- * SelectionClear
- */
- case SelectionClear:
-#ifdef _DEBUG
+ case SelectionClear:
winDebug("SelectionClear - doing nothing\n");
- {
- char *pszAtomName;
-
- pszAtomName = XGetAtomName (pDisplay,
- event.xselection.selection);
-
- winDebug ("SelectionClear - ATOM: %s\n",
- pszAtomName);
- winDebug ("SelectionClear - owner %d\n", event.xselectionrequest.owner);
-
- XFree (pszAtomName);
- }
-#endif
break;
case PropertyNotify:
break;
-
+
case MappingNotify:
XRefreshKeyboardMapping((XMappingEvent *)&event);
break;
default:
- ErrorF("winClipboardFlushXEvents - unexpected event type %d\n",
- event.type);
+ if (event.type == XFixesSetSelectionOwnerNotify + xfixes_event_base) {
+ XFixesSelectionNotifyEvent *e =
+ (XFixesSelectionNotifyEvent *) & event;
+
+ winDebug("winClipboardFlushXEvents - XFixesSetSelectionOwnerNotify\n");
+
+ /* Save selection owners for monitored selections, ignore other selections */
+ if ((e->selection == XA_PRIMARY) && fPrimarySelection) {
+ MonitorSelection(e, CLIP_OWN_PRIMARY);
+ }
+ else if (e->selection == atomClipboard) {
+ MonitorSelection(e, CLIP_OWN_CLIPBOARD);
+ }
+ else
+ break;
+
+ /* Selection is being disowned */
+ if (e->owner == None) {
+ winDebug
+ ("winClipboardFlushXEvents - No window, returning.\n");
+ break;
+ }
+
+ /*
+ XXX: there are all kinds of wacky edge cases we might need here:
+ - we own windows clipboard, but neither PRIMARY nor CLIPBOARD have an owner, so we should disown it?
+ - root window is taking ownership?
+ */
+
+ /* If we are the owner of the most recently owned selection, don't go all recursive :) */
+ if ((lastOwnedSelectionIndex != CLIP_OWN_NONE) &&
+ (s_iOwners[lastOwnedSelectionIndex] == iWindow)) {
+ winDebug("winClipboardFlushXEvents - Ownership changed to us, aborting.\n");
+ break;
+ }
+
+ /* Close clipboard if we have it open already (possible? correct??) */
+ if (GetOpenClipboardWindow() == hwnd) {
+ CloseClipboard();
+ }
+
+ /* Access the Windows clipboard */
+ if (!OpenClipboard(hwnd)) {
+ ErrorF("winClipboardFlushXEvents - OpenClipboard () failed: %08x\n",
+ (int) GetLastError());
+ break;
+ }
+
+ /* Take ownership of the Windows clipboard */
+ if (!EmptyClipboard()) {
+ ErrorF("winClipboardFlushXEvents - EmptyClipboard () failed: %08x\n",
+ (int) GetLastError());
+ break;
+ }
+
+ /* Advertise regular text and unicode */
+ SetClipboardData(CF_UNICODETEXT, NULL);
+ SetClipboardData(CF_TEXT, NULL);
+
+ /* Release the clipboard */
+ if (!CloseClipboard()) {
+ ErrorF("winClipboardFlushXEvents - CloseClipboard () failed: %08x\n",
+ (int) GetLastError());
+ break;
+ }
+ }
+ /* XFixesSelectionWindowDestroyNotifyMask */
+ /* XFixesSelectionClientCloseNotifyMask */
+ else {
+ ErrorF("winClipboardFlushXEvents - unexpected event type %d\n",
+ event.type);
+ }
break;
}
}
diff --git a/xorg-server/hw/xwin/winclipboard/xwinclip.c b/xorg-server/hw/xwin/winclipboard/xwinclip.c
index 3677974c4..856c4dd54 100644
--- a/xorg-server/hw/xwin/winclipboard/xwinclip.c
+++ b/xorg-server/hw/xwin/winclipboard/xwinclip.c
@@ -92,6 +92,13 @@ main (int argc, char *argv[])
continue;
}
+ /* Look for -noprimary */
+ if (!strcmp (argv[i], "-noprimary"))
+ {
+ fPrimarySelection = False;
+ continue;
+ }
+
/* Yack when we find a parameter that we don't know about */
printf ("Unknown parameter: %s\nExiting.\n", argv[i]);
exit (1);
diff --git a/xorg-server/hw/xwin/winclipboard/xwinclip.man b/xorg-server/hw/xwin/winclipboard/xwinclip.man
index 822db91d4..a53dc3029 100644
--- a/xorg-server/hw/xwin/winclipboard/xwinclip.man
+++ b/xorg-server/hw/xwin/winclipboard/xwinclip.man
@@ -29,6 +29,9 @@ Specifies the X server display to connect to.
.TP 8
.B \-nounicodeclipboard
Do not use unicode text on the clipboard.
+.TP 8
+.B \-noprimary
+Do not monitor the PRIMARY selection.
.SH "SEE ALSO"
XWin(1)
diff --git a/xorg-server/hw/xwin/winclipboardwrappers.c b/xorg-server/hw/xwin/winclipboardwrappers.c
index 2671fc000..c0598f9b3 100644..100755
--- a/xorg-server/hw/xwin/winclipboardwrappers.c
+++ b/xorg-server/hw/xwin/winclipboardwrappers.c
@@ -33,6 +33,7 @@
#ifdef HAVE_XWIN_CONFIG_H
#include <xwin-config.h>
#endif
+
#include "win.h"
#include "dixstruct.h"
#include <X11/Xatom.h>
@@ -52,19 +53,13 @@
DISPATCH_PROC(winProcEstablishConnection);
DISPATCH_PROC(winProcSetSelectionOwner);
-/*
- * References to external symbols
- */
-
extern Bool g_fClipboardLaunched;
extern Bool g_fClipboardStarted;
-extern Bool g_fClipboard;
extern Window g_iClipboardWindow;
extern Atom g_atomLastOwnedSelection;
extern HWND g_hwndClipboard;
extern Bool g_fClipboardPrimary;
-
/*
* Wrapper for internal EstablishConnection function.
* Initializes internal clients that must not be started until
diff --git a/xorg-server/hw/xwin/winprocarg.c b/xorg-server/hw/xwin/winprocarg.c
index ad0b5bbe9..29fcbc9ed 100644..100755
--- a/xorg-server/hw/xwin/winprocarg.c
+++ b/xorg-server/hw/xwin/winprocarg.c
@@ -37,13 +37,8 @@ from The Open Group.
#include "winmsg.h"
#include "winmonitors.h"
-/*
- * References to external symbols
- */
-
#ifdef XWIN_CLIPBOARD
-extern Bool g_fUnicodeClipboard;
-extern Bool g_fClipboard;
+#include "winclipboard/winclipboard.h"
extern Bool g_fClipboardPrimary;
#endif
@@ -719,6 +714,26 @@ ddxProcessArgument(int argc, char *argv[], int i)
/* Indicate that we have processed this argument */
return 1;
}
+
+ /*
+ * Look for the '-primary' argument
+ */
+ if (IS_OPTION("-primary")) {
+ fPrimarySelection = TRUE;
+
+ /* Indicate that we have processed this argument */
+ return 1;
+ }
+
+ /*
+ * Look for the '-noprimary' argument
+ */
+ if (IS_OPTION("-noprimary")) {
+ fPrimarySelection = FALSE;
+
+ /* Indicate that we have processed this argument */
+ return 1;
+ }
/*
* Look for the '-clipboard' argument
diff --git a/xorg-server/hw/xwin/winresource.h b/xorg-server/hw/xwin/winresource.h
index 39b890c7c..b9f88c18f 100644
--- a/xorg-server/hw/xwin/winresource.h
+++ b/xorg-server/hw/xwin/winresource.h
@@ -43,6 +43,7 @@
#define ID_APP_HIDE_ROOT 201
#define ID_APP_ALWAYS_ON_TOP 202
#define ID_APP_ABOUT 203
+#define ID_APP_MONITOR_PRIMARY 204
#define ID_ABOUT_WEBSITE 303
diff --git a/xorg-server/hw/xwin/wintrayicon.c b/xorg-server/hw/xwin/wintrayicon.c
index 3c7820cf7..7df1594e6 100644
--- a/xorg-server/hw/xwin/wintrayicon.c
+++ b/xorg-server/hw/xwin/wintrayicon.c
@@ -32,9 +32,13 @@
#ifdef HAVE_XWIN_CONFIG_H
#include <xwin-config.h>
#endif
+
#include "win.h"
#include <shellapi.h>
#include "winprefs.h"
+#ifdef XWIN_CLIPBOARD
+#include "winclipboard/winclipboard.h"
+#endif
static NOTIFYICONDATA nid;
/*
@@ -193,6 +197,21 @@ winHandleIconMessage(HWND hwnd, UINT message,
RemoveMenu(hmenuTray, ID_APP_HIDE_ROOT, MF_BYCOMMAND);
}
+#ifdef XWIN_CLIPBOARD
+ if (g_fClipboard) {
+ /* Set menu state to indicate if 'Monitor Primary' is enabled or not */
+ MENUITEMINFO mii = { 0 };
+ mii.cbSize = sizeof(MENUITEMINFO);
+ mii.fMask = MIIM_STATE;
+ mii.fState = fPrimarySelection ? MFS_CHECKED : MFS_UNCHECKED;
+ SetMenuItemInfo(hmenuTray, ID_APP_MONITOR_PRIMARY, FALSE, &mii);
+ }
+ else {
+ /* Remove 'Monitor Primary' menu item */
+ RemoveMenu(hmenuTray, ID_APP_MONITOR_PRIMARY, MF_BYCOMMAND);
+ }
+#endif
+
SetupRootMenu(hmenuTray);
/*
diff --git a/xorg-server/hw/xwin/winwndproc.c b/xorg-server/hw/xwin/winwndproc.c
index 9a150d57b..a88f7c68d 100755
--- a/xorg-server/hw/xwin/winwndproc.c
+++ b/xorg-server/hw/xwin/winwndproc.c
@@ -1189,6 +1189,12 @@ winWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
return 0;
#endif
+#ifdef XWIN_CLIPBOARD
+ case ID_APP_MONITOR_PRIMARY:
+ fPrimarySelection = !fPrimarySelection;
+ return 0;
+#endif
+
case ID_APP_ABOUT:
/* Display the About box */
winDisplayAboutDialog(s_pScreenPriv);