2021-10-11 18:37:13 -03:00

283 lines
7.0 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 appear 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.
*/
#ifndef lint
static char sccsid[] = "@(#)gp1_control.c 1.1 94/10/31 Copyr 1986 Sun Micro";
#endif
/*
* Copyright (c) 1986 by Sun Microsystems, Inc.
*/
#include <sunwindow/window_hs.h>
#include <sys/ioctl.h>
#include <sun/gpio.h>
#include "coretypes.h"
#include "corevars.h"
#include "gp1_pwpr.h"
#include <pixrect/gp1cmds.h>
#include <stdio.h>
#include <signal.h>
extern int _core_client;
_core_gp1_winupdate(ws, port, attr)
register struct windowstruct *ws;
register porttype *port;
register struct gp1_attr *attr;
{
int xpixmin, xpixmax, ypixmin, ypixmax;
_core_gp1_pw_updclplst( ws->pixwin, attr);
xpixmin = (port->xmin * ws->xscale >> 15) + ws->xoff + attr->org_x;
xpixmax = (port->xmax * ws->xscale >> 15) + ws->xoff + attr->org_x;
attr->xscale = ((float) (xpixmax - xpixmin)) / (float) 2.0;
attr->xoffset = ((float) (xpixmax + xpixmin)) / (float) 2.0;
ypixmin = ws->yoff - (port->ymin * ws->yscale >> 15) + attr->org_y;
ypixmax = ws->yoff - (port->ymax * ws->yscale >> 15) + attr->org_y;
attr->yscale = ((float) (ypixmax - ypixmin)) / (float) 2.0;
attr->yoffset = ((float) (ypixmax + ypixmin)) / (float) 2.0;
attr->zscale = (float)(port->zmax - port->zmin);
attr->zoffset = (float) port->zmin;
/* non screen (ndc) scaling */
attr->ndcxscale = ((float)(port->xmax - port->xmin)) / (float) 2.0;
attr->ndcxoffset = ((float)(port->xmax + port->xmin)) / (float) 2.0;
attr->ndcyscale = ((float)(port->ymax - port->ymin)) / (float) 2.0;
attr->ndcyoffset = ((float)(port->ymax + port->ymin)) / (float) 2.0;
attr->ndczscale = (float)(port->zmax - port->zmin);
attr->ndczoffset = (float) port->zmin;
attr->xfrmtype = XFORMTYPE_CHANGE;
}
/*
* _core_gp1_pw_lock and _core_gp1_pw_updclplst return:
* 0 if org_x and org_y are unchanged from last call
* 1 if either org_x or org_y has changed
*
* Note that these can change even though no SIGWINCH is received, but
* they cannot change when the screen is locked. Thus it should suffice
* to check the return code from _core_gp1_pw_lock and if it is non-zero
* update the gp1 NDC to screen transform.
*/
_core_gp1_pw_lock(pw, r, ptr)
struct pixwin *pw;
struct rect *r;
struct gp1_attr *ptr;
{
int retcode;
pw_lock(pw, r);
if (pw->pw_clipdata->pwcd_clipid == ptr->clipid)
return(0);
retcode = _core_gp1_pw_updclplst(pw, ptr);
if (ptr->hwzbuf) {
pw_unlock(pw);
ptr->forcerepaint = TRUE;
(void)_core_winsig();
pw_lock(pw, r);
}
return (retcode);
}
int _core_gp1_stblk_alloc(fd)
int fd;
{
int i;
if( ioctl(fd, GP1IO_GET_STATIC_BLOCK, &i) )
return (-1);
else
return(i);
}
_core_gp1_stblk_free(fd, num)
int num;
{
if ( ioctl(fd, GP1IO_FREE_STATIC_BLOCK, &num) )
return(-1);
else
return(0);
}
_core_gp1_chkloc(addr, fd)
short *addr;
int fd;
{
int i;
/* about a 5 second timeout */
for (i=0; i<600000; i++) {
if (!*addr) {
return(0);
}
}
gp1_kern_gp_restart(fd, 0);
return(-1);
}
Notify_value
_core_sigxcpu()
{
/* Receive this signal whenever kernel resets GP */
/* Must assume that all GP state has been lost for this process */
int gpsentsignal;
viewsurf *sp;
ddargtype ddstruct;
gpsentsignal = FALSE;
for (sp = &_core_surface[0]; sp < &_core_surface[MAXVSURF]; sp++) {
if (!sp->vinit)
continue;
if (sp->hphardwr) {
ddstruct.opcode = CHKGPRESETCOUNT;
ddstruct.instance = sp->vsurf.instance;
if ((* sp->vsurf.dd)(&ddstruct))
gpsentsignal = TRUE;
}
}
/* if SIGXCPU was not sent by the GP pass it on */
if (gpsentsignal) {
return (NOTIFY_DONE);
} else {
return (NOTIFY_IGNORED);
}
}
_core_gp1_pw_updclplst(pw, ptr)
struct pixwin *pw;
struct gp1_attr *ptr;
{
int nrect;
unsigned int bitvec;
short offset, *gp1_addr, *nptr;
register short *bufptr;
struct pixwin_prlist *prl;
struct gp1pr *dmd;
int x, y, retcode, cnt;
ptr->clipid = pw->pw_clipdata->pwcd_clipid;
Restart:
cnt = ptr->resetcnt;
retcode = 0;
dmd = gp1_d(pw->pw_pixrect);
gp1_addr = (short *) dmd->gp_shmem;
while((offset = gp1_alloc(gp1_addr, 1, &bitvec, dmd->minordev,
dmd->ioctl_fd)) == 0)
;
bufptr = &gp1_addr[offset];
*bufptr++ = GP1_USEFRAME | (ptr->statblkindx & 0x7);
*bufptr++ = GP1_SETCLPLST;
nptr = bufptr++;
if (pw->pw_clipdata->pwcd_state == PWCD_NULL)
{
*nptr = 1;
*bufptr++ = 0;
*bufptr++ = 0;
*bufptr++ = 0;
*bufptr++ = 0;
}
else
{ /* better be PWCD_SINGLERECT or PWCD_MULTIRECTS */
nrect = 0;
dmd = gp1_d(pw->pw_clipdata->pwcd_prmulti);
x = dmd->cgpr_offset.x;
y = dmd->cgpr_offset.y;
if (x != ptr->org_x | y != ptr->org_y)
{
ptr->org_x = x;
ptr->org_y = y;
retcode = 1;
}
for(prl = pw->pw_clipdata->pwcd_prl; prl; prl = prl->prl_next)
{
dmd = gp1_d(prl->prl_pixrect);
*bufptr++ = dmd->cgpr_offset.x;
*bufptr++ = dmd->cgpr_offset.y;
*bufptr++ = prl->prl_pixrect->pr_size.x;
*bufptr++ = prl->prl_pixrect->pr_size.y;
if(++nrect == 60)
break;
}
*nptr = nrect;
}
*bufptr++ = GP1_EOCL | GP1_FREEBLKS;
CORE_GP_PUT_INT(bufptr, &bitvec);
if (gp1_post(gp1_addr, offset, dmd->ioctl_fd))
{
while (cnt == ptr->resetcnt)
;
goto Restart;
}
ptr->clplstchg = FALSE;
return(retcode);
}
_core_gp1_reset(wind, gp1attr, port)
struct windowstruct *wind;
struct gp1_attr *gp1attr;
porttype *port;
{
struct gp1pr *dmd;
short * gp1_addr;
register short *shmptr;
int offset;
unsigned int bitvec;
int i, j, cnt;
register float *matptr;
struct pixwin *pw = wind->pixwin;
Restart:
cnt = gp1attr->resetcnt;
if (_core_gp1_pw_updclplst(pw, gp1attr))
_core_gp1_winupdate(wind, port, gp1attr);
gp1attr->attrchg = TRUE;
_core_gp1_snd_attr(pw, gp1attr);
_core_gp1_snd_xfrm_attr(pw, gp1attr, gp1attr->xfrmtype);
dmd = gp1_d(pw->pw_pixrect);
gp1_addr = gp1attr->gp1_addr;
while((offset = gp1_alloc(gp1_addr, 1, &bitvec, dmd->minordev,
dmd->ioctl_fd)) == 0)
;
shmptr = &gp1_addr[offset];
*shmptr++ = GP1_USEFRAME | (gp1attr->statblkindx);
matptr = (float *) gp1attr->mtxlist[0];
for (i = 0; i < 6; i++)
{
*shmptr++ = GP1_SET_MATRIX_3D | i;
for (j = 0; j < 16; j++)
CORE_GP_PUT_FLOAT(shmptr, matptr);
matptr++;
}
*shmptr++ = GP1_SELECTMATRIX | 1;
*shmptr++ = GP1_EOCL | GP1_FREEBLKS;
CORE_GP_PUT_INT(shmptr, &bitvec);
if (gp1_post(gp1_addr, offset, dmd->ioctl_fd))
{
while (cnt == gp1attr->resetcnt)
;
goto Restart;
}
gp1attr->needreset = FALSE;
}