mirror of
https://github.com/VincentWei/MiniGUI.git
synced 2026-09-30 06:23:22 +08:00
911 lines
23 KiB
C
911 lines
23 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~2018, 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/>.
|
|
*/
|
|
/*
|
|
** lf_manager.c: The Look and Feel manager file.
|
|
*/
|
|
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
#include "common.h"
|
|
#include "minigui.h"
|
|
#include "gdi.h"
|
|
#include "window.h"
|
|
#include "cliprect.h"
|
|
#include "gal.h"
|
|
#include "internals.h"
|
|
#include "element.h"
|
|
|
|
/* The default maximum number of LF renderers */
|
|
#define MAX_NR_RENDERERS 6
|
|
|
|
typedef struct _LFINFO {
|
|
char name[LEN_RENDERER_NAME + 1];
|
|
WINDOW_ELEMENT_RENDERER * wnd_rdr;
|
|
} LFINFO;
|
|
|
|
extern WINDOW_ELEMENT_RENDERER __mg_wnd_rdr_classic;
|
|
|
|
#ifdef _MGLF_RDR_FLAT
|
|
extern WINDOW_ELEMENT_RENDERER __mg_wnd_rdr_flat;
|
|
#endif
|
|
|
|
#ifdef _MGLF_RDR_SKIN
|
|
extern WINDOW_ELEMENT_RENDERER __mg_wnd_rdr_skin;
|
|
#endif
|
|
|
|
#ifdef _MGRM_THREADS
|
|
/** For MiniGUI renderer manager. */
|
|
static pthread_mutex_t gRendererMmutex;
|
|
#endif
|
|
|
|
static LFINFO wnd_lf_info [MAX_NR_RENDERERS] =
|
|
{
|
|
{"classic", &__mg_wnd_rdr_classic},
|
|
#ifdef _MGLF_RDR_FLAT
|
|
{"flat", &__mg_wnd_rdr_flat},
|
|
#endif
|
|
#ifdef _MGLF_RDR_SKIN
|
|
{"skin", &__mg_wnd_rdr_skin},
|
|
#endif
|
|
};
|
|
|
|
/** The default renderer */
|
|
WINDOW_ELEMENT_RENDERER * __mg_def_renderer = &__mg_wnd_rdr_classic;
|
|
|
|
WINDOW_ELEMENT_RENDERER* GUIAPI GetWindowRendererFromName (const char* name)
|
|
{
|
|
int i;
|
|
if (NULL == name)
|
|
return NULL;
|
|
for (i = 0; i < MAX_NR_RENDERERS; ++i)
|
|
{
|
|
/** find matching renderer by name which is case-insensitive */
|
|
if (0 == strcasecmp (name, wnd_lf_info[i].name))
|
|
{
|
|
return wnd_lf_info[i].wnd_rdr;
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
BOOL GUIAPI AddWindowElementRenderer (const char* name,
|
|
const WINDOW_ELEMENT_RENDERER* we_rdr)
|
|
{
|
|
int i;
|
|
int available_pos = -1;
|
|
if (NULL == name || '\0' == name[0] || NULL == we_rdr)
|
|
return FALSE;
|
|
|
|
#ifdef _MGRM_THREADS
|
|
pthread_mutex_lock (&gRendererMmutex);
|
|
#endif
|
|
|
|
for (i = 0; i < MAX_NR_RENDERERS; ++i)
|
|
{
|
|
/** find matching renderer by name which is case-insensitive */
|
|
if (0 == strcasecmp (name, wnd_lf_info[i].name))
|
|
{
|
|
available_pos = -1;
|
|
break;
|
|
}
|
|
|
|
/** find available slot */
|
|
if (-1 == available_pos && '\0' == wnd_lf_info[i].name[0])
|
|
{
|
|
available_pos = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
/** no available slot */
|
|
if (-1 == available_pos)
|
|
{
|
|
#ifdef _MGRM_THREADS
|
|
pthread_mutex_unlock (&gRendererMmutex);
|
|
#endif
|
|
return FALSE;
|
|
}
|
|
|
|
/** get available slot */
|
|
strncpy (wnd_lf_info[i].name, name, LEN_RENDERER_NAME);
|
|
wnd_lf_info[i].name[LEN_RENDERER_NAME] = '\0';
|
|
wnd_lf_info[i].wnd_rdr = (WINDOW_ELEMENT_RENDERER*) we_rdr;
|
|
|
|
/** initialize renderer private info */
|
|
if (0 != we_rdr->init ((WINDOW_ELEMENT_RENDERER*)we_rdr))
|
|
{
|
|
#ifdef _MGRM_THREADS
|
|
pthread_mutex_unlock (&gRendererMmutex);
|
|
#endif
|
|
return FALSE;
|
|
}
|
|
|
|
#ifdef _MGRM_THREADS
|
|
pthread_mutex_unlock (&gRendererMmutex);
|
|
#endif
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL GUIAPI RemoveWindowElementRenderer (const char* name)
|
|
{
|
|
int i;
|
|
BOOL find = FALSE;
|
|
if (NULL == name)
|
|
return FALSE;
|
|
|
|
#ifdef _MGRM_THREADS
|
|
pthread_mutex_lock (&gRendererMmutex);
|
|
#endif
|
|
|
|
/** find matching renderer by name which is case-insensitive */
|
|
for (i = 0; i < MAX_NR_RENDERERS; ++i)
|
|
{
|
|
if (0 == strcasecmp (name, wnd_lf_info[i].name))
|
|
{
|
|
find = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
/** find it out, then continue*/
|
|
if (FALSE == find || NULL == wnd_lf_info[i].wnd_rdr
|
|
|| 0 != wnd_lf_info[i].wnd_rdr->refcount)
|
|
{
|
|
#ifdef _MGRM_THREADS
|
|
pthread_mutex_unlock (&gRendererMmutex);
|
|
#endif
|
|
return FALSE;
|
|
}
|
|
|
|
/** release and clean renderer data as refcount is 0 */
|
|
wnd_lf_info[i].wnd_rdr->deinit (wnd_lf_info[i].wnd_rdr);
|
|
wnd_lf_info[i].wnd_rdr = NULL;
|
|
wnd_lf_info[i].name[0] = '\0';
|
|
|
|
#ifdef _MGRM_THREADS
|
|
pthread_mutex_unlock (&gRendererMmutex);
|
|
#endif
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
WINDOW_ELEMENT_RENDERER * GUIAPI GetDefaultWindowElementRenderer (void)
|
|
{
|
|
return __mg_def_renderer;
|
|
}
|
|
|
|
const char* GUIAPI SetDefaultWindowElementRenderer (const char* name)
|
|
{
|
|
int i;
|
|
BOOL find = FALSE;
|
|
const char* old_name;
|
|
|
|
if (NULL == name || '\0' == name[0])
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
/** return if default renderer is not different */
|
|
if (0 == strcasecmp (name, __mg_def_renderer->name))
|
|
return __mg_def_renderer->name;
|
|
|
|
/** find matching renderer by name which is case-insensitive */
|
|
for (i = 0; i < MAX_NR_RENDERERS; ++i)
|
|
{
|
|
if (0 == strcasecmp (name, wnd_lf_info[i].name))
|
|
{
|
|
find = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
/** find it out, then continue*/
|
|
if (FALSE == find)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
old_name = __mg_def_renderer->name;
|
|
/** reset new renderer as different name which is case-insensitive */
|
|
__mg_def_renderer = wnd_lf_info[i].wnd_rdr;
|
|
__mg_dsk_win->we_rdr = wnd_lf_info[i].wnd_rdr;
|
|
|
|
SendMessage (HWND_DESKTOP, MSG_ERASEDESKTOP, 0, 0);
|
|
return old_name;
|
|
}
|
|
|
|
BOOL GUIAPI SetWindowElementRenderer (HWND hWnd, const char* werdr_name,
|
|
const WINDOW_ELEMENT_ATTR* we_attrs)
|
|
{
|
|
int i;
|
|
BOOL update = FALSE;
|
|
WINDOW_ELEMENT_RENDERER * rdr;
|
|
PMAINWIN pwnd;
|
|
|
|
MG_CHECK_RET (MG_IS_NORMAL_WINDOW (hWnd), FALSE);
|
|
pwnd = MG_GET_WINDOW_PTR(hWnd);
|
|
|
|
if (NULL == pwnd ||
|
|
((NULL == werdr_name || '\0' == *werdr_name) && NULL == we_attrs))
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
/** ingnore this window style */
|
|
if (pwnd->dwExStyle & WS_EX_USEPARENTRDR)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
rdr = (WINDOW_ELEMENT_RENDERER*)GetWindowRendererFromName (werdr_name);
|
|
|
|
/** change to new renderer */
|
|
if (NULL != rdr)
|
|
{
|
|
if(0 != strcasecmp (pwnd->we_rdr->name, werdr_name))
|
|
{
|
|
pwnd->we_rdr = rdr;
|
|
update = TRUE;
|
|
}
|
|
}
|
|
|
|
/** append element attributes */
|
|
if (NULL != we_attrs)
|
|
{
|
|
update = TRUE;
|
|
for (i = 0; we_attrs[i].we_attr_id != -1; ++i)
|
|
{
|
|
__mg_append_window_element_data (&pwnd->wed,
|
|
we_attrs[i].we_attr_id, we_attrs[i].we_attr);
|
|
}
|
|
}
|
|
|
|
/** update window with new renderer and attributes */
|
|
if (update)
|
|
UpdateWindow (hWnd, TRUE);
|
|
return TRUE;
|
|
}
|
|
|
|
/************ window element block data heap interface ***********/
|
|
#define WE_HEAP 1
|
|
|
|
#ifdef WE_HEAP
|
|
|
|
#define SIZE_WE_HEAP 32
|
|
static BLOCKHEAP we_heap;
|
|
|
|
/*
|
|
* init_we_heap:
|
|
*
|
|
* This function initializes a block data heap.
|
|
*
|
|
* Author: Peng LIU
|
|
* Date: 2007-11-22
|
|
*/
|
|
static void init_we_heap (void)
|
|
{
|
|
InitBlockDataHeap (&we_heap, sizeof (WND_ELEMENT_DATA), SIZE_WE_HEAP);
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* alloc_we_attr:
|
|
*
|
|
* This function request a block mem from block data heap.
|
|
*
|
|
* Author: Peng LIU
|
|
* Date: 2007-11-22
|
|
*/
|
|
static WND_ELEMENT_DATA* alloc_we_attr (void)
|
|
{
|
|
return (WND_ELEMENT_DATA*) BlockDataAlloc (&we_heap);
|
|
}
|
|
|
|
/*
|
|
* free_we_attr:
|
|
*
|
|
* This function return a block mem to block data heap.
|
|
*
|
|
* Author: Peng LIU
|
|
* Date: 2007-11-22
|
|
*/
|
|
static void free_we_attr (WND_ELEMENT_DATA* wed)
|
|
{
|
|
BlockDataFree (&we_heap, wed);
|
|
return;
|
|
}
|
|
|
|
|
|
/*
|
|
* destroy_we_heap:
|
|
*
|
|
* This function destroy block data heap.
|
|
*
|
|
* Author: Peng LIU
|
|
* Date: 2007-11-22
|
|
*/
|
|
static void destroy_we_heap (void)
|
|
{
|
|
DestroyBlockDataHeap (&we_heap);
|
|
return;
|
|
}
|
|
|
|
#endif /*End of WE_HEAP*/
|
|
|
|
/******** get/set window element interface *****************/
|
|
|
|
/*
|
|
* get_attr_from_rdr:
|
|
*
|
|
* This function get a attribute value from render.
|
|
*
|
|
* Author: Peng LIU
|
|
* Date: 2007-12-17
|
|
*/
|
|
static DWORD get_attr_from_rdr (WINDOW_ELEMENT_RENDERER *rdr, int we_attr_id)
|
|
{
|
|
int index;
|
|
|
|
index = we_attr_id & WE_ATTR_INDEX_MASK;
|
|
switch (we_attr_id & WE_ATTR_TYPE_MASK) {
|
|
|
|
case WE_ATTR_TYPE_FONT:
|
|
return (DWORD)rdr->we_fonts[index];
|
|
|
|
case WE_ATTR_TYPE_METRICS:
|
|
return (DWORD)rdr->we_metrics[index];
|
|
|
|
case WE_ATTR_TYPE_COLOR: {
|
|
int color_index = (we_attr_id & WE_ATTR_TYPE_COLOR_MASK) >> 8;
|
|
return rdr->we_colors[index][color_index];
|
|
}
|
|
|
|
case WE_ATTR_TYPE_ICON:
|
|
{
|
|
int icon_idx = (we_attr_id & WE_ATTR_TYPE_ICON_MASK) >> 8;
|
|
return (DWORD)rdr->we_icon [icon_idx][index];
|
|
}
|
|
|
|
case WE_ATTR_TYPE_RDR:
|
|
if (!rdr->on_get_rdr_attr)
|
|
break;
|
|
return rdr->on_get_rdr_attr (rdr, we_attr_id);
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
static int get_window_element_data (HWND hwnd, Uint32 id, DWORD* data)
|
|
{
|
|
PMAINWIN pwnd = (PMAINWIN)hwnd;
|
|
list_t* me;
|
|
|
|
if (pwnd == NULL)
|
|
return WED_INVARG;
|
|
|
|
if (pwnd->wed == NULL)
|
|
return WED_NODEFINED;
|
|
|
|
list_for_each (me, &pwnd->wed->list) {
|
|
WND_ELEMENT_DATA* wed;
|
|
wed = list_entry (me, WND_ELEMENT_DATA, list);
|
|
if (wed->id == id) {
|
|
*data = wed->data;
|
|
return WED_OK;
|
|
}
|
|
}
|
|
|
|
return WED_NOTFOUND;
|
|
}
|
|
|
|
int
|
|
__mg_set_window_element_data (HWND hwnd, Uint32 id, DWORD new_data, DWORD* old_data)
|
|
{
|
|
PMAINWIN pwnd = (PMAINWIN)hwnd;
|
|
WND_ELEMENT_DATA* new_wed;
|
|
list_t* me;
|
|
|
|
|
|
if (pwnd == NULL)
|
|
return WED_INVARG;
|
|
|
|
*old_data = get_attr_from_rdr (pwnd->we_rdr, id);
|
|
|
|
if ((id& WE_ATTR_TYPE_MASK) == WE_ATTR_TYPE_COLOR) {
|
|
int index = id & WE_ATTR_INDEX_MASK;
|
|
int color_index = (id & WE_ATTR_TYPE_COLOR_MASK) >> 8;
|
|
/* SetWindowBkColor.*/
|
|
if ( index == WE_WINDOW && color_index == 1) {
|
|
SetWindowBkColor(hwnd, RGBA2Pixel(HDC_SCREEN, GetRValue(new_data),
|
|
GetGValue(new_data), GetBValue(new_data), GetAValue(new_data)));
|
|
}
|
|
}
|
|
|
|
if (pwnd->wed == NULL) {
|
|
//******************* create *************************/
|
|
#ifdef WE_HEAP
|
|
pwnd->wed = alloc_we_attr ();
|
|
#else
|
|
pwnd->wed = calloc (1, sizeof (WND_ELEMENT_DATA));
|
|
#endif
|
|
|
|
if (pwnd->wed == NULL)
|
|
return WED_MEMERR;
|
|
|
|
INIT_LIST_HEAD (&pwnd->wed->list);
|
|
|
|
#ifdef WE_HEAP
|
|
new_wed = alloc_we_attr ();
|
|
#else
|
|
new_wed = calloc (1, sizeof (WND_ELEMENT_DATA));
|
|
#endif
|
|
if (new_wed == NULL)
|
|
return WED_MEMERR;
|
|
|
|
if (((id & WE_ATTR_TYPE_MASK) == WE_ATTR_TYPE_RDR)
|
|
&& pwnd->we_rdr->on_set_rdr_attr)
|
|
new_data = pwnd->we_rdr->on_set_rdr_attr (pwnd->we_rdr, id, new_data, FALSE);
|
|
|
|
new_wed->id = id;
|
|
new_wed->data = new_data;
|
|
list_add_tail (&new_wed->list, &pwnd->wed->list);
|
|
|
|
return WED_NEW_DATA;
|
|
}
|
|
else {
|
|
//******************* change *************************/
|
|
list_for_each (me, &pwnd->wed->list) {
|
|
WND_ELEMENT_DATA* wed;
|
|
wed = list_entry (me, WND_ELEMENT_DATA, list);
|
|
if (wed->id == id) {
|
|
*old_data = wed->data;
|
|
|
|
if (((id & WE_ATTR_TYPE_MASK) == WE_ATTR_TYPE_RDR)
|
|
&& pwnd->we_rdr->on_set_rdr_attr)
|
|
new_data = pwnd->we_rdr->on_set_rdr_attr (pwnd->we_rdr, id, new_data, FALSE);
|
|
|
|
if (new_data == *old_data) {
|
|
return WED_NOT_CHANGED;
|
|
}
|
|
else {
|
|
wed->data = new_data;
|
|
|
|
return WED_OK;
|
|
}
|
|
}
|
|
}
|
|
|
|
//******************* add *************************/
|
|
#ifdef WE_HEAP
|
|
new_wed = alloc_we_attr ();
|
|
#else
|
|
new_wed = calloc (1, sizeof (WND_ELEMENT_DATA));
|
|
#endif
|
|
if (new_wed == NULL)
|
|
return WED_MEMERR;
|
|
|
|
new_wed->id = id;
|
|
if (((id & WE_ATTR_TYPE_MASK) == WE_ATTR_TYPE_RDR)
|
|
&& pwnd->we_rdr->on_set_rdr_attr)
|
|
new_wed->data = pwnd->we_rdr->on_set_rdr_attr (pwnd->we_rdr, id, new_data, FALSE);
|
|
else
|
|
new_wed->data = new_data;
|
|
|
|
list_add_tail (&new_wed->list, &pwnd->wed->list);
|
|
return WED_NEW_DATA;
|
|
}
|
|
return WED_NEW_DATA;
|
|
}
|
|
|
|
int __mg_free_window_element_data (HWND hwnd)
|
|
{
|
|
PMAINWIN pwnd = (PMAINWIN)hwnd;
|
|
WND_ELEMENT_DATA* wed;
|
|
|
|
if (pwnd == NULL)
|
|
return WED_INVARG;
|
|
|
|
if (pwnd->wed == NULL)
|
|
return WED_OK;
|
|
|
|
while (!list_empty (&pwnd->wed->list)) {
|
|
wed = list_entry (pwnd->wed->list.next, WND_ELEMENT_DATA, list);
|
|
list_del (&wed->list);
|
|
#ifdef WE_HEAP
|
|
free_we_attr (wed);
|
|
#else
|
|
free (wed);
|
|
#endif
|
|
}
|
|
|
|
#ifdef WE_HEAP
|
|
free_we_attr (pwnd->wed);
|
|
#else
|
|
free (pwnd->wed);
|
|
#endif
|
|
|
|
pwnd->wed = NULL;
|
|
return WED_OK;
|
|
}
|
|
|
|
int __mg_append_window_element_data (WND_ELEMENT_DATA** wed, Uint32 id, DWORD data)
|
|
//int __mg_append_window_element_data (PMAINWIN pwnd, Uint32 id, DWORD data)
|
|
{
|
|
WND_ELEMENT_DATA* new_wed;
|
|
|
|
if (*wed == NULL) {
|
|
#ifdef WE_HEAP
|
|
*wed = alloc_we_attr ();
|
|
#else
|
|
*wed = calloc (1, sizeof (WND_ELEMENT_DATA));
|
|
#endif
|
|
if (*wed == NULL)
|
|
return WED_MEMERR;
|
|
|
|
INIT_LIST_HEAD (&(*wed)->list);
|
|
}
|
|
|
|
#ifdef WE_HEAP
|
|
new_wed = alloc_we_attr ();
|
|
#else
|
|
new_wed = calloc (1, sizeof (WND_ELEMENT_DATA));
|
|
#endif
|
|
|
|
if (new_wed == NULL)
|
|
return WED_MEMERR;
|
|
|
|
new_wed->id = id;
|
|
new_wed->data = data;
|
|
list_add_tail (&new_wed->list, &(*wed)->list);
|
|
|
|
return WED_NEW_DATA;
|
|
}
|
|
|
|
#ifdef _DEBUG
|
|
void dump_window_element_data (HWND hwnd)
|
|
{
|
|
PMAINWIN pwnd = (PMAINWIN)hwnd;
|
|
list_t* me;
|
|
WND_ELEMENT_DATA* wed;
|
|
|
|
if (pwnd == NULL)
|
|
return;
|
|
|
|
if (pwnd->wed == NULL) {
|
|
_DBG_PRINTF ("GUI>DumpWED: No attributes in list.\n");
|
|
return;
|
|
}
|
|
|
|
_DBG_PRINTF ("GUI>DumpWED: The attributes of window elements:\n");
|
|
list_for_each (me, &pwnd->wed->list) {
|
|
wed = list_entry (me, WND_ELEMENT_DATA, list);
|
|
switch (wed->id & WE_ATTR_TYPE_MASK) {
|
|
case WE_ATTR_TYPE_FONT:
|
|
_DBG_PRINTF ("\tfont in list:%s-%s-%s.\n",
|
|
((PLOGFONT)(wed->data))->type,
|
|
((PLOGFONT)(wed->data))->family,
|
|
((PLOGFONT)(wed->data))->charset);
|
|
break;
|
|
|
|
case WE_ATTR_TYPE_METRICS:
|
|
_DBG_PRINTF ("\tmetrics in list:%d.\n", (int)wed->data);
|
|
break;
|
|
|
|
case WE_ATTR_TYPE_COLOR:
|
|
_DBG_PRINTF ("\tcolor in list: %p.\n", (PVOID)wed->data);
|
|
}
|
|
}
|
|
_DBG_PRINTF ("GUI>DumpWED: Done\n");
|
|
}
|
|
|
|
#endif /* _DEBUG */
|
|
|
|
/*
|
|
* SetWindowElementAttr:
|
|
*
|
|
* This function set a attribute value.
|
|
*
|
|
* Author: Peng LIU
|
|
* Date: 2007-11-22
|
|
*/
|
|
DWORD GUIAPI SetWindowElementAttr (HWND hwnd, int we_attr_id, DWORD we_attr)
|
|
{
|
|
DWORD old_data;
|
|
int index;
|
|
|
|
if (hwnd == HWND_DESKTOP || hwnd == HWND_NULL) {
|
|
index = we_attr_id & WE_ATTR_INDEX_MASK;
|
|
switch (we_attr_id & WE_ATTR_TYPE_MASK) {
|
|
case WE_ATTR_TYPE_FONT:
|
|
old_data = (DWORD)__mg_def_renderer->we_fonts[index];
|
|
__mg_def_renderer->we_fonts[index] = (PLOGFONT)we_attr;
|
|
return old_data;
|
|
|
|
case WE_ATTR_TYPE_METRICS:
|
|
old_data = __mg_def_renderer->we_metrics[index];
|
|
__mg_def_renderer->we_metrics[index] = (int)we_attr;
|
|
return old_data;
|
|
|
|
case WE_ATTR_TYPE_COLOR: {
|
|
int color_index = (we_attr_id & WE_ATTR_TYPE_COLOR_MASK) >> 8;
|
|
old_data = (DWORD)__mg_def_renderer->we_colors[index][color_index];
|
|
__mg_def_renderer->we_colors[index][color_index] = we_attr;
|
|
return old_data;
|
|
}
|
|
|
|
case WE_ATTR_TYPE_ICON:
|
|
{
|
|
int icon_idx = (we_attr_id & WE_ATTR_TYPE_ICON_MASK) >> 8;
|
|
old_data = (DWORD)__mg_def_renderer->we_icon [icon_idx][index];
|
|
__mg_def_renderer->we_icon [icon_idx][index] = (HICON)we_attr;
|
|
return old_data;
|
|
}
|
|
|
|
case WE_ATTR_TYPE_RDR:
|
|
return __mg_def_renderer->on_set_rdr_attr (__mg_def_renderer, we_attr_id, we_attr, TRUE);
|
|
}
|
|
}
|
|
|
|
if (__mg_set_window_element_data (hwnd, we_attr_id, we_attr, &old_data) >= 0)
|
|
return old_data;
|
|
|
|
return -1;
|
|
}
|
|
|
|
|
|
/*
|
|
* GetWindowElementAttr:
|
|
*
|
|
* This function get a attribute value.
|
|
*
|
|
* Author: Peng LIU
|
|
* Date: 2007-11-22
|
|
*/
|
|
DWORD GUIAPI GetWindowElementAttr (HWND hwnd, int we_attr_id)
|
|
{
|
|
DWORD data;
|
|
WINDOW_ELEMENT_RENDERER *rdr;
|
|
PMAINWIN pwnd;
|
|
|
|
if (hwnd == HWND_DESKTOP || hwnd == HWND_NULL) {
|
|
rdr = __mg_def_renderer;
|
|
}
|
|
else {
|
|
if (get_window_element_data (hwnd, we_attr_id, &data) == WED_OK)
|
|
return (DWORD)data;
|
|
pwnd = (PMAINWIN)hwnd;
|
|
rdr = pwnd->we_rdr;
|
|
}
|
|
|
|
data = get_attr_from_rdr (rdr, we_attr_id);
|
|
return data;
|
|
}
|
|
|
|
gal_pixel GUIAPI
|
|
GetWindowElementPixelEx (HWND hwnd, HDC hdc, int we_attr_id)
|
|
{
|
|
DWORD data;
|
|
Uint8 r, g, b, a;
|
|
gal_pixel pixel;
|
|
|
|
if ((we_attr_id & WE_ATTR_TYPE_MASK) != WE_ATTR_TYPE_COLOR) {
|
|
_WRN_PRINTF ("Can't get color; invalid attr id: %x.\n", we_attr_id);
|
|
return -1;
|
|
}
|
|
|
|
data = GetWindowElementAttr (hwnd, we_attr_id);
|
|
r = GetRValue (data);
|
|
g = GetGValue (data);
|
|
b = GetBValue (data);
|
|
a = GetAValue (data);
|
|
|
|
if (hdc == HDC_INVALID) {
|
|
if (hwnd == HWND_NULL || hwnd == HWND_DESKTOP)
|
|
pixel = RGBA2Pixel (HDC_SCREEN, r, g, b, a);
|
|
else {
|
|
#ifdef _MGSCHEMA_COMPOSITING
|
|
PMAINWIN pWin = (PMAINWIN)hwnd;
|
|
pixel = GAL_MapRGBA (pWin->surf->format, r, g, b, a);
|
|
#else
|
|
pixel = RGBA2Pixel (HDC_SCREEN, r, g, b, a);
|
|
#endif
|
|
}
|
|
}
|
|
else
|
|
pixel = RGBA2Pixel (hdc, r, g, b, a);
|
|
|
|
return pixel;
|
|
}
|
|
|
|
static const char* szMWMKeyNames [WE_METRICS_NUMBER] = {
|
|
"caption",
|
|
"menu",
|
|
NULL,
|
|
NULL,
|
|
"border",
|
|
"scrollbar"
|
|
};
|
|
|
|
static const char* szCKeyNames [WE_COLORS_NUMBER][3] = {
|
|
{"fgc_active_caption", "bgca_active_caption", "bgcb_active_caption"},
|
|
{"fgc_menu", "bgc_menu"},
|
|
{"fgc_msgbox"},
|
|
{"fgc_tip", "bgc_tip"},
|
|
{"fgc_active_border", "fgc_inactive_border"},
|
|
{NULL,NULL,NULL},
|
|
{"fgc_inactive_caption", "bgca_inactive_caption", "bgcb_inactive_caption"},
|
|
{"fgc_window", "bgc_window"},
|
|
{"fgc_3dbox", "mainc_3dbox"},
|
|
{"fgc_selected_item", "bgc_selected_item", "bgc_selected_lostfocus"},
|
|
{"fgc_disabled_item", "bgc_disabled_item"},
|
|
{"fgc_hilight_item", "bgc_hilight_item"},
|
|
{"fgc_significant_item", "bgc_significant_item"},
|
|
{NULL, "bgc_desktop"},
|
|
};
|
|
|
|
/*
|
|
* InitWindowElementAttrs:
|
|
*
|
|
* This function initializes window element attributes of the specified
|
|
* renderer according to the section of renderer name in MiniGUI.cfg.
|
|
*
|
|
* Author: XiaoweiYan
|
|
* Date: 2007-11-22
|
|
*/
|
|
BOOL GUIAPI InitWindowElementAttrs (PWERENDERER rdr)
|
|
{
|
|
int i, j, tmp;
|
|
char buff [20];
|
|
DWORD rgba;
|
|
|
|
if (!rdr || !rdr->name || rdr->name[0] == '\0')
|
|
return FALSE;
|
|
|
|
_DBG_PRINTF ("GUI>InitWEA: Initialize %s renderer window element attributes.\n",
|
|
rdr->name);
|
|
|
|
for (i = 0; i < WE_METRICS_NUMBER; i++) {
|
|
|
|
if (szMWMKeyNames[i]) {
|
|
if ( GetMgEtcValue (rdr->name, szMWMKeyNames[i],
|
|
buff, 12) != ETC_OK)
|
|
return FALSE;
|
|
else {
|
|
tmp = atoi (buff);
|
|
rdr->we_metrics [i] = tmp;
|
|
}
|
|
}
|
|
}
|
|
|
|
for (i = 0; i < WE_COLORS_NUMBER; i++) {
|
|
|
|
if (i == 5)
|
|
continue;
|
|
|
|
for (j = 0; j < 3; j++) {
|
|
|
|
if (szCKeyNames[i][j]) {
|
|
if (GetMgEtcValue (rdr->name, szCKeyNames[i][j],
|
|
buff, 12) != ETC_OK) {
|
|
_WRN_PRINTF ("InitWindowElementAttrs error: \
|
|
Can not Get %s color.\n", szCKeyNames[i][j]);
|
|
return FALSE;
|
|
}
|
|
|
|
else {
|
|
rgba = strtoul (buff, NULL, 0);
|
|
rdr->we_colors [i][j] = rgba;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL mg_InitLFManager (void)
|
|
{
|
|
int i;
|
|
WINDOW_ELEMENT_RENDERER * rdr;
|
|
#ifdef _MGRM_THREADS
|
|
pthread_mutex_init (&gRendererMmutex, NULL);
|
|
#endif
|
|
|
|
/** be sure to success initializing default renderer */
|
|
rdr = wnd_lf_info[0].wnd_rdr;
|
|
if (NULL == rdr)
|
|
return FALSE;
|
|
|
|
if (rdr->init && 0 != rdr->init (rdr)) {
|
|
_ERR_PRINTF ("GUI>LFRDR: failed to initialize default renderer's private info.\n");
|
|
return FALSE;
|
|
}
|
|
|
|
/** initialize other renderer */
|
|
for (i = 1; i < MAX_NR_RENDERERS; ++i)
|
|
{
|
|
rdr = wnd_lf_info [i].wnd_rdr;
|
|
if (NULL == rdr) continue;
|
|
|
|
if (rdr->init && 0 != rdr->init (rdr)) {
|
|
wnd_lf_info[i].wnd_rdr = NULL;
|
|
_WRN_PRINTF ("failed to initialize renderer[%d]'s private info.\n", i);
|
|
continue;
|
|
}
|
|
}
|
|
|
|
#ifdef WE_HEAP
|
|
/** initialize window element block data heap.*/
|
|
init_we_heap();
|
|
#endif
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void mg_TerminateLFManager (void)
|
|
{
|
|
int i;
|
|
WINDOW_ELEMENT_RENDERER * rdr;
|
|
|
|
/** terminate renderer */
|
|
for (i = 0; i < MAX_NR_RENDERERS; ++i) {
|
|
rdr = wnd_lf_info [i].wnd_rdr;
|
|
if (rdr && rdr->deinit) {
|
|
rdr->deinit (rdr);
|
|
}
|
|
}
|
|
|
|
#ifdef _MGRM_THREADS
|
|
pthread_mutex_destroy (&gRendererMmutex);
|
|
#endif
|
|
#ifdef WE_HEAP
|
|
destroy_we_heap ();
|
|
#endif
|
|
}
|
|
|