home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / yacl-012.zip / ui / colormap.cxx < prev    next >
C/C++ Source or Header  |  1995-04-04  |  11KB  |  456 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6. /*
  7.  *
  8.  *          Copyright (C) 1994, M. A. Sridhar
  9.  *  
  10.  *
  11.  *     This software is Copyright M. A. Sridhar, 1994. You are free
  12.  *     to copy, modify or distribute this software  as you see fit,
  13.  *     and to use  it  for  any  purpose, provided   this copyright
  14.  *     notice and the following   disclaimer are included  with all
  15.  *     copies.
  16.  *
  17.  *                        DISCLAIMER
  18.  *
  19.  *     The author makes no warranties, either expressed or implied,
  20.  *     with respect  to  this  software, its  quality, performance,
  21.  *     merchantability, or fitness for any particular purpose. This
  22.  *     software is distributed  AS IS.  The  user of this  software
  23.  *     assumes all risks  as to its quality  and performance. In no
  24.  *     event shall the author be liable for any direct, indirect or
  25.  *     consequential damages, even if the  author has been  advised
  26.  *     as to the possibility of such damages.
  27.  *
  28.  */
  29.  
  30.  
  31. #if defined(__GNUC__)
  32. #pragma implementation
  33. #endif
  34.  
  35.  
  36. #include "ui/colormap.h"
  37. #include "ui/applic.h"
  38. #include "ui/cntroler.h"
  39. #include "ui/dsplsurf.h"
  40. #include "ui/color.h"
  41.  
  42. #if defined (__MS_WINDOWS__)
  43. #include <windows.h>
  44.  
  45. #elif defined(__OS2__)
  46. class UI_ColorMapEntry {
  47.     ulong h;
  48. } ; // Temporary
  49. #elif defined (__X_MOTIF__)
  50. #include <X11/Intrinsic.h>
  51. extern "C" { short sprintf (char *, ...); };
  52. #endif
  53.  
  54. UI_ColorMapType UI_ColorMap::_defaultcmap;
  55.  
  56.  
  57. UI_ColorMap::UI_ColorMap (UI_DisplaySurface& d): _dsurface (d)
  58. {
  59.     _numcolors = 0;
  60.     _colors    = NULL;
  61.  
  62. #if defined (__MS_WINDOWS__)
  63.     LOGPALETTE lp;
  64.  
  65.     lp.palVersion    = 0x300;
  66.     lp.palNumEntries = 1;
  67.     _cmap   = CreatePalette (&lp);
  68.     if (!_cmap) {
  69.         CL_Error::Warning ("UI_ColorMap::UI_ColorMap: %s",
  70.                            "Cant Allocate the colormap");
  71.         return;
  72.     }
  73.  
  74. #elif defined (__X_MOTIF__)
  75.     XSetWindowAttributes     xattributes;
  76.     Display *dpy   = XtDisplay (_dsurface.Client ());
  77.     short screen_num = DefaultScreen (dpy);
  78.     
  79.     _defaultcmap = DefaultColormap (dpy, screen_num);
  80.     if (!(_cmap = XCreateColormap (dpy, RootWindow (dpy, screen_num),
  81.                                    DefaultVisual(dpy,screen_num),AllocNone))) {
  82.         CL_Error::Warning ("UI_ColorMap::UI_ColorMap: %s",
  83.                            "Cant Allocate the colormap");
  84.         return;
  85.     }
  86.     
  87.     xattributes.colormap = _cmap;
  88.     ulong valuemask = 0;
  89.     valuemask |= CWColormap;
  90.     XChangeWindowAttributes (dpy, XtWindow (_dsurface.Client ()),
  91.                              valuemask, &xattributes);
  92.     
  93. #endif
  94. }
  95.  
  96.  
  97.  
  98. UI_ColorMap::~UI_ColorMap ()
  99. {
  100. #if defined (__MS_WINDOWS__)
  101.     DeleteObject (_cmap);
  102.  
  103. #elif defined (__X_MOTIF__)
  104.     Display *dpy = XtDisplay (_dsurface.Client ());
  105.     if (_colors)
  106.         XFreeColors   (dpy, _cmap, _colors, _numcolors, 0);
  107.     if (_cmap != _defaultcmap)    
  108.         XFreeColormap (dpy, _cmap);
  109.     
  110. #endif
  111.  
  112.     if (_colors)
  113.         delete [] _colors;
  114. }
  115.  
  116.  
  117.  
  118.  
  119. bool UI_ColorMap::Load (const UI_ColorMapValues v [])
  120. {
  121.     UI_Color c;
  122.     
  123.     for (short i = 0; v [i].red != -1; ++i) {
  124.         c.Red   (v [i].red);
  125.         c.Green (v [i].green);
  126.         c.Blue  (v [i].blue);
  127.         Add (c);
  128.     }
  129.     return TRUE;
  130. }
  131.  
  132.  
  133.  
  134. UI_ColorMapHandle UI_ColorMap::Add (const UI_Color &c)
  135. {
  136.     if (_numcolors >= UI_MAXCOLORS)
  137.         return 0;
  138.  
  139. #if defined (__MS_WINDOWS__)
  140.     if (_colors) 
  141.         delete [] _colors;
  142.   
  143.     _numcolors ++;
  144.     _colors = new UI_ColorMapEntry [_numcolors];
  145.     if (!_colors) {
  146.         CL_Error::Warning ("ColorMap::Add: memory allocation failed");
  147.         return 0;
  148.     }
  149.     ResizePalette (_cmap, _numcolors); 
  150.     if (_numcolors != 1)
  151.         GetPaletteEntries (_cmap, 0, _numcolors - 1, _colors);
  152.     
  153.     short index = _numcolors - 1;
  154.  
  155.     _colors [index].peRed   = LOBYTE (c.Red   ());
  156.     _colors [index].peGreen = LOBYTE (c.Green ());
  157.     _colors [index].peBlue  = LOBYTE (c.Blue  ());
  158.     _colors [index].peFlags = NULL;
  159.  
  160.     if (!SetPaletteEntries (_cmap, index, 1, &(_colors [index]))) 
  161.         CL_Error::Warning ("UI_ColorMap::Add: %s",
  162.                            "Cant allocate Read/Write cells");
  163.     return index;
  164.  
  165. #elif defined (__X_MOTIF__)
  166.     Display *dpy   = XtDisplay (_dsurface.Client ());
  167.  
  168.     XColor &xcolor  = c.NativeForm ();
  169.     
  170.     ulong plane_mask [1];
  171.  
  172.     if (_colors) {
  173.         XFreeColors (dpy, _cmap, _colors, _numcolors, 0);
  174.         delete [] _colors;
  175.         _colors = 0;
  176.     }
  177.     _numcolors ++;
  178.     _colors = new UI_ColorMapEntry [_numcolors];
  179.     if (!_colors) {
  180.         CL_Error::Warning ("ColorMap::Add: memory allocation failed");
  181.         return 0;
  182.     }
  183.     while (1) {
  184.         if (XAllocColorCells (dpy, _cmap, False,
  185.                               plane_mask, 0, _colors, _numcolors))
  186.             break;
  187.         _numcolors --;
  188.         if (_numcolors == 0) {
  189.             CL_Error::Warning ("UI_ColorMap::Add:  %s",
  190.                                "Can't allocate read/write cells");
  191.             return 0;
  192.         }
  193.     
  194.     }
  195.     
  196.     xcolor.flags = DoRed | DoGreen | DoBlue;
  197.     if (_cmap != _defaultcmap)
  198.         _colors [_numcolors-1] = _numcolors - 1;
  199.     xcolor.pixel = _colors [_numcolors-1];
  200.     XStoreColor (dpy, _cmap, &xcolor);
  201.     
  202.     return _colors [_numcolors-1];
  203.     
  204. #endif
  205. }
  206.  
  207.  
  208.  
  209. bool UI_ColorMap::Remove (UI_ColorMapHandle h)
  210. {
  211.     bool retval = TRUE;
  212.  
  213.     ushort j = 0;
  214.     UI_ColorMapEntry *newcolors = new UI_ColorMapEntry [_numcolors-1];
  215.  
  216.     for (ushort i = 0; i < _numcolors; ++i) {
  217.         if (i == h) {
  218.             for (j = i; j < _numcolors-1; ++j) 
  219.                 newcolors [j] = _colors [j+1];
  220.             break;
  221.         }
  222.         newcolors [i] = _colors [i];
  223.     }
  224.  
  225.     delete [] _colors;
  226.     _colors = newcolors;
  227.     _numcolors --;
  228.  
  229. #if defined (__MS_WINDOWS__)
  230.     if (!SetPaletteEntries (_cmap, 0, _numcolors, _colors)) retval = FALSE;
  231.  
  232. #elif defined (__X_MOTIF__)
  233.     Display *dpy = XtDisplay (_dsurface.Client ());
  234.     
  235.     if (!XFreeColors (dpy, _cmap, &h, 1, 0)) retval = FALSE;
  236.      
  237. #endif
  238.  
  239.     return retval;
  240. }
  241.  
  242.  
  243.  
  244. UI_ColorMapHandle UI_ColorMap::Match (const UI_Color &c)
  245. {
  246. #if defined (__MS_WINDOWS__)
  247.     short index = GetNearestPaletteIndex (_cmap, c.NativeForm ());
  248.     return index;
  249.  
  250. #elif defined (__X_MOTIF__)
  251.     Display *dpy  = XtDisplay (_dsurface.Client ());
  252.     XColor xcolor = c.NativeForm ();
  253.     int scr       = DefaultScreen (dpy);
  254.  
  255.     if (XAllocColor (dpy, _cmap, &xcolor)) {
  256.         XFreeColors (dpy, _cmap, &xcolor.pixel, 1, 0);
  257.         return xcolor.pixel;
  258.     }
  259.     else
  260.         return BlackPixel (dpy, scr);
  261.  
  262. #endif
  263. }
  264.  
  265.  
  266.  
  267. UI_ColorMapHandle UI_ColorMap::ExactMatch (const UI_Color &c)
  268. {
  269. #if defined (__MS_WINDOWS__)
  270.     for (short i = 0; i < _numcolors; ++i) {
  271.         if (_colors [i].peRed   == LOBYTE (c.Red   ()) &&
  272.             _colors [i].peGreen == LOBYTE (c.Green ()) && 
  273.             _colors [i].peBlue  == LOBYTE (c.Blue  ())) 
  274.             return i;
  275.     }
  276.     return 0;
  277.             
  278. #elif defined (__X_MOTIF__)
  279.     Display *dpy  = XtDisplay (_dsurface.Client ());
  280.     int scr       = DefaultScreen (dpy);
  281.     XColor xcolor = c.NativeForm ();
  282.     char colorrep [30];
  283.  
  284.     sprintf (colorrep, "RGB:%4x/%4x/%4x", xcolor.red,
  285.              xcolor.green, xcolor.blue);
  286.     XParseColor (dpy, _cmap, colorrep, &xcolor);
  287.  
  288.     return xcolor.pixel;
  289.  
  290. #endif 
  291. }
  292.  
  293.  
  294.  
  295. UI_Color UI_ColorMap::operator[] (UI_ColorMapHandle& h) const
  296. {
  297. #if defined (__MS_WINDOWS__)
  298.     return UI_Color (_colors [h].peRed, _colors [h].peGreen,
  299.                      _colors [h].peBlue);
  300.  
  301. #elif defined (__X_MOTIF__)
  302.  
  303.     XColor xcolor;
  304.     Display *dpy = XtDisplay (_dsurface.Client ());
  305.     
  306.     xcolor.pixel = h;
  307.     XQueryColor (dpy, _cmap, &xcolor);
  308.  
  309.     UI_Color *c = new UI_Color (xcolor.red, xcolor.green, xcolor.blue);
  310.  
  311.     return *c;
  312. #endif 
  313. }
  314.  
  315.  
  316.  
  317. bool UI_ColorMap::Install ()
  318. {
  319.     bool retval = TRUE;
  320.     
  321. #if defined (__MS_WINDOWS__)
  322.     if (!SelectPalette (_dsurface.Handle (), _cmap, FALSE)) retval = FALSE;
  323.     if (!RealizePalette (_cmap)) retval = FALSE;
  324.  
  325. #elif defined (__X_MOTIF__)
  326.     extern UI_Application* _TheApplication;
  327.  
  328.     UI_Application *app        = _TheApplication;
  329.     Widget w                   = _dsurface.Client ();
  330.     Widget toplevel            = app->Controller().ShellWidget();
  331.     Widget colormapwidgets [2] = {w, toplevel};
  332.     Display *dpy               = XtDisplay (_dsurface.Client());
  333.  
  334.     XSetWindowColormap (dpy, XtWindow (w), _cmap);
  335.     XSetWindowColormap (dpy, XtWindow (toplevel), _cmap);
  336.     XtSetWMColormapWindows (toplevel, colormapwidgets, 2);
  337.  
  338. #endif 
  339.  
  340.     return retval;
  341. }
  342.  
  343.  
  344.  
  345. bool UI_ColorMap::UseDefault()
  346. {
  347. #if defined (__MS_WINDOWS__)
  348.     ushort numentries = GetDeviceCaps (_dsurface.Handle(), SIZEPALETTE);
  349.     LOGPALETTE FAR* lp = new LOGPALETTE;
  350.        
  351.     if (_colors)
  352.         delete [] _colors;
  353.     _colors = new UI_ColorMapEntry [numentries];
  354.     if (!_colors) {
  355.         CL_Error::Warning ("ColorMap::Add: memory allocation failed");
  356.         return FALSE;
  357.     }
  358.     GetSystemPaletteEntries (_dsurface.Handle(), 0, numentries, _colors);
  359.     DeleteObject (_cmap);
  360.  
  361.     _defaultcmap = CreatePalette (lp);
  362.     _cmap        = _defaultcmap;
  363.  
  364.     SetPaletteEntries (_defaultcmap, 0, numentries, _colors);
  365.     SelectPalette     (_dsurface.Handle(), _defaultcmap, FALSE);
  366.     _numcolors   = numentries;
  367.  
  368. #elif defined (__X_MOTIF__)
  369.     Display *dpy = XtDisplay (_dsurface.Client ());
  370.     if (_cmap)
  371.         XFreeColormap (dpy, _cmap);
  372.     _cmap = 0;
  373.     _cmap = _defaultcmap;
  374.     XSetWindowColormap (dpy, XtWindow (_dsurface.Client ()), _cmap);
  375.     
  376. #endif 
  377.  
  378.     return TRUE;
  379. }
  380.  
  381.  
  382.  
  383. bool UI_ColorMap::Clear()
  384. {
  385.     bool retval = TRUE;
  386.  
  387. #if defined (__MS_WINDOWS__)
  388.     if(!ResizePalette (_cmap, 0)) retval = FALSE;
  389.  
  390. #elif defined (__X_MOTIF__)
  391.     Display *dpy = XtDisplay (_dsurface.Client ());
  392.     
  393.     if (!XFreeColors (dpy, _cmap, _colors, _numcolors, 0)) retval = FALSE;
  394.  
  395. #endif
  396.  
  397.     _numcolors = 0;
  398.     if (_colors)
  399.         delete [] _colors;
  400.     return retval;
  401. }
  402.  
  403.  
  404.  
  405.  
  406. bool UI_ColorMap::Replace (const UI_ColorMapHandle h, UI_Color &c)
  407.     bool retval = TRUE;
  408.  
  409. #if defined (__MS_WINDOWS__)
  410.     _colors [h].peRed   = LOBYTE (c.Red   ());
  411.     _colors [h].peGreen = LOBYTE (c.Green ());
  412.     _colors [h].peBlue  = LOBYTE (c.Blue  ());
  413.     _colors [h].peFlags = PC_RESERVED;
  414.  
  415.     if (!SetPaletteEntries (_cmap, h, 1, &(_colors [h]))) retval = FALSE;
  416.     
  417. #elif defined (__X_MOTIF__)
  418.     Display *dpy  = XtDisplay (_dsurface.Client());
  419.     XColor xcolor = c.NativeForm ();
  420.  
  421.     xcolor.pixel  = h;
  422.     if (!XStoreColor (dpy, _cmap, &xcolor)) retval = FALSE;
  423.  
  424. #endif 
  425.     
  426.     return retval;
  427. }
  428.  
  429.  
  430.  
  431. bool UI_ColorMap::operator== (const UI_ColorMap &cmap) const
  432. {
  433.     if (_numcolors != cmap._numcolors) return FALSE;
  434.  
  435.     for (ulong i = 0; i < _numcolors; ++i) {
  436.         if ((*this) [(UI_ColorMapHandle &) i] 
  437.             == cmap [(UI_ColorMapHandle &) i]) continue;
  438.         else return FALSE;
  439.     }
  440.  
  441.     return TRUE;
  442. }
  443.  
  444.  
  445.  
  446. void UI_ColorMap::operator= (const UI_ColorMap &cmap)
  447. {
  448.     Clear ();
  449.     for (ulong i = 0; i < _numcolors; ++i) {
  450.         UI_Color *c = &(cmap [(ulong &) i]);
  451.         Add (*c);
  452.         delete c;    
  453.     }
  454. }
  455.