78b8760051846e7d49551b250cd93eec93fd7c19
[jabaws.git] / binaries / src / ViennaRNA / RNAforester / g2-0.70 / src / Win32 / g2_win32.c
1 /*****************************************************************************
2 **  Copyright (C) 1998-2001  Ljubomir Milanovic & Horst Wagner
3 **  This file is part of the g2 library
4 **
5 **  This library is free software; you can redistribute it and/or
6 **  modify it under the terms of the GNU Lesser General Public
7 **  License as published by the Free Software Foundation; either
8 **  version 2.1 of the License, or (at your option) any later version.
9 **
10 **  This library is distributed in the hope that it will be useful,
11 **  but WITHOUT ANY WARRANTY; without even the implied warranty of
12 **  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 **  Lesser General Public License for more details.
14 **
15 **  You should have received a copy of the GNU Lesser General Public
16 **  License along with this library; if not, write to the Free Software
17 **  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18 ******************************************************************************/
19
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <math.h>
23
24 #include "g2.h"
25 #include "g2_device.h"
26 #include "g2_util.h"
27 #include "g2_config.h"
28
29 #include "g2_win32.h"
30 #include "g2_win32_P.h"
31 #include "g2_win32_funix.h"
32
33 #include "resource.h"
34
35 /* Global Definitions */
36 int g2_win32_registered = FALSE;
37 HINSTANCE g2res_DLL;    /* Instance of the resource DLL */
38
39 #define PDP ((struct g2_win32_STRUCT *)pdp)
40
41 #ifndef PI
42 #define PI 3.14159265358979323846
43 #endif /* PI */
44
45 #define sgn(x) (x>0?1:x?-1:0)
46
47 /* someday their might be a DLL version of g2 */
48 #ifdef G2DLL
49 BOOL WINAPI DllMain( HANDLE hModule, DWORD fdwreason,  LPVOID lpReserved )
50 {
51     switch(fdwreason) {
52     case DLL_PROCESS_ATTACH:
53     // The DLL is being mapped into process's address space
54     //  Do any required initialization on a per application basis, return FALSE if failed
55     MessageBox(NULL, "DLL Process Attach", "DLL Message 1", MB_OK);    
56         break;
57     case DLL_THREAD_ATTACH:
58     // A thread is created. Do any required initialization on a per thread basis
59     MessageBox(NULL, "DLL Thread Attach", "DLL Message 1", MB_OK);    
60     break;
61     case DLL_THREAD_DETACH:
62     // Thread exits with  cleanup
63     MessageBox(NULL, "DLL Thread Detach", "DLL Message 1", MB_OK);    
64     break;
65     case DLL_PROCESS_DETACH:
66     // The DLL unmapped from process's address space. Do necessary cleanup
67     MessageBox(NULL, "DLL Process Detach", "DLL Message 1", MB_OK);    
68     break;
69         default:
70         MessageBox(NULL, "DLL default", "DLL Message 1", MB_OK);    
71
72     }
73     return TRUE;
74 }
75 #endif
76
77
78 g2_win32_SetPen(int pid, void *pdp)
79         {
80         HGDIOBJ oldpen;
81     LOGBRUSH    logBrush ;
82         logBrush.lbStyle = PS_SOLID;
83         logBrush.lbColor = PDP->Inks[PDP->Pen];
84     logBrush.lbHatch = 0 ;
85
86         oldpen = PDP->hPen;
87         PDP->hPen = ExtCreatePen (logBrush.lbStyle | PS_GEOMETRIC | 
88                          PS_ENDCAP_FLAT | PS_JOIN_BEVEL | (PDP->PenStyle > 0)*PS_USERSTYLE,
89                          PDP->PenWidth, &logBrush,
90                          PDP->PenStyle , PDP->PenDash) ;
91         if (PDP->hPen != NULL) 
92                 {
93                 SelectObject(PDP->hMemDC,PDP->hPen);
94 /*              if (PDP->type == g2_win32)*/
95                 DeleteObject(oldpen);
96                 }
97         else
98                 {
99                 errhandler("Pen",NULL);
100                 PDP->hPen = oldpen;
101                 }
102
103         oldpen = PDP->hNullPen;
104         PDP->hNullPen = CreatePen(PS_SOLID,1,PDP->Inks[PDP->Pen]);
105         if (PDP->hNullPen != NULL) 
106                 {
107 /*              if (PDP->type == g2_win32)*/
108                 DeleteObject(oldpen);
109                 }
110         else
111                 {
112                 errhandler("Pen",NULL);
113                 PDP->hNullPen = oldpen;
114                 }
115
116         return 0;
117         }
118
119
120 int g2_win32_Cleanup(int pid, void *pdp)
121         {
122         struct g2_win32_STRUCT *thispdp;
123
124         thispdp = pdp;
125         g2_win32_ClearPalette(pid,pdp);
126         if (PDP->hBrush != NULL) DeleteObject(PDP->hBrush);
127         if (PDP->hPen != NULL) DeleteObject(PDP->hPen);
128         if (PDP->hNullPen != NULL) DeleteObject(PDP->hPen);
129         if (PDP->hFont != NULL) DeleteObject(PDP->hFont);
130         if (PDP->hBitmap != NULL) DeleteObject(PDP->hBitmap);
131         if (PDP->hMemDC != NULL) DeleteDC(PDP->hMemDC);
132         if (PDP->PenDash != NULL) free(PDP->PenDash);
133         free(thispdp);
134         return 0;
135         }
136
137
138
139 int g2_win32_Delete(int pid, void *pdp)
140         {
141         switch(PDP->type)
142                 {
143                 case g2_win32:
144                         SendMessage(PDP->hwndThreadWindow,WM_CLOSE,(WPARAM)NULL,(LPARAM)NULL);
145                         break;
146                 case g2_wmf32:
147                         {
148                         CloseEnhMetaFile(PDP->hMemDC);
149                         g2_win32_Cleanup(pid,pdp);
150                         break;
151                         }
152                 }
153         return 0;
154     }
155
156
157 int g2_win32_Clear(int pid, void *pdp)
158         {
159         int OldPen;
160
161         OldPen = PDP->Pen;
162         g2_win32_Pen(pid,pdp,PDP->BkColor);
163         g2_win32_FilledRectangle(pid,pdp,0,0,PDP->nWidth,PDP->nHeight);
164         g2_win32_Pen(pid,pdp,OldPen);
165         return 0;
166     }
167
168 int g2_win32_Flush(int pid, void *pdp)
169         {
170         InvalidateRect(PDP->hwndThreadWindow, (RECT *)NULL, TRUE); 
171         return 0;
172     }
173
174 int g2_win32_Pen(int pid, void *pdp, int color)
175         {
176         struct tagLOGBRUSH logbrush;
177         HGDIOBJ oldbrush;
178         
179         if(color>=PDP->NoOfInks || color<0)
180                 {
181                 fprintf(stderr,"g2_WIN32: Ink %d not defined\n",color);
182                 return -1;
183                 }
184
185         PDP->Pen = color;
186         PDP->PenColor = PDP->Inks[color];
187         g2_win32_SetPen(pid,pdp);
188
189         logbrush.lbStyle = BS_SOLID;
190         logbrush.lbColor = PDP->PenColor;
191         oldbrush = PDP->hBrush;
192         PDP->hBrush = CreateBrushIndirect(&logbrush);
193         if (PDP->hBrush == NULL) 
194                 {
195                 errhandler("Pen (CreateBrush)",NULL);
196                 PDP->hBrush = oldbrush;
197                 }
198         else
199 /*              if (PDP->type == g2_win32)*/
200                 DeleteObject(oldbrush);
201         return 0;
202     }
203
204 int g2_win32_Ink(int pid, void *pdp, double red, double green, double blue)
205         {
206         BYTE rc,gc,bc;
207
208         rc = (BYTE)((int)(red*255));
209         gc = (BYTE)((int)(green*255));
210         bc = (BYTE)((int)(blue*255));
211
212         PDP->NoOfInks++;
213
214         if(PDP->Inks==NULL)
215                 PDP->Inks=(COLORREF *)malloc(PDP->NoOfInks*sizeof(COLORREF));
216         else
217                 PDP->Inks=(COLORREF *)realloc((void *)PDP->Inks,PDP->NoOfInks*sizeof(COLORREF));
218
219         if(PDP->Inks==NULL) 
220                 {
221                 fputs("g2: not enough memory\n",stderr);
222                 return -1;
223                 }
224
225         PDP->Inks[PDP->NoOfInks-1]=RGB(rc,gc,bc);
226         return PDP->NoOfInks-1;
227         }       
228
229
230 int g2_win32_ClearPalette(int pid, void *pdp)
231         {
232         if (PDP->Inks != NULL)
233                 free(PDP->Inks);
234         PDP->Inks = NULL;
235         PDP->NoOfInks = 0;
236         return 0;
237     }
238
239
240 int g2_win32_SetBackground(int pid, void *pdp, int color)
241         {
242         PDP->BkColor = color;
243         SetBkColor(PDP->hMemDC,PDP->BkColor);
244         return 0;
245     }
246
247 int g2_win32_SetLineWidth(int pid, void *pdp, int w)
248         {
249         PDP->PenWidth = w;
250         g2_win32_SetPen(pid,pdp);
251         return 0;
252     }
253
254 int g2_win32_SetDash(int pid, void *pdp, int n, int *data)
255         {
256         if (PDP->PenDash != NULL)
257                 free(PDP->PenDash);
258         PDP->PenDash = NULL;
259         PDP->PenStyle = n;
260         if (n > 0) 
261                 {
262                 int i;
263                 PDP->PenDash = (DWORD *)malloc(n*sizeof(DWORD));
264                 for (i=0;i<n;i++)
265                         PDP->PenDash[i] = data[i];
266                 }
267         g2_win32_SetPen(pid,pdp);
268         return 0;
269         }
270
271
272 int g2_win32_SetFontSize(int pid, void *pdp, int size)
273         {
274         //static LOGFONT lf = {10,0,0,0,0,0,0,0,0,0,0,0,0,"Arial\0"};
275     HGDIOBJ oldfont;
276    
277         oldfont = PDP->hFont;
278         //lf.lfHeight = size;
279         //PDP->hFont = CreateFontIndirect(&lf);
280         PDP->hFont = CreateFont(-size, 0, 0, 0, FW_NORMAL, 0, 0, 0, 0, OUT_TT_ONLY_PRECIS , 0, PROOF_QUALITY,0, "Times New Roman\0");
281         if (PDP->hFont == NULL) 
282                 {
283                 errhandler("Font (CreateFont)",NULL);
284                 PDP->hFont = oldfont;
285                 }
286         else
287                 {
288                 SelectObject(PDP->hMemDC,PDP->hFont);
289                 if (oldfont != NULL)// && PDP->type == g2_win32)
290                         DeleteObject(oldfont);
291                 }
292         return 0;
293     }
294
295 int g2_win32_Plot(int pid, void *pdp, int x, int y)
296         {
297         return SetPixel(PDP->hMemDC,x,y,PDP->PenColor);
298     }
299
300 int g2_win32_Line(int pid, void *pdp, int x1, int y1, int x2, int y2)
301         {
302         MoveToEx(PDP->hMemDC,x1,y1,NULL);
303         LineTo(PDP->hMemDC,x2,y2);
304         SetPixel(PDP->hMemDC,x1,y1,PDP->PenColor);
305         SetPixel(PDP->hMemDC,x2,y2,PDP->PenColor);
306         // specifically draw end points since windows does not include one endpoint
307         return 0;
308     }
309
310 int g2_win32_PolyLine(int pid, void *pdp, int N, int *points)
311         {
312         POINT *PointList;
313         int i;
314
315         PointList = (POINT *)malloc(N*sizeof(POINT));
316         if (PointList == NULL)
317                 {
318                 fprintf(stderr,"g2_win32: not enough memory !\n");
319                 return -1;
320                 }
321         for (i=0;i<N;i++)
322                 {
323                 PointList[i].x = points[2*i];
324                 PointList[i].y = points[2*i+1];
325                 }
326         Polyline(PDP->hMemDC,PointList,N);
327         free(PointList);
328         return 0;
329     }
330
331
332
333 int g2_win32_Rectangle(int pid, void *pdp, int x, int y, int x2, int y2)
334         {
335         SelectObject(PDP->hMemDC,GetStockObject(NULL_BRUSH));
336         Rectangle(PDP->hMemDC,x,y,x2+1,y2+1); // add one since windows excludes lower right point
337         return 0;
338     }
339
340 int g2_win32_FilledRectangle(int pid, void *pdp, int x1, int y1, int x2, int y2)
341         {
342         SelectObject(PDP->hMemDC,PDP->hBrush);
343         SelectObject(PDP->hMemDC,PDP->hNullPen);
344         return Rectangle(PDP->hMemDC,x1,y1,x2+1,y2+1); // add one since windows excludes lower right point
345         SelectObject(PDP->hMemDC,PDP->hPen);
346         return 0;
347         }
348
349 int g2_win32_Polygon(int pid, void *pdp, int N, int *points)
350         {
351         POINT *PointList;
352         int i;
353         PointList = (POINT *)malloc(N*sizeof(POINT));
354         if (PointList == NULL)
355                 {
356                 fprintf(stderr,"g2: not enough memory !\n");
357                 return -1;
358                 }
359         for (i=0;i<N;i++)
360                 {
361                 PointList[i].x = points[2*i];
362                 PointList[i].y = points[2*i+1];
363                 }
364         SelectObject(PDP->hMemDC,GetStockObject(NULL_BRUSH));
365         Polygon(PDP->hMemDC,PointList,N);
366         free(PointList);
367         return 0;
368     }
369
370 int g2_win32_FilledPolygon(int pid, void *pdp, int N, int *points)
371         {
372         POINT *PointList;
373         int i;
374         PointList = (POINT *)malloc(N*sizeof(POINT));
375         if (PointList == NULL)
376                 {
377                 fprintf(stderr,"g2: not enough memory !\n");
378                 return -1;
379                 }
380         for (i=0;i<N;i++)
381                 {
382                 PointList[i].x = points[2*i];
383                 PointList[i].y = points[2*i+1];
384                 }
385         SelectObject(PDP->hMemDC,PDP->hBrush);
386         SelectObject(PDP->hMemDC,PDP->hNullPen);
387         Polygon(PDP->hMemDC,PointList,N);
388         SelectObject(PDP->hMemDC,PDP->hPen);
389         free(PointList);
390         return 0;
391     }
392
393 int g2_win32_Ellipse(int pid, void *pdp, int x, int y, int r1, int r2)
394         {
395         SelectObject(PDP->hMemDC,GetStockObject(NULL_BRUSH));
396         return Ellipse(PDP->hMemDC,x-r1,y-r2,x+r1+1,y+r2+1); // add one since windows is end exclusive
397     }
398
399 int g2_win32_FilledEllipse(int pid, void *pdp, int x, int y, int r1, int r2)
400         {
401         SelectObject(PDP->hMemDC,PDP->hBrush);
402         SelectObject(PDP->hMemDC,PDP->hNullPen);
403         return Ellipse(PDP->hMemDC,x-r1,y-r2,x+r1+1,y+r2+1); // add one since windows is end exclusive
404         SelectObject(PDP->hMemDC,PDP->hPen);
405         return 0;
406     }
407
408 int g2_win32_Arc(int pid, void *pdp, int x, int y, int r1, int r2, double a1, double a2)
409         {
410         a1 *= PI/180.;
411         a2 *= PI/180.;
412         SelectObject(PDP->hMemDC,GetStockObject(NULL_BRUSH));
413         if (PDP->type == g2_win32)
414                 return Arc(PDP->hMemDC,x-r1,y-r2,x+r1,y+r2,dtoi(x+r1*cos(a1)),dtoi(y-r2*sin(a1)),dtoi(x+r1*cos(a2)),dtoi(y-r2*sin(a2)));
415         else
416                 return Arc(PDP->hMemDC,x-r1,y-r2,x+r1,y+r2,dtoi(x+r1*cos(a2)),dtoi(y-r2*sin(a2)),dtoi(x+r1*cos(a1)),dtoi(y-r2*sin(a1)));
417     }
418
419 int g2_win32_FilledArc(int pid, void *pdp, int x, int y, int r1, int r2, double a1, double a2)
420         {
421         a1 *= PI/180.;
422         a2 *= PI/180.;
423         SelectObject(PDP->hMemDC,PDP->hBrush);
424         SelectObject(PDP->hMemDC,PDP->hNullPen);
425         if (PDP->type == g2_win32)
426                 Pie(PDP->hMemDC,x-r1,y-r2,x+r1,y+r2,dtoi(x+r1*cos(a1)),dtoi(y-r2*sin(a1)),dtoi(x+r1*cos(a2)),dtoi(y-r2*sin(a2)));
427         else
428                 Pie(PDP->hMemDC,x-r1,y-r2,x+r1,y+r2,dtoi(x+r1*cos(a2)),dtoi(y-r2*sin(a2)),dtoi(x+r1*cos(a1)),dtoi(y-r2*sin(a1)));
429         SelectObject(PDP->hMemDC,PDP->hPen);
430         return 0;
431     }
432
433 int g2_win32_DrawString(int pid, void *pdp, int x, int y, const char *text)
434         {
435         SetTextColor(PDP->hMemDC,PDP->PenColor);
436         SetBkMode(PDP->hMemDC,TRANSPARENT);
437         return TextOut(PDP->hMemDC,x,y,text,strlen(text));
438     }
439
440 int g2_win32_QueryPointer(int pid, void *pdp, int *x, int *y, unsigned int *button)
441 //
442 // Thanks to input by Martin stéphane
443 //
444         { 
445         POINT point;
446
447         GetCursorPos(&point);
448
449         ScreenToClient(PDP->hwndThreadWindow,&point);
450
451         *y=point.y;
452         *x=point.x;
453         *button=0;
454
455         if (PDP->hwndThreadWindow != GetForegroundWindow())
456                 return; // return if our window does not have the focus
457
458         if (GetKeyState(VK_LBUTTON)<0) 
459                 *button=*button+256;
460
461         if (GetKeyState(VK_MBUTTON)<0) 
462                 *button=*button+512;
463
464         if (GetKeyState(VK_RBUTTON)<0) 
465                 *button=*button+1024;
466
467         return 0;
468         }
469
470 void errhandler(LPSTR errtxt,HWND hwnd)
471 {
472         LPVOID lpMessageBuffer;
473         char szError[255];
474         DWORD LastError;
475
476         LastError = GetLastError();
477
478         FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |FORMAT_MESSAGE_FROM_SYSTEM,
479         NULL,LastError,MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), //The user default language
480         (LPTSTR) &lpMessageBuffer,0,NULL );
481
482         sprintf(szError,"Error in %s\n Error code %d : %s\n" ,errtxt,LastError,lpMessageBuffer);
483         MessageBox(hwnd,szError,"error",MB_OK);
484
485         LocalFree( lpMessageBuffer );
486 }
487
488
489 int InitApplication()
490 {
491   WNDCLASS  wc;
492
493   // Fill in window class structure with parameters that describe the
494   // main window.
495
496     g2res_DLL = LoadLibrary("g2res.dll");
497
498   if (g2res_DLL == NULL) 
499                 printf("Warning: Could not load g2 resource DLL\n Menu and Icon are disabled\n");
500   
501
502   wc.style = CS_HREDRAW | CS_VREDRAW; // Class style(s).
503   wc.lpfnWndProc = g2_WndProc; // Function to retrieve messages for windows of this class.
504   wc.cbClsExtra = 0;    // No per-class extra data.
505   wc.cbWndExtra = 0;    // No per-window extra data.
506   wc.hInstance = 0;             // Application that owns the class.
507   wc.hIcon = NULL;
508   if (g2res_DLL != NULL)
509           {
510                 wc.hIcon = LoadIcon(g2res_DLL, MAKEINTRESOURCE(IDI_ICON1));
511                 if (wc.hIcon == NULL) 
512                         errhandler("Error in LoadIcon",NULL);
513           }
514   wc.hCursor = LoadCursor(NULL, IDC_ARROW);
515   wc.hbrBackground = NULL;
516   wc.lpszMenuName = "G2WIN32";  
517   wc.lpszClassName = "g2Window";        // Name used in call to CreateWindow.
518
519   /* Register the window class and return success/failure code. */
520
521
522         if(!RegisterClass(&wc)) 
523           {
524           errhandler("RegisterClass",NULL);
525           return FALSE;
526           }
527   g2_win32_registered = TRUE;
528   return TRUE;
529 }
530
531
532 /**
533  * \ingroup physdev
534  * \defgroup win32 MS Windows
535  */
536
537 /**
538  *
539  * Create a Windows device.
540  *
541  * \param width window width
542  * \param height window height
543  * \param title window title
544  * \param type window type, see ::g2_win32_type
545  *
546  * \return physical device id
547  *
548  * \ingroup win32
549  */
550 int  g2_open_win32(int width, int height, const char *title, int type)
551         {
552         int pid=0,vid;
553         long ThreadID;
554
555         g2_win32_STRUCT *pdp;
556         
557         pdp = (g2_win32_STRUCT *)malloc(sizeof(g2_win32_STRUCT));
558
559         PDP->type = type;
560         PDP->NoOfInks = 0;
561         PDP->Inks = NULL;
562         PDP->PenStyle = 0;
563         PDP->PenWidth = 1;
564         PDP->PenColor = RGB(1,1,1);
565         PDP->PenDash = NULL;
566         PDP->nWidth = width;
567         PDP->nHeight = height;
568         PDP->messageloop = 0;
569         PDP->hFont = NULL;
570         
571         switch(type) {
572                 case g2_win32:
573                         {
574                         if(g2_win32_registered == FALSE)
575                                 InitApplication();
576                 
577                         PDP->x = 1;
578                         PDP->y = 1;
579                         if (title != NULL)
580                                 PDP->title = title;
581                         else
582                                 PDP->title = "g2 Window";
583                         PDP->hThread = CreateThread(NULL, 0,
584                                          (LPTHREAD_START_ROUTINE)g2_StartThread,
585                                          (LPVOID)(pdp),
586                                          0,
587                                                                          (LPDWORD) &ThreadID );
588
589                         if (PDP->hThread == NULL) 
590                                 fprintf(stderr,"g2_win32: Thread could not be started\n");
591
592                     SetThreadPriority(PDP->hThread,THREAD_PRIORITY_ABOVE_NORMAL);
593                         //Wait till window is created by Thread
594                         while( PDP->messageloop == 0)
595                                 Sleep(10);
596                         break;
597                         }
598                 case g2_wmf32 :
599                         {
600             DWORD dwInchesX;
601             DWORD dwInchesY;
602             DWORD dwDPI = 72;    
603                     RECT   Rect = { 0, 0, 0, 0 };
604                         TCHAR   szDesc[] = "Created by g2\0\0";
605                         HDC     hScreenDC;
606                         float   PixelsX, PixelsY, MMX, MMY;
607                         
608                         dwInchesX = PDP->nWidth/72;
609             dwInchesY = PDP->nHeight/72;
610                         // dwInchesX x dwInchesY in .01mm units
611                         SetRect( &Rect, 0, 0,dwInchesX*2540, dwInchesY*2540 );
612  
613                         // Get a Reference DC
614                         hScreenDC = GetDC( NULL );
615  
616                         // Get the physical characteristics of the reference DC
617                         PixelsX = (float)GetDeviceCaps( hScreenDC, HORZRES );
618                         PixelsY = (float)GetDeviceCaps( hScreenDC, VERTRES );
619                         MMX = (float)GetDeviceCaps( hScreenDC, HORZSIZE );
620                         MMY = (float)GetDeviceCaps( hScreenDC, VERTSIZE );
621  
622                         // Create the Metafile
623                     PDP->hMemDC = CreateEnhMetaFile(hScreenDC, title, &Rect, szDesc);
624                     //tstDC = CreateEnhMetaFile(hScreenDC, "test.emf", &Rect, szDesc);
625
626                         // Release the reference DC
627                         ReleaseDC( NULL, hScreenDC );
628                         // Anisotropic mapping mode
629                         SetMapMode( PDP->hMemDC, MM_ANISOTROPIC );
630                         // Set the Windows extent
631                         SetWindowExtEx( PDP->hMemDC, dwInchesX*dwDPI, dwInchesY*dwDPI, NULL );
632  
633                         // Set the viewport extent to reflect
634                         // dwInchesX" x dwInchesY" in device units
635                         SetViewportExtEx( PDP->hMemDC,
636                       (int)((float)dwInchesX*25.4f*PixelsX/MMX),
637                       (int)((float)dwInchesY*25.4f*PixelsY/MMY),
638                       NULL );
639 //                      printf("viewport: %d %d\n",(int)((float)dwInchesX*25.4f*PixelsX/MMX),
640 //                                                                              (int)((float)dwInchesY*25.4f*PixelsY/MMY));
641                         // create the device context
642 //                      PDP->hMemDC = CreateMetaFile(NULL) ;
643        
644 //                      PDP->hMemDC =  CreateEnhMetaFile( (HDC)NULL, title, &WmfRect, "Created by g2"); 
645 //                      PDP->hMemDC = CreateMetaFile(title);
646 //                      SetMapMode(PDP->hMemDC,MM_LOMETRIC );
647 //                      SetWindowExtEx(PDP->hMemDC,width,height,NULL);
648 //                      SetViewportExtEx(PDP->hMemDC,width*1000,height*1000,NULL);
649                         if (PDP->hMemDC == NULL) errhandler("Could not Create Metafile !\n",NULL);
650                         SetArcDirection(PDP->hMemDC,AD_CLOCKWISE);
651                         break;
652                         }
653                 default:
654                         return height;
655                 }
656                 SetTextAlign(PDP->hMemDC,TA_BOTTOM | TA_LEFT);
657                 vid = g2_register_physical_device(pid, pdp,
658                                       g2_IntCoor, g2_win32_funix,
659                                       1.0, -1.0,
660                                       0.0, height-1);
661
662                 g2_allocate_basic_colors(vid);
663                 g2_pen(vid,1);
664                 g2_set_background(vid, 0);
665                 g2_set_font_size(vid, 10);
666                 g2_clear(vid);
667
668     return vid;
669         }
670
671 #undef PDP