From d577d991b97ae2b5ee1af23641bcffc3f83af5b2 Mon Sep 17 00:00:00 2001
From: Pixel <pixel@nobis-crew.org>
Date: Wed, 4 Nov 2009 11:56:41 -0800
Subject: Initial import. Contains the im, cd and iup librairies, and a
 "working" Makefile for them under linux.

---
 iup/srccontrols/color/iup_colorbrowser.c    |  849 ++++++++++++++++++++
 iup/srccontrols/color/iup_colorbrowserdlg.c | 1120 +++++++++++++++++++++++++++
 iup/srccontrols/color/iup_colorhsi.c        |  358 +++++++++
 iup/srccontrols/color/iup_colorhsi.h        |   44 ++
 4 files changed, 2371 insertions(+)
 create mode 100755 iup/srccontrols/color/iup_colorbrowser.c
 create mode 100755 iup/srccontrols/color/iup_colorbrowserdlg.c
 create mode 100755 iup/srccontrols/color/iup_colorhsi.c
 create mode 100755 iup/srccontrols/color/iup_colorhsi.h

(limited to 'iup/srccontrols/color')

diff --git a/iup/srccontrols/color/iup_colorbrowser.c b/iup/srccontrols/color/iup_colorbrowser.c
new file mode 100755
index 0000000..82b4a88
--- /dev/null
+++ b/iup/srccontrols/color/iup_colorbrowser.c
@@ -0,0 +1,849 @@
+/** \file
+* \brief ColorBrowser Control.
+*
+* See Copyright Notice in "iup.h"
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#include "iup.h"
+#include "iupcbs.h"
+#include "iupkey.h"
+
+#include <cd.h>
+#include <cdiup.h>
+#include <cdirgb.h>
+
+#include "iup_object.h"
+#include "iup_attrib.h"
+#include "iup_str.h"
+#include "iup_drv.h"
+#include "iup_stdcontrols.h"
+#include "iup_controls.h"
+#include "iup_cdutil.h"
+
+#include "iup_colorhsi.h"
+
+
+#ifndef min
+#define min(a, b) ( (a < b) ? (a) : (b) )
+#endif
+
+#define ICB_DEG2RAD  0.01745329252f  /* degrees to radians (rad = ICB_DEG2RAD * deg) */
+#define ICB_DEFAULTSIZE   181  /* default size */
+#define ICB_SPACE  4           /* size of the spacing */
+#define ICB_HUEWIDTH  18       /* width of the hue ring */
+#define ICB_MARKSIZE  6        /* size of the cursor mark */
+enum {ICB_INSIDE_NONE, ICB_INSIDE_HUE, ICB_INSIDE_SI};
+
+
+struct _IcontrolData
+{
+  iupCanvas canvas;  /* from IupCanvas (must reserve it) */
+
+  /* mouse interaction state */ 
+  int h_down,
+      si_down;
+
+  /* cursor positioning */
+  int h_x, h_y,
+      si_x, si_y;
+
+  /* HSI-XY coordinate convertion */
+  int xc, yc,  /* center */
+      R,       /* maximum radius available inside the size of the control */
+      Ix,      /* x coordinate where S is 0 */
+      Iy1,     /* y coordinate where I is 0 */
+      Iy2,     /* y coordinate where I is 1 */
+      SxMax;   /* x coordinate where S is 1 and I = 0.5 */
+
+  /* visual appearance control */
+  int w, h;
+  int has_focus; 
+  long bgcolor;
+
+  /* attributes */
+  float hue,          /* 0<=H<=359 */
+        saturation,   /* 0<=S<=1 */
+        intensity;    /* 0<=I<=1 */
+  unsigned char red, green, blue;  /* 0<=x<=255 */
+
+  cdCanvas *cddbuffer;
+  cdCanvas *cdcanvas;
+};
+
+
+static float iColorBrowserSXmax(Ihandle* ih, int y)
+{
+  if (y == ih->data->yc)
+    return (float)(ih->data->SxMax - ih->data->Ix);
+  else if (y < ih->data->yc)
+  {
+    float D2 = (ih->data->Iy2 - ih->data->Iy1)/2.0f;
+    return  ((float)(ih->data->SxMax - ih->data->Ix)*(y-ih->data->yc + D2))/D2;
+  }
+  else
+  {
+    float D2 = (ih->data->Iy2 - ih->data->Iy1)/2.0f;
+    return -((float)(ih->data->SxMax - ih->data->Ix)*(y-ih->data->yc - D2))/D2;
+  }
+}
+
+static float iColorBrowserCalcIntensity(Ihandle* ih, int y)
+{
+  return (float)(y - ih->data->Iy1)/(float)(ih->data->Iy2 - ih->data->Iy1);
+}
+
+static float iColorBrowserCalcSaturation(Ihandle* ih, int x, float sx_max)
+{
+  if (sx_max == 0)
+    return 0;
+  else
+    return (float)(x - ih->data->Ix)/sx_max;
+}
+
+/* Rotate points of 60 degrees */
+static void iColorBrowserRotatePoints(float *x1, float *y1, float *x2, float *y2, int xc, int yc)
+{
+  float xt, yt;
+  float nxt, nyt;
+  static const float s60 = 0.8660254f;
+  static const float c60 = 0.5f;
+
+  xt = *x1 - xc; 
+  yt = *y1 - yc;
+  nxt = xt * c60 - yt * s60;
+  nyt = xt * s60 + yt * c60;
+  *x1 = nxt + xc; 
+  *y1 = nyt + yc;
+
+  xt = *x2 - xc; 
+  yt = *y2 - yc;
+  nxt = xt * c60 - yt * s60;
+  nyt = xt * s60 + yt * c60;
+  *x2 = nxt + xc;
+  *y2 = nyt + yc;
+}
+
+static void iColorBrowserRenderImageHue(Ihandle* ih)
+{
+  int x, y, active = 1;
+  unsigned char *red, *green, *blue;
+  unsigned char bg_red, bg_green, bg_blue;
+  if (!ih->data->cddbuffer)
+    return;
+
+  cdCanvasBackground(ih->data->cddbuffer, ih->data->bgcolor);
+  cdCanvasClear(ih->data->cddbuffer);
+
+  if (!iupdrvIsActive(ih))
+    active = 0;
+
+  if (ih->data->has_focus)
+    cdDrawFocusRect(ih->data->cddbuffer, 0, 0, ih->data->w-1, ih->data->h-1);
+
+  red = cdRedImage(ih->data->cddbuffer);
+  green = cdGreenImage(ih->data->cddbuffer);
+  blue = cdBlueImage(ih->data->cddbuffer);
+
+  cdDecodeColor(ih->data->bgcolor, &bg_red, &bg_green, &bg_blue);
+
+  for (y = 0; y < ih->data->h; y++)
+  {
+    float sx_max = iColorBrowserSXmax(ih, y);
+
+    for (x = 0; x < ih->data->w; x++)
+    {
+      int xl, yl;
+      float radius, diff1, diff2;
+
+      if (y > ih->data->Iy1 && 
+          y < ih->data->Iy2 &&
+          x > ih->data->Ix  &&
+          x < ih->data->Ix+(int)sx_max)
+        continue;
+
+      xl = x - ih->data->xc;
+      yl = y - ih->data->yc;
+      radius = sqrtf(xl*xl + yl*yl);
+
+      diff1 = radius - (ih->data->R-ICB_SPACE-ICB_HUEWIDTH);
+      diff2 = (ih->data->R-ICB_SPACE) - radius;
+
+      if (diff1>0 && diff2>0)
+      {
+        float h, s, i;
+        int offset = y*ih->data->w + x;
+        unsigned char* r = red + offset;
+        unsigned char* g = green + offset;
+        unsigned char* b = blue + offset;
+
+        h = atan2f(yl, xl);
+        h = (float)(h * CD_RAD2DEG);
+        s = 1.0f;   /* maximum saturation */
+        i = 0.5f;   /* choose I where S is maximum */
+
+        iupColorHSI2RGB(h, s, i, r, g, b);
+
+        if (diff1<1 || diff2<1)  /* anti-aliasing */
+        {
+          float diff = (float)(diff1<1? diff1: diff2);
+          *r = (unsigned char)((*r)*diff + bg_red*(1.0f-diff));
+          *g = (unsigned char)((*g)*diff + bg_green*(1.0f-diff));
+          *b = (unsigned char)((*b)*diff + bg_blue*(1.0f-diff));
+        }
+
+        if (!active)
+        {
+          *r = cdIupLIGTHER(*r);
+          *g = cdIupLIGTHER(*g);
+          *b = cdIupLIGTHER(*b);
+        }
+      }
+    }
+  }
+
+  if (active)
+  {
+    float x1, x2, y1, y2;
+    unsigned char shade_lr, shade_lg, shade_lb,
+                  shade_dr, shade_dg, shade_db;
+    shade_dr = (unsigned char)((2 * bg_red) / 3);
+    shade_dg = (unsigned char)((2 * bg_green) / 3);
+    shade_db = (unsigned char)((2 * bg_blue) / 3);
+    shade_lr = (unsigned char)((255 + bg_red) / 2);
+    shade_lg = (unsigned char)((255 + bg_green) / 2);
+    shade_lb = (unsigned char)((255 + bg_blue) / 2);
+    cdCanvasForeground(ih->data->cddbuffer, cdEncodeColor(shade_dr, shade_dg, shade_db));
+    x1 = (float)(ih->data->xc-ih->data->R+ICB_SPACE); y1 = (float)ih->data->yc; x2 = (float)(x1+ICB_HUEWIDTH/2); y2 = (float)ih->data->yc;
+    cdCanvasLine(ih->data->cddbuffer, (int) x1, (int) y1, (int) x2, (int) y2);
+    iColorBrowserRotatePoints(&x1, &y1, &x2, &y2, ih->data->xc, ih->data->yc);
+    cdCanvasForeground(ih->data->cddbuffer, cdEncodeColor(shade_lr, shade_lg, shade_lb));
+    cdCanvasLine(ih->data->cddbuffer, (int) x1, (int) y1, (int) x2, (int) y2);
+    iColorBrowserRotatePoints(&x1, &y1, &x2, &y2, ih->data->xc, ih->data->yc);
+    cdCanvasForeground(ih->data->cddbuffer, cdEncodeColor(shade_dr, shade_dg, shade_db));
+    cdCanvasLine(ih->data->cddbuffer, (int) x1, (int) y1, (int) x2, (int) y2);
+    iColorBrowserRotatePoints(&x1, &y1, &x2, &y2, ih->data->xc, ih->data->yc);
+    cdCanvasForeground(ih->data->cddbuffer, cdEncodeColor(shade_lr, shade_lg, shade_lb));
+    cdCanvasLine(ih->data->cddbuffer, (int) x1, (int) y1, (int) x2, (int) y2);
+    iColorBrowserRotatePoints(&x1, &y1, &x2, &y2, ih->data->xc, ih->data->yc);
+    cdCanvasForeground(ih->data->cddbuffer, cdEncodeColor(shade_dr, shade_dg, shade_db));
+    cdCanvasLine(ih->data->cddbuffer, (int) x1, (int) y1, (int) x2, (int) y2);
+    iColorBrowserRotatePoints(&x1, &y1, &x2, &y2, ih->data->xc, ih->data->yc);
+    cdCanvasLine(ih->data->cddbuffer, (int) x1, (int) y1, (int) x2, (int) y2);
+  }
+}
+
+static void iColorBrowserRenderImageSI(Ihandle* ih)
+{
+  int x, y, active = 1;
+  unsigned char *red, *green, *blue;
+  unsigned char bg_red, bg_green, bg_blue;
+  float angle, cos_angle, sin_angle;
+  if (!ih->data->cddbuffer)
+    return;
+
+  if (!iupdrvIsActive(ih))
+    active = 0;
+
+  red = cdRedImage(ih->data->cddbuffer);
+  green = cdGreenImage(ih->data->cddbuffer);
+  blue = cdBlueImage(ih->data->cddbuffer);
+
+  cdDecodeColor(ih->data->bgcolor, &bg_red, &bg_green, &bg_blue);
+
+  angle = ih->data->hue * ICB_DEG2RAD;
+  cos_angle = cosf(angle);
+  sin_angle = sinf(angle);
+
+  for (y = 0; y < ih->data->h; y++)
+  {
+    float sx_max, i;
+
+    if (y < ih->data->Iy1)
+      continue;
+    else if (y > ih->data->Iy2)
+      continue;
+
+    sx_max = iColorBrowserSXmax(ih, y);
+    i = iColorBrowserCalcIntensity(ih, y);
+
+    for (x = 0; x < ih->data->w; x++)
+    {
+      if (x < ih->data->Ix)
+        continue;
+      else if (x > ih->data->Ix+(int)sx_max)
+        continue;
+
+      {
+        int offset = y*ih->data->w + x;
+        unsigned char* r = red + offset;
+        unsigned char* g = green + offset;
+        unsigned char* b = blue + offset;
+        float s, diff;
+
+        s = iColorBrowserCalcSaturation(ih, x, sx_max);
+
+        iupColorHSI2RGB(ih->data->hue, s, i, r, g, b);
+
+        diff = sx_max - (float)(x - ih->data->Ix);
+        if (diff<1.0f)  /* anti-aliasing */
+        {
+          *r = (unsigned char)((*r)*diff + bg_red*(1.0f-diff));
+          *g = (unsigned char)((*g)*diff + bg_green*(1.0f-diff));
+          *b = (unsigned char)((*b)*diff + bg_blue*(1.0f-diff));
+        }
+
+        if (!active)
+        {
+          *r = cdIupLIGTHER(*r);
+          *g = cdIupLIGTHER(*g);
+          *b = cdIupLIGTHER(*b);
+        }
+      }
+    }
+  }
+}
+
+static void iColorBrowserUpdateCursorSI(Ihandle* ih)
+{
+  int x;
+  int y = (int)(ih->data->intensity*(ih->data->Iy2 - ih->data->Iy1)) + ih->data->Iy1;
+  ih->data->si_y = iupROUND(y);
+  x = (int)(ih->data->saturation*iColorBrowserSXmax(ih, ih->data->si_y)) + ih->data->Ix;
+  ih->data->si_x = iupROUND(x);
+}
+
+static void iColorBrowserSetCursorSI(Ihandle* ih, int x, int y)
+{
+  float sx_max;
+
+  if (y < ih->data->Iy1)
+    ih->data->si_y = ih->data->Iy1;
+  else if (y > ih->data->Iy2)
+    ih->data->si_y = ih->data->Iy2;
+  else
+    ih->data->si_y = y;
+
+  sx_max = iColorBrowserSXmax(ih, ih->data->si_y);
+
+  if (x < ih->data->Ix)
+    ih->data->si_x = ih->data->Ix;
+  else if (x > ih->data->Ix+sx_max)
+    ih->data->si_x = ih->data->Ix+(int)sx_max;
+  else
+    ih->data->si_x = x;
+
+  ih->data->intensity = iColorBrowserCalcIntensity(ih, ih->data->si_y);
+  ih->data->saturation = iColorBrowserCalcSaturation(ih, ih->data->si_x, sx_max);
+
+  if (ih->data->saturation == -0.0f)
+    ih->data->saturation = 0;
+  if (ih->data->intensity == -0.0f)
+    ih->data->intensity = 0;
+}
+
+static void iColorBrowserUpdateCursorHue(Ihandle* ih)
+{
+  int rc = ih->data->R-ICB_SPACE-ICB_HUEWIDTH/2;
+  float angle = ih->data->hue * ICB_DEG2RAD;
+  float cos_angle = cosf(angle);
+  float sin_angle = sinf(angle);
+  float x = rc*cos_angle + ih->data->xc;
+  float y = rc*sin_angle + ih->data->yc;
+  ih->data->h_x = iupROUND(x);
+  ih->data->h_y = iupROUND(y);
+}
+
+static void iColorBrowserSetCursorHue(Ihandle* ih, int x, int y)
+{
+  int xl = x - ih->data->xc;
+  int yl = y - ih->data->yc;
+  ih->data->hue = (float)(atan2f(yl, xl) * CD_RAD2DEG);
+  ih->data->hue = fmodf(ih->data->hue, 360.0f);
+  if (ih->data->hue < 0.0f)
+    ih->data->hue += 360.0f;
+
+  iColorBrowserUpdateCursorHue(ih);
+}
+
+static int iColorBrowserCheckInside(Ihandle* ih, int x, int y)
+{
+  int xl = x - ih->data->xc;
+  int yl = y - ih->data->yc;
+  float radius = sqrtf(xl*xl + yl*yl);
+
+  if (radius < ih->data->R-ICB_SPACE-ICB_HUEWIDTH-ICB_SPACE)
+    return ICB_INSIDE_SI;
+
+  if (radius > ih->data->R-ICB_SPACE-ICB_HUEWIDTH &&
+      radius < ih->data->R-ICB_SPACE)
+    return ICB_INSIDE_HUE;
+
+  return ICB_INSIDE_NONE;
+}
+
+static void iColorBrowserHSI2RGB(Ihandle* ih)
+{
+  iupColorHSI2RGB(ih->data->hue, ih->data->saturation, ih->data->intensity, 
+                      &(ih->data->red), &(ih->data->green), &(ih->data->blue));
+}
+
+static void iColorBrowserRGB2HSI(Ihandle* ih)
+{
+  iupColorRGB2HSI(ih->data->red, ih->data->green, ih->data->blue,
+                      &(ih->data->hue), &(ih->data->saturation), &(ih->data->intensity));
+}
+
+static void iColorBrowserUpdateDisplay(Ihandle* ih)
+{
+  if (!ih->data->cddbuffer)
+    return;
+
+  cdCanvasFlush(ih->data->cddbuffer);  /* swap the RGB to the display canvas */
+
+  if (iupdrvIsActive(ih))
+  {
+    cdCanvasForeground(ih->data->cdcanvas, CD_GRAY);
+    cdCanvasArc(ih->data->cdcanvas, ih->data->h_x+1, ih->data->h_y, ICB_MARKSIZE, ICB_MARKSIZE, 0, 360);
+    cdCanvasArc(ih->data->cdcanvas, ih->data->si_x+1, ih->data->si_y, ICB_MARKSIZE, ICB_MARKSIZE, 0, 360);
+    cdCanvasForeground(ih->data->cdcanvas, CD_WHITE);
+    cdCanvasArc(ih->data->cdcanvas, ih->data->h_x, ih->data->h_y, ICB_MARKSIZE, ICB_MARKSIZE, 0, 360);
+    cdCanvasArc(ih->data->cdcanvas, ih->data->si_x, ih->data->si_y, ICB_MARKSIZE, ICB_MARKSIZE, 0, 360);
+  }
+  else
+  {
+    cdCanvasForeground(ih->data->cdcanvas, CD_DARK_GRAY);
+    cdCanvasSector(ih->data->cdcanvas, ih->data->h_x, ih->data->h_y, ICB_MARKSIZE+1, ICB_MARKSIZE+1, 0, 360);
+    cdCanvasSector(ih->data->cdcanvas, ih->data->si_x, ih->data->si_y, ICB_MARKSIZE+1, ICB_MARKSIZE+1, 0, 360);
+  }
+}
+
+static void iColorBrowserCallChangeCb(Ihandle* ih)
+{
+  IFnccc change_cb = (IFnccc) IupGetCallback(ih, "CHANGE_CB");
+  if (change_cb)
+    change_cb(ih, ih->data->red, ih->data->green, ih->data->blue);
+  
+  iupBaseCallValueChangedCb(ih);
+}
+  
+static void iColorBrowserCallDragCb(Ihandle* ih)
+{
+  IFnccc drag_cb = (IFnccc) IupGetCallback(ih, "DRAG_CB");
+  if (drag_cb)
+    drag_cb(ih, ih->data->red, ih->data->green, ih->data->blue);
+
+  iupBaseCallValueChangedCb(ih);
+}
+
+static int iColorBrowserHmouse(Ihandle* ih, int x, int y, int drag)
+{
+  iColorBrowserSetCursorHue(ih, x, y);
+  iColorBrowserHSI2RGB(ih);
+  /* must update the Si area */
+  iColorBrowserRenderImageSI(ih);
+  iColorBrowserUpdateDisplay(ih);
+
+  if (drag)
+    iColorBrowserCallDragCb(ih);
+  else
+    iColorBrowserCallChangeCb(ih);
+
+  return IUP_DEFAULT;
+}
+
+static int iColorBrowserSImouse(Ihandle* ih, int x, int y, int drag)
+{
+  iColorBrowserSetCursorSI(ih, x, y);
+  iColorBrowserHSI2RGB(ih);
+  iColorBrowserUpdateDisplay(ih);
+
+  if (drag)
+    iColorBrowserCallDragCb(ih);
+  else
+    iColorBrowserCallChangeCb(ih);
+
+  return IUP_DEFAULT;
+}
+
+
+/******************************************************************/
+
+
+static int iColorBrowserButton_CB(Ihandle* ih, int b, int press, int x, int y)
+{
+  if (b != IUP_BUTTON1)
+    return IUP_DEFAULT;
+
+  cdCanvasUpdateYAxis(ih->data->cdcanvas, &y);
+
+  if (press)
+  {
+    int inside = iColorBrowserCheckInside(ih, x, y);
+
+    if (!ih->data->h_down && inside==ICB_INSIDE_HUE)
+    {
+      iColorBrowserHmouse(ih, x, y, 1);
+      ih->data->h_down = 1;
+    } 
+
+    if (!ih->data->si_down && inside==ICB_INSIDE_SI)
+    {
+      iColorBrowserSImouse(ih, x, y, 1);
+      ih->data->si_down = 1;
+    } 
+  }
+  else
+  {
+    if (ih->data->h_down)
+    {
+      iColorBrowserHmouse(ih, x, y, 0);
+      ih->data->h_down = 0;
+    }
+
+    if (ih->data->si_down)
+    {
+      iColorBrowserSImouse(ih, x, y, 0);
+      ih->data->si_down = 0;
+    }
+  }
+
+  return IUP_DEFAULT;
+}
+
+/* Callback for the mouse motion in the canvas */
+static int iColorBrowserMotion_CB(Ihandle* ih, int x, int y, char *status)
+{
+  if (!iup_isbutton1(status))
+  {
+    ih->data->h_down = 0;
+    ih->data->si_down = 0;
+    return IUP_DEFAULT;
+  }
+
+  if (ih->data->h_down)
+  {
+    cdCanvasUpdateYAxis(ih->data->cdcanvas, &y);
+    iColorBrowserHmouse(ih, x, y, 1);
+  }
+  else if (ih->data->si_down)
+  {
+    cdCanvasUpdateYAxis(ih->data->cdcanvas, &y);
+    iColorBrowserSImouse(ih, x, y, 1);
+  }
+
+  return IUP_DEFAULT;
+}
+
+static int iColorBrowserFocus_CB(Ihandle* ih, int focus)
+{
+  ih->data->has_focus = focus;
+  iColorBrowserRenderImageHue(ih);
+  iColorBrowserRenderImageSI(ih);
+  iColorBrowserUpdateDisplay(ih);
+  return IUP_DEFAULT;
+}
+
+static void iColorBrowserUpdateSize(Ihandle* ih)
+{
+  int T, D;
+
+  /* update canvas size */
+  cdCanvasActivate(ih->data->cddbuffer);
+  cdCanvasGetSize(ih->data->cddbuffer, &ih->data->w, &ih->data->h, NULL, NULL);
+
+  ih->data->R = min(ih->data->w, ih->data->h)/2;
+  ih->data->xc = ih->data->w/2;
+  ih->data->yc = ih->data->h/2;
+  T = ih->data->R-ICB_SPACE-ICB_HUEWIDTH-ICB_SPACE;
+  ih->data->Ix = ih->data->xc - T/2; /* cos(60)=0.5 */
+  D = (int)(2*T*0.866);              /* sin(60)=0.866 */
+  ih->data->Iy1 = ih->data->yc - D/2;
+  ih->data->Iy2 = ih->data->Iy1 + D;
+  ih->data->SxMax = ih->data->xc + T;
+}
+
+static int iColorBrowserResize_CB(Ihandle* ih)
+{
+  if (!ih->data->cddbuffer)
+  {
+    /* update canvas size */
+    cdCanvasActivate(ih->data->cdcanvas);
+
+    /* this can fail if canvas size is zero */
+    ih->data->cddbuffer = cdCreateCanvas(CD_DBUFFERRGB, ih->data->cdcanvas);
+  }
+
+  if (!ih->data->cddbuffer)
+    return IUP_DEFAULT;
+
+  /* update size */
+  iColorBrowserUpdateSize(ih);
+
+  iColorBrowserUpdateCursorHue(ih);
+  iColorBrowserUpdateCursorSI(ih);
+
+  /* update render */
+  iColorBrowserRenderImageHue(ih);
+  iColorBrowserRenderImageSI(ih);
+
+  return IUP_DEFAULT;
+}
+
+static int iColorBrowserRedraw_CB(Ihandle* ih)
+{
+  iColorBrowserUpdateDisplay(ih);
+  return IUP_DEFAULT;
+}
+
+static int iColorBrowserWheel_CB(Ihandle* ih, float delta)
+{
+  ih->data->hue += delta;
+
+  iColorBrowserUpdateCursorHue(ih);
+  iColorBrowserHSI2RGB(ih);
+  /* must update the Si area */
+  iColorBrowserRenderImageSI(ih);
+  iColorBrowserUpdateDisplay(ih);
+  iColorBrowserCallChangeCb(ih);
+
+  return IUP_DEFAULT;
+}
+
+static int iColorBrowserKeypress_CB(Ihandle* ih, int c, int press)
+{
+  int x, y, changing_hue = 0;
+
+  if (!press)
+    return IUP_DEFAULT;
+
+  x = ih->data->si_x; 
+  y = ih->data->si_y; 
+
+  switch (c)
+  {
+    case K_UP:
+      y++; 
+      break;
+    case K_DOWN:
+      y--;
+      break;
+    case K_RIGHT:
+      x++;
+      break;
+    case K_LEFT:
+      x--;
+      break;
+    case K_PGUP:
+      ih->data->hue += 1.0f; 
+      changing_hue = 1; 
+      break;
+    case K_PGDN:
+      ih->data->hue -= 1.0f; 
+      changing_hue = 1; break;
+    case K_HOME:
+      ih->data->hue = 0.0f; 
+      changing_hue = 1; 
+      break;
+    case K_END:
+      ih->data->hue = 180.0f; 
+      changing_hue = 1; 
+      break;
+    default:
+      return IUP_DEFAULT;
+  }
+
+  if (changing_hue)
+  {
+    iColorBrowserUpdateCursorHue(ih);
+    /* must update the Si area */
+    iColorBrowserRenderImageSI(ih);
+  }
+  else
+    iColorBrowserSetCursorSI(ih, x, y);
+
+  iColorBrowserHSI2RGB(ih);
+
+  iColorBrowserUpdateDisplay(ih);
+  iColorBrowserCallChangeCb(ih);
+
+  return IUP_IGNORE;  /* to avoid arrow keys being processed by the system */
+}
+
+
+/*********************************************************************************/
+
+
+static char* iColorBrowserGetHSIAttrib(Ihandle* ih)
+{
+  char* buffer = iupStrGetMemory(100);
+  sprintf(buffer, "%f %f %f", (double)ih->data->hue, (double)ih->data->saturation, (double)ih->data->intensity);
+  return buffer;
+}
+
+static int iColorBrowserSetHSIAttrib(Ihandle* ih, const char* value)
+{
+  float old_hue = ih->data->hue,
+        old_saturation = ih->data->saturation,
+        old_intensity = ih->data->intensity;
+
+  if (!iupStrToHSI(value, &ih->data->hue, &ih->data->saturation, &ih->data->intensity))
+    return 0;
+  
+  if (ih->data->cddbuffer)
+  {
+    if (old_hue != ih->data->hue) 
+      iColorBrowserUpdateCursorHue(ih);
+    if (old_saturation != ih->data->saturation || old_intensity != ih->data->intensity) 
+      iColorBrowserUpdateCursorSI(ih);
+    iColorBrowserHSI2RGB(ih);
+    iColorBrowserRenderImageSI(ih);
+    iColorBrowserUpdateDisplay(ih);
+  }
+
+  return 0;
+}
+
+static char* iColorBrowserGetRGBAttrib(Ihandle* ih)
+{
+  char* buffer = iupStrGetMemory(20);
+  sprintf(buffer, "%d %d %d", (int) ih->data->red, (int) ih->data->green, (int) ih->data->blue);
+  return buffer;
+}
+
+static int iColorBrowserSetRGBAttrib(Ihandle* ih, const char* value)
+{
+  unsigned char r, g, b;
+  if (!iupStrToRGB(value, &r, &g, &b))
+    return 0;
+  
+  ih->data->red = r;
+  ih->data->green = g;
+  ih->data->blue = b;
+  iColorBrowserRGB2HSI(ih);
+
+  if (ih->data->cddbuffer)
+  {
+    iColorBrowserUpdateCursorHue(ih);
+    iColorBrowserUpdateCursorSI(ih);
+    iColorBrowserRenderImageSI(ih);
+    iColorBrowserUpdateDisplay(ih);
+  }
+
+  return 0;
+}
+
+static int iColorBrowserSetBgColorAttrib(Ihandle* ih, const char* value)
+{
+  if (!value)
+    value = iupControlBaseGetParentBgColor(ih);
+  ih->data->bgcolor = cdIupConvertColor(value);
+
+  if (ih->data->cddbuffer)
+  {
+    iColorBrowserRenderImageHue(ih);
+    iColorBrowserRenderImageSI(ih);
+    iColorBrowserUpdateDisplay(ih);
+  }
+  return 1;
+}
+
+static int iColorBrowserSetActiveAttrib(Ihandle* ih, const char* value)
+{
+  iupBaseSetActiveAttrib(ih, value);
+  iColorBrowserUpdateDisplay(ih);
+  return 0;   /* do not store value in hash table */
+}
+
+
+/****************************************************************************/
+
+
+static int iColorBrowserMapMethod(Ihandle* ih)
+{
+  ih->data->cdcanvas = cdCreateCanvas(CD_IUP, ih);
+  if (!ih->data->cdcanvas)
+    return IUP_ERROR;
+
+  /* this can fail if canvas size is zero */
+  ih->data->cddbuffer = cdCreateCanvas(CD_DBUFFERRGB, ih->data->cdcanvas);
+
+  if (ih->data->cddbuffer)
+    iColorBrowserUpdateSize(ih);
+
+  return IUP_NOERROR;
+}
+
+static void iColorBrowserUnMapMethod(Ihandle* ih)
+{
+  if (ih->data->cddbuffer)
+    cdKillCanvas(ih->data->cddbuffer);
+
+  if (ih->data->cdcanvas)
+    cdKillCanvas(ih->data->cdcanvas);
+}
+
+static int iColorBrowserCreateMethod(Ihandle* ih, void **params)
+{
+  (void)params;
+
+  /* free the data allocated by IupCanvas */
+  if (ih->data) free(ih->data);
+  ih->data = iupALLOCCTRLDATA();
+
+  /* change the IupCanvas default values */
+  IupSetfAttribute(ih, "RASTERSIZE", "%dx%d", ICB_DEFAULTSIZE, ICB_DEFAULTSIZE);
+  iupAttribSetStr(ih, "BORDER", "NO");
+  ih->expand = IUP_EXPAND_NONE;
+
+  /* IupCanvas callbacks */
+  IupSetCallback(ih, "ACTION",      (Icallback)iColorBrowserRedraw_CB);
+  IupSetCallback(ih, "RESIZE_CB",   (Icallback)iColorBrowserResize_CB);
+  IupSetCallback(ih, "BUTTON_CB",   (Icallback)iColorBrowserButton_CB);
+  IupSetCallback(ih, "MOTION_CB",   (Icallback)iColorBrowserMotion_CB);
+  IupSetCallback(ih, "FOCUS_CB",    (Icallback)iColorBrowserFocus_CB);
+  IupSetCallback(ih, "KEYPRESS_CB", (Icallback)iColorBrowserKeypress_CB);
+  IupSetCallback(ih, "WHEEL_CB",    (Icallback)iColorBrowserWheel_CB);
+
+  return IUP_NOERROR;
+}
+
+Iclass* iupColorBrowserGetClass(void)
+{
+  Iclass* ic = iupClassNew(iupCanvasGetClass());
+
+  ic->name = "colorbrowser";
+  ic->format = NULL; /* no parameters */
+  ic->nativetype = IUP_TYPECANVAS;
+  ic->childtype = IUP_CHILDNONE;
+  ic->is_interactive = 1;
+
+  /* Class functions */
+  ic->Create  = iColorBrowserCreateMethod;
+  ic->Map     = iColorBrowserMapMethod;
+  ic->UnMap   = iColorBrowserUnMapMethod;
+
+  /* IupColorBrowser Callbacks */
+  iupClassRegisterCallback(ic, "DRAG_CB",   "ccc");
+  iupClassRegisterCallback(ic, "CHANGE_CB", "ccc");
+  iupClassRegisterCallback(ic, "VALUECHANGED_CB", "");
+
+  /* IupColorBrowser only */
+  iupClassRegisterAttribute(ic, "RGB", iColorBrowserGetRGBAttrib, iColorBrowserSetRGBAttrib, "255 0 0", NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT);    /* force new default value */
+  iupClassRegisterAttribute(ic, "HSI", iColorBrowserGetHSIAttrib, iColorBrowserSetHSIAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT);
+
+  /* Overwrite IupCanvas Attributes */
+  iupClassRegisterAttribute(ic, "ACTIVE", iupBaseGetActiveAttrib, iColorBrowserSetActiveAttrib, IUPAF_SAMEASSYSTEM, "YES", IUPAF_DEFAULT);
+  iupClassRegisterAttribute(ic, "BGCOLOR", iupControlBaseGetBgColorAttrib, iColorBrowserSetBgColorAttrib, NULL, "255 255 255", IUPAF_NO_INHERIT);    /* overwrite canvas implementation, set a system default to force a new default */
+
+  return ic;
+}
+
+Ihandle *IupColorBrowser(void)
+{
+  return IupCreate("colorbrowser");
+}
diff --git a/iup/srccontrols/color/iup_colorbrowserdlg.c b/iup/srccontrols/color/iup_colorbrowserdlg.c
new file mode 100755
index 0000000..65e4d37
--- /dev/null
+++ b/iup/srccontrols/color/iup_colorbrowserdlg.c
@@ -0,0 +1,1120 @@
+/** \file
+ * \brief IupColorDlg pre-defined dialog control
+ *
+ * See Copyright Notice in "iup.h"
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "iup.h"
+#include "iupcbs.h"
+#include "iupkey.h"
+#include "iupcontrols.h"
+
+#include <cd.h>
+#include <cdiup.h>
+#include <cddbuf.h>
+#include <cdirgb.h>
+
+#include "iup_object.h"
+#include "iup_attrib.h"
+#include "iup_str.h"
+#include "iup_strmessage.h"
+#include "iup_drv.h"
+#include "iup_stdcontrols.h"
+#include "iup_controls.h"
+#include "iup_cdutil.h"
+#include "iup_register.h"
+#include "iup_register.h"
+#include "iup_image.h"
+#include "iup_colorhsi.h"
+#include "iup_childtree.h"
+
+       
+const char* default_colortable_cells[20] = 
+{
+  "0 0 0", "64 64 64", "128 128 128", "144 144 144", "0 128 128", "128 0 128", "128 128 0", "128 0 0", "0 128 0", "0 0 128",
+  "255 255 255", "240 240 240", "224 224 224", "192 192 192", "0 255 255", "255 0 255", "255 255 0", "255 0 0", "0 255 0", "0 0 255"
+};
+
+typedef struct _IcolorDlgData
+{
+  int status;
+
+  long previous_color, color;
+
+  float hue, saturation, intensity;
+  unsigned char red, green, blue, alpha;
+
+  Ihandle *red_txt, *green_txt, *blue_txt, *alpha_txt;
+  Ihandle *hue_txt, *intensity_txt, *saturation_txt;
+  Ihandle *color_browser, *color_cnv, *colorhex_txt;
+  Ihandle *colortable_cbar, *alpha_val;
+  Ihandle *help_bt;
+
+  cdCanvas* color_cdcanvas, *color_cddbuffer;
+} IcolorDlgData;
+
+
+static void iColorBrowserDlgColorCnvRepaint(IcolorDlgData* colordlg_data)
+{
+  int x, y, w, h, width, height, box_size = 10;
+
+  if (!colordlg_data->color_cddbuffer)
+    return;
+
+  cdCanvasGetSize(colordlg_data->color_cddbuffer, &width, &height, NULL, NULL);
+
+  cdCanvasBackground(colordlg_data->color_cddbuffer, CD_WHITE);
+  cdCanvasClear(colordlg_data->color_cddbuffer);
+
+  w = (width+box_size-1)/box_size;
+  h = (height+box_size-1)/box_size;
+
+  cdCanvasForeground(colordlg_data->color_cddbuffer, CD_GRAY);
+
+  for (y = 0; y < h; y++)
+  {                              
+    for (x = 0; x < w; x++)
+    {
+      if (((x%2) && (y%2)) || (((x+1)%2) && ((y+1)%2)))
+      {
+        int xmin, xmax, ymin, ymax;
+
+        xmin = x*box_size;
+        xmax = xmin+box_size;
+        ymin = y*box_size;
+        ymax = ymin+box_size;
+
+        cdCanvasBox(colordlg_data->color_cddbuffer, xmin, xmax, ymin, ymax);
+      }
+    }
+  }
+
+  cdCanvasForeground(colordlg_data->color_cddbuffer, colordlg_data->previous_color);
+  cdCanvasBox(colordlg_data->color_cddbuffer, 0, width/2, 0, height);
+
+  cdCanvasForeground(colordlg_data->color_cddbuffer, colordlg_data->color);
+  cdCanvasBox(colordlg_data->color_cddbuffer, width/2+1, width, 0, height);
+
+  cdCanvasFlush(colordlg_data->color_cddbuffer);
+}
+
+static void iColorBrowserDlgHSI2RGB(IcolorDlgData* colordlg_data)
+{
+  iupColorHSI2RGB(colordlg_data->hue, colordlg_data->saturation, colordlg_data->intensity,
+                  &colordlg_data->red, &colordlg_data->green, &colordlg_data->blue);
+}
+
+static void iColorBrowserDlgRGB2HSI(IcolorDlgData* colordlg_data)
+{
+  iupColorRGB2HSI(colordlg_data->red, colordlg_data->green, colordlg_data->blue,
+                  &(colordlg_data->hue), &(colordlg_data->saturation), &(colordlg_data->intensity));
+}
+
+static void iColorBrowserDlgHex_TXT_Update(IcolorDlgData* colordlg_data)
+{
+  IupSetfAttribute(colordlg_data->colorhex_txt, "VALUE", "#%02X%02X%02X", (int)colordlg_data->red, (int)colordlg_data->green, (int)colordlg_data->blue);
+}
+
+static int iupStrHexToRGB(const char *str, unsigned char *r, unsigned char *g, unsigned char *b)
+{
+  unsigned int ri = 0, gi = 0, bi = 0;
+  if (!str) return 0;
+  if (sscanf(str, "#%2X%2X%2X", &ri, &gi, &bi) != 3) return 0;
+  if (ri > 255 || gi > 255 || bi > 255) return 0;
+  *r = (unsigned char)ri;
+  *g = (unsigned char)gi;
+  *b = (unsigned char)bi;
+  return 1;
+}
+
+/*************************************************\
+* Updates text fields with the current HSI values *
+\*************************************************/
+static void iColorBrowserDlgHSI_TXT_Update(IcolorDlgData* colordlg_data)
+{
+  IupSetfAttribute(colordlg_data->hue_txt, "VALUE", "%d", iupROUND(colordlg_data->hue));
+  IupSetfAttribute(colordlg_data->saturation_txt, "VALUE", "%d", iupROUND(colordlg_data->saturation * 100));
+  IupSetfAttribute(colordlg_data->intensity_txt, "VALUE", "%d", iupROUND(colordlg_data->intensity * 100));
+}
+
+/*************************************************\
+* Updates text fields with the current RGB values *
+\*************************************************/
+static void iColorBrowserDlgRGB_TXT_Update(IcolorDlgData* colordlg_data)
+{
+  IupSetfAttribute(colordlg_data->red_txt, "VALUE", "%d", (int) colordlg_data->red);
+  IupSetfAttribute(colordlg_data->green_txt, "VALUE", "%d", (int) colordlg_data->green);
+  IupSetfAttribute(colordlg_data->blue_txt, "VALUE", "%d", (int) colordlg_data->blue);
+}
+
+static void iColorBrowserDlgBrowserRGB_Update(IcolorDlgData* colordlg_data)
+{
+  IupSetfAttribute(colordlg_data->color_browser, "RGB", "%d %d %d", colordlg_data->red, colordlg_data->green, colordlg_data->blue);
+}
+
+static void iColorBrowserDlgBrowserHSI_Update(IcolorDlgData* colordlg_data)
+{
+  IupSetfAttribute(colordlg_data->color_browser, "HSI", "%f %f %f", (double)colordlg_data->hue, (double)colordlg_data->saturation, (double)colordlg_data->intensity);
+}
+
+/*****************************************\
+* Sets the RGB color in the Color Canvas *
+\*****************************************/
+static void iColorBrowserDlgColor_Update(IcolorDlgData* colordlg_data)
+{
+  colordlg_data->color = cdEncodeColor(colordlg_data->red, colordlg_data->green, colordlg_data->blue);
+  colordlg_data->color = cdEncodeAlpha(colordlg_data->color, colordlg_data->alpha);
+  iColorBrowserDlgColorCnvRepaint(colordlg_data);
+}
+
+static void iColorBrowserDlgHSIChanged(IcolorDlgData* colordlg_data) 
+{
+  iColorBrowserDlgHSI2RGB(colordlg_data);
+  iColorBrowserDlgBrowserHSI_Update(colordlg_data);
+  iColorBrowserDlgHex_TXT_Update(colordlg_data);
+  iColorBrowserDlgRGB_TXT_Update(colordlg_data);
+  iColorBrowserDlgColor_Update(colordlg_data);
+}
+
+static void iColorBrowserDlgRGBChanged(IcolorDlgData* colordlg_data) 
+{
+  iColorBrowserDlgRGB2HSI(colordlg_data);
+  iColorBrowserDlgBrowserRGB_Update(colordlg_data);
+  iColorBrowserDlgHex_TXT_Update(colordlg_data);
+  iColorBrowserDlgHSI_TXT_Update(colordlg_data);
+  iColorBrowserDlgColor_Update(colordlg_data);
+}
+
+/***********************************************\
+* Initializes the default values to the element *
+\***********************************************/
+static void iColorBrowserDlgInit_Defaults(IcolorDlgData* colordlg_data)
+{
+  char* str = iupStrGetMemory(100);
+  Ihandle* box;
+  int i;
+
+  IupSetAttribute(colordlg_data->color_browser, "RGB", "0 0 0");
+
+  IupSetAttribute(colordlg_data->red_txt,   "VALUE", "0");
+  IupSetAttribute(colordlg_data->green_txt, "VALUE", "0");
+  IupSetAttribute(colordlg_data->blue_txt,  "VALUE", "0");
+
+  IupSetAttribute(colordlg_data->hue_txt,        "VALUE", "0");
+  IupSetAttribute(colordlg_data->saturation_txt, "VALUE", "0");
+  IupSetAttribute(colordlg_data->intensity_txt,  "VALUE", "0");
+  
+  IupSetAttribute(colordlg_data->colorhex_txt, "VALUE", "#000000");
+
+  colordlg_data->alpha = 255;
+  IupSetAttribute(colordlg_data->alpha_val, "VALUE", "255");
+  IupSetAttribute(colordlg_data->alpha_txt, "VALUE", "255");
+
+  box = IupGetParent(colordlg_data->alpha_val);
+  IupSetAttribute(box, "FLOATING", "YES");
+  IupSetAttribute(box, "VISIBLE", "NO");
+
+  box = IupGetParent(colordlg_data->colortable_cbar);
+  IupSetAttribute(box, "FLOATING", "YES");
+  IupSetAttribute(box, "VISIBLE", "NO");
+
+  box = IupGetParent(colordlg_data->colorhex_txt);
+  IupSetAttribute(box, "FLOATING", "YES");
+  IupSetAttribute(box, "VISIBLE", "NO");
+
+  for(i = 0; i < 20; i++)
+  {
+    sprintf(str, "CELL%d", i);
+    IupSetAttribute(colordlg_data->colortable_cbar, str, default_colortable_cells[i]);
+  }
+}
+
+
+/**************************************************************************************************************/
+/*                                 Internal Callbacks                                                         */
+/**************************************************************************************************************/
+
+
+static int iColorBrowserDlgButtonOK_CB(Ihandle* ih)
+{
+  IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA");
+  colordlg_data->status = 1;
+  return IUP_CLOSE;
+}
+
+static int iColorBrowserDlgButtonCancel_CB(Ihandle* ih)
+{
+  IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA");
+  colordlg_data->status = 0;
+  return IUP_CLOSE;
+}
+
+static int iColorBrowserDlgButtonHelp_CB(Ihandle* ih)
+{
+  Icallback cb = IupGetCallback(IupGetDialog(ih), "HELP_CB");
+  if (cb && cb(ih) == IUP_CLOSE)
+  {
+    IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA");
+    colordlg_data->status = 0;
+    return IUP_CLOSE;
+  }
+  return IUP_DEFAULT;
+}
+
+static int iColorBrowserDlgColorCnvRedraw_CB(Ihandle* ih)
+{
+  IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA");
+
+  if (!colordlg_data->color_cddbuffer)
+    return IUP_DEFAULT;
+
+  cdCanvasActivate(colordlg_data->color_cddbuffer);
+
+  iColorBrowserDlgColorCnvRepaint(colordlg_data);
+
+  return IUP_DEFAULT;
+}
+
+static int iColorBrowserDlgRedAction_CB(Ihandle* ih, int c, char *value) 
+{
+  IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA");
+  int vi;
+
+  if (iupStrToInt(value, &vi))
+  {
+    colordlg_data->red = (unsigned char)vi;
+    iColorBrowserDlgRGBChanged(colordlg_data);
+  }
+
+  (void)c;
+  return IUP_DEFAULT;
+}
+
+static int iColorBrowserDlgRedSpin_CB(Ihandle* ih, int vi) 
+{
+  IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA");
+
+  colordlg_data->red = (unsigned char)vi;
+  iColorBrowserDlgRGBChanged(colordlg_data);
+
+  return IUP_DEFAULT;
+}
+
+static int iColorBrowserDlgGreenAction_CB(Ihandle* ih, int c, char *value) 
+{
+  IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA");
+  int vi;
+
+  if (iupStrToInt(value, &vi))
+  {
+    colordlg_data->green = (unsigned char)vi;
+    iColorBrowserDlgRGBChanged(colordlg_data);
+  }
+
+  (void)c;
+  return IUP_DEFAULT;
+}
+
+static int iColorBrowserDlgGreenSpin_CB(Ihandle* ih, int vi) 
+{
+  IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA");
+
+  colordlg_data->green = (unsigned char)vi;
+  iColorBrowserDlgRGBChanged(colordlg_data);
+
+  return IUP_DEFAULT;
+}
+
+static int iColorBrowserDlgBlueAction_CB(Ihandle* ih, int c, char *value) 
+{
+  IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA");
+  int vi;
+
+  if (iupStrToInt(value, &vi))
+  {
+    colordlg_data->blue = (unsigned char)vi;
+    iColorBrowserDlgRGBChanged(colordlg_data);
+  }
+
+  (void)c;
+  return IUP_DEFAULT;
+}
+
+static int iColorBrowserDlgBlueSpin_CB(Ihandle* ih, int vi) 
+{
+  IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA");
+
+  colordlg_data->blue = (unsigned char)vi;
+  iColorBrowserDlgRGBChanged(colordlg_data);
+
+  return IUP_DEFAULT;
+}
+
+static int iColorBrowserDlgHueAction_CB(Ihandle* ih, int c, char *value) 
+{
+  IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA");
+  int vi;
+
+  if (iupStrToInt(value, &vi))
+  {
+    colordlg_data->hue = (float)vi;
+    iColorBrowserDlgHSIChanged(colordlg_data);
+  }
+
+  (void)c;
+  return IUP_DEFAULT;
+}
+
+static int iColorBrowserDlgHueSpin_CB(Ihandle* ih, int vi) 
+{
+  IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA");
+
+  colordlg_data->hue = (float)vi;
+  iColorBrowserDlgHSIChanged(colordlg_data);
+
+  return IUP_DEFAULT;
+}
+
+static int iColorBrowserDlgSaturationAction_CB(Ihandle* ih, int c, char *value) 
+{
+  IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA");
+  int vi;
+
+  if (iupStrToInt(value, &vi))
+  {
+    colordlg_data->saturation = (float)vi/100.0f;
+    iColorBrowserDlgHSIChanged(colordlg_data);
+  }
+
+  (void)c;
+  return IUP_DEFAULT;
+}
+
+static int iColorBrowserDlgSaturationSpin_CB(Ihandle* ih, int vi) 
+{
+  IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA");
+
+  colordlg_data->saturation = (float)vi/100.0f;
+  iColorBrowserDlgHSIChanged(colordlg_data);
+
+  return IUP_DEFAULT;
+}
+
+static int iColorBrowserDlgIntensityAction_CB(Ihandle* ih, int c, char *value) 
+{
+  IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA");
+  int vi;
+
+  if (iupStrToInt(value, &vi))
+  {
+    colordlg_data->intensity = (float)vi/100.0f;
+    iColorBrowserDlgHSIChanged(colordlg_data);
+  }
+
+  (void)c;
+  return IUP_DEFAULT;
+}
+
+static int iColorBrowserDlgIntensitySpin_CB(Ihandle* ih, int vi) 
+{
+  IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA");
+
+  colordlg_data->intensity = (float)vi/100.0f;
+  iColorBrowserDlgHSIChanged(colordlg_data);
+
+  return IUP_DEFAULT;
+}
+
+static int iColorBrowserDlgHexAction_CB(Ihandle* ih, int c, char* value) 
+{
+  IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA");
+
+  if (iupStrHexToRGB(value, &colordlg_data->red, &colordlg_data->green, &colordlg_data->blue))
+  {
+    iColorBrowserDlgRGB2HSI(colordlg_data);
+    iColorBrowserDlgBrowserRGB_Update(colordlg_data);
+    iColorBrowserDlgHSI_TXT_Update(colordlg_data);
+    iColorBrowserDlgRGB_TXT_Update(colordlg_data);
+    iColorBrowserDlgColor_Update(colordlg_data);
+  }
+
+  (void)c;
+  return IUP_DEFAULT;
+}
+
+static int iColorBrowserDlgColorSelDrag_CB(Ihandle* ih, unsigned char r, unsigned char g, unsigned char b)
+{
+  IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA");
+
+  colordlg_data->red   = r;
+  colordlg_data->green = g;
+  colordlg_data->blue  = b;
+
+  iColorBrowserDlgRGB2HSI(colordlg_data);
+  iColorBrowserDlgHex_TXT_Update(colordlg_data);
+  iColorBrowserDlgHSI_TXT_Update(colordlg_data);
+  iColorBrowserDlgRGB_TXT_Update(colordlg_data);
+
+  colordlg_data->color = cdEncodeColor(colordlg_data->red,colordlg_data->green,colordlg_data->blue);
+  colordlg_data->color = cdEncodeAlpha(colordlg_data->color, colordlg_data->alpha);
+  iColorBrowserDlgColorCnvRepaint(colordlg_data);
+
+  return IUP_DEFAULT;
+}
+
+static int iColorBrowserDlgAlphaVal_CB(Ihandle* ih, double val)
+{
+  IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA");
+
+  colordlg_data->alpha = (unsigned char)val;
+  IupSetfAttribute(colordlg_data->alpha_txt, "VALUE", "%d", (int)colordlg_data->alpha);
+
+  colordlg_data->color = cdEncodeAlpha(colordlg_data->color, colordlg_data->alpha);
+  iColorBrowserDlgColorCnvRepaint(colordlg_data);
+
+  return IUP_DEFAULT;  
+}
+
+static int iColorBrowserDlgAlphaAction_CB(Ihandle* ih, int c, char* value) 
+{
+  IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA");
+  int vi;
+
+  if (iupStrToInt(value, &vi))
+  {
+    colordlg_data->alpha = (unsigned char)vi;
+    IupSetfAttribute(colordlg_data->alpha_val, "VALUE", "%d", (int)colordlg_data->alpha);
+
+    colordlg_data->color = cdEncodeAlpha(colordlg_data->color, colordlg_data->alpha);
+    iColorBrowserDlgColorCnvRepaint(colordlg_data);
+  }
+
+  (void)c;
+  return IUP_DEFAULT;
+}
+
+static int iColorBrowserDlgAlphaSpin_CB(Ihandle* ih, int vi) 
+{
+  IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA");
+
+  colordlg_data->alpha = (unsigned char)vi;
+  IupSetfAttribute(colordlg_data->alpha_val, "VALUE", "%d", (int)colordlg_data->alpha);
+
+  colordlg_data->color = cdEncodeAlpha(colordlg_data->color, colordlg_data->alpha);
+  iColorBrowserDlgColorCnvRepaint(colordlg_data);
+
+  return IUP_DEFAULT;
+}
+
+static int iColorBrowserDlgColorTableSelect_CB(Ihandle* ih, int cell, int type)
+{
+  char* str = iupStrGetMemory(30);
+
+  IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA");
+
+  sprintf(str, "CELL%d", cell);
+  iupStrToRGB(IupGetAttribute(ih, str), &colordlg_data->red, &colordlg_data->green, &colordlg_data->blue);
+
+  iColorBrowserDlgRGB_TXT_Update(colordlg_data);
+  iColorBrowserDlgRGBChanged(colordlg_data);
+
+  (void)type;
+  return IUP_DEFAULT;
+}
+
+static int iColorBrowserDlgColorCnvButton_CB(Ihandle* ih, int b, int press, int x, int y)
+{
+  IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA");
+  int width;
+  (void)y;
+
+  if (b != IUP_BUTTON1 || !press || !colordlg_data->color_cddbuffer)
+    return IUP_DEFAULT;
+
+  cdCanvasGetSize(colordlg_data->color_cddbuffer, &width, NULL, NULL, NULL);
+
+  if (x < width/2)
+  {
+    /* reset color to previous */
+    colordlg_data->red = cdRed(colordlg_data->previous_color);
+    colordlg_data->green = cdGreen(colordlg_data->previous_color);
+    colordlg_data->blue = cdBlue(colordlg_data->previous_color);
+    colordlg_data->alpha = cdAlpha(colordlg_data->previous_color);
+
+    IupSetfAttribute(colordlg_data->alpha_txt, "VALUE", "%d", (int)colordlg_data->alpha);
+    IupSetfAttribute(colordlg_data->alpha_val, "VALUE", "%d", (int)colordlg_data->alpha);
+
+    iColorBrowserDlgRGB_TXT_Update(colordlg_data);
+    iColorBrowserDlgRGBChanged(colordlg_data);
+  }
+
+  return IUP_DEFAULT;
+}
+
+static int iColorBrowserDlgColorCnvMap_CB(Ihandle* ih)
+{
+  IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA");
+
+  /* Create Canvas */
+  colordlg_data->color_cdcanvas = cdCreateCanvas(CD_IUP, colordlg_data->color_cnv);
+
+  if (!colordlg_data->color_cdcanvas)
+    return IUP_DEFAULT;
+
+  /* this can fail if canvas size is zero */
+  colordlg_data->color_cddbuffer = cdCreateCanvas(CD_DBUFFERRGB, colordlg_data->color_cdcanvas);
+  return IUP_DEFAULT;
+}
+
+static int iColorBrowserDlgColorCnvUnMap_CB(Ihandle* ih)
+{
+  IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA");
+
+  if (colordlg_data->color_cddbuffer)
+    cdKillCanvas(colordlg_data->color_cddbuffer);
+
+  if (colordlg_data->color_cdcanvas)
+    cdKillCanvas(colordlg_data->color_cdcanvas);
+
+  return IUP_DEFAULT;
+}
+
+
+/**************************************************************************************************************/
+/*                                     Attributes                                                             */
+/**************************************************************************************************************/
+
+
+static char* iColorBrowserDlgGetStatusAttrib(Ihandle* ih)
+{
+  IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA");
+  if (colordlg_data->status) 
+    return "1";
+  else 
+    return NULL;
+}
+
+static int iColorBrowserDlgSetShowHelpAttrib(Ihandle* ih, const char* value)
+{
+  IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA");
+  IupSetAttribute(colordlg_data->help_bt, "VISIBLE", iupStrBoolean(value)? "YES": "NO");
+  return 1;
+}
+
+static int iColorBrowserDlgSetShowHexAttrib(Ihandle* ih, const char* value)
+{
+  IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA");
+
+  /* valid only before map */
+  if (ih->handle)
+    return 1;
+
+  if (iupStrBoolean(value))
+  {
+    Ihandle* box = IupGetParent(colordlg_data->colorhex_txt);
+    IupSetAttribute(box, "FLOATING", NULL);
+    IupSetAttribute(box, "VISIBLE", "YES");
+  }
+
+  return 1;
+}
+
+static int iColorBrowserDlgSetShowColorTableAttrib(Ihandle* ih, const char* value)
+{
+  IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA");
+
+  /* valid only before map */
+  if (ih->handle)
+    return 1;
+
+  if (iupStrBoolean(value))
+  {
+    Ihandle* box = IupGetParent(colordlg_data->colortable_cbar);
+    IupSetAttribute(box, "FLOATING", NULL);
+    IupSetAttribute(box, "VISIBLE", "YES");
+  }
+
+  return 1;
+}
+
+static int iColorBrowserDlgSetShowAlphaAttrib(Ihandle* ih, const char* value)
+{
+  IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA");
+
+  /* valid only before map */
+  if (ih->handle)
+    return 1;
+
+  if (iupStrBoolean(value))
+  {
+    Ihandle* box = IupGetParent(colordlg_data->alpha_val);
+    IupSetAttribute(box, "FLOATING", NULL);
+    IupSetAttribute(box, "VISIBLE", "YES");
+  }
+
+  return 1;
+}
+
+static int iColorBrowserDlgSetAlphaAttrib(Ihandle* ih, const char* value)
+{
+  IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA");
+  int alpha;
+  if (iupStrToInt(value, &alpha))
+  {
+    colordlg_data->alpha = (unsigned char)alpha;
+    IupSetfAttribute(colordlg_data->alpha_txt, "VALUE", "%d", (int)colordlg_data->alpha);
+    IupSetfAttribute(colordlg_data->alpha_val, "VALUE", "%d", (int)colordlg_data->alpha);
+
+    colordlg_data->color = cdEncodeAlpha(colordlg_data->color, colordlg_data->alpha);
+    colordlg_data->previous_color = cdEncodeAlpha(colordlg_data->previous_color, colordlg_data->alpha);
+    iColorBrowserDlgColorCnvRepaint(colordlg_data);
+
+    if (!ih->handle)  /* do it only before map */
+      IupSetAttribute(ih, "SHOWALPHA", "YES");
+  }
+ 
+  return 1;
+}
+
+static char* iColorBrowserDlgGetAlphaAttrib(Ihandle* ih)
+{
+  char* buffer = iupStrGetMemory(100);
+  IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA");
+  sprintf(buffer, "%d", (int)colordlg_data->alpha);
+  return buffer;
+}
+
+static int iColorBrowserDlgSetValueAttrib(Ihandle* ih, const char* value)
+{
+  IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA");
+  int ret = iupStrToRGBA(value, &colordlg_data->red, &colordlg_data->green, &colordlg_data->blue, &colordlg_data->alpha);
+  if (!ret)
+    return 0;
+  
+  colordlg_data->previous_color = cdEncodeColor(colordlg_data->red, colordlg_data->green, colordlg_data->blue);
+  colordlg_data->previous_color = cdEncodeAlpha(colordlg_data->previous_color, colordlg_data->alpha);
+
+  if (ret == 4)
+  {
+    IupSetfAttribute(colordlg_data->alpha_txt, "VALUE", "%d", (int)colordlg_data->alpha);
+    IupSetfAttribute(colordlg_data->alpha_val, "VALUE", "%d", (int)colordlg_data->alpha);
+
+    if (!ih->handle)  /* do it only before map */
+      IupSetAttribute(ih, "SHOWALPHA", "YES");
+  }
+
+  iColorBrowserDlgRGB_TXT_Update(colordlg_data);
+  iColorBrowserDlgRGBChanged(colordlg_data);
+
+  return 0;
+}
+
+static char* iColorBrowserDlgGetValueAttrib(Ihandle* ih)
+{
+  char* buffer = iupStrGetMemory(100);
+  IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA");
+  if (iupAttribGetBoolean(ih, "SHOWALPHA"))
+    sprintf(buffer, "%d %d %d %d", (int)colordlg_data->red, (int)colordlg_data->green, (int)colordlg_data->blue, (int)colordlg_data->alpha);
+  else
+    sprintf(buffer, "%d %d %d", (int)colordlg_data->red, (int)colordlg_data->green, (int)colordlg_data->blue);
+  return buffer;
+}
+
+static int iupStrToHSI_Int(const char *str, int *h, int *s, int *i)
+{
+  int fh, fs, fi;
+  if (!str) return 0;
+  if (sscanf(str, "%d %d %d", &fh, &fs, &fi) != 3) return 0;
+  if (fh > 359 || fs > 100 || fi > 100) return 0;
+  if (fh < 0 || fs < 0 || fi < 0) return 0;
+  *h = fh;
+  *s = fs;
+  *i = fi;
+  return 1;
+}
+
+static int iColorBrowserDlgSetValueHSIAttrib(Ihandle* ih, const char* value)
+{
+  IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA");
+  int hue, saturation, intensity;
+
+  if (!iupStrToHSI_Int(value, &hue, &saturation, &intensity))
+    return 0;
+  
+  colordlg_data->hue = (float)hue;
+  colordlg_data->saturation = (float)saturation/100.0f;
+  colordlg_data->intensity = (float)intensity/100.0f;
+
+  iColorBrowserDlgHSI2RGB(colordlg_data);
+  colordlg_data->previous_color = cdEncodeColor(colordlg_data->red, colordlg_data->green, colordlg_data->blue);
+  colordlg_data->previous_color = cdEncodeAlpha(colordlg_data->previous_color, colordlg_data->alpha);
+ 
+  iColorBrowserDlgHSIChanged(colordlg_data);
+  return 0;
+}
+
+static char* iColorBrowserDlgGetValueHSIAttrib(Ihandle* ih)
+{
+  char* buffer = iupStrGetMemory(100);
+  IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA");
+  sprintf(buffer, "%d %d %d", (int)colordlg_data->hue, (int)(colordlg_data->saturation*100), (int)(colordlg_data->intensity*100));
+  return buffer;
+}
+
+static int iColorBrowserDlgSetValueHexAttrib(Ihandle* ih, const char* value)
+{
+  IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA");
+
+  if (!iupStrHexToRGB(value, &colordlg_data->red, &colordlg_data->green, &colordlg_data->blue))
+    return 0;
+
+  colordlg_data->previous_color = cdEncodeColor(colordlg_data->red, colordlg_data->green, colordlg_data->blue);
+  colordlg_data->previous_color = cdEncodeAlpha(colordlg_data->previous_color, colordlg_data->alpha);
+
+  iColorBrowserDlgRGB2HSI(colordlg_data);
+  iColorBrowserDlgBrowserRGB_Update(colordlg_data);
+  iColorBrowserDlgHSI_TXT_Update(colordlg_data);
+  iColorBrowserDlgRGB_TXT_Update(colordlg_data);
+  iColorBrowserDlgColor_Update(colordlg_data);
+  return 0;
+}
+
+static char* iColorBrowserDlgGetValueHexAttrib(Ihandle* ih)
+{
+  char* buffer = iupStrGetMemory(100);
+  IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA");
+  sprintf(buffer, "#%02X%02X%02X", (int)colordlg_data->red, (int)colordlg_data->green, (int)colordlg_data->blue);
+  return buffer;
+}
+
+static char* iColorBrowserDlgGetColorTableAttrib(Ihandle* ih)
+{
+  int i, inc, off = 0;
+  IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA");
+  char* color_str, attrib_str[30];
+  char* str = iupStrGetMemory(300);
+  for (i=0; i < 20; i++)
+  {
+    sprintf(attrib_str, "CELL%d", i);
+    color_str = IupGetAttribute(colordlg_data->colortable_cbar, attrib_str);
+    inc = strlen(color_str);
+    memcpy(str+off, color_str, inc);
+    memcpy(str+off+inc, ";", 1);
+    off += inc+1;
+  }
+  str[off-1] = 0; /* remove last separator */
+  return str;
+}
+
+static int iColorBrowserDlgSetColorTableAttrib(Ihandle* ih, const char* value)
+{
+  int i = 0;
+  unsigned char r, g, b;
+  char str[30];
+  IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA");
+
+  if (!ih->handle)    /* do it only before map */
+    iColorBrowserDlgSetShowColorTableAttrib(ih, "YES");
+
+  while (value && *value && i < 20)
+  {
+    if (iupStrToRGB(value, &r, &g, &b))
+    {
+      sprintf(str, "CELL%d", i);
+      IupSetfAttribute(colordlg_data->colortable_cbar, str, "%d %d %d", (int)r, (int)g, (int)b);
+    }
+
+    value = strchr(value, ';');
+    if (value) value++;
+    i++;
+  }
+
+  return 1;
+}
+
+
+/**************************************************************************************************************/
+/*                                     Methods                                                                */
+/**************************************************************************************************************/
+
+static int iColorBrowserDlgMapMethod(Ihandle* ih)
+{
+  if (!IupGetCallback(ih, "HELP_CB"))
+  {
+    IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA");
+    IupSetAttribute(colordlg_data->help_bt, "VISIBLE", "NO");
+  }
+
+  return IUP_NOERROR;
+}
+
+static void iColorBrowserDlgDestroyMethod(Ihandle* ih)
+{
+  IcolorDlgData* colordlg_data = (IcolorDlgData*)iupAttribGetInherit(ih, "_IUP_GC_DATA");
+  free(colordlg_data);
+}
+
+static int iColorBrowserDlgCreateMethod(Ihandle* ih, void** params)
+{
+  Ihandle *ok_bt, *cancel_bt;
+  Ihandle *rgb_vb, *hsi_vb, *clr_vb;
+  Ihandle *lin1, *lin2, *col1, *col2;
+
+  IcolorDlgData* colordlg_data = (IcolorDlgData*)malloc(sizeof(IcolorDlgData));
+  memset(colordlg_data, 0, sizeof(IcolorDlgData));
+  iupAttribSetStr(ih, "_IUP_GC_DATA", (char*)colordlg_data);
+
+  /* ======================================================================= */
+  /* BUTTONS   ============================================================= */
+  /* ======================================================================= */
+  ok_bt = IupButton("OK", NULL);                      /* Ok Button */
+  IupSetAttribute(ok_bt, "PADDING", "20x0");
+  IupSetCallback (ok_bt, "ACTION", (Icallback)iColorBrowserDlgButtonOK_CB);
+  IupSetAttributeHandle(ih, "DEFAULTENTER", ok_bt);
+
+  cancel_bt = IupButton(iupStrMessageGet("IUP_CANCEL"), NULL);          /* Cancel Button */
+  IupSetAttribute(cancel_bt, "PADDING", "20x0");
+  IupSetCallback (cancel_bt, "ACTION", (Icallback)iColorBrowserDlgButtonCancel_CB);
+  IupSetAttributeHandle(ih, "DEFAULTESC", cancel_bt);
+
+  colordlg_data->help_bt = IupButton(iupStrMessageGet("IUP_HELP"), NULL);            /* Help Button */
+  IupSetAttribute(colordlg_data->help_bt, "PADDING", "20x0");
+  IupSetCallback (colordlg_data->help_bt, "ACTION", (Icallback)iColorBrowserDlgButtonHelp_CB);
+
+  /* ======================================================================= */
+  /* COLOR   =============================================================== */
+  /* ======================================================================= */
+  colordlg_data->color_browser = IupColorBrowser();
+  IupSetAttribute(colordlg_data->color_browser, "EXPAND", "YES");  
+  IupSetCallback(colordlg_data->color_browser, "DRAG_CB",   (Icallback)iColorBrowserDlgColorSelDrag_CB);
+  IupSetCallback(colordlg_data->color_browser, "CHANGE_CB", (Icallback)iColorBrowserDlgColorSelDrag_CB);
+
+  colordlg_data->color_cnv = IupCanvas(NULL);  /* Canvas of the color */
+  IupSetAttribute(colordlg_data->color_cnv, "SIZE", "x12");
+  IupSetAttribute(colordlg_data->color_cnv, "CANFOCUS", "NO");
+  IupSetAttribute(colordlg_data->color_cnv, "EXPAND", "HORIZONTAL");
+  IupSetCallback (colordlg_data->color_cnv, "ACTION", (Icallback)iColorBrowserDlgColorCnvRedraw_CB);
+  IupSetCallback (colordlg_data->color_cnv, "MAP_CB", (Icallback)iColorBrowserDlgColorCnvMap_CB);
+  IupSetCallback (colordlg_data->color_cnv, "UNMAP_CB", (Icallback)iColorBrowserDlgColorCnvUnMap_CB);
+  IupSetCallback (colordlg_data->color_cnv, "BUTTON_CB", (Icallback)iColorBrowserDlgColorCnvButton_CB);
+
+  colordlg_data->colorhex_txt = IupText(NULL);      /* Hex of the color */
+  IupSetAttribute(colordlg_data->colorhex_txt, "VISIBLECOLUMNS", "7");
+  IupSetCallback (colordlg_data->colorhex_txt, "ACTION", (Icallback)iColorBrowserDlgHexAction_CB);
+  IupSetAttribute(colordlg_data->colorhex_txt, "MASK", "#[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]");
+
+  /* ======================================================================= */
+  /* ALPHA TRANSPARENCY   ================================================== */
+  /* ======================================================================= */
+  colordlg_data->alpha_val = IupVal("HORIZONTAL");
+  IupSetAttribute(colordlg_data->alpha_val, "EXPAND", "HORIZONTAL");
+  IupSetAttribute(colordlg_data->alpha_val, "MIN", "0");
+  IupSetAttribute(colordlg_data->alpha_val, "MAX", "255");
+  IupSetAttribute(colordlg_data->alpha_val, "VALUE", "255");
+  IupSetAttribute(colordlg_data->alpha_val, "SIZE", "80x12");
+  IupSetCallback (colordlg_data->alpha_val, "MOUSEMOVE_CB", (Icallback)iColorBrowserDlgAlphaVal_CB);
+  IupSetCallback (colordlg_data->alpha_val, "BUTTON_PRESS_CB", (Icallback)iColorBrowserDlgAlphaVal_CB);
+  IupSetCallback (colordlg_data->alpha_val, "BUTTON_RELEASE_CB", (Icallback)iColorBrowserDlgAlphaVal_CB);
+
+  colordlg_data->alpha_txt = IupText(NULL);                        /* Alpha value */
+  IupSetAttribute(colordlg_data->alpha_txt, "VISIBLECOLUMNS", "3");
+  IupSetAttribute(colordlg_data->alpha_txt, "SPIN", "YES");
+  IupSetAttribute(colordlg_data->alpha_txt, "SPINMIN", "0");
+  IupSetAttribute(colordlg_data->alpha_txt, "SPINMAX", "255");
+  IupSetAttribute(colordlg_data->alpha_txt, "SPININC", "1");
+  IupSetCallback (colordlg_data->alpha_txt, "ACTION", (Icallback)iColorBrowserDlgAlphaAction_CB);
+  IupSetCallback (colordlg_data->alpha_txt, "SPIN_CB", (Icallback)iColorBrowserDlgAlphaSpin_CB);
+  IupSetAttribute(colordlg_data->alpha_txt, "MASKINT", "0:255");
+
+  /* ======================================================================= */
+  /* COLOR TABLE   ========================================================= */
+  /* ======================================================================= */
+  colordlg_data->colortable_cbar = IupColorbar();
+  IupSetAttribute(colordlg_data->colortable_cbar, "ORIENTATION", "HORIZONTAL");
+  IupSetAttribute(colordlg_data->colortable_cbar, "NUM_PARTS", "2");  
+  IupSetAttribute(colordlg_data->colortable_cbar, "NUM_CELLS", "20");
+  IupSetAttribute(colordlg_data->colortable_cbar, "SHOW_PREVIEW", "NO");
+  IupSetAttribute(colordlg_data->colortable_cbar, "SIZE", "138x22");
+  IupSetAttribute(colordlg_data->colortable_cbar, "SQUARED", "NO");
+  IupSetCallback (colordlg_data->colortable_cbar, "SELECT_CB",   (Icallback)iColorBrowserDlgColorTableSelect_CB);
+
+  /* ======================================================================= */
+  /* RGB TEXT FIELDS   ===================================================== */
+  /* ======================================================================= */
+  colordlg_data->red_txt = IupText(NULL);                            /* Red value */
+  IupSetAttribute(colordlg_data->red_txt, "VISIBLECOLUMNS", "3");
+  IupSetAttribute(colordlg_data->red_txt, "SPIN", "YES");
+  IupSetAttribute(colordlg_data->red_txt, "SPINMIN", "0");
+  IupSetAttribute(colordlg_data->red_txt, "SPINMAX", "255");
+  IupSetAttribute(colordlg_data->red_txt, "SPININC", "1");
+  IupSetCallback (colordlg_data->red_txt, "ACTION", (Icallback)iColorBrowserDlgRedAction_CB);
+  IupSetCallback (colordlg_data->red_txt, "SPIN_CB", (Icallback)iColorBrowserDlgRedSpin_CB);
+  IupSetAttribute(colordlg_data->red_txt, "MASKINT", "0:255");
+
+  colordlg_data->green_txt = IupText(NULL);                        /* Green value */
+  IupSetAttribute(colordlg_data->green_txt, "VISIBLECOLUMNS", "3");
+  IupSetAttribute(colordlg_data->green_txt, "SPIN", "YES");
+  IupSetAttribute(colordlg_data->green_txt, "SPINMIN", "0");
+  IupSetAttribute(colordlg_data->green_txt, "SPINMAX", "255");
+  IupSetAttribute(colordlg_data->green_txt, "SPININC", "1");
+  IupSetCallback (colordlg_data->green_txt, "ACTION", (Icallback)iColorBrowserDlgGreenAction_CB);
+  IupSetCallback (colordlg_data->green_txt, "SPIN_CB", (Icallback)iColorBrowserDlgGreenSpin_CB);
+  IupSetAttribute(colordlg_data->green_txt, "MASKINT", "0:255");
+
+  colordlg_data->blue_txt = IupText(NULL);                          /* Blue value */
+  IupSetAttribute(colordlg_data->blue_txt, "VISIBLECOLUMNS", "3");
+  IupSetAttribute(colordlg_data->blue_txt, "SPIN", "YES");
+  IupSetAttribute(colordlg_data->blue_txt, "SPINMIN", "0");
+  IupSetAttribute(colordlg_data->blue_txt, "SPINMAX", "255");
+  IupSetAttribute(colordlg_data->blue_txt, "SPININC", "1");
+  IupSetCallback (colordlg_data->blue_txt, "ACTION", (Icallback)iColorBrowserDlgBlueAction_CB);
+  IupSetCallback (colordlg_data->blue_txt, "SPIN_CB", (Icallback)iColorBrowserDlgBlueSpin_CB);
+  IupSetAttribute(colordlg_data->blue_txt, "MASKINT", "0:255");
+
+  /* ======================================================================= */
+  /* HSI TEXT FIELDS   ===================================================== */
+  /* ======================================================================= */
+  colordlg_data->hue_txt = IupText(NULL);                            /* Hue value */
+  IupSetAttribute(colordlg_data->hue_txt, "VISIBLECOLUMNS", "3");
+  IupSetAttribute(colordlg_data->hue_txt, "SPIN", "YES");
+  IupSetAttribute(colordlg_data->hue_txt, "SPINMIN", "0");
+  IupSetAttribute(colordlg_data->hue_txt, "SPINMAX", "359");
+  IupSetAttribute(colordlg_data->hue_txt, "SPINWRAP", "YES");
+  IupSetAttribute(colordlg_data->hue_txt, "SPININC", "1");
+  IupSetCallback(colordlg_data->hue_txt, "ACTION", (Icallback)iColorBrowserDlgHueAction_CB);
+  IupSetCallback(colordlg_data->hue_txt, "SPIN_CB", (Icallback)iColorBrowserDlgHueSpin_CB);
+  IupSetAttribute(colordlg_data->hue_txt, "MASKINT", "0:359");
+
+  colordlg_data->saturation_txt = IupText(NULL);              /* Saturation value */
+  IupSetAttribute(colordlg_data->saturation_txt, "VISIBLECOLUMNS", "3");
+  IupSetAttribute(colordlg_data->saturation_txt, "SPIN", "YES");
+  IupSetAttribute(colordlg_data->saturation_txt, "SPINMIN", "0");
+  IupSetAttribute(colordlg_data->saturation_txt, "SPINMAX", "100");
+  IupSetAttribute(colordlg_data->saturation_txt, "SPININC", "1");
+  IupSetCallback(colordlg_data->saturation_txt, "ACTION", (Icallback)iColorBrowserDlgSaturationAction_CB);
+  IupSetCallback(colordlg_data->saturation_txt, "SPIN_CB", (Icallback)iColorBrowserDlgSaturationSpin_CB);
+  IupSetAttribute(colordlg_data->saturation_txt, "MASKINT", "0:100");
+
+  colordlg_data->intensity_txt = IupText(NULL);                /* Intensity value */
+  IupSetAttribute(colordlg_data->intensity_txt, "VISIBLECOLUMNS", "3");
+  IupSetAttribute(colordlg_data->intensity_txt, "SPIN", "YES");
+  IupSetAttribute(colordlg_data->intensity_txt, "SPINMIN", "0");
+  IupSetAttribute(colordlg_data->intensity_txt, "SPINMAX", "100");
+  IupSetAttribute(colordlg_data->intensity_txt, "SPININC", "1");
+  IupSetCallback(colordlg_data->intensity_txt, "ACTION", (Icallback)iColorBrowserDlgIntensityAction_CB);
+  IupSetCallback(colordlg_data->intensity_txt, "SPIN_CB", (Icallback)iColorBrowserDlgIntensitySpin_CB);
+  IupSetAttribute(colordlg_data->intensity_txt, "MASKINT", "0:100");
+
+  /* =================== */
+  /* 1st line = Controls */
+  /* =================== */
+
+  col1 = IupVbox(colordlg_data->color_browser, IupSetAttributes(IupHbox(colordlg_data->color_cnv, NULL), "MARGIN=30x0"),NULL);
+
+  hsi_vb = IupVbox(IupSetAttributes(IupHbox(IupLabel(iupStrMessageGet("IUP_HUE")), 
+                                            colordlg_data->hue_txt, 
+                                            NULL), "ALIGNMENT=ACENTER"),
+                   IupSetAttributes(IupHbox(IupLabel(iupStrMessageGet("IUP_SATURATION")), 
+                                            colordlg_data->saturation_txt, 
+                                            NULL), "ALIGNMENT=ACENTER"),
+                   IupSetAttributes(IupHbox(IupLabel(iupStrMessageGet("IUP_INTENSITY")), 
+                                            colordlg_data->intensity_txt, 
+                                            NULL), "ALIGNMENT=ACENTER"),
+                   NULL);
+  IupSetAttribute(hsi_vb, "GAP", "5");
+  
+  rgb_vb = IupVbox(IupSetAttributes(IupHbox(IupLabel(iupStrMessageGet("IUP_RED")), 
+                                            colordlg_data->red_txt, 
+                                            NULL), "ALIGNMENT=ACENTER"),
+                   IupSetAttributes(IupHbox(IupLabel(iupStrMessageGet("IUP_GREEN")), 
+                                            colordlg_data->green_txt, 
+                                            NULL), "ALIGNMENT=ACENTER"),
+                   IupSetAttributes(IupHbox(IupLabel(iupStrMessageGet("IUP_BLUE")), 
+                                            colordlg_data->blue_txt, 
+                                            NULL), "ALIGNMENT=ACENTER"),
+                   NULL);
+  IupSetAttribute(rgb_vb, "GAP", "5");
+  
+  clr_vb = IupVbox(IupSetAttributes(IupHbox(IupLabel(iupStrMessageGet("IUP_OPACITY")), 
+                                            colordlg_data->alpha_txt, colordlg_data->alpha_val, 
+                                            NULL), "ALIGNMENT=ACENTER"),
+                   IupSetAttributes(IupHbox(IupLabel("He&xa:"), 
+                                            colordlg_data->colorhex_txt, 
+                                            NULL), "ALIGNMENT=ACENTER"),
+                   IupSetAttributes(IupVbox(IupLabel(iupStrMessageGet("IUP_PALETTE")), 
+                                            colordlg_data->colortable_cbar,
+                                            NULL), "GAP=3"),
+                   NULL);
+  IupSetAttribute(clr_vb, "GAP", "5");
+  IupSetAttribute(clr_vb, "EXPAND", "YES");
+
+  IupDestroy(IupSetAttributes(IupNormalizer(IupGetChild(IupGetChild(hsi_vb, 0), 0),  /* Hue Label */
+                                            IupGetChild(IupGetChild(hsi_vb, 1), 0),  /* Saturation Label */
+                                            IupGetChild(IupGetChild(hsi_vb, 2), 0),  /* Intensity Label */
+                                            IupGetChild(IupGetChild(clr_vb, 0), 0),  /* Opacity Label */
+                                            IupGetChild(IupGetChild(clr_vb, 1), 0),  /* Hexa Label */
+                                            NULL), "NORMALIZE=HORIZONTAL"));
+
+  IupDestroy(IupSetAttributes(IupNormalizer(IupGetChild(IupGetChild(rgb_vb, 0), 0),  /* Red Label */
+                                            IupGetChild(IupGetChild(rgb_vb, 1), 0),  /* Green Label */
+                                            IupGetChild(IupGetChild(rgb_vb, 2), 0),  /* Blue Label */
+                                            NULL), "NORMALIZE=HORIZONTAL"));
+
+  col2 = IupVbox(IupSetAttributes(IupHbox(hsi_vb, IupFill(), rgb_vb, NULL), "EXPAND=YES"), 
+                 IupSetAttributes(IupLabel(NULL), "SEPARATOR=HORIZONTAL"), 
+                 clr_vb,
+                 NULL);
+  IupSetAttributes(col2, "EXPAND=NO, GAP=10");
+
+  lin1 = IupHbox(col1, col2, NULL);
+  IupSetAttribute(lin1, "GAP", "10");
+  IupSetAttribute(lin1, "MARGIN", "0x0");
+
+  /* ================== */
+  /* 2nd line = Buttons */
+  /* ================== */
+
+  lin2 = IupHbox(IupFill(), ok_bt, cancel_bt, colordlg_data->help_bt, NULL);
+  IupSetAttribute(lin2, "GAP", "5");
+  IupSetAttribute(lin2, "MARGIN", "0x0");
+  IupSetAttribute(lin2, "NORMALIZESIZE", "HORIZONTAL");
+
+  /* Do not use IupAppend because we set childtype=IUP_CHILDNONE */
+  iupChildTreeAppend(ih, IupSetAttributes(IupVbox(lin1, IupSetAttributes(IupLabel(NULL), "SEPARATOR=HORIZONTAL"), lin2, NULL), "MARGIN=10x10, GAP=10"));
+
+  iColorBrowserDlgInit_Defaults(colordlg_data);
+
+  (void)params;
+  return IUP_NOERROR;
+}
+
+Iclass* iupColorBrowserDlgGetClass(void)
+{
+  Iclass* ic = iupClassNew(iupDialogGetClass());
+
+  ic->Create = iColorBrowserDlgCreateMethod;
+  ic->Destroy = iColorBrowserDlgDestroyMethod;
+  ic->Map = iColorBrowserDlgMapMethod;
+
+  ic->name = "colordlg";   /* this will hide the GTK and Windows implementations */
+  ic->nativetype = IUP_TYPEDIALOG;
+  ic->is_interactive = 1;
+  ic->childtype = IUP_CHILDNONE;
+
+  iupClassRegisterAttribute(ic, "COLORTABLE", iColorBrowserDlgGetColorTableAttrib, iColorBrowserDlgSetColorTableAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "STATUS", iColorBrowserDlgGetStatusAttrib, NULL, NULL, NULL, IUPAF_READONLY|IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "VALUE", iColorBrowserDlgGetValueAttrib, iColorBrowserDlgSetValueAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "ALPHA", iColorBrowserDlgGetAlphaAttrib, iColorBrowserDlgSetAlphaAttrib, IUPAF_SAMEASSYSTEM, "255", IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "VALUEHSI", iColorBrowserDlgGetValueHSIAttrib, iColorBrowserDlgSetValueHSIAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "VALUEHEX", iColorBrowserDlgGetValueHexAttrib, iColorBrowserDlgSetValueHexAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "SHOWALPHA", NULL, iColorBrowserDlgSetShowAlphaAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "SHOWCOLORTABLE", NULL, iColorBrowserDlgSetShowColorTableAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "SHOWHEX", NULL, iColorBrowserDlgSetShowHexAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT);
+  iupClassRegisterAttribute(ic, "SHOWHELP", NULL, iColorBrowserDlgSetShowHelpAttrib, NULL, NULL, IUPAF_NOT_MAPPED|IUPAF_NO_INHERIT);
+
+  return ic;
+}
diff --git a/iup/srccontrols/color/iup_colorhsi.c b/iup/srccontrols/color/iup_colorhsi.c
new file mode 100755
index 0000000..ce5e71f
--- /dev/null
+++ b/iup/srccontrols/color/iup_colorhsi.c
@@ -0,0 +1,358 @@
+/** \file
+ * \brief HSI Color Manipulation
+ * Copied and adapted from IM
+ *
+ * See Copyright Notice in "iup.h"
+ */
+
+
+#include <math.h>
+#include <stdio.h>
+#include "iup_colorhsi.h"
+
+static const float rad60 =  1.0471975f;
+static const float rad120 = 2.0943951f;
+static const float rad180 = 3.1415926f;
+static const float rad240 = 4.1887902f;
+static const float rad300 = 5.2359877f;
+static const float rad360 = 6.2831853f;
+static const float sqrt3 = 1.7320508f;
+static const float rad2deg = 57.2957795131f;
+
+static float costab[361];
+static float sintab[361];
+static int init_tab = 0;
+
+static void iColorBuildTables(void)
+{
+  int theta;
+  for (theta=0; theta<=360; theta++)
+  {
+    float th = ((float)theta)/rad2deg;
+    costab[theta] = cosf(th);
+    sintab[theta] = sinf(th);
+  }
+  init_tab = 1;
+}
+
+static void iColorSinCos(float H, float *sinH, float *cosH)
+{
+  int theta;
+
+  H *= rad2deg;
+  theta = (int)(H + 0.5f);  /* Round */
+
+  if (!init_tab)
+    iColorBuildTables();
+
+  if (theta<0) theta = 0;
+  if (theta>360) theta = 360;
+
+  *cosH = costab[theta];
+  *sinH = sintab[theta];
+}
+
+static float iColorNormHue(float H)
+{
+  while (H < 0.0f) 
+    H += rad360;
+
+  if (H > rad360)  
+    H = fmodf(H, rad360);
+
+  return H;
+}
+
+static unsigned char iColorQuantize(float value)
+{
+  if (value >= 1.0f) return 255;
+  if (value <= 0.0f) return 0;
+  return (unsigned char)(value*256);  
+}                               
+
+static float iColorReconstruct(unsigned char value)
+{
+  if (value <= 0) return 0.0f;
+  if (value >= 255) return 1.0f;
+  return (((float)value + 0.5f)/256.0f);
+}
+
+static void iColorSmax01(float h, float hr, float hb, float hg, float *h0, float *h1)
+{
+  if (h < rad60)
+  {
+    *h0 = hb;
+    *h1 = hr;
+  }
+  else if (h < rad120)
+  {
+    *h0 = hb;
+    *h1 = hg;
+  }
+  else if (h < rad180)
+  {
+    *h0 = hr;
+    *h1 = hg;
+  }
+  else if (h < rad240)
+  {
+    *h0 = hr;
+    *h1 = hb;
+  }
+  else if (h < rad300)
+  {
+    *h0 = hg;
+    *h1 = hb;
+  }
+  else
+  {
+    *h0 = hg;
+    *h1 = hr;
+  }
+}
+
+/* Given H and I, returns S max, but s is in u,v space. */
+static float iColorHSI_Smax(float h, float cosH, float sinH, float i)
+{
+  float hr, hb, hg, imax, h0, h1;
+
+  /* i here is normalized between 0-1 */
+
+  if (i == 0.0f || i == 1.0f)
+    return 0.0f;
+
+  /* Making r=0, g=0, b=0, r=1, g=1 or b=1 in the parametric equations and 
+     writting s in function of H and I. */
+
+  /* at bottom */
+  if (i <= 1.0f/3.0f)
+  {
+    /* face B=0 */
+    if (h < rad120)
+    {
+      hb = (cosH + sinH*sqrt3)/3.0f;
+      return i/hb;
+    }
+
+    /* face R=0 */
+    if (h < rad240)
+    {
+      hr = -cosH/1.5f;
+      return i/hr;
+    }
+
+    /* face G=0 (h < rad360) */
+    {
+      hg = (cosH - sinH*sqrt3)/3.0f;
+      return i/hg;
+    }
+  }
+
+  /* at top */
+  if (i >= 2.0f/3.0f)
+  {
+    /* face R=1 */
+    if (h < rad60 || h > rad300)
+    {
+      hr = cosH/1.5f;
+      return (1.0f-i)/hr;
+    }
+
+    /* face G=1 */
+    if (h < rad180)
+    {
+      hg = (-cosH + sinH*sqrt3)/3.0f;
+      return (1.0f-i)/hg;
+    }
+
+    /* face B=1 (h > rad180 && h < rad300) */
+    {
+      hb = (-cosH - sinH*sqrt3)/3.0f;
+      return (1.0f-i)/hb;
+    }
+  }
+
+  /* in the middle */
+  hr = cosH/1.5f;
+  hg = (-cosH + sinH*sqrt3)/3.0f;
+  hb = (-cosH - sinH*sqrt3)/3.0f;
+
+  iColorSmax01(h, hr, hb, hg, &h0, &h1);
+
+  if (h == 0.0f || h == rad120 || h == rad240)
+    imax = 1.0f/3.0f;
+  else if (h == rad60 || h == rad180 || h == rad300)
+    imax = 2.0f/3.0f;
+  else
+    imax = h0/(h0 - h1);
+
+  if (i < imax) 
+    return -i/h0;
+  else
+    return (1.0f-i)/h1;
+}
+
+/* Given H, returns I where S is max,
+   BUT the maximum S here is 1 at the corners of the cube. */
+static float iColorHSI_ImaxS(float h, float cosH, float sinH)
+{
+  float i, h0, h1;
+  float hr, hb, hg;
+
+  /* i here is normalized between 0-1 */
+
+  if (h == 0.0f || h == rad120 || h == rad240)
+    return 1.0f/3.0f;
+
+  if (h == rad60 || h == rad180 || h == rad300)
+    return 2.0f/3.0f;
+
+  hr = cosH/1.5f;
+  hg = (-cosH + sinH*sqrt3)/3.0f;
+  hb = (-cosH - sinH*sqrt3)/3.0f;
+
+  iColorSmax01(h, hr, hb, hg, &h0, &h1);
+
+  i = h0/(h0 - h1);
+
+  return i;
+}
+
+static void iColorRGB2HSI(float r, float g, float b, float *h, float *s, float *i)
+{            
+  float v, u, ImaxS; 
+
+  /* Parametric equations */
+  v = r - (g + b)/2.0f;
+  u = (g - b) * (sqrt3/2.0f);
+
+  *i = (r + g + b)/3;  /* already normalized to 0-1 */
+
+  *s = sqrtf(v*v + u*u);  /* s is between 0-1, BUT it is linear in the cube and it is in u,v space. */
+
+  if (*s == 0.0f)
+  {
+    /*  *h = <any>  (left unchanged) */
+    ImaxS = 1.0f/3.0f;
+  }
+  else
+  {
+    float Smax; 
+    float H, cosH, sinH;
+
+    H = atan2f(u, v);
+    H = iColorNormHue(H);
+    *h = H * rad2deg;
+
+    iColorSinCos(H, &sinH, &cosH);
+
+    /* must scale S from 0-Smax to 0-1 */
+    Smax = iColorHSI_Smax(H, cosH, sinH, *i);
+    if (Smax == 0.0f)
+      *s = 0.0f;
+    else
+    {
+      if (*s > Smax) /* because of round problems when calculating s and Smax */
+        *s = Smax;
+      *s /= Smax;
+    }
+
+    ImaxS = iColorHSI_ImaxS((float)H, cosH, sinH);
+  }
+
+  /* must convert I from linear scale to non-linear scale. USED ONLY FOR THE COLORBROWSER */
+  if (*i < 0.5f) /* half I is I=ImaxS, not I=0.5 */
+    *i = ((*i)*0.5f)/ImaxS;
+  else
+    *i = (((*i) - ImaxS)*0.5f)/(1.0f - ImaxS) + 0.5f;
+}
+
+static void iColorHSI2RGB(float h, float s, float i, float *r, float *g, float *b)
+{
+  float cosH, sinH, H, v, u;
+  float Smax, ImaxS; 
+
+  if (i < 0) i = 0;
+  else if (i > 1) i = 1;
+
+  if (s < 0) s = 0;
+  else if (s > 1) s = 1;
+
+  if (s == 0.0f || i == 1.0f || i == 0.0f || (int)h == 360)
+  {
+    *r = i;
+    *g = i;
+    *b = i;
+    return;
+  }
+
+  H = h/rad2deg;
+  H = iColorNormHue(H);
+
+  iColorSinCos(H, &sinH, &cosH);
+    
+  /* must convert I from non-linear scale to linear scale. USED ONLY FOR THE COLORBROWSER */
+  ImaxS = iColorHSI_ImaxS(H, cosH, sinH);
+  if (i < 0.5f) /* half I is I=ImaxS, not I=0.5 */
+    i  = ImaxS * (i / 0.5f);
+  else
+    i = (1.0f - ImaxS) * (i - 0.5f)/0.5f + ImaxS;
+
+  /* must scale S from 0-1 to 0-Smax */
+  Smax = iColorHSI_Smax(H, cosH, sinH, i);
+  s *= Smax;
+  if (s > 1.0f) /* because of round problems when calculating s and Smax */
+    s = 1.0f;
+
+  v = s * cosH;
+  u = s * sinH;
+
+  /* Inverse of the Parametric equations, using i normalized to 0-1 */
+  *r = i + v/1.5f;
+  *g = i - (v - u*sqrt3)/3.0f;
+  *b = i - (v + u*sqrt3)/3.0f;
+
+  /* fix round errors */
+  if (*r < 0.0f) *r = 0;
+  if (*g < 0.0f) *g = 0;
+  if (*b < 0.0f) *b = 0;
+    
+  if (*r > 1.0f) *r = 1.0f;
+  if (*g > 1.0f) *g = 1.0f;
+  if (*b > 1.0f) *b = 1.0f;
+}
+
+/*********************************************************************************************/
+
+void iupColorRGB2HSI(unsigned char r, unsigned char g, unsigned char b, float *h, float *s, float *i)
+{
+  float fr = iColorReconstruct(r);
+  float fg = iColorReconstruct(g);
+  float fb = iColorReconstruct(b);
+  
+  iColorRGB2HSI(fr, fg, fb, h, s, i);
+}
+
+void iupColorHSI2RGB(float h, float s, float i, unsigned char *r, unsigned char *g, unsigned char *b)
+{
+  float fr, fg, fb;
+  
+  iColorHSI2RGB(h, s, i, &fr, &fg, &fb);
+  
+  *r = iColorQuantize(fr);
+  *g = iColorQuantize(fg);
+  *b = iColorQuantize(fb);
+}
+
+int iupStrToHSI(const char *str, float *h, float *s, float *i)
+{
+  float fh, fs, fi;
+  if (!str) return 0;
+  if (sscanf(str, "%f %f %f", &fh, &fs, &fi) != 3) return 0;
+  if (fh > 359 || fs > 1 || fi > 1) return 0;
+  if (fh < 0 || fs < 0 || fi < 0) return 0;
+  *h = fh;
+  *s = fs;
+  *i = fi;
+  return 1;
+}
diff --git a/iup/srccontrols/color/iup_colorhsi.h b/iup/srccontrols/color/iup_colorhsi.h
new file mode 100755
index 0000000..b29ea48
--- /dev/null
+++ b/iup/srccontrols/color/iup_colorhsi.h
@@ -0,0 +1,44 @@
+/** \file
+ * \brief HSI Color Manipulation
+ * Copied and adapted from IM
+ *
+ * See Copyright Notice in "iup.h"
+ */
+
+#ifndef __IUP_COLORHSI_H
+#define __IUP_COLORHSI_H
+
+#if  defined(__cplusplus)
+extern "C" {
+#endif
+
+/* 0<=H<=359 */
+/* 0<=S<=1 */
+/* 0<=I<=1 */
+
+
+/* Converts from RGB to HSI.
+ */
+void iupColorRGB2HSI(unsigned char r, unsigned char g, unsigned char b, float *h, float *s, float *i);
+
+/* Converts from HSI to RGB.
+ */
+void iupColorHSI2RGB(float h, float s, float i, unsigned char *r, unsigned char *g, unsigned char *b);
+
+int iupStrToHSI(const char *str, float *h, float *s, float *i);
+
+#ifdef IUP_DEFMATHFLOAT
+#define atan2f(_X, _Y) ((float)atan2((double)_X, (double)_Y))
+#define cosf(_X)  ((float)cos((double)_X))
+#define fmodf(_X, _Y) ((float)fmod((double)_X, (double)_Y))
+#define sinf(_X) ((float)sin((double)_X))
+#define sqrtf(_X) ((float)sqrt((double)_X))
+#endif
+
+
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
-- 
cgit v1.2.3