mirror of
https://github.com/gryf/wmaker.git
synced 2025-12-20 21:08:08 +01:00
It is dangerous to let the compiler know about a function without letting him know the arguments because he won't be able to report invalid calls. This patch concern the cases where adding the arguments did not need other code change.
413 lines
9.8 KiB
C
413 lines
9.8 KiB
C
|
|
#include "WINGsP.h"
|
|
|
|
#define XDND_COLOR_DATA_TYPE "application/X-color"
|
|
|
|
char *WMColorWellDidChangeNotification = "WMColorWellDidChangeNotification";
|
|
|
|
typedef struct W_ColorWell {
|
|
W_Class widgetClass;
|
|
WMView *view;
|
|
|
|
WMView *colorView;
|
|
|
|
WMColor *color;
|
|
|
|
WMAction *action;
|
|
void *clientData;
|
|
|
|
WMPoint ipoint;
|
|
|
|
struct {
|
|
unsigned int active:1;
|
|
unsigned int bordered:1;
|
|
} flags;
|
|
|
|
WMArray *xdndTypes;
|
|
} ColorWell;
|
|
|
|
static char *_ColorWellActivatedNotification = "_ColorWellActivatedNotification";
|
|
|
|
static void destroyColorWell(ColorWell * cPtr);
|
|
static void paintColorWell(ColorWell * cPtr);
|
|
|
|
static void handleEvents(XEvent * event, void *data);
|
|
|
|
static void handleDragEvents(XEvent * event, void *data);
|
|
|
|
static void handleActionEvents(XEvent * event, void *data);
|
|
|
|
static void willResizeColorWell(W_ViewDelegate * self, WMView * view, unsigned int *width, unsigned int *height);
|
|
|
|
W_ViewDelegate _ColorWellViewDelegate = {
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
willResizeColorWell
|
|
};
|
|
|
|
static WMArray *dropDataTypes(WMView * self);
|
|
static WMDragOperationType wantedDropOperation(WMView * self);
|
|
static Bool acceptDropOperation(WMView * self, WMDragOperationType operation);
|
|
static WMData *fetchDragData(WMView * self, char *type);
|
|
|
|
static WMDragSourceProcs _DragSourceProcs = {
|
|
dropDataTypes,
|
|
wantedDropOperation,
|
|
NULL,
|
|
acceptDropOperation,
|
|
NULL,
|
|
NULL,
|
|
fetchDragData
|
|
};
|
|
|
|
static WMArray *requiredDataTypes(WMView * self,
|
|
WMDragOperationType requestedOperation, WMArray * sourceDataTypes);
|
|
static WMDragOperationType allowedOperation(WMView * self,
|
|
WMDragOperationType requestedOperation, WMArray * sourceDataTypes);
|
|
static void performDragOperation(WMView * self, WMArray * dropDatas,
|
|
WMArray * operationsList, WMPoint * dropLocation);
|
|
|
|
static WMDragDestinationProcs _DragDestinationProcs = {
|
|
NULL,
|
|
requiredDataTypes,
|
|
allowedOperation,
|
|
NULL,
|
|
performDragOperation,
|
|
NULL
|
|
};
|
|
|
|
#define DEFAULT_WIDTH 60
|
|
#define DEFAULT_HEIGHT 30
|
|
#define DEFAULT_BORDER_WIDTH 6
|
|
|
|
#define MIN_WIDTH 16
|
|
#define MIN_HEIGHT 8
|
|
|
|
static void colorChangedObserver(void *data, WMNotification * notification)
|
|
{
|
|
WMColorPanel *panel = (WMColorPanel *) WMGetNotificationObject(notification);
|
|
WMColorWell *cPtr = (WMColorWell *) data;
|
|
WMColor *color;
|
|
|
|
if (!cPtr->flags.active)
|
|
return;
|
|
|
|
color = WMGetColorPanelColor(panel);
|
|
|
|
WMSetColorWellColor(cPtr, color);
|
|
WMPostNotificationName(WMColorWellDidChangeNotification, cPtr, NULL);
|
|
}
|
|
|
|
static void updateColorCallback(void *self, void *data)
|
|
{
|
|
WMColorPanel *panel = (WMColorPanel *) self;
|
|
WMColorWell *cPtr = (ColorWell *) data;
|
|
WMColor *color;
|
|
|
|
color = WMGetColorPanelColor(panel);
|
|
WMSetColorWellColor(cPtr, color);
|
|
WMPostNotificationName(WMColorWellDidChangeNotification, cPtr, NULL);
|
|
}
|
|
|
|
static void activatedObserver(void *data, WMNotification * notification)
|
|
{
|
|
/*
|
|
WMColorWell *cPtr = (WMColorWell*)data;
|
|
|
|
if (!cPtr->flags.active || WMGetNotificationObject(notification) == cPtr)
|
|
return;
|
|
|
|
W_SetViewBackgroundColor(cPtr->view, WMWidgetScreen(cPtr)->gray);
|
|
paintColorWell(cPtr);
|
|
|
|
cPtr->flags.active = 0;
|
|
*/
|
|
}
|
|
|
|
static WMArray *getXdndTypeArray(void)
|
|
{
|
|
WMArray *types = WMCreateArray(1);
|
|
WMAddToArray(types, XDND_COLOR_DATA_TYPE);
|
|
return types;
|
|
}
|
|
|
|
WMColorWell *WMCreateColorWell(WMWidget * parent)
|
|
{
|
|
ColorWell *cPtr;
|
|
|
|
cPtr = wmalloc(sizeof(ColorWell));
|
|
|
|
cPtr->widgetClass = WC_ColorWell;
|
|
|
|
cPtr->view = W_CreateView(W_VIEW(parent));
|
|
if (!cPtr->view) {
|
|
wfree(cPtr);
|
|
return NULL;
|
|
}
|
|
cPtr->view->self = cPtr;
|
|
|
|
cPtr->view->delegate = &_ColorWellViewDelegate;
|
|
|
|
cPtr->colorView = W_CreateView(cPtr->view);
|
|
if (!cPtr->colorView) {
|
|
W_DestroyView(cPtr->view);
|
|
wfree(cPtr);
|
|
return NULL;
|
|
}
|
|
cPtr->colorView->self = cPtr;
|
|
|
|
WMCreateEventHandler(cPtr->view, ExposureMask | StructureNotifyMask
|
|
| ClientMessageMask, handleEvents, cPtr);
|
|
|
|
WMCreateEventHandler(cPtr->colorView, ExposureMask, handleEvents, cPtr);
|
|
|
|
WMCreateDragHandler(cPtr->colorView, handleDragEvents, cPtr);
|
|
|
|
WMCreateEventHandler(cPtr->view, ButtonPressMask, handleActionEvents, cPtr);
|
|
|
|
cPtr->colorView->flags.mapWhenRealized = 1;
|
|
|
|
cPtr->flags.bordered = 1;
|
|
|
|
W_ResizeView(cPtr->view, DEFAULT_WIDTH, DEFAULT_HEIGHT);
|
|
|
|
WMAddNotificationObserver(activatedObserver, cPtr, _ColorWellActivatedNotification, NULL);
|
|
|
|
cPtr->color = WMBlackColor(WMWidgetScreen(cPtr));
|
|
|
|
WMAddNotificationObserver(colorChangedObserver, cPtr, WMColorPanelColorChangedNotification, NULL);
|
|
|
|
WMSetViewDragSourceProcs(cPtr->colorView, &_DragSourceProcs);
|
|
WMSetViewDragDestinationProcs(cPtr->colorView, &_DragDestinationProcs);
|
|
|
|
cPtr->xdndTypes = getXdndTypeArray();
|
|
WMRegisterViewForDraggedTypes(cPtr->colorView, cPtr->xdndTypes);
|
|
|
|
return cPtr;
|
|
}
|
|
|
|
void WMSetColorWellColor(WMColorWell * cPtr, WMColor * color)
|
|
{
|
|
if (cPtr->color)
|
|
WMReleaseColor(cPtr->color);
|
|
|
|
cPtr->color = WMRetainColor(color);
|
|
|
|
if (cPtr->colorView->flags.realized && cPtr->colorView->flags.mapped)
|
|
paintColorWell(cPtr);
|
|
}
|
|
|
|
WMColor *WMGetColorWellColor(WMColorWell * cPtr)
|
|
{
|
|
return cPtr->color;
|
|
}
|
|
|
|
void WSetColorWellBordered(WMColorWell * cPtr, Bool flag)
|
|
{
|
|
flag = ((flag == 0) ? 0 : 1);
|
|
if (cPtr->flags.bordered != flag) {
|
|
cPtr->flags.bordered = flag;
|
|
W_ResizeView(cPtr->view, cPtr->view->size.width, cPtr->view->size.height);
|
|
}
|
|
}
|
|
|
|
static void willResizeColorWell(W_ViewDelegate * self, WMView * view, unsigned int *width, unsigned int *height)
|
|
{
|
|
WMColorWell *cPtr = (WMColorWell *) view->self;
|
|
int bw;
|
|
|
|
if (cPtr->flags.bordered) {
|
|
|
|
if (*width < MIN_WIDTH)
|
|
*width = MIN_WIDTH;
|
|
if (*height < MIN_HEIGHT)
|
|
*height = MIN_HEIGHT;
|
|
|
|
bw = (int)((float)WMIN(*width, *height) * 0.24);
|
|
|
|
W_ResizeView(cPtr->colorView, *width - 2 * bw, *height - 2 * bw);
|
|
|
|
if (cPtr->colorView->pos.x != bw || cPtr->colorView->pos.y != bw)
|
|
W_MoveView(cPtr->colorView, bw, bw);
|
|
} else {
|
|
W_ResizeView(cPtr->colorView, *width, *height);
|
|
|
|
W_MoveView(cPtr->colorView, 0, 0);
|
|
}
|
|
}
|
|
|
|
static void paintColorWell(ColorWell * cPtr)
|
|
{
|
|
W_Screen *scr = cPtr->view->screen;
|
|
|
|
W_DrawRelief(scr, cPtr->view->window, 0, 0, cPtr->view->size.width, cPtr->view->size.height, WRRaised);
|
|
|
|
W_DrawRelief(scr, cPtr->colorView->window, 0, 0,
|
|
cPtr->colorView->size.width, cPtr->colorView->size.height, WRSunken);
|
|
|
|
if (cPtr->color)
|
|
WMPaintColorSwatch(cPtr->color, cPtr->colorView->window,
|
|
2, 2, cPtr->colorView->size.width - 4, cPtr->colorView->size.height - 4);
|
|
}
|
|
|
|
static void handleEvents(XEvent * event, void *data)
|
|
{
|
|
ColorWell *cPtr = (ColorWell *) data;
|
|
|
|
CHECK_CLASS(data, WC_ColorWell);
|
|
|
|
switch (event->type) {
|
|
case Expose:
|
|
if (event->xexpose.count != 0)
|
|
break;
|
|
paintColorWell(cPtr);
|
|
break;
|
|
|
|
case DestroyNotify:
|
|
destroyColorWell(cPtr);
|
|
break;
|
|
|
|
}
|
|
}
|
|
|
|
static WMArray *dropDataTypes(WMView * self)
|
|
{
|
|
return ((ColorWell *) self->self)->xdndTypes;
|
|
}
|
|
|
|
static WMDragOperationType wantedDropOperation(WMView * self)
|
|
{
|
|
return WDOperationCopy;
|
|
}
|
|
|
|
static Bool acceptDropOperation(WMView * self, WMDragOperationType operation)
|
|
{
|
|
return (operation == WDOperationCopy);
|
|
}
|
|
|
|
static WMData *fetchDragData(WMView * self, char *type)
|
|
{
|
|
char *color = WMGetColorRGBDescription(((WMColorWell *) self->self)->color);
|
|
WMData *data;
|
|
|
|
data = WMCreateDataWithBytes(color, strlen(color) + 1);
|
|
wfree(color);
|
|
|
|
return data;
|
|
}
|
|
|
|
static WMPixmap *makeDragPixmap(WMColorWell * cPtr)
|
|
{
|
|
WMScreen *scr = cPtr->view->screen;
|
|
Pixmap pix;
|
|
|
|
pix = XCreatePixmap(scr->display, W_DRAWABLE(scr), 16, 16, scr->depth);
|
|
|
|
XFillRectangle(scr->display, pix, WMColorGC(cPtr->color), 0, 0, 15, 15);
|
|
|
|
XDrawRectangle(scr->display, pix, WMColorGC(scr->black), 0, 0, 15, 15);
|
|
|
|
return WMCreatePixmapFromXPixmaps(scr, pix, None, 16, 16, scr->depth);
|
|
}
|
|
|
|
static void handleDragEvents(XEvent * event, void *data)
|
|
{
|
|
WMColorWell *cPtr = (ColorWell *) data;
|
|
|
|
if (event->type == ButtonPress && event->xbutton.button == Button1) {
|
|
/* initialise drag icon */
|
|
WMSetViewDragImage(cPtr->colorView, makeDragPixmap(cPtr));
|
|
}
|
|
|
|
WMDragImageFromView(cPtr->colorView, event);
|
|
}
|
|
|
|
static void handleActionEvents(XEvent * event, void *data)
|
|
{
|
|
WMColorWell *cPtr = (ColorWell *) data;
|
|
WMScreen *scr = WMWidgetScreen(cPtr);
|
|
WMColorPanel *cpanel;
|
|
|
|
if (cPtr->flags.active)
|
|
W_SetViewBackgroundColor(cPtr->view, scr->gray);
|
|
else
|
|
W_SetViewBackgroundColor(cPtr->view, scr->white);
|
|
paintColorWell(cPtr);
|
|
|
|
cPtr->flags.active ^= 1;
|
|
|
|
if (cPtr->flags.active) {
|
|
WMPostNotificationName(_ColorWellActivatedNotification, cPtr, NULL);
|
|
}
|
|
cpanel = WMGetColorPanel(scr);
|
|
|
|
WMSetColorPanelAction(cpanel, updateColorCallback, cPtr);
|
|
|
|
if (cPtr->color)
|
|
WMSetColorPanelColor(cpanel, cPtr->color);
|
|
WMShowColorPanel(cpanel);
|
|
}
|
|
|
|
static void destroyColorWell(ColorWell * cPtr)
|
|
{
|
|
WMRemoveNotificationObserver(cPtr);
|
|
|
|
if (cPtr->color)
|
|
WMReleaseColor(cPtr->color);
|
|
|
|
WMFreeArray(cPtr->xdndTypes);
|
|
|
|
wfree(cPtr);
|
|
}
|
|
|
|
static Bool dropIsOk(WMDragOperationType request, WMArray * sourceDataTypes)
|
|
{
|
|
WMArrayIterator iter;
|
|
char *type;
|
|
|
|
if (request == WDOperationCopy) {
|
|
WM_ITERATE_ARRAY(sourceDataTypes, type, iter) {
|
|
if (type != NULL && strcmp(type, XDND_COLOR_DATA_TYPE) == 0) {
|
|
return True;
|
|
}
|
|
}
|
|
}
|
|
|
|
return False;
|
|
}
|
|
|
|
static WMArray *requiredDataTypes(WMView * self, WMDragOperationType request, WMArray * sourceDataTypes)
|
|
{
|
|
if (dropIsOk(request, sourceDataTypes))
|
|
return ((ColorWell *) self->self)->xdndTypes;
|
|
else
|
|
return NULL;
|
|
}
|
|
|
|
static WMDragOperationType allowedOperation(WMView * self, WMDragOperationType request, WMArray * sourceDataTypes)
|
|
{
|
|
if (dropIsOk(request, sourceDataTypes))
|
|
return WDOperationCopy;
|
|
else
|
|
return WDOperationNone;
|
|
}
|
|
|
|
static void performDragOperation(WMView * self, WMArray * dropData, WMArray * operations, WMPoint * dropLocation)
|
|
{
|
|
char *colorName;
|
|
WMColor *color;
|
|
WMData *data;
|
|
|
|
/* only one operation requested (WDOperationCopy) implies only one data */
|
|
data = (WMData *) WMGetFromArray(dropData, 0);
|
|
|
|
if (data != NULL) {
|
|
colorName = (char *)WMDataBytes(data);
|
|
color = WMCreateNamedColor(W_VIEW_SCREEN(self), colorName, True);
|
|
WMSetColorWellColor(self->self, color);
|
|
WMReleaseColor(color);
|
|
}
|
|
}
|