void initialize_console_dri() { /** * Fill dummy lines in log buffer with spaces */ for (int i = 0; i < CONSOLE_LOG_VIEW_LINES; ++i) for (int j = 0; j < CONSOLE_LOG_VIEW_LINE_WIDTH; ++j) log_buffer[i][j] = ' '; /** * Draw title */ int offset_x; if (strlen("EV3RT Console") * CONSOLE_TITLE_FONT_WIDTH > 178 /* screen width */) offset_x = 0; else offset_x = (178 /* screen width */ - strlen("EV3RT Console") * CONSOLE_TITLE_FONT_WIDTH) / 2; bitmap_bitblt(NULL, 0, 0, ev3rt_console_fb, 0, CONSOLE_TITLE_AREA_Y, 178 /* screen width */, CONSOLE_TITLE_FONT_HEIGHT, ROP_SET); // Clear bitmap_draw_string("EV3RT Console", ev3rt_console_fb, offset_x, CONSOLE_TITLE_AREA_Y, CONSOLE_TITLE_FONT, ROP_COPYINVERTED); // syslog(LOG_NOTICE, "%s", cm->title); /** * Draw menu */ console_menu_perform_action(CONSOLE_MENU_ACT_RESET); /** * Active by default */ SVC_PERROR(set_flg(console_button_flag, 1 << BRICK_BUTTON_BACK)); }
/** * ASCII control characters: * CR ('\r'): reset current column * LF ('\n'): scroll up */ static void log_view_putc(char c) { /** * Macros */ #define FONT (CONSOLE_LOG_VIEW_FONT) #define FONT_WIDTH (CONSOLE_LOG_VIEW_FONT_WIDTH) #define FONT_HEIGHT (CONSOLE_LOG_VIEW_FONT_HEIGHT) #define AREA_FB (ev3rt_console_fb) #define AREA_X (CONSOLE_LOG_VIEW_AREA_X) #define AREA_Y (CONSOLE_LOG_VIEW_AREA_Y) #define AREA_W (CONSOLE_LOG_VIEW_AREA_WIDTH) #define AREA_H (CONSOLE_LOG_VIEW_AREA_HEIGHT) #define LINE_WIDTH (CONSOLE_LOG_VIEW_LINE_WIDTH) static uint8_t log_view_current_column = 0; if (c == '\r') { log_view_current_column = 0; return; } if (c != '\n') { // Draw the character bitmap_t *char_bitmap = utf8_char_bitmap(c, FONT); if (char_bitmap == NULL) char_bitmap = utf8_char_bitmap('?', FONT); bitmap_bitblt(char_bitmap, 0, 0, AREA_FB, FONT_WIDTH * log_view_current_column, AREA_Y + AREA_H - FONT_HEIGHT, char_bitmap->width, char_bitmap->height, ROP_COPY); log_view_current_column++; } if (log_view_current_column >= LINE_WIDTH || c == '\n') { // Scroll up at first bitmap_bitblt(AREA_FB, AREA_X, AREA_Y + FONT_HEIGHT, AREA_FB, AREA_X, AREA_Y, AREA_W, AREA_H - FONT_HEIGHT, ROP_COPY); bitmap_bitblt(NULL, 0, 0, AREA_FB, AREA_X, AREA_Y + AREA_H - FONT_HEIGHT, AREA_W, FONT_HEIGHT, ROP_CLEAR); log_view_current_column = 0; } }
void lcd_console_update() { // TODO: mutex on current_line updated // Auto scroll mode (for test) int32_t first_line = current_line - 6; if (first_line < 0) first_line = 0; for (int i = first_line; i <= current_line; ++i) { for (int j = 0; j < linewidth; ++j) { bitmap_t *char_bitmap = utf8_char_bitmap(*(buffer + i * linewidth + j), &font); if (char_bitmap == NULL) char_bitmap = utf8_char_bitmap('?', &font); bitmap_bitblt(char_bitmap, 0, 0, &lcd_console_fb, char_bitmap->width * j, char_bitmap->height * (first_line + 6 - current_line), char_bitmap->width, char_bitmap->height, ROP_COPY); } } }
void show_message_box(const char *title, const char *msg) { int x, y; font_t *font = global_brick_info.font_w10h16; bitmap_t *screen = global_brick_info.lcd_screen; // Draw title y = 0; if (strlen(title) * font->width > screen->width) x = 0; else x = (screen->width - strlen(title) * font->width) / 2; bitmap_bitblt(NULL, 0, 0, screen, 0, y, screen->width, font->height, ROP_SET); // Clear bitmap_draw_string(title, screen, x, y, font, ROP_COPYINVERTED); y += font->height; // syslog(LOG_NOTICE, "%s", cm->title); // Draw message bitmap_bitblt(NULL, 0, 0, screen, 0, y, screen->width, screen->height, ROP_CLEAR); // Clear x = font->width, y += font->height; while (*msg != '\0') { if (*msg == '\n' || x + font->width > screen->width) { // newline x = font->width; y += font->height; } if (*msg != '\n') { char buf[2] = { *msg, '\0' }; bitmap_draw_string(buf, screen, x, y, font, ROP_COPY); x += font->width; } msg++; } // Draw 'OK' button bitmap_draw_string(" O K ", screen, (screen->width - strlen(" O K ") * font->width) / 2, screen->height - font->height - 5, font, ROP_COPYINVERTED); while(!global_brick_info.button_pressed[BRICK_BUTTON_ENTER]); while(global_brick_info.button_pressed[BRICK_BUTTON_ENTER]); }
void console_menu_perform_action(intptr_t action) { switch(action) { case CONSOLE_MENU_ACT_ENTER: entry_tab[current_idx].handler(entry_tab[current_idx].exinf); return; // won't draw case CONSOLE_MENU_ACT_RESET: current_idx = 0; break; case CONSOLE_MENU_ACT_PREV: if (current_idx > 0) { current_idx--; } else return; break; case CONSOLE_MENU_ACT_NEXT: if (current_idx + 1 < entry_num) { current_idx++; } else return; break; default: assert(false); } // Draw int offset_x; if (strlen(entry_tab[current_idx].title) * CONSOLE_MENU_FONT_WIDTH > 178 /* screen width */) offset_x = 0; else offset_x = (178 /* screen width */ - strlen(entry_tab[current_idx].title) * CONSOLE_MENU_FONT_WIDTH) / 2; bitmap_bitblt(NULL, 0, 0, ev3rt_console_fb, 0, CONSOLE_MENU_AREA_Y, 178 /* screen width */, CONSOLE_MENU_FONT_HEIGHT, ROP_SET); // Clear bitmap_draw_string(entry_tab[current_idx].title, ev3rt_console_fb, offset_x, CONSOLE_MENU_AREA_Y, CONSOLE_MENU_FONT, ROP_COPYINVERTED); if (current_idx != 0) { // has prev '<' bitmap_draw_string("<", ev3rt_console_fb, 0, CONSOLE_MENU_AREA_Y, CONSOLE_MENU_FONT, ROP_COPYINVERTED); } if (current_idx != entry_num - 1) { // has next '>' bitmap_draw_string(">", ev3rt_console_fb, 178 /* screen width */ - CONSOLE_MENU_FONT_WIDTH, CONSOLE_MENU_AREA_Y, CONSOLE_MENU_FONT, ROP_COPYINVERTED); } }
ER zmodem_recv_file(ID portid, void *buf, SIZE size, SIZE *filesz) { /** * Clear SIO port */ T_SERIAL_RPOR rpor; while (1) { char buf[1]; ER ercd = serial_ref_por(portid, &rpor); if (ercd != E_OK) return ercd; if (rpor.reacnt > 0) serial_rea_dat(portid, (char*)&buf, sizeof(buf)); else break; } /** * Draw GUI */ font_t *font = global_brick_info.font_w10h16; bitmap_t *screen = global_brick_info.lcd_screen; offset_y = 0; bitmap_bitblt(NULL, 0, 0, screen, 0, offset_y, screen->width, font->height * 2, ROP_CLEAR); // Clear bitmap_bitblt(NULL, 0, 0, screen, 0, offset_y, screen->width, font->height, ROP_SET); // Clear bitmap_draw_string("Receive App File", screen, (screen->width - strlen("Receive App File") * font->width) / 2, offset_y, font, ROP_COPYINVERTED); offset_y += font->height * 2; bitmap_bitblt(NULL, 0, 0, screen, 0, offset_y, screen->width, screen->height, ROP_CLEAR); // Clear bitmap_draw_string(portid == SIO_PORT_BT ? "Port: Bluetooth" : "Port: Port 1", screen, 0, offset_y, font, ROP_COPY); offset_y += font->height * 2; bitmap_draw_string("Protocol: ZMODEM", screen, 0, offset_y, font, ROP_COPY); offset_y += font->height * 2; // syslog(LOG_NOTICE, "%s", cm->title); /** * Setup static variables for ZMODEM task */ sio_portid = portid; p_recv_filesz = filesz; cookie_io_functions_t memfile_func = { .read = memfile_read, .write = memfile_write, .seek = memfile_seek, .close = memfile_close }; // FILE *fp; /* Set up the cookie before calling fopencookie() */ struct memfile_cookie mycookie; mycookie.buf = buf; mycookie.allocated = size; mycookie.offset = 0; mycookie.endpos = 0; recv_file = fopencookie(&mycookie,"w+", memfile_func); /** * Act ZMODEM task */ recv_task_compl = false; act_tsk(ZMODEM_RECV_TASK); /** * Task can be terminated by clicking BACK button */ while(!recv_task_compl && !global_brick_info.button_pressed[BRICK_BUTTON_BACK]) tslp_tsk(10); if (!recv_task_compl) { while(global_brick_info.button_pressed[BRICK_BUTTON_BACK]); // ter_tsk(ZMODEM_RECV_TASK); zm.cancelled = true; while(!recv_task_compl) { rel_wai(ZMODEM_RECV_TASK); tslp_tsk(10); } recv_ercd = E_TMOUT; } fclose(recv_file); /** * Dirty fix, store received file: */ if (recv_ercd == E_OK) { static char filepath[(MAX_PATH+1*2)]; strcpy(filepath, "/ev3rt/apps"/*SD_APP_FOLDER*/); strcat(filepath, "/"); strcat(filepath, recv_file_name); apploader_store_file(filepath, buf, *filesz); } return recv_ercd; }