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

📄 gfxsw.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
字号:
#ifndef lint#ifdef sccsstatic	char sccsid[] = "@(#)gfxsw.c 1.1 92/07/30 Copyr 1984 Sun Micro";#endif#endif/* * Copyright (c) 1984 by Sun Microsystems, Inc. *//* * Overview: Implement the abstraction defined in gfxsw.h */#include <sys/types.h>#include <sys/file.h>#include <signal.h>#include <stdio.h>#include <strings.h>#include <pixrect/pixrect.h>#include <pixrect/pr_util.h>#include <pixrect/memvar.h>#include <sunwindow/rect.h>#include <sunwindow/rectlist.h>#include <sunwindow/cms.h>#include <sunwindow/pixwin.h>#include <sunwindow/win_struct.h>#include <sunwindow/win_environ.h>#include <sunwindow/win_screen.h>#include <suntool/tool.h>#include <suntool/gfxsw.h>#include <suntool/gfxswimpl.h>#include "sunwindow/sv_malloc.h"int	gfxsw_selected(), gfxsw_handlesigwinch();void	gfxsw_catchsigwinch(), gfxsw_catchsigtstp(), gfxsw_catchsigcont();extern	int errno;static	struct	gfxsubwindow *gfxtakeover;struct	gfxsubwindow *gfxsw_init(windowfd, argv)	int	windowfd;	char	**argv;{	struct	gfxsubwindow *gfx;	struct	gfx_takeover *gt = (struct gfx_takeover *) 0;	char	*error_msg = NULL;	int	retained = 0, oldsigmask;	struct	screen screen;	int	parentfd = -1;	gfx = (struct gfxsubwindow *) (LINT_CAST(	    sv_calloc(1, sizeof (struct gfxsubwindow))));	/*	 * Prevent getting a sigwinch until ready for it.	 */	oldsigmask = sigblock(1 << (SIGWINCH-1));	if (windowfd)		/*		 * Not taking over window.		 */		gfx->gfx_windowfd = windowfd;	else {		/*		 * Taking over another window.		 */		if (gfxtakeover) {		    error_msg = "Can't take over two windows in same process";		    errno = 0;		    goto MsgErrorReturn;		}		gt = (struct gfx_takeover *) (LINT_CAST(		    sv_calloc(1, sizeof (struct gfx_takeover))));		gt->gt_rootfd = -1;		/*		 * Get framebuffer device name that may have been passed in.		 * (none will mean default fb).		 */		(void)win_initscreenfromargv(&screen, argv);		if (screen.scr_fbname[0]) {			/*			 * Try to create new screen to run on.			 */			if (gfxsw_newscreen(gt, &screen)) {				(void)fprintf(stderr,				    "couldn't create a new screen on %s\n",				    screen.scr_fbname);				goto PErrorReturn;			}		} else {			/*			 * Determine what window to run in.			 */			if (we_getgfxwindow(gt->gt_parentname) &&			    we_getmywindow(gt->gt_parentname) &&			    we_getparentwindow(gt->gt_parentname) &&			    gfxsw_newscreen(gt, &screen)) {				(void)fprintf(stderr,					"gfxsw: no %s or %s in environment\n",					"WINDOW_GFX", "WINDOW_ME");				error_msg = "   Cannot find a frame buffer";				errno = 0;				goto MsgErrorReturn;			}		}		/*		 * Open gt->gt_parentname window		 */		if ((parentfd = open(gt->gt_parentname, O_RDONLY, 0)) < 0) {			(void)fprintf(stderr, "%s would not open\n",			    gt->gt_parentname);			goto PErrorReturn;		}		/*		 * Create new window		 */		if ((gfx->gfx_windowfd = win_getnewwindow()) < 0) {			error_msg = "couldn't get a new gfxsw window";			goto MsgErrorReturn;		}		/*		 * Setup tool struct for passage to tool_select in gfxsw_select		 * This is kind of a hack.  The tool_select stuff should be		 * repackaged to accomodate "outside" clients like this.		 */		gt->gt_tool = (struct tool *) (LINT_CAST(			sv_calloc(1, sizeof (struct tool))));		gt->gt_tool->tl_windowfd = gfx->gfx_windowfd;		gt->gt_tool->tl_io.tio_handlesigwinch = gfxsw_handlesigwinch;		gt->gt_tool->tl_io.tio_selected = gfxsw_selected;	}	if (argv) {		char	**args;		int	nextisreps = 0;		/*		 * Get number of repetitions and retained flag from argv		 */		gfx->gfx_reps = 200000;		for (args = argv;*args;args++) {			if (nextisreps)				(void) sscanf(*args, "%hd", &gfx->gfx_reps);			if (strcmp(*args, "-r") == 0)				retained = 1;			if (strcmp(*args, "-n") == 0)				nextisreps = 1;		}	}	if (gt) {		/*		 * Set up for SIGWINCH signal.		 */		(void)signal_ifdfl(SIGWINCH, gfxsw_catchsigwinch);		/*		 * Install as blanket window.		 */		if (win_insertblanket(gfx->gfx_windowfd, parentfd)) {			error_msg = "couldn't insert blanket window";			goto MsgErrorReturn;		}		(void)close(parentfd);		/*		 * Set up for job control signals.		 * (Doing after insert as blanket because change blanket).		 */		(void)signal_ifdfl(SIGTSTP, gfxsw_catchsigtstp);		(void)signal_ifdfl(SIGCONT, gfxsw_catchsigcont);		/*		 * Set global to notices this situation as takeover one.		 */		gfxtakeover = gfx;		gfx->gfx_takeoverdata = (caddr_t) gt;	}	(void)win_getsize(gfx->gfx_windowfd, &gfx->gfx_rect);	/*	 * Setup pixwins	 */#ifdef	PRE_IBIS	if ((gfx->gfx_pixwin = pw_open(gfx->gfx_windowfd)) ==#else	if ((gfx->gfx_pixwin = pw_open_monochrome(gfx->gfx_windowfd)) ==#endif	    (struct pixwin *)0)		goto ErrorReturn;	if (retained)		(void)gfxsw_getretained(gfx);	/*	 * Now ready for SIGWINCH.	 */	(void)sigsetmask(oldsigmask);	return(gfx);MsgErrorReturn:	if (error_msg != NULL)	    (void)fprintf(stderr, "%s\n", error_msg);PErrorReturn:	if (errno != 0)	    perror("gfxsw");ErrorReturn:	if (parentfd != -1)		(void)close(parentfd);	(void)gfxsw_done(gfx);	(void)sigsetmask(oldsigmask);	return(0);}gfxsw_newscreen(gt, screen)	struct	gfx_takeover *gt;	struct	screen *screen;{	/*	 * The default kbd and ms should be NONE.	 */	if (screen->scr_msname[0] == '\0')		(void)strncpy(screen->scr_msname, "NONE", SCR_NAMESIZE);	if (screen->scr_kbdname[0] == '\0')		(void)strncpy(screen->scr_kbdname, "NONE", SCR_NAMESIZE);	/*	 * Create root window	 */	if ((gt->gt_rootfd = win_screennew(screen)) == -1) {		perror("gfxsw");		return(-1);	}	(void)win_screenget(gt->gt_rootfd, screen);	/*	 * Set up root's name in environment	 */	(void)win_fdtoname(gt->gt_rootfd, gt->gt_parentname);	return(0);}gfxsw_handlesigwinch(gfx)	struct	gfxsubwindow *gfx;{	struct	gfx_takeover *gt = (struct gfx_takeover *) 0;	if (gfxtakeover) {		/*		 * In case using this is called with tool handle for gfx		 */		gfx = gfxtakeover;		gt = gfxgettakeover(gfx);		gt->gt_tool->tl_flags &= ~TOOL_SIGWINCHPENDING;	}	/*	 * Change retained pixrect if size changed.	 */	if (gfxisretained(gfx) &&	    ((gfx->gfx_rect.r_width !=		gfx->gfx_pixwin->pw_prretained->pr_width) ||	    (gfx->gfx_rect.r_height !=		gfx->gfx_pixwin->pw_prretained->pr_height))) {		/*		 * Note: Could copy old to new here but sometimes blows up		 * with an out of swap space condition.  Releasing the old		 * first reduces the likelyhood of this situation.		 */		(void)gfxsw_getretained(gfx);	}	gfx->gfx_flags &= ~GFX_DAMAGED;	/*	 * Toss damaged area if not retained.  Fix if retained.	 */	(void)pw_damaged(gfx->gfx_pixwin);	if (gfxisretained(gfx))		(void)pw_repairretained(gfx->gfx_pixwin);	(void)pw_donedamaged(gfx->gfx_pixwin);	if (gt && gt->gt_selected && (gfx->gfx_flags & GFX_RESTART)) {		/*		 * Give chance to gfxsw_selected to look at GFX_RESTART		 * so that screen gets fixed before next event actually		 * happens.		 */		FD_ZERO(&gt->gt_tool->tl_io.tio_inputmask);		FD_ZERO(&gt->gt_tool->tl_io.tio_outputmask);		FD_ZERO(&gt->gt_tool->tl_io.tio_exceptmask);		(void)gfxsw_selected(gt->gt_tool, &gt->gt_tool->tl_io.tio_inputmask,		    &gt->gt_tool->tl_io.tio_outputmask,		    &gt->gt_tool->tl_io.tio_exceptmask,		    &gt->gt_tool->tl_io.tio_timer);	}}gfxsw_done(gfx)	struct	gfxsubwindow *gfx;{	if (gfx) {		struct	gfx_takeover *gt = gfxgettakeover(gfx);		/*		 * Reset state of window		 */		if (gt) {			gfxtakeover = (struct gfxsubwindow *) 0;			/*			 * Gt only non-zero if gt portion of gfxsw_init was			 * successful.			 */			(void)resetsignal_todfl(SIGTSTP, gfxsw_catchsigtstp);			(void)resetsignal_todfl(SIGCONT, gfxsw_catchsigcont);			(void)win_removeblanket(gfx->gfx_windowfd);			(void)resetsignal_todfl(SIGWINCH, gfxsw_catchsigwinch);			(void)close(gfx->gfx_windowfd);			free((char *)(LINT_CAST(gt->gt_tool)));			if (gfxmadescreen(gt)) (void)close(gt->gt_rootfd);			free((char *)(LINT_CAST(gt)));		}		if (gfx->gfx_pixwin)			(void)pw_close(gfx->gfx_pixwin);		free((char *)(LINT_CAST(gfx)));	}	return;}struct	toolsw *gfxsw_createtoolsubwindow(tool, name, width, height, argv)	struct	tool *tool;	char	*name;	short	width, height;	char	**argv;{	struct	toolsw *toolsw;	/*	 * Create subwindow	 * Note: Should be in another module so doesn't drag in tools code.	 */	toolsw = tool_createsubwindow(tool, name, width, height);	/*	 * Setup empty subwindow	 */	if ((toolsw->ts_data = (caddr_t) gfxsw_init(toolsw->ts_windowfd, argv))	    == (caddr_t)0)		return((struct  toolsw *)0);	toolsw->ts_io.tio_handlesigwinch = gfxsw_handlesigwinch;	toolsw->ts_destroy = gfxsw_done;	return(toolsw);}gfxsw_getretained(gfx)	struct	gfxsubwindow *gfx;{	struct	colormapseg cms;	(void)pw_getcmsdata(gfx->gfx_pixwin, &cms, (int *)0);	if (gfx->gfx_pixwin->pw_prretained) {		(void)pr_destroy(gfx->gfx_pixwin->pw_prretained);		gfx->gfx_pixwin->pw_prretained = (struct pixrect *)0;	}	gfx->gfx_pixwin->pw_prretained = mem_create(	    gfx->gfx_rect.r_width, gfx->gfx_rect.r_height,	    (cms.cms_size == 2 && gfx->gfx_pixwin->pw_pixrect->pr_depth < 32)		? 1 : gfx->gfx_pixwin->pw_pixrect->pr_depth);	if (!gfxisretained(gfx))		(void)fprintf(stderr, "graphics program: can't open retained win\n");}gfxsw_interpretesigwinch(gfx)	struct	gfxsubwindow *gfx;{	struct	rect rect;	struct	gfx_takeover *gt = gfxgettakeover(gfx);	/*	 * Always restart on size change.	 */	(void)win_getsize(gfx->gfx_windowfd, &rect);	if (!rect_equal(&rect, &gfx->gfx_rect)) {		gfx->gfx_flags |= GFX_RESTART;		gfx->gfx_rect = rect;	}	/*	 * Tell demo to restart after first signal (from win_setowner),	 * if not retained.	 */	if (gt) {		if (!gfxisretained(gfx))			gfx->gfx_flags |= GFX_RESTART;		(void)tool_sigwinch(gt->gt_tool);	} else		if (!gfxisretained(gfx))			gfx->gfx_flags |= GFX_RESTART;	gfx->gfx_flags |= GFX_DAMAGED;}gfxsw_select(gfx, selected, ibits, obits, ebits, timer)	struct	gfxsubwindow *gfx;	int	(*selected)();	fd_set  ibits, obits, ebits;	struct	timeval *timer;{	struct	gfx_takeover *gt = gfxgettakeover(gfx);	gt->gt_selected = selected;	gt->gt_tool->tl_io.tio_inputmask = ibits;	gt->gt_tool->tl_io.tio_outputmask = obits;	gt->gt_tool->tl_io.tio_exceptmask = ebits;	gt->gt_tool->tl_io.tio_timer = timer;	(void)tool_select(gt->gt_tool, 0);	gt->gt_selected = 0;}/*ARGSUSED*/gfxsw_selected(tool, ibitsptr, obitsptr, ebitsptr, timer)	struct	tool *tool;	fd_set	*ibitsptr, *obitsptr, *ebitsptr;	struct	timeval **timer;{	struct	gfx_takeover *gt = gfxgettakeover(gfxtakeover);	if (gt->gt_selected)		gt->gt_selected(gfxtakeover, ibitsptr, obitsptr, ebitsptr, timer);}gfxsw_selectdone(gfx)	struct	gfxsubwindow *gfx;{	struct	gfx_takeover *gt = gfxgettakeover(gfx);	(void)tool_done(gt->gt_tool);}voidgfxsw_catchsigwinch(){	if (gfxtakeover == (struct gfxsubwindow *)0)		return;	(void)gfxsw_interpretesigwinch(gfxtakeover);}voidgfxsw_catchsigtstp(){	struct	gfx_takeover *gt;	if (gfxtakeover == (struct gfxsubwindow *)0)		return;	gt = gfxgettakeover(gfxtakeover);	/*	 * Note: Haven't handled case of getting a TSTOP when outside suntools.	 * For now, do nothing.  Could set kbd and ms to NONE and then restore	 * old values on CONT.	 */	if (gfxmadescreen(gt))		return;	(void)win_removeblanket(gfxtakeover->gfx_windowfd);	/*	 * Reset pixwin while stopped.	 * Note: Assumes client is using pixwin interface, even when	 * display is locked, so that pixwin mechanism will notice reset	 * on the next access.  Note, also, that a race condition exists.	 * If a display access is already in progress then it will complete	 * after a SIGCONT is sent.	 */	(void)pw_reset(gfxtakeover->gfx_pixwin);	/*	 * Need to stop self in tracks when get SIGTSTP.	 */	(void)kill(getpid(), SIGSTOP);}voidgfxsw_catchsigcont(){	struct	gfx_takeover *gt;	int	parentfd;	if (gfxtakeover == (struct gfxsubwindow *)0)		return;	gt = gfxgettakeover(gfxtakeover);	/*	 * Open gt->gt_parentname window	 */	if ((parentfd = open(gt->gt_parentname, O_RDONLY, 0)) < 0) {		(void)fprintf(stderr, "%s would not open\n", gt->gt_parentname);		return;	}	if (win_insertblanket(gfxtakeover->gfx_windowfd, parentfd)) {		(void)fprintf(stderr, "couldn't insert blanket window\n");		perror("gfxsw");	}	(void)close(parentfd);}signal_ifdfl(sig, catchernew)	int	sig;	void	(*catchernew)();{	void	(*catcherold)();	struct sigvec vec, ovec;/*        if ((catcherold = signal(sig, catchernew)) != SIG_DFL) *              (void) signal(sig, catcherold); */	vec.sv_handler = catchernew;	vec.sv_mask = vec.sv_onstack = 0;	sigvec(sig, &vec, &ovec);	if (ovec.sv_handler != SIG_DFL)		sigvec(sig, &ovec, 0);}resetsignal_todfl(sig, catchermine)	int	sig;	void	(*catchermine)();{	void	(*catcherold)();	struct sigvec vec, ovec;/*	if ((catcherold = signal(sig, SIG_DFL)) != catchermine) *		(void) signal(sig, catcherold); */	vec.sv_handler = SIG_DFL;	vec.sv_mask = vec.sv_onstack = 0;	sigvec(sig, &vec, &ovec);	if (ovec.sv_handler != catchermine)		sigvec(sig, &ovec, 0);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -