📄 pmshell.c
字号:
{ if (pm_cons_ok) goto fail9; if ((pm_sin = dup(0)) < 0) goto fail; if ((pm_sout = dup(1)) < 0) goto fail1; if ((pm_serr = dup(2)) < 0) goto fail2; if (c_pipe(pm_ip)) goto fail3; if (c_pipe(pm_op)) goto fail4; if (c_pipe(pm_ep)) goto fail5; if (dup2(pm_ip[0], 0) != 0) goto fail6; if (dup2(pm_op[1], 1) != 1) goto fail7; if (dup2(pm_ep[1], 2) != 2) goto fail8; close(pm_ip[0]); close(pm_op[1]); close(pm_ep[1]); pm_cons_ok = 1; return;fail9: dup2(pm_serr, 2);fail8: dup2(pm_sout, 1);fail7: dup2(pm_sin, 0);fail6: close(pm_ep[0]); close(pm_ep[1]);fail5: close(pm_op[0]); close(pm_op[1]);fail4: close(pm_ip[0]); close(pm_ip[1]);fail3: close(pm_serr);fail2: close(pm_sout);fail1: close(pm_sin);fail: pm_cons_ok = 0;}static void pm_do_console(void){#define CONS_BUF 20 unsigned char buffer[CONS_BUF]; fd_set s; int m = pm_op[0] > pm_ep[0] ? pm_op[0] : pm_ep[0]; if (pm_sin > m) m = pm_sin; m++; if (!pm_cons_ok) return; while (1) { int r, w; FD_ZERO(&s); /*FD_SET(pm_sin, &s);*/ FD_SET(pm_op[0], &s); FD_SET(pm_ep[0], &s); if (select(m, &s, NULL, NULL, NULL) <= 0) goto br;#define SEL_CHK(ih, oh) \ if (FD_ISSET(ih, &s)) { \ if ((r = read(ih, buffer, CONS_BUF)) <= 0) goto br; \ do { \ if ((w = write(oh, buffer, r)) <= 0) goto br; \ r -= w; \ } while (r > 0); \ } /*SEL_CHK(pm_sin, pm_ip[1]);*/ SEL_CHK(pm_op[0], pm_sout); SEL_CHK(pm_ep[0], pm_serr); } br:;}static unsigned char *pm_get_driver_param(void){ return NULL;}static unsigned char *pm_init_driver(unsigned char *param, unsigned char *display){ unsigned char *s; pm_bitmap_count = 0; if ((hab = WinInitialize(0)) == 0) { s = "WinInitialize failed.\n"; goto r1; } if (DosCreateEventSem(NULL, &pm_sem, 0, 0)) { s = "Could not create event semaphore.\n"; goto r2; } if (c_pipe(pm_pipe)) { s = "Could not create pipe.\n"; goto r3; } fcntl(pm_pipe[1], F_SETFL, O_NONBLOCK); memset(pm_windows, 0, sizeof(struct pm_window *) * WIN_HASH); pm_lock_init; pm_thread_shutdown = 0; if (_beginthread(pm_dispatcher, NULL, 65536, NULL) == -1) { s = "Could not start thread.\n"; goto r4; } pm_wait; if (pm_status) { pid_t pid; char **arg; if (pm_status != pm_not_ses) goto f; if ((unsigned)g_argc > MAXINT / sizeof(char *) - 1) overalloc(); arg = mem_alloc((g_argc + 1) * sizeof(char *)); memcpy(arg, g_argv, g_argc * sizeof(char *)); arg[g_argc] = NULL; pm_child_pid = -1; install_signal_handler(SIGCHLD, pm_sigcld, NULL, 1); pm_setup_console(); pm_child_pid = pid = spawnvp(P_PM, path_to_exe, arg); mem_free(arg); if (pid < 0) { set_sigcld(); pm_setup_console(); goto f; } pm_do_console(); pm_setup_console(); while (1) select(1, NULL, NULL, NULL, NULL); f: s = pm_status; goto r4; } {#define N_FORMATS 100 int i, pm_bitcount; LONG formats[N_FORMATS]; memset(formats, 0, N_FORMATS * sizeof(LONG)); if (GpiQueryDeviceBitmapFormats(hps_msg, N_FORMATS, formats) == FALSE) goto std_form; for (i = 0; i + 1 < N_FORMATS; i += 2) if (formats[i] == 1) switch (formats[i+1]) { /* !!! FIXME: tady by se mely pridat dalsi formaty, ale neznam je */ /* case 15: pmshell_driver.depth = 0x7a; pm_bitcount = 15; goto e; */ case 16: pmshell_driver.depth = 0x82; pm_bitcount = 16; goto e; case 24: std_form: pmshell_driver.depth = 0xc3; pm_bitcount = 24; goto e; } goto std_form; e:; pm_bitmapinfo = mem_calloc(sizeof(BITMAPINFOHEADER)); pm_bitmapinfo->cbFix = sizeof(BITMAPINFOHEADER); pm_bitmapinfo->cPlanes = 1; pm_bitmapinfo->cBitCount = pm_bitcount; } { SIZEL sizl = { 0, 0 }; PSZ data[4] = { "DISPLAY", NULL, NULL, NULL }; hdc_mem = DevOpenDC(hab, OD_MEMORY, "*", 4L, (PDEVOPENDATA)data, NULLHANDLE); hps_mem = GpiCreatePS(hab, hdc_mem, &sizl, GPIA_ASSOC | PU_PELS | GPIT_MICRO); } set_handlers(pm_pipe[0], pm_handler, NULL, pm_pipe_error, NULL); return NULL; r4: close(pm_pipe[0]); close(pm_pipe[1]); r3: DosCloseEventSem(pm_sem); r2: WinTerminate(hab); r1: return stracpy(s);}static struct graphics_device *pm_init_device(void){ RECTL rect; struct graphics_device *dev; struct pm_window *win; win = mem_alloc(sizeof(struct pm_window)); win->lastpos = 0xffffffff; win->button = 0; init_list(win->queue); win->in = 0; pm_send_msg(MSG_CREATE_WINDOW, win); if (win->h == NULLHANDLE) goto r2; if ((win->ps = WinGetPS(win->hc)) == NULLHANDLE) goto r3; dev = mem_calloc(sizeof(struct graphics_device)); dev->driver_data = win; win->dev = dev; if (WinQueryWindowRect(win->hc, &rect) == TRUE) { win->x = dev->size.x2 = rect.xRight; win->y = dev->size.y2 = rect.yTop; } else dev->size.x2 = dev->size.y2 = 0; dev->clip.x1 = dev->clip.y1 = 0; dev->clip.x2 = dev->size.x2; dev->clip.y2 = dev->size.y2; dev->drv = &pmshell_driver; GpiCreateLogColorTable(win->ps, 0, LCOLF_RGB, 0, 0, NULL); pm_hash_window(win); pm_unlock; return dev; r3: pm_unlock; pm_send_msg(MSG_DELETE_WINDOW, win); r2: if (win->in) del_from_list(win); pm_unlock; mem_free(win); return NULL; }static void pm_shutdown_device(struct graphics_device *dev){ struct pm_window *win = pm_win(dev); WinReleasePS(win->ps); pm_send_msg(MSG_DELETE_WINDOW, win); pm_unhash_window(win); if (win->in) del_from_list(win); pm_unlock; while (!list_empty(win->queue)) { struct pm_event *ev = win->queue.next; del_from_list(ev); free(ev); } mem_free(win); mem_free(dev);}static void pm_shutdown_driver(void){ pm_send_msg(MSG_SHUTDOWN_THREAD, NULL); GpiDestroyPS(hps_mem); DevCloseDC(hdc_mem); if (pm_bitmapinfo) mem_free(pm_bitmapinfo); set_handlers(pm_pipe[0], NULL, NULL, NULL, NULL); close(pm_pipe[0]); close(pm_pipe[1]); DosCloseEventSem(pm_sem); WinTerminate(hab); if (pm_bitmap_count) internal("pm_shutdown_driver: %d bitmaps leaked", pm_bitmap_count);}static void pm_set_window_title(struct graphics_device *dev, unsigned char *title){ static int idx = -1; struct conv_table *ct = get_translation_table(idx >= 0 ? idx : (idx = get_cp_index("utf-8")), pm_cp); struct title_set w; w.win = pm_win(dev); w.text = convert_string(ct, title, strlen(title), NULL); clr_white(w.text); if (strlen(w.text) > 512) w.text[512] = 0; pm_send_msg(MSG_SET_WINDOW_TITLE, &w); pm_unlock; mem_free(w.text);}/*static int pm_get_filled_bitmap(struct bitmap *bmp, long color){ * Mikulas jestlize plati ze get_color u pmshell nic nedela (jen oanduje * 0xffffff), tak tady zavolej (*get_color_fn)(color) z dither.c a ta * vrati long a, a ty udelas (void *)(&a) a budes mit ty bajty co chces * internal("nedopsano"); return 0;}*/static int pm_get_empty_bitmap(struct bitmap *bmp){ debug_call(("get_empty_bitmap (%dx%d)\n", bmp->x, bmp->y)); if (bmp->x > 65535 || bmp->y > 65535) { error("too big bitmap: %dx%d", bmp->x, bmp->y); fatal_tty_exit(); exit(RET_FATAL); } if ((unsigned)bmp->x > MAXINT / (pmshell_driver.depth & 7) - 4) overalloc(); bmp->skip = -((bmp->x * (pmshell_driver.depth & 7) + 3) & ~3); if (-bmp->skip && (unsigned)-bmp->skip * (unsigned)bmp->y / (unsigned)-bmp->skip != (unsigned)bmp->y) overalloc(); if ((unsigned)-bmp->skip * (unsigned)bmp->y > MAXINT) overalloc(); bmp->data = (char *)(bmp->flags = mem_alloc(-bmp->skip * bmp->y)) - bmp->skip * (bmp->y - 1); debug_call(("done\n")); return 1;}static void pm_register_bitmap(struct bitmap *bmp){ HBITMAP hbm; debug_call(("register_bitmap (%dx%d)\n", bmp->x, bmp->y)); pm_bitmap_count++; pm_bitmapinfo->cx = bmp->x; pm_bitmapinfo->cy = bmp->y; hbm = GpiCreateBitmap(hps_msg, (PBITMAPINFOHEADER2)pm_bitmapinfo, CBM_INIT, bmp->flags, (PBITMAPINFO2)pm_bitmapinfo); mem_free(bmp->flags); bmp->flags = (void *)hbm; debug_call(("done\n"));}static void *pm_prepare_strip(struct bitmap *bmp, int top, int lines){ if (-bmp->skip && (unsigned)-bmp->skip * (unsigned)lines / (unsigned)-bmp->skip != (unsigned)lines) overalloc(); if ((unsigned)-bmp->skip * (unsigned)lines > MAXINT) overalloc(); bmp->data = mem_alloc(-bmp->skip * lines); return (char *)bmp->data - bmp->skip * (lines - 1);}static void pm_commit_strip(struct bitmap *bmp, int top, int lines){ LONG s; HBITMAP old; old = GpiSetBitmap(hps_mem, (HBITMAP)bmp->flags); pm_bitmapinfo->cx = bmp->x; pm_bitmapinfo->cy = bmp->y; s = GpiSetBitmapBits(hps_mem, bmp->y - top - lines, lines, bmp->data, (PBITMAPINFO2)pm_bitmapinfo); GpiSetBitmap(hps_mem, old); mem_free(bmp->data);}static void pm_unregister_bitmap(struct bitmap *bmp){ debug_call(("unregister_bitmap (%dx%d)\n", bmp->x, bmp->y)); pm_bitmap_count--; GpiDeleteBitmap((HBITMAP)bmp->flags); debug_call(("done\n"));}static void pm_draw_bitmap(struct graphics_device *dev, struct bitmap *bmp, int x, int y){ POINTL p; debug_call(("draw_bitmap (%dx%d -> %x,%x)\n", bmp->x, bmp->y, x, y)); p.x = x; p.y = pm_win(dev)->y - y - bmp->y; if (p.x < -65535 + pm_win(dev)->x || p.x + bmp->x > 65535) return; if (p.y < -65535 + pm_win(dev)->y || p.y + bmp->y > 65535) return; WinDrawBitmap(pm_win(dev)->ps, (HBITMAP)bmp->flags, NULL, &p, 0, 1, DBM_NORMAL); debug_call(("done\n"));}static void pm_draw_bitmaps(struct graphics_device *dev, struct bitmap **bmp, int n, int x, int y){ HPS ps = pm_win(dev)->ps; POINTL p; debug_call(("draw_bitmaps\n")); p.x = x; p.y = pm_win(dev)->y - y - (*bmp)->y; while (n--) { WinDrawBitmap(ps, (HBITMAP)(*bmp)->flags, NULL, &p, 0xffffffff, 0, DBM_NORMAL); p.x += (*bmp++)->x; } debug_call(("done\n"));}static long pm_get_color(int rgb){ return rgb & 0xffffff;}static void pm_fill_area(struct graphics_device *dev, int x1, int y1, int x2, int y2, long color){ RECTL r; debug_call(("fill_area (%d,%d)->(%d,%d)\n", x1, y1, x2, y2)); if (x1 >= pm_win(dev)->x) x1 = pm_win(dev)->x; if (x1 < 0) x1 = 0; if (x2 >= pm_win(dev)->x) x2 = pm_win(dev)->x; if (x2 < 0) x2 = 0; if (y1 >= pm_win(dev)->y) y1 = pm_win(dev)->y; if (y1 < 0) y1 = 0; if (y2 >= pm_win(dev)->y) y2 = pm_win(dev)->y; if (y2 < 0) y2 = 0; r.xLeft = x1; r.yBottom = pm_win(dev)->y - y2; r.xRight = x2; r.yTop = pm_win(dev)->y - y1; WinFillRect(pm_win(dev)->ps, &r, color); debug_call(("done\n"));}static void pm_draw_hline(struct graphics_device *dev, int x1, int y, int x2, long color){ HPS ps = pm_win(dev)->ps; POINTL p; debug_call(("draw_hline (%d,%d)->(%d)\n", x1, y, x2)); if (x1 >= x2) { debug_call(("done\n")); return; } if (x1 >= pm_win(dev)->x) x1 = pm_win(dev)->x; if (x1 < 0) x1 = 0; if (x2 >= pm_win(dev)->x) x2 = pm_win(dev)->x; if (x2 < 0) x2 = 0; if (y >= pm_win(dev)->y) y = pm_win(dev)->y; if (y < 0) y = 0; GpiSetColor(ps, color); p.x = x1; p.y = pm_win(dev)->y - y - 1; GpiMove(ps, &p); p.x = x2 - 1; GpiLine(ps, &p); debug_call(("done\n"));}static void pm_draw_vline(struct graphics_device *dev, int x, int y1, int y2, long color){ HPS ps = pm_win(dev)->ps; POINTL p; debug_call(("draw_vline (%d,%d)->(%d)\n", x, y1, y2)); if (y1 >= y2) { debug_call(("done\n")); return; } if (x >= pm_win(dev)->x) x = pm_win(dev)->x; if (x < 0) x = 0; if (y1 >= pm_win(dev)->y) y1 = pm_win(dev)->y; if (y1 < 0) y1 = 0; if (y2 >= pm_win(dev)->y) y2 = pm_win(dev)->y; if (y2 < 0) y2 = 0; GpiSetColor(ps, color); p.x = x; p.y = pm_win(dev)->y - y1 - 1; GpiMove(ps, &p); p.y = pm_win(dev)->y - y2; GpiLine(ps, &p); debug_call(("done\n"));}static void pm_hscroll_redraws(struct pm_window *win, struct rect *r, int dir){ struct pm_event *e; pm_cancel_event(win, E_REDRAW, &e); if (!e) return; if (dir > 0) { if (e->x2 > r->x1 && e->x2 < r->x2) { e->x2 += dir; if (e->x2 > r->x2) e->x2 = r->x2; } } else if (dir < 0) { if (e->x1 > r->x1 && e->x1 < r->x2) { e->x1 += dir; if (e->x1 < r->x1) e->x1 = r->x1; } }}static int pm_hscroll(struct graphics_device *dev, struct rect_set **ignore, int sc){ RECTL r; debug_call(("hscroll (%d)\n", sc)); ignore=NULL; r.xLeft = dev->clip.x1; r.yBottom = pm_win(dev)->y - dev->clip.y2; r.xRight = dev->clip.x2; r.yTop = pm_win(dev)->y - dev->clip.y1; pm_lock; WinScrollWindow(pm_win(dev)->hc, sc, 0, &r, &r, NULLHANDLE, NULL, SW_INVALIDATERGN); pm_hscroll_redraws(pm_win(dev), &dev->clip, sc); pm_unlock; debug_call(("done\n")); return 0;}static void pm_vscroll_redraws(struct pm_window *win, struct rect *r, int dir){ struct pm_event *e; pm_cancel_event(win, E_REDRAW, &e); if (!e) return; if (dir > 0) { if (e->y2 > r->y1 && e->y2 < r->y2) { e->y2 += dir; if (e->y2 > r->y2) e->y2 = r->y2; } } else if (dir < 0) { if (e->y1 > r->y1 && e->y1 < r->y2) { e->y1 += dir; if (e->y1 < r->y1) e->y1 = r->y1; } }}static int pm_vscroll(struct graphics_device *dev, struct rect_set **ignore, int sc){ RECTL r; debug_call(("vscroll (%d)\n", sc)); ignore=NULL; r.xLeft = dev->clip.x1; r.yBottom = pm_win(dev)->y - dev->clip.y2; r.xRight = dev->clip.x2; r.yTop = pm_win(dev)->y - dev->clip.y1; pm_lock; WinScrollWindow(pm_win(dev)->hc, 0, -sc, &r, &r, NULLHANDLE, NULL, SW_INVALIDATERGN); pm_vscroll_redraws(pm_win(dev), &dev->clip, sc); pm_unlock; debug_call(("done\n")); return 0;}static void pm_set_clip_area(struct graphics_device *dev, struct rect *rr){ HPS ps = pm_win(dev)->ps; HRGN rg, org; RECTL r; debug_call(("set_clip_area (%d,%d)x(%d,%d)\n", rr->x1, rr->y1, rr->x2, rr->y2)); memcpy(&dev->clip, rr, sizeof(struct rect)); if (dev->clip.x1 >= dev->clip.x2 || dev->clip.y1 >= dev->clip.y2) dev->clip.x1 = dev->clip.x2 = dev->clip.y1 = dev->clip.y2 = 0; r.xLeft = dev->clip.x1; r.yBottom = pm_win(dev)->y - dev->clip.y2; r.xRight = dev->clip.x2; r.yTop = pm_win(dev)->y - dev->clip.y1; if ((rg = GpiCreateRegion(ps, 1, &r)) == RGN_ERROR) return; if (GpiSetClipRegion(ps, rg, &org) == RGN_ERROR) org = rg; GpiDestroyRegion(ps, org); debug_call(("done\n"));}struct graphics_driver pmshell_driver = { "pmshell", pm_init_driver, pm_init_device, pm_shutdown_device, pm_shutdown_driver, pm_get_driver_param, pm_get_empty_bitmap, /*pm_get_filled_bitmap,*/ pm_register_bitmap, pm_prepare_strip, pm_commit_strip, pm_unregister_bitmap, pm_draw_bitmap, pm_draw_bitmaps, pm_get_color, pm_fill_area, pm_draw_hline, pm_draw_vline, pm_hscroll, pm_vscroll, pm_set_clip_area, dummy_block, dummy_unblock, pm_set_window_title, NULL, /* exec */ 0, /* depth */ 0, 0, /* x, y */ 0, /* flags */ 0, /* codepage */ NULL, /* shell */};#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -