#include #include #include #include #include #include #include #include #include #include #include #include #define TERM_BACKGROUND 0x000000 int cmdfd; GUI_Window *global_w; uint32_t screen_pos_x = 0; uint32_t screen_pos_y = 0; int serial_fd; void execsh(void) { char *argv[] = {NULL}; execv("/sh", argv); } uint32_t cursor_pos_x = 0; uint32_t cursor_pos_y = 0; void screen_remove_old_cursor() { GUI_OverwriteFont(global_w, cursor_pos_x, cursor_pos_y, TERM_BACKGROUND); } void screen_update_cursor() { GUI_OverwriteFont(global_w, screen_pos_x, screen_pos_y, 0xFFFFFF); cursor_pos_x = screen_pos_x; cursor_pos_y = screen_pos_y; } void screen_putchar(uint32_t c) { if (c == '\n') { screen_pos_x = 0; screen_pos_y += 8; screen_remove_old_cursor(); screen_update_cursor(); return; } if (screen_pos_y > global_w->sy - 8) { uint8_t line[global_w->sx * sizeof(uint32_t)]; for (int i = 0; i < global_w->sy - 8; i++) { memcpy(line, global_w->bitmap_ptr + ((i + 8) * global_w->sx), global_w->sx * sizeof(uint32_t)); memcpy(global_w->bitmap_ptr + (i * global_w->sx), line, global_w->sx * sizeof(uint32_t)); } for (int i = 0; i < global_w->sx; i += 8) { GUI_OverwriteFont(global_w, i, screen_pos_y - 8, TERM_BACKGROUND); } screen_pos_x = 0; screen_pos_y -= 8; } GUI_DrawFont(global_w, screen_pos_x, screen_pos_y, c); screen_pos_x += 8; if (screen_pos_x >= global_w->sx - 8) { screen_pos_x = 0; screen_pos_y += 8; } screen_update_cursor(); } void screen_delete_char(void) { GUI_OverwriteFont(global_w, screen_pos_x, screen_pos_y, TERM_BACKGROUND); screen_pos_x -= 8; GUI_OverwriteFont(global_w, screen_pos_x, screen_pos_y, TERM_BACKGROUND); screen_update_cursor(); } void screen_print(const unsigned char *s, int l) { for (; l; l--, s++) { if ('\b' == *s) { screen_delete_char(); continue; } screen_putchar((uint32_t)*s); } } void newtty(void) { int m; int s; openpty(&m, &s, NULL, NULL, NULL); int pid = fork(); if (0 == pid) { dup2(s, 0); dup2(s, 1); dup2(s, 2); execsh(); return; } close(s); cmdfd = m; } void writetty(const char *b, size_t len) { write(serial_fd, b, len); for (int rc; len; len -= rc) { rc = write(cmdfd, b, len); if (-1 == rc) { perror("write"); assert(0); } } } void run() { char buffer[4096]; struct pollfd fds[2]; fds[0].fd = cmdfd; fds[0].events = POLLIN; fds[0].revents = 0; fds[1].fd = global_w->ws_socket; fds[1].events = POLLIN; fds[1].revents = 0; for (;; fds[0].revents = fds[1].revents = 0) { poll(fds, 2, 0); if (fds[0].revents & POLLIN) { int rc; if ((rc = read(cmdfd, buffer, 4096))) { screen_print(buffer, rc); GUI_UpdateWindow(global_w); } } if (fds[1].revents & POLLIN) { WS_EVENT e; int rc; if (0 >= (rc = read(global_w->ws_socket, &e, sizeof(e)))) continue; if (1 == e.ev.release) continue; if (0 == e.ev.c) continue; write(cmdfd, &e.ev.c, 1); } } } int main(void) { open("/dev/serial", O_RDWR, 0); open("/dev/serial", O_RDWR, 0); global_w = GUI_CreateWindow(20, 20, 250 * 4, 150 * 4); assert(global_w); for (int i = 0; i < 250 * 150 * 4 * 4; i++) global_w->bitmap_ptr[i] = TERM_BACKGROUND; // memset(global_w->bitmap_ptr, 0x0, 50 * 50); GUI_UpdateWindow(global_w); newtty(); run(); return 0; }