⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pmshell.c

📁 ELinks is an advanced and well-established feature-rich text mode web (HTTP/FTP/..) browser. ELinks
💻 C
📖 第 1 页 / 共 2 页
字号:
{	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 + -