summaryrefslogtreecommitdiffstats
path: root/tqtinterface/qt4/src/kernel/tqcolor_x11.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tqtinterface/qt4/src/kernel/tqcolor_x11.cpp')
-rw-r--r--tqtinterface/qt4/src/kernel/tqcolor_x11.cpp1336
1 files changed, 0 insertions, 1336 deletions
diff --git a/tqtinterface/qt4/src/kernel/tqcolor_x11.cpp b/tqtinterface/qt4/src/kernel/tqcolor_x11.cpp
deleted file mode 100644
index ed3a764..0000000
--- a/tqtinterface/qt4/src/kernel/tqcolor_x11.cpp
+++ /dev/null
@@ -1,1336 +0,0 @@
-/****************************************************************************
-**
-** Implementation of TQColor class for X11
-**
-** Created : 940112
-**
-** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
-**
-** This file is part of the kernel module of the TQt GUI Toolkit.
-**
-** This file may be used under the terms of the GNU General
-** Public License versions 2.0 or 3.0 as published by the Free
-** Software Foundation and appearing in the files LICENSE.GPL2
-** and LICENSE.GPL3 included in the packaging of this file.
-** Alternatively you may (at your option) use any later version
-** of the GNU General Public License if such license has been
-** publicly approved by Trolltech ASA (or its successors, if any)
-** and the KDE Free TQt Foundation.
-**
-** Please review the following information to ensure GNU General
-** Public Licensing requirements will be met:
-** http://trolltech.com/products/qt/licenses/licensing/opensource/.
-** If you are unsure which license is appropriate for your use, please
-** review the following information:
-** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
-** or contact the sales department at sales@trolltech.com.
-**
-** This file may be used under the terms of the Q Public License as
-** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
-** included in the packaging of this file. Licensees holding valid TQt
-** Commercial licenses may use this file in accordance with the TQt
-** Commercial License Agreement provided with the Software.
-**
-** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
-** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
-** herein.
-**
-**********************************************************************/
-
-#include "tqcolor.h"
-#include "tqcolor_p.h"
-#include "string.h"
-#include "tqpaintdevice.h"
-#include "tqapplication.h"
-#include "tqapplication_p.h"
-#include "tqt_x11_p.h"
-
-#ifdef USE_QT4
-
-#include "tqintdict.h"
-
-static const uint col_std_dict = 419;
-static const uint col_large_dict = 18397;
-
-struct TQColorData {
- uint pix; // allocated pixel value
- int context; // allocation context
-};
-
-typedef TQIntDict<TQColorData> TQColorDict;
-typedef TQIntDictIterator<TQColorData> TQColorDictIt;
-
-static int current_alloc_context = 0; // current color alloc context
-
-class TQColorScreenData {
-public:
- TQColorScreenData()
- {
- colorDict = 0;
- colors_avail = TRUE;
- g_vis = 0;
- g_carr = 0;
- g_carr_fetch = TRUE;
- g_cells = 0;
- g_our_alloc = 0;
- color_reduce = FALSE;
- }
-
- TQColorDict *colorDict; // dict of allocated colors
- bool colors_avail; // X colors available
- bool g_truecolor; // truecolor visual
- Visual *g_vis; // visual
- XColor *g_carr; // color array
- bool g_carr_fetch; // perform XQueryColors?
- int g_cells; // number of entries in g_carr
- bool *g_our_alloc; // our allocated colors
- uint red_mask , green_mask , blue_mask;
- int red_shift, green_shift, blue_shift;
- bool color_reduce;
- int col_div_r;
- int col_div_g;
- int col_div_b;
-};
-
-static int screencount = 0;
-static TQColorScreenData **screendata = 0; // array of screendata pointers
-
-#define MAX_CONTEXTS 16
-static int context_stack[MAX_CONTEXTS];
-static int context_ptr = 0;
-
-static void init_context_stack()
-{
- static bool did_init = FALSE;
- if ( !did_init ) {
- did_init = TRUE;
- context_stack[0] = current_alloc_context = 0;
- }
-}
-
-/*
- This function is called from the event loop. It resets the colors_avail
- flag so that the application can retry to allocate read-only colors
- that other applications may have deallocated lately.
-
- The g_our_alloc and g_carr are global arrays that optimize color
- approximation when there are no more colors left to allocate.
-*/
-
-void qt_reset_color_avail()
-{
- int i;
- for ( i = 0; i < screencount; i++ ) {
- screendata[i]->colors_avail = TRUE;
- screendata[i]->g_carr_fetch = TRUE; // do XQueryColors if !colors_avail
- }
-}
-
-/*!
- Enters a color allocation context and returns a non-zero unique
- identifier.
-
- Color allocation contexts are useful for programs that need to
- allocate many colors and throw them away later, like image
- viewers. The allocation context functions work for true color
- displays as well as for colormap displays, except that
- TQColor::destroyAllocContext() does nothing for true color.
-
- Example:
- \code
- TQPixmap loadPixmap( TQString fileName )
- {
- static int alloc_context = 0;
- if ( alloc_context )
- TQColor::destroyAllocContext( alloc_context );
- alloc_context = TQColor::enterAllocContext();
- TQPixmap pm( fileName );
- TQColor::leaveAllocContext();
- return pm;
- }
- \endcode
-
- The example code loads a pixmap from file. It frees up all colors
- that were allocated the last time loadPixmap() was called.
-
- The initial/default context is 0. TQt keeps a list of colors
- associated with their allocation contexts. You can call
- destroyAllocContext() to get rid of all colors that were allocated
- in a specific context.
-
- Calling enterAllocContext() enters an allocation context. The
- allocation context lasts until you call leaveAllocContext().
- TQColor has an internal stack of allocation contexts. Each call to
- enterAllocContex() must have a corresponding leaveAllocContext().
-
- \code
- // context 0 active
- int c1 = TQColor::enterAllocContext(); // enter context c1
- // context c1 active
- int c2 = TQColor::enterAllocContext(); // enter context c2
- // context c2 active
- TQColor::leaveAllocContext(); // leave context c2
- // context c1 active
- TQColor::leaveAllocContext(); // leave context c1
- // context 0 active
- // Now, free all colors that were allocated in context c2
- TQColor::destroyAllocContext( c2 );
- \endcode
-
- You may also want to set the application's color specification.
- See TQApplication::setColorSpec() for more information.
-
- \sa leaveAllocContext(), currentAllocContext(), destroyAllocContext(),
- TQApplication::setColorSpec()
-*/
-
-int TQColor::enterAllocContext()
-{
- static int context_seq_no = 0;
- init_context_stack();
- if ( context_ptr+1 == MAX_CONTEXTS ) {
-#if defined(TQT_CHECK_STATE)
- qWarning( "TQColor::enterAllocContext: Context stack overflow" );
-#endif
- return 0;
- }
- current_alloc_context = context_stack[++context_ptr] = ++context_seq_no;
- return current_alloc_context;
-}
-
-
-/*!
- Leaves a color allocation context.
-
- See enterAllocContext() for a detailed explanation.
-
- \sa enterAllocContext(), currentAllocContext()
-*/
-
-void TQColor::leaveAllocContext()
-{
- init_context_stack();
- if ( context_ptr == 0 ) {
-#if defined(TQT_CHECK_STATE)
- qWarning( "TQColor::leaveAllocContext: Context stack underflow" );
-#endif
- return;
- }
- current_alloc_context = context_stack[--context_ptr];
-}
-
-
-/*!
- Returns the current color allocation context.
-
- The default context is 0.
-
- \sa enterAllocContext(), leaveAllocContext()
-*/
-
-int TQColor::currentAllocContext()
-{
- return current_alloc_context;
-}
-
-
-/*!
- Destroys a color allocation context, \e context.
-
- This function deallocates all colors that were allocated in the
- specified \a context. If \a context == -1, it frees up all colors
- that the application has allocated. If \a context == -2, it frees
- up all colors that the application has allocated, except those in
- the default context.
-
- The function does nothing for true color displays.
-
- \sa enterAllocContext(), alloc()
-*/
-
-void TQColor::destroyAllocContext( int context )
-{
- init_context_stack();
- if ( !color_init )
- return;
-
- int screen;
- for ( screen = 0; screen < screencount; ++screen ) {
- if ( screendata[screen]->g_truecolor )
- continue;
-
- ulong pixels[256];
- bool freeing[256];
- memset( freeing, FALSE, screendata[screen]->g_cells*sizeof(bool) );
- TQColorData *d;
- TQColorDictIt it( *screendata[screen]->colorDict );
- int i = 0;
- uint rgbv;
- while ( (d=it.current()) ) {
- rgbv = (uint)it.currentKey();
- if ( (d->context || context==-1) &&
- (d->context == context || context < 0) ) {
- if ( !screendata[screen]->g_our_alloc[d->pix] && !freeing[d->pix] ) {
- // will free this color
- pixels[i++] = d->pix;
- freeing[d->pix] = TRUE;
- }
- // remove from dict
- screendata[screen]->colorDict->remove( (long)rgbv );
- }
- ++it;
- }
- if ( i )
- XFreeColors( TQPaintDevice::x11AppDisplay(),
- TQPaintDevice::x11AppColormap( screen ),
- pixels, i, 0 );
- }
-}
-
-/*!
- Returns the number of color bit planes for the underlying window
- system.
-
- The returned value is equal to the default pixmap depth.
-
- \sa TQPixmap::defaultDepth()
-*/
-
-int TQColor::numBitPlanes()
-{
- return TQPaintDevice::x11AppDepth();
-}
-
-/*
- Finds the nearest color.
-*/
-
-static int find_nearest_color( int r, int g, int b, int* mindist_out,
- TQColorScreenData *sd )
-{
- int mincol = -1;
- int mindist = 200000;
- int rx, gx, bx, dist;
- XColor *xc = &sd->g_carr[0];
- for ( int i=0; i<sd->g_cells; i++ ) {
- rx = r - (xc->red >> 8);
- gx = g - (xc->green >> 8);
- bx = b - (xc->blue>> 8);
- dist = rx*rx + gx*gx + bx*bx; // calculate distance
- if ( dist < mindist ) { // minimal?
- mindist = dist;
- mincol = i;
- }
- xc++;
- }
- *mindist_out = mindist;
- return mincol;
-}
-
-/*!
- \internal
- Allocates the color on screen \a screen. Only used in X11.
-
- \sa alloc(), pixel()
-*/
-uint TQColor::alloc( int screen )
-{
- Display *dpy = TQPaintDevice::x11AppDisplay();
- if ( screen < 0 )
- screen = TQPaintDevice::x11AppScreen();
- if ( !color_init )
- return dpy ? (uint)BlackPixel(dpy, screen) : 0;
- int r = tqRed(d.argb);
- int g = tqGreen(d.argb);
- int b = tqBlue(d.argb);
- uint pix = 0;
- TQColorScreenData *sd = screendata[screen];
- if ( sd->g_truecolor ) { // truecolor: map to pixel
- r = sd->red_shift > 0 ? r << sd->red_shift : r >> -sd->red_shift;
- g = sd->green_shift > 0 ? g << sd->green_shift : g >> -sd->green_shift;
- b = sd->blue_shift > 0 ? b << sd->blue_shift : b >> -sd->blue_shift;
- pix = (b & sd->blue_mask) | (g & sd->green_mask) | (r & sd->red_mask)
- | ~(sd->blue_mask | sd->green_mask | sd->red_mask);
- if ( screen == TQPaintDevice::x11AppScreen() )
- d.d32.pix = pix;
- return pix;
- }
- TQColorData *c = sd->colorDict->find( (long)(d.argb) );
- if ( c ) { // found color in dictionary
- pix = c->pix;
- if ( screen == TQPaintDevice::x11AppScreen() ) {
- d.d8.invalid = FALSE; // color ok
- d.d8.dirty = FALSE;
- d.d8.pix = pix; // use same pixel value
- if ( c->context != current_alloc_context ) {
- c->context = 0; // convert to default context
- sd->g_our_alloc[pix] = TRUE; // reuse without XAllocColor
- }
- }
- return pix;
- }
-
- XColor col;
- col.red = r << 8;
- col.green = g << 8;
- col.blue = b << 8;
-
- bool try_again = FALSE;
- bool try_alloc = !sd->color_reduce;
- int try_count = 0;
-
- do {
- // This loop is run until we manage to either allocate or
- // find an approximate color, it stops after a few iterations.
-
- try_again = FALSE;
-
- if ( try_alloc && sd->colors_avail &&
- XAllocColor(dpy, TQPaintDevice::x11AppColormap( screen ),&col) ) {
- // We could allocate the color
- pix = (uint) col.pixel;
- if ( screen == TQPaintDevice::x11AppScreen() ) {
- d.d8.pix = pix;
- d.d8.invalid = FALSE;
- d.d8.dirty = FALSE;
- sd->g_carr[d.d8.pix] = col; // update color array
- if ( current_alloc_context == 0 )
- sd->g_our_alloc[d.d8.pix] = TRUE; // reuse without XAllocColor
- }
- } else {
- // No available colors, or we did not want to allocate one
- int i;
- sd->colors_avail = FALSE; // no more available colors
- if ( sd->g_carr_fetch ) { // refetch color array
- sd->g_carr_fetch = FALSE;
- XQueryColors( dpy, TQPaintDevice::x11AppColormap( screen ), sd->g_carr,
- sd->g_cells );
- }
- int mindist;
- i = find_nearest_color( r, g, b, &mindist, sd );
-
- if ( mindist != 0 && !try_alloc ) {
- // Not an exact match with an existing color
- int rr = ((r+sd->col_div_r/2)/sd->col_div_r)*sd->col_div_r;
- int rg = ((g+sd->col_div_g/2)/sd->col_div_g)*sd->col_div_g;
- int rb = ((b+sd->col_div_b/2)/sd->col_div_b)*sd->col_div_b;
- int rx = rr - r;
- int gx = rg - g;
- int bx = rb - b;
- int dist = rx*rx + gx*gx + bx*bx; // calculate distance
- if ( dist < mindist ) {
- // reduced color is closer - try to alloc it
- r = rr;
- g = rg;
- b = rb;
- col.red = r << 8;
- col.green = g << 8;
- col.blue = b << 8;
- try_alloc = TRUE;
- try_again = TRUE;
- sd->colors_avail = TRUE;
- continue; // Try alloc reduced color
- }
- }
-
- if ( i == -1 ) { // no nearest color?!
- int unused, value;
- hsv(&unused, &unused, &value);
- if (value < 128) { // dark, use black
- d.argb = tqRgb(0,0,0);
- pix = (uint)BlackPixel( dpy, screen );
- if ( screen == TQPaintDevice::x11AppScreen() ) {
- d.d8.invalid = FALSE;
- d.d8.dirty = FALSE;
- d.d8.pix = pix;
- }
- } else { // light, use white
- d.argb = tqRgb(0xff,0xff,0xff);
- pix = (uint)WhitePixel( dpy, screen );
- if ( screen == TQPaintDevice::x11AppScreen() ) {
- d.d8.invalid = FALSE;
- d.d8.dirty = FALSE;
- d.d8.pix = pix;
- }
- }
- return pix;
- }
- if ( sd->g_our_alloc[i] ) { // we've already allocated it
- ; // i == g_carr[i].pixel
- } else {
- // Try to allocate existing color
- col = sd->g_carr[i];
- if ( XAllocColor(dpy, TQPaintDevice::x11AppColormap( screen ), &col) ) {
- i = (uint)col.pixel;
- sd->g_carr[i] = col; // update color array
- if ( screen == TQPaintDevice::x11AppScreen() ) {
- if ( current_alloc_context == 0 )
- sd->g_our_alloc[i] = TRUE; // only in the default context
- }
- } else {
- // Oops, it's gone again
- try_count++;
- try_again = TRUE;
- sd->colors_avail = TRUE;
- sd->g_carr_fetch = TRUE;
- }
- }
- if ( !try_again ) { // got it
- pix = (uint)sd->g_carr[i].pixel;
- if ( screen == TQPaintDevice::x11AppScreen() ) {
- d.d8.invalid = FALSE;
- d.d8.dirty = FALSE;
- d.d8.pix = pix; // allocated X11 color
- }
- }
- }
-
- } while ( try_again && try_count < 2 );
-
- if ( try_again ) { // no hope of allocating color
- int unused, value;
- hsv(&unused, &unused, &value);
- if (value < 128) { // dark, use black
- d.argb = tqRgb(0,0,0);
- pix = (uint)BlackPixel( dpy, screen );
- if ( screen == TQPaintDevice::x11AppScreen() ) {
- d.d8.invalid = FALSE;
- d.d8.dirty = FALSE;
- d.d8.pix = pix;
- }
- } else { // light, use white
- d.argb = tqRgb(0xff,0xff,0xff);
- pix = (uint)WhitePixel( dpy, screen );
- if ( screen == TQPaintDevice::x11AppScreen() ) {
- d.d8.invalid = FALSE;
- d.d8.dirty = FALSE;
- d.d8.pix = pix;
- }
- }
- return pix;
- }
- // All colors outside context 0 must go into the dictionary
- bool many = sd->colorDict->count() >= sd->colorDict->size() * 8;
- if ( many && sd->colorDict->size() == col_std_dict ) {
- sd->colorDict->resize( col_large_dict );
- }
- if ( !many || current_alloc_context != 0 ) {
- c = new TQColorData; // insert into color dict
- TQ_CHECK_PTR( c );
- c->pix = pix;
- c->context = current_alloc_context;
- sd->colorDict->insert( (long)d.argb, c ); // store color in dict
- }
- return pix;
-}
-
-/*!
- Allocates the RGB color and returns the pixel value.
-
- Allocating a color means to obtain a pixel value from the RGB
- specification. The pixel value is an index into the global color
- table, but should be considered an arbitrary platform-dependent value.
-
- The pixel() function calls alloc() if necessary, so in general you
- don't need to call this function.
-
- \sa enterAllocContext()
-*/
-// ### 4.0 - remove me?
-uint TQColor::alloc()
-{
- return alloc( -1 );
-}
-
-#else // USE_QT4
-
-// NOT REVISED
-
-/*****************************************************************************
- The color dictionary speeds up color allocation significantly for X11.
- When there are no more colors, TQColor::alloc() will set the colors_avail
- flag to FALSE and try to find the nearest color.
- NOTE: From deep within the event loop, the colors_avail flag is reset to
- TRUE (calls the function qt_reset_color_avail()), because some other
- application might free its colors, thereby making them available for
- this TQt application.
- *****************************************************************************/
-
-#include "tqintdict.h"
-
-struct TQColorData {
- uint pix; // allocated pixel value
- int context; // allocation context
-};
-
-typedef TQIntDict<TQColorData> TQColorDict;
-typedef TQIntDictIterator<TQColorData> TQColorDictIt;
-static int current_alloc_context = 0; // current color alloc context
-static const uint col_std_dict = 419;
-static const uint col_large_dict = 18397;
-
-class TQColorScreenData {
-public:
- TQColorScreenData()
- {
- colorDict = 0;
- colors_avail = TRUE;
- g_vis = 0;
- g_carr = 0;
- g_carr_fetch = TRUE;
- g_cells = 0;
- g_our_alloc = 0;
- color_reduce = FALSE;
- }
-
- TQColorDict *colorDict; // dict of allocated colors
- bool colors_avail; // X colors available
- bool g_truecolor; // truecolor visual
- Visual *g_vis; // visual
- XColor *g_carr; // color array
- bool g_carr_fetch; // perform XQueryColors?
- int g_cells; // number of entries in g_carr
- bool *g_our_alloc; // our allocated colors
- uint red_mask , green_mask , blue_mask;
- int red_shift, green_shift, blue_shift;
- bool color_reduce;
- int col_div_r;
- int col_div_g;
- int col_div_b;
-};
-
-static int screencount = 0;
-static TQColorScreenData **screendata = 0; // array of screendata pointers
-
-
-/*
- This function is called from the event loop. It resets the colors_avail
- flag so that the application can retry to allocate read-only colors
- that other applications may have deallocated lately.
-
- The g_our_alloc and g_carr are global arrays that optimize color
- approximation when there are no more colors left to allocate.
-*/
-
-void qt_reset_color_avail()
-{
- int i;
- for ( i = 0; i < screencount; i++ ) {
- screendata[i]->colors_avail = TRUE;
- screendata[i]->g_carr_fetch = TRUE; // do XQueryColors if !colors_avail
- }
-}
-
-
-/*
- Finds the nearest color.
-*/
-
-static int find_nearest_color( int r, int g, int b, int* mindist_out,
- TQColorScreenData *sd )
-{
- int mincol = -1;
- int mindist = 200000;
- int rx, gx, bx, dist;
- XColor *xc = &sd->g_carr[0];
- for ( int i=0; i<sd->g_cells; i++ ) {
- rx = r - (xc->red >> 8);
- gx = g - (xc->green >> 8);
- bx = b - (xc->blue>> 8);
- dist = rx*rx + gx*gx + bx*bx; // calculate distance
- if ( dist < mindist ) { // minimal?
- mindist = dist;
- mincol = i;
- }
- xc++;
- }
- *mindist_out = mindist;
- return mincol;
-}
-
-
-/*****************************************************************************
- TQColor misc internal functions
- *****************************************************************************/
-
-static int highest_bit( uint v )
-{
- int i;
- uint b = (uint)1 << 31; // get pos of highest bit in v
- for ( i=31; ((b & v) == 0) && i>=0; i-- )
- b >>= 1;
- return i;
-}
-
-
-/*****************************************************************************
- TQColor static member functions
- *****************************************************************************/
-
-/*!
- Returns the maximum number of colors supported by the underlying
- window system if the window system uses a palette.
-
- Otherwise returns -1. Use numBitPlanes() to calculate the available
- colors in that case.
-*/
-
-int TQColor::maxColors()
-{
- Visual *visual = (Visual *) TQPaintDevice::x11AppVisual();
- if (visual->c_class & 1)
- return TQPaintDevice::x11AppCells();
- return -1;
-}
-
-/*!
- Returns the number of color bit planes for the underlying window
- system.
-
- The returned value is equal to the default pixmap depth.
-
- \sa TQPixmap::defaultDepth()
-*/
-
-int TQColor::numBitPlanes()
-{
- return TQPaintDevice::x11AppDepth();
-}
-
-
-/*!
- Internal initialization required for TQColor.
- This function is called from the TQApplication constructor.
-
- \sa cleanup()
-*/
-
-void TQColor::initialize()
-{
- static const int blackIdx = 2;
- static const int whiteIdx = 3;
-
- if ( color_init ) // already initialized
- return;
- color_init = TRUE;
-
- Display *dpy = TQPaintDevice::x11AppDisplay();
- int spec = TQApplication::colorSpec();
-
- screencount = ScreenCount( dpy );
- screendata = new TQColorScreenData*[ screencount ];
-
- int scr;
- for ( scr = 0; scr < screencount; ++scr ) {
- screendata[scr] = new TQColorScreenData;
- screendata[scr]->g_vis = (Visual *) TQPaintDevice::x11AppVisual( scr );
- screendata[scr]->g_truecolor = screendata[scr]->g_vis->c_class == TrueColor
- || screendata[scr]->g_vis->c_class == DirectColor;
-
- int ncols = TQPaintDevice::x11AppCells( scr );
-
- if ( screendata[scr]->g_truecolor ) {
- if (scr == DefaultScreen(dpy))
- colormodel = d32;
- } else {
- if (scr == DefaultScreen(dpy))
- colormodel = d8;
-
- // Create the g_our_alloc array, which remembers which color pixels
- // we allocated.
- screendata[scr]->g_cells = TQMIN(ncols,256);
- screendata[scr]->g_carr = new XColor[screendata[scr]->g_cells];
- TQ_CHECK_PTR( screendata[scr]->g_carr );
- memset( screendata[scr]->g_carr, 0,
- screendata[scr]->g_cells*sizeof(XColor) );
- screendata[scr]->g_carr_fetch = TRUE; // run XQueryColors on demand
- screendata[scr]->g_our_alloc = new bool[screendata[scr]->g_cells];
- TQ_CHECK_PTR( screendata[scr]->g_our_alloc );
- memset( screendata[scr]->g_our_alloc, FALSE,
- screendata[scr]->g_cells*sizeof(bool) );
- XColor *xc = &screendata[scr]->g_carr[0];
- for ( int i=0; i<screendata[scr]->g_cells; i++ ) {
- xc->pixel = i; // g_carr[i] = color i
- xc++;
- }
- }
-
- int dictsize;
- if ( screendata[scr]->g_truecolor ) { // truecolor
- dictsize = 1; // will not need color dict
- screendata[scr]->red_mask = (uint)screendata[scr]->g_vis->red_mask;
- screendata[scr]->green_mask = (uint)screendata[scr]->g_vis->green_mask;
- screendata[scr]->blue_mask = (uint)screendata[scr]->g_vis->blue_mask;
- screendata[scr]->red_shift =
- highest_bit( screendata[scr]->red_mask ) - 7;
- screendata[scr]->green_shift =
- highest_bit( screendata[scr]->green_mask ) - 7;
- screendata[scr]->blue_shift =
- highest_bit( screendata[scr]->blue_mask ) - 7;
- } else {
- dictsize = col_std_dict;
- }
- screendata[scr]->colorDict = new TQColorDict(dictsize); // create dictionary
- TQ_CHECK_PTR( screendata[scr]->colorDict );
-
- if ( spec == (int)TQApplication::ManyColor ) {
- screendata[scr]->color_reduce = TRUE;
-
- switch ( qt_ncols_option ) {
- case 216:
- // 6:6:6
- screendata[scr]->col_div_r = screendata[scr]->col_div_g =
- screendata[scr]->col_div_b = (255/(6-1));
- break;
- default: {
- // 2:3:1 proportions, solved numerically
- if ( qt_ncols_option > 255 ) qt_ncols_option = 255;
- if ( qt_ncols_option < 1 ) qt_ncols_option = 1;
- int nr = 2;
- int ng = 2;
- int nb = 2;
- for (;;) {
- if ( nb*2 < nr && (nb+1)*nr*ng < qt_ncols_option )
- nb++;
- else if ( nr*3 < ng*2 && nb*(nr+1)*ng < qt_ncols_option )
- nr++;
- else if ( nb*nr*(ng+1) < qt_ncols_option )
- ng++;
- else break;
- }
- qt_ncols_option = nr*ng*nb;
- screendata[scr]->col_div_r = (255/(nr-1));
- screendata[scr]->col_div_g = (255/(ng-1));
- screendata[scr]->col_div_b = (255/(nb-1));
- }
- }
- }
- }
-
- scr = TQPaintDevice::x11AppScreen();
-
- // Initialize global color objects
- if ( TQPaintDevice::x11AppDefaultVisual(scr) &&
- TQPaintDevice::x11AppDefaultColormap(scr) ) {
- globalColors()[blackIdx].setPixel((uint) BlackPixel(dpy, scr));
- globalColors()[whiteIdx].setPixel((uint) WhitePixel(dpy, scr));
- } else {
- globalColors()[blackIdx].alloc(scr);
- globalColors()[whiteIdx].alloc(scr);
- }
-
-#if 0 /* 0 == allocate colors on demand */
- setLazyAlloc( FALSE ); // allocate global colors
- ((TQColor*)(&darkGray))-> alloc();
- ((TQColor*)(&gray))-> alloc();
- ((TQColor*)(&lightGray))-> alloc();
- ((TQColor*)(&::red))-> alloc();
- ((TQColor*)(&::green))-> alloc();
- ((TQColor*)(&::blue))-> alloc();
- ((TQColor*)(&cyan))-> alloc();
- ((TQColor*)(&magenta))-> alloc();
- ((TQColor*)(&yellow))-> alloc();
- ((TQColor*)(&darkRed))-> alloc();
- ((TQColor*)(&darkGreen))-> alloc();
- ((TQColor*)(&darkBlue))-> alloc();
- ((TQColor*)(&darkCyan))-> alloc();
- ((TQColor*)(&darkMagenta))-> alloc();
- ((TQColor*)(&darkYellow))-> alloc();
- setLazyAlloc( TRUE );
-#endif
-}
-
-/*!
- Internal clean up required for TQColor.
- This function is called from the TQApplication destructor.
-
- \sa initialize()
-*/
-
-void TQColor::cleanup()
-{
- if ( !color_init )
- return;
- color_init = FALSE;
- int scr;
- for ( scr = 0; scr < screencount; scr++ ) {
- if ( screendata[scr]->g_carr ) {
- delete [] screendata[scr]->g_carr;
- screendata[scr]->g_carr = 0;
- }
- if ( screendata[scr]->g_our_alloc ) {
- delete [] screendata[scr]->g_our_alloc;
- screendata[scr]->g_our_alloc = 0;
- }
- if ( screendata[scr]->colorDict ) {
- screendata[scr]->colorDict->setAutoDelete( TRUE );
- screendata[scr]->colorDict->clear();
- delete screendata[scr]->colorDict;
- screendata[scr]->colorDict = 0;
- }
- delete screendata[scr];
- screendata[scr] = 0;
- }
- delete [] screendata;
- screendata = 0;
- screencount = 0;
-}
-
-
-/*****************************************************************************
- TQColor member functions
- *****************************************************************************/
-
-/*!
- \internal
- Allocates the color on screen \a screen. Only used in X11.
-
- \sa alloc(), pixel()
-*/
-uint TQColor::alloc( int screen )
-{
- Display *dpy = TQPaintDevice::x11AppDisplay();
- if ( screen < 0 )
- screen = TQPaintDevice::x11AppScreen();
- if ( !color_init )
- return dpy ? (uint)BlackPixel(dpy, screen) : 0;
- int r = tqRed(d.argb);
- int g = tqGreen(d.argb);
- int b = tqBlue(d.argb);
- uint pix = 0;
- TQColorScreenData *sd = screendata[screen];
- if ( sd->g_truecolor ) { // truecolor: map to pixel
- r = sd->red_shift > 0 ? r << sd->red_shift : r >> -sd->red_shift;
- g = sd->green_shift > 0 ? g << sd->green_shift : g >> -sd->green_shift;
- b = sd->blue_shift > 0 ? b << sd->blue_shift : b >> -sd->blue_shift;
- pix = (b & sd->blue_mask) | (g & sd->green_mask) | (r & sd->red_mask)
- | ~(sd->blue_mask | sd->green_mask | sd->red_mask);
- if ( screen == TQPaintDevice::x11AppScreen() )
- d.d32.pix = pix;
- return pix;
- }
- TQColorData *c = sd->colorDict->find( (long)(d.argb) );
- if ( c ) { // found color in dictionary
- pix = c->pix;
- if ( screen == TQPaintDevice::x11AppScreen() ) {
- d.d8.invalid = FALSE; // color ok
- d.d8.dirty = FALSE;
- d.d8.pix = pix; // use same pixel value
- if ( c->context != current_alloc_context ) {
- c->context = 0; // convert to default context
- sd->g_our_alloc[pix] = TRUE; // reuse without XAllocColor
- }
- }
- return pix;
- }
-
- XColor col;
- col.red = r << 8;
- col.green = g << 8;
- col.blue = b << 8;
-
- bool try_again = FALSE;
- bool try_alloc = !sd->color_reduce;
- int try_count = 0;
-
- do {
- // This loop is run until we manage to either allocate or
- // find an approximate color, it stops after a few iterations.
-
- try_again = FALSE;
-
- if ( try_alloc && sd->colors_avail &&
- XAllocColor(dpy, TQPaintDevice::x11AppColormap( screen ),&col) ) {
- // We could allocate the color
- pix = (uint) col.pixel;
- if ( screen == TQPaintDevice::x11AppScreen() ) {
- d.d8.pix = pix;
- d.d8.invalid = FALSE;
- d.d8.dirty = FALSE;
- sd->g_carr[d.d8.pix] = col; // update color array
- if ( current_alloc_context == 0 )
- sd->g_our_alloc[d.d8.pix] = TRUE; // reuse without XAllocColor
- }
- } else {
- // No available colors, or we did not want to allocate one
- int i;
- sd->colors_avail = FALSE; // no more available colors
- if ( sd->g_carr_fetch ) { // refetch color array
- sd->g_carr_fetch = FALSE;
- XQueryColors( dpy, TQPaintDevice::x11AppColormap( screen ), sd->g_carr,
- sd->g_cells );
- }
- int mindist;
- i = find_nearest_color( r, g, b, &mindist, sd );
-
- if ( mindist != 0 && !try_alloc ) {
- // Not an exact match with an existing color
- int rr = ((r+sd->col_div_r/2)/sd->col_div_r)*sd->col_div_r;
- int rg = ((g+sd->col_div_g/2)/sd->col_div_g)*sd->col_div_g;
- int rb = ((b+sd->col_div_b/2)/sd->col_div_b)*sd->col_div_b;
- int rx = rr - r;
- int gx = rg - g;
- int bx = rb - b;
- int dist = rx*rx + gx*gx + bx*bx; // calculate distance
- if ( dist < mindist ) {
- // reduced color is closer - try to alloc it
- r = rr;
- g = rg;
- b = rb;
- col.red = r << 8;
- col.green = g << 8;
- col.blue = b << 8;
- try_alloc = TRUE;
- try_again = TRUE;
- sd->colors_avail = TRUE;
- continue; // Try alloc reduced color
- }
- }
-
- if ( i == -1 ) { // no nearest color?!
- int unused, value;
- hsv(&unused, &unused, &value);
- if (value < 128) { // dark, use black
- d.argb = tqRgb(0,0,0);
- pix = (uint)BlackPixel( dpy, screen );
- if ( screen == TQPaintDevice::x11AppScreen() ) {
- d.d8.invalid = FALSE;
- d.d8.dirty = FALSE;
- d.d8.pix = pix;
- }
- } else { // light, use white
- d.argb = tqRgb(0xff,0xff,0xff);
- pix = (uint)WhitePixel( dpy, screen );
- if ( screen == TQPaintDevice::x11AppScreen() ) {
- d.d8.invalid = FALSE;
- d.d8.dirty = FALSE;
- d.d8.pix = pix;
- }
- }
- return pix;
- }
- if ( sd->g_our_alloc[i] ) { // we've already allocated it
- ; // i == g_carr[i].pixel
- } else {
- // Try to allocate existing color
- col = sd->g_carr[i];
- if ( XAllocColor(dpy, TQPaintDevice::x11AppColormap( screen ), &col) ) {
- i = (uint)col.pixel;
- sd->g_carr[i] = col; // update color array
- if ( screen == TQPaintDevice::x11AppScreen() ) {
- if ( current_alloc_context == 0 )
- sd->g_our_alloc[i] = TRUE; // only in the default context
- }
- } else {
- // Oops, it's gone again
- try_count++;
- try_again = TRUE;
- sd->colors_avail = TRUE;
- sd->g_carr_fetch = TRUE;
- }
- }
- if ( !try_again ) { // got it
- pix = (uint)sd->g_carr[i].pixel;
- if ( screen == TQPaintDevice::x11AppScreen() ) {
- d.d8.invalid = FALSE;
- d.d8.dirty = FALSE;
- d.d8.pix = pix; // allocated X11 color
- }
- }
- }
-
- } while ( try_again && try_count < 2 );
-
- if ( try_again ) { // no hope of allocating color
- int unused, value;
- hsv(&unused, &unused, &value);
- if (value < 128) { // dark, use black
- d.argb = tqRgb(0,0,0);
- pix = (uint)BlackPixel( dpy, screen );
- if ( screen == TQPaintDevice::x11AppScreen() ) {
- d.d8.invalid = FALSE;
- d.d8.dirty = FALSE;
- d.d8.pix = pix;
- }
- } else { // light, use white
- d.argb = tqRgb(0xff,0xff,0xff);
- pix = (uint)WhitePixel( dpy, screen );
- if ( screen == TQPaintDevice::x11AppScreen() ) {
- d.d8.invalid = FALSE;
- d.d8.dirty = FALSE;
- d.d8.pix = pix;
- }
- }
- return pix;
- }
- // All colors outside context 0 must go into the dictionary
- bool many = sd->colorDict->count() >= sd->colorDict->size() * 8;
- if ( many && sd->colorDict->size() == col_std_dict ) {
- sd->colorDict->resize( col_large_dict );
- }
- if ( !many || current_alloc_context != 0 ) {
- c = new TQColorData; // insert into color dict
- TQ_CHECK_PTR( c );
- c->pix = pix;
- c->context = current_alloc_context;
- sd->colorDict->insert( (long)d.argb, c ); // store color in dict
- }
- return pix;
-}
-
-/*!
- Allocates the RGB color and returns the pixel value.
-
- Allocating a color means to obtain a pixel value from the RGB
- specification. The pixel value is an index into the global color
- table, but should be considered an arbitrary platform-dependent value.
-
- The pixel() function calls alloc() if necessary, so in general you
- don't need to call this function.
-
- \sa enterAllocContext()
-*/
-// ### 4.0 - remove me?
-uint TQColor::alloc()
-{
- return alloc( -1 );
-}
-
-/*!
- \overload
-
- Returns the pixel value for screen \a screen.
-
- This value is used by the underlying window system to refer to a color.
- It can be thought of as an index into the display hardware's color table,
- but the value is an arbitrary 32-bit value.
-
- \sa alloc()
-*/
-uint TQColor::pixel( int screen ) const
-{
- if (screen != TQPaintDevice::x11AppScreen() &&
- // don't allocate color0 or color1, they have fixed pixel
- // values for all screens
- d.argb != tqRgba(255, 255, 255, 1) && d.argb != tqRgba(0, 0, 0, 1))
- return ((TQColor*)this)->alloc( screen );
- return pixel();
-}
-
-
-void TQColor::setSystemNamedColor( const TQString& name )
-{
- // setSystemNamedColor should look up rgb values from the built in
- // color tables first (see qcolor_p.cpp), and failing that, use
- // the window system's interface for translating names to rgb values...
- // we do this so that things like uic can load an XPM file with named colors
- // and convert it to a png without having to use window system functions...
- d.argb = qt_get_rgb_val( name.latin1() );
- TQRgb rgb;
- if ( qt_get_named_rgb( name.latin1(), &rgb ) ) {
- setRgb( tqRed(rgb), tqGreen(rgb), tqBlue(rgb) );
- if ( colormodel == d8 ) {
- d.d8.invalid = FALSE;
- d.d8.dirty = TRUE;
- d.d8.pix = 0;
- } else {
- alloc();
- }
- } else if ( !color_init ) {
-#if defined(TQT_CHECK_STATE)
- qWarning( "TQColor::setSystemNamedColor: Cannot perform this operation "
- "because TQApplication does not exist" );
-#endif
- // set color to invalid
- *this = TQColor();
- } else {
- XColor col, hw_col;
- if ( XLookupColor(TQPaintDevice::x11AppDisplay(),
- TQPaintDevice::x11AppColormap(), name.latin1(),
- &col, &hw_col) ) {
- setRgb( col.red>>8, col.green>>8, col.blue>>8 );
- } else {
- // set color to invalid
- *this = TQColor();
- }
- }
-}
-
-
-#define MAX_CONTEXTS 16
-static int context_stack[MAX_CONTEXTS];
-static int context_ptr = 0;
-
-static void init_context_stack()
-{
- static bool did_init = FALSE;
- if ( !did_init ) {
- did_init = TRUE;
- context_stack[0] = current_alloc_context = 0;
- }
-}
-
-
-/*!
- Enters a color allocation context and returns a non-zero unique
- identifier.
-
- Color allocation contexts are useful for programs that need to
- allocate many colors and throw them away later, like image
- viewers. The allocation context functions work for true color
- displays as well as for colormap displays, except that
- TQColor::destroyAllocContext() does nothing for true color.
-
- Example:
- \code
- TQPixmap loadPixmap( TQString fileName )
- {
- static int alloc_context = 0;
- if ( alloc_context )
- TQColor::destroyAllocContext( alloc_context );
- alloc_context = TQColor::enterAllocContext();
- TQPixmap pm( fileName );
- TQColor::leaveAllocContext();
- return pm;
- }
- \endcode
-
- The example code loads a pixmap from file. It frees up all colors
- that were allocated the last time loadPixmap() was called.
-
- The initial/default context is 0. TQt keeps a list of colors
- associated with their allocation contexts. You can call
- destroyAllocContext() to get rid of all colors that were allocated
- in a specific context.
-
- Calling enterAllocContext() enters an allocation context. The
- allocation context lasts until you call leaveAllocContext().
- TQColor has an internal stack of allocation contexts. Each call to
- enterAllocContex() must have a corresponding leaveAllocContext().
-
- \code
- // context 0 active
- int c1 = TQColor::enterAllocContext(); // enter context c1
- // context c1 active
- int c2 = TQColor::enterAllocContext(); // enter context c2
- // context c2 active
- TQColor::leaveAllocContext(); // leave context c2
- // context c1 active
- TQColor::leaveAllocContext(); // leave context c1
- // context 0 active
- // Now, free all colors that were allocated in context c2
- TQColor::destroyAllocContext( c2 );
- \endcode
-
- You may also want to set the application's color specification.
- See TQApplication::setColorSpec() for more information.
-
- \sa leaveAllocContext(), currentAllocContext(), destroyAllocContext(),
- TQApplication::setColorSpec()
-*/
-
-int TQColor::enterAllocContext()
-{
- static int context_seq_no = 0;
- init_context_stack();
- if ( context_ptr+1 == MAX_CONTEXTS ) {
-#if defined(TQT_CHECK_STATE)
- qWarning( "TQColor::enterAllocContext: Context stack overflow" );
-#endif
- return 0;
- }
- current_alloc_context = context_stack[++context_ptr] = ++context_seq_no;
- return current_alloc_context;
-}
-
-
-/*!
- Leaves a color allocation context.
-
- See enterAllocContext() for a detailed explanation.
-
- \sa enterAllocContext(), currentAllocContext()
-*/
-
-void TQColor::leaveAllocContext()
-{
- init_context_stack();
- if ( context_ptr == 0 ) {
-#if defined(TQT_CHECK_STATE)
- qWarning( "TQColor::leaveAllocContext: Context stack underflow" );
-#endif
- return;
- }
- current_alloc_context = context_stack[--context_ptr];
-}
-
-
-/*!
- Returns the current color allocation context.
-
- The default context is 0.
-
- \sa enterAllocContext(), leaveAllocContext()
-*/
-
-int TQColor::currentAllocContext()
-{
- return current_alloc_context;
-}
-
-
-/*!
- Destroys a color allocation context, \e context.
-
- This function deallocates all colors that were allocated in the
- specified \a context. If \a context == -1, it frees up all colors
- that the application has allocated. If \a context == -2, it frees
- up all colors that the application has allocated, except those in
- the default context.
-
- The function does nothing for true color displays.
-
- \sa enterAllocContext(), alloc()
-*/
-
-void TQColor::destroyAllocContext( int context )
-{
- init_context_stack();
- if ( !color_init )
- return;
-
- int screen;
- for ( screen = 0; screen < screencount; ++screen ) {
- if ( screendata[screen]->g_truecolor )
- continue;
-
- ulong pixels[256];
- bool freeing[256];
- memset( freeing, FALSE, screendata[screen]->g_cells*sizeof(bool) );
- TQColorData *d;
- TQColorDictIt it( *screendata[screen]->colorDict );
- int i = 0;
- uint rgbv;
- while ( (d=it.current()) ) {
- rgbv = (uint)it.currentKey();
- if ( (d->context || context==-1) &&
- (d->context == context || context < 0) ) {
- if ( !screendata[screen]->g_our_alloc[d->pix] && !freeing[d->pix] ) {
- // will free this color
- pixels[i++] = d->pix;
- freeing[d->pix] = TRUE;
- }
- // remove from dict
- screendata[screen]->colorDict->remove( (long)rgbv );
- }
- ++it;
- }
- if ( i )
- XFreeColors( TQPaintDevice::x11AppDisplay(),
- TQPaintDevice::x11AppColormap( screen ),
- pixels, i, 0 );
- }
-}
-
-#endif // USE_QT4 \ No newline at end of file