📄 xf86dmc.c
字号:
#if 1 xf86Msg(X_WARNING, "DMC : DeviceControl ON\n"); #endif pInfo->fd = xf86OpenSerial(pInfo->options); if (pInfo->fd == -1) { xf86Msg(X_WARNING, "%s: cannot open input device\n", pInfo->name); return (!Success); } priv->fd = pInfo->fd; priv->buffer = XisbNew(pInfo->fd, 256); // 64->256 if (!priv->buffer) { xf86CloseSerial(pInfo->fd); pInfo->fd = -1; return (!Success); } else { priv->do_calib = 0; asleep(priv,1); /* touch need ca. 500ms delay !!! */ if( !tx_reset_goto_init(priv,true) ) { xf86Msg(X_ERROR, "DMC : reset err\n"); return (!Success); } else { sleep(1); /* touch need ca. 500ms delay !!! */ xf86Msg(0, "DMC : init ok\n"); if( !tx_specify_goto_idle(priv,true) ) { xf86Msg(X_ERROR, "DMC : specify\n"); return (!Success); } else { sleep(1); /* touch need ca. 500ms delay !!! */ xf86Msg(0, "DMC : specify ok\n"); switch( read_eeprom(priv) ) { case 1: xf86Msg(0, "DMC : using EEPROM data\n"); priv->eeprom_read_ok = true; break; case 0: xf86Msg(0, "DMC : not using EEPROM data\n"); priv->eeprom_read_ok = true; break; default: xf86Msg(0, "DMC : no EEPROM\n"); priv->eeprom_read_ok = false; break; } // goto_xyp(priv); xf86Msg(0, "DMC : found (OK)\n"); } } priv->lex_mode = DMC_Response0; } XisbBlockDuration (priv->buffer, -1); priv->lex_mode = DMC_byte0; xf86FlushInput(pInfo->fd); AddEnabledDevice (pInfo->fd); dev->public.on = TRUE; return (Success); case DEVICE_OFF: case DEVICE_CLOSE: #if 1 xf86Msg(X_WARNING, "DMC : DeviceControl OFF/CLOSE\n"); #endif if (pInfo->fd != -1) { RemoveEnabledDevice (pInfo->fd); if (priv->buffer) { XisbFree(priv->buffer); priv->buffer = NULL; } xf86CloseSerial(pInfo->fd); } dev->public.on = FALSE; return (Success); default: #if 1 xf86Msg(X_WARNING, "DMC : DeviceControl No\n"); #endif return (BadValue); }}/* * The ReadInput function will have to be tailored to your device */static void ReadInput (InputInfoPtr pInfo){ DMCPrivatePtr priv = (DMCPrivatePtr) (pInfo->private); int x,y; char pre_pen; unsigned char opck[ DMC_PACKET_SIZE ]; /* * set blocking to -1 on the first call because we know there is data to * read. Xisb automatically clears it after one successful read so that * succeeding reads are preceeded buy a select with a 0 timeout to prevent * read from blocking indefinately. *///xf86Msg(X_WARNING, "DMC : ReadInput entry\n"); XisbBlockDuration (priv->buffer, -1); while (1) { memcpy(opck,priv->packet,5); #if 0 xf86Msg(X_WARNING, "DMC : ReadInput wait\n"); #endif if ( DMCGetPacket (priv) != Success) break; #if 0 xf86Msg(X_WARNING, "DMC : ReadInput $%x\n",priv->packet[0]); #endif pre_pen = priv->pen_down; #if _3MEX2 if ( (priv->packet[0]&0x40) ) priv->pen_down = 1; else priv->pen_down = 0; //priv->packet[0] |= priv->pen_down; if ( priv->swap_xy) { y = priv->packet[1]+(priv->packet[2]<<7); x = priv->packet[3]+(priv->packet[4]<<7); } else { x = priv->packet[1]+(priv->packet[2]<<7); y = priv->packet[3]+(priv->packet[4]<<7); } x >>= 4; y >>= 4; y = TP_MAX_Y - 1 - y; #else if ( priv->packet[0] == 0x11 ) priv->pen_down = 1; else priv->pen_down = 0; if( priv->usb_dev ) { if ( priv->swap_xy) { y = priv->packet[2]*256+priv->packet[1]; x = priv->packet[4]*256+priv->packet[3]; } else { x = priv->packet[2]*256+priv->packet[1]; y = priv->packet[4]*256+priv->packet[3]; } } else { if ( priv->swap_xy) { y = priv->packet[1]*256+priv->packet[2]; x = priv->packet[3]*256+priv->packet[4]; } else { x = priv->packet[1]*256+priv->packet[2]; y = priv->packet[3]*256+priv->packet[4]; } } #endif //priv->packet[0] = priv->pen_down ? 0x01 : 0x00; #if 0 xf86Msg(X_WARNING, "DMC ReadInput (x,y)=(%d,%d) %02x %02x %02x %02x %02x %02x \n" ,x,y ,priv->packet[0] ,priv->packet[1],priv->packet[2],priv->packet[3],priv->packet[4] ,priv->packet[5]); #endif if( !adjust_xy(priv,x,y,&x,&y) ) { break; } if( pre_pen != priv->pen_down ) ring_beep(priv); xf86XInputSetScreen (pInfo, priv->screen_num, x, y); if ((priv->proximity == FALSE) && priv->pen_down ) { priv->proximity = TRUE; xf86PostProximityEvent (pInfo->dev, 1, 0, 2, x, y); } /* * Send events. * * We *must* generate a motion before a button change if pointer * location has changed as DIX assumes this. This is why we always * emit a motion, regardless of the kind of packet processed. */ xf86PostMotionEvent (pInfo->dev, TRUE, 0, 2, x, y); /* * Emit a button press or release. */ if( !priv->button_down && priv->pen_down ) { if( priv->tp_state & B_SELECT_MID ) priv->button_number = 2; else if( priv->tp_state & B_SELECT_RIGHT ) priv->button_number = 3; else priv->button_number = 1; //xf86Msg(X_WARNING, "DMC : Button %d \n",priv->button_number); xf86PostButtonEvent (pInfo->dev, TRUE,priv->button_number, 1, 0, 2, x, y); priv->button_down = TRUE; } if( priv->button_down && !priv->pen_down ) { xf86PostButtonEvent (pInfo->dev, TRUE, priv->button_number, 0, 0, 2, x, y); priv->button_down = FALSE; priv->calib_raw_x = x; priv->calib_raw_y = y; if( priv->tp_state & MASK_SELECT ) priv->button_number = 1; priv->tp_state &= (~MASK_SELECT); } /* * the untouch should always come after the button release */ if ((priv->proximity == TRUE) && !priv->pen_down ) { priv->proximity = FALSE; xf86PostProximityEvent (pInfo->dev, 0, 0, 2, x, y); } }#if 0 xf86Msg(X_WARNING, "DMC : ReadInput exit\n");#endif}/* * The ControlProc function may need to be tailored for your device */static int ControlProc (InputInfoPtr pInfo, xDeviceCtl * control){#if 0 xDeviceTSCalibrationCtl *c = (xDeviceTSCalibrationCtl *) control; DMCPrivatePtr priv = (DMCPrivatePtr) (pInfo->private);#if DEBUG_DMCxf86Msg(X_WARNING, "DMC : ControlProc %d %d %d %d\n" ,c->min_x,c->min_y,c->max_x,c->max_y);#endif priv->min_x = c->min_x; priv->max_x = c->max_x; priv->min_y = c->min_y; priv->max_y = c->max_y;#else xDeviceResolutionCtl *c = (xDeviceResolutionCtl *) control;#if DEBUG_DMC int *p = (int *)(c + 1); xf86Msg(X_WARNING, "DMC : ControlProc %d %d (%d %d %d %d)\n" ,c->first_valuator,c->num_valuators,p[0],p[1],p[2],p[3]);#endif #endif return (Success);}/* * the CloseProc should not need to be tailored to your device */static void CloseProc (InputInfoPtr pInfo){}/* * the QueryHardware fuction should be tailored to your device to * verify the device is attached and functional and perform any * needed initialization. */static Bool QueryHardware (DMCPrivatePtr priv){ /* Maybe once we get the hardware to actually respond correctly to its configuration 'packets' */ return (Success);}/* * This function should be renamed for your device and tailored to handle * your device's protocol. */static Bool DMCGetPacket (DMCPrivatePtr priv){ int count = 0; int c; while ((c = XisbRead (priv->buffer)) >= 0) {#if 0xf86Msg(X_WARNING, "DMC $%x\n",c);#endif /* * fail after 500 bytes so the server doesn't hang forever if a * device sends bad data. */ if (count++ > 500) return (!Success); switch (priv->lex_mode) { case DMC_byte0: #if _3MEX2 if( ( c & 0xc0 ) != 0x80 && ( c & 0xc0 ) != 0xc0 ) return (!Success); priv->packet[0] = (unsigned char) c & 0x40; #else #if 0 if ((( c & 0x3f ) != 0x11 ) && (( c & 0x3f ) != 0x10 )) return (!Success); #else if (( c & 0x3f ) == 0x10 ) { priv->packet[0] = (unsigned char) c & 0x3f; if( priv->usb_dev == 0 ) return (Success); } else if (( c & 0x3f ) != 0x11 ) return (!Success); #endif priv->packet[0] = (unsigned char) c & 0x3f; #endif priv->lex_mode = DMC_byte1; break; case DMC_byte1: priv->packet[1] = (unsigned char) c; priv->lex_mode = DMC_byte2; break; case DMC_byte2: priv->packet[2] = (unsigned char) c; priv->lex_mode = DMC_byte3; break; case DMC_byte3: priv->packet[3] = (unsigned char) c; priv->lex_mode = DMC_byte4; break; case DMC_byte4: priv->packet[4] = (unsigned char) c; priv->lex_mode = DMC_byte0; return (Success); break; case DMC_Response0: priv->packet[0] = (unsigned char) c; return (Success); break; } } return (!Success);}static Bool DMCSendPacket (DMCPrivatePtr priv, unsigned char *buf, int len){ int count = 0;#if _3MEX2 return (Success);#else if( priv->usb_dev ) return (Success); while ( len > 0 ) { if ( XisbWrite(priv->buffer, buf, 1) == 1 ) { buf++; len--; continue; } if ( count++ > 500 ) break; } return (len ? !Success : Success);#endif}static void DMCPtrCtrl(DeviceIntPtr device, PtrCtrl *ctrl){ /* I have no clue what this does, except that registering it stops the X server segfaulting in ProcGetPointerMapping() Ho Hum. */}static int ring_beep(DMCPrivatePtr priv){int a; a = 0; if( priv->reporting_mode == TS_Raw ) { if( priv->pen_down == 0 ) a = 1; } else { if( ( (priv->tp_state & B_BELL_DOWN) && priv->pen_down == 1 ) || ( (priv->tp_state & B_BELL_UP) && priv->pen_down == 0 ) ) a = 1; } if( a ) xf86SoundKbdBell(100,880,15); return(0);}/**************************************************************************************//* * The ConvertProc function may need to be tailored for your device. * This function converts the device's valuator outputs to x and y coordinates * to simulate mouse events. */static Bool ConvertProc (InputInfoPtr pInfo,int first,int num ,int v0,int v1,int v2,int v3,int v4,int v5,int *x, int *y){ DMCPrivatePtr priv = (DMCPrivatePtr) (pInfo->private); *x = v0; *y = v1;#if DEBUG_DISP_POINTxf86Msg(X_WARNING, "DMC : ConvertProc (%4d,%4d) (%4d,%4d)\n",*x,*y,v0,v1);#endif return (TRUE);}BOOL adjust_xy(DMCPrivatePtr priv,int inx,int iny,int *x,int *y){NTIME tm;int dp;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -