1
0
mirror of https://github.com/gryf/wmaker.git synced 2025-12-19 04:20:27 +01:00

Fixes from Alban and Pascal.

This commit is contained in:
id
1999-12-29 11:59:30 +00:00
parent 8eb0c79c54
commit 95e71d500a
4 changed files with 596 additions and 446 deletions

View File

@@ -50,7 +50,7 @@ wmquery_LDADD = libWINGs.a $(LIBLIST)
connect_SOURCES = connect.c
connect_LDADD = libWUtil.a @NETLIBS@ @LIBPL@
connect_LDADD = libWUtil.a @LIBRARY_SEARCH_PATH@ @NETLIBS@ @LIBPL@
EXTRA_DIST = logo.xpm BUGS

View File

@@ -26,6 +26,10 @@ int main(int argc, char **argv)
WMPixmap *pixmap;
WMColorPanel *panel;
#if 0
XSynchronize(dpy, True);
fprintf(stderr, "...Running Synchronous...\n");
#endif
WMInitializeApplication("WMColorPicker", &argc, argv);
@@ -38,9 +42,6 @@ int main(int argc, char **argv)
scr = WMCreateSimpleApplicationScreen(dpy);
pixmap = WMCreatePixmapFromXPMData(scr, GNUSTEP_XPM);
WMSetApplicationIconImage(scr, pixmap); WMReleasePixmap(pixmap);
panel = WMGetColorPanel(scr);

View File

@@ -1,10 +1,12 @@
#include "../src/config.h"
#include "WINGsP.h"
#ifdef SHAPE
#include <X11/extensions/shape.h>
#endif
typedef struct W_Balloon {
@@ -434,8 +436,10 @@ showText(Balloon *bPtr, int x, int y, int h, int w, char *text)
XFreePixmap(dpy, pixmap);
#ifdef SHAPE
XShapeCombineMask(dpy, bPtr->view->window, ShapeBounding, 0, 0, mask,
ShapeSet);
#endif
XFreePixmap(dpy, mask);
W_MoveView(bPtr->view, bx, by);

View File

@@ -12,25 +12,19 @@
* problems and similair code-issues
* Marco van Hylckama-Vlieg : For once again doing the artwork ;-)
*
* small note: Tabstop size = 4
*
*/
/* BUGS:
* For some reason after using the magnifying glass, the windowlist
* of the color-panel (panel->view->screen) becomes 0x0. This
* results in a core-dump of testcolorpanel, and in 3 times
* "WPrefs in wfree(): warning: chunk is already free." with WPrefs.
*/
/* 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 120 degrees.
* - Custom color-lists and custom colors in custom colo-lists.
* - Stored colors
* - Resizing
*/
#include "../src/config.h"
#include "WINGsP.h"
#include <math.h>
#include <unistd.h>
@@ -41,6 +35,19 @@
#include <dirent.h>
#include <errno.h>
/* BUG There's something fishy with shaped windows */
#if 1
#ifdef SHAPE
#define SHAPE_WAS_DEFINED
#undef SHAPE
#endif
#endif
#ifdef SHAPE
#include <X11/extensions/shape.h>
#endif
#ifndef PATH_MAX
# define PATH_MAX 1024
@@ -85,21 +92,22 @@ static unsigned char Cursor_shape_bits[] = {
0x00,0x00,0x00,0xf8,0x00,0x00,0x00,0x70};
/* Clip-mask for magnified pixels */
#define Cursor_mask_width 22
#define Cursor_mask_height 22
#define Cursor_mask_width 24
#define Cursor_mask_height 24
static unsigned char Cursor_mask_bits[] = {
0x00,0x3f,0x00,0xe0,0xff,0x01,0xf0,0xff,0x03,0xf8,0xff,0x07,0xfc,0xff,0x0f,
0xfe,0xff,0x1f,0xfe,0xff,0x1f,0xfe,0xff,0x1f,0xff,0xff,0x3f,0xff,0xff,0x3f,
0xff,0xff,0x3f,0xff,0xff,0x3f,0xff,0xff,0x3f,0xff,0xff,0x3f,0xfe,0xff,0x1f,
0xfe,0xff,0x1f,0xfe,0xff,0x1f,0xfc,0xff,0x0f,0xf8,0xff,0x07,0xf0,0xff,0x03,
0xe0,0xff,0x01,0x00,0x3f,0x00};
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 */
Pixmap pixmap; /* What's under the view */
Pixmap mask; /* Pixmap mask for view-contents */
int valid; /* Are contents still valid ? */
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 */
} MovingView;
@@ -113,7 +121,6 @@ typedef struct W_ColorPanel {
WMWindow *win;
WMFont *font8;
WMFont *font12;
void *clientData;
WMAction2 *action;
@@ -221,7 +228,6 @@ typedef struct W_ColorPanel {
struct {
unsigned int continuous:1;
unsigned int dragging:1;
} flags;
} W_ColorPanel;
@@ -263,9 +269,9 @@ enum {
#define MAX_LENGTH 1024
static int fetchFile(char* toPath, char *imageSrcFile,
char *imageDestFileName);
static int fetchFile(char* toPath, char *imageSrcFile, char *imageDestFileName);
char *generateNewFilename(char *curName);
RColor ulongToRColor(WMScreen *scr, XImage *image, unsigned long value);
static void modeButtonCallback(WMWidget *w, void *data);
static int getPickerPart(W_ColorPanel *panel, int x, int y);
@@ -278,9 +284,10 @@ 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 Pixmap magnifyGetStorePixmap(W_ColorPanel *panel, int x1, int y1,
static void magnifyGetImageStored(W_ColorPanel *panel, int x1, int y1,
int x2, int y2);
static Pixmap magnifyGetImage(WMScreen *scr, int x, int y);
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);
@@ -636,9 +643,8 @@ makeColorPanel(WMScreen *scrPtr, char *name)
image = RRenderGradient(141, 16, &from, &to, RGRD_HORIZONTAL);
pixmap = WMCreatePixmapFromRImage(scrPtr, image, 0);
W_PaintText(W_VIEW(panel->rgbRedS), pixmap->pixmap, panel->font12,
2, 0, 100, WALeft, WMColorGC(scrPtr->white), False, "Red",
strlen("Red"));
W_PaintText(W_VIEW(panel->rgbRedS), pixmap->pixmap, panel->font12, 2, 0,
100, WALeft, WMColorGC(scrPtr->white), False, "Red", strlen("Red"));
RDestroyImage(image);
WMSetSliderImage(panel->rgbRedS, pixmap);
WMReleasePixmap(pixmap);
@@ -650,7 +656,6 @@ makeColorPanel(WMScreen *scrPtr, char *name)
WMAddNotificationObserver(rgbTextFieldCallback, panel,
WMTextDidEndEditingNotification, panel->rgbRedT);
panel->rgbGreenS = WMCreateSlider(panel->rgbFrm);
WMResizeWidget(panel->rgbGreenS, 141, 16);
WMMoveWidget(panel->rgbGreenS, 2, 36);
@@ -665,8 +670,8 @@ makeColorPanel(WMScreen *scrPtr, char *name)
image = RRenderGradient(141, 16, &from, &to, RGRD_HORIZONTAL);
pixmap = WMCreatePixmapFromRImage(scrPtr, image, 0);
W_PaintText(W_VIEW(panel->rgbGreenS), pixmap->pixmap, panel->font12,
2, 0, 100, WALeft, WMColorGC(scrPtr->white), False, "Green",
W_PaintText(W_VIEW(panel->rgbGreenS), pixmap->pixmap, panel->font12, 2, 0,
100, WALeft, WMColorGC(scrPtr->white), False, "Green",
strlen("Green"));
RDestroyImage(image);
WMSetSliderImage(panel->rgbGreenS, pixmap);
@@ -694,8 +699,8 @@ makeColorPanel(WMScreen *scrPtr, char *name)
image = RRenderGradient(141, 16, &from, &to, RGRD_HORIZONTAL);
pixmap = WMCreatePixmapFromRImage(scrPtr, image, 0);
W_PaintText(W_VIEW(panel->rgbBlueS), pixmap->pixmap, panel->font12,
2, 0, 100, WALeft, WMColorGC(scrPtr->white), False, "Blue",
W_PaintText(W_VIEW(panel->rgbBlueS), pixmap->pixmap, panel->font12, 2, 0,
100, WALeft, WMColorGC(scrPtr->white), False, "Blue",
strlen("Blue"));
RDestroyImage(image);
WMSetSliderImage(panel->rgbBlueS, pixmap);
@@ -749,8 +754,8 @@ makeColorPanel(WMScreen *scrPtr, char *name)
image = RRenderGradient(141, 16, &from, &to, RGRD_HORIZONTAL);
pixmap = WMCreatePixmapFromRImage(scrPtr, image, 0);
W_PaintText(W_VIEW(panel->cmykCyanS), pixmap->pixmap, panel->font12,
2, 0, 100, WALeft, WMColorGC(scrPtr->black), False, "Cyan",
W_PaintText(W_VIEW(panel->cmykCyanS), pixmap->pixmap, panel->font12, 2, 0,
100, WALeft, WMColorGC(scrPtr->black), False, "Cyan",
strlen("Cyan"));
RDestroyImage(image);
WMSetSliderImage(panel->cmykCyanS, pixmap);
@@ -778,8 +783,8 @@ makeColorPanel(WMScreen *scrPtr, char *name)
image = RRenderGradient(141, 16, &from, &to, RGRD_HORIZONTAL);
pixmap = WMCreatePixmapFromRImage(scrPtr, image, 0);
W_PaintText(W_VIEW(panel->cmykMagentaS), pixmap->pixmap, panel->font12,
2, 0, 100, WALeft, WMColorGC(scrPtr->black), False, "Magenta",
W_PaintText(W_VIEW(panel->cmykMagentaS), pixmap->pixmap, panel->font12, 2,
0, 100, WALeft, WMColorGC(scrPtr->black), False, "Magenta",
strlen("Magenta"));
RDestroyImage(image);
WMSetSliderImage(panel->cmykMagentaS, pixmap);
@@ -807,8 +812,8 @@ makeColorPanel(WMScreen *scrPtr, char *name)
image = RRenderGradient(141, 16, &from, &to, RGRD_HORIZONTAL);
pixmap = WMCreatePixmapFromRImage(scrPtr, image, 0);
W_PaintText(W_VIEW(panel->cmykYellowS), pixmap->pixmap, panel->font12,
2, 0, 100, WALeft, WMColorGC(scrPtr->black), False, "Yellow",
W_PaintText(W_VIEW(panel->cmykYellowS), pixmap->pixmap, panel->font12, 2, 0,
100, WALeft, WMColorGC(scrPtr->black), False, "Yellow",
strlen("Yellow"));
RDestroyImage(image);
WMSetSliderImage(panel->cmykYellowS, pixmap);
@@ -837,8 +842,8 @@ makeColorPanel(WMScreen *scrPtr, char *name)
image = RRenderGradient(141, 16, &from, &to, RGRD_HORIZONTAL);
pixmap = WMCreatePixmapFromRImage(scrPtr, image, 0);
W_PaintText(W_VIEW(panel->cmykBlackS), pixmap->pixmap, panel->font12,
2, 0, 100, WALeft, WMColorGC(scrPtr->black), False, "Black",
W_PaintText(W_VIEW(panel->cmykBlackS), pixmap->pixmap, panel->font12, 2, 0,
100, WALeft, WMColorGC(scrPtr->black), False, "Black",
strlen("Black"));
RDestroyImage(image);
WMSetSliderImage(panel->cmykBlackS, pixmap);
@@ -932,16 +937,15 @@ makeColorPanel(WMScreen *scrPtr, char *name)
panel->customPaletteContentView = W_CreateView(
W_VIEW(panel->customPaletteContentFrm));
/* XXX Can we create a view ? */
/* 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);
ButtonPressMask|ButtonReleaseMask|EnterWindowMask| LeaveWindowMask |
ButtonMotionMask, customPaletteHandleActionEvents, panel);
WMCreateEventHandler(panel->customPaletteContentView, ExposureMask,
customPaletteHandleEvents, panel);
@@ -1070,9 +1074,7 @@ WMFreeColorPanel(WMColorPanel *panel)
}
WMRemoveNotificationObserver(panel);
WMUnmapWidget(panel->win);
WMDestroyWidget(panel->win);
/* fonts */
if (panel->font8)
@@ -1098,6 +1100,8 @@ WMFreeColorPanel(WMColorPanel *panel)
if (panel->configurationPath)
wfree(panel->configurationPath);
WMDestroyWidget(panel->win);
wfree(panel);
}
@@ -1105,7 +1109,6 @@ WMFreeColorPanel(WMColorPanel *panel)
void
WMCloseColorPanel(WMColorPanel *panel)
{
WMCloseWindow(panel->win);
WMFreeColorPanel(panel);
}
@@ -1155,8 +1158,9 @@ readConfiguration(W_ColorPanel *panel)
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);
"File Error",
"Could not create ColorPanel configuration directory",
"OK", NULL, NULL);
}
return;
}
@@ -1429,101 +1433,186 @@ modeButtonCallback(WMWidget *w, void *data)
/****************** Magnifying Cursor Functions *******************/
static Pixmap
magnifyGetImage(WMScreen *scr, int x, int y)
static XImage*
magnifyGetImage(WMScreen *scr, XImage *image, int x, int y, int w, int h)
{
XImage *image;
Pixmap pixmap;
int x0, y0, w0, h0;
int displayWidth = DisplayWidth(scr->display, scr->screen);
int displayHeight = DisplayHeight(scr->display, scr->screen);
const int half_mask_width = (Cursor_mask_width +1)/2;
const int half_mask_height = (Cursor_mask_height +1)/2;
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("ColorPanel: X said I cannot grab an image from screen.");
return image;
}
/* Coordinate correction for back pixmap
* if magnifying glass is at screen-borders */
x0 = 0; y0 = 0; w0 = Cursor_mask_width; h0 = Cursor_mask_height;
* if magnifying glass is at screen-borders
*/
if (x < half_mask_width) {
if (x < 0) x = 0;
x0 = half_mask_width - x;
w0 = Cursor_mask_width - x0;
/* 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 (x > displayWidth - half_mask_width) {
if (x > displayWidth) x = displayWidth;
w0 = Cursor_mask_width - (half_mask_width - (displayWidth - x));
if (displayWidth -1 < x - Cursor_x_hot + w) { /* see fig. 2 */
w0 = (displayWidth) - (x - Cursor_x_hot);
}
if (y < half_mask_height) {
if (y < 0) y = 0;
y0 = half_mask_height - y;
h0 = Cursor_mask_height - y0;
if (y < Cursor_y_hot) { /* see fig. 1 */
y0 = Cursor_y_hot - y;
h0 = h - y0;
}
if (y > displayHeight - half_mask_height) {
if (y > displayHeight) y = displayHeight;
h0 = Cursor_mask_height - (half_mask_height - (displayHeight - y));
if (displayHeight -1 < y - Cursor_y_hot + h) { /* see fig. 2 */
h0 = (displayHeight) - (y - Cursor_y_hot);
}
/* end of coordinate correction */
image = XGetImage(scr->display, scr->rootWin, x + x0 - Cursor_x_hot,
y + y0 - Cursor_y_hot, w0, h0, AllPlanes, ZPixmap);
pixmap = XCreatePixmap(scr->display, W_DRAWABLE(scr), Cursor_mask_width,
Cursor_mask_height, scr->depth);
XPutImage(scr->display, pixmap, scr->copyGC, image, 0, 0, x0, y0, w0, h0);
XDestroyImage(image);
/* 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("ColorPanel: X said I cannot grab a subimage from screen.");
return pixmap;
return NULL;
}
static Pixmap
magnifyGetStorePixmap(WMColorPanel *panel, int x1, int y1, int x2, int y2)
static void
magnifyGetImageStored(WMColorPanel *panel, int x1, int y1, int x2, int y2)
{
/*
* (x1, y1) = topleft corner of existing rectangle
/* (x1, y1) = topleft corner of existing rectangle
* (x2, y2) = topleft corner of new position
*/
W_Screen *scr = WMWidgetScreen(panel->win);
Pixmap pixmap;
int xa, ya, xb, yb, w, h;
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 (x1 < x2) {
xa = x2 - x1;
xb = 0;
if ((dx == 0) && (dy == 0) && panel->magnifyGlass->image)
return; /* Eh, Captain, we didn't move...
* but... eh... how did we get here? */
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 {
xa = 0;
xb = x1 - x2;
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("ColorPanel: X said I cannot get a dirty rectangle.");
return; /* X returned a NULL from XSubImage */
}
}
}
if (y1 < y2) {
ya = y2 - y1;
yb = 0;
} else {
ya = 0;
yb = y1 - y2;
/* 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;
}
w = Cursor_mask_width - abs(x1-x2);
h = Cursor_mask_height - abs(y1-y2);
/* Copy previously stored rectangle on covered part of image */
if (panel->magnifyGlass->image && panel->magnifyGlass->dirtyRect) {
int old_height;
/* Get pixmap from screen */
pixmap = magnifyGetImage(scr, x2, y2);
/* "width" and "height" are used as coordinates here,
* and run from [0...width-1] and [0...height-1] respectively.
*/
width--;
height--;
old_height = height;
/* Copy previously stored pixmap on covered part of above pixmap */
if (panel->magnifyGlass->valid)
{
XCopyArea(scr->display, panel->magnifyGlass->pixmap, pixmap,
scr->copyGC, xa, ya, w, h, xb, yb);
/* Free it, so we can reuse it */
XFreePixmap(scr->display, panel->magnifyGlass->pixmap);
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 pixmap;
return;
}
@@ -1532,58 +1621,49 @@ magnifyCreatePixmap(WMColorPanel *panel)
{
W_Screen *scr = WMWidgetScreen(panel->win);
int u, v;
int i, j;
int ofs;
Pixmap magPix;
Pixmap backPix;
RImage *pixelImg;
const int half_mask_width = Cursor_mask_width/2;
const int half_mask_height = Cursor_mask_height/2;
Pixmap pixmap;
unsigned long color;
if (!panel->magnifyGlass->image)
return None;
if (!panel->magnifyGlass->magPix)
return None;
/*
* Get image
* 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);
/* Rectangle that's going to be the background */
backPix = XCreatePixmap(scr->display, W_DRAWABLE(scr), Cursor_mask_width,
XSetForeground(scr->display, scr->copyGC, color);
if ((u == 2) && (v == 2)) /* (2,2) is center pixel (unmagn.) */
panel->magnifyGlass->color = ulongToRColor(scr,
panel->magnifyGlass->image, color);
XFillRectangle(scr->display, panel->magnifyGlass->magPix,
scr->copyGC, u * 5, v * 5, 5, 5);
}
}
pixmap = XCreatePixmap(scr->display, W_DRAWABLE(scr), Cursor_mask_width,
Cursor_mask_height, scr->depth);
XCopyArea(scr->display, panel->magnifyGlass->pixmap, backPix, scr->copyGC,
0, 0, Cursor_mask_width, Cursor_mask_height, 0, 0);
if (!pixmap)
return None;
/*
* Magnify image
*/
magPix = XCreatePixmap(scr->display, W_DRAWABLE(scr), Cursor_mask_width +2,
Cursor_mask_height +2, scr->depth);
for (u=0; u<5+1; u++) /* Copy an area of 5x5 pixels from the center */
for (v=0; v<5+1; v++)
for (i=u*5; i < (u+1)*5; i++) /* magnify it 5 times */
for (j=v*5; j < (v+1)*5; j++)
XCopyArea(scr->display, backPix, magPix, scr->copyGC,
u +9, v +9, 1, 1, i, j);
/* Get color under hotspot */
ofs = half_mask_width + half_mask_height * Cursor_mask_width;
pixelImg = RCreateImageFromDrawable(scr->rcontext, backPix, backPix);
panel->magnifyGlass->color.red = pixelImg->data[0][ofs];
panel->magnifyGlass->color.green = pixelImg->data[1][ofs];
panel->magnifyGlass->color.blue = pixelImg->data[2][ofs];
RDestroyImage(pixelImg);
#ifndef SHAPE
XPutImage(scr->display, pixmap, scr->copyGC, panel->magnifyGlass->image,
0, 0, 0, 0, Cursor_mask_width, Cursor_mask_height);
#endif
/* Copy the magnified pixmap, with the clip mask, to background pixmap */
XSetClipMask(scr->display, scr->clipGC, panel->magnifyGlass->mask);
XSetClipOrigin(scr->display, scr->clipGC, 0, 0);
XCopyArea(scr->display, magPix, backPix, scr->clipGC, 2, 2,
Cursor_mask_width, Cursor_mask_height, 0, 0);
XCopyArea(scr->display, panel->magnifyGlass->magPix, pixmap,
scr->clipGC, 1, 1, Cursor_mask_width, Cursor_mask_height, 0, 0);
/* (2,2) puts center pixel on center of glass */
XFreePixmap(scr->display, magPix);
return backPix;
return pixmap;
}
@@ -1594,14 +1674,17 @@ magnifyCreateView(W_ColorPanel *panel)
WMView *magView;
magView = W_CreateTopView(scr);
if (!magView)
return NULL;
W_ResizeView(magView, Cursor_mask_width, Cursor_mask_height);
magView->self = panel->win;
magView->flags.topLevel = 1;
magView->attribFlags |= CWOverrideRedirect | CWSaveUnder;
magView->attribs.event_mask = StructureNotifyMask;
magView->attribs.override_redirect = True;
magView->attribs.save_under = True;
W_ResizeView(magView, Cursor_mask_width, Cursor_mask_height);
W_RealizeView(magView);
return magView;
@@ -1619,9 +1702,9 @@ magnifyGrabPointer(W_ColorPanel *panel)
/* Cursor creation stuff */
magPixmap = XCreatePixmapFromBitmapData(scr->display, W_DRAWABLE(scr),
Cursor_bits, Cursor_width, Cursor_height, 1, 0, 1);
(char *)Cursor_bits, Cursor_width, Cursor_height, 1, 0, 1);
magPixmap2 = XCreatePixmapFromBitmapData(scr->display, W_DRAWABLE(scr),
Cursor_shape_bits, Cursor_width, Cursor_height, 1, 0, 1);
(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);
@@ -1645,29 +1728,42 @@ static WMPoint
magnifyInitialize(W_ColorPanel *panel)
{
W_Screen *scr = WMWidgetScreen(panel->win);
int x, y, u, v;
unsigned int x, y, u, v;
unsigned int mask;
Pixmap pixmap;
Pixmap pixmap, clip_mask;
WMPoint point;
Window root_return, child_return;
XQueryPointer(scr->display, scr->rootWin, &scr->rootWin,
&W_VIEW(panel->win)->window, &x, &y, &u, &v, &mask);
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, 5*5, 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 */
panel->magnifyGlass->mask = XCreatePixmapFromBitmapData(scr->display,
W_DRAWABLE(scr), Cursor_mask_bits,
Cursor_mask_width, Cursor_mask_height, 1, 0, 1);
/* Draw initial magnified part */
panel->magnifyGlass->valid = False;
/* also free's magnifyGlass->pixmap */
panel->magnifyGlass->pixmap = magnifyGetStorePixmap(panel, x, y, x, y);
panel->magnifyGlass->valid = True;
#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, panel->magnifyGlass->view->window,
XSetWindowBackgroundPixmap(scr->display,
panel->magnifyGlass->view->window,
pixmap);
XClearWindow(scr->display, panel->magnifyGlass->view->window);
XFlush(scr->display);
@@ -1702,27 +1798,34 @@ magnifyPutCursor(WMWidget *w, void *data)
/* Create magnifying glass */
panel->magnifyGlass = wmalloc(sizeof(MovingView));
panel->magnifyGlass->view = magnifyCreateView(panel);
if (!panel->magnifyGlass->view)
return;
initialPosition = magnifyInitialize(panel);
x = initialPosition.x;
y = initialPosition.y;
W_MoveView(panel->magnifyGlass->view,
x - Cursor_x_hot +1,
y - Cursor_y_hot +1);
x - Cursor_x_hot,
y - Cursor_y_hot);
W_MapView(panel->magnifyGlass->view);
magCursor = magnifyGrabPointer(panel);
while(panel->magnifyGlass->valid)
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) {
updateSwatch(panel, panel->magnifyGlass->color);
}
@@ -1748,39 +1851,48 @@ magnifyPutCursor(WMWidget *w, void *data)
break;
}
panel->lastChanged = panel->mode;
panel->magnifyGlass->valid = False;
WMSetButtonSelected(panel->magnifyBtn, False);
break;
case MotionNotify:
/* Get a "dirty rectangle" */
panel->magnifyGlass->pixmap = magnifyGetStorePixmap(
panel, x+1, y+1,
event.xmotion.x_root+1, event.xmotion.y_root+1);
/* also free's magnifyGlass->pixmap */
magnifyGetImageStored( panel, x, y,
event.xmotion.x_root, event.xmotion.y_root);
/* Update coordinates */
x = event.xmotion.x_root;
y = event.xmotion.y_root;
/* Move view */
W_MoveView(panel->magnifyGlass->view, x - Cursor_x_hot +1,
y - Cursor_y_hot +1);
W_MoveView(panel->magnifyGlass->view, x - Cursor_x_hot,
y - Cursor_y_hot);
/* Put new image (with magn.) in view */
pixmap = magnifyCreatePixmap(panel);
if (pixmap != None) {
XSetWindowBackgroundPixmap(scr->display,
panel->magnifyGlass->view->window, pixmap);
XClearWindow(scr->display, panel->magnifyGlass->view->window);
XFreePixmap(scr->display, pixmap);
}
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);
@@ -1788,33 +1900,27 @@ magnifyPutCursor(WMWidget *w, void *data)
magnifyInitialize(panel);
W_MapView(panel->magnifyGlass->view);
XGrabPointer (scr->display,
panel->magnifyGlass->view->window,
True,
PointerMotionMask | ButtonPressMask,
GrabModeAsync,
GrabModeAsync,
scr->rootWin,
magCursor,
CurrentTime);
XGrabPointer (scr->display, panel->magnifyGlass->view->window,
True, PointerMotionMask | ButtonPressMask,
GrabModeAsync, GrabModeAsync,
scr->rootWin, magCursor, CurrentTime);
break;
#endif
default:
WMHandleEvent(&event);
break;
} /* of switch */
}
panel->magnifyGlass->valid = False;
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);
XFreePixmap(scr->display, panel->magnifyGlass->mask);
panel->magnifyGlass->mask = None;
XFreePixmap(scr->display, panel->magnifyGlass->pixmap);
panel->magnifyGlass->pixmap = None;
panel->magnifyGlass->view = NULL;
wfree(panel->magnifyGlass);
}
@@ -2104,8 +2210,7 @@ wheelHandleActionEvents(XEvent *event, void *data)
if (getPickerPart(panel, event->xbutton.x, event->xbutton.y) ==
COLORWHEEL_PART) {
panel->flags.dragging = 1;
wheelPositionSelection(panel, event->xbutton.x,
event->xbutton.y);
wheelPositionSelection(panel, event->xbutton.x, event->xbutton.y);
}
break;
@@ -2245,11 +2350,12 @@ wheelPositionSelection(W_ColorPanel *panel, int x, int y)
{
unsigned long ofs = (y * panel->wheelMtrx->width)+ x;
panel->color.red = panel->wheelMtrx->values[
panel->wheelMtrx->data[0][ofs] ];
panel->color.green = panel->wheelMtrx->values[
panel->wheelMtrx->data[1][ofs] ];
panel->color.blue = panel->wheelMtrx->values[
panel->wheelMtrx->data[2][ofs] ];
@@ -2361,7 +2467,6 @@ grayBrightnessSliderCallback(WMWidget *w, void *data)
RColor color;
int value;
char tmp[4];
W_ColorPanel *panel = (W_ColorPanel*)data;
value = WMGetSliderValue(panel->grayBrightnessS);
@@ -2382,7 +2487,6 @@ grayPresetButtonCallback(WMWidget *w, void *data)
char tmp[4];
int value;
int i=0;
W_ColorPanel *panel = (W_ColorPanel*)data;
while (i < 7) {
@@ -2435,7 +2539,6 @@ rgbSliderCallback(WMWidget *w, void *data)
RColor color;
int value[3];
char tmp[4];
W_ColorPanel *panel = (W_ColorPanel*)data;
value[0] = WMGetSliderValue(panel->rgbRedS);
@@ -2505,7 +2608,6 @@ cmykSliderCallback(WMWidget *w, void *data)
RColor color;
int value[4];
char tmp[4];
W_ColorPanel *panel = (W_ColorPanel*)data;
value[0] = WMGetSliderValue(panel->cmykCyanS);
@@ -2553,10 +2655,13 @@ cmykTextFieldCallback(void *observerData, WMNotification *notification)
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);
@@ -2581,7 +2686,6 @@ hsbSliderCallback(WMWidget *w, void *data)
RColor color;
int value[3];
char tmp[4];
W_ColorPanel *panel = (W_ColorPanel*)data;
value[0] = WMGetSliderValue(panel->hsbHueS);
@@ -2708,13 +2812,9 @@ hsbUpdateSaturationGradient(W_ColorPanel *panel)
sliderImg = RRenderGradient(141, 16, &from, &to, RGRD_HORIZONTAL);
sliderPxmp = WMCreatePixmapFromRImage(scr, sliderImg, 0);
RDestroyImage(sliderImg);
if (hsvcolor.value < 128)
W_PaintText(W_VIEW(panel->hsbSaturationS), sliderPxmp->pixmap,
panel->font12, 2, 0, 100, WALeft, WMColorGC(scr->white), False,
"Saturation", strlen("Saturation"));
else
W_PaintText(W_VIEW(panel->hsbSaturationS), sliderPxmp->pixmap,
panel->font12, 2, 0, 100, WALeft, WMColorGC(scr->black), False,
panel->font12, 2, 0, 100, WALeft,
WMColorGC(hsvcolor.value < 128 ? scr->white : scr->black), False,
"Saturation", strlen("Saturation"));
WMSetSliderImage(panel->hsbSaturationS, sliderPxmp);
@@ -2744,13 +2844,9 @@ hsbUpdateHueGradient(W_ColorPanel *panel)
sliderImg = RRenderMultiGradient(141, 16, colors, RGRD_HORIZONTAL);
sliderPxmp = WMCreatePixmapFromRImage(scr, sliderImg, 0);
RDestroyImage(sliderImg);
if (hsvcolor.value < 128)
W_PaintText(W_VIEW(panel->hsbHueS), sliderPxmp->pixmap,
panel->font12, 2, 0, 100, WALeft, WMColorGC(scr->white), False,
"Hue", strlen("Hue"));
else
W_PaintText(W_VIEW(panel->hsbHueS), sliderPxmp->pixmap,
panel->font12, 2, 0, 100, WALeft, WMColorGC(scr->black), False,
panel->font12, 2, 0, 100, WALeft,
WMColorGC(hsvcolor.value < 128 ? scr->white : scr->black), False,
"Hue", strlen("Hue"));
WMSetSliderImage(panel->hsbHueS, sliderPxmp);
@@ -3016,8 +3112,7 @@ customPaletteMenuNewFromFile(W_ColorPanel *panel)
/* Get a filename */
if (WMRunModalFilePanelForDirectory(browseP, panel->win, spath,
"Open Palette",
RSupportedFileFormats()) ) {
"Open Palette", RSupportedFileFormats()) ) {
filepath = WMGetFilePanelFileName(browseP);
/* Get seperation position between path and filename */
@@ -3190,8 +3285,8 @@ customPaletteMenuRemove(W_ColorPanel *panel)
tmp = wstrappend( "This will permanently remove the palette ",
WMGetPopUpButtonItem(panel->customPaletteHistoryBtn, item ));
text = wstrappend( tmp, ".\n\nAre you sure you want to remove this"
" palette ?");
text = wstrappend( tmp,
".\n\nAre you sure you want to remove this palette ?");
wfree(tmp);
choice = WMRunAlertPanel(scr, panel->win, NULL, text, "Yes", "No", NULL);
@@ -3533,3 +3628,53 @@ generateNewFilename(char *curName)
return newName;
}
static int
get_shifts(unsigned long mask)
{
int i=0;
while (mask) {
mask>>=1;
i++;
}
return i;
}
RColor
ulongToRColor(WMScreen *scr, XImage *image, unsigned long value)
{
RColor color;
int rmask, gmask, bmask;
int rshift, gshift, bshift;
if (scr->rcontext->depth == image->depth) {
rmask = scr->rcontext->visual->red_mask;
gmask = scr->rcontext->visual->green_mask;
bmask = scr->rcontext->visual->blue_mask;
} else {
rmask = image->red_mask;
gmask = image->green_mask;
bmask = image->blue_mask;
}
rshift = get_shifts(rmask) -8; /* -8 because otherwise the byte */
gshift = get_shifts(gmask) -8; /* containing the color would be */
bshift = get_shifts(bmask) -8; /* shifted over the edge. */
color.red = (rshift > 0) ? (value & rmask) >> rshift :
(value & rmask) << -rshift;
color.green = (gshift > 0) ? (value & gmask) >> gshift :
(value & gmask) << -gshift;
color.blue = (bshift > 0) ? (value & bmask) >> bshift :
(value & bmask) << -bshift;
return color;
}
#ifdef SHAPE_WAS_DEFINED
#undef SHAPE_WAS_DEFINED
#define SHAPE
#endif