void getxy(struct tsdev *ts, int *x, int *y) { #define MAX_SAMPLES 128 struct ts_sample samp[MAX_SAMPLES]; int index, middle; do { if (ts_read(ts, &samp[0], 1) < 0) { perror("ts_read"); } } while (samp[0].pressure == 0); /* Now collect up to MAX_SAMPLES touches into the samp array. */ index = 0; do { if (index < MAX_SAMPLES-1) index++; if (ts_read(ts, &samp[index], 1) < 0) { perror("ts_read"); exit(1); } } while (samp[index].pressure > 0); /* * At this point, we have samples in indices zero to (index-1) * which means that we have (index) number of samples. We want * to calculate the median of the samples so that wild outliers * don't skew the result. First off, let's assume that arrays * are one-based instead of zero-based. If this were the case * and index was odd, we would need sample number ((index+1)/2) * of a sorted array; if index was even, we would need the * average of sample number (index/2) and sample number * ((index/2)+1). To turn this into something useful for the * real world, we just need to subtract one off of the sample * numbers. So for when index is odd, we need sample number * (((index+1)/2)-1). Due to integer division truncation, we * can simplify this to just (index/2). When index is even, we * need the average of sample number ((index/2)-1) and sample * number (index/2). Calculate (index/2) now and we'll handle * the even odd stuff after we sort. */ middle = index/2; if (x) { qsort(samp, index, sizeof(struct ts_sample), sort_by_x); if (index & 1) *x = samp[middle].x; else *x = (samp[middle-1].x + samp[middle].x) / 2; } if (y) { qsort(samp, index, sizeof(struct ts_sample), sort_by_y); if (index & 1) *y = samp[middle].y; else *y = (samp[middle-1].y + samp[middle].y) / 2; } }
/*!*********************************************************************** @Function OsGet @Input prefName Name of value to get @Modified pp A pointer set to the value asked for @Returns true on success @Description Retrieves OS-specific data *************************************************************************/ bool PVRShellInit::OsGet(const prefNamePtrEnum prefName, void **pp) { #if defined(PVRSHELL_OMAP3_TS_SUPPORT) switch(prefName) { case prefPointerLocation: { int ret = ts_read(ts, samples, PVRSHELL_TS_SAMPLES); if (ret <= 0) { //m_bPointer = false; *pp = NULL; return false; } struct ts_sample &samp = samples[ret - 1]; m_vec2PointerLocation[0] = (float)samp.x / m_pShell->m_pShellData->nShellDimX; m_vec2PointerLocation[1] = (float)samp.y / m_pShell->m_pShellData->nShellDimY; //m_bPointer = true; *pp = m_vec2PointerLocation; return true; } default: return false; } #endif return false; }
static int TSGetInputEvent(struct InputEvent *ptInputEvent) { struct ts_sample tTSSample; int iError = 0; iError = ts_read(g_ptTouchScreenFd, &tTSSample, 1); if(iError != 1){ DebugPrint(DEBUG_WARNING"TS read error\n"); return -1; } /* 可能是驱动程序的问题,这里不能使用ts_read出来的时间数据,否则的话会进不去下面的 * if 判断,并且读取数据有bug,有时候会出现按了好几次但是翻页没有那么多次 * 然后再往后按下一次的时候突然多翻几次页 * 加上多线程之后就没问题了,应该是读取的问题 * 问题确定,是因为按键的 read 函数未阻塞导致其线程不断运行,该线程没有时间读取数据 */ // gettimeofday(&g_tCurTimeVal, NULL); #if 0 printf("tTSSample.sec = %d, tTSSample.usec = %d\n", tTSSample.tv.tv_sec, tTSSample.tv.tv_usec); printf("g_tPreTimeVal.sec = %d, g_tPreTimeVal.usec = %d\n", g_tPreTimeVal.tv_sec, g_tPreTimeVal.tv_usec); printf("xres = %d yres = %d\n", tTSSample.x, tTSSample.y); printf("touchscreen get event\n"); printf("xres = %d yres = %d\n", tTSSample.x, tTSSample.y); #endif g_tPreTimeVal = tTSSample.tv; ptInputEvent->iInputType = INPUT_TYPE_TS; ptInputEvent->iInputCode = INPUT_CODE_UNKNOW; ptInputEvent->iXPos = tTSSample.x; ptInputEvent->iYPos = tTSSample.y; ptInputEvent->bPressure = tTSSample.pressure; ptInputEvent->tTimeVal = tTSSample.tv; if((tTSSample.x > g_iTSXres / 3) && (tTSSample.x < g_iTSXres * 2 /3) && (tTSSample.y > g_iTSYres * 2 / 3)) { ptInputEvent->iInputCode = INPUT_CODE_DOWN; } if((tTSSample.x > g_iTSXres / 3) && (tTSSample.x < g_iTSXres * 2 /3) && (tTSSample.y < g_iTSYres / 3)) { ptInputEvent->iInputCode = INPUT_CODE_UP; } if((tTSSample.x > g_iTSXres * 2 /3) && (tTSSample.y > g_iTSYres / 3) && (tTSSample.y < g_iTSYres * 2 / 3)) { ptInputEvent->iInputCode = INPUT_CODE_EXIT; } return 0; }
void *read_ts(void *data) { int x,y; unsigned int i; unsigned int mode =0; while(1) { struct ts_sample samp; int ret; ret = ts_read(data, &samp,1); if(ret<0) { perror("ts_read"); close_framebuffer(); exit(1); } if(ret!=1) continue; for(i=0;i<NR_BUTTONS;i++) if(button_handle(&buttons[i],&samp)) switch(i) { case 0://clear button clicked mode = 0; refresh_screen(); break; case 1://exit button clicked mode = 1; put_string_center(xres/2,yres/2, "Bye~!!",1); sleep(2); fillrect(0,0,xres-1,yres-1,0); exit(1); break; } if(samp.pressure>0) { if(mode == 0x80000000) line(x,y,samp.x,samp.y,2); x = samp.x; y = samp.y; mode|=0x80000000; } else { mode&=~0x80000000; } } }
void TsRead (int tsPort, void *closure) { KdMouseInfo *mi = closure; int fd = (int) mi->driver; struct ts_sample event; int n; long pressure; long x, y; unsigned long flags; unsigned long buttons; n = ts_read(tsDev, &event, 1); if (n == 1) { if (event.pressure) { /* * HACK ATTACK. (static global variables used !) * Here we test for the touch screen driver actually being on the * touch screen, if it is we send absolute coordinates. If not, * then we send delta's so that we can track the entire vga screen. */ if (KdTsCurScreen == KdTsPhyScreen) { flags = KD_BUTTON_1; x = event.x; y = event.y; } else { flags = /* KD_BUTTON_1 |*/ KD_MOUSE_DELTA; if ((lastx == 0) || (lasty == 0)) { x = 0; y = 0; } else { x = event.x - lastx; y = event.y - lasty; } lastx = event.x; lasty = event.y; } } else { flags = KD_MOUSE_DELTA; x = 0; y = 0; lastx = 0; lasty = 0; } KdEnqueueMouseEvent (mi, flags, x, y); } }
/******************************************************************************* * Description : * Argurments : * Return value : * Modify : * warning : *******************************************************************************/ static void *t_touch_monitoring(void *ctx_t) { struct NCA_TOUCH_CTX *ctx; if( ctx_t == NULL ) return 0; else ctx = ctx_t; unsigned short x, y; int ret = 1; ctx->thread_start = 1; while(ctx->thread_start) { while(!ctx->monitoring_start) sleep(1); struct ts_sample samp; ret = ts_read( ctx->dev, &samp, 1 ); if( ret < 0 ) { printf("[ERROR] ts_read \n"); goto END; } else if( ret != 1 ) { goto END; } x = samp.x; y = samp.y; /* * if can read fb, don't need _240320_TO_320240( x, y ); */ // _240320_TO_320240( x, y ); ctx->callback(x, y); END: usleep(ctx->intaval); } return 0; }
int main() { struct tsdev *ts; char *tsdevice=NULL; if( (tsdevice = getenv("TSLIB_TSDEVICE")) != NULL ) { ts = ts_open(tsdevice,0); } else { if (!(ts = ts_open("/dev/input/event0", 0))) ts = ts_open("/dev/touchscreen/ucb1x00", 0); } if (!ts) { perror("ts_open"); exit(1); } if (ts_config(ts)) { perror("ts_config"); exit(1); } while (1) { struct ts_sample samp; int ret; ret = ts_read(ts, &samp, 1); if (ret < 0) { perror("ts_read"); exit(1); } if (ret != 1) continue; printf("%ld.%06ld: %6d %6d %6d\n", samp.tv.tv_sec, samp.tv.tv_usec, samp.x, samp.y, samp.pressure); } }
static int PD_Read(MWCOORD *px, MWCOORD *py, MWCOORD *pz, int *pb) { struct ts_sample samp; int ret; ret = ts_read(ts, &samp, 1); if (ret <= 0) { if (errno == EINTR || errno == EAGAIN) return 0; EPRINTF("Error reading from touchscreen: %s\n", strerror(errno)); return -1; } *px = samp.x; *py = samp.y; *pb = (samp.pressure) ? MWBUTTON_L : 0; *pz = samp.pressure; if(!*pb) return 3; return 2; }
int main(int argc, char *argv[]) { int ret; int serv_sock, clnt_sock; char *myip; char *tsdevice = "/dev/ts0"; struct tsdev *ts; if (argc < 2) { printf("USAGE : %s myip\n", argv[0]); exit(1); } myip = argv[1]; signal(SIGSEGV, sig); signal(SIGINT, sig); signal(SIGTERM, sig); #ifdef DEBUG fprintf(stderr, " *** server for theMeal ***\n\n"); #endif printf("theMeal: oo_ts_server started!\n"); /* initialize */ ts = ts_open(tsdevice, 0); if (!ts) { perror("ts_open"); exit(1); } if (ts_config(ts)) { perror("ts_config"); exit(1); } serv_sock = tcp_server_listen(ip2port(myip, 7000), 2); if (serv_sock < 0) exit(1); /* main process */ while (1) { int pid, status; char ts_ack[1]; struct ts_sample samp, v_samp; clnt_sock = tcp_server_accept(serv_sock); if (clnt_sock < 0) exit(1); pid = fork(); // Parent Process if (pid > 0) { #ifdef DEBUG fprintf(stderr, "clnt_sock #%d pid #%d\n", clnt_sock, pid); #endif close(clnt_sock); wait(&status); continue; } /* Child Process * send ts_sample structure and recv ack character * unless ack is not 1, it will send ts_sample structure */ else { do { ret = ts_read(ts, &samp, 1); if (ret < 0) { perror("ts_read"); continue; } if (ret != 1) continue; // v_samp = phy2vir_pos(samp, mylocation); // ret = write(clnt_sock, &v_samp, sizeof(struct ts_sample)); ret = write(clnt_sock, &samp, sizeof(struct ts_sample)); #ifdef DEBUG fprintf(stderr, "%ld.%06ld: %6d %6d %6d\n", samp.tv.tv_sec, samp.tv.tv_usec, samp.x, samp.y, samp.pressure); fprintf(stderr, "To #%d write: %d\n", clnt_sock, ret); #endif if (samp.x > 300 && samp.y < 20) break; } while (1); shutdown(clnt_sock, SHUT_WR); close(clnt_sock); #ifdef DEBUG fprintf(stderr, "\n *** child process is done\n"); #endif exit(0); } // end child process } // end while(1) close(serv_sock); #ifdef DEBUG fprintf(stderr, "\n *** All done completely. ***\n"); #endif exit(0); return 0; }
bool EventHub::getEvent(RawEvent* outEvent) { outEvent->deviceId = 0; outEvent->type = 0; outEvent->scanCode = 0; outEvent->keyCode = 0; outEvent->flags = 0; outEvent->value = 0; outEvent->when = 0; status_t err; LOGV("EventHub::getEvent() enter"); // Note that we only allow one caller to getEvent(), so don't need // to do locking here... only when adding/removing devices. if (!mOpened) { mError = openPlatformInput() ? NO_ERROR : UNKNOWN_ERROR; mOpened = true; mNeedToSendFinishedDeviceScan = true; } for (;;) { // Report any devices that had last been added/removed. if (mClosingDevices != NULL) { device_t* device = mClosingDevices; LOGV("Reporting device closed: id=0x%x, name=%s\n", device->id, device->path.string()); mClosingDevices = device->next; if (device->id == mFirstKeyboardId) { outEvent->deviceId = 0; } else { outEvent->deviceId = device->id; } outEvent->type = DEVICE_REMOVED; outEvent->when = systemTime(SYSTEM_TIME_MONOTONIC); delete device; mNeedToSendFinishedDeviceScan = true; return true; } if (mOpeningDevices != NULL) { device_t* device = mOpeningDevices; LOGV("Reporting device opened: id=0x%x, name=%s\n", device->id, device->path.string()); mOpeningDevices = device->next; if (device->id == mFirstKeyboardId) { outEvent->deviceId = 0; } else { outEvent->deviceId = device->id; } outEvent->type = DEVICE_ADDED; outEvent->when = systemTime(SYSTEM_TIME_MONOTONIC); mNeedToSendFinishedDeviceScan = true; return true; } if (mNeedToSendFinishedDeviceScan) { mNeedToSendFinishedDeviceScan = false; outEvent->type = FINISHED_DEVICE_SCAN; outEvent->when = systemTime(SYSTEM_TIME_MONOTONIC); return true; } // Grab the next input event for device mDevices[mInputDeviceIndex]. for (;;) { #ifdef HAVE_TSLIB //Checks if we have to send any more TS events read by input-raw plugin //else we process other events if (tsSamp.total_events && tsSamp.tsSampleReady) { LOGV("Processing TS Event"); outEvent->deviceId = mDevices[tsSamp.tsIndex]->id; outEvent->type = tsSamp.ev[numOfEventsSent].type; outEvent->scanCode = tsSamp.ev[numOfEventsSent].code; outEvent->keyCode = tsSamp.ev[numOfEventsSent].code; outEvent->value = tsSamp.ev[numOfEventsSent].value; outEvent->when = systemTime(SYSTEM_TIME_MONOTONIC); switch (outEvent->type) { case EV_KEY: outEvent->keyCode = AKEYCODE_UNKNOWN; outEvent->flags = 0; break; case EV_ABS: switch (outEvent->scanCode) { case ABS_X: outEvent->value = tsSamp.x; LOGV("outEvent->valueX=%d",outEvent->value); break; case ABS_Y: outEvent->value = tsSamp.y; LOGV("outEvent->valueY=%d",outEvent->value); break; case ABS_PRESSURE: outEvent->value = tsSamp.pressure; LOGV("outEvent->valueP=%d",outEvent->value); break; } break; } LOGV("%s (id: 0x%x) got: t0=%d, t1=%d, type=%d, code=%d, v=%d," " keyCode=%d, flags=0x%08x", mDevices[tsSamp.tsIndex]->path.string(), outEvent->deviceId, (int) tsSamp.ev[numOfEventsSent].time.tv_sec, (int) tsSamp.ev[numOfEventsSent].time.tv_usec, outEvent->type,outEvent->scanCode, outEvent->value, outEvent->keyCode,outEvent->flags); numOfEventsSent++; LOGV("numOfEventsSent: %d, tsSamp.total_events: %d", numOfEventsSent, tsSamp.total_events); LOGV("EventHub::getEvent() exit"); if (numOfEventsSent == tsSamp.total_events){ //All the events from the read call have been dealt with, //clearing tsSamp for next call. tsSamp.total_events = 0; tsSamp.tsSampleReady = 0; numOfEventsSent = 0; } return true; } #endif // Consume buffered input events, if any. if (mInputBufferIndex < mInputBufferCount) { const struct input_event& iev = mInputBufferData[mInputBufferIndex++]; const device_t* device = mDevices[mInputDeviceIndex]; LOGV("%s (id: 0x%x) got: t0=%d, t1=%d, type=%d, code=%d, v=%d", device->path.string(), device->id,(int) iev.time.tv_sec, (int) iev.time.tv_usec, iev.type, iev.code, iev.value); if (device->id == mFirstKeyboardId) { outEvent->deviceId = 0; } else { outEvent->deviceId = device->id; } outEvent->type = iev.type; outEvent->scanCode = iev.code; if (iev.type == EV_KEY) { err = device->layoutMap->map(iev.code,& outEvent->keyCode, & outEvent->flags); if (err != 0) { LOGV("EV_KEY event, error (%d) accessing device layout map \n",err); outEvent->keyCode = AKEYCODE_UNKNOWN; outEvent->flags = 0; } } else { outEvent->keyCode = iev.code; } LOGV("iev.code=%d keyCode=%d flags=0x%08x \n",iev.code, outEvent->keyCode, outEvent->flags); outEvent->value = iev.value; // Use an event timestamp in the same timebase as // java.lang.System.nanoTime() and android.os.SystemClock.uptimeMillis() // as expected by the rest of the system. outEvent->when = systemTime(SYSTEM_TIME_MONOTONIC); LOGV("EventHub::getEvent() exit"); return true; } // Finish reading all events from devices identified in previous poll(). // This code assumes that mInputDeviceIndex is initially 0 and that the // revents member of pollfd is initialized to 0 when the device is first added. // Since mFDs[0] is used for inotify, we process regular events starting at index 1. mInputDeviceIndex += 1; if (mInputDeviceIndex >= mFDCount) { LOGV("Done processing events received in last poll for all devices."); break; } const struct pollfd& pfd = mFDs[mInputDeviceIndex]; if (pfd.revents & POLLIN) { #ifdef HAVE_TSLIB LOGV("Reading events from device. id: 0x%x , mInputDeviceIndex: %d, fd: %d, mTS->fd: %d", mDevices[mInputDeviceIndex]->id,mInputDeviceIndex, mFDs[mInputDeviceIndex].fd, mTS->fd); if (mTS != NULL) { if (mFDs[mInputDeviceIndex].fd != mTS->fd ) { #endif int32_t readSize = read(pfd.fd, mInputBufferData, sizeof(struct input_event) * INPUT_BUFFER_SIZE); if (readSize < 0) { if (errno != EAGAIN && errno != EINTR) { LOGW("could not get event (errno=%d)", errno); } } else if ((readSize % sizeof(struct input_event)) != 0) { LOGE("could not get event (wrong size: %d)", readSize); } else { mInputBufferCount = readSize / sizeof(struct input_event); mInputBufferIndex = 0; LOGV("Buffered %d events from device", mInputBufferCount); } #ifdef HAVE_TSLIB } else{ int res = ts_read(mTS, &tsSamp, 1); if (res < 0) { LOGE("[EventHub::after poll] Error in ts_read()"); } else { tsSamp.tsIndex = mInputDeviceIndex; LOGV("After ts_read call: tsSamp[total_events: %d," " tsIndex: %d tsSampleReady: %d] res:%d ", tsSamp.total_events,tsSamp.tsIndex, tsSamp.tsSampleReady,res); //we have read a TS event, we want to process this now. } } } else { LOGE("EventHub:: ERROR in setup of mTS: mTS is NULL!"); } #endif }//end of if (pfd.revents & POLLIN) } //end of for(;;) get next input event #if HAVE_INOTIFY // readNotify() will modify mFDs and mFDCount, so this must be done after // processing all other events. if(mFDs[0].revents & POLLIN) { readNotify(mFDs[0].fd); mFDs[0].revents = 0; LOGV("After readNotify()"); continue; // report added or removed devices immediately } #endif mInputDeviceIndex = 0; // Poll for events. Mind the wake lock dance! // We hold a wake lock at all times except during poll(). This works due to some // subtle choreography. When a device driver has pending (unread) events, it acquires // a kernel wake lock. However, once the last pending event has been read, the device // driver will release the kernel wake lock. To prevent the system from going to sleep // when this happens, the EventHub holds onto its own user wake lock while the client // is processing events. Thus the system can only sleep if there are no events // pending or currently being processed. release_wake_lock(WAKE_LOCK_ID); LOGV("Calling Poll()"); int pollResult = poll(mFDs, mFDCount, -1); LOGV("After calling Poll()"); acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID); if (pollResult <= 0) { if (errno != EINTR) { LOGW("poll failed (errno=%d)\n", errno); usleep(100000); } } }//end of for(;;) }//end of getEvent()
int main(int argc, char *argv[]) { int ret; struct tsdev *ts; lua_State *L; myfb = myfb_open(); set_vfb_buf(1); ts = ts_init(); L = luaL_newstate(); luaL_openlibs(L); lua_register(L, "SET_COUNT", lua_set_icon_count); lua_register(L, "SET_ICON", lua_set_icon_info); lua_register(L, "SET_CMD", lua_set_cmd_list); lua_register(L, "SET_BGCOLOR", lua_set_bgcolor); lua_register(L, "SET_BGIMAGE", lua_set_bgimage); luaL_dofile(L, file_ui); lua_close(L); while (1) { int c, da_count, old_da_count, pid, state = 0; struct ts_sample samp; struct icon *i; struct cmd_list *j; da_count = get_DeviceAttached(); if (!da_count) da_count = 0; if (!old_da_count) old_da_count = da_count; else { if (old_da_count != da_count) { clear_screen(); put_string_center(myfb->fbvar.xres/2, myfb->fbvar.yres/2 - 10, "Attached Info is changed!", white); put_string_center(myfb->fbvar.xres/2, myfb->fbvar.yres/2 + 10, "Touch the screen!", white); old_da_count = da_count; ret = ts_read(ts, &samp, 1); continue; } } set_bgimage(); set_bgcolor(); for (c=0; c<=da_count; c++) draw_block(myfb->fbvar.xres-12*c-12, 3); if (head == NULL) { put_string_center(myfb->fbvar.xres/2, myfb->fbvar.yres/2, "Sorry, No Apps. registered!", white); #ifdef DEBUG fprintf(stderr, "No Apps!\n"); #endif break; } for (i=head; i != NULL; i=i->next) draw_icon(i); ret = ts_read(ts, &samp, 1); if (ret < 0) { perror("ts_read"); continue; } if (ret != 1) continue; if (samp.x > 310 && samp.y >230) break; for (i=head, j=cmdlist; i != NULL; i=i->next, j=j->next) { if (icon_handle(i, &samp) > 0) { if (chat_count < 20) continue; chat_count = 0; pid = fork(); if (pid == 0) { #ifdef DEBUG fprintf(stderr, " *** This is CHILD! ***\n"); #endif if (j) ret = execl(j->path, j->args, 0); if (ret < 0) { perror("execl"); exit(1); } } else { sleep(1); wait(&state); no_count = 0; put_string_center(myfb->fbvar.xres/2, myfb->fbvar.yres/2, "End of Program!", white); #ifdef DEBUG fprintf(stderr, " *** End of CHILD! ***\n"); #endif } } } } clear_screen(); put_string_center(myfb->fbvar.xres/2, myfb->fbvar.yres/2, "Thanks for Use!", white); free_icon(); free_cmd(); ts_close(ts); free_vfb_buf(1); myfb_close(); return 0; }
static int tarix_read(const char *path, char *buf, size_t size, off_t offset, struct fuse_file_info *fi) { union tar_block theader; int res; //TODO: cache state in the tar fd so we don't keep re-reading the beginning // of a file over and over again struct index_node *node = find_node(path); if (node == NULL) return -ENOENT; off64_t nodeoffset = get_node_effective_offset(node); if (nodeoffset < 0) return -EIO; if (ts_seek(tarixfs.tsp, nodeoffset) != 0) { fprintf(stderr, "seek error for initial tar header in record '%s'\n", node->entry.filename); return -EIO; } if ((res = ts_read(tarixfs.tsp, &theader, TARBLKSZ)) != TARBLKSZ) { fprintf(stderr, "read error for initial tar header in record '%s'\n", node->entry.filename); return -EIO; } // skip any prefix records (long names, symlinks) while (theader.header.typeflag == GNUTYPE_LONGNAME || theader.header.typeflag == GNUTYPE_LONGLINK) { // skip the long link/name if ((res = ts_read(tarixfs.tsp, &theader, TARBLKSZ)) != TARBLKSZ) { fprintf(stderr, "read error skipping long link/name in record '%s'\n", node->entry.filename); return -EIO; } // read the next header (maybe the real one) if ((res = ts_read(tarixfs.tsp, &theader, TARBLKSZ)) != TARBLKSZ) { fprintf(stderr, "read error skipping long link/name (#2) in record '%s'\n", node->entry.filename); return -EIO; } } if (theader.header.typeflag != REGTYPE && theader.header.typeflag != AREGTYPE) { // can only read from regular files return -EIO; } // use the buffer in the tar header to skip data //TODO: direct seek on normal files // skip to the desired data while (offset > 0) { int readcount = TARBLKSZ < offset ? TARBLKSZ : offset; res = ts_read(tarixfs.tsp, theader.buffer, readcount); if (res != readcount) { fprintf(stderr, "pseudo-seek read error in record '%s'\n", node->entry.filename); return -EIO; } offset -= res; } // read the desired data res = ts_read(tarixfs.tsp, buf, size); return res; }
static void * Handle_TouchScreen_Input () /* 功能:处理触屏输入 */ { char *tsdevice; struct ts_sample samp; int button, x, y, ret; LCUI_MouseEvent event; char str[100]; while (LCUI_Active()) { if (LCUI_Sys.ts.status != INSIDE) { tsdevice = getenv("TSLIB_TSDEVICE"); if( tsdevice != NULL ) { LCUI_Sys.ts.td = ts_open(tsdevice, 0); } else { tsdevice = TS_DEV; } LCUI_Sys.ts.td = ts_open (tsdevice, 0); if (!LCUI_Sys.ts.td) { sprintf (str, "ts_open: %s", tsdevice); perror (str); LCUI_Sys.ts.status = REMOVE; break; } if (ts_config (LCUI_Sys.ts.td)) { perror ("ts_config"); LCUI_Sys.ts.status = REMOVE; break; } LCUI_Sys.ts.status = INSIDE; } /* 开始获取触屏点击处的坐标 */ ret = ts_read (LCUI_Sys.ts.td, &samp, 1); if (ret < 0) { perror ("ts_read"); continue; } if (ret != 1) { continue; } x = samp.x; y = samp.y; if (x > Get_Screen_Width ()) { x = Get_Screen_Width (); } if (y > Get_Screen_Height ()) { y = Get_Screen_Height (); } if (x < 0) { x = 0; } if (y < 0) { y = 0; } /* 设定游标位置 */ Set_Cursor_Pos (Pos(x, y)); event.global_pos.x = x; event.global_pos.y = y; /* 获取当前鼠标指针覆盖到的部件的指针 */ event.widget = Get_Cursor_Overlay_Widget(); /* 如果有覆盖到的部件,就需要计算鼠标指针与部件的相对坐标 */ if(event.widget != NULL) { event.pos.x = x - Get_Widget_Global_Pos(event.widget).x; event.pos.y = y - Get_Widget_Global_Pos(event.widget).y; } else {/* 否则,和全局坐标一样 */ event.pos.x = x; event.pos.y = y; } if (samp.pressure > 0) { button = 1; } else { button = 0; } /* 处理鼠标事件 */ Handle_Mouse_Event(button, &event); //printf("%ld.%06ld: %6d %6d %6d\n", samp.tv.tv_sec, samp.tv.tv_usec, samp.x, samp.y, samp.pressure); } if(LCUI_Sys.ts.status == INSIDE) { ts_close(LCUI_Sys.ts.td); } LCUI_Sys.ts.status = REMOVE; thread_exit (NULL); }
void * ts_click(void* arg) { int i , ret ,t; int chat = 0 ; ts = ts_open(tsdevice, 0); if (!ts) { perror("ts_open"); exit(1); } if (ts_config(ts)) { perror("ts_config"); exit(1); } #if DEBUG printf(" thread func start \n"); #endif while(1) { ret = ts_read(ts, &samp, 1); chat ++; if (ret < 0) { perror("ts_read"); exit(1); } if (chat < 15) continue; else { chat = 0; for (i=0; i < myicon_count; i++) { if ( (t = myicon_handle(&icon[myicon_count -1], &samp))) { put_string_center(140, 100, " exit cam app ", white); event = 9 ; sleep(1); pthread_exit(NULL); } else if( (t = myicon_handle(&icon[i], &samp))) { func = i+1; event =1; #if DEBUG printf(" event is %d \n", event); #endif } } } } pthread_exit(NULL); }
int main() { struct tsdev *ts; int x, y; unsigned int i; unsigned int mode = 0; char *tsdevice=NULL; signal(SIGSEGV, sig); signal(SIGINT, sig); signal(SIGTERM, sig); if ((tsdevice = getenv("TSLIB_TSDEVICE")) == NULL) { #ifdef USE_INPUT_API tsdevice = strdup ("/dev/input/event0"); #else tsdevice = strdup ("/dev/touchscreen/ucb1x00"); #endif /* USE_INPUT_API */ } ts = ts_open (tsdevice, 0); if (!ts) { perror (tsdevice); exit(1); } if (ts_config(ts)) { perror("ts_config"); exit(1); } if (open_framebuffer()) { close_framebuffer(); exit(1); } x = xres/2; y = yres/2; for (i = 0; i < NR_COLORS; i++) setcolor (i, palette [i]); /* Initialize buttons */ memset (&buttons, 0, sizeof (buttons)); buttons [0].w = buttons [1].w = xres / 4; buttons [0].h = buttons [1].h = 20; buttons [0].x = xres / 4 - buttons [0].w / 2; buttons [1].x = (3 * xres) / 4 - buttons [0].w / 2; buttons [0].y = buttons [1].y = 10; buttons [0].text = "Drag"; buttons [1].text = "Draw"; refresh_screen (); while (1) { struct ts_sample samp; int ret; /* Show the cross */ if ((mode & 15) != 1) put_cross(x, y, 2 | XORMODE); ret = ts_read(ts, &samp, 1); /* Hide it */ if ((mode & 15) != 1) put_cross(x, y, 2 | XORMODE); if (ret < 0) { perror("ts_read"); close_framebuffer(); exit(1); } if (ret != 1) continue; for (i = 0; i < NR_BUTTONS; i++) if (button_handle (&buttons [i], &samp)) switch (i) { case 0: mode = 0; refresh_screen (); break; case 1: mode = 1; refresh_screen (); break; } printf("%ld.%06ld: %6d %6d %6d\n", samp.tv.tv_sec, samp.tv.tv_usec, samp.x, samp.y, samp.pressure); if (samp.pressure > 0) { if (mode == 0x80000001) line (x, y, samp.x, samp.y, 2); x = samp.x; y = samp.y; mode |= 0x80000000; } else mode &= ~0x80000000; } close_framebuffer(); }
int main() { struct tsdev *ts; int x, y; unsigned int i; unsigned int mode = 0; char *tsdevice=NULL; signal(SIGSEGV, sig); signal(SIGINT, sig); signal(SIGTERM, sig); if ((tsdevice = getenv("TSLIB_TSDEVICE")) == NULL) { #ifdef USE_INPUT_API tsdevice = strdup ("/dev/input/event0"); #else tsdevice = strdup ("/dev/touchscreen/ucb1x00"); #endif /* USE_INPUT_API */ } ts = ts_open (tsdevice, 0); if (!ts) { perror (tsdevice); exit(1); } if (ts_config(ts)) { perror("ts_config"); exit(1); } if (open_framebuffer()) { close_framebuffer(); exit(1); } x = xres/2; y = yres/2; for (i = 0; i < NR_COLORS; i++) setcolor (i, palette [i]); /* Initialize buttons */ memset (&buttons, 0, sizeof (buttons)); /*buttons [0].w = buttons [1].w = xres / 4; buttons [0].h = buttons [1].h = 20; buttons [0].x = xres / 4 - buttons [0].w / 2; buttons [1].x = (3 * xres) / 4 - buttons [0].w / 2; buttons [0].y = buttons [1].y = 10; buttons [0].text = "Drag"; buttons [1].text = "Draw"; buttons [0].*/ /*weight height*/ for(i=1; i<17; i++){ buttons [i].w = xres / 7; buttons [i].h = yres / 5; } buttons [0].w = (2*xres/7) + (xres/49); buttons [0].h = yres / 5; /*result a half of xres and position is center*/ buttons [17].w = xres / 2; buttons [17].h = yres / 5; buttons [17].text = ""; /*value*/ buttons [0].text = "0"; buttons [1].text = "1"; buttons [2].text = "2"; buttons [3].text = "3"; buttons [4].text = "4"; buttons [5].text = "5"; buttons [6].text = "6"; buttons [7].text = "7"; buttons [8].text = "8"; buttons [9].text = "9"; buttons [10].text = "+"; buttons [11].text = "-"; buttons [12].text = "*"; buttons [13].text = "/"; buttons [14].text = "="; buttons [15].text = "C"; buttons [16].text = "D"; /* *800 * 480 * *such design: the y-blank is yres/25 = 96px, x-blank is xres/49 = 114px; * */ /* * * 17 *15 16 10 11 12 13 *1 2 3 4 5 14 *6 7 8 9 0 * * */ /*the x position of buttons*/ buttons [15].x = buttons [1].x = buttons [6].x = xres / 49; buttons [16].x = buttons [2].x = buttons [7].x = (xres/7) + (2*xres/49); buttons [10].x = buttons [3].x = buttons [8].x = (2*xres/7) + (3*xres/49); buttons [11].x = buttons [4].x = buttons [9].x = (3*xres/7) + (4*xres/49); buttons [12].x = buttons [5].x = buttons [0].x = (4*xres/7) + (5*xres/49); buttons [13].x = buttons [14].x = (5*xres/7) + (6*xres/49); /*the y position of buttons*/ buttons [15].y =buttons [16].y =buttons [10].y =buttons [11].y =buttons [12].y = buttons [13].y = (yres/5) + (2*yres/25); buttons [1].y =buttons [2].y =buttons [3].y =buttons [4].y =buttons [5].y = buttons [14].y = (2*yres/5) + (3*yres/25); buttons [6].y =buttons [7].y =buttons [8].y =buttons [9].y =buttons [0].y = (3*yres/5) + (4*yres/25); /*result center*/ buttons [17].x = xres / 4; buttons [17].y = yres / 25; /*refresh*/ refresh_screen (); while (1) { struct ts_sample samp; int ret; // Show the cross if ((mode & 15) != 1) put_cross(x, y, 2 | XORMODE); ret = ts_read(ts, &samp, 1); // Hide it if ((mode & 15) != 1) put_cross(x, y, 2 | XORMODE); if (ret < 0) { perror("ts_read"); close_framebuffer(); exit(1); } if (ret != 1) continue; for (i = 0; i < NR_BUTTONS; i++) if (button_handle (&buttons [i], &samp)) switch (i) { case 0: mode = 0; refresh_screen (); break; case 1: mode = 1; refresh_screen (); break; } printf("%ld.%06ld: %6d %6d %6d\n", samp.tv.tv_sec, samp.tv.tv_usec, samp.x, samp.y, samp.pressure); if (samp.pressure > 0) { if (mode == 0x80000001) line (x, y, samp.x, samp.y, 2); x = samp.x; y = samp.y; mode |= 0x80000000; } else mode &= ~0x80000000; } close_framebuffer(); }
static int TouchScreenGetInputEvent(PT_InputEvent ptInputEvent) { struct ts_sample tSamp; struct ts_sample tSampPressed; struct ts_sample tSampReleased; int iRet; int bStart = 0; int iDelta; static struct timeval tPreTime; while (1) { iRet = ts_read(g_tTSDev, &tSamp, 1); /* 如果无数据则休眠 */ if (iRet == 1) { if ((tSamp.pressure > 0) && (bStart == 0)) { /* 刚按下 */ /* 记录刚开始压下的点 */ tSampPressed = tSamp; bStart = 1; } if (tSamp.pressure <= 0) { /* 松开 */ tSampReleased = tSamp; /* 处理数据 */ if (!bStart) { return -1; } else { iDelta = tSampReleased.x - tSampPressed.x; ptInputEvent->tTime = tSampReleased.tv; ptInputEvent->iType = INPUT_TYPE_TOUCHSCREEN; if (iDelta > giXres/5) { /* 翻到上一页 */ ptInputEvent->iVal = INPUT_VALUE_UP; } else if (iDelta < 0 - giXres/5) { /* 翻到下一页 */ ptInputEvent->iVal = INPUT_VALUE_DOWN; } else { ptInputEvent->iVal = INPUT_VALUE_UNKNOWN; } return 0; } } } else { return -1; } } return 0; }
static int tarix_readlink(const char *path, char *buf, size_t len) { union tar_block theader; int res; struct index_node *node = find_node(path); if (node == NULL) return -ENOENT; off64_t nodeoffset = get_node_effective_offset(node); if (nodeoffset < 0) return -EIO; if (ts_seek(tarixfs.tsp, nodeoffset) != 0) { fprintf(stderr, "seek error for initial tar header in record '%s'\n", node->entry.filename); return -EIO; } if ((res = ts_read(tarixfs.tsp, &theader, TARBLKSZ)) != TARBLKSZ) { fprintf(stderr, "read error for initial tar header in record '%s'\n", node->entry.filename); return -EIO; } // skip any longname prefix record if (theader.header.typeflag == GNUTYPE_LONGNAME) { // skip the text if ((res = ts_read(tarixfs.tsp, &theader, TARBLKSZ)) != TARBLKSZ) { fprintf(stderr, "read error skipping long link/name in record '%s'\n", node->entry.filename); return -EIO; } // read the next (maybe real) if ((res = ts_read(tarixfs.tsp, &theader, TARBLKSZ)) != TARBLKSZ) { fprintf(stderr, "read error skipping long link/name (#2) in record '%s'\n", node->entry.filename); return -EIO; } } int cpylen; char *cpysrc; // if we hit a longlink record, use that if (theader.header.typeflag == GNUTYPE_LONGLINK) { // read the long link name if ((res = ts_read(tarixfs.tsp, &theader, TARBLKSZ)) != TARBLKSZ) { fprintf(stderr, "read error reading long link/name in record '%s'\n", node->entry.filename); return -EIO; } // use the smaller of the two lengths cpylen = TARBLKSZ < len ? TARBLKSZ : len; cpysrc = theader.buffer; } else if (theader.header.typeflag == SYMTYPE) { // linkname is 100 bytes cpylen = sizeof(theader.header.linkname) < len ? sizeof(theader.header.linkname) : len; cpysrc = theader.header.linkname; } else { // not a symlink return -EINVAL; } // copy the data strncpy(buf, cpysrc, cpylen); // make sure it's null terminated buf[cpylen - 1] = 0; return 0; }
bool EventHub::getEvent(int32_t* outDeviceId, int32_t* outType, int32_t* outScancode, int32_t* outKeycode, uint32_t *outFlags, int32_t* outValue, nsecs_t* outWhen) { *outDeviceId = 0; *outType = 0; *outScancode = 0; *outKeycode = 0; *outFlags = 0; *outValue = 0; *outWhen = 0; status_t err; fd_set readfds; int maxFd = -1; int cc; int i; int res; int pollres; struct input_event iev; // Note that we only allow one caller to getEvent(), so don't need // to do locking here... only when adding/removing devices. if (!mOpened) { mError = openPlatformInput() ? NO_ERROR : UNKNOWN_ERROR; mOpened = true; } while(1) { #ifdef HAVE_TSLIB //Checks if we have to send any more events read by input-raw plugin. if(!samp.total_events) { #endif // First, report any devices that had last been added/removed. if (mClosingDevices != NULL) { device_t* device = mClosingDevices; LOGV("Reporting device closed: id=0x%x, name=%s\n", device->id, device->path.string()); mClosingDevices = device->next; *outDeviceId = device->id; if (*outDeviceId == mFirstKeyboardId) *outDeviceId = 0; *outType = DEVICE_REMOVED; delete device; return true; } if (mOpeningDevices != NULL) { device_t* device = mOpeningDevices; LOGV("Reporting device opened: id=0x%x, name=%s\n", device->id, device->path.string()); mOpeningDevices = device->next; *outDeviceId = device->id; if (*outDeviceId == mFirstKeyboardId) *outDeviceId = 0; *outType = DEVICE_ADDED; return true; } release_wake_lock(WAKE_LOCK_ID); pollres = poll(mFDs, mFDCount, -1); acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID); if (pollres <= 0) { if (errno != EINTR) { LOGW("select failed (errno=%d)\n", errno); usleep(100000); } continue; } //printf("poll %d, returned %d\n", mFDCount, pollres); // mFDs[0] is used for inotify, so process regular events starting at mFDs[1] for(i = 1; i < mFDCount; i++) { if(mFDs[i].revents) { LOGV("revents for %d = 0x%08x", i, mFDs[i].revents); if(mFDs[i].revents & POLLIN) { #ifdef HAVE_TSLIB LOGV("Inside EventHub.cpp with mFDs[i].fd=%d \n", mFDs[i].fd); if (mTS != NULL) { if (mFDs[i].fd != mTS->fd ) { LOGV("mFDs[%d].fd = %d and mTS->fd = %d", i, mFDs[i].fd, mTS->fd); #endif res = read(mFDs[i].fd, &iev, sizeof(iev)); #ifdef HAVE_TSLIB } else{ LOGV("mTS->fd = %d", mTS->fd); LOGV("tslib: calling ts_read from eventhub\n"); res = ts_read(mTS, &samp, 1); if (res < 0) { LOGE("[EventHub.cpp:: After Poll] Error in ts_read()\n"); } else { numOfEventsSent = 0; samp.tsIndex = i; break; } } } else { LOGE("ERROR in setup of mTS: mTS is NULL!\n"); } #endif if (res == sizeof(iev) #ifdef HAVE_TSLIB || ((iev.code == 0x1d || iev.code == 0x1e) && res >= 0) #endif ) { LOGV("%s got: t0=%d, t1=%d, type=%d, code=%d, v=%d", mDevices[i]->path.string(), (int) iev.time.tv_sec, (int) iev.time.tv_usec, iev.type, iev.code, iev.value); *outDeviceId = mDevices[i]->id; if (*outDeviceId == mFirstKeyboardId) *outDeviceId = 0; *outType = iev.type; *outScancode = iev.code; if (iev.type == EV_KEY) { err = mDevices[i]->layoutMap->map(iev.code, outKeycode, outFlags); LOGV("iev.code=%d outKeycode=%d outFlags=0x%08x err=%d\n", iev.code, *outKeycode, *outFlags, err); if (err != 0) { *outKeycode = 0; *outFlags = 0; } } else { *outKeycode = iev.code; } *outValue = iev.value; *outWhen = s2ns(iev.time.tv_sec) + us2ns(iev.time.tv_usec); return true; } else { if (res<0) { LOGW("could not get event (errno=%d)", errno); } else { LOGE("could not get event (wrong size: %d)", res); } continue; } } } } // read_notify() will modify mFDs and mFDCount, so this must be done after // processing all other events. if(mFDs[0].revents & POLLIN) { read_notify(mFDs[0].fd); } #ifdef HAVE_TSLIB } if(samp.total_events) { *outDeviceId = mDevices[samp.tsIndex]->id; *outType = samp.ev[numOfEventsSent].type; *outScancode = samp.ev[numOfEventsSent].code; if (samp.ev[numOfEventsSent].type == EV_KEY) { err = mDevices[samp.tsIndex]->layoutMap->map(samp.ev[numOfEventsSent].code, outKeycode, outFlags); if (err != 0) { *outKeycode = 0; *outFlags = 0; } } else { *outKeycode = samp.ev[numOfEventsSent].code; } if(*outType == EV_ABS) { if(*outScancode == ABS_X) *outValue = samp.x; if(*outScancode == ABS_Y) *outValue = samp.y; if(*outScancode == ABS_PRESSURE) *outValue = samp.pressure; } else { *outValue = samp.ev[numOfEventsSent].value; *outWhen = s2ns(iev.time.tv_sec) + us2ns(iev.time.tv_usec); } if(++numOfEventsSent == samp.total_events) samp.total_events = 0; return true; } #endif } }
void draw_rectangles(cairo_t *fbcr, struct tsdev *ts, cairo_linuxfb_device_t *device) { int bufid = 1; /* start drawing into second buffer */ float r, g, b; int fbsizex = device->fb_vinfo.xres; int fbsizey = device->fb_vinfo.yres; int startx, starty, sizex, sizey; struct ts_sample sample; cairo_surface_t *surface; cairo_t *cr; float scale = 1.0f; surface = cairo_image_surface_create(CAIRO_FORMAT_RGB16_565, fbsizex, fbsizey); cr = cairo_create(surface); /* * We clear the cairo surface here before drawing * This is required in case something was drawn on this surface * previously, the previous contents would not be cleared without this. */ cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR); cairo_paint(cr); cairo_set_operator(cr, CAIRO_OPERATOR_OVER); srand(time(NULL)); while (!cancel) { r = (rand() % 100) / 100.0; g = (rand() % 100) / 100.0; b = (rand() % 100) / 100.0; startx = rand() % fbsizex; starty = rand() % fbsizey; sizex = rand() % (fbsizex - startx); sizey = rand() % (fbsizey - starty); cairo_identity_matrix(cr); if (ts) { int pressed = 0; /* Pressure is our identication whether we act on axis... */ while (ts_read(ts, &sample, 1)) { if (sample.pressure > 0) pressed = 1; } if (pressed) { scale *= 1.05f; cairo_translate(cr, sample.x, sample.y); cairo_scale(cr, scale, scale); //r = g = b = 0; startx = -5; starty = -5; sizex = 10; sizey = 10; } else { scale = 1.0f; } } cairo_set_source_rgb(cr, r, g, b); cairo_rectangle(cr, startx, starty, sizex, sizey); cairo_stroke_preserve(cr); cairo_fill(cr); /* Draw to framebuffer at y offset according to current buffer.. */ cairo_set_source_surface(fbcr, surface, 0, bufid * fbsizey); cairo_paint(fbcr); flip_buffer(device, 1, bufid); /* Switch buffer ID for next draw */ bufid = !bufid; usleep(20000); } /* Make sure we leave with buffer 0 enabled */ flip_buffer(device, 1, 0); /* Destroy and release all cairo related contexts */ cairo_destroy(cr); cairo_surface_destroy(surface); }