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>
39 #define RETRY( x ) do { \
41 } while (errno == EINTR);
43 /* BUG There's something fishy with shaped windows */
44 /* Whithout shape extension the magnified image is completely broken -Dan */
47 # include <X11/extensions/shape.h>
50 char *WMColorPanelColorChangedNotification
= "WMColorPanelColorChangedNotification";
53 * Bitmaps for magnifying glass cursor
57 #define Cursor_x_hot 11
58 #define Cursor_y_hot 11
59 #define Cursor_width 32
60 #define Cursor_height 32
61 static unsigned char Cursor_bits
[] = {
62 0x00, 0x7e, 0x00, 0x00, 0xc0, 0x81, 0x03, 0x00, 0x20, 0x00, 0x04, 0x00, 0x10, 0x00, 0x08,
63 0x00, 0x08, 0x00, 0x10, 0x00, 0x04, 0x00, 0x20, 0x00, 0x02, 0x00, 0x40, 0x00, 0x02, 0x00,
64 0x40, 0x00, 0x02, 0x00, 0x40, 0x00, 0x01, 0x42, 0x80, 0x00, 0x01, 0x24, 0x80, 0x00, 0x01,
65 0x00, 0x80, 0x00, 0x01, 0x00, 0x80, 0x00, 0x01, 0x24, 0x80, 0x00, 0x01, 0x42, 0x80, 0x00,
66 0x02, 0x00, 0x40, 0x00, 0x02, 0x00, 0x40, 0x00, 0x02, 0x00, 0x40, 0x00, 0x04, 0x00, 0x20,
67 0x00, 0x08, 0x00, 0x50, 0x00, 0x10, 0x00, 0x88, 0x00, 0x20, 0x00, 0x5c, 0x01, 0xc0, 0x81,
68 0x3b, 0x02, 0x00, 0x7e, 0x70, 0x05, 0x00, 0x00, 0xe0, 0x08, 0x00, 0x00, 0xc0, 0x15, 0x00,
69 0x00, 0x80, 0x23, 0x00, 0x00, 0x00, 0x57, 0x00, 0x00, 0x00, 0x8e, 0x00, 0x00, 0x00, 0x5c,
70 0x00, 0x00, 0x00, 0xb8, 0x00, 0x00, 0x00, 0x70
73 /* Cursor shape-mask */
74 #define Cursor_shape_width 32
75 #define Cursor_shape_height 32
76 static unsigned char Cursor_shape_bits
[] = {
77 0x00, 0x7e, 0x00, 0x00, 0xc0, 0x81, 0x03, 0x00, 0x20, 0x00, 0x04, 0x00, 0x10, 0x00, 0x08,
78 0x00, 0x08, 0x00, 0x10, 0x00, 0x04, 0x00, 0x20, 0x00, 0x02, 0x00, 0x40, 0x00, 0x02, 0x00,
79 0x40, 0x00, 0x02, 0x00, 0x40, 0x00, 0x01, 0x42, 0x80, 0x00, 0x01, 0x24, 0x80, 0x00, 0x01,
80 0x00, 0x80, 0x00, 0x01, 0x00, 0x80, 0x00, 0x01, 0x24, 0x80, 0x00, 0x01, 0x42, 0x80, 0x00,
81 0x02, 0x00, 0x40, 0x00, 0x02, 0x00, 0x40, 0x00, 0x02, 0x00, 0x40, 0x00, 0x04, 0x00, 0x20,
82 0x00, 0x08, 0x00, 0x70, 0x00, 0x10, 0x00, 0xf8, 0x00, 0x20, 0x00, 0xfc, 0x01, 0xc0, 0x81,
83 0xfb, 0x03, 0x00, 0x7e, 0xf0, 0x07, 0x00, 0x00, 0xe0, 0x0f, 0x00, 0x00, 0xc0, 0x1f, 0x00,
84 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0xfc,
85 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x70
88 /* Clip-mask for magnified pixels */
89 #define Cursor_mask_width 24
90 #define Cursor_mask_height 24
91 static unsigned char Cursor_mask_bits
[] = {
92 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0xc0, 0xff, 0x03, 0xe0, 0xff, 0x07,
93 0xf0, 0xff, 0x0f, 0xf8, 0xff, 0x1f, 0xfc, 0xff, 0x3f, 0xfc, 0xff, 0x3f,
94 0xfc, 0xff, 0x3f, 0xfe, 0xff, 0x7f, 0xfe, 0xff, 0x7f, 0xfe, 0xff, 0x7f,
95 0xfe, 0xff, 0x7f, 0xfe, 0xff, 0x7f, 0xfe, 0xff, 0x7f, 0xfc, 0xff, 0x3f,
96 0xfc, 0xff, 0x3f, 0xfc, 0xff, 0x3f, 0xf8, 0xff, 0x1f, 0xf0, 0xff, 0x0f,
97 0xe0, 0xff, 0x07, 0xc0, 0xff, 0x03, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00
100 typedef struct MovingView
{
101 WMView
*view
; /* The view this is all about */
102 XImage
*image
; /* What's under the view */
103 XImage
*dirtyRect
; /* Storage of overlapped image area */
104 Pixmap magPix
; /* Magnified part of pixmap */
105 RColor color
; /* Color of a pixel in the image */
106 int x
, y
; /* Position of view */
109 typedef struct CPColor
{
110 RColor rgb
; /* The RGB values of the color */
111 RHSVColor hsv
; /* The HSV values of the color */
112 enum { /* Which one was last set ? */
119 typedef struct WheelMatrix
{
120 unsigned int width
, height
; /* Size of the colorwheel */
121 unsigned char *data
[3]; /* Wheel data (R,G,B) */
122 unsigned char values
[256]; /* Precalculated values R,G & B = 0-255 */
125 typedef struct W_ColorPanel
{
133 WMColorWell
*colorWell
;
134 WMButton
*magnifyBtn
;
136 WMButton
*slidersBtn
;
137 WMButton
*customPaletteBtn
;
138 WMButton
*colorListBtn
;
140 /* Magnifying Glass */
141 MovingView
*magnifyGlass
;
143 /* ColorWheel Panel */
145 WMSlider
*wheelBrightnessS
;
150 WMFrame
*seperatorFrm
;
155 /* Gray Scale Panel */
159 WMSlider
*grayBrightnessS
;
160 WMTextField
*grayBrightnessT
;
161 WMButton
*grayPresetBtn
[7];
172 WMTextField
*rgbRedT
;
173 WMTextField
*rgbGreenT
;
174 WMTextField
*rgbBlueT
;
185 WMSlider
*cmykMagentaS
;
186 WMSlider
*cmykYellowS
;
187 WMSlider
*cmykBlackS
;
188 WMTextField
*cmykCyanT
;
189 WMTextField
*cmykMagentaT
;
190 WMTextField
*cmykYellowT
;
191 WMTextField
*cmykBlackT
;
196 WMSlider
*hsbSaturationS
;
197 WMSlider
*hsbBrightnessS
;
198 WMTextField
*hsbHueT
;
199 WMTextField
*hsbSaturationT
;
200 WMTextField
*hsbBrightnessT
;
202 /* Custom Palette Panel */
203 WMFrame
*customPaletteFrm
;
204 WMPopUpButton
*customPaletteHistoryBtn
;
205 WMFrame
*customPaletteContentFrm
;
206 WMPopUpButton
*customPaletteMenuBtn
;
207 WMView
*customPaletteContentView
;
209 /* Color List Panel */
210 WMFrame
*colorListFrm
;
211 WMPopUpButton
*colorListHistoryBtn
;
212 WMList
*colorListContentLst
;
213 WMPopUpButton
*colorListColorMenuBtn
;
214 WMPopUpButton
*colorListListMenuBtn
;
216 /* Look-Up Tables and Images */
217 wheelMatrix
*wheelMtrx
;
220 Pixmap selectionBackImg
;
221 RImage
*customPaletteImg
;
224 /* Common Data Fields */
225 CPColor color
; /* Current color */
226 WMColorPanelMode mode
; /* Current color selection mode */
227 WMColorPanelMode slidersmode
; /* Current color sel. mode sliders panel */
228 WMColorPanelMode lastChanged
; /* Panel that last changed the color */
229 int colx
, coly
; /* (x,y) of sel.-marker in WheelMode */
230 int palx
, paly
; /* (x,y) of sel.-marker in
232 double palXRatio
, palYRatio
; /* Ratios in x & y between
236 char *configurationPath
;
239 unsigned int continuous
:1;
240 unsigned int dragging
:1;
249 CPmenuNewFromClipboard
250 } customPaletteMenuItem
;
260 #define colorWheelSize 150
261 #define customPaletteWidth 182
262 #define customPaletteHeight 106
263 #define knobThickness 8
265 #define SPECTRUM_WIDTH 511
266 #define SPECTRUM_HEIGHT 360
268 #define COLORWHEEL_PART 1
269 #define CUSTOMPALETTE_PART 2
272 #define MAX_LENGTH 1024
275 #define M_PI 3.14159265358979323846
278 static char *generateNewFilename(const char *curName
);
279 static void convertCPColor(CPColor
* color
);
280 static RColor
ulongToRColor(WMScreen
* scr
, unsigned long value
);
281 static unsigned char getShift(unsigned char value
);
283 static void modeButtonCallback(WMWidget
* w
, void *data
);
284 static int getPickerPart(W_ColorPanel
* panel
, int x
, int y
);
285 static void readConfiguration(W_ColorPanel
* panel
);
286 static void readXColors(W_ColorPanel
* panel
);
288 static void closeWindowCallback(WMWidget
* w
, void *data
);
290 static Cursor
magnifyGrabPointer(W_ColorPanel
* panel
);
291 static WMPoint
magnifyInitialize(W_ColorPanel
* panel
);
292 static void magnifyPutCursor(WMWidget
* w
, void *data
);
293 static Pixmap
magnifyCreatePixmap(WMColorPanel
* panel
);
294 static void magnifyGetImageStored(W_ColorPanel
* panel
, int x1
, int y1
, int x2
, int y2
);
295 static XImage
*magnifyGetImage(WMScreen
* scr
, XImage
* image
, int x
, int y
, int w
, int h
);
297 static wheelMatrix
*wheelCreateMatrix(unsigned int width
, unsigned int height
);
298 static void wheelDestroyMatrix(wheelMatrix
* matrix
);
299 static void wheelInitMatrix(W_ColorPanel
* panel
);
300 static void wheelCalculateValues(W_ColorPanel
* panel
, int maxvalue
);
301 static void wheelRender(W_ColorPanel
* panel
);
302 static Bool
wheelInsideColorWheel(W_ColorPanel
* panel
, unsigned long ofs
);
303 static void wheelPaint(W_ColorPanel
* panel
);
305 static void wheelHandleEvents(XEvent
* event
, void *data
);
306 static void wheelHandleActionEvents(XEvent
* event
, void *data
);
307 static void wheelBrightnessSliderCallback(WMWidget
* w
, void *data
);
308 static void wheelUpdateSelection(W_ColorPanel
* panel
);
309 static void wheelUndrawSelection(W_ColorPanel
* panel
);
311 static void wheelPositionSelection(W_ColorPanel
* panel
, int x
, int y
);
312 static void wheelPositionSelectionOutBounds(W_ColorPanel
* panel
, int x
, int y
);
313 static void wheelUpdateBrightnessGradientFromLocation(W_ColorPanel
* panel
);
314 static void wheelUpdateBrightnessGradient(W_ColorPanel
* panel
, CPColor topColor
);
316 static void grayBrightnessSliderCallback(WMWidget
* w
, void *data
);
317 static void grayPresetButtonCallback(WMWidget
* w
, void *data
);
318 static void grayBrightnessTextFieldCallback(void *observerData
, WMNotification
* notification
);
320 static void rgbSliderCallback(WMWidget
* w
, void *data
);
321 static void rgbTextFieldCallback(void *observerData
, WMNotification
* notification
);
322 static void rgbDecToHex(WMWidget
*w
, void *data
);
324 static void cmykSliderCallback(WMWidget
* w
, void *data
);
325 static void cmykTextFieldCallback(void *observerData
, WMNotification
* notification
);
327 static void hsbSliderCallback(WMWidget
* w
, void *data
);
328 static void hsbTextFieldCallback(void *observerData
, WMNotification
* notification
);
329 static void hsbUpdateBrightnessGradient(W_ColorPanel
* panel
);
330 static void hsbUpdateSaturationGradient(W_ColorPanel
* panel
);
331 static void hsbUpdateHueGradient(W_ColorPanel
* panel
);
333 static void customRenderSpectrum(W_ColorPanel
* panel
);
334 static void customSetPalette(W_ColorPanel
* panel
);
335 static void customPaletteHandleEvents(XEvent
* event
, void *data
);
336 static void customPaletteHandleActionEvents(XEvent
* event
, void *data
);
337 static void customPalettePositionSelection(W_ColorPanel
* panel
, int x
, int y
);
338 static void customPalettePositionSelectionOutBounds(W_ColorPanel
* panel
, int x
, int y
);
339 static void customPaletteMenuCallback(WMWidget
* w
, void *data
);
340 static void customPaletteHistoryCallback(WMWidget
* w
, void *data
);
342 static void customPaletteMenuNewFromFile(W_ColorPanel
* panel
);
343 static void customPaletteMenuRename(W_ColorPanel
* panel
);
344 static void customPaletteMenuRemove(W_ColorPanel
* panel
);
346 static void colorListPaintItem(WMList
* lPtr
, int index
, Drawable d
, char *text
, int state
, WMRect
* rect
);
347 static void colorListSelect(WMWidget
* w
, void *data
);
348 static void colorListColorMenuCallback(WMWidget
* w
, void *data
);
349 static void colorListListMenuCallback(WMWidget
* w
, void *data
);
351 static void wheelInit(W_ColorPanel
* panel
);
352 static void grayInit(W_ColorPanel
* panel
);
353 static void rgbInit(W_ColorPanel
* panel
);
354 static void cmykInit(W_ColorPanel
* panel
);
355 static void hsbInit(W_ColorPanel
* panel
);
358 static inline int get_textfield_as_integer(WMTextField
*widget
)
363 str
= WMGetTextFieldText(widget
);
369 void WMSetColorPanelAction(WMColorPanel
* panel
, WMAction2
* action
, void *data
)
371 panel
->action
= action
;
372 panel
->clientData
= data
;
375 static WMColorPanel
*makeColorPanel(WMScreen
* scrPtr
, const char *name
)
382 WMColor
*textcolor
, *graybuttoncolor
;
384 GC bgc
= WMColorGC(scrPtr
->black
);
385 GC wgc
= WMColorGC(scrPtr
->white
);
387 panel
= wmalloc(sizeof(WMColorPanel
));
388 panel
->color
.rgb
.red
= 0;
389 panel
->color
.rgb
.green
= 0;
390 panel
->color
.rgb
.blue
= 0;
391 panel
->color
.hsv
.hue
= 0;
392 panel
->color
.hsv
.saturation
= 0;
393 panel
->color
.hsv
.value
= 0;
394 panel
->color
.set
= cpNone
; /* Color has not been set yet */
396 panel
->font8
= WMSystemFontOfSize(scrPtr
, 8);
397 panel
->font12
= WMSystemFontOfSize(scrPtr
, 12);
399 panel
->win
= WMCreateWindowWithStyle(scrPtr
, name
,
400 WMTitledWindowMask
| WMClosableWindowMask
| WMResizableWindowMask
);
401 WMResizeWidget(panel
->win
, PWIDTH
, PHEIGHT
);
402 WMSetWindowTitle(panel
->win
, _("Colors"));
403 WMSetWindowCloseAction(panel
->win
, closeWindowCallback
, panel
);
405 /* Set Default ColorPanel Mode(s) */
406 panel
->mode
= WMWheelModeColorPanel
;
407 panel
->lastChanged
= 0;
408 panel
->slidersmode
= WMRGBModeColorPanel
;
409 panel
->configurationPath
= wstrconcat(wusergnusteppath(), "/Library/Colors/");
411 /* Some General Purpose Widgets */
412 panel
->colorWell
= WMCreateColorWell(panel
->win
);
413 WMResizeWidget(panel
->colorWell
, 134, 36);
414 WSetColorWellBordered(panel
->colorWell
, False
);
415 WMMoveWidget(panel
->colorWell
, 56, 4);
417 panel
->magnifyBtn
= WMCreateCustomButton(panel
->win
, WBBStateLightMask
| WBBStateChangeMask
);
418 WMResizeWidget(panel
->magnifyBtn
, 46, 36);
419 WMMoveWidget(panel
->magnifyBtn
, 6, 4);
420 WMSetButtonAction(panel
->magnifyBtn
, magnifyPutCursor
, panel
);
421 WMSetButtonImagePosition(panel
->magnifyBtn
, WIPImageOnly
);
422 WMSetButtonImage(panel
->magnifyBtn
, scrPtr
->magnifyIcon
);
424 panel
->wheelBtn
= WMCreateCustomButton(panel
->win
, WBBStateLightMask
| WBBStateChangeMask
);
425 WMResizeWidget(panel
->wheelBtn
, 46, 32);
426 WMMoveWidget(panel
->wheelBtn
, 6, 44);
427 WMSetButtonAction(panel
->wheelBtn
, modeButtonCallback
, panel
);
428 WMSetButtonImagePosition(panel
->wheelBtn
, WIPImageOnly
);
429 WMSetButtonImage(panel
->wheelBtn
, scrPtr
->wheelIcon
);
431 panel
->slidersBtn
= WMCreateCustomButton(panel
->win
, WBBStateLightMask
| WBBStateChangeMask
);
432 WMResizeWidget(panel
->slidersBtn
, 46, 32);
433 WMMoveWidget(panel
->slidersBtn
, 52, 44);
434 WMSetButtonAction(panel
->slidersBtn
, modeButtonCallback
, panel
);
435 WMSetButtonImagePosition(panel
->slidersBtn
, WIPImageOnly
);
436 WMSetButtonImage(panel
->slidersBtn
, scrPtr
->rgbIcon
);
438 panel
->customPaletteBtn
= WMCreateCustomButton(panel
->win
, WBBStateLightMask
| WBBStateChangeMask
);
439 WMResizeWidget(panel
->customPaletteBtn
, 46, 32);
440 WMMoveWidget(panel
->customPaletteBtn
, 98, 44);
441 WMSetButtonAction(panel
->customPaletteBtn
, modeButtonCallback
, panel
);
442 WMSetButtonImagePosition(panel
->customPaletteBtn
, WIPImageOnly
);
443 WMSetButtonImage(panel
->customPaletteBtn
, scrPtr
->customPaletteIcon
);
445 panel
->colorListBtn
= WMCreateCustomButton(panel
->win
, WBBStateLightMask
| WBBStateChangeMask
);
446 WMResizeWidget(panel
->colorListBtn
, 46, 32);
447 WMMoveWidget(panel
->colorListBtn
, 144, 44);
448 WMSetButtonAction(panel
->colorListBtn
, modeButtonCallback
, panel
);
449 WMSetButtonImagePosition(panel
->colorListBtn
, WIPImageOnly
);
450 WMSetButtonImage(panel
->colorListBtn
, scrPtr
->colorListIcon
);
452 /* Let's Group some of them together */
453 WMGroupButtons(panel
->wheelBtn
, panel
->slidersBtn
);
454 WMGroupButtons(panel
->wheelBtn
, panel
->customPaletteBtn
);
455 WMGroupButtons(panel
->wheelBtn
, panel
->colorListBtn
);
457 /* Widgets for the ColorWheel Panel */
458 panel
->wheelFrm
= WMCreateFrame(panel
->win
);
459 WMSetFrameRelief(panel
->wheelFrm
, WRFlat
);
460 WMResizeWidget(panel
->wheelFrm
, PWIDTH
- 8, PHEIGHT
- 80 - 26);
461 WMMoveWidget(panel
->wheelFrm
, 5, 80);
463 panel
->wheelView
= W_CreateView(W_VIEW(panel
->wheelFrm
));
464 /* XXX Can we create a view ? */
465 W_ResizeView(panel
->wheelView
, colorWheelSize
+ 4, colorWheelSize
+ 4);
466 W_MoveView(panel
->wheelView
, 0, 0);
468 /* Create an event handler to handle expose/click events in ColorWheel */
469 WMCreateEventHandler(panel
->wheelView
,
470 ButtonPressMask
| ButtonReleaseMask
| EnterWindowMask
|
471 LeaveWindowMask
| ButtonMotionMask
, wheelHandleActionEvents
, panel
);
473 WMCreateEventHandler(panel
->wheelView
, ExposureMask
, wheelHandleEvents
, panel
);
475 panel
->wheelBrightnessS
= WMCreateSlider(panel
->wheelFrm
);
476 WMResizeWidget(panel
->wheelBrightnessS
, 16, 153);
477 WMMoveWidget(panel
->wheelBrightnessS
, 5 + colorWheelSize
+ 14, 1);
478 WMSetSliderMinValue(panel
->wheelBrightnessS
, 0);
479 WMSetSliderMaxValue(panel
->wheelBrightnessS
, 255);
480 WMSetSliderAction(panel
->wheelBrightnessS
, wheelBrightnessSliderCallback
, panel
);
481 WMSetSliderKnobThickness(panel
->wheelBrightnessS
, knobThickness
);
483 panel
->wheelMtrx
= wheelCreateMatrix(colorWheelSize
+ 4, colorWheelSize
+ 4);
484 wheelInitMatrix(panel
);
486 /* Widgets for the Slider Panels */
487 panel
->slidersFrm
= WMCreateFrame(panel
->win
);
488 WMSetFrameRelief(panel
->slidersFrm
, WRFlat
);
489 WMResizeWidget(panel
->slidersFrm
, PWIDTH
- 8, PHEIGHT
- 80 - 26);
490 WMMoveWidget(panel
->slidersFrm
, 4, 80);
492 panel
->seperatorFrm
= WMCreateFrame(panel
->slidersFrm
);
493 WMSetFrameRelief(panel
->seperatorFrm
, WRPushed
);
494 WMResizeWidget(panel
->seperatorFrm
, PWIDTH
- 8, 2);
495 WMMoveWidget(panel
->seperatorFrm
, 0, 1);
497 panel
->grayBtn
= WMCreateCustomButton(panel
->slidersFrm
, WBBStateLightMask
| WBBStateChangeMask
);
498 WMResizeWidget(panel
->grayBtn
, 46, 24);
499 WMMoveWidget(panel
->grayBtn
, 1, 8);
500 WMSetButtonAction(panel
->grayBtn
, modeButtonCallback
, panel
);
501 WMSetButtonImagePosition(panel
->grayBtn
, WIPImageOnly
);
502 WMSetButtonImage(panel
->grayBtn
, scrPtr
->grayIcon
);
504 panel
->rgbBtn
= WMCreateCustomButton(panel
->slidersFrm
, WBBStateLightMask
| WBBStateChangeMask
);
505 WMResizeWidget(panel
->rgbBtn
, 46, 24);
506 WMMoveWidget(panel
->rgbBtn
, 47, 8);
507 WMSetButtonAction(panel
->rgbBtn
, modeButtonCallback
, panel
);
508 WMSetButtonImagePosition(panel
->rgbBtn
, WIPImageOnly
);
509 WMSetButtonImage(panel
->rgbBtn
, scrPtr
->rgbIcon
);
511 panel
->cmykBtn
= WMCreateCustomButton(panel
->slidersFrm
, WBBStateLightMask
| WBBStateChangeMask
);
512 WMResizeWidget(panel
->cmykBtn
, 46, 24);
513 WMMoveWidget(panel
->cmykBtn
, 93, 8);
514 WMSetButtonAction(panel
->cmykBtn
, modeButtonCallback
, panel
);
515 WMSetButtonImagePosition(panel
->cmykBtn
, WIPImageOnly
);
516 WMSetButtonImage(panel
->cmykBtn
, scrPtr
->cmykIcon
);
518 panel
->hsbBtn
= WMCreateCustomButton(panel
->slidersFrm
, WBBStateLightMask
| WBBStateChangeMask
);
519 WMResizeWidget(panel
->hsbBtn
, 46, 24);
520 WMMoveWidget(panel
->hsbBtn
, 139, 8);
521 WMSetButtonAction(panel
->hsbBtn
, modeButtonCallback
, panel
);
522 WMSetButtonImagePosition(panel
->hsbBtn
, WIPImageOnly
);
523 WMSetButtonImage(panel
->hsbBtn
, scrPtr
->hsbIcon
);
525 /* Let's Group the Slider Panel Buttons Together */
526 WMGroupButtons(panel
->grayBtn
, panel
->rgbBtn
);
527 WMGroupButtons(panel
->grayBtn
, panel
->cmykBtn
);
528 WMGroupButtons(panel
->grayBtn
, panel
->hsbBtn
);
530 textcolor
= WMDarkGrayColor(scrPtr
);
532 /* Widgets for GrayScale Panel */
533 panel
->grayFrm
= WMCreateFrame(panel
->slidersFrm
);
534 WMSetFrameRelief(panel
->grayFrm
, WRFlat
);
535 WMResizeWidget(panel
->grayFrm
, PWIDTH
- 8, PHEIGHT
- 80 - 26 - 32);
536 WMMoveWidget(panel
->grayFrm
, 0, 34);
538 panel
->grayMinL
= WMCreateLabel(panel
->grayFrm
);
539 WMResizeWidget(panel
->grayMinL
, 20, 10);
540 WMMoveWidget(panel
->grayMinL
, 2, 2);
541 WMSetLabelText(panel
->grayMinL
, "0");
542 WMSetLabelTextAlignment(panel
->grayMinL
, WALeft
);
543 WMSetLabelTextColor(panel
->grayMinL
, textcolor
);
544 WMSetLabelFont(panel
->grayMinL
, panel
->font8
);
546 panel
->grayMaxL
= WMCreateLabel(panel
->grayFrm
);
547 WMResizeWidget(panel
->grayMaxL
, 40, 10);
548 WMMoveWidget(panel
->grayMaxL
, 104, 2);
549 WMSetLabelText(panel
->grayMaxL
, "100");
550 WMSetLabelTextAlignment(panel
->grayMaxL
, WARight
);
551 WMSetLabelTextColor(panel
->grayMaxL
, textcolor
);
552 WMSetLabelFont(panel
->grayMaxL
, panel
->font8
);
554 panel
->grayBrightnessS
= WMCreateSlider(panel
->grayFrm
);
555 WMResizeWidget(panel
->grayBrightnessS
, 141, 16);
556 WMMoveWidget(panel
->grayBrightnessS
, 2, 14);
557 WMSetSliderMinValue(panel
->grayBrightnessS
, 0);
558 WMSetSliderMaxValue(panel
->grayBrightnessS
, 100);
559 WMSetSliderKnobThickness(panel
->grayBrightnessS
, knobThickness
);
560 WMSetSliderAction(panel
->grayBrightnessS
, grayBrightnessSliderCallback
, panel
);
570 image
= RRenderGradient(141, 16, &from
, &to
, RGRD_HORIZONTAL
);
571 pixmap
= WMCreatePixmapFromRImage(scrPtr
, image
, 0);
572 RReleaseImage(image
);
575 W_PaintText(W_VIEW(panel
->grayBrightnessS
), pixmap
->pixmap
,
576 panel
->font12
, 2, 0, 100, WALeft
, scrPtr
->white
,
577 False
, _("Brightness"), strlen(_("Brightness")));
579 wwarning(_("Color Panel: Could not allocate memory"));
581 WMSetSliderImage(panel
->grayBrightnessS
, pixmap
);
582 WMReleasePixmap(pixmap
);
584 panel
->grayBrightnessT
= WMCreateTextField(panel
->grayFrm
);
585 WMResizeWidget(panel
->grayBrightnessT
, 40, 18);
586 WMMoveWidget(panel
->grayBrightnessT
, 146, 13);
587 WMSetTextFieldAlignment(panel
->grayBrightnessT
, WALeft
);
588 WMAddNotificationObserver(grayBrightnessTextFieldCallback
, panel
,
589 WMTextDidEndEditingNotification
, panel
->grayBrightnessT
);
591 for (i
= 0; i
< 7; i
++) {
592 pixmap
= WMCreatePixmap(scrPtr
, 13, 13, scrPtr
->depth
, False
);
594 graybuttoncolor
= WMCreateRGBColor(scrPtr
, (255 / 6) * i
<< 8,
595 (255 / 6) * i
<< 8, (255 / 6) * i
<< 8, True
);
596 WMPaintColorSwatch(graybuttoncolor
, pixmap
->pixmap
, 0, 0, 15, 15);
597 WMReleaseColor(graybuttoncolor
);
599 panel
->grayPresetBtn
[i
] = WMCreateCommandButton(panel
->grayFrm
);
600 WMResizeWidget(panel
->grayPresetBtn
[i
], 20, 24);
601 WMMoveWidget(panel
->grayPresetBtn
[i
], 2 + (i
* 20), 34);
602 WMSetButtonAction(panel
->grayPresetBtn
[i
], grayPresetButtonCallback
, panel
);
603 WMSetButtonImage(panel
->grayPresetBtn
[i
], pixmap
);
604 WMSetButtonImagePosition(panel
->grayPresetBtn
[i
], WIPImageOnly
);
605 WMReleasePixmap(pixmap
);
609 /* End of GrayScale Panel */
611 /* Widgets for RGB Panel */
612 panel
->rgbFrm
= WMCreateFrame(panel
->slidersFrm
);
613 WMSetFrameRelief(panel
->rgbFrm
, WRFlat
);
614 WMResizeWidget(panel
->rgbFrm
, PWIDTH
- 8, PHEIGHT
- 80 - 26 - 32);
615 WMMoveWidget(panel
->rgbFrm
, 0, 34);
617 panel
->rgbMinL
= WMCreateLabel(panel
->rgbFrm
);
618 WMResizeWidget(panel
->rgbMinL
, 20, 10);
619 WMMoveWidget(panel
->rgbMinL
, 2, 2);
620 WMSetLabelText(panel
->rgbMinL
, "0");
621 WMSetLabelTextAlignment(panel
->rgbMinL
, WALeft
);
622 WMSetLabelTextColor(panel
->rgbMinL
, textcolor
);
623 WMSetLabelFont(panel
->rgbMinL
, panel
->font8
);
625 panel
->rgbMaxL
= WMCreateLabel(panel
->rgbFrm
);
626 WMResizeWidget(panel
->rgbMaxL
, 40, 10);
627 WMMoveWidget(panel
->rgbMaxL
, 104, 2);
628 WMSetLabelText(panel
->rgbMaxL
, "255");
629 WMSetLabelTextAlignment(panel
->rgbMaxL
, WARight
);
630 WMSetLabelTextColor(panel
->rgbMaxL
, textcolor
);
631 WMSetLabelFont(panel
->rgbMaxL
, panel
->font8
);
633 panel
->rgbRedS
= WMCreateSlider(panel
->rgbFrm
);
634 WMResizeWidget(panel
->rgbRedS
, 141, 16);
635 WMMoveWidget(panel
->rgbRedS
, 2, 14);
636 WMSetSliderMinValue(panel
->rgbRedS
, 0);
637 WMSetSliderMaxValue(panel
->rgbRedS
, 255);
638 WMSetSliderKnobThickness(panel
->rgbRedS
, knobThickness
);
639 WMSetSliderAction(panel
->rgbRedS
, rgbSliderCallback
, panel
);
645 image
= RRenderGradient(141, 16, &from
, &to
, RGRD_HORIZONTAL
);
646 pixmap
= WMCreatePixmapFromRImage(scrPtr
, image
, 0);
647 RReleaseImage(image
);
650 W_PaintText(W_VIEW(panel
->rgbRedS
), pixmap
->pixmap
, panel
->font12
,
651 2, 0, 100, WALeft
, scrPtr
->white
, False
, _("Red"), strlen(_("Red")));
653 wwarning(_("Color Panel: Could not allocate memory"));
655 WMSetSliderImage(panel
->rgbRedS
, pixmap
);
656 WMReleasePixmap(pixmap
);
658 panel
->rgbRedT
= WMCreateTextField(panel
->rgbFrm
);
659 WMResizeWidget(panel
->rgbRedT
, 40, 18);
660 WMMoveWidget(panel
->rgbRedT
, 146, 13);
661 WMSetTextFieldAlignment(panel
->rgbRedT
, WALeft
);
662 WMAddNotificationObserver(rgbTextFieldCallback
, panel
, WMTextDidEndEditingNotification
, panel
->rgbRedT
);
664 panel
->rgbGreenS
= WMCreateSlider(panel
->rgbFrm
);
665 WMResizeWidget(panel
->rgbGreenS
, 141, 16);
666 WMMoveWidget(panel
->rgbGreenS
, 2, 36);
667 WMSetSliderMinValue(panel
->rgbGreenS
, 0);
668 WMSetSliderMaxValue(panel
->rgbGreenS
, 255);
669 WMSetSliderKnobThickness(panel
->rgbGreenS
, knobThickness
);
670 WMSetSliderAction(panel
->rgbGreenS
, rgbSliderCallback
, panel
);
676 image
= RRenderGradient(141, 16, &from
, &to
, RGRD_HORIZONTAL
);
677 pixmap
= WMCreatePixmapFromRImage(scrPtr
, image
, 0);
678 RReleaseImage(image
);
681 W_PaintText(W_VIEW(panel
->rgbGreenS
), pixmap
->pixmap
, panel
->font12
,
682 2, 0, 100, WALeft
, scrPtr
->white
, False
, _("Green"), strlen(_("Green")));
684 wwarning(_("Color Panel: Could not allocate memory"));
686 WMSetSliderImage(panel
->rgbGreenS
, pixmap
);
687 WMReleasePixmap(pixmap
);
689 panel
->rgbGreenT
= WMCreateTextField(panel
->rgbFrm
);
690 WMResizeWidget(panel
->rgbGreenT
, 40, 18);
691 WMMoveWidget(panel
->rgbGreenT
, 146, 35);
692 WMSetTextFieldAlignment(panel
->rgbGreenT
, WALeft
);
693 WMAddNotificationObserver(rgbTextFieldCallback
, panel
, WMTextDidEndEditingNotification
, panel
->rgbGreenT
);
695 panel
->rgbBlueS
= WMCreateSlider(panel
->rgbFrm
);
696 WMResizeWidget(panel
->rgbBlueS
, 141, 16);
697 WMMoveWidget(panel
->rgbBlueS
, 2, 58);
698 WMSetSliderMinValue(panel
->rgbBlueS
, 0);
699 WMSetSliderMaxValue(panel
->rgbBlueS
, 255);
700 WMSetSliderKnobThickness(panel
->rgbBlueS
, knobThickness
);
701 WMSetSliderAction(panel
->rgbBlueS
, rgbSliderCallback
, panel
);
707 image
= RRenderGradient(141, 16, &from
, &to
, RGRD_HORIZONTAL
);
708 pixmap
= WMCreatePixmapFromRImage(scrPtr
, image
, 0);
709 RReleaseImage(image
);
712 W_PaintText(W_VIEW(panel
->rgbBlueS
), pixmap
->pixmap
, panel
->font12
,
713 2, 0, 100, WALeft
, scrPtr
->white
, False
, _("Blue"), strlen(_("Blue")));
715 wwarning(_("Color Panel: Could not allocate memory"));
717 WMSetSliderImage(panel
->rgbBlueS
, pixmap
);
718 WMReleasePixmap(pixmap
);
720 panel
->rgbBlueT
= WMCreateTextField(panel
->rgbFrm
);
721 WMResizeWidget(panel
->rgbBlueT
, 40, 18);
722 WMMoveWidget(panel
->rgbBlueT
, 146, 57);
723 WMSetTextFieldAlignment(panel
->rgbBlueT
, WALeft
);
724 WMAddNotificationObserver(rgbTextFieldCallback
, panel
, WMTextDidEndEditingNotification
, panel
->rgbBlueT
);
726 panel
->rgbDecB
= WMCreateButton(panel
->rgbFrm
, WBTRadio
);
727 WMSetButtonText(panel
->rgbDecB
, "Decimal");
728 WMSetButtonSelected(panel
->rgbDecB
, 1);
729 panel
->rgbState
= RGBdec
;
730 WMSetButtonAction(panel
->rgbDecB
, rgbDecToHex
, panel
);
731 WMResizeWidget(panel
->rgbDecB
, PWIDTH
- 8, 23);
732 WMMoveWidget(panel
->rgbDecB
, 2, 81);
734 panel
->rgbHexB
= WMCreateButton(panel
->rgbFrm
, WBTRadio
);
735 WMSetButtonText(panel
->rgbHexB
, "Hexadecimal");
736 WMSetButtonAction(panel
->rgbHexB
, rgbDecToHex
, panel
);
737 WMResizeWidget(panel
->rgbHexB
, PWIDTH
- 8, 23);
738 WMMoveWidget(panel
->rgbHexB
, 2, 104);
740 WMGroupButtons(panel
->rgbDecB
, panel
->rgbHexB
);
742 /* End of RGB Panel */
744 /* Widgets for CMYK Panel */
745 panel
->cmykFrm
= WMCreateFrame(panel
->slidersFrm
);
746 WMSetFrameRelief(panel
->cmykFrm
, WRFlat
);
747 WMResizeWidget(panel
->cmykFrm
, PWIDTH
- 8, PHEIGHT
- 80 - 26 - 32);
748 WMMoveWidget(panel
->cmykFrm
, 0, 34);
750 panel
->cmykMinL
= WMCreateLabel(panel
->cmykFrm
);
751 WMResizeWidget(panel
->cmykMinL
, 20, 10);
752 WMMoveWidget(panel
->cmykMinL
, 2, 2);
753 WMSetLabelText(panel
->cmykMinL
, "0");
754 WMSetLabelTextAlignment(panel
->cmykMinL
, WALeft
);
755 WMSetLabelTextColor(panel
->cmykMinL
, textcolor
);
756 WMSetLabelFont(panel
->cmykMinL
, panel
->font8
);
758 panel
->cmykMaxL
= WMCreateLabel(panel
->cmykFrm
);
759 WMResizeWidget(panel
->cmykMaxL
, 40, 10);
760 WMMoveWidget(panel
->cmykMaxL
, 104, 2);
761 WMSetLabelText(panel
->cmykMaxL
, "100");
762 WMSetLabelTextAlignment(panel
->cmykMaxL
, WARight
);
763 WMSetLabelTextColor(panel
->cmykMaxL
, textcolor
);
764 WMSetLabelFont(panel
->cmykMaxL
, panel
->font8
);
766 panel
->cmykCyanS
= WMCreateSlider(panel
->cmykFrm
);
767 WMResizeWidget(panel
->cmykCyanS
, 141, 16);
768 WMMoveWidget(panel
->cmykCyanS
, 2, 14);
769 WMSetSliderMinValue(panel
->cmykCyanS
, 0);
770 WMSetSliderMaxValue(panel
->cmykCyanS
, 100);
771 WMSetSliderKnobThickness(panel
->cmykCyanS
, knobThickness
);
772 WMSetSliderAction(panel
->cmykCyanS
, cmykSliderCallback
, panel
);
782 image
= RRenderGradient(141, 16, &from
, &to
, RGRD_HORIZONTAL
);
783 pixmap
= WMCreatePixmapFromRImage(scrPtr
, image
, 0);
784 RReleaseImage(image
);
787 W_PaintText(W_VIEW(panel
->cmykCyanS
), pixmap
->pixmap
, panel
->font12
,
788 2, 0, 100, WALeft
, scrPtr
->black
, False
, _("Cyan"), strlen(_("Cyan")));
790 wwarning(_("Color Panel: Could not allocate memory"));
792 WMSetSliderImage(panel
->cmykCyanS
, pixmap
);
793 WMReleasePixmap(pixmap
);
795 panel
->cmykCyanT
= WMCreateTextField(panel
->cmykFrm
);
796 WMResizeWidget(panel
->cmykCyanT
, 40, 18);
797 WMMoveWidget(panel
->cmykCyanT
, 146, 13);
798 WMSetTextFieldAlignment(panel
->cmykCyanT
, WALeft
);
799 WMAddNotificationObserver(cmykTextFieldCallback
, panel
, WMTextDidEndEditingNotification
, panel
->cmykCyanT
);
801 panel
->cmykMagentaS
= WMCreateSlider(panel
->cmykFrm
);
802 WMResizeWidget(panel
->cmykMagentaS
, 141, 16);
803 WMMoveWidget(panel
->cmykMagentaS
, 2, 36);
804 WMSetSliderMinValue(panel
->cmykMagentaS
, 0);
805 WMSetSliderMaxValue(panel
->cmykMagentaS
, 100);
806 WMSetSliderKnobThickness(panel
->cmykMagentaS
, knobThickness
);
807 WMSetSliderAction(panel
->cmykMagentaS
, cmykSliderCallback
, panel
);
813 image
= RRenderGradient(141, 16, &from
, &to
, RGRD_HORIZONTAL
);
814 pixmap
= WMCreatePixmapFromRImage(scrPtr
, image
, 0);
815 RReleaseImage(image
);
818 W_PaintText(W_VIEW(panel
->cmykMagentaS
), pixmap
->pixmap
, panel
->font12
,
819 2, 0, 100, WALeft
, scrPtr
->black
, False
, _("Magenta"), strlen(_("Magenta")));
821 wwarning(_("Color Panel: Could not allocate memory"));
823 WMSetSliderImage(panel
->cmykMagentaS
, pixmap
);
824 WMReleasePixmap(pixmap
);
826 panel
->cmykMagentaT
= WMCreateTextField(panel
->cmykFrm
);
827 WMResizeWidget(panel
->cmykMagentaT
, 40, 18);
828 WMMoveWidget(panel
->cmykMagentaT
, 146, 35);
829 WMSetTextFieldAlignment(panel
->cmykMagentaT
, WALeft
);
830 WMAddNotificationObserver(cmykTextFieldCallback
, panel
,
831 WMTextDidEndEditingNotification
, panel
->cmykMagentaT
);
833 panel
->cmykYellowS
= WMCreateSlider(panel
->cmykFrm
);
834 WMResizeWidget(panel
->cmykYellowS
, 141, 16);
835 WMMoveWidget(panel
->cmykYellowS
, 2, 58);
836 WMSetSliderMinValue(panel
->cmykYellowS
, 0);
837 WMSetSliderMaxValue(panel
->cmykYellowS
, 100);
838 WMSetSliderKnobThickness(panel
->cmykYellowS
, knobThickness
);
839 WMSetSliderAction(panel
->cmykYellowS
, cmykSliderCallback
, panel
);
845 image
= RRenderGradient(141, 16, &from
, &to
, RGRD_HORIZONTAL
);
846 pixmap
= WMCreatePixmapFromRImage(scrPtr
, image
, 0);
847 RReleaseImage(image
);
850 W_PaintText(W_VIEW(panel
->cmykYellowS
), pixmap
->pixmap
, panel
->font12
,
851 2, 0, 100, WALeft
, scrPtr
->black
, False
, _("Yellow"), strlen(_("Yellow")));
853 wwarning(_("Color Panel: Could not allocate memory"));
855 WMSetSliderImage(panel
->cmykYellowS
, pixmap
);
856 WMReleasePixmap(pixmap
);
858 panel
->cmykYellowT
= WMCreateTextField(panel
->cmykFrm
);
859 WMResizeWidget(panel
->cmykYellowT
, 40, 18);
860 WMMoveWidget(panel
->cmykYellowT
, 146, 57);
861 WMSetTextFieldAlignment(panel
->cmykYellowT
, WALeft
);
862 WMAddNotificationObserver(cmykTextFieldCallback
, panel
,
863 WMTextDidEndEditingNotification
, panel
->cmykYellowT
);
865 panel
->cmykBlackS
= WMCreateSlider(panel
->cmykFrm
);
866 WMResizeWidget(panel
->cmykBlackS
, 141, 16);
867 WMMoveWidget(panel
->cmykBlackS
, 2, 80);
868 WMSetSliderMinValue(panel
->cmykBlackS
, 0);
869 WMSetSliderMaxValue(panel
->cmykBlackS
, 100);
870 WMSetSliderValue(panel
->cmykBlackS
, 0);
871 WMSetSliderKnobThickness(panel
->cmykBlackS
, knobThickness
);
872 WMSetSliderAction(panel
->cmykBlackS
, cmykSliderCallback
, panel
);
878 image
= RRenderGradient(141, 16, &from
, &to
, RGRD_HORIZONTAL
);
879 pixmap
= WMCreatePixmapFromRImage(scrPtr
, image
, 0);
880 RReleaseImage(image
);
883 W_PaintText(W_VIEW(panel
->cmykBlackS
), pixmap
->pixmap
, panel
->font12
,
884 2, 0, 100, WALeft
, scrPtr
->black
, False
, _("Black"), strlen(_("Black")));
886 wwarning(_("Color Panel: Could not allocate memory"));
888 WMSetSliderImage(panel
->cmykBlackS
, pixmap
);
889 WMReleasePixmap(pixmap
);
891 panel
->cmykBlackT
= WMCreateTextField(panel
->cmykFrm
);
892 WMResizeWidget(panel
->cmykBlackT
, 40, 18);
893 WMMoveWidget(panel
->cmykBlackT
, 146, 79);
894 WMSetTextFieldAlignment(panel
->cmykBlackT
, WALeft
);
895 WMAddNotificationObserver(cmykTextFieldCallback
, panel
,
896 WMTextDidEndEditingNotification
, panel
->cmykBlackT
);
897 /* End of CMYK Panel */
899 /* Widgets for HSB Panel */
900 panel
->hsbFrm
= WMCreateFrame(panel
->slidersFrm
);
901 WMSetFrameRelief(panel
->hsbFrm
, WRFlat
);
902 WMResizeWidget(panel
->hsbFrm
, PWIDTH
- 8, PHEIGHT
- 80 - 26 - 32);
903 WMMoveWidget(panel
->hsbFrm
, 0, 34);
905 panel
->hsbHueS
= WMCreateSlider(panel
->hsbFrm
);
906 WMResizeWidget(panel
->hsbHueS
, 141, 16);
907 WMMoveWidget(panel
->hsbHueS
, 2, 14);
908 WMSetSliderMinValue(panel
->hsbHueS
, 0);
909 WMSetSliderMaxValue(panel
->hsbHueS
, 359);
910 WMSetSliderKnobThickness(panel
->hsbHueS
, knobThickness
);
911 WMSetSliderAction(panel
->hsbHueS
, hsbSliderCallback
, panel
);
913 panel
->hsbHueT
= WMCreateTextField(panel
->hsbFrm
);
914 WMResizeWidget(panel
->hsbHueT
, 40, 18);
915 WMMoveWidget(panel
->hsbHueT
, 146, 13);
916 WMSetTextFieldAlignment(panel
->hsbHueT
, WALeft
);
917 WMAddNotificationObserver(hsbTextFieldCallback
, panel
, WMTextDidEndEditingNotification
, panel
->hsbHueT
);
919 panel
->hsbSaturationS
= WMCreateSlider(panel
->hsbFrm
);
920 WMResizeWidget(panel
->hsbSaturationS
, 141, 16);
921 WMMoveWidget(panel
->hsbSaturationS
, 2, 36);
922 WMSetSliderMinValue(panel
->hsbSaturationS
, 0);
923 WMSetSliderMaxValue(panel
->hsbSaturationS
, 100);
924 WMSetSliderKnobThickness(panel
->hsbSaturationS
, knobThickness
);
925 WMSetSliderAction(panel
->hsbSaturationS
, hsbSliderCallback
, panel
);
927 panel
->hsbSaturationT
= WMCreateTextField(panel
->hsbFrm
);
928 WMResizeWidget(panel
->hsbSaturationT
, 40, 18);
929 WMMoveWidget(panel
->hsbSaturationT
, 146, 35);
930 WMSetTextFieldAlignment(panel
->hsbSaturationT
, WALeft
);
931 WMAddNotificationObserver(hsbTextFieldCallback
, panel
,
932 WMTextDidEndEditingNotification
, panel
->hsbSaturationT
);
934 panel
->hsbBrightnessS
= WMCreateSlider(panel
->hsbFrm
);
935 WMResizeWidget(panel
->hsbBrightnessS
, 141, 16);
936 WMMoveWidget(panel
->hsbBrightnessS
, 2, 58);
937 WMSetSliderMinValue(panel
->hsbBrightnessS
, 0);
938 WMSetSliderMaxValue(panel
->hsbBrightnessS
, 100);
939 WMSetSliderKnobThickness(panel
->hsbBrightnessS
, knobThickness
);
940 WMSetSliderAction(panel
->hsbBrightnessS
, hsbSliderCallback
, panel
);
942 panel
->hsbBrightnessT
= WMCreateTextField(panel
->hsbFrm
);
943 WMResizeWidget(panel
->hsbBrightnessT
, 40, 18);
944 WMMoveWidget(panel
->hsbBrightnessT
, 146, 57);
945 WMSetTextFieldAlignment(panel
->hsbBrightnessT
, WALeft
);
946 WMAddNotificationObserver(hsbTextFieldCallback
, panel
,
947 WMTextDidEndEditingNotification
, panel
->hsbBrightnessT
);
948 /* End of HSB Panel */
950 WMReleaseColor(textcolor
);
952 /* Widgets for the CustomPalette Panel */
953 panel
->customPaletteFrm
= WMCreateFrame(panel
->win
);
954 WMSetFrameRelief(panel
->customPaletteFrm
, WRFlat
);
955 WMResizeWidget(panel
->customPaletteFrm
, PWIDTH
- 8, PHEIGHT
- 80 - 26);
956 WMMoveWidget(panel
->customPaletteFrm
, 5, 80);
958 panel
->customPaletteHistoryBtn
= WMCreatePopUpButton(panel
->customPaletteFrm
);
959 WMAddPopUpButtonItem(panel
->customPaletteHistoryBtn
, _("Spectrum"));
960 WMSetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
,
961 WMGetPopUpButtonNumberOfItems(panel
->customPaletteHistoryBtn
) - 1);
962 WMSetPopUpButtonAction(panel
->customPaletteHistoryBtn
, customPaletteHistoryCallback
, panel
);
963 WMResizeWidget(panel
->customPaletteHistoryBtn
, PWIDTH
- 8, 20);
964 WMMoveWidget(panel
->customPaletteHistoryBtn
, 0, 0);
966 panel
->customPaletteContentFrm
= WMCreateFrame(panel
->customPaletteFrm
);
967 WMSetFrameRelief(panel
->customPaletteContentFrm
, WRSunken
);
968 WMResizeWidget(panel
->customPaletteContentFrm
, PWIDTH
- 8, PHEIGHT
- 156);
969 WMMoveWidget(panel
->customPaletteContentFrm
, 0, 23);
971 panel
->customPaletteContentView
= W_CreateView(W_VIEW(panel
->customPaletteContentFrm
));
972 /* XXX Test if we can create a view */
973 W_ResizeView(panel
->customPaletteContentView
, customPaletteWidth
, customPaletteHeight
);
974 W_MoveView(panel
->customPaletteContentView
, 2, 2);
976 /* Create event handler to handle expose/click events in CustomPalette */
977 WMCreateEventHandler(panel
->customPaletteContentView
,
978 ButtonPressMask
| ButtonReleaseMask
| EnterWindowMask
| LeaveWindowMask
|
979 ButtonMotionMask
, customPaletteHandleActionEvents
, panel
);
981 WMCreateEventHandler(panel
->customPaletteContentView
, ExposureMask
, customPaletteHandleEvents
, panel
);
983 panel
->customPaletteMenuBtn
= WMCreatePopUpButton(panel
->customPaletteFrm
);
984 WMSetPopUpButtonPullsDown(panel
->customPaletteMenuBtn
, 1);
985 WMSetPopUpButtonText(panel
->customPaletteMenuBtn
, _("Palette"));
986 WMSetPopUpButtonAction(panel
->customPaletteMenuBtn
, customPaletteMenuCallback
, panel
);
987 WMResizeWidget(panel
->customPaletteMenuBtn
, PWIDTH
- 8, 20);
988 WMMoveWidget(panel
->customPaletteMenuBtn
, 0, PHEIGHT
- 130);
990 WMAddPopUpButtonItem(panel
->customPaletteMenuBtn
, _("New from File..."));
991 WMAddPopUpButtonItem(panel
->customPaletteMenuBtn
, _("Rename..."));
992 WMAddPopUpButtonItem(panel
->customPaletteMenuBtn
, _("Remove"));
993 WMAddPopUpButtonItem(panel
->customPaletteMenuBtn
, _("Copy"));
994 WMAddPopUpButtonItem(panel
->customPaletteMenuBtn
, _("New from Clipboard"));
996 WMSetPopUpButtonItemEnabled(panel
->customPaletteMenuBtn
, CPmenuRename
, 0);
997 WMSetPopUpButtonItemEnabled(panel
->customPaletteMenuBtn
, CPmenuRemove
, 0);
998 WMSetPopUpButtonItemEnabled(panel
->customPaletteMenuBtn
, CPmenuCopy
, 0);
999 WMSetPopUpButtonItemEnabled(panel
->customPaletteMenuBtn
, CPmenuNewFromClipboard
, 0);
1001 customRenderSpectrum(panel
);
1002 panel
->currentPalette
= 0;
1003 panel
->palx
= customPaletteWidth
/ 2;
1004 panel
->paly
= customPaletteHeight
/ 2;
1006 /* Widgets for the ColorList Panel */
1007 panel
->colorListFrm
= WMCreateFrame(panel
->win
);
1008 WMSetFrameRelief(panel
->colorListFrm
, WRFlat
);
1009 WMResizeWidget(panel
->colorListFrm
, PWIDTH
- 8, PHEIGHT
- 80 - 26);
1010 WMMoveWidget(panel
->colorListFrm
, 5, 80);
1012 panel
->colorListHistoryBtn
= WMCreatePopUpButton(panel
->colorListFrm
);
1013 WMAddPopUpButtonItem(panel
->colorListHistoryBtn
, _("X11-Colors"));
1014 WMSetPopUpButtonSelectedItem(panel
->colorListHistoryBtn
,
1015 WMGetPopUpButtonNumberOfItems(panel
->colorListHistoryBtn
) - 1);
1016 /* WMSetPopUpButtonAction(panel->colorListHistoryBtn,
1017 * colorListHistoryCallback, panel); */
1018 WMResizeWidget(panel
->colorListHistoryBtn
, PWIDTH
- 8, 20);
1019 WMMoveWidget(panel
->colorListHistoryBtn
, 0, 0);
1021 panel
->colorListContentLst
= WMCreateList(panel
->colorListFrm
);
1022 WMSetListAction(panel
->colorListContentLst
, colorListSelect
, panel
);
1023 WMSetListUserDrawProc(panel
->colorListContentLst
, colorListPaintItem
);
1024 WMResizeWidget(panel
->colorListContentLst
, PWIDTH
- 8, PHEIGHT
- 156);
1025 WMMoveWidget(panel
->colorListContentLst
, 0, 23);
1026 WMHangData(panel
->colorListContentLst
, panel
);
1028 panel
->colorListColorMenuBtn
= WMCreatePopUpButton(panel
->colorListFrm
);
1029 WMSetPopUpButtonPullsDown(panel
->colorListColorMenuBtn
, 1);
1030 WMSetPopUpButtonText(panel
->colorListColorMenuBtn
, _("Color"));
1031 WMSetPopUpButtonAction(panel
->colorListColorMenuBtn
, colorListColorMenuCallback
, panel
);
1032 WMResizeWidget(panel
->colorListColorMenuBtn
, (PWIDTH
- 16) / 2, 20);
1033 WMMoveWidget(panel
->colorListColorMenuBtn
, 0, PHEIGHT
- 130);
1035 WMAddPopUpButtonItem(panel
->colorListColorMenuBtn
, _("Add..."));
1036 WMAddPopUpButtonItem(panel
->colorListColorMenuBtn
, _("Rename..."));
1037 WMAddPopUpButtonItem(panel
->colorListColorMenuBtn
, _("Remove"));
1039 WMSetPopUpButtonItemEnabled(panel
->colorListColorMenuBtn
, CLmenuAdd
, 0);
1040 WMSetPopUpButtonItemEnabled(panel
->colorListColorMenuBtn
, CLmenuRename
, 0);
1041 WMSetPopUpButtonItemEnabled(panel
->colorListColorMenuBtn
, CLmenuRemove
, 0);
1043 panel
->colorListListMenuBtn
= WMCreatePopUpButton(panel
->colorListFrm
);
1044 WMSetPopUpButtonPullsDown(panel
->colorListListMenuBtn
, 1);
1045 WMSetPopUpButtonText(panel
->colorListListMenuBtn
, _("List"));
1046 WMSetPopUpButtonAction(panel
->colorListListMenuBtn
, colorListListMenuCallback
, panel
);
1047 WMResizeWidget(panel
->colorListListMenuBtn
, (PWIDTH
- 16) / 2, 20);
1048 WMMoveWidget(panel
->colorListListMenuBtn
, (PWIDTH
- 16) / 2 + 8, PHEIGHT
- 130);
1050 WMAddPopUpButtonItem(panel
->colorListListMenuBtn
, _("New..."));
1051 WMAddPopUpButtonItem(panel
->colorListListMenuBtn
, _("Rename..."));
1052 WMAddPopUpButtonItem(panel
->colorListListMenuBtn
, _("Remove"));
1054 WMSetPopUpButtonItemEnabled(panel
->colorListListMenuBtn
, CLmenuAdd
, 0);
1055 WMSetPopUpButtonItemEnabled(panel
->colorListListMenuBtn
, CLmenuRename
, 0);
1056 WMSetPopUpButtonItemEnabled(panel
->colorListListMenuBtn
, CLmenuRemove
, 0);
1058 WMRealizeWidget(panel
->win
);
1059 WMMapSubwidgets(panel
->win
);
1061 WMMapSubwidgets(panel
->wheelFrm
);
1062 WMMapSubwidgets(panel
->slidersFrm
);
1063 WMMapSubwidgets(panel
->grayFrm
);
1064 WMMapSubwidgets(panel
->rgbFrm
);
1065 WMMapSubwidgets(panel
->cmykFrm
);
1066 WMMapSubwidgets(panel
->hsbFrm
);
1067 WMMapSubwidgets(panel
->customPaletteFrm
);
1068 WMMapSubwidgets(panel
->customPaletteContentFrm
);
1069 WMMapSubwidgets(panel
->colorListFrm
);
1071 /* Pixmap to indicate selection positions
1072 * wheelframe MUST be mapped.
1074 panel
->selectionImg
= XCreatePixmap(scrPtr
->display
, WMWidgetXID(panel
->win
), 4, 4, scrPtr
->depth
);
1075 XFillRectangle(scrPtr
->display
, panel
->selectionImg
, bgc
, 0, 0, 4, 4);
1076 XFillRectangle(scrPtr
->display
, panel
->selectionImg
, wgc
, 1, 1, 2, 2);
1078 readConfiguration(panel
);
1084 WMColorPanel
*WMGetColorPanel(WMScreen
* scrPtr
)
1086 WMColorPanel
*panel
;
1088 if (scrPtr
->sharedColorPanel
)
1089 return scrPtr
->sharedColorPanel
;
1091 panel
= makeColorPanel(scrPtr
, "colorPanel");
1093 scrPtr
->sharedColorPanel
= panel
;
1098 void WMFreeColorPanel(WMColorPanel
* panel
)
1105 scr
= WMWidgetScreen(panel
->win
);
1106 if (panel
== scr
->sharedColorPanel
) {
1107 scr
->sharedColorPanel
= NULL
;
1110 WMRemoveNotificationObserver(panel
);
1111 WMUnmapWidget(panel
->win
);
1114 WMReleaseFont(panel
->font8
);
1115 WMReleaseFont(panel
->font12
);
1118 wheelDestroyMatrix(panel
->wheelMtrx
);
1119 if (panel
->wheelImg
)
1120 XFreePixmap(scr
->display
, panel
->wheelImg
);
1121 if (panel
->selectionImg
)
1122 XFreePixmap(scr
->display
, panel
->selectionImg
);
1123 if (panel
->selectionBackImg
)
1124 XFreePixmap(scr
->display
, panel
->selectionBackImg
);
1125 RReleaseImage(panel
->customPaletteImg
);
1128 if (panel
->lastBrowseDir
)
1129 wfree(panel
->lastBrowseDir
);
1130 if (panel
->configurationPath
)
1131 wfree(panel
->configurationPath
);
1133 WMDestroyWidget(panel
->win
);
1138 void WMCloseColorPanel(WMColorPanel
* panel
)
1140 WMFreeColorPanel(panel
);
1143 void WMShowColorPanel(WMColorPanel
* panel
)
1145 WMScreen
*scr
= WMWidgetScreen(panel
->win
);
1146 WMColor
*white
= WMWhiteColor(scr
);
1148 if (panel
->color
.set
== cpNone
)
1149 WMSetColorPanelColor(panel
, white
);
1150 WMReleaseColor(white
);
1152 if (panel
->mode
!= WMWheelModeColorPanel
)
1153 WMPerformButtonClick(panel
->wheelBtn
);
1155 WMMapWidget(panel
->win
);
1158 static void closeWindowCallback(WMWidget
* w
, void *data
)
1160 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
1162 /* Parameter not used, but tell the compiler that it is ok */
1165 WMCloseColorPanel(panel
);
1168 static void readConfiguration(W_ColorPanel
* panel
)
1170 /* XXX Doesn't take care of "invalid" files */
1174 struct stat stat_buf
;
1177 if (stat(panel
->configurationPath
, &stat_buf
) != 0) {
1178 if (mkdir(panel
->configurationPath
, S_IRWXU
| S_IRGRP
| S_IROTH
| S_IXGRP
| S_IXOTH
) != 0) {
1179 werror(_("Color Panel: Could not create directory %s needed"
1180 " to store configurations"), panel
->configurationPath
);
1181 WMSetPopUpButtonEnabled(panel
->customPaletteMenuBtn
, False
);
1182 WMSetPopUpButtonEnabled(panel
->colorListColorMenuBtn
, False
);
1183 WMSetPopUpButtonEnabled(panel
->colorListListMenuBtn
, False
);
1184 WMRunAlertPanel(WMWidgetScreen(panel
->win
), panel
->win
,
1186 _("Could not create ColorPanel configuration directory"),
1187 _("OK"), NULL
, NULL
);
1192 if (!(dPtr
= opendir(panel
->configurationPath
))) {
1193 wwarning("%s: %s", _("Color Panel: Could not find file"), panel
->configurationPath
);
1197 while ((dp
= readdir(dPtr
)) != NULL
) {
1198 unsigned int perm_mask
;
1199 char *path
= wstrconcat(panel
->configurationPath
,
1202 if (dp
->d_name
[0] != '.') {
1203 item
= WMGetPopUpButtonNumberOfItems(panel
->customPaletteHistoryBtn
);
1204 WMAddPopUpButtonItem(panel
->customPaletteHistoryBtn
, dp
->d_name
);
1206 perm_mask
= (access(path
, R_OK
) == 0);
1207 WMSetPopUpButtonItemEnabled(panel
->customPaletteHistoryBtn
, item
, perm_mask
);
1214 static void readXColors(W_ColorPanel
* panel
)
1217 const RGBColor
*entry
;
1219 for (entry
= rgbColors
; entry
->name
!= NULL
; entry
++) {
1220 item
= WMAddListItem(panel
->colorListContentLst
, entry
->name
);
1221 item
->clientData
= (void *)&(entry
->color
);
1225 void WMSetColorPanelPickerMode(WMColorPanel
* panel
, WMColorPanelMode mode
)
1227 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1229 if (mode
!= WMWheelModeColorPanel
) {
1230 WMUnmapWidget(panel
->wheelFrm
);
1231 if (panel
->selectionBackImg
) {
1232 XFreePixmap(WMWidgetScreen(panel
->win
)->display
, panel
->selectionBackImg
);
1233 panel
->selectionBackImg
= None
;
1236 if (mode
!= WMGrayModeColorPanel
)
1237 WMUnmapWidget(panel
->grayFrm
);
1238 if (mode
!= WMRGBModeColorPanel
)
1239 WMUnmapWidget(panel
->rgbFrm
);
1240 if (mode
!= WMCMYKModeColorPanel
)
1241 WMUnmapWidget(panel
->cmykFrm
);
1242 if (mode
!= WMHSBModeColorPanel
)
1243 WMUnmapWidget(panel
->hsbFrm
);
1244 if (mode
!= WMCustomPaletteModeColorPanel
) {
1245 WMUnmapWidget(panel
->customPaletteFrm
);
1246 if (panel
->selectionBackImg
) {
1247 XFreePixmap(WMWidgetScreen(panel
->win
)->display
, panel
->selectionBackImg
);
1248 panel
->selectionBackImg
= None
;
1251 if (mode
!= WMColorListModeColorPanel
)
1252 WMUnmapWidget(panel
->colorListFrm
);
1253 if ((mode
!= WMGrayModeColorPanel
) && (mode
!= WMRGBModeColorPanel
) &&
1254 (mode
!= WMCMYKModeColorPanel
) && (mode
!= WMHSBModeColorPanel
))
1255 WMUnmapWidget(panel
->slidersFrm
);
1257 panel
->slidersmode
= mode
;
1259 if (mode
== WMWheelModeColorPanel
) {
1260 WMMapWidget(panel
->wheelFrm
);
1261 WMSetButtonSelected(panel
->wheelBtn
, True
);
1262 if (panel
->lastChanged
!= WMWheelModeColorPanel
)
1266 } else if (mode
== WMGrayModeColorPanel
) {
1267 WMMapWidget(panel
->slidersFrm
);
1268 WMSetButtonSelected(panel
->slidersBtn
, True
);
1269 WMMapWidget(panel
->grayFrm
);
1270 WMSetButtonSelected(panel
->grayBtn
, True
);
1271 WMSetButtonImage(panel
->slidersBtn
, scr
->grayIcon
);
1272 if (panel
->lastChanged
!= WMGrayModeColorPanel
)
1274 } else if (mode
== WMRGBModeColorPanel
) {
1275 WMMapWidget(panel
->slidersFrm
);
1276 WMSetButtonSelected(panel
->slidersBtn
, True
);
1277 WMMapWidget(panel
->rgbFrm
);
1278 WMSetButtonSelected(panel
->rgbBtn
, True
);
1279 WMSetButtonImage(panel
->slidersBtn
, scr
->rgbIcon
);
1280 if (panel
->lastChanged
!= WMRGBModeColorPanel
)
1282 } else if (mode
== WMCMYKModeColorPanel
) {
1283 WMMapWidget(panel
->slidersFrm
);
1284 WMSetButtonSelected(panel
->slidersBtn
, True
);
1285 WMMapWidget(panel
->cmykFrm
);
1286 WMSetButtonSelected(panel
->cmykBtn
, True
);
1287 WMSetButtonImage(panel
->slidersBtn
, scr
->cmykIcon
);
1288 if (panel
->lastChanged
!= WMCMYKModeColorPanel
)
1290 } else if (mode
== WMHSBModeColorPanel
) {
1291 WMMapWidget(panel
->slidersFrm
);
1292 WMSetButtonSelected(panel
->slidersBtn
, True
);
1293 WMMapWidget(panel
->hsbFrm
);
1294 WMSetButtonSelected(panel
->hsbBtn
, True
);
1295 WMSetButtonImage(panel
->slidersBtn
, scr
->hsbIcon
);
1296 if (panel
->lastChanged
!= WMHSBModeColorPanel
)
1298 } else if (mode
== WMCustomPaletteModeColorPanel
) {
1299 WMMapWidget(panel
->customPaletteFrm
);
1300 WMSetButtonSelected(panel
->customPaletteBtn
, True
);
1301 customSetPalette(panel
);
1302 } else if (mode
== WMColorListModeColorPanel
) {
1303 WMMapWidget(panel
->colorListFrm
);
1304 WMSetButtonSelected(panel
->colorListBtn
, True
);
1310 WMColor
*WMGetColorPanelColor(WMColorPanel
* panel
)
1312 return WMGetColorWellColor(panel
->colorWell
);
1315 void WMSetColorPanelColor(WMColorPanel
* panel
, WMColor
* color
)
1317 WMSetColorWellColor(panel
->colorWell
, color
);
1319 panel
->color
.rgb
.red
= color
->color
.red
>> 8;
1320 panel
->color
.rgb
.green
= color
->color
.green
>> 8;
1321 panel
->color
.rgb
.blue
= color
->color
.blue
>> 8;
1322 panel
->color
.set
= cpRGB
;
1324 if (panel
->mode
== panel
->lastChanged
)
1325 panel
->lastChanged
= 0;
1327 WMSetColorPanelPickerMode(panel
, panel
->mode
);
1330 static void updateSwatch(WMColorPanel
* panel
, CPColor color
)
1332 WMScreen
*scr
= WMWidgetScreen(panel
->win
);
1335 if (color
.set
!= cpRGB
)
1336 convertCPColor(&color
);
1338 panel
->color
= color
;
1340 wellcolor
= WMCreateRGBColor(scr
, color
.rgb
.red
<< 8, color
.rgb
.green
<< 8, color
.rgb
.blue
<< 8, True
);
1342 WMSetColorWellColor(panel
->colorWell
, wellcolor
);
1343 WMReleaseColor(wellcolor
);
1345 if (!panel
->flags
.dragging
|| panel
->flags
.continuous
) {
1347 (*panel
->action
) (panel
, panel
->clientData
);
1349 WMPostNotificationName(WMColorPanelColorChangedNotification
, panel
, NULL
);
1353 static void modeButtonCallback(WMWidget
* w
, void *data
)
1355 W_ColorPanel
*panel
= (W_ColorPanel
*) (data
);
1357 if (w
== panel
->wheelBtn
)
1358 WMSetColorPanelPickerMode(panel
, WMWheelModeColorPanel
);
1359 else if (w
== panel
->slidersBtn
)
1360 WMSetColorPanelPickerMode(panel
, panel
->slidersmode
);
1361 else if (w
== panel
->customPaletteBtn
)
1362 WMSetColorPanelPickerMode(panel
, WMCustomPaletteModeColorPanel
);
1363 else if (w
== panel
->colorListBtn
)
1364 WMSetColorPanelPickerMode(panel
, WMColorListModeColorPanel
);
1365 else if (w
== panel
->grayBtn
)
1366 WMSetColorPanelPickerMode(panel
, WMGrayModeColorPanel
);
1367 else if (w
== panel
->rgbBtn
)
1368 WMSetColorPanelPickerMode(panel
, WMRGBModeColorPanel
);
1369 else if (w
== panel
->cmykBtn
)
1370 WMSetColorPanelPickerMode(panel
, WMCMYKModeColorPanel
);
1371 else if (w
== panel
->hsbBtn
)
1372 WMSetColorPanelPickerMode(panel
, WMHSBModeColorPanel
);
1375 /****************** Magnifying Cursor Functions *******************/
1377 static XImage
*magnifyGetImage(WMScreen
* scr
, XImage
* image
, int x
, int y
, int w
, int h
)
1379 int x0
= 0, y0
= 0, w0
= w
, h0
= h
;
1380 const int displayWidth
= DisplayWidth(scr
->display
, scr
->screen
),
1381 displayHeight
= DisplayHeight(scr
->display
, scr
->screen
);
1383 if (!(image
&& image
->data
)) {
1384 /* The image in panel->magnifyGlass->image does not exist yet.
1385 * Grab one from the screen (not beyond) and use it from now on.
1387 if (!(image
= XGetImage(scr
->display
, scr
->rootWin
,
1388 x
- Cursor_x_hot
, y
- Cursor_y_hot
, w
, h
, AllPlanes
, ZPixmap
)))
1389 wwarning(_("Color Panel: X failed request"));
1394 /* Coordinate correction for back pixmap
1395 * if magnifying glass is at screen-borders
1398 /* Figure 1: Shifting of rectangle-to-grab at top/left screen borders
1399 * Hatched area is beyond screen border.
1401 * |<-Cursor_x_hot->|
1402 * ________________|_____
1403 * |/ / / / / / /| | |
1404 * | / / / / / / |(x,y) |
1405 * |/_/_/_/_/_/_/|________|
1406 * |<----x0----->|<--w0-->|
1410 /* Figure 2: Shifting of rectangle-to-grab at bottom/right
1412 * Hatched area is beyond screen border
1414 * |<-Cursor_x_hot->|
1415 * ________________|_______________
1416 * | | | / / / / / /|
1417 * | (x,y)|/ / / / / / |
1418 * |___________________|_/_/_/_/_/_/|
1419 * |<-------w0-------->| |
1420 * |<---------------w--|----------->|
1425 if (x
< Cursor_x_hot
) { /* see fig. 1 */
1426 x0
= Cursor_x_hot
- x
;
1430 if (displayWidth
- 1 < x
- Cursor_x_hot
+ w
) { /* see fig. 2 */
1431 w0
= (displayWidth
) - (x
- Cursor_x_hot
);
1434 if (y
< Cursor_y_hot
) { /* see fig. 1 */
1435 y0
= Cursor_y_hot
- y
;
1439 if (displayHeight
- 1 < y
- Cursor_y_hot
+ h
) { /* see fig. 2 */
1440 h0
= (displayHeight
) - (y
- Cursor_y_hot
);
1442 /* end of coordinate correction */
1444 /* Grab an image from the screen, clipped if necessary,
1445 * and put it in the existing panel->magnifyGlass->image
1446 * with the corresponding clipping offset.
1448 if (!XGetSubImage(scr
->display
, scr
->rootWin
,
1449 x
- Cursor_x_hot
+ x0
, y
- Cursor_y_hot
+ y0
, w0
, h0
, AllPlanes
, ZPixmap
, image
, x0
, y0
))
1450 wwarning(_("Color Panel: X failed request"));
1455 static void magnifyGetImageStored(WMColorPanel
* panel
, int x1
, int y1
, int x2
, int y2
)
1457 /* (x1, y1) = topleft corner of existing rectangle
1458 * (x2, y2) = topleft corner of new position
1461 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1462 int xa
= 0, ya
= 0, xb
= 0, yb
= 0;
1464 const int dx
= abs(x2
- x1
), dy
= abs(y2
- y1
);
1466 const int x_min
= Cursor_x_hot
,
1467 y_min
= Cursor_y_hot
,
1468 x_max
= DisplayWidth(scr
->display
, scr
->screen
) - 1 -
1469 (Cursor_mask_width
- Cursor_x_hot
),
1470 y_max
= DisplayHeight(scr
->display
, scr
->screen
) - 1 - (Cursor_mask_height
- Cursor_y_hot
);
1472 if ((dx
== 0) && (dy
== 0) && panel
->magnifyGlass
->image
)
1473 return; /* No movement */
1485 width
= Cursor_mask_width
- dx
;
1486 height
= Cursor_mask_height
- dy
;
1488 /* If the traversed distance is larger than the size of the magnifying
1489 * glass contents, there is no need to do dirty rectangles. A whole new
1490 * rectangle can be grabbed (unless that rectangle falls partially
1492 * Destroying the image and setting it to NULL will achieve that later on.
1494 * Of course, grabbing an XImage beyond the borders of the screen will
1495 * cause trouble, this is considdered a special case. Part of the screen
1496 * is grabbed, but there is no need for dirty rectangles.
1498 if ((width
<= 0) || (height
<= 0)) {
1499 if ((x2
>= x_min
) && (y2
>= y_min
) && (x2
<= x_max
) && (y2
<= y_max
)) {
1500 if (panel
->magnifyGlass
->image
)
1501 XDestroyImage(panel
->magnifyGlass
->image
);
1502 panel
->magnifyGlass
->image
= NULL
;
1505 if (panel
->magnifyGlass
->image
) {
1506 /* Get dirty rectangle from panel->magnifyGlass->image */
1507 panel
->magnifyGlass
->dirtyRect
=
1508 XSubImage(panel
->magnifyGlass
->image
, xa
, ya
, width
, height
);
1509 if (!panel
->magnifyGlass
->dirtyRect
) {
1510 wwarning(_("Color Panel: X failed request"));
1511 return; /* X returned a NULL from XSubImage */
1516 /* Get image from screen */
1517 image
= magnifyGetImage(scr
, panel
->magnifyGlass
->image
, x2
, y2
, Cursor_mask_width
, Cursor_mask_height
);
1518 if (image
) { /* Only reassign if a *new* image was grabbed */
1519 panel
->magnifyGlass
->image
= image
;
1523 /* Copy previously stored rectangle on covered part of image */
1524 if (panel
->magnifyGlass
->image
&& panel
->magnifyGlass
->dirtyRect
) {
1527 /* "width" and "height" are used as coordinates here,
1528 * and run from [0...width-1] and [0...height-1] respectively.
1532 old_height
= height
;
1534 for (; width
>= 0; width
--)
1535 for (height
= old_height
; height
>= 0; height
--)
1536 XPutPixel(panel
->magnifyGlass
->image
, xb
+ width
, yb
+ height
,
1537 XGetPixel(panel
->magnifyGlass
->dirtyRect
, width
, height
));
1538 XDestroyImage(panel
->magnifyGlass
->dirtyRect
);
1539 panel
->magnifyGlass
->dirtyRect
= NULL
;
1545 static Pixmap
magnifyCreatePixmap(WMColorPanel
* panel
)
1547 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1552 unsigned long color
;
1554 if (!panel
->magnifyGlass
->image
)
1557 if (!panel
->magnifyGlass
->magPix
)
1561 * Copy an area of only 5x5 pixels from the center of the image.
1563 for (u
= 0; u
< 5; u
++) {
1564 for (v
= 0; v
< 5; v
++) {
1565 color
= XGetPixel(panel
->magnifyGlass
->image
, u
+ 9, v
+ 9);
1567 XSetForeground(scr
->display
, scr
->copyGC
, color
);
1569 if ((u
== 2) && (v
== 2)) /* (2,2) is center pixel (unmagn.) */
1570 panel
->magnifyGlass
->color
= ulongToRColor(scr
, color
);
1572 /* The center square must eventually be centered around the
1573 * hotspot. The image needs shifting to achieve this. The amount of
1574 * shifting is (Cursor_mask_width/2 - 2 * square_size) = 11-10 = 1
1577 * ^------- center of center square == Cursor_x_hot
1579 XFillRectangle(scr
->display
, panel
->magnifyGlass
->magPix
,
1581 u
* 5 + (u
== 0 ? 0 : -1), v
* 5 + (v
== 0 ? 0 : -1),
1582 (u
== 0 ? 4 : 5), (v
== 0 ? 4 : 5));
1587 return panel
->magnifyGlass
->magPix
;
1589 pixmap
= XCreatePixmap(scr
->display
, W_DRAWABLE(scr
), Cursor_mask_width
, Cursor_mask_height
, scr
->depth
);
1593 XPutImage(scr
->display
, pixmap
, scr
->copyGC
, panel
->magnifyGlass
->image
,
1594 0, 0, 0, 0, Cursor_mask_width
, Cursor_mask_height
);
1596 /* Copy the magnified pixmap, with the clip mask, to background pixmap */
1597 XCopyArea(scr
->display
, panel
->magnifyGlass
->magPix
, pixmap
,
1598 scr
->clipGC
, 0, 0, Cursor_mask_width
, Cursor_mask_height
, 0, 0);
1599 /* (2,2) puts center pixel on center of glass */
1606 static WMView
*magnifyCreateView(W_ColorPanel
* panel
)
1608 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1611 magView
= W_CreateTopView(scr
);
1615 magView
->self
= panel
->win
;
1616 magView
->flags
.topLevel
= 1;
1617 magView
->attribFlags
|= CWOverrideRedirect
| CWSaveUnder
;
1618 magView
->attribs
.override_redirect
= True
;
1619 magView
->attribs
.save_under
= True
;
1621 W_ResizeView(magView
, Cursor_mask_width
, Cursor_mask_height
);
1623 W_RealizeView(magView
);
1628 static Cursor
magnifyGrabPointer(W_ColorPanel
* panel
)
1630 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1631 Pixmap magPixmap
, magPixmap2
;
1633 XColor fgColor
= { 0, 0, 0, 0, DoRed
| DoGreen
| DoBlue
, 0 };
1634 XColor bgColor
= { 0, 0xbf00, 0xa000, 0x5000, DoRed
| DoGreen
| DoBlue
, 0 };
1636 /* Cursor creation stuff */
1637 magPixmap
= XCreatePixmapFromBitmapData(scr
->display
, W_DRAWABLE(scr
),
1638 (char *)Cursor_bits
, Cursor_width
, Cursor_height
, 1, 0, 1);
1639 magPixmap2
= XCreatePixmapFromBitmapData(scr
->display
, W_DRAWABLE(scr
),
1640 (char *)Cursor_shape_bits
, Cursor_width
, Cursor_height
, 1, 0, 1);
1642 magCursor
= XCreatePixmapCursor(scr
->display
, magPixmap
, magPixmap2
,
1643 &fgColor
, &bgColor
, Cursor_x_hot
, Cursor_y_hot
);
1645 XFreePixmap(scr
->display
, magPixmap
);
1646 XFreePixmap(scr
->display
, magPixmap2
);
1648 XRecolorCursor(scr
->display
, magCursor
, &fgColor
, &bgColor
);
1650 /* Set up Pointer */
1651 XGrabPointer(scr
->display
, panel
->magnifyGlass
->view
->window
, True
,
1652 PointerMotionMask
| ButtonPressMask
,
1653 GrabModeAsync
, GrabModeAsync
, scr
->rootWin
, magCursor
, CurrentTime
);
1658 static WMPoint
magnifyInitialize(W_ColorPanel
* panel
)
1660 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1663 Pixmap pixmap
, clip_mask
;
1665 Window root_return
, child_return
;
1667 clip_mask
= XCreatePixmapFromBitmapData(scr
->display
, W_DRAWABLE(scr
),
1668 (char *)Cursor_mask_bits
, Cursor_mask_width
, Cursor_mask_height
,
1670 panel
->magnifyGlass
->magPix
= XCreatePixmap(scr
->display
, W_DRAWABLE(scr
),
1671 5 * 5 - 1, 5 * 5 - 1, scr
->depth
);
1673 XQueryPointer(scr
->display
, scr
->rootWin
, &root_return
, &child_return
, &x
, &y
, &u
, &v
, &mask
);
1675 panel
->magnifyGlass
->image
= NULL
;
1677 /* Clipmask to make magnified view-contents circular */
1679 XShapeCombineMask(scr
->display
, WMViewXID(panel
->magnifyGlass
->view
),
1680 ShapeBounding
, 0, 0, clip_mask
, ShapeSet
);
1682 /* Clip circle in glass cursor */
1683 XSetClipMask(scr
->display
, scr
->clipGC
, clip_mask
);
1684 XSetClipOrigin(scr
->display
, scr
->clipGC
, 0, 0);
1687 XFreePixmap(scr
->display
, clip_mask
);
1689 /* Draw initial magnifying glass contents */
1690 magnifyGetImageStored(panel
, x
, y
, x
, y
);
1692 pixmap
= magnifyCreatePixmap(panel
);
1693 XSetWindowBackgroundPixmap(scr
->display
, WMViewXID(panel
->magnifyGlass
->view
), pixmap
);
1694 XClearWindow(scr
->display
, WMViewXID(panel
->magnifyGlass
->view
));
1695 XFlush(scr
->display
);
1698 XFreePixmap(scr
->display
, pixmap
);
1707 static void magnifyPutCursor(WMWidget
* w
, void *data
)
1709 W_ColorPanel
*panel
= (W_ColorPanel
*) (data
);
1710 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
1714 WMPoint initialPosition
;
1716 /* Parameter not used, but tell the compiler that it is ok */
1719 /* Destroy wheelBackImg, so it'll update properly */
1720 if (panel
->selectionBackImg
) {
1721 XFreePixmap(WMWidgetScreen(panel
->win
)->display
, panel
->selectionBackImg
);
1722 panel
->selectionBackImg
= None
;
1725 /* Create magnifying glass */
1726 panel
->magnifyGlass
= wmalloc(sizeof(MovingView
));
1727 panel
->magnifyGlass
->view
= magnifyCreateView(panel
);
1728 if (!panel
->magnifyGlass
->view
)
1731 initialPosition
= magnifyInitialize(panel
);
1732 panel
->magnifyGlass
->x
= initialPosition
.x
;
1733 panel
->magnifyGlass
->y
= initialPosition
.y
;
1735 W_MoveView(panel
->magnifyGlass
->view
,
1736 panel
->magnifyGlass
->x
- Cursor_x_hot
, panel
->magnifyGlass
->y
- Cursor_y_hot
);
1737 W_MapView(panel
->magnifyGlass
->view
);
1739 magCursor
= magnifyGrabPointer(panel
);
1741 while (panel
->magnifyGlass
->image
) {
1742 WMNextEvent(scr
->display
, &event
);
1744 /* Pack motion events */
1745 while (XCheckTypedEvent(scr
->display
, MotionNotify
, &event
)) {
1748 switch (event
.type
) {
1750 XDestroyImage(panel
->magnifyGlass
->image
);
1751 panel
->magnifyGlass
->image
= NULL
;
1753 if (event
.xbutton
.button
== Button1
) {
1754 panel
->color
.rgb
= panel
->magnifyGlass
->color
;
1755 panel
->color
.set
= cpRGB
;
1756 updateSwatch(panel
, panel
->color
);
1758 switch (panel
->mode
) {
1759 case WMWheelModeColorPanel
:
1764 case WMGrayModeColorPanel
:
1767 case WMRGBModeColorPanel
:
1770 case WMCMYKModeColorPanel
:
1773 case WMHSBModeColorPanel
:
1779 panel
->lastChanged
= panel
->mode
;
1781 WMSetButtonSelected(panel
->magnifyBtn
, False
);
1785 while (XPending(event
.xmotion
.display
)) {
1787 XPeekEvent(event
.xmotion
.display
, &ev
);
1788 if (ev
.type
== MotionNotify
)
1789 XNextEvent(event
.xmotion
.display
, &event
);
1794 /* Get a "dirty rectangle" */
1795 magnifyGetImageStored(panel
,
1796 panel
->magnifyGlass
->x
, panel
->magnifyGlass
->y
,
1797 event
.xmotion
.x_root
, event
.xmotion
.y_root
);
1799 /* Update coordinates */
1800 panel
->magnifyGlass
->x
= event
.xmotion
.x_root
;
1801 panel
->magnifyGlass
->y
= event
.xmotion
.y_root
;
1804 W_MoveView(panel
->magnifyGlass
->view
,
1805 panel
->magnifyGlass
->x
- Cursor_x_hot
, panel
->magnifyGlass
->y
- Cursor_y_hot
);
1807 /* Put new image (with magn.) in view */
1808 pixmap
= magnifyCreatePixmap(panel
);
1809 if (pixmap
!= None
) {
1810 /* Change the window background */
1811 XSetWindowBackgroundPixmap(scr
->display
,
1812 WMViewXID(panel
->magnifyGlass
->view
), pixmap
);
1813 /* Force an Expose (handled by X) */
1814 XClearWindow(scr
->display
, WMViewXID(panel
->magnifyGlass
->view
));
1815 /* Synchronize the event queue, so the Expose is handled NOW */
1816 XFlush(scr
->display
);
1818 XFreePixmap(scr
->display
, pixmap
);
1823 /* Try XQueryPointer for this !!! It returns windows that the pointer
1824 * is over. Note: We found this solving the invisible donkey cap bug
1826 #if 0 /* As it is impossible to make this work in all cases,
1827 * we consider it confusing. Therefore we disabled it.
1829 case FocusOut
: /* fall through */
1832 * Color Panel window (panel->win) lost or received focus.
1833 * We need to update the pixmap in the magnifying glass.
1835 * BUG Doesn't work with focus switches between two windows
1836 * if none of them is the color panel.
1838 XUngrabPointer(scr
->display
, CurrentTime
);
1839 W_UnmapView(panel
->magnifyGlass
->view
);
1841 magnifyInitialize(panel
);
1843 W_MapView(panel
->magnifyGlass
->view
);
1844 XGrabPointer(scr
->display
, panel
->magnifyGlass
->view
->window
,
1845 True
, PointerMotionMask
| ButtonPressMask
,
1846 GrabModeAsync
, GrabModeAsync
, scr
->rootWin
, magCursor
, CurrentTime
);
1850 WMHandleEvent(&event
);
1855 XUngrabPointer(scr
->display
, CurrentTime
);
1856 XFreeCursor(scr
->display
, magCursor
);
1858 XFreePixmap(scr
->display
, panel
->magnifyGlass
->magPix
);
1859 panel
->magnifyGlass
->magPix
= None
;
1861 W_UnmapView(panel
->magnifyGlass
->view
);
1862 W_DestroyView(panel
->magnifyGlass
->view
);
1863 panel
->magnifyGlass
->view
= NULL
;
1865 wfree(panel
->magnifyGlass
);
1868 /****************** ColorWheel Functions ************************/
1870 static wheelMatrix
*wheelCreateMatrix(unsigned int width
, unsigned int height
)
1872 wheelMatrix
*matrix
= NULL
;
1875 assert((width
> 0) && (height
> 0));
1877 matrix
= wmalloc(sizeof(wheelMatrix
));
1878 matrix
->width
= width
;
1879 matrix
->height
= height
;
1881 for (i
= 0; i
< 3; i
++) {
1882 matrix
->data
[i
] = wmalloc(width
* height
* sizeof(unsigned char));
1888 static void wheelDestroyMatrix(wheelMatrix
* matrix
)
1895 for (i
= 0; i
< 3; i
++) {
1896 if (matrix
->data
[i
])
1897 wfree(matrix
->data
[i
]);
1902 static void wheelInitMatrix(W_ColorPanel
* panel
)
1906 unsigned char *rp
, *gp
, *bp
;
1912 const int cw_halfsize
= (colorWheelSize
+ 4) / 2,
1913 cw_sqsize
= (colorWheelSize
+ 4) * (colorWheelSize
+ 4), uchar_shift
= getShift(sizeof(unsigned char));
1915 if (!panel
->wheelMtrx
)
1918 cpColor
.hsv
.value
= 255;
1919 cpColor
.set
= cpHSV
;
1922 ofs
[1] = -(colorWheelSize
+ 4);
1924 /* offsets are counterclockwise (in triangles).
1927 * _______________________________________
1928 * [1] |_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_| o
1929 * s |_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_| f
1930 * f |_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_| s
1931 * o | | | | | | | | | | | | | | | | | | | | | [3]
1935 * |\ /| <-- triangles
1941 for (y
= 0; y
< cw_halfsize
; y
++) {
1942 for (x
= y
; x
< (colorWheelSize
+ 4 - y
); x
++) {
1943 /* (xcor, ycor) is (x,y) relative to center of matrix */
1944 xcor
= 2 * x
- 4 - colorWheelSize
;
1945 ycor
= 2 * y
- 4 - colorWheelSize
;
1947 /* RColor.saturation is unsigned char and will wrap after 255 */
1948 sat
= rint(255.0 * sqrt(xcor
* xcor
+ ycor
* ycor
) / colorWheelSize
);
1950 cpColor
.hsv
.saturation
= (unsigned char)sat
;
1952 ofs
[0]++; /* top quarter of matrix */
1953 ofs
[1] += colorWheelSize
+ 4; /* left quarter */
1954 ofs
[2] = cw_sqsize
- 1 - ofs
[0]; /* bottom quarter */
1955 ofs
[3] = cw_sqsize
- 1 - ofs
[1]; /* right quarter */
1959 dhue
[0] = rint(atan((double)ycor
/ (double)xcor
) *
1960 (180.0 / M_PI
)) + (xcor
< 0 ? 180.0 : 0.0);
1964 dhue
[0] = 360 - dhue
[0]; /* Reverse direction of ColorWheel */
1965 dhue
[1] = 270 - dhue
[0] + (dhue
[0] > 270 ? 360 : 0);
1966 dhue
[2] = dhue
[0] - 180 + (dhue
[0] < 180 ? 360 : 0);
1967 dhue
[3] = 90 - dhue
[0] + (dhue
[0] > 90 ? 360 : 0);
1969 for (i
= 0; i
< 4; i
++) {
1970 rp
= panel
->wheelMtrx
->data
[0] + (ofs
[i
] << uchar_shift
);
1971 gp
= panel
->wheelMtrx
->data
[1] + (ofs
[i
] << uchar_shift
);
1972 bp
= panel
->wheelMtrx
->data
[2] + (ofs
[i
] << uchar_shift
);
1974 cpColor
.hsv
.hue
= dhue
[i
];
1975 convertCPColor(&cpColor
);
1977 *rp
= (unsigned char)(cpColor
.rgb
.red
);
1978 *gp
= (unsigned char)(cpColor
.rgb
.green
);
1979 *bp
= (unsigned char)(cpColor
.rgb
.blue
);
1982 for (i
= 0; i
< 4; i
++) {
1983 rp
= panel
->wheelMtrx
->data
[0] + (ofs
[i
] << uchar_shift
);
1984 gp
= panel
->wheelMtrx
->data
[1] + (ofs
[i
] << uchar_shift
);
1985 bp
= panel
->wheelMtrx
->data
[2] + (ofs
[i
] << uchar_shift
);
1987 *rp
= (unsigned char)0;
1988 *gp
= (unsigned char)0;
1989 *bp
= (unsigned char)0;
1994 ofs
[0] += 2 * y
+ 1;
1995 ofs
[1] += 1 - (colorWheelSize
+ 4) * (colorWheelSize
+ 4 - 1 - 2 * y
);
1999 static void wheelCalculateValues(W_ColorPanel
* panel
, int maxvalue
)
2004 for (i
= 0; i
< 256; i
++) {
2005 /* We divide by 128 in advance, and check whether that number divides
2006 * by 2 properly. If not, we add one to round the number correctly
2008 v
= (i
* maxvalue
) >> 7;
2009 panel
->wheelMtrx
->values
[i
] = (unsigned char)((v
>> 1) + (v
& 0x01));
2013 static void wheelRender(W_ColorPanel
* panel
)
2015 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2020 unsigned long ofs
= 0;
2021 /*unsigned char shift = getShift(sizeof(unsigned char)); */
2023 image
= RCreateImage(colorWheelSize
+ 4, colorWheelSize
+ 4, True
);
2025 wwarning(_("Color Panel: Could not allocate memory"));
2031 /* TODO Make this transparent istead of gray */
2032 gray
.red
= gray
.blue
= 0xae;
2035 for (y
= 0; y
< colorWheelSize
+ 4; y
++) {
2036 for (x
= 0; x
< colorWheelSize
+ 4; x
++) {
2037 if (wheelInsideColorWheel(panel
, ofs
)) {
2039 (unsigned char)(panel
->wheelMtrx
->values
[panel
->wheelMtrx
->data
[0][ofs
]]);
2041 (unsigned char)(panel
->wheelMtrx
->values
[panel
->wheelMtrx
->data
[1][ofs
]]);
2043 (unsigned char)(panel
->wheelMtrx
->values
[panel
->wheelMtrx
->data
[2][ofs
]]);
2046 *(ptr
++) = (unsigned char)(gray
.red
);
2047 *(ptr
++) = (unsigned char)(gray
.green
);
2048 *(ptr
++) = (unsigned char)(gray
.blue
);
2055 if (panel
->wheelImg
)
2056 XFreePixmap(scr
->display
, panel
->wheelImg
);
2058 RConvertImage(scr
->rcontext
, image
, &panel
->wheelImg
);
2059 RReleaseImage(image
);
2061 /* Check if backimage exists. If it doesn't, allocate and fill it */
2062 if (!panel
->selectionBackImg
) {
2063 panel
->selectionBackImg
= XCreatePixmap(scr
->display
,
2064 W_VIEW(panel
->wheelFrm
)->window
, 4, 4, scr
->depth
);
2065 XCopyArea(scr
->display
, panel
->wheelImg
, panel
->selectionBackImg
,
2066 scr
->copyGC
, panel
->colx
- 2, panel
->coly
- 2, 4, 4, 0, 0);
2067 /* -2 is hot spot correction */
2071 static Bool
wheelInsideColorWheel(W_ColorPanel
* panel
, unsigned long ofs
)
2073 return ((panel
->wheelMtrx
->data
[0][ofs
] != 0) &&
2074 (panel
->wheelMtrx
->data
[1][ofs
] != 0) && (panel
->wheelMtrx
->data
[2][ofs
] != 0));
2077 static void wheelPaint(W_ColorPanel
* panel
)
2079 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2081 XCopyArea(scr
->display
, panel
->wheelImg
, panel
->wheelView
->window
,
2082 scr
->copyGC
, 0, 0, colorWheelSize
+ 4, colorWheelSize
+ 4, 0, 0);
2084 /* Draw selection image */
2085 XCopyArea(scr
->display
, panel
->selectionImg
, panel
->wheelView
->window
,
2086 scr
->copyGC
, 0, 0, 4, 4, panel
->colx
- 2, panel
->coly
- 2);
2089 static void wheelHandleEvents(XEvent
* event
, void *data
)
2091 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
2093 switch (event
->type
) {
2095 if (event
->xexpose
.count
!= 0) /* TODO Improve */
2102 static void wheelHandleActionEvents(XEvent
* event
, void *data
)
2104 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
2106 switch (event
->type
) {
2108 if (getPickerPart(panel
, event
->xbutton
.x
, event
->xbutton
.y
) == COLORWHEEL_PART
) {
2110 panel
->lastChanged
= WMWheelModeColorPanel
;
2111 panel
->flags
.dragging
= 1;
2113 wheelPositionSelection(panel
, event
->xbutton
.x
, event
->xbutton
.y
);
2118 panel
->flags
.dragging
= 0;
2119 if (!panel
->flags
.continuous
) {
2121 (*panel
->action
) (panel
, panel
->clientData
);
2126 if (panel
->flags
.dragging
) {
2127 if (getPickerPart(panel
, event
->xmotion
.x
, event
->xmotion
.y
) == COLORWHEEL_PART
) {
2128 wheelPositionSelection(panel
, event
->xmotion
.x
, event
->xmotion
.y
);
2130 wheelPositionSelectionOutBounds(panel
, event
->xmotion
.x
, event
->xmotion
.y
);
2136 static int getPickerPart(W_ColorPanel
* panel
, int x
, int y
)
2144 if (panel
->mode
== WMWheelModeColorPanel
) {
2145 if ((lx
>= 2) && (lx
<= 2 + colorWheelSize
) && (ly
>= 2) && (ly
<= 2 + colorWheelSize
)) {
2147 ofs
= ly
* panel
->wheelMtrx
->width
+ lx
;
2149 if (wheelInsideColorWheel(panel
, ofs
))
2150 return COLORWHEEL_PART
;
2154 if (panel
->mode
== WMCustomPaletteModeColorPanel
) {
2155 if ((lx
>= 2) && (lx
< customPaletteWidth
- 2) && (ly
>= 2) && (ly
< customPaletteHeight
- 2)) {
2156 return CUSTOMPALETTE_PART
;
2163 static void wheelBrightnessSliderCallback(WMWidget
* w
, void *data
)
2167 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
2169 /* Parameter not used, but tell the compiler that it is ok */
2172 value
= 255 - WMGetSliderValue(panel
->wheelBrightnessS
);
2174 wheelCalculateValues(panel
, value
);
2176 if (panel
->color
.set
== cpRGB
) {
2177 convertCPColor(&panel
->color
);
2178 panel
->color
.set
= cpHSV
;
2181 panel
->color
.hsv
.value
= value
;
2185 wheelUpdateSelection(panel
);
2188 static void wheelUpdateSelection(W_ColorPanel
* panel
)
2190 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2192 updateSwatch(panel
, panel
->color
);
2193 panel
->lastChanged
= WMWheelModeColorPanel
;
2195 /* Redraw color selector (and make a backup of the part it will cover) */
2196 XCopyArea(scr
->display
, panel
->wheelImg
, panel
->selectionBackImg
,
2197 scr
->copyGC
, panel
->colx
- 2, panel
->coly
- 2, 4, 4, 0, 0);
2198 /* "-2" is correction for hotspot location */
2199 XCopyArea(scr
->display
, panel
->selectionImg
, panel
->wheelView
->window
,
2200 scr
->copyGC
, 0, 0, 4, 4, panel
->colx
- 2, panel
->coly
- 2);
2204 static void wheelUndrawSelection(W_ColorPanel
* panel
)
2206 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2208 XCopyArea(scr
->display
, panel
->selectionBackImg
, panel
->wheelView
->window
,
2209 scr
->copyGC
, 0, 0, 4, 4, panel
->colx
- 2, panel
->coly
- 2);
2213 static void wheelPositionSelection(W_ColorPanel
* panel
, int x
, int y
)
2215 unsigned long ofs
= (y
* panel
->wheelMtrx
->width
) + x
;
2217 panel
->color
.rgb
.red
= panel
->wheelMtrx
->values
[panel
->wheelMtrx
->data
[0][ofs
]];
2219 panel
->color
.rgb
.green
= panel
->wheelMtrx
->values
[panel
->wheelMtrx
->data
[1][ofs
]];
2221 panel
->color
.rgb
.blue
= panel
->wheelMtrx
->values
[panel
->wheelMtrx
->data
[2][ofs
]];
2222 panel
->color
.set
= cpRGB
;
2224 wheelUndrawSelection(panel
);
2229 wheelUpdateSelection(panel
);
2230 wheelUpdateBrightnessGradientFromLocation(panel
);
2233 static void wheelPositionSelectionOutBounds(W_ColorPanel
* panel
, int x
, int y
)
2239 xcor
= x
* 2 - colorWheelSize
- 4;
2240 ycor
= y
* 2 - colorWheelSize
- 4;
2242 panel
->color
.hsv
.saturation
= 255;
2243 panel
->color
.hsv
.value
= 255 - WMGetSliderValue(panel
->wheelBrightnessS
);
2246 hue
= rint(atan(-(double)ycor
/ (double)xcor
) * (180.0 / M_PI
));
2257 if ((xcor
> 0) && (ycor
> 0))
2260 panel
->color
.hsv
.hue
= hue
;
2261 panel
->color
.set
= cpHSV
;
2262 convertCPColor(&panel
->color
);
2264 wheelUndrawSelection(panel
);
2266 panel
->colx
= 2 + rint((colorWheelSize
* (1.0 + cos(panel
->color
.hsv
.hue
* (M_PI
/ 180.0)))) / 2.0);
2267 /* "+2" because of "colorWheelSize + 4" */
2268 panel
->coly
= 2 + rint((colorWheelSize
* (1.0 + sin(-panel
->color
.hsv
.hue
* (M_PI
/ 180.0)))) / 2.0);
2270 wheelUpdateSelection(panel
);
2271 cpColor
= panel
->color
;
2272 wheelUpdateBrightnessGradient(panel
, cpColor
);
2275 static void wheelUpdateBrightnessGradientFromLocation(W_ColorPanel
* panel
)
2280 ofs
= panel
->coly
* panel
->wheelMtrx
->width
+ panel
->colx
;
2282 from
.rgb
.red
= panel
->wheelMtrx
->data
[0][ofs
];
2283 from
.rgb
.green
= panel
->wheelMtrx
->data
[1][ofs
];
2284 from
.rgb
.blue
= panel
->wheelMtrx
->data
[2][ofs
];
2287 wheelUpdateBrightnessGradient(panel
, from
);
2290 static void wheelUpdateBrightnessGradient(W_ColorPanel
* panel
, CPColor topColor
)
2294 WMPixmap
*sliderPxmp
;
2296 to
.red
= to
.green
= to
.blue
= 0;
2298 if (topColor
.set
== cpHSV
)
2299 convertCPColor(&topColor
);
2301 sliderImg
= RRenderGradient(16, 153, &(topColor
.rgb
), &to
, RGRD_VERTICAL
);
2302 sliderPxmp
= WMCreatePixmapFromRImage(WMWidgetScreen(panel
->win
), sliderImg
, 0);
2303 RReleaseImage(sliderImg
);
2304 WMSetSliderImage(panel
->wheelBrightnessS
, sliderPxmp
);
2305 WMReleasePixmap(sliderPxmp
);
2308 /****************** Grayscale Panel Functions ***************/
2310 static void grayBrightnessSliderCallback(WMWidget
* w
, void *data
)
2315 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
2317 /* Parameter not used, but tell the compiler that it is ok */
2320 value
= WMGetSliderValue(panel
->grayBrightnessS
);
2322 sprintf(tmp
, "%d", value
);
2324 WMSetTextFieldText(panel
->grayBrightnessT
, tmp
);
2325 cpColor
.rgb
.red
= cpColor
.rgb
.green
= cpColor
.rgb
.blue
= rint(2.55 * value
);
2326 cpColor
.set
= cpRGB
;
2328 updateSwatch(panel
, cpColor
);
2329 panel
->lastChanged
= WMGrayModeColorPanel
;
2332 static void grayPresetButtonCallback(WMWidget
* w
, void *data
)
2338 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
2341 if (w
== panel
->grayPresetBtn
[i
])
2346 value
= rint((100.0 * i
) / 6.0);
2347 sprintf(tmp
, "%d", value
);
2349 WMSetTextFieldText(panel
->grayBrightnessT
, tmp
);
2350 cpColor
.rgb
.red
= cpColor
.rgb
.green
= cpColor
.rgb
.blue
= rint((255.0 * i
) / 6.0);
2351 cpColor
.set
= cpRGB
;
2353 WMSetSliderValue(panel
->grayBrightnessS
, rint((100.0 * i
) / 6.0));
2355 updateSwatch(panel
, cpColor
);
2356 panel
->lastChanged
= WMGrayModeColorPanel
;
2359 static void grayBrightnessTextFieldCallback(void *observerData
, WMNotification
* notification
)
2364 W_ColorPanel
*panel
= (W_ColorPanel
*) observerData
;
2366 /* Parameter not used, but tell the compiler that it is ok */
2367 (void) notification
;
2369 value
= get_textfield_as_integer(panel
->grayBrightnessT
);
2375 sprintf(tmp
, "%d", value
);
2376 WMSetTextFieldText(panel
->grayBrightnessT
, tmp
);
2377 WMSetSliderValue(panel
->grayBrightnessS
, value
);
2379 cpColor
.rgb
.red
= cpColor
.rgb
.green
= cpColor
.rgb
.blue
= rint((255.0 * value
) / 100.0);
2380 cpColor
.set
= cpRGB
;
2382 updateSwatch(panel
, cpColor
);
2383 panel
->lastChanged
= WMGrayModeColorPanel
;
2386 /******************* RGB Panel Functions *****************/
2388 void rgbIntToChar(W_ColorPanel
*panel
, int *value
)
2393 switch (panel
->rgbState
) {
2402 sprintf(tmp
, format
, value
[0]);
2403 WMSetTextFieldText(panel
->rgbRedT
, tmp
);
2404 sprintf(tmp
, format
, value
[1]);
2405 WMSetTextFieldText(panel
->rgbGreenT
, tmp
);
2406 sprintf(tmp
, format
, value
[2]);
2407 WMSetTextFieldText(panel
->rgbBlueT
, tmp
);
2410 int *rgbCharToInt(W_ColorPanel
*panel
)
2413 static int value
[3];
2416 switch (panel
->rgbState
) {
2425 str
= WMGetTextFieldText(panel
->rgbRedT
);
2426 value
[0] = strtol(str
, NULL
, base
);
2429 str
= WMGetTextFieldText(panel
->rgbGreenT
);
2430 value
[1] = strtol(str
, NULL
, base
);
2433 str
= WMGetTextFieldText(panel
->rgbBlueT
);
2434 value
[2] = strtol(str
, NULL
, base
);
2440 static void rgbSliderCallback(WMWidget
* w
, void *data
)
2444 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
2446 /* Parameter not used, but tell the compiler that it is ok */
2449 value
[0] = WMGetSliderValue(panel
->rgbRedS
);
2450 value
[1] = WMGetSliderValue(panel
->rgbGreenS
);
2451 value
[2] = WMGetSliderValue(panel
->rgbBlueS
);
2453 rgbIntToChar(panel
, value
);
2455 cpColor
.rgb
.red
= value
[0];
2456 cpColor
.rgb
.green
= value
[1];
2457 cpColor
.rgb
.blue
= value
[2];
2458 cpColor
.set
= cpRGB
;
2460 updateSwatch(panel
, cpColor
);
2461 panel
->lastChanged
= WMRGBModeColorPanel
;
2464 static void rgbTextFieldCallback(void *observerData
, WMNotification
* notification
)
2469 W_ColorPanel
*panel
= (W_ColorPanel
*) observerData
;
2471 /* Parameter not used, but tell the compiler that it is ok */
2472 (void) notification
;
2474 value
= rgbCharToInt(panel
);
2476 for (n
= 0; n
< 3; n
++) {
2483 rgbIntToChar(panel
, value
);
2485 WMSetSliderValue(panel
->rgbRedS
, value
[0]);
2486 WMSetSliderValue(panel
->rgbGreenS
, value
[1]);
2487 WMSetSliderValue(panel
->rgbBlueS
, value
[2]);
2489 cpColor
.rgb
.red
= value
[0];
2490 cpColor
.rgb
.green
= value
[1];
2491 cpColor
.rgb
.blue
= value
[2];
2492 cpColor
.set
= cpRGB
;
2494 updateSwatch(panel
, cpColor
);
2495 panel
->lastChanged
= WMRGBModeColorPanel
;
2498 static void rgbDecToHex(WMWidget
*w
, void *data
)
2500 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
2505 switch (panel
->rgbState
) {
2507 if (WMGetButtonSelected(panel
->rgbDecB
)) {
2508 WMSetLabelText(panel
->rgbMaxL
, "255");
2509 WMRedisplayWidget(panel
->rgbMaxL
);
2510 value
= rgbCharToInt(panel
);
2511 panel
->rgbState
= RGBdec
;
2512 rgbIntToChar(panel
, value
);
2517 if (WMGetButtonSelected(panel
->rgbHexB
)) {
2518 WMSetLabelText(panel
->rgbMaxL
, "FF");
2519 WMRedisplayWidget(panel
->rgbMaxL
);
2520 value
= rgbCharToInt(panel
);
2521 panel
->rgbState
= RGBhex
;
2522 rgbIntToChar(panel
, value
);
2528 /******************* CMYK Panel Functions *****************/
2530 static void cmykSliderCallback(WMWidget
* w
, void *data
)
2535 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
2538 /* Parameter not used, but tell the compiler that it is ok */
2541 value
[0] = WMGetSliderValue(panel
->cmykCyanS
);
2542 value
[1] = WMGetSliderValue(panel
->cmykMagentaS
);
2543 value
[2] = WMGetSliderValue(panel
->cmykYellowS
);
2544 value
[3] = WMGetSliderValue(panel
->cmykBlackS
);
2546 sprintf(tmp
, "%d", value
[0]);
2547 WMSetTextFieldText(panel
->cmykCyanT
, tmp
);
2548 sprintf(tmp
, "%d", value
[1]);
2549 WMSetTextFieldText(panel
->cmykMagentaT
, tmp
);
2550 sprintf(tmp
, "%d", value
[2]);
2551 WMSetTextFieldText(panel
->cmykYellowT
, tmp
);
2552 sprintf(tmp
, "%d", value
[3]);
2553 WMSetTextFieldText(panel
->cmykBlackT
, tmp
);
2555 scale
= 2.55 * (1.0 - (value
[3] / 100.0));
2556 cpColor
.rgb
.red
= rint((100.0 - value
[0]) * scale
);
2557 cpColor
.rgb
.green
= rint((100.0 - value
[1]) * scale
);
2558 cpColor
.rgb
.blue
= rint((100.0 - value
[2]) * scale
);
2559 cpColor
.set
= cpRGB
;
2561 updateSwatch(panel
, cpColor
);
2562 panel
->lastChanged
= WMCMYKModeColorPanel
;
2565 static void cmykTextFieldCallback(void *observerData
, WMNotification
* notification
)
2572 W_ColorPanel
*panel
= (W_ColorPanel
*) observerData
;
2574 /* Parameter not used, but tell the compiler that it is ok */
2575 (void) notification
;
2577 value
[0] = get_textfield_as_integer(panel
->cmykCyanT
);
2578 value
[1] = get_textfield_as_integer(panel
->cmykMagentaT
);
2579 value
[2] = get_textfield_as_integer(panel
->cmykYellowT
);
2580 value
[3] = get_textfield_as_integer(panel
->cmykBlackT
);
2582 for (n
= 0; n
< 4; n
++) {
2589 sprintf(tmp
, "%d", value
[0]);
2590 WMSetTextFieldText(panel
->cmykCyanT
, tmp
);
2592 sprintf(tmp
, "%d", value
[1]);
2593 WMSetTextFieldText(panel
->cmykMagentaT
, tmp
);
2595 sprintf(tmp
, "%d", value
[2]);
2596 WMSetTextFieldText(panel
->cmykYellowT
, tmp
);
2598 sprintf(tmp
, "%d", value
[3]);
2599 WMSetTextFieldText(panel
->cmykBlackT
, tmp
);
2601 WMSetSliderValue(panel
->cmykCyanS
, value
[0]);
2602 WMSetSliderValue(panel
->cmykMagentaS
, value
[1]);
2603 WMSetSliderValue(panel
->cmykYellowS
, value
[2]);
2604 WMSetSliderValue(panel
->cmykBlackS
, value
[3]);
2606 scale
= 2.55 * (1.0 - (value
[3] / 100.0));
2607 cpColor
.rgb
.red
= rint((100.0 - value
[0]) * scale
);
2608 cpColor
.rgb
.green
= rint((100.0 - value
[1]) * scale
);
2609 cpColor
.rgb
.blue
= rint((100.0 - value
[2]) * scale
);
2610 cpColor
.set
= cpRGB
;
2612 updateSwatch(panel
, cpColor
);
2613 panel
->lastChanged
= WMCMYKModeColorPanel
;
2616 /********************** HSB Panel Functions ***********************/
2618 static void hsbSliderCallback(WMWidget
* w
, void *data
)
2623 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
2625 value
[0] = WMGetSliderValue(panel
->hsbHueS
);
2626 value
[1] = WMGetSliderValue(panel
->hsbSaturationS
);
2627 value
[2] = WMGetSliderValue(panel
->hsbBrightnessS
);
2629 sprintf(tmp
, "%d", value
[0]);
2630 WMSetTextFieldText(panel
->hsbHueT
, tmp
);
2631 sprintf(tmp
, "%d", value
[1]);
2632 WMSetTextFieldText(panel
->hsbSaturationT
, tmp
);
2633 sprintf(tmp
, "%d", value
[2]);
2634 WMSetTextFieldText(panel
->hsbBrightnessT
, tmp
);
2636 cpColor
.hsv
.hue
= value
[0];
2637 cpColor
.hsv
.saturation
= value
[1] * 2.55;
2638 cpColor
.hsv
.value
= value
[2] * 2.55;
2639 cpColor
.set
= cpHSV
;
2641 convertCPColor(&cpColor
);
2643 panel
->lastChanged
= WMHSBModeColorPanel
;
2644 updateSwatch(panel
, cpColor
);
2646 if (w
!= panel
->hsbBrightnessS
)
2647 hsbUpdateBrightnessGradient(panel
);
2648 if (w
!= panel
->hsbSaturationS
)
2649 hsbUpdateSaturationGradient(panel
);
2650 if (w
!= panel
->hsbHueS
)
2651 hsbUpdateHueGradient(panel
);
2654 static void hsbTextFieldCallback(void *observerData
, WMNotification
* notification
)
2660 W_ColorPanel
*panel
= (W_ColorPanel
*) observerData
;
2662 /* Parameter not used, but tell the compiler that it is ok */
2663 (void) notification
;
2665 value
[0] = get_textfield_as_integer(panel
->hsbHueT
);
2666 value
[1] = get_textfield_as_integer(panel
->hsbSaturationT
);
2667 value
[2] = get_textfield_as_integer(panel
->hsbBrightnessT
);
2674 for (n
= 1; n
< 3; n
++) {
2681 sprintf(tmp
, "%d", value
[0]);
2682 WMSetTextFieldText(panel
->hsbHueT
, tmp
);
2683 sprintf(tmp
, "%d", value
[1]);
2684 WMSetTextFieldText(panel
->hsbSaturationT
, tmp
);
2685 sprintf(tmp
, "%d", value
[2]);
2686 WMSetTextFieldText(panel
->hsbBrightnessT
, tmp
);
2688 WMSetSliderValue(panel
->hsbHueS
, value
[0]);
2689 WMSetSliderValue(panel
->hsbSaturationS
, value
[1]);
2690 WMSetSliderValue(panel
->hsbBrightnessS
, value
[2]);
2692 cpColor
.hsv
.hue
= value
[0];
2693 cpColor
.hsv
.saturation
= value
[1] * 2.55;
2694 cpColor
.hsv
.value
= value
[2] * 2.55;
2695 cpColor
.set
= cpHSV
;
2697 convertCPColor(&cpColor
);
2699 panel
->lastChanged
= WMHSBModeColorPanel
;
2700 updateSwatch(panel
, cpColor
);
2702 hsbUpdateBrightnessGradient(panel
);
2703 hsbUpdateSaturationGradient(panel
);
2704 hsbUpdateHueGradient(panel
);
2707 static void hsbUpdateBrightnessGradient(W_ColorPanel
* panel
)
2709 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2713 WMPixmap
*sliderPxmp
;
2715 from
.red
= from
.green
= from
.blue
= 0;
2716 to
.hsv
= panel
->color
.hsv
;
2720 convertCPColor(&to
);
2722 sliderImg
= RRenderGradient(141, 16, &from
, &(to
.rgb
), RGRD_HORIZONTAL
);
2723 sliderPxmp
= WMCreatePixmapFromRImage(scr
, sliderImg
, 0);
2724 RReleaseImage(sliderImg
);
2727 W_PaintText(W_VIEW(panel
->hsbBrightnessS
), sliderPxmp
->pixmap
,
2728 panel
->font12
, 2, 0, 100, WALeft
, scr
->white
,
2729 False
, _("Brightness"), strlen(_("Brightness")));
2731 wwarning(_("Color Panel: Could not allocate memory"));
2733 WMSetSliderImage(panel
->hsbBrightnessS
, sliderPxmp
);
2734 WMReleasePixmap(sliderPxmp
);
2737 static void hsbUpdateSaturationGradient(W_ColorPanel
* panel
)
2739 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2743 WMPixmap
*sliderPxmp
;
2745 from
.hsv
= panel
->color
.hsv
;
2746 from
.hsv
.saturation
= 0;
2748 convertCPColor(&from
);
2750 to
.hsv
= panel
->color
.hsv
;
2751 to
.hsv
.saturation
= 255;
2753 convertCPColor(&to
);
2755 sliderImg
= RRenderGradient(141, 16, &(from
.rgb
), &(to
.rgb
), RGRD_HORIZONTAL
);
2756 sliderPxmp
= WMCreatePixmapFromRImage(scr
, sliderImg
, 0);
2757 RReleaseImage(sliderImg
);
2760 W_PaintText(W_VIEW(panel
->hsbSaturationS
), sliderPxmp
->pixmap
,
2761 panel
->font12
, 2, 0, 100, WALeft
,
2762 from
.hsv
.value
< 128 ? scr
->white
: scr
->black
, False
,
2763 _("Saturation"), strlen(_("Saturation")));
2765 wwarning(_("Color Panel: Could not allocate memory"));
2767 WMSetSliderImage(panel
->hsbSaturationS
, sliderPxmp
);
2768 WMReleasePixmap(sliderPxmp
);
2771 static void hsbUpdateHueGradient(W_ColorPanel
* panel
)
2773 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2774 RColor
**colors
= NULL
;
2777 WMPixmap
*sliderPxmp
;
2780 hsvcolor
= panel
->color
.hsv
;
2782 colors
= wmalloc(sizeof(RColor
*) * (8));
2783 for (i
= 0; i
< 7; i
++) {
2784 hsvcolor
.hue
= (360 * i
) / 6;
2785 colors
[i
] = wmalloc(sizeof(RColor
));
2786 RHSVtoRGB(&hsvcolor
, colors
[i
]);
2790 sliderImg
= RRenderMultiGradient(141, 16, colors
, RGRD_HORIZONTAL
);
2791 sliderPxmp
= WMCreatePixmapFromRImage(scr
, sliderImg
, 0);
2792 RReleaseImage(sliderImg
);
2795 W_PaintText(W_VIEW(panel
->hsbHueS
), sliderPxmp
->pixmap
,
2796 panel
->font12
, 2, 0, 100, WALeft
,
2797 hsvcolor
.value
< 128 ? scr
->white
: scr
->black
, False
, _("Hue"), strlen(_("Hue")));
2799 wwarning(_("Color Panel: Could not allocate memory"));
2801 WMSetSliderImage(panel
->hsbHueS
, sliderPxmp
);
2802 WMReleasePixmap(sliderPxmp
);
2804 for (i
= 0; i
< 7; i
++)
2810 /*************** Custom Palette Functions ****************/
2812 static void customRenderSpectrum(W_ColorPanel
* panel
)
2819 spectrum
= RCreateImage(SPECTRUM_WIDTH
, SPECTRUM_HEIGHT
, False
);
2821 ptr
= spectrum
->data
;
2823 for (y
= 0; y
< SPECTRUM_HEIGHT
; y
++) {
2824 cpColor
.hsv
.hue
= y
;
2825 cpColor
.hsv
.saturation
= 0;
2826 cpColor
.hsv
.value
= 255;
2827 cpColor
.set
= cpHSV
;
2829 for (x
= 0; x
< SPECTRUM_WIDTH
; x
++) {
2830 convertCPColor(&cpColor
);
2832 *(ptr
++) = (unsigned char)cpColor
.rgb
.red
;
2833 *(ptr
++) = (unsigned char)cpColor
.rgb
.green
;
2834 *(ptr
++) = (unsigned char)cpColor
.rgb
.blue
;
2836 if (x
< (SPECTRUM_WIDTH
/ 2))
2837 cpColor
.hsv
.saturation
++;
2839 if (x
> (SPECTRUM_WIDTH
/ 2))
2840 cpColor
.hsv
.value
--;
2843 if (panel
->customPaletteImg
) {
2844 RReleaseImage(panel
->customPaletteImg
);
2845 panel
->customPaletteImg
= NULL
;
2847 panel
->customPaletteImg
= spectrum
;
2850 static void customSetPalette(W_ColorPanel
* panel
)
2852 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2856 image
= XCreatePixmap(scr
->display
, W_DRAWABLE(scr
), customPaletteWidth
, customPaletteHeight
, scr
->depth
);
2857 scaledImg
= RScaleImage(panel
->customPaletteImg
, customPaletteWidth
, customPaletteHeight
);
2858 RConvertImage(scr
->rcontext
, scaledImg
, &image
);
2859 RReleaseImage(scaledImg
);
2861 XCopyArea(scr
->display
, image
, panel
->customPaletteContentView
->window
,
2862 scr
->copyGC
, 0, 0, customPaletteWidth
, customPaletteHeight
, 0, 0);
2864 /* Check backimage exists. If it doesn't, allocate and fill it */
2865 if (!panel
->selectionBackImg
) {
2866 panel
->selectionBackImg
= XCreatePixmap(scr
->display
,
2867 panel
->customPaletteContentView
->window
, 4, 4, scr
->depth
);
2870 XCopyArea(scr
->display
, image
, panel
->selectionBackImg
, scr
->copyGC
,
2871 panel
->palx
- 2, panel
->paly
- 2, 4, 4, 0, 0);
2872 XCopyArea(scr
->display
, panel
->selectionImg
,
2873 panel
->customPaletteContentView
->window
, scr
->copyGC
, 0, 0, 4, 4,
2874 panel
->palx
- 2, panel
->paly
- 2);
2875 XFreePixmap(scr
->display
, image
);
2877 panel
->palXRatio
= (double)(panel
->customPaletteImg
->width
) / (double)(customPaletteWidth
);
2878 panel
->palYRatio
= (double)(panel
->customPaletteImg
->height
) / (double)(customPaletteHeight
);
2880 WMGetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
);
2883 static void customPalettePositionSelection(W_ColorPanel
* panel
, int x
, int y
)
2885 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
2888 /* undraw selection */
2889 XCopyArea(scr
->display
, panel
->selectionBackImg
,
2890 panel
->customPaletteContentView
->window
, scr
->copyGC
, 0, 0, 4, 4,
2891 panel
->palx
- 2, panel
->paly
- 2);
2896 ofs
= (rint(x
* panel
->palXRatio
) + rint(y
* panel
->palYRatio
) * panel
->customPaletteImg
->width
) * 3;
2898 panel
->color
.rgb
.red
= panel
->customPaletteImg
->data
[ofs
];
2899 panel
->color
.rgb
.green
= panel
->customPaletteImg
->data
[ofs
+ 1];
2900 panel
->color
.rgb
.blue
= panel
->customPaletteImg
->data
[ofs
+ 2];
2901 panel
->color
.set
= cpRGB
;
2903 updateSwatch(panel
, panel
->color
);
2904 panel
->lastChanged
= WMCustomPaletteModeColorPanel
;
2906 /* Redraw color selector (and make a backup of the part it will cover) */
2907 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 */
2908 XCopyArea(scr
->display
, panel
->selectionImg
, panel
->customPaletteContentView
->window
, scr
->copyGC
, 0, 0, 4, 4, panel
->palx
- 2, panel
->paly
- 2); /* see above */
2911 static void customPalettePositionSelectionOutBounds(W_ColorPanel
* panel
, int x
, int y
)
2917 if (x
>= customPaletteWidth
)
2918 x
= customPaletteWidth
- 2;
2919 if (y
>= customPaletteHeight
)
2920 y
= customPaletteHeight
- 2;
2922 customPalettePositionSelection(panel
, x
, y
);
2925 static void customPaletteHandleEvents(XEvent
* event
, void *data
)
2927 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
2929 switch (event
->type
) {
2931 if (event
->xexpose
.count
!= 0) /* TODO Improve. */
2933 customSetPalette(panel
);
2938 static void customPaletteHandleActionEvents(XEvent
* event
, void *data
)
2940 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
2943 switch (event
->type
) {
2945 x
= event
->xbutton
.x
;
2946 y
= event
->xbutton
.y
;
2948 if (getPickerPart(panel
, x
, y
) == CUSTOMPALETTE_PART
) {
2949 panel
->flags
.dragging
= 1;
2950 customPalettePositionSelection(panel
, x
, y
);
2955 panel
->flags
.dragging
= 0;
2956 if (!panel
->flags
.continuous
) {
2958 (*panel
->action
) (panel
, panel
->clientData
);
2963 x
= event
->xmotion
.x
;
2964 y
= event
->xmotion
.y
;
2966 if (panel
->flags
.dragging
) {
2967 if (getPickerPart(panel
, x
, y
) == CUSTOMPALETTE_PART
) {
2968 customPalettePositionSelection(panel
, x
, y
);
2970 customPalettePositionSelectionOutBounds(panel
, x
, y
);
2976 static void customPaletteMenuCallback(WMWidget
* w
, void *data
)
2978 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
2979 int item
= WMGetPopUpButtonSelectedItem(panel
->customPaletteMenuBtn
);
2981 /* Parameter not used, but tell the compiler that it is ok */
2985 case CPmenuNewFromFile
:
2986 customPaletteMenuNewFromFile(panel
);
2989 customPaletteMenuRename(panel
);
2992 customPaletteMenuRemove(panel
);
2996 case CPmenuNewFromClipboard
:
3001 static void customPaletteMenuNewFromFile(W_ColorPanel
* panel
)
3003 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
3004 WMOpenPanel
*browseP
;
3006 char *filename
= NULL
;
3010 RImage
*tmpImg
= NULL
;
3012 if ((!panel
->lastBrowseDir
) || (strcmp(panel
->lastBrowseDir
, "\0") == 0))
3013 spath
= wexpandpath(wgethomedir());
3015 spath
= wexpandpath(panel
->lastBrowseDir
);
3017 browseP
= WMGetOpenPanel(scr
);
3018 WMSetFilePanelCanChooseDirectories(browseP
, 0);
3019 WMSetFilePanelCanChooseFiles(browseP
, 1);
3021 /* Get a filename */
3022 if (WMRunModalFilePanelForDirectory(browseP
, panel
->win
, spath
,
3023 _("Open Palette"), RSupportedFileFormats())) {
3024 filepath
= WMGetFilePanelFileName(browseP
);
3026 /* Get seperation position between path and filename */
3027 i
= strrchr(filepath
, '/') - filepath
+ 1;
3028 if (i
> strlen(filepath
))
3029 i
= strlen(filepath
);
3031 /* Store last browsed path */
3032 if (panel
->lastBrowseDir
)
3033 wfree(panel
->lastBrowseDir
);
3034 panel
->lastBrowseDir
= wmalloc((i
+ 1) * sizeof(char));
3035 strncpy(panel
->lastBrowseDir
, filepath
, i
);
3036 panel
->lastBrowseDir
[i
] = '\0';
3038 /* Get filename from path */
3039 filename
= wstrdup(filepath
+ i
);
3041 /* Check for duplicate files, and rename it if there are any */
3042 tmp
= wstrconcat(panel
->configurationPath
, filename
);
3043 while (access(tmp
, F_OK
) == 0) {
3048 newName
= generateNewFilename(filename
);
3052 tmp
= wstrconcat(panel
->configurationPath
, filename
);
3056 /* Copy image to $(gnustepdir)/Library/Colors/ &
3057 * Add filename to history menu */
3058 if (wcopy_file(panel
->configurationPath
, filepath
, filename
) == 0) {
3060 /* filepath is a "local" path now the file has been copied */
3062 filepath
= wstrconcat(panel
->configurationPath
, filename
);
3064 /* load the image & add menu entries */
3065 tmpImg
= RLoadImage(scr
->rcontext
, filepath
, 0);
3067 if (panel
->customPaletteImg
)
3068 RReleaseImage(panel
->customPaletteImg
);
3069 panel
->customPaletteImg
= tmpImg
;
3071 customSetPalette(panel
);
3072 WMAddPopUpButtonItem(panel
->customPaletteHistoryBtn
, filename
);
3074 panel
->currentPalette
=
3075 WMGetPopUpButtonNumberOfItems(panel
->customPaletteHistoryBtn
) - 1;
3077 WMSetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
,
3078 panel
->currentPalette
);
3081 tmp
= wstrconcat(panel
->configurationPath
, filename
);
3083 i
= remove(tmp
); /* Delete the file, it doesn't belong here */
3084 WMRunAlertPanel(scr
, panel
->win
, _("File Error"),
3085 _("Invalid file format !"), _("OK"), NULL
, NULL
);
3087 werror(_("can't remove file %s"), tmp
);
3088 WMRunAlertPanel(scr
, panel
->win
, _("File Error"),
3089 _("Couldn't remove file from Configuration Directory !"),
3090 _("OK"), NULL
, NULL
);
3097 WMFreeFilePanel(browseP
);
3102 static void customPaletteMenuRename(W_ColorPanel
* panel
)
3104 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
3105 char *toName
= NULL
;
3107 char *toPath
, *fromPath
;
3111 item
= WMGetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
);
3112 fromName
= WMGetPopUpButtonItem(panel
->customPaletteHistoryBtn
, item
);
3114 toName
= WMRunInputPanel(scr
, panel
->win
, _("Rename"), _("Rename palette to:"),
3115 fromName
, _("OK"), _("Cancel"));
3119 /* As some people do certain stupid things... */
3120 if (strcmp(toName
, fromName
) == 0) {
3125 /* For normal people */
3126 fromPath
= wstrconcat(panel
->configurationPath
, fromName
);
3127 toPath
= wstrconcat(panel
->configurationPath
, toName
);
3129 if (access(toPath
, F_OK
) == 0) {
3130 /* Careful, this palette exists already */
3131 if (WMRunAlertPanel(scr
, panel
->win
, _("Warning"),
3132 _("Palette already exists !\n\nOverwrite ?"), _("No"), _("Yes"),
3134 /* "No" = 0, "Yes" = 1 */
3135 int items
= WMGetPopUpButtonNumberOfItems(panel
->customPaletteHistoryBtn
);
3139 /* Remove from History list too */
3141 while ((index
< items
)
3143 (strcmp(WMGetPopUpButtonItem(panel
->customPaletteHistoryBtn
, index
), toName
)
3147 if (index
< items
) {
3148 WMRemovePopUpButtonItem(panel
->customPaletteHistoryBtn
, index
);
3162 if (rename(fromPath
, toPath
) != 0)
3163 werror(_("Couldn't rename palette %s to %s"), fromName
, toName
);
3165 WMRemovePopUpButtonItem(panel
->customPaletteHistoryBtn
, item
);
3166 WMInsertPopUpButtonItem(panel
->customPaletteHistoryBtn
, item
, toName
);
3168 WMSetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
, item
);
3176 static void customPaletteMenuRemove(W_ColorPanel
* panel
)
3178 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
3184 item
= WMGetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
);
3186 tmp
= wstrconcat(_("This will permanently remove the palette "),
3187 WMGetPopUpButtonItem(panel
->customPaletteHistoryBtn
, item
));
3188 text
= wstrconcat(tmp
, _(".\n\nAre you sure you want to remove this palette ?"));
3191 choice
= WMRunAlertPanel(scr
, panel
->win
, _("Remove"), text
, _("Yes"), _("No"), NULL
);
3192 /* returns 0 (= "Yes") or 1 (="No") */
3197 tmp
= wstrconcat(panel
->configurationPath
,
3198 WMGetPopUpButtonItem(panel
->customPaletteHistoryBtn
, item
));
3200 if (remove(tmp
) == 0) {
3201 /* item-1 always exists */
3202 WMSetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
, item
- 1);
3204 customPaletteHistoryCallback(panel
->customPaletteHistoryBtn
, panel
);
3205 customSetPalette(panel
);
3207 WMRemovePopUpButtonItem(panel
->customPaletteHistoryBtn
, item
);
3210 werror(_("Couldn't remove palette %s"), tmp
);
3217 static void customPaletteHistoryCallback(WMWidget
* w
, void *data
)
3219 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
3220 W_Screen
*scr
= WMWidgetScreen(panel
->win
);
3224 unsigned char perm_mask
;
3226 item
= WMGetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
);
3227 if (item
== panel
->currentPalette
)
3231 customRenderSpectrum(panel
);
3233 WMSetPopUpButtonItemEnabled(panel
->customPaletteMenuBtn
, CPmenuRename
, False
);
3234 WMSetPopUpButtonItemEnabled(panel
->customPaletteMenuBtn
, CPmenuRemove
, False
);
3236 /* Load file from configpath */
3237 filename
= wstrconcat(panel
->configurationPath
,
3238 WMGetPopUpButtonItem(panel
->customPaletteHistoryBtn
, item
));
3240 /* If the file corresponding to the item does not exist,
3241 * remove it from the history list and select the next one.
3243 perm_mask
= (access(filename
, F_OK
) == 0);
3245 /* File does not exist */
3247 WMSetPopUpButtonSelectedItem(panel
->customPaletteHistoryBtn
, item
- 1);
3248 WMRemovePopUpButtonItem(panel
->customPaletteHistoryBtn
, item
);
3249 customPaletteHistoryCallback(w
, data
);
3254 tmp
= RLoadImage(scr
->rcontext
, filename
, 0);
3256 if (panel
->customPaletteImg
) {
3257 RReleaseImage(panel
->customPaletteImg
);
3258 panel
->customPaletteImg
= NULL
;
3260 panel
->customPaletteImg
= tmp
;
3263 /* If the image is not writable, don't allow removing/renaming */
3264 perm_mask
= (access(filename
, W_OK
) == 0);
3265 WMSetPopUpButtonItemEnabled(panel
->customPaletteMenuBtn
, CPmenuRename
, perm_mask
);
3266 WMSetPopUpButtonItemEnabled(panel
->customPaletteMenuBtn
, CPmenuRemove
, perm_mask
);
3270 customSetPalette(panel
);
3272 panel
->currentPalette
= item
;
3275 /************************* ColorList Panel Functions **********************/
3277 static void colorListPaintItem(WMList
* lPtr
, int index
, Drawable d
, char *text
, int state
, WMRect
* rect
)
3279 WMScreen
*scr
= WMWidgetScreen(lPtr
);
3280 Display
*dpy
= WMScreenDisplay(scr
);
3281 WMView
*view
= W_VIEW(lPtr
);
3282 RColor
*color
= (RColor
*) WMGetListItem(lPtr
, index
)->clientData
;
3283 W_ColorPanel
*panel
= WMGetHangedData(lPtr
);
3284 int width
, height
, x
, y
;
3287 width
= rect
->size
.width
;
3288 height
= rect
->size
.height
;
3292 if (state
& WLDSSelected
)
3293 XFillRectangle(dpy
, d
, WMColorGC(scr
->white
), x
, y
, width
, height
);
3295 XFillRectangle(dpy
, d
, WMColorGC(view
->backColor
), x
, y
, width
, height
);
3297 fillColor
= WMCreateRGBColor(scr
, color
->red
<< 8, color
->green
<< 8, color
->blue
<< 8, True
);
3299 XFillRectangle(dpy
, d
, WMColorGC(fillColor
), x
, y
, 15, height
);
3300 WMReleaseColor(fillColor
);
3302 WMDrawString(scr
, d
, scr
->black
, panel
->font12
, x
+ 18, y
, text
, strlen(text
));
3305 static void colorListSelect(WMWidget
* w
, void *data
)
3307 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
3310 cpColor
.rgb
= *((RColor
*) WMGetListSelectedItem(w
)->clientData
);
3311 cpColor
.set
= cpRGB
;
3313 panel
->lastChanged
= WMColorListModeColorPanel
;
3314 updateSwatch(panel
, cpColor
);
3317 static void colorListColorMenuCallback(WMWidget
* w
, void *data
)
3319 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
3320 int item
= WMGetPopUpButtonSelectedItem(panel
->colorListColorMenuBtn
);
3322 /* Parameter not used, but tell the compiler that it is ok */
3335 static void colorListListMenuCallback(WMWidget
* w
, void *data
)
3337 W_ColorPanel
*panel
= (W_ColorPanel
*) data
;
3338 int item
= WMGetPopUpButtonSelectedItem(panel
->colorListListMenuBtn
);
3340 /* Parameter not used, but tell the compiler that it is ok */
3353 /*************** Panel Initialisation Functions *****************/
3355 static void wheelInit(W_ColorPanel
* panel
)
3359 if (panel
->color
.set
!= cpHSV
)
3360 convertCPColor(&panel
->color
);
3362 WMSetSliderValue(panel
->wheelBrightnessS
, 255 - panel
->color
.hsv
.value
);
3364 panel
->colx
= 2 + rint((colorWheelSize
/ 2.0) *
3365 (1 + (panel
->color
.hsv
.saturation
/ 255.0) *
3366 cos(panel
->color
.hsv
.hue
* M_PI
/ 180.0)));
3367 panel
->coly
= 2 + rint((colorWheelSize
/ 2.0) *
3368 (1 + (panel
->color
.hsv
.saturation
/ 255.0) *
3369 sin(-panel
->color
.hsv
.hue
* M_PI
/ 180.0)));
3371 wheelCalculateValues(panel
, panel
->color
.hsv
.value
);
3373 cpColor
= panel
->color
;
3374 cpColor
.hsv
.value
= 255;
3375 cpColor
.set
= cpHSV
;
3376 wheelUpdateBrightnessGradient(panel
, cpColor
);
3379 static void grayInit(W_ColorPanel
* panel
)
3384 if (panel
->color
.set
!= cpHSV
)
3385 convertCPColor(&panel
->color
);
3387 value
= rint(panel
->color
.hsv
.value
/ 2.55);
3388 WMSetSliderValue(panel
->grayBrightnessS
, value
);
3390 sprintf(tmp
, "%d", value
);
3391 WMSetTextFieldText(panel
->grayBrightnessT
, tmp
);
3394 static void rgbInit(W_ColorPanel
* panel
)
3398 if (panel
->color
.set
!= cpRGB
)
3399 convertCPColor(&panel
->color
);
3401 WMSetSliderValue(panel
->rgbRedS
, panel
->color
.rgb
.red
);
3402 WMSetSliderValue(panel
->rgbGreenS
, panel
->color
.rgb
.green
);
3403 WMSetSliderValue(panel
->rgbBlueS
, panel
->color
.rgb
.blue
);
3405 sprintf(tmp
, "%d", panel
->color
.rgb
.red
);
3406 WMSetTextFieldText(panel
->rgbRedT
, tmp
);
3407 sprintf(tmp
, "%d", panel
->color
.rgb
.green
);
3408 WMSetTextFieldText(panel
->rgbGreenT
, tmp
);
3409 sprintf(tmp
, "%d", panel
->color
.rgb
.blue
);
3410 WMSetTextFieldText(panel
->rgbBlueT
, tmp
);
3413 static void cmykInit(W_ColorPanel
* panel
)
3418 if (panel
->color
.set
!= cpRGB
)
3419 convertCPColor(&panel
->color
);
3421 value
[0] = rint((255 - panel
->color
.rgb
.red
) / 2.55);
3422 value
[1] = rint((255 - panel
->color
.rgb
.green
) / 2.55);
3423 value
[2] = rint((255 - panel
->color
.rgb
.blue
) / 2.55);
3425 WMSetSliderValue(panel
->cmykCyanS
, value
[0]);
3426 WMSetSliderValue(panel
->cmykMagentaS
, value
[1]);
3427 WMSetSliderValue(panel
->cmykYellowS
, value
[2]);
3428 WMSetSliderValue(panel
->cmykBlackS
, 0);
3430 sprintf(tmp
, "%d", value
[0]);
3431 WMSetTextFieldText(panel
->cmykCyanT
, tmp
);
3432 sprintf(tmp
, "%d", value
[1]);
3433 WMSetTextFieldText(panel
->cmykMagentaT
, tmp
);
3434 sprintf(tmp
, "%d", value
[2]);
3435 WMSetTextFieldText(panel
->cmykYellowT
, tmp
);
3436 WMSetTextFieldText(panel
->cmykBlackT
, "0");
3439 static void hsbInit(W_ColorPanel
* panel
)
3444 if (panel
->color
.set
!= cpHSV
)
3445 convertCPColor(&panel
->color
);
3447 value
[0] = panel
->color
.hsv
.hue
;
3448 value
[1] = rint(panel
->color
.hsv
.saturation
/ 2.55);
3449 value
[2] = rint(panel
->color
.hsv
.value
/ 2.55);
3451 WMSetSliderValue(panel
->hsbHueS
, value
[0]);
3452 WMSetSliderValue(panel
->hsbSaturationS
, value
[1]);
3453 WMSetSliderValue(panel
->hsbBrightnessS
, value
[2]);
3455 sprintf(tmp
, "%d", value
[0]);
3456 WMSetTextFieldText(panel
->hsbHueT
, tmp
);
3457 sprintf(tmp
, "%d", value
[1]);
3458 WMSetTextFieldText(panel
->hsbSaturationT
, tmp
);
3459 sprintf(tmp
, "%d", value
[2]);
3460 WMSetTextFieldText(panel
->hsbBrightnessT
, tmp
);
3462 hsbUpdateBrightnessGradient(panel
);
3463 hsbUpdateSaturationGradient(panel
);
3464 hsbUpdateHueGradient(panel
);
3467 /************************** Common utility functions ************************/
3469 static char *generateNewFilename(const char *curName
)
3481 if (((ptr
= strrchr(ptr
, '{')) == 0) || sscanf(ptr
, "{%i}%c", &n
, &c
) != 1)
3482 return wstrconcat(curName
, " {1}");
3484 baseLen
= ptr
- curName
- 1;
3486 newName
= wmalloc(baseLen
+ 16);
3487 strncpy(newName
, curName
, baseLen
);
3489 snprintf(&newName
[baseLen
], 16, " {%i}", n
+ 1);
3494 static void convertCPColor(CPColor
* color
)
3496 unsigned short old_hue
= 0;
3498 switch (color
->set
) {
3500 wwarning(_("Color Panel: Color unspecified"));
3503 old_hue
= color
->hsv
.hue
;
3504 RRGBtoHSV(&(color
->rgb
), &(color
->hsv
));
3506 /* In black the hue is undefined, and may change by conversion
3507 * Same for white. */
3508 if (((color
->rgb
.red
== 0) &&
3509 (color
->rgb
.green
== 0) &&
3510 (color
->rgb
.blue
== 0)) ||
3511 ((color
->rgb
.red
== 0) && (color
->rgb
.green
== 0) && (color
->rgb
.blue
== 255))
3513 color
->hsv
.hue
= old_hue
;
3516 RHSVtoRGB(&(color
->hsv
), &(color
->rgb
));
3521 #define ABS_SHIFT(val, shift) \
3522 (((shift) > 0) ? (val) >> (shift) : (val) << -(shift))
3524 static RColor
ulongToRColor(WMScreen
* scr
, unsigned long value
)
3527 XColor
*xcolor
= NULL
;
3529 xcolor
= wmalloc(sizeof(XColor
));
3530 xcolor
->pixel
= value
;
3531 XQueryColor(scr
->display
, scr
->rcontext
->cmap
, xcolor
);
3533 color
.red
= xcolor
->red
>> 8;
3534 color
.green
= xcolor
->green
>> 8;
3535 color
.blue
= xcolor
->blue
>> 8;
3543 static unsigned char getShift(unsigned char value
)
3545 unsigned char i
= -1;