Compare commits

...
33 Commits
Author SHA1 Message Date
xueshuming 4cf4d204e7 add func blend_pixel to fix font rendering issues on transparent backgrounds(SUBPIXEL) 2025-05-28 20:55:38 +08:00
VincentWei 6aa294e75b ignore ltmain.sh 2025-05-28 14:45:58 +08:00
VincentWei 7718be5200 ignore m4/*.m4 2025-05-28 14:44:43 +08:00
VincentWei 78e6d6581e update Makefile.am 2025-05-28 14:43:56 +08:00
VincentWei 62b3dc11d0 update libtool files 2025-05-28 14:43:25 +08:00
Vincent Wei 67cddafa19 change version to 5.0.16 2025-05-27 16:04:53 +08:00
Vincent Wei 4ae46a4b94 update 2025-05-27 15:53:44 +08:00
xueshuming 2791dc99ef Init Order: call 'mg_InitTimer' before call 'SystemThreads' 2025-05-27 15:45:03 +08:00
Vincent Wei b7525f3001 fix a bug: MSG_TIMEOUT for desktop thread was not fired correctly 2025-05-27 14:45:53 +08:00
Vincent Wei 4c55f2eac3 use sem_timedwait in the idle handler for desktop threads 2025-05-27 11:08:55 +08:00
Vincent Wei 3ad600d1bf Merge branch 'rel-5-0' 2025-05-09 14:02:57 +08:00
Vincent Wei 3c233a4164 update version to 5.0.15 2025-05-09 13:59:17 +08:00
Vincent Wei 3643606a7f restore the system interval timer for the server under runmode procs 2025-04-30 14:12:19 +08:00
Vincent Wei 3ef2340749 restore old logic to update timer_expected 2025-04-30 12:10:47 +08:00
Vincent Wei a583dc1cbb optimize and cleanup the timer module to fix the bad update of tick counter 2025-04-30 12:00:38 +08:00
xueshuming 0abaeef4c7 impl : __mg_save_png 2024-02-20 19:28:14 +08:00
Vincent Wei c2779cbf09 implement a new API: TestIfSharedSurfaceChanged() 2023-09-26 10:52:09 +08:00
Vincent Wei e118805eef fix a bug of GetUpdateRect: intersect bouding rectangle of invalid region with client rect 2023-09-16 15:43:07 +08:00
Vincent Wei 7513d461bf remove code about semaphhore for shared surface 2023-09-08 18:14:20 +08:00
Vincent Wei b131f00a79 fix compiling errors for MiniGUI-Standalone runmode 2023-09-04 10:45:05 +08:00
Vincent Wei 649fbf571e change copyright year 2023-09-01 16:07:56 +08:00
Vincent Wei e38fd05cb4 debug: use fcntl() instead of flock() 2023-09-01 16:03:50 +08:00
Vincent Wei ce53f2c703 use MSG_WINCOMPOSITED to reset the dirty information of a shared surface of a window 2023-09-01 12:25:04 +08:00
Vincent Wei fbebc94718 use GAL_RefSurface() in CreateMemDCFromSurface() 2023-09-01 10:01:11 +08:00
Vincent Wei b4ce6f9f10 helpers for locking/unlocking a file 2023-09-01 08:36:08 +08:00
Vincent Wei c04dde31e5 use flock() instead of semaphore for shared surfaces 2023-09-01 08:35:32 +08:00
Vincent Wei 5a2b425012 debug 2023-08-31 17:00:50 +08:00
Vincent Wei fa18025350 debug APIs for shared surfaces 2023-08-31 16:02:06 +08:00
Vincent Wei 890ab1db44 debug 2023-08-30 15:40:13 +08:00
Vincent Wei 3d963b3d25 Extend JoinLayer() to JoinLayerEx() to return the client identifier; Add a new API GetClientId() 2023-08-30 12:23:26 +08:00
Vincent Wei 29ac6a4277 initial implementation of new APIs of shared surface: AttachToSharedSurface(), GetSharedSurfaceInfo(), LockSharedSurfaceIfDirty(), UnlockSharedSurface(), and DetachFromSharedSurface() 2023-08-29 16:21:49 +08:00
Vincent Wei 96ecf5e9b7 Tune layout of struct _SharedSurfaceHeader; Change interface of GetWindowSharedSurfaceFD() 2023-08-29 12:50:58 +08:00
Vincent Wei 50aafa3faa initial implementation of CreateSharedSurface(), DestroySharedSurface(), GetSharedSurfaceFDByClientWindow(), and GetSharedSurfaceFDByName() 2023-08-29 12:12:51 +08:00
57 changed files with 1671 additions and 9461 deletions
+2
View File
@@ -10,6 +10,7 @@ Makefile
Makefile.in Makefile.in
.deps/ .deps/
.libs/ .libs/
m4/*.m4
/acinclude.m4 /acinclude.m4
/aclocal.m4 /aclocal.m4
/autom4te.cache /autom4te.cache
@@ -21,6 +22,7 @@ Makefile.in
/depcomp /depcomp
/install-sh /install-sh
/libtool /libtool
/ltmain.sh
/*.pc /*.pc
/*config.h /*config.h
/*config.h.in /*config.h.in
+2
View File
@@ -1,3 +1,5 @@
ACLOCAL_AMFLAGS = -I m4
SUBDIRS = src 3rd-party include rtos etc m4 cmake build SUBDIRS = src 3rd-party include rtos etc m4 cmake build
EXTRA_DIST = minigui.pc.in \ EXTRA_DIST = minigui.pc.in \
+3 -2
View File
@@ -460,7 +460,7 @@ for examples:
## HISTORY ## HISTORY
21 years have pasted since MiniGUI was initially created at 27 years have pasted since MiniGUI was initially created at
the end of 1998, and now it becomes much reliable and stable. the end of 1998, and now it becomes much reliable and stable.
During the past years, many remarkable changes have taken place in During the past years, many remarkable changes have taken place in
the MiniGUI project. the MiniGUI project.
@@ -566,13 +566,14 @@ A brief history description of the development progress is listed as follow:
1. Jan., 2022: FMSoft released MiniGUI version 5.0.9. 1. Jan., 2022: FMSoft released MiniGUI version 5.0.9.
1. Sep., 2022: FMSoft released MiniGUI version 5.0.10. 1. Sep., 2022: FMSoft released MiniGUI version 5.0.10.
1. Aug., 2023: FMSoft released MiniGUI version 5.0.13. 1. Aug., 2023: FMSoft released MiniGUI version 5.0.13.
1. May., 2025: FMSoft released MiniGUI version 5.0.16.
## AUTHORS AND COPYING ## AUTHORS AND COPYING
The original author of MiniGUI is Vincent Wei, and now MiniGUI is maintained by FMSoft. The original author of MiniGUI is Vincent Wei, and now MiniGUI is maintained by FMSoft.
For more information, please refer to <http://www.fmsoft.cn>. For more information, please refer to <http://www.fmsoft.cn>.
Copyright (C) 2002 ~ 2023, Beijing FMSoft Technologies Co., Ltd. Copyright (C) 2002 ~ 2025, Beijing FMSoft Technologies Co., Ltd.
Copyright (C) 1998 ~ 2002, Vincent Wei Copyright (C) 1998 ~ 2002, Vincent Wei
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
+17 -5
View File
@@ -1,7 +1,9 @@
# Release Notes # Release Notes
- [Version 5.2.0](#version-520) - [Version 5.0.16](#version-5016)
+ [What's new in version 5.2.0](#whats-new-in-version-520) + [What's new in version 5.0.16](#whats-new-in-version-5016)
- [Version 5.0.15](#version-5015)
+ [What's new in version 5.0.15](#whats-new-in-version-5015)
- [Version 5.0.13](#version-5013) - [Version 5.0.13](#version-5013)
+ [What's new in version 5.0.13](#whats-new-in-version-5013) + [What's new in version 5.0.13](#whats-new-in-version-5013)
- [Version 5.0.12](#version-5012) - [Version 5.0.12](#version-5012)
@@ -34,10 +36,20 @@
+ [Changes leading to incompatibility](#changes-leading-to-incompatibility) + [Changes leading to incompatibility](#changes-leading-to-incompatibility)
+ [Deprecated APIs](#deprecated-apis) + [Deprecated APIs](#deprecated-apis)
## Version 5.2.0 ## Version 5.0.16
On Nov. 30, 2023, FMSoft announces the availability of MiniGUI 5.2.0, On May 27, 2025, FMSoft announces the availability of MiniGUI 5.0.16,
which is an mainline release with some major enhancements: which is a bugfix release with some minor enhancements of MiniGUI 5.0.x.
* BUGFIXING:
- The desktop thread can not handle the request from other threads as soon as possible.
- The `MSG_TIMEOUT` message can not be fired correctly under MiniGUI-Threads mode.
## Version 5.0.15
On May 09, 2025, FMSoft announces the availability of MiniGUI 5.0.15,
which is an enhancement release with some minor enhancements
of MiniGUI 5.0.x.
* ENHANCEMENTS: * ENHANCEMENTS:
- Optimize NEWGAL engines: `shadow`, `drm`, and `fbcon` for large resolution. - Optimize NEWGAL engines: `shadow`, `drm`, and `fbcon` for large resolution.
+1 -1
View File
@@ -1,4 +1,4 @@
Version 5.0.13 (2023/08/31) Version 5.0.16 (2025/05/27)
This is a minor enhancement and bugfix release of MiniGUI 5.0.x, the stable version. This is a minor enhancement and bugfix release of MiniGUI 5.0.x, the stable version.
+2 -1
View File
@@ -1,6 +1,7 @@
#!/bin/sh #!/bin/sh
cat m4/*.m4 > acinclude.m4 libtoolize
cat m4/*.m4 > aclocal.m4
aclocal aclocal
autoheader autoheader
automake --add-missing --foreign --copy automake --add-missing --foreign --copy
+23 -26
View File
@@ -1,7 +1,8 @@
dnl Process this file with autoconf to produce a configure script. dnl Process this file with autoconf to produce a configure script.
AC_PREREQ(2.60) AC_PREREQ([2.71])
AC_INIT(libminigui, 5.0.14) AC_INIT([libminigui],[5.0.16])
AC_CONFIG_SRCDIR(src/main/main.c) AC_CONFIG_SRCDIR(src/main/main.c)
AC_CONFIG_MACRO_DIRS([m4])
dnl Set various version strings - taken gratefully from the SDL sources dnl Set various version strings - taken gratefully from the SDL sources
# #
@@ -16,9 +17,9 @@ dnl Set various version strings - taken gratefully from the SDL sources
# #
MINIGUI_MAJOR_VERSION=5 MINIGUI_MAJOR_VERSION=5
MINIGUI_MINOR_VERSION=0 MINIGUI_MINOR_VERSION=0
MINIGUI_MICRO_VERSION=14 MINIGUI_MICRO_VERSION=16
MINIGUI_INTERFACE_AGE=0 MINIGUI_INTERFACE_AGE=1
MINIGUI_BINARY_AGE=0 MINIGUI_BINARY_AGE=1
MINIGUI_VERSION=$MINIGUI_MAJOR_VERSION.$MINIGUI_MINOR_VERSION.$MINIGUI_MICRO_VERSION MINIGUI_VERSION=$MINIGUI_MAJOR_VERSION.$MINIGUI_MINOR_VERSION.$MINIGUI_MICRO_VERSION
AC_SUBST(MINIGUI_MAJOR_VERSION) AC_SUBST(MINIGUI_MAJOR_VERSION)
@@ -40,35 +41,31 @@ AC_SUBST(LT_CURRENT)
AC_SUBST(LT_REVISION) AC_SUBST(LT_REVISION)
AC_SUBST(LT_AGE) AC_SUBST(LT_AGE)
AC_CANONICAL_SYSTEM AC_CANONICAL_TARGET
dnl ======================================================================== dnl ========================================================================
dnl Init automake dnl Init automake
AM_INIT_AUTOMAKE AM_INIT_AUTOMAKE
AC_CONFIG_HEADER(mgconfig.h) AC_CONFIG_HEADERS([mgconfig.h])
dnl ======================================================================== dnl ========================================================================
dnl Check for tools dnl Check for tools
AC_PROG_LIBTOOL
AC_PROG_CC AC_PROG_CC
AC_PROG_LD
AC_PROG_RANLIB
AC_PROG_INSTALL AC_PROG_INSTALL
AC_PROG_LN_S AC_PROG_LN_S
AC_PROG_MAKE_SET AC_PROG_MAKE_SET
LT_INIT
dnl ======================================================================== dnl ========================================================================
dnl Checks for header files. dnl Checks for header files.
AC_HEADER_STDC
AC_HEADER_DIRENT AC_HEADER_DIRENT
AC_CHECK_HEADERS(limits.h math.h locale.h unistd.h termio.h sys/types.h sys/time.h sys/select.h sys/memfd.h) AC_CHECK_HEADERS(limits.h math.h stdatomic.h locale.h unistd.h termio.h sys/types.h sys/time.h sys/select.h sys/memfd.h)
dnl Checks for typedefs, structures, and compiler characteristics. dnl Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST AC_C_CONST
AC_C_INLINE AC_C_INLINE
AC_TYPE_SIZE_T AC_TYPE_SIZE_T
AC_HEADER_TIME
AC_STRUCT_TM AC_STRUCT_TM
dnl Checks for library functions. dnl Checks for library functions.
@@ -884,14 +881,14 @@ CheckFBCON()
if test "x$enable_video_fbcon" = "xyes"; then if test "x$enable_video_fbcon" = "xyes"; then
AC_MSG_CHECKING(for FrameBuffer console support) AC_MSG_CHECKING(for FrameBuffer console support)
video_fbcon=no video_fbcon=no
AC_TRY_COMPILE([ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#include <linux/fb.h> #include <linux/fb.h>
#include <linux/kd.h> #include <linux/kd.h>
#include <linux/keyboard.h> #include <linux/keyboard.h>
],[ ]], [[
],[ ]])],[
video_fbcon=yes video_fbcon=yes
]) ],[])
AC_MSG_RESULT($video_fbcon) AC_MSG_RESULT($video_fbcon)
if test "x$video_fbcon" = "xyes"; then if test "x$video_fbcon" = "xyes"; then
AC_DEFINE(_MGGAL_FBCON, 1, AC_DEFINE(_MGGAL_FBCON, 1,
@@ -1170,12 +1167,12 @@ CheckDirectFBVideo()
if test "x$enable_video_dfb" = "xyes"; then if test "x$enable_video_dfb" = "xyes"; then
AC_MSG_CHECKING(for DirectFB support) AC_MSG_CHECKING(for DirectFB support)
video_dfb=no video_dfb=no
AC_TRY_COMPILE([ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
#include <directfb.h> #include <directfb.h>
],[ ]], [[
],[ ]])],[
video_dfb=yes video_dfb=yes
]) ],[])
AC_MSG_RESULT($video_dfb) AC_MSG_RESULT($video_dfb)
if test "x$video_dfb" = "xyes"; then if test "x$video_dfb" = "xyes"; then
AC_DEFINE(_MGGAL_DFB, 1, AC_DEFINE(_MGGAL_DFB, 1,
@@ -2641,7 +2638,7 @@ if test "x$devel_mode" = "xyes"; then
CPPFLAGS="$CPPFLAGS -D_DEBUG" CPPFLAGS="$CPPFLAGS -D_DEBUG"
fi fi
if test "$ac_cv_prog_gcc" = "yes"; then if test "$ac_cv_c_compiler_gnu" = "yes"; then
CFLAGS="$CFLAGS -Wall -Werror" CFLAGS="$CFLAGS -Wall -Werror"
fi fi
@@ -2651,7 +2648,7 @@ else
CPPFLAGS="$CPPFLAGS -DNDEBUG" CPPFLAGS="$CPPFLAGS -DNDEBUG"
fi fi
if test "$ac_cv_prog_gcc" = "yes"; then if test "$ac_cv_c_compiler_gnu" = "yes"; then
CFLAGS="$CFLAGS -fmax-errors=10 -Wstrict-prototypes -pipe" CFLAGS="$CFLAGS -fmax-errors=10 -Wstrict-prototypes -pipe"
fi fi
@@ -2688,8 +2685,7 @@ AM_CONDITIONAL(MGLIB_MVFB, test "x$with_libsuffix" = "xmvfb")
AM_CONDITIONAL(MG_ENABLE_SPLASH, test "x$build_splash" = "xyes") AM_CONDITIONAL(MG_ENABLE_SPLASH, test "x$build_splash" = "xyes")
AM_CONDITIONAL(MG_ENABLE_SCREENSAVER, test "x$build_screensaver" = "xyes") AM_CONDITIONAL(MG_ENABLE_SCREENSAVER, test "x$build_screensaver" = "xyes")
AC_OUTPUT( AC_CONFIG_FILES([minigui.pc
minigui.pc
Makefile Makefile
cmake/Makefile cmake/Makefile
src/Makefile src/Makefile
@@ -2756,7 +2752,8 @@ etc/Makefile
3rd-party/scripteasy/Makefile 3rd-party/scripteasy/Makefile
m4/Makefile m4/Makefile
build/Makefile build/Makefile
) ])
AC_OUTPUT
CCVERSION=`$CC --version | head -n 1` CCVERSION=`$CC --version | head -n 1`
+2
View File
@@ -268,6 +268,8 @@ MGUI_COMPILE_TIME_ASSERT(sint64, sizeof(Sint64) == 8);
#define MG_UNLIKELY(expr) (expr) #define MG_UNLIKELY(expr) (expr)
#endif #endif
#define HAVE(FEATURE) (defined HAVE_##FEATURE && HAVE_##FEATURE)
/** /**
* \defgroup endian_info Endianness information * \defgroup endian_info Endianness information
* @{ * @{
+99 -58
View File
File diff suppressed because it is too large Load Diff
+86 -5
View File
@@ -456,6 +456,45 @@ MG_EXPORT void GUIAPI MiniGUIPanic (int exitcode);
* @{ * @{
*/ */
/**
* \fn GHANDLE GUIAPI JoinLayerEx (const char* layer_name,
const char* client_name,
int max_nr_highers, int max_nr_normals, int *cli_id)
* \brief Joins to a layer and returns the client identifier if success.
*
* This function should be called by clients before calling any other MiniGUI
* functions. You can call \a GetLayerInfo to get the layer information.
* If the layer to be joined does not exist, the server, i.e. \a mginit, will
* try to create a new one. If you passed a NULL pointer or a null string for
* \a layer_name, the client will join to the default layer.
*
* If the client want to create a new layer, you should specify the maximal
* number of z-nodes in the higher level (max_nr_highers) and the maximal
* number of z-nodes in the normal level (max_nr_normals) of the new layer.
* Passing zero to \a max_nr_highers and max_nr_normals will use the default
* values, and the default values are specified by ServerStartup.
*
* Note that the server will create a default layer named "mginit".
*
* \param layer_name The name of the layer. You can use NAME_TOPMOST_LAYER to
* specify the current topmost layer.
* \param client_name The name of the client.
* \param max_nr_highers The maximal number of z-nodes in the higher level of
* the new layer.
* \param max_nr_normals The maximal number of z-nodes in the normal level of
* the new layer.
* \param cli_id The pointer to a buffer of int to return the client identifier.
*
* \return The handle to the layer on success, INV_LAYER_HANDLE on error.
*
* \note Only call this function in clients of MiniGUI-Processes.
*
* \sa GetLayerInfo, ServerStartup, ServerCreateLayer
*/
MG_EXPORT GHANDLE GUIAPI JoinLayerEx (const char* layer_name,
const char* client_name,
int max_nr_highers, int max_nr_normals, int *cli_id);
/** /**
* \fn GHANDLE GUIAPI JoinLayer (const char* layer_name, * \fn GHANDLE GUIAPI JoinLayer (const char* layer_name,
const char* client_name, const char* client_name,
@@ -490,9 +529,30 @@ MG_EXPORT void GUIAPI MiniGUIPanic (int exitcode);
* *
* \sa GetLayerInfo, ServerStartup, ServerCreateLayer * \sa GetLayerInfo, ServerStartup, ServerCreateLayer
*/ */
MG_EXPORT GHANDLE GUIAPI JoinLayer (const char* layer_name, static inline GHANDLE GUIAPI JoinLayer (const char* layer_name,
const char* client_name, const char* client_name,
int max_nr_highers, int max_nr_normals); int max_nr_highers, int max_nr_normals)
{
return JoinLayerEx (layer_name, client_name,
max_nr_highers, max_nr_normals, NULL);
}
/**
* \fn int GUIAPI GetClientId (void)
* \brief Gets the client identifier.
*
* You can get the information of a layer through this function.
* The information will be returned through the pointer arguments
* if the specific pointer is not NULL.
*
* \return Returns the client identifier of the current process.
* Note that the server always returns 0.
*
* \sa JoinLayerEx
*
* Since 5.2.0
*/
MG_EXPORT int GUIAPI GetClientId (void);
/** /**
* \fn GHANDLE GUIAPI GetLayerInfo (const char* layer_name, * \fn GHANDLE GUIAPI GetLayerInfo (const char* layer_name,
@@ -1958,7 +2018,7 @@ const CompositorOps* __ex_compositor_get (const char* name,
* *
* \sa RegisterRequestHandler * \sa RegisterRequestHandler
*/ */
#define MAX_SYS_REQID 0x0024 #define MAX_SYS_REQID 0x0023
/** /**
* \def MAX_REQID * \def MAX_REQID
@@ -2125,7 +2185,7 @@ MG_EXPORT int GUIAPI ServerSendReplyEx (int clifd,
* \fn int GUIAPI ServerSendReply (int clifd, const void* reply, int len) * \fn int GUIAPI ServerSendReply (int clifd, const void* reply, int len)
* \brief Sends the reply to the client. * \brief Sends the reply to the client.
* *
* This function sends a replay pointed to by \a reply which is * This function sends a reply pointed to by \a reply which is
* \a len bytes long to the client. * \a len bytes long to the client.
* *
* \note Only used by the server to send the reply to the client. * \note Only used by the server to send the reply to the client.
@@ -2673,6 +2733,26 @@ MG_EXPORT void GUIAPI DesktopUpdateAllWindow (void);
#define DUMMY_LAYER_HANDLE (GHANDLE)(-1) #define DUMMY_LAYER_HANDLE (GHANDLE)(-1)
/**
* \fn GHANDLE GUIAPI JoinLayerEx (const char* layer_name,
const char* client_name,
int max_nr_highers, int max_nr_normals, int *cli_fd)
* \brief The dummy replacement of the same function for MiniGUI-Processes.
*
* This function is a replacment of the same function for MiniGUI-Processes
* runtime mode. We provide this function for MiniGUI-Threads and
* MiniGUI-Standalone runtime modes, in order to avoid using the
* conditional compilation instructions in your source code.
*
* \return Always returns DUMMY_LAYER_HANDLE to indicate success.
*/
static inline GHANDLE GUIAPI JoinLayerEx (const char* layer_name,
const char* client_name,
int max_nr_highers, int max_nr_normals, int *cli_fd)
{
return DUMMY_LAYER_HANDLE;
}
/** /**
* \fn GHANDLE GUIAPI JoinLayer (const char* layer_name, * \fn GHANDLE GUIAPI JoinLayer (const char* layer_name,
const char* client_name, const char* client_name,
@@ -2687,7 +2767,8 @@ MG_EXPORT void GUIAPI DesktopUpdateAllWindow (void);
* \return Always returns DUMMY_LAYER_HANDLE to indicate success. * \return Always returns DUMMY_LAYER_HANDLE to indicate success.
*/ */
static inline GHANDLE GUIAPI JoinLayer (const char* layer_name, static inline GHANDLE GUIAPI JoinLayer (const char* layer_name,
const char* client_name, int max_nr_highers, int max_nr_normals) const char* client_name,
int max_nr_highers, int max_nr_normals)
{ {
return DUMMY_LAYER_HANDLE; return DUMMY_LAYER_HANDLE;
} }
+11 -5
View File
@@ -2990,18 +2990,22 @@ typedef struct _WINMASKINFO {
if the client moved to a new layer */ if the client moved to a new layer */
#define MSG_LAYERCHANGED 0x0149 #define MSG_LAYERCHANGED 0x0149
/* Since 5.2.0; the server send this message to the client
if a window has been composited to the screen. */
#define MSG_WINCOMPOSITED 0x014A
#endif /* defined _MGRM_PROCESSES */ #endif /* defined _MGRM_PROCESSES */
/* Since 5.0.0: for managing message thread */ /* Since 5.0.0: for managing message thread */
#define MSG_MANAGE_MSGTHREAD 0x014A #define MSG_MANAGE_MSGTHREAD 0x014B
#define MSGTHREAD_SIGNIN 0x00 #define MSGTHREAD_SIGNIN 0x00
#define MSGTHREAD_SIGNOUT 0x01 #define MSGTHREAD_SIGNOUT 0x01
/* Since 5.0.0: for calculating the default position */ /* Since 5.0.0: for calculating the default position */
#define MSG_CALC_POSITION 0x014B #define MSG_CALC_POSITION 0x014C
/* Since 5.0.6: for waking up the client */ /* Since 5.0.6: for waking up the client */
#define MSG_WAKEUP_CLIENT 0x014C #define MSG_WAKEUP_CLIENT 0x014D
/** /**
* \def MSG_DOESNEEDIME * \def MSG_DOESNEEDIME
@@ -7238,7 +7242,8 @@ MG_EXPORT BOOL GUIAPI SetMainWindowGestureFlags (HWND hWnd, DWORD dwFlags);
#ifdef _MGSCHEMA_COMPOSITING #ifdef _MGSCHEMA_COMPOSITING
/** /**
* \fn int GUIAPI GetWindowSharedSurfaceFD (HWND hwnd) * \fn int GUIAPI GetWindowSharedSurfaceFD (HWND hwnd, size_t *map_size,
* DWORD *flags)
* \brief Gets the file descriptor of the surface buffer for a window or * \brief Gets the file descriptor of the surface buffer for a window or
* the main window it locates. * the main window it locates.
* *
@@ -7258,7 +7263,8 @@ MG_EXPORT BOOL GUIAPI SetMainWindowGestureFlags (HWND hWnd, DWORD dwFlags);
* *
* Since 5.0.13 * Since 5.0.13
*/ */
MG_EXPORT int GUIAPI GetWindowSharedSurfaceFD (HWND hWnd); MG_EXPORT int GUIAPI GetWindowSharedSurfaceFD (HWND hWnd, size_t *map_size,
DWORD *flags);
/** /**
* \fn BOOL GUIAPI SetMainWindowCompositing (HWND hWnd, * \fn BOOL GUIAPI SetMainWindowCompositing (HWND hWnd,
-5064
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -1,4 +1,4 @@
# This file does not do anything, except making sure these files are included # This file does not do anything, except making sure these files are included
# when you run 'make dist'. # when you run 'make dist'.
EXTRA_DIST = libtool.m4 EXTRA_DIST =
-3724
View File
File diff suppressed because it is too large Load Diff
+32 -3
View File
@@ -184,6 +184,23 @@ static void process_socket_message (MSG *msg)
LOSWORD(msg->wParam), HISWORD(msg->wParam), LOSWORD(msg->wParam), HISWORD(msg->wParam),
LOSWORD(msg->lParam), HISWORD(msg->lParam)); LOSWORD(msg->lParam), HISWORD(msg->lParam));
} }
#ifdef _MGSCHEMA_COMPOSITING
else if (msg->message == MSG_WINCOMPOSITED) {
/* Since 5.2.0 */
int slot = (int)msg->wParam;
HWND hwnd = (HWND)msg->lParam;
unsigned dirty_age = (unsigned)msg->time;
if (__mg_client_check_znode_hwnd(slot, hwnd, __mg_client_id)) {
GAL_Surface *ssurf = ((PMAINWIN)hwnd)->surf;
assert(ssurf->shared_header);
__mg_lock_file_for_write(ssurf->fd);
if (ssurf->dirty_info->dirty_age == dirty_age) {
ssurf->dirty_info->nr_dirty_rcs = 0;
}
__mg_unlock_file_for_write(ssurf->fd);
}
}
#endif
else { else {
if (msg->hwnd == HWND_NULL) { if (msg->hwnd == HWND_NULL) {
msg->hwnd = HWND_DESKTOP; msg->hwnd = HWND_DESKTOP;
@@ -518,8 +535,8 @@ BOOL client_IdleHandler4Client (PMSGQUEUE msg_queue, BOOL wait)
return (n > 0); return (n > 0);
} }
GHANDLE GUIAPI JoinLayer (const char* layer_name, const char* client_name, GHANDLE GUIAPI JoinLayerEx (const char* layer_name, const char* client_name,
int max_nr_topmosts, int max_nr_normals) int max_nr_topmosts, int max_nr_normals, int *cli_id)
{ {
GHANDLE layer_handle = INV_LAYER_HANDLE; GHANDLE layer_handle = INV_LAYER_HANDLE;
REQUEST req; REQUEST req;
@@ -529,8 +546,12 @@ GHANDLE GUIAPI JoinLayer (const char* layer_name, const char* client_name,
if (mgIsServer) if (mgIsServer)
return layer_handle; return layer_handle;
if (__mg_client_id != 0) /* Already joined, return the handle */ if (__mg_client_id != 0) {
/* Already joined, return the handle */
if (cli_id)
*cli_id = __mg_client_id;
return GetLayerInfo (NAME_SELF_LAYER, NULL, NULL, NULL); return GetLayerInfo (NAME_SELF_LAYER, NULL, NULL, NULL);
}
if (layer_name) { if (layer_name) {
strncpy (info.layer_name, layer_name, LEN_LAYER_NAME); strncpy (info.layer_name, layer_name, LEN_LAYER_NAME);
@@ -593,10 +614,18 @@ GHANDLE GUIAPI JoinLayer (const char* layer_name, const char* client_name,
__mg_start_client_desktop (); __mg_start_client_desktop ();
if (cli_id)
*cli_id = __mg_client_id;
ret: ret:
return layer_handle; return layer_handle;
} }
int GUIAPI GetClientId (void)
{
return __mg_client_id;
}
GHANDLE GUIAPI GetLayerInfo (const char* layer_name, GHANDLE GUIAPI GetLayerInfo (const char* layer_name,
int* nr_clients, BOOL* is_topmost, int* cli_active) int* nr_clients, BOOL* is_topmost, int* cli_active)
{ {
+1 -1
View File
@@ -2185,7 +2185,7 @@ static int create_memdc_for_menu (TRACKMENUINFO* ptmi)
return -1; return -1;
} }
ptmi->dc = CreateMemDCFromSurface (surf); ptmi->dc = __mg_create_memdc_for_surface (surf);
if (ptmi->dc == HDC_INVALID) { if (ptmi->dc == HDC_INVALID) {
GAL_FreeSurface (surf); GAL_FreeSurface (surf);
return -1; return -1;
+24 -13
View File
@@ -4476,10 +4476,10 @@ HWND GUIAPI CreateMainWindowEx2 (PMAINWINCREATE pCreateInfo, LINT id,
#endif #endif
#ifdef _MGSCHEMA_COMPOSITING #ifdef _MGSCHEMA_COMPOSITING
// Close file descriptor to free kernel memory? /* Since 5.2.0: keep fd available. */
if (pWin->surf->shared_header) { if (0 && pWin->surf->shared_header) {
close (pWin->surf->shared_header->fd); close (pWin->surf->fd);
pWin->surf->shared_header->fd = -1; pWin->surf->fd = -1;
} }
#endif #endif
@@ -5585,11 +5585,13 @@ BOOL GUIAPI ValidateRegion (HWND hWnd, const CLIPRGN* pRgn)
BOOL GUIAPI GetUpdateRect (HWND hWnd, RECT* update_rect) BOOL GUIAPI GetUpdateRect (HWND hWnd, RECT* update_rect)
{ {
PMAINWIN pWin; PMAINWIN pWin;
RECT rcClient;
MG_CHECK_RET (MG_IS_NORMAL_WINDOW(hWnd), FALSE); MG_CHECK_RET (MG_IS_NORMAL_WINDOW(hWnd), FALSE);
pWin = MG_GET_WINDOW_PTR (hWnd); pWin = MG_GET_WINDOW_PTR (hWnd);
*update_rect = pWin->InvRgn.rgn.rcBound; GetClientRect(hWnd, &rcClient);
IntersectRect(update_rect, &pWin->InvRgn.rgn.rcBound, &rcClient);
return TRUE; return TRUE;
} }
@@ -6036,10 +6038,10 @@ HWND GUIAPI CreateWindowEx2 (const char* spClassName,
} }
#ifdef _MGSCHEMA_COMPOSITING #ifdef _MGSCHEMA_COMPOSITING
// Close file descriptor to free kernel memory? /* Since 5.2.0: keep fd available. */
if (dwExStyle & WS_EX_CTRLASMAINWIN && pNewCtrl->surf->shared_header) { if (0 && dwExStyle & WS_EX_CTRLASMAINWIN && pNewCtrl->surf->shared_header) {
close (pNewCtrl->surf->shared_header->fd); close (pNewCtrl->surf->fd);
pNewCtrl->surf->shared_header->fd = -1; pNewCtrl->surf->fd = -1;
} }
#endif #endif
@@ -6067,13 +6069,22 @@ error:
} }
#ifdef _MGSCHEMA_COMPOSITING #ifdef _MGSCHEMA_COMPOSITING
int GUIAPI GetWindowSharedSurfaceFD (HWND hWnd) int GUIAPI GetWindowSharedSurfaceFD (HWND hWnd, size_t *map_size, DWORD *flags)
{ {
MG_CHECK_RET (MG_IS_APP_WINDOW (hWnd), -1); MG_CHECK_RET (MG_IS_NORMAL_WINDOW (hWnd), -1);
PMAINWIN pWin = (PMAINWIN)hWnd; PMAINWIN pWin = (PMAINWIN)hWnd;
if (pWin->surf->shared_header) if (pWin->surf->shared_header) {
return pWin->surf->shared_header->fd; if (map_size)
*map_size = pWin->surf->shared_header->map_size;
if (flags) {
*flags = MEMDC_FLAG_SWSURFACE;
if (pWin->surf->shared_header->byhw)
*flags |= MEMDC_FLAG_HWSURFACE;
}
return pWin->surf->fd;
}
return -1; return -1;
} }
+16 -10
View File
@@ -117,10 +117,22 @@
#define REQID_LOADCURSOR_PNG 0x001D #define REQID_LOADCURSOR_PNG 0x001D
// Load cursor from in-memory PNG // Load cursor from in-memory PNG
#define REQID_LOADCURSOR_PNG_MEM 0x001E #define REQID_LOADCURSOR_PNG_MEM 0x001E
#if 0 // Deprecated since 5.2.0
// allocate semaphore for shared surface // allocate semaphore for shared surface
#define REQID_ALLOC_SURF_SEM 0x001F #define REQID_ALLOC_SURF_SEM 0x001F
// free semaphore of shared surface // free semaphore of shared surface
#define REQID_FREE_SURF_SEM 0x0020 #define REQID_FREE_SURF_SEM 0x0020
#endif
/* Since 5.2.0 */
// Operate a shared surface to register/revoke the name and set the fd
#define REQID_OPERATENAMEDSSURF 0x001F
#define ID_NAMEDSSURFOP_REGISTER 1
#define ID_NAMEDSSURFOP_SET 2
#define ID_NAMEDSSURFOP_REVOKE 3
#define REQID_RESERVED 0x0020
// Move the current client to another layer // Move the current client to another layer
#define REQID_MOVETOLAYER 0x0021 #define REQID_MOVETOLAYER 0x0021
@@ -130,14 +142,7 @@
// Authenticate client // Authenticate client
#define REQID_AUTHCLIENT 0x0023 #define REQID_AUTHCLIENT 0x0023
/* Since 5.2.0 */ #define REQID_SYS_LAST REQID_AUTHCLIENT
// Operate a shared surface to register/revoke the name and set the fd
#define REQID_OPERATENAMEDSSURF 0x0024
#define ID_NAMEDSSURFOP_REGISTER 1
#define ID_NAMEDSSURFOP_SET 2
#define ID_NAMEDSSURFOP_REVOKE 3
#define REQID_SYS_LAST REQID_OPERATENAMEDSSURF
/* /*
* XXX: To fellows who need to add a new REQID, * XXX: To fellows who need to add a new REQID,
@@ -163,13 +168,13 @@ typedef struct OperateNSSurfInfo
/* Since 5.0.0 */ /* Since 5.0.0 */
typedef struct _SharedSurfInfo { typedef struct _SharedSurfInfo {
size_t size; // whole size of the surface
off_t offset; // offset of pixel data
uint32_t flags; // the flags of the surface uint32_t flags; // the flags of the surface
uint32_t width, height; uint32_t width, height;
uint32_t pitch; uint32_t pitch;
uint32_t name; // when use flink name uint32_t name; // when use flink name
uint32_t drm_format; // DRM pixel format uint32_t drm_format; // DRM pixel format
size_t size; // whole size of the surface
off_t offset; // offset of pixel data
} SHAREDSURFINFO; } SHAREDSURFINFO;
typedef struct JoinLayerInfo { typedef struct JoinLayerInfo {
@@ -378,6 +383,7 @@ void __mg_start_client_desktop (void);
void __mg_update_window (HWND hwnd, int left, int top, int right, int bottom); void __mg_update_window (HWND hwnd, int left, int top, int right, int bottom);
BOOL __mg_client_check_znode_hwnd (int slot, HWND hwnd, int cli);
BOOL __mg_client_check_hwnd (HWND hwnd, int cli); BOOL __mg_client_check_hwnd (HWND hwnd, int cli);
BOOL __mg_client_on_layer_changed (GHANDLE layer_handle, int zi_shmid); BOOL __mg_client_on_layer_changed (GHANDLE layer_handle, int zi_shmid);
+6 -4
View File
@@ -521,14 +521,16 @@ static inline void _dc_step_y (PDC pdc, int step)
# define BLOCK_DRAW_SEM(pdc) \ # define BLOCK_DRAW_SEM(pdc) \
do { \ do { \
if (pdc->surface->shared_header) \ if (pdc->surface->shared_header) { \
LOCK_SURFACE_SEM (pdc->surface->shared_header->sem_num); \ __mg_lock_file_for_write(pdc->surface->fd); \
} \
} while (0) } while (0)
# define UNBLOCK_DRAW_SEM(pdc) \ # define UNBLOCK_DRAW_SEM(pdc) \
do { \ do { \
if (pdc->surface->shared_header) \ if (pdc->surface->shared_header) { \
UNLOCK_SURFACE_SEM (pdc->surface->shared_header->sem_num); \ __mg_unlock_file_for_write(pdc->surface->fd); \
} \
} while (0) } while (0)
# define IS_SCREEN_SURFACE(pdc) \ # define IS_SCREEN_SURFACE(pdc) \
+10 -8
View File
@@ -51,12 +51,10 @@
#ifndef GUI_DRAWSEMOP_H #ifndef GUI_DRAWSEMOP_H
#define GUI_DRAWSEMOP_H #define GUI_DRAWSEMOP_H
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#include <errno.h> #include <errno.h>
#include "misc.h"
static inline void my_sem_op (int semid, int num, int op) static inline void my_sem_op (int semid, int num, int op)
{ {
struct sembuf sb; struct sembuf sb;
@@ -70,6 +68,9 @@ again:
if (errno == EINTR) { if (errno == EINTR) {
goto again; goto again;
} }
else {
_ERR_PRINTF("Failed semop: %m\n");
}
} }
} }
@@ -79,10 +80,7 @@ again:
#define LOCK_SCREEN_SEM() my_sem_op(SHAREDRES_SEMID, _IDX_SEM_SCR, -1) #define LOCK_SCREEN_SEM() my_sem_op(SHAREDRES_SEMID, _IDX_SEM_SCR, -1)
#define UNLOCK_SCREEN_SEM() my_sem_op(SHAREDRES_SEMID, _IDX_SEM_SCR, 1) #define UNLOCK_SCREEN_SEM() my_sem_op(SHAREDRES_SEMID, _IDX_SEM_SCR, 1)
#ifdef _MGSCHEMA_COMPOSITING extern int __mg_client_id;
# define LOCK_SURFACE_SEM(num) my_sem_op(SHAREDRES_SEMID_SHARED_SURF, num, -1)
# define UNLOCK_SURFACE_SEM(num) my_sem_op(SHAREDRES_SEMID_SHARED_SURF, num, 1)
#endif
#ifdef _MGHAVE_CURSOR #ifdef _MGHAVE_CURSOR
@@ -157,6 +155,10 @@ again:
# define UNLOCK_MOUSEMOVE_SEM() my_sem_op(SHAREDRES_SEMID, _IDX_SEM_MOUSEMOVE, 1) # define UNLOCK_MOUSEMOVE_SEM() my_sem_op(SHAREDRES_SEMID, _IDX_SEM_MOUSEMOVE, 1)
#endif /* _MGRM_PROCESSES */ #endif /* _MGRM_PROCESSES */
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif /* __cplusplus */ #endif /* __cplusplus */
+5 -38
View File
@@ -258,7 +258,7 @@ struct _MSGQUEUE
int loop_depth; // message loop depth, for dialog boxes int loop_depth; // message loop depth, for dialog boxes
int idle_counter; // the idle connter for MSG_IDLE int idle_counter; // the idle connter for MSG_IDLE
DWORD last_ticks_desktop; // the last tick count for desktop timer DWORD last_ticks; // the last tick count saved; since 5.0.14
/* Since 5.0.0, MiniGUI provides support for timers per message thread */ /* Since 5.0.0, MiniGUI provides support for timers per message thread */
int nr_timers; // the number of active timers int nr_timers; // the number of active timers
@@ -911,40 +911,9 @@ static inline MSGQUEUE* getMsgQueueIfMainWindowInThisThread (PMAINWIN pMainWin)
#endif /* defined _MGHAVE_VIRTUAL_WINDOW */ #endif /* defined _MGHAVE_VIRTUAL_WINDOW */
#if 0 /* deprecated code */ /* Since 5.0.14, remove arg use_sys_timer */
/* since 5.0.0, we always use QS_DESKTIMER for desktop timer */ BOOL mg_InitTimer (void);
/* since 5.0.0, we no longer use the timer thread */ void mg_TerminateTimer (void);
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*/ /*window element renderer manager interface*/
extern WINDOW_ELEMENT_RENDERER * __mg_def_renderer; extern WINDOW_ELEMENT_RENDERER * __mg_def_renderer;
@@ -958,9 +927,7 @@ BOOL gui_LoadIconRes(HDC hdc, const char* rdr_name, char* file);
void gui_WndRect(HWND hWnd, PRECT prc); void gui_WndRect(HWND hWnd, PRECT prc);
void gui_WndClientRect(HWND hWnd, PRECT prc); void gui_WndClientRect(HWND hWnd, PRECT prc);
/* Undisclosed APIs */ HDC __mg_create_memdc_for_surface (struct GAL_Surface* surface);
HDC CreateMemDCFromSurface (struct GAL_Surface* surface);
struct GAL_Surface* GetSurfaceFromDC (HDC hdc);
/* Since 5.0.0 */ /* Since 5.0.0 */
#ifdef _MGRM_PROCESSES #ifdef _MGRM_PROCESSES
+9 -2
View File
@@ -105,8 +105,15 @@ int __mg_map_get_size (map_t* map);
map_entry_t* __mg_map_find (map_t* map, const void* key); map_entry_t* __mg_map_find (map_t* map, const void* key);
int __mg_map_insert_ex (map_t* map, const void* key, map_entry_t* __mg_map_insert_ex2 (map_t* map, const void* key,
const void* val, free_val_fn free_val_alt); const void* val, free_val_fn free_val_alt);
static int __mg_map_insert_ex (map_t* map, const void* key,
const void* val, free_val_fn free_val_alt)
{
return __mg_map_insert_ex2(map, key, val, NULL) ? 0 : -1;
}
static inline int __mg_map_insert (map_t* map, const void* key, static inline int __mg_map_insert (map_t* map, const void* key,
const void* val) const void* val)
{ {
@@ -119,7 +126,7 @@ int __mg_map_find_replace_or_insert (map_t* map, const void* key,
int __mg_map_replace (map_t* map, const void* key, int __mg_map_replace (map_t* map, const void* key,
const void* val, free_val_fn free_val_alt); const void* val, free_val_fn free_val_alt);
int __mg_map_erase (map_t* map, void* key); int __mg_map_erase (map_t* map, const void* key);
int __mg_map_get_size (map_t* map); int __mg_map_get_size (map_t* map);
#if 0 /* deprecated code */ #if 0 /* deprecated code */
+7 -1
View File
@@ -79,6 +79,11 @@ struct timezone {
extern "C" { extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
void __mg_lock_file_for_read(int fd);
void __mg_unlock_file_for_read(int fd);
void __mg_lock_file_for_write(int fd);
void __mg_unlock_file_for_write(int fd);
unsigned int __mg_os_get_random_seed (void); unsigned int __mg_os_get_random_seed (void);
void __mg_os_time_delay (int ms); void __mg_os_time_delay (int ms);
void __mg_os_start_time (void); void __mg_os_start_time (void);
@@ -115,10 +120,11 @@ void mg_TerminateMisc (void);
BOOL mg_InitSystemRes (void); BOOL mg_InitSystemRes (void);
void mg_TerminateSystemRes (void); void mg_TerminateSystemRes (void);
/* Deprecated since 5.2.0
#ifdef _MGSCHEMA_COMPOSITING #ifdef _MGSCHEMA_COMPOSITING
int __mg_alloc_sem_for_shared_surf (void); int __mg_alloc_sem_for_shared_surf (void);
int __mg_free_sem_for_shared_surf (int sem_num); int __mg_free_sem_for_shared_surf (int sem_num);
#endif /* _MGSCHEMA_COMPOSITING */ #endif _MGSCHEMA_COMPOSITING */
size_t __mg_lookfor_unused_slot (unsigned char* bitmap, size_t len_bmp, int set); size_t __mg_lookfor_unused_slot (unsigned char* bitmap, size_t len_bmp, int set);
+4 -4
View File
@@ -396,10 +396,10 @@ char * __mg_msgstr3 [] =
"MSG_SRVNOTIFY", // 0x0147 "MSG_SRVNOTIFY", // 0x0147
"MSG_UPDATECLIWIN", // 0x0148 "MSG_UPDATECLIWIN", // 0x0148
"MSG_LAYERCHANGED", // 0x0149 "MSG_LAYERCHANGED", // 0x0149
"MSG_MANAGE_MSGTHREAD", // 0x014A "MSG_WINCOMPOSITED", // 0x014A
"MSG_CALC_POSITION", // 0x014B "MSG_MANAGE_MSGTHREAD", // 0x014B
"", // 0x014C "MSG_CALC_POSITION", // 0x014C
"", // 0x014D "MSG_WAKEUP_CLIENT", // 0x014D
"", // 0x014E "", // 0x014E
"", // 0x014F "", // 0x014F
+31 -14
View File
@@ -139,20 +139,25 @@ typedef struct _DirtyInfo {
* than the creator. * than the creator.
*/ */
typedef struct _SharedSurfaceHeader { typedef struct _SharedSurfaceHeader {
/* The number of semphore for this surface. /* the name of the shared surface; since 5.2.0. */
The SysV semaphore set id for synchronizing this shared surface: char name[NAME_MAX + 1];
SHAREDRES_SEMID_SHARED_SURF. */
int sem_num;
/* The pid of the creator */ /* The client identifier of the creator. */
pid_t creator; int create_cli;
/* The file descriptor in context of the creator. */
int fd;
/* Not zero for hardware surface. */ /* Not zero for hardware surface. */
int byhw; int byhw;
/* The dirty information */
GAL_DirtyInfo dirty_info; /* Deprecated since 5.2.0.
The number of semphore for this surface.
The SysV semaphore set id for synchronizing this shared surface:
SHAREDRES_SEMID_SHARED_SURF.
int sem_num; */
/* Deprecated since 5.2.0.
The file descriptor in context of the creator.
int fd; */
/* the size of the surface */ /* the size of the surface */
int width, height; int width, height;
/* the pitch of the surface */ /* the pitch of the surface */
@@ -166,6 +171,9 @@ typedef struct _SharedSurfaceHeader {
size_t map_size; size_t map_size;
/* the offset of pixels data */ /* the offset of pixels data */
off_t pixels_off; off_t pixels_off;
/* The dirty information */
GAL_DirtyInfo dirty_info;
} GAL_SharedSurfaceHeader; } GAL_SharedSurfaceHeader;
#endif /* IS_COMPOSITING_SCHEMA */ #endif /* IS_COMPOSITING_SCHEMA */
@@ -230,6 +238,8 @@ typedef struct GAL_Surface {
GAL_SharedSurfaceHeader *shared_header; /* Private */ GAL_SharedSurfaceHeader *shared_header; /* Private */
/* The dirty info for non-shared surface. */ /* The dirty info for non-shared surface. */
GAL_DirtyInfo *dirty_info; /* Private */ GAL_DirtyInfo *dirty_info; /* Private */
/* The file descriptor if the surface is a shared surface. */
int fd; /* Private; since 5.2.0. */
#endif #endif
} GAL_Surface; } GAL_Surface;
@@ -252,6 +262,8 @@ typedef struct GAL_Surface {
#define GAL_PREALLOC 0x01000000 /* Surface uses preallocated memory */ #define GAL_PREALLOC 0x01000000 /* Surface uses preallocated memory */
#define GAL_FORMAT_CHECKED 0x02000000 /* Pixman format checked */ #define GAL_FORMAT_CHECKED 0x02000000 /* Pixman format checked */
#define GAL_SSURF_ATTACHED 0x04000000 /* The shared surface is attached to. */
#define GAL_SSURF_LOCKED 0x08000000 /* The shared surface is locked. */
/* Available for GAL_SetVideoMode() */ /* Available for GAL_SetVideoMode() */
#define GAL_ANYFORMAT 0x10000000 /* Allow any video depth/pixel-format */ #define GAL_ANYFORMAT 0x10000000 /* Allow any video depth/pixel-format */
@@ -571,6 +583,11 @@ GAL_Surface *GAL_CreateRGBSurface
GAL_Surface *GAL_CreateRGBSurfaceFrom (void *pixels, GAL_Surface *GAL_CreateRGBSurfaceFrom (void *pixels,
int width, int height, int depth, int pitch, int width, int height, int depth, int pitch,
Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask); Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask);
/* Since 5.2.0 */
static GAL_Surface *GAL_RefSurface (GAL_Surface *surface) {
surface->refcount++;
return surface;
}
void GAL_FreeSurface (GAL_Surface *surface); void GAL_FreeSurface (GAL_Surface *surface);
typedef struct REQ_HWSURFACE { typedef struct REQ_HWSURFACE {
@@ -651,11 +668,11 @@ GAL_Surface *GAL_CreateSurfaceForZNodeAs (const GAL_Surface* ref_surf,
void GAL_FreeSharedSurfaceData (GAL_Surface *surface); void GAL_FreeSharedSurfaceData (GAL_Surface *surface);
/* Attach to a shared RGB surface. */ /* Attach to a shared RGB surface. */
GAL_Surface *GAL_AttachSharedRGBSurface (int fd, size_t map_size, GAL_Surface *GAL_AttachSharedRGBSurface (GAL_VideoDevice* video,
Uint32 flags, BOOL with_wr); int fd, size_t map_size, Uint32 flags, BOOL with_wr);
/* Dettach from a shared RGB surface from the specific video device. */ /* Detach from a shared RGB surface from the specific video device. */
void GAL_DettachSharedSurfaceData (GAL_Surface *surface); void GAL_DetachSharedSurfaceData (GAL_Surface *surface);
/* Create a cursor surface from the specific video device. */ /* Create a cursor surface from the specific video device. */
GAL_Surface* GAL_CreateCursorSurface (GAL_VideoDevice* video, GAL_Surface* GAL_CreateCursorSurface (GAL_VideoDevice* video,
+3
View File
@@ -135,6 +135,9 @@ void __mg_release_global_res (int cli);
/* Since 5.2.0 */ /* Since 5.2.0 */
int __mg_nssurf_map_new(void); int __mg_nssurf_map_new(void);
void __mg_nssurf_map_delete(void); void __mg_nssurf_map_delete(void);
int __mg_nssurf_map_operate_srv(const OPERATENSSURFINFO* req_info,
int cli, int fd);
int __mg_get_shared_surface_srv(const char *itn_name, SHAREDSURFINFO *info);
void __mg_remove_client (int cli, int clifd); void __mg_remove_client (int cli, int clifd);
+2 -2
View File
@@ -112,7 +112,7 @@ typedef struct tagG_RES {
int nr_layers; int nr_layers;
int semid_layer; int semid_layer;
#ifdef _MGSCHEMA_COMPOSITING #if 0 && defined(_MGSCHEMA_COMPOSITING) // deprecated since 5.2.0
int semid_shared_surf; /* the id of semaphore set for shared surfaces */ int semid_shared_surf; /* the id of semaphore set for shared surfaces */
#endif #endif
@@ -208,7 +208,7 @@ typedef G_RES* PG_RES;
#define SHAREDRES_NR_LAYSERS (((PG_RES)mgSharedRes)->nr_layers) #define SHAREDRES_NR_LAYSERS (((PG_RES)mgSharedRes)->nr_layers)
#define SHAREDRES_SEMID_LAYER (((PG_RES)mgSharedRes)->semid_layer) #define SHAREDRES_SEMID_LAYER (((PG_RES)mgSharedRes)->semid_layer)
#ifdef _MGSCHEMA_COMPOSITING #if 0 && defined(_MGSCHEMA_COMPOSITING) // Deprecated since 5.2.0
# define SHAREDRES_SEMID_SHARED_SURF (((PG_RES)mgSharedRes)->semid_shared_surf) # define SHAREDRES_SEMID_SHARED_SURF (((PG_RES)mgSharedRes)->semid_shared_surf)
#endif #endif
+1 -1
View File
@@ -74,7 +74,7 @@ typedef struct _MSGQUEUE MSGQUEUE;
extern "C" { extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
void __mg_update_tick_count (void* data); DWORD __mg_update_tick_count (MSGQUEUE* msg_queue);
int __mg_check_expired_timers (MSGQUEUE* msg_queue, DWORD inter); int __mg_check_expired_timers (MSGQUEUE* msg_queue, DWORD inter);
void __mg_remove_timers_by_msg_queue (MSGQUEUE* msg_queue); void __mg_remove_timers_by_msg_queue (MSGQUEUE* msg_queue);
void __mg_remove_timer (MSGQUEUE* msg_queue, int slot); void __mg_remove_timer (MSGQUEUE* msg_queue, int slot);
+18 -1
View File
@@ -679,6 +679,19 @@ static BOOL merge_dirty_ppp (CompositorCtxt* ctxt, MG_Layer* layer, int zidx)
return rc; return rc;
} }
#if 0
static void dump_dirty_region(CompositorCtxt* ctxt, const char *prefix, int zidx)
{
CLIPRGN* rgn = &ctxt->dirty_rgn;
_WRN_PRINTF("%s (%d): dirty region on screen: (%d, %d) %d x %d; "
"highest dirty win: %d; lowest dirty win: %d\n",
prefix, zidx,
rgn->rcBound.left, rgn->rcBound.top,
RECTW (rgn->rcBound), RECTH (rgn->rcBound),
ctxt->highest_dirty_win, ctxt->lowest_dirty_win);
}
#endif
static BOOL merge_dirty_win (CompositorCtxt* ctxt, MG_Layer* layer, int zidx) static BOOL merge_dirty_win (CompositorCtxt* ctxt, MG_Layer* layer, int zidx)
{ {
BOOL rc = FALSE; BOOL rc = FALSE;
@@ -722,9 +735,13 @@ static BOOL merge_dirty_wpp (CompositorCtxt* ctxt, MG_Layer* layer)
static BOOL refresh_dirty_region (CompositorCtxt* ctxt, MG_Layer* layer) static BOOL refresh_dirty_region (CompositorCtxt* ctxt, MG_Layer* layer)
{ {
/* the fallback compositor only manages znodes on the topmost layer. */ /* the fallback compositor only manages znodes on the topmost layer. */
if (layer != mgTopmostLayer || IsEmptyClipRgn (&ctxt->dirty_rgn)) if (layer != mgTopmostLayer)
return FALSE; return FALSE;
if (IsEmptyClipRgn (&ctxt->dirty_rgn)) {
return FALSE;
}
if (ctxt->highest_dirty_ppp >= 0) { if (ctxt->highest_dirty_ppp >= 0) {
composite_ppp_znodes (ctxt); composite_ppp_znodes (ctxt);
} }
+32 -16
View File
@@ -56,7 +56,6 @@
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#define _DEBUG
#include "common.h" #include "common.h"
#if defined(_MGRM_PROCESSES) && defined(_MGSCHEMA_COMPOSITING) #if defined(_MGRM_PROCESSES) && defined(_MGSCHEMA_COMPOSITING)
@@ -69,6 +68,7 @@
#include "constants.h" #include "constants.h"
#include "zorder.h" #include "zorder.h"
#include "dc.h" #include "dc.h"
#include "server.h"
#define MAX_NR_COMPOSITORS 8 #define MAX_NR_COMPOSITORS 8
#define LEN_COMPOSITOR_NAME 15 #define LEN_COMPOSITOR_NAME 15
@@ -133,31 +133,51 @@ static void lock_znode_surface (PDC pdc, ZORDERNODE* node)
{ {
if (node->lock_count == 0) { if (node->lock_count == 0) {
if (pdc->surface->shared_header) { if (pdc->surface->shared_header) {
LOCK_SURFACE_SEM (pdc->surface->shared_header->sem_num); __mg_lock_file_for_read(pdc->surface->fd);
} }
node->dirty_age = pdc->surface->dirty_info->dirty_age; node->dirty_age = pdc->surface->dirty_info->dirty_age;
node->nr_dirty_rcs = pdc->surface->dirty_info->nr_dirty_rcs; node->nr_dirty_rcs = pdc->surface->dirty_info->nr_dirty_rcs;
node->dirty_rcs = pdc->surface->dirty_info->dirty_rcs; node->dirty_rcs = pdc->surface->dirty_info->dirty_rcs;
} }
node->lock_count++; node->lock_count++;
} }
static void unlock_znode_surface (PDC pdc, ZORDERNODE* node) static BOOL unlock_znode_surface (PDC pdc, ZORDERNODE* node)
{ {
BOOL need_reset = FALSE;
if (node->lock_count > 0) { if (node->lock_count > 0) {
node->lock_count--; node->lock_count--;
if (node->lock_count == 0) { if (node->lock_count == 0) {
if (pdc->surface->shared_header) if (node->changes != pdc->surface->dirty_info->dirty_age) {
UNLOCK_SURFACE_SEM (pdc->surface->shared_header->sem_num); node->changes = pdc->surface->dirty_info->dirty_age;
need_reset = TRUE;
}
if (pdc->surface->shared_header) {
__mg_unlock_file_for_read(pdc->surface->fd);
}
node->dirty_age = 0; node->dirty_age = 0;
node->nr_dirty_rcs = 0; node->nr_dirty_rcs = 0;
node->dirty_rcs = NULL; node->dirty_rcs = NULL;
} }
} }
return need_reset;
}
static void reset_znode_surface_dirty (PDC pdc, ZORDERNODE* node, int slot)
{
if (node->cli == 0 || slot == 0) {
pdc->surface->dirty_info->nr_dirty_rcs = 0;
}
else if (node->hwnd) {
MSG msg = { HWND_NULL, MSG_WINCOMPOSITED,
slot, (LPARAM)node->hwnd, (DWORD)node->changes };
__mg_send2client(&msg, mgClients + node->cli);
}
} }
#if 0 /* not optimized */ #if 0 /* not optimized */
@@ -322,10 +342,8 @@ static void composite_layer (MG_Layer* layer, CompositorCtxt* ctxt,
nodes = GET_MENUNODE(zi); nodes = GET_MENUNODE(zi);
for (i = 0; i < zi->nr_popupmenus; i++) { for (i = 0; i < zi->nr_popupmenus; i++) {
pdc = dc_HDC2PDC (nodes[i].mem_dc); pdc = dc_HDC2PDC (nodes[i].mem_dc);
if (unlock_znode_surface (pdc, nodes + i))
nodes[i].changes = pdc->surface->dirty_info->dirty_age; reset_znode_surface_dirty (pdc, nodes + i, i);
pdc->surface->dirty_info->nr_dirty_rcs = 0;
unlock_znode_surface (pdc, nodes + i);
} }
} }
@@ -335,9 +353,8 @@ static void composite_layer (MG_Layer* layer, CompositorCtxt* ctxt,
while ((next = __kernel_get_next_znode (zi, next)) > 0) { while ((next = __kernel_get_next_znode (zi, next)) > 0) {
if (nodes [next].flags & ZOF_VISIBLE) { if (nodes [next].flags & ZOF_VISIBLE) {
pdc = dc_HDC2PDC (nodes[next].mem_dc); pdc = dc_HDC2PDC (nodes[next].mem_dc);
nodes[next].changes = pdc->surface->dirty_info->dirty_age; if (unlock_znode_surface (pdc, nodes + next))
pdc->surface->dirty_info->nr_dirty_rcs = 0; reset_znode_surface_dirty (pdc, nodes + next, next);
unlock_znode_surface (pdc, nodes + next);
} }
} }
@@ -346,9 +363,8 @@ static void composite_layer (MG_Layer* layer, CompositorCtxt* ctxt,
if (layer == mgTopmostLayer) { if (layer == mgTopmostLayer) {
pdc = dc_HDC2PDC (HDC_SCREEN); pdc = dc_HDC2PDC (HDC_SCREEN);
if (pdc->surface->w > 0 && pdc->surface->h > 0) { if (pdc->surface->w > 0 && pdc->surface->h > 0) {
nodes[0].changes = pdc->surface->dirty_info->dirty_age; if (unlock_znode_surface (pdc, nodes))
pdc->surface->dirty_info->nr_dirty_rcs = 0; reset_znode_surface_dirty (pdc, nodes, 0);
unlock_znode_surface (pdc, nodes);
} }
} }
} }
+36 -16
View File
@@ -365,7 +365,7 @@ static intptr_t cliAllocZOrderNode (PMAINWIN pWin, const COMPOSITINGINFO* ct_inf
} }
if (ClientRequestEx2 (&req, caption, strlen(caption) + 1, if (ClientRequestEx2 (&req, caption, strlen(caption) + 1,
pWin->surf->shared_header->fd, pWin->surf->fd,
&ret, sizeof (intptr_t), NULL) < 0) &ret, sizeof (intptr_t), NULL) < 0)
return -1; return -1;
#else /* ndef _MGSCHEMA_COMPOSITING */ #else /* ndef _MGSCHEMA_COMPOSITING */
@@ -524,7 +524,7 @@ static intptr_t cliStartTrackPopupMenu (PTRACKMENUINFO ptmi)
info.surf_flags = surf->flags; info.surf_flags = surf->flags;
info.surf_size = surf->shared_header->map_size; info.surf_size = surf->shared_header->map_size;
if (ClientRequestEx2 (&req, NULL, 0, surf->shared_header->fd, if (ClientRequestEx2 (&req, NULL, 0, surf->fd,
&ret, sizeof (intptr_t), NULL) < 0) &ret, sizeof (intptr_t), NULL) < 0)
return -1; return -1;
} }
@@ -837,8 +837,10 @@ static int srvAllocZOrderNode (int cli, HWND hwnd, HWND main_win,
surf->refcount++; surf->refcount++;
} }
else if (fd >= 0) { else if (fd >= 0) {
surf = GAL_AttachSharedRGBSurface (fd, surf_size, surf_flags, TRUE); surf = GAL_AttachSharedRGBSurface (NULL, fd,
close (fd); surf_size, surf_flags, TRUE);
/* Since 5.2.0: keep fd available.
close (fd); */
} }
else { else {
_ERR_PRINTF("KERNEL: not server but fd for shared surface is invalid\n"); _ERR_PRINTF("KERNEL: not server but fd for shared surface is invalid\n");
@@ -846,7 +848,7 @@ static int srvAllocZOrderNode (int cli, HWND hwnd, HWND main_win,
} }
if (surf) { if (surf) {
memdc = CreateMemDCFromSurface (surf); memdc = __mg_create_memdc_for_surface (surf);
if (memdc == HDC_INVALID) { if (memdc == HDC_INVALID) {
if (cli > 0) { if (cli > 0) {
GAL_FreeSurface (surf); GAL_FreeSurface (surf);
@@ -994,12 +996,14 @@ static int srvMoveWindow (int cli, int idx_znode, const RECT* rcWin,
surf->refcount++; surf->refcount++;
} }
else { else {
surf = GAL_AttachSharedRGBSurface (fd, surf_size, surf_flags, TRUE); surf = GAL_AttachSharedRGBSurface (NULL, fd,
close (fd); surf_size, surf_flags, TRUE);
/* Since 5.2.0: keep fd available.
close (fd); */
} }
if (surf) { if (surf) {
memdc = CreateMemDCFromSurface (surf); memdc = __mg_create_memdc_for_surface (surf);
if (memdc == HDC_INVALID) { if (memdc == HDC_INVALID) {
if (cli > 0) { if (cli > 0) {
GAL_FreeSurface (surf); GAL_FreeSurface (surf);
@@ -1014,7 +1018,6 @@ static int srvMoveWindow (int cli, int idx_znode, const RECT* rcWin,
return -1; return -1;
} }
} }
#endif /* def _MGSCHEMA_COMPOSITING */ #endif /* def _MGSCHEMA_COMPOSITING */
ret = dskMoveWindow (cli, idx_znode, memdc, rcWin); ret = dskMoveWindow (cli, idx_znode, memdc, rcWin);
@@ -2208,7 +2211,7 @@ static int resize_window_surface (PMAINWIN pWin, const RECT* prcResult)
pWin->surf = new_surf; pWin->surf = new_surf;
if (pWin->surf->shared_header) if (pWin->surf->shared_header)
return pWin->surf->shared_header->fd; return pWin->surf->fd;
else else
return 0; return 0;
} }
@@ -2253,9 +2256,10 @@ static int dskMoveGlobalControl (PMAINWIN pCtrl, RECT* prcExpect)
} }
#ifdef _MGSCHEMA_COMPOSITING #ifdef _MGSCHEMA_COMPOSITING
if (pCtrl->surf->shared_header && pCtrl->surf->shared_header->fd >= 0) { /* Since 5.2.0: keep fd available. */
close (pCtrl->surf->shared_header->fd); if (0 && pCtrl->surf->shared_header && pCtrl->surf->fd >= 0) {
pCtrl->surf->shared_header->fd = -1; close (pCtrl->surf->fd);
pCtrl->surf->fd = -1;
} }
#endif #endif
@@ -2284,9 +2288,10 @@ static int dskMoveMainWindow (PMAINWIN pWin, RECT* prcExpect)
__mg_update_dc_on_surface_changed ((HWND)pWin, pWin->surf); __mg_update_dc_on_surface_changed ((HWND)pWin, pWin->surf);
} }
if (pWin->surf->shared_header && pWin->surf->shared_header->fd >= 0) { /* Since 5.2.0: keep fd available. */
close (pWin->surf->shared_header->fd); if (0 && pWin->surf->shared_header && pWin->surf->fd >= 0) {
pWin->surf->shared_header->fd = -1; close (pWin->surf->fd);
pWin->surf->fd = -1;
} }
#endif #endif
@@ -2902,6 +2907,21 @@ int __mg_handle_mouse_hook (int message, WPARAM wParam, LPARAM lParam)
} }
#endif /* deprecated code */ #endif /* deprecated code */
/* used by client to check the validation of a hwnd in the given znode slot. */
BOOL __mg_client_check_znode_hwnd (int slot, HWND hwnd, int cli)
{
BOOL ret = FALSE;
ZORDERINFO* zi = __mg_zorder_info;
ZORDERNODE* nodes;
nodes = GET_ZORDERNODE(zi);
lock_zi_for_read (zi);
if (nodes[slot].hwnd == hwnd && nodes[slot].cli == cli)
ret = TRUE;
unlock_zi_for_read (zi);
return ret;
}
/* used by client to check the validation of a hwnd */ /* used by client to check the validation of a hwnd */
BOOL __mg_client_check_hwnd (HWND hwnd, int cli) BOOL __mg_client_check_hwnd (HWND hwnd, int cli)
{ {
+24 -5
View File
@@ -55,6 +55,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <math.h> #include <math.h>
#include <time.h>
#include "common.h" #include "common.h"
@@ -141,12 +142,31 @@ BOOL mg_InitDesktop (void)
#include "debug.h" #include "debug.h"
static IDLEHANDLER std_idle_handler; /* According to a bug report, we use sem_timedwait() instead of
calling std_idle_handler for desktop thread.
Otherwise, the desktop might not handle the request from other GUI threads
as soon as possible. */
static BOOL idle_handler_for_desktop_thread (MSGQUEUE *msg_queue, BOOL wait) static BOOL idle_handler_for_desktop_thread (MSGQUEUE *msg_queue, BOOL wait)
{ {
__mg_update_tick_count (NULL); int retv, n = 0;
return std_idle_handler (msg_queue, wait);
__mg_update_tick_count (msg_queue);
if (wait) {
struct timespec ts;
if (clock_gettime (CLOCK_REALTIME, &ts) != -1) {
ts.tv_nsec += 10 * 1000 * 1000L; // 10ms
if (ts.tv_nsec >= 1000 * 1000 * 1000L) {
ts.tv_sec += 1;
ts.tv_nsec -= 1000 * 1000 * 1000L;
}
if (sem_timedwait (&msg_queue->wait, &ts) == 0)
return TRUE;
}
}
return n > 0;
} }
void* __kernel_desktop_main (void* data) void* __kernel_desktop_main (void* data)
@@ -162,7 +182,6 @@ void* __kernel_desktop_main (void* data)
/* For bug reported in Issue #116, under threads mode, the idle handler /* For bug reported in Issue #116, under threads mode, the idle handler
for the desktop thread should call __mg_update_tick_count () */ for the desktop thread should call __mg_update_tick_count () */
std_idle_handler = __mg_dsk_msg_queue->OnIdle;
__mg_dsk_msg_queue->OnIdle = idle_handler_for_desktop_thread; __mg_dsk_msg_queue->OnIdle = idle_handler_for_desktop_thread;
/* init desktop window */ /* init desktop window */
+10 -3
View File
@@ -1603,8 +1603,10 @@ static int srvStartTrackPopupMenu (int cli, const RECT* rc, HWND ptmi,
surf->refcount++; surf->refcount++;
} }
else if (fd >= 0) { else if (fd >= 0) {
surf = GAL_AttachSharedRGBSurface (fd, surf_size, surf_flags, TRUE); surf = GAL_AttachSharedRGBSurface (NULL, fd,
close (fd); surf_size, surf_flags, TRUE);
/* Since 5.2.0: keep fd available.
close (fd); */
} }
else { else {
_WRN_PRINTF("not server but fd for shared surface is invalid\n"); _WRN_PRINTF("not server but fd for shared surface is invalid\n");
@@ -1612,7 +1614,7 @@ static int srvStartTrackPopupMenu (int cli, const RECT* rc, HWND ptmi,
} }
if (surf) { if (surf) {
memdc = CreateMemDCFromSurface (surf); memdc = __mg_create_memdc_for_surface (surf);
if (memdc == HDC_INVALID) { if (memdc == HDC_INVALID) {
GAL_FreeSurface (surf); GAL_FreeSurface (surf);
_WRN_PRINTF("failed to create memory dc for znode\n"); _WRN_PRINTF("failed to create memory dc for znode\n");
@@ -1646,11 +1648,14 @@ static int srvStartTrackPopupMenu (int cli, const RECT* rc, HWND ptmi,
menu_nodes [zi->nr_popupmenus].flags = ZOF_TYPE_POPUPMENU; menu_nodes [zi->nr_popupmenus].flags = ZOF_TYPE_POPUPMENU;
menu_nodes [zi->nr_popupmenus].rc = *rc; menu_nodes [zi->nr_popupmenus].rc = *rc;
menu_nodes [zi->nr_popupmenus].hwnd = ptmi; menu_nodes [zi->nr_popupmenus].hwnd = ptmi;
menu_nodes [zi->nr_popupmenus].cli = 0;
#ifdef _MGSCHEMA_COMPOSITING #ifdef _MGSCHEMA_COMPOSITING
menu_nodes [zi->nr_popupmenus].changes = 0; menu_nodes [zi->nr_popupmenus].changes = 0;
menu_nodes [zi->nr_popupmenus].ct = CT_OPAQUE; menu_nodes [zi->nr_popupmenus].ct = CT_OPAQUE;
menu_nodes [zi->nr_popupmenus].ct_arg = 0; menu_nodes [zi->nr_popupmenus].ct_arg = 0;
menu_nodes [zi->nr_popupmenus].mem_dc = memdc; menu_nodes [zi->nr_popupmenus].mem_dc = memdc;
menu_nodes [zi->nr_popupmenus].dirty_age = 0;
menu_nodes [zi->nr_popupmenus].nr_dirty_rcs = 0;
menu_nodes [zi->nr_popupmenus].dirty_rcs = NULL; menu_nodes [zi->nr_popupmenus].dirty_rcs = NULL;
#endif #endif
menu_nodes [zi->nr_popupmenus].priv_data = NULL; menu_nodes [zi->nr_popupmenus].priv_data = NULL;
@@ -2356,6 +2361,8 @@ static int AllocZOrderNodeEx (ZORDERINFO* zi, int cli, HWND hwnd, HWND main_win,
nodes [free_slot].ct = validate_compositing_type (flags, ct); nodes [free_slot].ct = validate_compositing_type (flags, ct);
nodes [free_slot].ct_arg = ct_arg; nodes [free_slot].ct_arg = ct_arg;
nodes [free_slot].mem_dc = mem_dc; nodes [free_slot].mem_dc = mem_dc;
nodes [free_slot].dirty_age = 0;
nodes [free_slot].nr_dirty_rcs = 0;
nodes [free_slot].dirty_rcs = NULL; nodes [free_slot].dirty_rcs = NULL;
#else #else
nodes [free_slot].age = 1; nodes [free_slot].age = 1;
+8 -8
View File
@@ -562,6 +562,13 @@ int GUIAPI InitGUI (int args, const char *agr[])
_is_minigui_running = 1; _is_minigui_running = 1;
/* init timer for tick counter */
step++;
if (!mg_InitTimer()) {
_ERR_PRINTF ("KERNEL>InitGUI: failed to start time counter\n");
goto failure;
}
step++; step++;
if (!SystemThreads()) { if (!SystemThreads()) {
_ERR_PRINTF ("KERNEL>InitGUI: failed to init system threads!\n"); _ERR_PRINTF ("KERNEL>InitGUI: failed to init system threads!\n");
@@ -575,13 +582,6 @@ int GUIAPI InitGUI (int args, const char *agr[])
goto failure; goto failure;
} }
/* init timer for tick counter */
step++;
if (!mg_InitTimer (FALSE)) {
_ERR_PRINTF ("KERNEL>InitGUI: failed to start time counter\n");
goto failure;
}
SetKeyboardLayout ("default"); SetKeyboardLayout ("default");
SetCursor (GetSystemCursor (IDC_ARROW)); SetCursor (GetSystemCursor (IDC_ARROW));
@@ -602,7 +602,7 @@ failure1:
void GUIAPI TerminateGUI (int not_used) void GUIAPI TerminateGUI (int not_used)
{ {
mg_TerminateTimer (FALSE); mg_TerminateTimer ();
mg_FreeMsgQueueForThisThread (TRUE); mg_FreeMsgQueueForThisThread (TRUE);
+55 -139
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -7,7 +7,7 @@ EXTRA_DIST= misc.c systext.c rwops.c endianrw.c nposix.c clipboard.c \
libmisc_la_SOURCES = misc.c systext.c rwops.c endianrw.c nposix.c clipboard.c \ libmisc_la_SOURCES = misc.c systext.c rwops.c endianrw.c nposix.c clipboard.c \
math.c about.c license.c anon_file.c rbtree.c map.c \ math.c about.c license.c anon_file.c rbtree.c map.c \
error.c sockio.c error.c sockio.c lock_file.c
SRC_FILES = $(libmisc_la_SOURCES) SRC_FILES = $(libmisc_la_SOURCES)
LIB_NAME=libmisc LIB_NAME=libmisc
+1 -1
View File
@@ -114,7 +114,7 @@ static LRESULT AboutWinProc (HWND hWnd, UINT message,
DrawText (hdc, DrawText (hdc,
"MiniGUI -- a mature cross-platform windowing system " "MiniGUI -- a mature cross-platform windowing system "
"and GUI support system for embedded or IoT devices.\n\n" "and GUI support system for embedded or IoT devices.\n\n"
"Copyright (C) 2002 ~ 2020 FMSoft Co., Ltd.", "Copyright (C) 2002 ~ 2023 FMSoft Co., Ltd.",
-1, &rcClient, DT_WORDBREAK | DT_CENTER); -1, &rcClient, DT_WORDBREAK | DT_CENTER);
EndPaint (hWnd, hdc); EndPaint (hWnd, hdc);
+112
View File
@@ -0,0 +1,112 @@
///////////////////////////////////////////////////////////////////////////////
//
// 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) 2023, Beijing FMSoft Technologies Co., Ltd.
*
* 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/>.
*/
/*
** lock_file.c: This file include functions for locking/unlocking a file.
**
** Create date: 2023/09/10
**
** Current maintainer: Wei Yongming.
*/
#include "common.h"
#ifndef __NOUNIX__
#include "misc.h"
#include <unistd.h>
#include <sys/file.h>
#include <fcntl.h>
#include <errno.h>
void __mg_lock_file_for_read(int fd)
{
struct flock lock;
lock.l_type = F_RDLCK;
lock.l_whence = SEEK_SET;
lock.l_start = 0;
lock.l_len = 0;
while (fcntl(fd, F_SETLKW, &lock) == -1 && errno == EINTR);
}
void __mg_unlock_file_for_read(int fd)
{
struct flock lock;
lock.l_type = F_UNLCK;
lock.l_whence = SEEK_SET;
lock.l_start = 0;
lock.l_len = 0;
fcntl(fd, F_SETLK, &lock);
}
void __mg_lock_file_for_write(int fd)
{
struct flock lock;
lock.l_type = F_WRLCK;
lock.l_whence = SEEK_SET;
lock.l_start = 0;
lock.l_len = 0;
while (fcntl(fd, F_SETLKW, &lock) == -1 && errno == EINTR);
}
void __mg_unlock_file_for_write(int fd)
{
struct flock lock;
lock.l_type = F_UNLCK;
lock.l_whence = SEEK_SET;
lock.l_start = 0;
lock.l_len = 0;
fcntl(fd, F_SETLK, &lock);
}
#endif /* __NOUNIX__ */
+4 -4
View File
@@ -243,7 +243,7 @@ map_entry_t* __mg_map_find (map_t* map, const void* key)
return entry; return entry;
} }
int __mg_map_erase (map_t* map, void* key) int __mg_map_erase (map_t* map, const void* key)
{ {
int retval = -1; int retval = -1;
map_entry_t* entry = NULL; map_entry_t* entry = NULL;
@@ -299,7 +299,7 @@ ret:
return retval; return retval;
} }
int __mg_map_insert_ex (map_t* map, const void* key, map_entry_t* __mg_map_insert_ex2 (map_t* map, const void* key,
const void* val, free_val_fn free_val_alt) const void* val, free_val_fn free_val_alt)
{ {
map_entry_t **pentry; map_entry_t **pentry;
@@ -307,7 +307,7 @@ int __mg_map_insert_ex (map_t* map, const void* key,
map_entry_t *parent; map_entry_t *parent;
if (map == NULL) if (map == NULL)
return -1; return NULL;
WRLOCK_MAP (map); WRLOCK_MAP (map);
@@ -354,7 +354,7 @@ int __mg_map_insert_ex (map_t* map, const void* key,
} }
UNLOCK_MAP (map); UNLOCK_MAP (map);
return 0; return entry;
} }
int __mg_map_find_replace_or_insert (map_t* map, const void* key, int __mg_map_find_replace_or_insert (map_t* map, const void* key,
-84
View File
@@ -495,28 +495,6 @@ DWORD __mg_os_get_time_ticks (void)
return (current - startup_time_win32) / 10; return (current - startup_time_win32) / 10;
} }
#if 0 /* deprecated code */
DWORD __mg_os_get_elapsed_ms (void)
{
static DWORD last;
DWORD current = timeGetTime();
DWORD elapsed;
if (current >= last) {
elapsed = current - last;
return elapsed;
}
else {
/* overflowed */
elapsed = BITMASK_DWORD - last;
elapsed += current;
}
last = current;
return elapsed;
}
#endif /* deprecated code */
#elif defined (HAVE_CLOCK_GETTIME) #elif defined (HAVE_CLOCK_GETTIME)
static struct timespec timeval_startup; static struct timespec timeval_startup;
@@ -573,68 +551,6 @@ DWORD __mg_os_get_time_ticks (void)
return ds * 100 + dms; return ds * 100 + dms;
} }
#if 0 /* deprecated code */
DWORD __mg_os_get_elapsed_ms (void)
{
static struct timespec last;
DWORD ds, dms;
struct timespec current;
clock_gettime (CLOCK_MONOTONIC, &current);
ds = (current.tv_sec - last.tv_sec);
if (current.tv_sec == last.tv_sec) {
dms = (current.tv_nsec - last.tv_nsec) / 1000000L;
}
else if (current.tv_nsec >= last.tv_nsec) {
dms = (current.tv_nsec - last.tv_nsec) / 1000000L;
}
else {
assert (ds > 0);
ds--;
dms = 1000L - (last.tv_nsec - current.tv_nsec) / 1000000L;
}
last = current;
return ds * 1000 + dms;
}
#include <unistd.h>
#include <poll.h>
#include <sys/time.h>
static struct timeval timeval_startup;
void __mg_os_start_time(void)
{
gettimeofday(&timeval_startup, NULL);
}
DWORD __mg_os_get_time_ms(void)
{
DWORD ds, dms;
struct timeval current;
gettimeofday(&current, NULL);
ds = (current.tv_sec - timeval_startup.tv_sec);
if (current.tv_sec == timeval_startup.tv_sec) {
dms = (current.tv_usec - timeval_startup.tv_usec) / 1000L;
}
else if (current.tv_usec >= timeval_startup.tv_usec) {
dms = (current.tv_usec - timeval_startup.tv_usec) / 1000L;
}
else {
assert(ds > 0);
ds--;
dms = 1000L - (timeval_startup.tv_usec - current.tv_usec) / 1000L;
}
return ds * 1000 + dms;
}
#endif /* deprecated code */
#else /* defined HAVE_CLOCK_GETTIME */ #else /* defined HAVE_CLOCK_GETTIME */
#error "Please implement __mg_os_start_time and __mg_os_get_time_ticks for your OS" #error "Please implement __mg_os_start_time and __mg_os_get_time_ticks for your OS"
+4
View File
@@ -96,8 +96,12 @@ static BITMAP_TYPE_INFO bitmap_types [MAX_BITMAP_TYPES] =
{ "jpeg", __mg_init_jpg, __mg_load_jpg, __mg_cleanup_jpg, __mg_save_jpg, __mg_check_jpg }, { "jpeg", __mg_init_jpg, __mg_load_jpg, __mg_cleanup_jpg, __mg_save_jpg, __mg_check_jpg },
#endif #endif
#ifdef _MGIMAGE_PNG #ifdef _MGIMAGE_PNG
#if _MGLIBPNG_VER == 16
{ "png", __mg_init_png, __mg_load_png, __mg_cleanup_png, __mg_save_png, __mg_check_png },
#else
{ "png", __mg_init_png, __mg_load_png, __mg_cleanup_png, NULL, __mg_check_png }, { "png", __mg_init_png, __mg_load_png, __mg_cleanup_png, NULL, __mg_check_png },
#endif #endif
#endif
#ifdef _MGIMAGE_WEBP #ifdef _MGIMAGE_WEBP
{ "webp", __mg_init_webp, __mg_load_webp, __mg_cleanup_webp, NULL, __mg_check_webp }, { "webp", __mg_init_webp, __mg_load_webp, __mg_cleanup_webp, NULL, __mg_check_webp },
#endif #endif
+281
View File
File diff suppressed because it is too large Load Diff
+3 -3
View File
@@ -144,7 +144,7 @@ static int DRM_AllocSharedHWSurface(_THIS, GAL_Surface *surface,
static int DRM_FreeSharedHWSurface(_THIS, GAL_Surface *surface); static int DRM_FreeSharedHWSurface(_THIS, GAL_Surface *surface);
static int DRM_AttachSharedHWSurface(_THIS, GAL_Surface *surface, static int DRM_AttachSharedHWSurface(_THIS, GAL_Surface *surface,
int prime_fd, size_t mapsize, BOOL with_rw); int prime_fd, size_t mapsize, BOOL with_rw);
static int DRM_DettachSharedHWSurface(_THIS, GAL_Surface *surface); static int DRM_DetachSharedHWSurface(_THIS, GAL_Surface *surface);
static int DRM_SetCursor(_THIS, GAL_Surface *surface, int hot_x, int hot_y); static int DRM_SetCursor(_THIS, GAL_Surface *surface, int hot_x, int hot_y);
static int DRM_MoveCursor(_THIS, int x, int y); static int DRM_MoveCursor(_THIS, int x, int y);
@@ -1410,7 +1410,7 @@ static GAL_VideoDevice *DRM_CreateDevice(int devindex)
device->AllocSharedHWSurface = DRM_AllocSharedHWSurface; device->AllocSharedHWSurface = DRM_AllocSharedHWSurface;
device->FreeSharedHWSurface = DRM_FreeSharedHWSurface; device->FreeSharedHWSurface = DRM_FreeSharedHWSurface;
device->AttachSharedHWSurface = DRM_AttachSharedHWSurface; device->AttachSharedHWSurface = DRM_AttachSharedHWSurface;
device->DettachSharedHWSurface = DRM_DettachSharedHWSurface; device->DetachSharedHWSurface = DRM_DetachSharedHWSurface;
} }
#endif /* IS_COMPOSITING_SCHEMA */ #endif /* IS_COMPOSITING_SCHEMA */
@@ -3127,7 +3127,7 @@ error:
return retval; return retval;
} }
static int DRM_DettachSharedHWSurface(_THIS, GAL_Surface *surface) static int DRM_DetachSharedHWSurface(_THIS, GAL_Surface *surface)
{ {
int retval = -1; int retval = -1;
DrmVideoData* vdata = this->hidden; DrmVideoData* vdata = this->hidden;
+1 -1
View File
@@ -247,7 +247,7 @@ static GAL_Surface* create_wp_surface(GAL_Surface* screen)
_DBG_PRINTF ("REQID_GETSHAREDSURFACE: size (%lu), flags (0x%x), fd: %d\n", _DBG_PRINTF ("REQID_GETSHAREDSURFACE: size (%lu), flags (0x%x), fd: %d\n",
info.size, info.flags, fd); info.size, info.flags, fd);
wp_surf = GAL_AttachSharedRGBSurface (fd, info.size, wp_surf = GAL_AttachSharedRGBSurface (NULL, fd, info.size,
info.flags, TRUE); info.flags, TRUE);
close (fd); close (fd);
File diff suppressed because it is too large Load Diff
+8 -3
View File
@@ -1836,10 +1836,15 @@ void GAL_FreeSurface (GAL_Surface *surface)
} }
if (surface->shared_header) { if (surface->shared_header) {
if (surface->shared_header->creator == getpid()) if (surface->flags & GAL_SSURF_ATTACHED)
GAL_FreeSharedSurfaceData(surface); GAL_DetachSharedSurfaceData(surface);
else else
GAL_DettachSharedSurfaceData(surface); GAL_FreeSharedSurfaceData(surface);
if (surface->fd >= 0) {
close(surface->fd);
surface->fd = -1;
}
surface->hwdata = NULL; surface->hwdata = NULL;
surface->pixels = NULL; surface->pixels = NULL;
+2 -2
View File
@@ -174,10 +174,10 @@ struct GAL_VideoDevice {
int (*AttachSharedHWSurface)(_THIS, GAL_Surface *surface, int (*AttachSharedHWSurface)(_THIS, GAL_Surface *surface,
int prime_fd, size_t mapsize, BOOL with_rw); int prime_fd, size_t mapsize, BOOL with_rw);
/* Dettach from a shared surface in hardware video memory. /* Detach from a shared surface in hardware video memory.
Set to NULL if no hardware shared surface supported. Set to NULL if no hardware shared surface supported.
Return 0 if success, otherwise -1. */ Return 0 if success, otherwise -1. */
int (*DettachSharedHWSurface)(_THIS, GAL_Surface *surface); int (*DetachSharedHWSurface)(_THIS, GAL_Surface *surface);
/* Allocate a dumb surface from hardware. /* Allocate a dumb surface from hardware.
Set to NULL if dumb surface is not supported. Set to NULL if dumb surface is not supported.
+2 -2
View File
@@ -918,9 +918,9 @@ BOOL GAL_SyncUpdate (GAL_Surface *surface)
#ifdef _MGSCHEMA_COMPOSITING #ifdef _MGSCHEMA_COMPOSITING
if (surface->shared_header) { if (surface->shared_header) {
LOCK_SURFACE_SEM (surface->shared_header->sem_num); __mg_lock_file_for_write (surface->fd);
mark_surface_dirty (surface, numrects, rects); mark_surface_dirty (surface, numrects, rects);
UNLOCK_SURFACE_SEM (surface->shared_header->sem_num); __mg_unlock_file_for_write (surface->fd);
} }
else if (surface->dirty_info) { else if (surface->dirty_info) {
mark_surface_dirty (surface, numrects, rects); mark_surface_dirty (surface, numrects, rects);
+2 -1
View File
@@ -14,7 +14,8 @@ SRC_FILES = gdi.c attr.c clip.c map.c coor.c rect.c \
simple-glyph-renderer.c glyph-shaped.c \ simple-glyph-renderer.c glyph-shaped.c \
textruns.c \ textruns.c \
shape-glyphs-basic.c shape-glyphs-complex.c \ shape-glyphs-basic.c shape-glyphs-complex.c \
layout.c layout-utils.c layout-ellipsize.c layout.c layout-utils.c layout-ellipsize.c \
shared-surface.c
HDR_FILES = glyph.h drawtext.h mi.h midc.h mistruct.h miwideline.h \ HDR_FILES = glyph.h drawtext.h mi.h midc.h mistruct.h miwideline.h \
pixel_ops.h mifillarc.h mispans.h polygon.h mifpoly.h \ pixel_ops.h mifillarc.h mispans.h polygon.h mifpoly.h \
+17 -28
View File
@@ -3346,8 +3346,7 @@ HDC GUIAPI CreateMemDCEx (int width, int height, int depth, DWORD flags,
return (HDC)pmem_dc; return (HDC)pmem_dc;
} }
/* Since 5.0.0 */ static HDC create_memdc_from_surface(HSURF surface, BOOL take_owner)
HDC CreateMemDCFromSurface (GAL_Surface* surface)
{ {
PDC pmem_dc = NULL; PDC pmem_dc = NULL;
@@ -3360,7 +3359,10 @@ HDC CreateMemDCFromSurface (GAL_Surface* surface)
pmem_dc->DataType = TYPE_HDC; pmem_dc->DataType = TYPE_HDC;
pmem_dc->DCType = TYPE_MEMDC; pmem_dc->DCType = TYPE_MEMDC;
pmem_dc->bInUse = TRUE; pmem_dc->bInUse = TRUE;
if (take_owner)
pmem_dc->surface = surface; pmem_dc->surface = surface;
else
pmem_dc->surface = GAL_RefSurface(surface);
dc_InitDC (pmem_dc, HWND_NULL, FALSE); dc_InitDC (pmem_dc, HWND_NULL, FALSE);
@@ -3384,36 +3386,24 @@ HDC CreateMemDCFromSurface (GAL_Surface* surface)
return (HDC)pmem_dc; return (HDC)pmem_dc;
} }
struct GAL_Surface* GetSurfaceFromDC (HDC hdc) /* Since 5.2.0 */
HDC GUIAPI CreateMemDCFromSurface (HSURF surface)
{
return create_memdc_from_surface(surface, FALSE);
}
HDC __mg_create_memdc_for_surface (HSURF surface)
{
return create_memdc_from_surface(surface, TRUE);
}
HSURF GUIAPI GetSurfaceFromDC (HDC hdc)
{ {
PDC pdc; PDC pdc;
pdc = dc_HDC2PDC (hdc); pdc = dc_HDC2PDC(hdc);
return pdc->surface; return pdc->surface;
} }
#ifdef _MGSCHEMA_COMPOSITING
HDC GUIAPI CreateMemDCFromSharedSurfaceFD (int fd)
{
HDC memdc = HDC_INVALID;
GAL_Surface* surf;
surf = GAL_AttachSharedRGBSurface (fd, 0, GAL_HWSURFACE, TRUE);
if (surf) {
memdc = CreateMemDCFromSurface (surf);
if (memdc == HDC_INVALID) {
GAL_FreeSurface(surf);
_ERR_PRINTF("failed to create memory dc from surface: %p\n", surf);
}
}
else {
_ERR_PRINTF("failed to attach to surface buffer via fd: %d\n", fd);
}
return memdc;
}
#endif /* _MGSCHEMA_COMPOSITING */
HDC GUIAPI CreateSubMemDC (HDC parent, int off_x, int off_y, HDC GUIAPI CreateSubMemDC (HDC parent, int off_x, int off_y,
int width, int height, BOOL comp_to_parent) int width, int height, BOOL comp_to_parent)
{ {
@@ -3438,7 +3428,6 @@ HDC GUIAPI CreateSubMemDC (HDC parent, int off_x, int off_y,
if (width < 0) width = 0; if (width < 0) width = 0;
if (height < 0) height = 0; if (height < 0) height = 0;
if (off_x + width > pdc_parent->DevRC.right) if (off_x + width > pdc_parent->DevRC.right)
width = pdc_parent->DevRC.right - off_x; width = pdc_parent->DevRC.right - off_x;
if (off_y + height > pdc_parent->DevRC.bottom) if (off_y + height > pdc_parent->DevRC.bottom)
+78 -6
View File
@@ -1092,6 +1092,67 @@ nodraw_ret:
} }
#ifdef _MGFONT_FT2 #ifdef _MGFONT_FT2
static RGB blend_pixel(RGB font_pixel, RGB fg_color, RGB bg_color)
{
RGB result;
Uint8 src_pre_r, src_pre_g, src_pre_b;
Uint8 bg_pre_r, bg_pre_g, bg_pre_b, alpha_bg;
Uint8 out_r, out_g, out_b, alpha_out;
uint8_t alpha_font = 0.299 * font_pixel.r + 0.587 * font_pixel.g +
0.114 * font_pixel.b;
uint16_t alpha_src = (fg_color.a * alpha_font + 127) / 255;
if (alpha_src == 0) {
result = bg_color;
goto out;
}
src_pre_r = (fg_color.r * alpha_src + 127) / 255;
src_pre_g = (fg_color.g * alpha_src + 127) / 255;
src_pre_b = (fg_color.b * alpha_src + 127) / 255;
bg_pre_r = (bg_color.r * bg_color.a + 127) / 255;
bg_pre_g = (bg_color.g * bg_color.a + 127) / 255;
bg_pre_b = (bg_color.b * bg_color.a + 127) / 255;
alpha_bg = bg_color.a;
out_r = src_pre_r + (bg_pre_r * (255 - alpha_src)) / 255;
out_g = src_pre_g + (bg_pre_g * (255 - alpha_src)) / 255;
out_b = src_pre_b + (bg_pre_b * (255 - alpha_src)) / 255;
alpha_out = alpha_src + (alpha_bg * (255 - alpha_src)) / 255;
if (out_r > 255) {
out_r = 255;
}
if (out_g > 255) {
out_g = 255;
}
if (out_b > 255) {
out_b = 255;
}
if (alpha_out > 0) {
result.r = (out_r * 255 + alpha_out / 2) / alpha_out;
result.g = (out_g * 255 + alpha_out / 2) / alpha_out;
result.b = (out_b * 255 + alpha_out / 2) / alpha_out;
result.a = (uint8_t) alpha_out;
} else {
result.r = 0;
result.g = 0;
result.b = 0;
result.a = 0;
}
out:
return result;
}
static void _dc_ft2subpixel_scan_line(PDC pdc, int xpos, int ypos, static void _dc_ft2subpixel_scan_line(PDC pdc, int xpos, int ypos,
SCANLINE_CTXT* ctxt) SCANLINE_CTXT* ctxt)
{ {
@@ -1112,8 +1173,8 @@ static void _dc_ft2subpixel_scan_line(PDC pdc, int xpos, int ypos,
ctxt->glyph_ascent, ctxt->glyph_line, ctxt->glyph_ascent, ctxt->glyph_line,
ctxt->glyph_advance); ctxt->glyph_advance);
GAL_GetRGB (pdc->textcolor, pdc->surface->format, &rgba_fg.r, GAL_GetRGBA (pdc->textcolor, pdc->surface->format, &rgba_fg.r,
&rgba_fg.g, &rgba_fg.b); &rgba_fg.g, &rgba_fg.b, &rgba_fg.a);
for (x = 0; x < ctxt->bmp_w; x++) { for (x = 0; x < ctxt->bmp_w; x++) {
if (!PtInRect (&pdc->rc_output, x+xpos, ypos)) { if (!PtInRect (&pdc->rc_output, x+xpos, ypos)) {
@@ -1130,8 +1191,8 @@ static void _dc_ft2subpixel_scan_line(PDC pdc, int xpos, int ypos,
_glyph_move_to_pixel (pdc, x+xpos, ypos); _glyph_move_to_pixel (pdc, x+xpos, ypos);
pixel = _mem_get_pixel(pdc->cur_dst, GAL_BytesPerPixel (pdc->surface)); pixel = _mem_get_pixel(pdc->cur_dst, GAL_BytesPerPixel (pdc->surface));
GAL_GetRGB (pixel, pdc->surface->format, &rgba_cur.r, GAL_GetRGBA (pixel, pdc->surface->format, &rgba_cur.r,
&rgba_cur.g, &rgba_cur.b); &rgba_cur.g, &rgba_cur.b, &rgba_cur.a);
#define C_ALPHA(p, Cs, Cd) \ #define C_ALPHA(p, Cs, Cd) \
if (*p++) { \ if (*p++) { \
@@ -1140,14 +1201,25 @@ static void _dc_ft2subpixel_scan_line(PDC pdc, int xpos, int ypos,
Cd = sub_val >> 8; \ Cd = sub_val >> 8; \
} }
if (rgba_cur.r == 0 && rgba_cur.g == 0 && rgba_cur.b == 0 &&
rgba_cur.a == 0) {
RGB font_pixel = {bits[0], bits[1], bits[2], 255};
RGB ret = blend_pixel(font_pixel, rgba_fg, rgba_cur);
rgba_cur = ret;
bits += 3;
}
else {
C_ALPHA(bits, rgba_fg.r, rgba_cur.r); C_ALPHA(bits, rgba_fg.r, rgba_cur.r);
C_ALPHA(bits, rgba_fg.g, rgba_cur.g); C_ALPHA(bits, rgba_fg.g, rgba_cur.g);
C_ALPHA(bits, rgba_fg.b, rgba_cur.b); C_ALPHA(bits, rgba_fg.b, rgba_cur.b);
rgba_cur.a = 255.0;
}
#undef C_ALPHA #undef C_ALPHA
pdc->cur_pixel = GAL_MapRGB (pdc->surface->format, rgba_cur.r, pdc->cur_pixel = GAL_MapRGBA (pdc->surface->format, rgba_cur.r,
rgba_cur.g, rgba_cur.b); rgba_cur.g, rgba_cur.b, rgba_cur.a);
if (pdc->cur_pixel != pixel) { if (pdc->cur_pixel != pixel) {
_glyph_draw_pixel (pdc, x+xpos, ypos, pdc->cur_pixel); _glyph_draw_pixel (pdc, x+xpos, ypos, pdc->cur_pixel);
+1 -1
View File
@@ -269,7 +269,7 @@ void GUIAPI GetClipRgnBoundRect (PCLIPRGN pRgn, PRECT pRect)
BOOL GUIAPI IsEmptyClipRgn (const CLIPRGN* pRgn) BOOL GUIAPI IsEmptyClipRgn (const CLIPRGN* pRgn)
{ {
if (pRgn->head == NULL) if (pRgn->head == NULL || IsRectEmpty (&pRgn->rcBound))
return TRUE; return TRUE;
return FALSE; return FALSE;
File diff suppressed because it is too large Load Diff
+7 -5
View File
@@ -309,7 +309,7 @@ BOOL GUIAPI ServerDeleteLayer (MG_Layer* layer)
return TRUE; return TRUE;
} }
#ifdef _MGSCHEMA_COMPOSITING #if 0 // Deprecated since 5.2.0 def _MGSCHEMA_COMPOSITING
static SemSetManager* _ssm_shared_surf; static SemSetManager* _ssm_shared_surf;
@@ -395,6 +395,7 @@ int __mg_init_layers ()
memset (sem_usage, 0xFF, sizeof (sem_usage)); memset (sem_usage, 0xFF, sizeof (sem_usage));
#if 0 // Deprecated since 5.2.0
#ifdef _MGSCHEMA_COMPOSITING #ifdef _MGSCHEMA_COMPOSITING
if ((sem_key = get_sem_key_for_shared_surf ()) == -1) { if ((sem_key = get_sem_key_for_shared_surf ()) == -1) {
return -1; return -1;
@@ -415,6 +416,7 @@ int __mg_init_layers ()
__mg_alloc_mutual_sem (_ssm_shared_surf, NULL); __mg_alloc_mutual_sem (_ssm_shared_surf, NULL);
on_exit (__mg_delete_sem_set_manager, _ssm_shared_surf); on_exit (__mg_delete_sem_set_manager, _ssm_shared_surf);
#endif
#endif #endif
if ((sem_key = get_sem_key_for_layers ()) == -1) { if ((sem_key = get_sem_key_for_layers ()) == -1) {
@@ -910,7 +912,7 @@ const ZNODEHEADER* GUIAPI ServerGetWinZNodeHeader (MG_Layer* layer,
if (hdr->lock_count == 0) { if (hdr->lock_count == 0) {
if (pdc->surface->shared_header) { if (pdc->surface->shared_header) {
// XXX: consider timeout. // XXX: consider timeout.
LOCK_SURFACE_SEM (pdc->surface->shared_header->sem_num); __mg_lock_file_for_read(pdc->surface->fd);
} }
hdr->dirty_age = pdc->surface->dirty_info->dirty_age; hdr->dirty_age = pdc->surface->dirty_info->dirty_age;
@@ -962,7 +964,7 @@ const ZNODEHEADER* GUIAPI ServerGetPopupMenuZNodeHeader (int idx,
if (hdr->lock_count == 0) { if (hdr->lock_count == 0) {
if (pdc->surface->shared_header) { if (pdc->surface->shared_header) {
// XXX: consider timeout // XXX: consider timeout
LOCK_SURFACE_SEM (pdc->surface->shared_header->sem_num); __mg_lock_file_for_read(pdc->surface->fd);
} }
hdr->dirty_age = pdc->surface->dirty_info->dirty_age; hdr->dirty_age = pdc->surface->dirty_info->dirty_age;
@@ -1006,7 +1008,7 @@ BOOL GUIAPI ServerReleaseWinZNodeHeader (MG_Layer* layer, int idx_znode)
hdr->lock_count--; hdr->lock_count--;
if (hdr->lock_count == 0) { if (hdr->lock_count == 0) {
if (pdc->surface->shared_header) if (pdc->surface->shared_header)
UNLOCK_SURFACE_SEM (pdc->surface->shared_header->sem_num); __mg_unlock_file_for_read(pdc->surface->fd);
hdr->dirty_age = 0; hdr->dirty_age = 0;
hdr->nr_dirty_rcs = 0; hdr->nr_dirty_rcs = 0;
@@ -1035,7 +1037,7 @@ BOOL GUIAPI ServerReleasePopupMenuZNodeHeader (int idx)
hdr->lock_count--; hdr->lock_count--;
if (hdr->lock_count == 0) { if (hdr->lock_count == 0) {
if (pdc->surface->shared_header) if (pdc->surface->shared_header)
UNLOCK_SURFACE_SEM (pdc->surface->shared_header->sem_num); __mg_unlock_file_for_read(pdc->surface->fd);
hdr->dirty_age = 0; hdr->dirty_age = 0;
hdr->nr_dirty_rcs = 0; hdr->nr_dirty_rcs = 0;
+104 -69
View File
File diff suppressed because it is too large Load Diff
+2 -24
View File
@@ -84,20 +84,6 @@ extern DWORD __mg_tick_counter;
ON_NEW_DEL_CLIENT OnNewDelClient = NULL; ON_NEW_DEL_CLIENT OnNewDelClient = NULL;
#if 0
/* Since 5.0.0, use RegisterEventHookFunc to implement SetServerEventHook */
static SRVEVTHOOK srv_evt_hook = NULL;
SRVEVTHOOK GUIAPI SetServerEventHook (SRVEVTHOOK SrvEvtHook)
{
SRVEVTHOOK old_hook = srv_evt_hook;
srv_evt_hook = SrvEvtHook;
return old_hook;
}
#endif /* deprecated code; moved to window.c */
static void ParseEvent (PMSGQUEUE msg_que, int event) static void ParseEvent (PMSGQUEUE msg_que, int event)
{ {
LWEVENT lwe; LWEVENT lwe;
@@ -331,7 +317,7 @@ BOOL GUIAPI ServerStartup (int nr_globals,
__mg_dsk_msg_queue->maxfd = listenfd; __mg_dsk_msg_queue->maxfd = listenfd;
maxi = -1; maxi = -1;
mg_InitTimer (TRUE); mg_InitTimer ();
__mg_start_server_desktop (); __mg_start_server_desktop ();
@@ -363,7 +349,7 @@ void server_ServerCleanup (void)
__mg_nssurf_map_delete (); __mg_nssurf_map_delete ();
#endif #endif
mg_TerminateTimer (TRUE); mg_TerminateTimer ();
unlink (CS_PATH); unlink (CS_PATH);
} }
@@ -381,14 +367,6 @@ BOOL server_IdleHandler4Server (PMSGQUEUE msg_queue, BOOL wait)
EXTRA_INPUT_EVENT extra; // Since 4.0.0; for extra input events EXTRA_INPUT_EVENT extra; // Since 4.0.0; for extra input events
int nevts = 0; // Since 5.0.0; for timer and fd events int nevts = 0; // Since 5.0.0; for timer and fd events
#if 0 /* deprecated code */
/* since 5.0.0, use __mg_update_tick_count instead */
if (__mg_tick_counter != SHAREDRES_TIMER_COUNTER) {
__mg_tick_counter = SHAREDRES_TIMER_COUNTER;
AlertDesktopTimerEvent ();
}
#endif /* deprecated code */
/* rset gets modified each time around */ /* rset gets modified each time around */
rset = __mg_dsk_msg_queue->rfdset; rset = __mg_dsk_msg_queue->rfdset;
if (__mg_dsk_msg_queue->nr_wfds) { if (__mg_dsk_msg_queue->nr_wfds) {
+2 -2
View File
@@ -190,14 +190,14 @@ static void ParseEvent (PMSGQUEUE msg_que, int event)
BOOL GUIAPI salone_StandAloneStartup (void) BOOL GUIAPI salone_StandAloneStartup (void)
{ {
/* VW: do not use signal based interval timer; since 4.0 */ /* VW: do not use signal based interval timer; since 4.0 */
mg_InitTimer (FALSE); mg_InitTimer ();
return TRUE; return TRUE;
} }
void salone_StandAloneCleanup (void) void salone_StandAloneCleanup (void)
{ {
/* VW: do not use signal based interval timer; since 4.0 */ /* VW: do not use signal based interval timer; since 4.0 */
mg_TerminateTimer (FALSE); mg_TerminateTimer ();
} }
BOOL salone_IdleHandler4StandAlone (PMSGQUEUE msg_queue, BOOL wait) BOOL salone_IdleHandler4StandAlone (PMSGQUEUE msg_queue, BOOL wait)