📄 pw_cms.c
字号:
#ifndef lint#ifdef sccsstatic char sccsid[] = "@(#)pw_cms.c 1.1 92/07/30 Copyr 1986 Sun Micro";#endif#endif/* * Copyright (c) 1986 by Sun Microsystems, Inc. *//* * Pw_cms.c: Implement the colormap segment sharing aspect of * the pixwin.h interface. */#include <sys/types.h>#include <sys/time.h>#include <sys/ioctl.h>#include <errno.h>#include <stdio.h>#include <errno.h>#include <pixrect/pixrect.h>#include <pixrect/pr_util.h>#include <pixrect/pr_dblbuf.h>#include <pixrect/pr_planegroups.h>#include <pixrect/memvar.h>#include <sunwindow/rect.h>#include <sunwindow/rectlist.h>#include <sunwindow/cms.h>#include <sunwindow/cms_mono.h>#include <sunwindow/pixwin.h>#include <sunwindow/pw_dblbuf.h>#include <sunwindow/pw_util.h>#include <sunwindow/win_screen.h>#include <sunwindow/win_input.h>#include <sunwindow/win_ioctl.h>#include <strings.h>#ifndef PRE_IBIS#include <sun/fbio.h>#endifextern char *sprintf();static void pw_set_plane_group();static void pw_set_planes_limited();extern int errno;static cmsid;int pwenforcecmstd; /* Leave in case old program touching */ /* Not used anymore */#define NO_PLANE_PTR ((int *)0)struct colormapseg pw_defaultcms;u_char pw_defaultred[256];u_char pw_defaultgreen[256];u_char pw_defaultblue[256];struct cms_map pw_defaultmap = { pw_defaultred, pw_defaultgreen, pw_defaultblue};static int pw_plane_group_preference_set;static int pw_plane_group_preference;static int pw_global_groups_available_set;static struct win_plane_groups_available pw_global_groups_available;static void pw_read_plane_group_preference();static void pw_initialize_plane_group();static void pw_initialize_invisible_pg();static int pw_choose_prefered_plane_group();#ifndef PRE_FLAMINGOstatic void fullscreen_pw_start_plane_group_loop();static int fullscreen_pw_next_plane_group();static void fullscreen_pw_finish_plane_group();#endifstatic int fullscreen_pw_start_other_plane_group();static void fullscreen_pw_finish_other_plane_group();void pw_set_planes_directly();void win_set_plane_group();int win_get_plane_group();void pw_use_fast_monochrome();void pw_use_color24();/* * Colormap segment manager operations. */pw_setcmsname(pw, cmsname) struct pixwin *pw; char *cmsname;{ if (strncmp(pw->pw_cmsname, cmsname, CMS_NAMESIZE) != 0) { (void)win_clearcms(pw->pw_clipdata->pwcd_windowfd); (void)strncpy(pw->pw_cmsname, cmsname, CMS_NAMESIZE);#ifndef PRE_IBIS/* If the user tries to switch to a monochrome colormap segment, the window should no longer reside in the 24 bit planes. Question: Need to change plane groups here? This routine is called from tool_setgroundcolor () in libsuntool/tool/tla_set.c.*/ if (0 == strncmp (cmsname, CMS_MONOCHROME, CMS_NAMESIZE)) pw->pw_clipdata->pwcd_flags &= ~PWCD_COLOR24;#endif ndef PRE_IBIS }}pw_getcmsname(pw, cmsname) struct pixwin *pw; char *cmsname;{ (void)strncpy(cmsname, pw->pw_cmsname, CMS_NAMESIZE);}pwo_putattributes(pw, planes) struct pixwin *pw; register int *planes;{ struct colormapseg cms; int myplanes; int firstplanes; if (!planes) return(0); (void)pw_getcmsdata(pw, &cms, &firstplanes); if (cms.cms_size < 256) if (pw->pw_clipdata->pwcd_flags & PWCD_SET_CMAP_SIZE) { /* * restrict the mask to one less than the next power of 2 * greater or equal than the size of the cmap */ int mask; for (mask = 1; mask <= cms.cms_size; mask <<= 1); myplanes = *planes & mask - 1; } else myplanes = *planes & cms.cms_size - 1; else myplanes = *planes & PIX_ALL_PLANES; /* Put planes in pixrect for protection */#ifdef planes_fully_implemented pr_putattributes(pw->pw_pixrect, &myplanes);#else (void)pw_full_putattributes(pw->pw_pixrect, &myplanes);#endif planes_fully_implemented /* Reset clipping to get changes to clipping pixrects */ if (firstplanes != myplanes) (void)pw_getclipping(pw); return(0);}pwo_getattributes(pw, planes) struct pixwin *pw; int *planes;{ return(pr_getattributes(pw->pw_pixrect, planes));}/* * Will inherit screen inversion in single plane case. * Will initialize planes offset so that think are * writing to zero offset in multi-plane case. */pwo_putcolormap(pw, idx, count, red, green, blue) register Pixwin *pw; int idx, count; u_char red[], green[], blue[];{ struct colormapseg cms; struct cms_map cmap; int planes; int new_cms, base_pixrect_changed = 0; /* Determine status of cms */ (void)pw_getcmsdata(pw, &cms, NO_PLANE_PTR); /* See if changing cms */ new_cms = (strncmp(cms.cms_name, pw->pw_cmsname, CMS_NAMESIZE) != 0); /* * If pw_cmsname is not set then generate a unique name. * Obviously, this cms will not be shared. */ if (pw->pw_cmsname[0] == '\0') (void)sprintf(pw->pw_cmsname, "cms%10ld-%4ld", getpid(), cmsid++); /* * If changing colormap segments, maybe changing plane group. */ if (new_cms) { int original_plane_group, new_plane_group; /* * Choose plane group based on new cms name, user * preference and availability of plane groups. */ new_plane_group = pw_choose_prefered_plane_group(pw, &original_plane_group); /* Tell kernel about this window's plane group */ win_set_plane_group(pw->pw_windowfd, new_plane_group); /* * Put plane group in pixrect (got original_plane_group * from pixrect). */ if (original_plane_group != new_plane_group) pw_set_plane_group(pw, new_plane_group); /* * new_cms flag will cause change to pixrect to * be propagated to other pixrects in pixwin. */ } /* * Set the cms in the kernel using cmsname. * Kernel recognizes size<(original size) &| offset != 0 to be partial * cmap updates. */ cms.cms_addr = idx; cms.cms_size = count; (void)strncpy(cms.cms_name, pw->pw_cmsname, CMS_NAMESIZE); cmap.cm_red = red; cmap.cm_green = green; cmap.cm_blue = blue; (void)win_setcms(pw->pw_clipdata->pwcd_windowfd, &cms, &cmap); { /* * Indexed emulation in a true-color environment needs * some pw_colormap information. */ int win_fd; win_fd = (strcmp(cms.cms_name, CMS_MONOCHROME)) ? pw->pw_clipdata->pwcd_windowfd : -2; (void) pr_ioctl(pw->pw_pixrect, FBIOSWINFD, &win_fd); (void) pr_ioctl(pw->pw_pixrect, FBIOSCMS, &cms); } /* * Propagate actual color change. */ /* Clear shared locking inversion flag */ pw->pw_clipdata->pwcd_flags &= ~PWCD_CURSOR_INVERTED; if (pw->pw_pixrect->pr_depth == 1) { u_char rbefore[2], g[2], b[2], rafter[2]; struct screen screen; (void)pr_getcolormap(pw->pw_pixrect, 0, 2, rbefore, g, b); /* * One tells monochrome displays about being reversed * by doing a pr_putcolormap (although no colormap is modified). * Bws also don't use the planes attribute. */ (void)pr_putcolormap(pw->pw_pixrect, idx, count, red, green, blue); (void)pr_getcolormap(pw->pw_pixrect, 0, 2, rafter, g, b); /* * The zero entry of red controls the reverse mode on monochrome * devices. See if changed. */ if (rbefore[0] != rafter[0]) base_pixrect_changed = 1; /* set the revers-relative-to-kernel bit for cursor rops */ (void)win_screenget(pw->pw_windowfd, &screen); if (((screen.scr_background.red == rafter[0]) && (screen.scr_flags & SCR_SWITCHBKGRDFRGRD)) || ((screen.scr_background.red != rafter[0]) && (!(screen.scr_flags & SCR_SWITCHBKGRDFRGRD)))) pw->pw_clipdata->pwcd_flags |= PWCD_CURSOR_INVERTED; } else { if (new_cms) { /* Put planes in pixrect for offset protection */ if (cms.cms_size < 256) if (pw->pw_clipdata->pwcd_flags & PWCD_SET_CMAP_SIZE) { /* * set the mask to one less than the next power of * 2 greater or equal than the size of the cmap */ int mask; for (mask = 1; mask <= cms.cms_size; mask <<= 1); planes = mask - 1; } else planes = cms.cms_size - 1; else planes = PIX_ALL_PLANES;#ifdef planes_fully_implemented pr_putattributes(pw->pw_pixrect, &planes);#else (void)pw_full_putattributes(pw->pw_pixrect, &planes);#endif planes_fully_implemented } /* else used to AND with previous planes * in case user has restricted planes already * but this should be a no-op so removed this code. */ } /* * If changing colormap size, retained image may need to be * reallocated. */ if (new_cms && pw->pw_prretained) (void)pw_set_retain(pw, pw->pw_prretained->pr_width, pw->pw_prretained->pr_height); /* * Recompute clippers so that all accessing pixrects * are the same if change base pixrect or have new cms. */ if (base_pixrect_changed || new_cms) (void)pw_getclipping(pw); /* * Prepare surface of entire visible area of the pixwin. */ if (new_cms) (void)pw_preparesurface_full(pw, RECT_NULL, 1); return(0);}pwo_getcolormap(pw, idx, count, red, green, blue) struct pixwin *pw; int idx, count; u_char red[], green[], blue[];{ struct colormapseg cms; struct cms_map cmap; /* * If pw_cmsname is not set then error. */ if (pw->pw_cmsname[0] == '\0') { (void)fprintf(stderr, "pw_cmsname NULL in getcolormap\n"); return(EINVAL); } /* * Get cms from window system. */ cms.cms_addr = idx; cms.cms_size = count; (void)strncpy(cms.cms_name, pw->pw_cmsname, CMS_NAMESIZE); cmap.cm_red = red; cmap.cm_green = green; cmap.cm_blue = blue; (void)win_getcms(pw->pw_clipdata->pwcd_windowfd, &cms, &cmap); /* * Internal check. */ if (strncmp(pw->pw_cmsname, cms.cms_name, CMS_NAMESIZE) != 0) { (void)fprintf(stderr, "cms names differ in pw_getcolormap\n"); return(EINVAL); } return(0);}pw_preparesurface(pw, rect) register Pixwin *pw; struct rect *rect;{ (void)pw_preparesurface_full(pw, rect, 0);}pw_preparesurface_full(pw, rect, full) register Pixwin *pw; struct rect *rect; int full;{ struct rect rdest; struct colormapseg cms; char *plane_groups_available = pw->pw_clipdata->pwcd_plane_groups_available; int plane_group; int pw_dbl_wrstate; /* See if some other pixwin on this window changed the cms */ (void)pw_getcmsdata(pw, &cms, NO_PLANE_PTR); if (strncmp(pw->pw_cmsname, cms.cms_name, CMS_NAMESIZE) != 0) { /* Get current cms/planes of window for this pixwin */ (void)pw_initcms(pw); /* Update cms variable */ (void)pw_getcmsdata(pw, &cms, NO_PLANE_PTR); } /* Supply rdest if rect not supplied. Restrict to visible area. */ if (rect) (void)rect_intersection(&pw->pw_clipdata->pwcd_clipping.rl_bound, rect, &rdest); else rdest = pw->pw_clipdata->pwcd_clipping.rl_bound; /* See if anything to do */ if (rect_isnull(&rdest)) /* Assumes no side affects from calling this routine */ return; /* See if some other pixwin on this window changed the plane group */ if (plane_groups_available[PIXPG_OVERLAY_ENABLE] || plane_groups_available[PIXPG_VIDEO_ENABLE] || plane_groups_available[PIXPG_WID]) { /* NOTE: ADD HERE AS NEW ENABLE PLANES BECOME AVAILABLE */ /* Get this window's choice of planes from kernel */ plane_group = win_get_plane_group(pw->pw_windowfd, pw->pw_pixrect); if (plane_group != pw->pw_clipdata->pwcd_plane_group) { /* Get current cms/planes of window for this pixwin */ (void)pw_initcms(pw); /* Update plane_group variable */ plane_group = win_get_plane_group(pw->pw_windowfd, pw->pw_pixrect); } } /* * Get the state of the double buffering when there is no * fullscreen access. Set write to both. */ if ((pw->pw_clipdata->pwcd_flags & PWCD_DBL_AVAIL) && !(pw->pw_clipdata->pwcd_flags & PWCD_IGNORE_DBLSET)) { pw_dbl_wrstate = pw_dbl_get(pw, PW_DBL_WRITE); pw_dbl_set(pw, PW_DBL_WRITE, PW_DBL_BOTH, 0); } /* Remove cursor for duration of preparation */ (void)pw_lock(pw, &rdest); /* * Enable bits that program will be writing to. * Do before enable planes to avoid "ghost" image flashes. */ if (pw->pw_pixrect->pr_depth > 1 || plane_groups_available[PIXPG_OVERLAY_ENABLE] || plane_groups_available[PIXPG_VIDEO_ENABLE] || plane_groups_available[PIXPG_WID]) { /* NOTE: ADD HERE AS NEW ENABLE PLANES BECOME AVAILABLE */ /* Prepare depth > 1 pixwin's surface */ if ((pw->pw_clipdata->pwcd_flags & (PWCD_COLOR24|PWCD_VIDEO)) != (PWCD_COLOR24|PWCD_VIDEO) ) { pw_initialize_plane_group(pw, pr_get_plane_group(pw->pw_pixrect), (pw->pw_clipdata->pwcd_flags & PWCD_COLOR24) ? 0 : cms.cms_addr, &rdest); } } /* * else simple 1 deep pixwins clear own areas so don't prepare * surface because pixwins are supposed to clear (or set) their * own surfaces anyway. */ /* * The enable plane and other invisible plane groups are initialized * here. Do the "other" invisible plane groups last so as to not * slow down the preceived repaint speed so much. */ if (plane_groups_available[PIXPG_OVERLAY_ENABLE] || plane_groups_available[PIXPG_VIDEO_ENABLE] || plane_groups_available[PIXPG_WID]) { /* NOTE: ADD HERE AS NEW ENABLE PLANES BECOME AVAILABLE */ switch (plane_group) { case PIXPG_8BIT_COLOR: if (plane_groups_available[PIXPG_OVERLAY_ENABLE]) { pw_initialize_invisible_pg(pw, PIXPG_OVERLAY_ENABLE, 0, &rdest, plane_group); } if (plane_groups_available[PIXPG_VIDEO_ENABLE]) { pw_initialize_invisible_pg(pw, PIXPG_VIDEO_ENABLE, 0, &rdest, plane_group); } if (full && plane_groups_available[PIXPG_OVERLAY]) { pw_initialize_invisible_pg(pw, PIXPG_OVERLAY, 0, &rdest, plane_group); } if (plane_groups_available[PIXPG_WID]) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -