# HG changeset patch # User bsmith@81767d24-ef19-dc11-ae90-00e081727c95 # Date 1304574836 0 # Node ID 69f620df0c4758d9e2187392447eda61fb33aa47 # Parent 0345e37d6c86c28b4cc7354b02f705822d862d3c Step 1 in modernization of the Win32 module. Eliminate Windows NT based Windows checks, since that is all we support now. Eliminate thread limits by eliminating thread arrays and switching to using Thread Local Storage (TLS). Simplify dw_clipboard_get_text() by returning a malloc()ed buffer which now must need to be dw_free()ed. This makes this function the same as it does on OS/2 and Mac currently. diff -r 0345e37d6c86 -r 69f620df0c47 win/dw.c --- a/win/dw.c Wed May 04 00:58:53 2011 +0000 +++ b/win/dw.c Thu May 05 05:53:56 2011 +0000 @@ -61,12 +61,10 @@ /* Special flag used for internal tracking */ #define DW_CFA_RESERVED (1 << 30) -#define THREAD_LIMIT 128 -COLORREF _foreground[THREAD_LIMIT]; -COLORREF _background[THREAD_LIMIT]; -HPEN _hPen[THREAD_LIMIT]; -HBRUSH _hBrush[THREAD_LIMIT]; -char *_clipboard_contents[THREAD_LIMIT]; +DWORD _foreground; +DWORD _background; +DWORD _hPen; +DWORD _hBrush; BYTE _red[] = { 0x00, 0xbb, 0x00, 0xaa, 0x00, 0xbb, 0x00, 0xaa, 0x77, 0xff, 0x00, 0xee, 0x00, 0xff, 0x00, 0xff, 0xaa, 0x00 }; @@ -248,21 +246,6 @@ } #endif -/* This should return true for WinNT/2K/XP and false on Win9x */ -int IsWinNT(void) -{ - static int isnt = -1; - - if(isnt == -1) - { - if (GetVersion() < 0x80000000) - isnt = 1; - else - isnt = 0; - } - return isnt; -} - void DrawTransparentBitmap(HDC hdc, HDC hdcSrc, HBITMAP hBitmap, int xStart, int yStart, COLORREF cTransparentColor) { BITMAP bm; @@ -2855,10 +2838,7 @@ */ if (cinfo->buddy && !cinfo->combo) { - if (IsWinNT()) - PostMessage(cinfo->buddy, WM_USER+10, 0, 0); - else - SendMessage(cinfo->buddy, WM_USER+10, 0, 0); + PostMessage(cinfo->buddy, WM_USER+10, 0, 0); } break; case WM_USER+10: @@ -3641,6 +3621,17 @@ return windowtype; } +/* Initialize thread local values to the defaults */ +void _init_thread(void) +{ + COLORREF foreground = RGB(128,128,128); + COLORREF background = DW_RGB_TRANSPARENT; + TlsSetValue(_foreground, (LPVOID)foreground); + TlsSetValue(_background, (LPVOID)background); + TlsSetValue(_hPen, CreatePen(PS_SOLID, 1, foreground)); + TlsSetValue(_hBrush, CreateSolidBrush(foreground)); +} + /* * Initializes the Dynamic Windows engine. * Parameters: @@ -3655,6 +3646,13 @@ char *fname; HFONT oldfont; + /* Initialize our thread local storage */ + _foreground = TlsAlloc(); + _background = TlsAlloc(); + _hPen = TlsAlloc(); + _hBrush = TlsAlloc(); + _init_thread(); + icc.dwSize = sizeof(INITCOMMONCONTROLSEX); icc.dwICC = ICC_WIN95_CLASSES|ICC_DATE_CLASSES; @@ -3758,15 +3756,6 @@ dwVersion = GetVersion(); dwComctlVer = GetDllVersion(TEXT("comctl32.dll")); - for ( z = 0; z < THREAD_LIMIT; z++ ) - { - _foreground[z] = RGB(128,128,128); - _background[z] = DW_RGB_TRANSPARENT; - _hPen[z] = CreatePen(PS_SOLID, 1, _foreground[z]); - _hBrush[z] = CreateSolidBrush(_foreground[z]); - _clipboard_contents[z] = NULL; - } - /* Initialize Security for named events and memory */ InitializeSecurityDescriptor(&_dwsd, SECURITY_DESCRIPTOR_REVISION); SetSecurityDescriptorDacl(&_dwsd, TRUE, (PACL) NULL, FALSE); @@ -8388,18 +8377,18 @@ */ void API dw_color_foreground_set(unsigned long value) { - int threadid = dw_thread_id(); - - if(threadid < 0 || threadid >= THREAD_LIMIT) - threadid = 0; + HPEN hPen = TlsGetValue(_hPen); + HBRUSH hBrush = TlsGetValue(_hBrush); + COLORREF foreground; value = _internal_color(value); - - DeleteObject(_hPen[threadid]); - DeleteObject(_hBrush[threadid]); - _foreground[threadid] = RGB(DW_RED_VALUE(value), DW_GREEN_VALUE(value), DW_BLUE_VALUE(value)); - _hPen[threadid] = CreatePen(PS_SOLID, 1, _foreground[threadid]); - _hBrush[threadid] = CreateSolidBrush(_foreground[threadid]); + foreground = RGB(DW_RED_VALUE(value), DW_GREEN_VALUE(value), DW_BLUE_VALUE(value)); + + DeleteObject(hPen); + DeleteObject(hBrush); + TlsSetValue(_foreground, (LPVOID)foreground); + TlsSetValue(_hPen, CreatePen(PS_SOLID, 1, foreground)); + TlsSetValue(_hBrush, CreateSolidBrush(foreground)); } /* Sets the current background drawing color. @@ -8410,17 +8399,15 @@ */ void API dw_color_background_set(unsigned long value) { - int threadid = dw_thread_id(); - - if(threadid < 0 || threadid >= THREAD_LIMIT) - threadid = 0; + COLORREF background; value = _internal_color(value); + background = RGB(DW_RED_VALUE(value), DW_GREEN_VALUE(value), DW_BLUE_VALUE(value)); if(value == DW_RGB_TRANSPARENT) - _background[threadid] = DW_RGB_TRANSPARENT; + TlsSetValue(_background, (LPVOID)DW_RGB_TRANSPARENT); else - _background[threadid] = RGB(DW_RED_VALUE(value), DW_GREEN_VALUE(value), DW_BLUE_VALUE(value)); + TlsSetValue(_background, (LPVOID)background); } /* Allows the user to choose a color using the system's color chooser dialog. @@ -8461,10 +8448,6 @@ void API dw_draw_point(HWND handle, HPIXMAP pixmap, int x, int y) { HDC hdcPaint; - int threadid = dw_thread_id(); - - if(threadid < 0 || threadid >= THREAD_LIMIT) - threadid = 0; if(handle) hdcPaint = GetDC(handle); @@ -8473,7 +8456,7 @@ else return; - SetPixel(hdcPaint, x, y, _foreground[threadid]); + SetPixel(hdcPaint, x, y, (COLORREF)TlsGetValue(_foreground)); if(!pixmap) ReleaseDC(handle, hdcPaint); } @@ -8491,10 +8474,6 @@ { HDC hdcPaint; HPEN oldPen; - int threadid = dw_thread_id(); - - if(threadid < 0 || threadid >= THREAD_LIMIT) - threadid = 0; if(handle) hdcPaint = GetDC(handle); @@ -8503,14 +8482,14 @@ else return; - oldPen = SelectObject(hdcPaint, _hPen[threadid]); + oldPen = SelectObject(hdcPaint, TlsGetValue(_hPen)); MoveToEx(hdcPaint, x1, y1, NULL); LineTo(hdcPaint, x2, y2); SelectObject(hdcPaint, oldPen); /* For some reason Win98 (at least) fails * to draw the last pixel. So I do it myself. */ - SetPixel(hdcPaint, x2, y2, _foreground[threadid]); + SetPixel(hdcPaint, x2, y2, (COLORREF)TlsGetValue(_foreground)); if(!pixmap) ReleaseDC(handle, hdcPaint); } @@ -8531,10 +8510,6 @@ HPEN oldPen; POINT *points; int i; - int threadid = dw_thread_id(); - - if(threadid < 0 || threadid >= THREAD_LIMIT) - threadid = 0; if ( handle ) hdcPaint = GetDC( handle ); @@ -8569,8 +8544,8 @@ } } - oldBrush = SelectObject( hdcPaint, _hBrush[threadid] ); - oldPen = SelectObject( hdcPaint, _hPen[threadid] ); + oldBrush = SelectObject( hdcPaint, TlsGetValue(_hBrush) ); + oldPen = SelectObject( hdcPaint, TlsGetValue(_hPen) ); if ( fill ) Polygon( hdcPaint, points, npoints ); else @@ -8595,10 +8570,6 @@ { HDC hdcPaint; RECT Rect; - int threadid = dw_thread_id(); - - if(threadid < 0 || threadid >= THREAD_LIMIT) - threadid = 0; if(handle) hdcPaint = GetDC(handle); @@ -8609,9 +8580,9 @@ SetRect(&Rect, x, y, x + width , y + height ); if(fill) - FillRect(hdcPaint, &Rect, _hBrush[threadid]); + FillRect(hdcPaint, &Rect, TlsGetValue(_hBrush)); else - FrameRect(hdcPaint, &Rect, _hBrush[threadid]); + FrameRect(hdcPaint, &Rect, TlsGetValue(_hBrush)); if(!pixmap) ReleaseDC(handle, hdcPaint); } @@ -8629,11 +8600,8 @@ HDC hdc; int mustdelete = 0; HFONT hFont = 0, oldFont = 0; - int threadid = dw_thread_id(); ColorInfo *cinfo; - - if(threadid < 0 || threadid >= THREAD_LIMIT) - threadid = 0; + COLORREF background; if(handle) hdc = GetDC(handle); @@ -8653,15 +8621,16 @@ mustdelete = 1; } + background = (COLORREF)TlsGetValue(_background); if(hFont) oldFont = SelectObject(hdc, hFont); - SetTextColor(hdc, _foreground[threadid]); - if(_background[threadid] == DW_RGB_TRANSPARENT) + SetTextColor(hdc, (COLORREF)TlsGetValue(_foreground)); + if(background == DW_RGB_TRANSPARENT) SetBkMode(hdc, TRANSPARENT); else { SetBkMode(hdc, OPAQUE); - SetBkColor(hdc, _background[threadid]); + SetBkColor(hdc, background); } TextOut(hdc, x, y, text, strlen(text)); if(oldFont) @@ -9434,6 +9403,22 @@ } /* + * Encapsulate thread creation on Win32. + */ +void _dwthreadstart(void *data) +{ + void (* threadfunc)(void *) = NULL; + void **tmp = (void **)data; + + _init_thread(); + + threadfunc = (void (*)(void *))tmp[0]; + threadfunc(tmp[1]); + + free(tmp); +} + +/* * Creates a new thread with a starting point of func. * Parameters: * func: Function which will be run in the new thread. @@ -9445,7 +9430,12 @@ #if defined(__CYGWIN__) return 0; #else - return (DWTID)_beginthread((void(*)(void *))func, stack, data); + void **tmp = malloc(sizeof(void *) * 2); + + tmp[0] = func; + tmp[1] = data; + + return (DWTID)_beginthread((void(*)(void *))_dwthreadstart, stack, tmp); #endif } @@ -9803,38 +9793,24 @@ char *dw_clipboard_get_text() { HANDLE handle; - int threadid = dw_thread_id(); - long len; + char *tmp, *ret = NULL; if ( !OpenClipboard( NULL ) ) - return NULL; + return ret; if ( ( handle = GetClipboardData( CF_TEXT) ) == NULL ) { CloseClipboard(); - return NULL; - } - - len = strlen( (char *)handle ); - - if ( threadid < 0 || threadid >= THREAD_LIMIT ) - threadid = 0; - - if ( _clipboard_contents[threadid] != NULL ) - { - GlobalFree( _clipboard_contents[threadid] ); - } - _clipboard_contents[threadid] = (char *)GlobalAlloc(GMEM_FIXED, len + 1); - if ( !_clipboard_contents[threadid] ) - { - CloseClipboard(); - return NULL; - } - - strcpy( (char *)_clipboard_contents[threadid], (char *)handle ); + return ret; + } + + if ( (tmp = GlobalLock(handle)) && strlen(tmp) ) + { + ret = strdup(tmp); + GlobalUnlock(handle); + } CloseClipboard(); - - return _clipboard_contents[threadid]; + return ret; } /* @@ -9861,11 +9837,7 @@ GlobalUnlock( ptr1 ); EmptyClipboard(); - if ( !SetClipboardData( CF_TEXT, ptr1 ) ) - { - GlobalFree( ptr1 ); - return; - } + SetClipboardData( CF_TEXT, ptr1 ); CloseClipboard(); GlobalFree( ptr1 );