/* wacom graphire on serial port only... */ #include #include "s_stuff.h" #include #include #include #include #include #include #define BUFSIZE 256 #define HEADER_BIT 0x80 #define ZAXIS_SIGN_BIT 0x40 #define ZAXIS_BIT 0x04 #define ZAXIS_BITS 0x3f #define POINTER_BIT 0x20 #define PROXIMITY_BIT 0x40 #define BUTTON_FLAG 0x08 #define BUTTONS_BITS 0x78 #define TILT_SIGN_BIT 0x40 #define TILT_BITS 0x3f /* defines to discriminate second side button and the eraser */ #define ERASER_PROX 4 #define OTHER_PROX 1 #define Threshold 1000 unsigned char data[7]; typedef struct _wac { t_object t_ob; t_outlet *axis_out; t_outlet *button_out; t_symbol *file; int fd; int count; int oldbuttons; unsigned char data[BUFSIZE]; }t_wac; t_class *wac_class; void wac_setup(void); static void wac_read(t_wac *x,int fd); static void wac_process(t_wac *x); static void wac_open(t_wac *x) { if(x->fd>=0) return; x->fd = open (x->file->s_name, O_RDONLY | O_NONBLOCK); if(x->fd<0){ post("open (%s, O_RDONLY | O_NONBLOCK)",x->file->s_name); perror("open"); return; } sys_addpollfn(x->fd,(t_fdpollfn)wac_read,(void*)x); } static void wac_close(t_wac *x) { if(x->fd<0) return; sys_rmpollfn(x->fd); close(x->fd); x->fd=-1; } static void wac_float(t_wac *x,t_floatarg connect) { if(connect!=0) wac_open(x); else wac_close(x); } static void *wac_new(t_symbol *file) { t_wac *x = (t_wac *)pd_new(wac_class); //if(file->s_name) if(file!=&s_) x->file=file; else x->file=gensym("/dev/ttyS0"); post("wac_new file=%s",x->file->s_name); x->axis_out = outlet_new(&x->t_ob, &s_list); x->button_out = outlet_new(&x->t_ob, &s_list); x->fd=-1; return (void *)x; } void wac_setup(void) { wac_class = class_new(gensym("wac"),(t_newmethod)wac_new, (t_method)wac_close, sizeof(t_wac), 0, A_DEFSYM, 0); class_addfloat(wac_class, wac_float); } static void wac_read(t_wac *x,int fd) { int len,i=0; unsigned char b; unsigned char buffer[BUFSIZE]; while((len=read(fd,buffer,BUFSIZE))> -1){ for(i=0;icount=0; x->data[x->count++]=buffer[i]; if(x->count==7) wac_process(x); } } } static void wac_process(t_wac *X) { int is_stylus = 1, is_button, is_proximity, wheel=0; int x, y, z, buttons, tx = 0, ty = 0; unsigned char *data=X->data; t_atom ats[3]; is_stylus = (data[0] & POINTER_BIT); if(!is_stylus) return; x = (((data[0] & 0x3) << 14) + (data[1] << 7) + data[2]); y = (((data[3] & 0x3) << 14) + (data[4] << 7) + data[5]); z = ((data[6] & ZAXIS_BITS) * 2) + ((data[3] & ZAXIS_BIT) >> 2); //z = z*4 + ((data[0] & ZAXIS_BIT) >> 1); if (!(data[6] & ZAXIS_SIGN_BIT)) { z += 128; } is_proximity = (data[0] & PROXIMITY_BIT); buttons = ((data[3] & 0x38) >> 3); /*if (is_stylus) { buttons = ((data[3] & 0x30) >> 3) | (z >= Threshold ? 1 : 0); } else { buttons = (data[3] & 0x38) >> 3; wheel = (data[6] & 0x30) >> 4; if (data[6] & 0x40) { wheel = -wheel; } }*/ //is_button = (buttons != 0); if(buttons!=X->oldbuttons) { X->oldbuttons=buttons; SETFLOAT(&ats[0],buttons&1); SETFLOAT(&ats[1],(buttons&2)!=0); SETFLOAT(&ats[2],(buttons&4)!=0); outlet_list(X->button_out,0,3,ats); } SETFLOAT(&ats[0],x/5103.0); SETFLOAT(&ats[1],y/3711.0); SETFLOAT(&ats[2],z/256.0); outlet_list(X->axis_out,0,3,ats); } /* Format of 7 bytes data packet for Wacom Tablets Byte 1 bit 7 Sync bit always 1 bit 6 Pointing device detected bit 5 Cursor = 0 / Stylus = 1 bit 4 Reserved bit 3 1 if a button on the pointing device has been pressed bit 2 Reserved bit 1 X15 bit 0 X14 Byte 2 bit 7 Always 0 bits 6-0 = X13 - X7 Byte 3 bit 7 Always 0 bits 6-0 = X6 - X0 Byte 4 bit 7 Always 0 bit 6 B3 bit 5 B2 bit 4 B1 bit 3 B0 bit 2 P0 bit 1 Y15 bit 0 Y14 Byte 5 bit 7 Always 0 bits 6-0 = Y13 - Y7 Byte 6 bit 7 Always 0 bits 6-0 = Y6 - Y0 Byte 7 bit 7 Always 0 bit 6 Sign of pressure data bit 5 P6 bit 4 P5 bit 3 P4 bit 2 P3 bit 1 P2 bit 0 P1 byte 8 and 9 are optional and present only in tilt mode. Byte 8 bit 7 Always 0 bit 6 Sign of tilt X bit 5 Xt6 bit 4 Xt5 bit 3 Xt4 bit 2 Xt3 bit 1 Xt2 bit 0 Xt1 Byte 9 bit 7 Always 0 bit 6 Sign of tilt Y bit 5 Yt6 bit 4 Yt5 bit 3 Yt4 bit 2 Yt3 bit 1 Yt2 bit 0 Yt1 */