--- .empty Thu Jan 1 00:00:00 1970 +++ NEW/xc/programs/Xserver/hw/cg14/cg14-24.c Thu Jan 1 00:00:00 1970 @@ -0,0 +1,503 @@ +#include + +#include +#include +#include + +#include "cg14.h" +#include "vars.h" +#include "cg14-24.h" +#include "cg14curs.h" +#include "crossdepth.h" + +#define PSZ 32 +#include + +static ScreenRec *scr = 0; +static ColormapRec *instmap_8; +static ColormapRec *instmap_24; +static PixmapRec *pm_otherroot; +static RegionRec cur_24bpp; +static RegionRec cur_8bpp; +static RegionRec new_24bpp; +static RegionRec new_8bpp; +static RegionRec typetemp; + +PixmapRec *cg14_deepfb; + +static Bool savescreen(ScreenRec *s, int op) +{ + __typeof__(ctl->mctl) dbit; + + dbit = cg14_8only ? CG14_MCTL_PIXMODE_8 : CG14_MCTL_PIXMODE_32; + switch (op) + { case SCREEN_SAVER_FORCER: + break; + case SCREEN_SAVER_ON: + if ((ctl->rsr & CG14_RSR_REVMASK) > 0) + { ctl->mctl = dbit; + } + else + { ctl->mctl = dbit | CG14_MCTL_POWERCTL; + } + break; + case SCREEN_SAVER_OFF: + ctl->mctl = CG14_MCTL_ENABLEVID | dbit | CG14_MCTL_POWERCTL; + break; + default: + return(FALSE); + break; + } + return(TRUE); +} + +static Bool closescreen(int scrno, ScreenRec *s) +{ + Bool rv; + + if (! cg14_8only) (*s->DestroyPixmap)(pm_otherroot); + free_8bit_stuff(s); + if (! cg14_8only) (*s->DestroyPixmap)(cg14_deepfb); + REGION_UNINIT(scr,&cur_24bpp); + REGION_UNINIT(scr,&cur_8bpp); + REGION_UNINIT(scr,&new_24bpp); + REGION_UNINIT(scr,&new_8bpp); + REGION_UNINIT(scr,&typetemp); + switch (cg14_rootdepth) + { case 8: + s->CloseScreen = ds_8_CloseScreen; + rv = ds_8_CloseScreen(scrno,s); + break; + case 24: + s->CloseScreen = cfb32CloseScreen; + rv = cfb32CloseScreen(scrno,s); + break; + } + savescreen(s,SCREEN_SAVER_OFF); + return(rv); +} + +static void install_8(ColormapRec *cm) +{ + int i; + + if (cm == instmap_8) return; + if (instmap_8) WalkTree(instmap_8->pScreen,TellLostMap,&instmap_8->mid); + if ((cm->pVisual->class | DynamicClass) == DirectColor) + { for (i=0;i<256;i++) + { +#define MAP(col,Col) \ + (cm->col[(i&cm->pVisual->col##Mask)>>cm->pVisual->offset##Col].co.local.col>>8) + clut1->lut[i] = (MAP(blue,Blue) << 16) | (MAP(green,Green) << 8) | MAP(red,Red); +#undef MAP + } + } + else if (! (cm->pVisual->class & DynamicClass)) + { Entry *e; + e = &cm->red[0]; + for (i=0;i<256;i++,e++) + { clut1->lut[i] = ((e->co.local.blue >> 8) << 16) | + ((e->co.local.green >> 8) << 8) | + ((e->co.local.red >> 8) ); + } + } + else + { Entry *e; + e = &cm->red[0]; + for (i=0;i<256;i++,e++) + { if (e->fShared) + { clut1->lut[i] = ((e->co.shco.blue ->color >> 8) << 16) | + ((e->co.shco.green->color >> 8) << 8) | + ((e->co.shco.red ->color >> 8) ); + } + else if (e->refcnt) + { clut1->lut[i] = ((e->co.local.blue >> 8) << 16) | + ((e->co.local.green >> 8) << 8) | + ((e->co.local.red >> 8) ); + } + } + } + instmap_8 = cm; + WalkTree(cm->pScreen,TellGainedMap,&cm->mid); +} + +static void install_24(ColormapRec *cm) +{ + int i; + + if (cm == instmap_24) return; + if (instmap_24) WalkTree(instmap_24->pScreen,TellLostMap,&instmap_24->mid); + instmap_24 = cm; + WalkTree(cm->pScreen,TellGainedMap,&cm->mid); +} + +static void install(ColormapRec *cm) +{ + if ( (cm->pVisual->class == TrueColor) && + (cm->pVisual->ColormapEntries == 256) ) + { install_24(cm); + return; + } + install_8(cm); +} + +static void uninstall(ColormapRec *cm) +{ + ColormapRec *imrd; + ColormapRec **imop; + + switch (cg14_rootdepth) + { case 8: + imrd = instmap_8; + imop = &instmap_24; + break; + case 24: + imrd = instmap_24; + imop = &instmap_8; + break; + } + if (cm == imrd) + { Colormap defid; + defid = cm->pScreen->defColormap; + if (cm->mid != defid) + { ColormapRec *defmap; + defmap = LookupIDByType(defid,RT_COLORMAP); + if (defmap) + { (*cm->pScreen->InstallColormap)(defmap); + } + else + { ErrorF("can't find default colormap\n"); + } + } + } + else if (cm == *imop) + { WalkTree(cm->pScreen,TellLostMap,&cm->mid); + *imop = 0; + } +} + +static int list(ScreenRec *s __attribute__((__unused__)), Colormap *list) +{ + int i; + + i = 0; + if (instmap_8) list[i++] = instmap_8->mid; + if (instmap_24) list[i++] = instmap_24->mid; + return(i); +} + +static void store(ColormapRec *cm, int n, xColorItem *vals) +{ + xColorItem expanded[256]; + + if ( (cm->pVisual->class == TrueColor) && + (cm->pVisual->ColormapEntries == 256) ) return; + if (instmap_8 && (instmap_8 != cm)) return; + if ((cm->pVisual->class | DynamicClass) == DirectColor) + { n = cfbExpandDirectColors(cm,n,vals,&expanded[0]); + vals = &expanded[0]; + } + for (;n>0;n--,vals++) + { clut1->lut[vals->pixel] = ((vals->blue >> 8) << 16) | + ((vals->green >> 8) << 8) | + ((vals->red >> 8) ); + } +} + +static void ds_GetImage(DrawableRec *d, int x, int y, int w, int h, unsigned int fmt, unsigned long int pm, char *dst) +{ + if (d->depth == 8) + { ds_8_GetImage(d,x,y,w,h,fmt,pm,dst); + return; + } + cfbGetImage(d,x,y,w,h,fmt,pm,dst); +} + +static void ds_GetSpans(DrawableRec *d, int wmax, DDXPointPtr pts, int *wvec, int nsp, char *dst) +{ + if (d->depth == 8) + { ds_8_GetSpans(d,wmax,pts,wvec,nsp,dst); + return; + } + cfbGetSpans(d,wmax,pts,wvec,nsp,dst); +} + +static Bool create_window(WindowRec *w) +{ + switch (cg14_rootdepth) + { case 8: + if (!ds_8_CreateWindow(w)) return(FALSE); + if (w->drawable.depth == 24) w->devPrivates[frameWindowPrivateIndex].ptr = pm_otherroot; + return(TRUE); + break; + case 24: + if (!cfbCreateWindow(w)) return(FALSE); + if (w->drawable.depth == 8) w->devPrivates[frameWindowPrivateIndex].ptr = pm_otherroot; + return(TRUE); + break; + } +} + +static Bool ds_DestroyWindow(WindowRec *w) +{ + if (w->drawable.depth == 8) return(ds_8_DestroyWindow(w)); + return(cfbDestroyWindow(w)); +} + +static Bool ds_PositionWindow(WindowRec *w, int x, int y) +{ + if (w->drawable.depth == 8) return(ds_8_PositionWindow(w,x,y)); + return(cfbPositionWindow(w,x,y)); +} + +static Bool ds_ChangeWindowAttributes(WindowRec *w, unsigned long int mask) +{ + if (w->drawable.depth == 8) return(ds_8_ChangeWindowAttributes(w,mask)); + return(cfbChangeWindowAttributes(w,mask)); +} + +static void ds_PaintWindow(WindowRec *w, RegionRec *r, int what) +{ + if (w->drawable.depth == 8) return(ds_8_PaintWindow(w,r,what)); + return(cfbPaintWindow(w,r,what)); +} + +static Bool ds_CreateGC(GC *gc) +{ + if (gc->depth == 8) return(ds_8_CreateGC(gc)); + return(cfbCreateGC(gc)); +} + +/* + * cfbCopyWindow breaks in the presence of windows of depths other than + * the root's depth, so we can't just do the usual depth-switch trick. + * + * However, it turns out that the breakage is relatively easy to work + * around. The only reason we can get away with sticking a _pixmap_ + * in the root _window_ array is that cfbCopyWindow uses only the + * drawable from it. + */ +static void copy_window(WindowRec *w, DDXPointRec oo, RegionRec *src) +{ + extern WindowRec **WindowTable; + int sn; + WindowRec *rootsave; + + if (w->drawable.depth != cg14_rootdepth) + { sn = w->drawable.pScreen->myNum; + rootsave = WindowTable[sn]; + WindowTable[sn] = (void *) pm_otherroot; + } + switch (w->drawable.depth) + { case 8: + ds_8_CopyWindow(w,oo,src); + break; + case 24: + cfbCopyWindow(w,oo,src); + break; + } + if (w->drawable.depth != cg14_rootdepth) + { WindowTable[sn] = rootsave; + } +} + +static void set_depth_window(WindowRec *w) +{ + switch (w->drawable.depth) + { case 8: + REGION_SUBTRACT(scr,&new_24bpp,&new_24bpp,&w->borderClip); + REGION_UNION(scr,&new_8bpp,&new_8bpp,&w->borderClip); + break; + case 24: + REGION_SUBTRACT(scr,&new_8bpp,&new_8bpp,&w->borderClip); + REGION_UNION(scr,&new_24bpp,&new_24bpp,&w->borderClip); + break; + default: + FatalError("bad window depth %d",w->drawable.depth); + } +} + +static int set_depth_tree(WindowRec *w, int pd, int ind) +{ +#ifdef DEPTH_REGION_DEBUG + fprintf(stderr,"%*sset_depth_children: w=0x%x pd=%d\n",ind,"",w->drawable.id,pd); +#endif + if (w->drawable.depth != pd) + { set_depth_window(w); + pd = w->drawable.depth; + } + for (w=w->lastChild;w;w=w->prevSib) + { if (!w->viewable || (w->visibility == VisibilityFullyObscured)) continue; + set_depth_tree(w,pd,ind+2); + } +} + +static void set_depth_region(RegionRec *cur, RegionRec *new, int d) +{ + int i; + BoxRec *b; + + REGION_SUBTRACT(scr,&typetemp,new,cur); + b = REGION_RECTS(&typetemp); + for (i=REGION_NUM_RECTS(&typetemp)-1;i>=0;i--) + { set_depth(b[i].x1,b[i].y1,b[i].x2,b[i].y2,d); + } + REGION_COPY(scr,cur,new); +} + +static void install_depth_region(void) +{ + set_depth_region(&cur_24bpp,&new_24bpp,24); + set_depth_region(&cur_8bpp,&new_8bpp,8); +} + +static void post_validate(WindowRec *p, WindowRec *c, VTKind k) +{ +#ifdef DEPTH_REGION_DEBUG + fprintf(stderr,"post validate: parent "); + if (p) fprintf(stderr,"%08x",p->drawable.id); else fprintf(stderr,"(nil)"); + fprintf(stderr,", child "); + if (c) fprintf(stderr,"%08x",c->drawable.id); else fprintf(stderr,"(nil)"); + fprintf(stderr,", kind="); + switch (k) + { case VTOther: fprintf(stderr,"VTOther"); break; + case VTStack: fprintf(stderr,"VTStack"); break; + case VTMove: fprintf(stderr,"VTMove"); break; + case VTUnmap: fprintf(stderr,"VTUnmap"); break; + case VTMap: fprintf(stderr,"VTMap"); break; + default: fprintf(stderr,"?%d",k); break; + } + fprintf(stderr,"\n"); +#endif + if (! p) set_depth_window(c); else set_depth_tree(p,-1,8); + install_depth_region(); +} + +static void first_post_validate(WindowRec *p, WindowRec *c, VTKind k) +{ + WindowRec *w; + RegionRec t; + BoxRec b; + + w = p ? : c; + b.x1 = 0; + b.x2 = 0; + b.y1 = 0; + b.y2 = 0; + REGION_INIT(scr,&cur_24bpp,&b,0); + REGION_INIT(scr,&cur_8bpp,&b,0); + REGION_INIT(scr,&new_24bpp,&b,0); + REGION_INIT(scr,&new_8bpp,&b,0); + REGION_INIT(scr,&typetemp,&b,0); + scr->PostValidateTree = post_validate; + post_validate(p,c,k); +} + +static void query_best_size(int class, unsigned short int *w, unsigned short int *h, ScreenRec *s) +{ + switch (class) + { case CursorShape: + if (*w > 32) *w = 32; + if (*h > 32) *h = 32; + break; + default: + mfbQueryBestSize(class,w,h,s); + break; + } +} + +/* + * A few pieces want to use depth-32 pixmaps. Because we don't + * advertise any such pixmap format, simply calling cfbCreatePixmap + * with 32 for the depth argument ends up getting the memory stride + * value wrong (depths that don't appear in the pixmap formats array + * end up calculating the stride as if for one byte per pixel). The + * way cfb32 works, it's enough to create a 24bpp pixmap and bash its + * depth field.... + */ +static PixmapRec *create_pixmap(ScreenRec *s, int w, int h, int d) +{ + PixmapRec *pm; + + if (d != 32) return(cfbCreatePixmap(s,w,h,d)); + pm = cfbCreatePixmap(s,w,h,24); + if (pm) pm->drawable.depth = 32; + return(pm); +} + +Bool cg14_init(int scrno, ScreenRec *s, int ac __attribute__((__unused__)), char **av __attribute__((__unused__))) +{ + if (scr) return(FALSE); + scr = s; + cfbSetVisualTypes(1,0,8); + switch (cg14_rootdepth) + { case 8: + cfbSetVisualTypes(8, (1 << StaticGray) | (1 << GrayScale) | + (1 << StaticColor) | (1 << PseudoColor) | + (1 << TrueColor) | (1 << DirectColor), 8); + if (cg14_8only) + { if (! ds_8_ScreenInit(s,vram_norm,size_x,size_y,85,85,size_x)) return(FALSE); + } + else + { cfbSetVisualTypes(24,1<GetImage = ds_GetImage; + s->GetSpans = ds_GetSpans; + s->CreateWindow = create_window; + s->DestroyWindow = ds_DestroyWindow; + s->PositionWindow = ds_PositionWindow; + s->ChangeWindowAttributes = ds_ChangeWindowAttributes; + s->PaintWindowBackground = ds_PaintWindow; + s->PaintWindowBorder = ds_PaintWindow; + s->CopyWindow = copy_window; + s->CreateGC = ds_CreateGC; + s->InstallColormap = install; + s->UninstallColormap = uninstall; + s->ListInstalledColormaps = list; + s->StoreColors = store; + s->CloseScreen = closescreen; + s->SaveScreen = savescreen; + s->PostValidateTree = first_post_validate; + s->maxInstalledCmaps = 2; + s->CreatePixmap = create_pixmap; + instmap_8 = 0; + instmap_24 = 0; + switch (cg14_rootdepth) + { case 8: + if (cg14_8only) + { pm_otherroot = 0; + } + else + { pm_otherroot = cfbCreatePixmap(s,0,0,24); + miModifyPixmapHeader(pm_otherroot,size_x,size_y,24,24,PixmapBytePad(size_x,24),vram_cbgr); + } + break; + case 24: + pm_otherroot = create_8bit_pixmap(s); + miModifyPixmapHeader(pm_otherroot,size_x,size_y,8,8,PixmapBytePad(size_x,8),vram_pg32); + break; + } + if (! cg14_8only) + { cg14_deepfb = create_pixmap(s,0,0,32); + miModifyPixmapHeader(cg14_deepfb,size_x,size_y,32,8,PixmapBytePad(size_x,24/*32*/),vram_norm); + } + setup_8bit_stuff(s); + s->BlockHandler = cg14_block_handler; + s->WakeupHandler = cg14_wakeup_handler; + s->QueryBestSize = query_best_size; + if (cg14_8only) miDCInitialize(s,&cg14_ptrscrfuncs); else cg14_pointer_setup(s); + return(cfbCreateDefColormap(s)); +}