Start adding XRandR support. not really functional yet though.

(missing the code to compute the calibration data that restrict events
to a given output)
This commit is contained in:
matthieu 2010-01-22 07:47:54 +00:00
parent 09d4825f0e
commit 7d573b6e6c
3 changed files with 145 additions and 23 deletions

View File

@ -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 <bsd.xconf.mk>
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

View File

@ -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 <robert@openbsd.org>
.\" Copyright (c) 2009 Matthieu Herrb <matthieu@herrb.eu>
@ -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 ,

View File

@ -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 <robert@openbsd.org>
* Copyright (c) 2009 Matthieu Herrb <matthieu@herrb.eu>
@ -54,9 +54,12 @@
#include <X11/extensions/Xrender.h>
#include <X11/extensions/XInput.h>
#include <X11/extensions/Xrandr.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <math.h>
#include <ws-properties.h>
@ -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);