On Fri, Oct 08, 2010 at 07:22:40PM +0200, Takashi Iwai wrote:
> This is a daemon program to sync Xrandr rotation with the synaptics device.

can we please integrate this with the respective DEs instead?

Cheers,
  Peter

> Signed-off-by: Takashi Iwai <[email protected]>
> ---
>  tools/Makefile.am |    5 +-
>  tools/synxrrd.c   |  186 
> +++++++++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 190 insertions(+), 1 deletions(-)
>  create mode 100644 tools/synxrrd.c
> 
> diff --git a/tools/Makefile.am b/tools/Makefile.am
> index 2ad48f6..1111576 100644
> --- a/tools/Makefile.am
> +++ b/tools/Makefile.am
> @@ -18,7 +18,7 @@
>  #  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.
>  
> -bin_PROGRAMS = synclient syndaemon
> +bin_PROGRAMS = synclient syndaemon synxrrd
>  
>  AM_CPPFLAGS = -I$(top_srcdir)/include -I$(sdkdir)
>  AM_CFLAGS = $(XI_CFLAGS)
> @@ -30,3 +30,6 @@ syndaemon_SOURCES = syndaemon.c
>  syndaemon_CFLAGS = $(AM_CFLAGS) $(XTST_CFLAGS)
>  syndaemon_LDFLAGS = $(AM_LDFLAGS) $(XTST_LIBS)
>  
> +synxrrd_SOURCES = synxrrd.c
> +synxrrd_LDFLAGS = -lXrandr $(XLIB_LIBS) $(XI_LIBS)
> +
> diff --git a/tools/synxrrd.c b/tools/synxrrd.c
> new file mode 100644
> index 0000000..9f00e5b
> --- /dev/null
> +++ b/tools/synxrrd.c
> @@ -0,0 +1,186 @@
> +/*
> + * synxrrd.c
> + * Copyright (C) 2010 Takashi Iwai <[email protected]>
> + */
> +
> +#include <stdio.h>
> +#include <stdarg.h>
> +#include <stdlib.h>
> +#include <string.h>
> +#include <unistd.h>
> +#include <X11/Xlib.h>
> +#include <X11/extensions/Xrandr.h>
> +
> +#define progname     "synxrrd"
> +
> +static int verbose;
> +static const char *laptop_name;
> +
> +static int is_laptop(const char *name)
> +{
> +     if (laptop_name) {
> +             if (!strcmp(name, laptop_name))
> +                     return 1;
> +     } else {
> +             if (strstr(name, "LVDS") ||
> +                 strstr(name, "Lvds") ||
> +                 strstr(name, "LVDs"))
> +                     return 1;
> +             if (strstr(name, "LCD"))
> +                     return 1;
> +     }
> +     return 0;
> +}
> +
> +static int current_rotation = -1; /* unknown */
> +
> +static int (*xerror_saved)(Display *, XErrorEvent *);
> +static int xerror_code;
> +
> +static int xerror_ignore(Display *dpy, XErrorEvent *err)
> +{
> +     xerror_code = err->error_code;
> +     return 0;
> +}
> +
> +extern int (*_XErrorFunction)(Display *, XErrorEvent *);
> +extern int _XDefaultError(Display *dpy, XErrorEvent *event);
> +
> +static void xerror_save(void)
> +{
> +     xerror_code = 0;
> +     xerror_saved = _XErrorFunction;
> +     _XErrorFunction = xerror_ignore;
> +}
> +
> +static int xerror_restore(void)
> +{
> +     _XErrorFunction = xerror_saved;
> +     return xerror_code;
> +}
> +
> +static void notify_synaptics(XRRCrtcInfo *cres)
> +{
> +     int rotation;
> +     char buf[256];
> +
> +     if (cres->rotation & 8)
> +             rotation = 3;
> +     else if (cres->rotation & 4)
> +             rotation = 2;
> +     else if (cres->rotation & 2)
> +             rotation = 1;
> +     else
> +             rotation = 0;
> +     if (current_rotation == rotation)
> +             return;
> +     current_rotation = rotation;
> +     if (verbose)
> +             fprintf(stderr, "%s: notified rotation %d\n",
> +                     progname, current_rotation);
> +     sprintf(buf, "synclient Orientation=%d", current_rotation);
> +     system(buf);
> +}
> +
> +static void update_screen(Display *dpy, Window root)
> +{
> +     XRRScreenResources *res;
> +     int i;
> +
> +     res = XRRGetScreenResources(dpy, root);
> +     if (!res)
> +             return;
> +     for (i = 0; i < res->noutput; i++) {
> +             XRROutputInfo *info;
> +
> +             info = XRRGetOutputInfo(dpy, res, res->outputs[i]);
> +             if (!info)
> +                     continue;
> +             if (is_laptop(info->name)) {
> +                     RRCrtc crtc = info->crtc;
> +                     XRRCrtcInfo *cres;
> +
> +                     XRRFreeOutputInfo(info);
> +                     cres = XRRGetCrtcInfo(dpy, res, crtc);
> +                     if (!cres)
> +                             continue;
> +                     notify_synaptics(cres);
> +                     XRRFreeCrtcInfo(cres);
> +                     break;
> +             }
> +             XRRFreeOutputInfo(info);
> +     }
> +     XRRFreeScreenResources(res);
> +}
> +
> +static void synxrr_daemon(Display *dpy, Window root)
> +{
> +     int event_base, error_base;
> +
> +     XRRQueryExtension(dpy, &event_base, &error_base);
> +
> +     XRRSelectInput(dpy, root, RRScreenChangeNotifyMask);
> +
> +     for (;;) {
> +             XEvent event;
> +
> +             XNextEvent(dpy, &event);
> +             xerror_save();
> +             XRRUpdateConfiguration(&event);
> +             switch (event.type - event_base) {
> +             case RRScreenChangeNotify:
> +                     update_screen(dpy, root);
> +                     break;
> +             }
> +             xerror_restore();
> +     }
> +}
> +
> +static void usage(void)
> +{
> +     fprintf(stderr, "usage: %s [options]\n", progname);
> +     fprintf(stderr, "  options\n");
> +     fprintf(stderr, "  -d display  set X display name\n");
> +     fprintf(stderr, "  -l name     xrandr output name for laptop 
> display\n");
> +     fprintf(stderr, "  -v          verbose mode\n");
> +}
> +
> +int main(int argc, char **argv)
> +{
> +     Display *dpy;
> +     Window root;
> +     const char *display_name = NULL;
> +     const char *device_name;
> +     int c;
> +
> +     while ((c = getopt(argc, argv, "d:l:v")) != -1) {
> +             switch (c) {
> +             case 'd':
> +                     display_name = optarg;
> +                     break;
> +             case 'l':
> +                     laptop_name = optarg;
> +                     break;
> +             case 'v':
> +                     verbose++;
> +                     break;
> +             default:
> +                     usage();
> +                     return 1;
> +             }
> +     }
> +
> +     device_name = argv[optind];
> +
> +     dpy = XOpenDisplay(display_name);
> +     if (!dpy) {
> +             perror("open display");
> +             return 1;
> +     }
> +
> +     root = DefaultRootWindow(dpy);
> +     update_screen(dpy, root);
> +     synxrr_daemon(dpy, root);
> +
> +     return 0;
> +}
> -- 
> 1.7.3.1
> 
_______________________________________________
[email protected]: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: http://lists.x.org/mailman/listinfo/xorg-devel

Reply via email to