同步操作将从 Gitee 极速下载/MiniGUI 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
/////////////////////////////////////////////////////////////////////////////////// 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/en/about/licensing-policy/>.*//*** layer.c: maintain the layers in server.**** Current maintainer: Wei Yongming.**** Create date: 2005年08月14日*/#include <sys/types.h>#include <signal.h>#include "common.h"#include "minigui.h"#include "gdi.h"#include "window.h"#include "cliprect.h"#include "internals.h"#include "ourhdr.h"#include "sockio.h"#include "client.h"#include "server.h"#include "sharedres.h"#include "drawsemop.h"#include "misc.h"#define SEM_PARAM 0666MG_Layer* mgLayers = NULL;MG_Layer* mgTopmostLayer = NULL;ON_CHANGE_LAYER OnChangeLayer = NULL;#define CHANGE_TOPMOST_LAYER(layer) \lock_draw_sem (); \SHAREDRES_TOPMOST_LAYER = (GHANDLE)layer; \unlock_draw_sem ();static int sg_nr_layers = 0;static unsigned char sem_usage [(MAX_NR_LAYERS + 7)/8];static BOOL do_alloc_layer (MG_Layer* layer, const char* name,int nr_topmosts, int nr_normals){ZORDERINFO* zi;ZORDERNODE* znodes;void* maskrect_usage_bmp;layer->zorder_shmid = kernel_alloc_z_order_info (nr_topmosts, nr_normals);if (layer->zorder_shmid == -1)return FALSE;/* Attach to the share memory. */zi = shmat (layer->zorder_shmid, 0, 0);if (zi == (void*)-1)return FALSE;if (shmctl (layer->zorder_shmid, IPC_RMID, NULL) < 0)return FALSE;strcpy (layer->name, name);layer->zorder_info = zi;zi->size_usage_bmp = SIZE_USAGE_BMP;zi->size_maskrect_usage_bmp = SIZE_MASKRECT_USAGE_BMP;zi->max_nr_popupmenus = DEF_NR_POPUPMENUS;zi->max_nr_globals = SHAREDRES_NR_GLOBALS;zi->max_nr_topmosts = nr_topmosts;zi->max_nr_normals = nr_normals;zi->nr_popupmenus = 0;zi->nr_globals = 1;zi->nr_topmosts = 0;zi->nr_normals = 0;zi->first_global = 0;zi->first_topmost = 0;zi->first_normal = 0;zi->active_win = 0;zi->cli_trackmenu = -1;zi->ptmi_in_cli = HWND_INVALID;zi->zi_semid = SHAREDRES_SEMID_LAYER;/* find one unused semaphore slot here */zi->zi_semnum = __mg_lookfor_unused_slot (sem_usage, sizeof (sem_usage), 1);/* init the semaphore with semctl */{union semun arg;arg.val = zi->max_nr_popupmenus + zi->max_nr_globals+ zi->max_nr_topmosts + zi->max_nr_normals;semctl (zi->zi_semid, zi->zi_semnum, SETVAL, arg);}memset (zi + 1, 0xFF, SIZE_USAGE_BMP);/* get a unused mask rect slot. */maskrect_usage_bmp = GET_MASKRECT_USAGEBMP(zi);memset (maskrect_usage_bmp, 0xFF, zi->size_maskrect_usage_bmp);/* init z-order node for desktop */znodes = (ZORDERNODE*) ((char*)(zi + 1) + zi->size_usage_bmp +sizeof (ZORDERNODE) * DEF_NR_POPUPMENUS);znodes [0].flags = ZOF_TYPE_DESKTOP | ZOF_VISIBLE;znodes [0].rc = g_rcScr;znodes [0].age = 0;znodes [0].cli = 0;znodes [0].fortestinghwnd = HWND_DESKTOP;znodes [0].next = 0;znodes [0].prev = 0;/*for mask rect.*/znodes [0].idx_mask_rect = 0;__mg_slot_set_use ((unsigned char*)(zi + 1), 0);__mg_slot_set_use ((unsigned char*)(maskrect_usage_bmp), 0);sg_nr_layers ++;return TRUE;}static void do_free_layer (MG_Layer* layer){ZORDERINFO* zi = layer->zorder_info;/* free zorder_semid for reuse here... */__mg_slot_clear_use (sem_usage, zi->zi_semnum);kernel_free_z_order_info (zi);if (layer->prev)layer->prev->next = layer->next;if (layer->next)layer->next->prev = layer->prev;if (layer == mgLayers) {mgLayers = layer->next;}sg_nr_layers --;}BOOL GUIAPI ServerDeleteLayer (MG_Layer* layer){ZORDERINFO* zi = layer->zorder_info;MG_Client* client;if (layer == NULL || strcmp (layer->name, NAME_DEF_LAYER) == 0) {_WRN_PRINTF ("SERVER: Can not delete the default layer.\n");return FALSE;}if (zi->nr_topmosts + zi->nr_normals + zi->nr_popupmenus != 0) {_WRN_PRINTF ("SERVER: Some objects are still in this layer.\n");return FALSE;}if (layer != mgLayers)ServerSetTopmostLayer (mgLayers);elseServerSetTopmostLayer (layer->next);if (OnChangeLayer) OnChangeLayer (LCO_DEL_LAYER, layer, NULL);client = layer->cli_head;while (client) {MG_Client* next = client->next;__mg_remove_client (client - mgClients, client->fd);client = next;}do_free_layer (layer);return TRUE;}BOOL __mg_is_valid_layer (MG_Layer* layer){MG_Layer* myLayer;myLayer = mgLayers;while (myLayer) {if (layer == myLayer)return TRUE;myLayer = myLayer->next;}return FALSE;}inline static key_t get_sem_key (void){return (key_t)(IPC_KEY_BASE + 0x03);}void __mg_delete_zi_sem (void){union semun ignored;if (semctl (SHAREDRES_SEMID_LAYER, 0, IPC_RMID, ignored) < 0)goto error;return;error:perror("remove semaphore");}int __mg_init_layers (){key_t sem_key;int semid;mgLayers = calloc (1, sizeof (MG_Layer));if (mgLayers == NULL)return -1;memset (sem_usage, 0xFF, sizeof (sem_usage));if ((sem_key = get_sem_key ()) == -1) {return -1;}semid = semget (sem_key, MAX_NR_LAYERS, SEM_PARAM | IPC_CREAT | IPC_EXCL);if (semid == -1)return -1;atexit (__mg_delete_zi_sem);SHAREDRES_SEMID_LAYER = semid;/* allocate the first layer for the default layer. */if (!do_alloc_layer (mgLayers, NAME_DEF_LAYER,SHAREDRES_DEF_NR_TOPMOSTS, SHAREDRES_DEF_NR_NORMALS)) {free (mgLayers);mgLayers = NULL;return -1;}__mg_zorder_info = mgLayers->zorder_info;return semid;}void __mg_cleanup_layers (void){MG_Layer *layer = mgLayers, *next;while (layer) {next = layer->next;do_free_layer (layer);free (layer);layer = next;};mgLayers = NULL;mgTopmostLayer = NULL;__mg_zorder_info = NULL;}/* allocate a layer slot from the layer pool for the new layer */static MG_Layer* alloc_layer (const char* layer_name,int nr_topmosts, int nr_normals){MG_Layer* new_layer;if (sg_nr_layers >= MAX_NR_LAYERS) {return NULL;}if (!(new_layer = calloc (1, sizeof (MG_Layer))))return NULL;if (!do_alloc_layer (new_layer, layer_name, nr_topmosts, nr_normals)) {free (new_layer);return NULL;}_WRN_PRINTF ("SERVER: Create a new layer: %s\n", layer_name);strcpy (new_layer->name, layer_name);new_layer->cli_head = NULL;new_layer->cli_active = NULL;/* chain it */if (mgLayers)mgLayers->prev = new_layer;new_layer->prev = NULL;new_layer->next = mgLayers;mgLayers = new_layer;/* Notify that a new layer created. */if (OnChangeLayer)OnChangeLayer (LCO_NEW_LAYER, new_layer, NULL);mgTopmostLayer = new_layer;_WRN_PRINTF ("SERVER: alloc_layer, mgTopmostLayer->zi = %p\n",mgTopmostLayer->zorder_info);/* Topmost layer changed */CHANGE_TOPMOST_LAYER(mgTopmostLayer);__mg_do_change_topmost_layer ();_WRN_PRINTF ("SERVER: alloc_layer, mgTopmostLayer->zi = %p\n",mgTopmostLayer->zorder_info);/* Notify that a new topmost layer have been set. */if (OnChangeLayer)OnChangeLayer (LCO_TOPMOST_CHANGED, mgTopmostLayer, NULL);PostMessage (HWND_DESKTOP, MSG_ERASEDESKTOP, 0, 0);return new_layer;}/* Retrives the layer by the name. */MG_Layer* __mg_find_layer_by_name (const char* name){MG_Layer* layer = mgLayers;if (name == NULL || name [0] == '0円')return NULL;while (layer) {if (strncmp (layer->name, name, LEN_LAYER_NAME) == 0)return layer;layer = layer->next;}return NULL;}/* get information of a layer, the server side of GetLayerInfo */void __mg_get_layer_info (int cli, const char* layer_name, LAYERINFO* info){MG_Layer* layer;MG_Client* client;memset (info, 0, sizeof (LAYERINFO));info->cli_active = -1;if (layer_name [0]) {layer = __mg_find_layer_by_name (layer_name);if (layer == NULL) {info->handle = INV_LAYER_HANDLE;return;}}elselayer = mgClients[cli].layer;info->handle = (GHANDLE)layer;if (info->handle) {client = layer->cli_head;while (client) {info->nr_clients ++;client = client->next;}if (mgTopmostLayer == layer)info->is_topmost = TRUE;info->cli_active = layer->cli_active - mgClients;}}static void do_client_join_layer (int cli,const JOINLAYERINFO* info, JOINEDCLIENTINFO* joined_info){MG_Layer* layer = (MG_Layer*)(joined_info->layer);MG_Client* new_client = mgClients + cli;if (new_client->layer == layer) { /* duplicated calling of JoinLayer */joined_info->cli_id = cli;joined_info->zo_shmid = layer->zorder_shmid;return;}_WRN_PRINTF ("SERVER: Join a client (%s) to layer %s\n",info->client_name, layer->name);strcpy (new_client->name, info->client_name);new_client->layer = layer;/* Notify that a new client joined to this layer. */if (OnChangeLayer)OnChangeLayer (LCO_JOIN_CLIENT, layer, new_client);new_client->prev = NULL;new_client->next = layer->cli_head;if (layer->cli_head)layer->cli_head->prev = new_client;layer->cli_head = new_client;joined_info->cli_id = cli;joined_info->zo_shmid = layer->zorder_shmid;}/* Join a client to a layer, the server side of JoinLayer */void __mg_client_join_layer (int cli,const JOINLAYERINFO* info, JOINEDCLIENTINFO* joined_info){MG_Layer* layer;if ((layer = __mg_find_layer_by_name (info->layer_name)) == NULL) {layer = alloc_layer (info->layer_name,(info->max_nr_topmosts <= 0)?SHAREDRES_DEF_NR_TOPMOSTS:info->max_nr_topmosts,(info->max_nr_normals<= 0)?SHAREDRES_DEF_NR_NORMALS:info->max_nr_normals);}joined_info->layer = (GHANDLE)layer;do_client_join_layer (cli, info, joined_info);}BOOL GUIAPI ServerSetTopmostLayer (MG_Layer* layer){MG_Client* client;unsigned int IsPaint = 0;if (!mgIsServer)return FALSE;if (layer == mgTopmostLayer)return FALSE;if (mgTopmostLayer && mgTopmostLayer->cli_head)IsPaint = 1;mgTopmostLayer = layer;CHANGE_TOPMOST_LAYER (layer);__mg_do_change_topmost_layer ();client = layer->cli_head;while (client) {MSG msg = {0, MSG_PAINT, 0, 0, __mg_timer_counter};__mg_send2client (&msg, client);client = client->next;}/* Notify that a new topmost layer have been set. */if (OnChangeLayer)OnChangeLayer (LCO_TOPMOST_CHANGED, mgTopmostLayer, NULL);if (IsPaint){SendMessage (HWND_DESKTOP, MSG_PAINT, 0, 0);}return TRUE;}MG_Layer* GUIAPI ServerCreateLayer (const char* layer_name,int max_nr_topmosts, int max_nr_normals){MG_Layer* new_layer;if (layer_name == NULL || layer_name [0] == '0円')return NULL;new_layer = __mg_find_layer_by_name (layer_name);if (new_layer)return new_layer;if (sg_nr_layers >= MAX_NR_LAYERS) {return NULL;}if (!(new_layer = calloc (1, sizeof (MG_Layer))))return NULL;if (max_nr_topmosts <= 0) max_nr_topmosts = DEF_NR_TOPMOSTS;if (max_nr_normals <= 0) max_nr_normals = DEF_NR_NORMALS;max_nr_topmosts = (max_nr_topmosts + 7) & ~0x07;max_nr_normals = (max_nr_normals + 7) & ~0x07;if (!do_alloc_layer (new_layer, layer_name, max_nr_topmosts, max_nr_normals)) {free (new_layer);return NULL;}strcpy (new_layer->name, layer_name);new_layer->cli_head = NULL;new_layer->cli_active = NULL;/* chain it */if (mgLayers)mgLayers->prev = new_layer;new_layer->prev = NULL;new_layer->next = mgLayers;mgLayers = new_layer;/* Notify that a new layer created. */if (OnChangeLayer)OnChangeLayer (LCO_NEW_LAYER, new_layer, NULL);return new_layer;}void GUIAPI DisableClientsOutput (void){if (!mgIsServer)return;CHANGE_TOPMOST_LAYER(NULL);}void GUIAPI UpdateTopmostLayer (const RECT* dirty_rc){MSG msg = {0, MSG_PAINT, 0, 0, __mg_timer_counter};if (!mgIsServer)return;CHANGE_TOPMOST_LAYER(mgTopmostLayer);if (dirty_rc) {RECT eff_rc;IntersectRect (&eff_rc, dirty_rc, &g_rcScr);msg.wParam = MAKELONG (eff_rc.left, eff_rc.top);msg.lParam = MAKELONG (eff_rc.right, eff_rc.bottom);}Send2Client (&msg, CLIENTS_TOPMOST);PostMessage (HWND_DESKTOP, MSG_ERASEDESKTOP, 0, 0);SendMessage (HWND_DESKTOP, MSG_PAINT, 0, 0);}int GUIAPI ServerGetNextZNode (MG_Layer* layer, int idx_znode, int* cli){ZORDERINFO* zi;ZORDERNODE* nodes;int next = 0;DWORD type;if (layer == NULL)layer = mgTopmostLayer;if (!__mg_is_valid_layer (layer))return -1;zi = (ZORDERINFO*)layer->zorder_info;if (idx_znode > zi->max_nr_globals+ zi->max_nr_topmosts + zi->max_nr_normals) {return -1;}nodes = (ZORDERNODE*) ((char*)(zi + 1) + zi->size_usage_bmp +sizeof (ZORDERNODE) * DEF_NR_POPUPMENUS);if (idx_znode <= 0) {next = zi->first_global;if (next == 0)next = zi->first_topmost;if (next == 0)next = zi->first_normal;if (next > 0 && cli) {*cli = nodes [next].cli;}return next;}type = nodes [idx_znode].flags & ZOF_TYPE_MASK;if (type != ZOF_TYPE_GLOBAL && type != ZOF_TYPE_TOPMOST&& type != ZOF_TYPE_NORMAL)return -1;if (idx_znode > 0) {next = nodes [idx_znode].next;}if (next > 0 && cli) {*cli = nodes [next].cli;return next;}switch (nodes [idx_znode].flags & ZOF_TYPE_MASK) {case ZOF_TYPE_GLOBAL:next = zi->first_topmost;if (next == 0)next = zi->first_normal;break;case ZOF_TYPE_TOPMOST:next = zi->first_normal;break;case ZOF_TYPE_NORMAL:break;default:return -1;}if (next > 0 && cli) {*cli = nodes [next].cli;}return next;}BOOL GUIAPI ServerGetZNodeInfo (MG_Layer* layer, int idx_znode,ZNODEINFO* znode_info){ZORDERINFO* zi;ZORDERNODE* nodes;if (znode_info == NULL)return FALSE;if (layer == NULL)layer = mgTopmostLayer;if (!__mg_is_valid_layer (layer))return FALSE;zi = (ZORDERINFO*)layer->zorder_info;if (idx_znode > zi->max_nr_globals+ zi->max_nr_topmosts + zi->max_nr_normals) {return FALSE;}nodes = (ZORDERNODE*) ((char*)(zi + 1) + zi->size_usage_bmp +sizeof (ZORDERNODE) * DEF_NR_POPUPMENUS);znode_info->type = (nodes [idx_znode].flags & ZOF_TYPE_FLAG_MASK);znode_info->flags = (nodes [idx_znode].flags & ZOF_FLAG_MASK);znode_info->caption = nodes [idx_znode].caption;znode_info->rc = nodes [idx_znode].rc;znode_info->cli = nodes [idx_znode].cli;znode_info->hwnd = nodes [idx_znode].fortestinghwnd;znode_info->main_win = nodes [idx_znode].main_win;return TRUE;}BOOL GUIAPI ServerDoZNodeOperation (MG_Layer* layer,int idx_znode, int op_code, void* op_data, BOOL notify){ZORDERINFO* zi;ZORDERNODE* nodes;DWORD type;ZORDEROPINFO info;if (layer == NULL)layer = mgTopmostLayer;if (!__mg_is_valid_layer (layer))return FALSE;zi = (ZORDERINFO*)layer->zorder_info;if (idx_znode > zi->max_nr_globals+ zi->max_nr_topmosts + zi->max_nr_normals) {return FALSE;}nodes = (ZORDERNODE*) ((char*)(zi + 1) + zi->size_usage_bmp +sizeof (ZORDERNODE) * DEF_NR_POPUPMENUS);type = nodes [idx_znode].flags & ZOF_TYPE_MASK;if (type != ZOF_TYPE_GLOBAL && type != ZOF_TYPE_TOPMOST&& type != ZOF_TYPE_NORMAL)return FALSE;switch (op_code) {case ZNOP_MOVE2TOP:info.id_op = ID_ZOOP_MOVE2TOP;info.idx_znode = idx_znode;break;case ZNOP_SETACTIVE:info.id_op = ID_ZOOP_SETACTIVE;info.idx_znode = idx_znode;break;default:return FALSE;}__mg_do_zorder_operation (nodes[idx_znode].cli, &info);return TRUE;}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。