home *** CD-ROM | disk | FTP | other *** search
/ vsiftp.vmssoftware.com / VSIPUBLIC@vsiftp.vmssoftware.com.tar / FREEWARE / FREEWARE40.ZIP / xpaint-244 / src / chroma.c < prev    next >
C/C++ Source or Header  |  1996-07-28  |  16KB  |  434 lines

  1. /* +-------------------------------------------------------------------+ */
  2. /* | Copyright 1992, 1993, David Koblas (koblas@netcom.com)            | */
  3. /* | Copyright 1995, 1996 Torsten Martinsen (bullestock@dk-online.dk)  | */
  4. /* |                                                                   | */
  5. /* | Permission to use, copy, modify, and to distribute this software  | */
  6. /* | and its documentation for any purpose is hereby granted without   | */
  7. /* | fee, provided that the above copyright notice appear in all       | */
  8. /* | copies and that both that copyright notice and this permission    | */
  9. /* | notice appear in supporting documentation.  There is no           | */
  10. /* | representations about the suitability of this software for        | */
  11. /* | any purpose.  this software is provided "as is" without express   | */
  12. /* | or implied warranty.                                              | */
  13. /* |                                                                   | */
  14. /* +-------------------------------------------------------------------+ */
  15.  
  16. /* $Id: chroma.c,v 1.5 1996/04/19 08:53:58 torsten Exp $ */
  17.  
  18. #include <X11/Intrinsic.h>
  19. #include <X11/StringDefs.h>
  20. #include <X11/cursorfont.h>
  21. #ifndef VMS
  22. #include <X11/Xaw/Form.h>
  23. #include <X11/Xaw/AsciiText.h>
  24. #include <X11/Xaw/Toggle.h>
  25. #include <X11/Xaw/Scrollbar.h>
  26. #include <X11/Xaw/Command.h>
  27. #else
  28. #include <X11Xaw/Form.h>
  29. #include <X11Xaw/AsciiText.h>
  30. #include <X11Xaw/Toggle.h>
  31. #include <X11Xaw/Scrollbar.h>
  32. #include <X11Xaw/Command.h>
  33. #endif
  34. #include <X11/Shell.h>
  35. #include <X11/keysym.h>
  36. #include <stdio.h>
  37. #include <stdlib.h>
  38.  
  39. #include "xpaint.h"
  40. #include "Paint.h"
  41. #include "protocol.h"
  42. #include "palette.h"
  43. #include "color.h"
  44. #include "misc.h"
  45. #include "operation.h"
  46. #include "ops.h"
  47.  
  48.  
  49. static unsigned char backgroundRGB[3] =
  50. {255, 255, 255};
  51. static unsigned char varianceRGB[3] =
  52. {0, 0, 0};
  53.  
  54. /*
  55. **  Dialog box
  56.  */
  57. typedef struct {
  58.     Widget redBar, greenBar, blueBar;
  59.     Widget redText, greenText, blueText;
  60.     Widget mode;        /* Only used if RANGEBUTTONS is defined */
  61.     Widget shell;        /* Used for XtPopup() */
  62.     Widget cpick;        /* The ColorPicker's Form widget */
  63.     Palette *map;        /* Current palette */
  64.     float r, g, b;
  65.     float vr, vg, vb;
  66.     Pixel pixel;
  67. } DialogInfo;
  68.  
  69. static DialogInfo *dInfo = NULL;
  70.  
  71. static void 
  72. closePopup(Widget w, Widget shell)
  73. {
  74.     XtPopdown(shell);
  75. }
  76.  
  77. static void 
  78. barCB(Widget bar, DialogInfo * l, float *percent)
  79. {
  80.     Widget t;
  81.     char buf[20];
  82.  
  83.     if (l->redBar == bar) {
  84.     l->vr = *percent;
  85.     t = l->redText;
  86.     } else if (l->greenBar == bar) {
  87.     l->vg = *percent;
  88.     t = l->greenText;
  89.     } else if (l->blueBar == bar) {
  90.     l->vb = *percent;
  91.     t = l->blueText;
  92.     } else {
  93.     return;
  94.     }
  95.     sprintf(buf, "%d", (int) (255 * *percent));
  96.     XtVaSetValues(t, XtNstring, buf, NULL);
  97. }
  98.  
  99. static void 
  100. textAction(Widget w, XEvent * event, String * prms, Cardinal * nprms)
  101. {
  102.     String val;
  103.     int v;
  104.     char buf[20];
  105.  
  106.     XtVaGetValues(w, XtNstring, &val, NULL);
  107.     v = atoi(val);
  108.     if (v > 255) {
  109.     v = 255;
  110.     XtVaSetValues(w, XtNstring, "255", NULL);
  111.     }
  112.     if (v < 0) {
  113.     v = 0;
  114.     XtVaSetValues(w, XtNstring, "0", NULL);
  115.     }
  116.     sprintf(buf, "%d", v);
  117.  
  118.     if (w == dInfo->redText) {
  119.     dInfo->vr = v / 255.0;
  120.     XawScrollbarSetThumb(dInfo->redBar, dInfo->vr, -1.0);
  121.     XtVaSetValues(dInfo->redText, XtNstring, buf, NULL);
  122.     }
  123.     if (w == dInfo->greenText) {
  124.     dInfo->vg = v / 255.0;
  125.     XawScrollbarSetThumb(dInfo->greenBar, dInfo->vg, -1.0);
  126.     XtVaSetValues(dInfo->greenText, XtNstring, buf, NULL);
  127.     }
  128.     if (w == dInfo->blueText) {
  129.     dInfo->vb = v / 255.0;
  130.     XawScrollbarSetThumb(dInfo->blueBar, dInfo->vb, -1.0);
  131.     XtVaSetValues(dInfo->blueText, XtNstring, buf, NULL);
  132.     }
  133. }
  134.  
  135. /*
  136.  * Add a Form containing a Label, Scrollbar and TextWidget.
  137.  * Return the Form widget, and store the Scrollbar and TextWidgets in 'bar'
  138.  * and 'text'.  'title' is the Label title.
  139.  */
  140. static Widget
  141. addSB(Widget parent, Widget above, char *title, Widget * bar, Widget * text)
  142. {
  143.     Widget form, label;
  144.     static String textTranslations =
  145.     "#override\n\
  146.     <Key>Return: delta-text-ok()\n\
  147.     <Key>Linefeed: delta-text-ok()\n\
  148.     Ctrl<Key>M: delta-text-ok()\n\
  149.     Ctrl<Key>J: delta-text-ok()\n";
  150.     static XtTranslations trans = None;
  151.  
  152.     if (trans == None) {
  153.     static XtActionsRec act =
  154.     {"delta-text-ok", (XtActionProc) textAction};
  155.  
  156.     XtAppAddActions(XtWidgetToApplicationContext(parent), &act, 1);
  157.  
  158.     trans = XtParseTranslationTable(textTranslations);
  159.     }
  160.     form = XtVaCreateManagedWidget("form", formWidgetClass, parent,
  161.                    XtNborderWidth, 0,
  162.                    XtNfromVert, above,
  163.                    NULL);
  164.     label = XtVaCreateManagedWidget("varianceLabel", labelWidgetClass, form,
  165.                     XtNlabel, title,
  166.                     XtNborderWidth, 0,
  167.                     XtNright, XtChainLeft,
  168.                     XtNleft, XtChainLeft,
  169.                     NULL);
  170.     *bar = XtVaCreateManagedWidget("varianceBar", scrollbarWidgetClass, form,
  171.                    XtNorientation, XtorientHorizontal,
  172.                    XtNwidth, 50,
  173.                    XtNfromHoriz, label,
  174.                    XtNleft, XtChainLeft,
  175.                    NULL);
  176.     *text = XtVaCreateManagedWidget("varianceText", asciiTextWidgetClass, form,
  177.                     XtNfromHoriz, *bar,
  178.                     XtNeditType, XawtextEdit,
  179.                     XtNwrap, XawtextWrapNever,
  180.                     XtNresize, XawtextResizeWidth,
  181.                     XtNtranslations, trans,
  182.                     XtNwidth, 50,
  183.                     XtNlength, 5,
  184.                     XtNstring, "0",
  185.                     NULL);
  186.  
  187.     return form;
  188. }
  189.  
  190. static void 
  191. deltaSP(Widget form, XtPointer data, XtPointer p)
  192. {
  193.     ((DialogInfo *) data)->pixel = (Pixel) p;
  194. }
  195.  
  196. /*
  197.  * Callback for the 'Pixel Delta' button.
  198.  * Grab a colour and calculate the delta relative to the background colour.
  199.  */
  200. static void 
  201. deltaCB(Widget w, DialogInfo * l, XtPointer junk)
  202. {
  203.     XColor *xcol, xcol2;
  204.     int dr, dg, db;
  205.     char buf[20];
  206.  
  207.     xcol = DoGrabColor(w);
  208.  
  209.     xcol2.pixel = l->pixel;
  210.     XQueryColor(XtDisplay(w), l->map->cmap, &xcol2);
  211.  
  212.     dr = xcol->red - xcol2.red;
  213.     dg = xcol->green - xcol2.green;
  214.     db = xcol->blue - xcol2.blue;
  215.     if (dr < 0)
  216.     dr = -dr;
  217.     if (dg < 0)
  218.     dg = -dg;
  219.     if (db < 0)
  220.     db = -db;
  221.  
  222.     l->vr = (float) ((dr >> 8) & 0xff) / 255.0;
  223.     l->vg = (float) ((dg >> 8) & 0xff) / 255.0;
  224.     l->vb = (float) ((db >> 8) & 0xff) / 255.0;
  225.  
  226.     sprintf(buf, "%d", (int) (255 * l->vr));
  227.     XtVaSetValues(l->redText, XtNstring, buf, NULL);
  228.     XawScrollbarSetThumb(l->redBar, l->vr, -1.0);
  229.     sprintf(buf, "%d", (int) (255 * l->vg));
  230.     XtVaSetValues(l->greenText, XtNstring, buf, NULL);
  231.     XawScrollbarSetThumb(l->greenBar, l->vg, -1.0);
  232.     sprintf(buf, "%d", (int) (255 * l->vb));
  233.     XtVaSetValues(l->blueText, XtNstring, buf, NULL);
  234.     XawScrollbarSetThumb(l->blueBar, l->vb, -1.0);
  235. }
  236.  
  237. static void 
  238. applyCB(Widget w, DialogInfo * l, XtPointer junk)
  239. {
  240.     XColor xcol;
  241.     int t;
  242.  
  243.     xcol.pixel = l->pixel;
  244.     xcol.flags = DoRed | DoGreen | DoBlue;
  245.     XQueryColor(XtDisplay(w), l->map->cmap, &xcol);
  246.  
  247.     backgroundRGB[0] = (xcol.red >> 8) & 0xff;
  248.     backgroundRGB[1] = (xcol.green >> 8) & 0xff;
  249.     backgroundRGB[2] = (xcol.blue >> 8) & 0xff;
  250.  
  251. #define STUFF(src, dst) \
  252.     t = (src) * 255.0; if (t < 0) t = 0; else if (t > 255) t = 255; dst = t
  253.  
  254.     STUFF(l->vr, varianceRGB[0]);
  255.     STUFF(l->vg, varianceRGB[1]);
  256.     STUFF(l->vb, varianceRGB[2]);
  257.  
  258. #undef STUFF
  259.  
  260. #if RANGEBUTTONS
  261.     t = ((int) XawToggleGetCurrent(l->mode)) - 1;
  262.     OperationSelectCallAcross(t);
  263.     SelectSetCutMode(t);
  264. #endif
  265. }
  266.  
  267. static void 
  268. okCB(Widget w, DialogInfo * l, XtPointer junk)
  269. {
  270.     applyCB(w, l, junk);
  271.     closePopup(w, GetShell(w));
  272. }
  273.  
  274. void 
  275. ChromaDialog(Widget w, Palette * map)
  276. {
  277.     Widget topform, form, cpick, ok, cancel, apply;
  278.     Widget above;
  279.     DialogInfo *l = dInfo;
  280. #if RANGEBUTTONS
  281.     Widget label, tog;
  282.     int cutmode = SelectGetCutMode();
  283. #endif
  284.  
  285.     if (l != NULL && l->shell != None) {
  286. #if RANGEBUTTONS
  287.     XawToggleSetCurrent(l->mode, (XtPointer) (cutmode + 1));
  288. #endif
  289.     /*
  290.      * If the canvas has another colour map than the ColorPicker,
  291.      * update the ColorPicker's map (unless it is a TrueColor map)
  292.      */
  293.     if ((map != l->map) && (l->map->isMapped)) {
  294.         ColorPickerUpdateMap(l->cpick, map);
  295.         l->map = map;
  296.         XtVaSetValues(l->shell, XtNcolormap, map->cmap, NULL);
  297.     }
  298.     XtPopup(l->shell, XtGrabNone);
  299.     XMapRaised(XtDisplay(l->shell), XtWindow(l->shell));
  300.     return;
  301.     }
  302.     dInfo = l = XtNew(DialogInfo);
  303.  
  304.     l->map = map;
  305.  
  306.     l->r = (float) backgroundRGB[0] / 255.0;
  307.     l->g = (float) backgroundRGB[1] / 255.0;
  308.     l->b = (float) backgroundRGB[2] / 255.0;
  309.     l->vr = (float) varianceRGB[0] / 255.0;
  310.     l->vg = (float) varianceRGB[1] / 255.0;
  311.     l->vb = (float) varianceRGB[2] / 255.0;
  312.  
  313.     l->shell = XtVaCreatePopupShell("chroma", topLevelShellWidgetClass,
  314.                     GetToplevel(w),
  315.                     XtNcolormap, map->cmap,
  316.                     NULL);
  317.  
  318.     topform = XtVaCreateManagedWidget("form", formWidgetClass, l->shell,
  319.                       NULL);
  320.  
  321.     /*
  322.     **  First create the list of toggle buttons for the mode selection
  323.      */
  324. #if RANGEBUTTONS
  325.     form = XtVaCreateManagedWidget("form", formWidgetClass, topform,
  326.                    XtNborderWidth, 0,
  327.                    NULL);
  328.  
  329.     label = XtVaCreateManagedWidget("selectModeLabel", labelWidgetClass, form,
  330.                     XtNborderWidth, 0,
  331.                     NULL);
  332.  
  333.     /*
  334.     **  radioData = mode + 1
  335.      */
  336.     tog = None;
  337.     tog = XtVaCreateManagedWidget("mode0", toggleWidgetClass, form,
  338.                   XtNfromVert, label,
  339.                   XtNradioGroup, tog,
  340.                   XtNradioData, 1,
  341.                   XtNstate, (cutmode == 0),
  342.                   NULL);
  343.     tog = XtVaCreateManagedWidget("mode1", toggleWidgetClass, form,
  344.                   XtNfromVert, tog,
  345.                   XtNradioGroup, tog,
  346.                   XtNradioData, 2,
  347.                   XtNstate, (cutmode == 1),
  348.                   NULL);
  349.     tog = XtVaCreateManagedWidget("mode2", toggleWidgetClass, form,
  350.                   XtNfromVert, tog,
  351.                   XtNradioGroup, tog,
  352.                   XtNradioData, 3,
  353.                   XtNstate, (cutmode == 2),
  354.                   NULL);
  355.     l->mode = tog;
  356. #else
  357.     l->mode = None;
  358. #endif
  359.  
  360.     /*
  361.     **  Now the color chooser.
  362.      */
  363.     form = XtVaCreateManagedWidget("form", formWidgetClass, topform,
  364. #if RANGEBUTTONS
  365.                    XtNfromHoriz, form,
  366. #endif
  367.                    XtNborderWidth, 0,
  368.                    NULL);
  369.  
  370.     l->cpick = cpick = ColorPickerPalette(form, map, NULL);
  371.     l->pixel = ColorPickerGetPixel(cpick);
  372.  
  373.     above = XtVaCreateManagedWidget("delta", commandWidgetClass, form,
  374.                     XtNfromVert, cpick,
  375.                     NULL);
  376.     XtAddCallback(above, XtNcallback, (XtCallbackProc) deltaCB, (XtPointer) l);
  377.     ColorPickerSetFunction(cpick, deltaSP, (XtPointer) l);
  378.  
  379.     above = addSB(form, above, "Red Variance", &l->redBar, &l->redText);
  380.     above = addSB(form, above, "Green Variance", &l->greenBar, &l->greenText);
  381.     above = addSB(form, above, "Blue Variance", &l->blueBar, &l->blueText);
  382.  
  383.     XtAddCallback(l->redBar, XtNjumpProc, (XtCallbackProc) barCB, (XtPointer) l);
  384.     XtAddCallback(l->greenBar, XtNjumpProc,
  385.           (XtCallbackProc) barCB, (XtPointer) l);
  386.     XtAddCallback(l->blueBar, XtNjumpProc,
  387.           (XtCallbackProc) barCB, (XtPointer) l);
  388.  
  389.     AddDestroyCallback(l->shell, (DestroyCallbackFunc) closePopup, l->shell);
  390.  
  391.     ok = XtVaCreateManagedWidget("ok", commandWidgetClass, form,
  392.                  XtNfromVert, above,
  393.                  NULL);
  394.     apply = XtVaCreateManagedWidget("apply", commandWidgetClass, form,
  395.                     XtNfromVert, above,
  396.                     XtNfromHoriz, ok,
  397.                     NULL);
  398.     cancel = XtVaCreateManagedWidget("cancel", commandWidgetClass, form,
  399.                      XtNfromVert, above,
  400.                      XtNfromHoriz, apply,
  401.                      NULL);
  402.     XtAddCallback(cancel, XtNcallback, (XtCallbackProc) closePopup,
  403.           (XtPointer) l->shell);
  404.     XtAddCallback(apply, XtNcallback, (XtCallbackProc) applyCB, (XtPointer) l);
  405.     XtAddCallback(ok, XtNcallback, (XtCallbackProc) okCB, (XtPointer) l);
  406.  
  407.     XtPopup(l->shell, XtGrabNone);
  408. }
  409.  
  410. #if RANGEBUTTONS
  411. void 
  412. ChromaSetCutMode(int value)
  413. {
  414.     if (dInfo != NULL)
  415.     XawToggleSetCurrent(dInfo->mode, (XtPointer) (value + 1));
  416. }
  417. #endif
  418.  
  419. void 
  420. GetChromaBackground(int *rb, int *gb, int *bb)
  421. {
  422.     *rb = backgroundRGB[0];
  423.     *gb = backgroundRGB[1];
  424.     *bb = backgroundRGB[2];
  425. }
  426.  
  427. void 
  428. GetChromaDelta(int *rd, int *gd, int *bd)
  429. {
  430.     *rd = varianceRGB[0];
  431.     *gd = varianceRGB[1];
  432.     *bd = varianceRGB[2];
  433. }