4 * by ]d : Original idea and basic initial code
5 * Pascal Hofstee : Code for wheeldrawing and calculating
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 ;-)
18 * - Look at further optimization of colorWheel matrix calculation.
19 * It appears to be rather symmetric in angles of 60 degrees,
20 * while it is optimized in angles of 90 degrees.
21 * - Custom color-lists and custom colors in custom color-lists.
35 #include <sys/types.h>
40 /* BUG There's something fishy with shaped windows */
41 /* Whithout shape extension the magnified image is completely broken -Dan */
44 # include <X11/extensions/shape.h>
47 char *WMColorPanelColorChangedNotification
= "WMColorPanelColorChangedNotification";
50 * Bitmaps for magnifying glass cursor
54 #define Cursor_x_hot 11
55 #define Cursor_y_hot 11
56 #define Cursor_width 32
57 #define Cursor_height 32
58 static unsigned char Cursor_bits
[] = {
59 0x00, 0x7e, 0x00, 0x00, 0xc0, 0x81, 0x03, 0x00, 0x20, 0x00, 0x04, 0x00, 0x10, 0x00, 0x08,
60 0x00, 0x08, 0x00, 0x10, 0x00, 0x04, 0x00, 0x20, 0x00, 0x02, 0x00, 0x40, 0x00, 0x02, 0x00,
61 0x40, 0x00, 0x02, 0x00, 0x40, 0x00, 0x01, 0x42, 0x80, 0x00, 0x01, 0x24, 0x80, 0x00, 0x01,
62 0x00, 0x80, 0x00, 0x01, 0x00, 0x80, 0x00, 0x01, 0x24, 0x80, 0x00, 0x01, 0x42, 0x80, 0x00,
63 0x02, 0x00, 0x40, 0x00, 0x02, 0x00, 0x40, 0x00, 0x02, 0x00, 0x40, 0x00, 0x04, 0x00, 0x20,
64 0x00, 0x08, 0x00, 0x50, 0x00, 0x10, 0x00, 0x88, 0x00, 0x20, 0x00, 0x5c, 0x01, 0xc0, 0x81,
65 0x3b, 0x02, 0x00, 0x7e, 0x70, 0x05, 0x00, 0x00, 0xe0, 0x08, 0x00, 0x00, 0xc0, 0x15, 0x00,
66 0x00, 0x80, 0x23, 0x00, 0x00, 0x00, 0x57, 0x00, 0x00, 0x00, 0x8e, 0x00, 0x00, 0x00, 0x5c,
67 0x00, 0x00, 0x00, 0xb8, 0x00, 0x00, 0x00, 0x70
70 /* Cursor shape-mask */
71 #define Cursor_shape_width 32
72 #define Cursor_shape_height 32
73 static unsigned char Cursor_shape_bits
[] = {
74 0x00, 0x7e, 0x00, 0x00, 0xc0, 0x81, 0x03, 0x00, 0x20, 0x00, 0x04, 0x00, 0x10, 0x00, 0x08,
75 0x00, 0x08, 0x00, 0x10, 0x00, 0x04, 0x00, 0x20, 0x00, 0x02, 0x00, 0x40, 0x00, 0x02, 0x00,
76 0x40, 0x00, 0x02, 0x00, 0x40, 0x00, 0x01, 0x42, 0x80, 0x00, 0x01, 0x24, 0x80, 0x00, 0x01,
77 0x00, 0x80, 0x00, 0x01, 0x00, 0x80, 0x00, 0x01, 0x24, 0x80, 0x00, 0x01, 0x42, 0x80, 0x00,
78 0x02, 0x00, 0x40, 0x00, 0x02, 0x00, 0x40, 0x00, 0x02, 0x00, 0x40, 0x00, 0x04, 0x00, 0x20,
79 0x00, 0x08, 0x00, 0x70, 0x00, 0x10, 0x00, 0xf8, 0x00, 0x20, 0x00, 0xfc, 0x01, 0xc0, 0x81,
80 0xfb, 0x03, 0x00, 0x7e, 0xf0, 0x07, 0x00, 0x00, 0xe0, 0x0f, 0x00, 0x00, 0xc0, 0x1f, 0x00,
81 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0xfc,
82 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x70
85 /* Clip-mask for magnified pixels */
86 #define Cursor_mask_width 24
87 #define Cursor_mask_height 24
88 static unsigned char Cursor_mask_bits
[] = {
89 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0xc0, 0xff, 0x03, 0xe0, 0xff, 0x07,
90 0xf0, 0xff, 0x0f, 0xf8, 0xff, 0x1f, 0xfc, 0xff, 0x3f, 0xfc, 0xff, 0x3f,
91 0xfc, 0xff, 0x3f, 0xfe, 0xff, 0x7f, 0xfe, 0xff, 0x7f, 0xfe, 0xff, 0x7f,
92 0xfe, 0xff, 0x7f, 0xfe, 0xff, 0x7f, 0xfe, 0xff, 0x7f, 0xfc, 0xff, 0x3f,
93 0xfc, 0xff, 0x3f, 0xfc, 0xff, 0x3f, 0xf8, 0xff, 0x1f, 0xf0, 0xff, 0x0f,
94 0xe0, 0xff, 0x07, 0xc0, 0xff, 0x03, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00
97 typedef struct MovingView
{
98 WMView
*view
; /* The view this is all about */
99 XImage
*image
; /* What's under the view */
100 XImage
*dirtyRect
; /* Storage of overlapped image area */
101 Pixmap magPix
; /* Magnified part of pixmap */
102 RColor color
; /* Color of a pixel in the image */
103 int x
, y
; /* Position of view */
106 typedef struct CPColor
{
107 RColor rgb
; /* The RGB values of the color */
108 RHSVColor hsv
; /* The HSV values of the color */
109 enum { /* Which one was last set ? */
116 typedef struct WheelMatrix
{
117 unsigned int width
, height
; /* Size of the colorwheel */
118 unsigned char *data
[3]; /* Wheel data (R,G,B) */
119 unsigned char values
[256]; /* Precalculated values R,G & B = 0-255 */
122 typedef struct W_ColorPanel
{
130 WMColorWell
*colorWell
;
131 WMButton
*magnifyBtn
;
133 WMButton
*slidersBtn
;
134 WMButton
*customPaletteBtn
;
135 WMButton
*colorListBtn
;
137 /* Magnifying Glass */
138 MovingView
*magnifyGlass
;
140 /* ColorWheel Panel */
142 WMSlider
*wheelBrightnessS
;
147 WMFrame
*seperatorFrm
;
152 /* Gray Scale Panel */
156 WMSlider
*grayBrightnessS
;
157 WMTextField
*grayBrightnessT
;
158 WMButton
*grayPresetBtn
[7];
169 WMTextField
*rgbRedT
;
170 WMTextField
*rgbGreenT
;
171 WMTextField
*rgbBlueT
;
182 WMSlider
*cmykMagentaS
;
183 WMSlider
*cmykYellowS
;
184 WMSlider
*cmykBlackS
;
185 WMTextField
*cmykCyanT
;
186 WMTextField
*cmykMagentaT
;
187 WMTextField
*cmykYellowT
;
188 WMTextField
*cmykBlackT
;
193 WMSlider
*hsbSaturationS
;
194 WMSlider
*hsbBrightnessS
;
195 WMTextField
*hsbHueT
;
196 WMTextField
*hsbSaturationT
;
197 WMTextField
*hsbBrightnessT
;
199 /* Custom Palette Panel */
200 WMFrame
*customPaletteFrm
;
201 WMPopUpButton
*customPaletteHistoryBtn
;
202 WMFrame
*customPaletteContentFrm
;
203 WMPopUpButton
*customPaletteMenuBtn
;
204 WMView
*customPaletteContentView
;
206 /* Color List Panel */
207 WMFrame
*colorListFrm
;
208 WMPopUpButton
*colorListHistoryBtn
;
209 WMList
*colorListContentLst
;
210 WMPopUpButton
*colorListColorMenuBtn
;
211 WMPopUpButton
*colorListListMenuBtn
;
213 /* Look-Up Tables and Images */
214 wheelMatrix
*wheelMtrx
;
217 Pixmap selectionBackImg
;
218 RImage
*customPaletteImg
;
221 /* Common Data Fields */
222 CPColor color
; /* Current color */
223 WMColorPanelMode mode
; /* Current color selection mode */
224 WMColorPanelMode slidersmode
; /* Current color sel. mode sliders panel */
225 WMColorPanelMode lastChanged
; /* Panel that last changed the color */
226 int colx
, coly
; /* (x,y) of sel.-marker in WheelMode */
227 int palx
, paly
; /* (x,y) of sel.-marker in
229 double palXRatio
, palYRatio
; /* Ratios in x & y between
233 char *configurationPath
;
236 unsigned int continuous
:1;
237 unsigned int dragging
:1;
246 CPmenuNewFromClipboard
247 } customPaletteMenuItem
;
257 #define colorWheelSize 150
258 #define customPaletteWidth 182
259 #define customPaletteHeight 106
260 #define knobThickness 8
262 #define SPECTRUM_WIDTH 511
263 #define SPECTRUM_HEIGHT 360
265 #define COLORWHEEL_PART 1
266 #define CUSTOMPALETTE_PART 2
269 #define MAX_LENGTH 1024
272 #define M_PI 3.14159265358979323846
275 static char *generateNewFilename(const char *curName
);
276 static void convertCPColor(CPColor
* color
);
277 static RColor
ulongToRColor(WMScreen
* scr
, unsigned long value
);
278 static unsigned char getShift(unsigned char value
);
280 static void modeButtonCallback(WMWidget
* w
, void *data
);
281 static int getPickerPart(W_ColorPanel
* panel
, int x
, int y
);
282 static void readConfiguration(W_ColorPanel
* panel
);
283 static void readXColors(W_ColorPanel
* panel
);
285 static void closeWindowCallback(WMWidget
* w
, void *data
);
287 static Cursor
magnifyGrabPointer(W_ColorPanel
* panel
);
288 static WMPoint
magnifyInitialize(W_ColorPanel
* panel
);
289 static void magnifyPutCursor(WMWidget
* w
, void *data
);
290 static Pixmap
magnifyCreatePixmap(WMColorPanel
* panel
);
291 static void magnifyGetImageStored(W_ColorPanel
* panel
, int x1
, int y1
, int x2
, int y2
);
292 static XImage
*magnifyGetImage(WMScreen
* scr
, XImage
* image
, int x
, int y
, int w
, int h
);
294 static wheelMatrix
*wheelCreateMatrix(unsigned int width
, unsigned int height
);
295 static void wheelDestroyMatrix(wheelMatrix
* matrix
);
296 static void wheelInitMatrix(W_ColorPanel
* panel
);
297 static void wheelCalculateValues(W_ColorPanel
* panel
, int maxvalue
);
298 static void wheelRender(W_ColorPanel
* panel
);
299 static Bool
wheelInsideColorWheel(W_ColorPanel
* panel
, unsigned long ofs
);
300 static void wheelPaint(W_ColorPanel
* panel
);
302 static void wheelHandleEvents(XEvent
* event
, void *data
);
303 static void wheelHandleActionEvents(XEvent
* event
, void *data
);
304 static void wheelBrightnessSliderCallback(WMWidget
* w
, void *data
);
305 static void wheelUpdateSelection(W_ColorPanel
* panel
);
306 static void wheelUndrawSelection(W_ColorPanel
* panel
);
308 static void wheelPositionSelection(W_ColorPanel
* panel
, int x
, int y
);
309 static void wheelPositionSelectionOutBounds(W_ColorPanel
* panel
, int x
, int y
);
310 static void wheelUpdateBrightnessGradientFromLocation(W_ColorPanel
* panel
);
311 static void wheelUpdateBrightnessGradient(W_ColorPanel
* panel
, CPColor topColor
);
313 static void grayBrightnessSliderCallback(WMWidget
* w
, void *data
);
314 static void grayPresetButtonCallback(WMWidget
* w
, void *data
);
315 static void grayBrightnessTextFieldCallback(void *observerData
, WMNotification
* notification
);
317 static void rgbSliderCallback(WMWidget
* w
, void *data
);
318 static void rgbTextFieldCallback(void *observerData
, WMNotification
* notification
);
319 static void rgbDecToHex(WMWidget
*w
, void *data
);
321 static void cmykSliderCallback(WMWidget
* w
, void *data
);
322 static void cmykTextFieldCallback(void *observerData
, WMNotification
* notification
);
324 static void hsbSliderCallback(WMWidget
* w
, void *data
);
325 static void hsbTextFieldCallback(void *observerData
, WMNotification
* notification
);
326 static void hsbUpdateBrightnessGradient(W_ColorPanel
* panel
);
327 static void hsbUpdateSaturationGradient(W_ColorPanel
* panel
);
328 static void hsbUpdateHueGradient(W_ColorPanel
* panel
);
330 static void customRenderSpectrum(W_ColorPanel
* panel
);
331 static void customSetPalette(W_ColorPanel
* panel
);
332 static void customPaletteHandleEvents(XEvent
* event
, void *data
);
333 static void customPaletteHandleActionEvents(XEvent
* event
, void *data
);
334 static void customPalettePositionSelection(W_ColorPanel
* panel
, int x
, int y
);
335 static void customPalettePositionSelectionOutBounds(W_ColorPanel
* panel
, int x
, int y
);
336 static void customPaletteMenuCallback(WMWidget
* w
, void *data
);
337 static void customPaletteHistoryCallback(WMWidget
* w
, void *data
);
339 static void customPaletteMenuNewFromFile(W_ColorPanel
* panel
);
340 static void customPaletteMenuRename(W_ColorPanel
* panel
);
341 static void customPaletteMenuRemove(W_ColorPanel
* panel
);
343 static void colorListPaintItem(WMList
* lPtr
, int index
, Drawable d
, char *text
, int state
, WMRect
* rect
);
344 static void colorListSelect(WMWidget
* w
, void *data
);
345 static void colorListColorMenuCallback(WMWidget
* w
, void *data
);
346 static void colorListListMenuCallback(WMWidget
* w
, void *data
);
348 static void wheelInit(W_ColorPanel
* panel
);
349 static void grayInit(W_ColorPanel
* panel
);
350 static void rgbInit(W_ColorPanel
* panel
);
351 static void cmykInit(W_ColorPanel
* panel
);
352 static void hsbInit(W_ColorPanel
* panel
);
355 static inline int get_textfield_as_integer(WMTextField
*widget
)
360 str
= WMGetTextFieldText(widget
);
366 void WMSetColorPanelAction(WMColorPanel
* panel
, WMAction2
* action
, void *data
)
368 panel
->action
= action
;
369 panel
->clientData
= data
;
372 static WMColorPanel
*makeColorPanel(WMScreen
* scrPtr
, const char *name
)
379 WMColor
*textcolor
, *graybuttoncolor
;
381 GC bgc
= WMColorGC(scrPtr
->black
);
382 GC wgc
= WMColorGC(scrPtr
->white
);
384 panel
= wmalloc(sizeof(WMColorPanel
));
385 panel
->color
.rgb
.red
= 0;
386 panel
->color
.rgb
.green
= 0;
387 panel
->color
.rgb
.blue
= 0;
388 panel
->color
.hsv
.hue
= 0;
389 panel
->color
.hsv
.saturation
= 0;
390 panel
->color
.hsv
.value
= 0;
391 panel
->color
.set
= cpNone
; /* Color has not been set yet */
393 panel
->font8
= WMSystemFontOfSize(scrPtr
, 8);
394 panel
->font12
= WMSystemFontOfSize(scrPtr
, 12);
396 panel
->win
= WMCreateWindowWithStyle(scrPtr
, name
,
397 WMTitledWindowMask
| WMClosableWindowMask
| WMResizableWindowMask
);
398 WMResizeWidget(panel
->win
, PWIDTH
, PHEIGHT
);
399 WMSetWindowTitle(panel
->win
, _("Colors"));
400 WMSetWindowCloseAction(panel
->win
, closeWindowCallback
, panel
);
402 /* Set Default ColorPanel Mode(s) */
403 panel
->mode
= WMWheelModeColorPanel
;
404 panel
->lastChanged
= 0;
405 panel
->slidersmode
= WMRGBModeColorPanel
;
406 panel
->configurationPath
= wstrconcat(wusergnusteppath(), "/Library/Colors/");
408 /* Some General Purpose Widgets */
409 panel
->colorWell
= WMCreateColorWell(panel
->win
);
410 WMResizeWidget(panel
->colorWell
, 134, 36);
411 WSetColorWellBordered(panel
->colorWell
, False
);
412 WMMoveWidget(panel
->colorWell
, 56, 4);
414 panel
->magnifyBtn
= WMCreateCustomButton(panel
->win
, WBBStateLightMask
| WBBStateChangeMask
);
415 WMResizeWidget(panel
->magnifyBtn
, 46, 36);
416 WMMoveWidget(panel
->magnifyBtn
, 6, 4);
417 WMSetButtonAction(panel
->magnifyBtn
, magnifyPutCursor
, panel
);
418 WMSetButtonImagePosition(panel
->magnifyBtn
, WIPImageOnly
);
419 WMSetButtonImage(panel
->magnifyBtn
, scrPtr
->magnifyIcon
);
421 panel
->wheelBtn
= WMCreateCustomButton(panel
->win
, WBBStateLightMask
| WBBStateChangeMask
);
422 WMResizeWidget(panel
->wheelBtn
, 46, 32);
423 WMMoveWidget(panel
->wheelBtn
, 6, 44);
424 WMSetButtonAction(panel
->wheelBtn
, modeButtonCallback
, panel
);
425 WMSetButtonImagePosition(panel
->wheelBtn
, WIPImageOnly
);
426 WMSetButtonImage(panel
->wheelBtn
, scrPtr
->wheelIcon
);
428 panel
->slidersBtn
= WMCreateCustomButton(panel
->win
, WBBStateLightMask
| WBBStateChangeMask
);
429 WMResizeWidget(panel
->slidersBtn
, 46, 32);
430 WMMoveWidget(panel
->slidersBtn
, 52, 44);
431 WMSetButtonAction(panel
->slidersBtn
, modeButtonCallback
, panel
);
432 WMSetButtonImagePosition(panel
->slidersBtn
, WIPImageOnly
);
433 WMSetButtonImage(panel
->slidersBtn
, scrPtr
->rgbIcon
);
435 panel
->customPaletteBtn
= WMCreateCustomButton(panel
->win
, WBBStateLightMask
| WBBStateChangeMask
);
436 WMResizeWidget(panel
->customPaletteBtn
, 46, 32);
437 WMMoveWidget(panel
->customPaletteBtn
, 98, 44);
438 WMSetButtonAction(panel
->customPaletteBtn
, modeButtonCallback
, panel
);
439 WMSetButtonImagePosition(panel
->customPaletteBtn
, WIPImageOnly
);
440 WMSetButtonImage(panel
->customPaletteBtn
, scrPtr
->customPaletteIcon
);
442 panel
->colorListBtn
= WMCreateCustomButton(panel
->win
, WBBStateLightMask
| WBBStateChangeMask
);
443 WMResizeWidget(panel
->colorListBtn
, 46, 32);
444 WMMoveWidget(panel
->colorListBtn
, 144, 44);
445 WMSetButtonAction(panel
->colorListBtn
, modeButtonCallback
, panel
);
446 WMSetButtonImagePosition(panel
->colorListBtn
, WIPImageOnly
);
447 WMSetButtonImage(panel
->colorListBtn
, scrPtr
->colorListIcon
);
449 /* Let's Group some of them together */
450 WMGroupButtons(panel
->wheelBtn
, panel
->slidersBtn
);
451 WMGroupButtons(panel
->wheelBtn
, panel
->customPaletteBtn
);
452 WMGroupButtons(panel
->wheelBtn
, panel
->colorListBtn
);
454 /* Widgets for the ColorWheel Panel */
455 panel
->wheelFrm
= WMCreateFrame(panel
->win
);
456 WMSetFrameRelief(panel
->wheelFrm
, WRFlat
);
457 WMResizeWidget(panel
->wheelFrm
, PWIDTH
- 8, PHEIGHT
- 80 - 26);
458 WMMoveWidget(panel
->wheelFrm
, 5, 80);
460 panel
->wheelView
= W_CreateView(W_VIEW(panel
->wheelFrm
));
461 /* XXX Can we create a view ? */
462 W_ResizeView(panel
->wheelView
, colorWheelSize
+ 4, colorWheelSize
+ 4);
463 W_MoveView(panel
->wheelView
, 0, 0);
465 /* Create an event handler to handle expose/click events in ColorWheel */
466 WMCreateEventHandler(panel
->wheelView
,
467 ButtonPressMask
| ButtonReleaseMask
| EnterWindowMask
|
468 LeaveWindowMask
| ButtonMotionMask
, wheelHandleActionEvents
, panel
);
470 WMCreateEventHandler(panel
->wheelView
, ExposureMask
, wheelHandleEvents
, panel
);
472 panel
->wheelBrightnessS
= WMCreateSlider(panel
->wheelFrm
);
473 WMResizeWidget(panel
->wheelBrightnessS
, 16, 153);
474 WMMoveWidget(panel
->wheelBrightnessS
, 5 + colorWheelSize
+ 14, 1);
475 WMSetSliderMinValue(panel
->wheelBrightnessS
, 0);
476 WMSetSliderMaxValue(panel
->wheelBrightnessS
, 255);
477 WMSetSliderAction(panel
->wheelBrightnessS
, wheelBrightnessSliderCallback
, panel
);
478 WMSetSliderKnobThickness(panel
->wheelBrightnessS
, knobThickness
);
480 panel
->wheelMtrx
= wheelCreateMatrix(colorWheelSize
+ 4, colorWheelSize
+ 4);
481 wheelInitMatrix(panel
);
483 /* Widgets for the Slider Panels */
484 panel
->slidersFrm
= WMCreateFrame(panel
->win
);
485 WMSetFrameRelief(panel
->slidersFrm
, WRFlat
);
486 WMResizeWidget(panel
->slidersFrm
, PWIDTH
- 8, PHEIGHT
- 80 - 26);
487 WMMoveWidget(panel
->slidersFrm
, 4, 80);
489 panel
->seperatorFrm
= WMCreateFrame(panel
->slidersFrm
);
490 WMSetFrameRelief(panel
->seperatorFrm
, WRPushed
);
491 WMResizeWidget(panel
->seperatorFrm
, PWIDTH
- 8, 2);
492 WMMoveWidget(panel
->seperatorFrm
, 0, 1);
494 panel
->grayBtn
= WMCreateCustomButton(panel
->slidersFrm
, WBBStateLightMask
| WBBStateChangeMask
);
495 WMResizeWidget(panel
->grayBtn
, 46, 24);
496 WMMoveWidget(panel
->grayBtn
, 1, 8);
497 WMSetButtonAction(panel
->grayBtn
, modeButtonCallback
, panel
);
498 WMSetButtonImagePosition(panel
->grayBtn
, WIPImageOnly
);
499 WMSetButtonImage(panel
->grayBtn
, scrPtr
->grayIcon
);
501 panel
->rgbBtn
= WMCreateCustomButton(panel
->slidersFrm
, WBBStateLightMask
| WBBStateChangeMask
);
502 WMResizeWidget(panel
->rgbBtn
, 46, 24);
503 WMMoveWidget(panel
->rgbBtn
, 47, 8);
504 WMSetButtonAction(panel
->rgbBtn
, modeButtonCallback
, panel
);
505 WMSetButtonImagePosition(panel
->rgbBtn
, WIPImageOnly
);
506 WMSetButtonImage(panel
->rgbBtn
, scrPtr
->rgbIcon
);
508 panel
->cmykBtn
= WMCreateCustomButton(panel
->slidersFrm
, WBBStateLightMask
| WBBStateChangeMask
);
509 WMResizeWidget(panel
->cmykBtn
, 46, 24);
510 WMMoveWidget(panel
->cmykBtn
, 93, 8);
511 WMSetButtonAction(panel
->cmykBtn
, modeButtonCallback
, panel
);
512 WMSetButtonImagePosition(panel
->cmykBtn
, WIPImageOnly
);
513 WMSetButtonImage(panel
->cmykBtn
, scrPtr
->cmykIcon
);
515 panel
->hsbBtn
= WMCreateCustomButton(panel
->slidersFrm
, WBBStateLightMask
| WBBStateChangeMask
);
516 WMResizeWidget(panel
->hsbBtn
, 46, 24);
517 WMMoveWidget(panel
->hsbBtn
, 139, 8);
518 WMSetButtonAction(panel
->hsbBtn
, modeButtonCallback
, panel
);
519 WMSetButtonImagePosition(panel
->hsbBtn
, WIPImageOnly
);
520 WMSetButtonImage(panel
->hsbBtn
, scrPtr
->hsbIcon
);
522 /* Let's Group the Slider Panel Buttons Together */
523 WMGroupButtons(panel
->grayBtn
, panel
->rgbBtn
);
524 WMGroupButtons(panel
->grayBtn
, panel
->cmykBtn
);
525 WMGroupButtons(panel
->grayBtn
, panel
->hsbBtn
);
527 textcolor
= WMDarkGrayColor(scrPtr
);
529 /* Widgets for GrayScale Panel */
530 panel
->grayFrm
= WMCreateFrame(panel
->slidersFrm
);
531 WMSetFrameRelief(panel
->grayFrm
, WRFlat
);
532 WMResizeWidget(panel
->grayFrm
, PWIDTH
- 8, PHEIGHT
- 80 - 26 - 32);
533 WMMoveWidget(panel
->grayFrm
, 0, 34);
535 panel
->grayMinL
= WMCreateLabel(panel
->grayFrm
);
536 WMResizeWidget(panel
->grayMinL
, 20, 10);
537 WMMoveWidget(panel
->grayMinL
, 2, 2);
538 WMSetLabelText(panel
->grayMinL
, "0");
539 WMSetLabelTextAlignment(panel
->grayMinL
, WALeft
);
540 WMSetLabelTextColor(panel
->grayMinL
, textcolor
);
541 WMSetLabelFont(panel
->grayMinL
, panel
->font8
);
543 panel
->grayMaxL
= WMCreateLabel(panel
->grayFrm
);
544 WMResizeWidget(panel
->grayMaxL
, 40, 10);
545 WMMoveWidget(panel
->grayMaxL
, 104, 2);
546 WMSetLabelText(panel
->grayMaxL
, "100");
547 WMSetLabelTextAlignment(panel
->grayMaxL
, WARight
);
548 WMSetLabelTextColor(panel
->grayMaxL
, textcolor
);
549 WMSetLabelFont(panel
->grayMaxL
, panel
->font8
);
551 panel
->grayBrightnessS
= WMCreateSlider(panel
->grayFrm
);
552 WMResizeWidget(panel
->grayBrightnessS
, 141, 16);
553 WMMoveWidget(panel
->grayBrightnessS
, 2, 14);
554 WMSetSliderMinValue(panel
->grayBrightnessS
, 0);
555 WMSetSliderMaxValue(panel
->grayBrightnessS
, 100);
556 WMSetSliderKnobThickness(panel
->grayBrightnessS
, knobThickness
);
557 WMSetSliderAction(panel
->grayBrightnessS
, grayBrightnessSliderCallback
, panel
);
567 image
= RRenderGradient(141, 16, &from
, &to
, RGRD_HORIZONTAL
);
568 pixmap
= WMCreatePixmapFromRImage(scrPtr
, image
, 0);
569 RReleaseImage(image
);
572 W_PaintText(W_VIEW(panel
->grayBrightnessS
), pixmap
->pixmap
,
573 panel
->font12
, 2, 0, 100, WALeft
, scrPtr
->white
,
574 False
, _("Brightness"), strlen(_("Brightness")));
576 wwarning(_("Color Panel: Could not allocate memory"));
578 WMSetSliderImage(panel
->grayBrightnessS
, pixmap
);
579 WMReleasePixmap(pixmap
);
581 panel
->grayBrightnessT
= WMCreateTextField(panel
->grayFrm
);
582 WMResizeWidget(panel
->grayBrightnessT
, 40, 18);
583 WMMoveWidget(panel
->grayBrightnessT
, 146, 13);
584 WMSetTextFieldAlignment(panel
->grayBrightnessT
, WALeft
);
585 WMAddNotificationObserver(grayBrightnessTextFieldCallback
, panel
,
586 WMTextDidEndEditingNotification
, panel
->grayBrightnessT
);
588 for (i
= 0; i
< 7; i
++) {
589 pixmap
= WMCreatePixmap(scrPtr
, 13, 13, scrPtr
->depth
, False
);
591 graybuttoncolor
= WMCreateRGBColor(scrPtr
, (255 / 6) * i
<< 8,
592 (255 / 6) * i
<< 8, (255 / 6) * i
<< 8, True
);
593 WMPaintColorSwatch(graybuttoncolor
, pixmap
->pixmap
, 0, 0, 15, 15);
594 WMReleaseColor(graybuttoncolor
);
596 panel
->grayPresetBtn
[i
] = WMCreateCommandButton(panel
->grayFrm
);
597 WMResizeWidget(panel
->grayPresetBtn
[i
], 20, 24);
598 WMMoveWidget(panel
->grayPresetBtn
[i
], 2 + (i
* 20), 34);
599 WMSetButtonAction(panel
->grayPresetBtn
[i
], grayPresetButtonCallback
, panel
);
600 WMSetButtonImage(panel
->grayPresetBtn
[i
], pixmap
);
601 WMSetButtonImagePosition(panel
->grayPresetBtn
[i
], WIPImageOnly
);
602 WMReleasePixmap(pixmap
);
606 /* End of GrayScale Panel */
608 /* Widgets for RGB Panel */
609 panel
->rgbFrm
= WMCreateFrame(panel
->slidersFrm
);
610 WMSetFrameRelief(panel
->rgbFrm
, WRFlat
);
611 WMResizeWidget(panel
->rgbFrm
, PWIDTH
- 8, PHEIGHT
- 80 - 26 - 32);
612 WMMoveWidget(panel
->rgbFrm
, 0, 34);
614 panel
->rgbMinL
= WMCreateLabel(panel
->rgbFrm
);
615 WMResizeWidget(panel
->rgbMinL
, 20, 10);
616 WMMoveWidget(panel
->rgbMinL
, 2, 2);
617 WMSetLabelText(panel
->rgbMinL
, "0");
618 WMSetLabelTextAlignment(panel
->rgbMinL
, WALeft
);
619 WMSetLabelTextColor(panel
->rgbMinL
, textcolor
);
620 WMSetLabelFont(panel
->rgbMinL
, panel
->font8
);
622 panel
->rgbMaxL
= WMCreateLabel(panel
->rgbFrm
);
623 WMResizeWidget(panel
->rgbMaxL
, 40, 10);
624 WMMoveWidget(panel
->rgbMaxL
, 104, 2);
625 WMSetLabelText(panel
->rgbMaxL
, "255");
626 WMSetLabelTextAlignment(panel
->rgbMaxL
, WARight
);
627 WMSetLabelTextColor(panel
->rgbMaxL
, textcolor
);
628 WMSetLabelFont(panel
->rgbMaxL
, panel
->font8
);
630 panel
->rgbRedS
= WMCreateSlider(panel
->rgbFrm
);
631 WMResizeWidget(panel
->rgbRedS
, 141, 16);
632 WMMoveWidget(panel
->rgbRedS
, 2, 14);
633 WMSetSliderMinValue(panel
->rgbRedS
, 0);
634 WMSetSliderMaxValue(panel
->rgbRedS
, 255);
635 WMSetSliderKnobThickness(panel
->rgbRedS
, knobThickness
);
636 WMSetSliderAction(panel
->rgbRedS
, rgbSliderCallback
, panel
);
642 image
= RRenderGradient(141, 16, &from
, &to
, RGRD_HORIZONTAL
);
643 pixmap
= WMCreatePixmapFromRImage(scrPtr
, image
, 0);
644 RReleaseImage(image
);
647 W_PaintText(W_VIEW(panel
->rgbRedS
), pixmap
->pixmap
, panel
->font12
,
648 2, 0, 100, WALeft
, scrPtr
->white
, False
, _("Red"), strlen(_("Red")));
650 wwarning(_("Color Panel: Could not allocate memory"));
652 WMSetSliderImage(panel
->rgbRedS
, pixmap
);
653 WMReleasePixmap(pixmap
);
655 panel
->rgbRedT
= WMCreateTextField(panel
->rgbFrm
);
656 WMResizeWidget(panel
->rgbRedT
, 40, 18);
657 WMMoveWidget(panel
->rgbRedT
, 146, 13);
658 WMSetTextFieldAlignment(panel
->rgbRedT
, WALeft
);
659 WMAddNotificationObserver(rgbTextFieldCallback
, panel
, WMTextDidEndEditingNotification
, panel
->rgbRedT
);
661 panel
->rgbGreenS
= WMCreateSlider(panel
->rgbFrm
);
662 WMResizeWidget(panel
->rgbGreenS
, 141, 16);
663 WMMoveWidget(panel
->rgbGreenS
, 2, 36);
664 WMSetSliderMinValue(panel
->rgbGreenS
, 0);
665 WMSetSliderMaxValue(panel
->rgbGreenS
, 255);
666 WMSetSliderKnobThickness(panel
->rgbGreenS
, knobThickness
);
667 WMSetSliderAction(panel
->rgbGreenS
, rgbSliderCallback
, panel
);
673 image
= RRenderGradient(141, 16, &from
, &to
, RGRD_HORIZONTAL
);
674 pixmap
= WMCreatePixmapFromRImage(scrPtr
, image
, 0);
675 RReleaseImage(image
);
678 W_PaintText(W_VIEW(panel
->rgbGreenS
), pixmap
->pixmap
, panel
->font12
,
679 2, 0, 100, WALeft
, scrPtr
->white
, False
, _("Green"), strlen(_("Green")));
681 wwarning(_("Color Panel: Could not allocate memory"));
683 WMSetSliderImage(panel
->rgbGreenS
, pixmap
);
684 WMReleasePixmap(pixmap
);
686 panel
->rgbGreenT
= WMCreateTextField(panel
->rgbFrm
);
687 WMResizeWidget(panel
->rgbGreenT
, 40, 18);
688 WMMoveWidget(panel
->rgbGreenT
, 146, 35);
689 WMSetTextFieldAlignment(panel
->rgbGreenT
, WALeft
);
690 WMAddNotificationObserver(rgbTextFieldCallback
, panel
, WMTextDidEndEditingNotification
, panel
->rgbGreenT
);
692 panel
->rgbBlueS
= WMCreateSlider(panel
->rgbFrm
);
693 WMResizeWidget(panel
->rgbBlueS
, 141, 16);
694 WMMoveWidget(panel
->rgbBlueS
, 2, 58);
695 WMSetSliderMinValue(panel
->rgbBlueS
, 0);
696 WMSetSliderMaxValue(panel
->rgbBlueS
, 255);
697 WMSetSliderKnobThickness(panel
->rgbBlueS
, knobThickness
);
698 WMSetSliderAction(panel
->rgbBlueS
, rgbSliderCallback
, panel
);
704 image
= RRenderGradient(141, 16, &from
, &to
, RGRD_HORIZONTAL
);
705 pixmap
= WMCreatePixmapFromRImage(scrPtr
, image
, 0);
706 RReleaseImage(image
);
709 W_PaintText(W_VIEW(panel
->rgbBlueS
), pixmap
->pixmap
, panel
->font12
,
710 2, 0, 100, WALeft
, scrPtr
->white
, False
, _("Blue"), strlen(_("Blue")));
712 wwarning(_("Color Panel: Could not allocate memory"));
714 WMSetSliderImage(panel
->rgbBlueS
, pixmap
);
715 WMReleasePixmap(pixmap
);
717 panel
->rgbBlueT
= WMCreateTextField(panel
->rgbFrm
);
718 WMResizeWidget(panel
->rgbBlueT
, 40, 18);
719 WMMoveWidget(panel
->rgbBlueT
, 146, 57);
720 WMSetTextFieldAlignment(panel
->rgbBlueT
, WALeft
);
721 WMAddNotificationObserver(rgbTextFieldCallback
, panel
, WMTextDidEndEditingNotification
, panel
->rgbBlueT
);
723 panel
->rgbDecB
= WMCreateButton(panel
->rgbFrm
, WBTRadio
);
724 WMSetButtonText(panel
->rgbDecB
, "Decimal");
725 WMSetButtonSelected(panel
->rgbDecB
, 1);
726 panel
->rgbState
= RGBdec
;
727 WMSetButtonAction(panel
->rgbDecB
, rgbDecToHex
, panel
);
728 WMResizeWidget(panel
->rgbDecB
, PWIDTH
- 8, 23);
729 WMMoveWidget(panel
->rgbDecB
, 2, 81);
731 panel
->rgbHexB
= WMCreateButton(panel
->rgbFrm
, WBTRadio
);
732 WMSetButtonText(panel
->rgbHexB
, "Hexadecimal");
733 WMSetButtonAction(panel
->rgbHexB
, rgbDecToHex
, panel
);
734 WMResizeWidget(panel
->rgbHexB
, PWIDTH
- 8, 23);
735 WMMoveWidget(panel
->rgbHexB
, 2, 104);
737 WMGroupButtons(panel
->rgbDecB
, panel
->rgbHexB
);
739 /* End of RGB Panel */
741 /* Widgets for CMYK Panel */
742 panel
->cmykFrm
= WMCreateFrame(panel
->slidersFrm
);
743 WMSetFrameRelief(panel
->cmykFrm
, WRFlat
);
744 WMResizeWidget(panel
->cmykFrm
, PWIDTH
- 8, PHEIGHT
- 80 - 26 - 32);
745 WMMoveWidget(panel
->cmykFrm
, 0, 34);
747 panel
->cmykMinL
= WMCreateLabel(panel
->cmykFrm
);
748 WMResizeWidget(panel
->cmykMinL
, 20, 10);
749 WMMoveWidget(panel
->cmykMinL
, 2, 2);
750 WMSetLabelText(panel
->cmykMinL
, "0");
751 WMSetLabelTextAlignment(panel
->cmykMinL
, WALeft
);
752 WMSetLabelTextColor(panel
->cmykMinL
, textcolor
);
753 WMSetLabelFont(panel
->cmykMinL
, panel
->font8
);
755 panel
->cmykMaxL
= WMCreateLabel(panel
->cmykFrm
);
756 WMResizeWidget(panel
->cmykMaxL
, 40, 10);
757 WMMoveWidget(panel
->cmykMaxL
, 104, 2);
758 WMSetLabelText(panel
->cmykMaxL
, "100");
759 WMSetLabelTextAlignment(panel
->cmykMaxL
, WARight
);
760 WMSetLabelTextColor(panel
->cmykMaxL
, textcolor
);
761 WMSetLabelFont(panel
->cmykMaxL
, panel
->font8
);
763 panel
->cmykCyanS
= WMCreateSlider(panel
->cmykFrm
);
764 WMResizeWidget(panel
->cmykCyanS
, 141, 16);
765 WMMoveWidget(panel
->cmykCyanS
, 2, 14);
766 WMSetSliderMinValue(panel
->cmykCyanS
, 0);
767 WMSetSliderMaxValue(panel
->cmykCyanS
, 100);
768 WMSetSliderKnobThickness(panel
->cmykCyanS
, knobThickness
);
769 WMSetSliderAction(panel
->cmykCyanS
, cmykSliderCallback
, panel
);
779 image
= RRenderGradient(141, 16, &from
, &to
, RGRD_HORIZONTAL
);
780 pixmap
= WMCreatePixmapFromRImage(scrPtr
, image
, 0);
781 RReleaseImage(image
);
784 W_PaintText(W_VIEW(panel
->cmykCyanS
), pixmap
->pixmap
, panel
->font12
,
785 2, 0, 100, WALeft
, scrPtr
->black
, False
, _("Cyan"), strlen(_("Cyan")));
787 wwarning(_("Color Panel: Could not allocate memory"));
789 WMSetSliderImage(panel
->cmykCyanS
, pixmap
);
790 WMReleasePixmap(pixmap
);
792 panel
->cmykCyanT
= WMCreateTextField(panel
->cmykFrm
);
793 WMResizeWidget(panel
->cmykCyanT
, 40, 18);
794 WMMoveWidget(panel
->cmykCyanT
, 146, 13);
795 WMSetTextFieldAlignment(panel
->cmykCyanT
, WALeft
);
796 WMAddNotificationObserver(cmykTextFieldCallback
, panel
, WMTextDidEndEditingNotification
, panel
->cmykCyanT
);
798 panel
->cmykMagentaS
= WMCreateSlider(panel
->cmykFrm
);
799 WMResizeWidget(panel
->cmykMagentaS
, 141, 16);
800 WMMoveWidget(panel
->cmykMagentaS
, 2, 36);
801 WMSetSliderMinValue(panel
->cmykMagentaS
, 0);
802 WMSetSliderMaxValue(panel
->cmykMagentaS
, 100);
803 WMSetSliderKnobThickness(panel
->cmykMagentaS
, knobThickness
);
804 WMSetSliderAction(panel
->cmykMagentaS
, cmykSliderCallback
, panel
);
810 image
= RRenderGradient(141, 16, &from
, &to
, RGRD_HORIZONTAL
);
811 pixmap
= WMCreatePixmapFromRImage(scrPtr
, image
, 0);
812 RReleaseImage(image
);
815 W_PaintText(W_VIEW(panel
->cmykMagentaS
), pixmap
->pixmap
, panel
->font12
,
816 2, 0, 100, WALeft
, scrPtr
->black
, False
, _("Magenta"), strlen(_("Magenta")));
818 wwarning(_("Color Panel: Could not allocate memory"));
820 WMSetSliderImage(panel
->cmykMagentaS
, pixmap
);
821 WMReleasePixmap(pixmap
);
823 panel
->cmykMagentaT
= WMCreateTextField(panel
->cmykFrm
);
824 WMResizeWidget(panel
->cmykMagentaT
, 40, 18);
825 WMMoveWidget(panel
->cmykMagentaT
, 146, 35);
826 WMSetTextFieldAlignment(panel
->cmykMagentaT
, WALeft
);
827 WMAddNotificationObserver(cmykTextFieldCallback
, panel
,
828 WMTextDidEndEditingNotification
, panel
->cmykMagentaT
);
830 panel
->cmykYellowS
= WMCreateSlider(panel
->cmykFrm
);
831 WMResizeWidget(panel
->cmykYellowS
, 141, 16);
832 WMMoveWidget(panel
->cmykYellowS
, 2, 58);
833 WMSetSliderMinValue(panel
->cmykYellowS
, 0);
834 WMSetSliderMaxValue(panel
->cmykYellowS
, 100);
835 WMSetSliderKnobThickness(panel
->cmykYellowS
, knobThickness
);
836 WMSetSliderAction(panel
->cmykYellowS
, cmykSliderCallback
, panel
);
842 image
= RRenderGradient(141, 16, &from
, &to
, RGRD_HORIZONTAL
);
843 pixmap
= WMCreatePixmapFromRImage(scrPtr
, image
, 0);
844 RReleaseImage(image
);
847 W_PaintText(W_VIEW(panel
->cmykYellowS
), pixmap
->pixmap
, panel
->font12
,
848 2, 0, 100, WALeft
, scrPtr
->black
, False
, _("Yellow"), strlen(_("Yellow")));
850 wwarning(_("Color Panel: Could not allocate memory"));
852 WMSetSliderImage(panel
->cmykYellowS
, pixmap
);
853 WMReleasePixmap(pixmap
);
855 panel
->cmykYellowT
= WMCreateTextField(panel
->cmykFrm
);
856 WMResizeWidget(panel
->cmykYellowT
, 40, 18);
857 WMMoveWidget(panel
->cmykYellowT
, 146, 57);
858 WMSetTextFieldAlignment(panel
->cmykYellowT
, WALeft
);
859 WMAddNotificationObserver(cmykTextFieldCallback
, panel
,
860 WMTextDidEndEditingNotification
, panel
->cmykYellowT
);
862 panel
->cmykBlackS
= WMCreateSlider(panel
->cmykFrm
);
863 WMResizeWidget(panel
->cmykBlackS
, 141, 16);
864 WMMoveWidget(panel
->cmykBlackS
, 2, 80);
865 WMSetSliderMinValue(panel
->cmykBlackS
, 0);
866 WMSetSliderMaxValue(panel
->cmykBlackS
, 100);
867 WMSetSliderValue(panel
->cmykBlackS
, 0);
868 WMSetSliderKnobThickness(panel
->cmykBlackS
, knobThickness
);
869 WMSetSliderAction(panel
->cmykBlackS
, cmykSliderCallback
, panel
);
875 image
= RRenderGradient(141, 16, &from
, &to
, RGRD_HORIZONTAL
);
876 pixmap
= WMCreatePixmapFromRImage(scrPtr
, image
, 0);
877 RReleaseImage(image
);
880 W_PaintText(W_VIEW(panel
->cmykBlackS
), pixmap
->pixmap
, panel
->font12
,
881 2, 0, 100, WALeft
, scrPtr
->black
, False
, _("Black"), strlen(_("Black")));
883 wwarning(_("Color Panel: Could not allocate memory"));
885 WMSetSliderImage(panel
->cmykBlackS
, pixmap
);
886 WMReleasePixmap(pixmap
);
888 panel
->cmykBlackT
= WMCreateTextField(panel
->cmykFrm
);
889 WMResizeWidget(panel
->cmykBlackT
, 40, 18);
890 WMMoveWidget(panel
->cmykBlackT
, 146, 79);
891 WMSetTextFieldAlignment(panel
->cmykBlackT
, WALeft
);
892 WMAddNotificationObserver(cmykTextFieldCallback
, panel
,
893 WMTextDidEndEditingNotification
, panel
->cmykBlackT
);
894 /* End of CMYK Panel */
896 /* Widgets for HSB Panel */
897 panel
->hsbFrm
= WMCreateFrame(panel
->slidersFrm
);
898 WMSetFrameRelief(panel
->hsbFrm
, WRFlat
);
899 WMResizeWidget(panel
->hsbFrm
, PWIDTH
- 8, PHEIGHT
- 80 - 26 - 32);
900 WMMoveWidget(panel
->hsbFrm
, 0, 34);
902 panel
->hsbHueS
= WMCreateSlider(panel
->hsbFrm
);
903 WMResizeWidget(panel
->hsbHueS
, 141, 16);
904 WMMoveWidget(panel
->hsbHueS
, 2, 14);
905 WMSetSliderMinValue(panel
->hsbHueS
, 0);
906 WMSetSliderMaxValue(panel
->hsbHueS
, 359);
907 WMSetSliderKnobThickness(panel
->hsbHueS
, knobThickness
);
908 WMSetSliderAction(panel
->hsbHueS
, hsbSliderCallback
, panel
);
910 panel
->hsbHueT
= WMCreateTextField(panel
->hsbFrm
);
911 WMResizeWidget(panel
->hsbHueT
, 40, 18);
912 WMMoveWidget(panel
->hsbHueT
, 146, 13);
913 WMSetTextFieldAlignment(panel
->hsbHueT
, WALeft
);
914 WMAddNotificationObserver(hsbTextFieldCallback
, panel
, WMTextDidEndEditingNotification
, panel
->hsbHueT
);
916 panel
->hsbSaturationS
= WMCreateSlider(panel
->hsbFrm
);
917 WMResizeWidget(panel
->hsbSaturationS
, 141, 16);
918 WMMoveWidget(panel
->hsbSaturationS
, 2, 36);
919 WMSetSliderMinValue(panel
->hsbSaturationS
, 0);
920 WMSetSliderMaxValue(panel
->hsbSaturationS
, 100);
921 WMSetSliderKnobThickness(panel
->hsbSaturationS
, knobThickness
);
922 WMSetSliderAction(panel
->hsbSaturationS
, hsbSliderCallback
, panel
);
924 panel
->hsbSaturationT
= WMCreateTextField(panel
->hsbFrm
);
925 WMResizeWidget(panel
->hsbSaturationT
, 40, 18);
926 WMMoveWidget(panel
->hsbSaturationT
, 146, 35);
927 WMSetTextFieldAlignment(panel
->hsbSaturationT
, WALeft
);
928 WMAddNotificationObserver(hsbTextFieldCallback
, panel
,
929 WMTextDidEndEditingNotification
, panel
->hsbSaturationT
);
931 panel
->hsbBrightnessS
= WMCreateSlider(panel
->hsbFrm
);
932 WMResizeWidget(panel
->hsbBrightnessS
, 141, 16);
933 WMMoveWidget(panel
->hsbBrightnessS
, 2, 58);
934 WMSetSliderMinValue(panel
->hsbBrightnessS
, 0);
935 WMSetSliderMaxValue(panel
->hsbBrightnessS
, 100);
936 WMSetSliderKnobThickness(panel
->hsbBrightnessS
, knobThickness
);
937 WMSetSliderAction(panel
->hsbBrightnessS
, hsbSliderCallback
, panel
);
939 panel
->hsbBrightnessT
= WMCreateTextField(panel
->hsbFrm
);
940 WMResizeWidget(panel
->hsbBrightnessT
, 40, 18);
941 WMMoveWidget(panel
->hsbBrightnessT
, 146, 57);
942 WMSetTextFieldAlignment(panel
->hsbBrightnessT
, WALeft
);
943 WMAddNotificationObserver(hsbTextFieldCallback
, panel
,
944 WMTextDidEndEditingNotification
, panel
->hsbBrightnessT
);
945 /* End of HSB Panel */
947 WMReleaseColor(textcolor
);
949 /* Widgets for the CustomPalette Panel */
950 panel
->customPaletteFrm
= WMCreateFrame(panel
->win
);
951 WMSetFrameRelief(panel
->customPaletteFrm
, WRFlat
);
952 WMResizeWidget(panel
->customPaletteFrm
, PWIDTH
- 8, PHEIGHT
- 80 - 26);
953 WMMoveWidget(panel
->customPaletteFrm
, 5, 80);
955 panel
->customPaletteHistoryBtn
= WMCreatePopUpButton(panel
->customPaletteFrm
);
956 WMAddPopUpButtonItem(panel
->customPaletteHistoryBtn
, _("Spectrum"));
957 WMSetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
,
958 WMGetPopUpButtonNumberOfItems(panel
->customPaletteHistoryBtn
) - 1);
959 WMSetPopUpButtonAction(panel
->customPaletteHistoryBtn
, customPaletteHistoryCallback
, panel
);
960 WMResizeWidget(panel
->customPaletteHistoryBtn
, PWIDTH
- 8, 20);
961 WMMoveWidget(panel
->customPaletteHistoryBtn
, 0, 0);
963 panel
->customPaletteContentFrm
= WMCreateFrame(panel
->customPaletteFrm
);
964 WMSetFrameRelief(panel
->customPaletteContentFrm
, WRSunken
);
965 WMResizeWidget(panel
->customPaletteContentFrm
, PWIDTH
- 8, PHEIGHT
- 156);
966 WMMoveWidget(panel
->customPaletteContentFrm
, 0, 23);
968 panel
->customPaletteContentView
= W_CreateView(W_VIEW(panel
->customPaletteContentFrm
));
969 /* XXX Test if we can create a view */
970 W_ResizeView(panel
->customPaletteContentView
, customPaletteWidth
, customPaletteHeight
);
971 W_MoveView(panel
->customPaletteContentView
, 2, 2);
973 /* Create event handler to handle expose/click events in CustomPalette */
974 WMCreateEventHandler(panel
->customPaletteContentView
,
975 ButtonPressMask
| ButtonReleaseMask
| EnterWindowMask
| LeaveWindowMask
|
976 ButtonMotionMask
, customPaletteHandleActionEvents
, panel
);
978 WMCreateEventHandler(panel
->customPaletteContentView
, ExposureMask
, customPaletteHandleEvents
, panel
);
980 panel
->customPaletteMenuBtn
= WMCreatePopUpButton(panel
->customPaletteFrm
);
981 WMSetPopUpButtonPullsDown(panel
->customPaletteMenuBtn
, 1);
982 WMSetPopUpButtonText(panel
->customPaletteMenuBtn
, _("Palette"));
983 WMSetPopUpButtonAction(panel
->customPaletteMenuBtn
, customPaletteMenuCallback
, panel
);
984 WMResizeWidget(panel
->customPaletteMenuBtn
, PWIDTH
- 8, 20);
985 WMMoveWidget(panel
->customPaletteMenuBtn
, 0, PHEIGHT
- 130);
987 WMAddPopUpButtonItem(panel
->customPaletteMenuBtn
, _("New from File..."));
988 WMAddPopUpButtonItem(panel
->customPaletteMenuBtn
, _("Rename..."));
989 WMAddPopUpButtonItem(panel
->customPaletteMenuBtn
, _("Remove"));
990 WMAddPopUpButtonItem(panel
->customPaletteMenuBtn
, _("Copy"));
991 WMAddPopUpButtonItem(panel
->customPaletteMenuBtn
, _("New from Clipboard"));
993 WMSetPopUpButtonItemEnabled(panel
->customPaletteMenuBtn
, CPmenuRename
, 0);
994 WMSetPopUpButtonItemEnabled(panel
->customPaletteMenuBtn
, CPmenuRemove
, 0);
995 WMSetPopUpButtonItemEnabled(panel
->customPaletteMenuBtn
, CPmenuCopy
, 0);
996 WMSetPopUpButtonItemEnabled(panel
->customPaletteMenuBtn
, CPmenuNewFromClipboard
, 0);
998 customRenderSpectrum(panel
);
999 panel
->currentPalette
= 0;
1000 panel
->palx
= customPaletteWidth
/ 2;
1001 panel
->paly
= customPaletteHeight
/ 2;
1003 /* Widgets for the ColorList Panel */
1004 panel
->colorListFrm
= WMCreateFrame(panel
->win
);
1005 WMSetFrameRelief(panel
->colorListFrm
, WRFlat
);
1006 WMResizeWidget(panel
->colorListFrm
, PWIDTH
- 8, PHEIGHT
- 80 - 26);
1007 WMMoveWidget(panel
->colorListFrm
, 5, 80);
1009 panel
->colorListHistoryBtn
= WMCreatePopUpButton(panel
->colorListFrm
);
1010 WMAddPopUpButtonItem(panel
->colorListHistoryBtn
, _("X11-Colors"));
1011 WMSetPopUpButtonSelectedItem(panel
->colorListHistoryBtn
,
1012 WMGetPopUpButtonNumberOfItems(panel
->colorListHistoryBtn
) - 1);
1013 /* WMSetPopUpButtonAction(panel->colorListHistoryBtn,
1014 * colorListHistoryCallback, panel); */
1015 WMResizeWidget(panel
->colorListHistoryBtn
, PWIDTH
- 8, 20);
1016 WMMoveWidget(panel
->colorListHistoryBtn
, 0, 0);
1018 panel
->colorListContentLst
= WMCreateList(panel
->colorListFrm
);
1019 WMSetListAction(panel
->colorListContentLst
, colorListSelect
, panel
);
1020 WMSetListUserDrawProc(panel
->colorListContentLst
, colorListPaintItem
);
1021 WMResizeWidget(panel
->colorListContentLst
, PWIDTH
- 8, PHEIGHT
- 156);
1022 WMMoveWidget(panel
->colorListContentLst
, 0, 23);
1023 WMHangData(panel
->colorListContentLst
, panel
);
1025 panel
->colorListColorMenuBtn
= WMCreatePopUpButton(panel
->colorListFrm
);
1026 WMSetPopUpButtonPullsDown(panel
->colorListColorMenuBtn
, 1);
1027 WMSetPopUpButtonText(panel
->colorListColorMenuBtn
, _("Color"));
1028 WMSetPopUpButtonAction(panel
->colorListColorMenuBtn
, colorListColorMenuCallback
, panel
);
1029 WMResizeWidget(panel
->colorListColorMenuBtn
, (PWIDTH
- 16) / 2, 20);
1030 WMMoveWidget(panel
->colorListColorMenuBtn
, 0, PHEIGHT
- 130);
1032 WMAddPopUpButtonItem(panel
->colorListColorMenuBtn
, _("Add..."));
1033 WMAddPopUpButtonItem(panel
->colorListColorMenuBtn
, _("Rename..."));
1034 WMAddPopUpButtonItem(panel
->colorListColorMenuBtn
, _("Remove"));
1036 WMSetPopUpButtonItemEnabled(panel
->colorListColorMenuBtn
, CLmenuAdd
, 0);
1037 WMSetPopUpButtonItemEnabled(panel
->colorListColorMenuBtn
, CLmenuRename
, 0);
1038 WMSetPopUpButtonItemEnabled(panel
->colorListColorMenuBtn
, CLmenuRemove
, 0);
1040 panel
->colorListListMenuBtn
= WMCreatePopUpButton(panel
->colorListFrm
);
1041 WMSetPopUpButtonPullsDown(panel
->colorListListMenuBtn
, 1);
1042 WMSetPopUpButtonText(panel
->colorListListMenuBtn
, _("List"));
1043 WMSetPopUpButtonAction(panel
->colorListListMenuBtn
, colorListListMenuCallback
, panel
);
1044 WMResizeWidget(panel
->colorListListMenuBtn
, (PWIDTH
- 16) / 2, 20);
1045 WMMoveWidget(panel
->colorListListMenuBtn
, (PWIDTH
- 16) / 2 + 8, PHEIGHT
- 130);
1047 WMAddPopUpButtonItem(panel
->colorListListMenuBtn
, _("New..."));
1048 WMAddPopUpButtonItem(panel
->colorListListMenuBtn
, _("Rename..."));
1049 WMAddPopUpButtonItem(panel
->colorListListMenuBtn
, _("Remove"));
1051 WMSetPopUpButtonItemEnabled(panel
->colorListListMenuBtn
, CLmenuAdd
, 0);
1052 WMSetPopUpButtonItemEnabled(panel
->colorListListMenuBtn
, CLmenuRename
, 0);
1053 WMSetPopUpButtonItemEnabled(panel
->colorListListMenuBtn
, CLmenuRemove
, 0);
1055 WMRealizeWidget(panel
->win
);
1056 WMMapSubwidgets(panel
->win
);
1058 WMMapSubwidgets(panel
->wheelFrm
);
1059 WMMapSubwidgets(panel
->slidersFrm
);
1060 WMMapSubwidgets(panel
->grayFrm
);
1061 WMMapSubwidgets(panel
->rgbFrm
);
1062 WMMapSubwidgets(panel
->cmykFrm
);
1063 WMMapSubwidgets(panel
->hsbFrm
);
1064 WMMapSubwidgets(panel
->customPaletteFrm
);
1065 WMMapSubwidgets(panel
->customPaletteContentFrm
);
1066 WMMapSubwidgets(panel
->colorListFrm
);
1068 /* Pixmap to indicate selection positions
1069 * wheelframe MUST be mapped.
1071 panel
->selectionImg
= XCreatePixmap(scrPtr
->display
, WMWidgetXID(panel
->win
), 4, 4, scrPtr
->depth
);
1072 XFillRectangle(scrPtr
->display
, panel
->selectionImg
, bgc
, 0, 0, 4, 4);
1073 XFillRectangle(scrPtr
->display
, panel
->selectionImg
, wgc
, 1, 1, 2, 2);
1075 readConfiguration(panel
);
1081 WMColorPanel
*WMGetColorPanel(WMScreen
* scrPtr
)
1083 WMColorPanel
*panel
;
1085 if (scrPtr
->sharedColorPanel
)
1086 return scrPtr
->sharedColorPanel
;
1088 panel
= makeColorPanel(scrPtr
, "colorPanel");
1090 scrPtr
->sharedColorPanel
= panel
;
1095 void WMFreeColorPanel(WMColorPanel
* panel
)
1102 scr
= WMWidgetScreen(panel
->win
);
1103 if (panel
== scr
->sharedColorPanel
) {
1104 scr
->sharedColorPanel
= NULL
;
1107 WMRemoveNotificationObserver(panel
);
1108 WMUnmapWidget(panel
->win
);
1111 WMReleaseFont(panel
->font8
);
1112 WMReleaseFont(panel
->font12
);
1115 wheelDestroyMatrix(panel
->wheelMtrx
);
1116 if (panel
->wheelImg
)
1117 XFreePixmap(scr
->display
, panel
->wheelImg
);
1118 if (panel
->selectionImg
)
1119 XFreePixmap(scr
->display
, panel
->selectionImg
);
1120 if (panel
->selectionBackImg
)
1121 XFreePixmap(scr
->display
, panel
->selectionBackImg
);
1122 RReleaseImage(panel
->customPaletteImg
);
1125 if (panel
->lastBrowseDir
)
1126 wfree(panel
->lastBrowseDir
);
1127 if (panel
->configurationPath
)
1128 wfree(panel
->configurationPath
);
1130 WMDestroyWidget(panel
->win
);
1135 void WMCloseColorPanel(WMColorPanel
* panel
)
1137 WMFreeColorPanel(panel
);
1140 void WMShowColorPanel(WMColorPanel
* panel
)
1142 WMScreen
*scr
= WMWidgetScreen(panel
->win
);
1143 WMColor
*white
= WMWhiteColor(scr
);
1145 if (panel
->color
.set
== cpNone
)
1146 WMSetColorPanelColor(panel
, white
);
1147 WMReleaseColor(white
);
1149 if (panel
->mode
!= WMWheelModeColorPanel
)
1150 WMPerformButtonClick(panel
->wheelBtn
);
1152 WMMapWidget(panel
->win
);
1155 static void closeWindowCallback(WMWidget
* w
, void *data
)
1157 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
1159 /* Parameter not used, but tell the compiler that it is ok */
1162 WMCloseColorPanel(panel
);
1165 static void readConfiguration(W_ColorPanel
* panel
)
1167 /* XXX Doesn't take care of "invalid" files */
1171 struct stat stat_buf
;
1174 if (stat(panel
->configurationPath
, &stat_buf
) != 0) {
1175 if (mkdir(panel
->configurationPath
, S_IRWXU
| S_IRGRP
| S_IROTH
| S_IXGRP
| S_IXOTH
) != 0) {
1176 werror(_("Color Panel: Could not create directory %s needed"
1177 " to store configurations"), panel
->configurationPath
);
1178 WMSetPopUpButtonEnabled(panel
->customPaletteMenuBtn
, False
);
1179 WMSetPopUpButtonEnabled(panel
->colorListColorMenuBtn
, False
);
1180 WMSetPopUpButtonEnabled(panel
->colorListListMenuBtn
, False
);
1181 WMRunAlertPanel(WMWidgetScreen(panel
->win
), panel
->win
,
1183 _("Could not create ColorPanel configuration directory"),
1184 _("OK"), NULL
, NULL
);
1189 if (!(dPtr
= opendir(panel
->configurationPath
))) {
1190 wwarning("%s: %s", _("Color Panel: Could not find file"), panel
->configurationPath
);
1194 while ((dp
= readdir(dPtr
)) != NULL
) {
1195 unsigned int perm_mask
;
1196 char *path
= wstrconcat(panel
->configurationPath
,
1199 if (dp
->d_name
[0] != '.') {
1200 item
= WMGetPopUpButtonNumberOfItems(panel
->customPaletteHistoryBtn
);
1201 WMAddPopUpButtonItem(panel
->customPaletteHistoryBtn
, dp
->d_name
);
1203 perm_mask
= (access(path
, R_OK
) == 0);
1204 WMSetPopUpButtonItemEnabled(panel
->customPaletteHistoryBtn
, item
, perm_mask
);
1211 static void readXColors(W_ColorPanel
* panel
)
1214 const RGBColor
*entry
;
1216 for (entry
= rgbColors
; entry
->name
!= NULL
; entry
++) {
1217 item
= WMAddListItem(panel
->colorListContentLst
, entry
->name
);
1218 item
->clientData
= (void *)&(entry
->color
);
1222 void WMSetColorPanelPickerMode(WMColorPanel
* panel
, WMColorPanelMode mode
)
1224 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1226 if (mode
!= WMWheelModeColorPanel
) {
1227 WMUnmapWidget(panel
->wheelFrm
);
1228 if (panel
->selectionBackImg
) {
1229 XFreePixmap(WMWidgetScreen(panel
->win
)->display
, panel
->selectionBackImg
);
1230 panel
->selectionBackImg
= None
;
1233 if (mode
!= WMGrayModeColorPanel
)
1234 WMUnmapWidget(panel
->grayFrm
);
1235 if (mode
!= WMRGBModeColorPanel
)
1236 WMUnmapWidget(panel
->rgbFrm
);
1237 if (mode
!= WMCMYKModeColorPanel
)
1238 WMUnmapWidget(panel
->cmykFrm
);
1239 if (mode
!= WMHSBModeColorPanel
)
1240 WMUnmapWidget(panel
->hsbFrm
);
1241 if (mode
!= WMCustomPaletteModeColorPanel
) {
1242 WMUnmapWidget(panel
->customPaletteFrm
);
1243 if (panel
->selectionBackImg
) {
1244 XFreePixmap(WMWidgetScreen(panel
->win
)->display
, panel
->selectionBackImg
);
1245 panel
->selectionBackImg
= None
;
1248 if (mode
!= WMColorListModeColorPanel
)
1249 WMUnmapWidget(panel
->colorListFrm
);
1250 if ((mode
!= WMGrayModeColorPanel
) && (mode
!= WMRGBModeColorPanel
) &&
1251 (mode
!= WMCMYKModeColorPanel
) && (mode
!= WMHSBModeColorPanel
))
1252 WMUnmapWidget(panel
->slidersFrm
);
1254 panel
->slidersmode
= mode
;
1256 if (mode
== WMWheelModeColorPanel
) {
1257 WMMapWidget(panel
->wheelFrm
);
1258 WMSetButtonSelected(panel
->wheelBtn
, True
);
1259 if (panel
->lastChanged
!= WMWheelModeColorPanel
)
1263 } else if (mode
== WMGrayModeColorPanel
) {
1264 WMMapWidget(panel
->slidersFrm
);
1265 WMSetButtonSelected(panel
->slidersBtn
, True
);
1266 WMMapWidget(panel
->grayFrm
);
1267 WMSetButtonSelected(panel
->grayBtn
, True
);
1268 WMSetButtonImage(panel
->slidersBtn
, scr
->grayIcon
);
1269 if (panel
->lastChanged
!= WMGrayModeColorPanel
)
1271 } else if (mode
== WMRGBModeColorPanel
) {
1272 WMMapWidget(panel
->slidersFrm
);
1273 WMSetButtonSelected(panel
->slidersBtn
, True
);
1274 WMMapWidget(panel
->rgbFrm
);
1275 WMSetButtonSelected(panel
->rgbBtn
, True
);
1276 WMSetButtonImage(panel
->slidersBtn
, scr
->rgbIcon
);
1277 if (panel
->lastChanged
!= WMRGBModeColorPanel
)
1279 } else if (mode
== WMCMYKModeColorPanel
) {
1280 WMMapWidget(panel
->slidersFrm
);
1281 WMSetButtonSelected(panel
->slidersBtn
, True
);
1282 WMMapWidget(panel
->cmykFrm
);
1283 WMSetButtonSelected(panel
->cmykBtn
, True
);
1284 WMSetButtonImage(panel
->slidersBtn
, scr
->cmykIcon
);
1285 if (panel
->lastChanged
!= WMCMYKModeColorPanel
)
1287 } else if (mode
== WMHSBModeColorPanel
) {
1288 WMMapWidget(panel
->slidersFrm
);
1289 WMSetButtonSelected(panel
->slidersBtn
, True
);
1290 WMMapWidget(panel
->hsbFrm
);
1291 WMSetButtonSelected(panel
->hsbBtn
, True
);
1292 WMSetButtonImage(panel
->slidersBtn
, scr
->hsbIcon
);
1293 if (panel
->lastChanged
!= WMHSBModeColorPanel
)
1295 } else if (mode
== WMCustomPaletteModeColorPanel
) {
1296 WMMapWidget(panel
->customPaletteFrm
);
1297 WMSetButtonSelected(panel
->customPaletteBtn
, True
);
1298 customSetPalette(panel
);
1299 } else if (mode
== WMColorListModeColorPanel
) {
1300 WMMapWidget(panel
->colorListFrm
);
1301 WMSetButtonSelected(panel
->colorListBtn
, True
);
1307 WMColor
*WMGetColorPanelColor(WMColorPanel
* panel
)
1309 return WMGetColorWellColor(panel
->colorWell
);
1312 void WMSetColorPanelColor(WMColorPanel
* panel
, WMColor
* color
)
1314 WMSetColorWellColor(panel
->colorWell
, color
);
1316 panel
->color
.rgb
.red
= color
->color
.red
>> 8;
1317 panel
->color
.rgb
.green
= color
->color
.green
>> 8;
1318 panel
->color
.rgb
.blue
= color
->color
.blue
>> 8;
1319 panel
->color
.set
= cpRGB
;
1321 if (panel
->mode
== panel
->lastChanged
)
1322 panel
->lastChanged
= 0;
1324 WMSetColorPanelPickerMode(panel
, panel
->mode
);
1327 static void updateSwatch(WMColorPanel
* panel
, CPColor color
)
1329 WMScreen
*scr
= WMWidgetScreen(panel
->win
);
1332 if (color
.set
!= cpRGB
)
1333 convertCPColor(&color
);
1335 panel
->color
= color
;
1337 wellcolor
= WMCreateRGBColor(scr
, color
.rgb
.red
<< 8, color
.rgb
.green
<< 8, color
.rgb
.blue
<< 8, True
);
1339 WMSetColorWellColor(panel
->colorWell
, wellcolor
);
1340 WMReleaseColor(wellcolor
);
1342 if (!panel
->flags
.dragging
|| panel
->flags
.continuous
) {
1344 (*panel
->action
) (panel
, panel
->clientData
);
1346 WMPostNotificationName(WMColorPanelColorChangedNotification
, panel
, NULL
);
1350 static void modeButtonCallback(WMWidget
* w
, void *data
)
1352 W_ColorPanel
*panel
= (W_ColorPanel
*) (data
);
1354 if (w
== panel
->wheelBtn
)
1355 WMSetColorPanelPickerMode(panel
, WMWheelModeColorPanel
);
1356 else if (w
== panel
->slidersBtn
)
1357 WMSetColorPanelPickerMode(panel
, panel
->slidersmode
);
1358 else if (w
== panel
->customPaletteBtn
)
1359 WMSetColorPanelPickerMode(panel
, WMCustomPaletteModeColorPanel
);
1360 else if (w
== panel
->colorListBtn
)
1361 WMSetColorPanelPickerMode(panel
, WMColorListModeColorPanel
);
1362 else if (w
== panel
->grayBtn
)
1363 WMSetColorPanelPickerMode(panel
, WMGrayModeColorPanel
);
1364 else if (w
== panel
->rgbBtn
)
1365 WMSetColorPanelPickerMode(panel
, WMRGBModeColorPanel
);
1366 else if (w
== panel
->cmykBtn
)
1367 WMSetColorPanelPickerMode(panel
, WMCMYKModeColorPanel
);
1368 else if (w
== panel
->hsbBtn
)
1369 WMSetColorPanelPickerMode(panel
, WMHSBModeColorPanel
);
1372 /****************** Magnifying Cursor Functions *******************/
1374 static XImage
*magnifyGetImage(WMScreen
* scr
, XImage
* image
, int x
, int y
, int w
, int h
)
1376 int x0
= 0, y0
= 0, w0
= w
, h0
= h
;
1377 const int displayWidth
= DisplayWidth(scr
->display
, scr
->screen
),
1378 displayHeight
= DisplayHeight(scr
->display
, scr
->screen
);
1380 if (!(image
&& image
->data
)) {
1381 /* The image in panel->magnifyGlass->image does not exist yet.
1382 * Grab one from the screen (not beyond) and use it from now on.
1384 if (!(image
= XGetImage(scr
->display
, scr
->rootWin
,
1385 x
- Cursor_x_hot
, y
- Cursor_y_hot
, w
, h
, AllPlanes
, ZPixmap
)))
1386 wwarning(_("Color Panel: X failed request"));
1391 /* Coordinate correction for back pixmap
1392 * if magnifying glass is at screen-borders
1395 /* Figure 1: Shifting of rectangle-to-grab at top/left screen borders
1396 * Hatched area is beyond screen border.
1398 * |<-Cursor_x_hot->|
1399 * ________________|_____
1400 * |/ / / / / / /| | |
1401 * | / / / / / / |(x,y) |
1402 * |/_/_/_/_/_/_/|________|
1403 * |<----x0----->|<--w0-->|
1407 /* Figure 2: Shifting of rectangle-to-grab at bottom/right
1409 * Hatched area is beyond screen border
1411 * |<-Cursor_x_hot->|
1412 * ________________|_______________
1413 * | | | / / / / / /|
1414 * | (x,y)|/ / / / / / |
1415 * |___________________|_/_/_/_/_/_/|
1416 * |<-------w0-------->| |
1417 * |<---------------w--|----------->|
1422 if (x
< Cursor_x_hot
) { /* see fig. 1 */
1423 x0
= Cursor_x_hot
- x
;
1427 if (displayWidth
- 1 < x
- Cursor_x_hot
+ w
) { /* see fig. 2 */
1428 w0
= (displayWidth
) - (x
- Cursor_x_hot
);
1431 if (y
< Cursor_y_hot
) { /* see fig. 1 */
1432 y0
= Cursor_y_hot
- y
;
1436 if (displayHeight
- 1 < y
- Cursor_y_hot
+ h
) { /* see fig. 2 */
1437 h0
= (displayHeight
) - (y
- Cursor_y_hot
);
1439 /* end of coordinate correction */
1441 /* Grab an image from the screen, clipped if necessary,
1442 * and put it in the existing panel->magnifyGlass->image
1443 * with the corresponding clipping offset.
1445 if (!XGetSubImage(scr
->display
, scr
->rootWin
,
1446 x
- Cursor_x_hot
+ x0
, y
- Cursor_y_hot
+ y0
, w0
, h0
, AllPlanes
, ZPixmap
, image
, x0
, y0
))
1447 wwarning(_("Color Panel: X failed request"));
1452 static void magnifyGetImageStored(WMColorPanel
* panel
, int x1
, int y1
, int x2
, int y2
)
1454 /* (x1, y1) = topleft corner of existing rectangle
1455 * (x2, y2) = topleft corner of new position
1458 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1459 int xa
= 0, ya
= 0, xb
= 0, yb
= 0;
1461 const int dx
= abs(x2
- x1
), dy
= abs(y2
- y1
);
1463 const int x_min
= Cursor_x_hot
,
1464 y_min
= Cursor_y_hot
,
1465 x_max
= DisplayWidth(scr
->display
, scr
->screen
) - 1 -
1466 (Cursor_mask_width
- Cursor_x_hot
),
1467 y_max
= DisplayHeight(scr
->display
, scr
->screen
) - 1 - (Cursor_mask_height
- Cursor_y_hot
);
1469 if ((dx
== 0) && (dy
== 0) && panel
->magnifyGlass
->image
)
1470 return; /* No movement */
1482 width
= Cursor_mask_width
- dx
;
1483 height
= Cursor_mask_height
- dy
;
1485 /* If the traversed distance is larger than the size of the magnifying
1486 * glass contents, there is no need to do dirty rectangles. A whole new
1487 * rectangle can be grabbed (unless that rectangle falls partially
1489 * Destroying the image and setting it to NULL will achieve that later on.
1491 * Of course, grabbing an XImage beyond the borders of the screen will
1492 * cause trouble, this is considdered a special case. Part of the screen
1493 * is grabbed, but there is no need for dirty rectangles.
1495 if ((width
<= 0) || (height
<= 0)) {
1496 if ((x2
>= x_min
) && (y2
>= y_min
) && (x2
<= x_max
) && (y2
<= y_max
)) {
1497 if (panel
->magnifyGlass
->image
)
1498 XDestroyImage(panel
->magnifyGlass
->image
);
1499 panel
->magnifyGlass
->image
= NULL
;
1502 if (panel
->magnifyGlass
->image
) {
1503 /* Get dirty rectangle from panel->magnifyGlass->image */
1504 panel
->magnifyGlass
->dirtyRect
=
1505 XSubImage(panel
->magnifyGlass
->image
, xa
, ya
, width
, height
);
1506 if (!panel
->magnifyGlass
->dirtyRect
) {
1507 wwarning(_("Color Panel: X failed request"));
1508 return; /* X returned a NULL from XSubImage */
1513 /* Get image from screen */
1514 image
= magnifyGetImage(scr
, panel
->magnifyGlass
->image
, x2
, y2
, Cursor_mask_width
, Cursor_mask_height
);
1515 if (image
) { /* Only reassign if a *new* image was grabbed */
1516 panel
->magnifyGlass
->image
= image
;
1520 /* Copy previously stored rectangle on covered part of image */
1521 if (panel
->magnifyGlass
->image
&& panel
->magnifyGlass
->dirtyRect
) {
1524 /* "width" and "height" are used as coordinates here,
1525 * and run from [0...width-1] and [0...height-1] respectively.
1529 old_height
= height
;
1531 for (; width
>= 0; width
--)
1532 for (height
= old_height
; height
>= 0; height
--)
1533 XPutPixel(panel
->magnifyGlass
->image
, xb
+ width
, yb
+ height
,
1534 XGetPixel(panel
->magnifyGlass
->dirtyRect
, width
, height
));
1535 XDestroyImage(panel
->magnifyGlass
->dirtyRect
);
1536 panel
->magnifyGlass
->dirtyRect
= NULL
;
1542 static Pixmap
magnifyCreatePixmap(WMColorPanel
* panel
)
1544 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1549 unsigned long color
;
1551 if (!panel
->magnifyGlass
->image
)
1554 if (!panel
->magnifyGlass
->magPix
)
1558 * Copy an area of only 5x5 pixels from the center of the image.
1560 for (u
= 0; u
< 5; u
++) {
1561 for (v
= 0; v
< 5; v
++) {
1562 color
= XGetPixel(panel
->magnifyGlass
->image
, u
+ 9, v
+ 9);
1564 XSetForeground(scr
->display
, scr
->copyGC
, color
);
1566 if ((u
== 2) && (v
== 2)) /* (2,2) is center pixel (unmagn.) */
1567 panel
->magnifyGlass
->color
= ulongToRColor(scr
, color
);
1569 /* The center square must eventually be centered around the
1570 * hotspot. The image needs shifting to achieve this. The amount of
1571 * shifting is (Cursor_mask_width/2 - 2 * square_size) = 11-10 = 1
1574 * ^------- center of center square == Cursor_x_hot
1576 XFillRectangle(scr
->display
, panel
->magnifyGlass
->magPix
,
1578 u
* 5 + (u
== 0 ? 0 : -1), v
* 5 + (v
== 0 ? 0 : -1),
1579 (u
== 0 ? 4 : 5), (v
== 0 ? 4 : 5));
1584 return panel
->magnifyGlass
->magPix
;
1586 pixmap
= XCreatePixmap(scr
->display
, W_DRAWABLE(scr
), Cursor_mask_width
, Cursor_mask_height
, scr
->depth
);
1590 XPutImage(scr
->display
, pixmap
, scr
->copyGC
, panel
->magnifyGlass
->image
,
1591 0, 0, 0, 0, Cursor_mask_width
, Cursor_mask_height
);
1593 /* Copy the magnified pixmap, with the clip mask, to background pixmap */
1594 XCopyArea(scr
->display
, panel
->magnifyGlass
->magPix
, pixmap
,
1595 scr
->clipGC
, 0, 0, Cursor_mask_width
, Cursor_mask_height
, 0, 0);
1596 /* (2,2) puts center pixel on center of glass */
1603 static WMView
*magnifyCreateView(W_ColorPanel
* panel
)
1605 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1608 magView
= W_CreateTopView(scr
);
1612 magView
->self
= panel
->win
;
1613 magView
->flags
.topLevel
= 1;
1614 magView
->attribFlags
|= CWOverrideRedirect
| CWSaveUnder
;
1615 magView
->attribs
.override_redirect
= True
;
1616 magView
->attribs
.save_under
= True
;
1618 W_ResizeView(magView
, Cursor_mask_width
, Cursor_mask_height
);
1620 W_RealizeView(magView
);
1625 static Cursor
magnifyGrabPointer(W_ColorPanel
* panel
)
1627 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1628 Pixmap magPixmap
, magPixmap2
;
1630 XColor fgColor
= { 0, 0, 0, 0, DoRed
| DoGreen
| DoBlue
, 0 };
1631 XColor bgColor
= { 0, 0xbf00, 0xa000, 0x5000, DoRed
| DoGreen
| DoBlue
, 0 };
1633 /* Cursor creation stuff */
1634 magPixmap
= XCreatePixmapFromBitmapData(scr
->display
, W_DRAWABLE(scr
),
1635 (char *)Cursor_bits
, Cursor_width
, Cursor_height
, 1, 0, 1);
1636 magPixmap2
= XCreatePixmapFromBitmapData(scr
->display
, W_DRAWABLE(scr
),
1637 (char *)Cursor_shape_bits
, Cursor_width
, Cursor_height
, 1, 0, 1);
1639 magCursor
= XCreatePixmapCursor(scr
->display
, magPixmap
, magPixmap2
,
1640 &fgColor
, &bgColor
, Cursor_x_hot
, Cursor_y_hot
);
1642 XFreePixmap(scr
->display
, magPixmap
);
1643 XFreePixmap(scr
->display
, magPixmap2
);
1645 XRecolorCursor(scr
->display
, magCursor
, &fgColor
, &bgColor
);
1647 /* Set up Pointer */
1648 XGrabPointer(scr
->display
, panel
->magnifyGlass
->view
->window
, True
,
1649 PointerMotionMask
| ButtonPressMask
,
1650 GrabModeAsync
, GrabModeAsync
, scr
->rootWin
, magCursor
, CurrentTime
);
1655 static WMPoint
magnifyInitialize(W_ColorPanel
* panel
)
1657 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1660 Pixmap pixmap
, clip_mask
;
1662 Window root_return
, child_return
;
1664 clip_mask
= XCreatePixmapFromBitmapData(scr
->display
, W_DRAWABLE(scr
),
1665 (char *)Cursor_mask_bits
, Cursor_mask_width
, Cursor_mask_height
,
1667 panel
->magnifyGlass
->magPix
= XCreatePixmap(scr
->display
, W_DRAWABLE(scr
),
1668 5 * 5 - 1, 5 * 5 - 1, scr
->depth
);
1670 XQueryPointer(scr
->display
, scr
->rootWin
, &root_return
, &child_return
, &x
, &y
, &u
, &v
, &mask
);
1672 panel
->magnifyGlass
->image
= NULL
;
1674 /* Clipmask to make magnified view-contents circular */
1676 XShapeCombineMask(scr
->display
, WMViewXID(panel
->magnifyGlass
->view
),
1677 ShapeBounding
, 0, 0, clip_mask
, ShapeSet
);
1679 /* Clip circle in glass cursor */
1680 XSetClipMask(scr
->display
, scr
->clipGC
, clip_mask
);
1681 XSetClipOrigin(scr
->display
, scr
->clipGC
, 0, 0);
1684 XFreePixmap(scr
->display
, clip_mask
);
1686 /* Draw initial magnifying glass contents */
1687 magnifyGetImageStored(panel
, x
, y
, x
, y
);
1689 pixmap
= magnifyCreatePixmap(panel
);
1690 XSetWindowBackgroundPixmap(scr
->display
, WMViewXID(panel
->magnifyGlass
->view
), pixmap
);
1691 XClearWindow(scr
->display
, WMViewXID(panel
->magnifyGlass
->view
));
1692 XFlush(scr
->display
);
1695 XFreePixmap(scr
->display
, pixmap
);
1704 static void magnifyPutCursor(WMWidget
* w
, void *data
)
1706 W_ColorPanel
*panel
= (W_ColorPanel
*) (data
);
1707 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1711 WMPoint initialPosition
;
1713 /* Parameter not used, but tell the compiler that it is ok */
1716 /* Destroy wheelBackImg, so it'll update properly */
1717 if (panel
->selectionBackImg
) {
1718 XFreePixmap(WMWidgetScreen(panel
->win
)->display
, panel
->selectionBackImg
);
1719 panel
->selectionBackImg
= None
;
1722 /* Create magnifying glass */
1723 panel
->magnifyGlass
= wmalloc(sizeof(MovingView
));
1724 panel
->magnifyGlass
->view
= magnifyCreateView(panel
);
1725 if (!panel
->magnifyGlass
->view
)
1728 initialPosition
= magnifyInitialize(panel
);
1729 panel
->magnifyGlass
->x
= initialPosition
.x
;
1730 panel
->magnifyGlass
->y
= initialPosition
.y
;
1732 W_MoveView(panel
->magnifyGlass
->view
,
1733 panel
->magnifyGlass
->x
- Cursor_x_hot
, panel
->magnifyGlass
->y
- Cursor_y_hot
);
1734 W_MapView(panel
->magnifyGlass
->view
);
1736 magCursor
= magnifyGrabPointer(panel
);
1738 while (panel
->magnifyGlass
->image
) {
1739 WMNextEvent(scr
->display
, &event
);
1741 /* Pack motion events */
1742 while (XCheckTypedEvent(scr
->display
, MotionNotify
, &event
)) {
1745 switch (event
.type
) {
1747 XDestroyImage(panel
->magnifyGlass
->image
);
1748 panel
->magnifyGlass
->image
= NULL
;
1750 if (event
.xbutton
.button
== Button1
) {
1751 panel
->color
.rgb
= panel
->magnifyGlass
->color
;
1752 panel
->color
.set
= cpRGB
;
1753 updateSwatch(panel
, panel
->color
);
1755 switch (panel
->mode
) {
1756 case WMWheelModeColorPanel
:
1761 case WMGrayModeColorPanel
:
1764 case WMRGBModeColorPanel
:
1767 case WMCMYKModeColorPanel
:
1770 case WMHSBModeColorPanel
:
1776 panel
->lastChanged
= panel
->mode
;
1778 WMSetButtonSelected(panel
->magnifyBtn
, False
);
1782 while (XPending(event
.xmotion
.display
)) {
1784 XPeekEvent(event
.xmotion
.display
, &ev
);
1785 if (ev
.type
== MotionNotify
)
1786 XNextEvent(event
.xmotion
.display
, &event
);
1791 /* Get a "dirty rectangle" */
1792 magnifyGetImageStored(panel
,
1793 panel
->magnifyGlass
->x
, panel
->magnifyGlass
->y
,
1794 event
.xmotion
.x_root
, event
.xmotion
.y_root
);
1796 /* Update coordinates */
1797 panel
->magnifyGlass
->x
= event
.xmotion
.x_root
;
1798 panel
->magnifyGlass
->y
= event
.xmotion
.y_root
;
1801 W_MoveView(panel
->magnifyGlass
->view
,
1802 panel
->magnifyGlass
->x
- Cursor_x_hot
, panel
->magnifyGlass
->y
- Cursor_y_hot
);
1804 /* Put new image (with magn.) in view */
1805 pixmap
= magnifyCreatePixmap(panel
);
1806 if (pixmap
!= None
) {
1807 /* Change the window background */
1808 XSetWindowBackgroundPixmap(scr
->display
,
1809 WMViewXID(panel
->magnifyGlass
->view
), pixmap
);
1810 /* Force an Expose (handled by X) */
1811 XClearWindow(scr
->display
, WMViewXID(panel
->magnifyGlass
->view
));
1812 /* Synchronize the event queue, so the Expose is handled NOW */
1813 XFlush(scr
->display
);
1815 XFreePixmap(scr
->display
, pixmap
);
1820 /* Try XQueryPointer for this !!! It returns windows that the pointer
1821 * is over. Note: We found this solving the invisible donkey cap bug
1823 #if 0 /* As it is impossible to make this work in all cases,
1824 * we consider it confusing. Therefore we disabled it.
1826 case FocusOut
: /* fall through */
1829 * Color Panel window (panel->win) lost or received focus.
1830 * We need to update the pixmap in the magnifying glass.
1832 * BUG Doesn't work with focus switches between two windows
1833 * if none of them is the color panel.
1835 XUngrabPointer(scr
->display
, CurrentTime
);
1836 W_UnmapView(panel
->magnifyGlass
->view
);
1838 magnifyInitialize(panel
);
1840 W_MapView(panel
->magnifyGlass
->view
);
1841 XGrabPointer(scr
->display
, panel
->magnifyGlass
->view
->window
,
1842 True
, PointerMotionMask
| ButtonPressMask
,
1843 GrabModeAsync
, GrabModeAsync
, scr
->rootWin
, magCursor
, CurrentTime
);
1847 WMHandleEvent(&event
);
1852 XUngrabPointer(scr
->display
, CurrentTime
);
1853 XFreeCursor(scr
->display
, magCursor
);
1855 XFreePixmap(scr
->display
, panel
->magnifyGlass
->magPix
);
1856 panel
->magnifyGlass
->magPix
= None
;
1858 W_UnmapView(panel
->magnifyGlass
->view
);
1859 W_DestroyView(panel
->magnifyGlass
->view
);
1860 panel
->magnifyGlass
->view
= NULL
;
1862 wfree(panel
->magnifyGlass
);
1865 /****************** ColorWheel Functions ************************/
1867 static wheelMatrix
*wheelCreateMatrix(unsigned int width
, unsigned int height
)
1869 wheelMatrix
*matrix
= NULL
;
1872 assert((width
> 0) && (height
> 0));
1874 matrix
= wmalloc(sizeof(wheelMatrix
));
1875 matrix
->width
= width
;
1876 matrix
->height
= height
;
1878 for (i
= 0; i
< 3; i
++) {
1879 matrix
->data
[i
] = wmalloc(width
* height
* sizeof(unsigned char));
1885 static void wheelDestroyMatrix(wheelMatrix
* matrix
)
1892 for (i
= 0; i
< 3; i
++) {
1893 if (matrix
->data
[i
])
1894 wfree(matrix
->data
[i
]);
1899 static void wheelInitMatrix(W_ColorPanel
* panel
)
1903 unsigned char *rp
, *gp
, *bp
;
1909 const int cw_halfsize
= (colorWheelSize
+ 4) / 2,
1910 cw_sqsize
= (colorWheelSize
+ 4) * (colorWheelSize
+ 4), uchar_shift
= getShift(sizeof(unsigned char));
1912 if (!panel
->wheelMtrx
)
1915 cpColor
.hsv
.value
= 255;
1916 cpColor
.set
= cpHSV
;
1919 ofs
[1] = -(colorWheelSize
+ 4);
1921 /* offsets are counterclockwise (in triangles).
1924 * _______________________________________
1925 * [1] |_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_| o
1926 * s |_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_| f
1927 * f |_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_| s
1928 * o | | | | | | | | | | | | | | | | | | | | | [3]
1932 * |\ /| <-- triangles
1938 for (y
= 0; y
< cw_halfsize
; y
++) {
1939 for (x
= y
; x
< (colorWheelSize
+ 4 - y
); x
++) {
1940 /* (xcor, ycor) is (x,y) relative to center of matrix */
1941 xcor
= 2 * x
- 4 - colorWheelSize
;
1942 ycor
= 2 * y
- 4 - colorWheelSize
;
1944 /* RColor.saturation is unsigned char and will wrap after 255 */
1945 sat
= rint(255.0 * sqrt(xcor
* xcor
+ ycor
* ycor
) / colorWheelSize
);
1947 cpColor
.hsv
.saturation
= (unsigned char)sat
;
1949 ofs
[0]++; /* top quarter of matrix */
1950 ofs
[1] += colorWheelSize
+ 4; /* left quarter */
1951 ofs
[2] = cw_sqsize
- 1 - ofs
[0]; /* bottom quarter */
1952 ofs
[3] = cw_sqsize
- 1 - ofs
[1]; /* right quarter */
1956 dhue
[0] = rint(atan((double)ycor
/ (double)xcor
) *
1957 (180.0 / M_PI
)) + (xcor
< 0 ? 180.0 : 0.0);
1961 dhue
[0] = 360 - dhue
[0]; /* Reverse direction of ColorWheel */
1962 dhue
[1] = 270 - dhue
[0] + (dhue
[0] > 270 ? 360 : 0);
1963 dhue
[2] = dhue
[0] - 180 + (dhue
[0] < 180 ? 360 : 0);
1964 dhue
[3] = 90 - dhue
[0] + (dhue
[0] > 90 ? 360 : 0);
1966 for (i
= 0; i
< 4; i
++) {
1967 rp
= panel
->wheelMtrx
->data
[0] + (ofs
[i
] << uchar_shift
);
1968 gp
= panel
->wheelMtrx
->data
[1] + (ofs
[i
] << uchar_shift
);
1969 bp
= panel
->wheelMtrx
->data
[2] + (ofs
[i
] << uchar_shift
);
1971 cpColor
.hsv
.hue
= dhue
[i
];
1972 convertCPColor(&cpColor
);
1974 *rp
= (unsigned char)(cpColor
.rgb
.red
);
1975 *gp
= (unsigned char)(cpColor
.rgb
.green
);
1976 *bp
= (unsigned char)(cpColor
.rgb
.blue
);
1979 for (i
= 0; i
< 4; i
++) {
1980 rp
= panel
->wheelMtrx
->data
[0] + (ofs
[i
] << uchar_shift
);
1981 gp
= panel
->wheelMtrx
->data
[1] + (ofs
[i
] << uchar_shift
);
1982 bp
= panel
->wheelMtrx
->data
[2] + (ofs
[i
] << uchar_shift
);
1984 *rp
= (unsigned char)0;
1985 *gp
= (unsigned char)0;
1986 *bp
= (unsigned char)0;
1991 ofs
[0] += 2 * y
+ 1;
1992 ofs
[1] += 1 - (colorWheelSize
+ 4) * (colorWheelSize
+ 4 - 1 - 2 * y
);
1996 static void wheelCalculateValues(W_ColorPanel
* panel
, int maxvalue
)
2001 for (i
= 0; i
< 256; i
++) {
2002 /* We divide by 128 in advance, and check whether that number divides
2003 * by 2 properly. If not, we add one to round the number correctly
2005 v
= (i
* maxvalue
) >> 7;
2006 panel
->wheelMtrx
->values
[i
] = (unsigned char)((v
>> 1) + (v
& 0x01));
2010 static void wheelRender(W_ColorPanel
* panel
)
2012 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2017 unsigned long ofs
= 0;
2018 /*unsigned char shift = getShift(sizeof(unsigned char)); */
2020 image
= RCreateImage(colorWheelSize
+ 4, colorWheelSize
+ 4, True
);
2022 wwarning(_("Color Panel: Could not allocate memory"));
2028 /* TODO Make this transparent istead of gray */
2029 gray
.red
= gray
.blue
= 0xae;
2032 for (y
= 0; y
< colorWheelSize
+ 4; y
++) {
2033 for (x
= 0; x
< colorWheelSize
+ 4; x
++) {
2034 if (wheelInsideColorWheel(panel
, ofs
)) {
2036 (unsigned char)(panel
->wheelMtrx
->values
[panel
->wheelMtrx
->data
[0][ofs
]]);
2038 (unsigned char)(panel
->wheelMtrx
->values
[panel
->wheelMtrx
->data
[1][ofs
]]);
2040 (unsigned char)(panel
->wheelMtrx
->values
[panel
->wheelMtrx
->data
[2][ofs
]]);
2043 *(ptr
++) = (unsigned char)(gray
.red
);
2044 *(ptr
++) = (unsigned char)(gray
.green
);
2045 *(ptr
++) = (unsigned char)(gray
.blue
);
2052 if (panel
->wheelImg
)
2053 XFreePixmap(scr
->display
, panel
->wheelImg
);
2055 RConvertImage(scr
->rcontext
, image
, &panel
->wheelImg
);
2056 RReleaseImage(image
);
2058 /* Check if backimage exists. If it doesn't, allocate and fill it */
2059 if (!panel
->selectionBackImg
) {
2060 panel
->selectionBackImg
= XCreatePixmap(scr
->display
,
2061 W_VIEW(panel
->wheelFrm
)->window
, 4, 4, scr
->depth
);
2062 XCopyArea(scr
->display
, panel
->wheelImg
, panel
->selectionBackImg
,
2063 scr
->copyGC
, panel
->colx
- 2, panel
->coly
- 2, 4, 4, 0, 0);
2064 /* -2 is hot spot correction */
2068 static Bool
wheelInsideColorWheel(W_ColorPanel
* panel
, unsigned long ofs
)
2070 return ((panel
->wheelMtrx
->data
[0][ofs
] != 0) &&
2071 (panel
->wheelMtrx
->data
[1][ofs
] != 0) && (panel
->wheelMtrx
->data
[2][ofs
] != 0));
2074 static void wheelPaint(W_ColorPanel
* panel
)
2076 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2078 XCopyArea(scr
->display
, panel
->wheelImg
, panel
->wheelView
->window
,
2079 scr
->copyGC
, 0, 0, colorWheelSize
+ 4, colorWheelSize
+ 4, 0, 0);
2081 /* Draw selection image */
2082 XCopyArea(scr
->display
, panel
->selectionImg
, panel
->wheelView
->window
,
2083 scr
->copyGC
, 0, 0, 4, 4, panel
->colx
- 2, panel
->coly
- 2);
2086 static void wheelHandleEvents(XEvent
* event
, void *data
)
2088 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
2090 switch (event
->type
) {
2092 if (event
->xexpose
.count
!= 0) /* TODO Improve */
2099 static void wheelHandleActionEvents(XEvent
* event
, void *data
)
2101 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
2103 switch (event
->type
) {
2105 if (getPickerPart(panel
, event
->xbutton
.x
, event
->xbutton
.y
) == COLORWHEEL_PART
) {
2107 panel
->lastChanged
= WMWheelModeColorPanel
;
2108 panel
->flags
.dragging
= 1;
2110 wheelPositionSelection(panel
, event
->xbutton
.x
, event
->xbutton
.y
);
2115 panel
->flags
.dragging
= 0;
2116 if (!panel
->flags
.continuous
) {
2118 (*panel
->action
) (panel
, panel
->clientData
);
2123 if (panel
->flags
.dragging
) {
2124 if (getPickerPart(panel
, event
->xmotion
.x
, event
->xmotion
.y
) == COLORWHEEL_PART
) {
2125 wheelPositionSelection(panel
, event
->xmotion
.x
, event
->xmotion
.y
);
2127 wheelPositionSelectionOutBounds(panel
, event
->xmotion
.x
, event
->xmotion
.y
);
2133 static int getPickerPart(W_ColorPanel
* panel
, int x
, int y
)
2141 if (panel
->mode
== WMWheelModeColorPanel
) {
2142 if ((lx
>= 2) && (lx
<= 2 + colorWheelSize
) && (ly
>= 2) && (ly
<= 2 + colorWheelSize
)) {
2144 ofs
= ly
* panel
->wheelMtrx
->width
+ lx
;
2146 if (wheelInsideColorWheel(panel
, ofs
))
2147 return COLORWHEEL_PART
;
2151 if (panel
->mode
== WMCustomPaletteModeColorPanel
) {
2152 if ((lx
>= 2) && (lx
< customPaletteWidth
- 2) && (ly
>= 2) && (ly
< customPaletteHeight
- 2)) {
2153 return CUSTOMPALETTE_PART
;
2160 static void wheelBrightnessSliderCallback(WMWidget
* w
, void *data
)
2164 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
2166 /* Parameter not used, but tell the compiler that it is ok */
2169 value
= 255 - WMGetSliderValue(panel
->wheelBrightnessS
);
2171 wheelCalculateValues(panel
, value
);
2173 if (panel
->color
.set
== cpRGB
) {
2174 convertCPColor(&panel
->color
);
2175 panel
->color
.set
= cpHSV
;
2178 panel
->color
.hsv
.value
= value
;
2182 wheelUpdateSelection(panel
);
2185 static void wheelUpdateSelection(W_ColorPanel
* panel
)
2187 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2189 updateSwatch(panel
, panel
->color
);
2190 panel
->lastChanged
= WMWheelModeColorPanel
;
2192 /* Redraw color selector (and make a backup of the part it will cover) */
2193 XCopyArea(scr
->display
, panel
->wheelImg
, panel
->selectionBackImg
,
2194 scr
->copyGC
, panel
->colx
- 2, panel
->coly
- 2, 4, 4, 0, 0);
2195 /* "-2" is correction for hotspot location */
2196 XCopyArea(scr
->display
, panel
->selectionImg
, panel
->wheelView
->window
,
2197 scr
->copyGC
, 0, 0, 4, 4, panel
->colx
- 2, panel
->coly
- 2);
2201 static void wheelUndrawSelection(W_ColorPanel
* panel
)
2203 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2205 XCopyArea(scr
->display
, panel
->selectionBackImg
, panel
->wheelView
->window
,
2206 scr
->copyGC
, 0, 0, 4, 4, panel
->colx
- 2, panel
->coly
- 2);
2210 static void wheelPositionSelection(W_ColorPanel
* panel
, int x
, int y
)
2212 unsigned long ofs
= (y
* panel
->wheelMtrx
->width
) + x
;
2214 panel
->color
.rgb
.red
= panel
->wheelMtrx
->values
[panel
->wheelMtrx
->data
[0][ofs
]];
2216 panel
->color
.rgb
.green
= panel
->wheelMtrx
->values
[panel
->wheelMtrx
->data
[1][ofs
]];
2218 panel
->color
.rgb
.blue
= panel
->wheelMtrx
->values
[panel
->wheelMtrx
->data
[2][ofs
]];
2219 panel
->color
.set
= cpRGB
;
2221 wheelUndrawSelection(panel
);
2226 wheelUpdateSelection(panel
);
2227 wheelUpdateBrightnessGradientFromLocation(panel
);
2230 static void wheelPositionSelectionOutBounds(W_ColorPanel
* panel
, int x
, int y
)
2236 xcor
= x
* 2 - colorWheelSize
- 4;
2237 ycor
= y
* 2 - colorWheelSize
- 4;
2239 panel
->color
.hsv
.saturation
= 255;
2240 panel
->color
.hsv
.value
= 255 - WMGetSliderValue(panel
->wheelBrightnessS
);
2243 hue
= rint(atan(-(double)ycor
/ (double)xcor
) * (180.0 / M_PI
));
2254 if ((xcor
> 0) && (ycor
> 0))
2257 panel
->color
.hsv
.hue
= hue
;
2258 panel
->color
.set
= cpHSV
;
2259 convertCPColor(&panel
->color
);
2261 wheelUndrawSelection(panel
);
2263 panel
->colx
= 2 + rint((colorWheelSize
* (1.0 + cos(panel
->color
.hsv
.hue
* (M_PI
/ 180.0)))) / 2.0);
2264 /* "+2" because of "colorWheelSize + 4" */
2265 panel
->coly
= 2 + rint((colorWheelSize
* (1.0 + sin(-panel
->color
.hsv
.hue
* (M_PI
/ 180.0)))) / 2.0);
2267 wheelUpdateSelection(panel
);
2268 cpColor
= panel
->color
;
2269 wheelUpdateBrightnessGradient(panel
, cpColor
);
2272 static void wheelUpdateBrightnessGradientFromLocation(W_ColorPanel
* panel
)
2277 ofs
= panel
->coly
* panel
->wheelMtrx
->width
+ panel
->colx
;
2279 from
.rgb
.red
= panel
->wheelMtrx
->data
[0][ofs
];
2280 from
.rgb
.green
= panel
->wheelMtrx
->data
[1][ofs
];
2281 from
.rgb
.blue
= panel
->wheelMtrx
->data
[2][ofs
];
2284 wheelUpdateBrightnessGradient(panel
, from
);
2287 static void wheelUpdateBrightnessGradient(W_ColorPanel
* panel
, CPColor topColor
)
2291 WMPixmap
*sliderPxmp
;
2293 to
.red
= to
.green
= to
.blue
= 0;
2295 if (topColor
.set
== cpHSV
)
2296 convertCPColor(&topColor
);
2298 sliderImg
= RRenderGradient(16, 153, &(topColor
.rgb
), &to
, RGRD_VERTICAL
);
2299 sliderPxmp
= WMCreatePixmapFromRImage(WMWidgetScreen(panel
->win
), sliderImg
, 0);
2300 RReleaseImage(sliderImg
);
2301 WMSetSliderImage(panel
->wheelBrightnessS
, sliderPxmp
);
2302 WMReleasePixmap(sliderPxmp
);
2305 /****************** Grayscale Panel Functions ***************/
2307 static void grayBrightnessSliderCallback(WMWidget
* w
, void *data
)
2312 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
2314 /* Parameter not used, but tell the compiler that it is ok */
2317 value
= WMGetSliderValue(panel
->grayBrightnessS
);
2319 sprintf(tmp
, "%d", value
);
2321 WMSetTextFieldText(panel
->grayBrightnessT
, tmp
);
2322 cpColor
.rgb
.red
= cpColor
.rgb
.green
= cpColor
.rgb
.blue
= rint(2.55 * value
);
2323 cpColor
.set
= cpRGB
;
2325 updateSwatch(panel
, cpColor
);
2326 panel
->lastChanged
= WMGrayModeColorPanel
;
2329 static void grayPresetButtonCallback(WMWidget
* w
, void *data
)
2335 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
2338 if (w
== panel
->grayPresetBtn
[i
])
2343 value
= rint((100.0 * i
) / 6.0);
2344 sprintf(tmp
, "%d", value
);
2346 WMSetTextFieldText(panel
->grayBrightnessT
, tmp
);
2347 cpColor
.rgb
.red
= cpColor
.rgb
.green
= cpColor
.rgb
.blue
= rint((255.0 * i
) / 6.0);
2348 cpColor
.set
= cpRGB
;
2350 WMSetSliderValue(panel
->grayBrightnessS
, rint((100.0 * i
) / 6.0));
2352 updateSwatch(panel
, cpColor
);
2353 panel
->lastChanged
= WMGrayModeColorPanel
;
2356 static void grayBrightnessTextFieldCallback(void *observerData
, WMNotification
* notification
)
2361 W_ColorPanel
*panel
= (W_ColorPanel
*) observerData
;
2363 /* Parameter not used, but tell the compiler that it is ok */
2364 (void) notification
;
2366 value
= get_textfield_as_integer(panel
->grayBrightnessT
);
2372 sprintf(tmp
, "%d", value
);
2373 WMSetTextFieldText(panel
->grayBrightnessT
, tmp
);
2374 WMSetSliderValue(panel
->grayBrightnessS
, value
);
2376 cpColor
.rgb
.red
= cpColor
.rgb
.green
= cpColor
.rgb
.blue
= rint((255.0 * value
) / 100.0);
2377 cpColor
.set
= cpRGB
;
2379 updateSwatch(panel
, cpColor
);
2380 panel
->lastChanged
= WMGrayModeColorPanel
;
2383 /******************* RGB Panel Functions *****************/
2385 void rgbIntToChar(W_ColorPanel
*panel
, int *value
)
2390 switch (panel
->rgbState
) {
2399 sprintf(tmp
, format
, value
[0]);
2400 WMSetTextFieldText(panel
->rgbRedT
, tmp
);
2401 sprintf(tmp
, format
, value
[1]);
2402 WMSetTextFieldText(panel
->rgbGreenT
, tmp
);
2403 sprintf(tmp
, format
, value
[2]);
2404 WMSetTextFieldText(panel
->rgbBlueT
, tmp
);
2407 int *rgbCharToInt(W_ColorPanel
*panel
)
2410 static int value
[3];
2413 switch (panel
->rgbState
) {
2422 str
= WMGetTextFieldText(panel
->rgbRedT
);
2423 value
[0] = strtol(str
, NULL
, base
);
2426 str
= WMGetTextFieldText(panel
->rgbGreenT
);
2427 value
[1] = strtol(str
, NULL
, base
);
2430 str
= WMGetTextFieldText(panel
->rgbBlueT
);
2431 value
[2] = strtol(str
, NULL
, base
);
2437 static void rgbSliderCallback(WMWidget
* w
, void *data
)
2441 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
2443 /* Parameter not used, but tell the compiler that it is ok */
2446 value
[0] = WMGetSliderValue(panel
->rgbRedS
);
2447 value
[1] = WMGetSliderValue(panel
->rgbGreenS
);
2448 value
[2] = WMGetSliderValue(panel
->rgbBlueS
);
2450 rgbIntToChar(panel
, value
);
2452 cpColor
.rgb
.red
= value
[0];
2453 cpColor
.rgb
.green
= value
[1];
2454 cpColor
.rgb
.blue
= value
[2];
2455 cpColor
.set
= cpRGB
;
2457 updateSwatch(panel
, cpColor
);
2458 panel
->lastChanged
= WMRGBModeColorPanel
;
2461 static void rgbTextFieldCallback(void *observerData
, WMNotification
* notification
)
2466 W_ColorPanel
*panel
= (W_ColorPanel
*) observerData
;
2468 /* Parameter not used, but tell the compiler that it is ok */
2469 (void) notification
;
2471 value
= rgbCharToInt(panel
);
2473 for (n
= 0; n
< 3; n
++) {
2480 rgbIntToChar(panel
, value
);
2482 WMSetSliderValue(panel
->rgbRedS
, value
[0]);
2483 WMSetSliderValue(panel
->rgbGreenS
, value
[1]);
2484 WMSetSliderValue(panel
->rgbBlueS
, value
[2]);
2486 cpColor
.rgb
.red
= value
[0];
2487 cpColor
.rgb
.green
= value
[1];
2488 cpColor
.rgb
.blue
= value
[2];
2489 cpColor
.set
= cpRGB
;
2491 updateSwatch(panel
, cpColor
);
2492 panel
->lastChanged
= WMRGBModeColorPanel
;
2495 static void rgbDecToHex(WMWidget
*w
, void *data
)
2497 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
2502 switch (panel
->rgbState
) {
2504 if (WMGetButtonSelected(panel
->rgbDecB
)) {
2505 WMSetLabelText(panel
->rgbMaxL
, "255");
2506 WMRedisplayWidget(panel
->rgbMaxL
);
2507 value
= rgbCharToInt(panel
);
2508 panel
->rgbState
= RGBdec
;
2509 rgbIntToChar(panel
, value
);
2514 if (WMGetButtonSelected(panel
->rgbHexB
)) {
2515 WMSetLabelText(panel
->rgbMaxL
, "FF");
2516 WMRedisplayWidget(panel
->rgbMaxL
);
2517 value
= rgbCharToInt(panel
);
2518 panel
->rgbState
= RGBhex
;
2519 rgbIntToChar(panel
, value
);
2525 /******************* CMYK Panel Functions *****************/
2527 static void cmykSliderCallback(WMWidget
* w
, void *data
)
2532 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
2535 /* Parameter not used, but tell the compiler that it is ok */
2538 value
[0] = WMGetSliderValue(panel
->cmykCyanS
);
2539 value
[1] = WMGetSliderValue(panel
->cmykMagentaS
);
2540 value
[2] = WMGetSliderValue(panel
->cmykYellowS
);
2541 value
[3] = WMGetSliderValue(panel
->cmykBlackS
);
2543 sprintf(tmp
, "%d", value
[0]);
2544 WMSetTextFieldText(panel
->cmykCyanT
, tmp
);
2545 sprintf(tmp
, "%d", value
[1]);
2546 WMSetTextFieldText(panel
->cmykMagentaT
, tmp
);
2547 sprintf(tmp
, "%d", value
[2]);
2548 WMSetTextFieldText(panel
->cmykYellowT
, tmp
);
2549 sprintf(tmp
, "%d", value
[3]);
2550 WMSetTextFieldText(panel
->cmykBlackT
, tmp
);
2552 scale
= 2.55 * (1.0 - (value
[3] / 100.0));
2553 cpColor
.rgb
.red
= rint((100.0 - value
[0]) * scale
);
2554 cpColor
.rgb
.green
= rint((100.0 - value
[1]) * scale
);
2555 cpColor
.rgb
.blue
= rint((100.0 - value
[2]) * scale
);
2556 cpColor
.set
= cpRGB
;
2558 updateSwatch(panel
, cpColor
);
2559 panel
->lastChanged
= WMCMYKModeColorPanel
;
2562 static void cmykTextFieldCallback(void *observerData
, WMNotification
* notification
)
2569 W_ColorPanel
*panel
= (W_ColorPanel
*) observerData
;
2571 /* Parameter not used, but tell the compiler that it is ok */
2572 (void) notification
;
2574 value
[0] = get_textfield_as_integer(panel
->cmykCyanT
);
2575 value
[1] = get_textfield_as_integer(panel
->cmykMagentaT
);
2576 value
[2] = get_textfield_as_integer(panel
->cmykYellowT
);
2577 value
[3] = get_textfield_as_integer(panel
->cmykBlackT
);
2579 for (n
= 0; n
< 4; n
++) {
2586 sprintf(tmp
, "%d", value
[0]);
2587 WMSetTextFieldText(panel
->cmykCyanT
, tmp
);
2589 sprintf(tmp
, "%d", value
[1]);
2590 WMSetTextFieldText(panel
->cmykMagentaT
, tmp
);
2592 sprintf(tmp
, "%d", value
[2]);
2593 WMSetTextFieldText(panel
->cmykYellowT
, tmp
);
2595 sprintf(tmp
, "%d", value
[3]);
2596 WMSetTextFieldText(panel
->cmykBlackT
, tmp
);
2598 WMSetSliderValue(panel
->cmykCyanS
, value
[0]);
2599 WMSetSliderValue(panel
->cmykMagentaS
, value
[1]);
2600 WMSetSliderValue(panel
->cmykYellowS
, value
[2]);
2601 WMSetSliderValue(panel
->cmykBlackS
, value
[3]);
2603 scale
= 2.55 * (1.0 - (value
[3] / 100.0));
2604 cpColor
.rgb
.red
= rint((100.0 - value
[0]) * scale
);
2605 cpColor
.rgb
.green
= rint((100.0 - value
[1]) * scale
);
2606 cpColor
.rgb
.blue
= rint((100.0 - value
[2]) * scale
);
2607 cpColor
.set
= cpRGB
;
2609 updateSwatch(panel
, cpColor
);
2610 panel
->lastChanged
= WMCMYKModeColorPanel
;
2613 /********************** HSB Panel Functions ***********************/
2615 static void hsbSliderCallback(WMWidget
* w
, void *data
)
2620 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
2622 value
[0] = WMGetSliderValue(panel
->hsbHueS
);
2623 value
[1] = WMGetSliderValue(panel
->hsbSaturationS
);
2624 value
[2] = WMGetSliderValue(panel
->hsbBrightnessS
);
2626 sprintf(tmp
, "%d", value
[0]);
2627 WMSetTextFieldText(panel
->hsbHueT
, tmp
);
2628 sprintf(tmp
, "%d", value
[1]);
2629 WMSetTextFieldText(panel
->hsbSaturationT
, tmp
);
2630 sprintf(tmp
, "%d", value
[2]);
2631 WMSetTextFieldText(panel
->hsbBrightnessT
, tmp
);
2633 cpColor
.hsv
.hue
= value
[0];
2634 cpColor
.hsv
.saturation
= value
[1] * 2.55;
2635 cpColor
.hsv
.value
= value
[2] * 2.55;
2636 cpColor
.set
= cpHSV
;
2638 convertCPColor(&cpColor
);
2640 panel
->lastChanged
= WMHSBModeColorPanel
;
2641 updateSwatch(panel
, cpColor
);
2643 if (w
!= panel
->hsbBrightnessS
)
2644 hsbUpdateBrightnessGradient(panel
);
2645 if (w
!= panel
->hsbSaturationS
)
2646 hsbUpdateSaturationGradient(panel
);
2647 if (w
!= panel
->hsbHueS
)
2648 hsbUpdateHueGradient(panel
);
2651 static void hsbTextFieldCallback(void *observerData
, WMNotification
* notification
)
2657 W_ColorPanel
*panel
= (W_ColorPanel
*) observerData
;
2659 /* Parameter not used, but tell the compiler that it is ok */
2660 (void) notification
;
2662 value
[0] = get_textfield_as_integer(panel
->hsbHueT
);
2663 value
[1] = get_textfield_as_integer(panel
->hsbSaturationT
);
2664 value
[2] = get_textfield_as_integer(panel
->hsbBrightnessT
);
2671 for (n
= 1; n
< 3; n
++) {
2678 sprintf(tmp
, "%d", value
[0]);
2679 WMSetTextFieldText(panel
->hsbHueT
, tmp
);
2680 sprintf(tmp
, "%d", value
[1]);
2681 WMSetTextFieldText(panel
->hsbSaturationT
, tmp
);
2682 sprintf(tmp
, "%d", value
[2]);
2683 WMSetTextFieldText(panel
->hsbBrightnessT
, tmp
);
2685 WMSetSliderValue(panel
->hsbHueS
, value
[0]);
2686 WMSetSliderValue(panel
->hsbSaturationS
, value
[1]);
2687 WMSetSliderValue(panel
->hsbBrightnessS
, value
[2]);
2689 cpColor
.hsv
.hue
= value
[0];
2690 cpColor
.hsv
.saturation
= value
[1] * 2.55;
2691 cpColor
.hsv
.value
= value
[2] * 2.55;
2692 cpColor
.set
= cpHSV
;
2694 convertCPColor(&cpColor
);
2696 panel
->lastChanged
= WMHSBModeColorPanel
;
2697 updateSwatch(panel
, cpColor
);
2699 hsbUpdateBrightnessGradient(panel
);
2700 hsbUpdateSaturationGradient(panel
);
2701 hsbUpdateHueGradient(panel
);
2704 static void hsbUpdateBrightnessGradient(W_ColorPanel
* panel
)
2706 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2710 WMPixmap
*sliderPxmp
;
2712 from
.red
= from
.green
= from
.blue
= 0;
2713 to
.hsv
= panel
->color
.hsv
;
2717 convertCPColor(&to
);
2719 sliderImg
= RRenderGradient(141, 16, &from
, &(to
.rgb
), RGRD_HORIZONTAL
);
2720 sliderPxmp
= WMCreatePixmapFromRImage(scr
, sliderImg
, 0);
2721 RReleaseImage(sliderImg
);
2724 W_PaintText(W_VIEW(panel
->hsbBrightnessS
), sliderPxmp
->pixmap
,
2725 panel
->font12
, 2, 0, 100, WALeft
, scr
->white
,
2726 False
, _("Brightness"), strlen(_("Brightness")));
2728 wwarning(_("Color Panel: Could not allocate memory"));
2730 WMSetSliderImage(panel
->hsbBrightnessS
, sliderPxmp
);
2731 WMReleasePixmap(sliderPxmp
);
2734 static void hsbUpdateSaturationGradient(W_ColorPanel
* panel
)
2736 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2740 WMPixmap
*sliderPxmp
;
2742 from
.hsv
= panel
->color
.hsv
;
2743 from
.hsv
.saturation
= 0;
2745 convertCPColor(&from
);
2747 to
.hsv
= panel
->color
.hsv
;
2748 to
.hsv
.saturation
= 255;
2750 convertCPColor(&to
);
2752 sliderImg
= RRenderGradient(141, 16, &(from
.rgb
), &(to
.rgb
), RGRD_HORIZONTAL
);
2753 sliderPxmp
= WMCreatePixmapFromRImage(scr
, sliderImg
, 0);
2754 RReleaseImage(sliderImg
);
2757 W_PaintText(W_VIEW(panel
->hsbSaturationS
), sliderPxmp
->pixmap
,
2758 panel
->font12
, 2, 0, 100, WALeft
,
2759 from
.hsv
.value
< 128 ? scr
->white
: scr
->black
, False
,
2760 _("Saturation"), strlen(_("Saturation")));
2762 wwarning(_("Color Panel: Could not allocate memory"));
2764 WMSetSliderImage(panel
->hsbSaturationS
, sliderPxmp
);
2765 WMReleasePixmap(sliderPxmp
);
2768 static void hsbUpdateHueGradient(W_ColorPanel
* panel
)
2770 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2771 RColor
**colors
= NULL
;
2774 WMPixmap
*sliderPxmp
;
2777 hsvcolor
= panel
->color
.hsv
;
2779 colors
= wmalloc(sizeof(RColor
*) * (8));
2780 for (i
= 0; i
< 7; i
++) {
2781 hsvcolor
.hue
= (360 * i
) / 6;
2782 colors
[i
] = wmalloc(sizeof(RColor
));
2783 RHSVtoRGB(&hsvcolor
, colors
[i
]);
2787 sliderImg
= RRenderMultiGradient(141, 16, colors
, RGRD_HORIZONTAL
);
2788 sliderPxmp
= WMCreatePixmapFromRImage(scr
, sliderImg
, 0);
2789 RReleaseImage(sliderImg
);
2792 W_PaintText(W_VIEW(panel
->hsbHueS
), sliderPxmp
->pixmap
,
2793 panel
->font12
, 2, 0, 100, WALeft
,
2794 hsvcolor
.value
< 128 ? scr
->white
: scr
->black
, False
, _("Hue"), strlen(_("Hue")));
2796 wwarning(_("Color Panel: Could not allocate memory"));
2798 WMSetSliderImage(panel
->hsbHueS
, sliderPxmp
);
2799 WMReleasePixmap(sliderPxmp
);
2801 for (i
= 0; i
< 7; i
++)
2807 /*************** Custom Palette Functions ****************/
2809 static void customRenderSpectrum(W_ColorPanel
* panel
)
2816 spectrum
= RCreateImage(SPECTRUM_WIDTH
, SPECTRUM_HEIGHT
, False
);
2818 ptr
= spectrum
->data
;
2820 for (y
= 0; y
< SPECTRUM_HEIGHT
; y
++) {
2821 cpColor
.hsv
.hue
= y
;
2822 cpColor
.hsv
.saturation
= 0;
2823 cpColor
.hsv
.value
= 255;
2824 cpColor
.set
= cpHSV
;
2826 for (x
= 0; x
< SPECTRUM_WIDTH
; x
++) {
2827 convertCPColor(&cpColor
);
2829 *(ptr
++) = (unsigned char)cpColor
.rgb
.red
;
2830 *(ptr
++) = (unsigned char)cpColor
.rgb
.green
;
2831 *(ptr
++) = (unsigned char)cpColor
.rgb
.blue
;
2833 if (x
< (SPECTRUM_WIDTH
/ 2))
2834 cpColor
.hsv
.saturation
++;
2836 if (x
> (SPECTRUM_WIDTH
/ 2))
2837 cpColor
.hsv
.value
--;
2840 if (panel
->customPaletteImg
) {
2841 RReleaseImage(panel
->customPaletteImg
);
2842 panel
->customPaletteImg
= NULL
;
2844 panel
->customPaletteImg
= spectrum
;
2847 static void customSetPalette(W_ColorPanel
* panel
)
2849 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2853 image
= XCreatePixmap(scr
->display
, W_DRAWABLE(scr
), customPaletteWidth
, customPaletteHeight
, scr
->depth
);
2854 scaledImg
= RScaleImage(panel
->customPaletteImg
, customPaletteWidth
, customPaletteHeight
);
2855 RConvertImage(scr
->rcontext
, scaledImg
, &image
);
2856 RReleaseImage(scaledImg
);
2858 XCopyArea(scr
->display
, image
, panel
->customPaletteContentView
->window
,
2859 scr
->copyGC
, 0, 0, customPaletteWidth
, customPaletteHeight
, 0, 0);
2861 /* Check backimage exists. If it doesn't, allocate and fill it */
2862 if (!panel
->selectionBackImg
) {
2863 panel
->selectionBackImg
= XCreatePixmap(scr
->display
,
2864 panel
->customPaletteContentView
->window
, 4, 4, scr
->depth
);
2867 XCopyArea(scr
->display
, image
, panel
->selectionBackImg
, scr
->copyGC
,
2868 panel
->palx
- 2, panel
->paly
- 2, 4, 4, 0, 0);
2869 XCopyArea(scr
->display
, panel
->selectionImg
,
2870 panel
->customPaletteContentView
->window
, scr
->copyGC
, 0, 0, 4, 4,
2871 panel
->palx
- 2, panel
->paly
- 2);
2872 XFreePixmap(scr
->display
, image
);
2874 panel
->palXRatio
= (double)(panel
->customPaletteImg
->width
) / (double)(customPaletteWidth
);
2875 panel
->palYRatio
= (double)(panel
->customPaletteImg
->height
) / (double)(customPaletteHeight
);
2877 WMGetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
);
2880 static void customPalettePositionSelection(W_ColorPanel
* panel
, int x
, int y
)
2882 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2885 /* undraw selection */
2886 XCopyArea(scr
->display
, panel
->selectionBackImg
,
2887 panel
->customPaletteContentView
->window
, scr
->copyGC
, 0, 0, 4, 4,
2888 panel
->palx
- 2, panel
->paly
- 2);
2893 ofs
= (rint(x
* panel
->palXRatio
) + rint(y
* panel
->palYRatio
) * panel
->customPaletteImg
->width
) * 3;
2895 panel
->color
.rgb
.red
= panel
->customPaletteImg
->data
[ofs
];
2896 panel
->color
.rgb
.green
= panel
->customPaletteImg
->data
[ofs
+ 1];
2897 panel
->color
.rgb
.blue
= panel
->customPaletteImg
->data
[ofs
+ 2];
2898 panel
->color
.set
= cpRGB
;
2900 updateSwatch(panel
, panel
->color
);
2901 panel
->lastChanged
= WMCustomPaletteModeColorPanel
;
2903 /* Redraw color selector (and make a backup of the part it will cover) */
2904 XCopyArea(scr
->display
, panel
->customPaletteContentView
->window
, panel
->selectionBackImg
, scr
->copyGC
, panel
->palx
- 2, panel
->paly
- 2, 4, 4, 0, 0); /* "-2" is correction for hotspot location */
2905 XCopyArea(scr
->display
, panel
->selectionImg
, panel
->customPaletteContentView
->window
, scr
->copyGC
, 0, 0, 4, 4, panel
->palx
- 2, panel
->paly
- 2); /* see above */
2908 static void customPalettePositionSelectionOutBounds(W_ColorPanel
* panel
, int x
, int y
)
2914 if (x
>= customPaletteWidth
)
2915 x
= customPaletteWidth
- 2;
2916 if (y
>= customPaletteHeight
)
2917 y
= customPaletteHeight
- 2;
2919 customPalettePositionSelection(panel
, x
, y
);
2922 static void customPaletteHandleEvents(XEvent
* event
, void *data
)
2924 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
2926 switch (event
->type
) {
2928 if (event
->xexpose
.count
!= 0) /* TODO Improve. */
2930 customSetPalette(panel
);
2935 static void customPaletteHandleActionEvents(XEvent
* event
, void *data
)
2937 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
2940 switch (event
->type
) {
2942 x
= event
->xbutton
.x
;
2943 y
= event
->xbutton
.y
;
2945 if (getPickerPart(panel
, x
, y
) == CUSTOMPALETTE_PART
) {
2946 panel
->flags
.dragging
= 1;
2947 customPalettePositionSelection(panel
, x
, y
);
2952 panel
->flags
.dragging
= 0;
2953 if (!panel
->flags
.continuous
) {
2955 (*panel
->action
) (panel
, panel
->clientData
);
2960 x
= event
->xmotion
.x
;
2961 y
= event
->xmotion
.y
;
2963 if (panel
->flags
.dragging
) {
2964 if (getPickerPart(panel
, x
, y
) == CUSTOMPALETTE_PART
) {
2965 customPalettePositionSelection(panel
, x
, y
);
2967 customPalettePositionSelectionOutBounds(panel
, x
, y
);
2973 static void customPaletteMenuCallback(WMWidget
* w
, void *data
)
2975 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
2976 int item
= WMGetPopUpButtonSelectedItem(panel
->customPaletteMenuBtn
);
2978 /* Parameter not used, but tell the compiler that it is ok */
2982 case CPmenuNewFromFile
:
2983 customPaletteMenuNewFromFile(panel
);
2986 customPaletteMenuRename(panel
);
2989 customPaletteMenuRemove(panel
);
2993 case CPmenuNewFromClipboard
:
2998 static void customPaletteMenuNewFromFile(W_ColorPanel
* panel
)
3000 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
3001 WMOpenPanel
*browseP
;
3003 char *filename
= NULL
;
3007 RImage
*tmpImg
= NULL
;
3009 if ((!panel
->lastBrowseDir
) || (strcmp(panel
->lastBrowseDir
, "\0") == 0))
3010 spath
= wexpandpath(wgethomedir());
3012 spath
= wexpandpath(panel
->lastBrowseDir
);
3014 browseP
= WMGetOpenPanel(scr
);
3015 WMSetFilePanelCanChooseDirectories(browseP
, 0);
3016 WMSetFilePanelCanChooseFiles(browseP
, 1);
3018 /* Get a filename */
3019 if (WMRunModalFilePanelForDirectory(browseP
, panel
->win
, spath
,
3020 _("Open Palette"), RSupportedFileFormats())) {
3021 filepath
= WMGetFilePanelFileName(browseP
);
3023 /* Get seperation position between path and filename */
3024 i
= strrchr(filepath
, '/') - filepath
+ 1;
3025 if (i
> strlen(filepath
))
3026 i
= strlen(filepath
);
3028 /* Store last browsed path */
3029 if (panel
->lastBrowseDir
)
3030 wfree(panel
->lastBrowseDir
);
3031 panel
->lastBrowseDir
= wmalloc((i
+ 1) * sizeof(char));
3032 strncpy(panel
->lastBrowseDir
, filepath
, i
);
3033 panel
->lastBrowseDir
[i
] = '\0';
3035 /* Get filename from path */
3036 filename
= wstrdup(filepath
+ i
);
3038 /* Check for duplicate files, and rename it if there are any */
3039 tmp
= wstrconcat(panel
->configurationPath
, filename
);
3040 while (access(tmp
, F_OK
) == 0) {
3045 newName
= generateNewFilename(filename
);
3049 tmp
= wstrconcat(panel
->configurationPath
, filename
);
3053 /* Copy image to $(gnustepdir)/Library/Colors/ &
3054 * Add filename to history menu */
3055 if (wcopy_file(panel
->configurationPath
, filepath
, filename
) == 0) {
3057 /* filepath is a "local" path now the file has been copied */
3059 filepath
= wstrconcat(panel
->configurationPath
, filename
);
3061 /* load the image & add menu entries */
3062 tmpImg
= RLoadImage(scr
->rcontext
, filepath
, 0);
3064 if (panel
->customPaletteImg
)
3065 RReleaseImage(panel
->customPaletteImg
);
3066 panel
->customPaletteImg
= tmpImg
;
3068 customSetPalette(panel
);
3069 WMAddPopUpButtonItem(panel
->customPaletteHistoryBtn
, filename
);
3071 panel
->currentPalette
=
3072 WMGetPopUpButtonNumberOfItems(panel
->customPaletteHistoryBtn
) - 1;
3074 WMSetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
,
3075 panel
->currentPalette
);
3078 tmp
= wstrconcat(panel
->configurationPath
, filename
);
3080 i
= remove(tmp
); /* Delete the file, it doesn't belong here */
3081 WMRunAlertPanel(scr
, panel
->win
, _("File Error"),
3082 _("Invalid file format !"), _("OK"), NULL
, NULL
);
3084 werror(_("can't remove file %s"), tmp
);
3085 WMRunAlertPanel(scr
, panel
->win
, _("File Error"),
3086 _("Couldn't remove file from Configuration Directory !"),
3087 _("OK"), NULL
, NULL
);
3094 WMFreeFilePanel(browseP
);
3099 static void customPaletteMenuRename(W_ColorPanel
* panel
)
3101 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
3102 char *toName
= NULL
;
3104 char *toPath
, *fromPath
;
3108 item
= WMGetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
);
3109 fromName
= WMGetPopUpButtonItem(panel
->customPaletteHistoryBtn
, item
);
3111 toName
= WMRunInputPanel(scr
, panel
->win
, _("Rename"), _("Rename palette to:"),
3112 fromName
, _("OK"), _("Cancel"));
3116 /* As some people do certain stupid things... */
3117 if (strcmp(toName
, fromName
) == 0) {
3122 /* For normal people */
3123 fromPath
= wstrconcat(panel
->configurationPath
, fromName
);
3124 toPath
= wstrconcat(panel
->configurationPath
, toName
);
3126 if (access(toPath
, F_OK
) == 0) {
3127 /* Careful, this palette exists already */
3128 if (WMRunAlertPanel(scr
, panel
->win
, _("Warning"),
3129 _("Palette already exists !\n\nOverwrite ?"), _("No"), _("Yes"),
3131 /* "No" = 0, "Yes" = 1 */
3132 int items
= WMGetPopUpButtonNumberOfItems(panel
->customPaletteHistoryBtn
);
3136 /* Remove from History list too */
3138 while ((index
< items
)
3140 (strcmp(WMGetPopUpButtonItem(panel
->customPaletteHistoryBtn
, index
), toName
)
3144 if (index
< items
) {
3145 WMRemovePopUpButtonItem(panel
->customPaletteHistoryBtn
, index
);
3159 if (rename(fromPath
, toPath
) != 0)
3160 werror(_("Couldn't rename palette %s to %s"), fromName
, toName
);
3162 WMRemovePopUpButtonItem(panel
->customPaletteHistoryBtn
, item
);
3163 WMInsertPopUpButtonItem(panel
->customPaletteHistoryBtn
, item
, toName
);
3165 WMSetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
, item
);
3173 static void customPaletteMenuRemove(W_ColorPanel
* panel
)
3175 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
3181 item
= WMGetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
);
3183 tmp
= wstrconcat(_("This will permanently remove the palette "),
3184 WMGetPopUpButtonItem(panel
->customPaletteHistoryBtn
, item
));
3185 text
= wstrconcat(tmp
, _(".\n\nAre you sure you want to remove this palette ?"));
3188 choice
= WMRunAlertPanel(scr
, panel
->win
, _("Remove"), text
, _("Yes"), _("No"), NULL
);
3189 /* returns 0 (= "Yes") or 1 (="No") */
3194 tmp
= wstrconcat(panel
->configurationPath
,
3195 WMGetPopUpButtonItem(panel
->customPaletteHistoryBtn
, item
));
3197 if (remove(tmp
) == 0) {
3198 /* item-1 always exists */
3199 WMSetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
, item
- 1);
3201 customPaletteHistoryCallback(panel
->customPaletteHistoryBtn
, panel
);
3202 customSetPalette(panel
);
3204 WMRemovePopUpButtonItem(panel
->customPaletteHistoryBtn
, item
);
3207 werror(_("Couldn't remove palette %s"), tmp
);
3214 static void customPaletteHistoryCallback(WMWidget
* w
, void *data
)
3216 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
3217 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
3221 unsigned char perm_mask
;
3223 item
= WMGetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
);
3224 if (item
== panel
->currentPalette
)
3228 customRenderSpectrum(panel
);
3230 WMSetPopUpButtonItemEnabled(panel
->customPaletteMenuBtn
, CPmenuRename
, False
);
3231 WMSetPopUpButtonItemEnabled(panel
->customPaletteMenuBtn
, CPmenuRemove
, False
);
3233 /* Load file from configpath */
3234 filename
= wstrconcat(panel
->configurationPath
,
3235 WMGetPopUpButtonItem(panel
->customPaletteHistoryBtn
, item
));
3237 /* If the file corresponding to the item does not exist,
3238 * remove it from the history list and select the next one.
3240 perm_mask
= (access(filename
, F_OK
) == 0);
3242 /* File does not exist */
3244 WMSetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
, item
- 1);
3245 WMRemovePopUpButtonItem(panel
->customPaletteHistoryBtn
, item
);
3246 customPaletteHistoryCallback(w
, data
);
3251 tmp
= RLoadImage(scr
->rcontext
, filename
, 0);
3253 if (panel
->customPaletteImg
) {
3254 RReleaseImage(panel
->customPaletteImg
);
3255 panel
->customPaletteImg
= NULL
;
3257 panel
->customPaletteImg
= tmp
;
3260 /* If the image is not writable, don't allow removing/renaming */
3261 perm_mask
= (access(filename
, W_OK
) == 0);
3262 WMSetPopUpButtonItemEnabled(panel
->customPaletteMenuBtn
, CPmenuRename
, perm_mask
);
3263 WMSetPopUpButtonItemEnabled(panel
->customPaletteMenuBtn
, CPmenuRemove
, perm_mask
);
3267 customSetPalette(panel
);
3269 panel
->currentPalette
= item
;
3272 /************************* ColorList Panel Functions **********************/
3274 static void colorListPaintItem(WMList
* lPtr
, int index
, Drawable d
, char *text
, int state
, WMRect
* rect
)
3276 WMScreen
*scr
= WMWidgetScreen(lPtr
);
3277 Display
*dpy
= WMScreenDisplay(scr
);
3278 WMView
*view
= W_VIEW(lPtr
);
3279 RColor
*color
= (RColor
*) WMGetListItem(lPtr
, index
)->clientData
;
3280 W_ColorPanel
*panel
= WMGetHangedData(lPtr
);
3281 int width
, height
, x
, y
;
3284 width
= rect
->size
.width
;
3285 height
= rect
->size
.height
;
3289 if (state
& WLDSSelected
)
3290 XFillRectangle(dpy
, d
, WMColorGC(scr
->white
), x
, y
, width
, height
);
3292 XFillRectangle(dpy
, d
, WMColorGC(view
->backColor
), x
, y
, width
, height
);
3294 fillColor
= WMCreateRGBColor(scr
, color
->red
<< 8, color
->green
<< 8, color
->blue
<< 8, True
);
3296 XFillRectangle(dpy
, d
, WMColorGC(fillColor
), x
, y
, 15, height
);
3297 WMReleaseColor(fillColor
);
3299 WMDrawString(scr
, d
, scr
->black
, panel
->font12
, x
+ 18, y
, text
, strlen(text
));
3302 static void colorListSelect(WMWidget
* w
, void *data
)
3304 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
3307 cpColor
.rgb
= *((RColor
*) WMGetListSelectedItem(w
)->clientData
);
3308 cpColor
.set
= cpRGB
;
3310 panel
->lastChanged
= WMColorListModeColorPanel
;
3311 updateSwatch(panel
, cpColor
);
3314 static void colorListColorMenuCallback(WMWidget
* w
, void *data
)
3316 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
3317 int item
= WMGetPopUpButtonSelectedItem(panel
->colorListColorMenuBtn
);
3319 /* Parameter not used, but tell the compiler that it is ok */
3332 static void colorListListMenuCallback(WMWidget
* w
, void *data
)
3334 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
3335 int item
= WMGetPopUpButtonSelectedItem(panel
->colorListListMenuBtn
);
3337 /* Parameter not used, but tell the compiler that it is ok */
3350 /*************** Panel Initialisation Functions *****************/
3352 static void wheelInit(W_ColorPanel
* panel
)
3356 if (panel
->color
.set
!= cpHSV
)
3357 convertCPColor(&panel
->color
);
3359 WMSetSliderValue(panel
->wheelBrightnessS
, 255 - panel
->color
.hsv
.value
);
3361 panel
->colx
= 2 + rint((colorWheelSize
/ 2.0) *
3362 (1 + (panel
->color
.hsv
.saturation
/ 255.0) *
3363 cos(panel
->color
.hsv
.hue
* M_PI
/ 180.0)));
3364 panel
->coly
= 2 + rint((colorWheelSize
/ 2.0) *
3365 (1 + (panel
->color
.hsv
.saturation
/ 255.0) *
3366 sin(-panel
->color
.hsv
.hue
* M_PI
/ 180.0)));
3368 wheelCalculateValues(panel
, panel
->color
.hsv
.value
);
3370 cpColor
= panel
->color
;
3371 cpColor
.hsv
.value
= 255;
3372 cpColor
.set
= cpHSV
;
3373 wheelUpdateBrightnessGradient(panel
, cpColor
);
3376 static void grayInit(W_ColorPanel
* panel
)
3381 if (panel
->color
.set
!= cpHSV
)
3382 convertCPColor(&panel
->color
);
3384 value
= rint(panel
->color
.hsv
.value
/ 2.55);
3385 WMSetSliderValue(panel
->grayBrightnessS
, value
);
3387 sprintf(tmp
, "%d", value
);
3388 WMSetTextFieldText(panel
->grayBrightnessT
, tmp
);
3391 static void rgbInit(W_ColorPanel
* panel
)
3395 if (panel
->color
.set
!= cpRGB
)
3396 convertCPColor(&panel
->color
);
3398 WMSetSliderValue(panel
->rgbRedS
, panel
->color
.rgb
.red
);
3399 WMSetSliderValue(panel
->rgbGreenS
, panel
->color
.rgb
.green
);
3400 WMSetSliderValue(panel
->rgbBlueS
, panel
->color
.rgb
.blue
);
3402 sprintf(tmp
, "%d", panel
->color
.rgb
.red
);
3403 WMSetTextFieldText(panel
->rgbRedT
, tmp
);
3404 sprintf(tmp
, "%d", panel
->color
.rgb
.green
);
3405 WMSetTextFieldText(panel
->rgbGreenT
, tmp
);
3406 sprintf(tmp
, "%d", panel
->color
.rgb
.blue
);
3407 WMSetTextFieldText(panel
->rgbBlueT
, tmp
);
3410 static void cmykInit(W_ColorPanel
* panel
)
3415 if (panel
->color
.set
!= cpRGB
)
3416 convertCPColor(&panel
->color
);
3418 value
[0] = rint((255 - panel
->color
.rgb
.red
) / 2.55);
3419 value
[1] = rint((255 - panel
->color
.rgb
.green
) / 2.55);
3420 value
[2] = rint((255 - panel
->color
.rgb
.blue
) / 2.55);
3422 WMSetSliderValue(panel
->cmykCyanS
, value
[0]);
3423 WMSetSliderValue(panel
->cmykMagentaS
, value
[1]);
3424 WMSetSliderValue(panel
->cmykYellowS
, value
[2]);
3425 WMSetSliderValue(panel
->cmykBlackS
, 0);
3427 sprintf(tmp
, "%d", value
[0]);
3428 WMSetTextFieldText(panel
->cmykCyanT
, tmp
);
3429 sprintf(tmp
, "%d", value
[1]);
3430 WMSetTextFieldText(panel
->cmykMagentaT
, tmp
);
3431 sprintf(tmp
, "%d", value
[2]);
3432 WMSetTextFieldText(panel
->cmykYellowT
, tmp
);
3433 WMSetTextFieldText(panel
->cmykBlackT
, "0");
3436 static void hsbInit(W_ColorPanel
* panel
)
3441 if (panel
->color
.set
!= cpHSV
)
3442 convertCPColor(&panel
->color
);
3444 value
[0] = panel
->color
.hsv
.hue
;
3445 value
[1] = rint(panel
->color
.hsv
.saturation
/ 2.55);
3446 value
[2] = rint(panel
->color
.hsv
.value
/ 2.55);
3448 WMSetSliderValue(panel
->hsbHueS
, value
[0]);
3449 WMSetSliderValue(panel
->hsbSaturationS
, value
[1]);
3450 WMSetSliderValue(panel
->hsbBrightnessS
, value
[2]);
3452 sprintf(tmp
, "%d", value
[0]);
3453 WMSetTextFieldText(panel
->hsbHueT
, tmp
);
3454 sprintf(tmp
, "%d", value
[1]);
3455 WMSetTextFieldText(panel
->hsbSaturationT
, tmp
);
3456 sprintf(tmp
, "%d", value
[2]);
3457 WMSetTextFieldText(panel
->hsbBrightnessT
, tmp
);
3459 hsbUpdateBrightnessGradient(panel
);
3460 hsbUpdateSaturationGradient(panel
);
3461 hsbUpdateHueGradient(panel
);
3464 /************************** Common utility functions ************************/
3466 static char *generateNewFilename(const char *curName
)
3478 if (((ptr
= strrchr(ptr
, '{')) == 0) || sscanf(ptr
, "{%i}%c", &n
, &c
) != 1)
3479 return wstrconcat(curName
, " {1}");
3481 baseLen
= ptr
- curName
- 1;
3483 newName
= wmalloc(baseLen
+ 16);
3484 strncpy(newName
, curName
, baseLen
);
3486 snprintf(&newName
[baseLen
], 16, " {%i}", n
+ 1);
3491 static void convertCPColor(CPColor
* color
)
3493 unsigned short old_hue
= 0;
3495 switch (color
->set
) {
3497 wwarning(_("Color Panel: Color unspecified"));
3500 old_hue
= color
->hsv
.hue
;
3501 RRGBtoHSV(&(color
->rgb
), &(color
->hsv
));
3503 /* In black the hue is undefined, and may change by conversion
3504 * Same for white. */
3505 if (((color
->rgb
.red
== 0) &&
3506 (color
->rgb
.green
== 0) &&
3507 (color
->rgb
.blue
== 0)) ||
3508 ((color
->rgb
.red
== 0) && (color
->rgb
.green
== 0) && (color
->rgb
.blue
== 255))
3510 color
->hsv
.hue
= old_hue
;
3513 RHSVtoRGB(&(color
->hsv
), &(color
->rgb
));
3518 #define ABS_SHIFT(val, shift) \
3519 (((shift) > 0) ? (val) >> (shift) : (val) << -(shift))
3521 static RColor
ulongToRColor(WMScreen
* scr
, unsigned long value
)
3524 XColor
*xcolor
= NULL
;
3526 xcolor
= wmalloc(sizeof(XColor
));
3527 xcolor
->pixel
= value
;
3528 XQueryColor(scr
->display
, scr
->rcontext
->cmap
, xcolor
);
3530 color
.red
= xcolor
->red
>> 8;
3531 color
.green
= xcolor
->green
>> 8;
3532 color
.blue
= xcolor
->blue
>> 8;
3540 static unsigned char getShift(unsigned char value
)
3542 unsigned char i
= -1;