home *** CD-ROM | disk | FTP | other *** search
/ Amiga Elysian Archive / AmigaElysianArchive.iso / prog / source / colorw.lha / color.c next >
C/C++ Source or Header  |  1987-10-12  |  20KB  |  710 lines

  1.  
  2. /* *** color.c **************************************************************
  3.  *
  4.  * ColorWindow Routine  --  Color Window Routines
  5.  *     from Book 1 of the Amiga Programmers' Suite by RJ Mical
  6.  *
  7.  * Copyright (C) 1986, 1987, Robert J. Mical
  8.  * All Rights Reserved.
  9.  *
  10.  * Created for Amiga developers.
  11.  * Any or all of this code can be used in any program as long as this
  12.  * entire copyright notice is retained, ok?  Thanks.
  13.  *
  14.  * HISTORY      NAME            DESCRIPTION
  15.  * -----------  --------------  --------------------------------------------
  16.  * 3 Jan 87     RJ >:-{)*       Clean-up for release      
  17.  * 27 Feb 86    =RJ Mical=      Modified these routines for Zaphod
  18.  * January 86   =RJ=            Modified the originals for Mandelbrot
  19.  * Late 85      =RJ=            Created the color window for Graphicraft
  20.  *
  21.  * *********************************************************************** */
  22.  
  23.  
  24. #include "color.h"
  25.  
  26.  
  27.  
  28. extern struct Gadget ColorTemplateGadgets[COLOR_GADGETS_COUNT];
  29. extern struct Image ColorPropsImages[3];
  30. extern struct PropInfo ColorPropsInfos[3];
  31. extern struct Image ColorRGBImage;
  32. extern struct Image ColorHSLImage;
  33. extern struct Image SuperColorImages[32];
  34. extern USHORT RGBData[];
  35. extern USHORT HSLData[];
  36.  
  37. UBYTE *AllocRemember();
  38. struct IntuiMessage *GetMsg();
  39. struct Window *OpenWindow();
  40.  
  41.  
  42.  
  43. /* ColorMode definitions */
  44. #define COPYCOLOR 1
  45. #define RANGE_FIRST  2
  46. #define RANGE_SECOND 3
  47.  
  48. /* These are the dimensions of the color hit box */
  49. #define COLOR_COLOR_ROWS   (4 * 10)
  50. #define COLOR_COLOR_COLS   (8 * 15)
  51. #define COLOR_COLOR_RIGHT   (COLOR_BOX_LEFT + COLOR_COLOR_COLS - 1)
  52. #define COLOR_COLOR_BOTTOM  (COLOR_COLOR_TOP + COLOR_COLOR_ROWS - 1)
  53.  
  54. VOID ResetColorProps();
  55.  
  56.  
  57. struct NewWindow ColorNewWindow =
  58.    {
  59.    /*    SHORT LeftEdge, TopEdge;      /* screen dimensions of window */
  60.    /*    SHORT Width, Height;          /* screen dimensions of window */
  61.    20, 12,
  62.    COLORWINDOW_WIDTH, COLORWINDOW_HEIGHT,
  63.  
  64.    /*    UBYTE DetailPen, BlockPen;    /* for bar/border/gadget rendering */
  65.    -1, -1,
  66.  
  67.    /*    ULONG IDCMPFlags;          /* User-selected IDCMP flags */
  68.    GADGETDOWN | GADGETUP | MOUSEBUTTONS  
  69.          | MENUPICK | MOUSEMOVE | ACTIVEWINDOW | INACTIVEWINDOW,
  70.  
  71.    /*    ULONG Flags;                  /* see Window struct for defines */
  72.    BORDERLESS | SMART_REFRESH | NOCAREREFRESH | ACTIVATE,
  73.  
  74.    /*    struct Gadget *FirstGadget;*/
  75.    &ColorTemplateGadgets[COLOR_GADGETS_COUNT - 1],
  76.  
  77.    /*    struct Image *CheckMark;*/
  78.    NULL,
  79.  
  80.    /*    UBYTE *Title;                   /* the title text for this window */
  81.    NULL,
  82.    
  83.    /*    struct Screen *Screen;*/
  84.    NULL,
  85.    
  86.    /*    struct BitMap *BitMap;*/
  87.    NULL,
  88.  
  89.    /*    SHORT MinWidth, MinHeight;     /* minimums */
  90.    0, 0,
  91.    /*    SHORT MaxWidth, MaxHeight;     /* maximums */
  92.    0, 0,
  93.  
  94.    /*    USHORT Type;*/
  95.    CUSTOMSCREEN,
  96. };
  97.  
  98. USHORT ColorMode;
  99. USHORT RangeFirst;
  100. struct Window *ColorWindow = NULL;
  101. struct RastPort *ColorRPort;
  102. struct ViewPort *ColorVPort;
  103. SHORT RowCount, RowHeight, ColumnCount, ColumnWidth;
  104. USHORT SavePalette[32];
  105.  
  106.  
  107.  
  108.  
  109. /* ======================================================================= */
  110. /* === These Routines Open, Render, and Close the Color Window =========== */
  111. /* ======================================================================= */
  112.  
  113. VOID InitColorSizes(depth)
  114. SHORT depth;
  115. /* This routine adjusts the row and column variables based on the number
  116.  * of colors supported by the ColorWindow's screen.
  117.  */
  118. {
  119.    RowCount = 1 << (depth >> 1);
  120.    RowHeight = COLOR_COLOR_ROWS / RowCount;
  121.  
  122.    ColumnCount = 1 << ((depth + 1) >> 1);
  123.    ColumnWidth = COLOR_COLOR_COLS / ColumnCount;
  124. }
  125.  
  126.  
  127.  
  128. VOID DrawBox(rp, left, top, right, bottom)
  129. struct RastPort *rp;
  130. SHORT left, top, right, bottom;
  131. /* A quick utility routine */
  132. {
  133.    SHORT savepen;
  134.  
  135.    savepen = ColorRPort->FgPen;
  136.  
  137.    SetAPen(rp, 1);
  138.    SetDrMd(rp, JAM2);
  139.  
  140.    Move(rp, left, top);
  141.    Draw(rp, left, bottom);
  142.    Draw(rp, right, bottom);
  143.    Draw(rp, right, top);
  144.    Draw(rp, left, top);
  145.  
  146.    SetAPen(ColorRPort, savepen);
  147. }
  148.  
  149.  
  150.     
  151. VOID ColorRectFill(pen)
  152. SHORT pen;
  153. /* This routine sets the pen in the RastPort as the current pen selected
  154.  * by the user, and then fills the color box with that pen color.
  155.  */
  156. {
  157.    SetAPen(ColorRPort, pen);
  158.    SetDrMd(ColorRPort, JAM1);
  159.    RectFill(ColorRPort, COLOR_BOX_LEFT, COLOR_BOX_TOP, 
  160.       COLOR_BOX_RIGHT, COLOR_BOX_BOTTOM);
  161. }
  162.  
  163.  
  164.  
  165. VOID DrawColorWindow()
  166. /* This routine fills in all the graphic details of the ColorWindow */
  167. {
  168.    SHORT col, row, colstart, colend, rowstart;
  169.    SHORT savepen;
  170.  
  171.    savepen = ColorRPort->FgPen;
  172.  
  173.    InitColorSizes(ColorRPort->BitMap->Depth);
  174.  
  175.    ColorRectFill(ColorRPort->FgPen);
  176.    DrawBox(ColorRPort, 1, 1, COLORWINDOW_WIDTH - 2, COLORWINDOW_HEIGHT - 2);
  177.    DrawBox(ColorRPort, COLOR_BOX_LEFT - 2, COLOR_BOX_TOP - 2, 
  178.          COLOR_BOX_RIGHT + 2, COLOR_BOX_BOTTOM + 2);
  179.    DrawBox(ColorRPort, COLOR_BOX_LEFT - 2, COLOR_COLOR_TOP - 2, 
  180.          COLOR_BOX_LEFT + (8 * 15) + 1, COLOR_COLOR_TOP + (4 * 10) + 1);
  181.  
  182.    colstart = COLOR_BOX_LEFT;
  183.    colend = colstart + ColumnWidth - 1;
  184.    for (col = 0; col < ColumnCount; col++)
  185.       {
  186.       rowstart = COLOR_COLOR_TOP;
  187.       for (row = 0; row < RowCount; row++)
  188.          {
  189.          SetAPen(ColorRPort, (row * ColumnCount) + col);
  190.          RectFill(ColorRPort, colstart, rowstart, colend, 
  191.                rowstart + RowHeight - 1);
  192.          rowstart += RowHeight;
  193.          }
  194.       colstart += ColumnWidth;
  195.       colend += ColumnWidth;
  196.       }
  197.  
  198.    SetAPen(ColorRPort, savepen);
  199. }
  200.  
  201.  
  202.  
  203.                               
  204. struct Window *OpenColorWindow(screen, firstpen)
  205. struct Screen *screen;
  206. SHORT firstpen;
  207. {
  208.    SHORT i;
  209.  
  210.    if (ColorNewWindow.Screen = screen) ColorNewWindow.Type = CUSTOMSCREEN;
  211.    else ColorNewWindow.Type = WBENCHSCREEN;
  212.  
  213.    if ((ColorWindow = OpenWindow(&ColorNewWindow)) == 0) return(NULL);
  214.  
  215.    ColorVPort = &ColorWindow->WScreen->ViewPort;
  216.    ColorRPort = ColorWindow->RPort;
  217.  
  218.    for (i = 0; i < 32; i++)
  219.       SavePalette[i] = GetRGB4(ColorVPort->ColorMap, i);
  220.  
  221.    SetAPen(ColorRPort, firstpen);
  222.    ResetColorProps();
  223.    DrawColorWindow();
  224.  
  225.    ColorMode = NULL;
  226.  
  227.    return(ColorWindow);
  228. }
  229.  
  230.  
  231.  
  232.  
  233. VOID CloseColorWindow(accept)
  234. BOOL accept;
  235. {
  236.    if (ColorWindow == NULL) return;
  237.  
  238.    if (NOT accept) LoadRGB4(ColorVPort, &SavePalette[0], 32);
  239.  
  240.    CloseWindow(ColorWindow);
  241.    ColorWindow = NULL;
  242. }
  243.  
  244.  
  245.  
  246.  
  247. /* ======================================================================= */
  248. /* === These Routines Manage the User Interaction ======================== */
  249. /* ======================================================================= */
  250.  
  251. BOOL ColorGadgetGotten(gadget)
  252. struct Gadget *gadget;
  253. /* This routine manages the user's gadget selection.  If one of the 
  254.  * end gadgets, such as OK or CANCEL, was selected then this routine
  255.  * returns FALSE, else it returns TRUE.
  256.  */
  257. {
  258.    switch (gadget->GadgetID)
  259.       {
  260.       case COLOR_OK:
  261.          CloseColorWindow(TRUE);
  262.          return(FALSE);
  263.          break;
  264.       case COLOR_CANCEL:
  265.          CloseColorWindow(FALSE);
  266.          return(FALSE);
  267.          break;
  268.       case COLOR_COPY:
  269.          ColorMode = COPYCOLOR;
  270.          break;
  271.       case COLOR_RANGE:
  272.          ColorMode = RANGE_FIRST;
  273.          break;
  274.       case COLOR_HSL_RGB:
  275.          ResetColorProps();
  276.          break;
  277.       }
  278.    return(TRUE);
  279. }
  280.  
  281.  
  282.  
  283. VOID ColorRange(first, last)
  284. SHORT first, last;
  285. /* Create the color range from first to last */
  286. {
  287.    SHORT i;
  288.    SHORT whole, redfraction, greenfraction, bluefraction, divisor;
  289.    USHORT rgb;
  290.    SHORT firstred, firstgreen, firstblue;
  291.    SHORT lastred, lastgreen, lastblue;
  292.    SHORT workred, workgreen, workblue;
  293.  
  294.    /* If the pen numbers are out of order, swap */
  295.    if (first > last)
  296.       {
  297.       i = first;
  298.       first = last;
  299.       last = i;
  300.       }
  301.  
  302.    /* I need to see a spread of at least two, where there's at least one
  303.     * spot between the endpoints, else there's no work to do so I
  304.     * might as well just return now.
  305.     */
  306.    if (first >= last - 1) return;
  307.  
  308.    rgb = GetRGB4(ColorVPort->ColorMap, first);
  309.    firstred = (rgb >> 8) & 0xF;
  310.    firstgreen = (rgb >> 4) & 0xF;
  311.    firstblue = (rgb >> 0) & 0xF;
  312.  
  313.    rgb = GetRGB4(ColorVPort->ColorMap, last);
  314.    lastred = (rgb >> 8) & 0xF;
  315.    lastgreen = (rgb >> 4) & 0xF;
  316.    lastblue = (rgb >> 0) & 0xF;
  317.  
  318.  
  319.    divisor = last - first;
  320.  
  321.    /* Do all math as fixed-point fractions where the low 8 bits are 
  322.     * the fraction.  This greatly lessens the effect of rounding errors.
  323.     */
  324.    whole = (lastred - firstred) << 8;
  325.    redfraction = whole / divisor;
  326.  
  327.    whole = (lastgreen - firstgreen) << 8;
  328.    greenfraction = whole / divisor;
  329.  
  330.    whole = (lastblue - firstblue) << 8;
  331.    bluefraction = whole / divisor;
  332.  
  333.    for (i = first + 1; i < last; i++)
  334.       {
  335.       lastred = ((redfraction * (i - first)) + 0x0080) >> 8;
  336.       workred = firstred + lastred;
  337.       lastgreen = ((greenfraction * (i - first)) + 0x0080) >> 8;
  338.       workgreen = firstgreen + lastgreen;
  339.       lastblue = ((bluefraction * (i - first)) + 0x0080) >> 8;
  340.       workblue = firstblue + lastblue;
  341.       SetRGB4(ColorVPort, i, workred, workgreen, workblue);
  342.       }
  343. }
  344.  
  345.  
  346.  
  347.  
  348. VOID ColorWindowHit(x, y)
  349. SHORT x, y;
  350. /* The color boxes at the bottom-right of the ColorWindow are not gadgets.
  351.  * Instead, it's just graphics and this routine is used to detect whether
  352.  * the user has selected one of the color boxes.
  353.  */
  354. {
  355.    USHORT rgb, pen;
  356.  
  357.    /* Have we got a color specifier? */
  358.    if ( (x >= COLOR_BOX_LEFT) && (x <= COLOR_COLOR_RIGHT)
  359.          && (y >= COLOR_COLOR_TOP) && (y <= COLOR_COLOR_BOTTOM) )
  360.       {
  361.       /* Yes, it's one of the color boxes.  Set this pen number */
  362.       x = x - COLOR_BOX_LEFT;
  363.       x = x / ColumnWidth;
  364.       y = y - COLOR_COLOR_TOP;
  365.       y = y / RowHeight;
  366.       pen = (y * ColumnCount) + x;
  367.  
  368.       /* first, were we in COPY COLOR mode? */
  369.       if (ColorMode == COPYCOLOR)
  370.          {
  371.          /* ok, copy old color here first! */
  372.          rgb = GetRGB4(ColorVPort->ColorMap, ColorRPort->FgPen);
  373.          SetRGB4(ColorVPort, pen, rgb >> 8, rgb >> 4, rgb);
  374.          ColorMode = NULL;
  375.          }
  376.       else if (ColorMode == RANGE_FIRST)
  377.          {
  378.          ColorMode = RANGE_SECOND;
  379.          RangeFirst = pen;
  380.          }
  381.       else if (ColorMode == RANGE_SECOND)
  382.          {
  383.          ColorMode = NULL;
  384.          ColorRange(RangeFirst, pen);
  385.          }
  386.       ColorRectFill(pen);
  387.  
  388.       ResetColorProps();
  389.       }
  390. }
  391.  
  392.  
  393.  
  394. VOID SetPropValueGrunt(value, y)
  395. SHORT value, y;
  396. {
  397.    UBYTE text[16];
  398.  
  399.    if (value >= 0) sprintf(&text[0], "%ld ", value);
  400.    else
  401.       {
  402.       text[0] = ' ';
  403.       text[1] = ' ';
  404.       }
  405.  
  406.    Move(ColorRPort, COLOR_VALUE_X, y);
  407.    Text(ColorRPort, &text[0], 2);
  408. }
  409.  
  410.  
  411.  
  412. VOID SetPropValues(red, green, blue)
  413. SHORT red, green, blue;
  414. /* Sets the text to the right of the prop gadgets */
  415. {
  416.    SHORT savepen;
  417.  
  418.    savepen = ColorRPort->FgPen;
  419.  
  420.    SetAPen(ColorRPort, 1);
  421.    SetDrMd(ColorRPort, JAM2);
  422.  
  423.    SetPropValueGrunt(red, COLOR_VALUE_REDY);
  424.    SetPropValueGrunt(green, COLOR_VALUE_GREENY);
  425.    SetPropValueGrunt(blue, COLOR_VALUE_BLUEY);
  426.  
  427.    SetAPen(ColorRPort, savepen);
  428. }
  429.  
  430.  
  431.  
  432. VOID ModifyRGBColors()
  433. {
  434.    USHORT newred, newgreen, newblue;
  435.  
  436.    newred = ColorPropsInfos[0].HorizPot >> 12;
  437.    newgreen = ColorPropsInfos[1].HorizPot >> 12;
  438.    newblue = ColorPropsInfos[2].HorizPot >> 12;
  439.  
  440.    SetRGB4(ColorVPort, ColorRPort->FgPen, newred, newgreen, newblue);
  441.    SetPropValues(newred, newgreen, newblue);
  442. }
  443.  
  444.  
  445.  
  446.  
  447. VOID ModifyHSLColors()
  448. {
  449.    USHORT rgb;
  450.  
  451.    rgb = (USHORT)HSLToRGB(
  452.          ColorPropsInfos[0].HorizPot,
  453.          ColorPropsInfos[1].HorizPot,
  454.          ColorPropsInfos[2].HorizPot);
  455.  
  456.    SetRGB4(ColorVPort, ColorRPort->FgPen, rgb >> 8, rgb >> 4, rgb);
  457.    SetPropValues(-1, -1, -1);
  458. }
  459.  
  460.  
  461.  
  462.  
  463. VOID ModifyColors()
  464. /* This routine reacts to the user playing with one of the prop gadgets */
  465. {
  466.    if (ColorTemplateGadgets[COLOR_HSL_RGB].Flags & SELECTED)
  467.       ModifyHSLColors();
  468.    else
  469.       ModifyRGBColors();
  470. }
  471.  
  472.  
  473.  
  474. VOID SetRGBProps(rgb)
  475. USHORT rgb;
  476. {
  477.    USHORT red, green, blue;
  478.  
  479.    red = (rgb >> 8) & 0xF;
  480.    green = (rgb >> 4) & 0xF;
  481.    blue = (rgb >> 0) & 0xF;
  482.  
  483.    ColorPropsInfos[0].HorizPot
  484.          = (red << 12) | (red << 8) | (red << 4) | red;
  485.    ColorPropsInfos[1].HorizPot
  486.          = (green << 12) | (green << 8) | (green << 4) | green;
  487.    ColorPropsInfos[2].HorizPot
  488.          = (blue << 12) | (blue << 8) | (blue << 4) | blue;
  489.  
  490.    SetPropValues(red, green, blue);
  491. }
  492.  
  493.  
  494.  
  495. VOID SetHSLProps(rgb)
  496. USHORT rgb;
  497. {
  498.    RGBToHSL(rgb,
  499.          &ColorPropsInfos[0].HorizPot,
  500.          &ColorPropsInfos[1].HorizPot,
  501.          &ColorPropsInfos[2].HorizPot);
  502.  
  503.    SetPropValues(-1, -1, -1);
  504. }
  505.  
  506.  
  507.  
  508. VOID ResetColorProps()
  509. /* This routine resets the proportional gadgets according to the current
  510.  * pen number and the interaction technique
  511.  */
  512. {
  513.    SHORT bluepos;
  514.    USHORT rgb;
  515.  
  516.    rgb = GetRGB4(ColorVPort->ColorMap, ColorRPort->FgPen);
  517.  
  518.    bluepos = RemoveGList(ColorWindow, &ColorTemplateGadgets[COLOR_BLUE], 3);
  519.  
  520.    if (ColorTemplateGadgets[COLOR_HSL_RGB].Flags & SELECTED)
  521.       SetHSLProps(rgb);
  522.    else SetRGBProps(rgb);
  523.  
  524.    AddGList(ColorWindow, &ColorTemplateGadgets[COLOR_BLUE], bluepos, 3, 0);
  525.    RefreshGList(&ColorTemplateGadgets[COLOR_BLUE], ColorWindow, NULL, 3);
  526. }
  527.  
  528.  
  529.  
  530.  
  531.  
  532. /* ======================================================================= */
  533. /* === And finally, the Main Entry Point ================================= */
  534. /* ======================================================================= */
  535.  
  536.  
  537. /* *** DoColorWindow() ******************************************************
  538.  * 
  539.  * NAME
  540.  *     DoColorWindow  --  Allows the user to change a screen's colors
  541.  * 
  542.  * 
  543.  * SYNOPSIS
  544.  *     BOOL DoColorWindow(Screen, Left, Top, FirstPen, UseRGB);
  545.  * 
  546.  * 
  547.  * FUNCTION
  548.  *     This routine creates a window, called the ColorWindow, which has 
  549.  *     gadgets that allow the user to change the colors of any screen.  
  550.  *     After opening the ColorWindow, this routine interacts with the 
  551.  *     user until the user is satisfied with the current colors, at which 
  552.  *     time the window is closed and control is returned to you.  
  553.  * 
  554.  *     The ColorWindow will open in the specified Screen.  The Screen 
  555.  *     argument can be equal to NULL; if it is, the ColorWindow will be 
  556.  *     opened in the Workbench screen.  The ColorWindow automatically 
  557.  *     adapts itself to any screen.  
  558.  * 
  559.  *     With the Top and Left arguments you specify the position of the 
  560.  *     ColorWindow's top-left corner.  Note that no position-error 
  561.  *     checking is done, so you must take care to not place the window 
  562.  *     outside of the bounds of your screen.  Currently, the Left argument 
  563.  *     can range from 0 to 88 on low-resolution screens, and 0 to 408 
  564.  *     on high-resolution screens.  The Top argument can range from 
  565.  *     0 to 109 on a 200-line screen, and 0 to 309 on an interlaced screen.  
  566.  *     These figures don't include overscan, which most programmers 
  567.  *     don't use.  The width and height of the ColorWindow are defined 
  568.  *     by the constants COLORWINDOW_WIDTH and COLORWINDOW_HEIGHT in the 
  569.  *     color.h file.  
  570.  * 
  571.  *     The FirstPen argument is used to initialize the color that's 
  572.  *     displayed when the ColorWindow is first created.  
  573.  * 
  574.  *     The ColorWindow is capable of allowing the user to modify the 
  575.  *     colors using either an RGB or an HSL technique.  The RGB technique 
  576.  *     involves three proportional gadgets, one for each of Red, Green 
  577.  *     and Blue.  By adjusting one of these gadgets, the user adjusts 
  578.  *     the amount of the associated color component in the final color.  
  579.  *     Some people feel that this is the most intuitive way to change 
  580.  *     colors on the Amiga, as this is how colors are represented 
  581.  *     internally by the Amiga.  The other technique, HSL, allows the 
  582.  *     user to adjust the Hue, Saturation and Luminance of the final color.  
  583.  *     Some people feel that *this* is the most intuitive way for users 
  584.  *     to change color, because it's based on color theory and because 
  585.  *     these are the types of controls that people used on their 
  586.  *     color televisions in the old days.  
  587.  * 
  588.  *     You decide which mode is first used when the ColorWindow is created 
  589.  *     by setting the UseRGB argument to TRUE or FALSE.  If TRUE, 
  590.  *     the RGB technique will be used.  If FALSE, HSL is used.  
  591.  * 
  592.  *     But regardless of which technique you specify, the user can switch 
  593.  *     to using the other technique by clicking on the RGB / HSL characters 
  594.  *     that appear to the left of the proportional gadgets.  
  595.  * 
  596.  *     On return from this function, this routine returns TRUE if all 
  597.  *     went well.  If anything went wrong (usually out of memory) and 
  598.  *     the ColorWindow was never created, this routine returns FALSE.  
  599.  * 
  600.  *     NOTE:  This routine is not re-entrant.  What this means 
  601.  *     is that if you have created a program that has more than one task,
  602.  *     this routine cannot be called by more than one task at a time.
  603.  *     This was done for the sake of memory efficiency.
  604.  *     This restriction is not a problem for the grand majority of programs.
  605.  *     But if you have some application that would require calling this 
  606.  *     routine asynchronously from multiple tasks, you'll have to 
  607.  *     implement some quick semaphore arrangement to avoid collisions.
  608.  *     No big deal, actually.  See Exec semaphores for everything you need.
  609.  * 
  610.  * 
  611.  * INPUTS
  612.  *     Screen = address of the screen in which the ColorWindow will open.
  613.  *         Can be NULL; if so, the ColorWindow will open in the Workbench
  614.  *     Left = position of the left edge when the ColorWindow opens
  615.  *     Top = position of the top edge when the ColorWindow opens
  616.  *     FirstPen = pen number of the color displayed when the ColorWindow
  617.  *         first opens
  618.  *     UseRGB = TRUE if you want the RGB technique displayed first, 
  619.  *         FALSE if you want the HSL technqiue.  See the discussion above
  620.  * 
  621.  * 
  622.  * RESULT
  623.  *     Returns TRUE if all went well.  If the window couldn't be opened for
  624.  *     any reason, returns FALSE.
  625.  * 
  626.  * 
  627.  */
  628. BOOL DoColorWindow(screen, left, top, firstpen, usergb)
  629. struct Screen *screen;
  630. SHORT left, top, firstpen;
  631. BOOL usergb;
  632. {
  633.    struct IntuiMessage *message;
  634.    ULONG class;
  635.    struct Gadget *gadget;
  636.    BOOL mousemoved;
  637.    SHORT x, y, code, i;
  638.    struct Remember *key;
  639.    UWORD *ptr;
  640.    BOOL retvalue;
  641.  
  642.    key = NULL;
  643.    retvalue = FALSE;
  644.  
  645.    if (ColorWindow) goto DONE;
  646.  
  647.    ColorNewWindow.LeftEdge = left;
  648.    ColorNewWindow.TopEdge = top;
  649.  
  650.    if (usergb)
  651.       ColorTemplateGadgets[COLOR_HSL_RGB].Flags &= ~SELECTED;
  652.    else
  653.       ColorTemplateGadgets[COLOR_HSL_RGB].Flags |= SELECTED;
  654.  
  655.    if ((ptr = (UWORD *)AllocRemember(&key, RGBHSL_SIZE * 2, MEMF_CHIP))
  656.          == NULL)
  657.       goto DONE;
  658.    ColorRGBImage.ImageData = ptr;
  659.    for (i = 0; i < RGBHSL_SIZE; i++)
  660.       *ptr++ = RGBData[i];
  661.    if ((ptr = (UWORD *)AllocRemember(&key, RGBHSL_SIZE * 2, MEMF_CHIP))
  662.          == NULL)
  663.       goto DONE;
  664.    ColorHSLImage.ImageData = ptr;
  665.    for (i = 0; i < RGBHSL_SIZE; i++)
  666.       *ptr++ = HSLData[i];
  667.  
  668.    if (NOT OpenColorWindow(screen, firstpen & 0x3F)) goto DONE;
  669.  
  670.    retvalue = TRUE;
  671.  
  672.    FOREVER
  673.       {
  674.       Wait(1 << ColorWindow->UserPort->mp_SigBit);
  675.  
  676.       mousemoved = FALSE;
  677.       while (message = GetMsg(ColorWindow->UserPort))
  678.          {
  679.          class = message->Class;
  680.          code = message->Code;
  681.          gadget = (struct Gadget *)(message->IAddress);
  682.          x = message->MouseX;
  683.          y = message->MouseY;
  684.          ReplyMsg(message);
  685.  
  686.          switch (class)
  687.             {
  688.             case GADGETDOWN:
  689.             case GADGETUP:
  690.                if (ColorGadgetGotten(gadget) == FALSE)
  691.                   goto DONE;
  692.                break;
  693.             case MOUSEMOVE:
  694.                mousemoved = TRUE;
  695.                break;
  696.             case MOUSEBUTTONS:
  697.                if (code == SELECTDOWN) ColorWindowHit(x, y);
  698.                break;
  699.             }
  700.          }
  701.       if (mousemoved) ModifyColors();
  702.       }
  703.  
  704. DONE:
  705.    FreeRemember(&key, TRUE);
  706.    return(retvalue);
  707. }
  708.  
  709.  
  710.