Init
This commit is contained in:
250
sys/sunwindowdev/wincms.c
Normal file
250
sys/sunwindowdev/wincms.c
Normal file
@@ -0,0 +1,250 @@
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)wincms.c 1.1 94/10/31 SMI";
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Copyright (c) 1987 by Sun Microsystems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* SunWindows Desktop colormap sharing code.
|
||||
*/
|
||||
|
||||
#include <sunwindowdev/wintree.h>
|
||||
#include <sys/kmem_alloc.h>
|
||||
|
||||
int winenforcecmstd = 1;
|
||||
void dtop_set_bkgnd();
|
||||
|
||||
int
|
||||
dtop_cmsalloc(dtop, size)
|
||||
register struct desktop *dtop;
|
||||
long size;
|
||||
{
|
||||
int addr = cms_alloc((struct map *)dtop->dt_rmp, size);
|
||||
|
||||
if (addr == 0)
|
||||
return (-1);
|
||||
else
|
||||
return (addr - CRM_ADDROFFSET);
|
||||
}
|
||||
|
||||
dtop_cmsfree(dtop, w)
|
||||
register struct desktop *dtop;
|
||||
register struct window *w;
|
||||
{
|
||||
struct window *dtop_cmsmatch();
|
||||
|
||||
/*
|
||||
* Releasing color map segment.
|
||||
*/
|
||||
|
||||
if (dtop->dt_cmsize && w->w_cms.cms_size &&
|
||||
(dtop_cmsmatch(dtop, w, &w->w_cms) == NULL)) {
|
||||
if (w->w_flags & WF_CMSHOG)
|
||||
win_freecmapdata(w);
|
||||
else {
|
||||
/*
|
||||
* Guard against the case in which w was allocated,
|
||||
* a cms segment was assigned, the dtop was closed,
|
||||
* the w->w_pid was left hung, a new dtop was created,
|
||||
* w->w_pid was waken to end up on the new dtop,
|
||||
* w is eventually closed, w's previously assigned
|
||||
* cms segment (now invalid) is about to be freed
|
||||
* (which would cause a panic.
|
||||
*/
|
||||
if ((dtop->dt_rootwin &&
|
||||
dtop->dt_rootwin->w_pid <= w->w_pid))
|
||||
rmfree((struct map *)dtop->dt_rmp,
|
||||
(long)w->w_cms.cms_size,
|
||||
(u_long)(w->w_cms.cms_addr + CRM_ADDROFFSET));
|
||||
/* Reset addr 0 because special for fullscreen access */
|
||||
if (w->w_cms.cms_addr == 0) {
|
||||
dtop_set_bkgnd(dtop);
|
||||
}
|
||||
}
|
||||
}
|
||||
w->w_flags &= ~WF_CMSHOG;
|
||||
bzero((caddr_t)&w->w_cms, sizeof (struct colormapseg));
|
||||
bzero((caddr_t)&w->w_cmap, sizeof (struct cms_map));
|
||||
w->w_cmapdata = 0;
|
||||
}
|
||||
|
||||
struct window *
|
||||
dtop_cmsmatch(dtop, w, cms)
|
||||
struct desktop *dtop;
|
||||
struct window *w;
|
||||
struct colormapseg *cms;
|
||||
{
|
||||
register int wi;
|
||||
register struct window *wtmp;
|
||||
|
||||
/*
|
||||
* Must search all open windows instead of enumerating dtop because
|
||||
* need to match cms's whose windows are not in the tree currently.
|
||||
*/
|
||||
for (wi = 0; wi != win_nwindows; wi++) {
|
||||
wtmp = winbufs[wi];
|
||||
if (wtmp != NULL && wtmp != w &&
|
||||
(wtmp->w_flags & WF_OPEN) &&
|
||||
wtmp->w_desktop == dtop &&
|
||||
strncmp(cms->cms_name, wtmp->w_cms.cms_name,
|
||||
CMS_NAMESIZE) == 0)
|
||||
return (wtmp);
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
caddr_t
|
||||
dtop_alloccmapdata(dtop, cmap, size)
|
||||
struct desktop *dtop;
|
||||
register struct cms_map *cmap;
|
||||
int size;
|
||||
{
|
||||
caddr_t cmapdata = new_kmem_zalloc((u_int)3*size, KMEM_SLEEP);
|
||||
|
||||
if (cmapdata == 0) {
|
||||
printf("Couldn't allocate colormap buffer\n");
|
||||
cms_freecmapdata(cmapdata, cmap, size);
|
||||
} else {
|
||||
cmap->cm_red = (u_char *)cmapdata;
|
||||
cmap->cm_green = cmap->cm_red + size;
|
||||
cmap->cm_blue = cmap->cm_green + size;
|
||||
dtop_stdizecmap(dtop, cmap, 0, size);
|
||||
}
|
||||
return (cmapdata);
|
||||
}
|
||||
|
||||
dtop_stdizecmap(dtop, cmap, addr, size)
|
||||
register struct desktop *dtop;
|
||||
register struct cms_map *cmap;
|
||||
int addr, size;
|
||||
{
|
||||
register struct singlecolor *bkgnd = &dtop->dt_screen.scr_background;
|
||||
register struct singlecolor *frgnd = &dtop->dt_screen.scr_foreground;
|
||||
struct singlecolor *tmpgnd;
|
||||
register int fgnd_index = addr + size - 1, bgnd_index = addr;
|
||||
|
||||
/*
|
||||
* Standardize colormap by setting the foreground and background
|
||||
* only if they are the same. This is meant to reduce disasterous
|
||||
* blanking of the screen by errant programs.
|
||||
*/
|
||||
if (winenforcecmstd && (size > 0) &&
|
||||
cmap->cm_red[bgnd_index] == cmap->cm_red[fgnd_index] &&
|
||||
cmap->cm_green[bgnd_index] == cmap->cm_green[fgnd_index] &&
|
||||
cmap->cm_blue[bgnd_index] == cmap->cm_blue[fgnd_index]) {
|
||||
/*
|
||||
* Use foreground and background from dtop.
|
||||
* These were made sure to be different in user process
|
||||
* that called WIN_SCREENNEW (see sunwindow/win_screen.c).
|
||||
*/
|
||||
if (dtop->dt_screen.scr_flags & SCR_SWITCHBKGRDFRGRD) {
|
||||
tmpgnd = bkgnd;
|
||||
bkgnd = frgnd;
|
||||
frgnd = tmpgnd;
|
||||
}
|
||||
cmap->cm_red[bgnd_index] = bkgnd->red;
|
||||
cmap->cm_green[bgnd_index] = bkgnd->green;
|
||||
cmap->cm_blue[bgnd_index] = bkgnd->blue;
|
||||
cmap->cm_red[fgnd_index] = frgnd->red;
|
||||
cmap->cm_green[fgnd_index] = frgnd->green;
|
||||
cmap->cm_blue[fgnd_index] = frgnd->blue;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Colormap specific routines
|
||||
*/
|
||||
cms_freecmapdata(cmapdata, cmap, size)
|
||||
register caddr_t cmapdata;
|
||||
register struct cms_map *cmap;
|
||||
int size;
|
||||
{
|
||||
cmap->cm_red = 0;
|
||||
cmap->cm_green = 0;
|
||||
cmap->cm_blue = 0;
|
||||
if (cmapdata == 0)
|
||||
return;
|
||||
kmem_free((caddr_t)cmapdata, (u_int)3*size);
|
||||
}
|
||||
|
||||
int
|
||||
cms_alloc(rmp, size)
|
||||
struct map *rmp;
|
||||
long size;
|
||||
{
|
||||
register struct mapent *ep = (struct mapent *)(rmp + 1);
|
||||
register struct mapent *bp;
|
||||
register int expo, addr, addrlastok = -1;
|
||||
|
||||
/*
|
||||
* If size is not power of 2 then need to alloc at addr == 0.
|
||||
*/
|
||||
for (expo = 1; expo <= 8 /* 2**8==256 */; ++expo) {
|
||||
if (size == (1 << expo)) {
|
||||
/*
|
||||
* Addr % size must be zero.
|
||||
* Try to allocate from end of space in order to leave
|
||||
* room at addr == 0 for large consumers.
|
||||
*/
|
||||
for (bp = ep; bp->m_size; bp++) {
|
||||
addr = (bp->m_addr - CRM_ADDROFFSET) +
|
||||
bp->m_size - size;
|
||||
addr -= addr % size;
|
||||
if (addr >= (bp->m_addr - CRM_ADDROFFSET) &&
|
||||
addr % size == 0)
|
||||
addrlastok = addr;
|
||||
}
|
||||
if (addrlastok != -1)
|
||||
return (rmget(rmp, size,
|
||||
(u_long)(addrlastok + CRM_ADDROFFSET)));
|
||||
else
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
return (rmget(rmp, size, (u_long)(0 + CRM_ADDROFFSET)));
|
||||
}
|
||||
|
||||
void
|
||||
dtop_set_bkgnd(dtop)
|
||||
register Desktop *dtop;
|
||||
{
|
||||
register struct singlecolor *bkgnd;
|
||||
|
||||
if (dtop->dt_screen.scr_flags & SCR_SWITCHBKGRDFRGRD)
|
||||
bkgnd = &dtop->dt_screen.scr_foreground;
|
||||
else
|
||||
bkgnd = &dtop->dt_screen.scr_background;
|
||||
dtop->dt_cmap.cm_red[0] = bkgnd->red;
|
||||
dtop->dt_cmap.cm_green[0] = bkgnd->green;
|
||||
dtop->dt_cmap.cm_blue[0] = bkgnd->blue;
|
||||
}
|
||||
|
||||
void
|
||||
dtop_save_grnds(dtop)
|
||||
register Desktop *dtop;
|
||||
{
|
||||
int fg = dtop->dt_cmsize - 1;
|
||||
|
||||
dtop->dt_bkgnd_cache.red = dtop->dt_cmap.cm_red[0];
|
||||
dtop->dt_bkgnd_cache.green = dtop->dt_cmap.cm_green[0];
|
||||
dtop->dt_bkgnd_cache.blue = dtop->dt_cmap.cm_blue[0];
|
||||
dtop->dt_frgnd_cache.red = dtop->dt_cmap.cm_red[fg];
|
||||
dtop->dt_frgnd_cache.green = dtop->dt_cmap.cm_green[fg];
|
||||
dtop->dt_frgnd_cache.blue = dtop->dt_cmap.cm_blue[fg];
|
||||
}
|
||||
|
||||
void
|
||||
dtop_restore_grnds(dtop)
|
||||
register Desktop *dtop;
|
||||
{
|
||||
int fg = dtop->dt_cmsize - 1;
|
||||
|
||||
dtop->dt_cmap.cm_red[0] = dtop->dt_bkgnd_cache.red;
|
||||
dtop->dt_cmap.cm_green[0] = dtop->dt_bkgnd_cache.green;
|
||||
dtop->dt_cmap.cm_blue[0] = dtop->dt_bkgnd_cache.blue;
|
||||
dtop->dt_cmap.cm_red[fg] = dtop->dt_frgnd_cache.red;
|
||||
dtop->dt_cmap.cm_green[fg] = dtop->dt_frgnd_cache.green;
|
||||
dtop->dt_cmap.cm_blue[fg] = dtop->dt_frgnd_cache.blue;
|
||||
}
|
||||
Reference in New Issue
Block a user