xref: /petsc/src/sys/classes/draw/impls/win32/win32draw.c (revision b00a91154f763f12aa55f3d53a3f2776f15f49e3)
15c6c1daeSBarry Smith 
25c6c1daeSBarry Smith #include <petscsys.h>
35c6c1daeSBarry 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 
255c6c1daeSBarry Smith #define XTRANS(draw,win,x) \
265c6c1daeSBarry Smith     (int)(((win)->w)*((draw)->port_xl + (((x - (draw)->coor_xl)*         \
275c6c1daeSBarry Smith                             ((draw)->port_xr - (draw)->port_xl))/        \
285c6c1daeSBarry Smith                             ((draw)->coor_xr - (draw)->coor_xl))))
295c6c1daeSBarry Smith #define YTRANS(draw,win,y) \
305c6c1daeSBarry Smith     (int)(((win)->h)*(1.0-(draw)->port_yl - (((y - (draw)->coor_yl)*     \
315c6c1daeSBarry Smith                                 ((draw)->port_yr - (draw)->port_yl))/    \
325c6c1daeSBarry Smith                                 ((draw)->coor_yr - (draw)->coor_yl))))
335c6c1daeSBarry Smith 
345c6c1daeSBarry Smith HINSTANCE  hInst;
355c6c1daeSBarry Smith HANDLE     g_hWindowListMutex = NULL;
365c6c1daeSBarry Smith WindowNode WindowListHead     = NULL;
375c6c1daeSBarry Smith 
385c6c1daeSBarry Smith /* Hard coded color hue until hue.c works with this */
395c6c1daeSBarry 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};
405c6c1daeSBarry 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};
415c6c1daeSBarry 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};
425c6c1daeSBarry Smith 
435c6c1daeSBarry Smith /* Foward declarations of functions included in this code module: */
445c6c1daeSBarry Smith LRESULT CALLBACK PetscWndProc(HWND, UINT, WPARAM, LPARAM);
455c6c1daeSBarry Smith static PetscErrorCode TranslateColor_Win32(PetscDraw,int);
465c6c1daeSBarry Smith static PetscErrorCode AverageColorRectangle_Win32(PetscDraw,int,int,int,int);
475c6c1daeSBarry Smith static PetscErrorCode AverageColorTriangle_Win32(PetscDraw,int,int,int);
485c6c1daeSBarry Smith static PetscErrorCode deletemouselist_Win32(WindowNode);
495c6c1daeSBarry Smith static void OnPaint_Win32(HWND);
505c6c1daeSBarry Smith static void OnDestroy_Win32(HWND);
515c6c1daeSBarry Smith static PetscErrorCode MouseRecord_Win32(HWND,PetscDrawButton);
525c6c1daeSBarry Smith static PetscErrorCode PetscDrawGetPopup_Win32(PetscDraw,PetscDraw*);
535c6c1daeSBarry Smith 
545c6c1daeSBarry Smith #undef __FUNCT__
555c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawSetDoubleBuffer_Win32"
565c6c1daeSBarry Smith static PetscErrorCode PetscDrawSetDoubleBuffer_Win32(PetscDraw draw)
575c6c1daeSBarry Smith {
585c6c1daeSBarry Smith   PetscDraw_Win32 *windraw = (PetscDraw_Win32*)draw->data;
595c6c1daeSBarry Smith   HDC             hdc      = GetDC(windraw->hWnd);
605c6c1daeSBarry Smith 
615c6c1daeSBarry Smith   PetscFunctionBegin;
625c6c1daeSBarry Smith   windraw->node->DoubleBuffer    = CreateCompatibleDC(hdc);
635c6c1daeSBarry Smith   windraw->node->DoubleBufferBit = CreateCompatibleBitmap(hdc,windraw->w,windraw->h);
645c6c1daeSBarry Smith   windraw->node->dbstore         = SelectObject(windraw->node->DoubleBuffer,windraw->node->DoubleBufferBit);
655c6c1daeSBarry Smith   /* Fill background of second buffer */
665c6c1daeSBarry Smith   ExtFloodFill(windraw->node->DoubleBuffer,0,0,COLOR_WINDOW,FLOODFILLBORDER);
675c6c1daeSBarry Smith   /* Copy current buffer into seconf buffer and set window data as double buffered */
68be332245SKarl Rupp   BitBlt(windraw->node->DoubleBuffer,0,0,windraw->w,windraw->h,
69be332245SKarl Rupp          windraw->node->Buffer,0,0, SRCCOPY);
705c6c1daeSBarry Smith 
715c6c1daeSBarry Smith   windraw->node->DoubleBuffered = PETSC_TRUE;
725c6c1daeSBarry Smith   ReleaseDC(windraw->hWnd,hdc);
735c6c1daeSBarry Smith   PetscFunctionReturn(0);
745c6c1daeSBarry Smith }
755c6c1daeSBarry Smith 
765c6c1daeSBarry Smith #undef __FUNCT__
775c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawFlush_Win32"
785c6c1daeSBarry Smith static PetscErrorCode PetscDrawFlush_Win32(PetscDraw draw)
795c6c1daeSBarry Smith {
805c6c1daeSBarry Smith   PetscDraw_Win32 *windraw = (PetscDraw_Win32*)draw->data;
815c6c1daeSBarry Smith   HDC             hdc      = GetDC(windraw->hWnd);
825c6c1daeSBarry Smith 
835c6c1daeSBarry Smith   PetscFunctionBegin;
845c6c1daeSBarry Smith   /* flush double buffer into primary buffer */
85be332245SKarl Rupp   BitBlt(windraw->node->Buffer,0,0,windraw->w,windraw->h,
86be332245SKarl Rupp          windraw->node->DoubleBuffer,0,0,SRCCOPY);
875c6c1daeSBarry Smith   /* flush double buffer into window */
88be332245SKarl Rupp   BitBlt(hdc,0,0,windraw->w,windraw->h,
89be332245SKarl Rupp          windraw->node->DoubleBuffer, 0,0,SRCCOPY);
905c6c1daeSBarry Smith   ReleaseDC(windraw->hWnd,hdc);
915c6c1daeSBarry Smith   PetscFunctionReturn(0);
925c6c1daeSBarry Smith }
935c6c1daeSBarry Smith 
945c6c1daeSBarry Smith #undef __FUNCT__
955c6c1daeSBarry Smith #define __FUNCT__ "deletemouselist_Win32"
965c6c1daeSBarry Smith static PetscErrorCode deletemouselist_Win32(WindowNode deletelist)
975c6c1daeSBarry Smith {
985c6c1daeSBarry Smith   /* Called upon window close. Frees memory of linked list of stored mouse commands */
995c6c1daeSBarry Smith   MouseNode node;
1005c6c1daeSBarry Smith 
1015c6c1daeSBarry Smith   while (deletelist->MouseListHead != NULL) {
1025c6c1daeSBarry Smith     node = deletelist->MouseListHead;
103a297a907SKarl Rupp     if (deletelist->MouseListHead->mnext != NULL) deletelist->MouseListHead = deletelist->MouseListHead->mnext;
1045c6c1daeSBarry Smith     PetscFree(node);
1055c6c1daeSBarry Smith   }
1065c6c1daeSBarry Smith   deletelist->MouseListHead = deletelist->MouseListTail = NULL;
107a297a907SKarl Rupp   if (deletelist->wprev != NULL) deletelist->wprev->wnext = deletelist->wnext;
108a297a907SKarl Rupp   if (deletelist->wnext != NULL) deletelist->wnext->wprev = deletelist->wprev;
1095c6c1daeSBarry Smith   PetscFree(deletelist);
1105c6c1daeSBarry Smith   return 0;
1115c6c1daeSBarry Smith }
1125c6c1daeSBarry Smith 
1135c6c1daeSBarry Smith #undef __FUNCT__
1145c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawGetMouseButton_Win32"
1155c6c1daeSBarry Smith static PetscErrorCode PetscDrawGetMouseButton_Win32(PetscDraw draw, PetscDrawButton *button,PetscReal *x_user,PetscReal *y_user,PetscReal *x_phys,PetscReal *y_phys)
1165c6c1daeSBarry Smith {
1175c6c1daeSBarry Smith   PetscDraw_Win32 *windraw = (PetscDraw_Win32*)draw->data;
1185c6c1daeSBarry Smith   WindowNode      current;
1195c6c1daeSBarry Smith   MouseNode       node=0;
1205c6c1daeSBarry Smith 
1215c6c1daeSBarry Smith   PetscFunctionBegin;
1225c6c1daeSBarry Smith   /* Make sure no other code is using the linked list at this moment */
1235c6c1daeSBarry Smith   WaitForSingleObject(g_hWindowListMutex, INFINITE);
1245c6c1daeSBarry Smith   /* Look for the node that matches the window you are using */
1255c6c1daeSBarry Smith   current = WindowListHead;
1265c6c1daeSBarry Smith   while (current != NULL) {
1275c6c1daeSBarry Smith     if (current->hWnd == windraw->hWnd) {
1285c6c1daeSBarry Smith       current->IsGetMouseOn = TRUE;
1295c6c1daeSBarry Smith       break;
130a297a907SKarl Rupp     } else current = current->wnext;
1315c6c1daeSBarry Smith   }
1325c6c1daeSBarry Smith   /* If no actions have occured, wait for one */
1335c6c1daeSBarry Smith   node = current->MouseListHead;
1345c6c1daeSBarry Smith   if (!node) {
1355c6c1daeSBarry Smith     ReleaseMutex(g_hWindowListMutex);
1365c6c1daeSBarry Smith     WaitForSingleObject(current->event, INFINITE);
1375c6c1daeSBarry Smith     WaitForSingleObject(g_hWindowListMutex, INFINITE);
1385c6c1daeSBarry Smith   }
1395c6c1daeSBarry Smith   /* once we have the information, assign the pointers to it */
1405c6c1daeSBarry Smith   *button = current->MouseListHead->Button;
1415c6c1daeSBarry Smith   *x_user = current->MouseListHead->user.x;
1425c6c1daeSBarry Smith   *y_user = current->MouseListHead->user.y;
1435c6c1daeSBarry Smith   /* optional arguments */
1445c6c1daeSBarry Smith   if (x_phys) *x_phys = current->MouseListHead->phys.x;
1455c6c1daeSBarry Smith   if (y_phys) *y_phys = current->MouseListHead->phys.y;
1465c6c1daeSBarry Smith   /* remove set of information from sub linked-list, delete the node */
1475c6c1daeSBarry Smith   current->MouseListHead = current->MouseListHead->mnext;
1485c6c1daeSBarry Smith   if (!current->MouseListHead) {
1495c6c1daeSBarry Smith     ResetEvent(current->event);
1505c6c1daeSBarry Smith     current->MouseListTail = NULL;
1515c6c1daeSBarry Smith   }
1525c6c1daeSBarry Smith   if (node) PetscFree(node);
1535c6c1daeSBarry Smith 
1545c6c1daeSBarry Smith   /* Release mutex so that  other code can use
1555c6c1daeSBarry Smith      the linked list now that we are done with it */
1565c6c1daeSBarry Smith   ReleaseMutex(g_hWindowListMutex);
1575c6c1daeSBarry Smith   PetscFunctionReturn(0);
1585c6c1daeSBarry Smith }
1595c6c1daeSBarry Smith 
1605c6c1daeSBarry Smith #undef __FUNCT__
1615c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawPause_Win32"
1625c6c1daeSBarry Smith static PetscErrorCode PetscDrawPause_Win32(PetscDraw draw)
1635c6c1daeSBarry Smith {
1645c6c1daeSBarry Smith   PetscFunctionBegin;
1655c6c1daeSBarry Smith   PetscSleep(draw->pause);
1665c6c1daeSBarry Smith   PetscFunctionReturn(0);
1675c6c1daeSBarry Smith }
1685c6c1daeSBarry Smith 
1695c6c1daeSBarry Smith #undef __FUNCT__
1705c6c1daeSBarry Smith #define __FUNCT__ "TranslateColor_Win32"
1715c6c1daeSBarry Smith static PetscErrorCode TranslateColor_Win32(PetscDraw draw,int color)
1725c6c1daeSBarry Smith {
1735c6c1daeSBarry Smith   /* Maps single color value into the RGB colors in our tables */
1745c6c1daeSBarry Smith   PetscDraw_Win32 *windraw = (PetscDraw_Win32*)draw->data;
1755c6c1daeSBarry Smith   windraw->currentcolor = RGB(RedMap[color],GreenMap[color],BlueMap[color]);
1765c6c1daeSBarry Smith   return 0;
1775c6c1daeSBarry Smith }
1785c6c1daeSBarry Smith 
1795c6c1daeSBarry Smith #undef __FUNCT__
1805c6c1daeSBarry Smith #define __FUNCT__ "AverageColorRectangle_Win32"
1815c6c1daeSBarry Smith static PetscErrorCode AverageColorRectangle_Win32(PetscDraw draw,int c1,int c2, int c3, int c4)
1825c6c1daeSBarry Smith {
1835c6c1daeSBarry Smith   /* Averages colors given at points of rectangle and sets color from color table
1845c6c1daeSBarry Smith     will be changed once the color gradient problem is worked out */
1855c6c1daeSBarry Smith   PetscDraw_Win32 *windraw = (PetscDraw_Win32*)draw->data;
1865c6c1daeSBarry Smith   windraw->currentcolor = RGB(((RedMap[c1]+RedMap[c2]+RedMap[c3]+RedMap[c4])/4),
1875c6c1daeSBarry Smith                               ((GreenMap[c1]+GreenMap[c2]+GreenMap[c3]+GreenMap[c4])/4),
1885c6c1daeSBarry Smith                               ((BlueMap[c1]+BlueMap[c2]+BlueMap[c3]+BlueMap[c4])/4));
1895c6c1daeSBarry Smith   return 0;
1905c6c1daeSBarry Smith }
1915c6c1daeSBarry Smith 
1925c6c1daeSBarry Smith #undef __FUNCT__
1935c6c1daeSBarry Smith #define __FUNCT__ "AverageColorTriangle_Win32"
1945c6c1daeSBarry Smith static PetscErrorCode AverageColorTriangle_Win32(PetscDraw draw,int c1,int c2,int c3)
1955c6c1daeSBarry Smith {
1965c6c1daeSBarry Smith   /* Averages colors given at points of rectangle and sets color from color table
1975c6c1daeSBarry Smith     will be changed once the color gradient problem is worked out */
1985c6c1daeSBarry Smith   PetscDraw_Win32 *windraw = (PetscDraw_Win32*)draw->data;
1995c6c1daeSBarry Smith   windraw->currentcolor = RGB((RedMap[c1]+RedMap[c2]+RedMap[c3])/3,
2005c6c1daeSBarry Smith                               (GreenMap[c1]+GreenMap[c2]+GreenMap[c3])/3,
2015c6c1daeSBarry Smith                               (BlueMap[c1]+BlueMap[c2]+BlueMap[c3])/3);
2025c6c1daeSBarry Smith   return 0;
2035c6c1daeSBarry Smith }
2045c6c1daeSBarry Smith 
2055c6c1daeSBarry Smith #undef __FUNCT__
2065c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawRectangle_Win32"
2075c6c1daeSBarry Smith static PetscErrorCode PetscDrawRectangle_Win32(PetscDraw draw,PetscReal xl,PetscReal yl,PetscReal xr,PetscReal yr,int c1,int c2,int c3,int c4)
2085c6c1daeSBarry Smith {
2095c6c1daeSBarry Smith   PetscDraw_Win32 *windraw = (PetscDraw_Win32*)draw->data;
2105c6c1daeSBarry Smith   HBRUSH          hbrush;
2115c6c1daeSBarry Smith   RECT            rect;
2125c6c1daeSBarry Smith   int             x1,yone,x2,y2;
2135c6c1daeSBarry Smith   HDC             hdc;
2145c6c1daeSBarry Smith 
2155c6c1daeSBarry Smith   PetscFunctionBegin;
2165c6c1daeSBarry Smith   x1   = XTRANS(draw,windraw,xl);
2175c6c1daeSBarry Smith   x2   = XTRANS(draw,windraw,xr);
2185c6c1daeSBarry Smith   yone = YTRANS(draw,windraw,yl);
2195c6c1daeSBarry Smith   y2   = YTRANS(draw,windraw,yr);
2205c6c1daeSBarry Smith   SetRect(&rect,x1,y2,x2,yone);
221a297a907SKarl Rupp   if (c1==c2 && c2==c3 && c3==c4) TranslateColor_Win32(draw,c1);
222a297a907SKarl Rupp   else AverageColorRectangle_Win32(draw,c1,c2,c3,c4);
2235c6c1daeSBarry Smith   hbrush = CreateSolidBrush(windraw->currentcolor);
2245c6c1daeSBarry Smith 
225a297a907SKarl Rupp   if (windraw->node->DoubleBuffered) hdc = windraw->node->DoubleBuffer;
226a297a907SKarl Rupp   else                               hdc = windraw->node->Buffer;
227a297a907SKarl Rupp 
2285c6c1daeSBarry Smith   FillRect(hdc,&rect,hbrush);
2295c6c1daeSBarry Smith   /* Forces a WM_PAINT message and erases background */
2305c6c1daeSBarry Smith   InvalidateRect(windraw->hWnd,NULL,TRUE);
2315c6c1daeSBarry Smith   UpdateWindow(windraw->hWnd);
2325c6c1daeSBarry Smith   PetscFunctionReturn(0);
2335c6c1daeSBarry Smith }
2345c6c1daeSBarry Smith 
2355c6c1daeSBarry Smith #undef __FUNCT__
2365c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawLine_Win32"
2375c6c1daeSBarry Smith static PetscErrorCode PetscDrawLine_Win32(PetscDraw draw,PetscReal xl,PetscReal yl,PetscReal xr,PetscReal yr,int color)
2385c6c1daeSBarry Smith {
2395c6c1daeSBarry Smith   PetscDraw_Win32 *windraw = (PetscDraw_Win32*)draw->data;
2405c6c1daeSBarry Smith   HPEN            hpen;
2415c6c1daeSBarry Smith   int             x1,yone,x2,y2;
2425c6c1daeSBarry Smith   HDC             hdc;
2435c6c1daeSBarry Smith 
2445c6c1daeSBarry Smith   PetscFunctionBegin;
2455c6c1daeSBarry Smith   TranslateColor_Win32(draw,color);
2465c6c1daeSBarry Smith   x1   = XTRANS(draw,windraw,xl);x2  = XTRANS(draw,windraw,xr);
2475c6c1daeSBarry Smith   yone = YTRANS(draw,windraw,yl);y2  = YTRANS(draw,windraw,yr);
2485c6c1daeSBarry Smith   hpen = CreatePen (PS_SOLID, windraw->linewidth, windraw->currentcolor);
249a297a907SKarl Rupp   if (windraw->node->DoubleBuffered) hdc = windraw->node->DoubleBuffer;
250a297a907SKarl Rupp   else                               hdc = windraw->node->Buffer;
251a297a907SKarl Rupp 
2525c6c1daeSBarry Smith   SelectPen(hdc,hpen);
2535c6c1daeSBarry Smith   MoveToEx(hdc,x1,yone,NULL);
2545c6c1daeSBarry Smith   LineTo(hdc,x2,y2);
2555c6c1daeSBarry Smith   /* Forces a WM_PAINT message and erases background */
2565c6c1daeSBarry Smith   InvalidateRect(windraw->hWnd,NULL,TRUE);
2575c6c1daeSBarry Smith   UpdateWindow(windraw->hWnd);
2585c6c1daeSBarry Smith   PetscFunctionReturn(0);
2595c6c1daeSBarry Smith }
2605c6c1daeSBarry Smith 
2615c6c1daeSBarry Smith #undef __FUNCT__
2625c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawLineSetWidth_Win32"
2635c6c1daeSBarry Smith static PetscErrorCode PetscDrawLineSetWidth_Win32(PetscDraw draw,PetscReal width)
2645c6c1daeSBarry Smith {
2655c6c1daeSBarry Smith   PetscDraw_Win32 *windraw = (PetscDraw_Win32*)draw->data;
2665c6c1daeSBarry Smith   int             averagesize,finalwidth;
2675c6c1daeSBarry Smith   RECT            rect;
2685c6c1daeSBarry Smith 
2695c6c1daeSBarry Smith   PetscFunctionBegin;
2705c6c1daeSBarry Smith   GetClientRect(windraw->hWnd,&rect);
2715c6c1daeSBarry Smith   averagesize = ((rect.right - rect.left)+(rect.bottom - rect.top))/2;
2725c6c1daeSBarry Smith   finalwidth  = (int)floor(averagesize*width);
273a297a907SKarl Rupp   if (finalwidth < 1) finalwidth = 1; /* minimum size PetscDrawLine can except */
274a297a907SKarl Rupp 
2755c6c1daeSBarry Smith   windraw->linewidth = finalwidth;
2765c6c1daeSBarry Smith   PetscFunctionReturn(0);
2775c6c1daeSBarry Smith }
2785c6c1daeSBarry Smith 
2795c6c1daeSBarry Smith #undef __FUNCT__
2805c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawLineGetWidth_Win32"
2815c6c1daeSBarry Smith static PetscErrorCode PetscDrawLineGetWidth_Win32(PetscDraw draw,PetscReal *width)
2825c6c1daeSBarry Smith {
2835c6c1daeSBarry Smith   PetscDraw_Win32 *windraw = (PetscDraw_Win32*)draw->data;
2845c6c1daeSBarry Smith 
2855c6c1daeSBarry Smith   PetscFunctionBegin;
2865c6c1daeSBarry Smith   *width = (PetscReal)windraw->linewidth;
2875c6c1daeSBarry Smith   PetscFunctionReturn(0);
2885c6c1daeSBarry Smith }
2895c6c1daeSBarry Smith 
2905c6c1daeSBarry Smith #undef __FUNCT__
2915c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawPoint_Win32"
2925c6c1daeSBarry Smith static PetscErrorCode PetscDrawPoint_Win32(PetscDraw draw,PetscReal x,PetscReal y,int color)
2935c6c1daeSBarry Smith {
2945c6c1daeSBarry Smith   PetscDraw_Win32 *windraw = (PetscDraw_Win32*)draw->data;
2955c6c1daeSBarry Smith   HBRUSH          hbrush;
2965c6c1daeSBarry Smith   HRGN            hrgn;
2975c6c1daeSBarry Smith   int             radius;
2985c6c1daeSBarry Smith   int             x1,yone;
2995c6c1daeSBarry Smith   HDC             hdc;
3005c6c1daeSBarry Smith 
3015c6c1daeSBarry Smith   PetscFunctionBegin;
3025c6c1daeSBarry Smith   TranslateColor_Win32(draw,color);
3035c6c1daeSBarry Smith   x1     = XTRANS(draw,windraw,x);
3045c6c1daeSBarry Smith   yone   = YTRANS(draw,windraw,y);
3055c6c1daeSBarry Smith   hbrush = CreateSolidBrush(windraw->currentcolor);
306a297a907SKarl Rupp   if (windraw->node->DoubleBuffered) hdc = windraw->node->DoubleBuffer;
307a297a907SKarl Rupp   else                               hdc = windraw->node->Buffer;
308a297a907SKarl Rupp 
3095c6c1daeSBarry Smith   /* desired size is one logical pixel so just turn it on */
310a297a907SKarl Rupp   if (windraw->pointdiameter == 1) SetPixelV(hdc,x1,yone,windraw->currentcolor);
311a297a907SKarl Rupp   else {
3125c6c1daeSBarry Smith     /* draw point around position determined */
3135c6c1daeSBarry Smith     radius = windraw->pointdiameter/2; /* integer division */
3145c6c1daeSBarry Smith     hrgn   = CreateEllipticRgn(x1-radius,yone-radius,x1+radius,yone+radius);
3155c6c1daeSBarry Smith     FillRgn(hdc,hrgn,hbrush);
3165c6c1daeSBarry Smith   }
3175c6c1daeSBarry Smith   /* Forces a WM_PAINT and erases background */
3185c6c1daeSBarry Smith   InvalidateRect(windraw->hWnd,NULL,TRUE);
3195c6c1daeSBarry Smith   UpdateWindow(windraw->hWnd);
3205c6c1daeSBarry Smith   PetscFunctionReturn(0);
3215c6c1daeSBarry Smith }
3225c6c1daeSBarry Smith 
3235c6c1daeSBarry Smith #undef __FUNCT__
3245c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawPointSetSize_Win32"
3255c6c1daeSBarry Smith static PetscErrorCode PetscDrawPointSetSize_Win32(PetscDraw draw,PetscReal width)
3265c6c1daeSBarry Smith {
3275c6c1daeSBarry Smith   PetscDraw_Win32 *windraw = (PetscDraw_Win32*)draw->data;
3285c6c1daeSBarry Smith   int             averagesize,diameter;
3295c6c1daeSBarry Smith   RECT            rect;
3305c6c1daeSBarry Smith 
3315c6c1daeSBarry Smith   PetscFunctionBegin;
3325c6c1daeSBarry Smith   GetClientRect(windraw->hWnd,&rect);
3335c6c1daeSBarry Smith   averagesize = ((rect.right - rect.left)+(rect.bottom - rect.top))/2;
3345c6c1daeSBarry Smith   diameter    = (int)floor(averagesize*width);
3355c6c1daeSBarry Smith   if (diameter < 1) diameter = 1;
3365c6c1daeSBarry Smith   windraw->pointdiameter = diameter;
3375c6c1daeSBarry Smith   PetscFunctionReturn(0);
3385c6c1daeSBarry Smith }
3395c6c1daeSBarry Smith 
3405c6c1daeSBarry Smith #undef __FUNCT__
3415c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawString_Win32"
3425c6c1daeSBarry Smith static PetscErrorCode PetscDrawString_Win32(PetscDraw draw,PetscReal x,PetscReal y,int color,const char *text)
3435c6c1daeSBarry Smith {
3445c6c1daeSBarry Smith   PetscDraw_Win32 *windraw = (PetscDraw_Win32*)draw->data;
3455c6c1daeSBarry Smith   RECT            r;
3465c6c1daeSBarry Smith   HFONT           hfont;
3475c6c1daeSBarry Smith   LOGFONT         logfont;
3485c6c1daeSBarry Smith   int             x1,yone;
3495c6c1daeSBarry Smith   HDC             hdc;
3505c6c1daeSBarry Smith 
3515c6c1daeSBarry Smith   PetscFunctionBegin;
3525c6c1daeSBarry Smith   x1       = XTRANS(draw,windraw,x);
3535c6c1daeSBarry Smith   yone     = YTRANS(draw,windraw,y);
3545c6c1daeSBarry Smith   r.bottom = yone;
3555c6c1daeSBarry Smith   r.left   = x1;
3565c6c1daeSBarry Smith   r.right  = x1 + 1;
3575c6c1daeSBarry Smith   r.top    = yone + 1;
358a297a907SKarl Rupp 
3595c6c1daeSBarry Smith   logfont.lfHeight         = windraw->stringheight;
3605c6c1daeSBarry Smith   logfont.lfWidth          = windraw->stringwidth;
3615c6c1daeSBarry Smith   logfont.lfEscapement     = 0;
3625c6c1daeSBarry Smith   logfont.lfOrientation    = 0;
3635c6c1daeSBarry Smith   logfont.lfCharSet        = 0;
3645c6c1daeSBarry Smith   logfont.lfClipPrecision  = 0;
3655c6c1daeSBarry Smith   logfont.lfItalic         = 0;
3665c6c1daeSBarry Smith   logfont.lfOutPrecision   = 0;
3675c6c1daeSBarry Smith   logfont.lfPitchAndFamily = DEFAULT_PITCH;
3685c6c1daeSBarry Smith   logfont.lfQuality        = DEFAULT_QUALITY;
3695c6c1daeSBarry Smith   logfont.lfStrikeOut      = 0;
3705c6c1daeSBarry Smith   logfont.lfUnderline      = 0;
3715c6c1daeSBarry Smith   logfont.lfWeight         = FW_NORMAL;
372a297a907SKarl Rupp 
3735c6c1daeSBarry Smith   hfont = CreateFontIndirect(&logfont);
3745c6c1daeSBarry Smith   TranslateColor_Win32(draw,color);
375a297a907SKarl Rupp   if (windraw->node->DoubleBuffered) hdc = windraw->node->DoubleBuffer;
376a297a907SKarl Rupp   else                               hdc = windraw->node->Buffer;
377a297a907SKarl Rupp 
3785c6c1daeSBarry Smith   SelectFont(hdc,hfont);
3795c6c1daeSBarry Smith   SetTextColor(hdc,windraw->currentcolor);
3805c6c1daeSBarry Smith   DrawText(hdc,text,lstrlen(text),&r,DT_NOCLIP);
3815c6c1daeSBarry Smith   DeleteObject(hfont);
3825c6c1daeSBarry Smith   /* Forces a WM_PAINT message and erases background */
3835c6c1daeSBarry Smith   InvalidateRect(windraw->hWnd,NULL,TRUE);
3845c6c1daeSBarry Smith   UpdateWindow(windraw->hWnd);
3855c6c1daeSBarry Smith   PetscFunctionReturn(0);
3865c6c1daeSBarry Smith }
3875c6c1daeSBarry Smith 
3885c6c1daeSBarry Smith #undef __FUNCT__
3895c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawStringVertical_Win32"
3905c6c1daeSBarry Smith static PetscErrorCode PetscDrawStringVertical_Win32(PetscDraw draw,PetscReal x,PetscReal y,int color,const char *text)
3915c6c1daeSBarry Smith {
3925c6c1daeSBarry Smith   PetscDraw_Win32 *windraw = (PetscDraw_Win32*)draw->data;
3935c6c1daeSBarry Smith   RECT            r;
3945c6c1daeSBarry Smith   HFONT           hfont;
3955c6c1daeSBarry Smith   LOGFONT         logfont;
3965c6c1daeSBarry Smith   int             x1,yone;
3975c6c1daeSBarry Smith   HDC             hdc;
3985c6c1daeSBarry Smith 
3995c6c1daeSBarry Smith   PetscFunctionBegin;
4005c6c1daeSBarry Smith   x1       = XTRANS(draw,windraw,x);
4015c6c1daeSBarry Smith   yone     = YTRANS(draw,windraw,y);
4025c6c1daeSBarry Smith   r.left   = x1;
4035c6c1daeSBarry Smith   r.bottom = yone + 30;
4045c6c1daeSBarry Smith   r.right  = x1 + 1;
4055c6c1daeSBarry Smith   r.top    = yone - 30;
406a297a907SKarl Rupp 
4075c6c1daeSBarry Smith   logfont.lfEscapement     = 2700; /* Causes verticle text drawing */
4085c6c1daeSBarry Smith   logfont.lfHeight         = windraw->stringheight;
4095c6c1daeSBarry Smith   logfont.lfWidth          = windraw->stringwidth;
4105c6c1daeSBarry Smith   logfont.lfOrientation    = 0;
4115c6c1daeSBarry Smith   logfont.lfCharSet        = DEFAULT_CHARSET;
4125c6c1daeSBarry Smith   logfont.lfClipPrecision  = 0;
4135c6c1daeSBarry Smith   logfont.lfItalic         = 0;
4145c6c1daeSBarry Smith   logfont.lfOutPrecision   = 0;
4155c6c1daeSBarry Smith   logfont.lfPitchAndFamily = DEFAULT_PITCH;
4165c6c1daeSBarry Smith   logfont.lfQuality        = DEFAULT_QUALITY;
4175c6c1daeSBarry Smith   logfont.lfStrikeOut      = 0;
4185c6c1daeSBarry Smith   logfont.lfUnderline      = 0;
4195c6c1daeSBarry Smith   logfont.lfWeight         = FW_NORMAL;
420a297a907SKarl Rupp 
4215c6c1daeSBarry Smith   hfont = CreateFontIndirect(&logfont);
4225c6c1daeSBarry Smith   TranslateColor_Win32(draw,color);
423a297a907SKarl Rupp   if (windraw->node->DoubleBuffered) hdc = windraw->node->DoubleBuffer;
424a297a907SKarl Rupp   else                               hdc = windraw->node->Buffer;
425a297a907SKarl Rupp 
4265c6c1daeSBarry Smith   SelectFont(hdc,hfont);
4275c6c1daeSBarry Smith   SetTextColor(hdc,windraw->currentcolor);
4285c6c1daeSBarry Smith   DrawText(hdc,text,lstrlen(text),&r,DT_NOCLIP | DT_SINGLELINE);
4295c6c1daeSBarry Smith   DeleteObject(hfont);
4305c6c1daeSBarry Smith   /* Forces a WM_PAINT message and erases background */
4315c6c1daeSBarry Smith   InvalidateRect(windraw->hWnd,NULL,TRUE);
4325c6c1daeSBarry Smith   UpdateWindow(windraw->hWnd);
4335c6c1daeSBarry Smith   PetscFunctionReturn(0);
4345c6c1daeSBarry Smith }
4355c6c1daeSBarry Smith 
4365c6c1daeSBarry Smith #undef __FUNCT__
4375c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawStringSetSize_Win32"
4385c6c1daeSBarry Smith static PetscErrorCode PetscDrawStringSetSize_Win32(PetscDraw draw,PetscReal width,PetscReal height)
4395c6c1daeSBarry Smith {
4405c6c1daeSBarry Smith   PetscDraw_Win32 *windraw = (PetscDraw_Win32*)draw->data;
4415c6c1daeSBarry Smith   int             w,h;
4425c6c1daeSBarry Smith 
4435c6c1daeSBarry Smith   PetscFunctionBegin;
4445c6c1daeSBarry Smith   w = (int)((windraw->w)*width *(draw->port_xr - draw->port_xl)/(draw->coor_xr - draw->coor_xl));
4455c6c1daeSBarry Smith   h = (int)((windraw->h)*height*(draw->port_yr - draw->port_yl)/(draw->coor_yr - draw->coor_yl));
4465c6c1daeSBarry Smith   if (h < 1) h = 1;
4475c6c1daeSBarry Smith   if (w < 1) w = 1;
4485c6c1daeSBarry Smith   windraw->stringheight = h;
4495c6c1daeSBarry Smith   windraw->stringwidth  = w;
4505c6c1daeSBarry Smith   PetscFunctionReturn(0);
4515c6c1daeSBarry Smith }
4525c6c1daeSBarry Smith #undef __FUNCT__
4535c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawStringGetSize_Win32"
4545c6c1daeSBarry Smith static PetscErrorCode PetscDrawStringGetSize_Win32(PetscDraw draw,PetscReal *width,PetscReal *height)
4555c6c1daeSBarry Smith {
4565c6c1daeSBarry Smith   PetscDraw_Win32 *windraw = (PetscDraw_Win32*)draw->data;
4575c6c1daeSBarry Smith   double          scaleX   = (draw->coor_xr - draw->coor_xl)/(draw->w)*(draw->port_xr - draw->port_xl);
4585c6c1daeSBarry Smith   double          scaleY   = (draw->coor_yr - draw->coor_yl)/(draw->h)*(draw->port_yr - draw->port_yl);
4595c6c1daeSBarry Smith 
4605c6c1daeSBarry Smith   PetscFunctionBegin;
4615c6c1daeSBarry Smith   *height = (double)windraw->stringheight*scaleY;
4625c6c1daeSBarry Smith   *width  = (double)windraw->stringwidth*scaleX;
4635c6c1daeSBarry Smith   PetscFunctionReturn(0);
4645c6c1daeSBarry Smith }
4655c6c1daeSBarry Smith 
4665c6c1daeSBarry Smith #undef __FUNCT__
4675c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawResizeWindow_Win32"
4685c6c1daeSBarry Smith static PetscErrorCode PetscDrawResizeWindow_Win32(PetscDraw draw,int w,int h)
4695c6c1daeSBarry Smith {
4705c6c1daeSBarry Smith   PetscDraw_Win32 *windraw = (PetscDraw_Win32*)draw->data;
4715c6c1daeSBarry Smith   RECT            r;
4725c6c1daeSBarry Smith 
4735c6c1daeSBarry Smith   PetscFunctionBegin;
4745c6c1daeSBarry Smith   GetWindowRect(windraw->hWnd,&r);
4755c6c1daeSBarry Smith   MoveWindow(windraw->hWnd,r.left,r.top,(int)w,(int)h,TRUE);
4765c6c1daeSBarry Smith   /* set all variable dealing with window dimensions */
4775c6c1daeSBarry Smith   windraw->node->bitheight = windraw->h = draw->h = h;
4785c6c1daeSBarry Smith   windraw->node->bitwidth  = windraw->w = draw->w = w;
4795c6c1daeSBarry Smith   /* set up graphic buffers with the new size of window */
4805c6c1daeSBarry Smith   SetBitmapDimensionEx(windraw->node->BufferBit,w,h,NULL);
481a297a907SKarl Rupp   if (windraw->node->DoubleBuffered) SetBitmapDimensionEx(windraw->node->DoubleBufferBit,w,h,NULL);
4825c6c1daeSBarry Smith   windraw->haveresized = PETSC_TRUE;
4835c6c1daeSBarry Smith   PetscFunctionReturn(0);
4845c6c1daeSBarry Smith }
4855c6c1daeSBarry Smith 
4865c6c1daeSBarry Smith #undef __FUNCT__
4875c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawCheckResizeWindow_Win32"
4885c6c1daeSBarry Smith static PetscErrorCode PetscDrawCheckResizedWindow_Win32(PetscDraw draw)
4895c6c1daeSBarry Smith {
4905c6c1daeSBarry Smith   PetscDraw_Win32 *windraw = (PetscDraw_Win32*)draw->data;
4915c6c1daeSBarry Smith 
4925c6c1daeSBarry Smith   PetscFunctionBegin;
493a297a907SKarl Rupp   if (windraw->haveresized == 1) PetscFunctionReturn(1);
494a297a907SKarl Rupp   else PetscFunctionReturn(0);
4955c6c1daeSBarry Smith }
4965c6c1daeSBarry Smith 
4975c6c1daeSBarry Smith #undef __FUNCT__
4985c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawSetTitle_Win32"
4995c6c1daeSBarry Smith static PetscErrorCode PetscDrawSetTitle_Win32(PetscDraw draw, const char title[])
5005c6c1daeSBarry Smith {
5015c6c1daeSBarry Smith   PetscDraw_Win32 *windraw = (PetscDraw_Win32*)draw->data;
5025c6c1daeSBarry Smith 
5035c6c1daeSBarry Smith   PetscFunctionBegin;
5045c6c1daeSBarry Smith   SetWindowText(windraw->hWnd,title);
5055c6c1daeSBarry Smith   PetscFunctionReturn(0);
5065c6c1daeSBarry Smith }
5075c6c1daeSBarry Smith 
5085c6c1daeSBarry Smith #undef __FUNCT__
5095c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawClear_Win32"
5105c6c1daeSBarry Smith static PetscErrorCode PetscDrawClear_Win32(PetscDraw draw)
5115c6c1daeSBarry Smith {
5125c6c1daeSBarry Smith   PetscDraw_Win32 *windraw = (PetscDraw_Win32*)draw->data;
5135c6c1daeSBarry Smith 
5145c6c1daeSBarry Smith   PetscFunctionBegin;
5155c6c1daeSBarry Smith   /* clear primary buffer */
5165c6c1daeSBarry Smith   ExtFloodFill(windraw->node->Buffer,0,0,COLOR_WINDOW,FLOODFILLBORDER);
5175c6c1daeSBarry Smith   /* if exists clear secondary buffer */
518a297a907SKarl Rupp   if (windraw->node->DoubleBuffered) ExtFloodFill(windraw->node->DoubleBuffer,0,0,COLOR_WINDOW,FLOODFILLBORDER);
519a297a907SKarl Rupp 
5205c6c1daeSBarry Smith   /* force WM_PAINT message so cleared buffer will show */
5215c6c1daeSBarry Smith   InvalidateRect(windraw->hWnd,NULL,TRUE);
5225c6c1daeSBarry Smith   UpdateWindow(windraw->hWnd);
5235c6c1daeSBarry Smith   PetscFunctionReturn(0);
5245c6c1daeSBarry Smith }
5255c6c1daeSBarry Smith 
5265c6c1daeSBarry Smith #undef __FUNCT__
5275c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawTriangle_Win32"
5285c6c1daeSBarry Smith static PetscErrorCode PetscDrawTriangle_Win32(PetscDraw draw,PetscReal x1,PetscReal yone,PetscReal x2,PetscReal y2,
5295c6c1daeSBarry Smith                                               PetscReal x3,PetscReal y3,int c1,int c2,int c3)
5305c6c1daeSBarry Smith {
5315c6c1daeSBarry Smith   PetscDraw_Win32 *windraw = (PetscDraw_Win32*)draw->data;
5325c6c1daeSBarry Smith   HBRUSH          hbrush;
5335c6c1daeSBarry Smith   HPEN            hpen;
5345c6c1daeSBarry Smith   int             p1x,p1y,p2x,p2y,p3x,p3y;
5355c6c1daeSBarry Smith   HDC             bit;
5365c6c1daeSBarry Smith 
5375c6c1daeSBarry Smith   PetscFunctionBegin;
5385c6c1daeSBarry Smith   AverageColorTriangle_Win32(draw,c1,c2,c3);
5395c6c1daeSBarry Smith   hbrush = CreateSolidBrush(windraw->currentcolor);
5405c6c1daeSBarry Smith   hpen   = CreatePen(PS_SOLID,0,windraw->currentcolor);
5415c6c1daeSBarry Smith   p1x    = XTRANS(draw,windraw,x1);
5425c6c1daeSBarry Smith   p2x    = XTRANS(draw,windraw,x2);
5435c6c1daeSBarry Smith   p3x    = XTRANS(draw,windraw,x3);
5445c6c1daeSBarry Smith   p1y    = YTRANS(draw,windraw,yone);
5455c6c1daeSBarry Smith   p2y    = YTRANS(draw,windraw,y2);
5465c6c1daeSBarry Smith   p3y    = YTRANS(draw,windraw,y3);
5475c6c1daeSBarry Smith 
548a297a907SKarl Rupp   if (windraw->node->DoubleBuffered) bit = windraw->node->DoubleBuffer;
549a297a907SKarl Rupp   else                               bit = windraw->node->Buffer;
550a297a907SKarl Rupp 
5515c6c1daeSBarry Smith   BeginPath(bit);
5525c6c1daeSBarry Smith   MoveToEx(bit,p1x,p1y,NULL);
5535c6c1daeSBarry Smith   LineTo(bit,p2x,p2y);
5545c6c1daeSBarry Smith   LineTo(bit,p3x,p3y);
5555c6c1daeSBarry Smith   LineTo(bit,p1x,p1y);
5565c6c1daeSBarry Smith   EndPath(bit);
5575c6c1daeSBarry Smith   SelectPen(bit,hpen);
5585c6c1daeSBarry Smith   SelectBrush(bit,hbrush);
5595c6c1daeSBarry Smith   StrokeAndFillPath(bit);
5605c6c1daeSBarry Smith   /* Forces a WM_PAINT message and erases background */
5615c6c1daeSBarry Smith   InvalidateRect(windraw->hWnd,NULL,TRUE);
5625c6c1daeSBarry Smith   UpdateWindow(windraw->hWnd);
5635c6c1daeSBarry Smith   PetscFunctionReturn(0);
5645c6c1daeSBarry Smith }
5655c6c1daeSBarry Smith 
5665c6c1daeSBarry Smith #undef __FUNCT__
5675c6c1daeSBarry Smith #define __FUNCT__ "PopMessageLoopThread_Win32"
5685c6c1daeSBarry Smith void PopMessageLoopThread_Win32(PetscDraw popdraw)
5695c6c1daeSBarry Smith {
5705c6c1daeSBarry Smith   PetscDraw_Win32 *pop = (PetscDraw_Win32*)popdraw->data;
5715c6c1daeSBarry Smith   MSG             msg;
5725c6c1daeSBarry Smith   HWND            hWnd = NULL;
5735c6c1daeSBarry Smith   char            PopClassName [MAX_LOADSTRING + 1];
5745c6c1daeSBarry Smith   RECT            r;
5755c6c1daeSBarry Smith   int             width,height;
5765c6c1daeSBarry Smith   WNDCLASSEX      myclass;
5775c6c1daeSBarry Smith   LPVOID          lpMsgBuf;
5785c6c1daeSBarry Smith 
5795c6c1daeSBarry Smith   PetscFunctionBegin;
5805c6c1daeSBarry Smith   /* initialize window class parameters */
5815c6c1daeSBarry Smith   myclass.cbSize        = sizeof(WNDCLASSEX);
5825c6c1daeSBarry Smith   myclass.style         = CS_OWNDC;
5835c6c1daeSBarry Smith   myclass.lpfnWndProc   = (WNDPROC)PetscWndProc;
5845c6c1daeSBarry Smith   myclass.cbClsExtra    = 0;
5855c6c1daeSBarry Smith   myclass.cbWndExtra    = 0;
5865c6c1daeSBarry Smith   myclass.hInstance     = NULL;
5875c6c1daeSBarry Smith   myclass.hIcon         = NULL;
5885c6c1daeSBarry Smith   myclass.hCursor       = LoadCursor(NULL, IDC_ARROW);
5895c6c1daeSBarry Smith   myclass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
5905c6c1daeSBarry Smith   myclass.lpszMenuName  = NULL;
5915c6c1daeSBarry Smith   myclass.lpszClassName = PopClassName;
5925c6c1daeSBarry Smith   myclass.hIconSm       = NULL;
5935c6c1daeSBarry Smith 
5945c6c1daeSBarry Smith   RegisterClassEx(&myclass);
5955c6c1daeSBarry Smith 
5965c6c1daeSBarry Smith   SetRect(&r,0,0,450,450);
5975c6c1daeSBarry Smith 
5985c6c1daeSBarry Smith   width  = (r.right - r.left) / 3;
5995c6c1daeSBarry Smith   height = (r.bottom - r.top) / 3;
6005c6c1daeSBarry Smith 
6015c6c1daeSBarry Smith   hWnd = CreateWindowEx(0,
6025c6c1daeSBarry Smith                         PopClassName,
6035c6c1daeSBarry Smith                         NULL,
6045c6c1daeSBarry Smith                         WS_POPUPWINDOW | WS_CAPTION,
6055c6c1daeSBarry Smith                         0,0,
6065c6c1daeSBarry Smith                         width,height,
6075c6c1daeSBarry Smith                         NULL,
6085c6c1daeSBarry Smith                         NULL,
6095c6c1daeSBarry Smith                         hInst,
6105c6c1daeSBarry Smith                         NULL);
6115c6c1daeSBarry Smith   pop->x = 0;
6125c6c1daeSBarry Smith   pop->y = 0;
6135c6c1daeSBarry Smith   pop->w = width;
6145c6c1daeSBarry Smith   pop->h = height;
6155c6c1daeSBarry Smith 
6165c6c1daeSBarry Smith   if (!hWnd) {
6175c6c1daeSBarry Smith     lpMsgBuf = (LPVOID)"Window Not Succesfully Created";
6185c6c1daeSBarry Smith     MessageBox(NULL, (LPCTSTR)lpMsgBuf, "Error", MB_OK | MB_ICONINFORMATION);
6195c6c1daeSBarry Smith     LocalFree(lpMsgBuf);
6205c6c1daeSBarry Smith     exit(0);
6215c6c1daeSBarry Smith   }
6225c6c1daeSBarry Smith   pop->hWnd = hWnd;
6235c6c1daeSBarry Smith   /* display and update new popup window */
6245c6c1daeSBarry Smith   ShowWindow(pop->hWnd, SW_SHOWNORMAL);
6255c6c1daeSBarry Smith   UpdateWindow(pop->hWnd);
6265c6c1daeSBarry Smith   SetEvent(pop->hReadyEvent);
6275c6c1daeSBarry Smith 
6285c6c1daeSBarry Smith   while (GetMessage(&msg, pop->hWnd, 0, 0)) {
6295c6c1daeSBarry Smith     TranslateMessage(&msg);
6305c6c1daeSBarry Smith     DispatchMessage(&msg);
6315c6c1daeSBarry Smith   }
6325c6c1daeSBarry Smith   PetscFunctionReturnVoid();
6335c6c1daeSBarry Smith }
6345c6c1daeSBarry Smith 
6355c6c1daeSBarry Smith #undef __FUNCT__
6365c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawDestroy_Win32"
6375c6c1daeSBarry Smith static PetscErrorCode PetscDrawDestroy_Win32(PetscDraw draw)
6385c6c1daeSBarry Smith {
6395c6c1daeSBarry Smith   PetscDraw_Win32 *windraw = (PetscDraw_Win32*)draw->data;
6405c6c1daeSBarry Smith 
6415c6c1daeSBarry Smith   PetscFunctionBegin;
6425c6c1daeSBarry Smith   SendMessage(windraw->hWnd,WM_DESTROY,0,0);
6435c6c1daeSBarry Smith   PetscFree(windraw);
6445c6c1daeSBarry Smith   PetscFunctionReturn(0);
6455c6c1daeSBarry Smith }
6465c6c1daeSBarry Smith 
6475c6c1daeSBarry Smith #undef __FUNCT__
6485c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawSynchronizedFlush_Win32"
6495c6c1daeSBarry Smith static PetscErrorCode PetscDrawSynchronizedFlush_Win32(PetscDraw draw)
6505c6c1daeSBarry Smith {
6515c6c1daeSBarry Smith   /* Multi Processor is not implemeted yet */
6525c6c1daeSBarry Smith   PetscFunctionBegin;
6535c6c1daeSBarry Smith   PetscDrawFlush_Win32(draw);
6545c6c1daeSBarry Smith   PetscFunctionReturn(0);
6555c6c1daeSBarry Smith }
6565c6c1daeSBarry Smith 
6575c6c1daeSBarry Smith #undef __FUNCT__
6585c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawSynchronizedClear_Win32"
6595c6c1daeSBarry Smith static PetscErrorCode PetscDrawSynchronizedClear_Win32(PetscDraw draw)
6605c6c1daeSBarry Smith {
6615c6c1daeSBarry Smith   /* Multi Processor is not implemeted yet */
6625c6c1daeSBarry Smith   PetscFunctionBegin;
6635c6c1daeSBarry Smith   PetscDrawClear_Win32(draw);
6645c6c1daeSBarry Smith   PetscFunctionReturn(0);
6655c6c1daeSBarry Smith }
6665c6c1daeSBarry Smith 
6675c6c1daeSBarry Smith #undef __FUNCT__
6685c6c1daeSBarry Smith #define __FUNCT__ "MessageLoopThread_Win32"
6695c6c1daeSBarry Smith void MessageLoopThread_Win32(PetscDraw draw)
6705c6c1daeSBarry Smith {
6715c6c1daeSBarry Smith   PetscDraw_Win32 *windraw = (PetscDraw_Win32*)draw->data;
6725c6c1daeSBarry Smith   MSG             msg;
6735c6c1daeSBarry Smith   HWND            hWnd = NULL;
6745c6c1daeSBarry Smith   char            classname[MAX_LOADSTRING + 1];
6755c6c1daeSBarry Smith   WNDCLASSEX      wclass;
6765c6c1daeSBarry Smith   LPVOID          lpMsgBuf;
6775c6c1daeSBarry Smith 
6785c6c1daeSBarry Smith   PetscFunctionBegin;
6795c6c1daeSBarry Smith   /* initialize window class parameters */
6805c6c1daeSBarry Smith   wclass.cbSize        = sizeof(WNDCLASSEX);
6815c6c1daeSBarry Smith   wclass.style         = CS_SAVEBITS | CS_HREDRAW | CS_VREDRAW;
6825c6c1daeSBarry Smith   wclass.lpfnWndProc   = (WNDPROC)PetscWndProc;
6835c6c1daeSBarry Smith   wclass.cbClsExtra    = 0;
6845c6c1daeSBarry Smith   wclass.cbWndExtra    = 0;
6855c6c1daeSBarry Smith   wclass.hInstance     = NULL;
6865c6c1daeSBarry Smith   wclass.hIcon         = LoadIcon(NULL,IDI_APPLICATION);
6875c6c1daeSBarry Smith   wclass.hCursor       = LoadCursor(NULL,IDC_ARROW);
6885c6c1daeSBarry Smith   wclass.hbrBackground = GetStockBrush(WHITE_BRUSH);
6895c6c1daeSBarry Smith   wclass.lpszMenuName  = NULL;
6905c6c1daeSBarry Smith   wclass.lpszClassName = classname;
6915c6c1daeSBarry Smith   wclass.hIconSm       = NULL;
6925c6c1daeSBarry Smith 
6935c6c1daeSBarry Smith   RegisterClassEx(&wclass);
6945c6c1daeSBarry Smith 
6955c6c1daeSBarry Smith 
6965c6c1daeSBarry Smith   hWnd = CreateWindowEx(0,
6975c6c1daeSBarry Smith                         classname,
6985c6c1daeSBarry Smith                         NULL,
6995c6c1daeSBarry Smith                         WS_OVERLAPPEDWINDOW,
7005c6c1daeSBarry Smith                         draw->x,
7015c6c1daeSBarry Smith                         draw->y,
7025c6c1daeSBarry Smith                         draw->w,
7035c6c1daeSBarry Smith                         draw->h,
7045c6c1daeSBarry Smith                         NULL,
7055c6c1daeSBarry Smith                         NULL,
7065c6c1daeSBarry Smith                         hInst,
7075c6c1daeSBarry Smith                         NULL);
7085c6c1daeSBarry Smith 
7095c6c1daeSBarry Smith   if (!hWnd) {
7105c6c1daeSBarry Smith     lpMsgBuf = (LPVOID)"Window Not Succesfully Created";
7115c6c1daeSBarry Smith     MessageBox(NULL, (LPCTSTR)lpMsgBuf, "Error", MB_OK | MB_ICONINFORMATION);
7125c6c1daeSBarry Smith     LocalFree(lpMsgBuf);
7135c6c1daeSBarry Smith     exit(0);
7145c6c1daeSBarry Smith   }
7155c6c1daeSBarry Smith   windraw->hWnd = hWnd;
7165c6c1daeSBarry Smith   /* display and update new window */
7175c6c1daeSBarry Smith   ShowWindow(hWnd,SW_SHOWNORMAL);
7185c6c1daeSBarry Smith   UpdateWindow(hWnd);
7195c6c1daeSBarry Smith   SetEvent(windraw->hReadyEvent);
7205c6c1daeSBarry Smith 
7215c6c1daeSBarry Smith   while (GetMessage(&msg,hWnd, 0, 0)) {
7225c6c1daeSBarry Smith     TranslateMessage(&msg);
7235c6c1daeSBarry Smith     DispatchMessage(&msg);
7245c6c1daeSBarry Smith   }
7255c6c1daeSBarry Smith   PetscFunctionReturnVoid();
7265c6c1daeSBarry Smith }
7275c6c1daeSBarry Smith 
7285c6c1daeSBarry Smith 
7295c6c1daeSBarry Smith static struct _PetscDrawOps DvOps = { PetscDrawSetDoubleBuffer_Win32,
7305c6c1daeSBarry Smith                                       PetscDrawFlush_Win32,
7315c6c1daeSBarry Smith                                       PetscDrawLine_Win32,
7325c6c1daeSBarry Smith                                       PetscDrawLineSetWidth_Win32,
7335c6c1daeSBarry Smith                                       PetscDrawLineGetWidth_Win32,
7345c6c1daeSBarry Smith                                       PetscDrawPoint_Win32,
7355c6c1daeSBarry Smith                                       PetscDrawPointSetSize_Win32,
7365c6c1daeSBarry Smith                                       PetscDrawString_Win32,
7375c6c1daeSBarry Smith                                       PetscDrawStringVertical_Win32,
7385c6c1daeSBarry Smith                                       PetscDrawStringSetSize_Win32,
7395c6c1daeSBarry Smith                                       PetscDrawStringGetSize_Win32,
7405c6c1daeSBarry Smith                                       0,
7415c6c1daeSBarry Smith                                       PetscDrawClear_Win32,
7425c6c1daeSBarry Smith                                       PetscDrawSynchronizedFlush_Win32,
7435c6c1daeSBarry Smith                                       PetscDrawRectangle_Win32,
7445c6c1daeSBarry Smith                                       PetscDrawTriangle_Win32,
7455c6c1daeSBarry Smith                                       0,
7465c6c1daeSBarry Smith                                       PetscDrawGetMouseButton_Win32,
7475c6c1daeSBarry Smith                                       PetscDrawPause_Win32,
7485c6c1daeSBarry Smith                                       PetscDrawSynchronizedClear_Win32,
7495c6c1daeSBarry Smith                                       0,
7505c6c1daeSBarry Smith                                       0,
7515c6c1daeSBarry Smith                                       PetscDrawGetPopup_Win32,
7525c6c1daeSBarry Smith                                       PetscDrawSetTitle_Win32,
7535c6c1daeSBarry Smith                                       PetscDrawCheckResizedWindow_Win32,
7545c6c1daeSBarry Smith                                       PetscDrawResizeWindow_Win32,
7555c6c1daeSBarry Smith                                       PetscDrawDestroy_Win32,
7565c6c1daeSBarry Smith                                       0,
7575c6c1daeSBarry Smith                                       0,
7585c6c1daeSBarry Smith                                       0,
7595c6c1daeSBarry Smith                                       0};
7605c6c1daeSBarry Smith 
7615c6c1daeSBarry Smith #undef __FUNCT__
7625c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawGetPopup_Win32"
7635c6c1daeSBarry Smith static PetscErrorCode PetscDrawGetPopup_Win32(PetscDraw draw,PetscDraw *popdraw)
7645c6c1daeSBarry Smith {
7655c6c1daeSBarry Smith   PetscDraw_Win32 *pop;
7665c6c1daeSBarry Smith   HANDLE          hThread = NULL;
7675c6c1daeSBarry Smith   WindowNode      newnode;
7685c6c1daeSBarry Smith   PetscErrorCode  ierr;
7695c6c1daeSBarry Smith 
7705c6c1daeSBarry Smith   PetscFunctionBegin;
771*b00a9115SJed Brown   ierr = PetscNew(&pop);CHKERRQ(ierr);
772a297a907SKarl Rupp 
7735c6c1daeSBarry Smith   (*popdraw)->data = pop;
7745c6c1daeSBarry Smith 
7755c6c1daeSBarry Smith   /* the following is temporary fix for initializing a global datastructure */
776a297a907SKarl Rupp   if (!g_hWindowListMutex) g_hWindowListMutex = CreateMutex(NULL,FALSE,NULL);
7775c6c1daeSBarry Smith   ierr = PetscMemcpy((*popdraw)->ops,&DvOps,sizeof(DvOps));CHKERRQ(ierr);
7785c6c1daeSBarry Smith 
7795c6c1daeSBarry Smith   pop->hReadyEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
7805c6c1daeSBarry Smith   CreateThread(NULL, 0,(LPTHREAD_START_ROUTINE)PopMessageLoopThread_Win32,*popdraw,0,(unsigned long*)hThread);
7815c6c1daeSBarry Smith   CloseHandle(hThread);
7825c6c1daeSBarry Smith   WaitForSingleObject(pop->hReadyEvent, INFINITE);
7835c6c1daeSBarry Smith   CloseHandle(pop->hReadyEvent);
7845c6c1daeSBarry Smith   WaitForSingleObject(g_hWindowListMutex, INFINITE);
7855c6c1daeSBarry Smith 
7865c6c1daeSBarry Smith   draw->popup            = (*popdraw);
787*b00a9115SJed Brown   ierr                   = PetscNew(&newnode);CHKERRQ(ierr);
7885c6c1daeSBarry Smith   newnode->MouseListHead = NULL;
7895c6c1daeSBarry Smith   newnode->MouseListTail = NULL;
7905c6c1daeSBarry Smith   newnode->wnext         = WindowListHead;
7915c6c1daeSBarry Smith   newnode->wprev         = NULL;
7925c6c1daeSBarry Smith   newnode->hWnd          = pop->hWnd;
793a297a907SKarl Rupp   if (WindowListHead != NULL) WindowListHead->wprev = newnode;
7945c6c1daeSBarry Smith   WindowListHead         = newnode;
7955c6c1daeSBarry Smith   pop->hdc               = GetDC(pop->hWnd);
7965c6c1daeSBarry Smith 
7975c6c1daeSBarry Smith   pop->stringheight  = 10;
7985c6c1daeSBarry Smith   pop->stringwidth   = 6;
7995c6c1daeSBarry Smith   pop->linewidth     = 1;    /* default pixel sizes of graphics until user changes them */
8005c6c1daeSBarry Smith   pop->pointdiameter = 1;
8015c6c1daeSBarry Smith   pop->node          = newnode;
8025c6c1daeSBarry Smith 
8035c6c1daeSBarry Smith   newnode->bitwidth  = pop->w;
8045c6c1daeSBarry Smith   newnode->bitheight = pop->h;
8055c6c1daeSBarry Smith 
8065c6c1daeSBarry Smith   /* Create and initialize primary graphics buffer */
8075c6c1daeSBarry Smith   newnode->Buffer    = CreateCompatibleDC(pop->hdc);
8085c6c1daeSBarry Smith   newnode->BufferBit = CreateCompatibleBitmap(pop->hdc,pop->w,pop->h);
8095c6c1daeSBarry Smith   newnode->store     = SelectObject(newnode->Buffer,newnode->BufferBit);
8105c6c1daeSBarry Smith   ExtFloodFill(newnode->Buffer,0,0,COLOR_WINDOW,FLOODFILLBORDER);
8115c6c1daeSBarry Smith 
8125c6c1daeSBarry Smith 
8135c6c1daeSBarry Smith   newnode->event          = CreateEvent(NULL, TRUE, FALSE, NULL);
8145c6c1daeSBarry Smith   newnode->DoubleBuffered = PETSC_FALSE;
8155c6c1daeSBarry Smith 
8165c6c1daeSBarry Smith   ReleaseDC(pop->hWnd,pop->hdc);
8175c6c1daeSBarry Smith   ReleaseMutex(g_hWindowListMutex);
8185c6c1daeSBarry Smith   PetscFunctionReturn(0);
8195c6c1daeSBarry Smith }
8205c6c1daeSBarry Smith 
8215c6c1daeSBarry Smith EXTERN_C_BEGIN
8225c6c1daeSBarry Smith #undef __FUNCT__
8235c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawCreate_Win32"
8245c6c1daeSBarry Smith PetscErrorCode  PetscDrawCreate_Win32(PetscDraw draw)
8255c6c1daeSBarry Smith {
8265c6c1daeSBarry Smith   PetscDraw_Win32 *windraw;
8275c6c1daeSBarry Smith   HANDLE          hThread = NULL;
8285c6c1daeSBarry Smith   PetscErrorCode  ierr;
8295c6c1daeSBarry Smith   WindowNode      newnode;
8305c6c1daeSBarry Smith 
8315c6c1daeSBarry Smith   PetscFunctionBegin;
832*b00a9115SJed Brown   ierr       = PetscNew(&windraw);CHKERRQ(ierr);
8335c6c1daeSBarry Smith   draw->data = windraw;
8345c6c1daeSBarry Smith 
8355c6c1daeSBarry Smith   /* the following is temporary fix for initializing a global datastructure */
836a297a907SKarl Rupp   if (!g_hWindowListMutex) g_hWindowListMutex = CreateMutex(NULL,FALSE,NULL);
8375c6c1daeSBarry Smith   ierr = PetscMemcpy(draw->ops,&DvOps,sizeof(DvOps));CHKERRQ(ierr);
8385c6c1daeSBarry Smith 
8395c6c1daeSBarry Smith   windraw->hReadyEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
8405c6c1daeSBarry Smith   /* makes call to MessageLoopThread to creat window and attach a thread */
8415c6c1daeSBarry Smith   CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)MessageLoopThread_Win32,draw,0,(unsigned long*)hThread);
8425c6c1daeSBarry Smith   CloseHandle(hThread);
8435c6c1daeSBarry Smith   WaitForSingleObject(windraw->hReadyEvent,INFINITE);
8445c6c1daeSBarry Smith   CloseHandle(windraw->hReadyEvent);
8455c6c1daeSBarry Smith   WaitForSingleObject(g_hWindowListMutex,INFINITE);
8465c6c1daeSBarry Smith 
847*b00a9115SJed Brown   ierr                   = PetscNew(&newnode);CHKERRQ(ierr);
8485c6c1daeSBarry Smith   newnode->MouseListHead = NULL;
8495c6c1daeSBarry Smith   newnode->MouseListTail = NULL;
8505c6c1daeSBarry Smith   newnode->wnext         = WindowListHead;
8515c6c1daeSBarry Smith   newnode->wprev         = NULL;
8525c6c1daeSBarry Smith   newnode->hWnd          = windraw->hWnd;
853a297a907SKarl Rupp   if (WindowListHead != NULL) WindowListHead->wprev = newnode;
8545c6c1daeSBarry Smith   WindowListHead         = newnode;
8555c6c1daeSBarry Smith   windraw->hdc           = GetDC(windraw->hWnd);
8565c6c1daeSBarry Smith 
8575c6c1daeSBarry Smith   windraw->stringheight  = 10;
8585c6c1daeSBarry Smith   windraw->stringwidth   = 6;
8595c6c1daeSBarry Smith   windraw->linewidth     = 1;    /* default pixel sizes of graphics until user changes them */
8605c6c1daeSBarry Smith   windraw->pointdiameter = 1;
8615c6c1daeSBarry Smith   windraw->node          = newnode;
8625c6c1daeSBarry Smith 
8635c6c1daeSBarry Smith   windraw->x = draw->x;
8645c6c1daeSBarry Smith   windraw->y = draw->y;
8655c6c1daeSBarry Smith   windraw->w = newnode->bitwidth    = draw->w;
8665c6c1daeSBarry Smith   windraw->h = newnode->bitheight   = draw->h;
8675c6c1daeSBarry Smith 
8685c6c1daeSBarry Smith   /* Create and initialize primary graphics buffer */
8695c6c1daeSBarry Smith   newnode->Buffer    = CreateCompatibleDC(windraw->hdc);
8705c6c1daeSBarry Smith   newnode->BufferBit = CreateCompatibleBitmap(windraw->hdc,windraw->w,windraw->h);
8715c6c1daeSBarry Smith   newnode->store     = SelectObject(newnode->Buffer,newnode->BufferBit);
8725c6c1daeSBarry Smith   ExtFloodFill(newnode->Buffer,0,0,COLOR_WINDOW,FLOODFILLBORDER);
8735c6c1daeSBarry Smith 
8745c6c1daeSBarry Smith   newnode->event          = CreateEvent(NULL,TRUE,FALSE,NULL);
8755c6c1daeSBarry Smith   newnode->DoubleBuffered = PETSC_FALSE;
8765c6c1daeSBarry Smith 
8775c6c1daeSBarry Smith   ReleaseDC(windraw->hWnd,windraw->hdc);
8785c6c1daeSBarry Smith   ReleaseMutex(g_hWindowListMutex);
8795c6c1daeSBarry Smith   PetscFunctionReturn(0);
8805c6c1daeSBarry Smith }
8815c6c1daeSBarry Smith EXTERN_C_END
8825c6c1daeSBarry Smith 
8835c6c1daeSBarry Smith 
8845c6c1daeSBarry Smith /* FUNCTION: PetscWndProc(HWND, unsigned, WORD, LONG)
8855c6c1daeSBarry Smith    PURPOSE:  Processes messages for the main window.
8865c6c1daeSBarry Smith    WM_COMMAND  - process the application menu
8875c6c1daeSBarry Smith    WM_PAINT    - Paint the main window
8885c6c1daeSBarry Smith    WM_DESTROY  - post a quit message and return */
8895c6c1daeSBarry Smith 
8905c6c1daeSBarry Smith #undef __FUNCT__
8915c6c1daeSBarry Smith #define __FUNCT__ "PetscWndProc"
8925c6c1daeSBarry Smith LRESULT CALLBACK PetscWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
8935c6c1daeSBarry Smith {
8945c6c1daeSBarry Smith   int wmId, wmEvent;
8955c6c1daeSBarry Smith 
8965c6c1daeSBarry Smith   PetscFunctionBegin;
8975c6c1daeSBarry Smith   switch (message) {
8985c6c1daeSBarry Smith     HANDLE_MSG(hWnd,WM_PAINT,OnPaint_Win32);
8995c6c1daeSBarry Smith     HANDLE_MSG(hWnd,WM_DESTROY,OnDestroy_Win32);
9005c6c1daeSBarry Smith   case WM_COMMAND:
9015c6c1daeSBarry Smith     wmId    = LOWORD(wParam);
9025c6c1daeSBarry Smith     wmEvent = HIWORD(wParam);
9035c6c1daeSBarry Smith     /* Parse the menu selections:*/
9045c6c1daeSBarry Smith     switch (wmId) {
9055c6c1daeSBarry Smith     case IDM_EXIT:
9065c6c1daeSBarry Smith       DestroyWindow(hWnd);
9075c6c1daeSBarry Smith       break;
9085c6c1daeSBarry Smith     default:
9095c6c1daeSBarry Smith       return DefWindowProc(hWnd, message, wParam, lParam);
9105c6c1daeSBarry Smith     }
9115c6c1daeSBarry Smith     break;
9125c6c1daeSBarry Smith   case WM_LBUTTONUP:
9135c6c1daeSBarry Smith     MouseRecord_Win32(hWnd,PETSC_BUTTON_LEFT);
9145c6c1daeSBarry Smith     break;
9155c6c1daeSBarry Smith   case WM_RBUTTONUP:
9165c6c1daeSBarry Smith     MouseRecord_Win32(hWnd,PETSC_BUTTON_RIGHT);
9175c6c1daeSBarry Smith     break;
9185c6c1daeSBarry Smith   case WM_MBUTTONUP:
9195c6c1daeSBarry Smith     MouseRecord_Win32(hWnd,PETSC_BUTTON_CENTER);
9205c6c1daeSBarry Smith     break;
9215c6c1daeSBarry Smith   default:
9225c6c1daeSBarry Smith     PetscFunctionReturn(DefWindowProc(hWnd, message, wParam, lParam));
9235c6c1daeSBarry Smith   }
9245c6c1daeSBarry Smith   PetscFunctionReturn(0);
9255c6c1daeSBarry Smith }
9265c6c1daeSBarry Smith 
9275c6c1daeSBarry Smith #undef __FUNCT__
9285c6c1daeSBarry Smith #define __FUNCT__ "OnPaint_Win32"
9295c6c1daeSBarry Smith static void OnPaint_Win32(HWND hWnd)
9305c6c1daeSBarry Smith {
9315c6c1daeSBarry Smith   PAINTSTRUCT ps;
9325c6c1daeSBarry Smith   HDC         hdc;
9335c6c1daeSBarry Smith   WindowNode  current = NULL;
9345c6c1daeSBarry Smith 
9355c6c1daeSBarry Smith   PetscFunctionBegin;
9365c6c1daeSBarry Smith   InvalidateRect(hWnd,NULL,TRUE);
9375c6c1daeSBarry Smith   WaitForSingleObject(g_hWindowListMutex, INFINITE);
9385c6c1daeSBarry Smith   current = WindowListHead;
9395c6c1daeSBarry Smith   hdc     = BeginPaint(hWnd, &ps);
9405c6c1daeSBarry Smith 
9415c6c1daeSBarry Smith   while (current != NULL) {
9425c6c1daeSBarry Smith     if (current->hWnd == hWnd) {
9435c6c1daeSBarry Smith       /* flushes primary buffer to window */
944be332245SKarl Rupp       BitBlt(hdc,0,0,GetDeviceCaps(hdc,HORZRES),GetDeviceCaps(hdc,VERTRES),
945be332245SKarl Rupp              current->Buffer,0,0,SRCCOPY);
9465c6c1daeSBarry Smith 
947be332245SKarl Rupp       /* StretchBlt(hdc,0,0,w,h,
948be332245SKarl Rupp         current->Buffer,0,0,current->bitwidth,current->bitheight,SRCCOPY); */
9495c6c1daeSBarry Smith       break;
9505c6c1daeSBarry Smith     }
9515c6c1daeSBarry Smith     current = current->wnext;
9525c6c1daeSBarry Smith   }
9535c6c1daeSBarry Smith   EndPaint(hWnd, &ps);
9545c6c1daeSBarry Smith   ReleaseMutex(g_hWindowListMutex);
9555c6c1daeSBarry Smith   PetscFunctionReturnVoid();
9565c6c1daeSBarry Smith }
9575c6c1daeSBarry Smith 
9585c6c1daeSBarry Smith #undef __FUNCT__
9595c6c1daeSBarry Smith #define __FUNCT__ "MouseRecord_Win32"
9605c6c1daeSBarry Smith static PetscErrorCode MouseRecord_Win32(HWND hWnd,PetscDrawButton button)
9615c6c1daeSBarry Smith {
9625c6c1daeSBarry Smith   /* Called by all three mouse button actions
9635c6c1daeSBarry Smith     Records needed mouse data in windows data structure */
9645c6c1daeSBarry Smith   WindowNode     current = NULL;
9655c6c1daeSBarry Smith   MouseNode      newnode;
9665c6c1daeSBarry Smith   POINT          mousepos;
9675c6c1daeSBarry Smith   PetscErrorCode ierr;
9685c6c1daeSBarry Smith 
9695c6c1daeSBarry Smith   PetscFunctionBegin;
9705c6c1daeSBarry Smith   WaitForSingleObject(g_hWindowListMutex, INFINITE);
9715c6c1daeSBarry Smith   current = WindowListHead;
9725c6c1daeSBarry Smith   if (current->IsGetMouseOn == TRUE) {
9735c6c1daeSBarry Smith 
9745c6c1daeSBarry Smith     SetEvent(current->event);
9755c6c1daeSBarry Smith     while (current != NULL) {
9765c6c1daeSBarry Smith       if (current->hWnd == hWnd) {
9775c6c1daeSBarry Smith 
978*b00a9115SJed Brown         ierr            = PetscNew(&newnode);CHKERRQ(ierr);
9795c6c1daeSBarry Smith         newnode->Button = button;
9805c6c1daeSBarry Smith         GetCursorPos(&mousepos);
9815c6c1daeSBarry Smith         newnode->user.x = mousepos.x;
9825c6c1daeSBarry Smith         newnode->user.y = mousepos.y;
9835c6c1daeSBarry Smith         ScreenToClient(hWnd,&mousepos);
9845c6c1daeSBarry Smith         newnode->phys.x = mousepos.x;
9855c6c1daeSBarry Smith         newnode->phys.y = mousepos.y;
9865c6c1daeSBarry Smith         if (!current->MouseListTail) {
9875c6c1daeSBarry Smith           current->MouseListHead = newnode;
9885c6c1daeSBarry Smith           current->MouseListTail = newnode;
9895c6c1daeSBarry Smith         } else {
9905c6c1daeSBarry Smith           current->MouseListTail->mnext = newnode;
9915c6c1daeSBarry Smith           current->MouseListTail        = newnode;
9925c6c1daeSBarry Smith         }
9935c6c1daeSBarry Smith         newnode->mnext = NULL;
9945c6c1daeSBarry Smith 
9955c6c1daeSBarry Smith         break;
9965c6c1daeSBarry Smith       }
9975c6c1daeSBarry Smith       current = current->wnext;
9985c6c1daeSBarry Smith     }
9995c6c1daeSBarry Smith   }
10005c6c1daeSBarry Smith   ReleaseMutex(g_hWindowListMutex);
10015c6c1daeSBarry Smith   PetscFunctionReturn(0);
10025c6c1daeSBarry Smith }
10035c6c1daeSBarry Smith 
10045c6c1daeSBarry Smith #undef __FUNCT__
10055c6c1daeSBarry Smith #define __FUNCT__ "OnDestroy_Win32"
10065c6c1daeSBarry Smith static void OnDestroy_Win32(HWND hWnd)
10075c6c1daeSBarry Smith {
10085c6c1daeSBarry Smith   /* searches linked list of window data and frees corresponding memory */
10095c6c1daeSBarry Smith   WindowNode current;
10105c6c1daeSBarry Smith 
10115c6c1daeSBarry Smith   PetscFunctionBegin;
10125c6c1daeSBarry Smith   WaitForSingleObject(g_hWindowListMutex, INFINITE);
10135c6c1daeSBarry Smith   current = WindowListHead;
10145c6c1daeSBarry Smith 
10155c6c1daeSBarry Smith   SetEvent(current->event);
10165c6c1daeSBarry Smith   while (current != NULL) {
10175c6c1daeSBarry Smith     if (current->hWnd == hWnd) {
1018a297a907SKarl Rupp       if (current->wprev != NULL) current->wprev->wnext = current->wnext;
1019a297a907SKarl Rupp       else WindowListHead = current->wnext;
1020a297a907SKarl Rupp       if (current->MouseListHead) deletemouselist_Win32(current);
1021a297a907SKarl Rupp       else PetscFree(current);
10225c6c1daeSBarry Smith       break;
10235c6c1daeSBarry Smith     }
10245c6c1daeSBarry Smith     current = current->wnext;
10255c6c1daeSBarry Smith   }
10265c6c1daeSBarry Smith   ReleaseMutex(g_hWindowListMutex);
10275c6c1daeSBarry Smith   PostQuitMessage(0);
10285c6c1daeSBarry Smith   PetscFunctionReturnVoid();
10295c6c1daeSBarry Smith }
1030