From 429b4b20d5708d608fd55f91dd5bcd4ac0b51a12 Mon Sep 17 00:00:00 2001 From: George Staplin Date: Sat, 22 Nov 2008 10:57:58 -0700 Subject: [PATCH 1/6] XQuartz: GL: Add a branch to prevent a NULL DrawablePtr structure access. In attach() check for pDraw being NULL, and also print an ErrorF message, because we eventually want to track down why this is occuring. It's unclear how this occurs, but as I noted in the 1.4 branch, I believe that the DrawablePtr/struct _Drawable -> id is the member being accessed that causes KERN_PROTECTION_FAILURE at 0x0000000000000004 This passes my tests using: env LIBGL_ALWAYS_INDIRECT=1 ./sometest. I fixed a warning: caused by initializing the screen->base.visuals with the configs. It is a ** not a *. It seems that some other part of GLX will initialize this for us. (cherry picked from commit 17f6a261fca6d5856069dce28bb4838261afc6bc) --- hw/xquartz/GL/indirect.c | 61 ++++++++++++++++++++++++---------------- 1 file changed, 37 insertions(+), 24 deletions(-) diff --git a/hw/xquartz/GL/indirect.c b/hw/xquartz/GL/indirect.c index 5f508a461..3cdb0122a 100644 --- a/hw/xquartz/GL/indirect.c +++ b/hw/xquartz/GL/indirect.c @@ -298,49 +298,61 @@ static void surface_notify(void *_arg, void *data) { } } -static void attach(__GLXAquaContext *context, __GLXAquaDrawable *draw) { +static BOOL attach(__GLXAquaContext *context, __GLXAquaDrawable *draw) { DrawablePtr pDraw; - GLAQUA_DEBUG_MSG("attach(%p, %p)\n", context, draw); + + GLAQUA_DEBUG_MSG("attach(%p, %p)\n", context, draw); + + if(NULL == context || NULL == draw) + return TRUE; + pDraw = draw->base.pDraw; - if (draw->sid == 0) { -// if (!quartzProcs->CreateSurface(pDraw->pScreen, pDraw->id, pDraw, - if (!DRICreateSurface(pDraw->pScreen, pDraw->id, pDraw, - 0, &draw->sid, NULL, - surface_notify, draw)) - return; - draw->pDraw = pDraw; - } + if(NULL == pDraw) { + ErrorF("%s:attach() pDraw is NULL!\n", __FILE__); + return TRUE; + } + if (draw->sid == 0) { + //if (!quartzProcs->CreateSurface(pDraw->pScreen, pDraw->id, pDraw, + if (!DRICreateSurface(pDraw->pScreen, pDraw->id, pDraw, + 0, &draw->sid, NULL, + surface_notify, draw)) + return TRUE; + draw->pDraw = pDraw; + } + if (!context->isAttached || context->sid != draw->sid) { x_list *lst; - + if (xp_attach_gl_context(context->ctx, draw->sid) != Success) { -// quartzProcs->DestroySurface(pDraw->pScreen, pDraw->id, pDraw, + //quartzProcs->DestroySurface(pDraw->pScreen, pDraw->id, pDraw, DRIDestroySurface(pDraw->pScreen, pDraw->id, pDraw, - surface_notify, draw); + surface_notify, draw); if (surface_hash != NULL) x_hash_table_remove(surface_hash, x_cvt_uint_to_vptr(draw->sid)); - + draw->sid = 0; - return; + return TRUE; } - + context->isAttached = TRUE; context->sid = draw->sid; - + if (surface_hash == NULL) surface_hash = x_hash_table_new(NULL, NULL, NULL, NULL); - + lst = x_hash_table_lookup(surface_hash, x_cvt_uint_to_vptr(context->sid), NULL); if (x_list_find(lst, context) == NULL) { lst = x_list_prepend(lst, context); x_hash_table_insert(surface_hash, x_cvt_uint_to_vptr(context->sid), lst); } - + GLAQUA_DEBUG_MSG("attached 0x%x to 0x%x\n", (unsigned int) pDraw->id, (unsigned int) draw->sid); } + + return FALSE; } #if 0 // unused @@ -370,11 +382,12 @@ static void unattach(__GLXAquaContext *context) { static int __glXAquaContextMakeCurrent(__GLXcontext *baseContext) { CGLError gl_err; __GLXAquaContext *context = (__GLXAquaContext *) baseContext; - __GLXAquaDrawable *drawPriv = (__GLXAquaDrawable *) context->base.drawPriv; - + __GLXAquaDrawable *drawPriv = (__GLXAquaDrawable *) context->base.drawPriv; + GLAQUA_DEBUG_MSG("glAquaMakeCurrent (ctx 0x%p)\n", baseContext); - attach(context, drawPriv); + if(attach(context, drawPriv)) + return /*error*/ 0; gl_err = CGLSetCurrentContext(context->ctx); if (gl_err != 0) @@ -1310,8 +1323,8 @@ static __GLXscreen * __glXAquaScreenProbe(ScreenPtr pScreen) { screen->base.fbconfigs = configs; screen->base.numFBConfigs = 1; - screen->base.visuals = configs; - screen->base.numVisuals = 1; + screen->base.visuals = NULL; + screen->base.numVisuals = 0; GlxSetVisualConfig(GLX_ALL_VISUALS); From 6eb33bc0cb2e62339d323e1f1894015d7e3142f3 Mon Sep 17 00:00:00 2001 From: George Staplin Date: Sat, 22 Nov 2008 11:37:08 -0700 Subject: [PATCH 2/6] XQuartz: GL: Remove the inclusion of glcontextmodes.h. Add some commentary about future directions needed for the GLX drawable creation and destruction code. Match xalloc with xfree. I made some minor formatting improvements. (cherry picked from commit b772d64fce31d16b498c621096e39d5203994d6e) --- hw/xquartz/GL/indirect.c | 37 +++++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/hw/xquartz/GL/indirect.c b/hw/xquartz/GL/indirect.c index 3cdb0122a..4de49355d 100644 --- a/hw/xquartz/GL/indirect.c +++ b/hw/xquartz/GL/indirect.c @@ -81,7 +81,6 @@ typedef unsigned long long GLuint64EXT; typedef long long GLint64EXT; #include -#include "glcontextmodes.h" #include #include @@ -156,7 +155,7 @@ struct __GLXAquaContext { }; struct __GLXAquaDrawable { - __GLXdrawable base; + __GLXdrawable base; DrawablePtr pDraw; xp_surface_id sid; }; @@ -1350,14 +1349,34 @@ static __GLXscreen * __glXAquaScreenProbe(ScreenPtr pScreen) { return &screen->base; } -static void __glXAquaDrawableDestroy(__GLXdrawable *base) { - GLAQUA_DEBUG_MSG("glAquaDestroyDrawablePrivate\n"); +static void __glXAquaDrawableCopySubBuffer (__GLXdrawable *drawable, + int x, int y, int w, int h) { + /*TODO finish me*/ +} + +static void __glXAquaDrawableDestroy(__GLXdrawable *base) { + /* gstaplin: base is the head of the structure, so it's at the same + * offset in memory. + * Is this safe with strict aliasing? I noticed that the other dri code + * does this too... + */ + __GLXAquaDrawable *glxPriv = (__GLXAquaDrawable *)base; + + GLAQUA_DEBUG_MSG(__func__); + /* It doesn't work to call DRIDestroySurface here, the drawable's already gone.. But dri.c notices the window destruction and frees the surface itself. */ - free(base); + /*gstaplin: verify the statement above. The surface destroy + *messages weren't making it through, and may still not be. + *We need a good test case for surface creation and destruction. + *We also need a good way to enable introspection on the server + *to validate the test, beyond using gdb with print. + */ + + xfree(glxPriv); } static __GLXdrawable * @@ -1371,11 +1390,13 @@ __glXAquaScreenCreateDrawable(__GLXscreen *screen, GLAQUA_DEBUG_MSG("glAquaScreenCreateDrawable(%p,%p,%d,%p)\n", context, pDraw, drawId, modes); glxPriv = xalloc(sizeof *glxPriv); - if (glxPriv == NULL) return NULL; + + if(glxPriv == NULL) + return NULL; memset(glxPriv, 0, sizeof *glxPriv); - if (!__glXDrawableInit(&glxPriv->base, screen, pDraw, type, drawId, conf)) { + if(!__glXDrawableInit(&glxPriv->base, screen, pDraw, type, drawId, conf)) { xfree(glxPriv); return NULL; } @@ -1383,7 +1404,7 @@ __glXAquaScreenCreateDrawable(__GLXscreen *screen, glxPriv->base.destroy = __glXAquaDrawableDestroy; glxPriv->base.resize = __glXAquaDrawableResize; glxPriv->base.swapBuffers = __glXAquaDrawableSwapBuffers; - // glxPriv->base.copySubBuffer = __glXAquaDrawableCopySubBuffer; + glxPriv->base.copySubBuffer = __glXAquaDrawableCopySubBuffer; return &glxPriv->base; } From 8e2287c220694953e972cd5119c2b0cd256b7a30 Mon Sep 17 00:00:00 2001 From: Jeremy Huddleston Date: Sat, 22 Nov 2008 13:57:45 -0800 Subject: [PATCH 3/6] XQuartz: Updated some code to use newer server API --- configure.ac | 1 + hw/xquartz/darwin.c | 12 +++++------- hw/xquartz/darwinEvents.c | 10 +++++----- hw/xquartz/quartzKeyboard.c | 7 ++++--- hw/xquartz/quartzPasteboard.c | 2 +- 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/configure.ac b/configure.ac index d557b70e2..6286a6c16 100644 --- a/configure.ac +++ b/configure.ac @@ -1878,6 +1878,7 @@ hw/vfb/Makefile hw/xnest/Makefile hw/xwin/Makefile hw/xquartz/Makefile +hw/xquartz/GL/Makefile hw/xquartz/bundle/Makefile hw/xquartz/doc/Makefile hw/xquartz/mach-startup/Makefile diff --git a/hw/xquartz/darwin.c b/hw/xquartz/darwin.c index 3f22508cd..97791e6f4 100644 --- a/hw/xquartz/darwin.c +++ b/hw/xquartz/darwin.c @@ -345,7 +345,6 @@ static int DarwinMouseProc(DeviceIntPtr pPointer, int what) { // Set button map. InitPointerDeviceStruct((DevicePtr)pPointer, map, 7, - GetMotionHistory, (PtrCtrlProcPtr)NoopDDA, GetMotionHistorySize(), 2); InitAbsoluteClassDeviceStruct(pPointer); @@ -376,7 +375,6 @@ static int DarwinTabletProc(DeviceIntPtr pPointer, int what) { // Set button map. InitPointerDeviceStruct((DevicePtr)pPointer, map, 3, - GetMotionHistory, (PtrCtrlProcPtr)NoopDDA, GetMotionHistorySize(), 5); pPointer->valuator->mode = Absolute; // Relative @@ -477,7 +475,7 @@ int DarwinParseModifierList(const char *constmodifiers, int separatelr) */ void InitInput( int argc, char **argv ) { - darwinKeyboard = AddInputDevice(DarwinKeybdProc, TRUE); + darwinKeyboard = AddInputDevice(serverClient, DarwinKeybdProc, TRUE); RegisterKeyboardDevice( darwinKeyboard ); darwinKeyboard->name = strdup("keyboard"); @@ -495,19 +493,19 @@ void InitInput( int argc, char **argv ) gdkdev->info.source = GDK_SOURCE_PEN; */ - darwinPointer = AddInputDevice(DarwinMouseProc, TRUE); + darwinPointer = AddInputDevice(serverClient, DarwinMouseProc, TRUE); RegisterPointerDevice( darwinPointer ); darwinPointer->name = strdup("pointer"); - darwinTabletStylus = AddInputDevice(DarwinTabletProc, TRUE); + darwinTabletStylus = AddInputDevice(serverClient, DarwinTabletProc, TRUE); RegisterPointerDevice( darwinTabletStylus ); darwinTabletStylus->name = strdup("pen"); - darwinTabletCursor = AddInputDevice(DarwinTabletProc, TRUE); + darwinTabletCursor = AddInputDevice(serverClient, DarwinTabletProc, TRUE); RegisterPointerDevice( darwinTabletCursor ); darwinTabletCursor->name = strdup("cursor"); - darwinTabletEraser = AddInputDevice(DarwinTabletProc, TRUE); + darwinTabletEraser = AddInputDevice(serverClient, DarwinTabletProc, TRUE); RegisterPointerDevice( darwinTabletEraser ); darwinTabletEraser->name = strdup("eraser"); diff --git a/hw/xquartz/darwinEvents.c b/hw/xquartz/darwinEvents.c index 6a2a259b4..21fd76826 100644 --- a/hw/xquartz/darwinEvents.c +++ b/hw/xquartz/darwinEvents.c @@ -84,7 +84,7 @@ static pthread_mutex_t fd_add_lock = PTHREAD_MUTEX_INITIALIZER; static pthread_cond_t fd_add_ready_cond = PTHREAD_COND_INITIALIZER; static pthread_t fd_add_tid = NULL; -static xEvent *darwinEvents = NULL; +static EventList *darwinEvents = NULL; static pthread_mutex_t mieq_lock = PTHREAD_MUTEX_INITIALIZER; static pthread_cond_t mieq_ready_cond = PTHREAD_COND_INITIALIZER; @@ -324,7 +324,7 @@ Bool DarwinEQInit(void) { * here, so I don't bother. */ if (!darwinEvents) { - darwinEvents = (xEvent *)xcalloc(sizeof(xEvent), GetMaximumEventsNum()); + darwinEvents = InitEventList(GetMaximumEventsNum());; if (!darwinEvents) FatalError("Couldn't allocate event buffer\n"); @@ -450,7 +450,7 @@ void DarwinSendPointerEvents(DeviceIntPtr pDev, int ev_type, int ev_button, floa darwinEvents_lock(); { num_events = GetPointerEvents(darwinEvents, pDev, ev_type, ev_button, POINTER_ABSOLUTE, 0, pDev==darwinTabletCurrent?5:2, valuators); - for(i=0; inext) if (pDev->key && pDev->coreEvents) SendDeviceMappingNotify(serverClient, MappingModifier, 0, 0, pDev); @@ -442,7 +442,7 @@ static void DarwinKeyboardSetDeviceKeyMap(KeySymsRec *keySyms) { if ((pDev->coreEvents || pDev == inputInfo.keyboard) && pDev->key) assert(SetKeySymsMap(&pDev->key->curKeySyms, keySyms)); - SendMappingNotify(MappingKeyboard, keySyms->minKeyCode, + SendMappingNotify(darwinKeyboard, MappingKeyboard, keySyms->minKeyCode, keySyms->maxKeyCode - keySyms->minKeyCode + 1, serverClient); for (pDev = inputInfo.devices; pDev; pDev = pDev->next) if (pDev->key && pDev->coreEvents) @@ -477,7 +477,8 @@ void DarwinKeyboardInit(DeviceIntPtr pDev) { QuartzBell, DarwinChangeKeyboardControl)); pthread_mutex_unlock(&keyInfo_mutex); - SwitchCoreKeyboard(pDev); + // TODO: What do we do now in 1.6? + //SwitchCoreKeyboard(pDev); DarwinKeyboardSetDeviceKeyMap(&keySyms); } diff --git a/hw/xquartz/quartzPasteboard.c b/hw/xquartz/quartzPasteboard.c index d47047ce0..60bcabe4c 100644 --- a/hw/xquartz/quartzPasteboard.c +++ b/hw/xquartz/quartzPasteboard.c @@ -131,7 +131,7 @@ void QuartzReadPasteboard(int screenNum, xEventPtr xe, DeviceIntPtr dev, int nev event.u.selectionClear.time = GetTimeInMillis(); event.u.selectionClear.window = pSel->window; event.u.selectionClear.atom = pSel->selection; - TryClientEvents(pSel->client, &event, 1, NoEventMask, + TryClientEvents(pSel->client, dev, &event, 1, NoEventMask, NoEventMask /*CantBeFiltered*/, NullGrab); } From ad0f232165fe1a25ca4fb6da817da02b6ce31779 Mon Sep 17 00:00:00 2001 From: Jeremy Huddleston Date: Sat, 22 Nov 2008 14:04:28 -0800 Subject: [PATCH 4/6] XQuartz: Fixed --disable-glx --- hw/xquartz/Makefile.am | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/xquartz/Makefile.am b/hw/xquartz/Makefile.am index f9d782382..d1eb283e4 100644 --- a/hw/xquartz/Makefile.am +++ b/hw/xquartz/Makefile.am @@ -13,9 +13,9 @@ if GLX GL_DIR = GL endif -SUBDIRS = bundle . GL xpr pbproxy mach-startup doc +SUBDIRS = bundle . $(GL_DIR) xpr pbproxy mach-startup doc -DIST_SUBDIRS = bundle . $(GL_DIR) xpr pbproxy mach-startup doc +DIST_SUBDIRS = bundle . GL xpr pbproxy mach-startup doc libXquartz_la_SOURCES = \ $(top_srcdir)/fb/fbcmap_mi.c \ From 8964b8d0ec2b7b3b6bf540cd647b14a20e8f64a5 Mon Sep 17 00:00:00 2001 From: Jeremy Huddleston Date: Sat, 22 Nov 2008 14:23:23 -0800 Subject: [PATCH 5/6] XQuartz: More 1.6 server API updates --- hw/xquartz/xpr/xprCursor.c | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/hw/xquartz/xpr/xprCursor.c b/hw/xquartz/xpr/xprCursor.c index 6d1ca07ad..bf1a6e875 100644 --- a/hw/xquartz/xpr/xprCursor.c +++ b/hw/xquartz/xpr/xprCursor.c @@ -185,7 +185,7 @@ load_cursor(CursorPtr src, int screen) * Convert the X cursor representation to native format if possible. */ static Bool -QuartzRealizeCursor(ScreenPtr pScreen, CursorPtr pCursor) +QuartzRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor) { if(pCursor == NULL || pCursor->bits == NULL) return FALSE; @@ -201,7 +201,7 @@ QuartzRealizeCursor(ScreenPtr pScreen, CursorPtr pCursor) * Free the storage space associated with a realized cursor. */ static Bool -QuartzUnrealizeCursor(ScreenPtr pScreen, CursorPtr pCursor) +QuartzUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor) { return TRUE; } @@ -212,7 +212,7 @@ QuartzUnrealizeCursor(ScreenPtr pScreen, CursorPtr pCursor) * Set the cursor sprite and position. */ static void -QuartzSetCursor(ScreenPtr pScreen, CursorPtr pCursor, int x, int y) +QuartzSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor, int x, int y) { QuartzCursorScreenPtr ScreenPriv = CURSOR_PRIV(pScreen); @@ -245,16 +245,26 @@ QuartzSetCursor(ScreenPtr pScreen, CursorPtr pCursor, int x, int y) * Move the cursor. This is a noop for us. */ static void -QuartzMoveCursor(ScreenPtr pScreen, int x, int y) +QuartzMoveCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) { } +/* TODO: New for 1.6 ... probably noop */ +static Bool QuartzDeviceCursorInitialize(DeviceIntPtr pDev, ScreenPtr pScreen) { + return TRUE; +} + +/* TODO: New for 1.6 ... probably noop */ +static void QuartzDeviceCursorCleanup(DeviceIntPtr pDev, ScreenPtr pScreen) { +} static miPointerSpriteFuncRec quartzSpriteFuncsRec = { QuartzRealizeCursor, QuartzUnrealizeCursor, QuartzSetCursor, - QuartzMoveCursor + QuartzMoveCursor, + QuartzDeviceCursorInitialize, + QuartzDeviceCursorCleanup }; @@ -293,7 +303,7 @@ QuartzCrossScreen(ScreenPtr pScreen, Bool entering) * */ static void -QuartzWarpCursor(ScreenPtr pScreen, int x, int y) +QuartzWarpCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) { if (quartzServerVisible) { @@ -305,8 +315,8 @@ QuartzWarpCursor(ScreenPtr pScreen, int x, int y) CGWarpMouseCursorPosition(CGPointMake(sx + x, sy + y)); } - miPointerWarpCursor(pScreen, x, y); - miPointerUpdate(); + miPointerWarpCursor(pDev, pScreen, x, y); + miPointerUpdateSprite(pDev); } @@ -404,13 +414,15 @@ QuartzResumeXCursor(ScreenPtr pScreen, int x, int y) WindowPtr pWin; CursorPtr pCursor; - pWin = GetSpriteWindow(); + /* TODO: Tablet? */ + + pWin = GetSpriteWindow(darwinPointer); if (pWin->drawable.pScreen != pScreen) return; - pCursor = GetSpriteCursor(); + pCursor = GetSpriteCursor(darwinPointer); if (pCursor == NULL) return; - QuartzSetCursor(pScreen, pCursor, x, y); + QuartzSetCursor(darwinPointer, pScreen, pCursor, x, y); } From f6e01fa1b87ea190ea5ad723ce46893784ea1de4 Mon Sep 17 00:00:00 2001 From: Stefan Dirsch Date: Sun, 23 Nov 2008 11:16:03 +0100 Subject: [PATCH 6/6] Added '-showopts' option to print available driver options (#5564). --- hw/xfree86/common/Makefile.am | 2 +- hw/xfree86/common/xf86.h | 1 + hw/xfree86/common/xf86Globals.c | 1 + hw/xfree86/common/xf86Init.c | 15 +++- hw/xfree86/common/xf86Priv.h | 1 + hw/xfree86/common/xf86ShowOpts.c | 129 +++++++++++++++++++++++++++++++ 6 files changed, 147 insertions(+), 2 deletions(-) create mode 100644 hw/xfree86/common/xf86ShowOpts.c diff --git a/hw/xfree86/common/Makefile.am b/hw/xfree86/common/Makefile.am index 87913e8fa..06d53c14b 100644 --- a/hw/xfree86/common/Makefile.am +++ b/hw/xfree86/common/Makefile.am @@ -25,7 +25,7 @@ xf86DefModeSet.c: $(srcdir)/modeline2c.awk $(MODEDEFSOURCES) BUILT_SOURCES = xf86DefModeSet.c AM_LDFLAGS = -r -libcommon_la_SOURCES = xf86Configure.c xf86Bus.c xf86Config.c \ +libcommon_la_SOURCES = xf86Configure.c xf86ShowOpts.c xf86Bus.c xf86Config.c \ xf86Cursor.c xf86DGA.c xf86DPMS.c \ xf86DoProbe.c xf86Events.c \ xf86Globals.c xf86AutoConfig.c \ diff --git a/hw/xfree86/common/xf86.h b/hw/xfree86/common/xf86.h index 459712ea0..4432c551b 100644 --- a/hw/xfree86/common/xf86.h +++ b/hw/xfree86/common/xf86.h @@ -56,6 +56,7 @@ /* General parameters */ extern int xf86DoConfigure; +extern int xf86DoShowOptions; extern Bool xf86DoModalias; extern Bool xf86DoConfigurePass1; extern DevPrivateKey xf86ScreenKey; diff --git a/hw/xfree86/common/xf86Globals.c b/hw/xfree86/common/xf86Globals.c index db3b68463..57142beab 100644 --- a/hw/xfree86/common/xf86Globals.c +++ b/hw/xfree86/common/xf86Globals.c @@ -153,6 +153,7 @@ Bool xf86Resetting = FALSE; Bool xf86Initialising = FALSE; Bool xf86DoProbe = FALSE; Bool xf86DoConfigure = FALSE; +Bool xf86DoShowOptions = FALSE; Bool xf86DoModalias = FALSE; DriverPtr *xf86DriverList = NULL; int xf86NumDrivers = 0; diff --git a/hw/xfree86/common/xf86Init.c b/hw/xfree86/common/xf86Init.c index 45c116a8b..86f25de12 100644 --- a/hw/xfree86/common/xf86Init.c +++ b/hw/xfree86/common/xf86Init.c @@ -688,7 +688,7 @@ InitOutput(ScreenInfo *pScreenInfo, int argc, char **argv) } /* Read and parse the config file */ - if (!xf86DoProbe && !xf86DoConfigure && !xf86DoModalias) { + if (!xf86DoProbe && !xf86DoConfigure && !xf86DoModalias && !xf86DoShowOptions) { switch (xf86HandleConfigFile(FALSE)) { case CONFIG_OK: break; @@ -713,6 +713,9 @@ InitOutput(ScreenInfo *pScreenInfo, int argc, char **argv) LoaderSetOptions(LDR_OPT_ABI_MISMATCH_NONFATAL); } + if (xf86DoShowOptions) + DoShowOptions(); + xf86OpenConsole(); /* Do a general bus probe. This will be a PCI probe for x86 platforms */ @@ -1774,6 +1777,15 @@ ddxProcessArgument(int argc, char **argv, int i) xf86AllowMouseOpenFail = TRUE; return 1; } + if (!strcmp(argv[i], "-showopts")) + { + if (getuid() != 0 && geteuid() == 0) { + ErrorF("The '-showopts' option can only be used by root.\n"); + exit(1); + } + xf86DoShowOptions = TRUE; + return 1; + } if (!strcmp(argv[i], "-isolateDevice")) { int bus, device, func; @@ -1812,6 +1824,7 @@ ddxUseMsg() ErrorF("-modulepath paths specify the module search path\n"); ErrorF("-logfile file specify a log file name\n"); ErrorF("-configure probe for devices and write an "__XCONFIGFILE__"\n"); + ErrorF("-showopts print available options for all installed drivers\n"); } ErrorF("-modalias output a modalias-style filter for each driver installed\n"); ErrorF("-config file specify a configuration file, relative to the\n"); diff --git a/hw/xfree86/common/xf86Priv.h b/hw/xfree86/common/xf86Priv.h index 159dfb26b..f3dfd70d8 100644 --- a/hw/xfree86/common/xf86Priv.h +++ b/hw/xfree86/common/xf86Priv.h @@ -153,6 +153,7 @@ extern const int xf86NumDefaultModes; /* xf86DoProbe.c */ void DoProbe(void); void DoConfigure(void); +void DoShowOptions(void); /* xf86Events.c */ diff --git a/hw/xfree86/common/xf86ShowOpts.c b/hw/xfree86/common/xf86ShowOpts.c new file mode 100644 index 000000000..b8efa73c2 --- /dev/null +++ b/hw/xfree86/common/xf86ShowOpts.c @@ -0,0 +1,129 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/common/xf86ShopwOpts.c,v 3.80 2003/10/08 14:58:27 dawes Exp $ */ +/* + * Copyright 2000-2002 by Alan Hourihane, Flint Mountain, North Wales. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Alan Hourihane not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Alan Hourihane makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL ALAN HOURIHANE 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. + * + * Author: Marcus Schaefer, ms@suse.de + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "os.h" +#ifdef XFree86LOADER +#include "loaderProcs.h" +#endif +#include "xf86.h" +#include "xf86Config.h" +#include "xf86_OSlib.h" +#include "xf86Priv.h" +/* #include "xf86PciData.h" */ +#define IN_XSERVER +#include "xf86Parser.h" +#include "xf86tokens.h" +#include "Configint.h" +#include "vbe.h" +#include "xf86DDC.h" +#if defined(__sparc__) && !defined(__OpenBSD__) +#include "xf86Bus.h" +#include "xf86Sbus.h" +#endif +#include "globals.h" + +static const char* +optionTypeToSting(OptionValueType type) +{ + switch (type) { + case OPTV_NONE: + return ""; + case OPTV_INTEGER: + return ""; + case OPTV_STRING: + return ""; + case OPTV_ANYSTR: + return ""; + case OPTV_REAL: + return ""; + case OPTV_BOOLEAN: + return ""; + case OPTV_FREQ: + return ""; + default: + return ""; + } +} + +void DoShowOptions (void) { + int i = 0; + char **vlist = 0; + char *pSymbol = 0; + XF86ModuleData *initData = 0; + if (! (vlist = xf86DriverlistFromCompile())) { + ErrorF("Missing output drivers\n"); + goto bail; + } + xf86LoadModules (vlist,0); + xfree (vlist); + for (i = 0; i < xf86NumDrivers; i++) { + if (xf86DriverList[i]->AvailableOptions) { + OptionInfoPtr pOption = (OptionInfoPtr)(*xf86DriverList[i]->AvailableOptions)(0,0); + if (! pOption) { + ErrorF ("(EE) Couldn't read option table for %s driver\n", + xf86DriverList[i]->driverName + ); + continue; + } + pSymbol = xalloc ( + strlen(xf86DriverList[i]->driverName) + strlen("ModuleData") + 1 + ); + strcpy (pSymbol, xf86DriverList[i]->driverName); + strcat (pSymbol, "ModuleData"); + initData = LoaderSymbol (pSymbol); + if (initData) { + XF86ModuleVersionInfo *vers = initData->vers; + ErrorF ("Driver[%d]:%s[%s] {\n", + i,xf86DriverList[i]->driverName,vers->vendor + ); + OptionInfoPtr p; + for (p = pOption; p->name != NULL; p++) { + const char *opttype = optionTypeToSting(p->type); + char *optname = xalloc(strlen(p->name) + 2 + 1); + if (!optname) { + continue; + } + sprintf(optname, "%s", p->name); + ErrorF ("\t%s:%s\n", optname,opttype); + } + ErrorF ("}\n"); + } + } + } + bail: + OsCleanup (TRUE); + AbortDDX (); + fflush (stderr); + exit (0); +}