/* * Copyright (c) 1986, 1987, 1988, 1989 by Sun Microsystems, Inc. * Permission to use, copy, modify, and distribute this software for any * purpose and without fee is hereby granted, provided that the above * copyright notice appears in all copies and that both that copyright * notice and this permission notice are retained, and that the name * of Sun Microsystems, Inc., not be used in advertising or publicity * pertaining to this software without specific, written prior permission. * Sun Microsystems, Inc., makes no representations about the suitability * of this software or the interface defined in this software for any * purpose. It is provided "as is" without express or implied warranty. */ #if !defined(lint) && !defined(NOID) static char sccsid[] = "@(#)windowddsubs.c 1.1 94/10/31 SMI"; #endif /* * Copyright 1986-1989, Sun Microsystems, Inc. */ #include #include #include #include "coretypes.h" #include "corevars.h" #include #include #include #define NULL 0 int _core_gfxenvfd = -1; static char *srchptr; static struct screen *scrptr; static int foundscreen; _core_get_window_vwsurf(pwprfdp, pidp, colorflg, vsurfp) int *pwprfdp, *pidp, colorflg; struct vwsurf *vsurfp; { int i1, i2; static char name[DEVNAMESIZE]; static char *argvarray[] = {"view_surface", name, 0}; static char initstring[80] = "WINDOW_INITIALDATA="; static char *envparray[] = {0, 0}; int pwprfd, parentfd, fd, pipefd[2]; int pid; struct screen screen; int fbfd; int chkscreen(), chkcolor(); if ((*vsurfp->windowname != '\0') && !(vsurfp->flags & VWSURF_NEWFLG)) { if ((parentfd = openspecifiedwindow(vsurfp, colorflg)) < 0) return(1); if ((pwprfd = win_getnewwindow()) < 0) { close(parentfd); return(1); } if (win_insertblanket(pwprfd, parentfd)) { close(parentfd); close(pwprfd); return(1); } close(parentfd); _core_gfxenvfd = pwprfd; *pwprfdp = pwprfd; *pidp = getpid(); } else if ((_core_gfxenvfd == -1) && !(vsurfp->flags & VWSURF_NEWFLG) && (*vsurfp->screenname == '\0')) { if ((parentfd = opengfxwindowfromenv(colorflg)) < 0) return(1); if ((pwprfd = win_getnewwindow()) < 0) { close(parentfd); return(1); } if (win_insertblanket(pwprfd, parentfd)) { close(parentfd); close(pwprfd); return(1); } close(parentfd); _core_gfxenvfd = pwprfd; *pwprfdp = pwprfd; *pidp = getpid(); } else { if (*vsurfp->screenname != '\0') { foundscreen = FALSE; srchptr = vsurfp->screenname; scrptr = &screen; win_enumall(chkscreen); if (!foundscreen) return(1); if ((fbfd = open(screen.scr_fbname, O_RDWR, 0)) < 0) return(1); if (chkcolor(colorflg, fbfd)) { close(fbfd); return(1); } close(fbfd); } else if (_core_gfxenvfd != -1) { win_screenget(_core_gfxenvfd, &screen); if ((fbfd = open(screen.scr_fbname, O_RDWR, 0)) < 0) return(1); if (chkcolor(colorflg, fbfd)) { close(fbfd); return(1); } close(fbfd); } else { if ((fd = opengfxwindowfromenv(colorflg)) < 0) return(1); win_screenget(fd, &screen); close(fd); } if (pipe(pipefd) < 0) return(1); if ((pid = vfork()) == 0) { /* child process */ strncpy(name, screen.scr_rootname, DEVNAMESIZE); if (vsurfp->ptr == NULL) envparray[0] = NULL; else { envparray[0] = initstring; strncpy(initstring + 19, *vsurfp->ptr, 60); } if (dup2(pipefd[1], 1) < 0) _exit(0); close(0); /* assume fds 0,1,2 are left */ close(2); /* undisturbed by SunCore programs */ /* so it is ok to close them */ i2 = getdtablesize(); for (i1 = 3; i1 < i2; i1++) fcntl(i1, F_SETFD, 1); /*close on exec*/ execve("/usr/lib/view_surface", argvarray, envparray); _exit(0); /* only return if unable to exec */ } close(pipefd[1]); /* parent process */ if (pid < 0) { close(pipefd[0]); return(1); } if (read(pipefd[0], name, DEVNAMESIZE) < DEVNAMESIZE) { close(pipefd[0]); kill(pid, 9); return(1); } close(pipefd[0]); if ((pwprfd = open(name, O_RDWR, 0)) < 0) { kill(pid, 9); return(1); } win_setowner(pwprfd, getpid()); *pwprfdp = pwprfd; *pidp = pid; } return(0); } static int opengfxwindowfromenv(colorflg) int colorflg; { int gwfd, fbfd; char name[DEVNAMESIZE]; struct screen screen; int chkcolor(); if (we_getgfxwindow(name)) return(-1); if ((gwfd = open(name, O_RDWR, 0)) < 0) return(-1); win_screenget(gwfd, &screen); if ((fbfd = open(screen.scr_fbname, O_RDWR, 0)) < 0) { close(gwfd); return(-1); } if (chkcolor(colorflg, fbfd)) { close(fbfd); close(gwfd); return(-1); } close(fbfd); return(gwfd); } static int openspecifiedwindow(vsurfp, colorflg) struct vwsurf *vsurfp; int colorflg; { int gwfd, fbfd; struct screen screen; int chkcolor(); if ((gwfd = open(vsurfp->windowname, O_RDWR, 0)) < 0) return(-1); win_screenget(gwfd, &screen); if ((fbfd = open(screen.scr_fbname, O_RDWR, 0)) < 0) { close(gwfd); return(-1); } if (chkcolor(colorflg, fbfd)) { close(fbfd); close(gwfd); return(-1); } close(fbfd); return(gwfd); } static int chkscreen(windowfd) int windowfd; { win_screenget(windowfd, scrptr); if (strcmp(srchptr, scrptr->scr_fbname) == 0) { foundscreen = TRUE; return(TRUE); } return(FALSE); } static chkcolor(colorflg, fbfd) int colorflg, fbfd; { struct fbgattr attr; return (ioctl(fbfd, FBIOGATTR, &attr) == -1 || chkcolor2(colorflg, &attr.fbtype)) && (ioctl(fbfd, FBIOGTYPE, &attr.fbtype) == -1 || chkcolor2(colorflg, &attr.fbtype)); } static chkcolor2(colorflg, fb) struct fbtype *fb; { switch (colorflg) { case BW_FB: return fb->fb_depth != 1; case COLOR_FB: return fb->fb_depth != 8; case BW_COLOR_FB: return 0; case GP1_FB: return fb->fb_type != FBTYPE_SUN2GP; default: return 1; } }