1
0
mirror of https://github.com/gryf/wmaker.git synced 2026-01-07 06:14:13 +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: 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. - fixed WMInsertInBag(). It ignored index, and always put the new item at end.
- added WMSaveUserDefaults(). - added WMSaveUserDefaults().
- rewrote WMPopUpButton to use WMMenuItem - rewrote WMPopUpButton to use WMMenuItem

View File

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

View File

@@ -69,6 +69,7 @@ GFXLIBS = @GFXLIBS@
HEADER_SEARCH_PATH = @HEADER_SEARCH_PATH@ HEADER_SEARCH_PATH = @HEADER_SEARCH_PATH@
ICONEXT = @ICONEXT@ ICONEXT = @ICONEXT@
INTLIBS = @INTLIBS@ INTLIBS = @INTLIBS@
LD = @LD@
LIBPL = @LIBPL@ LIBPL = @LIBPL@
LIBRARY_SEARCH_PATH = @LIBRARY_SEARCH_PATH@ LIBRARY_SEARCH_PATH = @LIBRARY_SEARCH_PATH@
LIBTOOL = @LIBTOOL@ LIBTOOL = @LIBTOOL@
@@ -78,6 +79,7 @@ MAKEINFO = @MAKEINFO@
MOFILES = @MOFILES@ MOFILES = @MOFILES@
NETLIBS = @NETLIBS@ NETLIBS = @NETLIBS@
NLSDIR = @NLSDIR@ NLSDIR = @NLSDIR@
NM = @NM@
OBJDUMP = @OBJDUMP@ OBJDUMP = @OBJDUMP@
PACKAGE = @PACKAGE@ PACKAGE = @PACKAGE@
RANLIB = @RANLIB@ RANLIB = @RANLIB@
@@ -144,10 +146,10 @@ connect_LDADD = libWUtil.a @LIBRARY_SEARCH_PATH@ @NETLIBS@ @LIBPL@
EXTRA_DIST = logo.xpm BUGS EXTRA_DIST = logo.xpm BUGS
# wbutton.c # 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 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_LIBS = @X_LIBS@
X_PRE_LIBS = @X_PRE_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@
libWINGs_a_LIBADD = libWINGs_a_LIBADD =
libWINGs_a_OBJECTS = configuration.o international.o notification.o \ libWINGs_a_OBJECTS = configuration.o dragdestination.o dragsource.o \
selection.o userdefaults.o wapplication.o wappresource.o wballoon.o \ international.o notification.o selection.o userdefaults.o \
wbrowser.o wbutton.o wcolor.o wcolorpanel.o wcolorwell.o wevent.o \ wapplication.o wappresource.o wballoon.o wbrowser.o wbutton.o wcolor.o \
wfilepanel.o wframe.o wfont.o wfontpanel.o widgets.o wlabel.o wlist.o \ wcolorpanel.o wcolorwell.o wevent.o wfilepanel.o wframe.o wfont.o \
wmenuitem.o wmisc.o wpanel.o wpixmap.o wpopupbutton.o \ wfontpanel.o widgets.o wlabel.o wlist.o wmenuitem.o wmisc.o wpanel.o \
wprogressindicator.o wscroller.o wscrollview.o wslider.o wsplitview.o \ wpixmap.o wpopupbutton.o wprogressindicator.o wscroller.o wscrollview.o \
wtabview.o wtextfield.o wwindow.o wview.o error.o findfile.o bagarray.o \ wslider.o wsplitview.o wtabview.o wtextfield.o wwindow.o wview.o \
baglist.o connection.o data.o hashtable.o host.o memory.o usleep.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_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 \ international.o notification.o userdefaults.o wapplication.o wutil.o \
error.o findfile.o hashtable.o memory.o usleep.o error.o findfile.o hashtable.o memory.o usleep.o
AR = ar AR = ar
@@ -217,7 +220,7 @@ DIST_COMMON = README ChangeLog Makefile.am Makefile.in TODO
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
TAR = tar TAR = gtar
GZIP_ENV = --best GZIP_ENV = --best
SOURCES = $(libWINGs_a_SOURCES) $(libWUtil_a_SOURCES) $(wtest_SOURCES) $(wmquery_SOURCES) $(wmfile_SOURCES) $(fontl_SOURCES) $(testmywidget_SOURCES) $(testcolorpanel_SOURCES) $(connect_SOURCES) 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) 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:
.SUFFIXES: .S .c .lo .o .s .SUFFIXES: .S .c .lo .o .s
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) $(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 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) \ cd $(top_builddir) \
@@ -481,7 +484,7 @@ distdir: $(DISTFILES)
@for file in $(DISTFILES); do \ @for file in $(DISTFILES); do \
d=$(srcdir); \ d=$(srcdir); \
if test -d $$d/$$file; then \ if test -d $$d/$$file; then \
cp -pr $$d/$$file $(distdir)/$$file; \ cp -pr $$/$$file $(distdir)/$$file; \
else \ else \
test -f $(distdir)/$$file \ test -f $(distdir)/$$file \
|| ln $$d/$$file $(distdir)/$$file 2> /dev/null \ || 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) DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
TAR = tar TAR = gtar
GZIP_ENV = --best GZIP_ENV = --best
all: all-redirect all: all-redirect
.SUFFIXES: .SUFFIXES:
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) $(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) \ cd $(top_builddir) \
&& CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
@@ -146,10 +146,15 @@ distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
subdir = WINGs/Resources subdir = WINGs/Resources
distdir: $(DISTFILES) 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 \ @for file in $(DISTFILES); do \
d=$(srcdir); \ d=$(srcdir); \
if test -d $$d/$$file; then \ if test -d $$d/$$file; then \
cp -pr $$d/$$file $(distdir)/$$file; \ cp -pr $$/$$file $(distdir)/$$file; \
else \ else \
test -f $(distdir)/$$file \ test -f $(distdir)/$$file \
|| ln $$d/$$file $(distdir)/$$file 2> /dev/null \ || 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 WMGetViewPosition(WMView *view);
WMPoint WMGetViewScreenPosition(WMView *view);
WMWidget *WMWidgetOfView(WMView *view); WMWidget *WMWidgetOfView(WMView *view);
/* notifications */ /* notifications */

View File

@@ -24,7 +24,7 @@ extern "C" {
#define DOUBLE_BUFFER #define DOUBLE_BUFFER
#define WC_UserWidget 128 #define WC_UserWidget 128
@@ -32,22 +32,11 @@ extern "C" {
#define SCROLLER_WIDTH 20 #define SCROLLER_WIDTH 20
/* internal messages */
#define WM_UPDATE_COLORWELL 130
#define XDND_VERSION 4
#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;
typedef struct W_Application { typedef struct W_Application {
char *applicationName; char *applicationName;
int argc; int argc;
@@ -101,6 +90,27 @@ typedef struct W_FocusInfo {
} 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 { typedef struct W_Screen {
Display *display; Display *display;
int screen; int screen;
@@ -145,6 +155,8 @@ typedef struct W_Screen {
Pixmap stipple; Pixmap stipple;
struct W_DraggingInfo dragInfo;
/* colors */ /* colors */
W_Color *white; W_Color *white;
W_Color *black; W_Color *black;
@@ -232,17 +244,26 @@ typedef struct W_Screen {
Cursor textCursor; Cursor textCursor;
Cursor invisibleCursor; Cursor invisibleCursor;
Atom internalMessage; /* for ClientMessage */
Atom attribsAtom; /* GNUstepWindowAttributes */ Atom attribsAtom; /* GNUstepWindowAttributes */
Atom deleteWindowAtom; /* WM_DELETE_WINDOW */ Atom deleteWindowAtom; /* WM_DELETE_WINDOW */
Atom protocolsAtom; /* _XA_WM_PROTOCOLS */ Atom protocolsAtom; /* _XA_WM_PROTOCOLS */
Atom clipboardAtom; /* CLIPBOARD */ 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 */ /* stuff for detecting double-clicks */
Time lastClickTime; /* time of last mousedown event */ Time lastClickTime; /* time of last mousedown event */
@@ -302,11 +323,12 @@ typedef struct W_View {
WMColor *backColor; WMColor *backColor;
#if 0
Atom *droppableTypes;
struct W_DragSourceProcs *dragSourceProcs; struct W_DragSourceProcs *dragSourceProcs;
struct W_DragDestinationProcs *dragDestinationProcs; struct W_DragDestinationProcs *dragDestinationProcs;
int helpContext; int helpContext;
#endif
struct { struct {
unsigned int realized:1; unsigned int realized:1;
@@ -329,6 +351,7 @@ typedef struct W_View {
unsigned int pendingRelease3:1; unsigned int pendingRelease3:1;
unsigned int pendingRelease4:1; unsigned int pendingRelease4:1;
unsigned int pendingRelease5:1; unsigned int pendingRelease5:1;
unsigned int xdndHintSet:1;
} flags; } flags;
int refCount; int refCount;
@@ -442,8 +465,6 @@ void W_BroadcastMessage(W_View *targetParent, XEvent *event);
void W_DispatchMessage(W_View *target, 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); void W_SetFocusOfToplevel(W_View *toplevel, W_View *view);
W_View *W_FocusedViewOfToplevel(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_HandleSelectionEvent(XEvent *event);
void W_HandleDNDClientMessage(WMView *toplevel, XClientMessageEvent *event);
void W_FlushASAPNotificationQueue(); void W_FlushASAPNotificationQueue();

View File

@@ -2,7 +2,7 @@
#define _WUTIL_H_ #define _WUTIL_H_
#include <X11/Xlib.h> #include <X11/Xlib.h>
#include <limits.h>
#include <sys/types.h> #include <sys/types.h>
/* SunOS 4.x Blargh.... */ /* SunOS 4.x Blargh.... */
@@ -10,7 +10,6 @@
#define NULL ((void*)0) #define NULL ((void*)0)
#endif #endif
/* /*
* Warning: proplist.h #defines BOOL which will clash with the * Warning: proplist.h #defines BOOL which will clash with the
* typedef BOOL in Xmd.h * typedef BOOL in Xmd.h
@@ -102,6 +101,12 @@ typedef enum {
} WMConnectionState; } WMConnectionState;
enum {
WBNotFound = INT_MAX /* element was not found in bag */
};
typedef struct W_Bag WMBag; typedef struct W_Bag WMBag;
typedef struct W_Data WMData; typedef struct W_Data WMData;
typedef struct W_HashTable WMHashTable; typedef struct W_HashTable WMHashTable;
@@ -139,6 +144,8 @@ typedef struct {
void (*releaseKey)(const void *); void (*releaseKey)(const void *);
} WMHashTableCallbacks; } WMHashTableCallbacks;
typedef void *WMBagIterator;
typedef struct W_BagFunctions { typedef struct W_BagFunctions {
int (*getItemCount)(WMBag *self); int (*getItemCount)(WMBag *self);
@@ -151,15 +158,17 @@ typedef struct W_BagFunctions {
int (*firstInBag)(WMBag *bag, void *item); int (*firstInBag)(WMBag *bag, void *item);
int (*countInBag)(WMBag *bag, void *item); int (*countInBag)(WMBag *bag, void *item);
void *(*replaceInBag)(WMBag *bag, int index, 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 (*emptyBag)(WMBag *bag);
void (*freeBag)(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*)); int (*findInBag)(WMBag *bag, int (*match)(void*));
void *(*first)(WMBag *bag, void **ptr); void *(*first)(WMBag *bag, WMBagIterator *ptr);
void *(*last)(WMBag *bag, void **ptr); void *(*last)(WMBag *bag, WMBagIterator *ptr);
void *(*next)(WMBag *bag, void **ptr); void *(*next)(WMBag *bag, WMBagIterator *ptr);
void *(*previous)(WMBag *bag, void **ptr); void *(*previous)(WMBag *bag, WMBagIterator *ptr);
void *(*iteratorAtIndex)(WMBag *bag, int index, WMBagIterator *ptr);
int (*indexForIterator)(WMBag *bag, WMBagIterator ptr);
} W_BagFunctions; } 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); #define WMCreateArrayBag(a) WMCreateTreeBag()
WMBag *WMCreateListBagWithDestructor(void (*destructor)(void*)); #define WMCreateArrayBagWithDestructor(a,d) WMCreateTreeBagWithDestructor(d)
#define WMCreateBag(size) WMCreateArrayBag(size) #define WMCreateBag(size) WMCreateTreeBag()
#define WMGetBagItemCount(bag) bag->func.getItemCount(bag) #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 WMPutInBag(bag, item) bag->func.putInBag(bag, item)
#define WMInsertInBag(bag, index, item) bag->func.insertInBag(bag, index, 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 WMRemoveFromBag(bag, item) bag->func.removeFromBag(bag, item)
#define WMDeleteFromBag(bag, index) bag->func.deleteFromBag(bag, index) #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 WMCountInBag(bag, item) bag->func.countInBag(bag, item)
#define WMReplaceInBag(bag, index, item) bag->func.replaceInBag(bag, index, 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: /* comparer must return:
* < 0 if a < b * < 0 if a < b
@@ -342,8 +383,8 @@ WMBag *WMCreateListBagWithDestructor(void (*destructor)(void*));
#define WMEmptyBag(bag) bag->func.emptyBag(bag) #define WMEmptyBag(bag) bag->func.emptyBag(bag)
#define WMFreeBag(bag) bag->func.freeBag(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) #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 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; void **items;
int size; int size;
int count; int count;
int base;
int first;
int last;
} W_ArrayBag; } W_ArrayBag;
@@ -26,15 +30,17 @@ static void* getFromBag(WMBag *bag, int index);
static int firstInBag(WMBag *bag, void *item); static int firstInBag(WMBag *bag, void *item);
static int countInBag(WMBag *bag, void *item); static int countInBag(WMBag *bag, void *item);
static void* replaceInBag(WMBag *bag, int index, 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 emptyBag(WMBag *bag);
static void freeBag(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 int findInBag(WMBag *bag, int (*match)(void*));
static void* first(WMBag *bag, void **ptr); static void* first(WMBag *bag, void **ptr);
static void* last(WMBag *bag, void **ptr); static void* last(WMBag *bag, void **ptr);
static void* next(WMBag *bag, void **ptr); static void* next(WMBag *bag, void **ptr);
static void* previous(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 = { static W_BagFunctions arrayFunctions = {
@@ -56,21 +62,26 @@ static W_BagFunctions arrayFunctions = {
first, first,
last, last,
next, next,
previous previous,
iteratorAtIndex,
indexForIterator
}; };
#define ARRAY ((W_ArrayBag*)bag->data) #define ARRAY ((W_ArrayBag*)bag->data)
#define I2O(a, i) ((a)->base + i)
WMBag* WMBag*
WMCreateArrayBagWithDestructor(int size, void (*destructor)(void*)) WMCreateArrayBagWithDestructor(int initialSize, void (*destructor)(void*))
{ {
WMBag *bag; WMBag *bag;
W_ArrayBag *array; W_ArrayBag *array;
int size;
wassertrv(size > 0, NULL);
bag = wmalloc(sizeof(WMBag)); bag = wmalloc(sizeof(WMBag));
array = wmalloc(sizeof(W_ArrayBag)); array = wmalloc(sizeof(W_ArrayBag));
@@ -80,6 +91,9 @@ WMCreateArrayBagWithDestructor(int size, void (*destructor)(void*))
array->items = wmalloc(sizeof(void*) * size); array->items = wmalloc(sizeof(void*) * size);
array->size = size; array->size = size;
array->count = 0; array->count = 0;
array->first = 0;
array->last = 0;
array->base = 0;
bag->func = arrayFunctions; bag->func = arrayFunctions;
@@ -90,9 +104,9 @@ WMCreateArrayBagWithDestructor(int size, void (*destructor)(void*))
WMBag* WMBag*
WMCreateArrayBag(int size) WMCreateArrayBag(int initialSize)
{ {
return WMCreateArrayBagWithDestructor(size, NULL); return WMCreateArrayBagWithDestructor(initialSize, NULL);
} }
@@ -106,20 +120,18 @@ getItemCount(WMBag *bag)
static int static int
appendBag(WMBag *bag, WMBag *appendedBag) appendBag(WMBag *bag, WMBag *appendedBag)
{ {
W_ArrayBag *array1 = ARRAY; W_ArrayBag *array = (W_ArrayBag*)appendedBag->data;
W_ArrayBag *array2 = (W_ArrayBag*)appendedBag->data; int ok;
int i;
if (array1->count + array2->count >= array1->size) { for (i = array->first; i <= array->last; i++) {
array1->items = if (array->items[array->base+i]) {
wrealloc(array1->items, sizeof(void*) * (array1->size+array2->count)); ok = putInBag(bag, array->items[array->base+i]);
array1->size += array2->count; if (!ok)
return 0;
}
} }
memcpy(array1->items + array1->count, array2->items,
sizeof(void*) * array2->count);
array1->count += array2->count;
return 1; return 1;
} }
@@ -128,7 +140,7 @@ appendBag(WMBag *bag, WMBag *appendedBag)
static int static int
putInBag(WMBag *bag, void *item) 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; W_ArrayBag *array = ARRAY;
if (array->count == array->size) { if (I2O(array, index) >= array->size) {
array->size += 16; array->size = WMAX(array->size + 16, I2O(array, index));
array->items = wrealloc(array->items, sizeof(void*) * array->size); 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) { if (index > array->last) {
memmove(&array->items[index+1], &array->items[index], array->last = index;
(array->count - index) * sizeof(void*)); } else if (index >= array->first) {
memmove(array->items + I2O(array, index),
array->items + (I2O(array, index) + 1), sizeof(void*));
array->last++;
} else { } else {
/* If index is invalid, place it at end */ memmove(array->items,
index = array->count; 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++; array->count++;
return 1; 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*)) sortBag(WMBag *bag, int (*comparer)(const void*, const void*))
{ {
qsort(ARRAY->items, ARRAY->count, sizeof(void*), comparer); qsort(ARRAY->items, ARRAY->count, sizeof(void*), comparer);
return 1;
} }
@@ -294,20 +317,15 @@ freeBag(WMBag *bag)
} }
static WMBag* static void
mapBag(WMBag *bag, void *(*function)(void *)) mapBag(WMBag *bag, void (*function)(void *, void *), void *clientData)
{ {
int i; int i;
void *data;
WMBag *new = WMCreateArrayBagWithDestructor(ARRAY->size, bag->destructor);
for (i = 0; i < ARRAY->count; i++) { for (i = 0; i < ARRAY->last; i++) {
data = (*function)(ARRAY->items[i]); if (ARRAY->items[i])
if (data) (*function)(ARRAY->items[i], clientData);
putInBag(new, data);
} }
return new;
} }
@@ -316,7 +334,7 @@ findInBag(WMBag *bag, int (*match)(void*))
{ {
int i; int i;
for (i = 0; i < ARRAY->count; i++) { for (i = 0; i < ARRAY->last; i++) {
if ((*match)(ARRAY->items[i])) if ((*match)(ARRAY->items[i]))
return 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 *next;
struct W_Item *prev; struct W_Item *prev;
void *data; void *data;
int index;
} W_Item; } W_Item;
@@ -23,9 +24,6 @@ typedef struct W_ListBag {
static int getItemCount(WMBag *self); static int getItemCount(WMBag *self);
static int appendBag(WMBag *self, WMBag *bag); static int appendBag(WMBag *self, WMBag *bag);
static int putInBag(WMBag *self, void *item); 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 sortBag(WMBag *bag, int (*comparer)(const void*, const void*));
static void emptyBag(WMBag *bag); static void emptyBag(WMBag *bag);
static void freeBag(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 int findInBag(WMBag *bag, int (*match)(void*));;
static void *first(WMBag *bag, void **ptr); static void *first(WMBag *bag, WMBagIterator *ptr);
static void *last(WMBag *bag, void **ptr); static void *last(WMBag *bag, WMBagIterator *ptr);
static void *next(WMBag *bag, void **ptr); static void *next(WMBag *bag, WMBagIterator *ptr);
static void *previous(WMBag *bag, void **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 = { static W_BagFunctions bagFunctions = {
getItemCount, getItemCount,
@@ -65,7 +66,9 @@ static W_BagFunctions bagFunctions = {
first, first,
last, last,
next, 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); WMBag *bag = WMCreateListBagWithDestructor(self->destructor);
W_Item *ptr = SELF->first; W_Item *ptr = SELF->first;
while (ptr) { while (ptr) {
if ((*function)(ptr->data)) (*function)(ptr->data, data);
putInBag(bag, ptr->data);
ptr = ptr->next; ptr = ptr->next;
} }
return bag; 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; *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; *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; 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; 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 */ unsigned growth; /* How much to grow */
void *bytes; /* Actual data */ void *bytes; /* Actual data */
unsigned retainCount; unsigned retainCount;
unsigned freeData:1; /* whether the data should be released */
} W_Data; } W_Data;
@@ -52,6 +53,7 @@ WMCreateDataWithCapacity(unsigned capacity) /*FOLD00*/
aData->growth = capacity/2 > 0 ? capacity/2 : 1; aData->growth = capacity/2 > 0 ? capacity/2 : 1;
aData->length = 0; aData->length = 0;
aData->retainCount = 1; aData->retainCount = 1;
aData->freeData = 1;
return aData; return aData;
} }
@@ -96,6 +98,7 @@ WMCreateDataWithBytesNoCopy(void *bytes, unsigned length) /*FOLD00*/
aData->growth = length/2 > 0 ? length/2 : 1; aData->growth = length/2 > 0 ? length/2 : 1;
aData->bytes = bytes; aData->bytes = bytes;
aData->retainCount = 1; aData->retainCount = 1;
aData->freeData = 0;
return aData; return aData;
} }
@@ -125,7 +128,7 @@ WMReleaseData(WMData *aData) /*FOLD00*/
aData->retainCount--; aData->retainCount--;
if (aData->retainCount > 0) if (aData->retainCount > 0)
return; return;
if (aData->bytes) if (aData->bytes && aData->freeData)
wfree(aData->bytes); wfree(aData->bytes);
wfree(aData); 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 = { W_ViewDelegate _ColorWellViewDelegate = {
NULL, NULL,
NULL, NULL,
NULL, NULL,
NULL, NULL,
willResizeColorWell willResizeColorWell
}; };
#if 0 static unsigned draggingSourceOperation(WMView *self, Bool local);
static WMDragSourceProcs dragProcs = { 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_WIDTH 60
#define DEFAULT_HEIGHT 30 #define DEFAULT_HEIGHT 30
@@ -168,7 +193,16 @@ WMCreateColorWell(WMWidget *parent)
WMAddNotificationObserver(colorChangedObserver, cPtr, WMAddNotificationObserver(colorChangedObserver, cPtr,
WMColorPanelColorChangedNotification, NULL); WMColorPanelColorChangedNotification, NULL);
// WMSetViewDragSourceProcs(cPtr->view, &_DragSourceProcs);
// WMSetViewDragDestinationProcs(cPtr->view, &_DragDestinationProcs);
{
char *types[2] = {"application/X-color", NULL};
//WMRegisterViewForDraggedTypes(cPtr->view, types);
}
return cPtr; 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* static WMPixmap*
makeDragPixmap(WMColorWell *cPtr) 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 static void
handleDragEvents(XEvent *event, void *data) handleDragEvents(XEvent *event, void *data)
{ {
@@ -526,17 +371,17 @@ handleDragEvents(XEvent *event, void *data)
|| abs(cPtr->ipoint.y - event->xmotion.y) > 4) { || abs(cPtr->ipoint.y - event->xmotion.y) > 4) {
WMSize offs; WMSize offs;
WMPixmap *pixmap; WMPixmap *pixmap;
char *types[2] = {"application/X-color", NULL};
offs.width = 2; offs.width = 2;
offs.height = 2; offs.height = 2;
pixmap = makeDragPixmap(cPtr); pixmap = makeDragPixmap(cPtr);
/*
/* WMDragImageFromView(cPtr->view, pixmap, types,
WMDragImageFromView(cPtr->view, pixmap, cPtr->view->pos, wmkpoint(event->xmotion.x_root,
offs, event, True); event->xmotion.y_root),
* */ offs, event, True);
*/
dragColor(cPtr, event, pixmap);
WMReleasePixmap(pixmap); WMReleasePixmap(pixmap);
} }
@@ -585,3 +430,76 @@ destroyColorWell(ColorWell *cPtr)
wfree(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; IdleHandler *handler;
WMBag *handlerCopy; WMBag *handlerCopy;
int i, n; WMBagIterator iter;
if (!idleHandler || WMGetBagItemCount(idleHandler)==0) { if (!idleHandler || WMGetBagItemCount(idleHandler)==0) {
W_FlushIdleNotificationQueue(); W_FlushIdleNotificationQueue();
@@ -312,15 +312,14 @@ checkIdleHandlers()
return (idleHandler!=NULL && WMGetBagItemCount(idleHandler)>0); return (idleHandler!=NULL && WMGetBagItemCount(idleHandler)>0);
} }
n = WMGetBagItemCount(idleHandler); handlerCopy = WMCreateBag(WMGetBagItemCount(idleHandler));
handlerCopy = WMCreateBag(n); WMAppendBag(handlerCopy, idleHandler);
for (i=0; i<n; i++)
WMPutInBag(handlerCopy, WMGetFromBag(idleHandler, i));
for (i=0; i<n; i++) { for (handler = WMBagFirst(handlerCopy, &iter);
handler = WMGetFromBag(handlerCopy, i); iter != NULL;
handler = WMBagNext(handlerCopy, &iter)) {
/* check if the handler still exist or was removed by a callback */ /* check if the handler still exist or was removed by a callback */
if (WMGetFirstInBag(idleHandler, handler)<0) if (WMGetFirstInBag(idleHandler, handler) == WBNotFound)
continue; continue;
(*handler->callback)(handler->clientData); (*handler->callback)(handler->clientData);
@@ -586,6 +585,10 @@ WMHandleEvent(XEvent *event)
|| event->type == SelectionRequest) { || event->type == SelectionRequest) {
/* handle selection related events */ /* handle selection related events */
W_HandleSelectionEvent(event); 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 */ /* if it's a key event, redispatch it to the focused control */
@@ -640,12 +643,12 @@ WMHandleEvent(XEvent *event)
W_RetainView(toplevel); W_RetainView(toplevel);
hPtr = view->handlerList; hPtr = view->handlerList;
while (hPtr!=NULL) { while (hPtr!=NULL) {
W_EventHandler *tmp; W_EventHandler *tmp;
tmp = hPtr->nextHandler; tmp = hPtr->nextHandler;
if ((hPtr->eventMask & mask)) { if ((hPtr->eventMask & mask)) {
(*hPtr->proc)(event, hPtr->clientData); (*hPtr->proc)(event, hPtr->clientData);
} }
@@ -654,14 +657,14 @@ WMHandleEvent(XEvent *event)
} }
/* pass the event to the top level window of the widget */ /* pass the event to the top level window of the widget */
if (view->parent!=NULL) { if (view->parent != NULL) {
vPtr = view; vPtr = view;
while (vPtr->parent!=NULL) while (vPtr->parent != NULL)
vPtr = vPtr->parent; vPtr = vPtr->parent;
hPtr = vPtr->handlerList; hPtr = vPtr->handlerList;
while (hPtr!=NULL) { while (hPtr != NULL) {
if (hPtr->eventMask & mask) { if (hPtr->eventMask & mask) {
(*hPtr->proc)(event, hPtr->clientData); (*hPtr->proc)(event, hPtr->clientData);

View File

@@ -546,6 +546,23 @@ WMCreateScreenWithRContext(Display *display, int screen, RContext *context)
XGCValues gcv; XGCValues gcv;
Pixmap stipple; Pixmap stipple;
static int initialized = 0; 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) { if (!initialized) {
@@ -738,16 +755,29 @@ WMCreateScreenWithRContext(Display *display, int screen, RContext *context)
XFreePixmap(display, blank); 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->xdndAwareAtom = atoms[4];
scrPtr->xdndSelectionAtom = atoms[5];
scrPtr->clipboardAtom = XInternAtom(display, "CLIPBOARD", False); 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); 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. * Put the testSomething() function you want to test here.
*/ */
testTabView(scr);
testColorWell(scr); testColorWell(scr);
#if 0 #if 0
testTabView(scr);
testFontPanel(scr); testFontPanel(scr);
testSplitView(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 void
W_ReparentView(W_View *view, W_View *newParent, int x, int y) W_ReparentView(W_View *view, W_View *newParent, int x, int y)
{ {
@@ -414,6 +402,9 @@ destroyView(W_View *view)
unparentView(view); unparentView(view);
W_CleanUpEvents(view); W_CleanUpEvents(view);
// WMUnregisterViewDraggedTypes(view);
#if 0 #if 0
if (view->dragSourceProcs) if (view->dragSourceProcs)
wfree(view->dragSourceProcs); wfree(view->dragSourceProcs);
@@ -659,3 +650,19 @@ WMViewXID(WMView *view)
return view->window; 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);
}