#ifdef HAVE_DMX_CONFIG_H
#include <dmx-config.h>
#endif
#include "dmx.h"
#include "dmxinit.h"
#include "dmxsync.h"
#include "dmxlog.h"
#include "dmxinput.h"
#include "dmxscrinit.h"
#include "dmxcursor.h"
#include "dmxfont.h"
#include "config/dmxconfig.h"
#include "dmxcb.h"
#include "dmxprop.h"
#include "dmxstat.h"
#ifdef RENDER
#include "dmxpict.h"
#endif
#include <X11/Xos.h>
#include "dixstruct.h"
#include "panoramiXsrv.h"
#include <signal.h>
#ifdef GLXEXT
#include <GL/glx.h>
#include <GL/glxint.h>
#include "dmx_glxvisuals.h"
#include <X11/extensions/Xext.h>
#include <X11/extensions/extutil.h>
extern void GlxSetVisualConfigs(
int nconfigs,
__GLXvisualConfig *configs,
void **configprivs
);
#endif
int dmxNumScreens;
DMXScreenInfo *dmxScreens;
int dmxNumInputs;
DMXInputInfo *dmxInputs;
int dmxShadowFB = FALSE;
XErrorEvent dmxLastErrorEvent;
Bool dmxErrorOccurred = FALSE;
char *dmxFontPath = NULL;
Bool dmxOffScreenOpt = TRUE;
Bool dmxSubdividePrimitives = TRUE;
Bool dmxLazyWindowCreation = TRUE;
Bool dmxUseXKB = TRUE;
int dmxDepth = 0;
#ifndef GLXEXT
static Bool dmxGLXProxy = FALSE;
#else
Bool dmxGLXProxy = TRUE;
Bool dmxGLXSwapGroupSupport = TRUE;
Bool dmxGLXSyncSwap = FALSE;
Bool dmxGLXFinishSwap = FALSE;
#endif
Bool dmxIgnoreBadFontPaths = FALSE;
Bool dmxAddRemoveScreens = FALSE;
static int dmxErrorHandler(Display *dpy, XErrorEvent *ev)
{
#define DMX_ERROR_BUF_SIZE 256
char buf[DMX_ERROR_BUF_SIZE];
char request[DMX_ERROR_BUF_SIZE];
_XExtension *ext = NULL;
dmxErrorOccurred = TRUE;
dmxLastErrorEvent = *ev;
XGetErrorText(dpy, ev->error_code, buf, sizeof(buf));
dmxLog(dmxWarning, "dmxErrorHandler: %s\n", buf);
if (ev->request_code < 128) {
XmuSnprintf(request, sizeof(request), "%d", ev->request_code);
XGetErrorDatabaseText(dpy, "XRequest", request, "", buf, sizeof(buf));
} else {
for (ext = dpy->ext_procs;
ext && ext->codes.major_opcode != ev->request_code;
ext = ext->next);
if (ext) strncpy(buf, ext->name, sizeof(buf));
else buf[0] = '\0';
}
dmxLog(dmxWarning, " Major opcode: %d (%s)\n",
ev->request_code, buf);
if (ev->request_code >= 128 && ext) {
XmuSnprintf(request, sizeof(request), "%d", ev->request_code);
XmuSnprintf(request, sizeof(request), "%s.%d",
ext->name, ev->minor_code);
XGetErrorDatabaseText(dpy, "XRequest", request, "", buf, sizeof(buf));
dmxLog(dmxWarning, " Minor opcode: %d (%s)\n",
ev->minor_code, buf);
}
switch (ev->error_code) {
case BadValue:
dmxLog(dmxWarning, " Value: 0x%x\n",
ev->resourceid);
break;
case BadAtom:
dmxLog(dmxWarning, " AtomID: 0x%x\n",
ev->resourceid);
break;
default:
dmxLog(dmxWarning, " ResourceID: 0x%x\n",
ev->resourceid);
break;
}
dmxLog(dmxWarning, " Failed serial number: %d\n",
ev->serial);
dmxLog(dmxWarning, " Current serial number: %d\n",
dpy->request);
return 0;
}
#ifdef GLXEXT
static int dmxNOPErrorHandler(Display *dpy, XErrorEvent *ev)
{
return 0;
}
#endif
Bool dmxOpenDisplay(DMXScreenInfo *dmxScreen)
{
if (!(dmxScreen->beDisplay = XOpenDisplay(dmxScreen->name)))
return FALSE;
dmxPropertyDisplay(dmxScreen);
return TRUE;
}
void dmxSetErrorHandler(DMXScreenInfo *dmxScreen)
{
XSetErrorHandler(dmxErrorHandler);
}
static void dmxPrintScreenInfo(DMXScreenInfo *dmxScreen)
{
XWindowAttributes attribs;
int ndepths = 0, *depths = NULL;
int i;
Display *dpy = dmxScreen->beDisplay;
Screen *s = DefaultScreenOfDisplay(dpy);
int scr = DefaultScreen(dpy);
XGetWindowAttributes(dpy, DefaultRootWindow(dpy), &attribs);
if (!(depths = XListDepths(dpy, scr, &ndepths))) ndepths = 0;
dmxLogOutput(dmxScreen, "Name of display: %s\n", DisplayString(dpy));
dmxLogOutput(dmxScreen, "Version number: %d.%d\n",
ProtocolVersion(dpy), ProtocolRevision(dpy));
dmxLogOutput(dmxScreen, "Vendor string: %s\n", ServerVendor(dpy));
if (!strstr(ServerVendor(dpy), "XFree86")) {
dmxLogOutput(dmxScreen, "Vendor release: %d\n", VendorRelease(dpy));
} else {
int v = VendorRelease(dpy);
int major = -1, minor = -1, patch = -1, subpatch = -1;
if (v < 336)
major = v / 100, minor = (v / 10) % 10, patch = v % 10;
else if (v < 3900) {
major = v / 1000;
minor = (v / 100) % 10;
if (((v / 10) % 10) || (v % 10)) {
patch = (v / 10) % 10;
if (v % 10) subpatch = v % 10;
}
} else if (v < 40000000) {
major = v / 1000;
minor = (v / 10) % 10;
if (v % 10) patch = v % 10;
} else {
major = v / 10000000;
minor = (v / 100000) % 100;
patch = (v / 1000) % 100;
if (v % 1000) subpatch = v % 1000;
}
dmxLogOutput(dmxScreen, "Vendor release: %d (XFree86 version: %d.%d",
v, major, minor);
if (patch > 0) dmxLogOutputCont(dmxScreen, ".%d", patch);
if (subpatch > 0) dmxLogOutputCont(dmxScreen, ".%d", subpatch);
dmxLogOutputCont(dmxScreen, ")\n");
}
dmxLogOutput(dmxScreen, "Dimensions: %dx%d pixels\n",
attribs.width, attribs.height);
dmxLogOutput(dmxScreen, "%d depths on screen %d: ", ndepths, scr);
for (i = 0; i < ndepths; i++)
dmxLogOutputCont(dmxScreen, "%c%d", i ? ',' : ' ', depths[i]);
dmxLogOutputCont(dmxScreen, "\n");
dmxLogOutput(dmxScreen, "Depth of root window: %d plane%s (%d)\n",
attribs.depth, attribs.depth == 1 ? "" : "s",
DisplayPlanes(dpy, scr));
dmxLogOutput(dmxScreen, "Number of colormaps: %d min, %d max\n",
MinCmapsOfScreen(s), MaxCmapsOfScreen(s));
dmxLogOutput(dmxScreen, "Options: backing-store %s, save-unders %s\n",
(DoesBackingStore (s) == NotUseful) ? "no" :
((DoesBackingStore (s) == Always) ? "yes" : "when mapped"),
DoesSaveUnders (s) ? "yes" : "no");
dmxLogOutput(dmxScreen, "Window Manager running: %s\n",
(dmxScreen->WMRunningOnBE) ? "yes" : "no");
if (dmxScreen->WMRunningOnBE) {
dmxLogOutputWarning(dmxScreen,
"Window manager running "
"-- colormaps not supported\n");
}
XFree(depths);
}
void dmxGetScreenAttribs(DMXScreenInfo *dmxScreen)
{
XWindowAttributes attribs;
Display *dpy = dmxScreen->beDisplay;
#ifdef GLXEXT
int dummy;
#endif
XGetWindowAttributes(dpy, DefaultRootWindow(dpy), &attribs);
dmxScreen->beWidth = attribs.width;
dmxScreen->beHeight = attribs.height;
if (dmxScreen->scrnXSign < 0) {
if (dmxScreen->scrnWidth) {
dmxScreen->scrnX = (attribs.width - dmxScreen->scrnWidth
- dmxScreen->scrnX);
} else {
dmxScreen->scrnWidth = attribs.width - dmxScreen->scrnX;
dmxScreen->scrnX = 0;
}
}
if (dmxScreen->scrnYSign < 0) {
if (dmxScreen->scrnHeight) {
dmxScreen->scrnY = (attribs.height - dmxScreen->scrnHeight
- dmxScreen->scrnY);
} else {
dmxScreen->scrnHeight = attribs.height - dmxScreen->scrnY;
dmxScreen->scrnY = 0;
}
}
if (!dmxScreen->scrnWidth)
dmxScreen->scrnWidth = attribs.width - dmxScreen->scrnX;
if (!dmxScreen->scrnHeight)
dmxScreen->scrnHeight = attribs.height - dmxScreen->scrnY;
if (!dmxScreen->rootWidth) dmxScreen->rootWidth = dmxScreen->scrnWidth;
if (!dmxScreen->rootHeight) dmxScreen->rootHeight = dmxScreen->scrnHeight;
if (dmxScreen->rootWidth + dmxScreen->rootX > dmxScreen->scrnWidth)
dmxScreen->rootWidth = dmxScreen->scrnWidth - dmxScreen->rootX;
if (dmxScreen->rootHeight + dmxScreen->rootY > dmxScreen->scrnHeight)
dmxScreen->rootHeight = dmxScreen->scrnHeight - dmxScreen->rootY;
dmxScreen->beXDPI = 75;
dmxScreen->beYDPI = 75;
dmxScreen->beDepth = attribs.depth;
if (dmxScreen->beDepth <= 8) dmxScreen->beBPP = 8;
else if (dmxScreen->beDepth <= 16) dmxScreen->beBPP = 16;
else dmxScreen->beBPP = 32;
#ifdef GLXEXT
XQueryExtension(dpy, "GLX", &dmxScreen->glxMajorOpcode,
&dummy, &dmxScreen->glxErrorBase);
#endif
dmxPrintScreenInfo(dmxScreen);
dmxLogOutput(dmxScreen, "%dx%d+%d+%d on %dx%d at depth=%d, bpp=%d\n",
dmxScreen->scrnWidth, dmxScreen->scrnHeight,
dmxScreen->scrnX, dmxScreen->scrnY,
dmxScreen->beWidth, dmxScreen->beHeight,
dmxScreen->beDepth, dmxScreen->beBPP);
if (dmxScreen->beDepth == 8)
dmxLogOutputWarning(dmxScreen,
"Support for depth == 8 is not complete\n");
}
Bool dmxGetVisualInfo(DMXScreenInfo *dmxScreen)
{
int i;
XVisualInfo visinfo;
visinfo.screen = DefaultScreen(dmxScreen->beDisplay);
dmxScreen->beVisuals = XGetVisualInfo(dmxScreen->beDisplay,
VisualScreenMask,
&visinfo,
&dmxScreen->beNumVisuals);
dmxScreen->beDefVisualIndex = -1;
if (defaultColorVisualClass >= 0 || dmxDepth > 0) {
for (i = 0; i < dmxScreen->beNumVisuals; i++)
if (defaultColorVisualClass >= 0) {
if (dmxScreen->beVisuals[i].class == defaultColorVisualClass) {
if (dmxDepth > 0) {
if (dmxScreen->beVisuals[i].depth == dmxDepth) {
dmxScreen->beDefVisualIndex = i;
break;
}
} else {
dmxScreen->beDefVisualIndex = i;
break;
}
}
} else if (dmxScreen->beVisuals[i].depth == dmxDepth) {
dmxScreen->beDefVisualIndex = i;
break;
}
} else {
visinfo.visualid =
XVisualIDFromVisual(DefaultVisual(dmxScreen->beDisplay,
visinfo.screen));
for (i = 0; i < dmxScreen->beNumVisuals; i++)
if (visinfo.visualid == dmxScreen->beVisuals[i].visualid) {
dmxScreen->beDefVisualIndex = i;
break;
}
}
for (i = 0; i < dmxScreen->beNumVisuals; i++)
dmxLogVisual(dmxScreen, &dmxScreen->beVisuals[i],
(i == dmxScreen->beDefVisualIndex));
return (dmxScreen->beDefVisualIndex >= 0);
}
void dmxGetColormaps(DMXScreenInfo *dmxScreen)
{
int i;
dmxScreen->beNumDefColormaps = dmxScreen->beNumVisuals;
dmxScreen->beDefColormaps = xalloc(dmxScreen->beNumDefColormaps *
sizeof(*dmxScreen->beDefColormaps));
for (i = 0; i < dmxScreen->beNumDefColormaps; i++)
dmxScreen->beDefColormaps[i] =
XCreateColormap(dmxScreen->beDisplay,
DefaultRootWindow(dmxScreen->beDisplay),
dmxScreen->beVisuals[i].visual,
AllocNone);
dmxScreen->beBlackPixel = BlackPixel(dmxScreen->beDisplay,
DefaultScreen(dmxScreen->beDisplay));
dmxScreen->beWhitePixel = WhitePixel(dmxScreen->beDisplay,
DefaultScreen(dmxScreen->beDisplay));
}
void dmxGetPixmapFormats(DMXScreenInfo *dmxScreen)
{
dmxScreen->beDepths =
XListDepths(dmxScreen->beDisplay, DefaultScreen(dmxScreen->beDisplay),
&dmxScreen->beNumDepths);
dmxScreen->bePixmapFormats =
XListPixmapFormats(dmxScreen->beDisplay,
&dmxScreen->beNumPixmapFormats);
}
static Bool dmxSetPixmapFormats(ScreenInfo *pScreenInfo,
DMXScreenInfo *dmxScreen)
{
XPixmapFormatValues *bePixmapFormat;
PixmapFormatRec *format;
int i, j;
pScreenInfo->imageByteOrder = ImageByteOrder(dmxScreen->beDisplay);
pScreenInfo->bitmapScanlineUnit = BitmapUnit(dmxScreen->beDisplay);
pScreenInfo->bitmapScanlinePad = BitmapPad(dmxScreen->beDisplay);
pScreenInfo->bitmapBitOrder = BitmapBitOrder(dmxScreen->beDisplay);
pScreenInfo->numPixmapFormats = 0;
for (i = 0; i < dmxScreen->beNumPixmapFormats; i++) {
bePixmapFormat = &dmxScreen->bePixmapFormats[i];
for (j = 0; j < dmxScreen->beNumDepths; j++)
if ((bePixmapFormat->depth == 1) ||
(bePixmapFormat->depth == dmxScreen->beDepths[j])) {
format = &pScreenInfo->formats[pScreenInfo->numPixmapFormats];
format->depth = bePixmapFormat->depth;
format->bitsPerPixel = bePixmapFormat->bits_per_pixel;
format->scanlinePad = bePixmapFormat->scanline_pad;
pScreenInfo->numPixmapFormats++;
break;
}
}
return TRUE;
}
void dmxCheckForWM(DMXScreenInfo *dmxScreen)
{
Status status;
XWindowAttributes xwa;
status = XGetWindowAttributes(dmxScreen->beDisplay,
DefaultRootWindow(dmxScreen->beDisplay),
&xwa);
dmxScreen->WMRunningOnBE =
(status &&
((xwa.all_event_masks & SubstructureRedirectMask) ||
(xwa.all_event_masks & SubstructureNotifyMask)));
}
static void dmxDisplayInit(DMXScreenInfo *dmxScreen)
{
if (!dmxOpenDisplay(dmxScreen))
dmxLog(dmxFatal,
"dmxOpenDisplay: Unable to open display %s\n",
dmxScreen->name);
dmxSetErrorHandler(dmxScreen);
dmxCheckForWM(dmxScreen);
dmxGetScreenAttribs(dmxScreen);
if (!dmxGetVisualInfo(dmxScreen))
dmxLog(dmxFatal, "dmxGetVisualInfo: No matching visuals found\n");
dmxGetColormaps(dmxScreen);
dmxGetPixmapFormats(dmxScreen);
}
#if !defined(_POSIX_SOURCE) && !defined(__sgi)
static const char *dmxExecOS(void) { return ""; }
#else
#include <sys/utsname.h>
static const char *dmxExecOS(void)
{
static char buffer[128];
static int initialized = 0;
struct utsname u;
if (!initialized++) {
memset(buffer, 0, sizeof(buffer));
uname(&u);
XmuSnprintf(buffer, sizeof(buffer)-1, "%s %s %s",
u.sysname, u.release, u.version);
}
return buffer;
}
#endif
static const char *dmxBuildCompiler(void)
{
static char buffer[128];
static int initialized = 0;
if (!initialized++) {
memset(buffer, 0, sizeof(buffer));
#if defined(__GNUC__) && defined(__GNUC_MINOR__) &&defined(__GNUC_PATCHLEVEL__)
XmuSnprintf(buffer, sizeof(buffer)-1, "gcc %d.%d.%d",
__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__);
#elif defined(__sgi) && defined(_COMPILER_VERSION) && !defined(__GNUC__)
{
int a = _COMPILER_VERSION / 100;
int b = (_COMPILER_VERSION - a * 100) / 10;
int c = _COMPILER_VERSION - a * 100 - b * 10;
XmuSnprintf(buffer, sizeof(buffer)-1, "SGI MIPSpro %d.%d.%d",
a, b, c);
}
#endif
}
return buffer;
}
static const char *dmxExecHost(void)
{
static char buffer[128];
static int initialized = 0;
if (!initialized++) {
memset(buffer, 0, sizeof(buffer));
XmuGetHostname(buffer, sizeof(buffer) - 1);
}
return buffer;
}
void InitOutput(ScreenInfo *pScreenInfo, int argc, char *argv[])
{
int i;
static unsigned long dmxGeneration = 0;
#ifdef GLXEXT
Bool glxSupported = TRUE;
#endif
if (dmxGeneration != serverGeneration) {
int vendrel = VENDOR_RELEASE;
int major, minor, year, month, day;
dmxGeneration = serverGeneration;
major = vendrel / 100000000;
vendrel -= major * 100000000;
minor = vendrel / 1000000;
vendrel -= minor * 1000000;
year = vendrel / 10000;
vendrel -= year * 10000;
month = vendrel / 100;
vendrel -= month * 100;
day = vendrel;
if (major > 0 && minor > 0) year += 2000;
dmxLog(dmxInfo, "Generation: %d\n", dmxGeneration);
dmxLog(dmxInfo, "DMX version: %d.%d.%02d%02d%02d (%s)\n",
major, minor, year, month, day, VENDOR_STRING);
SetVendorRelease(VENDOR_RELEASE);
SetVendorString(VENDOR_STRING);
if (dmxGeneration == 1) {
dmxLog(dmxInfo, "DMX Build OS: %s (%s)\n", OSNAME, OSVENDOR);
dmxLog(dmxInfo, "DMX Build Compiler: %s\n", dmxBuildCompiler());
dmxLog(dmxInfo, "DMX Execution OS: %s\n", dmxExecOS());
dmxLog(dmxInfo, "DMX Execution Host: %s\n", dmxExecHost());
}
dmxLog(dmxInfo, "MAXSCREENS: %d\n", MAXSCREENS);
for (i = 0; i < dmxNumScreens; i++) {
if (dmxScreens[i].beDisplay)
dmxLog(dmxWarning, "Display \"%s\" still open\n",
dmxScreens[i].name);
dmxStatFree(dmxScreens[i].stat);
dmxScreens[i].stat = NULL;
}
for (i = 0; i < dmxNumInputs; i++) dmxInputFree(&dmxInputs[i]);
if (dmxScreens) free(dmxScreens);
if (dmxInputs) free(dmxInputs);
dmxScreens = NULL;
dmxInputs = NULL;
dmxNumScreens = 0;
dmxNumInputs = 0;
}
if (dmxAddRemoveScreens && dmxGLXProxy) {
dmxLog(dmxWarning,
"GLX Proxy and Render extensions do not yet support dynamic\n");
dmxLog(dmxWarning,
"screen addition and removal. Please specify -noglxproxy\n");
dmxLog(dmxWarning,
"and -norender on the command line or in the configuration\n");
dmxLog(dmxWarning,
"file to disable these two extensions if you wish to use\n");
dmxLog(dmxWarning,
"the dynamic addition and removal of screens support.\n");
dmxLog(dmxFatal,
"Dynamic screen addition/removal error (see above).\n");
}
dmxConfigConfigure();
if (!dmxNumScreens)
dmxLog(dmxFatal, "InitOutput: no back-end displays found\n");
if (!dmxNumInputs)
dmxLog(dmxInfo, "InitOutput: no inputs found\n");
if (!dmxOffScreenOpt && dmxLazyWindowCreation) {
dmxLog(dmxInfo,
"InitOutput: Disabling lazy window creation optimization\n");
dmxLog(dmxInfo,
" since it requires the offscreen optimization\n");
dmxLog(dmxInfo,
" to function properly.\n");
dmxLazyWindowCreation = FALSE;
}
for (i = 0; i < dmxNumScreens; i++)
dmxDisplayInit(&dmxScreens[i]);
#if PANORAMIX
XineramaRegisterConnectionBlockCallback(dmxConnectionBlockCallback);
#endif
if (!dmxSetPixmapFormats(pScreenInfo, &dmxScreens[0])) return;
OsSignal(SIGQUIT, GiveUp);
#ifdef GLXEXT
for (i = 0; i < dmxNumScreens; i++)
glxSupported &= (dmxScreens[i].glxMajorOpcode > 0);
#endif
for (i = 0; i < dmxNumScreens; i++) {
#ifdef GLXEXT
if (glxSupported) {
DMXScreenInfo *dmxScreen = &dmxScreens[i];
__GLXvisualConfig *configs = NULL;
dmxGlxVisualPrivate **configprivs = NULL;
int nconfigs = 0;
int (*oldErrorHandler)(Display *, XErrorEvent *);
int i;
oldErrorHandler = XSetErrorHandler(dmxNOPErrorHandler);
dmxScreen->fbconfigs = GetGLXFBConfigs(dmxScreen->beDisplay,
dmxScreen->glxMajorOpcode,
&dmxScreen->numFBConfigs);
XSetErrorHandler(oldErrorHandler);
dmxScreen->glxVisuals =
GetGLXVisualConfigs(dmxScreen->beDisplay,
DefaultScreen(dmxScreen->beDisplay),
&dmxScreen->numGlxVisuals);
if (dmxScreen->fbconfigs) {
configs =
GetGLXVisualConfigsFromFBConfigs(dmxScreen->fbconfigs,
dmxScreen->numFBConfigs,
dmxScreen->beVisuals,
dmxScreen->beNumVisuals,
dmxScreen->glxVisuals,
dmxScreen->numGlxVisuals,
&nconfigs);
} else {
configs = dmxScreen->glxVisuals;
nconfigs = dmxScreen->numGlxVisuals;
}
configprivs = xalloc(dmxScreen->beNumVisuals *
sizeof(dmxGlxVisualPrivate*));
if (configs != NULL && configprivs != NULL) {
for (i = 0; i < nconfigs; i++) {
configprivs[i] = (dmxGlxVisualPrivate *)
xalloc(sizeof(dmxGlxVisualPrivate));
configprivs[i]->x_visual_depth = 0;
configprivs[i]->x_visual_class = 0;
if (configs[i].vid > 0) {
int j;
for (j = 0; j < dmxScreen->beNumVisuals; j++) {
if (dmxScreen->beVisuals[j].visualid ==
configs[i].vid) {
configprivs[i]->x_visual_depth =
dmxScreen->beVisuals[j].depth;
configprivs[i]->x_visual_class =
dmxScreen->beVisuals[j].class;
break;
}
}
}
}
GlxSetVisualConfigs(nconfigs, configs, (void**)configprivs);
}
}
#endif
AddScreen(dmxScreenInit, argc, argv);
}
dmxInitOrigins();
dmxInitOverlap();
dmxComputeWidthHeight(DMX_NO_RECOMPUTE_BOUNDING_BOX);
dmxInitFonts();
#ifdef RENDER
if (!noRenderExtension)
dmxInitRender();
#endif
dmxStatInit();
dmxSyncInit();
dmxLog(dmxInfo, "Shadow framebuffer support %s\n",
dmxShadowFB ? "enabled" : "disabled");
}
static void dmxSetDefaultFontPath(char *fp)
{
int fplen = strlen(fp) + 1;
if (dmxFontPath) {
int len;
len = strlen(dmxFontPath);
dmxFontPath = xrealloc(dmxFontPath, len+fplen+1);
dmxFontPath[len] = ',';
strncpy(&dmxFontPath[len+1], fp, fplen);
} else {
dmxFontPath = xalloc(fplen);
strncpy(dmxFontPath, fp, fplen);
}
defaultFontPath = dmxFontPath;
}
void AbortDDX(void)
{
int i;
for (i=0; i < dmxNumScreens; i++) {
DMXScreenInfo *dmxScreen = &dmxScreens[i];
if (dmxScreen->beDisplay) XCloseDisplay(dmxScreen->beDisplay);
dmxScreen->beDisplay = NULL;
}
}
void ddxGiveUp(void)
{
AbortDDX();
}
void OsVendorInit(void)
{
}
void OsVendorFatalError(void)
{
}
void ddxInitGlobals(void)
{
}
int ddxProcessArgument(int argc, char *argv[], int i)
{
int retval = 0;
if (!strcmp(argv[i], "-display")) {
if (++i < argc) dmxConfigStoreDisplay(argv[i]);
retval = 2;
} else if (!strcmp(argv[i], "-inputfrom") || !strcmp(argv[i], "-input")) {
if (++i < argc) dmxConfigStoreInput(argv[i]);
retval = 2;
} else if (!strcmp(argv[i], "-xinputfrom") || !strcmp(argv[i],"-xinput")) {
if (++i < argc) dmxConfigStoreXInput(argv[i]);
retval = 2;
} else if (!strcmp(argv[i], "-noshadowfb")) {
dmxLog(dmxWarning,
"-noshadowfb has been deprecated "
"since it is now the default\n");
dmxShadowFB = FALSE;
retval = 1;
} else if (!strcmp(argv[i], "-nomulticursor")) {
dmxCursorNoMulti();
retval = 1;
} else if (!strcmp(argv[i], "-shadowfb")) {
dmxShadowFB = TRUE;
retval = 1;
} else if (!strcmp(argv[i], "-configfile")) {
if (++i < argc) dmxConfigStoreFile(argv[i]);
retval = 2;
} else if (!strcmp(argv[i], "-config")) {
if (++i < argc) dmxConfigStoreConfig(argv[i]);
retval = 2;
} else if (!strcmp(argv[i], "-fontpath")) {
if (++i < argc) dmxSetDefaultFontPath(argv[i]);
retval = 2;
} else if (!strcmp(argv[i], "-stat")) {
if ((i += 2) < argc) dmxStatActivate(argv[i-1], argv[i]);
retval = 3;
} else if (!strcmp(argv[i], "-syncbatch")) {
if (++i < argc) dmxSyncActivate(argv[i]);
retval = 2;
} else if (!strcmp(argv[i], "-nooffscreenopt")) {
dmxOffScreenOpt = FALSE;
retval = 1;
} else if (!strcmp(argv[i], "-nosubdivprims")) {
dmxSubdividePrimitives = FALSE;
retval = 1;
} else if (!strcmp(argv[i], "-nowindowopt")) {
dmxLazyWindowCreation = FALSE;
retval = 1;
} else if (!strcmp(argv[i], "-noxkb")) {
dmxUseXKB = FALSE;
retval = 1;
} else if (!strcmp(argv[i], "-depth")) {
if (++i < argc) dmxDepth = atoi(argv[i]);
retval = 2;
} else if (!strcmp(argv[i], "-norender")) {
noRenderExtension = TRUE;
retval = 1;
#ifdef GLXEXT
} else if (!strcmp(argv[i], "-noglxproxy")) {
dmxGLXProxy = FALSE;
retval = 1;
} else if (!strcmp(argv[i], "-noglxswapgroup")) {
dmxGLXSwapGroupSupport = FALSE;
retval = 1;
} else if (!strcmp(argv[i], "-glxsyncswap")) {
dmxGLXSyncSwap = TRUE;
retval = 1;
} else if (!strcmp(argv[i], "-glxfinishswap")) {
dmxGLXFinishSwap = TRUE;
retval = 1;
#endif
} else if (!strcmp(argv[i], "-ignorebadfontpaths")) {
dmxIgnoreBadFontPaths = TRUE;
retval = 1;
} else if (!strcmp(argv[i], "-addremovescreens")) {
dmxAddRemoveScreens = TRUE;
retval = 1;
} else if (!strcmp(argv[i], "-param")) {
if ((i += 2) < argc) {
if (!strcasecmp(argv[i-1], "xkbrules"))
dmxConfigSetXkbRules(argv[i]);
else if (!strcasecmp(argv[i-1], "xkbmodel"))
dmxConfigSetXkbModel(argv[i]);
else if (!strcasecmp(argv[i-1], "xkblayout"))
dmxConfigSetXkbLayout(argv[i]);
else if (!strcasecmp(argv[i-1], "xkbvariant"))
dmxConfigSetXkbVariant(argv[i]);
else if (!strcasecmp(argv[i-1], "xkboptions"))
dmxConfigSetXkbOptions(argv[i]);
else
dmxLog(dmxWarning,
"-param requires: XkbRules, XkbModel, XkbLayout,"
" XkbVariant, or XkbOptions\n");
}
retval = 3;
}
if (!serverGeneration) dmxConfigSetMaxScreens();
return retval;
}
void ddxUseMsg(void)
{
ErrorF("\n\nDevice Dependent Usage:\n");
ErrorF("-display string Specify the back-end display(s)\n");
ErrorF("-input string Specify input source for core device\n");
ErrorF("-xinput string Specify input source for XInput device\n");
ErrorF("-shadowfb Enable shadow frame buffer\n");
ErrorF("-configfile file Read from a configuration file\n");
ErrorF("-config config Select a specific configuration\n");
ErrorF("-nomulticursor Turn of multiple cursor support\n");
ErrorF("-fontpath Sets the default font path\n");
ErrorF("-stat inter scrns Print out performance statistics\n");
ErrorF("-syncbatch inter Set interval for XSync batching\n");
ErrorF("-nooffscreenopt Disable offscreen optimization\n");
ErrorF("-nosubdivprims Disable primitive subdivision\n");
ErrorF(" optimization\n");
ErrorF("-nowindowopt Disable lazy window creation optimization\n");
ErrorF("-noxkb Disable use of the XKB extension with\n");
ErrorF(" backend displays (cf. -kb).\n");
ErrorF("-depth Specify the default root window depth\n");
ErrorF("-norender Disable RENDER extension support\n");
#ifdef GLXEXT
ErrorF("-noglxproxy Disable GLX Proxy\n");
ErrorF("-noglxswapgroup Disable swap group and swap barrier\n");
ErrorF(" extensions in GLX proxy\n");
ErrorF("-glxsyncswap Force XSync after swap buffers\n");
ErrorF("-glxfinishswap Force glFinish after swap buffers\n");
#endif
ErrorF("-ignorebadfontpaths Ignore bad font paths during initialization\n");
ErrorF("-addremovescreens Enable dynamic screen addition/removal\n");
ErrorF("-param ... Specify configuration parameters (e.g.,\n");
ErrorF(" XkbRules, XkbModel, XkbLayout, etc.)\n");
ErrorF("\n");
ErrorF(" If the -input string matches a -display string, then input\n"
" is taken from that backend display. (XInput cannot be taken\n"
" from a backend display.) Placing \",console\" after the\n"
" display name will force a console window to be opened on\n"
" that display in addition to the backend input. This is\n"
" useful if the backend window does not cover the whole\n"
" physical display.\n\n");
ErrorF(" Otherwise, if the -input or -xinput string specifies another\n"
" X display, then a console window will be created on that\n"
" display. Placing \",windows\" or \",nowindows\" after the\n"
" display name will control the display of window outlines in\n"
" the console.\n\n");
ErrorF(" -input or -xinput dummy specifies no input.\n");
ErrorF(" -input or -xinput local specifies the use of a raw keyboard,\n"
" mouse, or other (extension) device:\n"
" -input local,kbd,ps2 will use a ps2 mouse\n"
" -input local,kbd,ms will use a serial mouse\n"
" -input local,usb-kbd,usb-mou will use USB devices \n"
" -xinput local,usb-oth will use a non-mouse and\n"
" non-keyboard USB device with XInput\n\n");
ErrorF(" Special Keys:\n");
ErrorF(" Ctrl-Alt-g Server grab/ungrab (console only)\n");
ErrorF(" Ctrl-Alt-f Fine (1-pixel) mouse mode (console only)\n");
ErrorF(" Ctrl-Alt-q Quit (core devices only)\n");
ErrorF(" Ctrl-Alt-F* Switch to VC (local only)\n");
}