Ah,merci pour cette optimisation. J'ai pas testé car j'essaie de voir comment je pourrai forcer le refresh des données de calibration.
Je post le fichier C pour faciliter sa consultation
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <inttypes.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include "firemake.h"
struct device {
XID id;
Window win;
GC gc;
char *calibration_file;
uint_least32_t minX;
uint_least32_t minY;
uint_least32_t maxX;
uint_least32_t maxY;
enum {
TABLET,
TOUCHSCREEN
} type;
struct device *next;
} *device_head = NULL;
Window create_window(Display* display, int screen_num, int width, int height, int x, int y);
GC create_gc(Display* display, Window win, int screen_num);
void target(Display *display, Window win, GC gc, int screen_num, unsigned int cx, unsigned int cy);
void get_devices(Display *display, int screenX, int screenY);
struct device *choose_device(Display *display, int screen_num);
void write_point(Display *display, Window win, XDevice *devptr, FILE *calfile, int Bx, int By, int x, int y);
void cal_tablet(Display *display, Window win, GC gc, int screen_num, XDevice *devhandle, FILE *calfile, int x, int y, int width, int height);
void cal_touchscreen(Display *display, Window win, GC gc, int screen_num, XDevice *devhandle, FILE *calfile, int x, int y, int width, int height);
Window create_window(Display* display, int screen_num, int width, int height, int x, int y) {
Window win;
XSetWindowAttributes attributes;
win = XCreateSimpleWindow(display, RootWindow(display, screen_num),
x, y, width, height, 0,
BlackPixel(display, screen_num),
WhitePixel(display, screen_num));
attributes.override_redirect = True;
XChangeWindowAttributes(display, win, CWOverrideRedirect, &attributes);
XMapWindow(display, win);
return win;
}
GC create_gc(Display* display, Window win, int screen_num) {
GC gc;
unsigned long valuemask = 0;
XGCValues values;
unsigned int line_width = 1;
int line_style = LineSolid;
int cap_style = CapButt;
int join_style = JoinBevel;
gc = XCreateGC(display, win, valuemask, &values);
XSetBackground(display, gc, WhitePixel(display, screen_num));
XSetFillStyle(display, gc, FillSolid);
XSetLineAttributes(display, gc, line_width, line_style, cap_style, join_style);
return gc;
}
void target(Display *display, Window win, GC gc, int screen_num, unsigned int cx, unsigned int cy) {
XSetForeground(display, gc, BlackPixel(display, screen_num));
XDrawLine(display, win, gc, cx - 25, cy, cx + 25, cy);
XDrawLine(display, win, gc, cx, cy - 25, cx, cy + 25);
XDrawArc(display, win, gc, cx - 25, cy - 25, 50, 50, 0, 360*64);
XFlush(display);
}
void get_devices(Display *display, int screenX, int screenY) {
int ndev;
XDeviceInfo *devlist;
int i;
devlist = XListInputDevices(display,&ndev);
for (i = 0; i < ndev; i++) {
XValuatorInfo *classptr;
int j;
struct device *old;
int good = 0;
if (devlist[i].use != IsXExtensionDevice)
continue;
if (strchr(devlist[i].name,'/') == NULL)
continue;
classptr = (XValuatorInfo *) devlist[i].inputclassinfo;
for (j = 0; j < devlist[i].num_classes; j++) {
if (classptr->class != ValuatorClass) {
char *skip = (char *) classptr;
skip += classptr->length;
classptr = (XValuatorInfo *) skip;
continue;
}
if (classptr->num_axes < 2 || classptr->mode != Absolute)
break;
good = 1;
break;
}
if (good == 0)
continue;
old = device_head;
device_head = malloc(sizeof(*device_head));
device_head->next = old;
device_head->id = devlist[i].id;
device_head->calibration_file = strchr(devlist[i].name,'/');
*device_head->calibration_file = '\0';
device_head->calibration_file++;
if (strcmp(devlist[i].name,XI_TABLET) == 0)
device_head->type = TABLET;
else if (strcmp(devlist[i].name,XI_TOUCHSCREEN) == 0)
device_head->type = TOUCHSCREEN;
else /* assume touchscreen when in doubt */
device_head->type = TOUCHSCREEN;
device_head->minX = classptr->axes[0].min_value;
device_head->maxX = classptr->axes[0].max_value;
device_head->minY = classptr->axes[1].min_value;
device_head->maxY = classptr->axes[1].max_value;
if (device_head->maxX == (unsigned int) -1)
device_head->maxX = screenX;
if (device_head->maxY == (unsigned int) -1)
device_head->maxY = screenY;
}
}
struct device *choose_device(Display *display, int screen_num) {
struct device *iter = device_head, *ret = NULL;
int done = 0;
while (iter != NULL) {
int width = iter->maxX - iter->minX + 1;
int height = iter->maxY - iter->minY + 1;
iter->win = create_window(display, screen_num, width, height, iter->minX, iter->minY);
iter->gc = create_gc(display, iter->win, screen_num);
target(display, iter->win, iter->gc, screen_num, width / 2, height / 2);
XSelectInput(display, iter->win, ButtonPressMask);
iter = iter->next;
}
while (done == 0) {
XEvent event;
XNextEvent(display, &event);
switch (event.type) {
case ButtonPress:
ret = device_head;
while (ret != NULL) {
if (ret->win == event.xbutton.window)
break;
ret = ret->next;
}
done = 1;
break;
}
}
iter = device_head;
while (iter != NULL) {
XDestroyWindow(display,iter->win);
iter = iter->next;
}
return ret;
}
void write_point(Display *display, Window win, XDevice *devptr, FILE *calfile, int Bx, int By, int x, int y) {
XSelectInput(display, win, ButtonPressMask);
int done = 0;
uint_least32_t Ax = 0, Ay = 0;
while (done == 0) {
int i;
XDeviceState *state;
XValuatorState *vstate;
XEvent event;
XNextEvent(display, &event);
switch (event.type) {
case ButtonPress:
state = XQueryDeviceState(display,devptr);
if (state == NULL) {
fprintf(stderr,"Unable to get device state\n");
exit(1);
}
vstate = (XValuatorState *) state->data;
for (i = 0; i < state->num_classes; i++) {
if (vstate->class != ValuatorClass) {
char *skip = (char *) vstate;
skip += vstate->length;
vstate = (XValuatorState *) skip;
continue;
}
Ax = vstate->valuators[0];
Ay = vstate->valuators[1];
break;
}
fprintf(calfile,"%u,%u,%d,%d\n",Ax,Ay,Bx+x,By+y);
done = 1;
break;
}
}
}
void cal_tablet(Display *display, Window win, GC gc, int screen_num, XDevice *devhandle, FILE *calfile, int x, int y, int width, int height) {
int i;
for (i = 0; i < 4; i++) {
int cx = 0, cy = 0, mx = 0, my = 0, ex = 0, ey = 0;
switch (i) {
case 0:
case 2:
cx = 0;
mx = 25;
ex = 50;
break;
case 1:
case 3:
cx = width;
mx = width-25;
ex = width-50;
break;
}
switch (i) {
case 0:
case 1:
cy = 0;
my = 25;
ey = 50;
break;
case 2:
case 3:
cy = height;
my = height-25;
ey = height-50;
break;
}
XDrawLine(display, win, gc, cx, cy, ex, ey);
XDrawLine(display, win, gc, mx, my, mx, ey);
XDrawLine(display, win, gc, mx, my, ex, my);
XFlush(display);
write_point(display, win, devhandle, calfile, 0, 0, cx, cy);
XClearWindow(display, win);
XSelectInput(display, win, 0);
XSync(display, False);
sleep(1);
}
}
void cal_touchscreen(Display *display, Window win, GC gc, int screen_num, XDevice *devhandle, FILE *calfile, int x, int y, int width, int height) {
int i;
for (i = 0; i < 13; i++) {
int cx = 0,cy = 0;
switch (i) {
case 0:
case 5:
case 10:
cx = 50;
break;
case 1:
case 6:
case 11:
cx = width / 2;
break;
case 2:
case 7:
case 12:
cx = width - 50;
break;
case 3:
case 8:
cx = (width / 4) + 25;
break;
case 4:
case 9:
cx = width - (width / 4) - 25;
break;
}
switch (i) {
case 0:
case 1:
case 2:
cy = 50;
break;
case 3:
case 4:
cy = (height / 4) + 25;
break;
case 5:
case 6:
case 7:
cy = height / 2;
break;
case 8:
case 9:
cy = height - (height / 4) - 25;
break;
case 10:
case 11:
case 12:
cy = height - 50;
break;
}
target(display, win, gc, screen_num, cx, cy);
write_point(display, win, devhandle, calfile, cx, cy, x, y);
XClearWindow(display, win);
XSelectInput(display, win, 0);
XSync(display, False);
sleep(1);
}
}
int main(int argc, char *argv[]) {
Display* display;
int screen_num;
Window win;
unsigned int x, y;
unsigned int width, height;
char *display_name = getenv("DISPLAY");
struct device *devptr;
XDevice *devhandle;
FILE *calfile;
char tempcal[256];
GC gc;
/* open connection with the X server. */
display = XOpenDisplay(display_name);
if (display == NULL) {
fprintf(stderr,"%s: cannot connect to X server '%s'\n", argv[0], display_name);
exit(1);
}
/* get the geometry of the default screen for our display. */
screen_num = DefaultScreen(display);
get_devices(display,DisplayWidth(display,screen_num),DisplayHeight(display,screen_num));
if (device_head == NULL) {
fprintf(stderr,"No compatible devices found\n");
exit(1);
}
if (device_head->next == NULL)
devptr = device_head;
else
devptr = choose_device(display, screen_num);
if (devptr == NULL) {
fprintf(stderr,"Error choosing device\n");
exit(1);
}
snprintf(tempcal,256,"%s.tmp",devptr->calibration_file);
calfile = fopen(tempcal,"w");
if (calfile == NULL) {
perror("fopen");
exit(1);
}
x = devptr->minX;
y = devptr->minY;
width = devptr->maxX - devptr->minX + 1;
height = devptr->maxY - devptr->minY + 1;
devhandle = XOpenDevice(display,devptr->id);
if (devhandle == NULL) {
fprintf(stderr,"Unable to open X input device\n");
exit(1);
}
win = create_window(display, screen_num, width, height, x, y);
/* allocate a new GC (graphics context) for drawing in the window. */
gc = create_gc(display, win, screen_num);
XSync(display, False);
if (devptr->type == TOUCHSCREEN)
cal_touchscreen(display,win,gc,screen_num,devhandle,calfile,x,y,width,height);
else if (devptr->type == TABLET)
cal_tablet(display,win,gc,screen_num,devhandle,calfile,x,y,width,height);
fclose(calfile);
if (rename(tempcal,devptr->calibration_file) != 0) {
perror("rename");
exit(1);
}
/* bad hack to cause reload */
XSetDeviceMode(display, devhandle, 3);
XCloseDisplay(display);
return 0;
}
Ce serai pas cette partie qui refresh les donnees ?
XSetDeviceMode(display, devhandle, 3);
XCloseDisplay(display);