📄 qcolormap_x11.cpp
字号:
Display *display = QX11Info::display(); const int screens = ScreenCount(display); cmaps = new QColormap*[screens]; for (int i = 0; i < screens; ++i) { cmaps[i] = new QColormap; QColormapPrivate * const d = cmaps[i]->d; bool use_stdcmap = false; int color_count = X11->color_count; // defaults d->depth = DefaultDepth(display, i); d->colormap = DefaultColormap(display, i); d->defaultColormap = true; d->visual = DefaultVisual(display, i); d->defaultVisual = true; if (X11->visual && i == DefaultScreen(display)) { // only use the outside colormap on the default screen d->visual = find_visual(display, i, X11->visual->c_class, XVisualIDFromVisual(X11->visual), &d->depth, &d->defaultVisual); } else if ((X11->visual_class != -1 && X11->visual_class >= 0 && X11->visual_class < 6) || (X11->visual_id != -1)) { // look for a specific visual or type of visual d->visual = find_visual(display, i, X11->visual_class, X11->visual_id, &d->depth, &d->defaultVisual); } else if (QApplication::colorSpec() == QApplication::ManyColor) { // look for a TrueColor w/ a depth higher than 8bpp d->visual = find_visual(display, i, TrueColor, -1, &d->depth, &d->defaultVisual); if (d->depth <= 8) { d->visual = DefaultVisual(display, i); d->defaultVisual = true; color_count = 216; } } else if (!X11->custom_cmap) { XStandardColormap *stdcmap = 0; int ncmaps = 0; if (XGetRGBColormaps(display, RootWindow(display, i), &stdcmap, &ncmaps, XA_RGB_DEFAULT_MAP)) { if (stdcmap) { for (int c = 0; c < ncmaps; ++c) { if (!stdcmap[c].red_max || !stdcmap[c].green_max || !stdcmap[c].blue_max || !stdcmap[c].red_mult || !stdcmap[c].green_mult || !stdcmap[c].blue_mult) continue; // invalid stdcmap XVisualInfo proto; proto.visualid = stdcmap[c].visualid; proto.screen = i; int nvisuals = 0; XVisualInfo *vi = XGetVisualInfo(display, VisualIDMask | VisualScreenMask, &proto, &nvisuals); if (vi) { if (nvisuals > 0) { use_stdcmap = true; d->mode = ((vi[0].visual->c_class < StaticColor) ? Gray : ((vi[0].visual->c_class < TrueColor) ? Indexed : Direct)); d->depth = vi[0].depth; d->colormap = stdcmap[c].colormap; d->defaultColormap = true; d->visual = vi[0].visual; d->defaultVisual = (d->visual == DefaultVisual(display, i)); d->r_max = stdcmap[c].red_max + 1; d->g_max = stdcmap[c].green_max + 1; d->b_max = stdcmap[c].blue_max + 1; if (d->mode == Direct) { // calculate offsets d->r_shift = lowest_bit(d->visual->red_mask); d->g_shift = lowest_bit(d->visual->green_mask); d->b_shift = lowest_bit(d->visual->blue_mask); } else { d->r_shift = 0; d->g_shift = 0; d->b_shift = 0; } } XFree(vi); } break; } XFree(stdcmap); } } } if (!use_stdcmap) { switch (d->visual->c_class) { case StaticGray: d->mode = Gray; d->r_max = d->g_max = d->b_max = d->visual->map_entries; break; case XGrayScale: d->mode = Gray; // follow precedent set in libXmu... if (color_count != 0) d->r_max = d->g_max = d->b_max = color_count; else if (d->visual->map_entries > 65000) d->r_max = d->g_max = d->b_max = 4096; else if (d->visual->map_entries > 4000) d->r_max = d->g_max = d->b_max = 512; else if (d->visual->map_entries > 250) d->r_max = d->g_max = d->b_max = 12; else d->r_max = d->g_max = d->b_max = 4; break; case StaticColor: d->mode = Indexed; d->r_max = right_align(d->visual->red_mask) + 1; d->g_max = right_align(d->visual->green_mask) + 1; d->b_max = right_align(d->visual->blue_mask) + 1; break; case PseudoColor: d->mode = Indexed; // follow precedent set in libXmu... if (color_count != 0) d->r_max = d->g_max = d->b_max = cube_root(color_count); else if (d->visual->map_entries > 65000) d->r_max = d->g_max = d->b_max = 27; else if (d->visual->map_entries > 4000) d->r_max = d->g_max = d->b_max = 12; else if (d->visual->map_entries > 250) d->r_max = d->g_max = d->b_max = cube_root(d->visual->map_entries - 125); else d->r_max = d->g_max = d->b_max = cube_root(d->visual->map_entries); break; case TrueColor: case DirectColor: d->mode = Direct; d->r_max = right_align(d->visual->red_mask) + 1; d->g_max = right_align(d->visual->green_mask) + 1; d->b_max = right_align(d->visual->blue_mask) + 1; d->r_shift = lowest_bit(d->visual->red_mask); d->g_shift = lowest_bit(d->visual->green_mask); d->b_shift = lowest_bit(d->visual->blue_mask); break; } } bool ownColormap = false; if (X11->colormap && i == DefaultScreen(display)) { // only use the outside colormap on the default screen d->colormap = X11->colormap; d->defaultColormap = (d->colormap == DefaultColormap(display, i)); } else if (!use_stdcmap && (((d->visual->c_class & 1) && X11->custom_cmap) || d->visual != DefaultVisual(display, i)) || d->visual->c_class == DirectColor) { // allocate custom colormap (we always do this when using DirectColor visuals) d->colormap = XCreateColormap(display, RootWindow(display, i), d->visual, d->visual->c_class == DirectColor ? AllocAll : AllocNone); d->defaultColormap = false; ownColormap = true; } switch (d->mode) { case Gray: init_gray(d, i); break; case Indexed: init_indexed(d, i); break; case Direct: init_direct(d, ownColormap); break; } QX11InfoData *screen = X11->screens + i; screen->depth = d->depth; screen->visual = d->visual; screen->defaultVisual = d->defaultVisual; screen->colormap = d->colormap; screen->defaultColormap = d->defaultColormap; screen->cells = screen->visual->map_entries; // ### // We assume that 8bpp == pseudocolor, but this is not // always the case (according to the X server), so we need // to make sure that our internal data is setup in a way // that is compatible with our assumptions if (screen->visual->c_class == TrueColor && screen->depth == 8 && screen->cells == 8) screen->cells = 256; }}/*! \internal*/void QColormap::cleanup(){ Display *display = QX11Info::display(); const int screens = ScreenCount(display); for (int i = 0; i < screens; ++i) delete cmaps[i]; delete [] cmaps; cmaps = 0;}/*! Returns the colormap for the specified \a screen. If \a screen is -1, this function returns the colormap for the default screen.*/QColormap QColormap::instance(int screen){ if (screen == -1) screen = QX11Info::appScreen(); return *cmaps[screen];}/*! \internal Constructs a new colormap.*/QColormap::QColormap() : d(new QColormapPrivate){}/*! Constructs a copy of another \a colormap. */QColormap::QColormap(const QColormap &colormap) :d (colormap.d){ d->ref.ref(); }/*! Destroys the colormap.*/QColormap::~QColormap(){ if (!d->ref.deref()) { if (!d->defaultColormap) XFreeColormap(QX11Info::display(), d->colormap); delete d; }}/*! Returns the mode of this colormap. \sa QColormap::Mode*/QColormap::Mode QColormap::mode() const{ return d->mode; }/*! Returns the depth of the device. \sa size()*/int QColormap::depth() const{ return d->depth; }/*! Returns the size of the colormap for \c Indexed and \c Gray modes; Returns -1 for \c Direct mode. \sa colormap()*/int QColormap::size() const{ return (d->mode == Gray ? d->r_max : (d->mode == Indexed ? d->r_max * d->g_max * d->b_max : -1));}/*! Returns a device dependent pixel value for the \a color. \sa colorAt()*/uint QColormap::pixel(const QColor &color) const{ const QColor c = color.toRgb(); const uint r = (c.ct.argb.red * d->r_max) >> 16; const uint g = (c.ct.argb.green * d->g_max) >> 16; const uint b = (c.ct.argb.blue * d->b_max) >> 16; if (d->mode != Direct) { if (d->mode == Gray) return d->pixels.at((r * 30 + g * 59 + b * 11) / 100); return d->pixels.at(r * d->g_max * d->b_max + g * d->b_max + b); } return (r << d->r_shift) + (g << d->g_shift) + (b << d->b_shift);}/*! Returns a QColor for the \a pixel. \sa pixel()*/const QColor QColormap::colorAt(uint pixel) const{ if (d->mode != Direct) { Q_ASSERT(pixel <= (uint)d->colors.size()); return d->colors.at(pixel); } const int r = (((pixel & d->visual->red_mask) >> d->r_shift) << 8) / d->r_max; const int g = (((pixel & d->visual->green_mask) >> d->g_shift) << 8) / d->g_max; const int b = (((pixel & d->visual->blue_mask) >> d->b_shift) << 8) / d->b_max; return QColor(r, g, b);}/*! Returns a vector of colors which represents the devices colormap for \c Indexed and \c Gray modes. This function returns an empty vector for \c Direct mode. \sa size()*/const QVector<QColor> QColormap::colormap() const{ return d->colors; }/*! \fn HPALETTE QColormap::hPal() This function is only available on Windows. Returns an handle to the HPALETTE used by this colormap. If no HPALETTE is being used, this function returns zero.*//*! \since 4.2 \fn QColormap &QColormap::operator=(const QColormap &colormap) Assigns the given \a colormap to \e this color map and returns a reference to \e this color map.*/QColormap &QColormap::operator=(const QColormap &colormap){ qAtomicAssign(d, colormap.d); return *this;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -