1*5c6c1daeSBarry Smith 2*5c6c1daeSBarry Smith #include <petscsys.h> 3*5c6c1daeSBarry Smith #include <petsc-private/drawimpl.h> 4*5c6c1daeSBarry Smith #include <../src/sys/draw/impls/win32/win32draw.h> 5*5c6c1daeSBarry Smith 6*5c6c1daeSBarry Smith #define IDC_FOUR 109 7*5c6c1daeSBarry Smith #define IDI_FOUR 107 8*5c6c1daeSBarry Smith #define IDM_EXIT 105 9*5c6c1daeSBarry Smith #define IDR_POPUP 103 10*5c6c1daeSBarry Smith #define MAX_LOADSTRING 100 11*5c6c1daeSBarry Smith 12*5c6c1daeSBarry Smith #if !defined(SelectPen) 13*5c6c1daeSBarry Smith #define SelectPen(hdc, hpen) ((HPEN)SelectObject((hdc), (HGDIOBJ)(HPEN)(hpen))) 14*5c6c1daeSBarry Smith #endif 15*5c6c1daeSBarry Smith #if !defined(SelectFont) 16*5c6c1daeSBarry Smith #define SelectFont(hdc,hfont) ((HFONT)SelectObject((hdc), (HGDIOBJ)(HFONT)(hfont))) 17*5c6c1daeSBarry Smith #endif 18*5c6c1daeSBarry Smith #if !defined(SelectBrush) 19*5c6c1daeSBarry Smith #define SelectBrush(hdc,hbrush) ((HBRUSH)SelectObject((hdc), (HGDIOBJ)(HBRUSH)(hbrush))) 20*5c6c1daeSBarry Smith #endif 21*5c6c1daeSBarry Smith #if !defined(GetStockBrush) 22*5c6c1daeSBarry Smith #define GetStockBrush(i) ((HBRUSH)GetStockObject(i)) 23*5c6c1daeSBarry Smith #endif 24*5c6c1daeSBarry Smith 25*5c6c1daeSBarry Smith #define XTRANS(draw,win,x) \ 26*5c6c1daeSBarry Smith (int)(((win)->w)*((draw)->port_xl + (((x - (draw)->coor_xl)*\ 27*5c6c1daeSBarry Smith ((draw)->port_xr - (draw)->port_xl))/\ 28*5c6c1daeSBarry Smith ((draw)->coor_xr - (draw)->coor_xl)))) 29*5c6c1daeSBarry Smith #define YTRANS(draw,win,y) \ 30*5c6c1daeSBarry Smith (int)(((win)->h)*(1.0-(draw)->port_yl - (((y - (draw)->coor_yl)*\ 31*5c6c1daeSBarry Smith ((draw)->port_yr - (draw)->port_yl))/\ 32*5c6c1daeSBarry Smith ((draw)->coor_yr - (draw)->coor_yl)))) 33*5c6c1daeSBarry Smith 34*5c6c1daeSBarry Smith HINSTANCE hInst; 35*5c6c1daeSBarry Smith HANDLE g_hWindowListMutex = NULL; 36*5c6c1daeSBarry Smith WindowNode WindowListHead = NULL; 37*5c6c1daeSBarry Smith 38*5c6c1daeSBarry Smith /* Hard coded color hue until hue.c works with this */ 39*5c6c1daeSBarry 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}; 40*5c6c1daeSBarry 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}; 41*5c6c1daeSBarry 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}; 42*5c6c1daeSBarry Smith 43*5c6c1daeSBarry Smith /* Foward declarations of functions included in this code module: */ 44*5c6c1daeSBarry Smith LRESULT CALLBACK PetscWndProc(HWND, UINT, WPARAM, LPARAM); 45*5c6c1daeSBarry Smith static PetscErrorCode TranslateColor_Win32(PetscDraw,int); 46*5c6c1daeSBarry Smith static PetscErrorCode AverageColorRectangle_Win32(PetscDraw,int,int,int,int); 47*5c6c1daeSBarry Smith static PetscErrorCode AverageColorTriangle_Win32(PetscDraw,int,int,int); 48*5c6c1daeSBarry Smith static PetscErrorCode deletemouselist_Win32(WindowNode); 49*5c6c1daeSBarry Smith static void OnPaint_Win32(HWND); 50*5c6c1daeSBarry Smith static void OnDestroy_Win32(HWND); 51*5c6c1daeSBarry Smith static PetscErrorCode MouseRecord_Win32(HWND,PetscDrawButton); 52*5c6c1daeSBarry Smith static PetscErrorCode PetscDrawGetPopup_Win32(PetscDraw,PetscDraw *); 53*5c6c1daeSBarry Smith 54*5c6c1daeSBarry Smith #undef __FUNCT__ 55*5c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawSetDoubleBuffer_Win32" 56*5c6c1daeSBarry Smith static PetscErrorCode PetscDrawSetDoubleBuffer_Win32(PetscDraw draw) 57*5c6c1daeSBarry Smith { 58*5c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32*)draw->data; 59*5c6c1daeSBarry Smith HDC hdc = GetDC(windraw->hWnd); 60*5c6c1daeSBarry Smith 61*5c6c1daeSBarry Smith PetscFunctionBegin; 62*5c6c1daeSBarry Smith windraw->node->DoubleBuffer = CreateCompatibleDC(hdc); 63*5c6c1daeSBarry Smith windraw->node->DoubleBufferBit = CreateCompatibleBitmap(hdc,windraw->w,windraw->h); 64*5c6c1daeSBarry Smith windraw->node->dbstore = SelectObject(windraw->node->DoubleBuffer,windraw->node->DoubleBufferBit); 65*5c6c1daeSBarry Smith /* Fill background of second buffer */ 66*5c6c1daeSBarry Smith ExtFloodFill(windraw->node->DoubleBuffer,0,0,COLOR_WINDOW,FLOODFILLBORDER); 67*5c6c1daeSBarry Smith /* Copy current buffer into seconf buffer and set window data as double buffered */ 68*5c6c1daeSBarry Smith BitBlt(windraw->node->DoubleBuffer, 69*5c6c1daeSBarry Smith 0,0, 70*5c6c1daeSBarry Smith windraw->w,windraw->h, 71*5c6c1daeSBarry Smith windraw->node->Buffer, 72*5c6c1daeSBarry Smith 0,0, 73*5c6c1daeSBarry Smith SRCCOPY); 74*5c6c1daeSBarry Smith 75*5c6c1daeSBarry Smith windraw->node->DoubleBuffered = PETSC_TRUE; 76*5c6c1daeSBarry Smith ReleaseDC(windraw->hWnd,hdc); 77*5c6c1daeSBarry Smith PetscFunctionReturn(0); 78*5c6c1daeSBarry Smith } 79*5c6c1daeSBarry Smith 80*5c6c1daeSBarry Smith #undef __FUNCT__ 81*5c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawFlush_Win32" 82*5c6c1daeSBarry Smith static PetscErrorCode PetscDrawFlush_Win32(PetscDraw draw) 83*5c6c1daeSBarry Smith { 84*5c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32*)draw->data; 85*5c6c1daeSBarry Smith HDC hdc = GetDC(windraw->hWnd); 86*5c6c1daeSBarry Smith 87*5c6c1daeSBarry Smith PetscFunctionBegin; 88*5c6c1daeSBarry Smith /* flush double buffer into primary buffer */ 89*5c6c1daeSBarry Smith BitBlt(windraw->node->Buffer, 90*5c6c1daeSBarry Smith 0,0, 91*5c6c1daeSBarry Smith windraw->w,windraw->h, 92*5c6c1daeSBarry Smith windraw->node->DoubleBuffer, 93*5c6c1daeSBarry Smith 0,0, 94*5c6c1daeSBarry Smith SRCCOPY); 95*5c6c1daeSBarry Smith /* flush double buffer into window */ 96*5c6c1daeSBarry Smith BitBlt(hdc, 97*5c6c1daeSBarry Smith 0,0, 98*5c6c1daeSBarry Smith windraw->w,windraw->h, 99*5c6c1daeSBarry Smith windraw->node->DoubleBuffer, 100*5c6c1daeSBarry Smith 0,0, 101*5c6c1daeSBarry Smith SRCCOPY); 102*5c6c1daeSBarry Smith ReleaseDC(windraw->hWnd,hdc); 103*5c6c1daeSBarry Smith PetscFunctionReturn(0); 104*5c6c1daeSBarry Smith } 105*5c6c1daeSBarry Smith 106*5c6c1daeSBarry Smith #undef __FUNCT__ 107*5c6c1daeSBarry Smith #define __FUNCT__ "deletemouselist_Win32" 108*5c6c1daeSBarry Smith static PetscErrorCode deletemouselist_Win32(WindowNode deletelist) 109*5c6c1daeSBarry Smith { 110*5c6c1daeSBarry Smith /* Called upon window close. Frees memory of linked list of stored mouse commands */ 111*5c6c1daeSBarry Smith MouseNode node; 112*5c6c1daeSBarry Smith 113*5c6c1daeSBarry Smith while(deletelist->MouseListHead != NULL) { 114*5c6c1daeSBarry Smith node = deletelist->MouseListHead; 115*5c6c1daeSBarry Smith if (deletelist->MouseListHead->mnext != NULL) { 116*5c6c1daeSBarry Smith deletelist->MouseListHead = deletelist->MouseListHead->mnext; 117*5c6c1daeSBarry Smith } 118*5c6c1daeSBarry Smith PetscFree(node); 119*5c6c1daeSBarry Smith } 120*5c6c1daeSBarry Smith deletelist->MouseListHead = deletelist->MouseListTail = NULL; 121*5c6c1daeSBarry Smith if (deletelist->wprev != NULL) { 122*5c6c1daeSBarry Smith deletelist->wprev->wnext = deletelist->wnext; 123*5c6c1daeSBarry Smith } 124*5c6c1daeSBarry Smith if (deletelist->wnext != NULL) { 125*5c6c1daeSBarry Smith deletelist->wnext->wprev = deletelist->wprev; 126*5c6c1daeSBarry Smith } 127*5c6c1daeSBarry Smith PetscFree(deletelist); 128*5c6c1daeSBarry Smith return 0; 129*5c6c1daeSBarry Smith } 130*5c6c1daeSBarry Smith 131*5c6c1daeSBarry Smith #undef __FUNCT__ 132*5c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawGetMouseButton_Win32" 133*5c6c1daeSBarry Smith static PetscErrorCode PetscDrawGetMouseButton_Win32(PetscDraw draw, PetscDrawButton *button,PetscReal *x_user,PetscReal *y_user,PetscReal *x_phys,PetscReal *y_phys) 134*5c6c1daeSBarry Smith { 135*5c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32*)draw->data; 136*5c6c1daeSBarry Smith WindowNode current; 137*5c6c1daeSBarry Smith MouseNode node=0; 138*5c6c1daeSBarry Smith 139*5c6c1daeSBarry Smith PetscFunctionBegin; 140*5c6c1daeSBarry Smith /* Make sure no other code is using the linked list at this moment */ 141*5c6c1daeSBarry Smith WaitForSingleObject(g_hWindowListMutex, INFINITE); 142*5c6c1daeSBarry Smith /* Look for the node that matches the window you are using */ 143*5c6c1daeSBarry Smith current = WindowListHead; 144*5c6c1daeSBarry Smith while (current != NULL) { 145*5c6c1daeSBarry Smith if (current->hWnd == windraw->hWnd) { 146*5c6c1daeSBarry Smith current->IsGetMouseOn = TRUE; 147*5c6c1daeSBarry Smith break; 148*5c6c1daeSBarry Smith } else { 149*5c6c1daeSBarry Smith current = current->wnext; 150*5c6c1daeSBarry Smith } 151*5c6c1daeSBarry Smith } 152*5c6c1daeSBarry Smith /* If no actions have occured, wait for one */ 153*5c6c1daeSBarry Smith node = current->MouseListHead; 154*5c6c1daeSBarry Smith if (!node) { 155*5c6c1daeSBarry Smith ReleaseMutex(g_hWindowListMutex); 156*5c6c1daeSBarry Smith WaitForSingleObject(current->event, INFINITE); 157*5c6c1daeSBarry Smith WaitForSingleObject(g_hWindowListMutex, INFINITE); 158*5c6c1daeSBarry Smith } 159*5c6c1daeSBarry Smith /* once we have the information, assign the pointers to it */ 160*5c6c1daeSBarry Smith *button = current->MouseListHead->Button; 161*5c6c1daeSBarry Smith *x_user = current->MouseListHead->user.x; 162*5c6c1daeSBarry Smith *y_user = current->MouseListHead->user.y; 163*5c6c1daeSBarry Smith /* optional arguments */ 164*5c6c1daeSBarry Smith if (x_phys) *x_phys = current->MouseListHead->phys.x; 165*5c6c1daeSBarry Smith if (y_phys) *y_phys = current->MouseListHead->phys.y; 166*5c6c1daeSBarry Smith /* remove set of information from sub linked-list, delete the node */ 167*5c6c1daeSBarry Smith current->MouseListHead = current->MouseListHead->mnext; 168*5c6c1daeSBarry Smith if (!current->MouseListHead) { 169*5c6c1daeSBarry Smith ResetEvent(current->event); 170*5c6c1daeSBarry Smith current->MouseListTail = NULL; 171*5c6c1daeSBarry Smith } 172*5c6c1daeSBarry Smith if (node) PetscFree(node); 173*5c6c1daeSBarry Smith 174*5c6c1daeSBarry Smith /* Release mutex so that other code can use 175*5c6c1daeSBarry Smith the linked list now that we are done with it */ 176*5c6c1daeSBarry Smith ReleaseMutex(g_hWindowListMutex); 177*5c6c1daeSBarry Smith PetscFunctionReturn(0); 178*5c6c1daeSBarry Smith } 179*5c6c1daeSBarry Smith 180*5c6c1daeSBarry Smith #undef __FUNCT__ 181*5c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawPause_Win32" 182*5c6c1daeSBarry Smith static PetscErrorCode PetscDrawPause_Win32(PetscDraw draw) 183*5c6c1daeSBarry Smith { 184*5c6c1daeSBarry Smith PetscFunctionBegin; 185*5c6c1daeSBarry Smith PetscSleep(draw->pause); 186*5c6c1daeSBarry Smith PetscFunctionReturn(0); 187*5c6c1daeSBarry Smith } 188*5c6c1daeSBarry Smith 189*5c6c1daeSBarry Smith #undef __FUNCT__ 190*5c6c1daeSBarry Smith #define __FUNCT__ "TranslateColor_Win32" 191*5c6c1daeSBarry Smith static PetscErrorCode TranslateColor_Win32(PetscDraw draw,int color) 192*5c6c1daeSBarry Smith { 193*5c6c1daeSBarry Smith /* Maps single color value into the RGB colors in our tables */ 194*5c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32*)draw->data; 195*5c6c1daeSBarry Smith windraw->currentcolor = RGB(RedMap[color],GreenMap[color],BlueMap[color]); 196*5c6c1daeSBarry Smith return 0; 197*5c6c1daeSBarry Smith } 198*5c6c1daeSBarry Smith 199*5c6c1daeSBarry Smith #undef __FUNCT__ 200*5c6c1daeSBarry Smith #define __FUNCT__ "AverageColorRectangle_Win32" 201*5c6c1daeSBarry Smith static PetscErrorCode AverageColorRectangle_Win32(PetscDraw draw,int c1,int c2, int c3, int c4) 202*5c6c1daeSBarry Smith { 203*5c6c1daeSBarry Smith /* Averages colors given at points of rectangle and sets color from color table 204*5c6c1daeSBarry Smith will be changed once the color gradient problem is worked out */ 205*5c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32*)draw->data; 206*5c6c1daeSBarry Smith windraw->currentcolor = RGB(((RedMap[c1]+RedMap[c2]+RedMap[c3]+RedMap[c4])/4), 207*5c6c1daeSBarry Smith ((GreenMap[c1]+GreenMap[c2]+GreenMap[c3]+GreenMap[c4])/4), 208*5c6c1daeSBarry Smith ((BlueMap[c1]+BlueMap[c2]+BlueMap[c3]+BlueMap[c4])/4)); 209*5c6c1daeSBarry Smith return 0; 210*5c6c1daeSBarry Smith } 211*5c6c1daeSBarry Smith 212*5c6c1daeSBarry Smith #undef __FUNCT__ 213*5c6c1daeSBarry Smith #define __FUNCT__ "AverageColorTriangle_Win32" 214*5c6c1daeSBarry Smith static PetscErrorCode AverageColorTriangle_Win32(PetscDraw draw,int c1,int c2,int c3) 215*5c6c1daeSBarry Smith { 216*5c6c1daeSBarry Smith /* Averages colors given at points of rectangle and sets color from color table 217*5c6c1daeSBarry Smith will be changed once the color gradient problem is worked out */ 218*5c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32*)draw->data; 219*5c6c1daeSBarry Smith windraw->currentcolor = RGB((RedMap[c1]+RedMap[c2]+RedMap[c3])/3, 220*5c6c1daeSBarry Smith (GreenMap[c1]+GreenMap[c2]+GreenMap[c3])/3, 221*5c6c1daeSBarry Smith (BlueMap[c1]+BlueMap[c2]+BlueMap[c3])/3); 222*5c6c1daeSBarry Smith return 0; 223*5c6c1daeSBarry Smith } 224*5c6c1daeSBarry Smith 225*5c6c1daeSBarry Smith #undef __FUNCT__ 226*5c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawRectangle_Win32" 227*5c6c1daeSBarry Smith static PetscErrorCode PetscDrawRectangle_Win32(PetscDraw draw,PetscReal xl,PetscReal yl,PetscReal xr,PetscReal yr,int c1,int c2,int c3,int c4) 228*5c6c1daeSBarry Smith { 229*5c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32*)draw->data; 230*5c6c1daeSBarry Smith HBRUSH hbrush; 231*5c6c1daeSBarry Smith RECT rect; 232*5c6c1daeSBarry Smith int x1,yone,x2,y2; 233*5c6c1daeSBarry Smith HDC hdc; 234*5c6c1daeSBarry Smith 235*5c6c1daeSBarry Smith PetscFunctionBegin; 236*5c6c1daeSBarry Smith x1 = XTRANS(draw,windraw,xl); 237*5c6c1daeSBarry Smith x2 = XTRANS(draw,windraw,xr); 238*5c6c1daeSBarry Smith yone = YTRANS(draw,windraw,yl); 239*5c6c1daeSBarry Smith y2 = YTRANS(draw,windraw,yr); 240*5c6c1daeSBarry Smith SetRect(&rect,x1,y2,x2,yone); 241*5c6c1daeSBarry Smith if (c1==c2 && c2==c3 && c3==c4) { 242*5c6c1daeSBarry Smith TranslateColor_Win32(draw,c1); 243*5c6c1daeSBarry Smith } else { 244*5c6c1daeSBarry Smith AverageColorRectangle_Win32(draw,c1,c2,c3,c4); 245*5c6c1daeSBarry Smith } 246*5c6c1daeSBarry Smith hbrush = CreateSolidBrush(windraw->currentcolor); 247*5c6c1daeSBarry Smith 248*5c6c1daeSBarry Smith if (windraw->node->DoubleBuffered) { 249*5c6c1daeSBarry Smith hdc = windraw->node->DoubleBuffer; 250*5c6c1daeSBarry Smith } else { 251*5c6c1daeSBarry Smith hdc = windraw->node->Buffer; 252*5c6c1daeSBarry Smith } 253*5c6c1daeSBarry Smith FillRect(hdc,&rect,hbrush); 254*5c6c1daeSBarry Smith /* Forces a WM_PAINT message and erases background */ 255*5c6c1daeSBarry Smith InvalidateRect(windraw->hWnd,NULL,TRUE); 256*5c6c1daeSBarry Smith UpdateWindow(windraw->hWnd); 257*5c6c1daeSBarry Smith PetscFunctionReturn(0); 258*5c6c1daeSBarry Smith } 259*5c6c1daeSBarry Smith 260*5c6c1daeSBarry Smith #undef __FUNCT__ 261*5c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawLine_Win32" 262*5c6c1daeSBarry Smith static PetscErrorCode PetscDrawLine_Win32(PetscDraw draw,PetscReal xl,PetscReal yl,PetscReal xr,PetscReal yr,int color) 263*5c6c1daeSBarry Smith { 264*5c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32*)draw->data; 265*5c6c1daeSBarry Smith HPEN hpen; 266*5c6c1daeSBarry Smith int x1,yone,x2,y2; 267*5c6c1daeSBarry Smith HDC hdc; 268*5c6c1daeSBarry Smith 269*5c6c1daeSBarry Smith PetscFunctionBegin; 270*5c6c1daeSBarry Smith TranslateColor_Win32(draw,color); 271*5c6c1daeSBarry Smith x1 = XTRANS(draw,windraw,xl);x2 = XTRANS(draw,windraw,xr); 272*5c6c1daeSBarry Smith yone = YTRANS(draw,windraw,yl);y2 = YTRANS(draw,windraw,yr); 273*5c6c1daeSBarry Smith hpen = CreatePen (PS_SOLID, windraw->linewidth, windraw->currentcolor); 274*5c6c1daeSBarry Smith if (windraw->node->DoubleBuffered) { 275*5c6c1daeSBarry Smith hdc = windraw->node->DoubleBuffer; 276*5c6c1daeSBarry Smith } else { 277*5c6c1daeSBarry Smith hdc = windraw->node->Buffer; 278*5c6c1daeSBarry Smith } 279*5c6c1daeSBarry Smith SelectPen(hdc,hpen); 280*5c6c1daeSBarry Smith MoveToEx(hdc,x1,yone,NULL); 281*5c6c1daeSBarry Smith LineTo(hdc,x2,y2); 282*5c6c1daeSBarry Smith /* Forces a WM_PAINT message and erases background */ 283*5c6c1daeSBarry Smith InvalidateRect(windraw->hWnd,NULL,TRUE); 284*5c6c1daeSBarry Smith UpdateWindow(windraw->hWnd); 285*5c6c1daeSBarry Smith PetscFunctionReturn(0); 286*5c6c1daeSBarry Smith } 287*5c6c1daeSBarry Smith 288*5c6c1daeSBarry Smith #undef __FUNCT__ 289*5c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawLineSetWidth_Win32" 290*5c6c1daeSBarry Smith static PetscErrorCode PetscDrawLineSetWidth_Win32(PetscDraw draw,PetscReal width) 291*5c6c1daeSBarry Smith { 292*5c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32*)draw->data; 293*5c6c1daeSBarry Smith int averagesize,finalwidth; 294*5c6c1daeSBarry Smith RECT rect; 295*5c6c1daeSBarry Smith 296*5c6c1daeSBarry Smith PetscFunctionBegin; 297*5c6c1daeSBarry Smith GetClientRect(windraw->hWnd,&rect); 298*5c6c1daeSBarry Smith averagesize = ((rect.right - rect.left)+(rect.bottom - rect.top))/2; 299*5c6c1daeSBarry Smith finalwidth = (int)floor(averagesize*width); 300*5c6c1daeSBarry Smith if (finalwidth < 1) { 301*5c6c1daeSBarry Smith finalwidth = 1; /* minimum size PetscDrawLine can except */ 302*5c6c1daeSBarry Smith } 303*5c6c1daeSBarry Smith windraw->linewidth = finalwidth; 304*5c6c1daeSBarry Smith PetscFunctionReturn(0); 305*5c6c1daeSBarry Smith } 306*5c6c1daeSBarry Smith 307*5c6c1daeSBarry Smith #undef __FUNCT__ 308*5c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawLineGetWidth_Win32" 309*5c6c1daeSBarry Smith static PetscErrorCode PetscDrawLineGetWidth_Win32(PetscDraw draw,PetscReal *width) 310*5c6c1daeSBarry Smith { 311*5c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32*)draw->data; 312*5c6c1daeSBarry Smith 313*5c6c1daeSBarry Smith PetscFunctionBegin; 314*5c6c1daeSBarry Smith *width = (PetscReal)windraw->linewidth; 315*5c6c1daeSBarry Smith PetscFunctionReturn(0); 316*5c6c1daeSBarry Smith } 317*5c6c1daeSBarry Smith 318*5c6c1daeSBarry Smith #undef __FUNCT__ 319*5c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawPoint_Win32" 320*5c6c1daeSBarry Smith static PetscErrorCode PetscDrawPoint_Win32(PetscDraw draw,PetscReal x,PetscReal y,int color) 321*5c6c1daeSBarry Smith { 322*5c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32*)draw->data; 323*5c6c1daeSBarry Smith HBRUSH hbrush; 324*5c6c1daeSBarry Smith HRGN hrgn; 325*5c6c1daeSBarry Smith int radius; 326*5c6c1daeSBarry Smith int x1,yone; 327*5c6c1daeSBarry Smith HDC hdc; 328*5c6c1daeSBarry Smith 329*5c6c1daeSBarry Smith PetscFunctionBegin; 330*5c6c1daeSBarry Smith TranslateColor_Win32(draw,color); 331*5c6c1daeSBarry Smith x1 = XTRANS(draw,windraw,x); 332*5c6c1daeSBarry Smith yone = YTRANS(draw,windraw,y); 333*5c6c1daeSBarry Smith hbrush = CreateSolidBrush(windraw->currentcolor); 334*5c6c1daeSBarry Smith if (windraw->node->DoubleBuffered) { 335*5c6c1daeSBarry Smith hdc = windraw->node->DoubleBuffer; 336*5c6c1daeSBarry Smith } else { 337*5c6c1daeSBarry Smith hdc = windraw->node->Buffer; 338*5c6c1daeSBarry Smith } 339*5c6c1daeSBarry Smith /* desired size is one logical pixel so just turn it on */ 340*5c6c1daeSBarry Smith if (windraw->pointdiameter == 1) { 341*5c6c1daeSBarry Smith SetPixelV(hdc,x1,yone,windraw->currentcolor); 342*5c6c1daeSBarry Smith } else { 343*5c6c1daeSBarry Smith /* draw point around position determined */ 344*5c6c1daeSBarry Smith radius = windraw->pointdiameter/2; /* integer division */ 345*5c6c1daeSBarry Smith hrgn = CreateEllipticRgn(x1-radius,yone-radius,x1+radius,yone+radius); 346*5c6c1daeSBarry Smith FillRgn(hdc,hrgn,hbrush); 347*5c6c1daeSBarry Smith } 348*5c6c1daeSBarry Smith /* Forces a WM_PAINT and erases background */ 349*5c6c1daeSBarry Smith InvalidateRect(windraw->hWnd,NULL,TRUE); 350*5c6c1daeSBarry Smith UpdateWindow(windraw->hWnd); 351*5c6c1daeSBarry Smith PetscFunctionReturn(0); 352*5c6c1daeSBarry Smith } 353*5c6c1daeSBarry Smith 354*5c6c1daeSBarry Smith #undef __FUNCT__ 355*5c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawPointSetSize_Win32" 356*5c6c1daeSBarry Smith static PetscErrorCode PetscDrawPointSetSize_Win32(PetscDraw draw,PetscReal width) 357*5c6c1daeSBarry Smith { 358*5c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32*)draw->data; 359*5c6c1daeSBarry Smith int averagesize,diameter; 360*5c6c1daeSBarry Smith RECT rect; 361*5c6c1daeSBarry Smith 362*5c6c1daeSBarry Smith PetscFunctionBegin; 363*5c6c1daeSBarry Smith GetClientRect(windraw->hWnd,&rect); 364*5c6c1daeSBarry Smith averagesize = ((rect.right - rect.left)+(rect.bottom - rect.top))/2; 365*5c6c1daeSBarry Smith diameter = (int)floor(averagesize*width); 366*5c6c1daeSBarry Smith if (diameter < 1) diameter = 1; 367*5c6c1daeSBarry Smith windraw->pointdiameter = diameter; 368*5c6c1daeSBarry Smith PetscFunctionReturn(0); 369*5c6c1daeSBarry Smith } 370*5c6c1daeSBarry Smith 371*5c6c1daeSBarry Smith #undef __FUNCT__ 372*5c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawString_Win32" 373*5c6c1daeSBarry Smith static PetscErrorCode PetscDrawString_Win32(PetscDraw draw,PetscReal x,PetscReal y,int color,const char *text) 374*5c6c1daeSBarry Smith { 375*5c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32*)draw->data; 376*5c6c1daeSBarry Smith RECT r; 377*5c6c1daeSBarry Smith HFONT hfont; 378*5c6c1daeSBarry Smith LOGFONT logfont; 379*5c6c1daeSBarry Smith int x1,yone; 380*5c6c1daeSBarry Smith HDC hdc; 381*5c6c1daeSBarry Smith 382*5c6c1daeSBarry Smith PetscFunctionBegin; 383*5c6c1daeSBarry Smith x1 = XTRANS(draw,windraw,x); 384*5c6c1daeSBarry Smith yone = YTRANS(draw,windraw,y); 385*5c6c1daeSBarry Smith r.bottom = yone; 386*5c6c1daeSBarry Smith r.left = x1; 387*5c6c1daeSBarry Smith r.right = x1 + 1; 388*5c6c1daeSBarry Smith r.top = yone + 1; 389*5c6c1daeSBarry Smith logfont.lfHeight = windraw->stringheight; 390*5c6c1daeSBarry Smith logfont.lfWidth = windraw->stringwidth; 391*5c6c1daeSBarry Smith logfont.lfEscapement = 0; 392*5c6c1daeSBarry Smith logfont.lfOrientation = 0; 393*5c6c1daeSBarry Smith logfont.lfCharSet = 0; 394*5c6c1daeSBarry Smith logfont.lfClipPrecision = 0; 395*5c6c1daeSBarry Smith logfont.lfItalic = 0; 396*5c6c1daeSBarry Smith logfont.lfOutPrecision = 0; 397*5c6c1daeSBarry Smith logfont.lfPitchAndFamily = DEFAULT_PITCH; 398*5c6c1daeSBarry Smith logfont.lfQuality = DEFAULT_QUALITY; 399*5c6c1daeSBarry Smith logfont.lfStrikeOut = 0; 400*5c6c1daeSBarry Smith logfont.lfUnderline = 0; 401*5c6c1daeSBarry Smith logfont.lfWeight = FW_NORMAL; 402*5c6c1daeSBarry Smith hfont = CreateFontIndirect(&logfont); 403*5c6c1daeSBarry Smith TranslateColor_Win32(draw,color); 404*5c6c1daeSBarry Smith if (windraw->node->DoubleBuffered) { 405*5c6c1daeSBarry Smith hdc = windraw->node->DoubleBuffer; 406*5c6c1daeSBarry Smith } else { 407*5c6c1daeSBarry Smith hdc = windraw->node->Buffer; 408*5c6c1daeSBarry Smith } 409*5c6c1daeSBarry Smith SelectFont(hdc,hfont); 410*5c6c1daeSBarry Smith SetTextColor(hdc,windraw->currentcolor); 411*5c6c1daeSBarry Smith DrawText(hdc,text,lstrlen(text),&r,DT_NOCLIP); 412*5c6c1daeSBarry Smith DeleteObject(hfont); 413*5c6c1daeSBarry Smith /* Forces a WM_PAINT message and erases background */ 414*5c6c1daeSBarry Smith InvalidateRect(windraw->hWnd,NULL,TRUE); 415*5c6c1daeSBarry Smith UpdateWindow(windraw->hWnd); 416*5c6c1daeSBarry Smith PetscFunctionReturn(0); 417*5c6c1daeSBarry Smith } 418*5c6c1daeSBarry Smith 419*5c6c1daeSBarry Smith #undef __FUNCT__ 420*5c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawStringVertical_Win32" 421*5c6c1daeSBarry Smith static PetscErrorCode PetscDrawStringVertical_Win32(PetscDraw draw,PetscReal x,PetscReal y,int color,const char *text) 422*5c6c1daeSBarry Smith { 423*5c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32*)draw->data; 424*5c6c1daeSBarry Smith RECT r; 425*5c6c1daeSBarry Smith HFONT hfont; 426*5c6c1daeSBarry Smith LOGFONT logfont; 427*5c6c1daeSBarry Smith int x1,yone; 428*5c6c1daeSBarry Smith HDC hdc; 429*5c6c1daeSBarry Smith 430*5c6c1daeSBarry Smith PetscFunctionBegin; 431*5c6c1daeSBarry Smith x1 = XTRANS(draw,windraw,x); 432*5c6c1daeSBarry Smith yone = YTRANS(draw,windraw,y); 433*5c6c1daeSBarry Smith r.left = x1; 434*5c6c1daeSBarry Smith r.bottom = yone + 30; 435*5c6c1daeSBarry Smith r.right = x1 + 1; 436*5c6c1daeSBarry Smith r.top = yone - 30; 437*5c6c1daeSBarry Smith logfont.lfEscapement = 2700; /* Causes verticle text drawing */ 438*5c6c1daeSBarry Smith logfont.lfHeight = windraw->stringheight; 439*5c6c1daeSBarry Smith logfont.lfWidth = windraw->stringwidth; 440*5c6c1daeSBarry Smith logfont.lfOrientation = 0; 441*5c6c1daeSBarry Smith logfont.lfCharSet = DEFAULT_CHARSET; 442*5c6c1daeSBarry Smith logfont.lfClipPrecision = 0; 443*5c6c1daeSBarry Smith logfont.lfItalic = 0; 444*5c6c1daeSBarry Smith logfont.lfOutPrecision = 0; 445*5c6c1daeSBarry Smith logfont.lfPitchAndFamily = DEFAULT_PITCH; 446*5c6c1daeSBarry Smith logfont.lfQuality = DEFAULT_QUALITY; 447*5c6c1daeSBarry Smith logfont.lfStrikeOut = 0; 448*5c6c1daeSBarry Smith logfont.lfUnderline = 0; 449*5c6c1daeSBarry Smith logfont.lfWeight = FW_NORMAL; 450*5c6c1daeSBarry Smith hfont = CreateFontIndirect(&logfont); 451*5c6c1daeSBarry Smith TranslateColor_Win32(draw,color); 452*5c6c1daeSBarry Smith if (windraw->node->DoubleBuffered) { 453*5c6c1daeSBarry Smith hdc = windraw->node->DoubleBuffer; 454*5c6c1daeSBarry Smith } else { 455*5c6c1daeSBarry Smith hdc = windraw->node->Buffer; 456*5c6c1daeSBarry Smith } 457*5c6c1daeSBarry Smith SelectFont(hdc,hfont); 458*5c6c1daeSBarry Smith SetTextColor(hdc,windraw->currentcolor); 459*5c6c1daeSBarry Smith DrawText(hdc,text,lstrlen(text),&r,DT_NOCLIP | DT_SINGLELINE ); 460*5c6c1daeSBarry Smith DeleteObject(hfont); 461*5c6c1daeSBarry Smith /* Forces a WM_PAINT message and erases background */ 462*5c6c1daeSBarry Smith InvalidateRect(windraw->hWnd,NULL,TRUE); 463*5c6c1daeSBarry Smith UpdateWindow(windraw->hWnd); 464*5c6c1daeSBarry Smith PetscFunctionReturn(0); 465*5c6c1daeSBarry Smith } 466*5c6c1daeSBarry Smith 467*5c6c1daeSBarry Smith #undef __FUNCT__ 468*5c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawStringSetSize_Win32" 469*5c6c1daeSBarry Smith static PetscErrorCode PetscDrawStringSetSize_Win32(PetscDraw draw,PetscReal width,PetscReal height) 470*5c6c1daeSBarry Smith { 471*5c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32*)draw->data; 472*5c6c1daeSBarry Smith int w,h; 473*5c6c1daeSBarry Smith 474*5c6c1daeSBarry Smith PetscFunctionBegin; 475*5c6c1daeSBarry Smith w = (int)((windraw->w)*width *(draw->port_xr - draw->port_xl)/(draw->coor_xr - draw->coor_xl)); 476*5c6c1daeSBarry Smith h = (int)((windraw->h)*height*(draw->port_yr - draw->port_yl)/(draw->coor_yr - draw->coor_yl)); 477*5c6c1daeSBarry Smith if (h < 1) h = 1; 478*5c6c1daeSBarry Smith if (w < 1) w = 1; 479*5c6c1daeSBarry Smith windraw->stringheight = h; 480*5c6c1daeSBarry Smith windraw->stringwidth = w; 481*5c6c1daeSBarry Smith PetscFunctionReturn(0); 482*5c6c1daeSBarry Smith } 483*5c6c1daeSBarry Smith #undef __FUNCT__ 484*5c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawStringGetSize_Win32" 485*5c6c1daeSBarry Smith static PetscErrorCode PetscDrawStringGetSize_Win32(PetscDraw draw,PetscReal *width,PetscReal *height) 486*5c6c1daeSBarry Smith { 487*5c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32*)draw->data; 488*5c6c1daeSBarry Smith double scaleX = (draw->coor_xr - draw->coor_xl)/(draw->w)*(draw->port_xr - draw->port_xl); 489*5c6c1daeSBarry Smith double scaleY = (draw->coor_yr - draw->coor_yl)/(draw->h)*(draw->port_yr - draw->port_yl); 490*5c6c1daeSBarry Smith 491*5c6c1daeSBarry Smith PetscFunctionBegin; 492*5c6c1daeSBarry Smith *height = (double)windraw->stringheight*scaleY; 493*5c6c1daeSBarry Smith *width = (double)windraw->stringwidth*scaleX; 494*5c6c1daeSBarry Smith PetscFunctionReturn(0); 495*5c6c1daeSBarry Smith } 496*5c6c1daeSBarry Smith 497*5c6c1daeSBarry Smith #undef __FUNCT__ 498*5c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawResizeWindow_Win32" 499*5c6c1daeSBarry Smith static PetscErrorCode PetscDrawResizeWindow_Win32(PetscDraw draw,int w,int h) 500*5c6c1daeSBarry Smith { 501*5c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32*)draw->data; 502*5c6c1daeSBarry Smith RECT r; 503*5c6c1daeSBarry Smith 504*5c6c1daeSBarry Smith PetscFunctionBegin; 505*5c6c1daeSBarry Smith GetWindowRect(windraw->hWnd,&r); 506*5c6c1daeSBarry Smith MoveWindow(windraw->hWnd,r.left,r.top,(int)w,(int)h,TRUE); 507*5c6c1daeSBarry Smith /* set all variable dealing with window dimensions */ 508*5c6c1daeSBarry Smith windraw->node->bitheight = windraw->h = draw->h = h; 509*5c6c1daeSBarry Smith windraw->node->bitwidth = windraw->w = draw->w = w; 510*5c6c1daeSBarry Smith /* set up graphic buffers with the new size of window */ 511*5c6c1daeSBarry Smith SetBitmapDimensionEx(windraw->node->BufferBit,w,h,NULL); 512*5c6c1daeSBarry Smith if (windraw->node->DoubleBuffered) { 513*5c6c1daeSBarry Smith SetBitmapDimensionEx(windraw->node->DoubleBufferBit,w,h,NULL); 514*5c6c1daeSBarry Smith } 515*5c6c1daeSBarry Smith windraw->haveresized = PETSC_TRUE; 516*5c6c1daeSBarry Smith PetscFunctionReturn(0); 517*5c6c1daeSBarry Smith } 518*5c6c1daeSBarry Smith 519*5c6c1daeSBarry Smith #undef __FUNCT__ 520*5c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawCheckResizeWindow_Win32" 521*5c6c1daeSBarry Smith static PetscErrorCode PetscDrawCheckResizedWindow_Win32(PetscDraw draw) 522*5c6c1daeSBarry Smith { 523*5c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32*)draw->data; 524*5c6c1daeSBarry Smith 525*5c6c1daeSBarry Smith PetscFunctionBegin; 526*5c6c1daeSBarry Smith if (windraw->haveresized == 1) { 527*5c6c1daeSBarry Smith PetscFunctionReturn(1); 528*5c6c1daeSBarry Smith } else { 529*5c6c1daeSBarry Smith PetscFunctionReturn(0); 530*5c6c1daeSBarry Smith } 531*5c6c1daeSBarry Smith 532*5c6c1daeSBarry Smith } 533*5c6c1daeSBarry Smith 534*5c6c1daeSBarry Smith #undef __FUNCT__ 535*5c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawSetTitle_Win32" 536*5c6c1daeSBarry Smith static PetscErrorCode PetscDrawSetTitle_Win32(PetscDraw draw, const char title[]) 537*5c6c1daeSBarry Smith { 538*5c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32*)draw->data; 539*5c6c1daeSBarry Smith 540*5c6c1daeSBarry Smith PetscFunctionBegin; 541*5c6c1daeSBarry Smith SetWindowText(windraw->hWnd,title); 542*5c6c1daeSBarry Smith PetscFunctionReturn(0); 543*5c6c1daeSBarry Smith } 544*5c6c1daeSBarry Smith 545*5c6c1daeSBarry Smith #undef __FUNCT__ 546*5c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawClear_Win32" 547*5c6c1daeSBarry Smith static PetscErrorCode PetscDrawClear_Win32(PetscDraw draw) 548*5c6c1daeSBarry Smith { 549*5c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32*)draw->data; 550*5c6c1daeSBarry Smith 551*5c6c1daeSBarry Smith PetscFunctionBegin; 552*5c6c1daeSBarry Smith /* clear primary buffer */ 553*5c6c1daeSBarry Smith ExtFloodFill(windraw->node->Buffer,0,0,COLOR_WINDOW,FLOODFILLBORDER); 554*5c6c1daeSBarry Smith /* if exists clear secondary buffer */ 555*5c6c1daeSBarry Smith if (windraw->node->DoubleBuffered) { 556*5c6c1daeSBarry Smith ExtFloodFill(windraw->node->DoubleBuffer,0,0,COLOR_WINDOW,FLOODFILLBORDER); 557*5c6c1daeSBarry Smith } 558*5c6c1daeSBarry Smith /* force WM_PAINT message so cleared buffer will show */ 559*5c6c1daeSBarry Smith InvalidateRect(windraw->hWnd,NULL,TRUE); 560*5c6c1daeSBarry Smith UpdateWindow(windraw->hWnd); 561*5c6c1daeSBarry Smith PetscFunctionReturn(0); 562*5c6c1daeSBarry Smith } 563*5c6c1daeSBarry Smith 564*5c6c1daeSBarry Smith #undef __FUNCT__ 565*5c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawTriangle_Win32" 566*5c6c1daeSBarry Smith static PetscErrorCode PetscDrawTriangle_Win32(PetscDraw draw,PetscReal x1,PetscReal yone,PetscReal x2,PetscReal y2, 567*5c6c1daeSBarry Smith PetscReal x3,PetscReal y3,int c1,int c2,int c3) 568*5c6c1daeSBarry Smith { 569*5c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32*)draw->data; 570*5c6c1daeSBarry Smith HBRUSH hbrush; 571*5c6c1daeSBarry Smith HPEN hpen; 572*5c6c1daeSBarry Smith int p1x,p1y,p2x,p2y,p3x,p3y; 573*5c6c1daeSBarry Smith HDC bit; 574*5c6c1daeSBarry Smith 575*5c6c1daeSBarry Smith PetscFunctionBegin; 576*5c6c1daeSBarry Smith AverageColorTriangle_Win32(draw,c1,c2,c3); 577*5c6c1daeSBarry Smith hbrush = CreateSolidBrush(windraw->currentcolor); 578*5c6c1daeSBarry Smith hpen = CreatePen(PS_SOLID,0,windraw->currentcolor); 579*5c6c1daeSBarry Smith p1x = XTRANS(draw,windraw,x1); 580*5c6c1daeSBarry Smith p2x = XTRANS(draw,windraw,x2); 581*5c6c1daeSBarry Smith p3x = XTRANS(draw,windraw,x3); 582*5c6c1daeSBarry Smith p1y = YTRANS(draw,windraw,yone); 583*5c6c1daeSBarry Smith p2y = YTRANS(draw,windraw,y2); 584*5c6c1daeSBarry Smith p3y = YTRANS(draw,windraw,y3); 585*5c6c1daeSBarry Smith 586*5c6c1daeSBarry Smith if (windraw->node->DoubleBuffered) { 587*5c6c1daeSBarry Smith bit = windraw->node->DoubleBuffer; 588*5c6c1daeSBarry Smith } else { 589*5c6c1daeSBarry Smith bit = windraw->node->Buffer; 590*5c6c1daeSBarry Smith } 591*5c6c1daeSBarry Smith BeginPath(bit); 592*5c6c1daeSBarry Smith MoveToEx(bit,p1x,p1y,NULL); 593*5c6c1daeSBarry Smith LineTo(bit,p2x,p2y); 594*5c6c1daeSBarry Smith LineTo(bit,p3x,p3y); 595*5c6c1daeSBarry Smith LineTo(bit,p1x,p1y); 596*5c6c1daeSBarry Smith EndPath(bit); 597*5c6c1daeSBarry Smith SelectPen(bit,hpen); 598*5c6c1daeSBarry Smith SelectBrush(bit,hbrush); 599*5c6c1daeSBarry Smith StrokeAndFillPath(bit); 600*5c6c1daeSBarry Smith /* Forces a WM_PAINT message and erases background */ 601*5c6c1daeSBarry Smith InvalidateRect(windraw->hWnd,NULL,TRUE); 602*5c6c1daeSBarry Smith UpdateWindow(windraw->hWnd); 603*5c6c1daeSBarry Smith PetscFunctionReturn(0); 604*5c6c1daeSBarry Smith } 605*5c6c1daeSBarry Smith 606*5c6c1daeSBarry Smith #undef __FUNCT__ 607*5c6c1daeSBarry Smith #define __FUNCT__ "PopMessageLoopThread_Win32" 608*5c6c1daeSBarry Smith void PopMessageLoopThread_Win32(PetscDraw popdraw) 609*5c6c1daeSBarry Smith { 610*5c6c1daeSBarry Smith PetscDraw_Win32 *pop = (PetscDraw_Win32*)popdraw->data; 611*5c6c1daeSBarry Smith MSG msg; 612*5c6c1daeSBarry Smith HWND hWnd = NULL; 613*5c6c1daeSBarry Smith char PopClassName [MAX_LOADSTRING + 1]; 614*5c6c1daeSBarry Smith RECT r; 615*5c6c1daeSBarry Smith int width,height; 616*5c6c1daeSBarry Smith WNDCLASSEX myclass; 617*5c6c1daeSBarry Smith LPVOID lpMsgBuf; 618*5c6c1daeSBarry Smith 619*5c6c1daeSBarry Smith PetscFunctionBegin; 620*5c6c1daeSBarry Smith /* initialize window class parameters */ 621*5c6c1daeSBarry Smith myclass.cbSize = sizeof(WNDCLASSEX); 622*5c6c1daeSBarry Smith myclass.style = CS_OWNDC; 623*5c6c1daeSBarry Smith myclass.lpfnWndProc = (WNDPROC)PetscWndProc; 624*5c6c1daeSBarry Smith myclass.cbClsExtra = 0; 625*5c6c1daeSBarry Smith myclass.cbWndExtra = 0; 626*5c6c1daeSBarry Smith myclass.hInstance = NULL; 627*5c6c1daeSBarry Smith myclass.hIcon = NULL; 628*5c6c1daeSBarry Smith myclass.hCursor = LoadCursor(NULL, IDC_ARROW); 629*5c6c1daeSBarry Smith myclass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); 630*5c6c1daeSBarry Smith myclass.lpszMenuName = NULL; 631*5c6c1daeSBarry Smith myclass.lpszClassName = PopClassName; 632*5c6c1daeSBarry Smith myclass.hIconSm = NULL; 633*5c6c1daeSBarry Smith 634*5c6c1daeSBarry Smith RegisterClassEx(&myclass); 635*5c6c1daeSBarry Smith 636*5c6c1daeSBarry Smith SetRect(&r,0,0,450,450); 637*5c6c1daeSBarry Smith 638*5c6c1daeSBarry Smith width = (r.right - r.left) / 3; 639*5c6c1daeSBarry Smith height = (r.bottom - r.top) / 3; 640*5c6c1daeSBarry Smith 641*5c6c1daeSBarry Smith hWnd = CreateWindowEx(0, 642*5c6c1daeSBarry Smith PopClassName, 643*5c6c1daeSBarry Smith NULL, 644*5c6c1daeSBarry Smith WS_POPUPWINDOW | WS_CAPTION, 645*5c6c1daeSBarry Smith 0,0, 646*5c6c1daeSBarry Smith width,height, 647*5c6c1daeSBarry Smith NULL, 648*5c6c1daeSBarry Smith NULL, 649*5c6c1daeSBarry Smith hInst, 650*5c6c1daeSBarry Smith NULL); 651*5c6c1daeSBarry Smith pop->x = 0; 652*5c6c1daeSBarry Smith pop->y = 0; 653*5c6c1daeSBarry Smith pop->w = width; 654*5c6c1daeSBarry Smith pop->h = height; 655*5c6c1daeSBarry Smith 656*5c6c1daeSBarry Smith if (!hWnd) { 657*5c6c1daeSBarry Smith lpMsgBuf = (LPVOID)"Window Not Succesfully Created"; 658*5c6c1daeSBarry Smith MessageBox( NULL, (LPCTSTR)lpMsgBuf, "Error", MB_OK | MB_ICONINFORMATION ); 659*5c6c1daeSBarry Smith LocalFree( lpMsgBuf ); 660*5c6c1daeSBarry Smith exit(0); 661*5c6c1daeSBarry Smith } 662*5c6c1daeSBarry Smith pop->hWnd = hWnd; 663*5c6c1daeSBarry Smith /* display and update new popup window */ 664*5c6c1daeSBarry Smith ShowWindow(pop->hWnd, SW_SHOWNORMAL); 665*5c6c1daeSBarry Smith UpdateWindow(pop->hWnd); 666*5c6c1daeSBarry Smith SetEvent(pop->hReadyEvent); 667*5c6c1daeSBarry Smith 668*5c6c1daeSBarry Smith while (GetMessage(&msg, pop->hWnd, 0, 0)) { 669*5c6c1daeSBarry Smith TranslateMessage(&msg); 670*5c6c1daeSBarry Smith DispatchMessage(&msg); 671*5c6c1daeSBarry Smith } 672*5c6c1daeSBarry Smith PetscFunctionReturnVoid(); 673*5c6c1daeSBarry Smith } 674*5c6c1daeSBarry Smith 675*5c6c1daeSBarry Smith #undef __FUNCT__ 676*5c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawDestroy_Win32" 677*5c6c1daeSBarry Smith static PetscErrorCode PetscDrawDestroy_Win32(PetscDraw draw) 678*5c6c1daeSBarry Smith { 679*5c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32*)draw->data; 680*5c6c1daeSBarry Smith 681*5c6c1daeSBarry Smith PetscFunctionBegin; 682*5c6c1daeSBarry Smith SendMessage(windraw->hWnd,WM_DESTROY,0,0); 683*5c6c1daeSBarry Smith PetscFree(windraw); 684*5c6c1daeSBarry Smith PetscFunctionReturn(0); 685*5c6c1daeSBarry Smith } 686*5c6c1daeSBarry Smith 687*5c6c1daeSBarry Smith #undef __FUNCT__ 688*5c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawSynchronizedFlush_Win32" 689*5c6c1daeSBarry Smith static PetscErrorCode PetscDrawSynchronizedFlush_Win32(PetscDraw draw) 690*5c6c1daeSBarry Smith { 691*5c6c1daeSBarry Smith /* Multi Processor is not implemeted yet */ 692*5c6c1daeSBarry Smith PetscFunctionBegin; 693*5c6c1daeSBarry Smith PetscDrawFlush_Win32(draw); 694*5c6c1daeSBarry Smith PetscFunctionReturn(0); 695*5c6c1daeSBarry Smith } 696*5c6c1daeSBarry Smith 697*5c6c1daeSBarry Smith #undef __FUNCT__ 698*5c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawSynchronizedClear_Win32" 699*5c6c1daeSBarry Smith static PetscErrorCode PetscDrawSynchronizedClear_Win32(PetscDraw draw) 700*5c6c1daeSBarry Smith { 701*5c6c1daeSBarry Smith /* Multi Processor is not implemeted yet */ 702*5c6c1daeSBarry Smith PetscFunctionBegin; 703*5c6c1daeSBarry Smith PetscDrawClear_Win32(draw); 704*5c6c1daeSBarry Smith PetscFunctionReturn(0); 705*5c6c1daeSBarry Smith } 706*5c6c1daeSBarry Smith 707*5c6c1daeSBarry Smith #undef __FUNCT__ 708*5c6c1daeSBarry Smith #define __FUNCT__ "MessageLoopThread_Win32" 709*5c6c1daeSBarry Smith void MessageLoopThread_Win32(PetscDraw draw) 710*5c6c1daeSBarry Smith { 711*5c6c1daeSBarry Smith PetscDraw_Win32 *windraw = (PetscDraw_Win32*)draw->data; 712*5c6c1daeSBarry Smith MSG msg; 713*5c6c1daeSBarry Smith HWND hWnd = NULL; 714*5c6c1daeSBarry Smith char classname[MAX_LOADSTRING + 1]; 715*5c6c1daeSBarry Smith WNDCLASSEX wclass; 716*5c6c1daeSBarry Smith LPVOID lpMsgBuf; 717*5c6c1daeSBarry Smith 718*5c6c1daeSBarry Smith PetscFunctionBegin; 719*5c6c1daeSBarry Smith /* initialize window class parameters */ 720*5c6c1daeSBarry Smith wclass.cbSize = sizeof(WNDCLASSEX); 721*5c6c1daeSBarry Smith wclass.style = CS_SAVEBITS | CS_HREDRAW | CS_VREDRAW; 722*5c6c1daeSBarry Smith wclass.lpfnWndProc = (WNDPROC)PetscWndProc; 723*5c6c1daeSBarry Smith wclass.cbClsExtra = 0; 724*5c6c1daeSBarry Smith wclass.cbWndExtra = 0; 725*5c6c1daeSBarry Smith wclass.hInstance = NULL; 726*5c6c1daeSBarry Smith wclass.hIcon = LoadIcon(NULL,IDI_APPLICATION); 727*5c6c1daeSBarry Smith wclass.hCursor = LoadCursor(NULL,IDC_ARROW); 728*5c6c1daeSBarry Smith wclass.hbrBackground = GetStockBrush(WHITE_BRUSH); 729*5c6c1daeSBarry Smith wclass.lpszMenuName = NULL; 730*5c6c1daeSBarry Smith wclass.lpszClassName = classname; 731*5c6c1daeSBarry Smith wclass.hIconSm = NULL; 732*5c6c1daeSBarry Smith 733*5c6c1daeSBarry Smith RegisterClassEx(&wclass); 734*5c6c1daeSBarry Smith 735*5c6c1daeSBarry Smith 736*5c6c1daeSBarry Smith hWnd = CreateWindowEx(0, 737*5c6c1daeSBarry Smith classname, 738*5c6c1daeSBarry Smith NULL, 739*5c6c1daeSBarry Smith WS_OVERLAPPEDWINDOW, 740*5c6c1daeSBarry Smith draw->x, 741*5c6c1daeSBarry Smith draw->y, 742*5c6c1daeSBarry Smith draw->w, 743*5c6c1daeSBarry Smith draw->h, 744*5c6c1daeSBarry Smith NULL, 745*5c6c1daeSBarry Smith NULL, 746*5c6c1daeSBarry Smith hInst, 747*5c6c1daeSBarry Smith NULL); 748*5c6c1daeSBarry Smith 749*5c6c1daeSBarry Smith if (!hWnd) { 750*5c6c1daeSBarry Smith lpMsgBuf = (LPVOID)"Window Not Succesfully Created"; 751*5c6c1daeSBarry Smith MessageBox( NULL, (LPCTSTR)lpMsgBuf, "Error", MB_OK | MB_ICONINFORMATION ); 752*5c6c1daeSBarry Smith LocalFree( lpMsgBuf ); 753*5c6c1daeSBarry Smith exit(0); 754*5c6c1daeSBarry Smith } 755*5c6c1daeSBarry Smith windraw->hWnd = hWnd; 756*5c6c1daeSBarry Smith /* display and update new window */ 757*5c6c1daeSBarry Smith ShowWindow(hWnd,SW_SHOWNORMAL); 758*5c6c1daeSBarry Smith UpdateWindow(hWnd); 759*5c6c1daeSBarry Smith SetEvent(windraw->hReadyEvent); 760*5c6c1daeSBarry Smith 761*5c6c1daeSBarry Smith while (GetMessage(&msg,hWnd, 0, 0)) { 762*5c6c1daeSBarry Smith TranslateMessage(&msg); 763*5c6c1daeSBarry Smith DispatchMessage(&msg); 764*5c6c1daeSBarry Smith } 765*5c6c1daeSBarry Smith PetscFunctionReturnVoid(); 766*5c6c1daeSBarry Smith } 767*5c6c1daeSBarry Smith 768*5c6c1daeSBarry Smith 769*5c6c1daeSBarry Smith static struct _PetscDrawOps DvOps = { PetscDrawSetDoubleBuffer_Win32, 770*5c6c1daeSBarry Smith PetscDrawFlush_Win32, 771*5c6c1daeSBarry Smith PetscDrawLine_Win32, 772*5c6c1daeSBarry Smith PetscDrawLineSetWidth_Win32, 773*5c6c1daeSBarry Smith PetscDrawLineGetWidth_Win32, 774*5c6c1daeSBarry Smith PetscDrawPoint_Win32, 775*5c6c1daeSBarry Smith PetscDrawPointSetSize_Win32, 776*5c6c1daeSBarry Smith PetscDrawString_Win32, 777*5c6c1daeSBarry Smith PetscDrawStringVertical_Win32, 778*5c6c1daeSBarry Smith PetscDrawStringSetSize_Win32, 779*5c6c1daeSBarry Smith PetscDrawStringGetSize_Win32, 780*5c6c1daeSBarry Smith 0, 781*5c6c1daeSBarry Smith PetscDrawClear_Win32, 782*5c6c1daeSBarry Smith PetscDrawSynchronizedFlush_Win32, 783*5c6c1daeSBarry Smith PetscDrawRectangle_Win32, 784*5c6c1daeSBarry Smith PetscDrawTriangle_Win32, 785*5c6c1daeSBarry Smith 0, 786*5c6c1daeSBarry Smith PetscDrawGetMouseButton_Win32, 787*5c6c1daeSBarry Smith PetscDrawPause_Win32, 788*5c6c1daeSBarry Smith PetscDrawSynchronizedClear_Win32, 789*5c6c1daeSBarry Smith 0, 790*5c6c1daeSBarry Smith 0, 791*5c6c1daeSBarry Smith PetscDrawGetPopup_Win32, 792*5c6c1daeSBarry Smith PetscDrawSetTitle_Win32, 793*5c6c1daeSBarry Smith PetscDrawCheckResizedWindow_Win32, 794*5c6c1daeSBarry Smith PetscDrawResizeWindow_Win32, 795*5c6c1daeSBarry Smith PetscDrawDestroy_Win32, 796*5c6c1daeSBarry Smith 0, 797*5c6c1daeSBarry Smith 0, 798*5c6c1daeSBarry Smith 0, 799*5c6c1daeSBarry Smith 0}; 800*5c6c1daeSBarry Smith 801*5c6c1daeSBarry Smith #undef __FUNCT__ 802*5c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawGetPopup_Win32" 803*5c6c1daeSBarry Smith static PetscErrorCode PetscDrawGetPopup_Win32(PetscDraw draw,PetscDraw *popdraw) 804*5c6c1daeSBarry Smith { 805*5c6c1daeSBarry Smith PetscDraw_Win32 *pop; 806*5c6c1daeSBarry Smith HANDLE hThread = NULL; 807*5c6c1daeSBarry Smith WindowNode newnode; 808*5c6c1daeSBarry Smith PetscErrorCode ierr; 809*5c6c1daeSBarry Smith 810*5c6c1daeSBarry Smith PetscFunctionBegin; 811*5c6c1daeSBarry Smith ierr = PetscNew(PetscDraw_Win32,&pop);CHKERRQ(ierr); 812*5c6c1daeSBarry Smith (*popdraw)->data = pop; 813*5c6c1daeSBarry Smith 814*5c6c1daeSBarry Smith /* the following is temporary fix for initializing a global datastructure */ 815*5c6c1daeSBarry Smith if (!g_hWindowListMutex) { 816*5c6c1daeSBarry Smith g_hWindowListMutex = CreateMutex(NULL,FALSE,NULL); 817*5c6c1daeSBarry Smith } 818*5c6c1daeSBarry Smith ierr = PetscMemcpy((*popdraw)->ops,&DvOps,sizeof(DvOps));CHKERRQ(ierr); 819*5c6c1daeSBarry Smith 820*5c6c1daeSBarry Smith pop->hReadyEvent = CreateEvent(NULL, TRUE, FALSE, NULL); 821*5c6c1daeSBarry Smith CreateThread(NULL, 0,(LPTHREAD_START_ROUTINE)PopMessageLoopThread_Win32,*popdraw,0,(unsigned long*)hThread); 822*5c6c1daeSBarry Smith CloseHandle(hThread); 823*5c6c1daeSBarry Smith WaitForSingleObject(pop->hReadyEvent, INFINITE); 824*5c6c1daeSBarry Smith CloseHandle(pop->hReadyEvent); 825*5c6c1daeSBarry Smith WaitForSingleObject(g_hWindowListMutex, INFINITE); 826*5c6c1daeSBarry Smith 827*5c6c1daeSBarry Smith draw->popup = (*popdraw); 828*5c6c1daeSBarry Smith ierr = PetscNew(struct _p_WindowNode,&newnode);CHKERRQ(ierr); 829*5c6c1daeSBarry Smith newnode->MouseListHead = NULL; 830*5c6c1daeSBarry Smith newnode->MouseListTail = NULL; 831*5c6c1daeSBarry Smith newnode->wnext = WindowListHead; 832*5c6c1daeSBarry Smith newnode->wprev = NULL; 833*5c6c1daeSBarry Smith newnode->hWnd = pop->hWnd; 834*5c6c1daeSBarry Smith if (WindowListHead != NULL) { 835*5c6c1daeSBarry Smith WindowListHead->wprev = newnode; 836*5c6c1daeSBarry Smith } 837*5c6c1daeSBarry Smith WindowListHead = newnode; 838*5c6c1daeSBarry Smith pop->hdc = GetDC(pop->hWnd); 839*5c6c1daeSBarry Smith 840*5c6c1daeSBarry Smith pop->stringheight = 10; 841*5c6c1daeSBarry Smith pop->stringwidth = 6; 842*5c6c1daeSBarry Smith pop->linewidth = 1; /* default pixel sizes of graphics until user changes them */ 843*5c6c1daeSBarry Smith pop->pointdiameter = 1; 844*5c6c1daeSBarry Smith pop->node = newnode; 845*5c6c1daeSBarry Smith 846*5c6c1daeSBarry Smith newnode->bitwidth = pop->w; 847*5c6c1daeSBarry Smith newnode->bitheight = pop->h; 848*5c6c1daeSBarry Smith 849*5c6c1daeSBarry Smith /* Create and initialize primary graphics buffer */ 850*5c6c1daeSBarry Smith newnode->Buffer = CreateCompatibleDC(pop->hdc); 851*5c6c1daeSBarry Smith newnode->BufferBit = CreateCompatibleBitmap(pop->hdc,pop->w,pop->h); 852*5c6c1daeSBarry Smith newnode->store = SelectObject(newnode->Buffer,newnode->BufferBit); 853*5c6c1daeSBarry Smith ExtFloodFill(newnode->Buffer,0,0,COLOR_WINDOW,FLOODFILLBORDER); 854*5c6c1daeSBarry Smith 855*5c6c1daeSBarry Smith 856*5c6c1daeSBarry Smith newnode->event = CreateEvent(NULL, TRUE, FALSE, NULL); 857*5c6c1daeSBarry Smith newnode->DoubleBuffered = PETSC_FALSE; 858*5c6c1daeSBarry Smith 859*5c6c1daeSBarry Smith ReleaseDC(pop->hWnd,pop->hdc); 860*5c6c1daeSBarry Smith ReleaseMutex(g_hWindowListMutex); 861*5c6c1daeSBarry Smith PetscFunctionReturn(0); 862*5c6c1daeSBarry Smith } 863*5c6c1daeSBarry Smith 864*5c6c1daeSBarry Smith EXTERN_C_BEGIN 865*5c6c1daeSBarry Smith #undef __FUNCT__ 866*5c6c1daeSBarry Smith #define __FUNCT__ "PetscDrawCreate_Win32" 867*5c6c1daeSBarry Smith PetscErrorCode PetscDrawCreate_Win32(PetscDraw draw) 868*5c6c1daeSBarry Smith { 869*5c6c1daeSBarry Smith PetscDraw_Win32 *windraw; 870*5c6c1daeSBarry Smith HANDLE hThread = NULL; 871*5c6c1daeSBarry Smith PetscErrorCode ierr; 872*5c6c1daeSBarry Smith WindowNode newnode; 873*5c6c1daeSBarry Smith 874*5c6c1daeSBarry Smith PetscFunctionBegin; 875*5c6c1daeSBarry Smith ierr = PetscNew(PetscDraw_Win32,&windraw);CHKERRQ(ierr); 876*5c6c1daeSBarry Smith draw->data = windraw; 877*5c6c1daeSBarry Smith 878*5c6c1daeSBarry Smith /* the following is temporary fix for initializing a global datastructure */ 879*5c6c1daeSBarry Smith if (!g_hWindowListMutex) { 880*5c6c1daeSBarry Smith g_hWindowListMutex = CreateMutex(NULL,FALSE,NULL); 881*5c6c1daeSBarry Smith } 882*5c6c1daeSBarry Smith ierr = PetscMemcpy(draw->ops,&DvOps,sizeof(DvOps));CHKERRQ(ierr); 883*5c6c1daeSBarry Smith 884*5c6c1daeSBarry Smith windraw->hReadyEvent = CreateEvent(NULL,TRUE,FALSE,NULL); 885*5c6c1daeSBarry Smith /* makes call to MessageLoopThread to creat window and attach a thread */ 886*5c6c1daeSBarry Smith CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)MessageLoopThread_Win32,draw,0,(unsigned long*)hThread); 887*5c6c1daeSBarry Smith CloseHandle(hThread); 888*5c6c1daeSBarry Smith WaitForSingleObject(windraw->hReadyEvent,INFINITE); 889*5c6c1daeSBarry Smith CloseHandle(windraw->hReadyEvent); 890*5c6c1daeSBarry Smith WaitForSingleObject(g_hWindowListMutex,INFINITE); 891*5c6c1daeSBarry Smith 892*5c6c1daeSBarry Smith ierr = PetscNew(struct _p_WindowNode,&newnode);CHKERRQ(ierr); 893*5c6c1daeSBarry Smith newnode->MouseListHead = NULL; 894*5c6c1daeSBarry Smith newnode->MouseListTail = NULL; 895*5c6c1daeSBarry Smith newnode->wnext = WindowListHead; 896*5c6c1daeSBarry Smith newnode->wprev = NULL; 897*5c6c1daeSBarry Smith newnode->hWnd = windraw->hWnd; 898*5c6c1daeSBarry Smith if (WindowListHead != NULL) { 899*5c6c1daeSBarry Smith WindowListHead->wprev = newnode; 900*5c6c1daeSBarry Smith } 901*5c6c1daeSBarry Smith WindowListHead = newnode; 902*5c6c1daeSBarry Smith windraw->hdc = GetDC(windraw->hWnd); 903*5c6c1daeSBarry Smith 904*5c6c1daeSBarry Smith windraw->stringheight = 10; 905*5c6c1daeSBarry Smith windraw->stringwidth = 6; 906*5c6c1daeSBarry Smith windraw->linewidth = 1; /* default pixel sizes of graphics until user changes them */ 907*5c6c1daeSBarry Smith windraw->pointdiameter = 1; 908*5c6c1daeSBarry Smith windraw->node = newnode; 909*5c6c1daeSBarry Smith 910*5c6c1daeSBarry Smith windraw->x = draw->x; 911*5c6c1daeSBarry Smith windraw->y = draw->y; 912*5c6c1daeSBarry Smith windraw->w = newnode->bitwidth = draw->w; 913*5c6c1daeSBarry Smith windraw->h = newnode->bitheight = draw->h; 914*5c6c1daeSBarry Smith 915*5c6c1daeSBarry Smith /* Create and initialize primary graphics buffer */ 916*5c6c1daeSBarry Smith newnode->Buffer = CreateCompatibleDC(windraw->hdc); 917*5c6c1daeSBarry Smith newnode->BufferBit = CreateCompatibleBitmap(windraw->hdc,windraw->w,windraw->h); 918*5c6c1daeSBarry Smith newnode->store = SelectObject(newnode->Buffer,newnode->BufferBit); 919*5c6c1daeSBarry Smith ExtFloodFill(newnode->Buffer,0,0,COLOR_WINDOW,FLOODFILLBORDER); 920*5c6c1daeSBarry Smith 921*5c6c1daeSBarry Smith newnode->event = CreateEvent(NULL,TRUE,FALSE,NULL); 922*5c6c1daeSBarry Smith newnode->DoubleBuffered = PETSC_FALSE; 923*5c6c1daeSBarry Smith 924*5c6c1daeSBarry Smith ReleaseDC(windraw->hWnd,windraw->hdc); 925*5c6c1daeSBarry Smith ReleaseMutex(g_hWindowListMutex); 926*5c6c1daeSBarry Smith PetscFunctionReturn(0); 927*5c6c1daeSBarry Smith } 928*5c6c1daeSBarry Smith EXTERN_C_END 929*5c6c1daeSBarry Smith 930*5c6c1daeSBarry Smith 931*5c6c1daeSBarry Smith /* FUNCTION: PetscWndProc(HWND, unsigned, WORD, LONG) 932*5c6c1daeSBarry Smith PURPOSE: Processes messages for the main window. 933*5c6c1daeSBarry Smith WM_COMMAND - process the application menu 934*5c6c1daeSBarry Smith WM_PAINT - Paint the main window 935*5c6c1daeSBarry Smith WM_DESTROY - post a quit message and return */ 936*5c6c1daeSBarry Smith 937*5c6c1daeSBarry Smith #undef __FUNCT__ 938*5c6c1daeSBarry Smith #define __FUNCT__ "PetscWndProc" 939*5c6c1daeSBarry Smith LRESULT CALLBACK PetscWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) 940*5c6c1daeSBarry Smith { 941*5c6c1daeSBarry Smith int wmId, wmEvent; 942*5c6c1daeSBarry Smith 943*5c6c1daeSBarry Smith PetscFunctionBegin; 944*5c6c1daeSBarry Smith switch (message) { 945*5c6c1daeSBarry Smith HANDLE_MSG(hWnd,WM_PAINT,OnPaint_Win32); 946*5c6c1daeSBarry Smith HANDLE_MSG(hWnd,WM_DESTROY,OnDestroy_Win32); 947*5c6c1daeSBarry Smith case WM_COMMAND: 948*5c6c1daeSBarry Smith wmId = LOWORD(wParam); 949*5c6c1daeSBarry Smith wmEvent = HIWORD(wParam); 950*5c6c1daeSBarry Smith /* Parse the menu selections:*/ 951*5c6c1daeSBarry Smith switch (wmId) { 952*5c6c1daeSBarry Smith case IDM_EXIT: 953*5c6c1daeSBarry Smith DestroyWindow(hWnd); 954*5c6c1daeSBarry Smith break; 955*5c6c1daeSBarry Smith default: 956*5c6c1daeSBarry Smith return DefWindowProc(hWnd, message, wParam, lParam); 957*5c6c1daeSBarry Smith } 958*5c6c1daeSBarry Smith break; 959*5c6c1daeSBarry Smith case WM_LBUTTONUP: 960*5c6c1daeSBarry Smith MouseRecord_Win32(hWnd,PETSC_BUTTON_LEFT); 961*5c6c1daeSBarry Smith break; 962*5c6c1daeSBarry Smith case WM_RBUTTONUP: 963*5c6c1daeSBarry Smith MouseRecord_Win32(hWnd,PETSC_BUTTON_RIGHT); 964*5c6c1daeSBarry Smith break; 965*5c6c1daeSBarry Smith case WM_MBUTTONUP: 966*5c6c1daeSBarry Smith MouseRecord_Win32(hWnd,PETSC_BUTTON_CENTER); 967*5c6c1daeSBarry Smith break; 968*5c6c1daeSBarry Smith default: 969*5c6c1daeSBarry Smith PetscFunctionReturn(DefWindowProc(hWnd, message, wParam, lParam)); 970*5c6c1daeSBarry Smith } 971*5c6c1daeSBarry Smith PetscFunctionReturn(0); 972*5c6c1daeSBarry Smith } 973*5c6c1daeSBarry Smith 974*5c6c1daeSBarry Smith #undef __FUNCT__ 975*5c6c1daeSBarry Smith #define __FUNCT__ "OnPaint_Win32" 976*5c6c1daeSBarry Smith static void OnPaint_Win32(HWND hWnd) 977*5c6c1daeSBarry Smith { 978*5c6c1daeSBarry Smith PAINTSTRUCT ps; 979*5c6c1daeSBarry Smith HDC hdc; 980*5c6c1daeSBarry Smith WindowNode current = NULL; 981*5c6c1daeSBarry Smith 982*5c6c1daeSBarry Smith PetscFunctionBegin; 983*5c6c1daeSBarry Smith InvalidateRect(hWnd,NULL,TRUE); 984*5c6c1daeSBarry Smith WaitForSingleObject(g_hWindowListMutex, INFINITE); 985*5c6c1daeSBarry Smith current = WindowListHead; 986*5c6c1daeSBarry Smith hdc = BeginPaint(hWnd, &ps); 987*5c6c1daeSBarry Smith 988*5c6c1daeSBarry Smith while(current != NULL) { 989*5c6c1daeSBarry Smith if (current->hWnd == hWnd) { 990*5c6c1daeSBarry Smith /* flushes primary buffer to window */ 991*5c6c1daeSBarry Smith BitBlt(hdc, 992*5c6c1daeSBarry Smith 0,0, 993*5c6c1daeSBarry Smith GetDeviceCaps(hdc,HORZRES), 994*5c6c1daeSBarry Smith GetDeviceCaps(hdc,VERTRES), 995*5c6c1daeSBarry Smith current->Buffer, 996*5c6c1daeSBarry Smith 0,0, 997*5c6c1daeSBarry Smith SRCCOPY); 998*5c6c1daeSBarry Smith 999*5c6c1daeSBarry Smith /* StretchBlt(hdc, 1000*5c6c1daeSBarry Smith 0,0, 1001*5c6c1daeSBarry Smith w,h, 1002*5c6c1daeSBarry Smith current->Buffer, 1003*5c6c1daeSBarry Smith 0,0, 1004*5c6c1daeSBarry Smith current->bitwidth, 1005*5c6c1daeSBarry Smith current->bitheight, 1006*5c6c1daeSBarry Smith SRCCOPY); */ 1007*5c6c1daeSBarry Smith break; 1008*5c6c1daeSBarry Smith } 1009*5c6c1daeSBarry Smith current = current->wnext; 1010*5c6c1daeSBarry Smith } 1011*5c6c1daeSBarry Smith EndPaint(hWnd, &ps); 1012*5c6c1daeSBarry Smith ReleaseMutex(g_hWindowListMutex); 1013*5c6c1daeSBarry Smith PetscFunctionReturnVoid(); 1014*5c6c1daeSBarry Smith } 1015*5c6c1daeSBarry Smith 1016*5c6c1daeSBarry Smith #undef __FUNCT__ 1017*5c6c1daeSBarry Smith #define __FUNCT__ "MouseRecord_Win32" 1018*5c6c1daeSBarry Smith static PetscErrorCode MouseRecord_Win32(HWND hWnd,PetscDrawButton button) 1019*5c6c1daeSBarry Smith { 1020*5c6c1daeSBarry Smith /* Called by all three mouse button actions 1021*5c6c1daeSBarry Smith Records needed mouse data in windows data structure */ 1022*5c6c1daeSBarry Smith WindowNode current = NULL; 1023*5c6c1daeSBarry Smith MouseNode newnode; 1024*5c6c1daeSBarry Smith POINT mousepos; 1025*5c6c1daeSBarry Smith PetscErrorCode ierr; 1026*5c6c1daeSBarry Smith 1027*5c6c1daeSBarry Smith PetscFunctionBegin; 1028*5c6c1daeSBarry Smith WaitForSingleObject(g_hWindowListMutex, INFINITE); 1029*5c6c1daeSBarry Smith current = WindowListHead; 1030*5c6c1daeSBarry Smith if (current->IsGetMouseOn == TRUE) { 1031*5c6c1daeSBarry Smith 1032*5c6c1daeSBarry Smith SetEvent(current->event); 1033*5c6c1daeSBarry Smith while (current != NULL) { 1034*5c6c1daeSBarry Smith if (current->hWnd == hWnd) { 1035*5c6c1daeSBarry Smith 1036*5c6c1daeSBarry Smith ierr = PetscNew(struct _p_MouseNode,&newnode);CHKERRQ(ierr); 1037*5c6c1daeSBarry Smith newnode->Button = button; 1038*5c6c1daeSBarry Smith GetCursorPos(&mousepos); 1039*5c6c1daeSBarry Smith newnode->user.x = mousepos.x; 1040*5c6c1daeSBarry Smith newnode->user.y = mousepos.y; 1041*5c6c1daeSBarry Smith ScreenToClient(hWnd,&mousepos); 1042*5c6c1daeSBarry Smith newnode->phys.x = mousepos.x; 1043*5c6c1daeSBarry Smith newnode->phys.y = mousepos.y; 1044*5c6c1daeSBarry Smith if (!current->MouseListTail) { 1045*5c6c1daeSBarry Smith current->MouseListHead = newnode; 1046*5c6c1daeSBarry Smith current->MouseListTail = newnode; 1047*5c6c1daeSBarry Smith } else { 1048*5c6c1daeSBarry Smith current->MouseListTail->mnext = newnode; 1049*5c6c1daeSBarry Smith current->MouseListTail = newnode; 1050*5c6c1daeSBarry Smith } 1051*5c6c1daeSBarry Smith newnode->mnext = NULL; 1052*5c6c1daeSBarry Smith 1053*5c6c1daeSBarry Smith break; 1054*5c6c1daeSBarry Smith } 1055*5c6c1daeSBarry Smith current = current->wnext; 1056*5c6c1daeSBarry Smith } 1057*5c6c1daeSBarry Smith } 1058*5c6c1daeSBarry Smith ReleaseMutex(g_hWindowListMutex); 1059*5c6c1daeSBarry Smith PetscFunctionReturn(0); 1060*5c6c1daeSBarry Smith } 1061*5c6c1daeSBarry Smith 1062*5c6c1daeSBarry Smith #undef __FUNCT__ 1063*5c6c1daeSBarry Smith #define __FUNCT__ "OnDestroy_Win32" 1064*5c6c1daeSBarry Smith static void OnDestroy_Win32(HWND hWnd) 1065*5c6c1daeSBarry Smith { 1066*5c6c1daeSBarry Smith /* searches linked list of window data and frees corresponding memory */ 1067*5c6c1daeSBarry Smith WindowNode current; 1068*5c6c1daeSBarry Smith 1069*5c6c1daeSBarry Smith PetscFunctionBegin; 1070*5c6c1daeSBarry Smith WaitForSingleObject(g_hWindowListMutex, INFINITE); 1071*5c6c1daeSBarry Smith current = WindowListHead; 1072*5c6c1daeSBarry Smith 1073*5c6c1daeSBarry Smith SetEvent(current->event); 1074*5c6c1daeSBarry Smith while (current != NULL) { 1075*5c6c1daeSBarry Smith if (current->hWnd == hWnd) { 1076*5c6c1daeSBarry Smith if (current->wprev != NULL) { 1077*5c6c1daeSBarry Smith current->wprev->wnext = current->wnext; 1078*5c6c1daeSBarry Smith } else { 1079*5c6c1daeSBarry Smith WindowListHead = current->wnext; 1080*5c6c1daeSBarry Smith } 1081*5c6c1daeSBarry Smith if (current->MouseListHead) { 1082*5c6c1daeSBarry Smith deletemouselist_Win32(current); 1083*5c6c1daeSBarry Smith } else { 1084*5c6c1daeSBarry Smith PetscFree(current); 1085*5c6c1daeSBarry Smith } 1086*5c6c1daeSBarry Smith break; 1087*5c6c1daeSBarry Smith } 1088*5c6c1daeSBarry Smith current = current->wnext; 1089*5c6c1daeSBarry Smith } 1090*5c6c1daeSBarry Smith ReleaseMutex(g_hWindowListMutex); 1091*5c6c1daeSBarry Smith PostQuitMessage(0); 1092*5c6c1daeSBarry Smith PetscFunctionReturnVoid(); 1093*5c6c1daeSBarry Smith } 1094