Exemplo n.º 1
0
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;
}
Exemplo n.º 2
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;

    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
}
Exemplo n.º 3
0
void ui_init(void)
{
    ui_has_initialized = 1;
    gr_init();
    ev_init(input_callback, NULL);
#if defined(BOARD_TOUCH_RECOVERY) || defined(PHILZ_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;
    }
#ifndef PHILZ_TOUCH_RECOVERY
    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.value = 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, ",");
            }
        }
    }
#endif

    pthread_t t;
    pthread_create(&t, NULL, progress_thread, NULL);
    pthread_create(&t, NULL, input_thread, NULL);
}
Exemplo n.º 4
0
void ui_print(const char *fmt, ...) {
    char buf[256];
    va_list ap;
    va_start(ap, fmt);
    vsnprintf(buf, 256, fmt, ap);
    va_end(ap);

    if (ui_log_stdout)
        fputs(buf, stdout);

    // This can get called before ui_init(), so be careful.
    pthread_mutex_lock(&gUpdateMutex);
    if (text_rows > 0 && text_cols > 0) {
        char *ptr;
#ifdef USE_CHINESE_FONT
        int fwidth = 0, fwidth_sum = 0;
#endif
        for (ptr = buf; *ptr != '\0'; ++ptr) {
#ifdef USE_CHINESE_FONT
            fwidth = gr_measure(&*ptr);
            //LOGI("%d \n", fwidth);
            fwidth_sum += fwidth;

            if (*ptr == '\n' || fwidth_sum >= gr_fb_width()) {
                fwidth_sum = 0;
#else
            if (*ptr == '\n' || text_col >= text_cols) {
#endif
                text[text_row][text_col] = '\0';
                text_col = 0;
                text_row = (text_row + 1) % text_rows;
                if (text_row == text_top) text_top = (text_top + 1) % text_rows;
            }
            if (*ptr != '\n') text[text_row][text_col++] = *ptr;
        }
        text[text_row][text_col] = '\0';
        update_screen_locked();
    }
    pthread_mutex_unlock(&gUpdateMutex);
}

void ui_printlogtail(int nb_lines) {
    char * log_data;
    char tmp[PATH_MAX];
    FILE * f;
    int line=0;
    //don't log output to recovery.log
    ui_log_stdout=0;
    sprintf(tmp, "tail -n %d /tmp/recovery.log > /tmp/tail.log", nb_lines);
    __system(tmp);
    f = fopen("/tmp/tail.log", "rb");
    if (f != NULL) {
        while (line < nb_lines) {
            log_data = fgets(tmp, PATH_MAX, f);
            if (log_data == NULL) break;
            ui_print("%s", tmp);
            line++;
        }
        fclose(f);
    }
    ui_print("Return to menu with any key.\n");
    ui_log_stdout=1;
}
Exemplo n.º 5
0
// 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;
    draw_background_locked(gCurrentIcon);
    draw_progress_locked();

#ifdef PHILZ_TOUCH_RECOVERY
        draw_touch_menu();
#else
    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]);
        }
    }
#endif
}