*************ipodhw.c**************** #include #include #include #include #include "ipodhw.h" static int version = -1; /** * Finds the hw-ID for the current iPod. * * 10000: iPod 1G * 20000: iPod 2G * 30000: iPod 3G * 40000: iPod Mini 1G * 50000: iPod 4G * 50013: iPod 4G * 60000: iPod Photo / Color * 60005: iPod Photo / Color Rev.2 * 70000: iPod Mini 2G * c0005: iPod Nano * ?????: iPod Video * * NOTE: These numbers are subject to change. This is not a complete list. */ static int get_ipod_hw_type(void) { if (version < 0) { int i; char cpuinfo[512]; char * ptr; FILE * file; if ((file = fopen("/proc/cpuinfo", "r")) != NULL) { while (fgets(cpuinfo, sizeof(cpuinfo), file) != NULL) if (strncmp(cpuinfo, "Revision", 8) == 0) break; fclose(file); } else { return 0; } for (i = 0; !isspace(cpuinfo[i]); i++); for (; isspace(cpuinfo[i]); i++); ptr = cpuinfo + i + 2; version = strtol(ptr, NULL, 16); } return version; } /** * Finds out the hardware specs. of the current iPod. */ void get_ipod_hw_info(hw_info * info) { info->flags = 0; switch (info->version = (get_ipod_hw_type() >> 16)) { case 0xb: /* iPod Video */ info->lcd_base = IPOD_VIDEO_LCD_BASE; info->lcd_busy_mask = IPOD_VIDEO_LCD_BUSY_MASK; info->lcd_width = IPOD_VIDEO_LCD_WIDTH; info->lcd_height = IPOD_VIDEO_LCD_HEIGHT; info->ipod_rtc = IPOD_PP5020_RTC; info->ipod_type = "iPod Video"; info->flags |= LCD_COLOR | LCD_VIDEO; break; case 0xc: /* iPod Nano */ info->lcd_base = IPOD_NANO_LCD_BASE; info->lcd_busy_mask = IPOD_NANO_LCD_BUSY_MASK; info->lcd_width = IPOD_NANO_LCD_WIDTH; info->lcd_height = IPOD_NANO_LCD_HEIGHT; info->ipod_rtc = IPOD_PP5020_RTC; info->ipod_type = "iPod Nano"; info->flags |= LCD_COLOR | LCD_TYPE_2; break; case 0x6: /* iPod Photo / Color */ info->lcd_base = IPOD_COLOR_LCD_BASE; info->lcd_busy_mask = IPOD_COL_LCD_BUSY_MASK; info->lcd_width = IPOD_COL_LCD_WIDTH; info->lcd_height = IPOD_COL_LCD_HEIGHT; info->ipod_rtc = IPOD_PP5020_RTC; info->ipod_type = "iPod Color"; info->flags |= LCD_COLOR; if(get_ipod_hw_type() == 0x60000) info->flags &= ~LCD_TYPE_2; // it's type 1, remove the flag else { int gpio_a01 = (inl(0x6000D030) & 0x02) >> 1; int gpio_a04 = (inl(0x6000D030) & 0x10) >> 4; if (((gpio_a01 << 1) | gpio_a04) == 0 || ((gpio_a01 << 1) | gpio_a04) == 2) { info->flags &= ~LCD_TYPE_2; // it's type 1, remove the flag } else { info->flags |= LCD_TYPE_2; // it's type 2 } } break; case 0x5: /* iPod 4G (gray)*/ info->lcd_base = IPOD_PP5020_LCD_BASE; info->lcd_busy_mask = IPOD_STD_LCD_BUSY_MASK; info->lcd_width = IPOD_STD_LCD_WIDTH; info->lcd_height = IPOD_STD_LCD_HEIGHT; info->ipod_rtc = IPOD_PP5020_RTC; info->ipod_type = "iPod 4G"; info->flags &= ~LCD_COLOR; break; case 0x7: /* iPod Mini 2G */ case 0x4: /* iPod Mini 1G */ info->lcd_width = IPOD_MINI_LCD_WIDTH; info->lcd_height = IPOD_MINI_LCD_HEIGHT; info->lcd_base = IPOD_PP5020_LCD_BASE; info->lcd_busy_mask = IPOD_STD_LCD_BUSY_MASK; info->ipod_rtc = IPOD_PP5020_RTC; info->ipod_type = "iPod Mini"; info->flags &= ~LCD_COLOR; break; case 0x3: /* iPod 3G */ case 0x2: /* iPod 2G */ case 0x1: /* iPod 1G */ info->lcd_width = IPOD_STD_LCD_WIDTH; info->lcd_height = IPOD_STD_LCD_HEIGHT; info->lcd_base = IPOD_PP5002_LCD_BASE; info->ipod_rtc = IPOD_PP5002_RTC; info->lcd_busy_mask = IPOD_STD_LCD_BUSY_MASK; info->ipod_type = "iPod"; info->flags &= ~LCD_COLOR; break; } } *********************keyHandler.c********************************** #include #include #include #include #include #include #include #include #include #include #include // For O_NONBLOCK #include "keyHandler.h" #define USE_WHEEL 255 #define WHEEL_SENS 254 static int consoleFd = -1; static struct termios old; static char keymap[60]; static boolean useWheelTurn = false; static char wheelSensitivity = 150; void finishWithMessage(char * msg) { fprintf(stderr, msg); closeKeyHandler(); exit(-1); } int startKeyHandler(void) { struct termios new; if ((consoleFd = open("/dev/console", O_NONBLOCK)) < 0) fprintf(stderr, "Could not open /dev/console"); if (tcgetattr(consoleFd, &old) < 0) fprintf(stderr, "Could not save old termios"); new = old; new.c_lflag &= ~(ICANON | ECHO | ISIG); new.c_iflag &= ~(ISTRIP | IGNCR | ICRNL | INLCR | IXOFF | IXON | BRKINT); new.c_cc[VMIN] = 0; new.c_cc[VTIME] = 0; if (tcsetattr(consoleFd, TCSAFLUSH, &new) < 0) finishWithMessage( "Could not set new termios"); if (ioctl(consoleFd, KDSKBMODE, K_MEDIUMRAW) < 0) finishWithMessage( "Could not set keyboardmode"); return 0; } void closeKeyHandler(void) { if (tcsetattr(consoleFd, TCSAFLUSH, &old) < 0) fprintf(stderr, "Could not reset old termios"); if (consoleFd > 2) if (close(consoleFd) < 0) fprintf(stderr, "Could not close console"); } int i_getKey(void) { int c = 0; if (read(consoleFd, &c, 1) != 1) c = -1; return c; } int getKeys(int buffsize, char* buff) { return read(consoleFd, buff, buffsize); } int tv_cmp(struct timeval *a, struct timeval *b) { if (a->tv_sec > b->tv_sec) return 1; if (a->tv_sec < b->tv_sec) return -1; if (a->tv_usec > b->tv_usec) return 1; if (a->tv_usec < b->tv_usec) return -1; return 0; } void tv_add(struct timeval *a, struct timeval *b) { a->tv_usec += b->tv_usec; a->tv_sec += b->tv_sec + (a->tv_usec / 1000000); a->tv_usec %= 1000000; } // is t1 greater than t2? int isGreaterThanTimeWithDiff( struct timeval * t1, struct timeval * t2, struct timeval * diff ) { if ((t1->tv_sec - t2->tv_sec) > diff->tv_sec) return 1; if ((t1->tv_sec - t2->tv_sec) == diff->tv_sec && (t1->tv_usec - t2->tv_usec) > diff->tv_usec) return 1; return 0; } int enhancedInput(struct timeval diff) { static int buff = 0; static int wheelDirection = 0; static struct timeval lastTime = {0, 0}; // Get key event. int c = i_getKey(); if (buff > 0) { int ret = buff; buff = c; c = ret; } if (wheelDirection != 0) { struct timeval now; struct timeval tmp = lastTime; gettimeofday(&now, 0); tv_add(&tmp, &diff); if (tv_cmp(&now, &tmp) == 1) { int dir = wheelDirection; buff = c; wheelDirection = 0; gettimeofday(&lastTime, 0); // NOTE: This should not be needed. return dir | KH_RELEASED; } } if(KEYCODE(c) == KH_WHEEL_L || KEYCODE(c) == KH_WHEEL_R) { gettimeofday(&lastTime, 0); if(wheelDirection != KEYCODE(c) && KEYSTATE(c) == KH_PRESSED) { int dir = wheelDirection; wheelDirection = KEYCODE(c); if (dir != 0) { buff = c; return dir | KH_RELEASED; } } else c = 0; } return c; } int getKey() { int button; if (useWheelTurn) { static struct timeval diff; diff.tv_sec = 0; diff.tv_usec = wheelSensitivity * 1000; button = enhancedInput(diff); } else button = i_getKey(); return button; }