static int input_callback(int fd, short revents, void *data) { struct input_event ev; int ret; int fake_key = 0; gr_surface surface = gVirtualKeys; ret = ev_get_input(fd, revents, &ev); if (ret) return -1; #ifdef BOARD_TOUCH_RECOVERY if (touch_handle_input(fd, ev)) return 0; #endif if (ev.type == EV_SYN) { return 0; } else if (ev.type == EV_REL) { if (ev.code == REL_Y) { // accumulate the up or down motion reported by // the trackball. When it exceeds a threshold // (positive or negative), fake an up/down // key event. rel_sum += ev.value; if (rel_sum > 3) { fake_key = 1; ev.type = EV_KEY; ev.code = KEY_DOWN; ev.value = 1; rel_sum = 0; } else if (rel_sum < -3) { fake_key = 1; ev.type = EV_KEY; ev.code = KEY_UP; ev.value = 1; rel_sum = 0; } } } else { rel_sum = 0; } if (ev.type == 3 && ev.code == 48 && ev.value != 0) { if (in_touch == 0) { in_touch = 1; //starting to track touch... reset_gestures(); } } else if (ev.type == 3 && ev.code == 48 && ev.value == 0) { //finger lifted! lets run with this ev.type = EV_KEY; //touch panel support!!! int keywidth = gr_get_width(surface) / 4; int keyoffset = (gr_fb_width() - gr_get_width(surface)) / 2; if (touch_y > (gr_fb_height() - gr_get_height(surface)) && touch_x > 0) { //they lifted in the touch panel region if (touch_x < (keywidth + keyoffset)) { //down button ev.code = KEY_DOWN; reset_gestures(); } else if (touch_x < ((keywidth * 2) + keyoffset)) { //up button ev.code = KEY_UP; reset_gestures(); } else if (touch_x < ((keywidth * 3) + keyoffset)) { //back button ev.code = KEY_BACK; reset_gestures(); } else { //enter key ev.code = KEY_ENTER; reset_gestures(); } vibrate(VIBRATOR_TIME_MS); } if (slide_right == 1) { ev.code = KEY_ENTER; slide_right = 0; } else if (slide_left == 1) { ev.code = KEY_BACK; slide_left = 0; } ev.value = 1; in_touch = 0; reset_gestures(); } else if (ev.type == 3 && ev.code == 53) { old_x = touch_x; touch_x = ev.value; if (old_x != 0) diff_x += touch_x - old_x; if (touch_y < (gr_fb_height() - gr_get_height(surface))) { if (diff_x > (gr_fb_width() / 4)) { slide_right = 1; reset_gestures(); } else if(diff_x < ((gr_fb_width() / 4) * -1)) { slide_left = 1; reset_gestures(); } } else { input_buttons(); //reset_gestures(); } } else if (ev.type == 3 && ev.code == 54) { old_y = touch_y; touch_y = ev.value; if (old_y != 0) diff_y += touch_y - old_y; if (touch_y < (gr_fb_height() - gr_get_height(surface))) { if (diff_y > 25) { ev.code = KEY_DOWN; ev.type = EV_KEY; reset_gestures(); } else if (diff_y < -25) { ev.code = KEY_UP; ev.type = EV_KEY; reset_gestures(); } } else { input_buttons(); //reset_gestures(); } } if (ev.type != EV_KEY || ev.code > KEY_MAX) return 0; pthread_mutex_lock(&key_queue_mutex); if (!fake_key) { // our "fake" keys only report a key-down event (no // key-up), so don't record them in the key_pressed // table. key_pressed[ev.code] = ev.value; } const int queue_max = sizeof(key_queue) / sizeof(key_queue[0]); if (ev.value > 0 && key_queue_len < queue_max) { key_queue[key_queue_len++] = ev.code; if (boardEnableKeyRepeat) { struct timeval now; gettimeofday(&now, NULL); key_press_time[ev.code] = (now.tv_sec * 1000) + (now.tv_usec / 1000); key_last_repeat[ev.code] = 0; } pthread_cond_signal(&key_queue_cond); } pthread_mutex_unlock(&key_queue_mutex); if (ev.value > 0 && device_toggle_display(key_pressed, ev.code)) { pthread_mutex_lock(&gUpdateMutex); show_text = !show_text; if (show_text) show_text_ever = 1; update_screen_locked(); pthread_mutex_unlock(&gUpdateMutex); } if (ev.value > 0 && device_reboot_now(key_pressed, ev.code)) { android_reboot(ANDROID_RB_RESTART, 0, 0); } return 0; }
// handle the user input events (mainly the touch events) inside the ui handler static void ui_handle_mouse_input(int* curPos) { pthread_mutex_lock(&key_queue_mutex); //In this case MENU_SELECT icon has maximum possible height. int menu_max_height = gr_get_height(gMenuIcon[MENU_SELECT]); struct { int x; int y; int xL; int xR; } MENU_ICON[] = { { gr_fb_width() - menu_max_height, 7*gr_fb_height()/8, 3*gr_fb_height()/4, 4*gr_fb_height()/4 }, { gr_fb_width() - menu_max_height, 5*gr_fb_height()/8, 2*gr_fb_height()/4, 3*gr_fb_height()/4 }, { gr_fb_width() - menu_max_height, 3*gr_fb_height()/8, 1*gr_fb_height()/4, 2*gr_fb_height()/4 }, { gr_fb_width() - menu_max_height, 1*gr_fb_height()/8, 0*gr_fb_height()/4, 1*gr_fb_height()/4 }, }; if (show_menu) { if (curPos[0] > 0) { int position = gr_fb_height() - curPos[1]; //ui_print("Pressure:%d\tX:%d\tY:%d\n",mousePos[0],mousePos[1],mousePos[2]); pthread_mutex_lock(&gUpdateMutex); if(position > MENU_ICON[MENU_BACK].xL && position < MENU_ICON[MENU_BACK].xR && selMenuIcon != MENU_BACK) { draw_icon_locked(gMenuIcon[selMenuIcon], MENU_ICON[selMenuIcon].x, MENU_ICON[selMenuIcon].y ); draw_icon_locked(gMenuIcon[MENU_BACK_M], MENU_ICON[MENU_BACK].x, MENU_ICON[MENU_BACK].y ); selMenuIcon = MENU_BACK; gr_flip(); } else if(position > MENU_ICON[MENU_DOWN].xL && position < MENU_ICON[MENU_DOWN].xR && selMenuIcon != MENU_DOWN) { draw_icon_locked(gMenuIcon[selMenuIcon], MENU_ICON[selMenuIcon].x, MENU_ICON[selMenuIcon].y ); draw_icon_locked(gMenuIcon[MENU_DOWN_M], MENU_ICON[MENU_DOWN].x, MENU_ICON[MENU_DOWN].y); selMenuIcon = MENU_DOWN; gr_flip(); } else if(position > MENU_ICON[MENU_UP].xL && position < MENU_ICON[MENU_UP].xR && selMenuIcon != MENU_UP) { draw_icon_locked(gMenuIcon[selMenuIcon], MENU_ICON[selMenuIcon].x, MENU_ICON[selMenuIcon].y ); draw_icon_locked(gMenuIcon[MENU_UP_M], MENU_ICON[MENU_UP].x, MENU_ICON[MENU_UP].y ); selMenuIcon = MENU_UP; gr_flip(); } else if(position > MENU_ICON[MENU_SELECT].xL && position < MENU_ICON[MENU_SELECT].xR && selMenuIcon != MENU_SELECT) { draw_icon_locked(gMenuIcon[selMenuIcon], MENU_ICON[selMenuIcon].x, MENU_ICON[selMenuIcon].y ); draw_icon_locked(gMenuIcon[MENU_SELECT_M], MENU_ICON[MENU_SELECT].x, MENU_ICON[MENU_SELECT].y ); selMenuIcon = MENU_SELECT; gr_flip(); } key_queue_len_back = key_queue_len; pthread_mutex_unlock(&gUpdateMutex); } } pthread_mutex_unlock(&key_queue_mutex); }
// Redraw everything on the screen. Does not flip pages. // Should only be called with gUpdateMutex locked. static void draw_screen_locked(void) { if (!ui_has_initialized) return; draw_background_locked(gCurrentIcon); draw_progress_locked(); if (show_text) { // don't "disable" the background anymore with this... // gr_color(0, 0, 0, 160); // gr_fill(0, 0, gr_fb_width(), gr_fb_height()); gr_surface surface = gVirtualKeys; int total_rows = (gr_fb_height() / CHAR_HEIGHT) - (gr_get_height(surface) / CHAR_HEIGHT) - 1; int i = 0; int j = 0; int offset = 0; // offset of separating bar under menus int row = 0; // current row that we are drawing on if (show_menu) { gr_color(MENU_TEXT_COLOR); int batt_level = 0; batt_level = get_batt_stats(); if (batt_level < 21) { gr_color(255, 0, 0, 255); } char batt_text[40]; sprintf(batt_text, "[%d%%]", batt_level); draw_text_line(0, batt_text, RIGHT_ALIGN); gr_color(MENU_TEXT_COLOR); gr_fill(0, (menu_top + menu_sel - menu_show_start) * CHAR_HEIGHT, gr_fb_width(), (menu_top + menu_sel - menu_show_start + 1)*CHAR_HEIGHT+1); gr_color(HEADER_TEXT_COLOR); for (i = 0; i < menu_top; ++i) { draw_text_line(i, menu[i], LEFT_ALIGN); row++; } if (menu_items - menu_show_start + menu_top >= max_menu_rows) j = max_menu_rows - menu_top; else j = menu_items - menu_show_start; gr_color(MENU_TEXT_COLOR); for (i = menu_show_start + menu_top; i < (menu_show_start + menu_top + j); ++i) { if (i == menu_top + menu_sel) { gr_color(255, 255, 255, 255); draw_text_line(i - menu_show_start , menu[i], LEFT_ALIGN); gr_color(MENU_TEXT_COLOR); } else { gr_color(MENU_TEXT_COLOR); draw_text_line(i - menu_show_start, menu[i], LEFT_ALIGN); } row++; if (row >= max_menu_rows) break; } if (menu_items <= max_menu_rows) offset = 0; gr_fill(0, (row-offset)*CHAR_HEIGHT+CHAR_HEIGHT/2-1, gr_fb_width(), (row-offset)*CHAR_HEIGHT+CHAR_HEIGHT/2+1); } gr_color(NORMAL_TEXT_COLOR); int cur_row = text_row; int available_rows = total_rows - row - 1; int start_row = row + 1; if (available_rows < MAX_ROWS) cur_row = (cur_row + (MAX_ROWS - available_rows)) % MAX_ROWS; else start_row = total_rows - MAX_ROWS; int r; for (r = 0; r < (available_rows < MAX_ROWS ? available_rows : MAX_ROWS); r++) { draw_text_line(start_row + r, text[(cur_row + r) % MAX_ROWS], LEFT_ALIGN); } } draw_virtualkeys_locked(); //added to draw the virtual keys }
static int input_callback(int fd, short revents, void *data) { struct input_event ev; int ret; int fake_key = 0; ret = ev_get_input(fd, revents, &ev); if (ret) return -1; input_device dev; dev.fd = fd; if(!dev.touch_calibrated) dev.touch_calibrated = calibrate_touch(&dev); if (ev.type == EV_SYN) { if (ev.code == SYN_MT_REPORT) { dev.saw_mt_report = 1; if (!dev.saw_mt_tracking_id) { if (dev.saw_pos_x && dev.saw_pos_y) { dev.saw_pos_x = 0; dev.saw_pos_y = 0; } else handle_release(&dev, &ev); } } } else if (ev.type == EV_REL) { if (ev.code == REL_Y) { // accumulate the up or down motion reported by // the trackball. When it exceeds a threshold // (positive or negative), fake an up/down // key event. rel_sum += ev.value; if (rel_sum > 3) { fake_key = 1; ev.type = EV_KEY; ev.code = KEY_DOWN; ev.value = 1; rel_sum = 0; } else if (rel_sum < -3) { fake_key = 1; ev.type = EV_KEY; ev.code = KEY_UP; ev.value = 1; rel_sum = 0; } } } else if (ev.type == EV_ABS) { switch(ev.code){ case ABS_MT_SLOT: dev.slot_current = ev.value; break; case ABS_MT_TRACKING_ID: dev.saw_mt_tracking_id = 1; dev.tracking_id = ev.value; if (dev.tracking_id == -1 && dev.slot_current == 0) handle_release(&dev, &ev); break; case ABS_MT_POSITION_X: dev.saw_pos_x = 1; if (dev.slot_current != 0) break; if(dev.touch_start.x == 0) dev.touch_start.x = dev.touch_pos.x; float touch_rel = (float)ev.value / ((float)dev.touch_max.x - (float)dev.touch_min.x); dev.touch_pos.x = touch_rel * gr_fb_width(); if (dev.touch_start.x == 0) break; //first touch. diff_x += dev.touch_pos.x - dev.touch_start.x; if (abs(diff_x) > abs(diff_y) && dev.touch_pos.y < (gr_fb_height() - virtualkey_h)) { if(diff_x > min_x_swipe_px) { dev.slide_right = 1; } else if (diff_x < -min_x_swipe_px) { dev.slide_left = 1; } } break; case ABS_MT_POSITION_Y: dev.saw_pos_y = 1; if (dev.slot_current != 0) break; if(dev.touch_start.y == 0) dev.touch_start.y = dev.touch_pos.y; touch_rel = (float)ev.value / ((float)dev.touch_max.y - (float)dev.touch_min.y); dev.touch_pos.y = touch_rel * gr_fb_height(); #ifdef USE_VIRTUAL_KEY ui_get_virtualkey_pressed(&dev); #endif if (dev.touch_start.y == 0) break; //first touch. diff_y += dev.touch_pos.y - dev.touch_start.y; if (abs(diff_y) >= abs(diff_x) && dev.touch_pos.y < (gr_fb_height() - virtualkey_h)) { if (diff_y > min_y_swipe_px) { ev.type = EV_KEY; ev.code = KEY_VOLUMEDOWN; ev.value = 2; reset_touch(&dev); } else if (diff_y < -min_y_swipe_px) { ev.type = EV_KEY; ev.code = KEY_VOLUMEUP; ev.value = 2; reset_touch(&dev); } } break; default: break; } } else if (ev.type == EV_KEY) { if (dev.saw_mt_report && dev.saw_mt_tracking_id && ev.code == BTN_TOUCH && ev.value == 0) handle_release(&dev, &ev); } else { rel_sum = 0; } if (ev.type != EV_KEY || ev.code > KEY_MAX) return 0; if (ev.value == 2) { boardEnableKeyRepeat = 0; } pthread_mutex_lock(&key_queue_mutex); if (!fake_key) { // our "fake" keys only report a key-down event (no // key-up), so don't record them in the key_pressed // table. key_pressed[ev.code] = ev.value; } const int queue_max = sizeof(key_queue) / sizeof(key_queue[0]); if (ev.value > 0 && key_queue_len < queue_max) { key_queue[key_queue_len++] = ev.code; if (boardEnableKeyRepeat) { struct timeval now; gettimeofday(&now, NULL); key_press_time[ev.code] = (now.tv_sec * 1000) + (now.tv_usec / 1000); key_last_repeat[ev.code] = 0; } pthread_cond_signal(&key_queue_cond); } pthread_mutex_unlock(&key_queue_mutex); if (ev.value > 0 && device_reboot_now(key_pressed, ev.code)) { reboot_main_system(ANDROID_RB_RESTART, 0, 0); } return 0; }
// Redraw everything on the screen. Does not flip pages. // Should only be called with gUpdateMutex locked. static void draw_screen_locked(void) { if (!ui_has_initialized) return; //In this case MENU_SELECT icon has maximum possible height. int menu_max_height = gr_get_height(gMenuIcon[MENU_SELECT]); struct { int x; int y; } MENU_ICON[] = { { gr_fb_width() - menu_max_height, 7*gr_fb_height()/8 }, { gr_fb_width() - menu_max_height, 5*gr_fb_height()/8 }, { gr_fb_width() - menu_max_height, 3*gr_fb_height()/8 }, { gr_fb_width() - menu_max_height, 1*gr_fb_height()/8 }, }; draw_background_locked(gCurrentIcon); draw_progress_locked(); if (show_text) { gr_color(0, 0, 0, 160); gr_fill(0, 0, gr_fb_width(), gr_fb_height()); int i = 0; int j = 0; int row = 0; // current row that we are drawing on if (show_menu) { draw_icon_locked(gMenuIcon[MENU_BACK], MENU_ICON[MENU_BACK].x, MENU_ICON[MENU_BACK].y ); draw_icon_locked(gMenuIcon[MENU_DOWN], MENU_ICON[MENU_DOWN].x, MENU_ICON[MENU_DOWN].y); draw_icon_locked(gMenuIcon[MENU_UP], MENU_ICON[MENU_UP].x, MENU_ICON[MENU_UP].y ); draw_icon_locked(gMenuIcon[MENU_SELECT], MENU_ICON[MENU_SELECT].x, MENU_ICON[MENU_SELECT].y ); gr_color(MENU_TEXT_COLOR); gr_fill(0, (menu_top + menu_sel - menu_show_start) * CHAR_HEIGHT, gr_fb_width()-menu_max_height*2, (menu_top + menu_sel - menu_show_start + 1)*CHAR_HEIGHT+1); gr_color(HEADER_TEXT_COLOR); for (i = 0; i < menu_top; ++i) { draw_text_line(i, menu[i]); row++; } if (menu_items - menu_show_start + menu_top >= MAX_ROWS) j = MAX_ROWS - menu_top; else j = menu_items - menu_show_start; gr_color(MENU_TEXT_COLOR); for (i = menu_show_start + menu_top; i < (menu_show_start + menu_top + j); ++i) { if (i == menu_top + menu_sel) { gr_color(255, 255, 255, 255); draw_text_line(i - menu_show_start , menu[i]); gr_color(MENU_TEXT_COLOR); } else { gr_color(MENU_TEXT_COLOR); draw_text_line(i - menu_show_start, menu[i]); } row++; } gr_fill(0, row*CHAR_HEIGHT+CHAR_HEIGHT/2-1, gr_fb_width()-menu_max_height*2, row*CHAR_HEIGHT+CHAR_HEIGHT/2+1); } gr_color(NORMAL_TEXT_COLOR); for (; row < text_rows; ++row) { draw_text_line(row, text[(row+text_top) % text_rows]); } } }
/* Returns non-zero when the event should be consumed */ static int vk_modify(struct ev *e, struct input_event *ev) { static int downX = -1, downY = -1; static int discard = 0; static int last_virt_key = 0; static int lastWasSynReport = 0; static int touchReleaseOnNextSynReport = 0; static int use_tracking_id_negative_as_touch_release = 0; // On some devices, type: 3 code: 39 value: -1, aka EV_ABS ABS_MT_TRACKING_ID -1 indicates a true touch release int i; int x, y; // This is used to ditch useless event handlers, like an accelerometer if (e->ignored) return 1; if (ev->type == EV_REL && ev->code == REL_Z) { // This appears to be an accelerometer or another strange input device. It's not the touchscreen. #ifdef _EVENT_LOGGING printf("EV: Device disabled due to non-touchscreen messages.\n"); #endif e->ignored = 1; return 1; } #ifdef _EVENT_LOGGING printf("EV: %s => type: %x code: %x value: %d\n", e->deviceName, ev->type, ev->code, ev->value); #endif // Handle keyboard events, value of 1 indicates key down, 0 indicates key up if (ev->type == EV_KEY) { return 0; } if (ev->type == EV_ABS) { switch (ev->code) { case ABS_X: //00 e->p.synced |= 0x01; e->p.x = ev->value; #ifdef _EVENT_LOGGING printf("EV: %s => EV_ABS ABS_X %d\n", e->deviceName, ev->value); #endif break; case ABS_Y: //01 e->p.synced |= 0x02; e->p.y = ev->value; #ifdef _EVENT_LOGGING printf("EV: %s => EV_ABS ABS_Y %d\n", e->deviceName, ev->value); #endif break; case ABS_MT_POSITION: //2a e->mt_p.synced = 0x03; if (ev->value == (1 << 31)) { e->mt_p.x = 0; e->mt_p.y = 0; lastWasSynReport = 1; } else { lastWasSynReport = 0; e->mt_p.x = (ev->value & 0x7FFF0000) >> 16; e->mt_p.y = (ev->value & 0xFFFF); } break; case ABS_MT_TOUCH_MAJOR: //30 if (ev->value == 0) { #ifndef TW_IGNORE_MAJOR_AXIS_0 // We're in a touch release, although some devices will still send positions as well e->mt_p.x = 0; e->mt_p.y = 0; touchReleaseOnNextSynReport = 1; #endif } #ifdef _EVENT_LOGGING printf("EV: %s => EV_ABS ABS_MT_TOUCH_MAJOR %d\n", e->deviceName, ev->value); #endif break; case ABS_MT_PRESSURE: //3a if (ev->value == 0) { // We're in a touch release, although some devices will still send positions as well e->mt_p.x = 0; e->mt_p.y = 0; touchReleaseOnNextSynReport = 1; } #ifdef _EVENT_LOGGING printf("EV: %s => EV_ABS ABS_MT_PRESSURE %d\n", e->deviceName, ev->value); #endif break; case ABS_MT_POSITION_X: //35 e->mt_p.synced |= 0x01; e->mt_p.x = ev->value; #ifdef _EVENT_LOGGING printf("EV: %s => EV_ABS ABS_MT_POSITION_X %d\n", e->deviceName, ev->value); #endif break; case ABS_MT_POSITION_Y: //36 e->mt_p.synced |= 0x02; e->mt_p.y = ev->value; #ifdef _EVENT_LOGGING printf("EV: %s => EV_ABS ABS_MT_POSITION_Y %d\n", e->deviceName, ev->value); #endif break; case ABS_MT_TOUCH_MINOR: //31 #ifdef _EVENT_LOGGING printf("EV: %s => EV_ABS ABS_MT_TOUCH_MINOR %d\n", e->deviceName, ev->value); #endif break; case ABS_MT_WIDTH_MAJOR: //32 #ifdef _EVENT_LOGGING printf("EV: %s => EV_ABS ABS_MT_WIDTH_MAJOR %d\n", e->deviceName, ev->value); #endif break; case ABS_MT_WIDTH_MINOR: //33 #ifdef _EVENT_LOGGING printf("EV: %s => EV_ABS ABS_MT_WIDTH_MINOR %d\n", e->deviceName, ev->value); #endif break; case ABS_MT_TRACKING_ID: //39 if (ev->value < 0) { e->mt_p.x = 0; e->mt_p.y = 0; touchReleaseOnNextSynReport = 2; use_tracking_id_negative_as_touch_release = 1; #ifdef _EVENT_LOGGING if (use_tracking_id_negative_as_touch_release) printf("using ABS_MT_TRACKING_ID value -1 to indicate touch releases\n"); #endif } #ifdef _EVENT_LOGGING printf("EV: %s => EV_ABS ABS_MT_TRACKING_ID %d\n", e->deviceName, ev->value); #endif break; #ifdef _EVENT_LOGGING // These are for touch logging purposes only case ABS_MT_ORIENTATION: //34 printf("EV: %s => EV_ABS ABS_MT_ORIENTATION %d\n", e->deviceName, ev->value); return 1; break; case ABS_MT_TOOL_TYPE: //37 LOGI("EV: %s => EV_ABS ABS_MT_TOOL_TYPE %d\n", e->deviceName, ev->value); return 1; break; case ABS_MT_BLOB_ID: //38 printf("EV: %s => EV_ABS ABS_MT_BLOB_ID %d\n", e->deviceName, ev->value); return 1; break; case ABS_MT_DISTANCE: //3b printf("EV: %s => EV_ABS ABS_MT_DISTANCE %d\n", e->deviceName, ev->value); return 1; break; #endif default: // This is an unhandled message, just skip it return 1; } if (ev->code != ABS_MT_POSITION) { lastWasSynReport = 0; return 1; } } // Check if we should ignore the message if (ev->code != ABS_MT_POSITION && (ev->type != EV_SYN || (ev->code != SYN_REPORT && ev->code != SYN_MT_REPORT))) { lastWasSynReport = 0; return 0; } #ifdef _EVENT_LOGGING if (ev->type == EV_SYN && ev->code == SYN_REPORT) printf("EV: %s => EV_SYN SYN_REPORT\n", e->deviceName); if (ev->type == EV_SYN && ev->code == SYN_MT_REPORT) printf("EV: %s => EV_SYN SYN_MT_REPORT\n", e->deviceName); #endif // Discard the MT versions if (ev->code == SYN_MT_REPORT) return 0; if (((lastWasSynReport == 1 || touchReleaseOnNextSynReport == 1) && !use_tracking_id_negative_as_touch_release) || (use_tracking_id_negative_as_touch_release && touchReleaseOnNextSynReport == 2)) { // Reset the value touchReleaseOnNextSynReport = 0; // We are a finger-up state if (!discard) { // Report the key up ev->type = EV_ABS; ev->code = 0; ev->value = (downX << 16) | downY; } downX = -1; downY = -1; if (discard) { discard = 0; // Send the keyUp event ev->type = EV_KEY; ev->code = last_virt_key; ev->value = 0; } return 0; } lastWasSynReport = 1; // Retrieve where the x,y position is if (e->p.synced & 0x03) { vk_tp_to_screen(&e->p, &x, &y); } else if (e->mt_p.synced & 0x03) { vk_tp_to_screen(&e->mt_p, &x, &y); } else { // We don't have useful information to convey return 1; } #ifdef RECOVERY_TOUCHSCREEN_SWAP_XY x ^= y; y ^= x; x ^= y; #endif #ifdef RECOVERY_TOUCHSCREEN_FLIP_X x = gr_fb_width() - x; #endif #ifdef RECOVERY_TOUCHSCREEN_FLIP_Y y = gr_fb_height() - y; #endif #ifdef _EVENT_LOGGING printf("EV: x: %d y: %d\n", x, y); #endif // Clear the current sync states e->p.synced = e->mt_p.synced = 0; // If we have nothing useful to report, skip it if (x == -1 || y == -1) return 1; // On first touch, see if we're at a virtual key if (downX == -1) { // Attempt mapping to virtual key for (i = 0; i < e->vk_count; ++i) { int xd = ABS(e->vks[i].centerx - x); int yd = ABS(e->vks[i].centery - y); if (xd < e->vks[i].width/2 && yd < e->vks[i].height/2) { ev->type = EV_KEY; ev->code = e->vks[i].scancode; ev->value = 1; last_virt_key = e->vks[i].scancode; vibrate(VIBRATOR_TIME_MS); // Mark that all further movement until lift is discard, // and make sure we don't come back into this area discard = 1; downX = 0; return 0; } } } // If we were originally a button press, discard this event if (discard) { return 1; } // Record where we started the touch for deciding if this is a key or a scroll downX = x; downY = y; ev->type = EV_ABS; ev->code = 1; ev->value = (x << 16) | y; return 0; }
/* Returns non-zero when the event should be consumed */ static int vk_modify(struct ev *e, struct input_event *ev) { int i; int x, y; if (ev->type == EV_KEY) { if (ev->code == BTN_TOUCH) e->p.pressed = ev->value; return 0; } if (ev->type == EV_ABS) { switch (ev->code) { case ABS_X: e->p.x = ev->value; return !vk_inside_display(e->p.x, &e->p.xi, gr_fb_width()); case ABS_Y: e->p.y = ev->value; return !vk_inside_display(e->p.y, &e->p.yi, gr_fb_height()); case ABS_MT_POSITION_X: if (e->mt_idx) return 1; e->mt_p.x = ev->value; return !vk_inside_display(e->mt_p.x, &e->mt_p.xi, gr_fb_width()); case ABS_MT_POSITION_Y: if (e->mt_idx) return 1; e->mt_p.y = ev->value; return !vk_inside_display(e->mt_p.y, &e->mt_p.yi, gr_fb_height()); case ABS_MT_TOUCH_MAJOR: if (e->mt_idx) return 1; if (e->sent) e->mt_p.pressed = (ev->value > 0); else e->mt_p.pressed = (ev->value > PRESS_THRESHHOLD); return 0; } return 0; } if (ev->type != EV_SYN) return 0; if (ev->code == SYN_MT_REPORT) { /* Ignore the rest of the points */ ++e->mt_idx; return 1; } if (ev->code != SYN_REPORT) return 0; /* Report complete */ e->mt_idx = 0; if (!e->p.pressed && !e->mt_p.pressed) { /* No touch */ e->sent = 0; return 0; } if (!(e->p.pressed && vk_tp_to_screen(&e->p, &x, &y)) && !(e->mt_p.pressed && vk_tp_to_screen(&e->mt_p, &x, &y))) { /* No touch inside vk area */ return 0; } if (e->sent) { /* We've already sent a fake key for this touch */ return 1; } /* The screen is being touched on the vk area */ e->sent = 1; for (i = 0; i < e->vk_count; ++i) { int xd = ABS(e->vks[i].centerx - x); int yd = ABS(e->vks[i].centery - y); if (xd < e->vks[i].width/2 && yd < e->vks[i].height/2) { /* Fake a key event */ ev->type = EV_KEY; ev->code = e->vks[i].scancode; ev->value = 1; vibrate(VIBRATOR_TIME_MS); return 0; } } return 1; }
void gr_noclip() { GGLContext *gl = gr_context; gl->scissor(gl, 0, 0, gr_fb_width(), gr_fb_height()); gl->disable(gl, GGL_SCISSOR_TEST); }
// Redraw everything on the screen. Does not flip pages. // Should only be called with gUpdateMutex locked. static void draw_screen_locked(void) { if (!ui_has_initialized) return; draw_background_locked(gCurrentIcon); draw_progress_locked(); if (show_text) { // don't "disable" the background anymore with this... // gr_color(0, 0, 0, 160); // gr_fill(0, 0, gr_fb_width(), gr_fb_height()); int total_rows = gr_fb_height() / CHAR_HEIGHT; int i = 0; int j = 0; int row = 0; // current row that we are drawing on if (show_menu) { #ifndef BOARD_TOUCH_RECOVERY gr_color(MENU_TEXT_COLOR); // 添加电量时间显示 int batt_level = 0; batt_level = get_batt_stats(); if(batt_level < 20) { gr_color(255, 0, 0, 255); } struct tm *current; time_t now; now = time(NULL) + (3600 * 8); // add 8 hours current = localtime(&now); char batt_text[40]; sprintf(batt_text, "[%d%% %02D:%02D]", batt_level, current->tm_hour, current->tm_min); if (now == NULL) { // just in case sprintf(batt_text, "[%d%%]", batt_level); } gr_color(MENU_TEXT_COLOR); draw_text_line(0, batt_text, RIGHT_ALIGN); gr_fill(0, (menu_top + menu_sel - menu_show_start) * CHAR_HEIGHT, gr_fb_width(), (menu_top + menu_sel - menu_show_start + 1)*CHAR_HEIGHT+1); gr_color(HEADER_TEXT_COLOR); for (i = 0; i < menu_top; ++i) { // 添加电量时间显示 // draw_text_line(i, menu[i]); draw_text_line(i, menu[i], LEFT_ALIGN); row++; } if (menu_items - menu_show_start + menu_top >= max_menu_rows) j = max_menu_rows - menu_top; else j = menu_items - menu_show_start; gr_color(MENU_TEXT_COLOR); for (i = menu_show_start + menu_top; i < (menu_show_start + menu_top + j); ++i) { if (i == menu_top + menu_sel) { gr_color(255, 255, 255, 255); // 添加电量时间显示 // draw_text_line(i - menu_show_start , menu[i]); draw_text_line(i - menu_show_start , menu[i], LEFT_ALIGN); gr_color(MENU_TEXT_COLOR); } else { gr_color(MENU_TEXT_COLOR); // 添加电量时间显示 // draw_text_line(i - menu_show_start, menu[i]); draw_text_line(i - menu_show_start, menu[i], LEFT_ALIGN); } row++; if (row >= max_menu_rows) break; } gr_fill(0, row*CHAR_HEIGHT+CHAR_HEIGHT/2-1, gr_fb_width(), row*CHAR_HEIGHT+CHAR_HEIGHT/2+1); #else row = draw_touch_menu(menu, menu_items, menu_top, menu_sel, menu_show_start); #endif } gr_color(NORMAL_TEXT_COLOR); int cur_row = text_row; int available_rows = total_rows - row - 1; int start_row = row + 1; if (available_rows < MAX_ROWS) cur_row = (cur_row + (MAX_ROWS - available_rows)) % MAX_ROWS; else start_row = total_rows - MAX_ROWS; int r; for (r = 0; r < (available_rows < MAX_ROWS ? available_rows : MAX_ROWS); r++) { // 添加电量时间显示 // draw_text_line(start_row + r, text[(cur_row + r) % MAX_ROWS]); draw_text_line(start_row + r, text[(cur_row + r) % MAX_ROWS], LEFT_ALIGN); } } }
int ScreenRecoveryUI::GetProgressBaseline() { return gr_fb_height() - PixelsFromDp(is_large_ ? 340 : 194) - gr_get_height(progressBarFill); }
void swipe_handle_input(int fd, struct input_event *ev) { int abs_store[6] = {0}; int k; set_min_swipe_lengths(); ioctl(fd, EVIOCGABS(ABS_MT_POSITION_X), abs_store); int max_x_touch = abs_store[2]; ioctl(fd, EVIOCGABS(ABS_MT_POSITION_Y), abs_store); int max_y_touch = abs_store[2]; if(ev->type == EV_ABS && ev->code == ABS_MT_TRACKING_ID) { if(in_touch == 0) { in_touch = 1; reset_gestures(); } else { // finger lifted ev->type = EV_KEY; if(slide_right == 1) { ev->code = KEY_POWER; slide_right = 0; } else if(slide_left == 1) { ev->code = KEY_BACK; slide_left = 0; } ev->value = 1; in_touch = 0; reset_gestures(); } } else if(ev->type == EV_ABS && ev->code == ABS_MT_POSITION_X) { old_x = touch_x; float touch_x_rel = (float)ev->value / (float)max_x_touch; touch_x = touch_x_rel * gr_fb_width(); if(old_x != 0) diff_x += touch_x - old_x; if(diff_x > min_x_swipe_px) { slide_right = 1; reset_gestures(); } else if(diff_x < -min_x_swipe_px) { slide_left = 1; reset_gestures(); } } else if(ev->type == EV_ABS && ev->code == ABS_MT_POSITION_Y) { old_y = touch_y; float touch_y_rel = (float)ev->value / (float)max_y_touch; touch_y = touch_y_rel * gr_fb_height(); if(old_y != 0) diff_y += touch_y - old_y; if(diff_y > min_y_swipe_px) { ev->code = KEY_VOLUMEDOWN; ev->type = EV_KEY; reset_gestures(); } else if(diff_y < -min_y_swipe_px) { ev->code = KEY_VOLUMEUP; ev->type = EV_KEY; reset_gestures(); } } return; }
// Redraw everything on the screen. Does not flip pages. // Should only be called with gUpdateMutex locked. // joeykrim-all the LOGI help me keep my sanity static void draw_screen_locked(void) { draw_background_locked(gCurrentIcon); draw_progress_locked(); if (show_text) { gr_color(0, 0, 0, 160); gr_fill(0, 0, gr_fb_width(), gr_fb_height()); int i = 0, j = 0; int k = menu_top + 1; //counter for bottom horizontal text line location if (show_menu) { //LOGI("text_rows: %i\n", text_rows); //LOGI("menu_items: %i\n", menu_items); //LOGI("menu_top: %i\n", menu_top); //LOGI("menu_show_start: %i\n", menu_show_start); //menu line item selection highlight draws gr_color(mihc.r, mihc.g, mihc.b, mihc.a); gr_fill(0, (menu_top + menu_sel - menu_show_start+1) * CHAR_HEIGHT, gr_fb_width(), (menu_top + menu_sel - menu_show_start + 2)*CHAR_HEIGHT+1); //draw semi-static headers for (i = 0; i < menu_top; ++i) { gr_color(htc.r, htc.g, htc.b, htc.a); draw_text_line(i, menu[i]); //LOGI("Semi-static headers internal counter i: %i\n", i); } //LOGI("Drawing horizontal start bar at k and k = %i\n", k); gr_color(mhebc.r, mhebc.g, mhebc.b, mhebc.a); //draws horizontal line at bottom of the menu gr_fill(0, (k-1)*CHAR_HEIGHT+CHAR_HEIGHT/2-1, gr_fb_width(), (k-1)*CHAR_HEIGHT+CHAR_HEIGHT/2+1); //adjust counter for current position of selection and menu display starting point if (menu_items - menu_show_start + menu_top >= text_rows){ j = text_rows - menu_top; //LOGI("j = text_rows - mneu_top and j = %i\n", j); } else { j = menu_items - menu_show_start; //LOGI("j = mneu_items - menu_show_start and j = %i\n", j); } //LOGI("outside draw menu items for loop and i goes until limit. limit-menu_show_start + menu_top + j = %i\n", menu_show_start + menu_top + j); //draw menu items dynamically based on current menu starting position, menu selection point and headers for (i = menu_show_start + menu_top; i < (menu_show_start + menu_top + j); ++i) { //LOGI("inside draw menu items for loop and i = %i\n", i); if (i == menu_top + menu_sel) { gr_color(miwhc.r, miwhc.g, miwhc.b, miwhc.a); //LOGI("draw_text_line -menu_item_when_highlighted_color- at i + 1= %i\n", i+1); draw_text_line(i - menu_show_start +1, menu[i]); } else { gr_color(mtc.r, mtc.g, mtc.b, mtc.a); //LOGI("draw_text_line -menu_item_color- at i + 1= %i\n", i+1); draw_text_line(i - menu_show_start +1, menu[i]); } //LOGI("inside draw menu items for loop and k = %i\n", k); k++; } //LOGI("drawing horizontal end bar at k and k = %i\n", k); gr_color(mhebc.r, mhebc.g, mhebc.b, mhebc.a); //draws horizontal line at bottom of the menu gr_fill(0, k*CHAR_HEIGHT+CHAR_HEIGHT/2-1, gr_fb_width(), k*CHAR_HEIGHT+CHAR_HEIGHT/2+1); } k++; //keep ui_print below menu items display gr_color(upc.r, upc.g, upc.b, upc.a); //called by at least ui_print for (; k < text_rows; ++k) { draw_text_line(k, text[(k+text_top) % text_rows]); } } }
// Redraw everything on the screen. Does not flip pages. // Should only be called with gUpdateMutex locked. static void draw_screen_locked(void) { draw_background_locked(gCurrentIcon); draw_progress_locked(); if (show_text) { gr_color(0, 0, 0, 160); gr_fill(0, 0, gr_fb_width(), gr_fb_height()); int i = 0; int j = 0; int row = 0; if (show_menu) { gr_color(MENU_TEXT_COLOR); gr_fill(0, (menu_top + menu_sel - menu_show_start) * CHAR_HEIGHT, gr_fb_width(), (menu_top + menu_sel - menu_show_start + 1)*CHAR_HEIGHT+1); for (i = 0; i < menu_top; ++i) { draw_text_line(i, menu[i]); row++; } if (menu_items - menu_show_start + menu_top >= MAX_ROWS) j = MAX_ROWS - menu_top; else j = menu_items - menu_show_start; gr_color(MENU_TEXT_COLOR); for (i = menu_show_start + menu_top; i < (menu_show_start + menu_top + j); ++i) { if (i == menu_top + menu_sel) { gr_color(SELECTED_TEXT_COLOR); draw_text_line(i - menu_show_start, menu[i]); gr_color(MENU_TEXT_COLOR); } else { gr_color(MENU_TEXT_COLOR); draw_text_line(i - menu_show_start, menu[i]); } row++; } gr_fill(0, row*CHAR_HEIGHT+CHAR_HEIGHT/2-1, gr_fb_width(), row*CHAR_HEIGHT+CHAR_HEIGHT/2+1); } gr_color(NORMAL_TEXT_COLOR); row++; for (; row < text_rows; ++row) { draw_text_line(row, text[(row+text_top) % text_rows]); } } }
// Redraw everything on the screen. Does not flip pages. // Should only be called with gUpdateMutex locked. void draw_screen_locked(void) { if (!ui_has_initialized) return; #ifdef BUILD_IN_LANDSCAPE //In this case MENU_SELECT icon has maximum possible height. int menu_max_height = gr_get_height(gMenuIcon[MENU_SELECT]); struct { int x; int y; } MENU_ICON[] = { { gr_fb_width() - menu_max_height, 7*gr_fb_height()/8 }, { gr_fb_width() - menu_max_height, 5*gr_fb_height()/8 }, { gr_fb_width() - menu_max_height, 3*gr_fb_height()/8 }, { gr_fb_width() - menu_max_height, 1*gr_fb_height()/8 }, #else //ToDo: Following structure should be global struct { int x; int y; int xL; int xR; } MENU_ICON[] = { { get_menu_icon_info(MENU_BACK,MENU_ICON_X), get_menu_icon_info(MENU_BACK,MENU_ICON_Y), get_menu_icon_info(MENU_BACK,MENU_ICON_XL), get_menu_icon_info(MENU_BACK,MENU_ICON_XR) }, { get_menu_icon_info(MENU_DOWN,MENU_ICON_X), get_menu_icon_info(MENU_DOWN,MENU_ICON_Y), get_menu_icon_info(MENU_DOWN,MENU_ICON_XL), get_menu_icon_info(MENU_DOWN,MENU_ICON_XR) }, { get_menu_icon_info(MENU_UP,MENU_ICON_X), get_menu_icon_info(MENU_UP,MENU_ICON_Y), get_menu_icon_info(MENU_UP,MENU_ICON_XL), get_menu_icon_info(MENU_UP,MENU_ICON_XR) }, { get_menu_icon_info(MENU_SELECT,MENU_ICON_X), get_menu_icon_info(MENU_SELECT,MENU_ICON_Y), get_menu_icon_info(MENU_SELECT,MENU_ICON_XL), get_menu_icon_info(MENU_SELECT,MENU_ICON_XR) }, #endif }; draw_background_locked(gCurrentIcon); draw_progress_locked(); if (show_text) { gr_color(0, 0, 0, 160); gr_fill(0, 0, gr_fb_width(), gr_fb_height()); int total_rows = gr_fb_height() / CHAR_HEIGHT+1; int i = 0; int j = 0; int row = 0; // current row that we are drawing on if (show_menu) { draw_icon_locked(gMenuIcon[MENU_BACK], MENU_ICON[MENU_BACK].x, MENU_ICON[MENU_BACK].y ); draw_icon_locked(gMenuIcon[MENU_DOWN], MENU_ICON[MENU_DOWN].x, MENU_ICON[MENU_DOWN].y); draw_icon_locked(gMenuIcon[MENU_UP], MENU_ICON[MENU_UP].x, MENU_ICON[MENU_UP].y ); draw_icon_locked(gMenuIcon[MENU_SELECT], MENU_ICON[MENU_SELECT].x, MENU_ICON[MENU_SELECT].y ); // Setup our text colors gr_color(UICOLOR0, UICOLOR1, UICOLOR2, 255); gr_color(UICOLOR0, UICOLOR1, UICOLOR2, 255); gr_fill(0, (menu_top + menu_sel - menu_show_start) * CHAR_HEIGHT, #ifdef BUILD_IN_LANDSCAPE gr_fb_width()-menu_max_height*2, (menu_top + menu_sel - menu_show_start + 1)*CHAR_HEIGHT+1); #else gr_fb_width(), (menu_top + menu_sel - menu_show_start + 1)*CHAR_HEIGHT+1); #endif gr_color(HEADER_TEXT_COLOR); for (i = 0; i < menu_top; ++i) { draw_text_line(i, menu[i], LEFT_ALIGN); row++; } if (menu_items - menu_show_start + menu_top >= MAX_ROWS) j = MAX_ROWS - menu_top; else j = menu_items - menu_show_start; gr_color(UICOLOR0, UICOLOR1, UICOLOR2, 255); for (i = menu_show_start + menu_top; i < (menu_show_start + menu_top + j); ++i) { if (i == menu_top + menu_sel) { gr_color(255, 255, 255, 255); draw_text_line(i - menu_show_start , menu[i], LEFT_ALIGN); gr_color(UICOLOR0, UICOLOR1, UICOLOR2, 255); } else { gr_color(UICOLOR0, UICOLOR1, UICOLOR2, 255); draw_text_line(i - menu_show_start, menu[i], LEFT_ALIGN); } row++; if (row >= max_menu_rows) break; } gr_fill(0, row*CHAR_HEIGHT+CHAR_HEIGHT/2-1, #ifdef BUILD_IN_LANDSCAPE gr_fb_width()-menu_max_height*2, row*CHAR_HEIGHT+CHAR_HEIGHT/2+1); #else gr_fb_width(), row*CHAR_HEIGHT+CHAR_HEIGHT/2+1); #endif } gr_color(NORMAL_TEXT_COLOR); for (; row < text_rows; ++row) { draw_text_line(row + 1, text[(row+text_top) % text_rows], LEFT_ALIGN); } } }
// Redraw everything on the screen. Does not flip pages. // Should only be called with gUpdateMutex locked. static void draw_screen_locked(void) { if (!ui_has_initialized) return; draw_background_locked(gCurrentIcon); draw_progress_locked(); if (show_text) { // don't "disable" the background anymore with this... // gr_color(0, 0, 0, 160); // gr_fill(0, 0, gr_fb_width(), gr_fb_height()); int total_rows = gr_fb_height() / CHAR_HEIGHT; int i = 0; int j = 0; int row = 0; // current row that we are drawing on if (show_menu) { #ifndef BOARD_TOUCH_RECOVERY gr_color(MENU_TEXT_COLOR); gr_fill(0, (menu_top + menu_sel - menu_show_start) * CHAR_HEIGHT, gr_fb_width(), (menu_top + menu_sel - menu_show_start + 1)*CHAR_HEIGHT+1); gr_color(HEADER_TEXT_COLOR); for (i = 0; i < menu_top; ++i) { draw_text_line(i, menu[i]); row++; } if (menu_items - menu_show_start + menu_top >= max_menu_rows) j = max_menu_rows - menu_top; else j = menu_items - menu_show_start; gr_color(MENU_TEXT_COLOR); for (i = menu_show_start + menu_top; i < (menu_show_start + menu_top + j); ++i) { if (i == menu_top + menu_sel) { gr_color(255, 255, 255, 255); draw_text_line(i - menu_show_start , menu[i]); gr_color(MENU_TEXT_COLOR); } else { gr_color(MENU_TEXT_COLOR); draw_text_line(i - menu_show_start, menu[i]); } row++; if (row >= max_menu_rows) break; } gr_fill(0, row*CHAR_HEIGHT+CHAR_HEIGHT/2-1, gr_fb_width(), row*CHAR_HEIGHT+CHAR_HEIGHT/2+1); #else row = draw_touch_menu(menu, menu_items, menu_top, menu_sel, menu_show_start); #endif } gr_color(NORMAL_TEXT_COLOR); int cur_row = text_row; int available_rows = total_rows - row - 1; int start_row = row + 1; if (available_rows < MAX_ROWS) cur_row = (cur_row + (MAX_ROWS - available_rows)) % MAX_ROWS; else start_row = total_rows - MAX_ROWS; int r; for (r = 0; r < (available_rows < MAX_ROWS ? available_rows : MAX_ROWS); r++) { draw_text_line(start_row + r, text[(cur_row + r) % MAX_ROWS]); } } }
static void sensor_magnetometer_indication(module_info * mod, layout * layout) { int w = gr_fb_width(); int h = gr_fb_height(); int centre_x = w / 2; int centre_y = 2 * h / 3; int radius = w / 4; int origin_x = 0; int origin_y = 0; int i = 0; int temp = 0; char x[SIZE_1K] = { 0 }; char y[SIZE_1K] = { 0 }; char z[SIZE_1K] = { 0 }; char angle[8] = { 0 }; double x_temp = 0; double y_temp = 0; double z_temp = 0; rect_t rect; button *btn[ROUND_ANGLE]; for(i = 0; i < ROUND_ANGLE; i++) { origin_x = radius * sin((i * M_PI / 180) + (M_PI / 2)); origin_y = radius * cos((i * M_PI / 180) + (M_PI / 2)); rect.x = centre_x + origin_x - ROUND_POINT_HALF_SIDE; rect.y = centre_y - origin_y - ROUND_POINT_HALF_SIDE; rect.w = ROUND_POINT_SIDE; rect.h = ROUND_POINT_SIDE; snprintf(angle, sizeof(angle), "%d", i); btn[i] = new button(angle, rect, "", NULL); btn[i]->set_color(COLOR_BLUE); layout->add_button_locked(btn[i]); } do { sem_wait(&g_data_print_sem); parse_sensors_xyz_value(mod->data, x, sizeof(x), y, sizeof(y), z, sizeof(z)); x_temp = atof(x); y_temp = atof(y); i = convert_orientation(x_temp, y_temp); if((i >= 0) && (i <= 180) && (i != temp)) { origin_x = radius * sin((i * M_PI / 180) + (M_PI / 2)); origin_y = radius * cos((i * M_PI / 180) + (M_PI / 2)); rect.x = centre_x + origin_x - POINT_HALF_SIDE; rect.y = centre_y - origin_y - POINT_HALF_SIDE; rect.w = POINT_SIDE; rect.h = POINT_SIDE; btn[i]->set_rect(&rect); btn[i]->set_color(COLOR_RED); origin_x = radius * sin((temp * M_PI / 180) + (M_PI / 2)); origin_y = radius * cos((temp * M_PI / 180) + (M_PI / 2)); rect.x = centre_x + origin_x - ROUND_POINT_HALF_SIDE; rect.y = centre_y - origin_y - ROUND_POINT_HALF_SIDE; rect.w = ROUND_POINT_SIDE; rect.h = ROUND_POINT_SIDE; btn[temp]->set_rect(&rect); btn[temp]->set_color(COLOR_GREEN); } else if((i < 0) && (i >= -180) && (i != temp)) { i = i + ROUND_ANGLE; origin_x = radius * sin((i * M_PI / 180) + (M_PI / 2)); origin_y = radius * cos((i * M_PI / 180) + (M_PI / 2)); rect.x = centre_x + origin_x - POINT_HALF_SIDE; rect.y = centre_y - origin_y - POINT_HALF_SIDE; rect.w = POINT_SIDE; rect.h = POINT_SIDE; btn[i]->set_rect(&rect); btn[i]->set_color(COLOR_RED); origin_x = radius * sin((i * M_PI / 180) + (M_PI / 2)); origin_y = radius * cos((i * M_PI / 180) + (M_PI / 2)); rect.x = centre_x + origin_x - ROUND_POINT_HALF_SIDE; rect.y = centre_y - origin_y - ROUND_POINT_HALF_SIDE; rect.w = ROUND_POINT_SIDE; rect.h = ROUND_POINT_SIDE; btn[temp]->set_rect(&rect); btn[temp]->set_color(COLOR_GREEN); } temp = i; } while(1); }
void ui_init(void) { ui_has_initialized = 1; gr_init(); ev_init(input_callback, NULL); #ifdef BOARD_TOUCH_RECOVERY touch_init(); #endif text_col = text_row = 0; text_rows = gr_fb_height() / CHAR_HEIGHT; max_menu_rows = text_rows - MIN_LOG_ROWS; #ifdef BOARD_TOUCH_RECOVERY max_menu_rows = get_max_menu_rows(max_menu_rows); #endif if (max_menu_rows > MENU_MAX_ROWS) max_menu_rows = MENU_MAX_ROWS; if (text_rows > MAX_ROWS) text_rows = MAX_ROWS; text_top = 1; text_cols = gr_fb_width() / CHAR_WIDTH; if (text_cols > MAX_COLS - 1) text_cols = MAX_COLS - 1; int i; for (i = 0; BITMAPS[i].name != NULL; ++i) { int result = res_create_surface(BITMAPS[i].name, BITMAPS[i].surface); if (result < 0) { LOGE("Missing bitmap %s\n(Code %d)\n", BITMAPS[i].name, result); } } gProgressBarIndeterminate = malloc(ui_parameters.indeterminate_frames * sizeof(gr_surface)); for (i = 0; i < ui_parameters.indeterminate_frames; ++i) { char filename[40]; // "indeterminate01.png", "indeterminate02.png", ... sprintf(filename, "indeterminate%02d", i+1); int result = res_create_surface(filename, gProgressBarIndeterminate+i); if (result < 0) { LOGE("Missing bitmap %s\n(Code %d)\n", filename, result); } } if (ui_parameters.installing_frames > 0) { gInstallationOverlay = malloc(ui_parameters.installing_frames * sizeof(gr_surface)); for (i = 0; i < ui_parameters.installing_frames; ++i) { char filename[40]; // "icon_installing_overlay01.png", // "icon_installing_overlay02.png", ... sprintf(filename, "icon_installing_overlay%02d", i+1); int result = res_create_surface(filename, gInstallationOverlay+i); if (result < 0) { LOGE("Missing bitmap %s\n(Code %d)\n", filename, result); } } // Adjust the offset to account for the positioning of the // base image on the screen. if (gBackgroundIcon[BACKGROUND_ICON_INSTALLING] != NULL) { gr_surface bg = gBackgroundIcon[BACKGROUND_ICON_INSTALLING]; ui_parameters.install_overlay_offset_x += (gr_fb_width() - gr_get_width(bg)) / 2; ui_parameters.install_overlay_offset_y += (gr_fb_height() - gr_get_height(bg)) / 2; } } else { gInstallationOverlay = NULL; } char enable_key_repeat[PROPERTY_VALUE_MAX]; property_get("ro.cwm.enable_key_repeat", enable_key_repeat, ""); if (!strcmp(enable_key_repeat, "true") || !strcmp(enable_key_repeat, "1")) { boardEnableKeyRepeat = 1; char key_list[PROPERTY_VALUE_MAX]; property_get("ro.cwm.repeatable_keys", key_list, ""); if (strlen(key_list) == 0) { boardRepeatableKeys[boardNumRepeatableKeys++] = KEY_UP; boardRepeatableKeys[boardNumRepeatableKeys++] = KEY_DOWN; boardRepeatableKeys[boardNumRepeatableKeys++] = KEY_VOLUMEUP; boardRepeatableKeys[boardNumRepeatableKeys++] = KEY_VOLUMEDOWN; } else { char *pch = strtok(key_list, ","); while (pch != NULL) { boardRepeatableKeys[boardNumRepeatableKeys++] = atoi(pch); pch = strtok(NULL, ","); } } } pthread_t t; pthread_create(&t, NULL, progress_thread, NULL); pthread_create(&t, NULL, input_thread, NULL); }
static int wifi_test_start(TestCase* thiz) { DECLES_PRIV(priv, thiz); LOGE("%s: start wifi test...", __func__); FILE* fd; int cell_num = 0; char buffer[1024]; char* ptr = NULL; struct wifi_cell cell; int start_y = 50; char cell_info[148]; wifi_test(1); gr_color(0, 0, 0, 255); ui_draw_title(gr_fb_height()/2, WIFI_WAIT_PROMPT); fd = fopen("/data/wifi_test.txt", "r"); if (fd == NULL) { LOGE("%s: open /data/wifi_test.txt fail", __func__); goto out; } gr_color(0, 255, 255, 255); do { char* tmp = NULL; ptr = fgets(buffer, 1024, fd); if (ptr == NULL) break; tmp = strstr(ptr, ADDRESS_WIFI); if (tmp != NULL) { tmp += strlen(ADDRESS_WIFI) + 1; memset(cell.address, 0, sizeof(cell.address)); strncpy(cell.address, tmp, strlen(tmp) - 1); } tmp = strstr(ptr, ESSID_WIFI); if (tmp != NULL) { char* m; tmp += strlen(ESSID_WIFI) + 1; m = strchr(tmp, '"'); memset(cell.ssid, 0, sizeof(cell.ssid)); strncpy(cell.ssid, tmp, m - tmp); memset(cell_info, 0, sizeof(cell_info)); sprintf(cell_info, "%s (%s)", cell.ssid, cell.address); gr_text(10, start_y, cell_info); start_y += CHAR_HEIGHT; cell_num ++; } } while(1); fclose(fd); out: wifi_test(0); priv->passed = cell_num > 0 ? 1 : 0; if (priv->passed) { return 0; } else { return -1; } }
void ScreenRecoveryUI::Init() { gr_init(); gr_font_size(&char_width, &char_height); text_col = text_row = 0; text_rows = gr_fb_height() / char_height; if (text_rows > kMaxRows) text_rows = kMaxRows; text_top = 1; text_cols = gr_fb_width() / char_width; if (text_cols > kMaxCols - 1) text_cols = kMaxCols - 1; backgroundIcon[NONE] = NULL; LoadBitmapArray("icon_installing", &installing_frames, &installation); backgroundIcon[INSTALLING_UPDATE] = installing_frames ? installation[0] : NULL; backgroundIcon[ERASING] = backgroundIcon[INSTALLING_UPDATE]; LoadBitmap("icon_error", &backgroundIcon[ERROR]); backgroundIcon[NO_COMMAND] = backgroundIcon[ERROR]; LoadBitmap("progress_empty", &progressBarEmpty); LoadBitmap("progress_fill", &progressBarFill); LoadBitmap("stage_empty", &stageMarkerEmpty); LoadBitmap("stage_fill", &stageMarkerFill); LoadLocalizedBitmap("installing_text", &backgroundText[INSTALLING_UPDATE]); LoadLocalizedBitmap("erasing_text", &backgroundText[ERASING]); LoadLocalizedBitmap("no_command_text", &backgroundText[NO_COMMAND]); LoadLocalizedBitmap("error_text", &backgroundText[ERROR]); // MStar Android Patch Begin //load title/tip bitmaps ,added by mstar semiconductor LoadBitmap("title_not_power_off",&titleNotPowerOff); LoadBitmap("title_not_unplug",&titleNotUnplug); LoadBitmap("tip_error", &tipTitle[TIP_TITLE_ERROR]); LoadBitmap("tip_ready", &tipTitle[TIP_TITLE_READY]); LoadBitmap("tip_success", &tipTitle[TIP_TITLE_SUCCESS]); LoadBitmap("tip_wipe_cache", &tipTitle[TIP_TITLE_WIPE_CACHE]); LoadBitmap("tip_wipe_data", &tipTitle[TIP_TITLE_WIPE_DATA]); LoadBitmap("tip_install_package", &tipTitle[TIP_TITLE_INSTALL_PACKAGE]); LoadBitmap("tip_backup_system", &tipTitle[TIP_TITLE_BACKUP_SYSTEM]); LoadBitmap("tip_restore_system", &tipTitle[TIP_TITLE_RESTORE_SYSTEM]); LoadBitmap("tip_blank_screen", &tipTitle[TIP_TITLE_BLANK_SCREEN]); // init exit recovery tip picture int j=0; char tipFileNmae[40]; exitRecoveryTipTitle = (gr_surface*)malloc(exitRecoveryTipTitleNum * sizeof(gr_surface)); for (j = 0;j < exitRecoveryTipTitleNum;++j) { // "tip_exit_recovery_1.png", "tip_exit_recovery_2.png", ... sprintf(tipFileNmae, "tip_exit_recovery_%d", j+1); LoadBitmap(tipFileNmae, exitRecoveryTipTitle+j); } // MStar Android Patch End pthread_create(&progress_t, NULL, progress_thread, NULL); RecoveryUI::Init(); }
void ui_init(void) { gr_init(); ev_init(input_callback, NULL); text_col = text_row = 0; text_rows = gr_fb_height() / CHAR_HEIGHT; if (text_rows > MAX_ROWS) text_rows = MAX_ROWS; text_top = 1; text_cols = gr_fb_width() / CHAR_WIDTH; if (text_cols > MAX_COLS - 1) text_cols = MAX_COLS - 1; int i; for (i = 0; BITMAPS[i].name != NULL; ++i) { int result = res_create_surface(BITMAPS[i].name, BITMAPS[i].surface); if (result < 0) { LOGE("Missing bitmap %s\n(Code %d)\n", BITMAPS[i].name, result); } } gProgressBarIndeterminate = malloc(ui_parameters.indeterminate_frames * sizeof(gr_surface)); for (i = 0; i < ui_parameters.indeterminate_frames; ++i) { char filename[40]; // "indeterminate01.png", "indeterminate02.png", ... sprintf(filename, "indeterminate%02d", i+1); int result = res_create_surface(filename, gProgressBarIndeterminate+i); if (result < 0) { LOGE("Missing bitmap %s\n(Code %d)\n", filename, result); } } if (ui_parameters.installing_frames > 0) { gInstallationOverlay = malloc(ui_parameters.installing_frames * sizeof(gr_surface)); for (i = 0; i < ui_parameters.installing_frames; ++i) { char filename[40]; // "icon_installing_overlay01.png", // "icon_installing_overlay02.png", ... sprintf(filename, "icon_installing_overlay%02d", i+1); int result = res_create_surface(filename, gInstallationOverlay+i); if (result < 0) { LOGE("Missing bitmap %s\n(Code %d)\n", filename, result); } } // Adjust the offset to account for the positioning of the // base image on the screen. if (gBackgroundIcon[BACKGROUND_ICON_INSTALLING] != NULL) { gr_surface bg = gBackgroundIcon[BACKGROUND_ICON_INSTALLING]; ui_parameters.install_overlay_offset_x += (gr_fb_width() - gr_get_width(bg)) / 2; ui_parameters.install_overlay_offset_y += (gr_fb_height() - gr_get_height(bg)) / 2; } } else { gInstallationOverlay = NULL; } pthread_t t; pthread_create(&t, NULL, progress_thread, NULL); pthread_create(&t, NULL, input_thread, NULL); }
GUIConsole::GUIConsole(xml_node<>* node) { xml_attribute<>* attr; xml_node<>* child; mFont = NULL; mCurrentLine = -1; memset(&mForegroundColor, 255, sizeof(COLOR)); memset(&mBackgroundColor, 0, sizeof(COLOR)); mBackgroundColor.alpha = 255; memset(&mScrollColor, 0x08, sizeof(COLOR)); mScrollColor.alpha = 255; mLastCount = 0; mSlideout = 0; mSlideoutState = hidden; mRenderX = 0; mRenderY = 0; mRenderW = gr_fb_width(); mRenderH = gr_fb_height(); if (!node) { mSlideoutX = 0; mSlideoutY = 0; mSlideoutW = 0; mSlideoutH = 0; mConsoleX = 0; mConsoleY = 0; mConsoleW = gr_fb_width(); mConsoleH = gr_fb_height(); } else { child = node->first_node("font"); if (child) { attr = child->first_attribute("resource"); if (attr) mFont = PageManager::FindResource(attr->value()); } child = node->first_node("color"); if (child) { attr = child->first_attribute("foreground"); if (attr) { std::string color = attr->value(); ConvertStrToColor(color, &mForegroundColor); } attr = child->first_attribute("background"); if (attr) { std::string color = attr->value(); ConvertStrToColor(color, &mBackgroundColor); } attr = child->first_attribute("scroll"); if (attr) { std::string color = attr->value(); ConvertStrToColor(color, &mScrollColor); } } // Load the placement LoadPlacement(node->first_node("placement"), &mConsoleX, &mConsoleY, &mConsoleW, &mConsoleH); child = node->first_node("slideout"); if (child) { mSlideout = 1; LoadPlacement(child, &mSlideoutX, &mSlideoutY); attr = child->first_attribute("resource"); if (attr) mSlideoutImage = PageManager::FindResource(attr->value()); if (mSlideoutImage && mSlideoutImage->GetResource()) { mSlideoutW = gr_get_width(mSlideoutImage->GetResource()); mSlideoutH = gr_get_height(mSlideoutImage->GetResource()); } } } gr_getFontDetails(mFont, &mFontHeight, NULL); SetActionPos(mRenderX, mRenderY, mRenderW, mRenderH); SetRenderPos(mConsoleX, mConsoleY); return; }
// Redraw everything on the screen. Does not flip pages. // Should only be called with gUpdateMutex locked. static void draw_screen_locked(void) { if (!ui_has_initialized) return; draw_background_locked(gCurrentIcon); draw_progress_locked(); if (show_text) { int total_rows = (gr_fb_height() - virtualkey_h) / CHAR_HEIGHT; int i = 0; int j = 0; int row = 0; // current row that we are drawing on if (show_menu) { int batt_level = 0; char batt_text[40]; batt_level = get_batt_stats(); /*struct tm *current; time_t now; now = time(NULL); // add 2 hours current = localtime(&now); sprintf(batt_text, "[%d%% %02D:%02D]", batt_level, current->tm_hour, current->tm_min); if (now == NULL)*/ sprintf(batt_text, " [%d%%]", batt_level); gr_color(menuTextColor[0], menuTextColor[1], menuTextColor[2], menuTextColor[3]); //gr_color(0, 255, 0, 255); if (batt_level < 21) gr_color(255, 0, 0, 255); draw_text_line(0, batt_text, RIGHT_ALIGN); gr_color(menuTextColor[0], menuTextColor[1], menuTextColor[2], menuTextColor[3]); gr_fill(0, (menu_top + menu_sel - menu_show_start) * CHAR_HEIGHT, gr_fb_width(), (menu_top + menu_sel - menu_show_start + 1)*CHAR_HEIGHT+1); gr_color(HEADER_TEXT_COLOR); for (i = 0; i < menu_top; ++i) { draw_text_line(i, menu[i], LEFT_ALIGN); row++; } if (menu_items - menu_show_start + menu_top >= max_menu_rows) j = max_menu_rows - menu_top; else j = menu_items - menu_show_start; gr_color(menuTextColor[0], menuTextColor[1], menuTextColor[2], menuTextColor[3]); for (i = menu_show_start + menu_top; i < (menu_show_start + menu_top + j); ++i) { if (i == menu_top + menu_sel) { gr_color(255, 255, 255, 255); draw_text_line(i - menu_show_start , menu[i], LEFT_ALIGN); gr_color(menuTextColor[0], menuTextColor[1], menuTextColor[2], menuTextColor[3]); } else { gr_color(menuTextColor[0], menuTextColor[1], menuTextColor[2], menuTextColor[3]); draw_text_line(i - menu_show_start, menu[i], LEFT_ALIGN); } row++; if (row >= max_menu_rows) break; } gr_fill(0, row*CHAR_HEIGHT+CHAR_HEIGHT/2-1, gr_fb_width(), row*CHAR_HEIGHT+CHAR_HEIGHT/2+1); } gr_color(NORMAL_TEXT_COLOR); int cur_row = text_row; int available_rows = total_rows - row - 1; int start_row = row + 1; if (available_rows < MAX_ROWS) cur_row = (cur_row + (MAX_ROWS - available_rows)) % MAX_ROWS; else start_row = total_rows - MAX_ROWS; int r; for (r = 0; r < (available_rows < MAX_ROWS ? available_rows : MAX_ROWS); r++) { draw_text_line(start_row + r, text[(cur_row + r) % MAX_ROWS], LEFT_ALIGN); } } #ifdef USE_VIRTUAL_KEY draw_virtualkeys_locked(); #endif }