From 4731d0ccca76a01ad1401b71b70c9e6f1e372050 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 13 Jun 2012 14:48:27 +0000 Subject: first attempt at Cygwin notifier adaptation --- unix/tclUnixNotfy.c | 119 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) diff --git a/unix/tclUnixNotfy.c b/unix/tclUnixNotfy.c index 0af7207..aff51b1 100644 --- a/unix/tclUnixNotfy.c +++ b/unix/tclUnixNotfy.c @@ -98,6 +98,12 @@ typedef struct ThreadSpecificData { * from these pointers. You must hold the * notifierMutex lock before accessing these * fields. */ +#ifdef __CYGWIN__ + void *event; /* Any other thread alerts a notifier + * that an event is ready to be processed + * by sending this event. */ + void *hwnd; /* Messaging window. */ +#endif /* __CYGWIN__ */ Tcl_Condition waitCV; /* Any other thread alerts a notifier * that an event is ready to be processed * by signaling this condition variable. */ @@ -205,6 +211,48 @@ static int FileHandlerEventProc _ANSI_ARGS_((Tcl_Event *evPtr, *---------------------------------------------------------------------- */ +#if defined(TCL_THREADS) && defined(__CYGWIN__) + +typedef struct { + void *hwnd; + unsigned int *message; + int wParam; + int lParam; + int time; + int x; + int y; +} MSG; + +typedef struct { + unsigned int style; + void *lpfnWndProc; + int cbClsExtra; + int cbWndExtra; + void *hInstance; + void *hIcon; + void *hCursor; + void *hbrBackground; + void *lpszMenuName; + void *lpszClassName; +} WNDCLASS; + +extern unsigned char __stdcall PeekMessageW(MSG *, void *, int, int, int); +extern unsigned char __stdcall GetMessageW(MSG *, void *, int, int); +extern unsigned char __stdcall TranslateMessage(const MSG *); +extern int __stdcall DispatchMessageW(const MSG *); +extern void __stdcall PostQuitMessage(int); +extern void * __stdcall CreateWindowExW(void *, void *, void *, DWORD, int, int, int, int, void *, void *, void *, void *); +extern unsigned char __stdcall DestroyWindow(void *); +extern unsigned char __stdcall PostMessageW(void *, unsigned int, void *, void *); +extern void *__stdcall RegisterClassW(const WNDCLASS *); +extern DWORD __stdcall DefWindowProcW(void *, int, void *, void *); +extern void *__stdcall CreateEventW(void *, unsigned char, unsigned char, void *); +extern void __stdcall CloseHandle(void *); +extern void __stdcall MsgWaitForMultipleObjects(DWORD, void *, unsigned char, DWORD, DWORD); +extern unsigned char __stdcall ResetEvent(void *); + +#endif + ClientData Tcl_InitNotifier() { @@ -304,6 +352,9 @@ Tcl_FinalizeNotifier(clientData) * Clean up any synchronization objects in the thread local storage. */ +#ifdef __CYGWIN__ + CloseHandle(tsdPtr->event); +#endif /* __CYGWIN__ */ Tcl_ConditionFinalize(&(tsdPtr->waitCV)); Tcl_MutexUnlock(¬ifierMutex); @@ -635,6 +686,31 @@ FileHandlerEventProc(evPtr, flags) return 1; } +#if defined(TCL_THREADS) && defined(__CYGWIN__) + +static DWORD __stdcall +NotifierProc( + void *hwnd, + unsigned int message, + void *wParam, + void *lParam) +{ + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); + + if (message != 1024) { + return DefWindowProcW(hwnd, message, wParam, lParam); + } + + /* + * Process all of the runnable events. + */ + + tsdPtr->eventReady = 1; + Tcl_ServiceAll(); + return 0; +} +#endif /* __CYGWIN__ */ + /* *---------------------------------------------------------------------- * @@ -663,6 +739,9 @@ Tcl_WaitForEvent(timePtr) int mask; #ifdef TCL_THREADS int waitForFiles; +# ifdef __CYGWIN__ + MSG msg; +# endif #else /* Impl. notes: timeout & timeoutPtr are used if, and only if * threads are not enabled. They are the arguments for the regular @@ -738,6 +817,31 @@ Tcl_WaitForEvent(timePtr) tsdPtr->pollState = 0; } +#ifdef __CYGWIN__ + if (!tsdPtr->hwnd) { + WNDCLASS class; + + class.style = 0; + class.cbClsExtra = 0; + class.cbWndExtra = 0; + class.hInstance = TclWinGetTclInstance(); + class.hbrBackground = NULL; + class.lpszMenuName = NULL; + class.lpszClassName = L"TclNotifier"; + class.lpfnWndProc = NotifierProc; + class.hIcon = NULL; + class.hCursor = NULL; + + if (!RegisterClassW(&class)) { + Tcl_Panic("Unable to register TclNotifier window class"); + } + tsdPtr->hwnd = CreateWindowExW(NULL, class.lpszClassName, class.lpszClassName, + 0, 0, 0, 0, 0, NULL, NULL, TclWinGetTclInstance(), NULL); + tsdPtr->event = CreateEventW(NULL, 1 /* manual */, + 0 /* !signaled */, NULL); + } + +#endif if (waitForFiles) { /* * Add the ThreadSpecificData structure of this thread to the list @@ -766,6 +870,21 @@ Tcl_WaitForEvent(timePtr) } tsdPtr->eventReady = 0; + while (PeekMessageW(&msg, NULL, 0, 0, 0)) { + /* + * Retrieve and dispatch the message. + */ + DWORD result = GetMessageW(&msg, NULL, 0, 0); + if (result == 0) { + PostQuitMessage(msg.wParam); + /* What to do here? */ + } else if (result != (DWORD)-1) { + TranslateMessage(&msg); + DispatchMessageW(&msg); + } + } + ResetEvent(tsdPtr->event); + if (waitForFiles && tsdPtr->onList) { /* * Remove the ThreadSpecificData structure of this thread from the -- cgit v0.12 From 39b1bc8eefca71fda1f8bebf08eee86cff6f5aec Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 22 Jun 2012 12:07:28 +0000 Subject: Cygwin network pathname support --- generic/tclFileName.c | 34 ++++++++++++++++++++++++++++------ tests/fileName.test | 6 +++--- 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/generic/tclFileName.c b/generic/tclFileName.c index 4c57256..de91d81 100644 --- a/generic/tclFileName.c +++ b/generic/tclFileName.c @@ -414,9 +414,17 @@ TclpGetNativePathType( } #endif if (path[0] == '/') { +#ifdef __CYGWIN__ + /* + * Check for Cygwin // network path prefix + */ + if (path[1] == '/') { + path++; + } +#endif if (driveNameLengthPtr != NULL) { /* - * We need this addition in case the QNX code was used. + * We need this addition in case the QNX or Cygwin code was used. */ *driveNameLengthPtr = (1 + path - origPath); @@ -643,11 +651,20 @@ SplitUnixPath( } #endif - if (path[0] == '/') { - Tcl_ListObjAppendElement(NULL, result, Tcl_NewStringObj("/",1)); - p = path+1; - } else { - p = path; + p = path; + if (*p == '/') { + Tcl_Obj *rootElt = Tcl_NewStringObj("/", 1); + p++; +#ifdef __CYGWIN__ + /* + * Check for Cygwin // network path prefix + */ + if (*p == '/') { + Tcl_AppendToObj(rootElt, "/", 1); + p++; + } +#endif + Tcl_ListObjAppendElement(NULL, result, rootElt); } /* @@ -2196,6 +2213,11 @@ DoGlob( && (strchr(separators, lastChar) == NULL)) || ((length == 0) && (count > 0)))) { Tcl_DStringAppend(&append, "/", 1); +#ifdef __CYGWIN__ + if ((length == 0) && (count > 1)) { + Tcl_DStringAppend(&append, "/", 1); + } +#endif } break; } diff --git a/tests/fileName.test b/tests/fileName.test index c613068..a91f4b3 100644 --- a/tests/fileName.test +++ b/tests/fileName.test @@ -189,7 +189,7 @@ test filename-4.12 {Tcl_SplitPath: unix} {testsetplatform} { test filename-4.13 {Tcl_SplitPath: unix} {testsetplatform} { testsetplatform unix file split //foo -} {/ foo} +} "[file split //] foo" test filename-4.14 {Tcl_SplitPath: unix} {testsetplatform} { testsetplatform unix file split foo//bar @@ -429,11 +429,11 @@ test filename-7.16 {Tcl_JoinPath: unix} {testsetplatform} { test filename-7.17 {Tcl_JoinPath: unix} {testsetplatform} { testsetplatform unix file join //a b -} {/a/b} +} "[file split //]a/b" test filename-7.18 {Tcl_JoinPath: unix} {testsetplatform} { testsetplatform unix file join /// a b -} {/a/b} +} "[file split //]a/b" test filename-9.1 {Tcl_JoinPath: win} {testsetplatform} { -- cgit v0.12 From c6060d6e629b818850b39214f796339032378217 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Sun, 24 Jun 2012 06:00:34 +0000 Subject: some wrong versions --- tests/msgcat.test | 4 ++-- unix/configure | 2 +- unix/tcl.m4 | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/msgcat.test b/tests/msgcat.test index 0669810..6fe4b31 100644 --- a/tests/msgcat.test +++ b/tests/msgcat.test @@ -17,8 +17,8 @@ if {[catch {package require tcltest 2}]} { puts stderr "Skipping tests in [info script]. tcltest 2 required." return } -if {[catch {package require msgcat 1.4.2}]} { - puts stderr "Skipping tests in [info script]. No msgcat 1.4.2 found to test." +if {[catch {package require msgcat 1.4.4}]} { + puts stderr "Skipping tests in [info script]. No msgcat 1.4.4 found to test." return } diff --git a/unix/configure b/unix/configure index 36ddde6..27a7f50 100755 --- a/unix/configure +++ b/unix/configure @@ -7006,7 +7006,7 @@ echo "$as_me: error: ${CC} is not a cygwin compiler." >&2;} echo "$as_me: error: CYGWIN compile is only supported with --enable-threads" >&2;} { (exit 1); exit 1; }; } fi - if test ! -f "../win/tcldde12.dll" -a ! -f "../win/tk84.dll"; then + if test ! -f "../win/tcldde13.dll" -a ! -f "../win/tk85.dll"; then { { echo "$as_me:$LINENO: error: Please configure and make the ../win directory first." >&5 echo "$as_me: error: Please configure and make the ../win directory first." >&2;} { (exit 1); exit 1; }; } diff --git a/unix/tcl.m4 b/unix/tcl.m4 index 744d6ed..390f4ec 100644 --- a/unix/tcl.m4 +++ b/unix/tcl.m4 @@ -1263,7 +1263,7 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [ if test "x${TCL_THREADS}" = "x0"; then AC_MSG_ERROR([CYGWIN compile is only supported with --enable-threads]) fi - if test ! -f "../win/tcldde12.dll" -a ! -f "../win/tk84.dll"; then + if test ! -f "../win/tcldde13.dll" -a ! -f "../win/tk85.dll"; then AC_MSG_ERROR([Please configure and make the ../win directory first.]) fi ;; -- cgit v0.12