From e7d0c5d9e9ee0c3aaaaad22cd1241a08f815825f Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 7 Apr 2004 02:50:52 +0000 Subject: [PATCH] - Added xdnd v3 support in WINGs (Sylvain Reynal ) - CVS should compile again --- ChangeLog | 1 + WINGs/ChangeLog | 9 +- WINGs/Makefile.am | 1 + WINGs/Tests/Makefile.am | 3 +- WINGs/Tests/wtest.c | 431 ++------ WINGs/WINGs/WINGs.h | 189 ++-- WINGs/WINGs/WINGsP.h | 197 +++- WINGs/configuration.c | 80 +- WINGs/dragdestination.c | 1386 +++++++++++++++++++++---- WINGs/dragsource.c | 2647 +++++++++++++++++++++++------------------------ WINGs/proplist.c | 2 +- WINGs/wcolorwell.c | 335 +++--- WINGs/wevent.c | 268 ++--- WINGs/wfont.c | 443 +++----- WINGs/wframe.c | 204 ++-- WINGs/widgets.c | 408 ++++---- WINGs/wtext.c | 1244 +++++++++++----------- WINGs/wview.c | 429 ++++---- WPrefs.app/Expert.c | 6 +- WPrefs.app/Font.c | 328 +++--- configure.ac | 6 +- src/dialog.c | 3 +- src/screen.c | 8 +- 23 files changed, 4633 insertions(+), 3995 deletions(-) rewrite WINGs/dragdestination.c (73%) rewrite WINGs/dragsource.c (89%) diff --git a/ChangeLog b/ChangeLog index f08d3689..8ed04745 100644 --- a/ChangeLog +++ b/ChangeLog @@ -122,6 +122,7 @@ Changes since version 0.80.2: - Added workaround in global WMWindowAttributes, to avoid creating a second appicon when a KDE3 application opens a config panel. - Updated slovak translation (Jan Tomka ) +- Added xdnd v3 support in WINGs (Sylvain Reynal ) Changes since version 0.80.1: diff --git a/WINGs/ChangeLog b/WINGs/ChangeLog index 8d482aa7..6dcd582c 100644 --- a/WINGs/ChangeLog +++ b/WINGs/ChangeLog @@ -47,13 +47,14 @@ Changes since wmaker 0.80.1: - Fixed small memory leak in the font panel code. - Fixed call to qsort in WMSortArray. - Fixed a memleak in the file panel. -- Double/triple-click selection in text widgets (Vitaly Ovtchinnikov - ) -- fixed bug in tableview (clicked row callback got incorrect row) (Carlos Torres - ) +- Double/triple-click selection in text widgets + (Vitaly Ovtchinnikov ) +- fixed bug in tableview (clicked row callback got incorrect row) + (Carlos Torres ) - Fixed bug in resizing a scrollview - Fixed bug with wrong text wrapping (Alexey Voinov ) - Added wmkrect() +- Added xdnd v3 support (Sylvain Reynal ) Changes since wmaker 0.80.0: diff --git a/WINGs/Makefile.am b/WINGs/Makefile.am index 0fb12dc7..9df6a54d 100644 --- a/WINGs/Makefile.am +++ b/WINGs/Makefile.am @@ -27,6 +27,7 @@ libWINGs_a_SOURCES = \ configuration.c \ connection.c \ data.c \ + dragcommon.c \ dragdestination.c \ dragsource.c \ error.c \ diff --git a/WINGs/Tests/Makefile.am b/WINGs/Tests/Makefile.am index f6b28a11..96842c52 100644 --- a/WINGs/Tests/Makefile.am +++ b/WINGs/Tests/Makefile.am @@ -16,6 +16,7 @@ wtest_DEPENDENCIES = $(top_builddir)/WINGs/libWINGs.a EXTRA_DIST = logo.xpm upbtn.xpm wm.html wm.png INCLUDES = -I$(top_srcdir)/WINGs -I$(top_srcdir)/wrlib -I$(top_srcdir)/src \ - -DRESOURCE_PATH=\"$(datadir)/WINGs\" @HEADER_SEARCH_PATH@ -DDEBUG + -DRESOURCE_PATH=\"$(datadir)/WINGs\" @XFTFLAGS@ @HEADER_SEARCH_PATH@ \ + -DDEBUG diff --git a/WINGs/Tests/wtest.c b/WINGs/Tests/wtest.c index fef03102..d180a6a9 100644 --- a/WINGs/Tests/wtest.c +++ b/WINGs/Tests/wtest.c @@ -28,13 +28,13 @@ Display *dpy; int windowCount = 0; void -closeAction(WMWidget *self, void *data) + closeAction(WMWidget *self, void *data) { WMDestroyWidget(self); windowCount--; printf("window closed, window count = %d\n", windowCount); if (windowCount < 1) - exit(0); + exit(0); } @@ -66,7 +66,7 @@ testFontPanel(WMScreen *scr) WMShowFontPanel(panel); -/* WMFreeFontPanel(panel);*/ + /*WMFreeFontPanel(panel);*/ } @@ -78,15 +78,15 @@ testFrame(WMScreen *scr) WMFrame *frame; int i; static char* titles[] = { - "AboveTop", - "AtTop", - "BelowTop", - "AboveBottom", - "AtBottom", - "BelowBottom" + "AboveTop", + "AtTop", + "BelowTop", + "AboveBottom", + "AtBottom", + "BelowBottom" }; static WMTitlePosition pos[] = { - WTPAboveTop, + WTPAboveTop, WTPAtTop, WTPBelowTop, WTPAboveBottom, @@ -102,11 +102,11 @@ testFrame(WMScreen *scr) WMResizeWidget(win, 400, 300); for (i = 0; i < 6; i++) { - frame = WMCreateFrame(win); - WMMoveWidget(frame, 8+(i%3)*130, 8+(i/3)*130); - WMResizeWidget(frame, 120, 120); + frame = WMCreateFrame(win); + WMMoveWidget(frame, 8+(i%3)*130, 8+(i/3)*130); + WMResizeWidget(frame, 120, 120); WMSetFrameTitle(frame, titles[i]); - WMSetFrameTitlePosition(frame, pos[i]); + WMSetFrameTitlePosition(frame, pos[i]); } WMRealizeWidget(win); @@ -147,31 +147,31 @@ testBox(WMScreen *scr) /*WMSetBoxHorizontal(box, True);*/ for (i = 0; i < 4; i++) { - btn = WMCreateCommandButton(box); - WMSetButtonText(btn, "bla"); - WMMapWidget(btn); - WMAddBoxSubview(box, WMWidgetView(btn), i&1, True, 20, 0, 5); + btn = WMCreateCommandButton(box); + WMSetButtonText(btn, "bla"); + WMMapWidget(btn); + WMAddBoxSubview(box, WMWidgetView(btn), i&1, True, 20, 0, 5); } - + pop = WMCreatePopUpButton(box); WMAddPopUpButtonItem(pop, "ewqeq"); WMAddPopUpButtonItem(pop, "ewqeqrewrw"); WMAddBoxSubview(box, WMWidgetView(pop), False, True, 20, 0, 5); WMMapWidget(pop); - + hbox = WMCreateBox(box); WMSetBoxHorizontal(hbox, True); WMAddBoxSubview(box, WMWidgetView(hbox), False, True, 24, 0, 0); WMMapWidget(hbox); - + for (i = 0; i < 4; i++) { - btn = WMCreateCommandButton(hbox); - WMSetButtonText(btn, "bla"); - WMMapWidget(btn); - WMAddBoxSubview(hbox, WMWidgetView(btn), 1, True, 60, 0, i<3?5:0); + btn = WMCreateCommandButton(hbox); + WMSetButtonText(btn, "bla"); + WMMapWidget(btn); + WMAddBoxSubview(hbox, WMWidgetView(btn), 1, True, 60, 0, i<3?5:0); } - - + + WMRealizeWidget(win); WMMapSubwidgets(win); WMMapWidget(win); @@ -242,16 +242,16 @@ testList(WMScreen *scr) /*WMSetListAllowEmptySelection(list, True);*/ WMMoveWidget(list, 10, 40); for (i=0; i<105; i++) { - sprintf(text, "Item %i", i); - WMAddListItem(list, text); + sprintf(text, "Item %i", i); + WMAddListItem(list, text); } mlist = WMCreateList(win); WMSetListAllowMultipleSelection(mlist, True); /*WMSetListAllowEmptySelection(mlist, True);*/ WMMoveWidget(mlist, 210, 40); for (i=0; i<135; i++) { - sprintf(text, "Item %i", i); - WMAddListItem(mlist, text); + sprintf(text, "Item %i", i); + WMAddListItem(mlist, text); } label = WMCreateLabel(win); @@ -272,9 +272,9 @@ testList(WMScreen *scr) WMSetListDoubleAction(mlist, doubleClick, mlabel); WMAddNotificationObserver(listSelectionObserver, label, - WMListSelectionDidChangeNotification, list); + WMListSelectionDidChangeNotification, list); WMAddNotificationObserver(listSelectionObserver, mlabel, - WMListSelectionDidChangeNotification, mlist); + WMListSelectionDidChangeNotification, mlist); WMRealizeWidget(win); @@ -289,14 +289,14 @@ testButton(WMScreen *scr) WMWindow *win; int i; char *types[] = { - "MomentaryPush", - "PushOnPushOff", - "Toggle", - "Switch", - "Radio", - "MomentaryChange", - "OnOff", - "MomentaryLigh" + "MomentaryPush", + "PushOnPushOff", + "Toggle", + "Switch", + "Radio", + "MomentaryChange", + "OnOff", + "MomentaryLigh" }; windowCount++; @@ -308,11 +308,11 @@ testButton(WMScreen *scr) WMSetWindowCloseAction(win, closeAction, NULL); for (i = 1; i < 9; i++) { - WMButton *b; - b = WMCreateButton(win, i); - WMResizeWidget(b, 150, 24); - WMMoveWidget(b, 20, i*30); - WMSetButtonText(b, types[i-1]); + WMButton *b; + b = WMCreateButton(win, i); + WMResizeWidget(b, 150, 24); + WMMoveWidget(b, 20, i*30); + WMSetButtonText(b, types[i-1]); } WMRealizeWidget(win); @@ -404,7 +404,7 @@ testGradientButtons(WMScreen *scr) WMSetButtonTextColor(btn, color); WMSetBalloonTextForView("This is yet another button.\nBut the balloon has 3 lines.\nYay!", - WMWidgetView(btn)); + WMWidgetView(btn)); WMReleaseColor(color); WMReleaseColor(altColor); @@ -450,12 +450,12 @@ testScrollView(WMScreen *scr) WMSetFrameRelief(f, WRFlat); for (i=0; i<20; i++) { - l = WMCreateLabel(f); - WMResizeWidget(l, 50, 18); - WMMoveWidget(l, 10, 20*i); - sprintf(buffer, "Label %i", i); - WMSetLabelText(l, buffer); - WMSetLabelRelief(l, WRSimple); + l = WMCreateLabel(f); + WMResizeWidget(l, 50, 18); + WMMoveWidget(l, 10, 20*i); + sprintf(buffer, "Label %i", i); + WMSetLabelText(l, buffer); + WMSetLabelRelief(l, WRSimple); } WMMapSubwidgets(f); WMMapWidget(f); @@ -509,10 +509,10 @@ testColorPanel(WMScreen *scr) WMColorPanel *panel = WMGetColorPanel(scr); /*if (colorname) { - startcolor = WMCreateNamedColor(scr, colorname, False); - WMSetColorPanelColor(panel, startcolor); - WMReleaseColor(startcolor); - }*/ + startcolor = WMCreateNamedColor(scr, colorname, False); + WMSetColorPanelColor(panel, startcolor); + WMReleaseColor(startcolor); + }*/ WMShowColorPanel(panel); } @@ -609,7 +609,7 @@ testText(WMScreen *scr) WMFont *font, *ifont; font = WMDefaultSystemFont(scr); - ifont = WMCopyFontWithChanges(scr, font, WFAEmphasized); + ifont = WMCopyFontWithStyle(scr, font, WFSEmphasized); if (ifont) { WMSetTextDefaultFont(text, ifont); WMReleaseFont(ifont); @@ -804,21 +804,21 @@ testTabView(WMScreen *scr) void splitViewConstrainProc(WMSplitView *sPtr, int indView, - int *minSize, int *maxSize) + int *minSize, int *maxSize) { switch (indView) { case 0: - *minSize = 20; - break; + *minSize = 20; + break; case 1: - *minSize = 40; - *maxSize = 80; - break; + *minSize = 40; + *maxSize = 80; + break; case 2: - *maxSize = 60; - break; + *maxSize = 60; + break; default: - break; + break; } } @@ -829,14 +829,14 @@ resizeSplitView(XEvent *event, void *data) WMSplitView *sPtr = (WMSplitView*)data; if (event->type == ConfigureNotify) { - int width = event->xconfigure.width - 10; + int width = event->xconfigure.width - 10; - if (width < WMGetSplitViewDividerThickness(sPtr)) - width = WMGetSplitViewDividerThickness(sPtr); + if (width < WMGetSplitViewDividerThickness(sPtr)) + width = WMGetSplitViewDividerThickness(sPtr); - if (width != WMWidgetWidth(sPtr) || + if (width != WMWidgetWidth(sPtr) || event->xconfigure.height != WMWidgetHeight(sPtr)) - WMResizeWidget(sPtr, width, event->xconfigure.height - 55); + WMResizeWidget(sPtr, width, event->xconfigure.height - 55); } } @@ -862,9 +862,9 @@ removeSubviewButtonAction(WMWidget *self, void *data) int count = WMGetSplitViewSubviewsCount(sPtr); if (count > 2) { - WMView *view = WMGetSplitViewSubviewAt(sPtr, count-1); - WMDestroyWidget(WMWidgetOfView(view)); - WMRemoveSplitViewSubviewAt(sPtr, count-1); + WMView *view = WMGetSplitViewSubviewAt(sPtr, count-1); + WMDestroyWidget(WMWidgetOfView(view)); + WMRemoveSplitViewSubviewAt(sPtr, count-1); } } @@ -969,275 +969,6 @@ testSplitView(WMScreen *scr) } -/*******************************************************************/ - -#include -#include -#include - - -typedef struct { - int x, y; - Bool mouseDown; - char *filename; -} DNDStuff; - -WMPixmap* -getImage(WMScreen *scr, char *file) -{ - char buffer[1000]; - WMPixmap *pix; - - sprintf(buffer, "../../WindowMaker/Icons/%s", file); - pix = WMCreatePixmapFromFile(scr, buffer); - - return pix; -} - - - - -static void -iconMouseStuff(XEvent *event, void *cdata) -{ - WMLabel *label = (WMLabel*)cdata; - DNDStuff *stuff = WMGetHangedData(label); - WMPoint where; - - switch (event->type) { - case ButtonPress: - stuff->x = event->xbutton.x; - stuff->y = event->xbutton.y; - stuff->mouseDown = True; - break; - case ButtonRelease: - stuff->mouseDown = False; - break; - case MotionNotify: - if (!stuff->mouseDown) - break; - - if (abs(stuff->x - event->xmotion.x)>4 - || abs(stuff->y - event->xmotion.y)>4) { - - where = WMGetViewScreenPosition(WMWidgetView(label)); - - WMDragImageFromView(WMWidgetView(label), - WMGetLabelImage(label), - NULL, /* XXX */ - where, - wmksize(stuff->x, stuff->y), - event, True); - } - break; - } -} - - -static void -endedDragImage(WMView *self, WMPixmap *image, WMPoint point, Bool deposited) -{ - DNDStuff *stuff = WMGetHangedData(WMWidgetOfView(self)); - - if (deposited) { - WMDestroyWidget(WMWidgetOfView(self)); - } - - stuff->mouseDown = False; -} - - -static WMData* -fetchDragData(WMView *self, char *type) -{ - DNDStuff *stuff = WMGetHangedData(WMWidgetOfView(self)); - - return WMCreateDataWithBytes(stuff->filename, strlen(stuff->filename)+1); -} - - -WMDragSourceProcs dragSourceProcs = { - NULL, - NULL, - endedDragImage, - fetchDragData -}; - - -/************************/ - - -unsigned -draggingEntered(WMView *self, WMDraggingInfo *info) -{ - return WDOperationCopy; -} - - -unsigned -draggingUpdated(WMView *self, WMDraggingInfo *info) -{ - return WDOperationCopy; -} - -/* - void (*draggingExited)(WMView *self, WMDraggingInfo *info); - */ -char* -prepareForDragOperation(WMView *self, WMDraggingInfo *info) -{ - return "application/X-WINGs-Bla"; -} - - -WMLabel* makeDraggableLabel(WMWidget *w, char *file, int x, int y); - -Bool -performDragOperation(WMView *self, WMDraggingInfo *info, WMData *data) -{ - char *file = (char*)WMDataBytes(data); - WMPoint pos; - - pos = WMGetDraggingInfoImageLocation(info); - - if (file!=NULL) { - WMLabel *label; - WMPoint pos2 = WMGetViewScreenPosition(self); - - - label = makeDraggableLabel(WMWidgetOfView(self), file, - pos.x-pos2.x, pos.y-pos2.y); - WMRealizeWidget(label); - WMMapWidget(label); - } - - - return True; -} - - -void -concludeDragOperation(WMView *self, WMDraggingInfo *info) -{ - -} - - - -WMDragDestinationProcs dragDestProcs = { - draggingEntered, - draggingUpdated, - NULL, - prepareForDragOperation, - performDragOperation, - concludeDragOperation -}; - - - - -WMLabel* -makeDraggableLabel(WMWidget *w, char *file, int x, int y) -{ - DNDStuff *stuff; - WMLabel *label; - WMPixmap *image = getImage(WMWidgetScreen(w), file); - - stuff = wmalloc(sizeof(DNDStuff)); - stuff->mouseDown = False; - - stuff->filename = wstrdup(file); - - label = WMCreateLabel(w); - WMResizeWidget(label, 48, 48); - WMMoveWidget(label, x, y); - - WMSetViewDragSourceProcs(WMWidgetView(label), &dragSourceProcs); - - WMHangData(label, stuff); - - WMCreateEventHandler(WMWidgetView(label), - ButtonPressMask|ButtonReleaseMask|ButtonMotionMask, - iconMouseStuff, label); - - - if (image != NULL) { - WMSetLabelImagePosition(label, WIPImageOnly); - WMSetLabelImage(label, image); - WMReleasePixmap(image); - } else puts(file); - - return label; -} - - - -void -testDragAndDrop(WMScreen *scr) -{ - WMWindow *win; - WMFrame *frame; - WMLabel *label; - int i, j; - DIR *dir; - struct dirent *ent; - char *types[] = { - "application/X-WINGs-Bla", - NULL - }; - - windowCount++; - - win = WMCreateWindow(scr, "dragDrop"); - WMResizeWidget(win, 300, 300); - WMSetWindowCloseAction(win, closeAction, NULL); - WMSetWindowTitle(win, "Drag and Drop"); - - - frame = WMCreateFrame(win); - WMSetFrameRelief(frame, WRSunken); - WMResizeWidget(frame, 250, 250); - WMMoveWidget(frame, 25, 25); - - WMRegisterViewForDraggedTypes(WMWidgetView(frame), types); - WMSetViewDragDestinationProcs(WMWidgetView(frame), &dragDestProcs); - - dir = opendir("../../WindowMaker/Icons"); - if (!dir) { - perror("../../WindowMaker/Icons"); - return; - } - - for (i = 0, j=0; j < 8; i++) { - ent = readdir(dir); - if (!ent) - break; - - if (strstr(ent->d_name, ".xpm")==NULL) { - continue; - } - - label = makeDraggableLabel(frame, ent->d_name,4+(j/4)*64, 4+(j%4)*64); - - j++; - } - - closedir(dir); - - WMMapSubwidgets(frame); - - WMMapSubwidgets(win); - WMRealizeWidget(win); - WMMapWidget(win); -} - - - - - -/*******************************************************************/ - - void testUD() { @@ -1271,8 +1002,8 @@ main(int argc, char **argv) dpy = XOpenDisplay(""); if (!dpy) { - puts("could not open display"); - exit(1); + puts("could not open display"); + exit(1); } /* This is used to disable buffering of X protocol requests. @@ -1295,7 +1026,10 @@ main(int argc, char **argv) /* * Makes the logo be used in standard dialog panels. */ - WMSetApplicationIconPixmap(scr, pixmap); WMReleasePixmap(pixmap); + if (pixmap) { + WMSetApplicationIconPixmap(scr, pixmap); + WMReleasePixmap(pixmap); + } /* * Do some test stuff. @@ -1303,12 +1037,13 @@ main(int argc, char **argv) * Put the testSomething() function you want to test here. */ - testText(scr); testFontPanel(scr); + testColorPanel(scr); #if 0 + testBox(scr); testButton(scr); testColorPanel(scr); diff --git a/WINGs/WINGs/WINGs.h b/WINGs/WINGs/WINGs.h index 7e0e2ed4..f3805b04 100644 --- a/WINGs/WINGs/WINGs.h +++ b/WINGs/WINGs/WINGs.h @@ -7,7 +7,7 @@ #include #include -#define WINGS_H_VERSION 20021124 +#define WINGS_H_VERSION 20040406 #ifdef __cplusplus @@ -223,7 +223,7 @@ enum { /* drag operations */ typedef enum { - WDOperationNone, + WDOperationNone = 0, WDOperationCopy, WDOperationMove, WDOperationLink, @@ -427,33 +427,13 @@ typedef struct WMInputPanel { } WMInputPanel; - -#define WFAUnchanged (NULL) -/* Struct for font change operations */ -typedef struct WMFontAttributes { - char *foundry; - char *family; - char *weight; - char *slant; - char *setWidth; - char *addStyle; - char *pixelSize; - char *pointSize; - char *resolutionX; - char *resolutionY; - char *spacing; - char *averageWidth; - char *registry; - char *encoding; -} WMFontAttributes; - -/* A few useful constant font attributes masks */ -extern const WMFontAttributes *WFANormal; -extern const WMFontAttributes *WFABold; -extern const WMFontAttributes *WFANotBold; -extern const WMFontAttributes *WFAEmphasized; -extern const WMFontAttributes *WFANotEmphasized; -extern const WMFontAttributes *WFABoldEmphasized; +/* Basic font styles. Used to easily get one style from another */ +typedef enum WMFontStyle { + WFSNormal = 0, + WFSBold = 1, + WFSEmphasized = 2, + WFSBoldEmphasized = 3 +} WMFontStyle; /* WMRuler: */ @@ -480,11 +460,9 @@ typedef void WMAction(WMWidget *self, void *clientData); typedef void WMAction2(void *self, void *clientData); -typedef void WMDropDataCallback(WMView *view, WMData *data); - /* delegate method like stuff */ typedef void WMListDrawProc(WMList *lPtr, int index, Drawable d, char *text, - int state, WMRect *rect); + int state, WMRect *rect); /* typedef void WMSplitViewResizeSubviewsProc(WMSplitView *sPtr, @@ -493,7 +471,7 @@ typedef void WMSplitViewResizeSubviewsProc(WMSplitView *sPtr, */ typedef void WMSplitViewConstrainProc(WMSplitView *sPtr, int dividerIndex, - int *minSize, int *maxSize); + int *minSize, int *maxSize); typedef WMWidget* WMMatrixCreateCellProc(WMMatrix *mPtr); @@ -504,10 +482,10 @@ typedef struct WMBrowserDelegate { void *data; void (*createRowsForColumn)(struct WMBrowserDelegate *self, - WMBrowser *sender, int column, WMList *list); + WMBrowser *sender, int column, WMList *list); char* (*titleOfColumn)(struct WMBrowserDelegate *self, WMBrowser *sender, - int column); + int column); void (*didScroll)(struct WMBrowserDelegate *self, WMBrowser *sender); @@ -539,7 +517,7 @@ typedef struct WMTextDelegate { void *data; Bool (*didDoubleClickOnPicture)(struct WMTextDelegate *self, - void *description); + void *description); } WMTextDelegate; @@ -549,7 +527,7 @@ typedef struct WMTabViewDelegate { void *data; void (*didChangeNumberOfItems)(struct WMTabViewDelegate *self, - WMTabView *tabView); + WMTabView *tabView); void (*didSelectItem)(struct WMTabViewDelegate *self, WMTabView *tabView, WMTabViewItem *item); @@ -565,26 +543,32 @@ typedef struct WMTabViewDelegate { typedef void WMSelectionCallback(WMView *view, Atom selection, Atom target, - Time timestamp, void *cdata, WMData *data); + Time timestamp, void *cdata, WMData *data); typedef struct WMSelectionProcs { WMData* (*convertSelection)(WMView *view, Atom selection, Atom target, - void *cdata, Atom *type); + void *cdata, Atom *type); void (*selectionLost)(WMView *view, Atom selection, void *cdata); void (*selectionDone)(WMView *view, Atom selection, Atom target, - void *cdata); + void *cdata); } WMSelectionProcs; typedef struct W_DraggingInfo WMDraggingInfo; +/* links a label to a dnd operation. */ +typedef struct W_DragOperationtItem WMDragOperationItem; + + typedef struct W_DragSourceProcs { - unsigned (*draggingSourceOperation)(WMView *self, Bool local); - void (*beganDragImage)(WMView *self, WMPixmap *image, WMPoint point); - void (*endedDragImage)(WMView *self, WMPixmap *image, WMPoint point, - Bool deposited); + WMArray* (*dropDataTypes)(WMView *self); + WMDragOperationType (*wantedDropOperation)(WMView *self); + WMArray* (*askedOperations)(WMView *self); + Bool (*acceptDropOperation)(WMView *self, WMDragOperationType operation); + void (*beganDrag)(WMView *self, WMPoint *point); + void (*endedDrag)(WMView *self, WMPoint *point, Bool deposited); WMData* (*fetchDragData)(WMView *self, char *type); /* Bool (*ignoreModifierKeysWhileDragging)(WMView *view);*/ } WMDragSourceProcs; @@ -592,16 +576,19 @@ typedef struct W_DragSourceProcs { typedef struct W_DragDestinationProcs { - unsigned (*draggingEntered)(WMView *self, WMDraggingInfo *info); - unsigned (*draggingUpdated)(WMView *self, WMDraggingInfo *info); - void (*draggingExited)(WMView *self, WMDraggingInfo *info); - Bool (*prepareForDragOperation)(WMView *self, WMDraggingInfo *info); - Bool (*performDragOperation)(WMView *self, WMDraggingInfo *info); - void (*concludeDragOperation)(WMView *self, WMDraggingInfo *info); + void (*prepareForDragOperation)(WMView *self); + WMArray* (*requiredDataTypes)(WMView *self, WMDragOperationType request, + WMArray *sourceDataTypes); + WMDragOperationType (*allowedOperation)(WMView *self, + WMDragOperationType request, + WMArray *sourceDataTypes); + Bool (*inspectDropData)(WMView *self, WMArray *dropData); + void (*performDragOperation)(WMView *self, WMArray *dropData, + WMArray *operations, WMPoint *dropLocation); + void (*concludeDragOperation)(WMView *self); } WMDragDestinationProcs; - /* ...................................................................... */ @@ -707,24 +694,44 @@ extern char *WMSelectionOwnerDidChangeNotification; /* ....................................................................... */ +WMArray* WMCreateDragOperationArray(int initialSize); + +WMDragOperationItem* WMCreateDragOperationItem(WMDragOperationType type, + char* text); + +WMDragOperationType WMGetDragOperationItemType(WMDragOperationItem* item); + +char* WMGetDragOperationItemText(WMDragOperationItem* item); + +void WMSetViewDragImage(WMView* view, WMPixmap *dragImage); + +void WMReleaseViewDragImage(WMView* view); + void WMSetViewDragSourceProcs(WMView *view, WMDragSourceProcs *procs); -void WMDragImageFromView(WMView *view, WMPixmap *image, char *dataTypes[], - WMPoint atLocation, WMSize mouseOffset, XEvent *event, - Bool slideBack); +Bool WMIsDraggingFromView(WMView *view); -void WMRegisterViewForDraggedTypes(WMView *view, char *acceptedTypes[]); +void WMDragImageFromView(WMView *view, XEvent *event); -void WMUnregisterViewDraggedTypes(WMView *view); +/* Create a drag handler, associating drag event masks with dragEventProc */ +void WMCreateDragHandler(WMView *view, WMEventProc *dragEventProc, void *clientData); -void WMSetViewDragDestinationProcs(WMView *view, WMDragDestinationProcs *procs); +void WMDeleteDragHandler(WMView *view, WMEventProc *dragEventProc, void *clientData); + +/* set default drag handler for view */ +void WMSetViewDraggable(WMView *view, WMDragSourceProcs *procs, WMPixmap *dragImage); + +void WMUnsetViewDraggable(WMView *view); +void WMRegisterViewForDraggedTypes(WMView *view, WMArray *acceptedTypes); -WMPoint WMGetDraggingInfoImageLocation(WMDraggingInfo *info); +void WMUnregisterViewDraggedTypes(WMView *view); + +void WMSetViewDragDestinationProcs(WMView *view, WMDragDestinationProcs *procs); /* ....................................................................... */ -Bool WMHasAntialiasingSupport(WMScreen *scrPtr); +//Bool WMHasAntialiasingSupport(WMScreen *scrPtr); Bool WMIsAntialiasingEnabled(WMScreen *scrPtr); @@ -732,12 +739,7 @@ Bool WMIsAntialiasingEnabled(WMScreen *scrPtr); WMFont* WMCreateFont(WMScreen *scrPtr, char *fontName); -//?? -WMFont* WMCreateFontWithAttributes(WMScreen *scrPtr, char *fontName, - WMFontAttributes *attribs); - -WMFont* WMCopyFontWithChanges(WMScreen *scrPtr, WMFont *font, - const WMFontAttributes *changes); +WMFont* WMCopyFontWithStyle(WMScreen *scrPtr, WMFont *font, WMFontStyle style); WMFont* WMRetainFont(WMFont *font); @@ -766,14 +768,14 @@ WMPixmap* WMRetainPixmap(WMPixmap *pixmap); void WMReleasePixmap(WMPixmap *pixmap); WMPixmap* WMCreatePixmap(WMScreen *scrPtr, int width, int height, int depth, - Bool masked); + Bool masked); WMPixmap* WMCreatePixmapFromXPixmaps(WMScreen *scrPtr, Pixmap pixmap, - Pixmap mask, int width, int height, - int depth); + Pixmap mask, int width, int height, + int depth); WMPixmap* WMCreatePixmapFromRImage(WMScreen *scrPtr, RImage *image, - int threshold); + int threshold); WMPixmap* WMCreatePixmapFromXPMData(WMScreen *scrPtr, char **data); @@ -785,7 +787,7 @@ WMPixmap* WMCreateBlendedPixmapFromRImage(WMScreen *scrPtr, RImage *image, RColor *color); WMPixmap* WMCreateBlendedPixmapFromFile(WMScreen *scrPtr, char *fileName, - RColor *color); + RColor *color); void WMDrawPixmap(WMPixmap *pixmap, Drawable d, int x, int y); @@ -813,15 +815,15 @@ GC WMColorGC(WMColor *color); WMPixel WMColorPixel(WMColor *color); void WMPaintColorSwatch(WMColor *color, Drawable d, int x, int y, - unsigned int width, unsigned int height); + unsigned int width, unsigned int height); void WMReleaseColor(WMColor *color); WMColor* WMRetainColor(WMColor *color); WMColor* WMCreateRGBColor(WMScreen *scr, unsigned short red, - unsigned short green, unsigned short blue, - Bool exact); + unsigned short green, unsigned short blue, + Bool exact); WMColor* WMCreateRGBAColor(WMScreen *scr, unsigned short red, unsigned short green, unsigned short blue, @@ -908,7 +910,7 @@ void WMRedisplayWidget(WMWidget *w); void WMSetViewNotifySizeChanges(WMView *view, Bool flag); void WMSetViewExpandsToParent(WMView *view, int topOffs, int leftOffs, - int rightOffs, int bottomOffs); + int rightOffs, int bottomOffs); WMSize WMGetViewSize(WMView *view); @@ -952,7 +954,7 @@ WMWindow* WMCreateWindow(WMScreen *screen, char *name); WMWindow* WMCreateWindowWithStyle(WMScreen *screen, char *name, int style); WMWindow* WMCreatePanelWithStyleForWindow(WMWindow *owner, char *name, - int style); + int style); WMWindow* WMCreatePanelForWindow(WMWindow *owner, char *name); @@ -971,7 +973,7 @@ void WMSetWindowInitialPosition(WMWindow *win, int x, int y); void WMSetWindowUserPosition(WMWindow *win, int x, int y); void WMSetWindowAspectRatio(WMWindow *win, int minX, int minY, - int maxX, int maxY); + int maxX, int maxY); void WMSetWindowMaxSize(WMWindow *win, unsigned width, unsigned height); @@ -1137,7 +1139,7 @@ extern char *WMTextDidEndEditingNotification; WMScroller* WMCreateScroller(WMWidget *parent); void WMSetScrollerParameters(WMScroller *sPtr, float floatValue, - float knobProportion); + float knobProportion); float WMGetScrollerKnobProportion(WMScroller *sPtr); @@ -1276,7 +1278,7 @@ WMArray* WMGetBrowserPaths(WMBrowser *bPtr); void WMSetBrowserAction(WMBrowser *bPtr, WMAction *action, void *clientData); void WMSetBrowserDoubleAction(WMBrowser *bPtr, WMAction *action, - void *clientData); + void *clientData); WMListItem* WMGetBrowserSelectedItemInColumn(WMBrowser *bPtr, int column); @@ -1368,14 +1370,14 @@ Bool WMGetMenuItemHasSubmenu(WMMenuItem *item); WMPopUpButton* WMCreatePopUpButton(WMWidget *parent); void WMSetPopUpButtonAction(WMPopUpButton *sPtr, WMAction *action, - void *clientData); + void *clientData); void WMSetPopUpButtonPullsDown(WMPopUpButton *bPtr, Bool flag); WMMenuItem* WMAddPopUpButtonItem(WMPopUpButton *bPtr, char *title); WMMenuItem* WMInsertPopUpButtonItem(WMPopUpButton *bPtr, int index, - char *title); + char *title); void WMRemovePopUpButtonItem(WMPopUpButton *bPtr, int index); @@ -1394,7 +1396,6 @@ char* WMGetPopUpButtonItem(WMPopUpButton *bPtr, int index); WMMenuItem* WMGetPopUpButtonMenuItem(WMPopUpButton *bPtr, int index); - int WMGetPopUpButtonNumberOfItems(WMPopUpButton *bPtr); void WMSetPopUpButtonEnabled(WMPopUpButton *bPtr, Bool flag); @@ -1457,7 +1458,7 @@ extern char *WMColorWellDidChangeNotification; WMScrollView* WMCreateScrollView(WMWidget *parent); void WMResizeScrollViewContent(WMScrollView *sPtr, unsigned int width, - unsigned int height); + unsigned int height); void WMSetScrollViewHasHorizontalScroller(WMScrollView *sPtr, Bool flag); @@ -1524,8 +1525,8 @@ void WMAddSplitViewSubview(WMSplitView *sPtr, WMView *subview); void WMAdjustSplitViewSubviews(WMSplitView *sPtr); -void WMSetSplitViewConstrainProc(WMSplitView *sPtr, - WMSplitViewConstrainProc *proc); +void WMSetSplitViewConstrainProc(WMSplitView *sPtr, + WMSplitViewConstrainProc *proc); /* void WMSetSplitViewResizeSubviewsProc(WMSplitView *sPtr, @@ -1713,7 +1714,7 @@ void WMInsertItemInTabView(WMTabView *tPtr, int index, WMTabViewItem *item); void WMRemoveTabViewItem(WMTabView *tPtr, WMTabViewItem *item); WMTabViewItem* WMAddTabViewItemWithView(WMTabView *tPtr, WMView *view, - int identifier, char *label); + int identifier, char *label); WMTabViewItem* WMTabViewItemAtPoint(WMTabView *tPtr, int x, int y); @@ -1758,10 +1759,10 @@ WMBox* WMCreateBox(WMWidget *parent); void WMSetBoxBorderWidth(WMBox *box, unsigned width); void WMAddBoxSubview(WMBox *bPtr, WMView *view, Bool expand, Bool fill, - int minSize, int maxSize, int space); + int minSize, int maxSize, int space); void WMAddBoxSubviewAtEnd(WMBox *bPtr, WMView *view, Bool expand, Bool fill, - int minSize, int maxSize, int space); + int minSize, int maxSize, int space); void WMRemoveBoxSubview(WMBox *bPtr, WMView *view); @@ -1775,20 +1776,20 @@ int WMRunAlertPanel(WMScreen *app, WMWindow *owner, char *title, char *msg, /* you can free the returned string */ char* WMRunInputPanel(WMScreen *app, WMWindow *owner, char *title, char *msg, - char *defaultText, char *okButton, char *cancelButton); + char *defaultText, char *okButton, char *cancelButton); WMAlertPanel* WMCreateAlertPanel(WMScreen *app, WMWindow *owner, char *title, - char *msg, char *defaultButton, - char *alternateButton, char *otherButton); + char *msg, char *defaultButton, + char *alternateButton, char *otherButton); WMInputPanel* WMCreateInputPanel(WMScreen *app, WMWindow *owner, char *title, - char *msg, char *defaultText, char *okButton, - char *cancelButton); + char *msg, char *defaultText, char *okButton, + char *cancelButton); WMGenericPanel* WMCreateGenericPanel(WMScreen *scrPtr, WMWindow *owner, - char *title, char *defaultButton, - char *alternateButton); + char *title, char *defaultButton, + char *alternateButton); void WMDestroyAlertPanel(WMAlertPanel *panel); diff --git a/WINGs/WINGs/WINGsP.h b/WINGs/WINGs/WINGsP.h index 9585b7af..7f42ed60 100644 --- a/WINGs/WINGs/WINGsP.h +++ b/WINGs/WINGs/WINGsP.h @@ -8,7 +8,7 @@ #include -#if WINGS_H_VERSION < 20021124 +#if WINGS_H_VERSION < 20040406 #error There_is_an_old_WINGs.h_file_somewhere_in_your_system._Please_remove_it. #endif @@ -97,6 +97,53 @@ typedef struct W_FocusInfo { +typedef void* W_DndState(WMView *destView, XClientMessageEvent *event, + WMDraggingInfo *info); + + +typedef struct W_DragOperationItem { + WMDragOperationType type; + char* text; +} W_DragOperationItem; + + +typedef struct W_DragSourceInfo { + WMView *sourceView; + Window destinationWindow; + W_DndState *state; + WMSelectionProcs *selectionProcs; + Window icon; + WMPoint imageLocation; + WMPoint mouseOffset; /* mouse pos in icon */ + Cursor dragCursor; + WMRect noPositionMessageZone; + Atom firstThreeTypes[3]; +} W_DragSourceInfo; + + +typedef struct W_DragDestinationInfo { + WMView *destView; + Window sourceWindow; + W_DndState *state; + WMArray *sourceTypes; + WMArray *requiredTypes; + Bool typeListAvailable; + WMArray *dropDatas; +} W_DragDestinationInfo; + + +struct W_DraggingInfo { + unsigned char protocolVersion; + Time timestamp; + + Atom sourceAction; + Atom destinationAction; + + W_DragSourceInfo* sourceInfo; /* infos needed by source */ + W_DragDestinationInfo* destInfo; /* infos needed by destination */ +} W_DraggingInfo; + +/* original struct W_DraggingInfo { Window destinationWindow; Window sourceWindow; @@ -113,12 +160,13 @@ struct W_DraggingInfo { int protocolVersion; - /* should be treated as internal data */ + // should be treated as internal data WMView *sourceView; WMView *destView; WMSize mouseOffset; unsigned finished:1; }; +*/ typedef struct W_Screen { @@ -173,7 +221,7 @@ typedef struct W_Screen { struct W_View *dragSourceView; struct W_DraggingInfo dragInfo; - + /* colors */ W_Color *white; W_Color *black; @@ -181,12 +229,12 @@ typedef struct W_Screen { W_Color *darkGray; GC stippleGC; - + GC copyGC; GC clipGC; - + GC monoGC; /* GC for 1bpp visuals */ - + GC xorGC; GC ixorGC; /* IncludeInferiors XOR */ @@ -214,7 +262,7 @@ typedef struct W_Screen { struct W_Pixmap *checkButtonImageOn; struct W_Pixmap *checkButtonImageOff; - + struct W_Pixmap *radioButtonImageOn; struct W_Pixmap *radioButtonImageOff; @@ -222,12 +270,12 @@ typedef struct W_Screen { struct W_Pixmap *pushedButtonArrow; struct W_Pixmap *scrollerDimple; - + struct W_Pixmap *upArrow; struct W_Pixmap *downArrow; struct W_Pixmap *leftArrow; struct W_Pixmap *rightArrow; - + struct W_Pixmap *hiUpArrow; struct W_Pixmap *hiDownArrow; struct W_Pixmap *hiLeftArrow; @@ -261,19 +309,19 @@ typedef struct W_Screen { struct W_Pixmap *hsbIcon; struct W_Pixmap *customPaletteIcon; struct W_Pixmap *colorListIcon; - + struct W_Pixmap *defaultObjectIcon; Cursor defaultCursor; - + Cursor textCursor; Cursor invisibleCursor; - + Atom attribsAtom; /* GNUstepWindowAttributes */ - + Atom deleteWindowAtom; /* WM_DELETE_WINDOW */ - + Atom protocolsAtom; /* _XA_WM_PROTOCOLS */ Atom clipboardAtom; /* CLIPBOARD */ @@ -286,6 +334,8 @@ typedef struct W_Screen { Atom xdndDropAtom; Atom xdndFinishedAtom; Atom xdndTypeListAtom; + Atom xdndActionListAtom; + Atom xdndActionDescriptionAtom; Atom xdndStatusAtom; Atom xdndActionCopy; @@ -293,7 +343,7 @@ typedef struct W_Screen { Atom xdndActionLink; Atom xdndActionAsk; Atom xdndActionPrivate; - + Atom wmIconDragOffsetAtom; Atom wmStateAtom; /* WM_STATE */ @@ -335,30 +385,30 @@ typedef struct W_View { Window window; WMSize size; - + short topOffs; short leftOffs; short bottomOffs; short rightOffs; WMPoint pos; - + struct W_View *nextFocusChain; /* next/prev in focus chain */ struct W_View *prevFocusChain; - + struct W_View *nextResponder; /* next to receive keyboard events */ - + struct W_View *parent; /* parent WMView */ - + struct W_View *childrenList; /* first in list of child windows */ - + struct W_View *nextSister; /* next on parent's children list */ - + WMArray *eventHandlers; /* event handlers for this window */ unsigned long attribFlags; XSetWindowAttributes attribs; - + void *hangedData; /* data holder for user program */ WMColor *backColor; @@ -366,35 +416,36 @@ typedef struct W_View { Cursor cursor; Atom *droppableTypes; - struct W_DragSourceProcs *dragSourceProcs; + struct W_DragSourceProcs *dragSourceProcs; struct W_DragDestinationProcs *dragDestinationProcs; + WMPixmap *dragImage; int helpContext; struct { - unsigned int realized:1; - unsigned int mapped:1; - unsigned int parentDying:1; - unsigned int dying:1; /* the view is being destroyed */ - unsigned int topLevel:1; /* is a top level window */ - unsigned int root:1; /* is the root window */ - unsigned int mapWhenRealized:1;/* map the view when it's realized */ - unsigned int alreadyDead:1; /* view was freed */ - - unsigned int dontCompressMotion:1; /* motion notify event compress */ - unsigned int notifySizeChanged:1; - unsigned int dontCompressExpose:1; /* will compress all expose - events into one */ - /* toplevel only */ - unsigned int worksWhenModal:1; - unsigned int pendingRelease1:1; - unsigned int pendingRelease2:1; - unsigned int pendingRelease3:1; - unsigned int pendingRelease4:1; - unsigned int pendingRelease5:1; - unsigned int xdndHintSet:1; + unsigned int realized:1; + unsigned int mapped:1; + unsigned int parentDying:1; + unsigned int dying:1; /* the view is being destroyed */ + unsigned int topLevel:1; /* is a top level window */ + unsigned int root:1; /* is the root window */ + unsigned int mapWhenRealized:1; /* map the view when it's realized */ + unsigned int alreadyDead:1; /* view was freed */ + + unsigned int dontCompressMotion:1; /* motion notify event compress */ + unsigned int notifySizeChanged:1; + unsigned int dontCompressExpose:1; /* expose event compress */ + + /* toplevel only */ + unsigned int worksWhenModal:1; + unsigned int pendingRelease1:1; + unsigned int pendingRelease2:1; + unsigned int pendingRelease3:1; + unsigned int pendingRelease4:1; + unsigned int pendingRelease5:1; + unsigned int xdndHintSet:1; } flags; - + int refCount; } W_View; @@ -434,7 +485,7 @@ extern _WINGsConfiguration WINGsConfiguration; #define W_VIEW_REALIZED(view) (view)->flags.realized #define W_VIEW_MAPPED(view) (view)->flags.mapped - + #define W_VIEW_DISPLAY(view) (view)->screen->display #define W_VIEW_SCREEN(view) (view)->screen #define W_VIEW_DRAWABLE(view) (view)->window @@ -492,19 +543,19 @@ void W_SetViewBackgroundColor(W_View *view, WMColor *color); void W_SetViewCursor(W_View *view, Cursor cursor); void W_DrawRelief(W_Screen *scr, Drawable d, int x, int y, unsigned int width, - unsigned int height, WMReliefType relief); + unsigned int height, WMReliefType relief); void W_DrawReliefWithGC(W_Screen *scr, Drawable d, int x, int y, - unsigned int width, unsigned int height, - WMReliefType relief, - GC black, GC dark, GC light, GC white); + unsigned int width, unsigned int height, + WMReliefType relief, + GC black, GC dark, GC light, GC white); void W_CallDestroyHandlers(W_View *view); void W_PaintTextAndImage(W_View *view, int wrap, WMColor *textColor, W_Font *font, WMReliefType relief, char *text, - WMAlignment alignment, W_Pixmap *image, - WMImagePosition position, WMColor *backColor, int ofs); + WMAlignment alignment, W_Pixmap *image, + WMImagePosition position, WMColor *backColor, int ofs); void W_PaintText(W_View *view, Drawable d, WMFont *font, int x, int y, int width, WMAlignment alignment, WMColor *color, @@ -525,7 +576,7 @@ void W_SetFocusOfToplevel(W_View *toplevel, W_View *view); W_View *W_FocusedViewOfToplevel(W_View *view); void W_SetFocusOfTopLevel(W_View *toplevel, W_View *view); - + void W_ReleaseView(WMView *view); WMView *W_RetainView(WMView *view); @@ -560,6 +611,44 @@ void W_CheckTimerHandlers(void); Bool W_HandleInputEvents(Bool waitForInput, int inputfd); +/* XDnD */ +Atom W_OperationToAction(WMScreen *scr, WMDragOperationType operation); + +WMDragOperationType W_ActionToOperation(WMScreen *scr, Atom action); + +void W_FreeDragOperationItem(void* item); + +Bool W_SendDnDClientMessage(Display *dpy, Window win, Atom message, + unsigned long data1, unsigned long data2, + unsigned long data3, unsigned long data4, + unsigned long data5); + +void W_DragSourceStartTimer(WMDraggingInfo *info); + +void W_DragSourceStopTimer(); + +void W_DragSourceStateHandler(WMDraggingInfo *info, XClientMessageEvent *event); + +void W_DragDestinationStartTimer(WMDraggingInfo *info); + +void W_DragDestinationStopTimer(); + +void W_DragDestinationStoreEnterMsgInfo(WMDraggingInfo *info, WMView *toplevel, + XClientMessageEvent *event); + +void W_DragDestinationStorePositionMsgInfo(WMDraggingInfo *info, + WMView *toplevel, + XClientMessageEvent *event); + +void W_DragDestinationCancelDropOnEnter(WMView *toplevel, WMDraggingInfo *info); + +void W_DragDestinationStateHandler(WMDraggingInfo *info, + XClientMessageEvent *event); + +void W_DragDestinationInfoClear(WMDraggingInfo *info); + +void W_FreeViewXdndPart(WMView *view); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/WINGs/configuration.c b/WINGs/configuration.c index c03973e3..0baf60bf 100644 --- a/WINGs/configuration.c +++ b/WINGs/configuration.c @@ -98,48 +98,48 @@ W_ReadConfigurations(void) if (defaults) { char *buttonName; unsigned button; - char *str; + char *str; - WINGsConfiguration.systemFont = - WMGetUDStringForKey(defaults, "SystemFont"); + WINGsConfiguration.systemFont = + WMGetUDStringForKey(defaults, "SystemFont"); - WINGsConfiguration.boldSystemFont = - WMGetUDStringForKey(defaults, "BoldSystemFont"); + WINGsConfiguration.boldSystemFont = + WMGetUDStringForKey(defaults, "BoldSystemFont"); #ifdef XFT - WINGsConfiguration.antialiasedText = + WINGsConfiguration.antialiasedText = WMGetUDBoolForKey(defaults, "AntialiasedText"); #else WINGsConfiguration.antialiasedText = False; #endif - WINGsConfiguration.useMultiByte = False; - str = WMGetUDStringForKey(defaults, "MultiByteText"); - if (str) { - if (strcasecmp(str, "YES") == 0) { - WINGsConfiguration.useMultiByte = True; - } else if (strcasecmp(str, "AUTO") == 0) { - char *locale; - - /* if it's a multibyte language (japanese, chinese or korean) - * then set it to True */ - locale = setlocale(LC_CTYPE, NULL); - if (locale != NULL - && (strncmp(locale, "ja", 2) == 0 - || strncmp(locale, "zh", 2) == 0 - || strncmp(locale, "ru", 2) == 0 - || strncmp(locale, "ko", 2) == 0)) { - - WINGsConfiguration.useMultiByte = True; - } - } - } - - WINGsConfiguration.doubleClickDelay = - WMGetUDIntegerForKey(defaults, "DoubleClickTime"); - - WINGsConfiguration.floppyPath = - WMGetUDStringForKey(defaults, "FloppyPath"); + WINGsConfiguration.useMultiByte = False; + str = WMGetUDStringForKey(defaults, "MultiByteText"); + if (str) { + if (strcasecmp(str, "YES") == 0) { + WINGsConfiguration.useMultiByte = True; + } else if (strcasecmp(str, "AUTO") == 0) { + char *locale; + + /* if it's a multibyte language (japanese, chinese or korean) + * then set it to True */ + locale = setlocale(LC_CTYPE, NULL); + if (locale != NULL + && (strncmp(locale, "ja", 2) == 0 + || strncmp(locale, "zh", 2) == 0 + || strncmp(locale, "ru", 2) == 0 + || strncmp(locale, "ko", 2) == 0)) { + + WINGsConfiguration.useMultiByte = True; + } + } + } + + WINGsConfiguration.doubleClickDelay = + WMGetUDIntegerForKey(defaults, "DoubleClickTime"); + + WINGsConfiguration.floppyPath = + WMGetUDStringForKey(defaults, "FloppyPath"); buttonName = WMGetUDStringForKey(defaults, "MouseWheelUp"); if (buttonName) { @@ -164,7 +164,7 @@ W_ReadConfigurations(void) WINGsConfiguration.mouseWheelDown = Button5; } - WINGsConfiguration.defaultFontSize = + WINGsConfiguration.defaultFontSize = WMGetUDIntegerForKey(defaults, "DefaultFontSize"); } @@ -172,22 +172,22 @@ W_ReadConfigurations(void) WINGsConfiguration.systemFont = SYSTEM_FONT; } if (missingOrInvalidXLFD(WINGsConfiguration.boldSystemFont)) { - WINGsConfiguration.boldSystemFont = BOLD_SYSTEM_FONT; + WINGsConfiguration.boldSystemFont = BOLD_SYSTEM_FONT; } if (!WINGsConfiguration.floppyPath) { - WINGsConfiguration.floppyPath = FLOPPY_PATH; + WINGsConfiguration.floppyPath = FLOPPY_PATH; } if (WINGsConfiguration.doubleClickDelay == 0) { - WINGsConfiguration.doubleClickDelay = 250; + WINGsConfiguration.doubleClickDelay = 250; } if (WINGsConfiguration.mouseWheelUp == 0) { - WINGsConfiguration.mouseWheelUp = Button4; + WINGsConfiguration.mouseWheelUp = Button4; } if (WINGsConfiguration.mouseWheelDown == 0) { - WINGsConfiguration.mouseWheelDown = Button5; + WINGsConfiguration.mouseWheelDown = Button5; } if (WINGsConfiguration.defaultFontSize == 0) { - WINGsConfiguration.defaultFontSize = 12; + WINGsConfiguration.defaultFontSize = 12; } } diff --git a/WINGs/dragdestination.c b/WINGs/dragdestination.c dissimilarity index 73% index f7b209a1..e982dacf 100644 --- a/WINGs/dragdestination.c +++ b/WINGs/dragdestination.c @@ -1,226 +1,1160 @@ - - -#include - -#include "WINGsP.h" - - -/* dropping */ - -typedef struct W_DNDTargetInfo { - /* data types accepted for drops */ - Atom *dropTypes; - int dropTypeCount; - - -} DNDTargetInfo; - - -static Atom XDNDversion = XDND_VERSION; - - -static void -realizedObserver(void *self, WMNotification *notif) -{ - WMView *view = (WMView*)WMGetNotificationObject(notif); - - XChangeProperty(W_VIEW_SCREEN(view)->display, W_VIEW_DRAWABLE(view), - W_VIEW_SCREEN(view)->xdndAwareAtom, - XA_ATOM, 32, PropModeReplace, - (unsigned char*)&XDNDversion, 1); - - WMRemoveNotificationObserver(self); -} - - -void -W_SetXdndAwareProperty(WMScreen *scr, WMView *view, Atom *types, int typeCount) -{ - Display *dpy = scr->display; - - view = W_TopLevelOfView(view); - - if (!view->flags.xdndHintSet) { - view->flags.xdndHintSet = 1; - - if (view->flags.realized) { - XChangeProperty(dpy, W_VIEW_DRAWABLE(view), scr->xdndAwareAtom, - XA_ATOM, 32, PropModeReplace, - (unsigned char*)&XDNDversion, 1); - } else { - WMAddNotificationObserver(realizedObserver, - /* just use as an id */ - &view->dragDestinationProcs, - WMViewRealizedNotification, - view); - } - } -} - - - -void -WMRegisterViewForDraggedTypes(WMView *view, char *acceptedTypes[]) -{ - Atom *types; - int typeCount; - int i; - - typeCount = 0; - while (acceptedTypes[typeCount++]); - - types = wmalloc(sizeof(Atom)*(typeCount+1)); - - for (i = 0; i < typeCount; i++) { - types[i] = XInternAtom(W_VIEW_SCREEN(view)->display, - acceptedTypes[i], False); - } - types[i] = 0; - - view->droppableTypes = types; - - W_SetXdndAwareProperty(W_VIEW_SCREEN(view), view, types, typeCount); -} - - -void -WMUnregisterViewDraggedTypes(WMView *view) -{ - if (view->droppableTypes != NULL) - wfree(view->droppableTypes); - view->droppableTypes = NULL; -} - -/***********************************************************************/ - - -static unsigned -defDraggingEntered(WMView *self, WMDraggingInfo *info) -{ - printf("%x drag entered\n", W_VIEW_DRAWABLE(self)); - return WDOperationNone; -} - -static unsigned -defDraggingUpdated(WMView *self, WMDraggingInfo *info) -{ - printf("%x drag update\n", W_VIEW_DRAWABLE(self)); - return WDOperationNone; -} - -static void -defDraggingExited(WMView *self, WMDraggingInfo *info) -{ - printf("%x drag exit\n", W_VIEW_DRAWABLE(self)); -} - -static Bool -defPrepareForDragOperation(WMView *self, WMDraggingInfo *info) -{ - printf("%x drag prepare\n", W_VIEW_DRAWABLE(self)); - return False; -} - -static Bool -defPerformDragOperation(WMView *self, WMDraggingInfo *info) -{ - printf("%x drag perform\n", W_VIEW_DRAWABLE(self)); - return False; -} - -static void -defConcludeDragOperation(WMView *self, WMDraggingInfo *info) -{ - printf("%x drag conclude\n", W_VIEW_DRAWABLE(self)); -} - - - -void -WMSetViewDragDestinationProcs(WMView *view, WMDragDestinationProcs *procs) -{ - if (view->dragDestinationProcs == NULL) { - view->dragDestinationProcs = wmalloc(sizeof(WMDragDestinationProcs)); - } else { - free(view->dragDestinationProcs); - } - *view->dragDestinationProcs = *procs; - - /*XXX fill in non-implemented stuffs */ - if (procs->draggingEntered == NULL) { - view->dragDestinationProcs->draggingEntered = defDraggingEntered; - } - if (procs->draggingUpdated == NULL) { - view->dragDestinationProcs->draggingUpdated = defDraggingUpdated; - } - if (procs->draggingExited == NULL) { - view->dragDestinationProcs->draggingExited = defDraggingExited; - } - if (procs->prepareForDragOperation == NULL) { - view->dragDestinationProcs->prepareForDragOperation = - defPrepareForDragOperation; - } - if (procs->performDragOperation == NULL) { - view->dragDestinationProcs->performDragOperation = - defPerformDragOperation; - } - if (procs->concludeDragOperation == NULL) { - view->dragDestinationProcs->concludeDragOperation = - defConcludeDragOperation; - } -} - - - -WMPoint -WMGetDraggingInfoImageLocation(WMDraggingInfo *info) -{ - return info->imageLocation; -} - - - -static void -receivedData(WMView *view, Atom selection, Atom target, Time timestamp, - void *cdata, WMData *data) -{ - -} - - - -Bool -WMRequestDroppedData(WMView *view, WMDraggingInfo *info, char *type, - WMDropDataCallback *callback) -{ -#if 0 - WMScreen *scr = W_VIEW_SCREEN(view); - if (info->finished) { - return False; - } - - if (type != NULL) { - if (!WMRequestSelection(scr->dragInfo.destView, - scr->xdndSelectionAtom, - XInternAtom(scr->display, type, False), - scr->dragInfo.timestamp, - receivedData, &scr->dragInfo)) { - wwarning("could not request data for dropped data"); - - /* send finished message */ - sendClientMessage(scr->display, source, - scr->xdndFinishedAtom, - scr->dragInfo.destinationWindow, - 0, 0, 0, 0); - } - } else { - /* send finished message */ - sendClientMessage(scr->display, source, - scr->xdndFinishedAtom, - scr->dragInfo.destinationWindow, - 0, 0, 0, 0); - } -#endif -} - - +#include +#include "WINGsP.h" + +#define XDND_SOURCE_RESPONSE_MAX_DELAY 3000 + +#define VERSION_INFO(dragInfo) dragInfo->protocolVersion + +#define XDND_PROPERTY_FORMAT 32 +#define XDND_ACTION_DESCRIPTION_FORMAT 8 + +#define XDND_DEST_INFO(dragInfo) dragInfo->destInfo +#define XDND_SOURCE_WIN(dragInfo) dragInfo->destInfo->sourceWindow +#define XDND_DEST_VIEW(dragInfo) dragInfo->destInfo->destView +#define XDND_DEST_STATE(dragInfo) dragInfo->destInfo->state +#define XDND_SOURCE_TYPES(dragInfo) dragInfo->destInfo->sourceTypes +#define XDND_TYPE_LIST_AVAILABLE(dragInfo) dragInfo->destInfo->typeListAvailable +#define XDND_REQUIRED_TYPES(dragInfo) dragInfo->destInfo->requiredTypes +#define XDND_SOURCE_ACTION(dragInfo) dragInfo->sourceAction +#define XDND_DEST_ACTION(dragInfo) dragInfo->destinationAction +#define XDND_SOURCE_OPERATIONS(dragInfo) dragInfo->destInfo->sourceOperations +#define XDND_DROP_DATAS(dragInfo) dragInfo->destInfo->dropDatas +#define XDND_DROP_DATA_COUNT(dragInfo) dragInfo->destInfo->dropDataCount +#define XDND_DEST_VIEW_STORED(dragInfo) ((dragInfo->destInfo) != NULL)\ + && ((dragInfo->destInfo->destView) != NULL) + + +static unsigned char XDNDversion = XDND_VERSION; +static WMHandlerID dndDestinationTimer = NULL; + + +static void* idleState(WMView *destView, XClientMessageEvent *event, + WMDraggingInfo *info); +static void* waitEnterState(WMView *destView, XClientMessageEvent *event, + WMDraggingInfo *info); +static void* inspectDropDataState(WMView *destView, XClientMessageEvent *event, + WMDraggingInfo *info); +static void* dropAllowedState(WMView *destView, XClientMessageEvent *event, + WMDraggingInfo *info); +static void* dropNotAllowedState(WMView *destView, XClientMessageEvent *event, + WMDraggingInfo *info); +static void* waitForDropDataState(WMView *destView, XClientMessageEvent *event, + WMDraggingInfo *info); + +/* ----- Types & datas list ----- */ +static void +freeSourceTypeArrayItem(void *type) +{ + XFree(type); +} + + +static WMArray* +createSourceTypeArray(int initialSize) +{ + return WMCreateArrayWithDestructor(initialSize, freeSourceTypeArrayItem); +} + + +static void +freeDropDataArrayItem(void* data) +{ + if (data != NULL) + WMReleaseData((WMData*) data); +} + + +static WMArray* +createDropDataArray(WMArray *requiredTypes) +{ + if (requiredTypes != NULL) + return WMCreateArrayWithDestructor( + WMGetArrayItemCount(requiredTypes), + freeDropDataArrayItem); + + else + return WMCreateArray(0); +} + +static WMArray* +getTypesFromTypeList(WMScreen *scr, Window sourceWin) +{ + WMDraggingInfo *info = &scr->dragInfo; + Atom dataType; + Atom* typeAtomList; + WMArray* typeList; + int i, format; + unsigned long count, remaining; + unsigned char *data = NULL; + + XGetWindowProperty(scr->display, sourceWin, scr->xdndTypeListAtom, + 0, 0x8000000L, False, XA_ATOM, &dataType, &format, + &count, &remaining, &data); + + if (dataType!=XA_ATOM || format!=XDND_PROPERTY_FORMAT || count==0 || !data) { + if (data) { + XFree(data); + } + return createSourceTypeArray(0); + } + + typeList = createSourceTypeArray(count); + typeAtomList = (Atom*) data; + for (i=0; i < count; i++) { + WMAddToArray(typeList, XGetAtomName(scr->display, typeAtomList[i])); + } + + XFree(data); + + return typeList; +} + + +static WMArray* +getTypesFromThreeTypes(WMScreen *scr, XClientMessageEvent *event) +{ + WMArray* typeList; + Atom atom; + int i; + + typeList = createSourceTypeArray(3); + for (i = 2; i < 5; i++) { + if (event->data.l[i] != None) { + atom = (Atom)event->data.l[i]; + WMAddToArray(typeList, XGetAtomName(scr->display, atom)); + } + } + + return typeList; +} + + +void +storeRequiredTypeList(WMDraggingInfo *info) +{ + WMView *destView = XDND_DEST_VIEW(info); + WMScreen *scr = W_VIEW_SCREEN(destView); + WMArray *requiredTypes; + + /* First, see if the 3 source types are enough for dest requirements */ + requiredTypes = destView->dragDestinationProcs->requiredDataTypes( + destView, + W_ActionToOperation(scr, XDND_SOURCE_ACTION(info)), + XDND_SOURCE_TYPES(info)); + + if (requiredTypes == NULL && XDND_TYPE_LIST_AVAILABLE(info)) { + /* None of the 3 source types fits, get the whole type list */ + requiredTypes = + destView->dragDestinationProcs->requiredDataTypes( + destView, + W_ActionToOperation(scr, XDND_SOURCE_ACTION(info)), + getTypesFromTypeList(scr, XDND_SOURCE_WIN(info))); + } + + + XDND_REQUIRED_TYPES(info) = requiredTypes; +} + + +char* +getNextRequestedDataType(WMDraggingInfo *info) +{ + /* get the type of the first data not yet retrieved from selection */ + int nextTypeIndex; + + if (XDND_REQUIRED_TYPES(info) != NULL) { + nextTypeIndex = WMGetArrayItemCount(XDND_DROP_DATAS(info)); + return WMGetFromArray(XDND_REQUIRED_TYPES(info), nextTypeIndex); + /* NULL if no more type */ + } else + return NULL; +} + + +/* ----- Action list ----- */ + +WMArray* +sourceOperationList(WMScreen *scr, Window sourceWin) +{ + Atom dataType, *actionList; + int i, size; + unsigned long count, remaining; + unsigned char* actionDatas = NULL; + unsigned char* descriptionList = NULL; + WMArray* operationArray; + WMDragOperationItem* operationItem; + char* description; + + remaining = 0; + XGetWindowProperty(scr->display, sourceWin, scr->xdndActionListAtom, + 0, 0x8000000L, False, XA_ATOM, &dataType, &size, + &count, &remaining, &actionDatas); + + if (dataType!=XA_ATOM || size!=XDND_PROPERTY_FORMAT || count==0 || !actionDatas) { + wwarning("Cannot read action list"); + if (actionDatas) { + XFree(actionDatas); + } + return NULL; + } + + actionList = (Atom*)actionDatas; + + XGetWindowProperty(scr->display, sourceWin, scr->xdndActionDescriptionAtom, + 0, 0x8000000L, False, XA_STRING, &dataType, &size, + &count, &remaining, &descriptionList); + + if (dataType!=XA_STRING || size!=XDND_ACTION_DESCRIPTION_FORMAT || + count==0 || !descriptionList) { + wwarning("Cannot read action description list"); + if (actionList) { + XFree(actionList); + } + if (descriptionList) { + XFree(descriptionList); + } + return NULL; + } + + operationArray = WMCreateDragOperationArray(count); + description = descriptionList; + + for (i=0; count > 0; i++) { + size = strlen(description); + operationItem = WMCreateDragOperationItem( + W_ActionToOperation(scr, actionList[i]), + wstrdup(description)); + + WMAddToArray(operationArray, operationItem); + count -= (size + 1); /* -1 : -NULL char */ + + /* next description */ + description = &(description[size + 1]); + } + + XFree(actionList); + XFree(descriptionList); + + return operationArray; +} + + +/* ----- Dragging Info ----- */ +static void +updateSourceWindow(WMDraggingInfo *info, XClientMessageEvent *event) +{ + XDND_SOURCE_WIN(info) = (Window) event->data.l[0]; +} + + +static Window +findChildInWindow(Display *dpy, Window toplevel, int x, int y) +{ + Window foo, bar; + Window *children; + unsigned nchildren; + int i; + + if (!XQueryTree(dpy, toplevel, &foo, &bar, + &children, &nchildren) || children == NULL) { + return None; + } + + /* first window that contains the point is the one */ + for (i = nchildren-1; i >= 0; i--) { + XWindowAttributes attr; + + if (XGetWindowAttributes(dpy, children[i], &attr) + && attr.map_state == IsViewable + && x >= attr.x && y >= attr.y + && x < attr.x + attr.width && y < attr.y + attr.height) { + Window child, tmp; + + tmp = children[i]; + child = findChildInWindow(dpy, tmp, x - attr.x, y - attr.y); + XFree(children); + + if (child == None) + return tmp; + else + return child; + } + } + + XFree(children); + return None; +} + + +static WMView* +findXdndViewInToplevel(WMView* toplevel, int x, int y) +{ + WMScreen *scr = W_VIEW_SCREEN(toplevel); + Window toplevelWin = WMViewXID(toplevel); + int xInToplevel, yInToplevel; + Window child, foo; + WMView *childView; + + XTranslateCoordinates(scr->display, scr->rootWin, toplevelWin, + x, y, &xInToplevel, &yInToplevel, + &foo); + + child = findChildInWindow(scr->display, toplevelWin, + xInToplevel, yInToplevel); + + if (child != None) { + childView = W_GetViewForXWindow(scr->display, child); + + /* if childView supports Xdnd, return childView */ + if (childView != NULL + && childView->dragDestinationProcs != NULL) + return childView; + } + + return NULL; +} + + +/* Clear datas only used by current destination view */ +static void +freeDestinationViewInfos(WMDraggingInfo *info) +{ + if (XDND_SOURCE_TYPES(info) != NULL) { + WMFreeArray(XDND_SOURCE_TYPES(info)); + XDND_SOURCE_TYPES(info) = NULL; + } + + if (XDND_DROP_DATAS(info) != NULL) { + WMFreeArray(XDND_DROP_DATAS(info)); + XDND_DROP_DATAS(info) = NULL; + } + + XDND_REQUIRED_TYPES(info) = NULL; +} + +void +W_DragDestinationInfoClear(WMDraggingInfo *info) +{ + W_DragDestinationStopTimer(); + + if (XDND_DEST_INFO(info) != NULL) { + freeDestinationViewInfos(info); + + wfree(XDND_DEST_INFO(info)); + XDND_DEST_INFO(info) = NULL; + } +} + +static void +initDestinationDragInfo(WMDraggingInfo *info) +{ + XDND_DEST_INFO(info) = + (W_DragDestinationInfo*) wmalloc(sizeof(W_DragDestinationInfo)); + + XDND_DEST_STATE(info) = idleState; + XDND_DEST_VIEW(info) = NULL; + + XDND_SOURCE_TYPES(info) = NULL; + XDND_REQUIRED_TYPES(info) = NULL; + XDND_DROP_DATAS(info) = NULL; +} + + +void +W_DragDestinationStoreEnterMsgInfo(WMDraggingInfo *info, + WMView *toplevel, XClientMessageEvent *event) +{ + WMScreen *scr = W_VIEW_SCREEN(toplevel); + int i,j, typesCount; + + if (XDND_DEST_INFO(info) == NULL) + initDestinationDragInfo(info); + + updateSourceWindow(info, event); + + /* store xdnd version for source */ + info->protocolVersion = (event->data.l[1] >> 24); + + XDND_SOURCE_TYPES(info) = getTypesFromThreeTypes(scr, event); + + /* to use if the 3 types are not enough */ + XDND_TYPE_LIST_AVAILABLE(info) = (event->data.l[1] & 1); +} + + +static void +cancelDrop(WMView *destView, WMDraggingInfo *info); + +static void +suspendDropAuthorization(WMView *destView, WMDraggingInfo *info); + + +void + W_DragDestinationStorePositionMsgInfo(WMDraggingInfo *info, + WMView *toplevel, XClientMessageEvent *event) +{ + int x = event->data.l[2] >> 16; + int y = event->data.l[2] & 0xffff; + WMView *oldDestView; + WMView *newDestView; + + newDestView = findXdndViewInToplevel(toplevel, x, y); + + if (XDND_DEST_INFO(info) == NULL) { + initDestinationDragInfo(info); + updateSourceWindow(info, event); + XDND_DEST_VIEW(info) = newDestView; + } + else { + oldDestView = XDND_DEST_VIEW(info); + + if (newDestView != oldDestView) { + if (oldDestView != NULL) { + suspendDropAuthorization(oldDestView, info); + XDND_DEST_STATE(info) = dropNotAllowedState; + } + + updateSourceWindow(info, event); + XDND_DEST_VIEW(info) = newDestView; + + if (newDestView != NULL) { + if (XDND_DEST_STATE(info) != waitEnterState) + XDND_DEST_STATE(info) = idleState; + } + } + } + + XDND_SOURCE_ACTION(info) = event->data.l[4]; + + /* note: source position is not stored */ +} + +/* ----- End of Dragging Info ----- */ + + +/* ----- Messages ----- */ + +/* send a DnD message to the source window */ +static void +sendDnDClientMessage(WMView *destView, Atom message, + unsigned long data1, + unsigned long data2, + unsigned long data3, + unsigned long data4) +{ + WMScreen *scr = W_VIEW_SCREEN(destView); + WMDraggingInfo *info = &scr->dragInfo; + + if (XDND_DEST_INFO(info) != NULL) { + if (! W_SendDnDClientMessage(scr->display, + XDND_SOURCE_WIN(info), + message, + WMViewXID(destView), + data1, + data2, + data3, + data4)) { + /* drop failed */ + W_DragDestinationInfoClear(info); + } + } +} + + +static void +storeDropData(WMView *destView, Atom selection, Atom target, + Time timestamp, void *cdata, WMData *data) +{ + WMScreen *scr = W_VIEW_SCREEN(destView); + WMDraggingInfo *info = &(scr->dragInfo); + WMData *dataToStore = NULL; + + if (data != NULL) + dataToStore = WMRetainData(data); + + if (XDND_DEST_INFO(info) != NULL && XDND_DROP_DATAS(info) != NULL) { + WMAddToArray(XDND_DROP_DATAS(info), dataToStore); + W_SendDnDClientMessage(scr->display, WMViewXID(destView), + scr->xdndSelectionAtom, + WMViewXID(destView), + 0, 0, 0, 0); + } +} + + +Bool +requestDropDataInSelection(WMView *destView, char* type) +{ + WMScreen *scr = W_VIEW_SCREEN(destView); + + if (type != NULL) { + if (!WMRequestSelection(destView, + scr->xdndSelectionAtom, + XInternAtom(scr->display, type, False), + CurrentTime, + storeDropData, NULL)) { + wwarning("could not request data for dropped data"); + return False; + } + + return True; + } + + return False; +} + + +Bool +requestDropData(WMDraggingInfo *info) +{ + WMView *destView = XDND_DEST_VIEW(info); + char* nextType = getNextRequestedDataType(info); + + while ((nextType != NULL) + && (!requestDropDataInSelection(destView, nextType)) ) { + /* store NULL if request failed, and try with next type */ + WMAddToArray(XDND_DROP_DATAS(info), NULL); + nextType = getNextRequestedDataType(info); + } + + /* remains types to retrieve ? */ + return (nextType != NULL); +} + + +static void +concludeDrop(WMView *destView) +{ + destView->dragDestinationProcs->concludeDragOperation(destView); +} + + +/* send cancel message to the source */ +static void +cancelDrop(WMView *destView, WMDraggingInfo *info) +{ + /* send XdndStatus with action None */ + sendDnDClientMessage(destView, + W_VIEW_SCREEN(destView)->xdndStatusAtom, + 0, 0, 0, None); + concludeDrop(destView); + freeDestinationViewInfos(info); +} + + +/* suspend drop, when dragged icon enter an unaware subview of destView */ +static void +suspendDropAuthorization(WMView *destView, WMDraggingInfo *info) +{ + /* free datas that depend on destination behaviour */ + /* (in short: only keep source's types) */ + if (XDND_DROP_DATAS(info) != NULL) { + WMFreeArray(XDND_DROP_DATAS(info)); + XDND_DROP_DATAS(info) = NULL; + } + XDND_REQUIRED_TYPES(info) = NULL; + + /* send XdndStatus with action None */ + sendDnDClientMessage(destView, + W_VIEW_SCREEN(destView)->xdndStatusAtom, + 0, 0, 0, None); +} + + +/* cancel drop on Enter message, if protocol version is nok */ +void +W_DragDestinationCancelDropOnEnter(WMView *toplevel, WMDraggingInfo *info) +{ + if (XDND_DEST_VIEW_STORED(info)) + cancelDrop(XDND_DEST_VIEW(info), info); + else { + /* send XdndStatus with action None */ + sendDnDClientMessage(toplevel, + W_VIEW_SCREEN(toplevel)->xdndStatusAtom, + 0, 0, 0, None); + } + + W_DragDestinationInfoClear(info); +} + + +static void +finishDrop(WMView *destView, WMDraggingInfo *info) +{ + sendDnDClientMessage(destView, + W_VIEW_SCREEN(destView)->xdndFinishedAtom, + 0, 0, 0, 0); + concludeDrop(destView); + W_DragDestinationInfoClear(info); +} + + +static Atom +getAllowedAction(WMView *destView, WMDraggingInfo *info) +{ + WMScreen *scr = W_VIEW_SCREEN(destView); + + return W_OperationToAction(scr, + destView->dragDestinationProcs->allowedOperation( + destView, + W_ActionToOperation(scr, XDND_SOURCE_ACTION(info)), + XDND_SOURCE_TYPES(info))); +} + + +/* send the action that can be performed, + and the limits outside wich the source must re-send + its position and action */ +static void +sendAllowedAction(WMView *destView, Atom action) +{ + WMScreen *scr = W_VIEW_SCREEN(destView); + WMPoint destPos = WMGetViewScreenPosition(destView); + WMSize destSize = WMGetViewSize(destView); + int destX, destY; + Window foo; + + XTranslateCoordinates(scr->display, scr->rootWin, WMViewXID(destView), + 0, 0, &destX, &destY, + &foo); + + sendDnDClientMessage(destView, + scr->xdndStatusAtom, + 1, + (destX << 16)|destY, + (destSize.width << 16)|destSize.height, + action); +} + + +static void* +checkActionAllowed(WMView *destView, WMDraggingInfo* info) +{ + XDND_DEST_ACTION(info) = + getAllowedAction(destView, info); + + if (XDND_DEST_ACTION(info) == None) { + suspendDropAuthorization(destView, info); + return dropNotAllowedState; + } + + sendAllowedAction(destView, XDND_DEST_ACTION(info)); + return dropAllowedState; +} + +static void* +checkDropAllowed(WMView *destView, XClientMessageEvent *event, + WMDraggingInfo* info) +{ + storeRequiredTypeList(info); + + if (destView->dragDestinationProcs->inspectDropData != NULL) { + XDND_DROP_DATAS(info) = createDropDataArray( + XDND_REQUIRED_TYPES(info)); + + /* store first available data */ + if (requestDropData(info)) + return inspectDropDataState; + + /* no data retrieved, but inspect can allow it */ + if (destView->dragDestinationProcs->inspectDropData( + destView, + XDND_DROP_DATAS(info))) + return checkActionAllowed(destView, info); + + suspendDropAuthorization(destView, info); + return dropNotAllowedState; + } + + return checkActionAllowed(destView, info); +} + +static WMPoint* +getDropLocationInView(WMView *view) +{ + Window rootWin, childWin; + int rootX, rootY; + unsigned int mask; + WMPoint* location; + + location = (WMPoint*) wmalloc(sizeof(WMPoint)); + + XQueryPointer( + W_VIEW_SCREEN(view)->display, + WMViewXID(view), &rootWin, &childWin, + &rootX, &rootY, + &(location->x), &(location->y), + &mask); + + return location; +} + +static void +callPerformDragOperation(WMView *destView, WMDraggingInfo *info) +{ + WMArray *operationList = NULL; + WMScreen *scr = W_VIEW_SCREEN(destView); + WMPoint* dropLocation; + + if (XDND_SOURCE_ACTION(info) == scr->xdndActionAsk) + operationList = sourceOperationList(scr, XDND_SOURCE_WIN(info)); + + dropLocation = getDropLocationInView(destView); + destView->dragDestinationProcs->performDragOperation( + destView, + XDND_DROP_DATAS(info), + operationList, + dropLocation); + + wfree(dropLocation); + if (operationList != NULL) + WMFreeArray(operationList); +} + + +/* ----- Destination timer ----- */ +static void +dragSourceResponseTimeOut(void *destView) +{ + WMView *view = (WMView*) destView; + WMDraggingInfo *info; + + wwarning("delay for drag source response expired"); + if (view != NULL) { + info = &(W_VIEW_SCREEN(view)->dragInfo); + if (XDND_DEST_VIEW_STORED(info)) + cancelDrop(view, info); + else { + /* send XdndStatus with action None */ + sendDnDClientMessage(view, + W_VIEW_SCREEN(view)->xdndStatusAtom, + 0, 0, 0, None); + } + + W_DragDestinationInfoClear(info); + } +} + +void +W_DragDestinationStopTimer() +{ + if (dndDestinationTimer != NULL) { + WMDeleteTimerHandler(dndDestinationTimer); + dndDestinationTimer = NULL; + } +} + +void +W_DragDestinationStartTimer(WMDraggingInfo *info) +{ + W_DragDestinationStopTimer(); + + if (XDND_DEST_STATE(info) != idleState + || XDND_DEST_VIEW(info) == NULL) { + /* note: info->destView == NULL means : + Enter message has been received, waiting for Position message */ + + dndDestinationTimer = WMAddTimerHandler( + XDND_SOURCE_RESPONSE_MAX_DELAY, + dragSourceResponseTimeOut, + XDND_DEST_VIEW(info)); + } +} +/* ----- End of Destination timer ----- */ + + +/* ----- Destination states ----- */ + +#ifdef XDND_DEBUG +static const char* +stateName(W_DndState *state) +{ + if (state == NULL) + return "no state defined"; + + if (state == idleState) + return "idleState"; + + if (state == waitEnterState) + return "waitEnterState"; + + if (state == inspectDropDataState) + return "inspectDropDataState"; + + if (state == dropAllowedState) + return "dropAllowedState"; + + if (state == dropNotAllowedState) + return "dropNotAllowedState"; + + if (state == waitForDropDataState) + return "waitForDropDataState"; + + return "unknown state"; +} +#endif + +static void* +idleState(WMView *destView, XClientMessageEvent *event, + WMDraggingInfo *info) +{ + WMScreen *scr; + Atom sourceMsg; + + scr = W_VIEW_SCREEN(destView); + sourceMsg = event->message_type; + + if (sourceMsg == scr->xdndPositionAtom) { + destView->dragDestinationProcs->prepareForDragOperation(destView); + + if (XDND_SOURCE_TYPES(info) != NULL) { + /* enter message infos are available */ + return checkDropAllowed(destView, event, info); + } + + /* waiting for enter message */ + return waitEnterState; + } + + return idleState; +} + + +/* Source position and action are stored, + waiting for xdnd protocol version and source type */ +static void* +waitEnterState(WMView *destView, XClientMessageEvent *event, + WMDraggingInfo *info) +{ + WMScreen *scr = W_VIEW_SCREEN(destView); + Atom sourceMsg = event->message_type; + + if (sourceMsg == scr->xdndEnterAtom) { + W_DragDestinationStoreEnterMsgInfo(info, destView, event); + return checkDropAllowed(destView, event, info); + } + + return waitEnterState; +} + + +/* We have requested a data, and have received it */ +static void* +inspectDropDataState(WMView *destView, XClientMessageEvent *event, + WMDraggingInfo *info) +{ + WMScreen *scr; + Atom sourceMsg; + + scr = W_VIEW_SCREEN(destView); + sourceMsg = event->message_type; + + if (sourceMsg == scr->xdndSelectionAtom) { + /* a data has been retrieved, store next available */ + if (requestDropData(info)) + return inspectDropDataState; + + /* all required (and available) datas are stored */ + if (destView->dragDestinationProcs->inspectDropData( + destView, + XDND_DROP_DATAS(info))) + return checkActionAllowed(destView, info); + + suspendDropAuthorization(destView, info); + return dropNotAllowedState; + } + + return inspectDropDataState; +} + + +static void* +dropNotAllowedState(WMView *destView, XClientMessageEvent *event, + WMDraggingInfo *info) +{ + WMScreen *scr = W_VIEW_SCREEN(destView); + Atom sourceMsg = event->message_type; + + if (sourceMsg == scr->xdndDropAtom) { + finishDrop(destView, info); + return idleState; + } + + return dropNotAllowedState; +} + + +static void* +dropAllowedState(WMView *destView, XClientMessageEvent *event, + WMDraggingInfo *info) +{ + WMScreen *scr = W_VIEW_SCREEN(destView); + Atom sourceMsg = event->message_type; + + if (sourceMsg == scr->xdndDropAtom) { + if (XDND_DROP_DATAS(info) != NULL) { + /* drop datas were cached with inspectDropData call */ + callPerformDragOperation(destView, info); + } else { + XDND_DROP_DATAS(info) = createDropDataArray( + XDND_REQUIRED_TYPES(info)); + + /* store first available data */ + if (requestDropData(info)) + return waitForDropDataState; + + /* no data retrieved */ + callPerformDragOperation(destView, info); + } + + finishDrop(destView, info); + return idleState; + } + + return dropAllowedState; +} + + +static void* +waitForDropDataState(WMView *destView, XClientMessageEvent *event, + WMDraggingInfo *info) +{ + WMScreen *scr = W_VIEW_SCREEN(destView); + Atom sourceMsg = event->message_type; + + if (sourceMsg == scr->xdndSelectionAtom) { + /* store next data */ + if (requestDropData(info)) + return waitForDropDataState; + + /* all required (and available) datas are stored */ + callPerformDragOperation(destView, info); + + finishDrop(destView, info); + return idleState; + } + + return waitForDropDataState; +} + +/* ----- End of Destination states ----- */ + + +void +W_DragDestinationStateHandler(WMDraggingInfo *info, XClientMessageEvent *event) +{ + WMView *destView; + W_DndState* newState; + + if (XDND_DEST_VIEW_STORED(info)) { + destView = XDND_DEST_VIEW(info); + if (XDND_DEST_STATE(info) == NULL) + XDND_DEST_STATE(info) = idleState; + +#ifdef XDND_DEBUG + + printf("current dest state: %s\n", + stateName(XDND_DEST_STATE(info))); +#endif + + newState = (W_DndState*) XDND_DEST_STATE(info)(destView, event, info); + +#ifdef XDND_DEBUG + + printf("new dest state: %s\n", stateName(newState)); +#endif + + if (XDND_DEST_INFO(info) != NULL) { + XDND_DEST_STATE(info) = newState; + if (XDND_DEST_STATE(info) != idleState) + W_DragDestinationStartTimer(info); + } + } +} + + +static void +realizedObserver(void *self, WMNotification *notif) +{ + WMView *view = (WMView*)WMGetNotificationObject(notif); + WMScreen *scr = W_VIEW_SCREEN(view); + + XChangeProperty(scr->display, W_VIEW_DRAWABLE(view), + scr->xdndAwareAtom, + XA_ATOM, XDND_PROPERTY_FORMAT, PropModeReplace, + &XDNDversion, 1); + + WMRemoveNotificationObserver(self); +} + + +void +W_SetXdndAwareProperty(WMScreen *scr, WMView *view, Atom *types, + int typeCount) +{ + WMView *toplevel = W_TopLevelOfView(view); + + if (!toplevel->flags.xdndHintSet) { + toplevel->flags.xdndHintSet = 1; + + if (toplevel->flags.realized) { + XChangeProperty(scr->display, W_VIEW_DRAWABLE(toplevel), + scr->xdndAwareAtom, XA_ATOM, XDND_PROPERTY_FORMAT, + PropModeReplace, &XDNDversion, 1); + } else { + WMAddNotificationObserver(realizedObserver, + /* just use as an id */ + &view->dragDestinationProcs, + WMViewRealizedNotification, + toplevel); + } + } +} + + +void +WMRegisterViewForDraggedTypes(WMView *view, WMArray *acceptedTypes) +{ + Atom *types; + int typeCount; + int i; + + typeCount = WMGetArrayItemCount(acceptedTypes); + types = wmalloc(sizeof(Atom)*(typeCount+1)); + + for (i = 0; i < typeCount; i++) { + types[i] = XInternAtom(W_VIEW_SCREEN(view)->display, + WMGetFromArray(acceptedTypes, i), + False); + } + types[i] = 0; + + view->droppableTypes = types; + /* WMFreeArray(acceptedTypes); */ + + W_SetXdndAwareProperty(W_VIEW_SCREEN(view), view, types, typeCount); +} + + +void +WMUnregisterViewDraggedTypes(WMView *view) +{ + if (view->droppableTypes != NULL) + wfree(view->droppableTypes); + view->droppableTypes = NULL; +} + + +/* + requestedOperation: operation requested by the source + sourceDataTypes: data types (mime-types strings) supported by the source + (never NULL, destroyed when drop ends) + return operation allowed by destination (self) + */ +static WMDragOperationType +defAllowedOperation(WMView *self, + WMDragOperationType requestedOperation, + WMArray* sourceDataTypes) +{ + /* no operation allowed */ + return WDOperationNone; +} + + +/* + requestedOperation: operation requested by the source + sourceDataTypes: data types (mime-types strings) supported by the source + (never NULL, destroyed when drop ends) + return data types (mime-types strings) required by destination (self) + or NULL if no suitable data type is available (force + to 2nd pass with full source type list). + */ +static WMArray* +defRequiredDataTypes (WMView *self, + WMDragOperationType requestedOperation, + WMArray* sourceDataTypes) +{ + /* no data type allowed (NULL even at 2nd pass) */ + return NULL; +} + + +/* + Executed when the drag enters destination (self) + */ +static void +defPrepareForDragOperation(WMView *self) +{ +} + + +/* + Checks datas to be dropped (optional). + dropDatas: datas (WMData*) required by destination (self) + (given in same order as returned by requiredDataTypes). + A NULL data means it couldn't be retreived. + Destroyed when drop ends. + return true if data array is ok + */ +/* Bool (*inspectDropData)(WMView *self, WMArray *dropDatas); */ + + +/* + Process drop + dropDatas: datas (WMData*) required by destination (self) + (given in same order as returned by requiredDataTypes). + A NULL data means it couldn't be retrivied. + Destroyed when drop ends. + operationList: if source operation is WDOperationAsk, contains + operations (and associated texts) that can be asked + to source. (destroyed after performDragOperation call) + Otherwise this parameter is NULL. + */ +static void +defPerformDragOperation(WMView *self, WMArray *dropDatas, + WMArray *operationList, WMPoint *dropLocation) +{ +} + + +/* Executed after drop */ +static void +defConcludeDragOperation(WMView *self) +{ +} + + +void +WMSetViewDragDestinationProcs(WMView *view, WMDragDestinationProcs *procs) +{ + if (view->dragDestinationProcs == NULL) { + view->dragDestinationProcs = wmalloc(sizeof(WMDragDestinationProcs)); + } else { + free(view->dragDestinationProcs); + } + + *view->dragDestinationProcs = *procs; + + /*XXX fill in non-implemented stuffs */ + if (procs->allowedOperation == NULL) { + view->dragDestinationProcs->allowedOperation = defAllowedOperation; + } + if (procs->allowedOperation == NULL) { + view->dragDestinationProcs->requiredDataTypes = defRequiredDataTypes; + } + + /* note: inspectDropData can be NULL, if data consultation is not needed + to give drop permission */ + + if (procs->prepareForDragOperation == NULL) { + view->dragDestinationProcs->prepareForDragOperation = defPrepareForDragOperation; + } + if (procs->performDragOperation == NULL) { + view->dragDestinationProcs->performDragOperation = defPerformDragOperation; + } + if (procs->concludeDragOperation == NULL) { + view->dragDestinationProcs->concludeDragOperation = defConcludeDragOperation; + } +} + + diff --git a/WINGs/dragsource.c b/WINGs/dragsource.c dissimilarity index 89% index 4eeb4413..b08ee783 100644 --- a/WINGs/dragsource.c +++ b/WINGs/dragsource.c @@ -1,1335 +1,1312 @@ - -#include "../src/config.h" - -#include -#include -#include - -#ifdef SHAPE -#include -#endif - -#include - - -#include "WINGsP.h" - - - - -#define SPIT(a) - - -#define IS_DROPPABLE(view) (view!=NULL && view->droppableTypes!=NULL && \ - view->dragDestinationProcs!=NULL) - - -static Atom operationToAction(WMScreen *scr, WMDragOperationType operation); -static WMDragOperationType actionToOperation(WMScreen *scr, Atom action); - -static Bool _XErrorOccured = False; - - - -static unsigned -defDraggingSourceOperation(WMView *self, Bool local) -{ - return WDOperationCopy; -} - - -static void -defBeganDragImage(WMView *self, WMPixmap *image, WMPoint point) -{ -} - - -static void -defEndedDragImage(WMView *self, WMPixmap *image, WMPoint point, Bool deposited) -{ -} - - -static WMData* -defFetchDragData(WMView *self, char *type) -{ - return NULL; -} - - -void -WMSetViewDragSourceProcs(WMView *view, WMDragSourceProcs *procs) -{ - if (view->dragSourceProcs) - wfree(view->dragSourceProcs); - view->dragSourceProcs = wmalloc(sizeof(WMDragSourceProcs)); - - *view->dragSourceProcs = *procs; - - if (procs->draggingSourceOperation == NULL) { - view->dragSourceProcs->draggingSourceOperation = defDraggingSourceOperation; - } - if (procs->beganDragImage == NULL) { - view->dragSourceProcs->beganDragImage = defBeganDragImage; - } - if (procs->endedDragImage == NULL) { - view->dragSourceProcs->endedDragImage = defEndedDragImage; - } - if (procs->fetchDragData == NULL) { - view->dragSourceProcs->fetchDragData = defFetchDragData; - } -} - - -/***********************************************************************/ - - -static int -handleXError(Display *dpy, XErrorEvent *ev) -{ - _XErrorOccured = True; - - return 1; -} - - -static void -protectBlock(Bool begin) -{ - static void *oldHandler = NULL; - - if (begin) { - oldHandler = XSetErrorHandler(handleXError); - } else { - XSetErrorHandler(oldHandler); - } -} - - - - -static Window -makeDragIcon(WMScreen *scr, WMPixmap *pixmap) -{ - Window window; - WMSize size; - unsigned long flags; - XSetWindowAttributes attribs; - Pixmap pix, mask; - - if (!pixmap) { - pixmap = scr->defaultObjectIcon; - } - size = WMGetPixmapSize(pixmap); - pix = pixmap->pixmap; - mask = pixmap->mask; - - flags = CWSaveUnder|CWBackPixmap|CWOverrideRedirect|CWColormap; - attribs.save_under = True; - attribs.background_pixmap = pix; - attribs.override_redirect = True; - attribs.colormap = scr->colormap; - window = XCreateWindow(scr->display, scr->rootWin, 0, 0, size.width, - size.height, 0, scr->depth, InputOutput, - scr->visual, flags, &attribs); - -#ifdef SHAPE - if (mask) { - XShapeCombineMask(scr->display, window, ShapeBounding, 0, 0, mask, - ShapeSet); - } -#endif - - return window; -} - - -static void -slideWindow(Display *dpy, Window win, int srcX, int srcY, int dstX, int dstY) -{ - double x, y, dx, dy; - int i; - int iterations; - - iterations = WMIN(25, WMAX(abs(dstX-srcX), abs(dstY-srcY))); - - x = srcX; - y = srcY; - - dx = (double)(dstX-srcX)/iterations; - dy = (double)(dstY-srcY)/iterations; - - for (i = 0; i <= iterations; i++) { - XMoveWindow(dpy, win, x, y); - XFlush(dpy); - - wusleep(800); - - x += dx; - y += dy; - } -} - - -static Window -findChildInWindow(Display *dpy, Window toplevel, int x, int y) -{ - Window foo, bar; - Window *children; - unsigned nchildren; - int i; - - if (!XQueryTree(dpy, toplevel, &foo, &bar, - &children, &nchildren) || children == NULL) { - return None; - } - - /* first window that contains the point is the one */ - for (i = nchildren-1; i >= 0; i--) { - XWindowAttributes attr; - - if (XGetWindowAttributes(dpy, children[i], &attr) - && attr.map_state == IsViewable - && x >= attr.x && y >= attr.y - && x < attr.x + attr.width && y < attr.y + attr.height) { - Window child, tmp; - - tmp = children[i]; - - child = findChildInWindow(dpy, tmp, x - attr.x, y - attr.y); - - XFree(children); - - if (child == None) - return tmp; - else - return child; - } - } - - XFree(children); - return None; -} - - -static WMView* -findViewInToplevel(Display *dpy, Window toplevel, int x, int y) -{ - Window child; - - child = findChildInWindow(dpy, toplevel, x, y); - - if (child != None) { - return W_GetViewForXWindow(dpy, child); - } else { - return NULL; - } -} - - - -static Window -lookForToplevel(WMScreen *scr, Window window, Bool *isAware) -{ - Window toplevel = None; - Atom *atoms; - int j, count; - - *isAware = False; - - atoms = XListProperties(scr->display, window, &count); - for (j = 0; j < count; j++) { - if (atoms[j] == scr->wmStateAtom) { - toplevel = window; - } else if (atoms[j] == scr->xdndAwareAtom) { - *isAware = True; - } - } - if (atoms) - XFree(atoms); - - if (toplevel == None) { - Window *children; - Window foo, bar; - unsigned nchildren; - - if (!XQueryTree(scr->display, window, &foo, &bar, - &children, &nchildren) || children == NULL) { - return None; - } - - for (j = 0; j < nchildren; j++) { - toplevel = lookForToplevel(scr, children[j], isAware); - if (toplevel != None) - break; - } - - XFree(children); - } - - return toplevel; -} - - - -static Window -findToplevelUnderDragPointer(WMScreen *scr, int x, int y, Window iconWindow) -{ - Window foo, bar; - Window *children; - unsigned nchildren; - Bool overSomething = False; - int i; - - if (!XQueryTree(scr->display, scr->rootWin, &foo, &bar, - &children, &nchildren) || children == NULL) { - SPIT("couldnt query tree!"); - return None; - } - - /* try to find the window below the iconWindow by traversing - * the whole window list */ - - /* first find the position of the iconWindow */ - for (i = nchildren-1; i >= 0; i--) { - if (children[i] == iconWindow) { - i--; - break; - } - } - if (i <= 0) { - XFree(children); - return scr->rootWin; - } - - /* first window that contains the point is the one */ - for (; i >= 0; i--) { - XWindowAttributes attr; - - if (XGetWindowAttributes(scr->display, children[i], &attr) - && attr.map_state == IsViewable - && x >= attr.x && y >= attr.y - && x < attr.x + attr.width && y < attr.y + attr.height) { - Window toplevel; - Bool isaware; - - overSomething = True; - - toplevel = lookForToplevel(scr, children[i], &isaware); - - XFree(children); - - if (isaware) - return toplevel; - else - return None; - } - } - - XFree(children); - if (!overSomething) - return scr->rootWin; - else - return None; -} - - - - - - -static void -sendClientMessage(Display *dpy, Window win, Atom message, - unsigned data1, unsigned data2, unsigned data3, - unsigned data4, unsigned data5) -{ - XEvent ev; - - ev.type = ClientMessage; - ev.xclient.message_type = message; - ev.xclient.format = 32; - ev.xclient.window = win; - ev.xclient.data.l[0] = data1; - ev.xclient.data.l[1] = data2; - ev.xclient.data.l[2] = data3; - ev.xclient.data.l[3] = data4; - ev.xclient.data.l[4] = data5; - - XSendEvent(dpy, win, False, 0, &ev); - XFlush(dpy); -} - - - - -static unsigned -notifyPosition(WMScreen *scr, WMDraggingInfo *info) -{ - Atom action = operationToAction(scr, info->sourceOperation); - - sendClientMessage(scr->display, info->destinationWindow, - scr->xdndPositionAtom, - info->sourceWindow, - 0, /* reserved */ - info->location.x<<16|info->location.y, - info->timestamp, - action/* operation */); - - return 0; -} - - - -static void -notifyDrop(WMScreen *scr, WMDraggingInfo *info) -{ - sendClientMessage(scr->display, info->destinationWindow, - scr->xdndDropAtom, - info->sourceWindow, - 0, /* reserved */ - info->timestamp, - 0, 0); -} - - - -static void -notifyDragLeave(WMScreen *scr, WMDraggingInfo *info) -{ - sendClientMessage(scr->display, info->destinationWindow, - scr->xdndLeaveAtom, - info->sourceWindow, 0, 0, 0, 0); -} - - - -static unsigned -notifyDragEnter(WMScreen *scr, WMDraggingInfo *info) -{ - unsigned d; - - d = XDND_VERSION << 24; - - sendClientMessage(scr->display, info->destinationWindow, - scr->xdndEnterAtom, - info->sourceWindow, d, 0, 0, 0); - - return 0; -} - - -static void -translateCoordinates(WMScreen *scr, Window target, int fromX, int fromY, - int *x, int *y) -{ - Window child; - - XTranslateCoordinates(scr->display, scr->rootWin, target, - fromX, fromY, x, y, &child); -} - - -static void -updateDraggingInfo(WMScreen *scr, WMDraggingInfo *info, WMSize offset, - XEvent *event, Window iconWindow) -{ - Window toplevel; - - if (event->type == MotionNotify) { - info->imageLocation.x = event->xmotion.x_root-offset.width; - info->imageLocation.y = event->xmotion.y_root-offset.height; - - info->location.x = event->xmotion.x_root; - info->location.y = event->xmotion.y_root; -/* info->timestamp = event->xmotion.time;*/ - - } else if (event->type == ButtonRelease) { - info->imageLocation.x = event->xbutton.x_root-offset.width; - info->imageLocation.y = event->xbutton.y_root-offset.height; - - info->location.x = event->xbutton.x_root; - info->location.y = event->xbutton.y_root; -/* info->timestamp = event->xbutton.time;*/ - } - - toplevel = findToplevelUnderDragPointer(scr, - info->location.x, - info->location.y, - iconWindow); - info->destinationWindow = toplevel; -} - - - - -static void -processMotion(WMScreen *scr, WMDraggingInfo *info, WMDraggingInfo *oldInfo, - WMRect *rect, unsigned currentAction) -{ - unsigned action; - - if (info->destinationWindow == None) { /* entered an unsupporeted window */ - - if (oldInfo->destinationWindow != None - && oldInfo->destinationWindow != scr->rootWin) { - SPIT("left window"); - - notifyDragLeave(scr, oldInfo); - } - - } else if (info->destinationWindow == scr->rootWin) { - - if (oldInfo->destinationWindow != None - && oldInfo->destinationWindow != scr->rootWin) { - SPIT("left window to root"); - - notifyDragLeave(scr, oldInfo); - } else { - /* nothing */ - } - - } else if (oldInfo->destinationWindow != info->destinationWindow) { - - if (oldInfo->destinationWindow != None - && oldInfo->destinationWindow != scr->rootWin) { - notifyDragLeave(scr, oldInfo); - SPIT("crossed"); - } else { - SPIT("entered window"); - } - - action = notifyDragEnter(scr, info); - - } else { - -#define LEFT_RECT(r, X, Y) (X < r->pos.x || Y < r->pos.y \ - || X >= r->pos.x + r->size.width \ - || Y >= r->pos.y + r->size.height) - - if (rect->size.width == 0 || - (LEFT_RECT(rect, info->location.x, info->location.y))) { - - action = notifyPosition(scr, info); - - rect->size.width = 0; - } - } -} - - - -static WMData* -convertSelection(WMView *view, Atom selection, Atom target, - void *cdata, Atom *type) -{ - WMScreen *scr = W_VIEW_SCREEN(view); - WMData *data; - char *typeName = XGetAtomName(scr->display, target); - - *type = target; - - data = view->dragSourceProcs->fetchDragData(view, typeName); - - if (typeName != NULL) - XFree(typeName); - - return data; -} - - -static void -selectionLost(WMView *view, Atom selection, void *cdata) -{ - if (W_VIEW_SCREEN(view)->dragSourceView == view) { - wwarning("DND selection lost during drag operation..."); - W_VIEW_SCREEN(view)->dragSourceView = NULL; - } -} - - -static void -selectionDone(WMView *view, Atom selection, Atom target, void *cdata) -{ - -} - - - - - -static void -setMouseOffsetHint(WMView *view, WMSize mouseOffset) -{ - WMScreen *scr = W_VIEW_SCREEN(view); - long hint[2]; - - /* - * Tell the offset from the topleft corner of the icon being - * dragged. Not from XDND, but it's backwards compatible. - */ - - hint[0] = mouseOffset.width; - hint[1] = mouseOffset.height; - - XChangeProperty(scr->display, W_VIEW_DRAWABLE(view), - scr->wmIconDragOffsetAtom, XA_INTEGER, 32, - PropModeReplace, (unsigned char*)hint, 2); -} - - -static Bool -getMouseOffsetHint(WMScreen *scr, Window source, WMSize *mouseOffset) -{ - long *hint; - Atom type_ret; - int fmt_ret; - unsigned long nitems_ret, bytes_after_ret; - Bool ok = False; - - - hint = NULL; - - XGetWindowProperty(scr->display, source, - scr->wmIconDragOffsetAtom, 0, 2, False, XA_INTEGER, - &type_ret, &fmt_ret, &nitems_ret, &bytes_after_ret, - (unsigned char **)&hint); - - if (hint && nitems_ret == 2) { - mouseOffset->width = hint[0]; - mouseOffset->height = hint[1]; - ok = True; - } - if (hint) - XFree(hint); - - return ok; -} - - - -static void -timeoutCallback(void *data) -{ - wwarning("drag & drop timed out while waiting for response from 0x%x\n", - (unsigned)data); - _XErrorOccured = 2; -} - -/* - * State Machine For Drag Source: - * ------------------------------ - * Events - * State Call Mtn Ent Lea Crs BUp StA StR Fin TO - * 0) idle 1bu - - - - - - - - - - * 1) drag over target - 1au - 2cu 1cbu 5fu 3 4 1w - - * 2) drag over nothing - 2 1bu - - 0 - - 2w - - * 3) drag targ+accept - 3u - 2cu 1cbu 6f 3 4w 0z - - * 4) drag targ+reject - 4u - 2cu 1cbu 0 3w 4 0z - - * 5) waiting status - 5X 5X 5X 5X - 6f 0 0z 0w - * 6) dropped - - - - - - - - 0 0w - * - * Events: - * Call - called WMDragImageFromView() - * Mtn - Motion - * Ent - Enter droppable window - * Lea - Leave droppable window (or rectangle) - * Crs - Leave droppable window (or rectangle) and enter another - * BUp - Button Released - * StA - XdndStatus client msg with Accept drop - * StR - XdndStatus client msg with Reject drop - * Fin - XdndFinish client msg - * TO - timeout - * - * Actions: - * a - send update message - * b - send enter message - * c - send leave message - * d - release drag section info - * e - send drop message - * f - setup timeout - * u - update dragInfo - * - * X - ignore - * w - warn about unexpected reply - * z - abort operation.. unexpected reply - * - shouldnt happen - */ -void -WMDragImageFromView(WMView *view, WMPixmap *image, char *dataTypes[], - WMPoint atLocation, WMSize mouseOffset, XEvent *event, - Bool slideBack) -{ - WMScreen *scr = view->screen; - Display *dpy = scr->display; - WMView *toplevel = W_TopLevelOfView(view); - Window icon; - XEvent ev; - WMRect rect = {{0,0},{0,0}}; - int ostate = -1; - int state; - int action = -1; - XColor black = {0, 0,0,0, DoRed|DoGreen|DoBlue}; - XColor green = {0x0045b045, 0x4500,0xb000,0x4500, DoRed|DoGreen|DoBlue}; - XColor back = {0, 0xffff,0xffff,0xffff, DoRed|DoGreen|DoBlue}; - WMDraggingInfo dragInfo; - WMDraggingInfo oldDragInfo; - WMHandlerID timer = NULL; - static WMSelectionProcs handler = { - convertSelection, - selectionLost, - selectionDone - }; - - - if (scr->dragSourceView != NULL) - return; - - wassertr(view->dragSourceProcs != NULL); - - - /* prepare icon to be dragged */ - if (image == NULL) - image = scr->defaultObjectIcon; - - icon = makeDragIcon(scr, image); - - XMoveWindow(dpy, icon, atLocation.x, atLocation.y); - XMapRaised(dpy, icon); - - - /* init dragging info */ - - scr->dragSourceView = view; - - memset(&dragInfo, 0, sizeof(WMDraggingInfo)); - memset(&oldDragInfo, 0, sizeof(WMDraggingInfo)); - dragInfo.image = image; - dragInfo.sourceView = view; - dragInfo.sourceWindow = W_VIEW_DRAWABLE(toplevel); - - dragInfo.destinationWindow = dragInfo.sourceWindow; - - dragInfo.location.x = atLocation.x + mouseOffset.width; - dragInfo.location.y = atLocation.y + mouseOffset.height; - dragInfo.imageLocation = atLocation; - - - /* start pointer grab */ - XGrabPointer(dpy, scr->rootWin, False, - ButtonPressMask|ButtonReleaseMask|ButtonMotionMask, - GrabModeAsync, GrabModeAsync, None, scr->defaultCursor, - CurrentTime); - - XFlush(dpy); - - _XErrorOccured = False; - - /* take ownership of XdndSelection */ - if (!WMCreateSelectionHandler(view, scr->xdndSelectionAtom, - event->xmotion.time, - &handler, NULL)) { - wwarning("could not get ownership or DND selection"); - return; - } - - setMouseOffsetHint(toplevel, mouseOffset); - - if (view->dragSourceProcs->beganDragImage != NULL) { - view->dragSourceProcs->beganDragImage(view, image, atLocation); - } - - processMotion(scr, &dragInfo, &oldDragInfo, &rect, action); - - state = 1; - - while (state != 6 && state != 0 && !_XErrorOccured) { - WMNextEvent(dpy, &ev); - - switch (ev.type) { - case MotionNotify: - if (state >= 1 && state <= 4) { - while (XCheckTypedEvent(dpy, MotionNotify, &ev)) ; - - protectBlock(True); - - oldDragInfo = dragInfo; - - updateDraggingInfo(scr, &dragInfo, mouseOffset, &ev, icon); - - XMoveWindow(dpy, icon, dragInfo.imageLocation.x, - dragInfo.imageLocation.y); - - processMotion(scr, &dragInfo, &oldDragInfo, &rect, action); - - protectBlock(False); - - /* XXXif entered a different destination, check the operation */ - - switch (state) { - case 1: - if (oldDragInfo.destinationWindow != None - && oldDragInfo.destinationWindow != scr->rootWin - && (dragInfo.destinationWindow == None - || dragInfo.destinationWindow == scr->rootWin)) { - /* left the droppable window */ - state = 2; - action = -1; - } - break; - - case 2: - if (dragInfo.destinationWindow != None - && dragInfo.destinationWindow != scr->rootWin) { - - state = 1; - action = -1; - } - break; - - case 3: - case 4: - if (oldDragInfo.destinationWindow != None - && oldDragInfo.destinationWindow != scr->rootWin - && (dragInfo.destinationWindow == None - || dragInfo.destinationWindow == scr->rootWin)) { - /* left the droppable window */ - state = 2; - action = -1; - } - break; - } - } - break; - - - case ButtonRelease: - /* if (state >= 1 && state <= 4) */ { - - protectBlock(True); - - oldDragInfo = dragInfo; - - updateDraggingInfo(scr, &dragInfo, mouseOffset, &ev, icon); - - XMoveWindow(dpy, icon, dragInfo.imageLocation.x, - dragInfo.imageLocation.y); - - if (state == 4 || state == 1) { - dragInfo.destinationWindow = None; - dragInfo.destView = NULL; - } - processMotion(scr, &dragInfo, &oldDragInfo, &rect, action); - - dragInfo.timestamp = ev.xbutton.time; - - protectBlock(False); - - switch (state) { - case 1: - state = 5; - timer = WMAddTimerHandler(3000, timeoutCallback, - (void*)dragInfo.destinationWindow); - break; - case 2: - state = 0; - break; - case 3: - state = 6; - break; - case 4: - state = 0; - break; - } - } - break; - - case ClientMessage: - if ((state == 1 || state == 3 || state == 4 || state == 5) - && ev.xclient.message_type == scr->xdndStatusAtom - && ev.xclient.data.l[0] == dragInfo.destinationWindow) { - - if (ev.xclient.data.l[1] & 1) { - SPIT("got accept msg"); - /* will accept drop */ - switch (state) { - case 1: - case 3: - case 4: - state = 3; - break; - case 5: - if (timer) { - WMDeleteTimerHandler(timer); - timer = NULL; - } - state = 6; - break; - } - action = actionToOperation(scr, ev.xclient.data.l[4]); - } else { - SPIT("got reject msg"); - switch (state) { - case 1: - case 3: - case 4: - state = 4; - break; - case 5: - state = 0; - if (timer) { - WMDeleteTimerHandler(timer); - timer = NULL; - } - break; - } - action = 0; - } - - if (ev.xclient.data.l[1] & (1<<1)) { - rect.pos.x = ev.xclient.data.l[2] >> 16; - rect.pos.y = ev.xclient.data.l[2] & 0xffff; - rect.size.width = ev.xclient.data.l[3] >> 16; - rect.size.height = ev.xclient.data.l[3] & 0xffff; - } else { - rect.size.width = 0; - } - - } else if ((state >= 1 && state <= 5) - && ev.xclient.message_type == scr->xdndFinishedAtom - && ev.xclient.window == dragInfo.destinationWindow) { - - wwarning("drag source received unexpected XdndFinished message from %x", - (unsigned)dragInfo.destinationWindow); - - if (state == 3 || state == 4 || state == 5) { - state = 0; - if (timer) { - WMDeleteTimerHandler(timer); - timer = NULL; - } - } - } - - default: - WMHandleEvent(&ev); - break; - } - - if (ostate != state) { - if (state == 3) { - XRecolorCursor(dpy, scr->defaultCursor, &green, &back); - } else if (ostate == 3) { - XRecolorCursor(dpy, scr->defaultCursor, &black, &back); - } - ostate = state; - } - } - - if (timer) { - WMDeleteTimerHandler(timer); - timer = NULL; - } else if (_XErrorOccured) { - /* got a timeout, send leave */ - notifyDragLeave(scr, &dragInfo); - } - - XUngrabPointer(dpy, CurrentTime); - - SPIT("exited main loop"); - - if (_XErrorOccured || state != 6) { - goto cancelled; - } - - assert(dragInfo.destinationWindow != None); - - protectBlock(True); - notifyDrop(scr, &dragInfo); - protectBlock(False); - - if (_XErrorOccured) - goto cancelled; - - - SPIT("dropped"); - - - XDestroyWindow(dpy, icon); - - return; - -cancelled: - scr->dragSourceView = NULL; - - WMDeleteSelectionHandler(view, scr->xdndSelectionAtom, - event->xmotion.time); - - if (slideBack) { - slideWindow(dpy, icon, - dragInfo.imageLocation.x, dragInfo.imageLocation.y, - atLocation.x, atLocation.y); - } - XDestroyWindow(dpy, icon); - if (view->dragSourceProcs->endedDragImage != NULL) { - view->dragSourceProcs->endedDragImage(view, image, - dragInfo.imageLocation, - False); - } -} - - - - - - - - - - - - -static Atom -operationToAction(WMScreen *scr, WMDragOperationType operation) -{ - switch (operation) { - case WDOperationNone: - return None; - - case WDOperationCopy: - return scr->xdndActionCopy; - - case WDOperationMove: - return scr->xdndActionMove; - - case WDOperationLink: - return scr->xdndActionLink; - - case WDOperationAsk: - return scr->xdndActionAsk; - - case WDOperationPrivate: - return scr->xdndActionPrivate; - - default: - return None; - } -} - - -static WMDragOperationType -actionToOperation(WMScreen *scr, Atom action) -{ - if (action == scr->xdndActionCopy) { - return WDOperationCopy; - - } else if (action == scr->xdndActionMove) { - return WDOperationMove; - - } else if (action == scr->xdndActionLink) { - return WDOperationLink; - - } else if (action == scr->xdndActionAsk) { - return WDOperationAsk; - - } else if (action == scr->xdndActionPrivate) { - return WDOperationPrivate; - - } else if (action == None) { - - return WDOperationCopy; - } else { - char *tmp = XGetAtomName(scr->display, action); - - wwarning("unknown XDND action %s from 0x%x", tmp, - (unsigned)scr->dragInfo.sourceWindow); - XFree(tmp); - - return WDOperationCopy; - } -} - - - - - - -static Atom* -getTypeList(Window window, XClientMessageEvent *event) -{ - int i = 0; - Atom *types = NULL; - - if (event->data.l[1] & 1) { /* > 3 types */ - - } else { - types = wmalloc(4 * sizeof(Atom)); - if (event->data.l[2] != None) - types[i++] = event->data.l[2]; - if (event->data.l[3] != None) - types[i++] = event->data.l[3]; - if (event->data.l[4] != None) - types[i++] = event->data.l[4]; - types[i] = 0; - } - - if (types[0] == 0) { - wwarning("received invalid drag & drop type list"); - /*XXX return;*/ - } - - return types; -} - - - -#define DISPATCH(view, func, info) (view)->dragDestinationProcs->func(view, info) - - - -static void -receivedData(WMView *view, Atom selection, Atom target, - Time timestamp, void *cdata, WMData *data) -{ - WMScreen *scr = W_VIEW_SCREEN(view); - WMDraggingInfo *info = (WMDraggingInfo*)cdata; - Bool res; - - res = view->dragDestinationProcs->performDragOperation(view, info); - - if (res) { - DISPATCH(view, concludeDragOperation, info); - } - - /* send finished message */ - sendClientMessage(scr->display, info->sourceWindow, - scr->xdndFinishedAtom, - info->destinationWindow, - 0, 0, 0, 0); - - memset(&scr->dragInfo, 0, sizeof(WMDraggingInfo)); -} - - - -void -W_HandleDNDClientMessage(WMView *toplevel, XClientMessageEvent *event) -{ - WMScreen *scr = W_VIEW_SCREEN(toplevel); - WMView *oldView = NULL; - WMView *newView = NULL; - unsigned operation = 0; - int x, y; - enum { - WNothing, - WEnter, - WLeave, - WCross, /* leave one and enter another */ - WUpdate, - WDrop - }; - Window source; - int what = WNothing; - Bool sendStatus = False; - - - source = scr->dragInfo.sourceWindow; - oldView = scr->dragInfo.destView; - - if (event->message_type == scr->xdndFinishedAtom) { - WMView *view = scr->dragSourceView; - - WMDeleteSelectionHandler(view, scr->xdndSelectionAtom, - scr->dragInfo.timestamp); - - if (view->dragSourceProcs->endedDragImage != NULL) { - view->dragSourceProcs->endedDragImage(view, - scr->dragInfo.image, - scr->dragInfo.imageLocation, - True); - } - - scr->dragSourceView = NULL; - - return; - } - - - - if (event->message_type == scr->xdndEnterAtom) { - Window foo, bar; - int bla; - unsigned ble; - - if (scr->dragInfo.sourceWindow != None) { - puts("received Enter event in bad order"); - } - - memset(&scr->dragInfo, 0, sizeof(WMDraggingInfo)); - - - if ((event->data.l[1] >> 24) > XDND_VERSION) { - wwarning("received drag & drop request with unsupported version %i", - (event->data.l[1] >> 24)); - return; - } - - scr->dragInfo.protocolVersion = event->data.l[1] >> 24; - scr->dragInfo.sourceWindow = source = event->data.l[0]; - scr->dragInfo.destinationWindow = event->window; - - getMouseOffsetHint(scr, source, &scr->dragInfo.mouseOffset); - - /* XXX */ - scr->dragInfo.image = NULL; - - XQueryPointer(scr->display, scr->rootWin, &foo, &bar, - &scr->dragInfo.location.x, &scr->dragInfo.location.y, - &bla, &bla, &ble); - - scr->dragInfo.imageLocation = scr->dragInfo.location; - scr->dragInfo.imageLocation.x -= scr->dragInfo.mouseOffset.width; - scr->dragInfo.imageLocation.y -= scr->dragInfo.mouseOffset.height; - - translateCoordinates(scr, scr->dragInfo.destinationWindow, - scr->dragInfo.location.x, - scr->dragInfo.location.y, &x, &y); - - - newView = findViewInToplevel(scr->display, - scr->dragInfo.destinationWindow, - x, y); - - } else if (event->message_type == scr->xdndPositionAtom - && scr->dragInfo.sourceWindow == event->data.l[0]) { - - scr->dragInfo.location.x = event->data.l[2] >> 16; - scr->dragInfo.location.y = event->data.l[2] & 0xffff; - - scr->dragInfo.imageLocation = scr->dragInfo.location; - scr->dragInfo.imageLocation.x -= scr->dragInfo.mouseOffset.width; - scr->dragInfo.imageLocation.y -= scr->dragInfo.mouseOffset.height; - - if (scr->dragInfo.protocolVersion >= 1) { - scr->dragInfo.timestamp = event->data.l[3]; - scr->dragInfo.sourceOperation = actionToOperation(scr, - event->data.l[4]); - - } else { - scr->dragInfo.timestamp = CurrentTime; - scr->dragInfo.sourceOperation = WDOperationCopy; - } - - translateCoordinates(scr, scr->dragInfo.destinationWindow, - scr->dragInfo.location.x, - scr->dragInfo.location.y, &x, &y); - - newView = findViewInToplevel(scr->display, - scr->dragInfo.destinationWindow, - x, y); - - } else if (event->message_type == scr->xdndLeaveAtom - && scr->dragInfo.sourceWindow == event->data.l[0]) { - - memset(&scr->dragInfo, 0, sizeof(WMDraggingInfo)); - - } else if (event->message_type == scr->xdndDropAtom - && scr->dragInfo.sourceWindow == event->data.l[0]) { - - /* drop */ - if (oldView != NULL) - what = WDrop; - - } else { - return; - } - - - /* - * Now map the XDND events to WINGs events. - */ - - if (what == WNothing) { - if (IS_DROPPABLE(newView)) { - if (!IS_DROPPABLE(oldView)) { /* entered */ - what = WEnter; - } else if (oldView == newView) { /* updated */ - what = WUpdate; - } else { - what = WCross; - } - } else { - if (IS_DROPPABLE(oldView)) { - what = WLeave; - } else { - /* just send rejection msg */ - sendStatus = True; - } - } - } - - - - switch (what) { - - case WEnter: - scr->dragInfo.destView = newView; - operation = DISPATCH(newView, draggingEntered, &scr->dragInfo); - sendStatus = True; - break; - - case WLeave: - scr->dragInfo.destView = NULL; - DISPATCH(oldView, draggingExited, &scr->dragInfo); - sendStatus = True; - operation = WDOperationNone; - break; - - case WCross: - DISPATCH(oldView, draggingExited, &scr->dragInfo); - scr->dragInfo.destView = newView; - operation = DISPATCH(newView, draggingEntered, &scr->dragInfo); - sendStatus = True; - break; - - case WUpdate: - operation = DISPATCH(oldView, draggingUpdated, &scr->dragInfo); - sendStatus = True; - break; - - case WDrop: - { - Bool res; - - res = DISPATCH(oldView, prepareForDragOperation, &scr->dragInfo); - - if (res) { - res = DISPATCH(oldView, performDragOperation, &scr->dragInfo); - } - - if (res) { - - } - } - break; - - default: - break; - } - - - - if (sendStatus) { - Atom action; - - action = operationToAction(scr, operation); - - sendClientMessage(scr->display, source, - scr->xdndStatusAtom, - scr->dragInfo.destinationWindow, - action != None ? 1 : 0, 0, 0, action); - } -} - - - - +#include "../src/config.h" + +#include +#include +#ifdef SHAPE +#include +#endif + +#include "WINGsP.h" + + +#define XDND_DESTINATION_RESPONSE_MAX_DELAY 10000 +#define MIN_X_MOVE_OFFSET 5 +#define MIN_Y_MOVE_OFFSET 5 +#define MAX_SLIDEBACK_ITER 15 + +#define VERSION_INFO(dragInfo) dragInfo->protocolVersion +#define XDND_PROPERTY_FORMAT 32 +#define XDND_ACTION_DESCRIPTION_FORMAT 8 + +#define XDND_SOURCE_INFO(dragInfo) dragInfo->sourceInfo +#define XDND_DEST_WIN(dragInfo) dragInfo->sourceInfo->destinationWindow +#define XDND_SOURCE_ACTION(dragInfo) dragInfo->sourceAction +#define XDND_DEST_ACTION(dragInfo) dragInfo->destinationAction +#define XDND_SOURCE_VIEW(dragInfo) dragInfo->sourceInfo->sourceView +#define XDND_SOURCE_STATE(dragInfo) dragInfo->sourceInfo->state +#define XDND_SELECTION_PROCS(dragInfo) dragInfo->sourceInfo->selectionProcs +#define XDND_DRAG_ICON(dragInfo) dragInfo->sourceInfo->icon +#define XDND_MOUSE_OFFSET(dragInfo) dragInfo->sourceInfo->mouseOffset +#define XDND_DRAG_CURSOR(dragInfo) dragInfo->sourceInfo->dragCursor +#define XDND_DRAG_ICON_POS(dragInfo) dragInfo->sourceInfo->imageLocation +#define XDND_NO_POS_ZONE(dragInfo) dragInfo->sourceInfo->noPositionMessageZone +#define XDND_TIMESTAMP(dragInfo) dragInfo->timestamp +#define XDND_3_TYPES(dragInfo) dragInfo->sourceInfo->firstThreeTypes +#define XDND_SOURCE_VIEW_STORED(dragInfo) dragInfo->sourceInfo != NULL \ + && dragInfo->sourceInfo->sourceView != NULL + + +static WMHandlerID dndSourceTimer = NULL; + + +static void* idleState(WMView *srcView, XClientMessageEvent *event, + WMDraggingInfo *info); +static void* dropAllowedState(WMView *srcView, XClientMessageEvent *event, + WMDraggingInfo *info); +static void* finishDropState(WMView *srcView, XClientMessageEvent *event, + WMDraggingInfo *info); + +#ifdef XDND_DEBUG +static const char* +stateName(W_DndState *state) +{ + if (state == NULL) + return "no state defined"; + + if (state == idleState) + return "idleState"; + + if (state == dropAllowedState) + return "dropAllowedState"; + + if (state == finishDropState) + return "finishDropState"; + + return "unknown state"; +} +#endif + + +static WMScreen* +sourceScreen(WMDraggingInfo *info) +{ + return W_VIEW_SCREEN(XDND_SOURCE_VIEW(info)); +} + + +static void +endDragProcess(WMDraggingInfo *info, Bool deposited) +{ + WMView *view = XDND_SOURCE_VIEW(info); + WMScreen *scr = W_VIEW_SCREEN(XDND_SOURCE_VIEW(info)); + + /* free selection handler while view exists */ + WMDeleteSelectionHandler(view, + scr->xdndSelectionAtom, + CurrentTime); + wfree(XDND_SELECTION_PROCS(info)); + + if (XDND_DRAG_CURSOR(info) != None) { + XFreeCursor(scr->display, + XDND_DRAG_CURSOR(info)); + XDND_DRAG_CURSOR(info) = None; + } + + if (view->dragSourceProcs->endedDrag != NULL) { + /* this can destroy source view (with a "move" action for example) */ + view->dragSourceProcs->endedDrag(view, &XDND_DRAG_ICON_POS(info), + deposited); + } + + /* clear remaining draggging infos */ + wfree(XDND_SOURCE_INFO(info)); + XDND_SOURCE_INFO(info) = NULL; +} + + +/* ----- drag cursor ----- */ +static void +initDragCursor(WMDraggingInfo *info) +{ + WMScreen *scr = sourceScreen(info); + XColor cursorFgColor, cursorBgColor; + + /* green */ + cursorFgColor.red = 0x4500; + cursorFgColor.green = 0xb000; + cursorFgColor.blue = 0x4500; + + /* white */ + cursorBgColor.red = 0xffff; + cursorBgColor.green = 0xffff; + cursorBgColor.blue = 0xffff; + + XDND_DRAG_CURSOR(info) = XCreateFontCursor(scr->display, XC_left_ptr); + XRecolorCursor(scr->display, + XDND_DRAG_CURSOR(info), + &cursorFgColor, + &cursorBgColor); + + XFlush(scr->display); +} + +static void +recolorCursor(WMDraggingInfo *info, Bool dropIsAllowed) +{ + WMScreen *scr = sourceScreen(info); + + if (dropIsAllowed) { + XDefineCursor(scr->display, + scr->rootWin, + XDND_DRAG_CURSOR(info)); + } else { + XDefineCursor(scr->display, + scr->rootWin, + scr->defaultCursor); + } + + XFlush(scr->display); +} +/* ----- end of drag cursor ----- */ + + +/* ----- selection procs ----- */ +static WMData* +convertSelection(WMView *view, Atom selection, Atom target, + void *cdata, Atom *type) +{ + WMScreen *scr; + WMData *data; + char *typeName; + + scr = W_VIEW_SCREEN(view); + typeName = XGetAtomName(scr->display, target); + + *type = target; + + if (view->dragSourceProcs->fetchDragData != NULL) { + data = view->dragSourceProcs->fetchDragData( + view, + typeName); + } else { + data = NULL; + } + + if (typeName != NULL) + XFree(typeName); + + return data; +} + + +static void +selectionLost(WMView *view, Atom selection, void *cdata) +{ + wwarning("DND selection lost during drag operation..."); +} + + +static void +selectionDone(WMView *view, Atom selection, Atom target, void *cdata) +{ +#ifdef XDND_DEBUG + printf("selection done\n"); +#endif +} +/* ----- end of selection procs ----- */ + + +/* ----- visual part ----- */ + +static Window +makeDragIcon(WMScreen *scr, WMPixmap *pixmap) +{ + Window window; + WMSize size; + unsigned long flags; + XSetWindowAttributes attribs; + Pixmap pix, mask; + + if (!pixmap) { + pixmap = scr->defaultObjectIcon; + } + + size = WMGetPixmapSize(pixmap); + pix = pixmap->pixmap; + mask = pixmap->mask; + + flags = CWSaveUnder|CWBackPixmap|CWOverrideRedirect|CWColormap; + attribs.save_under = True; + attribs.background_pixmap = pix; + attribs.override_redirect = True; + attribs.colormap = scr->colormap; + + window = XCreateWindow(scr->display, scr->rootWin, 0, 0, size.width, + size.height, 0, scr->depth, InputOutput, + scr->visual, flags, &attribs); + +#ifdef SHAPE + + if (mask) { + XShapeCombineMask(scr->display, window, ShapeBounding, 0, 0, mask, + ShapeSet); + } +#endif + + return window; +} + + +static void +slideWindow(Display *dpy, Window win, int srcX, int srcY, int dstX, int dstY) +{ + double x, y, dx, dy; + int i; + int iterations; + + iterations = WMIN(MAX_SLIDEBACK_ITER, + WMAX(abs(dstX-srcX), abs(dstY-srcY))); + + x = srcX; + y = srcY; + + dx = (double)(dstX-srcX)/iterations; + dy = (double)(dstY-srcY)/iterations; + + for (i = 0; i <= iterations; i++) { + XMoveWindow(dpy, win, x, y); + XFlush(dpy); + + wusleep(800); + + x += dx; + y += dy; + } +} + + +static int +getInitialDragImageCoord(int viewCoord, int mouseCoord, + int viewSize, int iconSize) +{ + if (iconSize >= viewSize) { + /* center icon coord on view */ + return viewCoord - iconSize/2; + } else { + /* try to center icon on mouse pos */ + + if (mouseCoord - iconSize/2 <= viewCoord) + /* if icon was centered on mouse, it would be off view + thus, put icon left (resp. top) side + at view (resp. top) side */ + return viewCoord; + + else if (mouseCoord + iconSize/2 >= viewCoord + viewSize) + /* if icon was centered on mouse, it would be off view + thus, put icon right (resp. bottom) side + at view right (resp. bottom) side */ + return viewCoord + viewSize - iconSize; + + else + return mouseCoord - iconSize/2; + } + +} + +static void +initDragImagePos(WMView *view, WMDraggingInfo *info, XEvent *event) +{ + WMSize iconSize = WMGetPixmapSize(view->dragImage); + WMSize viewSize = WMGetViewSize(view); + WMPoint viewPos; + Window foo; + + XTranslateCoordinates(W_VIEW_SCREEN(view)->display, + WMViewXID(view), W_VIEW_SCREEN(view)->rootWin, + 0, 0, &(viewPos.x), &(viewPos.y), + &foo); + + /* set icon pos */ + XDND_DRAG_ICON_POS(info).x = + getInitialDragImageCoord(viewPos.x, event->xmotion.x_root, + viewSize.width, iconSize.width); + + XDND_DRAG_ICON_POS(info).y = + getInitialDragImageCoord(viewPos.y, event->xmotion.y_root, + viewSize.height, iconSize.height); + + /* set mouse offset relative to icon */ + XDND_MOUSE_OFFSET(info).x = + event->xmotion.x_root - XDND_DRAG_ICON_POS(info).x; + XDND_MOUSE_OFFSET(info).y = + event->xmotion.y_root - XDND_DRAG_ICON_POS(info).y; +} + + +static void +refreshDragImage(WMView *view, WMDraggingInfo *info) +{ + WMScreen *scr = W_VIEW_SCREEN(view); + + XMoveWindow(scr->display, XDND_DRAG_ICON(info), + XDND_DRAG_ICON_POS(info).x, + XDND_DRAG_ICON_POS(info).y); +} + + +static void +startDragImage(WMView *view, WMDraggingInfo *info, XEvent* event) +{ + WMScreen *scr = W_VIEW_SCREEN(view); + + XDND_DRAG_ICON(info) = makeDragIcon(scr, view->dragImage); + initDragImagePos(view, info, event); + refreshDragImage(view, info); + XMapRaised(scr->display, XDND_DRAG_ICON(info)); + + initDragCursor(info); +} + + +static void +endDragImage(WMDraggingInfo *info, Bool slideBack) +{ + WMView *view = XDND_SOURCE_VIEW(info); + Display *dpy = W_VIEW_SCREEN(view)->display; + + if (slideBack) { + WMPoint toLocation; + Window foo; + + XTranslateCoordinates(W_VIEW_SCREEN(view)->display, + WMViewXID(view), W_VIEW_SCREEN(view)->rootWin, + 0, 0, &(toLocation.x), &(toLocation.y), + &foo); + + slideWindow(dpy, XDND_DRAG_ICON(info), + XDND_DRAG_ICON_POS(info).x, + XDND_DRAG_ICON_POS(info).y, + toLocation.x, + toLocation.y); + } + + XDestroyWindow(dpy, XDND_DRAG_ICON(info)); +} + +/* ----- end of visual part ----- */ + + +/* ----- messages ----- */ + +/* send a DnD message to the destination window */ +static Bool +sendDnDClientMessage(WMDraggingInfo *info, Atom message, + unsigned long data1, + unsigned long data2, + unsigned long data3, + unsigned long data4) +{ + Display *dpy = sourceScreen(info)->display; + Window srcWin = WMViewXID(XDND_SOURCE_VIEW(info)); + Window destWin = XDND_DEST_WIN(info); + + if (! W_SendDnDClientMessage(dpy, + destWin, + message, + srcWin, + data1, + data2, + data3, + data4)) { + /* drop failed */ + recolorCursor(info, False); + endDragImage(info, True); + endDragProcess(info, False); + return False; + } + + return True; +} + + +static Bool +sendEnterMessage(WMDraggingInfo *info) +{ + WMScreen *scr = sourceScreen(info); + unsigned long data1; + + data1 = (VERSION_INFO(info) << 24)|1; /* 1: support of type list */ + + return sendDnDClientMessage(info, scr->xdndEnterAtom, + data1, + XDND_3_TYPES(info)[0], + XDND_3_TYPES(info)[1], + XDND_3_TYPES(info)[2]); +} + + +static Bool +sendPositionMessage(WMDraggingInfo *info, WMPoint *mousePos) +{ + WMScreen *scr = sourceScreen(info); + WMRect *noPosZone = &(XDND_NO_POS_ZONE(info)); + + if (noPosZone->size.width != 0 || noPosZone->size.height != 0) { + if (mousePos->x < noPosZone->pos.x + || mousePos->x > (noPosZone->pos.x + noPosZone->size.width) + || mousePos->y < noPosZone->pos.y + || mousePos->y > (noPosZone->pos.y + noPosZone->size.width)) { + /* send position if out of zone defined by destination */ + return sendDnDClientMessage(info, scr->xdndPositionAtom, + 0, + mousePos->x<<16|mousePos->y, + XDND_TIMESTAMP(info), + XDND_SOURCE_ACTION(info)); + } + } else { + /* send position on each move */ + return sendDnDClientMessage(info, scr->xdndPositionAtom, + 0, + mousePos->x<<16|mousePos->y, + XDND_TIMESTAMP(info), + XDND_SOURCE_ACTION(info)); + } +} + + +static Bool +sendLeaveMessage(WMDraggingInfo *info) +{ + WMScreen *scr = sourceScreen(info); + + return sendDnDClientMessage(info, scr->xdndLeaveAtom, + 0, 0, 0, 0); +} + + +static Bool +sendDropMessage(WMDraggingInfo *info) +{ + WMScreen *scr = sourceScreen(info); + + return sendDnDClientMessage(info, + scr->xdndDropAtom, + 0, + XDND_TIMESTAMP(info), + 0, 0); +} + +/* ----- end of messages ----- */ + + +static Atom* +getTypeAtomList(WMScreen *scr, WMView *view, int* count) +{ + WMArray* types; + Atom* typeAtoms; + int i; + + types = view->dragSourceProcs->dropDataTypes(view); + + if (types != NULL) { + *count = WMGetArrayItemCount(types); + if (*count > 0) { + typeAtoms = wmalloc((*count)*sizeof(Atom)); + for (i=0; i < *count; i++) { + typeAtoms[i] = XInternAtom(scr->display, + WMGetFromArray(types, i), + False); + } + + /* WMFreeArray(types); */ + return typeAtoms; + } + + /* WMFreeArray(types); */ + } + + *count = 1; + typeAtoms = wmalloc(sizeof(Atom)); + *typeAtoms = None; + + return typeAtoms; +} + + +static void +registerDropTypes(WMScreen *scr, WMView *view, WMDraggingInfo *info) +{ + Atom* typeList; + int i, count; + + typeList = getTypeAtomList(scr, view, &count); + + /* store the first 3 types */ + for(i=0; i < 3 && i < count; i++) + XDND_3_TYPES(info)[i] = typeList[i]; + + for(; i < 3; i++) + XDND_3_TYPES(info)[i] = None; + + + /* store the entire type list */ + XChangeProperty(scr->display, + WMViewXID(view), + scr->xdndTypeListAtom, + XA_ATOM, + XDND_PROPERTY_FORMAT, + PropModeReplace, + (unsigned char*) typeList, + count); +} + + +static void +registerOperationList(WMScreen *scr, WMView *view, WMArray* operationArray) +{ + Atom* actionList; + WMDragOperationType operation; + int count = WMGetArrayItemCount(operationArray); + int i; + + actionList = wmalloc(sizeof(Atom)*count); + + for(i=0; i < count; i++) { + operation = WMGetDragOperationItemType( + WMGetFromArray(operationArray, i)); + actionList[i] = W_OperationToAction(scr, operation); + } + + XChangeProperty(scr->display, + WMViewXID(view), + scr->xdndActionListAtom, + XA_ATOM, + XDND_PROPERTY_FORMAT, + PropModeReplace, + (unsigned char*) actionList, + count); +} + +static void +registerDescriptionList(WMScreen *scr, WMView *view, WMArray* operationArray) +{ + char *text, *textListItem, *textList; + int count = WMGetArrayItemCount(operationArray); + int i; + int size = 0; + + /* size of XA_STRING info */ + for(i=0; i < count; i++) { + size += strlen(WMGetDragOperationItemText( + WMGetFromArray(operationArray, i))) + 1; /* +1 = +NULL */ + } + + /* create text list */ + textList = wmalloc(size); + textListItem = textList; + + for(i=0; i < count; i++) { + text = WMGetDragOperationItemText(WMGetFromArray(operationArray, i)); + strcpy(textListItem, text); + + /* to next text offset */ + textListItem = &(textListItem[strlen(textListItem) + 1]); + } + + XChangeProperty(scr->display, + WMViewXID(view), + scr->xdndActionDescriptionAtom, + XA_STRING, + XDND_ACTION_DESCRIPTION_FORMAT, + PropModeReplace, + (unsigned char*) textList, + size); +} + +/* called if wanted operation is WDOperationAsk */ +static void +registerSupportedOperations(WMView *view) +{ + WMScreen *scr = W_VIEW_SCREEN(view); + WMArray* operationArray; + + operationArray = view->dragSourceProcs->askedOperations(view); + + registerOperationList(scr, view, operationArray); + registerDescriptionList(scr, view, operationArray); + + /* WMFreeArray(operationArray); */ +} + + +static void +initSourceDragInfo(WMView *sourceView, WMDraggingInfo *info) +{ + WMRect emptyZone; + + XDND_SOURCE_INFO(info) = (W_DragSourceInfo*) wmalloc(sizeof(W_DragSourceInfo)); + + XDND_SOURCE_VIEW(info) = sourceView; + XDND_DEST_WIN(info) = None; + XDND_DRAG_ICON(info) = None; + + XDND_SOURCE_ACTION(info) = W_OperationToAction( + W_VIEW_SCREEN(sourceView), + sourceView->dragSourceProcs->wantedDropOperation(sourceView)); + + XDND_DEST_ACTION(info) = None; + + XDND_SOURCE_STATE(info) = idleState; + + emptyZone.pos = wmkpoint(0, 0); + emptyZone.size = wmksize(0, 0); + XDND_NO_POS_ZONE(info) = emptyZone; +} + + +/* + Returned array is destroyed after dropDataTypes call + */ +static WMArray* +defDropDataTypes(WMView *self) +{ + return NULL; +} + + +static WMDragOperationType +defWantedDropOperation(WMView *self) +{ + return WDOperationNone; +} + + +/* + Must be defined if wantedDropOperation return WDOperationAsk + (useless otherwise). + Return a WMDragOperationItem array (destroyed after call). + A WMDragOperationItem links a label to an operation. + static WMArray* + defAskedOperations(WMView *self); */ + + +static Bool +defAcceptDropOperation(WMView *self, WMDragOperationType allowedOperation) +{ + return False; +} + + +static void +defBeganDrag(WMView *self, WMPoint *point) +{ +} + + +static void +defEndedDrag(WMView *self, WMPoint *point, Bool deposited) +{ +} + + +/* + Returned data is not destroyed + */ +static WMData* +defFetchDragData(WMView *self, char *type) +{ + return NULL; +} + + +void +WMSetViewDragSourceProcs(WMView *view, WMDragSourceProcs *procs) +{ + if (view->dragSourceProcs) + wfree(view->dragSourceProcs); + view->dragSourceProcs = wmalloc(sizeof(WMDragSourceProcs)); + + *view->dragSourceProcs = *procs; + + if (procs->dropDataTypes == NULL) + view->dragSourceProcs->dropDataTypes = defDropDataTypes; + + if (procs->wantedDropOperation == NULL) + view->dragSourceProcs->wantedDropOperation = defWantedDropOperation; + + /* + Note: askedOperations can be NULL, if wantedDropOperation never returns + WDOperationAsk. + */ + + if (procs->acceptDropOperation == NULL) + view->dragSourceProcs->acceptDropOperation = defAcceptDropOperation; + + if (procs->beganDrag == NULL) + view->dragSourceProcs->beganDrag = defBeganDrag; + + if (procs->endedDrag == NULL) + view->dragSourceProcs->endedDrag = defEndedDrag; + + if (procs->fetchDragData == NULL) + view->dragSourceProcs->fetchDragData = defFetchDragData; +} + + +static Bool +isXdndAware(WMScreen *scr, Window win) +{ + Atom type; + int format; + unsigned long count, remain; + unsigned char *winXdndVersion; + unsigned char *proxy; + + if (win == None) + return False; + + XGetWindowProperty(scr->display, win, scr->xdndAwareAtom, + 0, 1, False, XA_ATOM, &type, &format, + &count, &remain, &winXdndVersion); + + if (type != XA_ATOM + || format != XDND_PROPERTY_FORMAT + || count == 0 || !winXdndVersion) { + if (winXdndVersion) + XFree(winXdndVersion); + return False; + } + + XFree(winXdndVersion); + return (count == 1); /* xdnd version is set */ +} + + +static Window* +windowChildren(Display *dpy, Window win, unsigned *nchildren) +{ + Window *children; + Window foo, bar; + + if (!XQueryTree(dpy, win, &foo, &bar, &children, nchildren)) { + *nchildren = 0; + return NULL; + } else + return children; +} + +static Window +lookForAwareWindow(WMScreen *scr, WMPoint *mousePos, Window win) +{ + int tmpx, tmpy; + Window child; + + /* Since xdnd v3, only the toplevel window should be aware */ + if (isXdndAware(scr, win)) + return win; + + /* inspect child under pointer */ + if (XTranslateCoordinates(scr->display, scr->rootWin, win, + mousePos->x, mousePos->y, &tmpx, &tmpy, + &child)) { + if (child == None) + return None; + else + return lookForAwareWindow(scr, mousePos, child); + } + + return None; +} + + +static Window +findDestination(WMDraggingInfo *info, WMPoint *mousePos) +{ + WMScreen *scr = sourceScreen(info); + unsigned nchildren; + Window *children = windowChildren(scr->display, scr->rootWin, &nchildren); + int i; + XWindowAttributes attr; + + if (isXdndAware(scr, scr->rootWin)) + return scr->rootWin; + + /* exclude drag icon (and upper) from search */ + for (i = nchildren-1; i >= 0; i--) { + if (children[i] == XDND_DRAG_ICON(info)) { + i--; + break; + } + } + + if (i < 0) { + /* root window has no child under drag icon, and is not xdnd aware. */ + return None; + } + + /* inspecting children, from upper to lower */ + for (; i >= 0; i--) { + if (XGetWindowAttributes(scr->display, children[i], &attr) + && attr.map_state == IsViewable + && mousePos->x >= attr.x + && mousePos->y >= attr.y + && mousePos->x < attr.x + attr.width + && mousePos->y < attr.y + attr.height) { + return lookForAwareWindow(scr, mousePos, children[i]); + } + } + + /* No child window under drag pointer */ + return None; +} + + +static void +initMotionProcess(WMView *view, WMDraggingInfo *info, + XEvent *event, WMPoint *startLocation) +{ + WMScreen *scr = W_VIEW_SCREEN(view); + + /* take ownership of XdndSelection */ + XDND_SELECTION_PROCS(info) = + (WMSelectionProcs*) wmalloc(sizeof(WMSelectionProcs)); + XDND_SELECTION_PROCS(info)->convertSelection = convertSelection; + XDND_SELECTION_PROCS(info)->selectionLost = selectionLost; + XDND_SELECTION_PROCS(info)->selectionDone = selectionDone; + XDND_TIMESTAMP(info) = event->xmotion.time; + + if (!WMCreateSelectionHandler(view, scr->xdndSelectionAtom, + CurrentTime, + XDND_SELECTION_PROCS(info), NULL)) { + wwarning("could not get ownership or DND selection"); + return; + } + + registerDropTypes(scr, view, info); + + if (XDND_SOURCE_ACTION(info) == W_VIEW_SCREEN(view)->xdndActionAsk) + registerSupportedOperations(view); + + if (view->dragSourceProcs->beganDrag != NULL) { + view->dragSourceProcs->beganDrag(view, startLocation); + } +} + + +static void +processMotion(WMDraggingInfo *info, Window windowUnderDrag, WMPoint *mousePos) +{ + WMScreen *scr = sourceScreen(info); + Window newDestination = findDestination(info, mousePos); + + W_DragSourceStopTimer(); + + if (newDestination != XDND_DEST_WIN(info)) { + recolorCursor(info, False); + + if (XDND_DEST_WIN(info) != None) { + /* leaving a xdnd window */ + sendLeaveMessage(info); + } + + XDND_DEST_WIN(info) = newDestination; + XDND_SOURCE_STATE(info) = idleState; + XDND_DEST_ACTION(info) = None; + XDND_NO_POS_ZONE(info).size.width = 0; + XDND_NO_POS_ZONE(info).size.height = 0; + + if (newDestination != None) { + /* entering a xdnd window */ + if (! sendEnterMessage(info)) { + XDND_DEST_WIN(info) = None; + return; + } + + W_DragSourceStartTimer(info); + } + } else { + if (XDND_DEST_WIN(info) != None) { + if (! sendPositionMessage(info, mousePos)) { + XDND_DEST_WIN(info) = None; + return; + } + + W_DragSourceStartTimer(info); + } + } +} + + +static Bool +processButtonRelease(WMDraggingInfo *info) +{ + if (XDND_SOURCE_STATE(info) == dropAllowedState) { + /* begin drop */ + W_DragSourceStopTimer(); + + if (! sendDropMessage(info)) + return False; + + W_DragSourceStartTimer(info); + return True; + } else { + if (XDND_DEST_WIN(info) != None) + sendLeaveMessage(info); + + W_DragSourceStopTimer(); + return False; + } +} + + +Bool +WMIsDraggingFromView(WMView *view) +{ + WMDraggingInfo *info = &W_VIEW_SCREEN(view)->dragInfo; + + return ( XDND_SOURCE_INFO(info) != NULL + && XDND_SOURCE_STATE(info) != finishDropState); + /* return W_VIEW_SCREEN(view)->dragInfo.sourceInfo != NULL; */ +} + + +void +WMDragImageFromView(WMView *view, XEvent *event) +{ + WMDraggingInfo *info = &W_VIEW_SCREEN(view)->dragInfo; + WMPoint mouseLocation; + + switch(event->type) { + case ButtonPress: + if (event->xbutton.button == Button1) { + XEvent nextEvent; + + XPeekEvent(event->xbutton.display, &nextEvent); + + /* Initialize only if a drag really begins (avoid clicks) */ + if (nextEvent.type == MotionNotify) { + initSourceDragInfo(view, info); + } + } + + break; + + case ButtonRelease: + if (WMIsDraggingFromView(view)) { + Bool dropBegan = processButtonRelease(info); + + recolorCursor(info, False); + if (dropBegan) { + endDragImage(info, False); + XDND_SOURCE_STATE(info) = finishDropState; + } else { + /* drop failed */ + endDragImage(info, True); + endDragProcess(info,False); + } + } + break; + + case MotionNotify: + if (WMIsDraggingFromView(view)) { + mouseLocation = wmkpoint(event->xmotion.x_root, + event->xmotion.y_root); + + if (abs(XDND_DRAG_ICON_POS(info).x - mouseLocation.x) >= + MIN_X_MOVE_OFFSET + || abs(XDND_DRAG_ICON_POS(info).y - mouseLocation.y) >= + MIN_Y_MOVE_OFFSET) { + if (XDND_DRAG_ICON(info) == None) { + initMotionProcess(view, info, event, &mouseLocation); + startDragImage(view, info, event); + } else { + XDND_DRAG_ICON_POS(info).x = + mouseLocation.x - XDND_MOUSE_OFFSET(info).x; + XDND_DRAG_ICON_POS(info).y = + mouseLocation.y - XDND_MOUSE_OFFSET(info).y; + + refreshDragImage(view, info); + processMotion(info, + event->xmotion.window, + &mouseLocation); + } + } + } + break; + } +} + + +/* Minimal mouse events handler: no right or double-click detection, + only drag is supported */ +static void +dragImageHandler(XEvent *event, void *cdata) +{ + WMView *view = (WMView*)cdata; + + WMDragImageFromView(view, event); +} + + +/* ----- source states ----- */ + +#ifdef XDND_DEBUG +static void +traceStatusMsg(Display *dpy, XClientMessageEvent *statusEvent) +{ + printf("Xdnd status message:\n"); + + if (statusEvent->data.l[1] & 0x2UL) + printf("send position on every move\n"); + else { + int x, y, w, h; + x = statusEvent->data.l[2] >> 16; + y = statusEvent->data.l[2] & 0xFFFFL; + w = statusEvent->data.l[3] >> 16; + h = statusEvent->data.l[3] & 0xFFFFL; + + printf("send position out of ((%d,%d) , (%d,%d))\n", + x, y, x+w, y+h); + } + + if (statusEvent->data.l[1] & 0x1L) + printf("allowed action: %s\n", + XGetAtomName(dpy, statusEvent->data.l[4])); + else + printf("no action allowed\n"); +} +#endif + + +storeDropAction(WMDraggingInfo *info, Atom destAction) +{ + WMView* sourceView = XDND_SOURCE_VIEW(info); + WMScreen *scr = W_VIEW_SCREEN(sourceView); + + if (sourceView->dragSourceProcs->acceptDropOperation != NULL) { + if (sourceView->dragSourceProcs->acceptDropOperation( + sourceView, + W_ActionToOperation(scr, destAction))) + XDND_DEST_ACTION(info) = destAction; + else + XDND_DEST_ACTION(info) = None; + } else { + XDND_DEST_ACTION(info) = destAction; + } +} + + +static void +storeStatusMessageInfos(WMDraggingInfo *info, XClientMessageEvent *statusEvent) +{ + WMRect* noPosZone = &(XDND_NO_POS_ZONE(info)); + +#ifdef XDND_DEBUG + + traceStatusMsg(sourceScreen(info)->display, statusEvent); +#endif + + if (statusEvent->data.l[1] & 0x2UL) { + /* bit 1 set: destination wants position messages on every move */ + noPosZone->size.width = 0; + noPosZone->size.height = 0; + } else { + /* don't send another position message while in given rectangle */ + noPosZone->pos.x = statusEvent->data.l[2] >> 16; + noPosZone->pos.y = statusEvent->data.l[2] & 0xFFFFL; + noPosZone->size.width = statusEvent->data.l[3] >> 16; + noPosZone->size.height = statusEvent->data.l[3] & 0xFFFFL; + } + + if ((statusEvent->data.l[1] & 0x1L) || statusEvent->data.l[4] != None) { + /* destination accept drop */ + storeDropAction(info, statusEvent->data.l[4]); + } else { + XDND_DEST_ACTION(info) = None; + } +} + + +static void* +idleState(WMView *view, XClientMessageEvent *event, WMDraggingInfo *info) +{ + WMScreen *scr; + Atom destMsg = event->message_type; + + scr = W_VIEW_SCREEN(view); + + if (destMsg == scr->xdndStatusAtom) { + storeStatusMessageInfos(info, event); + + if (XDND_DEST_ACTION(info) != None) { + recolorCursor(info, True); + W_DragSourceStartTimer(info); + return dropAllowedState; + } else { + /* drop denied */ + recolorCursor(info, False); + return idleState; + } + } + + if (destMsg == scr->xdndFinishedAtom) { + wwarning("received xdndFinishedAtom before drop began"); + } + + W_DragSourceStartTimer(info); + return idleState; +} + + +static void* +dropAllowedState(WMView *view, XClientMessageEvent *event, WMDraggingInfo *info) +{ + WMScreen *scr = W_VIEW_SCREEN(view); + Atom destMsg = event->message_type; + + if (destMsg == scr->xdndStatusAtom) { + storeStatusMessageInfos(info, event); + + if (XDND_DEST_ACTION(info) == None) { + /* drop denied */ + recolorCursor(info, False); + return idleState; + } + } + + W_DragSourceStartTimer(info); + return dropAllowedState; +} + + +static void* +finishDropState(WMView *view, XClientMessageEvent *event, WMDraggingInfo *info) +{ + WMScreen *scr = W_VIEW_SCREEN(view); + Atom destMsg = event->message_type; + + if (destMsg == scr->xdndFinishedAtom) { + endDragProcess(info, True); + return NULL; + } + + W_DragSourceStartTimer(info); + return finishDropState; +} +/* ----- end of source states ----- */ + + +/* ----- source timer ----- */ +static void +dragSourceResponseTimeOut(void *source) +{ + WMView *view = (WMView*)source; + WMDraggingInfo *info = &(W_VIEW_SCREEN(view)->dragInfo); + + wwarning("delay for drag destination response expired"); + sendLeaveMessage(info); + + recolorCursor(info, False); + if (XDND_SOURCE_STATE(info) == finishDropState) { + /* drop failed */ + endDragImage(info, True); + endDragProcess(info, False); + } else { + XDND_SOURCE_STATE(info) = idleState; + } +} + +void +W_DragSourceStopTimer() +{ + if (dndSourceTimer != NULL) { + WMDeleteTimerHandler(dndSourceTimer); + dndSourceTimer = NULL; + } +} + +void +W_DragSourceStartTimer(WMDraggingInfo *info) +{ + W_DragSourceStopTimer(); + + dndSourceTimer = WMAddTimerHandler( + XDND_DESTINATION_RESPONSE_MAX_DELAY, + dragSourceResponseTimeOut, + XDND_SOURCE_VIEW(info)); +} + +/* ----- End of Destination timer ----- */ + + +void +W_DragSourceStateHandler(WMDraggingInfo *info, XClientMessageEvent *event) +{ + WMView *view; + W_DndState* newState; + + if (XDND_SOURCE_VIEW_STORED(info)) { + view = XDND_SOURCE_VIEW(info); +#ifdef XDND_DEBUG + + printf("current source state: %s\n", + stateName(XDND_SOURCE_STATE(info))); +#endif + + newState = (W_DndState*) XDND_SOURCE_STATE(info)(view, event, info); + +#ifdef XDND_DEBUG + + printf("new source state: %s\n", stateName(newState)); +#endif + + if (newState != NULL) + XDND_SOURCE_STATE(info) = newState; + /* else drop finished, and info has been flushed */ + } +} + + +void WMSetViewDragImage(WMView* view, WMPixmap *dragImage) +{ + if (view->dragImage != NULL) + WMReleasePixmap(view->dragImage); + + view->dragImage = WMRetainPixmap(dragImage); +} + + +void WMReleaseViewDragImage(WMView* view) +{ + if (view->dragImage != NULL) + WMReleasePixmap(view->dragImage); +} + + +/* Create a drag handler, associating drag event masks with dragEventProc */ +void +WMCreateDragHandler(WMView *view, WMEventProc *dragEventProc, void *clientData) +{ + WMCreateEventHandler(view, + ButtonPressMask|ButtonReleaseMask|Button1MotionMask, + dragEventProc, clientData); +} + + +void +WMDeleteDragHandler(WMView *view, WMEventProc *dragEventProc, void *clientData) +{ + WMDeleteEventHandler(view, + ButtonPressMask|ButtonReleaseMask|Button1MotionMask, + dragEventProc, clientData); +} + + +/* set default drag handler for view */ +void +WMSetViewDraggable(WMView *view, WMDragSourceProcs *dragSourceProcs, + WMPixmap *dragImage) +{ + wassertr(dragImage != NULL); + view->dragImage = WMRetainPixmap(dragImage); + + WMSetViewDragSourceProcs(view, dragSourceProcs); + + WMCreateDragHandler(view, dragImageHandler, view); +} + + +void +WMUnsetViewDraggable(WMView *view) +{ + if (view->dragSourceProcs) { + wfree(view->dragSourceProcs); + view->dragSourceProcs = NULL; + } + + WMReleaseViewDragImage(view); + + WMDeleteDragHandler(view, dragImageHandler, view); +} + + diff --git a/WINGs/proplist.c b/WINGs/proplist.c index fa167dc4..df942630 100644 --- a/WINGs/proplist.c +++ b/WINGs/proplist.c @@ -865,7 +865,7 @@ getPropList(PLData *pldata) break; case '(': - DPUT("Getting PropList srrsy"); + DPUT("Getting PropList array"); plist = getPLArray(pldata); break; diff --git a/WINGs/wcolorwell.c b/WINGs/wcolorwell.c index 5dcfa04f..d955463a 100644 --- a/WINGs/wcolorwell.c +++ b/WINGs/wcolorwell.c @@ -4,6 +4,7 @@ #include "WINGsP.h" +#define XDND_COLOR_DATA_TYPE "application/X-color" char *WMColorWellDidChangeNotification = "WMColorWellDidChangeNotification"; @@ -11,7 +12,7 @@ char *WMColorWellDidChangeNotification = "WMColorWellDidChangeNotification"; typedef struct W_ColorWell { W_Class widgetClass; WMView *view; - + WMView *colorView; WMColor *color; @@ -22,9 +23,11 @@ typedef struct W_ColorWell { WMPoint ipoint; struct { - unsigned int active:1; - unsigned int bordered:1; + unsigned int active:1; + unsigned int bordered:1; } flags; + + WMArray *xdndTypes; } ColorWell; static char *_ColorWellActivatedNotification = "_ColorWellActivatedNotification"; @@ -53,33 +56,36 @@ W_ViewDelegate _ColorWellViewDelegate = { }; -static unsigned draggingSourceOperation(WMView *self, Bool local); - +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 = { - draggingSourceOperation, + dropDataTypes, + wantedDropOperation, + NULL, + acceptDropOperation, NULL, NULL, fetchDragData }; -static unsigned draggingEntered(WMView *self, WMDraggingInfo *info); -static unsigned draggingUpdated(WMView *self, WMDraggingInfo *info); -static void draggingExited(WMView *self, WMDraggingInfo *info); -static char *prepareForDragOperation(WMView *self, WMDraggingInfo *info); -static Bool performDragOperation(WMView *self, WMDraggingInfo *info, - WMData *data); -static void concludeDragOperation(WMView *self, WMDraggingInfo *info); +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 = { - draggingEntered, - draggingUpdated, - draggingExited, - prepareForDragOperation, - performDragOperation, - concludeDragOperation + NULL, + requiredDataTypes, + allowedOperation, + NULL, + performDragOperation , + NULL }; @@ -100,10 +106,10 @@ colorChangedObserver(void *data, WMNotification *notification) WMColor *color; if (!cPtr->flags.active) - return; + return; color = WMGetColorPanelColor(panel); - + WMSetColorWellColor(cPtr, color); WMPostNotificationName(WMColorWellDidChangeNotification, cPtr, NULL); } @@ -126,21 +132,30 @@ updateColorCallback(void *self, void *data) static void activatedObserver(void *data, WMNotification *notification) { -/* - WMColorWell *cPtr = (WMColorWell*)data; + /* + WMColorWell *cPtr = (WMColorWell*)data; - if (!cPtr->flags.active || WMGetNotificationObject(notification) == cPtr) - return; + if (!cPtr->flags.active || WMGetNotificationObject(notification) == cPtr) + return; - W_SetViewBackgroundColor(cPtr->view, WMWidgetScreen(cPtr)->gray); - paintColorWell(cPtr); + W_SetViewBackgroundColor(cPtr->view, WMWidgetScreen(cPtr)->gray); + paintColorWell(cPtr); - cPtr->flags.active = 0; - */ + cPtr->flags.active = 0; + */ } +static WMArray* +getXdndTypeArray() +{ + WMArray *types = WMCreateArray(1); + WMAddToArray(types, XDND_COLOR_DATA_TYPE); + return types; +} + + WMColorWell* WMCreateColorWell(WMWidget *parent) { @@ -150,11 +165,11 @@ WMCreateColorWell(WMWidget *parent) memset(cPtr, 0, sizeof(ColorWell)); cPtr->widgetClass = WC_ColorWell; - + cPtr->view = W_CreateView(W_VIEW(parent)); if (!cPtr->view) { - wfree(cPtr); - return NULL; + wfree(cPtr); + return NULL; } cPtr->view->self = cPtr; @@ -162,22 +177,21 @@ WMCreateColorWell(WMWidget *parent) cPtr->colorView = W_CreateView(cPtr->view); if (!cPtr->colorView) { - W_DestroyView(cPtr->view); - wfree(cPtr); - return NULL; + W_DestroyView(cPtr->view); + wfree(cPtr); + return NULL; } cPtr->colorView->self = cPtr; WMCreateEventHandler(cPtr->view, ExposureMask|StructureNotifyMask - |ClientMessageMask, handleEvents, cPtr); + |ClientMessageMask, handleEvents, cPtr); WMCreateEventHandler(cPtr->colorView, ExposureMask, handleEvents, cPtr); - WMCreateEventHandler(cPtr->colorView, ButtonPressMask|ButtonMotionMask - |EnterWindowMask, handleDragEvents, cPtr); + WMCreateDragHandler(cPtr->colorView, handleDragEvents, cPtr); - WMCreateEventHandler(cPtr->view, ButtonPressMask, handleActionEvents, - cPtr); + WMCreateEventHandler(cPtr->view, ButtonPressMask, handleActionEvents, + cPtr); cPtr->colorView->flags.mapWhenRealized = 1; @@ -185,22 +199,19 @@ WMCreateColorWell(WMWidget *parent) W_ResizeView(cPtr->view, DEFAULT_WIDTH, DEFAULT_HEIGHT); - WMAddNotificationObserver(activatedObserver, cPtr, - _ColorWellActivatedNotification, NULL); + WMAddNotificationObserver(activatedObserver, cPtr, + _ColorWellActivatedNotification, NULL); cPtr->color = WMBlackColor(WMWidgetScreen(cPtr)); WMAddNotificationObserver(colorChangedObserver, cPtr, - WMColorPanelColorChangedNotification, NULL); + WMColorPanelColorChangedNotification, NULL); WMSetViewDragSourceProcs(cPtr->colorView, &_DragSourceProcs); WMSetViewDragDestinationProcs(cPtr->colorView, &_DragDestinationProcs); - { - char *types[2] = {"application/X-color", NULL}; - - WMRegisterViewForDraggedTypes(cPtr->colorView, types); - } + cPtr->xdndTypes = getXdndTypeArray(); + WMRegisterViewForDraggedTypes(cPtr->colorView, cPtr->xdndTypes); return cPtr; } @@ -210,12 +221,12 @@ void WMSetColorWellColor(WMColorWell *cPtr, WMColor *color) { if (cPtr->color) - WMReleaseColor(cPtr->color); - + WMReleaseColor(cPtr->color); + cPtr->color = WMRetainColor(color); - + if (cPtr->colorView->flags.realized && cPtr->colorView->flags.mapped) - paintColorWell(cPtr); + paintColorWell(cPtr); } @@ -231,36 +242,36 @@ 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); + 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) + 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; + if (*width < MIN_WIDTH) + *width = MIN_WIDTH; + if (*height < MIN_HEIGHT) + *height = MIN_HEIGHT; - bw = (int)((float)WMIN(*width, *height)*0.24); + bw = (int)((float)WMIN(*width, *height)*0.24); - W_ResizeView(cPtr->colorView, *width-2*bw, *height-2*bw); + 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); + 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); + W_MoveView(cPtr->colorView, 0, 0); } } @@ -271,16 +282,16 @@ 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); + 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); + WMPaintColorSwatch(cPtr->color, cPtr->colorView->window, + 2, 2, cPtr->colorView->size.width-4, + cPtr->colorView->size.height-4); } @@ -293,38 +304,51 @@ handleEvents(XEvent *event, void *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; - + switch (event->type) { + case Expose: + if (event->xexpose.count!=0) + break; + paintColorWell(cPtr); + break; + + case DestroyNotify: + destroyColorWell(cPtr); + break; + } } -static unsigned -draggingSourceOperation(WMView *self, Bool local) +static WMArray* +dropDataTypes(WMView *self) +{ + return ((ColorWell*)self->self)->xdndTypes; +} + + +static WMDragOperationType +wantedDropOperation(WMView *self) { return WDOperationCopy; } -static WMData* +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; } @@ -334,13 +358,13 @@ 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); } @@ -350,36 +374,12 @@ handleDragEvents(XEvent *event, void *data) { WMColorWell *cPtr = (ColorWell*)data; - switch (event->type) { - case ButtonPress: - if (event->xbutton.button == Button1) { - cPtr->ipoint.x = event->xbutton.x; - cPtr->ipoint.y = event->xbutton.y; - } - break; - - case MotionNotify: - if (event->xmotion.state & Button1Mask) { - if (abs(cPtr->ipoint.x - event->xmotion.x) > 4 - || abs(cPtr->ipoint.y - event->xmotion.y) > 4) { - WMSize offs; - WMPixmap *pixmap; - char *types[2] = {"application/X-color", NULL}; - - offs.width = 2; - offs.height = 2; - pixmap = makeDragPixmap(cPtr); - - WMDragImageFromView(cPtr->colorView, pixmap, types, - wmkpoint(event->xmotion.x_root, - event->xmotion.y_root), - offs, event, True); - - WMReleasePixmap(pixmap); - } - } - break; + if (event->type == ButtonPress && event->xbutton.button == Button1) { + /* initialise drag icon */ + WMSetViewDragImage(cPtr->colorView, makeDragPixmap(cPtr)); } + + WMDragImageFromView(cPtr->colorView, event); } @@ -389,24 +389,24 @@ 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); + W_SetViewBackgroundColor(cPtr->view, scr->gray); else - W_SetViewBackgroundColor(cPtr->view, scr->white); + W_SetViewBackgroundColor(cPtr->view, scr->white); paintColorWell(cPtr); cPtr->flags.active ^= 1; if (cPtr->flags.active) { - WMPostNotificationName(_ColorWellActivatedNotification, cPtr, NULL); + WMPostNotificationName(_ColorWellActivatedNotification, cPtr, NULL); } cpanel = WMGetColorPanel(scr); WMSetColorPanelAction(cpanel, updateColorCallback, cPtr); if (cPtr->color) - WMSetColorPanelColor(cpanel, cPtr->color); + WMSetColorPanelColor(cpanel, cPtr->color); WMShowColorPanel(cpanel); } @@ -417,58 +417,69 @@ destroyColorWell(ColorWell *cPtr) WMRemoveNotificationObserver(cPtr); if (cPtr->color) - WMReleaseColor(cPtr->color); + WMReleaseColor(cPtr->color); + + WMFreeArray(cPtr->xdndTypes); wfree(cPtr); } - -static unsigned -draggingEntered(WMView *self, WMDraggingInfo *info) +static Bool +dropIsOk(WMDragOperationType request, WMArray *sourceDataTypes) { - return WDOperationCopy; -} - + 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; + } + } + } -static unsigned -draggingUpdated(WMView *self, WMDraggingInfo *info) -{ - return WDOperationCopy; + return False; } -static void -draggingExited(WMView *self, WMDraggingInfo *info) +static WMArray* +requiredDataTypes(WMView *self, WMDragOperationType request, WMArray *sourceDataTypes) { - + if (dropIsOk(request, sourceDataTypes)) + return ((ColorWell*)self->self)->xdndTypes; + else + return NULL; } -static char* -prepareForDragOperation(WMView *self, WMDraggingInfo *info) +static WMDragOperationType +allowedOperation(WMView *self, WMDragOperationType request, WMArray *sourceDataTypes) { - return "application/X-color"; + if (dropIsOk(request, sourceDataTypes)) + return WDOperationCopy; + else + return WDOperationNone; } -static Bool -performDragOperation(WMView *self, WMDraggingInfo *info, WMData *data) +static void +performDragOperation(WMView *self, WMArray *dropData, WMArray *operations, + WMPoint* dropLocation) { - char *colorName = (char*)WMDataBytes(data); + char *colorName; WMColor *color; - - color = WMCreateNamedColor(W_VIEW_SCREEN(self), colorName, True); - - WMSetColorWellColor(self->self, color); - - WMReleaseColor(color); - - return True; -} + WMData* data; + /* only one operation requested (WDOperationCopy) implies only one data */ + data = (WMData*)WMGetFromArray(dropData, 0); -static void -concludeDragOperation(WMView *self, WMDraggingInfo *info) -{ + if (data != NULL) { + colorName = (char*)WMDataBytes(data); + color = WMCreateNamedColor(W_VIEW_SCREEN(self), colorName, True); + WMSetColorWellColor(self->self, color); + WMReleaseColor(color); + } } + + diff --git a/WINGs/wevent.c b/WINGs/wevent.c index 82e0c87c..28cd4e0e 100644 --- a/WINGs/wevent.c +++ b/WINGs/wevent.c @@ -63,20 +63,20 @@ static WMEventHook *extraEventHandler=NULL; * Create an event handler and put it in the event handler list for the * view. If the same callback and clientdata are already used in another * handler, the masks are OR'ed. - * + * */ void -WMCreateEventHandler(WMView *view, unsigned long mask, WMEventProc *eventProc, - void *clientData) + WMCreateEventHandler(WMView *view, unsigned long mask, WMEventProc *eventProc, + void *clientData) { W_EventHandler *hPtr; WMArrayIterator iter; WM_ITERATE_ARRAY(view->eventHandlers, hPtr, iter) { - if (hPtr->clientData==clientData && hPtr->proc==eventProc) { + if (hPtr->clientData==clientData && hPtr->proc==eventProc) { hPtr->eventMask |= mask; return; - } + } } hPtr = wmalloc(sizeof(W_EventHandler)); @@ -105,11 +105,11 @@ matchHandler(void *item, void *cdata) * WMDeleteEventHandler-- * Delete event handler matching arguments from windows * event handler list. - * + * */ void -WMDeleteEventHandler(WMView *view, unsigned long mask, WMEventProc *eventProc, - void *clientData) +WMDeleteEventHandler(WMView *view, unsigned long mask, WMEventProc *eventProc, + void *clientData) { W_EventHandler tmp; @@ -124,27 +124,27 @@ static Time getEventTime(WMScreen *screen, XEvent *event) { switch (event->type) { - case ButtonPress: - case ButtonRelease: - return event->xbutton.time; - case KeyPress: - case KeyRelease: - return event->xkey.time; - case MotionNotify: - return event->xmotion.time; - case EnterNotify: - case LeaveNotify: - return event->xcrossing.time; - case PropertyNotify: - return event->xproperty.time; - case SelectionClear: - return event->xselectionclear.time; - case SelectionRequest: - return event->xselectionrequest.time; - case SelectionNotify: - return event->xselection.time; - default: - return screen->lastEventTime; + case ButtonPress: + case ButtonRelease: + return event->xbutton.time; + case KeyPress: + case KeyRelease: + return event->xkey.time; + case MotionNotify: + return event->xmotion.time; + case EnterNotify: + case LeaveNotify: + return event->xcrossing.time; + case PropertyNotify: + return event->xproperty.time; + case SelectionClear: + return event->xselectionclear.time; + case SelectionRequest: + return event->xselectionrequest.time; + case SelectionNotify: + return event->xselection.time; + default: + return screen->lastEventTime; } } @@ -162,9 +162,9 @@ W_CallDestroyHandlers(W_View *view) event.xdestroywindow.event = view->window; WM_ITERATE_ARRAY(view->eventHandlers, hPtr, iter) { - if (hPtr->eventMask & StructureNotifyMask) { - (*hPtr->proc)(&event, hPtr->clientData); - } + if (hPtr->eventMask & StructureNotifyMask) { + (*hPtr->proc)(&event, hPtr->clientData); + } } } @@ -175,7 +175,7 @@ WMSetViewNextResponder(WMView *view, WMView *responder) { /* set the widget to receive keyboard events that aren't handled * by this widget */ - + view->nextResponder = responder; } @@ -186,15 +186,15 @@ WMRelayToNextResponder(WMView *view, XEvent *event) unsigned long mask = eventMasks[event->xany.type]; if (view->nextResponder) { - WMView *next = view->nextResponder; - W_EventHandler *hPtr; - WMArrayIterator iter; + WMView *next = view->nextResponder; + W_EventHandler *hPtr; + WMArrayIterator iter; WM_ITERATE_ARRAY(next->eventHandlers, hPtr, iter) { - if ((hPtr->eventMask & mask)) { - (*hPtr->proc)(event, hPtr->clientData); - } - } + if ((hPtr->eventMask & mask)) { + (*hPtr->proc)(event, hPtr->clientData); + } + } } } @@ -209,28 +209,28 @@ WMHandleEvent(XEvent *event) WMArrayIterator iter; if (event->type == MappingNotify) { - XRefreshKeyboardMapping(&event->xmapping); - return True; + XRefreshKeyboardMapping(&event->xmapping); + return True; } mask = eventMasks[event->xany.type]; - + window = event->xany.window; /* diferentiate SubstructureNotify with StructureNotify */ if (mask == StructureNotifyMask) { - if (event->xmap.event != event->xmap.window) { - mask = SubstructureNotifyMask; - window = event->xmap.event; - } + if (event->xmap.event != event->xmap.window) { + mask = SubstructureNotifyMask; + window = event->xmap.event; + } } view = W_GetViewForXWindow(event->xany.display, window); if (!view) { - if (extraEventHandler) - (extraEventHandler)(event); + if (extraEventHandler) + (extraEventHandler)(event); - return False; + return False; } view->screen->lastEventTime = getEventTime(view->screen, event); @@ -238,22 +238,19 @@ WMHandleEvent(XEvent *event) toplevel = W_TopLevelOfView(view); if (event->type == SelectionNotify || event->type == SelectionClear - || event->type == SelectionRequest) { - /* handle selection related events */ - W_HandleSelectionEvent(event); - - } else if (event->type == ClientMessage) { - - W_HandleDNDClientMessage(toplevel, &event->xclient); + || event->type == SelectionRequest) { + /* handle selection related events */ + W_HandleSelectionEvent(event); + } /* if it's a key event, redispatch it to the focused control */ if (mask & (KeyPressMask|KeyReleaseMask)) { - W_View *focused = W_FocusedViewOfToplevel(toplevel); - - if (focused) { - view = focused; - } + W_View *focused = W_FocusedViewOfToplevel(toplevel); + + if (focused) { + view = focused; + } } /* compress Motion events */ @@ -261,37 +258,37 @@ WMHandleEvent(XEvent *event) while (XPending(event->xmotion.display)) { XEvent ev; XPeekEvent(event->xmotion.display, &ev); - if (ev.type == MotionNotify - && event->xmotion.window == ev.xmotion.window - && event->xmotion.subwindow == ev.xmotion.subwindow) { - /* replace events */ + if (ev.type == MotionNotify + && event->xmotion.window == ev.xmotion.window + && event->xmotion.subwindow == ev.xmotion.subwindow) { + /* replace events */ XNextEvent(event->xmotion.display, event); } else break; } } - + /* compress expose events */ if (event->type == Expose && !view->flags.dontCompressExpose) { while (XCheckTypedWindowEvent(event->xexpose.display, view->window, - Expose, event)); + Expose, event)); } if (view->screen->modalLoop && toplevel!=view->screen->modalView - && !toplevel->flags.worksWhenModal) { - if (event->type == KeyPress || event->type == KeyRelease - || event->type == MotionNotify || event->type == ButtonPress - || event->type == ButtonRelease - || event->type == FocusIn || event->type == FocusOut) { - return True; - } + && !toplevel->flags.worksWhenModal) { + if (event->type == KeyPress || event->type == KeyRelease + || event->type == MotionNotify || event->type == ButtonPress + || event->type == ButtonRelease + || event->type == FocusIn || event->type == FocusOut) { + return True; + } } /* do balloon stuffs */ if (event->type == EnterNotify) - W_BalloonHandleEnterView(view); + W_BalloonHandleEnterView(view); else if (event->type == LeaveNotify) - W_BalloonHandleLeaveView(view); + W_BalloonHandleLeaveView(view); /* This is a hack. It will make the panel be secure while * the event handlers are handled, as some event handler @@ -299,33 +296,38 @@ WMHandleEvent(XEvent *event) W_RetainView(toplevel); WM_ITERATE_ARRAY(view->eventHandlers, hPtr, iter) { - if ((hPtr->eventMask & mask)) { - (*hPtr->proc)(event, hPtr->clientData); - } + if ((hPtr->eventMask & mask)) { + (*hPtr->proc)(event, hPtr->clientData); + } } #if 0 /* pass the event to the top level window of the widget */ /* TODO: change this to a responder chain */ if (view->parent != NULL) { - vPtr = view; - while (vPtr->parent != NULL) - vPtr = vPtr->parent; - - WM_ITERATE_ARRAY(vPtr->eventHandlers, hPtr, iter) { - if (hPtr->eventMask & mask) { - (*hPtr->proc)(event, hPtr->clientData); - } - } + vPtr = view; + while (vPtr->parent != NULL) + vPtr = vPtr->parent; + + WM_ITERATE_ARRAY(vPtr->eventHandlers, hPtr, iter) { + if (hPtr->eventMask & mask) { + (*hPtr->proc)(event, hPtr->clientData); + } + } } #endif /* save button click info to track double-clicks */ if (view->screen->ignoreNextDoubleClick) { - view->screen->ignoreNextDoubleClick = 0; + view->screen->ignoreNextDoubleClick = 0; } else { - if (event->type == ButtonPress) { - view->screen->lastClickWindow = event->xbutton.window; - view->screen->lastClickTime = event->xbutton.time; - } + if (event->type == ButtonPress) { + view->screen->lastClickWindow = event->xbutton.window; + view->screen->lastClickTime = event->xbutton.time; + } + } + + if (event->type == ClientMessage) { + /* must be handled at the end, for such message can destroy the view */ + W_HandleDNDClientMessage(toplevel, &event->xclient); } W_ReleaseView(toplevel); @@ -338,26 +340,26 @@ int WMIsDoubleClick(XEvent *event) { W_View *view; - + if (event->type != ButtonPress) - return False; - + return False; + view = W_GetViewForXWindow(event->xany.display, event->xbutton.window); if (!view) - return False; - + return False; + if (view->screen->lastClickWindow != event->xbutton.window) - return False; - - if (event->xbutton.time - view->screen->lastClickTime - < WINGsConfiguration.doubleClickDelay) { - view->screen->lastClickTime = 0; - view->screen->lastClickWindow = None; - view->screen->ignoreNextDoubleClick = 1; - return True; + return False; + + if (event->xbutton.time - view->screen->lastClickTime + < WINGsConfiguration.doubleClickDelay) { + view->screen->lastClickTime = 0; + view->screen->lastClickWindow = None; + view->screen->ignoreNextDoubleClick = 1; + return True; } else - return False; + return False; } @@ -381,14 +383,14 @@ waitForEvent(Display *dpy, unsigned long xeventmask, Bool waitForInput) { XSync(dpy, False); if (xeventmask==0) { - if (XPending(dpy)) - return True; + if (XPending(dpy)) + return True; } else { - XEvent ev; - if (XCheckMaskEvent(dpy, xeventmask, &ev)) { - XPutBackEvent(dpy, &ev); - return True; - } + XEvent ev; + if (XCheckMaskEvent(dpy, xeventmask, &ev)) { + XPutBackEvent(dpy, &ev); + return True; + } } return W_HandleInputEvents(waitForInput, ConnectionNumber(dpy)); @@ -402,19 +404,19 @@ WMNextEvent(Display *dpy, XEvent *event) W_CheckTimerHandlers(); while (XPending(dpy) == 0) { - /* Do idle and timer stuff while there are no input or X events */ - while (!waitForEvent(dpy, 0, False) && W_CheckIdleHandlers()) { - /* dispatch timer events */ + /* Do idle and timer stuff while there are no input or X events */ + while (!waitForEvent(dpy, 0, False) && W_CheckIdleHandlers()) { + /* dispatch timer events */ W_CheckTimerHandlers(); - } + } - /* - * Make sure that new events did not arrive while we were doing - * timer/idle stuff. Or we might block forever waiting for - * an event that already arrived. - */ - /* wait for something to happen or a timer to expire */ - waitForEvent(dpy, 0, True); + /* + * Make sure that new events did not arrive while we were doing + * timer/idle stuff. Or we might block forever waiting for + * an event that already arrived. + */ + /* wait for something to happen or a timer to expire */ + waitForEvent(dpy, 0, True); /* Check any expired timers */ W_CheckTimerHandlers(); @@ -431,16 +433,16 @@ WMMaskEvent(Display *dpy, long mask, XEvent *event) W_CheckTimerHandlers(); while (!XCheckMaskEvent(dpy, mask, event)) { - /* Do idle and timer stuff while there are no input or X events */ + /* Do idle and timer stuff while there are no input or X events */ while (!waitForEvent(dpy, mask, False) && W_CheckIdleHandlers()) { W_CheckTimerHandlers(); - } + } if (XCheckMaskEvent(dpy, mask, event)) return; /* Wait for input on the X connection socket or another input handler */ - waitForEvent(dpy, mask, True); + waitForEvent(dpy, mask, True); /* Check any expired timers */ W_CheckTimerHandlers(); @@ -452,9 +454,9 @@ Bool WMScreenPending(WMScreen *scr) { if (XPending(scr->display)) - return True; + return True; else - return False; + return False; } @@ -462,9 +464,9 @@ WMEventHook* WMHookEventHandler(WMEventHook *handler) { WMEventHook *oldHandler = extraEventHandler; - + extraEventHandler = handler; - + return oldHandler; } diff --git a/WINGs/wfont.c b/WINGs/wfont.c index 54af9df5..6acc278d 100644 --- a/WINGs/wfont.c +++ b/WINGs/wfont.c @@ -149,8 +149,8 @@ alreadyHasStringValue(XftPattern *pattern, const char *object, char *value) return True; id = 0; - while ((r=XftPatternGetString(pattern, object, id, &s))!=XftResultNoId) { - if (r == XftResultMatch && strcasecmp(value, s) == 0) { + while ((r=XftPatternGetString(pattern, object, id, &s))==XftResultMatch) { + if (strcasecmp(value, s) == 0) { return True; } id++; @@ -165,23 +165,21 @@ alreadyHasStringValue(XftPattern *pattern, const char *object, char *value) static char* makeFontOfSize(char *font, int size, char *fallback) { - XftPattern *pattern; + FcPattern *pattern; char *result; - int len; - len = strlen(font) + 64; pattern = XftNameParse(font); XftPatternDel(pattern, "pixelsize"); XftPatternAddDouble(pattern, "pixelsize", (double)size); + if (fallback) { if (!alreadyHasStringValue(pattern, "family", fallback)) { - len += strlen(fallback); XftPatternAddString(pattern, "family", fallback); } } - result = wmalloc(len); - XftNameUnparse(pattern, result, len); - XftPatternDestroy(pattern); + + result = FcNameUnparse(pattern); + FcPatternDestroy(pattern); return result; } @@ -198,17 +196,17 @@ WMCreateFont(WMScreen *scrPtr, char *fontName) if (fontName[0]=='-' && (ptr = strchr(fontName, ','))) { // warn for deprecation fname = wmalloc(ptr - fontName + 1); - strncpy(fname, fontName, ptr - fontName); - fname[ptr - fontName] = 0; + strncpy(fname, fontName, ptr - fontName); + fname[ptr - fontName] = 0; } else { - fname = wstrdup(fontName); + fname = wstrdup(fontName); } font = WMHashGet(scrPtr->fontCache, fname); if (font) { - WMRetainFont(font); - wfree(fname); - return font; + WMRetainFont(font); + wfree(fname); + return font; } font = wmalloc(sizeof(WMFont)); @@ -217,7 +215,7 @@ WMCreateFont(WMScreen *scrPtr, char *fontName) font->screen = scrPtr; // remove - printf("%s\n", fname); + printf("WMCreateFont: %s\n", fname); if (fname[0] == '-') { // Backward compat thing. Remove in a later version @@ -264,9 +262,9 @@ WMReleaseFont(WMFont *font) XftFontClose(font->screen->display, font->font); if (font->name) { WMHashRemove(font->screen->fontCache, font->name); - wfree(font->name); - } - wfree(font); + wfree(font->name); + } + wfree(font); } } @@ -489,166 +487,50 @@ WMDrawImageString(WMScreen *scr, Drawable d, WMColor *color, WMColor *background WMFont* -WMCopyFontWithChanges(WMScreen *scrPtr, WMFont *font, - const WMFontAttributes *changes) -{ - int index[FONT_PROPS], count[FONT_PROPS]; - int totalProps, i, j, carry; - char fname[512]; - WMFontFlags fFlags; - WMBag *props; - WMArray *options; - WMFont *result; - char *prop; - - snprintf(fname, 512, "%s", font->name); - - fFlags = (font->antialiased ? WFAntialiased : WFNotAntialiased); - fFlags |= (font->notFontSet ? WFNormalFont : WFFontSet); - - props = WMCreateBagWithDestructor(1, (WMFreeDataProc*)WMFreeArray); - - totalProps = 0; - for (i=0; iprops[i]; - count[i] = index[i] = 0; - if (!prop) { - /* No change for this property */ - continue; - } else if (strchr(prop, ',')==NULL) { - /* Simple option */ - changeFontProp(fname, prop, i); - } else { - /* Option with fallback alternatives */ - if ((changes==WFAEmphasized || changes==WFABoldEmphasized) && - font->antialiased && strcmp(prop, "o,i")==0) { - options = getOptions("i,o"); - } else { - options = getOptions(prop); - } - WMInsertInBag(props, i, options); - count[i] = WMGetArrayItemCount(options); - if (totalProps==0) - totalProps = 1; - totalProps = totalProps * count[i]; - } - } - - if (totalProps == 0) { - /* No options with fallback alternatives at all */ - WMFreeBag(props); - return WMCreateFontWithFlags(scrPtr, fname, fFlags); - } - - for (i=0; i=0; j--) { - if (count[j]!=0) { - index[j] += carry; - carry = (index[j]==count[j]); - index[j] %= count[j]; - } - } - } - - WMFreeBag(props); - - return NULL; -} - - -#if 0 - -#define FONT_PROPS 14 - -typedef struct { - char *props[FONT_PROPS]; -} W_FontAttributes; - - -static void -changeFontProp(char *buf, char *newprop, int position) +WMCopyFontWithStyle(WMScreen *scrPtr, WMFont *font, WMFontStyle style) { - char buf2[512]; - char *ptr, *pptr, *rptr; - int count; + FcPattern *pattern; + WMFont *copy; + char *name; - if (buf[0]!='-') { - /* // remove warning later. or maybe not */ - wwarning(_("Invalid font specification: '%s'\n"), buf); - return; - } + if (!font) + return NULL; - ptr = pptr = rptr = buf; - count = 0; - while (*ptr && *ptr!=',') { - if (*ptr == '-') { - count++; - if (count-1==position+1) { - rptr = ptr; - break; - } - if (count-1==position) { - pptr = ptr+1; - } - } - ptr++; - } - if (position==FONT_PROPS-1) { - rptr = ptr; + pattern = XftNameParse(WMGetFontName(font)); + switch (style) { + case WFSNormal: + XftPatternDel(pattern, "weight"); + XftPatternDel(pattern, "slant"); + XftPatternAddString(pattern, "weight", "medium"); + XftPatternAddString(pattern, "slant", "roman"); + break; + case WFSBold: + XftPatternDel(pattern, "weight"); + XftPatternAddString(pattern, "weight", "bold"); + break; + case WFSEmphasized: + XftPatternDel(pattern, "slant"); + XftPatternAddString(pattern, "slant", "italic"); + XftPatternAddString(pattern, "slant", "oblique"); + break; + case WFSBoldEmphasized: + XftPatternDel(pattern, "weight"); + XftPatternDel(pattern, "slant"); + XftPatternAddString(pattern, "weight", "bold"); + XftPatternAddString(pattern, "slant", "italic"); + XftPatternAddString(pattern, "slant", "oblique"); + break; } - *pptr = 0; - snprintf(buf2, 512, "%s%s%s", buf, newprop, rptr); - strcpy(buf, buf2); -} - - -static WMArray* -getOptions(char *options) -{ - char *ptr, *ptr2, *str; - WMArray *result; - int count; - - result = WMCreateArrayWithDestructor(2, (WMFreeDataProc*)wfree); - - ptr = options; - while (1) { - ptr2 = strchr(ptr, ','); - if (!ptr2) { - WMAddToArray(result, wstrdup(ptr)); - break; - } else { - count = ptr2 - ptr; - str = wmalloc(count+1); - memcpy(str, ptr, count); - str[count] = 0; - WMAddToArray(result, str); - ptr = ptr2 + 1; - } - } + name = FcNameUnparse(pattern); + copy = WMCreateFont(scrPtr, name); + FcPatternDestroy(pattern); + wfree(name); - return result; + return copy; } -#endif - - #else /* No XFT support */ @@ -662,18 +544,18 @@ getElementFromXLFD(const char *xlfd, int index) { const char *p = xlfd; while (*p != 0) { - if (*p == '-' && --index == 0) { - const char *end = strchr(p + 1, '-'); - char *buf; - size_t len; - if (end == 0) end = p + strlen(p); - len = end - (p + 1); - buf = wmalloc(len); - memcpy(buf, p + 1, len); - buf[len] = 0; - return buf; - } - p++; + if (*p == '-' && --index == 0) { + const char *end = strchr(p + 1, '-'); + char *buf; + size_t len; + if (end == 0) end = p + strlen(p); + len = end - (p + 1); + buf = wmalloc(len); + memcpy(buf, p + 1, len); + buf[len] = 0; + return buf; + } + p++; } return strdup("*"); } @@ -695,8 +577,8 @@ generalizeXLFD(const char *xlfd) buf = wmalloc(len + 1); snprintf(buf, len + 1, "%s,-*-*-%s-%s-*-*-%s-*-*-*-*-*-*-*," - "-*-*-*-*-*-*-%s-*-*-*-*-*-*-*,*", - xlfd, weight, slant, pxlsz, pxlsz); + "-*-*-*-*-*-*-%s-*-*-*-*-*-*-*,*", + xlfd, weight, slant, pxlsz, pxlsz); wfree(pxlsz); wfree(slant); @@ -708,27 +590,27 @@ generalizeXLFD(const char *xlfd) /* XLFD pattern matching */ static XFontSet W_CreateFontSetWithGuess(Display *dpy, char *xlfd, char ***missing, - int *nmissing, char **def_string) + int *nmissing, char **def_string) { XFontSet fs = XCreateFontSet(dpy, xlfd, missing, nmissing, def_string); if (fs != NULL && *nmissing == 0) return fs; /* for non-iso8859-1 language and iso8859-1 specification - (this fontset is only for pattern analysis) */ + (this fontset is only for pattern analysis) */ if (fs == NULL) { - if (*nmissing != 0) XFreeStringList(*missing); - setlocale(LC_CTYPE, "C"); - fs = XCreateFontSet(dpy, xlfd, missing, nmissing, def_string); - setlocale(LC_CTYPE, ""); + if (*nmissing != 0) XFreeStringList(*missing); + setlocale(LC_CTYPE, "C"); + fs = XCreateFontSet(dpy, xlfd, missing, nmissing, def_string); + setlocale(LC_CTYPE, ""); } /* make XLFD font name for pattern analysis */ if (fs != NULL) { - XFontStruct **fontstructs; - char **fontnames; - if (XFontsOfFontSet(fs, &fontstructs, &fontnames) > 0) - xlfd = fontnames[0]; + XFontStruct **fontstructs; + char **fontnames; + if (XFontsOfFontSet(fs, &fontstructs, &fontnames) > 0) + xlfd = fontnames[0]; } xlfd = generalizeXLFD(xlfd); @@ -805,7 +687,7 @@ WMCreateFontSet(WMScreen *scrPtr, char *fontName) if (font) { WMRetainFont(font); wfree(fname); - return font; + return font; } font = wmalloc(sizeof(WMFont)); @@ -819,21 +701,21 @@ WMCreateFontSet(WMScreen *scrPtr, char *fontName) font->font.set = W_CreateFontSetWithGuess(display, fname, &missing, &nmissing, &defaultString); if (nmissing > 0 && font->font.set) { - int i; - - wwarning(_("the following character sets are missing in %s:"), fname); - for (i = 0; i < nmissing; i++) { - wwarning(missing[i]); - } - XFreeStringList(missing); - if (defaultString) - wwarning(_("the string \"%s\" will be used in place of any characters from those sets."), - defaultString); + int i; + + wwarning(_("the following character sets are missing in %s:"), fname); + for (i = 0; i < nmissing; i++) { + wwarning(missing[i]); + } + XFreeStringList(missing); + if (defaultString) + wwarning(_("the string \"%s\" will be used in place of any characters from those sets."), + defaultString); } if (!font->font.set) { wfree(font); wfree(fname); - return NULL; + return NULL; } extents = XExtentsOfFontSet(font->font.set); @@ -862,20 +744,20 @@ WMCreateNormalFont(WMScreen *scrPtr, char *fontName) fontName = xlfdFromFontName(fontName, False); if ((ptr = strchr(fontName, ','))) { - fname = wmalloc(ptr - fontName + 1); - strncpy(fname, fontName, ptr - fontName); - fname[ptr - fontName] = 0; + fname = wmalloc(ptr - fontName + 1); + strncpy(fname, fontName, ptr - fontName); + fname[ptr - fontName] = 0; } else { - fname = wstrdup(fontName); + fname = wstrdup(fontName); } wfree(fontName); font = WMHashGet(scrPtr->fontCache, fname); if (font) { - WMRetainFont(font); - wfree(fname); - return font; + WMRetainFont(font); + wfree(fname); + return font; } font = wmalloc(sizeof(WMFont)); @@ -916,20 +798,20 @@ WMCreateAntialiasedFont(WMScreen *scrPtr, char *fontName) fontName = xlfdFromFontName(fontName, True); if ((ptr = strchr(fontName, ','))) { - fname = wmalloc(ptr - fontName + 1); - strncpy(fname, fontName, ptr - fontName); - fname[ptr - fontName] = 0; + fname = wmalloc(ptr - fontName + 1); + strncpy(fname, fontName, ptr - fontName); + fname[ptr - fontName] = 0; } else { - fname = wstrdup(fontName); + fname = wstrdup(fontName); } wfree(fontName); font = WMHashGet(scrPtr->xftFontCache, fname); if (font) { - WMRetainFont(font); - wfree(fname); - return font; + WMRetainFont(font); + wfree(fname); + return font; } font = wmalloc(sizeof(WMFont)); @@ -993,19 +875,19 @@ WMCreateAntialiasedFontSet(WMScreen *scrPtr, char *fontName) if ((ptr = strchr(fontName, ','))) { fname = wmalloc(ptr - fontName + 1); - strncpy(fname, fontName, ptr - fontName); - fname[ptr - fontName] = 0; + strncpy(fname, fontName, ptr - fontName); + fname[ptr - fontName] = 0; } else { - fname = wstrdup(fontName); + fname = wstrdup(fontName); } wfree(fontName); font = WMHashGet(scrPtr->xftFontSetCache, fname); if (font) { - WMRetainFont(font); - wfree(fname); - return font; + WMRetainFont(font); + wfree(fname); + return font; } font = wmalloc(sizeof(WMFont)); @@ -1096,7 +978,7 @@ WMCreateFontWithFlags(WMScreen *scrPtr, char *fontName, WMFontFlags flags) font = WMCreateNormalFont(scrPtr, fontName); } } else if (multiByte) { - font = WMCreateFontSet(scrPtr, fontName); + font = WMCreateFontSet(scrPtr, fontName); } else { font = WMCreateNormalFont(scrPtr, fontName); } @@ -1145,9 +1027,9 @@ WMReleaseFont(WMFont *font) } else { WMHashRemove(font->screen->fontSetCache, font->name); } - wfree(font->name); - } - wfree(font); + wfree(font->name); + } + wfree(font); } } @@ -1401,7 +1283,7 @@ WMDrawString(WMScreen *scr, Drawable d, WMColor *color, WMFont *font, /* we can draw normal text, or we can draw as much widechar * text as was already converted until the error. go figure */ /*XftDrawString8(scr->xftdraw, &xftcolor, font->font.xft, - x, y + font->y, (XftChar8*)text, length);*/ + x, y + font->y, (XftChar8*)text, length);*/ } wfree(wtext); } else { @@ -1472,7 +1354,7 @@ WMDrawImageString(WMScreen *scr, Drawable d, WMColor *color, WMColor *background /* we can draw normal text, or we can draw as much widechar * text as was already converted until the error. go figure */ /*XftDrawString8(scr->xftdraw, &textColor, font->font.xft, - x, y + font->y, (XftChar8*)text, length);*/ + x, y + font->y, (XftChar8*)text, length);*/ } wfree(wtext); } else { @@ -1507,42 +1389,42 @@ makeFontSetOfSize(char *fontset, int size) char *ptr; do { - char *tmp; - int end; - - - f = fontset; - ptr = strchr(fontset, ','); - if (ptr) { - int count = ptr-fontset; - - if (count > 255) { - wwarning(_("font description %s is too large."), fontset); - } else { - memcpy(font, fontset, count); - font[count] = 0; - f = (char*)font; - } - } - - if (newfs) - end = strlen(newfs); - else - end = 0; - - tmp = wmalloc(end + strlen(f) + 8); - if (end != 0) { - sprintf(tmp, "%s,", newfs); - sprintf(tmp + end + 1, f, size); - } else { - sprintf(tmp + end, f, size); - } - - if (newfs) - wfree(newfs); - newfs = tmp; - - fontset = ptr+1; + char *tmp; + int end; + + + f = fontset; + ptr = strchr(fontset, ','); + if (ptr) { + int count = ptr-fontset; + + if (count > 255) { + wwarning(_("font description %s is too large."), fontset); + } else { + memcpy(font, fontset, count); + font[count] = 0; + f = (char*)font; + } + } + + if (newfs) + end = strlen(newfs); + else + end = 0; + + tmp = wmalloc(end + strlen(f) + 8); + if (end != 0) { + sprintf(tmp, "%s,", newfs); + sprintf(tmp + end + 1, f, size); + } else { + sprintf(tmp + end, f, size); + } + + if (newfs) + wfree(newfs); + newfs = tmp; + + fontset = ptr+1; } while (ptr!=NULL); return newfs; @@ -1623,6 +1505,25 @@ getOptions(char *options) } +#define WFAUnchanged (NULL) +/* Struct for font change operations */ +typedef struct WMFontAttributes { + char *foundry; + char *family; + char *weight; + char *slant; + char *setWidth; + char *addStyle; + char *pixelSize; + char *pointSize; + char *resolutionX; + char *resolutionY; + char *spacing; + char *averageWidth; + char *registry; + char *encoding; +} WMFontAttributes; + WMFont* WMCopyFontWithChanges(WMScreen *scrPtr, WMFont *font, const WMFontAttributes *changes) @@ -1704,9 +1605,6 @@ WMCopyFontWithChanges(WMScreen *scrPtr, WMFont *font, return NULL; } -#endif - - // should WFANormal also set "normal" or leave it alone? static const WMFontAttributes W_FANormal = { WFAUnchanged, WFAUnchanged, "medium,normal,regular", "r", "normal", @@ -1758,3 +1656,6 @@ const WMFontAttributes *WFANotEmphasized = &W_FANotEmphasized; const WMFontAttributes *WFABoldEmphasized = &W_FABoldEmphasized; +#endif + + diff --git a/WINGs/wframe.c b/WINGs/wframe.c index a41841ed..60d5959b 100644 --- a/WINGs/wframe.c +++ b/WINGs/wframe.c @@ -9,8 +9,8 @@ typedef struct W_Frame { char *caption; struct { - WMReliefType relief:4; - WMTitlePosition titlePosition:4; + WMReliefType relief:4; + WMTitlePosition titlePosition:4; } flags; } Frame; @@ -33,7 +33,7 @@ WMSetFrameTitlePosition(WMFrame *fPtr, WMTitlePosition position) fPtr->flags.titlePosition = position; if (fPtr->view->flags.realized) { - repaintFrame(fPtr); + repaintFrame(fPtr); } } @@ -98,101 +98,101 @@ paintFrame(Frame *fPtr) fh = view->size.height; fy = 0; - + switch (fPtr->flags.titlePosition) { - case WTPAboveTop: - ty = 0; - fy = th + 4; - fh = view->size.height - fy; - break; - - case WTPAtTop: - ty = 0; - fy = th/2; - fh = view->size.height - fy; - break; - - case WTPBelowTop: - ty = 4; - fy = 0; - fh = view->size.height; - break; - - case WTPAboveBottom: - ty = view->size.height - th - 4; - fy = 0; - fh = view->size.height; - break; - - case WTPAtBottom: - ty = view->size.height - th; - fy = 0; - fh = view->size.height - th/2; - break; - - case WTPBelowBottom: - ty = view->size.height - th; - fy = 0; - fh = view->size.height - th - 4; - break; - - default: - ty = 0; - fy = 0; - fh = view->size.height; + case WTPAboveTop: + ty = 0; + fy = th + 4; + fh = view->size.height - fy; + break; + + case WTPAtTop: + ty = 0; + fy = th/2; + fh = view->size.height - fy; + break; + + case WTPBelowTop: + ty = 4; + fy = 0; + fh = view->size.height; + break; + + case WTPAboveBottom: + ty = view->size.height - th - 4; + fy = 0; + fh = view->size.height; + break; + + case WTPAtBottom: + ty = view->size.height - th; + fy = 0; + fh = view->size.height - th/2; + break; + + case WTPBelowBottom: + ty = view->size.height - th; + fy = 0; + fh = view->size.height - th - 4; + break; + + default: + ty = 0; + fy = 0; + fh = view->size.height; } if (tlen>0 && fPtr->flags.titlePosition!=WTPNoTitle) { - tw = WMWidthOfString(font, fPtr->caption, tlen); + tw = WMWidthOfString(font, fPtr->caption, tlen); tx = (view->size.width - tw) / 2; drawTitle = True; } else { - drawTitle = False; + drawTitle = False; } { - XRectangle rect; - Region region, tmp; - GC gc[4]; - int i; - - region = XCreateRegion(); - - if (drawTitle) { - tmp = XCreateRegion(); - rect.x = tx; - rect.y = ty; - rect.width = tw; - rect.height = th; - XUnionRectWithRegion(&rect, tmp, tmp); - } - rect.x = 0; - rect.y = 0; - rect.width = view->size.width; - rect.height = view->size.height; - XUnionRectWithRegion(&rect, region, region); - if (drawTitle) { - XSubtractRegion(region, tmp, region); - XDestroyRegion(tmp); - } - gc[0] = WMColorGC(scrPtr->black); - gc[1] = WMColorGC(scrPtr->darkGray); - gc[2] = WMColorGC(scrPtr->gray); - gc[3] = WMColorGC(scrPtr->white); - - for (i = 0; i < 4; i++) { - XSetRegion(display, gc[i], region); - } - XDestroyRegion(region); - - W_DrawReliefWithGC(scrPtr, view->window, 0, fy, view->size.width, fh, - fPtr->flags.relief, gc[0], gc[1], gc[2], gc[3]); - - for (i = 0; i < 4; i++) { - XSetClipMask(display, gc[i], None); - } + XRectangle rect; + Region region, tmp; + GC gc[4]; + int i; + + region = XCreateRegion(); + + if (drawTitle) { + tmp = XCreateRegion(); + rect.x = tx; + rect.y = ty; + rect.width = tw; + rect.height = th; + XUnionRectWithRegion(&rect, tmp, tmp); + } + rect.x = 0; + rect.y = 0; + rect.width = view->size.width; + rect.height = view->size.height; + XUnionRectWithRegion(&rect, region, region); + if (drawTitle) { + XSubtractRegion(region, tmp, region); + XDestroyRegion(tmp); + } + gc[0] = WMColorGC(scrPtr->black); + gc[1] = WMColorGC(scrPtr->darkGray); + gc[2] = WMColorGC(scrPtr->gray); + gc[3] = WMColorGC(scrPtr->white); + + for (i = 0; i < 4; i++) { + XSetRegion(display, gc[i], region); + } + XDestroyRegion(region); + + W_DrawReliefWithGC(scrPtr, view->window, 0, fy, view->size.width, fh, + fPtr->flags.relief, gc[0], gc[1], gc[2], gc[3]); + + for (i = 0; i < 4; i++) { + XSetClipMask(display, gc[i], None); + } } if (drawTitle) { @@ -226,14 +226,14 @@ handleEvents(XEvent *event, void *data) CHECK_CLASS(data, WC_Frame); switch (event->type) { - case Expose: - if (event->xexpose.count == 0) - paintFrame(fPtr); - break; - - case DestroyNotify: - destroyFrame(fPtr); - break; + case Expose: + if (event->xexpose.count == 0) + paintFrame(fPtr); + break; + + case DestroyNotify: + destroyFrame(fPtr); + break; } } @@ -242,7 +242,7 @@ WMFrame* WMCreateFrame(WMWidget *parent) { Frame *fPtr; - + fPtr = wmalloc(sizeof(Frame)); memset(fPtr, 0, sizeof(Frame)); @@ -250,29 +250,29 @@ WMCreateFrame(WMWidget *parent) fPtr->view = W_CreateView(W_VIEW(parent)); if (!fPtr->view) { - wfree(fPtr); - return NULL; + wfree(fPtr); + return NULL; } fPtr->view->self = fPtr; - + WMCreateEventHandler(fPtr->view, ExposureMask|StructureNotifyMask, - handleEvents, fPtr); + handleEvents, fPtr); fPtr->flags.relief = DEFAULT_RELIEF; fPtr->flags.titlePosition = DEFAULT_TITLE_POSITION; WMResizeWidget(fPtr, DEFAULT_WIDTH, DEFAULT_HEIGHT); - + return fPtr; } static void destroyFrame(Frame *fPtr) -{ +{ if (fPtr->caption) - wfree(fPtr->caption); + wfree(fPtr->caption); wfree(fPtr); } diff --git a/WINGs/widgets.c b/WINGs/widgets.c index 108fafd0..f06bdafd 100644 --- a/WINGs/widgets.c +++ b/WINGs/widgets.c @@ -322,8 +322,8 @@ static int userWidgetCount=0; static void -renderPixmap(W_Screen *screen, Pixmap d, Pixmap mask, char **data, - int width, int height) +renderPixmap(W_Screen *screen, Pixmap d, Pixmap mask, char **data, + int width, int height) { int x, y; GC whiteGC = WMColorGC(screen->white); @@ -333,37 +333,37 @@ renderPixmap(W_Screen *screen, Pixmap d, Pixmap mask, char **data, if (mask) - XSetForeground(screen->display, screen->monoGC, 0); - + XSetForeground(screen->display, screen->monoGC, 0); + for (y = 0; y < height; y++) { - for (x = 0; x < width; x++) { - switch (data[y][x]) { - case ' ': - case 'w': - XDrawPoint(screen->display, d, whiteGC, x, y); - break; - - case '=': - if (mask) - XDrawPoint(screen->display, mask, screen->monoGC, x, y); - - case '.': - case 'l': - XDrawPoint(screen->display, d, lightGC, x, y); - break; - - case '%': - case 'd': - XDrawPoint(screen->display, d, darkGC, x, y); - break; - - case '#': - case 'b': - default: - XDrawPoint(screen->display, d, blackGC, x, y); - break; - } - } + for (x = 0; x < width; x++) { + switch (data[y][x]) { + case ' ': + case 'w': + XDrawPoint(screen->display, d, whiteGC, x, y); + break; + + case '=': + if (mask) + XDrawPoint(screen->display, mask, screen->monoGC, x, y); + + case '.': + case 'l': + XDrawPoint(screen->display, d, lightGC, x, y); + break; + + case '%': + case 'd': + XDrawPoint(screen->display, d, darkGC, x, y); + break; + + case '#': + case 'b': + default: + XDrawPoint(screen->display, d, blackGC, x, y); + break; + } + } } } @@ -373,20 +373,20 @@ static WMPixmap* makePixmap(W_Screen *sPtr, char **data, int width, int height, int masked) { Pixmap pixmap, mask = None; - - pixmap = XCreatePixmap(sPtr->display, W_DRAWABLE(sPtr), width, height, - sPtr->depth); - + + pixmap = XCreatePixmap(sPtr->display, W_DRAWABLE(sPtr), width, height, + sPtr->depth); + if (masked) { - mask = XCreatePixmap(sPtr->display, W_DRAWABLE(sPtr), width, height, 1); - XSetForeground(sPtr->display, sPtr->monoGC, 1); - XFillRectangle(sPtr->display, mask, sPtr->monoGC, 0, 0, width, height); + mask = XCreatePixmap(sPtr->display, W_DRAWABLE(sPtr), width, height, 1); + XSetForeground(sPtr->display, sPtr->monoGC, 1); + XFillRectangle(sPtr->display, mask, sPtr->monoGC, 0, 0, width, height); } renderPixmap(sPtr, pixmap, mask, data, width, height); return WMCreatePixmapFromXPixmaps(sPtr, pixmap, mask, width, height, - sPtr->depth); + sPtr->depth); } @@ -414,11 +414,11 @@ loadPixmaps(WMScreen *scr) image = RLoadImage(scr->rcontext, T_WINGS_IMAGES_FILE, 0); if (!image) - image = RLoadImage(scr->rcontext, X_WINGS_IMAGES_FILE, 0); + image = RLoadImage(scr->rcontext, X_WINGS_IMAGES_FILE, 0); if (!image) { - wwarning(_("WINGs: could not load widget images file: %s"), - RMessageForError(RErrorCode)); - return False; + wwarning(_("WINGs: could not load widget images file: %s"), + RMessageForError(RErrorCode)); + return False; } /* home icon */ /* make it have a gray background */ @@ -502,19 +502,19 @@ loadPixmaps(WMScreen *scr) tmp = RGetSubImage(image, 41, 57, 40, 24); scr->colorListIcon = WMCreatePixmapFromRImage(scr, tmp, 128); RReleaseImage(tmp); - + RReleaseImage(image); #if 0 scr->defaultObjectIcon = - WMCreatePixmapFromFile(scr, T_DEFAULT_OBJECT_ICON_FILE); - if (!scr->defaultObjectIcon) { - scr->defaultObjectIcon = - WMCreatePixmapFromFile(scr, X_DEFAULT_OBJECT_ICON_FILE); + WMCreatePixmapFromFile(scr, T_DEFAULT_OBJECT_ICON_FILE); + if (!scr->defaultObjectIcon) { + scr->defaultObjectIcon = + WMCreatePixmapFromFile(scr, X_DEFAULT_OBJECT_ICON_FILE); } if (!scr->defaultObjectIcon) { - wwarning("WINGs: could not load default icon file"); - return False; + wwarning("WINGs: could not load default icon file"); + return False; } #endif return True; @@ -525,13 +525,13 @@ WMScreen* WMOpenScreen(const char *display) { Display *dpy = XOpenDisplay(display); - + if (!dpy) { - wwarning("WINGs: could not open display %s", - XDisplayName(display)); - return NULL; + wwarning("WINGs: could not open display %s", + XDisplayName(display)); + return NULL; } - + return WMCreateSimpleApplicationScreen(dpy); } @@ -540,12 +540,12 @@ WMScreen* WMCreateSimpleApplicationScreen(Display *display) { WMScreen *scr; - + scr = WMCreateScreen(display, DefaultScreen(display)); - + scr->aflags.hasAppIcon = 0; scr->aflags.simpleApplication = 1; - + return scr; } @@ -555,7 +555,7 @@ WMScreen* WMCreateScreen(Display *display, int screen) { return WMCreateScreenWithRContext(display, screen, - RCreateContext(display, screen, NULL)); + RCreateContext(display, screen, NULL)); } @@ -567,46 +567,48 @@ WMCreateScreenWithRContext(Display *display, int screen, RContext *context) Pixmap stipple; static int initialized = 0; static char *atomNames[] = { - "_GNUSTEP_WM_ATTR", - "WM_DELETE_WINDOW", - "WM_PROTOCOLS", - "CLIPBOARD", - "XdndAware", - "XdndSelection", - "XdndEnter", - "XdndLeave", - "XdndPosition", - "XdndDrop", - "XdndFinished", - "XdndTypeList", - "XdndActionCopy", - "XdndActionMove", - "XdndActionLink", - "XdndActionAsk", - "XdndActionPrivate", - "XdndStatus", - "_WINGS_DND_MOUSE_OFFSET", - "WM_STATE" + "_GNUSTEP_WM_ATTR", + "WM_DELETE_WINDOW", + "WM_PROTOCOLS", + "CLIPBOARD", + "XdndAware", + "XdndSelection", + "XdndEnter", + "XdndLeave", + "XdndPosition", + "XdndDrop", + "XdndFinished", + "XdndTypeList", + "XdndActionList", + "XdndActionDescription", + "XdndStatus", + "XdndActionCopy", + "XdndActionMove", + "XdndActionLink", + "XdndActionAsk", + "XdndActionPrivate", + "_WINGS_DND_MOUSE_OFFSET", + "WM_STATE" }; Atom atoms[sizeof(atomNames)/sizeof(char*)]; int i; if (!initialized) { - initialized = 1; + initialized = 1; - W_ReadConfigurations(); + W_ReadConfigurations(); - assert(W_ApplicationInitialized()); + assert(W_ApplicationInitialized()); } - + scrPtr = malloc(sizeof(W_Screen)); if (!scrPtr) - return NULL; + return NULL; memset(scrPtr, 0, sizeof(W_Screen)); - + scrPtr->aflags.hasAppIcon = 1; - + scrPtr->display = display; scrPtr->screen = screen; scrPtr->rcontext = context; @@ -671,77 +673,77 @@ WMCreateScreenWithRContext(Display *display, int screen, RContext *context) scrPtr->ignoredModifierMask = 0; { - int i; - XModifierKeymap *modmap; - KeyCode nlock, slock; - static int mask_table[8] = { - ShiftMask,LockMask,ControlMask,Mod1Mask, - Mod2Mask, Mod3Mask, Mod4Mask, Mod5Mask - }; - unsigned int numLockMask=0, scrollLockMask=0; - - nlock = XKeysymToKeycode(display, XK_Num_Lock); - slock = XKeysymToKeycode(display, XK_Scroll_Lock); - - /* - * Find out the masks for the NumLock and ScrollLock modifiers, - * so that we can bind the grabs for when they are enabled too. - */ - modmap = XGetModifierMapping(display); - - if (modmap!=NULL && modmap->max_keypermod>0) { - for (i=0; i<8*modmap->max_keypermod; i++) { - if (modmap->modifiermap[i]==nlock && nlock!=0) - numLockMask = mask_table[i/modmap->max_keypermod]; - else if (modmap->modifiermap[i]==slock && slock!=0) - scrollLockMask = mask_table[i/modmap->max_keypermod]; - } - } - - if (modmap) - XFreeModifiermap(modmap); - - - scrPtr->ignoredModifierMask = numLockMask|scrollLockMask|LockMask; + int i; + XModifierKeymap *modmap; + KeyCode nlock, slock; + static int mask_table[8] = { + ShiftMask,LockMask,ControlMask,Mod1Mask, + Mod2Mask, Mod3Mask, Mod4Mask, Mod5Mask + }; + unsigned int numLockMask=0, scrollLockMask=0; + + nlock = XKeysymToKeycode(display, XK_Num_Lock); + slock = XKeysymToKeycode(display, XK_Scroll_Lock); + + /* + * Find out the masks for the NumLock and ScrollLock modifiers, + * so that we can bind the grabs for when they are enabled too. + */ + modmap = XGetModifierMapping(display); + + if (modmap!=NULL && modmap->max_keypermod>0) { + for (i=0; i<8*modmap->max_keypermod; i++) { + if (modmap->modifiermap[i]==nlock && nlock!=0) + numLockMask = mask_table[i/modmap->max_keypermod]; + else if (modmap->modifiermap[i]==slock && slock!=0) + scrollLockMask = mask_table[i/modmap->max_keypermod]; + } + } + + if (modmap) + XFreeModifiermap(modmap); + + + scrPtr->ignoredModifierMask = numLockMask|scrollLockMask|LockMask; } - + /* initially allocate some colors */ WMWhiteColor(scrPtr); WMBlackColor(scrPtr); WMGrayColor(scrPtr); WMDarkGrayColor(scrPtr); - + gcv.graphics_exposures = False; - + gcv.function = GXxor; gcv.foreground = W_PIXEL(scrPtr->white); if (gcv.foreground == 0) gcv.foreground = 1; scrPtr->xorGC = XCreateGC(display, W_DRAWABLE(scrPtr), GCFunction - |GCGraphicsExposures|GCForeground, &gcv); + |GCGraphicsExposures|GCForeground, &gcv); gcv.function = GXxor; gcv.foreground = W_PIXEL(scrPtr->gray); gcv.subwindow_mode = IncludeInferiors; scrPtr->ixorGC = XCreateGC(display, W_DRAWABLE(scrPtr), GCFunction - |GCGraphicsExposures|GCForeground - |GCSubwindowMode, &gcv); + |GCGraphicsExposures|GCForeground + |GCSubwindowMode, &gcv); gcv.function = GXcopy; scrPtr->copyGC = XCreateGC(display, W_DRAWABLE(scrPtr), GCFunction - |GCGraphicsExposures, &gcv); + |GCGraphicsExposures, &gcv); scrPtr->clipGC = XCreateGC(display, W_DRAWABLE(scrPtr), GCFunction - |GCGraphicsExposures, &gcv); + |GCGraphicsExposures, &gcv); - stipple = XCreateBitmapFromData(display, W_DRAWABLE(scrPtr), - STIPPLE_BITS, STIPPLE_WIDTH, STIPPLE_HEIGHT); + stipple = XCreateBitmapFromData(display, W_DRAWABLE(scrPtr), + STIPPLE_BITS, STIPPLE_WIDTH, STIPPLE_HEIGHT); gcv.foreground = W_PIXEL(scrPtr->darkGray); gcv.background = W_PIXEL(scrPtr->gray); gcv.fill_style = FillStippled; gcv.stipple = stipple; scrPtr->stippleGC = XCreateGC(display, W_DRAWABLE(scrPtr), - GCForeground|GCBackground|GCStipple - |GCFillStyle|GCGraphicsExposures, &gcv); + GCForeground|GCBackground|GCStipple + |GCFillStyle|GCGraphicsExposures, &gcv); scrPtr->drawStringGC = XCreateGC(display, W_DRAWABLE(scrPtr), GCGraphicsExposures, &gcv); @@ -759,67 +761,67 @@ WMCreateScreenWithRContext(Display *display, int screen, RContext *context) scrPtr->antialiasedText = WINGsConfiguration.antialiasedText; - scrPtr->normalFont = WMSystemFontOfSize(scrPtr, - WINGsConfiguration.defaultFontSize); + scrPtr->normalFont = WMSystemFontOfSize(scrPtr, + WINGsConfiguration.defaultFontSize); - scrPtr->boldFont = WMBoldSystemFontOfSize(scrPtr, - WINGsConfiguration.defaultFontSize); + scrPtr->boldFont = WMBoldSystemFontOfSize(scrPtr, + WINGsConfiguration.defaultFontSize); if (!scrPtr->boldFont) - scrPtr->boldFont = scrPtr->normalFont; + scrPtr->boldFont = scrPtr->normalFont; if (!scrPtr->normalFont) { - wwarning(_("could not load any fonts. Make sure your font installation" + wwarning(_("could not load any fonts. Make sure your font installation" " and locale settings are correct.")); - return NULL; + return NULL; } scrPtr->checkButtonImageOn = makePixmap(scrPtr, CHECK_BUTTON_ON, - CHECK_BUTTON_ON_WIDTH, - CHECK_BUTTON_ON_HEIGHT, False); + CHECK_BUTTON_ON_WIDTH, + CHECK_BUTTON_ON_HEIGHT, False); scrPtr->checkButtonImageOff = makePixmap(scrPtr, CHECK_BUTTON_OFF, CHECK_BUTTON_OFF_WIDTH, CHECK_BUTTON_OFF_HEIGHT, False); scrPtr->radioButtonImageOn = makePixmap(scrPtr, RADIO_BUTTON_ON, - RADIO_BUTTON_ON_WIDTH, - RADIO_BUTTON_ON_HEIGHT, False); + RADIO_BUTTON_ON_WIDTH, + RADIO_BUTTON_ON_HEIGHT, False); scrPtr->radioButtonImageOff = makePixmap(scrPtr, RADIO_BUTTON_OFF, RADIO_BUTTON_OFF_WIDTH, RADIO_BUTTON_OFF_HEIGHT, False); - scrPtr->buttonArrow = makePixmap(scrPtr, BUTTON_ARROW, - BUTTON_ARROW_WIDTH, BUTTON_ARROW_HEIGHT, - False); + scrPtr->buttonArrow = makePixmap(scrPtr, BUTTON_ARROW, + BUTTON_ARROW_WIDTH, BUTTON_ARROW_HEIGHT, + False); scrPtr->pushedButtonArrow = makePixmap(scrPtr, BUTTON_ARROW2, - BUTTON_ARROW2_WIDTH, BUTTON_ARROW2_HEIGHT, - False); + BUTTON_ARROW2_WIDTH, BUTTON_ARROW2_HEIGHT, + False); scrPtr->scrollerDimple = makePixmap(scrPtr, SCROLLER_DIMPLE, - SCROLLER_DIMPLE_WIDTH, - SCROLLER_DIMPLE_HEIGHT, False); + SCROLLER_DIMPLE_WIDTH, + SCROLLER_DIMPLE_HEIGHT, False); scrPtr->upArrow = makePixmap(scrPtr, SCROLLER_ARROW_UP, - SCROLLER_ARROW_UP_WIDTH, - SCROLLER_ARROW_UP_HEIGHT, True); + SCROLLER_ARROW_UP_WIDTH, + SCROLLER_ARROW_UP_HEIGHT, True); scrPtr->downArrow = makePixmap(scrPtr, SCROLLER_ARROW_DOWN, - SCROLLER_ARROW_DOWN_WIDTH, - SCROLLER_ARROW_DOWN_HEIGHT, True); + SCROLLER_ARROW_DOWN_WIDTH, + SCROLLER_ARROW_DOWN_HEIGHT, True); scrPtr->leftArrow = makePixmap(scrPtr, SCROLLER_ARROW_LEFT, - SCROLLER_ARROW_LEFT_WIDTH, - SCROLLER_ARROW_LEFT_HEIGHT, True); + SCROLLER_ARROW_LEFT_WIDTH, + SCROLLER_ARROW_LEFT_HEIGHT, True); scrPtr->rightArrow = makePixmap(scrPtr, SCROLLER_ARROW_RIGHT, - SCROLLER_ARROW_RIGHT_WIDTH, - SCROLLER_ARROW_RIGHT_HEIGHT, True); + SCROLLER_ARROW_RIGHT_WIDTH, + SCROLLER_ARROW_RIGHT_HEIGHT, True); scrPtr->hiUpArrow = makePixmap(scrPtr, HI_SCROLLER_ARROW_UP, SCROLLER_ARROW_UP_WIDTH, @@ -838,16 +840,16 @@ WMCreateScreenWithRContext(Display *display, int screen, RContext *context) SCROLLER_ARROW_RIGHT_HEIGHT, True); scrPtr->popUpIndicator = makePixmap(scrPtr, POPUP_INDICATOR, - POPUP_INDICATOR_WIDTH, - POPUP_INDICATOR_HEIGHT, True); + POPUP_INDICATOR_WIDTH, + POPUP_INDICATOR_HEIGHT, True); scrPtr->pullDownIndicator = makePixmap(scrPtr, PULLDOWN_INDICATOR, - PULLDOWN_INDICATOR_WIDTH, - PULLDOWN_INDICATOR_HEIGHT, True); + PULLDOWN_INDICATOR_WIDTH, + PULLDOWN_INDICATOR_HEIGHT, True); scrPtr->checkMark = makePixmap(scrPtr, CHECK_MARK, - CHECK_MARK_WIDTH, - CHECK_MARK_HEIGHT, True); + CHECK_MARK_WIDTH, + CHECK_MARK_HEIGHT, True); loadPixmaps(scrPtr); @@ -856,21 +858,21 @@ WMCreateScreenWithRContext(Display *display, int screen, RContext *context) scrPtr->textCursor = XCreateFontCursor(display, XC_xterm); { - XColor bla; - Pixmap blank; + XColor bla; + Pixmap blank; - blank = XCreatePixmap(display, scrPtr->stipple, 1, 1, 1); - XSetForeground(display, scrPtr->monoGC, 0); - XFillRectangle(display, blank, scrPtr->monoGC, 0, 0, 1, 1); + blank = XCreatePixmap(display, scrPtr->stipple, 1, 1, 1); + XSetForeground(display, scrPtr->monoGC, 0); + XFillRectangle(display, blank, scrPtr->monoGC, 0, 0, 1, 1); - scrPtr->invisibleCursor = XCreatePixmapCursor(display, blank, blank, - &bla, &bla, 0, 0); - XFreePixmap(display, blank); + scrPtr->invisibleCursor = XCreatePixmapCursor(display, blank, blank, + &bla, &bla, 0, 0); + XFreePixmap(display, blank); } #ifdef HAVE_XINTERNATOMS XInternAtoms(display, atomNames, sizeof(atomNames)/sizeof(char*), False, - atoms); + atoms); #else for (i = 0; i < sizeof(atomNames)/sizeof(char*); i++) { atoms[i] = XInternAtom(display, atomNames[i], False); @@ -883,7 +885,7 @@ WMCreateScreenWithRContext(Display *display, int screen, RContext *context) scrPtr->deleteWindowAtom = atoms[i++]; scrPtr->protocolsAtom = atoms[i++]; - + scrPtr->clipboardAtom = atoms[i++]; scrPtr->xdndAwareAtom = atoms[i++]; @@ -894,6 +896,8 @@ WMCreateScreenWithRContext(Display *display, int screen, RContext *context) scrPtr->xdndDropAtom = atoms[i++]; scrPtr->xdndFinishedAtom = atoms[i++]; scrPtr->xdndTypeListAtom = atoms[i++]; + scrPtr->xdndActionListAtom = atoms[i++]; + scrPtr->xdndActionDescriptionAtom = atoms[i++]; scrPtr->xdndStatusAtom = atoms[i++]; scrPtr->xdndActionCopy = atoms[i++]; @@ -935,7 +939,7 @@ WMSetWidgetDefaultBoldFont(WMScreen *scr, WMFont *font) -void +void WMHangData(WMWidget *widget, void *data) { W_VIEW(widget)->hangedData = data; @@ -968,7 +972,7 @@ WMSetFocusToWidget(WMWidget *widget) /* * WMRealizeWidget- * Realizes the widget and all it's children. - * + * */ void WMRealizeWidget(WMWidget *w) @@ -978,7 +982,7 @@ WMRealizeWidget(WMWidget *w) void WMMapWidget(WMWidget *w) -{ +{ W_MapView(W_VIEW(w)); } @@ -994,36 +998,36 @@ static void makeChildrenAutomap(W_View *view, int flag) { view = view->childrenList; - + while (view) { - view->flags.mapWhenRealized = flag; - makeChildrenAutomap(view, flag); - - view = view->nextSister; + view->flags.mapWhenRealized = flag; + makeChildrenAutomap(view, flag); + + view = view->nextSister; } } void WMMapSubwidgets(WMWidget *w) -{ +{ /* make sure that subwidgets created after the parent was realized * are mapped too */ if (!W_VIEW(w)->flags.realized) { - makeChildrenAutomap(W_VIEW(w), True); + makeChildrenAutomap(W_VIEW(w), True); } else { - W_MapSubviews(W_VIEW(w)); + W_MapSubviews(W_VIEW(w)); } } void WMUnmapSubwidgets(WMWidget *w) -{ +{ if (!W_VIEW(w)->flags.realized) { - makeChildrenAutomap(W_VIEW(w), False); + makeChildrenAutomap(W_VIEW(w), False); } else { - W_UnmapSubviews(W_VIEW(w)); + W_UnmapSubviews(W_VIEW(w)); } } @@ -1031,7 +1035,7 @@ WMUnmapSubwidgets(WMWidget *w) void WMUnmapWidget(WMWidget *w) -{ +{ W_UnmapView(W_VIEW(w)); } @@ -1048,7 +1052,7 @@ WMSetWidgetBackgroundColor(WMWidget *w, WMColor *color) { W_SetViewBackgroundColor(W_VIEW(w), color); if (W_VIEW(w)->flags.mapped) - WMRedisplayWidget(w); + WMRedisplayWidget(w); } @@ -1062,14 +1066,14 @@ WMGetWidgetBackgroundColor(WMWidget *w) void WMRaiseWidget(WMWidget *w) { - W_RaiseView(W_VIEW(w)); + W_RaiseView(W_VIEW(w)); } void WMLowerWidget(WMWidget *w) { - W_LowerView(W_VIEW(w)); + W_LowerView(W_VIEW(w)); } @@ -1106,7 +1110,7 @@ WMScreenRContext(WMScreen *scr) -unsigned int +unsigned int WMWidgetWidth(WMWidget *w) { return W_VIEW(w)->size.width; @@ -1139,10 +1143,10 @@ void WMScreenMainLoop(WMScreen *scr) { XEvent event; - + while (1) { - WMNextEvent(scr->display, &event); - WMHandleEvent(&event); + WMNextEvent(scr->display, &event); + WMHandleEvent(&event); } } @@ -1166,10 +1170,10 @@ WMRunModalLoop(WMScreen *scr, WMView *view) scr->modalLoop = 1; while (scr->modalLoop) { - XEvent event; - - WMNextEvent(scr->display, &event); - WMHandleEvent(&event); + XEvent event; + + WMNextEvent(scr->display, &event); + WMHandleEvent(&event); } scr->modalView = oldModalView; @@ -1184,14 +1188,14 @@ WMScreenDisplay(WMScreen *scr) } -int +int WMScreenDepth(WMScreen *scr) { return scr->depth; } -unsigned int +unsigned int WMScreenWidth(WMScreen *scr) { return scr->rootView->size.width; @@ -1205,7 +1209,7 @@ WMScreenHeight(WMScreen *scr) } -void +void WMRedisplayWidget(WMWidget *w) { W_RedisplayView(W_VIEW(w)); diff --git a/WINGs/wtext.c b/WINGs/wtext.c index 6bd0219b..45892e62 100644 --- a/WINGs/wtext.c +++ b/WINGs/wtext.c @@ -9,7 +9,7 @@ #define DO_BLINK 0 -/* TODO: +/* TODO: * - verify what happens with XK_return in insertTextInt... * - selection code... selects can be funny if it crosses over. use rect? * - also inspect behaviour for WACenter and WARight @@ -24,8 +24,8 @@ /* a Section is a section of a TextBlock that describes what parts - of a TextBlock has been laid out on which "line"... - o this greatly aids redraw, scroll and selection. + of a TextBlock has been laid out on which "line"... + o this greatly aids redraw, scroll and selection. o this is created during layoutLine, but may be later modified. o there may be many Sections per TextBlock, hence the array */ typedef struct { @@ -63,7 +63,7 @@ typedef struct _TextBlock { Section *sections; /* the region for layouts (a growable array) */ /* an _array_! of size _nsections_ */ - + unsigned short s_begin; /* where the selection begins */ unsigned short s_end; /* where it ends */ @@ -132,7 +132,7 @@ typedef struct W_Text { #if DO_BLINK WMHandlerID timerID; /* for nice twinky-winky */ #endif - + WMAction *parser; WMAction *writer; WMTextDelegate *delegate; @@ -166,6 +166,9 @@ typedef struct W_Text { unsigned int first:1; /* for plain text parsing, newline? */ /* unsigned int RESERVED:1; */ } flags; + + WMArray *xdndSourceTypes; + WMArray *xdndDestinationTypes; } Text; @@ -181,14 +184,14 @@ typedef struct W_Text { #if 0 /* just to print blocks of text not terminated by \0 */ -static void +static void output(char *ptr, int len) { char *s; s = wmalloc(len+1); memcpy(s, ptr, len); - s[len] = 0; + s[len] = 0; /* printf(" s is [%s] (%d)\n", s, strlen(s)); */ printf("[%s]\n", s); wfree(s); @@ -227,11 +230,11 @@ static void layOutDocument(Text *tPtr); static void updateScrollers(Text *tPtr); -static int +static int getMarginNumber(Text *tPtr, WMRulerMargins *margins) { unsigned int i=0; - + for(i=0; i < tPtr->nMargins; i++) { if(WMIsMarginEqualToMargin(&tPtr->margins[i], margins)) @@ -240,25 +243,25 @@ getMarginNumber(Text *tPtr, WMRulerMargins *margins) return -1; } - -static int + +static int newMargin(Text *tPtr, WMRulerMargins *margins) { int n; - if (!margins) { + if (!margins) { tPtr->margins[0].retainCount++; return 0; } n = getMarginNumber(tPtr, margins); - if (n == -1) { + if (n == -1) { - if(tPtr->nMargins >= 127) { - n = tPtr->nMargins-1; + if(tPtr->nMargins >= 127) { + n = tPtr->nMargins-1; return n; } @@ -278,78 +281,78 @@ newMargin(Text *tPtr, WMRulerMargins *margins) return n; } - -static Bool -sectionWasSelected(Text *tPtr, TextBlock *tb, XRectangle *rect, int s) + +static Bool +sectionWasSelected(Text *tPtr, TextBlock *tb, XRectangle *rect, int s) { unsigned short i, w, lw, selected = False, extend = False; - myRect sel; - + myRect sel; + /* if selection rectangle completely encloses the section */ - if ((tb->sections[s]._y >= tPtr->visible.y + tPtr->sel.y) - && (tb->sections[s]._y + tb->sections[s].h - <= tPtr->visible.y + tPtr->sel.y + tPtr->sel.h) ) { + if ((tb->sections[s]._y >= tPtr->visible.y + tPtr->sel.y) + && (tb->sections[s]._y + tb->sections[s].h + <= tPtr->visible.y + tPtr->sel.y + tPtr->sel.h) ) { sel.x = 0; sel.w = tPtr->visible.w; selected = extend = True; /* or if it starts on a line and then goes further down */ - } else if ((tb->sections[s]._y <= tPtr->visible.y + tPtr->sel.y) - && (tb->sections[s]._y + tb->sections[s].h - <= tPtr->visible.y + tPtr->sel.y + tPtr->sel.h) - && (tb->sections[s]._y + tb->sections[s].h - >= tPtr->visible.y + tPtr->sel.y) ) { + } else if ((tb->sections[s]._y <= tPtr->visible.y + tPtr->sel.y) + && (tb->sections[s]._y + tb->sections[s].h + <= tPtr->visible.y + tPtr->sel.y + tPtr->sel.h) + && (tb->sections[s]._y + tb->sections[s].h + >= tPtr->visible.y + tPtr->sel.y) ) { sel.x = WMAX(tPtr->sel.x, tPtr->clicked.x); sel.w = tPtr->visible.w; selected = extend = True; /* or if it begins before a line, but ends on it */ - } else if ((tb->sections[s]._y >= tPtr->visible.y + tPtr->sel.y) - && (tb->sections[s]._y + tb->sections[s].h - >= tPtr->visible.y + tPtr->sel.y + tPtr->sel.h) - && (tb->sections[s]._y - <= tPtr->visible.y + tPtr->sel.y + tPtr->sel.h) ) { + } else if ((tb->sections[s]._y >= tPtr->visible.y + tPtr->sel.y) + && (tb->sections[s]._y + tb->sections[s].h + >= tPtr->visible.y + tPtr->sel.y + tPtr->sel.h) + && (tb->sections[s]._y + <= tPtr->visible.y + tPtr->sel.y + tPtr->sel.h) ) { if (1||tPtr->sel.x + tPtr->sel.w > tPtr->clicked.x) sel.w = tPtr->sel.x + tPtr->sel.w; - else + else sel.w = tPtr->sel.x; sel.x = 0; selected = True; /* or if the selection rectangle lies entirely within a line */ - } else if ((tb->sections[s]._y <= tPtr->visible.y + tPtr->sel.y) - && (tPtr->sel.w >= 2) - && (tb->sections[s]._y + tb->sections[s].h - >= tPtr->visible.y + tPtr->sel.y + tPtr->sel.h) ) { + } else if ((tb->sections[s]._y <= tPtr->visible.y + tPtr->sel.y) + && (tPtr->sel.w >= 2) + && (tb->sections[s]._y + tb->sections[s].h + >= tPtr->visible.y + tPtr->sel.y + tPtr->sel.h) ) { sel.x = tPtr->sel.x; sel.w = tPtr->sel.w; selected = True; } - - if (selected) { + + if (selected) { selected = False; - + /* if not within (modified) selection rectangle */ if ( tb->sections[s].x > sel.x + sel.w || tb->sections[s].x + tb->sections[s].w < sel.x) return False; - if (tb->graphic) { - if ( tb->sections[s].x + tb->sections[s].w <= sel.x + sel.w - && tb->sections[s].x >= sel.x) { + if (tb->graphic) { + if ( tb->sections[s].x + tb->sections[s].w <= sel.x + sel.w + && tb->sections[s].x >= sel.x) { rect->width = tb->sections[s].w; rect->x = tb->sections[s].x; selected = True; } - } else { + } else { - i = tb->sections[s].begin; + i = tb->sections[s].begin; lw = 0; - if (0&& tb->sections[s].x >= sel.x) { + if (0&& tb->sections[s].x >= sel.x) { tb->s_begin = tb->sections[s].begin; goto _selEnd; } @@ -367,7 +370,7 @@ sectionWasSelected(Text *tPtr, TextBlock *tb, XRectangle *rect, int s) break; } } - + if (i > tb->sections[s].end) { printf("WasSelected: (i > tb->sections[s].end) \n"); return False; @@ -380,30 +383,30 @@ _selEnd: rect->x = tb->sections[s].x + lw; w = WMWidthOfString(tb->d.font, &(tb->text[i-1]), 1); lw += w; - if (lw + rect->x >= sel.x + sel.w + if (lw + rect->x >= sel.x + sel.w || i == tb->sections[s].end ) { - if (i != tb->sections[s].end) { + if (i != tb->sections[s].end) { lw -= w; i--; } - + rect->width = lw; if (tb->sections[s].last && sel.x + sel.w >= tb->sections[s].x + tb->sections[s].w - && extend ) { + && extend ) { rect->width += (tPtr->visible.w - rect->x - lw); } tb->s_end = (tb->selected? WMAX(tb->s_end, i) : i); selected = True; break; - } - } - } + } + } + } } - if (selected) { + if (selected) { rect->y = tb->sections[s]._y - tPtr->vpos; rect->height = tb->sections[s].h; if(tb->graphic) { printf("DEBUG: graphic s%d h%d\n", s,tb->sections[s].h);} @@ -411,8 +414,8 @@ if(tb->graphic) { printf("DEBUG: graphic s%d h%d\n", s,tb->sections[s].h);} return selected; } - -static void + +static void setSelectionProperty(WMText *tPtr, WMFont *font, WMColor *color, int underlined) { TextBlock *tb; @@ -426,12 +429,12 @@ setSelectionProperty(WMText *tPtr, WMFont *font, WMColor *color, int underlined) isFont = True; while (tb) { - if (tPtr->flags.monoFont || tb->selected) { - - if (tPtr->flags.monoFont || (tb->s_end - tb->s_begin == tb->used) - || tb->graphic) { + if (tPtr->flags.monoFont || tb->selected) { - if(isFont) { + if (tPtr->flags.monoFont || (tb->s_end - tb->s_begin == tb->used) + || tb->graphic) { + + if(isFont) { if(!tb->graphic) { WMReleaseFont(tb->d.font); tb->d.font = WMRetainFont(font); @@ -448,19 +451,19 @@ setSelectionProperty(WMText *tPtr, WMFont *font, WMColor *color, int underlined) TextBlock *midtb, *otb = tb; if(underlined != -1) { - midtb = (TextBlock *) WMCreateTextBlockWithText(tPtr, + midtb = (TextBlock *) WMCreateTextBlockWithText(tPtr, &(tb->text[tb->s_begin]), tb->d.font, tb->color, False, (tb->s_end - tb->s_begin)); - } else { - midtb = (TextBlock *) WMCreateTextBlockWithText(tPtr, + } else { + midtb = (TextBlock *) WMCreateTextBlockWithText(tPtr, &(tb->text[tb->s_begin]), - (isFont?font:tb->d.font), - (isFont?tb->color:color), + (isFont?font:tb->d.font), + (isFont?tb->color:color), False, (tb->s_end - tb->s_begin)); } - - - if (midtb) { + + + if (midtb) { if(underlined != -1) { midtb->underlined = underlined; } else { @@ -475,14 +478,14 @@ setSelectionProperty(WMText *tPtr, WMFont *font, WMColor *color, int underlined) tb = tPtr->currentTextBlock; } - if (otb->used - otb->s_end > 0) { + if (otb->used - otb->s_end > 0) { TextBlock *ntb; - ntb = (TextBlock *) - WMCreateTextBlockWithText(tPtr, + ntb = (TextBlock *) + WMCreateTextBlockWithText(tPtr, &(otb->text[otb->s_end]), otb->d.font, otb->color, False, otb->used - otb->s_end); - if (ntb) { + if (ntb) { ntb->underlined = otb->underlined; ntb->selected = False; WMAppendTextBlock(tPtr, ntb); @@ -498,7 +501,7 @@ setSelectionProperty(WMText *tPtr, WMFont *font, WMColor *color, int underlined) otb->used = otb->s_begin; } } - + tb = tb->next; } @@ -506,7 +509,7 @@ setSelectionProperty(WMText *tPtr, WMFont *font, WMColor *color, int underlined) WMThawText(tPtr); /* in case the size changed... */ - if(isFont && tPtr->currentTextBlock) { + if(isFont && tPtr->currentTextBlock) { TextBlock *tb = tPtr->currentTextBlock; printf("%d %d %d\n", tPtr->sel.y, tPtr->sel.h, tPtr->sel.w); @@ -532,14 +535,14 @@ removeSelection(Text *tPtr) return False; while (tb) { - if (tb->selected) { - if(!first && !tb->graphic) { + if (tb->selected) { + if(!first && !tb->graphic) { WMReleaseFont(tPtr->dFont); tPtr->dFont = WMRetainFont(tb->d.font); first = True; } - if ( (tb->s_end - tb->s_begin == tb->used) || tb->graphic) { + if ( (tb->s_end - tb->s_begin == tb->used) || tb->graphic) { tPtr->currentTextBlock = tb; if(tb->next) { tPtr->tpos = 0; @@ -561,9 +564,9 @@ removeSelection(Text *tPtr) tb->selected = False; tPtr->tpos = tb->s_begin; } - + } - + tb = tb->next; } return True; @@ -584,7 +587,7 @@ getFirstNonGraphicBlockFor(TextBlock *tb, short dir) tb = (dir? tb->next : tb->prior); } - if(!tb) { + if(!tb) { tb = hold; while (tb) { if (!tb->graphic) @@ -592,16 +595,16 @@ getFirstNonGraphicBlockFor(TextBlock *tb, short dir) tb = (dir? tb->prior : tb->next); } } - + if(!tb) return NULL; return tb; } - + static Bool -updateStartForCurrentTextBlock(Text *tPtr, int x, int y, int *dir, +updateStartForCurrentTextBlock(Text *tPtr, int x, int y, int *dir, TextBlock *tb) { if (tPtr->flags.monoFont && tb->graphic) { @@ -610,33 +613,33 @@ TextBlock *tb) return 0; if (tb->graphic) { - tPtr->currentTextBlock = + tPtr->currentTextBlock = (dir? tPtr->lastTextBlock : tPtr->firstTextBlock); tPtr->tpos = 0; return 0; } } - + if(!tb->sections) { layOutDocument(tPtr); return 0; } *dir = !(y <= tb->sections[0].y); - if(*dir) { + if(*dir) { if ( ( y <= tb->sections[0]._y + tb->sections[0].h ) && (y >= tb->sections[0]._y ) ) { /* if it's on the same line */ - if(x < tb->sections[0].x) + if(x < tb->sections[0].x) *dir = 0; } - } else { - if ( ( y <= tb->sections[tb->nsections-1]._y + } else { + if ( ( y <= tb->sections[tb->nsections-1]._y + tb->sections[tb->nsections-1].h ) && (y >= tb->sections[tb->nsections-1]._y ) ) { /* if it's on the same line */ - if(x > tb->sections[tb->nsections-1].x) + if(x > tb->sections[tb->nsections-1].x) *dir = 1; } } @@ -645,7 +648,7 @@ TextBlock *tb) } -static void +static void paintText(Text *tPtr) { TextBlock *tb; @@ -665,7 +668,7 @@ paintText(Text *tPtr) tPtr->visible.w, tPtr->visible.h); if (tPtr->bgPixmap) { - WMDrawPixmap(tPtr->bgPixmap, tPtr->db, + WMDrawPixmap(tPtr->bgPixmap, tPtr->db, (tPtr->visible.w-tPtr->visible.x-tPtr->bgPixmap->width)/2, (tPtr->visible.h-tPtr->visible.y-tPtr->bgPixmap->height)/2); } @@ -681,18 +684,18 @@ paintText(Text *tPtr) /* first, which direction? Don't waste time looking all over, - since the parts to be drawn will most likely be near what + since the parts to be drawn will most likely be near what was previously drawn */ if(!updateStartForCurrentTextBlock(tPtr, 0, tPtr->vpos, &dir, tb)) goto _copy_area; - - while(tb) { - if (tb->graphic && tPtr->flags.monoFont) + while(tb) { + + if (tb->graphic && tPtr->flags.monoFont) goto _getSibling; - if(dir) { - if(tPtr->vpos <= tb->sections[tb->nsections-1]._y + if(dir) { + if(tPtr->vpos <= tb->sections[tb->nsections-1]._y + tb->sections[tb->nsections-1].h) break; } else { @@ -702,8 +705,8 @@ paintText(Text *tPtr) } _getSibling: - if(dir) { - if(tb->next) + if(dir) { + if(tb->next) tb = tb->next; else break; } else { @@ -730,8 +733,8 @@ _getSibling: break; } - if ( tb->sections[s].y + tb->sections[s].h < tPtr->vpos) - continue; + if ( tb->sections[s].y + tb->sections[s].h < tPtr->vpos) + continue; if (tPtr->flags.monoFont) { font = tPtr->dFont; @@ -759,7 +762,7 @@ _getSibling: WMDrawString(scr, tPtr->db, color, font, tb->sections[s].x - tPtr->hpos, y, text, len); - if (!tPtr->flags.monoFont && tb->underlined) { + if (!tPtr->flags.monoFont && tb->underlined) { XDrawLine(dpy, tPtr->db, WMColorGC(color), tb->sections[s].x - tPtr->hpos, y + font->y + 1, @@ -777,11 +780,11 @@ _getSibling: for(j=0; jgfxItems, j); - + /* if it's not viewable, and mapped, unmap it */ - if (tb->sections[0]._y + tb->sections[0].h <= tPtr->vpos + if (tb->sections[0]._y + tb->sections[0].h <= tPtr->vpos || tb->sections[0]._y >= tPtr->vpos + tPtr->visible.h ) { - + if(tb->object) { if ((W_VIEW(tb->d.widget))->flags.mapped) { WMUnmapWidget(tb->d.widget); @@ -794,22 +797,22 @@ _getSibling: if (!view->flags.realized) WMRealizeWidget(tb->d.widget); - if(!view->flags.mapped) { + if(!view->flags.mapped) { XMapWindow(view->screen->display, view->window); XFlush(view->screen->display); view->flags.mapped = 1; } } - + if(tb->object) { - WMMoveWidget(tb->d.widget, - tb->sections[0].x + tPtr->visible.x - tPtr->hpos, + WMMoveWidget(tb->d.widget, + tb->sections[0].x + tPtr->visible.x - tPtr->hpos, tb->sections[0].y + tPtr->visible.y - tPtr->vpos); h = WMWidgetHeight(tb->d.widget) + 1; } else { - WMDrawPixmap(tb->d.pixmap, tPtr->db, - tb->sections[0].x - tPtr->hpos, + WMDrawPixmap(tb->d.pixmap, tPtr->db, + tb->sections[0].x - tPtr->hpos, tb->sections[0].y - tPtr->vpos); h = tb->d.pixmap->height + 1; @@ -829,21 +832,21 @@ _getSibling: } } - if (!tPtr->flags.monoFont && tb->underlined) { - XDrawLine(dpy, tPtr->db, WMColorGC(tb->color), + if (!tPtr->flags.monoFont && tb->underlined) { + XDrawLine(dpy, tPtr->db, WMColorGC(tb->color), tb->sections[0].x - tPtr->hpos, tb->sections[0].y + h - tPtr->vpos, tb->sections[0].x + tb->sections[0].w - tPtr->hpos, tb->sections[0].y + h - tPtr->vpos); - } - } - } - } + } + } + } + } _copy_area: - if (tPtr->flags.editable && tPtr->flags.cursorShown - && tPtr->cursor.x != -23 && tPtr->flags.focused) { + if (tPtr->flags.editable && tPtr->flags.cursorShown + && tPtr->cursor.x != -23 && tPtr->flags.focused) { int y = tPtr->cursor.y - tPtr->vpos; XDrawLine(dpy, tPtr->db, WMColorGC(tPtr->fgColor), tPtr->cursor.x, y, @@ -855,8 +858,8 @@ _copy_area: tPtr->visible.x, tPtr->visible.y); W_DrawRelief(scr, win, 0, 0, - tPtr->view->size.width, tPtr->view->size.height, - tPtr->flags.relief); + tPtr->view->size.width, tPtr->view->size.height, + tPtr->flags.relief); if (tPtr->ruler && tPtr->flags.rulerShown) XDrawLine(dpy, win, WMColorGC(tPtr->fgColor), @@ -864,8 +867,8 @@ _copy_area: } -static void -mouseOverObject(Text *tPtr, int x, int y) +static void +mouseOverObject(Text *tPtr, int x, int y) { TextBlock *tb; Bool result = False; @@ -875,7 +878,7 @@ mouseOverObject(Text *tPtr, int x, int y) y -= tPtr->visible.y; y += tPtr->vpos; - if(tPtr->flags.ownsSelection) { + if(tPtr->flags.ownsSelection) { if(tPtr->sel.x <= x && tPtr->sel.y <= y && tPtr->sel.x + tPtr->sel.w >= x @@ -884,24 +887,24 @@ mouseOverObject(Text *tPtr, int x, int y) result = True; } } - - if(!result) { + + if(!result) { int j, c = WMGetArrayItemCount(tPtr->gfxItems); - if (c<1) + if (c<1) tPtr->flags.isOverGraphic = 0; - - + + for(j=0; jgfxItems, j); - if(!tb || !tb->sections) { + if(!tb || !tb->sections) { tPtr->flags.isOverGraphic = 0; return; } - if(!tb->object) { + if(!tb->object) { if(tb->sections[0].x <= x && tb->sections[0].y <= y && tb->sections[0].x + tb->sections[0].w >= x @@ -940,10 +943,10 @@ blinkCursor(void *data) Text *tPtr = (Text*)data; if (tPtr->flags.cursorShown) { - tPtr->timerID = WMAddTimerHandler(CURSOR_BLINK_OFF_DELAY, + tPtr->timerID = WMAddTimerHandler(CURSOR_BLINK_OFF_DELAY, blinkCursor, data); } else { - tPtr->timerID = WMAddTimerHandler(CURSOR_BLINK_ON_DELAY, + tPtr->timerID = WMAddTimerHandler(CURSOR_BLINK_ON_DELAY, blinkCursor, data); } paintText(tPtr); @@ -964,16 +967,16 @@ updateCursorPosition(Text *tPtr) if (! (tb = tPtr->firstTextBlock)) { WMFont *font = tPtr->dFont; tPtr->tpos = 0; - tPtr->cursor.h = font->height + abs(font->height-font->y); + tPtr->cursor.h = font->height + abs(font->height-font->y); tPtr->cursor.y = 2; tPtr->cursor.x = 2; return; } - } + } - if(tb->blank) { + if(tb->blank) { tPtr->tpos = 0; y = tb->sections[0].y; h = tb->sections[0].h; @@ -996,12 +999,12 @@ updateCursorPosition(Text *tPtr) && tPtr->tpos <= tb->sections[s].end) break; } - + y = tb->sections[s]._y; h = tb->sections[s].h; x = tb->sections[s].x + WMWidthOfString( - (tPtr->flags.monoFont?tPtr->dFont:tb->d.font), - &tb->text[tb->sections[s].begin], + (tPtr->flags.monoFont?tPtr->dFont:tb->d.font), + &tb->text[tb->sections[s].begin], tPtr->tpos - tb->sections[s].begin); } @@ -1011,16 +1014,16 @@ updateCursorPosition(Text *tPtr) /* scroll the bars if the cursor is not visible */ - if(tPtr->flags.editable && tPtr->cursor.x != -23) { - if(tPtr->cursor.y+tPtr->cursor.h - > tPtr->vpos+tPtr->visible.y+tPtr->visible.h) { - tPtr->vpos += + if(tPtr->flags.editable && tPtr->cursor.x != -23) { + if(tPtr->cursor.y+tPtr->cursor.h + > tPtr->vpos+tPtr->visible.y+tPtr->visible.h) { + tPtr->vpos += (tPtr->cursor.y+tPtr->cursor.h+10 - (tPtr->vpos+tPtr->visible.y+tPtr->visible.h)); - } else if(tPtr->cursor.y < tPtr->vpos+tPtr->visible.y) { + } else if(tPtr->cursor.y < tPtr->vpos+tPtr->visible.y) { tPtr->vpos -= (tPtr->vpos+tPtr->visible.y-tPtr->cursor.y); } - + } updateScrollers(tPtr); @@ -1038,11 +1041,11 @@ cursorToTextPosition(Text *tPtr, int x, int y) layOutDocument(tPtr); y += (tPtr->vpos - tPtr->visible.y); - if (y<0) + if (y<0) y = 0; - x -= (tPtr->visible.x - 2); - if (x<0) + x -= (tPtr->visible.x - 2); + if (x<0) x=0; /* clicked is relative to document, not window... */ @@ -1053,29 +1056,29 @@ cursorToTextPosition(Text *tPtr, int x, int y) if (! (tb = tPtr->firstTextBlock)) { WMFont *font = tPtr->dFont; tPtr->tpos = 0; - tPtr->cursor.h = font->height + abs(font->height-font->y); + tPtr->cursor.h = font->height + abs(font->height-font->y); tPtr->cursor.y = 2; tPtr->cursor.x = 2; return; } } - /* first, which direction? Most likely, newly clicked + /* first, which direction? Most likely, newly clicked position will be close to previous */ if(!updateStartForCurrentTextBlock(tPtr, x, y, &dir, tb)) return; s = (dir? 0 : tb->nsections-1); - if ( y >= tb->sections[s]._y - && y <= tb->sections[s]._y + tb->sections[s].h) { + if ( y >= tb->sections[s]._y + && y <= tb->sections[s]._y + tb->sections[s].h) { goto _doneV; } - /* get the first (or last) section of the TextBlock that + /* get the first (or last) section of the TextBlock that lies about the vertical click point */ done = False; - while (!done && tb) { + while (!done && tb) { if (tPtr->flags.monoFont && tb->graphic) { if( (dir?tb->next:tb->prior)) @@ -1093,7 +1096,7 @@ cursorToTextPosition(Text *tPtr, int x, int y) dir? s++ : s--; } } - + if (!done) { if ( (dir? tb->next : tb->prior)) { tb = (dir ? tb->next : tb->prior); @@ -1104,7 +1107,7 @@ cursorToTextPosition(Text *tPtr, int x, int y) } } - + if (s<0 || s>=tb->nsections) { s = (dir? tb->nsections-1 : 0); } @@ -1123,14 +1126,14 @@ _doneV: goto _doNothing; } } - - if(tb->blank) + + if(tb->blank) _w = 0; _y = tb->sections[s]._y; - while (tb) { + while (tb) { if (tPtr->flags.monoFont && tb->graphic) { tb = (dir ? tb->next : tb->prior); @@ -1141,7 +1144,7 @@ _doneV: if (tb->graphic) { if(tb->object) _w = WMWidgetWidth(tb->d.widget)-5; - else + else _w = tb->d.pixmap->width-5; if (tb->sections[0].x + _w >= x) @@ -1152,9 +1155,9 @@ _doneV: _w = WMWidthOfString(tb->d.font, text, len); if (tb->sections[s].x + _w >= x) break; - + } - } else { + } else { if (tb->sections[s].x <= x) break; } @@ -1174,15 +1177,15 @@ _doneV: /* this must be the last/first on this line. stop */ pos = (dir? tb->sections[s].end : 0); tPtr->cursor.x = tb->sections[s].x; - if (!tb->blank) { + if (!tb->blank) { if (tb->graphic) { if(tb->object) tPtr->cursor.x += WMWidgetWidth(tb->d.widget); - else + else tPtr->cursor.x += tb->d.pixmap->width; } else if (pos > tb->sections[s].begin) { - tPtr->cursor.x += - WMWidthOfString(tb->d.font, + tPtr->cursor.x += + WMWidthOfString(tb->d.font, &(tb->text[tb->sections[s].begin]), pos - tb->sections[s].begin); } @@ -1193,36 +1196,36 @@ _doneV: if ( (dir? tb->next : tb->prior)) { tb = (dir ? tb->next : tb->prior); - } else { + } else { done = True; break; } - if (tb) + if (tb) s = (dir? 0 : tb->nsections-1); } - + /* we have said TextBlock, now where within it? */ - if (tb) { + if (tb) { if(tb->graphic) { - int gw = (tb->object ? + int gw = (tb->object ? WMWidgetWidth(tb->d.widget) : tb->d.pixmap->width); tPtr->cursor.x = tb->sections[0].x; - if(x > tPtr->cursor.x + gw/2) { + if(x > tPtr->cursor.x + gw/2) { pos = 1; tPtr->cursor.x += gw; - } else { + } else { printf("first %d\n", tb->first); - if(tb->prior) { + if(tb->prior) { if(tb->prior->graphic) pos = 1; else pos = tb->prior->used; tb = tb->prior; } else pos = 0; - + } - + s = 0; goto _doneH; @@ -1237,14 +1240,14 @@ printf("first %d\n", tb->first); while (poscursor.x = tb->sections[s].x + + tPtr->cursor.x = tb->sections[s].x + (pos? WMWidthOfString(f, text, pos) : 0); pos += tb->sections[s].begin; } } - -_doneH: + +_doneH: if(tb->graphic) { tPtr->tpos = (pos<=1)? pos : 0; } else { @@ -1257,20 +1260,20 @@ _doNothing: tPtr->currentTextBlock = tb; tPtr->cursor.h = tb->sections[s].h; tPtr->cursor.y = tb->sections[s]._y; - + /* scroll the bars if the cursor is not visible */ - if(tPtr->flags.editable && tPtr->cursor.x != -23) { - if(tPtr->cursor.y+tPtr->cursor.h - > tPtr->vpos+tPtr->visible.y+tPtr->visible.h) { - tPtr->vpos += + if(tPtr->flags.editable && tPtr->cursor.x != -23) { + if(tPtr->cursor.y+tPtr->cursor.h + > tPtr->vpos+tPtr->visible.y+tPtr->visible.h) { + tPtr->vpos += (tPtr->cursor.y+tPtr->cursor.h+10 - (tPtr->vpos+tPtr->visible.y+tPtr->visible.h)); updateScrollers(tPtr); - } else if(tPtr->cursor.y < tPtr->vpos+tPtr->visible.y) { + } else if(tPtr->cursor.y < tPtr->vpos+tPtr->visible.y) { tPtr->vpos -= (tPtr->vpos+tPtr->visible.y-tPtr->cursor.y); updateScrollers(tPtr); } - + } } @@ -1278,7 +1281,7 @@ _doNothing: static void updateScrollers(Text *tPtr) -{ +{ if (tPtr->flags.frozen) return; @@ -1287,43 +1290,43 @@ updateScrollers(Text *tPtr) if (tPtr->docHeight <= tPtr->visible.h) { WMSetScrollerParameters(tPtr->vS, 0, 1); tPtr->vpos = 0; - } else { + } else { float hmax = (float)(tPtr->docHeight); WMSetScrollerParameters(tPtr->vS, ((float)tPtr->vpos)/(hmax - (float)tPtr->visible.h), (float)tPtr->visible.h/hmax); - } + } } else tPtr->vpos = 0; - - if (tPtr->hS) { + + if (tPtr->hS) { if (tPtr->docWidth <= tPtr->visible.w) { WMSetScrollerParameters(tPtr->hS, 0, 1); tPtr->hpos = 0; - } else { + } else { float wmax = (float)(tPtr->docWidth); WMSetScrollerParameters(tPtr->hS, ((float)tPtr->hpos)/(wmax - (float)tPtr->visible.w), (float)tPtr->visible.w/wmax); - } + } } else tPtr->hpos = 0; -} +} static void scrollersCallBack(WMWidget *w, void *self) -{ +{ Text *tPtr = (Text *)self; Bool scroll = False; int which; - if (!tPtr->view->flags.realized || tPtr->flags.frozen) + if (!tPtr->view->flags.realized || tPtr->flags.frozen) return; if (w == tPtr->vS) { - int height; + int height; height = tPtr->visible.h; which = WMGetScrollerHitPart(tPtr->vS); - switch(which) { + switch(which) { case WSDecrementLine: if (tPtr->vpos > 0) { @@ -1358,28 +1361,28 @@ scrollersCallBack(WMWidget *w, void *self) tPtr->vpos = tPtr->docHeight - height; scroll = True; break; - - + + case WSKnob: tPtr->vpos = WMGetScrollerValue(tPtr->vS) * (float)(tPtr->docHeight - height); scroll = True; - break; - + break; + case WSKnobSlot: case WSNoPart: break; - } + } scroll = (tPtr->vpos != tPtr->prevVpos); tPtr->prevVpos = tPtr->vpos; } - + if (w == tPtr->hS) { int width = tPtr->visible.w; which = WMGetScrollerHitPart(tPtr->hS); - switch(which) { + switch(which) { case WSDecrementLine: if (tPtr->hpos > 0) { @@ -1412,22 +1415,22 @@ scrollersCallBack(WMWidget *w, void *self) tPtr->hpos = tPtr->docWidth - width; scroll = True; break; - - + + case WSKnob: tPtr->hpos = WMGetScrollerValue(tPtr->hS) * (float)(tPtr->docWidth - width); scroll = True; - break; - + break; + case WSKnobSlot: case WSNoPart: break; - } + } scroll = (tPtr->hpos != tPtr->prevHpos); tPtr->prevHpos = tPtr->hpos; } - + if (scroll) { updateScrollers(tPtr); paintText(tPtr); @@ -1444,7 +1447,7 @@ typedef struct { static int layOutLine(Text *tPtr, myLineItems *items, int nitems, int x, int y) -{ +{ int i, j=0, lw = 0, line_height=0, max_d=0, len, n; WMFont *font; char *text; @@ -1456,38 +1459,38 @@ layOutLine(Text *tPtr, myLineItems *items, int nitems, int x, int y) for(i=0; igraphic) { + if (tb->graphic) { if (!tPtr->flags.monoFont) { if(tb->object) { WMWidget *wdt = tb->d.widget; line_height = WMAX(line_height, WMWidgetHeight(wdt)); - if (tPtr->flags.alignment != WALeft) + if (tPtr->flags.alignment != WALeft) lw += WMWidgetWidth(wdt); } else { - line_height = WMAX(line_height, + line_height = WMAX(line_height, tb->d.pixmap->height + max_d); - if (tPtr->flags.alignment != WALeft) + if (tPtr->flags.alignment != WALeft) lw += tb->d.pixmap->width; } } - - } else { + + } else { font = (tPtr->flags.monoFont)?tPtr->dFont : tb->d.font; /*max_d = WMAX(max_d, abs(font->height-font->y));*/ max_d = 2; line_height = WMAX(line_height, font->height + max_d); text = &(tb->text[items[i].begin]); len = items[i].end - items[i].begin; - if (tPtr->flags.alignment != WALeft) + if (tPtr->flags.alignment != WALeft) lw += WMWidthOfString(font, text, len); } } - + if (tPtr->flags.alignment == WARight) { j = tPtr->visible.w - lw; } else if (tPtr->flags.alignment == WACenter) { j = (int) ((float)(tPtr->visible.w - lw))/2.0; - } + } for(i=0; isections[n].last = (i+1 == nitems); - if (tb->graphic) { + if (tb->graphic) { if (!tPtr->flags.monoFont) { if(tb->object) { WMWidget *wdt = tb->d.widget; - tb->sections[n].y = max_d + y + tb->sections[n].y = max_d + y + line_height - WMWidgetHeight(wdt); tb->sections[n].w = WMWidgetWidth(wdt); } else { - tb->sections[n].y = y + line_height + tb->sections[n].y = y + line_height + max_d - tb->d.pixmap->height; tb->sections[n].w = tb->d.pixmap->width; } @@ -1529,24 +1532,24 @@ layOutLine(Text *tPtr, myLineItems *items, int nitems, int x, int y) text = &(tb->text[items[i].begin]); tb->sections[n].y = y+line_height-font->y; - tb->sections[n].w = - WMWidthOfString(font, - &(tb->text[tb->sections[n].begin]), + tb->sections[n].w = + WMWidthOfString(font, + &(tb->text[tb->sections[n].begin]), tb->sections[n].end - tb->sections[n].begin); - x += WMWidthOfString(font, text, len); - } + x += WMWidthOfString(font, text, len); + } tbsame = tb; } return line_height; - + } static void -layOutDocument(Text *tPtr) +layOutDocument(Text *tPtr) { TextBlock *tb; myLineItems *items = NULL; @@ -1559,9 +1562,9 @@ layOutDocument(Text *tPtr) return; assert(tPtr->visible.w > 20); - + tPtr->docWidth = tPtr->visible.w; - x = tPtr->margins[tb->marginN].first; + x = tPtr->margins[tb->marginN].first; bmargin = tPtr->margins[tb->marginN].body; /* only partial layOut needed: re-Lay only affected textblocks */ @@ -1577,14 +1580,14 @@ layOutDocument(Text *tPtr) goto _layOut; } - if(!tb->prior->sections || tb->prior->nsections<1) { + if(!tb->prior->sections || tb->prior->nsections<1) { tb = tPtr->firstTextBlock; tPtr->flags.laidOut = False; y = 0; goto _layOut; } - if (tb->sections[0]._y != + if (tb->sections[0]._y != tb->prior->sections[tb->prior->nsections-1]._y) { break; } @@ -1592,8 +1595,8 @@ layOutDocument(Text *tPtr) } if(tb->prior && tb->prior->sections && tb->prior->nsections>0) { - y = tb->prior->sections[tb->prior->nsections-1]._y + - tb->prior->sections[tb->prior->nsections-1].h - + y = tb->prior->sections[tb->prior->nsections-1]._y + + tb->prior->sections[tb->prior->nsections-1].h - tb->prior->sections[tb->prior->nsections-1].max_d; } else { y = 0; @@ -1607,7 +1610,7 @@ _layOut: wfree(tb->sections); tb->sections = NULL; tb->nsections = 0; - } + } if (tb->first && tb->blank && tb->next && !tb->next->first) { TextBlock *next = tb->next; @@ -1625,19 +1628,19 @@ _layOut: nitems = 0; lw = 0; } - - if (tb->graphic) { - if (!tPtr->flags.monoFont) { + + if (tb->graphic) { + if (!tPtr->flags.monoFont) { if(tb->object) width = WMWidgetWidth(tb->d.widget); else width = tb->d.pixmap->width; - if (width > tPtr->docWidth) + if (width > tPtr->docWidth) tPtr->docWidth = width; lw += width; - if (lw >= tPtr->visible.w - x ) { + if (lw >= tPtr->visible.w - x ) { y += layOutLine(tPtr, items, nitems, x, y); nitems = 0; x = bmargin; @@ -1645,10 +1648,10 @@ _layOut: } if(nitems + 1> itemsSize) { - items = wrealloc(items, + items = wrealloc(items, (++itemsSize)*sizeof(myLineItems)); } - + items[nitems].tb = tb; items[nitems].begin = 0; items[nitems].end = 0; @@ -1673,17 +1676,17 @@ _layOut: end = tb->used; if (end-begin > 0) { - - width = WMWidthOfString(font, + + width = WMWidthOfString(font, &tb->text[begin], end-begin); /* if it won't fit, char wrap it */ - if (width >= tPtr->visible.w) { + if (width >= tPtr->visible.w) { char *t = &tb->text[begin]; int l=end-begin, i=0; - do { + do { width = WMWidthOfString(font, t, ++i); - } while (width < tPtr->visible.w && i < l); + } while (width < tPtr->visible.w && i < l); if(i>2) i--; end = begin+i; start = &tb->text[end]; @@ -1693,17 +1696,17 @@ _layOut: } if (lw >= tPtr->visible.w - x) { - y += layOutLine(tPtr, items, nitems, x, y); + y += layOutLine(tPtr, items, nitems, x, y); lw = width; x = bmargin; nitems = 0; } if(nitems + 1 > itemsSize) { - items = wrealloc(items, + items = wrealloc(items, (++itemsSize)*sizeof(myLineItems)); } - + items[nitems].tb = tb; items[nitems].begin = begin; items[nitems].end = end; @@ -1712,14 +1715,14 @@ _layOut: begin = end; } } - - + + /* not yet fully ready. but is already VERY FAST for a 3Mbyte file ;-) */ - if(0&&tPtr->flags.laidOut + if(0&&tPtr->flags.laidOut && tb->next && tb->next->sections && tb->next->nsections>0 - && (tPtr->vpos + tPtr->visible.h + && (tPtr->vpos + tPtr->visible.h < tb->next->sections[0]._y)) { - if(tPtr->lastTextBlock->sections + if(tPtr->lastTextBlock->sections && tPtr->lastTextBlock->nsections > 0 ) { TextBlock *ltb = tPtr->lastTextBlock; int ly = ltb->sections[ltb->nsections-1]._y; @@ -1729,7 +1732,7 @@ _layOut: lh += 1 + tPtr->visible.y + ltb->sections[ltb->nsections-1].max_d; printf("it's %d\n", tPtr->visible.y + ltb->sections[ltb->nsections-1].max_d); - y += layOutLine(tPtr, items, nitems, x, y); + y += layOutLine(tPtr, items, nitems, x, y); ss= ly+lh-y; sd = tPtr->docHeight-y; @@ -1737,21 +1740,21 @@ printf("dif %d-%d: %d\n", ss, sd, ss-sd); y += tb->next->sections[0]._y-y; nitems = 0; printf("nitems%d\n", nitems); -if(ss-sd!=0) +if(ss-sd!=0) y = tPtr->docHeight+ss-sd; break; - } else { + } else { tPtr->flags.laidOut = False; } } - + tb = tb->next; } - if (nitems > 0) - y += layOutLine(tPtr, items, nitems, x, y); + if (nitems > 0) + y += layOutLine(tPtr, items, nitems, x, y); if (tPtr->docHeight != y+10) { tPtr->docHeight = y+10; @@ -1760,29 +1763,29 @@ y = tPtr->docHeight+ss-sd; if(tPtr->docWidth > tPtr->visible.w && !tPtr->hS) { XEvent event; - + tPtr->flags.horizOnDemand = True; WMSetTextHasHorizontalScroller((WMText*)tPtr, True); event.type = Expose; handleEvents(&event, (void *)tPtr); - } else if(tPtr->docWidth <= tPtr->visible.w + } else if(tPtr->docWidth <= tPtr->visible.w && tPtr->hS && tPtr->flags.horizOnDemand ) { tPtr->flags.horizOnDemand = False; WMSetTextHasHorizontalScroller((WMText*)tPtr, False); } tPtr->flags.laidOut = True; - + if(items && itemsSize > 0) wfree(items); - + } static void textDidResize(W_ViewDelegate *self, WMView *view) -{ +{ Text *tPtr = (Text *)view->self; unsigned short w = tPtr->view->size.width; unsigned short h = tPtr->view->size.height; @@ -1790,13 +1793,13 @@ textDidResize(W_ViewDelegate *self, WMView *view) rel = (tPtr->flags.relief == WRFlat); - if (tPtr->ruler && tPtr->flags.rulerShown) { + if (tPtr->ruler && tPtr->flags.rulerShown) { WMMoveWidget(tPtr->ruler, 2, 2); WMResizeWidget(tPtr->ruler, w - 4, 40); rh = 40; - } - - if (tPtr->vS) { + } + + if (tPtr->vS) { WMMoveWidget(tPtr->vS, 1 - (rel?1:0), rh + 1 - (rel?1:0)); WMResizeWidget(tPtr->vS, 20, h - rh - 2 + (rel?2:0)); vw = 20; @@ -1827,18 +1830,18 @@ textDidResize(W_ViewDelegate *self, WMView *view) tPtr->db = (Pixmap) NULL; } - if (tPtr->visible.w < 40) + if (tPtr->visible.w < 40) tPtr->visible.w = 40; - if (tPtr->visible.h < 20) + if (tPtr->visible.h < 20) tPtr->visible.h = 20; - - if(!tPtr->db) { - tPtr->db = XCreatePixmap(tPtr->view->screen->display, - tPtr->view->window, tPtr->visible.w, + + if(!tPtr->db) { + tPtr->db = XCreatePixmap(tPtr->view->screen->display, + tPtr->view->window, tPtr->visible.w, tPtr->visible.h, tPtr->view->screen->depth); } } - + WMThawText(tPtr); } @@ -1860,10 +1863,10 @@ clearText(Text *tPtr) tPtr->docHeight = tPtr->docWidth = 0; tPtr->cursor.x = -23; - if (!tPtr->firstTextBlock) + if (!tPtr->firstTextBlock) return; - while (tPtr->currentTextBlock) + while (tPtr->currentTextBlock) WMDestroyTextBlock(tPtr, WMRemoveTextBlock(tPtr)); tPtr->firstTextBlock = NULL; @@ -1882,7 +1885,7 @@ deleteTextInteractively(Text *tPtr, KeySym ksym) Bool back = (Bool) (ksym == XK_BackSpace); Bool done = 1, wasFirst = 0; - if (!tPtr->flags.editable) + if (!tPtr->flags.editable) return; if ( !(tb = tPtr->currentTextBlock) ) @@ -1897,7 +1900,7 @@ deleteTextInteractively(Text *tPtr, KeySym ksym) wasFirst = tb->first; if (back && tPtr->tpos < 1) { if (tb->prior) { - if(tb->prior->blank) { + if(tb->prior->blank) { tPtr->currentTextBlock = tb->prior; WMRemoveTextBlock(tPtr); tPtr->currentTextBlock = tb; @@ -1911,7 +1914,7 @@ deleteTextInteractively(Text *tPtr, KeySym ksym) WMRemoveTextBlock(tPtr); tb = prior; } else { - tb = tb->prior; + tb = tb->prior; } if(tb->graphic) @@ -1922,7 +1925,7 @@ deleteTextInteractively(Text *tPtr, KeySym ksym) tPtr->currentTextBlock = tb; done = 1; if(wasFirst) { - if(tb->next) + if(tb->next) tb->next->first = False; layOutDocument(tPtr); return; @@ -1941,7 +1944,7 @@ deleteTextInteractively(Text *tPtr, KeySym ksym) done = 0; } - /* if there are no characters left to back over in the textblock, + /* if there are no characters left to back over in the textblock, but it still has characters to the right of the cursor: */ if ( (back? (tPtr->tpos == 0 && !done) : ( tPtr->tpos >= tb->used)) || tb->graphic) { @@ -1950,10 +1953,10 @@ deleteTextInteractively(Text *tPtr, KeySym ksym) if(tb->blank) { TextBlock *sibling = (back? tb->prior : tb->next); - if(tb->used == 0 || tb->graphic) + if(tb->used == 0 || tb->graphic) WMDestroyTextBlock(tPtr, WMRemoveTextBlock(tPtr)); - if (sibling) { + if (sibling) { tPtr->currentTextBlock = sibling; if(tb->graphic) tPtr->tpos = (back? 1 : 0); @@ -1963,13 +1966,13 @@ deleteTextInteractively(Text *tPtr, KeySym ksym) /* no more chars, so mark it as blank */ } else if(tb->used == 0) { tb->blank = 1; - } else if(tb->graphic) { + } else if(tb->graphic) { Bool hasNext = (Bool)(tb->next); WMDestroyTextBlock(tPtr, WMRemoveTextBlock(tPtr)); - if(hasNext) { + if(hasNext) { tPtr->tpos = 0; - } else if(tPtr->currentTextBlock) { + } else if(tPtr->currentTextBlock) { tPtr->tpos = (tPtr->currentTextBlock->graphic? 1 : tPtr->currentTextBlock->used); } @@ -1978,7 +1981,7 @@ deleteTextInteractively(Text *tPtr, KeySym ksym) layOutDocument(tPtr); } - + static void insertTextInteractively(Text *tPtr, char *text, int len) @@ -1994,18 +1997,18 @@ insertTextInteractively(Text *tPtr, char *text, int len) return; - if(tPtr->flags.ignoreNewLine && *text == '\n' && len == 1) + if(tPtr->flags.ignoreNewLine && *text == '\n' && len == 1) return; - if (tPtr->flags.ownsSelection) + if (tPtr->flags.ownsSelection) removeSelection(tPtr); if (tPtr->flags.ignoreNewLine) { int i; for(i=0; itpos>0 && tPtr->tpos < tb->used - && !tb->graphic && tb->text) { + if (tPtr->tpos>0 && tPtr->tpos < tb->used + && !tb->graphic && tb->text) { unsigned short savePos = tPtr->tpos; void *ntb = WMCreateTextBlockWithText( @@ -2047,42 +2050,42 @@ insertTextInteractively(Text *tPtr, char *text, int len) tb->d.font, tb->color, True, tb->used - tPtr->tpos); if(tb->sections[0].end == tPtr->tpos) - WMAppendTextBlock(tPtr, WMCreateTextBlockWithText(tPtr, + WMAppendTextBlock(tPtr, WMCreateTextBlockWithText(tPtr, NULL, tb->d.font, tb->color, True, 0)); tb->used = savePos; WMAppendTextBlock(tPtr, ntb); tPtr->tpos = 0; - } else if (tPtr->tpos == tb->used) { - if(tPtr->flags.indentNewLine) { - WMAppendTextBlock(tPtr, WMCreateTextBlockWithText(tPtr, + } else if (tPtr->tpos == tb->used) { + if(tPtr->flags.indentNewLine) { + WMAppendTextBlock(tPtr, WMCreateTextBlockWithText(tPtr, " ", tb->d.font, tb->color, True, 4)); tPtr->tpos = 4; } else { - WMAppendTextBlock(tPtr, WMCreateTextBlockWithText(tPtr, + WMAppendTextBlock(tPtr, WMCreateTextBlockWithText(tPtr, NULL, tb->d.font, tb->color, True, 0)); tPtr->tpos = 0; } - } else if (tPtr->tpos == 0) { - if(tPtr->flags.indentNewLine) { - WMPrependTextBlock(tPtr, WMCreateTextBlockWithText(tPtr, + } else if (tPtr->tpos == 0) { + if(tPtr->flags.indentNewLine) { + WMPrependTextBlock(tPtr, WMCreateTextBlockWithText(tPtr, " ", tb->d.font, tb->color, True, 4)); } else { - WMPrependTextBlock(tPtr, WMCreateTextBlockWithText(tPtr, + WMPrependTextBlock(tPtr, WMCreateTextBlockWithText(tPtr, NULL, tb->d.font, tb->color, True, 0)); } tPtr->tpos = 0; - if(tPtr->currentTextBlock->next) + if(tPtr->currentTextBlock->next) tPtr->currentTextBlock = tPtr->currentTextBlock->next; } } - } else { + } else { if (tb->used + len >= tb->allocated) { tb->allocated = reqBlockSize(tb->used+len); tb->text = wrealloc(tb->text, tb->allocated); } - + if (tb->blank) { memcpy(tb->text, text, len); tb->used = len; @@ -2105,16 +2108,16 @@ insertTextInteractively(Text *tPtr, char *text, int len) } -static void +static void selectRegion(Text *tPtr, int x, int y) { - if (x < 0 || y < 0) + if (x < 0 || y < 0) return; y += (tPtr->flags.rulerShown? 40: 0); y += tPtr->vpos; - if (y>10) + if (y>10) y -= 10; /* the original offset */ x -= tPtr->visible.x-2; @@ -2154,7 +2157,7 @@ requestHandler(WMView *view, Atom selection, Atom target, void *cdata, { Text *tPtr = view->self; Display *dpy = tPtr->view->screen->display; - Atom _TARGETS; + Atom _TARGETS; Atom TEXT = XInternAtom(dpy, "TEXT", False); Atom COMPOUND_TEXT = XInternAtom(dpy, "COMPOUND_TEXT", False); WMData *data = NULL; @@ -2162,7 +2165,7 @@ requestHandler(WMView *view, Atom selection, Atom target, void *cdata, if (target == XA_STRING || target == TEXT || target == COMPOUND_TEXT) { char *text = WMGetTextSelectedStream(tPtr); - + if (text) { data = WMCreateDataWithBytes(text, strlen(text)); WMSetDataFormat(data, TYPETEXT); @@ -2174,22 +2177,22 @@ requestHandler(WMView *view, Atom selection, Atom target, void *cdata, _TARGETS = XInternAtom(dpy, "TARGETS", False); if (target == _TARGETS) { Atom *ptr; - + ptr = wmalloc(4 * sizeof(Atom)); ptr[0] = _TARGETS; ptr[1] = XA_STRING; ptr[2] = TEXT; ptr[3] = COMPOUND_TEXT; - + data = WMCreateDataWithBytes(ptr, 4*4); WMSetDataFormat(data, 32); - + *type = target; return data; - } - + } + return NULL; -} +} static void @@ -2200,7 +2203,7 @@ lostHandler(WMView *view, Atom selection, void *cdata) static WMSelectionProcs selectionHandler = { - requestHandler, lostHandler, NULL + requestHandler, lostHandler, NULL }; @@ -2212,8 +2215,8 @@ ownershipObserver(void *observerData, WMNotification *notification) } -static void -autoSelectText(Text *tPtr, int clicks) +static void +autoSelectText(Text *tPtr, int clicks) { int x, start; TextBlock *tb; @@ -2224,7 +2227,7 @@ autoSelectText(Text *tPtr, int clicks) if(clicks == 2) { - + switch(tb->text[tPtr->tpos]) { case ' ': return; /* @@ -2238,7 +2241,7 @@ autoSelectText(Text *tPtr, int clicks) tPtr->sel.y = tPtr->cursor.y+5; tPtr->sel.h = 6;/*tPtr->cursor.h-10;*/ - if(tb->graphic) { + if(tb->graphic) { tPtr->sel.x = tb->sections[0].x; tPtr->sel.w = tb->sections[0].w; } else { @@ -2249,13 +2252,13 @@ autoSelectText(Text *tPtr, int clicks) start--; x = tPtr->cursor.x; - if(tPtr->tpos > start){ - x -= WMWidthOfString(font, &tb->text[start], + if(tPtr->tpos > start){ + x -= WMWidthOfString(font, &tb->text[start], tPtr->tpos - start); } tPtr->sel.x = (x<0?0:x)+1; - if((mark = strchr(&tb->text[start], ahead))) { + if((mark = strchr(&tb->text[start], ahead))) { tPtr->sel.w = WMWidthOfString(font, &tb->text[start], (int)(mark - &tb->text[start])); } else if(tb->used > start) { @@ -2264,19 +2267,19 @@ autoSelectText(Text *tPtr, int clicks) } } - } else if(clicks == 3) { + } else if(clicks == 3) { TextBlock *cur = tb; - + while(tb && !tb->first) { tb = tb->prior; } tPtr->sel.y = tb->sections[0]._y; - + tb = cur; - while(tb->next && !tb->next->first) { + while(tb->next && !tb->next->first) { tb = tb->next; } - tPtr->sel.h = tb->sections[tb->nsections-1]._y + tPtr->sel.h = tb->sections[tb->nsections-1]._y + 5 - tPtr->sel.y; tPtr->sel.x = 0; @@ -2284,8 +2287,8 @@ autoSelectText(Text *tPtr, int clicks) tPtr->clicked.x = 0; /* only for now, fix sel. code */ } - if (!tPtr->flags.ownsSelection) { - WMCreateSelectionHandler(tPtr->view, + if (!tPtr->flags.ownsSelection) { + WMCreateSelectionHandler(tPtr->view, XA_PRIMARY, tPtr->lastClickTime, &selectionHandler, NULL); tPtr->flags.ownsSelection = True; } @@ -2320,12 +2323,12 @@ handleTextKeyPress(Text *tPtr, XEvent *event) if (((XKeyEvent *) event)->state & ControlMask) control_pressed = True; buffer[XLookupString(&event->xkey, buffer, 63, &ksym, NULL)] = 0; - + switch(ksym) { case XK_Home: if((tPtr->currentTextBlock = tPtr->firstTextBlock)) - tPtr->tpos = 0; + tPtr->tpos = 0; updateCursorPosition(tPtr); paintText(tPtr); break; @@ -2335,19 +2338,19 @@ handleTextKeyPress(Text *tPtr, XEvent *event) if(tPtr->currentTextBlock->graphic) tPtr->tpos = 1; else - tPtr->tpos = tPtr->currentTextBlock->used; + tPtr->tpos = tPtr->currentTextBlock->used; } updateCursorPosition(tPtr); paintText(tPtr); break; - case XK_Left: + case XK_Left: if(!(tb = tPtr->currentTextBlock)) break; - if(tb->graphic) + if(tb->graphic) goto L_imaGFX; - - if(tPtr->tpos==0) { + + if(tPtr->tpos==0) { L_imaGFX: if(tb->prior) { tPtr->currentTextBlock = tb->prior; @@ -2364,10 +2367,10 @@ handleTextKeyPress(Text *tPtr, XEvent *event) paintText(tPtr); break; - case XK_Right: + case XK_Right: if(!(tb = tPtr->currentTextBlock)) break; - if(tb->graphic) + if(tb->graphic) goto R_imaGFX; if(tPtr->tpos == tb->used) { R_imaGFX: @@ -2376,7 +2379,7 @@ handleTextKeyPress(Text *tPtr, XEvent *event) tPtr->tpos = 0; if(!tb->next->first && tb->next->used>0) tPtr->tpos++; - } else { + } else { if(tb->graphic) tPtr->tpos = 1; else @@ -2386,17 +2389,17 @@ handleTextKeyPress(Text *tPtr, XEvent *event) updateCursorPosition(tPtr); paintText(tPtr); break; - + case XK_Down: - cursorToTextPosition(tPtr, tPtr->cursor.x + tPtr->visible.x, + cursorToTextPosition(tPtr, tPtr->cursor.x + tPtr->visible.x, tPtr->clicked.y + tPtr->cursor.h - tPtr->vpos); - paintText(tPtr); + paintText(tPtr); break; - case XK_Up: - cursorToTextPosition(tPtr, tPtr->cursor.x + tPtr->visible.x, + case XK_Up: + cursorToTextPosition(tPtr, tPtr->cursor.x + tPtr->visible.x, tPtr->visible.y + tPtr->cursor.y - tPtr->vpos - 3); - paintText(tPtr); + paintText(tPtr); break; case XK_BackSpace: @@ -2429,7 +2432,7 @@ handleTextKeyPress(Text *tPtr, XEvent *event) paintText(tPtr); } else if (control_pressed && ksym==XK_r) { - Bool i = !tPtr->flags.rulerShown; + Bool i = !tPtr->flags.rulerShown; WMShowTextRuler(tPtr, i); tPtr->flags.rulerShown = i; } else if (control_pressed && *buffer == '\a') { @@ -2456,7 +2459,7 @@ pasteText(WMView *view, Atom selection, Atom target, Time timestamp, if (data) { text = (char*)WMDataBytes(data); - + if (tPtr->parser) { (tPtr->parser) (tPtr, (void *) text); layOutDocument(tPtr); @@ -2466,9 +2469,9 @@ pasteText(WMView *view, Atom selection, Atom target, Time timestamp, } else { int n; - + text = XFetchBuffer(tPtr->view->screen->display, &n, 0); - + if (text) { text[n] = 0; if (tPtr->parser) { @@ -2479,8 +2482,8 @@ pasteText(WMView *view, Atom selection, Atom target, Time timestamp, paintText(tPtr); XFree(text); - } - } + } + } } @@ -2492,33 +2495,33 @@ handleActionEvents(XEvent *event, void *data) Text *tPtr = (Text *)data; Display *dpy = event->xany.display; KeySym ksym; - + switch (event->type) { case KeyPress: - ksym = XLookupKeysym((XKeyEvent*)event, 0); - if (ksym == XK_Shift_R || ksym == XK_Shift_L) { + ksym = XLookupKeysym((XKeyEvent*)event, 0); + if (ksym == XK_Shift_R || ksym == XK_Shift_L) { tPtr->flags.extendSelection = True; return; - } + } if (tPtr->flags.focused) { - XGrabPointer(dpy, W_VIEW(tPtr)->window, False, + XGrabPointer(dpy, W_VIEW(tPtr)->window, False, PointerMotionMask|ButtonPressMask|ButtonReleaseMask, - GrabModeAsync, GrabModeAsync, None, + GrabModeAsync, GrabModeAsync, None, tPtr->view->screen->invisibleCursor, CurrentTime); tPtr->flags.pointerGrabbed = True; handleTextKeyPress(tPtr, event); - + } break; case KeyRelease: - ksym = XLookupKeysym((XKeyEvent*)event, 0); + ksym = XLookupKeysym((XKeyEvent*)event, 0); if (ksym == XK_Shift_R || ksym == XK_Shift_L) { tPtr->flags.extendSelection = False; return; /* end modify flag so selection can be extended */ - } + } break; @@ -2528,52 +2531,40 @@ handleActionEvents(XEvent *event, void *data) tPtr->flags.pointerGrabbed = False; XUngrabPointer(dpy, CurrentTime); } - + if(tPtr->flags.waitingForSelection) break; if ((event->xmotion.state & Button1Mask)) { - TextBlock *tb = tPtr->currentTextBlock; - - if(tb && tPtr->flags.isOverGraphic && - tb->graphic && !tb->object) { - WMSize offs; - WMPixmap *pixmap = tb->d.pixmap; - char *types[2] = {"application/X-image", NULL}; - offs.width = 2; - offs.height = 2; - - WMDragImageFromView(tPtr->view, pixmap, types, - wmkpoint(event->xmotion.x_root, event->xmotion.y_root), - offs, event, True); + if (WMIsDraggingFromView(tPtr->view)) { + WMDragImageFromView(tPtr->view, event); + break; + } - - } else { - if (!tPtr->flags.ownsSelection) { - WMCreateSelectionHandler(tPtr->view, - XA_PRIMARY, event->xbutton.time, - &selectionHandler, NULL); - tPtr->flags.ownsSelection = True; - } + if (!tPtr->flags.ownsSelection) { + WMCreateSelectionHandler(tPtr->view, + XA_PRIMARY, event->xbutton.time, + &selectionHandler, NULL); + tPtr->flags.ownsSelection = True; } selectRegion(tPtr, event->xmotion.x, event->xmotion.y); break; } - + mouseOverObject(tPtr, event->xmotion.x, event->xmotion.y); - break; + break; - case ButtonPress: + case ButtonPress: if (tPtr->flags.pointerGrabbed) { tPtr->flags.pointerGrabbed = False; XUngrabPointer(dpy, CurrentTime); break; - } + } - if (tPtr->flags.waitingForSelection) + if (tPtr->flags.waitingForSelection) break; if (tPtr->flags.extendSelection && tPtr->flags.ownsSelection) { @@ -2581,17 +2572,17 @@ handleActionEvents(XEvent *event, void *data) return; } - if (tPtr->flags.ownsSelection) + if (tPtr->flags.ownsSelection) releaseSelection(tPtr); - - if (event->xbutton.button == Button1) { + + if (event->xbutton.button == Button1) { + TextBlock *tb = tPtr->currentTextBlock; if(WMIsDoubleClick(event)) { - TextBlock *tb = tPtr->currentTextBlock; - + tPtr->lastClickTime = event->xbutton.time; - if(tb && tb->graphic && !tb->object) { + if(tb && tb->graphic && !tb->object) { if(tPtr->delegate && tPtr->delegate->didDoubleClickOnPicture) { char *desc; @@ -2605,8 +2596,8 @@ handleActionEvents(XEvent *event, void *data) autoSelectText(tPtr, 2); } break; - } else if(event->xbutton.time - tPtr->lastClickTime - < WINGsConfiguration.doubleClickDelay) { + } else if (event->xbutton.time - tPtr->lastClickTime + < WINGsConfiguration.doubleClickDelay) { tPtr->lastClickTime = event->xbutton.time; autoSelectText(tPtr, 3); break; @@ -2614,21 +2605,27 @@ handleActionEvents(XEvent *event, void *data) if (!tPtr->flags.focused) { WMSetFocusToWidget(tPtr); - tPtr->flags.focused = True; - } + tPtr->flags.focused = True; + } else if (tb && tPtr->flags.isOverGraphic && + tb->graphic && !tb->object && tb->d.pixmap) { + + WMSetViewDragImage(tPtr->view, tb->d.pixmap); + WMDragImageFromView(tPtr->view, event); + break; + } tPtr->lastClickTime = event->xbutton.time; cursorToTextPosition(tPtr, event->xmotion.x, event->xmotion.y); paintText(tPtr); - } + } - if (event->xbutton.button + if (event->xbutton.button == WINGsConfiguration.mouseWheelDown) { WMScrollText(tPtr, 16); break; } - if (event->xbutton.button + if (event->xbutton.button == WINGsConfiguration.mouseWheelUp) { WMScrollText(tPtr, -16); break; @@ -2638,9 +2635,9 @@ handleActionEvents(XEvent *event, void *data) char *text = NULL; int n; - if (!tPtr->flags.editable) { + if (!tPtr->flags.editable) { XBell(dpy, 0); - break; + break; } if (!WMRequestSelection(tPtr->view, XA_PRIMARY, XA_STRING, @@ -2656,9 +2653,9 @@ handleActionEvents(XEvent *event, void *data) (tPtr->parser) (tPtr, (void *) text); layOutDocument(tPtr); } - else + else insertTextInteractively(tPtr, text, n); - + XFree(text); #if 0 NOTIFY(tPtr, didChange, WMTextDidChangeNotification, @@ -2670,7 +2667,7 @@ handleActionEvents(XEvent *event, void *data) } else { tPtr->flags.waitingForSelection = True; } - } + } break; } @@ -2680,32 +2677,35 @@ handleActionEvents(XEvent *event, void *data) tPtr->flags.pointerGrabbed = False; XUngrabPointer(dpy, CurrentTime); break; - } + } - if (tPtr->flags.waitingForSelection) + if (tPtr->flags.waitingForSelection) break; - } - + + if (WMIsDraggingFromView(tPtr->view)) + WMDragImageFromView(tPtr->view, event); + } + } -static void +static void handleEvents(XEvent *event, void *data) { Text *tPtr = (Text *)data; switch(event->type) { - case Expose: + case Expose: if (event->xexpose.count!=0) break; - if(tPtr->hS) { + if(tPtr->hS) { if (!(W_VIEW(tPtr->hS))->flags.realized) WMRealizeWidget(tPtr->hS); } - if(tPtr->vS) { + if(tPtr->vS) { if (!(W_VIEW(tPtr->vS))->flags.realized) WMRealizeWidget(tPtr->vS); } @@ -2716,13 +2716,13 @@ handleEvents(XEvent *event, void *data) } - if(!tPtr->db) + if(!tPtr->db) textDidResize(tPtr->view->delegate, tPtr->view); paintText(tPtr); break; - case FocusIn: + case FocusIn: if (W_FocusedViewOfToplevel(W_TopLevelOfView(tPtr->view)) != tPtr->view) return; @@ -2736,7 +2736,7 @@ handleEvents(XEvent *event, void *data) break; - case FocusOut: + case FocusOut: tPtr->flags.focused = False; paintText(tPtr); #if DO_BLINK @@ -2762,7 +2762,10 @@ handleEvents(XEvent *event, void *data) WMReleaseColor(tPtr->dColor); WMDeleteSelectionHandler(tPtr->view, XA_PRIMARY, CurrentTime); WMRemoveNotificationObserver(tPtr); - + + WMFreeArray(tPtr->xdndSourceTypes); + WMFreeArray(tPtr->xdndDestinationTypes); + wfree(tPtr); break; @@ -2772,17 +2775,17 @@ handleEvents(XEvent *event, void *data) static void -insertPlainText(Text *tPtr, char *text) +insertPlainText(Text *tPtr, char *text) { char *start, *mark; void *tb = NULL; - + start = text; while (start) { mark = strchr(start, '\n'); if (mark) { - tb = WMCreateTextBlockWithText(tPtr, - start, tPtr->dFont, + tb = WMCreateTextBlockWithText(tPtr, + start, tPtr->dFont, tPtr->dColor, tPtr->flags.first, (int)(mark-start)); start = mark+1; tPtr->flags.first = True; @@ -2795,7 +2798,7 @@ insertPlainText(Text *tPtr, char *text) start = mark; } - if (tPtr->flags.prepend) + if (tPtr->flags.prepend) WMPrependTextBlock(tPtr, tb); else WMAppendTextBlock(tPtr, tb); @@ -2831,12 +2834,28 @@ rulerReleaseCallBack(WMWidget *w, void *self) return; } -static unsigned -draggingSourceOperation(WMView *self, Bool local) + +static WMArray* +dropDataTypes(WMView *self) +{ + return ((Text*)self->self)->xdndSourceTypes; +} + + +static WMDragOperationType +wantedDropOperation(WMView *self) { return WDOperationCopy; } + +static Bool +acceptDropOperation(WMView *self, WMDragOperationType allowedOperation) +{ + return (allowedOperation == WDOperationCopy); +} + + static WMData* fetchDragData(WMView *self, char *type) { @@ -2844,138 +2863,84 @@ fetchDragData(WMView *self, char *type) char *desc; WMData *data; - if (!tb) - return NULL; + if (strcmp(type, "text/plain")) { + if (!tb) + return NULL; -printf("type is [%s]\n", type); - desc = wmalloc(tb->used+1); - memcpy(desc, tb->text, tb->used); - desc[tb->used] = 0; - data = WMCreateDataWithBytes(desc, strlen(desc)+1); + desc = wmalloc(tb->used+1); + memcpy(desc, tb->text, tb->used); + desc[tb->used] = 0; + data = WMCreateDataWithBytes(desc, strlen(desc)+1); - wfree(desc); + wfree(desc); - return data; + return data; + } + + return NULL; } static WMDragSourceProcs _DragSourceProcs = { - draggingSourceOperation, + dropDataTypes, + wantedDropOperation, + NULL, + acceptDropOperation, NULL, NULL, fetchDragData }; -static unsigned -draggingEntered(WMView *self, WMDraggingInfo *info) +static WMArray* +requiredDataTypes(WMView *self, WMDragOperationType request, WMArray *sourceDataTypes) { -printf("draggingEntered\n"); - return WDOperationCopy; -} + return ((Text*)self->self)->xdndDestinationTypes; +} -static unsigned -draggingUpdated(WMView *self, WMDraggingInfo *info) +static WMDragOperationType +allowedOperation(WMView *self, WMDragOperationType request, WMArray *sourceDataTypes) { return WDOperationCopy; -} - - -static void -draggingExited(WMView *self, WMDraggingInfo *info) -{ -printf("draggingExited\n"); } -static Bool -prepareForDragOperation(WMView *self, WMDraggingInfo *info) -{ - printf("prepareForDragOperation\n"); - return True; -} - - -char *badbadbad; static void -receivedData(WMView *view, Atom selection, Atom target, Time timestamp, - void *cdata, WMData *data) -{ -badbadbad = wstrdup((char *)WMDataBytes(data)); -} - - -/* when it's done in WINGs, remove this */ - -Bool -requestDroppedData(WMView *view, WMDraggingInfo *info, char *type) -{ - WMScreen *scr = W_VIEW_SCREEN(view); - - if (!WMRequestSelection(scr->dragInfo.destView, - scr->xdndSelectionAtom, - XInternAtom(scr->display, type, False), - scr->dragInfo.timestamp, - receivedData, &scr->dragInfo)) { - wwarning("could not request data for dropped data"); - } - - { - XEvent ev; - - ev.type = ClientMessage; - ev.xclient.message_type = scr->xdndFinishedAtom; - ev.xclient.format = 32; - ev.xclient.window = info->destinationWindow; - ev.xclient.data.l[0] = 0; - ev.xclient.data.l[1] = 0; - ev.xclient.data.l[2] = 0; - ev.xclient.data.l[3] = 0; - ev.xclient.data.l[4] = 0; - - XSendEvent(scr->display, info->sourceWindow, False, 0, &ev); - XFlush(scr->display); - } - return True; -} - -static Bool -performDragOperation(WMView *self, WMDraggingInfo *info) +performDragOperation(WMView *self, WMArray *dropData, WMArray *operations, + WMPoint* dropLocation) { - WMColor *color; WMText *tPtr = (WMText *)self->self; - - if (!tPtr) - return True; + WMData* data; + char* colorName; + WMColor *color; - requestDroppedData(tPtr->view, info, "application/X-color"); - color = WMCreateNamedColor(W_VIEW_SCREEN(self), badbadbad, True); - if(color) { - WMSetTextSelectionColor(tPtr, color); - WMReleaseColor(color); - } - + if (tPtr) { + /* only one required type, implies only one drop data */ - return True; -} + /* get application/X-color if any */ + data = (WMData*)WMPopFromArray(dropData); + if (data != NULL) { + colorName = (char*)WMDataBytes(data); + color = WMCreateNamedColor(W_VIEW_SCREEN(self), colorName, True); -static void -concludeDragOperation(WMView *self, WMDraggingInfo *info) -{ - printf("concludeDragOperation\n"); + if(color) { + WMSetTextSelectionColor(tPtr, color); + WMReleaseColor(color); + } + } + } } - static WMDragDestinationProcs _DragDestinationProcs = { - draggingEntered, - draggingUpdated, - draggingExited, - prepareForDragOperation, + NULL, + requiredDataTypes, + allowedOperation, + NULL, performDragOperation, - concludeDragOperation -}; + NULL +}; char * @@ -2995,7 +2960,7 @@ getStream(WMText *tPtr, int sel, int array) (tPtr->writer) (tPtr, (void *) text); return text; } - + tb = tPtr->firstTextBlock; while (tb) { @@ -3023,10 +2988,10 @@ getStream(WMText *tPtr, int sel, int array) memcpy(&text[where], tb->text, tb->used); where += tb->used; - + } else if (sel && tb->selected) { - if (!tPtr->flags.ignoreNewLine && tb->blank) { + if (!tPtr->flags.ignoreNewLine && tb->blank) { text = wrealloc(text, where+1); text[where++] = '\n'; } @@ -3035,16 +3000,16 @@ getStream(WMText *tPtr, int sel, int array) goto _gSnext; text = wrealloc(text, where+(tb->s_end - tb->s_begin)); - memcpy(&text[where], &tb->text[tb->s_begin], + memcpy(&text[where], &tb->text[tb->s_begin], tb->s_end - tb->s_begin); - where += tb->s_end - tb->s_begin; + where += tb->s_end - tb->s_begin; } - + } _gSnext:tb = tb->next; } - + /* +1 for the end of string, let's be nice */ text = wrealloc(text, where+1); text[where] = 0; @@ -3052,14 +3017,14 @@ _gSnext:tb = tb->next; } -static void +static void releaseStreamObjects(void *data) { if(data) wfree(data); } -WMArray * +WMArray * getStreamObjects(WMText *tPtr, int sel) { WMArray *array = WMCreateArrayWithDestructor(4, releaseStreamObjects); @@ -3071,42 +3036,62 @@ getStreamObjects(WMText *tPtr, int sel) stream = getStream(tPtr, sel, 1); if(!stream) return NULL; - + start = stream; while (start) { fa = strchr(start, 0xFA); if (fa) { - if((int)(fa - start)>0) { + if((int)(fa - start)>0) { desc = start; desc[(int)(fa - start)] = 0; data = WMCreateDataWithBytes((void *)desc, (int)(fa - start)); WMSetDataFormat(data, TYPETEXT); WMAddToArray(array, (void *) data); } - + len = *(fa+1)*0xff + *(fa+2); data = WMCreateDataWithBytes((void *)(fa+4), len); WMSetDataFormat(data, *(fa+3)); WMAddToArray(array, (void *) data); start = fa + len + 4; - + } else { if (start && strlen(start)) { data = WMCreateDataWithBytes((void *)start, strlen(start)); WMSetDataFormat(data, TYPETEXT); WMAddToArray(array, (void *) data); - } + } start = fa; - } - } + } + } wfree(stream); return array; } -WMText * +#define XDND_TEXT_DATA_TYPE "text/plain" +#define XDND_COLOR_DATA_TYPE "application/X-color" +static WMArray* +getXdndSourceTypeArray() +{ + WMArray *types = WMCreateArray(1); + WMAddToArray(types, XDND_TEXT_DATA_TYPE); + return types; +} + + +static WMArray* +getXdndDestinationTypeArray() +{ + WMArray *types = WMCreateArray(1); + WMAddToArray(types, XDND_COLOR_DATA_TYPE); + return types; +} + + +WMText* WMCreateTextForDocumentType(WMWidget *parent, WMAction *parser, WMAction *writer) { Text *tPtr; @@ -3163,23 +3148,25 @@ WMCreateTextForDocumentType(WMWidget *parent, WMAction *parser, WMAction *writer #endif WMCreateEventHandler(tPtr->view, ExposureMask|StructureNotifyMask - |EnterWindowMask|LeaveWindowMask|FocusChangeMask, + |EnterWindowMask|LeaveWindowMask|FocusChangeMask, handleEvents, tPtr); WMCreateEventHandler(tPtr->view, ButtonReleaseMask|ButtonPressMask - |KeyReleaseMask|KeyPressMask|Button1MotionMask, + |KeyReleaseMask|KeyPressMask|Button1MotionMask, handleActionEvents, tPtr); - - WMAddNotificationObserver(ownershipObserver, tPtr, + + WMAddNotificationObserver(ownershipObserver, tPtr, WMSelectionOwnerDidChangeNotification, tPtr); - + WMSetViewDragSourceProcs(tPtr->view, &_DragSourceProcs); WMSetViewDragDestinationProcs(tPtr->view, &_DragDestinationProcs); { - char *types[3] = {"application/X-color", "application/X-image", NULL}; + WMArray *types = WMCreateArray(2); + WMAddToArray(types, "application/X-color"); + WMAddToArray(types, "application/X-image"); WMRegisterViewForDraggedTypes(tPtr->view, types); } @@ -3204,7 +3191,7 @@ WMCreateTextForDocumentType(WMWidget *parent, WMAction *parser, WMAction *writer tPtr->visible.x = tPtr->visible.y = 2; tPtr->visible.h = tPtr->view->size.height; tPtr->visible.w = tPtr->view->size.width - 4; - + tPtr->cursor.x = -23; tPtr->docWidth = 0; @@ -3219,7 +3206,7 @@ WMCreateTextForDocumentType(WMWidget *parent, WMAction *parser, WMAction *writer tPtr->nMargins = 1; tPtr->flags.rulerShown = False; - tPtr->flags.monoFont = False; + tPtr->flags.monoFont = False; tPtr->flags.focused = False; tPtr->flags.editable = True; tPtr->flags.ownsSelection = False; @@ -3242,16 +3229,19 @@ WMCreateTextForDocumentType(WMWidget *parent, WMAction *parser, WMAction *writer tPtr->flags.alignment = WALeft; tPtr->flags.first = True; + tPtr->xdndSourceTypes = getXdndSourceTypeArray(); + tPtr->xdndDestinationTypes = getXdndDestinationTypeArray(); + return tPtr; } -void -WMPrependTextStream(WMText *tPtr, char *text) +void +WMPrependTextStream(WMText *tPtr, char *text) { CHECK_CLASS(tPtr, WC_Text); if(!text) { - if (tPtr->flags.ownsSelection) + if (tPtr->flags.ownsSelection) releaseSelection(tPtr); clearText(tPtr); updateScrollers(tPtr); @@ -3272,13 +3262,13 @@ WMPrependTextStream(WMText *tPtr, char *text) } -void -WMAppendTextStream(WMText *tPtr, char *text) +void +WMAppendTextStream(WMText *tPtr, char *text) { CHECK_CLASS(tPtr, WC_Text); if(!text) { - if (tPtr->flags.ownsSelection) + if (tPtr->flags.ownsSelection) releaseSelection(tPtr); clearText(tPtr); updateScrollers(tPtr); @@ -3292,7 +3282,7 @@ WMAppendTextStream(WMText *tPtr, char *text) insertPlainText(tPtr, text); tPtr->flags.needsLayOut = True; - if(tPtr->currentTextBlock) { + if(tPtr->currentTextBlock) { if(tPtr->currentTextBlock->graphic) tPtr->tpos = 1; else @@ -3356,7 +3346,7 @@ WMCreateTextBlockWithObject(WMText *tPtr, WMWidget *w, { TextBlock *tb; - if (!w || !description || !color) + if (!w || !description || !color) return NULL; tb = wmalloc(sizeof(TextBlock)); @@ -3364,7 +3354,7 @@ WMCreateTextBlockWithObject(WMText *tPtr, WMWidget *w, tb->text = wstrdup(description); tb->used = strlen(description); tb->blank = False; - tb->d.widget = w; + tb->d.widget = w; tb->color = WMRetainColor(color); tb->marginN = newMargin(tPtr, NULL); tb->allocated = extraInfo; @@ -3385,13 +3375,13 @@ WMCreateTextBlockWithObject(WMText *tPtr, WMWidget *w, void* -WMCreateTextBlockWithPixmap(WMText *tPtr, WMPixmap *p, +WMCreateTextBlockWithPixmap(WMText *tPtr, WMPixmap *p, char *description, WMColor *color, unsigned short first, unsigned short extraInfo) { TextBlock *tb; - if (!p || !description || !color) + if (!p || !description || !color) return NULL; tb = wmalloc(sizeof(TextBlock)); @@ -3399,7 +3389,7 @@ WMCreateTextBlockWithPixmap(WMText *tPtr, WMPixmap *p, tb->text = wstrdup(description); tb->used = strlen(description); tb->blank = False; - tb->d.pixmap = WMRetainPixmap(p); + tb->d.pixmap = WMRetainPixmap(p); tb->color = WMRetainColor(color); tb->marginN = newMargin(tPtr, NULL); tb->allocated = extraInfo; @@ -3420,12 +3410,12 @@ WMCreateTextBlockWithPixmap(WMText *tPtr, WMPixmap *p, void* -WMCreateTextBlockWithText(WMText *tPtr, char *text, WMFont *font, WMColor *color, +WMCreateTextBlockWithText(WMText *tPtr, char *text, WMFont *font, WMColor *color, unsigned short first, unsigned short len) { TextBlock *tb; - if (!font || !color) + if (!font || !color) return NULL; tb = wmalloc(sizeof(TextBlock)); @@ -3434,7 +3424,7 @@ WMCreateTextBlockWithText(WMText *tPtr, char *text, WMFont *font, WMColor *color tb->text = (char *)wmalloc(tb->allocated); memset(tb->text, 0, tb->allocated); - if (len < 1|| !text || (*text == '\n' && len==1 )) { + if (len < 1|| !text || (*text == '\n' && len==1 )) { *tb->text = ' '; tb->used = 1; tb->blank = True; @@ -3462,9 +3452,9 @@ WMCreateTextBlockWithText(WMText *tPtr, char *text, WMFont *font, WMColor *color } -void -WMSetTextBlockProperties(WMText *tPtr, void *vtb, unsigned int first, - unsigned int kanji, unsigned int underlined, int script, +void +WMSetTextBlockProperties(WMText *tPtr, void *vtb, unsigned int first, + unsigned int kanji, unsigned int underlined, int script, WMRulerMargins *margins) { TextBlock *tb = (TextBlock *) vtb; @@ -3480,8 +3470,8 @@ WMSetTextBlockProperties(WMText *tPtr, void *vtb, unsigned int first, void -WMGetTextBlockProperties(WMText *tPtr, void *vtb, unsigned int *first, - unsigned int *kanji, unsigned int *underlined, int *script, +WMGetTextBlockProperties(WMText *tPtr, void *vtb, unsigned int *first, + unsigned int *kanji, unsigned int *underlined, int *script, WMRulerMargins *margins) { TextBlock *tb = (TextBlock *) vtb; @@ -3522,7 +3512,7 @@ WMPrependTextBlock(WMText *tPtr, void *vtb) if (!tPtr->lastTextBlock || !tPtr->firstTextBlock) { tb->next = tb->prior = NULL; tb->first = True; - tPtr->lastTextBlock = tPtr->firstTextBlock + tPtr->lastTextBlock = tPtr->firstTextBlock = tPtr->currentTextBlock = tb; return; } @@ -3556,7 +3546,7 @@ WMAppendTextBlock(WMText *tPtr, void *vtb) if(tb->object) { WMWidget *w = tb->d.widget; if (W_CLASS(w) != WC_TextField && W_CLASS(w) != WC_Text) { - (W_VIEW(w))->attribs.cursor = + (W_VIEW(w))->attribs.cursor = tPtr->view->screen->defaultCursor; (W_VIEW(w))->attribFlags |= CWOverrideRedirect | CWCursor; } @@ -3572,7 +3562,7 @@ WMAppendTextBlock(WMText *tPtr, void *vtb) if (!tPtr->lastTextBlock || !tPtr->firstTextBlock) { tb->next = tb->prior = NULL; tb->first = True; - tPtr->lastTextBlock = tPtr->firstTextBlock + tPtr->lastTextBlock = tPtr->firstTextBlock = tPtr->currentTextBlock = tb; return; } @@ -3585,7 +3575,7 @@ WMAppendTextBlock(WMText *tPtr, void *vtb) tb->prior = tPtr->currentTextBlock; if (tPtr->currentTextBlock->next) tPtr->currentTextBlock->next->prior = tb; - + tPtr->currentTextBlock->next = tb; if (!tb->next) @@ -3596,7 +3586,7 @@ WMAppendTextBlock(WMText *tPtr, void *vtb) void* -WMRemoveTextBlock(WMText *tPtr) +WMRemoveTextBlock(WMText *tPtr) { TextBlock *tb = NULL; @@ -3613,9 +3603,9 @@ WMRemoveTextBlock(WMText *tPtr) WMUnmapWidget(tb->d.widget); } } - + if (tPtr->currentTextBlock == tPtr->firstTextBlock) { - if (tPtr->currentTextBlock->next) + if (tPtr->currentTextBlock->next) tPtr->currentTextBlock->next->prior = NULL; tPtr->firstTextBlock = tPtr->currentTextBlock->next; @@ -3630,7 +3620,7 @@ WMRemoveTextBlock(WMText *tPtr) tPtr->currentTextBlock->next->prior = tPtr->currentTextBlock->prior; tPtr->currentTextBlock = tPtr->currentTextBlock->next; } - + return (void *)tb; } @@ -3645,7 +3635,7 @@ destroyWidget(WMWidget *widget) #endif -void +void WMDestroyTextBlock(WMText *tPtr, void *vtb) { TextBlock *tb = (TextBlock *)vtb; @@ -3709,8 +3699,8 @@ WMSetTextBackgroundPixmap(WMText *tPtr, WMPixmap *pixmap) { if (tPtr->bgPixmap) WMReleasePixmap(tPtr->bgPixmap); - - if (pixmap) + + if (pixmap) tPtr->bgPixmap = WMRetainPixmap(pixmap); else tPtr->bgPixmap = NULL; @@ -3725,11 +3715,11 @@ WMSetTextRelief(WMText *tPtr, WMReliefType relief) } -void +void WMSetTextHasHorizontalScroller(WMText *tPtr, Bool shouldhave) { if (shouldhave && !tPtr->hS) { - tPtr->hS = WMCreateScroller(tPtr); + tPtr->hS = WMCreateScroller(tPtr); (W_VIEW(tPtr->hS))->attribs.cursor = tPtr->view->screen->defaultCursor; (W_VIEW(tPtr->hS))->attribFlags |= CWOverrideRedirect | CWCursor; WMSetScrollerArrowsPosition(tPtr->hS, WSAMinEnd); @@ -3753,7 +3743,7 @@ WMSetTextHasRuler(WMText *tPtr, Bool shouldhave) if(shouldhave && !tPtr->ruler) { tPtr->ruler = WMCreateRuler(tPtr); (W_VIEW(tPtr->ruler))->attribs.cursor = - tPtr->view->screen->defaultCursor; + tPtr->view->screen->defaultCursor; (W_VIEW(tPtr->ruler))->attribFlags |= CWOverrideRedirect | CWCursor; WMSetRulerReleaseAction(tPtr->ruler, rulerReleaseCallBack, tPtr); WMSetRulerMoveAction(tPtr->ruler, rulerMoveCallBack, tPtr); @@ -3763,7 +3753,7 @@ WMSetTextHasRuler(WMText *tPtr, Bool shouldhave) tPtr->ruler = NULL; } textDidResize(tPtr->view->delegate, tPtr->view); -} +} void WMShowTextRuler(WMText *tPtr, Bool show) @@ -3773,14 +3763,14 @@ WMShowTextRuler(WMText *tPtr, Bool show) if(tPtr->flags.monoFont) show = False; - + tPtr->flags.rulerShown = show; - if(show) { + if(show) { WMMapWidget(tPtr->ruler); } else { WMUnmapWidget(tPtr->ruler); } - + textDidResize(tPtr->view->delegate, tPtr->view); } @@ -3795,11 +3785,11 @@ WMGetTextRulerShown(WMText *tPtr) } -void +void WMSetTextHasVerticalScroller(WMText *tPtr, Bool shouldhave) { if (shouldhave && !tPtr->vS) { - tPtr->vS = WMCreateScroller(tPtr); + tPtr->vS = WMCreateScroller(tPtr); (W_VIEW(tPtr->vS))->attribs.cursor = tPtr->view->screen->defaultCursor; (W_VIEW(tPtr->vS))->attribFlags |= CWOverrideRedirect | CWCursor; WMSetScrollerArrowsPosition(tPtr->vS, WSAMaxEnd); @@ -3830,7 +3820,7 @@ WMScrollText(WMText *tPtr, int amount) if (tPtr->vpos > abs(amount)) tPtr->vpos += amount; else tPtr->vpos=0; scroll=True; - } + } } else { int limit = tPtr->docHeight - tPtr->visible.h; if (tPtr->vpos < limit) { @@ -3838,12 +3828,12 @@ WMScrollText(WMText *tPtr, int amount) else tPtr->vpos = limit; scroll = True; } - } + } if (scroll && tPtr->vpos != tPtr->prevVpos) { updateScrollers(tPtr); paintText(tPtr); - } + } tPtr->prevVpos = tPtr->vpos; return scroll; } @@ -3893,7 +3883,7 @@ WMGetTextIgnoresNewline(WMText *tPtr) void WMSetTextUsesMonoFont(WMText *tPtr, Bool mono) { - if (mono) { + if (mono) { if(tPtr->flags.rulerShown) WMShowTextRuler(tPtr, False); if(tPtr->flags.alignment != WALeft) @@ -3971,7 +3961,7 @@ WMGetTextInsertType(WMText *tPtr) } -void +void WMSetTextSelectionColor(WMText *tPtr, WMColor *color) { setSelectionProperty(tPtr, NULL, color, -1); @@ -4053,14 +4043,14 @@ WMGetTextSelectionUnderlined(WMText *tPtr) void -WMFreezeText(WMText *tPtr) +WMFreezeText(WMText *tPtr) { tPtr->flags.frozen = True; } void -WMThawText(WMText *tPtr) +WMThawText(WMText *tPtr) { tPtr->flags.frozen = False; @@ -4098,15 +4088,15 @@ mystrstr(char *haystack, char *needle, unsigned short len, char *end, return NULL; for (ptr = haystack; ptr < end; ptr++) { - if(caseSensitive) { + if(caseSensitive) { if (*ptr == *needle && !strncmp(ptr, needle, len)) return ptr; } else { - if (tolower(*ptr) == tolower(*needle) && + if (tolower(*ptr) == tolower(*needle) && !strncasecmp(ptr, needle, len)) return ptr; - + } } return NULL; @@ -4123,14 +4113,14 @@ mystrrstr(char *haystack, char *needle, unsigned short len, char *end, return NULL; for (ptr = haystack-2; ptr > end; ptr--) { - if(caseSensitive) { + if(caseSensitive) { if (*ptr == *needle && !strncmp(ptr, needle, len)) return ptr; } else { - if (tolower(*ptr) == tolower(*needle) && + if (tolower(*ptr) == tolower(*needle) && !strncasecmp(ptr, needle, len)) return ptr; - + } } return NULL; @@ -4152,7 +4142,7 @@ WMFindInTextStream(WMText *tPtr, char *needle, Bool direction, tPtr->firstTextBlock : tPtr->lastTextBlock) ) ){ return False; } - } else { + } else { /* if(tb != ((direction>0) ?tPtr->firstTextBlock : tPtr->lastTextBlock)) tb = (direction>0) ? tb->next : tb->prior; */ if(tb != tPtr->lastTextBlock) @@ -4161,17 +4151,17 @@ WMFindInTextStream(WMText *tPtr, char *needle, Bool direction, #endif tb = tPtr->currentTextBlock; pos = tPtr->tpos; - + while(tb) { - if (!tb->graphic) { + if (!tb->graphic) { - if(direction > 0) { + if(direction > 0) { if(pos+1 < tb->used) pos++; - if(tb->used - pos> 0 && pos > 0) { - mark = mystrstr(&tb->text[pos], needle, + if(tb->used - pos> 0 && pos > 0) { + mark = mystrstr(&tb->text[pos], needle, strlen(needle), &tb->text[tb->used], caseSensitive); } else { @@ -4184,8 +4174,8 @@ WMFindInTextStream(WMText *tPtr, char *needle, Bool direction, if(pos-1 > 0) pos--; - if(pos > 0) { - mark = mystrrstr(&tb->text[pos], needle, + if(pos > 0) { + mark = mystrrstr(&tb->text[pos], needle, strlen(needle), tb->text, caseSensitive); } else { tb = tb->prior; @@ -4194,10 +4184,10 @@ WMFindInTextStream(WMText *tPtr, char *needle, Bool direction, pos = tb->used; continue; } - } + } - if(mark) { + if(mark) { WMFont *font = tPtr->flags.monoFont?tPtr->dFont:tb->d.font; tPtr->tpos = (int)(mark - tb->text); @@ -4206,7 +4196,7 @@ WMFindInTextStream(WMText *tPtr, char *needle, Bool direction, tPtr->sel.y = tPtr->cursor.y+5; tPtr->sel.h = tPtr->cursor.h-10; tPtr->sel.x = tPtr->cursor.x +1; - tPtr->sel.w = WMIN(WMWidthOfString(font, + tPtr->sel.w = WMIN(WMWidthOfString(font, &tb->text[tPtr->tpos], strlen(needle)), tPtr->docWidth - tPtr->sel.x); tPtr->flags.ownsSelection = True; @@ -4215,9 +4205,9 @@ WMFindInTextStream(WMText *tPtr, char *needle, Bool direction, return True; } - } + } tb = (direction>0) ? tb->next : tb->prior; - if(tb) { + if(tb) { pos = (direction>0) ? 0 : tb->used; } } @@ -4227,7 +4217,7 @@ WMFindInTextStream(WMText *tPtr, char *needle, Bool direction, Bool -WMReplaceTextSelection(WMText *tPtr, char *replacement) +WMReplaceTextSelection(WMText *tPtr, char *replacement) { if (!tPtr->flags.ownsSelection) return False; diff --git a/WINGs/wview.c b/WINGs/wview.c index 62cf1402..37685441 100644 --- a/WINGs/wview.c +++ b/WINGs/wview.c @@ -14,10 +14,10 @@ char *WMViewRealizedNotification = "WMViewRealizedNotification"; #define EVENT_MASK \ - KeyPressMask|KeyReleaseMask|ButtonPressMask|ButtonReleaseMask| \ - EnterWindowMask|LeaveWindowMask|PointerMotionMask|ExposureMask| \ - VisibilityChangeMask|FocusChangeMask|PropertyChangeMask|\ - SubstructureNotifyMask|SubstructureRedirectMask + KeyPressMask|KeyReleaseMask|ButtonPressMask|ButtonReleaseMask| \ + EnterWindowMask|LeaveWindowMask|PointerMotionMask|ExposureMask| \ + VisibilityChangeMask|FocusChangeMask|PropertyChangeMask|\ + SubstructureNotifyMask|SubstructureRedirectMask static XSetWindowAttributes defAtts= { @@ -26,21 +26,21 @@ static XSetWindowAttributes defAtts= { CopyFromParent, /* border_pixmap */ 0, /* border_pixel */ ForgetGravity, /* bit_gravity */ - ForgetGravity, /* win_gravity */ + ForgetGravity, /* win_gravity */ NotUseful, /* backing_store */ (unsigned) ~0, /* backing_planes */ 0, /* backing_pixel */ False, /* save_under */ - EVENT_MASK, /* event_mask */ + EVENT_MASK, /* event_mask */ 0, /* do_not_propagate_mask */ False, /* override_redirect */ - None, /* colormap */ + None, /* colormap */ None /* cursor */ }; -static XContext ViewContext=0; /* context for views */ +static XContext ViewContext=0; /* context for views */ @@ -49,9 +49,9 @@ W_View* W_GetViewForXWindow(Display *display, Window window) { W_View *view; - + if (XFindContext(display, window, ViewContext, (XPointer*)&view)==0) { - return view; + return view; } return NULL; } @@ -63,20 +63,20 @@ unparentView(W_View *view) { /* remove from parent's children list */ if (view->parent!=NULL) { - W_View *ptr; - - ptr = view->parent->childrenList; - if (ptr == view) { - view->parent->childrenList = view->nextSister; - } else { - while (ptr!=NULL) { - if (ptr->nextSister == view) { - ptr->nextSister = view->nextSister; - break; - } - ptr = ptr->nextSister; - } - } + W_View *ptr; + + ptr = view->parent->childrenList; + if (ptr == view) { + view->parent->childrenList = view->nextSister; + } else { + while (ptr!=NULL) { + if (ptr->nextSister == view) { + ptr->nextSister = view->nextSister; + break; + } + ptr = ptr->nextSister; + } + } } view->parent = NULL; } @@ -89,14 +89,14 @@ adoptChildView(W_View *view, W_View *child) /* add to end of children list of parent */ if (view->childrenList == NULL) { - view->childrenList = child; + view->childrenList = child; } else { - W_View *ptr; - - ptr = view->childrenList; - while (ptr->nextSister!=NULL) - ptr = ptr->nextSister; - ptr->nextSister = child; + W_View *ptr; + + ptr = view->childrenList; + while (ptr->nextSister!=NULL) + ptr = ptr->nextSister; + ptr->nextSister = child; } child->parent = view; } @@ -108,26 +108,26 @@ createView(W_Screen *screen, W_View *parent) W_View *view; if (ViewContext==0) - ViewContext = XUniqueContext(); - + ViewContext = XUniqueContext(); + view = wmalloc(sizeof(W_View)); memset(view, 0, sizeof(W_View)); view->screen = screen; if (parent!=NULL) { - /* attributes are not valid for root window */ - view->attribFlags = CWEventMask|CWBitGravity; - view->attribs = defAtts; + /* attributes are not valid for root window */ + view->attribFlags = CWEventMask|CWBitGravity; + view->attribs = defAtts; - view->attribFlags |= CWBackPixel|CWColormap|CWBorderPixel; - view->attribs.background_pixel = W_PIXEL(screen->gray); - view->attribs.border_pixel = W_PIXEL(screen->black); - view->attribs.colormap = screen->colormap; + view->attribFlags |= CWBackPixel|CWColormap|CWBorderPixel; + view->attribs.background_pixel = W_PIXEL(screen->gray); + view->attribs.border_pixel = W_PIXEL(screen->black); + view->attribs.colormap = screen->colormap; - view->backColor = WMRetainColor(screen->gray); + view->backColor = WMRetainColor(screen->gray); - adoptChildView(parent, view); + adoptChildView(parent, view); } view->refCount = 1; @@ -150,19 +150,19 @@ W_View* W_CreateRootView(W_Screen *screen) { W_View *view; - + view = createView(screen, NULL); view->window = screen->rootWin; - + view->flags.realized = 1; view->flags.mapped = 1; view->flags.root = 1; - - view->size.width = - WidthOfScreen(ScreenOfDisplay(screen->display, screen->screen)); + + view->size.width = + WidthOfScreen(ScreenOfDisplay(screen->display, screen->screen)); view->size.height = - HeightOfScreen(ScreenOfDisplay(screen->display, screen->screen)); + HeightOfScreen(ScreenOfDisplay(screen->display, screen->screen)); return view; } @@ -172,10 +172,10 @@ W_View* W_CreateTopView(W_Screen *screen) { W_View *view; - + view = createView(screen, screen->rootView); if (!view) - return NULL; + return NULL; view->flags.topLevel = 1; view->attribs.event_mask |= StructureNotifyMask; @@ -188,10 +188,10 @@ W_View* W_CreateUnmanagedTopView(W_Screen *screen) { W_View *view; - + view = createView(screen, screen->rootView); if (!view) - return NULL; + return NULL; view->flags.topLevel = 1; view->attribs.event_mask |= StructureNotifyMask; @@ -215,36 +215,36 @@ W_RealizeView(W_View *view) if (view->parent && !view->parent->flags.realized) { - wwarning("trying to realize widget of unrealized parent"); - return; + wwarning("trying to realize widget of unrealized parent"); + return; } if (!view->flags.realized) { - parentWID = view->parent->window; - view->window = XCreateWindow(dpy, parentWID, view->pos.x, view->pos.y, - view->size.width, view->size.height, 0, - view->screen->depth, InputOutput, - view->screen->visual, view->attribFlags, - &view->attribs); + parentWID = view->parent->window; + view->window = XCreateWindow(dpy, parentWID, view->pos.x, view->pos.y, + view->size.width, view->size.height, 0, + view->screen->depth, InputOutput, + view->screen->visual, view->attribFlags, + &view->attribs); - XSaveContext(dpy, view->window, ViewContext, (XPointer)view); + XSaveContext(dpy, view->window, ViewContext, (XPointer)view); - view->flags.realized = 1; + view->flags.realized = 1; - if (view->flags.mapWhenRealized) { - W_MapView(view); - view->flags.mapWhenRealized = 0; - } + if (view->flags.mapWhenRealized) { + W_MapView(view); + view->flags.mapWhenRealized = 0; + } - WMPostNotificationName(WMViewRealizedNotification, view, NULL); + WMPostNotificationName(WMViewRealizedNotification, view, NULL); } - + /* realize children */ ptr = view->childrenList; while (ptr!=NULL) { - W_RealizeView(ptr); + W_RealizeView(ptr); - ptr = ptr->nextSister; + ptr = ptr->nextSister; } } @@ -260,14 +260,14 @@ W_ReparentView(W_View *view, W_View *newParent, int x, int y) adoptChildView(newParent, view); if (view->flags.realized) { - if (newParent->flags.realized) { - XReparentWindow(dpy, view->window, newParent->window, x, y); - } else { - wwarning("trying to reparent realized view to unrealized parent"); - return; - } + if (newParent->flags.realized) { + XReparentWindow(dpy, view->window, newParent->window, x, y); + } else { + wwarning("trying to reparent realized view to unrealized parent"); + return; + } } - + view->pos.x = x; view->pos.y = y; } @@ -277,7 +277,7 @@ void W_RaiseView(W_View *view) { if (W_VIEW_REALIZED(view)) - XRaiseWindow(W_VIEW_DISPLAY(view), W_VIEW_DRAWABLE(view)); + XRaiseWindow(W_VIEW_DISPLAY(view), W_VIEW_DRAWABLE(view)); } @@ -286,7 +286,7 @@ void W_LowerView(W_View *view) { if (W_VIEW_REALIZED(view)) - XLowerWindow(W_VIEW_DISPLAY(view), W_VIEW_DRAWABLE(view)); + XLowerWindow(W_VIEW_DISPLAY(view), W_VIEW_DRAWABLE(view)); } @@ -295,13 +295,13 @@ void W_MapView(W_View *view) { if (!view->flags.mapped) { - if (view->flags.realized) { - XMapRaised(view->screen->display, view->window); - XFlush(view->screen->display); - view->flags.mapped = 1; - } else { - view->flags.mapWhenRealized = 1; - } + if (view->flags.realized) { + XMapRaised(view->screen->display, view->window); + XFlush(view->screen->display); + view->flags.mapped = 1; + } else { + view->flags.mapWhenRealized = 1; + } } } @@ -315,12 +315,12 @@ W_MapSubviews(W_View *view) { XMapSubwindows(view->screen->display, view->window); XFlush(view->screen->display); - + view = view->childrenList; while (view) { - view->flags.mapped = 1; - view->flags.mapWhenRealized = 0; - view = view->nextSister; + view->flags.mapped = 1; + view->flags.mapWhenRealized = 0; + view = view->nextSister; } } @@ -331,12 +331,12 @@ W_UnmapSubviews(W_View *view) { XUnmapSubwindows(view->screen->display, view->window); XFlush(view->screen->display); - + view = view->childrenList; while (view) { - view->flags.mapped = 0; - view->flags.mapWhenRealized = 0; - view = view->nextSister; + view->flags.mapped = 0; + view->flags.mapWhenRealized = 0; + view = view->nextSister; } } @@ -347,7 +347,7 @@ W_UnmapView(W_View *view) { view->flags.mapWhenRealized = 0; if (!view->flags.mapped) - return; + return; XUnmapWindow(view->screen->display, view->window); XFlush(view->screen->display); @@ -360,11 +360,11 @@ W_View* W_TopLevelOfView(W_View *view) { W_View *toplevel; - + for (toplevel=view; - toplevel && !toplevel->flags.topLevel; - toplevel=toplevel->parent); - + toplevel && !toplevel->flags.topLevel; + toplevel=toplevel->parent); + return toplevel; } @@ -375,8 +375,8 @@ destroyView(W_View *view) W_View *ptr; if (view->flags.alreadyDead) - return; - view->flags.alreadyDead = 1; + return; + view->flags.alreadyDead = 1; /* delete the balloon text for the view, if there's any */ WMSetBalloonTextForView(NULL, view); @@ -388,78 +388,67 @@ destroyView(W_View *view) /* Do not leave focus in a inexisting control */ if (W_FocusedViewOfToplevel(W_TopLevelOfView(view))==view) - W_SetFocusOfTopLevel(W_TopLevelOfView(view), NULL); - + W_SetFocusOfTopLevel(W_TopLevelOfView(view), NULL); + if (view->flags.topLevel) { - W_FocusInfo *info = view->screen->focusInfo; - /* remove focus information associated to this toplevel */ - - if (info) { - if (info->toplevel==view) { - view->screen->focusInfo = info->next; - wfree(info); - } else { - while (info->next) { - if (info->next->toplevel == view) - break; - info = info->next; - } - if (info->next) { - W_FocusInfo *next = info->next->next; - wfree(info->next); - info->next = next; - } - /* else the toplevel did not have any focused subview */ - } - } + W_FocusInfo *info = view->screen->focusInfo; + /* remove focus information associated to this toplevel */ + + if (info) { + if (info->toplevel==view) { + view->screen->focusInfo = info->next; + wfree(info); + } else { + while (info->next) { + if (info->next->toplevel == view) + break; + info = info->next; + } + if (info->next) { + W_FocusInfo *next = info->next->next; + wfree(info->next); + info->next = next; + } + /* else the toplevel did not have any focused subview */ + } + } } /* destroy children recursively */ while (view->childrenList!=NULL) { - ptr = view->childrenList; - ptr->flags.parentDying = 1; + ptr = view->childrenList; + ptr->flags.parentDying = 1; - W_DestroyView(ptr); + W_DestroyView(ptr); - if (ptr == view->childrenList) { - view->childrenList = ptr->nextSister; - ptr->parent = NULL; - } + if (ptr == view->childrenList) { + view->childrenList = ptr->nextSister; + ptr->parent = NULL; + } } W_CallDestroyHandlers(view); if (view->flags.realized) { - XDeleteContext(view->screen->display, - view->window, ViewContext); - - /* if parent is being destroyed, it will die naturaly */ - if (!view->flags.parentDying || view->flags.topLevel) - XDestroyWindow(view->screen->display, view->window); + XDeleteContext(view->screen->display, + view->window, ViewContext); + + /* if parent is being destroyed, it will die naturaly */ + if (!view->flags.parentDying || view->flags.topLevel) + XDestroyWindow(view->screen->display, view->window); } - + /* remove self from parent's children list */ unparentView(view); /* the array has a wfree() destructor that will be called automatically */ WMFreeArray(view->eventHandlers); view->eventHandlers = NULL; - - WMUnregisterViewDraggedTypes(view); - + WMRemoveNotificationObserver(view); - -#if 0 - if (view->dragSourceProcs) - wfree(view->dragSourceProcs); - - if (view->dragDestinationProcs) - wfree(view->dragDestinationProcs); - - if (scr->dragInfo.destView == view) { - scr->dragInfo.destView = NULL; - } -#endif + + W_FreeViewXdndPart(view); + wfree(view); } @@ -483,20 +472,20 @@ W_MoveView(W_View *view, int x, int y) assert(view->flags.root==0); if (view->delegate && view->delegate->willMove) { - (*view->delegate->willMove)(view->delegate, view, &x, &y); + (*view->delegate->willMove)(view->delegate, view, &x, &y); } if (view->pos.x == x && view->pos.y == y) - return; + return; if (view->flags.realized) { - XMoveWindow(view->screen->display, view->window, x, y); + XMoveWindow(view->screen->display, view->window, x, y); } view->pos.x = x; view->pos.y = y; if (view->delegate && view->delegate->didMove) { - (*view->delegate->didMove)(view->delegate, view); + (*view->delegate->didMove)(view->delegate, view); } } @@ -507,30 +496,30 @@ W_ResizeView(W_View *view, unsigned int width, unsigned int height) /*int shrinked;*/ if (view->delegate && view->delegate->willResize) { - (*view->delegate->willResize)(view->delegate, view, &width, &height); + (*view->delegate->willResize)(view->delegate, view, &width, &height); } assert(width > 0); assert(height > 0); if (view->size.width == width && view->size.height == height) - return; + return; /*shrinked = width < view->size.width || height < view->size.height;*/ if (view->flags.realized) { - XResizeWindow(view->screen->display, view->window, width, height); + XResizeWindow(view->screen->display, view->window, width, height); } view->size.width = width; view->size.height = height; if (view->delegate && view->delegate->didResize) { - (*view->delegate->didResize)(view->delegate, view); + (*view->delegate->didResize)(view->delegate, view); } /* // TODO. replace in WINGs code, with the didResize delegate */ if (view->flags.notifySizeChanged) - WMPostNotificationName(WMViewSizeDidChangeNotification, view, NULL); + WMPostNotificationName(WMViewSizeDidChangeNotification, view, NULL); } @@ -538,10 +527,10 @@ void W_RedisplayView(W_View *view) { XEvent ev; - + if (!view->flags.mapped) - return; - + return; + ev.xexpose.type = Expose; ev.xexpose.display = view->screen->display; ev.xexpose.window = view->window; @@ -557,28 +546,28 @@ void W_SetViewBackgroundColor(W_View *view, WMColor *color) { if (view->backColor) - WMReleaseColor(view->backColor); + WMReleaseColor(view->backColor); view->backColor = WMRetainColor(color); view->attribFlags |= CWBackPixel; view->attribs.background_pixel = W_PIXEL(color); if (view->flags.realized) { - XSetWindowBackground(view->screen->display, view->window, - W_PIXEL(color)); - XClearWindow(view->screen->display, view->window); + XSetWindowBackground(view->screen->display, view->window, + W_PIXEL(color)); + XClearWindow(view->screen->display, view->window); } } -void +void W_SetViewCursor(W_View *view, Cursor cursor) { view->cursor = cursor; if (W_VIEW_REALIZED(view)) { - XDefineCursor(W_VIEW_DISPLAY(view), W_VIEW_DRAWABLE(view), cursor); + XDefineCursor(W_VIEW_DISPLAY(view), W_VIEW_DRAWABLE(view), cursor); } else { - view->attribFlags |= CWCursor; - view->attribs.cursor = cursor; + view->attribFlags |= CWCursor; + view->attribs.cursor = cursor; } } @@ -588,14 +577,14 @@ W_FocusedViewOfToplevel(W_View *view) { WMScreen *scr = view->screen; W_FocusInfo *info; - + for (info = scr->focusInfo; info!=NULL; info = info->next) - if (view == info->toplevel) - break; - + if (view == info->toplevel) + break; + if (!info) - return NULL; - + return NULL; + return info->focused; } @@ -606,61 +595,61 @@ W_SetFocusOfTopLevel(W_View *toplevel, W_View *view) WMScreen *scr = toplevel->screen; XEvent event; W_FocusInfo *info; - + for (info = scr->focusInfo; info!=NULL; info = info->next) - if (toplevel == info->toplevel) - break; + if (toplevel == info->toplevel) + break; if (!info) { - info = wmalloc(sizeof(W_FocusInfo)); - info->toplevel = toplevel; - info->focused = view; - info->next = scr->focusInfo; - scr->focusInfo = info; + info = wmalloc(sizeof(W_FocusInfo)); + info->toplevel = toplevel; + info->focused = view; + info->next = scr->focusInfo; + scr->focusInfo = info; } else { - event.xfocus.mode = NotifyNormal; - event.xfocus.detail = NotifyDetailNone; - if (info->focused) { - /* simulate FocusOut event */ - event.xfocus.type = FocusOut; - W_DispatchMessage(info->focused, &event); - } - info->focused = view; + event.xfocus.mode = NotifyNormal; + event.xfocus.detail = NotifyDetailNone; + if (info->focused) { + /* simulate FocusOut event */ + event.xfocus.type = FocusOut; + W_DispatchMessage(info->focused, &event); + } + info->focused = view; } if (view) { - /* simulate FocusIn event */ - event.xfocus.type = FocusIn; - W_DispatchMessage(view, &event); + /* simulate FocusIn event */ + event.xfocus.type = FocusIn; + W_DispatchMessage(view, &event); } } -void +void W_BroadcastMessage(W_View *targetParent, XEvent *event) { W_View *target; - + target = targetParent->childrenList; while (target!=NULL) { - W_DispatchMessage(target, event); - - target = target->nextSister; + W_DispatchMessage(target, event); + + target = target->nextSister; } } -void +void W_DispatchMessage(W_View *target, XEvent *event) { if (target->window==None) - return; + return; event->xclient.window = target->window; event->xclient.display = target->screen->display; - + WMHandleEvent(event); /* - XSendEvent(target->screen->display, target->window, False, - SubstructureNotifyMask, event); + XSendEvent(target->screen->display, target->window, False, + SubstructureNotifyMask, event); */ } @@ -681,7 +670,7 @@ W_ReleaseView(WMView *view) view->refCount--; if (view->refCount < 1) { - destroyView(view); + destroyView(view); } } @@ -693,13 +682,13 @@ WMWidgetOfView(WMView *view) } -WMSize +WMSize WMGetViewSize(WMView *view) { return view->size; } -WMPoint +WMPoint WMGetViewPosition(WMView *view) { return view->pos; @@ -738,7 +727,7 @@ WMGetViewScreenPosition(WMView *view) } XTranslateCoordinates(scr->display, W_VIEW_DRAWABLE(view), - scr->rootWin, 0, 0, &x, &y, &foo); + scr->rootWin, 0, 0, &x, &y, &foo); return wmkpoint(x-topX, y-topY); } @@ -752,13 +741,13 @@ resizedParent(void *self, WMNotification *notif) W_MoveView(view, view->leftOffs, view->topOffs); W_ResizeView(view, size.width - (view->leftOffs + view->rightOffs), - size.height - (view->topOffs + view->bottomOffs)); + size.height - (view->topOffs + view->bottomOffs)); } void -WMSetViewExpandsToParent(WMView *view, int leftOffs, int topOffs, - int rightOffs, int bottomOffs) +WMSetViewExpandsToParent(WMView *view, int leftOffs, int topOffs, + int rightOffs, int bottomOffs) { WMSize size = view->parent->size; @@ -766,15 +755,15 @@ WMSetViewExpandsToParent(WMView *view, int leftOffs, int topOffs, view->bottomOffs = bottomOffs; view->leftOffs = leftOffs; view->rightOffs = rightOffs; - + WMAddNotificationObserver(resizedParent, view, - WMViewSizeDidChangeNotification, - view->parent); + WMViewSizeDidChangeNotification, + view->parent); WMSetViewNotifySizeChanges(view->parent, True); W_MoveView(view, leftOffs, topOffs); - W_ResizeView(view, size.width - (leftOffs + rightOffs), - size.height - (topOffs + bottomOffs)); + W_ResizeView(view, size.width - (leftOffs + rightOffs), + size.height - (topOffs + bottomOffs)); } diff --git a/WPrefs.app/Expert.c b/WPrefs.app/Expert.c index cc8a6ce9..ece04a7f 100644 --- a/WPrefs.app/Expert.c +++ b/WPrefs.app/Expert.c @@ -54,7 +54,7 @@ showData(_Panel *panel) WMSetButtonSelected(panel->swi[4], GetBoolForKey("WindozeCycling")); WMSetButtonSelected(panel->swi[5], GetBoolForKey("DontConfirmKill")); WMSetButtonSelected(panel->swi[6], GetBoolForKey("DisableBlinking")); - if (WMHasAntialiasingSupport(WMWidgetScreen(panel->box))) + //if (WMHasAntialiasingSupport(WMWidgetScreen(panel->box))) WMSetButtonSelected(panel->swi[7], GetBoolForKey("AntialiasedText")); } @@ -83,7 +83,7 @@ createPanel(Panel *p) WMSetButtonText(panel->swi[6], _("Disable selection animation for selected icons.")); WMSetButtonText(panel->swi[7], _("Smooth font edges (needs restart).")); - if (!WMHasAntialiasingSupport(WMWidgetScreen(panel->box))) + //if (!WMHasAntialiasingSupport(WMWidgetScreen(panel->box))) WMSetButtonEnabled(panel->swi[7], False); WMRealizeWidget(panel->box); @@ -107,7 +107,7 @@ storeDefaults(_Panel *panel) SetBoolForKey(WMGetButtonSelected(panel->swi[4]), "WindozeCycling"); SetBoolForKey(WMGetButtonSelected(panel->swi[5]), "DontConfirmKill"); SetBoolForKey(WMGetButtonSelected(panel->swi[6]), "DisableBlinking"); - if (WMHasAntialiasingSupport(WMWidgetScreen(panel->box))) + //if (WMHasAntialiasingSupport(WMWidgetScreen(panel->box))) SetBoolForKey(WMGetButtonSelected(panel->swi[7]), "AntialiasedText"); } diff --git a/WPrefs.app/Font.c b/WPrefs.app/Font.c index 41a0f677..4d5c8b28 100644 --- a/WPrefs.app/Font.c +++ b/WPrefs.app/Font.c @@ -1,9 +1,9 @@ /* Font.c- text/font settings - * + * * WPrefs - Window Maker Preferences Program - * + * * Copyright (c) 1999-2003 Alfredo K. Kojima - * + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or @@ -16,7 +16,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, * USA. */ @@ -27,12 +27,12 @@ typedef struct _Panel { WMBox *box; - char *sectionName; + char *sectionName; char *description; CallbackRec callbacks; - + WMWidget *parent; @@ -47,15 +47,15 @@ typedef struct _Panel { WMPopUpButton *langP; WMFrame *aaF; WMButton *togAA; - + /* single byte */ WMTextField *fontT; WMButton *changeB; - + /* multibyte */ WMLabel *fsetL; WMList *fsetLs; - + WMButton *addB; WMButton *editB; WMButton *remB; @@ -67,7 +67,7 @@ typedef struct _Panel { WMColor *black; WMColor *light; WMColor *dark; - + WMColor *back; WMColor *colors[9]; @@ -78,7 +78,7 @@ typedef struct _Panel { WMPixmap *down_arrow; WMPixmap *alt_up_arrow; WMPixmap *alt_down_arrow; - + int oldsection; char menuStyle; char titleAlignment; @@ -104,7 +104,7 @@ static WMRect previewPositions[] = { {{156, 35},{64, 64}}, #define PICON 5 {{156, 105},{64, 64}} -}; +}; #define EVERYTHING 0xff static char *colorOptions[] = { @@ -277,7 +277,7 @@ static char* getFontEncoding(void *data); static char* getFontSampleString(void *data); /* note single element */ -static WMFont* getFontForPreview(void *data, int element); +static WMFont* getFontForPreview(void *data, int element); static WMFont* getDefaultSystemFont(void *data, int element); static WMPropList* getDefaultFontProp(void *data, char *encoding, int section); @@ -289,7 +289,7 @@ static void str2rcolor(RContext *rc, char *name, RColor *color) { XColor xcolor; - + XParseColor(rc->dpy, rc->cmap, name, &xcolor); color->alpha = 255; @@ -304,22 +304,22 @@ drawMenuBevel(RImage *img) RColor light, dark, mid; int i; int iheight = img->height / 4; - + light.alpha = 0; light.red = light.green = light.blue = 80; - + dark.alpha = 255; dark.red = dark.green = dark.blue = 0; - + mid.alpha = 0; mid.red = mid.green = mid.blue = 40; - + for (i = 1; i < 4; i++) { ROperateLine(img, RSubtractOperation, 0, i*iheight-2, img->width-1, i*iheight-2, &mid); - + RDrawLine(img, 0, i*iheight-1, img->width-1, i*iheight-1, &dark); - + ROperateLine(img, RAddOperation, 1, i*iheight, img->width-2, i*iheight, &light); } @@ -368,7 +368,7 @@ paintItems(WMScreen *scr, Drawable d, WMColor *color, WMFont *font, } static void -paintIcon(WMScreen *scr,Drawable d, WMColor *color, WMColor *Iback, +paintIcon(WMScreen *scr,Drawable d, WMColor *color, WMColor *Iback, WMFont *font, int part, char *text) { Display *dpy = WMScreenDisplay(scr); @@ -377,14 +377,14 @@ paintIcon(WMScreen *scr,Drawable d, WMColor *color, WMColor *Iback, int y = previewPositions[part].pos.y+1; int w = previewPositions[part].size.width-2; int h = WMFontHeight(font)+2; - + XFillRectangle(dpy, d, WMColorGC(Iback), x, y, w, h); x += (w - WMWidthOfString(font, text, l))/2; - WMDrawString(scr, d, color, font, x, + WMDrawString(scr, d, color, font, x, y + (h - WMFontHeight(font))/2, text, l); } - + static void drawFonts(_Panel *panel, int elements) { @@ -400,7 +400,7 @@ drawFonts(_Panel *panel, int elements) WINTITLE, panel->titleAlignment, _("Window Title Font")); } if(elements & DISCOL) { - paintTitle(scr, d, panel->white, getFontForPreview(panel, DISTITLE), + paintTitle(scr, d, panel->white, getFontForPreview(panel, DISTITLE), DISTITLE, WACenter, _("Display")); } if(elements & MTITLE) { @@ -412,13 +412,13 @@ drawFonts(_Panel *panel, int elements) PMITEM, _("Menu Item")); } if(elements & CLIP) { - WMDrawString(scr, d, panel->colors[4], + WMDrawString(scr, d, panel->colors[4], getFontForPreview(panel, PCLIP), 169,37, "1",1); - WMDrawString(scr, d, panel->colors[3], + WMDrawString(scr, d, panel->colors[3], getFontForPreview(panel, PCLIP),179, 84, _("Clip title"), 10); } if(elements & ICONT) { - paintIcon(scr, d, panel->colors[5], panel->colors[6], + paintIcon(scr, d, panel->colors[5], panel->colors[6], getFontForPreview(panel, PICON), PICON, _("Icon Title")); } } @@ -554,14 +554,14 @@ renderTexture(WMScreen *scr, WMPropList *texture, int width, int height, if (!path || !timage) { wwarning("could not load file '%s': %s", path, RMessageForError(RErrorCode)); - } else { + } else { grad = RRenderGradient(width, height, &rcolor, &rcolor2, style); image = RMakeTiledImage(timage, width, height); RReleaseImage(timage); i = atoi(WMGetFromPLString(WMGetFromPLArray(texture, 2))); - + RCombineImagesWithOpaqueness(image, grad, i); RReleaseImage(grad); } @@ -584,7 +584,7 @@ renderTexture(WMScreen *scr, WMPropList *texture, int width, int height, } j = WMGetPropListItemCount(texture); - + if (j > 0) { colors = wmalloc(j * sizeof(RColor*)); @@ -596,7 +596,7 @@ renderTexture(WMScreen *scr, WMPropList *texture, int width, int height, colors[i-2] = NULL; image = RRenderMultiGradient(width, height, colors, style); - + for (i = 0; colors[i]!=NULL; i++) wfree(colors[i]); wfree(colors); @@ -647,7 +647,7 @@ renderTexture(WMScreen *scr, WMPropList *texture, int width, int height, if (path) { dumpRImage(path, image); } - + if (border < 0) { if (border == MENU_BEVEL) { drawMenuBevel(image); @@ -695,7 +695,7 @@ renderMenu(_Panel *panel, WMPropList *texture, int width, int iheight) return pix; } -static void +static void renderClip(_Panel *panel, GC gc, int part, int relief) { WMScreen *scr = WMWidgetScreen(panel->box); @@ -703,7 +703,7 @@ renderClip(_Panel *panel, GC gc, int part, int relief) RContext *rc = WMScreenRContext(scr); WMPropList *prop; Pixmap pix; - XImage *original; + XImage *original; XPoint p[4]; RImage *tile; RColor black; @@ -714,22 +714,22 @@ renderClip(_Panel *panel, GC gc, int part, int relief) prop = GetObjectForKey(textureOptions[part]); - pix = renderTexture(scr, prop, + pix = renderTexture(scr, prop, previewPositions[part].size.width, previewPositions[part].size.height, NULL, relief); - + original = XGetImage(dpy, pix, 0, 0, 64, 64, AllPlanes, ZPixmap); - if (!original){ + if (!original){ wwarning(_("error capturing \"original\" tile image"), RMessageForError(RErrorCode)); } tile = RCreateImageFromXImage(rc, original, NULL); XDestroyImage(original); - XFreePixmap(WMScreenDisplay(scr), pix); + XFreePixmap(WMScreenDisplay(scr), pix); pt = CLIP_BUTTON_SIZE*ICON_SIZE/64; tp = ICON_SIZE-1 - pt; @@ -797,8 +797,8 @@ renderClip(_Panel *panel, GC gc, int part, int relief) XFillPolygon(dpy, pix, WMColorGC(panel->colors[4]), p, 3, Convex, CoordModeOrigin); XDrawLines(dpy, pix, WMColorGC(panel->colors[4]), p, 4, CoordModeOrigin); - XCopyArea(dpy, pix, panel->preview, gc, 0, 0, - previewPositions[part].size.width, + XCopyArea(dpy, pix, panel->preview, gc, 0, 0, + previewPositions[part].size.width, previewPositions[part].size.height, previewPositions[part].pos.x, previewPositions[part].pos.y); @@ -816,13 +816,13 @@ renderPreview(_Panel *panel, GC gc, int part, int relief) prop = GetObjectForKey(textureOptions[part]); - pix = renderTexture(scr, prop, + pix = renderTexture(scr, prop, previewPositions[part].size.width, previewPositions[part].size.height, NULL, relief); - XCopyArea(WMScreenDisplay(scr), pix, - panel->preview, gc, 0, 0, - previewPositions[part].size.width, + XCopyArea(WMScreenDisplay(scr), pix, + panel->preview, gc, 0, 0, + previewPositions[part].size.width, previewPositions[part].size.height, previewPositions[part].pos.x, previewPositions[part].pos.y); @@ -841,10 +841,10 @@ paintPreviewBox(Panel *panel, int elements) Pixmap mitem; gc = XCreateGC(dpy, WMWidgetXID(panel->parent), 0, NULL); - + if (panel->preview == None) { WMPixmap *pix; - + panel->preview = XCreatePixmap(dpy, WMWidgetXID(panel->parent), 240-4, 190-4, WMScreenDepth(scr)); @@ -885,23 +885,23 @@ paintPreviewBox(Panel *panel, int elements) prop = GetObjectForKey(textureOptions[PMITEM]); mitem = renderMenu(panel, prop, - previewPositions[PMITEM].size.width, + previewPositions[PMITEM].size.width, previewPositions[PMITEM].size.height/4); XCopyArea(dpy, mitem, panel->preview, gc, 0, 0, - previewPositions[PMITEM].size.width, + previewPositions[PMITEM].size.width, previewPositions[PMITEM].size.height, previewPositions[PMITEM].pos.x, previewPositions[PMITEM].pos.y); XFreePixmap(dpy, mitem); - } + } if (elements & (1<preview, gc, 29, 125, 29, 125+20*4+25); - XDrawLine(dpy, panel->preview, gc, 119, 125, 119, 125+20*4+25); + XDrawLine(dpy, panel->preview, gc, 119, 125, 119, 125+20*4+25); } if (elements & (1<preview, WMColorGC(black), previewPositions[PCLIP].pos.x-1, previewPositions[PCLIP].pos.y-1, @@ -922,7 +922,7 @@ paintPreviewBox(Panel *panel, int elements) WMReleaseColor(black); } -static void +static void paintTextField(void *data, int section) { _Panel *panel = (_Panel*)data; @@ -932,45 +932,45 @@ paintTextField(void *data, int section) WMSetTextFieldFont(panel->fontT, getFontForPreview(panel, section)); switch(encoding) { case 0: /* Current Font in theme */ - WMSetTextFieldText(panel->fontT, - "ABCDEFGHIKLMNOPQRSTUVXYWZabcdefghiklmnopqrstuvxywz0123456789\x00e0\x00e6\x00e7\x00eb\x00ee\x00f0\x00f1\x00f3\x00f9\x00fd\x00c0\x00c6\x00c7\x00cb\x00ce\x00d0\x00d1\x00d3\x00d9\x00dd"); + WMSetTextFieldText(panel->fontT, + "ABCDEFGHIKLMNOPQRSTUVXYWZabcdefghiklmnopqrstuvxywz0123456789\x00e0\x00e6\x00e7\x00eb\x00ee\x00f0\x00f1\x00f3\x00f9\x00fd\x00c0\x00c6\x00c7\x00cb\x00ce\x00d0\x00d1\x00d3\x00d9\x00dd"); break; case 1: /* default */ WMSetTextFieldText(panel->fontT, getFontSampleString(panel)); - // "ABCDEFGHIKLMNOPQRSTUVXYWZabcdefghiklmnopqrstuvxywz0123456789\x00e0\x00e6\x00e7\x00eb\x00ee\x00f0\x00f1\x00f3\x00f9\x00fd\x00c0\x00c6\x00c7\x00cb\x00ce\x00d0\x00d1\x00d3\x00d9\x00dd"); + // "ABCDEFGHIKLMNOPQRSTUVXYWZabcdefghiklmnopqrstuvxywz0123456789\x00e0\x00e6\x00e7\x00eb\x00ee\x00f0\x00f1\x00f3\x00f9\x00fd\x00c0\x00c6\x00c7\x00cb\x00ce\x00d0\x00d1\x00d3\x00d9\x00dd"); break; case 2: /* latin1 iso8859-1 */ WMSetTextFieldText(panel->fontT, getFontSampleString(panel)); - // "ABCDEFGHIKLMNOPQRSTUVXYWZabcdefghiklmnopqrstuvxywz0123456789\x00e0\x00e6\x00e7\x00eb\x00ee\x00f0\x00f1\x00f3\x00f9\x00fd\x00c0\x00c6\x00c7\x00cb\x00ce\x00d0\x00d1\x00d3\x00d9\x00dd"); + // "ABCDEFGHIKLMNOPQRSTUVXYWZabcdefghiklmnopqrstuvxywz0123456789\x00e0\x00e6\x00e7\x00eb\x00ee\x00f0\x00f1\x00f3\x00f9\x00fd\x00c0\x00c6\x00c7\x00cb\x00ce\x00d0\x00d1\x00d3\x00d9\x00dd"); break; case 3: /* latin2 iso8859-2 */ WMSetTextFieldText(panel->fontT, getFontSampleString(panel)); - // "ABCDEFGHIKLMNOPQRSTUVXYWZabcdefghiklmnopqrstuvxywz0123456789\x00e0\x00e6\x00e7\x00eb\x00ee\x00f0\x00f1\x00f3\x00f9\x00fd\x00c0\x00c6\x00c7\x00cb\x00ce\x00d0\x00d1\x00d3\x00d9\x00dd"); + // "ABCDEFGHIKLMNOPQRSTUVXYWZabcdefghiklmnopqrstuvxywz0123456789\x00e0\x00e6\x00e7\x00eb\x00ee\x00f0\x00f1\x00f3\x00f9\x00fd\x00c0\x00c6\x00c7\x00cb\x00ce\x00d0\x00d1\x00d3\x00d9\x00dd"); break; case 4: /* Greek iso8859-7 */ WMSetTextFieldText(panel->fontT, getFontSampleString(panel)); - // "ABCDEFGHIKLMNOPQRSTUVXYWZabcdefghiklmnopqrstuvxywz0123456789\x00e0\x00e6\x00e7\x00eb\x00ee\x00f0\x00f1\x00f3\x00f9\x00fd\x00c0\x00c6\x00c7\x00cb\x00ce\x00d0\x00d1\x00d3\x00d9\x00dd"); + // "ABCDEFGHIKLMNOPQRSTUVXYWZabcdefghiklmnopqrstuvxywz0123456789\x00e0\x00e6\x00e7\x00eb\x00ee\x00f0\x00f1\x00f3\x00f9\x00fd\x00c0\x00c6\x00c7\x00cb\x00ce\x00d0\x00d1\x00d3\x00d9\x00dd"); break; /* luckily all these happen to have the MultiByte chars in the same places */ case 5: /* Japanese jisx0208.1983 */ WMSetTextFieldText(panel->fontT, getFontSampleString(panel)); - // "Window Maker ÀßÄê¥æ¡¼¥Æ¥£¥ê¥Æ¥£"); + // "Window Maker ÀßÄê¥æ¡¼¥Æ¥£¥ê¥Æ¥£"); break; case 6: /* Korean ksc5601.1987 */ WMSetTextFieldText(panel->fontT, getFontSampleString(panel)); - // "À©µµ¿ì ¸ÞÀÌÄ¿ ¼³Á¤"); + // "À©µµ¿ì ¸ÞÀÌÄ¿ ¼³Á¤"); break; - case 7: /* korean2 daewoo */ + case 7: /* korean2 daewoo */ WMSetTextFieldText(panel->fontT, getFontSampleString(panel)); - // "À©µµ¿ì ¸ÞÀÌÄ¿ ¼³Á¤"); + // "À©µµ¿ì ¸ÞÀÌÄ¿ ¼³Á¤"); break; case 8: /* Russian koi8-r */ WMSetTextFieldText(panel->fontT, getFontSampleString(panel)); - // "ó×ÏÊÓÔ×Á Window Maker"); + // "ó×ÏÊÓÔ×Á Window Maker"); break; case 9: /* Ukranian koi8-u */ WMSetTextFieldText(panel->fontT, getFontSampleString(panel)); - // "ABCDEFGHIKLMNOPQRSTUVXYWZabcdefghiklmnopqrstuvxywz0123456789\x00e0\x00e6\x00e7\x00eb\x00ee\x00f0\x00f1\x00f3\x00f9\x00fd\x00c0\x00c6\x00c7\x00cb\x00ce\x00d0\x00d1\x00d3\x00d9\x00dd"); + // "ABCDEFGHIKLMNOPQRSTUVXYWZabcdefghiklmnopqrstuvxywz0123456789\x00e0\x00e6\x00e7\x00eb\x00ee\x00f0\x00f1\x00f3\x00f9\x00fd\x00c0\x00c6\x00c7\x00cb\x00ce\x00d0\x00d1\x00d3\x00d9\x00dd"); break; } } @@ -984,11 +984,11 @@ previewClick(XEvent *event, void *clientData) for (i = 0; i < sizeof(previewPositions)/sizeof(WMRect); i++) { if (event->xbutton.x >= previewPositions[i].pos.x && event->xbutton.y >= previewPositions[i].pos.y - && event->xbutton.x < previewPositions[i].pos.x + && event->xbutton.x < previewPositions[i].pos.x + previewPositions[i].size.width - && event->xbutton.y < previewPositions[i].pos.y + && event->xbutton.y < previewPositions[i].pos.y + previewPositions[i].size.height) { - + WMSetPopUpButtonSelectedItem(panel->fontSel, i); changePage(panel->fontSel, panel); return; @@ -1020,13 +1020,13 @@ changePage(WMWidget *w, void *data) color = WMCreateRGBColor(scr, 0x5100, 0x5100, 0x7100, True); XFillRectangle(rc->dpy, panel->preview, WMColorGC(color), - positions[panel->oldsection].x, + positions[panel->oldsection].x, positions[panel->oldsection].y, 22, 22); WMReleaseColor(color); } if (w) { panel->oldsection = section; - WMDrawPixmap(panel->hand, panel->preview, positions[section].x, + WMDrawPixmap(panel->hand, panel->preview, positions[section].x, positions[section].y); } WMRedisplayWidget(panel->prevL); @@ -1047,7 +1047,7 @@ setLanguageType(void *data, Bool multiByte) WMMapWidget(p->remB); WMMapWidget(p->upB); WMMapWidget(p->downB); - + WMUnmapWidget(p->fontT); WMUnmapWidget(p->changeB); } else { @@ -1058,7 +1058,7 @@ setLanguageType(void *data, Bool multiByte) WMUnmapWidget(p->remB); WMUnmapWidget(p->upB); WMUnmapWidget(p->downB); - + WMMapWidget(p->fontT); WMMapWidget(p->changeB); } @@ -1084,7 +1084,7 @@ refillFontSetList(void *data) } else { for (i = 0; i < WMGetPropListItemCount(array); i++) { WMGetFromPLArray(array, i); - WMAddListItem( panel->fsetLs, + WMAddListItem( panel->fsetLs, WMGetFromPLString( WMGetFromPLArray(array, i))); } @@ -1113,7 +1113,7 @@ insertCurrentFont(char *data, char *type) } wfree(str); - + WMPutInPLDictionary(CurrentFontArray, key, array); } @@ -1130,7 +1130,7 @@ readFontEncodings(void *data) msg = _("Could not locate font information file WPrefs.app/font.data"); goto error; } - + pl = WMReadPropListFromFile(path); if (!pl) { msg = _("Could not read font information file WPrefs.app/font.data"); @@ -1140,7 +1140,7 @@ readFontEncodings(void *data) WMPropList *key = WMCreatePLString("Encodings"); WMPropList *array; WMMenuItem *mi; - + array = WMGetFromPLDictionary(pl, key); WMReleasePropList(key); if (!array || !WMIsPLArray(array)) { @@ -1150,7 +1150,7 @@ readFontEncodings(void *data) } WMAddPopUpButtonItem(panel->langP, _("Current")); - + for (i = 0; i < WMGetPropListItemCount(array); i++) { WMPropList *item, *str; @@ -1161,11 +1161,11 @@ readFontEncodings(void *data) } WMSetPopUpButtonSelectedItem(panel->langP, 0); - + key = WMCreatePLString("WindowTitleFont"); DefaultWindowTitleFont = WMRetainPropList(WMGetFromPLDictionary(pl, key)); WMReleasePropList(key); - + key = WMCreatePLString("MenuTitleFont"); DefaultMenuTitleFont = WMRetainPropList(WMGetFromPLDictionary(pl, key)); WMReleasePropList(key); @@ -1193,20 +1193,20 @@ error: if (pl) WMReleasePropList(pl); - WMRunAlertPanel(WMWidgetScreen(panel->parent), panel->parent, + WMRunAlertPanel(WMWidgetScreen(panel->parent), panel->parent, _("Error"), msg, _("OK"), NULL, NULL); } -static void +static void checkListForArrows(void *data) { _Panel *panel = (_Panel*)data; int list; list = WMGetListNumberOfRows(panel->fsetLs); - - if(list > 1) + + if(list > 1) { - if(WMGetListSelectedItemRow(panel->fsetLs) == 0) { + if(WMGetListSelectedItemRow(panel->fsetLs) == 0) { WMSetButtonEnabled(panel->upB, False); WMSetButtonEnabled(panel->downB, True); } else if(WMGetListSelectedItemRow(panel->fsetLs) == list-1) { @@ -1222,9 +1222,9 @@ checkListForArrows(void *data) WMSetButtonEnabled(panel->downB, False); } /* added to control the Remove button */ - if(list > 1) + if(list > 1) WMSetButtonEnabled(panel->remB, True); - else + else WMSetButtonEnabled(panel->remB, False); } @@ -1238,14 +1238,14 @@ fontOfLang(void *data, char *encoding, int section) if(!encoding) array = getCurrentFontProp(panel, section); - else + else array = getDefaultFontProp(panel, encoding, section); if(!array) { wwarning("error no font prop given"); return NULL; } else { - for(i=0; iMultiByteText) setLanguageType(panel, True); @@ -1279,34 +1279,34 @@ static WMFont* getFontForPreview(void *data, int element) { _Panel *panel = (_Panel*)data; - WMFont *font; + WMFont *font; char *fname; WMScreen *scr = WMWidgetScreen(panel->box); char *encoding = getFontEncoding(panel); fname = fontOfLang(panel, encoding, element); - if (WMHasAntialiasingSupport(scr)) - { + //if (WMHasAntialiasingSupport(scr)) { if(panel->AntialiasedText) { - font = WMCreateFontWithFlags(scr, fname, WFAntialiased); + // fix this -Dan font = WMCreateFontWithFlags(scr, fname, WFAntialiased); + font = WMCreateFont(scr, fname); } else { font = WMCreateFont(scr, fname); } - } else { - font = WMCreateFont(scr, fname); - } + //} else { + // font = WMCreateFont(scr, fname); + //} if(!font) { char *msg; int length; length = strlen("\"")+ strlen(fname)+strlen("\" was not loaded correctly. Make sure the font is available for that encoding.\nLoadind default system font."); msg = wmalloc(length +1); - snprintf(msg, length + 1, - "\"%s\" was not loaded correctly. Make sure the font is available for that encoding.\nLoading default system font.", + snprintf(msg, length + 1, + "\"%s\" was not loaded correctly. Make sure the font is available for that encoding.\nLoading default system font.", fname); - WMRunAlertPanel(WMWidgetScreen(panel->parent),panel->parent, + WMRunAlertPanel(WMWidgetScreen(panel->parent),panel->parent, _("Warning"), msg, _("OK"), NULL, NULL); font = getDefaultSystemFont(panel, element); - } + } return font; } @@ -1393,17 +1393,17 @@ getCurrentFontProp(void *data, int section) break; case 1: array = WMRetainPropList( - WMGetFromPLDictionary(CurrentFontArray, + WMGetFromPLDictionary(CurrentFontArray, WMCreatePLString("LargeDisplayFont"))); break; case 2: array = WMRetainPropList( - WMGetFromPLDictionary(CurrentFontArray, + WMGetFromPLDictionary(CurrentFontArray, WMCreatePLString("MenuTitleFont"))); break; case 3: array = WMRetainPropList( - WMGetFromPLDictionary(CurrentFontArray, + WMGetFromPLDictionary(CurrentFontArray, WMCreatePLString("MenuTextFont"))); break; case 4: @@ -1413,7 +1413,7 @@ getCurrentFontProp(void *data, int section) break; case 5: array = WMRetainPropList( - WMGetFromPLDictionary(CurrentFontArray, + WMGetFromPLDictionary(CurrentFontArray, WMCreatePLString("IconTitleFont"))); break; } @@ -1511,7 +1511,7 @@ multiClick(WMWidget *w, void *data) } } -static void +static void toggleAA(WMWidget *w, void *data) { _Panel *panel = (_Panel*)data; @@ -1521,18 +1521,18 @@ toggleAA(WMWidget *w, void *data) else panel->AntialiasedText = True; /* hmm now i gotta redraw all the fonts in the preview section - * and the text field + * and the text field */ paintPreviewBox(panel, EVERYTHING); changePage(panel->fontSel, panel); if(isEncodingMultiByte(panel)) setLanguageType(panel, True); -} +} static void listClick(WMWidget *w, void *data) { _Panel *panel = (_Panel*)data; - + checkListForArrows(panel); } @@ -1704,11 +1704,11 @@ removeButtonClick(WMWidget *w, void *data) list = WMGetListNumberOfRows(panel->fsetLs); if(list != 0) { - if(list > pos) + if(list > pos) WMSelectListItem(panel->fsetLs, pos); - else if(list == pos) + else if(list == pos) WMSelectListItem(panel->fsetLs, list-1); - else + else WMSelectListItem(panel->fsetLs, 0); } checkListForArrows(panel); @@ -1723,15 +1723,15 @@ showData(_Panel *panel) WMScreen *scr = WMWidgetScreen(panel->parent); char *str; int i; - + CurrentFontArray = WMCreatePLDictionary(NULL, NULL); str = GetStringForKey("WindowTitleFont"); insertCurrentFont(wstrdup(str), "WindowTitleFont"); - + str = GetStringForKey("LargeDisplayFont"); insertCurrentFont(wstrdup(str), "LargeDisplayFont"); - + str = GetStringForKey("MenuTitleFont"); insertCurrentFont(wstrdup(str), "MenuTitleFont"); @@ -1785,56 +1785,55 @@ showData(_Panel *panel) WMSetButtonText(panel->togMulti, "Yes"); printf("yes multi\n"); panel->MultiByteText = True; - } else if (strcasecmp(str, "AUTO") == 0) { + } else if (strcasecmp(str, "AUTO") == 0) { char *locale; locale = setlocale(LC_CTYPE, NULL); - if(locale != NULL + if(locale != NULL && (strncmp(locale, "ja", 2) == 0 || strncmp(locale, "zh", 2) == 0 || strncmp(locale, "ko", 2) == 0)) { - setLanguageType(panel, True); + setLanguageType(panel, True); WMSetButtonText(panel->togMulti, "Auto"); printf("auto multi\n"); panel->MultiByteText = True; - } else { + } else { setLanguageType(panel, False); WMSetButtonText(panel->togMulti, "Auto"); panel->MultiByteText = False; } } - } else { + } else { char *locale; locale = setlocale(LC_CTYPE, NULL); - if(locale != NULL + if(locale != NULL && (strncmp(locale, "ja", 2) == 0 || strncmp(locale, "zh", 2) == 0 || strncmp(locale, "ko", 2) == 0)) { - setLanguageType(panel, True); + setLanguageType(panel, True); WMSetButtonText(panel->togMulti, "Auto"); printf("auto multi\n"); panel->MultiByteText = True; - } else { + } else { setLanguageType(panel, False); WMSetButtonText(panel->togMulti, "Auto"); panel->MultiByteText = False; } } - /* gotta check for Antialiasing AFTER MultiByte incase the use has both + /* gotta check for Antialiasing AFTER MultiByte incase the use has both * to maintain behavior in Current Fonts set or i could add another if * statement to setLanguageType =) */ - if (WMHasAntialiasingSupport(scr)) - { + //if (WMHasAntialiasingSupport(scr)) { WMMapWidget(panel->togAA); if(GetBoolForKey("AntialiasedText")){ WMSetButtonSelected(panel->togAA, True); panel->AntialiasedText = True; - } else { + } else { WMSetButtonSelected(panel->togAA, False); panel->AntialiasedText = False; } - } else { - WMUnmapWidget(panel->togAA); - } + //} else { + // WMUnmapWidget(panel->togAA); + //} paintPreviewBox(panel, EVERYTHING); @@ -1842,14 +1841,14 @@ showData(_Panel *panel) static void createPanel(Panel *p) -{ +{ _Panel *panel = (_Panel*)p; WMScreen *scr = WMWidgetScreen(panel->parent); - + panel->box = WMCreateBox(panel->parent); WMSetViewExpandsToParent(WMWidgetView(panel->box), 2, 2, 2, 2); - + panel->hand = WMCreatePixmapFromXPMData(scr, hand_xpm); panel->up_arrow = WMCreatePixmapFromXPMData(scr, up_arrow_xpm); panel->down_arrow = WMCreatePixmapFromXPMData(scr, down_arrow_xpm); @@ -1893,7 +1892,7 @@ createPanel(Panel *p) WMSetButtonAction(panel->togMulti, multiClick, panel); WMMapSubwidgets(panel->multiF); - + /* language selection */ panel->langF = WMCreateFrame(panel->box); WMResizeWidget(panel->langF, 165, 50); @@ -1909,17 +1908,16 @@ createPanel(Panel *p) WMMapSubwidgets(panel->langF); /* Antialiasing */ - if (WMHasAntialiasingSupport(scr)) - { - panel->togAA = WMCreateSwitchButton(panel->box); - WMResizeWidget(panel->togAA, 110, 20); - WMMoveWidget(panel->togAA, 155, 10); - WMSetButtonText(panel->togAA, _("Smooth Fonts")); - WMSetBalloonTextForView(_("Smooth Font edges for the eye candy\n" - "requires a restart after saving"), - WMWidgetView(panel->togAA)); - WMSetButtonAction(panel->togAA, toggleAA, panel); - } + //if (WMHasAntialiasingSupport(scr)) { + panel->togAA = WMCreateSwitchButton(panel->box); + WMResizeWidget(panel->togAA, 110, 20); + WMMoveWidget(panel->togAA, 155, 10); + WMSetButtonText(panel->togAA, _("Smooth Fonts")); + WMSetBalloonTextForView(_("Smooth Font edges for the eye candy\n" + "requires a restart after saving"), + WMWidgetView(panel->togAA)); + WMSetButtonAction(panel->togAA, toggleAA, panel); + //} /* multibyte */ panel->fsetL = WMCreateLabel(panel->box); WMResizeWidget(panel->fsetL, 245, 20); @@ -1930,16 +1928,16 @@ createPanel(Panel *p) { WMFont *font; WMColor *color; - + color = WMDarkGrayColor(scr); font = WMBoldSystemFontOfSize(scr, 12); - + WMSetWidgetBackgroundColor(panel->fsetL, color); WMSetLabelFont(panel->fsetL, font); - + WMReleaseFont(font); WMReleaseColor(color); - + color = WMWhiteColor(scr); WMSetLabelTextColor(panel->fsetL, color); WMReleaseColor(color); @@ -1992,24 +1990,24 @@ createPanel(Panel *p) panel->fontT = WMCreateTextField(panel->box); WMResizeWidget(panel->fontT, 245, 30); WMMoveWidget(panel->fontT, 265, 120); - + panel->changeB = WMCreateCommandButton(panel->box); WMResizeWidget(panel->changeB, 104, 24); WMMoveWidget(panel->changeB, 335, 160); WMSetButtonText(panel->changeB, _("Change...")); WMSetButtonAction(panel->changeB, changeButtonClick, panel); - + panel->black = WMBlackColor(scr); panel->white = WMWhiteColor(scr); panel->light = WMGrayColor(scr); panel->dark = WMDarkGrayColor(scr); - panel->back = WMCreateRGBColor(scr, 0x5100, 0x5100, 0x7100, True); + panel->back = WMCreateRGBColor(scr, 0x5100, 0x5100, 0x7100, True); /* Font Panel !!!!! */ panel->fontPanel = WMGetFontPanel(scr); - -#if 0 + +#if 0 for (i = 0; Languages[i].language != NULL; i++) { WMAddPopUpButtonItem(panel->langP, Languages[i].language); } @@ -2037,33 +2035,33 @@ storeData(Panel *p) { switch(i) { case 0: - SetStringForKey(fontOfLang(panel, encoding, i), + SetStringForKey(fontOfLang(panel, encoding, i), "WindowTitleFont"); break; case 1: - SetStringForKey(fontOfLang(panel, encoding, i), + SetStringForKey(fontOfLang(panel, encoding, i), "LargeDisplayFont"); break; case 2: - SetStringForKey(fontOfLang(panel, encoding, i), + SetStringForKey(fontOfLang(panel, encoding, i), "MenuTitleFont"); break; case 3: - SetStringForKey(fontOfLang(panel, encoding, i), + SetStringForKey(fontOfLang(panel, encoding, i), "MenuTextFont"); break; case 4: - SetStringForKey(fontOfLang(panel, encoding, i), + SetStringForKey(fontOfLang(panel, encoding, i), "ClipTitleFont"); break; case 5: - SetStringForKey(fontOfLang(panel, encoding, i), + SetStringForKey(fontOfLang(panel, encoding, i), "IconTitleFont"); break; } } - if (WMHasAntialiasingSupport(WMWidgetScreen(panel->box))) + //if (WMHasAntialiasingSupport(WMWidgetScreen(panel->box))) SetBoolForKey(WMGetButtonSelected(panel->togAA), "AntialiasedText"); if(panel->MultiByteText) @@ -2080,8 +2078,8 @@ prepClosure(Panel *p) _Panel *panel = (_Panel*)p; WMFreeFontPanel(panel->fontPanel); WMReleasePropList(CurrentFontArray); - /* and what ever else i've forgotten or overlooked - * maybe someone will add them */ + /* and what ever else i've forgotten or overlooked + * maybe someone will add them */ } Panel* @@ -2096,13 +2094,13 @@ InitFont(WMScreen *scr, WMWidget *parent) panel->description = _("Font Configurations for Windows, Menus etc"); panel->parent = parent; - + panel->callbacks.createWidgets = createPanel; panel->callbacks.updateDomain = storeData; panel->callbacks.prepareForClose = prepClosure; - + AddSection(panel, ICON_FILE); - + return panel; } diff --git a/configure.ac b/configure.ac index 5ed5ddce..eabd927f 100644 --- a/configure.ac +++ b/configure.ac @@ -15,7 +15,7 @@ AC_INIT(src/WindowMaker.h) -AM_INIT_AUTOMAKE(WindowMaker, 0.81.0) +AM_INIT_AUTOMAKE(WindowMaker, 0.90.0) AC_PROG_LIBTOOL @@ -102,8 +102,8 @@ AC_FUNC_VPRINTF AC_FUNC_ALLOCA AC_CHECK_FUNCS(gethostname select poll strerror strcasecmp strncasecmp \ setsid atexit mallinfo mkstemp snprintf vsnprintf asprintf \ - vasprintf mbsnrtowcs mbsrtowcs mbrtowc mbrlen) - + vasprintf mbsnrtowcs mbsrtowcs mbrtowc mbrlen wcsnrtombs \ + wcsrtombs wcstombs) dnl ripped from samba dnl diff --git a/src/dialog.c b/src/dialog.c index 8ccfe020..804ec381 100644 --- a/src/dialog.c +++ b/src/dialog.c @@ -1312,7 +1312,8 @@ wShowInfoPanel(WScreen *scr) WMSetLabelTextAlignment(panel->copyrL, WALeft); WMSetLabelText(panel->copyrL, COPYRIGHT_TEXT); /* we want the (c) character in the font, so don't use a FontSet here */ - font = WMCreateFontWithFlags(scr->wmscreen, "SystemFont-11", WFNormalFont); + // fix this -Dan font = WMCreateFontWithFlags(scr->wmscreen, "SystemFont-11", WFNormalFont); + font = WMSystemFontOfSize(scr->wmscreen, 11); if (font) { WMSetLabelFont(panel->copyrL, font); WMReleaseFont(font); diff --git a/src/screen.c b/src/screen.c index 4e1fb377..95a6b84b 100644 --- a/src/screen.c +++ b/src/screen.c @@ -821,9 +821,11 @@ wScreenInit(int screen_number) scr->info_text_font = WMBoldSystemFontOfSize(scr->wmscreen, 12); - scr->tech_draw_font = WMCreateFontWithFlags(scr->wmscreen, - "BoldSystemFont-12", - WFNotAntialiased); + // fix this too -Dan + //scr->tech_draw_font = WMCreateFontWithFlags(scr->wmscreen, + // "BoldSystemFont-12", + // WFNotAntialiased); + scr->tech_draw_font = WMBoldSystemFontOfSize(scr->wmscreen, 12); scr->gview = WCreateGeometryView(scr->wmscreen); WMRealizeWidget(scr->gview); -- 2.11.4.GIT