コード例 #1
0
/**
 * Toggle touchpad enabled/disabled state, decided by value.
 */
static void
toggle_touchpad(Bool enable)
{
    unsigned char data;

    if (pad_disabled && enable) {
        data = previous_state;
        pad_disabled = False;
        if (verbose)
            printf("Enable\n");
    }
    else if (!pad_disabled && !enable &&
             previous_state != disable_state && previous_state != TouchpadOff) {
        store_current_touchpad_state();
        pad_disabled = True;
        data = disable_state;
        if (verbose)
            printf("Disable\n");
    }
    else
        return;

    /* This potentially overwrites a different client's setting, but ... */
    XChangeDeviceProperty(display, dev, touchpad_off_prop, XA_INTEGER, 8,
                          PropModeReplace, &data, 1);
    XFlush(display);
}
コード例 #2
0
void synaptics_disable_3fingers_tap(Grabber* self, XDevice* dev) {
	Atom prop, type;
	double val;
	int format;
	unsigned long nitems, bytes_after;
	unsigned char* data = NULL;
	prop = XInternAtom(self->dpy, SYNAPTICS_PROP_TAP_ACTION, True);

	/* get current configuration */

	XGetDeviceProperty(self->dpy, dev, prop, 0, 1000, False, AnyPropertyType,
			&type, &format, &nitems, &bytes_after, &data);
	char* b = (char*) data;
	int offset = 6; // the position of 3TAP_FINGER inside config

	/* change configuration if needed */

	if (b[offset] != 0) {
		b[offset] = 0;//rint(val);

		XChangeDeviceProperty(self->dpy, dev, prop, type, format,
						PropModeReplace, data, nitems);
			XFlush(self->dpy);
	}
}
コード例 #3
0
ファイル: xtsscale.c プロジェクト: Bluerise/bitrig-xenocara
int
uncalibrate(XDevice *device)
{
	Atom type;
	int format;
	unsigned long nitems, nbytes;
	long values[4] = { 0, 32767, 0, 32767 }; /* uncalibrated */
	Bool swap = 0;
	unsigned char *retval;

	/* Save old values */
	XGetDeviceProperty(display, device, prop_calibration, 0,
	    4, False, XA_INTEGER, &type, &format, &nitems,
	    &nbytes, &retval);

	if (type != XA_INTEGER) {
		fprintf(stderr, "Device property \"%s\": invalid type %s\n",
		    WS_PROP_CALIBRATION, XGetAtomName(display, type));
		return -1;
	}
	if (nitems != 4 && nitems != 0) {
		fprintf(stderr, "Device property \"%s\": "
		    "invalid number of items %ld\n",
		    WS_PROP_CALIBRATION, nitems);
		return -1;
	}
	old_calib.minx = *(long *)retval;
	old_calib.maxx = *((long *)retval + 1);
	old_calib.miny = *((long *)retval + 2);
	old_calib.maxy = *((long *)retval + 3);

	XFree(retval);

	XGetDeviceProperty(display, device, prop_swap, 0,
	    1, False, XA_INTEGER, &type, &format, &nitems,
	    &nbytes, &retval);
	old_swap = *(Bool *)retval;
	XFree(retval);

	/* Force uncalibrated state */
	XChangeDeviceProperty(display, device, prop_calibration,
	    XA_INTEGER, 32, PropModeReplace, (unsigned char *)values, 4);
	XChangeDeviceProperty(display, device, prop_swap,
	    XA_INTEGER, 8, PropModeReplace, (unsigned char *)&swap, 1);

	return 0;
}
コード例 #4
0
gboolean
device_set_property (XDevice        *xdevice,
                     const char     *device_name,
                     PropertyHelper *property)
{
    int rc, i;
    Atom prop;
    Atom realtype;
    int realformat;
    unsigned long nitems, bytes_after;
    unsigned char *data;

    prop = XInternAtom (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
                        property->name, False);
    if (!prop)
        return FALSE;

    gdk_error_trap_push ();

    rc = XGetDeviceProperty (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
                             xdevice, prop, 0, property->nitems, False,
                             AnyPropertyType, &realtype, &realformat, &nitems,
                             &bytes_after, &data);

    if (rc != Success ||
            realtype != property->type ||
            realformat != property->format ||
            nitems < property->nitems) {
        gdk_error_trap_pop_ignored ();
        g_warning ("Error reading property \"%s\" for \"%s\"", property->name, device_name);
        return FALSE;
    }

    for (i = 0; i < nitems; i++) {
        switch (property->format) {
        case 8:
            data[i] = property->data.c[i];
            break;
        case 32:
            ((long*)data)[i] = property->data.i[i];
            break;
        }
    }

    XChangeDeviceProperty (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
                           xdevice, prop, realtype, realformat,
                           PropModeReplace, data, nitems);

    XFree (data);

    if (gdk_error_trap_pop ()) {
        g_warning ("Error in setting \"%s\" for \"%s\"", property->name, device_name);
        return FALSE;
    }

    return TRUE;
}
コード例 #5
0
ファイル: xtsscale.c プロジェクト: Bluerise/bitrig-xenocara
void
cleanup_exit(XDevice *device)
{
	long values[4];

	values[0] = old_calib.minx;
	values[1] = old_calib.maxx;
	values[2] = old_calib.miny;
	values[3] = old_calib.maxy;

	XChangeDeviceProperty(display, device, prop_calibration,
	    XA_INTEGER, 32, PropModeReplace, (unsigned char *)values, 4);

	XChangeDeviceProperty(display, device, prop_swap,
	    XA_INTEGER, 8, PropModeReplace, (unsigned char *)&old_swap, 1);

	XCloseDevice(display, device);
	XUngrabServer(display);
	XUngrabKeyboard(display, CurrentTime);
	XCloseDisplay(display);
	exit(1);
}
コード例 #6
0
ファイル: XInputHelper.cpp プロジェクト: INRIA/libpointing
  void executeCommand(Display	*dpy, XDeviceInfo *info, const char *command, unsigned char data)
  {
    if (!info)
    {
      fprintf(stderr, "unable to find the device\n");
      return;
    }

    XDevice *dev = XOpenDevice(dpy, info->id);
    if (!dev)
    {
      fprintf(stderr, "unable to open the device\n");
      return;
    }

    Atom prop = XInternAtom(dpy, command, False);

    XChangeDeviceProperty(dpy, dev, prop, XA_INTEGER, 8, PropModeReplace,
                          &data, 1);

    XCloseDevice(dpy, dev);
  }
コード例 #7
0
ファイル: xtsscale.c プロジェクト: Bluerise/bitrig-xenocara
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;
	int		xi_opcode, event, error;
	XExtensionVersion *version;
	XDeviceInfo	*info;
	XDevice		*device;
	long		 calib_data[4];
	unsigned long	 mask;
	unsigned char	 swap;
	int 		 keep_cursor = 0, ch;

	/* Crosshair placement */
	int		cpx[] = { 0, 0, 1, 1, 1 };
	int		cpy[] = { 0, 1, 0, 0, 1 };

	while ((ch = getopt(argc, argv, "cD:d:o:v")) != -1) {
		switch (ch) {
		case 'c':
			keep_cursor++;
			break;
		case 'D':
			display_name = optarg;
			break;
		case 'd':
			device_name = optarg;
			break;
		case 'o':
			output_name = optarg;
			break;
		case 'v':
			verbose = True;
			break;
		default:
			usage();
			/* NOTREACHED */
		}
	}
	argc -= optind;
	argv += optind;

	if (argc != 0)
		usage();

	/* connect to X server */
	if ((display = XOpenDisplay(display_name)) == NULL) {
		fprintf(stderr, "%s: cannot connect to X server %s\n",
		    __progname, 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",
		    __progname);
		exit(1);
	}

	version = XGetExtensionVersion(display, INAME);
	if (version == NULL ||
	    version == (XExtensionVersion *)NoSuchExtension) {
		fprintf(stderr, "Cannot query X Input version.\n");
		exit(1);
	}
	XFree(version);
	prop_calibration = XInternAtom(display, WS_PROP_CALIBRATION, True);
	if (prop_calibration == None) {
		fprintf(stderr, "Unable to find the \"%s\" device property.\n"
		    "There are probably no calibrable devices "
		    "on this system.\n", WS_PROP_CALIBRATION);
		exit(1);
	}
	prop_swap = XInternAtom(display, WS_PROP_SWAP_AXES, True);
	if (prop_swap == None) {
		fprintf(stderr, "Unable to find the \"%s\" device property\n",
		    WS_PROP_SWAP_AXES);
		exit(1);
	}
	info = find_device_info(device_name);
	if (info == NULL) {
		fprintf(stderr, "Unable to find the %s device\n",
			device_name ? device_name : "default");
		exit(1);
	}


	/* setup window attributes */
	xswa.override_redirect = True;
	xswa.background_pixel = BlackPixel(display, screen);
	xswa.event_mask = ExposureMask | KeyPressMask;
	mask = CWOverrideRedirect | CWBackPixel | CWEventMask;
	if (!keep_cursor) {
		xswa.cursor = create_empty_cursor();
		mask |= CWCursor;
	}
	win = XCreateWindow(display, RootWindow(display, screen),
			    xpos, ypos, width, height, 0,
			    CopyFromParent, InputOutput, CopyFromParent,
			    mask, &xswa);
	render_init();
	XMapWindow(display, win);
	XGrabKeyboard(display, win, False, GrabModeAsync, GrabModeAsync,
		      CurrentTime);
	XGrabServer(display);

	XClearWindow(display, win);

	if (verbose)
		printf("Calibrating %s\n", info->name);
	device = XOpenDevice(display, info->id);
	if (!device) {
		fprintf(stderr, "Unable to open the X input device \"%s\"\n",
		    info->name);
		return 0;
	}

	if (!register_events(info, device, 0))
		exit(1);

	uncalibrate(device);
calib:
	XftDrawRect(draw, &bg, 0, 0, width, height);

	for (i = 0; i < 5; i++) {
		draw_graphics(cpx[i], cpy[i], i);
		XFlush(display);
		if (!get_events(i))
			break;
		XftDrawRect(draw, &bg, 0, 0, width, height);
	}
	if (interrupted)
		cleanup_exit(device);

	/* Check if  X and Y should be swapped */
	if (fabs(x[0] - x[1]) > fabs(y[0] - y[1])) {

		calib.swapxy = 1;

		for (i = 0; i < 5; i++) {
			int t = x[i];
			x[i] = y[i];
			y[i] = t;
		}
	}

	/* get touch pad resolution to screen resolution ratio */
	a1 = (double) (x[4] - x[0]) / (double) (cx[4] - cx[0]);
	a2 = (double) (x[3] - x[1]) / (double) (cx[3] - cx[1]);
	/* get the minimum pad position on the X-axis */
	b1 = x[0] - a1 * cx[0];
	b2 = x[1] - a2 * cx[1];
	/* use the average ratio and average minimum position */
	a = (a1 + a2) / 2.0;
	b = (b1 + b2) / 2.0;
	xerr = a * width / 2 + b - x[2];
	if (fabs(xerr) > fabs(a * width * .01)) {
		fprintf(stderr, "Calibration problem: X axis error (%.2f) too high, try again\n",
			fabs(xerr));
		goto err;
	}
	calib.minx = (int) (b + 0.5);
	calib.maxx = (int) (a * width + b + 0.5);

	/* get touch pad resolution to screen resolution ratio */
	a1 = (double) (y[4] - y[0]) / (double) (cy[4] - cy[0]);
	a2 = (double) (y[3] - y[1]) / (double) (cy[3] - cy[1]);
	/* get the minimum pad position on the Y-axis */
	b1 = y[0] - a1 * cy[0];
	b2 = y[1] - a2 * cy[1];
	/* use the average ratio and average minimum position */
	a = (a1 + a2) / 2.0;
	b = (b1 + b2) / 2.0;
	yerr = a * height / 2 + b - y[2];
	if (fabs(yerr) > fabs(a * height * 0.01)) {
		fprintf(stderr, "Calibration problem: Y axis error (%.2f) too high, try again\n",
			fabs(yerr));
		goto err;
	}
	calib.miny = (int) (b + 0.5);
	calib.maxy = (int) (a * height + b + 0.5);

	XFlush(display);

	calib.resx = width;
	calib.resy = height;

	/* Send new values to the X server */
	calib_data[0] = calib.minx;
	calib_data[1] = calib.maxx;
	calib_data[2] = calib.miny;
	calib_data[3] = calib.maxy;
	XChangeDeviceProperty(display, device, prop_calibration,
	    XA_INTEGER, 32, PropModeReplace, (unsigned char *)calib_data, 4);

	swap = calib.swapxy;
	XChangeDeviceProperty(display, device, prop_swap,
	    XA_INTEGER, 8, PropModeReplace, (unsigned char *)&swap, 1);

	XCloseDevice(display, device);

	XCloseDisplay(display);

	/* And print them for storage in wsconsctl.conf */
	printf("mouse.scale=%d,%d,%d,%d,%d,%d,%d\n",
	    calib.minx, calib.maxx,
	    calib.miny, calib.maxy,
	    calib.swapxy,
	    calib.resx, calib.resy);

	return 0;
err:
	draw_text(error_message, &errorColor);
	XFlush(display);
	sleep(2);
	goto calib;
}
コード例 #8
0
static void
dp_set_variables(Display *dpy, XDevice* dev, int argc, char *argv[], int first_cmd)
{
    int i;
    double val;
    struct Parameter *par;
    Atom prop, type, float_type;
    int format;
    unsigned char* data;
    unsigned long nitems, bytes_after;

    union flong *f;
    long *n;
    char *b;

    float_type = XInternAtom(dpy, XATOM_FLOAT, True);
    if (!float_type)
	fprintf(stderr, "Float properties not available.\n");

    for (i = first_cmd; i < argc; i++) {
	val = parse_cmd(argv[i], &par);
	if (!par)
	    continue;

	prop = XInternAtom(dpy, par->prop_name, True);
	if (!prop)
	{
	    fprintf(stderr, "Property for '%s' not available. Skipping.\n",
		    par->name);
	    continue;

	}

	XGetDeviceProperty(dpy, dev, prop, 0, 1000, False, AnyPropertyType,
				&type, &format, &nitems, &bytes_after, &data);

	switch(par->prop_format)
	{
	    case 8:
		if (format != par->prop_format || type != XA_INTEGER) {
		    fprintf(stderr, "   %-23s = format mismatch (%d)\n",
			    par->name, format);
		    break;
		}
		b = (char*)data;
		b[par->prop_offset] = rint(val);
		break;
	    case 32:
		if (format != par->prop_format || type != XA_INTEGER) {
		    fprintf(stderr, "   %-23s = format mismatch (%d)\n",
			    par->name, format);
		    break;
		}
		n = (long*)data;
		n[par->prop_offset] = rint(val);
		break;
	    case 0: /* float */
		if (!float_type)
		    continue;
		if (format != 32 || type != float_type) {
		    fprintf(stderr, "   %-23s = format mismatch (%d)\n",
			    par->name, format);
		    break;
		}
		f = (union flong*)data;
		f[par->prop_offset].f = val;
		break;
	}

	XChangeDeviceProperty(dpy, dev, prop, type, format,
				PropModeReplace, data, nitems);
	XFlush(dpy);
    }
}
コード例 #9
0
ファイル: Evdev.cpp プロジェクト: SICOM/xinput_calibrator-1
// Set Integer property on  X
bool CalibratorEvdev::xinput_do_set_int_prop( const char * name,
                                         Display *display,
                                         int format,
                                         int argc,
                                         const int *argv )
{
#ifndef HAVE_XI_PROP
    return false;
#else

    Atom          prop;
    Atom          old_type;
    int           i;
    int           old_format;
    unsigned long act_nitems, bytes_after;

    union {
        unsigned char *c;
        short *s;
        long *l;
        Atom *a;
    } data;

    if (argc < 1)
    {
        fprintf(stderr, "Wrong usage of xinput_do_set_prop, need at least 1 arguments\n");
        return false;
    }

    prop = xinput_parse_atom(display, name);

    if (prop == None) {
        fprintf(stderr, "invalid property %s\n", name);
        return false;
    }

    if ( format == 0) {
        if (XGetDeviceProperty(display, dev, prop, 0, 0, False, AnyPropertyType,
                               &old_type, &old_format, &act_nitems,
                               &bytes_after, &data.c) != Success) {
            fprintf(stderr, "failed to get property type and format for %s\n",
                    name);
            return false;
        } else {
            format = old_format;
        }

        XFree(data.c);
    }

    data.c = (unsigned char*)calloc(argc, sizeof(long));

    for (i = 0; i < argc; i++) {
      switch (format) {
        case 8:
            data.c[i] = argv[i];
        case 16:
            data.s[i] = argv[i];
            break;
        case 32:
            data.l[i] = argv[i];
            break;

        default:
            fprintf(stderr, "unexpected size for property %s\n", name);
            return false;
      }
    }

    XChangeDeviceProperty(display, dev, prop, XA_INTEGER, format, PropModeReplace,
                      data.c, argc);
    free(data.c);
    return true;
#endif // HAVE_XI_PROP

}
コード例 #10
0
ファイル: property.c プロジェクト: aosm/X11apps
static int
do_set_prop_xi1(Display *dpy, Atom type, int format, int argc, char **argv, char *n, char *desc)
{
    XDeviceInfo  *info;
    XDevice      *dev;
    Atom          prop;
    Atom          old_type;
    char         *name;
    int           i;
    Atom          float_atom;
    int           old_format, nelements = 0;
    unsigned long act_nitems, bytes_after;
    char         *endptr;
    union {
        unsigned char *c;
        short *s;
        long *l;
        Atom *a;
    } data;

    if (argc < 3)
    {
        fprintf(stderr, "Usage: xinput %s %s\n", n, desc);
        return EXIT_FAILURE;
    }

    info = find_device_info(dpy, argv[0], False);
    if (!info)
    {
        fprintf(stderr, "unable to find device %s\n", argv[0]);
        return EXIT_FAILURE;
    }

    dev = XOpenDevice(dpy, info->id);
    if (!dev)
    {
        fprintf(stderr, "unable to open device %s\n", argv[0]);
        return EXIT_FAILURE;
    }

    name = argv[1];

    prop = parse_atom(dpy, name);

    if (prop == None) {
        fprintf(stderr, "invalid property %s\n", name);
        return EXIT_FAILURE;
    }

    float_atom = XInternAtom(dpy, "FLOAT", False);

    nelements = argc - 2;
    if (type == None || format == 0) {
        if (XGetDeviceProperty(dpy, dev, prop, 0, 0, False, AnyPropertyType,
                               &old_type, &old_format, &act_nitems,
                               &bytes_after, &data.c) != Success) {
            fprintf(stderr, "failed to get property type and format for %s\n",
                    name);
            return EXIT_FAILURE;
        } else {
            if (type == None)
                type = old_type;
            if (format == 0)
                format = old_format;
        }

        XFree(data.c);
    }

    if (type == None) {
        fprintf(stderr, "property %s doesn't exist, you need to specify "
                "its type and format\n", name);
        return EXIT_FAILURE;
    }

    data.c = calloc(nelements, sizeof(long));

    for (i = 0; i < nelements; i++)
    {
        if (type == XA_INTEGER) {
            switch (format)
            {
                case 8:
                    data.c[i] = atoi(argv[2 + i]);
                    break;
                case 16:
                    data.s[i] = atoi(argv[2 + i]);
                    break;
                case 32:
                    data.l[i] = atoi(argv[2 + i]);
                    break;
                default:
                    fprintf(stderr, "unexpected size for property %s", name);
                    return EXIT_FAILURE;
            }
        } else if (type == float_atom) {
            if (format != 32) {
                fprintf(stderr, "unexpected format %d for property %s\n",
                        format, name);
                return EXIT_FAILURE;
            }
            *(float *)(data.l + i) = strtod(argv[2 + i], &endptr);
            if (endptr == argv[2 + i]) {
                fprintf(stderr, "argument %s could not be parsed\n", argv[2 + i]);
                return EXIT_FAILURE;
            }
        } else if (type == XA_ATOM) {
            if (format != 32) {
                fprintf(stderr, "unexpected format %d for property %s\n",
                        format, name);
                return EXIT_FAILURE;
            }
            data.a[i] = parse_atom(dpy, argv[2 + i]);
        } else {
            fprintf(stderr, "unexpected type for property %s\n", name);
            return EXIT_FAILURE;
        }
    }

    XChangeDeviceProperty(dpy, dev, prop, type, format, PropModeReplace,
                          data.c, nelements);
    free(data.c);
    XCloseDevice(dpy, dev);
    return EXIT_SUCCESS;
}
コード例 #11
0
void setCalibration(int id, int minX, int maxX, int minY, int maxY, int axesSwap, int screenWidth, int screenHeight, int outputX, int outputY, int outputWidth, int outputHeight, int rotation) {

    float matrix[] = { 1., 0., 0.,    /* [0] [1] [2] */
                       0., 1., 0.,    /* [3] [4] [5] */
                       0., 0., 1.
                     };  /* [6] [7] [8] */

    int matrixMode = 0;
    /* Check if transformation matrix is supported */
    long l;
    if((sizeof l) == 4 || (sizeof l) == 8) {
        /* We only support matrix mode on systems where longs are 32 or 64 bits long */
        Atom retType;
        int retFormat;
        unsigned long retItems, retBytesAfter;
        unsigned char * data = NULL;
        if(XIGetProperty(display, id, XInternAtom(display,
                         "Coordinate Transformation Matrix", 0), 0, 9 * 32, False, floatAtom,
                         &retType, &retFormat, &retItems, &retBytesAfter,
                         &data) != Success) {
            data = NULL;
        }
        if(data != NULL && retItems == 9) {
            matrixMode = 1;
        }
        if(data != NULL) {
            XFree(data);
        }
    }

    unsigned char flipHoriz = 0, flipVerti = 0;

    if(matrixMode) {

        if(debugMode) printf("Use matrix method\n");

        /* Output rotation */
        if(rotation & RR_Rotate_180) {
            matrix[0] = -1.;
            matrix[4] = -1;
            matrix[2] = 1.;
            matrix[5] = 1.;
        } else if(rotation & RR_Rotate_90) {
            matrix[0] = 0.;
            matrix[1] = -1.;
            matrix[3] = 1.;
            matrix[4] = 0.;

            matrix[2] = 1.;
        } else if(rotation & RR_Rotate_270) {
            matrix[0] = 0.;
            matrix[1] = 1.;
            matrix[3] = -1.;
            matrix[4] = 0.;

            matrix[5] = 1.;
        }

        /* Output Reflection */
        if(rotation & RR_Reflect_X) {
            matrix[0]*= -1.;
            matrix[1]*= -1.;
            matrix[2]*= -1.;
            matrix[2]+= 1.;
        }
        if(rotation & RR_Reflect_Y) {
            matrix[3]*= -1.;
            matrix[4]*= -1.;
            matrix[5]*= -1.;
            matrix[5]+= 1.;
        }

        /* Output Size */
        float widthRel = outputWidth / (float) screenWidth;
        float heightRel = outputHeight / (float) screenHeight;
        matrix[0] *= widthRel;
        matrix[1] *= widthRel;
        matrix[2] *= widthRel;
        matrix[3] *= heightRel;
        matrix[4] *= heightRel;
        matrix[5] *= heightRel;

        /* Output Position */
        matrix[2] += outputX / (float) screenWidth;
        matrix[5] += outputY / (float) screenHeight;

    } else {

        if(debugMode) printf("Use legacy method\n");

        /* No support for transformations, so use legacy method */

        if(rotation & RR_Rotate_180) {
            flipHoriz = !flipHoriz;
            flipVerti = !flipVerti;

        } else if(rotation & RR_Rotate_90) {
            flipVerti = !flipVerti;
            axesSwap = !axesSwap;
        } else if(rotation & RR_Rotate_270) {
            flipHoriz = !flipHoriz;
            axesSwap = !axesSwap;
        }

        /* Output Reflection */
        if(rotation & RR_Reflect_X) {
            flipHoriz = !flipHoriz;
        }
        if(rotation & RR_Reflect_Y) {
            flipVerti = !flipVerti;
        }


        if(axesSwap) {
            swap(&maxX, &maxY);
            swap(&minX, &minY);
        }

        int leftSpace, rightSpace, topSpace, bottomSpace;
        leftSpace = outputX;
        rightSpace = screenWidth - outputX - outputWidth;

        topSpace = outputY;
        bottomSpace = screenHeight - outputY - outputHeight;

        if(flipHoriz) swap(&leftSpace, &rightSpace);
        if(flipVerti) swap(&topSpace, &bottomSpace);

        float fctX = ((float) (maxX - minX)) / ((float) outputWidth);
        float fctY = ((float) (maxY - minY)) / ((float) outputHeight);
        minX = minX - (int) (leftSpace * fctX);
        maxX = maxX + (int) (rightSpace * fctX);
        minY = minY - (int) (topSpace * fctY);
        maxY = maxY + (int) (bottomSpace * fctY);

    }

    XDevice *dev = XOpenDevice(display, id);
    if(dev) {
        if(matrixMode) {
            if((sizeof l) == 4) {
                XChangeDeviceProperty(display, dev, XInternAtom(display,
                                      "Coordinate Transformation Matrix", 0), floatAtom, 32, PropModeReplace, (unsigned char*) matrix, 9);
            } else if((sizeof l) == 8) {
                /* Xlib needs the floats long-aligned, so let's align them. */
                float matrix2[] = { matrix[0], 0., matrix[1], 0., matrix[2], 0.,
                                    matrix[3], 0., matrix[4], 0., matrix[5], 0.,
                                    matrix[6], 0., matrix[7], 0., matrix[8], 0.
                                  };
                XChangeDeviceProperty(display, dev, XInternAtom(display,
                                      "Coordinate Transformation Matrix", 0), floatAtom, 32, PropModeReplace, (unsigned char*) matrix2, 9);
            }
        }

        long calib[] = { minX, maxX, minY, maxY };
        //TODO instead of long, use platform 32 bit type
        XChangeDeviceProperty(display, dev, XInternAtom(display,
                              "Evdev Axis Calibration", 0), XA_INTEGER, 32, PropModeReplace, (unsigned char*) calib, 4);

        unsigned char flipData[] = {flipHoriz, flipVerti};
        XChangeDeviceProperty(display, dev, XInternAtom(display,
                              "Evdev Axis Inversion", 0), XA_INTEGER, 8, PropModeReplace, flipData, 2);

        unsigned char cAxesSwap = (unsigned char) axesSwap;
        XChangeDeviceProperty(display, dev, XInternAtom(display,
                              "Evdev Axes Swap", 0), XA_INTEGER, 8, PropModeReplace, &cAxesSwap, 1);

        XCloseDevice(display, dev);
    }
}