int display_get_info(int type, struct display_info *di) { struct fbcon_config* config = NULL; if (!di) return API_EINVAL; switch (type) { default: dprintf(INFO, "%s: unsupport display device type: %d\n", __FILE__, type); return API_ENODEV; case DISPLAY_TYPE_LCD: config = fbcon_display(); di->pixel_width = config->width; di->pixel_height = config->height; di->screen_rows = 0; di->screen_cols = 0; #if DISPLAY_USE_BGR di->color_format = DISPLAY_COLOR_FORMAT_BGR888; #else di->color_format = DISPLAY_COLOR_FORMAT_RGB888; #endif break; } di->type = type; return 0; }
void menu_putc(char c) { struct fbcon_config *config = fbcon_display(); static int in_putc = 0; if(in_putc) return; // lock if(is_initialized && !in_critical_section()) mutex_acquire(&logbuf_mutex); else enter_critical_section(); in_putc = 1; // automatic line break int cwidth = pf2font_get_cwidth(c); if(logbuf_posx+cwidth>config->width) { logbuf_row++; logbuf_col = 0; logbuf_posx = 0; display_server_refresh(); } // scroll down while(logbuf_row>ARRAY_SIZE(logbuf)-1) { unsigned i; for(i=1; i<ARRAY_SIZE(logbuf); i++) { memcpy(logbuf[i-1], logbuf[i], ARRAY_SIZE(logbuf[0])); } logbuf_row--; } // write char logbuf[logbuf_row][logbuf_col++] = c=='\n'?'\0':c; // expression start static int in_expr = 0; if(!in_expr && c=='\e') in_expr = 1; if(!in_expr) { logbuf_posx+=cwidth; } // expression end else if(in_expr && c=='m') in_expr = 0; // line break if(logbuf_col==ARRAY_SIZE(logbuf[logbuf_row]) || c=='\n') { logbuf_row++; logbuf_col = 0; logbuf_posx = 0; display_server_refresh(); } // unlock in_putc = 0; if(is_initialized && !in_critical_section()) mutex_release(&logbuf_mutex); else exit_critical_section(); }
void ui_clear_all(void) { struct fbcon_config* fbconfig = fbcon_display(); unsigned bytes_per_bpp = ((fbconfig->bpp) / 8); unsigned count = fbconfig->width * fbconfig->height; memset(fbconfig->base, background_color, count * bytes_per_bpp); }
void ui_menu_clear(void) { struct fbcon_config* fbconfig = fbcon_display(); unsigned bytes_per_bpp = ((fbconfig->bpp) / 8); unsigned count = fbconfig->width * MENU_MAX_HEIGHT; memset(fbconfig->base, background_color, count * bytes_per_bpp); }
void target_shutdown(void) { enter_critical_section(); if(fbcon_display()) htcleo_display_shutdown(); platform_exit(); msm_proc_comm(PCOM_POWER_DOWN, 0, 0); for (;;) ; }
static void ui_hightlight_line(unsigned lineno, uint16_t color) { struct fbcon_config* fbconfig = fbcon_display(); unsigned bytes_per_bpp = ((fbconfig->bpp) / 8); if (fbconfig == NULL) { return; } memset(fbconfig->base + fbconfig->width * (lineno * FONT_HEIGHT) * bytes_per_bpp, color, fbconfig->width * FONT_HEIGHT * bytes_per_bpp); }
void target_reboot(unsigned reboot_reason) { enter_critical_section(); if(fbcon_display()) htcleo_display_shutdown(); platform_exit(); writel(reboot_reason, LK_BOOTREASON_ADDR); writel(reboot_reason^MARK_LK_TAG, LK_BOOTREASON_ADDR + 4); reboot(reboot_reason); }
static void ui_draw_horizontal_line(unsigned y, uint16_t color, unsigned thickness) { struct fbcon_config* fbconfig = fbcon_display(); unsigned bytes_per_bpp = ((fbconfig->bpp) / 8); if (fbconfig == NULL) { return; } memset(fbconfig->base + fbconfig->width * y * bytes_per_bpp, color, fbconfig->width * thickness * bytes_per_bpp); }
static void menu_draw_divider(int dy, int height) { struct fbcon_config *config = fbcon_display(); uint8_t* base = config->base; unsigned x; uint8_t *row = &base[config->width * dy * config->bpp / 8]; for (x = 0; x < config->width*height; x++) { uint8_t *pixel = &row[x * config->bpp / 8]; pixel[0] = color_b; pixel[1] = color_g; pixel[2] = color_r; } }
/** * Display error message and stop boot process. */ void display_error_msg() { fb_config = fbcon_display(); if (fb_config) { fbcon_clear(); display_error_message(); // No point in checking the return value here } // Invalid state. Nothing to be done but contacting the OEM. // Stop boot process. dprintf(CRITICAL,"ERROR: blocking boot process\n"); for(;;); }
void htcleo_fastboot_init() { // off charge and recovery boot failed, reboot to normal mode if(get_boot_reason()==2) reboot(0); // display not initialized if(fbcon_display()==NULL) { display_init(); display_lk_version(); htcleo_ptable_dump(&flash_ptable); } cmd_oem_register(); }
static void ui_write_line(char* text, unsigned lineno, uint16_t color) { struct fbcon_config* fbconfig = fbcon_display(); uint16_t *pixels; unsigned bytes_per_bpp = ((fbconfig->bpp) / 8); if (fbconfig == NULL) { return; } pixels = fbconfig->base + fbconfig->width * (lineno * FONT_HEIGHT) * bytes_per_bpp; while(*text != 0) { char c = *text++; if(((unsigned char)c > 127) || ((unsigned char)c < 32)) continue; ui_draw_char(pixels, color, fbconfig->stride, (font + (c - 32) * FONT_PPCHAR)); pixels += FONT_WIDTH; } }
/** * Display the basic layout of the screen (done only once). */ static void display_initial_screen(uint32_t pin_length) { if (g_initial_screen_displayed == true) return; fb_config = fbcon_display(); if (fb_config) { fbcon_clear(); if (display_error_message()) display_error_msg(); /* This will never return */ display_initial_delay(); mdelay(INITIAL_DELAY_MSECONDS); g_pin_frames_y_location = ((fb_config->height)*PIN_RELATIVE_Y_LOCATION); uint32_t total_pin_length = pin_length*MDTP_PIN_DIGIT_WIDTH + DIGIT_SPACE*(pin_length - 1); uint32_t complete_pin_centered = (fb_config->width - total_pin_length)/2; for (uint32_t i=0; i<pin_length; i++) { g_pin_frames_x_location[i] = complete_pin_centered + i*(DIGIT_SPACE+MDTP_PIN_DIGIT_WIDTH); } for (uint32_t i=0; i<pin_length; i++) { display_digit(g_pin_frames_x_location[i], g_pin_frames_y_location, 0); } display_ok_button(); g_initial_screen_displayed = true; } else { dprintf(CRITICAL,"ERROR: fbcon_config struct is NULL\n"); display_error_msg(); /* This will never return */ } }
static void menu_renderer(int keycode) { int y = 1; unsigned i; int fh = pf2font_get_fontheight(); struct fbcon_config *config = fbcon_display(); // input handling if(!block_user) { // handle keypress if(keycode==KEY_RIGHT && menu_stack->entries[selection].execute) { menu_execute_entry(menu_stack->entries[selection].execute); return; } if(keycode==KEY_DOWN) { int first_visible = -1; int next_visible = -1; for(i=0; menu_stack->entries[i].name; i++) { if(!menu_stack->entries[i].hide || !menu_stack->entries[i].hide()) { if(first_visible==-1) first_visible = i; if(next_visible==-1 && i>selection) next_visible = i; } } if(next_visible!=-1) selection = next_visible; else selection=first_visible; } if(keycode==KEY_UP) { int last_visible = -1; int previous_visible = -1; for(i=0; menu_stack->entries[i].name; i++) { if(!menu_stack->entries[i].hide || !menu_stack->entries[i].hide()) { last_visible = i; if(i<selection) previous_visible = i; } } if(previous_visible!=-1) selection = previous_visible; else selection=last_visible; } } // clear fbcon_clear(); // title menu_set_color(NORMAL_TEXT_COLOR); pf2font_printf(0, fh*y++, "Fastboot Flash Mode (%s)", ABOOT_VERSION); // USB status if(usb_is_connected()) pf2font_printf(0, fh*y++, "Transfer Mode: USB Connected"); else pf2font_printf(0, fh*y++, "Connect USB Data Cable"); // device info char sn_buf[13]; target_serialno((unsigned char*)sn_buf); pf2font_printf(0, fh*y++, "CPU: %s Serial: %s", TARGET, sn_buf); #if WITH_DEV_PMIC_PM8921 // time unsigned long time; struct rtc_time tm; pm8xxx_rtc_read_time(&time); rtc_time_to_tm(time, &tm); pf2font_printf(0, fh*y++, "Time: %d-%02d-%02d %02d:%02d", tm.tm_year+1900, tm.tm_mon, tm.tm_mday, tm.tm_hour, tm.tm_min); #endif // divider 1 menu_set_color(DIVIDER_COLOR); menu_draw_divider(fh*y++ - pf2font_get_ascent()/2, 3); // draw interactive UI if(!block_user) { // menu header menu_set_color(NORMAL_TEXT_COLOR); pf2font_printf(0, fh*y++, "Boot Mode Selection Menu"); pf2font_printf(0, fh*y++, " Power Selects, Vol Up/Down Scrolls"); // menu entries for(i=0; menu_stack->entries[i].name; i++) { if(menu_stack->entries[i].hide && menu_stack->entries[i].hide()) continue; char* buf = NULL; if(menu_stack->entries[i].format) menu_stack->entries[i].format(&buf); else buf = strdup(menu_stack->entries[i].name); menu_draw_item(fh*y++, buf, selection==i); if(buf) free(buf); } // divider 2 menu_set_color(DIVIDER_COLOR); menu_draw_divider(fh*y++ - pf2font_get_ascent()/2, 3); } // draw log menu_set_color(LOG_COLOR_NORMAL); mutex_acquire(&logbuf_mutex); int log_top = y; int log_bottom = config->height/fh; int log_size = log_bottom-log_top; int start = (logbuf_row-log_size); for(i=(start>=0?start:0); i<=logbuf_row; i++) { pf2font_printf(0, fh*y++, logbuf[i]); } mutex_release(&logbuf_mutex); // flush fbcon_flush(); };