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

📄 win_central.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
#ifndef lint#ifdef sccsstatic  char sccsid[] = "@(#)win_central.c 1.1 92/07/30 Copyr 1985 Sun Micro";#endif#endif/* * Copyright (c) 1985 by Sun Microsystems, Inc. *//* * Implements library routines for centralized window event management. */#include <sys/types.h>#include <sys/time.h>#include <sys/ioctl.h>#include <errno.h>#include <signal.h>#include <stdio.h>#include <pixrect/pixrect.h>#include <pixrect/pr_util.h>#include <pixrect/memvar.h>#include <pixrect/pixfont.h>#include <pixrect/pr_planegroups.h>#include <sunwindow/notify.h>#include <sunwindow/rect.h>#include <sunwindow/rectlist.h>#include <sunwindow/pixwin.h>#include <sunwindow/cms.h>#include <sunwindow/win_input.h>#include <sunwindow/win_notify.h>#include <sunwindow/win_screen.h>#include <sunwindow/win_ioctl.h>#include <sunwindow/sv_malloc.h>#include <sunwindow/win_impl.h>static	Window_handles *wins;				/* Dynamically allocated to be getdtablesize */				/* (Isn't there a constant can use instead?) */				/* Position in table corresponds to fd number*/static  int win_num;		/* Size of wins array */static  int wins_managing;	/* Number of active windows in wins array */static	Window_handles *win_get_handles();	/* (Notify_client client,						    Pixwin_handles **pwh) */static	Pixwin_handles *win_find_handles();	/* (Notify_client client,						    Window_handles *win) */static	Pixwin_handles *win_find_consumer();	/* (Window_handles *win,						    Event *event) */static	Notify_value input_pending();		/* (Notify_client client,						    int fd) */static	Notify_value pw_change();		/* (Notify_client client,						    int signal,						    Notify_signal_mode mode) */static	Notify_value win_send_resize();		/* (Window_handles *win) */static	Notify_value win_send_repaint();	/* (Window_handles *win) */static	Notify_value pw_destroy_handles();static	Notify_error win_send();extern	int errno;static	int win_remove_handles();	int win_clear_cursor_planes();	int win_cursor_planes_available();extern	int	sv_journal;char	*shell_prompt;int	prompt_len;void    notify_perror();/* * Public interface: *//* performance: global cache of getdtablesize() */extern int dtablesize_cache;#define GETDTABLESIZE() \	(dtablesize_cache?dtablesize_cache:(dtablesize_cache=getdtablesize()))intwin_register(client, pw, event_func, destroy_func, flags)	register Notify_client client;	Pixwin	*pw;	Notify_func event_func;	Notify_func destroy_func;	register u_int	flags;{	register Window_handles *win;	register Pixwin_handles *pwh;	register int fd = pw->pw_windowfd;	char *calloc();	char *shell_ptr;	char *journal_ptr;	extern	char *getenv();	/* 	 * Allocating window handles in increments has the 	 * following problem:	 * In the case where an event/notify proc calls window_create	 * and additional window handles are created, *and* "wins" 	 * is realloc'ed, the caller program's event pointer will	 * no longer be valid. We therefore need to allocate all 	 * handles in one big chunk until the mechanism for passing	 * event pointers to event/notify procs is changed. Currently,	 * the events are obtained directly from the appropriate	 * Window_handle.	 */	/* Allocate wins if not done so already */	if (wins == WINDOW_HANDLES_NULL) {		win_num = GETDTABLESIZE();		wins = (Window_handles *)(LINT_CAST(			calloc((unsigned)win_num,sizeof(Window_handles))));		if (wins == WINDOW_HANDLES_NULL) {			errno = ENOMEM;			perror("win_register");			goto Error;		}		shell_prompt = (char *)sv_calloc(40,sizeof(char));		if ((shell_ptr = getenv("SVJ_PROMPT")) == NULL) 			strcpy(shell_prompt,"% ");		else 			strcpy(shell_prompt,shell_ptr);		prompt_len = strlen(shell_prompt);                sv_journal = FALSE;                if ((journal_ptr = getenv("WINDOW_JOURNAL")) != NULL) {			if (strcmp(journal_ptr,"ON") == 0)                        	sv_journal = TRUE;		}	}	/* See if this window has any pixwins yet */	win = &wins[fd];	if (win->next == PIXWIN_HANDLES_NULL) {		/* Set up input notifier function (one per window) */		if (notify_set_input_func(client, input_pending, fd) ==		    NOTIFY_FUNC_NULL) {			notify_perror("win_register");			return(-1);		}		(void)win_getrect(fd, &win->rect);	}	/* Set event handler */	if (notify_set_event_func(client, event_func, NOTIFY_SAFE) ==	      NOTIFY_FUNC_NULL) {		notify_perror("win_register");		goto Error;	}	/* Set destroy handler */	if (destroy_func == NOTIFY_FUNC_NULL) {		if ((destroy_func = notify_get_destroy_func(client)) ==		    NOTIFY_FUNC_NULL) 			/*			 * Set up our destroy routine so at least we clean			 * up ourselves.			 */			destroy_func = pw_destroy_handles;	}	if (notify_set_destroy_func(client, destroy_func) == NOTIFY_FUNC_NULL) {		notify_perror("win_register");		goto Error;	}	/* Allocate pixwin_handles */	pwh = (Pixwin_handles *)(LINT_CAST(		calloc(1, sizeof(Pixwin_handles))));	if (pwh == PIXWIN_HANDLES_NULL) {		errno = ENOMEM;		perror("win_register");		goto Error;	}	/* Conditionally make pixwin retained */	if ((flags & PW_RETAIN) && (pw->pw_prretained == ((struct pixrect *)0)))		win_set_retain(pw, win);	/* Fill in structure */	pwh->pw = pw;	pwh->client = client;	pwh->flags = flags; 	/* Add to head of client list */	pwh->next = win->next;	win->next = pwh;	if (++wins_managing == 1) {		/* Set up signal notifier function (one per process) */		if (notify_set_signal_func((Notify_client)wins, pw_change, SIGWINCH,		    NOTIFY_SYNC) == NOTIFY_FUNC_NULL) {			notify_perror("win_register");			goto Error;		}	}	return(0);Error:	/* Reset client entanglements with notifier */	(void)notify_remove(client);	return(-1);}intwin_unregister(client)	register Notify_client client;{	Pixwin_handles *pwh;	register Window_handles *win = win_get_handles(client, &pwh);	if ((win == WINDOW_HANDLES_NULL) || (pwh == PIXWIN_HANDLES_NULL))		return(-1);	/*	 * Although pw_close will release retained image, we do it now	 * because we allocated it originally.	 */	if (pwh->flags & PW_RETAIN) {		(void)pr_destroy(pwh->pw->pw_prretained);		pwh->pw->pw_prretained = (struct pixrect *)0;	}	/*	 * Remove conditions from notifier.  Could remove just conditions	 * set in win_register.  But we are doing everyone a favor here because	 * it is overwhelmingly the common case.  Common conditions set by	 * the first pixwin will be cleared by that pixwin's unregister.	 */	(void) notify_remove(client);	/* Do local data structure clean up */	if (win->next == pwh && pwh->next == PIXWIN_HANDLES_NULL)		/* If last client for win then zero win handles */		bzero((caddr_t)win, sizeof(Window_handles));	else		/* Axe client from list */		(void)win_remove_handles(win, pwh);	if (--wins_managing == 0)		/* Remove SunWindows notifier's notifier entanglements */		(void) notify_remove((Notify_client)wins);	/* Release client record */	free((caddr_t)pwh);	return(0);}intwin_set_flags(client, flags)	Notify_client client;	u_int flags;{	Pixwin_handles *pwh;	Window_handles *win = win_get_handles(client, &pwh);	if ((win == WINDOW_HANDLES_NULL) || (pwh == PIXWIN_HANDLES_NULL))		return(-1);	if ((pwh->flags ^ flags) & PW_RETAIN) {		if ((flags & PW_RETAIN) &&		    (pwh->pw->pw_prretained == ((struct pixrect *)0)))			win_set_retain(pwh->pw, win);		else if (pwh->flags & PW_RETAIN) {			(void)pr_destroy(pwh->pw->pw_prretained);			pwh->pw->pw_prretained = (struct pixrect *)0;		}	}	pwh->flags = flags; 	return(0);}u_intwin_get_flags(client)	Notify_client client;{	Pixwin_handles *pwh;	Window_handles *win = win_get_handles(client, &pwh);	if ((win == WINDOW_HANDLES_NULL) || (pwh == PIXWIN_HANDLES_NULL))		return(0);	return(pwh->flags);}Notify_errorwin_post_id(client, id, when)	Notify_client client;	short id;	Notify_event_type when;{	Pixwin_handles *pwh;	Window_handles *win = win_get_handles(client, &pwh);	int fd = win_get_fd(client);	if (win == WINDOW_HANDLES_NULL)		return(NOTIFY_UNKNOWN_CLIENT);	/* TODO: Get current event from kernel instead of win_event */	/* In light of keymapping, probably don't want to do this */	/* Using event_set_id() will zero out the upper 8 bit of the */	/* shiftmask.  This is kind of redundant, since win_keymap_map() */	/* will set those bit.  But this is good practice for consistency */	event_set_id(&win->event, id);	/*	 * Event is mapped to insure semantic event is correct in the	 * event struct.  It appears that flags and shiftmask are obtained	 * implicitly elsewhere.	 */	(void)win_keymap_map(fd, &win->event);	return (win_send(pwh, &win->event, when, (Notify_arg)0, win_copy_event,	    win_free_event));}Notify_errorwin_post_id_and_arg(client, id, when, arg, copy_func, release_func)	Notify_client client;	short id;	Notify_event_type when;	Notify_arg arg;	Notify_copy copy_func;	Notify_release release_func;{	Pixwin_handles *pwh;	Window_handles *win = win_get_handles(client, &pwh);	int fd = win_get_fd(client);	if (win == WINDOW_HANDLES_NULL)		return(NOTIFY_UNKNOWN_CLIENT);	/* TODO: Get current event from kernel instead of win_event */	/* In light of keymapping, probably don't want to do this */	/* Using event_set_id() will zero out the upper 8 bit of the */	/* shiftmask.  This is kind of redundant, since win_keymap_map() */	/* will set those bit.  But this is good practice for consistency */	event_set_id(&win->event, id);	/*	 * Event is mapped to insure semantic event is correct in the	 * event struct.  It appears that flags and shiftmask are obtained	 * implicitly elsewhere.	 */	(void)win_keymap_map(fd, &win->event);	return (win_send(pwh, &win->event, when, arg, copy_func, release_func));}Notify_errorwin_post_event(client, event, when)	Notify_client client;	Event *event;	Notify_event_type when;{	Pixwin_handles *pwh;	Window_handles *win = win_get_handles(client, (Pixwin_handles **)0);	int fd = win_get_fd(client);	if (win == WINDOW_HANDLES_NULL)		return(NOTIFY_UNKNOWN_CLIENT);	/* Find client for this event */	if ((pwh = win_find_consumer(win, event)) == PIXWIN_HANDLES_NULL)		return(NOTIFY_UNKNOWN_CLIENT);	/* Remember this event as latest one for this window */	(void)win_keymap_map(fd, event);	win->event = *event;	/* Send event */	return (win_send(pwh, event, when, (Notify_arg)0, 		win_copy_event, win_free_event));}Notify_errorwin_post_event_arg(client, event, when, arg, copy_func, release_func)	Notify_client client;	Event *event;	Notify_event_type when;	Notify_arg arg;	Notify_copy copy_func;	Notify_release release_func;{	Pixwin_handles *pwh;	Window_handles *win = win_get_handles(client, &pwh);	int fd = win_get_fd(client);	if (win == WINDOW_HANDLES_NULL)		return(NOTIFY_UNKNOWN_CLIENT);	/* Find client for this event */	if ((pwh = win_find_consumer(win, event)) == PIXWIN_HANDLES_NULL)		return(NOTIFY_UNKNOWN_CLIENT);	/* Remember this event as latest one for this window */	win->event = *event;	(void)win_keymap_map(fd, &win->event);	/* Send event */	return (win_send(pwh, event, when, arg, copy_func, release_func));}/*ARGSUSED*/Notify_argwin_copy_event(client, arg, event_ptr)	Notify_client client;	Notify_arg arg;	Event **event_ptr;{	caddr_t malloc();	Event *event_new;	if (*event_ptr != EVENT_NULL) {		event_new = (Event *) (LINT_CAST(sv_malloc(sizeof (Event))));		*event_new = **event_ptr;		*event_ptr = event_new;	}	return (0);}/*ARGSUSED*/voidwin_free_event(client, arg, event)	Notify_client client;	Notify_arg arg;	Event *event;{	if (event != EVENT_NULL)		free((caddr_t)event);}intwin_get_fd(client)	Notify_client client;{	Pixwin_handles *pwh;	Window_handles *win = win_get_handles(client, &pwh);	if (win == WINDOW_HANDLES_NULL)		return(-1);	else		return(pwh->pw->pw_windowfd);

⌨️ 快捷键说明

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