diff win/dw.c @ 1887:09860ba329a4

Divided thread initialization and deinitialization into separate exported functions so they can be accessed from language bindings.
author bsmith@81767d24-ef19-dc11-ae90-00e081727c95
date Mon, 09 Sep 2013 19:18:36 +0000
parents f7d408a47752
children cb5f9aa9aebb
line wrap: on
line diff
--- a/win/dw.c	Thu Sep 05 17:58:40 2013 +0000
+++ b/win/dw.c	Mon Sep 09 19:18:36 2013 +0000
@@ -3761,27 +3761,6 @@
 }
 #endif
 
-/* Initialize thread local values to the defaults */
-void _init_thread(void)
-{
-    COLORREF foreground = RGB(128,128,128);
-    COLORREF background = DW_RGB_TRANSPARENT;
-#ifdef GDIPLUS
-    ARGB gpfore = MAKEARGB(255, 128, 128, 128);
-    GpBrush *brush;
-    GpPen *pen;
-    
-    GdipCreatePen1(gpfore, 1.0, UnitPixel, &pen);
-    TlsSetValue(_gpPen, (LPVOID)pen);
-    GdipCreateSolidFill(gpfore, &brush);
-    TlsSetValue(_gpBrush, brush);
-#endif    
-    TlsSetValue(_foreground, DW_UINT_TO_POINTER(foreground));
-    TlsSetValue(_background, DW_UINT_TO_POINTER(background));
-    TlsSetValue(_hPen, CreatePen(PS_SOLID, 1, foreground));
-    TlsSetValue(_hBrush, CreateSolidBrush(foreground));
-}
-
 /*
  * Initializes the Dynamic Windows engine.
  * Parameters:
@@ -3978,8 +3957,8 @@
    GdiplusStartup(&gdiplusToken, &si, NULL);
 #endif
    
-   /* GDI+ Needs to be initialized before calling _init_thread(); */
-   _init_thread();
+   /* GDI+ Needs to be initialized before calling _dw_init_thread(); */
+   _dw_init_thread();
 
    if((huxtheme = LoadLibrary(TEXT("uxtheme"))))
       _SetWindowTheme = (HRESULT (WINAPI *)(HWND, LPCWSTR, LPCWSTR ))GetProcAddress(huxtheme, "SetWindowTheme");
@@ -11385,13 +11364,40 @@
    return 0;
 }
 
-/*
- * Encapsulate thread creation on Win32.
- */
-void _dwthreadstart(void *data)
-{
-   void (* threadfunc)(void *) = NULL;
-   void **tmp = (void **)data;
+/* 
+ * Generally an internal function called from a newly created
+ * thread to setup the Dynamic Windows environment for the thread.
+ * However it is exported so language bindings can call it when
+ * they create threads that require access to Dynamic Windows.
+ */
+void API _dw_init_thread(void)
+{
+    COLORREF foreground = RGB(128,128,128);
+    COLORREF background = DW_RGB_TRANSPARENT;
+#ifdef GDIPLUS
+    ARGB gpfore = MAKEARGB(255, 128, 128, 128);
+    GpBrush *brush;
+    GpPen *pen;
+    
+    GdipCreatePen1(gpfore, 1.0, UnitPixel, &pen);
+    TlsSetValue(_gpPen, (LPVOID)pen);
+    GdipCreateSolidFill(gpfore, &brush);
+    TlsSetValue(_gpBrush, brush);
+#endif    
+    TlsSetValue(_foreground, DW_UINT_TO_POINTER(foreground));
+    TlsSetValue(_background, DW_UINT_TO_POINTER(background));
+    TlsSetValue(_hPen, CreatePen(PS_SOLID, 1, foreground));
+    TlsSetValue(_hBrush, CreateSolidBrush(foreground));
+}
+
+/* 
+ * Generally an internal function called from a terminating
+ * thread to cleanup the Dynamic Windows environment for the thread.
+ * However it is exported so language bindings can call it when
+ * they exit threads that require access to Dynamic Windows.
+ */
+void API _dw_deinit_thread(void)
+{
    HPEN hPen;
    HBRUSH hBrush;
 #ifdef GDIPLUS
@@ -11399,12 +11405,6 @@
    GpPen *pen;
 #endif       
 
-   _init_thread();
-
-   threadfunc = (void (*)(void *))tmp[0];
-   threadfunc(tmp[1]);
-
-   free(tmp);
    if((hPen = TlsGetValue(_hPen)))
        DeleteObject(hPen);
    if((hBrush = TlsGetValue(_hBrush)))
@@ -11418,6 +11418,23 @@
 }
 
 /*
+ * Encapsulate thread creation on Win32.
+ */
+void _dwthreadstart(void *data)
+{
+   void (* threadfunc)(void *) = NULL;
+   void **tmp = (void **)data;
+
+   _dw_init_thread();
+
+   threadfunc = (void (*)(void *))tmp[0];
+   threadfunc(tmp[1]);
+
+   free(tmp);
+   _dw_deinit_thread();
+}
+
+/*
  * Creates a new thread with a starting point of func.
  * Parameters:
  *       func: Function which will be run in the new thread.