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:
@@ -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
|
||||||
|
|||||||
@@ -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 \
|
||||||
|
|||||||
@@ -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 \
|
||||||
|
|||||||
@@ -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 \
|
||||||
|
|||||||
@@ -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 */
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|||||||
114
WINGs/bagarray.c
114
WINGs/bagarray.c
@@ -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)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -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
838
WINGs/bagtree.c
Normal 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;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -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
118
WINGs/dragdestination.c
Normal 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
1042
WINGs/dragsource.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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");
|
||||||
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user