mirror of
https://github.com/VincentWei/MiniGUI.git
synced 2026-02-06 18:31:57 +08:00
982 lines
30 KiB
C
982 lines
30 KiB
C
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// IMPORTANT NOTICE
|
|
//
|
|
// The following open source license statement does not apply to any
|
|
// entity in the Exception List published by FMSoft.
|
|
//
|
|
// For more information, please visit:
|
|
//
|
|
// https://www.fmsoft.cn/exception-list
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
/*
|
|
* This file is part of MiniGUI, a mature cross-platform windowing
|
|
* and Graphics User Interface (GUI) support system for embedded systems
|
|
* and smart IoT devices.
|
|
*
|
|
* Copyright (C) 2002~2020, Beijing FMSoft Technologies Co., Ltd.
|
|
* Copyright (C) 1998~2002, WEI Yongming
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
* Or,
|
|
*
|
|
* As this program is a library, any link to this program must follow
|
|
* GNU General Public License version 3 (GPLv3). If you cannot accept
|
|
* GPLv3, you need to be licensed from FMSoft.
|
|
*
|
|
* If you have got a commercial license of this program, please use it
|
|
* under the terms and conditions of the commercial license.
|
|
*
|
|
* For more information about the commercial license, please refer to
|
|
* <http://www.minigui.com/blog/minigui-licensing-policy/>.
|
|
*/
|
|
/*
|
|
** internals.h: this head file declares all internal types and data.
|
|
**
|
|
** Create date: 1999/05/22
|
|
*/
|
|
|
|
#ifndef GUI_INTERNALS_H
|
|
#define GUI_INTERNALS_H
|
|
|
|
#include "common.h"
|
|
#include "minigui.h"
|
|
#include "gdi.h"
|
|
#include "window.h"
|
|
|
|
#include "constants.h"
|
|
#include "cliprect.h"
|
|
#include "zorder.h"
|
|
#include "list.h"
|
|
#include "map.h"
|
|
|
|
#ifdef HAVE_SELECT
|
|
# ifdef HAVE_SYS_SELECT_H
|
|
# include <sys/select.h>
|
|
# endif
|
|
# include <sys/time.h>
|
|
# include <sys/types.h>
|
|
# include <unistd.h>
|
|
#endif
|
|
|
|
/******************* Internal data *******************************************/
|
|
|
|
/* Internal window message. */
|
|
#if (defined(_MG_ENABLE_SCREENSAVER) || \
|
|
defined(_MG_ENABLE_WATERMARK)) && defined(_MGRM_THREADS)
|
|
#define MSG_CANCELSCREENSAVER 0x0201
|
|
#endif
|
|
|
|
/* Internal extended style. */
|
|
#define WS_EX_MODALDISABLED 0x10000000L
|
|
|
|
/*
|
|
* \def WS_EX_CTRLASMAINWIN
|
|
* \brief The control can be displayed out of the main window
|
|
* which contains the control.
|
|
*/
|
|
#define WS_EX_CTRLASMAINWIN 0x20000000L
|
|
|
|
/* Internal extended style. */
|
|
#define WS_EX_DIALOGBOX 0x40000000L
|
|
|
|
/* Make sure the internal window extended styles above are ok */
|
|
#define MGUI_COMPILE_TIME_ASSERT(name, x) \
|
|
typedef int MGUI_dummy_ ## name[((x)?1:0) * 2 - 1]
|
|
|
|
MGUI_COMPILE_TIME_ASSERT(ws_ex_int_1,
|
|
WS_EX_INTERNAL_MASK & WS_EX_MODALDISABLED);
|
|
MGUI_COMPILE_TIME_ASSERT(ws_ex_int_2,
|
|
WS_EX_INTERNAL_MASK & WS_EX_CTRLASMAINWIN);
|
|
|
|
#undef MGUI_COMPILE_TIME_ASSERT
|
|
|
|
/******************** Handle type and child type. ***************************/
|
|
#define TYPE_HWND 0x01
|
|
#define TYPE_MAINWIN 0x11
|
|
#define TYPE_CONTROL 0x12
|
|
#define TYPE_ROOTWIN 0x13
|
|
#define TYPE_VIRTWIN 0x14
|
|
#define TYPE_HMENU 0x02
|
|
#define TYPE_MENUBAR 0x21
|
|
#define TYPE_PPPMENU 0x22
|
|
#define TYPE_NMLMENU 0x23
|
|
#define TYPE_HACCEL 0x03
|
|
#define TYPE_HCURSOR 0x05
|
|
#define TYPE_HICON 0x07
|
|
#define TYPE_HDC 0x08
|
|
#define TYPE_SCRDC 0x81
|
|
#define TYPE_GENDC 0x82
|
|
#define TYPE_MEMDC 0x83
|
|
|
|
#define TYPE_WINTODEL 0xF1
|
|
#define TYPE_UNDEFINED 0xFF
|
|
|
|
struct GAL_Surface;
|
|
struct _MAINWIN;
|
|
typedef struct _MAINWIN* PMAINWIN;
|
|
|
|
struct _TIMER;
|
|
typedef struct _TIMER TIMER;
|
|
|
|
typedef struct _SCROLLWINDOWINFO
|
|
{
|
|
int iOffx;
|
|
int iOffy;
|
|
const RECT* rc1;
|
|
const RECT* rc2;
|
|
} SCROLLWINDOWINFO;
|
|
typedef SCROLLWINDOWINFO* PSCROLLWINDOWINFO;
|
|
|
|
typedef struct _CARETINFO {
|
|
int x; // position of caret
|
|
int y;
|
|
void* pNormal; // normal bitmap.
|
|
void* pXored; // bit-Xored bitmap.
|
|
|
|
PBITMAP pBitmap; // user defined caret bitmap.
|
|
|
|
int nWidth; // original size of caret
|
|
int nHeight;
|
|
int nBytesNr; // number of bitmap bytes.
|
|
|
|
BITMAP caret_bmp; // bitmap of caret.
|
|
|
|
BOOL fBlink; // does blink?
|
|
BOOL fShow; // show or hide currently.
|
|
|
|
HWND hOwner; // the window owns the caret.
|
|
UINT uTime; // the blink time.
|
|
} CARETINFO;
|
|
typedef CARETINFO* PCARETINFO;
|
|
|
|
/* ime status info */
|
|
typedef struct _IME_STATUS_INFO
|
|
{
|
|
HWND hWnd;
|
|
BYTE bEnabled;
|
|
BYTE bAutoTrack;
|
|
BYTE reserved[2];
|
|
IME_TARGET_INFO TargetInfo;
|
|
} IME_STATUS_INFO;
|
|
|
|
typedef struct _QMSG
|
|
{
|
|
MSG Msg;
|
|
struct _QMSG* next;
|
|
} QMSG;
|
|
typedef QMSG* PQMSG;
|
|
|
|
typedef struct _MSGQUEUE MSGQUEUE;
|
|
typedef MSGQUEUE* PMSGQUEUE;
|
|
|
|
#ifdef _MGHAVE_VIRTUAL_WINDOW
|
|
typedef struct _SYNCMSG
|
|
{
|
|
MSG Msg;
|
|
LRESULT retval;
|
|
sem_t* sem_handle;
|
|
struct _SYNCMSG* pNext;
|
|
} SYNCMSG;
|
|
typedef SYNCMSG* PSYNCMSG;
|
|
#endif /* defined _MGHAVE_VIRTUAL_WINDOW */
|
|
|
|
typedef BOOL (* IDLEHANDLER) (PMSGQUEUE msg_queue, BOOL wait);
|
|
|
|
#ifdef HAVE_SELECT
|
|
typedef struct _LISTEN_FD {
|
|
int type;
|
|
int fd;
|
|
void* hwnd;
|
|
void* context;
|
|
} LISTEN_FD;
|
|
#endif /* defined HAVE_SELECT */
|
|
|
|
#define QS_NOTIFYMSG 0x10000000
|
|
#ifdef _MGHAVE_VIRTUAL_WINDOW
|
|
#define QS_SYNCMSG 0x20000000
|
|
#endif
|
|
#define QS_POSTMSG 0x40000000
|
|
#define QS_QUIT 0x80000000
|
|
#define QS_INPUT 0x01000000
|
|
#define QS_PAINT 0x02000000
|
|
#define QS_DESKTIMER 0x04000000
|
|
#define QS_EMPTY 0x00000000
|
|
|
|
// the MSGQUEUE struct is an internal struct.
|
|
// use semaphores to implement message queue.
|
|
struct _MSGQUEUE
|
|
{
|
|
#ifdef _MGHAVE_VIRTUAL_WINDOW
|
|
struct list_head list; // for managing message threads
|
|
pthread_t th; // the thread identifier this message queue lives
|
|
// moved from window structures since 5.0.0.
|
|
pthread_mutex_t lock; // lock
|
|
sem_t wait; // the semaphore for wait message
|
|
//sem_t sync_msg; // the semaphore for sync message; deprecated
|
|
#endif
|
|
|
|
DWORD dwState; // message queue states
|
|
PQMSG pFirstNotifyMsg; // head of the notify message queue
|
|
PQMSG pLastNotifyMsg; // tail of the notify message queue
|
|
|
|
#ifdef _MGHAVE_VIRTUAL_WINDOW
|
|
PSYNCMSG pFirstSyncMsg; // head of the sync message queue
|
|
PSYNCMSG pLastSyncMsg; // tail of the sync message queue
|
|
#endif
|
|
|
|
IDLEHANDLER OnIdle; // idle handler for this message queue.
|
|
|
|
PMAINWIN pRootMainWin; // the root main window of this message queue.
|
|
int nrWindows; // the number of main/virtual windows.
|
|
|
|
/* buffer for post message */
|
|
int len; // buffer length
|
|
MSG* msg; // post message buffer
|
|
int readpos, writepos; // positions for reading and writing
|
|
|
|
int loop_depth; // message loop depth, for dialog boxes
|
|
|
|
int idle_counter; // the idle connter for MSG_IDLE
|
|
DWORD last_ticks_desktop; // the last tick count for desktop timer
|
|
|
|
/* Since 5.0.0, MiniGUI provides support for timers per message thread */
|
|
int nr_timers; // the number of active timers
|
|
int first_timer_slot; // the first timer slot to be checked
|
|
TIMER* timer_slots [DEF_NR_TIMERS];
|
|
// slots for timer
|
|
DWORD old_tick_count; // the old tick count.
|
|
DWORD expired_timer_mask; // timer slots mask
|
|
|
|
#ifdef HAVE_SELECT
|
|
/* Since 5.0.0, MiniGUI supports listening file descriptors
|
|
per message thread */
|
|
int nr_fd_slots;
|
|
int maxfd, nr_rfds, nr_wfds, nr_efds;
|
|
fd_set rfdset;
|
|
fd_set wfdset;
|
|
fd_set efdset;
|
|
LISTEN_FD** fd_slots;
|
|
#endif
|
|
};
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif /* __cplusplus */
|
|
|
|
BOOL mg_InitFreeQMSGList (void);
|
|
void mg_DestroyFreeQMSGList (void);
|
|
BOOL mg_InitMsgQueue (PMSGQUEUE pMsgQueue, int iBufferLen);
|
|
void mg_DestroyMsgQueue (PMSGQUEUE pMsgQueue);
|
|
BOOL kernel_QueueMessage (PMSGQUEUE pMsgQueue, PMSG pMsg);
|
|
|
|
/* Since 5.0.0 */
|
|
int __mg_broadcast_message (PMSGQUEUE msg_queue, MSG* msg);
|
|
|
|
/* Since 5.0.0 */
|
|
#ifdef HAVE_SELECT
|
|
int __mg_kernel_check_listen_fds (MSGQUEUE* msg_queue,
|
|
fd_set* rsetptr, fd_set* wsetptr, fd_set* esetptr);
|
|
#endif /* defined HAVE_SELECT */
|
|
|
|
extern PMSGQUEUE __mg_dsk_msg_queue;
|
|
|
|
#if 0 /* deprecated code */
|
|
/* Since 5.0.0, we do not use quiting stage */
|
|
/* Running stages */
|
|
#define _MG_QUITING_STAGE_RUNNING 1
|
|
/* Try to quit main thread, and for MiniGUI-Threads, to quit
|
|
other main window threads */
|
|
#define _MG_QUITING_STAGE_START (-10)
|
|
/* Force to quit main thread, and other main window threads */
|
|
#define _MG_QUITING_STAGE_FORCE (-15)
|
|
/* Quit Desktop thread (MiniGUI-Threads only) */
|
|
#define _MG_QUITING_STAGE_DESKTOP (-20)
|
|
/* Quit EventLoop (MiniGUI-Threads only) */
|
|
#define _MG_QUITING_STAGE_EVENT (-30)
|
|
/* Quit TimerEntry (MiniGUI-Threads only) */
|
|
#define _MG_QUITING_STAGE_TIMER (-40)
|
|
extern int __mg_quiting_stage;
|
|
#endif /* deprecated code */
|
|
|
|
static inline BOOL QueueDeskMessage (PMSG msg)
|
|
{
|
|
return kernel_QueueMessage (__mg_dsk_msg_queue, msg);
|
|
}
|
|
|
|
#ifndef _MGRM_THREADS
|
|
static inline void SetDskIdleHandler (IDLEHANDLER idle_handler)
|
|
{
|
|
__mg_dsk_msg_queue->OnIdle = idle_handler;
|
|
}
|
|
#endif /* not defined _MGRM_THREADS */
|
|
|
|
#ifdef _MGHAVE_VIRTUAL_WINDOW
|
|
|
|
#define MG_MUTEX_INIT(lock) pthread_mutex_init(lock, NULL)
|
|
#define MG_MUTEX_DESTROY(lock) pthread_mutex_destroy(lock)
|
|
#define MG_MUTEX_LOCK(lock) pthread_mutex_lock(lock)
|
|
#define MG_MUTEX_UNLOCK(lock) pthread_mutex_unlock(lock)
|
|
|
|
#define POST_MSGQ(pMsgQueue) \
|
|
do { \
|
|
int sem_value; \
|
|
/* Signal that the msg queue contains one more element for reading */ \
|
|
sem_getvalue (&(pMsgQueue)->wait, &sem_value); \
|
|
if (sem_value <= 0) {\
|
|
sem_post(&(pMsgQueue)->wait); \
|
|
} \
|
|
} while(0)
|
|
|
|
#else /* defined _MGHAVE_VIRTUAL_WINDOW */
|
|
|
|
#define MG_MUTEX_INIT(lock)
|
|
#define MG_MUTEX_DESTROY(lock)
|
|
#define MG_MUTEX_LOCK(lock)
|
|
#define MG_MUTEX_UNLOCK(lock)
|
|
|
|
#define POST_MSGQ(pMsgQueue)
|
|
|
|
#endif /* not defined _MGHAVE_VIRTUAL_WINDOW */
|
|
|
|
#define LOCK_MSGQ(pMsgQueue) MG_MUTEX_LOCK(&(pMsgQueue)->lock)
|
|
#define UNLOCK_MSGQ(pMsgQueue) MG_MUTEX_UNLOCK(&(pMsgQueue)->lock)
|
|
|
|
struct _wnd_element_data;
|
|
|
|
#define WF_ERASEBKGND 0x01 // flag to erase bkground or not
|
|
|
|
/* Since 5.0.0 */
|
|
typedef struct _VIRTWIN
|
|
{
|
|
/*
|
|
* Fields for data type
|
|
*/
|
|
unsigned char DataType; // the data type.
|
|
unsigned char WinType; // the window type, always be TYPE_VIRTWIN.
|
|
unsigned short Flags; // some flags for this viritual window.
|
|
|
|
/*
|
|
* Fields for both virtual window and main window.
|
|
*/
|
|
//pthread_t th; // the thread which creates this virtual window.
|
|
// moved to message queue structure since 5.0.0.
|
|
PMSGQUEUE pMsgQueue; // the message queue.
|
|
|
|
char* spCaption; // the caption of main window.
|
|
LINT id; // the identifier of main window.
|
|
|
|
WNDPROC WndProc; // the window procedure of this virtual window.
|
|
NOTIFPROC NotifProc; // the notification callback procedure (no use).
|
|
|
|
DWORD dwAddData; // the additional data.
|
|
DWORD dwAddData2; // the second addtional data.
|
|
|
|
map_t* mapLocalData; // the map of local data.
|
|
|
|
struct _VIRTWIN* pMainWin; // the main window that contains this window.
|
|
// for virtual window, always be itself.
|
|
struct _VIRTWIN* pHosting; // the hosting virtual window.
|
|
struct _VIRTWIN* pFirstHosted; // the first hosted virtual window.
|
|
struct _VIRTWIN* pNextHosted; // the next hosted virtual window.
|
|
} VIRTWIN;
|
|
typedef struct _VIRTWIN* PVIRTWIN;
|
|
|
|
// the structure represents a real main window.
|
|
typedef struct _MAINWIN
|
|
{
|
|
/*
|
|
* These following fields are similiar with CONTROL struct.
|
|
*/
|
|
|
|
/*
|
|
* Fields for data type
|
|
* VM[2020-02-14]: Move these fields back to support virtual main window.
|
|
* VM[2018-01-18]: Move these fields from header to here to compatible with
|
|
* WINDOWINFO
|
|
*/
|
|
unsigned char DataType; // the data type.
|
|
unsigned char WinType; // the window type.
|
|
unsigned short Flags; // special runtime flags, such EraseBkGnd flags
|
|
|
|
/*
|
|
* Common fields for control, virtual window, and main window.
|
|
* VM[2020-02-14]: Move these fields to header to support virtual window.
|
|
*/
|
|
// pthread_t th; // the thread which creates this main window.
|
|
// moved to message queue structure since 5.0.0.
|
|
PMSGQUEUE pMsgQueue; // the message queue.
|
|
|
|
char* spCaption; // the caption of main window.
|
|
LINT id; // the identifier of main window.
|
|
|
|
WNDPROC MainWindowProc; // the window procedure of this main window.
|
|
NOTIFPROC NotifProc; // the notification callback procedure.
|
|
|
|
DWORD dwAddData; // the additional data.
|
|
DWORD dwAddData2; // the second addtional data.
|
|
|
|
map_t* mapLocalData; // the map of local data.
|
|
|
|
/*
|
|
* The following members are implemented for main window and virtual window.
|
|
*/
|
|
struct _MAINWIN* pMainWin; // the main window that contains this window.
|
|
// for main window, always be itself.
|
|
struct _MAINWIN* pHosting; // the hosting main window.
|
|
struct _MAINWIN* pFirstHosted; // the first hosted main window.
|
|
struct _MAINWIN* pNextHosted; // the next hosted main window.
|
|
|
|
/*
|
|
* Fields for appearance of this main window.
|
|
*/
|
|
int left, top; // the position and size of main window.
|
|
int right, bottom;
|
|
|
|
int cl, ct; // the position and size of client area.
|
|
int cr, cb;
|
|
|
|
DWORD dwStyle; // the styles of main window.
|
|
DWORD dwExStyle; // the extended styles of main window.
|
|
|
|
int idx_znode; // the index of the z-node.
|
|
//gal_pixel iFgColor; // the foreground color.
|
|
gal_pixel iBkColor; // the background color.
|
|
|
|
HMENU hMenu; // handle of menu.
|
|
HACCEL hAccel; // handle of accelerator table.
|
|
HCURSOR hCursor; // handle of cursor.
|
|
HICON hIcon; // handle of icon.
|
|
HMENU hSysMenu; // handle of system menu.
|
|
PLOGFONT pLogFont; // pointer to logical font.
|
|
|
|
LFSCROLLBARINFO vscroll; // the vertical scroll bar information.
|
|
LFSCROLLBARINFO hscroll; // the horizital scroll bar information.
|
|
|
|
/*
|
|
* Fields for window element data.
|
|
*/
|
|
WINDOW_ELEMENT_RENDERER* we_rdr; // the window renderer
|
|
struct _wnd_element_data* wed; // the data of window elements
|
|
|
|
HDC privCDC; // the private client DC.
|
|
INVRGN InvRgn; // the invalid region of this main window.
|
|
#ifdef _MGSCHEMA_COMPOSITING
|
|
struct GAL_Surface* surf; // the shared surface of this main window.
|
|
#else
|
|
PGCRINFO pGCRInfo; // pointer to global clip region info struct.
|
|
#endif
|
|
|
|
PCARETINFO pCaretInfo; // pointer to system caret info struct.
|
|
|
|
/*
|
|
* Fields to manage the relationship among main windows and controls.
|
|
*/
|
|
HWND hParent; // the parent of this window.
|
|
// for main window, always be HWND_NULL.
|
|
|
|
HWND hFirstChild; // the handle of first child window.
|
|
HWND hActiveChild; // the currently active child window.
|
|
HWND hOldUnderPointer; // the old child window under pointer.
|
|
HWND hPrimitive; // the premitive child of mouse event.
|
|
|
|
/*
|
|
* The following members are only implemented for main window.
|
|
*/
|
|
#ifndef _MGSCHEMA_COMPOSITING
|
|
GCRINFO GCRInfo; // the global clip region info struct.
|
|
// put here to avoid invoking malloc function.
|
|
#endif
|
|
|
|
// the controls as main window
|
|
HWND hFirstChildAsMainWin;
|
|
|
|
HDC secondaryDC; // the secondary window dc.
|
|
ON_UPDATE_SECONDARYDC update_secdc; // the callback of secondary window dc
|
|
RECT update_rc;
|
|
} MAINWIN;
|
|
|
|
/* Structure defines a message hook function; moved here since 5.0.0 */
|
|
typedef struct _HOOKINFO
|
|
{
|
|
/* the pointer to the hook function. */
|
|
MSGHOOK hook;
|
|
/* the context which will be passed to the hook function. */
|
|
void* context;
|
|
} HOOKINFO;
|
|
|
|
/* since 5.0.0 */
|
|
int __mg_check_hook_func (int event_type, const MSG* msg);
|
|
int __mg_check_hook_wins (int event_type,
|
|
UINT uMsg, WPARAM wParam, LPARAM lParam);
|
|
int __mg_free_hook_wins (int cli);
|
|
|
|
/************************* Initialization/Termination ************************/
|
|
void __mg_init_local_sys_text (void);
|
|
|
|
/* the zorder information for the default layer */
|
|
extern ZORDERINFO* __mg_def_zorder_info;
|
|
|
|
/* the zorder information for the current layer */
|
|
extern ZORDERINFO* __mg_zorder_info;
|
|
|
|
#ifdef _MGRM_STANDALONE
|
|
|
|
BOOL salone_IdleHandler4StandAlone (PMSGQUEUE msg_que, BOOL wait);
|
|
BOOL salone_StandAloneStartup (void);
|
|
void salone_StandAloneCleanup (void);
|
|
|
|
#elif defined (_MGRM_PROCESSES)
|
|
|
|
/*
|
|
* Common for server and client.
|
|
*/
|
|
|
|
/* the client id is zero for the server */
|
|
extern int __mg_client_id;
|
|
|
|
BOOL kernel_IsOnlyMe (void);
|
|
void* kernel_LoadSharedResource (void);
|
|
void kernel_UnloadSharedResource (void);
|
|
BOOL server_IdleHandler4Server (PMSGQUEUE msg_que, BOOL wait);
|
|
void server_ServerCleanup (void);
|
|
|
|
/* Only for client. */
|
|
void* kernel_AttachSharedResource (void);
|
|
void kernel_UnattachSharedResource (void);
|
|
BOOL client_IdleHandler4Client (PMSGQUEUE msg_que, BOOL wait);
|
|
BOOL client_ClientStartup (void);
|
|
void client_ClientCleanup (void);
|
|
|
|
#endif /* defined (_MGRM_PROCESSES) */
|
|
|
|
BOOL mg_InitScreenDC (void);
|
|
void mg_TerminateScreenDC (void);
|
|
|
|
BOOL mg_InitGDI (void);
|
|
void mg_TerminateGDI (void);
|
|
|
|
BOOL mg_InitFixStr (void);
|
|
void mg_TerminateFixStr (void);
|
|
|
|
BOOL mg_InitMenu (void);
|
|
void mg_TerminateMenu (void);
|
|
|
|
BOOL mg_InitDesktop (void);
|
|
void mg_TerminateDesktop (void);
|
|
|
|
/* send MSG_IME_OPEN/CLOSE message to ime window */
|
|
void __gui_open_ime_window (PMAINWIN pWin, BOOL open_close, HWND rev_hwnd);
|
|
|
|
PMAINWIN gui_GetMainWindowPtrUnderPoint (int x, int y);
|
|
|
|
/* return the next window need to repaint. */
|
|
HWND kernel_CheckInvalidRegion (PMAINWIN pWin);
|
|
|
|
/* internal variables */
|
|
typedef struct _TRACKMENUINFO* PTRACKMENUINFO;
|
|
|
|
extern HWND __mg_captured_wnd;
|
|
extern HWND __mg_ime_wnd;
|
|
extern HWND __mg_hwnd_desktop;
|
|
extern DWORD __mg_tick_counter;
|
|
extern PMAINWIN __mg_dsk_win;
|
|
|
|
#if 0 /* Since 5.0.0: deprecated */
|
|
#ifndef _MGRM_PROCESSES
|
|
extern PMAINWIN __mg_active_mainwnd;
|
|
extern PTRACKMENUINFO __mg_ptmi;
|
|
#endif
|
|
#endif /* Since 5.0.0: deprecated */
|
|
|
|
extern LRESULT SendSyncMessage (HWND hWnd,
|
|
UINT msg, WPARAM wParam, LPARAM lParam);
|
|
|
|
#ifndef _MGRM_THREADS
|
|
# ifndef _MGSCHEMA_COMPOSITING
|
|
extern unsigned int __mg_csrimgsize;
|
|
extern unsigned int __mg_csrimgpitch;
|
|
# endif
|
|
#else /* not defined _MGRM_THREADS */
|
|
extern pthread_mutex_t __mg_gdilock, __mg_mouselock;
|
|
#endif /* defined _MGRM_THREADS */
|
|
|
|
/* hWnd is a window, including HWND_DESKTOP */
|
|
#define MG_IS_WINDOW(hWnd) \
|
|
(hWnd && hWnd != HWND_INVALID && \
|
|
((PMAINWIN)hWnd)->DataType == TYPE_HWND)
|
|
|
|
/* Whether hWnd is an window created by app */
|
|
#define MG_IS_APP_WINDOW(hWnd) \
|
|
(hWnd && hWnd != HWND_INVALID && \
|
|
hWnd != HWND_DESKTOP && \
|
|
((PMAINWIN)hWnd)->DataType == TYPE_HWND)
|
|
|
|
/* Changede since 5.0.0.
|
|
Whether hWnd is a normal window (a main window or a control),
|
|
not including HWND_DESKTOP */
|
|
#define MG_IS_NORMAL_WINDOW(hWnd) \
|
|
(MG_IS_WINDOW(hWnd) && hWnd != HWND_DESKTOP && \
|
|
(((PMAINWIN)hWnd)->WinType == TYPE_MAINWIN || \
|
|
((PMAINWIN)hWnd)->WinType == TYPE_CONTROL))
|
|
|
|
/* Changede since 5.0.0.
|
|
Whether hWnd is a graphics window, a main window, a control, or desktop */
|
|
#define MG_IS_GRAPHICS_WINDOW(hWnd) \
|
|
(MG_IS_WINDOW(hWnd) && \
|
|
((PMAINWIN)hWnd)->WinType != TYPE_VIRTWIN)
|
|
|
|
/* Whether hWnd is a main window, including HWND_DESKTOP */
|
|
#define MG_IS_MAIN_WINDOW(hWnd) \
|
|
(MG_IS_WINDOW(hWnd) && \
|
|
((PMAINWIN)hWnd)->WinType == TYPE_MAINWIN)
|
|
|
|
/* Whether hWnd is a virtual window */
|
|
#define MG_IS_VIRTUAL_WINDOW(hWnd) \
|
|
(MG_IS_WINDOW(hWnd) && \
|
|
((PMAINWIN)hWnd)->WinType == TYPE_VIRTWIN)
|
|
|
|
/* Whether hWnd is a control window */
|
|
#define MG_IS_CONTROL_WINDOW(hWnd) \
|
|
(MG_IS_WINDOW(hWnd) && \
|
|
((PMAINWIN)hWnd)->WinType == TYPE_CONTROL)
|
|
|
|
/* Whether hWnd is a main window or a virtual window */
|
|
#define MG_IS_MAIN_VIRT_WINDOW(hWnd) \
|
|
(MG_IS_WINDOW(hWnd) && \
|
|
(((PMAINWIN)hWnd)->WinType == TYPE_MAINWIN || \
|
|
((PMAINWIN)hWnd)->WinType == TYPE_VIRTWIN))
|
|
|
|
/* Whether hWnd is a main window or a control */
|
|
#define MG_IS_NOT_VIRT_WINDOW(hWnd) \
|
|
(MG_IS_WINDOW(hWnd) && hWnd != HWND_DESKTOP \
|
|
(((PMAINWIN)hWnd)->WinType == TYPE_MAINWIN || \
|
|
((PMAINWIN)hWnd)->WinType == TYPE_CONTROL))
|
|
|
|
#define MG_IS_NORMAL_MAIN_WINDOW(hWnd) \
|
|
(hWnd != HWND_DESKTOP && MG_IS_MAIN_WINDOW(hWnd))
|
|
|
|
#define MG_IS_DESTROYED_WINDOW(hWnd) \
|
|
(hWnd && hWnd != HWND_INVALID && \
|
|
(((PMAINWIN)hWnd)->DataType == TYPE_WINTODEL))
|
|
|
|
#define MG_IS_DESTROYED_MAIN_WINDOW(hWnd) \
|
|
(hWnd && hWnd != HWND_INVALID && \
|
|
(((PMAINWIN)hWnd)->DataType == TYPE_WINTODEL) && \
|
|
(((PMAINWIN)hWnd)->WinType == TYPE_MAINWIN))
|
|
|
|
#define MG_IS_DESTROYED_VIRT_WINDOW(hWnd) \
|
|
(hWnd && hWnd != HWND_INVALID && \
|
|
(((PMAINWIN)hWnd)->DataType == TYPE_WINTODEL) && \
|
|
(((PMAINWIN)hWnd)->WinType == TYPE_VIRTWIN))
|
|
|
|
#define MG_GET_WINDOW_PTR(hWnd) ((PMAINWIN)hWnd)
|
|
#define MG_GET_MAIN_WINDOW_PTR(hWnd) ((PMAINWIN)hWnd)
|
|
#define MG_GET_CONTROL_PTR(hWnd) ((PCONTROL)hWnd)
|
|
#define MG_GET_VIRTUAL_WINDOW_PTR(hWnd) ((PVIRTWIN)hWnd)
|
|
|
|
#define MG_CHECK_RET(condition, ret) \
|
|
if (!(condition)) return ret
|
|
|
|
#define MG_CHECK(condition) \
|
|
if (!(condition)) return
|
|
|
|
/* check whether hWnd is a main window and return the pointer to it. */
|
|
static inline PMAINWIN checkAndGetMainWinIfMainWin (HWND hWnd)
|
|
{
|
|
MG_CHECK_RET (MG_IS_NORMAL_MAIN_WINDOW (hWnd), NULL);
|
|
return MG_GET_WINDOW_PTR (hWnd);
|
|
}
|
|
|
|
/* return main window contains a control. */
|
|
static inline PMAINWIN checkAndGetMainWinIfWindow (HWND hWnd)
|
|
{
|
|
PMAINWIN pWin;
|
|
|
|
MG_CHECK_RET (MG_IS_NORMAL_WINDOW(hWnd), NULL);
|
|
pWin = MG_GET_WINDOW_PTR (hWnd);
|
|
|
|
return pWin->pMainWin;
|
|
}
|
|
|
|
/* return main window contains a control. */
|
|
static inline PMAINWIN checkAndGetMainWindowIfControl (HWND hWnd)
|
|
{
|
|
PMAINWIN pWin;
|
|
|
|
MG_CHECK_RET (MG_IS_CONTROL_WINDOW(hWnd), NULL);
|
|
pWin = MG_GET_WINDOW_PTR (hWnd);
|
|
|
|
return pWin->pMainWin;
|
|
}
|
|
|
|
static inline PVIRTWIN getVirtWinIfDestroyed (HWND hWnd)
|
|
{
|
|
PVIRTWIN pVirtWin = (PVIRTWIN)hWnd;
|
|
|
|
if (hWnd && hWnd != HWND_INVALID &&
|
|
(pVirtWin->DataType == TYPE_WINTODEL) &&
|
|
(pVirtWin->WinType == TYPE_VIRTWIN)) {
|
|
return pVirtWin;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
static inline PMAINWIN getMainWinIfDestroyed (HWND hWnd)
|
|
{
|
|
PMAINWIN pMainWin = (PMAINWIN)hWnd;
|
|
|
|
if (hWnd && hWnd != HWND_INVALID &&
|
|
(pMainWin->DataType == TYPE_WINTODEL) &&
|
|
(pMainWin->WinType == TYPE_MAINWIN)) {
|
|
return pMainWin;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
/* get main window pointer of a window, including desktop window */
|
|
static inline PMAINWIN getMainWindowPtr (HWND hWnd)
|
|
{
|
|
PMAINWIN pWin;
|
|
|
|
MG_CHECK_RET (MG_IS_WINDOW(hWnd), NULL);
|
|
pWin = MG_GET_WINDOW_PTR (hWnd);
|
|
|
|
return pWin->pMainWin;
|
|
}
|
|
|
|
/* Get message queue by window handle.
|
|
Note that hWnd may belong to a different thread. */
|
|
static inline PMSGQUEUE getMsgQueue (HWND hWnd)
|
|
{
|
|
PMAINWIN pWin;
|
|
pWin = getMainWindowPtr (hWnd);
|
|
if (pWin)
|
|
return pWin->pMsgQueue;
|
|
return NULL;
|
|
}
|
|
|
|
|
|
MSGQUEUE* mg_AllocMsgQueueForThisThread (BOOL sign_in);
|
|
void mg_FreeMsgQueueForThisThread (BOOL sign_off);
|
|
|
|
/* Since 5.0.0 */
|
|
int __mg_throw_away_messages (PMSGQUEUE pMsgQueue, HWND hWnd);
|
|
|
|
#ifdef _MGHAVE_VIRTUAL_WINDOW
|
|
|
|
extern pthread_key_t __mg_threadinfo_key;
|
|
|
|
#define TEST_CANCEL pthread_testcancel()
|
|
int __mg_join_all_message_threads (void);
|
|
|
|
static inline BOOL createThreadInfoKey (void)
|
|
{
|
|
if (pthread_key_create (&__mg_threadinfo_key, NULL))
|
|
return FALSE;
|
|
return TRUE;
|
|
}
|
|
|
|
static inline void deleteThreadInfoKey (void)
|
|
{
|
|
pthread_key_delete (__mg_threadinfo_key);
|
|
}
|
|
|
|
static inline MSGQUEUE* getMsgQueueForThisThread (void)
|
|
{
|
|
MSGQUEUE* pMsgQueue;
|
|
|
|
pMsgQueue = (MSGQUEUE*)pthread_getspecific (__mg_threadinfo_key);
|
|
#ifdef __VXWORKS__
|
|
if (pMsgQueue == (void *)-1) {
|
|
pMsgQueue = NULL;
|
|
}
|
|
#endif
|
|
|
|
return pMsgQueue;
|
|
}
|
|
|
|
static inline TIMER** getTimerSlotsForThisThread (PMSGQUEUE* retMsgQueue)
|
|
{
|
|
MSGQUEUE* pMsgQueue;
|
|
|
|
pMsgQueue = (MSGQUEUE*)pthread_getspecific (__mg_threadinfo_key);
|
|
#ifdef __VXWORKS__
|
|
if (pMsgQueue == (void *)-1) {
|
|
pMsgQueue = NULL;
|
|
}
|
|
#endif
|
|
|
|
if (pMsgQueue) {
|
|
if (retMsgQueue) {
|
|
*retMsgQueue = pMsgQueue;
|
|
}
|
|
return pMsgQueue->timer_slots;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
/* Be careful: does not check validity of hWnd */
|
|
static inline PMAINWIN getMainWinIfWindowInThisThread (HWND hWnd)
|
|
{
|
|
PMAINWIN pMainWin = getMainWindowPtr(hWnd);
|
|
#ifdef WIN32
|
|
if (pMainWin && pMainWin->pMsgQueue->th.p == pthread_self().p)
|
|
#else
|
|
if (pMainWin && pMainWin->pMsgQueue->th == pthread_self())
|
|
#endif
|
|
return pMainWin;
|
|
|
|
return NULL;
|
|
}
|
|
|
|
static inline MSGQUEUE* getMsgQueueIfWindowInThisThread (HWND hWnd)
|
|
{
|
|
PMAINWIN pMainWin = getMainWindowPtr(hWnd);
|
|
#ifdef WIN32
|
|
if (pMainWin && pMainWin->pMsgQueue->th.p == pthread_self().p)
|
|
#else
|
|
if (pMainWin && pMainWin->pMsgQueue->th == pthread_self())
|
|
#endif
|
|
return pMainWin->pMsgQueue;
|
|
|
|
return NULL;
|
|
}
|
|
|
|
static inline MSGQUEUE* getMsgQueueIfMainWindowInThisThread (PMAINWIN pMainWin)
|
|
{
|
|
#ifdef WIN32
|
|
if (pMainWin && pMainWin->pMsgQueue->th.p == pthread_self().p)
|
|
#else
|
|
if (pMainWin && pMainWin->pMsgQueue->th == pthread_self())
|
|
#endif
|
|
return pMainWin->pMsgQueue;
|
|
|
|
return NULL;
|
|
}
|
|
|
|
#else /* define _MGHAVE_VIRTUAL_WINDOW */
|
|
|
|
#define TEST_CANCEL
|
|
|
|
static inline MSGQUEUE* getMsgQueueForThisThread (void)
|
|
{
|
|
return __mg_dsk_msg_queue;
|
|
}
|
|
|
|
static inline TIMER** getTimerSlotsForThisThread (PMSGQUEUE* retMsgQueue)
|
|
{
|
|
if (retMsgQueue)
|
|
*retMsgQueue = __mg_dsk_msg_queue;
|
|
return __mg_dsk_msg_queue->timer_slots;
|
|
}
|
|
|
|
static inline PMAINWIN getMainWinIfWindowInThisThread (HWND hWnd)
|
|
{
|
|
return getMainWindowPtr(hWnd);
|
|
}
|
|
|
|
static inline MSGQUEUE* getMsgQueueIfWindowInThisThread (HWND hWnd)
|
|
{
|
|
return __mg_dsk_msg_queue;
|
|
}
|
|
|
|
static inline MSGQUEUE* getMsgQueueIfMainWindowInThisThread (PMAINWIN pMainWin)
|
|
{
|
|
return __mg_dsk_msg_queue;
|
|
}
|
|
|
|
#endif /* defined _MGHAVE_VIRTUAL_WINDOW */
|
|
|
|
#if 0 /* deprecated code */
|
|
/* since 5.0.0, we always use QS_DESKTIMER for desktop timer */
|
|
/* since 5.0.0, we no longer use the timer thread */
|
|
static inline void AlertDesktopTimerEvent (void)
|
|
{
|
|
if (__mg_dsk_msg_queue) {
|
|
__mg_dsk_msg_queue->expired_timer_mask = 1;
|
|
POST_MSGQ (__mg_dsk_msg_queue);
|
|
}
|
|
}
|
|
|
|
static inline void AlertDesktopTimerEvent (void)
|
|
{
|
|
__mg_dsk_msg_queue->dwState |= QS_DESKTIMER;
|
|
#ifdef _MGHAVE_VIRTUAL_WINDOW
|
|
if (getMsgQueueForThisThread() != __mg_dsk_msg_queue)
|
|
POST_MSGQ (__mg_dsk_msg_queue);
|
|
#endif /* defined _MGHAVE_VIRTUAL_WINDOW */
|
|
}
|
|
|
|
static inline void setMsgQueueTimerFlag (PMSGQUEUE pMsgQueue, int slot)
|
|
{
|
|
pMsgQueue->expired_timer_mask |= (0x01UL << slot);
|
|
POST_MSGQ (pMsgQueue);
|
|
}
|
|
|
|
static inline void removeMsgQueueTimerFlag (PMSGQUEUE pMsgQueue, int slot)
|
|
{
|
|
pMsgQueue->expired_timer_mask &= ~(0x01UL << slot);
|
|
}
|
|
#endif /* deprecated code */
|
|
|
|
BOOL mg_InitTimer (BOOL use_sys_timer);
|
|
void mg_TerminateTimer (BOOL use_sys_timer);
|
|
|
|
/*window element renderer manager interface*/
|
|
extern WINDOW_ELEMENT_RENDERER * __mg_def_renderer;
|
|
|
|
BOOL mg_InitLFManager (void);
|
|
void mg_TerminateLFManager (void);
|
|
|
|
char* gui_GetIconFile(const char* rdr_name, char* file, char* _szValue);
|
|
BOOL gui_LoadIconRes(HDC hdc, const char* rdr_name, char* file);
|
|
|
|
void gui_WndRect(HWND hWnd, PRECT prc);
|
|
void gui_WndClientRect(HWND hWnd, PRECT prc);
|
|
|
|
/* Undisclosed APIs */
|
|
HDC CreateMemDCFromSurface (struct GAL_Surface* surface);
|
|
struct GAL_Surface* GetSurfaceFromDC (HDC hdc);
|
|
|
|
/* Since 5.0.0 */
|
|
#ifdef _MGRM_PROCESSES
|
|
struct _SemSetManager;
|
|
typedef struct _SemSetManager SemSetManager;
|
|
|
|
SemSetManager* __mg_create_sem_set_manager (int semid, int nr_sems);
|
|
void __mg_delete_sem_set_manager (int code, void* manager);
|
|
int __mg_alloc_mutual_sem (SemSetManager* manager, int *semid);
|
|
int __mg_free_mutual_sem (SemSetManager* manager, int sem_num);
|
|
#endif /* _MGRM_PROCESSES */
|
|
|
|
/* Since 5.0.0 */
|
|
#ifdef _MGSCHEMA_COMPOSITING
|
|
BOOL mg_InitCompositor (void);
|
|
void mg_TerminateCompositor (void);
|
|
void __mg_composite_dirty_znodes (void);
|
|
#endif
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif /* __cplusplus */
|
|
|
|
#endif // GUI_INTERNALS_H
|
|
|