Edit

IABSD.fr/xenocara/app/xvctl/xvctl.c

Branch :

  • Show log

    Commit

  • Author : espie
    Date : 2013-08-26 19:25:10
    Hash : 6d7d1297
    Message : revisit old program of mine, make it look a bit more like sysctl after simplifications. okay matthieu@

  • app/xvctl/xvctl.c
  • /*	$OpenBSD: xvctl.c,v 1.3 2013/08/26 19:25:10 espie Exp $	*/
    /*
     * Copyright (c) 2001 Marc Espie.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     * 1. Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     * 2. 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.
     *
     * THIS SOFTWARE IS PROVIDED BY THE OPENBSD PROJECT 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 OPENBSD
     * PROJECT 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.
     */
    #include <X11/X.h>
    #include <X11/Xlib.h>
    #include <X11/extensions/Xvlib.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <err.h>
    #include <string.h>
    #include <ctype.h>
    
    void
    usage()
    {
    	fprintf(stderr,  "usage:\t%s\n\t%s\n\t%s\n",
    	    "xvctl [-n] [-d display] [-s screen] [-A adaptor] variable ...",
    	    "xvctl [-n] [-d display] [-s screen] [-A adaptor] variable=value ...",
    	    "xvctl [-n] [-d display] [-s screen] [-A adaptor] -a");
    	exit(1);
    }
    
    char *
    reformat(char *name)
    {
    	static char result[BUFSIZ];
    	char *s;
    	char *t;
    
    	if (strlcpy(result, name, sizeof result) >= sizeof result)
    		warnx("Name %s was truncated", name);
    	s = result;
    	if (strncmp(result, "XV_", 3) == 0)
    		s+=3;
    	for (t = s; *t; t++)
    		*t = tolower(*t);
        	return s;
    }
    
    XvAttribute *
    findname(XvAttribute table[], int nattr, const char *name)
    {
    	int i;
    
    	if (strncasecmp(name, "XV_", 3) == 0)
    		name +=3; 
    	for (i = 0; i < nattr; i++) {
    		if (strcasecmp(table[i].name+3, name) == 0)
    			return table+i;
    	}
    	warnx("No such attribute %s", name);
    	return NULL;
    }
    
    void
    printattribute(Display *dpy, XvPortID id, int nflag, XvAttribute *a)
    {
    	Atom atom;
    	int v;
    
    	atom = XInternAtom(dpy, a->name, True);
    	if (atom != None)
    		if (Success == XvGetPortAttribute(dpy, id, atom, &v)) {
    			if (!nflag)
    				printf("%s=", reformat(a->name));
    			printf("%d\n", v);
    		}
    }
    
    void
    showall(Display *dpy, XvPortID id, int nflag, XvAttribute table[], int nattr)
    {
    	int i;
    
    	for (i = 0; i < nattr; i++)
    		if (table[i].flags & XvGettable)
    			printattribute(dpy, id, nflag, table+i);
    }
    
    void
    setvar(Display *dpy, XvPortID id, int nflag, XvAttribute table[], int nattr,
        const char *name, int v)
    {
    	XvAttribute *at;
    	Atom atom;
    
    	at = findname(table, nattr, name);
    	if (!at) 
    		return;
    	if (!(at->flags & XvSettable)) {
    		warnx("Can't set %s", name);
    		return;
    	}
    	if ((at->max_value != -1 && v > at->max_value)  || v < at->min_value) {
    		warnx("Value %d for %s out of range (%d-%d)", v, name,
    		    at->min_value, at->max_value);
    		return;
    	}
    	atom = XInternAtom(dpy, at->name, True);
    	if (atom != None)
    		if (Success == XvSetPortAttribute(dpy, id, atom, v)) {
    			if (!nflag)
    				printattribute(dpy, id, nflag, at);
    		}
    }
    
    void
    showvar(Display *dpy, XvPortID id, int nflag, XvAttribute table[], int nattr,
        const char *name)
    {
    	XvAttribute *at;
    
    	at = findname(table, nattr, name);
    	if (!at)
    		return;
        	if (!(at->flags & XvGettable)) {
    		warnx("Can't get %s", name);
    		return;
    	}
    	printattribute(dpy, id, nflag, at);
    }
    
    void
    parse(Display *dpy, XvPortID id, int nflag, XvAttribute table[],
        int nattr, const char *s)
    {
    	char buf[BUFSIZ];
    	char *cp;
    
    	if (strlcpy(buf, s, sizeof buf) >= sizeof(buf))
    		warnx("Buffer too small for %s", s);
    	cp = strchr(buf, '=');
    	if (cp != NULL) {
    		long v;
    		char *end;
    		char *tail;
    
    		tail = cp;
    		while (tail > buf && isspace(tail[-1]))
    			tail--;
    		*tail = 0;
    		do {
    			cp++;
    		} while (isspace(*cp));
    		v = strtol(cp, &end, 0);
    		if (*end != 0) {
    			warnx("Bogus value: %s", cp);
    			return;
    		}
    		setvar(dpy, id, nflag, table, nattr, buf, v);
    	} else
    		showvar(dpy, id, nflag, table, nattr, buf);
    }
    
    char *
    displayname(char *display)
    {
    	return display ? display : XDisplayName(display);
    }
    
    int
    main(int argc, char *argv[])
    {
    	int ch;
    	int aflag = 0;
    	int nflag = 0;
    	char *display = NULL;
    	int screen = -1;
    	int nscreens;
    	int nattr;
    	unsigned int nadaptors;
    	XvAdaptorInfo *ainfo;
    	XvAttribute *table;
    	int adaptor = 0;
    	Display *dpy;
    	unsigned int ver, rev, eventB, reqB, errorB;
    
    	while ((ch = getopt(argc, argv, "ad:ns:A:w")) != -1) {
    		switch(ch) {
    		case 'a':
    			aflag = 1;
    			break;
    		case 'd':
    			display = optarg;
    			break;
    		case 's':
    			screen = atoi(optarg);
    			break;
    		case 'A':
    			adaptor = atoi(optarg);
    			break;
    		case 'n':
    			nflag = 1;
    			break;
    		case 'w':
    			/* flag no longer needed */
    			break;
    		default:
    			usage();
    		}
    	}
    	argc -= optind;
    	argv += optind;
    
    	dpy = XOpenDisplay(display);
    	if (!dpy)
    		errx(1, "Unable to open display %s", displayname(display));
    	if (Success != XvQueryExtension(dpy, &ver, &rev, &reqB, &eventB,
    	    &errorB)) 
    	    	errx(1, "No X-Video extension on %s", displayname(display));
    
    	if (!nflag)
    		printf("# X-Video extension version %i.%i on %s\n", ver, rev,
    		    displayname(display));
    
    	nscreens = ScreenCount(dpy);
    	if (screen == -1) {
    		for (screen = 0; screen < nscreens; screen++) {
    			XvQueryAdaptors(dpy, RootWindow(dpy, screen),
    			    &nadaptors, &ainfo);
    			if (nadaptors)
    				break;
    		}
    	}
    	if (screen >= nscreens)
    		errx(1, "Not a screen with adaptors");
    
    	if (adaptor > nadaptors)
    		errx(1, "No such adaptor");
    
    	table = XvQueryPortAttributes(dpy, ainfo[adaptor].base_id, &nattr);
    
    
    	if (argc == 0) {
    		showall(dpy, ainfo[adaptor].base_id, nflag, table, nattr);
    	}
    	for (; *argv != NULL; ++argv)
    		parse(dpy, ainfo[adaptor].base_id, nflag, table,
    		    nattr, *argv);
    	XFree(table);
    	exit(0);
    }