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
