283 lines
7.0 KiB
C
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;
|
|
}
|