Moving some Windows-specific "freeglut_init.c" helper functions into their own file
[freeglut] / src / mswin / freeglut_init_mswin.c
1 /*\r
2  * freeglut_cursor_mswin.c\r
3  *\r
4  * The Windows-specific mouse cursor related stuff.\r
5  *\r
6  * Copyright (c) 2012 Stephen J. Baker. All Rights Reserved.\r
7  * Written by John F. Fay, <fayjf@sourceforge.net>\r
8  * Creation date: Thu Jan 19, 2012\r
9  *\r
10  * Permission is hereby granted, free of charge, to any person obtaining a\r
11  * copy of this software and associated documentation files (the "Software"),\r
12  * to deal in the Software without restriction, including without limitation\r
13  * the rights to use, copy, modify, merge, publish, distribute, sublicense,\r
14  * and/or sell copies of the Software, and to permit persons to whom the\r
15  * Software is furnished to do so, subject to the following conditions:\r
16  *\r
17  * The above copyright notice and this permission notice shall be included\r
18  * in all copies or substantial portions of the Software.\r
19  *\r
20  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS\r
21  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
22  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL\r
23  * PAWEL W. OLSZTA BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\r
24  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
25  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
26  */\r
27 \r
28 #include <GL/freeglut.h>\r
29 #include "freeglut_internal_mswin.h"\r
30 \r
31 \r
32 /*\r
33  * A call to this function should initialize all the display stuff...\r
34  */\r
35 void fghInitialize( const char* displayName )\r
36 {\r
37     WNDCLASS wc;\r
38     ATOM atom;\r
39 \r
40     /* What we need to do is to initialize the fgDisplay global structure here. */\r
41     fgDisplay.Instance = GetModuleHandle( NULL );\r
42     fgDisplay.DisplayName= displayName ? strdup(displayName) : 0 ;\r
43     atom = GetClassInfo( fgDisplay.Instance, _T("FREEGLUT"), &wc );\r
44 \r
45     if( atom == 0 )\r
46     {\r
47         ZeroMemory( &wc, sizeof(WNDCLASS) );\r
48 \r
49         /*\r
50          * Each of the windows should have its own device context, and we\r
51          * want redraw events during Vertical and Horizontal Resizes by\r
52          * the user.\r
53          *\r
54          * XXX Old code had "| CS_DBCLCKS" commented out.  Plans for the\r
55          * XXX future?  Dead-end idea?\r
56          */\r
57         wc.lpfnWndProc    = fgWindowProc;\r
58         wc.cbClsExtra     = 0;\r
59         wc.cbWndExtra     = 0;\r
60         wc.hInstance      = fgDisplay.Instance;\r
61         wc.hIcon          = LoadIcon( fgDisplay.Instance, _T("GLUT_ICON") );\r
62 \r
63 #if defined(_WIN32_WCE)\r
64         wc.style          = CS_HREDRAW | CS_VREDRAW;\r
65 #else\r
66         wc.style          = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;\r
67         if (!wc.hIcon)\r
68           wc.hIcon        = LoadIcon( NULL, IDI_WINLOGO );\r
69 #endif\r
70 \r
71         wc.hCursor        = LoadCursor( NULL, IDC_ARROW );\r
72         wc.hbrBackground  = NULL;\r
73         wc.lpszMenuName   = NULL;\r
74         wc.lpszClassName  = _T("FREEGLUT");\r
75 \r
76         /* Register the window class */\r
77         atom = RegisterClass( &wc );\r
78         FREEGLUT_INTERNAL_ERROR_EXIT ( atom, "Window Class Not Registered", "fghInitialize" );\r
79     }\r
80 \r
81     /* The screen dimensions can be obtained via GetSystemMetrics() calls */\r
82     fgDisplay.ScreenWidth  = GetSystemMetrics( SM_CXSCREEN );\r
83     fgDisplay.ScreenHeight = GetSystemMetrics( SM_CYSCREEN );\r
84 \r
85     {\r
86         HWND desktop = GetDesktopWindow( );\r
87         HDC  context = GetDC( desktop );\r
88 \r
89         fgDisplay.ScreenWidthMM  = GetDeviceCaps( context, HORZSIZE );\r
90         fgDisplay.ScreenHeightMM = GetDeviceCaps( context, VERTSIZE );\r
91 \r
92         ReleaseDC( desktop, context );\r
93     }\r
94     /* If we have a DisplayName try to use it for metrics */\r
95     if( fgDisplay.DisplayName )\r
96     {\r
97         HDC context = CreateDC(fgDisplay.DisplayName,0,0,0);\r
98         if( context )\r
99         {\r
100             fgDisplay.ScreenWidth  = GetDeviceCaps( context, HORZRES );\r
101             fgDisplay.ScreenHeight = GetDeviceCaps( context, VERTRES );\r
102             fgDisplay.ScreenWidthMM  = GetDeviceCaps( context, HORZSIZE );\r
103             fgDisplay.ScreenHeightMM = GetDeviceCaps( context, VERTSIZE );\r
104             DeleteDC(context);\r
105         }\r
106         else\r
107             fgWarning("fghInitialize: "\r
108                       "CreateDC failed, Screen size info may be incorrect\n"\r
109           "This is quite likely caused by a bad '-display' parameter");\r
110       \r
111     }\r
112     /* Set the timer granularity to 1 ms */\r
113     timeBeginPeriod ( 1 );\r
114 \r
115 \r
116     fgState.Initialised = GL_TRUE;\r
117 \r
118     /* Avoid registering atexit callback on Win32 as it results in an access\r
119      * violation due to calling into a module which has been unloaded.\r
120      * Any cleanup isn't needed on Windows anyway, the OS takes care of it.c\r
121      * see: http://blogs.msdn.com/b/oldnewthing/archive/2012/01/05/10253268.aspx\r
122      */\r
123 /*    atexit(fgDeinitialize); */\r
124 \r
125     /* InputDevice uses GlutTimerFunc(), so fgState.Initialised must be TRUE */\r
126     fgInitialiseInputDevices();\r
127 }\r
128 \r
129 \r
130 \r
131 /* Platform-Specific Deinitialization Functions: */\r
132 void fghDeinitialiseInputDevices ( void )\r
133 {\r
134 #if !defined(_WIN32_WCE)\r
135     if ( fgState.JoysticksInitialised )\r
136         fgJoystickClose( );\r
137 \r
138     if ( fgState.InputDevsInitialised )\r
139         fgInputDeviceClose( );\r
140 #endif /* !defined(_WIN32_WCE) */\r
141     fgState.JoysticksInitialised = GL_FALSE;\r
142     fgState.InputDevsInitialised = GL_FALSE;\r
143 }\r
144 \r
145 void fghCloseDisplay ( void )\r
146 {\r
147     if( fgDisplay.DisplayName )\r
148     {\r
149         free( fgDisplay.DisplayName );\r
150         fgDisplay.DisplayName = NULL;\r
151     }\r
152 \r
153     /* Reset the timer granularity */\r
154     timeEndPeriod ( 1 );\r
155 }\r
156 \r
157 \r
158 \r
159 \r
160 \r