15c6c1daeSBarry Smith #include <petscsys.h> 2af0996ceSBarry Smith #include <petsc/private/drawimpl.h> 378ac5f8bSSatish Balay #include <../src/sys/classes/draw/impls/win32/win32draw.h> 45c6c1daeSBarry Smith 55c6c1daeSBarry Smith #define IDC_FOUR 109 65c6c1daeSBarry Smith #define IDI_FOUR 107 75c6c1daeSBarry Smith #define IDM_EXIT 105 85c6c1daeSBarry Smith #define IDR_POPUP 103 95c6c1daeSBarry Smith #define MAX_LOADSTRING 100 105c6c1daeSBarry Smith 115c6c1daeSBarry Smith #if !defined(SelectPen) 125c6c1daeSBarry Smith #define SelectPen(hdc, hpen) ((HPEN)SelectObject((hdc), (HGDIOBJ)(HPEN)(hpen))) 135c6c1daeSBarry Smith #endif 145c6c1daeSBarry Smith #if !defined(SelectFont) 155c6c1daeSBarry Smith #define SelectFont(hdc, hfont) ((HFONT)SelectObject((hdc), (HGDIOBJ)(HFONT)(hfont))) 165c6c1daeSBarry Smith #endif 175c6c1daeSBarry Smith #if !defined(SelectBrush) 185c6c1daeSBarry Smith #define SelectBrush(hdc, hbrush) ((HBRUSH)SelectObject((hdc), (HGDIOBJ)(HBRUSH)(hbrush))) 195c6c1daeSBarry Smith #endif 205c6c1daeSBarry Smith #if !defined(GetStockBrush) 215c6c1daeSBarry Smith #define GetStockBrush(i) ((HBRUSH)GetStockObject(i)) 225c6c1daeSBarry Smith #endif 235c6c1daeSBarry Smith 249371c9d4SSatish 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)))) 259371c9d4SSatish 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)))) 265c6c1daeSBarry Smith 275c6c1daeSBarry Smith HINSTANCE hInst; 285c6c1daeSBarry Smith HANDLE g_hWindowListMutex = NULL; 295c6c1daeSBarry Smith WindowNode WindowListHead = NULL; 305c6c1daeSBarry Smith 315c6c1daeSBarry Smith /* Hard coded color hue until hue.c works with this */ 325c6c1daeSBarry 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}; 335c6c1daeSBarry 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}; 345c6c1daeSBarry 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}; 355c6c1daeSBarry Smith 36da81f932SPierre Jolivet /* Forward declarations of functions included in this code module: */ 375c6c1daeSBarry Smith LRESULT CALLBACK PetscWndProc(HWND, UINT, WPARAM, LPARAM); 385c6c1daeSBarry Smith static PetscErrorCode TranslateColor_Win32(PetscDraw, int); 395c6c1daeSBarry Smith static PetscErrorCode AverageColorRectangle_Win32(PetscDraw, int, int, int, int); 405c6c1daeSBarry Smith static PetscErrorCode AverageColorTriangle_Win32(PetscDraw, int, int, int); 415c6c1daeSBarry Smith static PetscErrorCode deletemouselist_Win32(WindowNode); 425c6c1daeSBarry Smith static void OnPaint_Win32(HWND); 435c6c1daeSBarry Smith static void OnDestroy_Win32(HWND); 445c6c1daeSBarry Smith static PetscErrorCode MouseRecord_Win32(HWND, PetscDrawButton); 455c6c1daeSBarry Smith static PetscErrorCode PetscDrawGetPopup_Win32(PetscDraw, PetscDraw *); 465c6c1daeSBarry Smith 47d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDrawSetDoubleBuffer_Win32(PetscDraw draw) 48d71ae5a4SJacob Faibussowitsch { 495c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32 *)draw->data; 505c6c1daeSBarry Smith HDC hdc = GetDC(windraw->hWnd); 515c6c1daeSBarry Smith 525c6c1daeSBarry Smith PetscFunctionBegin; 535c6c1daeSBarry Smith windraw->node->DoubleBuffer = CreateCompatibleDC(hdc); 545c6c1daeSBarry Smith windraw->node->DoubleBufferBit = CreateCompatibleBitmap(hdc, windraw->w, windraw->h); 555c6c1daeSBarry Smith windraw->node->dbstore = SelectObject(windraw->node->DoubleBuffer, windraw->node->DoubleBufferBit); 565c6c1daeSBarry Smith /* Fill background of second buffer */ 575c6c1daeSBarry Smith ExtFloodFill(windraw->node->DoubleBuffer, 0, 0, COLOR_WINDOW, FLOODFILLBORDER); 58da81f932SPierre Jolivet /* Copy current buffer into second buffer and set window data as double buffered */ 599371c9d4SSatish Balay BitBlt(windraw->node->DoubleBuffer, 0, 0, windraw->w, windraw->h, windraw->node->Buffer, 0, 0, SRCCOPY); 605c6c1daeSBarry Smith 615c6c1daeSBarry Smith windraw->node->DoubleBuffered = PETSC_TRUE; 625c6c1daeSBarry Smith ReleaseDC(windraw->hWnd, hdc); 633ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 645c6c1daeSBarry Smith } 655c6c1daeSBarry Smith 66d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDrawFlush_Win32(PetscDraw draw) 67d71ae5a4SJacob Faibussowitsch { 685c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32 *)draw->data; 695c6c1daeSBarry Smith HDC hdc = GetDC(windraw->hWnd); 705c6c1daeSBarry Smith 715c6c1daeSBarry Smith PetscFunctionBegin; 725c6c1daeSBarry Smith /* flush double buffer into primary buffer */ 739371c9d4SSatish Balay BitBlt(windraw->node->Buffer, 0, 0, windraw->w, windraw->h, windraw->node->DoubleBuffer, 0, 0, SRCCOPY); 745c6c1daeSBarry Smith /* flush double buffer into window */ 759371c9d4SSatish Balay BitBlt(hdc, 0, 0, windraw->w, windraw->h, windraw->node->DoubleBuffer, 0, 0, SRCCOPY); 765c6c1daeSBarry Smith ReleaseDC(windraw->hWnd, hdc); 773ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 785c6c1daeSBarry Smith } 795c6c1daeSBarry Smith 80d71ae5a4SJacob Faibussowitsch static PetscErrorCode deletemouselist_Win32(WindowNode deletelist) 81d71ae5a4SJacob Faibussowitsch { 825c6c1daeSBarry Smith /* Called upon window close. Frees memory of linked list of stored mouse commands */ 835c6c1daeSBarry Smith MouseNode node; 845c6c1daeSBarry Smith 856c4ed002SBarry Smith while (deletelist->MouseListHead) { 865c6c1daeSBarry Smith node = deletelist->MouseListHead; 876c4ed002SBarry Smith if (deletelist->MouseListHead->mnext) deletelist->MouseListHead = deletelist->MouseListHead->mnext; 885c6c1daeSBarry Smith PetscFree(node); 895c6c1daeSBarry Smith } 905c6c1daeSBarry Smith deletelist->MouseListHead = deletelist->MouseListTail = NULL; 916c4ed002SBarry Smith if (deletelist->wprev) deletelist->wprev->wnext = deletelist->wnext; 926c4ed002SBarry Smith if (deletelist->wnext) deletelist->wnext->wprev = deletelist->wprev; 935c6c1daeSBarry Smith PetscFree(deletelist); 943ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 955c6c1daeSBarry Smith } 965c6c1daeSBarry Smith 97d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDrawGetMouseButton_Win32(PetscDraw draw, PetscDrawButton *button, PetscReal *x_user, PetscReal *y_user, PetscReal *x_phys, PetscReal *y_phys) 98d71ae5a4SJacob Faibussowitsch { 995c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32 *)draw->data; 1005c6c1daeSBarry Smith WindowNode current; 1015c6c1daeSBarry Smith MouseNode node = 0; 1025c6c1daeSBarry Smith 1035c6c1daeSBarry Smith PetscFunctionBegin; 1045c6c1daeSBarry Smith /* Make sure no other code is using the linked list at this moment */ 1055c6c1daeSBarry Smith WaitForSingleObject(g_hWindowListMutex, INFINITE); 1065c6c1daeSBarry Smith /* Look for the node that matches the window you are using */ 1075c6c1daeSBarry Smith current = WindowListHead; 1086c4ed002SBarry Smith while (current) { 1095c6c1daeSBarry Smith if (current->hWnd == windraw->hWnd) { 1105c6c1daeSBarry Smith current->IsGetMouseOn = TRUE; 1115c6c1daeSBarry Smith break; 112a297a907SKarl Rupp } else current = current->wnext; 1135c6c1daeSBarry Smith } 114a5b23f4aSJose E. Roman /* If no actions have occurred, wait for one */ 1155c6c1daeSBarry Smith node = current->MouseListHead; 1165c6c1daeSBarry Smith if (!node) { 1175c6c1daeSBarry Smith ReleaseMutex(g_hWindowListMutex); 1185c6c1daeSBarry Smith WaitForSingleObject(current->event, INFINITE); 1195c6c1daeSBarry Smith WaitForSingleObject(g_hWindowListMutex, INFINITE); 1205c6c1daeSBarry Smith } 1215c6c1daeSBarry Smith /* once we have the information, assign the pointers to it */ 1225c6c1daeSBarry Smith *button = current->MouseListHead->Button; 1235c6c1daeSBarry Smith *x_user = current->MouseListHead->user.x; 1245c6c1daeSBarry Smith *y_user = current->MouseListHead->user.y; 1255c6c1daeSBarry Smith /* optional arguments */ 1265c6c1daeSBarry Smith if (x_phys) *x_phys = current->MouseListHead->phys.x; 1275c6c1daeSBarry Smith if (y_phys) *y_phys = current->MouseListHead->phys.y; 1285c6c1daeSBarry Smith /* remove set of information from sub linked-list, delete the node */ 1295c6c1daeSBarry Smith current->MouseListHead = current->MouseListHead->mnext; 1305c6c1daeSBarry Smith if (!current->MouseListHead) { 1315c6c1daeSBarry Smith ResetEvent(current->event); 1325c6c1daeSBarry Smith current->MouseListTail = NULL; 1335c6c1daeSBarry Smith } 1345c6c1daeSBarry Smith if (node) PetscFree(node); 1355c6c1daeSBarry Smith 1365c6c1daeSBarry Smith /* Release mutex so that other code can use 1375c6c1daeSBarry Smith the linked list now that we are done with it */ 1385c6c1daeSBarry Smith ReleaseMutex(g_hWindowListMutex); 1393ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1405c6c1daeSBarry Smith } 1415c6c1daeSBarry Smith 142d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDrawPause_Win32(PetscDraw draw) 143d71ae5a4SJacob Faibussowitsch { 1445c6c1daeSBarry Smith PetscFunctionBegin; 1455c6c1daeSBarry Smith PetscSleep(draw->pause); 1463ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1475c6c1daeSBarry Smith } 1485c6c1daeSBarry Smith 149d71ae5a4SJacob Faibussowitsch static PetscErrorCode TranslateColor_Win32(PetscDraw draw, int color) 150d71ae5a4SJacob Faibussowitsch { 1515c6c1daeSBarry Smith /* Maps single color value into the RGB colors in our tables */ 1525c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32 *)draw->data; 1535c6c1daeSBarry Smith windraw->currentcolor = RGB(RedMap[color], GreenMap[color], BlueMap[color]); 1543ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 1555c6c1daeSBarry Smith } 1565c6c1daeSBarry Smith 157d71ae5a4SJacob Faibussowitsch static PetscErrorCode AverageColorRectangle_Win32(PetscDraw draw, int c1, int c2, int c3, int c4) 158d71ae5a4SJacob Faibussowitsch { 1595c6c1daeSBarry Smith /* Averages colors given at points of rectangle and sets color from color table 1605c6c1daeSBarry Smith will be changed once the color gradient problem is worked out */ 1615c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32 *)draw->data; 1629371c9d4SSatish 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)); 1633ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 1645c6c1daeSBarry Smith } 1655c6c1daeSBarry Smith 166d71ae5a4SJacob Faibussowitsch static PetscErrorCode AverageColorTriangle_Win32(PetscDraw draw, int c1, int c2, int c3) 167d71ae5a4SJacob Faibussowitsch { 1685c6c1daeSBarry Smith /* Averages colors given at points of rectangle and sets color from color table 1695c6c1daeSBarry Smith will be changed once the color gradient problem is worked out */ 1705c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32 *)draw->data; 1719371c9d4SSatish 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); 1723ba16761SJacob Faibussowitsch return PETSC_SUCCESS; 1735c6c1daeSBarry Smith } 1745c6c1daeSBarry Smith 175d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDrawRectangle_Win32(PetscDraw draw, PetscReal xl, PetscReal yl, PetscReal xr, PetscReal yr, int c1, int c2, int c3, int c4) 176d71ae5a4SJacob Faibussowitsch { 1775c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32 *)draw->data; 1785c6c1daeSBarry Smith HBRUSH hbrush; 1795c6c1daeSBarry Smith RECT rect; 1805c6c1daeSBarry Smith int x1, yone, x2, y2; 1815c6c1daeSBarry Smith HDC hdc; 1825c6c1daeSBarry Smith 1835c6c1daeSBarry Smith PetscFunctionBegin; 1845c6c1daeSBarry Smith x1 = XTRANS(draw, windraw, xl); 1855c6c1daeSBarry Smith x2 = XTRANS(draw, windraw, xr); 1865c6c1daeSBarry Smith yone = YTRANS(draw, windraw, yl); 1875c6c1daeSBarry Smith y2 = YTRANS(draw, windraw, yr); 1885c6c1daeSBarry Smith SetRect(&rect, x1, y2, x2, yone); 189a297a907SKarl Rupp if (c1 == c2 && c2 == c3 && c3 == c4) TranslateColor_Win32(draw, c1); 190a297a907SKarl Rupp else AverageColorRectangle_Win32(draw, c1, c2, c3, c4); 1915c6c1daeSBarry Smith hbrush = CreateSolidBrush(windraw->currentcolor); 1925c6c1daeSBarry Smith 193a297a907SKarl Rupp if (windraw->node->DoubleBuffered) hdc = windraw->node->DoubleBuffer; 194a297a907SKarl Rupp else hdc = windraw->node->Buffer; 195a297a907SKarl Rupp 1965c6c1daeSBarry Smith FillRect(hdc, &rect, hbrush); 1975c6c1daeSBarry Smith /* Forces a WM_PAINT message and erases background */ 1985c6c1daeSBarry Smith InvalidateRect(windraw->hWnd, NULL, TRUE); 1995c6c1daeSBarry Smith UpdateWindow(windraw->hWnd); 2003ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2015c6c1daeSBarry Smith } 2025c6c1daeSBarry Smith 203d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDrawLine_Win32(PetscDraw draw, PetscReal xl, PetscReal yl, PetscReal xr, PetscReal yr, int color) 204d71ae5a4SJacob Faibussowitsch { 2055c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32 *)draw->data; 2065c6c1daeSBarry Smith HPEN hpen; 2075c6c1daeSBarry Smith int x1, yone, x2, y2; 2085c6c1daeSBarry Smith HDC hdc; 2095c6c1daeSBarry Smith 2105c6c1daeSBarry Smith PetscFunctionBegin; 2115c6c1daeSBarry Smith TranslateColor_Win32(draw, color); 2129371c9d4SSatish Balay x1 = XTRANS(draw, windraw, xl); 2139371c9d4SSatish Balay x2 = XTRANS(draw, windraw, xr); 2149371c9d4SSatish Balay yone = YTRANS(draw, windraw, yl); 2159371c9d4SSatish Balay y2 = YTRANS(draw, windraw, yr); 2165c6c1daeSBarry Smith hpen = CreatePen(PS_SOLID, windraw->linewidth, windraw->currentcolor); 217a297a907SKarl Rupp if (windraw->node->DoubleBuffered) hdc = windraw->node->DoubleBuffer; 218a297a907SKarl Rupp else hdc = windraw->node->Buffer; 219a297a907SKarl Rupp 2205c6c1daeSBarry Smith SelectPen(hdc, hpen); 2215c6c1daeSBarry Smith MoveToEx(hdc, x1, yone, NULL); 2225c6c1daeSBarry Smith LineTo(hdc, x2, y2); 2235c6c1daeSBarry Smith /* Forces a WM_PAINT message and erases background */ 2245c6c1daeSBarry Smith InvalidateRect(windraw->hWnd, NULL, TRUE); 2255c6c1daeSBarry Smith UpdateWindow(windraw->hWnd); 2263ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2275c6c1daeSBarry Smith } 2285c6c1daeSBarry Smith 229d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDrawLineSetWidth_Win32(PetscDraw draw, PetscReal width) 230d71ae5a4SJacob Faibussowitsch { 2315c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32 *)draw->data; 2325c6c1daeSBarry Smith int averagesize, finalwidth; 2335c6c1daeSBarry Smith RECT rect; 2345c6c1daeSBarry Smith 2355c6c1daeSBarry Smith PetscFunctionBegin; 2365c6c1daeSBarry Smith GetClientRect(windraw->hWnd, &rect); 2375c6c1daeSBarry Smith averagesize = ((rect.right - rect.left) + (rect.bottom - rect.top)) / 2; 23877b4d14cSPeter Brune finalwidth = (int)PetscFloorReal(averagesize * width); 239a297a907SKarl Rupp if (finalwidth < 1) finalwidth = 1; /* minimum size PetscDrawLine can except */ 240a297a907SKarl Rupp 2415c6c1daeSBarry Smith windraw->linewidth = finalwidth; 2423ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2435c6c1daeSBarry Smith } 2445c6c1daeSBarry Smith 245d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDrawLineGetWidth_Win32(PetscDraw draw, PetscReal *width) 246d71ae5a4SJacob Faibussowitsch { 2475c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32 *)draw->data; 2485c6c1daeSBarry Smith 2495c6c1daeSBarry Smith PetscFunctionBegin; 2505c6c1daeSBarry Smith *width = (PetscReal)windraw->linewidth; 2513ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2525c6c1daeSBarry Smith } 2535c6c1daeSBarry Smith 254d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDrawPoint_Win32(PetscDraw draw, PetscReal x, PetscReal y, int color) 255d71ae5a4SJacob Faibussowitsch { 2565c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32 *)draw->data; 2575c6c1daeSBarry Smith HBRUSH hbrush; 2585c6c1daeSBarry Smith HRGN hrgn; 2595c6c1daeSBarry Smith int radius; 2605c6c1daeSBarry Smith int x1, yone; 2615c6c1daeSBarry Smith HDC hdc; 2625c6c1daeSBarry Smith 2635c6c1daeSBarry Smith PetscFunctionBegin; 2645c6c1daeSBarry Smith TranslateColor_Win32(draw, color); 2655c6c1daeSBarry Smith x1 = XTRANS(draw, windraw, x); 2665c6c1daeSBarry Smith yone = YTRANS(draw, windraw, y); 2675c6c1daeSBarry Smith hbrush = CreateSolidBrush(windraw->currentcolor); 268a297a907SKarl Rupp if (windraw->node->DoubleBuffered) hdc = windraw->node->DoubleBuffer; 269a297a907SKarl Rupp else hdc = windraw->node->Buffer; 270a297a907SKarl Rupp 2715c6c1daeSBarry Smith /* desired size is one logical pixel so just turn it on */ 272a297a907SKarl Rupp if (windraw->pointdiameter == 1) SetPixelV(hdc, x1, yone, windraw->currentcolor); 273a297a907SKarl Rupp else { 2745c6c1daeSBarry Smith /* draw point around position determined */ 2755c6c1daeSBarry Smith radius = windraw->pointdiameter / 2; /* integer division */ 2765c6c1daeSBarry Smith hrgn = CreateEllipticRgn(x1 - radius, yone - radius, x1 + radius, yone + radius); 2775c6c1daeSBarry Smith FillRgn(hdc, hrgn, hbrush); 2785c6c1daeSBarry Smith } 2795c6c1daeSBarry Smith /* Forces a WM_PAINT and erases background */ 2805c6c1daeSBarry Smith InvalidateRect(windraw->hWnd, NULL, TRUE); 2815c6c1daeSBarry Smith UpdateWindow(windraw->hWnd); 2823ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2835c6c1daeSBarry Smith } 2845c6c1daeSBarry Smith 285d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDrawPointSetSize_Win32(PetscDraw draw, PetscReal width) 286d71ae5a4SJacob Faibussowitsch { 2875c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32 *)draw->data; 2885c6c1daeSBarry Smith int averagesize, diameter; 2895c6c1daeSBarry Smith RECT rect; 2905c6c1daeSBarry Smith 2915c6c1daeSBarry Smith PetscFunctionBegin; 2925c6c1daeSBarry Smith GetClientRect(windraw->hWnd, &rect); 2935c6c1daeSBarry Smith averagesize = ((rect.right - rect.left) + (rect.bottom - rect.top)) / 2; 29477b4d14cSPeter Brune diameter = (int)PetscFloorReal(averagesize * width); 2955c6c1daeSBarry Smith if (diameter < 1) diameter = 1; 2965c6c1daeSBarry Smith windraw->pointdiameter = diameter; 2973ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2985c6c1daeSBarry Smith } 2995c6c1daeSBarry Smith 300d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDrawString_Win32(PetscDraw draw, PetscReal x, PetscReal y, int color, const char *text) 301d71ae5a4SJacob Faibussowitsch { 3025c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32 *)draw->data; 3035c6c1daeSBarry Smith RECT r; 3045c6c1daeSBarry Smith HFONT hfont; 3055c6c1daeSBarry Smith LOGFONT logfont; 3065c6c1daeSBarry Smith int x1, yone; 3075c6c1daeSBarry Smith HDC hdc; 3085c6c1daeSBarry Smith 3095c6c1daeSBarry Smith PetscFunctionBegin; 3105c6c1daeSBarry Smith x1 = XTRANS(draw, windraw, x); 3115c6c1daeSBarry Smith yone = YTRANS(draw, windraw, y); 3125c6c1daeSBarry Smith r.bottom = yone; 3135c6c1daeSBarry Smith r.left = x1; 3145c6c1daeSBarry Smith r.right = x1 + 1; 3155c6c1daeSBarry Smith r.top = yone + 1; 316a297a907SKarl Rupp 3175c6c1daeSBarry Smith logfont.lfHeight = windraw->stringheight; 3185c6c1daeSBarry Smith logfont.lfWidth = windraw->stringwidth; 3195c6c1daeSBarry Smith logfont.lfEscapement = 0; 3205c6c1daeSBarry Smith logfont.lfOrientation = 0; 3215c6c1daeSBarry Smith logfont.lfCharSet = 0; 3225c6c1daeSBarry Smith logfont.lfClipPrecision = 0; 3235c6c1daeSBarry Smith logfont.lfItalic = 0; 3245c6c1daeSBarry Smith logfont.lfOutPrecision = 0; 3255c6c1daeSBarry Smith logfont.lfPitchAndFamily = DEFAULT_PITCH; 3265c6c1daeSBarry Smith logfont.lfQuality = DEFAULT_QUALITY; 3275c6c1daeSBarry Smith logfont.lfStrikeOut = 0; 3285c6c1daeSBarry Smith logfont.lfUnderline = 0; 3295c6c1daeSBarry Smith logfont.lfWeight = FW_NORMAL; 330a297a907SKarl Rupp 3315c6c1daeSBarry Smith hfont = CreateFontIndirect(&logfont); 3325c6c1daeSBarry Smith TranslateColor_Win32(draw, color); 333a297a907SKarl Rupp if (windraw->node->DoubleBuffered) hdc = windraw->node->DoubleBuffer; 334a297a907SKarl Rupp else hdc = windraw->node->Buffer; 335a297a907SKarl Rupp 3365c6c1daeSBarry Smith SelectFont(hdc, hfont); 3375c6c1daeSBarry Smith SetTextColor(hdc, windraw->currentcolor); 3385c6c1daeSBarry Smith DrawText(hdc, text, lstrlen(text), &r, DT_NOCLIP); 3395c6c1daeSBarry Smith DeleteObject(hfont); 3405c6c1daeSBarry Smith /* Forces a WM_PAINT message and erases background */ 3415c6c1daeSBarry Smith InvalidateRect(windraw->hWnd, NULL, TRUE); 3425c6c1daeSBarry Smith UpdateWindow(windraw->hWnd); 3433ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3445c6c1daeSBarry Smith } 3455c6c1daeSBarry Smith 346d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDrawStringVertical_Win32(PetscDraw draw, PetscReal x, PetscReal y, int color, const char *text) 347d71ae5a4SJacob Faibussowitsch { 3485c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32 *)draw->data; 3495c6c1daeSBarry Smith RECT r; 3505c6c1daeSBarry Smith HFONT hfont; 3515c6c1daeSBarry Smith LOGFONT logfont; 3525c6c1daeSBarry Smith int x1, yone; 3535c6c1daeSBarry Smith HDC hdc; 3545c6c1daeSBarry Smith 3555c6c1daeSBarry Smith PetscFunctionBegin; 3565c6c1daeSBarry Smith x1 = XTRANS(draw, windraw, x); 3575c6c1daeSBarry Smith yone = YTRANS(draw, windraw, y); 3585c6c1daeSBarry Smith r.left = x1; 3595c6c1daeSBarry Smith r.bottom = yone + 30; 3605c6c1daeSBarry Smith r.right = x1 + 1; 3615c6c1daeSBarry Smith r.top = yone - 30; 362a297a907SKarl Rupp 3639c89aa79SPierre Jolivet logfont.lfEscapement = 2700; /* Causes vertical text drawing */ 3645c6c1daeSBarry Smith logfont.lfHeight = windraw->stringheight; 3655c6c1daeSBarry Smith logfont.lfWidth = windraw->stringwidth; 3665c6c1daeSBarry Smith logfont.lfOrientation = 0; 3675c6c1daeSBarry Smith logfont.lfCharSet = DEFAULT_CHARSET; 3685c6c1daeSBarry Smith logfont.lfClipPrecision = 0; 3695c6c1daeSBarry Smith logfont.lfItalic = 0; 3705c6c1daeSBarry Smith logfont.lfOutPrecision = 0; 3715c6c1daeSBarry Smith logfont.lfPitchAndFamily = DEFAULT_PITCH; 3725c6c1daeSBarry Smith logfont.lfQuality = DEFAULT_QUALITY; 3735c6c1daeSBarry Smith logfont.lfStrikeOut = 0; 3745c6c1daeSBarry Smith logfont.lfUnderline = 0; 3755c6c1daeSBarry Smith logfont.lfWeight = FW_NORMAL; 376a297a907SKarl Rupp 3775c6c1daeSBarry Smith hfont = CreateFontIndirect(&logfont); 3785c6c1daeSBarry Smith TranslateColor_Win32(draw, color); 379a297a907SKarl Rupp if (windraw->node->DoubleBuffered) hdc = windraw->node->DoubleBuffer; 380a297a907SKarl Rupp else hdc = windraw->node->Buffer; 381a297a907SKarl Rupp 3825c6c1daeSBarry Smith SelectFont(hdc, hfont); 3835c6c1daeSBarry Smith SetTextColor(hdc, windraw->currentcolor); 3845c6c1daeSBarry Smith DrawText(hdc, text, lstrlen(text), &r, DT_NOCLIP | DT_SINGLELINE); 3855c6c1daeSBarry Smith DeleteObject(hfont); 3865c6c1daeSBarry Smith /* Forces a WM_PAINT message and erases background */ 3875c6c1daeSBarry Smith InvalidateRect(windraw->hWnd, NULL, TRUE); 3885c6c1daeSBarry Smith UpdateWindow(windraw->hWnd); 3893ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3905c6c1daeSBarry Smith } 3915c6c1daeSBarry Smith 392d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDrawStringSetSize_Win32(PetscDraw draw, PetscReal width, PetscReal height) 393d71ae5a4SJacob Faibussowitsch { 3945c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32 *)draw->data; 3955c6c1daeSBarry Smith int w, h; 3965c6c1daeSBarry Smith 3975c6c1daeSBarry Smith PetscFunctionBegin; 398*f4f49eeaSPierre Jolivet w = (int)(windraw->w * width * (draw->port_xr - draw->port_xl) / (draw->coor_xr - draw->coor_xl)); 399*f4f49eeaSPierre Jolivet h = (int)(windraw->h * height * (draw->port_yr - draw->port_yl) / (draw->coor_yr - draw->coor_yl)); 4005c6c1daeSBarry Smith if (h < 1) h = 1; 4015c6c1daeSBarry Smith if (w < 1) w = 1; 4025c6c1daeSBarry Smith windraw->stringheight = h; 4035c6c1daeSBarry Smith windraw->stringwidth = w; 4043ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4055c6c1daeSBarry Smith } 406d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDrawStringGetSize_Win32(PetscDraw draw, PetscReal *width, PetscReal *height) 407d71ae5a4SJacob Faibussowitsch { 4085c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32 *)draw->data; 4095c6c1daeSBarry Smith double scaleX = (draw->coor_xr - draw->coor_xl) / (draw->w) * (draw->port_xr - draw->port_xl); 4105c6c1daeSBarry Smith double scaleY = (draw->coor_yr - draw->coor_yl) / (draw->h) * (draw->port_yr - draw->port_yl); 4115c6c1daeSBarry Smith 4125c6c1daeSBarry Smith PetscFunctionBegin; 4134a5237bfSSatish Balay if (height) *height = (double)windraw->stringheight * scaleY; 4144a5237bfSSatish Balay if (width) *width = (double)windraw->stringwidth * scaleX; 4153ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4165c6c1daeSBarry Smith } 4175c6c1daeSBarry Smith 418d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDrawResizeWindow_Win32(PetscDraw draw, int w, int h) 419d71ae5a4SJacob Faibussowitsch { 4205c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32 *)draw->data; 4215c6c1daeSBarry Smith RECT r; 4225c6c1daeSBarry Smith 4235c6c1daeSBarry Smith PetscFunctionBegin; 4245c6c1daeSBarry Smith GetWindowRect(windraw->hWnd, &r); 4255c6c1daeSBarry Smith MoveWindow(windraw->hWnd, r.left, r.top, (int)w, (int)h, TRUE); 4265c6c1daeSBarry Smith /* set all variable dealing with window dimensions */ 4275c6c1daeSBarry Smith windraw->node->bitheight = windraw->h = draw->h = h; 4285c6c1daeSBarry Smith windraw->node->bitwidth = windraw->w = draw->w = w; 4295c6c1daeSBarry Smith /* set up graphic buffers with the new size of window */ 4305c6c1daeSBarry Smith SetBitmapDimensionEx(windraw->node->BufferBit, w, h, NULL); 431a297a907SKarl Rupp if (windraw->node->DoubleBuffered) SetBitmapDimensionEx(windraw->node->DoubleBufferBit, w, h, NULL); 4325c6c1daeSBarry Smith windraw->haveresized = PETSC_TRUE; 4333ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4345c6c1daeSBarry Smith } 4355c6c1daeSBarry Smith 436d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDrawCheckResizedWindow_Win32(PetscDraw draw) 437d71ae5a4SJacob Faibussowitsch { 4385c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32 *)draw->data; 4395c6c1daeSBarry Smith 4405c6c1daeSBarry Smith PetscFunctionBegin; 44111cc89d2SBarry Smith PetscCheck(windraw->haveresized != 1, PETSC_COMM_SELF, PETSC_ERR_SUP, "No support for resizing windows on Microsoft Windows"); 4423ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4435c6c1daeSBarry Smith } 4445c6c1daeSBarry Smith 445d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDrawSetTitle_Win32(PetscDraw draw, const char title[]) 446d71ae5a4SJacob Faibussowitsch { 4475c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32 *)draw->data; 4485c6c1daeSBarry Smith 4495c6c1daeSBarry Smith PetscFunctionBegin; 4505c6c1daeSBarry Smith SetWindowText(windraw->hWnd, title); 4513ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4525c6c1daeSBarry Smith } 4535c6c1daeSBarry Smith 454d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDrawClear_Win32(PetscDraw draw) 455d71ae5a4SJacob Faibussowitsch { 4565c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32 *)draw->data; 4575c6c1daeSBarry Smith 4585c6c1daeSBarry Smith PetscFunctionBegin; 4595c6c1daeSBarry Smith /* clear primary buffer */ 4605c6c1daeSBarry Smith ExtFloodFill(windraw->node->Buffer, 0, 0, COLOR_WINDOW, FLOODFILLBORDER); 4615c6c1daeSBarry Smith /* if exists clear secondary buffer */ 462a297a907SKarl Rupp if (windraw->node->DoubleBuffered) ExtFloodFill(windraw->node->DoubleBuffer, 0, 0, COLOR_WINDOW, FLOODFILLBORDER); 463a297a907SKarl Rupp 4645c6c1daeSBarry Smith /* force WM_PAINT message so cleared buffer will show */ 4655c6c1daeSBarry Smith InvalidateRect(windraw->hWnd, NULL, TRUE); 4665c6c1daeSBarry Smith UpdateWindow(windraw->hWnd); 4673ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4685c6c1daeSBarry Smith } 4695c6c1daeSBarry Smith 470d71ae5a4SJacob 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) 471d71ae5a4SJacob Faibussowitsch { 4725c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32 *)draw->data; 4735c6c1daeSBarry Smith HBRUSH hbrush; 4745c6c1daeSBarry Smith HPEN hpen; 4755c6c1daeSBarry Smith int p1x, p1y, p2x, p2y, p3x, p3y; 4765c6c1daeSBarry Smith HDC bit; 4775c6c1daeSBarry Smith 4785c6c1daeSBarry Smith PetscFunctionBegin; 4795c6c1daeSBarry Smith AverageColorTriangle_Win32(draw, c1, c2, c3); 4805c6c1daeSBarry Smith hbrush = CreateSolidBrush(windraw->currentcolor); 4815c6c1daeSBarry Smith hpen = CreatePen(PS_SOLID, 0, windraw->currentcolor); 4825c6c1daeSBarry Smith p1x = XTRANS(draw, windraw, x1); 4835c6c1daeSBarry Smith p2x = XTRANS(draw, windraw, x2); 4845c6c1daeSBarry Smith p3x = XTRANS(draw, windraw, x3); 4855c6c1daeSBarry Smith p1y = YTRANS(draw, windraw, yone); 4865c6c1daeSBarry Smith p2y = YTRANS(draw, windraw, y2); 4875c6c1daeSBarry Smith p3y = YTRANS(draw, windraw, y3); 4885c6c1daeSBarry Smith 489a297a907SKarl Rupp if (windraw->node->DoubleBuffered) bit = windraw->node->DoubleBuffer; 490a297a907SKarl Rupp else bit = windraw->node->Buffer; 491a297a907SKarl Rupp 4925c6c1daeSBarry Smith BeginPath(bit); 4935c6c1daeSBarry Smith MoveToEx(bit, p1x, p1y, NULL); 4945c6c1daeSBarry Smith LineTo(bit, p2x, p2y); 4955c6c1daeSBarry Smith LineTo(bit, p3x, p3y); 4965c6c1daeSBarry Smith LineTo(bit, p1x, p1y); 4975c6c1daeSBarry Smith EndPath(bit); 4985c6c1daeSBarry Smith SelectPen(bit, hpen); 4995c6c1daeSBarry Smith SelectBrush(bit, hbrush); 5005c6c1daeSBarry Smith StrokeAndFillPath(bit); 5015c6c1daeSBarry Smith /* Forces a WM_PAINT message and erases background */ 5025c6c1daeSBarry Smith InvalidateRect(windraw->hWnd, NULL, TRUE); 5035c6c1daeSBarry Smith UpdateWindow(windraw->hWnd); 5043ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5055c6c1daeSBarry Smith } 5065c6c1daeSBarry Smith 507bb09dc67SDuncan Campbell static PetscErrorCode PetscDrawSetVisible_Win32(PetscDraw draw, PetscBool visible) 508bb09dc67SDuncan Campbell { 509bb09dc67SDuncan Campbell PetscDraw_Win32 *windraw = (PetscDraw_Win32 *)draw->data; 510bb09dc67SDuncan Campbell 511bb09dc67SDuncan Campbell PetscFunctionBegin; 512bb09dc67SDuncan Campbell ShowWindow(windraw->hWnd, visible ? SW_SHOWNA : SW_HIDE); 513bb09dc67SDuncan Campbell PetscFunctionReturn(PETSC_SUCCESS); 514bb09dc67SDuncan Campbell } 515bb09dc67SDuncan Campbell 516d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDrawDestroy_Win32(PetscDraw draw) 517d71ae5a4SJacob Faibussowitsch { 5185c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32 *)draw->data; 5195c6c1daeSBarry Smith 5205c6c1daeSBarry Smith PetscFunctionBegin; 5215c6c1daeSBarry Smith SendMessage(windraw->hWnd, WM_DESTROY, 0, 0); 52250c74209SLisandro Dalcin PetscFree(draw->data); 5233ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5245c6c1daeSBarry Smith } 5255c6c1daeSBarry Smith 526ba38deedSJacob Faibussowitsch static void MessageLoopThread_Win32(PetscDraw draw) 527d71ae5a4SJacob Faibussowitsch { 5285c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32 *)draw->data; 5295c6c1daeSBarry Smith MSG msg; 5305c6c1daeSBarry Smith HWND hWnd = NULL; 531fad2a674SVolker const char classname[] = "PETSc Window Class"; 5325c6c1daeSBarry Smith WNDCLASSEX wclass; 5335c6c1daeSBarry Smith LPVOID lpMsgBuf; 5345c6c1daeSBarry Smith 5355c6c1daeSBarry Smith /* initialize window class parameters */ 5365c6c1daeSBarry Smith wclass.cbSize = sizeof(WNDCLASSEX); 5375c6c1daeSBarry Smith wclass.style = CS_SAVEBITS | CS_HREDRAW | CS_VREDRAW; 5385c6c1daeSBarry Smith wclass.lpfnWndProc = (WNDPROC)PetscWndProc; 5395c6c1daeSBarry Smith wclass.cbClsExtra = 0; 5405c6c1daeSBarry Smith wclass.cbWndExtra = 0; 5415c6c1daeSBarry Smith wclass.hInstance = NULL; 5425c6c1daeSBarry Smith wclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); 5435c6c1daeSBarry Smith wclass.hCursor = LoadCursor(NULL, IDC_ARROW); 5445c6c1daeSBarry Smith wclass.hbrBackground = GetStockBrush(WHITE_BRUSH); 5455c6c1daeSBarry Smith wclass.lpszMenuName = NULL; 5465c6c1daeSBarry Smith wclass.lpszClassName = classname; 5475c6c1daeSBarry Smith wclass.hIconSm = NULL; 5485c6c1daeSBarry Smith 5495c6c1daeSBarry Smith RegisterClassEx(&wclass); 5505c6c1daeSBarry Smith 5519371c9d4SSatish Balay hWnd = CreateWindowEx(0, classname, NULL, WS_OVERLAPPEDWINDOW, draw->x, draw->y, draw->w, draw->h, NULL, NULL, hInst, NULL); 5525c6c1daeSBarry Smith 5535c6c1daeSBarry Smith if (!hWnd) { 554fad2a674SVolker lpMsgBuf = (LPVOID) "Window Not Successfully Created"; 5555c6c1daeSBarry Smith MessageBox(NULL, (LPCTSTR)lpMsgBuf, "Error", MB_OK | MB_ICONINFORMATION); 5565c6c1daeSBarry Smith LocalFree(lpMsgBuf); 5575c6c1daeSBarry Smith exit(0); 5585c6c1daeSBarry Smith } 5595c6c1daeSBarry Smith windraw->hWnd = hWnd; 5605c6c1daeSBarry Smith /* display and update new window */ 5615c6c1daeSBarry Smith ShowWindow(hWnd, SW_SHOWNORMAL); 5625c6c1daeSBarry Smith UpdateWindow(hWnd); 5635c6c1daeSBarry Smith SetEvent(windraw->hReadyEvent); 5645c6c1daeSBarry Smith 5655c6c1daeSBarry Smith while (GetMessage(&msg, hWnd, 0, 0)) { 5665c6c1daeSBarry Smith TranslateMessage(&msg); 5675c6c1daeSBarry Smith DispatchMessage(&msg); 5685c6c1daeSBarry Smith } 569f9baa8adSSatish Balay return; 5705c6c1daeSBarry Smith } 5715c6c1daeSBarry Smith 572bb09dc67SDuncan 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}; 5735c6c1daeSBarry Smith 574d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscDrawGetPopup_Win32(PetscDraw draw, PetscDraw *popup) 575d71ae5a4SJacob Faibussowitsch { 5764a5237bfSSatish Balay PetscDraw_Win32 *win = (PetscDraw_Win32 *)draw->data; 5774a5237bfSSatish Balay PetscBool flg = PETSC_TRUE; 5785c6c1daeSBarry Smith 5795c6c1daeSBarry Smith PetscFunctionBegin; 5809566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetBool(((PetscObject)draw)->options, ((PetscObject)draw)->prefix, "-draw_popup", &flg, NULL)); 5814a5237bfSSatish Balay if (flg) { 5829566063dSJacob Faibussowitsch PetscCall(PetscDrawCreate(PetscObjectComm((PetscObject)draw), NULL, NULL, win->x, win->y + win->h + 36, 220, 220, popup)); 5839566063dSJacob Faibussowitsch PetscCall(PetscDrawSetType(*popup, PETSC_DRAW_WIN32)); 5844a5237bfSSatish Balay draw->popup = *popup; 5854a5237bfSSatish Balay } else { 5864a5237bfSSatish Balay *popup = NULL; 5874a5237bfSSatish Balay } 5883ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5895c6c1daeSBarry Smith } 590d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PetscDrawCreate_Win32(PetscDraw draw) 591d71ae5a4SJacob Faibussowitsch { 5925c6c1daeSBarry Smith PetscDraw_Win32 *windraw; 5935c6c1daeSBarry Smith HANDLE hThread = NULL; 5945c6c1daeSBarry Smith WindowNode newnode; 5955c6c1daeSBarry Smith 5965c6c1daeSBarry Smith PetscFunctionBegin; 5979566063dSJacob Faibussowitsch PetscCall(PetscNew(&windraw)); 5985c6c1daeSBarry Smith draw->data = windraw; 5995c6c1daeSBarry Smith 6005c6c1daeSBarry Smith /* the following is temporary fix for initializing a global datastructure */ 601a297a907SKarl Rupp if (!g_hWindowListMutex) g_hWindowListMutex = CreateMutex(NULL, FALSE, NULL); 602aea10558SJacob Faibussowitsch draw->ops[0] = DvOps; 6035c6c1daeSBarry Smith 6045c6c1daeSBarry Smith windraw->hReadyEvent = CreateEvent(NULL, TRUE, FALSE, NULL); 6055c6c1daeSBarry Smith /* makes call to MessageLoopThread to creat window and attach a thread */ 60613d99558SMatthew G. Knepley CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)MessageLoopThread_Win32, draw, 0, (LPDWORD)hThread); 6075c6c1daeSBarry Smith CloseHandle(hThread); 6085c6c1daeSBarry Smith WaitForSingleObject(windraw->hReadyEvent, INFINITE); 6095c6c1daeSBarry Smith CloseHandle(windraw->hReadyEvent); 6105c6c1daeSBarry Smith WaitForSingleObject(g_hWindowListMutex, INFINITE); 6115c6c1daeSBarry Smith 6129566063dSJacob Faibussowitsch PetscCall(PetscNew(&newnode)); 6135c6c1daeSBarry Smith newnode->MouseListHead = NULL; 6145c6c1daeSBarry Smith newnode->MouseListTail = NULL; 6155c6c1daeSBarry Smith newnode->wnext = WindowListHead; 6165c6c1daeSBarry Smith newnode->wprev = NULL; 6175c6c1daeSBarry Smith newnode->hWnd = windraw->hWnd; 6186c4ed002SBarry Smith if (WindowListHead) WindowListHead->wprev = newnode; 6195c6c1daeSBarry Smith WindowListHead = newnode; 6205c6c1daeSBarry Smith windraw->hdc = GetDC(windraw->hWnd); 6215c6c1daeSBarry Smith 6225c6c1daeSBarry Smith windraw->stringheight = 10; 6235c6c1daeSBarry Smith windraw->stringwidth = 6; 6245c6c1daeSBarry Smith windraw->linewidth = 1; /* default pixel sizes of graphics until user changes them */ 6255c6c1daeSBarry Smith windraw->pointdiameter = 1; 6265c6c1daeSBarry Smith windraw->node = newnode; 6275c6c1daeSBarry Smith 6285c6c1daeSBarry Smith windraw->x = draw->x; 6295c6c1daeSBarry Smith windraw->y = draw->y; 6305c6c1daeSBarry Smith windraw->w = newnode->bitwidth = draw->w; 6315c6c1daeSBarry Smith windraw->h = newnode->bitheight = draw->h; 6325c6c1daeSBarry Smith 6335c6c1daeSBarry Smith /* Create and initialize primary graphics buffer */ 6345c6c1daeSBarry Smith newnode->Buffer = CreateCompatibleDC(windraw->hdc); 6355c6c1daeSBarry Smith newnode->BufferBit = CreateCompatibleBitmap(windraw->hdc, windraw->w, windraw->h); 6365c6c1daeSBarry Smith newnode->store = SelectObject(newnode->Buffer, newnode->BufferBit); 6375c6c1daeSBarry Smith ExtFloodFill(newnode->Buffer, 0, 0, COLOR_WINDOW, FLOODFILLBORDER); 6385c6c1daeSBarry Smith 6395c6c1daeSBarry Smith newnode->event = CreateEvent(NULL, TRUE, FALSE, NULL); 6405c6c1daeSBarry Smith newnode->DoubleBuffered = PETSC_FALSE; 6415c6c1daeSBarry Smith 6425c6c1daeSBarry Smith ReleaseDC(windraw->hWnd, windraw->hdc); 6435c6c1daeSBarry Smith ReleaseMutex(g_hWindowListMutex); 6443ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6455c6c1daeSBarry Smith } 6465c6c1daeSBarry Smith 6475c6c1daeSBarry Smith /* FUNCTION: PetscWndProc(HWND, unsigned, WORD, LONG) 6485c6c1daeSBarry Smith PURPOSE: Processes messages for the main window. 6495c6c1daeSBarry Smith WM_COMMAND - process the application menu 6505c6c1daeSBarry Smith WM_PAINT - Paint the main window 6515c6c1daeSBarry Smith WM_DESTROY - post a quit message and return */ 6525c6c1daeSBarry Smith 653d71ae5a4SJacob Faibussowitsch LRESULT CALLBACK PetscWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) 654d71ae5a4SJacob Faibussowitsch { 6557ae38d14SSatish Balay int wmId; 6565c6c1daeSBarry Smith 6575c6c1daeSBarry Smith switch (message) { 6585c6c1daeSBarry Smith HANDLE_MSG(hWnd, WM_PAINT, OnPaint_Win32); 6595c6c1daeSBarry Smith HANDLE_MSG(hWnd, WM_DESTROY, OnDestroy_Win32); 6605c6c1daeSBarry Smith case WM_COMMAND: 6615c6c1daeSBarry Smith wmId = LOWORD(wParam); 6625c6c1daeSBarry Smith /* Parse the menu selections:*/ 6635c6c1daeSBarry Smith switch (wmId) { 664d71ae5a4SJacob Faibussowitsch case IDM_EXIT: 665d71ae5a4SJacob Faibussowitsch DestroyWindow(hWnd); 666d71ae5a4SJacob Faibussowitsch break; 667d71ae5a4SJacob Faibussowitsch default: 668d71ae5a4SJacob Faibussowitsch return DefWindowProc(hWnd, message, wParam, lParam); 6695c6c1daeSBarry Smith } 6705c6c1daeSBarry Smith break; 671d71ae5a4SJacob Faibussowitsch case WM_LBUTTONUP: 672d71ae5a4SJacob Faibussowitsch MouseRecord_Win32(hWnd, PETSC_BUTTON_LEFT); 673d71ae5a4SJacob Faibussowitsch break; 674d71ae5a4SJacob Faibussowitsch case WM_RBUTTONUP: 675d71ae5a4SJacob Faibussowitsch MouseRecord_Win32(hWnd, PETSC_BUTTON_RIGHT); 676d71ae5a4SJacob Faibussowitsch break; 677d71ae5a4SJacob Faibussowitsch case WM_MBUTTONUP: 678d71ae5a4SJacob Faibussowitsch MouseRecord_Win32(hWnd, PETSC_BUTTON_CENTER); 679d71ae5a4SJacob Faibussowitsch break; 680d71ae5a4SJacob Faibussowitsch default: 681d71ae5a4SJacob Faibussowitsch return DefWindowProc(hWnd, message, wParam, lParam); 6825c6c1daeSBarry Smith } 683f9baa8adSSatish Balay return 0; 6845c6c1daeSBarry Smith } 6855c6c1daeSBarry Smith 686d71ae5a4SJacob Faibussowitsch static void OnPaint_Win32(HWND hWnd) 687d71ae5a4SJacob Faibussowitsch { 6885c6c1daeSBarry Smith PAINTSTRUCT ps; 6895c6c1daeSBarry Smith HDC hdc; 6905c6c1daeSBarry Smith WindowNode current = NULL; 6915c6c1daeSBarry Smith 6925c6c1daeSBarry Smith InvalidateRect(hWnd, NULL, TRUE); 6935c6c1daeSBarry Smith WaitForSingleObject(g_hWindowListMutex, INFINITE); 6945c6c1daeSBarry Smith current = WindowListHead; 6955c6c1daeSBarry Smith hdc = BeginPaint(hWnd, &ps); 6965c6c1daeSBarry Smith 6976c4ed002SBarry Smith while (current) { 6985c6c1daeSBarry Smith if (current->hWnd == hWnd) { 6995c6c1daeSBarry Smith /* flushes primary buffer to window */ 7009371c9d4SSatish Balay BitBlt(hdc, 0, 0, GetDeviceCaps(hdc, HORZRES), GetDeviceCaps(hdc, VERTRES), current->Buffer, 0, 0, SRCCOPY); 7015c6c1daeSBarry Smith 702be332245SKarl Rupp /* StretchBlt(hdc,0,0,w,h, 703be332245SKarl Rupp current->Buffer,0,0,current->bitwidth,current->bitheight,SRCCOPY); */ 7045c6c1daeSBarry Smith break; 7055c6c1daeSBarry Smith } 7065c6c1daeSBarry Smith current = current->wnext; 7075c6c1daeSBarry Smith } 7085c6c1daeSBarry Smith EndPaint(hWnd, &ps); 7095c6c1daeSBarry Smith ReleaseMutex(g_hWindowListMutex); 710f9baa8adSSatish Balay return; 7115c6c1daeSBarry Smith } 7125c6c1daeSBarry Smith 713d71ae5a4SJacob Faibussowitsch static PetscErrorCode MouseRecord_Win32(HWND hWnd, PetscDrawButton button) 714d71ae5a4SJacob Faibussowitsch { 7155c6c1daeSBarry Smith /* Called by all three mouse button actions 7165c6c1daeSBarry Smith Records needed mouse data in windows data structure */ 7175c6c1daeSBarry Smith WindowNode current = NULL; 7185c6c1daeSBarry Smith MouseNode newnode; 7195c6c1daeSBarry Smith POINT mousepos; 7205c6c1daeSBarry Smith 7215c6c1daeSBarry Smith PetscFunctionBegin; 7225c6c1daeSBarry Smith WaitForSingleObject(g_hWindowListMutex, INFINITE); 7235c6c1daeSBarry Smith current = WindowListHead; 7245c6c1daeSBarry Smith if (current->IsGetMouseOn == TRUE) { 7255c6c1daeSBarry Smith SetEvent(current->event); 7266c4ed002SBarry Smith while (current) { 7275c6c1daeSBarry Smith if (current->hWnd == hWnd) { 7289566063dSJacob Faibussowitsch PetscCall(PetscNew(&newnode)); 7295c6c1daeSBarry Smith newnode->Button = button; 7305c6c1daeSBarry Smith GetCursorPos(&mousepos); 7315c6c1daeSBarry Smith newnode->user.x = mousepos.x; 7325c6c1daeSBarry Smith newnode->user.y = mousepos.y; 7335c6c1daeSBarry Smith ScreenToClient(hWnd, &mousepos); 7345c6c1daeSBarry Smith newnode->phys.x = mousepos.x; 7355c6c1daeSBarry Smith newnode->phys.y = mousepos.y; 7365c6c1daeSBarry Smith if (!current->MouseListTail) { 7375c6c1daeSBarry Smith current->MouseListHead = newnode; 7385c6c1daeSBarry Smith current->MouseListTail = newnode; 7395c6c1daeSBarry Smith } else { 7405c6c1daeSBarry Smith current->MouseListTail->mnext = newnode; 7415c6c1daeSBarry Smith current->MouseListTail = newnode; 7425c6c1daeSBarry Smith } 7435c6c1daeSBarry Smith newnode->mnext = NULL; 7445c6c1daeSBarry Smith 7455c6c1daeSBarry Smith break; 7465c6c1daeSBarry Smith } 7475c6c1daeSBarry Smith current = current->wnext; 7485c6c1daeSBarry Smith } 7495c6c1daeSBarry Smith } 7505c6c1daeSBarry Smith ReleaseMutex(g_hWindowListMutex); 7513ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7525c6c1daeSBarry Smith } 7535c6c1daeSBarry Smith 754d71ae5a4SJacob Faibussowitsch static void OnDestroy_Win32(HWND hWnd) 755d71ae5a4SJacob Faibussowitsch { 7565c6c1daeSBarry Smith /* searches linked list of window data and frees corresponding memory */ 7575c6c1daeSBarry Smith WindowNode current; 7585c6c1daeSBarry Smith 7595c6c1daeSBarry Smith PetscFunctionBegin; 7605c6c1daeSBarry Smith WaitForSingleObject(g_hWindowListMutex, INFINITE); 7615c6c1daeSBarry Smith current = WindowListHead; 7625c6c1daeSBarry Smith 7635c6c1daeSBarry Smith SetEvent(current->event); 7646c4ed002SBarry Smith while (current) { 7655c6c1daeSBarry Smith if (current->hWnd == hWnd) { 7666c4ed002SBarry Smith if (current->wprev) current->wprev->wnext = current->wnext; 767a297a907SKarl Rupp else WindowListHead = current->wnext; 768a297a907SKarl Rupp if (current->MouseListHead) deletemouselist_Win32(current); 769a297a907SKarl Rupp else PetscFree(current); 7705c6c1daeSBarry Smith break; 7715c6c1daeSBarry Smith } 7725c6c1daeSBarry Smith current = current->wnext; 7735c6c1daeSBarry Smith } 7745c6c1daeSBarry Smith ReleaseMutex(g_hWindowListMutex); 7755c6c1daeSBarry Smith PostQuitMessage(0); 7765c6c1daeSBarry Smith PetscFunctionReturnVoid(); 7775c6c1daeSBarry Smith } 778