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

📄 win_central.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
{#define	REDO_LIMIT	3	register Pixwin_handles *pwh;	register struct pixwin *pw = ((struct pixwin *)0);	Notify_value return_code = NOTIFY_IGNORED;	int resize;	int damaged_id;	int not_fixed_image;	int done_damaged_called = 0;	int repaint_all = 0;	int redo_count = 0;	if ((win->next == PIXWIN_HANDLES_NULL) ||	    (win->flags & WH_OWN_SIGWINCH))		return (NOTIFY_IGNORED);Redo:	/* Prevent unsolved flicker repaint situation */	if (redo_count++ >= REDO_LIMIT) {		(void)pw_donedamaged(pw);		return (return_code);	}	/*	 * Must get through entire repair process with damaged_id equalling	 * its initial value at the first pw_damaged or should redo the	 * fixup.  This is because more damage might have occured between	 * the start and finish.	 */	damaged_id = 0;	resize = 0;	not_fixed_image = 0;	/* See what needs to be fixed up */	for (pwh = win->next;pwh; pwh = pwh->next) {		pw = pwh->pw;		(void)pw_damaged(pw);		/* See if first time called pw_damaged */		if (damaged_id == 0)			damaged_id = pw->pw_clipdata->pwcd_damagedid;		/*		 * Repair as much as possible from retained image unless		 * resizing.  Always repair if client specified a fixed		 * sized image.		 */		if (pwh->flags & PW_RESIZED)			resize = 1;		if ((pwh->flags & PW_RETAIN) &&		    pw->pw_prretained &&		    ((!(pwh->flags & PW_RESIZED)) ||		    (pwh->flags & PW_FIXED_IMAGE))) {			struct rect retain_rect;			struct rectlist retain_rl;			/* Reduce repaired area by intersecting tiles */			win_reduce_by_regions(win, pwh);			/* Copy bits to the screen */			(void)pw_repairretained(pw);			/* Reduce damaged area by amount repaired */			rect_construct(&retain_rect, 0, 0,			    pw->pw_prretained->pr_width,			    pw->pw_prretained->pr_height);			(void)rl_initwithrect(&retain_rect, &retain_rl);			(void)pw_reduce_clipping(pw, &retain_rl);			(void)rl_free(&retain_rl);			return_code = NOTIFY_DONE;		}		if (!(pwh->flags & PW_FIXED_IMAGE))			not_fixed_image = 1;		if (pwh->flags & PW_REPAINT_ALL)			repaint_all = 1;		pwh->flags &= ~PW_RESIZED;	}	/*	 * If not fixed size image and resize then set up clipping to be	 * the new entire exposed area.  Perhaps we could be smarter	 * to reduce repainting by doing this on a pixwin by pixwin basis.	 */	if ((resize && not_fixed_image) || repaint_all) {		if (pw->pw_clipdata->pwcd_damagedid != damaged_id)			goto Redo;		(void)pw_donedamaged(pw);		done_damaged_called = 1;	}	/* See if any thing else to repair */	for (pwh = win->next;pwh; pwh = pwh->next) {		pw = pwh->pw;		/*		 * Make sure every pixwin uses exposed clipping (a redundant		 * but harmless call for the pixwin that called pw_donedamaged).		 */		if (done_damaged_called)			(void)pw_exposed(pw);#ifndef PRE_FLAMINGO		if (!rl_empty(&pw->pw_clipdata->pwcd_clipping) ||		    win->flags & WH_NOTIFY_ALL) {#else		if (!rl_empty(&pw->pw_clipdata->pwcd_clipping)) {#endif			/* Clear fixed size image */			if (pwh->flags & PW_FIXED_IMAGE)				(void)pw_writebackground(pw, 0, 0,				    win->rect.r_width, win->rect.r_height,				    PIX_CLR);			/* Notify client to repair the rest */			switch (win_post_id(pwh->client, WIN_REPAINT,			    NOTIFY_SAFE)) {			case NOTIFY_OK:				if (return_code == NOTIFY_IGNORED)					return_code = NOTIFY_DONE;				break;			case NOTIFY_NO_CONDITION:				/*				 * Client may actually be handling				 * SIGWINCHes himself				 */				break;			default:				notify_perror("pw_change");				return_code = NOTIFY_UNEXPECTED;			}		}		/*		 * If haven't yet, set pixwin to exposed.  Last pixwin handled		 * below.		 */		if (!done_damaged_called && pwh->next != PIXWIN_HANDLES_NULL)			(void)pw_exposed(pw);	}	/* Tell kernel that fixed up image and reset clipping to exposed */	if (!done_damaged_called) {		if (pw->pw_clipdata->pwcd_damagedid != damaged_id)			goto Redo;		(void)pw_donedamaged(pw);	}	return (return_code);}/* * Reduce repaired area by intersecting tiles, * if full window pixwin.  Can't just reduce by * overlapping tiles because there is no notion * of overlapping tiles.  Choose only full window * pixwin because if did it arbitrarily, there * would not be any bits written for the intersection. * (This supports 3.0 textsw's that migrated to be able * to be retained in 3.2). */staticwin_reduce_by_regions(win, pwh_main)	Window_handles *win;	register Pixwin_handles *pwh_main;{	struct rectlist rl;	register Pixwin_handles *pwh_region;	if (pwh_main->pw->pw_clipdata->pwcd_regionrect)		return;	rl = rl_null;	for (pwh_region = win->next;pwh_region; pwh_region = pwh_region->next) {		if (pwh_region->pw->pw_clipdata->pwcd_regionrect == RECT_NULL)			continue;		(void)rl_rectunion(pwh_region->pw->pw_clipdata->pwcd_regionrect,		    &rl, &rl);	}	(void)pw_reduce_clipping(pwh_main->pw, &rl);	(void)rl_free(&rl);}static Notify_valuepw_destroy_handles(client, status)	Notify_client client;	Destroy_status status;{	if (status != DESTROY_CHECKING)		(void)win_unregister(client);	return(NOTIFY_DONE);}static Window_handles *win_get_handles(client, pwh_ptr)	Notify_client client;	register Pixwin_handles **pwh_ptr;{	register int i;	register Window_handles *win;	Pixwin_handles *pwh;	if (wins == WINDOW_HANDLES_NULL)		return(WINDOW_HANDLES_NULL);	/* Search through windows */	for (i = 0; i < win_num; i++) {		win = &wins[i];		/* Search through pixwin clients */		if ((pwh = win_find_handles(client, win)) !=		    PIXWIN_HANDLES_NULL) {			if (pwh_ptr)				*pwh_ptr = pwh;			return(win);		}	}	/* Didn't find client */	if (pwh_ptr)		*pwh_ptr = PIXWIN_HANDLES_NULL;	return(WINDOW_HANDLES_NULL);}static	intwin_remove_handles(win, pwh_axe)	register Window_handles *win;	register Pixwin_handles *pwh_axe;{	register Pixwin_handles **pwh_ptr;	register Pixwin_handles *pwh;	/* Search through pixwin clients */	pwh_ptr = &win->next;	for (pwh = win->next;pwh; pwh = pwh->next) {		if (pwh == pwh_axe) {			/* Fix up list pointer */			*pwh_ptr = pwh->next;			/* Remove win references to pwh */			if (win->latest == pwh_axe)				win->latest = PIXWIN_HANDLES_NULL;			if (win->current == pwh_axe)				win->current = PIXWIN_HANDLES_NULL;			return (0);		}		pwh_ptr = &pwh->next;	}	return (-1);}static Pixwin_handles *win_find_handles(client, win)	Notify_client client;	register Window_handles *win;{	register Pixwin_handles *pwh;	/* Search through pixwin clients */	for (pwh = win->next;pwh; pwh = pwh->next) {		if (pwh->client == client)			return(pwh);	}	return(PIXWIN_HANDLES_NULL);}static Pixwin_handles *win_find_consumer(win, event)	register Window_handles *win;	register Event *event;{	register Pixwin_handles *pwh = PIXWIN_HANDLES_NULL;	register Pixwin_handles *pwh_default = PIXWIN_HANDLES_NULL;	Pixwin_handles *pwh_largest;	Rect rect;	int biggest_area, test_area;	register int enters = 1;	/* If input is grabbed then send to the grabber */	if ((win->flags & WH_GRABBED_INPUT) && win->latest)		return(win->latest);	/* Search through pixwin clients */	for (pwh = win->next;pwh; pwh = pwh->next) {		/* Find region that includes x and y */		if (pwh->pw->pw_clipdata->pwcd_regionrect)			rect = *pwh->pw->pw_clipdata->pwcd_regionrect;		else			/* Make rect in own coordinate space */			rect_construct(&rect, 0, 0, win->rect.r_width,			    win->rect.r_height);		if (rect_includespoint(&rect, event->ie_locx, event->ie_locy))			goto Found;		if (pwh->flags & PW_INPUT_DEFAULT)			pwh_default = pwh;	}	/* Suppress sending of any enters */	enters = 0;	/*	 * Event doesn't fall within any region's rectangle so assume	 * send input to the default region.  Multiple regions that want	 * to change the kbd focus would need to explicitly change the	 * default region.	 */	if (pwh_default) {		pwh = pwh_default;		goto Found;	}	/*	 * Since there wasn't any default region then guess that	 * the latest region sent input to is the keyboard focus.	 */	if (win->latest) {		pwh = win->latest;		goto Found;	}	/*	 * If there is no default or no latest, then the region with the	 * biggest area is a third guess (assuming subwindow with scrollbars).	 */	pwh_largest = pwh;	biggest_area = 0;	for (pwh = win->next;pwh; pwh = pwh->next) {		/* Find region that includes x and y */		if (pwh->pw->pw_clipdata->pwcd_regionrect)			rect = *pwh->pw->pw_clipdata->pwcd_regionrect;		else			/* Make rect in own coordinate space */			rect_construct(&rect, 0, 0, win->rect.r_width,			    win->rect.r_height);		test_area = rect.r_width * rect.r_height;		if (test_area > biggest_area) {			pwh_largest = pwh;			biggest_area = test_area;		}	}	pwh = pwh_largest;Found:	/* Remember latest pixwin directed input towards */	win->latest = pwh;	/* See if exiting window */	if (event->ie_code == LOC_WINEXIT)		enters = 0;	/*	 * Send region exit if have entered region and the input recipent	 * is now different.	 */	if (win->current &&	    ((win->current != pwh) || (event->ie_code == LOC_WINEXIT)))		win_rgnexit(win, event);	/* Try sending region enter if last event sent was exit */	if (enters && (win->current == PIXWIN_HANDLES_NULL)) {		/* Delay region enter if window enter */		if (event->ie_code == LOC_WINENTER) {			pwh->flags |= PW_DELAYED_ENTER;			win->current = pwh;		} else			win_rgnenter(win, event, pwh);	}	return(pwh);}static Notify_errorwin_send(pwh, event, when, arg, copy_func, release_func)	Pixwin_handles *pwh;	register Event *event;	Notify_event_type when;	Notify_arg arg;	Notify_copy copy_func;	Notify_release release_func;{	register Rect *rect;	short x_save = event->ie_locx;	short y_save = event->ie_locy;	Notify_error error;	short pw_delayed_enter = (pwh->flags & PW_DELAYED_ENTER);	Notify_client client = pwh->client;	/* Translate mouse x and y */	rect = pwh->pw->pw_clipdata->pwcd_regionrect;	if (rect && !(pwh->flags & PW_NO_LOC_ADJUST)) {		event->ie_locx -= rect->r_left;		event->ie_locy -= rect->r_top;	}	/* Post event */	error = notify_post_event_and_arg(client, (Notify_event)event,	    when, arg, copy_func, release_func);	if (error != NOTIFY_OK)		notify_perror("win_send");	/* Restore mouse x and y to base because win_event shared with others */	event->ie_locx = x_save;	event->ie_locy = y_save;	/* Send delayed enter (don't rely on pwh being around any more) */	if (pw_delayed_enter) {		Window_handles *win = win_get_handles(client, &pwh);		if (pwh != PIXWIN_HANDLES_NULL) {			pwh->flags &= ~PW_DELAYED_ENTER;			win_rgnenter(win, event, pwh);		}	}	return (error);}staticwin_rgnenter(win, event, pwh)	register Window_handles *win;	register Event *event;	Pixwin_handles *pwh;{	unsigned short id = event->ie_code;	unsigned short action = event_action(event);	/* Make input sink */	win->current = pwh;	/* Send region enter event */	event_set_id(event, LOC_RGNENTER);	(void) win_send(pwh, event, NOTIFY_SAFE, (Notify_arg)0,	    win_copy_event, win_free_event);	event->ie_code = id;	/* this madness because event_*_action semantics are screwed */	if (action != id)	    event_set_action(event, action);	return;}staticwin_rgnexit(win, event)	register Window_handles *win;	register Event *event;{	unsigned short id = event->ie_code;	unsigned short action = event_action(event);	if (win->current == PIXWIN_HANDLES_NULL)		return;	/* Send enter event */	event_set_id(event, LOC_RGNEXIT);	(void) win_send(win->current, event, NOTIFY_SAFE, (Notify_arg)0,	    win_copy_event, win_free_event);	event->ie_code = id;	/* this madness because event_*_action semantics are screwed */	if (action != id)	    event_set_action(event, action);	/* No one currently has locator in it */	win->current = PIXWIN_HANDLES_NULL;	return;}

⌨️ 快捷键说明

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