Re: [AD] new window hooks patch

[ Thread Index | Date Index | More lists.liballeg.org/allegro-developers Archives ]


> How did you come to the conclusion of 8 callbacks?

I thought of a system similar to the current display switching routine... 
More than one callback could have been nice, giving more flexibility. Anyway, 
it seems my try wasn't well accepted, so I've modified it a lot.
This time I've based my work on Bob's resize hook one; one callback for the 
close event is now allowed.
The patch I'm attaching here replaces Bob's one; hope you don't mind, as the 
only modification to your code was to rename set_resize_hook and 
get_resize_hook to more comprehensible set_window_resize_hook 
(get_window_resize_hook).
I've also removed the X11 resize code you added, as it wasn't compiling and 
it also made no sense there... Michael, correct me if I'm wrong, but the 
function where the resize code was into is meant to resize the system program 
window only when the user sets a new windowed gfx mode.
About window resizeing, shouldn't the gfx driver also reset the screen buffer 
line pointers? I think the resize system is still a premature feature in 
Allegro...

Back to my patch. Now when the user hits the close window button, an ESC 
keypress is simulated and the hook function is called (if set).
The patch adds window close support to X, BeOS and Win32 (but this last one 
can be wrong, as I've not tested it. To avoid confusion, I've commented out 
the old code in wwnd.c, so we can restore it if needed; please check it out).

allegro._tx has also been updated with the new functions doc.

> I'd prefer if it didn't do that.  The user can easily do this in one
> of the hook functions.  Also, you can't prove that the user program
> doesn't interpret Escape as a "Delete all files!" command :-)

Humm, this works nicely with all the Allegro distro programs and examples 
AFAICS, except exkeys.
In addition, it is explained in the docs, so the coder knows of this 
behaviour. If you prefer, we could make CTRL-ALT-END keypresses simulated 
instead of the ESC key, but this sounds horrible to me...

-- 
Angelo Mottola
a.mottola@xxxxxxxxxx
ICQ UIN #66972680
diff -Nru allegro/docs/allegro._tx allegro.test/docs/allegro._tx
--- allegro/docs/allegro._tx	Thu Jan  4 01:53:31 2001
+++ allegro.test/docs/allegro._tx	Thu Jan 11 12:36:46 2001
@@ -151,6 +151,26 @@
    On platforms that are capable of it, this routine alters the window title 
    for your Allegro program.
 
+@@void @set_window_close_hook(void (*proc)(void));
+   On platforms that support windowed gfx modes, this sets the hook
+   function that will be called whenever the user attempts to close the
+   program window. When this happens, an ESC keypress is simulated and
+   this procedure is called (if set). On some operating systems it is not
+   safe to shutdown your program inside this callback; instead you should
+   set a flag and check it later.
+
+@@void @get_window_close_hook(void);
+   Returns the current window close hook.
+
+@@void @set_window_resize_hook(void (*proc)(int w, int h));
+   On platforms that support resizeable windowed gfx modes, this sets the
+   hook function that will be called whenever the user resizes the program
+   window. The function receives the new window width and height into the
+   w and h parameters.
+
+@@void @get_window_resize_hook(void);
+   Returns the current window resize hook.
+
 @@int @desktop_color_depth();
    On platforms that can run Allegro programs in a window on an existing 
    desktop, returns the currently selected desktop color depth (your program 
diff -Nru allegro/include/allegro.h allegro.test/include/allegro.h
--- allegro/include/allegro.h	Sat Dec 16 01:35:49 2000
+++ allegro.test/include/allegro.h	Wed Jan 10 14:40:26 2001
@@ -127,6 +127,12 @@
 AL_FUNC(void, register_assert_handler, (AL_METHOD(int, handler, (AL_CONST char *msg))));
 AL_FUNC(void, register_trace_handler, (AL_METHOD(int, handler, (AL_CONST char *msg))));
 
+AL_FUNC(void, set_window_resize_hook, (void (*proc) (int,int)));
+AL_FUNC(void *, get_window_resize_hook, (void));
+AL_VAR(int, _window_resize_mode);
+AL_FUNC(void, set_window_close_hook, (void (*proc) (void)));
+AL_FUNC(void *, get_window_close_hook, (void));
+
 
 #ifdef DEBUGMODE
    #define ASSERT(condition)     { if (!(condition)) al_assert(__FILE__, __LINE__); }
diff -Nru allegro/src/allegro.c allegro.test/src/allegro.c
--- allegro/src/allegro.c	Tue Sep 26 10:57:54 2000
+++ allegro.test/src/allegro.c	Wed Jan 10 14:40:24 2001
@@ -195,6 +195,56 @@
 static int (*assert_handler)(AL_CONST char *msg) = NULL;
 static int (*trace_handler)(AL_CONST char *msg) = NULL;
 
+/* User window hooks */
+static void (*window_user_close_hook)(void) = NULL;
+static void (*window_user_resize_hook)(int, int) = NULL;
+int _window_resize_mode = FALSE;
+
+/* set_window_resize_hook
+ *  Hooks a user defined resize procedure. It will be called whenever
+ *  the window is resized. The window must be resizable.
+ */
+void set_window_resize_hook(void (*proc) (int,int))
+{
+   TRACE("Hooking resize proc 0x%X\n", proc);
+   window_user_resize_hook = proc;
+   _window_resize_mode = (proc ? TRUE : FALSE);
+   TRACE("Resizing is now %i\n", _window_resize_mode);
+   return;
+}
+
+
+
+/* get_window_resize_hook
+ *  Returns the user resize hook
+ */
+void *get_window_resize_hook(void)
+{
+   return window_user_resize_hook;
+}
+
+
+
+/* set_window_close_hook:
+ *  Sets window closing hook function, to be called when user attempts
+ *  to close the program window.
+ */
+void set_window_close_hook(void (*proc)(void))
+{
+   window_user_close_hook = proc;
+}
+
+
+
+/* get_window_close_hook:
+ *  Returns current window closing hook.
+ */
+void *get_window_close_hook(void)
+{
+   return window_user_close_hook;
+}
+
+
 
 /* dynamic registration system for cleanup code */
 struct al_exit_func {
diff -Nru allegro/src/beos/bgfxapi.cpp allegro.test/src/beos/bgfxapi.cpp
--- allegro/src/beos/bgfxapi.cpp	Thu Dec 21 23:03:37 2000
+++ allegro.test/src/beos/bgfxapi.cpp	Wed Jan 10 19:42:56 2001
@@ -1169,6 +1169,12 @@
  */
 bool BeAllegroWindow::QuitRequested(void)
 {
+    void (*close_hook)();
+
+    simulate_keypress((KEY_ESC << 8) | 27);
+    close_hook = get_window_close_hook();
+    if (close_hook)
+       close_hook();
     return false;
 }
 
diff -Nru allegro/src/win/wwnd.c allegro.test/src/win/wwnd.c
--- allegro/src/win/wwnd.c	Tue Aug 15 13:30:06 2000
+++ allegro.test/src/win/wwnd.c	Wed Jan 10 19:44:04 2001
@@ -15,6 +15,7 @@
  *      See readme.txt for copyright information.
  */
 
+#include "allegro.h"
 
 #ifndef SCAN_DEPEND
    #include <string.h>
@@ -116,6 +117,7 @@
 					 WPARAM wparam, LPARAM lparam)
 {
    PAINTSTRUCT ps;
+   void (*resize_hook)(int,int);
 
    if (message == msg_call_proc)
       return ((int (*)(void))wparam) ();
@@ -200,8 +202,13 @@
 	 if (!allow_wm_close) {
 	    if (wnd_windowed) {
 	       /* turn close messages into Esc keypress */
-	       _handle_key_press(27, KEY_ESC);
-	       _handle_key_release(KEY_ESC);
+/*	       _handle_key_press(27, KEY_ESC);
+	       _handle_key_release(KEY_ESC); */
+	       void (*close_hook)();
+	       simulate_keypress((KEY_ESC << 8) | 27);
+	       close_hook = get_window_close_hook();
+	       if (close_hook)
+	          close_hook();
 	    }
 	    return 0;
 	 }
@@ -275,12 +282,13 @@
 
    do_uconvert(get_filename(fname), U_CURRENT, title, U_ASCII, sizeof(title));
 
+	TRACE("Window resize mode: %i\n", _window_resize_mode);
    /* create the window now */
    wnd = CreateWindowEx(
 			  0,
 			  ALLEGRO_WND_CLASS,
 			  title,
-			  WS_SYSMENU | WS_CAPTION | WS_MINIMIZEBOX,
+			  _window_resize_mode ? WS_OVERLAPPEDWINDOW : (WS_SYSMENU | WS_CAPTION | WS_MINIMIZEBOX),
 			  -1000, -1000, 0, 0,
 			  NULL, NULL,
 			  allegro_inst,
diff -Nru allegro/src/x/xwin.c allegro.test/src/x/xwin.c
--- allegro/src/x/xwin.c	Sat Nov 11 11:07:20 2000
+++ allegro.test/src/x/xwin.c	Wed Jan 10 19:43:31 2001
@@ -139,6 +139,9 @@
 /* Array of keycodes which are pressed now (used for auto-repeat).  */
 int _xwin_keycode_pressed[256];
 
+/* Atom to catch window delete events */
+static Atom wm_delete_window;
+
 
 
 /* Forward declarations for private functions.  */
@@ -346,7 +349,7 @@
    setattr.border_pixel = XBlackPixel(_xwin.display, _xwin.screen);
    setattr.event_mask = (KeyPressMask | KeyReleaseMask 
 			 | EnterWindowMask | LeaveWindowMask
-			 | FocusChangeMask | ExposureMask
+			 | FocusChangeMask | ExposureMask | PropertyChangeMask
 			 | ButtonPressMask | ButtonReleaseMask | PointerMotionMask
 			 /*| MappingNotifyMask (SubstructureRedirectMask?)*/);
    _xwin.window = XCreateWindow(_xwin.display, XDefaultRootWindow(_xwin.display),
@@ -372,6 +375,10 @@
    /* Set default window parameters.  */
    (*_xwin_window_defaultor)();
 
+   /* Set WM_DELETE_WINDOW atom in WM_PROTOCOLS property (to get window_delete requests).  */
+   wm_delete_window = XInternAtom (_xwin.display, "WM_DELETE_WINDOW", False);
+   XSetWMProtocols (_xwin.display, _xwin.window, &wm_delete_window, 1);
+
    /* Map window.  */
    XMapWindow(_xwin.display, _xwin.window);
 
@@ -2053,6 +2060,17 @@
 	 if (event->xmapping.request == MappingKeyboard)
 	    _xwin_private_init_keyboard_tables();
 	 break;
+      case ClientMessage:
+         /* Window closing request.  */
+         if (event->xclient.data.l[0] == wm_delete_window) {
+            void (*close_hook)();
+
+            simulate_keypress((KEY_ESC << 8) | 27);
+            close_hook = get_window_close_hook();
+            if (close_hook)
+               close_hook();
+         }
+         break;
    }
 }
 


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/