Exemplo n.º 1
0
/** Starting with the \a start screen, iterate over all of the screens
 * on the same physical X server as \a start, calling \a f with the
 * screen and the \a closure.  (The common case is that \a start is the
 * only DMX window on the backend X server.) */
void *
dmxPropertyIterate(DMXScreenInfo * start,
                   void *(*f) (DMXScreenInfo * dmxScreen, void *),
                   void *closure)
{
    DMXScreenInfo *pt;

    if (!start->next) {
        if (!start->beDisplay)
            return NULL;
        return f(start, closure);
    }

    for (pt = start->next; /* condition at end of loop */ ; pt = pt->next) {
        void *retval;

        /* beDisplay ban be NULL if a screen was detached */
        dmxLog(dmxDebug, "pt = %p\n", pt);
        dmxLog(dmxDebug, "pt->beDisplay = %p\n", pt->beDisplay);
        if (pt->beDisplay && (retval = f(pt, closure)))
            return retval;
        if (pt == start)
            break;
    }
    return NULL;
}
Exemplo n.º 2
0
/** Returns 1 if the dmxScreen and the display in \a name are on the
 * same display, or 0 otherwise.  We can't just compare the display
 * names because there can be multiple synonyms for the same display,
 * some of which cannot be determined without accessing the display
 * itself (e.g., domain aliases or machines with multiple NICs). */
int
dmxPropertySameDisplay(DMXScreenInfo * dmxScreen, const char *name)
{
    Display *dpy0 = dmxScreen->beDisplay;
    Atom atom0;
    XTextProperty tp0;
    Display *dpy1 = NULL;
    Atom atom1;
    XTextProperty tp1;
    int retval = 0;

    if (!dpy0)
        return 0;

    tp0.nitems = 0;
    tp1.nitems = 0;

    if ((atom0 = XInternAtom(dpy0, DMX_ATOMNAME, True)) == None) {
        dmxLog(dmxWarning, "No atom on %s\n", dmxScreen->name);
        return 0;
    }
    if (!XGetTextProperty(dpy0, RootWindow(dpy0, 0), &tp0, atom0)
        || !tp0.nitems) {
        dmxLog(dmxWarning, "No text property on %s\n", dmxScreen->name);
        return 0;
    }

    if (!(dpy1 = XOpenDisplay(name))) {
        dmxLog(dmxWarning, "Cannot open %s\n", name);
        goto cleanup;
    }
    atom1 = XInternAtom(dpy1, DMX_ATOMNAME, True);
    if (atom1 == None) {
        dmxLog(dmxDebug, "No atom on %s\n", name);
        goto cleanup;
    }
    if (!XGetTextProperty(dpy1, RootWindow(dpy1, 0), &tp1, atom1)
        || !tp1.nitems) {
        dmxLog(dmxDebug, "No text property on %s\n", name);
        goto cleanup;
    }
    if (!strcmp((char *) tp0.value, (char *) tp1.value))
        retval = 1;

 cleanup:
    if (tp0.nitems)
        XFree(tp0.value);
    if (tp1.nitems)
        XFree(tp1.value);
    if (dpy1)
        XCloseDisplay(dpy1);
    return retval;
}
Exemplo n.º 3
0
/** Initialize the XSync() batching optimization, but only if
 * #dmxSyncActivate was last called with a non-negative value. */
void dmxSyncInit(void)
{
    if (dmxSyncInterval) {
        RegisterBlockAndWakeupHandlers(dmxSyncBlockHandler,
                                       dmxSyncWakeupHandler,
                                       NULL);
        dmxLog(dmxInfo, "XSync batching with %d ms interval\n",
               dmxSyncInterval);
    } else {
        dmxLog(dmxInfo, "XSync batching disabled\n");
    }
}
Exemplo n.º 4
0
/* Actually do the work of printing out the human-readable message. */
static CARD32
dmxStatCallback(OsTimerPtr timer, CARD32 t, void *arg)
{
    int i, j;
    static int header = 0;
    int limit = dmxNumScreens;

    if (!dmxNumScreens) {
        header = 0;
        return DMX_STAT_INTERVAL;
    }

    if (!header++ || !(header % 10)) {
        dmxLog(dmxDebug,
               " S SyncCount  Sync/s avSync mxSync avPend mxPend | "
               "<10ms   <1s   >1s\n");
    }

    if (dmxStatDisplays && dmxStatDisplays < limit)
        limit = dmxStatDisplays;
    for (i = 0; i < limit; i++) {
        DMXScreenInfo *dmxScreen = &dmxScreens[i];
        DMXStatInfo *s = dmxScreen->stat;
        unsigned long aSync, mSync;
        unsigned long aPend, mPend;

        if (!s)
            continue;

        aSync = avg(&s->usec, &mSync);
        aPend = avg(&s->pending, &mPend);
        dmxLog(dmxDebug, "%2d %9lu %7lu %6lu %6lu %6lu %6lu |", i,      /* S */
               s->syncCount,    /* SyncCount */
               (s->syncCount - s->oldSyncCount) * 1000 / dmxStatInterval,       /* Sync/s */
               aSync,           /* us/Sync */
               mSync,           /* max/Sync */
               aPend,           /* avgPend */
               mPend);          /* maxPend */
        for (j = 0; j < DMX_STAT_BINS; j++)
            dmxLogCont(dmxDebug, " %5lu", s->bins[j]);
        dmxLogCont(dmxDebug, "\n");

        /* Reset/clear */
        s->oldSyncCount = s->syncCount;
        for (j = 0; j < DMX_STAT_BINS; j++)
            s->bins[j] = 0;
    }
    return DMX_STAT_INTERVAL;   /* Place on queue again */
}
Exemplo n.º 5
0
/** Prints a log message if \a dmxScreen is on the same backend X server
 * as some other DMX backend (output) screen.  Modifies the property
 * (#DMX_ATOMNAME) on the backend X server to reflect the creation of \a
 * dmxScreen.
 *
 * The root window of the backend X server holds a list of window ids
 * for all DMX windows (on this DMX server or some other DMX server).
 *
 * This list can then be iterated, and the property for each window can
 * be examined.  This property contains the following tuple (no quotes):
 *
 * "#DMX_IDENT:<hostname running DMX>:<display name of DMX>,<screen number>"
 */
void
dmxPropertyWindow(DMXScreenInfo * dmxScreen)
{
    Atom atom;
    const unsigned char *id = dmxPropertyIdentifier();
    Display *dpy = dmxScreen->beDisplay;
    Window win = dmxScreen->scrnWin;
    DMXScreenInfo *other;
    char buf[128];              /* RATS: only used with snprintf */

    if (!dpy)
        return;                 /* FIXME: What should be done here if Xdmx is started
                                 * with this screen initially detached?
                                 */

    atom = XInternAtom(dpy, DMX_ATOMNAME, False);
    if ((other = dmxPropertyCheckOtherWindows(dmxScreen, atom))) {
        DMXScreenInfo *tmp = dmxScreen->next;

        dmxScreen->next = (other->next ? other->next : other);
        other->next = (tmp ? tmp : dmxScreen);
        dmxLog(dmxDebug, "%d/%s/%lu and %d/%s/%lu are on the same backend\n",
               dmxScreen->index, dmxScreen->name, dmxScreen->scrnWin,
               other->index, other->name, other->scrnWin);
    }

    snprintf(buf, sizeof(buf), ".%d,%lu", dmxScreen->index,
             (long unsigned) win);
    XChangeProperty(dpy, RootWindow(dpy, 0), atom, XA_STRING, 8,
                    PropModeAppend, (unsigned char *) buf, strlen(buf));

    snprintf(buf, sizeof(buf), "%s,%d", id, dmxScreen->index);
    XChangeProperty(dpy, win, atom, XA_STRING, 8,
                    PropModeAppend, (unsigned char *) buf, strlen(buf));
}
Exemplo n.º 6
0
/** Create a mapping from \a remoteEvent to \a serverEvent. The \a
 * remoteEvent is the type returned from the remote server.  The \a
 * serverEvent is from the XI_* list of events in
 * include/extensions/XIproto.h. */
void
dmxMapInsert(DMXLocalInputInfoPtr dmxLocal, int remoteEvent, int serverEvent)
{
    int hash = remoteEvent & DMX_MAP_MASK;
    int i;

    /* Return if this has already been mapped */
    if (dmxLocal->map[hash].remote == remoteEvent
        && dmxLocal->map[hash].server == serverEvent)
        return;

    if (dmxLocal->map[hash].remote) {
        dmxLocal->mapOptimize = 0;
        for (i = 0; i < DMX_MAP_ENTRIES; i++) {
            if (!dmxLocal->map[i].remote) {
                dmxLocal->map[i].remote = remoteEvent;
                dmxLocal->map[i].server = serverEvent;
                return;
            }
        }
        dmxLog(dmxWarning,
               "Out of map entries, cannot map remove event type %d\n",
               remoteEvent);
    }
    else {
        dmxLocal->map[hash].remote = remoteEvent;
        dmxLocal->map[hash].server = serverEvent;
    }
}
Exemplo n.º 7
0
/** Make a note that \a config should be used as the configuration for
 * current instantiation of the DMX server. */
void
dmxConfigStoreConfig(const char *config)
{
    if (dmxConfigCmd.config)
        dmxLog(dmxFatal, "Only one -config allowed\n");
    dmxConfigCmd.config = strdup(config);
}
Exemplo n.º 8
0
/** Make a note that \a file is the configuration file. */
void
dmxConfigStoreFile(const char *file)
{
    if (dmxConfigCmd.filename)
        dmxLog(dmxFatal, "Only one -configfile allowed\n");
    dmxConfigCmd.filename = strdup(file);
}
Exemplo n.º 9
0
/** Returns NULL if this is the only Xdmx window on the display.
 * Otherwise, returns a pointer to the dmxScreen of the other windows on
 * the display. */
static DMXScreenInfo *
dmxPropertyCheckOtherWindows(DMXScreenInfo * dmxScreen, Atom atom)
{
    Display *dpy = dmxScreen->beDisplay;
    const unsigned char *id = dmxPropertyIdentifier();
    XTextProperty tproot;
    XTextProperty tp;
    const char *pt;
    int (*dmxOldHandler) (Display *, XErrorEvent *);

    if (!dpy)
        return NULL;

    if (!XGetTextProperty(dpy, RootWindow(dpy, 0), &tproot, atom)
        || !tproot.nitems)
        return 0;

    /* Ignore BadWindow errors for this
     * routine because the window id stored
     * in the property might be old */
    dmxOldHandler = XSetErrorHandler(dmxPropertyErrorHandler);
    for (pt = (const char *) tproot.value; pt && *pt; pt = pt ? pt + 1 : NULL) {
        if ((pt = strchr(pt, ','))) {
            Window win = strtol(pt + 1, NULL, 10);

            if (XGetTextProperty(dpy, win, &tp, atom) && tp.nitems) {
                dmxLog(dmxDebug, "On %s/%lu: %s\n",
                       dmxScreen->name, win, tp.value);
                if (!strncmp((char *) tp.value, (char *) id,
                             strlen((char *) id))) {
                    int idx;

                    if (!(pt = strchr((char *) tp.value, ',')))
                        continue;
                    idx = strtol(pt + 1, NULL, 10);
                    if (idx < 0 || idx >= dmxNumScreens)
                        continue;
                    if (dmxScreens[idx].scrnWin != win)
                        continue;
                    XSetErrorHandler(dmxOldHandler);
                    return &dmxScreens[idx];
                }
                XFree(tp.value);
            }
        }
    }
    XSetErrorHandler(dmxOldHandler);
    XFree(tproot.value);
    return 0;
}
Exemplo n.º 10
0
static int
dmxConfigReadFile(const char *filename, int debug)
{
    FILE *str;

    if (!(str = fopen(filename, "r")))
        return -1;
    dmxLog(dmxInfo, "Reading configuration file \"%s\"\n", filename);
    yyin = str;
    yydebug = debug;
    yyparse();
    fclose(str);
    return 0;
}
Exemplo n.º 11
0
/** Make a note that \a input is the name of an X11 display that should
 * be used for input from XInput extension devices. */
void
dmxConfigStoreXInput(const char *input)
{
    DMXConfigListPtr entry = malloc(sizeof(*entry));

    entry->name = strdup(input);
    entry->next = NULL;
    if (!dmxConfigCmd.xinputs)
        dmxConfigCmd.xinputs = entry;
    else {
        DMXConfigList *pt;

        for (pt = dmxConfigCmd.xinputs; pt->next; pt = pt->next);
        if (!pt)
            dmxLog(dmxFatal, "dmxConfigStoreXInput: end of list non-NULL\n");
        pt->next = entry;
    }
}
Exemplo n.º 12
0
/** Request an XSync() to the display used by \a dmxScreen.  If \a now
 * is TRUE, call XSync() immediately instead of waiting for the next
 * XSync() batching point.  Note that if XSync() batching was deselected
 * with #dmxSyncActivate() before #dmxSyncInit() was called, then no
 * XSync() batching is performed and this function always calles XSync()
 * immediately.
 *
 * (Note that this function uses TimerSet but works correctly in the
 * face of a server generation.  See the source for details.)
 *
 * If \a dmxScreen is \a NULL, then all pending syncs will be flushed
 * immediately.
 */
void dmxSync(DMXScreenInfo *dmxScreen, Bool now)
{
    static unsigned long dmxGeneration = 0;

    if (dmxSyncInterval) {
        if (dmxGeneration != serverGeneration) {
            /* Server generation does a TimerInit, which frees all
             * timers.  So, at this point dmxSyncTimer is either:
             * 1) NULL, iff dmxGeneration == 0,
             * 2) freed, if it was on a queue (dmxSyncPending != 0), or
             * 3) allocated, if it wasn't on a queue (dmxSyncPending == 0)
             */
            if (dmxSyncTimer && !dmxSyncPending) xfree(dmxSyncTimer);
            dmxSyncTimer  = NULL;
            now           = TRUE;
            dmxGeneration = serverGeneration;
        }
                                /* Queue sync */
        if (dmxScreen) {
            dmxScreen->needsSync = TRUE;
            ++dmxSyncPending;
        }

                                /* Do sync or set time for later */
        if (now || !dmxScreen) {
            if (!TimerForce(dmxSyncTimer)) dmxSyncCallback(NULL, 0, NULL);
            /* At this point, dmxSyncPending == 0 because
             * dmxSyncCallback must have been called. */
            if (dmxSyncPending)
                dmxLog(dmxFatal, "dmxSync(%s,%d): dmxSyncPending = %d\n",
                       dmxScreen ? dmxScreen->name : "", now, dmxSyncPending);
        } else {
            dmxScreen->needsSync = TRUE;
            if (dmxSyncPending == 1)
                dmxSyncTimer = TimerSet(dmxSyncTimer, 0, dmxSyncInterval,
                                        dmxSyncCallback, NULL);
        }
    } else {
                                /* If dmxSyncInterval is not being used,
                                 * then all the backends are already
                                 * up-to-date. */
        if (dmxScreen) dmxDoSync(dmxScreen);
    }
}
Exemplo n.º 13
0
/** Make a note that \a display is the name of an X11 display that
 * should be initialized as a backend (output) display.  Called from
 * #ddxProcessArgument. */
void
dmxConfigStoreDisplay(const char *display)
{
    DMXConfigListPtr entry = malloc(sizeof(*entry));

    entry->name = strdup(display);
    entry->next = NULL;
    if (!dmxConfigCmd.displays)
        dmxConfigCmd.displays = entry;
    else {
        DMXConfigList *pt;

        for (pt = dmxConfigCmd.displays; pt->next; pt = pt->next);
        if (!pt)
            dmxLog(dmxFatal, "dmxConfigStoreDisplay: end of list non-NULL\n");
        pt->next = entry;
    }
    ++dmxDisplaysFromCommandLine;
}
Exemplo n.º 14
0
/** Load the font, \a pFont, on the back-end server associated with \a
 *  pScreen.  When a font is loaded, the font path on back-end server is
 *  first initialized to that specified on the command line with the
 *  -fontpath options, and then the font is loaded. */
Bool
dmxBELoadFont(ScreenPtr pScreen, FontPtr pFont)
{
    DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
    dmxFontPrivPtr pFontPriv = FontGetPrivate(pFont, dmxFontPrivateIndex);
    const char *name;
    char **oldFontPath = NULL;
    int nOldPaths;
    Atom name_atom, value_atom;
    int i;

    /* Make sure we have a font private struct to work with */
    if (!pFontPriv)
        return FALSE;

    /* Don't load a font over top of itself */
    if (pFontPriv->font[pScreen->myNum]) {
        return TRUE;            /* Already loaded font */
    }

    /* Save old font path */
    oldFontPath = XGetFontPath(dmxScreen->beDisplay, &nOldPaths);

    /* Set the font path for the font about to be loaded on the back-end */
    if (dmxSetFontPath(dmxScreen)) {
        char **fp;
        int npaths;
        Bool *goodfps;

        /* This could fail only when first starting the X server and
         * loading the default font.  If it fails here, then the default
         * font path is invalid, no default font path will be set, the
         * DMX server will fail to load the default font, and it will
         * exit with an error unless we remove the offending font paths
         * with the -ignorebadfontpaths command line option.
         */

        fp = dmxGetFontPath(&npaths);
        if (!fp) {
            dmxLog(dmxError, "No default font path set.\n");
            dmxLog(dmxError,
                   "Please see the Xdmx man page for information on how to\n");
            dmxLog(dmxError,
                   "initialize the DMX server's default font path.\n");
            XFreeFontPath(oldFontPath);
            return FALSE;
        }

        if (!dmxFontPath)
            dmxLog(dmxWarning, "No default font path is set.\n");

        goodfps = xallocarray(npaths, sizeof(*goodfps));

        dmxLog(dmxError,
               "The DMX server failed to set the following font paths on "
               "screen #%d:\n", pScreen->myNum);

        for (i = 0; i < npaths; i++)
            if (!(goodfps[i] = dmxCheckFontPathElement(dmxScreen, fp[i])))
                dmxLog(dmxError, "    %s\n", fp[i]);

        if (dmxIgnoreBadFontPaths) {
            char *newfp;
            int newnpaths = 0;
            int len = 0;
            int j = 0;

            dmxLog(dmxError,
                   "These font paths will not be used because the "
                   "\"-ignorebadfontpaths\"\n");
            dmxLog(dmxError, "option is set.\n");

            for (i = 0; i < npaths; i++)
                if (goodfps[i]) {
                    len += strlen(fp[i]) + 1;
                    newnpaths++;
                }

            if (!newnpaths) {
                /* No valid font paths were found */
                dmxLog(dmxError,
                       "After removing the font paths above, no valid font "
                       "paths were\n");
                dmxLog(dmxError,
                       "available.  Please check that the font paths set on "
                       "the command\n");
                dmxLog(dmxError,
                       "line or in the configuration file via the "
                       "\"-fontpath\" option\n");
                dmxLog(dmxError,
                       "are valid on all back-end servers.  See the Xdmx man "
                       "page for\n");
                dmxLog(dmxError, "more information on font paths.\n");
                dmxFreeFontPath(fp);
                XFreeFontPath(oldFontPath);
                free(goodfps);
                return FALSE;
            }

            newfp = xallocarray(len, sizeof(*newfp));
            for (i = 0; i < npaths; i++) {
                if (goodfps[i]) {
                    int n = strlen(fp[i]);

                    newfp[j++] = n;
                    strncpy(&newfp[j], fp[i], n);
                    j += n;
                }
            }

            if (SetFontPath(serverClient, newnpaths, (unsigned char *) newfp)) {
                /* Note that this should never happen since all of the
                 * FPEs were previously valid. */
                dmxLog(dmxError, "Cannot reset the default font path.\n");
            }
        }
        else if (dmxFontPath) {
            dmxLog(dmxError,
                   "Please remove these font paths from the command line "
                   "or\n");
            dmxLog(dmxError,
                   "configuration file, or set the \"-ignorebadfontpaths\" "
                   "option to\n");
            dmxLog(dmxError,
                   "ignore them.  For more information on these options, see "
                   "the\n");
            dmxLog(dmxError, "Xdmx man page.\n");
        }
        else {
            dmxLog(dmxError,
                   "Please specify the font paths that are available on all "
                   "back-end\n");
            dmxLog(dmxError,
                   "servers with the \"-fontpath\" option, or use the "
                   "\"-ignorebadfontpaths\"\n");
            dmxLog(dmxError,
                   "to ignore bad defaults.  For more information on "
                   "these and other\n");
            dmxLog(dmxError,
                   "font-path-related options, see the Xdmx man page.\n");
        }

        free(goodfps);
        if (!dmxIgnoreBadFontPaths ||
            (dmxIgnoreBadFontPaths && dmxSetFontPath(dmxScreen))) {
            /* We still have errors so return with error */
            dmxFreeFontPath(fp);
            XFreeFontPath(oldFontPath);
            return FALSE;
        }
    }

    /* Find requested font on back-end server */
    name_atom = MakeAtom("FONT", 4, TRUE);
    value_atom = 0L;

    for (i = 0; i < pFont->info.nprops; i++) {
        if ((Atom) pFont->info.props[i].name == name_atom) {
            value_atom = pFont->info.props[i].value;
            break;
        }
    }
    if (!value_atom)
        return FALSE;

    name = NameForAtom(value_atom);
    if (!name)
        return FALSE;

    pFontPriv->font[pScreen->myNum] =
        XLoadQueryFont(dmxScreen->beDisplay, name);

    /* Restore old font path */
    XSetFontPath(dmxScreen->beDisplay, oldFontPath, nOldPaths);
    XFreeFontPath(oldFontPath);
    dmxSync(dmxScreen, FALSE);

    if (!pFontPriv->font[pScreen->myNum])
        return FALSE;

    return TRUE;
}
Exemplo n.º 15
0
/** Print \a argc messages, each describing an element in \a argv.  This
 * is maingly for debugging purposes. */
void dmxLogArgs(dmxLogLevel logLevel, int argc, char **argv)
{
    int i;
    for (i = 0; i < argc; i++)
        dmxLog(logLevel, "   Arg[%d] = \"%s\"\n", i, argv[i]);
}
Exemplo n.º 16
0
void
__glXScreenInit(GLint numscreens)
{
    int s;
    int c;
    DMXScreenInfo *dmxScreen0 = &dmxScreens[0];

    __glXNumActiveScreens = numscreens;

    CalcServerVersionAndExtensions();

    __glXFBConfigs = NULL;
    __glXNumFBConfigs = 0;

    if ((__glXVersionMajor == 1 && __glXVersionMinor >= 3) ||
        (__glXVersionMajor > 1) ||
        (strstr(ExtensionsString, "GLX_SGIX_fbconfig"))) {

        /*
           // Initialize FBConfig info.
           // find the set of FBConfigs that are present on all back-end
           // servers - only those configs will be supported
         */
        __glXFBConfigs = (__GLXFBConfig **) malloc(dmxScreen0->numFBConfigs *
                                                   (numscreens +
                                                    1) *
                                                   sizeof(__GLXFBConfig *));
        __glXNumFBConfigs = 0;

        for (c = 0; c < dmxScreen0->numFBConfigs; c++) {
            __GLXFBConfig *cfg = NULL;

            if (numscreens > 1) {
                for (s = 1; s < numscreens; s++) {
                    DMXScreenInfo *dmxScreen = &dmxScreens[s];

                    cfg = FindMatchingFBConfig(&dmxScreen0->fbconfigs[c],
                                               dmxScreen->fbconfigs,
                                               dmxScreen->numFBConfigs);
                    __glXFBConfigs[__glXNumFBConfigs * (numscreens + 1) + s +
                                   1] = cfg;
                    if (!cfg) {
                        dmxLog(dmxInfo,
                               "screen0 FBConfig 0x%x is missing on screen#%d\n",
                               dmxScreen0->fbconfigs[c].id, s);
                        break;
                    }
                    else {
                        dmxLog(dmxInfo,
                               "screen0 FBConfig 0x%x matched to  0x%x on screen#%d\n",
                               dmxScreen0->fbconfigs[c].id, cfg->id, s);
                    }
                }
            }
            else {
                cfg = &dmxScreen0->fbconfigs[c];
            }

            if (cfg) {

                /* filter out overlay visuals */
                if (cfg->level == 0) {
                    __GLXFBConfig *proxy_cfg;

                    __glXFBConfigs[__glXNumFBConfigs * (numscreens + 1) + 1] =
                        &dmxScreen0->fbconfigs[c];

                    proxy_cfg = malloc(sizeof(__GLXFBConfig));
                    memcpy(proxy_cfg, cfg, sizeof(__GLXFBConfig));
                    proxy_cfg->id = FakeClientID(0);
                    /* visual will be associated later in __glXGetFBConfigs */
                    proxy_cfg->associatedVisualId = (unsigned int) -1;

                    __glXFBConfigs[__glXNumFBConfigs * (numscreens + 1) + 0] =
                        proxy_cfg;

                    __glXNumFBConfigs++;
                }

            }

        }

    }

}
Exemplo n.º 17
0
/** Fill the \a info structure with information needed to initialize \a
 * pDev. */ 
void othUSBGetInfo(DevicePtr pDev, DMXLocalInitInfoPtr info)
{
    GETPRIV;
    int           i, j;
    static KeySym keyboard_mapping = NoSymbol;
    int           absolute[5];
    
#define test_bit(bit) (priv->mask[(bit)/8] & (1 << ((bit)%8)))

                                /* Some USB mice devices return key
                                 * events from their pair'd
                                 * keyboard...  */
    info->keyClass           = 1;
    info->keySyms.minKeyCode = 8;
    info->keySyms.maxKeyCode = 8;
    info->keySyms.mapWidth   = 1;
    info->keySyms.map        = &keyboard_mapping;

    for (i = 0; i < EV_MAX; i++) {
        if (test_bit(i)) {
            switch (i) {
            case EV_KEY:
                                /* See above */
                break;
            case EV_REL:
                info->valuatorClass      = 1;
                if (info->numRelAxes + info->numAbsAxes > DMX_MAX_AXES - 1) {
                    info->numRelAxes     = DMX_MAX_AXES - info->numAbsAxes - 1;
                    dmxLog(dmxWarning, "Can only use %d relative axes\n",
                           info->numRelAxes);
                } else
                    info->numRelAxes     = priv->numRel;
                info->minval[0]          = 0;
                info->maxval[0]          = 0;
                info->res[0]             = 1;
                info->minres[0]          = 0;
                info->maxres[0]          = 1;
                break;
            case EV_ABS:
                info->valuatorClass      = 1;
                if (info->numRelAxes + info->numAbsAxes > DMX_MAX_AXES - 1) {
                    info->numAbsAxes     = DMX_MAX_AXES - info->numRelAxes - 1;
                    dmxLog(dmxWarning, "Can only use %d absolute axes\n",
                           info->numAbsAxes);
                } else
                    info->numAbsAxes     = priv->numAbs;
                for (j = 0; j < info->numAbsAxes; j++) {
                    ioctl(priv->fd, EVIOCGABS(j), abs);
                    info->minval[1+j]    = absolute[1];
                    info->maxval[1+j]    = absolute[2];
                    info->res[1+j]       = absolute[3];
                    info->minres[1+j]    = absolute[3];
                    info->maxres[1+j]    = absolute[3];
                }
                break;
            case EV_LED:
                info->ledFeedbackClass   = 0; /* Not supported at this time */
                break;
            case EV_SND:
                info->belFeedbackClass   = 0; /* Not supported at this time */
                break;
            }
        }
    }
}