diff --git a/app/xtsscale/Makefile b/app/xtsscale/Makefile index 2d8bb9d88..4d37e3fa4 100644 --- a/app/xtsscale/Makefile +++ b/app/xtsscale/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.8 2009/12/07 21:21:02 matthieu Exp $ +# $OpenBSD: Makefile,v 1.9 2010/01/22 07:47:54 matthieu Exp $ .include PROG= xtsscale @@ -10,7 +10,7 @@ LIBXCB= -lxcb CPPFLAGS+= -I${X11BASE}/include -I${X11BASE}/include/freetype2 \ -I${.CURDIR}/../../driver/xf86-input-ws/include -LDADD+= -L${X11BASE}/lib -lXft -lXi -lXrender -lXext -lX11 \ +LDADD+= -L${X11BASE}/lib -lXft -lXi -lXrender -lXrandr -lXext -lX11 \ ${LIBXCB} -lXau -lXdmcp -lfontconfig -lexpat -lfreetype -lz CFLAGS+= -Wall diff --git a/app/xtsscale/xtsscale.1 b/app/xtsscale/xtsscale.1 index 66d80e43d..418b367cd 100644 --- a/app/xtsscale/xtsscale.1 +++ b/app/xtsscale/xtsscale.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: xtsscale.1,v 1.7 2009/11/26 12:01:38 matthieu Exp $ +.\" $OpenBSD: xtsscale.1,v 1.8 2010/01/22 07:47:54 matthieu Exp $ .\" .\" Copyright (c) 2007 Robert Nagy .\" Copyright (c) 2009 Matthieu Herrb @@ -24,7 +24,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE .\" OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: November 26 2009 $ +.Dd $Mdocdate: January 22 2010 $ .Dt XTSSCALE 1 .Os .Sh NAME @@ -33,15 +33,18 @@ .Sh SYNOPSIS .Nm xtsscale .Bk -words -.Op Ar device +.Op Fl d Ar device +.Op Fl o Ar output .Ek .Sh DESCRIPTION .Nm is used interactively to calculate both the scaling and offset values which will make the pointer act at the indicated location on the screen. .Pp -.Ar device -is the name or numerical identifier of the X Input extension device +The following options can be used: +.Bl -tag -width Ds +.It Fl d Ar device +defines the name or numerical identifier of the X Input extension device to calibrate. Use .Pp @@ -50,6 +53,18 @@ Use to figure out the actual name for the X configuration. .Ar device can be omitted if there is only one X extension pointer in the system. +.It Fl o Ar output +specifies the XRandR output to with the touch screen is connected. +If omitted +.Nm +will use all heads in multi-head configurations, which is probably +not what is expected. +Use +.Pp +.Dl # xrandr +.Pp +to figure out the names of the outputs. +.El .Pp When good deviations are calculated from the selections made at these points, @@ -81,7 +96,7 @@ that is not the first device. ( ) .Sh SEE ALSO .Xr xinput 1 , -.Xr ioctl 2 , +.Xr xrandr 1 , .Xr uts 4 , .Xr wscons 4 , .Xr ws 4 , diff --git a/app/xtsscale/xtsscale.c b/app/xtsscale/xtsscale.c index 4166b04de..9283deaca 100644 --- a/app/xtsscale/xtsscale.c +++ b/app/xtsscale/xtsscale.c @@ -1,4 +1,4 @@ -/* $OpenBSD: xtsscale.c,v 1.13 2009/11/26 18:13:47 matthieu Exp $ */ +/* $OpenBSD: xtsscale.c,v 1.14 2010/01/22 07:47:54 matthieu Exp $ */ /* * Copyright (c) 2007 Robert Nagy * Copyright (c) 2009 Matthieu Herrb @@ -54,9 +54,12 @@ #include #include +#include + #include #include #include +#include #include #include @@ -77,6 +80,11 @@ static int button_release_type = INVALID_EVENT_TYPE; static int proximity_in_type = INVALID_EVENT_TYPE; static int proximity_out_type = INVALID_EVENT_TYPE; +int has_xrandr = False; +int has_xrandr_1_2 = False; +int has_xrandr_1_3 = False; +int has_xinerama = False; + Atom prop_calibration, prop_swap; /* where the calibration points are placed */ @@ -95,13 +103,15 @@ Window win; XftFont *font; XftColor cross, errorColor, promptColor, bg; XftDraw *draw; -unsigned int width, height; /* window size */ +unsigned int xpos, ypos, width, height; /* window size */ char *progname; Bool interrupted = False; int cx[5], cy[5]; int x[5], y[5]; +extern char * __progname; + struct { int minx, maxx, miny, maxy, swapxy, resx, resy; } calib, old_calib; Bool old_swap; @@ -459,11 +469,67 @@ uncalibrate(XDevice *device) return 0; } +void +get_xrandr_config(Display *dpy, Window root, char *name, + int *x, int *y, int *width, int *height) +{ + XRRScreenResources *res; + XRROutputInfo *output_info; + XRRCrtcInfo *crtc_info; + int o, found = 0; + + res = XRRGetScreenResources(dpy, root); + + for (o = 0; o < res->noutput; o++) { + output_info = XRRGetOutputInfo (dpy, res, res->outputs[o]); + if (!output_info) { + fprintf(stderr, + "could not get output 0x%lx information\n", + res->outputs[o]); + exit(2); + } + if (output_info->crtc != 0) { + crtc_info = XRRGetCrtcInfo(dpy, res, + output_info->crtc); + if (!crtc_info) { + fprintf(stderr, + "%s: could not get crtc 0x%lx " + "information\n", __progname, + output_info->crtc); + exit(2); + } + printf("%s: %dx%d+%d+%d\n", + output_info->name, + crtc_info->width, crtc_info->height, + crtc_info->x, crtc_info->y); + if (!strcmp(output_info->name, name)) { + *x = crtc_info->x; + *y = crtc_info->y; + *width = crtc_info->width; + *height = crtc_info->height; + found = 1; + } + } + } + if (!found) { + fprintf(stderr, "%s: output %s not found\n", __progname, name); + exit(2); + } +} + +void __dead +usage(void) +{ + fprintf(stderr, "usage: xtsscale [-d device][-o output]\n"); + exit(2); +} + int main(int argc, char *argv[], char *env[]) { char *display_name = NULL; char *device_name = NULL; + char *output_name = NULL; XSetWindowAttributes xswa; int i = 0; double a, a1, a2, b, b1, b2, xerr, yerr; @@ -473,17 +539,30 @@ main(int argc, char *argv[], char *env[]) XDevice *device; long calib_data[4]; unsigned char swap; + int ch; /* Crosshair placement */ int cpx[] = { 0, 0, 1, 1, 1 }; int cpy[] = { 0, 1, 0, 0, 1 }; - if (argc != 1 && argc != 2) { - fprintf(stderr, "usage: %s [device]\n", argv[0]); - return 1; + while ((ch = getopt(argc, argv, "d:o:")) != -1) { + switch (ch) { + case 'd': + device_name = optarg; + break; + case 'o': + output_name = optarg; + break; + default: + usage(); + /* NOTREACHED */ + } } - if (argc == 2) - device_name = argv[1]; + argc -= optind; + argv += optind; + + if (argc != 0) + usage(); /* connect to X server */ if ((display = XOpenDisplay(display_name)) == NULL) { @@ -491,6 +570,41 @@ main(int argc, char *argv[], char *env[]) argv[0], XDisplayName(display_name)); exit(1); } + screen = DefaultScreen(display); + root = RootWindow(display, screen); + + /* get screen size from display structure macro */ + xpos = 0; + ypos = 0; + width = DisplayWidth(display, screen); + height = DisplayHeight(display, screen); + + if (XRRQueryExtension(display, &event, &error)) { + int major, minor; + + if (XRRQueryVersion(display, &major, &minor) != True) { + fprintf(stderr, "Error querying XRandR version"); + } else { + printf("XRandR extension version %d.%d present\n", + major, minor); + has_xrandr = True; + if (major > 1 || (major == 1 && minor >=2)) + has_xrandr_1_2 = True; + if (major > 1 || (major == 1 && minor >=3)) + has_xrandr_1_3 = True; + } + } + + if (output_name != NULL) { + if (has_xrandr_1_2) { + get_xrandr_config(display, root, output_name, + &xpos, &ypos, &width, &height); + } else { + fprintf(stderr, "%s: can not specify an output " + "whithout XRandr 1.2 or later", __progname); + exit(2); + } + } if (!XQueryExtension(display, INAME, &xi_opcode, &event, &error)) { fprintf(stderr, "%s: X Input extension not available.\n", @@ -526,21 +640,14 @@ main(int argc, char *argv[], char *env[]) exit(1); } - screen = DefaultScreen(display); - root = RootWindow(display, screen); - /* setup window attributes */ xswa.override_redirect = True; xswa.background_pixel = BlackPixel(display, screen); xswa.event_mask = ExposureMask | KeyPressMask; xswa.cursor = create_empty_cursor(); - /* get screen size from display structure macro */ - width = DisplayWidth(display, screen); - height = DisplayHeight(display, screen); - win = XCreateWindow(display, RootWindow(display, screen), - 0, 0, width, height, 0, + xpos, ypos, width, height, 0, CopyFromParent, InputOutput, CopyFromParent, CWOverrideRedirect | CWBackPixel | CWEventMask | CWCursor, &xswa);