capture feature
[censuslogo] / src / main_w32.c
1 #include <stdio.h>
2 #include <windows.h>
3 #include "app.h"
4
5 static int create_glwin(int xsz, int ysz);
6 static void destroy_glwin(void);
7 static long CALLBACK handle_events(HWND win, unsigned int msg, WPARAM wparam, LPARAM lparam);
8
9 static HWND win;
10 static HDC dc;
11 static HGLRC ctx;
12 static int quit;
13 static long start_time;
14
15
16 int WINAPI WinMain(HINSTANCE pid, HINSTANCE prevpid, char *cmdline, int showcmd)
17 {
18         if(memcmp(cmdline, "-c", 2) == 0) {
19                 return 0;
20         }
21         if(memcmp(cmdline, "-s", 2) == 0) {
22                 fullscr = 1;
23         }
24
25         if(create_glwin(1280, 800) == -1) {
26                 return 1;
27         }
28
29         if(app_init() == -1) {
30                 return 1;
31         }
32         start_time = timeGetTime();
33
34         while(!quit) {
35                 MSG ev;
36                 while(PeekMessage(&ev, 0, 0, 0, PM_REMOVE)) {
37                         if(ev.message == WM_QUIT) {
38                                 goto done;
39                         }
40                         TranslateMessage(&ev);
41                         DispatchMessage(&ev);
42                 }
43                 if(quit) goto done;
44
45                 msec = timeGetTime() - start_time;
46                 app_display();
47                 SwapBuffers(dc);
48         }
49
50 done:
51         destroy_glwin();
52         return 0;
53 }
54
55 void app_quit(void)
56 {
57         quit = 1;
58 }
59
60 void app_fullscreen(void)
61 {
62 }
63
64 void app_windowed(void)
65 {
66 }
67
68
69 static int create_glwin(int xsz, int ysz)
70 {
71         int x, y, win_xsz, win_ysz, pix_fmt;
72         unsigned int style;
73         HINSTANCE pid;
74         WNDCLASSEX wc;
75         PIXELFORMATDESCRIPTOR pfd;
76         RECT rect;
77
78         pid = GetModuleHandle(0);
79
80         memset(&wc, 0, sizeof wc);
81         wc.cbSize = sizeof wc;
82         wc.hbrBackground = (HBRUSH)GetStockObject(NULL_BRUSH);
83         wc.hCursor = LoadCursor(0, IDC_ARROW);
84         wc.hIcon = wc.hIconSm = LoadIcon(0, IDI_APPLICATION);
85         wc.hInstance = pid;
86         wc.lpfnWndProc = (WNDPROC)handle_events;
87         wc.lpszClassName = "census";
88         wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
89         RegisterClassEx(&wc);
90
91         if(fullscr) {
92                 x = y = 0;
93                 win_xsz = xsz = GetSystemMetrics(SM_CXSCREEN);
94                 win_ysz = ysz = GetSystemMetrics(SM_CYSCREEN);
95
96                 style = WS_POPUP;
97         } else {
98                 x = y = CW_USEDEFAULT;
99                 style = WS_OVERLAPPEDWINDOW;
100
101                 rect.left = rect.top = 0;
102                 rect.right = xsz;
103                 rect.bottom = ysz;
104                 AdjustWindowRect(&rect, style, 0);
105
106                 win_xsz = rect.right - rect.left;
107                 win_ysz = rect.bottom - rect.top;
108         }
109
110         printf("creating window: %dx%d\n", xsz, ysz);
111         win = CreateWindow("census", "census", style, x, y, win_xsz, win_ysz, 0, 0, pid, 0);
112         dc = GetDC(win);
113
114         memset(&pfd, 0, sizeof pfd);
115         pfd.nSize = sizeof pfd;
116         pfd.nVersion = 1;
117         pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER | PFD_DRAW_TO_WINDOW;
118         pfd.iPixelType = PFD_TYPE_RGBA;
119         pfd.cColorBits = 24;
120         pfd.cDepthBits = 24;
121         pfd.iLayerType = PFD_MAIN_PLANE;
122
123         if(!(pix_fmt = ChoosePixelFormat(dc, &pfd)) || !SetPixelFormat(dc, pix_fmt, &pfd)) {
124                 fprintf(stderr, "Failed to get suitable pixel format\n");
125                 ReleaseDC(win, dc);
126                 DestroyWindow(win);
127                 UnregisterClass("census", pid);
128                 return -1;
129         }
130
131         if(!(ctx = wglCreateContext(dc))) {
132                 fprintf(stderr, "Failed to create WGL context\n");
133                 ReleaseDC(win, dc);
134                 DestroyWindow(win);
135                 UnregisterClass("census", pid);
136                 return -1;
137         }
138         wglMakeCurrent(dc, ctx);
139
140         ShowWindow(win, SW_SHOW);
141         UpdateWindow(win);
142         SetFocus(win);
143
144         app_reshape(xsz, ysz);
145         win_width = xsz;
146         win_height = ysz;
147         return 0;
148 }
149
150 static void destroy_glwin(void)
151 {
152         wglMakeCurrent(0, 0);
153         wglDeleteContext(ctx);
154         ReleaseDC(win, dc);
155         DestroyWindow(win);
156         UnregisterClass("census", GetModuleHandle(0));
157 }
158
159 static long CALLBACK handle_events(HWND win, unsigned int msg, WPARAM wparam, LPARAM lparam)
160 {
161         static int window_mapped;
162
163         switch(msg) {
164         case WM_SHOWWINDOW:
165                 window_mapped = wparam;
166                 break;
167
168         case WM_PAINT:
169                 if(window_mapped) {
170                         ValidateRect(win, 0);
171                 }
172                 break;
173
174         case WM_DESTROY:
175                 PostQuitMessage(0);
176                 quit = 1;
177                 break;
178
179         case WM_KEYDOWN:
180                 app_keyboard(wparam, 1);
181                 break;
182
183         case WM_ACTIVATE:
184                 if(!wparam) {
185                         PostQuitMessage(0);
186                         quit = 1;
187                 }
188                 break;
189
190         case WM_SYSCOMMAND:
191                 if(wparam == SC_SCREENSAVE) {
192                         break;
193                 }
194
195         default:
196                 return DefWindowProc(win, msg, wparam, lparam);
197         }
198         return 0;
199 }
200
201 int WINAPI RegisterDialogClasses(HINSTANCE pid)
202 {
203         return TRUE;
204 }