1
0
mirror of https://github.com/gryf/wmaker.git synced 2026-01-03 20:34:14 +01:00

removed listbag added tree bag

started drag & drop
This commit is contained in:
kojima
2000-03-28 02:30:13 +00:00
parent 20c8f4fd58
commit 6672180d77
18 changed files with 2496 additions and 383 deletions

View File

@@ -1,6 +1,14 @@
changes since wmaker 0.61.1:
............................
- WARNING: semantic of bags has changed!
An index assigned to an item will always keep that index unless
you insert an item before it.
For example:
bag = WMCreateBag();
WMSetInBag(bag, 10, "bla");
That code will put "bla" in index 10, instead of 0, as it used to be.
- fixed WMInsertInBag(). It ignored index, and always put the new item at end.
- added WMSaveUserDefaults().
- rewrote WMPopUpButton to use WMMenuItem

View File

@@ -60,6 +60,8 @@ libWINGs_a_SOURCES = \
WINGs.h \
WINGsP.h \
configuration.c \
dragdestination.c \
dragsource.c \
international.c \
notification.c \
selection.c \
@@ -97,7 +99,7 @@ libWINGs_a_SOURCES = \
error.c \
findfile.c \
bagarray.c \
baglist.c \
bagtree.c \
connection.c \
data.c \
hashtable.c \
@@ -110,7 +112,7 @@ libWUtil_a_SOURCES = \
WINGs.h \
WINGsP.h \
bagarray.c \
baglist.c \
bagtree.c \
connection.c \
data.c \
host.c \

View File

@@ -69,6 +69,7 @@ GFXLIBS = @GFXLIBS@
HEADER_SEARCH_PATH = @HEADER_SEARCH_PATH@
ICONEXT = @ICONEXT@
INTLIBS = @INTLIBS@
LD = @LD@
LIBPL = @LIBPL@
LIBRARY_SEARCH_PATH = @LIBRARY_SEARCH_PATH@
LIBTOOL = @LIBTOOL@
@@ -78,6 +79,7 @@ MAKEINFO = @MAKEINFO@
MOFILES = @MOFILES@
NETLIBS = @NETLIBS@
NLSDIR = @NLSDIR@
NM = @NM@
OBJDUMP = @OBJDUMP@
PACKAGE = @PACKAGE@
RANLIB = @RANLIB@
@@ -144,10 +146,10 @@ connect_LDADD = libWUtil.a @LIBRARY_SEARCH_PATH@ @NETLIBS@ @LIBPL@
EXTRA_DIST = logo.xpm BUGS
# wbutton.c
libWINGs_a_SOURCES = WINGs.h WINGsP.h configuration.c international.c notification.c selection.c userdefaults.c wapplication.c wappresource.c wballoon.c wbrowser.c wbutton.c wcolor.c wcolorpanel.c wcolorwell.c wevent.c wfilepanel.c wframe.c wfont.c wfontpanel.c widgets.c wlabel.c wlist.c wmenuitem.c wmisc.c wpanel.c wpixmap.c wpopupbutton.c wprogressindicator.c wscroller.c wscrollview.c wslider.c wsplitview.c wtabview.c wtextfield.c wwindow.c wview.c error.c findfile.c bagarray.c baglist.c connection.c data.c hashtable.c host.c memory.c usleep.c
libWINGs_a_SOURCES = WINGs.h WINGsP.h configuration.c dragdestination.c dragsource.c international.c notification.c selection.c userdefaults.c wapplication.c wappresource.c wballoon.c wbrowser.c wbutton.c wcolor.c wcolorpanel.c wcolorwell.c wevent.c wfilepanel.c wframe.c wfont.c wfontpanel.c widgets.c wlabel.c wlist.c wmenuitem.c wmisc.c wpanel.c wpixmap.c wpopupbutton.c wprogressindicator.c wscroller.c wscrollview.c wslider.c wsplitview.c wtabview.c wtextfield.c wwindow.c wview.c error.c findfile.c bagarray.c bagtree.c connection.c data.c hashtable.c host.c memory.c usleep.c
libWUtil_a_SOURCES = WINGs.h WINGsP.h bagarray.c baglist.c connection.c data.c host.c international.c notification.c userdefaults.c wapplication.c wutil.c error.c findfile.c hashtable.c memory.c usleep.c
libWUtil_a_SOURCES = WINGs.h WINGsP.h bagarray.c bagtree.c connection.c data.c host.c international.c notification.c userdefaults.c wapplication.c wutil.c error.c findfile.c hashtable.c memory.c usleep.c
INCLUDES = -I$(top_srcdir)/wrlib -I$(top_srcdir)/src -DRESOURCE_PATH=\"$(datadir)/WINGs\" @HEADER_SEARCH_PATH@ -DDEBUG
@@ -166,16 +168,17 @@ X_CFLAGS = @X_CFLAGS@
X_LIBS = @X_LIBS@
X_PRE_LIBS = @X_PRE_LIBS@
libWINGs_a_LIBADD =
libWINGs_a_OBJECTS = configuration.o international.o notification.o \
selection.o userdefaults.o wapplication.o wappresource.o wballoon.o \
wbrowser.o wbutton.o wcolor.o wcolorpanel.o wcolorwell.o wevent.o \
wfilepanel.o wframe.o wfont.o wfontpanel.o widgets.o wlabel.o wlist.o \
wmenuitem.o wmisc.o wpanel.o wpixmap.o wpopupbutton.o \
wprogressindicator.o wscroller.o wscrollview.o wslider.o wsplitview.o \
wtabview.o wtextfield.o wwindow.o wview.o error.o findfile.o bagarray.o \
baglist.o connection.o data.o hashtable.o host.o memory.o usleep.o
libWINGs_a_OBJECTS = configuration.o dragdestination.o dragsource.o \
international.o notification.o selection.o userdefaults.o \
wapplication.o wappresource.o wballoon.o wbrowser.o wbutton.o wcolor.o \
wcolorpanel.o wcolorwell.o wevent.o wfilepanel.o wframe.o wfont.o \
wfontpanel.o widgets.o wlabel.o wlist.o wmenuitem.o wmisc.o wpanel.o \
wpixmap.o wpopupbutton.o wprogressindicator.o wscroller.o wscrollview.o \
wslider.o wsplitview.o wtabview.o wtextfield.o wwindow.o wview.o \
error.o findfile.o bagarray.o bagtree.o connection.o data.o hashtable.o \
host.o memory.o usleep.o
libWUtil_a_LIBADD =
libWUtil_a_OBJECTS = bagarray.o baglist.o connection.o data.o host.o \
libWUtil_a_OBJECTS = bagarray.o bagtree.o connection.o data.o host.o \
international.o notification.o userdefaults.o wapplication.o wutil.o \
error.o findfile.o hashtable.o memory.o usleep.o
AR = ar
@@ -217,7 +220,7 @@ DIST_COMMON = README ChangeLog Makefile.am Makefile.in TODO
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
TAR = tar
TAR = gtar
GZIP_ENV = --best
SOURCES = $(libWINGs_a_SOURCES) $(libWUtil_a_SOURCES) $(wtest_SOURCES) $(wmquery_SOURCES) $(wmfile_SOURCES) $(fontl_SOURCES) $(testmywidget_SOURCES) $(testcolorpanel_SOURCES) $(connect_SOURCES)
OBJECTS = $(libWINGs_a_OBJECTS) $(libWUtil_a_OBJECTS) $(wtest_OBJECTS) $(wmquery_OBJECTS) $(wmfile_OBJECTS) $(fontl_OBJECTS) $(testmywidget_OBJECTS) $(testcolorpanel_OBJECTS) $(connect_OBJECTS)
@@ -226,7 +229,7 @@ all: all-redirect
.SUFFIXES:
.SUFFIXES: .S .c .lo .o .s
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps WINGs/Makefile
cd $(top_srcdir) && $(AUTOMAKE) --gnu WINGs/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) \
@@ -481,7 +484,7 @@ distdir: $(DISTFILES)
@for file in $(DISTFILES); do \
d=$(srcdir); \
if test -d $$d/$$file; then \
cp -pr $$d/$$file $(distdir)/$$file; \
cp -pr $$/$$file $(distdir)/$$file; \
else \
test -f $(distdir)/$$file \
|| ln $$d/$$file $(distdir)/$$file 2> /dev/null \

View File

@@ -107,14 +107,14 @@ DIST_COMMON = Makefile.am Makefile.in
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
TAR = tar
TAR = gtar
GZIP_ENV = --best
all: all-redirect
.SUFFIXES:
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps WINGs/Resources/Makefile
cd $(top_srcdir) && $(AUTOMAKE) --gnu WINGs/Resources/Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES)
cd $(top_builddir) \
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
@@ -146,10 +146,15 @@ distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
subdir = WINGs/Resources
distdir: $(DISTFILES)
here=`cd $(top_builddir) && pwd`; \
top_distdir=`cd $(top_distdir) && pwd`; \
distdir=`cd $(distdir) && pwd`; \
cd $(top_srcdir) \
&& $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --gnu WINGs/Resources/Makefile
@for file in $(DISTFILES); do \
d=$(srcdir); \
if test -d $$d/$$file; then \
cp -pr $$d/$$file $(distdir)/$$file; \
cp -pr $$/$$file $(distdir)/$$file; \
else \
test -f $(distdir)/$$file \
|| ln $$d/$$file $(distdir)/$$file 2> /dev/null \

View File

@@ -474,6 +474,31 @@ typedef struct WMTabViewDelegate {
typedef struct W_DraggingInfo WMDraggingInfo;
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);
WMData* (*fetchDragData)(WMView *self, char *type, Bool local);
/* Bool (*ignoreModifierKeysWhileDragging)(WMView *view);*/
} WMDragSourceProcs;
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);
} WMDragDestinationProcs;
/* ...................................................................... */
@@ -727,6 +752,8 @@ WMSize WMGetViewSize(WMView *view);
WMPoint WMGetViewPosition(WMView *view);
WMPoint WMGetViewScreenPosition(WMView *view);
WMWidget *WMWidgetOfView(WMView *view);
/* notifications */

View File

@@ -24,7 +24,7 @@ extern "C" {
#define DOUBLE_BUFFER
#define WC_UserWidget 128
@@ -32,22 +32,11 @@ extern "C" {
#define SCROLLER_WIDTH 20
/* internal messages */
#define WM_UPDATE_COLORWELL 130
#define WM_USER_MESSAGE 1024
#define SETUP_INTERNAL_MESSAGE(event, scrPtr) \
event.xclient.type=ClientMessage;\
event.xclient.display=scrPtr->display;\
event.xclient.send_event=False;\
event.xclient.serial=0;\
event.xclient.format=32;\
event.xclient.message_type=scrPtr->internalMessage;
#define XDND_VERSION 4
typedef struct W_Application {
char *applicationName;
int argc;
@@ -101,6 +90,27 @@ typedef struct W_FocusInfo {
} W_FocusInfo;
struct W_DraggingInfo {
Window destinationWindow;
Window sourceWindow;
WMPoint location;
unsigned sourceOperation;
WMPixmap *image;
WMPoint imageLocation;
Time timestamp;
int protocolVersion;
/* only valid if in the same app.. should be treated as internal data */
// WMView *destination;
// WMView *source;
};
typedef struct W_Screen {
Display *display;
int screen;
@@ -145,6 +155,8 @@ typedef struct W_Screen {
Pixmap stipple;
struct W_DraggingInfo dragInfo;
/* colors */
W_Color *white;
W_Color *black;
@@ -232,17 +244,26 @@ typedef struct W_Screen {
Cursor textCursor;
Cursor invisibleCursor;
Atom internalMessage; /* for ClientMessage */
Atom attribsAtom; /* GNUstepWindowAttributes */
Atom deleteWindowAtom; /* WM_DELETE_WINDOW */
Atom protocolsAtom; /* _XA_WM_PROTOCOLS */
Atom clipboardAtom; /* CLIPBOARD */
Atom xdndAwareAtom; /* XdndAware */
Atom xdndSelectionAtom;
Atom xdndEnterAtom;
Atom xdndLeaveAtom;
Atom xdndPositionAtom;
Atom xdndDropAtom;
Atom xdndFinishedAtom;
Atom xdndTypeListAtom;
Atom xdndStatusAtom;
Atom wmStateAtom; /* WM_STATE */
/* stuff for detecting double-clicks */
Time lastClickTime; /* time of last mousedown event */
@@ -302,11 +323,12 @@ typedef struct W_View {
WMColor *backColor;
#if 0
Atom *droppableTypes;
struct W_DragSourceProcs *dragSourceProcs;
struct W_DragDestinationProcs *dragDestinationProcs;
int helpContext;
#endif
struct {
unsigned int realized:1;
@@ -329,6 +351,7 @@ typedef struct W_View {
unsigned int pendingRelease3:1;
unsigned int pendingRelease4:1;
unsigned int pendingRelease5:1;
unsigned int xdndHintSet:1;
} flags;
int refCount;
@@ -442,8 +465,6 @@ void W_BroadcastMessage(W_View *targetParent, XEvent *event);
void W_DispatchMessage(W_View *target, XEvent *event);
Bool W_CheckInternalMessage(W_Screen *scr, XClientMessageEvent *cev, int event);
void W_SetFocusOfToplevel(W_View *toplevel, W_View *view);
W_View *W_FocusedViewOfToplevel(W_View *view);
@@ -468,6 +489,7 @@ char *W_GetTextSelection(WMScreen *scr, Atom selection);
void W_HandleSelectionEvent(XEvent *event);
void W_HandleDNDClientMessage(WMView *toplevel, XClientMessageEvent *event);
void W_FlushASAPNotificationQueue();

View File

@@ -2,7 +2,7 @@
#define _WUTIL_H_
#include <X11/Xlib.h>
#include <limits.h>
#include <sys/types.h>
/* SunOS 4.x Blargh.... */
@@ -10,7 +10,6 @@
#define NULL ((void*)0)
#endif
/*
* Warning: proplist.h #defines BOOL which will clash with the
* typedef BOOL in Xmd.h
@@ -102,6 +101,12 @@ typedef enum {
} WMConnectionState;
enum {
WBNotFound = INT_MAX /* element was not found in bag */
};
typedef struct W_Bag WMBag;
typedef struct W_Data WMData;
typedef struct W_HashTable WMHashTable;
@@ -139,6 +144,8 @@ typedef struct {
void (*releaseKey)(const void *);
} WMHashTableCallbacks;
typedef void *WMBagIterator;
typedef struct W_BagFunctions {
int (*getItemCount)(WMBag *self);
@@ -151,15 +158,17 @@ typedef struct W_BagFunctions {
int (*firstInBag)(WMBag *bag, void *item);
int (*countInBag)(WMBag *bag, void *item);
void *(*replaceInBag)(WMBag *bag, int index, void *item);
void (*sortBag)(WMBag *bag, int (*comparer)(const void*, const void*));
int (*sortBag)(WMBag *bag, int (*comparer)(const void*, const void*));
void (*emptyBag)(WMBag *bag);
void (*freeBag)(WMBag *bag);
WMBag *(*mapBag)(WMBag *bag, void * (*function)(void*));
void (*mapBag)(WMBag *bag, void (*function)(void*, void*), void *data);
int (*findInBag)(WMBag *bag, int (*match)(void*));
void *(*first)(WMBag *bag, void **ptr);
void *(*last)(WMBag *bag, void **ptr);
void *(*next)(WMBag *bag, void **ptr);
void *(*previous)(WMBag *bag, void **ptr);
void *(*first)(WMBag *bag, WMBagIterator *ptr);
void *(*last)(WMBag *bag, WMBagIterator *ptr);
void *(*next)(WMBag *bag, WMBagIterator *ptr);
void *(*previous)(WMBag *bag, WMBagIterator *ptr);
void *(*iteratorAtIndex)(WMBag *bag, int index, WMBagIterator *ptr);
int (*indexForIterator)(WMBag *bag, WMBagIterator ptr);
} W_BagFunctions;
@@ -305,14 +314,44 @@ extern const WMHashTableCallbacks WMStringPointerHashCallbacks;
/*......................................................................*/
WMBag* WMCreateArrayBag(int size);
WMBag* WMCreateArrayBagWithDestructor(int size, void (*destructor)(void*));
/*
* Array bags use an array to store the elements.
* Item indexes may be any integer number.
*
* Pros:
* Fast [O(1)] access to elements
* Fast [O(1)] push/pop
*
* Cons:
* A little slower [O(n)] for insertion/deletion of elements that
* arent in the end
* Element indexes with large difference will cause large holes
*/
#if 0
WMBag* WMCreateArrayBag(int initialSize);
WMBag* WMCreateArrayBagWithDestructor(int initialSize,
void (*destructor)(void*));
#endif
/*
* Tree bags use a red-black tree for storage.
* Item indexes may be any integer number.
*
* Pros:
* O(lg n) insertion/deletion/search
* Good for large numbers of elements with sparse indexes
*
* Cons:
* O(lg n) insertion/deletion/search
* Slow for storing small numbers of elements
*/
WMBag *WMCreateTreeBag(void);
WMBag *WMCreateTreeBagWithDestructor(void (*destructor)(void*));
WMBag *WMCreateListBag(void);
WMBag *WMCreateListBagWithDestructor(void (*destructor)(void*));
#define WMCreateBag(size) WMCreateArrayBag(size)
#define WMCreateArrayBag(a) WMCreateTreeBag()
#define WMCreateArrayBagWithDestructor(a,d) WMCreateTreeBagWithDestructor(d)
#define WMCreateBag(size) WMCreateTreeBag()
#define WMGetBagItemCount(bag) bag->func.getItemCount(bag)
@@ -321,7 +360,8 @@ WMBag *WMCreateListBagWithDestructor(void (*destructor)(void*));
#define WMPutInBag(bag, item) bag->func.putInBag(bag, item)
#define WMInsertInBag(bag, index, item) bag->func.insertInBag(bag, index, item)
/* this is slow */
#define WMRemoveFromBag(bag, item) bag->func.removeFromBag(bag, item)
#define WMDeleteFromBag(bag, index) bag->func.deleteFromBag(bag, index)
@@ -331,6 +371,7 @@ WMBag *WMCreateListBagWithDestructor(void (*destructor)(void*));
#define WMCountInBag(bag, item) bag->func.countInBag(bag, item)
#define WMReplaceInBag(bag, index, item) bag->func.replaceInBag(bag, index, item)
#define WMSetInBag(bag, index, item) bag->func.replaceInBag(bag, index, item)
/* comparer must return:
* < 0 if a < b
@@ -342,8 +383,8 @@ WMBag *WMCreateListBagWithDestructor(void (*destructor)(void*));
#define WMEmptyBag(bag) bag->func.emptyBag(bag)
#define WMFreeBag(bag) bag->func.freeBag(bag)
#define WMMapBag(bag, function) bag->func.mapBag(bag, function)
#define WMMapBag(bag, function, cdata) bag->func.mapBag(bag, function, cdata)
#define WMGetFirstInBag(bag, item) bag->func.firstInBag(bag, item)
@@ -359,6 +400,10 @@ WMBag *WMCreateListBagWithDestructor(void (*destructor)(void*));
#define WMBagPrevious(bag, ptr) bag->func.previous(bag, ptr)
#define WMBagIteratorAtIndex(bag, index, ptr) bag->func.iteratorAtIndex(bag, index, ptr)
#define WMBagIndexForIterator(bag, ptr) bag->func.indexForIterator(bag, ptr)
/*-------------------------------------------------------------------------*/

View File

@@ -13,6 +13,10 @@ typedef struct W_ArrayBag {
void **items;
int size;
int count;
int base;
int first;
int last;
} W_ArrayBag;
@@ -26,15 +30,17 @@ static void* getFromBag(WMBag *bag, int index);
static int firstInBag(WMBag *bag, void *item);
static int countInBag(WMBag *bag, void *item);
static void* replaceInBag(WMBag *bag, int index, void *item);
static void sortBag(WMBag *bag, int (*comparer)(const void*, const void*));
static int sortBag(WMBag *bag, int (*comparer)(const void*, const void*));
static void emptyBag(WMBag *bag);
static void freeBag(WMBag *bag);
static WMBag* mapBag(WMBag *bag, void *(*function)(void *));
static int findInBag(WMBag *bag, int (*match)(void*));
static void mapBag(WMBag *bag, void (*function)(void*, void*), void *data);
static int findInBag(WMBag *bag, int (*match)(void*));
static void* first(WMBag *bag, void **ptr);
static void* last(WMBag *bag, void **ptr);
static void* next(WMBag *bag, void **ptr);
static void* previous(WMBag *bag, void **ptr);
static void* iteratorAtIndex(WMBag *bag, int index, WMBagIterator *ptr);
static int indexForIterator(WMBag *bag, WMBagIterator ptr);
static W_BagFunctions arrayFunctions = {
@@ -56,21 +62,26 @@ static W_BagFunctions arrayFunctions = {
first,
last,
next,
previous
previous,
iteratorAtIndex,
indexForIterator
};
#define ARRAY ((W_ArrayBag*)bag->data)
#define I2O(a, i) ((a)->base + i)
WMBag*
WMCreateArrayBagWithDestructor(int size, void (*destructor)(void*))
WMCreateArrayBagWithDestructor(int initialSize, void (*destructor)(void*))
{
WMBag *bag;
W_ArrayBag *array;
int size;
wassertrv(size > 0, NULL);
bag = wmalloc(sizeof(WMBag));
array = wmalloc(sizeof(W_ArrayBag));
@@ -80,6 +91,9 @@ WMCreateArrayBagWithDestructor(int size, void (*destructor)(void*))
array->items = wmalloc(sizeof(void*) * size);
array->size = size;
array->count = 0;
array->first = 0;
array->last = 0;
array->base = 0;
bag->func = arrayFunctions;
@@ -90,9 +104,9 @@ WMCreateArrayBagWithDestructor(int size, void (*destructor)(void*))
WMBag*
WMCreateArrayBag(int size)
WMCreateArrayBag(int initialSize)
{
return WMCreateArrayBagWithDestructor(size, NULL);
return WMCreateArrayBagWithDestructor(initialSize, NULL);
}
@@ -106,20 +120,18 @@ getItemCount(WMBag *bag)
static int
appendBag(WMBag *bag, WMBag *appendedBag)
{
W_ArrayBag *array1 = ARRAY;
W_ArrayBag *array2 = (W_ArrayBag*)appendedBag->data;
W_ArrayBag *array = (W_ArrayBag*)appendedBag->data;
int ok;
int i;
if (array1->count + array2->count >= array1->size) {
array1->items =
wrealloc(array1->items, sizeof(void*) * (array1->size+array2->count));
array1->size += array2->count;
for (i = array->first; i <= array->last; i++) {
if (array->items[array->base+i]) {
ok = putInBag(bag, array->items[array->base+i]);
if (!ok)
return 0;
}
}
memcpy(array1->items + array1->count, array2->items,
sizeof(void*) * array2->count);
array1->count += array2->count;
return 1;
}
@@ -128,7 +140,7 @@ appendBag(WMBag *bag, WMBag *appendedBag)
static int
putInBag(WMBag *bag, void *item)
{
return insertInBag(bag, ARRAY->count, item);
return insertInBag(bag, ARRAY->last+1, item);
}
@@ -138,19 +150,29 @@ insertInBag(WMBag *bag, int index, void *item)
{
W_ArrayBag *array = ARRAY;
if (array->count == array->size) {
array->size += 16;
if (I2O(array, index) >= array->size) {
array->size = WMAX(array->size + 16, I2O(array, index));
array->items = wrealloc(array->items, sizeof(void*) * array->size);
memset(array->items + I2O(array, array->last), 0,
sizeof(void*) * (array->size - I2O(array, array->last)));
}
if (index >= 0 && index < array->count) {
memmove(&array->items[index+1], &array->items[index],
(array->count - index) * sizeof(void*));
if (index > array->last) {
array->last = index;
} else if (index >= array->first) {
memmove(array->items + I2O(array, index),
array->items + (I2O(array, index) + 1), sizeof(void*));
array->last++;
} else {
/* If index is invalid, place it at end */
index = array->count;
memmove(array->items,
array->items + (abs(index) - array->base),
sizeof(void*) * (abs(index) - array->base));
memset(array->items, 0, sizeof(void*) * (abs(index) - array->base));
array->first = index;
array->base = abs(index);
}
array->items[index] = item;
array->items[array->base + index] = item;
array->count++;
return 1;
@@ -261,10 +283,11 @@ replaceInBag(WMBag *bag, int index, void *item)
}
static void
static int
sortBag(WMBag *bag, int (*comparer)(const void*, const void*))
{
qsort(ARRAY->items, ARRAY->count, sizeof(void*), comparer);
return 1;
}
@@ -294,20 +317,15 @@ freeBag(WMBag *bag)
}
static WMBag*
mapBag(WMBag *bag, void *(*function)(void *))
static void
mapBag(WMBag *bag, void (*function)(void *, void *), void *clientData)
{
int i;
void *data;
WMBag *new = WMCreateArrayBagWithDestructor(ARRAY->size, bag->destructor);
for (i = 0; i < ARRAY->count; i++) {
data = (*function)(ARRAY->items[i]);
if (data)
putInBag(new, data);
for (i = 0; i < ARRAY->last; i++) {
if (ARRAY->items[i])
(*function)(ARRAY->items[i], clientData);
}
return new;
}
@@ -316,7 +334,7 @@ findInBag(WMBag *bag, int (*match)(void*))
{
int i;
for (i = 0; i < ARRAY->count; i++) {
for (i = 0; i < ARRAY->last; i++) {
if ((*match)(ARRAY->items[i]))
return i;
}
@@ -384,3 +402,15 @@ previous(WMBag *bag, void **ptr)
}
static void*
iteratorAtIndex(WMBag *bag, int index, WMBagIterator *ptr)
{
}
static int
indexForIterator(WMBag *bag, WMBagIterator ptr)
{
}

View File

@@ -12,6 +12,7 @@ typedef struct W_Item {
struct W_Item *next;
struct W_Item *prev;
void *data;
int index;
} W_Item;
@@ -23,9 +24,6 @@ typedef struct W_ListBag {
static int getItemCount(WMBag *self);
static int appendBag(WMBag *self, WMBag *bag);
static int putInBag(WMBag *self, void *item);
@@ -39,12 +37,15 @@ static void *replaceInBag(WMBag *bag, int index, void *item);
static void sortBag(WMBag *bag, int (*comparer)(const void*, const void*));
static void emptyBag(WMBag *bag);
static void freeBag(WMBag *bag);
static WMBag *mapBag(WMBag *bag, void * (*function)(void*));
static void mapBag(WMBag *bag, void (*function)(void*, void*), void *data);
static int findInBag(WMBag *bag, int (*match)(void*));;
static void *first(WMBag *bag, void **ptr);
static void *last(WMBag *bag, void **ptr);
static void *next(WMBag *bag, void **ptr);
static void *previous(WMBag *bag, void **ptr);
static void *first(WMBag *bag, WMBagIterator *ptr);
static void *last(WMBag *bag, WMBagIterator *ptr);
static void *next(WMBag *bag, WMBagIterator *ptr);
static void *previous(WMBag *bag, WMBagIterator *ptr);
static void *iteratorAtIndex(WMBag *bag, int index, WMBagIterator *ptr);
static int indexForIterator(WMBag *bag, WMBagIterator ptr);
static W_BagFunctions bagFunctions = {
getItemCount,
@@ -65,7 +66,9 @@ static W_BagFunctions bagFunctions = {
first,
last,
next,
previous
previous,
iteratorAtIndex,
indexForIterator
};
@@ -353,14 +356,14 @@ static void freeBag(WMBag *self)
}
static WMBag *mapBag(WMBag *self, void * (*function)(void*))
static WMBag *mapBag(WMBag *self, void * (*function)(void*, void*), void *data)
{
WMBag *bag = WMCreateListBagWithDestructor(self->destructor);
W_Item *ptr = SELF->first;
while (ptr) {
if ((*function)(ptr->data))
putInBag(bag, ptr->data);
(*function)(ptr->data, data);
ptr = ptr->next;
}
return bag;
@@ -386,7 +389,7 @@ static int findInBag(WMBag *self, int (*match)(void*))
static void *first(WMBag *self, void **ptr)
static void *first(WMBag *self, WMBagIterator *ptr)
{
*ptr = SELF->first;
@@ -398,7 +401,7 @@ static void *first(WMBag *self, void **ptr)
static void *last(WMBag *self, void **ptr)
static void *last(WMBag *self, WMBagIterator *ptr)
{
*ptr = SELF->last;
@@ -410,7 +413,7 @@ static void *last(WMBag *self, void **ptr)
static void *next(WMBag *bag, void **ptr)
static void *next(WMBag *bag, WMBagIterator *ptr)
{
W_Item *item = *(W_Item**)ptr;
@@ -424,7 +427,7 @@ static void *next(WMBag *bag, void **ptr)
static void *previous(WMBag *bag, void **ptr)
static void *previous(WMBag *bag, WMBagIterator *ptr)
{
W_Item *item = *(W_Item**)ptr;
@@ -438,4 +441,12 @@ static void *previous(WMBag *bag, void **ptr)
static void *iteratorAtIndex(WMBag *bag, int index, WMBagIterator *ptr)
{
}
static int indexForIterator(WMBag *bag, WMBagIterator ptr)
{
}

838
WINGs/bagtree.c Normal file
View File

@@ -0,0 +1,838 @@
#include <stdlib.h>
#include <string.h>
#include "WUtil.h"
typedef struct W_Node {
struct W_Node *parent;
struct W_Node *left;
struct W_Node *right;
int color;
void *data;
int index;
} W_Node;
typedef struct W_TreeBag {
W_Node *root;
W_Node *nil; /* sentinel */
int count;
} W_TreeBag;
static int getItemCount(WMBag *self);
static int appendBag(WMBag *self, WMBag *bag);
static int putInBag(WMBag *self, void *item);
static int insertInBag(WMBag *self, int index, void *item);
static int removeFromBag(WMBag *bag, void *item);
static int deleteFromBag(WMBag *bag, int index);
static void *getFromBag(WMBag *bag, int index);
static int countInBag(WMBag *bag, void *item);
static int firstInBag(WMBag *bag, void *item);
static void *replaceInBag(WMBag *bag, int index, void *item);
static int sortBag(WMBag *bag, int (*comparer)(const void*, const void*));
static void emptyBag(WMBag *bag);
static void freeBag(WMBag *bag);
static void mapBag(WMBag *bag, void (*function)(void*, void*), void *data);
static int findInBag(WMBag *bag, int (*match)(void*));;
static void *first(WMBag *bag, WMBagIterator *ptr);
static void *last(WMBag *bag, WMBagIterator *ptr);
static void *next(WMBag *bag, WMBagIterator *ptr);
static void *previous(WMBag *bag, WMBagIterator *ptr);
static void *iteratorAtIndex(WMBag *bag, int index, WMBagIterator *ptr);
static int indexForIterator(WMBag *bag, WMBagIterator ptr);
static W_BagFunctions bagFunctions = {
getItemCount,
appendBag,
putInBag,
insertInBag,
removeFromBag,
deleteFromBag,
getFromBag,
firstInBag,
countInBag,
replaceInBag,
sortBag,
emptyBag,
freeBag,
mapBag,
findInBag,
first,
last,
next,
previous,
iteratorAtIndex,
indexForIterator
};
#define IS_LEFT(node) (node == node->parent->left)
#define IS_RIGHT(node) (node == node->parent->right)
static void leftRotate(W_TreeBag *tree, W_Node *node)
{
W_Node *node2;
node2 = node->right;
node->right = node2->left;
node2->left->parent = node;
node2->parent = node->parent;
if (node->parent == tree->nil) {
tree->root = node2;
} else {
if (IS_LEFT(node)) {
node->parent->left = node2;
} else {
node->parent->right = node2;
}
}
node2->left = node;
node->parent = node2;
}
static void rightRotate(W_TreeBag *tree, W_Node *node)
{
W_Node *node2;
node2 = node->left;
node->left = node2->right;
node2->right->parent = node;
node2->parent = node->parent;
if (node->parent == tree->nil) {
tree->root = node2;
} else {
if (IS_LEFT(node)) {
node->parent->left = node2;
} else {
node->parent->right = node2;
}
}
node2->right = node;
node->parent = node2;
}
static void treeInsert(W_TreeBag *tree, W_Node *node)
{
W_Node *y = tree->nil;
W_Node *x = tree->root;
while (x != tree->nil) {
y = x;
if (node->index < x->index)
x = x->left;
else
x = x->right;
}
node->parent = y;
if (y == tree->nil)
tree->root = node;
else if (node->index < y->index)
y->left = node;
else
y->right = node;
}
static void rbTreeInsert(W_TreeBag *tree, W_Node *node)
{
W_Node *y;
treeInsert(tree, node);
node->color = 'R';
while (node != tree->root && node->parent->color == 'R') {
if (IS_LEFT(node->parent)) {
y = node->parent->parent->right;
if (y->color == 'R') {
node->parent->color = 'B';
y->color = 'B';
node->parent->parent->color = 'R';
node = node->parent->parent;
} else {
if (IS_RIGHT(node)) {
node = node->parent;
leftRotate(tree, node);
}
node->parent->color = 'B';
node->parent->parent->color = 'R';
rightRotate(tree, node->parent->parent);
}
} else {
y = node->parent->parent->left;
if (y->color == 'R') {
node->parent->color = 'B';
y->color = 'B';
node->parent->parent->color = 'R';
node = node->parent->parent;
} else {
if (IS_LEFT(node)) {
node = node->parent;
rightRotate(tree, node);
}
node->parent->color = 'B';
node->parent->parent->color = 'R';
leftRotate(tree, node->parent->parent);
}
}
}
tree->root->color = 'B';
}
static void rbDeleteFixup(W_TreeBag *tree, W_Node *node)
{
W_Node *w;
while (node != tree->root && node->color == 'B') {
if (IS_LEFT(node)) {
w = node->parent->right;
if (w->color == 'R') {
w->color = 'B';
node->parent->color = 'R';
leftRotate(tree, node->parent);
w = node->parent->right;
}
if (w->left->color == 'B' && w->right->color == 'B') {
w->color = 'R';
node = node->parent;
} else {
if (w->right->color == 'B') {
w->left->color = 'B';
w->color = 'R';
rightRotate(tree, w);
w = node->parent->right;
}
w->color = node->parent->color;
node->parent->color = 'B';
w->right->color = 'B';
leftRotate(tree, node->parent);
node = tree->root;
}
} else {
w = node->parent->left;
if (w->color == 'R') {
w->color = 'B';
node->parent->color = 'R';
leftRotate(tree, node->parent);
w = node->parent->left;
}
if (w->left->color == 'B' && w->right->color == 'B') {
w->color = 'R';
node = node->parent;
} else {
if (w->left->color == 'B') {
w->right->color = 'B';
w->color = 'R';
rightRotate(tree, w);
w = node->parent->left;
}
w->color = node->parent->color;
node->parent->color = 'B';
w->left->color = 'B';
leftRotate(tree, node->parent);
node = tree->root;
}
}
}
node->color = 'B';
}
static W_Node *treeMinimum(W_Node *node, W_Node *nil)
{
while (node->left != nil)
node = node->left;
return node;
}
static W_Node *treeMaximum(W_Node *node, W_Node *nil)
{
while (node->right != nil)
node = node->right;
return node;
}
static W_Node *treeSuccessor(W_Node *node, W_Node *nil)
{
W_Node *y;
if (node->right != nil) {
return treeMinimum(node->right, nil);
}
y = node->parent;
while (y != nil && node == y->right) {
node = y;
y = y->parent;
}
return y;
}
static W_Node *treePredecessor(W_Node *node, W_Node *nil)
{
W_Node *y;
if (node->left != nil) {
return treeMaximum(node->left, nil);
}
y = node->parent;
while (y != nil && node == y->left) {
node = y;
y = y->parent;
}
return y;
}
static W_Node *rbTreeDelete(W_TreeBag *tree, W_Node *node)
{
W_Node *nil = tree->nil;
W_Node *x, *y;
if (node->left == nil || node->right == nil) {
y = node;
} else {
y = treeSuccessor(node, nil);
}
if (y->left != nil) {
x = y->left;
} else {
x = y->right;
}
x->parent = y->parent;
if (y->parent == nil) {
tree->root = x;
} else {
if (IS_LEFT(y)) {
y->parent->left = x;
} else {
y->parent->right = x;
}
}
if (y != node) {
node->index = y->index;
node->data = y->data;
}
if (y->color == 'B') {
rbDeleteFixup(tree, x);
}
return y;
}
static W_Node *treeSearch(W_Node *root, W_Node *nil, int index)
{
if (root == nil || root->index == index) {
return root;
}
if (index < root->index) {
return treeSearch(root->left, nil, index);
} else {
return treeSearch(root->right, nil, index);
}
}
static W_Node *treeFind(W_Node *root, W_Node *nil, void *data)
{
W_Node *tmp;
if (root == nil || root->data == data)
return root;
tmp = treeFind(root->left, nil, data);
if (tmp != nil)
return tmp;
tmp = treeFind(root->right, nil, data);
return tmp;
}
#if 0
static char buf[512];
static void printNodes(W_Node *node, W_Node *nil, int depth)
{
if (node == nil) {
return;
}
printNodes(node->left, nil, depth+1);
memset(buf, ' ', depth*2);
buf[depth*2] = 0;
if (IS_LEFT(node))
printf("%s/(%2i\n", buf, node->index);
else
printf("%s\\(%2i\n", buf, node->index);
printNodes(node->right, nil, depth+1);
}
void PrintTree(WMBag *bag)
{
W_TreeBag *tree = (W_TreeBag*)bag->data;
printNodes(tree->root, tree->nil, 0);
}
#endif
#define SELF ((W_TreeBag*)self->data)
WMBag *WMCreateTreeBag(void)
{
return WMCreateTreeBagWithDestructor(NULL);
}
WMBag *WMCreateTreeBagWithDestructor(void (*destructor)(void*))
{
WMBag *bag;
W_TreeBag *tree;
bag = wmalloc(sizeof(WMBag));
bag->data = tree = wmalloc(sizeof(W_TreeBag));
memset(tree, 0, sizeof(W_TreeBag));
tree->nil = wmalloc(sizeof(W_Node));
memset(tree->nil, 0, sizeof(W_Node));
tree->nil->left = tree->nil->right = tree->nil->parent = tree->nil;
tree->nil->index = WBNotFound;
tree->root = tree->nil;
bag->destructor = destructor;
bag->func = bagFunctions;
return bag;
}
static int getItemCount(WMBag *self)
{
return SELF->count;
}
static int appendBag(WMBag *self, WMBag *bag)
{
WMBagIterator ptr;
void *data;
for (data = first(bag, &ptr); data != NULL; data = next(bag, &ptr)) {
if (!putInBag(self, data))
return 0;
}
return 1;
}
static int putInBag(WMBag *self, void *item)
{
W_Node *ptr;
ptr = wmalloc(sizeof(W_Node));
ptr->data = item;
ptr->index = SELF->count;
ptr->left = SELF->nil;
ptr->right = SELF->nil;
ptr->parent = SELF->nil;
rbTreeInsert(SELF, ptr);
SELF->count++;
return 1;
}
static int insertInBag(WMBag *self, int index, void *item)
{
W_Node *ptr;
ptr = wmalloc(sizeof(W_Node));
ptr->data = item;
ptr->index = index;
ptr->left = SELF->nil;
ptr->right = SELF->nil;
ptr->parent = SELF->nil;
rbTreeInsert(SELF, ptr);
while ((ptr = treeSuccessor(ptr, SELF->nil))) {
ptr->index++;
}
SELF->count++;
return 1;
}
static int removeFromBag(WMBag *self, void *item)
{
W_Node *ptr = treeFind(SELF->root, SELF->nil, item);
if (ptr != SELF->nil) {
SELF->count--;
ptr = rbTreeDelete(SELF, ptr);
free(ptr);
return 1;
} else {
return 0;
}
}
static int deleteFromBag(WMBag *self, int index)
{
W_Node *ptr = treeSearch(SELF->root, SELF->nil, index);
if (ptr != SELF->nil) {
SELF->count--;
ptr = rbTreeDelete(SELF, ptr);
free(ptr);
return 1;
} else {
return 0;
}
}
static void *getFromBag(WMBag *self, int index)
{
W_Node *node;
if (SELF->count>0)
assert(SELF->root != SELF->nil);
node = treeSearch(SELF->root, SELF->nil, index);
if (node != SELF->nil)
return node->data;
else
return NULL;
}
static int firstInBag(WMBag *self, void *item)
{
W_Node *node;
node = treeFind(SELF->root, SELF->nil, item);
if (node != SELF->nil)
return node->index;
else
return WBNotFound;
}
static int treeCount(W_Node *root, W_Node *nil, void *item)
{
int count = 0;
if (root == nil)
return 0;
if (root->data == item)
count++;
if (root->left != nil)
count += treeCount(root->left, nil, item);
if (root->right != nil)
count += treeCount(root->right, nil, item);
return count;
}
static int countInBag(WMBag *self, void *item)
{
return treeCount(SELF->root, SELF->nil, item);
}
static void *replaceInBag(WMBag *self, int index, void *item)
{
W_Node *ptr = treeSearch(SELF->root, SELF->nil, index);
void *old = NULL;
if (item == NULL) {
SELF->count--;
ptr = rbTreeDelete(SELF, ptr);
free(ptr);
} else if (ptr != SELF->nil) {
old = ptr->data;
ptr->data = item;
} else {
insertInBag(self, index, item);
}
return old;
}
static int sortBag(WMBag *self, int (*comparer)(const void*, const void*))
{
assert(0&&"not implemented");
return 0;
}
static void deleteTree(WMBag *self, W_Node *node)
{
if (node == SELF->nil)
return;
deleteTree(self, node->left);
if (self->destructor)
self->destructor(node->data);
deleteTree(self, node->right);
free(node);
}
static void emptyBag(WMBag *self)
{
deleteTree(self, SELF->root);
SELF->root = SELF->nil;
SELF->count = 0;
}
static void freeBag(WMBag *self)
{
emptyBag(self);
free(self);
}
static void mapTree(W_TreeBag *tree, W_Node *node,
void (*function)(void*, void*), void *data)
{
if (node == tree->nil)
return;
mapTree(tree, node->left, function, data);
(*function)(node->data, data);
mapTree(tree, node->right, function, data);
}
static void mapBag(WMBag *self, void (*function)(void*, void*), void *data)
{
mapTree(SELF, SELF->root, function, data);
}
static int findInTree(W_TreeBag *tree, W_Node *node, int (*function)(void*))
{
int index;
if (node == tree->nil)
return WBNotFound;
index = findInTree(tree, node->left, function);
if (index != WBNotFound)
return index;
if ((*function)(node->data)) {
return node->index;
}
return findInTree(tree, node->right, function);
}
static int findInBag(WMBag *self, int (*match)(void*))
{
return findInTree(SELF, SELF->root, match);
}
static void *first(WMBag *self, WMBagIterator *ptr)
{
W_Node *node;
node = treeMinimum(SELF->root, SELF->nil);
if (node == SELF->nil) {
*ptr = NULL;
return NULL;
} else {
*ptr = node;
return node->data;
}
}
static void *last(WMBag *self, WMBagIterator *ptr)
{
W_Node *node;
node = treeMaximum(SELF->root, SELF->nil);
if (node == SELF->nil) {
*ptr = NULL;
return NULL;
} else {
*ptr = node;
return node->data;
}
}
static void *next(WMBag *self, WMBagIterator *ptr)
{
W_Node *node;
if (*ptr == NULL)
return NULL;
node = treeSuccessor(*ptr, SELF->nil);
if (node == SELF->nil) {
*ptr = NULL;
return NULL;
} else {
*ptr = node;
return node->data;
}
}
static void *previous(WMBag *self, WMBagIterator *ptr)
{
W_Node *node;
if (*ptr == NULL)
return NULL;
node = treePredecessor(*ptr, SELF->nil);
if (node == SELF->nil) {
*ptr = NULL;
return NULL;
} else {
*ptr = node;
return node->data;
}
}
static void *iteratorAtIndex(WMBag *self, int index, WMBagIterator *ptr)
{
W_Node *node;
node = treeSearch(SELF->root, SELF->nil, index);
if (node == SELF->nil) {
*ptr = NULL;
return NULL;
} else {
*ptr = node;
return node->data;
}
}
static int indexForIterator(WMBag *bag, WMBagIterator ptr)
{
return ((W_Node*)ptr)->index;
}

View File

@@ -30,6 +30,7 @@ typedef struct W_Data {
unsigned growth; /* How much to grow */
void *bytes; /* Actual data */
unsigned retainCount;
unsigned freeData:1; /* whether the data should be released */
} W_Data;
@@ -52,6 +53,7 @@ WMCreateDataWithCapacity(unsigned capacity) /*FOLD00*/
aData->growth = capacity/2 > 0 ? capacity/2 : 1;
aData->length = 0;
aData->retainCount = 1;
aData->freeData = 1;
return aData;
}
@@ -96,6 +98,7 @@ WMCreateDataWithBytesNoCopy(void *bytes, unsigned length) /*FOLD00*/
aData->growth = length/2 > 0 ? length/2 : 1;
aData->bytes = bytes;
aData->retainCount = 1;
aData->freeData = 0;
return aData;
}
@@ -125,7 +128,7 @@ WMReleaseData(WMData *aData) /*FOLD00*/
aData->retainCount--;
if (aData->retainCount > 0)
return;
if (aData->bytes)
if (aData->bytes && aData->freeData)
wfree(aData->bytes);
wfree(aData);
}

118
WINGs/dragdestination.c Normal file
View File

@@ -0,0 +1,118 @@
#include <X11/Xatom.h>
#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, view,
WMViewRealizedNotification,
/* just use as an id */
view->dragDestinationProcs);
}
}
}
WMData*
WMGetDroppedData(WMView *view, WMDraggingInfo *info)
{
return NULL;
}
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)
free(view->droppableTypes);
view->droppableTypes = NULL;
}
/***********************************************************************/
void
WMSetViewDragDestinationProcs(WMView *view, WMDragDestinationProcs *procs)
{
if (view->dragDestinationProcs == NULL) {
free(view->dragDestinationProcs);
view->dragDestinationProcs = wmalloc(sizeof(WMDragDestinationProcs));
}
*view->dragDestinationProcs = *procs;
/*XXX fill in non-implemented stuffs */
}

1042
WINGs/dragsource.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -46,18 +46,43 @@ static void willResizeColorWell();
W_ViewDelegate _ColorWellViewDelegate = {
NULL,
NULL,
NULL,
NULL,
willResizeColorWell
NULL,
NULL,
NULL,
willResizeColorWell
};
#if 0
static WMDragSourceProcs dragProcs = {
static unsigned draggingSourceOperation(WMView *self, Bool local);
static void beganDragImage(WMView *self, WMPixmap *image, WMPoint point);
static void endedDragImage(WMView *self, WMPixmap *image, WMPoint point,
Bool deposited);
static WMDragSourceProcs _DragSourceProcs = {
draggingSourceOperation,
beganDragImage,
endedDragImage,
NULL
};
#endif
static unsigned draggingEntered(WMView *self, WMDraggingInfo *info);
static unsigned draggingUpdated(WMView *self, WMDraggingInfo *info);
static void draggingExited(WMView *self, WMDraggingInfo *info);
static Bool prepareForDragOperation(WMView *self, WMDraggingInfo *info);
static Bool performDragOperation(WMView *self, WMDraggingInfo *info);
static void concludeDragOperation(WMView *self, WMDraggingInfo *info);
static WMDragDestinationProcs _DragDestinationProcs = {
draggingEntered,
draggingUpdated,
draggingExited,
prepareForDragOperation,
performDragOperation,
concludeDragOperation
};
#define DEFAULT_WIDTH 60
#define DEFAULT_HEIGHT 30
@@ -168,7 +193,16 @@ WMCreateColorWell(WMWidget *parent)
WMAddNotificationObserver(colorChangedObserver, cPtr,
WMColorPanelColorChangedNotification, NULL);
// WMSetViewDragSourceProcs(cPtr->view, &_DragSourceProcs);
// WMSetViewDragDestinationProcs(cPtr->view, &_DragDestinationProcs);
{
char *types[2] = {"application/X-color", NULL};
//WMRegisterViewForDraggedTypes(cPtr->view, types);
}
return cPtr;
}
@@ -276,6 +310,32 @@ handleEvents(XEvent *event, void *data)
}
static unsigned
draggingSourceOperation(WMView *self, Bool local)
{
puts("DRAG SOURCE");
return 0;
}
static void
beganDragImage(WMView *self, WMPixmap *image, WMPoint point)
{
puts("BEGAN DRAG");
}
static void
endedDragImage(WMView *self, WMPixmap *image, WMPoint point, Bool deposited)
{
if (deposited)
puts("ENDED DRAG SUCCESS");
else
puts("ENDED DRAG CANCEL");
}
static WMPixmap*
makeDragPixmap(WMColorWell *cPtr)
{
@@ -292,221 +352,6 @@ makeDragPixmap(WMColorWell *cPtr)
}
static void
slideView(WMView *view, int srcX, int srcY, int dstX, int dstY)
{
double x, y, dx, dy;
int i;
srcX -= 8;
srcY -= 8;
dstX -= 8;
dstY -= 8;
x = srcX;
y = srcY;
dx = (double)(dstX-srcX)/20.0;
dy = (double)(dstY-srcY)/20.0;
for (i = 0; i < 20; i++) {
W_MoveView(view, x, y);
XFlush(view->screen->display);
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;
child = findChildInWindow(dpy, children[i],
x - attr.x, y - attr.y);
XFree(children);
if (!child)
return toplevel;
else
return child;
}
}
XFree(children);
return None;
}
static Window
findWindowUnderDragPointer(WMScreen *scr, int x, int y, Window iconWindow)
{
Window foo, bar;
Window *children;
unsigned nchildren;
int i;
if (!XQueryTree(scr->display, scr->rootWin, &foo, &bar,
&children, &nchildren) || children == NULL) {
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;
Window child;
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
&& (child = findChildInWindow(scr->display, children[i],
x - attr.x, y - attr.y))) {
XFree(children);
return child;
}
}
XFree(children);
return None;
}
static void
dragColor(ColorWell *cPtr, XEvent *event, WMPixmap *image)
{
WMView *dragView;
WMScreen *scr = cPtr->view->screen;
Display *dpy = scr->display;
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};
Bool done = False;
WMColorWell *activeWell = NULL;
dragView = W_CreateTopView(scr);
W_ResizeView(dragView, 16, 16);
dragView->attribFlags |= CWOverrideRedirect | CWSaveUnder;
dragView->attribs.event_mask = StructureNotifyMask;
dragView->attribs.override_redirect = True;
dragView->attribs.save_under = True;
W_MoveView(dragView, event->xmotion.x_root-8, event->xmotion.y_root-8);
W_RealizeView(dragView);
W_MapView(dragView);
XSetWindowBackgroundPixmap(dpy, dragView->window, WMGetPixmapXID(image));
XClearWindow(dpy, dragView->window);
XGrabPointer(dpy, scr->rootWin, True,
ButtonMotionMask|ButtonReleaseMask,
GrabModeSync, GrabModeAsync,
scr->rootWin, scr->defaultCursor, CurrentTime);
while (!done) {
XEvent ev;
WMView *view;
Window win;
XAllowEvents(dpy, SyncPointer, CurrentTime);
WMNextEvent(dpy, &ev);
switch (ev.type) {
case ButtonRelease:
if (activeWell != NULL) {
WMSetColorWellColor(activeWell, cPtr->color);
WMPostNotificationName(WMColorWellDidChangeNotification,
activeWell, NULL);
} else {
slideView(dragView, ev.xbutton.x_root, ev.xbutton.y_root,
event->xmotion.x_root, event->xmotion.y_root);
}
done = True;
break;
case MotionNotify:
while (XCheckTypedEvent(dpy, MotionNotify, &ev)) ;
W_MoveView(dragView, ev.xmotion.x_root-8, ev.xmotion.y_root-8);
win = findWindowUnderDragPointer(scr, ev.xmotion.x_root,
ev.xmotion.y_root,
dragView->window);
if (win != None && win != scr->rootWin) {
view = W_GetViewForXWindow(dpy, win);
} else {
view = NULL;
}
if (view && view->self && W_CLASS(view->self) == WC_ColorWell
&& view->self != activeWell && view->self != cPtr) {
activeWell = view->self;
XRecolorCursor(dpy, scr->defaultCursor, &green, &back);
} else if (!view || view->self != activeWell) {
XRecolorCursor(dpy, scr->defaultCursor, &black, &back);
activeWell = NULL;
}
break;
default:
WMHandleEvent(&ev);
break;
}
}
XUngrabPointer(dpy, CurrentTime);
XRecolorCursor(dpy, scr->defaultCursor, &black, &back);
W_DestroyView(dragView);
}
static void
handleDragEvents(XEvent *event, void *data)
{
@@ -526,17 +371,17 @@ handleDragEvents(XEvent *event, void *data)
|| 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->view, pixmap, cPtr->view->pos,
offs, event, True);
* */
dragColor(cPtr, event, pixmap);
/*
WMDragImageFromView(cPtr->view, pixmap, types,
wmkpoint(event->xmotion.x_root,
event->xmotion.y_root),
offs, event, True);
*/
WMReleasePixmap(pixmap);
}
@@ -585,3 +430,76 @@ destroyColorWell(ColorWell *cPtr)
wfree(cPtr);
}
static unsigned
draggingEntered(WMView *self, WMDraggingInfo *info)
{
WMPoint point = WMGetViewScreenPosition(self);
printf("%i %i || %i %i %i %i\n", info->location.x, info->location.y,
point.x, point.y, W_VIEW_WIDTH(self), W_VIEW_HEIGHT(self));
if (info->location.x >= point.x
&& info->location.y >= point.y
&& info->location.x < point.x + W_VIEW_WIDTH(self)
&& info->location.y < point.y + W_VIEW_HEIGHT(self)) {
/* self */
puts("ENTERED 0");
return 0;
} else {
puts("ENTERED 1");
return 1;
}
}
static unsigned
draggingUpdated(WMView *self, WMDraggingInfo *info)
{
WMPoint point = WMGetViewScreenPosition(self);
puts("UPDATED");
if (info->location.x >= point.x
&& info->location.y >= point.y
&& info->location.x < point.x + W_VIEW_WIDTH(self)
&& info->location.y < point.y + W_VIEW_WIDTH(self)) {
return 0;
} else {
return 1;
}
}
static void
draggingExited(WMView *self, WMDraggingInfo *info)
{
puts("EXITED");
}
static Bool
prepareForDragOperation(WMView *self, WMDraggingInfo *info)
{
puts("PREPARING");
return True;
}
static Bool
performDragOperation(WMView *self, WMDraggingInfo *info)
{
WMData *data;
// data = WMGetDroppedData(self);
puts("DROPPED");
return True;
}
static void
concludeDragOperation(WMView *self, WMDraggingInfo *info)
{
puts("FINISHED");
}

View File

@@ -304,7 +304,7 @@ checkIdleHandlers()
{
IdleHandler *handler;
WMBag *handlerCopy;
int i, n;
WMBagIterator iter;
if (!idleHandler || WMGetBagItemCount(idleHandler)==0) {
W_FlushIdleNotificationQueue();
@@ -312,15 +312,14 @@ checkIdleHandlers()
return (idleHandler!=NULL && WMGetBagItemCount(idleHandler)>0);
}
n = WMGetBagItemCount(idleHandler);
handlerCopy = WMCreateBag(n);
for (i=0; i<n; i++)
WMPutInBag(handlerCopy, WMGetFromBag(idleHandler, i));
handlerCopy = WMCreateBag(WMGetBagItemCount(idleHandler));
WMAppendBag(handlerCopy, idleHandler);
for (i=0; i<n; i++) {
handler = WMGetFromBag(handlerCopy, i);
for (handler = WMBagFirst(handlerCopy, &iter);
iter != NULL;
handler = WMBagNext(handlerCopy, &iter)) {
/* check if the handler still exist or was removed by a callback */
if (WMGetFirstInBag(idleHandler, handler)<0)
if (WMGetFirstInBag(idleHandler, handler) == WBNotFound)
continue;
(*handler->callback)(handler->clientData);
@@ -586,6 +585,10 @@ WMHandleEvent(XEvent *event)
|| event->type == SelectionRequest) {
/* handle selection related events */
W_HandleSelectionEvent(event);
} else if (event->type == ClientMessage) {
//W_HandleDNDClientMessage(toplevel, &event->xclient);
}
/* if it's a key event, redispatch it to the focused control */
@@ -640,12 +643,12 @@ WMHandleEvent(XEvent *event)
W_RetainView(toplevel);
hPtr = view->handlerList;
while (hPtr!=NULL) {
W_EventHandler *tmp;
tmp = hPtr->nextHandler;
if ((hPtr->eventMask & mask)) {
(*hPtr->proc)(event, hPtr->clientData);
}
@@ -654,14 +657,14 @@ WMHandleEvent(XEvent *event)
}
/* pass the event to the top level window of the widget */
if (view->parent!=NULL) {
if (view->parent != NULL) {
vPtr = view;
while (vPtr->parent!=NULL)
while (vPtr->parent != NULL)
vPtr = vPtr->parent;
hPtr = vPtr->handlerList;
while (hPtr!=NULL) {
while (hPtr != NULL) {
if (hPtr->eventMask & mask) {
(*hPtr->proc)(event, hPtr->clientData);

View File

@@ -546,6 +546,23 @@ WMCreateScreenWithRContext(Display *display, int screen, RContext *context)
XGCValues gcv;
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",
"XdndStatus",
"WM_STATE"
};
Atom atoms[sizeof(atomNames)/sizeof(char*)];
if (!initialized) {
@@ -738,16 +755,29 @@ WMCreateScreenWithRContext(Display *display, int screen, RContext *context)
XFreePixmap(display, blank);
}
scrPtr->internalMessage = XInternAtom(display, "_WINGS_MESSAGE", False);
XInternAtoms(display, atomNames, sizeof(atomNames)/sizeof(char*), False,
atoms);
scrPtr->attribsAtom = atoms[0];
scrPtr->deleteWindowAtom = atoms[1];
scrPtr->attribsAtom = XInternAtom(display, "_GNUSTEP_WM_ATTR", False);
scrPtr->protocolsAtom = atoms[2];
scrPtr->deleteWindowAtom = XInternAtom(display, "WM_DELETE_WINDOW", False);
scrPtr->clipboardAtom = atoms[3];
scrPtr->protocolsAtom = XInternAtom(display, "WM_PROTOCOLS", False);
scrPtr->clipboardAtom = XInternAtom(display, "CLIPBOARD", False);
scrPtr->xdndAwareAtom = atoms[4];
scrPtr->xdndSelectionAtom = atoms[5];
scrPtr->xdndEnterAtom = atoms[6];
scrPtr->xdndLeaveAtom = atoms[7];
scrPtr->xdndPositionAtom = atoms[8];
scrPtr->xdndDropAtom = atoms[9];
scrPtr->xdndFinishedAtom = atoms[10];
scrPtr->xdndTypeListAtom = atoms[11];
scrPtr->xdndStatusAtom = atoms[12];
scrPtr->wmStateAtom = atoms[13];
scrPtr->rootView = W_CreateRootView(scrPtr);

View File

@@ -718,10 +718,11 @@ int main(int argc, char **argv)
* Put the testSomething() function you want to test here.
*/
testTabView(scr);
testColorWell(scr);
#if 0
testTabView(scr);
testFontPanel(scr);
testSplitView(scr);

View File

@@ -229,18 +229,6 @@ W_RealizeView(W_View *view)
}
Bool
W_CheckInternalMessage(W_Screen *scr, XClientMessageEvent *cev, int event)
{
if (cev->message_type == scr->internalMessage
&& cev->format == 32 && cev->data.l[1] == event)
return True;
else
return False;
}
void
W_ReparentView(W_View *view, W_View *newParent, int x, int y)
{
@@ -414,6 +402,9 @@ destroyView(W_View *view)
unparentView(view);
W_CleanUpEvents(view);
// WMUnregisterViewDraggedTypes(view);
#if 0
if (view->dragSourceProcs)
wfree(view->dragSourceProcs);
@@ -659,3 +650,19 @@ WMViewXID(WMView *view)
return view->window;
}
WMPoint
WMGetViewScreenPosition(WMView *view)
{
WMScreen *scr = W_VIEW_SCREEN(view);
Window foo;
int x, y;
XTranslateCoordinates(scr->display, W_VIEW_DRAWABLE(view),
scr->rootWin, 0, 0, &x, &y, &foo);
return wmkpoint(x, y);
}