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

📄 tool_bdry.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
#ifndef lint#ifdef sccsstatic	char sccsid[] = "@(#)tool_bdry.c 1.1 92/07/30 Copyr 1984 Sun Micro";#endif#endif/* * Copyright (c) 1983 by Sun Microsystems, Inc. *//* * Does tool interactive boundary mgt. */#include <sys/types.h>#include <sys/file.h>#include <sys/time.h>#include <sys/wait.h>#include <errno.h>#include <signal.h>#include <sundev/kbd.h>#include <pixrect/pixrect.h>#include <pixrect/pixfont.h>#include <sunwindow/rect.h>#include <sunwindow/rectlist.h>#include <sunwindow/pixwin.h>#include <sunwindow/cms_mono.h>#include <sunwindow/win_struct.h>#include <sunwindow/win_cursor.h>#include <sunwindow/win_input.h>#include <suntool/wmgr.h>#include <suntool/icon.h>#include <suntool/tool.h>#define	MIN_SW_WIDTH	16#define	MIN_SW_HEIGHT	16typedef enum border_side { 	BORDERS_NONE, 	BORDERS_LEFT,	BORDERS_RIGHT,	BORDERS_TOP,	BORDERS_BOTTOM} Border;static Border	rect_border();static Toolsw	*nearest_sw(), *resolve_xy_to_sw();static adjust_position();extern void	tool_expand_neighbors(),		tool_compute_constraint();static void	constrain_sw(),		compute_obstacles(), 		compute_shadows(),		constrain_from_tool(),		constrain_neighbor(),		change_sw(),		sw_set_rect(),		get_tool_info(),		compute_contortion();inttool_moveboundary(tool, event)	register Tool	*tool;	register Event	*event;{	Toolsw		*target_sw;	register int	x = event_x(event), y = event_y(event);	int		is_move = !event_ctrl_is_down(event);	int		wants_fill = !event_shift_is_down(event);	int		swsp = tool_subwindowspacing(tool);	int		top_border = tool_stripeheight(tool) + 2;	Rect		old_rect, new_rect;	Rect		rconstrain;	WM_Direction	grasp;	Rectlist 	obstacles;	int		x_used, y_used;	extern WM_Direction wmgr_compute_grasp();		if (~tool->tl_flags&TOOL_BOUNDARYMGR ||	    (tool->tl_rectcache.r_width - swsp <= x) ||	    (tool->tl_rectcache.r_height - swsp <= y) ||	    (tool->tl_rectcache.r_left + swsp >= x) ||	    (tool->tl_rectcache.r_top + top_border >= y))		return(-1);	target_sw = nearest_sw(tool, x, y, (int *)LINT_CAST(&x_used), 				(int *)LINT_CAST(&y_used));	if (!target_sw)		return (-1);		event_set_x(event, x_used);	event_set_y(event, y_used);				/*	 * Determine constrainning rect	 */	(void)win_getrect(target_sw->ts_windowfd, &old_rect);	new_rect = old_rect;		grasp = wmgr_compute_grasp(&new_rect, event, is_move, FALSE, TRUE);	constrain_sw(tool, target_sw, grasp, is_move, &rconstrain);		/* Compute the obstacles posed 	 * by the other subwindows	 */	compute_obstacles(tool, target_sw, &obstacles);		/*	 * Display feedback that the user drags around the screen.	 */	wmgr_providefeedback(tool->tl_windowfd, &new_rect, event, is_move, 				 FALSE, grasp, &rconstrain,				 (int (*)())adjust_position, (int)(swsp / 2), 				 &obstacles);	(void)rl_free(&obstacles);	/* Nothing to do if rect	 * size/position did not change.	 */	if (rect_equal(&new_rect, &old_rect))		return(0);			/* Apply the new subwindow position/size */		change_sw(tool, target_sw, &new_rect, wants_fill);		/* expand the subwindow's former neighbors	 * to fill any new holes.	 */	if (wants_fill)		tool_expand_neighbors(tool, target_sw, &old_rect);			/* call the client's subwindow layout routine	 * so the client knows the subwindows have changed.	 * Note that the default routine will not alter the	 * subwindows, since the above code will have adjusted	 * the subwindows already.	 */	(void)tool_layoutsubwindows(tool);        /*         * Need to redisplay the tool because the sw boundaries need to be         * fixed up.         */        (void)_tool_display(tool, FALSE);	return(0);}static Toolsw *nearest_sw(tool, x, y, x_used, y_used)	Tool		 *tool;	register int	 x, y;	register int	*x_used, *y_used;{	register Toolsw		*result = resolve_xy_to_sw(tool, x, y);	register Toolsw		*sw;	int			 min_dist_sq = 0x7FFFFFFF;	register int		 dist_sq;	int			 x_int, y_int;	Rect			 rect;		/* might be in a subwindow.	 * In that case return 0.	 */	if (result) {	    (void)win_getrect(result->ts_windowfd, &rect);	    if (rect_includespoint(&rect, x, y))	        return (Toolsw *) 0;	        	    if (x_used) *x_used = x;	    if (y_used) *y_used = y;	    return result;	}		/* not in a subwindow or on any border.	 * look for the closest subwindow.	 */	for (sw = tool->tl_sw; sw; sw = sw->ts_next) {	    (void)win_getrect(sw->ts_windowfd, &rect);	    dist_sq = rect_distance(&rect, x, y, &x_int, &y_int);	    if (dist_sq < min_dist_sq) {	        min_dist_sq = dist_sq;	        result = sw;	        if (x_used) *x_used = x_int;	        if (y_used) *y_used = y_int;	    }	}	return(result);}static Toolsw *resolve_xy_to_sw(tool, x, y)	register Tool	*tool;	register int	 x, y;{	register Toolsw		*sw;	Rect			rect, rtest;	Toolsw			*target_sw = 0;	int			swsp = tool_subwindowspacing(tool);		/*	 * Find sw window which is above or to left of position	 */	for (sw = tool->tl_sw; sw; sw = sw->ts_next) {		(void)win_getrect(sw->ts_windowfd, &rect);				if (rect_includespoint(&rect, x, y))			return sw;					/* First check the bottom edge */		rect_construct(&rtest, rect.r_left, rect_bottom(&rect),		    rect.r_width, swsp+1);		if (rect_includespoint(&rtest, x, y))			return sw;				/* Now check the right edge */		rect_construct(&rtest, rect_right(&rect), rect.r_top,		    swsp, rect.r_height+1);		if (rect_includespoint(&rtest, x, y))			return sw;				/* Now check the top edge */		rect_construct(&rtest, rect.r_left, rect.r_top - swsp,		    rect.r_width, swsp+1);		if (rect_includespoint(&rtest,  x, y)) {			target_sw = sw;			continue;		} 				/* Now check the left edge */		rect_construct(&rtest, rect.r_left - swsp, rect.r_top,		    swsp, rect.r_height+1);		if (rect_includespoint(&rtest, x, y)) {			target_sw = sw;			continue;		}	}	return target_sw;}/* Constrain target_sw from moving or stretching * outside the tool. */static void	constrain_sw(tool, target_sw, grasp, is_move, rconstrain)Tool	*tool;Toolsw	*target_sw;WM_Direction grasp;int	is_move;Rect	*rconstrain;{	Rect		target_rect;	extern Rect	wmgr_set_bounds();			constrain_from_tool(tool, rconstrain);	(void)win_getrect(target_sw->ts_windowfd, &target_rect);	*rconstrain = 	    wmgr_set_bounds(&target_rect, rconstrain,grasp, is_move, 	    	(struct pr_pos *)0, MIN_SW_WIDTH, MIN_SW_HEIGHT);	}/* Compute the constraining rect imposed * by the tool. */static void	constrain_from_tool(tool, rconstrain)Tool		*tool;register Rect	*rconstrain;{	short		border_width = tool_borderwidth(tool);		*rconstrain 		= tool->tl_rectcache;	rconstrain->r_left 	+= border_width;	rconstrain->r_width 	-= 2 * border_width;	rconstrain->r_top 	+= tool_stripeheight(tool) + 2;	rconstrain->r_height	-= tool_stripeheight(tool) + 2 + border_width;}	/* Compute the obstacle rectangles posed by the  * other subwindows in tool. */static voidcompute_obstacles(tool, target_sw, obstacles)Tool	*tool;Toolsw	*target_sw;Rectlist *obstacles;{	register Toolsw	*sw;	register short	swsp = tool_subwindowspacing(tool) / 2;	Rect		rect;		*obstacles = rl_null;			for (sw = tool->tl_sw; sw; sw = sw->ts_next) {		if (sw == target_sw)			continue;					(void)win_getrect(sw->ts_windowfd, &rect);		rect_marginadjust(&rect, swsp);		(void)rl_rectunion(&rect, obstacles, obstacles);	}}/* If new_rect collides with an obstacle and the obstacle can't * be contorted, use old_rect instead.  This is called by * wmgr_providefeedback() in wmgr_rect.c. */staticadjust_position(obstacles, swsp, old_rect, new_rect)Rectlist	*obstacles;short		swsp;Rect		*old_rect, *new_rect;{	register Rectnode	*rnode;	register Rect		*r;	short			width_left, width_right, width;	short			height_above, height_below, height;		rect_marginadjust(new_rect, swsp + 1);	for (rnode = obstacles->rl_head; rnode; rnode = rnode->rn_next) {		r = &rnode->rn_rect;		if (rect_intersectsrect(r, new_rect)) {			compute_contortion(r, new_rect, 				&width_left, &width_right, &width,				&height_above, &height_below, &height);			if ((width < MIN_SW_WIDTH) && (height < MIN_SW_HEIGHT)) {			    *new_rect = *old_rect;			    return;			}		}	}	rect_marginadjust(new_rect, -(swsp + 1));}			/* Expand neighboring subwindows to fill in the * gap caused by changing target_sw from old_rect. */		     extern voidtool_expand_neighbors(tool, target_sw, old_rect)Tool		*tool;Toolsw		*target_sw;Rect		*old_rect;{	register Toolsw	*sw;	Rect		rect, rconstrain;	register Rect	*r = &rect;	register short	swsp = tool_subwindowspacing(tool) / 2;	register Border	borders_on;	register int	hole;	int		tool_left, tool_top, tool_right, tool_bottom;		rect_marginadjust(old_rect, swsp + 1);		(void)win_lockdata(tool->tl_windowfd);		get_tool_info(tool, &tool_left, &tool_top,		      &tool_right, &tool_bottom);		/* For each subwindow bordering old_rect */	for (sw = tool->tl_sw; sw; sw = sw->ts_next) {		if (sw == target_sw)			continue;					(void)win_getrect(sw->ts_windowfd, r);		rect_marginadjust(r, swsp);		borders_on = rect_border(r, old_rect);		

⌨️ 快捷键说明

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