--- .empty Thu Jan 1 00:00:00 1970 +++ NEW/xc/programs/Xserver/hw/s24/s24-24.c Thu Jan 1 00:00:00 1970 @@ -0,0 +1,622 @@ +#include + +#include +#include +#include + +#include "s24.h" +#include "vars.h" +#include "s24-24.h" +#include "s24curs.h" +#include "crossdepth.h" + +#define PSZ 32 +#include + +static ScreenRec *scr = 0; +static ColormapRec *instmap_lut; +static ColormapRec *instmap_true; +static PixmapRec *pm_otherroot; +static RegionRec cur_24t; +static RegionRec cur_24d; +static RegionRec cur_8; +static RegionRec new_24t; +static RegionRec new_24d; +static RegionRec new_8; +static RegionRec typetemp; +static VisualID vtrue = None; +static VisualID vdirect; +static GC *gc_type[3]; + +PixmapRec *s24_deepfb; + +static Bool savescreen(ScreenRec *s, int op) +{ + switch (op) + { case SCREEN_SAVER_FORCER: + break; + case SCREEN_SAVER_ON: + s24_dac->addr = 0 << 24; + s24_dac->olut = 0 << 24; + s24_dac->olut = 0 << 24; + s24_dac->olut = 0 << 24; + s24_dac->addr = 6 << 24; + s24_dac->ctl1 &= ~0x40000000; + s24_dac->addr = 0 << 24; + s24_tec->cursloc = S24_CURSLOC(-32,-32); + break; + case SCREEN_SAVER_OFF: + { int x; + int y; + s24_dac->addr = 6 << 24; + s24_dac->ctl1 |= 0x40000000; + s24_dac->addr = 0 << 24; + if (s24_curcurs) + { miPointerPosition(&x,&y); + s24_tec->cursloc = S24_CURSLOC(x-s24_curcurs->bits->xhot,y-s24_curcurs->bits->yhot); + } + } + break; + default: + return(FALSE); + break; + } + return(TRUE); +} + +static Bool closescreen(int scrno, ScreenRec *s) +{ + Bool rv; + int i; + + (*s->DestroyPixmap)(pm_otherroot); + for (i=0;i<3;i++) FreeGC(gc_type[i],0); + (*s->DestroyPixmap)(s24_deepfb); + REGION_UNINIT(scr,&cur_24t); + REGION_UNINIT(scr,&cur_24d); + REGION_UNINIT(scr,&cur_8); + REGION_UNINIT(scr,&new_24t); + REGION_UNINIT(scr,&new_24d); + REGION_UNINIT(scr,&new_8); + REGION_UNINIT(scr,&typetemp); + switch (s24_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); + s24_tec->cursloc = S24_CURSLOC(-32,-32); + return(rv); +} + +static void install_8(ColormapRec *cm) +{ + int i; + + if (cm == instmap_lut) return; + if (instmap_lut) WalkTree(instmap_lut->pScreen,TellLostMap,&instmap_lut->mid); + if ((cm->pVisual->class | DynamicClass) == DirectColor) + { s24_dac->addr = 0 << 24; + 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) + s24_dac->clut = MAP(red,Red) * 0x01000000; + s24_dac->clut = MAP(green,Green) * 0x01000000; + s24_dac->clut = MAP(blue,Blue) * 0x01000000; +#undef MAP + } + } + else if (! (cm->pVisual->class & DynamicClass)) + { Entry *e; + e = &cm->red[0]; + s24_dac->addr = 0 << 24; + for (i=0;i<256;i++,e++) + { s24_dac->clut = (e->co.local.red >> 8) * 0x01000000; + s24_dac->clut = (e->co.local.green >> 8) * 0x01000000; + s24_dac->clut = (e->co.local.blue >> 8) * 0x01000000; + } + } + else + { Entry *e; + int at; + static void set(int inx, unsigned short int r, unsigned short int g, unsigned short int b) + { if (inx != at) + { s24_dac->addr = inx << 24; + at = inx; + } + s24_dac->clut = (r >> 8) * 0x01000000; + s24_dac->clut = (g >> 8) * 0x01000000; + s24_dac->clut = (b >> 8) * 0x01000000; + at ++; + } + e = &cm->red[0]; + at = -2; + for (i=0;i<256;i++,e++) + { if (e->fShared) + { set(i,e->co.shco.red->color,e->co.shco.green->color,e->co.shco.blue->color); + } + else if (e->refcnt) + { set(i,e->co.local.red,e->co.local.green,e->co.local.blue); + } + } + } + s24_dac->addr = 0; + instmap_lut = cm; + WalkTree(cm->pScreen,TellGainedMap,&cm->mid); +} + +static void install_24(ColormapRec *cm) +{ + int i; + + if ((cm == instmap_lut) || (cm == instmap_true)) return; + switch (cm->pVisual->class) + { case DirectColor: + if (instmap_lut) WalkTree(instmap_lut->pScreen,TellLostMap,&instmap_lut->mid); + s24_dac->addr = 0 << 24; + for (i=0;i<256;i++) + { s24_dac->clut = (cm->red [i].co.local.red >> 8) * 0x01000000; + s24_dac->clut = (cm->green[i].co.local.green >> 8) * 0x01000000; + s24_dac->clut = (cm->blue [i].co.local.blue >> 8) * 0x01000000; + } + s24_dac->addr = 0 << 24; + instmap_lut = cm; + WalkTree(cm->pScreen,TellGainedMap,&cm->mid); + break; + case TrueColor: + if (instmap_true) WalkTree(instmap_true->pScreen,TellLostMap,&instmap_true->mid); + instmap_true = cm; + WalkTree(cm->pScreen,TellGainedMap,&cm->mid); + break; + default: + FatalError("bad class %d in install_24",cm->pVisual->class); + break; + } +} + +static void install(ColormapRec *cm) +{ + if ( ((cm->pVisual->class|DynamicClass) == DirectColor) && + (cm->pVisual->ColormapEntries == 256) ) + { install_24(cm); + return; + } + install_8(cm); +} + +static void uninstall(ColormapRec *cm) +{ + switch (s24_rootdepth) + { case 8: + if (cm == instmap_lut) + { Colormap defid; + defid = cm->pScreen->defColormap; + if (cm->mid != defid) + { ColormapRec *defmap; + defmap = LookupIDByType(defid,RT_COLORMAP); + if (defmap) + { (*cm->pScreen->InstallColormap)(defmap); + return; + } + else + { ErrorF("can't find default colormap\n"); + } + } + instmap_lut = 0; + } + else if (cm == instmap_true) + { WalkTree(cm->pScreen,TellLostMap,&cm->mid); + instmap_true = 0; + } + break; + case 24: + { Colormap defid; + ColormapRec *defmap; + defid = cm->pScreen->defColormap; + if (cm->mid == defid) return; + defmap = LookupIDByType(defid,RT_COLORMAP); + if (! defmap) ErrorF("can't find default colormap\n"); + if ((cm != instmap_lut) && (cm != instmap_true)) return; + if ( defmap && + ( (defmap->pVisual->class == cm->pVisual->class) || + (defmap->pVisual->class & cm->pVisual->class & DynamicClass) ) ) + { (*cm->pScreen->InstallColormap)(defmap); + return; + } + WalkTree(cm->pScreen,TellLostMap,&cm->mid); + if (cm == instmap_lut) instmap_lut = 0; + if (cm == instmap_true) instmap_true = 0; + } + break; + } +} + +static int list(ScreenRec *s __attribute__((__unused__)), Colormap *list) +{ + int i; + + i = 0; + if (instmap_lut) list[i++] = instmap_lut->mid; + if (instmap_true) list[i++] = instmap_true->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 (cm != instmap_lut) return; + if ( (cm->pVisual->class == DirectColor) && + (cm->pVisual->ColormapEntries == 256) ) + { s24_dac->addr = vals->pixel * 0x01000000;; + for (;n>0;n--,vals++) + { s24_dac->clut = (vals->red >> 8) * 0x01000000; + s24_dac->clut = (vals->green >> 8) * 0x01000000; + s24_dac->clut = (vals->blue >> 8) * 0x01000000; + } + } + else + { if ((cm->pVisual->class | DynamicClass) == DirectColor) + { n = cfbExpandDirectColors(cm,n,vals,&expanded[0]); + vals = &expanded[0]; + } + s24_dac->addr = vals->pixel * 0x01000000; + for (;n>0;n--,vals++) + { s24_dac->clut = (vals->red >> 8) * 0x01000000; + s24_dac->clut = (vals->green >> 8) * 0x01000000; + s24_dac->clut = (vals->blue >> 8) * 0x01000000; + } + } + s24_dac->addr = 0 << 24; +} + +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 (s24_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. + * + * XXX use blit space here + */ +static void copy_window(WindowRec *w, DDXPointRec oo, RegionRec *src) +{ + extern WindowRec **WindowTable; + int sn; + WindowRec *rootsave; + + if (w->drawable.depth != s24_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 != s24_rootdepth) + { WindowTable[sn] = rootsave; + } +} + +static void find_24bpp_visuals(void) +{ + int i; + + for (i=0;inumVisuals;i++) + { if (scr->visuals[i].ColormapEntries != 256) continue; + switch (scr->visuals[i].class) + { case TrueColor: + vtrue = scr->visuals[i].vid; + break; + case DirectColor: + vdirect = scr->visuals[i].vid; + break; + } + } + if (vtrue == None) FatalError("Can't find 24bpp TrueColor visual"); + if (vdirect == None) FatalError("Can't find 24bpp DirectColor visual"); +} + +void set_type(int x1, int y1, int x2, int y2, int v) +{ + xRectangle rect; + +#ifdef DEPTH_REGION_DEBUG + fprintf(stderr,"set_type %d: %d..%d × %d..%d\n",v,x1,x2,y1,y2); +#endif + rect.x = x1; + rect.y = y1; + rect.width = x2 - x1; + rect.height = y2 - y1; + cfbPolyFillRect(&s24_deepfb->drawable,gc_type[v],1,&rect); +} + +static void set_type_window(WindowRec *w) +{ + switch (w->drawable.depth) + { case 8: + REGION_SUBTRACT(scr,&new_24t,&new_24t,&w->borderClip); + REGION_SUBTRACT(scr,&new_24d,&new_24d,&w->borderClip); + REGION_UNION(scr,&new_8,&new_8,&w->borderClip); + break; + case 24: + if (vtrue == None) find_24bpp_visuals(); + if (wVisual(w) == vtrue) + { REGION_SUBTRACT(scr,&new_24d,&new_24d,&w->borderClip); + REGION_UNION(scr,&new_24t,&new_24t,&w->borderClip); + } + else + { REGION_SUBTRACT(scr,&new_24t,&new_24t,&w->borderClip); + REGION_UNION(scr,&new_24d,&new_24d,&w->borderClip); + } + REGION_SUBTRACT(scr,&new_8,&new_8,&w->borderClip); + break; + default: + FatalError("bad window depth %d",w->drawable.depth); + } +} + +static int set_type_tree(WindowRec *w, VisualID pvid, int ind) +{ +#ifdef DEPTH_REGION_DEBUG + fprintf(stderr,"%*sset_type_tree: w=0x%x pd=%d\n",ind,"",w->drawable.id,pd); +#endif + if (w->optional && (w->optional->visual != pvid)) + { set_type_window(w); + pvid = w->optional->visual; + } + for (w=w->lastChild;w;w=w->prevSib) + { if (!w->viewable || (w->visibility == VisibilityFullyObscured)) continue; + set_type_tree(w,pvid,ind+2); + } +} + +static void set_type_region(RegionRec *cur, RegionRec *new, int v) +{ + 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_type(b[i].x1,b[i].y1,b[i].x2,b[i].y2,v); + } + REGION_COPY(scr,cur,new); +} + +static void install_type_region(void) +{ + set_type_region(&cur_24t,&new_24t,2); + set_type_region(&cur_24d,&new_24d,1); + set_type_region(&cur_8,&new_8,0); +} + +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_type_window(c); else set_type_tree(p,-1,8); + install_type_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_24t,&b,0); + REGION_INIT(scr,&cur_24d,&b,0); + REGION_INIT(scr,&cur_8,&b,0); + REGION_INIT(scr,&new_24t,&b,0); + REGION_INIT(scr,&new_24d,&b,0); + REGION_INIT(scr,&new_8,&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 s24_init(int scrno, ScreenRec *s, int ac __attribute__((__unused__)), char **av __attribute__((__unused__))) +{ + int i; + CARD32 attr; + + if (scr) return(FALSE); + scr = s; + cfbSetVisualTypes(1,0,8); + switch (s24_rootdepth) + { case 8: + cfbSetVisualTypes(8, (1 << StaticGray) | (1 << GrayScale) | + (1 << StaticColor) | (1 << PseudoColor) | + (1 << TrueColor) | (1 << DirectColor), 8); + 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_lut = 0; + instmap_true = 0; + switch (s24_rootdepth) + { case 8: + pm_otherroot = cfbCreatePixmap(s,0,0,24); + miModifyPixmapHeader(pm_otherroot,1152,900,24,24,PixmapBytePad(1152,24),s24_dfb24); + break; + case 24: + pm_otherroot = create_8bit_pixmap(s); + miModifyPixmapHeader(pm_otherroot,1152,900,8,8,PixmapBytePad(1152,8),s24_dfb8); + break; + } + s24_deepfb = create_pixmap(s,0,0,32); + miModifyPixmapHeader(s24_deepfb,1152,900,32,8,PixmapBytePad(1152,24/*32*/),s24_rdfb32); + for (i=0;i<3;i++) + { gc_type[i] = CreateScratchGC(s,32); + gc_type[i]->graphicsExposures = FALSE; + attr = i << 24; + ChangeGC(gc_type[i],GCForeground,&attr); + attr = 0x03000000; + ChangeGC(gc_type[i],GCPlaneMask,&attr); + ValidateGC(&s24_deepfb->drawable,gc_type[i]); + } + s->BlockHandler = s24_block_handler; + s->WakeupHandler = s24_wakeup_handler; + s->QueryBestSize = query_best_size; + s24_pointer_setup(s); + return(cfbCreateDefColormap(s)); +}