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