📄 win_central.c
字号:
#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 + -