Files
Arquivotheca.SunOS-4.1.4/usr.lib/libsuntool/window/window.c
seta75D ff309bfe1c Init
2021-10-11 18:37:13 -03:00

423 lines
10 KiB
C

#ifndef lint
#ifdef sccs
static char sccsid[] = "@(#)window.c 1.1 94/10/31";
#endif
#endif
/*
* Copyright (c) 1985, 1988 by Sun Microsystems, Inc.
*/
/*-
WINDOW wrapper: creation and destruction
*/
/* ------------------------------------------------------------------------- */
#include <stdio.h>
#include <varargs.h>
#include <sys/types.h>
#include <dirent.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sunwindow/notify.h>
#include <sunwindow/rect.h>
#include <sunwindow/win_struct.h>
#include "sunwindow/sv_malloc.h"
#include <pixrect/pixrect.h> /* pr_ioctl */
#include <sunwindow/rect.h>
#include <sunwindow/rectlist.h>
#include <sunwindow/pixwin.h> /* struct pixwin */
#include <sys/ioctl.h>
#include <sun/fbio.h> /* FBIO* */
#ifdef KEYMAP_DEBUG
#include "../../libsunwindow/win/win_keymap.h"
#else
#include <sunwindow/win_keymap.h>
#endif
#include <suntool/frame.h> /* for font scanning */
#include <suntool/window_impl.h>
/* ------------------------------------------------------------------------- */
/*
* Public
*/
Window window_create();
int window_fd();
void window_main_loop();
int/*bool*/ window_done();
int/*bool*/ window_destroy();
void window_release_event_lock();
void window_refuse_kbd_focus();
/*
* Package private
*/
Pkg_extern int/*bool*/ window_set_avlist();
Pkg_private int win_appeal_to_owner();
Pkg_private Notify_value window_default_event_func();
Pkg_private Notify_value window_default_destroy_func();
Pkg_private Window win_set_client();
Pkg_private void win_clear_client();
Pkg_private void window_scan_and_convert_to_pixels();
/*
* Private
*/
Private Notify_value destroy_win_struct();
/* Only used in window_create() */
#define eexit(msg) \
if (error_msg) { \
(void)fprintf(stderr, "window: %s\n%s\n", msg, error_msg); \
exit(1); \
} else { \
(void)fprintf(stderr, "window: %s\n", msg); \
return NULL; \
}
/* ------------------------------------------------------------------------- */
/*VARARGS2*/
Window
window_create(base_frame, create_proc, va_alist)
struct window *base_frame;
caddr_t (*create_proc)();
va_dcl
{
register struct window *win;
caddr_t avlist[ATTR_STANDARD_SIZE];
register Attr_avlist attrs;
int well_behaved = TRUE, capable_of_layout = FALSE;
char *error_msg = NULL, *name = "window";
va_list valist;
static short font_scanned; /* = FALSE */
char *defaults_get_string();
struct pixfont *pw_pfsysopen();
struct pixwin *pw_open();
base_frame = client_to_win((Window)(LINT_CAST(base_frame)));
va_start(valist);
(void)attr_make(avlist, ATTR_STANDARD_SIZE, valist);
va_end(valist);
if (!font_scanned) {
char *fname =
defaults_get_string("/SunView/Font", "",(int *)NULL);
if (*fname != '\0')
(void)setenv("DEFAULT_FONT", fname);
}
for (attrs = avlist; *attrs; attrs = attr_next(attrs)) {
switch (attrs[0]) {
case WIN_NAME:
name = (char *)attrs[1];
break;
case WIN_ERROR_MSG:
error_msg = (char *)attrs[1];
break;
case WIN_COMPATIBILITY:
well_behaved = FALSE;
break;
case FRAME_ARGS:
case FRAME_ARGC_PTR_ARGV:
if (!font_scanned)
if (tool_parse_font((((Frame_attribute) attrs[0])
== FRAME_ARGS) ?
(int) (LINT_CAST(attrs[1])) :
*((int *)(LINT_CAST(attrs[1]))),
(char **)(LINT_CAST(attrs[2]))) == 1)
eexit("NULL arg for '-Wt' or '-font' option.");
break;
default:
break;
}
}
win = (struct window *)(LINT_CAST(sv_calloc(1, sizeof(struct window))));
if (!win) eexit("Unable to allocate additional storage. Malloc failed.");
win->type = WINDOW_TYPE;
win->name = name;
win->object = (caddr_t)win; /* Hopefully this is changed by create_proc */
win->fd = -1;
win->well_behaved = well_behaved;
win->show_updates = TRUE;
win->default_event_proc = (void (*)())window_default_event_func;
while (base_frame && !base_frame->layout_proc)
base_frame = base_frame->owner;
win->owner = base_frame;
if (well_behaved) {
win->fd = win_getnewwindow();
if (win->fd < 0) eexit("Window creation failed to get new fd");
if (base_frame == NULL) {
int parentlink;
char parentname[WIN_NAMESIZE];
if (we_getparentwindow(parentname))
eexit("Base frame not passed parent window in environment");
parentlink = win_nametonumber(parentname);
(void)win_setlink(win->fd, WL_PARENT, parentlink);
} else {
int parentlink;
parentlink = win_fdtonumber(base_frame->fd);
(void)win_setlink(win->fd, WL_PARENT, parentlink);
}
if (!(win->pixwin = pw_open(win->fd)))
eexit("Cannot open pixwin.");
win->show = TRUE;
}
if (!(win->font = pw_pfsysopen())) /* ?? Fix this (see frame) */
eexit("Cannot open system font.");
font_scanned = TRUE;
/*
* create subwindow in frame
*/
(void)win_set_client(win, win->object, TRUE);
if (base_frame && base_frame->layout_proc && well_behaved)
(base_frame->layout_proc)(base_frame->object, win->object,
WIN_CREATE, win->name);
if (!(create_proc)(win->object,avlist)) eexit("Subwindow creation failed.");
if (win->object == (caddr_t)win)
eexit("Subwindow failed to create underlying object.");
if (win->layout_proc)
(win->layout_proc)(win->object, win->object,
WIN_LAYOUT, &capable_of_layout);
if (!base_frame && !capable_of_layout)
eexit("Subwindow needs a base frame.");
if (base_frame && base_frame->layout_proc) {
(base_frame->layout_proc)(base_frame->object, win->object,
WIN_INSTALL, win->name);
}
if (well_behaved) /* Set attrs */
(void)window_set(win->object, ATTR_LIST, avlist, 0);
else { /* Set window attrs ONLY */
window_scan_and_convert_to_pixels(win,
(Window_attribute *)(LINT_CAST(avlist)));
(void)window_set_avlist(win, (Window_attribute *)(LINT_CAST(avlist)));
}
if (win->object != (caddr_t)win) {
(void)notify_interpose_destroy_func(win->object, destroy_win_struct);
}
win->created = TRUE;
/* sorry/hacked-up kludge for 12bit double buffer in 24bit frame buffer */
(void) pr_ioctl((Pixrect *)((Pixwin *)win->pixwin)->pw_pixrect, FBIOSRWINFD,
&(Pixwin *)win->pixwin->pw_clipdata->pwcd_windowfd);
return (Window)(LINT_CAST(win->object));
}
int
window_fd(window)
Window window;
{
struct window *win;
win = client_to_win(window);
if (!win) return -1;
return win->fd;
}
void
window_main_loop(frame)
Window frame;
{
struct window *win = client_to_win(frame);
if (!(win && win->object)) return;
if (win->show == FALSE) {
win->show = TRUE;
(void)win_remove(win->fd);
(void)win_insert(win->fd); /* install win in tree */
}
/* do the initial subwindow layout */
(void)tool_layoutsubwindows((struct tool *)(LINT_CAST(frame)));
(void)notify_start(); /* main loop */
}
int/*bool*/
window_done(win)
Window win;
{
register Window owner = win;
while (owner) win = owner, owner = window_get(owner, WIN_OWNER);
return window_destroy(win);
}
int/*bool*/
window_destroy(window)
Window window;
{
int result;
register struct window *win;
win = client_to_win(window);
if (!win) return FALSE;
if (win->object) {
if (NOTIFY_DESTROY_VETOED != notify_post_destroy(win->object,
DESTROY_CHECKING,
NOTIFY_IMMEDIATE)) {
(void)notify_post_destroy(win->object, DESTROY_CLEANUP, NOTIFY_SAFE);
result = TRUE;
} else {
result = FALSE;
}
} else {
win_clear_client((Window)(LINT_CAST(win)));
result = TRUE;
}
return result;
}
void
window_release_event_lock(window)
Window window;
{
(void)win_release_event_lock(window_fd(window));
}
void
window_refuse_kbd_focus(window)
Window window;
{
(void)win_refuse_kbd_focus(window_fd(window));
}
Pkg_private int
win_appeal_to_owner(adjust, win, op, datum)
int adjust;
struct window *win;
caddr_t op;
caddr_t datum;
{
if (win->owner && win->owner->layout_proc) {
(win->owner->layout_proc)
(win->owner->object, win->object, op, datum);
return adjust;
}
if (win->layout_proc && (adjust || !win->owner)) {
(win->layout_proc)(win->owner ? win->object : NULL,
win->object, op, datum);
return TRUE;
}
return TRUE;
}
Pkg_private Notify_value
window_default_event_func()
{
return NOTIFY_DONE;
}
Pkg_private Notify_value
window_default_destroy_func()
{
return NOTIFY_DONE;
}
Pkg_private void
win_clear_client(win)
Window win;
{
(void)win_set_client((struct window *)(LINT_CAST(win)),
(caddr_t)NULL, FALSE);
free(win);
}
Private Notify_value
destroy_win_struct(client, status)
register caddr_t client;
Destroy_status status;
{
register struct window *win = client_to_win(client);
Notify_value result = notify_next_destroy_func(client, status);
char tmpfile [MAXNAMLEN];
char pid_str[10];
register int i, j;
struct stat stat_buf;
extern unsigned tmtn_counter;
if (status == DESTROY_CLEANUP && win) {
if (win->well_behaved) {
(void)win_unregister(client);
(void)pw_close(win->pixwin);
}
/* This is done after the unregister to prevent double destroys */
if (win->owner && win->owner->layout_proc)
(win->owner->layout_proc)
(win->owner->object, client, WIN_DESTROY);
win_clear_client((Window)(LINT_CAST(win)));
/* Delete empty /tmp/TextXXXXX and /tmp/Tty.txt.aXXXXXX files */
(void)sprintf (pid_str, "%d", getpid());
for (i = tmtn_counter-1; i >= 0; i--) {
(void)sprintf (tmpfile, "/tmp/Text%s.%d", pid_str, i);
if (stat (tmpfile, &stat_buf) == 0 && stat_buf.st_size == 0) {
(void)unlink (tmpfile);
}
}
(void)strcpy (tmpfile, "/tmp/tty.txt.a00000");
for (i = strlen(pid_str), j=0; i >= 0; i--, j++) {
tmpfile[strlen(tmpfile)-i] = pid_str[j];
}
if (stat (tmpfile, &stat_buf) == 0 && stat_buf.st_size == 0) {
(void)unlink (tmpfile);
}
(void)strcat (tmpfile, "%");
if (stat (tmpfile, &stat_buf) == 0 && stat_buf.st_size == 0) {
(void)unlink (tmpfile);
}
result = NOTIFY_DONE;
}
return result;
}