@@ -49,7 +49,10 @@ ALLEGRO_DEBUG_CHANNEL("wwindow")
49
49
50
50
static WNDCLASS window_class ;
51
51
52
- static bool resize_postponed = false;
52
+ static _AL_VECTOR resizing_displays ;
53
+ static ALLEGRO_MUTEX * resize_event_thread_mutex ;
54
+ static bool end_resize_event_thread ;
55
+ static bool resize_event_thread_ended ;
53
56
54
57
55
58
UINT _al_win_msg_call_proc = 0 ;
@@ -308,6 +311,10 @@ static void win_generate_resize_event(ALLEGRO_DISPLAY_WIN *win_display)
308
311
WINDOWINFO wi ;
309
312
int x , y , w , h ;
310
313
314
+ if (win_display -> ignore_resize ) {
315
+ return ;
316
+ }
317
+
311
318
wi .cbSize = sizeof (WINDOWINFO );
312
319
GetWindowInfo (win_display -> window , & wi );
313
320
x = wi .rcClient .left ;
@@ -347,25 +354,6 @@ static void win_generate_resize_event(ALLEGRO_DISPLAY_WIN *win_display)
347
354
}
348
355
}
349
356
350
- static void postpone_thread_proc (void * arg )
351
- {
352
- ALLEGRO_DISPLAY * display = (ALLEGRO_DISPLAY * )arg ;
353
- ALLEGRO_DISPLAY_WIN * win_display = (ALLEGRO_DISPLAY_WIN * )display ;
354
-
355
- Sleep (50 );
356
-
357
- if (win_display -> ignore_resize ) {
358
- win_display -> ignore_resize = false;
359
- }
360
- else {
361
- win_generate_resize_event (win_display );
362
- }
363
-
364
- resize_postponed = false;
365
- win_display -> can_acknowledge = true;
366
- }
367
-
368
-
369
357
static void handle_mouse_capture (bool down , HWND hWnd )
370
358
{
371
359
int i ;
@@ -412,6 +400,32 @@ static bool accept_mouse_event(void)
412
400
return !((GetMessageExtraInfo () & _AL_MOUSEEVENTF_FROMTOUCH ) == _AL_MOUSEEVENTF_FROMTOUCH );
413
401
}
414
402
403
+ /* We want to rate-limit the ALLEGRO_EVENT_DISPLAY_RESIZE events while
404
+ * live-resizing via mouse. To this end, we detect start/end of this
405
+ * via WM_ENTERSIZEMOVE/WM_EXITSIZEMOVE and then enable this code to
406
+ * periodically send those events.
407
+ */
408
+ static void resize_event_thread_proc (void * arg )
409
+ {
410
+ (void )arg ;
411
+ while (true) {
412
+ al_lock_mutex (resize_event_thread_mutex );
413
+ if (end_resize_event_thread ) {
414
+ al_unlock_mutex (resize_event_thread_mutex );
415
+ break ;
416
+ }
417
+
418
+ for (int j = 0 ; j < (int )_al_vector_size (& resizing_displays ); j ++ ) {
419
+ ALLEGRO_DISPLAY_WIN * * win_display = (ALLEGRO_DISPLAY_WIN * * )_al_vector_ref (& resizing_displays , j );
420
+ win_generate_resize_event (* win_display );
421
+ }
422
+
423
+ al_unlock_mutex (resize_event_thread_mutex );
424
+ Sleep (50 );
425
+ }
426
+ resize_event_thread_ended = true;
427
+ }
428
+
415
429
static LRESULT CALLBACK window_callback (HWND hWnd , UINT message ,
416
430
WPARAM wParam , LPARAM lParam )
417
431
{
@@ -438,6 +452,9 @@ static LRESULT CALLBACK window_callback(HWND hWnd, UINT message,
438
452
break_window_message_pump (win_display , hWnd );
439
453
if (_al_win_unregister_touch_window )
440
454
_al_win_unregister_touch_window (hWnd );
455
+ al_lock_mutex (resize_event_thread_mutex );
456
+ _al_vector_find_and_delete (& resizing_displays , & win_display );
457
+ al_unlock_mutex (resize_event_thread_mutex );
441
458
DestroyWindow (hWnd );
442
459
return 0 ;
443
460
}
@@ -459,6 +476,9 @@ static LRESULT CALLBACK window_callback(HWND hWnd, UINT message,
459
476
break_window_message_pump (win_display , hWnd );
460
477
if (_al_win_unregister_touch_window )
461
478
_al_win_unregister_touch_window (hWnd );
479
+ al_lock_mutex (resize_event_thread_mutex );
480
+ _al_vector_find_and_delete (& resizing_displays , & win_display );
481
+ al_unlock_mutex (resize_event_thread_mutex );
462
482
DestroyWindow (hWnd );
463
483
return 0 ;
464
484
}
@@ -939,15 +959,10 @@ static LRESULT CALLBACK window_callback(HWND hWnd, UINT message,
939
959
}
940
960
}
941
961
break ;
942
- case WM_SIZE :
962
+ case WM_SIZE : {
963
+ bool generate = false;
943
964
if (wParam == SIZE_RESTORED || wParam == SIZE_MAXIMIZED || wParam == SIZE_MINIMIZED ) {
944
- /*
945
- * Delay the resize event so we don't get bogged down with them
946
- */
947
- if (!resize_postponed ) {
948
- resize_postponed = true;
949
- _beginthread (postpone_thread_proc , 0 , (void * )d );
950
- }
965
+ generate = true;
951
966
d -> flags &= ~ALLEGRO_MAXIMIZED ;
952
967
if (wParam == SIZE_MAXIMIZED ) {
953
968
d -> flags |= ALLEGRO_MAXIMIZED ;
@@ -959,31 +974,43 @@ static LRESULT CALLBACK window_callback(HWND hWnd, UINT message,
959
974
* We have to create the resize event, so the application could
960
975
* redraw its content.
961
976
*/
962
- if (!resize_postponed ) {
963
- resize_postponed = true;
964
- _beginthread (postpone_thread_proc , 0 , (void * )d );
965
- }
977
+ generate = true;
978
+ }
979
+ al_lock_mutex (resize_event_thread_mutex );
980
+ if (_al_vector_contains (& resizing_displays , & win_display )) {
981
+ generate = false;
982
+ }
983
+ al_unlock_mutex (resize_event_thread_mutex );
984
+ if (generate ) {
985
+ win_generate_resize_event (win_display );
966
986
}
967
987
return 0 ;
968
- case WM_ENTERSIZEMOVE :
988
+ }
989
+ case WM_ENTERSIZEMOVE : {
969
990
/* DefWindowProc for WM_ENTERSIZEMOVE enters a modal loop, which also
970
991
* ends up blocking the loop in d3d_display_thread_proc (which is
971
992
* where we are called from, if using D3D). Rather than batching up
972
993
* intermediate resize events which the user cannot acknowledge in the
973
994
* meantime anyway, make it so only a single resize event is generated
974
995
* at WM_EXITSIZEMOVE.
975
996
*/
997
+ al_lock_mutex (resize_event_thread_mutex );
976
998
if (d -> flags & ALLEGRO_DIRECT3D_INTERNAL ) {
977
- resize_postponed = true;
999
+ win_display -> ignore_resize = true;
978
1000
}
1001
+ ALLEGRO_DISPLAY_WIN * * add = (ALLEGRO_DISPLAY_WIN * * )_al_vector_alloc_back (& resizing_displays );
1002
+ * add = win_display ;
1003
+ al_unlock_mutex (resize_event_thread_mutex );
979
1004
break ;
1005
+ }
980
1006
case WM_EXITSIZEMOVE :
981
- if ( resize_postponed ) {
982
- win_generate_resize_event ( win_display );
1007
+ al_lock_mutex ( resize_event_thread_mutex );
1008
+ if ( d -> flags & ALLEGRO_DIRECT3D_INTERNAL ) {
983
1009
win_display -> ignore_resize = false;
984
- resize_postponed = false;
985
- win_display -> can_acknowledge = true;
986
1010
}
1011
+ _al_vector_find_and_delete (& resizing_displays , & win_display );
1012
+ al_unlock_mutex (resize_event_thread_mutex );
1013
+ win_generate_resize_event (win_display );
987
1014
break ;
988
1015
case WM_DPICHANGED :
989
1016
if ((d -> flags & ALLEGRO_RESIZABLE ) && !(d -> flags & ALLEGRO_FULLSCREEN )) {
@@ -1008,7 +1035,7 @@ static LRESULT CALLBACK window_callback(HWND hWnd, UINT message,
1008
1035
return DefWindowProc (hWnd ,message ,wParam ,lParam );
1009
1036
}
1010
1037
1011
- int _al_win_init_window ()
1038
+ int _al_win_init_window (void )
1012
1039
{
1013
1040
// Create A Window Class Structure
1014
1041
window_class .cbClsExtra = 0 ;
@@ -1029,9 +1056,33 @@ int _al_win_init_window()
1029
1056
_al_win_msg_suicide = RegisterWindowMessage (TEXT ("Allegro window suicide" ));
1030
1057
}
1031
1058
1059
+ resize_event_thread_mutex = al_create_mutex ();
1060
+ _al_vector_init (& resizing_displays , sizeof (ALLEGRO_DISPLAY_WIN * ));
1061
+ _beginthread (resize_event_thread_proc , 0 , 0 );
1062
+
1032
1063
return true;
1033
1064
}
1034
1065
1066
+ void _al_win_shutdown_window (void )
1067
+ {
1068
+ al_lock_mutex (resize_event_thread_mutex );
1069
+ end_resize_event_thread = true;
1070
+ al_unlock_mutex (resize_event_thread_mutex );
1071
+
1072
+ while (true) {
1073
+ al_lock_mutex (resize_event_thread_mutex );
1074
+ if (resize_event_thread_ended ) {
1075
+ al_unlock_mutex (resize_event_thread_mutex );
1076
+ break ;
1077
+ }
1078
+ al_unlock_mutex (resize_event_thread_mutex );
1079
+ Sleep (10 );
1080
+ }
1081
+ _al_vector_free (& resizing_displays );
1082
+ al_destroy_mutex (resize_event_thread_mutex );
1083
+ resize_event_thread_mutex = NULL ;
1084
+ }
1085
+
1035
1086
1036
1087
static int win_choose_icon_bitmap (const int sys_w , const int sys_h ,
1037
1088
const int num_icons , ALLEGRO_BITMAP * bmps [])
0 commit comments