/* Copyright 1996 Acorn Computers Ltd
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/****************************************************************************
 * This source file was written by Acorn Computers Limited. It is part of   *
 * the RISCOS library for writing applications in C for RISC OS. It may be  *
 * used freely in the creation of programs for Archimedes. It should be     *
 * used with Acorn's C Compiler Release 3 or later.                         *
 *                                                                          *
 ***************************************************************************/

/* Title:   win.h
 * Purpose: central management of RISC OS windows
 *
 */

# ifndef __win_h
# define __win_h

# ifndef __wimp_h
# include "wimp.h"
# endif

#ifndef BOOL
#define BOOL int
#define TRUE 1
#define FALSE 0
#endif


/* This module constructs a very simple idea of "window class" within RISCOS.
 * RISCOS window class implementations register the existence of each window
 * with this module.
 */

/* This structure allows event-processing loops to be constructed that
 * have no knowledge of what other modules are present in the program.
 * For instance, the dialogue box module can contain an event-processing loop
 * without reference to what other window types are present in the program.
 */

typedef void (*win_event_handler)(wimp_eventstr*, void *handle);

/* ************************** Claiming Events. *************************** */


/* ------------------------- win_register_event_handler --------------------
 * Description:   Install an event handler function for a given window.
 *
 * Parameters:    wimp_w -- the window's handle
 *                win_event_handler -- the event handler function
 *                void *handle -- caller-defined handle
 * Returns:       void.
 * Other Info:    This call has no effect on the window itself -- it just
 *                informs the win module that the supplied function should
 *                be called when events are delivered to the window.
 *                To remove a handler, call with a null function pointer,
 *                ie.  win_register_event_handler(w,(win_event_handler)0,0)
 *                To catch key events for an icon on the icon bar register
 *                a handler for win_ICONBAR,
 *                   ie. win_event_handler(win_ICONBAR, handler_func, handle)
 *                To catch load event for an icon on the icon bar register
 *                a handler for win_ICONBARLOAD,
 *                 ie. win_event_handler(win_ICONBARLOAD, load_func, handle).
 *
 */

#define win_ICONBAR (-3)
#define win_ICONBARLOAD (-99)
void win_register_event_handler(wimp_w, win_event_handler, void *handle);


/* ------------------------- win_read_event_handler ------------------------
 * Description:   Read current event handler for a given window, and the
 *                handle which it is passed.
 *
 * Parameters:    wimp_w w -- the window's handle
 *                win_event_handler *p -- the handler function
 *                void **handle -- the handle passed to the handler function
 * Returns:       TRUE if given window is registered, FALSE otherwise
 * Other Info:    This is useful for registering an alternative event handler
 *                which can vet events, before passing them on to the original
 *                handler.
 *
 */

BOOL win_read_eventhandler(wimp_w w, win_event_handler *p, void **handle);


/* ------------------------- win_claim_idle_events -------------------------
 * Description:   Cause "idle" events to be delivered to a given window.
 *
 * Parameters:    wimp_w -- the window's handle
 * Returns:       void.
 * Other Info:    To cancel this, call with window handle (wimp_w)-1.
 *
 */

void win_claim_idle_events(wimp_w);



typedef BOOL (*win_unknown_event_processor)(wimp_eventstr*, void *handle);
/* You can ask to vet unknown events, before they are passed to the default
   unknown event handler. These procs return TRUE if they have dealt with the
   event.
*/


/* --------------------- win_add_unknown_event_processor -------------------
 * Description:   Add a handler for unknown events onto the front of the
 *                queue of such handlers.
 *
 * Parameters:    win_unknown_event_processor -- handler function
 *                void *handle -- passed to handler on call
 * Returns:       void.
 * Other Info:    The win module maintains a list of unknown event handlers.
 *                An unknown event results in the "head of the list" function
 *                being called; if this function doesn't deal with the event
 *                it is passed on to the next in the list, and so on.
 *                Handler functios should return a Boolean result to show
 *                if they dealt with the event, or if it should be passed on.
 *                "Known" events are as follows:
 *                         ENULL, EREDRAW, ECLOSE, EOPEN, EPTRLEAVE,
 *                         EPTRENTER, EKEY, ESCROLL, EBUT
 *                         and ESEND/ESENDWANTACK for the following msg types
 *                             MCLOSEDOWN, MDATASAVE, MDATALOAD, MHELPREQUEST
 *                All other events are considered "unknown"
 *                Note: if none of the unknown event handlers deals with the
 *                event, then it is passed on to the unknown event claiming
 *                window (registered by win_claim_unknown_events()). If
 *                there is no such claimer, then the unknown event is
 *                ignored.
 *
 */

void win_add_unknown_event_processor(win_unknown_event_processor,
                                     void *handle) ;


/* ------------------ win_remove_unknown_event_processor -------------------
 * Description:   Removes the given unknown event handler with the given
 *                handle from the stack of handlers.
 *
 * Parameters:    win_unknown_event_processor -- the handler to be removed
 *                void *handle -- its handle
 * Returns:       void.
 * Other Info:    The handler to be removed can be anyway in the stack
 *                (not necessarily at the top).
 *
 */

void win_remove_unknown_event_processor(win_unknown_event_processor,
                                        void *handle) ;


/* ---------------------- win_idle_event_claimer ---------------------------
 * Description:   Informs caller of which window is claiming idle events.
 *
 * Parameters:    void
 * Returns:       Handle of window claiming idle events.
 * Other Info:    Returns (wimp_w)-1, if no window is claiming idle events.
 *
 */

wimp_w win_idle_event_claimer(void);


/* ---------------------- win_claim_unknown_events -------------------------
 * Description:   Cause any unknown, or non-window-specific events to be
 *                delivered to a given window.
 *
 * Parameters:    wimp_w -- handle of window to which unknown events should
 *                          be delivered
 * Returns:       void.
 * Other Info:    Calling with (wimp_w)-1 cancels this
 *                See win_add_unknown_event_processor() for details of which
 *                events are "known".
 *
 */

void win_claim_unknown_events(wimp_w);


/* ------------------------- win_unknown_event_claimer ---------------------
 * Description:   Informs caller of which window is claiming unknown events.
 *
 * Parameters:    void
 * Returns:       Handle of window claiming unknown events.
 * Other Info:    Return of (wimp_w)-1 means no claimer registered.
 *
 */

wimp_w win_unknown_event_claimer(void);



/* ********************************* Menus. ****************************** */


/* ---------------------------- win_setmenuh -------------------------------
 * Description:   Attaches the given menu structure to the given window
 *
 * Parameters:    wimp_w -- handle of window
 *                void *handle -- pointer to menu structure
 * Returns:       void.
 * Other Info:    Mainly used by higher level RISC_OSlib routines to attach
 *                menus to windows (eg. event_attachmenu()).
 *
 */

void win_setmenuh(wimp_w, void *handle);


/* --------------------------- win_getmenuh --------------------------------
 * Description:   Returns a pointer to the menu structure attached to given
 *                window.
 *
 * Parameters:    wimp_w -- handle of window
 * Returns:       pointer to the attached menu (0 if no menu attached).
 * Other Info:    As for win_setmenuh(), this is used mainly by higher level
 *                RISC_OSlib routines (eg. event_attachmenu()).
 *
 */

void *win_getmenuh(wimp_w);


/* ************************** Event Processing. ************************** */


/* -------------------------- win_processevent -----------------------------
 * Description:   Delivers an event to its relevant window, if such a window
 *                has been registered with this module (via
 *                win_register_event_handler()).
 *
 * Parameters:    wimp_eventstr* -- pointer to the event which has occurred
 * Returns:       true if an event handler (registered with this module)
 *                has dealt with the event, false otherwise.
 * Other Info:    the main client for this routine is event_process(), which
 *                uses it to deliver an event to its appropriate window.
 *                Keyboard events are delivered to the current owner of the
 *                caret.
 *
 */

BOOL win_processevent(wimp_eventstr*);


/* ****************************** Termination. *************************** */


/* --------------------------- win_activeinc -------------------------------
 * Description:   Increment by one the win module's idea of the number of
 *                active windows owned by a program.
 *
 * Parameters:    void
 * Returns:       void.
 * Other Info:    Note: event_process() calls exit() on behalf of the program
 *                when the number of active windows reaches zero
 *                Programs which wish to remain running even when they have
 *                no active windows, should ensure that win_activeinc() is
 *                called once before creating any windows, so that the no.
 *                of active windows is always >= 1. This is done for you
 *                if you use baricon() to install your program's icon on the
 *                iconbar.
 *
 */

void win_activeinc(void);


/* ---------------------------- win_activedec ------------------------------
 * Description:   Decrements by one the win module's idea of the number of
 *                active windows owned by a program.
 *
 * Parameters:    void
 * Returns:       void.
 * Other Info:    See note in win_activeinc() regarding program termination.
 *
 */

void win_activedec(void);


/* ---------------------------- win_activeno -------------------------------
 * Description:   Informs the caller of the number of active windows owned
 *                by your program.
 *
 * Parameters:    void
 * Returns:       no. of active windows owned by program.
 * Other Info:    This is given by (no. of calls to win_activeinc()) minus
 *                (no. of calls to win_activedec())
 *                Note that modules in RISCOSlib itself may have made calls
 *                to win_activeinc() and win_activedec().
 *
 */

int win_activeno(void);


/* -------------------------- win_give_away_caret --------------------------
 * Description:   gives the caret away to the open window at the top of the
 *                WIMP's window stack (if that window is owned by your
 *                program).
 *
 * Parameters:    void
 * Returns:       void.
 * Other Info:    If the top window is interested it will take the caret
 *                If not then nothing happens.
 *                Note: only works if polling is done using the wimpt module,
 *                which is the case if your main inner loop goes something
 *                like:   while (TRUE)
 *                            event_process();
 *
 */

void win_give_away_caret(void);

/* ------------------------------ win_settitle -----------------------------
 * Description:   changes the title displayed in a given window
 *
 * Parameters:    wimp_w w      -- given window's handle
 *                char *newtitle -- null-terminated string giving new
 *                                  title for window
 *
 * Returns:       void.
 * Other Info:    The title icon of the given window must be indirected text
 *                This will change the title used by all windows created
 *                from the given window's template if you have used the
 *                template module (since the Window manager uses your address
 *                space to hold indirected text icons). To avoid this the
 *                window can be created from a copy of the template, ie.
 *                    template *t = template_copy(template_find("name"));
 *                    wimp_create_wind(t->window, &w);
 *
 */

void win_settitle(wimp_w w, char *newtitle);

/* ------------------------------ win_init ---------------------------------
 * Description:   initialise the centralised window event system
 *
 * Parameters:    void
 * Returns:       TRUE if initialisation went OK.
 * Other Info:    If you use wimpt_init(), to start your application, then
 *                this call is made for you.
 *
 */

BOOL win_init(void);

#endif

/* end win.h */