From 27bcf40cda1d7c52b189cc76528f1f51cbe1d5eb Mon Sep 17 00:00:00 2001 From: Eamon Walsh Date: Thu, 28 Feb 2008 16:43:43 -0500 Subject: [PATCH 001/149] XACE: Fix instances of DixUnknownAccess at hook callsites. --- GL/glx/glxcmds.c | 8 ++++---- Xext/panoramiX.c | 6 +++--- Xext/panoramiXprocs.c | 8 ++++---- Xext/shm.c | 6 +++--- Xext/xprint.c | 2 +- Xi/exevents.c | 2 +- composite/compwindow.c | 2 +- config/dbus.c | 2 +- hw/dmx/glxProxy/glxcmds.c | 24 ++++++++++++------------ hw/xquartz/pseudoramiX.c | 6 +++--- randr/rrxinerama.c | 6 +++--- 11 files changed, 36 insertions(+), 36 deletions(-) diff --git a/GL/glx/glxcmds.c b/GL/glx/glxcmds.c index 21f3206c3..32d1bc834 100644 --- a/GL/glx/glxcmds.c +++ b/GL/glx/glxcmds.c @@ -479,7 +479,7 @@ __glXGetDrawable(__GLXcontext *glxc, GLXDrawable drawId, ClientPtr client, * resource ID clashes. Effectively, the X Window is now also a * GLXWindow. */ - rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixUnknownAccess); + rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixGetAttrAccess); if (rc != Success || pDraw->type != DRAWABLE_WINDOW) { client->errorValue = drawId; *error = __glXError(GLXBadDrawable); @@ -1086,7 +1086,7 @@ DoCreateGLXPixmap(ClientPtr client, __GLXscreen *pGlxScreen, __GLcontextModes *c DrawablePtr pDraw; int err; - err = dixLookupDrawable(&pDraw, drawableId, client, 0, DixUnknownAccess); + err = dixLookupDrawable(&pDraw, drawableId, client, 0, DixAddAccess); if (err != Success || pDraw->type != DRAWABLE_PIXMAP) { client->errorValue = drawableId; return BadPixmap; @@ -1364,7 +1364,7 @@ int __glXDisp_CreateWindow(__GLXclientState *cl, GLbyte *pc) if (!validGlxFBConfig(client, pGlxScreen, req->fbconfig, &config, &err)) return err; - err = dixLookupDrawable(&pDraw, req->window, client, 0, DixUnknownAccess); + err = dixLookupDrawable(&pDraw, req->window, client, 0, DixAddAccess); if (err != Success || pDraw->type != DRAWABLE_WINDOW) { client->errorValue = req->window; return BadWindow; @@ -2004,7 +2004,7 @@ int __glXDisp_BindSwapBarrierSGIX(__GLXclientState *cl, GLbyte *pc) int screen, rc; __GLXscreen *pGlxScreen; - rc = dixLookupDrawable(&pDraw, drawable, client, 0, DixUnknownAccess); + rc = dixLookupDrawable(&pDraw, drawable, client, 0, DixGetAttrAccess); pGlxScreen = glxGetScreen(pDraw->pScreen); if (rc == Success && (pDraw->type == DRAWABLE_WINDOW)) { screen = pDraw->pScreen->myNum; diff --git a/Xext/panoramiX.c b/Xext/panoramiX.c index d8ec588aa..f92414764 100644 --- a/Xext/panoramiX.c +++ b/Xext/panoramiX.c @@ -919,7 +919,7 @@ ProcPanoramiXGetState(ClientPtr client) register int n, rc; REQUEST_SIZE_MATCH(xPanoramiXGetStateReq); - rc = dixLookupWindow(&pWin, stuff->window, client, DixUnknownAccess); + rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess); if (rc != Success) return rc; @@ -946,7 +946,7 @@ ProcPanoramiXGetScreenCount(ClientPtr client) register int n, rc; REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq); - rc = dixLookupWindow(&pWin, stuff->window, client, DixUnknownAccess); + rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess); if (rc != Success) return rc; @@ -972,7 +972,7 @@ ProcPanoramiXGetScreenSize(ClientPtr client) register int n, rc; REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq); - rc = dixLookupWindow(&pWin, stuff->window, client, DixUnknownAccess); + rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess); if (rc != Success) return rc; diff --git a/Xext/panoramiXprocs.c b/Xext/panoramiXprocs.c index d19b3039a..30aff7460 100644 --- a/Xext/panoramiXprocs.c +++ b/Xext/panoramiXprocs.c @@ -525,7 +525,7 @@ int PanoramiXGetGeometry(ClientPtr client) REQUEST(xResourceReq); REQUEST_SIZE_MATCH(xResourceReq); - rc = dixLookupDrawable(&pDraw, stuff->id, client, M_ANY, DixUnknownAccess); + rc = dixLookupDrawable(&pDraw, stuff->id, client, M_ANY, DixGetAttrAccess); if (rc != Success) return rc; @@ -1024,7 +1024,7 @@ int PanoramiXCopyArea(ClientPtr client) FOR_NSCREENS(j) { rc = dixLookupDrawable(drawables+j, src->info[j].id, client, 0, - DixUnknownAccess); + DixGetAttrAccess); if (rc != Success) return rc; } @@ -1779,7 +1779,7 @@ int PanoramiXGetImage(ClientPtr client) return (*SavedProcVector[X_GetImage])(client); rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, - DixUnknownAccess); + DixReadAccess); if (rc != Success) return rc; @@ -1817,7 +1817,7 @@ int PanoramiXGetImage(ClientPtr client) drawables[0] = pDraw; for(i = 1; i < PanoramiXNumScreens; i++) { rc = dixLookupDrawable(drawables+i, draw->info[i].id, client, 0, - DixUnknownAccess); + DixGetAttrAccess); if (rc != Success) return rc; } diff --git a/Xext/shm.c b/Xext/shm.c index a7a1ecf75..b2973bff6 100644 --- a/Xext/shm.c +++ b/Xext/shm.c @@ -655,7 +655,7 @@ ProcPanoramiXShmGetImage(ClientPtr client) return ProcShmGetImage(client); rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, - DixUnknownAccess); + DixReadAccess); if (rc != Success) return rc; @@ -692,7 +692,7 @@ ProcPanoramiXShmGetImage(ClientPtr client) drawables[0] = pDraw; for(i = 1; i < PanoramiXNumScreens; i++) { rc = dixLookupDrawable(drawables+i, draw->info[i].id, client, 0, - DixUnknownAccess); + DixReadAccess); if (rc != Success) return rc; } @@ -767,7 +767,7 @@ ProcPanoramiXShmCreatePixmap( return BadImplementation; LEGAL_NEW_RESOURCE(stuff->pid, client); rc = dixLookupDrawable(&pDraw, stuff->drawable, client, M_ANY, - DixUnknownAccess); + DixGetAttrAccess); if (rc != Success) return rc; diff --git a/Xext/xprint.c b/Xext/xprint.c index dba7989cc..a5d8fcc33 100644 --- a/Xext/xprint.c +++ b/Xext/xprint.c @@ -1800,7 +1800,7 @@ ProcXpPutDocumentData(ClientPtr client) if (pContext->state & DOC_RAW_STARTED) return BadDrawable; result = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, - DixUnknownAccess); + DixWriteAccess); if (result != Success) return result; if (pDraw->pScreen->myNum != pContext->screenNum) diff --git a/Xi/exevents.c b/Xi/exevents.c index ac6b92383..fb84bef6f 100644 --- a/Xi/exevents.c +++ b/Xi/exevents.c @@ -833,7 +833,7 @@ SendEvent(ClientPtr client, DeviceIntPtr d, Window dest, Bool propagate, } else effectiveFocus = pWin = inputFocus; } else - dixLookupWindow(&pWin, dest, client, DixUnknownAccess); + dixLookupWindow(&pWin, dest, client, DixSendAccess); if (!pWin) return BadWindow; if ((propagate != xFalse) && (propagate != xTrue)) { diff --git a/composite/compwindow.c b/composite/compwindow.c index ee0f7d270..c022027db 100644 --- a/composite/compwindow.c +++ b/composite/compwindow.c @@ -92,7 +92,7 @@ static Bool compRepaintBorder (ClientPtr pClient, pointer closure) { WindowPtr pWindow; - int rc = dixLookupWindow(&pWindow, (XID)closure, pClient,DixUnknownAccess); + int rc = dixLookupWindow(&pWindow, (XID)closure, pClient, DixWriteAccess); if (rc == Success) { RegionRec exposed; diff --git a/config/dbus.c b/config/dbus.c index 0be42afb6..cef8ed5db 100644 --- a/config/dbus.c +++ b/config/dbus.c @@ -213,7 +213,7 @@ remove_device(DBusMessage *message, DBusMessage *reply, DBusError *error) MALFORMED_MESSAGE_ERROR(); } - dixLookupDevice(&dev, deviceid, serverClient, DixUnknownAccess); + dixLookupDevice(&dev, deviceid, serverClient, DixDestroyAccess); if (!dev) { DebugF("[config/dbus] bogus device id %d given\n", deviceid); ret = BadMatch; diff --git a/hw/dmx/glxProxy/glxcmds.c b/hw/dmx/glxProxy/glxcmds.c index 85e0f8701..ab7ee96b9 100644 --- a/hw/dmx/glxProxy/glxcmds.c +++ b/hw/dmx/glxProxy/glxcmds.c @@ -431,7 +431,7 @@ int __glXBindSwapBarrierSGIX(__GLXclientState *cl, GLbyte *pc) __glXWindow *pGlxWindow = NULL; int rc; - rc = dixLookupDrawable(&pDraw, req->drawable, client, 0, DixUnknownAccess); + rc = dixLookupDrawable(&pDraw, req->drawable, client, 0, DixGetAttrAccess); if (rc != Success) { pGlxPixmap = (__GLXpixmap *) LookupIDByType(req->drawable, __glXPixmapRes); @@ -461,7 +461,7 @@ int __glXJoinSwapGroupSGIX(__GLXclientState *cl, GLbyte *pc) __glXWindow *pGlxWindow = NULL; int rc; - rc = dixLookupDrawable(&pDraw, req->drawable, client, 0, DixUnknownAccess); + rc = dixLookupDrawable(&pDraw, req->drawable, client, 0, DixManageAccess); if (rc != Success) { pGlxPixmap = (__GLXpixmap *) LookupIDByType(req->drawable, __glXPixmapRes); @@ -481,7 +481,7 @@ int __glXJoinSwapGroupSGIX(__GLXclientState *cl, GLbyte *pc) if (req->member != None) { rc = dixLookupDrawable(&pMember, req->member, client, 0, - DixUnknownAccess); + DixGetAttrAccess); if (rc != Success) { pGlxPixmap = (__GLXpixmap *) LookupIDByType(req->member, __glXPixmapRes); @@ -780,7 +780,7 @@ static int MakeCurrent(__GLXclientState *cl, } if (drawId != None) { - rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixUnknownAccess); + rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixWriteAccess); if (rc == Success) { if (pDraw->type == DRAWABLE_WINDOW) { /* @@ -887,7 +887,7 @@ static int MakeCurrent(__GLXclientState *cl, } if (readId != None && readId != drawId ) { - rc = dixLookupDrawable(&pReadDraw, readId, client, 0,DixUnknownAccess); + rc = dixLookupDrawable(&pReadDraw, readId, client, 0, DixReadAccess); if (rc == Success) { if (pReadDraw->type == DRAWABLE_WINDOW) { /* @@ -1645,7 +1645,7 @@ static int CreateGLXPixmap(__GLXclientState *cl, #endif rc = dixLookupDrawable(&pDraw, pixmapId, client, M_DRAWABLE_PIXMAP, - DixUnknownAccess); + DixAddAccess); if (rc != Success) return rc; @@ -1779,7 +1779,7 @@ static int CreateGLXPixmap(__GLXclientState *cl, #ifdef PANORAMIX if (pXinDraw) { dixLookupDrawable(&pRealDraw, pXinDraw->info[s].id, client, 0, - DixUnknownAccess); + DixAddAccess); } #endif @@ -1950,7 +1950,7 @@ int __glXDoSwapBuffers(__GLXclientState *cl, XID drawId, GLXContextTag tag) /* ** Check that the GLX drawable is valid. */ - rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixUnknownAccess); + rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixWriteAccess); if (rc == Success) { from_screen = to_screen = pDraw->pScreen->myNum; @@ -2104,7 +2104,7 @@ int __glXSwapBuffers(__GLXclientState *cl, GLbyte *pc) /* ** Check that the GLX drawable is valid. */ - rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixUnknownAccess); + rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixWriteAccess); if (rc == Success) { if (pDraw->type != DRAWABLE_WINDOW) { /* @@ -2893,7 +2893,7 @@ int __glXCreateWindow(__GLXclientState *cl, GLbyte *pc) ** Check if windowId is valid */ rc = dixLookupDrawable(&pDraw, windowId, client, M_DRAWABLE_WINDOW, - DixUnknownAccess); + DixAddAccess); if (rc != Success) return rc; @@ -3277,7 +3277,7 @@ int __glXGetDrawableAttributes(__GLXclientState *cl, GLbyte *pc) #endif if (drawId != None) { - rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixUnknownAccess); + rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixGetAttrAccess); if (rc == Success) { if (pDraw->type == DRAWABLE_WINDOW) { WindowPtr pWin = (WindowPtr)pDraw; @@ -3438,7 +3438,7 @@ int __glXChangeDrawableAttributes(__GLXclientState *cl, GLbyte *pc) #endif if (drawId != None) { - rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixUnknownAccess); + rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixSetAttrAccess); if (rc == Success) { if (pDraw->type == DRAWABLE_WINDOW) { WindowPtr pWin = (WindowPtr)pDraw; diff --git a/hw/xquartz/pseudoramiX.c b/hw/xquartz/pseudoramiX.c index 4a9d8e1f1..49d5eb6d4 100644 --- a/hw/xquartz/pseudoramiX.c +++ b/hw/xquartz/pseudoramiX.c @@ -179,7 +179,7 @@ static int ProcPseudoramiXGetState(ClientPtr client) register int n, rc; REQUEST_SIZE_MATCH(xPanoramiXGetStateReq); - rc = dixLookupWindow(&pWin, stuff->window, client, DixUnknownAccess); + rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess); if (rc != Success) return rc; @@ -206,7 +206,7 @@ static int ProcPseudoramiXGetScreenCount(ClientPtr client) register int n, rc; REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq); - rc = dixLookupWindow(&pWin, stuff->window, client, DixUnknownAccess); + rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess); if (rc != Success) return rc; @@ -233,7 +233,7 @@ static int ProcPseudoramiXGetScreenSize(ClientPtr client) register int n, rc; REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq); - rc = dixLookupWindow(&pWin, stuff->window, client, DixUnknownAccess); + rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess); if (rc != Success) return rc; diff --git a/randr/rrxinerama.c b/randr/rrxinerama.c index 896f61fb5..240fca27a 100644 --- a/randr/rrxinerama.c +++ b/randr/rrxinerama.c @@ -122,7 +122,7 @@ ProcRRXineramaGetState(ClientPtr client) Bool active = FALSE; REQUEST_SIZE_MATCH(xPanoramiXGetStateReq); - rc = dixLookupWindow(&pWin, stuff->window, client, DixUnknownAccess); + rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess); if(rc != Success) return rc; @@ -184,7 +184,7 @@ ProcRRXineramaGetScreenCount(ClientPtr client) register int n, rc; REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq); - rc = dixLookupWindow(&pWin, stuff->window, client, DixUnknownAccess); + rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess); if (rc != Success) return rc; @@ -211,7 +211,7 @@ ProcRRXineramaGetScreenSize(ClientPtr client) register int n, rc; REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq); - rc = dixLookupWindow(&pWin, stuff->window, client, DixUnknownAccess); + rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess); if (rc != Success) return rc; From 5675ae1f72145e9b719c613023da525731b42461 Mon Sep 17 00:00:00 2001 From: Eamon Walsh Date: Thu, 28 Feb 2008 18:12:52 -0500 Subject: [PATCH 002/149] XACE: Call the creation hook to properly label COMPOSITE window pixmaps. --- composite/compext.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/composite/compext.c b/composite/compext.c index 2918556f8..97ea6d616 100644 --- a/composite/compext.c +++ b/composite/compext.c @@ -291,6 +291,12 @@ ProcCompositeNameWindowPixmap (ClientPtr client) ++pPixmap->refcnt; + /* security creation/labeling check */ + rc = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pixmap, RT_PIXMAP, + pPixmap, RT_WINDOW, pWin, DixCreateAccess); + if (rc != Success) + return rc; + if (!AddResource (stuff->pixmap, RT_PIXMAP, (pointer) pPixmap)) return BadAlloc; From 4d91b1d5e422c5c460b1b7050baa9487a59b8aa8 Mon Sep 17 00:00:00 2001 From: Eamon Walsh Date: Thu, 28 Feb 2008 21:52:32 -0500 Subject: [PATCH 003/149] XACE: Adjust the location of the COMPOSITE creation hook. Avoids incrementing the refcnt if the hook fails. --- composite/compext.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composite/compext.c b/composite/compext.c index 97ea6d616..b3433f72b 100644 --- a/composite/compext.c +++ b/composite/compext.c @@ -289,14 +289,14 @@ ProcCompositeNameWindowPixmap (ClientPtr client) if (!pPixmap) return BadMatch; - ++pPixmap->refcnt; - /* security creation/labeling check */ rc = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pixmap, RT_PIXMAP, pPixmap, RT_WINDOW, pWin, DixCreateAccess); if (rc != Success) return rc; + ++pPixmap->refcnt; + if (!AddResource (stuff->pixmap, RT_PIXMAP, (pointer) pPixmap)) return BadAlloc; From 3fb17a3e647e926688c91a49a9b5b97f37dbc367 Mon Sep 17 00:00:00 2001 From: Eamon Walsh Date: Thu, 28 Feb 2008 21:52:57 -0500 Subject: [PATCH 004/149] xselinux: Log messages to both libaudit and Xorg.0.log. --- Xext/xselinux.c | 1 + 1 file changed, 1 insertion(+) diff --git a/Xext/xselinux.c b/Xext/xselinux.c index 98e1ec563..3aa62e2c6 100644 --- a/Xext/xselinux.c +++ b/Xext/xselinux.c @@ -497,6 +497,7 @@ SELinuxLog(int type, const char *fmt, ...) vsnprintf(buf, MAX_AUDIT_MESSAGE_LENGTH, fmt, ap); rc = audit_log_user_avc_message(audit_fd, aut, buf, NULL, NULL, NULL, 0); va_end(ap); + LogMessageVerb(X_WARNING, 0, "%s", buf); return 0; } From d04ea267a4a51c16088d9ef429681a1edde536b1 Mon Sep 17 00:00:00 2001 From: Eamon Walsh Date: Thu, 28 Feb 2008 21:53:16 -0500 Subject: [PATCH 005/149] xselinux: Don't require device "read" permission for XQueryPointer. These keyboard and pointer state polling calls are a real problem. --- Xext/xselinux.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Xext/xselinux.c b/Xext/xselinux.c index 3aa62e2c6..9adc93195 100644 --- a/Xext/xselinux.c +++ b/Xext/xselinux.c @@ -532,6 +532,17 @@ SELinuxDevice(CallbackListPtr *pcbl, pointer unused, pointer calldata) dsubj->sid = subj->sid; } + /* XXX only check read permission on XQueryKeymap */ + /* This is to allow the numerous apps that call XQueryPointer to work */ + if (rec->access_mode & DixReadAccess) { + ClientPtr client = rec->client; + REQUEST(xReq); + if (stuff && stuff->reqType != X_QueryKeymap) { + rec->access_mode &= ~DixReadAccess; + rec->access_mode |= DixGetAttrAccess; + } + } + rc = SELinuxDoCheck(subj, obj, SECCLASS_X_DEVICE, rec->access_mode, &auditdata); if (rc != Success) From 13bfa5937d43392f686b76a99ea6331e3dce5987 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Fri, 29 Feb 2008 15:10:36 -0500 Subject: [PATCH 006/149] GLX: Adjust to changes in DRI driver interface. --- GL/glx/glxdri.c | 32 ++++++++++++++++++++++------ GL/glx/glxdri2.c | 48 ++++++++++++++---------------------------- hw/xfree86/dri2/dri2.c | 10 --------- hw/xfree86/dri2/dri2.h | 4 ---- 4 files changed, 41 insertions(+), 53 deletions(-) diff --git a/GL/glx/glxdri.c b/GL/glx/glxdri.c index f9b28e427..dc15b0fcc 100644 --- a/GL/glx/glxdri.c +++ b/GL/glx/glxdri.c @@ -828,18 +828,38 @@ static void __glXReportDamage(__DRIdrawable *driDraw, } /* Table of functions that we export to the driver. */ -static const __DRIinterfaceMethods interface_methods = { +static const __DRIcontextModesExtension contextModesExtension = { + { __DRI_CONTEXT_MODES, __DRI_CONTEXT_MODES_VERSION }, _gl_context_modes_create, _gl_context_modes_destroy, +}; - getDrawableInfo, - +static const __DRIsystemTimeExtension systemTimeExtension = { + { __DRI_SYSTEM_TIME, __DRI_SYSTEM_TIME_VERSION }, getUST, - NULL, /* glXGetMscRateOML, */ + NULL, +}; +static const __DRIgetDrawableInfoExtension getDrawableInfoExtension = { + { __DRI_GET_DRAWABLE_INFO, __DRI_GET_DRAWABLE_INFO_VERSION }, + getDrawableInfo +}; + +static const __DRIdamageExtension damageExtension = { + { __DRI_DAMAGE, __DRI_DAMAGE_VERSION }, __glXReportDamage, }; +static const __DRIextension *loader_extensions[] = { + &contextModesExtension.base, + &systemTimeExtension.base, + &getDrawableInfoExtension.base, + &damageExtension.base, + NULL +}; + + + static const char dri_driver_path[] = DRI_DRIVER_PATH; static Bool @@ -926,7 +946,6 @@ __glXDRIscreenProbe(ScreenPtr pScreen) __DRIframebuffer framebuffer; int fd = -1; int status; - int api_ver = 20070121; drm_magic_t magic; drmVersionPtr version; int newlyopened; @@ -1091,8 +1110,7 @@ __glXDRIscreenProbe(ScreenPtr pScreen) &framebuffer, pSAREA, fd, - api_ver, - &interface_methods, + loader_extensions, &screen->base.fbconfigs); if (screen->driScreen.private == NULL) { diff --git a/GL/glx/glxdri2.c b/GL/glx/glxdri2.c index d1c8d417e..b0082a040 100644 --- a/GL/glx/glxdri2.c +++ b/GL/glx/glxdri2.c @@ -414,18 +414,30 @@ static void __glXReportDamage(__DRIdrawable *driDraw, } /* Table of functions that we export to the driver. */ -static const __DRIinterfaceMethods interface_methods = { +static const __DRIcontextModesExtension contextModesExtension = { + { __DRI_CONTEXT_MODES, __DRI_CONTEXT_MODES_VERSION }, _gl_context_modes_create, _gl_context_modes_destroy, +}; - NULL, - +static const __DRIsystemTimeExtension systemTimeExtension = { + { __DRI_SYSTEM_TIME, __DRI_SYSTEM_TIME_VERSION }, getUST, NULL, +}; +static const __DRIdamageExtension damageExtension = { + { __DRI_DAMAGE, __DRI_DAMAGE_VERSION }, __glXReportDamage, }; +static const __DRIextension *loader_extensions[] = { + &contextModesExtension.base, + &systemTimeExtension.base, + &damageExtension.base, + NULL +}; + static const char dri_driver_path[] = DRI_DRIVER_PATH; static Bool @@ -502,10 +514,6 @@ static __GLXscreen * __glXDRIscreenProbe(ScreenPtr pScreen) { __DRI2_CREATE_NEW_SCREEN_FUNC *createNewScreen; - __DRIversion ddx_version; - __DRIversion dri_version; - __DRIversion drm_version; - drmVersionPtr version; const char *driverName; __GLXDRIscreen *screen; char filename[128]; @@ -522,9 +530,6 @@ __glXDRIscreenProbe(ScreenPtr pScreen) !DRI2Connect(pScreen, &screen->fd, &driverName, - &ddx_version.major, - &ddx_version.minor, - &ddx_version.patch, &sareaHandle)) { LogMessage(X_INFO, "AIGLX: Screen %d is not DRI2 capable\n", pScreen->myNum); @@ -539,24 +544,6 @@ __glXDRIscreenProbe(ScreenPtr pScreen) __glXInitExtensionEnableBits(screen->glx_enable_bits); - /* DRI protocol version. */ - dri_version.major = XF86DRI_MAJOR_VERSION; - dri_version.minor = XF86DRI_MINOR_VERSION; - dri_version.patch = XF86DRI_PATCH_VERSION; - - version = drmGetVersion(screen->fd); - if (version) { - drm_version.major = version->version_major; - drm_version.minor = version->version_minor; - drm_version.patch = version->version_patchlevel; - drmFreeVersion(version); - } - else { - drm_version.major = -1; - drm_version.minor = -1; - drm_version.patch = -1; - } - snprintf(filename, sizeof filename, "%s/%s_dri.so", dri_driver_path, driverName); @@ -577,12 +564,9 @@ __glXDRIscreenProbe(ScreenPtr pScreen) screen->driScreen.private = (*createNewScreen)(pScreen->myNum, &screen->driScreen, - &ddx_version, - &dri_version, - &drm_version, screen->fd, sareaHandle, - &interface_methods, + loader_extensions, &screen->base.fbconfigs); if (screen->driScreen.private == NULL) { diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c index 3bc533ede..9b4c18c61 100644 --- a/hw/xfree86/dri2/dri2.c +++ b/hw/xfree86/dri2/dri2.c @@ -58,9 +58,6 @@ typedef struct _DRI2Screen { void *sarea; unsigned int sareaSize; const char *driverName; - int ddxVersionMajor; - int ddxVersionMinor; - int ddxVersionPatch; __DRIEventBuffer *buffer; int locked; @@ -330,7 +327,6 @@ DRI2DestroyDrawable(ScreenPtr pScreen, DrawablePtr pDraw) Bool DRI2Connect(ScreenPtr pScreen, int *fd, const char **driverName, - int *ddxMajor, int *ddxMinor, int *ddxPatch, unsigned int *sareaHandle) { DRI2ScreenPtr ds = DRI2GetScreen(pScreen); @@ -340,9 +336,6 @@ DRI2Connect(ScreenPtr pScreen, int *fd, const char **driverName, *fd = ds->fd; *driverName = ds->driverName; - *ddxMajor = ds->ddxVersionMajor; - *ddxMinor = ds->ddxVersionMinor; - *ddxPatch = ds->ddxVersionPatch; *sareaHandle = ds->sareaBO.handle; return TRUE; @@ -406,9 +399,6 @@ DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info) ds->fd = info->fd; ds->driverName = info->driverName; - ds->ddxVersionMajor = info->ddxVersionMajor; - ds->ddxVersionMinor = info->ddxVersionMinor; - ds->ddxVersionPatch = info->ddxVersionPatch; ds->getPixmapHandle = info->getPixmapHandle; ds->beginClipNotify = info->beginClipNotify; diff --git a/hw/xfree86/dri2/dri2.h b/hw/xfree86/dri2/dri2.h index c687a93f6..c8482477e 100644 --- a/hw/xfree86/dri2/dri2.h +++ b/hw/xfree86/dri2/dri2.h @@ -43,7 +43,6 @@ typedef struct { int fd; size_t driverSareaSize; const char *driverName; - int ddxVersionMajor, ddxVersionMinor, ddxVersionPatch; DRI2GetPixmapHandleProcPtr getPixmapHandle; DRI2BeginClipNotifyProcPtr beginClipNotify; DRI2EndClipNotifyProcPtr endClipNotify; @@ -57,9 +56,6 @@ void DRI2CloseScreen(ScreenPtr pScreen); Bool DRI2Connect(ScreenPtr pScreen, int *fd, const char **driverName, - int *ddxMajor, - int *ddxMinor, - int *ddxPatch, unsigned int *sareaHandle); unsigned int DRI2GetPixmapHandle(PixmapPtr pPixmap, From 8ac19d16a030ec416e30d3650cf43e024ada167f Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Fri, 11 Jan 2008 21:58:21 -0500 Subject: [PATCH 007/149] Add several comments documenting our EDID failures. --- hw/xfree86/modes/xf86EdidModes.c | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/hw/xfree86/modes/xf86EdidModes.c b/hw/xfree86/modes/xf86EdidModes.c index a1bdb0b99..39328398f 100644 --- a/hw/xfree86/modes/xf86EdidModes.c +++ b/hw/xfree86/modes/xf86EdidModes.c @@ -264,7 +264,22 @@ DDCModesFromEstablished(int scrnIndex, struct established_timings *timing, } /* + * This is not really correct. Appendix B of the EDID 1.4 spec defines + * the right thing to do here. If the timing given here matches a mode + * defined in the VESA DMT standard, we _must_ use that. If the device + * supports CVT modes, then we should generate a CVT timing. If both + * of the above fail, use GTF. * + * There are some wrinkles here. EDID 1.1 and 1.0 sinks can't really + * "support" GTF, since it wasn't a standard yet; so if they ask for a + * timing in this section that isn't defined in DMT, returning a GTF mode + * may not actually be valid. EDID 1.3 sinks often report support for + * some CVT modes, but they are not required to support CVT timings for + * modes in the standard timing descriptor, so we should _not_ treat them + * as CVT-compliant (unless specified in an extension block I suppose). + * + * EDID 1.4 requires that all sink devices support both GTF and CVT timings + * for modes in this section, but does say that CVT is preferred. */ static DisplayModePtr DDCModesFromStandardTiming(int scrnIndex, struct std_timings *timing, @@ -405,7 +420,11 @@ DDCModesFromCVT(int scrnIndex, struct cvt_timings *t) /* - * + * This is only valid when the sink claims to be continuous-frequency + * but does not supply a detailed range descriptor. Such sinks are + * arguably broken. Currently the mode validation code isn't aware of + * this; the non-RANDR code even punts the decision of optional sync + * range checking to the driver. Loss. */ static void DDCGuessRangesFromModes(int scrnIndex, MonPtr Monitor, DisplayModePtr Modes) @@ -623,10 +642,12 @@ xf86DDCMonitorSet(int scrnIndex, MonPtr Monitor, xf86MonPtr DDC) Monitor->widthmm = 10 * DDC->features.hsize; Monitor->heightmm = 10 * DDC->features.vsize; - /* If this is a digital display, then we can use reduced blanking */ + /* + * If this is a digital display, then we can use reduced blanking. + * XXX This is a 1.3 heuristic. 1.4 explicitly defines rb support. + */ if (DDC->features.input_type) Monitor->reducedblanking = TRUE; - /* Allow the user to also enable this through config */ Modes = xf86DDCGetModes(scrnIndex, DDC); From fd41f46ac62033a724bd1f4612f19448a21c1224 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Fri, 11 Jan 2008 22:38:21 -0500 Subject: [PATCH 008/149] Allow xf86DuplicateMode() to work correctly on read-only modes. Before this it was meaningless to try to mark DisplayModeRec tables const, since the mode name would be emitted as a pointer to an anonymous string constant, and therefore would have to be fixed up by ld.so and so couldn't live in .rodata. With this change the standard mode lists can live in .rodata, and modes duplicated from them will have their names filled in on the fly. --- hw/xfree86/modes/xf86Modes.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/hw/xfree86/modes/xf86Modes.c b/hw/xfree86/modes/xf86Modes.c index 3d222cc73..d6aa61aaf 100644 --- a/hw/xfree86/modes/xf86Modes.c +++ b/hw/xfree86/modes/xf86Modes.c @@ -214,10 +214,8 @@ xf86DuplicateMode(DisplayModePtr pMode) *pNew = *pMode; pNew->next = NULL; pNew->prev = NULL; - if (pNew->name == NULL) { - xf86SetModeDefaultName(pMode); - } - pNew->name = xnfstrdup(pMode->name); + if (pNew->name == NULL) + xf86SetModeDefaultName(pNew); return pNew; } From 85617b56e5e00e7b8c7d8ce5b49af289056921a7 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Fri, 11 Jan 2008 22:55:37 -0500 Subject: [PATCH 009/149] Remove some #if 0 guarding code duplicated in xf86Modes.c --- hw/xfree86/common/xf86Mode.c | 140 ----------------------------------- 1 file changed, 140 deletions(-) diff --git a/hw/xfree86/common/xf86Mode.c b/hw/xfree86/common/xf86Mode.c index fb899a1e4..c1b0a5fc9 100644 --- a/hw/xfree86/common/xf86Mode.c +++ b/hw/xfree86/common/xf86Mode.c @@ -636,146 +636,6 @@ xf86LookupMode(ScrnInfoPtr scrp, DisplayModePtr modep, return MODE_OK; } - -#if 0 -/* - * xf86SetModeCrtc - * - * Initialises the Crtc parameters for a mode. The initialisation includes - * adjustments for interlaced and double scan modes. - */ -_X_EXPORT void -xf86SetModeCrtc(DisplayModePtr p, int adjustFlags) -{ - if ((p == NULL) || ((p->type & M_T_CRTC_C) == M_T_BUILTIN)) - return; - - p->CrtcHDisplay = p->HDisplay; - p->CrtcHSyncStart = p->HSyncStart; - p->CrtcHSyncEnd = p->HSyncEnd; - p->CrtcHTotal = p->HTotal; - p->CrtcHSkew = p->HSkew; - p->CrtcVDisplay = p->VDisplay; - p->CrtcVSyncStart = p->VSyncStart; - p->CrtcVSyncEnd = p->VSyncEnd; - p->CrtcVTotal = p->VTotal; - if (p->Flags & V_INTERLACE) { - if (adjustFlags & INTERLACE_HALVE_V) { - p->CrtcVDisplay /= 2; - p->CrtcVSyncStart /= 2; - p->CrtcVSyncEnd /= 2; - p->CrtcVTotal /= 2; - } - /* Force interlaced modes to have an odd VTotal */ - /* maybe we should only do this when INTERLACE_HALVE_V is set? */ - p->CrtcVTotal |= 1; - } - - if (p->Flags & V_DBLSCAN) { - p->CrtcVDisplay *= 2; - p->CrtcVSyncStart *= 2; - p->CrtcVSyncEnd *= 2; - p->CrtcVTotal *= 2; - } - if (p->VScan > 1) { - p->CrtcVDisplay *= p->VScan; - p->CrtcVSyncStart *= p->VScan; - p->CrtcVSyncEnd *= p->VScan; - p->CrtcVTotal *= p->VScan; - } - p->CrtcVBlankStart = min(p->CrtcVSyncStart, p->CrtcVDisplay); - p->CrtcVBlankEnd = max(p->CrtcVSyncEnd, p->CrtcVTotal); - p->CrtcHBlankStart = min(p->CrtcHSyncStart, p->CrtcHDisplay); - p->CrtcHBlankEnd = max(p->CrtcHSyncEnd, p->CrtcHTotal); - - p->CrtcHAdjusted = FALSE; - p->CrtcVAdjusted = FALSE; -} -#endif - -#if 0 -/** - * Allocates and returns a copy of pMode, including pointers within pMode. - */ -_X_EXPORT DisplayModePtr -xf86DuplicateMode(DisplayModePtr pMode) -{ - DisplayModePtr pNew; - - pNew = xnfalloc(sizeof(DisplayModeRec)); - *pNew = *pMode; - pNew->next = NULL; - pNew->prev = NULL; - if (pNew->name == NULL) { - xf86SetModeDefaultName(pMode); - } else { - pNew->name = xnfstrdup(pMode->name); - } - - return pNew; -} - -/** - * Duplicates every mode in the given list and returns a pointer to the first - * mode. - * - * \param modeList doubly-linked mode list - */ -_X_EXPORT DisplayModePtr -xf86DuplicateModes(ScrnInfoPtr pScrn, DisplayModePtr modeList) -{ - DisplayModePtr first = NULL, last = NULL; - DisplayModePtr mode; - - for (mode = modeList; mode != NULL; mode = mode->next) { - DisplayModePtr new; - - new = xf86DuplicateMode(mode); - - /* Insert pNew into modeList */ - if (last) { - last->next = new; - new->prev = last; - } else { - first = new; - new->prev = NULL; - } - new->next = NULL; - last = new; - } - - return first; -} - -/** - * Returns true if the given modes should program to the same timings. - * - * This doesn't use Crtc values, as it might be used on ModeRecs without the - * Crtc values set. So, it's assumed that the other numbers are enough. - */ -_X_EXPORT Bool -xf86ModesEqual(DisplayModePtr pMode1, DisplayModePtr pMode2) -{ - if (pMode1->Clock == pMode2->Clock && - pMode1->HDisplay == pMode2->HDisplay && - pMode1->HSyncStart == pMode2->HSyncStart && - pMode1->HSyncEnd == pMode2->HSyncEnd && - pMode1->HTotal == pMode2->HTotal && - pMode1->HSkew == pMode2->HSkew && - pMode1->VDisplay == pMode2->VDisplay && - pMode1->VSyncStart == pMode2->VSyncStart && - pMode1->VSyncEnd == pMode2->VSyncEnd && - pMode1->VTotal == pMode2->VTotal && - pMode1->VScan == pMode2->VScan && - pMode1->Flags == pMode2->Flags) - { - return TRUE; - } else { - return FALSE; - } -} -#endif - /* * xf86CheckModeForMonitor * From 6828d8fc2b464e0755f46e3fbdeb07be0c38b620 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Fri, 11 Jan 2008 22:57:42 -0500 Subject: [PATCH 010/149] Clean up DisplayModeRec handling in many places. Use xf86DuplicateMode() instead of rolling our own, and change malloc+memset to calloc. --- hw/xfree86/common/xf86Config.c | 8 ++------ hw/xfree86/common/xf86cvt.c | 4 +--- hw/xfree86/fbdevhw/fbdevhw.c | 7 ++----- hw/xfree86/modes/xf86EdidModes.c | 3 +-- hw/xfree86/modes/xf86cvt.c | 4 +--- 5 files changed, 7 insertions(+), 19 deletions(-) diff --git a/hw/xfree86/common/xf86Config.c b/hw/xfree86/common/xf86Config.c index 605c6b347..de3edf638 100644 --- a/hw/xfree86/common/xf86Config.c +++ b/hw/xfree86/common/xf86Config.c @@ -2088,8 +2088,7 @@ configMonitor(MonPtr monitorp, XF86ConfMonitorPtr conf_monitor) */ cmodep = conf_monitor->mon_modeline_lst; while( cmodep ) { - mode = xnfalloc(sizeof(DisplayModeRec)); - memset(mode,'\0',sizeof(DisplayModeRec)); + mode = xnfcalloc(1, sizeof(DisplayModeRec)); mode->type = 0; mode->Clock = cmodep->ml_clock; mode->HDisplay = cmodep->ml_hdisplay; @@ -2426,10 +2425,7 @@ addDefaultModes(MonPtr monitorp) if ( ! modeIsPresent(xf86DefaultModes[i].name,monitorp) ) do { - mode = xnfalloc(sizeof(DisplayModeRec)); - memcpy(mode,&xf86DefaultModes[i],sizeof(DisplayModeRec)); - if (xf86DefaultModes[i].name) - mode->name = xnfstrdup(xf86DefaultModes[i].name); + mode = xf86DuplicateMode(&xf86DefaultModes[i]); if( last ) { mode->prev = last; last->next = mode; diff --git a/hw/xfree86/common/xf86cvt.c b/hw/xfree86/common/xf86cvt.c index dfb6e71e4..f8185a38c 100644 --- a/hw/xfree86/common/xf86cvt.c +++ b/hw/xfree86/common/xf86cvt.c @@ -56,7 +56,7 @@ _X_EXPORT DisplayModePtr xf86CVTMode(int HDisplay, int VDisplay, float VRefresh, Bool Reduced, Bool Interlaced) { - DisplayModeRec *Mode = xnfalloc(sizeof(DisplayModeRec)); + DisplayModeRec *Mode = xnfcalloc(1, sizeof(DisplayModeRec)); /* 1) top/bottom margin size (% of height) - default: 1.8 */ #define CVT_MARGIN_PERCENTAGE 1.8 @@ -79,8 +79,6 @@ xf86CVTMode(int HDisplay, int VDisplay, float VRefresh, Bool Reduced, int VDisplayRnd, VMargin, VSync; float Interlace; /* Please rename this */ - memset(Mode, 0, sizeof(DisplayModeRec)); - /* CVT default is 60.0Hz */ if (!VRefresh) VRefresh = 60.0; diff --git a/hw/xfree86/fbdevhw/fbdevhw.c b/hw/xfree86/fbdevhw/fbdevhw.c index 13be7858f..a1f67486f 100644 --- a/hw/xfree86/fbdevhw/fbdevhw.c +++ b/hw/xfree86/fbdevhw/fbdevhw.c @@ -625,14 +625,11 @@ fbdevHWSetVideoModes(ScrnInfoPtr pScrn) pScrn->virtualY = mode->VDisplay; if (NULL == pScrn->modes) { - pScrn->modes = xnfalloc(sizeof(DisplayModeRec)); - this = pScrn->modes; - memcpy(this,mode,sizeof(DisplayModeRec)); + this = pScrn->modes = xf86DuplicateMode(mode); this->next = this; this->prev = this; } else { - this = xnfalloc(sizeof(DisplayModeRec)); - memcpy(this,mode,sizeof(DisplayModeRec)); + this = xf86DuplicateMode(mode); this->next = pScrn->modes; this->prev = last; last->next = this; diff --git a/hw/xfree86/modes/xf86EdidModes.c b/hw/xfree86/modes/xf86EdidModes.c index 39328398f..47b984d0f 100644 --- a/hw/xfree86/modes/xf86EdidModes.c +++ b/hw/xfree86/modes/xf86EdidModes.c @@ -336,8 +336,7 @@ DDCModeFromDetailedTiming(int scrnIndex, struct detailed_timings *timing, " sync.\n", __func__, timing->h_active, timing->v_active); } - Mode = xnfalloc(sizeof(DisplayModeRec)); - memset(Mode, 0, sizeof(DisplayModeRec)); + Mode = xnfcalloc(1, sizeof(DisplayModeRec)); Mode->type = M_T_DRIVER; if (preferred) diff --git a/hw/xfree86/modes/xf86cvt.c b/hw/xfree86/modes/xf86cvt.c index 69ccc4259..68a94627c 100644 --- a/hw/xfree86/modes/xf86cvt.c +++ b/hw/xfree86/modes/xf86cvt.c @@ -72,7 +72,7 @@ _X_EXPORT DisplayModePtr xf86CVTMode(int HDisplay, int VDisplay, float VRefresh, Bool Reduced, Bool Interlaced) { - DisplayModeRec *Mode = xnfalloc(sizeof(DisplayModeRec)); + DisplayModeRec *Mode = xnfcalloc(1, sizeof(DisplayModeRec)); /* 1) top/bottom margin size (% of height) - default: 1.8 */ #define CVT_MARGIN_PERCENTAGE 1.8 @@ -95,8 +95,6 @@ xf86CVTMode(int HDisplay, int VDisplay, float VRefresh, Bool Reduced, int VDisplayRnd, VMargin, VSync; float Interlace; /* Please rename this */ - memset(Mode, 0, sizeof(DisplayModeRec)); - /* CVT default is 60.0Hz */ if (!VRefresh) VRefresh = 60.0; From e65e51a99b17a0510782775f010e9820ca567fcb Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Fri, 11 Jan 2008 23:19:20 -0500 Subject: [PATCH 011/149] Constify the built-in mode tables. --- hw/xfree86/common/modeline2c.awk | 16 ++++++------- hw/xfree86/common/xf86Priv.h | 2 +- hw/xfree86/modes/xf86EdidModes.c | 40 ++++++++++++++++---------------- 3 files changed, 28 insertions(+), 30 deletions(-) diff --git a/hw/xfree86/common/modeline2c.awk b/hw/xfree86/common/modeline2c.awk index d4b9649c8..b9ad3cdf9 100644 --- a/hw/xfree86/common/modeline2c.awk +++ b/hw/xfree86/common/modeline2c.awk @@ -44,8 +44,6 @@ BEGIN { flagsdict["-hsync +vsync interlace"] = "V_NHSYNC | V_PVSYNC | V_INTERLACE" flagsdict["-hsync -vsync interlace"] = "V_NHSYNC | V_NVSYNC | V_INTERLACE" - print "/* $" "XFree86$ */" - print print "/* THIS FILE IS AUTOMATICALLY GENERATED -- DO NOT EDIT -- LOOK at" print " * modeline2c.awk */" print "" @@ -68,12 +66,12 @@ BEGIN { print "" print "#include \"globals.h\"" print "" - print "#define MODEPREFIX(name) NULL, NULL, name, MODE_OK, M_T_DEFAULT" - print "#define MODESUFFIX 0,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0,FALSE,FALSE,0,NULL,0,0.0,0.0" + print "#define MODEPREFIX NULL, NULL, NULL, MODE_OK, M_T_DEFAULT" + print "#define MODESUFFIX 0,0, 0,0,0,0,0,0,0, 0,0,0,0,0,0,FALSE,FALSE,0,NULL,0,0.0,0.0" print "" - print "DisplayModeRec xf86DefaultModes [] = {" + print "const DisplayModeRec xf86DefaultModes [] = {" - modeline = "\t{MODEPREFIX(\"%dx%d\"),%d, %d,%d,%d,%d,0, %d,%d,%d,%d,0, %s, MODESUFFIX},\n" + modeline = "\t{MODEPREFIX,%d, %d,%d,%d,%d,0, %d,%d,%d,%d,0, %s, MODESUFFIX},\n" modeline_data = "^[a-zA-Z]+[ \t]+[^ \t]+[ \t0-9.]+" } @@ -81,10 +79,10 @@ BEGIN { flags = $0 gsub(modeline_data, "", flags) flags = tolower(flags) - printf(modeline, $4, $8, $3 * 1000, $4, $5, $6, $7, + printf(modeline, $3 * 1000, $4, $5, $6, $7, $8, $9, $10, $11, flagsdict[flags]) # Half-width double scanned modes - printf(modeline, $4/2, $8/2, $3 * 500, $4/2, $5/2, $6/2, $7/2, + printf(modeline, $3 * 500, $4/2, $5/2, $6/2, $7/2, $8/2, $9/2, $10/2, $11/2, flagsdict[flags] " | V_DBLSCAN") } @@ -93,5 +91,5 @@ BEGIN { } END { - printf("\t{MODEPREFIX(NULL),0,0,0,0,0,0,0,0,0,0,0,0,MODESUFFIX}\n};\n") + printf("\t{MODEPREFIX,0,0,0,0,0,0,0,0,0,0,0,0,MODESUFFIX}\n};\n") } diff --git a/hw/xfree86/common/xf86Priv.h b/hw/xfree86/common/xf86Priv.h index fb9ecaea8..dd8b5a022 100644 --- a/hw/xfree86/common/xf86Priv.h +++ b/hw/xfree86/common/xf86Priv.h @@ -153,7 +153,7 @@ Bool xf86PathIsSafe(const char *path); /* xf86DefaultModes */ -extern DisplayModeRec xf86DefaultModes []; +extern const DisplayModeRec xf86DefaultModes[]; /* xf86DoProbe.c */ void DoProbe(void); diff --git a/hw/xfree86/modes/xf86EdidModes.c b/hw/xfree86/modes/xf86EdidModes.c index 47b984d0f..467f03251 100644 --- a/hw/xfree86/modes/xf86EdidModes.c +++ b/hw/xfree86/modes/xf86EdidModes.c @@ -221,27 +221,27 @@ static const ddc_quirk_map_t ddc_quirks[] = { * TODO: * - for those with access to the VESA DMT standard; review please. */ -#define MODEPREFIX(name) NULL, NULL, name, 0,M_T_DRIVER -#define MODESUFFIX 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,FALSE,FALSE,0,NULL,0,0.0,0.0 +#define MODEPREFIX NULL, NULL, NULL, 0, M_T_DRIVER +#define MODESUFFIX 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,FALSE,FALSE,0,NULL,0,0.0,0.0 -static DisplayModeRec DDCEstablishedModes[17] = { - { MODEPREFIX("800x600"), 40000, 800, 840, 968, 1056, 0, 600, 601, 605, 628, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600@60Hz */ - { MODEPREFIX("800x600"), 36000, 800, 824, 896, 1024, 0, 600, 601, 603, 625, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600@56Hz */ - { MODEPREFIX("640x480"), 31500, 640, 656, 720, 840, 0, 480, 481, 484, 500, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480@75Hz */ - { MODEPREFIX("640x480"), 31500, 640, 664, 704, 832, 0, 480, 489, 491, 520, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480@72Hz */ - { MODEPREFIX("640x480"), 30240, 640, 704, 768, 864, 0, 480, 483, 486, 525, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480@67Hz */ - { MODEPREFIX("640x480"), 25200, 640, 656, 752, 800, 0, 480, 490, 492, 525, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480@60Hz */ - { MODEPREFIX("720x400"), 35500, 720, 738, 846, 900, 0, 400, 421, 423, 449, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 720x400@88Hz */ - { MODEPREFIX("720x400"), 28320, 720, 738, 846, 900, 0, 400, 412, 414, 449, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 720x400@70Hz */ - { MODEPREFIX("1280x1024"), 135000, 1280, 1296, 1440, 1688, 0, 1024, 1025, 1028, 1066, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1280x1024@75Hz */ - { MODEPREFIX("1024x768"), 78800, 1024, 1040, 1136, 1312, 0, 768, 769, 772, 800, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1024x768@75Hz */ - { MODEPREFIX("1024x768"), 75000, 1024, 1048, 1184, 1328, 0, 768, 771, 777, 806, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 1024x768@70Hz */ - { MODEPREFIX("1024x768"), 65000, 1024, 1048, 1184, 1344, 0, 768, 771, 777, 806, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 1024x768@60Hz */ - { MODEPREFIX("1024x768"), 44900, 1024, 1032, 1208, 1264, 0, 768, 768, 776, 817, 0, V_PHSYNC | V_PVSYNC | V_INTERLACE, MODESUFFIX }, /* 1024x768@43Hz */ - { MODEPREFIX("832x624"), 57284, 832, 864, 928, 1152, 0, 624, 625, 628, 667, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 832x624@75Hz */ - { MODEPREFIX("800x600"), 49500, 800, 816, 896, 1056, 0, 600, 601, 604, 625, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600@75Hz */ - { MODEPREFIX("800x600"), 50000, 800, 856, 976, 1040, 0, 600, 637, 643, 666, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600@72Hz */ - { MODEPREFIX("1152x864"), 108000, 1152, 1216, 1344, 1600, 0, 864, 865, 868, 900, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1152x864@75Hz */ +static const DisplayModeRec DDCEstablishedModes[17] = { + { MODEPREFIX, 40000, 800, 840, 968, 1056, 0, 600, 601, 605, 628, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600@60Hz */ + { MODEPREFIX, 36000, 800, 824, 896, 1024, 0, 600, 601, 603, 625, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600@56Hz */ + { MODEPREFIX, 31500, 640, 656, 720, 840, 0, 480, 481, 484, 500, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480@75Hz */ + { MODEPREFIX, 31500, 640, 664, 704, 832, 0, 480, 489, 491, 520, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480@72Hz */ + { MODEPREFIX, 30240, 640, 704, 768, 864, 0, 480, 483, 486, 525, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480@67Hz */ + { MODEPREFIX, 25200, 640, 656, 752, 800, 0, 480, 490, 492, 525, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480@60Hz */ + { MODEPREFIX, 35500, 720, 738, 846, 900, 0, 400, 421, 423, 449, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 720x400@88Hz */ + { MODEPREFIX, 28320, 720, 738, 846, 900, 0, 400, 412, 414, 449, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 720x400@70Hz */ + { MODEPREFIX, 135000, 1280, 1296, 1440, 1688, 0, 1024, 1025, 1028, 1066, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1280x1024@75Hz */ + { MODEPREFIX, 78800, 1024, 1040, 1136, 1312, 0, 768, 769, 772, 800, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1024x768@75Hz */ + { MODEPREFIX, 75000, 1024, 1048, 1184, 1328, 0, 768, 771, 777, 806, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 1024x768@70Hz */ + { MODEPREFIX, 65000, 1024, 1048, 1184, 1344, 0, 768, 771, 777, 806, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 1024x768@60Hz */ + { MODEPREFIX, 44900, 1024, 1032, 1208, 1264, 0, 768, 768, 776, 817, 0, V_PHSYNC | V_PVSYNC | V_INTERLACE, MODESUFFIX }, /* 1024x768@43Hz */ + { MODEPREFIX, 57284, 832, 864, 928, 1152, 0, 624, 625, 628, 667, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 832x624@75Hz */ + { MODEPREFIX, 49500, 800, 816, 896, 1056, 0, 600, 601, 604, 625, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600@75Hz */ + { MODEPREFIX, 50000, 800, 856, 976, 1040, 0, 600, 637, 643, 666, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600@72Hz */ + { MODEPREFIX, 108000, 1152, 1216, 1344, 1600, 0, 864, 865, 868, 900, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1152x864@75Hz */ }; static DisplayModePtr From 4cb4817c1072e1d31333db47d95f71d08bf0d1dc Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Fri, 11 Jan 2008 23:38:48 -0500 Subject: [PATCH 012/149] Remove the duplicate copy of xf86cvt.c --- hw/xfree86/common/Makefile.am | 2 +- hw/xfree86/common/xf86cvt.c | 290 ------------------------------- hw/xfree86/modes/xf86cvt.c | 5 - hw/xfree86/utils/cvt/Makefile.am | 6 +- 4 files changed, 5 insertions(+), 298 deletions(-) delete mode 100644 hw/xfree86/common/xf86cvt.c diff --git a/hw/xfree86/common/Makefile.am b/hw/xfree86/common/Makefile.am index 4f0a2d6b3..0f44075ba 100644 --- a/hw/xfree86/common/Makefile.am +++ b/hw/xfree86/common/Makefile.am @@ -30,7 +30,7 @@ BUILT_SOURCES = xf86DefModeSet.c AM_LDFLAGS = -r libcommon_la_SOURCES = xf86Configure.c xf86Bus.c xf86Config.c \ - xf86Cursor.c xf86cvt.c xf86DGA.c xf86DPMS.c \ + xf86Cursor.c xf86DGA.c xf86DPMS.c \ xf86DoProbe.c xf86Events.c \ xf86Globals.c xf86AutoConfig.c \ xf86MiscExt.c xf86Option.c \ diff --git a/hw/xfree86/common/xf86cvt.c b/hw/xfree86/common/xf86cvt.c deleted file mode 100644 index f8185a38c..000000000 --- a/hw/xfree86/common/xf86cvt.c +++ /dev/null @@ -1,290 +0,0 @@ -/* - * Copyright 2005-2006 Luc Verhaegen. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -/* - * The reason for having this function in a file of its own is - * so that ../utils/cvt/cvt can link to it, and that xf86CVTMode - * code is shared directly. - */ - -#include "xf86.h" - -/* - * Generate a CVT standard mode from HDisplay, VDisplay and VRefresh. - * - * These calculations are stolen from the CVT calculation spreadsheet written - * by Graham Loveridge. He seems to be claiming no copyright and there seems to - * be no license attached to this. He apparently just wants to see his name - * mentioned. - * - * This file can be found at http://www.vesa.org/Public/CVT/CVTd6r1.xls - * - * Comments and structure corresponds to the comments and structure of the xls. - * This should ease importing of future changes to the standard (not very - * likely though). - * - * About margins; i'm sure that they are to be the bit between HDisplay and - * HBlankStart, HBlankEnd and HTotal, VDisplay and VBlankStart, VBlankEnd and - * VTotal, where the overscan colour is shown. FB seems to call _all_ blanking - * outside sync "margin" for some reason. Since we prefer seeing proper - * blanking instead of the overscan colour, and since the Crtc* values will - * probably get altered after us, we will disable margins altogether. With - * these calculations, Margins will plainly expand H/VDisplay, and we don't - * want that. -- libv - * - */ -_X_EXPORT DisplayModePtr -xf86CVTMode(int HDisplay, int VDisplay, float VRefresh, Bool Reduced, - Bool Interlaced) -{ - DisplayModeRec *Mode = xnfcalloc(1, sizeof(DisplayModeRec)); - - /* 1) top/bottom margin size (% of height) - default: 1.8 */ -#define CVT_MARGIN_PERCENTAGE 1.8 - - /* 2) character cell horizontal granularity (pixels) - default 8 */ -#define CVT_H_GRANULARITY 8 - - /* 4) Minimum vertical porch (lines) - default 3 */ -#define CVT_MIN_V_PORCH 3 - - /* 4) Minimum number of vertical back porch lines - default 6 */ -#define CVT_MIN_V_BPORCH 6 - - /* Pixel Clock step (kHz) */ -#define CVT_CLOCK_STEP 250 - - Bool Margins = FALSE; - float VFieldRate, HPeriod; - int HDisplayRnd, HMargin; - int VDisplayRnd, VMargin, VSync; - float Interlace; /* Please rename this */ - - /* CVT default is 60.0Hz */ - if (!VRefresh) - VRefresh = 60.0; - - /* 1. Required field rate */ - if (Interlaced) - VFieldRate = VRefresh * 2; - else - VFieldRate = VRefresh; - - /* 2. Horizontal pixels */ - HDisplayRnd = HDisplay - (HDisplay % CVT_H_GRANULARITY); - - /* 3. Determine left and right borders */ - if (Margins) { - /* right margin is actually exactly the same as left */ - HMargin = (((float) HDisplayRnd) * CVT_MARGIN_PERCENTAGE / 100.0); - HMargin -= HMargin % CVT_H_GRANULARITY; - } else - HMargin = 0; - - /* 4. Find total active pixels */ - Mode->HDisplay = HDisplayRnd + 2*HMargin; - - /* 5. Find number of lines per field */ - if (Interlaced) - VDisplayRnd = VDisplay / 2; - else - VDisplayRnd = VDisplay; - - /* 6. Find top and bottom margins */ - /* nope. */ - if (Margins) - /* top and bottom margins are equal again. */ - VMargin = (((float) VDisplayRnd) * CVT_MARGIN_PERCENTAGE / 100.0); - else - VMargin = 0; - - Mode->VDisplay = VDisplay + 2*VMargin; - - /* 7. Interlace */ - if (Interlaced) - Interlace = 0.5; - else - Interlace = 0.0; - - /* Determine VSync Width from aspect ratio */ - if (!(VDisplay % 3) && ((VDisplay * 4 / 3) == HDisplay)) - VSync = 4; - else if (!(VDisplay % 9) && ((VDisplay * 16 / 9) == HDisplay)) - VSync = 5; - else if (!(VDisplay % 10) && ((VDisplay * 16 / 10) == HDisplay)) - VSync = 6; - else if (!(VDisplay % 4) && ((VDisplay * 5 / 4) == HDisplay)) - VSync = 7; - else if (!(VDisplay % 9) && ((VDisplay * 15 / 9) == HDisplay)) - VSync = 7; - else /* Custom */ - VSync = 10; - - if (!Reduced) { /* simplified GTF calculation */ - - /* 4) Minimum time of vertical sync + back porch interval (µs) - * default 550.0 */ -#define CVT_MIN_VSYNC_BP 550.0 - - /* 3) Nominal HSync width (% of line period) - default 8 */ -#define CVT_HSYNC_PERCENTAGE 8 - - float HBlankPercentage; - int VSyncAndBackPorch, VBackPorch; - int HBlank; - - /* 8. Estimated Horizontal period */ - HPeriod = ((float) (1000000.0 / VFieldRate - CVT_MIN_VSYNC_BP)) / - (VDisplayRnd + 2 * VMargin + CVT_MIN_V_PORCH + Interlace); - - /* 9. Find number of lines in sync + backporch */ - if (((int)(CVT_MIN_VSYNC_BP / HPeriod) + 1) < (VSync + CVT_MIN_V_PORCH)) - VSyncAndBackPorch = VSync + CVT_MIN_V_PORCH; - else - VSyncAndBackPorch = (int)(CVT_MIN_VSYNC_BP / HPeriod) + 1; - - /* 10. Find number of lines in back porch */ - VBackPorch = VSyncAndBackPorch - VSync; - - /* 11. Find total number of lines in vertical field */ - Mode->VTotal = VDisplayRnd + 2 * VMargin + VSyncAndBackPorch + Interlace - + CVT_MIN_V_PORCH; - - /* 5) Definition of Horizontal blanking time limitation */ - /* Gradient (%/kHz) - default 600 */ -#define CVT_M_FACTOR 600 - - /* Offset (%) - default 40 */ -#define CVT_C_FACTOR 40 - - /* Blanking time scaling factor - default 128 */ -#define CVT_K_FACTOR 128 - - /* Scaling factor weighting - default 20 */ -#define CVT_J_FACTOR 20 - -#define CVT_M_PRIME CVT_M_FACTOR * CVT_K_FACTOR / 256 -#define CVT_C_PRIME (CVT_C_FACTOR - CVT_J_FACTOR) * CVT_K_FACTOR / 256 + \ - CVT_J_FACTOR - - /* 12. Find ideal blanking duty cycle from formula */ - HBlankPercentage = CVT_C_PRIME - CVT_M_PRIME * HPeriod/1000.0; - - /* 13. Blanking time */ - if (HBlankPercentage < 20) - HBlankPercentage = 20; - - HBlank = Mode->HDisplay * HBlankPercentage/(100.0 - HBlankPercentage); - HBlank -= HBlank % (2*CVT_H_GRANULARITY); - - /* 14. Find total number of pixels in a line. */ - Mode->HTotal = Mode->HDisplay + HBlank; - - /* Fill in HSync values */ - Mode->HSyncEnd = Mode->HDisplay + HBlank / 2; - - Mode->HSyncStart = Mode->HSyncEnd - - (Mode->HTotal * CVT_HSYNC_PERCENTAGE) / 100; - Mode->HSyncStart += CVT_H_GRANULARITY - - Mode->HSyncStart % CVT_H_GRANULARITY; - - /* Fill in VSync values */ - Mode->VSyncStart = Mode->VDisplay + CVT_MIN_V_PORCH; - Mode->VSyncEnd = Mode->VSyncStart + VSync; - - } else { /* Reduced blanking */ - /* Minimum vertical blanking interval time (µs) - default 460 */ -#define CVT_RB_MIN_VBLANK 460.0 - - /* Fixed number of clocks for horizontal sync */ -#define CVT_RB_H_SYNC 32.0 - - /* Fixed number of clocks for horizontal blanking */ -#define CVT_RB_H_BLANK 160.0 - - /* Fixed number of lines for vertical front porch - default 3 */ -#define CVT_RB_VFPORCH 3 - - int VBILines; - - /* 8. Estimate Horizontal period. */ - HPeriod = ((float) (1000000.0 / VFieldRate - CVT_RB_MIN_VBLANK)) / - (VDisplayRnd + 2*VMargin); - - /* 9. Find number of lines in vertical blanking */ - VBILines = ((float) CVT_RB_MIN_VBLANK) / HPeriod + 1; - - /* 10. Check if vertical blanking is sufficient */ - if (VBILines < (CVT_RB_VFPORCH + VSync + CVT_MIN_V_BPORCH)) - VBILines = CVT_RB_VFPORCH + VSync + CVT_MIN_V_BPORCH; - - /* 11. Find total number of lines in vertical field */ - Mode->VTotal = VDisplayRnd + 2 * VMargin + Interlace + VBILines; - - /* 12. Find total number of pixels in a line */ - Mode->HTotal = Mode->HDisplay + CVT_RB_H_BLANK; - - /* Fill in HSync values */ - Mode->HSyncEnd = Mode->HDisplay + CVT_RB_H_BLANK / 2; - Mode->HSyncStart = Mode->HSyncEnd - CVT_RB_H_SYNC; - - /* Fill in VSync values */ - Mode->VSyncStart = Mode->VDisplay + CVT_RB_VFPORCH; - Mode->VSyncEnd = Mode->VSyncStart + VSync; - } - - /* 15/13. Find pixel clock frequency (kHz for xf86) */ - Mode->Clock = Mode->HTotal * 1000.0 / HPeriod; - Mode->Clock -= Mode->Clock % CVT_CLOCK_STEP; - - /* 16/14. Find actual Horizontal Frequency (kHz) */ - Mode->HSync = ((float) Mode->Clock) / ((float) Mode->HTotal); - - /* 17/15. Find actual Field rate */ - Mode->VRefresh = (1000.0 * ((float) Mode->Clock)) / - ((float) (Mode->HTotal * Mode->VTotal)); - - /* 18/16. Find actual vertical frame frequency */ - /* ignore - just set the mode flag for interlaced */ - if (Interlaced) - Mode->VTotal *= 2; - - { - char Name[256]; - Name[0] = 0; - - snprintf(Name, 256, "%dx%d", HDisplay, VDisplay); - - Mode->name = xnfalloc(strlen(Name) + 1); - memcpy(Mode->name, Name, strlen(Name) + 1); - } - - if (Reduced) - Mode->Flags |= V_PHSYNC | V_NVSYNC; - else - Mode->Flags |= V_NHSYNC | V_PVSYNC; - - if (Interlaced) - Mode->Flags |= V_INTERLACE; - - return Mode; -} diff --git a/hw/xfree86/modes/xf86cvt.c b/hw/xfree86/modes/xf86cvt.c index 68a94627c..e9c74aa62 100644 --- a/hw/xfree86/modes/xf86cvt.c +++ b/hw/xfree86/modes/xf86cvt.c @@ -20,11 +20,6 @@ * OTHER DEALINGS IN THE SOFTWARE. */ -/** - * @file This is a copy of xf86cvt.c from the X Server, for compatibility with - * old servers (pre-1.2). - */ - /* * The reason for having this function in a file of its own is * so that ../utils/cvt/cvt can link to it, and that xf86CVTMode diff --git a/hw/xfree86/utils/cvt/Makefile.am b/hw/xfree86/utils/cvt/Makefile.am index 365c6cb88..4db175fbd 100644 --- a/hw/xfree86/utils/cvt/Makefile.am +++ b/hw/xfree86/utils/cvt/Makefile.am @@ -28,11 +28,13 @@ bin_PROGRAMS = cvt -INCLUDES = $(XORG_INCS) +INCLUDES = $(XORG_INCS) \ + -I$(top_srcdir)/hw/xfree86/ddc \ + -I$(top_srcdir)/hw/xfree86/parser DUMMYLIB_SRCDIR = $(XFREE86_SRCDIR)/dummylib # gah -cvt_SOURCES = cvt.c $(top_srcdir)/hw/xfree86/common/xf86cvt.c +cvt_SOURCES = cvt.c $(top_srcdir)/hw/xfree86/modes/xf86cvt.c cvt_CFLAGS = $(DIX_CFLAGS) $(XORG_CFLAGS) cvt_LDADD = $(top_builddir)/hw/xfree86/dummylib/libdummy-nonserver.a From ca5625b911e65fdfd410247b3eff57fedcfc1f79 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Sat, 12 Jan 2008 00:08:00 -0500 Subject: [PATCH 013/149] Add xf86GTFMode(). This should probably be shared like xf86CVTMode(). --- hw/xfree86/loader/xf86sym.c | 1 + hw/xfree86/modes/Makefile.am | 1 + hw/xfree86/modes/xf86Modes.h | 1 + hw/xfree86/modes/xf86gtf.c | 384 +++++++++++++++++++++++++++++++++++ 4 files changed, 387 insertions(+) create mode 100644 hw/xfree86/modes/xf86gtf.c diff --git a/hw/xfree86/loader/xf86sym.c b/hw/xfree86/loader/xf86sym.c index 754e9c06b..50a19b916 100644 --- a/hw/xfree86/loader/xf86sym.c +++ b/hw/xfree86/loader/xf86sym.c @@ -949,6 +949,7 @@ _X_HIDDEN void *xfree86LookupTab[] = { SYMFUNC(xf86CrtcSetSizeRange) SYMFUNC(xf86CrtcScreenInit) SYMFUNC(xf86CVTMode) + SYMFUNC(xf86GTFMode) SYMFUNC(xf86DisableUnusedFunctions) SYMFUNC(xf86DPMSSet) SYMFUNC(xf86DuplicateMode) diff --git a/hw/xfree86/modes/Makefile.am b/hw/xfree86/modes/Makefile.am index 6ee85757a..331e4061c 100644 --- a/hw/xfree86/modes/Makefile.am +++ b/hw/xfree86/modes/Makefile.am @@ -5,6 +5,7 @@ libxf86modes_a_SOURCES = \ xf86Crtc.h \ xf86Cursors.c \ xf86cvt.c \ + xf86gtf.c \ xf86DiDGA.c \ xf86EdidModes.c \ xf86Modes.c \ diff --git a/hw/xfree86/modes/xf86Modes.h b/hw/xfree86/modes/xf86Modes.h index 9ad5ee653..5d49c9314 100644 --- a/hw/xfree86/modes/xf86Modes.h +++ b/hw/xfree86/modes/xf86Modes.h @@ -62,6 +62,7 @@ DisplayModePtr xf86ModesAdd(DisplayModePtr modes, DisplayModePtr new); DisplayModePtr xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC); DisplayModePtr xf86CVTMode(int HDisplay, int VDisplay, float VRefresh, Bool Reduced, Bool Interlaced); +DisplayModePtr xf86GTFMode(int h_pixels, int v_lines, float freq, int interlaced, int margins); void xf86ValidateModesFlags(ScrnInfoPtr pScrn, DisplayModePtr modeList, diff --git a/hw/xfree86/modes/xf86gtf.c b/hw/xfree86/modes/xf86gtf.c new file mode 100644 index 000000000..acbac83b6 --- /dev/null +++ b/hw/xfree86/modes/xf86gtf.c @@ -0,0 +1,384 @@ +/* + * gtf.c Generate mode timings using the GTF Timing Standard + * + * gcc gtf.c -o gtf -lm -Wall + * + * Copyright (c) 2001, Andy Ritger aritger@nvidia.com + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * o Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * o Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * o Neither the name of NVIDIA nor the names of its contributors + * may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT + * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * This program is based on the Generalized Timing Formula(GTF TM) + * Standard Version: 1.0, Revision: 1.0 + * + * The GTF Document contains the following Copyright information: + * + * Copyright (c) 1994, 1995, 1996 - Video Electronics Standards + * Association. Duplication of this document within VESA member + * companies for review purposes is permitted. All other rights + * reserved. + * + * While every precaution has been taken in the preparation + * of this standard, the Video Electronics Standards Association and + * its contributors assume no responsibility for errors or omissions, + * and make no warranties, expressed or implied, of functionality + * of suitability for any purpose. The sample code contained within + * this standard may be used without restriction. + * + * + * + * The GTF EXCEL(TM) SPREADSHEET, a sample (and the definitive) + * implementation of the GTF Timing Standard, is available at: + * + * ftp://ftp.vesa.org/pub/GTF/GTF_V1R1.xls + */ + +/* Ruthlessly converted to server code by Adam Jackson */ + +#ifdef HAVE_XORG_CONFIG_H +# include +#endif + +#include "xf86.h" +#include "xf86Modes.h" +#include + +#define MARGIN_PERCENT 1.8 /* % of active vertical image */ +#define CELL_GRAN 8.0 /* assumed character cell granularity */ +#define MIN_PORCH 1 /* minimum front porch */ +#define V_SYNC_RQD 3 /* width of vsync in lines */ +#define H_SYNC_PERCENT 8.0 /* width of hsync as % of total line */ +#define MIN_VSYNC_PLUS_BP 550.0 /* min time of vsync + back porch (microsec) */ +#define M 600.0 /* blanking formula gradient */ +#define C 40.0 /* blanking formula offset */ +#define K 128.0 /* blanking formula scaling factor */ +#define J 20.0 /* blanking formula scaling factor */ + +/* C' and M' are part of the Blanking Duty Cycle computation */ + +#define C_PRIME (((C - J) * K/256.0) + J) +#define M_PRIME (K/256.0 * M) + + +/* + * xf86GTFMode() - as defined by the GTF Timing Standard, compute the + * Stage 1 Parameters using the vertical refresh frequency. In other + * words: input a desired resolution and desired refresh rate, and + * output the GTF mode timings. + * + * XXX All the code is in place to compute interlaced modes, but I don't + * feel like testing it right now. + * + * XXX margin computations are implemented but not tested (nor used by + * XServer of fbset mode descriptions, from what I can tell). + */ + +_X_EXPORT DisplayModePtr +xf86GTFMode(int h_pixels, int v_lines, float freq, int interlaced, int margins) +{ + DisplayModeRec *mode = xnfcalloc(1, sizeof(DisplayModeRec)); + + float h_pixels_rnd; + float v_lines_rnd; + float v_field_rate_rqd; + float top_margin; + float bottom_margin; + float interlace; + float h_period_est; + float vsync_plus_bp; + float v_back_porch; + float total_v_lines; + float v_field_rate_est; + float h_period; + float v_field_rate; + float v_frame_rate; + float left_margin; + float right_margin; + float total_active_pixels; + float ideal_duty_cycle; + float h_blank; + float total_pixels; + float pixel_freq; + float h_freq; + + float h_sync; + float h_front_porch; + float v_odd_front_porch_lines; + + /* 1. In order to give correct results, the number of horizontal + * pixels requested is first processed to ensure that it is divisible + * by the character size, by rounding it to the nearest character + * cell boundary: + * + * [H PIXELS RND] = ((ROUND([H PIXELS]/[CELL GRAN RND],0))*[CELLGRAN RND]) + */ + + h_pixels_rnd = rint((float) h_pixels / CELL_GRAN) * CELL_GRAN; + + /* 2. If interlace is requested, the number of vertical lines assumed + * by the calculation must be halved, as the computation calculates + * the number of vertical lines per field. In either case, the + * number of lines is rounded to the nearest integer. + * + * [V LINES RND] = IF([INT RQD?]="y", ROUND([V LINES]/2,0), + * ROUND([V LINES],0)) + */ + + v_lines_rnd = interlaced ? + rint((float) v_lines) / 2.0 : + rint((float) v_lines); + + /* 3. Find the frame rate required: + * + * [V FIELD RATE RQD] = IF([INT RQD?]="y", [I/P FREQ RQD]*2, + * [I/P FREQ RQD]) + */ + + v_field_rate_rqd = interlaced ? (freq * 2.0) : (freq); + + /* 4. Find number of lines in Top margin: + * + * [TOP MARGIN (LINES)] = IF([MARGINS RQD?]="Y", + * ROUND(([MARGIN%]/100*[V LINES RND]),0), + * 0) + */ + + top_margin = margins ? rint(MARGIN_PERCENT / 100.0 * v_lines_rnd) : (0.0); + + /* 5. Find number of lines in Bottom margin: + * + * [BOT MARGIN (LINES)] = IF([MARGINS RQD?]="Y", + * ROUND(([MARGIN%]/100*[V LINES RND]),0), + * 0) + */ + + bottom_margin = margins ? rint(MARGIN_PERCENT/100.0 * v_lines_rnd) : (0.0); + + /* 6. If interlace is required, then set variable [INTERLACE]=0.5: + * + * [INTERLACE]=(IF([INT RQD?]="y",0.5,0)) + */ + + interlace = interlaced ? 0.5 : 0.0; + + /* 7. Estimate the Horizontal period + * + * [H PERIOD EST] = ((1/[V FIELD RATE RQD]) - [MIN VSYNC+BP]/1000000) / + * ([V LINES RND] + (2*[TOP MARGIN (LINES)]) + + * [MIN PORCH RND]+[INTERLACE]) * 1000000 + */ + + h_period_est = (((1.0/v_field_rate_rqd) - (MIN_VSYNC_PLUS_BP/1000000.0)) + / (v_lines_rnd + (2*top_margin) + MIN_PORCH + interlace) + * 1000000.0); + + /* 8. Find the number of lines in V sync + back porch: + * + * [V SYNC+BP] = ROUND(([MIN VSYNC+BP]/[H PERIOD EST]),0) + */ + + vsync_plus_bp = rint(MIN_VSYNC_PLUS_BP/h_period_est); + + /* 9. Find the number of lines in V back porch alone: + * + * [V BACK PORCH] = [V SYNC+BP] - [V SYNC RND] + * + * XXX is "[V SYNC RND]" a typo? should be [V SYNC RQD]? + */ + + v_back_porch = vsync_plus_bp - V_SYNC_RQD; + + /* 10. Find the total number of lines in Vertical field period: + * + * [TOTAL V LINES] = [V LINES RND] + [TOP MARGIN (LINES)] + + * [BOT MARGIN (LINES)] + [V SYNC+BP] + [INTERLACE] + + * [MIN PORCH RND] + */ + + total_v_lines = v_lines_rnd + top_margin + bottom_margin + vsync_plus_bp + + interlace + MIN_PORCH; + + /* 11. Estimate the Vertical field frequency: + * + * [V FIELD RATE EST] = 1 / [H PERIOD EST] / [TOTAL V LINES] * 1000000 + */ + + v_field_rate_est = 1.0 / h_period_est / total_v_lines * 1000000.0; + + /* 12. Find the actual horizontal period: + * + * [H PERIOD] = [H PERIOD EST] / ([V FIELD RATE RQD] / [V FIELD RATE EST]) + */ + + h_period = h_period_est / (v_field_rate_rqd / v_field_rate_est); + + /* 13. Find the actual Vertical field frequency: + * + * [V FIELD RATE] = 1 / [H PERIOD] / [TOTAL V LINES] * 1000000 + */ + + v_field_rate = 1.0 / h_period / total_v_lines * 1000000.0; + + /* 14. Find the Vertical frame frequency: + * + * [V FRAME RATE] = (IF([INT RQD?]="y", [V FIELD RATE]/2, [V FIELD RATE])) + */ + + v_frame_rate = interlaced ? v_field_rate / 2.0 : v_field_rate; + + /* 15. Find number of pixels in left margin: + * + * [LEFT MARGIN (PIXELS)] = (IF( [MARGINS RQD?]="Y", + * (ROUND( ([H PIXELS RND] * [MARGIN%] / 100 / + * [CELL GRAN RND]),0)) * [CELL GRAN RND], + * 0)) + */ + + left_margin = margins ? + rint(h_pixels_rnd * MARGIN_PERCENT / 100.0 / CELL_GRAN) * CELL_GRAN : + 0.0; + + /* 16. Find number of pixels in right margin: + * + * [RIGHT MARGIN (PIXELS)] = (IF( [MARGINS RQD?]="Y", + * (ROUND( ([H PIXELS RND] * [MARGIN%] / 100 / + * [CELL GRAN RND]),0)) * [CELL GRAN RND], + * 0)) + */ + + right_margin = margins ? + rint(h_pixels_rnd * MARGIN_PERCENT / 100.0 / CELL_GRAN) * CELL_GRAN : + 0.0; + + /* 17. Find total number of active pixels in image and left and right + * margins: + * + * [TOTAL ACTIVE PIXELS] = [H PIXELS RND] + [LEFT MARGIN (PIXELS)] + + * [RIGHT MARGIN (PIXELS)] + */ + + total_active_pixels = h_pixels_rnd + left_margin + right_margin; + + /* 18. Find the ideal blanking duty cycle from the blanking duty cycle + * equation: + * + * [IDEAL DUTY CYCLE] = [C'] - ([M']*[H PERIOD]/1000) + */ + + ideal_duty_cycle = C_PRIME - (M_PRIME * h_period / 1000.0); + + /* 19. Find the number of pixels in the blanking time to the nearest + * double character cell: + * + * [H BLANK (PIXELS)] = (ROUND(([TOTAL ACTIVE PIXELS] * + * [IDEAL DUTY CYCLE] / + * (100-[IDEAL DUTY CYCLE]) / + * (2*[CELL GRAN RND])), 0)) + * * (2*[CELL GRAN RND]) + */ + + h_blank = rint(total_active_pixels * + ideal_duty_cycle / + (100.0 - ideal_duty_cycle) / + (2.0 * CELL_GRAN)) * (2.0 * CELL_GRAN); + + /* 20. Find total number of pixels: + * + * [TOTAL PIXELS] = [TOTAL ACTIVE PIXELS] + [H BLANK (PIXELS)] + */ + + total_pixels = total_active_pixels + h_blank; + + /* 21. Find pixel clock frequency: + * + * [PIXEL FREQ] = [TOTAL PIXELS] / [H PERIOD] + */ + + pixel_freq = total_pixels / h_period; + + /* 22. Find horizontal frequency: + * + * [H FREQ] = 1000 / [H PERIOD] + */ + + h_freq = 1000.0 / h_period; + + + /* Stage 1 computations are now complete; I should really pass + the results to another function and do the Stage 2 + computations, but I only need a few more values so I'll just + append the computations here for now */ + + + /* 17. Find the number of pixels in the horizontal sync period: + * + * [H SYNC (PIXELS)] =(ROUND(([H SYNC%] / 100 * [TOTAL PIXELS] / + * [CELL GRAN RND]),0))*[CELL GRAN RND] + */ + + h_sync = rint(H_SYNC_PERCENT/100.0 * total_pixels / CELL_GRAN) * CELL_GRAN; + + /* 18. Find the number of pixels in the horizontal front porch period: + * + * [H FRONT PORCH (PIXELS)] = ([H BLANK (PIXELS)]/2)-[H SYNC (PIXELS)] + */ + + h_front_porch = (h_blank / 2.0) - h_sync; + + /* 36. Find the number of lines in the odd front porch period: + * + * [V ODD FRONT PORCH(LINES)]=([MIN PORCH RND]+[INTERLACE]) + */ + + v_odd_front_porch_lines = MIN_PORCH + interlace; + + /* finally, pack the results in the mode struct */ + + mode->HDisplay = (int) (h_pixels_rnd); + mode->HSyncStart = (int) (h_pixels_rnd + h_front_porch); + mode->HSyncEnd = (int) (h_pixels_rnd + h_front_porch + h_sync); + mode->HTotal = (int) (total_pixels); + mode->VDisplay = (int) (v_lines_rnd); + mode->VSyncStart = (int) (v_lines_rnd + v_odd_front_porch_lines); + mode->VSyncEnd = (int) (v_lines_rnd + v_odd_front_porch_lines + V_SYNC_RQD); + mode->VTotal = (int) (total_v_lines); + + mode->Clock = (int) (pixel_freq * 1000.0); + mode->HSync = h_freq; + mode->VRefresh = freq; + + xf86SetModeDefaultName(mode); + + mode->Flags = V_NHSYNC | V_PVSYNC; + if (interlaced) { + mode->VTotal *= 2; + mode->Flags |= V_INTERLACE; + } + + return mode; +} From 26c2e95fa5bf30726356cf4bdd0fea32a771a179 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Sat, 12 Jan 2008 00:09:34 -0500 Subject: [PATCH 014/149] Nuke a duplicate SYMFUNC(xf86CVTMode) --- hw/xfree86/loader/xf86sym.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/hw/xfree86/loader/xf86sym.c b/hw/xfree86/loader/xf86sym.c index 50a19b916..f86a1433d 100644 --- a/hw/xfree86/loader/xf86sym.c +++ b/hw/xfree86/loader/xf86sym.c @@ -348,9 +348,6 @@ _X_HIDDEN void *xfree86LookupTab[] = { SYMFUNC(xf86AllocateEntityPrivateIndex) SYMFUNC(xf86GetEntityPrivate) - /* xf86cvt.c */ - SYMFUNC(xf86CVTMode) - /* xf86Configure.c */ SYMFUNC(xf86AddDeviceToConfigure) From d1c48955f80692a32ab6adcee1384e3d298f471a Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Sat, 12 Jan 2008 00:30:58 -0500 Subject: [PATCH 015/149] Fix CVT abuse in DDCModesFromStandardTiming. CVT is enough different from GTF that it should not be used on monitors that aren't expecting it. This brings us closer to what the spec says the correct behaviour is. --- hw/xfree86/ddc/edid.h | 2 ++ hw/xfree86/modes/xf86EdidModes.c | 40 +++++++++++++++++++++++++------- 2 files changed, 34 insertions(+), 8 deletions(-) diff --git a/hw/xfree86/ddc/edid.h b/hw/xfree86/ddc/edid.h index 2496e19e6..c03427683 100644 --- a/hw/xfree86/ddc/edid.h +++ b/hw/xfree86/ddc/edid.h @@ -339,6 +339,8 @@ #define STD_COLOR_SPACE(x) (x & 0x4) #define PREFERRED_TIMING_MODE(x) (x & 0x2) #define GFT_SUPPORTED(x) (x & 0x1) +#define GTF_SUPPORTED(x) (x & 0x1) +#define CVT_SUPPORTED(x) (x & 0x1) /* detailed timing misc */ #define IS_INTERLACED(x) (x) diff --git a/hw/xfree86/modes/xf86EdidModes.c b/hw/xfree86/modes/xf86EdidModes.c index 467f03251..a9d672265 100644 --- a/hw/xfree86/modes/xf86EdidModes.c +++ b/hw/xfree86/modes/xf86EdidModes.c @@ -263,6 +263,22 @@ DDCModesFromEstablished(int scrnIndex, struct established_timings *timing, return Modes; } +#define LEVEL_DMT 0 +#define LEVEL_GTF 1 +#define LEVEL_CVT 2 + +static int +MonitorStandardTimingLevel(xf86MonPtr DDC) +{ + if (DDC->ver.revision >= 2) { + if (DDC->ver.revision >= 4 && CVT_SUPPORTED(DDC->features.msc)) { + return LEVEL_CVT; + } + return LEVEL_GTF; + } + return LEVEL_DMT; +} + /* * This is not really correct. Appendix B of the EDID 1.4 spec defines * the right thing to do here. If the timing given here matches a mode @@ -282,16 +298,22 @@ DDCModesFromEstablished(int scrnIndex, struct established_timings *timing, * for modes in this section, but does say that CVT is preferred. */ static DisplayModePtr -DDCModesFromStandardTiming(int scrnIndex, struct std_timings *timing, - ddc_quirk_t quirks) +DDCModesFromStandardTiming(struct std_timings *timing, ddc_quirk_t quirks, + int timing_level) { DisplayModePtr Modes = NULL, Mode = NULL; int i; for (i = 0; i < STD_TIMINGS; i++) { if (timing[i].hsize && timing[i].vsize && timing[i].refresh) { - Mode = xf86CVTMode(timing[i].hsize, timing[i].vsize, - timing[i].refresh, FALSE, FALSE); + /* XXX check for DMT first, else... */ + if (timing_level == LEVEL_CVT) + Mode = xf86CVTMode(timing[i].hsize, timing[i].vsize, + timing[i].refresh, FALSE, FALSE); + else + Mode = xf86GTFMode(timing[i].hsize, timing[i].vsize, + timing[i].refresh, FALSE, FALSE); + Mode->type = M_T_DRIVER; Modes = xf86ModesAdd(Modes, Mode); } @@ -565,6 +587,7 @@ xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC) DisplayModePtr Modes = NULL, Mode; ddc_quirk_t quirks; Bool preferred; + int timing_level; xf86DrvMsg (scrnIndex, X_INFO, "EDID vendor \"%s\", prod id %d\n", DDC->vendor.name, DDC->vendor.prod_id); @@ -579,6 +602,8 @@ xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC) if (quirks & (DDC_QUIRK_PREFER_LARGE_60 | DDC_QUIRK_PREFER_LARGE_75)) preferred = FALSE; + timing_level = MonitorStandardTimingLevel(DDC); + for (i = 0; i < DET_TIMINGS; i++) { struct detailed_monitor_section *det_mon = &DDC->det_mon[i]; @@ -592,9 +617,8 @@ xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC) Modes = xf86ModesAdd(Modes, Mode); break; case DS_STD_TIMINGS: - Mode = DDCModesFromStandardTiming(scrnIndex, - det_mon->section.std_t, - quirks); + Mode = DDCModesFromStandardTiming(det_mon->section.std_t, + quirks, timing_level); Modes = xf86ModesAdd(Modes, Mode); break; case DS_CVT: @@ -611,7 +635,7 @@ xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC) Modes = xf86ModesAdd(Modes, Mode); /* Add standard timings */ - Mode = DDCModesFromStandardTiming(scrnIndex, DDC->timings2, quirks); + Mode = DDCModesFromStandardTiming(DDC->timings2, quirks, timing_level); Modes = xf86ModesAdd(Modes, Mode); if (quirks & DDC_QUIRK_PREFER_LARGE_60) From 31014d88aff8dc8a502cf0f26e4cde141e1a92f5 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Sat, 12 Jan 2008 01:03:44 -0500 Subject: [PATCH 016/149] EDID 1.4: Decode additional CVT support information. Table 3.28: Display Range Limits & CVT Support Definition --- hw/xfree86/ddc/edid.h | 44 +++++++++++++++++++++++++++++++-- hw/xfree86/ddc/interpret_edid.c | 15 ++++++++++- 2 files changed, 56 insertions(+), 3 deletions(-) diff --git a/hw/xfree86/ddc/edid.h b/hw/xfree86/ddc/edid.h index c03427683..a4e79dae0 100644 --- a/hw/xfree86/ddc/edid.h +++ b/hw/xfree86/ddc/edid.h @@ -271,6 +271,39 @@ #define K_2ND_GTF _K_2ND_GTF(c) #define _J_2ND_GTF(x) (x[17] / 2) #define J_2ND_GTF _J_2ND_GTF(c) +#define _HAVE_CVT(x) (x[10] == 0x04) +#define HAVE_CVT _HAVE_CVT(c) +#define _MAX_CLOCK_KHZ(x) (x[12] >> 2) +#define MAX_CLOCK_KHZ (MAX_CLOCK * 10000) - (_MAX_CLOCK_KHZ(c) * 250) +#define _MAXWIDTH(x) ((x[13] == 0 ? 0 : x[13] + ((x[12] & 0x03) << 8)) * 8) +#define MAXWIDTH _MAXWIDTH(c) +#define _SUPPORTED_ASPECT(x) x[14] +#define SUPPORTED_ASPECT _SUPPORTED_ASPECT(c) +#define SUPPORTED_ASPECT_4_3 0x80 +#define SUPPORTED_ASPECT_16_9 0x40 +#define SUPPORTED_ASPECT_16_10 0x20 +#define SUPPORTED_ASPECT_5_4 0x10 +#define SUPPORTED_ASPECT_15_9 0x08 +#define _PREFERRED_ASPECT(x) ((x[15] & 0xe0) >> 5) +#define PREFERRED_ASPECT _PREFERRED_ASPECT(c) +#define PREFERRED_ASPECT_4_3 0 +#define PREFERRED_ASPECT_16_9 1 +#define PREFERRED_ASPECT_16_10 2 +#define PREFERRED_ASPECT_5_4 3 +#define PREFERRED_ASPECT_15_9 4 +#define _SUPPORTED_BLANKING(x) ((x[15] & 0x18) >> 3) +#define SUPPORTED_BLANKING _SUPPORTED_BLANKING(c) +#define CVT_STANDARD 0x01 +#define CVT_REDUCED 0x02 +#define _SUPPORTED_SCALING(x) ((x[16] & 0xf0) >> 4) +#define SUPPORTED_SCALING _SUPPORTED_SCALING(c) +#define SCALING_HSHRINK 0x08 +#define SCALING_HSTRETCH 0x04 +#define SCALING_VSHRINK 0x02 +#define SCALING_VSTRETCH 0x01 +#define _PREFERRED_REFRESH(x) x[17] +#define PREFERRED_REFRESH _PREFERRED_REFRESH(c) + #define MONITOR_NAME 0xFC #define ADD_COLOR_POINT 0xFB #define WHITEX F_CC(I_CC((GET(D_BW_LOW)),(GET(D_WHITEX)),2)) @@ -447,12 +480,19 @@ struct monitor_ranges { int max_v; int min_h; int max_h; - int max_clock; + int max_clock; /* in mhz */ int gtf_2nd_f; int gtf_2nd_c; int gtf_2nd_m; int gtf_2nd_k; int gtf_2nd_j; + int max_clock_khz; + int maxwidth; /* in pixels */ + char supported_aspect; + char preferred_aspect; + char supported_blanking; + char supported_scaling; + int preferred_refresh; /* in hz */ }; struct whitePoints{ @@ -482,7 +522,7 @@ struct detailed_monitor_section { Uchar serial[13]; Uchar ascii_data[13]; Uchar name[13]; - struct monitor_ranges ranges; /* 40 */ + struct monitor_ranges ranges; /* 56 */ struct std_timings std_t[5]; /* 80 */ struct whitePoints wp[2]; /* 32 */ /* color management data */ diff --git a/hw/xfree86/ddc/interpret_edid.c b/hw/xfree86/ddc/interpret_edid.c index 14b0fd73a..21391dd66 100644 --- a/hw/xfree86/ddc/interpret_edid.c +++ b/hw/xfree86/ddc/interpret_edid.c @@ -329,8 +329,21 @@ get_monitor_ranges(Uchar *c, struct monitor_ranges *r) r->gtf_2nd_m = M_2ND_GTF; r->gtf_2nd_k = K_2ND_GTF; r->gtf_2nd_j = J_2ND_GTF; - } else + } else { r->gtf_2nd_f = 0; + } + if (HAVE_CVT) { + r->max_clock_khz = MAX_CLOCK_KHZ; + r->max_clock = r->max_clock_khz / 1000; + r->maxwidth = MAXWIDTH; + r->supported_aspect = SUPPORTED_ASPECT; + r->preferred_aspect = PREFERRED_ASPECT; + r->supported_blanking = SUPPORTED_BLANKING; + r->supported_scaling = SUPPORTED_SCALING; + r->preferred_refresh = PREFERRED_REFRESH; + } else { + r->max_clock_khz = 0; + } } static void From b7eb92774a58639aff3f26bb28a3dcff910c3fb6 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Sat, 12 Jan 2008 01:22:05 -0500 Subject: [PATCH 017/149] EDID 1.4: Print additional CVT support data in the log. --- hw/xfree86/ddc/print_edid.c | 69 ++++++++++++++++++++++++++++++------- 1 file changed, 56 insertions(+), 13 deletions(-) diff --git a/hw/xfree86/ddc/print_edid.c b/hw/xfree86/ddc/print_edid.c index d9f18fa9f..f5442adb7 100644 --- a/hw/xfree86/ddc/print_edid.c +++ b/hw/xfree86/ddc/print_edid.c @@ -27,6 +27,9 @@ #include #endif +/* XXX kinda gross */ +#define _PARSE_EDID_ + #include "misc.h" #include "xf86.h" #include "xf86_OSproc.h" @@ -350,23 +353,63 @@ print_detailed_monitor_section(int scrnIndex, xf86DrvMsg(scrnIndex,X_INFO,"Monitor name: %s\n",m[i].section.name); break; case DS_RANGES: + { + struct monitor_ranges *r = &m[i].section.ranges; xf86DrvMsg(scrnIndex,X_INFO, - "Ranges: V min: %i V max: %i Hz, H min: %i H max: %i kHz,", - m[i].section.ranges.min_v, m[i].section.ranges.max_v, - m[i].section.ranges.min_h, m[i].section.ranges.max_h); - if (m[i].section.ranges.max_clock != 0) - xf86ErrorF(" PixClock max %i MHz\n",m[i].section.ranges.max_clock); - else + "Ranges: V min: %i V max: %i Hz, H min: %i H max: %i kHz,", + r->min_v, r->max_v, r->min_h, r->max_h); + if (r->max_clock_khz != 0) { + xf86ErrorF(" PixClock max %i kHz\n", r->max_clock_khz); + if (r->maxwidth) + xf86DrvMsg(scrnIndex, X_INFO, "Maximum pixel width: %d\n", + r->maxwidth); + xf86DrvMsg(scrnIndex, X_INFO, "Supported aspect ratios:"); + if (r->supported_aspect & SUPPORTED_ASPECT_4_3) + xf86ErrorF(" 4:3%s", + r->preferred_aspect == PREFERRED_ASPECT_4_3?"*":""); + if (r->supported_aspect & SUPPORTED_ASPECT_16_9) + xf86ErrorF(" 16:9%s", + r->preferred_aspect == PREFERRED_ASPECT_16_9?"*":""); + if (r->supported_aspect & SUPPORTED_ASPECT_16_10) + xf86ErrorF(" 16:10%s", + r->preferred_aspect == PREFERRED_ASPECT_16_10?"*":""); + if (r->supported_aspect & SUPPORTED_ASPECT_5_4) + xf86ErrorF(" 5:4%s", + r->preferred_aspect == PREFERRED_ASPECT_5_4?"*":""); + if (r->supported_aspect & SUPPORTED_ASPECT_15_9) + xf86ErrorF(" 15:9%s", + r->preferred_aspect == PREFERRED_ASPECT_15_9?"*":""); xf86ErrorF("\n"); - if (m[i].section.ranges.gtf_2nd_f > 0) + xf86DrvMsg(scrnIndex, X_INFO, "Supported blankings:"); + if (r->supported_blanking & CVT_STANDARD) + xf86ErrorF(" standard"); + if (r->supported_blanking & CVT_REDUCED) + xf86ErrorF(" reduced"); + xf86ErrorF("\n"); + xf86DrvMsg(scrnIndex, X_INFO, "Supported scalings:"); + if (r->supported_scaling & SCALING_HSHRINK) + xf86ErrorF(" hshrink"); + if (r->supported_scaling & SCALING_HSTRETCH) + xf86ErrorF(" hstretch"); + if (r->supported_scaling & SCALING_VSHRINK) + xf86ErrorF(" vshrink"); + if (r->supported_scaling & SCALING_VSTRETCH) + xf86ErrorF(" vstretch"); + xf86ErrorF("\n"); + xf86DrvMsg(scrnIndex, X_INFO, "Preferred refresh rate: %d\n", + r->preferred_refresh); + } else if (r->max_clock != 0) { + xf86ErrorF(" PixClock max %i MHz\n", r->max_clock); + } else { + xf86ErrorF("\n"); + } + if (r->gtf_2nd_f > 0) xf86DrvMsg(scrnIndex,X_INFO," 2nd GTF parameters: f: %i kHz " - "c: %i m: %i k %i j %i\n", - m[i].section.ranges.gtf_2nd_f, - m[i].section.ranges.gtf_2nd_c, - m[i].section.ranges.gtf_2nd_m, - m[i].section.ranges.gtf_2nd_k, - m[i].section.ranges.gtf_2nd_j); + "c: %i m: %i k %i j %i\n", r->gtf_2nd_f, + r->gtf_2nd_c, r->gtf_2nd_m, r->gtf_2nd_k, + r->gtf_2nd_j); break; + } case DS_STD_TIMINGS: for (j = 0; j<5; j++) xf86DrvMsg(scrnIndex,X_INFO,"#%i: hsize: %i vsize %i refresh: %i " From 8f0a4282f0ac33625eda9466e3db0bcef64e403a Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 29 Feb 2008 16:39:29 -0500 Subject: [PATCH 018/149] Bug #10463: Always initialize reference pixel before AllocColor() --- render/miindex.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/render/miindex.c b/render/miindex.c index 0e12dca4a..4e0cf0084 100644 --- a/render/miindex.c +++ b/render/miindex.c @@ -147,6 +147,7 @@ miBuildRenderColormap (ColormapPtr pColormap, Pixel *pixels, int *nump) for (g = 0; g < cube; g++) for (b = 0; b < cube; b++) { + pixel = 0; red = (r * 65535 + (cube-1)/2) / (cube - 1); green = (g * 65535 + (cube-1)/2) / (cube - 1); blue = (b * 65535 + (cube-1)/2) / (cube - 1); @@ -157,6 +158,7 @@ miBuildRenderColormap (ColormapPtr pColormap, Pixel *pixels, int *nump) } for (g = 0; g < gray; g++) { + pixel = 0; red = green = blue = (g * 65535 + (gray-1)/2) / (gray - 1); if (AllocColor (pColormap, &red, &green, &blue, &pixel, 0) != Success) return FALSE; From 5d5fcc7198ca54fa9dc24fe974763eff9fddabee Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 29 Feb 2008 16:42:04 -0500 Subject: [PATCH 019/149] Bug #10464: Set pixel value to 0 before FindColor() --- dix/colormap.c | 1 + 1 file changed, 1 insertion(+) diff --git a/dix/colormap.c b/dix/colormap.c index c4c8c8bfe..8b1bad8a3 100644 --- a/dix/colormap.c +++ b/dix/colormap.c @@ -1006,6 +1006,7 @@ FakeAllocColor (ColormapPtr pmap, xColorItem *item) switch (class) { case GrayScale: case PseudoColor: + temp = 0; item->pixel = 0; if (FindColor(pmap, pmap->red, entries, &rgb, &temp, PSEUDOMAP, -1, AllComp) == Success) { From 4a44fe7c8678360d0549cf0e0d63870f3623b1db Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 29 Feb 2008 16:43:14 -0500 Subject: [PATCH 020/149] Bug #10465: Use calloc() for allocating PixmapRec's. --- dix/pixmap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dix/pixmap.c b/dix/pixmap.c index 82e388cf3..d4b41953e 100644 --- a/dix/pixmap.c +++ b/dix/pixmap.c @@ -113,7 +113,7 @@ AllocatePixmap(ScreenPtr pScreen, int pixDataSize) if (pScreen->totalPixmapSize > ((size_t)-1) - pixDataSize) return NullPixmap; - pPixmap = (PixmapPtr)xalloc(pScreen->totalPixmapSize + pixDataSize); + pPixmap = (PixmapPtr)xcalloc(1, pScreen->totalPixmapSize + pixDataSize); if (!pPixmap) return NullPixmap; From c0e1959f285d7a7df66f42d55912a5a595decd0f Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Fri, 29 Feb 2008 16:45:11 -0500 Subject: [PATCH 021/149] On second thought, revert that, it'll make large pixmaps painfully slow. Need to just fix the callers. --- dix/pixmap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dix/pixmap.c b/dix/pixmap.c index d4b41953e..82e388cf3 100644 --- a/dix/pixmap.c +++ b/dix/pixmap.c @@ -113,7 +113,7 @@ AllocatePixmap(ScreenPtr pScreen, int pixDataSize) if (pScreen->totalPixmapSize > ((size_t)-1) - pixDataSize) return NullPixmap; - pPixmap = (PixmapPtr)xcalloc(1, pScreen->totalPixmapSize + pixDataSize); + pPixmap = (PixmapPtr)xalloc(pScreen->totalPixmapSize + pixDataSize); if (!pPixmap) return NullPixmap; From d5715f7beaad6816db27b01b67d7a3c69164d106 Mon Sep 17 00:00:00 2001 From: Eamon Walsh Date: Fri, 29 Feb 2008 16:16:12 -0500 Subject: [PATCH 022/149] dix: Refactoring of property code to allow for polyinstantiation. Introduces dixLookupProperty() API. --- dix/property.c | 221 +++++++++++++++++-------------------- hw/xfree86/loader/dixsym.c | 1 + include/property.h | 7 ++ 3 files changed, 112 insertions(+), 117 deletions(-) diff --git a/dix/property.c b/dix/property.c index ce6116992..e74becfa2 100644 --- a/dix/property.c +++ b/dix/property.c @@ -63,11 +63,10 @@ SOFTWARE. /***************************************************************** * Property Stuff * - * ChangeProperty, DeleteProperty, GetProperties, - * ListProperties + * dixLookupProperty, dixChangeProperty, DeleteProperty * - * Properties below to windows. A allocate slots each time - * a property is added. No fancy searching done. + * Properties belong to windows. The list of properties should not be + * traversed directly. Instead, use the three functions listed above. * *****************************************************************/ @@ -91,17 +90,22 @@ PrintPropertys(WindowPtr pWin) } #endif -static _X_INLINE PropertyPtr -FindProperty(WindowPtr pWin, Atom propertyName) +_X_EXPORT int +dixLookupProperty(PropertyPtr *result, WindowPtr pWin, Atom propertyName, + ClientPtr client, Mask access_mode) { - PropertyPtr pProp = wUserProps(pWin); - while (pProp) - { + PropertyPtr pProp; + int rc = BadMatch; + client->errorValue = propertyName; + + for (pProp = wUserProps(pWin); pProp; pProp = pProp->next) if (pProp->propertyName == propertyName) break; - pProp = pProp->next; - } - return pProp; + + if (pProp) + rc = XaceHookPropertyAccess(client, pWin, pProp, access_mode); + *result = pProp; + return rc; } static void @@ -125,65 +129,69 @@ ProcRotateProperties(ClientPtr client) WindowPtr pWin; Atom * atoms; PropertyPtr * props; /* array of pointer */ - PropertyPtr pProp; + PropertyPtr pProp, saved; REQUEST_FIXED_SIZE(xRotatePropertiesReq, stuff->nAtoms << 2); UpdateCurrentTime(); rc = dixLookupWindow(&pWin, stuff->window, client, DixSetPropAccess); - if (rc != Success) + if (rc != Success || stuff->nAtoms <= 0) return rc; - if (!stuff->nAtoms) - return(Success); + atoms = (Atom *) & stuff[1]; props = (PropertyPtr *)xalloc(stuff->nAtoms * sizeof(PropertyPtr)); - if (!props) - return(BadAlloc); + saved = (PropertyPtr)xalloc(stuff->nAtoms * sizeof(PropertyRec)); + if (!props || !saved) { + rc = BadAlloc; + goto out; + } + for (i = 0; i < stuff->nAtoms; i++) { if (!ValidAtom(atoms[i])) { - xfree(props); + rc = BadAtom; client->errorValue = atoms[i]; - return BadAtom; + goto out; } for (j = i + 1; j < stuff->nAtoms; j++) if (atoms[j] == atoms[i]) { - xfree(props); - return BadMatch; + rc = BadMatch; + goto out; } - pProp = FindProperty(pWin, atoms[i]); - if (!pProp) { - xfree(props); - return BadMatch; - } - rc = XaceHookPropertyAccess(client, pWin, pProp, - DixReadAccess|DixWriteAccess); - if (rc != Success) { - xfree(props); - client->errorValue = atoms[i]; - return rc; - } + + rc = dixLookupProperty(&pProp, pWin, atoms[i], client, + DixReadAccess|DixWriteAccess); + if (rc != Success) + goto out; + props[i] = pProp; + saved[i] = *pProp; } delta = stuff->nPositions; /* If the rotation is a complete 360 degrees, then moving the properties around and generating PropertyNotify events should be skipped. */ - if ( (stuff->nAtoms != 0) && (abs(delta) % stuff->nAtoms) != 0 ) + if (abs(delta) % stuff->nAtoms) { while (delta < 0) /* faster if abs value is small */ delta += stuff->nAtoms; for (i = 0; i < stuff->nAtoms; i++) { - deliverPropertyNotifyEvent(pWin, PropertyNewValue, - props[i]->propertyName); - - props[i]->propertyName = atoms[(i + delta) % stuff->nAtoms]; + j = (i + delta) % stuff->nAtoms; + deliverPropertyNotifyEvent(pWin, PropertyNewValue, atoms[i]); + + /* Preserve name and devPrivates */ + props[j]->type = saved[i].type; + props[j]->format = saved[i].format; + props[j]->size = saved[i].size; + props[j]->data = saved[i].data; } } +out: + xfree(saved); xfree(props); - return Success; + return rc; } int @@ -253,9 +261,9 @@ dixChangeWindowProperty(ClientPtr pClient, WindowPtr pWin, Atom property, totalSize = len * sizeInBytes; /* first see if property already exists */ - pProp = FindProperty(pWin, property); + rc = dixLookupProperty(&pProp, pWin, property, pClient, DixWriteAccess); - if (!pProp) /* just add to list */ + if (rc == BadMatch) /* just add to list */ { if (!pWin->optional && !MakeWindowOptional (pWin)) return(BadAlloc); @@ -287,13 +295,8 @@ dixChangeWindowProperty(ClientPtr pClient, WindowPtr pWin, Atom property, pProp->next = pWin->optional->userProps; pWin->optional->userProps = pProp; } - else + else if (rc == Success) { - rc = XaceHookPropertyAccess(pClient, pWin, pProp, DixWriteAccess); - if (rc != Success) { - pClient->errorValue = property; - return rc; - } /* To append or prepend to a property the request format and type must match those of the already defined property. The existing format and type are irrelevant when using the mode @@ -347,6 +350,8 @@ dixChangeWindowProperty(ClientPtr pClient, WindowPtr pWin, Atom property, pProp->size += len; } } + else + return rc; if (sendevent) deliverPropertyNotifyEvent(pWin, PropertyNewValue, pProp->propertyName); @@ -369,37 +374,29 @@ DeleteProperty(ClientPtr client, WindowPtr pWin, Atom propName) PropertyPtr pProp, prevProp; int rc; - if (!(pProp = wUserProps (pWin))) - return(Success); - prevProp = (PropertyPtr)NULL; - while (pProp) - { - if (pProp->propertyName == propName) - break; - prevProp = pProp; - pProp = pProp->next; - } - if (pProp) - { - rc = XaceHookPropertyAccess(client, pWin, pProp, DixDestroyAccess); - if (rc != Success) - return rc; + rc = dixLookupProperty(&pProp, pWin, propName, client, DixDestroyAccess); + if (rc == BadMatch) + return Success; /* Succeed if property does not exist */ - if (prevProp == (PropertyPtr)NULL) /* takes care of head */ - { + if (rc == Success) { + if (pWin->optional->userProps == pProp) { + /* Takes care of head */ if (!(pWin->optional->userProps = pProp->next)) CheckWindowOptionalNeed (pWin); - } - else - { - prevProp->next = pProp->next; - } + } else { + /* Need to traverse to find the previous element */ + prevProp = pWin->optional->userProps; + while (prevProp->next != pProp) + prevProp = prevProp->next; + prevProp->next = pProp->next; + } + deliverPropertyNotifyEvent(pWin, PropertyDelete, pProp->propertyName); dixFreePrivates(pProp->devPrivates); xfree(pProp->data); xfree(pProp); } - return(Success); + return rc; } void @@ -453,15 +450,16 @@ ProcGetProperty(ClientPtr client) int rc; WindowPtr pWin; xGetPropertyReply reply; - Mask access_mode = DixGetPropAccess; + Mask win_mode = DixGetPropAccess, prop_mode = DixReadAccess; REQUEST(xGetPropertyReq); REQUEST_SIZE_MATCH(xGetPropertyReq); if (stuff->delete) { UpdateCurrentTime(); - access_mode |= DixSetPropAccess; + win_mode |= DixSetPropAccess; + prop_mode |= DixDestroyAccess; } - rc = dixLookupWindow(&pWin, stuff->window, client, access_mode); + rc = dixLookupWindow(&pWin, stuff->window, client, win_mode); if (rc != Success) return rc; @@ -481,30 +479,14 @@ ProcGetProperty(ClientPtr client) return(BadAtom); } - pProp = wUserProps (pWin); - prevProp = (PropertyPtr)NULL; - while (pProp) - { - if (pProp->propertyName == stuff->property) - break; - prevProp = pProp; - pProp = pProp->next; - } - reply.type = X_Reply; reply.sequenceNumber = client->sequence; - if (!pProp) + + rc = dixLookupProperty(&pProp, pWin, stuff->property, client, prop_mode); + if (rc == BadMatch) return NullPropertyReply(client, None, 0, &reply); - - access_mode = DixReadAccess; - if (stuff->delete) - access_mode |= DixDestroyAccess; - - rc = XaceHookPropertyAccess(client, pWin, pProp, access_mode); - if (rc != Success) { - client->errorValue = stuff->property; + else if (rc != Success) return rc; - } /* If the request type and actual type don't match. Return the property information, but not the data. */ @@ -560,15 +542,20 @@ ProcGetProperty(ClientPtr client) (char *)pProp->data + ind); } - if (stuff->delete && (reply.bytesAfter == 0)) - { /* delete the Property */ - if (prevProp == (PropertyPtr)NULL) /* takes care of head */ - { - if (!(pWin->optional->userProps = pProp->next)) + if (stuff->delete && (reply.bytesAfter == 0)) { + /* Delete the Property */ + if (pWin->optional->userProps == pProp) { + /* Takes care of head */ + if (!(pWin->optional->userProps = pProp->next)) CheckWindowOptionalNeed (pWin); - } - else + } else { + /* Need to traverse to find the previous element */ + prevProp = pWin->optional->userProps; + while (prevProp->next != pProp) + prevProp = prevProp->next; prevProp->next = pProp->next; + } + dixFreePrivates(pProp->devPrivates); xfree(pProp->data); xfree(pProp); @@ -583,7 +570,7 @@ ProcListProperties(ClientPtr client) xListPropertiesReply xlpr; int rc, numProps = 0; WindowPtr pWin; - PropertyPtr pProp; + PropertyPtr pProp, realProp; REQUEST(xResourceReq); REQUEST_SIZE_MATCH(xResourceReq); @@ -591,34 +578,34 @@ ProcListProperties(ClientPtr client) if (rc != Success) return rc; - pProp = wUserProps (pWin); - while (pProp) - { - pProp = pProp->next; + for (pProp = wUserProps(pWin); pProp; pProp = pProp->next) numProps++; + + if (numProps && !(pAtoms = (Atom *)xalloc(numProps * sizeof(Atom)))) + return BadAlloc; + + numProps = 0; + temppAtoms = pAtoms; + for (pProp = wUserProps(pWin); pProp; pProp = pProp->next) { + realProp = pProp; + rc = XaceHookPropertyAccess(client, pWin, pProp, DixGetAttrAccess); + if (rc == Success && realProp == pProp) { + *temppAtoms++ = pProp->propertyName; + numProps++; + } } - if (numProps) - if(!(pAtoms = (Atom *)xalloc(numProps * sizeof(Atom)))) - return(BadAlloc); xlpr.type = X_Reply; xlpr.nProperties = numProps; xlpr.length = (numProps * sizeof(Atom)) >> 2; xlpr.sequenceNumber = client->sequence; - pProp = wUserProps (pWin); - temppAtoms = pAtoms; - while (pProp) - { - *temppAtoms++ = pProp->propertyName; - pProp = pProp->next; - } WriteReplyToClient(client, sizeof(xGenericReply), &xlpr); if (numProps) { client->pSwapReplyFunc = (ReplySwapPtr)Swap32Write; WriteSwappedDataToClient(client, numProps * sizeof(Atom), pAtoms); - xfree(pAtoms); } + xfree(pAtoms); return(client->noClientException); } diff --git a/hw/xfree86/loader/dixsym.c b/hw/xfree86/loader/dixsym.c index 49c7d271b..e6c37fe00 100644 --- a/hw/xfree86/loader/dixsym.c +++ b/hw/xfree86/loader/dixsym.c @@ -193,6 +193,7 @@ _X_HIDDEN void *dixLookupTab[] = { SYMFUNC(XineramaGetCursorScreen) #endif /* property.c */ + SYMFUNC(dixLookupProperty) SYMFUNC(ChangeWindowProperty) SYMFUNC(dixChangeWindowProperty) /* extension.c */ diff --git a/include/property.h b/include/property.h index ba7d226cd..1207e8191 100644 --- a/include/property.h +++ b/include/property.h @@ -52,6 +52,13 @@ SOFTWARE. typedef struct _Property *PropertyPtr; +extern int dixLookupProperty( + PropertyPtr * /*result*/, + WindowPtr /*pWin*/, + Atom /*proprty*/, + ClientPtr /*pClient*/, + Mask /*access_mode*/); + extern int dixChangeWindowProperty( ClientPtr /*pClient*/, WindowPtr /*pWin*/, From 34bf308a9e66f1a2f48630a15b1802afad50ec24 Mon Sep 17 00:00:00 2001 From: Eamon Walsh Date: Fri, 29 Feb 2008 18:00:23 -0500 Subject: [PATCH 023/149] dix: Refactoring of selection code to allow for polyinstantiation. Introduces dixLookupSelection() API. Removes NumCurrentSelections from API. --- Xext/xselinux.c | 2 - dix/Makefile.am | 1 + dix/dispatch.c | 274 --------------------------------- dix/main.c | 2 + dix/selection.c | 306 +++++++++++++++++++++++++++++++++++++ hw/xfree86/loader/dixsym.c | 8 +- include/dix.h | 23 --- include/selection.h | 47 +++++- 8 files changed, 352 insertions(+), 311 deletions(-) create mode 100644 dix/selection.c diff --git a/Xext/xselinux.c b/Xext/xselinux.c index 9adc93195..8d66ea199 100644 --- a/Xext/xselinux.c +++ b/Xext/xselinux.c @@ -967,8 +967,6 @@ SELinuxSelectionState(CallbackListPtr *pcbl, pointer unused, pointer calldata) switch (rec->kind) { case SelectionSetOwner: - case SelectionGetOwner: - case SelectionConvertSelection: default: break; } diff --git a/dix/Makefile.am b/dix/Makefile.am index 2cf90142f..b7b1ec071 100644 --- a/dix/Makefile.am +++ b/dix/Makefile.am @@ -29,6 +29,7 @@ libdix_la_SOURCES = \ property.c \ registry.c \ resource.c \ + selection.c \ swaprep.c \ swapreq.c \ tables.c \ diff --git a/dix/dispatch.c b/dix/dispatch.c index e8e650a91..bb8b0c416 100644 --- a/dix/dispatch.c +++ b/dix/dispatch.c @@ -165,10 +165,6 @@ typedef const char *string; extern xConnSetupPrefix connSetupPrefix; extern char *ConnectionInfo; -_X_EXPORT Selection *CurrentSelections; -_X_EXPORT int NumCurrentSelections; -CallbackListPtr SelectionCallback = NULL; - static ClientPtr grabClient; #define GrabNone 0 #define GrabActive 1 @@ -181,8 +177,6 @@ extern int connBlockScreenStart; static void KillAllClients(void); -static void DeleteClientFromAnySelections(ClientPtr client); - static int nextFreeClientID; /* always MIN free client ID */ static int nClients; /* number of authorized clients */ @@ -246,14 +240,6 @@ UpdateCurrentTimeIf(void) currentTime = systime; } -static void -InitSelections(void) -{ - if (CurrentSelections) - xfree(CurrentSelections); - CurrentSelections = (Selection *)NULL; - NumCurrentSelections = 0; -} #ifdef SMART_SCHEDULE #undef SMART_DEBUG @@ -372,7 +358,6 @@ Dispatch(void) #endif nextFreeClientID = 1; - InitSelections(); nClients = 0; clientReady = (int *) xalloc(sizeof(int) * MaxClients); @@ -967,217 +952,6 @@ ProcGetAtomName(ClientPtr client) } } -int -ProcSetSelectionOwner(ClientPtr client) -{ - WindowPtr pWin; - TimeStamp time; - int rc; - REQUEST(xSetSelectionOwnerReq); - REQUEST_SIZE_MATCH(xSetSelectionOwnerReq); - - UpdateCurrentTime(); - time = ClientTimeToServerTime(stuff->time); - - /* If the client's time stamp is in the future relative to the server's - time stamp, do not set the selection, just return success. */ - if (CompareTimeStamps(time, currentTime) == LATER) - return Success; - if (stuff->window != None) - { - rc = dixLookupWindow(&pWin, stuff->window, client, DixSetAttrAccess); - if (rc != Success) - return rc; - } - else - pWin = (WindowPtr)None; - if (ValidAtom(stuff->selection)) - { - int i = 0; - - rc = XaceHookSelectionAccess(client, stuff->selection, - DixSetAttrAccess); - if (rc != Success) - return rc; - - /* - * First, see if the selection is already set... - */ - while ((i < NumCurrentSelections) && - CurrentSelections[i].selection != stuff->selection) - i++; - if (i < NumCurrentSelections) - { - xEvent event; - - /* If the timestamp in client's request is in the past relative - to the time stamp indicating the last time the owner of the - selection was set, do not set the selection, just return - success. */ - if (CompareTimeStamps(time, CurrentSelections[i].lastTimeChanged) - == EARLIER) - return Success; - if (CurrentSelections[i].client && - (!pWin || (CurrentSelections[i].client != client))) - { - event.u.u.type = SelectionClear; - event.u.selectionClear.time = time.milliseconds; - event.u.selectionClear.window = CurrentSelections[i].window; - event.u.selectionClear.atom = CurrentSelections[i].selection; - (void) TryClientEvents (CurrentSelections[i].client, &event, 1, - NoEventMask, NoEventMask /* CantBeFiltered */, - NullGrab); - } - } - else - { - /* - * It doesn't exist, so add it... - */ - Selection *newsels; - - if (i == 0) - newsels = (Selection *)xalloc(sizeof(Selection)); - else - newsels = (Selection *)xrealloc(CurrentSelections, - (NumCurrentSelections + 1) * sizeof(Selection)); - if (!newsels) - return BadAlloc; - NumCurrentSelections++; - CurrentSelections = newsels; - CurrentSelections[i].selection = stuff->selection; - CurrentSelections[i].devPrivates = NULL; - } - CurrentSelections[i].lastTimeChanged = time; - CurrentSelections[i].window = stuff->window; - CurrentSelections[i].pWin = pWin; - CurrentSelections[i].client = (pWin ? client : NullClient); - if (SelectionCallback) - { - SelectionInfoRec info; - - info.selection = &CurrentSelections[i]; - info.client = client; - info.kind= SelectionSetOwner; - CallCallbacks(&SelectionCallback, &info); - } - return (client->noClientException); - } - else - { - client->errorValue = stuff->selection; - return (BadAtom); - } -} - -int -ProcGetSelectionOwner(ClientPtr client) -{ - REQUEST(xResourceReq); - - REQUEST_SIZE_MATCH(xResourceReq); - if (ValidAtom(stuff->id)) - { - int rc, i; - xGetSelectionOwnerReply reply; - - rc = XaceHookSelectionAccess(client, stuff->id, DixGetAttrAccess); - if (rc != Success) - return rc; - - i = 0; - while ((i < NumCurrentSelections) && - CurrentSelections[i].selection != stuff->id) i++; - reply.type = X_Reply; - reply.length = 0; - reply.sequenceNumber = client->sequence; - if (i < NumCurrentSelections) { - if (SelectionCallback) { - SelectionInfoRec info; - - info.selection = &CurrentSelections[i]; - info.client = client; - info.kind= SelectionGetOwner; - CallCallbacks(&SelectionCallback, &info); - } - reply.owner = CurrentSelections[i].window; - } else - reply.owner = None; - WriteReplyToClient(client, sizeof(xGetSelectionOwnerReply), &reply); - return(client->noClientException); - } - else - { - client->errorValue = stuff->id; - return (BadAtom); - } -} - -int -ProcConvertSelection(ClientPtr client) -{ - Bool paramsOkay; - xEvent event; - WindowPtr pWin; - REQUEST(xConvertSelectionReq); - int rc; - - REQUEST_SIZE_MATCH(xConvertSelectionReq); - rc = dixLookupWindow(&pWin, stuff->requestor, client, DixSetAttrAccess); - if (rc != Success) - return rc; - rc = XaceHookSelectionAccess(client, stuff->selection, DixReadAccess); - if (rc != Success) - return rc; - - paramsOkay = (ValidAtom(stuff->selection) && ValidAtom(stuff->target)); - if (stuff->property != None) - paramsOkay &= ValidAtom(stuff->property); - if (paramsOkay) - { - int i; - - i = 0; - while ((i < NumCurrentSelections) && - CurrentSelections[i].selection != stuff->selection) i++; - if (i < NumCurrentSelections && CurrentSelections[i].window != None) { - if (SelectionCallback) { - SelectionInfoRec info; - - info.selection = &CurrentSelections[i]; - info.client = client; - info.kind= SelectionConvertSelection; - CallCallbacks(&SelectionCallback, &info); - } - event.u.u.type = SelectionRequest; - event.u.selectionRequest.time = stuff->time; - event.u.selectionRequest.owner = CurrentSelections[i].window; - event.u.selectionRequest.requestor = stuff->requestor; - event.u.selectionRequest.selection = stuff->selection; - event.u.selectionRequest.target = stuff->target; - event.u.selectionRequest.property = stuff->property; - if (TryClientEvents( - CurrentSelections[i].client, &event, 1, NoEventMask, - NoEventMask /* CantBeFiltered */, NullGrab)) - return (client->noClientException); - } - event.u.u.type = SelectionNotify; - event.u.selectionNotify.time = stuff->time; - event.u.selectionNotify.requestor = stuff->requestor; - event.u.selectionNotify.selection = stuff->selection; - event.u.selectionNotify.target = stuff->target; - event.u.selectionNotify.property = None; - (void) TryClientEvents(client, &event, 1, NoEventMask, - NoEventMask /* CantBeFiltered */, NullGrab); - return (client->noClientException); - } - else - { - client->errorValue = stuff->property; - return (BadAtom); - } -} - int ProcGrabServer(ClientPtr client) { @@ -3980,54 +3754,6 @@ SendErrorToClient(ClientPtr client, unsigned majorCode, unsigned minorCode, WriteEventsToClient (client, 1, (xEvent *)&rep); } -void -DeleteWindowFromAnySelections(WindowPtr pWin) -{ - int i; - - for (i = 0; i< NumCurrentSelections; i++) - if (CurrentSelections[i].pWin == pWin) - { - if (SelectionCallback) - { - SelectionInfoRec info; - - info.selection = &CurrentSelections[i]; - info.kind = SelectionWindowDestroy; - CallCallbacks(&SelectionCallback, &info); - } - dixFreePrivates(CurrentSelections[i].devPrivates); - CurrentSelections[i].pWin = (WindowPtr)NULL; - CurrentSelections[i].window = None; - CurrentSelections[i].client = NullClient; - CurrentSelections[i].devPrivates = NULL; - } -} - -static void -DeleteClientFromAnySelections(ClientPtr client) -{ - int i; - - for (i = 0; i< NumCurrentSelections; i++) - if (CurrentSelections[i].client == client) - { - if (SelectionCallback) - { - SelectionInfoRec info; - - info.selection = &CurrentSelections[i]; - info.kind = SelectionWindowDestroy; - CallCallbacks(&SelectionCallback, &info); - } - dixFreePrivates(CurrentSelections[i].devPrivates); - CurrentSelections[i].pWin = (WindowPtr)NULL; - CurrentSelections[i].window = None; - CurrentSelections[i].client = NullClient; - CurrentSelections[i].devPrivates = NULL; - } -} - void MarkClientException(ClientPtr client) { diff --git a/dix/main.c b/dix/main.c index 068dae92e..db4347341 100644 --- a/dix/main.c +++ b/dix/main.c @@ -93,6 +93,7 @@ Equipment Corporation. #include "colormap.h" #include "colormapst.h" #include "cursorstr.h" +#include "selection.h" #include #include "opaque.h" #include "servermd.h" @@ -346,6 +347,7 @@ main(int argc, char *argv[], char *envp[]) InitAtoms(); InitEvents(); + InitSelections(); InitGlyphCaching(); if (!dixResetPrivates()) FatalError("couldn't init private data storage"); diff --git a/dix/selection.c b/dix/selection.c new file mode 100644 index 000000000..e2e279a6f --- /dev/null +++ b/dix/selection.c @@ -0,0 +1,306 @@ +/************************************************************ + +Copyright 1987, 1989, 1998 The Open Group + +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. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP 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. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987, 1989 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +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 Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL 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 +#endif + +#include "windowstr.h" +#include "dixstruct.h" +#include "dispatch.h" +#include "selection.h" +#include "xace.h" + +/***************************************************************** + * Selection Stuff + * + * dixLookupSelection + * + * Selections are global to the server. The list of selections should + * not be traversed directly. Instead, use the functions listed above. + * + *****************************************************************/ + +_X_EXPORT Selection *CurrentSelections; +static int NumCurrentSelections; +CallbackListPtr SelectionCallback; + +_X_EXPORT int +dixLookupSelection(Selection **result, Atom selectionName, + ClientPtr client, Mask access_mode) +{ + Selection *pSel = NULL; + int i, rc = BadMatch; + client->errorValue = selectionName; + + for (i = 0; i < NumCurrentSelections; i++) + if (CurrentSelections[i].selection == selectionName) { + pSel = CurrentSelections + i; + rc = XaceHookSelectionAccess(client, selectionName, access_mode); + break; + } + + *result = pSel; + return rc; +} + +void +InitSelections(void) +{ + Selection *pSel = CurrentSelections; + + for (; pSel - CurrentSelections < NumCurrentSelections; pSel++) + dixFreePrivates(pSel->devPrivates); + + xfree(CurrentSelections); + CurrentSelections = NULL; + NumCurrentSelections = 0; +} + +static _X_INLINE void +CallSelectionCallback(Selection *pSel, ClientPtr client, + SelectionCallbackKind kind) +{ + SelectionInfoRec info = { pSel, client, kind }; + CallCallbacks(&SelectionCallback, &info); +} + +void +DeleteWindowFromAnySelections(WindowPtr pWin) +{ + Selection *pSel = CurrentSelections; + + for (; pSel - CurrentSelections < NumCurrentSelections; pSel++) + if (pSel->pWin == pWin) { + CallSelectionCallback(pSel, NULL, SelectionWindowDestroy); + + pSel->pWin = (WindowPtr)NULL; + pSel->window = None; + pSel->client = NullClient; + } +} + +void +DeleteClientFromAnySelections(ClientPtr client) +{ + Selection *pSel = CurrentSelections; + + for (; pSel - CurrentSelections < NumCurrentSelections; pSel++) + if (pSel->client == client) { + CallSelectionCallback(pSel, NULL, SelectionClientClose); + + pSel->pWin = (WindowPtr)NULL; + pSel->window = None; + pSel->client = NullClient; + } +} + +int +ProcSetSelectionOwner(ClientPtr client) +{ + WindowPtr pWin = NULL; + TimeStamp time; + Selection *pSel; + int rc; + + REQUEST(xSetSelectionOwnerReq); + REQUEST_SIZE_MATCH(xSetSelectionOwnerReq); + + UpdateCurrentTime(); + time = ClientTimeToServerTime(stuff->time); + + /* If the client's time stamp is in the future relative to the server's + time stamp, do not set the selection, just return success. */ + if (CompareTimeStamps(time, currentTime) == LATER) + return Success; + + if (stuff->window != None) { + rc = dixLookupWindow(&pWin, stuff->window, client, DixSetAttrAccess); + if (rc != Success) + return rc; + } + if (!ValidAtom(stuff->selection)) { + client->errorValue = stuff->selection; + return BadAtom; + } + + /* + * First, see if the selection is already set... + */ + rc = dixLookupSelection(&pSel, stuff->selection, client, DixSetAttrAccess); + + if (rc == Success) { + xEvent event; + + /* If the timestamp in client's request is in the past relative + to the time stamp indicating the last time the owner of the + selection was set, do not set the selection, just return + success. */ + if (CompareTimeStamps(time, pSel->lastTimeChanged) == EARLIER) + return Success; + if (pSel->client && (!pWin || (pSel->client != client))) + { + event.u.u.type = SelectionClear; + event.u.selectionClear.time = time.milliseconds; + event.u.selectionClear.window = pSel->window; + event.u.selectionClear.atom = pSel->selection; + TryClientEvents(pSel->client, &event, 1, NoEventMask, + NoEventMask /* CantBeFiltered */, NullGrab); + } + } + else if (rc == BadMatch) + { + /* + * It doesn't exist, so add it... + */ + int size = (NumCurrentSelections + 1) * sizeof(Selection); + CurrentSelections = xrealloc(CurrentSelections, size); + if (!CurrentSelections) { + NumCurrentSelections = 0; + return BadAlloc; + } + pSel = CurrentSelections + NumCurrentSelections; + pSel->selection = stuff->selection; + pSel->devPrivates = NULL; + pSel->next = NULL; + if (NumCurrentSelections > 0) + CurrentSelections[NumCurrentSelections - 1].next = pSel; + NumCurrentSelections++; + } + else + return rc; + + pSel->lastTimeChanged = time; + pSel->window = stuff->window; + pSel->pWin = pWin; + pSel->client = (pWin ? client : NullClient); + + CallSelectionCallback(pSel, client, SelectionSetOwner); + return client->noClientException; +} + +int +ProcGetSelectionOwner(ClientPtr client) +{ + int rc; + Selection *pSel; + xGetSelectionOwnerReply reply; + + REQUEST(xResourceReq); + REQUEST_SIZE_MATCH(xResourceReq); + + if (!ValidAtom(stuff->id)) { + client->errorValue = stuff->id; + return BadAtom; + } + + reply.type = X_Reply; + reply.length = 0; + reply.sequenceNumber = client->sequence; + + rc = dixLookupSelection(&pSel, stuff->id, client, DixGetAttrAccess); + if (rc == Success) + reply.owner = pSel->window; + else if (rc == BadMatch) + reply.owner = None; + else + return rc; + + WriteReplyToClient(client, sizeof(xGetSelectionOwnerReply), &reply); + return client->noClientException; +} + +int +ProcConvertSelection(ClientPtr client) +{ + Bool paramsOkay; + xEvent event; + WindowPtr pWin; + Selection *pSel; + int rc; + + REQUEST(xConvertSelectionReq); + REQUEST_SIZE_MATCH(xConvertSelectionReq); + + rc = dixLookupWindow(&pWin, stuff->requestor, client, DixSetAttrAccess); + if (rc != Success) + return rc; + + paramsOkay = ValidAtom(stuff->selection) && ValidAtom(stuff->target); + paramsOkay &= (stuff->property == None) || ValidAtom(stuff->property); + if (!paramsOkay) { + client->errorValue = stuff->property; + return BadAtom; + } + + rc = dixLookupSelection(&pSel, stuff->selection, client, DixReadAccess); + + if (rc != Success && rc != BadMatch) + return rc; + else if (rc == Success && pSel->window != None) { + event.u.u.type = SelectionRequest; + event.u.selectionRequest.owner = pSel->window; + event.u.selectionRequest.time = stuff->time; + event.u.selectionRequest.requestor = stuff->requestor; + event.u.selectionRequest.selection = stuff->selection; + event.u.selectionRequest.target = stuff->target; + event.u.selectionRequest.property = stuff->property; + if (TryClientEvents(pSel->client, &event, 1, NoEventMask, + NoEventMask /* CantBeFiltered */, NullGrab)) + return client->noClientException; + } + + event.u.u.type = SelectionNotify; + event.u.selectionNotify.time = stuff->time; + event.u.selectionNotify.requestor = stuff->requestor; + event.u.selectionNotify.selection = stuff->selection; + event.u.selectionNotify.target = stuff->target; + event.u.selectionNotify.property = None; + TryClientEvents(client, &event, 1, NoEventMask, + NoEventMask /* CantBeFiltered */, NullGrab); + return client->noClientException; +} diff --git a/hw/xfree86/loader/dixsym.c b/hw/xfree86/loader/dixsym.c index e6c37fe00..d035c762f 100644 --- a/hw/xfree86/loader/dixsym.c +++ b/hw/xfree86/loader/dixsym.c @@ -92,9 +92,6 @@ extern int XkbDfltRepeatDelay, XkbDfltRepeatInterval; #endif -extern Selection *CurrentSelections; -extern int NumCurrentSelections; - /* DIX things */ _X_HIDDEN void *dixLookupTab[] = { @@ -150,8 +147,6 @@ _X_HIDDEN void *dixLookupTab[] = { SYMVAR(isItTimeToYield) SYMVAR(ClientStateCallback) SYMVAR(ServerGrabCallback) - SYMVAR(CurrentSelections) - SYMVAR(NumCurrentSelections) /* dixfonts.c */ SYMFUNC(CloseFont) SYMFUNC(FontToXError) @@ -196,6 +191,9 @@ _X_HIDDEN void *dixLookupTab[] = { SYMFUNC(dixLookupProperty) SYMFUNC(ChangeWindowProperty) SYMFUNC(dixChangeWindowProperty) + /* selection.c */ + SYMFUNC(dixLookupSelection) + SYMVAR(CurrentSelections) /* extension.c */ SYMFUNC(AddExtension) SYMFUNC(AddExtensionAlias) diff --git a/include/dix.h b/include/dix.h index 52212e7e7..0790f5847 100644 --- a/include/dix.h +++ b/include/dix.h @@ -166,9 +166,6 @@ extern void SendErrorToClient( XID /*resId*/, int /*errorCode*/); -extern void DeleteWindowFromAnySelections( - WindowPtr /*pWin*/); - extern void MarkClientException( ClientPtr /*client*/); @@ -556,26 +553,6 @@ typedef struct { int count; } DeviceEventInfoRec; -/* - * SelectionCallback stuff - */ - -extern CallbackListPtr SelectionCallback; - -typedef enum { - SelectionSetOwner, - SelectionGetOwner, - SelectionConvertSelection, - SelectionWindowDestroy, - SelectionClientClose -} SelectionCallbackKind; - -typedef struct { - struct _Selection *selection; - ClientPtr client; - SelectionCallbackKind kind; -} SelectionInfoRec; - /* strcasecmp.c */ #if NEED_STRCASECMP #define strcasecmp xstrcasecmp diff --git a/include/selection.h b/include/selection.h index 859b6a3b5..dd9b056fe 100644 --- a/include/selection.h +++ b/include/selection.h @@ -1,7 +1,3 @@ - -#ifndef SELECTION_H -#define SELECTION_H 1 - /*********************************************************** Copyright 1987, 1998 The Open Group @@ -49,10 +45,13 @@ SOFTWARE. ******************************************************************/ +#ifndef SELECTION_H +#define SELECTION_H 1 + #include "dixstruct.h" #include "privates.h" + /* - * * Selection data structures */ @@ -62,11 +61,45 @@ typedef struct _Selection { Window window; WindowPtr pWin; ClientPtr client; - ClientPtr alt_client; /* support for redirection */ - Window alt_window; /* support for redirection */ + struct _Selection *next; PrivateRec *devPrivates; } Selection; + +/* + * Selection API + */ + +int dixLookupSelection(Selection **result, Atom name, + ClientPtr client, Mask access_mode); + +extern Selection *CurrentSelections; + +extern CallbackListPtr SelectionCallback; + +typedef enum { + SelectionSetOwner, + SelectionWindowDestroy, + SelectionClientClose +} SelectionCallbackKind; + +typedef struct { + struct _Selection *selection; + ClientPtr client; + SelectionCallbackKind kind; +} SelectionInfoRec; + + +/* + * Selection server internals + */ + +void InitSelections(void); + +void DeleteWindowFromAnySelections(WindowPtr pWin); + +void DeleteClientFromAnySelections(ClientPtr client); + #endif /* SELECTION_H */ From cc76ea6e3ac6a405f0c198c4e62be40aa8d2b546 Mon Sep 17 00:00:00 2001 From: Eamon Walsh Date: Fri, 29 Feb 2008 17:55:31 -0500 Subject: [PATCH 024/149] XACE: Add generic support for property and selection polyinstantiation. --- Xext/security.c | 2 +- Xext/xace.c | 9 +++++---- Xext/xace.h | 7 ++++--- Xext/xacestr.h | 4 ++-- Xext/xselinux.c | 29 +++++++++++++---------------- dix/property.c | 10 ++++++---- dix/selection.c | 6 +++++- 7 files changed, 36 insertions(+), 31 deletions(-) diff --git a/Xext/security.c b/Xext/security.c index cd67120d9..e82b97626 100644 --- a/Xext/security.c +++ b/Xext/security.c @@ -910,7 +910,7 @@ SecurityProperty(CallbackListPtr *pcbl, pointer unused, pointer calldata) { XacePropertyAccessRec *rec = calldata; SecurityStateRec *subj, *obj; - ATOM name = rec->pProp->propertyName; + ATOM name = (*rec->ppProp)->propertyName; Mask requested = rec->access_mode; Mask allowed = SecurityResourceMask | DixReadAccess; diff --git a/Xext/xace.c b/Xext/xace.c index e88debc5f..8a8f8c61d 100644 --- a/Xext/xace.c +++ b/Xext/xace.c @@ -56,16 +56,17 @@ int XaceHookDispatch(ClientPtr client, int major) } int XaceHookPropertyAccess(ClientPtr client, WindowPtr pWin, - PropertyPtr pProp, Mask access_mode) + PropertyPtr *ppProp, Mask access_mode) { - XacePropertyAccessRec rec = { client, pWin, pProp, access_mode, Success }; + XacePropertyAccessRec rec = { client, pWin, ppProp, access_mode, Success }; CallCallbacks(&XaceHooks[XACE_PROPERTY_ACCESS], &rec); return rec.status; } -int XaceHookSelectionAccess(ClientPtr client, Atom name, Mask access_mode) +int XaceHookSelectionAccess(ClientPtr client, + Selection **ppSel, Mask access_mode) { - XaceSelectionAccessRec rec = { client, name, access_mode, Success }; + XaceSelectionAccessRec rec = { client, ppSel, access_mode, Success }; CallCallbacks(&XaceHooks[XACE_SELECTION_ACCESS], &rec); return rec.status; } diff --git a/Xext/xace.h b/Xext/xace.h index 1f07d9fd2..bd69bca98 100644 --- a/Xext/xace.h +++ b/Xext/xace.h @@ -29,6 +29,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "region.h" #include "window.h" #include "property.h" +#include "selection.h" /* Default window background */ #define XaceBackgroundNoneState(w) ((w)->forcedBG ? BackgroundPixel : None) @@ -68,9 +69,9 @@ extern int XaceHook( */ extern int XaceHookDispatch(ClientPtr ptr, int major); extern int XaceHookPropertyAccess(ClientPtr ptr, WindowPtr pWin, - PropertyPtr pProp, Mask access_mode); -extern int XaceHookSelectionAccess(ClientPtr ptr, Atom name, - Mask access_mode); + PropertyPtr *ppProp, Mask access_mode); +extern int XaceHookSelectionAccess(ClientPtr ptr, + Selection **ppSel, Mask access_mode); extern void XaceHookAuditEnd(ClientPtr ptr, int result); /* Register a callback for a given hook. diff --git a/Xext/xacestr.h b/Xext/xacestr.h index e31d4246a..ba115a427 100644 --- a/Xext/xacestr.h +++ b/Xext/xacestr.h @@ -59,7 +59,7 @@ typedef struct { typedef struct { ClientPtr client; WindowPtr pWin; - PropertyPtr pProp; + PropertyPtr *ppProp; Mask access_mode; int status; } XacePropertyAccessRec; @@ -110,7 +110,7 @@ typedef struct { /* XACE_SELECTION_ACCESS */ typedef struct { ClientPtr client; - Atom name; + Selection **ppSel; Mask access_mode; int status; } XaceSelectionAccessRec; diff --git a/Xext/xselinux.c b/Xext/xselinux.c index 8d66ea199..a7d3999b0 100644 --- a/Xext/xselinux.c +++ b/Xext/xselinux.c @@ -134,7 +134,7 @@ static struct security_class_mapping map[] = { { "x_gc", { "", "", "destroy", "create", "getattr", "setattr", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "use", NULL }}, { "x_font", { "", "", "destroy", "create", "getattr", "", "", "", "", "", "", "", "add_glyph", "remove_glyph", "", "", "", "", "", "", "", "", "", "", "use", NULL }}, { "x_colormap", { "read", "write", "destroy", "create", "getattr", "", "", "", "", "", "", "", "add_color", "remove_color", "", "", "", "", "", "", "install", "uninstall", "", "", "use", NULL }}, - { "x_property", { "read", "write", "destroy", "create", "getattr", "setattr", NULL }}, + { "x_property", { "read", "write", "destroy", "create", "getattr", "setattr", "", "", "", "", "", "", "", "", "", "", "write", NULL }}, { "x_selection", { "read", "", "", "", "getattr", "setattr", NULL }}, { "x_cursor", { "read", "write", "destroy", "create", "getattr", "setattr", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "use", NULL }}, { "x_client", { "", "", "destroy", "", "getattr", "setattr", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "manage", NULL }}, @@ -691,14 +691,15 @@ SELinuxProperty(CallbackListPtr *pcbl, pointer unused, pointer calldata) SELinuxSubjectRec *subj; SELinuxObjectRec *obj; SELinuxAuditRec auditdata = { .client = rec->client }; + PropertyPtr pProp = *rec->ppProp; int rc; subj = dixLookupPrivate(&rec->client->devPrivates, subjectKey); - obj = dixLookupPrivate(&rec->pProp->devPrivates, objectKey); + obj = dixLookupPrivate(&pProp->devPrivates, objectKey); /* If this is a new object that needs labeling, do it now */ if (rec->access_mode & DixCreateAccess) { - const char *name = NameForAtom(rec->pProp->propertyName); + const char *name = NameForAtom(pProp->propertyName); security_context_t con; security_id_t sid; @@ -729,7 +730,7 @@ SELinuxProperty(CallbackListPtr *pcbl, pointer unused, pointer calldata) } /* Perform the security check */ - auditdata.property = rec->pProp->propertyName; + auditdata.property = pProp->propertyName; rc = SELinuxDoCheck(subj, obj, SECCLASS_X_PROPERTY, rec->access_mode, &auditdata); if (rc != Success) @@ -870,17 +871,21 @@ SELinuxSelection(CallbackListPtr *pcbl, pointer unused, pointer calldata) SELinuxSubjectRec *subj; SELinuxObjectRec sel_sid; SELinuxAuditRec auditdata = { .client = rec->client }; + Selection *pSel = *rec->ppSel; int rc; + if (rec->access_mode & DixCreateAccess) + return; /* don't use create currently */ + subj = dixLookupPrivate(&rec->client->devPrivates, subjectKey); - rc = SELinuxSelectionToSID(rec->name, &sel_sid); + rc = SELinuxSelectionToSID(pSel->selection, &sel_sid); if (rc != Success) { rec->status = rc; return; } - auditdata.selection = rec->name; + auditdata.selection = pSel->selection; rc = SELinuxDoCheck(subj, &sel_sid, SECCLASS_X_SELECTION, rec->access_mode, &auditdata); if (rc != Success) @@ -1206,16 +1211,8 @@ ProcSELinuxGetPropertyContext(ClientPtr client) if (rc != Success) return rc; - pProp = wUserProps(pWin); - while (pProp) { - if (pProp->propertyName == stuff->property) - break; - pProp = pProp->next; - } - if (!pProp) - return BadValue; - - rc = XaceHookPropertyAccess(client, pWin, pProp, DixGetAttrAccess); + rc = dixLookupProperty(&pProp, pWin, stuff->property, client, + DixGetAttrAccess); if (rc != Success) return rc; diff --git a/dix/property.c b/dix/property.c index e74becfa2..8b66ad6a2 100644 --- a/dix/property.c +++ b/dix/property.c @@ -103,7 +103,7 @@ dixLookupProperty(PropertyPtr *result, WindowPtr pWin, Atom propertyName, break; if (pProp) - rc = XaceHookPropertyAccess(client, pWin, pProp, access_mode); + rc = XaceHookPropertyAccess(client, pWin, &pProp, access_mode); *result = pProp; return rc; } @@ -256,12 +256,14 @@ dixChangeWindowProperty(ClientPtr pClient, WindowPtr pWin, Atom property, PropertyPtr pProp; int sizeInBytes, totalSize, rc; pointer data; + Mask access_mode; sizeInBytes = format>>3; totalSize = len * sizeInBytes; + access_mode = (mode == PropModeReplace) ? DixWriteAccess : DixBlendAccess; /* first see if property already exists */ - rc = dixLookupProperty(&pProp, pWin, property, pClient, DixWriteAccess); + rc = dixLookupProperty(&pProp, pWin, property, pClient, access_mode); if (rc == BadMatch) /* just add to list */ { @@ -284,7 +286,7 @@ dixChangeWindowProperty(ClientPtr pClient, WindowPtr pWin, Atom property, memmove((char *)data, (char *)value, totalSize); pProp->size = len; pProp->devPrivates = NULL; - rc = XaceHookPropertyAccess(pClient, pWin, pProp, + rc = XaceHookPropertyAccess(pClient, pWin, &pProp, DixCreateAccess|DixWriteAccess); if (rc != Success) { xfree(data); @@ -588,7 +590,7 @@ ProcListProperties(ClientPtr client) temppAtoms = pAtoms; for (pProp = wUserProps(pWin); pProp; pProp = pProp->next) { realProp = pProp; - rc = XaceHookPropertyAccess(client, pWin, pProp, DixGetAttrAccess); + rc = XaceHookPropertyAccess(client, pWin, &realProp, DixGetAttrAccess); if (rc == Success && realProp == pProp) { *temppAtoms++ = pProp->propertyName; numProps++; diff --git a/dix/selection.c b/dix/selection.c index e2e279a6f..52b1611c5 100644 --- a/dix/selection.c +++ b/dix/selection.c @@ -80,7 +80,7 @@ dixLookupSelection(Selection **result, Atom selectionName, for (i = 0; i < NumCurrentSelections; i++) if (CurrentSelections[i].selection == selectionName) { pSel = CurrentSelections + i; - rc = XaceHookSelectionAccess(client, selectionName, access_mode); + rc = XaceHookSelectionAccess(client, &pSel, access_mode); break; } @@ -206,6 +206,10 @@ ProcSetSelectionOwner(ClientPtr client) pSel = CurrentSelections + NumCurrentSelections; pSel->selection = stuff->selection; pSel->devPrivates = NULL; + + /* security creation/labeling check */ + (void)XaceHookSelectionAccess(client, &pSel, DixCreateAccess); + pSel->next = NULL; if (NumCurrentSelections > 0) CurrentSelections[NumCurrentSelections - 1].next = pSel; From ef60632e200853680282016e32a7a9fb01882852 Mon Sep 17 00:00:00 2001 From: Eamon Walsh Date: Fri, 29 Feb 2008 18:00:27 -0500 Subject: [PATCH 025/149] dix: Modify callers of property and selection API to use new interfaces. --- hw/xfree86/common/xf86Init.c | 11 ++++---- hw/xprint/pcl/PclMisc.c | 17 +++++------- hw/xprint/pcl/PclWindow.c | 6 ++--- hw/xprint/ps/PsMisc.c | 17 +++++------- hw/xprint/ps/PsWindow.c | 6 ++--- hw/xquartz/applewm.c | 14 ++++------ hw/xquartz/quartzPasteboard.c | 48 ++++++++++++++------------------- hw/xquartz/xpr/xprFrame.c | 4 +-- hw/xwin/winwin32rootless.c | 4 +-- miext/rootless/rootlessWindow.c | 4 +-- xkb/xkbInit.c | 4 +-- 11 files changed, 58 insertions(+), 77 deletions(-) diff --git a/hw/xfree86/common/xf86Init.c b/hw/xfree86/common/xf86Init.c index d1603c081..6d5eaadc3 100644 --- a/hw/xfree86/common/xf86Init.c +++ b/hw/xfree86/common/xf86Init.c @@ -172,12 +172,11 @@ xf86CreateRootWindow(WindowPtr pWin) Atom prop; prop = MakeAtom(pProp->name, strlen(pProp->name), TRUE); - err = ChangeWindowProperty(pWin, - prop, pProp->type, - pProp->format, PropModeReplace, - pProp->size, pProp->data, - FALSE - ); + err = dixChangeWindowProperty(serverClient, pWin, + prop, pProp->type, + pProp->format, PropModeReplace, + pProp->size, pProp->data, + FALSE); } /* Look at err */ diff --git a/hw/xprint/pcl/PclMisc.c b/hw/xprint/pcl/PclMisc.c index e0b7dced9..0b37836e9 100644 --- a/hw/xprint/pcl/PclMisc.c +++ b/hw/xprint/pcl/PclMisc.c @@ -115,7 +115,7 @@ GetPropString( if(atom != BAD_RESOURCE) { WindowPtr pPropWin; - int n; + int rc, n; /* * The atom has been defined, but it might only exist as a @@ -124,15 +124,12 @@ GetPropString( for(pPropWin = pWin; pPropWin != (WindowPtr)NULL; pPropWin = pPropWin->parent) { - for(pProp = (PropertyPtr)(wUserProps(pPropWin)); - pProp != (PropertyPtr)NULL; - pProp = pProp->next) - { - if (pProp->propertyName == atom) - break; - } - if(pProp != (PropertyPtr)NULL) - break; + rc = dixLookupProperty(&pProp, pPropWin, atom, + serverClient, DixReadAccess); + if (rc == Success) + break; + else + pProp = NULL; } if(pProp == (PropertyPtr)NULL) return (char *)NULL; diff --git a/hw/xprint/pcl/PclWindow.c b/hw/xprint/pcl/PclWindow.c index a87dc0e7a..950933e49 100644 --- a/hw/xprint/pcl/PclWindow.c +++ b/hw/xprint/pcl/PclWindow.c @@ -128,9 +128,9 @@ PclCreateWindow( { propName = MakeAtom(propStrings[i], strlen(propStrings[i]), TRUE); - ChangeWindowProperty(pWin, propName, XA_STRING, 8, - PropModeReplace, strlen(propVal), - (pointer)propVal, FALSE); + dixChangeWindowProperty(serverClient, pWin, propName, XA_STRING, + 8, PropModeReplace, strlen(propVal), + (pointer)propVal, FALSE); xfree(propVal); } } diff --git a/hw/xprint/ps/PsMisc.c b/hw/xprint/ps/PsMisc.c index 0df039e0b..8d5005f91 100644 --- a/hw/xprint/ps/PsMisc.c +++ b/hw/xprint/ps/PsMisc.c @@ -175,7 +175,7 @@ GetPropString( if(atom != BAD_RESOURCE) { WindowPtr pPropWin; - int n; + int rc, n; */ /* @@ -186,15 +186,12 @@ GetPropString( for(pPropWin = pWin; pPropWin != (WindowPtr)NULL; pPropWin = pPropWin->parent) { - for(pProp = (PropertyPtr)(wUserProps(pPropWin)); - pProp != (PropertyPtr)NULL; - pProp = pProp->next) - { - if (pProp->propertyName == atom) - break; - } - if(pProp != (PropertyPtr)NULL) - break; + rc = dixLookupProperty(&pProp, pPropWin, atom, + serverClient, DixReadAccess); + if (rc == Success) + break; + else + pProp = NULL; } if(pProp == (PropertyPtr)NULL) return (char *)NULL; diff --git a/hw/xprint/ps/PsWindow.c b/hw/xprint/ps/PsWindow.c index d17cf8ce0..8bfde4b0d 100644 --- a/hw/xprint/ps/PsWindow.c +++ b/hw/xprint/ps/PsWindow.c @@ -154,9 +154,9 @@ PsCreateWindow(WindowPtr pWin) { propName = MakeAtom(propStrings[i], strlen(propStrings[i]), TRUE); - ChangeWindowProperty(pWin, propName, XA_STRING, 8, - PropModeReplace, strlen(propVal), - (pointer)propVal, FALSE); + dixChangeWindowProperty(serverClient, pWin, propName, XA_STRING, + 8, PropModeReplace, strlen(propVal), + (pointer)propVal, FALSE); xfree(propVal); } } diff --git a/hw/xquartz/applewm.c b/hw/xquartz/applewm.c index c460ec6ae..072e57ff4 100644 --- a/hw/xquartz/applewm.c +++ b/hw/xquartz/applewm.c @@ -154,8 +154,8 @@ AppleWMSetScreenOrigin( data[1] = (dixScreenOrigins[pWin->drawable.pScreen->myNum].y + darwinMainScreenY); - ChangeWindowProperty(pWin, xa_native_screen_origin(), XA_INTEGER, - 32, PropModeReplace, 2, data, TRUE); + dixChangeWindowProperty(serverClient, pWin, xa_native_screen_origin(), + XA_INTEGER, 32, PropModeReplace, 2, data, TRUE); } /* Window managers can set the _APPLE_NO_ORDER_IN property on windows @@ -169,15 +169,11 @@ AppleWMDoReorderWindow( { Atom atom; PropertyPtr prop; + int rc; atom = xa_apple_no_order_in(); - for (prop = wUserProps(pWin); prop != NULL; prop = prop->next) - { - if (prop->propertyName == atom && prop->type == atom) - return FALSE; - } - - return TRUE; + rc = dixLookupProperty(&prop, pWin, atom, serverClient, DixReadAccess); + return (rc == Success) && (prop->type == atom); } diff --git a/hw/xquartz/quartzPasteboard.c b/hw/xquartz/quartzPasteboard.c index 0cecff54a..0bf84f5d5 100644 --- a/hw/xquartz/quartzPasteboard.c +++ b/hw/xquartz/quartzPasteboard.c @@ -43,9 +43,6 @@ #include "selection.h" #include "globals.h" -extern Selection *CurrentSelections; -extern int NumCurrentSelections; - // Helper function to read the X11 cut buffer // FIXME: What about multiple screens? Currently, this reads the first @@ -54,18 +51,16 @@ extern int NumCurrentSelections; // Returns NULL if there is no cut text or there is not enough memory. static char * QuartzReadCutBuffer(void) { - int i; + int rc, i; char *text = NULL; for (i = 0; i < screenInfo.numScreens; i++) { ScreenPtr pScreen = screenInfo.screens[i]; PropertyPtr pProp; - pProp = wUserProps (WindowTable[pScreen->myNum]); - while (pProp && pProp->propertyName != XA_CUT_BUFFER0) { - pProp = pProp->next; - } - if (! pProp) continue; + rc = dixLookupProperty(&pProp, WindowTable[pScreen->myNum], + XA_CUT_BUFFER0, serverClient, DixReadAccess); + if (rc != Success) continue; if (pProp->type != XA_STRING) continue; if (pProp->format != 8) continue; @@ -108,43 +103,40 @@ void QuartzReadPasteboard(void) if ((text && oldText && !strequal(text, oldText)) || (text && !oldText)) { - int scrn, sel; + int scrn, rc; + Selection *pSel; for (scrn = 0; scrn < screenInfo.numScreens; scrn++) { ScreenPtr pScreen = screenInfo.screens[scrn]; // Set the cut buffers on each screen // fixme really on each screen? - ChangeWindowProperty(WindowTable[pScreen->myNum], XA_CUT_BUFFER0, - XA_STRING, 8, PropModeReplace, - strlen(text), (pointer)text, TRUE); + dixChangeWindowProperty(serverClient, WindowTable[pScreen->myNum], + XA_CUT_BUFFER0, XA_STRING, 8, PropModeReplace, + strlen(text), (pointer)text, TRUE); } // Undo any current X selection (similar to code in dispatch.c) // FIXME: what about secondary selection? // FIXME: only touch first XA_PRIMARY selection? - sel = 0; - while ((sel < NumCurrentSelections) && - CurrentSelections[sel].selection != XA_PRIMARY) - sel++; - if (sel < NumCurrentSelections) { + rc = dixLookupSelection(&pSel, XA_PRIMARY, serverClient, + DixSetAttrAccess); + if (rc == Success) { // Notify client if necessary - if (CurrentSelections[sel].client) { + if (pSel->client) { xEvent event; event.u.u.type = SelectionClear; event.u.selectionClear.time = GetTimeInMillis(); - event.u.selectionClear.window = CurrentSelections[sel].window; - event.u.selectionClear.atom = CurrentSelections[sel].selection; - TryClientEvents(CurrentSelections[sel].client, &event, 1, - NoEventMask, NoEventMask /*CantBeFiltered*/, - NullGrab); + event.u.selectionClear.window = pSel->window; + event.u.selectionClear.atom = pSel->selection; + TryClientEvents(pSel->client, &event, 1, NoEventMask, + NoEventMask /*CantBeFiltered*/, NullGrab); } // Erase it - // FIXME: need to erase .selection too? dispatch.c doesn't - CurrentSelections[sel].pWin = NullWindow; - CurrentSelections[sel].window = None; - CurrentSelections[sel].client = NullClient; + pSel->pWin = NullWindow; + pSel->window = None; + pSel->client = NullClient; } } diff --git a/hw/xquartz/xpr/xprFrame.c b/hw/xquartz/xpr/xprFrame.c index b9a33de90..864ef0d40 100644 --- a/hw/xquartz/xpr/xprFrame.c +++ b/hw/xquartz/xpr/xprFrame.c @@ -90,8 +90,8 @@ xprSetNativeProperty(RootlessWindowPtr pFrame) /* FIXME: move this to AppleWM extension */ data = native_id; - ChangeWindowProperty(pFrame->win, xa_native_window_id(), - XA_INTEGER, 32, PropModeReplace, 1, &data, TRUE); + dixChangeWindowProperty(serverClient, pFrame->win, xa_native_window_id(), + XA_INTEGER, 32, PropModeReplace, 1, &data, TRUE); } } diff --git a/hw/xwin/winwin32rootless.c b/hw/xwin/winwin32rootless.c index 4b4cd3ded..6f4e2c97e 100755 --- a/hw/xwin/winwin32rootless.c +++ b/hw/xwin/winwin32rootless.c @@ -1087,6 +1087,6 @@ winMWExtWMSetNativeProperty (RootlessWindowPtr pFrame) /* FIXME: move this to WindowsWM extension */ lData = (long) pRLWinPriv->hWnd; - ChangeWindowProperty (pFrame->win, AtmWindowsWmNativeHwnd (), - XA_INTEGER, 32, PropModeReplace, 1, &lData, TRUE); + dixChangeWindowProperty(serverClient, pFrame->win, AtmWindowsWmNativeHwnd(), + XA_INTEGER, 32, PropModeReplace, 1, &lData, TRUE); } diff --git a/miext/rootless/rootlessWindow.c b/miext/rootless/rootlessWindow.c index 7285f959d..0dad44a99 100644 --- a/miext/rootless/rootlessWindow.c +++ b/miext/rootless/rootlessWindow.c @@ -181,8 +181,8 @@ set_screen_origin (WindowPtr pWin) data[1] = (dixScreenOrigins[pWin->drawable.pScreen->myNum].y + darwinMainScreenY); - ChangeWindowProperty (pWin, xa_native_screen_origin (), XA_INTEGER, - 32, PropModeReplace, 2, data, TRUE); + dixChangeWindowProperty(serverClient, pWin, xa_native_screen_origin(), + XA_INTEGER, 32, PropModeReplace, 2, data, TRUE); } /* diff --git a/xkb/xkbInit.c b/xkb/xkbInit.c index 2b5f1fb68..c0afad026 100644 --- a/xkb/xkbInit.c +++ b/xkb/xkbInit.c @@ -222,8 +222,8 @@ char * pval; ErrorF("Internal Error! bad size (%d!=%d) for _XKB_RULES_NAMES\n", out,len); } - ChangeWindowProperty(WindowTable[0],name,XA_STRING,8,PropModeReplace, - len,pval,True); + dixChangeWindowProperty(serverClient, WindowTable[0], name, XA_STRING, 8, + PropModeReplace, len, pval, True); xfree(pval); return True; } From 8af2c39bcc4ddc4693d5a2597c9622fa17b6c272 Mon Sep 17 00:00:00 2001 From: Maarten Maathuis Date: Sat, 1 Mar 2008 16:54:01 +0100 Subject: [PATCH 026/149] Fix big mistake in commit fd41f46ac62033a724bd1f4612f19448a21c1224. - When a mode is deleted, the name pointer is also free()'ed. - This leaves other modes with an invalid pointer. --- hw/xfree86/modes/xf86Modes.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/hw/xfree86/modes/xf86Modes.c b/hw/xfree86/modes/xf86Modes.c index d6aa61aaf..9e3151254 100644 --- a/hw/xfree86/modes/xf86Modes.c +++ b/hw/xfree86/modes/xf86Modes.c @@ -214,8 +214,15 @@ xf86DuplicateMode(DisplayModePtr pMode) *pNew = *pMode; pNew->next = NULL; pNew->prev = NULL; - if (pNew->name == NULL) + /* + * It is important to copy the name explicitly. + * Otherwise a mode could reference an invalid piece of memory, after one of them runs free(). + * This will lead to obscure problems, that you really don't want. + */ + if (pMode->name == NULL) xf86SetModeDefaultName(pNew); + else + pNew->name = xnfstrdup(pMode->name); return pNew; } From cdd46aa3cd2e720558186cdbe48d871ab385fcdd Mon Sep 17 00:00:00 2001 From: George Sapountzis Date: Sat, 1 Mar 2008 15:57:57 +0200 Subject: [PATCH 027/149] configure: minor cleanup - dmx - darwin: remove from xorg options - xephyr: libxv is client lib --- configure.ac | 118 +++++++++++++++++++++++---------------------------- 1 file changed, 54 insertions(+), 64 deletions(-) diff --git a/configure.ac b/configure.ac index 10aa24158..ebbf87746 100644 --- a/configure.ac +++ b/configure.ac @@ -293,7 +293,6 @@ dnl Bus options and CPU capabilities. Replaces logic in dnl hw/xfree86/os-support/bus/Makefile.am, among others. dnl --------------------------------------------------------------------------- DEFAULT_INT10="x86emu" -use_x86_asm="no" dnl Override defaults as needed for specific platforms: @@ -310,10 +309,8 @@ case $host_cpu in ARM_VIDEO=yes ;; i*86) - use_x86_asm="yes" I386_VIDEO=yes case $host_os in - darwin*) use_x86_asm="no" ;; *linux*) DEFAULT_INT10=vm86 ;; *freebsd*) AC_DEFINE(USE_DEV_IO) ;; *netbsd*) AC_DEFINE(USE_I386_IOPL) @@ -337,10 +334,8 @@ case $host_cpu in GLX_ARCH_DEFINES="-D__GLX_ALIGN64" ;; x86_64*|amd64*) - use_x86_asm="yes" I386_VIDEO=yes case $host_os in - darwin*) use_x86_asm="no" ;; *freebsd*) AC_DEFINE(USE_DEV_IO, 1, [BSD /dev/io]) ;; *netbsd*) AC_DEFINE(USE_I386_IOPL, 1, [BSD i386 iopl]) SYS_LIBS=-lx86_64 @@ -758,7 +753,6 @@ if test "x$XV" = xyes; then AC_DEFINE(XV, 1, [Support Xv extension]) AC_DEFINE(XvExtension, 1, [Build Xv extension]) REQUIRED_MODULES="$REQUIRED_MODULES videoproto" - PKG_CHECK_MODULES(XV, [xv >= 0.22]) else XVMC=no fi @@ -1160,9 +1154,6 @@ if test "x$GCC" = "xyes"; then LD_EXPORT_SYMBOLS_FLAG="-rdynamic" fi case $host_os in - darwin*) - LD_EXPORT_SYMBOLS_FLAG="" - ;; openbsd*) LD_EXPORT_SYMBOLS_FLAG="-Wl,--export-dynamic" ;; @@ -1423,17 +1414,9 @@ if test "x$XORG" = xyes -o "x$XGL" = xyes; then esac case $host_cpu in - i*86) - case $host_os in - darwin*) ;; - *bsd*) ;; - linux*) ;; - *) xorg_bus_ix86pci=yes ;; - esac - ;; powerpc*) case $host_os in - darwin*|linux*|freebsd*|netbsd*|openbsd*|kfreebsd*-gnu) + linux*|freebsd*|netbsd*|openbsd*|kfreebsd*-gnu) ;; *) xorg_bus_ppcpci="yes" @@ -1444,9 +1427,9 @@ if test "x$XORG" = xyes -o "x$XGL" = xyes; then xorg_bus_sparcpci="yes" xorg_bus_sparc="yes" ;; - x86_64*|amd64*) + i*86|x86_64*|amd64*) case $host_os in - darwin*|*bsd*|linux*) + *bsd*|linux*) ;; *) xorg_bus_ix86pci="yes" @@ -1649,17 +1632,17 @@ fi AC_MSG_RESULT([$XWIN]) if test "x$XWIN" = xyes; then - XWIN_SERVER_NAME=XWin case $host_os in cygwin*) + XWIN_SERVER_NAME=XWin PKG_CHECK_MODULES([XWINMODULES],[x11 xdmcp xau xfont]) AC_DEFINE(HAS_DEVWINDOWS,1,[Cygwin has /dev/windows for signaling new win32 messages]) AC_DEFINE(ROOTLESS,1,[Build Rootless code]) CFLAGS="$CFLAGS -DFD_SETSIZE=256" ;; mingw*) - PKG_CHECK_MODULES([XWINMODULES],[x11 xdmcp xau xfont]) XWIN_SERVER_NAME=Xming + PKG_CHECK_MODULES([XWINMODULES],[x11 xdmcp xau xfont]) AC_DEFINE(RELOCATE_PROJECTROOT,1,[Make PROJECT_ROOT relative to the xserver location]) AC_DEFINE(HAS_WINSOCK,1,[Use Windows sockets]) XWIN_SYS_LIBS=-lwinsock2 @@ -1755,10 +1738,6 @@ if test "x$XQUARTZ" = xyes; then AC_MSG_NOTICE([Disabling DGA extension]) DGA=no fi - if test "x$DMX" = xyes || test "x$DMX" = xauto; then - AC_MSG_NOTICE([Disabling DMX DDX]) - DMX=no - fi fi # Support for objc in autotools is minimal and not documented. @@ -1801,51 +1780,58 @@ if test "x$LAUNCHD" = "xyes" ; then fi AM_CONDITIONAL(LAUNCHD, [test "x$LAUNCHD" = "xyes"]) + +dnl DMX DDX + AC_MSG_CHECKING([whether to build Xdmx DDX]) PKG_CHECK_MODULES([DMXMODULES], [xmuu xext x11 xrender xfixes xfont xi dmxproto xau $XDMCP_MODULES], [have_dmx=yes], [have_dmx=no]) if test "x$DMX" = xauto; then - DMX="$have_dmx" + DMX="$have_dmx" + case $host_os in + cygwin*) DMX="no" ;; + darwin*) DMX="no" ;; + esac fi AC_MSG_RESULT([$DMX]) AM_CONDITIONAL(DMX, [test "x$DMX" = xyes]) if test "x$DMX" = xyes; then - if test "x$have_dmx" = xno; then - AC_MSG_ERROR([Xdmx build explicitly requested, but required - modules not found.]) - fi - DMX_INCLUDES="$XEXT_INC $RENDER_INC $XTRAP_INC $RECORD_INC" - XDMX_CFLAGS="$DMXMODULES_CFLAGS" - XDMX_LIBS="$XEXT_LIB $FB_LIB $CONFIG_LIB $RENDER_LIB $XTRAP_LIB $RECORD_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $MIEXT_SHADOW_LIB $MIEXT_DAMAGE_LIB" - XDMX_SYS_LIBS="$DMXMODULES_LIBS" - AC_SUBST([XDMX_CFLAGS]) - AC_SUBST([XDMX_LIBS]) - AC_SUBST([XDMX_SYS_LIBS]) + if test "x$have_dmx" = xno; then + AC_MSG_ERROR([Xdmx build explicitly requested, but required + modules not found.]) + fi + DMX_INCLUDES="$XEXT_INC $RENDER_INC $XTRAP_INC $RECORD_INC" + XDMX_CFLAGS="$DMXMODULES_CFLAGS" + XDMX_LIBS="$XEXT_LIB $FB_LIB $CONFIG_LIB $RENDER_LIB $XTRAP_LIB $RECORD_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $MIEXT_SHADOW_LIB $MIEXT_DAMAGE_LIB" + XDMX_SYS_LIBS="$DMXMODULES_LIBS" + AC_SUBST([XDMX_CFLAGS]) + AC_SUBST([XDMX_LIBS]) + AC_SUBST([XDMX_SYS_LIBS]) dnl USB sources in DMX require - AC_CHECK_HEADER([linux/input.h], DMX_BUILD_USB="yes", - DMX_BUILD_USB="no") + AC_CHECK_HEADER([linux/input.h], DMX_BUILD_USB="yes", + DMX_BUILD_USB="no") dnl Linux sources in DMX require - AC_CHECK_HEADER([linux/keyboard.h], DMX_BUILD_LNX="yes", - DMX_BUILD_LNX="no") - if test "x$GLX" = xyes; then - PKG_CHECK_MODULES([GL], [glproto]) - fi - PKG_CHECK_MODULES([XDMXCONFIG_DEP], [xaw7 xmu xt xpm x11]) - AC_SUBST(XDMXCONFIG_DEP_CFLAGS) - AC_SUBST(XDMXCONFIG_DEP_LIBS) - PKG_CHECK_MODULES([DMXEXAMPLES_DEP], [dmx xext x11]) - AC_SUBST(DMXEXAMPLES_DEP_LIBS) - PKG_CHECK_MODULES([DMXXMUEXAMPLES_DEP], [dmx xmu xext x11]) - AC_SUBST(DMXXMUEXAMPLES_DEP_LIBS) - PKG_CHECK_MODULES([DMXXIEXAMPLES_DEP], [dmx xi xext x11]) - AC_SUBST(DMXXIEXAMPLES_DEP_LIBS) - PKG_CHECK_MODULES([XTSTEXAMPLES_DEP], [xtst xext x11]) - AC_SUBST(XTSTEXAMPLES_DEP_LIBS) - PKG_CHECK_MODULES([XRESEXAMPLES_DEP], [xres xext x11]) - AC_SUBST(XRESEXAMPLES_DEP_LIBS) - PKG_CHECK_MODULES([X11EXAMPLES_DEP], [xext x11]) - AC_SUBST(X11EXAMPLES_DEP_LIBS) + AC_CHECK_HEADER([linux/keyboard.h], DMX_BUILD_LNX="yes", + DMX_BUILD_LNX="no") + if test "x$GLX" = xyes; then + PKG_CHECK_MODULES([GL], [glproto]) + fi + PKG_CHECK_MODULES([XDMXCONFIG_DEP], [xaw7 xmu xt xpm x11]) + AC_SUBST(XDMXCONFIG_DEP_CFLAGS) + AC_SUBST(XDMXCONFIG_DEP_LIBS) + PKG_CHECK_MODULES([DMXEXAMPLES_DEP], [dmx xext x11]) + AC_SUBST(DMXEXAMPLES_DEP_LIBS) + PKG_CHECK_MODULES([DMXXMUEXAMPLES_DEP], [dmx xmu xext x11]) + AC_SUBST(DMXXMUEXAMPLES_DEP_LIBS) + PKG_CHECK_MODULES([DMXXIEXAMPLES_DEP], [dmx xi xext x11]) + AC_SUBST(DMXXIEXAMPLES_DEP_LIBS) + PKG_CHECK_MODULES([XTSTEXAMPLES_DEP], [xtst xext x11]) + AC_SUBST(XTSTEXAMPLES_DEP_LIBS) + PKG_CHECK_MODULES([XRESEXAMPLES_DEP], [xres xext x11]) + AC_SUBST(XRESEXAMPLES_DEP_LIBS) + PKG_CHECK_MODULES([X11EXAMPLES_DEP], [xext x11]) + AC_SUBST(X11EXAMPLES_DEP_LIBS) fi AM_CONDITIONAL([DMX_BUILD_LNX], [test "x$DMX_BUILD_LNX" = xyes]) AM_CONDITIONAL([DMX_BUILD_USB], [test "x$DMX_BUILD_USB" = xyes]) @@ -1909,7 +1895,11 @@ if test "$KDRIVE" = yes; then XSDL_INCS="`sdl-config --cflags` $XSERVER_CFLAGS" fi - PKG_CHECK_MODULES(XEPHYR, x11 xext xfont xau xdmcp, [xephyr="yes"], [xephyr="no"]) + XEPHYR_REQUIRED_LIBS="x11 xext xfont xau xdmcp" + if test "x$XV" = xyes; then + XEPHYR_REQUIRED_LIBS="$XEPHYR_REQUIRED_LIBS xv" + fi + PKG_CHECK_MODULES(XEPHYR, $XEPHYR_REQUIRED_LIBS, [xephyr="yes"], [xephyr="no"]) if test "x$XEPHYR" = xauto; then XEPHYR=$xephyr fi @@ -1941,7 +1931,7 @@ if test "$KDRIVE" = yes; then KDRIVE_OS_INC='-I$(top_srcdir)/hw/kdrive/linux' KDRIVE_INCS="$KDRIVE_PURE_INCS $KDRIVE_OS_INC" - KDRIVE_CFLAGS="$XSERVER_CFLAGS -DHAVE_KDRIVE_CONFIG_H $TSLIB_CFLAGS $XV_CFLAGS" + KDRIVE_CFLAGS="$XSERVER_CFLAGS -DHAVE_KDRIVE_CONFIG_H $TSLIB_CFLAGS" KDRIVE_PURE_LIBS="$FB_LIB $MI_LIB $FIXES_LIB $XEXT_LIB $DBE_LIB $XTRAP_LIB $RECORD_LIB $GLX_LIBS $RENDER_LIB $RANDR_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $COMPOSITE_LIB $XPSTUBS_LIB $OS_LIB" KDRIVE_LIB='$(top_builddir)/hw/kdrive/src/libkdrive.a' @@ -1955,10 +1945,10 @@ if test "$KDRIVE" = yes; then KDRIVE_LOCAL_LIBS="$TSLIB_LIBS $DIX_LIB $KDRIVE_LIB $KDRIVE_STUB_LIB $CONFIG_LIB" KDRIVE_LOCAL_LIBS="$KDRIVE_LOCAL_LIBS $FB_LIB $MI_LIB $KDRIVE_PURE_LIBS" KDRIVE_LOCAL_LIBS="$KDRIVE_LOCAL_LIBS $KDRIVE_OS_LIB $OS_LIB" - KDRIVE_LIBS="$KDRIVE_LOCAL_LIBS $XSERVER_SYS_LIBS $XV_LIBS" + KDRIVE_LIBS="$KDRIVE_LOCAL_LIBS $XSERVER_SYS_LIBS" # check if we can build Xephyr - PKG_CHECK_MODULES(XEPHYR, x11 xext xfont xau xdmcp, [xephyr="yes"], [xephyr="no"]) + PKG_CHECK_MODULES(XEPHYR, $XEPHYR_REQUIRED_LIBS, [xephyr="yes"], [xephyr="no"]) AC_SUBST([XEPHYR_LIBS]) AC_SUBST([XEPHYR_INCS]) From e7a6f79754816976d92857d55840262cccff80a6 Mon Sep 17 00:00:00 2001 From: George Sapountzis Date: Sat, 1 Mar 2008 16:16:29 +0200 Subject: [PATCH 028/149] glcore: split mesa and X in build system --- GL/mesa/Makefile.am | 7 +++++-- GL/mesa/X/Makefile.am | 38 ++++++++++++++++---------------------- 2 files changed, 21 insertions(+), 24 deletions(-) diff --git a/GL/mesa/Makefile.am b/GL/mesa/Makefile.am index 99d3834ac..6d1a439da 100644 --- a/GL/mesa/Makefile.am +++ b/GL/mesa/Makefile.am @@ -1,9 +1,10 @@ -SUBDIRS = main math swrast swrast_setup tnl shader X glapi vbo +SUBDIRS = X +SUBDIRS += main math swrast swrast_setup tnl shader glapi vbo noinst_LTLIBRARIES = libGLcore.la libGLcore_la_SOURCES = dummy.c -libGLcore_la_LIBADD = main/libmain.la \ +MESA_LIBS = main/libmain.la \ math/libmath.la \ swrast/libswrast.la \ swrast_setup/libss.la \ @@ -12,4 +13,6 @@ libGLcore_la_LIBADD = main/libmain.la \ shader/grammar/libgrammar.la \ shader/slang/libslang.la \ vbo/libvbo.la \ + +libGLcore_la_LIBADD = $(MESA_LIBS) \ X/libX.la diff --git a/GL/mesa/X/Makefile.am b/GL/mesa/X/Makefile.am index ace118170..d8abbc6bd 100644 --- a/GL/mesa/X/Makefile.am +++ b/GL/mesa/X/Makefile.am @@ -1,19 +1,10 @@ noinst_LTLIBRARIES = libX.la INCLUDES = -I@MESA_SOURCE@/include \ - -I../X \ - -I../glapi \ - -I../main \ - -I../math \ - -I../shader \ - -I../swrast \ - -I../swrast_setup \ - -I../tnl \ - -I.. \ - -I../../glx \ - -I$(top_srcdir)/GL/glx \ - -I$(top_srcdir)/GL/include \ - -I$(top_srcdir)/hw/xfree86/os-support + -I. \ + -I@MESA_SOURCE@/src/mesa/glapi \ + -I@MESA_SOURCE@/src/mesa/main \ + -I@MESA_SOURCE@/src/mesa # -DXFree86Server is required because the X11 driver in Mesa thinks that # symbol means "being built in the server" @@ -22,12 +13,15 @@ AM_CFLAGS = \ -DXFree86Server \ @GLX_DEFINES@ -nodist_libX_la_SOURCES = \ - xm_api.c \ - xm_buffer.c \ - xm_dd.c \ - xm_image.c \ - xm_line.c \ - xm_span.c \ - xm_tri.c \ - drivers/common/driverfuncs.c +XM_SOURCES = \ + xm_api.c \ + xm_buffer.c \ + xm_dd.c \ + xm_image.c \ + xm_line.c \ + xm_span.c \ + xm_tri.c + +XM_SOURCES += drivers/common/driverfuncs.c + +nodist_libX_la_SOURCES = $(XM_SOURCES) From 3d642905477f4b1ec3223f1fbe0d0d37e959ec81 Mon Sep 17 00:00:00 2001 From: George Sapountzis Date: Sat, 1 Mar 2008 16:18:18 +0200 Subject: [PATCH 029/149] clean some "unused" warnings --- hw/xfree86/common/xf86Helper.c | 1 - hw/xfree86/ddc/xf86DDC.c | 9 --- hw/xfree86/int10/helper_exec.c | 2 - hw/xfree86/parser/Screen.c | 1 - hw/xfree86/parser/scan.c | 2 +- hw/xfree86/vbe/vbeModes.c | 3 +- mi/midash.c | 32 -------- mi/miexpose.c | 2 - mi/mioverlay.c | 1 - mi/miwindow.c | 1 - os/connection.c | 1 - os/io.c | 129 --------------------------------- randr/rrscreen.c | 1 - 13 files changed, 2 insertions(+), 183 deletions(-) diff --git a/hw/xfree86/common/xf86Helper.c b/hw/xfree86/common/xf86Helper.c index 0d2471aa1..1dd0bbc0d 100644 --- a/hw/xfree86/common/xf86Helper.c +++ b/hw/xfree86/common/xf86Helper.c @@ -1093,7 +1093,6 @@ xf86SetRootClip (ScreenPtr pScreen, Bool enable) WindowPtr pChild; Bool WasViewable = (Bool)(pWin->viewable); Bool anyMarked = FALSE; - RegionPtr pOldClip = NULL; #ifdef DO_SAVE_UNDERS Bool dosave = FALSE; #endif diff --git a/hw/xfree86/ddc/xf86DDC.c b/hw/xfree86/ddc/xf86DDC.c index e47b8b80c..28e2ead28 100644 --- a/hw/xfree86/ddc/xf86DDC.c +++ b/hw/xfree86/ddc/xf86DDC.c @@ -13,8 +13,6 @@ #include "ddcPriv.h" #include -static const OptionInfoRec *DDCAvailableOptions(void *unused); - #define RETRIES 4 static unsigned char *EDIDRead_DDC1( @@ -58,13 +56,6 @@ static const OptionInfoRec DDCOptions[] = { { -1, NULL, OPTV_NONE, {0}, FALSE }, }; -/*ARGSUSED*/ -static const OptionInfoRec * -DDCAvailableOptions(void *unused) -{ - return (DDCOptions); -} - /** * Attempts to probe the monitor for EDID information, if NoDDC and NoDDC1 are * unset. EDID information blocks are interpreted and the results returned in diff --git a/hw/xfree86/int10/helper_exec.c b/hw/xfree86/int10/helper_exec.c index e8334262e..de6fde5d8 100644 --- a/hw/xfree86/int10/helper_exec.c +++ b/hw/xfree86/int10/helper_exec.c @@ -46,8 +46,6 @@ static void SetResetBIOSVars(xf86Int10InfoPtr pInt, Bool set); #define REG pInt -static int pci_config_cycle = 0; - int setup_int(xf86Int10InfoPtr pInt) { diff --git a/hw/xfree86/parser/Screen.c b/hw/xfree86/parser/Screen.c index ad08c1382..dfc02bb72 100644 --- a/hw/xfree86/parser/Screen.c +++ b/hw/xfree86/parser/Screen.c @@ -508,7 +508,6 @@ xf86validateScreen (XF86ConfigPtr p) { XF86ConfScreenPtr screen = p->conf_screen_lst; XF86ConfMonitorPtr monitor; - XF86ConfDevicePtr device; XF86ConfAdaptorLinkPtr adaptor; while (screen) diff --git a/hw/xfree86/parser/scan.c b/hw/xfree86/parser/scan.c index 9706d483b..1f9b1b8de 100644 --- a/hw/xfree86/parser/scan.c +++ b/hw/xfree86/parser/scan.c @@ -612,7 +612,7 @@ DoSubstitution(const char *template, const char *cmdline, const char *projroot, { char *result; int i, l; - static const char *env = NULL, *home = NULL; + static const char *env = NULL; static char *hostname = NULL; static char majorvers[3] = ""; diff --git a/hw/xfree86/vbe/vbeModes.c b/hw/xfree86/vbe/vbeModes.c index 061d7b695..fb730a708 100644 --- a/hw/xfree86/vbe/vbeModes.c +++ b/hw/xfree86/vbe/vbeModes.c @@ -127,10 +127,9 @@ CheckMode(ScrnInfoPtr pScrn, vbeInfoPtr pVbe, VbeInfoBlock *vbe, int id, { CARD16 major; VbeModeInfoBlock *mode; - DisplayModePtr pMode, p; + DisplayModePtr pMode; VbeModeInfoData *data; Bool modeOK = FALSE; - ModeStatus status = MODE_OK; major = (unsigned)(vbe->VESAVersion >> 8); diff --git a/mi/midash.c b/mi/midash.c index 912fb0389..95a19c295 100644 --- a/mi/midash.c +++ b/mi/midash.c @@ -52,38 +52,6 @@ SOFTWARE. #include "mistruct.h" #include "mifpoly.h" -static miDashPtr CheckDashStorage(miDashPtr *ppseg, int nseg, int *pnsegMax); - -#define NSEGDELTA 16 - -/* returns a pointer to the pseg[nseg-1], growing the storage as -necessary. this interface seems unnecessarily cumbersome. - -*/ - -static miDashPtr -CheckDashStorage( - miDashPtr *ppseg, /* base pointer */ - int nseg, /* number of segment we want to write to */ - int *pnsegMax) /* size (in segments) of list so far */ -{ - if (nseg > *pnsegMax) - { - miDashPtr newppseg; - - *pnsegMax += NSEGDELTA; - newppseg = (miDashPtr)xrealloc(*ppseg, - (*pnsegMax)*sizeof(miDashRec)); - if (!newppseg) - { - xfree(*ppseg); - return (miDashPtr)NULL; - } - *ppseg = newppseg; - } - return(*ppseg+(nseg-1)); -} - _X_EXPORT void miStepDash (dist, pDashIndex, pDash, numInDashList, pDashOffset) int dist; /* distance to step */ diff --git a/mi/miexpose.c b/mi/miexpose.c index 2d3b0d510..5c2bd0382 100644 --- a/mi/miexpose.c +++ b/mi/miexpose.c @@ -288,8 +288,6 @@ miHandleExposures(pSrcDrawable, pDstDrawable, #endif if (extents) { - WindowPtr pWin = (WindowPtr)pDstDrawable; - expBox = *REGION_EXTENTS(pscr, &rgnExposed); REGION_RESET(pscr, &rgnExposed, &expBox); } diff --git a/mi/mioverlay.c b/mi/mioverlay.c index a0adac54d..6ddcc052d 100644 --- a/mi/mioverlay.c +++ b/mi/mioverlay.c @@ -1528,7 +1528,6 @@ miOverlaySetShape(WindowPtr pWin) { Bool WasViewable = (Bool)(pWin->viewable); ScreenPtr pScreen = pWin->drawable.pScreen; - RegionPtr pOldClip = NULL; #ifdef DO_SAVE_UNDERS Bool dosave = FALSE; #endif diff --git a/mi/miwindow.c b/mi/miwindow.c index 77cb75009..cb8400c0c 100644 --- a/mi/miwindow.c +++ b/mi/miwindow.c @@ -938,7 +938,6 @@ miSetShape(pWin) Bool WasViewable = (Bool)(pWin->viewable); ScreenPtr pScreen = pWin->drawable.pScreen; Bool anyMarked = FALSE; - RegionPtr pOldClip = NULL; #ifdef DO_SAVE_UNDERS Bool dosave = FALSE; #endif diff --git a/os/connection.c b/os/connection.c index 8b6541ce6..1ae50fef0 100644 --- a/os/connection.c +++ b/os/connection.c @@ -546,7 +546,6 @@ AuthAudit (ClientPtr client, Bool letin, { char addr[128]; char *out = addr; - int client_uid; char client_uid_string[64]; LocalClientCredRec *lcc; #ifdef XSERVER_DTRACE diff --git a/os/io.c b/os/io.c index be89021e5..e7ec60952 100644 --- a/os/io.c +++ b/os/io.c @@ -91,8 +91,6 @@ _X_EXPORT CallbackListPtr FlushCallback; static ConnectionInputPtr AllocateInputBuffer(void); static ConnectionOutputPtr AllocateOutputBuffer(void); -static xReqPtr PeekNextRequest(xReqPtr req, ClientPtr client, Bool readmore); -static void SkipRequests(xReqPtr req, ClientPtr client, int numskipped); /* check for both EAGAIN and EWOULDBLOCK, because some supposedly POSIX * systems are broken and return EWOULDBLOCK when they should return EAGAIN @@ -618,135 +616,8 @@ ResetCurrentRequest(ClientPtr client) -/***************************************************************** - * PeekNextRequest and SkipRequests were implemented to support DBE - * idioms, but can certainly be used outside of DBE. There are two - * related macros in os.h, ReqLen and CastxReq. See the porting - * layer document for more details. - * - **********************/ - - -/***************************************************************** - * PeekNextRequest - * lets you look ahead at the unexecuted requests in a - * client's request buffer. - * - * Note: this implementation of PeekNextRequest ignores the - * readmore parameter. - * - **********************/ - -static xReqPtr -PeekNextRequest( - xReqPtr req, /* request we're starting from */ - ClientPtr client, /* client whose requests we're skipping */ - Bool readmore) /* attempt to read more if next request isn't there? */ -{ - register ConnectionInputPtr oci = ((OsCommPtr)client->osPrivate)->input; - xReqPtr pnextreq; - int needed, gotnow, reqlen; - - if (!oci) return NULL; - - if (!req) - { - /* caller wants the request after the one currently being executed */ - pnextreq = (xReqPtr) - (((CARD32 *)client->requestBuffer) + client->req_len); - } - else - { - /* caller wants the request after the one specified by req */ - reqlen = get_req_len(req, client); -#ifdef BIGREQS - if (!reqlen) reqlen = get_big_req_len(req, client); -#endif - pnextreq = (xReqPtr)(((char *)req) + (reqlen << 2)); - } - - /* see how much of the next request we have available */ - - gotnow = oci->bufcnt - (((char *)pnextreq) - oci->buffer); - - if (gotnow < sizeof(xReq)) - return NULL; - - needed = get_req_len(pnextreq, client) << 2; -#ifdef BIGREQS - if (!needed) - { - /* it's a big request */ - if (gotnow < sizeof(xBigReq)) - return NULL; - needed = get_big_req_len(pnextreq, client) << 2; - } -#endif - - /* if we have less than we need, return NULL */ - - return (gotnow < needed) ? NULL : pnextreq; -} - -/***************************************************************** - * SkipRequests - * lets you skip over some of the requests in a client's - * request buffer. Presumably the caller has used PeekNextRequest - * to examine the requests being skipped and has performed whatever - * actions they dictate. - * - **********************/ - _X_EXPORT CallbackListPtr SkippedRequestsCallback = NULL; -static void -SkipRequests( - xReqPtr req, /* last request being skipped */ - ClientPtr client, /* client whose requests we're skipping */ - int numskipped) /* how many requests we're skipping */ -{ - OsCommPtr oc = (OsCommPtr)client->osPrivate; - register ConnectionInputPtr oci = oc->input; - int reqlen; - - /* see if anyone wants to snoop the skipped requests */ - - if (SkippedRequestsCallback) - { - SkippedRequestInfoRec skipinfo; - skipinfo.req = req; - skipinfo.client = client; - skipinfo.numskipped = numskipped; - CallCallbacks(&SkippedRequestsCallback, &skipinfo); - } - - /* adjust the sequence number */ - client->sequence += numskipped; - - /* twiddle the oci to skip over the requests */ - - reqlen = get_req_len(req, client); -#ifdef BIGREQS - if (!reqlen) reqlen = get_big_req_len(req, client); -#endif - reqlen <<= 2; - oci->bufptr = (char *)req; - oci->lenLastReq = reqlen; - - /* see if any requests left in the buffer */ - - if ( ((char *)req + reqlen) == (oci->buffer + oci->bufcnt) ) - { - /* no requests; mark input buffer as available and client - * as having no input - */ - int fd = oc->fd; - AvailableInput = oc; - YieldControlNoInput(); - } -} - - /* lookup table for adding padding bytes to data that is read from or written to the X socket. */ static int padlength[4] = {0, 3, 2, 1}; diff --git a/randr/rrscreen.c b/randr/rrscreen.c index 811a5571b..f39197337 100644 --- a/randr/rrscreen.c +++ b/randr/rrscreen.c @@ -731,7 +731,6 @@ ProcRRSetScreenConfig (ClientPtr client) int n, rc; ScreenPtr pScreen; rrScrPrivPtr pScrPriv; - TimeStamp configTime; TimeStamp time; int i; Rotation rotation; From b0b9c811cda3e35a8f6d0813483f750602c55ff6 Mon Sep 17 00:00:00 2001 From: George Sapountzis Date: Sat, 1 Mar 2008 20:24:50 +0200 Subject: [PATCH 030/149] fix typo --- GL/mesa/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GL/mesa/Makefile.am b/GL/mesa/Makefile.am index 6d1a439da..7f27c58ba 100644 --- a/GL/mesa/Makefile.am +++ b/GL/mesa/Makefile.am @@ -12,7 +12,7 @@ MESA_LIBS = main/libmain.la \ shader/libshader.la \ shader/grammar/libgrammar.la \ shader/slang/libslang.la \ - vbo/libvbo.la \ + vbo/libvbo.la libGLcore_la_LIBADD = $(MESA_LIBS) \ X/libX.la From 2bb9c1f36f685044b837f42076dec2ea7d22d034 Mon Sep 17 00:00:00 2001 From: David Nusinow Date: Sat, 1 Mar 2008 18:44:58 -0500 Subject: [PATCH 031/149] bug #10008: Make Xvfb.1 document the correct default depth --- hw/vfb/Xvfb.man.pre | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/hw/vfb/Xvfb.man.pre b/hw/vfb/Xvfb.man.pre index e78e296f5..569afe175 100644 --- a/hw/vfb/Xvfb.man.pre +++ b/hw/vfb/Xvfb.man.pre @@ -55,7 +55,7 @@ manual page, \fIXvfb\fP accepts the following command line switches: .B "\-screen \fIscreennum\fP \fIWxHxD\fP" This option creates screen \fIscreennum\fP and sets its width, height, and depth to W, H, and D respectively. By default, only screen 0 exists -and has the dimensions 1280x1024x12. +and has the dimensions 1280x1024x8. .TP 4 .B "\-pixdepths \fIlist-of-depths\fP" This option specifies a list of pixmap depths that the server should @@ -106,12 +106,12 @@ will be depth 32 1600x1200. .TP 8 Xvfb :1 -screen 1 1600x1200x16 The server will listen for connections as server number 1, will have the -default screen configuration (one screen, 1280x1024x12), and screen 1 +default screen configuration (one screen, 1280x1024x8), and screen 1 will be depth 16 1600x1200. .TP 8 Xvfb -pixdepths 3 27 -fbdir /var/tmp The server will listen for connections as server number 0, will have the -default screen configuration (one screen, 1280x1024x12), +default screen configuration (one screen, 1280x1024x8), will also support pixmap depths of 3 and 27, and will use memory mapped files in /var/tmp for the framebuffer. From c934366424b0d20e013c84e6b94b226b20e7baa2 Mon Sep 17 00:00:00 2001 From: Matthieu Herrb Date: Sun, 2 Mar 2008 19:27:53 +0100 Subject: [PATCH 032/149] use UTILS_SYS_LIBS to pass SYS_LIBS to utils/ioports correctly --- configure.ac | 3 +++ hw/xfree86/utils/ioport/Makefile.am | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index ebbf87746..6388e747c 100644 --- a/configure.ac +++ b/configure.ac @@ -1137,6 +1137,9 @@ XSERVER_SYS_LIBS="${XSERVERLIBS_LIBS} ${SYS_LIBS} ${LIBS} ${LIBCRYPTO}" AC_SUBST([XSERVER_LIBS]) AC_SUBST([XSERVER_SYS_LIBS]) +UTILS_SYS_LIBS="${SYS_LIBS}" +AC_SUBST([UTILS_SYS_LIBS]) + # The Xorg binary needs to export symbols so that they can be used from modules # Some platforms require extra flags to do this. gcc should set these flags # when -rdynamic is passed to it, other compilers/linkers may need to be added diff --git a/hw/xfree86/utils/ioport/Makefile.am b/hw/xfree86/utils/ioport/Makefile.am index 1839c9a60..c1f9453a8 100644 --- a/hw/xfree86/utils/ioport/Makefile.am +++ b/hw/xfree86/utils/ioport/Makefile.am @@ -37,7 +37,7 @@ ioport_CFLAGS = $(DIX_CFLAGS) $(XORG_CFLAGS) ioport_LDADD = \ ../../os-support/libxorgos.la \ ../../dummylib/libdummy-nonserver.a \ - ${SYS_LIBS} + ${UTILS_SYS_LIBS} ioport_SOURCES = \ From b5ce0e1d0b861dc5521fcd9db6287ed6da817726 Mon Sep 17 00:00:00 2001 From: David Nusinow Date: Sun, 2 Mar 2008 17:12:02 -0500 Subject: [PATCH 033/149] Bug #13860: Ensure that the DRI mode is in octal format. --- hw/xfree86/parser/Configint.h | 5 +++++ hw/xfree86/parser/DRI.c | 2 ++ 2 files changed, 7 insertions(+) diff --git a/hw/xfree86/parser/Configint.h b/hw/xfree86/parser/Configint.h index 4d5fbcfab..684a001fc 100644 --- a/hw/xfree86/parser/Configint.h +++ b/hw/xfree86/parser/Configint.h @@ -71,11 +71,14 @@ #include #include "xf86Parser.h" +typedef enum { PARSE_DECIMAL, PARSE_OCTAL, PARSE_HEX } ParserNumType; + typedef struct { int num; /* returned number */ char *str; /* private copy of the return-string */ double realnum; /* returned number as a real */ + ParserNumType numType; /* used to enforce correct number formatting */ } LexRec, *LexPtr; @@ -211,6 +214,8 @@ else\ "\ta numerical group id." #define MULTIPLE_MSG \ "Multiple \"%s\" lines." +#define MUST_BE_OCTAL_MSG \ +"The number \"%d\" given in this section must be in octal (0xxx) format." /* Warning messages */ #define OBSOLETE_MSG \ diff --git a/hw/xfree86/parser/DRI.c b/hw/xfree86/parser/DRI.c index 18644bcc7..68a6db90b 100644 --- a/hw/xfree86/parser/DRI.c +++ b/hw/xfree86/parser/DRI.c @@ -117,6 +117,8 @@ xf86parseDRISection (void) case MODE: if (xf86getSubToken (&(ptr->dri_comment)) != NUMBER) Error (NUMBER_MSG, "Mode"); + if (val.numType != PARSE_OCTAL) + Error (MUST_BE_OCTAL_MSG, val.num); ptr->dri_mode = val.num; break; case BUFFERS: From f7ab2d3821e6bccc943f088e308fd58395a186d2 Mon Sep 17 00:00:00 2001 From: David Nusinow Date: Sun, 2 Mar 2008 18:36:25 -0500 Subject: [PATCH 034/149] Add missing file from previous commit. --- hw/xfree86/parser/scan.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/hw/xfree86/parser/scan.c b/hw/xfree86/parser/scan.c index 1f9b1b8de..851b91161 100644 --- a/hw/xfree86/parser/scan.c +++ b/hw/xfree86/parser/scan.c @@ -380,11 +380,20 @@ again: if (c == '0') if ((configBuf[configPos] == 'x') || (configBuf[configPos] == 'X')) + { base = 16; + val.numType = PARSE_HEX; + } else + { base = 8; + val.numType = PARSE_OCTAL; + } else + { base = 10; + val.numType = PARSE_DECIMAL; + } configRBuf[0] = c; i = 1; From 7c16b68ab879f5b4b1aedfc6b2aadbe56193dd19 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Mon, 3 Mar 2008 15:09:11 -0500 Subject: [PATCH 035/149] 1.5 has branched, start 1.5.99.x. --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 6388e747c..5417bbbda 100644 --- a/configure.ac +++ b/configure.ac @@ -26,7 +26,7 @@ dnl dnl Process this file with autoconf to create configure. AC_PREREQ(2.57) -AC_INIT([xorg-server], 1.4.99.2, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server) +AC_INIT([xorg-server], 1.5.99.1, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], xorg-server) AC_CONFIG_SRCDIR([Makefile.am]) AM_INIT_AUTOMAKE([dist-bzip2 foreign]) AM_MAINTAINER_MODE From 3b73d62791d925c465ec855f96981d151dd3c179 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Mon, 3 Mar 2008 15:43:22 -0500 Subject: [PATCH 036/149] xf86DDCMonitorSet: Honor the DisplaySize from the config file. We honor sync ranges and pixel clock settings from the config here, no reason to ignore DisplaySize. --- hw/xfree86/modes/xf86EdidModes.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/hw/xfree86/modes/xf86EdidModes.c b/hw/xfree86/modes/xf86EdidModes.c index a9d672265..ea36d0a59 100644 --- a/hw/xfree86/modes/xf86EdidModes.c +++ b/hw/xfree86/modes/xf86EdidModes.c @@ -662,8 +662,10 @@ xf86DDCMonitorSet(int scrnIndex, MonPtr Monitor, xf86MonPtr DDC) Monitor->DDC = DDC; - Monitor->widthmm = 10 * DDC->features.hsize; - Monitor->heightmm = 10 * DDC->features.vsize; + if (Monitor->widthmm <= 0 && Monitor->heightmm <= 0) { + Monitor->widthmm = 10 * DDC->features.hsize; + Monitor->heightmm = 10 * DDC->features.vsize; + } /* * If this is a digital display, then we can use reduced blanking. From 605e6764dfd3e9cb917b9cfcd92fe89857c1a1c9 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Mon, 3 Mar 2008 15:45:17 -0500 Subject: [PATCH 037/149] Fix Motif menu drawing in Xnest. See also Red Hat bug #229350, OpenSolaris bug #6366490. --- hw/xnest/Events.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/xnest/Events.c b/hw/xnest/Events.c index 38fefa7a2..073535482 100644 --- a/hw/xnest/Events.c +++ b/hw/xnest/Events.c @@ -88,7 +88,7 @@ xnestCollectExposures(void) while (XCheckIfEvent(xnestDisplay, &X, xnestExposurePredicate, NULL)) { pWin = xnestWindowPtr(X.xexpose.window); - if (pWin) { + if (pWin && X.xexpose.width && X.xexpose.height) { Box.x1 = pWin->drawable.x + wBorderWidth(pWin) + X.xexpose.x; Box.y1 = pWin->drawable.y + wBorderWidth(pWin) + X.xexpose.y; Box.x2 = Box.x1 + X.xexpose.width; @@ -96,7 +96,7 @@ xnestCollectExposures(void) REGION_INIT(pWin->drawable.pScreen, &Rgn, &Box, 1); - miWindowExposures(pWin, &Rgn, NullRegion); + miSendExposures(pWin, &Rgn, Box.x2, Box.y2); } } } From 708f07753ff22ade54e9ee8885e4198fff363b87 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Mon, 3 Mar 2008 15:49:48 -0500 Subject: [PATCH 038/149] RANDR 1.2: Inherit PreferredMode from the global configuration, if any. If you don't do this, then Modes "800x600" in the Display subsection will be dutifully ignored and the driver will start at whatever resolution it feels like. --- hw/xfree86/modes/xf86Crtc.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c index 266e08195..14b60496a 100644 --- a/hw/xfree86/modes/xf86Crtc.c +++ b/hw/xfree86/modes/xf86Crtc.c @@ -1261,6 +1261,23 @@ xf86SortModes (DisplayModePtr input) return output; } +static char * +preferredMode(ScrnInfoPtr pScrn, xf86OutputPtr output) +{ + char *preferred_mode = NULL; + + /* Check for a configured preference for a particular mode */ + preferred_mode = xf86GetOptValString (output->options, + OPTION_PREFERRED_MODE); + if (preferred_mode) + return preferred_mode; + + if (pScrn->display->modes && *pScrn->display->modes) + preferred_mode = *pScrn->display->modes; + + return preferred_mode; +} + _X_EXPORT void xf86ProbeOutputModes (ScrnInfoPtr scrn, int maxX, int maxY) { @@ -1445,8 +1462,7 @@ xf86ProbeOutputModes (ScrnInfoPtr scrn, int maxX, int maxY) output->probed_modes = xf86SortModes (output->probed_modes); /* Check for a configured preference for a particular mode */ - preferred_mode = xf86GetOptValString (output->options, - OPTION_PREFERRED_MODE); + preferred_mode = preferredMode(scrn, output); if (preferred_mode) { From 3f23139137e024e09d207be05a61968100cf53e8 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Mon, 3 Mar 2008 13:05:12 -0800 Subject: [PATCH 039/149] Add cscope files to .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 406b74c4e..fb2f7e597 100644 --- a/.gitignore +++ b/.gitignore @@ -29,6 +29,7 @@ ltmain.sh missing TAGS tags +cscope* ylwrap xorg-server.pc stamp-h? From 613852ce6a821ce6f6382fc14629f517776a3701 Mon Sep 17 00:00:00 2001 From: James Cloos Date: Mon, 3 Mar 2008 16:10:04 -0500 Subject: [PATCH 040/149] Fix some documentation typos --- hw/xfree86/ddc/DDC.HOWTO | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/hw/xfree86/ddc/DDC.HOWTO b/hw/xfree86/ddc/DDC.HOWTO index 833a7ab54..1d06ca124 100644 --- a/hw/xfree86/ddc/DDC.HOWTO +++ b/hw/xfree86/ddc/DDC.HOWTO @@ -6,24 +6,24 @@ When implementing DDC in the driver one has the choice between DDC1 and DDC2. - DDC1 data is contiuously transmitted by a DDC1 capable display + DDC1 data is continuously transmitted by a DDC1 capable display device. The data is send serially over a data line; the Vsync signal serves as clock. Only one EDID 1.x data block can be transmitted using DDC1. Since transmission of an EDID1 block using a regular Vsync frequency would take up several seconds the driver can increase the Vsync frequency to up to 25 kHz as - soon as it detects DDC1 activety on the data line. + soon as it detects DDC1 activity on the data line. DDC2 data is transmitted using the I2C protocol. This requires an additional clock line. DDC2 is capable of transmitting EDID1 and EDID2 block as well as a VDIF block on display devices that support these. Display devices switch into the DDC2 mode as soon as they detect - activety on the DDC clock line. Once the are in DDC2 mode they + activity on the DDC clock line. Once the are in DDC2 mode they stop transmitting DDC1 signals until the next power cycle. Some graphics chipset configurations which are not capable of DDC2 might still be able to read DDC1 data. Where available - DDC2 it is preferrable. + DDC2 it is preferable. All relevant prototypes and defines are in xf86DDC.h. DDC2 additionally requires I2C support. The I2C prototypes @@ -37,7 +37,7 @@ unsigned int XXX_ddc1Read(ScrnInfoPtr pScrn) - Additionally a function is required to inclrease the Vsync + Additionally a function is required to increase the Vsync frequency to max. 25 kHz. void XXX_ddc1SetSpeed(ScrnInfoPtr pScrn, xf86ddcSpeed speed) @@ -58,7 +58,7 @@ in PreInit(). DDC1SetSpeed is a pointer to the SetSpeed() function, DDC1Read has to point to the DDC1 read function. The function will return a pointer to the xf86Monitor structure - which contains all information retreived by DDC. + which contains all information retrieved by DDC. NULL will be returned on failure. DDC2 Support @@ -73,7 +73,7 @@ to the I2CBusRec of the appropriate I2C Bus has to be passed as the second argument. The function will return a pointer to the xf86Monitor structure - which contains all information retreived by DDC. + which contains all information retrieved by DDC. NULL will be returned on failure. Printing monitor parameters @@ -86,7 +86,7 @@ is provided. Further processing of the xf86Monitor structure is not yet - implemented. Howerver it is planned to use the information + implemented. However, it is planned to use the information about video modes, gamma values etc. Therefore it is strongly recommended to read out DDC data before any video mode processing is done. From 0bd0f90d7c7928052197da7119177e5a1c9eee2c Mon Sep 17 00:00:00 2001 From: Daniel Stone Date: Tue, 4 Mar 2008 03:47:36 +0200 Subject: [PATCH 041/149] XKB: Fix initial map setting on startup Due to an unwitting sense inversion when eliminating XkbFileInfo, we were setting the complete wrong keymap on startup (non-XKB map if we had an XKB map available, or the XKB map if we didn't have any available). Invert the sense properly, and add two small bits that also went missing in that commit. --- xkb/xkbInit.c | 7 ++++--- xkb/xkbfmisc.c | 24 +++++++++++++++++++++--- 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/xkb/xkbInit.c b/xkb/xkbInit.c index c0afad026..3b47396e5 100644 --- a/xkb/xkbInit.c +++ b/xkb/xkbInit.c @@ -375,7 +375,8 @@ Atom unknown; names->vmods[vmod_AltGr]= CREATE_ATOM("ModeSwitch"); } - if (!(xkb->defined & XkmIndicatorsMask)) { + if (!(xkb->defined & XkmIndicatorsMask) || + !(xkb->defined & XkmGeometryMask)) { initIndicatorNames(NULL,xkb); if (names->indicators[LED_CAPS-1]==None) names->indicators[LED_CAPS-1] = CREATE_ATOM("Caps Lock"); @@ -531,10 +532,10 @@ XkbEventCauseRec cause; XkbDDXInitDevice(pXDev); if (xkb->defined & XkmSymbolsMask) + XkbUpdateCoreDescription(pXDev, True); + else XkbUpdateKeyTypesFromCore(pXDev, xkb->min_key_code, XkbNumKeys(xkb), &changes); - else - XkbUpdateCoreDescription(pXDev, True); XkbSetCauseUnknown(&cause); XkbUpdateActions(pXDev,xkb->min_key_code, XkbNumKeys(xkb),&changes, diff --git a/xkb/xkbfmisc.c b/xkb/xkbfmisc.c index 866b4b154..ae752e945 100644 --- a/xkb/xkbfmisc.c +++ b/xkb/xkbfmisc.c @@ -184,9 +184,27 @@ unsigned wantNames,wantConfig,wantDflts; if (want==0) return False; - if (xkb!=NULL) - old_names= xkb->names; - else old_names= NULL; + if (xkb) { + old_names = xkb->names; + + xkb->defined = 0; + /* Wow would it ever be neat if we didn't need this noise. */ + if (xkb->names && xkb->names->keys) + xkb->defined |= XkmKeyNamesMask; + if (xkb->map && xkb->map->types) + xkb->defined |= XkmTypesMask; + if (xkb->compat) + xkb->defined |= XkmCompatMapMask; + if (xkb->map && xkb->map->num_syms) + xkb->defined |= XkmSymbolsMask; + if (xkb->indicators) + xkb->defined |= XkmIndicatorsMask; + if (xkb->geom) + xkb->defined |= XkmGeometryMask; + } + else { + old_names= NULL; + } wantConfig= want&(~complete); if (xkb!=NULL) { From 72f2197545e734cd0aa785d05a57b2fc0351a763 Mon Sep 17 00:00:00 2001 From: Eamon Walsh Date: Tue, 4 Mar 2008 02:02:54 -0500 Subject: [PATCH 042/149] dix: Convert selection list to a linked list. Fixes a bug where pointers were being invalidated after a realloc. --- dix/selection.c | 48 ++++++++++++++++++++++-------------------------- 1 file changed, 22 insertions(+), 26 deletions(-) diff --git a/dix/selection.c b/dix/selection.c index 52b1611c5..11a174ee6 100644 --- a/dix/selection.c +++ b/dix/selection.c @@ -66,24 +66,22 @@ SOFTWARE. *****************************************************************/ _X_EXPORT Selection *CurrentSelections; -static int NumCurrentSelections; CallbackListPtr SelectionCallback; _X_EXPORT int dixLookupSelection(Selection **result, Atom selectionName, ClientPtr client, Mask access_mode) { - Selection *pSel = NULL; - int i, rc = BadMatch; + Selection *pSel; + int rc = BadMatch; client->errorValue = selectionName; - for (i = 0; i < NumCurrentSelections; i++) - if (CurrentSelections[i].selection == selectionName) { - pSel = CurrentSelections + i; - rc = XaceHookSelectionAccess(client, &pSel, access_mode); + for (pSel = CurrentSelections; pSel; pSel = pSel->next) + if (pSel->selection == selectionName) break; - } + if (pSel) + rc = XaceHookSelectionAccess(client, &pSel, access_mode); *result = pSel; return rc; } @@ -91,14 +89,17 @@ dixLookupSelection(Selection **result, Atom selectionName, void InitSelections(void) { - Selection *pSel = CurrentSelections; + Selection *pSel, *pNextSel; - for (; pSel - CurrentSelections < NumCurrentSelections; pSel++) + pSel = CurrentSelections; + while (pSel) { + pNextSel = pSel->next; dixFreePrivates(pSel->devPrivates); + xfree(pSel); + pSel = pNextSel; + } - xfree(CurrentSelections); CurrentSelections = NULL; - NumCurrentSelections = 0; } static _X_INLINE void @@ -112,9 +113,9 @@ CallSelectionCallback(Selection *pSel, ClientPtr client, void DeleteWindowFromAnySelections(WindowPtr pWin) { - Selection *pSel = CurrentSelections; + Selection *pSel; - for (; pSel - CurrentSelections < NumCurrentSelections; pSel++) + for (pSel = CurrentSelections; pSel; pSel = pSel->next) if (pSel->pWin == pWin) { CallSelectionCallback(pSel, NULL, SelectionWindowDestroy); @@ -127,9 +128,9 @@ DeleteWindowFromAnySelections(WindowPtr pWin) void DeleteClientFromAnySelections(ClientPtr client) { - Selection *pSel = CurrentSelections; + Selection *pSel; - for (; pSel - CurrentSelections < NumCurrentSelections; pSel++) + for (pSel = CurrentSelections; pSel; pSel = pSel->next) if (pSel->client == client) { CallSelectionCallback(pSel, NULL, SelectionClientClose); @@ -197,23 +198,18 @@ ProcSetSelectionOwner(ClientPtr client) /* * It doesn't exist, so add it... */ - int size = (NumCurrentSelections + 1) * sizeof(Selection); - CurrentSelections = xrealloc(CurrentSelections, size); - if (!CurrentSelections) { - NumCurrentSelections = 0; + pSel = xalloc(sizeof(Selection)); + if (!pSel) return BadAlloc; - } - pSel = CurrentSelections + NumCurrentSelections; + pSel->selection = stuff->selection; pSel->devPrivates = NULL; /* security creation/labeling check */ (void)XaceHookSelectionAccess(client, &pSel, DixCreateAccess); - pSel->next = NULL; - if (NumCurrentSelections > 0) - CurrentSelections[NumCurrentSelections - 1].next = pSel; - NumCurrentSelections++; + pSel->next = CurrentSelections; + CurrentSelections = pSel; } else return rc; From 056a2ce02ce85013e89055ee44a7aa3eabedac09 Mon Sep 17 00:00:00 2001 From: Eamon Walsh Date: Tue, 4 Mar 2008 02:44:48 -0500 Subject: [PATCH 043/149] XACE: Check the return value of the selection create hook call. --- dix/selection.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/dix/selection.c b/dix/selection.c index 11a174ee6..6a9198e96 100644 --- a/dix/selection.c +++ b/dix/selection.c @@ -206,7 +206,12 @@ ProcSetSelectionOwner(ClientPtr client) pSel->devPrivates = NULL; /* security creation/labeling check */ - (void)XaceHookSelectionAccess(client, &pSel, DixCreateAccess); + rc = XaceHookSelectionAccess(client, &pSel, + DixCreateAccess|DixSetAttrAccess); + if (rc != Success) { + xfree(pSel); + return rc; + } pSel->next = CurrentSelections; CurrentSelections = pSel; From 95df04b744c6a3498a9a9e2ea9bb03ee780e60f8 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Tue, 4 Mar 2008 10:59:24 -0500 Subject: [PATCH 044/149] Remove all mention of the vga driver from the config logic. --- hw/xfree86/common/xf86AutoConfig.c | 3 --- hw/xfree86/common/xf86Config.c | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/hw/xfree86/common/xf86AutoConfig.c b/hw/xfree86/common/xf86AutoConfig.c index da6c3f38d..e3e0bb3a3 100644 --- a/hw/xfree86/common/xf86AutoConfig.c +++ b/hw/xfree86/common/xf86AutoConfig.c @@ -82,7 +82,6 @@ static int builtinLines = 0; static const char *deviceList[] = { "fbdev", "vesa", - "vga", NULL }; @@ -450,8 +449,6 @@ chooseVideoDriver(void) if (chosen_driver == NULL) { #if defined __i386__ || defined __amd64__ || defined __hurd__ chosen_driver = "vesa"; -#elif defined __alpha__ - chosen_driver = "vga"; #elif defined __sparc__ chosen_driver = "sunffb"; #else diff --git a/hw/xfree86/common/xf86Config.c b/hw/xfree86/common/xf86Config.c index de3edf638..635a88c91 100644 --- a/hw/xfree86/common/xf86Config.c +++ b/hw/xfree86/common/xf86Config.c @@ -494,7 +494,7 @@ xf86InputDriverlistFromConfig() static void fixup_video_driver_list(char **drivers) { - static const char *fallback[5] = { "vga", "vesa", "fbdev", "wsfb", NULL }; + static const char *fallback[4] = { "vesa", "fbdev", "wsfb", NULL }; char **end, **drv; char *x; char **ati, **atimisc; From 27e7dacbf7ef17712be31ff90f98ee3a5c5cf909 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Tue, 4 Mar 2008 11:38:34 -0500 Subject: [PATCH 045/149] Make xf86InitialConfiguration slightly smarter. Old heuristic was to find the first monitor that expressed a preference, then attempt to get all other monitors to agree. This doesn't work particularly well when the two sets of modes don't precisely intersect, you get overlapping-but-not-identical output geometry and things go wrong. New heuristic is: - Exact user preference, if given - Exact output preference, if the same for all outputs - Best (largest) mode of modes common to all outputs: - with the same aspect ratio as all outputs (may be NULL) - with 4:3 aspect ratio - Then the old heuristic to try to get something lit Note that it is simply not doable to have a reliable initial output guess if you insist on trying to clone all outputs together. It's far too easy to end up with displays that simply don't have modes in common. We need to switch to right-of placement someday, once we're not limited to CRTC size limits and we have working multi-GPU in RANDR. --- hw/xfree86/modes/xf86Crtc.c | 374 ++++++++++++++++++++++++++++-------- 1 file changed, 298 insertions(+), 76 deletions(-) diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c index 14b60496a..4d5d7b848 100644 --- a/hw/xfree86/modes/xf86Crtc.c +++ b/hw/xfree86/modes/xf86Crtc.c @@ -1,5 +1,6 @@ /* * Copyright © 2006 Keith Packard + * Copyright © 2008 Red Hat, Inc. * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that @@ -808,7 +809,7 @@ xf86ClosestMode (xf86OutputPtr output, return target_mode; } -static Bool +static DisplayModePtr xf86OutputHasPreferredMode (xf86OutputPtr output, int width, int height) { DisplayModePtr mode; @@ -820,9 +821,21 @@ xf86OutputHasPreferredMode (xf86OutputPtr output, int width, int height) continue; if (mode->type & M_T_PREFERRED) - return TRUE; + return mode; } - return FALSE; + return NULL; +} + +static DisplayModePtr +xf86OutputHasUserPreferredMode (xf86OutputPtr output) +{ + DisplayModePtr mode, first = output->probed_modes; + + for (mode = first; mode && mode->next != first; mode = mode->next) + if (mode->type & M_T_USERPREF) + return mode; + + return NULL; } static int @@ -1577,6 +1590,265 @@ xf86SetScrnInfoModes (ScrnInfoPtr scrn) scrn->currentMode = scrn->modes; } +static void +xf86EnableOutputs(ScrnInfoPtr scrn, xf86CrtcConfigPtr config, Bool *enabled) +{ + Bool any_enabled = FALSE; + int o; + + for (o = 0; o < config->num_output; o++) + any_enabled |= enabled[o] = xf86OutputEnabled(config->output[o], TRUE); + + if (!any_enabled) { + xf86DrvMsg(scrn->scrnIndex, X_WARNING, + "No outputs definitely connected, trying again...\n"); + + for (o = 0; o < config->num_output; o++) + enabled[o] = xf86OutputEnabled(config->output[o], FALSE); + } +} + +static Bool +nextEnabledOutput(xf86CrtcConfigPtr config, Bool *enabled, int *index) +{ + int o = *index; + + for (o++; o < config->num_output; o++) { + if (enabled[o]) { + *index = o; + return TRUE; + } + } + + return FALSE; +} + +static Bool +xf86TargetExact(ScrnInfoPtr scrn, xf86CrtcConfigPtr config, + DisplayModePtr *modes, Bool *enabled, + int width, int height) +{ + int o; + int pref_width = 0, pref_height = 0; + DisplayModePtr *preferred; + Bool ret = FALSE; + + preferred = xnfcalloc(config->num_output, sizeof(DisplayModePtr)); + + /* Find all the preferred modes; fail if any outputs lack them */ + for (o = -1; nextEnabledOutput(config, enabled, &o); ) { + preferred[o] = + xf86OutputHasPreferredMode(config->output[o], width, height); + + if (!preferred[o]) + goto out; + } + + /* check that they're all the same size */ + for (o = -1; nextEnabledOutput(config, enabled, &o); ) { + Rotation r = config->output[o]->initial_rotation; + if (!pref_width) { + pref_width = xf86ModeWidth(preferred[o], r); + pref_height = xf86ModeHeight(preferred[o], r); + } else { + if (pref_width != xf86ModeWidth(preferred[o], r)) + goto out; + if (pref_height != xf86ModeHeight(preferred[o], r)) + goto out; + } + } + + /* oh good, they match. stash the selected modes and return. */ + memcpy(modes, preferred, config->num_output * sizeof(DisplayModePtr)); + ret = TRUE; + +out: + xfree(preferred); + return ret; +} + +static Bool +aspectMatch(float a, float b) +{ + return fabs(1 - (a / b)) < 0.05; +} + +static DisplayModePtr +nextAspectMode(DisplayModePtr start, float aspect) +{ + DisplayModePtr m = start; + + for (m = m->next; m; m = m->next) + if (aspectMatch(aspect, (float)m->HDisplay / (float)m->VDisplay)) + return m; + + return NULL; +} + +static DisplayModePtr +bestModeForAspect(xf86CrtcConfigPtr config, Bool *enabled, float aspect) +{ + int o, p; + DisplayModePtr mode, test = NULL, match = NULL; + + for (o = -1; nextEnabledOutput(config, enabled, &o); ) { + mode = config->output[o]->probed_modes; + while ((mode = nextAspectMode(mode, aspect))) { + for (p = o; nextEnabledOutput(config, enabled, &p); ) { + test = xf86OutputFindClosestMode(config->output[p], mode); + if (!test) + break; + if (test->HDisplay != mode->HDisplay || + test->VDisplay != mode->VDisplay) { + test = NULL; + break; + } + } + + /* if we didn't match it on all outputs, try the next one */ + if (!test) + continue; + + /* if it's bigger than the last one, save it */ + if (!match || (test->HDisplay > match->HDisplay)) + match = test; + } + } + + /* return the biggest one found */ + return match; +} + +static DisplayModePtr +biggestMode(DisplayModePtr a, DisplayModePtr b) +{ + int A, B; + + if (!a) + return b; + if (!b) + return a; + + A = a->HDisplay * a->VDisplay; + B = b->HDisplay * b->VDisplay; + + if (A > B) + return a; + + return b; +} + +static Bool +xf86TargetAspect(ScrnInfoPtr scrn, xf86CrtcConfigPtr config, + DisplayModePtr *modes, Bool *enabled, + int width, int height) +{ + int o; + float aspect = 0.0, *aspects; + xf86OutputPtr output; + Bool ret = FALSE; + DisplayModePtr guess = NULL, aspect_guess = NULL, base_guess = NULL; + + aspects = xnfcalloc(config->num_output, sizeof(float)); + + /* collect the aspect ratios */ + for (o = -1; nextEnabledOutput(config, enabled, &o); ) { + output = config->output[o]; + if (output->mm_height) + aspects[o] = (float)output->mm_width / (float)output->mm_height; + else + aspects[o] = 4.0 / 3.0; + } + + /* check that they're all the same */ + for (o = -1; nextEnabledOutput(config, enabled, &o); ) { + output = config->output[o]; + if (!aspect) { + aspect = aspects[o]; + } else if (!aspectMatch(aspect, aspects[o])) { + goto no_aspect_match; + } + } + + /* if they're all 4:3, just skip ahead and save effort */ + if (!aspectMatch(aspect, 4.0/3.0)) + aspect_guess = bestModeForAspect(config, enabled, aspect); + +no_aspect_match: + base_guess = bestModeForAspect(config, enabled, 4.0/3.0); + + guess = biggestMode(base_guess, aspect_guess); + + if (!guess) + goto out; + + /* found a mode that works everywhere, now apply it */ + for (o = -1; nextEnabledOutput(config, enabled, &o); ) { + modes[o] = xf86OutputFindClosestMode(config->output[o], guess); + } + ret = TRUE; + +out: + xfree(aspects); + return ret; +} + +static Bool +xf86TargetFallback(ScrnInfoPtr scrn, xf86CrtcConfigPtr config, + DisplayModePtr *modes, Bool *enabled, + int width, int height) +{ + DisplayModePtr target_mode = NULL; + Rotation target_rotation = RR_Rotate_0; + DisplayModePtr default_mode; + int default_preferred, target_preferred = 0, o; + + /* User preferred > preferred > other modes */ + for (o = -1; nextEnabledOutput(config, enabled, &o); ) { + default_mode = xf86DefaultMode (config->output[o], width, height); + if (!default_mode) + continue; + + default_preferred = (((default_mode->type & M_T_PREFERRED) != 0) + + ((default_mode->type & M_T_USERPREF) != 0)); + + if (default_preferred > target_preferred || !target_mode) { + target_mode = default_mode; + target_preferred = default_preferred; + target_rotation = config->output[o]->initial_rotation; + config->compat_output = o; + } + } + + if (target_mode) + modes[config->compat_output] = target_mode; + + /* Fill in other output modes */ + for (o = -1; nextEnabledOutput(config, enabled, &o); ) { + if (!modes[o]) + modes[o] = xf86ClosestMode(config->output[o], target_mode, + target_rotation, width, height); + } + + return (target_mode != NULL); +} + +static Bool +xf86TargetUserpref(ScrnInfoPtr scrn, xf86CrtcConfigPtr config, + DisplayModePtr *modes, Bool *enabled, + int width, int height) +{ + int o; + + for (o = -1; nextEnabledOutput(config, enabled, &o); ) + if (xf86OutputHasUserPreferredMode(config->output[o])) + return + xf86TargetFallback(scrn, config, modes, enabled, width, height); + + return FALSE; +} + + /** * Construct default screen configuration * @@ -1596,14 +1868,11 @@ xf86InitialConfiguration (ScrnInfoPtr scrn, Bool canGrow) { xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); int o, c; - DisplayModePtr target_mode = NULL; - int target_preferred = 0; - Rotation target_rotation = RR_Rotate_0; xf86CrtcPtr *crtcs; DisplayModePtr *modes; - Bool *enabled, any_enabled = FALSE; - int width; - int height; + Bool *enabled; + int width, height; + int i = scrn->scrnIndex; /* Set up the device options */ config->options = xnfalloc (sizeof (xf86DeviceOptions)); @@ -1629,75 +1898,28 @@ xf86InitialConfiguration (ScrnInfoPtr scrn, Bool canGrow) modes = xnfcalloc (config->num_output, sizeof (DisplayModePtr)); enabled = xnfcalloc (config->num_output, sizeof (Bool)); - for (o = 0; o < config->num_output; o++) - { - xf86OutputPtr output = config->output[o]; - - modes[o] = NULL; - any_enabled |= (enabled[o] = xf86OutputEnabled (output, TRUE)); - } - - if (!any_enabled) - { - xf86DrvMsg (scrn->scrnIndex, X_WARNING, - "No outputs definitely connected, trying again...\n"); + xf86EnableOutputs(scrn, config, enabled); - for (o = 0; o < config->num_output; o++) - { - xf86OutputPtr output = config->output[o]; - - modes[o] = NULL; - enabled[o] = xf86OutputEnabled (output, FALSE); - } - } + if (xf86TargetUserpref(scrn, config, modes, enabled, width, height)) + xf86DrvMsg(i, X_INFO, "Using user preference for initial modes\n"); + else if (xf86TargetExact(scrn, config, modes, enabled, width, height)) + xf86DrvMsg(i, X_INFO, "Using exact sizes for initial modes\n"); + else if (xf86TargetAspect(scrn, config, modes, enabled, width, height)) + xf86DrvMsg(i, X_INFO, "Using fuzzy aspect match for initial modes\n"); + else if (xf86TargetFallback(scrn, config, modes, enabled, width, height)) + xf86DrvMsg(i, X_INFO, "Using sloppy heuristic for initial modes\n"); + else + xf86DrvMsg(i, X_WARNING, "Unable to find initial modes\n"); - /* - * User preferred > preferred > other modes - */ - for (o = 0; o < config->num_output; o++) - { - xf86OutputPtr output = config->output[o]; - DisplayModePtr default_mode; - int default_preferred; - - if (!enabled[o]) - continue; - default_mode = xf86DefaultMode (output, width, height); - if (!default_mode) - continue; - default_preferred = (((default_mode->type & M_T_PREFERRED) != 0) + - ((default_mode->type & M_T_USERPREF) != 0)); - if (default_preferred > target_preferred || !target_mode) - { - target_mode = default_mode; - target_preferred = default_preferred; - target_rotation = output->initial_rotation; - config->compat_output = o; - } - } - if (target_mode) - modes[config->compat_output] = target_mode; - /* - * Fill in other output modes - */ - for (o = 0; o < config->num_output; o++) - { - xf86OutputPtr output = config->output[o]; - - if (enabled[o]) - { - if (!modes[o]) - modes[o] = xf86ClosestMode (output, target_mode, - target_rotation, width, height); - if (!modes[o]) - xf86DrvMsg (scrn->scrnIndex, X_ERROR, - "Output %s enabled but has no modes\n", - output->name); - else - xf86DrvMsg (scrn->scrnIndex, X_INFO, - "Output %s using initial mode %s\n", - output->name, modes[o]->name); - } + for (o = -1; nextEnabledOutput(config, enabled, &o); ) { + if (!modes[o]) + xf86DrvMsg (scrn->scrnIndex, X_ERROR, + "Output %s enabled but has no modes\n", + config->output[o]->name); + else + xf86DrvMsg (scrn->scrnIndex, X_INFO, + "Output %s using initial mode %s\n", + config->output[o]->name, modes[o]->name); } /* From cf984dcc156958d4f8d98110e7add150628ce97e Mon Sep 17 00:00:00 2001 From: Alan Coopersmith Date: Tue, 4 Mar 2008 16:03:04 -0800 Subject: [PATCH 046/149] Make sure SIOGLIFCONF buffer is properly aligned for socket structures --- os/access.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/os/access.c b/os/access.c index e91dd37e4..db14380df 100644 --- a/os/access.c +++ b/os/access.c @@ -713,19 +713,21 @@ void DefineSelf (int fd) { #ifndef HAS_GETIFADDRS - char buf[2048], *cp, *cplim; - void * bufptr = buf; -#ifdef USE_SIOCGLIFCONF + char *cp, *cplim; +# ifdef USE_SIOCGLIFCONF + struct sockaddr_storage buf[16]; struct lifconf ifc; register struct lifreq *ifr; -#ifdef SIOCGLIFNUM +# ifdef SIOCGLIFNUM struct lifnum ifn; -#endif -#else +# endif +# else /* !USE_SIOCGLIFCONF */ + char buf[2048]; struct ifconf ifc; register struct ifreq *ifr; -#endif -#else +# endif + void * bufptr = buf; +#else /* HAS_GETIFADDRS */ struct ifaddrs * ifap, *ifr; #endif int len; From d4101140f4e569f18554cf0cbf43138d08bd1277 Mon Sep 17 00:00:00 2001 From: Eamon Walsh Date: Tue, 4 Mar 2008 22:39:41 -0500 Subject: [PATCH 047/149] xselinux: Implement polyinstantiation support and related protocol. --- Xext/xselinux.c | 1060 ++++++++++++++++++++++++++++++----------------- Xext/xselinux.h | 102 ++--- 2 files changed, 717 insertions(+), 445 deletions(-) diff --git a/Xext/xselinux.c b/Xext/xselinux.c index a7d3999b0..18c652645 100644 --- a/Xext/xselinux.c +++ b/Xext/xselinux.c @@ -60,31 +60,36 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * Globals */ -/* private state record */ +/* private state keys */ static DevPrivateKey subjectKey = &subjectKey; static DevPrivateKey objectKey = &objectKey; +static DevPrivateKey dataKey = &dataKey; -/* This is what we store for security state */ +/* subject state (clients and devices only) */ typedef struct { security_id_t sid; + security_id_t dev_create_sid; + security_id_t win_create_sid; + security_id_t sel_create_sid; + security_id_t prp_create_sid; + security_id_t sel_use_sid; + security_id_t prp_use_sid; struct avc_entry_ref aeref; char *command; int privileged; } SELinuxSubjectRec; +/* object state */ typedef struct { security_id_t sid; int poly; } SELinuxObjectRec; -/* selection manager */ +/* selection and property atom cache */ typedef struct { - Atom selection; - security_id_t sid; -} SELinuxSelectionRec; - -static ClientPtr securityManager; -static Window securityWindow; + SELinuxObjectRec prp; + SELinuxObjectRec sel; +} SELinuxAtomRec; /* audit file descriptor */ static int audit_fd; @@ -123,9 +128,9 @@ static unsigned numKnownTypes; static security_id_t *knownEvents; static unsigned numKnownEvents; -/* Array of selection SID structures */ -static SELinuxSelectionRec *knownSelections; -static unsigned numKnownSelections; +/* Array of property and selection SID structures */ +static SELinuxAtomRec *knownAtoms; +static unsigned numKnownAtoms; /* dynamically allocated security classes and permissions */ static struct security_class_mapping map[] = { @@ -135,7 +140,7 @@ static struct security_class_mapping map[] = { { "x_font", { "", "", "destroy", "create", "getattr", "", "", "", "", "", "", "", "add_glyph", "remove_glyph", "", "", "", "", "", "", "", "", "", "", "use", NULL }}, { "x_colormap", { "read", "write", "destroy", "create", "getattr", "", "", "", "", "", "", "", "add_color", "remove_color", "", "", "", "", "", "", "install", "uninstall", "", "", "use", NULL }}, { "x_property", { "read", "write", "destroy", "create", "getattr", "setattr", "", "", "", "", "", "", "", "", "", "", "write", NULL }}, - { "x_selection", { "read", "", "", "", "getattr", "setattr", NULL }}, + { "x_selection", { "read", "", "", "setattr", "getattr", "setattr", NULL }}, { "x_cursor", { "read", "write", "destroy", "create", "getattr", "setattr", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "use", NULL }}, { "x_client", { "", "", "destroy", "", "getattr", "setattr", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "manage", NULL }}, { "x_device", { "read", "write", "", "", "getattr", "setattr", "", "", "", "getfocus", "setfocus", "", "", "", "", "", "", "grab", "freeze", "force_cursor", "", "", "", "", "use", "manage", "", "bell", NULL }}, @@ -159,48 +164,164 @@ static pointer truep = (pointer)1; */ /* - * Looks up the SID corresponding to the given selection atom + * Looks up a name in the selection or property mappings */ static int -SELinuxSelectionToSID(Atom selection, SELinuxObjectRec *sid_return) +SELinuxAtomToSIDLookup(Atom atom, SELinuxObjectRec *obj, int map, int polymap) { - const char *name; - unsigned i, size; + const char *name = NameForAtom(atom); + security_context_t ctx; + int rc = Success; - for (i = 0; i < numKnownSelections; i++) - if (knownSelections[i].selection == selection) { - sid_return->sid = knownSelections[i].sid; - return Success; - } + obj->poly = 1; - /* Need to increase size of array */ - i = numKnownSelections; - size = (i + 1) * sizeof(SELinuxSelectionRec); - knownSelections = xrealloc(knownSelections, size); - if (!knownSelections) - return BadAlloc; - knownSelections[i].selection = selection; + /* Look in the mappings of names to contexts */ + if (selabel_lookup(label_hnd, &ctx, name, map) == 0) { + obj->poly = 0; + } else if (errno != ENOENT) { + ErrorF("SELinux: a property label lookup failed!\n"); + return BadValue; + } else if (selabel_lookup(label_hnd, &ctx, name, polymap) < 0) { + ErrorF("SELinux: a property label lookup failed!\n"); + return BadValue; + } - /* Look in the mappings of selection names to contexts */ - name = NameForAtom(selection); - if (name) { - security_context_t con; - security_id_t sid; + /* Get a SID for context */ + if (avc_context_to_sid(ctx, &obj->sid) < 0) { + ErrorF("SELinux: a context_to_SID call failed!\n"); + rc = BadAlloc; + } - if (selabel_lookup(label_hnd, &con, name, SELABEL_X_SELN) < 0) { - ErrorF("SELinux: a selection label lookup failed!\n"); + freecon(ctx); + return rc; +} + +/* + * Looks up the SID corresponding to the given property or selection atom + */ +static int +SELinuxAtomToSID(Atom atom, int prop, SELinuxObjectRec **obj_rtn) +{ + SELinuxObjectRec *obj; + int rc, map, polymap; + + if (atom >= numKnownAtoms) { + /* Need to increase size of atoms array */ + unsigned size = sizeof(SELinuxAtomRec); + knownAtoms = xrealloc(knownAtoms, (atom + 1) * size); + if (!knownAtoms) + return BadAlloc; + memset(knownAtoms + numKnownAtoms, 0, + (atom - numKnownAtoms + 1) * size); + numKnownAtoms = atom + 1; + } + + if (prop) { + obj = &knownAtoms[atom].prp; + map = SELABEL_X_PROP; + polymap = SELABEL_X_POLYPROP; + } else { + obj = &knownAtoms[atom].sel; + map = SELABEL_X_SELN; + polymap = SELABEL_X_POLYSELN; + } + + if (!obj->sid) { + rc = SELinuxAtomToSIDLookup(atom, obj, map, polymap); + if (rc != Success) + goto out; + } + + *obj_rtn = obj; + rc = Success; +out: + return rc; +} + +/* + * Looks up a SID for a selection/subject pair + */ +static int +SELinuxSelectionToSID(Atom selection, SELinuxSubjectRec *subj, + security_id_t *sid_rtn, int *poly_rtn) +{ + int rc; + SELinuxObjectRec *obj; + security_id_t tsid; + + /* Get the default context and polyinstantiation bit */ + rc = SELinuxAtomToSID(selection, 0, &obj); + if (rc != Success) + return rc; + + /* Check for an override context next */ + if (subj->sel_use_sid) { + sidget(tsid = subj->sel_use_sid); + goto out; + } + + sidget(tsid = obj->sid); + + /* Polyinstantiate if necessary to obtain the final SID */ + if (obj->poly) { + sidput(tsid); + if (avc_compute_member(subj->sid, obj->sid, + SECCLASS_X_SELECTION, &tsid) < 0) { + ErrorF("SELinux: a compute_member call failed!\n"); return BadValue; } - /* Get a SID for context */ - if (avc_context_to_sid(con, &sid) < 0) { - ErrorF("SELinux: a context_to_SID call failed!\n"); - return BadAlloc; - } - freecon(con); - knownSelections[i].sid = sid_return->sid = sid; - } else - knownSelections[i].sid = sid_return->sid = unlabeled_sid; + } +out: + *sid_rtn = tsid; + if (poly_rtn) + *poly_rtn = obj->poly; + return Success; +} +/* + * Looks up a SID for a property/subject pair + */ +static int +SELinuxPropertyToSID(Atom property, SELinuxSubjectRec *subj, + security_id_t *sid_rtn, int *poly_rtn) +{ + int rc; + SELinuxObjectRec *obj; + security_id_t tsid, tsid2; + + /* Get the default context and polyinstantiation bit */ + rc = SELinuxAtomToSID(property, 1, &obj); + if (rc != Success) + return rc; + + /* Check for an override context next */ + if (subj->prp_use_sid) { + sidget(tsid = subj->prp_use_sid); + goto out; + } + + /* Perform a transition */ + if (avc_compute_create(subj->sid, obj->sid, + SECCLASS_X_PROPERTY, &tsid) < 0) { + ErrorF("SELinux: a compute_create call failed!\n"); + return BadValue; + } + + /* Polyinstantiate if necessary to obtain the final SID */ + if (obj->poly) { + tsid2 = tsid; + if (avc_compute_member(subj->sid, tsid2, + SECCLASS_X_PROPERTY, &tsid) < 0) { + ErrorF("SELinux: a compute_member call failed!\n"); + sidput(tsid2); + return BadValue; + } + sidput(tsid2); + } +out: + *sid_rtn = tsid; + if (poly_rtn) + *poly_rtn = obj->poly; return Success; } @@ -383,8 +504,7 @@ finish: FatalError("SELinux: client %d: context_to_sid(%s) failed\n", client->index, ctx); - sidget(subj->sid); - obj->sid = subj->sid; + sidget(obj->sid = subj->sid); freecon(ctx); } @@ -415,8 +535,7 @@ SELinuxLabelInitial(void) if (avc_context_to_sid(ctx, &subj->sid) < 0) FatalError("SELinux: serverClient: context_to_sid(%s) failed\n", ctx); - sidget(subj->sid); - obj->sid = subj->sid; + sidget(obj->sid = subj->sid); freecon(ctx); srec.client = serverClient; @@ -434,6 +553,44 @@ SELinuxLabelInitial(void) } } +/* + * Labels new resource objects. + */ +static int +SELinuxLabelResource(XaceResourceAccessRec *rec, SELinuxSubjectRec *subj, + SELinuxObjectRec *obj, security_class_t class) +{ + int offset; + security_id_t tsid; + + /* Check for a create context */ + if (rec->rtype == RT_WINDOW && subj->win_create_sid) { + sidget(obj->sid = subj->win_create_sid); + return Success; + } + + if (rec->parent) + offset = dixLookupPrivateOffset(rec->ptype); + + if (rec->parent && offset >= 0) { + /* Use the SID of the parent object in the labeling operation */ + PrivateRec **privatePtr = DEVPRIV_AT(rec->parent, offset); + SELinuxObjectRec *pobj = dixLookupPrivate(privatePtr, objectKey); + tsid = pobj->sid; + } else { + /* Use the SID of the subject */ + tsid = subj->sid; + } + + /* Perform a transition to obtain the final SID */ + if (avc_compute_create(subj->sid, tsid, class, &obj->sid) < 0) { + ErrorF("SELinux: a compute_create call failed!\n"); + return BadValue; + } + + return Success; +} + /* * Libselinux Callbacks @@ -525,11 +682,15 @@ SELinuxDevice(CallbackListPtr *pcbl, pointer unused, pointer calldata) sidput(dsubj->sid); sidput(obj->sid); - /* Label the device directly with the process SID */ - sidget(subj->sid); - obj->sid = subj->sid; - sidget(subj->sid); - dsubj->sid = subj->sid; + if (subj->dev_create_sid) { + /* Label the device with the create context */ + sidget(obj->sid = subj->dev_create_sid); + sidget(dsubj->sid = subj->dev_create_sid); + } else { + /* Label the device directly with the process SID */ + sidget(obj->sid = subj->sid); + sidget(dsubj->sid = subj->sid); + } } /* XXX only check read permission on XQueryKeymap */ @@ -684,14 +845,77 @@ SELinuxExtension(CallbackListPtr *pcbl, pointer unused, pointer calldata) rec->status = rc; } +static void +SELinuxSelection(CallbackListPtr *pcbl, pointer unused, pointer calldata) +{ + XaceSelectionAccessRec *rec = calldata; + SELinuxSubjectRec *subj; + SELinuxObjectRec *obj, *data; + Selection *pSel = *rec->ppSel; + Atom name = pSel->selection; + SELinuxAuditRec auditdata = { .client = rec->client, .selection = name }; + security_id_t tsid; + int rc; + + subj = dixLookupPrivate(&rec->client->devPrivates, subjectKey); + obj = dixLookupPrivate(&pSel->devPrivates, objectKey); + + /* If this is a new object that needs labeling, do it now */ + if (rec->access_mode & DixCreateAccess) { + sidput(obj->sid); + rc = SELinuxSelectionToSID(name, subj, &obj->sid, &obj->poly); + if (rc != Success) + obj->sid = unlabeled_sid; + } + /* If this is a polyinstantiated object, find the right instance */ + else if (obj->poly) { + rc = SELinuxSelectionToSID(name, subj, &tsid, NULL); + if (rc != Success) { + rec->status = rc; + return; + } + while (pSel->selection != name || obj->sid != tsid) { + if ((pSel = pSel->next) == NULL) + break; + obj = dixLookupPrivate(&pSel->devPrivates, objectKey); + } + sidput(tsid); + + if (pSel) + *rec->ppSel = pSel; + else { + rec->status = BadMatch; + return; + } + } + + /* Perform the security check */ + rc = SELinuxDoCheck(subj, obj, SECCLASS_X_SELECTION, rec->access_mode, + &auditdata); + if (rc != Success) + rec->status = rc; + + /* Label the content (advisory only) */ + if (rec->access_mode & DixSetAttrAccess) { + data = dixLookupPrivate(&pSel->devPrivates, dataKey); + sidput(data->sid); + if (subj->sel_create_sid) + sidget(data->sid = subj->sel_create_sid); + else + sidget(data->sid = obj->sid); + } +} + static void SELinuxProperty(CallbackListPtr *pcbl, pointer unused, pointer calldata) { XacePropertyAccessRec *rec = calldata; SELinuxSubjectRec *subj; - SELinuxObjectRec *obj; - SELinuxAuditRec auditdata = { .client = rec->client }; + SELinuxObjectRec *obj, *data; PropertyPtr pProp = *rec->ppProp; + Atom name = pProp->propertyName; + SELinuxAuditRec auditdata = { .client = rec->client, .property = name }; + security_id_t tsid; int rc; subj = dixLookupPrivate(&rec->client->devPrivates, subjectKey); @@ -699,42 +923,50 @@ SELinuxProperty(CallbackListPtr *pcbl, pointer unused, pointer calldata) /* If this is a new object that needs labeling, do it now */ if (rec->access_mode & DixCreateAccess) { - const char *name = NameForAtom(pProp->propertyName); - security_context_t con; - security_id_t sid; - - /* Look in the mappings of property names to contexts */ - if (selabel_lookup(label_hnd, &con, name, SELABEL_X_PROP) < 0) { - ErrorF("SELinux: a property label lookup failed!\n"); - rec->status = BadValue; - return; - } - /* Get a SID for context */ - if (avc_context_to_sid(con, &sid) < 0) { - ErrorF("SELinux: a context_to_SID call failed!\n"); - rec->status = BadAlloc; - return; - } - sidput(obj->sid); - - /* Perform a transition to obtain the final SID */ - if (avc_compute_create(subj->sid, sid, SECCLASS_X_PROPERTY, - &obj->sid) < 0) { - ErrorF("SELinux: a SID transition call failed!\n"); - freecon(con); - rec->status = BadValue; + rc = SELinuxPropertyToSID(name, subj, &obj->sid, &obj->poly); + if (rc != Success) { + rec->status = rc; + return; + } + } + /* If this is a polyinstantiated object, find the right instance */ + else if (obj->poly) { + rc = SELinuxPropertyToSID(name, subj, &tsid, NULL); + if (rc != Success) { + rec->status = rc; + return; + } + while (pProp->propertyName != name || obj->sid != tsid) { + if ((pProp = pProp->next) == NULL) + break; + obj = dixLookupPrivate(&pProp->devPrivates, objectKey); + } + sidput(tsid); + + if (pProp) + *rec->ppProp = pProp; + else { + rec->status = BadMatch; return; } - freecon(con); } /* Perform the security check */ - auditdata.property = pProp->propertyName; rc = SELinuxDoCheck(subj, obj, SECCLASS_X_PROPERTY, rec->access_mode, &auditdata); if (rc != Success) rec->status = rc; + + /* Label the content (advisory only) */ + if (rec->access_mode & DixWriteAccess) { + data = dixLookupPrivate(&pProp->devPrivates, dataKey); + sidput(data->sid); + if (subj->prp_create_sid) + sidget(data->sid = subj->prp_create_sid); + else + sidget(data->sid = obj->sid); + } } static void @@ -742,14 +974,13 @@ SELinuxResource(CallbackListPtr *pcbl, pointer unused, pointer calldata) { XaceResourceAccessRec *rec = calldata; SELinuxSubjectRec *subj; - SELinuxObjectRec *obj, *sobj, *pobj; + SELinuxObjectRec *obj; SELinuxAuditRec auditdata = { .client = rec->client }; PrivateRec **privatePtr; security_class_t class; int rc, offset; subj = dixLookupPrivate(&rec->client->devPrivates, subjectKey); - sobj = dixLookupPrivate(&rec->client->devPrivates, objectKey); /* Determine if the resource object has a devPrivates field */ offset = dixLookupPrivateOffset(rec->rtype); @@ -767,21 +998,9 @@ SELinuxResource(CallbackListPtr *pcbl, pointer unused, pointer calldata) /* If this is a new object that needs labeling, do it now */ if (rec->access_mode & DixCreateAccess && offset >= 0) { - if (rec->parent) - offset = dixLookupPrivateOffset(rec->ptype); - if (rec->parent && offset >= 0) - /* Use the SID of the parent object in the labeling operation */ - pobj = dixLookupPrivate(DEVPRIV_AT(rec->parent, offset), objectKey); - else - /* Use the SID of the subject */ - pobj = sobj; - - sidput(obj->sid); - - /* Perform a transition to obtain the final SID */ - if (avc_compute_create(subj->sid, pobj->sid, class, &obj->sid) < 0) { - ErrorF("SELinux: a compute_create call failed!\n"); - rec->status = BadValue; + rc = SELinuxLabelResource(rec, subj, obj, class); + if (rc != Success) { + rec->status = rc; return; } } @@ -864,34 +1083,6 @@ SELinuxServer(CallbackListPtr *pcbl, pointer unused, pointer calldata) rec->status = rc; } -static void -SELinuxSelection(CallbackListPtr *pcbl, pointer unused, pointer calldata) -{ - XaceSelectionAccessRec *rec = (XaceSelectionAccessRec *)calldata; - SELinuxSubjectRec *subj; - SELinuxObjectRec sel_sid; - SELinuxAuditRec auditdata = { .client = rec->client }; - Selection *pSel = *rec->ppSel; - int rc; - - if (rec->access_mode & DixCreateAccess) - return; /* don't use create currently */ - - subj = dixLookupPrivate(&rec->client->devPrivates, subjectKey); - - rc = SELinuxSelectionToSID(pSel->selection, &sel_sid); - if (rc != Success) { - rec->status = rc; - return; - } - - auditdata.selection = pSel->selection; - rc = SELinuxDoCheck(subj, &sel_sid, SECCLASS_X_SELECTION, rec->access_mode, - &auditdata); - if (rc != Success) - rec->status = rc; -} - /* * DIX Callbacks @@ -907,14 +1098,6 @@ SELinuxClientState(CallbackListPtr *pcbl, pointer unused, pointer calldata) SELinuxLabelClient(pci->client); break; - case ClientStateRetained: - case ClientStateGone: - if (pci->client == securityManager) { - securityManager = NULL; - securityWindow = 0; - } - break; - default: break; } @@ -965,18 +1148,6 @@ SELinuxResourceState(CallbackListPtr *pcbl, pointer unused, pointer calldata) FatalError("SELinux: Unexpected unlabeled window found\n"); } -static void -SELinuxSelectionState(CallbackListPtr *pcbl, pointer unused, pointer calldata) -{ - SelectionInfoRec *rec = calldata; - - switch (rec->kind) { - case SelectionSetOwner: - default: - break; - } -} - /* * DevPrivates Callbacks @@ -1002,8 +1173,13 @@ SELinuxSubjectFree(CallbackListPtr *pcbl, pointer unused, pointer calldata) xfree(subj->command); - if (avc_active) + if (avc_active) { sidput(subj->sid); + sidput(subj->dev_create_sid); + sidput(subj->win_create_sid); + sidput(subj->sel_create_sid); + sidput(subj->prp_create_sid); + } } static void @@ -1031,6 +1207,21 @@ SELinuxObjectFree(CallbackListPtr *pcbl, pointer unused, pointer calldata) * Extension Dispatch */ +#define CTX_DEV offsetof(SELinuxSubjectRec, dev_create_sid) +#define CTX_WIN offsetof(SELinuxSubjectRec, win_create_sid) +#define CTX_PRP offsetof(SELinuxSubjectRec, prp_create_sid) +#define CTX_SEL offsetof(SELinuxSubjectRec, sel_create_sid) +#define USE_PRP offsetof(SELinuxSubjectRec, prp_use_sid) +#define USE_SEL offsetof(SELinuxSubjectRec, sel_use_sid) + +typedef struct { + security_context_t octx; + security_context_t dctx; + CARD32 octx_len; + CARD32 dctx_len; + CARD32 id; +} SELinuxListItemRec; + static int ProcSELinuxQueryVersion(ClientPtr client) { @@ -1053,65 +1244,101 @@ ProcSELinuxQueryVersion(ClientPtr client) } static int -ProcSELinuxSetSecurityManager(ClientPtr client) +SELinuxSendContextReply(ClientPtr client, security_id_t sid) { - WindowPtr pWin; - int rc; + SELinuxGetContextReply rep; + security_context_t ctx = NULL; + int len = 0; - REQUEST(SELinuxSetSecurityManagerReq); - REQUEST_SIZE_MATCH(SELinuxSetSecurityManagerReq); - - if (stuff->window == None) { - securityManager = NULL; - securityWindow = None; - } else { - rc = dixLookupResource((pointer *)&pWin, stuff->window, RT_WINDOW, - client, DixGetAttrAccess); - if (rc != Success) - return rc; - - securityManager = client; - securityWindow = stuff->window; + if (sid) { + if (avc_sid_to_context(sid, &ctx) < 0) + return BadValue; + len = strlen(ctx) + 1; } - return Success; -} - -static int -ProcSELinuxGetSecurityManager(ClientPtr client) -{ - SELinuxGetSecurityManagerReply rep; - rep.type = X_Reply; - rep.length = 0; + rep.length = (len + 3) >> 2; rep.sequenceNumber = client->sequence; - rep.window = securityWindow; + rep.context_len = len; + if (client->swapped) { int n; - swaps(&rep.sequenceNumber, n); swapl(&rep.length, n); - swapl(&rep.window, n); + swaps(&rep.sequenceNumber, n); + swapl(&rep.context_len, n); } - WriteToClient(client, sizeof(rep), (char *)&rep); - return (client->noClientException); + + WriteToClient(client, sizeof(SELinuxGetContextReply), (char *)&rep); + WriteToClient(client, len, ctx); + freecon(ctx); + return client->noClientException; } static int -ProcSELinuxSetDeviceCreateContext(ClientPtr client) +ProcSELinuxSetCreateContext(ClientPtr client, unsigned offset) { + PrivateRec **privPtr = &client->devPrivates; + security_id_t *pSid; + security_context_t ctx; + char *ptr; + + REQUEST(SELinuxSetCreateContextReq); + REQUEST_FIXED_SIZE(SELinuxSetCreateContextReq, stuff->context_len); + + ctx = (char *)(stuff + 1); + if (stuff->context_len > 0 && ctx[stuff->context_len - 1]) + return BadLength; + + if (offset == CTX_DEV) { + /* Device create context currently requires manage permission */ + int rc = XaceHook(XACE_SERVER_ACCESS, client, DixManageAccess); + if (rc != Success) + return rc; + privPtr = &serverClient->devPrivates; + } + else if (offset == USE_SEL) { + /* Selection use context currently requires no selections owned */ + Selection *pSel; + for (pSel = CurrentSelections; pSel; pSel = pSel->next) + if (pSel->client == client) + return BadMatch; + } + + ptr = dixLookupPrivate(privPtr, subjectKey); + pSid = (security_id_t *)(ptr + offset); + sidput(*pSid); + *pSid = NULL; + + if (stuff->context_len > 0) { + if (security_check_context(ctx) < 0) + return BadValue; + if (avc_context_to_sid(ctx, pSid) < 0) + return BadValue; + } return Success; } static int -ProcSELinuxGetDeviceCreateContext(ClientPtr client) +ProcSELinuxGetCreateContext(ClientPtr client, unsigned offset) { - return Success; + security_id_t *pSid; + char *ptr; + + REQUEST_SIZE_MATCH(SELinuxGetCreateContextReq); + + if (offset == CTX_DEV) + ptr = dixLookupPrivate(&serverClient->devPrivates, subjectKey); + else + ptr = dixLookupPrivate(&client->devPrivates, subjectKey); + + pSid = (security_id_t *)(ptr + offset); + return SELinuxSendContextReply(client, *pSid); } static int ProcSELinuxSetDeviceContext(ClientPtr client) { - char *ctx; + security_context_t ctx; security_id_t sid; DeviceIntPtr dev; SELinuxSubjectRec *subj; @@ -1122,15 +1349,16 @@ ProcSELinuxSetDeviceContext(ClientPtr client) REQUEST_FIXED_SIZE(SELinuxSetContextReq, stuff->context_len); ctx = (char *)(stuff + 1); - if (ctx[stuff->context_len - 1]) + if (stuff->context_len < 1 || ctx[stuff->context_len - 1]) return BadLength; rc = dixLookupDevice(&dev, stuff->id, client, DixManageAccess); if (rc != Success) return rc; - rc = avc_context_to_sid(ctx, &sid); - if (rc != Success) + if (security_check_context(ctx) < 0) + return BadValue; + if (avc_context_to_sid(ctx, &sid) < 0) return BadValue; subj = dixLookupPrivate(&dev->devPrivates, subjectKey); @@ -1138,7 +1366,7 @@ ProcSELinuxSetDeviceContext(ClientPtr client) subj->sid = sid; obj = dixLookupPrivate(&dev->devPrivates, objectKey); sidput(obj->sid); - obj->sid = sid; + sidget(obj->sid = sid); return Success; } @@ -1146,10 +1374,8 @@ ProcSELinuxSetDeviceContext(ClientPtr client) static int ProcSELinuxGetDeviceContext(ClientPtr client) { - char *ctx; DeviceIntPtr dev; SELinuxSubjectRec *subj; - SELinuxGetContextReply rep; int rc; REQUEST(SELinuxGetContextReq); @@ -1160,48 +1386,33 @@ ProcSELinuxGetDeviceContext(ClientPtr client) return rc; subj = dixLookupPrivate(&dev->devPrivates, subjectKey); - rc = avc_sid_to_context(subj->sid, &ctx); + return SELinuxSendContextReply(client, subj->sid); +} + +static int +ProcSELinuxGetWindowContext(ClientPtr client) +{ + WindowPtr pWin; + SELinuxObjectRec *obj; + int rc; + + REQUEST(SELinuxGetContextReq); + REQUEST_SIZE_MATCH(SELinuxGetContextReq); + + rc = dixLookupWindow(&pWin, stuff->id, client, DixGetAttrAccess); if (rc != Success) - return BadValue; + return rc; - rep.type = X_Reply; - rep.length = (strlen(ctx) + 4) >> 2; - rep.sequenceNumber = client->sequence; - rep.context_len = strlen(ctx) + 1; - - if (client->swapped) { - int n; - swapl(&rep.length, n); - swaps(&rep.sequenceNumber, n); - swaps(&rep.context_len, n); - } - - WriteToClient(client, sizeof(SELinuxGetContextReply), (char *)&rep); - WriteToClient(client, rep.context_len, ctx); - free(ctx); - return client->noClientException; + obj = dixLookupPrivate(&pWin->devPrivates, objectKey); + return SELinuxSendContextReply(client, obj->sid); } static int -ProcSELinuxSetPropertyCreateContext(ClientPtr client) +ProcSELinuxGetPropertyContext(ClientPtr client, pointer privKey) { - return Success; -} - -static int -ProcSELinuxGetPropertyCreateContext(ClientPtr client) -{ - return Success; -} - -static int -ProcSELinuxGetPropertyContext(ClientPtr client) -{ - char *ctx; WindowPtr pWin; PropertyPtr pProp; SELinuxObjectRec *obj; - SELinuxGetContextReply rep; int rc; REQUEST(SELinuxGetPropertyContextReq); @@ -1216,96 +1427,191 @@ ProcSELinuxGetPropertyContext(ClientPtr client) if (rc != Success) return rc; - obj = dixLookupPrivate(&pProp->devPrivates, objectKey); - rc = avc_sid_to_context(obj->sid, &ctx); - if (rc != Success) - return BadValue; - - rep.type = X_Reply; - rep.length = (strlen(ctx) + 4) >> 2; - rep.sequenceNumber = client->sequence; - rep.context_len = strlen(ctx) + 1; - - if (client->swapped) { - int n; - swapl(&rep.length, n); - swaps(&rep.sequenceNumber, n); - swaps(&rep.context_len, n); - } - - WriteToClient(client, sizeof(SELinuxGetContextReply), (char *)&rep); - WriteToClient(client, rep.context_len, ctx); - free(ctx); - return client->noClientException; + obj = dixLookupPrivate(&pProp->devPrivates, privKey); + return SELinuxSendContextReply(client, obj->sid); } static int -ProcSELinuxSetWindowCreateContext(ClientPtr client) +ProcSELinuxGetSelectionContext(ClientPtr client, pointer privKey) { - return Success; -} - -static int -ProcSELinuxGetWindowCreateContext(ClientPtr client) -{ - return Success; -} - -static int -ProcSELinuxGetWindowContext(ClientPtr client) -{ - char *ctx; - WindowPtr pWin; + Selection *pSel; SELinuxObjectRec *obj; - SELinuxGetContextReply rep; int rc; REQUEST(SELinuxGetContextReq); REQUEST_SIZE_MATCH(SELinuxGetContextReq); - rc = dixLookupWindow(&pWin, stuff->id, client, DixGetAttrAccess); + rc = dixLookupSelection(&pSel, stuff->id, client, DixGetAttrAccess); if (rc != Success) return rc; - obj = dixLookupPrivate(&pWin->devPrivates, objectKey); - rc = avc_sid_to_context(obj->sid, &ctx); - if (rc != Success) + obj = dixLookupPrivate(&pSel->devPrivates, privKey); + return SELinuxSendContextReply(client, obj->sid); +} + +static int +SELinuxPopulateItem(SELinuxListItemRec *i, PrivateRec **privPtr, CARD32 id, + int *size) +{ + SELinuxObjectRec *obj = dixLookupPrivate(privPtr, objectKey); + SELinuxObjectRec *data = dixLookupPrivate(privPtr, dataKey); + + if (avc_sid_to_context(obj->sid, &i->octx) < 0) + return BadValue; + if (avc_sid_to_context(data->sid, &i->dctx) < 0) return BadValue; - rep.type = X_Reply; - rep.length = (strlen(ctx) + 4) >> 2; - rep.sequenceNumber = client->sequence; - rep.context_len = strlen(ctx) + 1; + i->id = id; + i->octx_len = (strlen(i->octx) + 4) >> 2; + i->dctx_len = (strlen(i->dctx) + 4) >> 2; - if (client->swapped) { - int n; - swapl(&rep.length, n); - swaps(&rep.sequenceNumber, n); - swaps(&rep.context_len, n); + *size += i->octx_len + i->dctx_len + 3; + return Success; +} + +static void +SELinuxFreeItems(SELinuxListItemRec *items, int count) +{ + int k; + for (k = 0; k < count; k++) { + freecon(items[k].octx); + freecon(items[k].dctx); + } + xfree(items); +} + +static int +SELinuxSendItemsToClient(ClientPtr client, SELinuxListItemRec *items, + int size, int count) +{ + int rc, k, n, pos = 0; + SELinuxListItemsReply rep; + CARD32 *buf; + + buf = xcalloc(size, sizeof(CARD32)); + if (!buf) { + rc = BadAlloc; + goto out; } - WriteToClient(client, sizeof(SELinuxGetContextReply), (char *)&rep); - WriteToClient(client, rep.context_len, ctx); - free(ctx); - return client->noClientException; + /* Fill in the buffer */ + for (k = 0; k < count; k++) { + buf[pos] = items[k].id; + if (client->swapped) + swapl(buf + pos, n); + pos++; + + buf[pos] = items[k].octx_len * 4; + if (client->swapped) + swapl(buf + pos, n); + pos++; + + buf[pos] = items[k].dctx_len * 4; + if (client->swapped) + swapl(buf + pos, n); + pos++; + + memcpy((char *)(buf + pos), items[k].octx, strlen(items[k].octx) + 1); + pos += items[k].octx_len; + memcpy((char *)(buf + pos), items[k].dctx, strlen(items[k].dctx) + 1); + pos += items[k].dctx_len; + } + + /* Send reply to client */ + rep.type = X_Reply; + rep.length = size; + rep.sequenceNumber = client->sequence; + rep.count = count; + + if (client->swapped) { + swapl(&rep.length, n); + swaps(&rep.sequenceNumber, n); + swapl(&rep.count, n); + } + + WriteToClient(client, sizeof(SELinuxListItemsReply), (char *)&rep); + WriteToClient(client, size * 4, (char *)buf); + + /* Free stuff and return */ + rc = client->noClientException; + xfree(buf); +out: + SELinuxFreeItems(items, count); + return rc; } static int -ProcSELinuxSetSelectionCreateContext(ClientPtr client) +ProcSELinuxListProperties(ClientPtr client) { - return Success; + WindowPtr pWin; + PropertyPtr pProp; + SELinuxListItemRec *items; + int rc, count, size, i; + CARD32 id; + + REQUEST(SELinuxGetContextReq); + REQUEST_SIZE_MATCH(SELinuxGetContextReq); + + rc = dixLookupWindow(&pWin, stuff->id, client, DixListPropAccess); + if (rc != Success) + return rc; + + /* Count the number of properties and allocate items */ + count = 0; + for (pProp = wUserProps(pWin); pProp; pProp = pProp->next) + count++; + items = xcalloc(count, sizeof(SELinuxListItemRec)); + if (!items) + return BadAlloc; + + /* Fill in the items and calculate size */ + i = 0; + size = 0; + for (pProp = wUserProps(pWin); pProp; pProp = pProp->next) { + id = pProp->propertyName; + rc = SELinuxPopulateItem(items + i, &pProp->devPrivates, id, &size); + if (rc != Success) { + SELinuxFreeItems(items, count); + return rc; + } + i++; + } + + return SELinuxSendItemsToClient(client, items, size, count); } static int -ProcSELinuxGetSelectionCreateContext(ClientPtr client) +ProcSELinuxListSelections(ClientPtr client) { - return Success; -} + Selection *pSel; + SELinuxListItemRec *items; + int rc, count, size, i; + CARD32 id; -static int -ProcSELinuxGetSelectionContext(ClientPtr client) -{ - return Success; + REQUEST_SIZE_MATCH(SELinuxGetCreateContextReq); + + /* Count the number of selections and allocate items */ + count = 0; + for (pSel = CurrentSelections; pSel; pSel = pSel->next) + count++; + items = xcalloc(count, sizeof(SELinuxListItemRec)); + if (!items) + return BadAlloc; + + /* Fill in the items and calculate size */ + i = 0; + size = 0; + for (pSel = CurrentSelections; pSel; pSel = pSel->next) { + id = pSel->selection; + rc = SELinuxPopulateItem(items + i, &pSel->devPrivates, id, &size); + if (rc != Success) { + SELinuxFreeItems(items, count); + return rc; + } + i++; + } + + return SELinuxSendItemsToClient(client, items, size, count); } static int @@ -1315,36 +1621,48 @@ ProcSELinuxDispatch(ClientPtr client) switch (stuff->data) { case X_SELinuxQueryVersion: return ProcSELinuxQueryVersion(client); - case X_SELinuxSetSecurityManager: - return ProcSELinuxSetSecurityManager(client); - case X_SELinuxGetSecurityManager: - return ProcSELinuxGetSecurityManager(client); case X_SELinuxSetDeviceCreateContext: - return ProcSELinuxSetDeviceCreateContext(client); + return ProcSELinuxSetCreateContext(client, CTX_DEV); case X_SELinuxGetDeviceCreateContext: - return ProcSELinuxGetDeviceCreateContext(client); + return ProcSELinuxGetCreateContext(client, CTX_DEV); case X_SELinuxSetDeviceContext: return ProcSELinuxSetDeviceContext(client); case X_SELinuxGetDeviceContext: return ProcSELinuxGetDeviceContext(client); - case X_SELinuxSetPropertyCreateContext: - return ProcSELinuxSetPropertyCreateContext(client); - case X_SELinuxGetPropertyCreateContext: - return ProcSELinuxGetPropertyCreateContext(client); - case X_SELinuxGetPropertyContext: - return ProcSELinuxGetPropertyContext(client); case X_SELinuxSetWindowCreateContext: - return ProcSELinuxSetWindowCreateContext(client); + return ProcSELinuxSetCreateContext(client, CTX_WIN); case X_SELinuxGetWindowCreateContext: - return ProcSELinuxGetWindowCreateContext(client); + return ProcSELinuxGetCreateContext(client, CTX_WIN); case X_SELinuxGetWindowContext: return ProcSELinuxGetWindowContext(client); + case X_SELinuxSetPropertyCreateContext: + return ProcSELinuxSetCreateContext(client, CTX_PRP); + case X_SELinuxGetPropertyCreateContext: + return ProcSELinuxGetCreateContext(client, CTX_PRP); + case X_SELinuxSetPropertyUseContext: + return ProcSELinuxSetCreateContext(client, USE_PRP); + case X_SELinuxGetPropertyUseContext: + return ProcSELinuxGetCreateContext(client, USE_PRP); + case X_SELinuxGetPropertyContext: + return ProcSELinuxGetPropertyContext(client, objectKey); + case X_SELinuxGetPropertyDataContext: + return ProcSELinuxGetPropertyContext(client, dataKey); + case X_SELinuxListProperties: + return ProcSELinuxListProperties(client); case X_SELinuxSetSelectionCreateContext: - return ProcSELinuxSetSelectionCreateContext(client); + return ProcSELinuxSetCreateContext(client, CTX_SEL); case X_SELinuxGetSelectionCreateContext: - return ProcSELinuxGetSelectionCreateContext(client); + return ProcSELinuxGetCreateContext(client, CTX_SEL); + case X_SELinuxSetSelectionUseContext: + return ProcSELinuxSetCreateContext(client, USE_SEL); + case X_SELinuxGetSelectionUseContext: + return ProcSELinuxGetCreateContext(client, USE_SEL); case X_SELinuxGetSelectionContext: - return ProcSELinuxGetSelectionContext(client); + return ProcSELinuxGetSelectionContext(client, objectKey); + case X_SELinuxGetSelectionDataContext: + return ProcSELinuxGetSelectionContext(client, dataKey); + case X_SELinuxListSelections: + return ProcSELinuxListSelections(client); default: return BadRequest; } @@ -1363,25 +1681,14 @@ SProcSELinuxQueryVersion(ClientPtr client) } static int -SProcSELinuxSetSecurityManager(ClientPtr client) -{ - REQUEST(SELinuxSetSecurityManagerReq); - int n; - - REQUEST_SIZE_MATCH(SELinuxSetSecurityManagerReq); - swapl(&stuff->window, n); - return ProcSELinuxSetSecurityManager(client); -} - -static int -SProcSELinuxSetDeviceCreateContext(ClientPtr client) +SProcSELinuxSetCreateContext(ClientPtr client, unsigned offset) { REQUEST(SELinuxSetCreateContextReq); int n; REQUEST_AT_LEAST_SIZE(SELinuxSetCreateContextReq); - swaps(&stuff->context_len, n); - return ProcSELinuxSetDeviceCreateContext(client); + swapl(&stuff->context_len, n); + return ProcSELinuxSetCreateContext(client, offset); } static int @@ -1392,7 +1699,7 @@ SProcSELinuxSetDeviceContext(ClientPtr client) REQUEST_AT_LEAST_SIZE(SELinuxSetContextReq); swapl(&stuff->id, n); - swaps(&stuff->context_len, n); + swapl(&stuff->context_len, n); return ProcSELinuxSetDeviceContext(client); } @@ -1407,40 +1714,6 @@ SProcSELinuxGetDeviceContext(ClientPtr client) return ProcSELinuxGetDeviceContext(client); } -static int -SProcSELinuxSetPropertyCreateContext(ClientPtr client) -{ - REQUEST(SELinuxSetCreateContextReq); - int n; - - REQUEST_AT_LEAST_SIZE(SELinuxSetCreateContextReq); - swaps(&stuff->context_len, n); - return ProcSELinuxSetPropertyCreateContext(client); -} - -static int -SProcSELinuxGetPropertyContext(ClientPtr client) -{ - REQUEST(SELinuxGetPropertyContextReq); - int n; - - REQUEST_SIZE_MATCH(SELinuxGetPropertyContextReq); - swapl(&stuff->window, n); - swapl(&stuff->property, n); - return ProcSELinuxGetPropertyContext(client); -} - -static int -SProcSELinuxSetWindowCreateContext(ClientPtr client) -{ - REQUEST(SELinuxSetCreateContextReq); - int n; - - REQUEST_AT_LEAST_SIZE(SELinuxSetCreateContextReq); - swaps(&stuff->context_len, n); - return ProcSELinuxSetWindowCreateContext(client); -} - static int SProcSELinuxGetWindowContext(ClientPtr client) { @@ -1453,25 +1726,37 @@ SProcSELinuxGetWindowContext(ClientPtr client) } static int -SProcSELinuxSetSelectionCreateContext(ClientPtr client) +SProcSELinuxGetPropertyContext(ClientPtr client, pointer privKey) { - REQUEST(SELinuxSetCreateContextReq); + REQUEST(SELinuxGetPropertyContextReq); int n; - REQUEST_AT_LEAST_SIZE(SELinuxSetCreateContextReq); - swaps(&stuff->context_len, n); - return ProcSELinuxSetSelectionCreateContext(client); + REQUEST_SIZE_MATCH(SELinuxGetPropertyContextReq); + swapl(&stuff->window, n); + swapl(&stuff->property, n); + return ProcSELinuxGetPropertyContext(client, privKey); } static int -SProcSELinuxGetSelectionContext(ClientPtr client) +SProcSELinuxGetSelectionContext(ClientPtr client, pointer privKey) { REQUEST(SELinuxGetContextReq); int n; REQUEST_SIZE_MATCH(SELinuxGetContextReq); swapl(&stuff->id, n); - return ProcSELinuxGetSelectionContext(client); + return ProcSELinuxGetSelectionContext(client, privKey); +} + +static int +SProcSELinuxListProperties(ClientPtr client) +{ + REQUEST(SELinuxGetContextReq); + int n; + + REQUEST_SIZE_MATCH(SELinuxGetContextReq); + swapl(&stuff->id, n); + return ProcSELinuxListProperties(client); } static int @@ -1485,36 +1770,48 @@ SProcSELinuxDispatch(ClientPtr client) switch (stuff->data) { case X_SELinuxQueryVersion: return SProcSELinuxQueryVersion(client); - case X_SELinuxSetSecurityManager: - return SProcSELinuxSetSecurityManager(client); - case X_SELinuxGetSecurityManager: - return ProcSELinuxGetSecurityManager(client); case X_SELinuxSetDeviceCreateContext: - return SProcSELinuxSetDeviceCreateContext(client); + return SProcSELinuxSetCreateContext(client, CTX_DEV); case X_SELinuxGetDeviceCreateContext: - return ProcSELinuxGetDeviceCreateContext(client); + return ProcSELinuxGetCreateContext(client, CTX_DEV); case X_SELinuxSetDeviceContext: return SProcSELinuxSetDeviceContext(client); case X_SELinuxGetDeviceContext: return SProcSELinuxGetDeviceContext(client); - case X_SELinuxSetPropertyCreateContext: - return SProcSELinuxSetPropertyCreateContext(client); - case X_SELinuxGetPropertyCreateContext: - return ProcSELinuxGetPropertyCreateContext(client); - case X_SELinuxGetPropertyContext: - return SProcSELinuxGetPropertyContext(client); case X_SELinuxSetWindowCreateContext: - return SProcSELinuxSetWindowCreateContext(client); + return SProcSELinuxSetCreateContext(client, CTX_WIN); case X_SELinuxGetWindowCreateContext: - return ProcSELinuxGetWindowCreateContext(client); + return ProcSELinuxGetCreateContext(client, CTX_WIN); case X_SELinuxGetWindowContext: return SProcSELinuxGetWindowContext(client); + case X_SELinuxSetPropertyCreateContext: + return SProcSELinuxSetCreateContext(client, CTX_PRP); + case X_SELinuxGetPropertyCreateContext: + return ProcSELinuxGetCreateContext(client, CTX_PRP); + case X_SELinuxSetPropertyUseContext: + return SProcSELinuxSetCreateContext(client, USE_PRP); + case X_SELinuxGetPropertyUseContext: + return ProcSELinuxGetCreateContext(client, USE_PRP); + case X_SELinuxGetPropertyContext: + return SProcSELinuxGetPropertyContext(client, objectKey); + case X_SELinuxGetPropertyDataContext: + return SProcSELinuxGetPropertyContext(client, dataKey); + case X_SELinuxListProperties: + return SProcSELinuxListProperties(client); case X_SELinuxSetSelectionCreateContext: - return SProcSELinuxSetSelectionCreateContext(client); + return SProcSELinuxSetCreateContext(client, CTX_SEL); case X_SELinuxGetSelectionCreateContext: - return ProcSELinuxGetSelectionCreateContext(client); + return ProcSELinuxGetCreateContext(client, CTX_SEL); + case X_SELinuxSetSelectionUseContext: + return SProcSELinuxSetCreateContext(client, USE_SEL); + case X_SELinuxGetSelectionUseContext: + return ProcSELinuxGetCreateContext(client, USE_SEL); case X_SELinuxGetSelectionContext: - return SProcSELinuxGetSelectionContext(client); + return SProcSELinuxGetSelectionContext(client, objectKey); + case X_SELinuxGetSelectionDataContext: + return SProcSELinuxGetSelectionContext(client, dataKey); + case X_SELinuxListSelections: + return ProcSELinuxListSelections(client); default: return BadRequest; } @@ -1531,7 +1828,6 @@ SELinuxResetProc(ExtensionEntry *extEntry) /* Unregister callbacks */ DeleteCallback(&ClientStateCallback, SELinuxClientState, NULL); DeleteCallback(&ResourceStateCallback, SELinuxResourceState, NULL); - DeleteCallback(&SelectionCallback, SELinuxSelectionState, NULL); XaceDeleteCallback(XACE_EXT_DISPATCH, SELinuxExtension, NULL); XaceDeleteCallback(XACE_RESOURCE_ACCESS, SELinuxResource, NULL); @@ -1556,9 +1852,9 @@ SELinuxResetProc(ExtensionEntry *extEntry) avc_active = 0; /* Free local state */ - xfree(knownSelections); - knownSelections = NULL; - numKnownSelections = 0; + xfree(knownAtoms); + knownAtoms = NULL; + numKnownAtoms = 0; xfree(knownEvents); knownEvents = NULL; @@ -1615,7 +1911,8 @@ SELinuxExtensionInit(INITARGS) /* Allocate private storage */ if (!dixRequestPrivate(subjectKey, sizeof(SELinuxSubjectRec)) || - !dixRequestPrivate(objectKey, sizeof(SELinuxObjectRec))) + !dixRequestPrivate(objectKey, sizeof(SELinuxObjectRec)) || + !dixRequestPrivate(dataKey, sizeof(SELinuxObjectRec))) FatalError("SELinux: Failed to allocate private storage.\n"); /* Create atoms for doing window labeling */ @@ -1631,10 +1928,11 @@ SELinuxExtensionInit(INITARGS) ret &= dixRegisterPrivateDeleteFunc(subjectKey, SELinuxSubjectFree, NULL); ret &= dixRegisterPrivateInitFunc(objectKey, SELinuxObjectInit, NULL); ret &= dixRegisterPrivateDeleteFunc(objectKey, SELinuxObjectFree, NULL); + ret &= dixRegisterPrivateInitFunc(dataKey, SELinuxObjectInit, NULL); + ret &= dixRegisterPrivateDeleteFunc(dataKey, SELinuxObjectFree, NULL); ret &= AddCallback(&ClientStateCallback, SELinuxClientState, NULL); ret &= AddCallback(&ResourceStateCallback, SELinuxResourceState, NULL); - ret &= AddCallback(&SelectionCallback, SELinuxSelectionState, NULL); ret &= XaceRegisterCallback(XACE_EXT_DISPATCH, SELinuxExtension, NULL); ret &= XaceRegisterCallback(XACE_RESOURCE_ACCESS, SELinuxResource, NULL); diff --git a/Xext/xselinux.h b/Xext/xselinux.h index 480276154..2d0de3222 100644 --- a/Xext/xselinux.h +++ b/Xext/xselinux.h @@ -31,21 +31,27 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. /* Extension protocol */ #define X_SELinuxQueryVersion 0 -#define X_SELinuxSetSecurityManager 1 -#define X_SELinuxGetSecurityManager 2 -#define X_SELinuxSetDeviceCreateContext 3 -#define X_SELinuxGetDeviceCreateContext 4 -#define X_SELinuxSetDeviceContext 5 -#define X_SELinuxGetDeviceContext 6 -#define X_SELinuxSetPropertyCreateContext 7 -#define X_SELinuxGetPropertyCreateContext 8 -#define X_SELinuxGetPropertyContext 9 -#define X_SELinuxSetWindowCreateContext 10 -#define X_SELinuxGetWindowCreateContext 11 -#define X_SELinuxGetWindowContext 12 -#define X_SELinuxSetSelectionCreateContext 13 -#define X_SELinuxGetSelectionCreateContext 14 -#define X_SELinuxGetSelectionContext 15 +#define X_SELinuxSetDeviceCreateContext 1 +#define X_SELinuxGetDeviceCreateContext 2 +#define X_SELinuxSetDeviceContext 3 +#define X_SELinuxGetDeviceContext 4 +#define X_SELinuxSetWindowCreateContext 5 +#define X_SELinuxGetWindowCreateContext 6 +#define X_SELinuxGetWindowContext 7 +#define X_SELinuxSetPropertyCreateContext 8 +#define X_SELinuxGetPropertyCreateContext 9 +#define X_SELinuxSetPropertyUseContext 10 +#define X_SELinuxGetPropertyUseContext 11 +#define X_SELinuxGetPropertyContext 12 +#define X_SELinuxGetPropertyDataContext 13 +#define X_SELinuxListProperties 14 +#define X_SELinuxSetSelectionCreateContext 15 +#define X_SELinuxGetSelectionCreateContext 16 +#define X_SELinuxSetSelectionUseContext 17 +#define X_SELinuxGetSelectionUseContext 18 +#define X_SELinuxGetSelectionContext 19 +#define X_SELinuxGetSelectionDataContext 20 +#define X_SELinuxListSelections 21 typedef struct { CARD8 reqType; @@ -53,7 +59,6 @@ typedef struct { CARD16 length; CARD8 client_major; CARD8 client_minor; - CARD16 unused; } SELinuxQueryVersionReq; typedef struct { @@ -74,35 +79,7 @@ typedef struct { CARD8 reqType; CARD8 SELinuxReqType; CARD16 length; - CARD32 window; -} SELinuxSetSecurityManagerReq; - -typedef struct { - CARD8 reqType; - CARD8 SELinuxReqType; - CARD16 length; -} SELinuxGetSecurityManagerReq; - -typedef struct { - CARD8 type; - CARD8 pad1; - CARD16 sequenceNumber; - CARD32 length; - CARD32 window; - CARD32 pad2; - CARD32 pad3; - CARD32 pad4; - CARD32 pad5; - CARD32 pad6; -} SELinuxGetSecurityManagerReply; - -typedef struct { - CARD8 reqType; - CARD8 SELinuxReqType; - CARD16 length; - CARD8 permanent; - CARD8 unused; - CARD16 context_len; + CARD32 context_len; } SELinuxSetCreateContextReq; typedef struct { @@ -111,27 +88,12 @@ typedef struct { CARD16 length; } SELinuxGetCreateContextReq; -typedef struct { - CARD8 type; - CARD8 permanent; - CARD16 sequenceNumber; - CARD32 length; - CARD16 context_len; - CARD16 pad1; - CARD32 pad2; - CARD32 pad3; - CARD32 pad4; - CARD32 pad5; - CARD32 pad6; -} SELinuxGetCreateContextReply; - typedef struct { CARD8 reqType; CARD8 SELinuxReqType; CARD16 length; CARD32 id; - CARD16 unused; - CARD16 context_len; + CARD32 context_len; } SELinuxSetContextReq; typedef struct { @@ -154,15 +116,27 @@ typedef struct { CARD8 pad1; CARD16 sequenceNumber; CARD32 length; - CARD16 context_len; - CARD16 pad2; + CARD32 context_len; + CARD32 pad2; CARD32 pad3; CARD32 pad4; CARD32 pad5; CARD32 pad6; - CARD32 pad7; } SELinuxGetContextReply; +typedef struct { + CARD8 type; + CARD8 pad1; + CARD16 sequenceNumber; + CARD32 length; + CARD32 count; + CARD32 pad2; + CARD32 pad3; + CARD32 pad4; + CARD32 pad5; + CARD32 pad6; +} SELinuxListItemsReply; + /* Private Flask definitions */ #define SECCLASS_X_DRAWABLE 1 From 34b69e3bc0e6462eb60029fbcb4f5479494007a2 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Wed, 5 Mar 2008 23:56:49 -0500 Subject: [PATCH 048/149] Fix distcheck. (cherry picked from commit 2a47accff8dccded4dfe031f9366c028ba927824) --- GL/apple/Makefile.am | 8 ++++---- hw/xfree86/x86emu/Makefile.am | 1 + include/Makefile.am | 4 ++-- xkb/Makefile.am | 2 +- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/GL/apple/Makefile.am b/GL/apple/Makefile.am index 33ad15714..c064c03f8 100644 --- a/GL/apple/Makefile.am +++ b/GL/apple/Makefile.am @@ -11,10 +11,10 @@ AM_CPPFLAGS = \ if HAVE_AGL_FRAMEWORK noinst_LIBRARIES = libAGLcore.a libAGLcore_a_SOURCES = aglGlx.c \ - $(top_srcdir)/hw/darwin/quartz/xpr/x-list.c \ - $(top_srcdir)/hw/darwin/quartz/xpr/x-list.h \ - $(top_srcdir)/hw/darwin/quartz/xpr/x-hash.c \ - $(top_srcdir)/hw/darwin/quartz/xpr/x-hash.h \ + $(top_srcdir)/hw/xquartz/xpr/x-list.c \ + $(top_srcdir)/hw/xquartz/xpr/x-list.h \ + $(top_srcdir)/hw/xquartz/xpr/x-hash.c \ + $(top_srcdir)/hw/xquartz/xpr/x-hash.h \ $(top_srcdir)/hw/dmx/glxProxy/compsize.c endif diff --git a/hw/xfree86/x86emu/Makefile.am b/hw/xfree86/x86emu/Makefile.am index 9f9c87f4f..acd249c7f 100644 --- a/hw/xfree86/x86emu/Makefile.am +++ b/hw/xfree86/x86emu/Makefile.am @@ -21,6 +21,7 @@ EXTRA_DIST = validate.c \ x86emu/ops.h \ x86emu/prim_asm.h \ x86emu/prim_ops.h \ + x86emu/prim_x86_gcc.h \ x86emu/regs.h \ x86emu/types.h \ x86emu/x86emui.h diff --git a/include/Makefile.am b/include/Makefile.am index 0654b5788..673a97685 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -50,10 +50,10 @@ sdk_HEADERS = \ validate.h \ window.h \ windowstr.h \ - xkbsrv.h \ xorg-server.h endif AM_CFLAGS = $(DIX_CFLAGS) -EXTRA_DIST = $(sdk_HEADERS) do-not-use-config.h dix-config.h xorg-config.h +EXTRA_DIST = $(sdk_HEADERS) do-not-use-config.h dix-config.h xorg-config.h \ + xkb-config.h xkbfile.h xkbsrv.h xkbstr.h diff --git a/xkb/Makefile.am b/xkb/Makefile.am index e750d6098..5b594c130 100644 --- a/xkb/Makefile.am +++ b/xkb/Makefile.am @@ -47,7 +47,7 @@ libxkb_la_SOURCES = $(DDX_SRCS) $(DIX_SRCS) $(XI_SRCS) $(XKBFILE_SRCS) \ $(X11_SRCS) libxkbstubs_la_SOURCES = ddxVT.c ddxPrivate.c ddxKillSrv.c -EXTRA_DIST = xkb.h xkbDflts.h +EXTRA_DIST = xkbDflts.h xkbgeom.h xkb.h xkbcompileddir = $(XKB_COMPILED_DIR) dist_xkbcompiled_DATA = README.compiled From ca616b902b2c5d0f046c7a042c11f045479e373a Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Thu, 6 Mar 2008 13:47:44 -0800 Subject: [PATCH 049/149] Allow RandR get output property to call into drivers In order to report accurate values to users of the RandR property interface, it's sometimes necessary to ask the driver to update the value (for example when backlight brightness changes without the server's knowledge, due to hotkey events or direct sysfs banging). This patch wires up the core server code with a new xf86CrtcFuncs callback, get_property, to allow for this. The new code is available under the RANDR_13_INTERFACE define, which in turn depends on the RANDR_12_INTERFACE code. --- hw/xfree86/modes/xf86Crtc.h | 23 +++++++++++++++++++++++ hw/xfree86/modes/xf86RandR12.c | 17 +++++++++++++++++ randr/mirandr.c | 11 +++++++++++ randr/randrstr.h | 10 ++++++++++ randr/rrproperty.c | 19 +++++++++++++------ 5 files changed, 74 insertions(+), 6 deletions(-) diff --git a/hw/xfree86/modes/xf86Crtc.h b/hw/xfree86/modes/xf86Crtc.h index cc045b229..b87a32548 100644 --- a/hw/xfree86/modes/xf86Crtc.h +++ b/hw/xfree86/modes/xf86Crtc.h @@ -215,7 +215,14 @@ typedef struct _xf86CrtcFuncs { Rotation rotation, int x, int y); } xf86CrtcFuncsRec, *xf86CrtcFuncsPtr; +#define XF86_CRTC_VERSION 1 + struct _xf86Crtc { + /** + * ABI versioning + */ + int version; + /** * Associated ScrnInfo */ @@ -409,6 +416,14 @@ typedef struct _xf86OutputFuncs { (*set_property)(xf86OutputPtr output, Atom property, RRPropertyValuePtr value); +#endif +#ifdef RANDR_13_INTERFACE + /** + * Callback to get an updated property value + */ + Bool + (*get_property)(xf86OutputPtr output, + Atom property); #endif /** * Clean up driver-specific bits of the output @@ -417,7 +432,15 @@ typedef struct _xf86OutputFuncs { (*destroy) (xf86OutputPtr output); } xf86OutputFuncsRec, *xf86OutputFuncsPtr; + +#define XF86_OUTPUT_VERSION 1 + struct _xf86Output { + /** + * ABI versioning + */ + int version; + /** * Associated ScrnInfo */ diff --git a/hw/xfree86/modes/xf86RandR12.c b/hw/xfree86/modes/xf86RandR12.c index e2668fbbc..8b13758af 100644 --- a/hw/xfree86/modes/xf86RandR12.c +++ b/hw/xfree86/modes/xf86RandR12.c @@ -847,6 +847,20 @@ xf86RandR12OutputSetProperty (ScreenPtr pScreen, return output->funcs->set_property(output, property, value); } +static Bool +xf86RandR13OutputGetProperty (ScreenPtr pScreen, + RROutputPtr randr_output, + Atom property) +{ + xf86OutputPtr output = randr_output->devPrivate; + + if (output->funcs->get_property == NULL) + return TRUE; + + /* Should be safe even w/o vtSema */ + return output->funcs->get_property(output, property); +} + static Bool xf86RandR12OutputValidateMode (ScreenPtr pScreen, RROutputPtr randr_output, @@ -1126,6 +1140,9 @@ xf86RandR12Init12 (ScreenPtr pScreen) rp->rrCrtcSetGamma = xf86RandR12CrtcSetGamma; rp->rrOutputSetProperty = xf86RandR12OutputSetProperty; rp->rrOutputValidateMode = xf86RandR12OutputValidateMode; +#if RANDR_13_INTERFACE + rp->rrOutputGetProperty = xf86RandR13OutputGetProperty; +#endif rp->rrModeDestroy = xf86RandR12ModeDestroy; rp->rrSetConfig = NULL; pScrn->PointerMoved = xf86RandR12PointerMoved; diff --git a/randr/mirandr.c b/randr/mirandr.c index 3c4991e5a..777785380 100644 --- a/randr/mirandr.c +++ b/randr/mirandr.c @@ -73,6 +73,14 @@ miRROutputSetProperty (ScreenPtr pScreen, return TRUE; } +Bool +miRROutputGetProperty (ScreenPtr pScreen, + RROutputPtr output, + Atom property) +{ + return TRUE; +} + Bool miRROutputValidateMode (ScreenPtr pScreen, RROutputPtr output, @@ -116,6 +124,9 @@ miRandRInit (ScreenPtr pScreen) pScrPriv->rrCrtcSet = miRRCrtcSet; pScrPriv->rrCrtcSetGamma = miRRCrtcSetGamma; pScrPriv->rrOutputSetProperty = miRROutputSetProperty; +#if RANDR_13_INTERFACE + pScrPriv->rrOutputGetProperty = miRROutputGetProperty; +#endif pScrPriv->rrOutputValidateMode = miRROutputValidateMode; pScrPriv->rrModeDestroy = miRRModeDestroy; diff --git a/randr/randrstr.h b/randr/randrstr.h index e8358bc0c..3b48f5c2b 100644 --- a/randr/randrstr.h +++ b/randr/randrstr.h @@ -54,6 +54,7 @@ /* required for ABI compatibility for now */ #define RANDR_10_INTERFACE 1 #define RANDR_12_INTERFACE 1 +#define RANDR_13_INTERFACE 1 /* requires RANDR_12_INTERFACE */ typedef XID RRMode; typedef XID RROutput; @@ -175,6 +176,12 @@ typedef void (*RRModeDestroyProcPtr) (ScreenPtr pScreen, #endif +#if RANDR_13_INTERFACE +typedef Bool (*RROutputGetPropertyProcPtr) (ScreenPtr pScreen, + RROutputPtr output, + Atom property); +#endif /* RANDR_13_INTERFACE */ + typedef Bool (*RRGetInfoProcPtr) (ScreenPtr pScreen, Rotation *rotations); typedef Bool (*RRCloseScreenProcPtr) ( int i, ScreenPtr pscreen); @@ -220,6 +227,9 @@ typedef struct _rrScrPriv { RROutputValidateModeProcPtr rrOutputValidateMode; RRModeDestroyProcPtr rrModeDestroy; #endif +#if RANDR_13_INTERFACE + RROutputGetPropertyProcPtr rrOutputGetProperty; +#endif /* * Private part of the structure; not considered part of the ABI diff --git a/randr/rrproperty.c b/randr/rrproperty.c index 4617064e4..9bb7081ca 100644 --- a/randr/rrproperty.c +++ b/randr/rrproperty.c @@ -300,13 +300,21 @@ RRPropertyValuePtr RRGetOutputProperty (RROutputPtr output, Atom property, Bool pending) { RRPropertyPtr prop = RRQueryOutputProperty (output, property); + rrScrPrivPtr pScrPriv = rrGetScrPriv(output->pScreen); if (!prop) return NULL; if (pending && prop->is_pending) return &prop->pending; - else + else { +#if RANDR_13_INTERFACE + /* If we can, try to update the property value first */ + if (pScrPriv->rrOutputGetProperty) + pScrPriv->rrOutputGetProperty(output->pScreen, output, + prop->propertyName); +#endif return &prop->current; + } } int @@ -610,11 +618,10 @@ ProcRRGetOutputProperty (ClientPtr client) if (prop->immutable && stuff->delete) return BadAccess; - if (stuff->pending && prop->is_pending) - prop_value = &prop->pending; - else - prop_value = &prop->current; - + prop_value = RRGetOutputProperty(output, stuff->property, stuff->pending); + if (!prop_value) + return BadAtom; + /* If the request type and actual type don't match. Return the property information, but not the data. */ From a8d760f567b19268329c4682495caa591f08a854 Mon Sep 17 00:00:00 2001 From: Aaron Plattner Date: Sun, 2 Mar 2008 20:13:11 -0800 Subject: [PATCH 050/149] Get modes code building with old X servers again. This change uses XORG_VERSION_CURRENT < 7.0 to mean "server newer than 1.2" since XORG_VERSION current went backwards at some point. --- hw/xfree86/modes/xf86Cursors.c | 16 ++++++++++++--- hw/xfree86/modes/xf86EdidModes.c | 4 ++++ hw/xfree86/modes/xf86Modes.c | 5 +++++ hw/xfree86/modes/xf86RandR12.c | 35 +++++++++++++++++++++++++++++++- hw/xfree86/modes/xf86gtf.c | 4 ++++ 5 files changed, 60 insertions(+), 4 deletions(-) diff --git a/hw/xfree86/modes/xf86Cursors.c b/hw/xfree86/modes/xf86Cursors.c index 5a4d0f6fa..08cf78d82 100644 --- a/hw/xfree86/modes/xf86Cursors.c +++ b/hw/xfree86/modes/xf86Cursors.c @@ -226,8 +226,13 @@ xf86_set_cursor_colors (ScrnInfoPtr scrn, int bg, int fg) xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); CursorPtr cursor = xf86_config->cursor; int c; - CARD8 *bits = cursor ? dixLookupPrivate(&cursor->devPrivates, - screen) : NULL; + CARD8 *bits = cursor ? +#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(7,0,0,0,0) + dixLookupPrivate(&cursor->devPrivates, screen) +#else + cursor->devPriv[screen->myNum] +#endif + : NULL; /* Save ARGB versions of these colors */ xf86_config->cursor_fg = (CARD32) fg | 0xff000000; @@ -613,7 +618,12 @@ xf86_reload_cursors (ScreenPtr screen) else #endif (*cursor_info->LoadCursorImage)(cursor_info->pScrn, - dixLookupPrivate(&cursor->devPrivates, screen)); +#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(7,0,0,0,0) + dixLookupPrivate(&cursor->devPrivates, screen) +#else + cursor->devPriv[screen->myNum] +#endif + ); (*cursor_info->SetCursorPosition)(cursor_info->pScrn, x, y); (*cursor_info->ShowCursor)(cursor_info->pScrn); diff --git a/hw/xfree86/modes/xf86EdidModes.c b/hw/xfree86/modes/xf86EdidModes.c index ea36d0a59..2d1a6abd2 100644 --- a/hw/xfree86/modes/xf86EdidModes.c +++ b/hw/xfree86/modes/xf86EdidModes.c @@ -410,6 +410,7 @@ DDCModeFromDetailedTiming(int scrnIndex, struct detailed_timings *timing, return Mode; } +#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(7,0,0,0,0) static DisplayModePtr DDCModesFromCVT(int scrnIndex, struct cvt_timings *t) { @@ -438,6 +439,7 @@ DDCModesFromCVT(int scrnIndex, struct cvt_timings *t) return modes; } +#endif /* @@ -621,10 +623,12 @@ xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC) quirks, timing_level); Modes = xf86ModesAdd(Modes, Mode); break; +#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(7,0,0,0,0) case DS_CVT: Mode = DDCModesFromCVT(scrnIndex, det_mon->section.cvt); Modes = xf86ModesAdd(Modes, Mode); break; +#endif default: break; } diff --git a/hw/xfree86/modes/xf86Modes.c b/hw/xfree86/modes/xf86Modes.c index 9e3151254..aa2635c48 100644 --- a/hw/xfree86/modes/xf86Modes.c +++ b/hw/xfree86/modes/xf86Modes.c @@ -513,7 +513,12 @@ xf86ValidateModesBandwidth(ScrnInfoPtr pScrn, DisplayModePtr modeList, for (mode = modeList; mode != NULL; mode = mode->next) { if (xf86ModeBandwidth(mode, depth) > bandwidth) +#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(7,0,0,0,0) mode->status = MODE_BANDWIDTH; +#else + /* MODE_BANDWIDTH didn't exist in xserver 1.2 */ + mode->status = MODE_BAD; +#endif } } diff --git a/hw/xfree86/modes/xf86RandR12.c b/hw/xfree86/modes/xf86RandR12.c index 8b13758af..816175cc3 100644 --- a/hw/xfree86/modes/xf86RandR12.c +++ b/hw/xfree86/modes/xf86RandR12.c @@ -60,11 +60,21 @@ static Bool xf86RandR12CreateScreenResources12 (ScreenPtr pScreen); #endif static int xf86RandR12Generation; -static DevPrivateKey xf86RandR12Key; +#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(7,0,0,0,0) +static DevPrivateKey xf86RandR12Key; #define XF86RANDRINFO(p) ((XF86RandRInfoPtr) \ dixLookupPrivate(&(p)->devPrivates, xf86RandR12Key)) +#else /* XORG_VERSION_CURRENT < 7.0 */ + +static int xf86RandR12Index; +#define XF86RANDRINFO(p) \ + ((XF86RandRInfoPtr)(p)->devPrivates[xf86RandR12Index].ptr) + +#endif /* XORG_VERSION_CURRENT < 7.0 */ + + static int xf86RandR12ModeRefresh (DisplayModePtr mode) { @@ -340,13 +350,17 @@ xf86RandR12ScreenSetSize (ScreenPtr pScreen, PixmapPtr pScrnPix = (*pScreen->GetScreenPixmap)(pScreen); Bool ret = FALSE; +#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(7,0,0,0,0) if (xf86RandR12Key) { +#endif if (randrp->virtualX == -1 || randrp->virtualY == -1) { randrp->virtualX = pScrn->virtualX; randrp->virtualY = pScrn->virtualY; } +#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(7,0,0,0,0) } +#endif if (pRoot && pScrn->vtSema) (*pScrn->EnableDisableFBAccess) (pScreen->myNum, FALSE); @@ -468,8 +482,10 @@ xf86RandR12CreateScreenResources (ScreenPtr pScreen) mmHeight); } +#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(7,0,0,0,0) if (xf86RandR12Key == NULL) return TRUE; +#endif if (randrp->virtualX == -1 || randrp->virtualY == -1) { @@ -500,7 +516,11 @@ xf86RandR12Init (ScreenPtr pScreen) if (xf86RandR12Generation != serverGeneration) xf86RandR12Generation = serverGeneration; +#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(7,0,0,0,0) xf86RandR12Key = &xf86RandR12Key; +#else + xf86RandR12Index = AllocateScreenPrivateIndex(); +#endif randrp = xalloc (sizeof (XF86RandRInfoRec)); if (!randrp) @@ -526,7 +546,11 @@ xf86RandR12Init (ScreenPtr pScreen) randrp->maxX = randrp->maxY = 0; +#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(7,0,0,0,0) dixSetPrivate(&pScreen->devPrivates, xf86RandR12Key, randrp); +#else + pScreen->devPrivates[xf86RandR12Index].ptr = randrp; +#endif #if RANDR_12_INTERFACE if (!xf86RandR12Init12 (pScreen)) @@ -545,8 +569,10 @@ xf86RandR12SetRotations (ScreenPtr pScreen, Rotation rotations) xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); #endif +#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(7,0,0,0,0) if (xf86RandR12Key == NULL) return; +#endif randrp = XF86RANDRINFO(pScreen); #if RANDR_12_INTERFACE @@ -1090,8 +1116,10 @@ xf86RandR12CreateScreenResources12 (ScreenPtr pScreen) ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); +#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(7,0,0,0,0) if (xf86RandR12Key == NULL) return TRUE; +#endif for (c = 0; c < config->num_crtc; c++) xf86RandR12CrtcNotify (config->crtc[c]->randr_crtc); @@ -1113,8 +1141,13 @@ xf86RandR12TellChanged (ScreenPtr pScreen) xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); int c; +#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(7,0,0,0,0) if (xf86RandR12Key == NULL) return; +#else + if (!XF86RANDRINFO(pScreen)) + return; +#endif xf86RandR12SetInfo12 (pScreen); for (c = 0; c < config->num_crtc; c++) diff --git a/hw/xfree86/modes/xf86gtf.c b/hw/xfree86/modes/xf86gtf.c index acbac83b6..fed56bd12 100644 --- a/hw/xfree86/modes/xf86gtf.c +++ b/hw/xfree86/modes/xf86gtf.c @@ -62,6 +62,10 @@ #ifdef HAVE_XORG_CONFIG_H # include +#else +#ifdef HAVE_CONFIG_H +#include +#endif #endif #include "xf86.h" From 3fcb6445dc08f42488287162e3b7009d405e9c5b Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Fri, 7 Mar 2008 08:29:49 -0500 Subject: [PATCH 051/149] Fix segfault when a monitor exists but has no modes. Thanks to Zhenyu Wang for finding this. --- hw/xfree86/modes/xf86Crtc.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c index 4d5d7b848..0bef5b42f 100644 --- a/hw/xfree86/modes/xf86Crtc.c +++ b/hw/xfree86/modes/xf86Crtc.c @@ -1678,6 +1678,9 @@ nextAspectMode(DisplayModePtr start, float aspect) { DisplayModePtr m = start; + if (!m) + return NULL; + for (m = m->next; m; m = m->next) if (aspectMatch(aspect, (float)m->HDisplay / (float)m->VDisplay)) return m; From 3bf7ff70323d533a3a05c0f3e22393e63beada99 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Fri, 7 Mar 2008 09:25:06 -0500 Subject: [PATCH 052/149] Size xf86DefaultModes explicitly. i.e., don't check for the end of the list by ->name == NULL, since that won't work now. Fix the consumers of xf86DefaultModes to use the new explicit size as well. --- hw/xfree86/common/modeline2c.awk | 3 ++- hw/xfree86/common/xf86Config.c | 30 +++++++++--------------------- hw/xfree86/common/xf86Priv.h | 1 + hw/xfree86/modes/xf86Modes.c | 28 +++++----------------------- 4 files changed, 17 insertions(+), 45 deletions(-) diff --git a/hw/xfree86/common/modeline2c.awk b/hw/xfree86/common/modeline2c.awk index b9ad3cdf9..ca32e2f2d 100644 --- a/hw/xfree86/common/modeline2c.awk +++ b/hw/xfree86/common/modeline2c.awk @@ -91,5 +91,6 @@ BEGIN { } END { - printf("\t{MODEPREFIX,0,0,0,0,0,0,0,0,0,0,0,0,MODESUFFIX}\n};\n") + print "};" + printf "const int xf86NumDefaultModes = sizeof(xf86NumDefaultModes) / sizeof(DisplayModeRec);" } diff --git a/hw/xfree86/common/xf86Config.c b/hw/xfree86/common/xf86Config.c index 635a88c91..4a4aabcb5 100644 --- a/hw/xfree86/common/xf86Config.c +++ b/hw/xfree86/common/xf86Config.c @@ -2420,28 +2420,16 @@ addDefaultModes(MonPtr monitorp) DisplayModePtr last = monitorp->Last; int i = 0; - while (xf86DefaultModes[i].name != NULL) + for (i = 0; i < xf86NumDefaultModes; i++) { - if ( ! modeIsPresent(xf86DefaultModes[i].name,monitorp) ) - do - { - mode = xf86DuplicateMode(&xf86DefaultModes[i]); - if( last ) { - mode->prev = last; - last->next = mode; - } - else { - /* this is the first mode */ - monitorp->Modes = mode; - mode->prev = NULL; - } - last = mode; - i++; - } - while((xf86DefaultModes[i].name != NULL) && - (!strcmp(xf86DefaultModes[i].name,xf86DefaultModes[i-1].name))); - else - i++; + mode = xf86DuplicateMode(&xf86DefaultModes[i]); + if (!modeIsPresent(mode, monitorp)) + { + monitorp->Modes = xf86ModesAdd(monitorp->Modes, mode); + last = mode; + } else { + xfree(mode); + } } monitorp->Last = last; diff --git a/hw/xfree86/common/xf86Priv.h b/hw/xfree86/common/xf86Priv.h index dd8b5a022..c0d240dd5 100644 --- a/hw/xfree86/common/xf86Priv.h +++ b/hw/xfree86/common/xf86Priv.h @@ -154,6 +154,7 @@ Bool xf86PathIsSafe(const char *path); /* xf86DefaultModes */ extern const DisplayModeRec xf86DefaultModes[]; +extern const int xf86NumDefaultModes; /* xf86DoProbe.c */ void DoProbe(void); diff --git a/hw/xfree86/modes/xf86Modes.c b/hw/xfree86/modes/xf86Modes.c index aa2635c48..2dff31b3a 100644 --- a/hw/xfree86/modes/xf86Modes.c +++ b/hw/xfree86/modes/xf86Modes.c @@ -214,11 +214,7 @@ xf86DuplicateMode(DisplayModePtr pMode) *pNew = *pMode; pNew->next = NULL; pNew->prev = NULL; - /* - * It is important to copy the name explicitly. - * Otherwise a mode could reference an invalid piece of memory, after one of them runs free(). - * This will lead to obscure problems, that you really don't want. - */ + if (pMode->name == NULL) xf86SetModeDefaultName(pNew); else @@ -667,7 +663,7 @@ xf86GetDefaultModes (Bool interlaceAllowed, Bool doubleScanAllowed) DisplayModePtr head = NULL, prev = NULL, mode; int i; - for (i = 0; xf86DefaultModes[i].name != NULL; i++) + for (i = 0; i < xf86NumDefaultModes; i++) { DisplayModePtr defMode = &xf86DefaultModes[i]; @@ -676,23 +672,9 @@ xf86GetDefaultModes (Bool interlaceAllowed, Bool doubleScanAllowed) if (!doubleScanAllowed && (defMode->Flags & V_DBLSCAN)) continue; - mode = xalloc(sizeof(DisplayModeRec)); - if (!mode) - continue; - memcpy(mode,&xf86DefaultModes[i],sizeof(DisplayModeRec)); - mode->name = xstrdup(xf86DefaultModes[i].name); - if (!mode->name) - { - xfree (mode); - continue; - } - mode->prev = prev; - mode->next = NULL; - if (prev) - prev->next = mode; - else - head = mode; - prev = mode; + mode = xf86DuplicateMode(defMode); + + head = xf86ModesAdd(head, mode); } return head; } From 9abaad115cb6245b12b2adb3552ace99b634ab4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Fri, 7 Mar 2008 14:12:28 -0500 Subject: [PATCH 053/149] Fix DRI2 texture target for GLX_EXT_texture_from_pixmap. Thanks to Dennis Kasprzyk for pointing it out and for reminding me to commit it. --- GL/glx/glxdri2.c | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/GL/glx/glxdri2.c b/GL/glx/glxdri2.c index b0082a040..27257d3e0 100644 --- a/GL/glx/glxdri2.c +++ b/GL/glx/glxdri2.c @@ -216,8 +216,6 @@ __glXDRIcontextForceCurrent(__GLXcontext *baseContext) #ifdef __DRI_TEX_BUFFER -#define isPowerOfTwo(n) (((n) & ((n) - 1 )) == 0) - static int __glXDRIbindTexImage(__GLXcontext *baseContext, int buffer, @@ -228,26 +226,17 @@ __glXDRIbindTexImage(__GLXcontext *baseContext, PixmapPtr pixmap; __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext; unsigned int flags; - int w, h, target; if (screen->texBuffer == NULL) return Success; pixmap = (PixmapPtr) glxPixmap->pDraw; - w = pixmap->drawable.width; - h = pixmap->drawable.height; - - if (!isPowerOfTwo(w) || !isPowerOfTwo(h)) - target = GL_TEXTURE_RECTANGLE_ARB; - else - target = GL_TEXTURE_2D; - screen->texBuffer->setTexBuffer(&context->driContext, - target, + glxPixmap->target, DRI2GetPixmapHandle(pixmap, &flags), pixmap->drawable.depth, pixmap->devKind, - h); + pixmap->drawable.height); return Success; } From 911f0c147699d3b8d97491be2ef6d2e4a6682a0b Mon Sep 17 00:00:00 2001 From: Julien Cristau Date: Fri, 7 Mar 2008 23:24:06 +0100 Subject: [PATCH 054/149] Programs in hw/dmx/examples/ want client-side xkb headers. --- hw/dmx/examples/xinput.c | 2 +- hw/dmx/examples/xled.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/dmx/examples/xinput.c b/hw/dmx/examples/xinput.c index b6753e4ec..74353a93b 100644 --- a/hw/dmx/examples/xinput.c +++ b/hw/dmx/examples/xinput.c @@ -38,7 +38,7 @@ #include #include #include -#include "xkbstr.h" +#include #include #include diff --git a/hw/dmx/examples/xled.c b/hw/dmx/examples/xled.c index 322dda2f3..270f80511 100644 --- a/hw/dmx/examples/xled.c +++ b/hw/dmx/examples/xled.c @@ -37,7 +37,7 @@ #include #include #include -#include "xkbstr.h" +#include #include int main(int argc, char **argv) From acedc03367e9e69f03b4838f0f0e8d8a8e872b9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Sun, 9 Mar 2008 21:39:19 -0400 Subject: [PATCH 055/149] DRI2: Return event buffer head index in DRI2CreateDrawable. And pass it to the DRI driver in AIGLX. --- GL/glx/glxdri.c | 2 +- GL/glx/glxdri2.c | 6 ++++-- hw/xfree86/dri2/dri2.c | 5 +++-- hw/xfree86/dri2/dri2.h | 3 ++- 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/GL/glx/glxdri.c b/GL/glx/glxdri.c index dc15b0fcc..1e1791122 100644 --- a/GL/glx/glxdri.c +++ b/GL/glx/glxdri.c @@ -704,7 +704,7 @@ __glXDRIscreenCreateDrawable(__GLXscreen *screen, (driScreen->driScreen.createNewDrawable)(&driScreen->driScreen, modes, &private->driDrawable, - hwDrawable, 0, NULL); + hwDrawable, 0, 0, NULL); if (private->driDrawable.private == NULL) { __glXenterServer(GL_FALSE); diff --git a/GL/glx/glxdri2.c b/GL/glx/glxdri2.c index 27257d3e0..fbc018caf 100644 --- a/GL/glx/glxdri2.c +++ b/GL/glx/glxdri2.c @@ -341,6 +341,7 @@ __glXDRIscreenCreateDrawable(__GLXscreen *screen, __GLXDRIdrawable *private; GLboolean retval; drm_drawable_t hwDrawable; + unsigned int head; private = xalloc(sizeof *private); if (private == NULL) @@ -359,13 +360,14 @@ __glXDRIscreenCreateDrawable(__GLXscreen *screen, private->base.swapBuffers = __glXDRIdrawableSwapBuffers; private->base.copySubBuffer = __glXDRIdrawableCopySubBuffer; - retval = DRI2CreateDrawable(screen->pScreen, pDraw, &hwDrawable); + retval = DRI2CreateDrawable(screen->pScreen, pDraw, + &hwDrawable, &head); private->driDrawable.private = (driScreen->driScreen.createNewDrawable)(&driScreen->driScreen, modes, &private->driDrawable, - hwDrawable, 0, NULL); + hwDrawable, head, 0, NULL); return &private->base; } diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c index 9b4c18c61..d2664b1cb 100644 --- a/hw/xfree86/dri2/dri2.c +++ b/hw/xfree86/dri2/dri2.c @@ -262,8 +262,8 @@ DRI2CloseScreen(ScreenPtr pScreen) } Bool -DRI2CreateDrawable(ScreenPtr pScreen, - DrawablePtr pDraw, drm_drawable_t *pDrmDrawable) +DRI2CreateDrawable(ScreenPtr pScreen, DrawablePtr pDraw, + drm_drawable_t *pDrmDrawable, unsigned int *head) { DRI2ScreenPtr ds = DRI2GetScreen(pScreen); WindowPtr pWin; @@ -293,6 +293,7 @@ DRI2CreateDrawable(ScreenPtr pScreen, *pDrmDrawable = pPriv->drawable; + *head = ds->buffer->head; DRI2PostDrawableConfig(pDraw); DRI2PostBufferAttach(pDraw); DRI2ScreenCommitEvents(ds); diff --git a/hw/xfree86/dri2/dri2.h b/hw/xfree86/dri2/dri2.h index c8482477e..a31908508 100644 --- a/hw/xfree86/dri2/dri2.h +++ b/hw/xfree86/dri2/dri2.h @@ -66,7 +66,8 @@ void DRI2Unlock(ScreenPtr pScreen); Bool DRI2CreateDrawable(ScreenPtr pScreen, DrawablePtr pDraw, - drm_drawable_t *pDrmDrawable); + drm_drawable_t *pDrmDrawable, + unsigned int *head); void DRI2DestroyDrawable(ScreenPtr pScreen, DrawablePtr pDraw); From 01c2e01f2aee580438b74bfb9da8f584f3878e6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Sun, 9 Mar 2008 21:40:27 -0400 Subject: [PATCH 056/149] GLX: Track changes to DRI_TEX_BUFFER extension. We now just pass in the __DRIdrawable. --- GL/glx/glxdri2.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/GL/glx/glxdri2.c b/GL/glx/glxdri2.c index fbc018caf..fecfb1977 100644 --- a/GL/glx/glxdri2.c +++ b/GL/glx/glxdri2.c @@ -225,7 +225,7 @@ __glXDRIbindTexImage(__GLXcontext *baseContext, __GLXDRIscreen * const screen = (__GLXDRIscreen *) glxGetScreen(pScreen); PixmapPtr pixmap; __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext; - unsigned int flags; + __GLXDRIdrawable *drawable = (__GLXDRIdrawable *) glxPixmap; if (screen->texBuffer == NULL) return Success; @@ -233,10 +233,7 @@ __glXDRIbindTexImage(__GLXcontext *baseContext, pixmap = (PixmapPtr) glxPixmap->pDraw; screen->texBuffer->setTexBuffer(&context->driContext, glxPixmap->target, - DRI2GetPixmapHandle(pixmap, &flags), - pixmap->drawable.depth, - pixmap->devKind, - pixmap->drawable.height); + &drawable->driDrawable); return Success; } From 0f6aaf636b7ac4c98467284ff7baf1b83e0b72e7 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Mon, 10 Mar 2008 09:14:20 -0400 Subject: [PATCH 057/149] Bug #14927: Fix the math for xf86NumDefaultModes. --- hw/xfree86/common/modeline2c.awk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/xfree86/common/modeline2c.awk b/hw/xfree86/common/modeline2c.awk index ca32e2f2d..71a956e05 100644 --- a/hw/xfree86/common/modeline2c.awk +++ b/hw/xfree86/common/modeline2c.awk @@ -92,5 +92,5 @@ BEGIN { END { print "};" - printf "const int xf86NumDefaultModes = sizeof(xf86NumDefaultModes) / sizeof(DisplayModeRec);" + printf "const int xf86NumDefaultModes = sizeof(xf86DefaultModes) / sizeof(DisplayModeRec);" } From ab9b0b36ac8ac72fc48c0abd91a83de49a18313c Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Mon, 10 Mar 2008 13:40:00 -0400 Subject: [PATCH 058/149] Add the "amd" driver to magic driver selection. --- hw/xfree86/common/xf86AutoConfig.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/hw/xfree86/common/xf86AutoConfig.c b/hw/xfree86/common/xf86AutoConfig.c index e3e0bb3a3..268b50cb5 100644 --- a/hw/xfree86/common/xf86AutoConfig.c +++ b/hw/xfree86/common/xf86AutoConfig.c @@ -140,12 +140,13 @@ videoPtrToDriverName(struct pci_device *dev) { /* * things not handled yet: - * amd/cyrix/nsc - * xgi + * cyrix/nsc. should be merged into geode anyway. + * xgi. */ switch (dev->vendor_id) { + case 0x1022: return "amd"; case 0x1142: return "apm"; case 0xedd8: return "ark"; case 0x1a03: return "ast"; From b2657ec5981122e7cc0bda0d8802aec63cde9014 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 6 Feb 2008 16:51:57 -0800 Subject: [PATCH 059/149] XkbCopyKeymap was mangling doodads and overlays --- xkb/xkbUtils.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/xkb/xkbUtils.c b/xkb/xkbUtils.c index b3132701d..a3ae655f0 100644 --- a/xkb/xkbUtils.c +++ b/xkb/xkbUtils.c @@ -1796,6 +1796,7 @@ XkbCopyKeymap(XkbDescPtr src, XkbDescPtr dst, Bool sendNotifies) dsection = dst->geom->sections; i < src->geom->num_sections; i++, ssection++, dsection++) { + *dsection = *ssection; if (ssection->num_rows) { tmp = xcalloc(ssection->num_rows, sizeof(XkbRowRec)); if (!tmp) @@ -1830,6 +1831,7 @@ XkbCopyKeymap(XkbDescPtr src, XkbDescPtr dst, Bool sendNotifies) dsection->doodads = NULL; } + dsection->sz_doodads = ssection->num_doodads; for (k = 0, sdoodad = ssection->doodads, ddoodad = dsection->doodads; @@ -1850,8 +1852,9 @@ XkbCopyKeymap(XkbDescPtr src, XkbDescPtr dst, Bool sendNotifies) } ddoodad->any.type = sdoodad->any.type; } - dsection->num_doodads = ssection->num_doodads; - dsection->sz_doodads = ssection->num_doodads; + dsection->overlays = NULL; + dsection->sz_overlays = 0; + dsection->num_overlays = 0; } } else { From bc504ffbba3dec2e3467bab8ba1ac25db6dd317e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Tue, 11 Mar 2008 00:35:31 -0400 Subject: [PATCH 060/149] DRI2: Add DRI2AuthConnection(). DRI2 uses the same authentication scheme as XF86DRI, so implement this entry point so DRI2 protocol code can access it. --- hw/xfree86/dri2/dri2.c | 11 +++++++++++ hw/xfree86/dri2/dri2.h | 2 ++ 2 files changed, 13 insertions(+) diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c index d2664b1cb..d5273877e 100644 --- a/hw/xfree86/dri2/dri2.c +++ b/hw/xfree86/dri2/dri2.c @@ -342,6 +342,17 @@ DRI2Connect(ScreenPtr pScreen, int *fd, const char **driverName, return TRUE; } +Bool +DRI2AuthConnection(ScreenPtr pScreen, drm_magic_t magic) +{ + DRI2ScreenPtr ds = DRI2GetScreen(pScreen); + + if (ds == NULL || drmAuthMagic(ds->fd, magic)) + return FALSE; + + return TRUE; +} + unsigned int DRI2GetPixmapHandle(PixmapPtr pPixmap, unsigned int *flags) { diff --git a/hw/xfree86/dri2/dri2.h b/hw/xfree86/dri2/dri2.h index a31908508..126087a2f 100644 --- a/hw/xfree86/dri2/dri2.h +++ b/hw/xfree86/dri2/dri2.h @@ -58,6 +58,8 @@ Bool DRI2Connect(ScreenPtr pScreen, const char **driverName, unsigned int *sareaHandle); +Bool DRI2AuthConnection(ScreenPtr pScreen, drm_magic_t magic); + unsigned int DRI2GetPixmapHandle(PixmapPtr pPixmap, unsigned int *flags); From cc05255191413b3f376edbc600122ff085f45f7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Tue, 11 Mar 2008 00:51:43 -0400 Subject: [PATCH 061/149] Make WriteToClient take a const void * like any decent IO write function. Enough with the casting. Doesn't break API or even ABI, but does make a lot of silly casts superfluos. --- include/os.h | 4 ++-- os/io.c | 10 ++++++---- os/osdep.h | 2 +- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/include/os.h b/include/os.h index 4be6b8010..c0f04c6af 100644 --- a/include/os.h +++ b/include/os.h @@ -115,7 +115,7 @@ extern void FlushIfCriticalOutputPending(void); extern void SetCriticalOutputPending(void); -extern int WriteToClient(ClientPtr /*who*/, int /*count*/, char* /*buf*/); +extern int WriteToClient(ClientPtr /*who*/, int /*count*/, const void* /*buf*/); extern void ResetOsBuffers(void); @@ -448,7 +448,7 @@ typedef struct { extern CallbackListPtr ReplyCallback; typedef struct { ClientPtr client; - pointer replyData; + const void *replyData; unsigned long dataLenBytes; unsigned long bytesRemaining; Bool startOfReply; diff --git a/os/io.c b/os/io.c index e7ec60952..4f4a10903 100644 --- a/os/io.c +++ b/os/io.c @@ -730,11 +730,12 @@ SetCriticalOutputPending(void) *****************/ _X_EXPORT int -WriteToClient (ClientPtr who, int count, char *buf) +WriteToClient (ClientPtr who, int count, const void *__buf) { OsCommPtr oc = (OsCommPtr)who->osPrivate; ConnectionOutputPtr oco = oc->output; int padBytes; + const char *buf = __buf; #ifdef DEBUG_COMMUNICATION Bool multicount = FALSE; #endif @@ -871,13 +872,14 @@ WriteToClient (ClientPtr who, int count, char *buf) **********************/ int -FlushClient(ClientPtr who, OsCommPtr oc, char *extraBuf, int extraCount) +FlushClient(ClientPtr who, OsCommPtr oc, const void *__extraBuf, int extraCount) { ConnectionOutputPtr oco = oc->output; int connection = oc->fd; XtransConnInfo trans_conn = oc->trans_conn; struct iovec iov[3]; static char padBuffer[3]; + const char *extraBuf = __extraBuf; long written; long padsize; long notWritten; @@ -916,14 +918,14 @@ FlushClient(ClientPtr who, OsCommPtr oc, char *extraBuf, int extraCount) before = (-len); \ } else { \ iov[i].iov_len = len; \ - iov[i].iov_base = (pointer) + before; \ + iov[i].iov_base = (pointer) + before; \ i++; \ remain -= len; \ before = 0; \ } InsertIOV ((char *)oco->buf, oco->count) - InsertIOV (extraBuf, extraCount) + InsertIOV ((char *)extraBuf, extraCount) InsertIOV (padBuffer, padsize) errno = 0; diff --git a/os/osdep.h b/os/osdep.h index b6894c146..84f7177db 100644 --- a/os/osdep.h +++ b/os/osdep.h @@ -184,7 +184,7 @@ typedef struct _osComm { extern int FlushClient( ClientPtr /*who*/, OsCommPtr /*oc*/, - char* /*extraBuf*/, + const void * /*extraBuf*/, int /*extraCount*/ ); From c7536f4b87e089a7e7c43026b189922fec70c565 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Tue, 11 Mar 2008 13:11:04 -0400 Subject: [PATCH 062/149] Silence REGION_INIT() warning. Evaluating the address of a BoxRec as a boolean gives this warning: i830_driver.c:2317: warning: the address of 'ScreenBox' will always evaluate as 'true' which is pretty annoying. This patch compares the address to NULL to avoid the pointer->bool conversion and gets rid of the warning. Seems like a lame hack, but the warning is worse. --- include/regionstr.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/regionstr.h b/include/regionstr.h index f44cab7b0..5a79b1228 100644 --- a/include/regionstr.h +++ b/include/regionstr.h @@ -158,7 +158,7 @@ extern RegDataRec miBrokenData; #define REGION_INIT(_pScreen, _pReg, _rect, _size) \ { \ - if (_rect) \ + if ((_rect) != NULL) \ { \ (_pReg)->extents = *(_rect); \ (_pReg)->data = (RegDataPtr)NULL; \ From 2036851125226065891f13583ade3ce559e7bd37 Mon Sep 17 00:00:00 2001 From: Matthias Hopf Date: Mon, 10 Mar 2008 19:29:07 +0100 Subject: [PATCH 063/149] Return randr interface version in xf86CrtcScreenInit() Necessary to allow drivers to be run-time backwards compatible when using the modes/ functions w/o providing their own copy. --- hw/xfree86/modes/xf86Crtc.c | 13 +++++++++++-- hw/xfree86/modes/xf86Crtc.h | 4 ++++ randr/randrstr.h | 2 ++ 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c index 0bef5b42f..39e84e641 100644 --- a/hw/xfree86/modes/xf86Crtc.c +++ b/hw/xfree86/modes/xf86Crtc.c @@ -694,7 +694,12 @@ xf86CrtcCloseScreen (int index, ScreenPtr screen) /* * Called at ScreenInit time to set up */ -_X_EXPORT Bool +_X_EXPORT +#ifdef RANDR_13_INTERFACE +int +#else +Bool +#endif xf86CrtcScreenInit (ScreenPtr screen) { ScrnInfoPtr scrn = xf86Screens[screen->myNum]; @@ -727,7 +732,11 @@ xf86CrtcScreenInit (ScreenPtr screen) config->CloseScreen = screen->CloseScreen; screen->CloseScreen = xf86CrtcCloseScreen; +#ifdef RANDR_13_INTERFACE + return RANDR_INTERFACE_VERSION; +#else return TRUE; +#endif } static DisplayModePtr @@ -2228,7 +2237,7 @@ xf86SetSingleMode (ScrnInfoPtr pScrn, DisplayModePtr desired, Rotation rotation) } } xf86DisableUnusedFunctions(pScrn); -#if RANDR_12_INTERFACE +#ifdef RANDR_12_INTERFACE xf86RandR12TellChanged (pScrn->pScreen); #endif return ok; diff --git a/hw/xfree86/modes/xf86Crtc.h b/hw/xfree86/modes/xf86Crtc.h index b87a32548..a542e7f39 100644 --- a/hw/xfree86/modes/xf86Crtc.h +++ b/hw/xfree86/modes/xf86Crtc.h @@ -692,7 +692,11 @@ xf86ProbeOutputModes (ScrnInfoPtr pScrn, int maxX, int maxY); void xf86SetScrnInfoModes (ScrnInfoPtr pScrn); +#ifdef RANDR_13_INTERFACE +int +#else Bool +#endif xf86CrtcScreenInit (ScreenPtr pScreen); Bool diff --git a/randr/randrstr.h b/randr/randrstr.h index 3b48f5c2b..4d7c9ccfc 100644 --- a/randr/randrstr.h +++ b/randr/randrstr.h @@ -56,6 +56,8 @@ #define RANDR_12_INTERFACE 1 #define RANDR_13_INTERFACE 1 /* requires RANDR_12_INTERFACE */ +#define RANDR_INTERFACE_VERSION 0x0103 + typedef XID RRMode; typedef XID RROutput; typedef XID RRCrtc; From 06c0372c3a1b45005eb6d50406f77f4e93f1de1e Mon Sep 17 00:00:00 2001 From: Mark Kettenis Date: Wed, 12 Mar 2008 21:45:37 +0100 Subject: [PATCH 064/149] OpenBSD support for libpciaccess. xserver and libpciaccess both need to open /dev/xf86, which can only be opened once. I implemented pci_system_init_dev_mem() like Ian suggested. This requires some minor changes to the BSD-specific os-support code. Since pci_system_init_dev_mem() is a no-op on FreeBSD this should be no problem. --- hw/xfree86/os-support/bsd/i386_video.c | 3 +++ hw/xfree86/os-support/bus/bsd_pci.c | 2 ++ hw/xfree86/utils/ioport/Makefile.am | 2 +- 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/hw/xfree86/os-support/bsd/i386_video.c b/hw/xfree86/os-support/bsd/i386_video.c index 0dcff6631..7e4a4d2a3 100644 --- a/hw/xfree86/os-support/bsd/i386_video.c +++ b/hw/xfree86/os-support/bsd/i386_video.c @@ -212,6 +212,9 @@ xf86OSInitVidMem(VidMemInfoPtr pVidMem) pVidMem->mapMem = mapVidMem; pVidMem->unmapMem = unmapVidMem; + if (useDevMem) + pci_system_init_dev_mem(devMemFd); + #ifdef HAS_MTRR_SUPPORT if (useDevMem) { if (cleanMTRR()) { diff --git a/hw/xfree86/os-support/bus/bsd_pci.c b/hw/xfree86/os-support/bus/bsd_pci.c index bceb1087f..57ad09b6a 100644 --- a/hw/xfree86/os-support/bus/bsd_pci.c +++ b/hw/xfree86/os-support/bus/bsd_pci.c @@ -81,4 +81,6 @@ bsdPciInit(void) { pciNumBuses = 1; pciBusInfo[0] = &bsd_pci; + + xf86InitVidMem(); } diff --git a/hw/xfree86/utils/ioport/Makefile.am b/hw/xfree86/utils/ioport/Makefile.am index c1f9453a8..12f861372 100644 --- a/hw/xfree86/utils/ioport/Makefile.am +++ b/hw/xfree86/utils/ioport/Makefile.am @@ -37,7 +37,7 @@ ioport_CFLAGS = $(DIX_CFLAGS) $(XORG_CFLAGS) ioport_LDADD = \ ../../os-support/libxorgos.la \ ../../dummylib/libdummy-nonserver.a \ - ${UTILS_SYS_LIBS} + ${UTILS_SYS_LIBS} ${PCIACCESS_LIBS} ioport_SOURCES = \ From 61c3f63a75d8b0cc47ffed4a0e30147fab2ae8f4 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Thu, 13 Mar 2008 17:34:54 -0400 Subject: [PATCH 065/149] RANDR 1.2: Don't report a square resolution to RANDR 1.1 clients. It can't possibly do anything useful, and older versions of Gnome (and proably others) get very confused by it. So do the drivers, for that matter. --- hw/xfree86/modes/xf86RandR12.c | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/hw/xfree86/modes/xf86RandR12.c b/hw/xfree86/modes/xf86RandR12.c index 816175cc3..af950e61c 100644 --- a/hw/xfree86/modes/xf86RandR12.c +++ b/hw/xfree86/modes/xf86RandR12.c @@ -145,23 +145,6 @@ xf86RandR12GetInfo (ScreenPtr pScreen, Rotation *rotations) randrp->maxY = maxY; } - if (scrp->currentMode->HDisplay != randrp->virtualX || - scrp->currentMode->VDisplay != randrp->virtualY) - { - pSize = RRRegisterSize (pScreen, - randrp->virtualX, randrp->virtualY, - randrp->mmWidth, - randrp->mmHeight); - if (!pSize) - return FALSE; - RRRegisterRate (pScreen, pSize, refresh0); - if (scrp->virtualX == randrp->virtualX && - scrp->virtualY == randrp->virtualY) - { - RRSetCurrentConfig (pScreen, randrp->rotation, refresh0, pSize); - } - } - return TRUE; } From 5d7437c29e686a081b20823450d78c4c2f4e0aec Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Thu, 13 Mar 2008 17:37:12 -0400 Subject: [PATCH 066/149] RANDR 1.2: Fix the RANDR 1.1 screen size estimation to approach reality. While the ScreenRec's notion of size in millimeters would get updates, the RANDR 1.1 notion wouldn't, so your screen would appear to be square and probably at some ludicrous DPI. --- hw/xfree86/modes/xf86RandR12.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/xfree86/modes/xf86RandR12.c b/hw/xfree86/modes/xf86RandR12.c index af950e61c..1dca223fe 100644 --- a/hw/xfree86/modes/xf86RandR12.c +++ b/hw/xfree86/modes/xf86RandR12.c @@ -355,8 +355,8 @@ xf86RandR12ScreenSetSize (ScreenPtr pScreen, pScreen->width = pScrnPix->drawable.width = width; pScreen->height = pScrnPix->drawable.height = height; - pScreen->mmWidth = mmWidth; - pScreen->mmHeight = mmHeight; + randrp->mmWidth = pScreen->mmWidth = mmWidth; + randrp->mmHeight = pScreen->mmHeight = mmHeight; xf86SetViewport (pScreen, pScreen->width-1, pScreen->height-1); xf86SetViewport (pScreen, 0, 0); From f7abe05b3306ed9a6f2cf5e3e45ed524d725d029 Mon Sep 17 00:00:00 2001 From: Doug Chapman Date: Thu, 13 Mar 2008 17:40:34 -0400 Subject: [PATCH 067/149] Bug #14091: Fix build (and runtime) on ia64. --- hw/xfree86/os-support/bus/Makefile.am | 12 ------ hw/xfree86/os-support/bus/Pci.h | 3 +- hw/xfree86/os-support/linux/Makefile.am | 2 +- hw/xfree86/os-support/shared/ia64Pci.c | 55 ------------------------- 4 files changed, 2 insertions(+), 70 deletions(-) diff --git a/hw/xfree86/os-support/bus/Makefile.am b/hw/xfree86/os-support/bus/Makefile.am index 381b9923c..5a15430c1 100644 --- a/hw/xfree86/os-support/bus/Makefile.am +++ b/hw/xfree86/os-support/bus/Makefile.am @@ -27,18 +27,6 @@ if LINUX_ALPHA PCI_SOURCES += axpPci.c endif -if LINUX_IA64 -PLATFORM_PCI_SOURCES = \ - 460gxPCI.c \ - 460gxPCI.h \ - altixPCI.c \ - altixPCI.h \ - e8870PCI.c \ - e8870PCI.h \ - zx1PCI.c \ - zx1PCI.h -endif - if XORG_BUS_SPARC PLATFORM_SOURCES = Sbus.c sdk_HEADERS += xf86Sbus.h diff --git a/hw/xfree86/os-support/bus/Pci.h b/hw/xfree86/os-support/bus/Pci.h index 0abb34f98..ebac0905b 100644 --- a/hw/xfree86/os-support/bus/Pci.h +++ b/hw/xfree86/os-support/bus/Pci.h @@ -207,9 +207,8 @@ # endif #elif defined(__ia64__) # if defined(linux) -# define ARCH_PCI_INIT ia64linuxPciInit +# define ARCH_PCI_INIT linuxPciInit # endif -# define XF86SCANPCI_WRAPPER ia64ScanPCIWrapper #elif defined(__i386__) || defined(__i386) # if defined(linux) # define ARCH_PCI_INIT linuxPciInit diff --git a/hw/xfree86/os-support/linux/Makefile.am b/hw/xfree86/os-support/linux/Makefile.am index 5a52ffdd4..beaae3d5b 100644 --- a/hw/xfree86/os-support/linux/Makefile.am +++ b/hw/xfree86/os-support/linux/Makefile.am @@ -1,7 +1,7 @@ noinst_LTLIBRARIES = liblinux.la if LINUX_IA64 -PLATFORM_PCI_SUPPORT = $(srcdir)/lnx_ia64.c $(srcdir)/../shared/ia64Pci.c +PLATFORM_PCI_SUPPORT = $(srcdir)/../shared/ia64Pci.c PLATFORM_DEFINES = -DOS_PROBE_PCI_CHIPSET=lnxProbePciChipset PLATFORM_INCLUDES = -I$(srcdir)/../shared endif diff --git a/hw/xfree86/os-support/shared/ia64Pci.c b/hw/xfree86/os-support/shared/ia64Pci.c index 45522e933..6f6924b59 100644 --- a/hw/xfree86/os-support/shared/ia64Pci.c +++ b/hw/xfree86/os-support/shared/ia64Pci.c @@ -42,12 +42,7 @@ #include #include "compiler.h" -#include "460gxPCI.h" -#include "e8870PCI.h" -#include "zx1PCI.h" -#include "altixPCI.h" #include "Pci.h" -#include "ia64Pci.h" /* * We use special in/out routines here since Altix platforms require the @@ -191,53 +186,3 @@ _X_EXPORT unsigned int inl(unsigned long port) return val; } -void -ia64ScanPCIWrapper(scanpciWrapperOpt flags) -{ - static IA64Chipset chipset = NONE_CHIPSET; - - if (flags == SCANPCI_INIT) { - - /* PCI configuration space probes should be done first */ - if (xorgProbe460GX(flags)) { - chipset = I460GX_CHIPSET; - xf86PreScan460GX(); - return; - } else if (xorgProbeE8870(flags)) { - chipset = E8870_CHIPSET; - xf86PreScanE8870(); - return; - } -#ifdef OS_PROBE_PCI_CHIPSET - chipset = OS_PROBE_PCI_CHIPSET(flags); - switch (chipset) { - case ZX1_CHIPSET: - xf86PreScanZX1(); - return; - case ALTIX_CHIPSET: - xf86PreScanAltix(); - return; - default: - return; - } -#endif - } else /* if (flags == SCANPCI_TERM) */ { - - switch (chipset) { - case I460GX_CHIPSET: - xf86PostScan460GX(); - return; - case E8870_CHIPSET: - xf86PostScanE8870(); - return; - case ZX1_CHIPSET: - xf86PostScanZX1(); - return; - case ALTIX_CHIPSET: - xf86PostScanAltix(); - return; - default: - return; - } - } -} From 1b9878ffcfc0c0dbc4a6e674827fe508ba77db4b Mon Sep 17 00:00:00 2001 From: Bart Trojanowski Date: Thu, 13 Mar 2008 17:42:16 -0400 Subject: [PATCH 068/149] Bug #14332: Fix PCI access cycles from x86emu. The address written to 0xcf8 contains the PCI slot address to send the config cycle to. However, we would ignore that and always send the cycle to the device whose BIOS we were running. This breaks some integrated graphics platforms that have explicit knowledge about the system's host bridge, for example. --- hw/xfree86/int10/helper_exec.c | 57 +++++++++++++++++++++++++++++----- 1 file changed, 50 insertions(+), 7 deletions(-) diff --git a/hw/xfree86/int10/helper_exec.c b/hw/xfree86/int10/helper_exec.c index de6fde5d8..9daff22dc 100644 --- a/hw/xfree86/int10/helper_exec.c +++ b/hw/xfree86/int10/helper_exec.c @@ -33,6 +33,7 @@ #ifdef _X86EMU #include "x86emu/x86emui.h" #endif +#include static int pciCfg1in(CARD16 addr, CARD32 *val); static int pciCfg1out(CARD16 addr, CARD32 val); @@ -459,7 +460,43 @@ Mem_wl(CARD32 addr, CARD32 val) static CARD32 PciCfg1Addr = 0; -#define OFFSET(Cfg1Addr) (Cfg1Addr & 0xff) +#define PCI_OFFSET(x) ((x) & 0x000000ff) +#define PCI_TAG(x) ((x) & 0xffffff00) + +static struct pci_device* +pci_device_for_cfg_address (CARD32 addr) +{ + struct pci_device *dev = NULL; + PCITAG tag = PCI_TAG(addr); + struct pci_slot_match slot_match = { + .domain = PCI_DOM_FROM_TAG(tag), + .bus = PCI_BUS_NO_DOMAIN(PCI_BUS_FROM_TAG(tag)), + .dev = PCI_DEV_FROM_TAG(tag), + .func = PCI_FUNC_FROM_TAG(tag), + .match_data = 0 + }; + + struct pci_device_iterator *iter = + pci_slot_match_iterator_create (&slot_match); + if (iter) + dev = pci_device_next(iter); + if (!dev) { + char buf[128]; /* enough to store "%u@%u" */ + xf86FormatPciBusNumber(tag >> 16, buf); + ErrorF("Failed to find device matching %s:%u:%u\n", + buf, slot_match.dev, slot_match.func); + return NULL; + } + + if (pci_device_next(iter)) { + char buf[128]; /* enough to store "%u@%u" */ + xf86FormatPciBusNumber(tag >> 16, buf); + ErrorF("Multiple devices matching %s:%u:%u\n", + buf, slot_match.dev, slot_match.func); + } + + return dev; +} static int pciCfg1in(CARD16 addr, CARD32 *val) @@ -469,7 +506,8 @@ pciCfg1in(CARD16 addr, CARD32 *val) return 1; } if (addr == 0xCFC) { - pci_device_cfg_read_u32(Int10Current->dev, val, OFFSET(PciCfg1Addr)); + pci_device_cfg_read_u32(pci_device_for_cfg_address(PciCfg1Addr), + val, PCI_OFFSET(PciCfg1Addr)); if (PRINT_PORT && DEBUG_IO_TRACE()) ErrorF(" cfg_inl(%#x) = %8.8x\n", PciCfg1Addr, *val); return 1; @@ -487,7 +525,8 @@ pciCfg1out(CARD16 addr, CARD32 val) if (addr == 0xCFC) { if (PRINT_PORT && DEBUG_IO_TRACE()) ErrorF(" cfg_outl(%#x, %8.8x)\n", PciCfg1Addr, val); - pci_device_cfg_write_u32(Int10Current->dev, val, OFFSET(PciCfg1Addr)); + pci_device_cfg_write_u32(pci_device_for_cfg_address(PciCfg1Addr), + val, PCI_OFFSET(PciCfg1Addr)); return 1; } return 0; @@ -506,7 +545,8 @@ pciCfg1inw(CARD16 addr, CARD16 *val) if ((addr >= 0xCFC) && (addr <= 0xCFF)) { const unsigned offset = addr - 0xCFC; - pci_device_cfg_read_u16(Int10Current->dev, val, OFFSET(PciCfg1Addr) + offset); + pci_device_cfg_read_u16(pci_device_for_cfg_address(PciCfg1Addr), + val, PCI_OFFSET(PciCfg1Addr) + offset); if (PRINT_PORT && DEBUG_IO_TRACE()) ErrorF(" cfg_inw(%#x) = %4.4x\n", PciCfg1Addr + offset, *val); return 1; @@ -530,7 +570,8 @@ pciCfg1outw(CARD16 addr, CARD16 val) if (PRINT_PORT && DEBUG_IO_TRACE()) ErrorF(" cfg_outw(%#x, %4.4x)\n", PciCfg1Addr + offset, val); - pci_device_cfg_write_u16(Int10Current->dev, val, OFFSET(PciCfg1Addr) + offset); + pci_device_cfg_write_u16(pci_device_for_cfg_address(PciCfg1Addr), + val, PCI_OFFSET(PciCfg1Addr) + offset); return 1; } return 0; @@ -549,7 +590,8 @@ pciCfg1inb(CARD16 addr, CARD8 *val) if ((addr >= 0xCFC) && (addr <= 0xCFF)) { const unsigned offset = addr - 0xCFC; - pci_device_cfg_read_u8(Int10Current->dev, val, OFFSET(PciCfg1Addr) + offset); + pci_device_cfg_read_u8(pci_device_for_cfg_address(PciCfg1Addr), + val, PCI_OFFSET(PciCfg1Addr) + offset); if (PRINT_PORT && DEBUG_IO_TRACE()) ErrorF(" cfg_inb(%#x) = %2.2x\n", PciCfg1Addr + offset, *val); return 1; @@ -573,7 +615,8 @@ pciCfg1outb(CARD16 addr, CARD8 val) if (PRINT_PORT && DEBUG_IO_TRACE()) ErrorF(" cfg_outb(%#x, %2.2x)\n", PciCfg1Addr + offset, val); - pci_device_cfg_write_u8(Int10Current->dev, val, OFFSET(PciCfg1Addr) + offset); + pci_device_cfg_write_u8(pci_device_for_cfg_address(PciCfg1Addr), + val, PCI_OFFSET(PciCfg1Addr) + offset); return 1; } return 0; From 824853772241acf64bc37ac8b85254194741ae13 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Fri, 14 Mar 2008 14:24:21 -0400 Subject: [PATCH 069/149] RANDR 1.2: Fix initial mode aspect ratio match in a corner case. Actually more like in the mainline case, where the ideal mode happens to be the very first aspect match on the first monitor. But let's not split hairs. --- hw/xfree86/modes/xf86Crtc.c | 55 +++++++++++++++++++------------------ 1 file changed, 29 insertions(+), 26 deletions(-) diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c index 39e84e641..6b845b7c9 100644 --- a/hw/xfree86/modes/xf86Crtc.c +++ b/hw/xfree86/modes/xf86Crtc.c @@ -1683,14 +1683,19 @@ aspectMatch(float a, float b) } static DisplayModePtr -nextAspectMode(DisplayModePtr start, float aspect) +nextAspectMode(xf86OutputPtr o, DisplayModePtr last, float aspect) { - DisplayModePtr m = start; + DisplayModePtr m = NULL; - if (!m) + if (!o) return NULL; - for (m = m->next; m; m = m->next) + if (!last) + m = o->probed_modes; + else + m = last->next; + + for (; m; m = m->next) if (aspectMatch(aspect, (float)m->HDisplay / (float)m->VDisplay)) return m; @@ -1700,31 +1705,29 @@ nextAspectMode(DisplayModePtr start, float aspect) static DisplayModePtr bestModeForAspect(xf86CrtcConfigPtr config, Bool *enabled, float aspect) { - int o, p; - DisplayModePtr mode, test = NULL, match = NULL; + int o = -1, p; + DisplayModePtr mode = NULL, test = NULL, match = NULL; - for (o = -1; nextEnabledOutput(config, enabled, &o); ) { - mode = config->output[o]->probed_modes; - while ((mode = nextAspectMode(mode, aspect))) { - for (p = o; nextEnabledOutput(config, enabled, &p); ) { - test = xf86OutputFindClosestMode(config->output[p], mode); - if (!test) - break; - if (test->HDisplay != mode->HDisplay || - test->VDisplay != mode->VDisplay) { - test = NULL; - break; - } - } - - /* if we didn't match it on all outputs, try the next one */ + nextEnabledOutput(config, enabled, &o); + while ((mode = nextAspectMode(config->output[o], mode, aspect))) { + for (p = o; nextEnabledOutput(config, enabled, &p); ) { + test = xf86OutputFindClosestMode(config->output[p], mode); if (!test) - continue; - - /* if it's bigger than the last one, save it */ - if (!match || (test->HDisplay > match->HDisplay)) - match = test; + break; + if (test->HDisplay != mode->HDisplay || + test->VDisplay != mode->VDisplay) { + test = NULL; + break; + } } + + /* if we didn't match it on all outputs, try the next one */ + if (!test) + continue; + + /* if it's bigger than the last one, save it */ + if (!match || (test->HDisplay > match->HDisplay)) + match = test; } /* return the biggest one found */ From 57d48d94b8947c571925e6fd4c9bf041fbd1b2ac Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Fri, 14 Mar 2008 14:37:42 -0400 Subject: [PATCH 070/149] Fix a stray use of ALLOCATE_LOCAL. --- hw/xfree86/xf4bpp/ppcSpMcro.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/hw/xfree86/xf4bpp/ppcSpMcro.h b/hw/xfree86/xf4bpp/ppcSpMcro.h index 2b7f951d4..655a883e5 100644 --- a/hw/xfree86/xf4bpp/ppcSpMcro.h +++ b/hw/xfree86/xf4bpp/ppcSpMcro.h @@ -28,11 +28,11 @@ #define SETSPANPTRS(IN,N,IPW,PW,IPPT,PPT,FPW,FPPT,FSORT) \ { \ N = IN * miFindMaxBand(pGC->pCompositeClip); \ - if(!(PW = (int *)ALLOCATE_LOCAL(N * sizeof(int)))) \ + if(!(PW = (int *)xalloc(N * sizeof(int)))) \ return; \ - if(!(PPT = (DDXPointRec *)ALLOCATE_LOCAL(N * sizeof(DDXPointRec)))) \ + if(!(PPT = (DDXPointRec *)xalloc(N * sizeof(DDXPointRec)))) \ { \ - DEALLOCATE_LOCAL(PW); \ + free(PW); \ return; \ } \ FPW = PW; \ From 88bec0915e3867f8dbf859a3dfbb771d0d07092d Mon Sep 17 00:00:00 2001 From: Daniel Stone Date: Fri, 14 Mar 2008 21:54:13 +0200 Subject: [PATCH 071/149] mi: More meaningful assert crashes When we fail an assert in miregion.c (which happens every now and then, though I haven't yet checked up why), at least generate a segfault, so we'll get a backtrace. --- mi/miregion.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/mi/miregion.c b/mi/miregion.c index 45768a34f..69ecdc246 100644 --- a/mi/miregion.c +++ b/mi/miregion.c @@ -89,9 +89,14 @@ Equipment Corporation. #undef assert #ifdef DEBUG -#define assert(expr) {if (!(expr)) \ - FatalError("Assertion failed file %s, line %d: expr\n", \ - __FILE__, __LINE__); } +#define assert(expr) { \ + CARD32 *foo = NULL; \ + if (!(expr)) { \ + ErrorF("Assertion failed file %s, line %d: %s\n", \ + __FILE__, __LINE__, #expr); \ + *foo = 0xdeadbeef; /* to get a backtrace */ \ + } \ + } #else #define assert(expr) #endif From 090b26db767d296e7a3452da83b136d1caa0ed01 Mon Sep 17 00:00:00 2001 From: Daniel Stone Date: Fri, 14 Mar 2008 21:58:27 +0200 Subject: [PATCH 072/149] XkbCopyKeymap: Fix broken indentation An astute observer will note that the entirety of XkbCopyKeymap is indented with spaces, and no tabs whatsoever, and not commit changes which break the otherwise consistent indentation. A non-astute observer will note the breakage when the commit mail comes through with clearly broken indentation. A polite, non-astute, observer will then fix it. C'est la vie. --- xkb/xkbUtils.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/xkb/xkbUtils.c b/xkb/xkbUtils.c index a3ae655f0..8339cef00 100644 --- a/xkb/xkbUtils.c +++ b/xkb/xkbUtils.c @@ -1796,7 +1796,7 @@ XkbCopyKeymap(XkbDescPtr src, XkbDescPtr dst, Bool sendNotifies) dsection = dst->geom->sections; i < src->geom->num_sections; i++, ssection++, dsection++) { - *dsection = *ssection; + *dsection = *ssection; if (ssection->num_rows) { tmp = xcalloc(ssection->num_rows, sizeof(XkbRowRec)); if (!tmp) @@ -1852,9 +1852,9 @@ XkbCopyKeymap(XkbDescPtr src, XkbDescPtr dst, Bool sendNotifies) } ddoodad->any.type = sdoodad->any.type; } - dsection->overlays = NULL; - dsection->sz_overlays = 0; - dsection->num_overlays = 0; + dsection->overlays = NULL; + dsection->sz_overlays = 0; + dsection->num_overlays = 0; } } else { From a955c3b587b22b8bf20cb6bedbbec4ad5fcb32ac Mon Sep 17 00:00:00 2001 From: Donnie Berkholz Date: Fri, 14 Mar 2008 18:41:07 -0700 Subject: [PATCH 073/149] Xephyr: Distribute ephyrdriext.h in tarballs. --- hw/kdrive/ephyr/Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/hw/kdrive/ephyr/Makefile.am b/hw/kdrive/ephyr/Makefile.am index d025c201c..81d3d69ea 100644 --- a/hw/kdrive/ephyr/Makefile.am +++ b/hw/kdrive/ephyr/Makefile.am @@ -35,6 +35,7 @@ if XEPHYR_HAS_DRI libxephyr_hostdri_a_SOURCES= \ ephyrdriext.c \ +ephyrdriext.h \ ephyrdri.c \ ephyrdri.h \ XF86dri.c \ From aa231f28d56402d7daea6cbd3002fbf760f79497 Mon Sep 17 00:00:00 2001 From: Donnie Berkholz Date: Fri, 14 Mar 2008 18:41:25 -0700 Subject: [PATCH 074/149] Xephyr: Build fix: Port across XF86dri.c changes from Mesa. --- hw/kdrive/ephyr/XF86dri.c | 37 +++++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/hw/kdrive/ephyr/XF86dri.c b/hw/kdrive/ephyr/XF86dri.c index 506d7bed8..e656ff5a0 100644 --- a/hw/kdrive/ephyr/XF86dri.c +++ b/hw/kdrive/ephyr/XF86dri.c @@ -385,9 +385,8 @@ Bool XF86DRICreateContext(dpy, screen, visual, context, hHWContext) context, hHWContext ); } -GLboolean XF86DRIDestroyContext( __DRInativeDisplay * ndpy, int screen, __DRIid context) +GLboolean XF86DRIDestroyContext( Display *dpy, int screen, XID context) { - Display * const dpy = (Display *) ndpy; XExtDisplayInfo *info = find_display (dpy); xXF86DRIDestroyContextReq *req; @@ -407,10 +406,9 @@ GLboolean XF86DRIDestroyContext( __DRInativeDisplay * ndpy, int screen, __DRIid } GLboolean -XF86DRICreateDrawable (__DRInativeDisplay * ndpy, int screen, - __DRIid drawable, drm_drawable_t * hHWDrawable) +XF86DRICreateDrawable (Display *dpy, int screen, + XID drawable, drm_drawable_t * hHWDrawable) { - Display * const dpy = (Display *) ndpy; XExtDisplayInfo *info = find_display (dpy); xXF86DRICreateDrawableReply rep; xXF86DRICreateDrawableReq *req; @@ -437,16 +435,36 @@ XF86DRICreateDrawable (__DRInativeDisplay * ndpy, int screen, return True; } -GLboolean XF86DRIDestroyDrawable( __DRInativeDisplay * ndpy, int screen, - __DRIid drawable ) +static int noopErrorHandler(Display *dpy, XErrorEvent *xerr) +{ + return 0; +} + +GLboolean XF86DRIDestroyDrawable( Display *dpy, int screen, + XID drawable ) { - Display * const dpy = (Display *) ndpy; XExtDisplayInfo *info = find_display (dpy); xXF86DRIDestroyDrawableReq *req; + int (*oldXErrorHandler)(Display *, XErrorEvent *); TRACE("DestroyDrawable..."); XF86DRICheckExtension (dpy, info, False); + /* This is called from the DRI driver, which used call it like this + * + * if (windowExists(drawable)) + * destroyDrawable(drawable); + * + * which is a textbook race condition - the window may disappear + * from the server between checking for its existance and + * destroying it. Instead we change the semantics of + * __DRIinterfaceMethodsRec::destroyDrawable() to succeed even if + * the windows is gone, by wrapping the destroy call in an error + * handler. */ + + XSync(dpy, GL_FALSE); + oldXErrorHandler = XSetErrorHandler(noopErrorHandler); + LockDisplay(dpy); GetReq(XF86DRIDestroyDrawable, req); req->reqType = info->codes->major_opcode; @@ -455,6 +473,9 @@ GLboolean XF86DRIDestroyDrawable( __DRInativeDisplay * ndpy, int screen, req->drawable = drawable; UnlockDisplay(dpy); SyncHandle(); + + XSetErrorHandler(oldXErrorHandler); + TRACE("DestroyDrawable... return True"); return True; } From db248ffb840a0c113b6eb508a0fa1e74e752474d Mon Sep 17 00:00:00 2001 From: Matthieu Herrb Date: Sun, 16 Mar 2008 18:46:11 +0100 Subject: [PATCH 075/149] test for the presence of pci_system_init_dev_mem() before calling it. This avoids creating a dependency on -current libpciaccess for BSD systems other than OpenBSD (which don't otherwise need it). --- configure.ac | 7 +++++++ hw/xfree86/os-support/bsd/i386_video.c | 2 ++ include/xorg-config.h.in | 3 +++ 3 files changed, 12 insertions(+) diff --git a/configure.ac b/configure.ac index 5417bbbda..49f2395fa 100644 --- a/configure.ac +++ b/configure.ac @@ -1308,6 +1308,13 @@ if test "x$XORG" = xyes -o "x$XGL" = xyes; then XORG_LIBS="$COMPOSITE_LIB $FIXES_LIB $XEXTXORG_LIB $GLX_LIBS $RENDER_LIB $RANDR_LIB $DAMAGE_LIB $MIEXT_DAMAGE_LIB $MIEXT_SHADOW_LIB $XI_LIB $XKB_LIB $XPSTUBS_LIB $SELINUX_LIB" PKG_CHECK_MODULES([PCIACCESS], [pciaccess >= 0.8.0]) + SAVE_LIBS=$LIBS + SAVE_CFLAGS=$CFLAGS + CFLAGS=$PCIACCESS_CFLAGS + LIBS=$PCIACCESS_LIBS + AC_CHECK_FUNCS([pci_system_init_dev_mem]) + LIBS=$SAVE_LIBS + CFLAGS=$SAVE_CFLAGS XORG_SYS_LIBS="$XORG_SYS_LIBS $PCIACCESS_LIBS $DLOPEN_LIBS $GLX_SYS_LIBS" XORG_CFLAGS="$XORG_CFLAGS $PCIACCESS_CFLAGS" diff --git a/hw/xfree86/os-support/bsd/i386_video.c b/hw/xfree86/os-support/bsd/i386_video.c index 7e4a4d2a3..1ebac678d 100644 --- a/hw/xfree86/os-support/bsd/i386_video.c +++ b/hw/xfree86/os-support/bsd/i386_video.c @@ -212,8 +212,10 @@ xf86OSInitVidMem(VidMemInfoPtr pVidMem) pVidMem->mapMem = mapVidMem; pVidMem->unmapMem = unmapVidMem; +#if HAVE_PCI_SYSTEM_INIT_DEV_MEM if (useDevMem) pci_system_init_dev_mem(devMemFd); +#endif #ifdef HAS_MTRR_SUPPORT if (useDevMem) { diff --git a/include/xorg-config.h.in b/include/xorg-config.h.in index 0603eab67..5587c0a8d 100644 --- a/include/xorg-config.h.in +++ b/include/xorg-config.h.in @@ -115,6 +115,9 @@ /* Have execinfo.h */ #undef HAVE_EXECINFO_H +/* Have pci_system_init_dev_mem() */ +#undef HAVE_PCI_SYSTEM_INIT_DEV_MEM + /* Path to text files containing PCI IDs */ #undef PCI_TXT_IDS_PATH From bee2ddf35f75086cee951142098637f2c756b96b Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Mon, 17 Mar 2008 08:33:01 -0700 Subject: [PATCH 076/149] Fail CRTC configuration if !vtSema Unless we check for vtSema before calling into the CRTC and output callbacks, we may end up trying to access video memory that no longer exists, leading to a crash. So if we don't have vtSema, return FALSE to the caller, indicating that we didn't do anything. Fixes #14444. --- hw/xfree86/modes/xf86RandR12.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/hw/xfree86/modes/xf86RandR12.c b/hw/xfree86/modes/xf86RandR12.c index 1dca223fe..4767f2671 100644 --- a/hw/xfree86/modes/xf86RandR12.c +++ b/hw/xfree86/modes/xf86RandR12.c @@ -743,6 +743,9 @@ xf86RandR12CrtcSet (ScreenPtr pScreen, xf86CrtcPtr *save_crtcs; Bool save_enabled = crtc->enabled; + if (!crtc->scrn->vtSema) + return FALSE; + save_crtcs = xalloc(config->num_output * sizeof (xf86CrtcPtr)); if ((randr_mode != NULL) != crtc->enabled) changed = TRUE; From ba85caacb565b9aa0aeace52a362350304b0566d Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Mon, 17 Mar 2008 14:13:09 -0700 Subject: [PATCH 077/149] Make xf86SetDesiredModes aware of current output configuration By adding a new output callback, ->get_crtc, xf86SetDesiredModes is able to avoid turning off outputs & CRTCs if the current output<->CRTC mappings are the same as the desired configuration. This helps avoid flickering displays at startup time, which speeds things up a little and looks better. --- hw/xfree86/modes/xf86Crtc.c | 87 +++++++++++++++++++++++++++++-------- hw/xfree86/modes/xf86Crtc.h | 7 +++ randr/randrstr.h | 1 + 3 files changed, 77 insertions(+), 18 deletions(-) diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c index 6b845b7c9..536b53033 100644 --- a/hw/xfree86/modes/xf86Crtc.c +++ b/hw/xfree86/modes/xf86Crtc.c @@ -2033,6 +2033,72 @@ xf86InitialConfiguration (ScrnInfoPtr scrn, Bool canGrow) return TRUE; } +/* + * Check the CRTC we're going to map each output to vs. it's current + * CRTC. If they don't match, we have to disable the output and the CRTC + * since the driver will have to re-route things. + */ +static void +xf86PrepareOutputs (ScrnInfoPtr scrn) +{ + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); + int o; + + for (o = 0; o < config->num_output; o++) { + xf86OutputPtr output = config->output[o]; +#if RANDR_GET_CRTC_INTERFACE + /* If we can't get the current CRTC, play it safe */ + if (!output->funcs->get_crtc) { + (*output->funcs->dpms)(output, DPMSModeOff); + continue; + } + /* Disable outputs that are unused or will be re-routed */ + if (output->crtc != (*output->funcs->get_crtc)(output) || + output->crtc == NULL) +#endif + (*output->funcs->dpms)(output, DPMSModeOff); + } +} + +static void +xf86PrepareCrtcs (ScrnInfoPtr scrn) +{ + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); + int c; + + for (c = 0; c < config->num_crtc; c++) { +#if RANDR_GET_CRTC_INTERFACE + xf86CrtcPtr crtc = config->crtc[c]; + xf86OutputPtr output = NULL; + uint32_t desired_outputs = 0, current_outputs = 0; + int o; + + for (o = 0; o < config->num_output; o++) { + output = config->output[o]; + if (output->crtc == crtc) + desired_outputs |= (1<funcs->get_crtc) { + desired_outputs = 0; + break; + } + if ((*output->funcs->get_crtc)(output) == crtc) + current_outputs |= (1<funcs->dpms)(crtc, DPMSModeOff); +#else + (*crtc->funcs->dpms)(crtc, DPMSModeOff); +#endif + } +} + /* * Using the desired mode information in each crtc, set * modes (used in EnterVT functions, or at server startup) @@ -2042,26 +2108,11 @@ _X_EXPORT Bool xf86SetDesiredModes (ScrnInfoPtr scrn) { xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); - int c, o; + int c; - /* - * Turn off everything so mode setting is done - * with hardware in a consistent state - */ - for (o = 0; o < config->num_output; o++) - { - xf86OutputPtr output = config->output[o]; - (*output->funcs->dpms)(output, DPMSModeOff); - } + xf86PrepareOutputs(scrn); + xf86PrepareCrtcs(scrn); - for (c = 0; c < config->num_crtc; c++) - { - xf86CrtcPtr crtc = config->crtc[c]; - - crtc->funcs->dpms(crtc, DPMSModeOff); - memset(&crtc->mode, 0, sizeof(crtc->mode)); - } - for (c = 0; c < config->num_crtc; c++) { xf86CrtcPtr crtc = config->crtc[c]; diff --git a/hw/xfree86/modes/xf86Crtc.h b/hw/xfree86/modes/xf86Crtc.h index a542e7f39..2d723a5cd 100644 --- a/hw/xfree86/modes/xf86Crtc.h +++ b/hw/xfree86/modes/xf86Crtc.h @@ -424,6 +424,13 @@ typedef struct _xf86OutputFuncs { Bool (*get_property)(xf86OutputPtr output, Atom property); +#endif +#ifdef RANDR_GET_CRTC_INTERFACE + /** + * Callback to get current CRTC for a given output + */ + xf86CrtcPtr + (*get_crtc)(xf86OutputPtr output); #endif /** * Clean up driver-specific bits of the output diff --git a/randr/randrstr.h b/randr/randrstr.h index 4d7c9ccfc..62d4bbf46 100644 --- a/randr/randrstr.h +++ b/randr/randrstr.h @@ -55,6 +55,7 @@ #define RANDR_10_INTERFACE 1 #define RANDR_12_INTERFACE 1 #define RANDR_13_INTERFACE 1 /* requires RANDR_12_INTERFACE */ +#define RANDR_GET_CRTC_INTERFACE 1 #define RANDR_INTERFACE_VERSION 0x0103 From afd7428690d87097117ab20335658f6d59d60103 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Mon, 17 Mar 2008 14:55:44 -0700 Subject: [PATCH 078/149] Cleanup logic in xf86PrepareOutputs Should have done this in the first place. Since we're checking for the absence of the get_crtc callback in the first place, we'll short circuit the later call and disable the output, so the ugly "continue" block is unnecesary. --- hw/xfree86/modes/xf86Crtc.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c index 536b53033..8c2b24786 100644 --- a/hw/xfree86/modes/xf86Crtc.c +++ b/hw/xfree86/modes/xf86Crtc.c @@ -2047,13 +2047,9 @@ xf86PrepareOutputs (ScrnInfoPtr scrn) for (o = 0; o < config->num_output; o++) { xf86OutputPtr output = config->output[o]; #if RANDR_GET_CRTC_INTERFACE - /* If we can't get the current CRTC, play it safe */ - if (!output->funcs->get_crtc) { - (*output->funcs->dpms)(output, DPMSModeOff); - continue; - } /* Disable outputs that are unused or will be re-routed */ - if (output->crtc != (*output->funcs->get_crtc)(output) || + if (!output->funcs->get_crtc || + output->crtc != (*output->funcs->get_crtc)(output) || output->crtc == NULL) #endif (*output->funcs->dpms)(output, DPMSModeOff); From cdadd2ff9bade318caac5c1d9bcdc8a001347da9 Mon Sep 17 00:00:00 2001 From: Dodji Seketeli Date: Tue, 18 Mar 2008 14:00:15 +0100 Subject: [PATCH 079/149] [Xephyr/DRI] correctly route motion events targeted at GL drawable --- hw/kdrive/ephyr/ephyr.c | 34 ++++++++++++++++++++++++++++------ hw/kdrive/ephyr/hostx.c | 3 ++- hw/kdrive/ephyr/hostx.h | 1 + 3 files changed, 31 insertions(+), 7 deletions(-) diff --git a/hw/kdrive/ephyr/ephyr.c b/hw/kdrive/ephyr/ephyr.c index e95001dcd..b02f9903c 100644 --- a/hw/kdrive/ephyr/ephyr.c +++ b/hw/kdrive/ephyr/ephyr.c @@ -891,9 +891,12 @@ ephyrPoll(void) continue; } { - if (ephyrCurScreen != ev.data.mouse_motion.screen) + if (ev.data.mouse_motion.screen >=0 + && (ephyrCurScreen != ev.data.mouse_motion.screen)) { - EPHYR_LOG ("warping mouse cursor:%d\n", ephyrCurScreen) ; + EPHYR_LOG ("warping mouse cursor. " + "cur_screen%d, motion_screen:%d\n", + ephyrCurScreen, ev.data.mouse_motion.screen) ; if (ev.data.mouse_motion.screen >= 0) { ephyrWarpCursor @@ -904,11 +907,30 @@ ephyrPoll(void) } else { + int x=0, y=0; +#ifdef XEPHYR_DRI + EphyrWindowPair *pair = NULL; +#endif EPHYR_LOG ("enqueuing mouse motion:%d\n", ephyrCurScreen) ; - KdEnqueuePointerEvent(ephyrMouse, mouseState, - ev.data.mouse_motion.x, - ev.data.mouse_motion.y, - 0); + x = ev.data.mouse_motion.x; + y = ev.data.mouse_motion.y; + EPHYR_LOG ("initial (x,y):(%d,%d)\n", x, y) ; +#ifdef XEPHYR_DRI + EPHYR_LOG ("is this window peered by a gl drawable ?\n") ; + if (findWindowPairFromRemote (ev.data.mouse_motion.window, + &pair)) + { + EPHYR_LOG ("yes, it is peered\n") ; + x += pair->local->drawable.x; + y += pair->local->drawable.y; + } + else + { + EPHYR_LOG ("no, it is not peered\n") ; + } + EPHYR_LOG ("final (x,y):(%d,%d)\n", x, y) ; +#endif + KdEnqueuePointerEvent(ephyrMouse, mouseState, x, y, 0); } } break; diff --git a/hw/kdrive/ephyr/hostx.c b/hw/kdrive/ephyr/hostx.c index ae1bb4bf9..fd84ec0ef 100644 --- a/hw/kdrive/ephyr/hostx.c +++ b/hw/kdrive/ephyr/hostx.c @@ -914,8 +914,9 @@ hostx_get_event(EphyrHostXEvent *ev) host_screen_from_window (xev.xmotion.window); ev->type = EPHYR_EV_MOUSE_MOTION; - ev->data.mouse_motion.x = xev.xmotion.x; + ev->data.mouse_motion.x = xev.xmotion.x; ev->data.mouse_motion.y = xev.xmotion.y; + ev->data.mouse_motion.window = xev.xmotion.window; ev->data.mouse_motion.screen = (host_screen ? host_screen->mynum : -1); } return 1; diff --git a/hw/kdrive/ephyr/hostx.h b/hw/kdrive/ephyr/hostx.h index f72cfe700..48d314748 100644 --- a/hw/kdrive/ephyr/hostx.h +++ b/hw/kdrive/ephyr/hostx.h @@ -70,6 +70,7 @@ struct EphyrHostXEvent int x; int y; int screen; + int window; } mouse_motion; struct mouse_down { From edad0a9dfebcce5c54b2f9c32bd9d45549e20c51 Mon Sep 17 00:00:00 2001 From: Eamon Walsh Date: Tue, 18 Mar 2008 17:51:21 -0400 Subject: [PATCH 080/149] Apply __glXDisp_GetVisualConfigs message patch From http://bugs.freedesktop.org/show_bug.cgi?id=13863 Problem was that the glxcmds.c __glXDisp_GetVisualConfigs function left garbage in the tail end of the message used for extensions. --- GL/glx/glxcmds.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/GL/glx/glxcmds.c b/GL/glx/glxcmds.c index 32d1bc834..3b79cca20 100644 --- a/GL/glx/glxcmds.c +++ b/GL/glx/glxcmds.c @@ -944,6 +944,12 @@ int __glXDisp_GetVisualConfigs(__GLXclientState *cl, GLbyte *pc) buf[p++] = modes->transparentAlpha; buf[p++] = GLX_TRANSPARENT_INDEX_VALUE; buf[p++] = modes->transparentIndex; + buf[p++] = 0; + buf[p++] = 0; + buf[p++] = 0; + buf[p++] = 0; + buf[p++] = 0; + buf[p++] = 0; if (client->swapped) { __GLX_SWAP_INT_ARRAY(buf, __GLX_TOTAL_CONFIG); From f37046984d7839faefa4d716624e4a85ddde9634 Mon Sep 17 00:00:00 2001 From: Alan Coopersmith Date: Wed, 19 Mar 2008 14:06:53 -0700 Subject: [PATCH 081/149] Xevie cleanups, byteswapping fixes & request length check fixes --- Xext/xevie.c | 39 ++++++++++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/Xext/xevie.c b/Xext/xevie.c index ea409f104..f36ead478 100644 --- a/Xext/xevie.c +++ b/Xext/xevie.c @@ -147,8 +147,6 @@ XevieExtensionInit (void) ReqCode = (unsigned char)extEntry->base; ErrorBase = extEntry->errorBase; } - - /* PC servers initialize the desktop colors (citems) here! */ } /*ARGSUSED*/ @@ -218,6 +216,8 @@ int ProcEnd (register ClientPtr client) { xXevieEndReply rep; + REQUEST_SIZE_MATCH (xXevieEndReq); + if (xevieFlag) { if (client->index != xevieClientIndex) return BadAccess; @@ -240,6 +240,8 @@ int ProcSend (register ClientPtr client) xEvent *xE; static unsigned char lastDetail = 0, lastType = 0; + REQUEST_SIZE_MATCH (xXevieSendReq); + if (client->index != xevieClientIndex) return BadAccess; @@ -284,10 +286,12 @@ int ProcSelectInput (register ClientPtr client) REQUEST (xXevieSelectInputReq); xXevieSelectInputReply rep; + REQUEST_SIZE_MATCH (xXevieSelectInputReq); + if (client->index != xevieClientIndex) return BadAccess; - xevieMask = (long)stuff->event_mask; + xevieMask = stuff->event_mask; rep.type = X_Reply; rep.sequence_number = client->sequence; WriteToClient (client, sizeof (xXevieSelectInputReply), (char *)&rep); @@ -321,7 +325,10 @@ int SProcQueryVersion (register ClientPtr client) register int n; REQUEST(xXevieQueryVersionReq); - swaps(&stuff->length, n); + swaps (&stuff->length, n); + REQUEST_SIZE_MATCH (xXevieQueryVersionReq); + swaps (&stuff->client_major_version, n); + swaps (&stuff->client_minor_version, n); return ProcQueryVersion(client); } @@ -332,8 +339,8 @@ int SProcStart (ClientPtr client) REQUEST (xXevieStartReq); swaps (&stuff->length, n); + REQUEST_SIZE_MATCH (xXevieStartReq); swapl (&stuff->screen, n); - REQUEST_AT_LEAST_SIZE (xXevieStartReq); return ProcStart (client); } @@ -344,8 +351,8 @@ int SProcEnd (ClientPtr client) REQUEST (xXevieEndReq); swaps (&stuff->length, n); - REQUEST_AT_LEAST_SIZE (xXevieEndReq); - swapl(&stuff->cmap, n); + REQUEST_SIZE_MATCH (xXevieEndReq); + swapl (&stuff->cmap, n); return ProcEnd (client); } @@ -353,11 +360,21 @@ static int SProcSend (ClientPtr client) { register int n; + xEvent eventT; + EventSwapPtr proc; REQUEST (xXevieSendReq); swaps (&stuff->length, n); - REQUEST_AT_LEAST_SIZE (xXevieSendReq); - swapl(&stuff->event, n); + REQUEST_SIZE_MATCH (xXevieSendReq); + swapl (&stuff->dataType, n); + + /* Swap event */ + proc = EventSwapVector[stuff->event.u.u.type & 0177]; + if (!proc || proc == NotImplemented) /* no swapping proc; invalid event type? */ + return (BadValue); + (*proc)(&stuff->event, &eventT); + stuff->event = eventT; + return ProcSend (client); } @@ -368,8 +385,8 @@ int SProcSelectInput (ClientPtr client) REQUEST (xXevieSelectInputReq); swaps (&stuff->length, n); - REQUEST_AT_LEAST_SIZE (xXevieSelectInputReq); - swapl(&stuff->event_mask, n); + REQUEST_SIZE_MATCH (xXevieSelectInputReq); + swapl (&stuff->event_mask, n); return ProcSelectInput (client); } From 060a99444ee25a684b0ab9b4819bf8e855aea2d8 Mon Sep 17 00:00:00 2001 From: Alan Coopersmith Date: Wed, 19 Mar 2008 16:04:16 -0700 Subject: [PATCH 082/149] Make Xevie private symbol names less generic Makes it easier to figure out what you're seeing in the stack trace instead of wondering where in the server "ProcSend" is. --- Xext/xevie.c | 83 +++++++++++++++++++++++++--------------------------- 1 file changed, 40 insertions(+), 43 deletions(-) diff --git a/Xext/xevie.c b/Xext/xevie.c index f36ead478..5e20bd91c 100644 --- a/Xext/xevie.c +++ b/Xext/xevie.c @@ -63,11 +63,13 @@ extern Bool noXkbExtension; #endif extern int xeviegrabState; -static int ProcDispatch (register ClientPtr client), SProcDispatch (register ClientPtr client); -static void ResetProc (ExtensionEntry *extEntry); +static DISPATCH_PROC(ProcXevieDispatch); +static DISPATCH_PROC(SProcXevieDispatch); -static unsigned char ReqCode = 0; -static int ErrorBase; +static void XevieResetProc (ExtensionEntry *extEntry); + +static unsigned char XevieReqCode = 0; +static int XevieErrorBase; int xevieFlag = 0; int xevieClientIndex = 0; @@ -77,7 +79,7 @@ Mask xevieMask = 0; int xevieEventSent = 0; int xevieKBEventSent = 0; static DevPrivateKey xevieDevicePrivateKey = &xevieDevicePrivateKey; -static Bool xevieModifiersOn = FALSE; +static Bool xevieModifiersOn = FALSE; #define XEVIEINFO(dev) ((xevieDeviceInfoPtr) \ dixLookupPrivate(&(dev)->devPrivates, xevieDevicePrivateKey)) @@ -108,11 +110,6 @@ typedef struct { static xevieKeycQueueRec keycq[KEYC_QUEUE_SIZE] = {{0, NULL}}; static int keycqHead = 0, keycqTail = 0; -static int ProcDispatch (ClientPtr), SProcDispatch (ClientPtr); -static void ResetProc (ExtensionEntry*); - -static int ErrorBase; - static Bool XevieStart(void); static void XevieEnd(int clientIndex); static void XevieClientStateCallback(CallbackListPtr *pcbl, pointer nulldata, @@ -140,23 +137,23 @@ XevieExtensionInit (void) if ((extEntry = AddExtension (XEVIENAME, 0, XevieNumberErrors, - ProcDispatch, - SProcDispatch, - ResetProc, + ProcXevieDispatch, + SProcXevieDispatch, + XevieResetProc, StandardMinorOpcode))) { - ReqCode = (unsigned char)extEntry->base; - ErrorBase = extEntry->errorBase; + XevieReqCode = (unsigned char)extEntry->base; + XevieErrorBase = extEntry->errorBase; } } /*ARGSUSED*/ static -void ResetProc (ExtensionEntry *extEntry) +void XevieResetProc (ExtensionEntry *extEntry) { } static -int ProcQueryVersion (register ClientPtr client) +int ProcXevieQueryVersion (register ClientPtr client) { xXevieQueryVersionReply rep; @@ -171,7 +168,7 @@ int ProcQueryVersion (register ClientPtr client) } static -int ProcStart (register ClientPtr client) +int ProcXevieStart (register ClientPtr client) { xXevieStartReply rep; @@ -212,7 +209,7 @@ int ProcStart (register ClientPtr client) } static -int ProcEnd (register ClientPtr client) +int ProcXevieEnd (register ClientPtr client) { xXevieEndReply rep; @@ -233,7 +230,7 @@ int ProcEnd (register ClientPtr client) } static -int ProcSend (register ClientPtr client) +int ProcXevieSend (register ClientPtr client) { REQUEST (xXevieSendReq); xXevieSendReply rep; @@ -281,7 +278,7 @@ int ProcSend (register ClientPtr client) } static -int ProcSelectInput (register ClientPtr client) +int ProcXevieSelectInput (register ClientPtr client) { REQUEST (xXevieSelectInputReq); xXevieSelectInputReply rep; @@ -299,28 +296,28 @@ int ProcSelectInput (register ClientPtr client) } static -int ProcDispatch (register ClientPtr client) +int ProcXevieDispatch (register ClientPtr client) { REQUEST (xReq); switch (stuff->data) { case X_XevieQueryVersion: - return ProcQueryVersion (client); + return ProcXevieQueryVersion (client); case X_XevieStart: - return ProcStart (client); + return ProcXevieStart (client); case X_XevieEnd: - return ProcEnd (client); + return ProcXevieEnd (client); case X_XevieSend: - return ProcSend (client); + return ProcXevieSend (client); case X_XevieSelectInput: - return ProcSelectInput(client); + return ProcXevieSelectInput(client); default: return BadRequest; } } static -int SProcQueryVersion (register ClientPtr client) +int SProcXevieQueryVersion (register ClientPtr client) { register int n; @@ -329,11 +326,11 @@ int SProcQueryVersion (register ClientPtr client) REQUEST_SIZE_MATCH (xXevieQueryVersionReq); swaps (&stuff->client_major_version, n); swaps (&stuff->client_minor_version, n); - return ProcQueryVersion(client); + return ProcXevieQueryVersion(client); } static -int SProcStart (ClientPtr client) +int SProcXevieStart (ClientPtr client) { register int n; @@ -341,11 +338,11 @@ int SProcStart (ClientPtr client) swaps (&stuff->length, n); REQUEST_SIZE_MATCH (xXevieStartReq); swapl (&stuff->screen, n); - return ProcStart (client); + return ProcXevieStart (client); } static -int SProcEnd (ClientPtr client) +int SProcXevieEnd (ClientPtr client) { register int n; @@ -353,11 +350,11 @@ int SProcEnd (ClientPtr client) swaps (&stuff->length, n); REQUEST_SIZE_MATCH (xXevieEndReq); swapl (&stuff->cmap, n); - return ProcEnd (client); + return ProcXevieEnd (client); } static -int SProcSend (ClientPtr client) +int SProcXevieSend (ClientPtr client) { register int n; xEvent eventT; @@ -375,11 +372,11 @@ int SProcSend (ClientPtr client) (*proc)(&stuff->event, &eventT); stuff->event = eventT; - return ProcSend (client); + return ProcXevieSend (client); } static -int SProcSelectInput (ClientPtr client) +int SProcXevieSelectInput (ClientPtr client) { register int n; @@ -387,26 +384,26 @@ int SProcSelectInput (ClientPtr client) swaps (&stuff->length, n); REQUEST_SIZE_MATCH (xXevieSelectInputReq); swapl (&stuff->event_mask, n); - return ProcSelectInput (client); + return ProcXevieSelectInput (client); } static -int SProcDispatch (register ClientPtr client) +int SProcXevieDispatch (register ClientPtr client) { REQUEST(xReq); switch (stuff->data) { case X_XevieQueryVersion: - return SProcQueryVersion (client); + return SProcXevieQueryVersion (client); case X_XevieStart: - return SProcStart (client); + return SProcXevieStart (client); case X_XevieEnd: - return SProcEnd (client); + return SProcXevieEnd (client); case X_XevieSend: - return SProcSend (client); + return SProcXevieSend (client); case X_XevieSelectInput: - return SProcSelectInput(client); + return SProcXevieSelectInput(client); default: return BadRequest; } From 267352579612155adfd4743432d6569b2cdeebde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Wed, 19 Mar 2008 19:12:37 -0400 Subject: [PATCH 083/149] Fix RandR 1.2 driver interface conversion of two colour cursors to ARGB See bug 11796 --- hw/xfree86/modes/xf86Cursors.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hw/xfree86/modes/xf86Cursors.c b/hw/xfree86/modes/xf86Cursors.c index 08cf78d82..4fe94f3c6 100644 --- a/hw/xfree86/modes/xf86Cursors.c +++ b/hw/xfree86/modes/xf86Cursors.c @@ -137,7 +137,9 @@ cursor_bitpos (int flags, int x, Bool mask) mask = !mask; if (flags & HARDWARE_CURSOR_NIBBLE_SWAPPED) x = (x & ~3) | (3 - (x & 3)); +#if X_BYTE_ORDER == X_LITTLE_ENDIAN if (flags & HARDWARE_CURSOR_BIT_ORDER_MSBFIRST) +#endif x = (x & ~7) | (7 - (x & 7)); if (flags & HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1) x = (x << 1) + mask; From f8c1eb29e28818895d744c4e1d6897353d51790b Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 20 Mar 2008 09:14:41 -0400 Subject: [PATCH 084/149] Revert "Fix RandR 1.2 driver interface conversion of two colour cursors to ARGB" This reverts commit 267352579612155adfd4743432d6569b2cdeebde. Pushed the wrong patch. --- hw/xfree86/modes/xf86Cursors.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/hw/xfree86/modes/xf86Cursors.c b/hw/xfree86/modes/xf86Cursors.c index 4fe94f3c6..08cf78d82 100644 --- a/hw/xfree86/modes/xf86Cursors.c +++ b/hw/xfree86/modes/xf86Cursors.c @@ -137,9 +137,7 @@ cursor_bitpos (int flags, int x, Bool mask) mask = !mask; if (flags & HARDWARE_CURSOR_NIBBLE_SWAPPED) x = (x & ~3) | (3 - (x & 3)); -#if X_BYTE_ORDER == X_LITTLE_ENDIAN if (flags & HARDWARE_CURSOR_BIT_ORDER_MSBFIRST) -#endif x = (x & ~7) | (7 - (x & 7)); if (flags & HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1) x = (x << 1) + mask; From da973e962d09854b571320dee7dd9569060bc39e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michel=20D=C3=A4nzer?= Date: Thu, 20 Mar 2008 09:18:29 -0400 Subject: [PATCH 085/149] Fix RandR 1.2 driver interface conversion of two colour cursors to ARGB This patch (and not setting HARDWARE_CURSOR_BIT_ORDER_MSBFIRST on big endian platforms) fixes it for me with the radeon driver and doesn't break intel. Correct patch this time :) --- hw/xfree86/modes/xf86Cursors.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hw/xfree86/modes/xf86Cursors.c b/hw/xfree86/modes/xf86Cursors.c index 08cf78d82..57cfcb65a 100644 --- a/hw/xfree86/modes/xf86Cursors.c +++ b/hw/xfree86/modes/xf86Cursors.c @@ -137,7 +137,8 @@ cursor_bitpos (int flags, int x, Bool mask) mask = !mask; if (flags & HARDWARE_CURSOR_NIBBLE_SWAPPED) x = (x & ~3) | (3 - (x & 3)); - if (flags & HARDWARE_CURSOR_BIT_ORDER_MSBFIRST) + if (((flags & HARDWARE_CURSOR_BIT_ORDER_MSBFIRST) == 0) == + (X_BYTE_ORDER == X_BIG_ENDIAN)) x = (x & ~7) | (7 - (x & 7)); if (flags & HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1) x = (x << 1) + mask; From e323bb426ce8a072d119cb2720b773241259c137 Mon Sep 17 00:00:00 2001 From: Eamon Walsh Date: Thu, 20 Mar 2008 19:42:09 -0400 Subject: [PATCH 086/149] XSELinux: Correctly handle some permission bits that are used more than once. --- Xext/xselinux.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/Xext/xselinux.c b/Xext/xselinux.c index 18c652645..303589860 100644 --- a/Xext/xselinux.c +++ b/Xext/xselinux.c @@ -152,6 +152,12 @@ static struct security_class_mapping map[] = { { NULL } }; +/* x_resource "read" bits from the list above */ +#define SELinuxReadMask (DixReadAccess|DixGetAttrAccess|DixListPropAccess| \ + DixGetPropAccess|DixGetFocusAccess|DixListAccess| \ + DixShowAccess|DixBlendAccess|DixReceiveAccess| \ + DixUseAccess|DixDebugAccess) + /* forward declarations */ static void SELinuxScreen(CallbackListPtr *, pointer, pointer); @@ -853,6 +859,7 @@ SELinuxSelection(CallbackListPtr *pcbl, pointer unused, pointer calldata) SELinuxObjectRec *obj, *data; Selection *pSel = *rec->ppSel; Atom name = pSel->selection; + Mask access_mode = rec->access_mode; SELinuxAuditRec auditdata = { .client = rec->client, .selection = name }; security_id_t tsid; int rc; @@ -861,11 +868,12 @@ SELinuxSelection(CallbackListPtr *pcbl, pointer unused, pointer calldata) obj = dixLookupPrivate(&pSel->devPrivates, objectKey); /* If this is a new object that needs labeling, do it now */ - if (rec->access_mode & DixCreateAccess) { + if (access_mode & DixCreateAccess) { sidput(obj->sid); rc = SELinuxSelectionToSID(name, subj, &obj->sid, &obj->poly); if (rc != Success) obj->sid = unlabeled_sid; + access_mode = DixSetAttrAccess; } /* If this is a polyinstantiated object, find the right instance */ else if (obj->poly) { @@ -890,13 +898,13 @@ SELinuxSelection(CallbackListPtr *pcbl, pointer unused, pointer calldata) } /* Perform the security check */ - rc = SELinuxDoCheck(subj, obj, SECCLASS_X_SELECTION, rec->access_mode, + rc = SELinuxDoCheck(subj, obj, SECCLASS_X_SELECTION, access_mode, &auditdata); if (rc != Success) rec->status = rc; /* Label the content (advisory only) */ - if (rec->access_mode & DixSetAttrAccess) { + if (access_mode & DixSetAttrAccess) { data = dixLookupPrivate(&pSel->devPrivates, dataKey); sidput(data->sid); if (subj->sel_create_sid) @@ -976,6 +984,7 @@ SELinuxResource(CallbackListPtr *pcbl, pointer unused, pointer calldata) SELinuxSubjectRec *subj; SELinuxObjectRec *obj; SELinuxAuditRec auditdata = { .client = rec->client }; + Mask access_mode = rec->access_mode; PrivateRec **privatePtr; security_class_t class; int rc, offset; @@ -997,7 +1006,7 @@ SELinuxResource(CallbackListPtr *pcbl, pointer unused, pointer calldata) } /* If this is a new object that needs labeling, do it now */ - if (rec->access_mode & DixCreateAccess && offset >= 0) { + if (access_mode & DixCreateAccess && offset >= 0) { rc = SELinuxLabelResource(rec, subj, obj, class); if (rc != Success) { rec->status = rc; @@ -1005,10 +1014,16 @@ SELinuxResource(CallbackListPtr *pcbl, pointer unused, pointer calldata) } } + /* Collapse generic resource permissions down to read/write */ + if (class == SECCLASS_X_RESOURCE) { + access_mode = !!(rec->access_mode & SELinuxReadMask); /* rd */ + access_mode |= !!(rec->access_mode & ~SELinuxReadMask) << 1; /* wr */ + } + /* Perform the security check */ auditdata.restype = rec->rtype; auditdata.id = rec->id; - rc = SELinuxDoCheck(subj, obj, class, rec->access_mode, &auditdata); + rc = SELinuxDoCheck(subj, obj, class, access_mode, &auditdata); if (rc != Success) rec->status = rc; } From 3bbd77ff98478153afe3251de9ba11d757218213 Mon Sep 17 00:00:00 2001 From: Eamon Walsh Date: Thu, 20 Mar 2008 20:03:02 -0400 Subject: [PATCH 087/149] XSELinux: Do a check for whether background "None" is allowed. --- Xext/xselinux.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Xext/xselinux.c b/Xext/xselinux.c index 303589860..17ce7af10 100644 --- a/Xext/xselinux.c +++ b/Xext/xselinux.c @@ -1026,6 +1026,13 @@ SELinuxResource(CallbackListPtr *pcbl, pointer unused, pointer calldata) rc = SELinuxDoCheck(subj, obj, class, access_mode, &auditdata); if (rc != Success) rec->status = rc; + + /* Perform the background none check on windows */ + if (access_mode & DixCreateAccess && rec->rtype == RT_WINDOW) { + rc = SELinuxDoCheck(subj, obj, class, DixBlendAccess, &auditdata); + if (rc != Success) + ((WindowPtr)rec->res)->forcedBG = TRUE; + } } static void From 87c64cfd6901083da5a9375d0bde65691d374b5b Mon Sep 17 00:00:00 2001 From: Jeremy Huddleston Date: Fri, 14 Mar 2008 17:31:54 -0700 Subject: [PATCH 088/149] =?UTF-8?q?=3D=3Futf-8=3Fq=3FApple:=3D20Xserver=3D?= =?UTF-8?q?20half=3D20of=3D20the=3D20Expos=3DC3=3DA9=3D20bug-fix=3D20(requ?= =?UTF-8?q?ires=3D20updated=3D20libXplugin=3D20from=3D20Apple...=3D20comin?= =?UTF-8?q?g=3D20with=3D202.2)?= =20(cherry=20picked=20from=20commit=2037be23e8c1d8e5c7a1157e9d66ef3f30a4c472c5)?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit --- hw/xquartz/X11Application.m | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hw/xquartz/X11Application.m b/hw/xquartz/X11Application.m index be5511d30..1cf992d92 100644 --- a/hw/xquartz/X11Application.m +++ b/hw/xquartz/X11Application.m @@ -320,6 +320,8 @@ static void message_kit_thread (SEL selector, NSObject *arg) { SetFrontProcess(&psn); QuartzMessageServerThread(kXDarwinBringAllToFront, 0); + ProcessSerialNumber psn = { 0, kCurrentProcess }; + SetFrontProcess(&psn); } - (void) set_can_quit:(NSNumber *)state { From 4c76607b699431183ee7e88fa7818cb7644a5a02 Mon Sep 17 00:00:00 2001 From: Jeremy Huddleston Date: Mon, 17 Mar 2008 23:57:41 -0700 Subject: [PATCH 089/149] Rootless: Removed safeAlphaXXXX() in favor of using fb/pixman (cherry picked from commit f03202ad15457c98be7ca78cc59bac88cf5f1966) --- configure.ac | 1 - hw/xquartz/xpr/Makefile.am | 4 +- hw/xquartz/xpr/xprScreen.c | 10 - miext/rootless/Makefile.am | 2 +- miext/rootless/safeAlpha/Makefile.am | 7 - miext/rootless/safeAlpha/safeAlpha.h | 42 ---- miext/rootless/safeAlpha/safeAlphaPicture.c | 211 -------------------- 7 files changed, 2 insertions(+), 275 deletions(-) delete mode 100644 miext/rootless/safeAlpha/Makefile.am delete mode 100644 miext/rootless/safeAlpha/safeAlpha.h delete mode 100644 miext/rootless/safeAlpha/safeAlphaPicture.c diff --git a/configure.ac b/configure.ac index 49f2395fa..3b007051c 100644 --- a/configure.ac +++ b/configure.ac @@ -2120,7 +2120,6 @@ miext/damage/Makefile miext/shadow/Makefile miext/cw/Makefile miext/rootless/Makefile -miext/rootless/safeAlpha/Makefile miext/rootless/accel/Makefile os/Makefile randr/Makefile diff --git a/hw/xquartz/xpr/Makefile.am b/hw/xquartz/xpr/Makefile.am index ae1b19297..b4d67c7b7 100644 --- a/hw/xquartz/xpr/Makefile.am +++ b/hw/xquartz/xpr/Makefile.am @@ -4,8 +4,7 @@ AM_CFLAGS = $(XSERVER_CFLAGS) $(DIX_CFLAGS) AM_CPPFLAGS = \ -I$(srcdir) -I$(srcdir)/.. \ -I$(top_srcdir)/miext \ - -I$(top_srcdir)/miext/rootless \ - -I$(top_srcdir)/miext/rootless/safeAlpha + -I$(top_srcdir)/miext/rootless Xquartz_SOURCES = \ appledri.c \ @@ -41,7 +40,6 @@ Xquartz_LDADD = \ $(top_builddir)/record/librecord.la \ $(top_builddir)/XTrap/libxtrap.la \ $(top_builddir)/miext/rootless/librootless.la \ - $(top_builddir)/miext/rootless/safeAlpha/libsafeAlpha.la \ $(top_builddir)/miext/rootless/accel/librlAccel.la \ $(DARWIN_LIBS) $(XSERVER_LIBS) $(XSERVER_SYS_LIBS) -lXplugin diff --git a/hw/xquartz/xpr/xprScreen.c b/hw/xquartz/xpr/xprScreen.c index e4e1fda7e..db36403df 100644 --- a/hw/xquartz/xpr/xprScreen.c +++ b/hw/xquartz/xpr/xprScreen.c @@ -37,7 +37,6 @@ #include "pseudoramiX.h" #include "darwin.h" #include "rootless.h" -#include "safeAlpha/safeAlpha.h" #include "dri.h" #include "globals.h" #include "Xplugin.h" @@ -341,15 +340,6 @@ xprAddScreen(int index, ScreenPtr pScreen) static Bool xprSetupScreen(int index, ScreenPtr pScreen) { - // Add alpha protecting replacements for fb screen functions - -#ifdef RENDER - { - PictureScreenPtr ps = GetPictureScreen(pScreen); - ps->Composite = SafeAlphaComposite; - } -#endif /* RENDER */ - // Initialize accelerated rootless drawing // Note that this must be done before DamageSetup(). RootlessAccelInit(pScreen); diff --git a/miext/rootless/Makefile.am b/miext/rootless/Makefile.am index aa8528e6a..dc851702f 100644 --- a/miext/rootless/Makefile.am +++ b/miext/rootless/Makefile.am @@ -1,7 +1,7 @@ AM_CFLAGS = $(DIX_CFLAGS) $(XSERVER_CFLAGS) AM_CPPFLAGS = -I$(top_srcdir)/hw/xfree86/os-support -SUBDIRS = safeAlpha accel +SUBDIRS = accel noinst_LTLIBRARIES = librootless.la librootless_la_SOURCES = \ diff --git a/miext/rootless/safeAlpha/Makefile.am b/miext/rootless/safeAlpha/Makefile.am deleted file mode 100644 index a22afb6a2..000000000 --- a/miext/rootless/safeAlpha/Makefile.am +++ /dev/null @@ -1,7 +0,0 @@ -AM_CFLAGS = $(DIX_CFLAGS) $(XSERVER_CFLAGS) -AM_CPPFLAGS = -I$(srcdir)/.. -I$(top_srcdir)/hw/xfree86/os-support - -noinst_LTLIBRARIES = libsafeAlpha.la -libsafeAlpha_la_SOURCES = safeAlphaPicture.c - -EXTRA_DIST = safeAlpha.h diff --git a/miext/rootless/safeAlpha/safeAlpha.h b/miext/rootless/safeAlpha/safeAlpha.h deleted file mode 100644 index 9b9b39c92..000000000 --- a/miext/rootless/safeAlpha/safeAlpha.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Replacement functions to protect the alpha channel - */ -/* - * Copyright (c) 2002-2003 Torrey T. Lyons. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Except as contained in this notice, the name(s) of the above copyright - * holders shall not be used in advertising or otherwise to promote the sale, - * use or other dealings in this Software without prior written authorization. - */ - -#ifndef _SAFEALPHA_H -#define _SAFEALPHA_H - -#include "picturestr.h" - -#ifdef RENDER -void -SafeAlphaComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst, - INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask, - INT16 xDst, INT16 yDst, CARD16 width, CARD16 height); -#endif /* RENDER */ - -#endif /* _SAFEALPHA_H */ diff --git a/miext/rootless/safeAlpha/safeAlphaPicture.c b/miext/rootless/safeAlpha/safeAlphaPicture.c deleted file mode 100644 index 8f6631531..000000000 --- a/miext/rootless/safeAlpha/safeAlphaPicture.c +++ /dev/null @@ -1,211 +0,0 @@ -/* - * Support for RENDER extension while protecting the alpha channel - */ -/* - * Copyright (c) 2002-2003 Torrey T. Lyons. All Rights Reserved. - * Copyright (c) 2002 Apple Computer, Inc. All Rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Except as contained in this notice, the name(s) of the above copyright - * holders shall not be used in advertising or otherwise to promote the sale, - * use or other dealings in this Software without prior written authorization. - */ -/* This file is largely based on fbcompose.c and fbpict.c, which contain - * the following copyright: - * - * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc. - */ - - -#ifdef HAVE_DIX_CONFIG_H -#include -#endif -#ifdef RENDER - -#include /* For NULL */ -#include "fb.h" -#include "picturestr.h" -#include "mipict.h" -#include "fbpict.h" -#include "safeAlpha.h" -#include "rootlessCommon.h" -# define mod(a,b) ((b) == 1 ? 0 : (a) >= 0 ? (a) % (b) : (b) - (-a) % (b)) - -/* Optimized version of fbCompositeSolidMask_nx8x8888 */ -void -SafeAlphaCompositeSolidMask_nx8x8888( - CARD8 op, - PicturePtr pSrc, - PicturePtr pMask, - PicturePtr pDst, - INT16 xSrc, - INT16 ySrc, - INT16 xMask, - INT16 yMask, - INT16 xDst, - INT16 yDst, - CARD16 width, - CARD16 height) -{ - CARD32 src, srca; - CARD32 *dstLine, *dst, d, dstMask; - CARD8 *maskLine, *mask, m; - FbStride dstStride, maskStride; - CARD16 w; - - fbComposeGetSolid(pSrc, src, pDst->format); - - dstMask = FbFullMask (pDst->pDrawable->depth); - srca = src >> 24; - if (src == 0) - return; - - fbComposeGetStart (pDst, xDst, yDst, CARD32, dstStride, dstLine, 1); - fbComposeGetStart (pMask, xMask, yMask, CARD8, maskStride, maskLine, 1); - - if (dstMask == FB_ALLONES && pDst->pDrawable->bitsPerPixel == 32 && - width * height > rootless_CompositePixels_threshold && - SCREENREC(pDst->pDrawable->pScreen)->imp->CompositePixels) - { - void *srcp[2], *destp[2]; - unsigned int dest_rowbytes[2]; - unsigned int fn; - - srcp[0] = &src; srcp[1] = &src; - /* null rowbytes pointer means use first value as a constant */ - destp[0] = dstLine; destp[1] = dstLine; - dest_rowbytes[0] = dstStride * 4; dest_rowbytes[1] = dest_rowbytes[0]; - fn = RL_COMPOSITE_FUNCTION(RL_COMPOSITE_OVER, RL_DEPTH_ARGB8888, - RL_DEPTH_A8, RL_DEPTH_ARGB8888); - - if (SCREENREC(pDst->pDrawable->pScreen)->imp->CompositePixels( - width, height, fn, srcp, NULL, - maskLine, maskStride, - destp, dest_rowbytes) == Success) - { - return; - } - } - - while (height--) - { - dst = dstLine; - dstLine += dstStride; - mask = maskLine; - maskLine += maskStride; - w = width; - - while (w--) - { - m = *mask++; - if (m == 0xff) - { - if (srca == 0xff) - *dst = src & dstMask; - else - *dst = fbOver (src, *dst) & dstMask; - } - else if (m) - { - d = fbIn (src, m); - *dst = fbOver (d, *dst) & dstMask; - } - dst++; - } - } -} - -void -SafeAlphaComposite (CARD8 op, - PicturePtr pSrc, - PicturePtr pMask, - PicturePtr pDst, - INT16 xSrc, - INT16 ySrc, - INT16 xMask, - INT16 yMask, - INT16 xDst, - INT16 yDst, - CARD16 width, - CARD16 height) -{ - if (!pSrc) { - ErrorF("SafeAlphaComposite: pSrc must not be null!\n"); - return; - } - - if (!pDst) { - ErrorF("SafeAlphaComposite: pDst must not be null!\n"); - return; - } - - int oldDepth = pDst->pDrawable->depth; - int oldFormat = pDst->format; - - /* - * We can use the more optimized fbpict code, but it sets bits above - * the depth to zero. Temporarily adjust destination depth if needed. - */ - if (pDst->pDrawable->type == DRAWABLE_WINDOW - && pDst->pDrawable->depth == 24 - && pDst->pDrawable->bitsPerPixel == 32) - { - pDst->pDrawable->depth = 32; - } - - /* For rootless preserve the alpha in x8r8g8b8 which really is - * a8r8g8b8 - */ - if (oldFormat == PICT_x8r8g8b8) - { - pDst->format = PICT_a8r8g8b8; - } - - if (pSrc->pDrawable && pMask && pMask->pDrawable && - !pSrc->transform && !pMask->transform && - !pSrc->alphaMap && !pMask->alphaMap && - !pMask->repeat && !pMask->componentAlpha && !pDst->alphaMap && - pMask->format == PICT_a8 && - pSrc->repeatType == RepeatNormal && - pSrc->pDrawable->width == 1 && - pSrc->pDrawable->height == 1 && - (pDst->format == PICT_a8r8g8b8 || - pDst->format == PICT_x8r8g8b8 || - pDst->format == PICT_a8b8g8r8 || - pDst->format == PICT_x8b8g8r8)) - { - fbWalkCompositeRegion (op, pSrc, pMask, pDst, - xSrc, ySrc, xMask, yMask, xDst, yDst, - width, height, - TRUE /* srcRepeat */, - FALSE /* maskRepeat */, - SafeAlphaCompositeSolidMask_nx8x8888); - } - else - { - fbComposite (op, pSrc, pMask, pDst, - xSrc, ySrc, xMask, yMask, xDst, yDst, width, height); - } - - pDst->pDrawable->depth = oldDepth; - pDst->format = oldFormat; -} - -#endif /* RENDER */ From c49e11268322712c211f29d51d664d3f8a59b00b Mon Sep 17 00:00:00 2001 From: Jeremy Huddleston Date: Fri, 21 Mar 2008 18:07:38 -0700 Subject: [PATCH 090/149] XQuartz: Initial framework for dealing with spaces on OS-X (cherry picked from commit 9831324998f9d1f05ff944c58c5bf60dcae17355) --- hw/xquartz/darwin.h | 3 ++- hw/xquartz/quartz.c | 14 +++++++++++++- hw/xquartz/xpr/xprScreen.c | 11 ++++++++++- 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/hw/xquartz/darwin.h b/hw/xquartz/darwin.h index c5e2ed80d..325122dfd 100644 --- a/hw/xquartz/darwin.h +++ b/hw/xquartz/darwin.h @@ -106,6 +106,7 @@ enum { kXDarwinBringAllToFront, // bring all X windows to front kXDarwinToggleFullscreen, // Enable/Disable fullscreen mode kXDarwinSetRootless, // Set rootless mode + kXDarwinSpaceChanged, // Spaces changed /* * AppleWM events */ @@ -116,7 +117,7 @@ enum { */ kXDarwinDisplayChanged, // display configuration has changed kXDarwinWindowState, // window visibility state has changed - kXDarwinWindowMoved // window has moved on screen + kXDarwinWindowMoved, // window has moved on screen }; #define ENABLE_DEBUG_LOG 1 diff --git a/hw/xquartz/quartz.c b/hw/xquartz/quartz.c index 6f42c538f..a034c9fac 100644 --- a/hw/xquartz/quartz.c +++ b/hw/xquartz/quartz.c @@ -266,7 +266,7 @@ static void QuartzUpdateScreens(void) #ifndef FAKE_RANDR if(!QuartzRandRInit(pScreen)) - FatalError("Failed to init RandR extension.\n"); + FatalError("Failed to init RandR extension.\n"); #endif DarwinAdjustScreenOrigins(&screenInfo); @@ -364,6 +364,14 @@ static void QuartzSetRootClip( } } +/* + * QuartzSpaceChanged + * Unmap offscreen windows, map onscreen windows + */ +static void QuartzSpaceChanged(uint32_t space_id) { + /* Do something special here, so we don't depend on quartz-wm for spaces to work... */ + DEBUG_LOG("Space Changed (%u) ... do something interesting...\n", space_id); +} /* * QuartzMessageServerThread @@ -494,6 +502,10 @@ void QuartzProcessEvent(xEvent *xe) { RootlessOrderAllWindows(); break; + case kXDarwinSpaceChanged: + DEBUG_LOG("kXDarwinSpaceChanged\n"); + QuartzSpaceChanged(xe->u.clientMessage.u.l.longs0); + break; default: ErrorF("Unknown application defined event type %d.\n", xe->u.u.type); } diff --git a/hw/xquartz/xpr/xprScreen.c b/hw/xquartz/xpr/xprScreen.c index db36403df..4dc5846d5 100644 --- a/hw/xquartz/xpr/xprScreen.c +++ b/hw/xquartz/xpr/xprScreen.c @@ -63,6 +63,7 @@ static const char *xprOpenGLBundle = "glxCGL.bundle"; */ static void eventHandler(unsigned int type, const void *arg, unsigned int arg_size, void *data) { + switch (type) { case XP_EVENT_DISPLAY_CHANGED: DEBUG_LOG("XP_EVENT_DISPLAY_CHANGED\n"); @@ -105,6 +106,13 @@ static void eventHandler(unsigned int type, const void *arg, DRISurfaceNotify(*(xp_surface_id *) arg, kind); } break; + case XP_EVENT_SPACE_CHANGED: + ErrorF("XP_EVENT_SPACE_CHANGED\n"); + if(arg_size == sizeof(uint32_t)) { + uint32_t space_id = *(uint32_t *)arg; + QuartzMessageServerThread(kXDarwinSpaceChanged, 1, space_id); + } + break; default: ErrorF("Unknown XP_EVENT type (%d) in xprScreen:eventHandler\n", type); } @@ -233,7 +241,8 @@ xprDisplayInit(void) | XP_EVENT_WINDOW_STATE_CHANGED | XP_EVENT_WINDOW_MOVED | XP_EVENT_SURFACE_CHANGED - | XP_EVENT_SURFACE_DESTROYED, + | XP_EVENT_SURFACE_DESTROYED + | XP_EVENT_SPACE_CHANGED, eventHandler, NULL); AppleDRIExtensionInit(); From 93daa3a3bf1a981757024847882ce92b6bdaae83 Mon Sep 17 00:00:00 2001 From: Jeremy Huddleston Date: Fri, 21 Mar 2008 19:11:59 -0700 Subject: [PATCH 091/149] Xquartz: Added separate preference tab for quartz-wm settings Added FFM and "Focus on new window" options (cherry picked from commit 6841d078b7cb0b0db3db948d26b4d5ec7747deb8) --- hw/xquartz/X11Application.h | 4 +- hw/xquartz/X11Controller.h | 2 + hw/xquartz/X11Controller.m | 40 +- .../English.lproj/main.nib/designable.nib | 508 +++++++++++++----- .../English.lproj/main.nib/keyedobjects.nib | Bin 35571 -> 37953 bytes hw/xquartz/quartzCommon.h | 14 +- hw/xquartz/quartzForeground.c | 2 +- 7 files changed, 410 insertions(+), 160 deletions(-) diff --git a/hw/xquartz/X11Application.h b/hw/xquartz/X11Application.h index 86da67f2e..ea9a6b758 100644 --- a/hw/xquartz/X11Application.h +++ b/hw/xquartz/X11Application.h @@ -98,6 +98,8 @@ extern int quartzHasRoot, quartzEnableRootless; #define PREFS_XP_OPTIONS "xp_options" #define PREFS_ENABLE_STEREO "enable_stereo" #define PREFS_LOGIN_SHELL "login_shell" -#define PREFS_QUARTZ_WM_CLICK_THROUGH "wm_click_through" +#define PREFS_CLICK_THROUGH "wm_click_through" +#define PREFS_FFM "wm_ffm" +#define PREFS_FOCUS_ON_NEW_WINDOW "wm_focus_on_new_window" #endif /* X11APPLICATION_H */ diff --git a/hw/xquartz/X11Controller.h b/hw/xquartz/X11Controller.h index 64d5cd1ce..8d6a38ff0 100644 --- a/hw/xquartz/X11Controller.h +++ b/hw/xquartz/X11Controller.h @@ -45,6 +45,8 @@ IBOutlet NSButton *enable_keyequivs; IBOutlet NSButton *sync_keymap; IBOutlet NSButton *click_through; + IBOutlet NSButton *focus_follows_mouse; + IBOutlet NSButton *focus_on_new_window; IBOutlet NSButton *enable_auth; IBOutlet NSButton *enable_tcp; IBOutlet NSPopUpButton *depth; diff --git a/hw/xquartz/X11Controller.m b/hw/xquartz/X11Controller.m index 5111eafc3..3880b3f38 100644 --- a/hw/xquartz/X11Controller.m +++ b/hw/xquartz/X11Controller.m @@ -609,24 +609,28 @@ objectValueForTableColumn:(NSTableColumn *)tableColumn row:(int)row - (IBAction)prefs_changed:sender { - darwinFakeButtons = [fake_buttons intValue]; - quartzUseSysBeep = [use_sysbeep intValue]; - X11EnableKeyEquivalents = [enable_keyequivs intValue]; - darwinSyncKeymap = [sync_keymap intValue]; - - /* after adding prefs here, also add to [X11Application read_defaults] + darwinFakeButtons = [fake_buttons intValue]; + quartzUseSysBeep = [use_sysbeep intValue]; + X11EnableKeyEquivalents = [enable_keyequivs intValue]; + darwinSyncKeymap = [sync_keymap intValue]; + + /* after adding prefs here, also add to [X11Application read_defaults] and below */ - [NSApp prefs_set_boolean:@PREFS_FAKEBUTTONS value:darwinFakeButtons]; - [NSApp prefs_set_boolean:@PREFS_SYSBEEP value:quartzUseSysBeep]; - [NSApp prefs_set_boolean:@PREFS_KEYEQUIVS value:X11EnableKeyEquivalents]; - [NSApp prefs_set_boolean:@PREFS_SYNC_KEYMAP value:darwinSyncKeymap]; - [NSApp prefs_set_boolean:@PREFS_QUARTZ_WM_CLICK_THROUGH value:[click_through intValue]]; - [NSApp prefs_set_boolean:@PREFS_NO_AUTH value:![enable_auth intValue]]; - [NSApp prefs_set_boolean:@PREFS_NO_TCP value:![enable_tcp intValue]]; - [NSApp prefs_set_integer:@PREFS_DEPTH value:[depth selectedTag]]; + [NSApp prefs_set_boolean:@PREFS_FAKEBUTTONS value:darwinFakeButtons]; + [NSApp prefs_set_boolean:@PREFS_SYSBEEP value:quartzUseSysBeep]; + [NSApp prefs_set_boolean:@PREFS_KEYEQUIVS value:X11EnableKeyEquivalents]; + [NSApp prefs_set_boolean:@PREFS_SYNC_KEYMAP value:darwinSyncKeymap]; + [NSApp prefs_set_boolean:@PREFS_CLICK_THROUGH value:[click_through intValue]]; + [NSApp prefs_set_boolean:@PREFS_FFM value:[focus_follows_mouse intValue]]; + [NSApp prefs_set_boolean:@PREFS_FOCUS_ON_NEW_WINDOW value:[focus_on_new_window intValue]]; + [NSApp prefs_set_boolean:@PREFS_NO_AUTH value:![enable_auth intValue]]; + [NSApp prefs_set_boolean:@PREFS_NO_TCP value:![enable_tcp intValue]]; + [NSApp prefs_set_integer:@PREFS_DEPTH value:[depth selectedTag]]; + + system("killall -HUP quartz-wm"); - [NSApp prefs_synchronize]; + [NSApp prefs_synchronize]; } - (IBAction) prefs_show:sender @@ -636,8 +640,10 @@ objectValueForTableColumn:(NSTableColumn *)tableColumn row:(int)row [enable_keyequivs setIntValue:X11EnableKeyEquivalents]; [sync_keymap setIntValue:darwinSyncKeymap]; [sync_keymap setEnabled:darwinKeymapFile == NULL]; - [click_through setIntValue:[NSApp prefs_get_boolean:@PREFS_QUARTZ_WM_CLICK_THROUGH default:NO]]; - + [click_through setIntValue:[NSApp prefs_get_boolean:@PREFS_CLICK_THROUGH default:NO]]; + [focus_follows_mouse setIntValue:[NSApp prefs_get_boolean:@PREFS_FFM default:NO]]; + [focus_on_new_window setIntValue:[NSApp prefs_get_boolean:@PREFS_FOCUS_ON_NEW_WINDOW default:YES]]; + [enable_auth setIntValue:![NSApp prefs_get_boolean:@PREFS_NO_AUTH default:NO]]; [enable_tcp setIntValue:![NSApp prefs_get_boolean:@PREFS_NO_TCP default:NO]]; [depth selectItemAtIndex:[depth indexOfItemWithTag:[NSApp prefs_get_integer:@PREFS_DEPTH default:-1]]]; diff --git a/hw/xquartz/bundle/English.lproj/main.nib/designable.nib b/hw/xquartz/bundle/English.lproj/main.nib/designable.nib index ea3a0daa8..adc0340ed 100644 --- a/hw/xquartz/bundle/English.lproj/main.nib/designable.nib +++ b/hw/xquartz/bundle/English.lproj/main.nib/designable.nib @@ -8,8 +8,6 @@ 352.00 YES - - YES @@ -448,7 +446,7 @@ 3 2 - {{319, 294}, {481, 345}} + {{266, 392}, {484, 280}} 1350041600 X11 Preferences NSPanel @@ -465,7 +463,7 @@ 256 - {{10, 10}, {458, 325}} + {{13, 10}, {458, 264}} YES @@ -474,14 +472,14 @@ 1 - + 256 YES 256 - {{18, 243}, {402, 18}} + {{18, 182}, {402, 18}} YES @@ -508,7 +506,7 @@ 256 - {{36, 93}, {385, 31}} + {{36, 32}, {385, 31}} YES @@ -544,7 +542,7 @@ 256 - {{36, 208}, {385, 29}} + {{36, 147}, {385, 29}} YES @@ -561,7 +559,7 @@ ZSBhbmQgcmlnaHQgbW91c2UgYnV0dG9ucy4KA 256 - {{18, 130}, {402, 18}} + {{18, 69}, {402, 18}} YES @@ -582,7 +580,7 @@ ZSBhbmQgcmlnaHQgbW91c2UgYnV0dG9ucy4KA 256 - {{36, 159}, {385, 14}} + {{36, 98}, {385, 14}} YES @@ -598,7 +596,7 @@ ZSBhbmQgcmlnaHQgbW91c2UgYnV0dG9ucy4KA 256 - {{18, 179}, {402, 18}} + {{18, 118}, {402, 18}} YES @@ -616,46 +614,8 @@ ZSBhbmQgcmlnaHQgbW91c2UgYnV0dG9ucy4KA 25 - - - 256 - {{18, 69}, {402, 18}} - - YES - - 67239424 - 0 - Click-through Inactive Windows - - - 1211912703 - 2 - - - - 200 - 25 - - - - - 256 - {{33, 32}, {385, 31}} - - YES - - 67239424 - 4194304 - When enabled, clicking on an inactive window will cause that mouse click to pass through to that window in addition to activating it. - - - - - - - {{10, 33}, {438, 279}} - + {{10, 33}, {438, 218}} Input @@ -673,7 +633,7 @@ ZSBhbmQgcmlnaHQgbW91c2UgYnV0dG9ucy4KA 256 - {{18, 116}, {402, 18}} + {{18, 55}, {402, 18}} YES @@ -694,7 +654,7 @@ ZSBhbmQgcmlnaHQgbW91c2UgYnV0dG9ucy4KA 256 - {{36, 82}, {385, 28}} + {{36, 21}, {385, 28}} YES @@ -710,7 +670,7 @@ ZSBhbmQgcmlnaHQgbW91c2UgYnV0dG9ucy4KA 256 - {{74, 235}, {128, 26}} + {{74, 174}, {128, 26}} YES @@ -801,7 +761,7 @@ ZSBhbmQgcmlnaHQgbW91c2UgYnV0dG9ucy4KA 256 - {{17, 238}, {55, 20}} + {{17, 177}, {55, 20}} YES @@ -817,7 +777,7 @@ ZSBhbmQgcmlnaHQgbW91c2UgYnV0dG9ucy4KA 256 - {{36, 216}, {392, 14}} + {{36, 155}, {392, 14}} YES @@ -833,7 +793,7 @@ ZSBhbmQgcmlnaHQgbW91c2UgYnV0dG9ucy4KA 256 - {{18, 182}, {409, 23}} + {{18, 121}, {409, 23}} YES @@ -854,7 +814,7 @@ ZSBhbmQgcmlnaHQgbW91c2UgYnV0dG9ucy4KA 256 - {{36, 145}, {385, 31}} + {{36, 84}, {385, 31}} YES @@ -868,12 +828,140 @@ ZSBhbmQgcmlnaHQgbW91c2UgYnV0dG9ucy4KA - {{10, 33}, {438, 279}} + {{10, 33}, {438, 218}} Output + + + 2 + + + + 256 + + YES + + + 256 + {{15, 184}, {402, 18}} + + YES + + 67239424 + 0 + Click-through Inactive Windows + + + 1211912703 + 2 + + + + 200 + 25 + + + + + 256 + {{23, 147}, {385, 31}} + + YES + + 67239424 + 4194304 + When enabled, clicking on an inactive window will cause that mouse click to pass through to that window in addition to activating it. + + + + + + + + + 256 + {{15, 123}, {402, 18}} + + YES + + 67239424 + 0 + Focus Follows Mouse + + + 1211912703 + 2 + + + + 200 + 25 + + + + + 256 + {{23, 100}, {385, 17}} + + YES + + 67239424 + 4194304 + X11 window focus follows the cursor + + + + + + + + + 256 + {{15, 79}, {402, 18}} + + YES + + 67239424 + 0 + Focus On New Windows + + + 1211912703 + 2 + + + + 200 + 25 + + + + + 256 + {{23, 45}, {385, 28}} + + YES + + 67239424 + 4194304 + When enabled, creation of a new X11 window will cause X11.app to move to the foreground (instead of Finder.app, Terminal.app, etc. + + + + + + + + {{10, 33}, {438, 218}} + + + Windows + + + @@ -883,7 +971,7 @@ ZSBhbmQgcmlnaHQgbW91c2UgYnV0dG9ucy4KA 256 - {{18, 243}, {402, 18}} + {{18, 182}, {402, 18}} YES @@ -904,7 +992,7 @@ ZSBhbmQgcmlnaHQgbW91c2UgYnV0dG9ucy4KA 256 - {{18, 166}, {402, 18}} + {{18, 105}, {402, 18}} YES @@ -925,7 +1013,7 @@ ZSBhbmQgcmlnaHQgbW91c2UgYnV0dG9ucy4KA 256 - {{36, 195}, {385, 42}} + {{36, 134}, {385, 42}} YES @@ -943,7 +1031,7 @@ d2hpY2ggbWF5IHByZXZlbnQgWDExIGFwcGxpY2F0aW9ucyBmcm9tIGxhdW5jaGluZy4 256 - {{36, 118}, {385, 42}} + {{36, 57}, {385, 42}} YES @@ -959,7 +1047,7 @@ d2hpY2ggbWF5IHByZXZlbnQgWDExIGFwcGxpY2F0aW9ucyBmcm9tIGxhdW5jaGluZy4 256 - {{20, 17}, {404, 14}} + {{20, -44}, {404, 14}} YES @@ -973,27 +1061,27 @@ d2hpY2ggbWF5IHByZXZlbnQgWDExIGFwcGxpY2F0aW9ucyBmcm9tIGxhdW5jaGluZy4 - {{10, 33}, {438, 279}} + {{10, 33}, {438, 218}} Security - + 0 YES YES YES - + - {481, 345} + {484, 280} - {{0, 0}, {1440, 878}} + {{0, 0}, {1280, 938}} {213, 129} {3.40282e+38, 3.40282e+38} x11_prefs @@ -1001,7 +1089,7 @@ d2hpY2ggbWF5IHByZXZlbnQgWDExIGFwcGxpY2F0aW9ucyBmcm9tIGxhdW5jaGluZy4 11 2 - {{361, 362}, {454, 311}} + {{302, 400}, {454, 311}} 1350041600 X11 Application Menu NSPanel @@ -1011,7 +1099,7 @@ d2hpY2ggbWF5IHByZXZlbnQgWDExIGFwcGxpY2F0aW9ucyBmcm9tIGxhdW5jaGluZy4 {10000, 10000} {320, 240} - + 256 YES @@ -1353,9 +1441,8 @@ d2hpY2ggbWF5IHByZXZlbnQgWDExIGFwcGxpY2F0aW9ucyBmcm9tIGxhdW5jaGluZy4 {454, 311} - - {{0, 0}, {1440, 878}} + {{0, 0}, {1280, 938}} {320, 262} x11_apps @@ -1841,14 +1928,6 @@ d2hpY2ggbWF5IHByZXZlbnQgWDExIGFwcGxpY2F0aW9ucyBmcm9tIGxhdW5jaGluZy4 549 - - - prefs_changed: - - - - 300300 - window_separator @@ -1857,14 +1936,6 @@ d2hpY2ggbWF5IHByZXZlbnQgWDExIGFwcGxpY2F0aW9ucyBmcm9tIGxhdW5jaGluZy4 300331 - - - click_through - - - - 300332 - menu @@ -1881,6 +1952,54 @@ d2hpY2ggbWF5IHByZXZlbnQgWDExIGFwcGxpY2F0aW9ucyBmcm9tIGxhdW5jaGluZy4 300336 + + + prefs_changed: + + + + 300389 + + + + prefs_changed: + + + + 300390 + + + + prefs_changed: + + + + 300391 + + + + click_through + + + + 300392 + + + + focus_follows_mouse + + + + 300393 + + + + focus_on_new_window + + + + 300394 + @@ -2239,6 +2358,7 @@ d2hpY2ggbWF5IHByZXZlbnQgWDExIGFwcGxpY2F0aW9ucyBmcm9tIGxhdW5jaGluZy4 + @@ -2262,8 +2382,6 @@ d2hpY2ggbWF5IHByZXZlbnQgWDExIGFwcGxpY2F0aW9ucyBmcm9tIGxhdW5jaGluZy4 - - @@ -2670,34 +2788,6 @@ d2hpY2ggbWF5IHByZXZlbnQgWDExIGFwcGxpY2F0aW9ucyBmcm9tIGxhdW5jaGluZy4 - - 300296 - - - YES - - - - - - 300297 - - - - - 300298 - - - YES - - - - - - 300299 - - - 295 @@ -2853,6 +2943,113 @@ d2hpY2ggbWF5IHByZXZlbnQgWDExIGFwcGxpY2F0aW9ucyBmcm9tIGxhdW5jaGluZy4 + + 300337 + + + YES + + + + + + 300338 + + + YES + + + + + + + + + + + 300358 + + + YES + + + + + + 300359 + + + YES + + + + + + 300360 + + + + + 300361 + + + + + 300362 + + + YES + + + + + + 300363 + + + + + 300364 + + + YES + + + + + + 300365 + + + + + 300368 + + + YES + + + + + + 300369 + + + + + 300370 + + + YES + + + + + + 300371 + + + @@ -2919,10 +3116,12 @@ d2hpY2ggbWF5IHByZXZlbnQgWDExIGFwcGxpY2F0aW9ucyBmcm9tIGxhdW5jaGluZy4 24.IBPluginDependency 24.ImportedFromIB2 24.editorWindowContentRectSynchronizationRect + 244.IBEditorWindowLastContentRect 244.IBPluginDependency 244.IBWindowTemplateEditedContentRect 244.ImportedFromIB2 244.editorWindowContentRectSynchronizationRect + 244.lastResizeAction 244.windowTemplate.hasMaxSize 244.windowTemplate.hasMinSize 244.windowTemplate.maxSize @@ -2971,12 +3170,24 @@ d2hpY2ggbWF5IHByZXZlbnQgWDExIGFwcGxpY2F0aW9ucyBmcm9tIGxhdW5jaGluZy4 299.IBPluginDependency 299.ImportedFromIB2 300295.IBShouldRemoveOnLegacySave - 300296.IBPluginDependency - 300296.ImportedFromIB2 - 300298.IBPluginDependency - 300298.ImportedFromIB2 300330.IBPluginDependency 300330.ImportedFromIB2 + 300337.IBPluginDependency + 300337.ImportedFromIB2 + 300338.IBPluginDependency + 300338.ImportedFromIB2 + 300358.IBPluginDependency + 300358.ImportedFromIB2 + 300359.IBPluginDependency + 300359.ImportedFromIB2 + 300362.IBPluginDependency + 300362.ImportedFromIB2 + 300364.IBPluginDependency + 300364.ImportedFromIB2 + 300368.IBPluginDependency + 300368.ImportedFromIB2 + 300370.IBPluginDependency + 300370.ImportedFromIB2 305.IBPluginDependency 305.ImportedFromIB2 310.IBPluginDependency @@ -3152,10 +3363,24 @@ d2hpY2ggbWF5IHByZXZlbnQgWDExIGFwcGxpY2F0aW9ucyBmcm9tIGxhdW5jaGluZy4 com.apple.InterfaceBuilder.CocoaPlugin {{271, 666}, {301, 153}} + {{460, 353}, {484, 280}} com.apple.InterfaceBuilder.CocoaPlugin - {{184, 290}, {481, 345}} + {{460, 353}, {484, 280}} {{184, 290}, {481, 345}} + + YES + + YES + IBResizeActionFinalFrame + IBResizeActionInitialFrame + + + YES + {{182, 481}, {484, 280}} + {{182, 103}, {536, 658}} + + {3.40282e+38, 3.40282e+38} @@ -3169,11 +3394,11 @@ d2hpY2ggbWF5IHByZXZlbnQgWDExIGFwcGxpY2F0aW9ucyBmcm9tIGxhdW5jaGluZy4 {{100, 746}, {155, 33}} com.apple.InterfaceBuilder.CocoaPlugin - {{537, 545}, {454, 311}} + {{407, 545}, {454, 311}} com.apple.InterfaceBuilder.CocoaPlugin - {{537, 545}, {454, 311}} + {{407, 545}, {454, 311}} {{433, 406}, {486, 327}} @@ -3320,6 +3545,18 @@ d2hpY2ggbWF5IHByZXZlbnQgWDExIGFwcGxpY2F0aW9ucyBmcm9tIGxhdW5jaGluZy4 com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + {{12, 633}, {218, 203}} com.apple.InterfaceBuilder.CocoaPlugin @@ -3356,7 +3593,7 @@ d2hpY2ggbWF5IHByZXZlbnQgWDExIGFwcGxpY2F0aW9ucyBmcm9tIGxhdW5jaGluZy4 - 300336 + 300394 @@ -3375,6 +3612,17 @@ d2hpY2ggbWF5IHByZXZlbnQgWDExIGFwcGxpY2F0aW9ucyBmcm9tIGxhdW5jaGluZy4 + + X11Controller + NSObject + + IBUserSource + + + + + + YES X11Controller NSObject @@ -3439,6 +3687,8 @@ d2hpY2ggbWF5IHByZXZlbnQgWDExIGFwcGxpY2F0aW9ucyBmcm9tIGxhdW5jaGluZy4 enable_keyequivs enable_tcp fake_buttons + focus_follows_mouse + focus_on_new_window prefs_panel sync_keymap toggle_fullscreen_item @@ -3460,6 +3710,8 @@ d2hpY2ggbWF5IHByZXZlbnQgWDExIGFwcGxpY2F0aW9ucyBmcm9tIGxhdW5jaGluZy4 NSButton NSButton NSButton + NSButton + NSButton NSPanel NSButton NSMenuItem @@ -3469,8 +3721,8 @@ d2hpY2ggbWF5IHByZXZlbnQgWDExIGFwcGxpY2F0aW9ucyBmcm9tIGxhdW5jaGluZy4 - IBUserSource - + IBDocumentRelativeSource + ../../X11Controller.h diff --git a/hw/xquartz/bundle/English.lproj/main.nib/keyedobjects.nib b/hw/xquartz/bundle/English.lproj/main.nib/keyedobjects.nib index f60dcbacb0385caa8292cd06bd178d709632566b..400ee5c286d85b2df5e37b1495b458793faba732 100644 GIT binary patch literal 37953 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%0AE@Z69nOYLBr)cE3Gf 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 diff --git a/hw/xquartz/quartzCommon.h b/hw/xquartz/quartzCommon.h index a0d467389..c4bd2d803 100644 --- a/hw/xquartz/quartzCommon.h +++ b/hw/xquartz/quartzCommon.h @@ -68,6 +68,7 @@ extern int quartzEventWriteFD; // User preferences used by Quartz modes extern int quartzRootless; extern int quartzUseSysBeep; +extern int focusOnNewWindow; extern int quartzUseAGL; extern int quartzEnableKeyEquivalents; @@ -91,17 +92,4 @@ int QuartzFSUseQDCursor(int depth); void QuartzBlockHandler(pointer blockData, OSTimePtr pTimeout, pointer pReadmask); void QuartzWakeupHandler(pointer blockData, int result, pointer pReadmask); -// Messages that can be sent to the main thread. -enum { - kQuartzServerHidden, - kQuartzServerStarted, - kQuartzServerDied, - kQuartzCursorUpdate, - kQuartzPostEvent, - kQuartzSetWindowMenu, - kQuartzSetWindowMenuCheck, - kQuartzSetFrontProcess, - kQuartzSetCanQuit -}; - #endif /* _QUARTZCOMMON_H */ diff --git a/hw/xquartz/quartzForeground.c b/hw/xquartz/quartzForeground.c index 0e724de76..80a04a13b 100644 --- a/hw/xquartz/quartzForeground.c +++ b/hw/xquartz/quartzForeground.c @@ -38,7 +38,7 @@ int QuartzMoveToForeground() { ProcessSerialNumber psn = { 0, kCurrentProcess }; OSStatus returnCode = TransformProcessType(& psn, kProcessTransformToForegroundApplication); if( returnCode == 0) { - fprintf(stderr, "TransformProcessType: Success\n"); + /* fprintf(stderr, "TransformProcessType: Success\n"); */ SetFrontProcess(&psn); } else { fprintf(stderr, "TransformProcessType: Failure\n"); From 63859473965f911515bc6e8d87b32a65ec41eb73 Mon Sep 17 00:00:00 2001 From: Jeremy Huddleston Date: Fri, 21 Mar 2008 19:31:31 -0700 Subject: [PATCH 092/149] XQuartz: Disable 256 color option and fullscreen option (cherry picked from commit 7c1964338a33558d3f25e369dfca99e3ef9d10f9) --- hw/xquartz/X11Application.m | 10 ++++-- hw/xquartz/X11Controller.m | 31 ++++++++++-------- .../English.lproj/main.nib/designable.nib | 14 ++++---- .../English.lproj/main.nib/keyedobjects.nib | Bin 37953 -> 38044 bytes 4 files changed, 33 insertions(+), 22 deletions(-) diff --git a/hw/xquartz/X11Application.m b/hw/xquartz/X11Application.m index 1cf992d92..b7c876365 100644 --- a/hw/xquartz/X11Application.m +++ b/hw/xquartz/X11Application.m @@ -612,8 +612,10 @@ static NSMutableArray * cfarray_to_nsarray (CFArrayRef in) { quartzUseSysBeep = [self prefs_get_boolean:@PREFS_SYSBEEP default:quartzUseSysBeep]; - quartzEnableRootless = [self prefs_get_boolean:@PREFS_ROOTLESS - default:quartzEnableRootless]; + + // TODO: Add fullscreen support + //quartzEnableRootless = [self prefs_get_boolean:@PREFS_ROOTLESS + // default:quartzEnableRootless]; #ifdef DARWIN_DDX_MISSING quartzFullscreenDisableHotkeys = ![self prefs_get_boolean: @PREFS_FULLSCREEN_HOTKEYS default: @@ -645,6 +647,10 @@ static NSMutableArray * cfarray_to_nsarray (CFArrayRef in) { darwinDesiredDepth = [self prefs_get_integer:@PREFS_DEPTH default:darwinDesiredDepth]; + + // TODO: Add 256 color support + if(darwinDesiredDepth == 8) + darwinDesiredDepth = -1; enable_stereo = [self prefs_get_boolean:@PREFS_ENABLE_STEREO default:false]; diff --git a/hw/xquartz/X11Controller.m b/hw/xquartz/X11Controller.m index 3880b3f38..a9d2addbd 100644 --- a/hw/xquartz/X11Controller.m +++ b/hw/xquartz/X11Controller.m @@ -635,22 +635,27 @@ objectValueForTableColumn:(NSTableColumn *)tableColumn row:(int)row - (IBAction) prefs_show:sender { - [fake_buttons setIntValue:darwinFakeButtons]; - [use_sysbeep setIntValue:quartzUseSysBeep]; - [enable_keyequivs setIntValue:X11EnableKeyEquivalents]; - [sync_keymap setIntValue:darwinSyncKeymap]; - [sync_keymap setEnabled:darwinKeymapFile == NULL]; - [click_through setIntValue:[NSApp prefs_get_boolean:@PREFS_CLICK_THROUGH default:NO]]; - [focus_follows_mouse setIntValue:[NSApp prefs_get_boolean:@PREFS_FFM default:NO]]; - [focus_on_new_window setIntValue:[NSApp prefs_get_boolean:@PREFS_FOCUS_ON_NEW_WINDOW default:YES]]; + [fake_buttons setIntValue:darwinFakeButtons]; + [use_sysbeep setIntValue:quartzUseSysBeep]; + [enable_keyequivs setIntValue:X11EnableKeyEquivalents]; + [sync_keymap setIntValue:darwinSyncKeymap]; + [sync_keymap setEnabled:darwinKeymapFile == NULL]; + [click_through setIntValue:[NSApp prefs_get_boolean:@PREFS_CLICK_THROUGH default:NO]]; + [focus_follows_mouse setIntValue:[NSApp prefs_get_boolean:@PREFS_FFM default:NO]]; + [focus_on_new_window setIntValue:[NSApp prefs_get_boolean:@PREFS_FOCUS_ON_NEW_WINDOW default:YES]]; + + [enable_auth setIntValue:![NSApp prefs_get_boolean:@PREFS_NO_AUTH default:NO]]; + [enable_tcp setIntValue:![NSApp prefs_get_boolean:@PREFS_NO_TCP default:NO]]; - [enable_auth setIntValue:![NSApp prefs_get_boolean:@PREFS_NO_AUTH default:NO]]; - [enable_tcp setIntValue:![NSApp prefs_get_boolean:@PREFS_NO_TCP default:NO]]; - [depth selectItemAtIndex:[depth indexOfItemWithTag:[NSApp prefs_get_integer:@PREFS_DEPTH default:-1]]]; + [depth selectItemAtIndex:[depth indexOfItemWithTag:[NSApp prefs_get_integer:@PREFS_DEPTH default:-1]]]; + // TODO: Add 256 color support + [depth removeItemAtIndex:[depth indexOfItemWithTag:8]]; - [enable_fullscreen setIntValue:!quartzEnableRootless]; + [enable_fullscreen setIntValue:!quartzEnableRootless]; + // TODO: Add fullscreen support + [enable_fullscreen setEnabled:NO]; - [prefs_panel makeKeyAndOrderFront:sender]; + [prefs_panel makeKeyAndOrderFront:sender]; } - (IBAction) quit:sender diff --git a/hw/xquartz/bundle/English.lproj/main.nib/designable.nib b/hw/xquartz/bundle/English.lproj/main.nib/designable.nib index adc0340ed..672ba904d 100644 --- a/hw/xquartz/bundle/English.lproj/main.nib/designable.nib +++ b/hw/xquartz/bundle/English.lproj/main.nib/designable.nib @@ -472,7 +472,7 @@ 1 - + 256 YES @@ -616,6 +616,7 @@ ZSBhbmQgcmlnaHQgbW91c2UgYnV0dG9ucy4KA {{10, 33}, {438, 218}} + Input @@ -839,7 +840,7 @@ ZSBhbmQgcmlnaHQgbW91c2UgYnV0dG9ucy4KA 2 - + 256 YES @@ -956,7 +957,6 @@ ZSBhbmQgcmlnaHQgbW91c2UgYnV0dG9ucy4KA {{10, 33}, {438, 218}} - Windows @@ -1068,14 +1068,14 @@ d2hpY2ggbWF5IHByZXZlbnQgWDExIGFwcGxpY2F0aW9ucyBmcm9tIGxhdW5jaGluZy4 - + 0 YES YES YES - + @@ -3363,9 +3363,9 @@ d2hpY2ggbWF5IHByZXZlbnQgWDExIGFwcGxpY2F0aW9ucyBmcm9tIGxhdW5jaGluZy4 com.apple.InterfaceBuilder.CocoaPlugin {{271, 666}, {301, 153}} - {{460, 353}, {484, 280}} + {{313, 353}, {484, 280}} com.apple.InterfaceBuilder.CocoaPlugin - {{460, 353}, {484, 280}} + {{313, 353}, {484, 280}} {{184, 290}, {481, 345}} diff --git a/hw/xquartz/bundle/English.lproj/main.nib/keyedobjects.nib b/hw/xquartz/bundle/English.lproj/main.nib/keyedobjects.nib index 400ee5c286d85b2df5e37b1495b458793faba732..91a7c5adb44e6355d01211d48fe4c5a0121a6b43 100644 GIT binary patch literal 38044 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 literal 37953 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%0AE@Z69nOYLBr)cE3Gf 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 Date: Sat, 22 Mar 2008 17:28:48 +0100 Subject: [PATCH 093/149] exa: use xf86ReturnOptValBool instead of xf86IsOptionSet The latter doesn't give you the option's value, it just tells you if it's present in the configuration. So using Option "EXANoComposite" "false" disabled composite acceleration. --- hw/xfree86/exa/examodule.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/hw/xfree86/exa/examodule.c b/hw/xfree86/exa/examodule.c index 086639cc5..e18da0a37 100644 --- a/hw/xfree86/exa/examodule.c +++ b/hw/xfree86/exa/examodule.c @@ -148,22 +148,23 @@ exaDDXDriverInit(ScreenPtr pScreen) FALSE); } - if (xf86IsOptionSet(pScreenPriv->options, EXAOPT_NO_COMPOSITE)) { - xf86DrvMsg(pScreen->myNum, X_INFO, + if (xf86ReturnOptValBool(pScreenPriv->options, + EXAOPT_NO_COMPOSITE, FALSE)) { + xf86DrvMsg(pScreen->myNum, X_CONFIG, "EXA: Disabling Composite operation " "(RENDER acceleration)\n"); pExaScr->info->CheckComposite = NULL; pExaScr->info->PrepareComposite = NULL; } - if (xf86IsOptionSet(pScreenPriv->options, EXAOPT_NO_UTS)) { - xf86DrvMsg(pScreen->myNum, X_INFO, + if (xf86ReturnOptValBool(pScreenPriv->options, EXAOPT_NO_UTS, FALSE)) { + xf86DrvMsg(pScreen->myNum, X_CONFIG, "EXA: Disabling UploadToScreen\n"); pExaScr->info->UploadToScreen = NULL; } - if (xf86IsOptionSet(pScreenPriv->options, EXAOPT_NO_DFS)) { - xf86DrvMsg(pScreen->myNum, X_INFO, + if (xf86ReturnOptValBool(pScreenPriv->options, EXAOPT_NO_DFS, FALSE)) { + xf86DrvMsg(pScreen->myNum, X_CONFIG, "EXA: Disabling DownloadFromScreen\n"); pExaScr->info->DownloadFromScreen = NULL; } From 4217ba0cf0c9bbea3774760e836ab372acf3237c Mon Sep 17 00:00:00 2001 From: Julien Cristau Date: Sat, 22 Mar 2008 17:31:08 +0100 Subject: [PATCH 094/149] xaa: use xf86ReturnOptValBool instead of xf86IsOptionSet The latter doesn't return the option's value, just whether it's present in the configuration. --- hw/xfree86/xaa/xaaInitAccel.c | 57 ++++++++++++++++++++++------------- 1 file changed, 36 insertions(+), 21 deletions(-) diff --git a/hw/xfree86/xaa/xaaInitAccel.c b/hw/xfree86/xaa/xaaInitAccel.c index 1b7c15487..53795f067 100644 --- a/hw/xfree86/xaa/xaaInitAccel.c +++ b/hw/xfree86/xaa/xaaInitAccel.c @@ -181,7 +181,7 @@ XAAInitAccel(ScreenPtr pScreen, XAAInfoRecPtr infoRec) if(infoRec->SetupForScreenToScreenCopy && infoRec->SubsequentScreenToScreenCopy && - !xf86IsOptionSet(options, XAAOPT_SCREEN_TO_SCREEN_COPY)) { + !xf86ReturnOptValBool(options, XAAOPT_SCREEN_TO_SCREEN_COPY, FALSE)) { HaveScreenToScreenCopy = TRUE; } else { infoRec->ScreenToScreenCopyFlags = 0; @@ -192,10 +192,10 @@ XAAInitAccel(ScreenPtr pScreen, XAAInfoRecPtr infoRec) /**** Solid Filled Rects ****/ if(infoRec->SetupForSolidFill && infoRec->SubsequentSolidFillRect && - !xf86IsOptionSet(options, XAAOPT_SOLID_FILL_RECT)) { + !xf86ReturnOptValBool(options, XAAOPT_SOLID_FILL_RECT, FALSE)) { HaveSolidFillRect = TRUE; if(infoRec->SubsequentSolidFillTrap && - !xf86IsOptionSet(options, XAAOPT_SOLID_FILL_TRAP)) + !xf86ReturnOptValBool(options, XAAOPT_SOLID_FILL_TRAP, FALSE)) HaveSolidFillTrap = TRUE; else infoRec->SubsequentSolidFillTrap = NULL; @@ -210,10 +210,11 @@ XAAInitAccel(ScreenPtr pScreen, XAAInfoRecPtr infoRec) if(infoRec->SetupForSolidLine) { if(infoRec->SubsequentSolidTwoPointLine && - !xf86IsOptionSet(options, XAAOPT_SOLID_TWO_POINT_LINE)) + !xf86ReturnOptValBool(options, + XAAOPT_SOLID_TWO_POINT_LINE, FALSE)) HaveSolidTwoPointLine = TRUE; if(infoRec->SubsequentSolidBresenhamLine && - !xf86IsOptionSet(options, XAAOPT_SOLID_BRESENHAM_LINE)) { + !xf86ReturnOptValBool(options, XAAOPT_SOLID_BRESENHAM_LINE, FALSE)) { HaveSolidBresenhamLine = TRUE; if(infoRec->SolidBresenhamLineErrorTermBits) @@ -222,7 +223,8 @@ XAAInitAccel(ScreenPtr pScreen, XAAInfoRecPtr infoRec) } if(infoRec->SubsequentSolidHorVertLine && - !xf86IsOptionSet(options, XAAOPT_SOLID_HORVERT_LINE)) + !xf86ReturnOptValBool(options, + XAAOPT_SOLID_HORVERT_LINE, FALSE)) HaveSolidHorVertLine = TRUE; else if(HaveSolidTwoPointLine) { infoRec->SubsequentSolidHorVertLine = @@ -265,10 +267,14 @@ XAAInitAccel(ScreenPtr pScreen, XAAInfoRecPtr infoRec) if(infoRec->SetupForMono8x8PatternFill && infoRec->SubsequentMono8x8PatternFillRect && - !xf86IsOptionSet(options, XAAOPT_MONO_8x8_PATTERN_FILL_RECT)) { + !xf86ReturnOptValBool(options, + XAAOPT_MONO_8x8_PATTERN_FILL_RECT, + FALSE)) { HaveMono8x8PatternFillRect = TRUE; if(infoRec->SubsequentMono8x8PatternFillTrap && - !xf86IsOptionSet(options, XAAOPT_MONO_8x8_PATTERN_FILL_TRAP)) + !xf86ReturnOptValBool(options, + XAAOPT_MONO_8x8_PATTERN_FILL_TRAP, + FALSE)) HaveMono8x8PatternFillTrap = TRUE; if(infoRec->Mono8x8PatternFillFlags & @@ -318,10 +324,12 @@ XAAInitAccel(ScreenPtr pScreen, XAAInfoRecPtr infoRec) if(infoRec->SetupForDashedLine && infoRec->DashPatternMaxLength) { if(infoRec->SubsequentDashedTwoPointLine && - !xf86IsOptionSet(options, XAAOPT_DASHED_TWO_POINT_LINE)) + !xf86ReturnOptValBool(options, XAAOPT_DASHED_TWO_POINT_LINE, + FALSE)) HaveDashedTwoPointLine = TRUE; if(infoRec->SubsequentDashedBresenhamLine && - !xf86IsOptionSet(options, XAAOPT_DASHED_BRESENHAM_LINE)) { + !xf86ReturnOptValBool(options, XAAOPT_DASHED_BRESENHAM_LINE, + FALSE)) { HaveDashedBresenhamLine = TRUE; if(infoRec->DashedBresenhamLineErrorTermBits) @@ -345,10 +353,11 @@ XAAInitAccel(ScreenPtr pScreen, XAAInfoRecPtr infoRec) if(infoRec->SetupForColor8x8PatternFill && infoRec->SubsequentColor8x8PatternFillRect && - !xf86IsOptionSet(options, XAAOPT_COL_8x8_PATTERN_FILL_RECT)) { + !xf86ReturnOptValBool(options, XAAOPT_COL_8x8_PATTERN_FILL_RECT, FALSE)) { HaveColor8x8PatternFillRect = TRUE; if(infoRec->SubsequentColor8x8PatternFillTrap && - !xf86IsOptionSet(options, XAAOPT_COL_8x8_PATTERN_FILL_TRAP)) + !xf86ReturnOptValBool(options, XAAOPT_COL_8x8_PATTERN_FILL_TRAP, + FALSE)) HaveColor8x8PatternFillTrap = TRUE; else infoRec->SubsequentColor8x8PatternFillTrap = NULL; @@ -381,7 +390,8 @@ XAAInitAccel(ScreenPtr pScreen, XAAInfoRecPtr infoRec) if(infoRec->SetupForCPUToScreenColorExpandFill && infoRec->ColorExpandBase && infoRec->SubsequentCPUToScreenColorExpandFill && - !xf86IsOptionSet(options, XAAOPT_CPU_TO_SCREEN_COL_EXP_FILL)) { + !xf86ReturnOptValBool(options, XAAOPT_CPU_TO_SCREEN_COL_EXP_FILL, + FALSE)) { int dwordsNeeded = pScrn->virtualX; infoRec->ColorExpandRange >>= 2; /* convert to DWORDS */ @@ -406,7 +416,9 @@ XAAInitAccel(ScreenPtr pScreen, XAAInfoRecPtr infoRec) infoRec->SubsequentColorExpandScanline && infoRec->ScanlineColorExpandBuffers && (infoRec->NumScanlineColorExpandBuffers > 0) && - !xf86IsOptionSet(options, XAAOPT_SCANLINE_CPU_TO_SCREEN_COL_EXP_FILL)) { + !xf86ReturnOptValBool(options, + XAAOPT_SCANLINE_CPU_TO_SCREEN_COL_EXP_FILL, + FALSE)) { HaveScanlineColorExpansion = TRUE; } else { infoRec->ScanlineCPUToScreenColorExpandFillFlags = 0; @@ -419,7 +431,8 @@ XAAInitAccel(ScreenPtr pScreen, XAAInfoRecPtr infoRec) if(infoRec->SetupForScreenToScreenColorExpandFill && infoRec->SubsequentScreenToScreenColorExpandFill && - !xf86IsOptionSet(options, XAAOPT_SCREEN_TO_SCREEN_COL_EXP_FILL)) { + !xf86ReturnOptValBool(options, XAAOPT_SCREEN_TO_SCREEN_COL_EXP_FILL, + FALSE)) { HaveScreenToScreenColorExpandFill = TRUE; if (!infoRec->CacheColorExpandDensity) infoRec->CacheColorExpandDensity = 1; @@ -433,7 +446,7 @@ XAAInitAccel(ScreenPtr pScreen, XAAInfoRecPtr infoRec) if(infoRec->SetupForImageWrite && infoRec->ImageWriteBase && infoRec->SubsequentImageWriteRect && - !xf86IsOptionSet(options, XAAOPT_IMAGE_WRITE_RECT)) { + !xf86ReturnOptValBool(options, XAAOPT_IMAGE_WRITE_RECT, FALSE)) { infoRec->ImageWriteRange >>= 2; /* convert to DWORDS */ if(infoRec->ImageWriteFlags & CPU_TRANSFER_BASE_FIXED) @@ -452,7 +465,8 @@ XAAInitAccel(ScreenPtr pScreen, XAAInfoRecPtr infoRec) infoRec->SubsequentImageWriteScanline && infoRec->ScanlineImageWriteBuffers && (infoRec->NumScanlineImageWriteBuffers > 0) && - !xf86IsOptionSet(options, XAAOPT_SCANLINE_IMAGE_WRITE_RECT)) { + !xf86ReturnOptValBool(options, XAAOPT_SCANLINE_IMAGE_WRITE_RECT, + FALSE)) { HaveScanlineImageWriteRect = TRUE; } else { infoRec->ScanlineImageWriteFlags = 0; @@ -518,7 +532,8 @@ XAAInitAccel(ScreenPtr pScreen, XAAInfoRecPtr infoRec) #define XAAMSG(s) do { if (serverGeneration == 1) xf86ErrorF(s); } while (0) if((infoRec->Flags & OFFSCREEN_PIXMAPS) && HaveScreenToScreenCopy && - !xf86IsOptionSet(options, XAAOPT_OFFSCREEN_PIXMAPS)) { + !xf86ReturnOptValBool(options, XAAOPT_OFFSCREEN_PIXMAPS, + FALSE)) { XAAMSG("\tOffscreen Pixmaps\n"); } else { infoRec->Flags &= ~OFFSCREEN_PIXMAPS; @@ -800,7 +815,7 @@ XAAInitAccel(ScreenPtr pScreen, XAAInfoRecPtr infoRec) /**** WriteBitmap ****/ if(infoRec->WriteBitmap && - !xf86IsOptionSet(options, XAAOPT_WRITE_BITMAP)) { + !xf86ReturnOptValBool(options, XAAOPT_WRITE_BITMAP, FALSE)) { XAAMSG("\tDriver provided WriteBitmap replacement\n"); } else if(HaveColorExpansion) { if (infoRec->CPUToScreenColorExpandFillFlags & TRIPLE_BITS_24BPP) { @@ -959,7 +974,7 @@ XAAInitAccel(ScreenPtr pScreen, XAAInfoRecPtr infoRec) /**** WritePixmap ****/ if(infoRec->WritePixmap && - !xf86IsOptionSet(options, XAAOPT_WRITE_PIXMAP)) { + !xf86ReturnOptValBool(options, XAAOPT_WRITE_PIXMAP, FALSE)) { XAAMSG("\tDriver provided WritePixmap replacement\n"); } else if(HaveImageWriteRect) { infoRec->WritePixmap = XAAWritePixmap; @@ -1433,7 +1448,7 @@ XAAInitAccel(ScreenPtr pScreen, XAAInfoRecPtr infoRec) else infoRec->Flags &= ~PIXMAP_CACHE; - if (xf86IsOptionSet(options, XAAOPT_PIXMAP_CACHE)) + if (xf86ReturnOptValBool(options, XAAOPT_PIXMAP_CACHE, FALSE)) infoRec->Flags &= ~PIXMAP_CACHE; if(infoRec->WriteMono8x8PatternToCache) {} From 536f2ff5382aaaace3b55481e15366bb15d87801 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Mon, 24 Mar 2008 12:22:19 -0400 Subject: [PATCH 095/149] Bug #13962: Re-arm the DPMS timer when re-enabling DPMS. --- Xext/dpms.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Xext/dpms.c b/Xext/dpms.c index 6f01fa348..e3204febb 100644 --- a/Xext/dpms.c +++ b/Xext/dpms.c @@ -188,12 +188,15 @@ static int ProcDPMSEnable(client) register ClientPtr client; { - /* REQUEST(xDPMSEnableReq); */ + Bool was_enabled = DPMSEnabled; REQUEST_SIZE_MATCH(xDPMSEnableReq); - if (DPMSCapableFlag) + if (DPMSCapableFlag) { DPMSEnabled = TRUE; + if (!was_enabled) + SetScreenSaverTimer(); + } return(client->noClientException); } From 87bfd3bd96c714a1c252d42408b5a1a4ff9dab06 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Mon, 24 Mar 2008 13:33:38 -0400 Subject: [PATCH 096/149] Bug #11508: Fix build without XV. --- hw/xfree86/loader/xf86sym.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hw/xfree86/loader/xf86sym.c b/hw/xfree86/loader/xf86sym.c index f86a1433d..24fc44c1b 100644 --- a/hw/xfree86/loader/xf86sym.c +++ b/hw/xfree86/loader/xf86sym.c @@ -68,8 +68,10 @@ # include "xf86Xinput.h" #endif #include "xf86OSmouse.h" +#ifdef XV #include "xf86xv.h" #include "xf86xvmc.h" +#endif #include "xf86cmap.h" #include "xf86fbman.h" #include "dgaproc.h" From 862ff9ac92037e13629329eb6ba50ff6bd2c5f71 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Mon, 24 Mar 2008 13:37:42 -0400 Subject: [PATCH 097/149] Bug #11510: Fix build without RECORD. --- Makefile.am | 6 +++++- hw/xfree86/dixmods/Makefile.am | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/Makefile.am b/Makefile.am index e382d58e7..71ba2c429 100644 --- a/Makefile.am +++ b/Makefile.am @@ -30,6 +30,10 @@ if DBE DBE_DIR=dbe endif +if RECORD +RECORD_DIR=record +endif + SUBDIRS = \ doc \ include \ @@ -48,7 +52,7 @@ SUBDIRS = \ $(AFB_DIR) \ $(CFB_DIR) \ $(CFB32_DIR) \ - record \ + $(RECORD_DIR) \ xfixes \ damageext \ $(XTRAP_DIR) \ diff --git a/hw/xfree86/dixmods/Makefile.am b/hw/xfree86/dixmods/Makefile.am index efc5f4a39..dad2dd36b 100644 --- a/hw/xfree86/dixmods/Makefile.am +++ b/hw/xfree86/dixmods/Makefile.am @@ -26,6 +26,10 @@ if MFB MFBMOD = libmfb.la endif +if RECORD +RECORDMOD = librecord.la +endif + module_LTLIBRARIES = $(AFBMOD) \ $(CFBMOD) \ libfb.la \ @@ -34,7 +38,7 @@ module_LTLIBRARIES = $(AFBMOD) \ libshadow.la extsmoduledir = $(moduledir)/extensions -extsmodule_LTLIBRARIES = librecord.la \ +extsmodule_LTLIBRARIES = $(RECORDMOD) \ $(DBEMOD) \ $(GLXMODS) \ $(XTRAPMOD) From f028e245a7932362656701c08fcfbfa8e8949077 Mon Sep 17 00:00:00 2001 From: David Nusinow Date: Thu, 28 Feb 2008 19:45:21 -0500 Subject: [PATCH 098/149] Bug #10016: Implement WM_CLASS hints in Xephyr. --- hw/kdrive/ephyr/ephyr.h | 1 + hw/kdrive/ephyr/ephyrinit.c | 19 +++++++++++++++++++ hw/kdrive/ephyr/hostx.c | 28 ++++++++++++++++++++++++++++ hw/kdrive/ephyr/hostx.h | 3 +++ 4 files changed, 51 insertions(+) diff --git a/hw/kdrive/ephyr/ephyr.h b/hw/kdrive/ephyr/ephyr.h index 8ed7e23dd..5d58a216c 100644 --- a/hw/kdrive/ephyr/ephyr.h +++ b/hw/kdrive/ephyr/ephyr.h @@ -28,6 +28,7 @@ #include #include #include +#include #include "os.h" /* for OsSignal() */ #include "kdrive.h" diff --git a/hw/kdrive/ephyr/ephyrinit.c b/hw/kdrive/ephyr/ephyrinit.c index 6196996a9..47ddb3d82 100644 --- a/hw/kdrive/ephyr/ephyrinit.c +++ b/hw/kdrive/ephyr/ephyrinit.c @@ -109,6 +109,7 @@ ddxUseMsg (void) ErrorF("-nodri do not use DRI\n"); #endif ErrorF("-noxv do not use XV\n"); + ErrorF("-name [name] define the name in the WM_CLASS property\n"); ErrorF("\n"); exit(1); @@ -148,6 +149,11 @@ ddxProcessArgument (int argc, char **argv, int i) { EPHYR_DBG("mark argv[%d]='%s'", i, argv[i] ); + if (i == 1) + { + hostx_use_resname(basename(argv[0]), 0); + } + if (!strcmp (argv[i], "-parent")) { if(i+1 < argc) @@ -223,6 +229,19 @@ ddxProcessArgument (int argc, char **argv, int i) EPHYR_LOG ("no XVideo enabled\n") ; return 1 ; } + else if (!strcmp (argv[i], "-name")) + { + if (i+1 < argc && argv[i+1][0] != '-') + { + hostx_use_resname(argv[i+1], 1); + return 2; + } + else + { + UseMsg(); + return 0; + } + } else if (argv[i][0] == ':') { hostx_set_display_name(argv[i]); diff --git a/hw/kdrive/ephyr/hostx.c b/hw/kdrive/ephyr/hostx.c index fd84ec0ef..1a71d0641 100644 --- a/hw/kdrive/ephyr/hostx.c +++ b/hw/kdrive/ephyr/hostx.c @@ -107,6 +107,9 @@ extern EphyrKeySyms ephyrKeySyms; extern int monitorResolution; +char *ephyrResName = NULL; +int ephyrResNameFromCmd = 0; + static void hostx_set_fullscreen_hint(void); @@ -296,6 +299,13 @@ hostx_handle_signal (int signum) HostXWantDamageDebug); } +void +hostx_use_resname (char *name, int fromcmd) +{ + ephyrResName = name; + ephyrResNameFromCmd = fromcmd; +} + int hostx_init (void) { @@ -304,6 +314,8 @@ hostx_init (void) Pixmap cursor_pxm; XColor col; int index; + char *tmpstr; + XClassHint *class_hint; attr.event_mask = ButtonPressMask @@ -327,6 +339,8 @@ hostx_init (void) HostX.depth = DefaultDepth(HostX.dpy, HostX.screen); HostX.visual = DefaultVisual(HostX.dpy, HostX.screen); + class_hint = XAllocClassHint(); + for (index = 0 ; index < HostX.n_screens ; index++) { struct EphyrHostScreen *host_screen = &HostX.screens[index]; @@ -389,9 +403,23 @@ hostx_init (void) hostx_set_fullscreen_hint(); } + + if (class_hint) + { + tmpstr = getenv("RESOURCE_NAME"); + if (tmpstr && (!ephyrResNameFromCmd)) + ephyrResName = tmpstr; + class_hint->res_name = ephyrResName; + class_hint->res_class = "Xephyr"; + XSetClassHint(hostx_get_display(), host_screen->win, class_hint); + + } + } } + if (class_hint) + XFree(class_hint); XParseColor (HostX.dpy, DefaultColormap (HostX.dpy,HostX.screen), "red", &col); diff --git a/hw/kdrive/ephyr/hostx.h b/hw/kdrive/ephyr/hostx.h index 48d314748..47ba61b5b 100644 --- a/hw/kdrive/ephyr/hostx.h +++ b/hw/kdrive/ephyr/hostx.h @@ -145,6 +145,9 @@ hostx_want_preexisting_window(EphyrScreenInfo screen); void hostx_use_preexisting_window(unsigned long win_id); +void +hostx_use_resname (char *name, int fromcmd); + void hostx_handle_signal(int signum); From e7a364425547103a98acabfc67d16e1ae0c2967f Mon Sep 17 00:00:00 2001 From: Sascha Hlusiak Date: Tue, 25 Mar 2008 12:32:33 -0400 Subject: [PATCH 099/149] Fix getValuatorEvents to compute number of valuators correctly. --- dix/getevents.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dix/getevents.c b/dix/getevents.c index 3e6fe5ae0..6a2f7baf6 100644 --- a/dix/getevents.c +++ b/dix/getevents.c @@ -349,7 +349,7 @@ getValuatorEvents(xEvent *events, DeviceIntPtr pDev, int first_valuator, for (i = first_valuator; i < final_valuator; i += 6, xv++, events++) { xv->type = DeviceValuator; xv->first_valuator = i; - xv->num_valuators = ((num_valuators - i) > 6) ? 6 : (num_valuators - i); + xv->num_valuators = ((num_valuators - i) > 6) ? 6 : (final_valuator - i); xv->deviceid = pDev->id; switch (final_valuator - i) { case 6: From 47eb658e802775021e3efec109f95431cca188ca Mon Sep 17 00:00:00 2001 From: Sascha Hlusiak Date: Tue, 25 Mar 2008 17:37:25 +0100 Subject: [PATCH 100/149] Support to pass arbitrary options via HAL hotplugging Parse "input.x11_options" and pass every key/name pair to the driver. Remove check for input.capabilities, because that's part of the fdi files. Thanks to Dustin Spicuzza for the patch. --- config/hal.c | 194 +++++++++++++++++++++++++------------------ config/x11-input.fdi | 62 ++++++++++++-- configure.ac | 2 + 3 files changed, 173 insertions(+), 85 deletions(-) diff --git a/config/hal.c b/config/hal.c index 1575422c3..f15064646 100644 --- a/config/hal.c +++ b/config/hal.c @@ -38,9 +38,10 @@ #include "config-backends.h" #include "os.h" -#define TYPE_NONE 0 -#define TYPE_KEYS 1 -#define TYPE_POINTER 2 + +#define LIBHAL_PROP_KEY "input.x11_options." +#define LIBHAL_XKB_PROP_KEY "input.xkb." + struct config_hal_info { DBusConnection *system_bus; @@ -50,7 +51,8 @@ struct config_hal_info { static void remove_device(DeviceIntPtr dev) { - DebugF("[config/hal] removing device %s\n", dev->name); + /* this only gets called for devices that have already been added */ + LogMessage(X_INFO, "config/hal: removing device %s\n", dev->name); /* Call PIE here so we don't try to dereference a device that's * already been removed. */ @@ -105,7 +107,7 @@ get_prop_string(LibHalContext *hal_ctx, const char *udi, const char *name) char *prop, *ret; prop = libhal_device_get_property_string(hal_ctx, udi, name, NULL); - DebugF("[config/hal] getting %s on %s returned %s\n", name, udi, prop); + LogMessageVerb(X_INFO, 10, "config/hal: getting %s on %s returned %s\n", name, udi, prop); if (prop) { ret = xstrdup(prop); libhal_free_string(prop); @@ -117,6 +119,9 @@ get_prop_string(LibHalContext *hal_ctx, const char *udi, const char *name) return ret; } +/* this function is no longer used... keep it here in case its needed in + * the future. */ +#if 0 static char * get_prop_string_array(LibHalContext *hal_ctx, const char *udi, const char *prop) { @@ -150,117 +155,146 @@ get_prop_string_array(LibHalContext *hal_ctx, const char *udi, const char *prop) return ret; } +#endif static void device_added(LibHalContext *hal_ctx, const char *udi) { - char **props; - char *path = NULL, *driver = NULL, *name = NULL, *xkb_rules = NULL; - char *xkb_model = NULL, *xkb_layout = NULL, *xkb_variant = NULL; - char *xkb_options = NULL, *config_info = NULL; + char *path = NULL, *driver = NULL, *name = NULL, *config_info = NULL; InputOption *options = NULL, *tmpo = NULL; DeviceIntPtr dev; DBusError error; - int type = TYPE_NONE; - int i; - + + LibHalPropertySet *set = NULL; + LibHalPropertySetIterator set_iter; + char *psi_key = NULL, *tmp_val, *tmp_key; + + dbus_error_init(&error); - props = libhal_device_get_property_strlist(hal_ctx, udi, - "info.capabilities", &error); - if (!props) { - DebugF("[config/hal] couldn't get capabilities for %s: %s (%s)\n", - udi, error.name, error.message); - goto out_error; - } - for (i = 0; props[i]; i++) { - /* input.keys is the new, of which input.keyboard is a subset, but - * input.keyboard is the old 'we have keys', so we have to keep it - * around. */ - if (strcmp(props[i], "input.keys") == 0 || - strcmp(props[i], "input.keyboard") == 0) - type |= TYPE_KEYS; - if (strcmp(props[i], "input.mouse") == 0 || - strcmp(props[i], "input.touchpad") == 0) - type |= TYPE_POINTER; - } - libhal_free_string_array(props); - - if (type == TYPE_NONE) - goto out_error; - driver = get_prop_string(hal_ctx, udi, "input.x11_driver"); - path = get_prop_string(hal_ctx, udi, "input.device"); - if (!driver || !path) { - DebugF("[config/hal] no driver or path specified for %s\n", udi); + if (!driver){ + /* verbose, don't tell the user unless they _want_ to see it */ + LogMessageVerb(X_INFO,7,"config/hal: no driver specified for device %s\n", udi); goto unwind; } + + path = get_prop_string(hal_ctx, udi, "input.device"); + if (!path) { + LogMessage(X_WARNING,"config/hal: no driver or path specified for %s\n", udi); + goto unwind; + } + name = get_prop_string(hal_ctx, udi, "info.product"); if (!name) name = xstrdup("(unnamed)"); - if (type & TYPE_KEYS) { - xkb_rules = get_prop_string(hal_ctx, udi, "input.xkb.rules"); - xkb_model = get_prop_string(hal_ctx, udi, "input.xkb.model"); - xkb_layout = get_prop_string(hal_ctx, udi, "input.xkb.layout"); - xkb_variant = get_prop_string(hal_ctx, udi, "input.xkb.variant"); - xkb_options = get_prop_string_array(hal_ctx, udi, "input.xkb.options"); - } - options = xcalloc(sizeof(*options), 1); + if (!options){ + LogMessage(X_ERROR, "config/hal: couldn't allocate space for input options!\n"); + goto unwind; + } + options->key = xstrdup("_source"); options->value = xstrdup("server/hal"); if (!options->key || !options->value) { - ErrorF("[config] couldn't allocate first key/value pair\n"); + LogMessage(X_ERROR, "config/hal: couldn't allocate first key/value pair\n"); goto unwind; } + /* most drivers use device.. not path. evdev uses both however, but the + * path version isn't documented apparently. support both for now. */ add_option(&options, "path", path); + add_option(&options, "device", path); + add_option(&options, "driver", driver); add_option(&options, "name", name); + config_info = xalloc(strlen(udi) + 5); /* "hal:" and NULL */ - if (!config_info) + if (!config_info) { + LogMessage(X_ERROR, "config/hal: couldn't allocate name\n"); goto unwind; + } sprintf(config_info, "hal:%s", udi); - if (xkb_rules) - add_option(&options, "xkb_rules", xkb_rules); - if (xkb_model) - add_option(&options, "xkb_model", xkb_model); - if (xkb_layout) - add_option(&options, "xkb_layout", xkb_layout); - if (xkb_variant) - add_option(&options, "xkb_variant", xkb_variant); - if (xkb_options) - add_option(&options, "xkb_options", xkb_options); + /* ok, grab options from hal.. iterate through all properties + * and lets see if any of them are options that we can add */ + set = libhal_device_get_all_properties(hal_ctx, udi, &error); + + if (!set) { + LogMessage(X_ERROR, "config/hal: couldn't get property list for %s: %s (%s)\n", + udi, error.name, error.message); + goto unwind; + } + + libhal_psi_init(&set_iter,set); + while (libhal_psi_has_more(&set_iter)) { + /* we are looking for supported keys.. extract and add to options */ + psi_key = libhal_psi_get_key(&set_iter); + + if (psi_key){ - DebugF("[config/hal] Adding device %s\n", name); + /* normal options first (input.x11_options.) */ + if (!strncasecmp(psi_key, LIBHAL_PROP_KEY, sizeof(LIBHAL_PROP_KEY)-1)){ + + /* only support strings for all values */ + tmp_val = get_prop_string(hal_ctx, udi, psi_key); + + if (tmp_val){ + add_option(&options, psi_key + sizeof(LIBHAL_PROP_KEY)-1, tmp_val); + xfree(tmp_val); + } + + /* evdev's XKB options... we should probably depreciate this usage */ + } else if (!strncasecmp(psi_key, LIBHAL_XKB_PROP_KEY, sizeof(LIBHAL_XKB_PROP_KEY)-1)){ + + /* only support strings for all values */ + tmp_val = get_prop_string(hal_ctx, udi, psi_key); + + if (tmp_val){ + /* add "xkb_" + NULL */ + tmp_key = xalloc(strlen(psi_key) - ( sizeof(LIBHAL_XKB_PROP_KEY) - 1) + 5); + + if (!tmp_key){ + LogMessage(X_ERROR, "config/hal: couldn't allocate memory for option %s\n", psi_key); + } else { + sprintf(tmp_key, "xkb_%s", psi_key + sizeof(LIBHAL_XKB_PROP_KEY)-1); + add_option(&options, tmp_key, tmp_val); + + xfree(tmp_key); + } + xfree(tmp_val); + } + } + } + + /* psi_key doesn't need to be freed */ + libhal_psi_next(&set_iter); + } + + /* this isn't an error, but how else do you output something that the user can see? */ + LogMessage(X_INFO, "config/hal: Adding input device %s\n", name); if (NewInputDeviceRequest(options, &dev) != Success) { - ErrorF("[config/hal] NewInputDeviceRequest failed\n"); + LogMessage(X_ERROR, "config/hal: NewInputDeviceRequest failed\n"); dev = NULL; goto unwind; } - for (; dev; dev = dev->next) + for (; dev; dev = dev->next){ + if (dev->config_info) + xfree(dev->config_info); dev->config_info = xstrdup(config_info); + } unwind: + if (set) + libhal_free_property_set(set); if (path) xfree(path); if (driver) xfree(driver); if (name) xfree(name); - if (xkb_rules) - xfree(xkb_rules); - if (xkb_model) - xfree(xkb_model); - if (xkb_layout) - xfree(xkb_layout); - if (xkb_variant) - xfree(xkb_variant); - if (xkb_options) - xfree(xkb_options); if (config_info) xfree(config_info); while (!dev && (tmpo = options)) { @@ -270,7 +304,6 @@ unwind: xfree(tmpo); } -out_error: dbus_error_free(&error); return; @@ -286,7 +319,7 @@ disconnect_hook(void *data) if (dbus_connection_get_is_connected(info->system_bus)) { dbus_error_init(&error); if (!libhal_ctx_shutdown(info->hal_ctx, &error)) - DebugF("[config/hal] couldn't shut down context: %s (%s)\n", + LogMessage(X_WARNING, "config/hal: disconnect_hook couldn't shut down context: %s (%s)\n", error.name, error.message); dbus_error_free(&error); } @@ -312,21 +345,21 @@ connect_hook(DBusConnection *connection, void *data) if (!info->hal_ctx) info->hal_ctx = libhal_ctx_new(); if (!info->hal_ctx) { - ErrorF("[config/hal] couldn't create HAL context\n"); + LogMessage(X_ERROR, "config/hal: couldn't create HAL context\n"); goto out_err; } if (!libhal_ctx_set_dbus_connection(info->hal_ctx, info->system_bus)) { - ErrorF("[config/hal] couldn't associate HAL context with bus\n"); + LogMessage(X_ERROR, "config/hal: couldn't associate HAL context with bus\n"); goto out_ctx; } if (!libhal_ctx_init(info->hal_ctx, &error)) { - ErrorF("[config/hal] couldn't initialise context: %s (%s)\n", + LogMessage(X_ERROR, "config/hal: couldn't initialise context: %s (%s)\n", error.name, error.message); goto out_ctx; } if (!libhal_device_property_watch_all(info->hal_ctx, &error)) { - ErrorF("[config/hal] couldn't watch all properties: %s (%s)\n", + LogMessage(X_ERROR, "config/hal: couldn't watch all properties: %s (%s)\n", error.name, error.message); goto out_ctx2; } @@ -346,7 +379,7 @@ connect_hook(DBusConnection *connection, void *data) out_ctx2: if (!libhal_ctx_shutdown(info->hal_ctx, &error)) - DebugF("[config/hal] couldn't shut down context: %s (%s)\n", + LogMessage(X_WARNING, "config/hal: couldn't shut down context: %s (%s)\n", error.name, error.message); out_ctx: libhal_ctx_free(info->hal_ctx); @@ -374,10 +407,13 @@ config_hal_init(void) hal_info.hal_ctx = NULL; if (!config_dbus_core_add_hook(&hook)) { - ErrorF("[config/hal] failed to add D-Bus hook\n"); + LogMessage(X_ERROR, "config/hal: failed to add D-Bus hook\n"); return 0; } + /* verbose message */ + LogMessageVerb(X_INFO,7,"config/hal: initialized"); + return 1; } diff --git a/config/x11-input.fdi b/config/x11-input.fdi index c390706fb..f2e2d50ab 100644 --- a/config/x11-input.fdi +++ b/config/x11-input.fdi @@ -1,7 +1,57 @@ - + + + mouse - base + base keyboard - pc105 + pc105 evdev - evdev + evdev - us + us - + diff --git a/configure.ac b/configure.ac index 3b007051c..959f0aedf 100644 --- a/configure.ac +++ b/configure.ac @@ -1009,6 +1009,8 @@ XKB_STUB_LIB='$(top_builddir)/xkb/libxkbstubs.la' AC_CHECK_FUNC(strcasecmp, [], AC_DEFINE([NEED_STRCASECMP], 1, [Do not have 'strcasecmp'.])) +AC_CHECK_FUNC(strncasecmp, [], AC_DEFINE([NEED_STRNCASECMP], 1, + [Do not have 'strncasecmp'.])) if test "x$NULL_ROOT_CURSOR" = xyes; then AC_DEFINE(NULL_ROOT_CURSOR, 1, [Use an empty root cursor]) From 333e7123dc484888d79c0f5aa3977bd72f1eb341 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Tue, 25 Mar 2008 12:48:22 -0400 Subject: [PATCH 101/149] Fix that last commit. I can apply patches, really. --- dix/getevents.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dix/getevents.c b/dix/getevents.c index 6a2f7baf6..bf9331eae 100644 --- a/dix/getevents.c +++ b/dix/getevents.c @@ -349,7 +349,7 @@ getValuatorEvents(xEvent *events, DeviceIntPtr pDev, int first_valuator, for (i = first_valuator; i < final_valuator; i += 6, xv++, events++) { xv->type = DeviceValuator; xv->first_valuator = i; - xv->num_valuators = ((num_valuators - i) > 6) ? 6 : (final_valuator - i); + xv->num_valuators = ((final_valuator - i) > 6) ? 6 : (final_valuator - i); xv->deviceid = pDev->id; switch (final_valuator - i) { case 6: From c747030a49dd289e873e2b686cd129d840e55468 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Thu, 27 Mar 2008 15:18:39 +1000 Subject: [PATCH 102/149] quirk: fix LPL monitors properly. no point having a h cm fix when we really want to copy the sizes from the other place. RH BZ 435216 --- hw/xfree86/modes/xf86EdidModes.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/hw/xfree86/modes/xf86EdidModes.c b/hw/xfree86/modes/xf86EdidModes.c index 2d1a6abd2..777bb70c7 100644 --- a/hw/xfree86/modes/xf86EdidModes.c +++ b/hw/xfree86/modes/xf86EdidModes.c @@ -108,13 +108,6 @@ static Bool quirk_prefer_large_75 (int scrnIndex, xf86MonPtr DDC) static Bool quirk_detailed_h_in_cm (int scrnIndex, xf86MonPtr DDC) { - /* Bug #10304: "LGPhilipsLCD LP154W01-A5" */ - /* Bug #12784: "LGPhilipsLCD LP154W01-TLA2" */ - /* Red Hat #435216 "LGPhilipsLCD LP154W01-TLAE" */ - if (memcmp (DDC->vendor.name, "LPL", 4) == 0 && - (DDC->vendor.prod_id == 0 || DDC->vendor.prod_id == 0x2a00)) - return TRUE; - /* Bug #11603: Funai Electronics PM36B */ if (memcmp (DDC->vendor.name, "FCM", 4) == 0 && DDC->vendor.prod_id == 13600) @@ -137,7 +130,7 @@ static Bool quirk_detailed_use_maximum_size (int scrnIndex, xf86MonPtr DDC) { /* Bug #10304: LGPhilipsLCD LP154W01-A5 */ if (memcmp (DDC->vendor.name, "LPL", 4) == 0 && - DDC->vendor.prod_id == 0) + (DDC->vendor.prod_id == 0 || DDC->vendor.prod_id == 0x2a00)) return TRUE; return FALSE; From c4a616a741e15865ce0ff98781c6f1dca4d62887 Mon Sep 17 00:00:00 2001 From: Ben Byer Date: Mon, 24 Mar 2008 22:43:10 -0700 Subject: [PATCH 103/149] prevent "fake mouse clicks" from generating spurious extra events (cherry picked from commit bd85a24969427e41389688663ead2d4dd41c9999) --- hw/xquartz/darwinEvents.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/hw/xquartz/darwinEvents.c b/hw/xquartz/darwinEvents.c index 827fd81b8..22d895795 100644 --- a/hw/xquartz/darwinEvents.c +++ b/hw/xquartz/darwinEvents.c @@ -391,10 +391,12 @@ void DarwinSendPointerEvents(int ev_type, int ev_button, int pointer_x, int poin DarwinSimulateMouseClick(pointer_x, pointer_y, 2, darwinFakeMouse2Mask); darwinFakeMouseButtonDown = 2; darwinFakeMouseButtonMask = darwinFakeMouse2Mask; + return; } else if ((old_flags & darwinFakeMouse3Mask) == darwinFakeMouse3Mask) { DarwinSimulateMouseClick(pointer_x, pointer_y, 3, darwinFakeMouse3Mask); darwinFakeMouseButtonDown = 3; darwinFakeMouseButtonMask = darwinFakeMouse3Mask; + return; } } if (ev_type == ButtonRelease && darwinFakeButtons && darwinFakeMouseButtonDown) { @@ -406,6 +408,7 @@ void DarwinSendPointerEvents(int ev_type, int ev_button, int pointer_x, int poin // Bring modifiers back up to date DarwinUpdateModifiers(KeyPress, darwinFakeMouseButtonMask & old_flags); darwinFakeMouseButtonMask = 0; + return; } num_events = GetPointerEvents(darwinEvents, darwinPointer, ev_type, ev_button, From c1d37efe9aae5f2895b3437418f7e4bb2eb3400f Mon Sep 17 00:00:00 2001 From: Ben Byer Date: Tue, 25 Mar 2008 19:25:00 -0700 Subject: [PATCH 104/149] xquartz: copy in new stubs from Xi/stubs.c to replace our old Xinput stubs. Hey, it's a start. (cherry picked from commit 566412b4aece24ae6af8c7c835986b685aa456a2) --- hw/xquartz/darwinXinput.c | 186 ++++++++++++-------------------------- 1 file changed, 59 insertions(+), 127 deletions(-) diff --git a/hw/xquartz/darwinXinput.c b/hw/xquartz/darwinXinput.c index e62ec0ab6..50ba656f8 100644 --- a/hw/xquartz/darwinXinput.c +++ b/hw/xquartz/darwinXinput.c @@ -1,8 +1,7 @@ - /* - * X server support of the XINPUT extension for Darwin + * X server support of the XINPUT extension for xquartz * - * This is currently a copy of mi/stubs.c, but eventually this + * This is currently a copy of Xi/stubs.c, but eventually this * should include more complete XINPUT support. */ @@ -52,100 +51,17 @@ SOFTWARE. ********************************************************/ +#define NEED_EVENTS #ifdef HAVE_DIX_CONFIG_H #include #endif -#define NEED_EVENTS #include #include #include "inputstr.h" #include #include #include "XIstubs.h" -#include "chgkbd.h" - -/*********************************************************************** - * - * Caller: ProcXChangeKeyboardDevice - * - * This procedure does the implementation-dependent portion of the work - * needed to change the keyboard device. - * - * The X keyboard device has a FocusRec. If the device that has been - * made into the new X keyboard did not have a FocusRec, - * ProcXChangeKeyboardDevice will allocate one for it. - * - * If you do not want clients to be able to focus the old X keyboard - * device, call DeleteFocusClassDeviceStruct to free the FocusRec. - * - * If you support input devices with keys that you do not want to be - * used as the X keyboard, you need to check for them here and return - * a BadDevice error. - * - * The default implementation is to do nothing (assume you do want - * clients to be able to focus the old X keyboard). The commented-out - * sample code shows what you might do if you don't want the default. - * - */ - -int ChangeKeyboardDevice (DeviceIntPtr old_dev, DeviceIntPtr new_dev) { - /*********************************************************************** - DeleteFocusClassDeviceStruct(old_dev); * defined in xchgptr.c * - **********************************************************************/ - return BadMatch; -} - - -/*********************************************************************** - * - * Caller: ProcXChangePointerDevice - * - * This procedure does the implementation-dependent portion of the work - * needed to change the pointer device. - * - * The X pointer device does not have a FocusRec. If the device that - * has been made into the new X pointer had a FocusRec, - * ProcXChangePointerDevice will free it. - * - * If you want clients to be able to focus the old pointer device that - * has now become accessible through the input extension, you need to - * add a FocusRec to it here. - * - * The XChangePointerDevice protocol request also allows the client - * to choose which axes of the new pointer device are used to move - * the X cursor in the X- and Y- directions. If the axes are different - * than the default ones, you need to keep track of that here. - * - * If you support input devices with valuators that you do not want to be - * used as the X pointer, you need to check for them here and return a - * BadDevice error. - * - * The default implementation is to do nothing (assume you don't want - * clients to be able to focus the old X pointer). The commented-out - * sample code shows what you might do if you don't want the default. - * - */ - -int -ChangePointerDevice ( - DeviceIntPtr old_dev, - DeviceIntPtr new_dev, - unsigned char x, - unsigned char y) - { - /*********************************************************************** - InitFocusClassDeviceStruct(old_dev); * allow focusing old ptr* - - x_axis = x; * keep track of new x-axis* - y_axis = y; * keep track of new y-axis* - if (x_axis != 0 || y_axis != 1) - axes_changed = TRUE; * remember axes have changed* - else - axes_changed = FALSE; - *************************************************************************/ - return BadMatch; - } /*********************************************************************** * @@ -161,11 +77,9 @@ ChangePointerDevice ( */ void -CloseInputDevice (d, client) - DeviceIntPtr d; - ClientPtr client; - { - } +CloseInputDevice(DeviceIntPtr d, ClientPtr client) +{ +} /*********************************************************************** * @@ -194,8 +108,8 @@ CloseInputDevice (d, client) */ void -AddOtherInputDevices () - { +AddOtherInputDevices(void) +{ /********************************************************************** for each uninitialized device, do something like: @@ -209,7 +123,7 @@ AddOtherInputDevices () dev->inited = ((*dev->deviceProc)(dev, DEVICE_INIT) == Success); ************************************************************************/ - } +} /*********************************************************************** * @@ -234,12 +148,9 @@ AddOtherInputDevices () */ void -OpenInputDevice (dev, client, status) - DeviceIntPtr dev; - ClientPtr client; - int *status; - { - } +OpenInputDevice(DeviceIntPtr dev, ClientPtr client, int *status) +{ +} /**************************************************************************** * @@ -254,13 +165,10 @@ OpenInputDevice (dev, client, status) */ int -SetDeviceMode (client, dev, mode) - register ClientPtr client; - DeviceIntPtr dev; - int mode; - { +SetDeviceMode(ClientPtr client, DeviceIntPtr dev, int mode) +{ return BadMatch; - } +} /**************************************************************************** * @@ -275,15 +183,11 @@ SetDeviceMode (client, dev, mode) */ int -SetDeviceValuators (client, dev, valuators, first_valuator, num_valuators) - register ClientPtr client; - DeviceIntPtr dev; - int *valuators; - int first_valuator; - int num_valuators; - { +SetDeviceValuators(ClientPtr client, DeviceIntPtr dev, + int *valuators, int first_valuator, int num_valuators) +{ return BadMatch; - } +} /**************************************************************************** * @@ -294,16 +198,44 @@ SetDeviceValuators (client, dev, valuators, first_valuator, num_valuators) */ int -ChangeDeviceControl (client, dev, control) - register ClientPtr client; - DeviceIntPtr dev; - xDeviceCtl *control; - { - switch (control->control) - { - case DEVICE_RESOLUTION: - return (BadMatch); - default: - return (BadMatch); - } +ChangeDeviceControl(ClientPtr client, DeviceIntPtr dev, + xDeviceCtl * control) +{ + switch (control->control) { + case DEVICE_RESOLUTION: + return (BadMatch); + case DEVICE_ABS_CALIB: + case DEVICE_ABS_AREA: + return (BadMatch); + case DEVICE_CORE: + return (BadMatch); + default: + return (BadMatch); } +} + + +/**************************************************************************** + * + * Caller: configAddDevice (and others) + * + * Add a new device with the specified options. + * + */ +int +NewInputDeviceRequest(InputOption *options, DeviceIntPtr *pdev) +{ + return BadValue; +} + +/**************************************************************************** + * + * Caller: configRemoveDevice (and others) + * + * Remove the specified device previously added. + * + */ +void +DeleteInputDeviceRequest(DeviceIntPtr dev) +{ +} From 415e49b940bba2d08870db410ebb47d2add5d836 Mon Sep 17 00:00:00 2001 From: Jeremy Huddleston Date: Tue, 25 Mar 2008 23:01:02 -0700 Subject: [PATCH 105/149] XQuartz: Sanity-check the removal of the 256-color option Fixes the 'one-time-preferences' bug in 2.2.0_rc1 (cherry picked from commit 38cbd13490fc21724e8eef0ec7e1a20a9cc2e39d) --- hw/xquartz/X11Controller.m | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hw/xquartz/X11Controller.m b/hw/xquartz/X11Controller.m index a9d2addbd..dfa2074fd 100644 --- a/hw/xquartz/X11Controller.m +++ b/hw/xquartz/X11Controller.m @@ -649,7 +649,8 @@ objectValueForTableColumn:(NSTableColumn *)tableColumn row:(int)row [depth selectItemAtIndex:[depth indexOfItemWithTag:[NSApp prefs_get_integer:@PREFS_DEPTH default:-1]]]; // TODO: Add 256 color support - [depth removeItemAtIndex:[depth indexOfItemWithTag:8]]; + if([depth indexOfItemWithTag:8] != -1) + [depth removeItemAtIndex:[depth indexOfItemWithTag:8]]; [enable_fullscreen setIntValue:!quartzEnableRootless]; // TODO: Add fullscreen support From b5f98fcea2024c67e598947782913982072cf4fb Mon Sep 17 00:00:00 2001 From: Eamon Walsh Date: Fri, 28 Mar 2008 14:01:34 -0400 Subject: [PATCH 106/149] XSELinux: Add xorg.conf option for permissive/enforcing/disabled. Patch by Joe Nall. The option goes in the "extmod" subsection. TODO: Make it easier for extension modules to handle their own options. --- Xext/xselinux.c | 31 ++++++++++++++++++++++++----- hw/xfree86/dixmods/extmod/modinit.c | 23 ++++++++++++++++++++- hw/xfree86/loader/dixsym.c | 3 +++ include/globals.h | 10 ++++++++++ mi/miinitext.c | 8 +++++++- os/utils.c | 4 ++++ 6 files changed, 72 insertions(+), 7 deletions(-) diff --git a/Xext/xselinux.c b/Xext/xselinux.c index 17ce7af10..2e059a4c3 100644 --- a/Xext/xselinux.c +++ b/Xext/xselinux.c @@ -37,6 +37,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include #include +#include "globals.h" #include "resource.h" #include "privates.h" #include "registry.h" @@ -1891,16 +1892,36 @@ void SELinuxExtensionInit(INITARGS) { ExtensionEntry *extEntry; - struct selinux_opt options[] = { { SELABEL_OPT_VALIDATE, (char *)1 } }; + struct selinux_opt selabel_option = { SELABEL_OPT_VALIDATE, (char *)1 }; + struct selinux_opt avc_option = { AVC_OPT_SETENFORCE, (char *)0 }; security_context_t con; int ret = TRUE; - /* Setup SELinux stuff */ + /* Check SELinux mode on system */ if (!is_selinux_enabled()) { - ErrorF("SELinux: SELinux not enabled, disabling SELinux support.\n"); + ErrorF("SELinux: Disabled on system, not enabling in X server\n"); return; } + /* Check SELinux mode in configuration file */ + switch(selinuxEnforcingState) { + case SELINUX_MODE_DISABLED: + LogMessage(X_INFO, "SELinux: Disabled in configuration file\n"); + return; + case SELINUX_MODE_ENFORCING: + LogMessage(X_INFO, "SELinux: Configured in enforcing mode\n"); + avc_option.value = (char *)1; + break; + case SELINUX_MODE_PERMISSIVE: + LogMessage(X_INFO, "SELinux: Configured in permissive mode\n"); + avc_option.value = (char *)0; + break; + default: + avc_option.type = AVC_OPT_UNUSED; + break; + } + + /* Set up SELinux stuff */ selinux_set_callback(SELINUX_CB_LOG, (union selinux_callback)SELinuxLog); selinux_set_callback(SELINUX_CB_AUDIT, (union selinux_callback)SELinuxAudit); @@ -1912,11 +1933,11 @@ SELinuxExtensionInit(INITARGS) FatalError("SELinux: Failed to set up security class mapping\n"); } - if (avc_open(NULL, 0) < 0) + if (avc_open(&avc_option, 1) < 0) FatalError("SELinux: Couldn't initialize SELinux userspace AVC\n"); avc_active = 1; - label_hnd = selabel_open(SELABEL_CTX_X, options, 1); + label_hnd = selabel_open(SELABEL_CTX_X, &selabel_option, 1); if (!label_hnd) FatalError("SELinux: Failed to open x_contexts mapping in policy\n"); diff --git a/hw/xfree86/dixmods/extmod/modinit.c b/hw/xfree86/dixmods/extmod/modinit.c index d0d892aaf..8c8a4ceeb 100644 --- a/hw/xfree86/dixmods/extmod/modinit.c +++ b/hw/xfree86/dixmods/extmod/modinit.c @@ -42,7 +42,7 @@ static ExtensionModule extensionModules[] = { { SELinuxExtensionInit, SELINUX_EXTENSION_NAME, - NULL, + &noSELinuxExtension, NULL, NULL }, @@ -258,6 +258,27 @@ extmodSetup(pointer module, pointer opts, int *errmaj, int *errmin) } } } + +#ifdef XSELINUX + if (! strcmp(SELINUX_EXTENSION_NAME, extensionModules[i].name)) { + pointer o; + selinuxEnforcingState = SELINUX_MODE_DEFAULT; + + if ((o = xf86FindOption(opts, "SELinux mode disabled"))) { + xf86MarkOptionUsed(o); + selinuxEnforcingState = SELINUX_MODE_DISABLED; + } + if ((o = xf86FindOption(opts, "SELinux mode permissive"))) { + xf86MarkOptionUsed(o); + selinuxEnforcingState = SELINUX_MODE_PERMISSIVE; + } + if ((o = xf86FindOption(opts, "SELinux mode enforcing"))) { + xf86MarkOptionUsed(o); + selinuxEnforcingState = SELINUX_MODE_ENFORCING; + } + } +#endif + LoadExtension(&extensionModules[i], FALSE); } /* Need a non-NULL return */ diff --git a/hw/xfree86/loader/dixsym.c b/hw/xfree86/loader/dixsym.c index d035c762f..d6d22c4b9 100644 --- a/hw/xfree86/loader/dixsym.c +++ b/hw/xfree86/loader/dixsym.c @@ -440,6 +440,9 @@ _X_HIDDEN void *dixLookupTab[] = { #ifdef XIDLE SYMVAR(noXIdleExtension) #endif +#ifdef XSELINUX + SYMVAR(noSELinuxExtension) +#endif #ifdef XV SYMVAR(noXvExtension) #endif diff --git a/include/globals.h b/include/globals.h index b230dfc37..2ca9531d9 100644 --- a/include/globals.h +++ b/include/globals.h @@ -175,6 +175,16 @@ extern Bool noXInputExtension; extern Bool noXIdleExtension; #endif +#ifdef XSELINUX +extern Bool noSELinuxExtension; + +#define SELINUX_MODE_DEFAULT 0 +#define SELINUX_MODE_DISABLED 1 +#define SELINUX_MODE_PERMISSIVE 2 +#define SELINUX_MODE_ENFORCING 3 +extern int selinuxEnforcingState; +#endif + #ifdef XV extern Bool noXvExtension; #endif diff --git a/mi/miinitext.c b/mi/miinitext.c index 3c55eebb3..cc4c15c9d 100644 --- a/mi/miinitext.c +++ b/mi/miinitext.c @@ -215,6 +215,9 @@ extern Bool noXInputExtension; #ifdef XIDLE extern Bool noXIdleExtension; #endif +#ifdef XSELINUX +extern Bool noSELinuxExtension; +#endif #ifdef XV extern Bool noXvExtension; #endif @@ -487,6 +490,9 @@ static ExtensionToggle ExtensionToggleList[] = #endif #ifdef XKB { "XKEYBOARD", &noXkbExtension }, +#endif +#ifdef XSELINUX + { "SELinux", &noSELinuxExtension }, #endif { "XTEST", &noTestExtensions }, #ifdef XV @@ -597,7 +603,7 @@ InitExtensions(argc, argv) if (!noSecurityExtension) SecurityExtensionInit(); #endif #ifdef XSELINUX - SELinuxExtensionInit(); + if (!noSELinuxExtension) SELinuxExtensionInit(); #endif #ifdef XPRINT XpExtensionInit(); /* server-specific extension, cannot be disabled */ diff --git a/os/utils.c b/os/utils.c index 4041028a3..57293ab6f 100644 --- a/os/utils.c +++ b/os/utils.c @@ -232,6 +232,10 @@ _X_EXPORT Bool noXInputExtension = FALSE; #ifdef XIDLE _X_EXPORT Bool noXIdleExtension = FALSE; #endif +#ifdef XSELINUX +_X_EXPORT Bool noSELinuxExtension = FALSE; +_X_EXPORT int selinuxEnforcingState = SELINUX_MODE_DEFAULT; +#endif #ifdef XV _X_EXPORT Bool noXvExtension = FALSE; #endif From 88ece11d6c45c6f4b94f7fb2da64a46e879d7c27 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Mon, 3 Dec 2007 15:47:39 -0500 Subject: [PATCH 107/149] Start E-EDID support in the DDC module. Since there's no way to safely know how many blocks xf86DoEDID_DDC2 would return, add a new xf86DoEEDID entrypoint to do that, and implement the one in terms of the other. --- hw/xfree86/ddc/xf86DDC.c | 110 ++++++++++++++++++++++----------------- hw/xfree86/ddc/xf86DDC.h | 2 + 2 files changed, 65 insertions(+), 47 deletions(-) diff --git a/hw/xfree86/ddc/xf86DDC.c b/hw/xfree86/ddc/xf86DDC.c index 28e2ead28..98f60061e 100644 --- a/hw/xfree86/ddc/xf86DDC.c +++ b/hw/xfree86/ddc/xf86DDC.c @@ -2,6 +2,14 @@ * * Copyright 1998,1999 by Egbert Eich */ + +/* + * Note that DDC1 does not define any method for returning blocks beyond + * the first. DDC2 does, but the original implementation would only ever + * read the first block. If you want to read and parse all blocks, use + * xf86DoEEDID(). + */ + #ifdef HAVE_XORG_CONFIG_H #include #endif @@ -31,11 +39,6 @@ static unsigned int *FetchEDID_DDC1( register unsigned int (*)(ScrnInfoPtr) ); -static unsigned char* EDID1Read_DDC2( - int scrnIndex, - I2CBusPtr pBus -); - static unsigned char * DDCRead_DDC2( int scrnIndex, I2CBusPtr pBus, @@ -107,6 +110,59 @@ xf86DoEDID_DDC1( return tmp; } +/** + * Attempts to probe the monitor for EDID information, if NoDDC and NoDDC2 are + * unset. EDID information blocks are interpreted and the results returned in + * an xf86MonPtr. Unlike xf86DoEDID_DDC[12](), this function will return + * the complete EDID data, including all extension blocks. + * + * This function does not affect the list of modes used by drivers -- it is up + * to the driver to decide policy on what to do with EDID information. + * + * @return pointer to a new xf86MonPtr containing the EDID information. + * @return NULL if no monitor attached or failure to interpret the EDID. + * + * nblocks is an in/out parameter. If non-zero, it defines the number of + * blocks to read from the monitor; zero (or NULL pointer) means read all. + * If non-NULL, on return it will be filled in with the number of blocks + * read. + */ +xf86MonPtr +xf86DoEEDID(int scrnIndex, I2CBusPtr pBus, int *nblocks) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + unsigned char *EDID_block = NULL; + xf86MonPtr tmp = NULL; + /* Default DDC and DDC2 to enabled. */ + Bool noddc = FALSE, noddc2 = FALSE; + OptionInfoPtr options; + + options = xnfalloc(sizeof(DDCOptions)); + memcpy(options, DDCOptions, sizeof(DDCOptions)); + xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, options); + + xf86GetOptValBool(options, DDCOPT_NODDC, &noddc); + xf86GetOptValBool(options, DDCOPT_NODDC2, &noddc2); + xfree(options); + + if (noddc || noddc2) + return NULL; + + EDID_block = DDCRead_DDC2(scrnIndex, pBus, 0, EDID1_LEN); + + if (EDID_block) + tmp = xf86InterpretEDID(scrnIndex, EDID_block); + + if (nblocks) { + if (tmp) + *nblocks = tmp->no_sections; + else + *nblocks = 0; + } + + return tmp; +} + /** * Attempts to probe the monitor for EDID information, if NoDDC and NoDDC2 are * unset. EDID information blocks are interpreted and the results returned in @@ -121,42 +177,8 @@ xf86DoEDID_DDC1( xf86MonPtr xf86DoEDID_DDC2(int scrnIndex, I2CBusPtr pBus) { - ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; - unsigned char *EDID_block = NULL; - xf86MonPtr tmp = NULL; - /* Default DDC and DDC2 to enabled. */ - Bool noddc = FALSE, noddc2 = FALSE; - OptionInfoPtr options; - - options = xnfalloc(sizeof(DDCOptions)); - (void)memcpy(options, DDCOptions, sizeof(DDCOptions)); - xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, options); - - xf86GetOptValBool(options, DDCOPT_NODDC, &noddc); - xf86GetOptValBool(options, DDCOPT_NODDC2, &noddc2); - xfree(options); - - if (noddc || noddc2) - return NULL; - - EDID_block = EDID1Read_DDC2(scrnIndex,pBus); - - if (EDID_block){ - tmp = xf86InterpretEDID(scrnIndex,EDID_block); - } else { -#ifdef DEBUG - ErrorF("No EDID block returned\n"); -#endif - return NULL; - } -#ifdef DEBUG - if (!tmp) - ErrorF("Cannot interpret EDID block\n"); - else - ErrorF("Sections to follow: %i\n",tmp->no_sections); -#endif - - return tmp; + int nblocks = 1; + return xf86DoEEDID(scrnIndex, pBus, &nblocks); } /* @@ -226,12 +248,6 @@ FetchEDID_DDC1(register ScrnInfoPtr pScrn, return (ptr); } -static unsigned char* -EDID1Read_DDC2(int scrnIndex, I2CBusPtr pBus) -{ - return DDCRead_DDC2(scrnIndex, pBus, 0, EDID1_LEN); -} - static unsigned char * DDCRead_DDC2(int scrnIndex, I2CBusPtr pBus, int start, int len) { diff --git a/hw/xfree86/ddc/xf86DDC.h b/hw/xfree86/ddc/xf86DDC.h index 3b072dda7..6e5bf6f7a 100644 --- a/hw/xfree86/ddc/xf86DDC.h +++ b/hw/xfree86/ddc/xf86DDC.h @@ -35,6 +35,8 @@ extern xf86MonPtr xf86DoEDID_DDC2( I2CBusPtr pBus ); +extern xf86MonPtr xf86DoEEDID(int scrnIndex, I2CBusPtr pBus, int *nblocks); + extern xf86MonPtr xf86PrintEDID( xf86MonPtr monPtr ); From 0b4aef4d6df7a5525d381de035fbbf78c5fffeef Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Mon, 3 Dec 2007 16:00:00 -0500 Subject: [PATCH 108/149] Refactor DDC2 code to allow for proper segmented addressing. --- hw/xfree86/ddc/xf86DDC.c | 132 +++++++++++++++++++-------------------- 1 file changed, 64 insertions(+), 68 deletions(-) diff --git a/hw/xfree86/ddc/xf86DDC.c b/hw/xfree86/ddc/xf86DDC.c index 98f60061e..3e51c4e17 100644 --- a/hw/xfree86/ddc/xf86DDC.c +++ b/hw/xfree86/ddc/xf86DDC.c @@ -39,13 +39,6 @@ static unsigned int *FetchEDID_DDC1( register unsigned int (*)(ScrnInfoPtr) ); -static unsigned char * DDCRead_DDC2( - int scrnIndex, - I2CBusPtr pBus, - int start, - int len -); - typedef enum { DDCOPT_NODDC1, DDCOPT_NODDC2, @@ -110,6 +103,64 @@ xf86DoEDID_DDC1( return tmp; } +static I2CDevPtr +DDC2Init(int scrnIndex, I2CBusPtr pBus) +{ + I2CDevPtr dev = NULL; + /* + * Slow down the bus so that older monitors don't + * miss things. + */ + pBus->RiseFallTime = 20; + + if (!(dev = xf86I2CFindDev(pBus, 0x00A0))) { + dev = xf86CreateI2CDevRec(); + dev->DevName = "ddc2"; + dev->SlaveAddr = 0xA0; + dev->ByteTimeout = 2200; /* VESA DDC spec 3 p. 43 (+10 %) */ + dev->StartTimeout = 550; + dev->BitTimeout = 40; + dev->AcknTimeout = 40; + + dev->pI2CBus = pBus; + if (!xf86I2CDevInit(dev)) { + xf86DrvMsg(scrnIndex, X_PROBED, "No DDC2 device\n"); + return NULL; + } + } + + return dev; +} + +static unsigned char * +DDC2Read(I2CDevPtr dev, int start, int len) +{ + unsigned char W_Buffer[2]; + int w_bytes; + unsigned char *R_Buffer; + int i; + + if (start < 0x100) { + w_bytes = 1; + W_Buffer[0] = start; + } else { + w_bytes = 2; + W_Buffer[0] = start & 0xFF; + W_Buffer[1] = (start & 0xFF00) >> 8; + } + + R_Buffer = xcalloc(sizeof(unsigned char), len); + for (i = 0; i < RETRIES; i++) { + if (xf86I2CWriteRead(dev, W_Buffer, w_bytes, R_Buffer, len)) { + if (!DDC_checksum(R_Buffer, len)) + return R_Buffer; + } + } + + xfree(R_Buffer); + return NULL; +} + /** * Attempts to probe the monitor for EDID information, if NoDDC and NoDDC2 are * unset. EDID information blocks are interpreted and the results returned in @@ -133,6 +184,7 @@ xf86DoEEDID(int scrnIndex, I2CBusPtr pBus, int *nblocks) ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; unsigned char *EDID_block = NULL; xf86MonPtr tmp = NULL; + I2CDevPtr dev = NULL; /* Default DDC and DDC2 to enabled. */ Bool noddc = FALSE, noddc2 = FALSE; OptionInfoPtr options; @@ -144,11 +196,14 @@ xf86DoEEDID(int scrnIndex, I2CBusPtr pBus, int *nblocks) xf86GetOptValBool(options, DDCOPT_NODDC, &noddc); xf86GetOptValBool(options, DDCOPT_NODDC2, &noddc2); xfree(options); - + if (noddc || noddc2) return NULL; - EDID_block = DDCRead_DDC2(scrnIndex, pBus, 0, EDID1_LEN); + if (!(dev = DDC2Init(scrnIndex, pBus))) + return NULL; + + EDID_block = DDC2Read(dev, 0, EDID1_LEN); if (EDID_block) tmp = xf86InterpretEDID(scrnIndex, EDID_block); @@ -247,62 +302,3 @@ FetchEDID_DDC1(register ScrnInfoPtr pScrn, } while(--count); return (ptr); } - -static unsigned char * -DDCRead_DDC2(int scrnIndex, I2CBusPtr pBus, int start, int len) -{ - I2CDevPtr dev; - unsigned char W_Buffer[2]; - int w_bytes; - unsigned char *R_Buffer; - int i; - - /* - * Slow down the bus so that older monitors don't - * miss things. - */ - pBus->RiseFallTime = 20; - - if (!(dev = xf86I2CFindDev(pBus, 0x00A0))) { - dev = xf86CreateI2CDevRec(); - dev->DevName = "ddc2"; - dev->SlaveAddr = 0xA0; - dev->ByteTimeout = 2200; /* VESA DDC spec 3 p. 43 (+10 %) */ - dev->StartTimeout = 550; - dev->BitTimeout = 40; - dev->AcknTimeout = 40; - - dev->pI2CBus = pBus; - if (!xf86I2CDevInit(dev)) { - xf86DrvMsg(scrnIndex, X_PROBED, "No DDC2 device\n"); - return NULL; - } - } - if (start < 0x100) { - w_bytes = 1; - W_Buffer[0] = start; - } else { - w_bytes = 2; - W_Buffer[0] = start & 0xFF; - W_Buffer[1] = (start & 0xFF00) >> 8; - } - R_Buffer = xcalloc(1,sizeof(unsigned char) - * (len)); - for (i=0; i Date: Mon, 3 Dec 2007 17:38:53 -0500 Subject: [PATCH 109/149] Add E-EDID segment selection. --- hw/xfree86/ddc/xf86DDC.c | 105 ++++++++++++++++++++++++++------------- 1 file changed, 71 insertions(+), 34 deletions(-) diff --git a/hw/xfree86/ddc/xf86DDC.c b/hw/xfree86/ddc/xf86DDC.c index 3e51c4e17..7e267227f 100644 --- a/hw/xfree86/ddc/xf86DDC.c +++ b/hw/xfree86/ddc/xf86DDC.c @@ -104,19 +104,14 @@ xf86DoEDID_DDC1( } static I2CDevPtr -DDC2Init(int scrnIndex, I2CBusPtr pBus) +DDC2MakeDevice(I2CBusPtr pBus, int address, char *name) { I2CDevPtr dev = NULL; - /* - * Slow down the bus so that older monitors don't - * miss things. - */ - pBus->RiseFallTime = 20; - - if (!(dev = xf86I2CFindDev(pBus, 0x00A0))) { + + if (!(dev = xf86I2CFindDev(pBus, address))) { dev = xf86CreateI2CDevRec(); - dev->DevName = "ddc2"; - dev->SlaveAddr = 0xA0; + dev->DevName = name; + dev->SlaveAddr = address; dev->ByteTimeout = 2200; /* VESA DDC spec 3 p. 43 (+10 %) */ dev->StartTimeout = 550; dev->BitTimeout = 40; @@ -132,33 +127,70 @@ DDC2Init(int scrnIndex, I2CBusPtr pBus) return dev; } -static unsigned char * -DDC2Read(I2CDevPtr dev, int start, int len) +static I2CDevPtr +DDC2Init(int scrnIndex, I2CBusPtr pBus) { - unsigned char W_Buffer[2]; - int w_bytes; - unsigned char *R_Buffer; - int i; - - if (start < 0x100) { - w_bytes = 1; - W_Buffer[0] = start; - } else { - w_bytes = 2; - W_Buffer[0] = start & 0xFF; - W_Buffer[1] = (start & 0xFF00) >> 8; - } + I2CDevPtr dev = NULL; + + /* + * Slow down the bus so that older monitors don't + * miss things. + */ + pBus->RiseFallTime = 20; + + DDC2MakeDevice(pBus, 0x0060, "E-EDID segment register"); + dev = DDC2MakeDevice(pBus, 0x00A0, "ddc2"); + + return dev; +} + +/* Mmmm, smell the hacks */ +static void +EEDIDStop(I2CDevPtr d) +{ +} + +/* block is the EDID block number. a segment is two blocks. */ +static Bool +DDC2Read(I2CDevPtr dev, int block, unsigned char *R_Buffer) +{ + unsigned char W_Buffer[1]; + int i, segment; + I2CDevPtr seg; + void (*stop)(I2CDevPtr); - R_Buffer = xcalloc(sizeof(unsigned char), len); for (i = 0; i < RETRIES; i++) { - if (xf86I2CWriteRead(dev, W_Buffer, w_bytes, R_Buffer, len)) { - if (!DDC_checksum(R_Buffer, len)) - return R_Buffer; + /* Stop bits reset the segment pointer to 0, so be careful here. */ + segment = block >> 1; + if (segment) { + Bool b; + + if (!(seg = xf86I2CFindDev(dev->pI2CBus, 0x0060))) + return FALSE; + + W_Buffer[0] = segment; + + stop = dev->pI2CBus->I2CStop; + dev->pI2CBus->I2CStop = EEDIDStop; + + b = xf86I2CWriteRead(seg, W_Buffer, 1, NULL, 0); + + dev->pI2CBus->I2CStop = stop; + if (!b) { + dev->pI2CBus->I2CStop(dev); + continue; + } + } + + W_Buffer[0] = (block & 0x01) * EDID1_LEN; + + if (xf86I2CWriteRead(dev, W_Buffer, 1, R_Buffer, EDID1_LEN)) { + if (!DDC_checksum(R_Buffer, EDID1_LEN)) + return TRUE; } } - xfree(R_Buffer); - return NULL; + return FALSE; } /** @@ -189,7 +221,9 @@ xf86DoEEDID(int scrnIndex, I2CBusPtr pBus, int *nblocks) Bool noddc = FALSE, noddc2 = FALSE; OptionInfoPtr options; - options = xnfalloc(sizeof(DDCOptions)); + options = xalloc(sizeof(DDCOptions)); + if (!options) + return NULL; memcpy(options, DDCOptions, sizeof(DDCOptions)); xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, options); @@ -203,10 +237,13 @@ xf86DoEEDID(int scrnIndex, I2CBusPtr pBus, int *nblocks) if (!(dev = DDC2Init(scrnIndex, pBus))) return NULL; - EDID_block = DDC2Read(dev, 0, EDID1_LEN); + EDID_block = xcalloc(1, EDID1_LEN); + if (!EDID_block) + return NULL; - if (EDID_block) + if (DDC2Read(dev, 0, EDID_block)) { tmp = xf86InterpretEDID(scrnIndex, EDID_block); + } if (nblocks) { if (tmp) From 933ffcdf7d2eaaf7caabfe6f861f04bcb149918f Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Fri, 28 Mar 2008 17:53:55 -0400 Subject: [PATCH 110/149] Compile fix. --- hw/xfree86/ddc/xf86DDC.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/xfree86/ddc/xf86DDC.c b/hw/xfree86/ddc/xf86DDC.c index 7e267227f..8dda35ac4 100644 --- a/hw/xfree86/ddc/xf86DDC.c +++ b/hw/xfree86/ddc/xf86DDC.c @@ -119,7 +119,7 @@ DDC2MakeDevice(I2CBusPtr pBus, int address, char *name) dev->pI2CBus = pBus; if (!xf86I2CDevInit(dev)) { - xf86DrvMsg(scrnIndex, X_PROBED, "No DDC2 device\n"); + xf86DrvMsg(pBus->scrnIndex, X_PROBED, "No DDC2 device\n"); return NULL; } } From bd28839eb866a9e6dc3ff80f13a67611da7eaf64 Mon Sep 17 00:00:00 2001 From: Jeremy Huddleston Date: Fri, 28 Mar 2008 17:02:02 -0700 Subject: [PATCH 111/149] =?UTF-8?q?=3D=3Futf-8=3Fq=3FXQuartz:=3D20Another?= =?UTF-8?q?=3D20Expos=3DC3=3DA9=3D20fix:=3D20F9=3D20doesn't=3D20raise=3D20?= =?UTF-8?q?all=3D20windows?= =20(cherry=20picked=20from=20commit=20b9cffa20debae73737c674bf75ab65db1bd74556)?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit --- hw/xquartz/X11Application.m | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/hw/xquartz/X11Application.m b/hw/xquartz/X11Application.m index b7c876365..e1581af90 100644 --- a/hw/xquartz/X11Application.m +++ b/hw/xquartz/X11Application.m @@ -314,14 +314,10 @@ static void message_kit_thread (SEL selector, NSObject *arg) { } - (void) set_front_process:unused { - /* Hackery needed due to argv[0] hackery */ - // [self activateX:YES]; - ProcessSerialNumber psn = { 0, kCurrentProcess }; - SetFrontProcess(&psn); + [NSApp activateIgnoringOtherApps:YES]; - QuartzMessageServerThread(kXDarwinBringAllToFront, 0); - ProcessSerialNumber psn = { 0, kCurrentProcess }; - SetFrontProcess(&psn); + if ([self modalWindow] == nil) + [self activateX:YES]; } - (void) set_can_quit:(NSNumber *)state { From b8ea9f2a25aad88aee77a68f8e20ac07276f0dab Mon Sep 17 00:00:00 2001 From: Jeremy Huddleston Date: Fri, 28 Mar 2008 17:00:08 -0700 Subject: [PATCH 112/149] XQuartz: Fixed names of enums to be more consistent (cherry picked from commit c309a08806daf5d716a860c709e51eacad2c745a) --- hw/xquartz/X11Application.m | 10 +++---- hw/xquartz/X11Controller.m | 30 ++++++++++---------- hw/xquartz/darwin.c | 4 +-- hw/xquartz/darwin.h | 36 ++++++++++++------------ hw/xquartz/darwinEvents.c | 18 ++++++------ hw/xquartz/quartz.c | 56 ++++++++++++++++++------------------- hw/xquartz/quartzKeyboard.h | 2 +- hw/xquartz/xpr/xprScreen.c | 8 +++--- 8 files changed, 82 insertions(+), 82 deletions(-) diff --git a/hw/xquartz/X11Application.m b/hw/xquartz/X11Application.m index e1581af90..31c80dfa8 100644 --- a/hw/xquartz/X11Application.m +++ b/hw/xquartz/X11Application.m @@ -153,7 +153,7 @@ static void message_kit_thread (SEL selector, NSObject *arg) { tem = [infoDict objectForKey:@"CFBundleShortVersionString"]; - [dict setObject:[NSString stringWithFormat:@"XQuartz %@ - (xorg-server %s)", tem, XSERVER_VERSION] + [dict setObject:[NSString stringWithFormat:@"Xquartz %@ - (xorg-server %s)", tem, XSERVER_VERSION] forKey:@"ApplicationVersion"]; [self orderFrontStandardAboutPanelWithOptions: dict]; @@ -166,7 +166,7 @@ static void message_kit_thread (SEL selector, NSObject *arg) { static TSMDocumentID x11_document; DEBUG_LOG("state=%d, _x_active=%d, \n", state, _x_active) if (state) { - QuartzMessageServerThread (kXDarwinActivate, 0); + QuartzMessageServerThread (kXquartzActivate, 0); if (!_x_active) { if (x11_document == 0 && darwinKeymapFile == NULL) { @@ -178,7 +178,7 @@ static void message_kit_thread (SEL selector, NSObject *arg) { if (x11_document != 0) ActivateTSMDocument (x11_document); } } else { - QuartzMessageServerThread (kXDarwinDeactivate, 0); + QuartzMessageServerThread (kXquartzDeactivate, 0); if (_x_active && x11_document != 0) DeactivateTSMDocument (x11_document); @@ -246,7 +246,7 @@ static void message_kit_thread (SEL selector, NSObject *arg) { swallow_up = 0; for_x = NO; #ifdef DARWIN_DDX_MISSING - QuartzMessageServerThread (kXDarwinToggleFullscreen, 0); + QuartzMessageServerThread (kXquartzToggleFullscreen, 0); #endif } } else { @@ -654,7 +654,7 @@ static NSMutableArray * cfarray_to_nsarray (CFArrayRef in) { /* This will end up at the end of the responder chain. */ - (void) copy:sender { - QuartzMessageServerThread (kXDarwinPasteboardNotify, 1, + QuartzMessageServerThread (kXquartzPasteboardNotify, 1, AppleWMCopyToPasteboard); } diff --git a/hw/xquartz/X11Controller.m b/hw/xquartz/X11Controller.m index dfa2074fd..aa9fa94be 100644 --- a/hw/xquartz/X11Controller.m +++ b/hw/xquartz/X11Controller.m @@ -103,7 +103,7 @@ { [NSApp activateIgnoringOtherApps:YES]; - QuartzMessageServerThread (kXDarwinControllerNotify, 2, + QuartzMessageServerThread (kXquartzControllerNotify, 2, AppleWMWindowMenuItem, [sender tag]); } @@ -254,7 +254,7 @@ [self remove_window_menu]; [self install_window_menu:list]; - QuartzMessageServerThread (kXDarwinControllerNotify, 1, + QuartzMessageServerThread (kXquartzControllerNotify, 1, AppleWMWindowMenuNotify); } @@ -539,20 +539,20 @@ objectValueForTableColumn:(NSTableColumn *)tableColumn row:(int)row - (void) hide_window:sender { if ([X11App x_active]) - QuartzMessageServerThread (kXDarwinControllerNotify, 1, AppleWMHideWindow); + QuartzMessageServerThread (kXquartzControllerNotify, 1, AppleWMHideWindow); else NSBeep (); /* FIXME: something here */ } - (IBAction)bring_to_front:sender { - QuartzMessageServerThread(kXDarwinControllerNotify, 1, AppleWMBringAllToFront); + QuartzMessageServerThread(kXquartzControllerNotify, 1, AppleWMBringAllToFront); } - (IBAction)close_window:sender { if ([X11App x_active]) - QuartzMessageServerThread (kXDarwinControllerNotify, 1, AppleWMCloseWindow); + QuartzMessageServerThread (kXquartzControllerNotify, 1, AppleWMCloseWindow); else [[NSApp keyWindow] performClose:sender]; } @@ -560,7 +560,7 @@ objectValueForTableColumn:(NSTableColumn *)tableColumn row:(int)row - (IBAction)minimize_window:sender { if ([X11App x_active]) - QuartzMessageServerThread (kXDarwinControllerNotify, 1, AppleWMMinimizeWindow); + QuartzMessageServerThread (kXquartzControllerNotify, 1, AppleWMMinimizeWindow); else [[NSApp keyWindow] performMiniaturize:sender]; } @@ -568,19 +568,19 @@ objectValueForTableColumn:(NSTableColumn *)tableColumn row:(int)row - (IBAction)zoom_window:sender { if ([X11App x_active]) - QuartzMessageServerThread (kXDarwinControllerNotify, 1, AppleWMZoomWindow); + QuartzMessageServerThread (kXquartzControllerNotify, 1, AppleWMZoomWindow); else [[NSApp keyWindow] performZoom:sender]; } - (IBAction) next_window:sender { - QuartzMessageServerThread (kXDarwinControllerNotify, 1, AppleWMNextWindow); + QuartzMessageServerThread (kXquartzControllerNotify, 1, AppleWMNextWindow); } - (IBAction) previous_window:sender { - QuartzMessageServerThread (kXDarwinControllerNotify, 1, AppleWMPreviousWindow); + QuartzMessageServerThread (kXquartzControllerNotify, 1, AppleWMPreviousWindow); } - (IBAction) enable_fullscreen_changed:sender @@ -588,7 +588,7 @@ objectValueForTableColumn:(NSTableColumn *)tableColumn row:(int)row int value = ![enable_fullscreen intValue]; #ifdef DARWIN_DDX_MISSING - QuartzMessageServerThread (kXDarwinSetRootless, 1, value); + QuartzMessageServerThread (kXquartzSetRootless, 1, value); #endif [NSApp prefs_set_boolean:@PREFS_ROOTLESS value:value]; @@ -598,7 +598,7 @@ objectValueForTableColumn:(NSTableColumn *)tableColumn row:(int)row - (IBAction) toggle_fullscreen:sender { #ifdef DARWIN_DDX_MISSING - QuartzMessageServerThread (kXDarwinToggleFullscreen, 0); + QuartzMessageServerThread (kXquartzToggleFullscreen, 0); #endif } @@ -661,7 +661,7 @@ objectValueForTableColumn:(NSTableColumn *)tableColumn row:(int)row - (IBAction) quit:sender { - QuartzMessageServerThread (kXDarwinQuit, 0); + QuartzMessageServerThread (kXquartzQuit, 0); } - (IBAction) x11_help:sender @@ -684,12 +684,12 @@ objectValueForTableColumn:(NSTableColumn *)tableColumn row:(int)row - (void) applicationDidHide:(NSNotification *)notify { - QuartzMessageServerThread (kXDarwinControllerNotify, 1, AppleWMHideAll); + QuartzMessageServerThread (kXquartzControllerNotify, 1, AppleWMHideAll); } - (void) applicationDidUnhide:(NSNotification *)notify { - QuartzMessageServerThread (kXDarwinControllerNotify, 1, AppleWMShowAll); + QuartzMessageServerThread (kXquartzControllerNotify, 1, AppleWMShowAll); } - (NSApplicationTerminateReply) applicationShouldTerminate:sender @@ -717,7 +717,7 @@ objectValueForTableColumn:(NSTableColumn *)tableColumn row:(int)row [X11App prefs_synchronize]; /* shutdown the X server, it will exit () for us. */ - QuartzMessageServerThread (kXDarwinQuit, 0); + QuartzMessageServerThread (kXquartzQuit, 0); /* In case it doesn't, exit anyway after a while. */ while (sleep (10) != 0) ; diff --git a/hw/xquartz/darwin.c b/hw/xquartz/darwin.c index 20bcee592..0dbfafefa 100644 --- a/hw/xquartz/darwin.c +++ b/hw/xquartz/darwin.c @@ -150,7 +150,7 @@ void DarwinPrintBanner(void) { // this should change depending on which specific server we are building - ErrorF("XQuartz starting:\n"); + ErrorF("Xquartz starting:\n"); ErrorF("X.org Release 7.2\n"); // This is here to help fink until they fix their packages. ErrorF("X.Org X Server %s\nBuild Date: %s\n", XSERVER_VERSION, BUILD_DATE ); } @@ -856,7 +856,7 @@ void ddxUseMsg( void ) */ void ddxGiveUp( void ) { - ErrorF( "Quitting XQuartz...\n" ); + ErrorF( "Quitting Xquartz...\n" ); //if (!quartzRootless) // quartzProcs->ReleaseScreens(); diff --git a/hw/xquartz/darwin.h b/hw/xquartz/darwin.h index 325122dfd..bd1b9a42a 100644 --- a/hw/xquartz/darwin.h +++ b/hw/xquartz/darwin.h @@ -90,34 +90,34 @@ extern int darwinMainScreenY; * Special ddx events understood by the X server */ enum { - kXDarwinUpdateModifiers // update all modifier keys + kXquartzUpdateModifiers // update all modifier keys = LASTEvent+1, // (from X.h list of event names) - kXDarwinUpdateButtons, // update state of mouse buttons 2 and up - kXDarwinScrollWheel, // scroll wheel event + kXquartzUpdateButtons, // update state of mouse buttons 2 and up + kXquartzScrollWheel, // scroll wheel event /* * Quartz-specific events -- not used in IOKit mode */ - kXDarwinActivate, // restore X drawing and cursor - kXDarwinDeactivate, // clip X drawing and switch to Aqua cursor - kXDarwinSetRootClip, // enable or disable drawing to the X screen - kXDarwinQuit, // kill the X server and release the display - kXDarwinReadPasteboard, // copy Mac OS X pasteboard into X cut buffer - kXDarwinWritePasteboard, // copy X cut buffer onto Mac OS X pasteboard - kXDarwinBringAllToFront, // bring all X windows to front - kXDarwinToggleFullscreen, // Enable/Disable fullscreen mode - kXDarwinSetRootless, // Set rootless mode - kXDarwinSpaceChanged, // Spaces changed + kXquartzActivate, // restore X drawing and cursor + kXquartzDeactivate, // clip X drawing and switch to Aqua cursor + kXquartzSetRootClip, // enable or disable drawing to the X screen + kXquartzQuit, // kill the X server and release the display + kXquartzReadPasteboard, // copy Mac OS X pasteboard into X cut buffer + kXquartzWritePasteboard, // copy X cut buffer onto Mac OS X pasteboard + kXquartzBringAllToFront, // bring all X windows to front + kXquartzToggleFullscreen, // Enable/Disable fullscreen mode + kXquartzSetRootless, // Set rootless mode + kXquartzSpaceChanged, // Spaces changed /* * AppleWM events */ - kXDarwinControllerNotify, // send an AppleWMControllerNotify event - kXDarwinPasteboardNotify, // notify the WM to copy or paste + kXquartzControllerNotify, // send an AppleWMControllerNotify event + kXquartzPasteboardNotify, // notify the WM to copy or paste /* * Xplugin notification events */ - kXDarwinDisplayChanged, // display configuration has changed - kXDarwinWindowState, // window visibility state has changed - kXDarwinWindowMoved, // window has moved on screen + kXquartzDisplayChanged, // display configuration has changed + kXquartzWindowState, // window visibility state has changed + kXquartzWindowMoved, // window has moved on screen }; #define ENABLE_DEBUG_LOG 1 diff --git a/hw/xquartz/darwinEvents.c b/hw/xquartz/darwinEvents.c index 22d895795..113cfc109 100644 --- a/hw/xquartz/darwinEvents.c +++ b/hw/xquartz/darwinEvents.c @@ -152,7 +152,7 @@ static void DarwinUpdateModifiers( /* * DarwinReleaseModifiers * This hacky function releases all modifier keys. It should be called when X11.app - * is deactivated (kXDarwinDeactivate) to prevent modifiers from getting stuck if they + * is deactivated (kXquartzDeactivate) to prevent modifiers from getting stuck if they * are held down during a "context" switch -- otherwise, we would miss the KeyUp. */ static void DarwinReleaseModifiers(void) { @@ -341,22 +341,22 @@ void ProcessInputEvents(void) { break; case MotionNotify: - ErrorF("Unexpected ButtonRelease event in DarwinProcessInputEvents\n"); + ErrorF("Unexpected MotionNotify event in DarwinProcessInputEvents\n"); break; - case kXDarwinUpdateModifiers: - ErrorF("Unexpected ButtonRelease event in DarwinProcessInputEvents\n"); + case kXquartzUpdateModifiers: + ErrorF("Unexpected kXquartzUpdateModifiers event in DarwinProcessInputEvents\n"); break; - case kXDarwinUpdateButtons: - ErrorF("Unexpected XDarwinScrollWheel event in DarwinProcessInputEvents\n"); + case kXquartzUpdateButtons: + ErrorF("Unexpected kXquartzUpdateButtons event in DarwinProcessInputEvents\n"); break; - case kXDarwinScrollWheel: - ErrorF("Unexpected XDarwinScrollWheel event in DarwinProcessInputEvents\n"); + case kXquartzScrollWheel: + ErrorF("Unexpected kXquartzScrollWheel event in DarwinProcessInputEvents\n"); break; - case kXDarwinDeactivate: + case kXquartzDeactivate: DarwinReleaseModifiers(); // fall through default: diff --git a/hw/xquartz/quartz.c b/hw/xquartz/quartz.c index a034c9fac..971c9b278 100644 --- a/hw/xquartz/quartz.c +++ b/hw/xquartz/quartz.c @@ -411,24 +411,24 @@ QuartzMessageServerThread( */ void QuartzProcessEvent(xEvent *xe) { switch (xe->u.u.type) { - case kXDarwinControllerNotify: - DEBUG_LOG("kXDarwinControllerNotify\n"); + case kXquartzControllerNotify: + DEBUG_LOG("kXquartzControllerNotify\n"); AppleWMSendEvent(AppleWMControllerNotify, AppleWMControllerNotifyMask, xe->u.clientMessage.u.l.longs0, xe->u.clientMessage.u.l.longs1); break; - case kXDarwinPasteboardNotify: - DEBUG_LOG("kXDarwinPasteboardNotify\n"); + case kXquartzPasteboardNotify: + DEBUG_LOG("kXquartzPasteboardNotify\n"); AppleWMSendEvent(AppleWMPasteboardNotify, AppleWMPasteboardNotifyMask, xe->u.clientMessage.u.l.longs0, xe->u.clientMessage.u.l.longs1); break; - case kXDarwinActivate: - DEBUG_LOG("kXDarwinActivate\n"); + case kXquartzActivate: + DEBUG_LOG("kXquartzActivate\n"); QuartzShow(xe->u.keyButtonPointer.rootX, xe->u.keyButtonPointer.rootY); AppleWMSendEvent(AppleWMActivationNotify, @@ -436,74 +436,74 @@ void QuartzProcessEvent(xEvent *xe) { AppleWMIsActive, 0); break; - case kXDarwinDeactivate: - DEBUG_LOG("kXDarwinDeactivate\n"); + case kXquartzDeactivate: + DEBUG_LOG("kXquartzDeactivate\n"); AppleWMSendEvent(AppleWMActivationNotify, AppleWMActivationNotifyMask, AppleWMIsInactive, 0); QuartzHide(); break; - case kXDarwinDisplayChanged: - DEBUG_LOG("kXDarwinDisplayChanged\n"); + case kXquartzDisplayChanged: + DEBUG_LOG("kXquartzDisplayChanged\n"); QuartzUpdateScreens(); break; - case kXDarwinWindowState: - DEBUG_LOG("kXDarwinWindowState\n"); + case kXquartzWindowState: + DEBUG_LOG("kXquartzWindowState\n"); RootlessNativeWindowStateChanged(xe->u.clientMessage.u.l.longs0, xe->u.clientMessage.u.l.longs1); break; - case kXDarwinWindowMoved: - DEBUG_LOG("kXDarwinWindowMoved\n"); + case kXquartzWindowMoved: + DEBUG_LOG("kXquartzWindowMoved\n"); RootlessNativeWindowMoved ((WindowPtr)xe->u.clientMessage.u.l.longs0); break; - case kXDarwinToggleFullscreen: - DEBUG_LOG("kXDarwinToggleFullscreen\n"); + case kXquartzToggleFullscreen: + DEBUG_LOG("kXquartzToggleFullscreen\n"); #ifdef DARWIN_DDX_MISSING if (quartzEnableRootless) QuartzSetFullscreen(!quartzHasRoot); else if (quartzHasRoot) QuartzHide(); else QuartzShow(); #else - // ErrorF("kXDarwinToggleFullscreen not implemented\n"); + // ErrorF("kXquartzToggleFullscreen not implemented\n"); #endif break; - case kXDarwinSetRootless: - DEBUG_LOG("kXDarwinSetRootless\n"); + case kXquartzSetRootless: + DEBUG_LOG("kXquartzSetRootless\n"); #ifdef DARWIN_DDX_MISSING QuartzSetRootless(xe->u.clientMessage.u.l.longs0); if (!quartzEnableRootless && !quartzHasRoot) QuartzHide(); #else - // ErrorF("kXDarwinSetRootless not implemented\n"); + // ErrorF("kXquartzSetRootless not implemented\n"); #endif break; - case kXDarwinSetRootClip: + case kXquartzSetRootClip: QuartzSetRootClip((BOOL)xe->u.clientMessage.u.l.longs0); break; - case kXDarwinQuit: + case kXquartzQuit: GiveUp(0); break; - case kXDarwinReadPasteboard: + case kXquartzReadPasteboard: QuartzReadPasteboard(); break; - case kXDarwinWritePasteboard: + case kXquartzWritePasteboard: QuartzWritePasteboard(); break; - case kXDarwinBringAllToFront: - DEBUG_LOG("kXDarwinBringAllToFront\n"); + case kXquartzBringAllToFront: + DEBUG_LOG("kXquartzBringAllToFront\n"); RootlessOrderAllWindows(); break; - case kXDarwinSpaceChanged: - DEBUG_LOG("kXDarwinSpaceChanged\n"); + case kXquartzSpaceChanged: + DEBUG_LOG("kXquartzSpaceChanged\n"); QuartzSpaceChanged(xe->u.clientMessage.u.l.longs0); break; default: diff --git a/hw/xquartz/quartzKeyboard.h b/hw/xquartz/quartzKeyboard.h index 0c7e70e48..8131b5650 100644 --- a/hw/xquartz/quartzKeyboard.h +++ b/hw/xquartz/quartzKeyboard.h @@ -45,7 +45,7 @@ typedef struct darwinKeyboardInfo_struct { unsigned char modifierKeycodes[32][2]; } darwinKeyboardInfo; -/* These functions need to be implemented by XQuartz, XDarwin, etc. */ +/* These functions need to be implemented by Xquartz, XDarwin, etc. */ void DarwinKeyboardReload(DeviceIntPtr pDev); Bool QuartzReadSystemKeymap(darwinKeyboardInfo *info); unsigned int QuartzSystemKeymapSeed(void); diff --git a/hw/xquartz/xpr/xprScreen.c b/hw/xquartz/xpr/xprScreen.c index 4dc5846d5..b653a6e3b 100644 --- a/hw/xquartz/xpr/xprScreen.c +++ b/hw/xquartz/xpr/xprScreen.c @@ -67,7 +67,7 @@ static void eventHandler(unsigned int type, const void *arg, switch (type) { case XP_EVENT_DISPLAY_CHANGED: DEBUG_LOG("XP_EVENT_DISPLAY_CHANGED\n"); - QuartzMessageServerThread(kXDarwinDisplayChanged, 0); + QuartzMessageServerThread(kXquartzDisplayChanged, 0); break; case XP_EVENT_WINDOW_STATE_CHANGED: @@ -75,7 +75,7 @@ static void eventHandler(unsigned int type, const void *arg, const xp_window_state_event *ws_arg = arg; DEBUG_LOG("XP_EVENT_WINDOW_STATE_CHANGED: id=%d, state=%d\n", ws_arg->id, ws_arg->state); - QuartzMessageServerThread(kXDarwinWindowState, 2, + QuartzMessageServerThread(kXquartzWindowState, 2, ws_arg->id, ws_arg->state); } else { DEBUG_LOG("XP_EVENT_WINDOW_STATE_CHANGED: ignored\n"); @@ -87,7 +87,7 @@ static void eventHandler(unsigned int type, const void *arg, if (arg_size == sizeof(xp_window_id)) { xp_window_id id = * (xp_window_id *) arg; WindowPtr pWin = xprGetXWindow(id); - QuartzMessageServerThread(kXDarwinWindowMoved, 1, pWin); + QuartzMessageServerThread(kXquartzWindowMoved, 1, pWin); } break; @@ -110,7 +110,7 @@ static void eventHandler(unsigned int type, const void *arg, ErrorF("XP_EVENT_SPACE_CHANGED\n"); if(arg_size == sizeof(uint32_t)) { uint32_t space_id = *(uint32_t *)arg; - QuartzMessageServerThread(kXDarwinSpaceChanged, 1, space_id); + QuartzMessageServerThread(kXquartzSpaceChanged, 1, space_id); } break; default: From 7034484f0887ea0f8ab956515f2d9301ea5842ce Mon Sep 17 00:00:00 2001 From: Daniel Stone Date: Fri, 28 Mar 2008 10:23:36 +0200 Subject: [PATCH 113/149] gitignore: Add two more bits Get slightly better at ignoring vim swap files, and let people keep local changes if they want to. --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index fb2f7e597..837b0380b 100644 --- a/.gitignore +++ b/.gitignore @@ -8,11 +8,12 @@ Makefile.in *.a *.o *~ -.*.swp +.*sw? *.pbxuser *.mode1v3 obj* build* +local aclocal.m4 autom4te.cache compile From 93d876891dbba41b920a9a29a5de77f647f43928 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20H=C3=B6glund?= Date: Mon, 31 Mar 2008 21:15:50 +0200 Subject: [PATCH 114/149] EXA: Improve the algorithm used for tracking offscreen pixmap use. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace the current score keeping algorithm with a rolling counter that's incremented in ExaOffscreenMarkUsed, with the previous value being stored in the area. exaOffscreenAlloc uses the difference between the counter value and the value in the area when deciding which area to evict. It now also takes the size of the areas into account, and favors evicting smaller areas. The credit for these ideas goes to Michel Dänzer. --- exa/exa.h | 2 +- exa/exa_offscreen.c | 36 ++++++++++++++---------------------- exa/exa_priv.h | 1 + 3 files changed, 16 insertions(+), 23 deletions(-) diff --git a/exa/exa.h b/exa/exa.h index 0774a700a..97ae6c0a5 100644 --- a/exa/exa.h +++ b/exa/exa.h @@ -56,7 +56,7 @@ struct _ExaOffscreenArea { int base_offset; /* allocation base */ int offset; /* aligned offset */ int size; /* total allocation size */ - int score; + unsigned last_use; pointer privData; ExaOffscreenSaveProc save; diff --git a/exa/exa_offscreen.c b/exa/exa_offscreen.c index c666b001b..2701e84cf 100644 --- a/exa/exa_offscreen.c +++ b/exa/exa_offscreen.c @@ -71,6 +71,8 @@ ExaOffscreenKickOut (ScreenPtr pScreen, ExaOffscreenArea *area) return exaOffscreenFree (pScreen, area); } +#define AREA_SCORE(area) (area->size / (double)(pExaScr->offScreenCounter - area->last_use)) + /** * exaOffscreenAlloc allocates offscreen memory * @@ -98,7 +100,7 @@ exaOffscreenAlloc (ScreenPtr pScreen, int size, int align, { ExaOffscreenArea *area, *begin, *best; ExaScreenPriv (pScreen); - int tmp, real_size = 0, best_score; + int tmp, real_size = 0; #if DEBUG_OFFSCREEN static int number = 0; ErrorF("================= ============ allocating a new pixmap %d\n", ++number); @@ -143,6 +145,7 @@ exaOffscreenAlloc (ScreenPtr pScreen, int size, int align, if (!area) { + double best_score; /* * Kick out existing users to make space. * @@ -151,11 +154,12 @@ exaOffscreenAlloc (ScreenPtr pScreen, int size, int align, /* prev points at the first object to boot */ best = NULL; - best_score = INT_MAX; + best_score = UINT_MAX; for (begin = pExaScr->info->offScreenAreas; begin != NULL; begin = begin->next) { - int avail, score; + int avail; + double score; ExaOffscreenArea *scan; if (begin->state == ExaOffscreenLocked) @@ -177,8 +181,7 @@ exaOffscreenAlloc (ScreenPtr pScreen, int size, int align, begin = scan; break; } - /* Score should only be non-zero for ExaOffscreenRemovable */ - score += scan->score; + score += AREA_SCORE(scan); avail += scan->size; if (avail >= real_size) break; @@ -230,7 +233,7 @@ exaOffscreenAlloc (ScreenPtr pScreen, int size, int align, new_area->size = area->size - real_size; new_area->state = ExaOffscreenAvail; new_area->save = NULL; - new_area->score = 0; + new_area->last_use = 0; new_area->next = area->next; area->next = new_area; area->size = real_size; @@ -244,7 +247,7 @@ exaOffscreenAlloc (ScreenPtr pScreen, int size, int align, area->state = ExaOffscreenRemovable; area->privData = privData; area->save = save; - area->score = 0; + area->last_use = pExaScr->offScreenCounter++; area->offset = (area->base_offset + align - 1); area->offset -= area->offset % align; @@ -395,7 +398,7 @@ exaOffscreenFree (ScreenPtr pScreen, ExaOffscreenArea *area) area->state = ExaOffscreenAvail; area->save = NULL; - area->score = 0; + area->last_use = 0; /* * Find previous area */ @@ -427,23 +430,11 @@ ExaOffscreenMarkUsed (PixmapPtr pPixmap) { ExaPixmapPriv (pPixmap); ExaScreenPriv (pPixmap->drawable.pScreen); - static int iter = 0; if (!pExaPixmap || !pExaPixmap->area) return; - /* The numbers here are arbitrary. We may want to tune these. */ - pExaPixmap->area->score += 100; - if (++iter == 10) { - ExaOffscreenArea *area; - for (area = pExaScr->info->offScreenAreas; area != NULL; - area = area->next) - { - if (area->state == ExaOffscreenRemovable) - area->score = (area->score * 7) / 8; - } - iter = 0; - } + pExaPixmap->area->last_use = pExaScr->offScreenCounter++; } /** @@ -472,10 +463,11 @@ exaOffscreenInit (ScreenPtr pScreen) area->size = pExaScr->info->memorySize - area->base_offset; area->save = NULL; area->next = NULL; - area->score = 0; + area->last_use = 0; /* Add it to the free areas */ pExaScr->info->offScreenAreas = area; + pExaScr->offScreenCounter = 1; ExaOffscreenValidate (pScreen); diff --git a/exa/exa_priv.h b/exa/exa_priv.h index 89f47184f..e41f46aba 100644 --- a/exa/exa_priv.h +++ b/exa/exa_priv.h @@ -120,6 +120,7 @@ typedef struct { Bool checkDirtyCorrectness; unsigned disableFbCount; Bool optimize_migration; + unsigned offScreenCounter; } ExaScreenPrivRec, *ExaScreenPrivPtr; /* From 8074676d2df8d577b443e3fa5e22d7c71c944bd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20H=C3=B6glund?= Date: Mon, 31 Mar 2008 21:24:59 +0200 Subject: [PATCH 115/149] EXA: Optimize the eviction scanning loop in exaOffscreenAlloc. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reduce the cost of the inner loop, by keeping a set of pointers to the first and the last areas in the series, subtracting the cost of the first area from the score, and adding the cost of the last area while walking the list. This commit also moves the scanning loop from exaOffscreenAlloc into a separate function. Idea by Michel Dänzer. --- exa/exa_offscreen.c | 106 ++++++++++++++++++++++++-------------------- 1 file changed, 58 insertions(+), 48 deletions(-) diff --git a/exa/exa_offscreen.c b/exa/exa_offscreen.c index 2701e84cf..85b538896 100644 --- a/exa/exa_offscreen.c +++ b/exa/exa_offscreen.c @@ -73,6 +73,62 @@ ExaOffscreenKickOut (ScreenPtr pScreen, ExaOffscreenArea *area) #define AREA_SCORE(area) (area->size / (double)(pExaScr->offScreenCounter - area->last_use)) +static ExaOffscreenArea * +exaFindAreaToEvict(ExaScreenPrivPtr pExaScr, int size, int align) +{ + ExaOffscreenArea *begin, *end, *best; + double score, best_score; + int avail, real_size, tmp; + + best_score = UINT_MAX; + begin = end = pExaScr->info->offScreenAreas; + avail = 0; + score = 0; + best = 0; + + while (end != NULL) + { + restart: + while (begin != NULL && begin->state == ExaOffscreenLocked) + begin = end = begin->next; + + if (begin == NULL) + break; + + /* adjust size needed to account for alignment loss for this area */ + real_size = size; + tmp = begin->base_offset % align; + if (tmp) + real_size += (align - tmp); + + while (avail < real_size && end != NULL) + { + if (end->state == ExaOffscreenLocked) { + /* Can't more room here, restart after this locked area */ + avail = 0; + score = 0; + begin = end; + goto restart; + } + avail += end->size; + score += AREA_SCORE(end); + end = end->next; + } + + /* Check the score, update best */ + if (avail >= real_size && score < best_score) { + best = begin; + best_score = score; + } + + avail -= begin->size; + score -= AREA_SCORE(begin); + begin = begin->next; + } + + return best; +} + /** * exaOffscreenAlloc allocates offscreen memory * @@ -98,7 +154,7 @@ exaOffscreenAlloc (ScreenPtr pScreen, int size, int align, ExaOffscreenSaveProc save, pointer privData) { - ExaOffscreenArea *area, *begin, *best; + ExaOffscreenArea *area; ExaScreenPriv (pScreen); int tmp, real_size = 0; #if DEBUG_OFFSCREEN @@ -145,54 +201,8 @@ exaOffscreenAlloc (ScreenPtr pScreen, int size, int align, if (!area) { - double best_score; - /* - * Kick out existing users to make space. - * - * First, locate a region which can hold the desired object. - */ + area = exaFindAreaToEvict(pExaScr, size, align); - /* prev points at the first object to boot */ - best = NULL; - best_score = UINT_MAX; - for (begin = pExaScr->info->offScreenAreas; begin != NULL; - begin = begin->next) - { - int avail; - double score; - ExaOffscreenArea *scan; - - if (begin->state == ExaOffscreenLocked) - continue; - - /* adjust size needed to account for alignment loss for this area */ - real_size = size; - tmp = begin->base_offset % align; - if (tmp) - real_size += (align - tmp); - - avail = 0; - score = 0; - /* now see if we can make room here, and how "costly" it'll be. */ - for (scan = begin; scan != NULL; scan = scan->next) - { - if (scan->state == ExaOffscreenLocked) { - /* Can't make room here, start after this locked area. */ - begin = scan; - break; - } - score += AREA_SCORE(scan); - avail += scan->size; - if (avail >= real_size) - break; - } - /* Is it the best option we've found so far? */ - if (avail >= real_size && score < best_score) { - best = begin; - best_score = score; - } - } - area = best; if (!area) { DBG_OFFSCREEN (("Alloc 0x%x -> NOSPACE\n", size)); From c40e0b51f0d9ef5e1f30f233d7db1e6db9d6681b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Wed, 26 Mar 2008 19:28:09 -0400 Subject: [PATCH 116/149] Implement DRI2 direct rendering and update AIGLX to DRI interface changes. Get rid of glcontextmodes.[ch] from build, rename __GlcontextModes to __GLXcontext. Drop all #includes of glcontextmodes.h and glcore.h. Drop the DRI context modes extension. Add protocol code to DRI2 module and load DRI2 extension by default. --- GL/glx/Makefile.am | 2 - GL/glx/glxcmds.c | 51 ++-- GL/glx/glxcontext.h | 6 +- GL/glx/glxdrawable.h | 2 +- GL/glx/glxdri.c | 257 ++++++++++---------- GL/glx/glxdri2.c | 427 ++++++++++++++++++++++----------- GL/glx/glxglcore.c | 56 +++-- GL/glx/glxscreens.c | 55 +++-- GL/glx/glxscreens.h | 88 ++++++- GL/glx/glxutil.c | 5 +- GL/glx/glxutil.h | 2 +- GL/symlink-mesa.sh | 2 - configure.ac | 2 +- hw/xfree86/common/xf86Config.c | 1 + hw/xfree86/dri2/Makefile.am | 5 +- hw/xfree86/dri2/dri2.c | 107 ++++++--- hw/xfree86/dri2/dri2.h | 16 +- hw/xfree86/dri2/dri2ext.c | 361 ++++++++++++++++++++++++++++ os/utils.c | 3 + 19 files changed, 1054 insertions(+), 394 deletions(-) create mode 100644 hw/xfree86/dri2/dri2ext.c diff --git a/GL/glx/Makefile.am b/GL/glx/Makefile.am index 377d76019..1d4719c88 100644 --- a/GL/glx/Makefile.am +++ b/GL/glx/Makefile.am @@ -31,8 +31,6 @@ INCLUDES = \ nodist_libglx_la_SOURCES = indirect_size.h \ glapi.c \ - glcontextmodes.c \ - glcontextmode.h \ glthread.c \ indirect_dispatch.c \ indirect_dispatch.h \ diff --git a/GL/glx/glxcmds.c b/GL/glx/glxcmds.c index 3b79cca20..36aae61b9 100644 --- a/GL/glx/glxcmds.c +++ b/GL/glx/glxcmds.c @@ -50,7 +50,6 @@ #include #include "glxutil.h" #include "glxext.h" -#include "glcontextmodes.h" #include "glapitable.h" #include "glapi.h" #include "glthread.h" @@ -83,9 +82,9 @@ validGlxScreen(ClientPtr client, int screen, __GLXscreen **pGlxScreen, int *err) static int validGlxFBConfig(ClientPtr client, __GLXscreen *pGlxScreen, XID id, - __GLcontextModes **config, int *err) + __GLXconfig **config, int *err) { - __GLcontextModes *m; + __GLXconfig *m; for (m = pGlxScreen->fbconfigs; m != NULL; m = m->next) if (m->fbconfigID == id) { @@ -101,7 +100,7 @@ validGlxFBConfig(ClientPtr client, __GLXscreen *pGlxScreen, XID id, static int validGlxVisual(ClientPtr client, __GLXscreen *pGlxScreen, XID id, - __GLcontextModes **config, int *err) + __GLXconfig **config, int *err) { int i; @@ -118,7 +117,7 @@ validGlxVisual(ClientPtr client, __GLXscreen *pGlxScreen, XID id, } static int -validGlxFBConfigForWindow(ClientPtr client, __GLcontextModes *config, +validGlxFBConfigForWindow(ClientPtr client, __GLXconfig *config, DrawablePtr pDraw, int *err) { ScreenPtr pScreen = pDraw->pScreen; @@ -135,7 +134,7 @@ validGlxFBConfigForWindow(ClientPtr client, __GLcontextModes *config, } /* FIXME: What exactly should we check here... */ - if (pVisual->class != _gl_convert_to_x_visual_type(config->visualType) || + if (pVisual->class != glxConvertToXVisualType(config->visualType) || !(config->drawableType & GLX_WINDOW_BIT)) { client->errorValue = pDraw->id; *err = BadMatch; @@ -161,7 +160,7 @@ static void __glXdirectContextDestroy(__GLXcontext *context) } static __GLXcontext *__glXdirectContextCreate(__GLXscreen *screen, - __GLcontextModes *modes, + __GLXconfig *modes, __GLXcontext *shareContext) { __GLXcontext *context; @@ -186,7 +185,7 @@ static __GLXcontext *__glXdirectContextCreate(__GLXscreen *screen, static int DoCreateContext(__GLXclientState *cl, GLXContextID gcId, - GLXContextID shareList, __GLcontextModes *config, + GLXContextID shareList, __GLXconfig *config, __GLXscreen *pGlxScreen, GLboolean isDirect) { ClientPtr client = cl->client; @@ -248,7 +247,7 @@ DoCreateContext(__GLXclientState *cl, GLXContextID gcId, ** a GL core that needs windowing information (e.g., Mesa). */ glxc->pGlxScreen = pGlxScreen; - glxc->modes = config; + glxc->config = config; /* ** Register this context as a resource. @@ -276,7 +275,7 @@ DoCreateContext(__GLXclientState *cl, GLXContextID gcId, int __glXDisp_CreateContext(__GLXclientState *cl, GLbyte *pc) { xGLXCreateContextReq *req = (xGLXCreateContextReq *) pc; - __GLcontextModes *config; + __GLXconfig *config; __GLXscreen *pGlxScreen; int err; @@ -292,7 +291,7 @@ int __glXDisp_CreateContext(__GLXclientState *cl, GLbyte *pc) int __glXDisp_CreateNewContext(__GLXclientState *cl, GLbyte *pc) { xGLXCreateNewContextReq *req = (xGLXCreateNewContextReq *) pc; - __GLcontextModes *config; + __GLXconfig *config; __GLXscreen *pGlxScreen; int err; @@ -309,7 +308,7 @@ int __glXDisp_CreateContextWithConfigSGIX(__GLXclientState *cl, GLbyte *pc) { xGLXCreateContextWithConfigSGIXReq *req = (xGLXCreateContextWithConfigSGIXReq *) pc; - __GLcontextModes *config; + __GLXconfig *config; __GLXscreen *pGlxScreen; int err; @@ -462,7 +461,7 @@ __glXGetDrawable(__GLXcontext *glxc, GLXDrawable drawId, ClientPtr client, * GLXPixmap and we just return the __GLXdrawable. */ pGlxDraw = (__GLXdrawable *) LookupIDByType(drawId, __glXDrawableRes); if (pGlxDraw != NULL) { - if (glxc != NULL && pGlxDraw->modes != glxc->modes) { + if (glxc != NULL && pGlxDraw->config != glxc->config) { client->errorValue = drawId; *error = BadMatch; return NULL; @@ -497,12 +496,12 @@ __glXGetDrawable(__GLXcontext *glxc, GLXDrawable drawId, ClientPtr client, * the context screen and that the context fbconfig is compatible * with the window visual. */ if (pDraw->pScreen != glxc->pGlxScreen->pScreen || - !validGlxFBConfigForWindow(client, glxc->modes, pDraw, error)) + !validGlxFBConfigForWindow(client, glxc->config, pDraw, error)) return NULL; pGlxDraw = glxc->pGlxScreen->createDrawable(glxc->pGlxScreen, pDraw, GLX_DRAWABLE_WINDOW, - drawId, glxc->modes); + drawId, glxc->config); /* since we are creating the drawablePrivate, drawId should be new */ if (!AddResource(drawId, __glXDrawableRes, pGlxDraw)) { @@ -878,7 +877,7 @@ int __glXDisp_GetVisualConfigs(__GLXclientState *cl, GLbyte *pc) ClientPtr client = cl->client; xGLXGetVisualConfigsReply reply; __GLXscreen *pGlxScreen; - __GLcontextModes *modes; + __GLXconfig *modes; CARD32 buf[__GLX_TOTAL_CONFIG]; int p, i, err; __GLX_DECLARE_SWAP_VARIABLES; @@ -907,7 +906,7 @@ int __glXDisp_GetVisualConfigs(__GLXclientState *cl, GLbyte *pc) p = 0; buf[p++] = modes->visualID; - buf[p++] = _gl_convert_to_x_visual_type( modes->visualType ); + buf[p++] = glxConvertToXVisualType( modes->visualType ); buf[p++] = modes->rgbMode; buf[p++] = modes->redBits; @@ -980,7 +979,7 @@ DoGetFBConfigs(__GLXclientState *cl, unsigned screen) __GLXscreen *pGlxScreen; CARD32 buf[__GLX_FBCONFIG_ATTRIBS_LENGTH]; int p, err; - __GLcontextModes *modes; + __GLXconfig *modes; __GLX_DECLARE_SWAP_VARIABLES; __GLX_DECLARE_SWAP_ARRAY_VARIABLES; @@ -1062,7 +1061,7 @@ int __glXDisp_GetFBConfigsSGIX(__GLXclientState *cl, GLbyte *pc) } static int -DoCreateGLXDrawable(ClientPtr client, __GLXscreen *pGlxScreen, __GLcontextModes *config, +DoCreateGLXDrawable(ClientPtr client, __GLXscreen *pGlxScreen, __GLXconfig *config, DrawablePtr pDraw, XID glxDrawableId, int type) { __GLXdrawable *pGlxDraw; @@ -1086,7 +1085,7 @@ DoCreateGLXDrawable(ClientPtr client, __GLXscreen *pGlxScreen, __GLcontextModes } static int -DoCreateGLXPixmap(ClientPtr client, __GLXscreen *pGlxScreen, __GLcontextModes *config, +DoCreateGLXPixmap(ClientPtr client, __GLXscreen *pGlxScreen, __GLXconfig *config, XID drawableId, XID glxDrawableId) { DrawablePtr pDraw; @@ -1144,7 +1143,7 @@ determineTextureTarget(XID glxDrawableID, CARD32 *attribs, CARD32 numAttribs) int __glXDisp_CreateGLXPixmap(__GLXclientState *cl, GLbyte *pc) { xGLXCreateGLXPixmapReq *req = (xGLXCreateGLXPixmapReq *) pc; - __GLcontextModes *config; + __GLXconfig *config; __GLXscreen *pGlxScreen; int err; @@ -1160,7 +1159,7 @@ int __glXDisp_CreateGLXPixmap(__GLXclientState *cl, GLbyte *pc) int __glXDisp_CreatePixmap(__GLXclientState *cl, GLbyte *pc) { xGLXCreatePixmapReq *req = (xGLXCreatePixmapReq *) pc; - __GLcontextModes *config; + __GLXconfig *config; __GLXscreen *pGlxScreen; int err; @@ -1184,7 +1183,7 @@ int __glXDisp_CreateGLXPixmapWithConfigSGIX(__GLXclientState *cl, GLbyte *pc) { xGLXCreateGLXPixmapWithConfigSGIXReq *req = (xGLXCreateGLXPixmapWithConfigSGIXReq *) pc; - __GLcontextModes *config; + __GLXconfig *config; __GLXscreen *pGlxScreen; int err; @@ -1246,7 +1245,7 @@ static int DoCreatePbuffer(ClientPtr client, int screenNum, XID fbconfigId, int width, int height, XID glxDrawableId) { - __GLcontextModes *config; + __GLXconfig *config; __GLXscreen *pGlxScreen; PixmapPtr pPixmap; int err; @@ -1359,7 +1358,7 @@ int __glXDisp_ChangeDrawableAttributesSGIX(__GLXclientState *cl, GLbyte *pc) int __glXDisp_CreateWindow(__GLXclientState *cl, GLbyte *pc) { xGLXCreateWindowReq *req = (xGLXCreateWindowReq *) pc; - __GLcontextModes *config; + __GLXconfig *config; __GLXscreen *pGlxScreen; ClientPtr client = cl->client; DrawablePtr pDraw; @@ -1473,7 +1472,7 @@ DoQueryContext(__GLXclientState *cl, GLXContextID gcId) *pSendBuf++ = GLX_SHARE_CONTEXT_EXT; *pSendBuf++ = (int)(ctx->share_id); *pSendBuf++ = GLX_VISUAL_ID_EXT; - *pSendBuf++ = (int)(ctx->modes->visualID); + *pSendBuf++ = (int)(ctx->config->visualID); *pSendBuf++ = GLX_SCREEN_EXT; *pSendBuf++ = (int)(ctx->pGlxScreen->pScreen->myNum); diff --git a/GL/glx/glxcontext.h b/GL/glx/glxcontext.h index 4c36801c1..18d3c6fe5 100644 --- a/GL/glx/glxcontext.h +++ b/GL/glx/glxcontext.h @@ -40,8 +40,6 @@ ** */ -#include "GL/internal/glcore.h" - typedef struct __GLXtextureFromPixmap __GLXtextureFromPixmap; struct __GLXtextureFromPixmap { int (*bindTexImage) (__GLXcontext *baseContext, @@ -77,9 +75,9 @@ struct __GLXcontext { __GLXcontext *nextReadPriv; /* - ** mode struct for this context + ** config struct for this context */ - __GLcontextModes *modes; + __GLXconfig *config; /* ** Pointer to screen info data for this context. This is set diff --git a/GL/glx/glxdrawable.h b/GL/glx/glxdrawable.h index f62d1ee34..98e301b88 100644 --- a/GL/glx/glxdrawable.h +++ b/GL/glx/glxdrawable.h @@ -74,7 +74,7 @@ struct __GLXdrawable { /* ** Configuration of the visual to which this drawable was created. */ - __GLcontextModes *modes; + __GLXconfig *config; /* ** Lists of contexts bound to this drawable. There are two lists here. diff --git a/GL/glx/glxdri.c b/GL/glx/glxdri.c index 1e1791122..ffa9a0b76 100644 --- a/GL/glx/glxdri.c +++ b/GL/glx/glxdri.c @@ -52,7 +52,6 @@ #define DRI_NEW_INTERFACE_ONLY #include "glxserver.h" #include "glxutil.h" -#include "glcontextmodes.h" #include "g_disptab.h" #include "glapitable.h" @@ -61,26 +60,26 @@ #include "dispatch.h" #include "extension_string.h" -#define containerOf(ptr, type, member) \ - (type *)( (char *)ptr - offsetof(type,member) ) - typedef struct __GLXDRIscreen __GLXDRIscreen; typedef struct __GLXDRIcontext __GLXDRIcontext; typedef struct __GLXDRIdrawable __GLXDRIdrawable; +typedef struct __GLXDRIconfig __GLXDRIconfig; struct __GLXDRIscreen { __GLXscreen base; - __DRIscreen driScreen; + __DRIscreen *driScreen; void *driver; xf86EnterVTProc *enterVT; xf86LeaveVTProc *leaveVT; - __DRIcopySubBufferExtension *copySubBuffer; - __DRIswapControlExtension *swapControl; + const __DRIcoreExtension *core; + const __DRIlegacyExtension *legacy; + const __DRIcopySubBufferExtension *copySubBuffer; + const __DRIswapControlExtension *swapControl; #ifdef __DRI_TEX_OFFSET - __DRItexOffsetExtension *texOffset; + const __DRItexOffsetExtension *texOffset; DRITexOffsetStartProcPtr texOffsetStart; DRITexOffsetFinishProcPtr texOffsetFinish; __GLXDRIdrawable *texOffsetOverride[16]; @@ -92,13 +91,13 @@ struct __GLXDRIscreen { struct __GLXDRIcontext { __GLXcontext base; - __DRIcontext driContext; + __DRIcontext *driContext; XID hwContextID; }; struct __GLXDRIdrawable { __GLXdrawable base; - __DRIdrawable driDrawable; + __DRIdrawable *driDrawable; /* Pulled in from old __GLXpixmap */ #ifdef __DRI_TEX_OFFSET @@ -109,7 +108,10 @@ struct __GLXDRIdrawable { #endif }; -static const char CREATE_NEW_SCREEN_FUNC[] = __DRI_CREATE_NEW_SCREEN_STRING; +struct __GLXDRIconfig { + __GLXconfig config; + __DRIconfig *driConfig; +}; static void __glXDRIleaveServer(GLboolean rendering) @@ -151,7 +153,7 @@ __glXDRIleaveServer(GLboolean rendering) __GLXDRIdrawable *pGlxPix = texOffsetOverride[j]; if (pGlxPix && pGlxPix->texname) { - screen->texOffset->setTexOffset(&pGlxPix->ctx->driContext, + screen->texOffset->setTexOffset(pGlxPix->ctx->driContext, pGlxPix->texname, pGlxPix->offset, pGlxPix->base.pDraw->depth, @@ -219,24 +221,24 @@ static void __glXDRIdrawableDestroy(__GLXdrawable *drawable) { __GLXDRIdrawable *private = (__GLXDRIdrawable *) drawable; - + __GLXDRIscreen *screen; int i; for (i = 0; i < screenInfo.numScreens; i++) { - __glXDRIdoReleaseTexImage((__GLXDRIscreen *) - glxGetScreen(screenInfo.screens[i]), - private); + screen = (__GLXDRIscreen *) glxGetScreen(screenInfo.screens[i]); + __glXDRIdoReleaseTexImage(screen, private); } - (*private->driDrawable.destroyDrawable)(&private->driDrawable); - /* If the X window was destroyed, the dri DestroyWindow hook will * aready have taken care of this, so only call if pDraw isn't NULL. */ if (drawable->pDraw != NULL) { - __glXenterServer(GL_FALSE); - DRIDestroyDrawable(drawable->pDraw->pScreen, - serverClient, drawable->pDraw); - __glXleaveServer(GL_FALSE); + screen = (__GLXDRIscreen *) glxGetScreen(drawable->pDraw->pScreen); + (*screen->core->destroyDrawable)(private->driDrawable); + + __glXenterServer(GL_FALSE); + DRIDestroyDrawable(drawable->pDraw->pScreen, + serverClient, drawable->pDraw); + __glXleaveServer(GL_FALSE); } xfree(private); @@ -255,8 +257,10 @@ static GLboolean __glXDRIdrawableSwapBuffers(__GLXdrawable *basePrivate) { __GLXDRIdrawable *private = (__GLXDRIdrawable *) basePrivate; + __GLXDRIscreen *screen = + (__GLXDRIscreen *) glxGetScreen(basePrivate->pDraw->pScreen); - (*private->driDrawable.swapBuffers)(&private->driDrawable); + (*screen->core->swapBuffers)(private->driDrawable); return TRUE; } @@ -266,11 +270,11 @@ static int __glXDRIdrawableSwapInterval(__GLXdrawable *baseDrawable, int interval) { __GLXDRIdrawable *draw = (__GLXDRIdrawable *) baseDrawable; - __GLXDRIscreen *screen = (__GLXDRIscreen *) - glxGetScreen(baseDrawable->pDraw->pScreen); + __GLXDRIscreen *screen = + (__GLXDRIscreen *) glxGetScreen(baseDrawable->pDraw->pScreen); if (screen->swapControl) - screen->swapControl->setSwapInterval(&draw->driDrawable, interval); + screen->swapControl->setSwapInterval(draw->driDrawable, interval); return 0; } @@ -285,20 +289,21 @@ __glXDRIdrawableCopySubBuffer(__GLXdrawable *basePrivate, glxGetScreen(basePrivate->pDraw->pScreen); if (screen->copySubBuffer) - screen->copySubBuffer->copySubBuffer(&private->driDrawable, - x, y, w, h); + screen->copySubBuffer->copySubBuffer(private->driDrawable, x, y, w, h); } static void __glXDRIcontextDestroy(__GLXcontext *baseContext) { __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext; + __GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen; Bool retval; - context->driContext.destroyContext(&context->driContext); + screen->core->destroyContext(context->driContext); __glXenterServer(GL_FALSE); - retval = DRIDestroyContext(baseContext->pGlxScreen->pScreen, context->hwContextID); + retval = DRIDestroyContext(baseContext->pGlxScreen->pScreen, + context->hwContextID); __glXleaveServer(GL_FALSE); __glXContextDestroy(&context->base); @@ -309,20 +314,22 @@ static int __glXDRIcontextMakeCurrent(__GLXcontext *baseContext) { __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext; + __GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen; __GLXDRIdrawable *draw = (__GLXDRIdrawable *) baseContext->drawPriv; __GLXDRIdrawable *read = (__GLXDRIdrawable *) baseContext->readPriv; - return (*context->driContext.bindContext)(&context->driContext, - &draw->driDrawable, - &read->driDrawable); + return (*screen->core->bindContext)(context->driContext, + draw->driDrawable, + read->driDrawable); } static int __glXDRIcontextLoseCurrent(__GLXcontext *baseContext) { __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext; + __GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen; - return (*context->driContext.unbindContext)(&context->driContext); + return (*screen->core->unbindContext)(context->driContext); } static int @@ -331,13 +338,10 @@ __glXDRIcontextCopy(__GLXcontext *baseDst, __GLXcontext *baseSrc, { __GLXDRIcontext *dst = (__GLXDRIcontext *) baseDst; __GLXDRIcontext *src = (__GLXDRIcontext *) baseSrc; + __GLXDRIscreen *screen = (__GLXDRIscreen *) dst->base.pGlxScreen; - /* FIXME: We will need to add DRIcontext::copyContext for this. */ - - (void) dst; - (void) src; - - return FALSE; + return (*screen->core->copyContext)(dst->driContext, + src->driContext, mask); } static int @@ -346,10 +350,11 @@ __glXDRIcontextForceCurrent(__GLXcontext *baseContext) __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext; __GLXDRIdrawable *draw = (__GLXDRIdrawable *) baseContext->drawPriv; __GLXDRIdrawable *read = (__GLXDRIdrawable *) baseContext->readPriv; + __GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen; - return (*context->driContext.bindContext)(&context->driContext, - &draw->driDrawable, - &read->driDrawable); + return (*screen->core->bindContext)(context->driContext, + draw->driDrawable, + read->driDrawable); } static void @@ -392,10 +397,8 @@ __glXDRIbindTexImage(__GLXcontext *baseContext, int bpp, override = 0, texname; GLenum format, type; ScreenPtr pScreen = glxPixmap->pDraw->pScreen; - __GLXDRIdrawable *driDraw = - containerOf(glxPixmap, __GLXDRIdrawable, base); - __GLXDRIscreen * const screen = - (__GLXDRIscreen *) glxGetScreen(pScreen); + __GLXDRIdrawable *driDraw = (__GLXDRIdrawable *) glxPixmap; + __GLXDRIscreen * const screen = (__GLXDRIscreen *) glxGetScreen(pScreen); CALL_GetIntegerv(GET_DISPATCH(), (glxPixmap->target == GL_TEXTURE_2D ? GL_TEXTURE_BINDING_2D : @@ -439,7 +442,7 @@ alreadyin: driDraw->texname = texname; - screen->texOffset->setTexOffset(&driDraw->ctx->driContext, texname, 0, + screen->texOffset->setTexOffset(driDraw->ctx->driContext, texname, 0, pixmap->drawable.depth, pixmap->devKind); } @@ -568,9 +571,11 @@ __glXDRIreleaseTexImage(__GLXcontext *baseContext, int buffer, __GLXdrawable *pixmap) { - __glXDRIdoReleaseTexImage((__GLXDRIscreen *) - glxGetScreen(pixmap->pDraw->pScreen), - containerOf(pixmap, __GLXDRIdrawable, base)); + __GLXDRIscreen *screen = + (__GLXDRIscreen *) glxGetScreen(pixmap->pDraw->pScreen); + __GLXDRIdrawable *drawable = (__GLXDRIdrawable *) pixmap; + + __glXDRIdoReleaseTexImage(screen, drawable); return Success; } @@ -585,7 +590,7 @@ __glXDRIscreenDestroy(__GLXscreen *baseScreen) { __GLXDRIscreen *screen = (__GLXDRIscreen *) baseScreen; - screen->driScreen.destroyScreen(&screen->driScreen); + screen->core->destroyScreen(screen->driScreen); dlclose(screen->driver); @@ -596,11 +601,12 @@ __glXDRIscreenDestroy(__GLXscreen *baseScreen) static __GLXcontext * __glXDRIscreenCreateContext(__GLXscreen *baseScreen, - __GLcontextModes *modes, + __GLXconfig *glxConfig, __GLXcontext *baseShareContext) { __GLXDRIscreen *screen = (__GLXDRIscreen *) baseScreen; __GLXDRIcontext *context, *shareContext; + __GLXDRIconfig *config = (__GLXDRIconfig *) glxConfig; VisualPtr visual; int i; GLboolean retval; @@ -610,7 +616,7 @@ __glXDRIscreenCreateContext(__GLXscreen *baseScreen, shareContext = (__GLXDRIcontext *) baseShareContext; if (shareContext) - driShare = &shareContext->driContext; + driShare = shareContext->driContext; else driShare = NULL; @@ -632,7 +638,7 @@ __glXDRIscreenCreateContext(__GLXscreen *baseScreen, /* Find the requested X visual */ visual = pScreen->visuals; for (i = 0; i < pScreen->numVisuals; i++, visual++) - if (visual->vid == modes->visualID) + if (visual->vid == glxConfig->visualID) break; if (i == pScreen->numVisuals) return GL_FALSE; @@ -644,15 +650,15 @@ __glXDRIscreenCreateContext(__GLXscreen *baseScreen, context->hwContextID, &hwContext); __glXleaveServer(GL_FALSE); - context->driContext.private = - screen->driScreen.createNewContext(&screen->driScreen, - modes, - 0, /* render type */ - driShare, - hwContext, - &context->driContext); + context->driContext = + screen->legacy->createNewContext(screen->driScreen, + config->driConfig, + 0, /* render type */ + driShare, + hwContext, + context); - if (context->driContext.private == NULL) { + if (context->driContext == NULL) { __glXenterServer(GL_FALSE); retval = DRIDestroyContext(baseScreen->pScreen, context->hwContextID); __glXleaveServer(GL_FALSE); @@ -668,9 +674,10 @@ __glXDRIscreenCreateDrawable(__GLXscreen *screen, DrawablePtr pDraw, int type, XID drawId, - __GLcontextModes *modes) + __GLXconfig *glxConfig) { __GLXDRIscreen *driScreen = (__GLXDRIscreen *) screen; + __GLXDRIconfig *config = (__GLXDRIconfig *) glxConfig; __GLXDRIdrawable *private; GLboolean retval; drm_drawable_t hwDrawable; @@ -682,7 +689,7 @@ __glXDRIscreenCreateDrawable(__GLXscreen *screen, memset(private, 0, sizeof *private); if (!__glXDrawableInit(&private->base, screen, - pDraw, type, drawId, modes)) { + pDraw, type, drawId, glxConfig)) { xfree(private); return NULL; } @@ -700,13 +707,12 @@ __glXDRIscreenCreateDrawable(__GLXscreen *screen, /* The last argument is 'attrs', which is used with pbuffers which * we currently don't support. */ - private->driDrawable.private = - (driScreen->driScreen.createNewDrawable)(&driScreen->driScreen, - modes, - &private->driDrawable, - hwDrawable, 0, 0, NULL); + private->driDrawable = + (driScreen->legacy->createNewDrawable)(driScreen->driScreen, + config->driConfig, + hwDrawable, 0, NULL, private); - if (private->driDrawable.private == NULL) { + if (private->driDrawable == NULL) { __glXenterServer(GL_FALSE); DRIDestroyDrawable(screen->pScreen, serverClient, pDraw); __glXleaveServer(GL_FALSE); @@ -723,10 +729,10 @@ getDrawableInfo(__DRIdrawable *driDrawable, int *x, int *y, int *width, int *height, int *numClipRects, drm_clip_rect_t **ppClipRects, int *backX, int *backY, - int *numBackClipRects, drm_clip_rect_t **ppBackClipRects) + int *numBackClipRects, drm_clip_rect_t **ppBackClipRects, + void *data) { - __GLXDRIdrawable *drawable = containerOf(driDrawable, - __GLXDRIdrawable, driDrawable); + __GLXDRIdrawable *drawable = data; ScreenPtr pScreen; drm_clip_rect_t *pClipRects, *pBackClipRects; GLboolean retval; @@ -810,10 +816,10 @@ getUST(int64_t *ust) static void __glXReportDamage(__DRIdrawable *driDraw, int x, int y, drm_clip_rect_t *rects, int num_rects, - GLboolean front_buffer) + GLboolean front_buffer, + void *data) { - __GLXDRIdrawable *drawable = - containerOf(driDraw, __GLXDRIdrawable, driDrawable); + __GLXDRIdrawable *drawable = data; DrawablePtr pDraw = drawable->base.pDraw; RegionRec region; @@ -827,13 +833,6 @@ static void __glXReportDamage(__DRIdrawable *driDraw, __glXleaveServer(GL_FALSE); } -/* Table of functions that we export to the driver. */ -static const __DRIcontextModesExtension contextModesExtension = { - { __DRI_CONTEXT_MODES, __DRI_CONTEXT_MODES_VERSION }, - _gl_context_modes_create, - _gl_context_modes_destroy, -}; - static const __DRIsystemTimeExtension systemTimeExtension = { { __DRI_SYSTEM_TIME, __DRI_SYSTEM_TIME_VERSION }, getUST, @@ -851,7 +850,6 @@ static const __DRIdamageExtension damageExtension = { }; static const __DRIextension *loader_extensions[] = { - &contextModesExtension.base, &systemTimeExtension.base, &getDrawableInfoExtension.base, &damageExtension.base, @@ -897,7 +895,8 @@ initializeExtensions(__GLXDRIscreen *screen) const __DRIextension **extensions; int i; - extensions = screen->driScreen.getExtensions(&screen->driScreen); + extensions = screen->core->getExtensions(screen->driScreen); + for (i = 0; extensions[i]; i++) { #ifdef __DRI_COPY_SUB_BUFFER if (strcmp(extensions[i]->name, __DRI_COPY_SUB_BUFFER) == 0) { @@ -931,12 +930,12 @@ initializeExtensions(__GLXDRIscreen *screen) } } -#define COPY_SUB_BUFFER_INTERNAL_VERSION 20060314 +extern __GLXconfig * +glxConvertConfigs(const __DRIcoreExtension *core, const __DRIconfig **configs); static __GLXscreen * __glXDRIscreenProbe(ScreenPtr pScreen) { - PFNCREATENEWSCREENFUNC createNewScreen; drm_handle_t hSAREA; drmAddress pSAREA = NULL; char *BusID; @@ -953,11 +952,13 @@ __glXDRIscreenProbe(ScreenPtr pScreen) drm_handle_t hFB; int junk; __GLXDRIscreen *screen; - void *dev_priv = NULL; char filename[128]; Bool isCapable; size_t buffer_size; ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + const __DRIconfig **driConfigs; + const __DRIextension **extensions; + int i; if (!xf86LoaderCheckSymbol("DRIQueryDirectRenderingCapable") || !DRIQueryDirectRenderingCapable(pScreen, &isCapable) || @@ -985,9 +986,6 @@ __glXDRIscreenProbe(ScreenPtr pScreen) dri_version.minor = XF86DRI_MINOR_VERSION; dri_version.patch = XF86DRI_PATCH_VERSION; - framebuffer.base = NULL; - framebuffer.dev_priv = NULL; - if (!DRIOpenConnection(pScreen, &hSAREA, &BusID)) { LogMessage(X_ERROR, "AIGLX error: DRIOpenConnection failed\n"); goto handle_error; @@ -1046,11 +1044,30 @@ __glXDRIscreenProbe(ScreenPtr pScreen) goto handle_error; } - createNewScreen = dlsym(screen->driver, CREATE_NEW_SCREEN_FUNC); - if (createNewScreen == NULL) { - LogMessage(X_ERROR, "AIGLX error: dlsym for %s failed (%s)\n", - CREATE_NEW_SCREEN_FUNC, dlerror()); - goto handle_error; + extensions = dlsym(screen->driver, __DRI_DRIVER_EXTENSIONS); + if (extensions == NULL) { + LogMessage(X_ERROR, "AIGLX error: %s exports no extensions (%s)\n", + driverName, dlerror()); + goto handle_error; + } + + for (i = 0; extensions[i]; i++) { + if (strcmp(extensions[i]->name, __DRI_CORE) == 0 && + extensions[i]->version >= __DRI_CORE_VERSION) { + screen->core = (__DRIcoreExtension *) extensions[i]; + } + + if (strcmp(extensions[i]->name, __DRI_LEGACY) == 0 && + extensions[i]->version >= __DRI_LEGACY_VERSION) { + screen->legacy = (__DRIlegacyExtension *) extensions[i]; + } + } + + if (screen->core == NULL || screen->legacy == NULL) { + LogMessage(X_ERROR, + "AIGLX error: %s does not export required DRI extension\n", + driverName); + goto handle_error; } /* @@ -1066,19 +1083,6 @@ __glXDRIscreenProbe(ScreenPtr pScreen) goto handle_error; } - /* Sigh... the DRI interface is broken; the DRI driver will free - * the dev private pointer using _mesa_free() on screen destroy, - * but we can't use _mesa_malloc() here. In fact, the DRI driver - * shouldn't free data it didn't allocate itself, but what can you - * do... */ - dev_priv = xalloc(framebuffer.dev_priv_size); - if (dev_priv == NULL) { - LogMessage(X_ERROR, "AIGLX error: dev_priv allocation failed"); - goto handle_error; - } - memcpy(dev_priv, framebuffer.dev_priv, framebuffer.dev_priv_size); - framebuffer.dev_priv = dev_priv; - framebuffer.width = pScreen->width; framebuffer.height = pScreen->height; @@ -1101,28 +1105,30 @@ __glXDRIscreenProbe(ScreenPtr pScreen) goto handle_error; } - screen->driScreen.private = - (*createNewScreen)(pScreen->myNum, - &screen->driScreen, - &ddx_version, - &dri_version, - &drm_version, - &framebuffer, - pSAREA, - fd, - loader_extensions, - &screen->base.fbconfigs); + screen->driScreen = + (*screen->legacy->createNewScreen)(pScreen->myNum, + &ddx_version, + &dri_version, + &drm_version, + &framebuffer, + pSAREA, + fd, + loader_extensions, + &driConfigs, + screen); - if (screen->driScreen.private == NULL) { + screen->base.fbconfigs = glxConvertConfigs(screen->core, driConfigs); + + if (screen->driScreen == NULL) { LogMessage(X_ERROR, "AIGLX error: Calling driver entry point failed"); goto handle_error; } + initializeExtensions(screen); + DRIGetTexOffsetFuncs(pScreen, &screen->texOffsetStart, &screen->texOffsetFinish); - initializeExtensions(screen); - __glXScreenInit(&screen->base, pScreen); buffer_size = __glXGetExtensionString(screen->glx_enable_bits, NULL); @@ -1155,9 +1161,6 @@ __glXDRIscreenProbe(ScreenPtr pScreen) if (framebuffer.base != NULL) drmUnmap((drmAddress)framebuffer.base, framebuffer.size); - if (dev_priv != NULL) - xfree(dev_priv); - if (fd >= 0) drmCloseOnce(fd); diff --git a/GL/glx/glxdri2.c b/GL/glx/glxdri2.c index fecfb1977..40590c167 100644 --- a/GL/glx/glxdri2.c +++ b/GL/glx/glxdri2.c @@ -35,20 +35,18 @@ #include #include #include +#include #include #include #define _XF86DRI_SERVER_ #include -#include -#include #include #include #include "glxserver.h" #include "glxutil.h" -#include "glcontextmodes.h" #include "g_disptab.h" #include "glapitable.h" @@ -57,53 +55,56 @@ #include "dispatch.h" #include "extension_string.h" -#define containerOf(ptr, type, member) \ - (type *)( (char *)ptr - offsetof(type,member) ) - typedef struct __GLXDRIscreen __GLXDRIscreen; typedef struct __GLXDRIcontext __GLXDRIcontext; typedef struct __GLXDRIdrawable __GLXDRIdrawable; +typedef struct __GLXDRIconfig __GLXDRIconfig; struct __GLXDRIscreen { __GLXscreen base; - __DRIscreen driScreen; + __DRIscreen *driScreen; void *driver; int fd; xf86EnterVTProc *enterVT; xf86LeaveVTProc *leaveVT; - __DRIcopySubBufferExtension *copySubBuffer; - __DRIswapControlExtension *swapControl; - __DRItexBufferExtension *texBuffer; + const __DRIcoreExtension *core; + const __DRIcopySubBufferExtension *copySubBuffer; + const __DRIswapControlExtension *swapControl; + const __DRItexBufferExtension *texBuffer; unsigned char glx_enable_bits[__GLX_EXT_BYTES]; }; struct __GLXDRIcontext { - __GLXcontext base; - __DRIcontext driContext; - drm_context_t hwContext; + __GLXcontext base; + __DRIcontext *driContext; }; struct __GLXDRIdrawable { - __GLXdrawable base; - __DRIdrawable driDrawable; + __GLXdrawable base; + __DRIdrawable *driDrawable; + __GLXDRIscreen *screen; }; -static const char CREATE_NEW_SCREEN_FUNC[] = __DRI2_CREATE_NEW_SCREEN_STRING; +struct __GLXDRIconfig { + __GLXconfig config; + const __DRIconfig *driConfig; +}; static void __glXDRIdrawableDestroy(__GLXdrawable *drawable) { __GLXDRIdrawable *private = (__GLXDRIdrawable *) drawable; - - (*private->driDrawable.destroyDrawable)(&private->driDrawable); + const __DRIcoreExtension *core = private->screen->core; + + (*core->destroyDrawable)(private->driDrawable); /* If the X window was destroyed, the dri DestroyWindow hook will * aready have taken care of this, so only call if pDraw isn't NULL. */ if (drawable->pDraw != NULL) - DRI2DestroyDrawable(drawable->pDraw->pScreen, drawable->pDraw); + DRI2DestroyDrawable(drawable->pDraw); xfree(private); } @@ -118,25 +119,25 @@ __glXDRIdrawableResize(__GLXdrawable *glxPriv) } static GLboolean -__glXDRIdrawableSwapBuffers(__GLXdrawable *basePrivate) +__glXDRIdrawableSwapBuffers(__GLXdrawable *drawable) { - __GLXDRIdrawable *private = (__GLXDRIdrawable *) basePrivate; + __GLXDRIdrawable *private = (__GLXDRIdrawable *) drawable; + const __DRIcoreExtension *core = private->screen->core; - (*private->driDrawable.swapBuffers)(&private->driDrawable); + (*core->swapBuffers)(private->driDrawable); return TRUE; } static int -__glXDRIdrawableSwapInterval(__GLXdrawable *baseDrawable, int interval) +__glXDRIdrawableSwapInterval(__GLXdrawable *drawable, int interval) { - __GLXDRIdrawable *draw = (__GLXDRIdrawable *) baseDrawable; - __GLXDRIscreen *screen = (__GLXDRIscreen *) - glxGetScreen(baseDrawable->pDraw->pScreen); + __GLXDRIdrawable *private = (__GLXDRIdrawable *) drawable; + const __DRIswapControlExtension *swapControl = private->screen->swapControl; - if (screen->swapControl) - screen->swapControl->setSwapInterval(&draw->driDrawable, interval); + if (swapControl) + swapControl->setSwapInterval(private->driDrawable, interval); return 0; } @@ -147,22 +148,20 @@ __glXDRIdrawableCopySubBuffer(__GLXdrawable *basePrivate, int x, int y, int w, int h) { __GLXDRIdrawable *private = (__GLXDRIdrawable *) basePrivate; - __GLXDRIscreen *screen = (__GLXDRIscreen *) - glxGetScreen(basePrivate->pDraw->pScreen); + const __DRIcopySubBufferExtension *copySubBuffer = + private->screen->copySubBuffer; - if (screen->copySubBuffer) - screen->copySubBuffer->copySubBuffer(&private->driDrawable, - x, y, w, h); + if (copySubBuffer) + (*copySubBuffer->copySubBuffer)(private->driDrawable, x, y, w, h); } static void __glXDRIcontextDestroy(__GLXcontext *baseContext) { __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext; - __GLXDRIscreen *screen = (__GLXDRIscreen *) baseContext->pGlxScreen; + __GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen; - context->driContext.destroyContext(&context->driContext); - drmDestroyContext(screen->fd, context->hwContext); + (*screen->core->destroyContext)(context->driContext); __glXContextDestroy(&context->base); xfree(context); } @@ -173,18 +172,20 @@ __glXDRIcontextMakeCurrent(__GLXcontext *baseContext) __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext; __GLXDRIdrawable *draw = (__GLXDRIdrawable *) baseContext->drawPriv; __GLXDRIdrawable *read = (__GLXDRIdrawable *) baseContext->readPriv; + __GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen; - return (*context->driContext.bindContext)(&context->driContext, - &draw->driDrawable, - &read->driDrawable); + return (*screen->core->bindContext)(context->driContext, + draw->driDrawable, + read->driDrawable); } static int __glXDRIcontextLoseCurrent(__GLXcontext *baseContext) { __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext; + __GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen; - return (*context->driContext.unbindContext)(&context->driContext); + return (*screen->core->unbindContext)(context->driContext); } static int @@ -193,13 +194,10 @@ __glXDRIcontextCopy(__GLXcontext *baseDst, __GLXcontext *baseSrc, { __GLXDRIcontext *dst = (__GLXDRIcontext *) baseDst; __GLXDRIcontext *src = (__GLXDRIcontext *) baseSrc; + __GLXDRIscreen *screen = (__GLXDRIscreen *) dst->base.pGlxScreen; - /* FIXME: We will need to add DRIcontext::copyContext for this. */ - - (void) dst; - (void) src; - - return FALSE; + return (*screen->core->copyContext)(dst->driContext, + src->driContext, mask); } static int @@ -208,10 +206,11 @@ __glXDRIcontextForceCurrent(__GLXcontext *baseContext) __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext; __GLXDRIdrawable *draw = (__GLXDRIdrawable *) baseContext->drawPriv; __GLXDRIdrawable *read = (__GLXDRIdrawable *) baseContext->readPriv; + __GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen; - return (*context->driContext.bindContext)(&context->driContext, - &draw->driDrawable, - &read->driDrawable); + return (*screen->core->bindContext)(context->driContext, + draw->driDrawable, + read->driDrawable); } #ifdef __DRI_TEX_BUFFER @@ -221,19 +220,16 @@ __glXDRIbindTexImage(__GLXcontext *baseContext, int buffer, __GLXdrawable *glxPixmap) { - ScreenPtr pScreen = glxPixmap->pDraw->pScreen; - __GLXDRIscreen * const screen = (__GLXDRIscreen *) glxGetScreen(pScreen); - PixmapPtr pixmap; - __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext; __GLXDRIdrawable *drawable = (__GLXDRIdrawable *) glxPixmap; + const __DRItexBufferExtension *texBuffer = drawable->screen->texBuffer; + __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext; - if (screen->texBuffer == NULL) + if (texBuffer == NULL) return Success; - pixmap = (PixmapPtr) glxPixmap->pDraw; - screen->texBuffer->setTexBuffer(&context->driContext, - glxPixmap->target, - &drawable->driDrawable); + texBuffer->setTexBuffer(context->driContext, + glxPixmap->target, + drawable->driDrawable); return Success; } @@ -277,7 +273,7 @@ __glXDRIscreenDestroy(__GLXscreen *baseScreen) { __GLXDRIscreen *screen = (__GLXDRIscreen *) baseScreen; - screen->driScreen.destroyScreen(&screen->driScreen); + (*screen->core->destroyScreen)(screen->driScreen); dlclose(screen->driver); @@ -288,16 +284,18 @@ __glXDRIscreenDestroy(__GLXscreen *baseScreen) static __GLXcontext * __glXDRIscreenCreateContext(__GLXscreen *baseScreen, - __GLcontextModes *modes, + __GLXconfig *glxConfig, __GLXcontext *baseShareContext) { __GLXDRIscreen *screen = (__GLXDRIscreen *) baseScreen; __GLXDRIcontext *context, *shareContext; + __GLXDRIconfig *config = (__GLXDRIconfig *) glxConfig; + const __DRIcoreExtension *core = screen->core; __DRIcontext *driShare; shareContext = (__GLXDRIcontext *) baseShareContext; if (shareContext) - driShare = &shareContext->driContext; + driShare = shareContext->driContext; else driShare = NULL; @@ -313,16 +311,9 @@ __glXDRIscreenCreateContext(__GLXscreen *baseScreen, context->base.forceCurrent = __glXDRIcontextForceCurrent; context->base.textureFromPixmap = &__glXDRItextureFromPixmap; - if (drmCreateContext(screen->fd, &context->hwContext)) - return GL_FALSE; - - context->driContext.private = - screen->driScreen.createNewContext(&screen->driScreen, - modes, - 0, /* render type */ - driShare, - context->hwContext, - &context->driContext); + context->driContext = + (*core->createNewContext)(screen->driScreen, + config->driConfig, driShare, context); return &context->base; } @@ -332,13 +323,13 @@ __glXDRIscreenCreateDrawable(__GLXscreen *screen, DrawablePtr pDraw, int type, XID drawId, - __GLcontextModes *modes) + __GLXconfig *glxConfig) { __GLXDRIscreen *driScreen = (__GLXDRIscreen *) screen; + __GLXDRIconfig *config = (__GLXDRIconfig *) glxConfig; __GLXDRIdrawable *private; GLboolean retval; - drm_drawable_t hwDrawable; - unsigned int head; + unsigned int handle, head; private = xalloc(sizeof *private); if (private == NULL) @@ -346,8 +337,9 @@ __glXDRIscreenCreateDrawable(__GLXscreen *screen, memset(private, 0, sizeof *private); + private->screen = driScreen; if (!__glXDrawableInit(&private->base, screen, - pDraw, type, drawId, modes)) { + pDraw, type, drawId, glxConfig)) { xfree(private); return NULL; } @@ -357,14 +349,12 @@ __glXDRIscreenCreateDrawable(__GLXscreen *screen, private->base.swapBuffers = __glXDRIdrawableSwapBuffers; private->base.copySubBuffer = __glXDRIdrawableCopySubBuffer; - retval = DRI2CreateDrawable(screen->pScreen, pDraw, - &hwDrawable, &head); + retval = DRI2CreateDrawable(pDraw, &handle, &head); - private->driDrawable.private = - (driScreen->driScreen.createNewDrawable)(&driScreen->driScreen, - modes, - &private->driDrawable, - hwDrawable, head, 0, NULL); + private->driDrawable = + (*driScreen->core->createNewDrawable)(driScreen->driScreen, + config->driConfig, + handle, head, private); return &private->base; } @@ -385,44 +375,43 @@ getUST(int64_t *ust) } } -static void __glXReportDamage(__DRIdrawable *driDraw, - int x, int y, - drm_clip_rect_t *rects, int num_rects, - GLboolean front_buffer) -{ - __GLXDRIdrawable *drawable = - containerOf(driDraw, __GLXDRIdrawable, driDrawable); - DrawablePtr pDraw = drawable->base.pDraw; - RegionRec region; - - REGION_INIT(pDraw->pScreen, ®ion, (BoxPtr) rects, num_rects); - REGION_TRANSLATE(pScreen, ®ion, pDraw->x, pDraw->y); - DamageDamageRegion(pDraw, ®ion); - REGION_UNINIT(pDraw->pScreen, ®ion); -} - -/* Table of functions that we export to the driver. */ -static const __DRIcontextModesExtension contextModesExtension = { - { __DRI_CONTEXT_MODES, __DRI_CONTEXT_MODES_VERSION }, - _gl_context_modes_create, - _gl_context_modes_destroy, -}; - static const __DRIsystemTimeExtension systemTimeExtension = { { __DRI_SYSTEM_TIME, __DRI_SYSTEM_TIME_VERSION }, getUST, NULL, }; -static const __DRIdamageExtension damageExtension = { - { __DRI_DAMAGE, __DRI_DAMAGE_VERSION }, - __glXReportDamage, +static void dri2ReemitDrawableInfo(__DRIdrawable *draw, unsigned int *tail, + void *loaderPrivate) +{ + __GLXDRIdrawable *pdraw = loaderPrivate; + + DRI2ReemitDrawableInfo(pdraw->base.pDraw, tail); +} + +static void dri2PostDamage(__DRIdrawable *draw, + struct drm_clip_rect *rects, + int numRects, void *loaderPrivate) +{ + __GLXDRIdrawable *drawable = loaderPrivate; + DrawablePtr pDraw = drawable->base.pDraw; + RegionRec region; + + REGION_INIT(pDraw->pScreen, ®ion, (BoxPtr) rects, numRects); + REGION_TRANSLATE(pScreen, ®ion, pDraw->x, pDraw->y); + DamageDamageRegion(pDraw, ®ion); + REGION_UNINIT(pDraw->pScreen, ®ion); +} + +static const __DRIloaderExtension loaderExtension = { + { __DRI_LOADER, __DRI_LOADER_VERSION }, + dri2ReemitDrawableInfo, + dri2PostDamage }; static const __DRIextension *loader_extensions[] = { - &contextModesExtension.base, &systemTimeExtension.base, - &damageExtension.base, + &loaderExtension.base, NULL }; @@ -463,11 +452,13 @@ initializeExtensions(__GLXDRIscreen *screen) const __DRIextension **extensions; int i; - extensions = screen->driScreen.getExtensions(&screen->driScreen); + extensions = screen->core->getExtensions(screen->driScreen); + for (i = 0; extensions[i]; i++) { #ifdef __DRI_COPY_SUB_BUFFER if (strcmp(extensions[i]->name, __DRI_COPY_SUB_BUFFER) == 0) { - screen->copySubBuffer = (__DRIcopySubBufferExtension *) extensions[i]; + screen->copySubBuffer = + (const __DRIcopySubBufferExtension *) extensions[i]; __glXEnableExtension(screen->glx_enable_bits, "GLX_MESA_copy_sub_buffer"); @@ -477,7 +468,8 @@ initializeExtensions(__GLXDRIscreen *screen) #ifdef __DRI_SWAP_CONTROL if (strcmp(extensions[i]->name, __DRI_SWAP_CONTROL) == 0) { - screen->swapControl = (__DRIswapControlExtension *) extensions[i]; + screen->swapControl = + (const __DRIswapControlExtension *) extensions[i]; __glXEnableExtension(screen->glx_enable_bits, "GLX_SGI_swap_control"); __glXEnableExtension(screen->glx_enable_bits, @@ -489,7 +481,8 @@ initializeExtensions(__GLXDRIscreen *screen) #ifdef __DRI_TEX_BUFFER if (strcmp(extensions[i]->name, __DRI_TEX_BUFFER) == 0) { - screen->texBuffer = (__DRItexBufferExtension *) extensions[i]; + screen->texBuffer = + (const __DRItexBufferExtension *) extensions[i]; /* GLX_EXT_texture_from_pixmap is always enabled. */ LogMessage(X_INFO, "AIGLX: GLX_EXT_texture_from_pixmap backed by buffer objects\n"); } @@ -498,27 +491,176 @@ initializeExtensions(__GLXDRIscreen *screen) } } +#define __ATTRIB(attrib, field) \ + { attrib, offsetof(__GLXconfig, field) } + +static const struct { unsigned int attrib, offset; } attribMap[] = { + __ATTRIB(__DRI_ATTRIB_BUFFER_SIZE, rgbBits), + __ATTRIB(__DRI_ATTRIB_LEVEL, level), + __ATTRIB(__DRI_ATTRIB_RED_SIZE, redBits), + __ATTRIB(__DRI_ATTRIB_GREEN_SIZE, greenBits), + __ATTRIB(__DRI_ATTRIB_BLUE_SIZE, blueBits), + __ATTRIB(__DRI_ATTRIB_ALPHA_SIZE, alphaBits), + __ATTRIB(__DRI_ATTRIB_DEPTH_SIZE, depthBits), + __ATTRIB(__DRI_ATTRIB_STENCIL_SIZE, stencilBits), + __ATTRIB(__DRI_ATTRIB_ACCUM_RED_SIZE, accumRedBits), + __ATTRIB(__DRI_ATTRIB_ACCUM_GREEN_SIZE, accumGreenBits), + __ATTRIB(__DRI_ATTRIB_ACCUM_BLUE_SIZE, accumBlueBits), + __ATTRIB(__DRI_ATTRIB_ACCUM_ALPHA_SIZE, accumAlphaBits), + __ATTRIB(__DRI_ATTRIB_SAMPLE_BUFFERS, sampleBuffers), + __ATTRIB(__DRI_ATTRIB_SAMPLES, samples), + __ATTRIB(__DRI_ATTRIB_DOUBLE_BUFFER, doubleBufferMode), + __ATTRIB(__DRI_ATTRIB_STEREO, stereoMode), + __ATTRIB(__DRI_ATTRIB_AUX_BUFFERS, numAuxBuffers), + __ATTRIB(__DRI_ATTRIB_TRANSPARENT_TYPE, transparentPixel), + __ATTRIB(__DRI_ATTRIB_TRANSPARENT_INDEX_VALUE, transparentPixel), + __ATTRIB(__DRI_ATTRIB_TRANSPARENT_RED_VALUE, transparentRed), + __ATTRIB(__DRI_ATTRIB_TRANSPARENT_GREEN_VALUE, transparentGreen), + __ATTRIB(__DRI_ATTRIB_TRANSPARENT_BLUE_VALUE, transparentBlue), + __ATTRIB(__DRI_ATTRIB_TRANSPARENT_ALPHA_VALUE, transparentAlpha), + __ATTRIB(__DRI_ATTRIB_FLOAT_MODE, floatMode), + __ATTRIB(__DRI_ATTRIB_RED_MASK, redMask), + __ATTRIB(__DRI_ATTRIB_GREEN_MASK, greenMask), + __ATTRIB(__DRI_ATTRIB_BLUE_MASK, blueMask), + __ATTRIB(__DRI_ATTRIB_ALPHA_MASK, alphaMask), + __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_WIDTH, maxPbufferWidth), + __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_HEIGHT, maxPbufferHeight), + __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_PIXELS, maxPbufferPixels), + __ATTRIB(__DRI_ATTRIB_OPTIMAL_PBUFFER_WIDTH, optimalPbufferWidth), + __ATTRIB(__DRI_ATTRIB_OPTIMAL_PBUFFER_HEIGHT, optimalPbufferHeight), + __ATTRIB(__DRI_ATTRIB_SWAP_METHOD, swapMethod), + __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGB, bindToTextureRgb), + __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGBA, bindToTextureRgba), + __ATTRIB(__DRI_ATTRIB_BIND_TO_MIPMAP_TEXTURE, bindToMipmapTexture), + __ATTRIB(__DRI_ATTRIB_YINVERTED, yInverted), +}; + +#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0])) + +static void +setScalar(__GLXconfig *config, unsigned int attrib, unsigned int value) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(attribMap); i++) + if (attribMap[i].attrib == attrib) { + *(unsigned int *) ((char *) config + attribMap[i].offset) = value; + return; + } +} + +static __GLXconfig * +createModeFromConfig(const __DRIcoreExtension *core, + const __DRIconfig *driConfig, + unsigned int visualType) +{ + __GLXDRIconfig *config; + unsigned int attrib, value; + int i; + + config = xalloc(sizeof *config); + + config->driConfig = driConfig; + + i = 0; + while (core->indexConfigAttrib(driConfig, i++, &attrib, &value)) { + switch (attrib) { + case __DRI_ATTRIB_RENDER_TYPE: + if (value & __DRI_ATTRIB_RGBA_BIT) { + config->config.renderType |= GLX_RGBA_BIT; + config->config.rgbMode = GL_TRUE; + } else if (value & __DRI_ATTRIB_COLOR_INDEX_BIT) { + config->config.renderType |= GLX_COLOR_INDEX_BIT; + config->config.rgbMode = GL_FALSE; + } else { + config->config.renderType = 0; + config->config.rgbMode = GL_FALSE; + } + break; + case __DRI_ATTRIB_CONFIG_CAVEAT: + if (value & __DRI_ATTRIB_NON_CONFORMANT_CONFIG) + config->config.visualRating = GLX_NON_CONFORMANT_CONFIG; + else if (value & __DRI_ATTRIB_SLOW_BIT) + config->config.visualRating = GLX_SLOW_CONFIG; + else + config->config.visualRating = GLX_NONE; + break; + case __DRI_ATTRIB_BIND_TO_TEXTURE_TARGETS: + config->config.bindToTextureTargets = 0; + if (value & __DRI_ATTRIB_TEXTURE_1D_BIT) + config->config.bindToTextureTargets |= GLX_TEXTURE_1D_BIT_EXT; + if (value & __DRI_ATTRIB_TEXTURE_2D_BIT) + config->config.bindToTextureTargets |= GLX_TEXTURE_2D_BIT_EXT; + if (value & __DRI_ATTRIB_TEXTURE_RECTANGLE_BIT) + config->config.bindToTextureTargets |= GLX_TEXTURE_RECTANGLE_BIT_EXT; + break; + default: + setScalar(&config->config, attrib, value); + break; + } + } + + config->config.next = NULL; + config->config.xRenderable = GL_TRUE; + config->config.visualType = visualType; + config->config.drawableType = GLX_WINDOW_BIT | GLX_PIXMAP_BIT; + + return &config->config; +} + +__GLXconfig * +glxConvertConfigs(const __DRIcoreExtension *core, const __DRIconfig **configs); + +__GLXconfig * +glxConvertConfigs(const __DRIcoreExtension *core, const __DRIconfig **configs) +{ + __GLXconfig head, *tail; + int i; + + tail = &head; + head.next = NULL; + + for (i = 0; configs[i]; i++) { + tail->next = createModeFromConfig(core, + configs[i], GLX_TRUE_COLOR); + if (tail->next == NULL) + break; + + tail = tail->next; + } + + for (i = 0; configs[i]; i++) { + tail->next = createModeFromConfig(core, + configs[i], GLX_DIRECT_COLOR); + if (tail->next == NULL) + break; + + tail = tail->next; + } + + return head.next; +} + static __GLXscreen * __glXDRIscreenProbe(ScreenPtr pScreen) { - __DRI2_CREATE_NEW_SCREEN_FUNC *createNewScreen; const char *driverName; __GLXDRIscreen *screen; char filename[128]; size_t buffer_size; ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; unsigned int sareaHandle; + const __DRIextension **extensions; + const __DRIconfig **driConfigs; + int i; screen = xalloc(sizeof *screen); if (screen == NULL) - return NULL; + return NULL; memset(screen, 0, sizeof *screen); if (!xf86LoaderCheckSymbol("DRI2Connect") || - !DRI2Connect(pScreen, - &screen->fd, - &driverName, - &sareaHandle)) { + !DRI2Connect(pScreen, &screen->fd, &driverName, &sareaHandle)) { LogMessage(X_INFO, "AIGLX: Screen %d is not DRI2 capable\n", pScreen->myNum); return NULL; @@ -532,8 +674,8 @@ __glXDRIscreenProbe(ScreenPtr pScreen) __glXInitExtensionEnableBits(screen->glx_enable_bits); - snprintf(filename, sizeof filename, "%s/%s_dri.so", - dri_driver_path, driverName); + snprintf(filename, sizeof filename, + "%s/%s_dri.so", dri_driver_path, driverName); screen->driver = dlopen(filename, RTLD_LAZY | RTLD_LOCAL); if (screen->driver == NULL) { @@ -542,28 +684,43 @@ __glXDRIscreenProbe(ScreenPtr pScreen) goto handle_error; } - createNewScreen = dlsym(screen->driver, CREATE_NEW_SCREEN_FUNC); - if (createNewScreen == NULL) { - LogMessage(X_ERROR, "AIGLX error: dlsym for %s failed (%s)\n", - CREATE_NEW_SCREEN_FUNC, dlerror()); - goto handle_error; + extensions = dlsym(screen->driver, __DRI_DRIVER_EXTENSIONS); + if (extensions == NULL) { + LogMessage(X_ERROR, "AIGLX error: %s exports no extensions (%s)\n", + driverName, dlerror()); + goto handle_error; } - screen->driScreen.private = - (*createNewScreen)(pScreen->myNum, - &screen->driScreen, - screen->fd, - sareaHandle, - loader_extensions, - &screen->base.fbconfigs); + for (i = 0; extensions[i]; i++) { + if (strcmp(extensions[i]->name, __DRI_CORE) == 0 && + extensions[i]->version >= __DRI_CORE_VERSION) { + screen->core = (const __DRIcoreExtension *) extensions[i]; + } + } - if (screen->driScreen.private == NULL) { + if (screen->core == NULL) { + LogMessage(X_ERROR, "AIGLX error: %s exports no DRI extension\n", + driverName); + goto handle_error; + } + + screen->driScreen = + (*screen->core->createNewScreen)(pScreen->myNum, + screen->fd, + sareaHandle, + loader_extensions, + &driConfigs, + screen); + + if (screen->driScreen == NULL) { LogMessage(X_ERROR, "AIGLX error: Calling driver entry point failed"); goto handle_error; } initializeExtensions(screen); + screen->base.fbconfigs = glxConvertConfigs(screen->core, driConfigs); + __glXScreenInit(&screen->base, pScreen); buffer_size = __glXGetExtensionString(screen->glx_enable_bits, NULL); diff --git a/GL/glx/glxglcore.c b/GL/glx/glxglcore.c index 0750e1282..bbfa02b79 100644 --- a/GL/glx/glxglcore.c +++ b/GL/glx/glxglcore.c @@ -46,7 +46,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include #include -#include "glcontextmodes.h" #include "os.h" typedef struct __GLXMESAscreen __GLXMESAscreen; @@ -120,7 +119,7 @@ static __GLXdrawable * __glXMesaScreenCreateDrawable(__GLXscreen *screen, DrawablePtr pDraw, int type, XID drawId, - __GLcontextModes *modes) + __GLXconfig *modes) { __GLXMESAdrawable *glxPriv; XMesaVisual xm_vis; @@ -217,7 +216,7 @@ __glXMesaContextForceCurrent(__GLXcontext *baseContext) static __GLXcontext * __glXMesaScreenCreateContext(__GLXscreen *screen, - __GLcontextModes *modes, + __GLXconfig *config, __GLXcontext *baseShareContext) { __GLXMESAcontext *context; @@ -232,7 +231,7 @@ __glXMesaScreenCreateContext(__GLXscreen *screen, memset(context, 0, sizeof *context); context->base.pGlxScreen = screen; - context->base.modes = modes; + context->base.config = config; context->base.destroy = __glXMesaContextDestroy; context->base.makeCurrent = __glXMesaContextMakeCurrent; @@ -240,10 +239,10 @@ __glXMesaScreenCreateContext(__GLXscreen *screen, context->base.copy = __glXMesaContextCopy; context->base.forceCurrent = __glXMesaContextForceCurrent; - xm_vis = find_mesa_visual(screen, modes->fbconfigID); + xm_vis = find_mesa_visual(screen, config->fbconfigID); if (!xm_vis) { ErrorF("find_mesa_visual returned NULL for visualID = 0x%04x\n", - modes->visualID); + config->visualID); xfree(context); return NULL; } @@ -282,11 +281,11 @@ static XMesaVisual find_mesa_visual(__GLXscreen *screen, XID fbconfigID) { __GLXMESAscreen *mesaScreen = (__GLXMESAscreen *) screen; - const __GLcontextModes *modes; + const __GLXconfig *config; unsigned i = 0; - for (modes = screen->fbconfigs; modes != NULL; modes = modes->next) { - if (modes->fbconfigID == fbconfigID) + for (config = screen->fbconfigs; config != NULL; config = config->next) { + if (config->fbconfigID == fbconfigID) return mesaScreen->xm_vis[i]; i++; } @@ -298,18 +297,31 @@ const static int numBack = 2; const static int numDepth = 2; const static int numStencil = 2; -static __GLcontextModes * +static const int glx_visual_types[] = { + GLX_STATIC_GRAY, + GLX_GRAY_SCALE, + GLX_STATIC_COLOR, + GLX_PSEUDO_COLOR, + GLX_TRUE_COLOR, + GLX_DIRECT_COLOR +}; + +static __GLXconfig * createFBConfigsForVisual(__GLXscreen *screen, ScreenPtr pScreen, - VisualPtr visual, __GLcontextModes *config) + VisualPtr visual, __GLXconfig *tail) { int back, depth, stencil; + __GLXconfig *config; /* FIXME: Ok, I'm making all this up... anybody has a better idea? */ for (back = numBack - 1; back >= 0; back--) for (depth = 0; depth < numDepth; depth++) for (stencil = 0; stencil < numStencil; stencil++) { - config->visualType = _gl_convert_from_x_visual_type(visual->class); + config->next = xalloc(sizeof *config); + config = config->next; + + config->visualType = glx_visual_types[visual->class]; config->xRenderable = GL_TRUE; config->drawableType = GLX_WINDOW_BIT | GLX_PIXMAP_BIT; config->rgbMode = (visual->class >= TrueColor); @@ -333,35 +345,35 @@ createFBConfigsForVisual(__GLXscreen *screen, ScreenPtr pScreen, config->alphaMask = 0; config->rgbBits = config->rgbMode ? visual->nplanes : 0; config->indexBits = config->colorIndexMode ? visual->nplanes : 0; - config = config->next; } - return config; + return tail; } static void createFBConfigs(__GLXscreen *pGlxScreen, ScreenPtr pScreen) { - __GLcontextModes *configs; + __GLXconfig head, *tail; int i; /* We assume here that each existing visual correspond to a * different visual class. Note, this runs before COMPOSITE adds * its visual, so it's not entirely crazy. */ pGlxScreen->numFBConfigs = pScreen->numVisuals * numBack * numDepth * numStencil; - pGlxScreen->fbconfigs = _gl_context_modes_create(pGlxScreen->numFBConfigs, - sizeof *configs); - - configs = pGlxScreen->fbconfigs; + + head.next = NULL; + tail = &head; for (i = 0; i < pScreen->numVisuals; i++) - configs = createFBConfigsForVisual(pGlxScreen, pScreen, - &pScreen->visuals[i], configs); + tail = createFBConfigsForVisual(pGlxScreen, pScreen, + &pScreen->visuals[i], tail); + + pGlxScreen->fbconfigs = head.next; } static void createMesaVisuals(__GLXMESAscreen *pMesaScreen) { - __GLcontextModes *config; + __GLXconfig *config; ScreenPtr pScreen; VisualPtr visual = NULL; int i, j; diff --git a/GL/glx/glxscreens.c b/GL/glx/glxscreens.c index 6575b271d..b49a775b5 100644 --- a/GL/glx/glxscreens.c +++ b/GL/glx/glxscreens.c @@ -37,6 +37,7 @@ #include #endif +#include #include #include #include @@ -46,7 +47,6 @@ #include "glxserver.h" #include "glxutil.h" #include "glxext.h" -#include "glcontextmodes.h" static DevPrivateKey glxScreenPrivateKey = &glxScreenPrivateKey; @@ -280,10 +280,23 @@ void GlxSetVisualConfigs(int nconfigs, * call it. */ } +GLint glxConvertToXVisualType(int visualType) +{ + static const int x_visual_types[] = { + TrueColor, DirectColor, + PseudoColor, StaticColor, + GrayScale, StaticGray + }; + + return ( (unsigned) (visualType - GLX_TRUE_COLOR) < 6 ) + ? x_visual_types[ visualType - GLX_TRUE_COLOR ] : -1; +} + + static void filterOutNativeConfigs(__GLXscreen *pGlxScreen) { - __GLcontextModes *m, *next, *native_modes, **last; + __GLXconfig *m, *next, **last; ScreenPtr pScreen = pGlxScreen->pScreen; int i, depth; @@ -305,12 +318,12 @@ filterOutNativeConfigs(__GLXscreen *pGlxScreen) } static XID -findVisualForConfig(ScreenPtr pScreen, __GLcontextModes *m) +findVisualForConfig(ScreenPtr pScreen, __GLXconfig *m) { int i; for (i = 0; i < pScreen->numVisuals; i++) { - if (_gl_convert_to_x_visual_type(m->visualType) == pScreen->visuals[i].class) + if (glxConvertToXVisualType(m->visualType) == pScreen->visuals[i].class) return pScreen->visuals[i].vid; } @@ -405,10 +418,10 @@ findFirstSet(unsigned int v) } static void -initGlxVisual(VisualPtr visual, __GLcontextModes *config) +initGlxVisual(VisualPtr visual, __GLXconfig *config) { config->visualID = visual->vid; - visual->class = _gl_convert_to_x_visual_type(config->visualType); + visual->class = glxConvertToXVisualType(config->visualType); visual->bitsPerRGBValue = config->redBits; visual->ColormapEntries = 1 << config->redBits; visual->nplanes = config->redBits + config->greenBits + config->blueBits; @@ -426,15 +439,15 @@ typedef struct { GLboolean depthBuffer; } FBConfigTemplateRec, *FBConfigTemplatePtr; -static __GLcontextModes * +static __GLXconfig * pickFBConfig(__GLXscreen *pGlxScreen, FBConfigTemplatePtr template, int class) { - __GLcontextModes *config; + __GLXconfig *config; for (config = pGlxScreen->fbconfigs; config != NULL; config = config->next) { if (config->visualRating != GLX_NONE) continue; - if (_gl_convert_to_x_visual_type(config->visualType) != class) + if (glxConvertToXVisualType(config->visualType) != class) continue; if ((config->doubleBufferMode > 0) != template->doubleBuffer) continue; @@ -450,32 +463,36 @@ pickFBConfig(__GLXscreen *pGlxScreen, FBConfigTemplatePtr template, int class) static void addMinimalSet(__GLXscreen *pGlxScreen) { - __GLcontextModes *config; + __GLXconfig *config; VisualPtr visuals; - int i; + int i, j; FBConfigTemplateRec best = { GL_TRUE, GL_TRUE }; FBConfigTemplateRec minimal = { GL_FALSE, GL_FALSE }; pGlxScreen->visuals = xcalloc(pGlxScreen->pScreen->numVisuals, - sizeof (__GLcontextModes *)); + sizeof (__GLXconfig *)); if (pGlxScreen->visuals == NULL) { ErrorF("Failed to allocate for minimal set of GLX visuals\n"); return; } - pGlxScreen->numVisuals = pGlxScreen->pScreen->numVisuals; visuals = pGlxScreen->pScreen->visuals; - for (i = 0; i < pGlxScreen->numVisuals; i++) { + for (i = 0, j = 0; i < pGlxScreen->pScreen->numVisuals; i++) { if (visuals[i].nplanes == 32) config = pickFBConfig(pGlxScreen, &minimal, visuals[i].class); else config = pickFBConfig(pGlxScreen, &best, visuals[i].class); if (config == NULL) config = pGlxScreen->fbconfigs; - pGlxScreen->visuals[i] = config; - config->visualID = visuals[i].vid; + if (config == NULL) + continue; + + pGlxScreen->visuals[j] = config; + config->visualID = visuals[j].vid; + j++; } + pGlxScreen->numVisuals = j; } static void @@ -487,12 +504,12 @@ addTypicalSet(__GLXscreen *pGlxScreen) static void addFullSet(__GLXscreen *pGlxScreen) { - __GLcontextModes *config; + __GLXconfig *config; VisualPtr visuals; int i, depth; pGlxScreen->visuals = - xcalloc(pGlxScreen->numFBConfigs, sizeof (__GLcontextModes *)); + xcalloc(pGlxScreen->numFBConfigs, sizeof (__GLXconfig *)); if (pGlxScreen->visuals == NULL) { ErrorF("Failed to allocate for full set of GLX visuals\n"); return; @@ -522,7 +539,7 @@ void GlxSetVisualConfig(int config) void __glXScreenInit(__GLXscreen *pGlxScreen, ScreenPtr pScreen) { - __GLcontextModes *m; + __GLXconfig *m; int i; pGlxScreen->pScreen = pScreen; diff --git a/GL/glx/glxscreens.h b/GL/glx/glxscreens.h index f1eef912c..39d162d76 100644 --- a/GL/glx/glxscreens.h +++ b/GL/glx/glxscreens.h @@ -40,8 +40,6 @@ ** */ -#include "GL/internal/glcore.h" - typedef struct { void * (* queryHyperpipeNetworkFunc)(int, int *, int *); void * (* queryHyperpipeConfigFunc)(int, int, int *, int *); @@ -57,6 +55,84 @@ typedef struct { void __glXHyperpipeInit(int screen, __GLXHyperpipeExtensionFuncs *funcs); void __glXSwapBarrierInit(int screen, __GLXSwapBarrierExtensionFuncs *funcs); +typedef struct __GLXconfig __GLXconfig; +struct __GLXconfig { + __GLXconfig *next; + GLboolean rgbMode; + GLboolean floatMode; + GLboolean colorIndexMode; + GLuint doubleBufferMode; + GLuint stereoMode; + + GLboolean haveAccumBuffer; + GLboolean haveDepthBuffer; + GLboolean haveStencilBuffer; + + GLint redBits, greenBits, blueBits, alphaBits; /* bits per comp */ + GLuint redMask, greenMask, blueMask, alphaMask; + GLint rgbBits; /* total bits for rgb */ + GLint indexBits; /* total bits for colorindex */ + + GLint accumRedBits, accumGreenBits, accumBlueBits, accumAlphaBits; + GLint depthBits; + GLint stencilBits; + + GLint numAuxBuffers; + + GLint level; + + GLint pixmapMode; + + /* GLX */ + GLint visualID; + GLint visualType; /**< One of the GLX X visual types. (i.e., + * \c GLX_TRUE_COLOR, etc.) + */ + + /* EXT_visual_rating / GLX 1.2 */ + GLint visualRating; + + /* EXT_visual_info / GLX 1.2 */ + GLint transparentPixel; + /* colors are floats scaled to ints */ + GLint transparentRed, transparentGreen, transparentBlue, transparentAlpha; + GLint transparentIndex; + + /* ARB_multisample / SGIS_multisample */ + GLint sampleBuffers; + GLint samples; + + /* SGIX_fbconfig / GLX 1.3 */ + GLint drawableType; + GLint renderType; + GLint xRenderable; + GLint fbconfigID; + + /* SGIX_pbuffer / GLX 1.3 */ + GLint maxPbufferWidth; + GLint maxPbufferHeight; + GLint maxPbufferPixels; + GLint optimalPbufferWidth; /* Only for SGIX_pbuffer. */ + GLint optimalPbufferHeight; /* Only for SGIX_pbuffer. */ + + /* SGIX_visual_select_group */ + GLint visualSelectGroup; + + /* OML_swap_method */ + GLint swapMethod; + + GLint screen; + + /* EXT_texture_from_pixmap */ + GLint bindToTextureRgb; + GLint bindToTextureRgba; + GLint bindToMipmapTexture; + GLint bindToTextureTargets; + GLint yInverted; +}; + +GLint glxConvertToXVisualType(int visualType); + /* ** Screen dependent data. These methods are the interface between the DIX ** and DDX layers of the GLX server extension. The methods provide an @@ -67,14 +143,14 @@ struct __GLXscreen { void (*destroy) (__GLXscreen *screen); __GLXcontext *(*createContext) (__GLXscreen *screen, - __GLcontextModes *modes, + __GLXconfig *modes, __GLXcontext *shareContext); __GLXdrawable *(*createDrawable)(__GLXscreen *context, DrawablePtr pDraw, int type, XID drawId, - __GLcontextModes *modes); + __GLXconfig *modes); int (*swapInterval) (__GLXdrawable *drawable, int interval); @@ -84,11 +160,11 @@ struct __GLXscreen { ScreenPtr pScreen; /* Linked list of valid fbconfigs for this screen. */ - __GLcontextModes *fbconfigs; + __GLXconfig *fbconfigs; int numFBConfigs; /* Subset of fbconfigs that are exposed as GLX visuals. */ - __GLcontextModes **visuals; + __GLXconfig **visuals; GLint numVisuals; char *GLextensions; diff --git a/GL/glx/glxutil.c b/GL/glx/glxutil.c index f531ed954..11e9f898b 100644 --- a/GL/glx/glxutil.c +++ b/GL/glx/glxutil.c @@ -49,7 +49,6 @@ #include "glxutil.h" #include "GL/internal/glcore.h" #include "GL/glxint.h" -#include "glcontextmodes.h" /************************************************************************/ /* Context stuff */ @@ -140,13 +139,13 @@ __glXUnrefDrawable(__GLXdrawable *glxPriv) GLboolean __glXDrawableInit(__GLXdrawable *drawable, __GLXscreen *screen, DrawablePtr pDraw, int type, - XID drawId, __GLcontextModes *modes) + XID drawId, __GLXconfig *config) { drawable->pDraw = pDraw; drawable->type = type; drawable->drawId = drawId; drawable->refCount = 1; - drawable->modes = modes; + drawable->config = config; drawable->eventMask = 0; return GL_TRUE; diff --git a/GL/glx/glxutil.h b/GL/glx/glxutil.h index 6534c3f94..00c7b2084 100644 --- a/GL/glx/glxutil.h +++ b/GL/glx/glxutil.h @@ -51,7 +51,7 @@ extern void __glXUnrefDrawable(__GLXdrawable *glxPriv); extern GLboolean __glXDrawableInit(__GLXdrawable *drawable, __GLXscreen *screen, DrawablePtr pDraw, int type, XID drawID, - __GLcontextModes *modes); + __GLXconfig *config); /* context helper routines */ extern __GLXcontext *__glXLookupContextByTag(__GLXclientState*, GLXContextTag); diff --git a/GL/symlink-mesa.sh b/GL/symlink-mesa.sh index af9adbd94..47afdcd37 100755 --- a/GL/symlink-mesa.sh +++ b/GL/symlink-mesa.sh @@ -227,8 +227,6 @@ symlink_glx() { dst_dir glx action indirect_size.h - action glcontextmodes.c - action glcontextmodes.h action indirect_dispatch.c action indirect_dispatch.h action indirect_dispatch_swap.c diff --git a/configure.ac b/configure.ac index 959f0aedf..e72e3b99a 100644 --- a/configure.ac +++ b/configure.ac @@ -860,7 +860,7 @@ AM_CONDITIONAL(DRI2, test "x$DRI2" = xyes) if test "x$DRI2" = xyes; then # FIXME: Bump the versions once we have releases of these. AC_DEFINE(DRI2, 1, [Build DRI2 extension]) - PKG_CHECK_MODULES([DRIPROTO], [xf86driproto >= 2.0.3]) + PKG_CHECK_MODULES([DRI2PROTO], [dri2proto >= 1.0.0]) PKG_CHECK_MODULES([LIBDRM], [libdrm >= 2.3.1]) fi diff --git a/hw/xfree86/common/xf86Config.c b/hw/xfree86/common/xf86Config.c index 4a4aabcb5..8de742620 100644 --- a/hw/xfree86/common/xf86Config.c +++ b/hw/xfree86/common/xf86Config.c @@ -121,6 +121,7 @@ static ModuleDefault ModuleDefaults[] = { {.name = "freetype", .toLoad = TRUE, .load_opt=NULL}, {.name = "record", .toLoad = TRUE, .load_opt=NULL}, {.name = "dri", .toLoad = TRUE, .load_opt=NULL}, + {.name = "dri2", .toLoad = TRUE, .load_opt=NULL}, {.name = NULL, .toLoad = FALSE, .load_opt=NULL} }; diff --git a/hw/xfree86/dri2/Makefile.am b/hw/xfree86/dri2/Makefile.am index be3cea48f..844c91240 100644 --- a/hw/xfree86/dri2/Makefile.am +++ b/hw/xfree86/dri2/Makefile.am @@ -2,7 +2,7 @@ libdri2_la_LTLIBRARIES = libdri2.la libdri2_la_CFLAGS = \ -DHAVE_XORG_CONFIG_H \ -I@MESA_SOURCE@/include \ - @DIX_CFLAGS@ @DRIPROTO_CFLAGS@ @LIBDRM_CFLAGS@ \ + @DIX_CFLAGS@ @DRI2PROTO_CFLAGS@ @LIBDRM_CFLAGS@ \ -I$(top_srcdir)/hw/xfree86/common \ -I$(top_srcdir)/hw/xfree86/os-support/bus @@ -10,6 +10,7 @@ libdri2_la_LDFLAGS = -module -avoid-version @LIBDRM_LIBS@ libdri2_ladir = $(moduledir)/extensions libdri2_la_SOURCES = \ dri2.c \ - dri2.h + dri2.h \ + dri2ext.c sdk_HEADERS = dri2.h diff --git a/hw/xfree86/dri2/dri2.c b/hw/xfree86/dri2/dri2.c index d5273877e..74aef7196 100644 --- a/hw/xfree86/dri2/dri2.c +++ b/hw/xfree86/dri2/dri2.c @@ -38,6 +38,8 @@ #include "xf86Module.h" #include "scrnintstr.h" #include "windowstr.h" +#include "region.h" +#include "damage.h" #include "dri2.h" #include @@ -48,8 +50,9 @@ static DevPrivateKey dri2WindowPrivateKey = &dri2WindowPrivateKey; static DevPrivateKey dri2PixmapPrivateKey = &dri2PixmapPrivateKey; typedef struct _DRI2DrawablePriv { - drm_drawable_t drawable; - unsigned int handle; + unsigned int refCount; + unsigned int boHandle; + unsigned int dri2Handle; } DRI2DrawablePrivRec, *DRI2DrawablePrivPtr; typedef struct _DRI2Screen { @@ -58,6 +61,7 @@ typedef struct _DRI2Screen { void *sarea; unsigned int sareaSize; const char *driverName; + unsigned int nextHandle; __DRIEventBuffer *buffer; int locked; @@ -147,7 +151,7 @@ DRI2PostDrawableConfig(DrawablePtr pDraw) e = DRI2ScreenAllocEvent(ds, size); e->event_header = DRI2_EVENT_HEADER(DRI2_EVENT_DRAWABLE_CONFIG, size); - e->drawable = pPriv->drawable; + e->drawable = pPriv->dri2Handle; e->x = pDraw->x - pPixmap->screen_x; e->y = pDraw->y - pPixmap->screen_y; e->width = pDraw->width; @@ -164,7 +168,7 @@ DRI2PostDrawableConfig(DrawablePtr pDraw) } static void -DRI2PostBufferAttach(DrawablePtr pDraw) +DRI2PostBufferAttach(DrawablePtr pDraw, Bool force) { ScreenPtr pScreen = pDraw->pScreen; DRI2ScreenPtr ds = DRI2GetScreen(pScreen); @@ -173,7 +177,8 @@ DRI2PostBufferAttach(DrawablePtr pDraw) PixmapPtr pPixmap; __DRIBufferAttachEvent *e; size_t size; - unsigned int handle, flags; + unsigned int flags; + unsigned int boHandle; if (pDraw->type == DRAWABLE_WINDOW) { pWin = (WindowPtr) pDraw; @@ -187,22 +192,20 @@ DRI2PostBufferAttach(DrawablePtr pDraw) if (!pPriv) return; - size = sizeof *e; - - handle = ds->getPixmapHandle(pPixmap, &flags); - if (handle == 0 || handle == pPriv->handle) + boHandle = ds->getPixmapHandle(pPixmap, &flags); + if (boHandle == pPriv->boHandle && !force) return; + pPriv->boHandle = boHandle; + size = sizeof *e; e = DRI2ScreenAllocEvent(ds, size); e->event_header = DRI2_EVENT_HEADER(DRI2_EVENT_BUFFER_ATTACH, size); - e->drawable = pPriv->drawable; + e->drawable = pPriv->dri2Handle; e->buffer.attachment = DRI_DRAWABLE_BUFFER_FRONT_LEFT; - e->buffer.handle = handle; + e->buffer.handle = pPriv->boHandle; e->buffer.pitch = pPixmap->devKind; e->buffer.cpp = pPixmap->drawable.bitsPerPixel / 8; e->buffer.flags = flags; - - pPriv->handle = handle; } static void @@ -223,7 +226,7 @@ DRI2ClipNotify(WindowPtr pWin, int dx, int dy) } DRI2PostDrawableConfig(&pWin->drawable); - DRI2PostBufferAttach(&pWin->drawable); + DRI2PostBufferAttach(&pWin->drawable, FALSE); } static void @@ -262,10 +265,10 @@ DRI2CloseScreen(ScreenPtr pScreen) } Bool -DRI2CreateDrawable(ScreenPtr pScreen, DrawablePtr pDraw, - drm_drawable_t *pDrmDrawable, unsigned int *head) +DRI2CreateDrawable(DrawablePtr pDraw, + unsigned int *handle, unsigned int *head) { - DRI2ScreenPtr ds = DRI2GetScreen(pScreen); + DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen); WindowPtr pWin; PixmapPtr pPixmap; DRI2DrawablePrivPtr pPriv; @@ -283,47 +286,66 @@ DRI2CreateDrawable(ScreenPtr pScreen, DrawablePtr pDraw, } pPriv = dixLookupPrivate(devPrivates, key); - if (pPriv == NULL) { + if (pPriv != NULL) { + pPriv->refCount++; + } else { pPriv = xalloc(sizeof *pPriv); - if (drmCreateDrawable(ds->fd, &pPriv->drawable)) - return FALSE; - + pPriv->refCount = 1; + pPriv->boHandle = 0; + pPriv->dri2Handle = ds->nextHandle++; dixSetPrivate(devPrivates, key, pPriv); } - *pDrmDrawable = pPriv->drawable; - + *handle = pPriv->dri2Handle; *head = ds->buffer->head; + DRI2PostDrawableConfig(pDraw); - DRI2PostBufferAttach(pDraw); + DRI2PostBufferAttach(pDraw, TRUE); DRI2ScreenCommitEvents(ds); return TRUE; } void -DRI2DestroyDrawable(ScreenPtr pScreen, DrawablePtr pDraw) +DRI2DestroyDrawable(DrawablePtr pDraw) { - DRI2ScreenPtr ds = DRI2GetScreen(pScreen); - PixmapPtr pPixmap; - WindowPtr pWin; - DRI2DrawablePrivPtr pPriv; + PixmapPtr pPixmap; + WindowPtr pWin; + DRI2DrawablePrivPtr pPriv; + DevPrivateKey key; + PrivateRec **devPrivates; if (pDraw->type == DRAWABLE_WINDOW) { pWin = (WindowPtr) pDraw; - pPriv = dixLookupPrivate(&pWin->devPrivates, dri2WindowPrivateKey); - dixSetPrivate(&pWin->devPrivates, dri2WindowPrivateKey, NULL); + devPrivates = &pWin->devPrivates; + key = dri2WindowPrivateKey; } else { pPixmap = (PixmapPtr) pDraw; - pPriv = dixLookupPrivate(&pPixmap->devPrivates, dri2PixmapPrivateKey); - dixSetPrivate(&pPixmap->devPrivates, dri2PixmapPrivateKey, NULL); + devPrivates = &pPixmap->devPrivates; + key = dri2PixmapPrivateKey; } + pPriv = dixLookupPrivate(devPrivates, key); if (pPriv == NULL) return; - drmDestroyDrawable(ds->fd, pPriv->drawable); - xfree(pPriv); + pPriv->refCount--; + if (pPriv->refCount == 0) { + dixSetPrivate(devPrivates, key, NULL); + xfree(pPriv); + } +} + +void +DRI2ReemitDrawableInfo(DrawablePtr pDraw, unsigned int *head) +{ + DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen); + + *head = ds->buffer->head; + + DRI2PostDrawableConfig(pDraw); + DRI2PostBufferAttach(pDraw, TRUE); + DRI2ScreenCommitEvents(ds); } Bool @@ -409,8 +431,9 @@ DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info) if (!ds) return NULL; - ds->fd = info->fd; + ds->fd = info->fd; ds->driverName = info->driverName; + ds->nextHandle = 1; ds->getPixmapHandle = info->getPixmapHandle; ds->beginClipNotify = info->beginClipNotify; @@ -434,9 +457,21 @@ DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info) return p; } +extern ExtensionModule dri2ExtensionModule; + static pointer DRI2Setup(pointer module, pointer opts, int *errmaj, int *errmin) { + static Bool setupDone = FALSE; + + if (!setupDone) { + setupDone = TRUE; + LoadExtension(&dri2ExtensionModule, FALSE); + } else { + if (errmaj) + *errmaj = LDR_ONCEONLY; + } + return (pointer) 1; } diff --git a/hw/xfree86/dri2/dri2.h b/hw/xfree86/dri2/dri2.h index 126087a2f..85b3da41c 100644 --- a/hw/xfree86/dri2/dri2.h +++ b/hw/xfree86/dri2/dri2.h @@ -66,14 +66,16 @@ unsigned int DRI2GetPixmapHandle(PixmapPtr pPixmap, void DRI2Lock(ScreenPtr pScreen); void DRI2Unlock(ScreenPtr pScreen); -Bool DRI2CreateDrawable(ScreenPtr pScreen, - DrawablePtr pDraw, - drm_drawable_t *pDrmDrawable, - unsigned int *head); +Bool DRI2CreateDrawable(DrawablePtr pDraw, + unsigned int *handle, + unsigned int *head); -void DRI2DestroyDrawable(ScreenPtr pScreen, - DrawablePtr pDraw); +void DRI2DestroyDrawable(DrawablePtr pDraw); -void DRI2ExtensionInit(void); +void DRI2ReemitDrawableInfo(DrawablePtr pDraw, + unsigned int *head); + +Bool DRI2PostDamage(DrawablePtr pDrawable, + struct drm_clip_rect *rects, int numRects); #endif diff --git a/hw/xfree86/dri2/dri2ext.c b/hw/xfree86/dri2/dri2ext.c new file mode 100644 index 000000000..ca2e02970 --- /dev/null +++ b/hw/xfree86/dri2/dri2ext.c @@ -0,0 +1,361 @@ +/* + * Copyright © 2008 Red Hat, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Soft- + * ware"), to deal in the Software without restriction, including without + * limitation the rights to use, copy, modify, merge, publish, distribute, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, provided that the above copyright + * notice(s) and this permission notice appear in all copies of the Soft- + * ware and that both the above copyright notice(s) and this permission + * notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL- + * ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY + * RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN + * THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSE- + * QUENTIAL 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 PERFOR- + * MANCE OF THIS SOFTWARE. + * + * Except as contained in this notice, the name of a copyright holder shall + * not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization of + * the copyright holder. + * + * Authors: + * Kristian Høgsberg (krh@redhat.com) + */ + +#ifdef HAVE_XORG_CONFIG_H +#include +#endif + +#define NEED_REPLIES +#include +#include +#include "dixstruct.h" +#include "scrnintstr.h" +#include "pixmapstr.h" +#include "extnsionst.h" +#include "xf86drm.h" +#include "dri2proto.h" +#include "dri2.h" + +/* The only xf86 include */ +#include "xf86Module.h" + +static ExtensionEntry *dri2Extension; +static RESTYPE dri2DrawableRes; + +static Bool +validScreen(ClientPtr client, int screen, ScreenPtr *pScreen) +{ + if (screen >= screenInfo.numScreens) { + client->errorValue = screen; + return FALSE; + } + + *pScreen = screenInfo.screens[screen]; + + return TRUE; +} + +static Bool +validDrawable(ClientPtr client, XID drawable, + DrawablePtr *pDrawable, int *status) +{ + *status = dixLookupDrawable(pDrawable, drawable, client, 0, DixReadAccess); + if (*status != Success) { + client->errorValue = drawable; + return FALSE; + } + + return TRUE; +} + +static int +ProcDRI2QueryVersion(ClientPtr client) +{ + REQUEST(xDRI2QueryVersionReq); + xDRI2QueryVersionReply rep; + int n; + + if (client->swapped) + swaps(&stuff->length, n); + + REQUEST_SIZE_MATCH(xDRI2QueryVersionReq); + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.majorVersion = DRI2_MAJOR; + rep.minorVersion = DRI2_MINOR; + + if (client->swapped) { + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swapl(&rep.majorVersion, n); + swapl(&rep.minorVersion, n); + } + + WriteToClient(client, sizeof(xDRI2QueryVersionReply), &rep); + + return client->noClientException; +} + +static int +ProcDRI2Connect(ClientPtr client) +{ + REQUEST(xDRI2ConnectReq); + xDRI2ConnectReply rep; + ScreenPtr pScreen; + int fd; + const char *driverName; + char *busId; + unsigned int sareaHandle; + + REQUEST_SIZE_MATCH(xDRI2ConnectReq); + if (!validScreen(client, stuff->screen, &pScreen)) + return BadValue; + + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.driverNameLength = 0; + rep.busIdLength = 0; + rep.sareaHandle = 0; + + if (!DRI2Connect(pScreen, &fd, &driverName, &sareaHandle)) + goto fail; + + busId = drmGetBusid(fd); + if (busId == NULL) + goto fail; + + rep.driverNameLength = strlen(driverName); + rep.busIdLength = strlen(busId); + rep.sareaHandle = sareaHandle; + rep.length = (rep.driverNameLength + 3) / 4 + (rep.busIdLength + 3) / 4; + + fail: + WriteToClient(client, sizeof(xDRI2ConnectReply), &rep); + WriteToClient(client, rep.driverNameLength, driverName); + WriteToClient(client, rep.busIdLength, busId); + drmFreeBusid(busId); + + return client->noClientException; +} + +static int +ProcDRI2AuthConnection(ClientPtr client) +{ + REQUEST(xDRI2AuthConnectionReq); + xDRI2AuthConnectionReply rep; + ScreenPtr pScreen; + + REQUEST_SIZE_MATCH(xDRI2AuthConnectionReq); + if (!validScreen(client, stuff->screen, &pScreen)) + return BadValue; + + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.authenticated = 1; + + if (!DRI2AuthConnection(pScreen, stuff->magic)) { + ErrorF("DRI2: Failed to authenticate %lu\n", + (unsigned long) stuff->magic); + rep.authenticated = 0; + } + + WriteToClient(client, sizeof(xDRI2AuthConnectionReply), &rep); + + return client->noClientException; +} + +static int +ProcDRI2CreateDrawable(ClientPtr client) +{ + REQUEST(xDRI2CreateDrawableReq); + xDRI2CreateDrawableReply rep; + DrawablePtr pDrawable; + unsigned int handle, head; + int status; + + REQUEST_SIZE_MATCH(xDRI2CreateDrawableReq); + + if (!validDrawable(client, stuff->drawable, &pDrawable, &status)) + return status; + + if (!DRI2CreateDrawable(pDrawable, &handle, &head)) + return BadMatch; + + if (!AddResource(stuff->drawable, dri2DrawableRes, pDrawable)) { + DRI2DestroyDrawable(pDrawable); + return BadAlloc; + } + + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.handle = handle; + rep.head = head; + + WriteToClient(client, sizeof(xDRI2CreateDrawableReply), &rep); + + return client->noClientException; +} + +static int +ProcDRI2DestroyDrawable(ClientPtr client) +{ + REQUEST(xDRI2DestroyDrawableReq); + DrawablePtr pDrawable; + int status; + + REQUEST_SIZE_MATCH(xDRI2DestroyDrawableReq); + if (!validDrawable(client, stuff->drawable, &pDrawable, &status)) + return status; + + FreeResourceByType(stuff->drawable, dri2DrawableRes, FALSE); + + return client->noClientException; +} + +static int +ProcDRI2ReemitDrawableInfo(ClientPtr client) +{ + REQUEST(xDRI2ReemitDrawableInfoReq); + xDRI2ReemitDrawableInfoReply rep; + DrawablePtr pDrawable; + unsigned int head; + int status; + + REQUEST_SIZE_MATCH(xDRI2ReemitDrawableInfoReq); + if (!validDrawable(client, stuff->drawable, &pDrawable, &status)) + return status; + + DRI2ReemitDrawableInfo(pDrawable, &head); + + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.head = head; + + WriteToClient(client, sizeof(xDRI2ReemitDrawableInfoReply), &rep); + + return client->noClientException; +} + +static int +ProcDRI2Dispatch (ClientPtr client) +{ + REQUEST(xReq); + + switch (stuff->data) { + case X_DRI2QueryVersion: + return ProcDRI2QueryVersion(client); + } + + if (!LocalClient(client)) + return BadRequest; + + switch (stuff->data) { + case X_DRI2Connect: + return ProcDRI2Connect(client); + case X_DRI2AuthConnection: + return ProcDRI2AuthConnection(client); + case X_DRI2CreateDrawable: + return ProcDRI2CreateDrawable(client); + case X_DRI2DestroyDrawable: + return ProcDRI2DestroyDrawable(client); + case X_DRI2ReemitDrawableInfo: + return ProcDRI2ReemitDrawableInfo(client); + default: + return BadRequest; + } +} + +static int +SProcDRI2Connect(ClientPtr client) +{ + REQUEST(xDRI2ConnectReq); + xDRI2ConnectReply rep; + int n; + + /* If the client is swapped, it's not local. Talk to the hand. */ + + swaps(&stuff->length, n); + if (sizeof(*stuff) / 4 != client->req_len) + return BadLength; + + rep.sequenceNumber = client->sequence; + swaps(&rep.sequenceNumber, n); + rep.length = 0; + rep.driverNameLength = 0; + rep.busIdLength = 0; + rep.sareaHandle = 0; + + return client->noClientException; +} + +static int +SProcDRI2Dispatch (ClientPtr client) +{ + REQUEST(xReq); + + /* + * Only local clients are allowed DRI access, but remote clients + * still need these requests to find out cleanly. + */ + switch (stuff->data) + { + case X_DRI2QueryVersion: + return ProcDRI2QueryVersion(client); + case X_DRI2Connect: + return SProcDRI2Connect(client); + default: + return BadRequest; + } +} + +static void +DRI2ResetProc (ExtensionEntry *extEntry) +{ +} + +static int DRI2DrawableGone(pointer p, XID id) +{ + DrawablePtr pDrawable = p; + + DRI2DestroyDrawable(pDrawable); + + return Success; +} + +static void +DRI2ExtensionInit(void) +{ + dri2Extension = AddExtension(DRI2_NAME, + DRI2NumberEvents, + DRI2NumberErrors, + ProcDRI2Dispatch, + SProcDRI2Dispatch, + DRI2ResetProc, + StandardMinorOpcode); + + dri2DrawableRes = CreateNewResourceType(DRI2DrawableGone); +} + +extern Bool noDRI2Extension; + +_X_HIDDEN ExtensionModule dri2ExtensionModule = { + DRI2ExtensionInit, + DRI2_NAME, + &noDRI2Extension, + NULL, + NULL +}; diff --git a/os/utils.c b/os/utils.c index 57293ab6f..d785d46d2 100644 --- a/os/utils.c +++ b/os/utils.c @@ -239,6 +239,9 @@ _X_EXPORT int selinuxEnforcingState = SELINUX_MODE_DEFAULT; #ifdef XV _X_EXPORT Bool noXvExtension = FALSE; #endif +#ifdef DRI2 +_X_EXPORT Bool noDRI2Extension = FALSE; +#endif #define X_INCLUDE_NETDB_H #include From 9f56fc580646a519875b5a1452738d8c6e1fa860 Mon Sep 17 00:00:00 2001 From: Eamon Walsh Date: Mon, 31 Mar 2008 17:34:07 -0400 Subject: [PATCH 117/149] XSELinux: Add a request to get a client's context from a resource ID. --- Xext/xselinux.c | 33 +++++++++++++++++++++++++++++++++ Xext/xselinux.h | 1 + 2 files changed, 34 insertions(+) diff --git a/Xext/xselinux.c b/Xext/xselinux.c index 2e059a4c3..1e3b4d66c 100644 --- a/Xext/xselinux.c +++ b/Xext/xselinux.c @@ -1472,6 +1472,24 @@ ProcSELinuxGetSelectionContext(ClientPtr client, pointer privKey) return SELinuxSendContextReply(client, obj->sid); } +static int +ProcSELinuxGetClientContext(ClientPtr client) +{ + ClientPtr target; + SELinuxSubjectRec *subj; + int rc; + + REQUEST(SELinuxGetContextReq); + REQUEST_SIZE_MATCH(SELinuxGetContextReq); + + rc = dixLookupClient(&target, stuff->id, client, DixGetAttrAccess); + if (rc != Success) + return rc; + + subj = dixLookupPrivate(&target->devPrivates, subjectKey); + return SELinuxSendContextReply(client, subj->sid); +} + static int SELinuxPopulateItem(SELinuxListItemRec *i, PrivateRec **privPtr, CARD32 id, int *size) @@ -1686,6 +1704,8 @@ ProcSELinuxDispatch(ClientPtr client) return ProcSELinuxGetSelectionContext(client, dataKey); case X_SELinuxListSelections: return ProcSELinuxListSelections(client); + case X_SELinuxGetClientContext: + return ProcSELinuxGetClientContext(client); default: return BadRequest; } @@ -1782,6 +1802,17 @@ SProcSELinuxListProperties(ClientPtr client) return ProcSELinuxListProperties(client); } +static int +SProcSELinuxGetClientContext(ClientPtr client) +{ + REQUEST(SELinuxGetContextReq); + int n; + + REQUEST_SIZE_MATCH(SELinuxGetContextReq); + swapl(&stuff->id, n); + return ProcSELinuxGetClientContext(client); +} + static int SProcSELinuxDispatch(ClientPtr client) { @@ -1835,6 +1866,8 @@ SProcSELinuxDispatch(ClientPtr client) return SProcSELinuxGetSelectionContext(client, dataKey); case X_SELinuxListSelections: return ProcSELinuxListSelections(client); + case X_SELinuxGetClientContext: + return SProcSELinuxGetClientContext(client); default: return BadRequest; } diff --git a/Xext/xselinux.h b/Xext/xselinux.h index 2d0de3222..7c3ffdcb7 100644 --- a/Xext/xselinux.h +++ b/Xext/xselinux.h @@ -52,6 +52,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define X_SELinuxGetSelectionContext 19 #define X_SELinuxGetSelectionDataContext 20 #define X_SELinuxListSelections 21 +#define X_SELinuxGetClientContext 22 typedef struct { CARD8 reqType; From 19ff23ab0e72a27d05ed4470f75a0934d6f6c1d1 Mon Sep 17 00:00:00 2001 From: Ben Byer Date: Fri, 28 Mar 2008 18:25:03 -0700 Subject: [PATCH 118/149] Remove calls to InitValuatorAxisStruct -- these are now handled in dix by InitValuatorDeviceClass. Add InitProximityClassDeviceStruct call to prepare for tablet support. (cherry picked from commit 1bd980a5b114f5320360943214f8f9f23b29c1e3) --- hw/xquartz/darwin.c | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/hw/xquartz/darwin.c b/hw/xquartz/darwin.c index 0dbfafefa..8f2511dbb 100644 --- a/hw/xquartz/darwin.c +++ b/hw/xquartz/darwin.c @@ -353,24 +353,8 @@ static int DarwinMouseProc( InitPointerDeviceStruct( (DevicePtr)pPointer, map, 5, GetMotionHistory, (PtrCtrlProcPtr)NoopDDA, - GetMotionHistorySize(), 2); - -#ifdef XINPUT - InitValuatorAxisStruct( pPointer, - 0, // X axis - 0, // min value - 16000, // max value (fixme screen size?) - 1, // resolution (fixme ?) - 1, // min resolution - 1 ); // max resolution - InitValuatorAxisStruct( pPointer, - 1, // X axis - 0, // min value - 16000, // max value (fixme screen size?) - 1, // resolution (fixme ?) - 1, // min resolution - 1 ); // max resolution -#endif + GetMotionHistorySize(), 5); + InitProximityClassDeviceStruct( (DevicePtr)pPointer); break; case DEVICE_ON: From 6648867d8bd1e86458d2ade77a3ee4567c3d6a97 Mon Sep 17 00:00:00 2001 From: Ben Byer Date: Fri, 28 Mar 2008 18:27:02 -0700 Subject: [PATCH 119/149] add debug statements so we can see if/when our Xinput stubs are getting called. (cherry picked from commit 6e160bbe15dd2c2b8685847c06831cb6aebc6f74) --- hw/xquartz/darwinXinput.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/hw/xquartz/darwinXinput.c b/hw/xquartz/darwinXinput.c index 50ba656f8..59bae6fde 100644 --- a/hw/xquartz/darwinXinput.c +++ b/hw/xquartz/darwinXinput.c @@ -62,6 +62,7 @@ SOFTWARE. #include #include #include "XIstubs.h" +#include "darwin.h" /*********************************************************************** * @@ -79,6 +80,7 @@ SOFTWARE. void CloseInputDevice(DeviceIntPtr d, ClientPtr client) { + DEBUG_LOG("CloseInputDevice(%p, %p)\n", d, client); } /*********************************************************************** @@ -122,7 +124,7 @@ AddOtherInputDevices(void) RegisterOtherDevice(dev); dev->inited = ((*dev->deviceProc)(dev, DEVICE_INIT) == Success); ************************************************************************/ - + DEBUG_LOG("AddOtherInputDevices\n"); } /*********************************************************************** @@ -150,6 +152,7 @@ AddOtherInputDevices(void) void OpenInputDevice(DeviceIntPtr dev, ClientPtr client, int *status) { + DEBUG_LOG("OpenInputDevice(%p, %p, %p)\n", dev, client, status); } /**************************************************************************** @@ -167,6 +170,7 @@ OpenInputDevice(DeviceIntPtr dev, ClientPtr client, int *status) int SetDeviceMode(ClientPtr client, DeviceIntPtr dev, int mode) { + DEBUG_LOG("SetDeviceMode(%p, %p, %d)\n", client, dev, mode); return BadMatch; } @@ -186,7 +190,9 @@ int SetDeviceValuators(ClientPtr client, DeviceIntPtr dev, int *valuators, int first_valuator, int num_valuators) { - return BadMatch; + DEBUG_LOG("SetDeviceValuators(%p, %p, %p, %d, %d)\n", client, + dev, valuators, first_valuator, num_valuators); + return BadMatch; } /**************************************************************************** @@ -201,6 +207,8 @@ int ChangeDeviceControl(ClientPtr client, DeviceIntPtr dev, xDeviceCtl * control) { + + DEBUG_LOG("ChangeDeviceControl(%p, %p, %p)\n", client, dev, control); switch (control->control) { case DEVICE_RESOLUTION: return (BadMatch); @@ -225,7 +233,8 @@ ChangeDeviceControl(ClientPtr client, DeviceIntPtr dev, int NewInputDeviceRequest(InputOption *options, DeviceIntPtr *pdev) { - return BadValue; + DEBUG_LOG("NewInputDeviceRequest(%p, %p)\n", options, pdev); + return BadValue; } /**************************************************************************** @@ -238,4 +247,5 @@ NewInputDeviceRequest(InputOption *options, DeviceIntPtr *pdev) void DeleteInputDeviceRequest(DeviceIntPtr dev) { + DEBUG_LOG("DeleteInputDeviceRequest(%p)\n", dev); } From a4d034941100c6ca3b7cc4e59952c2745b9306cc Mon Sep 17 00:00:00 2001 From: Ben Byer Date: Fri, 28 Mar 2008 20:47:44 -0700 Subject: [PATCH 120/149] Add code to track 5 valuators for pointing device, in preparation for supporting tablet input in Xquartz. (cherry picked from commit 22c8849ea819eb70a14b2e06330b11b22aa63ebc) --- hw/xquartz/X11Application.m | 28 ++++++++++++---- hw/xquartz/darwinEvents.c | 64 ++++++++++++++++++++++++++++++------- hw/xquartz/darwinEvents.h | 8 +++-- 3 files changed, 80 insertions(+), 20 deletions(-) diff --git a/hw/xquartz/X11Application.m b/hw/xquartz/X11Application.m index 31c80dfa8..147b4b4c0 100644 --- a/hw/xquartz/X11Application.m +++ b/hw/xquartz/X11Application.m @@ -61,7 +61,7 @@ int X11EnableKeyEquivalents = TRUE; int quartzHasRoot = FALSE, quartzEnableRootless = TRUE; extern int darwinFakeButtons, input_check_flag; -extern Bool enable_stereo; +extern Bool enable_stereo; extern xEvent *darwinEvents; @@ -153,7 +153,7 @@ static void message_kit_thread (SEL selector, NSObject *arg) { tem = [infoDict objectForKey:@"CFBundleShortVersionString"]; - [dict setObject:[NSString stringWithFormat:@"Xquartz %@ - (xorg-server %s)", tem, XSERVER_VERSION] + [dict setObject:[NSString stringWithFormat:@"XQuartz %@ - (xorg-server %s)", tem, XSERVER_VERSION] forKey:@"ApplicationVersion"]; [self orderFrontStandardAboutPanelWithOptions: dict]; @@ -501,7 +501,7 @@ static NSMutableArray * cfarray_to_nsarray (CFArrayRef in) { if (value != NULL && CFGetTypeID (value) == CFNumberGetTypeID () - && CFNumberIsFloatType (value)) + && CFNumberIsFloatType (value)) CFNumberGetValue (value, kCFNumberFloatType, &ret); else if (value != NULL && CFGetTypeID (value) == CFStringGetTypeID ()) ret = CFStringGetDoubleValue (value); @@ -862,7 +862,9 @@ static void send_nsevent (NSEventType type, NSEvent *e) { NSRect screen; NSPoint location; NSWindow *window; - int pointer_x, pointer_y, ev_button, ev_type; + int pointer_x, pointer_y, ev_button, ev_type; + float pressure, tilt_x, tilt_y; + // int num_events=0, i=0, state; // xEvent xe; @@ -884,6 +886,10 @@ static void send_nsevent (NSEventType type, NSEvent *e) { pointer_y -= aquaMenuBarHeight; // state = convert_flags ([e modifierFlags]); + pressure = 0; // for tablets + tilt_x = 0; + tilt_y = 0; + switch (type) { case NSLeftMouseDown: ev_button=1; ev_type=ButtonPress; goto handle_mouse; case NSOtherMouseDown: ev_button=2; ev_type=ButtonPress; goto handle_mouse; @@ -894,6 +900,10 @@ static void send_nsevent (NSEventType type, NSEvent *e) { case NSLeftMouseDragged: ev_button=1; ev_type=MotionNotify; goto handle_mouse; case NSOtherMouseDragged: ev_button=2; ev_type=MotionNotify; goto handle_mouse; case NSRightMouseDragged: ev_button=3; ev_type=MotionNotify; goto handle_mouse; + case NSTabletPoint: + pressure = [e pressure]; + tilt_x = [e tilt].x; + tilt_y = [e tilt].y; // fall through case NSMouseMoved: ev_button=0; ev_type=MotionNotify; goto handle_mouse; handle_mouse: @@ -907,10 +917,14 @@ static void send_nsevent (NSEventType type, NSEvent *e) { DarwinSendPointerEvents(ev_type, ev_button, pointer_x, pointer_y); } else if (ev_type==ButtonRelease && (button_state & (1 << ev_button)) == 0) break; */ - DarwinSendPointerEvents(ev_type, ev_button, pointer_x, pointer_y); + + // if ([e subtype] == NSTabletPointEventSubtype) pressure = [e pressure]; + DarwinSendPointerEvents(ev_type, ev_button, pointer_x, pointer_y, + pressure, tilt_x, tilt_y); break; - case NSScrollWheel: - DarwinSendScrollEvents([e deltaY], pointer_x, pointer_y); + case NSScrollWheel: + DarwinSendScrollEvents([e deltaY], pointer_x, pointer_y, + pressure, tilt_x, tilt_y); break; case NSKeyDown: // do we need to translate these keyCodes? diff --git a/hw/xquartz/darwinEvents.c b/hw/xquartz/darwinEvents.c index 113cfc109..2a28b1a31 100644 --- a/hw/xquartz/darwinEvents.c +++ b/hw/xquartz/darwinEvents.c @@ -173,6 +173,9 @@ static void DarwinReleaseModifiers(void) { static void DarwinSimulateMouseClick( int pointer_x, int pointer_y, + float pressure, + float tilt_x, + float tilt_y, int whichButton, // mouse button to be pressed int modifierMask) // modifiers used for the fake click { @@ -183,8 +186,10 @@ static void DarwinSimulateMouseClick( DarwinUpdateModifiers(KeyRelease, modifierMask); // push the mouse button - DarwinSendPointerEvents(ButtonPress, whichButton, pointer_x, pointer_y); - DarwinSendPointerEvents(ButtonRelease, whichButton, pointer_x, pointer_y); + DarwinSendPointerEvents(ButtonPress, whichButton, pointer_x, pointer_y, + pressure, tilt_x, tilt_y); + DarwinSendPointerEvents(ButtonRelease, whichButton, pointer_x, pointer_y, + pressure, tilt_x, tilt_y); // restore old modifiers DarwinUpdateModifiers(KeyPress, modifierMask); @@ -378,22 +383,39 @@ void DarwinPokeEQ(void) { write(darwinEventWriteFD, &nullbyte, 1); } -void DarwinSendPointerEvents(int ev_type, int ev_button, int pointer_x, int pointer_y) { +void DarwinSendPointerEvents(int ev_type, int ev_button, int pointer_x, int pointer_y, + float pressure, float tilt_x, float tilt_y) { static int darwinFakeMouseButtonDown = 0; static int darwinFakeMouseButtonMask = 0; int i, num_events; - int valuators[2] = {pointer_x, pointer_y}; + + /* I can't find a spec for this, but at least GTK expects that tablets are + just like mice, except they have either one or three extra valuators, in this + order: + + X coord, Y coord, pressure, X tilt, Y tilt + Pressure and tilt should be represented natively as floats; unfortunately, + we can't do that. Again, GTK seems to record the min/max of each valuator, + and then perform scaling back to float itself using that info. Soo.... */ + + int valuators[5] = {pointer_x, pointer_y, + pressure * INT32_MAX * 1.0f, + tilt_x * INT32_MAX * 1.0f, + tilt_y * INT32_MAX * 1.0f}; + if (ev_type == ButtonPress && darwinFakeButtons && ev_button == 1) { // Mimic multi-button mouse with modifier-clicks // If both sets of modifiers are pressed, // button 2 is clicked. if ((old_flags & darwinFakeMouse2Mask) == darwinFakeMouse2Mask) { - DarwinSimulateMouseClick(pointer_x, pointer_y, 2, darwinFakeMouse2Mask); + DarwinSimulateMouseClick(pointer_x, pointer_y, pressure, + tilt_x, tilt_y, 2, darwinFakeMouse2Mask); darwinFakeMouseButtonDown = 2; darwinFakeMouseButtonMask = darwinFakeMouse2Mask; return; } else if ((old_flags & darwinFakeMouse3Mask) == darwinFakeMouse3Mask) { - DarwinSimulateMouseClick(pointer_x, pointer_y, 3, darwinFakeMouse3Mask); + DarwinSimulateMouseClick(pointer_x, pointer_y, pressure, + tilt_x, tilt_y, 3, darwinFakeMouse3Mask); darwinFakeMouseButtonDown = 3; darwinFakeMouseButtonMask = darwinFakeMouse3Mask; return; @@ -412,7 +434,7 @@ void DarwinSendPointerEvents(int ev_type, int ev_button, int pointer_x, int poin } num_events = GetPointerEvents(darwinEvents, darwinPointer, ev_type, ev_button, - POINTER_ABSOLUTE, 0, 2, valuators); + POINTER_ABSOLUTE, 0, 5, valuators); for(i=0; i 0.0f ? 4 : 5; - int valuators[2] = {pointer_x, pointer_y}; + int valuators[5] = {pointer_x, pointer_y, + pressure * INT32_MAX * 1.0f, + tilt_x * INT32_MAX * 1.0f, + tilt_y * INT32_MAX * 1.0f}; for (count = fabs(count); count > 0.0; count = count - 1.0f) { int num_events = GetPointerEvents(darwinEvents, darwinPointer, ButtonPress, ev_button, - POINTER_ABSOLUTE, 0, 2, valuators); + POINTER_ABSOLUTE, 0, 5, valuators); for(i=0; i Date: Tue, 1 Apr 2008 15:27:06 +0300 Subject: [PATCH 121/149] XKB: Fix processInputProc wrapping If input processing is frozen, only wrap realInputProc: don't smash processInputProc as well. When input processing is thawed, pIP will be rewrapped correctly. This supersedes the previous workaround in 50e80c9. Signed-off-by: Daniel Stone --- include/xkbsrv.h | 16 ++++++++++++---- xkb/xkbActions.c | 9 ++++----- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/include/xkbsrv.h b/include/xkbsrv.h index ef99e94e7..040bb936a 100644 --- a/include/xkbsrv.h +++ b/include/xkbsrv.h @@ -237,6 +237,14 @@ typedef struct _XkbSrvLedInfo { typedef struct { ProcessInputProc processInputProc; + /* If processInputProc is set to something different than realInputProc, + * UNWRAP and COND_WRAP will not touch processInputProc and update only + * realInputProc. This ensures that + * processInputProc == (frozen ? EnqueueEvent : realInputProc) + * + * WRAP_PROCESS_INPUT_PROC should only be called during initialization, + * since it may destroy this invariant. + */ ProcessInputProc realInputProc; DeviceUnwrapProc unwrapProc; } xkbDeviceInfoRec, *xkbDeviceInfoPtr; @@ -254,14 +262,14 @@ typedef struct device->public.processInputProc = proc; \ oldprocs->processInputProc = \ oldprocs->realInputProc = device->public.realInputProc; \ - if (proc != device->public.enqueueInputProc) \ - device->public.realInputProc = proc; \ + device->public.realInputProc = proc; \ oldprocs->unwrapProc = device->unwrapProc; \ device->unwrapProc = unwrapproc; #define UNWRAP_PROCESS_INPUT_PROC(device, oldprocs, backupproc) \ - backupproc = device->public.processInputProc; \ - device->public.processInputProc = oldprocs->processInputProc; \ + backupproc = device->public.realInputProc; \ + if (device->public.processInputProc == device->public.realInputProc)\ + device->public.processInputProc = oldprocs->realInputProc; \ device->public.realInputProc = oldprocs->realInputProc; \ device->unwrapProc = oldprocs->unwrapProc; diff --git a/xkb/xkbActions.c b/xkb/xkbActions.c index 890cf4250..8c72874df 100644 --- a/xkb/xkbActions.c +++ b/xkb/xkbActions.c @@ -49,15 +49,14 @@ xkbUnwrapProc(DeviceIntPtr device, DeviceHandleProc proc, pointer data) { xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(device); - ProcessInputProc tmp = device->public.processInputProc; - ProcessInputProc dummy; /* unused, but neede for macro */ + ProcessInputProc backupproc; if(xkbPrivPtr->unwrapProc) xkbPrivPtr->unwrapProc = NULL; - UNWRAP_PROCESS_INPUT_PROC(device,xkbPrivPtr, dummy); + UNWRAP_PROCESS_INPUT_PROC(device,xkbPrivPtr, backupproc); proc(device,data); - WRAP_PROCESS_INPUT_PROC(device,xkbPrivPtr, - tmp,xkbUnwrapProc); + COND_WRAP_PROCESS_INPUT_PROC(device,xkbPrivPtr, + backupproc,xkbUnwrapProc); } From 9500033b9ecdfaf5a56a4355ffc94d74cb17ca17 Mon Sep 17 00:00:00 2001 From: Goneri Le Bouder Date: Tue, 1 Apr 2008 20:19:40 +0200 Subject: [PATCH 122/149] xfree86: don't crash in AutoConfig if the primary device is not pci Only call matchDriverFromFiles() if we found a pci device. Debian bug#472823 (http://bugs.debian.org/472823). --- hw/xfree86/common/xf86AutoConfig.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/hw/xfree86/common/xf86AutoConfig.c b/hw/xfree86/common/xf86AutoConfig.c index 268b50cb5..3210e4460 100644 --- a/hw/xfree86/common/xf86AutoConfig.c +++ b/hw/xfree86/common/xf86AutoConfig.c @@ -436,9 +436,10 @@ chooseVideoDriver(void) if (!info) { ErrorF("Primary device is not PCI\n"); } - #ifdef __linux__ - matchDriverFromFiles(matches, info->vendor_id, info->device_id); + else { + matchDriverFromFiles(matches, info->vendor_id, info->device_id); + } #endif /* __linux__ */ /* TODO Handle multiple drivers claiming to support the same PCI ID */ From ebc56aca8bdfec1918cac3c8380895dfddea48ce Mon Sep 17 00:00:00 2001 From: Hong Liu Date: Wed, 2 Apr 2008 10:43:19 +0800 Subject: [PATCH 123/149] Bug #15160: quirk Proview AY765C prefer first detailed timing --- hw/xfree86/modes/xf86EdidModes.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/hw/xfree86/modes/xf86EdidModes.c b/hw/xfree86/modes/xf86EdidModes.c index 777bb70c7..f15c39642 100644 --- a/hw/xfree86/modes/xf86EdidModes.c +++ b/hw/xfree86/modes/xf86EdidModes.c @@ -153,6 +153,11 @@ static Bool quirk_first_detailed_preferred (int scrnIndex, xf86MonPtr DDC) DDC->vendor.prod_id == 57364) return TRUE; + /* Proview AY765C 17" LCD. See bug #15160*/ + if (memcmp (DDC->vendor.name, "PTS", 4) == 0 && + DDC->vendor.prod_id == 765) + return TRUE; + return FALSE; } From b31de6a59044f91f8230aa581c9ca8540289c168 Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Wed, 2 Apr 2008 16:29:30 +1000 Subject: [PATCH 124/149] dri2: fix crasher if DRI2Connect fails --- hw/xfree86/dri2/dri2ext.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/xfree86/dri2/dri2ext.c b/hw/xfree86/dri2/dri2ext.c index ca2e02970..d1d52a427 100644 --- a/hw/xfree86/dri2/dri2ext.c +++ b/hw/xfree86/dri2/dri2ext.c @@ -114,7 +114,7 @@ ProcDRI2Connect(ClientPtr client) ScreenPtr pScreen; int fd; const char *driverName; - char *busId; + char *busId = NULL; unsigned int sareaHandle; REQUEST_SIZE_MATCH(xDRI2ConnectReq); From b13ab156894074fb38cc812738bc7aeeebd9614d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Wed, 2 Apr 2008 12:38:36 -0400 Subject: [PATCH 125/149] dri2: Unbreak glcore visual setup. --- GL/glx/glxglcore.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/GL/glx/glxglcore.c b/GL/glx/glxglcore.c index bbfa02b79..972ab88e6 100644 --- a/GL/glx/glxglcore.c +++ b/GL/glx/glxglcore.c @@ -308,10 +308,9 @@ static const int glx_visual_types[] = { static __GLXconfig * createFBConfigsForVisual(__GLXscreen *screen, ScreenPtr pScreen, - VisualPtr visual, __GLXconfig *tail) + VisualPtr visual, __GLXconfig *config) { int back, depth, stencil; - __GLXconfig *config; /* FIXME: Ok, I'm making all this up... anybody has a better idea? */ @@ -347,7 +346,7 @@ createFBConfigsForVisual(__GLXscreen *screen, ScreenPtr pScreen, config->indexBits = config->colorIndexMode ? visual->nplanes : 0; } - return tail; + return config; } static void From 7c20f65fea3dd3170cde89d7113d85f377671bfb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Wed, 2 Apr 2008 18:00:06 -0400 Subject: [PATCH 126/149] Add @XORG_CFLAGS@ to satisfy xf86* includes. Pointed out by Hasso Tepper. --- hw/xfree86/dri/Makefile.am | 2 +- hw/xfree86/dri2/Makefile.am | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/xfree86/dri/Makefile.am b/hw/xfree86/dri/Makefile.am index 68f1eaefa..bee315288 100644 --- a/hw/xfree86/dri/Makefile.am +++ b/hw/xfree86/dri/Makefile.am @@ -7,7 +7,7 @@ libdri_la_CFLAGS = -I$(top_srcdir)/hw/xfree86/common \ -I$(top_builddir)/GL/include \ -I@MESA_SOURCE@/include \ -DHAVE_XORG_CONFIG_H \ - @DIX_CFLAGS@ @DRIPROTO_CFLAGS@ \ + @DIX_CFLAGS@ @XORG_CFLAGS@ @DRIPROTO_CFLAGS@ \ @LIBDRM_CFLAGS@ \ @GL_CFLAGS@ libdri_la_LDFLAGS = -module -avoid-version @LIBDRM_LIBS@ diff --git a/hw/xfree86/dri2/Makefile.am b/hw/xfree86/dri2/Makefile.am index 844c91240..fd8962ebb 100644 --- a/hw/xfree86/dri2/Makefile.am +++ b/hw/xfree86/dri2/Makefile.am @@ -2,7 +2,7 @@ libdri2_la_LTLIBRARIES = libdri2.la libdri2_la_CFLAGS = \ -DHAVE_XORG_CONFIG_H \ -I@MESA_SOURCE@/include \ - @DIX_CFLAGS@ @DRI2PROTO_CFLAGS@ @LIBDRM_CFLAGS@ \ + @DIX_CFLAGS@ @XORG_CFLAGS@ @DRI2PROTO_CFLAGS@ @LIBDRM_CFLAGS@ \ -I$(top_srcdir)/hw/xfree86/common \ -I$(top_srcdir)/hw/xfree86/os-support/bus From 8cde0af3c57f0375ba8ba77af9fdf74b79d9496d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Wed, 2 Apr 2008 19:06:40 -0400 Subject: [PATCH 127/149] Send the GLX_EXT_texture_from_pixmap attributes to the client. --- GL/glx/glxcmds.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/GL/glx/glxcmds.c b/GL/glx/glxcmds.c index 36aae61b9..dcd83525f 100644 --- a/GL/glx/glxcmds.c +++ b/GL/glx/glxcmds.c @@ -959,7 +959,7 @@ int __glXDisp_GetVisualConfigs(__GLXclientState *cl, GLbyte *pc) return Success; } -#define __GLX_TOTAL_FBCONFIG_ATTRIBS (28) +#define __GLX_TOTAL_FBCONFIG_ATTRIBS (33) #define __GLX_FBCONFIG_ATTRIBS_LENGTH (__GLX_TOTAL_FBCONFIG_ATTRIBS * 2) /** * Send the set of GLXFBConfigs to the client. There is not currently @@ -1037,6 +1037,11 @@ DoGetFBConfigs(__GLXclientState *cl, unsigned screen) WRITE_PAIR( GLX_TRANSPARENT_ALPHA_VALUE, modes->transparentAlpha ); WRITE_PAIR( GLX_TRANSPARENT_INDEX_VALUE, modes->transparentIndex ); WRITE_PAIR( GLX_SWAP_METHOD_OML, modes->swapMethod ); + WRITE_PAIR( GLX_DRAWABLE_TYPE, modes->drawableType ); + WRITE_PAIR( GLX_BIND_TO_TEXTURE_RGB_EXT, modes->bindToTextureRgb ); + WRITE_PAIR( GLX_BIND_TO_TEXTURE_RGBA_EXT, modes->bindToTextureRgba ); + WRITE_PAIR( GLX_BIND_TO_MIPMAP_TEXTURE_EXT, modes->bindToMipmapTexture ); + WRITE_PAIR( GLX_BIND_TO_TEXTURE_TARGETS_EXT, modes->bindToTextureTargets ); if (client->swapped) { __GLX_SWAP_INT_ARRAY(buf, __GLX_FBCONFIG_ATTRIBS_LENGTH); From b5a0a865c3045cc08c33388320d4ec3ab7065efb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Wed, 2 Apr 2008 19:21:41 -0400 Subject: [PATCH 128/149] Pick up dri2proto from the standard proto header include path. --- configure.ac | 2 +- hw/xfree86/dri2/dri2ext.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index e72e3b99a..985c8e227 100644 --- a/configure.ac +++ b/configure.ac @@ -860,7 +860,7 @@ AM_CONDITIONAL(DRI2, test "x$DRI2" = xyes) if test "x$DRI2" = xyes; then # FIXME: Bump the versions once we have releases of these. AC_DEFINE(DRI2, 1, [Build DRI2 extension]) - PKG_CHECK_MODULES([DRI2PROTO], [dri2proto >= 1.0.0]) + PKG_CHECK_MODULES([DRI2PROTO], [dri2proto >= 1.1]) PKG_CHECK_MODULES([LIBDRM], [libdrm >= 2.3.1]) fi diff --git a/hw/xfree86/dri2/dri2ext.c b/hw/xfree86/dri2/dri2ext.c index d1d52a427..4ae0fda3a 100644 --- a/hw/xfree86/dri2/dri2ext.c +++ b/hw/xfree86/dri2/dri2ext.c @@ -37,12 +37,12 @@ #define NEED_REPLIES #include #include +#include #include "dixstruct.h" #include "scrnintstr.h" #include "pixmapstr.h" #include "extnsionst.h" #include "xf86drm.h" -#include "dri2proto.h" #include "dri2.h" /* The only xf86 include */ From 8746daa6732d9837f66d925f2fd74818ecbf8ba2 Mon Sep 17 00:00:00 2001 From: Jeremy Huddleston Date: Wed, 2 Apr 2008 15:01:33 -0700 Subject: [PATCH 129/149] XQuartz: Fixed missing close-paren in preference pane text. (cherry picked from commit ea37e151dc6032d2a1a33cef809f2a7d507aae35) --- .../English.lproj/main.nib/designable.nib | 4 ++-- .../English.lproj/main.nib/keyedobjects.nib | Bin 38044 -> 37918 bytes 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/xquartz/bundle/English.lproj/main.nib/designable.nib b/hw/xquartz/bundle/English.lproj/main.nib/designable.nib index 672ba904d..c159d6ee1 100644 --- a/hw/xquartz/bundle/English.lproj/main.nib/designable.nib +++ b/hw/xquartz/bundle/English.lproj/main.nib/designable.nib @@ -2,7 +2,7 @@ 1050 - 9C31 + 9C7010 639 949.26 352.00 @@ -948,7 +948,7 @@ ZSBhbmQgcmlnaHQgbW91c2UgYnV0dG9ucy4KA 67239424 4194304 - When enabled, creation of a new X11 window will cause X11.app to move to the foreground (instead of Finder.app, Terminal.app, etc. + When enabled, creation of a new X11 window will cause X11.app to move to the foreground (instead of Finder.app, Terminal.app, etc.) diff --git a/hw/xquartz/bundle/English.lproj/main.nib/keyedobjects.nib b/hw/xquartz/bundle/English.lproj/main.nib/keyedobjects.nib index 91a7c5adb44e6355d01211d48fe4c5a0121a6b43..95420e4f77d13556c624c3232b9c713cb056a537 100644 GIT binary patch literal 37918 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

438$p#mSl9A{$5E~45BR(b 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�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 literal 38044 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 From 1400a51ae70d8e498d9ae3975f58ba7c1768ca6f Mon Sep 17 00:00:00 2001 From: Ben Byer Date: Mon, 31 Mar 2008 16:24:01 -0700 Subject: [PATCH 130/149] Begin to move all of our Xquartz DDX-specific event handlers to miEQ, in preparation to remove the DDX-specific code entirely. (cherry picked from commit 3f4447b95f73a82b3aa0f7b0d1640aba5fb0d1bc) --- hw/xquartz/darwinEvents.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/hw/xquartz/darwinEvents.c b/hw/xquartz/darwinEvents.c index 2a28b1a31..b4ff9fd61 100644 --- a/hw/xquartz/darwinEvents.c +++ b/hw/xquartz/darwinEvents.c @@ -195,10 +195,34 @@ static void DarwinSimulateMouseClick( DarwinUpdateModifiers(KeyPress, modifierMask); } +void DarwinEventHandler(int screenNum, xEventPtr xe, DeviceIntPtr dev, int nevents) { + int i; + + DEBUG_LOG("DarwinEventHandler(%d, %p, %p, %d)\n", screenNum, xe, dev, nevents); + for (i=0; i Date: Mon, 31 Mar 2008 16:30:16 -0700 Subject: [PATCH 131/149] add logging of current thread ID to DEBUG_LOG macro (cherry picked from commit 5848510cc5a8091b30230ab920d904ca6b159480) --- hw/xquartz/darwin.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/xquartz/darwin.h b/hw/xquartz/darwin.h index bd1b9a42a..9384b9dbb 100644 --- a/hw/xquartz/darwin.h +++ b/hw/xquartz/darwin.h @@ -125,7 +125,7 @@ enum { #ifdef ENABLE_DEBUG_LOG extern FILE *debug_log_fp; #define DEBUG_LOG_NAME "x11-debug.txt" -#define DEBUG_LOG(msg, args...) if (debug_log_fp) fprintf(debug_log_fp, "%s:%s:%d " msg, __FILE__, __FUNCTION__, __LINE__, ##args ); fflush(debug_log_fp); +#define DEBUG_LOG(msg, args...) if (debug_log_fp) fprintf(debug_log_fp, "%x:%s:%s:%d " msg, pthread_self(), __FILE__, __FUNCTION__, __LINE__, ##args ); fflush(debug_log_fp); #else #define DEBUG_LOG(msg, args...) #endif From 5b6c273eaa53d7b554d69c2b4865988068e73a26 Mon Sep 17 00:00:00 2001 From: Ben Byer Date: Mon, 31 Mar 2008 17:08:45 -0700 Subject: [PATCH 132/149] add prototype for DarwinEventHandler (cherry picked from commit 9a03ae33c4f9de830f15eabf3b994882ead7c000) --- hw/xquartz/darwinEvents.c | 2 -- hw/xquartz/darwinEvents.h | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/xquartz/darwinEvents.c b/hw/xquartz/darwinEvents.c index b4ff9fd61..ce21ff540 100644 --- a/hw/xquartz/darwinEvents.c +++ b/hw/xquartz/darwinEvents.c @@ -204,8 +204,6 @@ void DarwinEventHandler(int screenNum, xEventPtr xe, DeviceIntPtr dev, int neven Bool DarwinEQInit(DevicePtr pKbd, DevicePtr pPtr) { - void mieqSetHandler(int event, mieqHandler handler); - darwinEvents = (xEvent *)malloc(sizeof(xEvent) * GetMaximumEventsNum()); mieqInit(); mieqSetHandler(kXquartzActivate, DarwinEventHandler); diff --git a/hw/xquartz/darwinEvents.h b/hw/xquartz/darwinEvents.h index 496061420..1d8e92a7b 100644 --- a/hw/xquartz/darwinEvents.h +++ b/hw/xquartz/darwinEvents.h @@ -41,4 +41,6 @@ void DarwinSendScrollEvents(float count, int pointer_x, int pointer_y, float pressure, float tilt_x, float tilt_y); void DarwinUpdateModKeys(int flags); +void DarwinEventHandler(int screenNum, xEventPtr xe, DeviceIntPtr dev, + int nevents); #endif /* _DARWIN_EVENTS_H */ From c6f0d5d1e51326e5110d27918d834eb0096df7db Mon Sep 17 00:00:00 2001 From: Ben Byer Date: Mon, 31 Mar 2008 17:48:09 -0700 Subject: [PATCH 133/149] gut darwinEQEnqueue, and make it just call mieqEnqueue (for the moment) (cherry picked from commit a9e081a60ca227c0d96d4613075d97d6b762366a) --- hw/xquartz/darwinEvents.c | 40 +++++++-------------------------------- 1 file changed, 7 insertions(+), 33 deletions(-) diff --git a/hw/xquartz/darwinEvents.c b/hw/xquartz/darwinEvents.c index ce21ff540..f7b141980 100644 --- a/hw/xquartz/darwinEvents.c +++ b/hw/xquartz/darwinEvents.c @@ -199,7 +199,11 @@ void DarwinEventHandler(int screenNum, xEventPtr xe, DeviceIntPtr dev, int neven int i; DEBUG_LOG("DarwinEventHandler(%d, %p, %p, %d)\n", screenNum, xe, dev, nevents); - for (i=0; iu.keyButtonPointer.time < darwinEventQueue.lastEventTime && - darwinEventQueue.lastEventTime - e->u.keyButtonPointer.time < 10000) - { - darwinEventQueue.events[oldtail].event.u.keyButtonPointer.time = - darwinEventQueue.lastEventTime; - } - darwinEventQueue.events[oldtail].pScreen = darwinEventQueue.pEnqueueScreen; - - // Update the tail after the event is prepared - darwinEventQueue.tail = newtail; - - // Signal there is an event ready to handle - DarwinPokeEQ(); + mieqEnqueue(NULL, e); + DarwinPokeEQ(); } - /* * DarwinEQPointerPost * Post a pointer event. Used by the mipointer.c routines. From 6c5962e44730395f81cdb333322c9ad5242c32d4 Mon Sep 17 00:00:00 2001 From: Ben Byer Date: Mon, 31 Mar 2008 18:15:18 -0700 Subject: [PATCH 134/149] remove vestigal DarwinEQPointerPost etc (cherry picked from commit a25704c423598d596fd7f2ed4290d4b860bd5d5f) --- hw/xquartz/darwinEvents.c | 17 ----------------- hw/xquartz/quartzCursor.c | 4 ++-- hw/xquartz/xpr/xprCursor.c | 4 ++-- 3 files changed, 4 insertions(+), 21 deletions(-) diff --git a/hw/xquartz/darwinEvents.c b/hw/xquartz/darwinEvents.c index f7b141980..46f567536 100644 --- a/hw/xquartz/darwinEvents.c +++ b/hw/xquartz/darwinEvents.c @@ -250,23 +250,6 @@ void DarwinEQEnqueue(const xEventPtr e) { DarwinPokeEQ(); } -/* - * DarwinEQPointerPost - * Post a pointer event. Used by the mipointer.c routines. - */ -void DarwinEQPointerPost(DeviceIntPtr pdev, xEventPtr e) { - (*darwinEventQueue.pPtr->processInputProc) - (e, (DeviceIntPtr)darwinEventQueue.pPtr, 1); -} - - -void DarwinEQSwitchScreen(ScreenPtr pScreen, Bool fromDIX) { - darwinEventQueue.pEnqueueScreen = pScreen; - if (fromDIX) - darwinEventQueue.pDequeueScreen = pScreen; -} - - /* * ProcessInputEvents * Read and process events from the event queue until it is empty. diff --git a/hw/xquartz/quartzCursor.c b/hw/xquartz/quartzCursor.c index f82ccd380..10e671a7e 100644 --- a/hw/xquartz/quartzCursor.c +++ b/hw/xquartz/quartzCursor.c @@ -539,8 +539,8 @@ static miPointerScreenFuncRec quartzScreenFuncsRec = { QuartzCursorOffScreen, QuartzCrossScreen, QuartzWarpCursor, - DarwinEQPointerPost, - DarwinEQSwitchScreen + NULL, + NULL }; diff --git a/hw/xquartz/xpr/xprCursor.c b/hw/xquartz/xpr/xprCursor.c index e084ef90e..2ad8d6f56 100644 --- a/hw/xquartz/xpr/xprCursor.c +++ b/hw/xquartz/xpr/xprCursor.c @@ -320,8 +320,8 @@ static miPointerScreenFuncRec quartzScreenFuncsRec = { QuartzCursorOffScreen, QuartzCrossScreen, QuartzWarpCursor, - DarwinEQPointerPost, - DarwinEQSwitchScreen + NULL, + NULL }; From aa6d12e93e8661da841192ef7c3aa7c6a7731c7f Mon Sep 17 00:00:00 2001 From: Jeremy Huddleston Date: Wed, 2 Apr 2008 17:46:59 -0700 Subject: [PATCH 135/149] turns out we weren't actually using these files. oops (cherry picked from commit bfec44d7b4baf0ad0aae55c8209bc60ac93c5b58) --- hw/xquartz/Makefile.am | 2 - hw/xquartz/quartzCursor.c | 646 -------------------------------------- hw/xquartz/quartzCursor.h | 42 --- 3 files changed, 690 deletions(-) delete mode 100644 hw/xquartz/quartzCursor.c delete mode 100644 hw/xquartz/quartzCursor.h diff --git a/hw/xquartz/Makefile.am b/hw/xquartz/Makefile.am index 99d23eb1f..075382476 100644 --- a/hw/xquartz/Makefile.am +++ b/hw/xquartz/Makefile.am @@ -50,8 +50,6 @@ EXTRA_DIST = \ quartz.h \ quartzAudio.h \ quartzCommon.h \ - quartzCursor.c \ - quartzCursor.h \ quartzForeground.h \ quartzKeyboard.h \ quartzPasteboard.h diff --git a/hw/xquartz/quartzCursor.c b/hw/xquartz/quartzCursor.c deleted file mode 100644 index 10e671a7e..000000000 --- a/hw/xquartz/quartzCursor.c +++ /dev/null @@ -1,646 +0,0 @@ -/************************************************************** - * - * Support for using the Quartz Window Manager cursor - * - * Copyright (c) 2001-2003 Torrey T. Lyons and Greg Parker. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Except as contained in this notice, the name(s) of the above copyright - * holders shall not be used in advertising or otherwise to promote the sale, - * use or other dealings in this Software without prior written authorization. - */ - -#ifdef HAVE_DIX_CONFIG_H -#include -#endif - -#include "quartzCommon.h" -#include "quartzCursor.h" -#include "darwin.h" - -#include - -#include "mi.h" -#include "scrnintstr.h" -#include "cursorstr.h" -#include "mipointrst.h" -#include "globals.h" - -// Size of the QuickDraw cursor -#define CURSORWIDTH 16 -#define CURSORHEIGHT 16 - -typedef struct { - int qdCursorMode; - int qdCursorVisible; - int useQDCursor; - QueryBestSizeProcPtr QueryBestSize; - miPointerSpriteFuncPtr spriteFuncs; -} QuartzCursorScreenRec, *QuartzCursorScreenPtr; - -static DevPrivateKey darwinCursorScreenKey = &darwinCursorScreenKey; -static CursorPtr quartzLatentCursor = NULL; -static QD_Cursor gQDArrow; // QuickDraw arrow cursor - -// Cursor for the main thread to set (NULL = arrow cursor). -static CCrsrHandle currentCursor = NULL; -static pthread_mutex_t cursorMutex; -static pthread_cond_t cursorCondition; - -#define CURSOR_PRIV(pScreen) ((QuartzCursorScreenPtr) \ - dixLookupPrivate(&pScreen->devPrivates, darwinCursorScreenKey)) - -#define HIDE_QD_CURSOR(pScreen, visible) \ - if (visible) { \ - int ix; \ - for (ix = 0; ix < QUARTZ_PRIV(pScreen)->displayCount; ix++) { \ - CGDisplayHideCursor(QUARTZ_PRIV(pScreen)->displayIDs[ix]); \ - } \ - visible = FALSE; \ - } ((void)0) - -#define SHOW_QD_CURSOR(pScreen, visible) \ - { \ - int ix; \ - for (ix = 0; ix < QUARTZ_PRIV(pScreen)->displayCount; ix++) { \ - CGDisplayShowCursor(QUARTZ_PRIV(pScreen)->displayIDs[ix]); \ - } \ - visible = TRUE; \ - } ((void)0) - -#define CHANGE_QD_CURSOR(cursorH) \ - if (!quartzServerQuitting) { \ - /* Acquire lock and tell the main thread to change cursor */ \ - pthread_mutex_lock(&cursorMutex); \ - currentCursor = (CCrsrHandle) (cursorH); \ - QuartzMessageMainThread(kQuartzCursorUpdate, NULL, 0); \ - \ - /* Wait for the main thread to change the cursor */ \ - pthread_cond_wait(&cursorCondition, &cursorMutex); \ - pthread_mutex_unlock(&cursorMutex); \ - } ((void)0) - - -/* - * MakeQDCursor helpers: CTAB_ENTER, interleave - */ - -// Add a color entry to a ctab -#define CTAB_ENTER(ctab, index, r, g, b) \ - ctab->ctTable[index].value = index; \ - ctab->ctTable[index].rgb.red = r; \ - ctab->ctTable[index].rgb.green = g; \ - ctab->ctTable[index].rgb.blue = b - -// Make an unsigned short by interleaving the bits of bytes c1 and c2. -// High bit of c1 is first; low bit of c2 is last. -// Interleave is a built-in INTERCAL operator. -static unsigned short -interleave( - unsigned char c1, - unsigned char c2 ) -{ - return - ((c1 & 0x80) << 8) | ((c2 & 0x80) << 7) | - ((c1 & 0x40) << 7) | ((c2 & 0x40) << 6) | - ((c1 & 0x20) << 6) | ((c2 & 0x20) << 5) | - ((c1 & 0x10) << 5) | ((c2 & 0x10) << 4) | - ((c1 & 0x08) << 4) | ((c2 & 0x08) << 3) | - ((c1 & 0x04) << 3) | ((c2 & 0x04) << 2) | - ((c1 & 0x02) << 2) | ((c2 & 0x02) << 1) | - ((c1 & 0x01) << 1) | ((c2 & 0x01) << 0) ; -} - -/* - * MakeQDCursor - * Make a QuickDraw color cursor from the given X11 cursor. - * Warning: This code is nasty. Color cursors were meant to be read - * from resources; constructing the structures programmatically is messy. - */ -/* - QuickDraw cursor representation: - Our color cursor is a 2 bit per pixel pixmap. - Each pixel's bits are (source<<1 | mask) from the original X cursor pixel. - The cursor's color table maps the colors like this: - (2-bit value | X result | colortable | Mac result) - 00 | transparent | white | transparent (white outside mask) - 01 | back color | back color | back color - 10 | undefined | black | invert background (just for fun) - 11 | fore color | fore color | fore color -*/ -static CCrsrHandle -MakeQDCursor( - CursorPtr pCursor ) -{ - CCrsrHandle result; - CCrsrPtr curs; - int i, w, h; - unsigned short rowMask; - PixMap *pix; - ColorTable *ctab; - unsigned short *image; - - result = (CCrsrHandle) NewHandleClear(sizeof(CCrsr)); - if (!result) return NULL; - HLock((Handle)result); - curs = *result; - - // Initialize CCrsr - curs->crsrType = 0x8001; // 0x8000 = b&w, 0x8001 = color - curs->crsrMap = (PixMapHandle) NewHandleClear(sizeof(PixMap)); - if (!curs->crsrMap) goto pixAllocFailed; - HLock((Handle)curs->crsrMap); - pix = *curs->crsrMap; - curs->crsrData = NULL; // raw cursor image data (set below) - curs->crsrXData = NULL; // QD's processed data - curs->crsrXValid = 0; // zero means QD must re-process cursor data - curs->crsrXHandle = NULL; // reserved - memset(curs->crsr1Data, 0, CURSORWIDTH*CURSORHEIGHT/8); // b&w data - memset(curs->crsrMask, 0, CURSORWIDTH*CURSORHEIGHT/8); // b&w & color mask - curs->crsrHotSpot.h = min(CURSORWIDTH, pCursor->bits->xhot); // hot spot - curs->crsrHotSpot.v = min(CURSORHEIGHT, pCursor->bits->yhot); // hot spot - curs->crsrXTable = 0; // reserved - curs->crsrID = GetCTSeed(); // unique ID from Color Manager - - // Set the b&w data and mask - w = min(pCursor->bits->width, CURSORWIDTH); - h = min(pCursor->bits->height, CURSORHEIGHT); - rowMask = ~((1 << (CURSORWIDTH - w)) - 1); - for (i = 0; i < h; i++) { - curs->crsr1Data[i] = rowMask & - ((pCursor->bits->source[i*4]<<8) | pCursor->bits->source[i*4+1]); - curs->crsrMask[i] = rowMask & - ((pCursor->bits->mask[i*4]<<8) | pCursor->bits->mask[i*4+1]); - } - - // Set the color data and mask - // crsrMap: defines bit depth and size and colortable only - pix->rowBytes = (CURSORWIDTH * 2 / 8) | 0x8000; // last bit on means PixMap - SetRect(&pix->bounds, 0, 0, CURSORWIDTH, CURSORHEIGHT); // see TN 1020 - pix->pixelSize = 2; - pix->cmpCount = 1; - pix->cmpSize = 2; - // pix->pmTable set below - - // crsrData is the pixel data. crsrMap's baseAddr is not used. - curs->crsrData = NewHandleClear(CURSORWIDTH*CURSORHEIGHT * 2 / 8); - if (!curs->crsrData) goto imageAllocFailed; - HLock((Handle)curs->crsrData); - image = (unsigned short *) *curs->crsrData; - // Pixel data is just 1-bit data and mask interleaved (see above) - for (i = 0; i < h; i++) { - unsigned char s, m; - s = pCursor->bits->source[i*4] & (rowMask >> 8); - m = pCursor->bits->mask[i*4] & (rowMask >> 8); - image[2*i] = interleave(s, m); - s = pCursor->bits->source[i*4+1] & (rowMask & 0x00ff); - m = pCursor->bits->mask[i*4+1] & (rowMask & 0x00ff); - image[2*i+1] = interleave(s, m); - } - - // Build the color table (entries described above) - // NewPixMap allocates a color table handle. - pix->pmTable = (CTabHandle) NewHandleClear(sizeof(ColorTable) + 3 - * sizeof(ColorSpec)); - if (!pix->pmTable) goto ctabAllocFailed; - HLock((Handle)pix->pmTable); - ctab = *pix->pmTable; - ctab->ctSeed = GetCTSeed(); - ctab->ctFlags = 0; - ctab->ctSize = 3; // color count - 1 - CTAB_ENTER(ctab, 0, 0xffff, 0xffff, 0xffff); - CTAB_ENTER(ctab, 1, pCursor->backRed, pCursor->backGreen, - pCursor->backBlue); - CTAB_ENTER(ctab, 2, 0x0000, 0x0000, 0x0000); - CTAB_ENTER(ctab, 3, pCursor->foreRed, pCursor->foreGreen, - pCursor->foreBlue); - - HUnlock((Handle)pix->pmTable); // ctab - HUnlock((Handle)curs->crsrData); // image data - HUnlock((Handle)curs->crsrMap); // pix - HUnlock((Handle)result); // cursor - - return result; - - // "What we have here is a failure to allocate" -ctabAllocFailed: - HUnlock((Handle)curs->crsrData); - DisposeHandle((Handle)curs->crsrData); -imageAllocFailed: - HUnlock((Handle)curs->crsrMap); - DisposeHandle((Handle)curs->crsrMap); -pixAllocFailed: - HUnlock((Handle)result); - DisposeHandle((Handle)result); - return NULL; -} - - -/* - * FreeQDCursor - * Destroy a QuickDraw color cursor created with MakeQDCursor(). - * The cursor must not currently be on screen. - */ -static void FreeQDCursor(CCrsrHandle cursHandle) -{ - CCrsrPtr curs; - PixMap *pix; - - HLock((Handle)cursHandle); - curs = *cursHandle; - HLock((Handle)curs->crsrMap); - pix = *curs->crsrMap; - DisposeHandle((Handle)pix->pmTable); - HUnlock((Handle)curs->crsrMap); - DisposeHandle((Handle)curs->crsrMap); - DisposeHandle((Handle)curs->crsrData); - HUnlock((Handle)cursHandle); - DisposeHandle((Handle)cursHandle); -} - - -/* -=========================================================================== - - Pointer sprite functions - -=========================================================================== -*/ - -/* - * QuartzRealizeCursor - * Convert the X cursor representation to QuickDraw format if possible. - */ -Bool -QuartzRealizeCursor( - ScreenPtr pScreen, - CursorPtr pCursor ) -{ - CCrsrHandle qdCursor; - QuartzCursorScreenPtr ScreenPriv = CURSOR_PRIV(pScreen); - - if(!pCursor || !pCursor->bits) - return FALSE; - - // if the cursor is too big we use a software cursor - if ((pCursor->bits->height > CURSORHEIGHT) || - (pCursor->bits->width > CURSORWIDTH) || !ScreenPriv->useQDCursor) - { - if (quartzRootless) { - // rootless can't use a software cursor - return TRUE; - } else { - return (*ScreenPriv->spriteFuncs->RealizeCursor) - (pScreen, pCursor); - } - } - - // make new cursor image - qdCursor = MakeQDCursor(pCursor); - if (!qdCursor) return FALSE; - - // save the result - dixSetPrivate(&pCursor->devPrivates, pScreen, qdCursor); - - return TRUE; -} - - -/* - * QuartzUnrealizeCursor - * Free the storage space associated with a realized cursor. - */ -Bool -QuartzUnrealizeCursor( - ScreenPtr pScreen, - CursorPtr pCursor ) -{ - QuartzCursorScreenPtr ScreenPriv = CURSOR_PRIV(pScreen); - - if ((pCursor->bits->height > CURSORHEIGHT) || - (pCursor->bits->width > CURSORWIDTH) || !ScreenPriv->useQDCursor) - { - if (quartzRootless) { - return TRUE; - } else { - return (*ScreenPriv->spriteFuncs->UnrealizeCursor) - (pScreen, pCursor); - } - } else { - CCrsrHandle oldCursor = dixLookupPrivate(&pCursor->devPrivates, - pScreen); - if (currentCursor != oldCursor) { - // This should only fail when quitting, in which case we just leak. - FreeQDCursor(oldCursor); - } - dixSetPrivate(&pCursor->devPrivates, pScreen, NULL); - return TRUE; - } -} - - -/* - * QuartzSetCursor - * Set the cursor sprite and position. - * Use QuickDraw cursor if possible. - */ -static void -QuartzSetCursor( - ScreenPtr pScreen, - CursorPtr pCursor, - int x, - int y) -{ - QuartzCursorScreenPtr ScreenPriv = CURSOR_PRIV(pScreen); - - quartzLatentCursor = pCursor; - - // Don't touch Mac OS cursor if X is hidden! - if (!quartzServerVisible) - return; - - if (!pCursor) { - // Remove the cursor completely. - HIDE_QD_CURSOR(pScreen, ScreenPriv->qdCursorVisible); - if (! ScreenPriv->qdCursorMode) - (*ScreenPriv->spriteFuncs->SetCursor)(pScreen, 0, x, y); - } - else if ((pCursor->bits->height <= CURSORHEIGHT) && - (pCursor->bits->width <= CURSORWIDTH) && ScreenPriv->useQDCursor) - { - // Cursor is small enough to use QuickDraw directly. - if (! ScreenPriv->qdCursorMode) // remove the X cursor - (*ScreenPriv->spriteFuncs->SetCursor)(pScreen, 0, x, y); - ScreenPriv->qdCursorMode = TRUE; - - CHANGE_QD_CURSOR(dixLookupPrivate(&pCursor->devPrivates, pScreen)); - SHOW_QD_CURSOR(pScreen, ScreenPriv->qdCursorVisible); - } - else if (quartzRootless) { - // Rootless can't use a software cursor, so we just use Mac OS arrow. - CHANGE_QD_CURSOR(NULL); - SHOW_QD_CURSOR(pScreen, ScreenPriv->qdCursorVisible); - } - else { - // Cursor is too big for QuickDraw. Use X software cursor. - HIDE_QD_CURSOR(pScreen, ScreenPriv->qdCursorVisible); - ScreenPriv->qdCursorMode = FALSE; - (*ScreenPriv->spriteFuncs->SetCursor)(pScreen, pCursor, x, y); - } -} - - -/* - * QuartzReallySetCursor - * Set the QuickDraw cursor. Called from the main thread since changing the - * cursor with QuickDraw is not thread safe on dual processor machines. - */ -void -QuartzReallySetCursor() -{ - pthread_mutex_lock(&cursorMutex); - - if (currentCursor) { - SetCCursor(currentCursor); - } else { - SetCursor(&gQDArrow); - } - - pthread_cond_signal(&cursorCondition); - pthread_mutex_unlock(&cursorMutex); -} - - -/* - * QuartzMoveCursor - * Move the cursor. This is a noop for QuickDraw. - */ -static void -QuartzMoveCursor( - ScreenPtr pScreen, - int x, - int y) -{ - QuartzCursorScreenPtr ScreenPriv = CURSOR_PRIV(pScreen); - - // only the X cursor needs to be explicitly moved - if (!ScreenPriv->qdCursorMode) - (*ScreenPriv->spriteFuncs->MoveCursor)(pScreen, x, y); -} - - -static miPointerSpriteFuncRec quartzSpriteFuncsRec = { - QuartzRealizeCursor, - QuartzUnrealizeCursor, - QuartzSetCursor, - QuartzMoveCursor -}; - - -/* -=========================================================================== - - Pointer screen functions - -=========================================================================== -*/ - -/* - * QuartzCursorOffScreen - */ -static Bool QuartzCursorOffScreen(ScreenPtr *pScreen, int *x, int *y) -{ - return FALSE; -} - - -/* - * QuartzCrossScreen - */ -static void QuartzCrossScreen(ScreenPtr pScreen, Bool entering) -{ - return; -} - - -/* - * QuartzWarpCursor - * Change the cursor position without generating an event or motion history. - * The input coordinates (x,y) are in pScreen-local X11 coordinates. - * - */ -static void -QuartzWarpCursor( - ScreenPtr pScreen, - int x, - int y) -{ - static int neverMoved = TRUE; - - if (neverMoved) { - // Don't move the cursor the first time. This is the jump-to-center - // initialization, and it's annoying because we may still be in MacOS. - neverMoved = FALSE; - return; - } - - if (quartzServerVisible) { - CGDisplayErr cgErr; - CGPoint cgPoint; - // Only need to do this for one display. Any display will do. - CGDirectDisplayID cgID = QUARTZ_PRIV(pScreen)->displayIDs[0]; - CGRect cgRect = CGDisplayBounds(cgID); - - // Convert (x,y) to CoreGraphics screen-local CG coordinates. - // This is necessary because the X11 screen and CG screen may not - // coincide. (e.g. X11 screen may be moved to dodge the menu bar) - - // Make point in X11 global coordinates - cgPoint = CGPointMake(x + dixScreenOrigins[pScreen->myNum].x, - y + dixScreenOrigins[pScreen->myNum].y); - // Shift to CoreGraphics global screen coordinates - cgPoint.x += darwinMainScreenX; - cgPoint.y += darwinMainScreenY; - // Shift to CoreGraphics screen-local coordinates - cgPoint.x -= cgRect.origin.x; - cgPoint.y -= cgRect.origin.y; - - cgErr = CGDisplayMoveCursorToPoint(cgID, cgPoint); - if (cgErr != CGDisplayNoErr) { - ErrorF("Could not set cursor position with error code 0x%x.\n", - cgErr); - } - } - - miPointerWarpCursor(pScreen, x, y); - miPointerUpdate(); -} - - -static miPointerScreenFuncRec quartzScreenFuncsRec = { - QuartzCursorOffScreen, - QuartzCrossScreen, - QuartzWarpCursor, - NULL, - NULL -}; - - -/* -=========================================================================== - - Other screen functions - -=========================================================================== -*/ - -/* - * QuartzCursorQueryBestSize - * Handle queries for best cursor size - */ -static void -QuartzCursorQueryBestSize( - int class, - unsigned short *width, - unsigned short *height, - ScreenPtr pScreen) -{ - QuartzCursorScreenPtr ScreenPriv = CURSOR_PRIV(pScreen); - - if (class == CursorShape) { - *width = CURSORWIDTH; - *height = CURSORHEIGHT; - } else { - (*ScreenPriv->QueryBestSize)(class, width, height, pScreen); - } -} - - -/* - * QuartzInitCursor - * Initialize cursor support - */ -Bool -QuartzInitCursor( - ScreenPtr pScreen ) -{ - QuartzCursorScreenPtr ScreenPriv; - miPointerScreenPtr PointPriv; - DarwinFramebufferPtr dfb = SCREEN_PRIV(pScreen); - - // initialize software cursor handling (always needed as backup) - if (!miDCInitialize(pScreen, &quartzScreenFuncsRec)) { - return FALSE; - } - - ScreenPriv = xcalloc( 1, sizeof(QuartzCursorScreenRec) ); - if (!ScreenPriv) return FALSE; - - CURSOR_PRIV(pScreen) = ScreenPriv; - - // override some screen procedures - ScreenPriv->QueryBestSize = pScreen->QueryBestSize; - pScreen->QueryBestSize = QuartzCursorQueryBestSize; - - // initialize QuickDraw cursor handling - GetQDGlobalsArrow(&gQDArrow); - PointPriv = (miPointerScreenPtr) - dixLookupPrivate(&pScreen->devPrivates, miPointerScreenKey); - - ScreenPriv->spriteFuncs = PointPriv->spriteFuncs; - PointPriv->spriteFuncs = &quartzSpriteFuncsRec; - - if (!quartzRootless) - ScreenPriv->useQDCursor = QuartzFSUseQDCursor(dfb->colorBitsPerPixel); - else - ScreenPriv->useQDCursor = TRUE; - ScreenPriv->qdCursorMode = TRUE; - ScreenPriv->qdCursorVisible = TRUE; - - // initialize cursor mutex lock - pthread_mutex_init(&cursorMutex, NULL); - - // initialize condition for waiting - pthread_cond_init(&cursorCondition, NULL); - - return TRUE; -} - - -// X server is hiding. Restore the Aqua cursor. -void QuartzSuspendXCursor( - ScreenPtr pScreen ) -{ - QuartzCursorScreenPtr ScreenPriv = CURSOR_PRIV(pScreen); - - CHANGE_QD_CURSOR(NULL); - SHOW_QD_CURSOR(pScreen, ScreenPriv->qdCursorVisible); -} - - -// X server is showing. Restore the X cursor. -void QuartzResumeXCursor( - ScreenPtr pScreen, - int x, - int y ) -{ - QuartzSetCursor(pScreen, quartzLatentCursor, x, y); -} diff --git a/hw/xquartz/quartzCursor.h b/hw/xquartz/quartzCursor.h deleted file mode 100644 index 56a02098d..000000000 --- a/hw/xquartz/quartzCursor.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * quartzCursor.h - * - * External interface for Quartz hardware cursor - * - * Copyright (c) 2001 Torrey T. Lyons and Greg Parker. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - * Except as contained in this notice, the name(s) of the above copyright - * holders shall not be used in advertising or otherwise to promote the sale, - * use or other dealings in this Software without prior written authorization. - */ - -#ifndef QUARTZCURSOR_H -#define QUARTZCURSOR_H - -#include "screenint.h" - -Bool QuartzInitCursor(ScreenPtr pScreen); -void QuartzReallySetCursor(void); -void QuartzSuspendXCursor(ScreenPtr pScreen); -void QuartzResumeXCursor(ScreenPtr pScreen, int x, int y); - -#endif From 8944b77ec0c18476a25ba3179bcc45b338be22b8 Mon Sep 17 00:00:00 2001 From: Jeremy Huddleston Date: Wed, 2 Apr 2008 17:47:42 -0700 Subject: [PATCH 136/149] continue with gutting darwinEvents.c (cherry picked from commit c34fce7051b996633291dddc061b696ff737f3fb) --- hw/xquartz/darwinEvents.c | 124 +++++++++----------------------------- 1 file changed, 28 insertions(+), 96 deletions(-) diff --git a/hw/xquartz/darwinEvents.c b/hw/xquartz/darwinEvents.c index 46f567536..5b037d2fa 100644 --- a/hw/xquartz/darwinEvents.c +++ b/hw/xquartz/darwinEvents.c @@ -78,7 +78,7 @@ typedef struct _EventQueue { } EventQueueRec, *EventQueuePtr; static EventQueueRec darwinEventQueue; -xEvent *darwinEvents; +xEvent *darwinEvents = NULL; /* * DarwinPressModifierMask @@ -207,8 +207,11 @@ void DarwinEventHandler(int screenNum, xEventPtr xe, DeviceIntPtr dev, int neven } Bool DarwinEQInit(DevicePtr pKbd, DevicePtr pPtr) { + if (!darwinEvents) + darwinEvents = (xEvent *)xcalloc(sizeof(xEvent), GetMaximumEventsNum()); + if (!darwinEvents) + FatalError("Couldn't allocate event buffer\n"); - darwinEvents = (xEvent *)malloc(sizeof(xEvent) * GetMaximumEventsNum()); mieqInit(); mieqSetHandler(kXquartzActivate, DarwinEventHandler); mieqSetHandler(kXquartzDeactivate, DarwinEventHandler); @@ -225,13 +228,6 @@ Bool DarwinEQInit(DevicePtr pKbd, DevicePtr pPtr) { mieqSetHandler(kXquartzWindowState, DarwinEventHandler); mieqSetHandler(kXquartzWindowMoved, DarwinEventHandler); - darwinEventQueue.head = darwinEventQueue.tail = 0; - darwinEventQueue.lastEventTime = GetTimeInMillis (); - darwinEventQueue.pKbd = pKbd; - darwinEventQueue.pPtr = pPtr; - darwinEventQueue.pEnqueueScreen = screenInfo.screens[0]; - darwinEventQueue.pDequeueScreen = darwinEventQueue.pEnqueueScreen; - SetInputCheck(&input_check_zero, &input_check_flag); return TRUE; } @@ -255,8 +251,6 @@ void DarwinEQEnqueue(const xEventPtr e) { * Read and process events from the event queue until it is empty. */ void ProcessInputEvents(void) { - EventRec *e; - int x, y; xEvent xe; // button number and modifier mask of currently pressed fake button input_check_flag=0; @@ -265,92 +259,11 @@ void ProcessInputEvents(void) { mieqProcessInputEvents(); // Empty the signaling pipe - x = sizeof(xe); - while (x == sizeof(xe)) - x = read(darwinEventReadFD, &xe, sizeof(xe)); - - while (darwinEventQueue.head != darwinEventQueue.tail) - { - if (screenIsSaved == SCREEN_SAVER_ON) - dixSaveScreens (serverClient, SCREEN_SAVER_OFF, ScreenSaverReset); - - e = &darwinEventQueue.events[darwinEventQueue.head]; - xe = e->event; - - // Shift from global screen coordinates to coordinates relative to - // the origin of the current screen. - xe.u.keyButtonPointer.rootX -= darwinMainScreenX + - dixScreenOrigins[miPointerCurrentScreen()->myNum].x; - xe.u.keyButtonPointer.rootY -= darwinMainScreenY + - dixScreenOrigins[miPointerCurrentScreen()->myNum].y; - - /* ErrorF("old rootX = (%d,%d) darwinMainScreen = (%d,%d) dixScreenOrigins[%d]=(%d,%d)\n", - xe.u.keyButtonPointer.rootX, xe.u.keyButtonPointer.rootY, - darwinMainScreenX, darwinMainScreenY, - miPointerCurrentScreen()->myNum, - dixScreenOrigins[miPointerCurrentScreen()->myNum].x, - dixScreenOrigins[miPointerCurrentScreen()->myNum].y); */ - - //Assumption - screen switching can only occur on motion events - - if (e->pScreen != darwinEventQueue.pDequeueScreen) - { - darwinEventQueue.pDequeueScreen = e->pScreen; - x = xe.u.keyButtonPointer.rootX; - y = xe.u.keyButtonPointer.rootY; - if (darwinEventQueue.head == QUEUE_SIZE - 1) - darwinEventQueue.head = 0; - else - ++darwinEventQueue.head; - NewCurrentScreen (darwinEventQueue.pDequeueScreen, x, y); - } - else - { - if (darwinEventQueue.head == QUEUE_SIZE - 1) - darwinEventQueue.head = 0; - else - ++darwinEventQueue.head; - switch (xe.u.u.type) { - case KeyPress: - case KeyRelease: - ErrorF("Unexpected Keyboard event in DarwinProcessInputEvents\n"); - break; - - case ButtonPress: - ErrorF("Unexpected ButtonPress event in DarwinProcessInputEvents\n"); - break; - - case ButtonRelease: - ErrorF("Unexpected ButtonRelease event in DarwinProcessInputEvents\n"); - break; - - case MotionNotify: - ErrorF("Unexpected MotionNotify event in DarwinProcessInputEvents\n"); - break; - - case kXquartzUpdateModifiers: - ErrorF("Unexpected kXquartzUpdateModifiers event in DarwinProcessInputEvents\n"); - break; - - case kXquartzUpdateButtons: - ErrorF("Unexpected kXquartzUpdateButtons event in DarwinProcessInputEvents\n"); - break; - - case kXquartzScrollWheel: - ErrorF("Unexpected kXquartzScrollWheel event in DarwinProcessInputEvents\n"); - break; - - case kXquartzDeactivate: - DarwinReleaseModifiers(); - // fall through - default: - // Check for mode specific event - QuartzProcessEvent(&xe); - } - } + int x = sizeof(xe); + while (x == sizeof(xe)) { + DEBUG_LOG("draining pipe\n"); + x = read(darwinEventReadFD, &xe, sizeof(xe)); } - - // miPointerUpdate(); } /* Sends a null byte down darwinEventWriteFD, which will cause the @@ -368,6 +281,10 @@ void DarwinSendPointerEvents(int ev_type, int ev_button, int pointer_x, int poin static int darwinFakeMouseButtonMask = 0; int i, num_events; + if(!darwinEvents) { + ErrorF("DarwinSendPointerEvents called before darwinEvents was initialized\n"); + return; + } /* I can't find a spec for this, but at least GTK expects that tablets are just like mice, except they have either one or three extra valuators, in this order: @@ -421,6 +338,11 @@ void DarwinSendPointerEvents(int ev_type, int ev_button, int pointer_x, int poin void DarwinSendKeyboardEvents(int ev_type, int keycode) { int i, num_events; + if(!darwinEvents) { + ErrorF("DarwinSendKeyboardEvents called before darwinEvents was initialized\n"); + return; + } + if (old_flags == 0 && darwinSyncKeymap && darwinKeymapFile == NULL) { /* See if keymap has changed. */ @@ -447,6 +369,11 @@ void DarwinSendProximityEvents(int ev_type, int pointer_x, int pointer_y, tilt_x * INT32_MAX * 1.0f, tilt_y * INT32_MAX * 1.0f}; + if(!darwinEvents) { + ErrorF("DarwinSendProximityvents called before darwinEvents was initialized\n"); + return; +} + num_events = GetProximityEvents(darwinEvents, darwinPointer, ev_type, 0, 5, valuators); @@ -465,6 +392,11 @@ void DarwinSendScrollEvents(float count, int pointer_x, int pointer_y, tilt_x * INT32_MAX * 1.0f, tilt_y * INT32_MAX * 1.0f}; + if(!darwinEvents) { + ErrorF("DarwinSendScrollEvents called before darwinEvents was initialized\n"); + return; + } + for (count = fabs(count); count > 0.0; count = count - 1.0f) { int num_events = GetPointerEvents(darwinEvents, darwinPointer, ButtonPress, ev_button, POINTER_ABSOLUTE, 0, 5, valuators); From 89f1d880e83e32b72d35c4dbd6795defa6efa847 Mon Sep 17 00:00:00 2001 From: Ben Byer Date: Mon, 31 Mar 2008 19:47:28 -0700 Subject: [PATCH 137/149] nuke DarwinEventQueue (cherry picked from commit 1e0ec02202eeaffae480048b91bf02140ee29f8a) --- hw/xquartz/darwinEvents.c | 33 --------------------------------- hw/xquartz/quartz.c | 2 +- 2 files changed, 1 insertion(+), 34 deletions(-) diff --git a/hw/xquartz/darwinEvents.c b/hw/xquartz/darwinEvents.c index 5b037d2fa..230050f60 100644 --- a/hw/xquartz/darwinEvents.c +++ b/hw/xquartz/darwinEvents.c @@ -56,28 +56,10 @@ in this Software without prior written authorization from The Open Group. #define SCROLLWHEELUPFAKE 4 #define SCROLLWHEELDOWNFAKE 5 -#define QUEUE_SIZE 256 - -typedef struct _Event { - xEvent event; - ScreenPtr pScreen; -} EventRec, *EventPtr; - int input_check_zero, input_check_flag; static int old_flags = 0; // last known modifier state -typedef struct _EventQueue { - HWEventQueueType head, tail; /* long for SetInputCheck */ - CARD32 lastEventTime; /* to avoid time running backwards */ - Bool lastMotion; - EventRec events[QUEUE_SIZE]; /* static allocation for signals */ - DevicePtr pKbd, pPtr; /* device pointer, to get funcs */ - ScreenPtr pEnqueueScreen; /* screen events are being delivered to */ - ScreenPtr pDequeueScreen; /* screen events are being dispatched to */ -} EventQueueRec, *EventQueuePtr; - -static EventQueueRec darwinEventQueue; xEvent *darwinEvents = NULL; /* @@ -231,21 +213,6 @@ Bool DarwinEQInit(DevicePtr pKbd, DevicePtr pPtr) { return TRUE; } - -/* - * DarwinEQEnqueue - * Must be thread safe with ProcessInputEvents. - * DarwinEQEnqueue - called from event gathering thread - * ProcessInputEvents - called from X server thread - * DarwinEQEnqueue should never be called from more than one thread. - * - * This should be deprecated in favor of miEQEnqueue -- BB - */ -void DarwinEQEnqueue(const xEventPtr e) { - mieqEnqueue(NULL, e); - DarwinPokeEQ(); -} - /* * ProcessInputEvents * Read and process events from the event queue until it is empty. diff --git a/hw/xquartz/quartz.c b/hw/xquartz/quartz.c index 971c9b278..5dfdeeb30 100644 --- a/hw/xquartz/quartz.c +++ b/hw/xquartz/quartz.c @@ -401,7 +401,7 @@ QuartzMessageServerThread( va_end (args); } - DarwinEQEnqueue(&xe); + mieqEnqueue(NULL, &xe); } From 985c631b2e1f113039e6e620f030505435fd9815 Mon Sep 17 00:00:00 2001 From: Ben Byer Date: Mon, 31 Mar 2008 20:18:58 -0700 Subject: [PATCH 138/149] just a bit of juggling headers around -- we're preparing to call our Xquartz-specific event handlers directly as mieqHandlers (cherry picked from commit 4aedba5aa727e22316e8ca456f7218bea9ee0313) --- hw/xquartz/darwin.c | 2 +- hw/xquartz/darwin.h | 2 +- hw/xquartz/quartz.c | 3 +++ hw/xquartz/quartzCocoa.m | 3 ++- hw/xquartz/quartzPasteboard.c | 10 ++++++---- hw/xquartz/quartzPasteboard.h | 4 ++-- hw/xquartz/xpr/xprScreen.c | 1 + 7 files changed, 16 insertions(+), 9 deletions(-) diff --git a/hw/xquartz/darwin.c b/hw/xquartz/darwin.c index 8f2511dbb..002ea413d 100644 --- a/hw/xquartz/darwin.c +++ b/hw/xquartz/darwin.c @@ -880,7 +880,7 @@ void AbortDDX( void ) */ void -xf86SetRootClip (ScreenPtr pScreen, BOOL enable) +xf86SetRootClip (ScreenPtr pScreen, int enable) { WindowPtr pWin = WindowTable[pScreen->myNum]; WindowPtr pChild; diff --git a/hw/xquartz/darwin.h b/hw/xquartz/darwin.h index 9384b9dbb..8c3cabbd1 100644 --- a/hw/xquartz/darwin.h +++ b/hw/xquartz/darwin.h @@ -54,7 +54,7 @@ typedef struct { void DarwinPrintBanner(void); int DarwinParseModifierList(const char *constmodifiers); void DarwinAdjustScreenOrigins(ScreenInfo *pScreenInfo); -void xf86SetRootClip (ScreenPtr pScreen, BOOL enable); +void xf86SetRootClip (ScreenPtr pScreen, int enable); #define SCREEN_PRIV(pScreen) ((DarwinFramebufferPtr) \ dixLookupPrivate(&pScreen->devPrivates, darwinScreenKey)) diff --git a/hw/xquartz/quartz.c b/hw/xquartz/quartz.c index 5dfdeeb30..ec211cf0a 100644 --- a/hw/xquartz/quartz.c +++ b/hw/xquartz/quartz.c @@ -33,6 +33,7 @@ #endif #include "quartzCommon.h" +#include "inputstr.h" #include "quartz.h" #include "darwin.h" #include "darwinEvents.h" @@ -489,6 +490,7 @@ void QuartzProcessEvent(xEvent *xe) { GiveUp(0); break; +#if 0 case kXquartzReadPasteboard: QuartzReadPasteboard(); break; @@ -496,6 +498,7 @@ void QuartzProcessEvent(xEvent *xe) { case kXquartzWritePasteboard: QuartzWritePasteboard(); break; +#endif case kXquartzBringAllToFront: DEBUG_LOG("kXquartzBringAllToFront\n"); diff --git a/hw/xquartz/quartzCocoa.m b/hw/xquartz/quartzCocoa.m index 53e3f0897..d8f9c69e4 100644 --- a/hw/xquartz/quartzCocoa.m +++ b/hw/xquartz/quartzCocoa.m @@ -37,13 +37,14 @@ #endif #include "quartzCommon.h" +#include "inputstr.h" #include "quartzPasteboard.h" #define BOOL xBOOL #include "darwin.h" -#undef BOOL #include +#undef BOOL #include "pseudoramiX.h" diff --git a/hw/xquartz/quartzPasteboard.c b/hw/xquartz/quartzPasteboard.c index 0bf84f5d5..d47047ce0 100644 --- a/hw/xquartz/quartzPasteboard.c +++ b/hw/xquartz/quartzPasteboard.c @@ -34,6 +34,8 @@ #include #endif +#include "misc.h" +#include "inputstr.h" #include "quartzPasteboard.h" #include @@ -76,8 +78,8 @@ static char * QuartzReadCutBuffer(void) } // Write X cut buffer to Mac OS X pasteboard -// Called by ProcessInputEvents() in response to request from X server thread. -void QuartzWritePasteboard(void) +// Called by mieqProcessInputEvents() in response to request from X server thread. +void QuartzWritePasteboard(int screenNum, xEventPtr xe, DeviceIntPtr dev, int nevents) { char *text; text = QuartzReadCutBuffer(); @@ -90,8 +92,8 @@ void QuartzWritePasteboard(void) #define strequal(a, b) (0 == strcmp((a), (b))) // Read Mac OS X pasteboard into X cut buffer -// Called by ProcessInputEvents() in response to request from X server thread. -void QuartzReadPasteboard(void) +// Called by mieqProcessInputEvents() in response to request from X server thread. +void QuartzReadPasteboard(int screenNum, xEventPtr xe, DeviceIntPtr dev, int nevents) { char *oldText = QuartzReadCutBuffer(); char *text = QuartzReadCocoaPasteboard(); diff --git a/hw/xquartz/quartzPasteboard.h b/hw/xquartz/quartzPasteboard.h index d6a8ee815..b51cd88e0 100644 --- a/hw/xquartz/quartzPasteboard.h +++ b/hw/xquartz/quartzPasteboard.h @@ -34,11 +34,11 @@ #define _QUARTZPASTEBOARD_H // Aqua->X -void QuartzReadPasteboard(void); +void QuartzReadPasteboard(int, xEventPtr, DeviceIntPtr, int); char * QuartzReadCocoaPasteboard(void); // caller must free string // X->Aqua -void QuartzWritePasteboard(void); +void QuartzWritePasteboard(int, xEventPtr, DeviceIntPtr, int); void QuartzWriteCocoaPasteboard(char *text); #endif /* _QUARTZPASTEBOARD_H */ diff --git a/hw/xquartz/xpr/xprScreen.c b/hw/xquartz/xpr/xprScreen.c index b653a6e3b..5e144731d 100644 --- a/hw/xquartz/xpr/xprScreen.c +++ b/hw/xquartz/xpr/xprScreen.c @@ -32,6 +32,7 @@ #endif #include "quartzCommon.h" +#include "inputstr.h" #include "quartz.h" #include "xpr.h" #include "pseudoramiX.h" From c1be4e3379d8780dff20390939b657ca0973995a Mon Sep 17 00:00:00 2001 From: Ben Byer Date: Mon, 31 Mar 2008 21:04:37 -0700 Subject: [PATCH 139/149] shovelling code around ... (cherry picked from commit 2143182ba49195bbb2e9163ea6872fd68e7a4a85) --- dix/main.c | 14 ++++ hw/xquartz/darwinEvents.c | 106 +++++++++++++++++++++++++++++-- hw/xquartz/darwinKeyboard.c | 8 +++ hw/xquartz/quartz.c | 123 ++---------------------------------- hw/xquartz/quartz.h | 2 +- 5 files changed, 130 insertions(+), 123 deletions(-) diff --git a/dix/main.c b/dix/main.c index db4347341..8f6507f5c 100644 --- a/dix/main.c +++ b/dix/main.c @@ -113,6 +113,9 @@ Equipment Corporation. #include "dispatch.h" /* InitProcVectors() */ #endif +#include +pthread_key_t threadname_key=0; + #ifdef DPMSExtension #define DPMS_SERVER #include @@ -248,6 +251,17 @@ main(int argc, char *argv[], char *envp[]) char *xauthfile; HWEventQueueType alwaysCheckForInput[2]; + if(threadname_key == 0) ErrorF("pthread_key_create returned %d\n", pthread_key_create(&threadname_key, NULL)); + ErrorF("threadname_key = %d\n", threadname_key); + if(pthread_getspecific(threadname_key) == NULL) { + char *nameptr = malloc(32); + sprintf(nameptr, "main thread %d", random()); + // strcpy(nameptr, "main thread"); + ErrorF("calling: pthread_setspecific(%d, %s)=%d\n", threadname_key, nameptr, pthread_setspecific(threadname_key, nameptr)); + if (pthread_getspecific(threadname_key) != NULL) ErrorF("current thread: %s\n", (char *)pthread_getspecific(threadname_key)); + } else { + if (pthread_getspecific(threadname_key) != NULL) ErrorF("thread was already: %s\n", (char *)pthread_getspecific(threadname_key)); + } display = "0"; InitGlobals(); diff --git a/hw/xquartz/darwinEvents.c b/hw/xquartz/darwinEvents.c index 230050f60..28a712dab 100644 --- a/hw/xquartz/darwinEvents.c +++ b/hw/xquartz/darwinEvents.c @@ -52,6 +52,11 @@ in this Software without prior written authorization from The Open Group. #include #include +#define _APPLEWM_SERVER_ +#include "applewmExt.h" +#include + + /* Fake button press/release for scroll wheel move. */ #define SCROLLWHEELUPFAKE 4 #define SCROLLWHEELDOWNFAKE 5 @@ -177,14 +182,103 @@ static void DarwinSimulateMouseClick( DarwinUpdateModifiers(KeyPress, modifierMask); } +/* Generic handler for Xquartz-specifc events. When possible, these should + be moved into their own individual functions and set as handlers using + mieqSetHandler. */ + void DarwinEventHandler(int screenNum, xEventPtr xe, DeviceIntPtr dev, int nevents) { int i; DEBUG_LOG("DarwinEventHandler(%d, %p, %p, %d)\n", screenNum, xe, dev, nevents); for (i=0; iu.u.type) { - case kXquartzControllerNotify: - DEBUG_LOG("kXquartzControllerNotify\n"); - AppleWMSendEvent(AppleWMControllerNotify, - AppleWMControllerNotifyMask, - xe->u.clientMessage.u.l.longs0, - xe->u.clientMessage.u.l.longs1); - break; - - case kXquartzPasteboardNotify: - DEBUG_LOG("kXquartzPasteboardNotify\n"); - AppleWMSendEvent(AppleWMPasteboardNotify, - AppleWMPasteboardNotifyMask, - xe->u.clientMessage.u.l.longs0, - xe->u.clientMessage.u.l.longs1); - break; - - case kXquartzActivate: - DEBUG_LOG("kXquartzActivate\n"); - QuartzShow(xe->u.keyButtonPointer.rootX, - xe->u.keyButtonPointer.rootY); - AppleWMSendEvent(AppleWMActivationNotify, - AppleWMActivationNotifyMask, - AppleWMIsActive, 0); - break; - - case kXquartzDeactivate: - DEBUG_LOG("kXquartzDeactivate\n"); - AppleWMSendEvent(AppleWMActivationNotify, - AppleWMActivationNotifyMask, - AppleWMIsInactive, 0); - QuartzHide(); - break; - - case kXquartzDisplayChanged: - DEBUG_LOG("kXquartzDisplayChanged\n"); - QuartzUpdateScreens(); - break; - - case kXquartzWindowState: - DEBUG_LOG("kXquartzWindowState\n"); - RootlessNativeWindowStateChanged(xe->u.clientMessage.u.l.longs0, - xe->u.clientMessage.u.l.longs1); - break; - - case kXquartzWindowMoved: - DEBUG_LOG("kXquartzWindowMoved\n"); - RootlessNativeWindowMoved ((WindowPtr)xe->u.clientMessage.u.l.longs0); - break; - - case kXquartzToggleFullscreen: - DEBUG_LOG("kXquartzToggleFullscreen\n"); -#ifdef DARWIN_DDX_MISSING - if (quartzEnableRootless) QuartzSetFullscreen(!quartzHasRoot); - else if (quartzHasRoot) QuartzHide(); - else QuartzShow(); -#else - // ErrorF("kXquartzToggleFullscreen not implemented\n"); -#endif - break; - - case kXquartzSetRootless: - DEBUG_LOG("kXquartzSetRootless\n"); -#ifdef DARWIN_DDX_MISSING - QuartzSetRootless(xe->u.clientMessage.u.l.longs0); - if (!quartzEnableRootless && !quartzHasRoot) QuartzHide(); -#else - // ErrorF("kXquartzSetRootless not implemented\n"); -#endif - break; - - case kXquartzSetRootClip: - QuartzSetRootClip((BOOL)xe->u.clientMessage.u.l.longs0); - break; - - case kXquartzQuit: - GiveUp(0); - break; - -#if 0 - case kXquartzReadPasteboard: - QuartzReadPasteboard(); - break; - - case kXquartzWritePasteboard: - QuartzWritePasteboard(); - break; -#endif - - case kXquartzBringAllToFront: - DEBUG_LOG("kXquartzBringAllToFront\n"); - RootlessOrderAllWindows(); - break; - - case kXquartzSpaceChanged: - DEBUG_LOG("kXquartzSpaceChanged\n"); - QuartzSpaceChanged(xe->u.clientMessage.u.l.longs0); - break; - default: - ErrorF("Unknown application defined event type %d.\n", xe->u.u.type); - } -} diff --git a/hw/xquartz/quartz.h b/hw/xquartz/quartz.h index fbe308a92..ffe06f9c6 100644 --- a/hw/xquartz/quartz.h +++ b/hw/xquartz/quartz.h @@ -130,5 +130,5 @@ void QuartzInitOutput(int argc,char **argv); void QuartzInitInput(int argc, char **argv); void QuartzGiveUp(void); void QuartzProcessEvent(xEvent *xe); - +void QuartzDisplayChangedHandler(int screenNum, xEventPtr xe, DeviceIntPtr dev, int nevents); #endif From e9e2d88436597875f102085d216dc0a8fce1450a Mon Sep 17 00:00:00 2001 From: Ben Byer Date: Mon, 31 Mar 2008 22:55:24 -0700 Subject: [PATCH 140/149] moved and renamed QuartzMessageServerThread to DarwinSendDDXEvent to make more clear what it actually does. (cherry picked from commit bee2b377efc930e25017636e5112093a3a6549c7) --- hw/xquartz/X11Application.m | 14 +++++++------- hw/xquartz/X11Controller.m | 32 ++++++++++++++++---------------- hw/xquartz/darwin.h | 3 +++ hw/xquartz/darwinEvents.c | 28 ++++++++++++++++++++++++++++ hw/xquartz/darwinEvents.h | 2 ++ hw/xquartz/quartz.c | 31 ------------------------------- hw/xquartz/xpr/xprScreen.c | 8 ++++---- 7 files changed, 60 insertions(+), 58 deletions(-) diff --git a/hw/xquartz/X11Application.m b/hw/xquartz/X11Application.m index 147b4b4c0..28bb52995 100644 --- a/hw/xquartz/X11Application.m +++ b/hw/xquartz/X11Application.m @@ -1,6 +1,6 @@ /* X11Application.m -- subclass of NSApplication to multiplex events - Copyright (c) 2002-2007 Apple Inc. + Copyright (c) 2002-2008 Apple Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files @@ -166,7 +166,7 @@ static void message_kit_thread (SEL selector, NSObject *arg) { static TSMDocumentID x11_document; DEBUG_LOG("state=%d, _x_active=%d, \n", state, _x_active) if (state) { - QuartzMessageServerThread (kXquartzActivate, 0); + DarwinSendDDXEvent(kXquartzActivate, 0); if (!_x_active) { if (x11_document == 0 && darwinKeymapFile == NULL) { @@ -178,10 +178,10 @@ static void message_kit_thread (SEL selector, NSObject *arg) { if (x11_document != 0) ActivateTSMDocument (x11_document); } } else { - QuartzMessageServerThread (kXquartzDeactivate, 0); + DarwinSendDDXEvent(kXquartzDeactivate, 0); if (_x_active && x11_document != 0) - DeactivateTSMDocument (x11_document); + DeactivateTSMDocument (x11_document); } _x_active = state; @@ -246,7 +246,7 @@ static void message_kit_thread (SEL selector, NSObject *arg) { swallow_up = 0; for_x = NO; #ifdef DARWIN_DDX_MISSING - QuartzMessageServerThread (kXquartzToggleFullscreen, 0); + DarwinSendDDXEvent(kXquartzToggleFullscreen, 0); #endif } } else { @@ -271,7 +271,7 @@ static void message_kit_thread (SEL selector, NSObject *arg) { case NSApplicationActivatedEventType: for_x = NO; if ([self modalWindow] == nil) { - for_appkit = NO; + for_appkit = NO; /* FIXME: hack to avoid having to pass the event to appkit, which would cause it to raise one of its windows. */ @@ -654,7 +654,7 @@ static NSMutableArray * cfarray_to_nsarray (CFArrayRef in) { /* This will end up at the end of the responder chain. */ - (void) copy:sender { - QuartzMessageServerThread (kXquartzPasteboardNotify, 1, + DarwinSendDDXEvent(kXquartzPasteboardNotify, 1, AppleWMCopyToPasteboard); } diff --git a/hw/xquartz/X11Controller.m b/hw/xquartz/X11Controller.m index aa9fa94be..5bf4f4d52 100644 --- a/hw/xquartz/X11Controller.m +++ b/hw/xquartz/X11Controller.m @@ -1,6 +1,6 @@ /* X11Controller.m -- connect the IB ui, also the NSApp delegate - Copyright (c) 2002-2007 Apple Inc. All rights reserved. + Copyright (c) 2002-2008 Apple Inc. All rights reserved. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files @@ -103,7 +103,7 @@ { [NSApp activateIgnoringOtherApps:YES]; - QuartzMessageServerThread (kXquartzControllerNotify, 2, + DarwinSendDDXEvent(kXquartzControllerNotify, 2, AppleWMWindowMenuItem, [sender tag]); } @@ -254,7 +254,7 @@ [self remove_window_menu]; [self install_window_menu:list]; - QuartzMessageServerThread (kXquartzControllerNotify, 1, + DarwinSendDDXEvent(kXquartzControllerNotify, 1, AppleWMWindowMenuNotify); } @@ -539,20 +539,20 @@ objectValueForTableColumn:(NSTableColumn *)tableColumn row:(int)row - (void) hide_window:sender { if ([X11App x_active]) - QuartzMessageServerThread (kXquartzControllerNotify, 1, AppleWMHideWindow); + DarwinSendDDXEvent(kXquartzControllerNotify, 1, AppleWMHideWindow); else NSBeep (); /* FIXME: something here */ } - (IBAction)bring_to_front:sender { - QuartzMessageServerThread(kXquartzControllerNotify, 1, AppleWMBringAllToFront); + DarwinSendDDXEvent(kXquartzControllerNotify, 1, AppleWMBringAllToFront); } - (IBAction)close_window:sender { if ([X11App x_active]) - QuartzMessageServerThread (kXquartzControllerNotify, 1, AppleWMCloseWindow); + DarwinSendDDXEvent(kXquartzControllerNotify, 1, AppleWMCloseWindow); else [[NSApp keyWindow] performClose:sender]; } @@ -560,7 +560,7 @@ objectValueForTableColumn:(NSTableColumn *)tableColumn row:(int)row - (IBAction)minimize_window:sender { if ([X11App x_active]) - QuartzMessageServerThread (kXquartzControllerNotify, 1, AppleWMMinimizeWindow); + DarwinSendDDXEvent(kXquartzControllerNotify, 1, AppleWMMinimizeWindow); else [[NSApp keyWindow] performMiniaturize:sender]; } @@ -568,19 +568,19 @@ objectValueForTableColumn:(NSTableColumn *)tableColumn row:(int)row - (IBAction)zoom_window:sender { if ([X11App x_active]) - QuartzMessageServerThread (kXquartzControllerNotify, 1, AppleWMZoomWindow); + DarwinSendDDXEvent(kXquartzControllerNotify, 1, AppleWMZoomWindow); else [[NSApp keyWindow] performZoom:sender]; } - (IBAction) next_window:sender { - QuartzMessageServerThread (kXquartzControllerNotify, 1, AppleWMNextWindow); + DarwinSendDDXEvent(kXquartzControllerNotify, 1, AppleWMNextWindow); } - (IBAction) previous_window:sender { - QuartzMessageServerThread (kXquartzControllerNotify, 1, AppleWMPreviousWindow); + DarwinSendDDXEvent(kXquartzControllerNotify, 1, AppleWMPreviousWindow); } - (IBAction) enable_fullscreen_changed:sender @@ -588,7 +588,7 @@ objectValueForTableColumn:(NSTableColumn *)tableColumn row:(int)row int value = ![enable_fullscreen intValue]; #ifdef DARWIN_DDX_MISSING - QuartzMessageServerThread (kXquartzSetRootless, 1, value); + DarwinSendDDXEvent(kXquartzSetRootless, 1, value); #endif [NSApp prefs_set_boolean:@PREFS_ROOTLESS value:value]; @@ -598,7 +598,7 @@ objectValueForTableColumn:(NSTableColumn *)tableColumn row:(int)row - (IBAction) toggle_fullscreen:sender { #ifdef DARWIN_DDX_MISSING - QuartzMessageServerThread (kXquartzToggleFullscreen, 0); + DarwinSendDDXEvent(kXquartzToggleFullscreen, 0); #endif } @@ -661,7 +661,7 @@ objectValueForTableColumn:(NSTableColumn *)tableColumn row:(int)row - (IBAction) quit:sender { - QuartzMessageServerThread (kXquartzQuit, 0); + DarwinSendDDXEvent(kXquartzQuit, 0); } - (IBAction) x11_help:sender @@ -684,12 +684,12 @@ objectValueForTableColumn:(NSTableColumn *)tableColumn row:(int)row - (void) applicationDidHide:(NSNotification *)notify { - QuartzMessageServerThread (kXquartzControllerNotify, 1, AppleWMHideAll); + DarwinSendDDXEvent(kXquartzControllerNotify, 1, AppleWMHideAll); } - (void) applicationDidUnhide:(NSNotification *)notify { - QuartzMessageServerThread (kXquartzControllerNotify, 1, AppleWMShowAll); + DarwinSendDDXEvent(kXquartzControllerNotify, 1, AppleWMShowAll); } - (NSApplicationTerminateReply) applicationShouldTerminate:sender @@ -717,7 +717,7 @@ objectValueForTableColumn:(NSTableColumn *)tableColumn row:(int)row [X11App prefs_synchronize]; /* shutdown the X server, it will exit () for us. */ - QuartzMessageServerThread (kXquartzQuit, 0); + DarwinSendDDXEvent(kXquartzQuit, 0); /* In case it doesn't, exit anyway after a while. */ while (sleep (10) != 0) ; diff --git a/hw/xquartz/darwin.h b/hw/xquartz/darwin.h index 8c3cabbd1..01e6f41f2 100644 --- a/hw/xquartz/darwin.h +++ b/hw/xquartz/darwin.h @@ -1,4 +1,5 @@ /* + * Copyright (C) 2008 Apple, Inc. * Copyright (c) 2001-2004 Torrey T. Lyons. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -120,6 +121,8 @@ enum { kXquartzWindowMoved, // window has moved on screen }; +void DarwinSendDDXEvent(int type, int argc, ...); + #define ENABLE_DEBUG_LOG 1 #ifdef ENABLE_DEBUG_LOG diff --git a/hw/xquartz/darwinEvents.c b/hw/xquartz/darwinEvents.c index 28a712dab..b6cd3f2b0 100644 --- a/hw/xquartz/darwinEvents.c +++ b/hw/xquartz/darwinEvents.c @@ -476,3 +476,31 @@ void DarwinUpdateModKeys(int flags) { DarwinUpdateModifiers(KeyPress, ~old_flags & flags); old_flags = flags; } + + +/* + * DarwinSendDDXEvent + * Send the X server thread a message by placing it on the event queue. + */ +void DarwinSendDDXEvent(int type, int argc, ...) { + xEvent xe; + INT32 *argv; + int i, max_args; + va_list args; + + memset(&xe, 0, sizeof(xe)); + xe.u.u.type = type; + xe.u.clientMessage.u.l.type = type; + + argv = &xe.u.clientMessage.u.l.longs0; + max_args = 4; + + if (argc > 0 && argc <= max_args) { + va_start (args, argc); + for (i = 0; i < argc; i++) + argv[i] = (int) va_arg (args, int); + va_end (args); + } + + mieqEnqueue(NULL, &xe); +} diff --git a/hw/xquartz/darwinEvents.h b/hw/xquartz/darwinEvents.h index 1d8e92a7b..7c56be9c8 100644 --- a/hw/xquartz/darwinEvents.h +++ b/hw/xquartz/darwinEvents.h @@ -1,4 +1,5 @@ /* + * Copyright (c) 2008 Apple, Inc. * Copyright (c) 2001-2004 Torrey T. Lyons. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a @@ -43,4 +44,5 @@ void DarwinUpdateModKeys(int flags); void DarwinEventHandler(int screenNum, xEventPtr xe, DeviceIntPtr dev, int nevents); + #endif /* _DARWIN_EVENTS_H */ diff --git a/hw/xquartz/quartz.c b/hw/xquartz/quartz.c index a65bd3748..96dc021a6 100644 --- a/hw/xquartz/quartz.c +++ b/hw/xquartz/quartz.c @@ -373,34 +373,3 @@ void QuartzSpaceChanged(uint32_t space_id) { /* Do something special here, so we don't depend on quartz-wm for spaces to work... */ DEBUG_LOG("Space Changed (%u) ... do something interesting...\n", space_id); } - -/* - * QuartzMessageServerThread - * Send the X server thread a message by placing it on the event queue. - */ -void -QuartzMessageServerThread( - int type, - int argc, ...) -{ - xEvent xe; - INT32 *argv; - int i, max_args; - va_list args; - - memset(&xe, 0, sizeof(xe)); - xe.u.u.type = type; - xe.u.clientMessage.u.l.type = type; - - argv = &xe.u.clientMessage.u.l.longs0; - max_args = 4; - - if (argc > 0 && argc <= max_args) { - va_start (args, argc); - for (i = 0; i < argc; i++) - argv[i] = (int) va_arg (args, int); - va_end (args); - } - - mieqEnqueue(NULL, &xe); -} diff --git a/hw/xquartz/xpr/xprScreen.c b/hw/xquartz/xpr/xprScreen.c index 5e144731d..91bf25ac2 100644 --- a/hw/xquartz/xpr/xprScreen.c +++ b/hw/xquartz/xpr/xprScreen.c @@ -68,7 +68,7 @@ static void eventHandler(unsigned int type, const void *arg, switch (type) { case XP_EVENT_DISPLAY_CHANGED: DEBUG_LOG("XP_EVENT_DISPLAY_CHANGED\n"); - QuartzMessageServerThread(kXquartzDisplayChanged, 0); + DarwinSendDDXEvent(kXquartzDisplayChanged, 0); break; case XP_EVENT_WINDOW_STATE_CHANGED: @@ -76,7 +76,7 @@ static void eventHandler(unsigned int type, const void *arg, const xp_window_state_event *ws_arg = arg; DEBUG_LOG("XP_EVENT_WINDOW_STATE_CHANGED: id=%d, state=%d\n", ws_arg->id, ws_arg->state); - QuartzMessageServerThread(kXquartzWindowState, 2, + DarwinSendDDXEvent(kXquartzWindowState, 2, ws_arg->id, ws_arg->state); } else { DEBUG_LOG("XP_EVENT_WINDOW_STATE_CHANGED: ignored\n"); @@ -88,7 +88,7 @@ static void eventHandler(unsigned int type, const void *arg, if (arg_size == sizeof(xp_window_id)) { xp_window_id id = * (xp_window_id *) arg; WindowPtr pWin = xprGetXWindow(id); - QuartzMessageServerThread(kXquartzWindowMoved, 1, pWin); + DarwinSendDDXEvent(kXquartzWindowMoved, 1, pWin); } break; @@ -111,7 +111,7 @@ static void eventHandler(unsigned int type, const void *arg, ErrorF("XP_EVENT_SPACE_CHANGED\n"); if(arg_size == sizeof(uint32_t)) { uint32_t space_id = *(uint32_t *)arg; - QuartzMessageServerThread(kXquartzSpaceChanged, 1, space_id); + DarwinSendDDXEvent(kXquartzSpaceChanged, 1, space_id); } break; default: From 15b0084f1ab23042190d8beeb3f088b92dee5a10 Mon Sep 17 00:00:00 2001 From: Ben Byer Date: Mon, 31 Mar 2008 23:31:25 -0700 Subject: [PATCH 141/149] formatting cleanup for X11Application.m (no code changes) (cherry picked from commit eb083d3f68f459d90417558da1ed00729b749950) --- hw/xquartz/X11Application.m | 493 +++++++++++++++++------------------- 1 file changed, 237 insertions(+), 256 deletions(-) diff --git a/hw/xquartz/X11Application.m b/hw/xquartz/X11Application.m index 28bb52995..2844fca10 100644 --- a/hw/xquartz/X11Application.m +++ b/hw/xquartz/X11Application.m @@ -166,171 +166,170 @@ static void message_kit_thread (SEL selector, NSObject *arg) { static TSMDocumentID x11_document; DEBUG_LOG("state=%d, _x_active=%d, \n", state, _x_active) if (state) { - DarwinSendDDXEvent(kXquartzActivate, 0); - - if (!_x_active) { - if (x11_document == 0 && darwinKeymapFile == NULL) { - OSType types[1]; - types[0] = kUnicodeDocument; - NewTSMDocument (1, types, &x11_document, 0); - } - - if (x11_document != 0) ActivateTSMDocument (x11_document); - } + DarwinSendDDXEvent(kXquartzActivate, 0); + + if (!_x_active) { + if (x11_document == 0 && darwinKeymapFile == NULL) { + OSType types[1]; + types[0] = kUnicodeDocument; + NewTSMDocument (1, types, &x11_document, 0); + } + + if (x11_document != 0) ActivateTSMDocument (x11_document); + } } else { - DarwinSendDDXEvent(kXquartzDeactivate, 0); - - if (_x_active && x11_document != 0) - DeactivateTSMDocument (x11_document); - } - - _x_active = state; + DarwinSendDDXEvent(kXquartzDeactivate, 0); + + if (_x_active && x11_document != 0) + DeactivateTSMDocument (x11_document); + } + + _x_active = state; } - (void) became_key:(NSWindow *)win { - [self activateX:NO]; + [self activateX:NO]; } - (void) sendEvent:(NSEvent *)e { - NSEventType type; - BOOL for_appkit, for_x; + NSEventType type; + BOOL for_appkit, for_x; + + type = [e type]; + + /* By default pass down the responder chain and to X. */ + for_appkit = YES; + for_x = YES; - type = [e type]; - - /* By default pass down the responder chain and to X. */ - for_appkit = YES; - for_x = YES; - - switch (type) { - case NSLeftMouseDown: case NSRightMouseDown: case NSOtherMouseDown: - case NSLeftMouseUp: case NSRightMouseUp: case NSOtherMouseUp: - if ([e window] != nil) { - /* Pointer event has an (AppKit) window. Probably something for the kit. */ - for_x = NO; - if (_x_active) [self activateX:NO]; - } else if ([self modalWindow] == nil) { - /* Must be an X window. Tell appkit it doesn't have focus. */ - WindowPtr pWin = xprGetXWindowFromAppKit([e windowNumber]); - if (pWin) RootlessReorderWindow(pWin); - for_appkit = NO; - - if ([self isActive]) { - [self deactivate]; - - if (!_x_active && quartzProcs->IsX11Window([e window], - [e windowNumber])) - [self activateX:YES]; - } - } - break; - - case NSKeyDown: case NSKeyUp: - if (_x_active) { - static int swallow_up; - - /* No kit window is focused, so send it to X. */ - for_appkit = NO; - if (type == NSKeyDown) { - /* Before that though, see if there are any global - shortcuts bound to it. */ - - if (X11EnableKeyEquivalents - && [[self mainMenu] performKeyEquivalent:e]) { - swallow_up = [e keyCode]; - for_x = NO; - } else if (!quartzEnableRootless - && ([e modifierFlags] & ALL_KEY_MASKS) - == (NSCommandKeyMask | NSAlternateKeyMask) - && ([e keyCode] == 0 /*a*/ - || [e keyCode] == 53 /*Esc*/)) { - swallow_up = 0; - for_x = NO; + switch (type) { + case NSLeftMouseDown: case NSRightMouseDown: case NSOtherMouseDown: + case NSLeftMouseUp: case NSRightMouseUp: case NSOtherMouseUp: + if ([e window] != nil) { + /* Pointer event has an (AppKit) window. Probably something for the kit. */ + for_x = NO; + if (_x_active) [self activateX:NO]; + } else if ([self modalWindow] == nil) { + /* Must be an X window. Tell appkit it doesn't have focus. */ + WindowPtr pWin = xprGetXWindowFromAppKit([e windowNumber]); + if (pWin) RootlessReorderWindow(pWin); + for_appkit = NO; + + if ([self isActive]) { + [self deactivate]; + if (!_x_active && quartzProcs->IsX11Window([e window], + [e windowNumber])) + [self activateX:YES]; + } + } + break; + + case NSKeyDown: case NSKeyUp: + if (_x_active) { + static int swallow_up; + + /* No kit window is focused, so send it to X. */ + for_appkit = NO; + if (type == NSKeyDown) { + /* Before that though, see if there are any global + shortcuts bound to it. */ + + if (X11EnableKeyEquivalents + && [[self mainMenu] performKeyEquivalent:e]) { + swallow_up = [e keyCode]; + for_x = NO; + } else if (!quartzEnableRootless + && ([e modifierFlags] & ALL_KEY_MASKS) + == (NSCommandKeyMask | NSAlternateKeyMask) + && ([e keyCode] == 0 /*a*/ + || [e keyCode] == 53 /*Esc*/)) { + swallow_up = 0; + for_x = NO; #ifdef DARWIN_DDX_MISSING - DarwinSendDDXEvent(kXquartzToggleFullscreen, 0); + DarwinSendDDXEvent(kXquartzToggleFullscreen, 0); #endif + } + } else { + /* If we saw a key equivalent on the down, don't pass + the up through to X. */ + + if (swallow_up != 0 && [e keyCode] == swallow_up) { + swallow_up = 0; + for_x = NO; + } + } + } else for_x = NO; + break; + + case NSFlagsChanged: + /* For the l33t X users who remap modifier keys to normal keysyms. */ + if (!_x_active) for_x = NO; + break; + + case NSAppKitDefined: + switch ([e subtype]) { + case NSApplicationActivatedEventType: + for_x = NO; + if ([self modalWindow] == nil) { + for_appkit = NO; + + /* FIXME: hack to avoid having to pass the event to appkit, + which would cause it to raise one of its windows. */ + _appFlags._active = YES; + + [self activateX:YES]; + if ([e data2] & 0x10) X11ApplicationSetFrontProcess(); + } + break; + + case 18: /* ApplicationDidReactivate */ + if (quartzHasRoot) for_appkit = NO; + break; + + case NSApplicationDeactivatedEventType: + for_x = NO; + [self activateX:NO]; + break; + } + break; + + default: break; /* for gcc */ } - } else { - /* If we saw a key equivalent on the down, don't pass - the up through to X. */ - - if (swallow_up != 0 && [e keyCode] == swallow_up) { - swallow_up = 0; - for_x = NO; - } - } - } else for_x = NO; - break; - - case NSFlagsChanged: - /* For the l33t X users who remap modifier keys to normal keysyms. */ - if (!_x_active) for_x = NO; - break; - - case NSAppKitDefined: - switch ([e subtype]) { - case NSApplicationActivatedEventType: - for_x = NO; - if ([self modalWindow] == nil) { - for_appkit = NO; - - /* FIXME: hack to avoid having to pass the event to appkit, - which would cause it to raise one of its windows. */ - _appFlags._active = YES; - - [self activateX:YES]; - if ([e data2] & 0x10) X11ApplicationSetFrontProcess(); - } - break; - - case 18: /* ApplicationDidReactivate */ - if (quartzHasRoot) for_appkit = NO; - break; - - case NSApplicationDeactivatedEventType: - for_x = NO; - [self activateX:NO]; - break; - } - break; - - default: break; /* for gcc */ - } - - if (for_appkit) [super sendEvent:e]; - - if (for_x) send_nsevent (type, e); + + if (for_appkit) [super sendEvent:e]; + + if (for_x) send_nsevent (type, e); } - (void) set_window_menu:(NSArray *)list { - [_controller set_window_menu:list]; + [_controller set_window_menu:list]; } - (void) set_window_menu_check:(NSNumber *)n { - [_controller set_window_menu_check:n]; + [_controller set_window_menu_check:n]; } - (void) set_apps_menu:(NSArray *)list { - [_controller set_apps_menu:list]; + [_controller set_apps_menu:list]; } - (void) set_front_process:unused { - [NSApp activateIgnoringOtherApps:YES]; + [NSApp activateIgnoringOtherApps:YES]; - if ([self modalWindow] == nil) - [self activateX:YES]; + if ([self modalWindow] == nil) + [self activateX:YES]; } - (void) set_can_quit:(NSNumber *)state { - [_controller set_can_quit:[state boolValue]]; + [_controller set_can_quit:[state boolValue]]; } - (void) server_ready:unused { - [_controller server_ready]; + [_controller server_ready]; } - (void) show_hide_menubar:(NSNumber *)state { - if ([state boolValue]) ShowMenuBar (); - else HideMenuBar (); + if ([state boolValue]) ShowMenuBar (); + else HideMenuBar (); } @@ -348,57 +347,57 @@ static void cfrelease (CFAllocatorRef a, const void *b) { } static CFMutableArrayRef nsarray_to_cfarray (NSArray *in) { - CFMutableArrayRef out; - CFArrayCallBacks cb; - NSObject *ns; - const CFTypeRef *cf; - int i, count; - - memset (&cb, 0, sizeof (cb)); - cb.version = 0; - cb.retain = cfretain; - cb.release = cfrelease; - - count = [in count]; - out = CFArrayCreateMutable (NULL, count, &cb); - - for (i = 0; i < count; i++) { - ns = [in objectAtIndex:i]; - - if ([ns isKindOfClass:[NSArray class]]) - cf = (CFTypeRef) nsarray_to_cfarray ((NSArray *) ns); - else - cf = CFRetain ((CFTypeRef) ns); - - CFArrayAppendValue (out, cf); - CFRelease (cf); - } - - return out; + CFMutableArrayRef out; + CFArrayCallBacks cb; + NSObject *ns; + const CFTypeRef *cf; + int i, count; + + memset (&cb, 0, sizeof (cb)); + cb.version = 0; + cb.retain = cfretain; + cb.release = cfrelease; + + count = [in count]; + out = CFArrayCreateMutable (NULL, count, &cb); + + for (i = 0; i < count; i++) { + ns = [in objectAtIndex:i]; + + if ([ns isKindOfClass:[NSArray class]]) + cf = (CFTypeRef) nsarray_to_cfarray ((NSArray *) ns); + else + cf = CFRetain ((CFTypeRef) ns); + + CFArrayAppendValue (out, cf); + CFRelease (cf); + } + + return out; } static NSMutableArray * cfarray_to_nsarray (CFArrayRef in) { - NSMutableArray *out; - const CFTypeRef *cf; - NSObject *ns; - int i, count; - - count = CFArrayGetCount (in); - out = [[NSMutableArray alloc] initWithCapacity:count]; - - for (i = 0; i < count; i++) { - cf = CFArrayGetValueAtIndex (in, i); - - if (CFGetTypeID (cf) == CFArrayGetTypeID ()) - ns = cfarray_to_nsarray ((CFArrayRef) cf); - else - ns = [(id)cf retain]; - - [out addObject:ns]; - [ns release]; - } - - return out; + NSMutableArray *out; + const CFTypeRef *cf; + NSObject *ns; + int i, count; + + count = CFArrayGetCount (in); + out = [[NSMutableArray alloc] initWithCapacity:count]; + + for (i = 0; i < count; i++) { + cf = CFArrayGetValueAtIndex (in, i); + + if (CFGetTypeID (cf) == CFArrayGetTypeID ()) + ns = cfarray_to_nsarray ((CFArrayRef) cf); + else + ns = [(id)cf retain]; + + [out addObject:ns]; + [ns release]; + } + + return out; } - (CFPropertyListRef) prefs_get:(NSString *)key { @@ -855,86 +854,68 @@ convert_flags (unsigned int nsflags) { return xflags; } - -// This code should probably be merged with that in XDarwin's XServer.m - BB static void send_nsevent (NSEventType type, NSEvent *e) { - // static unsigned int button_state = 0; - NSRect screen; - NSPoint location; - NSWindow *window; - int pointer_x, pointer_y, ev_button, ev_type; - float pressure, tilt_x, tilt_y; + NSRect screen; + NSPoint location; + NSWindow *window; + int pointer_x, pointer_y, ev_button, ev_type; + float pressure, tilt_x, tilt_y; + + /* convert location to global top-left coordinates */ + location = [e locationInWindow]; + window = [e window]; + screen = [[[NSScreen screens] objectAtIndex:0] frame]; - // int num_events=0, i=0, state; - // xEvent xe; - - /* convert location to global top-left coordinates */ - location = [e locationInWindow]; - window = [e window]; - screen = [[[NSScreen screens] objectAtIndex:0] frame]; - if (window != nil) { - NSRect frame = [window frame]; - pointer_x = location.x + frame.origin.x; - pointer_y = (((screen.origin.y + screen.size.height) - - location.y) - frame.origin.y); - } else { - pointer_x = location.x; - pointer_y = (screen.origin.y + screen.size.height) - location.y; - } - - pointer_y -= aquaMenuBarHeight; - // state = convert_flags ([e modifierFlags]); - - pressure = 0; // for tablets - tilt_x = 0; - tilt_y = 0; - - switch (type) { - case NSLeftMouseDown: ev_button=1; ev_type=ButtonPress; goto handle_mouse; - case NSOtherMouseDown: ev_button=2; ev_type=ButtonPress; goto handle_mouse; - case NSRightMouseDown: ev_button=3; ev_type=ButtonPress; goto handle_mouse; - case NSLeftMouseUp: ev_button=1; ev_type=ButtonRelease; goto handle_mouse; - case NSOtherMouseUp: ev_button=2; ev_type=ButtonRelease; goto handle_mouse; - case NSRightMouseUp: ev_button=3; ev_type=ButtonRelease; goto handle_mouse; - case NSLeftMouseDragged: ev_button=1; ev_type=MotionNotify; goto handle_mouse; - case NSOtherMouseDragged: ev_button=2; ev_type=MotionNotify; goto handle_mouse; - case NSRightMouseDragged: ev_button=3; ev_type=MotionNotify; goto handle_mouse; - case NSTabletPoint: - pressure = [e pressure]; - tilt_x = [e tilt].x; - tilt_y = [e tilt].y; // fall through - case NSMouseMoved: ev_button=0; ev_type=MotionNotify; goto handle_mouse; - handle_mouse: - - /* I'm not sure the below code is necessary or useful (-bb) - if(ev_type==ButtonPress) { - if (!quartzProcs->IsX11Window([e window], [e windowNumber])) { - fprintf(stderr, "Dropping event because it's not a window\n"); - break; + NSRect frame = [window frame]; + pointer_x = location.x + frame.origin.x; + pointer_y = (((screen.origin.y + screen.size.height) + - location.y) - frame.origin.y); + } else { + pointer_x = location.x; + pointer_y = (screen.origin.y + screen.size.height) - location.y; } - button_state |= (1 << ev_button); - DarwinSendPointerEvents(ev_type, ev_button, pointer_x, pointer_y); - } else if (ev_type==ButtonRelease && (button_state & (1 << ev_button)) == 0) break; - */ - // if ([e subtype] == NSTabletPointEventSubtype) pressure = [e pressure]; - DarwinSendPointerEvents(ev_type, ev_button, pointer_x, pointer_y, - pressure, tilt_x, tilt_y); - break; - case NSScrollWheel: - DarwinSendScrollEvents([e deltaY], pointer_x, pointer_y, - pressure, tilt_x, tilt_y); - break; - - case NSKeyDown: // do we need to translate these keyCodes? - case NSKeyUp: - DarwinSendKeyboardEvents((type == NSKeyDown)?KeyPress:KeyRelease, [e keyCode]); - break; + pointer_y -= aquaMenuBarHeight; - case NSFlagsChanged: - DarwinUpdateModKeys([e modifierFlags]); - break; - default: break; /* for gcc */ - } + pressure = 0; // for tablets + tilt_x = 0; + tilt_y = 0; + + switch (type) { + case NSLeftMouseDown: ev_button=1; ev_type=ButtonPress; goto handle_mouse; + case NSOtherMouseDown: ev_button=2; ev_type=ButtonPress; goto handle_mouse; + case NSRightMouseDown: ev_button=3; ev_type=ButtonPress; goto handle_mouse; + case NSLeftMouseUp: ev_button=1; ev_type=ButtonRelease; goto handle_mouse; + case NSOtherMouseUp: ev_button=2; ev_type=ButtonRelease; goto handle_mouse; + case NSRightMouseUp: ev_button=3; ev_type=ButtonRelease; goto handle_mouse; + case NSLeftMouseDragged: ev_button=1; ev_type=MotionNotify; goto handle_mouse; + case NSOtherMouseDragged: ev_button=2; ev_type=MotionNotify; goto handle_mouse; + case NSRightMouseDragged: ev_button=3; ev_type=MotionNotify; goto handle_mouse; + case NSTabletPoint: + pressure = [e pressure]; + tilt_x = [e tilt].x; + tilt_y = [e tilt].y; // fall through + case NSMouseMoved: ev_button=0; ev_type=MotionNotify; goto handle_mouse; + handle_mouse: + +// if ([e subtype] == NSTabletPointEventSubtype) pressure = [e pressure]; + DarwinSendPointerEvents(ev_type, ev_button, pointer_x, pointer_y, + pressure, tilt_x, tilt_y); + break; + + case NSScrollWheel: + DarwinSendScrollEvents([e deltaY], pointer_x, pointer_y, + pressure, tilt_x, tilt_y); + break; + + case NSKeyDown: case NSKeyUp: + DarwinSendKeyboardEvents((type == NSKeyDown)?KeyPress:KeyRelease, [e keyCode]); + break; + + case NSFlagsChanged: + DarwinUpdateModKeys([e modifierFlags]); + break; + default: break; /* for gcc */ + } } From c737d04c758e03e32f692a31ed2a665ccbafa931 Mon Sep 17 00:00:00 2001 From: Ben Byer Date: Tue, 1 Apr 2008 00:40:46 -0700 Subject: [PATCH 142/149] The AppKit thread should not be calling directly into the X server functions to change state when the keyboard is reloaded; instead, pass it as an event. (cherry picked from commit 7e653f806ff5508aace059312156f319a9ed4479) --- hw/xquartz/darwin.h | 7 +------ hw/xquartz/darwinEvents.c | 7 ++++--- hw/xquartz/darwinKeyboard.c | 12 +++++++----- hw/xquartz/darwinKeyboard.h | 2 +- hw/xquartz/quartzKeyboard.h | 1 - 5 files changed, 13 insertions(+), 16 deletions(-) diff --git a/hw/xquartz/darwin.h b/hw/xquartz/darwin.h index 01e6f41f2..df92d8b49 100644 --- a/hw/xquartz/darwin.h +++ b/hw/xquartz/darwin.h @@ -91,13 +91,8 @@ extern int darwinMainScreenY; * Special ddx events understood by the X server */ enum { - kXquartzUpdateModifiers // update all modifier keys + kXquartzReloadKeymap // Reload system keymap = LASTEvent+1, // (from X.h list of event names) - kXquartzUpdateButtons, // update state of mouse buttons 2 and up - kXquartzScrollWheel, // scroll wheel event - /* - * Quartz-specific events -- not used in IOKit mode - */ kXquartzActivate, // restore X drawing and cursor kXquartzDeactivate, // clip X drawing and switch to Aqua cursor kXquartzSetRootClip, // enable or disable drawing to the X screen diff --git a/hw/xquartz/darwinEvents.c b/hw/xquartz/darwinEvents.c index b6cd3f2b0..3afbaf890 100644 --- a/hw/xquartz/darwinEvents.c +++ b/hw/xquartz/darwinEvents.c @@ -289,6 +289,7 @@ Bool DarwinEQInit(DevicePtr pKbd, DevicePtr pPtr) { FatalError("Couldn't allocate event buffer\n"); mieqInit(); + mieqSetHandler(kXquartzReloadKeymap, DarwinKeyboardReloadHandler); mieqSetHandler(kXquartzActivate, DarwinEventHandler); mieqSetHandler(kXquartzDeactivate, DarwinEventHandler); mieqSetHandler(kXquartzSetRootClip, DarwinEventHandler); @@ -322,7 +323,7 @@ void ProcessInputEvents(void) { // Empty the signaling pipe int x = sizeof(xe); while (x == sizeof(xe)) { - DEBUG_LOG("draining pipe\n"); +// DEBUG_LOG("draining pipe\n"); x = read(darwinEventReadFD, &xe, sizeof(xe)); } } @@ -412,8 +413,8 @@ void DarwinSendKeyboardEvents(int ev_type, int keycode) { this_seed = QuartzSystemKeymapSeed(); if (this_seed != last_seed) { - last_seed = this_seed; - DarwinKeyboardReload(darwinKeyboard); + last_seed = this_seed; + DarwinSendDDXEvent(kXquartzReloadKeymap, 0); } } diff --git a/hw/xquartz/darwinKeyboard.c b/hw/xquartz/darwinKeyboard.c index 355d9f066..6f2758e53 100644 --- a/hw/xquartz/darwinKeyboard.c +++ b/hw/xquartz/darwinKeyboard.c @@ -850,16 +850,18 @@ static Bool InitModMap(register KeyClassPtr keyc) { } -void DarwinKeyboardReload(DeviceIntPtr pDev) { +void DarwinKeyboardReloadHandler(int screenNum, xEventPtr xe, DeviceIntPtr dev, int nevents) { KeySymsRec keySyms; - + if (dev == NULL) dev = darwinKeyboard; + + DEBUG_LOG("DarwinKeyboardReloadHandler(%p)\n", dev); DarwinLoadKeyboardMapping(&keySyms); - if (SetKeySymsMap(&pDev->key->curKeySyms, &keySyms)) { + if (SetKeySymsMap(&dev->key->curKeySyms, &keySyms)) { /* now try to update modifiers. */ - memmove(pDev->key->modifierMap, keyInfo.modMap, MAP_LENGTH); - InitModMap(pDev->key); + memmove(dev->key->modifierMap, keyInfo.modMap, MAP_LENGTH); + InitModMap(dev->key); } else DEBUG_LOG("SetKeySymsMap=0\n"); SendMappingNotify(MappingKeyboard, MIN_KEYCODE, NUM_KEYCODES, 0); diff --git a/hw/xquartz/darwinKeyboard.h b/hw/xquartz/darwinKeyboard.h index 5cf64c7d1..762f65919 100644 --- a/hw/xquartz/darwinKeyboard.h +++ b/hw/xquartz/darwinKeyboard.h @@ -31,7 +31,7 @@ /* Provided for darwinEvents.c */ extern darwinKeyboardInfo keyInfo; -void DarwinKeyboardReload(DeviceIntPtr pDev); +void DarwinKeyboardReloadHandler(int screenNum, xEventPtr xe, DeviceIntPtr dev, int nevents); void DarwinKeyboardInit(DeviceIntPtr pDev); int DarwinModifierNXKeycodeToNXKey(unsigned char keycode, int *outSide); int DarwinModifierNXKeyToNXKeycode(int key, int side); diff --git a/hw/xquartz/quartzKeyboard.h b/hw/xquartz/quartzKeyboard.h index 8131b5650..4f495bb46 100644 --- a/hw/xquartz/quartzKeyboard.h +++ b/hw/xquartz/quartzKeyboard.h @@ -46,7 +46,6 @@ typedef struct darwinKeyboardInfo_struct { } darwinKeyboardInfo; /* These functions need to be implemented by Xquartz, XDarwin, etc. */ -void DarwinKeyboardReload(DeviceIntPtr pDev); Bool QuartzReadSystemKeymap(darwinKeyboardInfo *info); unsigned int QuartzSystemKeymapSeed(void); From 2e42b67b82db0f9128dd00e339b9dfdd9fe6d667 Mon Sep 17 00:00:00 2001 From: Jeremy Huddleston Date: Wed, 2 Apr 2008 18:05:34 -0700 Subject: [PATCH 143/149] XQuartz: Change reporting of space change to debug log rather than stderr (cherry picked from commit ed15556a9fc4ebdb88f42961052fc8456082165f) --- hw/xquartz/xpr/xprScreen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/xquartz/xpr/xprScreen.c b/hw/xquartz/xpr/xprScreen.c index 91bf25ac2..d685fca33 100644 --- a/hw/xquartz/xpr/xprScreen.c +++ b/hw/xquartz/xpr/xprScreen.c @@ -108,7 +108,7 @@ static void eventHandler(unsigned int type, const void *arg, } break; case XP_EVENT_SPACE_CHANGED: - ErrorF("XP_EVENT_SPACE_CHANGED\n"); + DEBUG_LOG("XP_EVENT_SPACE_CHANGED\n"); if(arg_size == sizeof(uint32_t)) { uint32_t space_id = *(uint32_t *)arg; DarwinSendDDXEvent(kXquartzSpaceChanged, 1, space_id); From f0915fb3c4a9712200882440a64d11dc595a02bb Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 4 Apr 2008 09:29:51 +1000 Subject: [PATCH 144/149] quirk: add quirk for ACER EDID --- hw/xfree86/modes/xf86EdidModes.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/hw/xfree86/modes/xf86EdidModes.c b/hw/xfree86/modes/xf86EdidModes.c index f15c39642..8f7d45dd6 100644 --- a/hw/xfree86/modes/xf86EdidModes.c +++ b/hw/xfree86/modes/xf86EdidModes.c @@ -158,6 +158,11 @@ static Bool quirk_first_detailed_preferred (int scrnIndex, xf86MonPtr DDC) DDC->vendor.prod_id == 765) return TRUE; + /* ACR of some sort RH #284231 */ + if (memcmp (DDC->vendor.name, "ACR", 4) == 0 && + DDC->vendor.prod_id == 2423) + return TRUE; + return FALSE; } From 16a8ce75585ea360c39e0ffce4f7bb26a359b754 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Thu, 3 Apr 2008 16:44:32 -0400 Subject: [PATCH 145/149] Only autoload RECORD if it was enabled. --- hw/xfree86/common/xf86Config.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hw/xfree86/common/xf86Config.c b/hw/xfree86/common/xf86Config.c index 8de742620..208e23dc4 100644 --- a/hw/xfree86/common/xf86Config.c +++ b/hw/xfree86/common/xf86Config.c @@ -119,7 +119,9 @@ static ModuleDefault ModuleDefaults[] = { {.name = "dbe", .toLoad = TRUE, .load_opt=NULL}, {.name = "glx", .toLoad = TRUE, .load_opt=NULL}, {.name = "freetype", .toLoad = TRUE, .load_opt=NULL}, +#ifdef XRECORD {.name = "record", .toLoad = TRUE, .load_opt=NULL}, +#endif {.name = "dri", .toLoad = TRUE, .load_opt=NULL}, {.name = "dri2", .toLoad = TRUE, .load_opt=NULL}, {.name = NULL, .toLoad = FALSE, .load_opt=NULL} From ec17900f52bbd25d07566834756e5c7e832e0463 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20H=C3=B8gsberg?= Date: Fri, 4 Apr 2008 10:46:45 -0400 Subject: [PATCH 146/149] Convert __DRIconfigs after we've made sure createNewScreen succeeded. --- GL/glx/glxdri.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/GL/glx/glxdri.c b/GL/glx/glxdri.c index ffa9a0b76..9cd0738a0 100644 --- a/GL/glx/glxdri.c +++ b/GL/glx/glxdri.c @@ -1117,13 +1117,13 @@ __glXDRIscreenProbe(ScreenPtr pScreen) &driConfigs, screen); - screen->base.fbconfigs = glxConvertConfigs(screen->core, driConfigs); - if (screen->driScreen == NULL) { LogMessage(X_ERROR, "AIGLX error: Calling driver entry point failed"); goto handle_error; } + screen->base.fbconfigs = glxConvertConfigs(screen->core, driConfigs); + initializeExtensions(screen); DRIGetTexOffsetFuncs(pScreen, &screen->texOffsetStart, From d1de3dda8efe501d4192c8a99c34ab4265316c32 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Mon, 17 Mar 2008 14:22:39 -0700 Subject: [PATCH 147/149] Fix clock_gettime presence detect on FreeBSD. For non-Linux, _POSIX_C_SOURCE and friends restrict symbols defined rather than enabling defines of symbols. Additionally, CLOCK_MONOTONIC was apparently added to the standard around 2000 anyway, not 1993. --- configure.ac | 2 ++ 1 file changed, 2 insertions(+) diff --git a/configure.ac b/configure.ac index 985c8e227..1431f4b8f 100644 --- a/configure.ac +++ b/configure.ac @@ -722,7 +722,9 @@ if ! test "x$have_clock_gettime" = xno; then LIBS="$CLOCK_LIBS" AC_RUN_IFELSE([ +#ifdef __linux__ #define _POSIX_C_SOURCE 199309L +#endif #include int main(int argc, char *argv[[]]) { From cc7c045bae01d90d8f1b750080ba48a96e983c68 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Fri, 4 Apr 2008 12:58:12 -0400 Subject: [PATCH 148/149] Fix PCI config space cycles from int10 emulator. The top bit of 0xCF8 is an enable bit, not part of the domain. Sending cycles to domain 128 instead of domain 0 is rarely the right thing to do. --- hw/xfree86/int10/helper_exec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/xfree86/int10/helper_exec.c b/hw/xfree86/int10/helper_exec.c index 9daff22dc..c3af5bc08 100644 --- a/hw/xfree86/int10/helper_exec.c +++ b/hw/xfree86/int10/helper_exec.c @@ -461,7 +461,7 @@ Mem_wl(CARD32 addr, CARD32 val) static CARD32 PciCfg1Addr = 0; #define PCI_OFFSET(x) ((x) & 0x000000ff) -#define PCI_TAG(x) ((x) & 0xffffff00) +#define PCI_TAG(x) ((x) & 0x7fffff00) static struct pci_device* pci_device_for_cfg_address (CARD32 addr) From 6c0cfe3d43b177c4cfaf7e228f32c655f9a98459 Mon Sep 17 00:00:00 2001 From: Julien Cristau Date: Fri, 4 Apr 2008 19:01:40 +0200 Subject: [PATCH 149/149] Fix the clock_gettime check for glibc-based non-Linux systems We need to define _POSIX_C_SOURCE on glibc, not just Linux, so add a new test for the __GLIBC__ macro. --- configure.ac | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index 1431f4b8f..025b91214 100644 --- a/configure.ac +++ b/configure.ac @@ -705,6 +705,15 @@ if test "x$NEED_DBUS" = xyes; then fi CONFIG_LIB='$(top_builddir)/config/libconfig.a' +AC_MSG_CHECKING([for glibc...]) +AC_PREPROC_IFELSE([ +#include +#ifndef __GLIBC__ +#error +#endif +], glibc=yes, glibc=no) +AC_MSG_RESULT([$glibc]) + AC_CHECK_FUNCS([clock_gettime], [have_clock_gettime=yes], [AC_CHECK_LIB([rt], [clock_gettime], [have_clock_gettime=-lrt], [have_clock_gettime=no])]) @@ -720,11 +729,13 @@ if ! test "x$have_clock_gettime" = xno; then LIBS_SAVE="$LIBS" LIBS="$CLOCK_LIBS" + CPPFLAGS_SAVE="$CPPFLAGS" + + if test x"$glibc" = xyes; then + CPPFLAGS="$CPPFLAGS -D_POSIX_C_SOURCE=199309L" + fi AC_RUN_IFELSE([ -#ifdef __linux__ -#define _POSIX_C_SOURCE 199309L -#endif #include int main(int argc, char *argv[[]]) { @@ -739,6 +750,7 @@ int main(int argc, char *argv[[]]) { [MONOTONIC_CLOCK="cross compiling"]) LIBS="$LIBS_SAVE" + CPPFLAGS="$CPPFLAGS_SAVE" else MONOTONIC_CLOCK=no fi