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