/* * ColorPanel for WINGs * * by ]d : Original idea and basic initial code * Pascal Hofstee : Code for wheeldrawing and calculating * colors from it. * Primary coder of this Color Panel. * Alban Hertroys : Optimizations for algorithms for color- * wheel. Also custom ColorPalettes and * magnifying glass. Secondary coder ;) * Alfredo K. Kojima : For pointing out memory-allocation * problems and similair code-issues * Marco van Hylckama-Vlieg : For once again doing the artwork ;-) * */ /* TODO: * - Look at further optimization of colorWheel matrix calculation. * It appears to be rather symmetric in angles of 60 degrees, * while it is optimized in angles of 90 degrees. * - Custom color-lists and custom colors in custom color-lists. * - Stored colors * - Resizing */ #include "wconfig.h" #include "WINGsP.h" #include #include #include #include #include #include #include #include /* BUG There's something fishy with shaped windows */ /* Whithout shape extension the magnified image is completely broken -Dan */ #if 0 # ifdef SHAPE # define SHAPE_WAS_DEFINED # undef SHAPE # endif #endif #ifdef SHAPE # include #endif #ifndef PATH_MAX # define PATH_MAX 1024 #endif char *WMColorPanelColorChangedNotification = "WMColorPanelColorChangedNotification"; /* * Bitmaps for magnifying glass cursor */ /* Cursor */ #define Cursor_x_hot 11 #define Cursor_y_hot 11 #define Cursor_width 32 #define Cursor_height 32 static unsigned char Cursor_bits[] = { 0x00,0x7e,0x00,0x00,0xc0,0x81,0x03,0x00,0x20,0x00,0x04,0x00,0x10,0x00,0x08, 0x00,0x08,0x00,0x10,0x00,0x04,0x00,0x20,0x00,0x02,0x00,0x40,0x00,0x02,0x00, 0x40,0x00,0x02,0x00,0x40,0x00,0x01,0x42,0x80,0x00,0x01,0x24,0x80,0x00,0x01, 0x00,0x80,0x00,0x01,0x00,0x80,0x00,0x01,0x24,0x80,0x00,0x01,0x42,0x80,0x00, 0x02,0x00,0x40,0x00,0x02,0x00,0x40,0x00,0x02,0x00,0x40,0x00,0x04,0x00,0x20, 0x00,0x08,0x00,0x50,0x00,0x10,0x00,0x88,0x00,0x20,0x00,0x5c,0x01,0xc0,0x81, 0x3b,0x02,0x00,0x7e,0x70,0x05,0x00,0x00,0xe0,0x08,0x00,0x00,0xc0,0x15,0x00, 0x00,0x80,0x23,0x00,0x00,0x00,0x57,0x00,0x00,0x00,0x8e,0x00,0x00,0x00,0x5c, 0x00,0x00,0x00,0xb8,0x00,0x00,0x00,0x70}; /* Cursor shape-mask */ #define Cursor_shape_width 32 #define Cursor_shape_height 32 static unsigned char Cursor_shape_bits[] = { 0x00,0x7e,0x00,0x00,0xc0,0x81,0x03,0x00,0x20,0x00,0x04,0x00,0x10,0x00,0x08, 0x00,0x08,0x00,0x10,0x00,0x04,0x00,0x20,0x00,0x02,0x00,0x40,0x00,0x02,0x00, 0x40,0x00,0x02,0x00,0x40,0x00,0x01,0x42,0x80,0x00,0x01,0x24,0x80,0x00,0x01, 0x00,0x80,0x00,0x01,0x00,0x80,0x00,0x01,0x24,0x80,0x00,0x01,0x42,0x80,0x00, 0x02,0x00,0x40,0x00,0x02,0x00,0x40,0x00,0x02,0x00,0x40,0x00,0x04,0x00,0x20, 0x00,0x08,0x00,0x70,0x00,0x10,0x00,0xf8,0x00,0x20,0x00,0xfc,0x01,0xc0,0x81, 0xfb,0x03,0x00,0x7e,0xf0,0x07,0x00,0x00,0xe0,0x0f,0x00,0x00,0xc0,0x1f,0x00, 0x00,0x80,0x3f,0x00,0x00,0x00,0x7f,0x00,0x00,0x00,0xfe,0x00,0x00,0x00,0xfc, 0x00,0x00,0x00,0xf8,0x00,0x00,0x00,0x70}; /* Clip-mask for magnified pixels */ #define Cursor_mask_width 24 #define Cursor_mask_height 24 static unsigned char Cursor_mask_bits[] = { 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0xc0, 0xff, 0x03, 0xe0, 0xff, 0x07, 0xf0, 0xff, 0x0f, 0xf8, 0xff, 0x1f, 0xfc, 0xff, 0x3f, 0xfc, 0xff, 0x3f, 0xfc, 0xff, 0x3f, 0xfe, 0xff, 0x7f, 0xfe, 0xff, 0x7f, 0xfe, 0xff, 0x7f, 0xfe, 0xff, 0x7f, 0xfe, 0xff, 0x7f, 0xfe, 0xff, 0x7f, 0xfc, 0xff, 0x3f, 0xfc, 0xff, 0x3f, 0xfc, 0xff, 0x3f, 0xf8, 0xff, 0x1f, 0xf0, 0xff, 0x0f, 0xe0, 0xff, 0x07, 0xc0, 0xff, 0x03, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00}; typedef struct MovingView { WMView *view; /* The view this is all about */ XImage *image; /* What's under the view */ XImage *dirtyRect; /* Storage of overlapped image area */ Pixmap magPix; /* Magnified part of pixmap */ RColor color; /* Color of a pixel in the image */ int x, y; /* Position of view */ } MovingView; typedef struct CPColor { RColor rgb; /* The RGB values of the color */ RHSVColor hsv; /* The HSV values of the color */ enum { /* Which one was last set ? */ cpNone, cpRGB, cpHSV } set; } CPColor; typedef struct WheelMatrix { unsigned int width, height; /* Size of the colorwheel */ unsigned char *data[3]; /* Wheel data (R,G,B) */ unsigned char values[256]; /* Precalculated values R,G & B = 0-255 */ } wheelMatrix; typedef struct W_ColorPanel { WMWindow *win; WMFont *font8; WMFont *font12; void *clientData; WMAction2 *action; /* Common Stuff */ WMColorWell *colorWell; WMButton *magnifyBtn; WMButton *wheelBtn; WMButton *slidersBtn; WMButton *customPaletteBtn; WMButton *colorListBtn; /* Magnifying Glass */ MovingView *magnifyGlass; /* ColorWheel Panel */ WMFrame *wheelFrm; WMSlider *wheelBrightnessS; WMView *wheelView; /* Slider Panels */ WMFrame *slidersFrm; WMFrame *seperatorFrm; WMButton *grayBtn; WMButton *rgbBtn; WMButton *cmykBtn; WMButton *hsbBtn; /* Gray Scale Panel */ WMFrame *grayFrm; WMLabel *grayMinL; WMLabel *grayMaxL; WMSlider *grayBrightnessS; WMTextField *grayBrightnessT; WMButton *grayPresetBtn[7]; /* RGB Panel */ WMFrame *rgbFrm; WMLabel *rgbMinL; WMLabel *rgbMaxL; WMSlider *rgbRedS; WMSlider *rgbGreenS; WMSlider *rgbBlueS; WMTextField *rgbRedT; WMTextField *rgbGreenT; WMTextField *rgbBlueT; /* CMYK Panel */ WMFrame *cmykFrm; WMLabel *cmykMinL; WMLabel *cmykMaxL; WMSlider *cmykCyanS; WMSlider *cmykMagentaS; WMSlider *cmykYellowS; WMSlider *cmykBlackS; WMTextField *cmykCyanT; WMTextField *cmykMagentaT; WMTextField *cmykYellowT; WMTextField *cmykBlackT; /* HSB Panel */ WMFrame *hsbFrm; WMSlider *hsbHueS; WMSlider *hsbSaturationS; WMSlider *hsbBrightnessS; WMTextField *hsbHueT; WMTextField *hsbSaturationT; WMTextField *hsbBrightnessT; /* Custom Palette Panel*/ WMFrame *customPaletteFrm; WMPopUpButton *customPaletteHistoryBtn; WMFrame *customPaletteContentFrm; WMPopUpButton *customPaletteMenuBtn; WMView *customPaletteContentView; /* Color List Panel */ WMFrame *colorListFrm; WMPopUpButton *colorListHistoryBtn; WMList *colorListContentLst; WMPopUpButton *colorListColorMenuBtn; WMPopUpButton *colorListListMenuBtn; /* Look-Up Tables and Images */ wheelMatrix *wheelMtrx; Pixmap wheelImg; Pixmap selectionImg; Pixmap selectionBackImg; RImage *customPaletteImg; char *lastBrowseDir; /* Common Data Fields */ CPColor color; /* Current color */ WMColorPanelMode mode; /* Current color selection mode */ WMColorPanelMode slidersmode; /* Current color sel. mode sliders panel */ WMColorPanelMode lastChanged; /* Panel that last changed the color */ int colx, coly; /* (x,y) of sel.-marker in WheelMode */ int palx, paly; /* (x,y) of sel.-marker in CustomPaletteMode */ double palXRatio, palYRatio; /* Ratios in x & y between original and scaled palettesize */ int currentPalette; char *configurationPath; struct { unsigned int continuous:1; unsigned int dragging:1; } flags; } W_ColorPanel; enum { CPmenuNewFromFile, CPmenuRename, CPmenuRemove, CPmenuCopy, CPmenuNewFromClipboard } customPaletteMenuItem; enum { CLmenuAdd, CLmenuRename, CLmenuRemove } colorListMenuItem; #define PWIDTH 194 #define PHEIGHT 266 #define colorWheelSize 150 #define customPaletteWidth 182 #define customPaletteHeight 106 #define knobThickness 8 #define SPECTRUM_WIDTH 511 #define SPECTRUM_HEIGHT 360 #define COLORWHEEL_PART 1 #define CUSTOMPALETTE_PART 2 #define BUFSIZE 1024 #ifndef RGBTXT #define RGBTXT "/usr/X11R6/lib/X11/rgb.txt" #endif #define MAX_LENGTH 1024 #ifndef M_PI #define M_PI 3.14159265358979323846 #endif /* Silly hack for Windows systems with cygwin */ #ifndef O_BINARY # define O_BINARY 0 #endif static int fetchFile(char* toPath, char *imageSrcFile, char *imageDestFileName); char *generateNewFilename(char *curName); void convertCPColor(CPColor *color); RColor ulongToRColor(WMScreen *scr, unsigned long value); unsigned char getShift(unsigned char value); static void modeButtonCallback(WMWidget *w, void *data); static int getPickerPart(W_ColorPanel *panel, int x, int y); static void readConfiguration(W_ColorPanel *panel); static void readXColors(W_ColorPanel *panel); static void closeWindowCallback(WMWidget *w, void *data); static Cursor magnifyGrabPointer(W_ColorPanel *panel); static WMPoint magnifyInitialize(W_ColorPanel *panel); static void magnifyPutCursor(WMWidget *w, void *data); static Pixmap magnifyCreatePixmap(WMColorPanel *panel); static void magnifyGetImageStored(W_ColorPanel *panel, int x1, int y1, int x2, int y2); static XImage* magnifyGetImage(WMScreen *scr, XImage *image, int x, int y, int w, int h); static wheelMatrix* wheelCreateMatrix(unsigned int width , unsigned int height); static void wheelDestroyMatrix(wheelMatrix *matrix); static void wheelInitMatrix(W_ColorPanel *panel); static void wheelCalculateValues(W_ColorPanel *panel, int maxvalue); static void wheelRender(W_ColorPanel *panel); static Bool wheelInsideColorWheel(W_ColorPanel *panel, unsigned long ofs); static void wheelPaint(W_ColorPanel *panel); static void wheelHandleEvents(XEvent *event, void *data); static void wheelHandleActionEvents(XEvent *event, void *data); static void wheelBrightnessSliderCallback(WMWidget *w, void *data); static void wheelUpdateSelection(W_ColorPanel *panel); static void wheelUndrawSelection(W_ColorPanel *panel); static void wheelPositionSelection(W_ColorPanel *panel, int x, int y); static void wheelPositionSelectionOutBounds(W_ColorPanel *panel, int x, int y); static void wheelUpdateBrightnessGradientFromLocation (W_ColorPanel *panel); static void wheelUpdateBrightnessGradient(W_ColorPanel *panel, CPColor topColor); static void grayBrightnessSliderCallback(WMWidget *w, void *data); static void grayPresetButtonCallback(WMWidget *w, void *data); static void grayBrightnessTextFieldCallback(void *observerData, WMNotification *notification); static void rgbSliderCallback(WMWidget *w, void *data); static void rgbTextFieldCallback(void *observerData, WMNotification *notification); static void cmykSliderCallback(WMWidget *w, void *data); static void cmykTextFieldCallback(void *observerData, WMNotification *notification); static void hsbSliderCallback(WMWidget *w, void *data); static void hsbTextFieldCallback(void *observerData, WMNotification *notification); static void hsbUpdateBrightnessGradient(W_ColorPanel *panel); static void hsbUpdateSaturationGradient(W_ColorPanel *panel); static void hsbUpdateHueGradient(W_ColorPanel *panel); static void customRenderSpectrum(W_ColorPanel *panel); static void customSetPalette(W_ColorPanel *panel); static void customPaletteHandleEvents(XEvent *event, void *data); static void customPaletteHandleActionEvents(XEvent *event, void *data); static void customPalettePositionSelection(W_ColorPanel *panel, int x, int y); static void customPalettePositionSelectionOutBounds(W_ColorPanel *panel, int x, int y); static void customPaletteMenuCallback(WMWidget *w, void *data); static void customPaletteHistoryCallback(WMWidget *w, void *data); static void customPaletteMenuNewFromFile(W_ColorPanel *panel); static void customPaletteMenuRename(W_ColorPanel *panel); static void customPaletteMenuRemove(W_ColorPanel *panel); static void colorListPaintItem(WMList *lPtr, int index, Drawable d, char *text, int state, WMRect *rect); static void colorListSelect(WMWidget *w, void *data); static void colorListColorMenuCallback(WMWidget *w, void *data); static void colorListListMenuCallback(WMWidget *w, void *data); static void colorListListMenuNew(W_ColorPanel *panel); static void wheelInit(W_ColorPanel *panel); static void grayInit(W_ColorPanel *panel); static void rgbInit(W_ColorPanel *panel); static void cmykInit(W_ColorPanel *panel); static void hsbInit(W_ColorPanel *panel); void WMSetColorPanelAction(WMColorPanel *panel, WMAction2 *action, void *data) { panel->action = action; panel->clientData = data; } static WMColorPanel* makeColorPanel(WMScreen *scrPtr, char *name) { WMColorPanel *panel; RImage *image; WMPixmap *pixmap; RColor from; RColor to; WMColor *textcolor, *graybuttoncolor; int i; GC bgc = WMColorGC(scrPtr->black); GC wgc = WMColorGC(scrPtr->white); panel = wmalloc(sizeof(WMColorPanel)); memset(panel, 0, sizeof(WMColorPanel)); panel->color.rgb.red = 0; panel->color.rgb.green = 0; panel->color.rgb.blue = 0; panel->color.hsv.hue = 0; panel->color.hsv.saturation = 0; panel->color.hsv.value = 0; panel->color.set = cpNone; /* Color has not been set yet */ panel->font8 = WMSystemFontOfSize(scrPtr, 8); panel->font12 = WMSystemFontOfSize(scrPtr, 12); panel->win = WMCreateWindowWithStyle(scrPtr, name, WMTitledWindowMask | WMClosableWindowMask | WMResizableWindowMask); WMResizeWidget(panel->win, PWIDTH, PHEIGHT); WMSetWindowTitle(panel->win, _("Colors")); WMSetWindowCloseAction(panel->win, closeWindowCallback, panel); /* Set Default ColorPanel Mode(s) */ panel->mode = WMWheelModeColorPanel; panel->lastChanged = 0; panel->slidersmode = WMRGBModeColorPanel; panel->configurationPath = wstrconcat(wusergnusteppath(), "/Library/Colors/"); /* Some General Purpose Widgets */ panel->colorWell = WMCreateColorWell(panel->win); WMResizeWidget(panel->colorWell, 134, 36); WSetColorWellBordered(panel->colorWell, False); WMMoveWidget(panel->colorWell, 56, 4); panel->magnifyBtn = WMCreateCustomButton(panel->win, WBBStateLightMask|WBBStateChangeMask); WMResizeWidget(panel->magnifyBtn, 46, 36); WMMoveWidget(panel->magnifyBtn, 6,4); WMSetButtonAction(panel->magnifyBtn, magnifyPutCursor, panel); WMSetButtonImagePosition(panel->magnifyBtn, WIPImageOnly); WMSetButtonImage(panel->magnifyBtn, scrPtr->magnifyIcon); panel->wheelBtn = WMCreateCustomButton(panel->win, WBBStateLightMask|WBBStateChangeMask); WMResizeWidget(panel->wheelBtn, 46, 32); WMMoveWidget(panel->wheelBtn, 6, 44); WMSetButtonAction(panel->wheelBtn, modeButtonCallback, panel); WMSetButtonImagePosition(panel->wheelBtn, WIPImageOnly); WMSetButtonImage(panel->wheelBtn, scrPtr->wheelIcon); panel->slidersBtn = WMCreateCustomButton(panel->win, WBBStateLightMask|WBBStateChangeMask); WMResizeWidget(panel->slidersBtn, 46, 32); WMMoveWidget(panel->slidersBtn, 52, 44); WMSetButtonAction(panel->slidersBtn, modeButtonCallback, panel); WMSetButtonImagePosition(panel->slidersBtn, WIPImageOnly); WMSetButtonImage(panel->slidersBtn, scrPtr->rgbIcon); panel->customPaletteBtn = WMCreateCustomButton(panel->win, WBBStateLightMask|WBBStateChangeMask); WMResizeWidget(panel->customPaletteBtn, 46, 32); WMMoveWidget(panel->customPaletteBtn, 98, 44); WMSetButtonAction(panel->customPaletteBtn, modeButtonCallback, panel); WMSetButtonImagePosition(panel->customPaletteBtn, WIPImageOnly); WMSetButtonImage(panel->customPaletteBtn, scrPtr->customPaletteIcon); panel->colorListBtn = WMCreateCustomButton(panel->win, WBBStateLightMask|WBBStateChangeMask); WMResizeWidget(panel->colorListBtn, 46, 32); WMMoveWidget(panel->colorListBtn, 144, 44); WMSetButtonAction(panel->colorListBtn, modeButtonCallback, panel); WMSetButtonImagePosition(panel->colorListBtn, WIPImageOnly); WMSetButtonImage(panel->colorListBtn, scrPtr->colorListIcon); /* Let's Group some of them together */ WMGroupButtons(panel->wheelBtn, panel->slidersBtn); WMGroupButtons(panel->wheelBtn, panel->customPaletteBtn); WMGroupButtons(panel->wheelBtn, panel->colorListBtn); /* Widgets for the ColorWheel Panel */ panel->wheelFrm = WMCreateFrame(panel->win); WMSetFrameRelief(panel->wheelFrm, WRFlat); WMResizeWidget(panel->wheelFrm, PWIDTH - 8, PHEIGHT - 80 - 26); WMMoveWidget(panel->wheelFrm, 5, 80); panel->wheelView = W_CreateView(W_VIEW(panel->wheelFrm)); /* XXX Can we create a view ? */ W_ResizeView(panel->wheelView, colorWheelSize+4, colorWheelSize+4); W_MoveView(panel->wheelView, 0, 0); /* Create an event handler to handle expose/click events in ColorWheel */ WMCreateEventHandler(panel->wheelView, ButtonPressMask|ButtonReleaseMask|EnterWindowMask| LeaveWindowMask|ButtonMotionMask, wheelHandleActionEvents, panel); WMCreateEventHandler(panel->wheelView, ExposureMask, wheelHandleEvents, panel); panel->wheelBrightnessS = WMCreateSlider(panel->wheelFrm); WMResizeWidget(panel->wheelBrightnessS, 16, 153); WMMoveWidget(panel->wheelBrightnessS, 5+colorWheelSize+14, 1); WMSetSliderMinValue(panel->wheelBrightnessS, 0); WMSetSliderMaxValue(panel->wheelBrightnessS, 255); WMSetSliderAction(panel->wheelBrightnessS, wheelBrightnessSliderCallback, panel); WMSetSliderKnobThickness(panel->wheelBrightnessS, knobThickness); panel->wheelMtrx = wheelCreateMatrix(colorWheelSize+4, colorWheelSize+4); wheelInitMatrix(panel); /* Widgets for the Slider Panels */ panel->slidersFrm = WMCreateFrame(panel->win); WMSetFrameRelief(panel->slidersFrm, WRFlat); WMResizeWidget(panel->slidersFrm, PWIDTH - 8, PHEIGHT - 80 - 26); WMMoveWidget(panel->slidersFrm, 4, 80); panel->seperatorFrm = WMCreateFrame(panel->slidersFrm); WMSetFrameRelief(panel->seperatorFrm, WRPushed); WMResizeWidget(panel->seperatorFrm, PWIDTH - 8, 2); WMMoveWidget(panel->seperatorFrm, 0, 1); panel->grayBtn = WMCreateCustomButton(panel->slidersFrm, WBBStateLightMask|WBBStateChangeMask); WMResizeWidget(panel->grayBtn, 46, 24); WMMoveWidget(panel->grayBtn, 1, 8); WMSetButtonAction(panel->grayBtn, modeButtonCallback, panel); WMSetButtonImagePosition(panel->grayBtn, WIPImageOnly); WMSetButtonImage(panel->grayBtn, scrPtr->grayIcon); panel->rgbBtn = WMCreateCustomButton(panel->slidersFrm, WBBStateLightMask|WBBStateChangeMask); WMResizeWidget(panel->rgbBtn, 46, 24); WMMoveWidget(panel->rgbBtn, 47, 8); WMSetButtonAction(panel->rgbBtn, modeButtonCallback, panel); WMSetButtonImagePosition(panel->rgbBtn, WIPImageOnly); WMSetButtonImage(panel->rgbBtn, scrPtr->rgbIcon); panel->cmykBtn = WMCreateCustomButton(panel->slidersFrm, WBBStateLightMask|WBBStateChangeMask); WMResizeWidget(panel->cmykBtn, 46, 24); WMMoveWidget(panel->cmykBtn, 93, 8); WMSetButtonAction(panel->cmykBtn, modeButtonCallback, panel); WMSetButtonImagePosition(panel->cmykBtn, WIPImageOnly); WMSetButtonImage(panel->cmykBtn, scrPtr->cmykIcon); panel->hsbBtn = WMCreateCustomButton(panel->slidersFrm, WBBStateLightMask|WBBStateChangeMask); WMResizeWidget(panel->hsbBtn, 46, 24); WMMoveWidget(panel->hsbBtn, 139, 8); WMSetButtonAction(panel->hsbBtn, modeButtonCallback, panel); WMSetButtonImagePosition(panel->hsbBtn, WIPImageOnly); WMSetButtonImage(panel->hsbBtn, scrPtr->hsbIcon); /* Let's Group the Slider Panel Buttons Together */ WMGroupButtons(panel->grayBtn, panel->rgbBtn); WMGroupButtons(panel->grayBtn, panel->cmykBtn); WMGroupButtons(panel->grayBtn, panel->hsbBtn); textcolor = WMDarkGrayColor(scrPtr); /* Widgets for GrayScale Panel */ panel->grayFrm = WMCreateFrame(panel->slidersFrm); WMSetFrameRelief(panel->grayFrm, WRFlat); WMResizeWidget(panel->grayFrm, PWIDTH - 8, PHEIGHT - 80 - 26 - 32); WMMoveWidget(panel->grayFrm, 0, 34); panel->grayMinL = WMCreateLabel(panel->grayFrm); WMResizeWidget(panel->grayMinL, 20, 10); WMMoveWidget(panel->grayMinL, 2, 2); WMSetLabelText(panel->grayMinL, "0"); WMSetLabelTextAlignment(panel->grayMinL, WALeft); WMSetLabelTextColor(panel->grayMinL, textcolor); WMSetLabelFont(panel->grayMinL, panel->font8); panel->grayMaxL = WMCreateLabel(panel->grayFrm); WMResizeWidget(panel->grayMaxL, 40, 10); WMMoveWidget(panel->grayMaxL, 104, 2); WMSetLabelText(panel->grayMaxL, "100"); WMSetLabelTextAlignment(panel->grayMaxL, WARight); WMSetLabelTextColor(panel->grayMaxL, textcolor); WMSetLabelFont(panel->grayMaxL, panel->font8); panel->grayBrightnessS = WMCreateSlider(panel->grayFrm); WMResizeWidget(panel->grayBrightnessS, 141, 16); WMMoveWidget(panel->grayBrightnessS, 2, 14); WMSetSliderMinValue(panel->grayBrightnessS, 0); WMSetSliderMaxValue(panel->grayBrightnessS, 100); WMSetSliderKnobThickness(panel->grayBrightnessS, knobThickness); WMSetSliderAction(panel->grayBrightnessS, grayBrightnessSliderCallback, panel); from.red = 0; from.green = 0; from.blue = 0; to.red = 255; to.green = 255; to.blue = 255; image = RRenderGradient(141, 16, &from, &to, RGRD_HORIZONTAL); pixmap = WMCreatePixmapFromRImage(scrPtr, image, 0); RReleaseImage(image); if (pixmap) W_PaintText(W_VIEW(panel->grayBrightnessS), pixmap->pixmap, panel->font12, 2, 0, 100, WALeft, scrPtr->white, False, _("Brightness"), strlen(_("Brightness"))); else wwarning(_("Color Panel: Could not allocate memory")); WMSetSliderImage(panel->grayBrightnessS, pixmap); WMReleasePixmap(pixmap); panel->grayBrightnessT = WMCreateTextField(panel->grayFrm); WMResizeWidget(panel->grayBrightnessT, 40, 18); WMMoveWidget(panel->grayBrightnessT, 146, 13); WMSetTextFieldAlignment(panel->grayBrightnessT, WALeft); WMAddNotificationObserver(grayBrightnessTextFieldCallback, panel, WMTextDidEndEditingNotification, panel->grayBrightnessT); for (i=0; i < 7; i++) { pixmap = WMCreatePixmap(scrPtr, 13, 13, scrPtr->depth, False); graybuttoncolor = WMCreateRGBColor(scrPtr, (255/6)*i << 8, (255/6)*i << 8, (255/6)*i << 8, True); WMPaintColorSwatch(graybuttoncolor, pixmap->pixmap, 0, 0, 15, 15); WMReleaseColor(graybuttoncolor); panel->grayPresetBtn[i] = WMCreateCommandButton(panel->grayFrm); WMResizeWidget(panel->grayPresetBtn[i], 20, 24); WMMoveWidget(panel->grayPresetBtn[i], 2+(i*20), 34); WMSetButtonAction(panel->grayPresetBtn[i], grayPresetButtonCallback, panel); WMSetButtonImage(panel->grayPresetBtn[i], pixmap); WMSetButtonImagePosition(panel->grayPresetBtn[i], WIPImageOnly); WMReleasePixmap(pixmap); } /* End of GrayScale Panel */ /* Widgets for RGB Panel */ panel->rgbFrm = WMCreateFrame(panel->slidersFrm); WMSetFrameRelief(panel->rgbFrm, WRFlat); WMResizeWidget(panel->rgbFrm, PWIDTH - 8, PHEIGHT - 80 - 26 - 32); WMMoveWidget(panel->rgbFrm, 0, 34); panel->rgbMinL = WMCreateLabel(panel->rgbFrm); WMResizeWidget(panel->rgbMinL, 20, 10); WMMoveWidget(panel->rgbMinL, 2, 2); WMSetLabelText(panel->rgbMinL, "0"); WMSetLabelTextAlignment(panel->rgbMinL, WALeft); WMSetLabelTextColor(panel->rgbMinL, textcolor); WMSetLabelFont(panel->rgbMinL, panel->font8); panel->rgbMaxL = WMCreateLabel(panel->rgbFrm); WMResizeWidget(panel->rgbMaxL, 40, 10); WMMoveWidget(panel->rgbMaxL, 104, 2); WMSetLabelText(panel->rgbMaxL, "255"); WMSetLabelTextAlignment(panel->rgbMaxL, WARight); WMSetLabelTextColor(panel->rgbMaxL, textcolor); WMSetLabelFont(panel->rgbMaxL, panel->font8); panel->rgbRedS = WMCreateSlider(panel->rgbFrm); WMResizeWidget(panel->rgbRedS, 141, 16); WMMoveWidget(panel->rgbRedS, 2, 14); WMSetSliderMinValue(panel->rgbRedS, 0); WMSetSliderMaxValue(panel->rgbRedS, 255); WMSetSliderKnobThickness(panel->rgbRedS, knobThickness); WMSetSliderAction(panel->rgbRedS, rgbSliderCallback, panel); to.red = 255; to.green = 0; to.blue = 0; image = RRenderGradient(141, 16, &from, &to, RGRD_HORIZONTAL); pixmap = WMCreatePixmapFromRImage(scrPtr, image, 0); RReleaseImage(image); if (pixmap) W_PaintText(W_VIEW(panel->rgbRedS), pixmap->pixmap, panel->font12, 2, 0, 100, WALeft, scrPtr->white, False, _("Red"), strlen(_("Red"))); else wwarning(_("Color Panel: Could not allocate memory")); WMSetSliderImage(panel->rgbRedS, pixmap); WMReleasePixmap(pixmap); panel->rgbRedT = WMCreateTextField(panel->rgbFrm); WMResizeWidget(panel->rgbRedT, 40, 18); WMMoveWidget(panel->rgbRedT, 146, 13); WMSetTextFieldAlignment(panel->rgbRedT, WALeft); WMAddNotificationObserver(rgbTextFieldCallback, panel, WMTextDidEndEditingNotification, panel->rgbRedT); panel->rgbGreenS = WMCreateSlider(panel->rgbFrm); WMResizeWidget(panel->rgbGreenS, 141, 16); WMMoveWidget(panel->rgbGreenS, 2, 36); WMSetSliderMinValue(panel->rgbGreenS, 0); WMSetSliderMaxValue(panel->rgbGreenS, 255); WMSetSliderKnobThickness(panel->rgbGreenS, knobThickness); WMSetSliderAction(panel->rgbGreenS, rgbSliderCallback, panel); to.red = 0; to.green = 255; to.blue = 0; image = RRenderGradient(141, 16, &from, &to, RGRD_HORIZONTAL); pixmap = WMCreatePixmapFromRImage(scrPtr, image, 0); RReleaseImage(image); if (pixmap) W_PaintText(W_VIEW(panel->rgbGreenS), pixmap->pixmap, panel->font12, 2, 0, 100, WALeft, scrPtr->white, False, _("Green"), strlen(_("Green"))); else wwarning(_("Color Panel: Could not allocate memory")); WMSetSliderImage(panel->rgbGreenS, pixmap); WMReleasePixmap(pixmap); panel->rgbGreenT = WMCreateTextField(panel->rgbFrm); WMResizeWidget(panel->rgbGreenT, 40, 18); WMMoveWidget(panel->rgbGreenT, 146, 35); WMSetTextFieldAlignment(panel->rgbGreenT, WALeft); WMAddNotificationObserver(rgbTextFieldCallback, panel, WMTextDidEndEditingNotification, panel->rgbGreenT); panel->rgbBlueS = WMCreateSlider(panel->rgbFrm); WMResizeWidget(panel->rgbBlueS, 141, 16); WMMoveWidget(panel->rgbBlueS, 2, 58); WMSetSliderMinValue(panel->rgbBlueS, 0); WMSetSliderMaxValue(panel->rgbBlueS, 255); WMSetSliderKnobThickness(panel->rgbBlueS, knobThickness); WMSetSliderAction(panel->rgbBlueS, rgbSliderCallback, panel); to.red = 0; to.green = 0; to.blue = 255; image = RRenderGradient(141, 16, &from, &to, RGRD_HORIZONTAL); pixmap = WMCreatePixmapFromRImage(scrPtr, image, 0); RReleaseImage(image); if (pixmap) W_PaintText(W_VIEW(panel->rgbBlueS), pixmap->pixmap, panel->font12, 2, 0, 100, WALeft, scrPtr->white, False, _("Blue"), strlen(_("Blue"))); else wwarning(_("Color Panel: Could not allocate memory")); WMSetSliderImage(panel->rgbBlueS, pixmap); WMReleasePixmap(pixmap); panel->rgbBlueT = WMCreateTextField(panel->rgbFrm); WMResizeWidget(panel->rgbBlueT, 40, 18); WMMoveWidget(panel->rgbBlueT, 146, 57); WMSetTextFieldAlignment(panel->rgbBlueT, WALeft); WMAddNotificationObserver(rgbTextFieldCallback, panel, WMTextDidEndEditingNotification, panel->rgbBlueT); /* End of RGB Panel */ /* Widgets for CMYK Panel */ panel->cmykFrm = WMCreateFrame(panel->slidersFrm); WMSetFrameRelief(panel->cmykFrm, WRFlat); WMResizeWidget(panel->cmykFrm, PWIDTH - 8, PHEIGHT - 80 - 26 - 32); WMMoveWidget(panel->cmykFrm, 0, 34); panel->cmykMinL = WMCreateLabel(panel->cmykFrm); WMResizeWidget(panel->cmykMinL, 20, 10); WMMoveWidget(panel->cmykMinL, 2, 2); WMSetLabelText(panel->cmykMinL, "0"); WMSetLabelTextAlignment(panel->cmykMinL, WALeft); WMSetLabelTextColor(panel->cmykMinL, textcolor); WMSetLabelFont(panel->cmykMinL, panel->font8); panel->cmykMaxL = WMCreateLabel(panel->cmykFrm); WMResizeWidget(panel->cmykMaxL, 40, 10); WMMoveWidget(panel->cmykMaxL, 104, 2); WMSetLabelText(panel->cmykMaxL, "100"); WMSetLabelTextAlignment(panel->cmykMaxL, WARight); WMSetLabelTextColor(panel->cmykMaxL, textcolor); WMSetLabelFont(panel->cmykMaxL, panel->font8); panel->cmykCyanS = WMCreateSlider(panel->cmykFrm); WMResizeWidget(panel->cmykCyanS, 141, 16); WMMoveWidget(panel->cmykCyanS, 2, 14); WMSetSliderMinValue(panel->cmykCyanS, 0); WMSetSliderMaxValue(panel->cmykCyanS, 100); WMSetSliderKnobThickness(panel->cmykCyanS, knobThickness); WMSetSliderAction(panel->cmykCyanS, cmykSliderCallback, panel); from.red = 255; from.green = 255; from.blue = 255; to.red = 0; to.green = 255; to.blue = 255; image = RRenderGradient(141, 16, &from, &to, RGRD_HORIZONTAL); pixmap = WMCreatePixmapFromRImage(scrPtr, image, 0); RReleaseImage(image); if (pixmap) W_PaintText(W_VIEW(panel->cmykCyanS), pixmap->pixmap, panel->font12, 2, 0, 100, WALeft, scrPtr->black, False, _("Cyan"), strlen(_("Cyan"))); else wwarning(_("Color Panel: Could not allocate memory")); WMSetSliderImage(panel->cmykCyanS, pixmap); WMReleasePixmap(pixmap); panel->cmykCyanT = WMCreateTextField(panel->cmykFrm); WMResizeWidget(panel->cmykCyanT, 40, 18); WMMoveWidget(panel->cmykCyanT, 146, 13); WMSetTextFieldAlignment(panel->cmykCyanT, WALeft); WMAddNotificationObserver(cmykTextFieldCallback, panel, WMTextDidEndEditingNotification, panel->cmykCyanT); panel->cmykMagentaS = WMCreateSlider(panel->cmykFrm); WMResizeWidget(panel->cmykMagentaS, 141, 16); WMMoveWidget(panel->cmykMagentaS, 2, 36); WMSetSliderMinValue(panel->cmykMagentaS, 0); WMSetSliderMaxValue(panel->cmykMagentaS, 100); WMSetSliderKnobThickness(panel->cmykMagentaS, knobThickness); WMSetSliderAction(panel->cmykMagentaS, cmykSliderCallback, panel); to.red = 255; to.green = 0; to.blue = 255; image = RRenderGradient(141, 16, &from, &to, RGRD_HORIZONTAL); pixmap = WMCreatePixmapFromRImage(scrPtr, image, 0); RReleaseImage(image); if (pixmap) W_PaintText(W_VIEW(panel->cmykMagentaS), pixmap->pixmap, panel->font12, 2, 0, 100, WALeft, scrPtr->black, False, _("Magenta"), strlen(_("Magenta"))); else wwarning(_("Color Panel: Could not allocate memory")); WMSetSliderImage(panel->cmykMagentaS, pixmap); WMReleasePixmap(pixmap); panel->cmykMagentaT = WMCreateTextField(panel->cmykFrm); WMResizeWidget(panel->cmykMagentaT, 40, 18); WMMoveWidget(panel->cmykMagentaT, 146, 35); WMSetTextFieldAlignment(panel->cmykMagentaT, WALeft); WMAddNotificationObserver(cmykTextFieldCallback, panel, WMTextDidEndEditingNotification, panel->cmykMagentaT); panel->cmykYellowS = WMCreateSlider(panel->cmykFrm); WMResizeWidget(panel->cmykYellowS, 141, 16); WMMoveWidget(panel->cmykYellowS, 2, 58); WMSetSliderMinValue(panel->cmykYellowS, 0); WMSetSliderMaxValue(panel->cmykYellowS, 100); WMSetSliderKnobThickness(panel->cmykYellowS, knobThickness); WMSetSliderAction(panel->cmykYellowS, cmykSliderCallback, panel); to.red = 255; to.green = 255; to.blue = 0; image = RRenderGradient(141, 16, &from, &to, RGRD_HORIZONTAL); pixmap = WMCreatePixmapFromRImage(scrPtr, image, 0); RReleaseImage(image); if (pixmap) W_PaintText(W_VIEW(panel->cmykYellowS), pixmap->pixmap, panel->font12, 2, 0, 100, WALeft, scrPtr->black, False, _("Yellow"), strlen(_("Yellow"))); else wwarning(_("Color Panel: Could not allocate memory")); WMSetSliderImage(panel->cmykYellowS, pixmap); WMReleasePixmap(pixmap); panel->cmykYellowT = WMCreateTextField(panel->cmykFrm); WMResizeWidget(panel->cmykYellowT, 40, 18); WMMoveWidget(panel->cmykYellowT, 146, 57); WMSetTextFieldAlignment(panel->cmykYellowT, WALeft); WMAddNotificationObserver(cmykTextFieldCallback, panel, WMTextDidEndEditingNotification, panel->cmykYellowT); panel->cmykBlackS = WMCreateSlider(panel->cmykFrm); WMResizeWidget(panel->cmykBlackS, 141, 16); WMMoveWidget(panel->cmykBlackS, 2, 80); WMSetSliderMinValue(panel->cmykBlackS, 0); WMSetSliderMaxValue(panel->cmykBlackS, 100); WMSetSliderValue(panel->cmykBlackS, 0); WMSetSliderKnobThickness(panel->cmykBlackS, knobThickness); WMSetSliderAction(panel->cmykBlackS, cmykSliderCallback, panel); to.red = 0; to.green = 0; to.blue = 0; image = RRenderGradient(141, 16, &from, &to, RGRD_HORIZONTAL); pixmap = WMCreatePixmapFromRImage(scrPtr, image, 0); RReleaseImage(image); if (pixmap) W_PaintText(W_VIEW(panel->cmykBlackS), pixmap->pixmap, panel->font12, 2, 0, 100, WALeft, scrPtr->black, False, _("Black"), strlen(_("Black"))); else wwarning(_("Color Panel: Could not allocate memory")); WMSetSliderImage(panel->cmykBlackS, pixmap); WMReleasePixmap(pixmap); panel->cmykBlackT = WMCreateTextField(panel->cmykFrm); WMResizeWidget(panel->cmykBlackT, 40, 18); WMMoveWidget(panel->cmykBlackT, 146, 79); WMSetTextFieldAlignment(panel->cmykBlackT, WALeft); WMAddNotificationObserver(cmykTextFieldCallback, panel, WMTextDidEndEditingNotification, panel->cmykBlackT); /* End of CMYK Panel */ /* Widgets for HSB Panel */ panel->hsbFrm = WMCreateFrame(panel->slidersFrm); WMSetFrameRelief(panel->hsbFrm, WRFlat); WMResizeWidget(panel->hsbFrm, PWIDTH - 8, PHEIGHT - 80 - 26 - 32); WMMoveWidget(panel->hsbFrm, 0, 34); panel->hsbHueS = WMCreateSlider(panel->hsbFrm); WMResizeWidget(panel->hsbHueS, 141, 16); WMMoveWidget(panel->hsbHueS, 2, 14); WMSetSliderMinValue(panel->hsbHueS, 0); WMSetSliderMaxValue(panel->hsbHueS, 359); WMSetSliderKnobThickness(panel->hsbHueS, knobThickness); WMSetSliderAction(panel->hsbHueS, hsbSliderCallback, panel); panel->hsbHueT = WMCreateTextField(panel->hsbFrm); WMResizeWidget(panel->hsbHueT, 40, 18); WMMoveWidget(panel->hsbHueT, 146, 13); WMSetTextFieldAlignment(panel->hsbHueT, WALeft); WMAddNotificationObserver(hsbTextFieldCallback, panel, WMTextDidEndEditingNotification, panel->hsbHueT); panel->hsbSaturationS = WMCreateSlider(panel->hsbFrm); WMResizeWidget(panel->hsbSaturationS, 141, 16); WMMoveWidget(panel->hsbSaturationS, 2, 36); WMSetSliderMinValue(panel->hsbSaturationS, 0); WMSetSliderMaxValue(panel->hsbSaturationS, 100); WMSetSliderKnobThickness(panel->hsbSaturationS, knobThickness); WMSetSliderAction(panel->hsbSaturationS, hsbSliderCallback, panel); panel->hsbSaturationT = WMCreateTextField(panel->hsbFrm); WMResizeWidget(panel->hsbSaturationT, 40, 18); WMMoveWidget(panel->hsbSaturationT, 146, 35); WMSetTextFieldAlignment(panel->hsbSaturationT, WALeft); WMAddNotificationObserver(hsbTextFieldCallback, panel, WMTextDidEndEditingNotification, panel->hsbSaturationT); panel->hsbBrightnessS = WMCreateSlider(panel->hsbFrm); WMResizeWidget(panel->hsbBrightnessS, 141, 16); WMMoveWidget(panel->hsbBrightnessS, 2, 58); WMSetSliderMinValue(panel->hsbBrightnessS, 0); WMSetSliderMaxValue(panel->hsbBrightnessS, 100); WMSetSliderKnobThickness(panel->hsbBrightnessS, knobThickness); WMSetSliderAction(panel->hsbBrightnessS, hsbSliderCallback, panel); panel->hsbBrightnessT = WMCreateTextField(panel->hsbFrm); WMResizeWidget(panel->hsbBrightnessT, 40, 18); WMMoveWidget(panel->hsbBrightnessT, 146, 57); WMSetTextFieldAlignment(panel->hsbBrightnessT, WALeft); WMAddNotificationObserver(hsbTextFieldCallback, panel, WMTextDidEndEditingNotification, panel->hsbBrightnessT); /* End of HSB Panel */ WMReleaseColor(textcolor); /* Widgets for the CustomPalette Panel */ panel->customPaletteFrm = WMCreateFrame(panel->win); WMSetFrameRelief(panel->customPaletteFrm, WRFlat); WMResizeWidget(panel->customPaletteFrm, PWIDTH - 8, PHEIGHT - 80 - 26); WMMoveWidget(panel->customPaletteFrm, 5, 80); panel->customPaletteHistoryBtn = WMCreatePopUpButton( panel->customPaletteFrm); WMAddPopUpButtonItem(panel->customPaletteHistoryBtn, _("Spectrum")); WMSetPopUpButtonSelectedItem(panel->customPaletteHistoryBtn, WMGetPopUpButtonNumberOfItems(panel->customPaletteHistoryBtn)-1); WMSetPopUpButtonAction(panel->customPaletteHistoryBtn, customPaletteHistoryCallback, panel); WMResizeWidget(panel->customPaletteHistoryBtn, PWIDTH - 8, 20); WMMoveWidget(panel->customPaletteHistoryBtn, 0, 0); panel->customPaletteContentFrm = WMCreateFrame(panel->customPaletteFrm); WMSetFrameRelief(panel->customPaletteContentFrm, WRSunken); WMResizeWidget(panel->customPaletteContentFrm, PWIDTH - 8, PHEIGHT - 156); WMMoveWidget(panel->customPaletteContentFrm, 0, 23); panel->customPaletteContentView = W_CreateView( W_VIEW(panel->customPaletteContentFrm)); /* XXX Test if we can create a view */ W_ResizeView(panel->customPaletteContentView, customPaletteWidth, customPaletteHeight); W_MoveView(panel->customPaletteContentView, 2, 2); /* Create event handler to handle expose/click events in CustomPalette */ WMCreateEventHandler(panel->customPaletteContentView, ButtonPressMask|ButtonReleaseMask|EnterWindowMask| LeaveWindowMask | ButtonMotionMask, customPaletteHandleActionEvents, panel); WMCreateEventHandler(panel->customPaletteContentView, ExposureMask, customPaletteHandleEvents, panel); panel->customPaletteMenuBtn = WMCreatePopUpButton(panel->customPaletteFrm); WMSetPopUpButtonPullsDown(panel->customPaletteMenuBtn, 1); WMSetPopUpButtonText(panel->customPaletteMenuBtn, _("Palette")); WMSetPopUpButtonAction(panel->customPaletteMenuBtn, customPaletteMenuCallback, panel); WMResizeWidget(panel->customPaletteMenuBtn, PWIDTH - 8, 20); WMMoveWidget(panel->customPaletteMenuBtn, 0, PHEIGHT - 130); WMAddPopUpButtonItem(panel->customPaletteMenuBtn, _("New from File...")); WMAddPopUpButtonItem(panel->customPaletteMenuBtn, _("Rename...")); WMAddPopUpButtonItem(panel->customPaletteMenuBtn, _("Remove")); WMAddPopUpButtonItem(panel->customPaletteMenuBtn, _("Copy")); WMAddPopUpButtonItem(panel->customPaletteMenuBtn, _("New from Clipboard")); WMSetPopUpButtonItemEnabled(panel->customPaletteMenuBtn, CPmenuRename, 0); WMSetPopUpButtonItemEnabled(panel->customPaletteMenuBtn, CPmenuRemove, 0); WMSetPopUpButtonItemEnabled(panel->customPaletteMenuBtn, CPmenuCopy, 0); WMSetPopUpButtonItemEnabled(panel->customPaletteMenuBtn, CPmenuNewFromClipboard, 0); customRenderSpectrum(panel); panel->currentPalette = 0; panel->palx = customPaletteWidth/2; panel->paly = customPaletteHeight/2; /* Widgets for the ColorList Panel */ panel->colorListFrm = WMCreateFrame(panel->win); WMSetFrameRelief(panel->colorListFrm, WRFlat); WMResizeWidget(panel->colorListFrm, PWIDTH - 8, PHEIGHT - 80 - 26); WMMoveWidget(panel->colorListFrm, 5, 80); panel->colorListHistoryBtn = WMCreatePopUpButton(panel->colorListFrm); WMAddPopUpButtonItem(panel->colorListHistoryBtn, _("X11-Colors")); WMSetPopUpButtonSelectedItem(panel->colorListHistoryBtn, WMGetPopUpButtonNumberOfItems(panel->colorListHistoryBtn)-1); /* WMSetPopUpButtonAction(panel->colorListHistoryBtn, * colorListHistoryCallback, panel); */ WMResizeWidget(panel->colorListHistoryBtn, PWIDTH - 8, 20); WMMoveWidget(panel->colorListHistoryBtn, 0, 0); panel->colorListContentLst = WMCreateList(panel->colorListFrm); WMSetListAction(panel->colorListContentLst, colorListSelect, panel); WMSetListUserDrawProc(panel->colorListContentLst, colorListPaintItem); WMResizeWidget(panel->colorListContentLst, PWIDTH - 8, PHEIGHT - 156); WMMoveWidget(panel->colorListContentLst, 0, 23); WMHangData(panel->colorListContentLst, panel); panel->colorListColorMenuBtn = WMCreatePopUpButton(panel->colorListFrm); WMSetPopUpButtonPullsDown(panel->colorListColorMenuBtn, 1); WMSetPopUpButtonText(panel->colorListColorMenuBtn, _("Color")); WMSetPopUpButtonAction(panel->colorListColorMenuBtn, colorListColorMenuCallback, panel); WMResizeWidget(panel->colorListColorMenuBtn, (PWIDTH - 16)/2, 20); WMMoveWidget(panel->colorListColorMenuBtn, 0, PHEIGHT - 130); WMAddPopUpButtonItem(panel->colorListColorMenuBtn, _("Add...")); WMAddPopUpButtonItem(panel->colorListColorMenuBtn, _("Rename...")); WMAddPopUpButtonItem(panel->colorListColorMenuBtn, _("Remove")); WMSetPopUpButtonItemEnabled(panel->colorListColorMenuBtn, CLmenuAdd, 0); WMSetPopUpButtonItemEnabled(panel->colorListColorMenuBtn, CLmenuRename, 0); WMSetPopUpButtonItemEnabled(panel->colorListColorMenuBtn, CLmenuRemove, 0); panel->colorListListMenuBtn = WMCreatePopUpButton(panel->colorListFrm); WMSetPopUpButtonPullsDown(panel->colorListListMenuBtn, 1); WMSetPopUpButtonText(panel->colorListListMenuBtn, _("List")); WMSetPopUpButtonAction(panel->colorListListMenuBtn, colorListListMenuCallback, panel); WMResizeWidget(panel->colorListListMenuBtn, (PWIDTH - 16)/2, 20); WMMoveWidget(panel->colorListListMenuBtn, (PWIDTH - 16)/2 + 8, PHEIGHT - 130); WMAddPopUpButtonItem(panel->colorListListMenuBtn, _("New...")); WMAddPopUpButtonItem(panel->colorListListMenuBtn, _("Rename...")); WMAddPopUpButtonItem(panel->colorListListMenuBtn, _("Remove")); WMSetPopUpButtonItemEnabled(panel->colorListListMenuBtn, CLmenuAdd, 0); WMSetPopUpButtonItemEnabled(panel->colorListListMenuBtn, CLmenuRename, 0); WMSetPopUpButtonItemEnabled(panel->colorListListMenuBtn, CLmenuRemove, 0); WMRealizeWidget(panel->win); WMMapSubwidgets(panel->win); WMMapSubwidgets(panel->wheelFrm); WMMapSubwidgets(panel->slidersFrm); WMMapSubwidgets(panel->grayFrm); WMMapSubwidgets(panel->rgbFrm); WMMapSubwidgets(panel->cmykFrm); WMMapSubwidgets(panel->hsbFrm); WMMapSubwidgets(panel->customPaletteFrm); WMMapSubwidgets(panel->customPaletteContentFrm); WMMapSubwidgets(panel->colorListFrm); /* Pixmap to indicate selection positions * wheelframe MUST be mapped. */ panel->selectionImg = XCreatePixmap(scrPtr->display, WMWidgetXID(panel->win), 4, 4, scrPtr->depth); XFillRectangle(scrPtr->display, panel->selectionImg, bgc, 0, 0, 4, 4); XFillRectangle(scrPtr->display, panel->selectionImg, wgc, 1, 1, 2, 2); readConfiguration(panel); readXColors(panel); return panel; } WMColorPanel* WMGetColorPanel(WMScreen *scrPtr) { WMColorPanel *panel; if (scrPtr->sharedColorPanel) return scrPtr->sharedColorPanel; panel = makeColorPanel(scrPtr, "colorPanel"); scrPtr->sharedColorPanel = panel; return panel; } void WMFreeColorPanel(WMColorPanel *panel) { W_Screen *scr = WMWidgetScreen(panel->win); if (panel == scr->sharedColorPanel) { scr->sharedColorPanel = NULL; } if (!panel) return; WMRemoveNotificationObserver(panel); WMUnmapWidget(panel->win); /* fonts */ WMReleaseFont(panel->font8); WMReleaseFont(panel->font12); /* pixmaps */ wheelDestroyMatrix(panel->wheelMtrx); if (panel->wheelImg) XFreePixmap(scr->display, panel->wheelImg); if (panel->selectionImg) XFreePixmap(scr->display, panel->selectionImg); if (panel->selectionBackImg) XFreePixmap(scr->display, panel->selectionBackImg); RReleaseImage(panel->customPaletteImg); /* structs */ if (panel->lastBrowseDir) wfree(panel->lastBrowseDir); if (panel->configurationPath) wfree(panel->configurationPath); WMDestroyWidget(panel->win); wfree(panel); } void WMCloseColorPanel(WMColorPanel *panel) { WMFreeColorPanel(panel); } void WMShowColorPanel(WMColorPanel *panel) { WMScreen *scr = WMWidgetScreen(panel->win); WMColor *white = WMWhiteColor(scr); if (panel->color.set == cpNone) WMSetColorPanelColor(panel, white); WMReleaseColor(white); if (panel->mode != WMWheelModeColorPanel) WMPerformButtonClick(panel->wheelBtn); WMMapWidget(panel->win); } static void closeWindowCallback(WMWidget *w, void *data) { W_ColorPanel *panel = (W_ColorPanel*)data; WMCloseColorPanel(panel); } static void readConfiguration(W_ColorPanel *panel) { /* XXX Doesn't take care of "invalid" files */ DIR *dPtr; struct dirent *dp; struct stat stat_buf; int item; if (stat(panel->configurationPath, &stat_buf)!=0) { if (mkdir(panel->configurationPath, S_IRWXU|S_IRGRP|S_IROTH|S_IXGRP|S_IXOTH)!=0) { wsyserror(_("Color Panel: Could not create directory %s needed" " to store configurations"), panel->configurationPath); WMSetPopUpButtonEnabled(panel->customPaletteMenuBtn, False); WMSetPopUpButtonEnabled(panel->colorListColorMenuBtn, False); WMSetPopUpButtonEnabled(panel->colorListListMenuBtn, False); WMRunAlertPanel(WMWidgetScreen(panel->win), panel->win, _("File Error"), _("Could not create ColorPanel configuration directory"), _("OK"), NULL, NULL); } return; } if (!(dPtr = opendir(panel->configurationPath))) { wwarning(_("Color Panel: Could not find file"), "%s", panel->configurationPath); return; } while ((dp = readdir(dPtr)) != NULL) { unsigned int perm_mask; char *path = wstrconcat(panel->configurationPath, dp->d_name); if (dp->d_name[0] != '.') { item = WMGetPopUpButtonNumberOfItems( panel->customPaletteHistoryBtn); WMAddPopUpButtonItem(panel->customPaletteHistoryBtn, dp->d_name); perm_mask = (access(path, R_OK) == 0); WMSetPopUpButtonItemEnabled(panel->customPaletteHistoryBtn, item, perm_mask); } wfree(path); } (void)closedir(dPtr); } static void readXColors(W_ColorPanel *panel) { struct stat stat_buf; FILE *rgbtxt; char line[MAX_LENGTH]; int red, green, blue; char name[48]; RColor *color; WMListItem *item; if (stat(RGBTXT, &stat_buf) != 0) { wsyserror(_("Color Panel: Could not find file"), " %s", RGBTXT); return; } else { if ((rgbtxt = fopen(RGBTXT, "rb"))) { while (fgets(line, MAX_LENGTH, rgbtxt)) { if (sscanf(line, "%d%d%d %[^\n]", &red, &green, &blue, name)) { color = wmalloc(sizeof(RColor)); color->red = (unsigned char)red; color->green = (unsigned char)green; color->blue = (unsigned char)blue; item = WMAddListItem(panel->colorListContentLst, name); item->clientData = (void *)color; } } fclose(rgbtxt); } else { wsyserror(_("Color Panel: Could not find file"), "%s", RGBTXT); } } } void WMSetColorPanelPickerMode(WMColorPanel *panel, WMColorPanelMode mode) { W_Screen *scr = WMWidgetScreen(panel->win); if (mode != WMWheelModeColorPanel) { WMUnmapWidget(panel->wheelFrm); if (panel->selectionBackImg) { XFreePixmap(WMWidgetScreen(panel->win)->display, panel->selectionBackImg); panel->selectionBackImg = None; } } if (mode != WMGrayModeColorPanel) WMUnmapWidget(panel->grayFrm); if (mode != WMRGBModeColorPanel) WMUnmapWidget(panel->rgbFrm); if (mode != WMCMYKModeColorPanel) WMUnmapWidget(panel->cmykFrm); if (mode != WMHSBModeColorPanel) WMUnmapWidget(panel->hsbFrm); if (mode != WMCustomPaletteModeColorPanel) { WMUnmapWidget(panel->customPaletteFrm); if (panel->selectionBackImg) { XFreePixmap(WMWidgetScreen(panel->win)->display, panel->selectionBackImg); panel->selectionBackImg = None; } } if (mode != WMColorListModeColorPanel) WMUnmapWidget(panel->colorListFrm); if ((mode != WMGrayModeColorPanel) && (mode != WMRGBModeColorPanel) && (mode != WMCMYKModeColorPanel) && (mode != WMHSBModeColorPanel)) WMUnmapWidget(panel->slidersFrm); else panel->slidersmode = mode; if (mode == WMWheelModeColorPanel) { WMMapWidget(panel->wheelFrm); WMSetButtonSelected(panel->wheelBtn, True); if (panel->lastChanged != WMWheelModeColorPanel) wheelInit(panel); wheelRender(panel); wheelPaint(panel); } else if (mode == WMGrayModeColorPanel) { WMMapWidget(panel->slidersFrm); WMSetButtonSelected(panel->slidersBtn, True); WMMapWidget(panel->grayFrm); WMSetButtonSelected(panel->grayBtn, True); WMSetButtonImage(panel->slidersBtn, scr->grayIcon); if (panel->lastChanged != WMGrayModeColorPanel) grayInit(panel); } else if (mode == WMRGBModeColorPanel) { WMMapWidget(panel->slidersFrm); WMSetButtonSelected(panel->slidersBtn, True); WMMapWidget(panel->rgbFrm); WMSetButtonSelected(panel->rgbBtn, True); WMSetButtonImage(panel->slidersBtn, scr->rgbIcon); if (panel->lastChanged != WMRGBModeColorPanel) rgbInit(panel); } else if (mode == WMCMYKModeColorPanel) { WMMapWidget(panel->slidersFrm); WMSetButtonSelected(panel->slidersBtn, True); WMMapWidget(panel->cmykFrm); WMSetButtonSelected(panel->cmykBtn, True); WMSetButtonImage(panel->slidersBtn, scr->cmykIcon); if (panel->lastChanged != WMCMYKModeColorPanel) cmykInit(panel); } else if (mode == WMHSBModeColorPanel) { WMMapWidget(panel->slidersFrm); WMSetButtonSelected(panel->slidersBtn, True); WMMapWidget(panel->hsbFrm); WMSetButtonSelected(panel->hsbBtn, True); WMSetButtonImage(panel->slidersBtn, scr->hsbIcon); if (panel->lastChanged != WMHSBModeColorPanel) hsbInit(panel); } else if (mode == WMCustomPaletteModeColorPanel) { WMMapWidget(panel->customPaletteFrm); WMSetButtonSelected(panel->customPaletteBtn, True); customSetPalette(panel); } else if (mode == WMColorListModeColorPanel) { WMMapWidget(panel->colorListFrm); WMSetButtonSelected(panel->colorListBtn, True); } panel->mode = mode; } WMColor* WMGetColorPanelColor(WMColorPanel *panel) { return WMGetColorWellColor(panel->colorWell); } void WMSetColorPanelColor(WMColorPanel *panel, WMColor *color) { WMSetColorWellColor(panel->colorWell, color); panel->color.rgb.red = color->color.red >> 8; panel->color.rgb.green = color->color.green >> 8; panel->color.rgb.blue = color->color.blue >> 8; panel->color.set = cpRGB; if (panel->mode == panel->lastChanged) panel->lastChanged = 0; WMSetColorPanelPickerMode(panel, panel->mode); } static void updateSwatch(WMColorPanel *panel, CPColor color) { WMScreen *scr = WMWidgetScreen(panel->win); WMColor *wellcolor; if (color.set != cpRGB) convertCPColor(&color); panel->color = color; wellcolor = WMCreateRGBColor(scr, color.rgb.red << 8, color.rgb.green << 8, color.rgb.blue << 8, True); WMSetColorWellColor(panel->colorWell, wellcolor); WMReleaseColor(wellcolor); if (!panel->flags.dragging || panel->flags.continuous) { if (panel->action) (*panel->action)(panel, panel->clientData); WMPostNotificationName(WMColorPanelColorChangedNotification, panel, NULL); } } static void modeButtonCallback(WMWidget *w, void *data) { W_ColorPanel *panel = (W_ColorPanel*)(data); if (w == panel->wheelBtn) WMSetColorPanelPickerMode(panel, WMWheelModeColorPanel); else if (w == panel->slidersBtn) WMSetColorPanelPickerMode(panel, panel->slidersmode); else if (w == panel->customPaletteBtn) WMSetColorPanelPickerMode(panel, WMCustomPaletteModeColorPanel); else if (w == panel->colorListBtn) WMSetColorPanelPickerMode(panel, WMColorListModeColorPanel); else if (w == panel->grayBtn) WMSetColorPanelPickerMode(panel, WMGrayModeColorPanel); else if (w == panel->rgbBtn) WMSetColorPanelPickerMode(panel, WMRGBModeColorPanel); else if (w == panel->cmykBtn) WMSetColorPanelPickerMode(panel, WMCMYKModeColorPanel); else if (w == panel->hsbBtn) WMSetColorPanelPickerMode(panel, WMHSBModeColorPanel); } /****************** Magnifying Cursor Functions *******************/ static XImage* magnifyGetImage(WMScreen *scr, XImage *image, int x, int y, int w, int h) { int x0 = 0, y0 = 0, w0 = w, h0 = h; const int displayWidth = DisplayWidth(scr->display, scr->screen), displayHeight = DisplayHeight(scr->display, scr->screen); if (!(image && image->data)) { /* The image in panel->magnifyGlass->image does not exist yet. * Grab one from the screen (not beyond) and use it from now on. */ if (!(image = XGetImage(scr->display, scr->rootWin, x - Cursor_x_hot, y - Cursor_y_hot, w, h, AllPlanes, ZPixmap))) wwarning(_("Color Panel: X failed request")); return image; } /* Coordinate correction for back pixmap * if magnifying glass is at screen-borders */ /* Figure 1: Shifting of rectangle-to-grab at top/left screen borders * Hatched area is beyond screen border. * * |<-Cursor_x_hot->| * ________________|_____ * |/ / / / / / /| | | * | / / / / / / |(x,y) | * |/_/_/_/_/_/_/|________| * |<----x0----->|<--w0-->| * 0 */ /* Figure 2: Shifting of rectangle-to-grab at bottom/right * screen borders * Hatched area is beyond screen border * * |<-Cursor_x_hot->| * ________________|_______________ * | | | / / / / / /| * | (x,y)|/ / / / / / | * |___________________|_/_/_/_/_/_/| * |<-------w0-------->| | * |<---------------w--|----------->| * | | * x0 Displaywidth-1 */ if (x < Cursor_x_hot) { /* see fig. 1 */ x0 = Cursor_x_hot - x; w0 = w - x0; } if (displayWidth -1 < x - Cursor_x_hot + w) { /* see fig. 2 */ w0 = (displayWidth) - (x - Cursor_x_hot); } if (y < Cursor_y_hot) { /* see fig. 1 */ y0 = Cursor_y_hot - y; h0 = h - y0; } if (displayHeight -1 < y - Cursor_y_hot + h) { /* see fig. 2 */ h0 = (displayHeight) - (y - Cursor_y_hot); } /* end of coordinate correction */ /* Grab an image from the screen, clipped if necessary, * and put it in the existing panel->magnifyGlass->image * with the corresponding clipping offset. */ if (!XGetSubImage(scr->display, scr->rootWin, x - Cursor_x_hot + x0, y - Cursor_y_hot + y0, w0, h0, AllPlanes, ZPixmap, image, x0, y0)) wwarning(_("Color Panel: X failed request")); return NULL; } static void magnifyGetImageStored(WMColorPanel *panel, int x1, int y1, int x2, int y2) { /* (x1, y1) = topleft corner of existing rectangle * (x2, y2) = topleft corner of new position */ W_Screen *scr = WMWidgetScreen(panel->win); int xa = 0, ya = 0, xb = 0, yb = 0; int width, height; const int dx = abs(x2 - x1), dy = abs(y2 - y1); XImage *image; const int x_min = Cursor_x_hot, y_min = Cursor_y_hot, x_max = DisplayWidth(scr->display, scr->screen) -1 - (Cursor_mask_width - Cursor_x_hot), y_max = DisplayHeight(scr->display, scr->screen) -1 - (Cursor_mask_height - Cursor_y_hot); if ((dx == 0) && (dy == 0) && panel->magnifyGlass->image) return; /* No movement */ if (x1 < x2) xa = dx; else xb = dx; if (y1 < y2) ya = dy; else yb = dy; width = Cursor_mask_width - dx; height = Cursor_mask_height - dy; /* If the traversed distance is larger than the size of the magnifying * glass contents, there is no need to do dirty rectangles. A whole new * rectangle can be grabbed (unless that rectangle falls partially * off screen). * Destroying the image and setting it to NULL will achieve that later on. * * Of course, grabbing an XImage beyond the borders of the screen will * cause trouble, this is considdered a special case. Part of the screen * is grabbed, but there is no need for dirty rectangles. */ if ((width <= 0) || (height <= 0)) { if ((x2 >= x_min) && (y2 >= y_min) && (x2 <= x_max) && (y2 <= y_max)) { if (panel->magnifyGlass->image) XDestroyImage(panel->magnifyGlass->image); panel->magnifyGlass->image = NULL; } } else { if (panel->magnifyGlass->image) { /* Get dirty rectangle from panel->magnifyGlass->image */ panel->magnifyGlass->dirtyRect = XSubImage(panel->magnifyGlass->image, xa, ya, width, height); if (!panel->magnifyGlass->dirtyRect) { wwarning(_("Color Panel: X failed request")); return; /* X returned a NULL from XSubImage */ } } } /* Get image from screen */ image = magnifyGetImage(scr, panel->magnifyGlass->image, x2, y2, Cursor_mask_width, Cursor_mask_height); if (image) { /* Only reassign if a *new* image was grabbed */ panel->magnifyGlass->image = image; return; } /* Copy previously stored rectangle on covered part of image */ if (panel->magnifyGlass->image && panel->magnifyGlass->dirtyRect) { int old_height; /* "width" and "height" are used as coordinates here, * and run from [0...width-1] and [0...height-1] respectively. */ width--; height--; old_height = height; for (; width >= 0; width--) for (height = old_height; height >= 0; height--) XPutPixel(panel->magnifyGlass->image, xb + width, yb + height, XGetPixel(panel->magnifyGlass->dirtyRect, width, height)); XDestroyImage(panel->magnifyGlass->dirtyRect); panel->magnifyGlass->dirtyRect = NULL; } return; } static Pixmap magnifyCreatePixmap(WMColorPanel *panel) { W_Screen *scr = WMWidgetScreen(panel->win); int u, v; #ifndef SHAPE Pixmap pixmap; #endif unsigned long color; if (!panel->magnifyGlass->image) return None; if (!panel->magnifyGlass->magPix) return None; /* * Copy an area of only 5x5 pixels from the center of the image. */ for (u = 0; u < 5; u++) { for (v = 0; v < 5; v++) { color = XGetPixel(panel->magnifyGlass->image, u + 9, v + 9); XSetForeground(scr->display, scr->copyGC, color); if ((u == 2) && (v == 2)) /* (2,2) is center pixel (unmagn.) */ panel->magnifyGlass->color = ulongToRColor(scr, color); /* The center square must eventually be centered around the * hotspot. The image needs shifting to achieve this. The amount of * shifting is (Cursor_mask_width/2 - 2 * square_size) = 11-10 = 1 * _ _ _ _ _ * |_|_|_|_|_| * ^------- center of center square == Cursor_x_hot */ XFillRectangle(scr->display, panel->magnifyGlass->magPix, scr->copyGC, u * 5 + (u == 0 ? 0 : -1), v * 5 + (v == 0 ? 0 : -1), (u == 0 ? 4 : 5), (v == 0 ? 4 : 5)); } } #ifdef SHAPE return panel->magnifyGlass->magPix; #else pixmap = XCreatePixmap(scr->display, W_DRAWABLE(scr), Cursor_mask_width, Cursor_mask_height, scr->depth); if (!pixmap) return None; XPutImage(scr->display, pixmap, scr->copyGC, panel->magnifyGlass->image, 0, 0, 0, 0, Cursor_mask_width, Cursor_mask_height); /* Copy the magnified pixmap, with the clip mask, to background pixmap */ XCopyArea(scr->display, panel->magnifyGlass->magPix, pixmap, scr->clipGC, 0, 0, Cursor_mask_width, Cursor_mask_height, 0, 0); /* (2,2) puts center pixel on center of glass */ return pixmap; #endif } static WMView* magnifyCreateView(W_ColorPanel *panel) { W_Screen *scr = WMWidgetScreen(panel->win); WMView *magView; magView = W_CreateTopView(scr); if (!magView) return NULL; magView->self = panel->win; magView->flags.topLevel = 1; magView->attribFlags |= CWOverrideRedirect | CWSaveUnder; magView->attribs.override_redirect = True; magView->attribs.save_under = True; W_ResizeView(magView, Cursor_mask_width, Cursor_mask_height); W_RealizeView(magView); return magView; } static Cursor magnifyGrabPointer(W_ColorPanel *panel) { W_Screen *scr = WMWidgetScreen(panel->win); Pixmap magPixmap, magPixmap2; Cursor magCursor; XColor fgColor = {0, 0,0,0, DoRed|DoGreen|DoBlue}; XColor bgColor = {0, 0xbf00, 0xa000, 0x5000, DoRed|DoGreen|DoBlue}; /* Cursor creation stuff */ magPixmap = XCreatePixmapFromBitmapData(scr->display, W_DRAWABLE(scr), (char *)Cursor_bits, Cursor_width, Cursor_height, 1, 0, 1); magPixmap2 = XCreatePixmapFromBitmapData(scr->display, W_DRAWABLE(scr), (char *)Cursor_shape_bits, Cursor_width, Cursor_height, 1, 0, 1); magCursor = XCreatePixmapCursor(scr->display, magPixmap, magPixmap2, &fgColor, &bgColor, Cursor_x_hot, Cursor_y_hot); XFreePixmap(scr->display, magPixmap); XFreePixmap(scr->display, magPixmap2); XRecolorCursor(scr->display, magCursor, &fgColor, &bgColor); /* Set up Pointer */ XGrabPointer (scr->display, panel->magnifyGlass->view->window, True, PointerMotionMask | ButtonPressMask, GrabModeAsync, GrabModeAsync, scr->rootWin, magCursor, CurrentTime); return magCursor; } static WMPoint magnifyInitialize(W_ColorPanel *panel) { W_Screen *scr = WMWidgetScreen(panel->win); int x, y, u, v; unsigned int mask; Pixmap pixmap, clip_mask; WMPoint point; Window root_return, child_return; clip_mask = XCreatePixmapFromBitmapData(scr->display, W_DRAWABLE(scr), (char *)Cursor_mask_bits, Cursor_mask_width, Cursor_mask_height, 1, 0, 1); panel->magnifyGlass->magPix = XCreatePixmap(scr->display, W_DRAWABLE(scr), 5*5 -1, 5*5 -1, scr->depth); XQueryPointer(scr->display, scr->rootWin, &root_return, &child_return, &x, &y, &u, &v, &mask); panel->magnifyGlass->image = NULL; /* Clipmask to make magnified view-contents circular */ #ifdef SHAPE XShapeCombineMask(scr->display, WMViewXID(panel->magnifyGlass->view), ShapeBounding, 0, 0, clip_mask, ShapeSet); #else /* Clip circle in glass cursor */ XSetClipMask(scr->display, scr->clipGC, clip_mask); XSetClipOrigin(scr->display, scr->clipGC, 0, 0); #endif XFreePixmap(scr->display, clip_mask); /* Draw initial magnifying glass contents */ magnifyGetImageStored(panel, x, y, x, y); pixmap = magnifyCreatePixmap(panel); XSetWindowBackgroundPixmap(scr->display, WMViewXID(panel->magnifyGlass->view), pixmap); XClearWindow(scr->display, WMViewXID(panel->magnifyGlass->view)); XFlush(scr->display); #ifndef SHAPE XFreePixmap(scr->display, pixmap); #endif point.x = x; point.y = y; return point; } static void magnifyPutCursor(WMWidget *w, void *data) { W_ColorPanel *panel = (W_ColorPanel*)(data); W_Screen *scr = WMWidgetScreen(panel->win); Cursor magCursor; Pixmap pixmap; XEvent event; WMPoint initialPosition; /* Destroy wheelBackImg, so it'll update properly */ if (panel->selectionBackImg) { XFreePixmap(WMWidgetScreen(panel->win)->display, panel->selectionBackImg); panel->selectionBackImg = None; } /* Create magnifying glass */ panel->magnifyGlass = wmalloc(sizeof(MovingView)); panel->magnifyGlass->view = magnifyCreateView(panel); if (!panel->magnifyGlass->view) return; initialPosition = magnifyInitialize(panel); panel->magnifyGlass->x = initialPosition.x; panel->magnifyGlass->y = initialPosition.y; W_MoveView(panel->magnifyGlass->view, panel->magnifyGlass->x - Cursor_x_hot, panel->magnifyGlass->y - Cursor_y_hot); W_MapView(panel->magnifyGlass->view); magCursor = magnifyGrabPointer(panel); while (panel->magnifyGlass->image) { WMNextEvent(scr->display, &event); /* Pack motion events */ while (XCheckTypedEvent(scr->display, MotionNotify, &event)) { } switch (event.type) { case ButtonPress: XDestroyImage(panel->magnifyGlass->image); panel->magnifyGlass->image = NULL; if (event.xbutton.button == Button1) { panel->color.rgb = panel->magnifyGlass->color; panel->color.set = cpRGB; updateSwatch(panel, panel->color); } switch (panel->mode) { case WMWheelModeColorPanel: wheelInit(panel); wheelRender(panel); wheelPaint(panel); break; case WMGrayModeColorPanel: grayInit(panel); break; case WMRGBModeColorPanel: rgbInit(panel); break; case WMCMYKModeColorPanel: cmykInit(panel); break; case WMHSBModeColorPanel: hsbInit(panel); break; default: break; } panel->lastChanged = panel->mode; WMSetButtonSelected(panel->magnifyBtn, False); break; case MotionNotify: while (XPending(event.xmotion.display)) { XEvent ev; XPeekEvent(event.xmotion.display, &ev); if (ev.type == MotionNotify) XNextEvent(event.xmotion.display, &event); else break; } /* Get a "dirty rectangle" */ magnifyGetImageStored( panel, panel->magnifyGlass->x, panel->magnifyGlass->y, event.xmotion.x_root, event.xmotion.y_root); /* Update coordinates */ panel->magnifyGlass->x = event.xmotion.x_root; panel->magnifyGlass->y = event.xmotion.y_root; /* Move view */ W_MoveView(panel->magnifyGlass->view, panel->magnifyGlass->x - Cursor_x_hot, panel->magnifyGlass->y - Cursor_y_hot); /* Put new image (with magn.) in view */ pixmap = magnifyCreatePixmap(panel); if (pixmap != None) { /* Change the window background */ XSetWindowBackgroundPixmap(scr->display, WMViewXID(panel->magnifyGlass->view), pixmap); /* Force an Expose (handled by X) */ XClearWindow(scr->display, WMViewXID(panel->magnifyGlass->view)); /* Synchronize the event queue, so the Expose is handled NOW */ XFlush(scr->display); #ifndef SHAPE XFreePixmap(scr->display, pixmap); #endif } break; /* Try XQueryPointer for this !!! It returns windows that the pointer * is over. Note: We found this solving the invisible donkey cap bug */ #if 0 /* As it is impossible to make this work in all cases, * we consider it confusing. Therefore we disabled it. */ case FocusOut: /* fall through */ case FocusIn: /* * Color Panel window (panel->win) lost or received focus. * We need to update the pixmap in the magnifying glass. * * BUG Doesn't work with focus switches between two windows * if none of them is the color panel. */ XUngrabPointer(scr->display, CurrentTime); W_UnmapView(panel->magnifyGlass->view); magnifyInitialize(panel); W_MapView(panel->magnifyGlass->view); XGrabPointer (scr->display, panel->magnifyGlass->view->window, True, PointerMotionMask | ButtonPressMask, GrabModeAsync, GrabModeAsync, scr->rootWin, magCursor, CurrentTime); break; #endif default: WMHandleEvent(&event); break; } /* of switch */ } XUngrabPointer(scr->display, CurrentTime); XFreeCursor(scr->display, magCursor); XFreePixmap(scr->display, panel->magnifyGlass->magPix); panel->magnifyGlass->magPix = None; W_UnmapView(panel->magnifyGlass->view); W_DestroyView(panel->magnifyGlass->view); panel->magnifyGlass->view = NULL; wfree(panel->magnifyGlass); } /****************** ColorWheel Functions ************************/ static wheelMatrix* wheelCreateMatrix(unsigned int width, unsigned int height) { wheelMatrix *matrix = NULL; int i; assert((width > 0) && (height > 0)); matrix = wmalloc(sizeof(wheelMatrix)); memset(matrix, 0, sizeof(wheelMatrix)); matrix->width = width; matrix->height = height; for (i = 0; i < 3; i++) { matrix->data[i] = wmalloc(width*height*sizeof(unsigned char)); } return matrix; } static void wheelDestroyMatrix(wheelMatrix *matrix) { int i; if (!matrix) return; for (i = 0; i < 3; i++) { if (matrix->data[i]) wfree(matrix->data[i]); } wfree(matrix); } static void wheelInitMatrix(W_ColorPanel *panel) { int i; int x,y; unsigned char *rp, *gp, *bp; CPColor cpColor; long ofs[4]; int xcor, ycor; unsigned short sat; int dhue[4]; const int cw_halfsize = (colorWheelSize + 4)/2, cw_sqsize = (colorWheelSize +4) * (colorWheelSize +4), uchar_shift = getShift(sizeof(unsigned char)); if (!panel->wheelMtrx) return; cpColor.hsv.value = 255; cpColor.set = cpHSV; ofs[0] = -1; ofs[1] = -(colorWheelSize + 4); /* offsets are counterclockwise (in triangles). * * ofs[0] ----> * _______________________________________ * [1] |_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_| o * s |_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_| f * f |_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_|_| s * o | | | | | | | | | | | | | | | | | | | | | [3] * * <---- ofs[2] * ____ * |\ /| <-- triangles * | \/ | * | /\ | * |/__\| */ for (y = 0; y < cw_halfsize; y++) { for (x = y; x < (colorWheelSize+4-y); x++) { /* (xcor, ycor) is (x,y) relative to center of matrix */ xcor = 2 * x - 4 - colorWheelSize; ycor = 2 * y - 4 - colorWheelSize; /* RColor.saturation is unsigned char and will wrap after 255 */ sat = rint(255.0 * sqrt(xcor*xcor + ycor*ycor) / colorWheelSize); cpColor.hsv.saturation = (unsigned char)sat; ofs[0]++; /* top quarter of matrix*/ ofs[1] += colorWheelSize + 4; /* left quarter */ ofs[2] = cw_sqsize - 1 - ofs[0]; /* bottom quarter */ ofs[3] = cw_sqsize - 1 - ofs[1]; /* right quarter */ if (sat < 256) { if (xcor != 0) dhue[0] = rint(atan((double)ycor / (double)xcor) * (180.0 / M_PI)) + (xcor < 0 ? 180.0 : 0.0); else dhue[0] = 270; dhue[0] = 360 - dhue[0]; /* Reverse direction of ColorWheel */ dhue[1] = 270 - dhue[0] + (dhue[0] > 270 ? 360 : 0); dhue[2] = dhue[0] - 180 + (dhue[0] < 180 ? 360 : 0); dhue[3] = 90 - dhue[0] + (dhue[0] > 90 ? 360 : 0); for (i = 0; i < 4; i++) { rp = panel->wheelMtrx->data[0] + (ofs[i] << uchar_shift); gp = panel->wheelMtrx->data[1] + (ofs[i] << uchar_shift); bp = panel->wheelMtrx->data[2] + (ofs[i] << uchar_shift); cpColor.hsv.hue = dhue[i]; convertCPColor(&cpColor); *rp = (unsigned char)(cpColor.rgb.red); *gp = (unsigned char)(cpColor.rgb.green); *bp = (unsigned char)(cpColor.rgb.blue); } } else { for (i = 0; i < 4; i++) { rp = panel->wheelMtrx->data[0] + (ofs[i] << uchar_shift); gp = panel->wheelMtrx->data[1] + (ofs[i] << uchar_shift); bp = panel->wheelMtrx->data[2] + (ofs[i] << uchar_shift); *rp = (unsigned char)0; *gp = (unsigned char)0; *bp = (unsigned char)0; } } } ofs[0] += 2*y+1; ofs[1] += 1 - (colorWheelSize + 4) * (colorWheelSize + 4 - 1 - 2*y); } } static void wheelCalculateValues(W_ColorPanel *panel, int maxvalue) { unsigned int i; unsigned int v; for (i = 0; i < 256; i++) { /* We divide by 128 in advance, and check whether that number divides * by 2 properly. If not, we add one to round the number correctly */ v = (i*maxvalue) >> 7; panel->wheelMtrx->values[i] = (unsigned char)((v >> 1) +(v & 0x01)); } } static void wheelRender(W_ColorPanel *panel) { W_Screen *scr = WMWidgetScreen(panel->win); int x,y; RImage *image; unsigned char *ptr; RColor gray; unsigned long ofs = 0; /*unsigned char shift = getShift(sizeof(unsigned char));*/ image = RCreateImage(colorWheelSize+4, colorWheelSize+4, True); if (!image) { wwarning(_("Color Panel: Could not allocate memory")); return; } ptr = image->data; /* TODO Make this transparent istead of gray */ gray.red = gray.blue = 0xae; gray.green = 0xaa; for (y = 0; y < colorWheelSize+4; y++) { for (x = 0; x < colorWheelSize+4; x++) { if (wheelInsideColorWheel(panel, ofs)) { *(ptr++) = (unsigned char)(panel->wheelMtrx->values[ panel->wheelMtrx->data[0][ofs] ]); *(ptr++) = (unsigned char)(panel->wheelMtrx->values[ panel->wheelMtrx->data[1][ofs] ]); *(ptr++) = (unsigned char)(panel->wheelMtrx->values[ panel->wheelMtrx->data[2][ofs] ]); *(ptr++) = 0; } else { *(ptr++) = (unsigned char)(gray.red); *(ptr++) = (unsigned char)(gray.green); *(ptr++) = (unsigned char)(gray.blue); *(ptr++) = 255; } ofs++; } } if (panel->wheelImg) XFreePixmap(scr->display, panel->wheelImg); RConvertImage(scr->rcontext, image, &panel->wheelImg); RReleaseImage(image); /* Check if backimage exists. If it doesn't, allocate and fill it */ if (!panel->selectionBackImg) { panel->selectionBackImg = XCreatePixmap(scr->display, W_VIEW(panel->wheelFrm)->window, 4, 4, scr->depth); XCopyArea(scr->display, panel->wheelImg, panel->selectionBackImg, scr->copyGC, panel->colx -2, panel->coly -2, 4, 4, 0, 0); /* -2 is hot spot correction */ } } static Bool wheelInsideColorWheel(W_ColorPanel *panel, unsigned long ofs) { return ((panel->wheelMtrx->data[0][ofs] != 0) && (panel->wheelMtrx->data[1][ofs] != 0) && (panel->wheelMtrx->data[2][ofs] != 0)); } static void wheelPaint (W_ColorPanel *panel) { W_Screen *scr = WMWidgetScreen(panel->win); XCopyArea(scr->display, panel->wheelImg, panel->wheelView->window, scr->copyGC, 0, 0, colorWheelSize+4, colorWheelSize+4, 0, 0); /* Draw selection image */ XCopyArea(scr->display, panel->selectionImg, panel->wheelView->window, scr->copyGC, 0, 0, 4, 4, panel->colx -2, panel->coly -2); } static void wheelHandleEvents(XEvent *event, void *data) { W_ColorPanel *panel = (W_ColorPanel*)data; switch (event->type) { case Expose: if (event->xexpose.count != 0) /* TODO Improve */ break; wheelPaint(panel); break; } } static void wheelHandleActionEvents(XEvent *event, void *data) { W_ColorPanel *panel = (W_ColorPanel*)data; switch (event->type) { case ButtonPress: if (getPickerPart(panel, event->xbutton.x, event->xbutton.y) == COLORWHEEL_PART) { panel->lastChanged = WMWheelModeColorPanel; panel->flags.dragging = 1; wheelPositionSelection(panel, event->xbutton.x, event->xbutton.y); } break; case ButtonRelease: panel->flags.dragging = 0; if (!panel->flags.continuous) { if (panel->action) (*panel->action)(panel, panel->clientData); } break; case MotionNotify: if (panel->flags.dragging) { if (getPickerPart(panel, event->xmotion.x, event->xmotion.y) == COLORWHEEL_PART) { wheelPositionSelection(panel, event->xmotion.x, event->xmotion.y); } else wheelPositionSelectionOutBounds(panel, event->xmotion.x, event->xmotion.y); } break; } } static int getPickerPart(W_ColorPanel *panel, int x, int y) { int lx, ly; unsigned long ofs; lx = x; ly = y; if (panel->mode == WMWheelModeColorPanel) { if ((lx >= 2) && (lx <= 2+colorWheelSize) && (ly >= 2) && (ly <= 2+colorWheelSize)) { ofs = ly*panel->wheelMtrx->width+lx; if (wheelInsideColorWheel(panel, ofs)) return COLORWHEEL_PART; } } if (panel->mode == WMCustomPaletteModeColorPanel) { if ((lx >= 2) && (lx < customPaletteWidth-2) && (ly >= 2) && (ly < customPaletteHeight-2)) { return CUSTOMPALETTE_PART; } } return 0; } static void wheelBrightnessSliderCallback(WMWidget *w, void *data) { int value; W_ColorPanel *panel = (W_ColorPanel*)data; value = 255-WMGetSliderValue(panel->wheelBrightnessS); wheelCalculateValues(panel, value); if (panel->color.set == cpRGB) { convertCPColor(&panel->color); panel->color.set = cpHSV; } panel->color.hsv.value = value; wheelRender(panel); wheelPaint(panel); wheelUpdateSelection(panel); } static void wheelUpdateSelection(W_ColorPanel *panel) { W_Screen *scr = WMWidgetScreen(panel->win); updateSwatch(panel, panel->color); panel->lastChanged = WMWheelModeColorPanel; /* Redraw color selector (and make a backup of the part it will cover) */ XCopyArea(scr->display, panel->wheelImg, panel->selectionBackImg, scr->copyGC, panel->colx -2, panel->coly -2, 4, 4, 0, 0); /* "-2" is correction for hotspot location */ XCopyArea(scr->display, panel->selectionImg, panel->wheelView->window, scr->copyGC, 0, 0, 4, 4, panel->colx -2, panel->coly -2); /* see above */ } static void wheelUndrawSelection(W_ColorPanel *panel) { W_Screen *scr = WMWidgetScreen(panel->win); XCopyArea(scr->display, panel->selectionBackImg, panel->wheelView->window, scr->copyGC, 0, 0, 4, 4, panel->colx -2, panel->coly -2); /* see above */ } static void wheelPositionSelection(W_ColorPanel *panel, int x, int y) { unsigned long ofs = (y * panel->wheelMtrx->width)+ x; panel->color.rgb.red = panel->wheelMtrx->values[ panel->wheelMtrx->data[0][ofs] ]; panel->color.rgb.green = panel->wheelMtrx->values[ panel->wheelMtrx->data[1][ofs] ]; panel->color.rgb.blue = panel->wheelMtrx->values[ panel->wheelMtrx->data[2][ofs] ]; panel->color.set = cpRGB; wheelUndrawSelection(panel); panel->colx = x; panel->coly = y; wheelUpdateSelection(panel); wheelUpdateBrightnessGradientFromLocation(panel); } static void wheelPositionSelectionOutBounds(W_ColorPanel *panel, int x, int y) { int hue; int xcor, ycor; CPColor cpColor; xcor = x * 2 - colorWheelSize - 4; ycor = y * 2 - colorWheelSize - 4; panel->color.hsv.saturation = 255; panel->color.hsv.value = 255 - WMGetSliderValue(panel->wheelBrightnessS); if (xcor != 0) hue = rint(atan(- (double)ycor / (double)xcor) * (180.0/M_PI)); else { if (ycor < 0) hue = 90; else hue = 270; } if (xcor < 0) hue += 180; if ((xcor > 0) && (ycor > 0)) hue += 360; panel->color.hsv.hue = hue; panel->color.set = cpHSV; convertCPColor(&panel->color); wheelUndrawSelection(panel); panel->colx = 2 + rint((colorWheelSize * (1.0 + cos( panel->color.hsv.hue * (M_PI/180.0) ))) / 2.0); /* "+2" because of "colorWheelSize + 4" */ panel->coly = 2 + rint((colorWheelSize * (1.0 + sin(- panel->color.hsv.hue * (M_PI/180.0) ))) / 2.0); wheelUpdateSelection(panel); cpColor = panel->color; wheelUpdateBrightnessGradient(panel, cpColor); } static void wheelUpdateBrightnessGradientFromLocation(W_ColorPanel *panel) { CPColor from; unsigned long ofs; ofs = panel->coly * panel->wheelMtrx->width + panel->colx; from.rgb.red = panel->wheelMtrx->data[0][ofs]; from.rgb.green = panel->wheelMtrx->data[1][ofs]; from.rgb.blue = panel->wheelMtrx->data[2][ofs]; from.set = cpRGB; wheelUpdateBrightnessGradient(panel, from); } static void wheelUpdateBrightnessGradient(W_ColorPanel *panel, CPColor topColor) { RColor to; RImage *sliderImg; WMPixmap *sliderPxmp; to.red = to.green = to.blue = 0; if (topColor.set == cpHSV) convertCPColor(&topColor); sliderImg = RRenderGradient(16, 153, &(topColor.rgb), &to, RGRD_VERTICAL); sliderPxmp = WMCreatePixmapFromRImage(WMWidgetScreen(panel->win), sliderImg, 0); RReleaseImage(sliderImg); WMSetSliderImage(panel->wheelBrightnessS, sliderPxmp); WMReleasePixmap(sliderPxmp); } /****************** Grayscale Panel Functions ***************/ static void grayBrightnessSliderCallback(WMWidget *w, void *data) { CPColor cpColor; int value; char tmp[4]; W_ColorPanel *panel = (W_ColorPanel*)data; value = WMGetSliderValue(panel->grayBrightnessS); sprintf(tmp, "%d", value); WMSetTextFieldText(panel->grayBrightnessT, tmp); cpColor.rgb.red = cpColor.rgb.green = cpColor.rgb.blue = rint(2.55*value); cpColor.set = cpRGB; updateSwatch(panel, cpColor); panel->lastChanged = WMGrayModeColorPanel; } static void grayPresetButtonCallback(WMWidget *w, void *data) { CPColor cpColor; char tmp[4]; int value; int i=0; W_ColorPanel *panel = (W_ColorPanel*)data; while (i < 7) { if (w == panel->grayPresetBtn[i]) break; i++; } value = rint((100.0*i)/6.0); sprintf(tmp, "%d", value); WMSetTextFieldText(panel->grayBrightnessT, tmp); cpColor.rgb.red = cpColor.rgb.green = cpColor.rgb.blue = rint((255.0*i)/6.0); cpColor.set = cpRGB; WMSetSliderValue(panel->grayBrightnessS, rint((100.0*i)/6.0)); updateSwatch(panel, cpColor); panel->lastChanged = WMGrayModeColorPanel; } static void grayBrightnessTextFieldCallback(void *observerData, WMNotification *notification) { CPColor cpColor; char tmp[4]; int value; W_ColorPanel *panel = (W_ColorPanel*)observerData; value = atoi(WMGetTextFieldText(panel->grayBrightnessT)); if (value > 100) value = 100; if (value < 0) value = 0; sprintf(tmp, "%d", value); WMSetTextFieldText(panel->grayBrightnessT, tmp); WMSetSliderValue(panel->grayBrightnessS, value); cpColor.rgb.red = cpColor.rgb.green = cpColor.rgb.blue = rint((255.0*value)/100.0); cpColor.set = cpRGB; updateSwatch(panel, cpColor); panel->lastChanged = WMGrayModeColorPanel; } /******************* RGB Panel Functions *****************/ static void rgbSliderCallback(WMWidget *w, void *data) { CPColor cpColor; int value[3]; char tmp[4]; W_ColorPanel *panel = (W_ColorPanel*)data; value[0] = WMGetSliderValue(panel->rgbRedS); value[1] = WMGetSliderValue(panel->rgbGreenS); value[2] = WMGetSliderValue(panel->rgbBlueS); sprintf(tmp, "%d", value[0]); WMSetTextFieldText(panel->rgbRedT, tmp); sprintf(tmp, "%d", value[1]); WMSetTextFieldText(panel->rgbGreenT, tmp); sprintf(tmp, "%d", value[2]); WMSetTextFieldText(panel->rgbBlueT, tmp); cpColor.rgb.red = value[0]; cpColor.rgb.green = value[1]; cpColor.rgb.blue = value[2]; cpColor.set = cpRGB; updateSwatch(panel, cpColor); panel->lastChanged = WMRGBModeColorPanel; } static void rgbTextFieldCallback(void *observerData, WMNotification *notification) { CPColor cpColor; int value[3]; char tmp[4]; int n; W_ColorPanel *panel = (W_ColorPanel*)observerData; value[0] = atoi(WMGetTextFieldText(panel->rgbRedT)); value[1] = atoi(WMGetTextFieldText(panel->rgbGreenT)); value[2] = atoi(WMGetTextFieldText(panel->rgbBlueT)); for (n=0; n < 3; n++) { if (value[n] > 255) value[n] = 255; if (value[n] < 0) value[n] = 0; } sprintf(tmp, "%d", value[0]); WMSetTextFieldText(panel->rgbRedT, tmp); sprintf(tmp, "%d", value[1]); WMSetTextFieldText(panel->rgbGreenT, tmp); sprintf(tmp, "%d", value[2]); WMSetTextFieldText(panel->rgbBlueT, tmp); WMSetSliderValue(panel->rgbRedS, value[0]); WMSetSliderValue(panel->rgbGreenS, value[1]); WMSetSliderValue(panel->rgbBlueS, value[2]); cpColor.rgb.red = value[0]; cpColor.rgb.green = value[1]; cpColor.rgb.blue = value[2]; cpColor.set = cpRGB; updateSwatch(panel, cpColor); panel->lastChanged = WMRGBModeColorPanel; } /******************* CMYK Panel Functions *****************/ static void cmykSliderCallback(WMWidget *w, void *data) { CPColor cpColor; int value[4]; char tmp[4]; W_ColorPanel *panel = (W_ColorPanel*)data; double scale; value[0] = WMGetSliderValue(panel->cmykCyanS); value[1] = WMGetSliderValue(panel->cmykMagentaS); value[2] = WMGetSliderValue(panel->cmykYellowS); value[3] = WMGetSliderValue(panel->cmykBlackS); sprintf(tmp, "%d", value[0]); WMSetTextFieldText(panel->cmykCyanT, tmp); sprintf(tmp, "%d", value[1]); WMSetTextFieldText(panel->cmykMagentaT, tmp); sprintf(tmp, "%d", value[2]); WMSetTextFieldText(panel->cmykYellowT, tmp); sprintf(tmp, "%d", value[3]); WMSetTextFieldText(panel->cmykBlackT, tmp); scale = 2.55 * (1.0 - (value[3] / 100.0)); cpColor.rgb.red = rint((100.0 - value[0]) * scale); cpColor.rgb.green = rint((100.0 - value[1]) * scale); cpColor.rgb.blue = rint((100.0 - value[2]) * scale); cpColor.set = cpRGB; updateSwatch(panel, cpColor); panel->lastChanged = WMCMYKModeColorPanel; } static void cmykTextFieldCallback(void *observerData, WMNotification *notification) { CPColor cpColor; int value[4]; char tmp[4]; int n; double scale; W_ColorPanel *panel = (W_ColorPanel*)observerData; value[0] = atoi(WMGetTextFieldText(panel->cmykCyanT)); value[1] = atoi(WMGetTextFieldText(panel->cmykMagentaT)); value[2] = atoi(WMGetTextFieldText(panel->cmykYellowT)); value[3] = atoi(WMGetTextFieldText(panel->cmykBlackT)); for (n=0; n < 4; n++) { if (value[n] > 100) value[n] = 100; if (value[n] < 0) value[n] = 0; } sprintf(tmp, "%d", value[0]); WMSetTextFieldText(panel->cmykCyanT, tmp); sprintf(tmp, "%d", value[1]); WMSetTextFieldText(panel->cmykMagentaT, tmp); sprintf(tmp, "%d", value[2]); WMSetTextFieldText(panel->cmykYellowT, tmp); sprintf(tmp, "%d", value[3]); WMSetTextFieldText(panel->cmykBlackT, tmp); WMSetSliderValue(panel->cmykCyanS, value[0]); WMSetSliderValue(panel->cmykMagentaS, value[1]); WMSetSliderValue(panel->cmykYellowS, value[2]); WMSetSliderValue(panel->cmykBlackS, value[3]); scale = 2.55 * (1.0 - (value[3] / 100.0)); cpColor.rgb.red = rint((100.0 - value[0]) * scale); cpColor.rgb.green = rint((100.0 - value[1]) * scale); cpColor.rgb.blue = rint((100.0 - value[2]) * scale); cpColor.set = cpRGB; updateSwatch(panel, cpColor); panel->lastChanged = WMCMYKModeColorPanel; } /********************** HSB Panel Functions ***********************/ static void hsbSliderCallback(WMWidget *w, void *data) { CPColor cpColor; int value[3]; char tmp[4]; W_ColorPanel *panel = (W_ColorPanel*)data; value[0] = WMGetSliderValue(panel->hsbHueS); value[1] = WMGetSliderValue(panel->hsbSaturationS); value[2] = WMGetSliderValue(panel->hsbBrightnessS); sprintf(tmp, "%d", value[0]); WMSetTextFieldText(panel->hsbHueT, tmp); sprintf(tmp, "%d", value[1]); WMSetTextFieldText(panel->hsbSaturationT, tmp); sprintf(tmp, "%d", value[2]); WMSetTextFieldText(panel->hsbBrightnessT, tmp); cpColor.hsv.hue = value[0]; cpColor.hsv.saturation = value[1]*2.55; cpColor.hsv.value = value[2]*2.55; cpColor.set = cpHSV; convertCPColor(&cpColor); panel->lastChanged = WMHSBModeColorPanel; updateSwatch(panel, cpColor); if (w != panel->hsbBrightnessS) hsbUpdateBrightnessGradient(panel); if (w != panel->hsbSaturationS) hsbUpdateSaturationGradient(panel); if (w != panel->hsbHueS) hsbUpdateHueGradient(panel); } static void hsbTextFieldCallback(void *observerData, WMNotification *notification) { CPColor cpColor; int value[3]; char tmp[4]; int n; W_ColorPanel *panel = (W_ColorPanel*)observerData; value[0] = atoi(WMGetTextFieldText(panel->hsbHueT)); value[1] = atoi(WMGetTextFieldText(panel->hsbSaturationT)); value[2] = atoi(WMGetTextFieldText(panel->hsbBrightnessT)); if (value[0] > 359) value[0] = 359; if (value[0] < 0) value[0] = 0; for (n=1; n < 3; n++) { if (value[n] > 100) value[n] = 100; if (value[n] < 0) value[n] = 0; } sprintf(tmp, "%d", value[0]); WMSetTextFieldText(panel->hsbHueT, tmp); sprintf(tmp, "%d", value[1]); WMSetTextFieldText(panel->hsbSaturationT, tmp); sprintf(tmp, "%d", value[2]); WMSetTextFieldText(panel->hsbBrightnessT, tmp); WMSetSliderValue(panel->hsbHueS, value[0]); WMSetSliderValue(panel->hsbSaturationS, value[1]); WMSetSliderValue(panel->hsbBrightnessS, value[2]); cpColor.hsv.hue = value[0]; cpColor.hsv.saturation = value[1]*2.55; cpColor.hsv.value = value[2]*2.55; cpColor.set = cpHSV; convertCPColor(&cpColor); panel->lastChanged = WMHSBModeColorPanel; updateSwatch(panel, cpColor); hsbUpdateBrightnessGradient(panel); hsbUpdateSaturationGradient(panel); hsbUpdateHueGradient(panel); } static void hsbUpdateBrightnessGradient(W_ColorPanel *panel) { W_Screen *scr = WMWidgetScreen(panel->win); RColor from; CPColor to; RImage *sliderImg; WMPixmap *sliderPxmp; from.red = from.green = from.blue = 0; to.hsv = panel->color.hsv; to.hsv.value = 255; to.set = cpHSV; convertCPColor(&to); sliderImg = RRenderGradient(141, 16, &from, &(to.rgb), RGRD_HORIZONTAL); sliderPxmp = WMCreatePixmapFromRImage(scr, sliderImg, 0); RReleaseImage(sliderImg); if (sliderPxmp) W_PaintText(W_VIEW(panel->hsbBrightnessS), sliderPxmp->pixmap, panel->font12, 2, 0, 100, WALeft, scr->white, False, _("Brightness"), strlen(_("Brightness"))); else wwarning(_("Color Panel: Could not allocate memory")); WMSetSliderImage(panel->hsbBrightnessS, sliderPxmp); WMReleasePixmap(sliderPxmp); } static void hsbUpdateSaturationGradient(W_ColorPanel *panel) { W_Screen *scr = WMWidgetScreen(panel->win); CPColor from; CPColor to; RImage *sliderImg; WMPixmap *sliderPxmp; from.hsv = panel->color.hsv; from.hsv.saturation = 0; from.set = cpHSV; convertCPColor(&from); to.hsv = panel->color.hsv; to.hsv.saturation = 255; to.set = cpHSV; convertCPColor(&to); sliderImg = RRenderGradient(141, 16, &(from.rgb), &(to.rgb), RGRD_HORIZONTAL); sliderPxmp = WMCreatePixmapFromRImage(scr, sliderImg, 0); RReleaseImage(sliderImg); if (sliderPxmp) W_PaintText(W_VIEW(panel->hsbSaturationS), sliderPxmp->pixmap, panel->font12, 2, 0, 100, WALeft, from.hsv.value < 128 ? scr->white : scr->black, False, _("Saturation"), strlen(_("Saturation"))); else wwarning(_("Color Panel: Could not allocate memory")); WMSetSliderImage(panel->hsbSaturationS, sliderPxmp); WMReleasePixmap(sliderPxmp); } static void hsbUpdateHueGradient(W_ColorPanel *panel) { W_Screen *scr = WMWidgetScreen(panel->win); RColor **colors = NULL; RHSVColor hsvcolor; RImage *sliderImg; WMPixmap *sliderPxmp; int i; hsvcolor = panel->color.hsv; colors = wmalloc(sizeof(RColor*)*(8)); for (i=0; i<7; i++) { hsvcolor.hue = (360*i)/6; colors[i] = wmalloc(sizeof(RColor)); RHSVtoRGB(&hsvcolor, colors[i]); } colors[7] = NULL; sliderImg = RRenderMultiGradient(141, 16, colors, RGRD_HORIZONTAL); sliderPxmp = WMCreatePixmapFromRImage(scr, sliderImg, 0); RReleaseImage(sliderImg); if (sliderPxmp) W_PaintText(W_VIEW(panel->hsbHueS), sliderPxmp->pixmap, panel->font12, 2, 0, 100, WALeft, hsvcolor.value < 128 ? scr->white : scr->black, False, _("Hue"), strlen(_("Hue"))); else wwarning(_("Color Panel: Could not allocate memory")); WMSetSliderImage(panel->hsbHueS, sliderPxmp); WMReleasePixmap(sliderPxmp); for (i=0; i<7; i++) wfree(colors[i]); wfree(colors); } /*************** Custom Palette Functions ****************/ static void customRenderSpectrum(W_ColorPanel *panel) { RImage *spectrum; int x,y; unsigned char *ptr; CPColor cpColor; spectrum = RCreateImage(SPECTRUM_WIDTH, SPECTRUM_HEIGHT, False); ptr = spectrum->data; for (y = 0; y < SPECTRUM_HEIGHT; y++) { cpColor.hsv.hue = y; cpColor.hsv.saturation = 0; cpColor.hsv.value = 255; cpColor.set = cpHSV; for (x = 0; x < SPECTRUM_WIDTH; x++) { convertCPColor(&cpColor); *(ptr++) = (unsigned char)cpColor.rgb.red; *(ptr++) = (unsigned char)cpColor.rgb.green; *(ptr++) = (unsigned char)cpColor.rgb.blue; if (x < (SPECTRUM_WIDTH/2)) cpColor.hsv.saturation++; if (x > (SPECTRUM_WIDTH/2)) cpColor.hsv.value--; } } if (panel->customPaletteImg) { RReleaseImage(panel->customPaletteImg); panel->customPaletteImg = NULL; } panel->customPaletteImg = spectrum; } static void customSetPalette(W_ColorPanel *panel) { W_Screen *scr = WMWidgetScreen(panel->win); RImage *scaledImg; Pixmap image; int item; image = XCreatePixmap(scr->display, W_DRAWABLE(scr), customPaletteWidth, customPaletteHeight, scr->depth); scaledImg = RScaleImage(panel->customPaletteImg, customPaletteWidth, customPaletteHeight); RConvertImage(scr->rcontext, scaledImg, &image); RReleaseImage(scaledImg); XCopyArea(scr->display, image, panel->customPaletteContentView->window, scr->copyGC, 0, 0, customPaletteWidth, customPaletteHeight, 0, 0); /* Check backimage exists. If it doesn't, allocate and fill it */ if (!panel->selectionBackImg) { panel->selectionBackImg = XCreatePixmap(scr->display, panel->customPaletteContentView->window, 4, 4, scr->depth); } XCopyArea(scr->display, image, panel->selectionBackImg, scr->copyGC, panel->palx-2, panel->paly-2, 4, 4, 0, 0); XCopyArea(scr->display, panel->selectionImg, panel->customPaletteContentView->window, scr->copyGC, 0 , 0, 4, 4, panel->palx-2, panel->paly-2); XFreePixmap(scr->display, image); panel->palXRatio = (double)(panel->customPaletteImg->width) / (double)(customPaletteWidth); panel->palYRatio = (double)(panel->customPaletteImg->height) / (double)(customPaletteHeight); item = WMGetPopUpButtonSelectedItem (panel->customPaletteHistoryBtn); } static void customPalettePositionSelection(W_ColorPanel *panel, int x, int y) { W_Screen *scr = WMWidgetScreen(panel->win); unsigned long ofs; /* undraw selection */ XCopyArea(scr->display, panel->selectionBackImg, panel->customPaletteContentView->window, scr->copyGC, 0, 0, 4, 4, panel->palx-2, panel->paly-2); panel->palx = x; panel->paly = y; ofs = (rint(x * panel->palXRatio) + rint(y * panel->palYRatio) * panel->customPaletteImg->width) * 3; panel->color.rgb.red = panel->customPaletteImg->data[ofs]; panel->color.rgb.green = panel->customPaletteImg->data[ofs+1]; panel->color.rgb.blue = panel->customPaletteImg->data[ofs+2]; panel->color.set = cpRGB; updateSwatch(panel, panel->color); panel->lastChanged = WMCustomPaletteModeColorPanel; /* Redraw color selector (and make a backup of the part it will cover) */ 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 */ XCopyArea(scr->display, panel->selectionImg, panel->customPaletteContentView->window, scr->copyGC, 0, 0, 4, 4, panel->palx-2, panel->paly-2); /* see above */ } static void customPalettePositionSelectionOutBounds(W_ColorPanel *panel, int x, int y) { if (x < 2) x = 2; if (y < 2) y = 2; if (x >= customPaletteWidth) x = customPaletteWidth -2; if (y >= customPaletteHeight) y = customPaletteHeight -2; customPalettePositionSelection(panel, x, y); } static void customPaletteHandleEvents(XEvent *event, void *data) { W_ColorPanel *panel = (W_ColorPanel*)data; switch (event->type) { case Expose: if (event->xexpose.count != 0) /* TODO Improve. */ break; customSetPalette(panel); break; } } static void customPaletteHandleActionEvents(XEvent *event, void *data) { W_ColorPanel *panel = (W_ColorPanel*)data; int x, y; switch (event->type) { case ButtonPress: x = event->xbutton.x; y = event->xbutton.y; if (getPickerPart(panel, x, y) == CUSTOMPALETTE_PART) { panel->flags.dragging = 1; customPalettePositionSelection(panel, x, y); } break; case ButtonRelease: panel->flags.dragging = 0; if (!panel->flags.continuous) { if (panel->action) (*panel->action)(panel, panel->clientData); } break; case MotionNotify: x = event->xmotion.x; y = event->xmotion.y; if (panel->flags.dragging) { if (getPickerPart(panel, x, y) == CUSTOMPALETTE_PART) { customPalettePositionSelection(panel, x, y); } else customPalettePositionSelectionOutBounds(panel, x, y); } break; } } static void customPaletteMenuCallback(WMWidget *w, void *data) { W_ColorPanel *panel = (W_ColorPanel*)data; int item = WMGetPopUpButtonSelectedItem(panel->customPaletteMenuBtn); switch (item) { case CPmenuNewFromFile: customPaletteMenuNewFromFile(panel); break; case CPmenuRename: customPaletteMenuRename(panel); break; case CPmenuRemove: customPaletteMenuRemove(panel); break; case CPmenuCopy: break; case CPmenuNewFromClipboard: break; } } static void customPaletteMenuNewFromFile(W_ColorPanel *panel) { W_Screen *scr = WMWidgetScreen(panel->win); WMOpenPanel *browseP; char *filepath; char *filename = NULL; char *spath; char *tmp; int i; RImage *tmpImg = NULL; if ((!panel->lastBrowseDir) || (strcmp(panel->lastBrowseDir,"\0") == 0)) spath = wexpandpath(wgethomedir()); else spath = wexpandpath(panel->lastBrowseDir); browseP = WMGetOpenPanel(scr); WMSetFilePanelCanChooseDirectories(browseP, 0); WMSetFilePanelCanChooseFiles(browseP, 1); /* Get a filename */ if (WMRunModalFilePanelForDirectory(browseP, panel->win, spath, _("Open Palette"), RSupportedFileFormats()) ) { filepath = WMGetFilePanelFileName(browseP); /* Get seperation position between path and filename */ i = strrchr(filepath, '/') - filepath + 1; if (i > strlen(filepath)) i = strlen(filepath); /* Store last browsed path */ if (panel->lastBrowseDir) wfree(panel->lastBrowseDir); panel->lastBrowseDir = wmalloc((i+1)*sizeof(char)); strncpy(panel->lastBrowseDir, filepath, i); panel->lastBrowseDir[i] = '\0'; /* Get filename from path */ filename = wstrdup(filepath + i); /* Check for duplicate files, and rename it if there are any */ tmp = wstrconcat(panel->configurationPath, filename); while (access (tmp, F_OK) == 0) { char *newName; wfree(tmp); newName = generateNewFilename(filename); wfree(filename); filename = newName; tmp = wstrconcat(panel->configurationPath, filename); } wfree(tmp); /* Copy image to $(gnustepdir)/Library/Colors/ & * Add filename to history menu */ if (fetchFile (panel->configurationPath, filepath, filename) == 0) { /* filepath is a "local" path now the file has been copied */ wfree(filepath); filepath = wstrconcat(panel->configurationPath, filename); /* load the image & add menu entries */ tmpImg = RLoadImage(scr->rcontext, filepath, 0); if (tmpImg) { if (panel->customPaletteImg) RReleaseImage(panel->customPaletteImg); panel->customPaletteImg = tmpImg; customSetPalette(panel); WMAddPopUpButtonItem(panel->customPaletteHistoryBtn, filename); panel->currentPalette = WMGetPopUpButtonNumberOfItems( panel->customPaletteHistoryBtn)-1; WMSetPopUpButtonSelectedItem(panel->customPaletteHistoryBtn, panel->currentPalette); } } else { tmp = wstrconcat(panel->configurationPath, filename); i = remove(tmp); /* Delete the file, it doesn't belong here */ WMRunAlertPanel(scr, panel->win, _("File Error"), _("Invalid file format !"), _("OK"), NULL, NULL); if (i != 0) { wsyserror(_("can't remove file %s"), tmp); WMRunAlertPanel(scr, panel->win, _("File Error"), _("Couldn't remove file from Configuration Directory !"), _("OK"), NULL, NULL); } wfree(tmp); } wfree(filepath); wfree(filename); } WMFreeFilePanel(browseP); wfree(spath); } static void customPaletteMenuRename(W_ColorPanel *panel) { W_Screen *scr = WMWidgetScreen(panel->win); char *toName = NULL; char *fromName; char *toPath, *fromPath; int item; int index; item = WMGetPopUpButtonSelectedItem(panel->customPaletteHistoryBtn); fromName = WMGetPopUpButtonItem(panel->customPaletteHistoryBtn, item); toName = WMRunInputPanel(scr, panel->win, _("Rename"), _("Rename palette to:"), fromName, _("OK"), _("Cancel")); if (toName) { /* As some people do certain stupid things... */ if (strcmp(toName, fromName) == 0) { wfree(toName); return; } /* For normal people */ fromPath = wstrconcat(panel->configurationPath, fromName); toPath = wstrconcat(panel->configurationPath, toName); if (access (toPath, F_OK) == 0) { /* Careful, this palette exists already */ if (WMRunAlertPanel(scr, panel->win, _("Warning"), _("Palette already exists !\n\nOverwrite ?"), _("No"), _("Yes"), NULL) == 1) { /* "No" = 0, "Yes" = 1 */ int items = WMGetPopUpButtonNumberOfItems( panel->customPaletteHistoryBtn); remove(toPath); /* Remove from History list too */ index = 1; while ((index < items) && (strcmp(WMGetPopUpButtonItem( panel->customPaletteHistoryBtn, index), toName) != 0 )) index++; if (index < items) { WMRemovePopUpButtonItem(panel->customPaletteHistoryBtn, index); if (index < item) item--; } } else { wfree(fromPath); wfree(toName); wfree(toPath); return; } } if ( rename(fromPath, toPath) != 0) wsyserror(_("Couldn't rename palette %s to %s\n"), fromName, toName); else { WMRemovePopUpButtonItem(panel->customPaletteHistoryBtn, item); WMInsertPopUpButtonItem(panel->customPaletteHistoryBtn, item, toName); WMSetPopUpButtonSelectedItem(panel->customPaletteHistoryBtn, item); } wfree(fromPath); wfree(toPath); wfree(toName); } } static void customPaletteMenuRemove(W_ColorPanel *panel) { W_Screen *scr = WMWidgetScreen(panel->win); char *text; char *tmp; int choice; int item; item = WMGetPopUpButtonSelectedItem(panel->customPaletteHistoryBtn); tmp = wstrconcat( _("This will permanently remove the palette "), WMGetPopUpButtonItem(panel->customPaletteHistoryBtn, item )); text = wstrconcat( tmp, _(".\n\nAre you sure you want to remove this palette ?")); wfree(tmp); choice = WMRunAlertPanel(scr, panel->win, _("Remove"), text, _("Yes"), _("No"), NULL); /* returns 0 (= "Yes") or 1 (="No") */ wfree(text); if (choice == 0) { tmp = wstrconcat(panel->configurationPath, WMGetPopUpButtonItem(panel->customPaletteHistoryBtn, item )); if ( remove(tmp) == 0) { /* item-1 always exists */ WMSetPopUpButtonSelectedItem(panel->customPaletteHistoryBtn, item-1); customPaletteHistoryCallback(panel->customPaletteHistoryBtn, panel); customSetPalette(panel); WMRemovePopUpButtonItem(panel->customPaletteHistoryBtn, item); } else { wsyserror(_("Couldn't remove palette %s\n"), tmp); } wfree(tmp); } } static void customPaletteHistoryCallback(WMWidget *w, void *data) { W_ColorPanel *panel = (W_ColorPanel*)data; W_Screen *scr = WMWidgetScreen(panel->win); int item; char *filename; RImage *tmp = NULL; unsigned char perm_mask; item = WMGetPopUpButtonSelectedItem(panel->customPaletteHistoryBtn); if (item == panel->currentPalette) return; if (item == 0) { customRenderSpectrum(panel); WMSetPopUpButtonItemEnabled(panel->customPaletteMenuBtn, CPmenuRename, False ); WMSetPopUpButtonItemEnabled(panel->customPaletteMenuBtn, CPmenuRemove, False ); } else { /* Load file from configpath */ filename = wstrconcat( panel->configurationPath, WMGetPopUpButtonItem(panel->customPaletteHistoryBtn, item) ); /* If the file corresponding to the item does not exist, * remove it from the history list and select the next one. */ perm_mask = (access(filename, F_OK) == 0); if (!perm_mask) { /* File does not exist */ wfree(filename); WMSetPopUpButtonSelectedItem(panel->customPaletteHistoryBtn, item-1); WMRemovePopUpButtonItem(panel->customPaletteHistoryBtn, item); customPaletteHistoryCallback(w, data); return; } /* Get the image */ tmp = RLoadImage(scr->rcontext, filename, 0); if (tmp) { if (panel->customPaletteImg) { RReleaseImage(panel->customPaletteImg); panel->customPaletteImg = NULL; } panel->customPaletteImg = tmp; } /* If the image is not writable, don't allow removing/renaming */ perm_mask = (access(filename, W_OK) == 0); WMSetPopUpButtonItemEnabled(panel->customPaletteMenuBtn, CPmenuRename, perm_mask); WMSetPopUpButtonItemEnabled(panel->customPaletteMenuBtn, CPmenuRemove, perm_mask); wfree(filename); } customSetPalette(panel); panel->currentPalette = item; } /************************* ColorList Panel Functions **********************/ static void colorListPaintItem(WMList *lPtr, int index, Drawable d, char *text, int state, WMRect *rect) { WMScreen *scr = WMWidgetScreen(lPtr); Display *dpy = WMScreenDisplay(scr); WMView *view = W_VIEW(lPtr); RColor color = *((RColor *)WMGetListItem(lPtr, index)->clientData); W_ColorPanel *panel = WMGetHangedData(lPtr); int width, height, x, y; WMColor *fillColor; width = rect->size.width; height = rect->size.height; x = rect->pos.x; y = rect->pos.y; if (state & WLDSSelected) XFillRectangle(dpy, d, WMColorGC(scr->white), x, y, width, height); else XFillRectangle(dpy, d, WMColorGC(view->backColor), x, y, width, height); fillColor = WMCreateRGBColor(scr, color.red<<8, color.green<<8, color.blue<<8, True); XFillRectangle(dpy, d, WMColorGC(fillColor), x, y, 15, height); WMReleaseColor(fillColor); WMDrawString(scr, d, scr->black, panel->font12, x+18, y, text, strlen(text)); } static void colorListSelect(WMWidget *w, void *data) { W_ColorPanel *panel = (W_ColorPanel *)data; CPColor cpColor; cpColor.rgb = *((RColor *)WMGetListSelectedItem(w)->clientData); cpColor.set = cpRGB; panel->lastChanged = WMColorListModeColorPanel; updateSwatch(panel, cpColor); } static void colorListColorMenuCallback(WMWidget *w, void *data) { W_ColorPanel *panel = (W_ColorPanel *)data; int item = WMGetPopUpButtonSelectedItem(panel->colorListColorMenuBtn); switch (item) { case CLmenuAdd: break; case CLmenuRename: break; case CLmenuRemove: break; } } static void colorListListMenuCallback(WMWidget *w, void *data) { W_ColorPanel *panel = (W_ColorPanel *)data; int item = WMGetPopUpButtonSelectedItem(panel->colorListListMenuBtn); switch (item) { case CLmenuAdd: /* New Color List */ colorListListMenuNew(panel); break; case CLmenuRename: break; case CLmenuRemove: break; } } static void colorListListMenuNew(W_ColorPanel *panel) { } /*************** Panel Initialisation Functions *****************/ static void wheelInit(W_ColorPanel *panel) { CPColor cpColor; if (panel->color.set != cpHSV) convertCPColor(&panel->color); WMSetSliderValue(panel->wheelBrightnessS, 255 - panel->color.hsv.value); panel->colx = 2 + rint((colorWheelSize / 2.0) * (1 + ( panel->color.hsv.saturation/255.0) * cos( panel->color.hsv.hue * M_PI/180.0))); panel->coly = 2 + rint((colorWheelSize / 2.0) * (1 + ( panel->color.hsv.saturation/255.0) * sin(- panel->color.hsv.hue*M_PI/180.0))); wheelCalculateValues(panel, panel->color.hsv.value); cpColor = panel->color; cpColor.hsv.value = 255; cpColor.set = cpHSV; wheelUpdateBrightnessGradient(panel, cpColor); } static void grayInit(W_ColorPanel *panel) { int value; char tmp[4]; if (panel->color.set != cpHSV) convertCPColor(&panel->color); value = rint(panel->color.hsv.value/2.55); WMSetSliderValue(panel->grayBrightnessS, value); sprintf(tmp, "%d", value); WMSetTextFieldText(panel->grayBrightnessT, tmp); } static void rgbInit(W_ColorPanel *panel) { char tmp[4]; if (panel->color.set != cpRGB) convertCPColor(&panel->color); WMSetSliderValue(panel->rgbRedS, panel->color.rgb.red); WMSetSliderValue(panel->rgbGreenS, panel->color.rgb.green); WMSetSliderValue(panel->rgbBlueS, panel->color.rgb.blue); sprintf(tmp, "%d", panel->color.rgb.red); WMSetTextFieldText(panel->rgbRedT, tmp); sprintf(tmp, "%d", panel->color.rgb.green); WMSetTextFieldText(panel->rgbGreenT, tmp); sprintf(tmp, "%d", panel->color.rgb.blue); WMSetTextFieldText(panel->rgbBlueT, tmp); } static void cmykInit(W_ColorPanel *panel) { int value[3]; char tmp[4]; if (panel->color.set != cpRGB) convertCPColor(&panel->color); value[0] = rint((255-panel->color.rgb.red)/2.55); value[1] = rint((255-panel->color.rgb.green)/2.55); value[2] = rint((255-panel->color.rgb.blue)/2.55); WMSetSliderValue(panel->cmykCyanS, value[0]); WMSetSliderValue(panel->cmykMagentaS, value[1]); WMSetSliderValue(panel->cmykYellowS, value[2]); WMSetSliderValue(panel->cmykBlackS, 0); sprintf(tmp, "%d", value[0]); WMSetTextFieldText(panel->cmykCyanT, tmp); sprintf(tmp, "%d", value[1]); WMSetTextFieldText(panel->cmykMagentaT, tmp); sprintf(tmp, "%d", value[2]); WMSetTextFieldText(panel->cmykYellowT, tmp); WMSetTextFieldText(panel->cmykBlackT, "0"); } static void hsbInit(W_ColorPanel *panel) { int value[3]; char tmp[4]; if (panel->color.set != cpHSV) convertCPColor(&panel->color); value[0] = panel->color.hsv.hue; value[1] = rint(panel->color.hsv.saturation/2.55); value[2] = rint(panel->color.hsv.value/2.55); WMSetSliderValue(panel->hsbHueS,value[0]); WMSetSliderValue(panel->hsbSaturationS,value[1]); WMSetSliderValue(panel->hsbBrightnessS,value[2]); sprintf(tmp, "%d", value[0]); WMSetTextFieldText(panel->hsbHueT, tmp); sprintf(tmp, "%d", value[1]); WMSetTextFieldText(panel->hsbSaturationT, tmp); sprintf(tmp, "%d", value[2]); WMSetTextFieldText(panel->hsbBrightnessT, tmp); hsbUpdateBrightnessGradient(panel); hsbUpdateSaturationGradient(panel); hsbUpdateHueGradient(panel); } /************************** Common utility functions ************************/ static int fetchFile(char *toPath, char *srcFile, char *destFile) { int src, dest; int n; char *tmp; char buf[BUFSIZE]; if ((src = open(srcFile, O_RDONLY|O_BINARY)) == 0) { wsyserror(_("Could not open %s"), srcFile); return -1; } tmp = wstrconcat(toPath, destFile); if ((dest = open( tmp, O_RDWR|O_CREAT|O_BINARY, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) == 0) { wsyserror(_("Could not create %s"), tmp); wfree(tmp); return -1; } wfree(tmp); /* Copy the file */ while ((n = read(src, buf, BUFSIZE)) > 0) { if (write (dest, buf, n) != n) { wsyserror(_("Write error on file %s"), destFile); return -1; } } return 0; } char* generateNewFilename(char *curName) { int n; char c; int baseLen; char *ptr; char *newName; assert(curName); ptr = curName; if (((ptr = strrchr(ptr, '{'))==0) || sscanf(ptr, "{%i}%c", &n, &c)!=1) return wstrconcat(curName, " {1}"); baseLen = ptr - curName -1; newName = wmalloc(baseLen + 16); strncpy(newName, curName, baseLen); newName[baseLen] = 0; sprintf(&newName[baseLen], " {%i}", n+1); return newName; } void convertCPColor(CPColor *color) { unsigned short old_hue = 0; switch (color->set) { case cpNone: wwarning(_("Color Panel: Color unspecified")); return; case cpRGB: old_hue = color->hsv.hue; RRGBtoHSV(&(color->rgb), &(color->hsv)); /* In black the hue is undefined, and may change by conversion * Same for white. */ if ( ((color->rgb.red == 0) && (color->rgb.green == 0) && (color->rgb.blue == 0)) || ((color->rgb.red == 0) && (color->rgb.green == 0) && (color->rgb.blue == 255)) ) color->hsv.hue = old_hue; break; case cpHSV: RHSVtoRGB(&(color->hsv), &(color->rgb)); break; } } #define ABS_SHIFT(val, shift) \ (((shift) > 0) ? (val) >> (shift) : (val) << -(shift)) RColor ulongToRColor(WMScreen *scr, unsigned long value) { RColor color; XColor *xcolor = NULL; if (!(xcolor = wmalloc(sizeof(XColor)) )) { wwarning(_("Color Panel: Could not allocate memory")); color.red = 0; color.green = 0; color.blue = 0; return color; } xcolor->pixel = value; XQueryColor(scr->display, scr->rcontext->cmap, xcolor); color.red = xcolor->red >> 8; color.green = xcolor->green >> 8; color.blue = xcolor->blue >> 8; wfree(xcolor); return color; } unsigned char getShift(unsigned char value) { unsigned char i = -1; if (value == 0) return 0; while (value) { value >>= 1; i++; } return i; } #ifdef SHAPE_WAS_DEFINED #undef SHAPE_WAS_DEFINED #define SHAPE #endif