15c6c1daeSBarry Smith 25c6c1daeSBarry Smith #include <petscsys.h> 3af0996ceSBarry Smith #include <petsc/private/drawimpl.h> 478ac5f8bSSatish Balay #include <../src/sys/classes/draw/impls/win32/win32draw.h> 55c6c1daeSBarry Smith 65c6c1daeSBarry Smith #define IDC_FOUR 109 75c6c1daeSBarry Smith #define IDI_FOUR 107 85c6c1daeSBarry Smith #define IDM_EXIT 105 95c6c1daeSBarry Smith #define IDR_POPUP 103 105c6c1daeSBarry Smith #define MAX_LOADSTRING 100 115c6c1daeSBarry Smith 125c6c1daeSBarry Smith #if !defined(SelectPen) 135c6c1daeSBarry Smith #define SelectPen(hdc, hpen) ((HPEN)SelectObject((hdc), (HGDIOBJ)(HPEN)(hpen))) 145c6c1daeSBarry Smith #endif 155c6c1daeSBarry Smith #if !defined(SelectFont) 165c6c1daeSBarry Smith #define SelectFont(hdc, hfont) ((HFONT)SelectObject((hdc), (HGDIOBJ)(HFONT)(hfont))) 175c6c1daeSBarry Smith #endif 185c6c1daeSBarry Smith #if !defined(SelectBrush) 195c6c1daeSBarry Smith #define SelectBrush(hdc, hbrush) ((HBRUSH)SelectObject((hdc), (HGDIOBJ)(HBRUSH)(hbrush))) 205c6c1daeSBarry Smith #endif 215c6c1daeSBarry Smith #if !defined(GetStockBrush) 225c6c1daeSBarry Smith #define GetStockBrush(i) ((HBRUSH)GetStockObject(i)) 235c6c1daeSBarry Smith #endif 245c6c1daeSBarry Smith 259371c9d4SSatish Balay #define XTRANS(draw, win, x) (int)(((win)->w) * ((draw)->port_xl + (((x - (draw)->coor_xl) * ((draw)->port_xr - (draw)->port_xl)) / ((draw)->coor_xr - (draw)->coor_xl)))) 269371c9d4SSatish Balay #define YTRANS(draw, win, y) (int)(((win)->h) * (1.0 - (draw)->port_yl - (((y - (draw)->coor_yl) * ((draw)->port_yr - (draw)->port_yl)) / ((draw)->coor_yr - (draw)->coor_yl)))) 275c6c1daeSBarry Smith 285c6c1daeSBarry Smith HINSTANCE hInst; 295c6c1daeSBarry Smith HANDLE g_hWindowListMutex = NULL; 305c6c1daeSBarry Smith WindowNode WindowListHead = NULL; 315c6c1daeSBarry Smith 325c6c1daeSBarry Smith /* Hard coded color hue until hue.c works with this */ 335c6c1daeSBarry Smith unsigned char RedMap[] = {255, 0, 255, 0, 0, 0, 255, 127, 34, 255, 238, 165, 255, 255, 190, 255, 255, 238, 0, 255, 105, 154, 135, 0, 0, 244, 152, 176, 220, 216, 50, 255}; 345c6c1daeSBarry Smith unsigned char GreenMap[] = {255, 0, 0, 255, 255, 0, 0, 255, 139, 165, 130, 42, 182, 127, 190, 255, 215, 162, 197, 246, 105, 205, 206, 100, 0, 164, 245, 224, 17, 191, 205, 240}; 355c6c1daeSBarry Smith unsigned char BlueMap[] = {255, 0, 0, 0, 255, 255, 225, 212, 34, 0, 238, 42, 193, 80, 190, 0, 0, 173, 205, 143, 105, 50, 235, 0, 128, 96, 255, 230, 120, 216, 50, 245}; 365c6c1daeSBarry Smith 37da81f932SPierre Jolivet /* Forward declarations of functions included in this code module: */ 385c6c1daeSBarry Smith LRESULT CALLBACK PetscWndProc(HWND, UINT, WPARAM, LPARAM); 395c6c1daeSBarry Smith static PetscErrorCode TranslateColor_Win32(PetscDraw, int); 405c6c1daeSBarry Smith static PetscErrorCode AverageColorRectangle_Win32(PetscDraw, int, int, int, int); 415c6c1daeSBarry Smith static PetscErrorCode AverageColorTriangle_Win32(PetscDraw, int, int, int); 425c6c1daeSBarry Smith static PetscErrorCode deletemouselist_Win32(WindowNode); 435c6c1daeSBarry Smith static void OnPaint_Win32(HWND); 445c6c1daeSBarry Smith static void OnDestroy_Win32(HWND); 455c6c1daeSBarry Smith static PetscErrorCode MouseRecord_Win32(HWND, PetscDrawButton); 465c6c1daeSBarry Smith static PetscErrorCode PetscDrawGetPopup_Win32(PetscDraw, PetscDraw *); 475c6c1daeSBarry Smith 48d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDrawSetDoubleBuffer_Win32(PetscDraw draw) 49d71ae5a4SJacob Faibussowitsch { 505c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32 *)draw->data; 515c6c1daeSBarry Smith HDC hdc = GetDC(windraw->hWnd); 525c6c1daeSBarry Smith 535c6c1daeSBarry Smith PetscFunctionBegin; 545c6c1daeSBarry Smith windraw->node->DoubleBuffer = CreateCompatibleDC(hdc); 555c6c1daeSBarry Smith windraw->node->DoubleBufferBit = CreateCompatibleBitmap(hdc, windraw->w, windraw->h); 565c6c1daeSBarry Smith windraw->node->dbstore = SelectObject(windraw->node->DoubleBuffer, windraw->node->DoubleBufferBit); 575c6c1daeSBarry Smith /* Fill background of second buffer */ 585c6c1daeSBarry Smith ExtFloodFill(windraw->node->DoubleBuffer, 0, 0, COLOR_WINDOW, FLOODFILLBORDER); 59da81f932SPierre Jolivet /* Copy current buffer into second buffer and set window data as double buffered */ 609371c9d4SSatish Balay BitBlt(windraw->node->DoubleBuffer, 0, 0, windraw->w, windraw->h, windraw->node->Buffer, 0, 0, SRCCOPY); 615c6c1daeSBarry Smith 625c6c1daeSBarry Smith windraw->node->DoubleBuffered = PETSC_TRUE; 635c6c1daeSBarry Smith ReleaseDC(windraw->hWnd, hdc); 643ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 655c6c1daeSBarry Smith } 665c6c1daeSBarry Smith 67d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDrawFlush_Win32(PetscDraw draw) 68d71ae5a4SJacob Faibussowitsch { 695c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32 *)draw->data; 705c6c1daeSBarry Smith HDC hdc = GetDC(windraw->hWnd); 715c6c1daeSBarry Smith 725c6c1daeSBarry Smith PetscFunctionBegin; 735c6c1daeSBarry Smith /* flush double buffer into primary buffer */ 749371c9d4SSatish Balay BitBlt(windraw->node->Buffer, 0, 0, windraw->w, windraw->h, windraw->node->DoubleBuffer, 0, 0, SRCCOPY); 755c6c1daeSBarry Smith /* flush double buffer into window */ 769371c9d4SSatish Balay BitBlt(hdc, 0, 0, windraw->w, windraw->h, windraw->node->DoubleBuffer, 0, 0, SRCCOPY); 775c6c1daeSBarry Smith ReleaseDC(windraw->hWnd, hdc); 783ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 795c6c1daeSBarry Smith } 805c6c1daeSBarry Smith 81d71ae5a4SJacob Faibussowitsch static PetscErrorCode deletemouselist_Win32(WindowNode deletelist) 82d71ae5a4SJacob Faibussowitsch { 835c6c1daeSBarry Smith /* Called upon window close. Frees memory of linked list of stored mouse commands */ 845c6c1daeSBarry Smith MouseNode node; 855c6c1daeSBarry Smith 866c4ed002SBarry Smith while (deletelist->MouseListHead) { 875c6c1daeSBarry Smith node = deletelist->MouseListHead; 886c4ed002SBarry Smith if (deletelist->MouseListHead->mnext) deletelist->MouseListHead = deletelist->MouseListHead->mnext; 895c6c1daeSBarry Smith PetscFree(node); 905c6c1daeSBarry Smith } 915c6c1daeSBarry Smith deletelist->MouseListHead = deletelist->MouseListTail = NULL; 926c4ed002SBarry Smith if (deletelist->wprev) deletelist->wprev->wnext = deletelist->wnext; 936c4ed002SBarry Smith if (deletelist->wnext) deletelist->wnext->wprev = deletelist->wprev; 945c6c1daeSBarry Smith PetscFree(deletelist); 953ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 965c6c1daeSBarry Smith } 975c6c1daeSBarry Smith 98d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDrawGetMouseButton_Win32(PetscDraw draw, PetscDrawButton *button, PetscReal *x_user, PetscReal *y_user, PetscReal *x_phys, PetscReal *y_phys) 99d71ae5a4SJacob Faibussowitsch { 1005c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32 *)draw->data; 1015c6c1daeSBarry Smith WindowNode current; 1025c6c1daeSBarry Smith MouseNode node = 0; 1035c6c1daeSBarry Smith 1045c6c1daeSBarry Smith PetscFunctionBegin; 1055c6c1daeSBarry Smith /* Make sure no other code is using the linked list at this moment */ 1065c6c1daeSBarry Smith WaitForSingleObject(g_hWindowListMutex, INFINITE); 1075c6c1daeSBarry Smith /* Look for the node that matches the window you are using */ 1085c6c1daeSBarry Smith current = WindowListHead; 1096c4ed002SBarry Smith while (current) { 1105c6c1daeSBarry Smith if (current->hWnd == windraw->hWnd) { 1115c6c1daeSBarry Smith current->IsGetMouseOn = TRUE; 1125c6c1daeSBarry Smith break; 113a297a907SKarl Rupp } else current = current->wnext; 1145c6c1daeSBarry Smith } 115a5b23f4aSJose E. Roman /* If no actions have occurred, wait for one */ 1165c6c1daeSBarry Smith node = current->MouseListHead; 1175c6c1daeSBarry Smith if (!node) { 1185c6c1daeSBarry Smith ReleaseMutex(g_hWindowListMutex); 1195c6c1daeSBarry Smith WaitForSingleObject(current->event, INFINITE); 1205c6c1daeSBarry Smith WaitForSingleObject(g_hWindowListMutex, INFINITE); 1215c6c1daeSBarry Smith } 1225c6c1daeSBarry Smith /* once we have the information, assign the pointers to it */ 1235c6c1daeSBarry Smith *button = current->MouseListHead->Button; 1245c6c1daeSBarry Smith *x_user = current->MouseListHead->user.x; 1255c6c1daeSBarry Smith *y_user = current->MouseListHead->user.y; 1265c6c1daeSBarry Smith /* optional arguments */ 1275c6c1daeSBarry Smith if (x_phys) *x_phys = current->MouseListHead->phys.x; 1285c6c1daeSBarry Smith if (y_phys) *y_phys = current->MouseListHead->phys.y; 1295c6c1daeSBarry Smith /* remove set of information from sub linked-list, delete the node */ 1305c6c1daeSBarry Smith current->MouseListHead = current->MouseListHead->mnext; 1315c6c1daeSBarry Smith if (!current->MouseListHead) { 1325c6c1daeSBarry Smith ResetEvent(current->event); 1335c6c1daeSBarry Smith current->MouseListTail = NULL; 1345c6c1daeSBarry Smith } 1355c6c1daeSBarry Smith if (node) PetscFree(node); 1365c6c1daeSBarry Smith 1375c6c1daeSBarry Smith /* Release mutex so that other code can use 1385c6c1daeSBarry Smith the linked list now that we are done with it */ 1395c6c1daeSBarry Smith ReleaseMutex(g_hWindowListMutex); 1403ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1415c6c1daeSBarry Smith } 1425c6c1daeSBarry Smith 143d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDrawPause_Win32(PetscDraw draw) 144d71ae5a4SJacob Faibussowitsch { 1455c6c1daeSBarry Smith PetscFunctionBegin; 1465c6c1daeSBarry Smith PetscSleep(draw->pause); 1473ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1485c6c1daeSBarry Smith } 1495c6c1daeSBarry Smith 150d71ae5a4SJacob Faibussowitsch static PetscErrorCode TranslateColor_Win32(PetscDraw draw, int color) 151d71ae5a4SJacob Faibussowitsch { 1525c6c1daeSBarry Smith /* Maps single color value into the RGB colors in our tables */ 1535c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32 *)draw->data; 1545c6c1daeSBarry Smith windraw->currentcolor = RGB(RedMap[color], GreenMap[color], BlueMap[color]); 1553ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 1565c6c1daeSBarry Smith } 1575c6c1daeSBarry Smith 158d71ae5a4SJacob Faibussowitsch static PetscErrorCode AverageColorRectangle_Win32(PetscDraw draw, int c1, int c2, int c3, int c4) 159d71ae5a4SJacob Faibussowitsch { 1605c6c1daeSBarry Smith /* Averages colors given at points of rectangle and sets color from color table 1615c6c1daeSBarry Smith will be changed once the color gradient problem is worked out */ 1625c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32 *)draw->data; 1639371c9d4SSatish Balay windraw->currentcolor = RGB(((RedMap[c1] + RedMap[c2] + RedMap[c3] + RedMap[c4]) / 4), ((GreenMap[c1] + GreenMap[c2] + GreenMap[c3] + GreenMap[c4]) / 4), ((BlueMap[c1] + BlueMap[c2] + BlueMap[c3] + BlueMap[c4]) / 4)); 1643ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 1655c6c1daeSBarry Smith } 1665c6c1daeSBarry Smith 167d71ae5a4SJacob Faibussowitsch static PetscErrorCode AverageColorTriangle_Win32(PetscDraw draw, int c1, int c2, int c3) 168d71ae5a4SJacob Faibussowitsch { 1695c6c1daeSBarry Smith /* Averages colors given at points of rectangle and sets color from color table 1705c6c1daeSBarry Smith will be changed once the color gradient problem is worked out */ 1715c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32 *)draw->data; 1729371c9d4SSatish Balay windraw->currentcolor = RGB((RedMap[c1] + RedMap[c2] + RedMap[c3]) / 3, (GreenMap[c1] + GreenMap[c2] + GreenMap[c3]) / 3, (BlueMap[c1] + BlueMap[c2] + BlueMap[c3]) / 3); 1733ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 1745c6c1daeSBarry Smith } 1755c6c1daeSBarry Smith 176d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDrawRectangle_Win32(PetscDraw draw, PetscReal xl, PetscReal yl, PetscReal xr, PetscReal yr, int c1, int c2, int c3, int c4) 177d71ae5a4SJacob Faibussowitsch { 1785c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32 *)draw->data; 1795c6c1daeSBarry Smith HBRUSH hbrush; 1805c6c1daeSBarry Smith RECT rect; 1815c6c1daeSBarry Smith int x1, yone, x2, y2; 1825c6c1daeSBarry Smith HDC hdc; 1835c6c1daeSBarry Smith 1845c6c1daeSBarry Smith PetscFunctionBegin; 1855c6c1daeSBarry Smith x1 = XTRANS(draw, windraw, xl); 1865c6c1daeSBarry Smith x2 = XTRANS(draw, windraw, xr); 1875c6c1daeSBarry Smith yone = YTRANS(draw, windraw, yl); 1885c6c1daeSBarry Smith y2 = YTRANS(draw, windraw, yr); 1895c6c1daeSBarry Smith SetRect(&rect, x1, y2, x2, yone); 190a297a907SKarl Rupp if (c1 == c2 && c2 == c3 && c3 == c4) TranslateColor_Win32(draw, c1); 191a297a907SKarl Rupp else AverageColorRectangle_Win32(draw, c1, c2, c3, c4); 1925c6c1daeSBarry Smith hbrush = CreateSolidBrush(windraw->currentcolor); 1935c6c1daeSBarry Smith 194a297a907SKarl Rupp if (windraw->node->DoubleBuffered) hdc = windraw->node->DoubleBuffer; 195a297a907SKarl Rupp else hdc = windraw->node->Buffer; 196a297a907SKarl Rupp 1975c6c1daeSBarry Smith FillRect(hdc, &rect, hbrush); 1985c6c1daeSBarry Smith /* Forces a WM_PAINT message and erases background */ 1995c6c1daeSBarry Smith InvalidateRect(windraw->hWnd, NULL, TRUE); 2005c6c1daeSBarry Smith UpdateWindow(windraw->hWnd); 2013ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2025c6c1daeSBarry Smith } 2035c6c1daeSBarry Smith 204d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDrawLine_Win32(PetscDraw draw, PetscReal xl, PetscReal yl, PetscReal xr, PetscReal yr, int color) 205d71ae5a4SJacob Faibussowitsch { 2065c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32 *)draw->data; 2075c6c1daeSBarry Smith HPEN hpen; 2085c6c1daeSBarry Smith int x1, yone, x2, y2; 2095c6c1daeSBarry Smith HDC hdc; 2105c6c1daeSBarry Smith 2115c6c1daeSBarry Smith PetscFunctionBegin; 2125c6c1daeSBarry Smith TranslateColor_Win32(draw, color); 2139371c9d4SSatish Balay x1 = XTRANS(draw, windraw, xl); 2149371c9d4SSatish Balay x2 = XTRANS(draw, windraw, xr); 2159371c9d4SSatish Balay yone = YTRANS(draw, windraw, yl); 2169371c9d4SSatish Balay y2 = YTRANS(draw, windraw, yr); 2175c6c1daeSBarry Smith hpen = CreatePen(PS_SOLID, windraw->linewidth, windraw->currentcolor); 218a297a907SKarl Rupp if (windraw->node->DoubleBuffered) hdc = windraw->node->DoubleBuffer; 219a297a907SKarl Rupp else hdc = windraw->node->Buffer; 220a297a907SKarl Rupp 2215c6c1daeSBarry Smith SelectPen(hdc, hpen); 2225c6c1daeSBarry Smith MoveToEx(hdc, x1, yone, NULL); 2235c6c1daeSBarry Smith LineTo(hdc, x2, y2); 2245c6c1daeSBarry Smith /* Forces a WM_PAINT message and erases background */ 2255c6c1daeSBarry Smith InvalidateRect(windraw->hWnd, NULL, TRUE); 2265c6c1daeSBarry Smith UpdateWindow(windraw->hWnd); 2273ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2285c6c1daeSBarry Smith } 2295c6c1daeSBarry Smith 230d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDrawLineSetWidth_Win32(PetscDraw draw, PetscReal width) 231d71ae5a4SJacob Faibussowitsch { 2325c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32 *)draw->data; 2335c6c1daeSBarry Smith int averagesize, finalwidth; 2345c6c1daeSBarry Smith RECT rect; 2355c6c1daeSBarry Smith 2365c6c1daeSBarry Smith PetscFunctionBegin; 2375c6c1daeSBarry Smith GetClientRect(windraw->hWnd, &rect); 2385c6c1daeSBarry Smith averagesize = ((rect.right - rect.left) + (rect.bottom - rect.top)) / 2; 23977b4d14cSPeter Brune finalwidth = (int)PetscFloorReal(averagesize * width); 240a297a907SKarl Rupp if (finalwidth < 1) finalwidth = 1; /* minimum size PetscDrawLine can except */ 241a297a907SKarl Rupp 2425c6c1daeSBarry Smith windraw->linewidth = finalwidth; 2433ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2445c6c1daeSBarry Smith } 2455c6c1daeSBarry Smith 246d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDrawLineGetWidth_Win32(PetscDraw draw, PetscReal *width) 247d71ae5a4SJacob Faibussowitsch { 2485c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32 *)draw->data; 2495c6c1daeSBarry Smith 2505c6c1daeSBarry Smith PetscFunctionBegin; 2515c6c1daeSBarry Smith *width = (PetscReal)windraw->linewidth; 2523ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2535c6c1daeSBarry Smith } 2545c6c1daeSBarry Smith 255d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDrawPoint_Win32(PetscDraw draw, PetscReal x, PetscReal y, int color) 256d71ae5a4SJacob Faibussowitsch { 2575c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32 *)draw->data; 2585c6c1daeSBarry Smith HBRUSH hbrush; 2595c6c1daeSBarry Smith HRGN hrgn; 2605c6c1daeSBarry Smith int radius; 2615c6c1daeSBarry Smith int x1, yone; 2625c6c1daeSBarry Smith HDC hdc; 2635c6c1daeSBarry Smith 2645c6c1daeSBarry Smith PetscFunctionBegin; 2655c6c1daeSBarry Smith TranslateColor_Win32(draw, color); 2665c6c1daeSBarry Smith x1 = XTRANS(draw, windraw, x); 2675c6c1daeSBarry Smith yone = YTRANS(draw, windraw, y); 2685c6c1daeSBarry Smith hbrush = CreateSolidBrush(windraw->currentcolor); 269a297a907SKarl Rupp if (windraw->node->DoubleBuffered) hdc = windraw->node->DoubleBuffer; 270a297a907SKarl Rupp else hdc = windraw->node->Buffer; 271a297a907SKarl Rupp 2725c6c1daeSBarry Smith /* desired size is one logical pixel so just turn it on */ 273a297a907SKarl Rupp if (windraw->pointdiameter == 1) SetPixelV(hdc, x1, yone, windraw->currentcolor); 274a297a907SKarl Rupp else { 2755c6c1daeSBarry Smith /* draw point around position determined */ 2765c6c1daeSBarry Smith radius = windraw->pointdiameter / 2; /* integer division */ 2775c6c1daeSBarry Smith hrgn = CreateEllipticRgn(x1 - radius, yone - radius, x1 + radius, yone + radius); 2785c6c1daeSBarry Smith FillRgn(hdc, hrgn, hbrush); 2795c6c1daeSBarry Smith } 2805c6c1daeSBarry Smith /* Forces a WM_PAINT and erases background */ 2815c6c1daeSBarry Smith InvalidateRect(windraw->hWnd, NULL, TRUE); 2825c6c1daeSBarry Smith UpdateWindow(windraw->hWnd); 2833ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2845c6c1daeSBarry Smith } 2855c6c1daeSBarry Smith 286d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDrawPointSetSize_Win32(PetscDraw draw, PetscReal width) 287d71ae5a4SJacob Faibussowitsch { 2885c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32 *)draw->data; 2895c6c1daeSBarry Smith int averagesize, diameter; 2905c6c1daeSBarry Smith RECT rect; 2915c6c1daeSBarry Smith 2925c6c1daeSBarry Smith PetscFunctionBegin; 2935c6c1daeSBarry Smith GetClientRect(windraw->hWnd, &rect); 2945c6c1daeSBarry Smith averagesize = ((rect.right - rect.left) + (rect.bottom - rect.top)) / 2; 29577b4d14cSPeter Brune diameter = (int)PetscFloorReal(averagesize * width); 2965c6c1daeSBarry Smith if (diameter < 1) diameter = 1; 2975c6c1daeSBarry Smith windraw->pointdiameter = diameter; 2983ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2995c6c1daeSBarry Smith } 3005c6c1daeSBarry Smith 301d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDrawString_Win32(PetscDraw draw, PetscReal x, PetscReal y, int color, const char *text) 302d71ae5a4SJacob Faibussowitsch { 3035c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32 *)draw->data; 3045c6c1daeSBarry Smith RECT r; 3055c6c1daeSBarry Smith HFONT hfont; 3065c6c1daeSBarry Smith LOGFONT logfont; 3075c6c1daeSBarry Smith int x1, yone; 3085c6c1daeSBarry Smith HDC hdc; 3095c6c1daeSBarry Smith 3105c6c1daeSBarry Smith PetscFunctionBegin; 3115c6c1daeSBarry Smith x1 = XTRANS(draw, windraw, x); 3125c6c1daeSBarry Smith yone = YTRANS(draw, windraw, y); 3135c6c1daeSBarry Smith r.bottom = yone; 3145c6c1daeSBarry Smith r.left = x1; 3155c6c1daeSBarry Smith r.right = x1 + 1; 3165c6c1daeSBarry Smith r.top = yone + 1; 317a297a907SKarl Rupp 3185c6c1daeSBarry Smith logfont.lfHeight = windraw->stringheight; 3195c6c1daeSBarry Smith logfont.lfWidth = windraw->stringwidth; 3205c6c1daeSBarry Smith logfont.lfEscapement = 0; 3215c6c1daeSBarry Smith logfont.lfOrientation = 0; 3225c6c1daeSBarry Smith logfont.lfCharSet = 0; 3235c6c1daeSBarry Smith logfont.lfClipPrecision = 0; 3245c6c1daeSBarry Smith logfont.lfItalic = 0; 3255c6c1daeSBarry Smith logfont.lfOutPrecision = 0; 3265c6c1daeSBarry Smith logfont.lfPitchAndFamily = DEFAULT_PITCH; 3275c6c1daeSBarry Smith logfont.lfQuality = DEFAULT_QUALITY; 3285c6c1daeSBarry Smith logfont.lfStrikeOut = 0; 3295c6c1daeSBarry Smith logfont.lfUnderline = 0; 3305c6c1daeSBarry Smith logfont.lfWeight = FW_NORMAL; 331a297a907SKarl Rupp 3325c6c1daeSBarry Smith hfont = CreateFontIndirect(&logfont); 3335c6c1daeSBarry Smith TranslateColor_Win32(draw, color); 334a297a907SKarl Rupp if (windraw->node->DoubleBuffered) hdc = windraw->node->DoubleBuffer; 335a297a907SKarl Rupp else hdc = windraw->node->Buffer; 336a297a907SKarl Rupp 3375c6c1daeSBarry Smith SelectFont(hdc, hfont); 3385c6c1daeSBarry Smith SetTextColor(hdc, windraw->currentcolor); 3395c6c1daeSBarry Smith DrawText(hdc, text, lstrlen(text), &r, DT_NOCLIP); 3405c6c1daeSBarry Smith DeleteObject(hfont); 3415c6c1daeSBarry Smith /* Forces a WM_PAINT message and erases background */ 3425c6c1daeSBarry Smith InvalidateRect(windraw->hWnd, NULL, TRUE); 3435c6c1daeSBarry Smith UpdateWindow(windraw->hWnd); 3443ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3455c6c1daeSBarry Smith } 3465c6c1daeSBarry Smith 347d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDrawStringVertical_Win32(PetscDraw draw, PetscReal x, PetscReal y, int color, const char *text) 348d71ae5a4SJacob Faibussowitsch { 3495c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32 *)draw->data; 3505c6c1daeSBarry Smith RECT r; 3515c6c1daeSBarry Smith HFONT hfont; 3525c6c1daeSBarry Smith LOGFONT logfont; 3535c6c1daeSBarry Smith int x1, yone; 3545c6c1daeSBarry Smith HDC hdc; 3555c6c1daeSBarry Smith 3565c6c1daeSBarry Smith PetscFunctionBegin; 3575c6c1daeSBarry Smith x1 = XTRANS(draw, windraw, x); 3585c6c1daeSBarry Smith yone = YTRANS(draw, windraw, y); 3595c6c1daeSBarry Smith r.left = x1; 3605c6c1daeSBarry Smith r.bottom = yone + 30; 3615c6c1daeSBarry Smith r.right = x1 + 1; 3625c6c1daeSBarry Smith r.top = yone - 30; 363a297a907SKarl Rupp 3645c6c1daeSBarry Smith logfont.lfEscapement = 2700; /* Causes verticle text drawing */ 3655c6c1daeSBarry Smith logfont.lfHeight = windraw->stringheight; 3665c6c1daeSBarry Smith logfont.lfWidth = windraw->stringwidth; 3675c6c1daeSBarry Smith logfont.lfOrientation = 0; 3685c6c1daeSBarry Smith logfont.lfCharSet = DEFAULT_CHARSET; 3695c6c1daeSBarry Smith logfont.lfClipPrecision = 0; 3705c6c1daeSBarry Smith logfont.lfItalic = 0; 3715c6c1daeSBarry Smith logfont.lfOutPrecision = 0; 3725c6c1daeSBarry Smith logfont.lfPitchAndFamily = DEFAULT_PITCH; 3735c6c1daeSBarry Smith logfont.lfQuality = DEFAULT_QUALITY; 3745c6c1daeSBarry Smith logfont.lfStrikeOut = 0; 3755c6c1daeSBarry Smith logfont.lfUnderline = 0; 3765c6c1daeSBarry Smith logfont.lfWeight = FW_NORMAL; 377a297a907SKarl Rupp 3785c6c1daeSBarry Smith hfont = CreateFontIndirect(&logfont); 3795c6c1daeSBarry Smith TranslateColor_Win32(draw, color); 380a297a907SKarl Rupp if (windraw->node->DoubleBuffered) hdc = windraw->node->DoubleBuffer; 381a297a907SKarl Rupp else hdc = windraw->node->Buffer; 382a297a907SKarl Rupp 3835c6c1daeSBarry Smith SelectFont(hdc, hfont); 3845c6c1daeSBarry Smith SetTextColor(hdc, windraw->currentcolor); 3855c6c1daeSBarry Smith DrawText(hdc, text, lstrlen(text), &r, DT_NOCLIP | DT_SINGLELINE); 3865c6c1daeSBarry Smith DeleteObject(hfont); 3875c6c1daeSBarry Smith /* Forces a WM_PAINT message and erases background */ 3885c6c1daeSBarry Smith InvalidateRect(windraw->hWnd, NULL, TRUE); 3895c6c1daeSBarry Smith UpdateWindow(windraw->hWnd); 3903ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3915c6c1daeSBarry Smith } 3925c6c1daeSBarry Smith 393d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDrawStringSetSize_Win32(PetscDraw draw, PetscReal width, PetscReal height) 394d71ae5a4SJacob Faibussowitsch { 3955c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32 *)draw->data; 3965c6c1daeSBarry Smith int w, h; 3975c6c1daeSBarry Smith 3985c6c1daeSBarry Smith PetscFunctionBegin; 3995c6c1daeSBarry Smith w = (int)((windraw->w) * width * (draw->port_xr - draw->port_xl) / (draw->coor_xr - draw->coor_xl)); 4005c6c1daeSBarry Smith h = (int)((windraw->h) * height * (draw->port_yr - draw->port_yl) / (draw->coor_yr - draw->coor_yl)); 4015c6c1daeSBarry Smith if (h < 1) h = 1; 4025c6c1daeSBarry Smith if (w < 1) w = 1; 4035c6c1daeSBarry Smith windraw->stringheight = h; 4045c6c1daeSBarry Smith windraw->stringwidth = w; 4053ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4065c6c1daeSBarry Smith } 407d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDrawStringGetSize_Win32(PetscDraw draw, PetscReal *width, PetscReal *height) 408d71ae5a4SJacob Faibussowitsch { 4095c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32 *)draw->data; 4105c6c1daeSBarry Smith double scaleX = (draw->coor_xr - draw->coor_xl) / (draw->w) * (draw->port_xr - draw->port_xl); 4115c6c1daeSBarry Smith double scaleY = (draw->coor_yr - draw->coor_yl) / (draw->h) * (draw->port_yr - draw->port_yl); 4125c6c1daeSBarry Smith 4135c6c1daeSBarry Smith PetscFunctionBegin; 4144a5237bfSSatish Balay if (height) *height = (double)windraw->stringheight * scaleY; 4154a5237bfSSatish Balay if (width) *width = (double)windraw->stringwidth * scaleX; 4163ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4175c6c1daeSBarry Smith } 4185c6c1daeSBarry Smith 419d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDrawResizeWindow_Win32(PetscDraw draw, int w, int h) 420d71ae5a4SJacob Faibussowitsch { 4215c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32 *)draw->data; 4225c6c1daeSBarry Smith RECT r; 4235c6c1daeSBarry Smith 4245c6c1daeSBarry Smith PetscFunctionBegin; 4255c6c1daeSBarry Smith GetWindowRect(windraw->hWnd, &r); 4265c6c1daeSBarry Smith MoveWindow(windraw->hWnd, r.left, r.top, (int)w, (int)h, TRUE); 4275c6c1daeSBarry Smith /* set all variable dealing with window dimensions */ 4285c6c1daeSBarry Smith windraw->node->bitheight = windraw->h = draw->h = h; 4295c6c1daeSBarry Smith windraw->node->bitwidth = windraw->w = draw->w = w; 4305c6c1daeSBarry Smith /* set up graphic buffers with the new size of window */ 4315c6c1daeSBarry Smith SetBitmapDimensionEx(windraw->node->BufferBit, w, h, NULL); 432a297a907SKarl Rupp if (windraw->node->DoubleBuffered) SetBitmapDimensionEx(windraw->node->DoubleBufferBit, w, h, NULL); 4335c6c1daeSBarry Smith windraw->haveresized = PETSC_TRUE; 4343ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4355c6c1daeSBarry Smith } 4365c6c1daeSBarry Smith 437d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDrawCheckResizedWindow_Win32(PetscDraw draw) 438d71ae5a4SJacob Faibussowitsch { 4395c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32 *)draw->data; 4405c6c1daeSBarry Smith 4415c6c1daeSBarry Smith PetscFunctionBegin; 44211cc89d2SBarry Smith PetscCheck(windraw->haveresized != 1, PETSC_COMM_SELF, PETSC_ERR_SUP, "No support for resizing windows on Microsoft Windows"); 4433ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4445c6c1daeSBarry Smith } 4455c6c1daeSBarry Smith 446d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDrawSetTitle_Win32(PetscDraw draw, const char title[]) 447d71ae5a4SJacob Faibussowitsch { 4485c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32 *)draw->data; 4495c6c1daeSBarry Smith 4505c6c1daeSBarry Smith PetscFunctionBegin; 4515c6c1daeSBarry Smith SetWindowText(windraw->hWnd, title); 4523ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4535c6c1daeSBarry Smith } 4545c6c1daeSBarry Smith 455d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDrawClear_Win32(PetscDraw draw) 456d71ae5a4SJacob Faibussowitsch { 4575c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32 *)draw->data; 4585c6c1daeSBarry Smith 4595c6c1daeSBarry Smith PetscFunctionBegin; 4605c6c1daeSBarry Smith /* clear primary buffer */ 4615c6c1daeSBarry Smith ExtFloodFill(windraw->node->Buffer, 0, 0, COLOR_WINDOW, FLOODFILLBORDER); 4625c6c1daeSBarry Smith /* if exists clear secondary buffer */ 463a297a907SKarl Rupp if (windraw->node->DoubleBuffered) ExtFloodFill(windraw->node->DoubleBuffer, 0, 0, COLOR_WINDOW, FLOODFILLBORDER); 464a297a907SKarl Rupp 4655c6c1daeSBarry Smith /* force WM_PAINT message so cleared buffer will show */ 4665c6c1daeSBarry Smith InvalidateRect(windraw->hWnd, NULL, TRUE); 4675c6c1daeSBarry Smith UpdateWindow(windraw->hWnd); 4683ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4695c6c1daeSBarry Smith } 4705c6c1daeSBarry Smith 471d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDrawTriangle_Win32(PetscDraw draw, PetscReal x1, PetscReal yone, PetscReal x2, PetscReal y2, PetscReal x3, PetscReal y3, int c1, int c2, int c3) 472d71ae5a4SJacob Faibussowitsch { 4735c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32 *)draw->data; 4745c6c1daeSBarry Smith HBRUSH hbrush; 4755c6c1daeSBarry Smith HPEN hpen; 4765c6c1daeSBarry Smith int p1x, p1y, p2x, p2y, p3x, p3y; 4775c6c1daeSBarry Smith HDC bit; 4785c6c1daeSBarry Smith 4795c6c1daeSBarry Smith PetscFunctionBegin; 4805c6c1daeSBarry Smith AverageColorTriangle_Win32(draw, c1, c2, c3); 4815c6c1daeSBarry Smith hbrush = CreateSolidBrush(windraw->currentcolor); 4825c6c1daeSBarry Smith hpen = CreatePen(PS_SOLID, 0, windraw->currentcolor); 4835c6c1daeSBarry Smith p1x = XTRANS(draw, windraw, x1); 4845c6c1daeSBarry Smith p2x = XTRANS(draw, windraw, x2); 4855c6c1daeSBarry Smith p3x = XTRANS(draw, windraw, x3); 4865c6c1daeSBarry Smith p1y = YTRANS(draw, windraw, yone); 4875c6c1daeSBarry Smith p2y = YTRANS(draw, windraw, y2); 4885c6c1daeSBarry Smith p3y = YTRANS(draw, windraw, y3); 4895c6c1daeSBarry Smith 490a297a907SKarl Rupp if (windraw->node->DoubleBuffered) bit = windraw->node->DoubleBuffer; 491a297a907SKarl Rupp else bit = windraw->node->Buffer; 492a297a907SKarl Rupp 4935c6c1daeSBarry Smith BeginPath(bit); 4945c6c1daeSBarry Smith MoveToEx(bit, p1x, p1y, NULL); 4955c6c1daeSBarry Smith LineTo(bit, p2x, p2y); 4965c6c1daeSBarry Smith LineTo(bit, p3x, p3y); 4975c6c1daeSBarry Smith LineTo(bit, p1x, p1y); 4985c6c1daeSBarry Smith EndPath(bit); 4995c6c1daeSBarry Smith SelectPen(bit, hpen); 5005c6c1daeSBarry Smith SelectBrush(bit, hbrush); 5015c6c1daeSBarry Smith StrokeAndFillPath(bit); 5025c6c1daeSBarry Smith /* Forces a WM_PAINT message and erases background */ 5035c6c1daeSBarry Smith InvalidateRect(windraw->hWnd, NULL, TRUE); 5045c6c1daeSBarry Smith UpdateWindow(windraw->hWnd); 5053ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5065c6c1daeSBarry Smith } 5075c6c1daeSBarry Smith 508*bb09dc67SDuncan Campbell static PetscErrorCode PetscDrawSetVisible_Win32(PetscDraw draw, PetscBool visible) 509*bb09dc67SDuncan Campbell { 510*bb09dc67SDuncan Campbell PetscDraw_Win32 *windraw = (PetscDraw_Win32 *)draw->data; 511*bb09dc67SDuncan Campbell 512*bb09dc67SDuncan Campbell PetscFunctionBegin; 513*bb09dc67SDuncan Campbell ShowWindow(windraw->hWnd, visible ? SW_SHOWNA : SW_HIDE); 514*bb09dc67SDuncan Campbell PetscFunctionReturn(PETSC_SUCCESS); 515*bb09dc67SDuncan Campbell } 516*bb09dc67SDuncan Campbell 517d71ae5a4SJacob Faibussowitsch void PopMessageLoopThread_Win32(PetscDraw popdraw) 518d71ae5a4SJacob Faibussowitsch { 5195c6c1daeSBarry Smith PetscDraw_Win32 *pop = (PetscDraw_Win32 *)popdraw->data; 5205c6c1daeSBarry Smith MSG msg; 5215c6c1daeSBarry Smith HWND hWnd = NULL; 522fad2a674SVolker const char PopClassName[] = "PETSc Window Pop Class"; 5235c6c1daeSBarry Smith RECT r; 5245c6c1daeSBarry Smith int width, height; 5255c6c1daeSBarry Smith WNDCLASSEX myclass; 5265c6c1daeSBarry Smith LPVOID lpMsgBuf; 5275c6c1daeSBarry Smith 5285c6c1daeSBarry Smith PetscFunctionBegin; 5295c6c1daeSBarry Smith /* initialize window class parameters */ 5305c6c1daeSBarry Smith myclass.cbSize = sizeof(WNDCLASSEX); 5315c6c1daeSBarry Smith myclass.style = CS_OWNDC; 5325c6c1daeSBarry Smith myclass.lpfnWndProc = (WNDPROC)PetscWndProc; 5335c6c1daeSBarry Smith myclass.cbClsExtra = 0; 5345c6c1daeSBarry Smith myclass.cbWndExtra = 0; 5355c6c1daeSBarry Smith myclass.hInstance = NULL; 5365c6c1daeSBarry Smith myclass.hIcon = NULL; 5375c6c1daeSBarry Smith myclass.hCursor = LoadCursor(NULL, IDC_ARROW); 5385c6c1daeSBarry Smith myclass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); 5395c6c1daeSBarry Smith myclass.lpszMenuName = NULL; 5405c6c1daeSBarry Smith myclass.lpszClassName = PopClassName; 5415c6c1daeSBarry Smith myclass.hIconSm = NULL; 5425c6c1daeSBarry Smith 5435c6c1daeSBarry Smith RegisterClassEx(&myclass); 5445c6c1daeSBarry Smith 5455c6c1daeSBarry Smith SetRect(&r, 0, 0, 450, 450); 5465c6c1daeSBarry Smith 5475c6c1daeSBarry Smith width = (r.right - r.left) / 3; 5485c6c1daeSBarry Smith height = (r.bottom - r.top) / 3; 5495c6c1daeSBarry Smith 5509371c9d4SSatish Balay hWnd = CreateWindowEx(0, PopClassName, NULL, WS_POPUPWINDOW | WS_CAPTION, 0, 0, width, height, NULL, NULL, hInst, NULL); 5515c6c1daeSBarry Smith pop->x = 0; 5525c6c1daeSBarry Smith pop->y = 0; 5535c6c1daeSBarry Smith pop->w = width; 5545c6c1daeSBarry Smith pop->h = height; 5555c6c1daeSBarry Smith 5565c6c1daeSBarry Smith if (!hWnd) { 557fad2a674SVolker lpMsgBuf = (LPVOID) "Window Not Successfully Created"; 5585c6c1daeSBarry Smith MessageBox(NULL, (LPCTSTR)lpMsgBuf, "Error", MB_OK | MB_ICONINFORMATION); 5595c6c1daeSBarry Smith LocalFree(lpMsgBuf); 5605c6c1daeSBarry Smith exit(0); 5615c6c1daeSBarry Smith } 5625c6c1daeSBarry Smith pop->hWnd = hWnd; 5635c6c1daeSBarry Smith /* display and update new popup window */ 5645c6c1daeSBarry Smith ShowWindow(pop->hWnd, SW_SHOWNORMAL); 5655c6c1daeSBarry Smith UpdateWindow(pop->hWnd); 5665c6c1daeSBarry Smith SetEvent(pop->hReadyEvent); 5675c6c1daeSBarry Smith 5685c6c1daeSBarry Smith while (GetMessage(&msg, pop->hWnd, 0, 0)) { 5695c6c1daeSBarry Smith TranslateMessage(&msg); 5705c6c1daeSBarry Smith DispatchMessage(&msg); 5715c6c1daeSBarry Smith } 5725c6c1daeSBarry Smith PetscFunctionReturnVoid(); 5735c6c1daeSBarry Smith } 5745c6c1daeSBarry Smith 575d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDrawDestroy_Win32(PetscDraw draw) 576d71ae5a4SJacob Faibussowitsch { 5775c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32 *)draw->data; 5785c6c1daeSBarry Smith 5795c6c1daeSBarry Smith PetscFunctionBegin; 5805c6c1daeSBarry Smith SendMessage(windraw->hWnd, WM_DESTROY, 0, 0); 58150c74209SLisandro Dalcin PetscFree(draw->data); 5823ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5835c6c1daeSBarry Smith } 5845c6c1daeSBarry Smith 585d71ae5a4SJacob Faibussowitsch void MessageLoopThread_Win32(PetscDraw draw) 586d71ae5a4SJacob Faibussowitsch { 5875c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32 *)draw->data; 5885c6c1daeSBarry Smith MSG msg; 5895c6c1daeSBarry Smith HWND hWnd = NULL; 590fad2a674SVolker const char classname[] = "PETSc Window Class"; 5915c6c1daeSBarry Smith WNDCLASSEX wclass; 5925c6c1daeSBarry Smith LPVOID lpMsgBuf; 5935c6c1daeSBarry Smith 5945c6c1daeSBarry Smith /* initialize window class parameters */ 5955c6c1daeSBarry Smith wclass.cbSize = sizeof(WNDCLASSEX); 5965c6c1daeSBarry Smith wclass.style = CS_SAVEBITS | CS_HREDRAW | CS_VREDRAW; 5975c6c1daeSBarry Smith wclass.lpfnWndProc = (WNDPROC)PetscWndProc; 5985c6c1daeSBarry Smith wclass.cbClsExtra = 0; 5995c6c1daeSBarry Smith wclass.cbWndExtra = 0; 6005c6c1daeSBarry Smith wclass.hInstance = NULL; 6015c6c1daeSBarry Smith wclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); 6025c6c1daeSBarry Smith wclass.hCursor = LoadCursor(NULL, IDC_ARROW); 6035c6c1daeSBarry Smith wclass.hbrBackground = GetStockBrush(WHITE_BRUSH); 6045c6c1daeSBarry Smith wclass.lpszMenuName = NULL; 6055c6c1daeSBarry Smith wclass.lpszClassName = classname; 6065c6c1daeSBarry Smith wclass.hIconSm = NULL; 6075c6c1daeSBarry Smith 6085c6c1daeSBarry Smith RegisterClassEx(&wclass); 6095c6c1daeSBarry Smith 6109371c9d4SSatish Balay hWnd = CreateWindowEx(0, classname, NULL, WS_OVERLAPPEDWINDOW, draw->x, draw->y, draw->w, draw->h, NULL, NULL, hInst, NULL); 6115c6c1daeSBarry Smith 6125c6c1daeSBarry Smith if (!hWnd) { 613fad2a674SVolker lpMsgBuf = (LPVOID) "Window Not Successfully Created"; 6145c6c1daeSBarry Smith MessageBox(NULL, (LPCTSTR)lpMsgBuf, "Error", MB_OK | MB_ICONINFORMATION); 6155c6c1daeSBarry Smith LocalFree(lpMsgBuf); 6165c6c1daeSBarry Smith exit(0); 6175c6c1daeSBarry Smith } 6185c6c1daeSBarry Smith windraw->hWnd = hWnd; 6195c6c1daeSBarry Smith /* display and update new window */ 6205c6c1daeSBarry Smith ShowWindow(hWnd, SW_SHOWNORMAL); 6215c6c1daeSBarry Smith UpdateWindow(hWnd); 6225c6c1daeSBarry Smith SetEvent(windraw->hReadyEvent); 6235c6c1daeSBarry Smith 6245c6c1daeSBarry Smith while (GetMessage(&msg, hWnd, 0, 0)) { 6255c6c1daeSBarry Smith TranslateMessage(&msg); 6265c6c1daeSBarry Smith DispatchMessage(&msg); 6275c6c1daeSBarry Smith } 628f9baa8adSSatish Balay return; 6295c6c1daeSBarry Smith } 6305c6c1daeSBarry Smith 631*bb09dc67SDuncan Campbell static struct _PetscDrawOps DvOps = {PetscDrawSetDoubleBuffer_Win32, PetscDrawFlush_Win32, PetscDrawLine_Win32, PetscDrawLineSetWidth_Win32, PetscDrawLineGetWidth_Win32, PetscDrawPoint_Win32, PetscDrawPointSetSize_Win32, PetscDrawString_Win32, PetscDrawStringVertical_Win32, PetscDrawStringSetSize_Win32, PetscDrawStringGetSize_Win32, 0, PetscDrawClear_Win32, PetscDrawRectangle_Win32, PetscDrawTriangle_Win32, 0, PetscDrawGetMouseButton_Win32, PetscDrawPause_Win32, 0, 0, PetscDrawGetPopup_Win32, PetscDrawSetTitle_Win32, PetscDrawCheckResizedWindow_Win32, PetscDrawResizeWindow_Win32, PetscDrawDestroy_Win32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, PetscDrawSetVisible_Win32}; 6325c6c1daeSBarry Smith 633d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDrawGetPopup_Win32(PetscDraw draw, PetscDraw *popup) 634d71ae5a4SJacob Faibussowitsch { 6354a5237bfSSatish Balay PetscDraw_Win32 *win = (PetscDraw_Win32 *)draw->data; 6364a5237bfSSatish Balay PetscBool flg = PETSC_TRUE; 6375c6c1daeSBarry Smith 6385c6c1daeSBarry Smith PetscFunctionBegin; 6399566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetBool(((PetscObject)draw)->options, ((PetscObject)draw)->prefix, "-draw_popup", &flg, NULL)); 6404a5237bfSSatish Balay if (flg) { 6419566063dSJacob Faibussowitsch PetscCall(PetscDrawCreate(PetscObjectComm((PetscObject)draw), NULL, NULL, win->x, win->y + win->h + 36, 220, 220, popup)); 6429566063dSJacob Faibussowitsch PetscCall(PetscDrawSetType(*popup, PETSC_DRAW_WIN32)); 6434a5237bfSSatish Balay draw->popup = *popup; 6444a5237bfSSatish Balay } else { 6454a5237bfSSatish Balay *popup = NULL; 6464a5237bfSSatish Balay } 6473ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6485c6c1daeSBarry Smith } 649d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscDrawCreate_Win32(PetscDraw draw) 650d71ae5a4SJacob Faibussowitsch { 6515c6c1daeSBarry Smith PetscDraw_Win32 *windraw; 6525c6c1daeSBarry Smith HANDLE hThread = NULL; 6535c6c1daeSBarry Smith WindowNode newnode; 6545c6c1daeSBarry Smith 6555c6c1daeSBarry Smith PetscFunctionBegin; 6569566063dSJacob Faibussowitsch PetscCall(PetscNew(&windraw)); 6575c6c1daeSBarry Smith draw->data = windraw; 6585c6c1daeSBarry Smith 6595c6c1daeSBarry Smith /* the following is temporary fix for initializing a global datastructure */ 660a297a907SKarl Rupp if (!g_hWindowListMutex) g_hWindowListMutex = CreateMutex(NULL, FALSE, NULL); 6619566063dSJacob Faibussowitsch PetscCall(PetscMemcpy(draw->ops, &DvOps, sizeof(DvOps))); 6625c6c1daeSBarry Smith 6635c6c1daeSBarry Smith windraw->hReadyEvent = CreateEvent(NULL, TRUE, FALSE, NULL); 6645c6c1daeSBarry Smith /* makes call to MessageLoopThread to creat window and attach a thread */ 66513d99558SMatthew G. Knepley CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)MessageLoopThread_Win32, draw, 0, (LPDWORD)hThread); 6665c6c1daeSBarry Smith CloseHandle(hThread); 6675c6c1daeSBarry Smith WaitForSingleObject(windraw->hReadyEvent, INFINITE); 6685c6c1daeSBarry Smith CloseHandle(windraw->hReadyEvent); 6695c6c1daeSBarry Smith WaitForSingleObject(g_hWindowListMutex, INFINITE); 6705c6c1daeSBarry Smith 6719566063dSJacob Faibussowitsch PetscCall(PetscNew(&newnode)); 6725c6c1daeSBarry Smith newnode->MouseListHead = NULL; 6735c6c1daeSBarry Smith newnode->MouseListTail = NULL; 6745c6c1daeSBarry Smith newnode->wnext = WindowListHead; 6755c6c1daeSBarry Smith newnode->wprev = NULL; 6765c6c1daeSBarry Smith newnode->hWnd = windraw->hWnd; 6776c4ed002SBarry Smith if (WindowListHead) WindowListHead->wprev = newnode; 6785c6c1daeSBarry Smith WindowListHead = newnode; 6795c6c1daeSBarry Smith windraw->hdc = GetDC(windraw->hWnd); 6805c6c1daeSBarry Smith 6815c6c1daeSBarry Smith windraw->stringheight = 10; 6825c6c1daeSBarry Smith windraw->stringwidth = 6; 6835c6c1daeSBarry Smith windraw->linewidth = 1; /* default pixel sizes of graphics until user changes them */ 6845c6c1daeSBarry Smith windraw->pointdiameter = 1; 6855c6c1daeSBarry Smith windraw->node = newnode; 6865c6c1daeSBarry Smith 6875c6c1daeSBarry Smith windraw->x = draw->x; 6885c6c1daeSBarry Smith windraw->y = draw->y; 6895c6c1daeSBarry Smith windraw->w = newnode->bitwidth = draw->w; 6905c6c1daeSBarry Smith windraw->h = newnode->bitheight = draw->h; 6915c6c1daeSBarry Smith 6925c6c1daeSBarry Smith /* Create and initialize primary graphics buffer */ 6935c6c1daeSBarry Smith newnode->Buffer = CreateCompatibleDC(windraw->hdc); 6945c6c1daeSBarry Smith newnode->BufferBit = CreateCompatibleBitmap(windraw->hdc, windraw->w, windraw->h); 6955c6c1daeSBarry Smith newnode->store = SelectObject(newnode->Buffer, newnode->BufferBit); 6965c6c1daeSBarry Smith ExtFloodFill(newnode->Buffer, 0, 0, COLOR_WINDOW, FLOODFILLBORDER); 6975c6c1daeSBarry Smith 6985c6c1daeSBarry Smith newnode->event = CreateEvent(NULL, TRUE, FALSE, NULL); 6995c6c1daeSBarry Smith newnode->DoubleBuffered = PETSC_FALSE; 7005c6c1daeSBarry Smith 7015c6c1daeSBarry Smith ReleaseDC(windraw->hWnd, windraw->hdc); 7025c6c1daeSBarry Smith ReleaseMutex(g_hWindowListMutex); 7033ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7045c6c1daeSBarry Smith } 7055c6c1daeSBarry Smith 7065c6c1daeSBarry Smith /* FUNCTION: PetscWndProc(HWND, unsigned, WORD, LONG) 7075c6c1daeSBarry Smith PURPOSE: Processes messages for the main window. 7085c6c1daeSBarry Smith WM_COMMAND - process the application menu 7095c6c1daeSBarry Smith WM_PAINT - Paint the main window 7105c6c1daeSBarry Smith WM_DESTROY - post a quit message and return */ 7115c6c1daeSBarry Smith 712d71ae5a4SJacob Faibussowitsch LRESULT CALLBACK PetscWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) 713d71ae5a4SJacob Faibussowitsch { 7147ae38d14SSatish Balay int wmId; 7155c6c1daeSBarry Smith 7165c6c1daeSBarry Smith switch (message) { 7175c6c1daeSBarry Smith HANDLE_MSG(hWnd, WM_PAINT, OnPaint_Win32); 7185c6c1daeSBarry Smith HANDLE_MSG(hWnd, WM_DESTROY, OnDestroy_Win32); 7195c6c1daeSBarry Smith case WM_COMMAND: 7205c6c1daeSBarry Smith wmId = LOWORD(wParam); 7215c6c1daeSBarry Smith /* Parse the menu selections:*/ 7225c6c1daeSBarry Smith switch (wmId) { 723d71ae5a4SJacob Faibussowitsch case IDM_EXIT: 724d71ae5a4SJacob Faibussowitsch DestroyWindow(hWnd); 725d71ae5a4SJacob Faibussowitsch break; 726d71ae5a4SJacob Faibussowitsch default: 727d71ae5a4SJacob Faibussowitsch return DefWindowProc(hWnd, message, wParam, lParam); 7285c6c1daeSBarry Smith } 7295c6c1daeSBarry Smith break; 730d71ae5a4SJacob Faibussowitsch case WM_LBUTTONUP: 731d71ae5a4SJacob Faibussowitsch MouseRecord_Win32(hWnd, PETSC_BUTTON_LEFT); 732d71ae5a4SJacob Faibussowitsch break; 733d71ae5a4SJacob Faibussowitsch case WM_RBUTTONUP: 734d71ae5a4SJacob Faibussowitsch MouseRecord_Win32(hWnd, PETSC_BUTTON_RIGHT); 735d71ae5a4SJacob Faibussowitsch break; 736d71ae5a4SJacob Faibussowitsch case WM_MBUTTONUP: 737d71ae5a4SJacob Faibussowitsch MouseRecord_Win32(hWnd, PETSC_BUTTON_CENTER); 738d71ae5a4SJacob Faibussowitsch break; 739d71ae5a4SJacob Faibussowitsch default: 740d71ae5a4SJacob Faibussowitsch return DefWindowProc(hWnd, message, wParam, lParam); 7415c6c1daeSBarry Smith } 742f9baa8adSSatish Balay return 0; 7435c6c1daeSBarry Smith } 7445c6c1daeSBarry Smith 745d71ae5a4SJacob Faibussowitsch static void OnPaint_Win32(HWND hWnd) 746d71ae5a4SJacob Faibussowitsch { 7475c6c1daeSBarry Smith PAINTSTRUCT ps; 7485c6c1daeSBarry Smith HDC hdc; 7495c6c1daeSBarry Smith WindowNode current = NULL; 7505c6c1daeSBarry Smith 7515c6c1daeSBarry Smith InvalidateRect(hWnd, NULL, TRUE); 7525c6c1daeSBarry Smith WaitForSingleObject(g_hWindowListMutex, INFINITE); 7535c6c1daeSBarry Smith current = WindowListHead; 7545c6c1daeSBarry Smith hdc = BeginPaint(hWnd, &ps); 7555c6c1daeSBarry Smith 7566c4ed002SBarry Smith while (current) { 7575c6c1daeSBarry Smith if (current->hWnd == hWnd) { 7585c6c1daeSBarry Smith /* flushes primary buffer to window */ 7599371c9d4SSatish Balay BitBlt(hdc, 0, 0, GetDeviceCaps(hdc, HORZRES), GetDeviceCaps(hdc, VERTRES), current->Buffer, 0, 0, SRCCOPY); 7605c6c1daeSBarry Smith 761be332245SKarl Rupp /* StretchBlt(hdc,0,0,w,h, 762be332245SKarl Rupp current->Buffer,0,0,current->bitwidth,current->bitheight,SRCCOPY); */ 7635c6c1daeSBarry Smith break; 7645c6c1daeSBarry Smith } 7655c6c1daeSBarry Smith current = current->wnext; 7665c6c1daeSBarry Smith } 7675c6c1daeSBarry Smith EndPaint(hWnd, &ps); 7685c6c1daeSBarry Smith ReleaseMutex(g_hWindowListMutex); 769f9baa8adSSatish Balay return; 7705c6c1daeSBarry Smith } 7715c6c1daeSBarry Smith 772d71ae5a4SJacob Faibussowitsch static PetscErrorCode MouseRecord_Win32(HWND hWnd, PetscDrawButton button) 773d71ae5a4SJacob Faibussowitsch { 7745c6c1daeSBarry Smith /* Called by all three mouse button actions 7755c6c1daeSBarry Smith Records needed mouse data in windows data structure */ 7765c6c1daeSBarry Smith WindowNode current = NULL; 7775c6c1daeSBarry Smith MouseNode newnode; 7785c6c1daeSBarry Smith POINT mousepos; 7795c6c1daeSBarry Smith 7805c6c1daeSBarry Smith PetscFunctionBegin; 7815c6c1daeSBarry Smith WaitForSingleObject(g_hWindowListMutex, INFINITE); 7825c6c1daeSBarry Smith current = WindowListHead; 7835c6c1daeSBarry Smith if (current->IsGetMouseOn == TRUE) { 7845c6c1daeSBarry Smith SetEvent(current->event); 7856c4ed002SBarry Smith while (current) { 7865c6c1daeSBarry Smith if (current->hWnd == hWnd) { 7879566063dSJacob Faibussowitsch PetscCall(PetscNew(&newnode)); 7885c6c1daeSBarry Smith newnode->Button = button; 7895c6c1daeSBarry Smith GetCursorPos(&mousepos); 7905c6c1daeSBarry Smith newnode->user.x = mousepos.x; 7915c6c1daeSBarry Smith newnode->user.y = mousepos.y; 7925c6c1daeSBarry Smith ScreenToClient(hWnd, &mousepos); 7935c6c1daeSBarry Smith newnode->phys.x = mousepos.x; 7945c6c1daeSBarry Smith newnode->phys.y = mousepos.y; 7955c6c1daeSBarry Smith if (!current->MouseListTail) { 7965c6c1daeSBarry Smith current->MouseListHead = newnode; 7975c6c1daeSBarry Smith current->MouseListTail = newnode; 7985c6c1daeSBarry Smith } else { 7995c6c1daeSBarry Smith current->MouseListTail->mnext = newnode; 8005c6c1daeSBarry Smith current->MouseListTail = newnode; 8015c6c1daeSBarry Smith } 8025c6c1daeSBarry Smith newnode->mnext = NULL; 8035c6c1daeSBarry Smith 8045c6c1daeSBarry Smith break; 8055c6c1daeSBarry Smith } 8065c6c1daeSBarry Smith current = current->wnext; 8075c6c1daeSBarry Smith } 8085c6c1daeSBarry Smith } 8095c6c1daeSBarry Smith ReleaseMutex(g_hWindowListMutex); 8103ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8115c6c1daeSBarry Smith } 8125c6c1daeSBarry Smith 813d71ae5a4SJacob Faibussowitsch static void OnDestroy_Win32(HWND hWnd) 814d71ae5a4SJacob Faibussowitsch { 8155c6c1daeSBarry Smith /* searches linked list of window data and frees corresponding memory */ 8165c6c1daeSBarry Smith WindowNode current; 8175c6c1daeSBarry Smith 8185c6c1daeSBarry Smith PetscFunctionBegin; 8195c6c1daeSBarry Smith WaitForSingleObject(g_hWindowListMutex, INFINITE); 8205c6c1daeSBarry Smith current = WindowListHead; 8215c6c1daeSBarry Smith 8225c6c1daeSBarry Smith SetEvent(current->event); 8236c4ed002SBarry Smith while (current) { 8245c6c1daeSBarry Smith if (current->hWnd == hWnd) { 8256c4ed002SBarry Smith if (current->wprev) current->wprev->wnext = current->wnext; 826a297a907SKarl Rupp else WindowListHead = current->wnext; 827a297a907SKarl Rupp if (current->MouseListHead) deletemouselist_Win32(current); 828a297a907SKarl Rupp else PetscFree(current); 8295c6c1daeSBarry Smith break; 8305c6c1daeSBarry Smith } 8315c6c1daeSBarry Smith current = current->wnext; 8325c6c1daeSBarry Smith } 8335c6c1daeSBarry Smith ReleaseMutex(g_hWindowListMutex); 8345c6c1daeSBarry Smith PostQuitMessage(0); 8355c6c1daeSBarry Smith PetscFunctionReturnVoid(); 8365c6c1daeSBarry Smith } 837