~profzoom/ubuntu/quantal/wmaker/bug-1079925

« back to all changes in this revision

Viewing changes to WINGs/wcolorpanel.c

  • Committer: Bazaar Package Importer
  • Author(s): Marcelo E. Magallon
  • Date: 2004-11-10 14:05:30 UTC
  • Revision ID: james.westby@ubuntu.com-20041110140530-qpd66b5lm38x7apk
Tags: upstream-0.91.0
ImportĀ upstreamĀ versionĀ 0.91.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * ColorPanel for WINGs
 
3
 *
 
4
 * by   ]d                              : Original idea and basic initial code
 
5
 *      Pascal Hofstee                  : Code for wheeldrawing and calculating
 
6
 *                                        colors from it.
 
7
 *                                        Primary coder of this Color Panel.
 
8
 *      Alban Hertroys                  : Optimizations for algorithms for color-
 
9
 *                                        wheel. Also custom ColorPalettes and
 
10
 *                                        magnifying glass. Secondary coder ;)
 
11
 *      Alfredo K. Kojima               : For pointing out memory-allocation
 
12
 *                                        problems and similair code-issues
 
13
 *      Marco van Hylckama-Vlieg        : For once again doing the artwork ;-)
 
14
 *
 
15
 */
 
16
 
 
17
 
 
18
/* TODO:
 
19
 *      -       Look at further optimization of colorWheel matrix calculation.
 
20
 *              It appears to be rather symmetric in angles of 60 degrees,
 
21
 *              while it is optimized in angles of 90 degrees.
 
22
 *      -       Custom color-lists and custom colors in custom color-lists.
 
23
 *      -       Stored colors
 
24
 *      -       Resizing
 
25
 */
 
26
 
 
27
#include "wconfig.h"
 
28
#include "WINGsP.h"
 
29
#include <math.h>
 
30
#include <unistd.h>
 
31
#include <ctype.h>
 
32
#include <fcntl.h>
 
33
#include <sys/types.h>
 
34
#include <sys/stat.h>
 
35
#include <dirent.h>
 
36
#include <errno.h>
 
37
 
 
38
/* BUG There's something fishy with shaped windows */
 
39
/* Whithout shape extension the magnified image is completely broken -Dan */
 
40
#if 0
 
41
# ifdef SHAPE
 
42
#  define SHAPE_WAS_DEFINED
 
43
#  undef SHAPE
 
44
# endif
 
45
#endif
 
46
 
 
47
 
 
48
#ifdef SHAPE
 
49
# include <X11/extensions/shape.h>
 
50
#endif
 
51
 
 
52
 
 
53
#ifndef PATH_MAX
 
54
# define PATH_MAX       1024
 
55
#endif
 
56
 
 
57
 
 
58
char *WMColorPanelColorChangedNotification = "WMColorPanelColorChangedNotification";
 
59
 
 
60
 
 
61
/*
 
62
 * Bitmaps for magnifying glass cursor
 
63
 */
 
64
 
 
65
/* Cursor */
 
66
#define Cursor_x_hot 11
 
67
#define Cursor_y_hot 11
 
68
#define Cursor_width 32
 
69
#define Cursor_height 32
 
70
static unsigned char Cursor_bits[] = {
 
71
    0x00,0x7e,0x00,0x00,0xc0,0x81,0x03,0x00,0x20,0x00,0x04,0x00,0x10,0x00,0x08,
 
72
    0x00,0x08,0x00,0x10,0x00,0x04,0x00,0x20,0x00,0x02,0x00,0x40,0x00,0x02,0x00,
 
73
    0x40,0x00,0x02,0x00,0x40,0x00,0x01,0x42,0x80,0x00,0x01,0x24,0x80,0x00,0x01,
 
74
    0x00,0x80,0x00,0x01,0x00,0x80,0x00,0x01,0x24,0x80,0x00,0x01,0x42,0x80,0x00,
 
75
    0x02,0x00,0x40,0x00,0x02,0x00,0x40,0x00,0x02,0x00,0x40,0x00,0x04,0x00,0x20,
 
76
    0x00,0x08,0x00,0x50,0x00,0x10,0x00,0x88,0x00,0x20,0x00,0x5c,0x01,0xc0,0x81,
 
77
    0x3b,0x02,0x00,0x7e,0x70,0x05,0x00,0x00,0xe0,0x08,0x00,0x00,0xc0,0x15,0x00,
 
78
    0x00,0x80,0x23,0x00,0x00,0x00,0x57,0x00,0x00,0x00,0x8e,0x00,0x00,0x00,0x5c,
 
79
    0x00,0x00,0x00,0xb8,0x00,0x00,0x00,0x70};
 
80
 
 
81
/* Cursor shape-mask */
 
82
#define Cursor_shape_width 32
 
83
#define Cursor_shape_height 32
 
84
static unsigned char Cursor_shape_bits[] = {
 
85
    0x00,0x7e,0x00,0x00,0xc0,0x81,0x03,0x00,0x20,0x00,0x04,0x00,0x10,0x00,0x08,
 
86
    0x00,0x08,0x00,0x10,0x00,0x04,0x00,0x20,0x00,0x02,0x00,0x40,0x00,0x02,0x00,
 
87
    0x40,0x00,0x02,0x00,0x40,0x00,0x01,0x42,0x80,0x00,0x01,0x24,0x80,0x00,0x01,
 
88
    0x00,0x80,0x00,0x01,0x00,0x80,0x00,0x01,0x24,0x80,0x00,0x01,0x42,0x80,0x00,
 
89
    0x02,0x00,0x40,0x00,0x02,0x00,0x40,0x00,0x02,0x00,0x40,0x00,0x04,0x00,0x20,
 
90
    0x00,0x08,0x00,0x70,0x00,0x10,0x00,0xf8,0x00,0x20,0x00,0xfc,0x01,0xc0,0x81,
 
91
    0xfb,0x03,0x00,0x7e,0xf0,0x07,0x00,0x00,0xe0,0x0f,0x00,0x00,0xc0,0x1f,0x00,
 
92
    0x00,0x80,0x3f,0x00,0x00,0x00,0x7f,0x00,0x00,0x00,0xfe,0x00,0x00,0x00,0xfc,
 
93
    0x00,0x00,0x00,0xf8,0x00,0x00,0x00,0x70};
 
94
 
 
95
/* Clip-mask for magnified pixels */
 
96
#define Cursor_mask_width 24
 
97
#define Cursor_mask_height 24
 
98
static unsigned char Cursor_mask_bits[] = {
 
99
    0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0xc0, 0xff, 0x03, 0xe0, 0xff, 0x07,
 
100
    0xf0, 0xff, 0x0f, 0xf8, 0xff, 0x1f, 0xfc, 0xff, 0x3f, 0xfc, 0xff, 0x3f,
 
101
    0xfc, 0xff, 0x3f, 0xfe, 0xff, 0x7f, 0xfe, 0xff, 0x7f, 0xfe, 0xff, 0x7f,
 
102
    0xfe, 0xff, 0x7f, 0xfe, 0xff, 0x7f, 0xfe, 0xff, 0x7f, 0xfc, 0xff, 0x3f,
 
103
    0xfc, 0xff, 0x3f, 0xfc, 0xff, 0x3f, 0xf8, 0xff, 0x1f, 0xf0, 0xff, 0x0f,
 
104
    0xe0, 0xff, 0x07, 0xc0, 0xff, 0x03, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00};
 
105
 
 
106
 
 
107
typedef struct MovingView {
 
108
    WMView      *view;          /* The view this is all about */
 
109
    XImage      *image;         /* What's under the view */
 
110
    XImage      *dirtyRect;     /* Storage of overlapped image area */
 
111
    Pixmap      magPix;         /* Magnified part of pixmap */
 
112
    RColor      color;          /* Color of a pixel in the image */
 
113
    int         x, y;           /* Position of view */
 
114
} MovingView;
 
115
 
 
116
typedef struct CPColor {
 
117
    RColor      rgb;            /* The RGB values of the color  */
 
118
    RHSVColor   hsv;            /* The HSV values of the color  */
 
119
    enum {                      /* Which one was last set ?     */
 
120
        cpNone,
 
121
        cpRGB,
 
122
        cpHSV
 
123
    } set;
 
124
} CPColor;
 
125
 
 
126
 
 
127
typedef struct WheelMatrix {
 
128
    unsigned int        width, height;  /* Size of the colorwheel */
 
129
    unsigned char       *data[3];       /* Wheel data (R,G,B) */
 
130
    unsigned char       values[256];    /* Precalculated values R,G & B = 0-255 */
 
131
} wheelMatrix;
 
132
 
 
133
typedef struct W_ColorPanel {
 
134
    WMWindow    *win;
 
135
    WMFont      *font8;
 
136
    WMFont      *font12;
 
137
    void        *clientData;
 
138
    WMAction2   *action;
 
139
 
 
140
    /* Common Stuff */
 
141
    WMColorWell *colorWell;
 
142
    WMButton    *magnifyBtn;
 
143
    WMButton    *wheelBtn;
 
144
    WMButton    *slidersBtn;
 
145
    WMButton    *customPaletteBtn;
 
146
    WMButton    *colorListBtn;
 
147
 
 
148
    /* Magnifying Glass */
 
149
    MovingView  *magnifyGlass;
 
150
 
 
151
    /* ColorWheel Panel */
 
152
    WMFrame     *wheelFrm;
 
153
    WMSlider    *wheelBrightnessS;
 
154
    WMView      *wheelView;
 
155
 
 
156
    /* Slider Panels */
 
157
    WMFrame     *slidersFrm;
 
158
    WMFrame     *seperatorFrm;
 
159
    WMButton    *grayBtn;
 
160
    WMButton    *rgbBtn;
 
161
    WMButton    *cmykBtn;
 
162
    WMButton    *hsbBtn;
 
163
    /* Gray Scale Panel */
 
164
    WMFrame     *grayFrm;
 
165
    WMLabel     *grayMinL;
 
166
    WMLabel     *grayMaxL;
 
167
    WMSlider    *grayBrightnessS;
 
168
    WMTextField *grayBrightnessT;
 
169
    WMButton    *grayPresetBtn[7];
 
170
 
 
171
    /* RGB Panel */
 
172
    WMFrame     *rgbFrm;
 
173
    WMLabel     *rgbMinL;
 
174
    WMLabel     *rgbMaxL;
 
175
    WMSlider    *rgbRedS;
 
176
    WMSlider    *rgbGreenS;
 
177
    WMSlider    *rgbBlueS;
 
178
    WMTextField *rgbRedT;
 
179
    WMTextField *rgbGreenT;
 
180
    WMTextField *rgbBlueT;
 
181
 
 
182
    /* CMYK Panel */
 
183
    WMFrame     *cmykFrm;
 
184
    WMLabel     *cmykMinL;
 
185
    WMLabel     *cmykMaxL;
 
186
    WMSlider    *cmykCyanS;
 
187
    WMSlider    *cmykMagentaS;
 
188
    WMSlider    *cmykYellowS;
 
189
    WMSlider    *cmykBlackS;
 
190
    WMTextField *cmykCyanT;
 
191
    WMTextField *cmykMagentaT;
 
192
    WMTextField *cmykYellowT;
 
193
    WMTextField *cmykBlackT;
 
194
 
 
195
    /* HSB Panel */
 
196
    WMFrame     *hsbFrm;
 
197
    WMSlider    *hsbHueS;
 
198
    WMSlider    *hsbSaturationS;
 
199
    WMSlider    *hsbBrightnessS;
 
200
    WMTextField *hsbHueT;
 
201
    WMTextField *hsbSaturationT;
 
202
    WMTextField *hsbBrightnessT;
 
203
 
 
204
    /* Custom Palette Panel*/
 
205
    WMFrame             *customPaletteFrm;
 
206
    WMPopUpButton       *customPaletteHistoryBtn;
 
207
    WMFrame             *customPaletteContentFrm;
 
208
    WMPopUpButton       *customPaletteMenuBtn;
 
209
    WMView              *customPaletteContentView;
 
210
 
 
211
    /* Color List Panel */
 
212
    WMFrame             *colorListFrm;
 
213
    WMPopUpButton       *colorListHistoryBtn;
 
214
    WMList              *colorListContentLst;
 
215
    WMPopUpButton       *colorListColorMenuBtn;
 
216
    WMPopUpButton       *colorListListMenuBtn;
 
217
 
 
218
    /* Look-Up Tables and Images */
 
219
    wheelMatrix *wheelMtrx;
 
220
    Pixmap              wheelImg;
 
221
    Pixmap              selectionImg;
 
222
    Pixmap              selectionBackImg;
 
223
    RImage              *customPaletteImg;
 
224
    char                *lastBrowseDir;
 
225
 
 
226
    /* Common Data Fields */
 
227
    CPColor             color;          /* Current color */
 
228
    WMColorPanelMode    mode;           /* Current color selection mode */
 
229
    WMColorPanelMode    slidersmode;    /* Current color sel. mode sliders panel */
 
230
    WMColorPanelMode    lastChanged;    /* Panel that last changed the color */
 
231
    int                 colx, coly;     /* (x,y) of sel.-marker in WheelMode */
 
232
    int                 palx, paly;     /* (x,y) of sel.-marker in
 
233
    CustomPaletteMode */
 
234
    double              palXRatio, palYRatio;   /* Ratios in x & y between
 
235
    original and scaled
 
236
    palettesize */
 
237
    int                 currentPalette;
 
238
    char                *configurationPath;
 
239
 
 
240
    struct {
 
241
        unsigned int    continuous:1;
 
242
        unsigned int    dragging:1;
 
243
    } flags;
 
244
} W_ColorPanel;
 
245
 
 
246
enum {
 
247
    CPmenuNewFromFile,
 
248
    CPmenuRename,
 
249
    CPmenuRemove,
 
250
    CPmenuCopy,
 
251
    CPmenuNewFromClipboard
 
252
} customPaletteMenuItem;
 
253
 
 
254
enum {
 
255
    CLmenuAdd,
 
256
    CLmenuRename,
 
257
    CLmenuRemove
 
258
} colorListMenuItem;
 
259
 
 
260
 
 
261
#define PWIDTH                  194
 
262
#define PHEIGHT                 266
 
263
#define colorWheelSize          150
 
264
#define customPaletteWidth      182
 
265
#define customPaletteHeight     106
 
266
#define knobThickness           8
 
267
 
 
268
#define SPECTRUM_WIDTH          511
 
269
#define SPECTRUM_HEIGHT         360
 
270
 
 
271
#define COLORWHEEL_PART         1
 
272
#define CUSTOMPALETTE_PART      2
 
273
#define BUFSIZE                 1024
 
274
 
 
275
#ifndef RGBTXT
 
276
#define RGBTXT "/usr/X11R6/lib/X11/rgb.txt"
 
277
#endif
 
278
 
 
279
#define MAX_LENGTH  1024
 
280
 
 
281
 
 
282
#ifndef M_PI
 
283
#define M_PI 3.14159265358979323846
 
284
#endif
 
285
 
 
286
/* Silly hack for Windows systems with cygwin */
 
287
#ifndef O_BINARY
 
288
# define O_BINARY 0
 
289
#endif
 
290
 
 
291
static int fetchFile(char* toPath, char *imageSrcFile,
 
292
                     char *imageDestFileName);
 
293
char *generateNewFilename(char *curName);
 
294
void convertCPColor(CPColor *color);
 
295
RColor ulongToRColor(WMScreen *scr, unsigned long value);
 
296
unsigned char getShift(unsigned char value);
 
297
 
 
298
static void modeButtonCallback(WMWidget *w, void *data);
 
299
static int getPickerPart(W_ColorPanel *panel, int x, int y);
 
300
static void readConfiguration(W_ColorPanel *panel);
 
301
static void readXColors(W_ColorPanel *panel);
 
302
 
 
303
static void closeWindowCallback(WMWidget *w, void *data);
 
304
 
 
305
static Cursor magnifyGrabPointer(W_ColorPanel *panel);
 
306
static WMPoint magnifyInitialize(W_ColorPanel *panel);
 
307
static void magnifyPutCursor(WMWidget *w, void *data);
 
308
static Pixmap magnifyCreatePixmap(WMColorPanel *panel);
 
309
static void magnifyGetImageStored(W_ColorPanel *panel, int x1, int y1,
 
310
                                  int x2, int y2);
 
311
static XImage* magnifyGetImage(WMScreen *scr, XImage *image, int x, int y,
 
312
                               int w, int h);
 
313
 
 
314
static wheelMatrix* wheelCreateMatrix(unsigned int width , unsigned int height);
 
315
static void wheelDestroyMatrix(wheelMatrix *matrix);
 
316
static void wheelInitMatrix(W_ColorPanel *panel);
 
317
static void wheelCalculateValues(W_ColorPanel *panel, int maxvalue);
 
318
static void wheelRender(W_ColorPanel *panel);
 
319
static Bool wheelInsideColorWheel(W_ColorPanel *panel, unsigned long ofs);
 
320
static void wheelPaint(W_ColorPanel *panel);
 
321
 
 
322
static void wheelHandleEvents(XEvent *event, void *data);
 
323
static void wheelHandleActionEvents(XEvent *event, void *data);
 
324
static void wheelBrightnessSliderCallback(WMWidget *w, void *data);
 
325
static void wheelUpdateSelection(W_ColorPanel *panel);
 
326
static void wheelUndrawSelection(W_ColorPanel *panel);
 
327
 
 
328
static void wheelPositionSelection(W_ColorPanel *panel, int x, int y);
 
329
static void wheelPositionSelectionOutBounds(W_ColorPanel *panel, int x, int y);
 
330
static void wheelUpdateBrightnessGradientFromLocation (W_ColorPanel *panel);
 
331
static void wheelUpdateBrightnessGradient(W_ColorPanel *panel, CPColor topColor);
 
332
 
 
333
static void grayBrightnessSliderCallback(WMWidget *w, void *data);
 
334
static void grayPresetButtonCallback(WMWidget *w, void *data);
 
335
static void grayBrightnessTextFieldCallback(void *observerData,
 
336
                                            WMNotification *notification);
 
337
 
 
338
static void rgbSliderCallback(WMWidget *w, void *data);
 
339
static void rgbTextFieldCallback(void *observerData,
 
340
                                 WMNotification *notification);
 
341
 
 
342
static void cmykSliderCallback(WMWidget *w, void *data);
 
343
static void cmykTextFieldCallback(void *observerData,
 
344
                                  WMNotification *notification);
 
345
 
 
346
static void hsbSliderCallback(WMWidget *w, void *data);
 
347
static void hsbTextFieldCallback(void *observerData,
 
348
                                 WMNotification *notification);
 
349
static void hsbUpdateBrightnessGradient(W_ColorPanel *panel);
 
350
static void hsbUpdateSaturationGradient(W_ColorPanel *panel);
 
351
static void hsbUpdateHueGradient(W_ColorPanel *panel);
 
352
 
 
353
static void customRenderSpectrum(W_ColorPanel *panel);
 
354
static void customSetPalette(W_ColorPanel *panel);
 
355
static void customPaletteHandleEvents(XEvent *event, void *data);
 
356
static void customPaletteHandleActionEvents(XEvent *event, void *data);
 
357
static void customPalettePositionSelection(W_ColorPanel *panel, int x, int y);
 
358
static void customPalettePositionSelectionOutBounds(W_ColorPanel *panel,
 
359
                                                    int x, int y);
 
360
static void customPaletteMenuCallback(WMWidget *w, void *data);
 
361
static void customPaletteHistoryCallback(WMWidget *w, void *data);
 
362
 
 
363
static void customPaletteMenuNewFromFile(W_ColorPanel *panel);
 
364
static void customPaletteMenuRename(W_ColorPanel *panel);
 
365
static void customPaletteMenuRemove(W_ColorPanel *panel);
 
366
 
 
367
static void colorListPaintItem(WMList *lPtr, int index, Drawable d, char *text,
 
368
                               int state, WMRect *rect);
 
369
static void colorListSelect(WMWidget *w, void *data);
 
370
static void colorListColorMenuCallback(WMWidget *w, void *data);
 
371
static void colorListListMenuCallback(WMWidget *w, void *data);
 
372
static void colorListListMenuNew(W_ColorPanel *panel);
 
373
 
 
374
static void wheelInit(W_ColorPanel *panel);
 
375
static void grayInit(W_ColorPanel *panel);
 
376
static void rgbInit(W_ColorPanel *panel);
 
377
static void cmykInit(W_ColorPanel *panel);
 
378
static void hsbInit(W_ColorPanel *panel);
 
379
 
 
380
 
 
381
 
 
382
void
 
383
WMSetColorPanelAction(WMColorPanel *panel, WMAction2 *action, void *data)
 
384
{
 
385
    panel->action = action;
 
386
    panel->clientData = data;
 
387
}
 
388
 
 
389
static WMColorPanel*
 
390
makeColorPanel(WMScreen *scrPtr, char *name)
 
391
{
 
392
    WMColorPanel        *panel;
 
393
    RImage              *image;
 
394
    WMPixmap            *pixmap;
 
395
    RColor              from;
 
396
    RColor              to;
 
397
    WMColor             *textcolor, *graybuttoncolor;
 
398
    int                 i;
 
399
    GC                  bgc = WMColorGC(scrPtr->black);
 
400
    GC                  wgc = WMColorGC(scrPtr->white);
 
401
 
 
402
 
 
403
    panel = wmalloc(sizeof(WMColorPanel));
 
404
    memset(panel, 0, sizeof(WMColorPanel));
 
405
 
 
406
    panel->color.rgb.red = 0;
 
407
    panel->color.rgb.green = 0;
 
408
    panel->color.rgb.blue = 0;
 
409
    panel->color.hsv.hue = 0;
 
410
    panel->color.hsv.saturation = 0;
 
411
    panel->color.hsv.value = 0;
 
412
    panel->color.set = cpNone;  /* Color has not been set yet */
 
413
 
 
414
    panel->font8 = WMSystemFontOfSize(scrPtr, 8);
 
415
    panel->font12 = WMSystemFontOfSize(scrPtr, 12);
 
416
 
 
417
    panel->win = WMCreateWindowWithStyle(scrPtr, name,
 
418
                                         WMTitledWindowMask | WMClosableWindowMask | WMResizableWindowMask);
 
419
    WMResizeWidget(panel->win, PWIDTH, PHEIGHT);
 
420
    WMSetWindowTitle(panel->win, _("Colors"));
 
421
    WMSetWindowCloseAction(panel->win, closeWindowCallback, panel);
 
422
 
 
423
 
 
424
    /* Set Default ColorPanel Mode(s) */
 
425
    panel->mode = WMWheelModeColorPanel;
 
426
    panel->lastChanged = 0;
 
427
    panel->slidersmode = WMRGBModeColorPanel;
 
428
    panel->configurationPath = wstrconcat(wusergnusteppath(),
 
429
                                          "/Library/Colors/");
 
430
 
 
431
    /* Some General Purpose Widgets */
 
432
    panel->colorWell = WMCreateColorWell(panel->win);
 
433
    WMResizeWidget(panel->colorWell, 134, 36);
 
434
    WSetColorWellBordered(panel->colorWell, False);
 
435
    WMMoveWidget(panel->colorWell, 56, 4);
 
436
 
 
437
    panel->magnifyBtn = WMCreateCustomButton(panel->win,
 
438
                                             WBBStateLightMask|WBBStateChangeMask);
 
439
    WMResizeWidget(panel->magnifyBtn, 46, 36);
 
440
    WMMoveWidget(panel->magnifyBtn, 6,4);
 
441
    WMSetButtonAction(panel->magnifyBtn, magnifyPutCursor, panel);
 
442
    WMSetButtonImagePosition(panel->magnifyBtn, WIPImageOnly);
 
443
    WMSetButtonImage(panel->magnifyBtn, scrPtr->magnifyIcon);
 
444
 
 
445
    panel->wheelBtn = WMCreateCustomButton(panel->win,
 
446
                                           WBBStateLightMask|WBBStateChangeMask);
 
447
    WMResizeWidget(panel->wheelBtn, 46, 32);
 
448
    WMMoveWidget(panel->wheelBtn, 6, 44);
 
449
    WMSetButtonAction(panel->wheelBtn, modeButtonCallback, panel);
 
450
    WMSetButtonImagePosition(panel->wheelBtn, WIPImageOnly);
 
451
    WMSetButtonImage(panel->wheelBtn, scrPtr->wheelIcon);
 
452
 
 
453
    panel->slidersBtn = WMCreateCustomButton(panel->win,
 
454
                                             WBBStateLightMask|WBBStateChangeMask);
 
455
    WMResizeWidget(panel->slidersBtn, 46, 32);
 
456
    WMMoveWidget(panel->slidersBtn, 52, 44);
 
457
    WMSetButtonAction(panel->slidersBtn, modeButtonCallback, panel);
 
458
    WMSetButtonImagePosition(panel->slidersBtn, WIPImageOnly);
 
459
    WMSetButtonImage(panel->slidersBtn, scrPtr->rgbIcon);
 
460
 
 
461
    panel->customPaletteBtn = WMCreateCustomButton(panel->win,
 
462
                                                   WBBStateLightMask|WBBStateChangeMask);
 
463
    WMResizeWidget(panel->customPaletteBtn, 46, 32);
 
464
    WMMoveWidget(panel->customPaletteBtn, 98, 44);
 
465
    WMSetButtonAction(panel->customPaletteBtn, modeButtonCallback, panel);
 
466
    WMSetButtonImagePosition(panel->customPaletteBtn, WIPImageOnly);
 
467
    WMSetButtonImage(panel->customPaletteBtn, scrPtr->customPaletteIcon);
 
468
 
 
469
    panel->colorListBtn = WMCreateCustomButton(panel->win,
 
470
                                               WBBStateLightMask|WBBStateChangeMask);
 
471
    WMResizeWidget(panel->colorListBtn, 46, 32);
 
472
    WMMoveWidget(panel->colorListBtn, 144, 44);
 
473
    WMSetButtonAction(panel->colorListBtn, modeButtonCallback, panel);
 
474
    WMSetButtonImagePosition(panel->colorListBtn, WIPImageOnly);
 
475
    WMSetButtonImage(panel->colorListBtn, scrPtr->colorListIcon);
 
476
 
 
477
    /* Let's Group some of them together */
 
478
    WMGroupButtons(panel->wheelBtn, panel->slidersBtn);
 
479
    WMGroupButtons(panel->wheelBtn, panel->customPaletteBtn);
 
480
    WMGroupButtons(panel->wheelBtn, panel->colorListBtn);
 
481
 
 
482
    /* Widgets for the ColorWheel Panel */
 
483
    panel->wheelFrm = WMCreateFrame(panel->win);
 
484
    WMSetFrameRelief(panel->wheelFrm, WRFlat);
 
485
    WMResizeWidget(panel->wheelFrm, PWIDTH - 8, PHEIGHT - 80 - 26);
 
486
    WMMoveWidget(panel->wheelFrm, 5, 80);
 
487
 
 
488
    panel->wheelView = W_CreateView(W_VIEW(panel->wheelFrm));
 
489
    /* XXX Can we create a view ? */
 
490
    W_ResizeView(panel->wheelView, colorWheelSize+4, colorWheelSize+4);
 
491
    W_MoveView(panel->wheelView, 0, 0);
 
492
 
 
493
    /* Create an event handler to handle expose/click events in ColorWheel */
 
494
    WMCreateEventHandler(panel->wheelView,
 
495
                         ButtonPressMask|ButtonReleaseMask|EnterWindowMask|
 
496
                         LeaveWindowMask|ButtonMotionMask, wheelHandleActionEvents, panel);
 
497
 
 
498
    WMCreateEventHandler(panel->wheelView, ExposureMask, wheelHandleEvents,
 
499
                         panel);
 
500
 
 
501
    panel->wheelBrightnessS = WMCreateSlider(panel->wheelFrm);
 
502
    WMResizeWidget(panel->wheelBrightnessS, 16, 153);
 
503
    WMMoveWidget(panel->wheelBrightnessS, 5+colorWheelSize+14, 1);
 
504
    WMSetSliderMinValue(panel->wheelBrightnessS, 0);
 
505
    WMSetSliderMaxValue(panel->wheelBrightnessS, 255);
 
506
    WMSetSliderAction(panel->wheelBrightnessS, wheelBrightnessSliderCallback,
 
507
                      panel);
 
508
    WMSetSliderKnobThickness(panel->wheelBrightnessS, knobThickness);
 
509
 
 
510
    panel->wheelMtrx = wheelCreateMatrix(colorWheelSize+4, colorWheelSize+4);
 
511
    wheelInitMatrix(panel);
 
512
 
 
513
 
 
514
    /* Widgets for the Slider Panels */
 
515
    panel->slidersFrm = WMCreateFrame(panel->win);
 
516
    WMSetFrameRelief(panel->slidersFrm, WRFlat);
 
517
    WMResizeWidget(panel->slidersFrm, PWIDTH - 8, PHEIGHT - 80 - 26);
 
518
    WMMoveWidget(panel->slidersFrm, 4, 80);
 
519
 
 
520
    panel->seperatorFrm = WMCreateFrame(panel->slidersFrm);
 
521
    WMSetFrameRelief(panel->seperatorFrm, WRPushed);
 
522
    WMResizeWidget(panel->seperatorFrm, PWIDTH - 8, 2);
 
523
    WMMoveWidget(panel->seperatorFrm, 0, 1);
 
524
 
 
525
    panel->grayBtn = WMCreateCustomButton(panel->slidersFrm,
 
526
                                          WBBStateLightMask|WBBStateChangeMask);
 
527
    WMResizeWidget(panel->grayBtn, 46, 24);
 
528
    WMMoveWidget(panel->grayBtn, 1, 8);
 
529
    WMSetButtonAction(panel->grayBtn, modeButtonCallback, panel);
 
530
    WMSetButtonImagePosition(panel->grayBtn, WIPImageOnly);
 
531
    WMSetButtonImage(panel->grayBtn, scrPtr->grayIcon);
 
532
 
 
533
    panel->rgbBtn = WMCreateCustomButton(panel->slidersFrm,
 
534
                                         WBBStateLightMask|WBBStateChangeMask);
 
535
    WMResizeWidget(panel->rgbBtn, 46, 24);
 
536
    WMMoveWidget(panel->rgbBtn, 47, 8);
 
537
    WMSetButtonAction(panel->rgbBtn, modeButtonCallback, panel);
 
538
    WMSetButtonImagePosition(panel->rgbBtn, WIPImageOnly);
 
539
    WMSetButtonImage(panel->rgbBtn, scrPtr->rgbIcon);
 
540
 
 
541
    panel->cmykBtn = WMCreateCustomButton(panel->slidersFrm,
 
542
                                          WBBStateLightMask|WBBStateChangeMask);
 
543
    WMResizeWidget(panel->cmykBtn, 46, 24);
 
544
    WMMoveWidget(panel->cmykBtn, 93, 8);
 
545
    WMSetButtonAction(panel->cmykBtn, modeButtonCallback, panel);
 
546
    WMSetButtonImagePosition(panel->cmykBtn, WIPImageOnly);
 
547
    WMSetButtonImage(panel->cmykBtn, scrPtr->cmykIcon);
 
548
 
 
549
    panel->hsbBtn = WMCreateCustomButton(panel->slidersFrm,
 
550
                                         WBBStateLightMask|WBBStateChangeMask);
 
551
    WMResizeWidget(panel->hsbBtn, 46, 24);
 
552
    WMMoveWidget(panel->hsbBtn, 139, 8);
 
553
    WMSetButtonAction(panel->hsbBtn, modeButtonCallback, panel);
 
554
    WMSetButtonImagePosition(panel->hsbBtn, WIPImageOnly);
 
555
    WMSetButtonImage(panel->hsbBtn, scrPtr->hsbIcon);
 
556
 
 
557
    /* Let's Group the Slider Panel Buttons Together */
 
558
    WMGroupButtons(panel->grayBtn, panel->rgbBtn);
 
559
    WMGroupButtons(panel->grayBtn, panel->cmykBtn);
 
560
    WMGroupButtons(panel->grayBtn, panel->hsbBtn);
 
561
 
 
562
    textcolor = WMDarkGrayColor(scrPtr);
 
563
 
 
564
    /* Widgets for GrayScale Panel */
 
565
    panel->grayFrm = WMCreateFrame(panel->slidersFrm);
 
566
    WMSetFrameRelief(panel->grayFrm, WRFlat);
 
567
    WMResizeWidget(panel->grayFrm, PWIDTH - 8, PHEIGHT - 80 - 26 - 32);
 
568
    WMMoveWidget(panel->grayFrm, 0, 34);
 
569
 
 
570
    panel->grayMinL = WMCreateLabel(panel->grayFrm);
 
571
    WMResizeWidget(panel->grayMinL, 20, 10);
 
572
    WMMoveWidget(panel->grayMinL, 2, 2);
 
573
    WMSetLabelText(panel->grayMinL, "0");
 
574
    WMSetLabelTextAlignment(panel->grayMinL, WALeft);
 
575
    WMSetLabelTextColor(panel->grayMinL, textcolor);
 
576
    WMSetLabelFont(panel->grayMinL, panel->font8);
 
577
 
 
578
    panel->grayMaxL = WMCreateLabel(panel->grayFrm);
 
579
    WMResizeWidget(panel->grayMaxL, 40, 10);
 
580
    WMMoveWidget(panel->grayMaxL, 104, 2);
 
581
    WMSetLabelText(panel->grayMaxL, "100");
 
582
    WMSetLabelTextAlignment(panel->grayMaxL, WARight);
 
583
    WMSetLabelTextColor(panel->grayMaxL, textcolor);
 
584
    WMSetLabelFont(panel->grayMaxL, panel->font8);
 
585
 
 
586
    panel->grayBrightnessS = WMCreateSlider(panel->grayFrm);
 
587
    WMResizeWidget(panel->grayBrightnessS, 141, 16);
 
588
    WMMoveWidget(panel->grayBrightnessS, 2, 14);
 
589
    WMSetSliderMinValue(panel->grayBrightnessS, 0);
 
590
    WMSetSliderMaxValue(panel->grayBrightnessS, 100);
 
591
    WMSetSliderKnobThickness(panel->grayBrightnessS, knobThickness);
 
592
    WMSetSliderAction(panel->grayBrightnessS, grayBrightnessSliderCallback,
 
593
                      panel);
 
594
 
 
595
    from.red = 0;
 
596
    from.green = 0;
 
597
    from.blue = 0;
 
598
 
 
599
    to.red = 255;
 
600
    to.green = 255;
 
601
    to.blue = 255;
 
602
 
 
603
    image = RRenderGradient(141, 16, &from, &to, RGRD_HORIZONTAL);
 
604
    pixmap = WMCreatePixmapFromRImage(scrPtr, image, 0);
 
605
    RReleaseImage(image);
 
606
 
 
607
    if (pixmap)
 
608
        W_PaintText(W_VIEW(panel->grayBrightnessS), pixmap->pixmap,
 
609
                    panel->font12, 2, 0, 100, WALeft, scrPtr->white,
 
610
                    False, _("Brightness"), strlen(_("Brightness")));
 
611
    else
 
612
        wwarning(_("Color Panel: Could not allocate memory"));
 
613
 
 
614
    WMSetSliderImage(panel->grayBrightnessS, pixmap);
 
615
    WMReleasePixmap(pixmap);
 
616
 
 
617
    panel->grayBrightnessT = WMCreateTextField(panel->grayFrm);
 
618
    WMResizeWidget(panel->grayBrightnessT, 40, 18);
 
619
    WMMoveWidget(panel->grayBrightnessT, 146, 13);
 
620
    WMSetTextFieldAlignment(panel->grayBrightnessT, WALeft);
 
621
    WMAddNotificationObserver(grayBrightnessTextFieldCallback, panel,
 
622
                              WMTextDidEndEditingNotification, panel->grayBrightnessT);
 
623
 
 
624
    for (i=0; i < 7; i++) {
 
625
        pixmap = WMCreatePixmap(scrPtr, 13, 13, scrPtr->depth, False);
 
626
 
 
627
        graybuttoncolor = WMCreateRGBColor(scrPtr, (255/6)*i << 8,
 
628
                                           (255/6)*i << 8, (255/6)*i << 8, True);
 
629
        WMPaintColorSwatch(graybuttoncolor, pixmap->pixmap, 0, 0, 15, 15);
 
630
        WMReleaseColor(graybuttoncolor);
 
631
 
 
632
        panel->grayPresetBtn[i] = WMCreateCommandButton(panel->grayFrm);
 
633
        WMResizeWidget(panel->grayPresetBtn[i], 20, 24);
 
634
        WMMoveWidget(panel->grayPresetBtn[i], 2+(i*20), 34);
 
635
        WMSetButtonAction(panel->grayPresetBtn[i],
 
636
                          grayPresetButtonCallback, panel);
 
637
        WMSetButtonImage(panel->grayPresetBtn[i], pixmap);
 
638
        WMSetButtonImagePosition(panel->grayPresetBtn[i], WIPImageOnly);
 
639
        WMReleasePixmap(pixmap);
 
640
 
 
641
    }
 
642
 
 
643
    /* End of GrayScale Panel */
 
644
 
 
645
    /* Widgets for RGB Panel */
 
646
    panel->rgbFrm = WMCreateFrame(panel->slidersFrm);
 
647
    WMSetFrameRelief(panel->rgbFrm, WRFlat);
 
648
    WMResizeWidget(panel->rgbFrm, PWIDTH - 8, PHEIGHT - 80 - 26 - 32);
 
649
    WMMoveWidget(panel->rgbFrm, 0, 34);
 
650
 
 
651
    panel->rgbMinL = WMCreateLabel(panel->rgbFrm);
 
652
    WMResizeWidget(panel->rgbMinL, 20, 10);
 
653
    WMMoveWidget(panel->rgbMinL, 2, 2);
 
654
    WMSetLabelText(panel->rgbMinL, "0");
 
655
    WMSetLabelTextAlignment(panel->rgbMinL, WALeft);
 
656
    WMSetLabelTextColor(panel->rgbMinL, textcolor);
 
657
    WMSetLabelFont(panel->rgbMinL, panel->font8);
 
658
 
 
659
    panel->rgbMaxL = WMCreateLabel(panel->rgbFrm);
 
660
    WMResizeWidget(panel->rgbMaxL, 40, 10);
 
661
    WMMoveWidget(panel->rgbMaxL, 104, 2);
 
662
    WMSetLabelText(panel->rgbMaxL, "255");
 
663
    WMSetLabelTextAlignment(panel->rgbMaxL, WARight);
 
664
    WMSetLabelTextColor(panel->rgbMaxL, textcolor);
 
665
    WMSetLabelFont(panel->rgbMaxL, panel->font8);
 
666
 
 
667
    panel->rgbRedS = WMCreateSlider(panel->rgbFrm);
 
668
    WMResizeWidget(panel->rgbRedS, 141, 16);
 
669
    WMMoveWidget(panel->rgbRedS, 2, 14);
 
670
    WMSetSliderMinValue(panel->rgbRedS, 0);
 
671
    WMSetSliderMaxValue(panel->rgbRedS, 255);
 
672
    WMSetSliderKnobThickness(panel->rgbRedS, knobThickness);
 
673
    WMSetSliderAction(panel->rgbRedS, rgbSliderCallback, panel);
 
674
 
 
675
    to.red = 255;
 
676
    to.green = 0;
 
677
    to.blue = 0;
 
678
 
 
679
    image = RRenderGradient(141, 16, &from, &to, RGRD_HORIZONTAL);
 
680
    pixmap = WMCreatePixmapFromRImage(scrPtr, image, 0);
 
681
    RReleaseImage(image);
 
682
 
 
683
    if (pixmap)
 
684
        W_PaintText(W_VIEW(panel->rgbRedS), pixmap->pixmap, panel->font12,
 
685
                    2, 0, 100, WALeft, scrPtr->white, False, _("Red"),
 
686
                    strlen(_("Red")));
 
687
    else
 
688
        wwarning(_("Color Panel: Could not allocate memory"));
 
689
 
 
690
    WMSetSliderImage(panel->rgbRedS, pixmap);
 
691
    WMReleasePixmap(pixmap);
 
692
 
 
693
    panel->rgbRedT = WMCreateTextField(panel->rgbFrm);
 
694
    WMResizeWidget(panel->rgbRedT, 40, 18);
 
695
    WMMoveWidget(panel->rgbRedT, 146, 13);
 
696
    WMSetTextFieldAlignment(panel->rgbRedT, WALeft);
 
697
    WMAddNotificationObserver(rgbTextFieldCallback, panel,
 
698
                              WMTextDidEndEditingNotification, panel->rgbRedT);
 
699
 
 
700
    panel->rgbGreenS = WMCreateSlider(panel->rgbFrm);
 
701
    WMResizeWidget(panel->rgbGreenS, 141, 16);
 
702
    WMMoveWidget(panel->rgbGreenS, 2, 36);
 
703
    WMSetSliderMinValue(panel->rgbGreenS, 0);
 
704
    WMSetSliderMaxValue(panel->rgbGreenS, 255);
 
705
    WMSetSliderKnobThickness(panel->rgbGreenS, knobThickness);
 
706
    WMSetSliderAction(panel->rgbGreenS, rgbSliderCallback, panel);
 
707
 
 
708
    to.red = 0;
 
709
    to.green = 255;
 
710
    to.blue = 0;
 
711
 
 
712
    image = RRenderGradient(141, 16, &from, &to, RGRD_HORIZONTAL);
 
713
    pixmap = WMCreatePixmapFromRImage(scrPtr, image, 0);
 
714
    RReleaseImage(image);
 
715
 
 
716
    if (pixmap)
 
717
        W_PaintText(W_VIEW(panel->rgbGreenS), pixmap->pixmap, panel->font12,
 
718
                    2, 0, 100, WALeft, scrPtr->white, False, _("Green"),
 
719
                    strlen(_("Green")));
 
720
    else
 
721
        wwarning(_("Color Panel: Could not allocate memory"));
 
722
 
 
723
    WMSetSliderImage(panel->rgbGreenS, pixmap);
 
724
    WMReleasePixmap(pixmap);
 
725
 
 
726
    panel->rgbGreenT = WMCreateTextField(panel->rgbFrm);
 
727
    WMResizeWidget(panel->rgbGreenT, 40, 18);
 
728
    WMMoveWidget(panel->rgbGreenT, 146, 35);
 
729
    WMSetTextFieldAlignment(panel->rgbGreenT, WALeft);
 
730
    WMAddNotificationObserver(rgbTextFieldCallback, panel,
 
731
                              WMTextDidEndEditingNotification, panel->rgbGreenT);
 
732
 
 
733
 
 
734
    panel->rgbBlueS = WMCreateSlider(panel->rgbFrm);
 
735
    WMResizeWidget(panel->rgbBlueS, 141, 16);
 
736
    WMMoveWidget(panel->rgbBlueS, 2, 58);
 
737
    WMSetSliderMinValue(panel->rgbBlueS, 0);
 
738
    WMSetSliderMaxValue(panel->rgbBlueS, 255);
 
739
    WMSetSliderKnobThickness(panel->rgbBlueS, knobThickness);
 
740
    WMSetSliderAction(panel->rgbBlueS, rgbSliderCallback, panel);
 
741
 
 
742
    to.red = 0;
 
743
    to.green = 0;
 
744
    to.blue = 255;
 
745
 
 
746
    image = RRenderGradient(141, 16, &from, &to, RGRD_HORIZONTAL);
 
747
    pixmap = WMCreatePixmapFromRImage(scrPtr, image, 0);
 
748
    RReleaseImage(image);
 
749
 
 
750
    if (pixmap)
 
751
        W_PaintText(W_VIEW(panel->rgbBlueS), pixmap->pixmap, panel->font12,
 
752
                    2, 0, 100, WALeft, scrPtr->white, False, _("Blue"),
 
753
                    strlen(_("Blue")));
 
754
    else
 
755
        wwarning(_("Color Panel: Could not allocate memory"));
 
756
 
 
757
    WMSetSliderImage(panel->rgbBlueS, pixmap);
 
758
    WMReleasePixmap(pixmap);
 
759
 
 
760
    panel->rgbBlueT = WMCreateTextField(panel->rgbFrm);
 
761
    WMResizeWidget(panel->rgbBlueT, 40, 18);
 
762
    WMMoveWidget(panel->rgbBlueT, 146, 57);
 
763
    WMSetTextFieldAlignment(panel->rgbBlueT, WALeft);
 
764
    WMAddNotificationObserver(rgbTextFieldCallback, panel,
 
765
                              WMTextDidEndEditingNotification, panel->rgbBlueT);
 
766
    /* End of RGB Panel */
 
767
 
 
768
    /* Widgets for CMYK Panel */
 
769
    panel->cmykFrm = WMCreateFrame(panel->slidersFrm);
 
770
    WMSetFrameRelief(panel->cmykFrm, WRFlat);
 
771
    WMResizeWidget(panel->cmykFrm, PWIDTH - 8, PHEIGHT - 80 - 26 - 32);
 
772
    WMMoveWidget(panel->cmykFrm, 0, 34);
 
773
 
 
774
    panel->cmykMinL = WMCreateLabel(panel->cmykFrm);
 
775
    WMResizeWidget(panel->cmykMinL, 20, 10);
 
776
    WMMoveWidget(panel->cmykMinL, 2, 2);
 
777
    WMSetLabelText(panel->cmykMinL, "0");
 
778
    WMSetLabelTextAlignment(panel->cmykMinL, WALeft);
 
779
    WMSetLabelTextColor(panel->cmykMinL, textcolor);
 
780
    WMSetLabelFont(panel->cmykMinL, panel->font8);
 
781
 
 
782
    panel->cmykMaxL = WMCreateLabel(panel->cmykFrm);
 
783
    WMResizeWidget(panel->cmykMaxL, 40, 10);
 
784
    WMMoveWidget(panel->cmykMaxL, 104, 2);
 
785
    WMSetLabelText(panel->cmykMaxL, "100");
 
786
    WMSetLabelTextAlignment(panel->cmykMaxL, WARight);
 
787
    WMSetLabelTextColor(panel->cmykMaxL, textcolor);
 
788
    WMSetLabelFont(panel->cmykMaxL, panel->font8);
 
789
 
 
790
    panel->cmykCyanS = WMCreateSlider(panel->cmykFrm);
 
791
    WMResizeWidget(panel->cmykCyanS, 141, 16);
 
792
    WMMoveWidget(panel->cmykCyanS, 2, 14);
 
793
    WMSetSliderMinValue(panel->cmykCyanS, 0);
 
794
    WMSetSliderMaxValue(panel->cmykCyanS, 100);
 
795
    WMSetSliderKnobThickness(panel->cmykCyanS, knobThickness);
 
796
    WMSetSliderAction(panel->cmykCyanS, cmykSliderCallback, panel);
 
797
 
 
798
    from.red = 255;
 
799
    from.green = 255;
 
800
    from.blue = 255;
 
801
 
 
802
    to.red = 0;
 
803
    to.green = 255;
 
804
    to.blue = 255;
 
805
 
 
806
    image = RRenderGradient(141, 16, &from, &to, RGRD_HORIZONTAL);
 
807
    pixmap = WMCreatePixmapFromRImage(scrPtr, image, 0);
 
808
    RReleaseImage(image);
 
809
 
 
810
    if (pixmap)
 
811
        W_PaintText(W_VIEW(panel->cmykCyanS), pixmap->pixmap, panel->font12,
 
812
                    2, 0, 100, WALeft, scrPtr->black, False, _("Cyan"),
 
813
                    strlen(_("Cyan")));
 
814
    else
 
815
        wwarning(_("Color Panel: Could not allocate memory"));
 
816
 
 
817
    WMSetSliderImage(panel->cmykCyanS, pixmap);
 
818
    WMReleasePixmap(pixmap);
 
819
 
 
820
    panel->cmykCyanT = WMCreateTextField(panel->cmykFrm);
 
821
    WMResizeWidget(panel->cmykCyanT, 40, 18);
 
822
    WMMoveWidget(panel->cmykCyanT, 146, 13);
 
823
    WMSetTextFieldAlignment(panel->cmykCyanT, WALeft);
 
824
    WMAddNotificationObserver(cmykTextFieldCallback, panel,
 
825
                              WMTextDidEndEditingNotification, panel->cmykCyanT);
 
826
 
 
827
 
 
828
    panel->cmykMagentaS = WMCreateSlider(panel->cmykFrm);
 
829
    WMResizeWidget(panel->cmykMagentaS, 141, 16);
 
830
    WMMoveWidget(panel->cmykMagentaS, 2, 36);
 
831
    WMSetSliderMinValue(panel->cmykMagentaS, 0);
 
832
    WMSetSliderMaxValue(panel->cmykMagentaS, 100);
 
833
    WMSetSliderKnobThickness(panel->cmykMagentaS, knobThickness);
 
834
    WMSetSliderAction(panel->cmykMagentaS, cmykSliderCallback, panel);
 
835
 
 
836
    to.red = 255;
 
837
    to.green = 0;
 
838
    to.blue = 255;
 
839
 
 
840
    image = RRenderGradient(141, 16, &from, &to, RGRD_HORIZONTAL);
 
841
    pixmap = WMCreatePixmapFromRImage(scrPtr, image, 0);
 
842
    RReleaseImage(image);
 
843
 
 
844
    if (pixmap)
 
845
        W_PaintText(W_VIEW(panel->cmykMagentaS), pixmap->pixmap, panel->font12,
 
846
                    2, 0, 100, WALeft, scrPtr->black, False, _("Magenta"),
 
847
                    strlen(_("Magenta")));
 
848
    else
 
849
        wwarning(_("Color Panel: Could not allocate memory"));
 
850
 
 
851
    WMSetSliderImage(panel->cmykMagentaS, pixmap);
 
852
    WMReleasePixmap(pixmap);
 
853
 
 
854
    panel->cmykMagentaT = WMCreateTextField(panel->cmykFrm);
 
855
    WMResizeWidget(panel->cmykMagentaT, 40, 18);
 
856
    WMMoveWidget(panel->cmykMagentaT, 146, 35);
 
857
    WMSetTextFieldAlignment(panel->cmykMagentaT, WALeft);
 
858
    WMAddNotificationObserver(cmykTextFieldCallback, panel,
 
859
                              WMTextDidEndEditingNotification, panel->cmykMagentaT);
 
860
 
 
861
 
 
862
    panel->cmykYellowS = WMCreateSlider(panel->cmykFrm);
 
863
    WMResizeWidget(panel->cmykYellowS, 141, 16);
 
864
    WMMoveWidget(panel->cmykYellowS, 2, 58);
 
865
    WMSetSliderMinValue(panel->cmykYellowS, 0);
 
866
    WMSetSliderMaxValue(panel->cmykYellowS, 100);
 
867
    WMSetSliderKnobThickness(panel->cmykYellowS, knobThickness);
 
868
    WMSetSliderAction(panel->cmykYellowS, cmykSliderCallback, panel);
 
869
 
 
870
    to.red = 255;
 
871
    to.green = 255;
 
872
    to.blue = 0;
 
873
 
 
874
    image = RRenderGradient(141, 16, &from, &to, RGRD_HORIZONTAL);
 
875
    pixmap = WMCreatePixmapFromRImage(scrPtr, image, 0);
 
876
    RReleaseImage(image);
 
877
 
 
878
    if (pixmap)
 
879
        W_PaintText(W_VIEW(panel->cmykYellowS), pixmap->pixmap, panel->font12,
 
880
                    2, 0, 100, WALeft, scrPtr->black, False, _("Yellow"),
 
881
                    strlen(_("Yellow")));
 
882
    else
 
883
        wwarning(_("Color Panel: Could not allocate memory"));
 
884
 
 
885
    WMSetSliderImage(panel->cmykYellowS, pixmap);
 
886
    WMReleasePixmap(pixmap);
 
887
 
 
888
    panel->cmykYellowT = WMCreateTextField(panel->cmykFrm);
 
889
    WMResizeWidget(panel->cmykYellowT, 40, 18);
 
890
    WMMoveWidget(panel->cmykYellowT, 146, 57);
 
891
    WMSetTextFieldAlignment(panel->cmykYellowT, WALeft);
 
892
    WMAddNotificationObserver(cmykTextFieldCallback, panel,
 
893
                              WMTextDidEndEditingNotification, panel->cmykYellowT);
 
894
 
 
895
 
 
896
    panel->cmykBlackS = WMCreateSlider(panel->cmykFrm);
 
897
    WMResizeWidget(panel->cmykBlackS, 141, 16);
 
898
    WMMoveWidget(panel->cmykBlackS, 2, 80);
 
899
    WMSetSliderMinValue(panel->cmykBlackS, 0);
 
900
    WMSetSliderMaxValue(panel->cmykBlackS, 100);
 
901
    WMSetSliderValue(panel->cmykBlackS, 0);
 
902
    WMSetSliderKnobThickness(panel->cmykBlackS, knobThickness);
 
903
    WMSetSliderAction(panel->cmykBlackS, cmykSliderCallback, panel);
 
904
 
 
905
    to.red = 0;
 
906
    to.green = 0;
 
907
    to.blue = 0;
 
908
 
 
909
    image = RRenderGradient(141, 16, &from, &to, RGRD_HORIZONTAL);
 
910
    pixmap = WMCreatePixmapFromRImage(scrPtr, image, 0);
 
911
    RReleaseImage(image);
 
912
 
 
913
    if (pixmap)
 
914
        W_PaintText(W_VIEW(panel->cmykBlackS), pixmap->pixmap, panel->font12,
 
915
                    2, 0, 100, WALeft, scrPtr->black, False, _("Black"),
 
916
                    strlen(_("Black")));
 
917
    else
 
918
        wwarning(_("Color Panel: Could not allocate memory"));
 
919
 
 
920
    WMSetSliderImage(panel->cmykBlackS, pixmap);
 
921
    WMReleasePixmap(pixmap);
 
922
 
 
923
    panel->cmykBlackT = WMCreateTextField(panel->cmykFrm);
 
924
    WMResizeWidget(panel->cmykBlackT, 40, 18);
 
925
    WMMoveWidget(panel->cmykBlackT, 146, 79);
 
926
    WMSetTextFieldAlignment(panel->cmykBlackT, WALeft);
 
927
    WMAddNotificationObserver(cmykTextFieldCallback, panel,
 
928
                              WMTextDidEndEditingNotification, panel->cmykBlackT);
 
929
    /* End of CMYK Panel */
 
930
 
 
931
    /* Widgets for HSB Panel */
 
932
    panel->hsbFrm = WMCreateFrame(panel->slidersFrm);
 
933
    WMSetFrameRelief(panel->hsbFrm, WRFlat);
 
934
    WMResizeWidget(panel->hsbFrm, PWIDTH - 8, PHEIGHT - 80 - 26 - 32);
 
935
    WMMoveWidget(panel->hsbFrm, 0, 34);
 
936
 
 
937
    panel->hsbHueS = WMCreateSlider(panel->hsbFrm);
 
938
    WMResizeWidget(panel->hsbHueS, 141, 16);
 
939
    WMMoveWidget(panel->hsbHueS, 2, 14);
 
940
    WMSetSliderMinValue(panel->hsbHueS, 0);
 
941
    WMSetSliderMaxValue(panel->hsbHueS, 359);
 
942
    WMSetSliderKnobThickness(panel->hsbHueS, knobThickness);
 
943
    WMSetSliderAction(panel->hsbHueS, hsbSliderCallback, panel);
 
944
 
 
945
    panel->hsbHueT = WMCreateTextField(panel->hsbFrm);
 
946
    WMResizeWidget(panel->hsbHueT, 40, 18);
 
947
    WMMoveWidget(panel->hsbHueT, 146, 13);
 
948
    WMSetTextFieldAlignment(panel->hsbHueT, WALeft);
 
949
    WMAddNotificationObserver(hsbTextFieldCallback, panel,
 
950
                              WMTextDidEndEditingNotification, panel->hsbHueT);
 
951
 
 
952
 
 
953
    panel->hsbSaturationS = WMCreateSlider(panel->hsbFrm);
 
954
    WMResizeWidget(panel->hsbSaturationS, 141, 16);
 
955
    WMMoveWidget(panel->hsbSaturationS, 2, 36);
 
956
    WMSetSliderMinValue(panel->hsbSaturationS, 0);
 
957
    WMSetSliderMaxValue(panel->hsbSaturationS, 100);
 
958
    WMSetSliderKnobThickness(panel->hsbSaturationS, knobThickness);
 
959
    WMSetSliderAction(panel->hsbSaturationS, hsbSliderCallback, panel);
 
960
 
 
961
    panel->hsbSaturationT = WMCreateTextField(panel->hsbFrm);
 
962
    WMResizeWidget(panel->hsbSaturationT, 40, 18);
 
963
    WMMoveWidget(panel->hsbSaturationT, 146, 35);
 
964
    WMSetTextFieldAlignment(panel->hsbSaturationT, WALeft);
 
965
    WMAddNotificationObserver(hsbTextFieldCallback, panel,
 
966
                              WMTextDidEndEditingNotification, panel->hsbSaturationT);
 
967
 
 
968
 
 
969
    panel->hsbBrightnessS = WMCreateSlider(panel->hsbFrm);
 
970
    WMResizeWidget(panel->hsbBrightnessS, 141, 16);
 
971
    WMMoveWidget(panel->hsbBrightnessS, 2, 58);
 
972
    WMSetSliderMinValue(panel->hsbBrightnessS, 0);
 
973
    WMSetSliderMaxValue(panel->hsbBrightnessS, 100);
 
974
    WMSetSliderKnobThickness(panel->hsbBrightnessS, knobThickness);
 
975
    WMSetSliderAction(panel->hsbBrightnessS, hsbSliderCallback, panel);
 
976
 
 
977
    panel->hsbBrightnessT = WMCreateTextField(panel->hsbFrm);
 
978
    WMResizeWidget(panel->hsbBrightnessT, 40, 18);
 
979
    WMMoveWidget(panel->hsbBrightnessT, 146, 57);
 
980
    WMSetTextFieldAlignment(panel->hsbBrightnessT, WALeft);
 
981
    WMAddNotificationObserver(hsbTextFieldCallback, panel,
 
982
                              WMTextDidEndEditingNotification, panel->hsbBrightnessT);
 
983
    /* End of HSB Panel */
 
984
 
 
985
 
 
986
    WMReleaseColor(textcolor);
 
987
 
 
988
    /* Widgets for the CustomPalette Panel */
 
989
    panel->customPaletteFrm = WMCreateFrame(panel->win);
 
990
    WMSetFrameRelief(panel->customPaletteFrm, WRFlat);
 
991
    WMResizeWidget(panel->customPaletteFrm, PWIDTH - 8, PHEIGHT - 80 - 26);
 
992
    WMMoveWidget(panel->customPaletteFrm, 5, 80);
 
993
 
 
994
    panel->customPaletteHistoryBtn = WMCreatePopUpButton(
 
995
                                                         panel->customPaletteFrm);
 
996
    WMAddPopUpButtonItem(panel->customPaletteHistoryBtn, _("Spectrum"));
 
997
    WMSetPopUpButtonSelectedItem(panel->customPaletteHistoryBtn,
 
998
                                 WMGetPopUpButtonNumberOfItems(panel->customPaletteHistoryBtn)-1);
 
999
    WMSetPopUpButtonAction(panel->customPaletteHistoryBtn,
 
1000
                           customPaletteHistoryCallback, panel);
 
1001
    WMResizeWidget(panel->customPaletteHistoryBtn, PWIDTH - 8, 20);
 
1002
    WMMoveWidget(panel->customPaletteHistoryBtn, 0, 0);
 
1003
 
 
1004
    panel->customPaletteContentFrm = WMCreateFrame(panel->customPaletteFrm);
 
1005
    WMSetFrameRelief(panel->customPaletteContentFrm, WRSunken);
 
1006
    WMResizeWidget(panel->customPaletteContentFrm, PWIDTH - 8, PHEIGHT - 156);
 
1007
    WMMoveWidget(panel->customPaletteContentFrm, 0, 23);
 
1008
 
 
1009
    panel->customPaletteContentView = W_CreateView(
 
1010
                                                   W_VIEW(panel->customPaletteContentFrm));
 
1011
    /* XXX Test if we can create a view */
 
1012
    W_ResizeView(panel->customPaletteContentView, customPaletteWidth,
 
1013
                 customPaletteHeight);
 
1014
    W_MoveView(panel->customPaletteContentView, 2, 2);
 
1015
 
 
1016
    /* Create event handler to handle expose/click events in CustomPalette */
 
1017
    WMCreateEventHandler(panel->customPaletteContentView,
 
1018
                         ButtonPressMask|ButtonReleaseMask|EnterWindowMask| LeaveWindowMask |
 
1019
                         ButtonMotionMask, customPaletteHandleActionEvents, panel);
 
1020
 
 
1021
    WMCreateEventHandler(panel->customPaletteContentView, ExposureMask,
 
1022
                         customPaletteHandleEvents, panel);
 
1023
 
 
1024
    panel->customPaletteMenuBtn = WMCreatePopUpButton(panel->customPaletteFrm);
 
1025
    WMSetPopUpButtonPullsDown(panel->customPaletteMenuBtn, 1);
 
1026
    WMSetPopUpButtonText(panel->customPaletteMenuBtn, _("Palette"));
 
1027
    WMSetPopUpButtonAction(panel->customPaletteMenuBtn,
 
1028
                           customPaletteMenuCallback, panel);
 
1029
    WMResizeWidget(panel->customPaletteMenuBtn, PWIDTH - 8, 20);
 
1030
    WMMoveWidget(panel->customPaletteMenuBtn, 0, PHEIGHT - 130);
 
1031
 
 
1032
    WMAddPopUpButtonItem(panel->customPaletteMenuBtn, _("New from File..."));
 
1033
    WMAddPopUpButtonItem(panel->customPaletteMenuBtn, _("Rename..."));
 
1034
    WMAddPopUpButtonItem(panel->customPaletteMenuBtn, _("Remove"));
 
1035
    WMAddPopUpButtonItem(panel->customPaletteMenuBtn, _("Copy"));
 
1036
    WMAddPopUpButtonItem(panel->customPaletteMenuBtn, _("New from Clipboard"));
 
1037
 
 
1038
    WMSetPopUpButtonItemEnabled(panel->customPaletteMenuBtn, CPmenuRename, 0);
 
1039
    WMSetPopUpButtonItemEnabled(panel->customPaletteMenuBtn, CPmenuRemove, 0);
 
1040
    WMSetPopUpButtonItemEnabled(panel->customPaletteMenuBtn, CPmenuCopy, 0);
 
1041
    WMSetPopUpButtonItemEnabled(panel->customPaletteMenuBtn,
 
1042
                                CPmenuNewFromClipboard, 0);
 
1043
 
 
1044
    customRenderSpectrum(panel);
 
1045
    panel->currentPalette = 0;
 
1046
    panel->palx = customPaletteWidth/2;
 
1047
    panel->paly = customPaletteHeight/2;
 
1048
 
 
1049
 
 
1050
    /* Widgets for the ColorList Panel */
 
1051
    panel->colorListFrm = WMCreateFrame(panel->win);
 
1052
    WMSetFrameRelief(panel->colorListFrm, WRFlat);
 
1053
    WMResizeWidget(panel->colorListFrm, PWIDTH - 8, PHEIGHT - 80 - 26);
 
1054
    WMMoveWidget(panel->colorListFrm, 5, 80);
 
1055
 
 
1056
    panel->colorListHistoryBtn = WMCreatePopUpButton(panel->colorListFrm);
 
1057
    WMAddPopUpButtonItem(panel->colorListHistoryBtn, _("X11-Colors"));
 
1058
    WMSetPopUpButtonSelectedItem(panel->colorListHistoryBtn,
 
1059
                                 WMGetPopUpButtonNumberOfItems(panel->colorListHistoryBtn)-1);
 
1060
    /*  WMSetPopUpButtonAction(panel->colorListHistoryBtn,
 
1061
     *  colorListHistoryCallback, panel); */
 
1062
    WMResizeWidget(panel->colorListHistoryBtn, PWIDTH - 8, 20);
 
1063
    WMMoveWidget(panel->colorListHistoryBtn, 0, 0);
 
1064
 
 
1065
    panel->colorListContentLst = WMCreateList(panel->colorListFrm);
 
1066
    WMSetListAction(panel->colorListContentLst, colorListSelect, panel);
 
1067
    WMSetListUserDrawProc(panel->colorListContentLst, colorListPaintItem);
 
1068
    WMResizeWidget(panel->colorListContentLst, PWIDTH - 8, PHEIGHT - 156);
 
1069
    WMMoveWidget(panel->colorListContentLst, 0, 23);
 
1070
    WMHangData(panel->colorListContentLst, panel);
 
1071
 
 
1072
    panel->colorListColorMenuBtn = WMCreatePopUpButton(panel->colorListFrm);
 
1073
    WMSetPopUpButtonPullsDown(panel->colorListColorMenuBtn, 1);
 
1074
    WMSetPopUpButtonText(panel->colorListColorMenuBtn, _("Color"));
 
1075
    WMSetPopUpButtonAction(panel->colorListColorMenuBtn,
 
1076
                           colorListColorMenuCallback, panel);
 
1077
    WMResizeWidget(panel->colorListColorMenuBtn, (PWIDTH - 16)/2, 20);
 
1078
    WMMoveWidget(panel->colorListColorMenuBtn, 0, PHEIGHT - 130);
 
1079
 
 
1080
    WMAddPopUpButtonItem(panel->colorListColorMenuBtn, _("Add..."));
 
1081
    WMAddPopUpButtonItem(panel->colorListColorMenuBtn, _("Rename..."));
 
1082
    WMAddPopUpButtonItem(panel->colorListColorMenuBtn, _("Remove"));
 
1083
 
 
1084
    WMSetPopUpButtonItemEnabled(panel->colorListColorMenuBtn, CLmenuAdd, 0);
 
1085
    WMSetPopUpButtonItemEnabled(panel->colorListColorMenuBtn, CLmenuRename, 0);
 
1086
    WMSetPopUpButtonItemEnabled(panel->colorListColorMenuBtn, CLmenuRemove, 0);
 
1087
 
 
1088
    panel->colorListListMenuBtn = WMCreatePopUpButton(panel->colorListFrm);
 
1089
    WMSetPopUpButtonPullsDown(panel->colorListListMenuBtn, 1);
 
1090
    WMSetPopUpButtonText(panel->colorListListMenuBtn, _("List"));
 
1091
    WMSetPopUpButtonAction(panel->colorListListMenuBtn,
 
1092
                           colorListListMenuCallback, panel);
 
1093
    WMResizeWidget(panel->colorListListMenuBtn, (PWIDTH - 16)/2, 20);
 
1094
    WMMoveWidget(panel->colorListListMenuBtn, (PWIDTH - 16)/2 + 8,
 
1095
                 PHEIGHT - 130);
 
1096
 
 
1097
    WMAddPopUpButtonItem(panel->colorListListMenuBtn, _("New..."));
 
1098
    WMAddPopUpButtonItem(panel->colorListListMenuBtn, _("Rename..."));
 
1099
    WMAddPopUpButtonItem(panel->colorListListMenuBtn, _("Remove"));
 
1100
 
 
1101
    WMSetPopUpButtonItemEnabled(panel->colorListListMenuBtn, CLmenuAdd, 0);
 
1102
    WMSetPopUpButtonItemEnabled(panel->colorListListMenuBtn, CLmenuRename, 0);
 
1103
    WMSetPopUpButtonItemEnabled(panel->colorListListMenuBtn, CLmenuRemove, 0);
 
1104
 
 
1105
    WMRealizeWidget(panel->win);
 
1106
    WMMapSubwidgets(panel->win);
 
1107
 
 
1108
    WMMapSubwidgets(panel->wheelFrm);
 
1109
    WMMapSubwidgets(panel->slidersFrm);
 
1110
    WMMapSubwidgets(panel->grayFrm);
 
1111
    WMMapSubwidgets(panel->rgbFrm);
 
1112
    WMMapSubwidgets(panel->cmykFrm);
 
1113
    WMMapSubwidgets(panel->hsbFrm);
 
1114
    WMMapSubwidgets(panel->customPaletteFrm);
 
1115
    WMMapSubwidgets(panel->customPaletteContentFrm);
 
1116
    WMMapSubwidgets(panel->colorListFrm);
 
1117
 
 
1118
    /* Pixmap to indicate selection positions
 
1119
     * wheelframe MUST be mapped.
 
1120
     */
 
1121
    panel->selectionImg = XCreatePixmap(scrPtr->display,
 
1122
                                        WMWidgetXID(panel->win), 4, 4, scrPtr->depth);
 
1123
    XFillRectangle(scrPtr->display, panel->selectionImg, bgc, 0, 0, 4, 4);
 
1124
    XFillRectangle(scrPtr->display, panel->selectionImg, wgc, 1, 1, 2, 2);
 
1125
 
 
1126
    readConfiguration(panel);
 
1127
    readXColors(panel);
 
1128
 
 
1129
    return panel;
 
1130
}
 
1131
 
 
1132
 
 
1133
WMColorPanel*
 
1134
WMGetColorPanel(WMScreen *scrPtr)
 
1135
{
 
1136
    WMColorPanel        *panel;
 
1137
 
 
1138
    if (scrPtr->sharedColorPanel)
 
1139
        return scrPtr->sharedColorPanel;
 
1140
 
 
1141
    panel = makeColorPanel(scrPtr, "colorPanel");
 
1142
 
 
1143
    scrPtr->sharedColorPanel = panel;
 
1144
 
 
1145
    return panel;
 
1146
}
 
1147
 
 
1148
 
 
1149
void
 
1150
WMFreeColorPanel(WMColorPanel *panel)
 
1151
{
 
1152
    W_Screen    *scr = WMWidgetScreen(panel->win);
 
1153
 
 
1154
    if (panel == scr->sharedColorPanel) {
 
1155
        scr->sharedColorPanel = NULL;
 
1156
    }
 
1157
 
 
1158
    if (!panel)
 
1159
        return;
 
1160
 
 
1161
    WMRemoveNotificationObserver(panel);
 
1162
    WMUnmapWidget(panel->win);
 
1163
 
 
1164
    /* fonts */
 
1165
    WMReleaseFont(panel->font8);
 
1166
    WMReleaseFont(panel->font12);
 
1167
 
 
1168
    /* pixmaps */
 
1169
    wheelDestroyMatrix(panel->wheelMtrx);
 
1170
    if (panel->wheelImg)
 
1171
        XFreePixmap(scr->display, panel->wheelImg);
 
1172
    if (panel->selectionImg)
 
1173
        XFreePixmap(scr->display, panel->selectionImg);
 
1174
    if (panel->selectionBackImg)
 
1175
        XFreePixmap(scr->display, panel->selectionBackImg);
 
1176
    RReleaseImage(panel->customPaletteImg);
 
1177
 
 
1178
    /* structs */
 
1179
    if (panel->lastBrowseDir)
 
1180
        wfree(panel->lastBrowseDir);
 
1181
    if (panel->configurationPath)
 
1182
        wfree(panel->configurationPath);
 
1183
 
 
1184
    WMDestroyWidget(panel->win);
 
1185
 
 
1186
    wfree(panel);
 
1187
}
 
1188
 
 
1189
 
 
1190
void
 
1191
WMCloseColorPanel(WMColorPanel *panel)
 
1192
{
 
1193
    WMFreeColorPanel(panel);
 
1194
}
 
1195
 
 
1196
 
 
1197
void
 
1198
WMShowColorPanel(WMColorPanel *panel)
 
1199
{
 
1200
    WMScreen    *scr = WMWidgetScreen(panel->win);
 
1201
    WMColor     *white = WMWhiteColor(scr);
 
1202
 
 
1203
    if (panel->color.set == cpNone)
 
1204
        WMSetColorPanelColor(panel, white);
 
1205
    WMReleaseColor(white);
 
1206
 
 
1207
    if (panel->mode != WMWheelModeColorPanel)
 
1208
        WMPerformButtonClick(panel->wheelBtn);
 
1209
 
 
1210
    WMMapWidget(panel->win);
 
1211
}
 
1212
 
 
1213
 
 
1214
static void
 
1215
closeWindowCallback(WMWidget *w, void *data)
 
1216
{
 
1217
    W_ColorPanel        *panel = (W_ColorPanel*)data;
 
1218
 
 
1219
    WMCloseColorPanel(panel);
 
1220
}
 
1221
 
 
1222
 
 
1223
static void
 
1224
readConfiguration(W_ColorPanel *panel)
 
1225
{
 
1226
    /* XXX Doesn't take care of "invalid" files */
 
1227
 
 
1228
    DIR *dPtr;
 
1229
    struct dirent       *dp;
 
1230
    struct stat         stat_buf;
 
1231
    int                 item;
 
1232
 
 
1233
    if (stat(panel->configurationPath, &stat_buf)!=0) {
 
1234
        if (mkdir(panel->configurationPath,
 
1235
                  S_IRWXU|S_IRGRP|S_IROTH|S_IXGRP|S_IXOTH)!=0) {
 
1236
            wsyserror(_("Color Panel: Could not create directory %s needed"
 
1237
                        " to store configurations"), panel->configurationPath);
 
1238
            WMSetPopUpButtonEnabled(panel->customPaletteMenuBtn, False);
 
1239
            WMSetPopUpButtonEnabled(panel->colorListColorMenuBtn, False);
 
1240
            WMSetPopUpButtonEnabled(panel->colorListListMenuBtn, False);
 
1241
            WMRunAlertPanel(WMWidgetScreen(panel->win), panel->win,
 
1242
                            _("File Error"),
 
1243
                            _("Could not create ColorPanel configuration directory"),
 
1244
                            _("OK"), NULL, NULL);
 
1245
        }
 
1246
        return;
 
1247
    }
 
1248
 
 
1249
    if (!(dPtr = opendir(panel->configurationPath))) {
 
1250
        wwarning(_("Color Panel: Could not find file"), "%s", panel->configurationPath);
 
1251
        return;
 
1252
    }
 
1253
 
 
1254
    while ((dp = readdir(dPtr)) != NULL) {
 
1255
        unsigned int    perm_mask;
 
1256
        char            *path = wstrconcat(panel->configurationPath,
 
1257
                                           dp->d_name);
 
1258
 
 
1259
        if (dp->d_name[0] != '.') {
 
1260
            item = WMGetPopUpButtonNumberOfItems(
 
1261
                                                 panel->customPaletteHistoryBtn);
 
1262
            WMAddPopUpButtonItem(panel->customPaletteHistoryBtn, dp->d_name);
 
1263
 
 
1264
            perm_mask = (access(path, R_OK) == 0);
 
1265
            WMSetPopUpButtonItemEnabled(panel->customPaletteHistoryBtn,
 
1266
                                        item, perm_mask);
 
1267
        }
 
1268
        wfree(path);
 
1269
    }
 
1270
    (void)closedir(dPtr);
 
1271
}
 
1272
 
 
1273
 
 
1274
static void
 
1275
readXColors(W_ColorPanel *panel)
 
1276
{
 
1277
    struct stat         stat_buf;
 
1278
    FILE                *rgbtxt;
 
1279
    char                line[MAX_LENGTH];
 
1280
    int                 red, green, blue;
 
1281
    char                name[48];
 
1282
    RColor              *color;
 
1283
    WMListItem          *item;
 
1284
 
 
1285
    if (stat(RGBTXT, &stat_buf) != 0) {
 
1286
        wsyserror(_("Color Panel: Could not find file"), " %s", RGBTXT);
 
1287
        return;
 
1288
    }
 
1289
    else {
 
1290
        if ((rgbtxt = fopen(RGBTXT, "rb"))) {
 
1291
            while (fgets(line, MAX_LENGTH, rgbtxt)) {
 
1292
                if (sscanf(line, "%d%d%d %[^\n]", &red, &green, &blue, name)) {
 
1293
                    color = wmalloc(sizeof(RColor));
 
1294
                    color->red = (unsigned char)red;
 
1295
                    color->green = (unsigned char)green;
 
1296
                    color->blue = (unsigned char)blue;
 
1297
                    item = WMAddListItem(panel->colorListContentLst, name);
 
1298
                    item->clientData = (void *)color;
 
1299
                }
 
1300
            }
 
1301
            fclose(rgbtxt);
 
1302
        }
 
1303
        else {
 
1304
            wsyserror(_("Color Panel: Could not find file"), "%s", RGBTXT);
 
1305
        }
 
1306
    }
 
1307
}
 
1308
 
 
1309
 
 
1310
void
 
1311
WMSetColorPanelPickerMode(WMColorPanel *panel, WMColorPanelMode mode)
 
1312
{
 
1313
    W_Screen    *scr = WMWidgetScreen(panel->win);
 
1314
 
 
1315
    if (mode != WMWheelModeColorPanel) {
 
1316
        WMUnmapWidget(panel->wheelFrm);
 
1317
        if (panel->selectionBackImg) {
 
1318
            XFreePixmap(WMWidgetScreen(panel->win)->display,
 
1319
                        panel->selectionBackImg);
 
1320
            panel->selectionBackImg = None;
 
1321
        }
 
1322
    }
 
1323
    if (mode != WMGrayModeColorPanel)
 
1324
        WMUnmapWidget(panel->grayFrm);
 
1325
    if (mode != WMRGBModeColorPanel)
 
1326
        WMUnmapWidget(panel->rgbFrm);
 
1327
    if (mode != WMCMYKModeColorPanel)
 
1328
        WMUnmapWidget(panel->cmykFrm);
 
1329
    if (mode != WMHSBModeColorPanel)
 
1330
        WMUnmapWidget(panel->hsbFrm);
 
1331
    if (mode != WMCustomPaletteModeColorPanel) {
 
1332
        WMUnmapWidget(panel->customPaletteFrm);
 
1333
        if (panel->selectionBackImg) {
 
1334
            XFreePixmap(WMWidgetScreen(panel->win)->display,
 
1335
                        panel->selectionBackImg);
 
1336
            panel->selectionBackImg = None;
 
1337
        }
 
1338
    }
 
1339
    if (mode != WMColorListModeColorPanel)
 
1340
        WMUnmapWidget(panel->colorListFrm);
 
1341
    if ((mode != WMGrayModeColorPanel) && (mode != WMRGBModeColorPanel) &&
 
1342
        (mode != WMCMYKModeColorPanel) && (mode != WMHSBModeColorPanel))
 
1343
        WMUnmapWidget(panel->slidersFrm);
 
1344
    else
 
1345
        panel->slidersmode = mode;
 
1346
 
 
1347
    if (mode == WMWheelModeColorPanel) {
 
1348
        WMMapWidget(panel->wheelFrm);
 
1349
        WMSetButtonSelected(panel->wheelBtn, True);
 
1350
        if (panel->lastChanged != WMWheelModeColorPanel)
 
1351
            wheelInit(panel);
 
1352
        wheelRender(panel);
 
1353
        wheelPaint(panel);
 
1354
    } else if (mode == WMGrayModeColorPanel) {
 
1355
        WMMapWidget(panel->slidersFrm);
 
1356
        WMSetButtonSelected(panel->slidersBtn, True);
 
1357
        WMMapWidget(panel->grayFrm);
 
1358
        WMSetButtonSelected(panel->grayBtn, True);
 
1359
        WMSetButtonImage(panel->slidersBtn, scr->grayIcon);
 
1360
        if (panel->lastChanged != WMGrayModeColorPanel)
 
1361
            grayInit(panel);
 
1362
    } else if (mode == WMRGBModeColorPanel) {
 
1363
        WMMapWidget(panel->slidersFrm);
 
1364
        WMSetButtonSelected(panel->slidersBtn, True);
 
1365
        WMMapWidget(panel->rgbFrm);
 
1366
        WMSetButtonSelected(panel->rgbBtn, True);
 
1367
        WMSetButtonImage(panel->slidersBtn, scr->rgbIcon);
 
1368
        if (panel->lastChanged != WMRGBModeColorPanel)
 
1369
            rgbInit(panel);
 
1370
    } else if (mode == WMCMYKModeColorPanel) {
 
1371
        WMMapWidget(panel->slidersFrm);
 
1372
        WMSetButtonSelected(panel->slidersBtn, True);
 
1373
        WMMapWidget(panel->cmykFrm);
 
1374
        WMSetButtonSelected(panel->cmykBtn, True);
 
1375
        WMSetButtonImage(panel->slidersBtn, scr->cmykIcon);
 
1376
        if (panel->lastChanged != WMCMYKModeColorPanel)
 
1377
            cmykInit(panel);
 
1378
    } else if (mode == WMHSBModeColorPanel) {
 
1379
        WMMapWidget(panel->slidersFrm);
 
1380
        WMSetButtonSelected(panel->slidersBtn, True);
 
1381
        WMMapWidget(panel->hsbFrm);
 
1382
        WMSetButtonSelected(panel->hsbBtn, True);
 
1383
        WMSetButtonImage(panel->slidersBtn, scr->hsbIcon);
 
1384
        if (panel->lastChanged != WMHSBModeColorPanel)
 
1385
            hsbInit(panel);
 
1386
    } else if (mode == WMCustomPaletteModeColorPanel) {
 
1387
        WMMapWidget(panel->customPaletteFrm);
 
1388
        WMSetButtonSelected(panel->customPaletteBtn, True);
 
1389
        customSetPalette(panel);
 
1390
    } else if (mode == WMColorListModeColorPanel) {
 
1391
        WMMapWidget(panel->colorListFrm);
 
1392
        WMSetButtonSelected(panel->colorListBtn, True);
 
1393
    }
 
1394
 
 
1395
    panel->mode = mode;
 
1396
}
 
1397
 
 
1398
 
 
1399
WMColor*
 
1400
WMGetColorPanelColor(WMColorPanel *panel)
 
1401
{
 
1402
    return WMGetColorWellColor(panel->colorWell);
 
1403
}
 
1404
 
 
1405
 
 
1406
void
 
1407
WMSetColorPanelColor(WMColorPanel *panel, WMColor *color)
 
1408
{
 
1409
    WMSetColorWellColor(panel->colorWell, color);
 
1410
 
 
1411
    panel->color.rgb.red        = color->color.red >> 8;
 
1412
    panel->color.rgb.green      = color->color.green >> 8;
 
1413
    panel->color.rgb.blue       = color->color.blue >> 8;
 
1414
    panel->color.set            = cpRGB;
 
1415
 
 
1416
    if (panel->mode == panel->lastChanged)
 
1417
        panel->lastChanged = 0;
 
1418
 
 
1419
    WMSetColorPanelPickerMode(panel, panel->mode);
 
1420
}
 
1421
 
 
1422
 
 
1423
static void
 
1424
updateSwatch(WMColorPanel *panel, CPColor color)
 
1425
{
 
1426
    WMScreen    *scr = WMWidgetScreen(panel->win);
 
1427
    WMColor     *wellcolor;
 
1428
 
 
1429
    if (color.set != cpRGB)
 
1430
        convertCPColor(&color);
 
1431
 
 
1432
    panel->color = color;
 
1433
 
 
1434
    wellcolor = WMCreateRGBColor(scr, color.rgb.red << 8,
 
1435
                                 color.rgb.green << 8,
 
1436
                                 color.rgb.blue  << 8, True);
 
1437
 
 
1438
    WMSetColorWellColor(panel->colorWell, wellcolor);
 
1439
    WMReleaseColor(wellcolor);
 
1440
 
 
1441
    if (!panel->flags.dragging || panel->flags.continuous) {
 
1442
        if (panel->action)
 
1443
            (*panel->action)(panel, panel->clientData);
 
1444
 
 
1445
        WMPostNotificationName(WMColorPanelColorChangedNotification, panel,
 
1446
                               NULL);
 
1447
    }
 
1448
}
 
1449
 
 
1450
static void
 
1451
modeButtonCallback(WMWidget *w, void *data)
 
1452
{
 
1453
    W_ColorPanel        *panel = (W_ColorPanel*)(data);
 
1454
 
 
1455
    if (w == panel->wheelBtn)
 
1456
        WMSetColorPanelPickerMode(panel, WMWheelModeColorPanel);
 
1457
    else if (w == panel->slidersBtn)
 
1458
        WMSetColorPanelPickerMode(panel, panel->slidersmode);
 
1459
    else if (w == panel->customPaletteBtn)
 
1460
        WMSetColorPanelPickerMode(panel, WMCustomPaletteModeColorPanel);
 
1461
    else if (w == panel->colorListBtn)
 
1462
        WMSetColorPanelPickerMode(panel, WMColorListModeColorPanel);
 
1463
    else if (w == panel->grayBtn)
 
1464
        WMSetColorPanelPickerMode(panel, WMGrayModeColorPanel);
 
1465
    else if (w == panel->rgbBtn)
 
1466
        WMSetColorPanelPickerMode(panel, WMRGBModeColorPanel);
 
1467
    else if (w == panel->cmykBtn)
 
1468
        WMSetColorPanelPickerMode(panel, WMCMYKModeColorPanel);
 
1469
    else if (w == panel->hsbBtn)
 
1470
        WMSetColorPanelPickerMode(panel, WMHSBModeColorPanel);
 
1471
}
 
1472
 
 
1473
 
 
1474
/******************  Magnifying Cursor Functions *******************/
 
1475
 
 
1476
static XImage*
 
1477
magnifyGetImage(WMScreen *scr, XImage *image, int x, int y, int w, int h)
 
1478
{
 
1479
    int         x0 = 0, y0 = 0, w0 = w, h0 = h;
 
1480
    const int   displayWidth = DisplayWidth(scr->display, scr->screen),
 
1481
        displayHeight = DisplayHeight(scr->display, scr->screen);
 
1482
 
 
1483
    if (!(image && image->data)) {
 
1484
        /* The image in panel->magnifyGlass->image does not exist yet.
 
1485
         * Grab one from the screen (not beyond) and use it from now on.
 
1486
         */
 
1487
        if (!(image = XGetImage(scr->display, scr->rootWin,
 
1488
                                x - Cursor_x_hot,
 
1489
                                y - Cursor_y_hot,
 
1490
                                w, h, AllPlanes, ZPixmap)))
 
1491
            wwarning(_("Color Panel: X failed request"));
 
1492
 
 
1493
        return image;
 
1494
    }
 
1495
 
 
1496
    /* Coordinate correction for back pixmap
 
1497
     * if magnifying glass is at screen-borders
 
1498
     */
 
1499
 
 
1500
    /* Figure 1: Shifting of rectangle-to-grab at top/left screen borders
 
1501
     * Hatched area is beyond screen border.
 
1502
     *
 
1503
     * |<-Cursor_x_hot->|
 
1504
     *  ________________|_____
 
1505
     * |/ / / / / / /|  |     |
 
1506
     * | / / / / / / |(x,y)   |
 
1507
     * |/_/_/_/_/_/_/|________|
 
1508
     * |<----x0----->|<--w0-->|
 
1509
     *               0
 
1510
     */
 
1511
 
 
1512
    /* Figure 2: Shifting of rectangle-to-grab at bottom/right
 
1513
     * screen borders
 
1514
     * Hatched area is beyond screen border
 
1515
     *
 
1516
     * |<-Cursor_x_hot->|
 
1517
     *  ________________|_______________
 
1518
     * |                |  | / / / / / /|
 
1519
     * |              (x,y)|/ / / / / / |
 
1520
     * |___________________|_/_/_/_/_/_/|
 
1521
     * |<-------w0-------->|            |
 
1522
     * |<---------------w--|----------->|
 
1523
     * |                   |
 
1524
     * x0                  Displaywidth-1
 
1525
     */
 
1526
 
 
1527
    if (x < Cursor_x_hot) {                             /* see fig. 1 */
 
1528
        x0 = Cursor_x_hot - x;
 
1529
        w0 = w - x0;
 
1530
    }
 
1531
 
 
1532
    if (displayWidth -1 < x - Cursor_x_hot + w) {       /* see fig. 2 */
 
1533
        w0 = (displayWidth) - (x - Cursor_x_hot);
 
1534
    }
 
1535
 
 
1536
    if (y < Cursor_y_hot) {                             /* see fig. 1 */
 
1537
        y0 = Cursor_y_hot - y;
 
1538
        h0 = h - y0;
 
1539
    }
 
1540
 
 
1541
    if (displayHeight -1 < y - Cursor_y_hot + h) {      /* see fig. 2 */
 
1542
        h0 = (displayHeight) - (y - Cursor_y_hot);
 
1543
    }
 
1544
    /* end of coordinate correction */
 
1545
 
 
1546
 
 
1547
    /* Grab an image from the screen, clipped if necessary,
 
1548
     * and put it in the existing panel->magnifyGlass->image
 
1549
     * with the corresponding clipping offset.
 
1550
     */
 
1551
    if (!XGetSubImage(scr->display, scr->rootWin,
 
1552
                      x - Cursor_x_hot + x0,
 
1553
                      y - Cursor_y_hot + y0,
 
1554
                      w0, h0,   AllPlanes, ZPixmap,
 
1555
                      image, x0, y0))
 
1556
        wwarning(_("Color Panel: X failed request"));
 
1557
 
 
1558
    return NULL;
 
1559
}
 
1560
 
 
1561
 
 
1562
static void
 
1563
magnifyGetImageStored(WMColorPanel *panel, int x1, int y1, int x2, int y2)
 
1564
{
 
1565
    /* (x1, y1) = topleft corner of existing rectangle
 
1566
     * (x2, y2) = topleft corner of new position
 
1567
     */
 
1568
 
 
1569
    W_Screen    *scr = WMWidgetScreen(panel->win);
 
1570
    int         xa = 0, ya = 0, xb = 0, yb = 0;
 
1571
    int         width, height;
 
1572
    const int   dx = abs(x2 - x1),
 
1573
        dy = abs(y2 - y1);
 
1574
    XImage      *image;
 
1575
    const int   x_min = Cursor_x_hot,
 
1576
        y_min = Cursor_y_hot,
 
1577
    x_max = DisplayWidth(scr->display, scr->screen) -1 -
 
1578
        (Cursor_mask_width - Cursor_x_hot),
 
1579
    y_max = DisplayHeight(scr->display, scr->screen) -1 -
 
1580
        (Cursor_mask_height - Cursor_y_hot);
 
1581
 
 
1582
    if ((dx == 0) && (dy == 0) && panel->magnifyGlass->image)
 
1583
        return; /* No movement */
 
1584
 
 
1585
    if (x1 < x2)
 
1586
        xa = dx;
 
1587
    else
 
1588
        xb = dx;
 
1589
 
 
1590
    if (y1 < y2)
 
1591
        ya = dy;
 
1592
    else
 
1593
        yb = dy;
 
1594
 
 
1595
    width  = Cursor_mask_width - dx;
 
1596
    height = Cursor_mask_height - dy;
 
1597
 
 
1598
    /* If the traversed distance is larger than the size of the magnifying
 
1599
     * glass contents, there is no need to do dirty rectangles. A whole new
 
1600
     * rectangle can be grabbed (unless that rectangle falls partially
 
1601
     * off screen).
 
1602
     * Destroying the image and setting it to NULL will achieve that later on.
 
1603
     *
 
1604
     * Of course, grabbing an XImage beyond the borders of the screen will
 
1605
     * cause trouble, this is considdered a special case. Part of the screen
 
1606
     * is grabbed, but there is no need for dirty rectangles.
 
1607
     */
 
1608
    if ((width <= 0) || (height <= 0)) {
 
1609
        if ((x2 >= x_min) && (y2 >= y_min) && (x2 <= x_max) && (y2 <= y_max)) {
 
1610
            if (panel->magnifyGlass->image)
 
1611
                XDestroyImage(panel->magnifyGlass->image);
 
1612
            panel->magnifyGlass->image = NULL;
 
1613
        }
 
1614
    } else {
 
1615
        if (panel->magnifyGlass->image) {
 
1616
            /* Get dirty rectangle from panel->magnifyGlass->image */
 
1617
            panel->magnifyGlass->dirtyRect =
 
1618
                XSubImage(panel->magnifyGlass->image, xa, ya, width, height);
 
1619
            if (!panel->magnifyGlass->dirtyRect) {
 
1620
                wwarning(_("Color Panel: X failed request"));
 
1621
                return; /* X returned a NULL from XSubImage */
 
1622
            }
 
1623
        }
 
1624
    }
 
1625
 
 
1626
    /* Get image from screen */
 
1627
    image = magnifyGetImage(scr, panel->magnifyGlass->image, x2, y2,
 
1628
                            Cursor_mask_width, Cursor_mask_height);
 
1629
    if (image) { /* Only reassign if a *new* image was grabbed */
 
1630
        panel->magnifyGlass->image = image;
 
1631
        return;
 
1632
    }
 
1633
 
 
1634
    /* Copy previously stored rectangle on covered part of image */
 
1635
    if (panel->magnifyGlass->image && panel->magnifyGlass->dirtyRect) {
 
1636
        int old_height;
 
1637
 
 
1638
        /* "width" and "height" are used as coordinates here,
 
1639
         * and run from [0...width-1] and [0...height-1] respectively.
 
1640
         */
 
1641
        width--;
 
1642
        height--;
 
1643
        old_height = height;
 
1644
 
 
1645
        for (; width >= 0; width--)
 
1646
            for (height = old_height; height >= 0; height--)
 
1647
                XPutPixel(panel->magnifyGlass->image, xb + width, yb + height,
 
1648
                          XGetPixel(panel->magnifyGlass->dirtyRect, width, height));
 
1649
        XDestroyImage(panel->magnifyGlass->dirtyRect);
 
1650
        panel->magnifyGlass->dirtyRect = NULL;
 
1651
    }
 
1652
 
 
1653
    return;
 
1654
}
 
1655
 
 
1656
 
 
1657
static Pixmap
 
1658
magnifyCreatePixmap(WMColorPanel *panel)
 
1659
{
 
1660
    W_Screen            *scr = WMWidgetScreen(panel->win);
 
1661
    int                 u, v;
 
1662
#ifndef SHAPE
 
1663
    Pixmap              pixmap;
 
1664
#endif
 
1665
    unsigned long       color;
 
1666
 
 
1667
    if (!panel->magnifyGlass->image)
 
1668
        return None;
 
1669
 
 
1670
    if (!panel->magnifyGlass->magPix)
 
1671
        return None;
 
1672
 
 
1673
    /*
 
1674
     * Copy an area of only 5x5 pixels from the center of the image.
 
1675
     */
 
1676
    for (u = 0; u < 5; u++) {
 
1677
        for (v = 0; v < 5; v++) {
 
1678
            color = XGetPixel(panel->magnifyGlass->image, u + 9, v + 9);
 
1679
 
 
1680
            XSetForeground(scr->display, scr->copyGC, color);
 
1681
 
 
1682
            if ((u == 2) && (v == 2)) /* (2,2) is center pixel (unmagn.) */
 
1683
                panel->magnifyGlass->color = ulongToRColor(scr, color);
 
1684
 
 
1685
            /* The center square must eventually be centered around the
 
1686
             * hotspot. The image needs shifting to achieve this. The amount of
 
1687
             * shifting is (Cursor_mask_width/2 - 2 * square_size) = 11-10 = 1
 
1688
             *  _ _ _ _ _
 
1689
             * |_|_|_|_|_|
 
1690
             *      ^------- center of center square == Cursor_x_hot
 
1691
             */
 
1692
            XFillRectangle(scr->display, panel->magnifyGlass->magPix,
 
1693
                           scr->copyGC,
 
1694
                           u * 5 + (u == 0 ? 0 : -1), v * 5 + (v == 0 ? 0 : -1),
 
1695
                           (u == 0 ? 4 : 5), (v == 0 ? 4 : 5));
 
1696
        }
 
1697
    }
 
1698
 
 
1699
#ifdef SHAPE
 
1700
    return panel->magnifyGlass->magPix;
 
1701
#else
 
1702
    pixmap = XCreatePixmap(scr->display, W_DRAWABLE(scr), Cursor_mask_width,
 
1703
                           Cursor_mask_height, scr->depth);
 
1704
    if (!pixmap)
 
1705
        return None;
 
1706
 
 
1707
    XPutImage(scr->display, pixmap, scr->copyGC, panel->magnifyGlass->image,
 
1708
              0, 0, 0, 0, Cursor_mask_width, Cursor_mask_height);
 
1709
 
 
1710
    /* Copy the magnified pixmap, with the clip mask, to background pixmap */
 
1711
    XCopyArea(scr->display, panel->magnifyGlass->magPix, pixmap,
 
1712
              scr->clipGC, 0, 0, Cursor_mask_width, Cursor_mask_height, 0, 0);
 
1713
    /* (2,2) puts center pixel on center of glass */
 
1714
 
 
1715
    return pixmap;
 
1716
#endif
 
1717
 
 
1718
}
 
1719
 
 
1720
 
 
1721
static WMView*
 
1722
magnifyCreateView(W_ColorPanel *panel)
 
1723
{
 
1724
    W_Screen    *scr = WMWidgetScreen(panel->win);
 
1725
    WMView      *magView;
 
1726
 
 
1727
    magView = W_CreateTopView(scr);
 
1728
    if (!magView)
 
1729
        return NULL;
 
1730
 
 
1731
    magView->self = panel->win;
 
1732
    magView->flags.topLevel = 1;
 
1733
    magView->attribFlags |= CWOverrideRedirect | CWSaveUnder;
 
1734
    magView->attribs.override_redirect = True;
 
1735
    magView->attribs.save_under = True;
 
1736
 
 
1737
    W_ResizeView(magView, Cursor_mask_width, Cursor_mask_height);
 
1738
 
 
1739
    W_RealizeView(magView);
 
1740
 
 
1741
    return magView;
 
1742
}
 
1743
 
 
1744
 
 
1745
static Cursor
 
1746
magnifyGrabPointer(W_ColorPanel *panel)
 
1747
{
 
1748
    W_Screen    *scr = WMWidgetScreen(panel->win);
 
1749
    Pixmap      magPixmap, magPixmap2;
 
1750
    Cursor      magCursor;
 
1751
    XColor      fgColor = {0, 0,0,0, DoRed|DoGreen|DoBlue};
 
1752
    XColor      bgColor = {0, 0xbf00, 0xa000, 0x5000, DoRed|DoGreen|DoBlue};
 
1753
 
 
1754
    /* Cursor creation stuff */
 
1755
    magPixmap = XCreatePixmapFromBitmapData(scr->display, W_DRAWABLE(scr),
 
1756
                                            (char *)Cursor_bits, Cursor_width, Cursor_height, 1, 0, 1);
 
1757
    magPixmap2 = XCreatePixmapFromBitmapData(scr->display, W_DRAWABLE(scr),
 
1758
                                             (char *)Cursor_shape_bits, Cursor_width, Cursor_height, 1, 0, 1);
 
1759
 
 
1760
    magCursor = XCreatePixmapCursor(scr->display, magPixmap, magPixmap2,
 
1761
                                    &fgColor, &bgColor, Cursor_x_hot, Cursor_y_hot);
 
1762
 
 
1763
    XFreePixmap(scr->display, magPixmap);
 
1764
    XFreePixmap(scr->display, magPixmap2);
 
1765
 
 
1766
    XRecolorCursor(scr->display, magCursor, &fgColor, &bgColor);
 
1767
 
 
1768
    /* Set up Pointer */
 
1769
    XGrabPointer (scr->display, panel->magnifyGlass->view->window, True,
 
1770
                  PointerMotionMask | ButtonPressMask,
 
1771
                  GrabModeAsync, GrabModeAsync,
 
1772
                  scr->rootWin, magCursor, CurrentTime);
 
1773
 
 
1774
    return magCursor;
 
1775
}
 
1776
 
 
1777
 
 
1778
static WMPoint
 
1779
magnifyInitialize(W_ColorPanel *panel)
 
1780
{
 
1781
    W_Screen            *scr = WMWidgetScreen(panel->win);
 
1782
    int                 x, y, u, v;
 
1783
    unsigned int        mask;
 
1784
    Pixmap              pixmap, clip_mask;
 
1785
    WMPoint             point;
 
1786
    Window              root_return, child_return;
 
1787
 
 
1788
    clip_mask = XCreatePixmapFromBitmapData(scr->display, W_DRAWABLE(scr),
 
1789
                                            (char *)Cursor_mask_bits, Cursor_mask_width, Cursor_mask_height,
 
1790
                                            1, 0, 1);
 
1791
    panel->magnifyGlass->magPix = XCreatePixmap(scr->display, W_DRAWABLE(scr),
 
1792
                                                5*5 -1, 5*5 -1, scr->depth);
 
1793
 
 
1794
    XQueryPointer(scr->display, scr->rootWin, &root_return, &child_return,
 
1795
                  &x, &y, &u, &v, &mask);
 
1796
 
 
1797
    panel->magnifyGlass->image = NULL;
 
1798
 
 
1799
    /* Clipmask to make magnified view-contents circular */
 
1800
#ifdef SHAPE
 
1801
    XShapeCombineMask(scr->display, WMViewXID(panel->magnifyGlass->view),
 
1802
                      ShapeBounding, 0, 0, clip_mask, ShapeSet);
 
1803
#else
 
1804
    /* Clip circle in glass cursor */
 
1805
    XSetClipMask(scr->display, scr->clipGC, clip_mask);
 
1806
    XSetClipOrigin(scr->display, scr->clipGC, 0, 0);
 
1807
#endif
 
1808
 
 
1809
    XFreePixmap(scr->display, clip_mask);
 
1810
 
 
1811
    /* Draw initial magnifying glass contents */
 
1812
    magnifyGetImageStored(panel, x, y, x, y);
 
1813
 
 
1814
    pixmap = magnifyCreatePixmap(panel);
 
1815
    XSetWindowBackgroundPixmap(scr->display,
 
1816
                               WMViewXID(panel->magnifyGlass->view),
 
1817
                               pixmap);
 
1818
    XClearWindow(scr->display, WMViewXID(panel->magnifyGlass->view));
 
1819
    XFlush(scr->display);
 
1820
 
 
1821
#ifndef SHAPE
 
1822
    XFreePixmap(scr->display, pixmap);
 
1823
#endif
 
1824
 
 
1825
    point.x = x;
 
1826
    point.y = y;
 
1827
 
 
1828
    return point;
 
1829
}
 
1830
 
 
1831
 
 
1832
static void
 
1833
magnifyPutCursor(WMWidget *w, void *data)
 
1834
{
 
1835
    W_ColorPanel        *panel = (W_ColorPanel*)(data);
 
1836
    W_Screen            *scr = WMWidgetScreen(panel->win);
 
1837
    Cursor              magCursor;
 
1838
    Pixmap              pixmap;
 
1839
    XEvent              event;
 
1840
    WMPoint             initialPosition;
 
1841
 
 
1842
    /* Destroy wheelBackImg, so it'll update properly */
 
1843
    if (panel->selectionBackImg) {
 
1844
        XFreePixmap(WMWidgetScreen(panel->win)->display,
 
1845
                    panel->selectionBackImg);
 
1846
        panel->selectionBackImg = None;
 
1847
    }
 
1848
 
 
1849
    /* Create magnifying glass */
 
1850
    panel->magnifyGlass = wmalloc(sizeof(MovingView));
 
1851
    panel->magnifyGlass->view = magnifyCreateView(panel);
 
1852
    if (!panel->magnifyGlass->view)
 
1853
        return;
 
1854
 
 
1855
    initialPosition = magnifyInitialize(panel);
 
1856
    panel->magnifyGlass->x = initialPosition.x;
 
1857
    panel->magnifyGlass->y = initialPosition.y;
 
1858
 
 
1859
    W_MoveView(panel->magnifyGlass->view,
 
1860
               panel->magnifyGlass->x - Cursor_x_hot,
 
1861
               panel->magnifyGlass->y - Cursor_y_hot);
 
1862
    W_MapView(panel->magnifyGlass->view);
 
1863
 
 
1864
    magCursor = magnifyGrabPointer(panel);
 
1865
 
 
1866
    while (panel->magnifyGlass->image)
 
1867
    {
 
1868
        WMNextEvent(scr->display, &event);
 
1869
 
 
1870
        /* Pack motion events */
 
1871
        while (XCheckTypedEvent(scr->display, MotionNotify, &event)) {
 
1872
        }
 
1873
 
 
1874
        switch (event.type)
 
1875
        {
 
1876
        case ButtonPress:
 
1877
            XDestroyImage(panel->magnifyGlass->image);
 
1878
            panel->magnifyGlass->image = NULL;
 
1879
 
 
1880
            if (event.xbutton.button == Button1) {
 
1881
                panel->color.rgb = panel->magnifyGlass->color;
 
1882
                panel->color.set = cpRGB;
 
1883
                updateSwatch(panel, panel->color);
 
1884
            }
 
1885
            switch (panel->mode) {
 
1886
            case WMWheelModeColorPanel:
 
1887
                wheelInit(panel);
 
1888
                wheelRender(panel);
 
1889
                wheelPaint(panel);
 
1890
                break;
 
1891
            case WMGrayModeColorPanel:
 
1892
                grayInit(panel);
 
1893
                break;
 
1894
            case WMRGBModeColorPanel:
 
1895
                rgbInit(panel);
 
1896
                break;
 
1897
            case WMCMYKModeColorPanel:
 
1898
                cmykInit(panel);
 
1899
                break;
 
1900
            case WMHSBModeColorPanel:
 
1901
                hsbInit(panel);
 
1902
                break;
 
1903
            default:
 
1904
                break;
 
1905
            }
 
1906
            panel->lastChanged = panel->mode;
 
1907
 
 
1908
            WMSetButtonSelected(panel->magnifyBtn, False);
 
1909
            break;
 
1910
 
 
1911
        case MotionNotify:
 
1912
            while (XPending(event.xmotion.display)) {
 
1913
                XEvent ev;
 
1914
                XPeekEvent(event.xmotion.display, &ev);
 
1915
                if (ev.type == MotionNotify)
 
1916
                    XNextEvent(event.xmotion.display, &event);
 
1917
                else
 
1918
                    break;
 
1919
            }
 
1920
 
 
1921
            /* Get a "dirty rectangle" */
 
1922
            magnifyGetImageStored( panel,
 
1923
                                  panel->magnifyGlass->x, panel->magnifyGlass->y,
 
1924
                                  event.xmotion.x_root, event.xmotion.y_root);
 
1925
 
 
1926
            /* Update coordinates */
 
1927
            panel->magnifyGlass->x = event.xmotion.x_root;
 
1928
            panel->magnifyGlass->y = event.xmotion.y_root;
 
1929
 
 
1930
            /* Move view */
 
1931
            W_MoveView(panel->magnifyGlass->view,
 
1932
                       panel->magnifyGlass->x - Cursor_x_hot,
 
1933
                       panel->magnifyGlass->y - Cursor_y_hot);
 
1934
 
 
1935
            /* Put new image (with magn.) in view */
 
1936
            pixmap = magnifyCreatePixmap(panel);
 
1937
            if (pixmap != None) {
 
1938
                /* Change the window background */
 
1939
                XSetWindowBackgroundPixmap(scr->display,
 
1940
                                           WMViewXID(panel->magnifyGlass->view), pixmap);
 
1941
                /* Force an Expose (handled by X) */
 
1942
                XClearWindow(scr->display,
 
1943
                             WMViewXID(panel->magnifyGlass->view));
 
1944
                /* Synchronize the event queue, so the Expose is handled NOW */
 
1945
                XFlush(scr->display);
 
1946
#ifndef SHAPE
 
1947
                XFreePixmap(scr->display, pixmap);
 
1948
#endif
 
1949
            }
 
1950
            break;
 
1951
 
 
1952
            /* Try XQueryPointer for this !!! It returns windows that the pointer
 
1953
             * is over. Note: We found this solving the invisible donkey cap bug
 
1954
             */
 
1955
#if 0   /* As it is impossible to make this work in all cases,
 
1956
         * we consider it confusing. Therefore we disabled it.
 
1957
         */
 
1958
        case FocusOut:          /* fall through */
 
1959
        case FocusIn:
 
1960
            /*
 
1961
             * Color Panel window (panel->win) lost or received focus.
 
1962
             * We need to update the pixmap in the magnifying glass.
 
1963
             *
 
1964
             * BUG Doesn't work with focus switches between two windows
 
1965
             * if none of them is the color panel.
 
1966
             */
 
1967
            XUngrabPointer(scr->display, CurrentTime);
 
1968
            W_UnmapView(panel->magnifyGlass->view);
 
1969
 
 
1970
            magnifyInitialize(panel);
 
1971
 
 
1972
            W_MapView(panel->magnifyGlass->view);
 
1973
            XGrabPointer (scr->display, panel->magnifyGlass->view->window,
 
1974
                          True, PointerMotionMask | ButtonPressMask,
 
1975
                          GrabModeAsync, GrabModeAsync,
 
1976
                          scr->rootWin, magCursor, CurrentTime);
 
1977
            break;
 
1978
#endif
 
1979
        default:
 
1980
            WMHandleEvent(&event);
 
1981
            break;
 
1982
        } /* of switch */
 
1983
    }
 
1984
 
 
1985
    XUngrabPointer(scr->display, CurrentTime);
 
1986
    XFreeCursor(scr->display, magCursor);
 
1987
 
 
1988
    XFreePixmap(scr->display, panel->magnifyGlass->magPix);
 
1989
    panel->magnifyGlass->magPix = None;
 
1990
 
 
1991
    W_UnmapView(panel->magnifyGlass->view);
 
1992
    W_DestroyView(panel->magnifyGlass->view);
 
1993
    panel->magnifyGlass->view = NULL;
 
1994
 
 
1995
    wfree(panel->magnifyGlass);
 
1996
}
 
1997
 
 
1998
 
 
1999
 
 
2000
/******************  ColorWheel Functions  ************************/
 
2001
 
 
2002
static wheelMatrix*
 
2003
wheelCreateMatrix(unsigned int width, unsigned int height)
 
2004
{
 
2005
    wheelMatrix *matrix = NULL;
 
2006
    int i;
 
2007
 
 
2008
    assert((width > 0) && (height > 0));
 
2009
 
 
2010
    matrix = wmalloc(sizeof(wheelMatrix));
 
2011
    memset(matrix, 0, sizeof(wheelMatrix));
 
2012
    matrix->width = width;
 
2013
    matrix->height = height;
 
2014
 
 
2015
    for (i = 0; i < 3; i++) {
 
2016
        matrix->data[i] = wmalloc(width*height*sizeof(unsigned char));
 
2017
    }
 
2018
 
 
2019
    return matrix;
 
2020
}
 
2021
 
 
2022
 
 
2023
static void
 
2024
wheelDestroyMatrix(wheelMatrix *matrix)
 
2025
{
 
2026
    int i;
 
2027
 
 
2028
    if (!matrix)
 
2029
        return;
 
2030
 
 
2031
    for (i = 0; i < 3; i++) {
 
2032
        if (matrix->data[i])
 
2033
            wfree(matrix->data[i]);
 
2034
    }
 
2035
    wfree(matrix);
 
2036
}
 
2037
 
 
2038
 
 
2039
static void
 
2040
wheelInitMatrix(W_ColorPanel *panel)
 
2041
{
 
2042
    int                 i;
 
2043
    int                 x,y;
 
2044
    unsigned char       *rp, *gp, *bp;
 
2045
    CPColor             cpColor;
 
2046
    long                ofs[4];
 
2047
    int                 xcor, ycor;
 
2048
    unsigned short      sat;
 
2049
    int                 dhue[4];
 
2050
    const int           cw_halfsize = (colorWheelSize + 4)/2,
 
2051
        cw_sqsize = (colorWheelSize +4) * (colorWheelSize +4),
 
2052
    uchar_shift = getShift(sizeof(unsigned char));
 
2053
 
 
2054
    if (!panel->wheelMtrx)
 
2055
        return;
 
2056
 
 
2057
    cpColor.hsv.value = 255;
 
2058
    cpColor.set = cpHSV;
 
2059
 
 
2060
    ofs[0] = -1;
 
2061
    ofs[1] = -(colorWheelSize + 4);
 
2062
 
 
2063
    /* offsets are counterclockwise (in triangles).
 
2064
     *
 
2065
     *     ofs[0] ---->
 
2066
     *      _______________________________________
 
2067
     * [1] |_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|  o
 
2068
     *  s  |_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|  f
 
2069
     *  f  |_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|  s
 
2070
     *  o  | | | | | | | | | | | | | | | | | | | | | [3]
 
2071
     *
 
2072
     *                                  <---- ofs[2]
 
2073
     *       ____
 
2074
     *      |\  /| <-- triangles
 
2075
     *      | \/ |
 
2076
     *      | /\ |
 
2077
     *      |/__\|
 
2078
     */
 
2079
 
 
2080
    for (y = 0; y < cw_halfsize; y++) {
 
2081
        for (x = y; x < (colorWheelSize+4-y); x++) {
 
2082
            /* (xcor, ycor) is (x,y) relative to center of matrix */
 
2083
            xcor = 2 * x - 4 - colorWheelSize;
 
2084
            ycor = 2 * y - 4 - colorWheelSize;
 
2085
 
 
2086
            /* RColor.saturation is unsigned char and will wrap after 255 */
 
2087
            sat = rint(255.0 * sqrt(xcor*xcor + ycor*ycor) / colorWheelSize);
 
2088
 
 
2089
            cpColor.hsv.saturation = (unsigned char)sat;
 
2090
 
 
2091
            ofs[0]++;                           /* top quarter of matrix*/
 
2092
            ofs[1] += colorWheelSize + 4;       /* left quarter */
 
2093
            ofs[2] = cw_sqsize - 1 - ofs[0];    /* bottom quarter */
 
2094
            ofs[3] = cw_sqsize - 1 - ofs[1];    /* right quarter */
 
2095
 
 
2096
            if (sat < 256) {
 
2097
                if (xcor != 0)
 
2098
                    dhue[0] = rint(atan((double)ycor / (double)xcor) *
 
2099
                                   (180.0 / M_PI)) + (xcor < 0 ? 180.0 : 0.0);
 
2100
                else
 
2101
                    dhue[0] = 270;
 
2102
 
 
2103
                dhue[0] = 360 - dhue[0];  /* Reverse direction of ColorWheel */
 
2104
                dhue[1] = 270 - dhue[0] + (dhue[0] > 270 ? 360 : 0);
 
2105
                dhue[2] = dhue[0] - 180 + (dhue[0] < 180 ? 360 : 0);
 
2106
                dhue[3] = 90 - dhue[0]  + (dhue[0] > 90  ? 360 : 0);
 
2107
 
 
2108
                for (i = 0; i < 4; i++) {
 
2109
                    rp = panel->wheelMtrx->data[0] + (ofs[i] << uchar_shift);
 
2110
                    gp = panel->wheelMtrx->data[1] + (ofs[i] << uchar_shift);
 
2111
                    bp = panel->wheelMtrx->data[2] + (ofs[i] << uchar_shift);
 
2112
 
 
2113
                    cpColor.hsv.hue = dhue[i];
 
2114
                    convertCPColor(&cpColor);
 
2115
 
 
2116
                    *rp = (unsigned char)(cpColor.rgb.red);
 
2117
                    *gp = (unsigned char)(cpColor.rgb.green);
 
2118
                    *bp = (unsigned char)(cpColor.rgb.blue);
 
2119
                }
 
2120
            }
 
2121
            else {
 
2122
                for (i = 0; i < 4; i++) {
 
2123
                    rp = panel->wheelMtrx->data[0] + (ofs[i] << uchar_shift);
 
2124
                    gp = panel->wheelMtrx->data[1] + (ofs[i] << uchar_shift);
 
2125
                    bp = panel->wheelMtrx->data[2] + (ofs[i] << uchar_shift);
 
2126
 
 
2127
                    *rp = (unsigned char)0;
 
2128
                    *gp = (unsigned char)0;
 
2129
                    *bp = (unsigned char)0;
 
2130
                }
 
2131
            }
 
2132
        }
 
2133
 
 
2134
        ofs[0] += 2*y+1;
 
2135
        ofs[1] += 1 - (colorWheelSize + 4) * (colorWheelSize + 4 - 1 - 2*y);
 
2136
    }
 
2137
}
 
2138
 
 
2139
 
 
2140
static void
 
2141
wheelCalculateValues(W_ColorPanel *panel, int maxvalue)
 
2142
{
 
2143
    unsigned int i;
 
2144
    unsigned int v;
 
2145
 
 
2146
    for (i = 0; i < 256; i++) {
 
2147
        /* We divide by 128 in advance, and check whether that number divides
 
2148
         * by 2 properly. If not, we add one to round the number correctly
 
2149
         */
 
2150
        v = (i*maxvalue) >> 7;
 
2151
        panel->wheelMtrx->values[i] = (unsigned char)((v >> 1) +(v & 0x01));
 
2152
    }
 
2153
}
 
2154
 
 
2155
 
 
2156
static void
 
2157
wheelRender(W_ColorPanel *panel)
 
2158
{
 
2159
    W_Screen            *scr = WMWidgetScreen(panel->win);
 
2160
    int                 x,y;
 
2161
    RImage              *image;
 
2162
    unsigned char       *ptr;
 
2163
    RColor              gray;
 
2164
    unsigned long       ofs = 0;
 
2165
    /*unsigned char     shift = getShift(sizeof(unsigned char));*/
 
2166
 
 
2167
    image = RCreateImage(colorWheelSize+4, colorWheelSize+4, True);
 
2168
    if (!image) {
 
2169
        wwarning(_("Color Panel: Could not allocate memory"));
 
2170
        return;
 
2171
    }
 
2172
 
 
2173
    ptr = image->data;
 
2174
 
 
2175
    /* TODO Make this transparent istead of gray */
 
2176
    gray.red = gray.blue = 0xae; gray.green = 0xaa;
 
2177
 
 
2178
    for (y = 0; y < colorWheelSize+4; y++) {
 
2179
        for (x = 0; x < colorWheelSize+4; x++) {
 
2180
            if (wheelInsideColorWheel(panel, ofs)) {
 
2181
                *(ptr++) = (unsigned char)(panel->wheelMtrx->values[
 
2182
                                                                    panel->wheelMtrx->data[0][ofs] ]);
 
2183
                *(ptr++) = (unsigned char)(panel->wheelMtrx->values[
 
2184
                                                                    panel->wheelMtrx->data[1][ofs] ]);
 
2185
                *(ptr++) = (unsigned char)(panel->wheelMtrx->values[
 
2186
                                                                    panel->wheelMtrx->data[2][ofs] ]);
 
2187
                *(ptr++) = 0;
 
2188
            }
 
2189
            else {
 
2190
                *(ptr++) = (unsigned char)(gray.red);
 
2191
                *(ptr++) = (unsigned char)(gray.green);
 
2192
                *(ptr++) = (unsigned char)(gray.blue);
 
2193
                *(ptr++) = 255;
 
2194
            }
 
2195
            ofs++;
 
2196
        }
 
2197
    }
 
2198
 
 
2199
    if (panel->wheelImg)
 
2200
        XFreePixmap(scr->display, panel->wheelImg);
 
2201
 
 
2202
    RConvertImage(scr->rcontext, image, &panel->wheelImg);
 
2203
    RReleaseImage(image);
 
2204
 
 
2205
    /* Check if backimage exists. If it doesn't, allocate and fill it */
 
2206
    if (!panel->selectionBackImg) {
 
2207
        panel->selectionBackImg = XCreatePixmap(scr->display,
 
2208
                                                W_VIEW(panel->wheelFrm)->window, 4, 4, scr->depth);
 
2209
        XCopyArea(scr->display, panel->wheelImg, panel->selectionBackImg,
 
2210
                  scr->copyGC, panel->colx -2, panel->coly -2, 4, 4, 0, 0);
 
2211
        /* -2 is hot spot correction */
 
2212
    }
 
2213
}
 
2214
 
 
2215
 
 
2216
static Bool
 
2217
wheelInsideColorWheel(W_ColorPanel *panel, unsigned long ofs)
 
2218
{
 
2219
    return ((panel->wheelMtrx->data[0][ofs] != 0) &&
 
2220
            (panel->wheelMtrx->data[1][ofs] != 0) &&
 
2221
            (panel->wheelMtrx->data[2][ofs] != 0));
 
2222
}
 
2223
 
 
2224
 
 
2225
static void
 
2226
wheelPaint (W_ColorPanel *panel)
 
2227
{
 
2228
    W_Screen    *scr = WMWidgetScreen(panel->win);
 
2229
 
 
2230
    XCopyArea(scr->display, panel->wheelImg, panel->wheelView->window,
 
2231
              scr->copyGC, 0, 0, colorWheelSize+4, colorWheelSize+4, 0, 0);
 
2232
 
 
2233
    /* Draw selection image */
 
2234
    XCopyArea(scr->display, panel->selectionImg, panel->wheelView->window,
 
2235
              scr->copyGC, 0, 0, 4, 4, panel->colx -2, panel->coly -2);
 
2236
}
 
2237
 
 
2238
 
 
2239
static void
 
2240
wheelHandleEvents(XEvent *event, void *data)
 
2241
{
 
2242
    W_ColorPanel        *panel = (W_ColorPanel*)data;
 
2243
 
 
2244
    switch (event->type) {
 
2245
    case Expose:
 
2246
        if (event->xexpose.count != 0) /* TODO Improve */
 
2247
            break;
 
2248
        wheelPaint(panel);
 
2249
        break;
 
2250
    }
 
2251
}
 
2252
 
 
2253
 
 
2254
static void
 
2255
wheelHandleActionEvents(XEvent *event, void *data)
 
2256
{
 
2257
    W_ColorPanel        *panel = (W_ColorPanel*)data;
 
2258
 
 
2259
    switch (event->type) {
 
2260
    case ButtonPress:
 
2261
        if (getPickerPart(panel, event->xbutton.x, event->xbutton.y) ==
 
2262
            COLORWHEEL_PART) {
 
2263
 
 
2264
            panel->lastChanged = WMWheelModeColorPanel;
 
2265
            panel->flags.dragging = 1;
 
2266
 
 
2267
            wheelPositionSelection(panel, event->xbutton.x, event->xbutton.y);
 
2268
        }
 
2269
        break;
 
2270
 
 
2271
    case ButtonRelease:
 
2272
        panel->flags.dragging = 0;
 
2273
        if (!panel->flags.continuous) {
 
2274
            if (panel->action)
 
2275
                (*panel->action)(panel, panel->clientData);
 
2276
        }
 
2277
        break;
 
2278
 
 
2279
    case MotionNotify:
 
2280
        if (panel->flags.dragging) {
 
2281
            if (getPickerPart(panel, event->xmotion.x, event->xmotion.y) ==
 
2282
                COLORWHEEL_PART) {
 
2283
                wheelPositionSelection(panel, event->xmotion.x,
 
2284
                                       event->xmotion.y);
 
2285
            }
 
2286
            else
 
2287
                wheelPositionSelectionOutBounds(panel, event->xmotion.x,
 
2288
                                                event->xmotion.y);
 
2289
        }
 
2290
        break;
 
2291
    }
 
2292
}
 
2293
 
 
2294
 
 
2295
static int
 
2296
getPickerPart(W_ColorPanel *panel, int x, int y)
 
2297
{
 
2298
    int                 lx, ly;
 
2299
    unsigned long       ofs;
 
2300
 
 
2301
    lx = x;
 
2302
    ly = y;
 
2303
 
 
2304
    if (panel->mode == WMWheelModeColorPanel) {
 
2305
        if ((lx >= 2) && (lx <= 2+colorWheelSize) && (ly >= 2) &&
 
2306
            (ly <= 2+colorWheelSize)) {
 
2307
 
 
2308
            ofs = ly*panel->wheelMtrx->width+lx;
 
2309
 
 
2310
            if (wheelInsideColorWheel(panel, ofs))
 
2311
                return COLORWHEEL_PART;
 
2312
        }
 
2313
    }
 
2314
 
 
2315
    if (panel->mode == WMCustomPaletteModeColorPanel) {
 
2316
        if ((lx >= 2) && (lx < customPaletteWidth-2) && (ly >= 2) &&
 
2317
            (ly < customPaletteHeight-2)) {
 
2318
            return CUSTOMPALETTE_PART;
 
2319
        }
 
2320
    }
 
2321
 
 
2322
    return 0;
 
2323
}
 
2324
 
 
2325
 
 
2326
static void
 
2327
wheelBrightnessSliderCallback(WMWidget *w, void *data)
 
2328
{
 
2329
    int                 value;
 
2330
 
 
2331
    W_ColorPanel *panel = (W_ColorPanel*)data;
 
2332
 
 
2333
    value = 255-WMGetSliderValue(panel->wheelBrightnessS);
 
2334
 
 
2335
    wheelCalculateValues(panel, value);
 
2336
 
 
2337
    if (panel->color.set == cpRGB) {
 
2338
        convertCPColor(&panel->color);
 
2339
        panel->color.set = cpHSV;
 
2340
    }
 
2341
 
 
2342
    panel->color.hsv.value = value;
 
2343
 
 
2344
    wheelRender(panel);
 
2345
    wheelPaint(panel);
 
2346
    wheelUpdateSelection(panel);
 
2347
}
 
2348
 
 
2349
 
 
2350
static void
 
2351
wheelUpdateSelection(W_ColorPanel *panel)
 
2352
{
 
2353
    W_Screen    *scr = WMWidgetScreen(panel->win);
 
2354
 
 
2355
    updateSwatch(panel, panel->color);
 
2356
    panel->lastChanged = WMWheelModeColorPanel;
 
2357
 
 
2358
    /* Redraw color selector (and make a backup of the part it will cover) */
 
2359
    XCopyArea(scr->display, panel->wheelImg, panel->selectionBackImg,
 
2360
              scr->copyGC, panel->colx -2, panel->coly -2, 4, 4, 0, 0);
 
2361
    /* "-2" is correction for hotspot location */
 
2362
    XCopyArea(scr->display, panel->selectionImg, panel->wheelView->window,
 
2363
              scr->copyGC, 0, 0, 4, 4, panel->colx -2, panel->coly -2);
 
2364
    /* see above */
 
2365
}
 
2366
 
 
2367
 
 
2368
static void
 
2369
wheelUndrawSelection(W_ColorPanel *panel)
 
2370
{
 
2371
    W_Screen    *scr = WMWidgetScreen(panel->win);
 
2372
 
 
2373
    XCopyArea(scr->display, panel->selectionBackImg, panel->wheelView->window,
 
2374
              scr->copyGC, 0, 0, 4, 4, panel->colx -2, panel->coly -2);
 
2375
    /* see above */
 
2376
}
 
2377
 
 
2378
static void
 
2379
wheelPositionSelection(W_ColorPanel *panel, int x, int y)
 
2380
{
 
2381
    unsigned long       ofs = (y * panel->wheelMtrx->width)+ x;
 
2382
 
 
2383
    panel->color.rgb.red        = panel->wheelMtrx->values[
 
2384
                                                           panel->wheelMtrx->data[0][ofs] ];
 
2385
 
 
2386
    panel->color.rgb.green      = panel->wheelMtrx->values[
 
2387
                                                           panel->wheelMtrx->data[1][ofs] ];
 
2388
 
 
2389
    panel->color.rgb.blue       = panel->wheelMtrx->values[
 
2390
                                                           panel->wheelMtrx->data[2][ofs] ];
 
2391
    panel->color.set = cpRGB;
 
2392
 
 
2393
    wheelUndrawSelection(panel);
 
2394
 
 
2395
    panel->colx = x;
 
2396
    panel->coly = y;
 
2397
 
 
2398
    wheelUpdateSelection(panel);
 
2399
    wheelUpdateBrightnessGradientFromLocation(panel);
 
2400
}
 
2401
 
 
2402
static void
 
2403
wheelPositionSelectionOutBounds(W_ColorPanel *panel, int x, int y)
 
2404
{
 
2405
    int         hue;
 
2406
    int         xcor, ycor;
 
2407
    CPColor     cpColor;
 
2408
 
 
2409
    xcor = x * 2 - colorWheelSize - 4;
 
2410
    ycor = y * 2 - colorWheelSize - 4;
 
2411
 
 
2412
    panel->color.hsv.saturation = 255;
 
2413
    panel->color.hsv.value = 255 - WMGetSliderValue(panel->wheelBrightnessS);
 
2414
 
 
2415
    if (xcor != 0)
 
2416
        hue = rint(atan(- (double)ycor / (double)xcor) * (180.0/M_PI));
 
2417
    else {
 
2418
        if (ycor < 0)
 
2419
            hue = 90;
 
2420
        else
 
2421
            hue = 270;
 
2422
    }
 
2423
 
 
2424
    if (xcor < 0)
 
2425
        hue += 180;
 
2426
 
 
2427
    if ((xcor > 0) && (ycor > 0))
 
2428
        hue += 360;
 
2429
 
 
2430
    panel->color.hsv.hue = hue;
 
2431
    panel->color.set = cpHSV;
 
2432
    convertCPColor(&panel->color);
 
2433
 
 
2434
    wheelUndrawSelection(panel);
 
2435
 
 
2436
    panel->colx = 2 + rint((colorWheelSize * (1.0 +
 
2437
                                              cos( panel->color.hsv.hue * (M_PI/180.0) ))) / 2.0);
 
2438
    /* "+2" because of "colorWheelSize + 4" */
 
2439
    panel->coly = 2 + rint((colorWheelSize * (1.0 +
 
2440
                                              sin(- panel->color.hsv.hue * (M_PI/180.0) ))) / 2.0);
 
2441
 
 
2442
    wheelUpdateSelection(panel);
 
2443
    cpColor = panel->color;
 
2444
    wheelUpdateBrightnessGradient(panel, cpColor);
 
2445
}
 
2446
 
 
2447
static void
 
2448
wheelUpdateBrightnessGradientFromLocation(W_ColorPanel *panel)
 
2449
{
 
2450
    CPColor             from;
 
2451
    unsigned long       ofs;
 
2452
 
 
2453
    ofs = panel->coly * panel->wheelMtrx->width + panel->colx;
 
2454
 
 
2455
    from.rgb.red        = panel->wheelMtrx->data[0][ofs];
 
2456
    from.rgb.green      = panel->wheelMtrx->data[1][ofs];
 
2457
    from.rgb.blue       = panel->wheelMtrx->data[2][ofs];
 
2458
    from.set = cpRGB;
 
2459
 
 
2460
    wheelUpdateBrightnessGradient(panel, from);
 
2461
}
 
2462
 
 
2463
static void
 
2464
wheelUpdateBrightnessGradient(W_ColorPanel *panel, CPColor topColor)
 
2465
{
 
2466
    RColor      to;
 
2467
    RImage      *sliderImg;
 
2468
    WMPixmap    *sliderPxmp;
 
2469
 
 
2470
    to.red = to.green = to.blue = 0;
 
2471
 
 
2472
    if (topColor.set == cpHSV)
 
2473
        convertCPColor(&topColor);
 
2474
 
 
2475
    sliderImg = RRenderGradient(16, 153, &(topColor.rgb), &to, RGRD_VERTICAL);
 
2476
    sliderPxmp = WMCreatePixmapFromRImage(WMWidgetScreen(panel->win),
 
2477
                                          sliderImg, 0);
 
2478
    RReleaseImage(sliderImg);
 
2479
    WMSetSliderImage(panel->wheelBrightnessS, sliderPxmp);
 
2480
    WMReleasePixmap(sliderPxmp);
 
2481
}
 
2482
 
 
2483
/****************** Grayscale Panel Functions ***************/
 
2484
 
 
2485
static void
 
2486
grayBrightnessSliderCallback(WMWidget *w, void *data)
 
2487
{
 
2488
    CPColor             cpColor;
 
2489
    int                 value;
 
2490
    char                tmp[4];
 
2491
    W_ColorPanel        *panel = (W_ColorPanel*)data;
 
2492
 
 
2493
    value = WMGetSliderValue(panel->grayBrightnessS);
 
2494
 
 
2495
    sprintf(tmp, "%d", value);
 
2496
 
 
2497
    WMSetTextFieldText(panel->grayBrightnessT, tmp);
 
2498
    cpColor.rgb.red = cpColor.rgb.green = cpColor.rgb.blue = rint(2.55*value);
 
2499
    cpColor.set = cpRGB;
 
2500
 
 
2501
    updateSwatch(panel, cpColor);
 
2502
    panel->lastChanged = WMGrayModeColorPanel;
 
2503
}
 
2504
 
 
2505
static void
 
2506
grayPresetButtonCallback(WMWidget *w, void *data)
 
2507
{
 
2508
    CPColor             cpColor;
 
2509
    char                tmp[4];
 
2510
    int                 value;
 
2511
    int                 i=0;
 
2512
    W_ColorPanel        *panel = (W_ColorPanel*)data;
 
2513
 
 
2514
    while (i < 7) {
 
2515
        if (w == panel->grayPresetBtn[i])
 
2516
            break;
 
2517
        i++;
 
2518
    }
 
2519
 
 
2520
    value = rint((100.0*i)/6.0);
 
2521
    sprintf(tmp, "%d", value);
 
2522
 
 
2523
    WMSetTextFieldText(panel->grayBrightnessT, tmp);
 
2524
    cpColor.rgb.red = cpColor.rgb.green = cpColor.rgb.blue =
 
2525
        rint((255.0*i)/6.0);
 
2526
    cpColor.set = cpRGB;
 
2527
 
 
2528
    WMSetSliderValue(panel->grayBrightnessS, rint((100.0*i)/6.0));
 
2529
 
 
2530
    updateSwatch(panel, cpColor);
 
2531
    panel->lastChanged = WMGrayModeColorPanel;
 
2532
}
 
2533
 
 
2534
static void
 
2535
grayBrightnessTextFieldCallback(void *observerData,
 
2536
                                WMNotification *notification)
 
2537
{
 
2538
    CPColor             cpColor;
 
2539
    char                tmp[4];
 
2540
    int                 value;
 
2541
    W_ColorPanel        *panel = (W_ColorPanel*)observerData;
 
2542
 
 
2543
    value = atoi(WMGetTextFieldText(panel->grayBrightnessT));
 
2544
    if (value > 100)
 
2545
        value = 100;
 
2546
    if (value < 0)
 
2547
        value = 0;
 
2548
 
 
2549
    sprintf(tmp, "%d", value);
 
2550
    WMSetTextFieldText(panel->grayBrightnessT, tmp);
 
2551
    WMSetSliderValue(panel->grayBrightnessS, value);
 
2552
 
 
2553
    cpColor.rgb.red = cpColor.rgb.green = cpColor.rgb.blue =
 
2554
        rint((255.0*value)/100.0);
 
2555
    cpColor.set = cpRGB;
 
2556
 
 
2557
    updateSwatch(panel, cpColor);
 
2558
    panel->lastChanged = WMGrayModeColorPanel;
 
2559
}
 
2560
 
 
2561
/******************* RGB Panel Functions *****************/
 
2562
 
 
2563
static void
 
2564
rgbSliderCallback(WMWidget *w, void *data)
 
2565
{
 
2566
    CPColor             cpColor;
 
2567
    int                 value[3];
 
2568
    char                tmp[4];
 
2569
    W_ColorPanel        *panel = (W_ColorPanel*)data;
 
2570
 
 
2571
    value[0] = WMGetSliderValue(panel->rgbRedS);
 
2572
    value[1] = WMGetSliderValue(panel->rgbGreenS);
 
2573
    value[2] = WMGetSliderValue(panel->rgbBlueS);
 
2574
 
 
2575
    sprintf(tmp, "%d", value[0]);
 
2576
    WMSetTextFieldText(panel->rgbRedT, tmp);
 
2577
    sprintf(tmp, "%d", value[1]);
 
2578
    WMSetTextFieldText(panel->rgbGreenT, tmp);
 
2579
    sprintf(tmp, "%d", value[2]);
 
2580
    WMSetTextFieldText(panel->rgbBlueT, tmp);
 
2581
 
 
2582
    cpColor.rgb.red   = value[0];
 
2583
    cpColor.rgb.green = value[1];
 
2584
    cpColor.rgb.blue  = value[2];
 
2585
    cpColor.set = cpRGB;
 
2586
 
 
2587
    updateSwatch(panel, cpColor);
 
2588
    panel->lastChanged = WMRGBModeColorPanel;
 
2589
}
 
2590
 
 
2591
static void
 
2592
rgbTextFieldCallback(void *observerData, WMNotification *notification)
 
2593
{
 
2594
    CPColor             cpColor;
 
2595
    int                 value[3];
 
2596
    char                tmp[4];
 
2597
    int                 n;
 
2598
    W_ColorPanel        *panel = (W_ColorPanel*)observerData;
 
2599
 
 
2600
    value[0] = atoi(WMGetTextFieldText(panel->rgbRedT));
 
2601
    value[1] = atoi(WMGetTextFieldText(panel->rgbGreenT));
 
2602
    value[2] = atoi(WMGetTextFieldText(panel->rgbBlueT));
 
2603
 
 
2604
    for (n=0; n < 3; n++) {
 
2605
        if (value[n] > 255)
 
2606
            value[n] = 255;
 
2607
        if (value[n] < 0)
 
2608
            value[n] = 0;
 
2609
    }
 
2610
 
 
2611
    sprintf(tmp, "%d", value[0]);
 
2612
    WMSetTextFieldText(panel->rgbRedT, tmp);
 
2613
    sprintf(tmp, "%d", value[1]);
 
2614
    WMSetTextFieldText(panel->rgbGreenT, tmp);
 
2615
    sprintf(tmp, "%d", value[2]);
 
2616
    WMSetTextFieldText(panel->rgbBlueT, tmp);
 
2617
 
 
2618
    WMSetSliderValue(panel->rgbRedS, value[0]);
 
2619
    WMSetSliderValue(panel->rgbGreenS, value[1]);
 
2620
    WMSetSliderValue(panel->rgbBlueS, value[2]);
 
2621
 
 
2622
    cpColor.rgb.red   = value[0];
 
2623
    cpColor.rgb.green = value[1];
 
2624
    cpColor.rgb.blue  = value[2];
 
2625
    cpColor.set = cpRGB;
 
2626
 
 
2627
    updateSwatch(panel, cpColor);
 
2628
    panel->lastChanged = WMRGBModeColorPanel;
 
2629
}
 
2630
 
 
2631
 
 
2632
/******************* CMYK Panel Functions *****************/
 
2633
 
 
2634
static void
 
2635
cmykSliderCallback(WMWidget *w, void *data)
 
2636
{
 
2637
    CPColor             cpColor;
 
2638
    int                 value[4];
 
2639
    char                tmp[4];
 
2640
    W_ColorPanel        *panel = (W_ColorPanel*)data;
 
2641
    double              scale;
 
2642
 
 
2643
    value[0] = WMGetSliderValue(panel->cmykCyanS);
 
2644
    value[1] = WMGetSliderValue(panel->cmykMagentaS);
 
2645
    value[2] = WMGetSliderValue(panel->cmykYellowS);
 
2646
    value[3] = WMGetSliderValue(panel->cmykBlackS);
 
2647
 
 
2648
    sprintf(tmp, "%d", value[0]);
 
2649
    WMSetTextFieldText(panel->cmykCyanT, tmp);
 
2650
    sprintf(tmp, "%d", value[1]);
 
2651
    WMSetTextFieldText(panel->cmykMagentaT, tmp);
 
2652
    sprintf(tmp, "%d", value[2]);
 
2653
    WMSetTextFieldText(panel->cmykYellowT, tmp);
 
2654
    sprintf(tmp, "%d", value[3]);
 
2655
    WMSetTextFieldText(panel->cmykBlackT, tmp);
 
2656
 
 
2657
    scale = 2.55 * (1.0 - (value[3] / 100.0));
 
2658
    cpColor.rgb.red     = rint((100.0 - value[0]) * scale);
 
2659
    cpColor.rgb.green   = rint((100.0 - value[1]) * scale);
 
2660
    cpColor.rgb.blue    = rint((100.0 - value[2]) * scale);
 
2661
    cpColor.set = cpRGB;
 
2662
 
 
2663
    updateSwatch(panel, cpColor);
 
2664
    panel->lastChanged = WMCMYKModeColorPanel;
 
2665
}
 
2666
 
 
2667
static void
 
2668
cmykTextFieldCallback(void *observerData, WMNotification *notification)
 
2669
{
 
2670
    CPColor             cpColor;
 
2671
    int                 value[4];
 
2672
    char                tmp[4];
 
2673
    int                 n;
 
2674
    double              scale;
 
2675
    W_ColorPanel        *panel = (W_ColorPanel*)observerData;
 
2676
 
 
2677
    value[0] = atoi(WMGetTextFieldText(panel->cmykCyanT));
 
2678
    value[1] = atoi(WMGetTextFieldText(panel->cmykMagentaT));
 
2679
    value[2] = atoi(WMGetTextFieldText(panel->cmykYellowT));
 
2680
    value[3] = atoi(WMGetTextFieldText(panel->cmykBlackT));
 
2681
 
 
2682
    for (n=0; n < 4; n++) {
 
2683
        if (value[n] > 100)
 
2684
            value[n] = 100;
 
2685
        if (value[n] < 0)
 
2686
            value[n] = 0;
 
2687
    }
 
2688
 
 
2689
    sprintf(tmp, "%d", value[0]);
 
2690
    WMSetTextFieldText(panel->cmykCyanT, tmp);
 
2691
 
 
2692
    sprintf(tmp, "%d", value[1]);
 
2693
    WMSetTextFieldText(panel->cmykMagentaT, tmp);
 
2694
 
 
2695
    sprintf(tmp, "%d", value[2]);
 
2696
    WMSetTextFieldText(panel->cmykYellowT, tmp);
 
2697
 
 
2698
    sprintf(tmp, "%d", value[3]);
 
2699
    WMSetTextFieldText(panel->cmykBlackT, tmp);
 
2700
 
 
2701
    WMSetSliderValue(panel->cmykCyanS, value[0]);
 
2702
    WMSetSliderValue(panel->cmykMagentaS, value[1]);
 
2703
    WMSetSliderValue(panel->cmykYellowS, value[2]);
 
2704
    WMSetSliderValue(panel->cmykBlackS, value[3]);
 
2705
 
 
2706
    scale = 2.55 * (1.0 - (value[3] / 100.0));
 
2707
    cpColor.rgb.red     = rint((100.0 - value[0]) * scale);
 
2708
    cpColor.rgb.green   = rint((100.0 - value[1]) * scale);
 
2709
    cpColor.rgb.blue    = rint((100.0 - value[2]) * scale);
 
2710
    cpColor.set = cpRGB;
 
2711
 
 
2712
    updateSwatch(panel, cpColor);
 
2713
    panel->lastChanged = WMCMYKModeColorPanel;
 
2714
}
 
2715
 
 
2716
/********************** HSB Panel Functions ***********************/
 
2717
 
 
2718
static void
 
2719
hsbSliderCallback(WMWidget *w, void *data)
 
2720
{
 
2721
    CPColor             cpColor;
 
2722
    int                 value[3];
 
2723
    char                tmp[4];
 
2724
    W_ColorPanel        *panel = (W_ColorPanel*)data;
 
2725
 
 
2726
    value[0] = WMGetSliderValue(panel->hsbHueS);
 
2727
    value[1] = WMGetSliderValue(panel->hsbSaturationS);
 
2728
    value[2] = WMGetSliderValue(panel->hsbBrightnessS);
 
2729
 
 
2730
    sprintf(tmp, "%d", value[0]);
 
2731
    WMSetTextFieldText(panel->hsbHueT, tmp);
 
2732
    sprintf(tmp, "%d", value[1]);
 
2733
    WMSetTextFieldText(panel->hsbSaturationT, tmp);
 
2734
    sprintf(tmp, "%d", value[2]);
 
2735
    WMSetTextFieldText(panel->hsbBrightnessT, tmp);
 
2736
 
 
2737
    cpColor.hsv.hue = value[0];
 
2738
    cpColor.hsv.saturation = value[1]*2.55;
 
2739
    cpColor.hsv.value = value[2]*2.55;
 
2740
    cpColor.set = cpHSV;
 
2741
 
 
2742
    convertCPColor(&cpColor);
 
2743
 
 
2744
    panel->lastChanged = WMHSBModeColorPanel;
 
2745
    updateSwatch(panel, cpColor);
 
2746
 
 
2747
    if (w != panel->hsbBrightnessS)
 
2748
        hsbUpdateBrightnessGradient(panel);
 
2749
    if (w != panel->hsbSaturationS)
 
2750
        hsbUpdateSaturationGradient(panel);
 
2751
    if (w != panel->hsbHueS)
 
2752
        hsbUpdateHueGradient(panel);
 
2753
}
 
2754
 
 
2755
static void
 
2756
hsbTextFieldCallback(void *observerData, WMNotification *notification)
 
2757
{
 
2758
    CPColor             cpColor;
 
2759
    int                 value[3];
 
2760
    char                tmp[4];
 
2761
    int                 n;
 
2762
    W_ColorPanel        *panel = (W_ColorPanel*)observerData;
 
2763
 
 
2764
    value[0] = atoi(WMGetTextFieldText(panel->hsbHueT));
 
2765
    value[1] = atoi(WMGetTextFieldText(panel->hsbSaturationT));
 
2766
    value[2] = atoi(WMGetTextFieldText(panel->hsbBrightnessT));
 
2767
 
 
2768
    if (value[0] > 359)
 
2769
        value[0] = 359;
 
2770
    if (value[0] < 0)
 
2771
        value[0] = 0;
 
2772
 
 
2773
    for (n=1; n < 3; n++) {
 
2774
        if (value[n] > 100)
 
2775
            value[n] = 100;
 
2776
        if (value[n] < 0)
 
2777
            value[n] = 0;
 
2778
    }
 
2779
 
 
2780
    sprintf(tmp, "%d", value[0]);
 
2781
    WMSetTextFieldText(panel->hsbHueT, tmp);
 
2782
    sprintf(tmp, "%d", value[1]);
 
2783
    WMSetTextFieldText(panel->hsbSaturationT, tmp);
 
2784
    sprintf(tmp, "%d", value[2]);
 
2785
    WMSetTextFieldText(panel->hsbBrightnessT, tmp);
 
2786
 
 
2787
    WMSetSliderValue(panel->hsbHueS, value[0]);
 
2788
    WMSetSliderValue(panel->hsbSaturationS, value[1]);
 
2789
    WMSetSliderValue(panel->hsbBrightnessS, value[2]);
 
2790
 
 
2791
    cpColor.hsv.hue = value[0];
 
2792
    cpColor.hsv.saturation = value[1]*2.55;
 
2793
    cpColor.hsv.value = value[2]*2.55;
 
2794
    cpColor.set = cpHSV;
 
2795
 
 
2796
    convertCPColor(&cpColor);
 
2797
 
 
2798
    panel->lastChanged = WMHSBModeColorPanel;
 
2799
    updateSwatch(panel, cpColor);
 
2800
 
 
2801
    hsbUpdateBrightnessGradient(panel);
 
2802
    hsbUpdateSaturationGradient(panel);
 
2803
    hsbUpdateHueGradient(panel);
 
2804
}
 
2805
 
 
2806
static void
 
2807
hsbUpdateBrightnessGradient(W_ColorPanel *panel)
 
2808
{
 
2809
    W_Screen    *scr = WMWidgetScreen(panel->win);
 
2810
    RColor      from;
 
2811
    CPColor     to;
 
2812
    RImage      *sliderImg;
 
2813
    WMPixmap    *sliderPxmp;
 
2814
 
 
2815
    from.red = from.green = from.blue = 0;
 
2816
    to.hsv = panel->color.hsv;
 
2817
    to.hsv.value = 255;
 
2818
    to.set = cpHSV;
 
2819
 
 
2820
    convertCPColor(&to);
 
2821
 
 
2822
    sliderImg = RRenderGradient(141, 16, &from, &(to.rgb), RGRD_HORIZONTAL);
 
2823
    sliderPxmp = WMCreatePixmapFromRImage(scr, sliderImg, 0);
 
2824
    RReleaseImage(sliderImg);
 
2825
 
 
2826
    if (sliderPxmp)
 
2827
        W_PaintText(W_VIEW(panel->hsbBrightnessS), sliderPxmp->pixmap,
 
2828
                    panel->font12, 2, 0, 100, WALeft, scr->white,
 
2829
                    False, _("Brightness"), strlen(_("Brightness")));
 
2830
    else
 
2831
        wwarning(_("Color Panel: Could not allocate memory"));
 
2832
 
 
2833
    WMSetSliderImage(panel->hsbBrightnessS, sliderPxmp);
 
2834
    WMReleasePixmap(sliderPxmp);
 
2835
}
 
2836
 
 
2837
static void
 
2838
hsbUpdateSaturationGradient(W_ColorPanel *panel)
 
2839
{
 
2840
    W_Screen    *scr = WMWidgetScreen(panel->win);
 
2841
    CPColor     from;
 
2842
    CPColor     to;
 
2843
    RImage      *sliderImg;
 
2844
    WMPixmap    *sliderPxmp;
 
2845
 
 
2846
    from.hsv = panel->color.hsv;
 
2847
    from.hsv.saturation = 0;
 
2848
    from.set = cpHSV;
 
2849
    convertCPColor(&from);
 
2850
 
 
2851
    to.hsv = panel->color.hsv;
 
2852
    to.hsv.saturation = 255;
 
2853
    to.set = cpHSV;
 
2854
    convertCPColor(&to);
 
2855
 
 
2856
    sliderImg = RRenderGradient(141, 16, &(from.rgb), &(to.rgb),
 
2857
                                RGRD_HORIZONTAL);
 
2858
    sliderPxmp = WMCreatePixmapFromRImage(scr, sliderImg, 0);
 
2859
    RReleaseImage(sliderImg);
 
2860
 
 
2861
    if (sliderPxmp)
 
2862
        W_PaintText(W_VIEW(panel->hsbSaturationS), sliderPxmp->pixmap,
 
2863
                    panel->font12, 2, 0, 100, WALeft,
 
2864
                    from.hsv.value < 128 ? scr->white : scr->black, False,
 
2865
                    _("Saturation"), strlen(_("Saturation")));
 
2866
    else
 
2867
        wwarning(_("Color Panel: Could not allocate memory"));
 
2868
 
 
2869
    WMSetSliderImage(panel->hsbSaturationS, sliderPxmp);
 
2870
    WMReleasePixmap(sliderPxmp);
 
2871
}
 
2872
 
 
2873
static void
 
2874
hsbUpdateHueGradient(W_ColorPanel *panel)
 
2875
{
 
2876
    W_Screen    *scr = WMWidgetScreen(panel->win);
 
2877
    RColor      **colors = NULL;
 
2878
    RHSVColor   hsvcolor;
 
2879
    RImage      *sliderImg;
 
2880
    WMPixmap    *sliderPxmp;
 
2881
    int         i;
 
2882
 
 
2883
    hsvcolor = panel->color.hsv;
 
2884
 
 
2885
    colors = wmalloc(sizeof(RColor*)*(8));
 
2886
    for (i=0; i<7; i++) {
 
2887
        hsvcolor.hue = (360*i)/6;
 
2888
        colors[i] = wmalloc(sizeof(RColor));
 
2889
        RHSVtoRGB(&hsvcolor, colors[i]);
 
2890
    }
 
2891
    colors[7] = NULL;
 
2892
 
 
2893
    sliderImg = RRenderMultiGradient(141, 16, colors, RGRD_HORIZONTAL);
 
2894
    sliderPxmp = WMCreatePixmapFromRImage(scr, sliderImg, 0);
 
2895
    RReleaseImage(sliderImg);
 
2896
 
 
2897
    if (sliderPxmp)
 
2898
        W_PaintText(W_VIEW(panel->hsbHueS), sliderPxmp->pixmap,
 
2899
                    panel->font12, 2, 0, 100, WALeft,
 
2900
                    hsvcolor.value < 128 ? scr->white : scr->black, False,
 
2901
                    _("Hue"), strlen(_("Hue")));
 
2902
    else
 
2903
        wwarning(_("Color Panel: Could not allocate memory"));
 
2904
 
 
2905
    WMSetSliderImage(panel->hsbHueS, sliderPxmp);
 
2906
    WMReleasePixmap(sliderPxmp);
 
2907
 
 
2908
    for (i=0; i<7; i++)
 
2909
        wfree(colors[i]);
 
2910
 
 
2911
    wfree(colors);
 
2912
}
 
2913
 
 
2914
/*************** Custom Palette Functions ****************/
 
2915
 
 
2916
static void
 
2917
customRenderSpectrum(W_ColorPanel *panel)
 
2918
{
 
2919
    RImage              *spectrum;
 
2920
    int                 x,y;
 
2921
    unsigned char       *ptr;
 
2922
    CPColor             cpColor;
 
2923
 
 
2924
    spectrum = RCreateImage(SPECTRUM_WIDTH, SPECTRUM_HEIGHT, False);
 
2925
 
 
2926
    ptr = spectrum->data;
 
2927
 
 
2928
    for (y = 0; y < SPECTRUM_HEIGHT; y++) {
 
2929
        cpColor.hsv.hue = y;
 
2930
        cpColor.hsv.saturation = 0;
 
2931
        cpColor.hsv.value = 255;
 
2932
        cpColor.set = cpHSV;
 
2933
 
 
2934
        for (x = 0; x < SPECTRUM_WIDTH; x++) {
 
2935
            convertCPColor(&cpColor);
 
2936
 
 
2937
            *(ptr++) = (unsigned char)cpColor.rgb.red;
 
2938
            *(ptr++) = (unsigned char)cpColor.rgb.green;
 
2939
            *(ptr++) = (unsigned char)cpColor.rgb.blue;
 
2940
 
 
2941
            if (x < (SPECTRUM_WIDTH/2))
 
2942
                cpColor.hsv.saturation++;
 
2943
 
 
2944
            if (x > (SPECTRUM_WIDTH/2))
 
2945
                cpColor.hsv.value--;
 
2946
        }
 
2947
    }
 
2948
    if (panel->customPaletteImg)        {
 
2949
        RReleaseImage(panel->customPaletteImg);
 
2950
        panel->customPaletteImg = NULL;
 
2951
    }
 
2952
    panel->customPaletteImg = spectrum;
 
2953
}
 
2954
 
 
2955
 
 
2956
 
 
2957
static void
 
2958
customSetPalette(W_ColorPanel *panel)
 
2959
{
 
2960
    W_Screen    *scr = WMWidgetScreen(panel->win);
 
2961
    RImage      *scaledImg;
 
2962
    Pixmap      image;
 
2963
    int         item;
 
2964
 
 
2965
    image = XCreatePixmap(scr->display, W_DRAWABLE(scr), customPaletteWidth,
 
2966
                          customPaletteHeight, scr->depth);
 
2967
    scaledImg = RScaleImage(panel->customPaletteImg, customPaletteWidth,
 
2968
                            customPaletteHeight);
 
2969
    RConvertImage(scr->rcontext, scaledImg, &image);
 
2970
    RReleaseImage(scaledImg);
 
2971
 
 
2972
    XCopyArea(scr->display, image, panel->customPaletteContentView->window,
 
2973
              scr->copyGC, 0, 0, customPaletteWidth, customPaletteHeight, 0, 0);
 
2974
 
 
2975
    /* Check backimage exists. If it doesn't, allocate and fill it */
 
2976
    if (!panel->selectionBackImg) {
 
2977
        panel->selectionBackImg = XCreatePixmap(scr->display,
 
2978
                                                panel->customPaletteContentView->window, 4, 4, scr->depth);
 
2979
    }
 
2980
 
 
2981
    XCopyArea(scr->display, image, panel->selectionBackImg, scr->copyGC,
 
2982
              panel->palx-2, panel->paly-2, 4, 4, 0, 0);
 
2983
    XCopyArea(scr->display, panel->selectionImg,
 
2984
              panel->customPaletteContentView->window, scr->copyGC, 0 , 0, 4, 4,
 
2985
              panel->palx-2, panel->paly-2);
 
2986
    XFreePixmap(scr->display, image);
 
2987
 
 
2988
    panel->palXRatio = (double)(panel->customPaletteImg->width) /
 
2989
        (double)(customPaletteWidth);
 
2990
    panel->palYRatio = (double)(panel->customPaletteImg->height) /
 
2991
        (double)(customPaletteHeight);
 
2992
 
 
2993
    item = WMGetPopUpButtonSelectedItem (panel->customPaletteHistoryBtn);
 
2994
}
 
2995
 
 
2996
 
 
2997
static void
 
2998
customPalettePositionSelection(W_ColorPanel *panel, int x, int y)
 
2999
{
 
3000
    W_Screen            *scr = WMWidgetScreen(panel->win);
 
3001
    unsigned long       ofs;
 
3002
 
 
3003
 
 
3004
    /* undraw selection */
 
3005
    XCopyArea(scr->display, panel->selectionBackImg,
 
3006
              panel->customPaletteContentView->window, scr->copyGC, 0, 0, 4, 4,
 
3007
              panel->palx-2, panel->paly-2);
 
3008
 
 
3009
    panel->palx = x;
 
3010
    panel->paly = y;
 
3011
 
 
3012
    ofs = (rint(x * panel->palXRatio) + rint(y * panel->palYRatio) *
 
3013
           panel->customPaletteImg->width) * 3;
 
3014
 
 
3015
    panel->color.rgb.red   = panel->customPaletteImg->data[ofs];
 
3016
    panel->color.rgb.green = panel->customPaletteImg->data[ofs+1];
 
3017
    panel->color.rgb.blue  = panel->customPaletteImg->data[ofs+2];
 
3018
    panel->color.set = cpRGB;
 
3019
 
 
3020
    updateSwatch(panel, panel->color);
 
3021
    panel->lastChanged = WMCustomPaletteModeColorPanel;
 
3022
 
 
3023
    /* Redraw color selector (and make a backup of the part it will cover) */
 
3024
    XCopyArea(scr->display, panel->customPaletteContentView->window,
 
3025
              panel->selectionBackImg, scr->copyGC, panel->palx-2, panel->paly-2,
 
3026
              4, 4, 0, 0);      /* "-2" is correction for hotspot location */
 
3027
    XCopyArea(scr->display, panel->selectionImg,
 
3028
              panel->customPaletteContentView->window, scr->copyGC, 0, 0, 4, 4,
 
3029
              panel->palx-2, panel->paly-2);    /* see above */
 
3030
}
 
3031
 
 
3032
 
 
3033
static void
 
3034
customPalettePositionSelectionOutBounds(W_ColorPanel *panel, int x, int y)
 
3035
{
 
3036
    if (x < 2)
 
3037
        x = 2;
 
3038
    if (y < 2)
 
3039
        y = 2;
 
3040
    if (x >= customPaletteWidth)
 
3041
        x = customPaletteWidth -2;
 
3042
    if (y >= customPaletteHeight)
 
3043
        y = customPaletteHeight -2;
 
3044
 
 
3045
    customPalettePositionSelection(panel, x, y);
 
3046
}
 
3047
 
 
3048
 
 
3049
static void
 
3050
customPaletteHandleEvents(XEvent *event, void *data)
 
3051
{
 
3052
    W_ColorPanel        *panel = (W_ColorPanel*)data;
 
3053
 
 
3054
    switch (event->type) {
 
3055
    case Expose:
 
3056
        if (event->xexpose.count != 0) /* TODO Improve. */
 
3057
            break;
 
3058
        customSetPalette(panel);
 
3059
        break;
 
3060
    }
 
3061
}
 
3062
 
 
3063
static void
 
3064
customPaletteHandleActionEvents(XEvent *event, void *data)
 
3065
{
 
3066
    W_ColorPanel        *panel = (W_ColorPanel*)data;
 
3067
    int                 x, y;
 
3068
 
 
3069
    switch (event->type) {
 
3070
    case ButtonPress:
 
3071
        x = event->xbutton.x;
 
3072
        y = event->xbutton.y;
 
3073
 
 
3074
        if (getPickerPart(panel, x, y) == CUSTOMPALETTE_PART) {
 
3075
            panel->flags.dragging = 1;
 
3076
            customPalettePositionSelection(panel, x, y);
 
3077
        }
 
3078
        break;
 
3079
 
 
3080
    case ButtonRelease:
 
3081
        panel->flags.dragging = 0;
 
3082
        if (!panel->flags.continuous) {
 
3083
            if (panel->action)
 
3084
                (*panel->action)(panel, panel->clientData);
 
3085
        }
 
3086
        break;
 
3087
 
 
3088
    case MotionNotify:
 
3089
        x = event->xmotion.x;
 
3090
        y = event->xmotion.y;
 
3091
 
 
3092
        if (panel->flags.dragging) {
 
3093
            if (getPickerPart(panel, x, y) == CUSTOMPALETTE_PART) {
 
3094
                customPalettePositionSelection(panel, x, y);
 
3095
            }
 
3096
            else
 
3097
                customPalettePositionSelectionOutBounds(panel, x, y);
 
3098
        }
 
3099
        break;
 
3100
    }
 
3101
}
 
3102
 
 
3103
 
 
3104
static void
 
3105
customPaletteMenuCallback(WMWidget *w, void *data)
 
3106
{
 
3107
    W_ColorPanel        *panel = (W_ColorPanel*)data;
 
3108
    int item = WMGetPopUpButtonSelectedItem(panel->customPaletteMenuBtn);
 
3109
 
 
3110
    switch (item) {
 
3111
    case CPmenuNewFromFile:
 
3112
        customPaletteMenuNewFromFile(panel);
 
3113
        break;
 
3114
    case CPmenuRename:
 
3115
        customPaletteMenuRename(panel);
 
3116
        break;
 
3117
    case CPmenuRemove:
 
3118
        customPaletteMenuRemove(panel);
 
3119
        break;
 
3120
    case CPmenuCopy:
 
3121
        break;
 
3122
    case CPmenuNewFromClipboard:
 
3123
        break;
 
3124
    }
 
3125
}
 
3126
 
 
3127
 
 
3128
static void
 
3129
customPaletteMenuNewFromFile(W_ColorPanel *panel)
 
3130
{
 
3131
    W_Screen    *scr = WMWidgetScreen(panel->win);
 
3132
    WMOpenPanel *browseP;
 
3133
    char        *filepath;
 
3134
    char        *filename = NULL;
 
3135
    char        *spath;
 
3136
    char        *tmp;
 
3137
    int         i;
 
3138
    RImage      *tmpImg = NULL;
 
3139
 
 
3140
    if ((!panel->lastBrowseDir) || (strcmp(panel->lastBrowseDir,"\0") == 0))
 
3141
        spath = wexpandpath(wgethomedir());
 
3142
    else
 
3143
        spath = wexpandpath(panel->lastBrowseDir);
 
3144
 
 
3145
    browseP = WMGetOpenPanel(scr);
 
3146
    WMSetFilePanelCanChooseDirectories(browseP, 0);
 
3147
    WMSetFilePanelCanChooseFiles(browseP, 1);
 
3148
 
 
3149
    /* Get a filename */
 
3150
    if (WMRunModalFilePanelForDirectory(browseP, panel->win, spath,
 
3151
                                        _("Open Palette"), RSupportedFileFormats()) ) {
 
3152
        filepath = WMGetFilePanelFileName(browseP);
 
3153
 
 
3154
        /* Get seperation position between path and filename */
 
3155
        i = strrchr(filepath, '/') - filepath + 1;
 
3156
        if (i > strlen(filepath))
 
3157
            i = strlen(filepath);
 
3158
 
 
3159
        /* Store last browsed path */
 
3160
        if (panel->lastBrowseDir)
 
3161
            wfree(panel->lastBrowseDir);
 
3162
        panel->lastBrowseDir = wmalloc((i+1)*sizeof(char));
 
3163
        strncpy(panel->lastBrowseDir, filepath, i);
 
3164
        panel->lastBrowseDir[i] = '\0';
 
3165
 
 
3166
        /* Get filename from path */
 
3167
        filename = wstrdup(filepath + i);
 
3168
 
 
3169
        /* Check for duplicate files, and rename it if there are any */
 
3170
        tmp = wstrconcat(panel->configurationPath, filename);
 
3171
        while (access (tmp, F_OK) == 0) {
 
3172
            char        *newName;
 
3173
 
 
3174
            wfree(tmp);
 
3175
 
 
3176
            newName = generateNewFilename(filename);
 
3177
            wfree(filename);
 
3178
            filename = newName;
 
3179
 
 
3180
            tmp = wstrconcat(panel->configurationPath, filename);
 
3181
        }
 
3182
        wfree(tmp);
 
3183
 
 
3184
        /* Copy image to $(gnustepdir)/Library/Colors/ &
 
3185
         * Add filename to history menu */
 
3186
        if (fetchFile (panel->configurationPath, filepath, filename) == 0) {
 
3187
 
 
3188
            /* filepath is a "local" path now the file has been copied */
 
3189
            wfree(filepath);
 
3190
            filepath = wstrconcat(panel->configurationPath, filename);
 
3191
 
 
3192
            /* load the image & add menu entries */
 
3193
            tmpImg = RLoadImage(scr->rcontext, filepath, 0);
 
3194
            if (tmpImg) {
 
3195
                if (panel->customPaletteImg)
 
3196
                    RReleaseImage(panel->customPaletteImg);
 
3197
                panel->customPaletteImg = tmpImg;
 
3198
 
 
3199
                customSetPalette(panel);
 
3200
                WMAddPopUpButtonItem(panel->customPaletteHistoryBtn, filename);
 
3201
 
 
3202
                panel->currentPalette = WMGetPopUpButtonNumberOfItems(
 
3203
                                                                      panel->customPaletteHistoryBtn)-1;
 
3204
 
 
3205
                WMSetPopUpButtonSelectedItem(panel->customPaletteHistoryBtn,
 
3206
                                             panel->currentPalette);
 
3207
            }
 
3208
        } else {
 
3209
            tmp = wstrconcat(panel->configurationPath, filename);
 
3210
 
 
3211
            i = remove(tmp);    /* Delete the file, it doesn't belong here */
 
3212
            WMRunAlertPanel(scr, panel->win, _("File Error"),
 
3213
                            _("Invalid file format !"), _("OK"), NULL, NULL);
 
3214
            if (i != 0) {
 
3215
                wsyserror(_("can't remove file %s"), tmp);
 
3216
                WMRunAlertPanel(scr, panel->win, _("File Error"),
 
3217
                                _("Couldn't remove file from Configuration Directory !"),
 
3218
                                _("OK"), NULL, NULL);
 
3219
            }
 
3220
            wfree(tmp);
 
3221
        }
 
3222
        wfree(filepath);
 
3223
        wfree(filename);
 
3224
    }
 
3225
    WMFreeFilePanel(browseP);
 
3226
 
 
3227
    wfree(spath);
 
3228
}
 
3229
 
 
3230
 
 
3231
static void
 
3232
customPaletteMenuRename(W_ColorPanel *panel)
 
3233
{
 
3234
    W_Screen    *scr = WMWidgetScreen(panel->win);
 
3235
    char        *toName = NULL;
 
3236
    char        *fromName;
 
3237
    char        *toPath, *fromPath;
 
3238
    int         item;
 
3239
    int         index;
 
3240
 
 
3241
    item = WMGetPopUpButtonSelectedItem(panel->customPaletteHistoryBtn);
 
3242
    fromName = WMGetPopUpButtonItem(panel->customPaletteHistoryBtn, item);
 
3243
 
 
3244
    toName = WMRunInputPanel(scr, panel->win, _("Rename"), _("Rename palette to:"),
 
3245
                             fromName, _("OK"), _("Cancel"));
 
3246
 
 
3247
    if (toName) {
 
3248
 
 
3249
        /* As some people do certain stupid things... */
 
3250
        if (strcmp(toName, fromName) == 0) {
 
3251
            wfree(toName);
 
3252
            return;
 
3253
        }
 
3254
 
 
3255
        /* For normal people */
 
3256
        fromPath = wstrconcat(panel->configurationPath, fromName);
 
3257
        toPath   = wstrconcat(panel->configurationPath, toName);
 
3258
 
 
3259
        if (access (toPath, F_OK) == 0) {
 
3260
            /* Careful, this palette exists already */
 
3261
            if (WMRunAlertPanel(scr, panel->win, _("Warning"),
 
3262
                                _("Palette already exists !\n\nOverwrite ?"), _("No"), _("Yes"),
 
3263
                                NULL) == 1) {
 
3264
                /* "No" = 0, "Yes" = 1 */
 
3265
                int items = WMGetPopUpButtonNumberOfItems(
 
3266
                                                          panel->customPaletteHistoryBtn);
 
3267
 
 
3268
                remove(toPath);
 
3269
 
 
3270
                /* Remove from History list too */
 
3271
                index = 1;
 
3272
                while ((index < items) && (strcmp(WMGetPopUpButtonItem(
 
3273
                                                                       panel->customPaletteHistoryBtn, index),
 
3274
                                                  toName) != 0 ))
 
3275
                    index++;
 
3276
 
 
3277
                if (index < items) {
 
3278
                    WMRemovePopUpButtonItem(panel->customPaletteHistoryBtn,
 
3279
                                            index);
 
3280
                    if (index < item)
 
3281
                        item--;
 
3282
                }
 
3283
 
 
3284
            } else {
 
3285
                wfree(fromPath);
 
3286
                wfree(toName);
 
3287
                wfree(toPath);
 
3288
 
 
3289
                return;
 
3290
            }
 
3291
        }
 
3292
 
 
3293
        if ( rename(fromPath, toPath) != 0)
 
3294
            wsyserror(_("Couldn't rename palette %s to %s\n"), fromName, toName);
 
3295
        else {
 
3296
            WMRemovePopUpButtonItem(panel->customPaletteHistoryBtn, item);
 
3297
            WMInsertPopUpButtonItem(panel->customPaletteHistoryBtn, item,
 
3298
                                    toName);
 
3299
 
 
3300
            WMSetPopUpButtonSelectedItem(panel->customPaletteHistoryBtn, item);
 
3301
        }
 
3302
        wfree(fromPath);
 
3303
        wfree(toPath);
 
3304
        wfree(toName);
 
3305
    }
 
3306
}
 
3307
 
 
3308
 
 
3309
static void
 
3310
customPaletteMenuRemove(W_ColorPanel *panel)
 
3311
{
 
3312
    W_Screen    *scr = WMWidgetScreen(panel->win);
 
3313
    char        *text;
 
3314
    char        *tmp;
 
3315
    int         choice;
 
3316
    int         item;
 
3317
 
 
3318
    item = WMGetPopUpButtonSelectedItem(panel->customPaletteHistoryBtn);
 
3319
 
 
3320
    tmp = wstrconcat( _("This will permanently remove the palette "),
 
3321
                     WMGetPopUpButtonItem(panel->customPaletteHistoryBtn, item ));
 
3322
    text = wstrconcat( tmp,
 
3323
                      _(".\n\nAre you sure you want to remove this palette ?"));
 
3324
    wfree(tmp);
 
3325
 
 
3326
    choice = WMRunAlertPanel(scr, panel->win, _("Remove"), text, _("Yes"), _("No"),
 
3327
                             NULL);
 
3328
    /* returns 0 (= "Yes") or 1 (="No") */
 
3329
    wfree(text);
 
3330
 
 
3331
    if (choice == 0) {
 
3332
 
 
3333
        tmp = wstrconcat(panel->configurationPath,
 
3334
                         WMGetPopUpButtonItem(panel->customPaletteHistoryBtn, item ));
 
3335
 
 
3336
        if ( remove(tmp) == 0) {
 
3337
            /* item-1 always exists */
 
3338
            WMSetPopUpButtonSelectedItem(panel->customPaletteHistoryBtn,
 
3339
                                         item-1);
 
3340
 
 
3341
            customPaletteHistoryCallback(panel->customPaletteHistoryBtn,
 
3342
                                         panel);
 
3343
            customSetPalette(panel);
 
3344
 
 
3345
            WMRemovePopUpButtonItem(panel->customPaletteHistoryBtn, item);
 
3346
 
 
3347
        } else {
 
3348
            wsyserror(_("Couldn't remove palette %s\n"), tmp);
 
3349
        }
 
3350
 
 
3351
        wfree(tmp);
 
3352
    }
 
3353
}
 
3354
 
 
3355
 
 
3356
static void
 
3357
customPaletteHistoryCallback(WMWidget *w, void *data)
 
3358
{
 
3359
    W_ColorPanel        *panel = (W_ColorPanel*)data;
 
3360
    W_Screen            *scr = WMWidgetScreen(panel->win);
 
3361
    int                 item;
 
3362
    char                *filename;
 
3363
    RImage              *tmp = NULL;
 
3364
    unsigned char       perm_mask;
 
3365
 
 
3366
    item = WMGetPopUpButtonSelectedItem(panel->customPaletteHistoryBtn);
 
3367
    if (item == panel->currentPalette)
 
3368
        return;
 
3369
 
 
3370
    if (item == 0) {
 
3371
        customRenderSpectrum(panel);
 
3372
 
 
3373
        WMSetPopUpButtonItemEnabled(panel->customPaletteMenuBtn, CPmenuRename,
 
3374
                                    False );
 
3375
        WMSetPopUpButtonItemEnabled(panel->customPaletteMenuBtn, CPmenuRemove,
 
3376
                                    False );
 
3377
    } else {
 
3378
        /* Load file from configpath */
 
3379
        filename = wstrconcat( panel->configurationPath,
 
3380
                              WMGetPopUpButtonItem(panel->customPaletteHistoryBtn, item) );
 
3381
 
 
3382
        /* If the file corresponding to the item does not exist,
 
3383
         * remove it from the history list and select the next one.
 
3384
         */
 
3385
        perm_mask = (access(filename, F_OK) == 0);
 
3386
        if (!perm_mask) {
 
3387
            /* File does not exist */
 
3388
            wfree(filename);
 
3389
            WMSetPopUpButtonSelectedItem(panel->customPaletteHistoryBtn,
 
3390
                                         item-1);
 
3391
            WMRemovePopUpButtonItem(panel->customPaletteHistoryBtn, item);
 
3392
            customPaletteHistoryCallback(w, data);
 
3393
            return;
 
3394
        }
 
3395
 
 
3396
        /* Get the image */
 
3397
        tmp = RLoadImage(scr->rcontext,  filename, 0);
 
3398
        if (tmp) {
 
3399
            if (panel->customPaletteImg) {
 
3400
                RReleaseImage(panel->customPaletteImg);
 
3401
                panel->customPaletteImg = NULL;
 
3402
            }
 
3403
            panel->customPaletteImg = tmp;
 
3404
        }
 
3405
 
 
3406
        /* If the image is not writable, don't allow removing/renaming */
 
3407
        perm_mask = (access(filename, W_OK) == 0);
 
3408
        WMSetPopUpButtonItemEnabled(panel->customPaletteMenuBtn, CPmenuRename,
 
3409
                                    perm_mask);
 
3410
        WMSetPopUpButtonItemEnabled(panel->customPaletteMenuBtn, CPmenuRemove,
 
3411
                                    perm_mask);
 
3412
 
 
3413
        wfree(filename);
 
3414
    }
 
3415
    customSetPalette(panel);
 
3416
 
 
3417
    panel->currentPalette = item;
 
3418
}
 
3419
 
 
3420
/************************* ColorList Panel Functions **********************/
 
3421
 
 
3422
static void
 
3423
colorListPaintItem(WMList *lPtr, int index, Drawable d, char *text,
 
3424
                   int state, WMRect *rect)
 
3425
{
 
3426
    WMScreen *scr = WMWidgetScreen(lPtr);
 
3427
    Display *dpy = WMScreenDisplay(scr);
 
3428
    WMView *view = W_VIEW(lPtr);
 
3429
    RColor color = *((RColor *)WMGetListItem(lPtr, index)->clientData);
 
3430
    W_ColorPanel *panel = WMGetHangedData(lPtr);
 
3431
    int width, height, x, y;
 
3432
    WMColor *fillColor;
 
3433
 
 
3434
    width = rect->size.width;
 
3435
    height = rect->size.height;
 
3436
    x = rect->pos.x;
 
3437
    y = rect->pos.y;
 
3438
 
 
3439
    if (state & WLDSSelected)
 
3440
        XFillRectangle(dpy, d, WMColorGC(scr->white), x, y, width, height);
 
3441
    else
 
3442
        XFillRectangle(dpy, d, WMColorGC(view->backColor), x, y, width, height);
 
3443
 
 
3444
    fillColor = WMCreateRGBColor(scr, color.red<<8, color.green<<8,
 
3445
                                 color.blue<<8, True);
 
3446
 
 
3447
    XFillRectangle(dpy, d, WMColorGC(fillColor), x, y, 15, height);
 
3448
    WMReleaseColor(fillColor);
 
3449
 
 
3450
    WMDrawString(scr, d, scr->black, panel->font12, x+18, y, text, strlen(text));
 
3451
}
 
3452
 
 
3453
 
 
3454
static void
 
3455
colorListSelect(WMWidget *w, void *data)
 
3456
{
 
3457
    W_ColorPanel        *panel = (W_ColorPanel *)data;
 
3458
    CPColor             cpColor;
 
3459
 
 
3460
    cpColor.rgb = *((RColor *)WMGetListSelectedItem(w)->clientData);
 
3461
    cpColor.set = cpRGB;
 
3462
 
 
3463
    panel->lastChanged = WMColorListModeColorPanel;
 
3464
    updateSwatch(panel, cpColor);
 
3465
}
 
3466
 
 
3467
 
 
3468
static void
 
3469
colorListColorMenuCallback(WMWidget *w, void *data)
 
3470
{
 
3471
    W_ColorPanel *panel = (W_ColorPanel *)data;
 
3472
    int item = WMGetPopUpButtonSelectedItem(panel->colorListColorMenuBtn);
 
3473
 
 
3474
    switch (item) {
 
3475
    case CLmenuAdd:
 
3476
        break;
 
3477
    case CLmenuRename:
 
3478
        break;
 
3479
    case CLmenuRemove:
 
3480
        break;
 
3481
    }
 
3482
}
 
3483
 
 
3484
 
 
3485
static void
 
3486
colorListListMenuCallback(WMWidget *w, void *data)
 
3487
{
 
3488
    W_ColorPanel *panel = (W_ColorPanel *)data;
 
3489
    int item = WMGetPopUpButtonSelectedItem(panel->colorListListMenuBtn);
 
3490
 
 
3491
    switch (item) {
 
3492
    case CLmenuAdd:
 
3493
        /* New Color List */
 
3494
        colorListListMenuNew(panel);
 
3495
        break;
 
3496
    case CLmenuRename:
 
3497
        break;
 
3498
    case CLmenuRemove:
 
3499
        break;
 
3500
    }
 
3501
}
 
3502
 
 
3503
 
 
3504
static void
 
3505
colorListListMenuNew(W_ColorPanel *panel)
 
3506
{
 
3507
 
 
3508
}
 
3509
 
 
3510
 
 
3511
/*************** Panel Initialisation Functions *****************/
 
3512
 
 
3513
static void
 
3514
wheelInit(W_ColorPanel *panel)
 
3515
{
 
3516
    CPColor     cpColor;
 
3517
 
 
3518
    if (panel->color.set != cpHSV)
 
3519
        convertCPColor(&panel->color);
 
3520
 
 
3521
    WMSetSliderValue(panel->wheelBrightnessS, 255 - panel->color.hsv.value);
 
3522
 
 
3523
    panel->colx = 2 + rint((colorWheelSize / 2.0) *
 
3524
                           (1 + ( panel->color.hsv.saturation/255.0) *
 
3525
                            cos( panel->color.hsv.hue * M_PI/180.0)));
 
3526
    panel->coly = 2 + rint((colorWheelSize / 2.0) *
 
3527
                           (1 + ( panel->color.hsv.saturation/255.0) *
 
3528
                            sin(- panel->color.hsv.hue*M_PI/180.0)));
 
3529
 
 
3530
    wheelCalculateValues(panel, panel->color.hsv.value);
 
3531
 
 
3532
    cpColor = panel->color;
 
3533
    cpColor.hsv.value = 255;
 
3534
    cpColor.set = cpHSV;
 
3535
    wheelUpdateBrightnessGradient(panel, cpColor);
 
3536
}
 
3537
 
 
3538
 
 
3539
static void
 
3540
grayInit(W_ColorPanel *panel)
 
3541
{
 
3542
    int         value;
 
3543
    char        tmp[4];
 
3544
 
 
3545
    if (panel->color.set != cpHSV)
 
3546
        convertCPColor(&panel->color);
 
3547
 
 
3548
    value = rint(panel->color.hsv.value/2.55);
 
3549
    WMSetSliderValue(panel->grayBrightnessS, value);
 
3550
 
 
3551
    sprintf(tmp, "%d", value);
 
3552
    WMSetTextFieldText(panel->grayBrightnessT, tmp);
 
3553
}
 
3554
 
 
3555
 
 
3556
static void
 
3557
rgbInit(W_ColorPanel *panel)
 
3558
{
 
3559
    char        tmp[4];
 
3560
 
 
3561
    if (panel->color.set != cpRGB)
 
3562
        convertCPColor(&panel->color);
 
3563
 
 
3564
    WMSetSliderValue(panel->rgbRedS, panel->color.rgb.red);
 
3565
    WMSetSliderValue(panel->rgbGreenS, panel->color.rgb.green);
 
3566
    WMSetSliderValue(panel->rgbBlueS, panel->color.rgb.blue);
 
3567
 
 
3568
    sprintf(tmp, "%d", panel->color.rgb.red);
 
3569
    WMSetTextFieldText(panel->rgbRedT, tmp);
 
3570
    sprintf(tmp, "%d", panel->color.rgb.green);
 
3571
    WMSetTextFieldText(panel->rgbGreenT, tmp);
 
3572
    sprintf(tmp, "%d", panel->color.rgb.blue);
 
3573
    WMSetTextFieldText(panel->rgbBlueT, tmp);
 
3574
}
 
3575
 
 
3576
 
 
3577
static void
 
3578
cmykInit(W_ColorPanel *panel)
 
3579
{
 
3580
    int         value[3];
 
3581
    char        tmp[4];
 
3582
 
 
3583
    if (panel->color.set != cpRGB)
 
3584
        convertCPColor(&panel->color);
 
3585
 
 
3586
    value[0] = rint((255-panel->color.rgb.red)/2.55);
 
3587
    value[1] = rint((255-panel->color.rgb.green)/2.55);
 
3588
    value[2] = rint((255-panel->color.rgb.blue)/2.55);
 
3589
 
 
3590
    WMSetSliderValue(panel->cmykCyanS, value[0]);
 
3591
    WMSetSliderValue(panel->cmykMagentaS, value[1]);
 
3592
    WMSetSliderValue(panel->cmykYellowS, value[2]);
 
3593
    WMSetSliderValue(panel->cmykBlackS, 0);
 
3594
 
 
3595
    sprintf(tmp, "%d", value[0]);
 
3596
    WMSetTextFieldText(panel->cmykCyanT, tmp);
 
3597
    sprintf(tmp, "%d", value[1]);
 
3598
    WMSetTextFieldText(panel->cmykMagentaT, tmp);
 
3599
    sprintf(tmp, "%d", value[2]);
 
3600
    WMSetTextFieldText(panel->cmykYellowT, tmp);
 
3601
    WMSetTextFieldText(panel->cmykBlackT, "0");
 
3602
}
 
3603
 
 
3604
 
 
3605
static void
 
3606
hsbInit(W_ColorPanel *panel)
 
3607
{
 
3608
    int         value[3];
 
3609
    char        tmp[4];
 
3610
 
 
3611
    if (panel->color.set != cpHSV)
 
3612
        convertCPColor(&panel->color);
 
3613
 
 
3614
    value[0] = panel->color.hsv.hue;
 
3615
    value[1] = rint(panel->color.hsv.saturation/2.55);
 
3616
    value[2] = rint(panel->color.hsv.value/2.55);
 
3617
 
 
3618
    WMSetSliderValue(panel->hsbHueS,value[0]);
 
3619
    WMSetSliderValue(panel->hsbSaturationS,value[1]);
 
3620
    WMSetSliderValue(panel->hsbBrightnessS,value[2]);
 
3621
 
 
3622
    sprintf(tmp, "%d", value[0]);
 
3623
    WMSetTextFieldText(panel->hsbHueT, tmp);
 
3624
    sprintf(tmp, "%d", value[1]);
 
3625
    WMSetTextFieldText(panel->hsbSaturationT, tmp);
 
3626
    sprintf(tmp, "%d", value[2]);
 
3627
    WMSetTextFieldText(panel->hsbBrightnessT, tmp);
 
3628
 
 
3629
    hsbUpdateBrightnessGradient(panel);
 
3630
    hsbUpdateSaturationGradient(panel);
 
3631
    hsbUpdateHueGradient(panel);
 
3632
}
 
3633
 
 
3634
 
 
3635
 
 
3636
/************************** Common utility functions ************************/
 
3637
 
 
3638
static int
 
3639
fetchFile(char *toPath, char *srcFile, char *destFile)
 
3640
{
 
3641
    int         src, dest;
 
3642
    int         n;
 
3643
    char        *tmp;
 
3644
    char        buf[BUFSIZE];
 
3645
 
 
3646
    if ((src = open(srcFile, O_RDONLY|O_BINARY)) == 0) {
 
3647
        wsyserror(_("Could not open %s"), srcFile);
 
3648
        return -1;
 
3649
    }
 
3650
 
 
3651
    tmp = wstrconcat(toPath, destFile);
 
3652
    if ((dest = open( tmp, O_RDWR|O_CREAT|O_BINARY, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH))
 
3653
        == 0) {
 
3654
        wsyserror(_("Could not create %s"), tmp);
 
3655
        wfree(tmp);
 
3656
        return -1;
 
3657
    }
 
3658
    wfree(tmp);
 
3659
 
 
3660
 
 
3661
    /* Copy the file */
 
3662
    while ((n = read(src, buf, BUFSIZE)) > 0)
 
3663
    {
 
3664
        if (write (dest, buf, n) != n)  {
 
3665
            wsyserror(_("Write error on file %s"), destFile);
 
3666
            return -1;
 
3667
        }
 
3668
    }
 
3669
 
 
3670
    return 0;
 
3671
}
 
3672
 
 
3673
 
 
3674
char*
 
3675
generateNewFilename(char *curName)
 
3676
{
 
3677
    int         n;
 
3678
    char        c;
 
3679
    int         baseLen;
 
3680
    char        *ptr;
 
3681
    char        *newName;
 
3682
 
 
3683
 
 
3684
    assert(curName);
 
3685
 
 
3686
    ptr = curName;
 
3687
 
 
3688
    if (((ptr = strrchr(ptr, '{'))==0) || sscanf(ptr, "{%i}%c", &n, &c)!=1)
 
3689
        return wstrconcat(curName, " {1}");
 
3690
 
 
3691
    baseLen = ptr - curName -1;
 
3692
 
 
3693
    newName = wmalloc(baseLen + 16);
 
3694
    strncpy(newName, curName, baseLen);
 
3695
    newName[baseLen] = 0;
 
3696
 
 
3697
    sprintf(&newName[baseLen], " {%i}", n+1);
 
3698
 
 
3699
    return newName;
 
3700
}
 
3701
 
 
3702
 
 
3703
void
 
3704
convertCPColor(CPColor *color)
 
3705
{
 
3706
    unsigned short old_hue = 0;
 
3707
 
 
3708
    switch (color->set) {
 
3709
    case cpNone:
 
3710
        wwarning(_("Color Panel: Color unspecified"));
 
3711
        return;
 
3712
    case cpRGB:
 
3713
        old_hue = color->hsv.hue;
 
3714
        RRGBtoHSV(&(color->rgb), &(color->hsv));
 
3715
 
 
3716
        /* In black the hue is undefined, and may change by conversion
 
3717
         * Same for white. */
 
3718
        if (
 
3719
            ((color->rgb.red == 0) &&
 
3720
             (color->rgb.green == 0) &&
 
3721
             (color->rgb.blue == 0)) ||
 
3722
            ((color->rgb.red == 0) &&
 
3723
             (color->rgb.green == 0) &&
 
3724
             (color->rgb.blue == 255))
 
3725
           )
 
3726
            color->hsv.hue = old_hue;
 
3727
        break;
 
3728
    case cpHSV:
 
3729
        RHSVtoRGB(&(color->hsv), &(color->rgb));
 
3730
        break;
 
3731
    }
 
3732
}
 
3733
 
 
3734
 
 
3735
#define ABS_SHIFT(val, shift) \
 
3736
    (((shift) > 0) ? (val) >> (shift) : (val) << -(shift))
 
3737
 
 
3738
RColor
 
3739
ulongToRColor(WMScreen *scr, unsigned long value)
 
3740
{
 
3741
    RColor      color;
 
3742
    XColor      *xcolor = NULL;
 
3743
 
 
3744
    if (!(xcolor = wmalloc(sizeof(XColor)) )) {
 
3745
        wwarning(_("Color Panel: Could not allocate memory"));
 
3746
        color.red = 0;
 
3747
        color.green = 0;
 
3748
        color.blue = 0;
 
3749
        return color;
 
3750
    }
 
3751
 
 
3752
    xcolor->pixel = value;
 
3753
    XQueryColor(scr->display, scr->rcontext->cmap, xcolor);
 
3754
 
 
3755
    color.red   = xcolor->red >> 8;
 
3756
    color.green = xcolor->green >> 8;
 
3757
    color.blue  = xcolor->blue >> 8;
 
3758
 
 
3759
    wfree(xcolor);
 
3760
 
 
3761
    return color;
 
3762
}
 
3763
 
 
3764
 
 
3765
unsigned char
 
3766
getShift(unsigned char value)
 
3767
{
 
3768
    unsigned char i = -1;
 
3769
 
 
3770
    if (value == 0)
 
3771
        return 0;
 
3772
 
 
3773
    while (value) {
 
3774
        value >>= 1;
 
3775
        i++;
 
3776
    }
 
3777
 
 
3778
    return i;
 
3779
}
 
3780
 
 
3781
 
 
3782
 
 
3783
#ifdef SHAPE_WAS_DEFINED
 
3784
#undef SHAPE_WAS_DEFINED
 
3785
#define SHAPE
 
3786
#endif
 
3787