mirror of
https://github.com/VincentWei/MiniGUI.git
synced 2026-09-26 20:45:36 +08:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
42b28fcc59 | ||
|
|
2bde8e299a | ||
|
|
08d4ab78e5 | ||
|
|
0cda03a2eb | ||
|
|
4cf4d204e7 | ||
|
|
6aa294e75b | ||
|
|
7718be5200 | ||
|
|
78e6d6581e | ||
|
|
62b3dc11d0 | ||
|
|
67cddafa19 | ||
|
|
4ae46a4b94 | ||
|
|
2791dc99ef | ||
|
|
b7525f3001 | ||
|
|
4c55f2eac3 | ||
|
|
3ad600d1bf | ||
|
|
3c233a4164 | ||
|
|
3643606a7f | ||
|
|
3ef2340749 | ||
|
|
a583dc1cbb |
@@ -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
|
||||||
|
|||||||
@@ -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 \
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
+21
-5
@@ -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,24 @@
|
|||||||
+ [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.
|
||||||
|
- Bad subpixel rendering when background color is RGBA0000.
|
||||||
|
* TUNING:
|
||||||
|
- Tune `configure.ac` and `Makefile.am` to use the system libtool scripts.
|
||||||
|
- Do not check `pciaccess` if the target architecture is not `i386`.
|
||||||
|
|
||||||
|
## 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.
|
||||||
|
|||||||
+2
-2
@@ -1,6 +1,6 @@
|
|||||||
Version 5.2.0 (2023/09/30)
|
Version 5.0.16 (2025/05/27)
|
||||||
|
|
||||||
This is a minor enhancement and bugfix release of MiniGUI 5.2.x, the stable version.
|
This is a minor enhancement and bugfix release of MiniGUI 5.0.x, the stable version.
|
||||||
|
|
||||||
Other packages for MiniGUI resource, tools, components, and samples:
|
Other packages for MiniGUI resource, tools, components, and samples:
|
||||||
|
|
||||||
|
|||||||
+2
-1
@@ -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
|
||||||
|
|||||||
+31
-29
@@ -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.2.0)
|
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
|
||||||
#
|
#
|
||||||
@@ -15,10 +16,10 @@ dnl Set various version strings - taken gratefully from the SDL sources
|
|||||||
# set MINIGUI_BINARY_AGE and MINIGUI_INTERFACE_AGE to 0.
|
# set MINIGUI_BINARY_AGE and MINIGUI_INTERFACE_AGE to 0.
|
||||||
#
|
#
|
||||||
MINIGUI_MAJOR_VERSION=5
|
MINIGUI_MAJOR_VERSION=5
|
||||||
MINIGUI_MINOR_VERSION=2
|
MINIGUI_MINOR_VERSION=0
|
||||||
MINIGUI_MICRO_VERSION=0
|
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,27 +41,24 @@ 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 stdatomic.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)
|
||||||
|
|
||||||
@@ -68,7 +66,6 @@ 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,
|
||||||
@@ -899,9 +896,13 @@ CheckFBCON()
|
|||||||
VIDEO_SUBDIRS="$VIDEO_SUBDIRS fbcon"
|
VIDEO_SUBDIRS="$VIDEO_SUBDIRS fbcon"
|
||||||
VIDEO_DRIVERS="$VIDEO_DRIVERS fbcon/libvideo_fbcon.la"
|
VIDEO_DRIVERS="$VIDEO_DRIVERS fbcon/libvideo_fbcon.la"
|
||||||
|
|
||||||
have_pciaccess="yes"
|
if test "x$target_cpu" = "xi386"; then
|
||||||
AC_CHECK_LIB(pciaccess, pci_system_init,
|
have_pciaccess="yes"
|
||||||
DEP_LIBS="$DEP_LIBS -lpciaccess", have_pciaccess="no")
|
AC_CHECK_LIB(pciaccess, pci_system_init,
|
||||||
|
DEP_LIBS="$DEP_LIBS -lpciaccess", have_pciaccess="no")
|
||||||
|
else
|
||||||
|
have_pciaccess="no"
|
||||||
|
fi
|
||||||
|
|
||||||
if test "x$have_pciaccess" = "xyes"; then
|
if test "x$have_pciaccess" = "xyes"; then
|
||||||
AC_DEFINE(_MGHAVE_PCIACCESS, 1,
|
AC_DEFINE(_MGHAVE_PCIACCESS, 1,
|
||||||
@@ -1170,12 +1171,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 +2642,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 +2652,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 +2689,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 +2756,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`
|
||||||
|
|
||||||
@@ -2765,6 +2766,7 @@ AC_MSG_NOTICE([
|
|||||||
# Main building configuration:
|
# Main building configuration:
|
||||||
|
|
||||||
## Global Features:
|
## Global Features:
|
||||||
|
* Architecture: ${target_cpu}
|
||||||
* Operating system: ${osname}
|
* Operating system: ${osname}
|
||||||
* Runtime mode: ${runtime_mode}
|
* Runtime mode: ${runtime_mode}
|
||||||
* Virtual Window: ${virtual_window}
|
* Virtual Window: ${virtual_window}
|
||||||
|
|||||||
+1
-1
@@ -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 =
|
||||||
|
|||||||
Vendored
-3724
File diff suppressed because it is too large
Load Diff
@@ -166,7 +166,7 @@ static unsigned short iso8859_68x_unicode_map [] =
|
|||||||
0xFEB3, 0xFEB7, 0xFEBB, 0xFEBF, /*0xF1~0xF4*/
|
0xFEB3, 0xFEB7, 0xFEBB, 0xFEBF, /*0xF1~0xF4*/
|
||||||
0xFECB, 0xFECF, 0xFED3, 0xFED7, /*0xF5~0xF8*/
|
0xFECB, 0xFECF, 0xFED3, 0xFED7, /*0xF5~0xF8*/
|
||||||
0xFEDB, 0xFEDF, 0xFEE3, 0xFEE7, /*0xF9~0xFC*/
|
0xFEDB, 0xFEDF, 0xFEE3, 0xFEE7, /*0xF9~0xFC*/
|
||||||
0xFEEB, 0xFEF4, 0xFFFF, /*0xFD~0xFF*/
|
0xFEEB, 0xFEF3, 0xFFFF, /*0xFD~0xFF*/
|
||||||
|
|
||||||
0xFEC4, 0xFEC6, 0xFE82, 0xFE84, /*0x100~0x103*/
|
0xFEC4, 0xFEC6, 0xFE82, 0xFE84, /*0x100~0x103*/
|
||||||
0xFE86, 0xFE88, 0xFE8C, 0xFE8E, /*0x104~0x107*/
|
0xFE86, 0xFE88, 0xFE8C, 0xFE8E, /*0x104~0x107*/
|
||||||
@@ -576,7 +576,7 @@ static BidiType __mg_iso8859_6_bidi_char_type_map[] = {
|
|||||||
BIDI_TYPE_AL, BIDI_TYPE_AL, BIDI_TYPE_AL, BIDI_TYPE_AL,
|
BIDI_TYPE_AL, BIDI_TYPE_AL, BIDI_TYPE_AL, BIDI_TYPE_AL,
|
||||||
BIDI_TYPE_AL, BIDI_TYPE_AL, BIDI_TYPE_AL, BIDI_TYPE_AL,
|
BIDI_TYPE_AL, BIDI_TYPE_AL, BIDI_TYPE_AL, BIDI_TYPE_AL,
|
||||||
BIDI_TYPE_AL, BIDI_TYPE_AL, BIDI_TYPE_AL, BIDI_TYPE_AL,
|
BIDI_TYPE_AL, BIDI_TYPE_AL, BIDI_TYPE_AL, BIDI_TYPE_AL,
|
||||||
BIDI_TYPE_AL, BIDI_TYPE_AL, BIDI_TYPE_AL, BIDI_TYPE_ON,
|
BIDI_TYPE_AL, BIDI_TYPE_AL, BIDI_TYPE_AL, BIDI_TYPE_AL,
|
||||||
|
|
||||||
/*0xf0~0xff*/
|
/*0xf0~0xff*/
|
||||||
BIDI_TYPE_AL, BIDI_TYPE_AL, BIDI_TYPE_AL, BIDI_TYPE_AL,
|
BIDI_TYPE_AL, BIDI_TYPE_AL, BIDI_TYPE_AL, BIDI_TYPE_AL,
|
||||||
|
|||||||
+110
-9
@@ -286,7 +286,7 @@ static TYPERUN* get_runtype_link (const CHARSETOPS* charset_ops, Achar32* achars
|
|||||||
last = list;
|
last = list;
|
||||||
|
|
||||||
for (i = 0; i < len; i++){
|
for (i = 0; i < len; i++){
|
||||||
if ((type = charset_ops->bidi_char_type (achars[i])) != last->type){
|
if ((type = charset_ops->bidi_char_type (REAL_ACHAR(achars[i]))) != last->type){
|
||||||
link = calloc(1, sizeof(TYPERUN));
|
link = calloc(1, sizeof(TYPERUN));
|
||||||
link->type = type;
|
link->type = type;
|
||||||
link->pos = i;
|
link->pos = i;
|
||||||
@@ -456,7 +456,7 @@ static void bidi_resolveWeak(TYPERUN **ptype_rl_list, Uint32 base_dir)
|
|||||||
prev_type_org = TYPE(pp);
|
prev_type_org = TYPE(pp);
|
||||||
}
|
}
|
||||||
|
|
||||||
compact_neutrals (type_rl_list);
|
compact_list (type_rl_list);
|
||||||
|
|
||||||
#ifdef BIDI_DEBUG
|
#ifdef BIDI_DEBUG
|
||||||
print_run_types(type_rl_list);
|
print_run_types(type_rl_list);
|
||||||
@@ -469,19 +469,115 @@ static void bidi_resolveWeak(TYPERUN **ptype_rl_list, Uint32 base_dir)
|
|||||||
#define BIDI_EMBEDDING_DIR(list) BIDI_LEVEL_TO_DIR(LEVEL(list))
|
#define BIDI_EMBEDDING_DIR(list) BIDI_LEVEL_TO_DIR(LEVEL(list))
|
||||||
|
|
||||||
/* 4.Resolving Neutral Types */
|
/* 4.Resolving Neutral Types */
|
||||||
static void bidi_resolveNeutrals(TYPERUN **ptype_rl_list, Uint32 base_bir)
|
static void bidi_resolveNeutrals(const CHARSETOPS* charset_ops, Achar32* achars, int len,
|
||||||
|
TYPERUN **ptype_rl_list, Uint32 base_bir)
|
||||||
{
|
{
|
||||||
TYPERUN *type_rl_list = *ptype_rl_list, *pp = NULL;
|
TYPERUN *type_rl_list = *ptype_rl_list, *pp = NULL;
|
||||||
|
Uint32* bracket_types = NULL;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (charset_ops->bidi_mirror_char && achars && len > 0) {
|
||||||
|
typedef struct {
|
||||||
|
int pos;
|
||||||
|
Achar32 mirror;
|
||||||
|
} BRSTACK;
|
||||||
|
|
||||||
|
BRSTACK* stack = NULL;
|
||||||
|
int top = 0;
|
||||||
|
|
||||||
|
bracket_types = calloc(len, sizeof(Uint32));
|
||||||
|
stack = calloc(len, sizeof(BRSTACK));
|
||||||
|
|
||||||
|
if (bracket_types && stack) {
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
|
Achar32 ch = REAL_ACHAR(achars[i]);
|
||||||
|
Achar32 mirrored;
|
||||||
|
if (!charset_ops->bidi_mirror_char(ch, &mirrored))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (ch < mirrored) {
|
||||||
|
stack[top].pos = i;
|
||||||
|
stack[top].mirror = mirrored;
|
||||||
|
top++;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (top > 0 && stack[top - 1].mirror == ch) {
|
||||||
|
int open_pos = stack[top - 1].pos;
|
||||||
|
int close_pos = i;
|
||||||
|
Uint32 found_dir = BIDI_TYPE_ON;
|
||||||
|
int k;
|
||||||
|
|
||||||
|
for (k = open_pos + 1; k < close_pos; k++) {
|
||||||
|
Uint32 t = charset_ops->bidi_char_type(REAL_ACHAR(achars[k]));
|
||||||
|
if (t == BIDI_TYPE_AL)
|
||||||
|
t = BIDI_TYPE_RTL;
|
||||||
|
if (BIDI_IS_LETTER(t)) {
|
||||||
|
found_dir = BIDI_IS_RTL(t) ? BIDI_TYPE_RTL : BIDI_TYPE_LTR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found_dir != BIDI_TYPE_ON) {
|
||||||
|
bracket_types[open_pos] = found_dir;
|
||||||
|
bracket_types[close_pos] = found_dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
top--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stack)
|
||||||
|
free(stack);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bracket_types) {
|
||||||
|
for (pp = type_rl_list->next; pp->next; pp = pp->next) {
|
||||||
|
if (BIDI_IS_NEUTRAL(TYPE(pp))) {
|
||||||
|
int start = POS(pp);
|
||||||
|
int end = start + LEN(pp);
|
||||||
|
Uint32 forced = BIDI_TYPE_ON;
|
||||||
|
|
||||||
|
if (end > len)
|
||||||
|
end = len;
|
||||||
|
|
||||||
|
for (i = start; i < end; i++) {
|
||||||
|
if (bracket_types[i] == BIDI_TYPE_RTL) {
|
||||||
|
forced = BIDI_TYPE_RTL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (bracket_types[i] == BIDI_TYPE_LTR) {
|
||||||
|
forced = BIDI_TYPE_LTR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (forced != BIDI_TYPE_ON) {
|
||||||
|
TYPE(pp) = forced;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
compact_list (type_rl_list);
|
||||||
|
}
|
||||||
|
|
||||||
DBGLOG ("\n4.Resolving neutral types\n");
|
DBGLOG ("\n4.Resolving neutral types\n");
|
||||||
|
|
||||||
for (pp = type_rl_list->next; pp->next; pp = pp->next)
|
for (pp = type_rl_list->next; pp->next; pp = pp->next)
|
||||||
{
|
{
|
||||||
Uint32 prev_type, this_type, next_type;
|
Uint32 prev_type, this_type, next_type;
|
||||||
|
TYPERUN* prev = NULL;
|
||||||
|
TYPERUN* next = NULL;
|
||||||
|
|
||||||
|
prev = pp->prev;
|
||||||
|
while (prev && BIDI_IS_NEUTRAL(TYPE(prev)) && !BIDI_IS_SENTINEL(TYPE(prev)))
|
||||||
|
prev = prev->prev;
|
||||||
|
prev_type = (!prev || BIDI_IS_SENTINEL(TYPE(prev))) ? base_bir : TYPE(prev);
|
||||||
|
|
||||||
prev_type = TYPE(pp->prev);
|
|
||||||
this_type = TYPE(pp);
|
this_type = TYPE(pp);
|
||||||
next_type = (pp->next) ? TYPE(pp->next) : this_type;
|
next = pp->next;
|
||||||
|
while (next && BIDI_IS_NEUTRAL(TYPE(next)) && !BIDI_IS_SENTINEL(TYPE(next)))
|
||||||
|
next = next->next;
|
||||||
|
next_type = (!next || BIDI_IS_SENTINEL(TYPE(next))) ? base_bir : TYPE(next);
|
||||||
/* "European and arabic numbers are treated as though they were R, NUMBER_TO_RTL does this. */
|
/* "European and arabic numbers are treated as though they were R, NUMBER_TO_RTL does this. */
|
||||||
this_type = BIDI_NUMBER_TO_RTL(this_type);
|
this_type = BIDI_NUMBER_TO_RTL(this_type);
|
||||||
prev_type = BIDI_NUMBER_TO_RTL(prev_type);
|
prev_type = BIDI_NUMBER_TO_RTL(prev_type);
|
||||||
@@ -498,6 +594,9 @@ static void bidi_resolveNeutrals(TYPERUN **ptype_rl_list, Uint32 base_bir)
|
|||||||
print_resolved_levels (type_rl_list);
|
print_resolved_levels (type_rl_list);
|
||||||
print_resolved_types (type_rl_list);
|
print_resolved_types (type_rl_list);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (bracket_types)
|
||||||
|
free(bracket_types);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 5.Resolving implicit levels. */
|
/* 5.Resolving implicit levels. */
|
||||||
@@ -549,10 +648,13 @@ bidi_resolveMirrorChar (const CHARSETOPS* charset_ops, Achar32* achars, int len,
|
|||||||
int i;
|
int i;
|
||||||
for (i = POS (pp); i < POS (pp) + LEN (pp); i++)
|
for (i = POS (pp); i < POS (pp) + LEN (pp); i++)
|
||||||
{
|
{
|
||||||
|
Achar32 ch = achars[i];
|
||||||
|
Achar32 real_ch = REAL_ACHAR(ch);
|
||||||
Achar32 mirrored_ch;
|
Achar32 mirrored_ch;
|
||||||
if (charset_ops->bidi_mirror_char &&
|
if (charset_ops->bidi_mirror_char &&
|
||||||
charset_ops->bidi_mirror_char (achars[i], &mirrored_ch))
|
charset_ops->bidi_mirror_char (real_ch, &mirrored_ch)) {
|
||||||
achars[i] = mirrored_ch;
|
achars[i] = IS_MBCHV(ch) ? SET_MBCHV(mirrored_ch) : mirrored_ch;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -593,7 +695,7 @@ static void bidi_resolve_string (const CHARSETOPS* charset_ops,
|
|||||||
bidi_resolveWeak(&type_rl_list, base_dir);
|
bidi_resolveWeak(&type_rl_list, base_dir);
|
||||||
|
|
||||||
/* 4.Resolving Neutral Types */
|
/* 4.Resolving Neutral Types */
|
||||||
bidi_resolveNeutrals(&type_rl_list, base_dir);
|
bidi_resolveNeutrals(charset_ops, achars, len, &type_rl_list, base_dir);
|
||||||
|
|
||||||
/* 5.Resolving implicit levels. */
|
/* 5.Resolving implicit levels. */
|
||||||
*pmax_level = bidi_resolveImplicit(&type_rl_list, base_level);
|
*pmax_level = bidi_resolveImplicit(&type_rl_list, base_level);
|
||||||
@@ -826,4 +928,3 @@ Uint32 __mg_legacy_bidi_str_base_dir (const CHARSETOPS* charset_ops,
|
|||||||
|
|
||||||
return base_dir;
|
return base_dir;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+4
-35
@@ -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;
|
||||||
|
|||||||
+1
-1
@@ -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);
|
||||||
|
|||||||
@@ -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 */
|
||||||
|
|||||||
+8
-8
@@ -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);
|
||||||
|
|
||||||
|
|||||||
+58
-142
@@ -44,7 +44,7 @@
|
|||||||
* <http://www.minigui.com/blog/minigui-licensing-policy/>.
|
* <http://www.minigui.com/blog/minigui-licensing-policy/>.
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
** timer.c: The Timer module for MiniGUI-Threads.
|
** timer.c: The Timer module for MiniGUI.
|
||||||
**
|
**
|
||||||
** Current maintainer: Wei Yongming.
|
** Current maintainer: Wei Yongming.
|
||||||
**
|
**
|
||||||
@@ -79,82 +79,45 @@
|
|||||||
|
|
||||||
DWORD __mg_tick_counter = 0;
|
DWORD __mg_tick_counter = 0;
|
||||||
|
|
||||||
/* update timer count for desktop thread */
|
/* update timer count for message and desktop thread */
|
||||||
void __mg_update_tick_count (void *data)
|
DWORD __mg_update_tick_count (MSGQUEUE* msg_queue)
|
||||||
{
|
{
|
||||||
|
DWORD ticks;
|
||||||
|
|
||||||
#if defined(_MGRM_PROCESSES)
|
#if defined(_MGRM_PROCESSES)
|
||||||
if (mgIsServer) {
|
if (mgIsServer) {
|
||||||
__mg_tick_counter = __mg_os_get_time_ticks ();
|
ticks = __mg_os_get_time_ticks ();
|
||||||
SHAREDRES_TIMER_COUNTER = __mg_tick_counter;
|
SHAREDRES_TIMER_COUNTER = ticks;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
__mg_tick_counter = SHAREDRES_TIMER_COUNTER;
|
ticks = SHAREDRES_TIMER_COUNTER;
|
||||||
}
|
}
|
||||||
#else /* defined _MGRM_PROCESSES */
|
#else /* defined _MGRM_PROCESSES */
|
||||||
__mg_tick_counter = __mg_os_get_time_ticks ();
|
ticks = __mg_os_get_time_ticks ();
|
||||||
#endif /* not defined _MGRM_PROCESSES */
|
#endif /* not defined _MGRM_PROCESSES */
|
||||||
|
|
||||||
/* Since 5.0.0, the desktop only handles caret blinking in MSG_TIMEOUT
|
if (msg_queue && ticks != msg_queue->last_ticks) {
|
||||||
message, and the interval for the timer of desktop changes to 0.05s. */
|
/* Since 5.0.0, the desktop only handles caret blinking in MSG_TIMEOUT
|
||||||
if (__mg_tick_counter >
|
message, and the interval for the timer of desktop changes to 0.05s.
|
||||||
__mg_dsk_msg_queue->last_ticks_desktop + DESKTOP_TIMER_INERTVAL) {
|
*/
|
||||||
__mg_dsk_msg_queue->dwState |= QS_DESKTIMER;
|
if (msg_queue == __mg_dsk_msg_queue &&
|
||||||
|
ticks > __mg_dsk_msg_queue->old_tick_count +
|
||||||
|
DESKTOP_TIMER_INERTVAL) {
|
||||||
|
__mg_dsk_msg_queue->dwState |= QS_DESKTIMER;
|
||||||
#ifdef _MGRM_THREADS /* only wake up desktop for threads mode */
|
#ifdef _MGRM_THREADS /* only wake up desktop for threads mode */
|
||||||
POST_MSGQ (__mg_dsk_msg_queue);
|
POST_MSGQ (__mg_dsk_msg_queue);
|
||||||
#endif
|
#endif
|
||||||
__mg_dsk_msg_queue->last_ticks_desktop = __mg_tick_counter;
|
__mg_dsk_msg_queue->old_tick_count = ticks;
|
||||||
|
}
|
||||||
|
|
||||||
|
msg_queue->last_ticks = ticks;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0 /* deprecated code */
|
__mg_tick_counter = ticks;
|
||||||
|
return ticks;
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(_MGRM_PROCESSES)
|
#if defined(_MGRM_PROCESSES)
|
||||||
if (mgIsServer) {
|
|
||||||
DWORD elapsed_ticks;
|
|
||||||
|
|
||||||
/* Since 5.0.0, we use elapsed time in ms to count the ticks */
|
|
||||||
elapsed_ticks = __mg_os_get_elapsed_ms ();
|
|
||||||
elapsed_ticks = (elapsed_ticks + 5) / 10;
|
|
||||||
|
|
||||||
__mg_tick_counter += elapsed_ticks;
|
|
||||||
SHAREDRES_TIMER_COUNTER = __mg_tick_counter;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
__mg_tick_counter = SHAREDRES_TIMER_COUNTER;
|
|
||||||
}
|
|
||||||
#else /* defined _MGRM_PROCESSES */
|
|
||||||
DWORD elapsed_ticks;
|
|
||||||
|
|
||||||
/* Since 5.0.0, we use elapsed time in ms to count the ticks */
|
|
||||||
elapsed_ticks = __mg_os_get_elapsed_ms ();
|
|
||||||
elapsed_ticks = (elapsed_ticks + 5) / 10;
|
|
||||||
__mg_tick_counter += elapsed_ticks;
|
|
||||||
#endif /* not defined _MGRM_PROCESSES */
|
|
||||||
|
|
||||||
/* Since 5.0.0, the desktop only handles caret blinking in MSG_TIMEOUT
|
|
||||||
message, and the interval for the timer of desktop changes to 0.05s. */
|
|
||||||
if (__mg_tick_counter >
|
|
||||||
__mg_dsk_msg_queue->last_ticks_desktop + DESKTOP_TIMER_INERTVAL) {
|
|
||||||
__mg_dsk_msg_queue->dwState |= QS_DESKTIMER;
|
|
||||||
#ifdef _MGRM_THREADS /* only wake up desktop for threads mode */
|
|
||||||
POST_MSGQ (__mg_dsk_msg_queue);
|
|
||||||
#endif
|
|
||||||
__mg_dsk_msg_queue->last_ticks_desktop = __mg_tick_counter;
|
|
||||||
}
|
|
||||||
#endif /* deprecated code */
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __NOUNIX__
|
|
||||||
|
|
||||||
static BOOL install_system_timer (void)
|
|
||||||
{
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static BOOL unintall_system_timer (void)
|
|
||||||
{
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else /* defined __NOUNIX__ */
|
|
||||||
|
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@@ -163,6 +126,12 @@ static BOOL unintall_system_timer (void)
|
|||||||
static struct sigaction old_alarm_handler;
|
static struct sigaction old_alarm_handler;
|
||||||
static struct itimerval old_timer;
|
static struct itimerval old_timer;
|
||||||
|
|
||||||
|
static void timer_handler(int sig)
|
||||||
|
{
|
||||||
|
(void)sig;
|
||||||
|
__mg_update_tick_count(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
static BOOL install_system_timer (void)
|
static BOOL install_system_timer (void)
|
||||||
{
|
{
|
||||||
struct itimerval timerv;
|
struct itimerval timerv;
|
||||||
@@ -171,20 +140,12 @@ static BOOL install_system_timer (void)
|
|||||||
sigaction (SIGALRM, NULL, &old_alarm_handler);
|
sigaction (SIGALRM, NULL, &old_alarm_handler);
|
||||||
|
|
||||||
siga = old_alarm_handler;
|
siga = old_alarm_handler;
|
||||||
siga.sa_handler = (void(*)(int))__mg_update_tick_count;
|
siga.sa_handler = timer_handler;
|
||||||
#ifndef _MGRM_STANDALONE
|
|
||||||
siga.sa_flags = 0;
|
siga.sa_flags = 0;
|
||||||
#else
|
|
||||||
siga.sa_flags = SA_RESTART;
|
|
||||||
#endif
|
|
||||||
sigaction (SIGALRM, &siga, NULL);
|
sigaction (SIGALRM, &siga, NULL);
|
||||||
|
|
||||||
timerv.it_interval.tv_sec = 0;
|
timerv.it_interval.tv_sec = 0;
|
||||||
#if defined(__uClinux__) && defined(_MGRM_STANDALONE)
|
|
||||||
timerv.it_interval.tv_usec = 100000; /* 100 ms */
|
|
||||||
#else
|
|
||||||
timerv.it_interval.tv_usec = 10000; /* 10 ms */
|
timerv.it_interval.tv_usec = 10000; /* 10 ms */
|
||||||
#endif
|
|
||||||
timerv.it_value = timerv.it_interval;
|
timerv.it_value = timerv.it_interval;
|
||||||
|
|
||||||
if (setitimer (ITIMER_REAL, &timerv, &old_timer) == -1) {
|
if (setitimer (ITIMER_REAL, &timerv, &old_timer) == -1) {
|
||||||
@@ -209,26 +170,30 @@ static BOOL unintall_system_timer (void)
|
|||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
#endif /* defined(_MGRM_PROCESSES) */
|
||||||
|
|
||||||
#endif /* not defined __NOUNIX__ */
|
BOOL mg_InitTimer ()
|
||||||
|
|
||||||
BOOL mg_InitTimer (BOOL use_sys_timer)
|
|
||||||
{
|
{
|
||||||
__mg_tick_counter = 0;
|
__mg_tick_counter = 0;
|
||||||
|
|
||||||
__mg_os_start_time();
|
__mg_os_start_time();
|
||||||
|
|
||||||
if (use_sys_timer) {
|
#if defined(_MGRM_PROCESSES)
|
||||||
|
if (mgIsServer) {
|
||||||
install_system_timer ();
|
install_system_timer ();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void mg_TerminateTimer (BOOL use_sys_timer)
|
void mg_TerminateTimer (void)
|
||||||
{
|
{
|
||||||
if (use_sys_timer)
|
#if defined(_MGRM_PROCESSES)
|
||||||
|
if (mgIsServer) {
|
||||||
unintall_system_timer ();
|
unintall_system_timer ();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************* Functions run in message thread *******************/
|
/************************* Functions run in message thread *******************/
|
||||||
@@ -247,34 +212,19 @@ int __mg_check_expired_timers (MSGQUEUE* msg_queue, DWORD inter)
|
|||||||
int i;
|
int i;
|
||||||
TIMER** timer_slots = msg_queue->timer_slots;
|
TIMER** timer_slots = msg_queue->timer_slots;
|
||||||
|
|
||||||
|
__mg_update_tick_count (msg_queue);
|
||||||
|
|
||||||
for (i = 0; i < DEF_NR_TIMERS; i++) {
|
for (i = 0; i < DEF_NR_TIMERS; i++) {
|
||||||
if (timer_slots[i]) {
|
if (timer_slots[i]) {
|
||||||
if (__mg_tick_counter >= timer_slots[i]->ticks_expected) {
|
if (msg_queue->last_ticks >= timer_slots[i]->ticks_expected) {
|
||||||
/* setting timer flag is simple, we do not need to lock
|
/* setting timer flag is simple, we do not need to lock
|
||||||
msgq, or else we may encounter dead lock here */
|
msgq, or else we may encounter dead lock here */
|
||||||
msg_queue->expired_timer_mask |= (0x01UL << i);
|
msg_queue->expired_timer_mask |= (0x01UL << i);
|
||||||
POST_MSGQ (msg_queue);
|
POST_MSGQ (msg_queue);
|
||||||
|
|
||||||
timer_slots[i]->ticks_expected += timer_slots[i]->interv;
|
timer_slots[i]->ticks_expected += timer_slots[i]->interv;
|
||||||
timer_slots[i]->ticks_fired = __mg_tick_counter;
|
timer_slots[i]->ticks_fired = msg_queue->last_ticks;
|
||||||
nr++;
|
nr++;
|
||||||
}
|
}
|
||||||
#if 0 /* deprecated code */
|
|
||||||
timer_slots[i]->count += inter;
|
|
||||||
if (timer_slots[i]->count >= timer_slots[i]->interv) {
|
|
||||||
#ifdef _MGRM_PROCESSES
|
|
||||||
timer_slots[i]->ticks_current = SHAREDRES_TIMER_COUNTER;
|
|
||||||
#else
|
|
||||||
timer_slots[i]->ticks_current = __mg_tick_counter;
|
|
||||||
#endif
|
|
||||||
/* setting timer flag is simple, we do not need to lock msgq,
|
|
||||||
or else we may encounter dead lock here */
|
|
||||||
msg_queue->expired_timer_mask |= (0x01UL << i);
|
|
||||||
POST_MSGQ (msg_queue);
|
|
||||||
timer_slots[i]->count -= timer_slots[i]->interv;
|
|
||||||
nr++;
|
|
||||||
}
|
|
||||||
#endif /* deprecated code */
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -291,12 +241,7 @@ BOOL GUIAPI SetTimerEx (HWND hWnd, LINT id, DWORD interv,
|
|||||||
int i;
|
int i;
|
||||||
int slot = -1;
|
int slot = -1;
|
||||||
TIMER** timer_slots;
|
TIMER** timer_slots;
|
||||||
PMSGQUEUE pMsgQueue;
|
PMSGQUEUE msg_queue;
|
||||||
|
|
||||||
#ifndef _MGRM_THREADS
|
|
||||||
/* Force to update tick count */
|
|
||||||
GetTickCount();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (id == 0) {
|
if (id == 0) {
|
||||||
_WRN_PRINTF ("bad identifier (%ld).\n", id);
|
_WRN_PRINTF ("bad identifier (%ld).\n", id);
|
||||||
@@ -307,12 +252,14 @@ BOOL GUIAPI SetTimerEx (HWND hWnd, LINT id, DWORD interv,
|
|||||||
interv = 1;
|
interv = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
timer_slots = getTimerSlotsForThisThread (&pMsgQueue);
|
timer_slots = getTimerSlotsForThisThread (&msg_queue);
|
||||||
if (MG_UNLIKELY (timer_slots == NULL)) {
|
if (MG_UNLIKELY (timer_slots == NULL)) {
|
||||||
_WRN_PRINTF ("called for non message thread\n");
|
_WRN_PRINTF ("called for non message thread\n");
|
||||||
goto badret;
|
goto badret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__mg_update_tick_count (msg_queue);
|
||||||
|
|
||||||
/* Since 5.0.0: only check hWnd if timer_proc is NULL */
|
/* Since 5.0.0: only check hWnd if timer_proc is NULL */
|
||||||
if (MG_UNLIKELY (timer_proc == NULL &&
|
if (MG_UNLIKELY (timer_proc == NULL &&
|
||||||
!getMainWinIfWindowInThisThread (hWnd))) {
|
!getMainWinIfWindowInThisThread (hWnd))) {
|
||||||
@@ -331,7 +278,7 @@ BOOL GUIAPI SetTimerEx (HWND hWnd, LINT id, DWORD interv,
|
|||||||
/* Since 5.0.0: we reset timer parameters for duplicated call of
|
/* Since 5.0.0: we reset timer parameters for duplicated call of
|
||||||
this function */
|
this function */
|
||||||
timer_slots[i]->interv = interv;
|
timer_slots[i]->interv = interv;
|
||||||
timer_slots[i]->ticks_expected = __mg_tick_counter + interv;
|
timer_slots[i]->ticks_expected = msg_queue->last_ticks + interv;
|
||||||
timer_slots[i]->ticks_fired = 0;
|
timer_slots[i]->ticks_fired = 0;
|
||||||
timer_slots[i]->proc = timer_proc;
|
timer_slots[i]->proc = timer_proc;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@@ -348,14 +295,14 @@ BOOL GUIAPI SetTimerEx (HWND hWnd, LINT id, DWORD interv,
|
|||||||
timer_slots[slot]->hWnd = hWnd;
|
timer_slots[slot]->hWnd = hWnd;
|
||||||
timer_slots[slot]->id = id;
|
timer_slots[slot]->id = id;
|
||||||
timer_slots[slot]->interv = interv;
|
timer_slots[slot]->interv = interv;
|
||||||
timer_slots[slot]->ticks_expected = __mg_tick_counter + interv;
|
timer_slots[slot]->ticks_expected = msg_queue->last_ticks + interv;
|
||||||
timer_slots[slot]->ticks_fired = 0;
|
timer_slots[slot]->ticks_fired = 0;
|
||||||
timer_slots[slot]->proc = timer_proc;
|
timer_slots[slot]->proc = timer_proc;
|
||||||
|
|
||||||
_DBG_PRINTF ("ticks_expected (%d): %lu, tick_counter: %lu\n",
|
_DBG_PRINTF ("ticks_expected (%d): %lu, tick_counter: %lu\n",
|
||||||
slot, timer_slots[slot]->ticks_expected, __mg_tick_counter);
|
slot, timer_slots[slot]->ticks_expected, msg_queue->last_ticks);
|
||||||
|
|
||||||
pMsgQueue->nr_timers++;
|
msg_queue->nr_timers++;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
@@ -363,24 +310,6 @@ badret:
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0 /* deprected code */
|
|
||||||
#ifdef _MGRM_PROCESSES
|
|
||||||
static void reset_select_timeout (TIMER** timer_slots)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
unsigned int interv = 0;
|
|
||||||
for (i = 0; i < DEF_NR_TIMERS; i++) {
|
|
||||||
if (timer_slots[i]) {
|
|
||||||
if (interv == 0 || timer_slots[i]->interv < interv)
|
|
||||||
interv = timer_slots[i]->interv;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
__mg_set_select_timeout (USEC_10MS * interv);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif /* deprecated code */
|
|
||||||
|
|
||||||
void __mg_remove_timer (MSGQUEUE* msg_queue, int slot)
|
void __mg_remove_timer (MSGQUEUE* msg_queue, int slot)
|
||||||
{
|
{
|
||||||
TIMER** timer_slots;
|
TIMER** timer_slots;
|
||||||
@@ -470,13 +399,14 @@ BOOL GUIAPI ResetTimerEx (HWND hWnd, LINT id, DWORD interv,
|
|||||||
if (MG_LIKELY (msg_queue)) {
|
if (MG_LIKELY (msg_queue)) {
|
||||||
TIMER** timer_slots = msg_queue->timer_slots;
|
TIMER** timer_slots = msg_queue->timer_slots;
|
||||||
|
|
||||||
|
__mg_update_tick_count (msg_queue);
|
||||||
for (i = 0; i < DEF_NR_TIMERS; i++) {
|
for (i = 0; i < DEF_NR_TIMERS; i++) {
|
||||||
if (timer_slots[i] &&
|
if (timer_slots[i] &&
|
||||||
timer_slots[i]->hWnd == hWnd && timer_slots[i]->id == id) {
|
timer_slots[i]->hWnd == hWnd && timer_slots[i]->id == id) {
|
||||||
/* Should clear old timer flags */
|
/* Should clear old timer flags */
|
||||||
msg_queue->expired_timer_mask &= ~(0x01UL << i);
|
msg_queue->expired_timer_mask &= ~(0x01UL << i);
|
||||||
timer_slots[i]->interv = interv;
|
timer_slots[i]->interv = interv;
|
||||||
timer_slots[i]->ticks_expected = __mg_tick_counter + interv;
|
timer_slots[i]->ticks_expected = msg_queue->last_ticks + interv;
|
||||||
timer_slots[i]->ticks_fired = 0;
|
timer_slots[i]->ticks_fired = 0;
|
||||||
if (timer_proc != (TIMERPROC)INV_PTR)
|
if (timer_proc != (TIMERPROC)INV_PTR)
|
||||||
timer_slots[i]->proc = timer_proc;
|
timer_slots[i]->proc = timer_proc;
|
||||||
@@ -548,20 +478,6 @@ BOOL GUIAPI HaveFreeTimer (void)
|
|||||||
|
|
||||||
DWORD GUIAPI GetTickCount (void)
|
DWORD GUIAPI GetTickCount (void)
|
||||||
{
|
{
|
||||||
#if defined(_MGRM_PROCESSES)
|
return __mg_update_tick_count(getMsgQueueForThisThread ());
|
||||||
if (mgIsServer) {
|
|
||||||
__mg_tick_counter = __mg_os_get_time_ticks ();
|
|
||||||
SHAREDRES_TIMER_COUNTER = __mg_tick_counter;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
__mg_tick_counter = SHAREDRES_TIMER_COUNTER;
|
|
||||||
}
|
|
||||||
#elif defined(_MGRM_STANDALONE)
|
|
||||||
__mg_tick_counter = __mg_os_get_time_ticks ();
|
|
||||||
#else /* not defined _MGRM_PROCESSES and _MGRM_PROCESSES */
|
|
||||||
/* do nothing here because the desktop thread updates the tick count */
|
|
||||||
#endif /* not defined _MGRM_PROCESSES and _MGRM_PROCESSES */
|
|
||||||
|
|
||||||
return __mg_tick_counter;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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, ¤t);
|
|
||||||
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(¤t, 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"
|
||||||
|
|||||||
+81
-9
@@ -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; \
|
||||||
}
|
}
|
||||||
|
|
||||||
C_ALPHA(bits, rgba_fg.r, rgba_cur.r);
|
if (rgba_cur.r == 0 && rgba_cur.g == 0 && rgba_cur.b == 0 &&
|
||||||
C_ALPHA(bits, rgba_fg.g, rgba_cur.g);
|
rgba_cur.a == 0) {
|
||||||
C_ALPHA(bits, rgba_fg.b, rgba_cur.b);
|
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.g, rgba_cur.g);
|
||||||
|
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);
|
||||||
|
|||||||
+2
-24
@@ -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) {
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
Reference in New Issue
Block a user