275 lines
5.9 KiB
C
275 lines
5.9 KiB
C
/*
|
|
* 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 <sunwindow/window_hs.h>
|
|
#include <strings.h>
|
|
#include <vfork.h>
|
|
#include "coretypes.h"
|
|
#include "corevars.h"
|
|
#include <sys/file.h>
|
|
#include <sys/ioctl.h>
|
|
#include <sun/fbio.h>
|
|
#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;
|
|
}
|
|
}
|