diff options
Diffstat (limited to 'Src/Wasabi/bfc/platform')
-rw-r--r-- | Src/Wasabi/bfc/platform/Makefile.am | 6 | ||||
-rw-r--r-- | Src/Wasabi/bfc/platform/Makefile.in | 376 | ||||
-rw-r--r-- | Src/Wasabi/bfc/platform/export.h | 20 | ||||
-rw-r--r-- | Src/Wasabi/bfc/platform/guid.h | 1 | ||||
-rw-r--r-- | Src/Wasabi/bfc/platform/linux.h | 437 | ||||
-rw-r--r-- | Src/Wasabi/bfc/platform/linux/linux.cpp | 961 | ||||
-rw-r--r-- | Src/Wasabi/bfc/platform/minmax.h | 19 | ||||
-rw-r--r-- | Src/Wasabi/bfc/platform/platform.cpp | 6 | ||||
-rw-r--r-- | Src/Wasabi/bfc/platform/platform.h | 498 | ||||
-rw-r--r-- | Src/Wasabi/bfc/platform/std_string_osx.cpp | 246 | ||||
-rw-r--r-- | Src/Wasabi/bfc/platform/strcmp.h | 15 | ||||
-rw-r--r-- | Src/Wasabi/bfc/platform/types.h | 2 | ||||
-rw-r--r-- | Src/Wasabi/bfc/platform/win32.h | 34 |
13 files changed, 2621 insertions, 0 deletions
diff --git a/Src/Wasabi/bfc/platform/Makefile.am b/Src/Wasabi/bfc/platform/Makefile.am new file mode 100644 index 00000000..aa27d337 --- /dev/null +++ b/Src/Wasabi/bfc/platform/Makefile.am @@ -0,0 +1,6 @@ +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO +noinst_LIBRARIES = libbfc_platform.a +libbfc_platform_a_SOURCES = guid.h linux.h platform.h platform.cpp + +libbfc_platform_a_LIBADD = $(top_builddir)/src/bfc/platform/linux/libbfc_platform_linux.a diff --git a/Src/Wasabi/bfc/platform/Makefile.in b/Src/Wasabi/bfc/platform/Makefile.in new file mode 100644 index 00000000..3ccf8a57 --- /dev/null +++ b/Src/Wasabi/bfc/platform/Makefile.in @@ -0,0 +1,376 @@ +# Makefile.in generated automatically by automake 1.4-p6 from Makefile.am + +# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DESTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = ../../.. + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_alias = @host_alias@ +host_triplet = @host@ +AR = @AR@ +AS = @AS@ +CC = @CC@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +DLLTOOL = @DLLTOOL@ +ECHO = @ECHO@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +F77 = @F77@ +GCJ = @GCJ@ +GCJFLAGS = @GCJFLAGS@ +HAVE_LIB = @HAVE_LIB@ +LIB = @LIB@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +LTLIB = @LTLIB@ +MAKEINFO = @MAKEINFO@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +RANLIB = @RANLIB@ +RC = @RC@ +STRIP = @STRIP@ +VERSION = @VERSION@ + +INCLUDES = -I$(top_srcdir)/src $(all_includes) +METASOURCES = AUTO +noinst_LIBRARIES = libbfc_platform.a +libbfc_platform_a_SOURCES = guid.h linux.h platform.h platform.cpp + +libbfc_platform_a_LIBADD = $(top_builddir)/src/bfc/platform/linux/libbfc_platform_linux.a +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = ../../../config.h +CONFIG_CLEAN_FILES = +LIBRARIES = $(noinst_LIBRARIES) + + +DEFS = @DEFS@ -I. -I$(srcdir) -I../../.. +CPPFLAGS = @CPPFLAGS@ +LDFLAGS = @LDFLAGS@ +LIBS = @LIBS@ +libbfc_platform_a_DEPENDENCIES = \ +$(top_builddir)/src/bfc/platform/linux/libbfc_platform_linux.a +libbfc_platform_a_OBJECTS = platform.$(OBJEXT) +CXXFLAGS = @CXXFLAGS@ +CXXCOMPILE = $(CXX) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) --mode=compile $(CXX) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(LDFLAGS) -o $@ +CFLAGS = @CFLAGS@ +COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ +DIST_COMMON = Makefile.am Makefile.in + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = tar +GZIP_ENV = --best +DEP_FILES = .deps/platform.P +SOURCES = $(libbfc_platform_a_SOURCES) +OBJECTS = $(libbfc_platform_a_OBJECTS) + +all: all-redirect +.SUFFIXES: +.SUFFIXES: .S .c .cpp .lo .o .obj .s +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --gnu src/bfc/platform/Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES) + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + + +mostlyclean-noinstLIBRARIES: + +clean-noinstLIBRARIES: + -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES) + +distclean-noinstLIBRARIES: + +maintainer-clean-noinstLIBRARIES: + +# FIXME: We should only use cygpath when building on Windows, +# and only if it is available. +.c.obj: + $(COMPILE) -c `cygpath -w $<` + +.s.o: + $(COMPILE) -c $< + +.S.o: + $(COMPILE) -c $< + +mostlyclean-compile: + -rm -f *.o core *.core + -rm -f *.$(OBJEXT) + +clean-compile: + +distclean-compile: + -rm -f *.tab.c + +maintainer-clean-compile: + +.s.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +.S.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + +maintainer-clean-libtool: + +libbfc_platform.a: $(libbfc_platform_a_OBJECTS) $(libbfc_platform_a_DEPENDENCIES) + -rm -f libbfc_platform.a + $(AR) cru libbfc_platform.a $(libbfc_platform_a_OBJECTS) $(libbfc_platform_a_LIBADD) + $(RANLIB) libbfc_platform.a +.cpp.o: + $(CXXCOMPILE) -c $< +.cpp.obj: + $(CXXCOMPILE) -c `cygpath -w $<` +.cpp.lo: + $(LTCXXCOMPILE) -c $< + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + here=`pwd` && cd $(srcdir) \ + && mkid -f$$here/ID $$unique $(LISP) + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ + || (cd $(srcdir) && etags -o $$here/TAGS $(ETAGS_ARGS) $$tags $$unique $(LISP)) + +mostlyclean-tags: + +clean-tags: + +distclean-tags: + -rm -f TAGS ID + +maintainer-clean-tags: + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +subdir = src/bfc/platform + +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 src/bfc/platform/Makefile + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + if test -d $$d/$$file; then \ + cp -pr $$d/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ + done + +DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :) + +-include $(DEP_FILES) + +mostlyclean-depend: + +clean-depend: + +distclean-depend: + -rm -rf .deps + +maintainer-clean-depend: + +%.o: %.c + @echo '$(COMPILE) -c $<'; \ + $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $< + @-cp .deps/$(*F).pp .deps/$(*F).P; \ + tr ' ' '\012' < .deps/$(*F).pp \ + | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \ + >> .deps/$(*F).P; \ + rm .deps/$(*F).pp + +%.lo: %.c + @echo '$(LTCOMPILE) -c $<'; \ + $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $< + @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \ + < .deps/$(*F).pp > .deps/$(*F).P; \ + tr ' ' '\012' < .deps/$(*F).pp \ + | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \ + >> .deps/$(*F).P; \ + rm -f .deps/$(*F).pp + +%.o: %.cpp + @echo '$(CXXCOMPILE) -c $<'; \ + $(CXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $< + @-cp .deps/$(*F).pp .deps/$(*F).P; \ + tr ' ' '\012' < .deps/$(*F).pp \ + | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \ + >> .deps/$(*F).P; \ + rm .deps/$(*F).pp + +%.lo: %.cpp + @echo '$(LTCXXCOMPILE) -c $<'; \ + $(LTCXXCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $< + @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \ + < .deps/$(*F).pp > .deps/$(*F).P; \ + tr ' ' '\012' < .deps/$(*F).pp \ + | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \ + >> .deps/$(*F).P; \ + rm -f .deps/$(*F).pp +info-am: +info: info-am +dvi-am: +dvi: dvi-am +check-am: all-am +check: check-am +installcheck-am: +installcheck: installcheck-am +install-exec-am: +install-exec: install-exec-am + +install-data-am: +install-data: install-data-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-am +uninstall-am: +uninstall: uninstall-am +all-am: Makefile $(LIBRARIES) +all-redirect: all-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install +installdirs: + + +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + +maintainer-clean-generic: +mostlyclean-am: mostlyclean-noinstLIBRARIES mostlyclean-compile \ + mostlyclean-libtool mostlyclean-tags mostlyclean-depend \ + mostlyclean-generic + +mostlyclean: mostlyclean-am + +clean-am: clean-noinstLIBRARIES clean-compile clean-libtool clean-tags \ + clean-depend clean-generic mostlyclean-am + +clean: clean-am + +distclean-am: distclean-noinstLIBRARIES distclean-compile \ + distclean-libtool distclean-tags distclean-depend \ + distclean-generic clean-am + -rm -f libtool + +distclean: distclean-am + +maintainer-clean-am: maintainer-clean-noinstLIBRARIES \ + maintainer-clean-compile maintainer-clean-libtool \ + maintainer-clean-tags maintainer-clean-depend \ + maintainer-clean-generic distclean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +maintainer-clean: maintainer-clean-am + +.PHONY: mostlyclean-noinstLIBRARIES distclean-noinstLIBRARIES \ +clean-noinstLIBRARIES maintainer-clean-noinstLIBRARIES \ +mostlyclean-compile distclean-compile clean-compile \ +maintainer-clean-compile mostlyclean-libtool distclean-libtool \ +clean-libtool maintainer-clean-libtool tags mostlyclean-tags \ +distclean-tags clean-tags maintainer-clean-tags distdir \ +mostlyclean-depend distclean-depend clean-depend \ +maintainer-clean-depend info-am info dvi-am dvi check check-am \ +installcheck-am installcheck install-exec-am install-exec \ +install-data-am install-data install-am install uninstall-am uninstall \ +all-redirect all-am all installdirs mostlyclean-generic \ +distclean-generic clean-generic maintainer-clean-generic clean \ +mostlyclean distclean maintainer-clean + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/Src/Wasabi/bfc/platform/export.h b/Src/Wasabi/bfc/platform/export.h new file mode 100644 index 00000000..68e6e3c9 --- /dev/null +++ b/Src/Wasabi/bfc/platform/export.h @@ -0,0 +1,20 @@ +#ifndef NULLSOFT_BFC_EXPORT_H +#define NULLSOFT_BFC_EXPORT_H + +#ifdef _MSC_VER +#define DLLEXPORT __declspec(dllexport) +#elif defined(__GNUC__) +#define DLLEXPORT __attribute__ ((visibility("default"))) +#else +#error port me! +#endif + +#ifdef _MSC_VER +#define DLLIMPORT __declspec(dllimport) +#elif defined(__GNUC__) +#define DLLIMPORT +#else +#error port me! +#endif + +#endif
\ No newline at end of file diff --git a/Src/Wasabi/bfc/platform/guid.h b/Src/Wasabi/bfc/platform/guid.h new file mode 100644 index 00000000..3724f6e1 --- /dev/null +++ b/Src/Wasabi/bfc/platform/guid.h @@ -0,0 +1 @@ +#include "../../../replicant/foundation/guid.h" diff --git a/Src/Wasabi/bfc/platform/linux.h b/Src/Wasabi/bfc/platform/linux.h new file mode 100644 index 00000000..b57ec3f0 --- /dev/null +++ b/Src/Wasabi/bfc/platform/linux.h @@ -0,0 +1,437 @@ +#ifndef __LINUX_H_WASABI +#define __LINUX_H_WASABI + +#include <stdio.h> +#include <stdlib.h> +#include <ctype.h> +#include <unistd.h> +#include <sys/timeb.h> +#include <stdarg.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <dirent.h> +#include <dlfcn.h> +#include <signal.h> +#include <sys/ipc.h> +#include <sys/msg.h> +#include <errno.h> +#include <math.h> +#include <string.h> +#include <strings.h> +#include <sys/shm.h> + +#ifndef NOVTABLE +#define NOVTABLE +#endif + +#ifndef __USE_GNU +#define __USE_GNU +#include <pthread.h> +#undef __USE_GNU +#else +#include <pthread.h> +#endif + +#ifdef WASABI_COMPILE_WND + +// Fucking api_region and Font namespace conflicts +#define _XRegion _XRegion +#define api_region HRGN +#define Font HFONT +#define Cursor _Cursor +#include <X11/Xlib.h> +#include <X11/Xutil.h> +#include <X11/Xresource.h> +#include <X11/extensions/shape.h> +#include <X11/extensions/XShm.h> +#include <X11/Xos.h> +#include <X11/Xatom.h> +#include <X11/xpm.h> +#include <X11/keysym.h> +#include <X11/cursorfont.h> +#undef _XRegion +#undef api_region +#undef Font +#undef Cursor + +#ifdef WASABI_COMPILE_FONTS + +#ifdef __INCLUDE_FREETYPE +#include <freetype/freetype.h> +#include <freetype/ftglyph.h> + +#endif // freetype + +//typedef FT_Face HFONT; +#endif // fonts + +#ifdef __INCLUDE_GTK +#include <gdk/gdkx.h> +#include <gtk/gtk.h> +#endif // gtk + +typedef Window HWND; + +#else // wnd +typedef void * HWND; +#endif // wnd + +// I know about XRectangle, but it's easier to recreate this than it is +// to merge it with the rest of the code +typedef struct { int left, top, right, bottom; } RECT; + +typedef unsigned long COLORREF; +typedef struct { + char rgbBlue; + char rgbGreen; + char rgbRed; + char filler; +} RGBQUAD; +#define RGB( r, g, b ) ((((r)&0xFF)<<16)|(((g)&0xFF)<<8)|((b)&0xFF)) +#define min( a, b ) ((a>b)?b:a) +#define max( a, b ) ((a>b)?a:b) +#define CLR_NONE 0 + +#ifdef __cplusplus +#ifndef XMD_H +typedef int BOOL; // It's int not bool because of some inheritance conflicts +#endif +#ifndef TRUE +#define TRUE true +#endif +#ifndef FALSE +#define FALSE false +#endif +#else +#ifndef XMD_H +typedef int BOOL; +#endif +#ifndef TRUE +#define TRUE 1 +#endif +#ifndef FALSE +#define FALSE 0 +#endif +#endif +typedef BOOL BOOLEAN; +typedef struct { int x, y; } POINT; + +#ifdef WASABI_COMPILE_WND + +typedef void *HPEN; + +// The HDC knows what it's drawing on +typedef struct hdc_typ { + GC gc; + Drawable d; + HRGN clip; +} *HDC; + +// Pixmaps don't have associated width and height, at least not that I know of +typedef struct { + Pixmap p; + int bmWidth; + int bmHeight; + XShmSegmentInfo *shmseginfo; + +} BITMAP, HBITMAP; + +typedef Pixmap HICON; + +#endif // wnd + +typedef int LRESULT; +typedef int LPARAM; +typedef int WPARAM; +typedef int RPARAM; +typedef unsigned int TCHAR; +typedef long long __int64; +typedef long long LARGE_INTEGER; +typedef unsigned long long ULARGE_INTEGER; +#define OSPIPE int +#define OSPROCESSID int +#define LOWORD(a) ((a)&0xffff) +#define HIWORD(a) (((a)>>16)&0xffff) + +#define MAX_PATH 8192 + +#define COMEXP +#define EXTC extern "C" +#define __cdecl +#define CALLBACK +#define WINAPI +#define HRESULT void* +#define WINUSERAPI +#define APIENTRY +#define __declspec(a) +typedef char * LPSTR; +typedef unsigned long DWORD; +typedef short int WORD; +#ifndef XMD_H +typedef unsigned char BYTE; +#endif +typedef void* LPVOID; +typedef struct { + long cx, cy; +} SIZE; +typedef long LONG; +#define VOID void + +#ifdef WASABI_COMPILE_WND +// Fix this for canvas +typedef void * PAINTSTRUCT; +#endif + +#ifndef WASABI_COMPILE_WND +#ifndef None +#define None (HWND)0 +#endif +#endif + +typedef void* THREAD_RET; + +#ifdef WASABI_COMPILE_WND +// Fix this with editwnd! +typedef void * WNDPROC; +typedef void * DRAWITEMSTRUCT; + +#define VK_MENU (XK_Alt_L | (XK_Alt_R << 16)) +#define VK_MBUTTON (XK_Meta_L | (XK_Meta_R << 16)) +#define VK_SHIFT (XK_Shift_L | (XK_Shift_R << 16)) +#define MK_RBUTTON ((XK_VoidSymbol << 16) | 1) +#define MK_LBUTTON ((XK_VoidSymbol << 16) | 2) +#define VK_CONTROL (XK_Control_L | (XK_Control_R << 16)) +#define VK_DELETE (XK_Delete | (XK_KP_Delete << 16)) +#define VK_RETURN (XK_Return) +#define VK_ESCAPE (XK_Escape) +#define VK_DOWN (XK_Down) +#define VK_UP (XK_Up) +#define VK_LEFT (XK_Left) +#define VK_RIGHT (XK_Right) +#define VK_HOME (XK_Home) +#define VK_END (XK_End) +#define VK_PRIOR (XK_Prior) +#define VK_NEXT (XK_Next) +#define VK_BACK (XK_BackSpace) +#define VK_F1 (XK_F1) +#define VK_SPACE (XK_space) + +#define INVALID_HANDLE_VALUE NULL +#endif + +// Come back here later +typedef struct { + pthread_mutex_t mutex; + pthread_t id; + int count; +} CRITICAL_SECTION; +typedef pthread_t HANDLE; + +typedef char OLECHAR; + +//#define NO_MMX +//CUT? #define NULLREGION 0 + +#define MAIN_MINX 0 +#define MAIN_MINY 0 + +typedef void (*TIMERPROC)(HWND, UINT, UINT, DWORD); + +typedef struct { + HWND hwnd; + UINT message; + WPARAM wParam; + LPARAM lParam; + DWORD time; + POINT pt; +} MSG; + +#ifdef __cplusplus + +#define _TRY try +#define _EXCEPT(x) catch(...) + +#include <new> + +#ifdef WASABI_COMPILE_WND + +#define NULLREGION 1 +#define SIMPLEREGION 2 +#define COMPLEXREGION 3 + +#endif + +// some of these are used even without wnd support + +enum { + WM_CREATE, // MULL + WM_CLOSE, // NULL + WM_PAINT, // NULL + WM_NCPAINT, // NULL + WM_SYNCPAINT, // NULL + WM_SETCURSOR, // NULL + WM_TIMER, // timerid + WM_SETFOCUS, // NULL + WM_KILLFOCUS, // NULL + WM_LBUTTONDOWN, // xPos | yPos << 16 + WM_RBUTTONDOWN, // " + WM_MOUSEMOVE, // " + WM_LBUTTONUP, // " + WM_RBUTTONUP, // " + WM_CONTEXTMENU, // " + WM_ERASEBKGND, // NULL + WM_MOUSEWHEEL, // a << 16 | t (l=a/120) + WM_CHAR, // char + WM_KEYDOWN, // keypress + WM_KEYUP, // " + WM_SYSKEYDOWN, // look at OnSysKeyDown + WM_SYSKEYUP, // " + WM_SYSCOMMAND, // Hunh? + WM_MOUSEACTIVATE, // Hunh? + WM_ACTIVATEAPP, // Hunh? + WM_ACTIVATE, // WA_ACTIVE || WA_CLICKACTIVE + WM_NCACTIVATE, // NULL + WM_WINDOWPOSCHANGED, // NULL, WINDOWPOS * + WM_DROPFILES, // HDROP + WM_CAPTURECHANGED, // NULL + WM_COMMAND, // Commands?.. + WM_SETTINGCHANGE, + WM_QUIT, + WM_DESTROY, + WM_USER = 1000, // wParam, lParam -> make sure this is last +}; + +#define PM_NOREMOVE 0x0000 +#define PM_REMOVE 0x0001 +#define PM_NOYIELD 0x0002 // ignored + +#ifdef WASABI_COMPILE_WND + +enum { + WA_ACTIVE, WA_CLICKACTIVE, +}; + +enum { + SC_CLOSE, +}; + +enum { + DT_LEFT, + DT_CENTER, + DT_RIGHT, + DT_VCENTER, + DT_WORDBREAK, + DT_SINGLELINE, + DT_NOPREFIX, + DT_PATH_ELLIPSIS, + DT_END_ELLIPSIS, + DT_MODIFYSTRING, + DT_CALCRECT, + +}; + +#define ALL_EVENTS ExposureMask | StructureNotifyMask | \ + KeyPressMask | KeyReleaseMask | \ + ButtonPressMask | ButtonReleaseMask | \ + PointerMotionMask | FocusChangeMask | \ + EnterWindowMask | LeaveWindowMask + + +#define NO_INPUT_EVENTS ExposureMask | StructureNotifyMask | \ + PointerMotionMask | FocusChangeMask | \ + EnterWindowMask | LeaveWindowMask + +class Linux { + private: + static Display *display; + static XContext context; + + public: + static Display *getDisplay(); + static int getScreenNum(); + static Window RootWin(); + static Visual *DefaultVis(); + + static int convertEvent( MSG *, XEvent * ); + static void initContextData( HWND h ); + static void nukeContextData( HWND h ); + static XContext getContext(); + static void setCursor( HWND h, int cursor ); +}; + +#endif + +#endif + +typedef void* HINSTANCE; // Useless, just a placeholder +typedef void* HMONITOR; +typedef void* WIN32_FIND_DATA; +typedef void* WIN32_FIND_DATAW; +typedef void* BLENDFUNCTION; +typedef void* ATOM; +typedef void* HGLOBAL; +typedef void* HKEY; +typedef char* LPTSTR; +typedef char* LPCTSTR; +typedef DWORD* LPDWORD; + +#if defined(WASABI_API_TIMER) || defined(WASABI_API_WND) +int GetMessage( MSG *, HWND, UINT, UINT ); +int PeekMessage( MSG *, HWND, UINT, UINT, UINT ); +int DispatchMessage( MSG * ); +int SendMessage( HWND, UINT, WPARAM, LPARAM ); +int SetTimer( HWND, int id, int ms, TIMERPROC ); +void KillTimer( HWND, int id ); +#endif + +#ifdef WASABI_COMPILE_WND + +void TranslateMessage( MSG * ); +void PostMessage( HWND, UINT, WPARAM, LPARAM ); +void PostQuitMessage( int ); + +enum contextdata { + GWL_HINSTANCE = 0, + GWL_USERDATA, + GWL_INVALIDREGION, + GWL_RECT_LEFT, + GWL_RECT_TOP, + GWL_RECT_RIGHT, + GWL_RECT_BOTTOM, + GWL_HWND, + GWL_PARENT, + + GWL_ENUM_SIZE +}; +void MoveWindowRect( HWND, int, int ); +void SetWindowRect( HWND, RECT * ); +int GetWindowRect( HWND, RECT * ); +void SetWindowLong( HWND, enum contextdata, LONG ); +LONG GetWindowLong( HWND, enum contextdata ); +int GetUpdateRect( HWND, RECT *, BOOL ); +void GetUpdateRgn( HWND, HRGN, BOOL ); +void InvalidateRgn( HWND, HRGN, BOOL ); +void InvalidateRect( HWND, const RECT *, BOOL ); +void ValidateRgn( HWND, HRGN ); +void ValidateRect( HWND, const RECT * ); +HWND GetActiveWindow(); +HWND WindowFromPoint( POINT p ); +#endif + +void OutputDebugString( const char *s ); +int MulDiv( int m1, int m2, int d ); +DWORD GetTickCount(); +void Sleep( int ms ); +int IntersectRect(RECT *, const RECT *, const RECT *); +void ExitProcess( int ret ); +DWORD GetModuleFileName(void *pid, const char *filename, int bufsize); +const char *CharPrev(const char *lpszStart, const char *lpszCurrent); + +int SubtractRect( RECT *out, RECT *in1, RECT *in2 ); +int EqualRect( RECT *a, RECT *b ); + + +void CopyFile( const char *f1, const char *f2, BOOL b ); + +#endif + diff --git a/Src/Wasabi/bfc/platform/linux/linux.cpp b/Src/Wasabi/bfc/platform/linux/linux.cpp new file mode 100644 index 00000000..67471d4a --- /dev/null +++ b/Src/Wasabi/bfc/platform/linux/linux.cpp @@ -0,0 +1,961 @@ +#include <precomp.h> + +#include <api/api.h> + #include <api/linux/api_linux.h> + +#include <bfc/ptrlist.h> +#include <bfc/string/string.h> +#include <bfc/critsec.h> +#include <bfc/thread.h> +#include <api/application/ipcs.h> + +#ifdef WASABI_COMPILE_WND +Display *Linux::display = NULL; + +int linux_atoms_loaded = 0; + +Atom winamp_msg; +Atom dnd_enter, dnd_position, dnd_status, dnd_leave, dnd_drop, dnd_finished; +Atom dnd_selection, dnd_wa3drop, dnd_private, dnd_typelist; +Atom dnd_urilist, dnd_textplain, dnd_mozurl; +#endif + +#ifndef _NOSTUDIO + +#ifdef WASABI_COMPILE_WND +void LoadAtoms() { + if ( !linux_atoms_loaded ) { + linux_atoms_loaded = 1; + winamp_msg = XInternAtom( Linux::getDisplay(), "Winamp3", False ); + dnd_wa3drop = XInternAtom( Linux::getDisplay(), "Winamp3_drop", False ); + dnd_enter = XInternAtom( Linux::getDisplay(), "XdndEnter", True ); + dnd_position = XInternAtom( Linux::getDisplay(), "XdndPosition", True ); + dnd_status = XInternAtom( Linux::getDisplay(), "XdndStatus", True ); + dnd_leave = XInternAtom( Linux::getDisplay(), "XdndLeave", True ); + dnd_drop = XInternAtom( Linux::getDisplay(), "XdndDrop", True ); + dnd_finished = XInternAtom( Linux::getDisplay(), "XdndFinished", True ); + dnd_selection = XInternAtom( Linux::getDisplay(), "XdndSelection", True ); + dnd_private = XInternAtom( Linux::getDisplay(), "XdndActionPrivate", True ); + dnd_typelist = XInternAtom( Linux::getDisplay(), "XdndTypeList", True ); + dnd_urilist = XInternAtom( Linux::getDisplay(), "text/uri-list", True ); + dnd_textplain = XInternAtom( Linux::getDisplay(), "text/plain", True ); + dnd_mozurl = XInternAtom( Linux::getDisplay(), "text/x-moz-url", True ); + } +} +#endif + +#endif + +void OutputDebugString( const char *s ) { +#ifdef _DEBUG + fprintf( stderr, "%s", s ); +#endif + char *file = getenv( "WASABI_LOG_FILE" ); + if ( file ) { + if ( !STRCMP( file, "-" ) ) { + fprintf( stdout, "%s", s ); + } else { + FILE *f = fopen( file, "a" ); + if ( f ) { + fprintf( f, "%s", s ); + fclose( f ); + } + } + } +} + +DWORD GetTickCount() { + static int starttime = -1; + + if ( starttime == -1 ) + starttime = time( NULL ); + + struct timeb tb; + ftime( &tb ); + tb.time -= starttime; + return tb.time * 1000 + tb.millitm; +} +void Sleep( int ms ) { + if ( ms != 0 ) { + struct timespec ts = { 0, 0 }; + ts.tv_sec = ms / 1000; + ts.tv_nsec = (ms % 1000) * 1000000; + nanosleep( &ts, NULL); + // usleep(ms * 1000); + } +} + +#ifndef _NOSTUDIO + +#ifdef WASABI_COMPILE_WND + +Display *Linux::getDisplay() { + if ( ! display ) + display = WASABI_API_LINUX->linux_getDisplay(); + + return display; +} + +XContext Linux::getContext() { + static XContext context = 0; + + if ( context == 0 ) + context = WASABI_API_LINUX->linux_getContext(); + + return context; +} + +int Linux::getScreenNum() { return DefaultScreen( getDisplay() ); } + +Window Linux::RootWin() { + return RootWindow( getDisplay(), getScreenNum() ); +} +Visual *Linux::DefaultVis() { + return DefaultVisual( getDisplay(), getScreenNum() ); +} + +void Linux::setCursor( HWND h, int cursor ) { + Cursor c = XCreateFontCursor( Linux::getDisplay(), cursor ); + + if ( cursor == None ) + XUndefineCursor( Linux::getDisplay(), h ); + else + XDefineCursor( Linux::getDisplay(), h, c ); + + XFreeCursor( Linux::getDisplay(), c ); +} + +int Linux::convertEvent( MSG *m, XEvent *e ) { + m->hwnd = e->xany.window; + + if ( m->hwnd ) { + api_window *rw =(api_window *)GetWindowLong( m->hwnd, GWL_USERDATA ); + if ( !rw ) { + // This is to fix messages for dead windows... + return 0; + } + } + + switch ( e->type ) { + case ButtonPress: + switch( e->xbutton.button ) { + case 1: + m->message = WM_LBUTTONDOWN; + m->lParam = (e->xbutton.x & 0xffff) | (e->xbutton.y << 16); + break; + + case 2: + + case 3: + m->message = WM_RBUTTONDOWN; + m->lParam = (e->xbutton.x & 0xffff) | (e->xbutton.y << 16); + break; + + case 4: + m->message = WM_MOUSEWHEEL; + m->wParam = 120 << 16 | 0; // 1 tick, no modifiers + m->lParam = (e->xbutton.x & 0xffff) | (e->xbutton.y << 16); + break; + + case 5: + m->message = WM_MOUSEWHEEL; + m->wParam = (-120) << 16 | 0; // 1 tick, no modifiers + m->lParam = (e->xbutton.x & 0xffff) | (e->xbutton.y << 16); + break; + } + break; + case ButtonRelease: + switch( e->xbutton.button ) { + case 1: + m->message = WM_LBUTTONUP; + m->lParam = (e->xbutton.x & 0xffff) | (e->xbutton.y << 16); + break; + + case 2: + + case 3: + m->message = WM_RBUTTONUP; + m->lParam = (e->xbutton.x & 0xffff) | (e->xbutton.y << 16); + break; + } + break; + case MotionNotify: + { + m->message = WM_MOUSEMOVE; + do { + // Spin... + } while( XCheckTypedWindowEvent( Linux::getDisplay(), m->hwnd, MotionNotify, e ) ); + + RECT r; + POINT offset = {0, 0}; + HWND hwnd = m->hwnd; + + GetWindowRect( hwnd, &r ); + + m->lParam = ((e->xmotion.x_root - r.left) & 0xffff) | + ((e->xmotion.y_root - r.top) << 16); + + if ( ! (e->xmotion.state & ( Button1Mask | Button2Mask | Button3Mask )) ) + PostMessage( m->hwnd, WM_SETCURSOR, m->hwnd, 0 ); + } + break; + + case KeyPress: + m->message = WM_KEYDOWN; + m->wParam = e->xkey.keycode; + break; + + case KeyRelease: + m->message = WM_KEYUP; + m->wParam = e->xkey.keycode; + break; + + case Expose: + { + RECT r; + m->message = WM_PAINT; + do { + r.left = e->xexpose.x; + r.top = e->xexpose.y; + r.right = r.left + e->xexpose.width; + r.bottom = r.top + e->xexpose.height; + InvalidateRect( m->hwnd, &r, FALSE ); + } while( XCheckTypedWindowEvent( Linux::getDisplay(), m->hwnd, Expose, e ) ); + } + break; + + case ClientMessage: { + static int coord = -1; + static Atom supported = None; + XClientMessageEvent cme; + + LoadAtoms(); + + int message = e->xclient.message_type; + if ( message == dnd_enter ) { + if ( e->xclient.data.l[1] & 1 ) { + Atom actual; + int format; + long unsigned int nitems, bytes; + unsigned char *data = NULL; + + XGetWindowProperty( Linux::getDisplay(), e->xclient.data.l[0], + dnd_typelist, 0, 65536, True, XA_ATOM, + &actual, &format, &nitems, &bytes, &data ); + + Atom *atomdata = (Atom *)data; + + supported = None; + for( int i = 0; i < nitems; i++ ) { + if ( atomdata[i] == dnd_urilist ) { + supported = dnd_urilist; + } + } + if ( supported == None ) { + for( int i = 0; i < nitems; i++ ) { + if ( atomdata[i] == dnd_textplain ) { + OutputDebugString( "text/plain found\n" ); + supported = dnd_textplain; + } + } + } + if ( supported == None ) { + for( int i = 0; i < nitems; i++ ) { + if ( atomdata[i] == dnd_mozurl ) { + supported = dnd_mozurl; + } + } + } + + XFree( data ); + } else { + if ( e->xclient.data.l[2] == dnd_urilist || + e->xclient.data.l[3] == dnd_urilist || + e->xclient.data.l[4] == dnd_urilist ) { + supported = dnd_urilist; + } else if ( e->xclient.data.l[2] == dnd_mozurl || + e->xclient.data.l[3] == dnd_mozurl || + e->xclient.data.l[4] == dnd_mozurl ) { + supported = dnd_mozurl; + } + } + + + // DnD Enter + return 0; + + } else if ( message == dnd_position ) { + // DnD Position Notify + + cme.type = ClientMessage; + cme.message_type = dnd_status; + cme.format = 32; + cme.window = e->xclient.data.l[0]; + cme.data.l[0] = e->xclient.window; + cme.data.l[1] = 1; // Can Accept + cme.data.l[2] = cme.data.l[3] = 0; // Empty rectangle - give us moves + cme.data.l[4] = dnd_private; // We're doing our own thing + + if ( coord == -1 && supported != None ) { + XConvertSelection( Linux::getDisplay(), dnd_selection, supported, + dnd_wa3drop, cme.window, CurrentTime ); + } + + coord = e->xclient.data.l[2]; + + XSendEvent( Linux::getDisplay(), e->xclient.data.l[0], False, + NoEventMask, (XEvent *)&cme ); + + return 0; + + } else if ( message == dnd_leave ) { + // DnD Leave + coord = -1; + supported = None; + + return 0; + + } else if ( message == dnd_drop ) { + // DnD Drop + + Window win = e->xclient.data.l[0]; + + cme.type = ClientMessage; + cme.message_type = dnd_finished; + cme.format = 32; + cme.window = e->xclient.data.l[0]; + cme.data.l[0] = e->xclient.window; + cme.data.l[1] = cme.data.l[2] = cme.data.l[3] = cme.data.l[4] = 0; + + XSendEvent( Linux::getDisplay(), e->xclient.data.l[0], False, + NoEventMask, (XEvent *)&cme ); + + if ( supported != None ) { + Atom actual; + int format; + long unsigned int nitems, bytes; + unsigned char *data = NULL; + + XGetWindowProperty( Linux::getDisplay(), cme.window, dnd_wa3drop, + 0, 65536, True, supported, &actual, + &format, &nitems, &bytes, + &data ); + + OutputDebugString( StringPrintf( "Drop data (%d):\n%s\n", nitems, data ) ); + + m->message = WM_DROPFILES; + m->wParam = coord; + m->lParam = (LPARAM)data; + + coord = -1; + supported = None; + + } else { + coord = -1; + supported = None; + return 0; + } + + break; + + } else if ( message == winamp_msg ) { + // Internal Message ... + + m->message = e->xclient.data.l[0]; + m->wParam = e->xclient.data.l[1]; + m->lParam = e->xclient.data.l[2]; + break; + + } else { + return 0; + } + break; + } + + case LeaveNotify: + case EnterNotify: + m->message = WM_MOUSEMOVE; + m->lParam = (e->xcrossing.x & 0xffff) | (e->xcrossing.y << 16); + + if ( ! (e->xcrossing.state & ( Button1Mask | Button2Mask | Button3Mask )) ) + PostMessage( m->hwnd, WM_SETCURSOR, m->hwnd, 0 ); + break; + + case FocusIn: + m->message = WM_SETFOCUS; + break; + + case FocusOut: + m->message = WM_KILLFOCUS; + break; + + default: + return 0; + } + + return 1; +} + +static HWND activeWindow; + +HWND GetActiveWindow() { + return activeWindow; +} + +int IntersectRect( RECT *out, const RECT *i1, const RECT *i2 ) { + return Std::rectIntersect(i1, i2, out); +} + +void TranslateMessage( MSG *m ) { + if ( m->message != WM_CHAR && m->message != WM_KEYDOWN && + m->message != WM_KEYUP ) + return; + + int index = !!( Std::keyDown( VK_SHIFT )); + + m->wParam = XKeycodeToKeysym( Linux::getDisplay(), m->wParam, index ); +} + +void PostMessage( HWND win, UINT msg, WPARAM wParam, LPARAM lParam ) { + XEvent e; + + LoadAtoms(); + + e.type = ClientMessage; + e.xclient.window = win; + e.xclient.message_type = winamp_msg; + e.xclient.format = 32; + e.xclient.data.l[0] = msg; + e.xclient.data.l[1] = wParam; + e.xclient.data.l[2] = lParam; + + XSendEvent( Linux::getDisplay(), win, FALSE, NoEventMask, &e ); +} + +void PostQuitMessage( int i ) { + PostMessage( None, WM_QUIT, i, 0 ); +} + +#endif // wnd + +#if defined(WASABI_API_TIMER) | defined(WASABI_API_WND) + +struct TimerElem { + HWND win; + int id; + int nexttime; + int delta; + TIMERPROC tproc; + + TimerElem( HWND _win, int _id, int ms, TIMERPROC _tproc ) { + win = _win; + id = _id; + delta = ms; + tproc = _tproc; + nexttime = Std::getTickCount() + delta; + } +}; + +int timer_id = 0; +CriticalSection timer_cs; +PtrList<TimerElem> timer_elems; + +int SetTimer( HWND win, int id, int ms, TIMERPROC tproc ) { + KillTimer(win, id); + + if ( win == (HWND)0 ) { + id = timer_id++; + } + + TimerElem *te = new TimerElem( win, id, ms, tproc ); + timer_cs.enter(); + timer_elems.addItem( te, PTRLIST_POS_LAST ); + timer_cs.leave(); + + return id; +} + +void KillTimer( HWND win, int id ) { + timer_cs.enter(); + for( int i = 0; i < timer_elems.getNumItems(); i++ ) + if ( timer_elems[i]->win == win && timer_elems[i]->id == id ) { + delete timer_elems[i]; + timer_elems.delByPos( i ); + i--; + } + timer_cs.leave(); +} + +CriticalSection send_cs; +MSG *send_msg; +int sending = 0; +int send_ret; +pthread_t message_thread = (pthread_t)-1; + +int _GetMessage( MSG *m, HWND, UINT, UINT, int block=1) { + MEMSET( m, 0, sizeof( MSG ) ); + + message_thread = pthread_self(); + +#ifdef WASABI_COMPILE_WND + XEvent e; +#endif // wnd + int curtime; + int done = 0; + int first = 1; + static wa_msgbuf ipcm; + static int qid = -1; + int size; + + if ( qid == -1 ) { qid = WASABI_API_LINUX->linux_getIPCId(); } + + if ( sending ) { + *m = *send_msg; + done = 1; + } + + while( !done && (block || first)) { + if ( qid != -1 ) { + if ( (size = msgrcv( qid, &ipcm, IPC_MSGMAX , 0, IPC_NOWAIT )) != -1 ) { + m->hwnd = None; + m->message = WM_WA_IPC; + m->wParam = (WPARAM)&ipcm; + break; + } + } + + curtime = GetTickCount(); + + timer_cs.enter(); + for( int i = 0; i < timer_elems.getNumItems(); i++ ) { + if ( timer_elems[i]->nexttime < curtime ) { + if (block) + while( timer_elems[i]->nexttime < curtime ) + timer_elems[i]->nexttime += timer_elems[i]->delta; + + m->hwnd = timer_elems[i]->win; + m->message = WM_TIMER; + m->wParam = (WPARAM)timer_elems[i]->id; + m->lParam = (LPARAM)timer_elems[i]->tproc; + + done = 1; + } + } + timer_cs.leave(); + + if ( !done && ! first ) + Sleep( 1 ); + else + first = 0; + +#ifdef WASABI_API_WND + if ( !done && XPending( Linux::getDisplay() ) ) { + int n = XEventsQueued( Linux::getDisplay(), QueuedAlready ); + + for ( int i = 0; !done && i < n; i++ ) { + XNextEvent( Linux::getDisplay(), &e ); + if ( Linux::convertEvent( m, &e ) ) + done = 1; + } + if ( done ) + break; + } +#endif // wnd + } + +#ifdef WASABI_API_WND + activeWindow = m->hwnd; +#endif // wnd + + return m->message != WM_QUIT; +} + +int GetMessage( MSG *m, HWND w, UINT f, UINT l) { + return _GetMessage(m, w, f, l, 1); +} + +// on linux, we don't really simply peek when PM_NOREMOVE is used, +// we just don't block, which is the only thing we want to accomplish here +int PeekMessage( MSG *m, HWND w, UINT f, UINT l, UINT remove) { + if (remove == PM_NOREMOVE) return _GetMessage(m, w, f, l, 0); + else _GetMessage(m, w, f, l, 1); +} + + +int DispatchMessage( MSG *m ) { + if ( m->message == WM_TIMER && m->hwnd == None ) { + TIMERPROC tproc = (TIMERPROC)m->lParam; + tproc( m->hwnd, m->message, m->wParam, 0 ); + return 1; + } + + int ret = 0; + +#ifdef WASABI_COMPILE_WND + api_window *rootwnd = (api_window *)GetWindowLong( m->hwnd, GWL_USERDATA ); + + if ( rootwnd ) { + ret = rootwnd->wndProc( m->hwnd, m->message, m->wParam, m->lParam ); + rootwnd->performBatchProcesses(); + } +#endif // wnd + + if ( sending ) { + send_ret = ret; + sending = 0; + } + + return ret; +} + +int SendMessage( HWND win, UINT msg, WPARAM wParam, LPARAM lParam ) { + MSG m; + m.hwnd = win; + m.message = msg; + m.wParam = wParam; + m.lParam = lParam; + + int ret; + + if ( pthread_equal( message_thread, pthread_self() ) ) { + return DispatchMessage( &m ); + + } else { + send_cs.enter(); + sending = 1; + send_msg = &m; + while( sending ) { Sleep( 1 ); } + ret = send_ret; + send_cs.leave(); + + return ret; + } +} + +#endif // timer | wnd + +int MulDiv( int m1, int m2, int d ) { + __asm__ volatile ( + "mov %0, %%eax\n" + "mov %1, %%ebx\n" + "mov %2, %%ecx\n" + "mul %%ebx\n" + "div %%ecx\n" + : : "m" (m1), "m" (m2), "m" (d) + : "%eax", "%ebx", "%ecx", "%edx" ); +} + +void ExitProcess( int ret ) { + exit( ret ); +} + +#ifdef WASABI_COMPILE_WND + +void Linux::initContextData( HWND h ) { + int *data; + XPointer xp; + + ASSERT( XFindContext( Linux::getDisplay(), h, Linux::getContext(), &xp )); + + data = (int *)MALLOC( GWL_ENUM_SIZE * sizeof( int ) ); + + data[GWL_HWND] = h; + + XSaveContext( Linux::getDisplay(), h, Linux::getContext(), (char *)data ); +} + +void Linux::nukeContextData( HWND h ) { + int *data; + XPointer xp; + + if ( XFindContext( Linux::getDisplay(), h, Linux::getContext(), &xp ) ) + return; + + data = (int *)xp; + + ASSERT( data[GWL_HWND] == h ); + + if ( data[GWL_INVALIDREGION] ) { + XDestroyRegion( (HRGN)data[GWL_INVALIDREGION] ); + } + + XDeleteContext( Linux::getDisplay(), h, Linux::getContext() ); + + FREE( data ); +} + +void SetWindowLong( HWND h, contextdata type, LONG value ) { + XPointer data; + + if ( XFindContext( Linux::getDisplay(), h, Linux::getContext(), &data ) ) + return; + + ASSERT( ((int *)data)[GWL_HWND] == h ); + + ((int*)data)[type] = value; +} + +LONG GetWindowLong( HWND h, contextdata type ) { + XPointer data; + + if ( XFindContext( Linux::getDisplay(), h, Linux::getContext(), &data ) ) + return 0; + + ASSERT( ((int *)data)[GWL_HWND] == h ); + + return ((int*)data)[type]; +} + +void MoveWindowRect( HWND h, int x, int y ) { + XPointer xp; + int *data; + + if ( XFindContext( Linux::getDisplay(), h, Linux::getContext(), &xp ) ) + return; + + data = (int *)xp; + + ASSERT( data[GWL_HWND] == h ); + + data[GWL_RECT_RIGHT] -= data[GWL_RECT_LEFT] - x; + data[GWL_RECT_BOTTOM] -= data[GWL_RECT_TOP] - y; + data[GWL_RECT_LEFT] = x; + data[GWL_RECT_TOP] = y; +} + +void SetWindowRect( HWND h, RECT *r ) { + int *data; + XPointer xp; + + if ( XFindContext( Linux::getDisplay(), h, Linux::getContext(), &xp ) ) + return; + + data = (int *)xp; + + ASSERT( data[GWL_HWND] == h ); + + data[GWL_RECT_LEFT] = r->left; + data[GWL_RECT_TOP] = r->top; + data[GWL_RECT_RIGHT] = r->right; + data[GWL_RECT_BOTTOM] = r->bottom; +} + +int GetWindowRect( HWND h, RECT *r ) { + int *data; + XPointer xp; + + if ( XFindContext( Linux::getDisplay(), h, Linux::getContext(), &xp ) ) + return 0; + + data = (int *)xp; + + ASSERT( data[GWL_HWND] == h ); + + r->left = data[GWL_RECT_LEFT]; + r->top = data[GWL_RECT_TOP]; + r->right = data[GWL_RECT_RIGHT]; + r->bottom = data[GWL_RECT_BOTTOM]; + + POINT offset = { 0, 0}; + while( (h = data[GWL_PARENT]) != Linux::RootWin() ) { + if ( XFindContext( Linux::getDisplay(), h, Linux::getContext(), &xp ) ) + return 0; + + data = (int *)xp; + + ASSERT( data[GWL_HWND] == h ); + + offset.x += data[GWL_RECT_LEFT]; + offset.y += data[GWL_RECT_TOP]; + } + r->left += offset.x; + r->top += offset.y; + r->right += offset.x; + r->bottom += offset.y; + + return 1; +} + +int GetUpdateRect( HWND h, RECT *ret, BOOL ) { + HRGN invalid = (HRGN)GetWindowLong( h, GWL_INVALIDREGION ); + if ( ! invalid || XEmptyRegion( invalid ) ) + return 0; + + XRectangle xr; + XClipBox( invalid, &xr ); + ret->left = xr.x; + ret->top = xr.y; + ret->right = xr.x + xr.width; + ret->bottom = xr.y + xr.height; + + return 1; +} + +void GetUpdateRgn( HWND h, HRGN r, BOOL ) { + XSubtractRegion( r, r, r ); + + HRGN invalid = (HRGN)GetWindowLong( h, GWL_INVALIDREGION ); + if ( ! invalid ) return; + + + XUnionRegion( r, invalid, r ); + + XRectangle xr; + + RECT rct; + GetWindowRect( h, &rct ); + xr.x = 0; + xr.y = 0; + xr.width = rct.right - rct.left; + xr.height = rct.bottom - rct.top; + + HRGN tmp = XCreateRegion(); + + XUnionRectWithRegion( &xr, tmp, tmp ); + XIntersectRegion( r, tmp, r ); + XDestroyRegion( tmp ); +} + +void InvalidateRect( HWND h, const RECT *r, BOOL ) { + HRGN invalid = (HRGN)GetWindowLong( h, GWL_INVALIDREGION ); + if ( ! invalid ) { + invalid = XCreateRegion(); + SetWindowLong( h, GWL_INVALIDREGION, (LONG)invalid ); + } + + XRectangle xr; + if ( r == NULL ) { + RECT rct; + GetWindowRect( h, &rct ); + xr.x = 0; + xr.y = 0; + xr.width = rct.right - rct.left; + xr.height = rct.bottom - rct.top; + } else { + xr.x = r->left; + xr.y = r->top; + xr.width = r->right - r->left; + xr.height = r->bottom - r->top; + } + + XUnionRectWithRegion( &xr, invalid, invalid ); + + PostMessage( h, WM_PAINT, 0, 0 ); +} + +void InvalidateRgn( HWND h, HRGN r, BOOL ) { + HRGN invalid = (HRGN)GetWindowLong( h, GWL_INVALIDREGION ); + + if ( ! invalid ) { + invalid = XCreateRegion(); + SetWindowLong( h, GWL_INVALIDREGION, (LONG)invalid ); + } + + ASSERT( r != invalid ); + XUnionRegion( invalid, r, invalid ); + + PostMessage( h, WM_PAINT, 0, 0 ); +} + +void ValidateRect( HWND h, const RECT *r ) { + HRGN invalid = (HRGN)GetWindowLong( h, GWL_INVALIDREGION ); + if ( ! invalid ) return; + + XRectangle xr; + if ( r == NULL ) { + XDestroyRegion( invalid ); + SetWindowLong( h, GWL_INVALIDREGION, 0 ); + return; + } + + xr.x = r->left; + xr.y = r->top; + xr.width = r->right - r->left; + xr.height = r->bottom - r->top; + + HRGN tmp = XCreateRegion(); + XUnionRectWithRegion( &xr, tmp, tmp ); + XSubtractRegion( invalid, tmp, invalid ); + XDestroyRegion( tmp ); +} + +void ValidateRgn( HWND h, HRGN r ) { + HRGN invalid = (HRGN)GetWindowLong( h, GWL_INVALIDREGION ); + if ( ! invalid ) return; + + ASSERT( r != invalid ); + XSubtractRegion( invalid, r, invalid ); +} +#endif // wnd + +int SubtractRect( RECT *out, RECT *in1, RECT *in2 ) { + int ret; + if ( in1->left >= in2->left && in1->right <= in2->right ) { + out->left = in1->left; out->right = in1->right; + + if ( in1->top >= in2->top && in2->bottom >= in2->top && in2->bottom <= in2->bottom ) { + out->top = in1->bottom; out->bottom = in2->bottom; + + ret = 1; + } else if ( in1->top <= in2->top && in1->bottom >= in2->top && in1->bottom <= in2->bottom ) { + out->top = in1->top; out->bottom = in2->top; + + ret = 1; + } else { + ret = 0; + } + + } else if ( in1->top >= in2->top && in1->bottom <= in2->bottom ) { + out->top = in1->top; out->bottom = in1->bottom; + + if ( in1->left >= in2->left && in2->right >= in2->left && in2->right <= in2->right ) { + out->left = in1->right; out->right = in2->right; + + ret = 1; + } else if ( in1->left <= in2->left && in1->right >= in2->left && in1->right <= in2->right ) { + out->left = in1->left; out->right = in2->left; + + ret = 1; + } else { + ret = 0; + } + + + } else { + ret = 0; + } + return ret; +} + +int EqualRect( RECT *a, RECT *b ) { + return ( a->top == b->top && a->bottom == b->bottom && + a->left == b->left && a->right == b->right ); +} + +#ifdef WASABI_COMPILE_WND + +HWND WindowFromPoint( POINT p ) { + int x, y; + Window child; + + XTranslateCoordinates( Linux::getDisplay(), Linux::RootWin(), Linux::RootWin(), p.x, p.y, &x, &y, &child ); + return child; +} +#endif // wnd + +void CopyFile( const char *f1, const char *f2, BOOL b ) { + COPYFILE( f1, f2 ); +} + +DWORD GetModuleFileName(void *pid, const char *filename, int bufsize) { + char procbuffer[512]; + sprintf(procbuffer, "/proc/%d/exe", (int)pid); + return readlink(procbuffer, (char *)filename, bufsize); +} + +const char *CharPrev(const char *lpszStart, const char *lpszCurrent) { + if (lpszCurrent-1 >= lpszStart) return lpszCurrent-1; + return lpszStart; +} + +#endif diff --git a/Src/Wasabi/bfc/platform/minmax.h b/Src/Wasabi/bfc/platform/minmax.h new file mode 100644 index 00000000..ccc37e96 --- /dev/null +++ b/Src/Wasabi/bfc/platform/minmax.h @@ -0,0 +1,19 @@ +#ifndef NULLSOFT_BFC_PLATFORM_MINMAX_H +#define NULLSOFT_BFC_PLATFORM_MINMAX_H + +#if defined(_WIN32) && !defined(MIN) +#define MIN( a, b ) ((a>b)?b:a) +#define MAX( a, b ) ((a>b)?a:b) +#endif + +#if defined(__APPLE__) && !defined(MIN) +#define MIN( a, b ) ((a>b)?b:a) +#define MAX( a, b ) ((a>b)?a:b) +#endif + +#if defined(__linux__) && !defined(MIN) +#define MIN( a, b ) ((a>b)?b:a) +#define MAX( a, b ) ((a>b)?a:b) +#endif + +#endif
\ No newline at end of file diff --git a/Src/Wasabi/bfc/platform/platform.cpp b/Src/Wasabi/bfc/platform/platform.cpp new file mode 100644 index 00000000..bd9ece7b --- /dev/null +++ b/Src/Wasabi/bfc/platform/platform.cpp @@ -0,0 +1,6 @@ +#include "precomp_wasabi_bfc.h" +#include "platform.h" + +void link_platform() { + OutputDebugString(L"dummy"); +}
\ No newline at end of file diff --git a/Src/Wasabi/bfc/platform/platform.h b/Src/Wasabi/bfc/platform/platform.h new file mode 100644 index 00000000..6a14967a --- /dev/null +++ b/Src/Wasabi/bfc/platform/platform.h @@ -0,0 +1,498 @@ +#pragma once + +#include <bfc/platform/types.h> +#include <bfc/std_mkncc.h> // for MKnCC + +#ifdef WIN32 +# include <bfc/platform/win32.h> + +#define OSMODULEHANDLE HINSTANCE +#define INVALIDOSMODULEHANDLE ((OSMODULEHANDLE)0) +#define OSWINDOWHANDLE HWND +#define INVALIDOSWINDOWHANDLE ((OSWINDOWHANDLE)0) +#define OSICONHANDLE HICON +#define INVALIDOSICONHANDLE ((OSICONHANDLE)0) +#define OSCURSORHANDLE HICON +#define INVALIDOSCURSORHANDLE ((OSCURSORHANDLE)0) +#define OSTHREADHANDLE HANDLE +#define INVALIDOSTHREADHANDLE ((OSTHREADHANDLE)0) +#define OSREGIONHANDLE HRGN +#define INVALIDOSREGIONHANDLE ((OSREGIONHANDLE)0) +typedef HMENU OSMENUHANDLE; + +#define RGBA(r,g,b,a) ((ARGB32)((uint8_t)(r) | ((uint8_t)(g) << 8) | ((uint8_t)(b) << 16) | ((uint8_t)(a) << 24))) + +#ifndef PATH_MAX +#define PATH_MAX MAX_PATH +#endif + +#elif defined(LINUX) +# include <bfc/platform/linux.h> +#elif defined(__APPLE__) +#include <Carbon/Carbon.h> + +typedef HIShapeRef OSREGIONHANDLE; +typedef int OSCURSOR; // TODO: find a good one for this +typedef int OSCURSORHANDLE; // TODO: find a good one for this +typedef HIWindowRef OSWINDOWHANDLE; +typedef void *OSMODULEHANDLE; // TODO: +typedef CGContextRef HDC; // TODO: find a better name +typedef MenuRef OSMENUHANDLE; +typedef CGImageRef OSICONHANDLE; + +#ifdef __LITTLE_ENDIAN__ +#define RGBA(r,g,b,a) ((ARGB32)((uint8_t)(r) | ((uint8_t)(g) << 8) | ((uint8_t)(b) << 16) | ((uint8_t)(a) << 24))) +#elif defined(__BIG_ENDIAN__) +#define RGBA(r,g,b,a) ((ARGB32)((uint8_t)(a) | ((uint8_t)(r) << 8) | ((uint8_t)(g) << 16) | ((uint8_t)(b) << 24))) +#else +#error endian preprocessor symbol not defined +#endif + +#define RGB(r,g,b) RGBA(r,g,b,0xFF) + +static const HIWindowRef INVALIDOSWINDOWHANDLE = 0; // TODO: maybe there's an apple-defined name for this +#define INVALIDOSMODULEHANDLE 0 +#define INVALIDOSCURSORHANDLE 0 + +typedef char OSFNCHAR; +typedef char *OSFNSTR; + +typedef const char OSFNCCHAR; +typedef const char *OSFNCSTR; + +#define FNT(x) x + +typedef struct tagRECT +{ + int left; + int top; + int right; + int bottom; +} +RECT; +typedef RECT * LPRECT; + +inline RECT RECTFromHIRect(const HIRect *r) +{ + RECT rect; + rect.left = r->origin.x; + rect.right = r->origin.x + r->size.width; + rect.top = r->origin.y; + rect.bottom = r->origin.y + r->size.height; + return rect; +} + +inline HIRect HIRectFromRECT(const RECT *r) +{ + HIRect rect; + rect.origin.x = r->left; + rect.origin.y = r->top; + rect.size.width = r->right - r->left; + rect.size.height = r->bottom - r->top; + return rect; +} + +typedef struct tagPOINT +{ + int x; + int y; +} +POINT; +typedef struct tagPOINT * LPPOINT; + +inline HIPoint HIPointFromPOINT(const POINT *pt) +{ + HIPoint p; + p.x = pt->x; + p.y = pt->y; + return p; +} + +inline int MulDiv(int a, int b, int c) +{ + int s; + int v; + + s = 0; + if (a < 0) + { + s = !s; + a = -a; + } + if (b < 0) + { + s = !s; + b = -b; + } + if (c < 0) + { + s = !s; + c = -c; + } + double d; + d = ((double)a * (double)b) / (double)c; + if (d >= 4294967296.) + return -1; + v = d; + if (s) + v = -v; + return v; +} + +#else +#error port me +// Windows API dependant definitions for non-windows platforms + +#define __cdecl +#define __stdcall +#define WINAPI +#define WINBASEAPI +#define WINUSERAPI +#define WINGDIAPI +#define WINOLEAPI +#define CALLBACK +#define FARPROC void * + +#define FALSE 0 +#define TRUE 1 + +#define ERROR 0 + +#define CONST const +#define VOID void + +typedef unsigned long DWORD; +typedef unsigned short WORD; +typedef unsigned char BYTE; +typedef long LONG; +typedef int INT; +typedef int BOOL; +typedef short SHORT; +typedef void * PVOID; +typedef void * LPVOID; + +typedef char CHAR; +typedef unsigned short WCHAR; +typedef char * LPSTR; +typedef WCHAR * LPWSTR; +typedef const char * LPCSTR; +typedef const WCHAR * LPCWSTR; +typedef LPWSTR PTSTR, LPTSTR; +typedef LPCWSTR LPCTSTR; +typedef char TCHAR; +typedef WCHAR OLECHAR; + +typedef void * HANDLE; +typedef void * HWND; +typedef void * HDC; +typedef void * HFONT; +typedef void * HBITMAP; +typedef void * HINSTANCE; +typedef void * HICON; +typedef void * HRGN; +typedef void * HPEN; +typedef void * HBRUSH; +typedef void * HRSRC; +typedef void * HGLOBAL; +typedef void * HACCEL; +typedef void * HMODULE; +typedef void * HMENU; +typedef void * HGDIOBJ; + +typedef void * ATOM; +typedef void * CRITICAL_SECTION; +typedef void * LPCRITICAL_SECTION; + +typedef UINT WPARAM; +typedef UINT LPARAM; +typedef LONG LRESULT; +typedef UINT COLORREF; + +typedef LRESULT(*WNDPROC)(HWND, UINT, WPARAM, LPARAM); +typedef BOOL CALLBACK WNDENUMPROC(HWND, LPARAM); +typedef VOID CALLBACK *TIMERPROC(HWND, UINT, UINT, DWORD); + +typedef struct tagPOINT +{ + LONG x; + LONG y; +} +POINT; +typedef struct tagPOINT * LPPOINT; + +typedef struct tagSIZE +{ + LONG cx; + LONG cy; +} +SIZE; + + +typedef struct tagRECT +{ + LONG left; + LONG top; + LONG right; + LONG bottom; +} +RECT; +typedef RECT * LPRECT; + +typedef struct _COORD +{ + SHORT X; + SHORT Y; +} +COORD, *PCOORD; + +typedef struct tagPAINTSTRUCT +{ + HDC hdc; + BOOL fErase; + RECT rcPaint; + BOOL fRestore; + BOOL fIncUpdate; + BYTE rgbReserved[32]; +} +PAINTSTRUCT; + +typedef struct tagBITMAP +{ /* bm */ + int bmType; + int bmWidth; + int bmHeight; + int bmWidthBytes; + BYTE bmPlanes; + BYTE bmBitsPixel; + LPVOID bmBits; +} +BITMAP; + +typedef struct tagRGBQUAD +{ + BYTE rgbRed; + BYTE rgbGreen; + BYTE rgbBlue; + BYTE rgbReserved; +} +RGBQUAD; + +typedef struct tagBITMAPINFOHEADER +{ + DWORD biSize; + LONG biWidth; + LONG biHeight; + WORD biPlanes; + WORD biBitCount; + DWORD biCompression; + DWORD biSizeImage; + LONG biXPelsPerMeter; + LONG biYPelsPerMeter; + DWORD biClrUsed; + DWORD biClrImportant; +} +BITMAPINFOHEADER; + +typedef struct tagBITMAPINFO +{ + BITMAPINFOHEADER bmiHeader; + RGBQUAD bmiColors[1]; +} +BITMAPINFO, *LPBITMAPINFO; + +typedef struct tagMSG +{ + HWND hwnd; + UINT message; + WPARAM wParam; + LPARAM lParam; + DWORD time; + POINT pt; +} +MSG; + +typedef MSG * LPMSG; + +typedef struct _RGNDATAHEADER +{ + DWORD dwSize; + DWORD iType; + DWORD nCount; + DWORD nRgnSize; + RECT rcBound; +} +RGNDATAHEADER, *PRGNDATAHEADER; + +typedef struct _RGNDATA +{ + RGNDATAHEADER rdh; + char Buffer[1]; +} +RGNDATA, *PRGNDATA; + +// Windows messages + +#define WM_SYSCOMMAND 0x112 +#define WM_LBUTTONDOWN 0x201 +#define WM_LBUTTONUP 0x202 +#define WM_RBUTTONDOWN 0x204 +#define WM_RBUTTONUP 0x205 + +#define WM_USER 0x400 + +#define WS_EX_TOOLWINDOW 0x00000080L + +#define WS_OVERLAPPED 0x00000000L +#define WS_MAXIMIZEBOX 0x00010000L +#define WS_MINIMIZEBOX 0x00020000L +#define WS_SYSMENU 0x00080000L +#define WS_CAPTION 0x00C00000L +#define WS_CLIPCHILDREN 0x02000000L +#define WS_CLIPSIBLINGS 0x04000000L +#define WS_VISIBLE 0x10000000L +#define WS_CHILD 0x40000000L +#define WS_POPUP 0x80000000L + +#define HWND_TOP ((HWND)0) +#define HWND_TOPMOST ((HWND)-1) +#define HWND_NOTOPMOST ((HWND)-2) + +#define GWL_STYLE (-16) + +#define GW_HWNDFIRST 0 +#define GW_HWNDNEXT 2 + +#define SWP_NOMOVE 0x0002 +#define SWP_NOSIZE 0x0001 +#define SWP_SHOWWINDOW 0x0040 +#define SWP_DEFERERASE 0x2000 +#define SWP_NOZORDER 0x0004 +#define SWP_NOACTIVATE 0x0010 + +#define SW_SHOW 5 + +#define SC_MINIMIZE 0xF020 +#define SC_MAXIMIZE 0xF030 +#define SC_RESTORE 0xF120 + +#define GCL_HICONSM (-34) +#define GCL_HICON (-14) + +#define MB_OK 0 +#define MB_OKCANCEL 1 +#define MB_TASKMODAL 0x2000L + +#define IDOK 1 +#define IDCANCEL 2 + +#define VK_SHIFT 0x10 +#define VK_CONTROL 0x11 +#define VK_MENU 0x12 + +#define RT_RCDATA 10 + +#define IMAGE_BITMAP 0 + +#define LR_LOADFROMFILE 0x0010 + +#define DIB_RGB_COLORS 0 + +#define MAX_PATH 1024 +#define _MAX_PATH MAX_PATH +#define _MAX_DRIVE 3 +#define _MAX_DIR 256 +#define _MAX_FNAME 256 +#define _MAX_EXT 256 + +#define GMEM_FIXED 0x0 +#define GMEM_ZEROINIT 0x40 +#define GPTR (GMEM_FIXED | GMEM_ZEROINIT) + +#define SPI_GETWORKAREA 48 + +#define SM_CXDOUBLECLK 36 +#define SM_CYDOUBLECLK 37 + +#define COLORONCOLOR 3 + +#define SRCCOPY (DWORD)0x00CC0020 + +#define BI_RGB 0L + +#define NULLREGION 1 + +#define DT_LEFT 0x00000000 +#define DT_CENTER 0x00000001 +#define DT_RIGHT 0x00000002 +#define DT_VCENTER 0x00000004 +#define DT_WORDBREAK 0x00000010 +#define DT_SINGLELINE 0x00000020 +#define DT_CALCRECT 0x00000400 +#define DT_NOPREFIX 0x00000800 +#define DT_PATH_ELLIPSIS 0x00004000 +#define DT_END_ELLIPSIS 0x00008000 +#define DT_MODIFYSTRING 0x00010000 + +#define FW_NORMAL 400 +#define FW_BOLD 700 + +#define FF_DONTCARE (0<<4) + +#define BLACK_BRUSH 4 +#define NULL_BRUSH 5 + +#define PS_SOLID 0 +#define PS_DOT 2 + +#define TRANSPARENT 1 +#define OPAQUE 2 + +#define ANSI_CHARSET 0 +#define ANSI_VAR_FONT 12 + +#define OUT_DEFAULT_PRECIS 0 +#define CLIP_DEFAULT_PRECIS 0 + +#define PROOF_QUALITY 2 + +#define VARIABLE_PITCH 2 + +#define RGN_AND 1 +#define RGN_OR 2 +#define RGN_DIFF 4 +#define RGN_COPY 5 + +#define RDH_RECTANGLES 1 + +#define MAXLONG 0x7fffffff + +// define GUID +#include <bfc/platform/guid.h> + +#endif /* not WIN32 */ + +#include <stdio.h> +#include <stdlib.h> +//#ifdef __cplusplus +//#include <new> +//#else +//#include <new.h> +//#endif +#include <limits.h> + + +#ifdef WIN32 +#define OSPIPE HANDLE +#define OSPROCESSID int +#endif + +// Ode macro keyworkds +#define DISPATCH_ // makes a method dispatchable, automatically assigns a free ID (requires Interface) +#define DISPATCH(x) // makes a method dispatchable and specifies its ID (not duplicate check, requires Interface) +#define NODISPATCH // prevents a method from being dispatched if the class is marked for dispatching by default +#define EVENT // marks a method as being an event to which other classes can connect to receive notification (used by Script and DependentItem helpers) +#define SCRIPT // exposes a method to script interfaces (requires Script helper) +#define IN // Input parameter +#define OUT // Output parameter +#define INOUT // Input/Output parameter + diff --git a/Src/Wasabi/bfc/platform/std_string_osx.cpp b/Src/Wasabi/bfc/platform/std_string_osx.cpp new file mode 100644 index 00000000..ecfb16db --- /dev/null +++ b/Src/Wasabi/bfc/platform/std_string_osx.cpp @@ -0,0 +1,246 @@ +#include <bfc/std.h> + +// not perfect but it should work +int WCSICMP(const wchar_t *str1, const wchar_t *str2) +{ + while (*str1 && *str2) + { + if (towlower(*str1) < towlower(*str2)) + return -1; + if (towlower(*str2) < towlower(*str1)) + return 1; + str1++; + str2++; + } + + if (!*str1 && !*str2) return 0; + if (*str1) return 1; + if (*str2) return -1; + + return -1; // shouldn't get here but we'll make the compiler shut up +} + +int WCSNICMP(const wchar_t *str1, const wchar_t *str2, size_t len) +{ + while (*str1 && *str2 && len) + { + if (towlower(*str1) < towlower(*str2)) + return -1; + if (towlower(*str2) < towlower(*str1)) + return 1; + str1++; + str2++; + len--; + } + + if (!len) return 0; + if (!*str1 && !*str2) return 0; + if (*str1) return 1; + if (*str2) return -1; + + return -1; // shouldn't get here but we'll make the compiler shut up +} + + +/* these are super slow because of memory allocation, but will tide us over until apple adds wcscasecmp and family to their BSD API */ + +#if 0 // remember this if we ever decide to use -fshort-wchar +int WCSICMP(const wchar_t *str1, const wchar_t *str2) +{ + CFStringRef cfstr1 = CFStringCreateWithBytes(kCFAllocatorDefault, (UInt8 *)str1, wcslen(str1)*sizeof(wchar_t), kCFStringEncodingUTF32, false); + CFStringRef cfstr2 = CFStringCreateWithBytes(kCFAllocatorDefault, (UInt8 *)str2, wcslen(str2)*sizeof(wchar_t), kCFStringEncodingUTF32, false); + int result = CFStringCompare(cfstr1, cfstr2, kCFCompareCaseInsensitive); + CFRelease(cfstr1); + CFRelease(cfstr2); + return result; +} + +int WCSNICMP(const wchar_t *str1, const wchar_t *str2, size_t len) +{ + CFStringRef cfstr1 = CFStringCreateWithBytes(kCFAllocatorDefault, (UInt8 *)str1, wcslen(str1)*sizeof(wchar_t), kCFStringEncodingUTF32, false); + CFStringRef cfstr2 = CFStringCreateWithBytes(kCFAllocatorDefault, (UInt8 *)str2, wcslen(str2)*sizeof(wchar_t), kCFStringEncodingUTF32, false); + int result = CFStringCompareWithOptions(cfstr1, cfstr2, CFRangeMake(0, len), kCFCompareCaseInsensitive); + CFRelease(cfstr1); + CFRelease(cfstr2); + return result; +} +#endif + +int WCSICOLL(const wchar_t *str1, const wchar_t *str2) +{ + CFStringRef cfstr1 = CFStringCreateWithBytes(kCFAllocatorDefault, (UInt8 *)str1, wcslen(str1)*sizeof(wchar_t), kCFStringEncodingUTF32, false); + CFStringRef cfstr2 = CFStringCreateWithBytes(kCFAllocatorDefault, (UInt8 *)str2, wcslen(str2)*sizeof(wchar_t), kCFStringEncodingUTF32, false); + int result = CFStringCompare(cfstr1, cfstr2, kCFCompareCaseInsensitive|kCFCompareNonliteral); + CFRelease(cfstr1); + CFRelease(cfstr2); + return result; +} + +bool WCSIPREFIX(const wchar_t *str1, const wchar_t *prefix) +{ + CFStringRef cfstr1 = CFStringCreateWithBytes(kCFAllocatorDefault, (UInt8 *)str1, wcslen(str1)*sizeof(wchar_t), kCFStringEncodingUTF32, false); + CFStringRef cfstr2 = CFStringCreateWithBytes(kCFAllocatorDefault, (UInt8 *)prefix, wcslen(prefix)*sizeof(wchar_t), kCFStringEncodingUTF32, false); + bool result = CFStringHasPrefix(cfstr1, cfstr2); + CFRelease(cfstr1); + CFRelease(cfstr2); + return result; +} + +wchar_t *DO_WCSDUP(const wchar_t *ptr EXTRA_INFO) +{ + if (ptr == NULL) return NULL; + int size = wcslen(ptr); + wchar_t *ret = (wchar_t *)MALLOC((size + 1) * sizeof(wchar_t)); + if (ret != NULL) + { + WCSCPYN(ret, ptr, size+1); + } + return ret; +} + +void WCSCPYN(wchar_t *dest, const wchar_t *src, int maxchar) +{ + ASSERT(dest != NULL); + ASSERT(src != NULL); + wcsncpy(dest, src, maxchar-1); // TODO: switch to a less brain dead function + dest[maxchar-1]=0; +} + +void STRTOUPPER(char *str) +{ +if (str) +{ + while (*str) + { + *str = toupper(*str); + } +} +} +void STRTOLOWER(char *str) +{ + if (str) + { + while (*str) + { + *str = towlower(*str); + } + } +} + +COMEXP void WCSTOUPPER(wchar_t *str) +{ + if (str) + { + while (*str) + { + *str = towupper(*str); + } + } +} + +COMEXP void WCSTOLOWER(wchar_t *str) +{ + if (str) + { + while (*str) + { + *str = towlower(*str); + } + } +} + +int WCSICMPSAFE(const wchar_t *str1, const wchar_t *str2, const wchar_t *defval1, const wchar_t *defval2) +{ + if (str1 == NULL) str1 = defval1; + if (str2 == NULL) str2 = defval2; + return WCSICMP(str1, str2); +} + +wchar_t *WCSTOK(wchar_t *str, const wchar_t *sep, wchar_t **last) +{ + return wcstok(str, sep, last); +} + +int WCSCASEEQLSAFE(const wchar_t *str1, const wchar_t *str2, const wchar_t *defval1, const wchar_t *defval2) +{ + return !WCSICMPSAFE(str1, str2, defval1, defval2); +} + +int STRLEN(const char *str) +{ + ASSERT(str != NULL); + return strlen(str); +} + +bool ISALPHA(wchar_t alpha) +{ + return iswalpha(alpha); +} + +bool ISDIGIT(wchar_t digit) +{ + return iswdigit(digit); +} + +bool ISSPACE(wchar_t space) +{ + return iswspace(space); +} + +bool ISPUNCT(wchar_t punct) +{ + return iswpunct(punct); +} + +int STRCMP(const char *str1, const char *str2) +{ + ASSERT(str1!=NULL); + ASSERT(str2!=NULL); + return strcmp(str1, str2); +} + +int STRCMPSAFE(const char *str1, const char *str2, const char *defval1, const char *defval2) +{ + if (str1 == NULL) str1 = defval1; + if (str2 == NULL) str2 = defval2; + return STRCMP(str1, str2); +} + +void STRNCPY(char *dest, const char *src, int maxchar) +{ + ASSERT(dest != NULL); + ASSERT(src != NULL); + strncpy(dest, src, maxchar); + //INLINE +} + +int STRICMPSAFE(const char *str1, const char *str2, const char *defval1, const char *defval2) +{ + if (str1 == NULL) str1 = defval1; + if (str2 == NULL) str2 = defval2; + return STRICMP(str1, str2); +} + +int STRICMP(const char *str1, const char *str2) +{ + ASSERT(str1!=NULL); + ASSERT(str2!=NULL); + return strcasecmp(str1, str2); +} + +void STRCPY(char *dest, const char *src) +{ + ASSERT(dest != NULL); + ASSERT(src != NULL); + ASSERT(dest != src); + strcpy(dest, src); + //INLINE +} + +char *STRSTR(const char *str1, const char *str2) +{ + ASSERT(str1!=NULL); + ASSERT(str2!=NULL); + ASSERT(str1 != str2); + return strstr(str1, str2); +} diff --git a/Src/Wasabi/bfc/platform/strcmp.h b/Src/Wasabi/bfc/platform/strcmp.h new file mode 100644 index 00000000..f76d47af --- /dev/null +++ b/Src/Wasabi/bfc/platform/strcmp.h @@ -0,0 +1,15 @@ +#ifndef NULLSOFT_BFC_STRCMP_H +#define NULLSOFT_BFC_STRCMP_H + +#ifdef _WIN32 +#include <shlwapi.h> +#define strcasestr StrStrIA +#endif + +#ifdef __APPLE__ +#include <string.h> +#define _strnicmp strncasecmp +#define _stricmp strcasecmp +#endif + +#endif
\ No newline at end of file diff --git a/Src/Wasabi/bfc/platform/types.h b/Src/Wasabi/bfc/platform/types.h new file mode 100644 index 00000000..ff83ce04 --- /dev/null +++ b/Src/Wasabi/bfc/platform/types.h @@ -0,0 +1,2 @@ +#include <bfc/platform/platform.h> +#include "../replicant/foundation/types.h"
\ No newline at end of file diff --git a/Src/Wasabi/bfc/platform/win32.h b/Src/Wasabi/bfc/platform/win32.h new file mode 100644 index 00000000..73d8872e --- /dev/null +++ b/Src/Wasabi/bfc/platform/win32.h @@ -0,0 +1,34 @@ +#pragma once + +#include <stdio.h> + +#ifndef WIN32 +#error this file is only for win32 +#endif + + +// this should be the *only* place windows.h gets included! +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#include <windows.h> +#ifndef _WIN32_WCE +#include <io.h> +#endif + +#if defined(_MSC_VER) // msvc +# define WASABIDLLEXPORT __declspec(dllexport) +# if _MSC_VER >= 1100 +# define NOVTABLE __declspec(novtable) +# endif +#endif + + + +#define OSPIPE HANDLE + + +typedef WCHAR OSFNCHAR; +typedef LPWSTR OSFNSTR; +typedef LPCWSTR OSFNCSTR; + |