From 4862bc46f17adf2fa55f568363f8abdfecdbc068 Mon Sep 17 00:00:00 2001 From: Vincent Torri Date: Thu, 27 Nov 2008 19:30:39 +0000 Subject: [PATCH] * Patch by Dmitriy Mazovka - add shape support in ecore_win32 - add drag'n drop support in ecore_win32 (reworked) * remove strange character (ecore_evas_win32.c) * include Eina.h before defining EAPI (Ecore_Data.h) * add -lole32 as lib for DnD, minor thing (configure.ac) next steps will be the new direct3d engine, and full support of DnD, shapes and fullscreen for the directdraw engine and in ecore_evas. SVN revision: 37831 --- legacy/ecore/configure.ac | 9 +- legacy/ecore/src/lib/ecore/Ecore_Data.h | 4 +- .../src/lib/ecore_evas/ecore_evas_win32.c | 2 +- .../ecore/src/lib/ecore_win32/Ecore_Win32.h | 34 ++++++ legacy/ecore/src/lib/ecore_win32/Makefile.am | 12 +- .../ecore/src/lib/ecore_win32/ecore_win32.c | 18 +++ .../src/lib/ecore_win32/ecore_win32_private.h | 28 +++++ .../src/lib/ecore_win32/ecore_win32_window.c | 104 +++++++++++++++++- 8 files changed, 198 insertions(+), 13 deletions(-) diff --git a/legacy/ecore/configure.ac b/legacy/ecore/configure.ac index b77632d77e..ea3b0077ba 100644 --- a/legacy/ecore/configure.ac +++ b/legacy/ecore/configure.ac @@ -101,13 +101,14 @@ case "$host_os" in fi fi lt_enable_auto_import="-Wl,--enable-auto-import" + dlopen_libs=-ldl ;; *) AC_CHECK_HEADERS([dlfcn.h features.h langinfo.h locale.h netdb.h netinet/in.h sys/time.h sys/mman.h signal.h sys/resource.h]) AC_CHECK_LIB(dl, dlopen, dlopen_libs=-ldl) - AC_SUBST(dlopen_libs) ;; esac +AC_SUBST(dlopen_libs) AC_SUBST(WIN32_CPPFLAGS) AC_SUBST(WIN32_CFLAGS) AC_SUBST(WIN32_LIBS) @@ -578,7 +579,7 @@ fi dnl ecore_win32 ECORE_CHECK_MODULE([Win32], [no], [yes], - [ecore_win32_libs="-lgdi32"]) + [ecore_win32_libs="-lole32 -lgdi32"]) AC_SUBST(ecore_win32_libs) want_ecore_evas_software_ddraw="yes" @@ -587,7 +588,7 @@ ECORE_EVAS_CHECK_MODULE([software-ddraw], [Software DirectDraw], $have_ecore_win32) -want_ecore_evas_direct3d="yes" +want_ecore_evas_direct3d="auto" ECORE_EVAS_CHECK_MODULE([direct3d], [$want_ecore_evas_direct3d], [Direct3d], @@ -599,7 +600,7 @@ ECORE_EVAS_CHECK_MODULE([opengl-glew], [Glew OpenGL], $have_ecore_win32) -want_ecore_evas_software_16_ddraw="yes" +want_ecore_evas_software_16_ddraw="auto" ECORE_EVAS_CHECK_MODULE([software-16-ddraw], [$want_ecore_evas_software_16_ddraw], [16 bpp Software DirectDraw], diff --git a/legacy/ecore/src/lib/ecore/Ecore_Data.h b/legacy/ecore/src/lib/ecore/Ecore_Data.h index 3d4b51266f..2a8331e647 100644 --- a/legacy/ecore/src/lib/ecore/Ecore_Data.h +++ b/legacy/ecore/src/lib/ecore/Ecore_Data.h @@ -1,6 +1,8 @@ #ifndef _ECORE_DATA_H # define _ECORE_DATA_H +#include + #ifdef EAPI # undef EAPI #endif @@ -30,8 +32,6 @@ /* we need this for size_t */ #include -#include - /** * @file Ecore_Data.h * @brief Contains threading, list, hash, debugging and tree functions. diff --git a/legacy/ecore/src/lib/ecore_evas/ecore_evas_win32.c b/legacy/ecore/src/lib/ecore_evas/ecore_evas_win32.c index 80e4db6999..381c23cd51 100644 --- a/legacy/ecore/src/lib/ecore_evas/ecore_evas_win32.c +++ b/legacy/ecore/src/lib/ecore_evas/ecore_evas_win32.c @@ -67,7 +67,7 @@ _ecore_evas_win32_render(Ecore_Evas *ee) Eina_List *updates; #ifdef BUILD_ECORE_EVAS_BUFFER Eina_List *ll; - Ecore_Evas *ee2;² + Ecore_Evas *ee2; #endif #ifdef BUILD_ECORE_EVAS_BUFFER diff --git a/legacy/ecore/src/lib/ecore_win32/Ecore_Win32.h b/legacy/ecore/src/lib/ecore_win32/Ecore_Win32.h index 6c9e4a0097..2e97dacc70 100644 --- a/legacy/ecore/src/lib/ecore_win32/Ecore_Win32.h +++ b/legacy/ecore/src/lib/ecore_win32/Ecore_Win32.h @@ -33,6 +33,11 @@ #endif /* ! _WIN32 */ +#ifdef __cplusplus +extern "C" { +#endif + + typedef void Ecore_Win32_Window; typedef void Ecore_Win32_Cursor; @@ -281,6 +286,14 @@ struct _Ecore_Win32_Event_Window_Delete_Request double time; }; +#define ECORE_WIN32_DND_EVENT_DRAG_ENTER 1 +#define ECORE_WIN32_DND_EVENT_DRAG_OVER 2 +#define ECORE_WIN32_DND_EVENT_DRAG_LEAVE 3 +#define ECORE_WIN32_DND_EVENT_DROP 4 + + +typedef int (*Ecore_Win32_Dnd_DropTarget_Callback)(void *window, int event, int pt_x, int pt_y, void *data, int size); + EAPI extern int ECORE_WIN32_EVENT_KEY_DOWN; EAPI extern int ECORE_WIN32_EVENT_KEY_UP; EAPI extern int ECORE_WIN32_EVENT_MOUSE_BUTTON_DOWN; @@ -404,6 +417,11 @@ EAPI void ecore_win32_window_borderless_set(Ecore_Win32_Window *window, EAPI void ecore_win32_window_fullscreen_set(Ecore_Win32_Window *window, int on); +EAPI void ecore_win32_window_shape_set(Ecore_Win32_Window *window, + unsigned short width, + unsigned short height, + unsigned char *mask); + EAPI void ecore_win32_window_cursor_set(Ecore_Win32_Window *window, Ecore_Win32_Cursor *cursor); @@ -434,4 +452,20 @@ EAPI Ecore_Win32_Cursor *ecore_win32_cursor_shape_get(Ecore_Win32_Cursor_Shape s EAPI int ecore_win32_cursor_size_get(void); + +/* Drag and drop */ +EAPI int ecore_win32_dnd_init(); +EAPI int ecore_win32_dnd_shutdown(); +EAPI int ecore_win32_dnd_begin(const char *data, + int size); +EAPI int ecore_win32_dnd_register_drop_target(Ecore_Win32_Window *window, + Ecore_Win32_Dnd_DropTarget_Callback callback); +EAPI void ecore_win32_dnd_unregister_drop_target(Ecore_Win32_Window *window); + + +#ifdef __cplusplus +} +#endif + + #endif /* __ECORE_WIN32_H__ */ diff --git a/legacy/ecore/src/lib/ecore_win32/Makefile.am b/legacy/ecore/src/lib/ecore_win32/Makefile.am index e2d2225527..f8ccc95037 100644 --- a/legacy/ecore/src/lib/ecore_win32/Makefile.am +++ b/legacy/ecore/src/lib/ecore_win32/Makefile.am @@ -16,6 +16,11 @@ Ecore_Win32.h libecore_win32_la_SOURCES = \ ecore_win32.c \ ecore_win32_cursor.c \ +ecore_win32_dnd.c \ +ecore_win32_dnd_enumformatetc.cpp \ +ecore_win32_dnd_data_object.cpp \ +ecore_win32_dnd_drop_source.cpp \ +ecore_win32_dnd_drop_target.cpp \ ecore_win32_event.c \ ecore_win32_window.c @@ -29,4 +34,9 @@ libecore_win32_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -version-info endif -EXTRA_DIST = ecore_win32_private.h +EXTRA_DIST = \ +ecore_win32_private.h \ +ecore_win32_dnd_enumformatetc.h \ +ecore_win32_dnd_data_object.h \ +ecore_win32_dnd_drop_source.h \ +ecore_win32_dnd_drop_target.h diff --git a/legacy/ecore/src/lib/ecore_win32/ecore_win32.c b/legacy/ecore/src/lib/ecore_win32/ecore_win32.c index 7ea27d37a4..b5f0cfc396 100644 --- a/legacy/ecore/src/lib/ecore_win32/ecore_win32.c +++ b/legacy/ecore/src/lib/ecore_win32/ecore_win32.c @@ -19,6 +19,17 @@ #include "ecore_win32_private.h" +/* OLE IID for Drag'n Drop */ + +# define INITGUID +# include +DEFINE_OLEGUID(IID_IEnumFORMATETC, 0x00000103L, 0, 0); +DEFINE_OLEGUID(IID_IDataObject, 0x0000010EL, 0, 0); +DEFINE_OLEGUID(IID_IDropSource, 0x00000121L, 0, 0); +DEFINE_OLEGUID(IID_IDropTarget, 0x00000122L, 0, 0); +DEFINE_OLEGUID(IID_IUnknown, 0x00000000L, 0, 0); + + /***** Global declarations *****/ HINSTANCE _ecore_win32_instance = NULL; @@ -93,6 +104,12 @@ ecore_win32_init() return 0; } + if (!ecore_win32_dnd_init()) + { + FreeLibrary(_ecore_win32_instance); + return 0; + } + if (!ECORE_WIN32_EVENT_KEY_DOWN) { ECORE_WIN32_EVENT_KEY_DOWN = ecore_event_type_new(); @@ -127,6 +144,7 @@ ecore_win32_shutdown() if (_ecore_win32_init_count > 0) return _ecore_win32_init_count; if (!_ecore_win32_instance) return _ecore_win32_init_count; + ecore_win32_dnd_shutdown(); UnregisterClass(ECORE_WIN32_WINDOW_CLASS, _ecore_win32_instance); FreeLibrary(_ecore_win32_instance); _ecore_win32_instance = NULL; diff --git a/legacy/ecore/src/lib/ecore_win32/ecore_win32_private.h b/legacy/ecore/src/lib/ecore_win32/ecore_win32_private.h index 93b6fa70ec..7a55f4e8ba 100644 --- a/legacy/ecore/src/lib/ecore_win32/ecore_win32_private.h +++ b/legacy/ecore/src/lib/ecore_win32/ecore_win32_private.h @@ -6,6 +6,11 @@ #define __ECORE_WIN32_PRIVATE_H__ +#ifdef __cplusplus +extern "C" { +#endif + + #define ECORE_WIN32_WINDOW_CLASS "Ecore_Win32_Window_Class" @@ -68,6 +73,16 @@ struct _Ecore_Win32_Window unsigned int borderless : 1; unsigned int iconified : 1; unsigned int fullscreen : 1; + + struct { + unsigned short width; + unsigned short height; + unsigned char *mask; + unsigned int enabled : 1; + unsigned int layered : 1; + } shape; + + void *dnd_drop_target; }; @@ -97,5 +112,18 @@ void _ecore_win32_event_handle_configure_notify(Ecore_Win32_Callback_Data *msg) void _ecore_win32_event_handle_resize(Ecore_Win32_Callback_Data *msg); void _ecore_win32_event_handle_delete_request(Ecore_Win32_Callback_Data *msg); +void *_ecore_win32_dnd_data_object_new(void *fmtetc, void *stgmeds, int count); +void _ecore_win32_dnd_data_object_free(void *data_object); +void *_ecore_win32_dnd_drop_source_new(); +void _ecore_win32_dnd_drop_source_free(void *drop_source); +void *_ecore_win32_dnd_register_drop_window(HWND hwnd, + Ecore_Win32_Dnd_DropTarget_Callback callback, void *ptr); +void _ecore_win32_dnd_unregister_drop_window(HWND hwnd, void *drop_target); + + +#ifdef __cplusplus +} +#endif + #endif /* __ECORE_WIN32_PRIVATE_H__ */ diff --git a/legacy/ecore/src/lib/ecore_win32/ecore_win32_window.c b/legacy/ecore/src/lib/ecore_win32/ecore_win32_window.c index a3129ee83c..0c7bc43512 100644 --- a/legacy/ecore/src/lib/ecore_win32/ecore_win32_window.c +++ b/legacy/ecore/src/lib/ecore_win32/ecore_win32_window.c @@ -9,6 +9,8 @@ #include #include /* for printf */ +#define _WIN32_WINNT 0x0500 // For WS_EX_LAYERED + #define WIN32_LEAN_AND_MEAN #include #undef WIN32_LEAN_AND_MEAN @@ -69,8 +71,13 @@ ecore_win32_window_override_new(Ecore_Win32_Window *parent, void ecore_win32_window_del(Ecore_Win32_Window *window) { + struct _Ecore_Win32_Window *wnd = window; + if (!window) return; + if (wnd->shape.mask != NULL) + free(wnd->shape.mask); + DestroyWindow(((struct _Ecore_Win32_Window *)window)->window); free(window); printf ("ecore_win32_window_del\n"); @@ -423,7 +430,90 @@ ecore_win32_window_size_step_get(Ecore_Win32_Window *window, if (step_height) *step_height = w->step_height; } -/* TODO: ecore_win32_window_shaped_set */ +void +ecore_win32_window_shape_set(Ecore_Win32_Window *window, + unsigned short width, + unsigned short height, + unsigned char *mask) +{ + struct _Ecore_Win32_Window *wnd; + HRGN rgn; + int x; + int y; + OSVERSIONINFO version_info; + + if (window == NULL) + return; + + wnd = (struct _Ecore_Win32_Window *)window; + + if (mask == NULL) + { + wnd->shape.enabled = 0; + if (wnd->shape.layered != 0) + { + wnd->shape.layered = 0; +#if defined(WS_EX_LAYERED) + SetWindowLong(wnd->window, GWL_EXSTYLE, + GetWindowLong(wnd->window, GWL_EXSTYLE) & (~WS_EX_LAYERED)); + RedrawWindow(wnd->window, NULL, NULL, + RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN); +#endif + } + else + SetWindowRgn(wnd->window, NULL, TRUE); + return; + } + + if (width == 0 || height == 0) + return; + + wnd->shape.enabled = 1; + + if (width != wnd->shape.width || height != wnd->shape.height) + { + wnd->shape.width = width; + wnd->shape.height = height; + if (wnd->shape.mask != NULL) + { + free(wnd->shape.mask); + wnd->shape.mask = NULL; + } + wnd->shape.mask = malloc(width * height); + } + memcpy(wnd->shape.mask, mask, width * height); + + wnd->shape.layered = 0; + +#if defined(WS_EX_LAYERED) + version_info.dwOSVersionInfoSize = sizeof(version_info); + if (GetVersionEx(&version_info) == TRUE && version_info.dwMajorVersion == 5) + { + SetWindowLong(wnd->window, GWL_EXSTYLE, + GetWindowLong(wnd->window, GWL_EXSTYLE) | WS_EX_LAYERED); + wnd->shape.layered = 1; + return; + } +#endif + + rgn = CreateRectRgn(0, 0, 0, 0); + for (y = 0; y < height; y++) + { + HRGN rgnLine = CreateRectRgn(0, 0, 0, 0); + for (x = 0; x < width; x++) + { + if (mask[y * width + x] > 0) + { + HRGN rgnDot = CreateRectRgn(x, y, x + 1, y + 1); + CombineRgn(rgnLine, rgnLine, rgnDot, RGN_OR); + DeleteObject(rgnDot); + } + } + CombineRgn(rgn, rgn, rgnLine, RGN_OR); + DeleteObject(rgnLine); + } + SetWindowRgn(wnd->window, rgn, TRUE); +} void ecore_win32_window_show(Ecore_Win32_Window *window) @@ -579,19 +669,23 @@ ecore_win32_window_fullscreen_set(Ecore_Win32_Window *window, if (!SetWindowLong(w, GWL_STYLE, (ew->style & ~WS_OVERLAPPEDWINDOW) | WS_POPUP)) return; - SetWindowPos(w, HWND_TOP, 0, 0, width, height, - SWP_NOCOPYBITS | SWP_SHOWWINDOW); + if (!SetWindowLong(w, GWL_EXSTYLE, WS_EX_TOPMOST)) + return; + SetWindowPos(w, HWND_TOPMOST, 0, 0, width, height, + SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED); } else { - if (!SetWindowLong(w, GWL_STYLE, ew->style)) + if (!SetWindowLong(w, GWL_STYLE, (ew->style & ~WS_POPUP) | WS_OVERLAPPEDWINDOW) + return; + if (!SetWindowLong(w, GWL_EXSTYLE, 0)) return; SetWindowPos(w, HWND_NOTOPMOST, ew->rect.left, ew->rect.top, ew->rect.right - ew->rect.left, ew->rect.bottom - ew->rect.top, - SWP_NOCOPYBITS | SWP_SHOWWINDOW); + SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED); } }