123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785 |
- /*
- *
- * Copyright © 1999 Keith Packard
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of Keith Packard not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. Keith Packard makes no
- * representations about the suitability of this software for any purpose. It
- * is provided "as is" without express or implied warranty.
- *
- * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
- #ifdef HAVE_CONFIG_H
- #include <kdrive-config.h>
- #endif
- #include "fbdev.h"
- #include <sys/ioctl.h>
- #include <errno.h>
- extern int KdTsPhyScreen;
- const char *fbdevDevicePath = NULL;
- static Bool fbdevMapFramebuffer(KdScreenInfo * screen);
- static Bool fbdevInitialize(KdCardInfo * card, FbdevPriv * priv)
- {
- unsigned long off;
- if (fbdevDevicePath == NULL)
- fbdevDevicePath = "/dev/fb0";
- if ((priv->fd = open(fbdevDevicePath, O_RDWR)) < 0) {
- ErrorF("Error opening framebuffer %s: %s\n",
- fbdevDevicePath, strerror(errno));
- return FALSE;
- }
- /* quiet valgrind */
- memset(&priv->fix, '\0', sizeof(priv->fix));
- if (ioctl(priv->fd, FBIOGET_FSCREENINFO, &priv->fix) < 0) {
- perror("Error with /dev/fb ioctl FIOGET_FSCREENINFO");
- close(priv->fd);
- return FALSE;
- }
- /* quiet valgrind */
- memset(&priv->var, '\0', sizeof(priv->var));
- if (ioctl(priv->fd, FBIOGET_VSCREENINFO, &priv->var) < 0) {
- perror("Error with /dev/fb ioctl FIOGET_VSCREENINFO");
- close(priv->fd);
- return FALSE;
- }
- priv->fb_base = (char *) mmap((caddr_t) NULL,
- priv->fix.smem_len,
- PROT_READ | PROT_WRITE,
- MAP_SHARED, priv->fd, 0);
- if (priv->fb_base == (char *) -1) {
- perror("ERROR: mmap framebuffer fails!");
- close(priv->fd);
- return FALSE;
- }
- off = (unsigned long) priv->fix.smem_start % (unsigned long) getpagesize();
- priv->fb = priv->fb_base + off;
- return TRUE;
- }
- Bool fbdevCardInit(KdCardInfo * card)
- {
- FbdevPriv *priv;
- priv = malloc(sizeof(FbdevPriv));
- if (!priv)
- return FALSE;
- if (!fbdevInitialize(card, priv)) {
- free(priv);
- return FALSE;
- }
- card->driver = priv;
- return TRUE;
- }
- static Pixel fbdevMakeContig(Pixel orig, Pixel others)
- {
- Pixel low;
- low = lowbit(orig) >> 1;
- while (low && (others & low) == 0) {
- orig |= low;
- low >>= 1;
- }
- return orig;
- }
- static Bool fbdevModeSupported(KdScreenInfo * screen, const KdMonitorTiming * t)
- {
- return TRUE;
- }
- static void
- fbdevConvertMonitorTiming(const KdMonitorTiming * t,
- struct fb_var_screeninfo *var)
- {
- memset(var, 0, sizeof(struct fb_var_screeninfo));
- var->xres = t->horizontal;
- var->yres = t->vertical;
- var->xres_virtual = t->horizontal;
- var->yres_virtual = t->vertical;
- var->xoffset = 0;
- var->yoffset = 0;
- var->pixclock = t->clock ? 1000000000 / t->clock : 0;
- var->left_margin = t->hbp;
- var->right_margin = t->hfp;
- var->upper_margin = t->vbp;
- var->lower_margin = t->vfp;
- var->hsync_len = t->hblank - t->hfp - t->hbp;
- var->vsync_len = t->vblank - t->vfp - t->vbp;
- var->sync = 0;
- var->vmode = 0;
- if (t->hpol == KdSyncPositive)
- var->sync |= FB_SYNC_HOR_HIGH_ACT;
- if (t->vpol == KdSyncPositive)
- var->sync |= FB_SYNC_VERT_HIGH_ACT;
- }
- static Bool fbdevScreenInitialize(KdScreenInfo * screen, FbdevScrPriv * scrpriv)
- {
- FbdevPriv *priv = screen->card->driver;
- Pixel allbits;
- int depth;
- Bool gray;
- struct fb_var_screeninfo var;
- const KdMonitorTiming *t;
- int k;
- k = ioctl(priv->fd, FBIOGET_VSCREENINFO, &var);
- if (!screen->width || !screen->height) {
- if (k >= 0) {
- screen->width = var.xres;
- screen->height = var.yres;
- } else {
- screen->width = 1024;
- screen->height = 768;
- }
- screen->rate = 103; /* FIXME: should get proper value from fb driver */
- }
- if (!screen->fb.depth) {
- if (k >= 0)
- screen->fb.depth = var.bits_per_pixel;
- else
- screen->fb.depth = 16;
- }
- if ((screen->width != var.xres) || (screen->height != var.yres)) {
- t = KdFindMode(screen, fbdevModeSupported);
- screen->rate = t->rate;
- screen->width = t->horizontal;
- screen->height = t->vertical;
- /* Now try setting the mode */
- if (k < 0 || (t->horizontal != var.xres || t->vertical != var.yres))
- fbdevConvertMonitorTiming(t, &var);
- }
- var.activate = FB_ACTIVATE_NOW;
- var.bits_per_pixel = screen->fb.depth;
- var.nonstd = 0;
- var.grayscale = 0;
- k = ioctl(priv->fd, FBIOPUT_VSCREENINFO, &var);
- if (k < 0) {
- fprintf(stderr, "error: %s\n", strerror(errno));
- return FALSE;
- }
- /* Re-get the "fixed" parameters since they might have changed */
- k = ioctl(priv->fd, FBIOGET_FSCREENINFO, &priv->fix);
- if (k < 0)
- perror("FBIOGET_FSCREENINFO");
- /* Now get the new screeninfo */
- ioctl(priv->fd, FBIOGET_VSCREENINFO, &priv->var);
- depth = priv->var.bits_per_pixel;
- gray = priv->var.grayscale;
- /* Calculate fix.line_length if it's zero */
- if (!priv->fix.line_length)
- priv->fix.line_length = (priv->var.xres_virtual * depth + 7) / 8;
- switch (priv->fix.visual) {
- case FB_VISUAL_PSEUDOCOLOR:
- if (gray) {
- screen->fb.visuals = (1 << StaticGray);
- /* could also support GrayScale, but what's the point? */
- } else {
- screen->fb.visuals = ((1 << StaticGray) |
- (1 << GrayScale) |
- (1 << StaticColor) |
- (1 << PseudoColor) |
- (1 << TrueColor) |
- (1 << DirectColor));
- }
- screen->fb.blueMask = 0x00;
- screen->fb.greenMask = 0x00;
- screen->fb.redMask = 0x00;
- break;
- case FB_VISUAL_STATIC_PSEUDOCOLOR:
- if (gray) {
- screen->fb.visuals = (1 << StaticGray);
- } else {
- screen->fb.visuals = (1 << StaticColor);
- }
- screen->fb.blueMask = 0x00;
- screen->fb.greenMask = 0x00;
- screen->fb.redMask = 0x00;
- break;
- case FB_VISUAL_TRUECOLOR:
- case FB_VISUAL_DIRECTCOLOR:
- screen->fb.visuals = (1 << TrueColor);
- #define Mask(o,l) (((1 << l) - 1) << o)
- screen->fb.redMask =
- Mask(priv->var.red.offset, priv->var.red.length);
- screen->fb.greenMask =
- Mask(priv->var.green.offset, priv->var.green.length);
- screen->fb.blueMask =
- Mask(priv->var.blue.offset, priv->var.blue.length);
- /*
- * This is a kludge so that Render will work -- fill in the gaps
- * in the pixel
- */
- screen->fb.redMask = fbdevMakeContig(screen->fb.redMask,
- screen->fb.
- greenMask | screen->
- fb.blueMask);
- screen->fb.greenMask =
- fbdevMakeContig(screen->fb.greenMask,
- screen->fb.redMask | screen->fb.
- blueMask);
- screen->fb.blueMask = fbdevMakeContig(screen->fb.blueMask,
- screen->fb.redMask |
- screen->fb.
- greenMask);
- allbits =
- screen->fb.redMask | screen->fb.greenMask | screen->
- fb.blueMask;
- depth = 32;
- while (depth && !(allbits & (1 << (depth - 1))))
- depth--;
- break;
- default:
- return FALSE;
- break;
- }
- screen->fb.depth = depth;
- screen->fb.bitsPerPixel = priv->var.bits_per_pixel;
- scrpriv->randr = screen->randr;
- return fbdevMapFramebuffer(screen);
- }
- Bool fbdevScreenInit(KdScreenInfo * screen)
- {
- FbdevScrPriv *scrpriv;
- scrpriv = calloc(1, sizeof(FbdevScrPriv));
- if (!scrpriv)
- return FALSE;
- screen->driver = scrpriv;
- if (!fbdevScreenInitialize(screen, scrpriv)) {
- screen->driver = 0;
- free(scrpriv);
- return FALSE;
- }
- return TRUE;
- }
- static void *fbdevWindowLinear(ScreenPtr pScreen,
- CARD32 row,
- CARD32 offset, int mode, CARD32 * size, void *closure)
- {
- KdScreenPriv(pScreen);
- FbdevPriv *priv = pScreenPriv->card->driver;
- if (!pScreenPriv->enabled)
- return 0;
- *size = priv->fix.line_length;
- return (CARD8 *) priv->fb + row * priv->fix.line_length + offset;
- }
- static Bool fbdevMapFramebuffer(KdScreenInfo * screen)
- {
- FbdevScrPriv *scrpriv = screen->driver;
- KdMouseMatrix m;
- FbdevPriv *priv = screen->card->driver;
- if (scrpriv->randr != RR_Rotate_0 ||
- priv->fix.type != FB_TYPE_PACKED_PIXELS)
- scrpriv->shadow = TRUE;
- else
- scrpriv->shadow = FALSE;
- KdComputeMouseMatrix(&m, scrpriv->randr, screen->width, screen->height);
- KdSetMouseMatrix(&m);
- screen->width = priv->var.xres;
- screen->height = priv->var.yres;
- screen->memory_base = (CARD8 *) (priv->fb);
- screen->memory_size = priv->fix.smem_len;
- if (scrpriv->shadow) {
- if (!KdShadowFbAlloc(screen,
- scrpriv->
- randr & (RR_Rotate_90 | RR_Rotate_270)))
- return FALSE;
- screen->off_screen_base = screen->memory_size;
- } else {
- screen->fb.byteStride = priv->fix.line_length;
- screen->fb.pixelStride = (priv->fix.line_length * 8 /
- priv->var.bits_per_pixel);
- screen->fb.frameBuffer = (CARD8 *) (priv->fb);
- screen->off_screen_base =
- screen->fb.byteStride * screen->height;
- }
- return TRUE;
- }
- static void fbdevSetScreenSizes(ScreenPtr pScreen)
- {
- KdScreenPriv(pScreen);
- KdScreenInfo *screen = pScreenPriv->screen;
- FbdevScrPriv *scrpriv = screen->driver;
- FbdevPriv *priv = screen->card->driver;
- if (scrpriv->randr & (RR_Rotate_0 | RR_Rotate_180)) {
- pScreen->width = priv->var.xres;
- pScreen->height = priv->var.yres;
- pScreen->mmWidth = screen->width_mm;
- pScreen->mmHeight = screen->height_mm;
- } else {
- pScreen->width = priv->var.yres;
- pScreen->height = priv->var.xres;
- pScreen->mmWidth = screen->height_mm;
- pScreen->mmHeight = screen->width_mm;
- }
- }
- static Bool fbdevUnmapFramebuffer(KdScreenInfo * screen)
- {
- KdShadowFbFree(screen);
- return TRUE;
- }
- static Bool fbdevSetShadow(ScreenPtr pScreen)
- {
- KdScreenPriv(pScreen);
- KdScreenInfo *screen = pScreenPriv->screen;
- FbdevScrPriv *scrpriv = screen->driver;
- FbdevPriv *priv = screen->card->driver;
- ShadowUpdateProc update;
- ShadowWindowProc window;
- int useYX = 0;
- #ifdef __arm__
- /* Use variant copy routines that always read left to right in the
- shadow framebuffer. Reading vertical strips is exceptionally
- slow on XScale due to cache effects. */
- useYX = 1;
- #endif
- window = fbdevWindowLinear;
- update = 0;
- if (priv->fix.type != FB_TYPE_PACKED_PIXELS)
- FatalError("Unsupported frame buffer type %u\n", priv->fix.type);
- if (scrpriv->randr)
- if (priv->var.bits_per_pixel == 16) {
- switch (scrpriv->randr) {
- case RR_Rotate_90:
- if (useYX)
- update = shadowUpdateRotate16_90YX;
- else
- update = shadowUpdateRotate16_90;
- break;
- case RR_Rotate_180:
- update = shadowUpdateRotate16_180;
- break;
- case RR_Rotate_270:
- if (useYX)
- update = shadowUpdateRotate16_270YX;
- else
- update = shadowUpdateRotate16_270;
- break;
- default:
- update = shadowUpdateRotate16;
- break;
- }
- } else
- update = shadowUpdateRotatePacked;
- else
- update = shadowUpdatePacked;
- return KdShadowSet(pScreen, scrpriv->randr, update, window);
- }
- static Bool fbdevRandRGetInfo(ScreenPtr pScreen, Rotation * rotations)
- {
- KdScreenPriv(pScreen);
- KdScreenInfo *screen = pScreenPriv->screen;
- FbdevScrPriv *scrpriv = screen->driver;
- RRScreenSizePtr pSize;
- Rotation randr;
- int n;
- *rotations = RR_Rotate_All | RR_Reflect_All;
- for (n = 0; n < pScreen->numDepths; n++)
- if (pScreen->allowedDepths[n].numVids)
- break;
- if (n == pScreen->numDepths)
- return FALSE;
- pSize = RRRegisterSize(pScreen,
- screen->width,
- screen->height,
- screen->width_mm, screen->height_mm);
- randr = KdSubRotation(scrpriv->randr, screen->randr);
- RRSetCurrentConfig(pScreen, randr, 0, pSize);
- return TRUE;
- }
- static Bool
- fbdevRandRSetConfig(ScreenPtr pScreen,
- Rotation randr, int rate, RRScreenSizePtr pSize)
- {
- KdScreenPriv(pScreen);
- KdScreenInfo *screen = pScreenPriv->screen;
- FbdevScrPriv *scrpriv = screen->driver;
- Bool wasEnabled = pScreenPriv->enabled;
- FbdevScrPriv oldscr;
- int oldwidth;
- int oldheight;
- int oldmmwidth;
- int oldmmheight;
- int newwidth, newheight, newmmwidth, newmmheight;
- if (screen->randr & (RR_Rotate_0 | RR_Rotate_180)) {
- newwidth = pSize->width;
- newheight = pSize->height;
- newmmwidth = pSize->mmWidth;
- newmmheight = pSize->mmHeight;
- } else {
- newwidth = pSize->height;
- newheight = pSize->width;
- newmmwidth = pSize->mmHeight;
- newmmheight = pSize->mmWidth;
- }
- if (wasEnabled)
- KdDisableScreen(pScreen);
- oldscr = *scrpriv;
- oldwidth = screen->width;
- oldheight = screen->height;
- oldmmwidth = pScreen->mmWidth;
- oldmmheight = pScreen->mmHeight;
- /*
- * Set new configuration
- */
- scrpriv->randr = KdAddRotation(screen->randr, randr);
- pScreen->width = newwidth;
- pScreen->height = newheight;
- pScreen->mmWidth = newmmwidth;
- pScreen->mmHeight = newmmheight;
- fbdevUnmapFramebuffer(screen);
- if (!fbdevMapFramebuffer(screen))
- goto bail4;
- KdShadowUnset(screen->pScreen);
- if (!fbdevSetShadow(screen->pScreen))
- goto bail4;
- fbdevSetScreenSizes(screen->pScreen);
- /*
- * Set frame buffer mapping
- */
- (*pScreen->ModifyPixmapHeader) (fbGetScreenPixmap(pScreen),
- pScreen->width,
- pScreen->height,
- screen->fb.depth,
- screen->fb.bitsPerPixel,
- screen->fb.byteStride,
- screen->fb.frameBuffer);
- /* set the subpixel order */
- KdSetSubpixelOrder(pScreen, scrpriv->randr);
- if (wasEnabled)
- KdEnableScreen(pScreen);
- return TRUE;
- bail4:
- fbdevUnmapFramebuffer(screen);
- *scrpriv = oldscr;
- fbdevMapFramebuffer(screen);
- pScreen->width = oldwidth;
- pScreen->height = oldheight;
- pScreen->mmWidth = oldmmwidth;
- pScreen->mmHeight = oldmmheight;
- if (wasEnabled)
- KdEnableScreen(pScreen);
- return FALSE;
- }
- static Bool fbdevRandRInit(ScreenPtr pScreen)
- {
- rrScrPrivPtr pScrPriv;
- if (!RRScreenInit(pScreen))
- return FALSE;
- pScrPriv = rrGetScrPriv(pScreen);
- pScrPriv->rrGetInfo = fbdevRandRGetInfo;
- pScrPriv->rrSetConfig = fbdevRandRSetConfig;
- return TRUE;
- }
- static Bool fbdevCreateColormap(ColormapPtr pmap)
- {
- ScreenPtr pScreen = pmap->pScreen;
- KdScreenPriv(pScreen);
- FbdevPriv *priv = pScreenPriv->card->driver;
- VisualPtr pVisual;
- int i;
- int nent;
- xColorItem *pdefs;
- switch (priv->fix.visual) {
- case FB_VISUAL_STATIC_PSEUDOCOLOR:
- pVisual = pmap->pVisual;
- nent = pVisual->ColormapEntries;
- pdefs = malloc(nent * sizeof(xColorItem));
- if (!pdefs)
- return FALSE;
- for (i = 0; i < nent; i++)
- pdefs[i].pixel = i;
- fbdevGetColors(pScreen, nent, pdefs);
- for (i = 0; i < nent; i++) {
- pmap->red[i].co.local.red = pdefs[i].red;
- pmap->red[i].co.local.green = pdefs[i].green;
- pmap->red[i].co.local.blue = pdefs[i].blue;
- }
- free(pdefs);
- return TRUE;
- default:
- return fbInitializeColormap(pmap);
- }
- }
- Bool fbdevInitScreen(ScreenPtr pScreen)
- {
- pScreen->CreateColormap = fbdevCreateColormap;
- return TRUE;
- }
- Bool fbdevFinishInitScreen(ScreenPtr pScreen)
- {
- if (!shadowSetup(pScreen))
- return FALSE;
- if (!fbdevRandRInit(pScreen))
- return FALSE;
- return TRUE;
- }
- Bool fbdevCreateResources(ScreenPtr pScreen)
- {
- return fbdevSetShadow(pScreen);
- }
- void fbdevPreserve(KdCardInfo * card)
- {
- }
- static int fbdevUpdateFbColormap(FbdevPriv *priv, int minidx, int maxidx)
- {
- struct fb_cmap cmap;
- cmap.start = minidx;
- cmap.len = maxidx - minidx + 1;
- cmap.red = &priv->red[minidx];
- cmap.green = &priv->green[minidx];
- cmap.blue = &priv->blue[minidx];
- cmap.transp = 0;
- return ioctl(priv->fd, FBIOPUTCMAP, &cmap);
- }
- Bool fbdevEnable(ScreenPtr pScreen)
- {
- KdScreenPriv(pScreen);
- FbdevPriv *priv = pScreenPriv->card->driver;
- int k;
- priv->var.activate = FB_ACTIVATE_NOW | FB_CHANGE_CMAP_VBL;
- /* display it on the LCD */
- k = ioctl(priv->fd, FBIOPUT_VSCREENINFO, &priv->var);
- if (k < 0) {
- perror("FBIOPUT_VSCREENINFO");
- return FALSE;
- }
- if (priv->fix.visual == FB_VISUAL_DIRECTCOLOR) {
- int i;
- for (i = 0;
- i < (1 << priv->var.red.length) ||
- i < (1 << priv->var.green.length) ||
- i < (1 << priv->var.blue.length); i++) {
- priv->red[i] =
- i * 65535 / ((1 << priv->var.red.length) - 1);
- priv->green[i] =
- i * 65535 / ((1 << priv->var.green.length) - 1);
- priv->blue[i] =
- i * 65535 / ((1 << priv->var.blue.length) - 1);
- }
- i--;
- fbdevUpdateFbColormap(priv, 0, i);
- }
- return TRUE;
- }
- Bool fbdevDPMS(ScreenPtr pScreen, int mode)
- {
- KdScreenPriv(pScreen);
- FbdevPriv *priv = pScreenPriv->card->driver;
- static int oldmode = -1;
- if (mode == oldmode)
- return TRUE;
- #ifdef FBIOPUT_POWERMODE
- if (ioctl(priv->fd, FBIOPUT_POWERMODE, &mode) >= 0) {
- oldmode = mode;
- return TRUE;
- }
- #endif
- #ifdef FBIOBLANK
- if (ioctl(priv->fd, FBIOBLANK, mode ? mode + 1 : 0) >= 0) {
- oldmode = mode;
- return TRUE;
- }
- #endif
- return FALSE;
- }
- void fbdevDisable(ScreenPtr pScreen)
- {
- }
- void fbdevRestore(KdCardInfo * card)
- {
- }
- void fbdevScreenFini(KdScreenInfo * screen)
- {
- }
- void fbdevCardFini(KdCardInfo * card)
- {
- FbdevPriv *priv = card->driver;
- munmap(priv->fb_base, priv->fix.smem_len);
- close(priv->fd);
- free(priv);
- }
- /*
- * Retrieve actual colormap and return selected n entries in pdefs.
- */
- void fbdevGetColors(ScreenPtr pScreen, int n, xColorItem * pdefs)
- {
- KdScreenPriv(pScreen);
- FbdevPriv *priv = pScreenPriv->card->driver;
- struct fb_cmap cmap;
- int p;
- int k;
- int min, max;
- min = 256;
- max = 0;
- for (k = 0; k < n; k++) {
- if (pdefs[k].pixel < min)
- min = pdefs[k].pixel;
- if (pdefs[k].pixel > max)
- max = pdefs[k].pixel;
- }
- cmap.start = min;
- cmap.len = max - min + 1;
- cmap.red = &priv->red[min];
- cmap.green = &priv->green[min];
- cmap.blue = &priv->blue[min];
- cmap.transp = 0;
- k = ioctl(priv->fd, FBIOGETCMAP, &cmap);
- if (k < 0) {
- perror("can't get colormap");
- return;
- }
- while (n--) {
- p = pdefs->pixel;
- pdefs->red = priv->red[p];
- pdefs->green = priv->green[p];
- pdefs->blue = priv->blue[p];
- pdefs++;
- }
- }
- /*
- * Change colormap by updating n entries described in pdefs.
- */
- void fbdevPutColors(ScreenPtr pScreen, int n, xColorItem * pdefs)
- {
- KdScreenPriv(pScreen);
- FbdevPriv *priv = pScreenPriv->card->driver;
- int p;
- int min, max;
- min = 256;
- max = 0;
- while (n--) {
- p = pdefs->pixel;
- priv->red[p] = pdefs->red;
- priv->green[p] = pdefs->green;
- priv->blue[p] = pdefs->blue;
- if (p < min)
- min = p;
- if (p > max)
- max = p;
- pdefs++;
- }
- fbdevUpdateFbColormap(priv, min, max);
- }
|