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 25*9371c9d4SSatish 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)))) 26*9371c9d4SSatish 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 375c6c1daeSBarry Smith /* Foward 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 48*9371c9d4SSatish Balay static PetscErrorCode PetscDrawSetDoubleBuffer_Win32(PetscDraw draw) { 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); 585c6c1daeSBarry Smith /* Copy current buffer into seconf buffer and set window data as double buffered */ 59*9371c9d4SSatish 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); 635c6c1daeSBarry Smith PetscFunctionReturn(0); 645c6c1daeSBarry Smith } 655c6c1daeSBarry Smith 66*9371c9d4SSatish Balay static PetscErrorCode PetscDrawFlush_Win32(PetscDraw draw) { 675c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32 *)draw->data; 685c6c1daeSBarry Smith HDC hdc = GetDC(windraw->hWnd); 695c6c1daeSBarry Smith 705c6c1daeSBarry Smith PetscFunctionBegin; 715c6c1daeSBarry Smith /* flush double buffer into primary buffer */ 72*9371c9d4SSatish Balay BitBlt(windraw->node->Buffer, 0, 0, windraw->w, windraw->h, windraw->node->DoubleBuffer, 0, 0, SRCCOPY); 735c6c1daeSBarry Smith /* flush double buffer into window */ 74*9371c9d4SSatish Balay BitBlt(hdc, 0, 0, windraw->w, windraw->h, windraw->node->DoubleBuffer, 0, 0, SRCCOPY); 755c6c1daeSBarry Smith ReleaseDC(windraw->hWnd, hdc); 765c6c1daeSBarry Smith PetscFunctionReturn(0); 775c6c1daeSBarry Smith } 785c6c1daeSBarry Smith 79*9371c9d4SSatish Balay static PetscErrorCode deletemouselist_Win32(WindowNode deletelist) { 805c6c1daeSBarry Smith /* Called upon window close. Frees memory of linked list of stored mouse commands */ 815c6c1daeSBarry Smith MouseNode node; 825c6c1daeSBarry Smith 836c4ed002SBarry Smith while (deletelist->MouseListHead) { 845c6c1daeSBarry Smith node = deletelist->MouseListHead; 856c4ed002SBarry Smith if (deletelist->MouseListHead->mnext) deletelist->MouseListHead = deletelist->MouseListHead->mnext; 865c6c1daeSBarry Smith PetscFree(node); 875c6c1daeSBarry Smith } 885c6c1daeSBarry Smith deletelist->MouseListHead = deletelist->MouseListTail = NULL; 896c4ed002SBarry Smith if (deletelist->wprev) deletelist->wprev->wnext = deletelist->wnext; 906c4ed002SBarry Smith if (deletelist->wnext) deletelist->wnext->wprev = deletelist->wprev; 915c6c1daeSBarry Smith PetscFree(deletelist); 925c6c1daeSBarry Smith return 0; 935c6c1daeSBarry Smith } 945c6c1daeSBarry Smith 95*9371c9d4SSatish Balay static PetscErrorCode PetscDrawGetMouseButton_Win32(PetscDraw draw, PetscDrawButton *button, PetscReal *x_user, PetscReal *y_user, PetscReal *x_phys, PetscReal *y_phys) { 965c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32 *)draw->data; 975c6c1daeSBarry Smith WindowNode current; 985c6c1daeSBarry Smith MouseNode node = 0; 995c6c1daeSBarry Smith 1005c6c1daeSBarry Smith PetscFunctionBegin; 1015c6c1daeSBarry Smith /* Make sure no other code is using the linked list at this moment */ 1025c6c1daeSBarry Smith WaitForSingleObject(g_hWindowListMutex, INFINITE); 1035c6c1daeSBarry Smith /* Look for the node that matches the window you are using */ 1045c6c1daeSBarry Smith current = WindowListHead; 1056c4ed002SBarry Smith while (current) { 1065c6c1daeSBarry Smith if (current->hWnd == windraw->hWnd) { 1075c6c1daeSBarry Smith current->IsGetMouseOn = TRUE; 1085c6c1daeSBarry Smith break; 109a297a907SKarl Rupp } else current = current->wnext; 1105c6c1daeSBarry Smith } 111a5b23f4aSJose E. Roman /* If no actions have occurred, wait for one */ 1125c6c1daeSBarry Smith node = current->MouseListHead; 1135c6c1daeSBarry Smith if (!node) { 1145c6c1daeSBarry Smith ReleaseMutex(g_hWindowListMutex); 1155c6c1daeSBarry Smith WaitForSingleObject(current->event, INFINITE); 1165c6c1daeSBarry Smith WaitForSingleObject(g_hWindowListMutex, INFINITE); 1175c6c1daeSBarry Smith } 1185c6c1daeSBarry Smith /* once we have the information, assign the pointers to it */ 1195c6c1daeSBarry Smith *button = current->MouseListHead->Button; 1205c6c1daeSBarry Smith *x_user = current->MouseListHead->user.x; 1215c6c1daeSBarry Smith *y_user = current->MouseListHead->user.y; 1225c6c1daeSBarry Smith /* optional arguments */ 1235c6c1daeSBarry Smith if (x_phys) *x_phys = current->MouseListHead->phys.x; 1245c6c1daeSBarry Smith if (y_phys) *y_phys = current->MouseListHead->phys.y; 1255c6c1daeSBarry Smith /* remove set of information from sub linked-list, delete the node */ 1265c6c1daeSBarry Smith current->MouseListHead = current->MouseListHead->mnext; 1275c6c1daeSBarry Smith if (!current->MouseListHead) { 1285c6c1daeSBarry Smith ResetEvent(current->event); 1295c6c1daeSBarry Smith current->MouseListTail = NULL; 1305c6c1daeSBarry Smith } 1315c6c1daeSBarry Smith if (node) PetscFree(node); 1325c6c1daeSBarry Smith 1335c6c1daeSBarry Smith /* Release mutex so that other code can use 1345c6c1daeSBarry Smith the linked list now that we are done with it */ 1355c6c1daeSBarry Smith ReleaseMutex(g_hWindowListMutex); 1365c6c1daeSBarry Smith PetscFunctionReturn(0); 1375c6c1daeSBarry Smith } 1385c6c1daeSBarry Smith 139*9371c9d4SSatish Balay static PetscErrorCode PetscDrawPause_Win32(PetscDraw draw) { 1405c6c1daeSBarry Smith PetscFunctionBegin; 1415c6c1daeSBarry Smith PetscSleep(draw->pause); 1425c6c1daeSBarry Smith PetscFunctionReturn(0); 1435c6c1daeSBarry Smith } 1445c6c1daeSBarry Smith 145*9371c9d4SSatish Balay static PetscErrorCode TranslateColor_Win32(PetscDraw draw, int color) { 1465c6c1daeSBarry Smith /* Maps single color value into the RGB colors in our tables */ 1475c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32 *)draw->data; 1485c6c1daeSBarry Smith windraw->currentcolor = RGB(RedMap[color], GreenMap[color], BlueMap[color]); 1495c6c1daeSBarry Smith return 0; 1505c6c1daeSBarry Smith } 1515c6c1daeSBarry Smith 152*9371c9d4SSatish Balay static PetscErrorCode AverageColorRectangle_Win32(PetscDraw draw, int c1, int c2, int c3, int c4) { 1535c6c1daeSBarry Smith /* Averages colors given at points of rectangle and sets color from color table 1545c6c1daeSBarry Smith will be changed once the color gradient problem is worked out */ 1555c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32 *)draw->data; 156*9371c9d4SSatish 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)); 1575c6c1daeSBarry Smith return 0; 1585c6c1daeSBarry Smith } 1595c6c1daeSBarry Smith 160*9371c9d4SSatish Balay static PetscErrorCode AverageColorTriangle_Win32(PetscDraw draw, int c1, int c2, int c3) { 1615c6c1daeSBarry Smith /* Averages colors given at points of rectangle and sets color from color table 1625c6c1daeSBarry Smith will be changed once the color gradient problem is worked out */ 1635c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32 *)draw->data; 164*9371c9d4SSatish 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); 1655c6c1daeSBarry Smith return 0; 1665c6c1daeSBarry Smith } 1675c6c1daeSBarry Smith 168*9371c9d4SSatish Balay static PetscErrorCode PetscDrawRectangle_Win32(PetscDraw draw, PetscReal xl, PetscReal yl, PetscReal xr, PetscReal yr, int c1, int c2, int c3, int c4) { 1695c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32 *)draw->data; 1705c6c1daeSBarry Smith HBRUSH hbrush; 1715c6c1daeSBarry Smith RECT rect; 1725c6c1daeSBarry Smith int x1, yone, x2, y2; 1735c6c1daeSBarry Smith HDC hdc; 1745c6c1daeSBarry Smith 1755c6c1daeSBarry Smith PetscFunctionBegin; 1765c6c1daeSBarry Smith x1 = XTRANS(draw, windraw, xl); 1775c6c1daeSBarry Smith x2 = XTRANS(draw, windraw, xr); 1785c6c1daeSBarry Smith yone = YTRANS(draw, windraw, yl); 1795c6c1daeSBarry Smith y2 = YTRANS(draw, windraw, yr); 1805c6c1daeSBarry Smith SetRect(&rect, x1, y2, x2, yone); 181a297a907SKarl Rupp if (c1 == c2 && c2 == c3 && c3 == c4) TranslateColor_Win32(draw, c1); 182a297a907SKarl Rupp else AverageColorRectangle_Win32(draw, c1, c2, c3, c4); 1835c6c1daeSBarry Smith hbrush = CreateSolidBrush(windraw->currentcolor); 1845c6c1daeSBarry Smith 185a297a907SKarl Rupp if (windraw->node->DoubleBuffered) hdc = windraw->node->DoubleBuffer; 186a297a907SKarl Rupp else hdc = windraw->node->Buffer; 187a297a907SKarl Rupp 1885c6c1daeSBarry Smith FillRect(hdc, &rect, hbrush); 1895c6c1daeSBarry Smith /* Forces a WM_PAINT message and erases background */ 1905c6c1daeSBarry Smith InvalidateRect(windraw->hWnd, NULL, TRUE); 1915c6c1daeSBarry Smith UpdateWindow(windraw->hWnd); 1925c6c1daeSBarry Smith PetscFunctionReturn(0); 1935c6c1daeSBarry Smith } 1945c6c1daeSBarry Smith 195*9371c9d4SSatish Balay static PetscErrorCode PetscDrawLine_Win32(PetscDraw draw, PetscReal xl, PetscReal yl, PetscReal xr, PetscReal yr, int color) { 1965c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32 *)draw->data; 1975c6c1daeSBarry Smith HPEN hpen; 1985c6c1daeSBarry Smith int x1, yone, x2, y2; 1995c6c1daeSBarry Smith HDC hdc; 2005c6c1daeSBarry Smith 2015c6c1daeSBarry Smith PetscFunctionBegin; 2025c6c1daeSBarry Smith TranslateColor_Win32(draw, color); 203*9371c9d4SSatish Balay x1 = XTRANS(draw, windraw, xl); 204*9371c9d4SSatish Balay x2 = XTRANS(draw, windraw, xr); 205*9371c9d4SSatish Balay yone = YTRANS(draw, windraw, yl); 206*9371c9d4SSatish Balay y2 = YTRANS(draw, windraw, yr); 2075c6c1daeSBarry Smith hpen = CreatePen(PS_SOLID, windraw->linewidth, windraw->currentcolor); 208a297a907SKarl Rupp if (windraw->node->DoubleBuffered) hdc = windraw->node->DoubleBuffer; 209a297a907SKarl Rupp else hdc = windraw->node->Buffer; 210a297a907SKarl Rupp 2115c6c1daeSBarry Smith SelectPen(hdc, hpen); 2125c6c1daeSBarry Smith MoveToEx(hdc, x1, yone, NULL); 2135c6c1daeSBarry Smith LineTo(hdc, x2, y2); 2145c6c1daeSBarry Smith /* Forces a WM_PAINT message and erases background */ 2155c6c1daeSBarry Smith InvalidateRect(windraw->hWnd, NULL, TRUE); 2165c6c1daeSBarry Smith UpdateWindow(windraw->hWnd); 2175c6c1daeSBarry Smith PetscFunctionReturn(0); 2185c6c1daeSBarry Smith } 2195c6c1daeSBarry Smith 220*9371c9d4SSatish Balay static PetscErrorCode PetscDrawLineSetWidth_Win32(PetscDraw draw, PetscReal width) { 2215c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32 *)draw->data; 2225c6c1daeSBarry Smith int averagesize, finalwidth; 2235c6c1daeSBarry Smith RECT rect; 2245c6c1daeSBarry Smith 2255c6c1daeSBarry Smith PetscFunctionBegin; 2265c6c1daeSBarry Smith GetClientRect(windraw->hWnd, &rect); 2275c6c1daeSBarry Smith averagesize = ((rect.right - rect.left) + (rect.bottom - rect.top)) / 2; 22877b4d14cSPeter Brune finalwidth = (int)PetscFloorReal(averagesize * width); 229a297a907SKarl Rupp if (finalwidth < 1) finalwidth = 1; /* minimum size PetscDrawLine can except */ 230a297a907SKarl Rupp 2315c6c1daeSBarry Smith windraw->linewidth = finalwidth; 2325c6c1daeSBarry Smith PetscFunctionReturn(0); 2335c6c1daeSBarry Smith } 2345c6c1daeSBarry Smith 235*9371c9d4SSatish Balay static PetscErrorCode PetscDrawLineGetWidth_Win32(PetscDraw draw, PetscReal *width) { 2365c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32 *)draw->data; 2375c6c1daeSBarry Smith 2385c6c1daeSBarry Smith PetscFunctionBegin; 2395c6c1daeSBarry Smith *width = (PetscReal)windraw->linewidth; 2405c6c1daeSBarry Smith PetscFunctionReturn(0); 2415c6c1daeSBarry Smith } 2425c6c1daeSBarry Smith 243*9371c9d4SSatish Balay static PetscErrorCode PetscDrawPoint_Win32(PetscDraw draw, PetscReal x, PetscReal y, int color) { 2445c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32 *)draw->data; 2455c6c1daeSBarry Smith HBRUSH hbrush; 2465c6c1daeSBarry Smith HRGN hrgn; 2475c6c1daeSBarry Smith int radius; 2485c6c1daeSBarry Smith int x1, yone; 2495c6c1daeSBarry Smith HDC hdc; 2505c6c1daeSBarry Smith 2515c6c1daeSBarry Smith PetscFunctionBegin; 2525c6c1daeSBarry Smith TranslateColor_Win32(draw, color); 2535c6c1daeSBarry Smith x1 = XTRANS(draw, windraw, x); 2545c6c1daeSBarry Smith yone = YTRANS(draw, windraw, y); 2555c6c1daeSBarry Smith hbrush = CreateSolidBrush(windraw->currentcolor); 256a297a907SKarl Rupp if (windraw->node->DoubleBuffered) hdc = windraw->node->DoubleBuffer; 257a297a907SKarl Rupp else hdc = windraw->node->Buffer; 258a297a907SKarl Rupp 2595c6c1daeSBarry Smith /* desired size is one logical pixel so just turn it on */ 260a297a907SKarl Rupp if (windraw->pointdiameter == 1) SetPixelV(hdc, x1, yone, windraw->currentcolor); 261a297a907SKarl Rupp else { 2625c6c1daeSBarry Smith /* draw point around position determined */ 2635c6c1daeSBarry Smith radius = windraw->pointdiameter / 2; /* integer division */ 2645c6c1daeSBarry Smith hrgn = CreateEllipticRgn(x1 - radius, yone - radius, x1 + radius, yone + radius); 2655c6c1daeSBarry Smith FillRgn(hdc, hrgn, hbrush); 2665c6c1daeSBarry Smith } 2675c6c1daeSBarry Smith /* Forces a WM_PAINT and erases background */ 2685c6c1daeSBarry Smith InvalidateRect(windraw->hWnd, NULL, TRUE); 2695c6c1daeSBarry Smith UpdateWindow(windraw->hWnd); 2705c6c1daeSBarry Smith PetscFunctionReturn(0); 2715c6c1daeSBarry Smith } 2725c6c1daeSBarry Smith 273*9371c9d4SSatish Balay static PetscErrorCode PetscDrawPointSetSize_Win32(PetscDraw draw, PetscReal width) { 2745c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32 *)draw->data; 2755c6c1daeSBarry Smith int averagesize, diameter; 2765c6c1daeSBarry Smith RECT rect; 2775c6c1daeSBarry Smith 2785c6c1daeSBarry Smith PetscFunctionBegin; 2795c6c1daeSBarry Smith GetClientRect(windraw->hWnd, &rect); 2805c6c1daeSBarry Smith averagesize = ((rect.right - rect.left) + (rect.bottom - rect.top)) / 2; 28177b4d14cSPeter Brune diameter = (int)PetscFloorReal(averagesize * width); 2825c6c1daeSBarry Smith if (diameter < 1) diameter = 1; 2835c6c1daeSBarry Smith windraw->pointdiameter = diameter; 2845c6c1daeSBarry Smith PetscFunctionReturn(0); 2855c6c1daeSBarry Smith } 2865c6c1daeSBarry Smith 287*9371c9d4SSatish Balay static PetscErrorCode PetscDrawString_Win32(PetscDraw draw, PetscReal x, PetscReal y, int color, const char *text) { 2885c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32 *)draw->data; 2895c6c1daeSBarry Smith RECT r; 2905c6c1daeSBarry Smith HFONT hfont; 2915c6c1daeSBarry Smith LOGFONT logfont; 2925c6c1daeSBarry Smith int x1, yone; 2935c6c1daeSBarry Smith HDC hdc; 2945c6c1daeSBarry Smith 2955c6c1daeSBarry Smith PetscFunctionBegin; 2965c6c1daeSBarry Smith x1 = XTRANS(draw, windraw, x); 2975c6c1daeSBarry Smith yone = YTRANS(draw, windraw, y); 2985c6c1daeSBarry Smith r.bottom = yone; 2995c6c1daeSBarry Smith r.left = x1; 3005c6c1daeSBarry Smith r.right = x1 + 1; 3015c6c1daeSBarry Smith r.top = yone + 1; 302a297a907SKarl Rupp 3035c6c1daeSBarry Smith logfont.lfHeight = windraw->stringheight; 3045c6c1daeSBarry Smith logfont.lfWidth = windraw->stringwidth; 3055c6c1daeSBarry Smith logfont.lfEscapement = 0; 3065c6c1daeSBarry Smith logfont.lfOrientation = 0; 3075c6c1daeSBarry Smith logfont.lfCharSet = 0; 3085c6c1daeSBarry Smith logfont.lfClipPrecision = 0; 3095c6c1daeSBarry Smith logfont.lfItalic = 0; 3105c6c1daeSBarry Smith logfont.lfOutPrecision = 0; 3115c6c1daeSBarry Smith logfont.lfPitchAndFamily = DEFAULT_PITCH; 3125c6c1daeSBarry Smith logfont.lfQuality = DEFAULT_QUALITY; 3135c6c1daeSBarry Smith logfont.lfStrikeOut = 0; 3145c6c1daeSBarry Smith logfont.lfUnderline = 0; 3155c6c1daeSBarry Smith logfont.lfWeight = FW_NORMAL; 316a297a907SKarl Rupp 3175c6c1daeSBarry Smith hfont = CreateFontIndirect(&logfont); 3185c6c1daeSBarry Smith TranslateColor_Win32(draw, color); 319a297a907SKarl Rupp if (windraw->node->DoubleBuffered) hdc = windraw->node->DoubleBuffer; 320a297a907SKarl Rupp else hdc = windraw->node->Buffer; 321a297a907SKarl Rupp 3225c6c1daeSBarry Smith SelectFont(hdc, hfont); 3235c6c1daeSBarry Smith SetTextColor(hdc, windraw->currentcolor); 3245c6c1daeSBarry Smith DrawText(hdc, text, lstrlen(text), &r, DT_NOCLIP); 3255c6c1daeSBarry Smith DeleteObject(hfont); 3265c6c1daeSBarry Smith /* Forces a WM_PAINT message and erases background */ 3275c6c1daeSBarry Smith InvalidateRect(windraw->hWnd, NULL, TRUE); 3285c6c1daeSBarry Smith UpdateWindow(windraw->hWnd); 3295c6c1daeSBarry Smith PetscFunctionReturn(0); 3305c6c1daeSBarry Smith } 3315c6c1daeSBarry Smith 332*9371c9d4SSatish Balay static PetscErrorCode PetscDrawStringVertical_Win32(PetscDraw draw, PetscReal x, PetscReal y, int color, const char *text) { 3335c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32 *)draw->data; 3345c6c1daeSBarry Smith RECT r; 3355c6c1daeSBarry Smith HFONT hfont; 3365c6c1daeSBarry Smith LOGFONT logfont; 3375c6c1daeSBarry Smith int x1, yone; 3385c6c1daeSBarry Smith HDC hdc; 3395c6c1daeSBarry Smith 3405c6c1daeSBarry Smith PetscFunctionBegin; 3415c6c1daeSBarry Smith x1 = XTRANS(draw, windraw, x); 3425c6c1daeSBarry Smith yone = YTRANS(draw, windraw, y); 3435c6c1daeSBarry Smith r.left = x1; 3445c6c1daeSBarry Smith r.bottom = yone + 30; 3455c6c1daeSBarry Smith r.right = x1 + 1; 3465c6c1daeSBarry Smith r.top = yone - 30; 347a297a907SKarl Rupp 3485c6c1daeSBarry Smith logfont.lfEscapement = 2700; /* Causes verticle text drawing */ 3495c6c1daeSBarry Smith logfont.lfHeight = windraw->stringheight; 3505c6c1daeSBarry Smith logfont.lfWidth = windraw->stringwidth; 3515c6c1daeSBarry Smith logfont.lfOrientation = 0; 3525c6c1daeSBarry Smith logfont.lfCharSet = DEFAULT_CHARSET; 3535c6c1daeSBarry Smith logfont.lfClipPrecision = 0; 3545c6c1daeSBarry Smith logfont.lfItalic = 0; 3555c6c1daeSBarry Smith logfont.lfOutPrecision = 0; 3565c6c1daeSBarry Smith logfont.lfPitchAndFamily = DEFAULT_PITCH; 3575c6c1daeSBarry Smith logfont.lfQuality = DEFAULT_QUALITY; 3585c6c1daeSBarry Smith logfont.lfStrikeOut = 0; 3595c6c1daeSBarry Smith logfont.lfUnderline = 0; 3605c6c1daeSBarry Smith logfont.lfWeight = FW_NORMAL; 361a297a907SKarl Rupp 3625c6c1daeSBarry Smith hfont = CreateFontIndirect(&logfont); 3635c6c1daeSBarry Smith TranslateColor_Win32(draw, color); 364a297a907SKarl Rupp if (windraw->node->DoubleBuffered) hdc = windraw->node->DoubleBuffer; 365a297a907SKarl Rupp else hdc = windraw->node->Buffer; 366a297a907SKarl Rupp 3675c6c1daeSBarry Smith SelectFont(hdc, hfont); 3685c6c1daeSBarry Smith SetTextColor(hdc, windraw->currentcolor); 3695c6c1daeSBarry Smith DrawText(hdc, text, lstrlen(text), &r, DT_NOCLIP | DT_SINGLELINE); 3705c6c1daeSBarry Smith DeleteObject(hfont); 3715c6c1daeSBarry Smith /* Forces a WM_PAINT message and erases background */ 3725c6c1daeSBarry Smith InvalidateRect(windraw->hWnd, NULL, TRUE); 3735c6c1daeSBarry Smith UpdateWindow(windraw->hWnd); 3745c6c1daeSBarry Smith PetscFunctionReturn(0); 3755c6c1daeSBarry Smith } 3765c6c1daeSBarry Smith 377*9371c9d4SSatish Balay static PetscErrorCode PetscDrawStringSetSize_Win32(PetscDraw draw, PetscReal width, PetscReal height) { 3785c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32 *)draw->data; 3795c6c1daeSBarry Smith int w, h; 3805c6c1daeSBarry Smith 3815c6c1daeSBarry Smith PetscFunctionBegin; 3825c6c1daeSBarry Smith w = (int)((windraw->w) * width * (draw->port_xr - draw->port_xl) / (draw->coor_xr - draw->coor_xl)); 3835c6c1daeSBarry Smith h = (int)((windraw->h) * height * (draw->port_yr - draw->port_yl) / (draw->coor_yr - draw->coor_yl)); 3845c6c1daeSBarry Smith if (h < 1) h = 1; 3855c6c1daeSBarry Smith if (w < 1) w = 1; 3865c6c1daeSBarry Smith windraw->stringheight = h; 3875c6c1daeSBarry Smith windraw->stringwidth = w; 3885c6c1daeSBarry Smith PetscFunctionReturn(0); 3895c6c1daeSBarry Smith } 390*9371c9d4SSatish Balay static PetscErrorCode PetscDrawStringGetSize_Win32(PetscDraw draw, PetscReal *width, PetscReal *height) { 3915c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32 *)draw->data; 3925c6c1daeSBarry Smith double scaleX = (draw->coor_xr - draw->coor_xl) / (draw->w) * (draw->port_xr - draw->port_xl); 3935c6c1daeSBarry Smith double scaleY = (draw->coor_yr - draw->coor_yl) / (draw->h) * (draw->port_yr - draw->port_yl); 3945c6c1daeSBarry Smith 3955c6c1daeSBarry Smith PetscFunctionBegin; 3964a5237bfSSatish Balay if (height) *height = (double)windraw->stringheight * scaleY; 3974a5237bfSSatish Balay if (width) *width = (double)windraw->stringwidth * scaleX; 3985c6c1daeSBarry Smith PetscFunctionReturn(0); 3995c6c1daeSBarry Smith } 4005c6c1daeSBarry Smith 401*9371c9d4SSatish Balay static PetscErrorCode PetscDrawResizeWindow_Win32(PetscDraw draw, int w, int h) { 4025c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32 *)draw->data; 4035c6c1daeSBarry Smith RECT r; 4045c6c1daeSBarry Smith 4055c6c1daeSBarry Smith PetscFunctionBegin; 4065c6c1daeSBarry Smith GetWindowRect(windraw->hWnd, &r); 4075c6c1daeSBarry Smith MoveWindow(windraw->hWnd, r.left, r.top, (int)w, (int)h, TRUE); 4085c6c1daeSBarry Smith /* set all variable dealing with window dimensions */ 4095c6c1daeSBarry Smith windraw->node->bitheight = windraw->h = draw->h = h; 4105c6c1daeSBarry Smith windraw->node->bitwidth = windraw->w = draw->w = w; 4115c6c1daeSBarry Smith /* set up graphic buffers with the new size of window */ 4125c6c1daeSBarry Smith SetBitmapDimensionEx(windraw->node->BufferBit, w, h, NULL); 413a297a907SKarl Rupp if (windraw->node->DoubleBuffered) SetBitmapDimensionEx(windraw->node->DoubleBufferBit, w, h, NULL); 4145c6c1daeSBarry Smith windraw->haveresized = PETSC_TRUE; 4155c6c1daeSBarry Smith PetscFunctionReturn(0); 4165c6c1daeSBarry Smith } 4175c6c1daeSBarry Smith 418*9371c9d4SSatish Balay static PetscErrorCode PetscDrawCheckResizedWindow_Win32(PetscDraw draw) { 4195c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32 *)draw->data; 4205c6c1daeSBarry Smith 4215c6c1daeSBarry Smith PetscFunctionBegin; 422a297a907SKarl Rupp if (windraw->haveresized == 1) PetscFunctionReturn(1); 423a297a907SKarl Rupp else PetscFunctionReturn(0); 4245c6c1daeSBarry Smith } 4255c6c1daeSBarry Smith 426*9371c9d4SSatish Balay static PetscErrorCode PetscDrawSetTitle_Win32(PetscDraw draw, const char title[]) { 4275c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32 *)draw->data; 4285c6c1daeSBarry Smith 4295c6c1daeSBarry Smith PetscFunctionBegin; 4305c6c1daeSBarry Smith SetWindowText(windraw->hWnd, title); 4315c6c1daeSBarry Smith PetscFunctionReturn(0); 4325c6c1daeSBarry Smith } 4335c6c1daeSBarry Smith 434*9371c9d4SSatish Balay static PetscErrorCode PetscDrawClear_Win32(PetscDraw draw) { 4355c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32 *)draw->data; 4365c6c1daeSBarry Smith 4375c6c1daeSBarry Smith PetscFunctionBegin; 4385c6c1daeSBarry Smith /* clear primary buffer */ 4395c6c1daeSBarry Smith ExtFloodFill(windraw->node->Buffer, 0, 0, COLOR_WINDOW, FLOODFILLBORDER); 4405c6c1daeSBarry Smith /* if exists clear secondary buffer */ 441a297a907SKarl Rupp if (windraw->node->DoubleBuffered) ExtFloodFill(windraw->node->DoubleBuffer, 0, 0, COLOR_WINDOW, FLOODFILLBORDER); 442a297a907SKarl Rupp 4435c6c1daeSBarry Smith /* force WM_PAINT message so cleared buffer will show */ 4445c6c1daeSBarry Smith InvalidateRect(windraw->hWnd, NULL, TRUE); 4455c6c1daeSBarry Smith UpdateWindow(windraw->hWnd); 4465c6c1daeSBarry Smith PetscFunctionReturn(0); 4475c6c1daeSBarry Smith } 4485c6c1daeSBarry Smith 449*9371c9d4SSatish Balay static PetscErrorCode PetscDrawTriangle_Win32(PetscDraw draw, PetscReal x1, PetscReal yone, PetscReal x2, PetscReal y2, PetscReal x3, PetscReal y3, int c1, int c2, int c3) { 4505c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32 *)draw->data; 4515c6c1daeSBarry Smith HBRUSH hbrush; 4525c6c1daeSBarry Smith HPEN hpen; 4535c6c1daeSBarry Smith int p1x, p1y, p2x, p2y, p3x, p3y; 4545c6c1daeSBarry Smith HDC bit; 4555c6c1daeSBarry Smith 4565c6c1daeSBarry Smith PetscFunctionBegin; 4575c6c1daeSBarry Smith AverageColorTriangle_Win32(draw, c1, c2, c3); 4585c6c1daeSBarry Smith hbrush = CreateSolidBrush(windraw->currentcolor); 4595c6c1daeSBarry Smith hpen = CreatePen(PS_SOLID, 0, windraw->currentcolor); 4605c6c1daeSBarry Smith p1x = XTRANS(draw, windraw, x1); 4615c6c1daeSBarry Smith p2x = XTRANS(draw, windraw, x2); 4625c6c1daeSBarry Smith p3x = XTRANS(draw, windraw, x3); 4635c6c1daeSBarry Smith p1y = YTRANS(draw, windraw, yone); 4645c6c1daeSBarry Smith p2y = YTRANS(draw, windraw, y2); 4655c6c1daeSBarry Smith p3y = YTRANS(draw, windraw, y3); 4665c6c1daeSBarry Smith 467a297a907SKarl Rupp if (windraw->node->DoubleBuffered) bit = windraw->node->DoubleBuffer; 468a297a907SKarl Rupp else bit = windraw->node->Buffer; 469a297a907SKarl Rupp 4705c6c1daeSBarry Smith BeginPath(bit); 4715c6c1daeSBarry Smith MoveToEx(bit, p1x, p1y, NULL); 4725c6c1daeSBarry Smith LineTo(bit, p2x, p2y); 4735c6c1daeSBarry Smith LineTo(bit, p3x, p3y); 4745c6c1daeSBarry Smith LineTo(bit, p1x, p1y); 4755c6c1daeSBarry Smith EndPath(bit); 4765c6c1daeSBarry Smith SelectPen(bit, hpen); 4775c6c1daeSBarry Smith SelectBrush(bit, hbrush); 4785c6c1daeSBarry Smith StrokeAndFillPath(bit); 4795c6c1daeSBarry Smith /* Forces a WM_PAINT message and erases background */ 4805c6c1daeSBarry Smith InvalidateRect(windraw->hWnd, NULL, TRUE); 4815c6c1daeSBarry Smith UpdateWindow(windraw->hWnd); 4825c6c1daeSBarry Smith PetscFunctionReturn(0); 4835c6c1daeSBarry Smith } 4845c6c1daeSBarry Smith 485*9371c9d4SSatish Balay void PopMessageLoopThread_Win32(PetscDraw popdraw) { 4865c6c1daeSBarry Smith PetscDraw_Win32 *pop = (PetscDraw_Win32 *)popdraw->data; 4875c6c1daeSBarry Smith MSG msg; 4885c6c1daeSBarry Smith HWND hWnd = NULL; 489fad2a674SVolker const char PopClassName[] = "PETSc Window Pop Class"; 4905c6c1daeSBarry Smith RECT r; 4915c6c1daeSBarry Smith int width, height; 4925c6c1daeSBarry Smith WNDCLASSEX myclass; 4935c6c1daeSBarry Smith LPVOID lpMsgBuf; 4945c6c1daeSBarry Smith 4955c6c1daeSBarry Smith PetscFunctionBegin; 4965c6c1daeSBarry Smith /* initialize window class parameters */ 4975c6c1daeSBarry Smith myclass.cbSize = sizeof(WNDCLASSEX); 4985c6c1daeSBarry Smith myclass.style = CS_OWNDC; 4995c6c1daeSBarry Smith myclass.lpfnWndProc = (WNDPROC)PetscWndProc; 5005c6c1daeSBarry Smith myclass.cbClsExtra = 0; 5015c6c1daeSBarry Smith myclass.cbWndExtra = 0; 5025c6c1daeSBarry Smith myclass.hInstance = NULL; 5035c6c1daeSBarry Smith myclass.hIcon = NULL; 5045c6c1daeSBarry Smith myclass.hCursor = LoadCursor(NULL, IDC_ARROW); 5055c6c1daeSBarry Smith myclass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); 5065c6c1daeSBarry Smith myclass.lpszMenuName = NULL; 5075c6c1daeSBarry Smith myclass.lpszClassName = PopClassName; 5085c6c1daeSBarry Smith myclass.hIconSm = NULL; 5095c6c1daeSBarry Smith 5105c6c1daeSBarry Smith RegisterClassEx(&myclass); 5115c6c1daeSBarry Smith 5125c6c1daeSBarry Smith SetRect(&r, 0, 0, 450, 450); 5135c6c1daeSBarry Smith 5145c6c1daeSBarry Smith width = (r.right - r.left) / 3; 5155c6c1daeSBarry Smith height = (r.bottom - r.top) / 3; 5165c6c1daeSBarry Smith 517*9371c9d4SSatish Balay hWnd = CreateWindowEx(0, PopClassName, NULL, WS_POPUPWINDOW | WS_CAPTION, 0, 0, width, height, NULL, NULL, hInst, NULL); 5185c6c1daeSBarry Smith pop->x = 0; 5195c6c1daeSBarry Smith pop->y = 0; 5205c6c1daeSBarry Smith pop->w = width; 5215c6c1daeSBarry Smith pop->h = height; 5225c6c1daeSBarry Smith 5235c6c1daeSBarry Smith if (!hWnd) { 524fad2a674SVolker lpMsgBuf = (LPVOID) "Window Not Successfully Created"; 5255c6c1daeSBarry Smith MessageBox(NULL, (LPCTSTR)lpMsgBuf, "Error", MB_OK | MB_ICONINFORMATION); 5265c6c1daeSBarry Smith LocalFree(lpMsgBuf); 5275c6c1daeSBarry Smith exit(0); 5285c6c1daeSBarry Smith } 5295c6c1daeSBarry Smith pop->hWnd = hWnd; 5305c6c1daeSBarry Smith /* display and update new popup window */ 5315c6c1daeSBarry Smith ShowWindow(pop->hWnd, SW_SHOWNORMAL); 5325c6c1daeSBarry Smith UpdateWindow(pop->hWnd); 5335c6c1daeSBarry Smith SetEvent(pop->hReadyEvent); 5345c6c1daeSBarry Smith 5355c6c1daeSBarry Smith while (GetMessage(&msg, pop->hWnd, 0, 0)) { 5365c6c1daeSBarry Smith TranslateMessage(&msg); 5375c6c1daeSBarry Smith DispatchMessage(&msg); 5385c6c1daeSBarry Smith } 5395c6c1daeSBarry Smith PetscFunctionReturnVoid(); 5405c6c1daeSBarry Smith } 5415c6c1daeSBarry Smith 542*9371c9d4SSatish Balay static PetscErrorCode PetscDrawDestroy_Win32(PetscDraw draw) { 5435c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32 *)draw->data; 5445c6c1daeSBarry Smith 5455c6c1daeSBarry Smith PetscFunctionBegin; 5465c6c1daeSBarry Smith SendMessage(windraw->hWnd, WM_DESTROY, 0, 0); 54750c74209SLisandro Dalcin PetscFree(draw->data); 5485c6c1daeSBarry Smith PetscFunctionReturn(0); 5495c6c1daeSBarry Smith } 5505c6c1daeSBarry Smith 551*9371c9d4SSatish Balay void MessageLoopThread_Win32(PetscDraw draw) { 5525c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32 *)draw->data; 5535c6c1daeSBarry Smith MSG msg; 5545c6c1daeSBarry Smith HWND hWnd = NULL; 555fad2a674SVolker const char classname[] = "PETSc Window Class"; 5565c6c1daeSBarry Smith WNDCLASSEX wclass; 5575c6c1daeSBarry Smith LPVOID lpMsgBuf; 5585c6c1daeSBarry Smith 5595c6c1daeSBarry Smith /* initialize window class parameters */ 5605c6c1daeSBarry Smith wclass.cbSize = sizeof(WNDCLASSEX); 5615c6c1daeSBarry Smith wclass.style = CS_SAVEBITS | CS_HREDRAW | CS_VREDRAW; 5625c6c1daeSBarry Smith wclass.lpfnWndProc = (WNDPROC)PetscWndProc; 5635c6c1daeSBarry Smith wclass.cbClsExtra = 0; 5645c6c1daeSBarry Smith wclass.cbWndExtra = 0; 5655c6c1daeSBarry Smith wclass.hInstance = NULL; 5665c6c1daeSBarry Smith wclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); 5675c6c1daeSBarry Smith wclass.hCursor = LoadCursor(NULL, IDC_ARROW); 5685c6c1daeSBarry Smith wclass.hbrBackground = GetStockBrush(WHITE_BRUSH); 5695c6c1daeSBarry Smith wclass.lpszMenuName = NULL; 5705c6c1daeSBarry Smith wclass.lpszClassName = classname; 5715c6c1daeSBarry Smith wclass.hIconSm = NULL; 5725c6c1daeSBarry Smith 5735c6c1daeSBarry Smith RegisterClassEx(&wclass); 5745c6c1daeSBarry Smith 575*9371c9d4SSatish Balay hWnd = CreateWindowEx(0, classname, NULL, WS_OVERLAPPEDWINDOW, draw->x, draw->y, draw->w, draw->h, NULL, NULL, hInst, NULL); 5765c6c1daeSBarry Smith 5775c6c1daeSBarry Smith if (!hWnd) { 578fad2a674SVolker lpMsgBuf = (LPVOID) "Window Not Successfully Created"; 5795c6c1daeSBarry Smith MessageBox(NULL, (LPCTSTR)lpMsgBuf, "Error", MB_OK | MB_ICONINFORMATION); 5805c6c1daeSBarry Smith LocalFree(lpMsgBuf); 5815c6c1daeSBarry Smith exit(0); 5825c6c1daeSBarry Smith } 5835c6c1daeSBarry Smith windraw->hWnd = hWnd; 5845c6c1daeSBarry Smith /* display and update new window */ 5855c6c1daeSBarry Smith ShowWindow(hWnd, SW_SHOWNORMAL); 5865c6c1daeSBarry Smith UpdateWindow(hWnd); 5875c6c1daeSBarry Smith SetEvent(windraw->hReadyEvent); 5885c6c1daeSBarry Smith 5895c6c1daeSBarry Smith while (GetMessage(&msg, hWnd, 0, 0)) { 5905c6c1daeSBarry Smith TranslateMessage(&msg); 5915c6c1daeSBarry Smith DispatchMessage(&msg); 5925c6c1daeSBarry Smith } 593f9baa8adSSatish Balay return; 5945c6c1daeSBarry Smith } 5955c6c1daeSBarry Smith 596*9371c9d4SSatish Balay 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}; 5975c6c1daeSBarry Smith 598*9371c9d4SSatish Balay static PetscErrorCode PetscDrawGetPopup_Win32(PetscDraw draw, PetscDraw *popup) { 5994a5237bfSSatish Balay PetscDraw_Win32 *win = (PetscDraw_Win32 *)draw->data; 6004a5237bfSSatish Balay PetscBool flg = PETSC_TRUE; 6015c6c1daeSBarry Smith 6025c6c1daeSBarry Smith PetscFunctionBegin; 6039566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetBool(((PetscObject)draw)->options, ((PetscObject)draw)->prefix, "-draw_popup", &flg, NULL)); 6044a5237bfSSatish Balay if (flg) { 6059566063dSJacob Faibussowitsch PetscCall(PetscDrawCreate(PetscObjectComm((PetscObject)draw), NULL, NULL, win->x, win->y + win->h + 36, 220, 220, popup)); 6069566063dSJacob Faibussowitsch PetscCall(PetscDrawSetType(*popup, PETSC_DRAW_WIN32)); 6074a5237bfSSatish Balay draw->popup = *popup; 6084a5237bfSSatish Balay } else { 6094a5237bfSSatish Balay *popup = NULL; 6104a5237bfSSatish Balay } 6115c6c1daeSBarry Smith PetscFunctionReturn(0); 6125c6c1daeSBarry Smith } 613*9371c9d4SSatish Balay PETSC_EXTERN PetscErrorCode PetscDrawCreate_Win32(PetscDraw draw) { 6145c6c1daeSBarry Smith PetscDraw_Win32 *windraw; 6155c6c1daeSBarry Smith HANDLE hThread = NULL; 6165c6c1daeSBarry Smith WindowNode newnode; 6175c6c1daeSBarry Smith 6185c6c1daeSBarry Smith PetscFunctionBegin; 6199566063dSJacob Faibussowitsch PetscCall(PetscNew(&windraw)); 6205c6c1daeSBarry Smith draw->data = windraw; 6215c6c1daeSBarry Smith 6225c6c1daeSBarry Smith /* the following is temporary fix for initializing a global datastructure */ 623a297a907SKarl Rupp if (!g_hWindowListMutex) g_hWindowListMutex = CreateMutex(NULL, FALSE, NULL); 6249566063dSJacob Faibussowitsch PetscCall(PetscMemcpy(draw->ops, &DvOps, sizeof(DvOps))); 6255c6c1daeSBarry Smith 6265c6c1daeSBarry Smith windraw->hReadyEvent = CreateEvent(NULL, TRUE, FALSE, NULL); 6275c6c1daeSBarry Smith /* makes call to MessageLoopThread to creat window and attach a thread */ 62813d99558SMatthew G. Knepley CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)MessageLoopThread_Win32, draw, 0, (LPDWORD)hThread); 6295c6c1daeSBarry Smith CloseHandle(hThread); 6305c6c1daeSBarry Smith WaitForSingleObject(windraw->hReadyEvent, INFINITE); 6315c6c1daeSBarry Smith CloseHandle(windraw->hReadyEvent); 6325c6c1daeSBarry Smith WaitForSingleObject(g_hWindowListMutex, INFINITE); 6335c6c1daeSBarry Smith 6349566063dSJacob Faibussowitsch PetscCall(PetscNew(&newnode)); 6355c6c1daeSBarry Smith newnode->MouseListHead = NULL; 6365c6c1daeSBarry Smith newnode->MouseListTail = NULL; 6375c6c1daeSBarry Smith newnode->wnext = WindowListHead; 6385c6c1daeSBarry Smith newnode->wprev = NULL; 6395c6c1daeSBarry Smith newnode->hWnd = windraw->hWnd; 6406c4ed002SBarry Smith if (WindowListHead) WindowListHead->wprev = newnode; 6415c6c1daeSBarry Smith WindowListHead = newnode; 6425c6c1daeSBarry Smith windraw->hdc = GetDC(windraw->hWnd); 6435c6c1daeSBarry Smith 6445c6c1daeSBarry Smith windraw->stringheight = 10; 6455c6c1daeSBarry Smith windraw->stringwidth = 6; 6465c6c1daeSBarry Smith windraw->linewidth = 1; /* default pixel sizes of graphics until user changes them */ 6475c6c1daeSBarry Smith windraw->pointdiameter = 1; 6485c6c1daeSBarry Smith windraw->node = newnode; 6495c6c1daeSBarry Smith 6505c6c1daeSBarry Smith windraw->x = draw->x; 6515c6c1daeSBarry Smith windraw->y = draw->y; 6525c6c1daeSBarry Smith windraw->w = newnode->bitwidth = draw->w; 6535c6c1daeSBarry Smith windraw->h = newnode->bitheight = draw->h; 6545c6c1daeSBarry Smith 6555c6c1daeSBarry Smith /* Create and initialize primary graphics buffer */ 6565c6c1daeSBarry Smith newnode->Buffer = CreateCompatibleDC(windraw->hdc); 6575c6c1daeSBarry Smith newnode->BufferBit = CreateCompatibleBitmap(windraw->hdc, windraw->w, windraw->h); 6585c6c1daeSBarry Smith newnode->store = SelectObject(newnode->Buffer, newnode->BufferBit); 6595c6c1daeSBarry Smith ExtFloodFill(newnode->Buffer, 0, 0, COLOR_WINDOW, FLOODFILLBORDER); 6605c6c1daeSBarry Smith 6615c6c1daeSBarry Smith newnode->event = CreateEvent(NULL, TRUE, FALSE, NULL); 6625c6c1daeSBarry Smith newnode->DoubleBuffered = PETSC_FALSE; 6635c6c1daeSBarry Smith 6645c6c1daeSBarry Smith ReleaseDC(windraw->hWnd, windraw->hdc); 6655c6c1daeSBarry Smith ReleaseMutex(g_hWindowListMutex); 6665c6c1daeSBarry Smith PetscFunctionReturn(0); 6675c6c1daeSBarry Smith } 6685c6c1daeSBarry Smith 6695c6c1daeSBarry Smith /* FUNCTION: PetscWndProc(HWND, unsigned, WORD, LONG) 6705c6c1daeSBarry Smith PURPOSE: Processes messages for the main window. 6715c6c1daeSBarry Smith WM_COMMAND - process the application menu 6725c6c1daeSBarry Smith WM_PAINT - Paint the main window 6735c6c1daeSBarry Smith WM_DESTROY - post a quit message and return */ 6745c6c1daeSBarry Smith 675*9371c9d4SSatish Balay LRESULT CALLBACK PetscWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { 6767ae38d14SSatish Balay int wmId; 6775c6c1daeSBarry Smith 6785c6c1daeSBarry Smith switch (message) { 6795c6c1daeSBarry Smith HANDLE_MSG(hWnd, WM_PAINT, OnPaint_Win32); 6805c6c1daeSBarry Smith HANDLE_MSG(hWnd, WM_DESTROY, OnDestroy_Win32); 6815c6c1daeSBarry Smith case WM_COMMAND: 6825c6c1daeSBarry Smith wmId = LOWORD(wParam); 6835c6c1daeSBarry Smith /* Parse the menu selections:*/ 6845c6c1daeSBarry Smith switch (wmId) { 685*9371c9d4SSatish Balay case IDM_EXIT: DestroyWindow(hWnd); break; 686*9371c9d4SSatish Balay default: return DefWindowProc(hWnd, message, wParam, lParam); 6875c6c1daeSBarry Smith } 6885c6c1daeSBarry Smith break; 689*9371c9d4SSatish Balay case WM_LBUTTONUP: MouseRecord_Win32(hWnd, PETSC_BUTTON_LEFT); break; 690*9371c9d4SSatish Balay case WM_RBUTTONUP: MouseRecord_Win32(hWnd, PETSC_BUTTON_RIGHT); break; 691*9371c9d4SSatish Balay case WM_MBUTTONUP: MouseRecord_Win32(hWnd, PETSC_BUTTON_CENTER); break; 692*9371c9d4SSatish Balay default: return DefWindowProc(hWnd, message, wParam, lParam); 6935c6c1daeSBarry Smith } 694f9baa8adSSatish Balay return 0; 6955c6c1daeSBarry Smith } 6965c6c1daeSBarry Smith 697*9371c9d4SSatish Balay static void OnPaint_Win32(HWND hWnd) { 6985c6c1daeSBarry Smith PAINTSTRUCT ps; 6995c6c1daeSBarry Smith HDC hdc; 7005c6c1daeSBarry Smith WindowNode current = NULL; 7015c6c1daeSBarry Smith 7025c6c1daeSBarry Smith InvalidateRect(hWnd, NULL, TRUE); 7035c6c1daeSBarry Smith WaitForSingleObject(g_hWindowListMutex, INFINITE); 7045c6c1daeSBarry Smith current = WindowListHead; 7055c6c1daeSBarry Smith hdc = BeginPaint(hWnd, &ps); 7065c6c1daeSBarry Smith 7076c4ed002SBarry Smith while (current) { 7085c6c1daeSBarry Smith if (current->hWnd == hWnd) { 7095c6c1daeSBarry Smith /* flushes primary buffer to window */ 710*9371c9d4SSatish Balay BitBlt(hdc, 0, 0, GetDeviceCaps(hdc, HORZRES), GetDeviceCaps(hdc, VERTRES), current->Buffer, 0, 0, SRCCOPY); 7115c6c1daeSBarry Smith 712be332245SKarl Rupp /* StretchBlt(hdc,0,0,w,h, 713be332245SKarl Rupp current->Buffer,0,0,current->bitwidth,current->bitheight,SRCCOPY); */ 7145c6c1daeSBarry Smith break; 7155c6c1daeSBarry Smith } 7165c6c1daeSBarry Smith current = current->wnext; 7175c6c1daeSBarry Smith } 7185c6c1daeSBarry Smith EndPaint(hWnd, &ps); 7195c6c1daeSBarry Smith ReleaseMutex(g_hWindowListMutex); 720f9baa8adSSatish Balay return; 7215c6c1daeSBarry Smith } 7225c6c1daeSBarry Smith 723*9371c9d4SSatish Balay static PetscErrorCode MouseRecord_Win32(HWND hWnd, PetscDrawButton button) { 7245c6c1daeSBarry Smith /* Called by all three mouse button actions 7255c6c1daeSBarry Smith Records needed mouse data in windows data structure */ 7265c6c1daeSBarry Smith WindowNode current = NULL; 7275c6c1daeSBarry Smith MouseNode newnode; 7285c6c1daeSBarry Smith POINT mousepos; 7295c6c1daeSBarry Smith 7305c6c1daeSBarry Smith PetscFunctionBegin; 7315c6c1daeSBarry Smith WaitForSingleObject(g_hWindowListMutex, INFINITE); 7325c6c1daeSBarry Smith current = WindowListHead; 7335c6c1daeSBarry Smith if (current->IsGetMouseOn == TRUE) { 7345c6c1daeSBarry Smith SetEvent(current->event); 7356c4ed002SBarry Smith while (current) { 7365c6c1daeSBarry Smith if (current->hWnd == hWnd) { 7379566063dSJacob Faibussowitsch PetscCall(PetscNew(&newnode)); 7385c6c1daeSBarry Smith newnode->Button = button; 7395c6c1daeSBarry Smith GetCursorPos(&mousepos); 7405c6c1daeSBarry Smith newnode->user.x = mousepos.x; 7415c6c1daeSBarry Smith newnode->user.y = mousepos.y; 7425c6c1daeSBarry Smith ScreenToClient(hWnd, &mousepos); 7435c6c1daeSBarry Smith newnode->phys.x = mousepos.x; 7445c6c1daeSBarry Smith newnode->phys.y = mousepos.y; 7455c6c1daeSBarry Smith if (!current->MouseListTail) { 7465c6c1daeSBarry Smith current->MouseListHead = newnode; 7475c6c1daeSBarry Smith current->MouseListTail = newnode; 7485c6c1daeSBarry Smith } else { 7495c6c1daeSBarry Smith current->MouseListTail->mnext = newnode; 7505c6c1daeSBarry Smith current->MouseListTail = newnode; 7515c6c1daeSBarry Smith } 7525c6c1daeSBarry Smith newnode->mnext = NULL; 7535c6c1daeSBarry Smith 7545c6c1daeSBarry Smith break; 7555c6c1daeSBarry Smith } 7565c6c1daeSBarry Smith current = current->wnext; 7575c6c1daeSBarry Smith } 7585c6c1daeSBarry Smith } 7595c6c1daeSBarry Smith ReleaseMutex(g_hWindowListMutex); 7605c6c1daeSBarry Smith PetscFunctionReturn(0); 7615c6c1daeSBarry Smith } 7625c6c1daeSBarry Smith 763*9371c9d4SSatish Balay static void OnDestroy_Win32(HWND hWnd) { 7645c6c1daeSBarry Smith /* searches linked list of window data and frees corresponding memory */ 7655c6c1daeSBarry Smith WindowNode current; 7665c6c1daeSBarry Smith 7675c6c1daeSBarry Smith PetscFunctionBegin; 7685c6c1daeSBarry Smith WaitForSingleObject(g_hWindowListMutex, INFINITE); 7695c6c1daeSBarry Smith current = WindowListHead; 7705c6c1daeSBarry Smith 7715c6c1daeSBarry Smith SetEvent(current->event); 7726c4ed002SBarry Smith while (current) { 7735c6c1daeSBarry Smith if (current->hWnd == hWnd) { 7746c4ed002SBarry Smith if (current->wprev) current->wprev->wnext = current->wnext; 775a297a907SKarl Rupp else WindowListHead = current->wnext; 776a297a907SKarl Rupp if (current->MouseListHead) deletemouselist_Win32(current); 777a297a907SKarl Rupp else PetscFree(current); 7785c6c1daeSBarry Smith break; 7795c6c1daeSBarry Smith } 7805c6c1daeSBarry Smith current = current->wnext; 7815c6c1daeSBarry Smith } 7825c6c1daeSBarry Smith ReleaseMutex(g_hWindowListMutex); 7835c6c1daeSBarry Smith PostQuitMessage(0); 7845c6c1daeSBarry Smith PetscFunctionReturnVoid(); 7855c6c1daeSBarry Smith } 786