1
+ /*
2
+ * Copyright 2025 The Emscripten Authors. All rights reserved.
3
+ * Emscripten is available under two separate licenses, the MIT license and the
4
+ * University of Illinois/NCSA Open Source License. Both these licenses can be
5
+ * found in the LICENSE file.
6
+ */
7
+
8
+ #include <stdio.h>
9
+ #include <assert.h>
10
+ #include <emscripten/emscripten.h>
11
+ #include <GL/glut.h>
12
+
13
+ typedef struct {
14
+ int width ;
15
+ int height ;
16
+ } rect_size_t ;
17
+
18
+ static rect_size_t browser_window_size = { 0 , 0 };
19
+ static rect_size_t glut_init_size = { 0 , 0 };
20
+ static rect_size_t glut_reshape_size = { 0 , 0 };
21
+
22
+ void print_size_test (const char * name , rect_size_t rect_size ) {
23
+ static int test_count = 0 ;
24
+ printf ("Test %d: %s = %d x %d\n" , ++ test_count , name , rect_size .width , rect_size .height );
25
+ }
26
+
27
+ int equal_size (rect_size_t rect_1 , rect_size_t rect_2 ) {
28
+ return (rect_1 .width == rect_2 .width && rect_1 .height == rect_2 .height );
29
+ }
30
+
31
+ /**
32
+ * Obtain various dimensions
33
+ */
34
+ EM_JS (void , get_browser_window_size , (int * width , int * height ), {
35
+ setValue (width , window .innerWidth , 'i32' );
36
+ setValue (height , window .innerHeight , 'i32' );
37
+ });
38
+
39
+ EM_JS (void , get_canvas_client_size , (int * width , int * height ), {
40
+ const canvas = Module .canvas ;
41
+ setValue (width , canvas .clientWidth , 'i32' );
42
+ setValue (height , canvas .clientHeight , 'i32' );
43
+ });
44
+
45
+ EM_JS (void , get_canvas_size , (int * width , int * height ), {
46
+ const canvas = Module .canvas ;
47
+ setValue (width , canvas .width , 'i32' );
48
+ setValue (height , canvas .height , 'i32' );
49
+ });
50
+
51
+ /**
52
+ * Update canvas style with given width and height, then invoke window resize event
53
+ */
54
+ EM_JS (void , test_resize_with_CSS , (const char * position , const char * width , const char * height ), {
55
+ const canvas = Module .canvas ;
56
+ canvas .style .position = UTF8ToString (position );
57
+ canvas .style .width = UTF8ToString (width );
58
+ canvas .style .height = UTF8ToString (height );
59
+
60
+ window .dispatchEvent (new UIEvent ('resize' ));
61
+ });
62
+
63
+ /**
64
+ * Verify canvas and reshape callback match target size, and also that
65
+ * canvas width, height matches canvas clientWidth, clientHeight
66
+ */
67
+ void assert_sizes_equal (rect_size_t target_size ) {
68
+ /* verify target size match */
69
+ rect_size_t canvas_size ;
70
+ get_canvas_size (& canvas_size .width , & canvas_size .height );
71
+ assert (equal_size (canvas_size , target_size ));
72
+ assert (equal_size (glut_reshape_size , target_size ));
73
+
74
+ /* verify canvas client size match */
75
+ rect_size_t canvas_client_size ;
76
+ get_canvas_client_size (& canvas_client_size .width , & canvas_client_size .height );
77
+ assert (equal_size (canvas_size , canvas_client_size ));
78
+ }
79
+
80
+ /**
81
+ * Resizing tests
82
+ */
83
+ void run_tests () {
84
+
85
+ /* startup */
86
+ print_size_test ("startup, no CSS: canvas == glutReshapeFunc == glutInitWindow size" , glut_init_size );
87
+ assert_sizes_equal (glut_init_size );
88
+
89
+ /* glutReshapeWindow */
90
+ rect_size_t new_reshape_size = { glut_init_size .width + 40 , glut_init_size .height + 20 };
91
+ print_size_test ("glut reshape, no CSS: canvas == glutReshapeFunc == glutReshapeWindow size" , new_reshape_size );
92
+ glutReshapeWindow (new_reshape_size .width , new_reshape_size .height );
93
+ assert_sizes_equal (new_reshape_size );
94
+
95
+ /* 100% scale CSS */
96
+ print_size_test ("100% window scale CSS: canvas == glutReshapeFunc == browser window size" , browser_window_size );
97
+ test_resize_with_CSS ("fixed" , "100%" , "100%" ); /* fixed, so canvas is driven by window size */
98
+ assert_sizes_equal (browser_window_size );
99
+
100
+ /* specific pixel size CSS */
101
+ rect_size_t css_pixels_size = { glut_init_size .width - 20 , glut_init_size .height + 40 };
102
+ print_size_test ("specific pixel size CSS: canvas == glutReshapeFunc == CSS specific size" , css_pixels_size );
103
+ char css_width [16 ], css_height [16 ];
104
+ snprintf (css_width , 16 , "%dpx" , css_pixels_size .width );
105
+ snprintf (css_height , 16 , "%dpx" , css_pixels_size .height );
106
+ test_resize_with_CSS ("static" , css_width , css_height ); /* static, canvas is driven by CSS size */
107
+ assert_sizes_equal (css_pixels_size );
108
+
109
+ /* mix of CSS scale and pixel size */
110
+ rect_size_t css_mixed_size = { browser_window_size .width * 0.6 , 100 };
111
+ print_size_test ("60% width, 100px height CSS: canvas == glutReshapeFunc == CSS mixed size" , css_mixed_size );
112
+ test_resize_with_CSS ("fixed" , "60%" , "100px" ); /* fixed, canvas width is driven by window size */
113
+ assert_sizes_equal (css_mixed_size );
114
+
115
+ /* run tests once */
116
+ glutIdleFunc (NULL );
117
+ emscripten_force_exit (0 );
118
+ }
119
+
120
+ /**
121
+ * Reshape callback
122
+ */
123
+ void reshape (int w , int h ) {
124
+ glut_reshape_size .width = w ;
125
+ glut_reshape_size .height = h ;
126
+ }
127
+
128
+ int main (int argc , char * argv []) {
129
+ /* Make glut initial canvas size be 1/2 of browser window */
130
+ get_browser_window_size (& browser_window_size .width , & browser_window_size .height );
131
+ glut_init_size .width = browser_window_size .width / 2 ;
132
+ glut_init_size .height = browser_window_size .height / 2 ;
133
+
134
+ glutInit (& argc , argv );
135
+ glutInitWindowSize (glut_init_size .width , glut_init_size .height );
136
+ glutInitDisplayMode (GLUT_RGB );
137
+ glutCreateWindow ("test_glut_resize.c" );
138
+
139
+ /* Set up glut callback functions */
140
+ glutIdleFunc (run_tests );
141
+ glutReshapeFunc (reshape );
142
+ glutDisplayFunc (NULL );
143
+
144
+ glutMainLoop ();
145
+ return 0 ;
146
+ }
0 commit comments