win32
authorJohn Tsiombikas <nuclear@member.fsf.org>
Sun, 1 Sep 2019 17:56:51 +0000 (20:56 +0300)
committerJohn Tsiombikas <nuclear@member.fsf.org>
Sun, 1 Sep 2019 17:56:51 +0000 (20:56 +0300)
Makefile
src/app.c [new file with mode: 0644]
src/app.h [new file with mode: 0644]
src/main.c [deleted file]
src/main_glut.c [new file with mode: 0644]
src/main_w32.c [new file with mode: 0644]

index f27fe85..3a89b00 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-src = $(wildcard src/*.c)
+src = $(src_main) $(filter-out $(wildcard src/main_*.c), $(wildcard src/*.c))
 obj = $(src:.c=.o)
 dep = $(obj:.o=.d)
 bin = censuslogo
@@ -6,15 +6,19 @@ bin = censuslogo
 sys ?= $(shell uname -s | sed 's/MINGW.*/mingw/')
 
 CFLAGS = -pedantic -Wall -g -DNOLOAD
-LDFLAGS = $(LDFLAGS_$(sys)) -lm
+LDFLAGS = $(ldflags_sys) -lm
 
-LDFLAGS_Linux = -lGL -lGLU -lglut
-LDFLAGS_mingw = -lmingw32 -mconsole -lfreeglut_static -lopengl32 -lglu32 -lgdi32 -lwinmm
 
 ifeq ($(sys), mingw)
+       src_main = src/main_w32.c
        obj = $(src:.c=.w32.o)
        bin = censuslogo.exe
        CFLAGS += -DFREEGLUT_STATIC
+
+       ldflags_sys = -lmingw32 -mconsole -lfreeglut_static -lopengl32 -lglu32 -lgdi32 -lwinmm
+else
+       src_main = src/main_glut.c
+       ldflags_sys = -lGL -lGLU -lglut
 endif
 
 $(bin): $(obj)
diff --git a/src/app.c b/src/app.c
new file mode 100644 (file)
index 0000000..8c4b6dd
--- /dev/null
+++ b/src/app.c
@@ -0,0 +1,199 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <GL/gl.h>
+#include "app.h"
+#include "logo.h"
+
+#ifndef GL_MULTISAMPLE
+#define GL_MULTISAMPLE 0x809d
+#endif
+
+int nverts = 256;
+int msaa = 1;
+int fullscr = 0;
+
+
+static void draw_disc(float x, float y, float rad, int sub);
+static void draw_line(float x0, float y0, float x1, float y1, float rad);
+static void print_usage(const char *argv0);
+
+int app_init(void)
+{
+       if(init_logo("data/census.curves") == -1) {
+               return -1;
+       }
+
+#ifdef MSAA
+       if(msaa) {
+               glEnable(GL_MULTISAMPLE);
+       }
+#endif
+
+       return 0;
+}
+
+#define LOOPTIME       1.45f
+
+void app_display(void)
+{
+       int i;
+       float t = (float)msec / 1000.0f;
+       float a[2], b[2], dt;
+       float anim, alpha;
+
+       glClear(GL_COLOR_BUFFER_BIT);
+
+       glLineWidth(5.0);
+
+       anim = fmod(t / 6.0f, LOOPTIME);
+       alpha = 1.0f - ((anim - (LOOPTIME - 0.075)) / 0.06f);
+       if(alpha < 0.0f) alpha = 0.0f;
+       if(alpha > 1.0f) alpha = 1.0f;
+
+       dt = (anim > 1.0f ? 1.0f : anim) / (float)(nverts - 1);
+
+       glColor4f(1, 1, 1, alpha);
+       for(i=0; i<nverts-1; i++) {
+               float t0 = (float)i * dt;
+               float t1 = (float)(i + 1) * dt;
+               eval_logo(a, t0);
+               eval_logo(b, t1);
+               draw_line(a[0], a[1], b[0], b[1], 0.02);
+       }
+
+       if(anim > 0.0f) {
+               eval_logo(a, 0);
+               draw_disc(a[0], a[1], 0.05, 22);
+       }
+       if(anim >= 1.0f) {
+               eval_logo(b, 1);
+               draw_disc(b[0], b[1], 0.05, 22);
+       }
+
+       glEnable(GL_BLEND);
+       glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+       glColor4f(0.8, 0, 0, 2.0 * (anim - 1.0f) / (LOOPTIME - 1.0f));
+       draw_disc(0, 0, 0.14, 30);
+
+       if(alpha < 1.0f) {
+               glBegin(GL_QUADS);
+               glColor4f(0, 0, 0, 1.0f - alpha);
+               glVertex2f(-1, -1);
+               glVertex2f(1, -1);
+               glVertex2f(1, 1);
+               glVertex2f(-1, 1);
+               glEnd();
+       }
+
+       glDisable(GL_BLEND);
+}
+
+static void draw_disc(float x, float y, float rad, int sub)
+{
+       int i;
+       glBegin(GL_TRIANGLE_FAN);
+       glVertex2f(x, y);
+       for(i=0; i<sub; i++) {
+               float t = (float)i / (float)(sub - 1);
+               float theta = t * M_PI * 2.0;
+               glVertex2f(cos(theta) * rad + x, sin(theta) * rad + y);
+       }
+       glEnd();
+}
+
+static void draw_line(float x0, float y0, float x1, float y1, float rad)
+{
+       float dx, dy, rx, ry, len;
+
+       dx = x1 - x0;
+       dy = y1 - y0;
+       len = sqrt(dx * dx + dy * dy);
+
+       rx = rad * dy / len;
+       ry = -rad * dx / len;
+
+       draw_disc(x0, y0, rad, 12);
+       draw_disc(x1, y1, rad, 12);
+
+       glBegin(GL_QUADS);
+       glVertex2f(x0 + rx, y0 + ry);
+       glVertex2f(x1 + rx, y1 + ry);
+       glVertex2f(x1 - rx, y1 - ry);
+       glVertex2f(x0 - rx, y0 - ry);
+       glEnd();
+}
+
+
+void app_reshape(int x, int y)
+{
+       float aspect = (float)x / (float)y;
+       glViewport(0, 0, x, y);
+       glMatrixMode(GL_PROJECTION);
+       glLoadIdentity();
+       glScalef(1.0f / aspect, 1.0f, 1.0f);
+}
+
+void app_keyboard(int key, int pressed)
+{
+       switch(key) {
+       case 27:
+               app_quit();
+
+       case '-':
+               nverts -= 8;
+               printf("nverts: %d\n", nverts);
+               break;
+
+       case '=':
+               nverts += 8;
+               printf("nverts: %d\n", nverts);
+               break;
+
+       case 'f':
+               fullscr = !fullscr;
+               if(fullscr) {
+                       app_fullscreen();
+               } else {
+                       app_windowed();
+               }
+               break;
+       }
+}
+
+
+int app_parse_args(int argc, char **argv)
+{
+       int i;
+
+       for(i=1; i<argc; i++) {
+               if(argv[i][0] == '-') {
+                       if(strcmp(argv[i], "-fs") == 0) {
+                               fullscr = 1;
+                       } else if(strcmp(argv[i], "-noaa") == 0) {
+                               msaa = 0;
+                       } else if(strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "-help") == 0) {
+                               print_usage(argv[0]);
+                               exit(0);
+                       } else {
+                               fprintf(stderr, "invalid option: %s\n", argv[i]);
+                               return -1;
+                       }
+               } else {
+                       fprintf(stderr, "unexpected argument: %s\n", argv[i]);
+                       return -1;
+               }
+       }
+       return 0;
+}
+
+static void print_usage(const char *argv0)
+{
+       printf("Usage: %s [options]\n", argv0);
+       printf("Options:\n");
+       printf(" -fs: fullscreen\n");
+       printf(" -noaa: disable anti-aliasing\n");
+       printf(" -h,-help: print usage and exit\n");
+}
diff --git a/src/app.h b/src/app.h
new file mode 100644 (file)
index 0000000..70f89ed
--- /dev/null
+++ b/src/app.h
@@ -0,0 +1,24 @@
+#ifndef APP_H_
+#define APP_H_
+
+/* undefine to build without anti-aliasing */
+#define MSAA
+
+int win_width, win_height;
+int nverts;
+int msaa;
+int fullscr;
+long msec;
+
+int app_init(void);
+void app_display(void);
+void app_reshape(int x, int y);
+void app_keyboard(int key, int pressed);
+int app_parse_args(int argc, char **argv);
+
+/* defined in main_*.c */
+void app_quit(void);
+void app_fullscreen(void);
+void app_windowed(void);
+
+#endif /* APP_H_ */
diff --git a/src/main.c b/src/main.c
deleted file mode 100644 (file)
index b5e1f5e..0000000
+++ /dev/null
@@ -1,263 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
-#include <assert.h>
-#include <GL/glut.h>
-#include "logo.h"
-
-#ifndef GL_MULTISAMPLE
-#define GL_MULTISAMPLE 0x809d
-#endif
-
-#define MSAA
-
-int init(void);
-void display(void);
-void idle(void);
-void reshape(int x, int y);
-void keyb(unsigned char key, int x, int y);
-int parse_args(int argc, char **argv);
-void print_usage(const char *argv0);
-
-int win_width, win_height;
-int nverts = 256;
-long start_time;
-int msaa = 1;
-int fullscr = 0;
-
-
-int main(int argc, char **argv)
-{
-       unsigned int flags = GLUT_RGB | GLUT_DOUBLE;
-
-       glutInit(&argc, argv);
-       if(parse_args(argc, argv) == -1) {
-               return 1;
-       }
-
-#ifdef MSAA
-       if(msaa) {
-               flags |= GLUT_MULTISAMPLE;
-       }
-#endif
-
-       glutInitWindowSize(1280, 800);
-       glutInitDisplayMode(flags);
-       glutCreateWindow("census");
-
-       if(fullscr) {
-               glutFullScreen();
-               glutSetCursor(GLUT_CURSOR_NONE);
-       }
-
-       glutDisplayFunc(display);
-       glutIdleFunc(idle);
-       glutReshapeFunc(reshape);
-       glutKeyboardFunc(keyb);
-
-       if(init() == -1) {
-               return 1;
-       }
-
-       glutMainLoop();
-       return 0;
-}
-
-int init(void)
-{
-       if(init_logo("data/census.curves") == -1) {
-               return -1;
-       }
-
-#ifdef MSAA
-       if(msaa) {
-               glEnable(GL_MULTISAMPLE);
-       }
-#endif
-
-       start_time = glutGet(GLUT_ELAPSED_TIME);
-       return 0;
-}
-
-static void draw_disc(float x, float y, float rad, int sub)
-{
-       int i;
-       glBegin(GL_TRIANGLE_FAN);
-       glVertex2f(x, y);
-       for(i=0; i<sub; i++) {
-               float t = (float)i / (float)(sub - 1);
-               float theta = t * M_PI * 2.0;
-               glVertex2f(cos(theta) * rad + x, sin(theta) * rad + y);
-       }
-       glEnd();
-}
-
-static void draw_line(float x0, float y0, float x1, float y1, float rad)
-{
-       float dx, dy, rx, ry, len;
-
-       dx = x1 - x0;
-       dy = y1 - y0;
-       len = sqrt(dx * dx + dy * dy);
-
-       rx = rad * dy / len;
-       ry = -rad * dx / len;
-
-       draw_disc(x0, y0, rad, 12);
-       draw_disc(x1, y1, rad, 12);
-
-       glBegin(GL_QUADS);
-       glVertex2f(x0 + rx, y0 + ry);
-       glVertex2f(x1 + rx, y1 + ry);
-       glVertex2f(x1 - rx, y1 - ry);
-       glVertex2f(x0 - rx, y0 - ry);
-       glEnd();
-}
-
-#define LOOPTIME       1.45f
-
-void display(void)
-{
-       int i;
-       long msec = glutGet(GLUT_ELAPSED_TIME) - start_time;
-       float t = (float)msec / 1000.0f;
-       float a[2], b[2], dt;
-       float anim, alpha;
-
-       glClear(GL_COLOR_BUFFER_BIT);
-
-       glLineWidth(5.0);
-
-       anim = fmod(t / 6.0f, LOOPTIME);
-       alpha = 1.0f - ((anim - (LOOPTIME - 0.075)) / 0.06f);
-       if(alpha < 0.0f) alpha = 0.0f;
-       if(alpha > 1.0f) alpha = 1.0f;
-
-       dt = (anim > 1.0f ? 1.0f : anim) / (float)(nverts - 1);
-
-       glColor4f(1, 1, 1, alpha);
-       for(i=0; i<nverts-1; i++) {
-               float t0 = (float)i * dt;
-               float t1 = (float)(i + 1) * dt;
-               eval_logo(a, t0);
-               eval_logo(b, t1);
-               draw_line(a[0], a[1], b[0], b[1], 0.02);
-       }
-
-       if(anim > 0.0f) {
-               eval_logo(a, 0);
-               draw_disc(a[0], a[1], 0.05, 22);
-       }
-       if(anim >= 1.0f) {
-               eval_logo(b, 1);
-               draw_disc(b[0], b[1], 0.05, 22);
-       }
-
-       glEnable(GL_BLEND);
-       glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
-       glColor4f(0.8, 0, 0, 2.0 * (anim - 1.0f) / (LOOPTIME - 1.0f));
-       draw_disc(0, 0, 0.14, 30);
-
-       if(alpha < 1.0f) {
-               glBegin(GL_QUADS);
-               glColor4f(0, 0, 0, 1.0f - alpha);
-               glVertex2f(-1, -1);
-               glVertex2f(1, -1);
-               glVertex2f(1, 1);
-               glVertex2f(-1, 1);
-               glEnd();
-       }
-
-       glDisable(GL_BLEND);
-
-       glutSwapBuffers();
-       assert(glGetError() == GL_NO_ERROR);
-}
-
-void idle(void)
-{
-       glutPostRedisplay();
-}
-
-void reshape(int x, int y)
-{
-       float aspect = (float)x / (float)y;
-       win_width = x;
-       win_height = y;
-
-       glViewport(0, 0, x, y);
-       glMatrixMode(GL_PROJECTION);
-       glLoadIdentity();
-       glScalef(1.0f / aspect, 1.0f, 1.0f);
-}
-
-void keyb(unsigned char key, int x, int y)
-{
-       static int saved_width = 800, saved_height = 600;
-
-       switch(key) {
-       case 27:
-               exit(0);
-
-       case '-':
-               nverts -= 8;
-               printf("nverts: %d\n", nverts);
-               glutPostRedisplay();
-               break;
-
-       case '=':
-               nverts += 8;
-               printf("nverts: %d\n", nverts);
-               glutPostRedisplay();
-               break;
-
-       case 'f':
-               fullscr = !fullscr;
-               if(fullscr) {
-                       saved_width = win_width;
-                       saved_height = win_height;
-                       glutFullScreen();
-                       glutSetCursor(GLUT_CURSOR_NONE);
-               } else {
-                       glutReshapeWindow(saved_width, saved_height);
-                       glutSetCursor(GLUT_CURSOR_INHERIT);
-               }
-               break;
-       }
-}
-
-int parse_args(int argc, char **argv)
-{
-       int i;
-
-       for(i=1; i<argc; i++) {
-               if(argv[i][0] == '-') {
-                       if(strcmp(argv[i], "-fs") == 0) {
-                               fullscr = 1;
-                       } else if(strcmp(argv[i], "-noaa") == 0) {
-                               msaa = 0;
-                       } else if(strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "-help") == 0) {
-                               print_usage(argv[0]);
-                               exit(0);
-                       } else {
-                               fprintf(stderr, "invalid option: %s\n", argv[i]);
-                               return -1;
-                       }
-               } else {
-                       fprintf(stderr, "unexpected argument: %s\n", argv[i]);
-                       return -1;
-               }
-       }
-       return 0;
-}
-
-void print_usage(const char *argv0)
-{
-       printf("Usage: %s [options]\n", argv0);
-       printf("Options:\n");
-       printf(" -fs: fullscreen\n");
-       printf(" -noaa: disable anti-aliasing\n");
-       printf(" -h,-help: print usage and exit\n");
-}
diff --git a/src/main_glut.c b/src/main_glut.c
new file mode 100644 (file)
index 0000000..2cd51ef
--- /dev/null
@@ -0,0 +1,97 @@
+#include <stdlib.h>
+#include <assert.h>
+#include <GL/glut.h>
+#include "app.h"
+
+static void display(void);
+static void idle(void);
+static void reshape(int x, int y);
+static void keyb(unsigned char key, int x, int y);
+
+static long start_time;
+
+int main(int argc, char **argv)
+{
+       unsigned int flags = GLUT_RGB | GLUT_DOUBLE;
+
+       glutInit(&argc, argv);
+       if(app_parse_args(argc, argv) == -1) {
+               return 1;
+       }
+
+#ifdef MSAA
+       if(msaa) {
+               flags |= GLUT_MULTISAMPLE;
+       }
+#endif
+
+       glutInitWindowSize(1280, 800);
+       glutInitDisplayMode(flags);
+       glutCreateWindow("census");
+
+       if(fullscr) {
+               glutFullScreen();
+               glutSetCursor(GLUT_CURSOR_NONE);
+       }
+
+       glutDisplayFunc(display);
+       glutIdleFunc(idle);
+       glutReshapeFunc(reshape);
+       glutKeyboardFunc(keyb);
+
+       if(app_init() == -1) {
+               return 1;
+       }
+       start_time = glutGet(GLUT_ELAPSED_TIME);
+
+       glutMainLoop();
+       return 0;
+}
+
+static void display(void)
+{
+       msec = glutGet(GLUT_ELAPSED_TIME) - start_time;
+
+       app_display();
+
+       glutSwapBuffers();
+       assert(glGetError() == GL_NO_ERROR);
+}
+
+static void idle(void)
+{
+       glutPostRedisplay();
+}
+
+static void reshape(int x, int y)
+{
+       app_reshape(x, y);
+       win_width = x;
+       win_height = y;
+}
+
+static void keyb(unsigned char key, int x, int y)
+{
+       app_keyboard(key, 1);
+}
+
+void app_quit(void)
+{
+       exit(0);
+}
+
+static int saved_width = 1280, saved_height = 800;
+
+void app_fullscreen(void)
+{
+       saved_width = win_width;
+       saved_height = win_height;
+       glutFullScreen();
+       glutSetCursor(GLUT_CURSOR_NONE);
+}
+
+void app_windowed(void)
+{
+       glutReshapeWindow(saved_width, saved_height);
+       glutSetCursor(GLUT_CURSOR_INHERIT);
+}
diff --git a/src/main_w32.c b/src/main_w32.c
new file mode 100644 (file)
index 0000000..f3577f3
--- /dev/null
@@ -0,0 +1,199 @@
+#include <stdio.h>
+#include <windows.h>
+#include "app.h"
+
+static int create_glwin(int xsz, int ysz);
+static void destroy_glwin(void);
+static long CALLBACK handle_events(HWND win, unsigned int msg, WPARAM wparam, LPARAM lparam);
+
+static HWND win;
+static HDC dc;
+static HGLRC ctx;
+static int quit;
+static long start_time;
+
+
+int WINAPI WinMain(HINSTANCE pid, HINSTANCE prevpid, char *cmdline, int showcmd)
+{
+       if(memcmp(cmdline, "-c", 2) == 0) {
+               return 0;
+       }
+       if(memcmp(cmdline, "-s", 2) == 0) {
+               fullscr = 1;
+       }
+
+       if(create_glwin(1280, 800) == -1) {
+               return 1;
+       }
+
+       if(app_init() == -1) {
+               return 1;
+       }
+       start_time = timeGetTime();
+
+       while(!quit) {
+               MSG ev;
+               while(PeekMessage(&ev, 0, 0, 0, PM_REMOVE)) {
+                       if(ev.message == WM_QUIT) {
+                               goto done;
+                       }
+                       TranslateMessage(&ev);
+                       DispatchMessage(&ev);
+               }
+               if(quit) goto done;
+
+               msec = timeGetTime() - start_time;
+               app_display();
+               SwapBuffers(dc);
+       }
+
+done:
+       destroy_glwin();
+       return 0;
+}
+
+void app_quit(void)
+{
+       quit = 1;
+}
+
+void app_fullscreen(void)
+{
+}
+
+void app_windowed(void)
+{
+}
+
+
+static int create_glwin(int xsz, int ysz)
+{
+       int x, y, win_xsz, win_ysz, pix_fmt;
+       unsigned int style;
+       HINSTANCE pid;
+       WNDCLASSEX wc;
+       PIXELFORMATDESCRIPTOR pfd;
+       RECT rect;
+
+       pid = GetModuleHandle(0);
+
+       memset(&wc, 0, sizeof wc);
+       wc.cbSize = sizeof wc;
+       wc.hbrBackground = (HBRUSH)GetStockObject(NULL_BRUSH);
+       wc.hCursor = LoadCursor(0, IDC_ARROW);
+       wc.hIcon = wc.hIconSm = LoadIcon(0, IDI_APPLICATION);
+       wc.hInstance = pid;
+       wc.lpfnWndProc = (WNDPROC)handle_events;
+       wc.lpszClassName = "census";
+       wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
+       RegisterClassEx(&wc);
+
+       if(fullscr) {
+               x = y = 0;
+               win_xsz = xsz = GetSystemMetrics(SM_CXSCREEN);
+               win_ysz = ysz = GetSystemMetrics(SM_CYSCREEN);
+
+               style = WS_POPUP;
+       } else {
+               x = y = CW_USEDEFAULT;
+               style = WS_OVERLAPPEDWINDOW;
+
+               rect.left = rect.top = 0;
+               rect.right = xsz;
+               rect.bottom = ysz;
+               AdjustWindowRect(&rect, style, 0);
+
+               win_xsz = rect.right - rect.left;
+               win_ysz = rect.bottom - rect.top;
+       }
+
+       printf("creating window: %dx%d\n", xsz, ysz);
+       win = CreateWindow("census", "census", style, x, y, win_xsz, win_ysz, 0, 0, pid, 0);
+       dc = GetDC(win);
+
+       memset(&pfd, 0, sizeof pfd);
+       pfd.nSize = sizeof pfd;
+       pfd.nVersion = 1;
+       pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER | PFD_DRAW_TO_WINDOW;
+       pfd.iPixelType = PFD_TYPE_RGBA;
+       pfd.cColorBits = 24;
+       pfd.cDepthBits = 24;
+       pfd.iLayerType = PFD_MAIN_PLANE;
+
+       if(!(pix_fmt = ChoosePixelFormat(dc, &pfd)) || !SetPixelFormat(dc, pix_fmt, &pfd)) {
+               fprintf(stderr, "Failed to get suitable pixel format\n");
+               ReleaseDC(win, dc);
+               DestroyWindow(win);
+               UnregisterClass("census", pid);
+               return -1;
+       }
+
+       if(!(ctx = wglCreateContext(dc))) {
+               fprintf(stderr, "Failed to create WGL context\n");
+               ReleaseDC(win, dc);
+               DestroyWindow(win);
+               UnregisterClass("census", pid);
+               return -1;
+       }
+       wglMakeCurrent(dc, ctx);
+
+       ShowWindow(win, SW_SHOW);
+       UpdateWindow(win);
+       SetFocus(win);
+
+       app_reshape(xsz, ysz);
+       win_width = xsz;
+       win_height = ysz;
+       return 0;
+}
+
+static void destroy_glwin(void)
+{
+       wglMakeCurrent(0, 0);
+       wglDeleteContext(ctx);
+       ReleaseDC(win, dc);
+       DestroyWindow(win);
+       UnregisterClass("census", GetModuleHandle(0));
+}
+
+static long CALLBACK handle_events(HWND win, unsigned int msg, WPARAM wparam, LPARAM lparam)
+{
+       static int window_mapped;
+
+       switch(msg) {
+       case WM_SHOWWINDOW:
+               window_mapped = wparam;
+               break;
+
+       case WM_PAINT:
+               if(window_mapped) {
+                       ValidateRect(win, 0);
+               }
+               break;
+
+       case WM_DESTROY:
+               PostQuitMessage(0);
+               quit = 1;
+               break;
+
+       case WM_KEYDOWN:
+               app_keyboard(wparam, 1);
+               break;
+
+       case WM_ACTIVATE:
+               if(!wparam) {
+                       PostQuitMessage(0);
+                       quit = 1;
+               }
+               break;
+
+       case WM_SYSCOMMAND:
+               if(wparam == SC_SCREENSAVE) {
+                       break;
+               }
+
+       default:
+               return DefWindowProc(win, msg, wparam, lparam);
+       }
+       return 0;
+}