Add support for the Haiku operating system and its window system
* .gitignore: Add binaries specific to Haiku. * Makefie.in (HAVE_BE_APP): New variable. (install-arch-dep): Install Emacs and Emacs.pdmp when using Haiku. * configure.ac: Detect and configure for Haiku and various related configurations. (be-app, be-freetype, be-cairo): New options. (HAVE_BE_APP, HAIKU_OBJ, HAIKU_CXX_OBJ) (HAIKU_LIBS, HAIKU_CFLAGS): New variables. (HAIKU, HAVE_TINY_SPEED_T): New define. (emacs_config_features): Add BE_APP. * doc/emacs/Makefile.in (EMACSSOURCES): Add Haiku appendix. * doc/emacs/emacs.texi: Add Haiku appendix to menus and include it. * doc/emacs/haiku.texi: New Haiku appendix. * doc/lispref/display.texi (Defining Faces, Window Systems): Explain meaning of `haiku' as a window system identifier. (haiku-use-system-tooltips): Explain meaning of system tooltips on Haiku. * doc/lispref/frames.texi (Multiple Terminals): Explain meaning of haiku as a display type. (Frame Layout): Clarify section for Haiku frames. (Size Parameters): Explain limitations of fullwidth and fullheight on Haiku. (Management Parameters): Explain limitations of inhibiting double buffering on builds with Cairo, and the inability of frames with no-accept-focus to receive keyboard input on Haiku. (Font and Color Parameters): Explain the different font backends available on Haiku. (Raising and Lowering): Explain that lowering and restacking frames doesn't work on Haiku. (Child Frames): Explain oddities of child frame visibility on Haiku. * doc/lispref/os.texi (System Environment): Explain meaning of haiku. * etc/MACHINES: Add appropriate notices for Haiku. * etc/NEWS: Document changes. * etc/PROBLEMS: Document font spacing bug on Haiku. * lib-src/Makefile.in: Build be-resources binary on Haiku. (CXX, CXXFLAGS, NON_CXX_FLAGS, ALL_CXXFLAGS) (HAVE_BE_APP, HAIKU_LIBS, HAIKU_CFLAGS): New variables. (DONT_INSTALL): Add be-resources binary if on Haiku. (be-resources): New target. * lib-src/be_resources: Add helper binary for setting resources on the Emacs application. * lib-src/emacsclient.c (decode_options): Set alt_display to "be" on Haiku. * lisp/cus-edit.el (custom-button, custom-button-mouse) (custom-button-unraised, custom-button-pressed): Update face definitions for Haiku. * lisp/cus-start.el: Add haiku-debug-on-fatal-error and haiku-use-system-tooltips. * lisp/faces.el (face-valid-attribute-values): Clarify attribute comment for Haiku. (tool-bar): Add appropriate toolbar color for Haiku. * lisp/frame.el (haiku-frame-geometry) (haiku-mouse-absolute-pixel-position) (haiku-set-mouse-absolute-pixel-position) (haiku-frame-edges) (haiku-frame-list-z-order): New function declarations. (frame-geometry, frame-edges) (mouse-absolute-pixel-position) (set-mouse-absolute-pixel-position) (frame-list-z-order): Call appropriate window system functions on Haiku. (display-mouse-p, display-graphic-p) (display-images-p, display-pixel-height) (display-pixel-width, display-mm-height) (display-mm-width, display-backing-store) (display-save-under, display-planes) (display-color-cells, display-visual-class): Update type tests for Haiku. * lisp/international/mule-cmds.el (set-coding-system-map): Also prevent set-terminal-coding-system from appearing in the menu bar on Haiku. * lisp/loadup.el: Load Haiku-specific files when built with Haiku, and don't rename newly built Emacs on Haiku as BFS doesn't support hard links. * lisp/menu-bar.el (menu-bar-open): Add for Haiku. * lisp/mwheel.el (mouse-wheel-down-event): Expect wheel-up on Haiku. (mouse-wheel-up-event): Expect wheel-down on Haiku. (mouse-wheel-left-event): Expect wheel-left on Haiku. (mouse-wheel-right-event): Expect wheel-right on Haiku. * lisp/net/browse-url.el (browse-url--browser-defcustom-type): Add option for WebPositive. (browse-url-webpositive-program): New variable. (browse-url-default-program): Search for WebPositive. (browse-url-webpositive): New function. * lisp/net/eww.el (eww-form-submit, eww-form-file) (eww-form-checkbox, eww-form-select): Define faces appropriately for Haiku. * lisp/term/haiku-win.el: New file. * lisp/tooltip.el (menu-or-popup-active-p): New function declaration. (tooltip-show-help): Don't use tooltips on Haiku when a menu is active. * lisp/version.el (haiku-get-version-string): New function declaration. (emacs-version): Add Haiku version string if appropriate. * src/Makefile.in: Also produce binary named "Emacs" with Haiku resources set. (CXX, HAIKU_OBJ, HAIKU_CXX_OBJ, HAIKU_LIBS) (HAIKU_CFLAGS, HAVE_BE_APP, NON_CXX_FLAGS) (ALL_CXX_FLAGS): New variables. (.SUFFIXES): Add .cc. (.cc.o): New target. (base_obj): Add Haiku C objects. (doc_obj, obj): Split objects that should scanned for documentation into doc_obj. (SOME_MACHINE_OBJECTS): Add appropriate Haiku C objects. (all): Depend on Emacs and Emacs.pdmp on Haiku. (LIBES): Add Haiku libraries. (gl-stamp) ($(etc)/DOC): Scan doc_obj instead of obj (temacs$(EXEEXT): Use C++ linker on Haiku. (ctagsfiles3): New variable. (TAGS): Scan C++ files. * src/alloc.c (garbage_collect): Mark Haiku display. * src/dispextern.h (HAVE_NATIVE_TRANSFORMS): Also enable on Haiku. (struct image): Add fields for Haiku transforms. (RGB_PIXEL_COLOR): Define to unsigned long on Haiku as well. (sit_for): Also check USABLE_SIGPOLL. (init_display_interactive): Set initial window system to Haiku on Haiku builds. * src/emacs.c (main): Define Haiku syms and init haiku clipboard. (shut_down_emacs): Quit BApplication on Haiku and trigger debug on aborts if haiku_debug_on_fatal_error. (Vsystem_type): Update docstring. * src/fileio.c (next-read-file-uses-dialog-p): Enable on Haiku. * src/filelock.c (WTMP_FILE): Only define if BOOT_TIME is also defined. * src/floatfns.c (double_integer_scale): Work around Haiku libroot brain damage. * src/font.c (syms_of_font): Define appropriate font driver symbols for Haiku builds with various options. * src/font.h: Also enable ftcrfont on Haiku builds with Cairo. (font_data_structures_may_be_ill_formed): Also enable on Haiku builds that have Cairo. * src/frame.c (Fframep): Update doc-string for Haiku builds and return haiku if appropriate. (syms_of_frame): New symbol `haiku'. * src/frame.h (struct frame): Add output data for Haiku. (FRAME_HAIKU_P): New macro. (FRAME_WINDOW_P): Test for Haiku frames as well. * src/ftcrfont.c (RED_FROM_ULONG, GREEN_FROM_ULONG) (BLUE_FROM_ULONG): New macros. (ftcrfont_draw): Add haiku specific code for Haiku builds with Cairo. * src/ftfont.c (ftfont_open): Set face. (ftfont_has_char, ftfont_text_extents): Work around crash. (syms_of_ftfont): New symbol `mono'. * src/ftfont.h (struct font_info): Enable Cairo-specific fields for Cairo builds on Haiku. * src/haiku_draw_support.cc: * src/haiku_font_support.cc: * src/haiku_io.c: * src/haiku_select.cc: * src/haiku_support.cc: * src/haiku_support.h: * src/haikufns.c: * src/haikufont.c: * src/haikugui.h: * src/haikuimage.c: * src/haikumenu.c: * src/haikuselect.c: * src/haikuselect.h: * src/haikuterm.c: * src/haikuterm.h: Add new files for Haiku windowing support. * src/haiku.c: Add new files for Haiku operating system support. * src/image.c: Implement image transforms and native XPM support on Haiku. (GET_PIXEL, PUT_PIXEL, NO_PIXMAP) (PIX_MASK_RETAIN, PIX_MASK_DRAW) (RGB_TO_ULONG, RED_FROM_ULONG, GREEN_FROM_ULONG) (BLUE_FROM_ULONG, RED16_FROM_ULONG, GREEN16_FROM_ULONG) (BLUE16_FROM_ULONG): Define to appropriate values on Haiku. (image_create_bitmap_from_data): Add Haiku support. (image_create_bitmap_from_file): Add TODO on Haiku. (free_bitmap_record): Free bitmap on Haiku. (image_size_in_bytes): Implement for Haiku bitmaps. (image_set_transform): Implement on Haiku. (image_create_x_image_and_pixmap_1): Implement on Haiku, 24-bit or 1-bit only. (image_destroy_x_image, image_get_x_image): Use correct img and pixmap values on Haiku. (lookup_rgb_color): Use correct macro on Haiku. (image_to_emacs_colors): Implement on Haiku. (image_disable_image): Disable on Haiku. (image_can_use_native_api): Test for translator presence on Haiku. (native_image_load): Use translator on Haiku. (imagemagick_load_image): Add Haiku-specific quirks. (Fimage_transforms_p): Allow rotate90 on Haiku. (image_types): Enable native XPM support on Haiku. (syms_of_image): Enable XPM images on Haiku. * src/keyboard.c (kbd_buffer_get_event) (handle_async_input, handle_input_available_signal) (handle_user_signal, Fset_input_interrupt_mode) (init_keyboard): Check for USABLE_SIGPOLL along with USABLE_SIGIO. * src/lisp.h (pD): Work around broken Haiku headers. (HAVE_EXT_MENU_BAR): Define on Haiku. (handle_input_available_signal): Enable if we just have SIGPOLL as well. * src/menu.c (have_boxes): Return true on Haiku. (single_menu_item): Enable toolkit menus on Haiku. (find_and_call_menu_selection): Also enable on Haiku. * src/process.c (keyboard_bit_set): Enable with only usable SIGPOLL. (wait_reading_process_output): Test for SIGPOLL as well as SIGIO availability. * src/sound.c (sound_perror, vox_open) (vox_configure, vox_close): Enable for usable SIGPOLL as well. * src/sysdep.c (sys_subshell): Enable for usable SIGPOLL. (reset_sigio): Make conditional on F_SETOWN. (request_sigio, unrequest_sigio) (emacs_sigaction_init): Also handle SIGPOLLs. (init_sys_modes): Disable TCXONC usage on Haiku, as it doesn't have any ttys other than pseudo ttys, which don't support C-s/C-q flow control, and causes compiler warnings. (speeds): Disable high speeds if HAVE_TINY_SPEED_T. * src/termhooks.h (enum output_method): Add output_haiku. (struct terminal): Add Haiku display info. (TERMINAL_FONT_CACHE): Enable for Haiku. * src/terminal.c (Fterminal_live_p): Return `haiku' if appropriate. * src/verbose.mk.in (AM_V_CXX, AM_V_CXXLD): New logging variables. * src/xdisp.c (redisplay_internal) (note_mouse_highlight): Return on Haiku if a popup is activated. (display_menu_bar): Return on Haiku if frame is a Haiku frame. * src/xfaces.c (GCGraphicsExposures): Enable correctly on Haiku. (x_create_gc): Enable dummy GC code on Haiku. * src/xfns.c (x-server-version, x-file-dialog): Add Haiku specifics to doc strings. * src/xterm.c (syms_of_xterm): Add Haiku information to doc string.
This commit is contained in:
parent
bfcc59371b
commit
85a078e785
73 changed files with 15344 additions and 138 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -182,6 +182,7 @@ ID
|
|||
# Executables.
|
||||
*.exe
|
||||
a.out
|
||||
lib-src/be-resources
|
||||
lib-src/blessmail
|
||||
lib-src/ctags
|
||||
lib-src/ebrowse
|
||||
|
@ -203,6 +204,7 @@ nextstep/GNUstep/Emacs.base/Resources/Info-gnustep.plist
|
|||
src/bootstrap-emacs
|
||||
src/emacs
|
||||
src/emacs-[0-9]*
|
||||
src/Emacs
|
||||
src/temacs
|
||||
src/dmpstruct.h
|
||||
src/*.pdmp
|
||||
|
|
|
@ -102,6 +102,8 @@ HAVE_NATIVE_COMP = @HAVE_NATIVE_COMP@
|
|||
|
||||
USE_STARTUP_NOTIFICATION = @USE_STARTUP_NOTIFICATION@
|
||||
|
||||
HAVE_BE_APP = @HAVE_BE_APP@
|
||||
|
||||
# ==================== Where To Install Things ====================
|
||||
|
||||
# Location to install Emacs.app under GNUstep / macOS.
|
||||
|
@ -521,7 +523,13 @@ install-arch-dep: src install-arch-indep install-etcdoc install-$(NTDIR)
|
|||
$(MAKE) -C lib-src install
|
||||
ifeq (${ns_self_contained},no)
|
||||
${INSTALL_PROGRAM} $(INSTALL_STRIP) src/emacs${EXEEXT} "$(DESTDIR)${bindir}/$(EMACSFULL)"
|
||||
ifeq (${HAVE_BE_APP},yes)
|
||||
${INSTALL_PROGRAM} $(INSTALL_STRIP) src/Emacs "$(DESTDIR)${prefix}/apps/Emacs"
|
||||
endif
|
||||
ifeq (${DUMPING},pdumper)
|
||||
ifeq (${HAVE_BE_APP},yes)
|
||||
${INSTALL_DATA} src/Emacs.pdmp "$(DESTDIR)${libexecdir}/emacs/${version}/${configuration}"/Emacs.pdmp
|
||||
endif
|
||||
${INSTALL_DATA} src/emacs.pdmp "$(DESTDIR)${libexecdir}/emacs/${version}/${configuration}"/emacs-${EMACS_PDMP}
|
||||
endif
|
||||
-chmod 755 "$(DESTDIR)${bindir}/$(EMACSFULL)"
|
||||
|
|
222
configure.ac
222
configure.ac
|
@ -511,6 +511,12 @@ otherwise for the first of 'inotify', 'kqueue' or 'gfile' that is usable.])
|
|||
OPTION_DEFAULT_OFF([xwidgets],
|
||||
[enable use of xwidgets in Emacs buffers (requires gtk3 or macOS Cocoa)])
|
||||
|
||||
OPTION_DEFAULT_OFF([be-app],
|
||||
[enable use of Haiku's Application Kit as a window system])
|
||||
|
||||
OPTION_DEFAULT_OFF([be-cairo],
|
||||
[enable use of cairo under Haiku's Application Kit])
|
||||
|
||||
## Makefile.in needs the cache file name.
|
||||
AC_SUBST(cache_file)
|
||||
|
||||
|
@ -787,6 +793,10 @@ case "${canonical}" in
|
|||
LDFLAGS="-N2M $LDFLAGS"
|
||||
;;
|
||||
|
||||
*-haiku )
|
||||
opsys=haiku
|
||||
;;
|
||||
|
||||
## Intel 386 machines where we don't care about the manufacturer.
|
||||
i[3456]86-*-* )
|
||||
case "${canonical}" in
|
||||
|
@ -908,7 +918,9 @@ if test "$ac_test_CFLAGS" != set; then
|
|||
if test $emacs_cv_prog_cc_g3 != yes; then
|
||||
CFLAGS=$emacs_save_CFLAGS
|
||||
fi
|
||||
if test $opsys = mingw32; then
|
||||
# Haiku also needs -gdwarf-2 because its GDB is too old
|
||||
# to understand newer formats.
|
||||
if test $opsys = mingw32 || test $opsys = haiku; then
|
||||
CFLAGS="$CFLAGS -gdwarf-2"
|
||||
fi
|
||||
fi
|
||||
|
@ -1575,6 +1587,8 @@ case "$opsys" in
|
|||
|
||||
## Motif needs -lgen.
|
||||
unixware) LIBS_SYSTEM="-lsocket -lnsl -lelf -lgen" ;;
|
||||
|
||||
haiku) LIBS_SYSTEM="-lnetwork" ;;
|
||||
esac
|
||||
|
||||
AC_SUBST(LIBS_SYSTEM)
|
||||
|
@ -2080,6 +2094,22 @@ if test "${HAVE_NS}" = yes; then
|
|||
fi
|
||||
fi
|
||||
|
||||
HAVE_BE_APP=no
|
||||
if test "${opsys}" = "haiku" && test "${with_be_app}" = "yes"; then
|
||||
dnl Only GCC is supported. Clang might work, but it's
|
||||
dnl not reliable, so don't check for it here.
|
||||
AC_PROG_CXX([gcc g++])
|
||||
CXXFLAGS="$CXXFLAGS $emacs_g3_CFLAGS"
|
||||
AC_LANG_PUSH([C++])
|
||||
AC_CHECK_HEADER([app/Application.h], [HAVE_BE_APP=yes],
|
||||
[AC_MSG_ERROR([The Application Kit headers required for building
|
||||
with the Application Kit were not found or cannot be compiled. Either fix this, or
|
||||
re-configure with the option '--without-be-app'.])])
|
||||
AC_LANG_POP([C++])
|
||||
fi
|
||||
|
||||
AC_SUBST(HAVE_BE_APP)
|
||||
|
||||
HAVE_W32=no
|
||||
W32_OBJ=
|
||||
W32_LIBS=
|
||||
|
@ -2201,6 +2231,39 @@ if test "${HAVE_W32}" = "yes"; then
|
|||
with_xft=no
|
||||
fi
|
||||
|
||||
HAIKU_OBJ=
|
||||
HAIKU_CXX_OBJ=
|
||||
HAIKU_LIBS=
|
||||
HAIKU_CFLAGS=
|
||||
|
||||
if test "$opsys" = "haiku"; then
|
||||
HAIKU_OBJ="$HAIKU_OBJ haiku.o"
|
||||
fi
|
||||
|
||||
if test "${HAVE_BE_APP}" = "yes"; then
|
||||
AC_DEFINE([HAVE_HAIKU], 1,
|
||||
[Define if Emacs will be built with Haiku windowing support])
|
||||
fi
|
||||
|
||||
if test "${HAVE_BE_APP}" = "yes"; then
|
||||
window_system=haiku
|
||||
with_xft=no
|
||||
HAIKU_OBJ="$HAIKU_OBJ haikufns.o haikuterm.o haikumenu.o haikufont.o haikuselect.o haiku_io.o"
|
||||
HAIKU_CXX_OBJ="haiku_support.o haiku_font_support.o haiku_draw_support.o haiku_select.o"
|
||||
HAIKU_LIBS="-lbe -lgame -ltranslation -ltracker" # -lgame is needed for set_mouse_position.
|
||||
|
||||
if test "${with_native_image_api}" = yes; then
|
||||
AC_DEFINE(HAVE_NATIVE_IMAGE_API, 1, [Define to use native OS APIs for images.])
|
||||
NATIVE_IMAGE_API="yes (haiku)"
|
||||
HAIKU_OBJ="$HAIKU_OBJ haikuimage.o"
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_SUBST(HAIKU_LIBS)
|
||||
AC_SUBST(HAIKU_OBJ)
|
||||
AC_SUBST(HAIKU_CXX_OBJ)
|
||||
AC_SUBST(HAIKU_CFLAGS)
|
||||
|
||||
## $window_system is now set to the window system we will
|
||||
## ultimately use.
|
||||
|
||||
|
@ -2240,6 +2303,9 @@ dnl use the toolkit if we have gtk, or X11R5 or newer.
|
|||
w32 )
|
||||
term_header=w32term.h
|
||||
;;
|
||||
haiku )
|
||||
term_header=haikuterm.h
|
||||
;;
|
||||
esac
|
||||
|
||||
if test "$window_system" = none && test "X$with_x" != "Xno"; then
|
||||
|
@ -2571,7 +2637,8 @@ fi
|
|||
|
||||
### Use -lrsvg-2 if available, unless '--with-rsvg=no' is specified.
|
||||
HAVE_RSVG=no
|
||||
if test "${HAVE_X11}" = "yes" || test "${HAVE_NS}" = "yes" || test "${opsys}" = "mingw32"; then
|
||||
if test "${HAVE_X11}" = "yes" || test "${HAVE_NS}" = "yes" \
|
||||
|| test "${opsys}" = "mingw32" || test "${HAVE_BE_APP}" = "yes"; then
|
||||
if test "${with_rsvg}" != "no"; then
|
||||
RSVG_REQUIRED=2.14.0
|
||||
RSVG_MODULE="librsvg-2.0 >= $RSVG_REQUIRED"
|
||||
|
@ -2595,7 +2662,8 @@ fi
|
|||
HAVE_WEBP=no
|
||||
if test "${with_webp}" != "no"; then
|
||||
if test "${HAVE_X11}" = "yes" || test "${opsys}" = "mingw32" \
|
||||
|| test "${HAVE_W32}" = "yes" || test "${HAVE_NS}" = "yes"; then
|
||||
|| test "${HAVE_W32}" = "yes" || test "${HAVE_NS}" = "yes" \
|
||||
|| test "${HAVE_BE_APP}" = "yes"; then
|
||||
WEBP_REQUIRED=0.6.0
|
||||
WEBP_MODULE="libwebp >= $WEBP_REQUIRED"
|
||||
|
||||
|
@ -2614,7 +2682,8 @@ if test "${with_webp}" != "no"; then
|
|||
fi
|
||||
|
||||
HAVE_IMAGEMAGICK=no
|
||||
if test "${HAVE_X11}" = "yes" || test "${HAVE_NS}" = "yes" || test "${HAVE_W32}" = "yes"; then
|
||||
if test "${HAVE_X11}" = "yes" || test "${HAVE_NS}" = "yes" || test "${HAVE_W32}" = "yes" || \
|
||||
test "${HAVE_BE_APP}" = "yes"; then
|
||||
if test "${with_imagemagick}" != "no"; then
|
||||
if test -n "$BREW"; then
|
||||
# Homebrew doesn't link ImageMagick 6 by default, so make sure
|
||||
|
@ -3264,6 +3333,9 @@ if test "${with_toolkit_scroll_bars}" != "no"; then
|
|||
elif test "${HAVE_W32}" = "yes"; then
|
||||
AC_DEFINE(USE_TOOLKIT_SCROLL_BARS)
|
||||
USE_TOOLKIT_SCROLL_BARS=yes
|
||||
elif test "${HAVE_BE_APP}" = "yes"; then
|
||||
AC_DEFINE(USE_TOOLKIT_SCROLL_BARS)
|
||||
USE_TOOLKIT_SCROLL_BARS=yes
|
||||
fi
|
||||
fi
|
||||
|
||||
|
@ -3353,6 +3425,22 @@ if test "${HAVE_X11}" = "yes"; then
|
|||
fi
|
||||
fi
|
||||
fi
|
||||
if test "${HAVE_BE_APP}" = "yes"; then
|
||||
if test "${with_be_cairo}" != "no"; then
|
||||
CAIRO_REQUIRED=1.8.0
|
||||
CAIRO_MODULE="cairo >= $CAIRO_REQUIRED"
|
||||
EMACS_CHECK_MODULES(CAIRO, $CAIRO_MODULE)
|
||||
if test $HAVE_CAIRO = yes; then
|
||||
AC_DEFINE(USE_BE_CAIRO, 1, [Define to 1 if using cairo on Haiku.])
|
||||
CFLAGS="$CFLAGS $CAIRO_CFLAGS"
|
||||
LIBS="$LIBS $CAIRO_LIBS"
|
||||
AC_SUBST(CAIRO_CFLAGS)
|
||||
AC_SUBST(CAIRO_LIBS)
|
||||
else
|
||||
AC_MSG_WARN([cairo requested but not found.])
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
### Start of font-backend (under any platform) section.
|
||||
# (nothing here yet -- this is a placeholder)
|
||||
|
@ -3502,6 +3590,58 @@ if test "${HAVE_X11}" = "yes" && test "${HAVE_FREETYPE}" = "yes" \
|
|||
fi
|
||||
fi
|
||||
|
||||
### Start of font-backend (under Haiku) selectionn.
|
||||
if test "${HAVE_BE_APP}" = "yes"; then
|
||||
if test $HAVE_CAIRO = "yes"; then
|
||||
EMACS_CHECK_MODULES([FREETYPE], [freetype2 >= 2.5.0])
|
||||
test "$HAVE_FREETYPE" = "no" && AC_MSG_ERROR(cairo on Haiku requires libfreetype)
|
||||
EMACS_CHECK_MODULES([FONTCONFIG], [fontconfig >= 2.2.0])
|
||||
test "$HAVE_FONTCONFIG" = "no" && AC_MSG_ERROR(cairo on Haiku requires libfontconfig)
|
||||
fi
|
||||
|
||||
HAVE_LIBOTF=no
|
||||
|
||||
if test "${HAVE_FREETYPE}" = "yes"; then
|
||||
AC_DEFINE(HAVE_FREETYPE, 1,
|
||||
[Define to 1 if using the freetype and fontconfig libraries.])
|
||||
OLD_CFLAGS=$CFLAGS
|
||||
OLD_LIBS=$LIBS
|
||||
CFLAGS="$CFLAGS $FREETYPE_CFLAGS"
|
||||
LIBS="$FREETYPE_LIBS $LIBS"
|
||||
AC_CHECK_FUNCS(FT_Face_GetCharVariantIndex)
|
||||
CFLAGS=$OLD_CFLAGS
|
||||
LIBS=$OLD_LIBS
|
||||
if test "${with_libotf}" != "no"; then
|
||||
EMACS_CHECK_MODULES([LIBOTF], [libotf])
|
||||
if test "$HAVE_LIBOTF" = "yes"; then
|
||||
AC_DEFINE(HAVE_LIBOTF, 1, [Define to 1 if using libotf.])
|
||||
AC_CHECK_LIB(otf, OTF_get_variation_glyphs,
|
||||
HAVE_OTF_GET_VARIATION_GLYPHS=yes,
|
||||
HAVE_OTF_GET_VARIATION_GLYPHS=no)
|
||||
if test "${HAVE_OTF_GET_VARIATION_GLYPHS}" = "yes"; then
|
||||
AC_DEFINE(HAVE_OTF_GET_VARIATION_GLYPHS, 1,
|
||||
[Define to 1 if libotf has OTF_get_variation_glyphs.])
|
||||
fi
|
||||
if ! $PKG_CONFIG --atleast-version=0.9.16 libotf; then
|
||||
AC_DEFINE(HAVE_OTF_KANNADA_BUG, 1,
|
||||
[Define to 1 if libotf is affected by https://debbugs.gnu.org/28110.])
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
dnl FIXME should there be an error if HAVE_FREETYPE != yes?
|
||||
dnl Does the new font backend require it, or can it work without it?
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "${HAVE_BE_APP}" = "yes" && test "${HAVE_FREETYPE}" = "yes"; then
|
||||
if test "${with_harfbuzz}" != "no"; then
|
||||
EMACS_CHECK_MODULES([HARFBUZZ], [harfbuzz >= $harfbuzz_required_ver])
|
||||
if test "$HAVE_HARFBUZZ" = "yes"; then
|
||||
AC_DEFINE(HAVE_HARFBUZZ, 1, [Define to 1 if using HarfBuzz.])
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
### End of font-backend section.
|
||||
|
||||
AC_SUBST(FREETYPE_CFLAGS)
|
||||
|
@ -3623,7 +3763,7 @@ AC_SUBST(LIBXPM)
|
|||
HAVE_JPEG=no
|
||||
LIBJPEG=
|
||||
if test "${HAVE_X11}" = "yes" || test "${HAVE_W32}" = "yes" \
|
||||
|| test "${HAVE_NS}" = "yes"; then
|
||||
|| test "${HAVE_NS}" = "yes" || test "${HAVE_BE_APP}" = "yes"; then
|
||||
if test "${with_jpeg}" != "no"; then
|
||||
AC_CACHE_CHECK([for jpeglib 6b or later],
|
||||
[emacs_cv_jpeglib],
|
||||
|
@ -3941,7 +4081,7 @@ if test "${with_png}" != no; then
|
|||
if test "$opsys" = mingw32; then
|
||||
AC_CHECK_HEADER([png.h], [HAVE_PNG=yes])
|
||||
elif test "${HAVE_X11}" = "yes" || test "${HAVE_W32}" = "yes" \
|
||||
|| test "${HAVE_NS}" = "yes"; then
|
||||
|| test "${HAVE_NS}" = "yes" || test "${HAVE_BE_APP}" = "yes"; then
|
||||
EMACS_CHECK_MODULES([PNG], [libpng >= 1.0.0])
|
||||
if test $HAVE_PNG = yes; then
|
||||
LIBPNG=$PNG_LIBS
|
||||
|
@ -4016,7 +4156,7 @@ if test "${opsys}" = "mingw32"; then
|
|||
AC_DEFINE(HAVE_TIFF, 1, [Define to 1 if you have the tiff library (-ltiff).])
|
||||
fi
|
||||
elif test "${HAVE_X11}" = "yes" || test "${HAVE_W32}" = "yes" \
|
||||
|| test "${HAVE_NS}" = "yes"; then
|
||||
|| test "${HAVE_NS}" = "yes" || test "${HAVE_BE_APP}" = "yes"; then
|
||||
if test "${with_tiff}" != "no"; then
|
||||
AC_CHECK_HEADER(tiffio.h,
|
||||
[tifflibs="-lz -lm"
|
||||
|
@ -4045,7 +4185,8 @@ if test "${opsys}" = "mingw32"; then
|
|||
AC_DEFINE(HAVE_GIF, 1, [Define to 1 if you have a gif (or ungif) library.])
|
||||
fi
|
||||
elif test "${HAVE_X11}" = "yes" && test "${with_gif}" != "no" \
|
||||
|| test "${HAVE_W32}" = "yes" || test "${HAVE_NS}" = "yes"; then
|
||||
|| test "${HAVE_W32}" = "yes" || test "${HAVE_NS}" = "yes" \
|
||||
|| test "${HAVE_BE_APP}" = "yes"; then
|
||||
AC_CHECK_HEADER(gif_lib.h,
|
||||
# EGifPutExtensionLast only exists from version libungif-4.1.0b1.
|
||||
# Earlier versions can crash Emacs, but version 5.0 removes EGifPutExtensionLast.
|
||||
|
@ -4482,6 +4623,13 @@ case $with_unexec,$canonical in
|
|||
[AC_MSG_ERROR([Non-ELF systems are not supported on this platform.])]);;
|
||||
esac
|
||||
|
||||
if test "$with_unexec" = yes && test "$opsys" = "haiku"; then
|
||||
dnl A serious attempt was actually made to port unexec to Haiku.
|
||||
dnl Something in libstdc++ seems to prevent it from working.
|
||||
AC_MSG_ERROR([Haiku is not supported by the legacy unexec dumper.
|
||||
Please use the portable dumper instead.])
|
||||
fi
|
||||
|
||||
# Dump loading
|
||||
AC_CHECK_FUNCS([posix_madvise])
|
||||
|
||||
|
@ -4835,7 +4983,7 @@ CFLAGS="$OLDCFLAGS"
|
|||
LIBS="$OLDLIBS"])
|
||||
if test "${emacs_cv_links_glib}" = "yes"; then
|
||||
AC_DEFINE(HAVE_GLIB, 1, [Define to 1 if GLib is linked in.])
|
||||
if test "$HAVE_NS" = no;then
|
||||
if test "$HAVE_NS" = no ; then
|
||||
XGSELOBJ=xgselect.o
|
||||
fi
|
||||
fi
|
||||
|
@ -5090,7 +5238,7 @@ dnl It would have Emacs fork off a separate process
|
|||
dnl to read the input and send it to the true Emacs process
|
||||
dnl through a pipe.
|
||||
case $opsys in
|
||||
darwin | gnu-linux | gnu-kfreebsd )
|
||||
darwin | gnu-linux | gnu-kfreebsd)
|
||||
AC_DEFINE(INTERRUPT_INPUT, 1, [Define to read input using SIGIO.])
|
||||
;;
|
||||
esac
|
||||
|
@ -5186,6 +5334,14 @@ case $opsys in
|
|||
AC_DEFINE(PTY_OPEN, [fd = open (pty_name, O_RDWR | O_NONBLOCK)])
|
||||
AC_DEFINE(PTY_TTY_NAME_SPRINTF, [{ char *ptsname (int), *ptyname; int grantpt_result; sigset_t blocked; sigemptyset (&blocked); sigaddset (&blocked, SIGCHLD); pthread_sigmask (SIG_BLOCK, &blocked, 0); grantpt_result = grantpt (fd); pthread_sigmask (SIG_UNBLOCK, &blocked, 0); if (grantpt_result == -1) fatal("could not grant slave pty"); if (unlockpt(fd) == -1) fatal("could not unlock slave pty"); if (!(ptyname = ptsname(fd))) fatal ("could not enable slave pty"); snprintf (pty_name, PTY_NAME_SIZE, "%s", ptyname); }])
|
||||
;;
|
||||
|
||||
haiku*)
|
||||
AC_DEFINE(FIRST_PTY_LETTER, ['s'])
|
||||
AC_DEFINE(PTY_NAME_SPRINTF, [])
|
||||
dnl on Haiku pty names aren't distinctive, thus the use of posix_openpt
|
||||
AC_DEFINE(PTY_OPEN, [fd = posix_openpt (O_RDWR | O_NONBLOCK)])
|
||||
AC_DEFINE(PTY_TTY_NAME_SPRINTF, [{ char *ptyname; int grantpt_result; sigset_t blocked; sigemptyset (&blocked); sigaddset (&blocked, SIGCHLD); pthread_sigmask (SIG_BLOCK, &blocked, 0); grantpt_result = grantpt (fd); pthread_sigmask (SIG_UNBLOCK, &blocked, 0); if (grantpt_result == -1) fatal("could not grant slave pty"); if (unlockpt(fd) == -1) fatal("could not unlock slave pty"); if (!(ptyname = ptsname(fd))) fatal ("could not enable slave pty"); snprintf (pty_name, PTY_NAME_SIZE, "%s", ptyname); }])
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
|
@ -5407,8 +5563,25 @@ case $opsys in
|
|||
AC_DEFINE(USG, [])
|
||||
AC_DEFINE(USG5_4, [])
|
||||
;;
|
||||
|
||||
haiku)
|
||||
AC_DEFINE(HAIKU, [], [Define if the system is Haiku.])
|
||||
;;
|
||||
esac
|
||||
|
||||
AC_SYS_POSIX_TERMIOS
|
||||
if test $ac_cv_sys_posix_termios = yes; then
|
||||
AC_CHECK_SIZEOF([speed_t], [], [#include <termios.h>])
|
||||
dnl on Haiku, and possibly other platforms, speed_t is defined to
|
||||
dnl unsigned char, even when speeds greater than 200 baud are
|
||||
dnl defined.
|
||||
|
||||
if test ${ac_cv_sizeof_speed_t} -lt 2; then
|
||||
AC_DEFINE([HAVE_TINY_SPEED_T], [1],
|
||||
[Define to 1 if speed_t has some sort of nonsensically tiny size.])
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_CACHE_CHECK([for usable FIONREAD], [emacs_cv_usable_FIONREAD],
|
||||
[case $opsys in
|
||||
aix4-2 | nacl)
|
||||
|
@ -5451,6 +5624,22 @@ if test $emacs_cv_usable_FIONREAD = yes; then
|
|||
AC_DEFINE([USABLE_SIGIO], [1], [Define to 1 if SIGIO is usable.])
|
||||
fi
|
||||
fi
|
||||
|
||||
if test $emacs_broken_SIGIO = no && test $emacs_cv_usable_SIGIO = no; then
|
||||
AC_CACHE_CHECK([for usable SIGPOLL], [emacs_cv_usable_SIGPOLL],
|
||||
[AC_COMPILE_IFELSE(
|
||||
[AC_LANG_PROGRAM([[#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
]],
|
||||
[[int foo = SIGPOLL | F_SETFL;]])],
|
||||
[emacs_cv_usable_SIGPOLL=yes],
|
||||
[emacs_cv_usable_SIGPOLL=no])],
|
||||
[emacs_cv_usable_SIGPOLL=yes],
|
||||
[emacs_cv_usable_SIGPOLL=no])
|
||||
if test $emacs_cv_usable_SIGPOLL = yes; then
|
||||
AC_DEFINE([USABLE_SIGPOLL], [1], [Define to 1 if SIGPOLL is usable but SIGIO is not.])
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
case $opsys in
|
||||
|
@ -5563,6 +5752,17 @@ if test "${HAVE_X_WINDOWS}" = "yes" ; then
|
|||
FONT_OBJ="$FONT_OBJ ftfont.o"
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "${HAVE_BE_APP}" = "yes" ; then
|
||||
if test "${HAVE_FREETYPE}" = "yes" || \
|
||||
test "${HAVE_CAIRO}" = "yes"; then
|
||||
FONT_OBJ="$FONT_OBJ ftfont.o"
|
||||
fi
|
||||
if test "${HAVE_CAIRO}" = "yes"; then
|
||||
FONT_OBJ="$FONT_OBJ ftcrfont.o"
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "${HAVE_HARFBUZZ}" = "yes" ; then
|
||||
FONT_OBJ="$FONT_OBJ hbfont.o"
|
||||
fi
|
||||
|
@ -5951,7 +6151,7 @@ Configured for '${canonical}'.
|
|||
#### Please respect alphabetical ordering when making additions.
|
||||
optsep=
|
||||
emacs_config_features=
|
||||
for opt in ACL CAIRO DBUS FREETYPE GCONF GIF GLIB GMP GNUTLS GPM GSETTINGS \
|
||||
for opt in ACL BE_APP CAIRO DBUS FREETYPE GCONF GIF GLIB GMP GNUTLS GPM GSETTINGS \
|
||||
HARFBUZZ IMAGEMAGICK JPEG JSON LCMS2 LIBOTF LIBSELINUX LIBSYSTEMD LIBXML2 \
|
||||
M17N_FLT MODULES NATIVE_COMP NOTIFY NS OLDXMENU PDUMPER PNG RSVG SECCOMP \
|
||||
SOUND THREADS TIFF TOOLKIT_SCROLL_BARS \
|
||||
|
|
|
@ -140,6 +140,7 @@ EMACSSOURCES= \
|
|||
${srcdir}/xresources.texi \
|
||||
${srcdir}/anti.texi \
|
||||
${srcdir}/macos.texi \
|
||||
$(srcdir)/haiku.texi \
|
||||
${srcdir}/msdos.texi \
|
||||
${srcdir}/gnu.texi \
|
||||
${srcdir}/glossary.texi \
|
||||
|
|
|
@ -221,6 +221,7 @@ Appendices
|
|||
* X Resources:: X resources for customizing Emacs.
|
||||
* Antinews:: Information about Emacs version 27.
|
||||
* Mac OS / GNUstep:: Using Emacs under macOS and GNUstep.
|
||||
* Haiku:: Using Emacs on Haiku.
|
||||
* Microsoft Windows:: Using Emacs on Microsoft Windows and MS-DOS.
|
||||
* Manifesto:: What's GNU? Gnu's Not Unix!
|
||||
|
||||
|
@ -1249,6 +1250,11 @@ Emacs and macOS / GNUstep
|
|||
* Mac / GNUstep Events:: How window system events are handled.
|
||||
* GNUstep Support:: Details on status of GNUstep support.
|
||||
|
||||
Emacs and Haiku
|
||||
|
||||
* Haiku Basics:: Basic Emacs usage and installation under Haiku.
|
||||
* Haiku Fonts:: The various options for displaying fonts on Haiku.
|
||||
|
||||
Emacs and Microsoft Windows/MS-DOS
|
||||
|
||||
* Windows Startup:: How to start Emacs on Windows.
|
||||
|
@ -1618,6 +1624,7 @@ Lisp programming.
|
|||
|
||||
@include anti.texi
|
||||
@include macos.texi
|
||||
@include haiku.texi
|
||||
@c Includes msdos-xtra.
|
||||
@include msdos.texi
|
||||
@include gnu.texi
|
||||
|
|
136
doc/emacs/haiku.texi
Normal file
136
doc/emacs/haiku.texi
Normal file
|
@ -0,0 +1,136 @@
|
|||
@c This is part of the Emacs manual.
|
||||
@c Copyright (C) 2021 Free Software Foundation, Inc.
|
||||
@c See file emacs.texi for copying conditions.
|
||||
@node Haiku
|
||||
@appendix Emacs and Haiku
|
||||
@cindex Haiku
|
||||
|
||||
Haiku is a Unix-like operating system that originated as a
|
||||
re-implementation of the operating system BeOS.
|
||||
|
||||
This section describes the peculiarities of using Emacs built with
|
||||
the Application Kit, the windowing system native to Haiku. The
|
||||
oddities described here do not apply to using Emacs on Haiku built
|
||||
without windowing support, or built with X11.
|
||||
|
||||
@menu
|
||||
* Haiku Basics:: Basic Emacs usage and installation under Haiku.
|
||||
* Haiku Fonts:: The various options for displaying fonts on Haiku.
|
||||
@end menu
|
||||
|
||||
@node Haiku Basics
|
||||
@section Installation and usage peculiarities under Haiku
|
||||
@cindex haiku application
|
||||
@cindex haiku installation
|
||||
|
||||
Emacs installs two separate executables under Haiku; it is up to the
|
||||
user to decide which one suits him best: A regular executable, with
|
||||
the lowercase name @code{emacs}, and a binary containing
|
||||
Haiku-specific application metadata, with the name @code{Emacs}.
|
||||
|
||||
@cindex launching Emacs from the tracker
|
||||
@cindex tty Emacs in haiku
|
||||
If you are launching Emacs from the Tracker, or want to make the
|
||||
Tracker open files using Emacs, you should use the binary named
|
||||
@code{Emacs}; ff you are going to use Emacs in the terminal, or wish
|
||||
to launch separate instances of Emacs, or do not care for the
|
||||
aforementioned system integration features, use the binary named
|
||||
@code{emacs} instead.
|
||||
|
||||
@cindex modifier keys and system keymap (Haiku)
|
||||
@cindex haiku keymap
|
||||
On Haiku, unusual modifier keys such as the Hyper key are
|
||||
unsupported. By default, the super key corresponds with the option
|
||||
key defined by the operating system, the meta key with the command
|
||||
key, the control key with the system control key, and the shift key
|
||||
with the system shift key. On a standard PC keyboard, Haiku should
|
||||
map these keys to positions familiar to those using a GNU system, but
|
||||
this may require some adjustment to your system's configuration to
|
||||
work.
|
||||
|
||||
It is impossible to type accented characters using the system super
|
||||
key map.
|
||||
|
||||
You can customize the correspondence between modifier keys known to
|
||||
the system, and those known to Emacs. The variables that allow for
|
||||
that are described below.
|
||||
|
||||
@cindex modifier key customization (Haiku)
|
||||
You can customize which Emacs modifiers the various system modifier
|
||||
keys correspond to through the following variables:
|
||||
|
||||
@table @code
|
||||
@vindex haiku-meta-keysym
|
||||
@item haiku-meta-keysym
|
||||
The system modifier key that will be treated as the Meta key by Emacs.
|
||||
It defaults to @code{command}.
|
||||
|
||||
@vindex haiku-control-keysym
|
||||
@item haiku-control-keysym
|
||||
The system modifier key that will be treated as the Control key by
|
||||
Emacs. It defaults to @code{control}.
|
||||
|
||||
@vindex haiku-super-keysym
|
||||
@item haiku-super-keysym
|
||||
The system modifier key that will be treated as the Super key by
|
||||
Emacs. It defaults to @code{option}.
|
||||
|
||||
@vindex haiku-shift-keysym
|
||||
@item haiku-shift-keysym
|
||||
The system modifier key that will be treated as the Shift key by
|
||||
Emacs. It defaults to @code{shift}.
|
||||
@end table
|
||||
|
||||
The value of each variable can be one of the symbols @code{command},
|
||||
@code{control}, @code{option}, @code{shift}, or @code{nil}.
|
||||
@code{nil} or any other value will cause the default value to be used
|
||||
instead.
|
||||
|
||||
@cindex tooltips (haiku)
|
||||
@cindex haiku tooltips
|
||||
@vindex haiku-use-system-tooltips
|
||||
On Haiku, Emacs defaults to using the system tooltip mechanism.
|
||||
This usually leads to more responsive tooltips, but the tooltips will
|
||||
not be able to display text properties or faces. If you need those
|
||||
features, customize the variable @code{haiku-use-system-tooltips} to
|
||||
the nil value, and Emacs will use its own implementation of tooltips.
|
||||
|
||||
Both system tooltips and Emacs's own tooltips cannot display above
|
||||
the menu bar, so help text in the menu bar will display in the echo
|
||||
area instead.
|
||||
|
||||
@subsection What to do when Emacs crashes
|
||||
@cindex crashes, Haiku
|
||||
@cindex haiku debugger
|
||||
@vindex haiku-debug-on-fatal-error
|
||||
If the variable @code{haiku-debug-on-fatal-error} is non-nil, Emacs
|
||||
will launch the system debugger when a fatal signal is received. It
|
||||
defaults to @code{t}. If GDB cannot be used on your system, please
|
||||
attach the report generated by the system debugger when reporting a
|
||||
bug.
|
||||
|
||||
@table @code
|
||||
@vindex haiku-use-system-debugger
|
||||
@item haiku-use-system-debugger
|
||||
When non-nil, Emacs will ask the system to launch the system debugger
|
||||
whenever it experiences a fatal error. This behaviour is standard
|
||||
among Haiku applications.
|
||||
@end table
|
||||
|
||||
@node Haiku Fonts
|
||||
@section Font and font backend selection on Haiku
|
||||
@cindex font backend selection (Haiku)
|
||||
|
||||
Emacs, when built with Haiku windowing support, can be built with
|
||||
several different font backends. You can specify font backends by
|
||||
specifying @kbd{-xrm Emacs.fontBackend:BACKEND} on the command line
|
||||
used to invoke Emacs, where @kbd{BACKEND} is one of the backends
|
||||
specified below, or on a per-frame basis by changing the
|
||||
@code{font-backend} frame parameter. (@pxref{Parameter Access,,,
|
||||
elisp, The Emacs Lisp Reference Manual}).
|
||||
|
||||
Two of these backends, @code{ftcr} and @code{ftcrhb} are identical
|
||||
to their counterparts on the X Window System. There is also a
|
||||
Haiku-specific backend named @code{haiku}, that uses the App Server to
|
||||
draw fonts, but does not at present support display of color font and
|
||||
emoji.
|
|
@ -2767,8 +2767,9 @@ apply to. Here are the possible values of @var{characteristic}:
|
|||
@item type
|
||||
The kind of window system the terminal uses---either @code{graphic}
|
||||
(any graphics-capable display), @code{x}, @code{pc} (for the MS-DOS
|
||||
console), @code{w32} (for MS Windows 9X/NT/2K/XP), or @code{tty} (a
|
||||
non-graphics-capable display). @xref{Window Systems, window-system}.
|
||||
console), @code{w32} (for MS Windows 9X/NT/2K/XP), @code{haiku} (for
|
||||
Haiku), or @code{tty} (a non-graphics-capable display).
|
||||
@xref{Window Systems, window-system}.
|
||||
|
||||
@item class
|
||||
What kinds of colors the terminal supports---either @code{color},
|
||||
|
@ -8274,6 +8275,8 @@ Emacs is displaying the frame using the Nextstep interface (used on
|
|||
GNUstep and macOS).
|
||||
@item pc
|
||||
Emacs is displaying the frame using MS-DOS direct screen writes.
|
||||
@item haiku
|
||||
Emacs is displaying the frame using the Application Kit on Haiku.
|
||||
@item nil
|
||||
Emacs is displaying the frame on a character-based terminal.
|
||||
@end table
|
||||
|
@ -8320,6 +8323,7 @@ area. On text-mode (a.k.a.@: ``TTY'') frames, tooltips are always
|
|||
displayed in the echo area.
|
||||
@end defun
|
||||
|
||||
@cindex system tooltips
|
||||
@vindex x-gtk-use-system-tooltips
|
||||
When Emacs is built with GTK+ support, it by default displays tooltips
|
||||
using GTK+ functions, and the appearance of the tooltips is then
|
||||
|
|
|
@ -214,7 +214,8 @@ The terminal and keyboard coding systems used on the terminal.
|
|||
@item
|
||||
The kind of display associated with the terminal. This is the symbol
|
||||
returned by the function @code{terminal-live-p} (i.e., @code{x},
|
||||
@code{t}, @code{w32}, @code{ns}, or @code{pc}). @xref{Frames}.
|
||||
@code{t}, @code{w32}, @code{ns}, @code{pc}, or @code{haiku}).
|
||||
@xref{Frames}.
|
||||
|
||||
@item
|
||||
A list of terminal parameters. @xref{Terminal Parameters}.
|
||||
|
@ -680,7 +681,7 @@ indicate that position for the various builds:
|
|||
@itemize @w{}
|
||||
@item (1) non-toolkit and terminal frames
|
||||
|
||||
@item (2) Lucid, Motif and MS-Windows frames
|
||||
@item (2) Lucid, Motif, MS-Windows, and Haiku frames
|
||||
|
||||
@item (3) GTK+ and NS frames
|
||||
@end itemize
|
||||
|
@ -1729,7 +1730,9 @@ fit will be clipped by the window manager.
|
|||
@item fullscreen
|
||||
This parameter specifies whether to maximize the frame's width, height
|
||||
or both. Its value can be @code{fullwidth}, @code{fullheight},
|
||||
@code{fullboth}, or @code{maximized}. A @dfn{fullwidth} frame is as
|
||||
@code{fullboth}, or @code{maximized}.@footnote{On Haiku, setting
|
||||
@code{fullscreen} to @code{fullwidth} or @code{fullheight} has no
|
||||
effect.} A @dfn{fullwidth} frame is as
|
||||
wide as possible, a @dfn{fullheight} frame is as tall as possible, and
|
||||
a @dfn{fullboth} frame is both as wide and as tall as possible. A
|
||||
@dfn{maximized} frame is like a ``fullboth'' frame, except that it usually
|
||||
|
@ -2191,7 +2194,10 @@ either via @code{focus-follows-mouse} (@pxref{Input Focus}) or
|
|||
@code{mouse-autoselect-window} (@pxref{Mouse Window Auto-selection}).
|
||||
This may have the unwanted side-effect that a user cannot scroll a
|
||||
non-selected frame with the mouse. Some window managers may not honor
|
||||
this parameter.
|
||||
this parameter. On Haiku, it also has the side-effect that the window
|
||||
will not be able to receive any keyboard input from the user, not even
|
||||
if the user switches to the frame using the key combination
|
||||
@kbd{Alt-@key{TAB}}.
|
||||
|
||||
@vindex undecorated@r{, a frame parameter}
|
||||
@item undecorated
|
||||
|
@ -2352,7 +2358,10 @@ driver for OTF and TTF fonts with text shaping by the Uniscribe
|
|||
engine), and @code{harfbuzz} (font driver for OTF and TTF fonts with
|
||||
HarfBuzz text shaping) (@pxref{Windows Fonts,,, emacs, The GNU Emacs
|
||||
Manual}). The @code{harfbuzz} driver is similarly recommended. On
|
||||
other systems, there is only one available font backend, so it does
|
||||
Haiku, there can be several font drivers (@pxref{Haiku Fonts,,, emacs,
|
||||
The GNU Emacs Manual}).
|
||||
|
||||
On other systems, there is only one available font backend, so it does
|
||||
not make sense to modify this frame parameter.
|
||||
|
||||
@vindex background-mode@r{, a frame parameter}
|
||||
|
@ -3141,8 +3150,10 @@ raises @var{frame} above all other child frames of its parent.
|
|||
@deffn Command lower-frame &optional frame
|
||||
This function lowers frame @var{frame} (default, the selected frame)
|
||||
below all other frames belonging to the same or a higher z-group as
|
||||
@var{frame}. If @var{frame} is a child frame (@pxref{Child Frames}),
|
||||
this lowers @var{frame} below all other child frames of its parent.
|
||||
@var{frame}.@footnote{Lowering frames is not supported on Haiku, due
|
||||
to limitations imposed by the system.} If @var{frame} is a child
|
||||
frame (@pxref{Child Frames}), this lowers @var{frame} below all other
|
||||
child frames of its parent.
|
||||
@end deffn
|
||||
|
||||
@defun frame-restack frame1 frame2 &optional above
|
||||
|
@ -3152,7 +3163,8 @@ that if both frames are visible and their display areas overlap,
|
|||
third argument @var{above} is non-@code{nil}, this function restacks
|
||||
@var{frame1} above @var{frame2}. This means that if both frames are
|
||||
visible and their display areas overlap, @var{frame1} will (partially)
|
||||
obscure @var{frame2}.
|
||||
obscure @var{frame2}.@footnote{Restacking frames is not supported on
|
||||
Haiku, due to limitations imposed by the system.}
|
||||
|
||||
Technically, this function may be thought of as an atomic action
|
||||
performed in two steps: The first step removes @var{frame1}'s
|
||||
|
@ -3247,12 +3259,16 @@ parent frame's window-system window.
|
|||
|
||||
@cindex reparent frame
|
||||
@cindex nest frame
|
||||
The @code{parent-frame} parameter can be changed at any time. Setting
|
||||
it to another frame @dfn{reparents} the child frame. Setting it to
|
||||
another child frame makes the frame a @dfn{nested} child frame. Setting
|
||||
it to @code{nil} restores the frame's status as a top-level frame---a
|
||||
frame whose window-system window is a child of its display's root
|
||||
window.
|
||||
The @code{parent-frame} parameter can be changed at any time.
|
||||
Setting it to another frame @dfn{reparents} the child frame. Setting
|
||||
it to another child frame makes the frame a @dfn{nested} child frame.
|
||||
Setting it to @code{nil} restores the frame's status as a top-level
|
||||
frame---a frame whose window-system window is a child of its display's
|
||||
root window.@footnote{On Haiku, child frames are only visible when a
|
||||
parent frame is active, owing to a limitation of the Haiku windowing
|
||||
system. Owing to the same limitation, child frames are only
|
||||
guaranteed to appear above their top-level parent; that is to say, the
|
||||
top-most frame in the hierarchy, which does not have a parent frame.}
|
||||
|
||||
Since child frames can be arbitrarily nested, a frame can be both a
|
||||
child and a parent frame. Also, the relative roles of child and parent
|
||||
|
|
|
@ -947,6 +947,9 @@ actually Linux is just the kernel, not the whole system.)
|
|||
@item gnu/kfreebsd
|
||||
A GNU (glibc-based) system with a FreeBSD kernel.
|
||||
|
||||
@item haiku
|
||||
The Haiku operating system, a derivative of the Be Operating System.
|
||||
|
||||
@item hpux
|
||||
Hewlett-Packard HPUX operating system.
|
||||
|
||||
|
|
28
etc/MACHINES
28
etc/MACHINES
|
@ -103,6 +103,34 @@ the list at the end of this file.
|
|||
./configure CC='gcc -m64' # GCC
|
||||
./configure CC='cc -m64' # Oracle Developer Studio
|
||||
|
||||
** Haiku
|
||||
|
||||
On 32-bit Haiku it is required that the newer GCC 8 be used, instead
|
||||
of the legacy GCC 2 used by default. This can be achieved by
|
||||
invoking configure inside a shell launched by the 'setarch' program
|
||||
invoked as 'setarch x86'.
|
||||
|
||||
When building with packages discovered through pkg-config, such as
|
||||
libpng, on a GCC 2/GCC 8 hybrid system, simply evaluating 'setarch
|
||||
x86' is insufficient to ensure that all required libraries are found
|
||||
at their correct locations. To avoid this problem, set the
|
||||
environment variable 'PKG_CONFIG_PATH' to the GCC 8 pkg-config
|
||||
directory at '/system/develop/lib/x86/pkgconfig/' before configuring
|
||||
Emacs.
|
||||
|
||||
If GCC complains about not being able to resolve symbols such as
|
||||
"BHandler::LockLooper", you are almost certainly experiencing this
|
||||
problem.
|
||||
|
||||
Haiku running on non-x86 systems has not been tested. It is
|
||||
anticipated that Haiku running on big-endian systems will experience
|
||||
problems when Emacs is built with Haiku windowing support, but there
|
||||
doesn't seem to be any reliable way to get Haiku running on a
|
||||
big-endian system at present.
|
||||
|
||||
The earliest release of Haiku that will successfully compile Emacs
|
||||
is R1/Beta2. For windowing support, R1/Beta3 or later is required.
|
||||
|
||||
|
||||
* Obsolete platforms
|
||||
|
||||
|
|
21
etc/NEWS
21
etc/NEWS
|
@ -24,6 +24,27 @@ applies, and please also update docstrings as needed.
|
|||
|
||||
* Installation Changes in Emacs 29.1
|
||||
|
||||
** Emacs has been ported to the Haiku operating system.
|
||||
The configuration process should automatically detect and build for
|
||||
Haiku. There is also an optional window-system port to Haiku, which
|
||||
can be enabled by configuring Emacs with the option '--with-be-app',
|
||||
which will require the Haiku Application Kit development headers and a
|
||||
C++ compiler to be present on your system. If Emacs is not built with
|
||||
the option '--with-be-app', the resulting Emacs will only run in
|
||||
text-mode terminals.
|
||||
|
||||
+++
|
||||
*** Cairo drawing support has been enabled for Haiku builds.
|
||||
To enable Cairo support, ensure that the Cairo and FreeType
|
||||
development files are present on your system, and configure Emacs with
|
||||
'--with-be-cairo'.
|
||||
|
||||
---
|
||||
*** Double buffering is now enabled on the Haiku operating system.
|
||||
Unlike X, there is no compile-time option to enable or disable
|
||||
double-buffering. If you wish to disable double-buffering, change the
|
||||
frame parameter `inhibit-double-buffering' instead.
|
||||
|
||||
** Emacs now installs the ".pdmp" file using a unique fingerprint in the name.
|
||||
The file is typically installed using a file name akin to
|
||||
"...dir/libexec/emacs/29.1/x86_64-pc-linux-gnu/emacs-<fingerprint>.pdmp".
|
||||
|
|
16
etc/PROBLEMS
16
etc/PROBLEMS
|
@ -1022,6 +1022,15 @@ modern fonts are used, such as Noto Emoji or Ebrima.
|
|||
The solution is to switch to a configuration that uses HarfBuzz as its
|
||||
shaping engine, where these problems don't exist.
|
||||
|
||||
** On Haiku, some proportionally-spaced fonts display with artifacting.
|
||||
|
||||
This is a Haiku bug: https://dev.haiku-os.org/ticket/17229, which can
|
||||
be remedied by using a different font that does not exhibit this
|
||||
problem, or by configuring Emacs '--with-be-cairo'.
|
||||
|
||||
So far, Bitstream Charter and Noto Sans have been known to exhibit
|
||||
this problem, while Noto Sans Display is known to not do so.
|
||||
|
||||
* Internationalization problems
|
||||
|
||||
** M-{ does not work on a Spanish PC keyboard.
|
||||
|
@ -1105,6 +1114,13 @@ In your ~/.Xresources file, then run
|
|||
|
||||
And restart Emacs.
|
||||
|
||||
** On Haiku, BeCJK doesn't work properly with Emacs
|
||||
|
||||
Some popular Haiku input methods such BeCJK are known to behave badly
|
||||
when interacting with Emacs, in ways such as stealing input focus and
|
||||
displaying popup windows that don't disappear. If you are affected,
|
||||
you should use an Emacs input method instead.
|
||||
|
||||
* X runtime problems
|
||||
|
||||
** X keyboard problems
|
||||
|
|
|
@ -27,7 +27,9 @@ EMACSOPT = -batch --no-site-file --no-site-lisp
|
|||
# ==================== Things 'configure' will edit ====================
|
||||
|
||||
CC=@CC@
|
||||
CXX=@CXX@
|
||||
CFLAGS=@CFLAGS@
|
||||
CXXFLAGS=@CXXFLAGS@
|
||||
CPPFLAGS = @CPPFLAGS@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
|
||||
|
@ -130,6 +132,11 @@ MKDIR_P = @MKDIR_P@
|
|||
|
||||
# ========================== Lists of Files ===========================
|
||||
|
||||
## Haiku build-time support
|
||||
HAVE_BE_APP=@HAVE_BE_APP@
|
||||
HAIKU_LIBS=@HAIKU_LIBS@
|
||||
HAIKU_CFLAGS=@HAIKU_CFLAGS@
|
||||
|
||||
# emacsclientw.exe for MinGW, empty otherwise
|
||||
CLIENTW = @CLIENTW@
|
||||
|
||||
|
@ -143,7 +150,11 @@ UTILITIES = hexl${EXEEXT} \
|
|||
$(if $(with_mailutils), , movemail${EXEEXT}) \
|
||||
$(and $(use_gamedir), update-game-score${EXEEXT})
|
||||
|
||||
ifeq ($(HAVE_BE_APP),yes)
|
||||
DONT_INSTALL= make-docfile${EXEEXT} make-fingerprint${EXEEXT} be-resources
|
||||
else
|
||||
DONT_INSTALL= make-docfile${EXEEXT} make-fingerprint${EXEEXT}
|
||||
endif
|
||||
|
||||
# Like UTILITIES, but they're not system-dependent, and should not be
|
||||
# deleted by the distclean target.
|
||||
|
@ -230,6 +241,10 @@ WINDRES = @WINDRES@
|
|||
## Some systems define this to request special libraries.
|
||||
LIBS_SYSTEM = @LIBS_SYSTEM@
|
||||
|
||||
# Flags that could be in WARN_CFLAGS, but are invalid for C++.
|
||||
NON_CXX_CFLAGS = -Wmissing-prototypes -Wnested-externs -Wold-style-definition \
|
||||
-Wstrict-prototypes -Wno-override-init
|
||||
|
||||
BASE_CFLAGS = $(C_SWITCH_SYSTEM) $(C_SWITCH_MACHINE) \
|
||||
$(WARN_CFLAGS) $(WERROR_CFLAGS) \
|
||||
-I. -I../src -I../lib \
|
||||
|
@ -238,6 +253,9 @@ BASE_CFLAGS = $(C_SWITCH_SYSTEM) $(C_SWITCH_MACHINE) \
|
|||
ALL_CFLAGS = ${BASE_CFLAGS} ${PROFILING_CFLAGS} ${LDFLAGS} ${CPPFLAGS} ${CFLAGS}
|
||||
CPP_CFLAGS = ${BASE_CFLAGS} ${PROFILING_CFLAGS} ${CPPFLAGS} ${CFLAGS}
|
||||
|
||||
ALL_CXXFLAGS = $(filter-out ${NON_CXX_CFLAGS},${BASE_CFLAGS}) \
|
||||
${PROFILING_CFLAGS} ${LDFLAGS} ${CPPFLAGS} ${CFLAGS} ${CXXFLAGS} ${HAIKU_CFLAGS}
|
||||
|
||||
# Configuration files for .o files to depend on.
|
||||
config_h = ../src/config.h $(srcdir)/../src/conf_post.h
|
||||
|
||||
|
@ -407,6 +425,9 @@ emacsclientw${EXEEXT}: ${srcdir}/emacsclient.c $(NTLIB) $(CLIENTRES) $(config_h)
|
|||
$(LOADLIBES) \
|
||||
$(LIB_WSOCK32) $(LIB_EACCESS) $(LIBS_ECLIENT) -o $@
|
||||
|
||||
be-resources: ${srcdir}/be_resources.cc ${config_h}
|
||||
$(AM_V_CXXLD)$(CXX) ${ALL_CXXFLAGS} ${HAIKU_LIBS} $< -o $@
|
||||
|
||||
NTINC = ${srcdir}/../nt/inc
|
||||
NTDEPS = $(NTINC)/ms-w32.h $(NTINC)/sys/stat.h $(NTINC)/inttypes.h \
|
||||
$(NTINC)/stdint.h $(NTINC)/pwd.h $(NTINC)/sys/time.h $(NTINC)/stdbool.h \
|
||||
|
|
144
lib-src/be_resources.cc
Normal file
144
lib-src/be_resources.cc
Normal file
|
@ -0,0 +1,144 @@
|
|||
/* Haiku window system support
|
||||
Copyright (C) 2021 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Emacs.
|
||||
|
||||
GNU Emacs 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.
|
||||
|
||||
GNU Emacs 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 GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
#include <SupportDefs.h>
|
||||
#include <Path.h>
|
||||
#include <AppFileInfo.h>
|
||||
#include <TranslationUtils.h>
|
||||
#include <Application.h>
|
||||
#include <Catalog.h>
|
||||
#include <Roster.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
static void
|
||||
be_perror (status_t code, char *arg)
|
||||
{
|
||||
if (code != B_OK)
|
||||
{
|
||||
switch (code)
|
||||
{
|
||||
case B_BAD_VALUE:
|
||||
fprintf (stderr, "%s: Bad value\n", arg);
|
||||
break;
|
||||
case B_ENTRY_NOT_FOUND:
|
||||
fprintf (stderr, "%s: Not found\n", arg);
|
||||
break;
|
||||
case B_PERMISSION_DENIED:
|
||||
fprintf (stderr, "%s: Permission denied\n", arg);
|
||||
break;
|
||||
case B_NO_MEMORY:
|
||||
fprintf (stderr, "%s: No memory\n", arg);
|
||||
break;
|
||||
case B_LINK_LIMIT:
|
||||
fprintf (stderr, "%s: Link limit reached\n", arg);
|
||||
break;
|
||||
case B_BUSY:
|
||||
fprintf (stderr, "%s: Busy\n", arg);
|
||||
break;
|
||||
case B_NO_MORE_FDS:
|
||||
fprintf (stderr, "%s: No more file descriptors\n", arg);
|
||||
break;
|
||||
case B_FILE_ERROR:
|
||||
fprintf (stderr, "%s: File error\n", arg);
|
||||
break;
|
||||
default:
|
||||
fprintf (stderr, "%s: Unknown error\n", arg);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
abort ();
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
BApplication app ("application/x-vnd.GNU-emacs-resource-helper");
|
||||
BFile file;
|
||||
BBitmap *icon;
|
||||
BAppFileInfo info;
|
||||
status_t code;
|
||||
struct version_info vinfo;
|
||||
char *v = strdup (PACKAGE_VERSION);
|
||||
|
||||
if (argc != 3)
|
||||
{
|
||||
printf ("be-resources ICON FILE: make FILE appropriate for Emacs.\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
code = file.SetTo (argv[2], B_READ_WRITE);
|
||||
if (code != B_OK)
|
||||
{
|
||||
be_perror (code, argv[2]);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
code = info.SetTo (&file);
|
||||
if (code != B_OK)
|
||||
{
|
||||
be_perror (code, argv[2]);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
code = info.SetAppFlags (B_EXCLUSIVE_LAUNCH | B_ARGV_ONLY);
|
||||
if (code != B_OK)
|
||||
{
|
||||
be_perror (code, argv[2]);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
icon = BTranslationUtils::GetBitmapFile (argv[1], NULL);
|
||||
|
||||
if (!icon)
|
||||
{
|
||||
be_perror (B_ERROR, argv[1]);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
info.SetIcon (icon, B_MINI_ICON);
|
||||
info.SetIcon (icon, B_LARGE_ICON);
|
||||
info.SetSignature ("application/x-vnd.GNU-emacs");
|
||||
|
||||
v = strtok (v, ".");
|
||||
vinfo.major = atoi (v);
|
||||
|
||||
v = strtok (NULL, ".");
|
||||
vinfo.middle = atoi (v);
|
||||
|
||||
v = strtok (NULL, ".");
|
||||
vinfo.minor = v ? atoi (v) : 0;
|
||||
|
||||
vinfo.variety = 0;
|
||||
vinfo.internal = 0;
|
||||
|
||||
strncpy ((char *) &vinfo.short_info, PACKAGE_VERSION,
|
||||
sizeof vinfo.short_info - 1);
|
||||
strncpy ((char *) &vinfo.long_info, PACKAGE_STRING,
|
||||
sizeof vinfo.long_info - 1);
|
||||
|
||||
info.SetVersionInfo (&vinfo, B_APP_VERSION_KIND);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
|
@ -603,6 +603,8 @@ decode_options (int argc, char **argv)
|
|||
alt_display = "ns";
|
||||
#elif defined (HAVE_NTGUI)
|
||||
alt_display = "w32";
|
||||
#elif defined (HAVE_HAIKU)
|
||||
alt_display = "be";
|
||||
#endif
|
||||
|
||||
display = egetenv ("DISPLAY");
|
||||
|
|
|
@ -2176,7 +2176,7 @@ and `face'."
|
|||
;;; The `custom' Widget.
|
||||
|
||||
(defface custom-button
|
||||
'((((type x w32 ns) (class color)) ; Like default mode line
|
||||
'((((type x w32 ns haiku) (class color)) ; Like default mode line
|
||||
:box (:line-width 2 :style released-button)
|
||||
:background "lightgrey" :foreground "black"))
|
||||
"Face for custom buffer buttons if `custom-raised-buttons' is non-nil."
|
||||
|
@ -2184,7 +2184,7 @@ and `face'."
|
|||
:group 'custom-faces)
|
||||
|
||||
(defface custom-button-mouse
|
||||
'((((type x w32 ns) (class color))
|
||||
'((((type x w32 ns haiku) (class color))
|
||||
:box (:line-width 2 :style released-button)
|
||||
:background "grey90" :foreground "black")
|
||||
(t
|
||||
|
@ -2209,7 +2209,7 @@ and `face'."
|
|||
(if custom-raised-buttons 'custom-button-mouse 'highlight))
|
||||
|
||||
(defface custom-button-pressed
|
||||
'((((type x w32 ns) (class color))
|
||||
'((((type x w32 ns haiku) (class color))
|
||||
:box (:line-width 2 :style pressed-button)
|
||||
:background "lightgrey" :foreground "black")
|
||||
(t :inverse-video t))
|
||||
|
|
|
@ -829,7 +829,11 @@ since it could result in memory overflow and make Emacs crash."
|
|||
;; xselect.c
|
||||
(x-select-enable-clipboard-manager killing boolean "24.1")
|
||||
;; xsettings.c
|
||||
(font-use-system-font font-selection boolean "23.2")))
|
||||
(font-use-system-font font-selection boolean "23.2")
|
||||
;; haikuterm.c
|
||||
(haiku-debug-on-fatal-error debug boolean "29.1")
|
||||
;; haikufns.c
|
||||
(haiku-use-system-tooltips tooltip boolean "29.1")))
|
||||
(setq ;; If we did not specify any standard value expression above,
|
||||
;; use the current value as the standard value.
|
||||
standard (if (setq prop (memq :standard rest))
|
||||
|
@ -846,6 +850,8 @@ since it could result in memory overflow and make Emacs crash."
|
|||
(eq system-type 'windows-nt))
|
||||
((string-match "\\`ns-" (symbol-name symbol))
|
||||
(featurep 'ns))
|
||||
((string-match "\\`haiku-" (symbol-name symbol))
|
||||
(featurep 'haiku))
|
||||
((string-match "\\`x-.*gtk" (symbol-name symbol))
|
||||
(featurep 'gtk))
|
||||
((string-match "clipboard-manager" (symbol-name symbol))
|
||||
|
|
|
@ -1172,7 +1172,7 @@ an integer value."
|
|||
(:height
|
||||
'integerp)
|
||||
(:stipple
|
||||
(and (memq (window-system frame) '(x ns)) ; No stipple on w32
|
||||
(and (memq (window-system frame) '(x ns)) ; No stipple on w32 or haiku
|
||||
(mapcar #'list
|
||||
(apply #'nconc
|
||||
(mapcar (lambda (dir)
|
||||
|
@ -2822,7 +2822,7 @@ Note: Other faces cannot inherit from the cursor face."
|
|||
'((default
|
||||
:box (:line-width 1 :style released-button)
|
||||
:foreground "black")
|
||||
(((type x w32 ns) (class color))
|
||||
(((type x w32 ns haiku) (class color))
|
||||
:background "grey75")
|
||||
(((type x) (class mono))
|
||||
:background "grey"))
|
||||
|
|
|
@ -1633,6 +1633,7 @@ live frame and defaults to the selected one."
|
|||
(declare-function x-frame-geometry "xfns.c" (&optional frame))
|
||||
(declare-function w32-frame-geometry "w32fns.c" (&optional frame))
|
||||
(declare-function ns-frame-geometry "nsfns.m" (&optional frame))
|
||||
(declare-function haiku-frame-geometry "haikufns.c" (&optional frame))
|
||||
|
||||
(defun frame-geometry (&optional frame)
|
||||
"Return geometric attributes of FRAME.
|
||||
|
@ -1682,6 +1683,8 @@ and width values are in pixels.
|
|||
(w32-frame-geometry frame))
|
||||
((eq frame-type 'ns)
|
||||
(ns-frame-geometry frame))
|
||||
((eq frame-type 'haiku)
|
||||
(haiku-frame-geometry frame))
|
||||
(t
|
||||
(list
|
||||
'(outer-position 0 . 0)
|
||||
|
@ -1806,6 +1809,7 @@ of frames like calls to map a frame or change its visibility."
|
|||
(declare-function x-frame-edges "xfns.c" (&optional frame type))
|
||||
(declare-function w32-frame-edges "w32fns.c" (&optional frame type))
|
||||
(declare-function ns-frame-edges "nsfns.m" (&optional frame type))
|
||||
(declare-function haiku-frame-edges "haikufns.c" (&optional frame type))
|
||||
|
||||
(defun frame-edges (&optional frame type)
|
||||
"Return coordinates of FRAME's edges.
|
||||
|
@ -1829,12 +1833,15 @@ FRAME."
|
|||
(w32-frame-edges frame type))
|
||||
((eq frame-type 'ns)
|
||||
(ns-frame-edges frame type))
|
||||
((eq frame-type 'haiku)
|
||||
(haiku-frame-edges frame type))
|
||||
(t
|
||||
(list 0 0 (frame-width frame) (frame-height frame))))))
|
||||
|
||||
(declare-function w32-mouse-absolute-pixel-position "w32fns.c")
|
||||
(declare-function x-mouse-absolute-pixel-position "xfns.c")
|
||||
(declare-function ns-mouse-absolute-pixel-position "nsfns.m")
|
||||
(declare-function haiku-mouse-absolute-pixel-position "haikufns.c")
|
||||
|
||||
(defun mouse-absolute-pixel-position ()
|
||||
"Return absolute position of mouse cursor in pixels.
|
||||
|
@ -1849,12 +1856,15 @@ position (0, 0) of the selected frame's terminal."
|
|||
(w32-mouse-absolute-pixel-position))
|
||||
((eq frame-type 'ns)
|
||||
(ns-mouse-absolute-pixel-position))
|
||||
((eq frame-type 'haiku)
|
||||
(haiku-mouse-absolute-pixel-position))
|
||||
(t
|
||||
(cons 0 0)))))
|
||||
|
||||
(declare-function ns-set-mouse-absolute-pixel-position "nsfns.m" (x y))
|
||||
(declare-function w32-set-mouse-absolute-pixel-position "w32fns.c" (x y))
|
||||
(declare-function x-set-mouse-absolute-pixel-position "xfns.c" (x y))
|
||||
(declare-function haiku-set-mouse-absolute-pixel-position "haikufns.c" (x y))
|
||||
|
||||
(defun set-mouse-absolute-pixel-position (x y)
|
||||
"Move mouse pointer to absolute pixel position (X, Y).
|
||||
|
@ -1867,7 +1877,9 @@ position (0, 0) of the selected frame's terminal."
|
|||
((eq frame-type 'x)
|
||||
(x-set-mouse-absolute-pixel-position x y))
|
||||
((eq frame-type 'w32)
|
||||
(w32-set-mouse-absolute-pixel-position x y)))))
|
||||
(w32-set-mouse-absolute-pixel-position x y))
|
||||
((eq frame-type 'haiku)
|
||||
(haiku-set-mouse-absolute-pixel-position x y)))))
|
||||
|
||||
(defun frame-monitor-attributes (&optional frame)
|
||||
"Return the attributes of the physical monitor dominating FRAME.
|
||||
|
@ -1960,6 +1972,7 @@ workarea attribute."
|
|||
(declare-function x-frame-list-z-order "xfns.c" (&optional display))
|
||||
(declare-function w32-frame-list-z-order "w32fns.c" (&optional display))
|
||||
(declare-function ns-frame-list-z-order "nsfns.m" (&optional display))
|
||||
(declare-function haiku-frame-list-z-order "haikufns.c" (&optional display))
|
||||
|
||||
(defun frame-list-z-order (&optional display)
|
||||
"Return list of Emacs' frames, in Z (stacking) order.
|
||||
|
@ -1979,7 +1992,9 @@ Return nil if DISPLAY contains no Emacs frame."
|
|||
((eq frame-type 'w32)
|
||||
(w32-frame-list-z-order display))
|
||||
((eq frame-type 'ns)
|
||||
(ns-frame-list-z-order display)))))
|
||||
(ns-frame-list-z-order display))
|
||||
((eq frame-type 'haiku)
|
||||
(haiku-frame-list-z-order display)))))
|
||||
|
||||
(declare-function x-frame-restack "xfns.c" (frame1 frame2 &optional above))
|
||||
(declare-function w32-frame-restack "w32fns.c" (frame1 frame2 &optional above))
|
||||
|
@ -2060,8 +2075,8 @@ frame's display)."
|
|||
((eq frame-type 'w32)
|
||||
(with-no-warnings
|
||||
(> w32-num-mouse-buttons 0)))
|
||||
((memq frame-type '(x ns))
|
||||
t) ;; We assume X and NeXTstep *always* have a pointing device
|
||||
((memq frame-type '(x ns haiku))
|
||||
t) ;; We assume X, NeXTstep and Haiku *always* have a pointing device
|
||||
(t
|
||||
(or (and (featurep 'xt-mouse)
|
||||
xterm-mouse-mode)
|
||||
|
@ -2086,7 +2101,7 @@ frames and several different fonts at once. This is true for displays
|
|||
that use a window system such as X, and false for text-only terminals.
|
||||
DISPLAY can be a display name, a frame, or nil (meaning the selected
|
||||
frame's display)."
|
||||
(not (null (memq (framep-on-display display) '(x w32 ns)))))
|
||||
(not (null (memq (framep-on-display display) '(x w32 ns haiku)))))
|
||||
|
||||
(defun display-images-p (&optional display)
|
||||
"Return non-nil if DISPLAY can display images.
|
||||
|
@ -2137,7 +2152,7 @@ DISPLAY should be either a frame or a display name (a string).
|
|||
If DISPLAY is omitted or nil, it defaults to the selected frame's display."
|
||||
(let ((frame-type (framep-on-display display)))
|
||||
(cond
|
||||
((memq frame-type '(x w32 ns))
|
||||
((memq frame-type '(x w32 ns haiku))
|
||||
(x-display-screens display))
|
||||
(t
|
||||
1))))
|
||||
|
@ -2157,7 +2172,7 @@ with DISPLAY. To get information for each physical monitor, use
|
|||
`display-monitor-attributes-list'."
|
||||
(let ((frame-type (framep-on-display display)))
|
||||
(cond
|
||||
((memq frame-type '(x w32 ns))
|
||||
((memq frame-type '(x w32 ns haiku))
|
||||
(x-display-pixel-height display))
|
||||
(t
|
||||
(frame-height (if (framep display) display (selected-frame)))))))
|
||||
|
@ -2177,7 +2192,7 @@ with DISPLAY. To get information for each physical monitor, use
|
|||
`display-monitor-attributes-list'."
|
||||
(let ((frame-type (framep-on-display display)))
|
||||
(cond
|
||||
((memq frame-type '(x w32 ns))
|
||||
((memq frame-type '(x w32 ns haiku))
|
||||
(x-display-pixel-width display))
|
||||
(t
|
||||
(frame-width (if (framep display) display (selected-frame)))))))
|
||||
|
@ -2215,7 +2230,7 @@ For graphical terminals, note that on \"multi-monitor\" setups this
|
|||
refers to the height in millimeters for all physical monitors
|
||||
associated with DISPLAY. To get information for each physical
|
||||
monitor, use `display-monitor-attributes-list'."
|
||||
(and (memq (framep-on-display display) '(x w32 ns))
|
||||
(and (memq (framep-on-display display) '(x w32 ns haiku))
|
||||
(or (cddr (assoc (or display (frame-parameter nil 'display))
|
||||
display-mm-dimensions-alist))
|
||||
(cddr (assoc t display-mm-dimensions-alist))
|
||||
|
@ -2236,7 +2251,7 @@ For graphical terminals, note that on \"multi-monitor\" setups this
|
|||
refers to the width in millimeters for all physical monitors
|
||||
associated with DISPLAY. To get information for each physical
|
||||
monitor, use `display-monitor-attributes-list'."
|
||||
(and (memq (framep-on-display display) '(x w32 ns))
|
||||
(and (memq (framep-on-display display) '(x w32 ns haiku))
|
||||
(or (cadr (assoc (or display (frame-parameter nil 'display))
|
||||
display-mm-dimensions-alist))
|
||||
(cadr (assoc t display-mm-dimensions-alist))
|
||||
|
@ -2254,7 +2269,7 @@ DISPLAY can be a display name or a frame.
|
|||
If DISPLAY is omitted or nil, it defaults to the selected frame's display."
|
||||
(let ((frame-type (framep-on-display display)))
|
||||
(cond
|
||||
((memq frame-type '(x w32 ns))
|
||||
((memq frame-type '(x w32 ns haiku))
|
||||
(x-display-backing-store display))
|
||||
(t
|
||||
'not-useful))))
|
||||
|
@ -2267,7 +2282,7 @@ DISPLAY can be a display name or a frame.
|
|||
If DISPLAY is omitted or nil, it defaults to the selected frame's display."
|
||||
(let ((frame-type (framep-on-display display)))
|
||||
(cond
|
||||
((memq frame-type '(x w32 ns))
|
||||
((memq frame-type '(x w32 ns haiku))
|
||||
(x-display-save-under display))
|
||||
(t
|
||||
'not-useful))))
|
||||
|
@ -2280,7 +2295,7 @@ DISPLAY can be a display name or a frame.
|
|||
If DISPLAY is omitted or nil, it defaults to the selected frame's display."
|
||||
(let ((frame-type (framep-on-display display)))
|
||||
(cond
|
||||
((memq frame-type '(x w32 ns))
|
||||
((memq frame-type '(x w32 ns haiku))
|
||||
(x-display-planes display))
|
||||
((eq frame-type 'pc)
|
||||
4)
|
||||
|
@ -2295,7 +2310,7 @@ DISPLAY can be a display name or a frame.
|
|||
If DISPLAY is omitted or nil, it defaults to the selected frame's display."
|
||||
(let ((frame-type (framep-on-display display)))
|
||||
(cond
|
||||
((memq frame-type '(x w32 ns))
|
||||
((memq frame-type '(x w32 ns haiku))
|
||||
(x-display-color-cells display))
|
||||
((eq frame-type 'pc)
|
||||
16)
|
||||
|
@ -2312,7 +2327,7 @@ DISPLAY can be a display name or a frame.
|
|||
If DISPLAY is omitted or nil, it defaults to the selected frame's display."
|
||||
(let ((frame-type (framep-on-display display)))
|
||||
(cond
|
||||
((memq frame-type '(x w32 ns))
|
||||
((memq frame-type '(x w32 ns haiku))
|
||||
(x-display-visual-class display))
|
||||
((and (memq frame-type '(pc t))
|
||||
(tty-display-color-p display))
|
||||
|
|
|
@ -88,7 +88,7 @@
|
|||
(bindings--define-key map [separator-3] menu-bar-separator)
|
||||
(bindings--define-key map [set-terminal-coding-system]
|
||||
'(menu-item "For Terminal" set-terminal-coding-system
|
||||
:enable (null (memq initial-window-system '(x w32 ns)))
|
||||
:enable (null (memq initial-window-system '(x w32 ns haiku)))
|
||||
:help "How to encode terminal output"))
|
||||
(bindings--define-key map [set-keyboard-coding-system]
|
||||
'(menu-item "For Keyboard" set-keyboard-coding-system
|
||||
|
|
|
@ -303,6 +303,11 @@
|
|||
(load "term/common-win")
|
||||
(load "term/x-win")))
|
||||
|
||||
(if (featurep 'haiku)
|
||||
(progn
|
||||
(load "term/common-win")
|
||||
(load "term/haiku-win")))
|
||||
|
||||
(if (or (eq system-type 'windows-nt)
|
||||
(featurep 'w32))
|
||||
(progn
|
||||
|
@ -558,6 +563,7 @@ lost after dumping")))
|
|||
(delete-file output)))))
|
||||
;; Recompute NAME now, so that it isn't set when we dump.
|
||||
(if (not (or (eq system-type 'ms-dos)
|
||||
(eq system-type 'haiku) ;; BFS doesn't support hard links
|
||||
;; Don't bother adding another name if we're just
|
||||
;; building bootstrap-emacs.
|
||||
(member dump-mode '("pbootstrap" "bootstrap"))))
|
||||
|
|
|
@ -2540,6 +2540,7 @@ See `menu-bar-mode' for more information."
|
|||
|
||||
(declare-function x-menu-bar-open "term/x-win" (&optional frame))
|
||||
(declare-function w32-menu-bar-open "term/w32-win" (&optional frame))
|
||||
(declare-function haiku-menu-bar-open "haikumenu.c" (&optional frame))
|
||||
|
||||
(defun lookup-key-ignore-too-long (map key)
|
||||
"Call `lookup-key' and convert numeric values to nil."
|
||||
|
@ -2665,9 +2666,10 @@ first TTY menu-bar menu to be dropped down. Interactively,
|
|||
this is the numeric argument to the command.
|
||||
This function decides which method to use to access the menu
|
||||
depending on FRAME's terminal device. On X displays, it calls
|
||||
`x-menu-bar-open'; on Windows, `w32-menu-bar-open'; otherwise it
|
||||
calls either `popup-menu' or `tmm-menubar' depending on whether
|
||||
`tty-menu-open-use-tmm' is nil or not.
|
||||
`x-menu-bar-open'; on Windows, `w32-menu-bar-open'; on Haiku,
|
||||
`haiku-menu-bar-open'; otherwise it calls either `popup-menu'
|
||||
or `tmm-menubar' depending on whether `tty-menu-open-use-tmm'
|
||||
is nil or not.
|
||||
|
||||
If FRAME is nil or not given, use the selected frame."
|
||||
(interactive
|
||||
|
@ -2676,6 +2678,7 @@ If FRAME is nil or not given, use the selected frame."
|
|||
(cond
|
||||
((eq type 'x) (x-menu-bar-open frame))
|
||||
((eq type 'w32) (w32-menu-bar-open frame))
|
||||
((eq type 'haiku) (haiku-menu-bar-open frame))
|
||||
((and (null tty-menu-open-use-tmm)
|
||||
(not (zerop (or (frame-parameter nil 'menu-bar-lines) 0))))
|
||||
;; Make sure the menu bar is up to date. One situation where
|
||||
|
|
|
@ -55,7 +55,8 @@
|
|||
(mouse-wheel-mode 1)))
|
||||
|
||||
(defcustom mouse-wheel-down-event
|
||||
(if (or (featurep 'w32-win) (featurep 'ns-win))
|
||||
(if (or (featurep 'w32-win) (featurep 'ns-win)
|
||||
(featurep 'haiku-win))
|
||||
'wheel-up
|
||||
'mouse-4)
|
||||
"Event used for scrolling down."
|
||||
|
@ -71,7 +72,8 @@
|
|||
:set 'mouse-wheel-change-button)
|
||||
|
||||
(defcustom mouse-wheel-up-event
|
||||
(if (or (featurep 'w32-win) (featurep 'ns-win))
|
||||
(if (or (featurep 'w32-win) (featurep 'ns-win)
|
||||
(featurep 'haiku-win))
|
||||
'wheel-down
|
||||
'mouse-5)
|
||||
"Event used for scrolling up."
|
||||
|
@ -235,7 +237,8 @@ Also see `mouse-wheel-tilt-scroll'."
|
|||
"Function that does the job of scrolling right.")
|
||||
|
||||
(defvar mouse-wheel-left-event
|
||||
(if (or (featurep 'w32-win) (featurep 'ns-win))
|
||||
(if (or (featurep 'w32-win) (featurep 'ns-win)
|
||||
(featurep 'haiku-win))
|
||||
'wheel-left
|
||||
'mouse-6)
|
||||
"Event used for scrolling left.")
|
||||
|
@ -245,7 +248,8 @@ Also see `mouse-wheel-tilt-scroll'."
|
|||
"Alternative wheel left event to consider.")
|
||||
|
||||
(defvar mouse-wheel-right-event
|
||||
(if (or (featurep 'w32-win) (featurep 'ns-win))
|
||||
(if (or (featurep 'w32-win) (featurep 'ns-win)
|
||||
(featurep 'haiku-win))
|
||||
'wheel-right
|
||||
'mouse-7)
|
||||
"Event used for scrolling right.")
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
;; browse-url-chrome Chrome 47.0.2526.111
|
||||
;; browse-url-chromium Chromium 3.0
|
||||
;; browse-url-epiphany Epiphany Don't know
|
||||
;; browse-url-webpositive WebPositive 1.2-alpha (Haiku R1/beta3)
|
||||
;; browse-url-w3 w3 0
|
||||
;; browse-url-text-* Any text browser 0
|
||||
;; browse-url-generic arbitrary
|
||||
|
@ -156,6 +157,7 @@
|
|||
(function-item :tag "Google Chrome" :value browse-url-chrome)
|
||||
(function-item :tag "Chromium" :value browse-url-chromium)
|
||||
(function-item :tag "Epiphany" :value browse-url-epiphany)
|
||||
(function-item :tag "WebPositive" :value browse-url-webpositive)
|
||||
(function-item :tag "Text browser in an xterm window"
|
||||
:value browse-url-text-xterm)
|
||||
(function-item :tag "Text browser in an Emacs window"
|
||||
|
@ -366,6 +368,11 @@ Defaults to the value of `browse-url-epiphany-arguments' at the time
|
|||
`browse-url' is loaded."
|
||||
:type '(repeat (string :tag "Argument")))
|
||||
|
||||
(defcustom browse-url-webpositive-program "WebPositive"
|
||||
"The name by which to invoke WebPositive."
|
||||
:type 'string
|
||||
:version "28.1")
|
||||
|
||||
;; GNOME means of invoking either Mozilla or Netscape.
|
||||
(defvar browse-url-gnome-moz-program "gnome-moz-remote")
|
||||
|
||||
|
@ -1050,6 +1057,7 @@ instead of `browse-url-new-window-flag'."
|
|||
((executable-find browse-url-kde-program) 'browse-url-kde)
|
||||
;;; ((executable-find browse-url-netscape-program) 'browse-url-netscape)
|
||||
((executable-find browse-url-chrome-program) 'browse-url-chrome)
|
||||
((executable-find browse-url-webpositive-program) 'browse-url-webpositive)
|
||||
((executable-find browse-url-xterm-program) 'browse-url-text-xterm)
|
||||
((locate-library "w3") 'browse-url-w3)
|
||||
(t
|
||||
|
@ -1376,6 +1384,18 @@ used instead of `browse-url-new-window-flag'."
|
|||
|
||||
(defvar url-handler-regexp)
|
||||
|
||||
;;;###autoload
|
||||
(defun browse-url-webpositive (url &optional _new-window)
|
||||
"Ask the WebPositive WWW browser to load URL.
|
||||
Default to the URL around or before point.
|
||||
The optional argument NEW-WINDOW is not used."
|
||||
(interactive (browse-url-interactive-arg "URL: "))
|
||||
(setq url (browse-url-encode-url url))
|
||||
(let* ((process-environment (browse-url-process-environment)))
|
||||
(start-process (concat "WebPositive " url) nil "WebPositive" url)))
|
||||
|
||||
(function-put 'browse-url-webpositive 'browse-url-browser-kind 'external)
|
||||
|
||||
;;;###autoload
|
||||
(defun browse-url-emacs (url &optional same-window)
|
||||
"Ask Emacs to load URL into a buffer and show it in another window.
|
||||
|
|
|
@ -239,7 +239,7 @@ parameter, and should return the (possibly) transformed URL."
|
|||
:version "29.1")
|
||||
|
||||
(defface eww-form-submit
|
||||
'((((type x w32 ns) (class color)) ; Like default mode line
|
||||
'((((type x w32 ns haiku) (class color)) ; Like default mode line
|
||||
:box (:line-width 2 :style released-button)
|
||||
:background "#808080" :foreground "black"))
|
||||
"Face for eww buffer buttons."
|
||||
|
@ -247,7 +247,7 @@ parameter, and should return the (possibly) transformed URL."
|
|||
:group 'eww)
|
||||
|
||||
(defface eww-form-file
|
||||
'((((type x w32 ns) (class color)) ; Like default mode line
|
||||
'((((type x w32 ns haiku) (class color)) ; Like default mode line
|
||||
:box (:line-width 2 :style released-button)
|
||||
:background "#808080" :foreground "black"))
|
||||
"Face for eww buffer buttons."
|
||||
|
@ -255,7 +255,7 @@ parameter, and should return the (possibly) transformed URL."
|
|||
:group 'eww)
|
||||
|
||||
(defface eww-form-checkbox
|
||||
'((((type x w32 ns) (class color)) ; Like default mode line
|
||||
'((((type x w32 ns haiku) (class color)) ; Like default mode line
|
||||
:box (:line-width 2 :style released-button)
|
||||
:background "lightgrey" :foreground "black"))
|
||||
"Face for eww buffer buttons."
|
||||
|
@ -263,7 +263,7 @@ parameter, and should return the (possibly) transformed URL."
|
|||
:group 'eww)
|
||||
|
||||
(defface eww-form-select
|
||||
'((((type x w32 ns) (class color)) ; Like default mode line
|
||||
'((((type x w32 ns haiku) (class color)) ; Like default mode line
|
||||
:box (:line-width 2 :style released-button)
|
||||
:background "lightgrey" :foreground "black"))
|
||||
"Face for eww buffer buttons."
|
||||
|
|
134
lisp/term/haiku-win.el
Normal file
134
lisp/term/haiku-win.el
Normal file
|
@ -0,0 +1,134 @@
|
|||
;;; haiku-win.el --- set up windowing on Haiku -*- lexical-binding: t -*-
|
||||
|
||||
;; Copyright (C) 2021 Free Software Foundation, Inc.
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;; GNU Emacs 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.
|
||||
|
||||
;; GNU Emacs 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 GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; Support for using Haiku's BeOS derived windowing system.
|
||||
|
||||
;;; Code:
|
||||
|
||||
(eval-when-compile (require 'cl-lib))
|
||||
(unless (featurep 'haiku)
|
||||
(error "%s: Loading haiku-win without having Haiku"
|
||||
invocation-name))
|
||||
|
||||
;; Documentation-purposes only: actually loaded in loadup.el.
|
||||
(require 'frame)
|
||||
(require 'mouse)
|
||||
(require 'scroll-bar)
|
||||
(require 'menu-bar)
|
||||
(require 'fontset)
|
||||
(require 'dnd)
|
||||
|
||||
(add-to-list 'display-format-alist '(".*" . haiku-win))
|
||||
|
||||
;;;; Command line argument handling.
|
||||
|
||||
(defvar x-invocation-args)
|
||||
(defvar x-command-line-resources)
|
||||
|
||||
(defvar haiku-initialized)
|
||||
|
||||
(declare-function x-open-connection "haikufns.c")
|
||||
(declare-function x-handle-args "common-win")
|
||||
(declare-function haiku-selection-data "haikuselect.c")
|
||||
(declare-function haiku-selection-put "haikuselect.c")
|
||||
(declare-function haiku-put-resource "haikufns.c")
|
||||
|
||||
(defun haiku--handle-x-command-line-resources (command-line-resources)
|
||||
"Handle command line X resources specified with the option `-xrm'.
|
||||
The resources should be a list of strings in COMMAND-LINE-RESOURCES."
|
||||
(dolist (s command-line-resources)
|
||||
(let ((components (split-string s ":")))
|
||||
(when (car components)
|
||||
(haiku-put-resource (car components)
|
||||
(string-trim-left
|
||||
(mapconcat #'identity (cdr components) ":")))))))
|
||||
|
||||
(cl-defmethod window-system-initialization (&context (window-system haiku)
|
||||
&optional display)
|
||||
"Set up the window system. WINDOW-SYSTEM must be HAIKU.
|
||||
DISPLAY may be set to the name of a display that will be initialized."
|
||||
(cl-assert (not haiku-initialized))
|
||||
|
||||
(create-default-fontset)
|
||||
(when x-command-line-resources
|
||||
(haiku--handle-x-command-line-resources
|
||||
(split-string x-command-line-resources "\n")))
|
||||
(x-open-connection (or display "be") x-command-line-resources t)
|
||||
(setq haiku-initialized t))
|
||||
|
||||
(cl-defmethod frame-creation-function (params &context (window-system haiku))
|
||||
(x-create-frame-with-faces params))
|
||||
|
||||
(cl-defmethod handle-args-function (args &context (window-system haiku))
|
||||
(x-handle-args args))
|
||||
|
||||
(defun haiku--selection-type-to-mime (type)
|
||||
"Convert symbolic selection type TYPE to its MIME equivalent.
|
||||
If TYPE is nil, return \"text/plain\"."
|
||||
(cond
|
||||
((memq type '(TEXT COMPOUND_TEXT STRING UTF8_STRING)) "text/plain")
|
||||
((stringp type) type)
|
||||
(t "text/plain")))
|
||||
|
||||
(cl-defmethod gui-backend-get-selection (type data-type
|
||||
&context (window-system haiku))
|
||||
(haiku-selection-data type (haiku--selection-type-to-mime data-type)))
|
||||
|
||||
(cl-defmethod gui-backend-set-selection (type value
|
||||
&context (window-system haiku))
|
||||
(haiku-selection-put type "text/plain" value))
|
||||
|
||||
(cl-defmethod gui-backend-selection-exists-p (selection
|
||||
&context (window-system haiku))
|
||||
(haiku-selection-data selection "text/plain"))
|
||||
|
||||
(cl-defmethod gui-backend-selection-owner-p (_
|
||||
&context (window-system haiku))
|
||||
t)
|
||||
|
||||
(declare-function haiku-read-file-name "haikufns.c")
|
||||
|
||||
(defun x-file-dialog (prompt dir default_filename mustmatch only_dir_p)
|
||||
"SKIP: real doc in xfns.c."
|
||||
(if (eq (framep-on-display (selected-frame)) 'haiku)
|
||||
(haiku-read-file-name prompt (selected-frame)
|
||||
(or dir (and default_filename
|
||||
(file-name-directory default_filename)))
|
||||
mustmatch only_dir_p
|
||||
(file-name-nondirectory default_filename))
|
||||
(error "x-file-dialog on a tty frame")))
|
||||
|
||||
(defun haiku-dnd-handle-drag-n-drop-event (event)
|
||||
"Handle specified drag-n-drop EVENT."
|
||||
(interactive "e")
|
||||
(let* ((string (caddr event))
|
||||
(window (posn-window (event-start event))))
|
||||
(with-selected-window window
|
||||
(raise-frame)
|
||||
(dnd-handle-one-url window 'private (concat "file:" string)))))
|
||||
|
||||
(define-key special-event-map [drag-n-drop]
|
||||
'haiku-dnd-handle-drag-n-drop-event)
|
||||
|
||||
(provide 'haiku-win)
|
||||
(provide 'term/haiku-win)
|
||||
|
||||
;;; haiku-win.el ends here
|
|
@ -368,10 +368,15 @@ It is also called if Tooltip mode is on, for text-only displays."
|
|||
((equal-including-properties tooltip-help-message (current-message))
|
||||
(message nil)))))
|
||||
|
||||
(declare-function menu-or-popup-active-p "xmenu.c" ())
|
||||
|
||||
(defun tooltip-show-help (msg)
|
||||
"Function installed as `show-help-function'.
|
||||
MSG is either a help string to display, or nil to cancel the display."
|
||||
(if (display-graphic-p)
|
||||
(if (and (display-graphic-p)
|
||||
(or (not (eq window-system 'haiku)) ;; On Haiku, there isn't a reliable way to show tooltips
|
||||
;; above menus.
|
||||
(not (menu-or-popup-active-p))))
|
||||
(let ((previous-help tooltip-help-message))
|
||||
(setq tooltip-help-message msg)
|
||||
(cond ((null msg)
|
||||
|
|
|
@ -53,6 +53,8 @@ developing Emacs.")
|
|||
(defvar ns-version-string)
|
||||
(defvar cairo-version-string)
|
||||
|
||||
(declare-function haiku-get-version-string "haikufns.c")
|
||||
|
||||
(defun emacs-version (&optional here)
|
||||
"Return string describing the version of Emacs that is running.
|
||||
If optional argument HERE is non-nil, insert string at point.
|
||||
|
@ -71,6 +73,8 @@ to the system configuration; look at `system-configuration' instead."
|
|||
((featurep 'x-toolkit) ", X toolkit")
|
||||
((featurep 'ns)
|
||||
(format ", NS %s" ns-version-string))
|
||||
((featurep 'haiku)
|
||||
(format ", Haiku %s" (haiku-get-version-string)))
|
||||
(t ""))
|
||||
(if (featurep 'cairo)
|
||||
(format ", cairo version %s" cairo-version-string)
|
||||
|
|
|
@ -34,6 +34,7 @@ top_builddir = @top_builddir@
|
|||
abs_top_srcdir=@abs_top_srcdir@
|
||||
VPATH = $(srcdir)
|
||||
CC = @CC@
|
||||
CXX = @CXX@
|
||||
CFLAGS = @CFLAGS@
|
||||
CPPFLAGS = @CPPFLAGS@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
|
@ -346,10 +347,17 @@ BUILD_DETAILS = @BUILD_DETAILS@
|
|||
|
||||
UNEXEC_OBJ = @UNEXEC_OBJ@
|
||||
|
||||
HAIKU_OBJ = @HAIKU_OBJ@
|
||||
HAIKU_CXX_OBJ = @HAIKU_CXX_OBJ@
|
||||
HAIKU_LIBS = @HAIKU_LIBS@
|
||||
HAIKU_CFLAGS = @HAIKU_CFLAGS@
|
||||
|
||||
DUMPING=@DUMPING@
|
||||
CHECK_STRUCTS = @CHECK_STRUCTS@
|
||||
HAVE_PDUMPER = @HAVE_PDUMPER@
|
||||
|
||||
HAVE_BE_APP = @HAVE_BE_APP@
|
||||
|
||||
## ARM Macs require that all code have a valid signature. Since pdump
|
||||
## invalidates the signature, we must re-sign to fix it.
|
||||
DO_CODESIGN=$(patsubst aarch64-apple-darwin%,yes,@configuration@)
|
||||
|
@ -367,6 +375,9 @@ endif
|
|||
|
||||
# Flags that might be in WARN_CFLAGS but are not valid for Objective C.
|
||||
NON_OBJC_CFLAGS = -Wignored-attributes -Wignored-qualifiers -Wopenmp-simd
|
||||
# Ditto, but for C++.
|
||||
NON_CXX_CFLAGS = -Wmissing-prototypes -Wnested-externs -Wold-style-definition \
|
||||
-Wstrict-prototypes -Wno-override-init
|
||||
|
||||
# -Demacs makes some files produce the correct version for use in Emacs.
|
||||
# MYCPPFLAGS is for by-hand Emacs-specific overrides, e.g.,
|
||||
|
@ -382,17 +393,21 @@ EMACS_CFLAGS=-Demacs $(MYCPPFLAGS) -I. -I$(srcdir) \
|
|||
$(HARFBUZZ_CFLAGS) $(LIBOTF_CFLAGS) $(M17N_FLT_CFLAGS) $(DEPFLAGS) \
|
||||
$(LIBSYSTEMD_CFLAGS) $(JSON_CFLAGS) \
|
||||
$(LIBGNUTLS_CFLAGS) $(NOTIFY_CFLAGS) $(CAIRO_CFLAGS) \
|
||||
$(WERROR_CFLAGS)
|
||||
$(WERROR_CFLAGS) $(HAIKU_CFLAGS)
|
||||
ALL_CFLAGS = $(EMACS_CFLAGS) $(WARN_CFLAGS) $(CFLAGS)
|
||||
ALL_OBJC_CFLAGS = $(EMACS_CFLAGS) \
|
||||
$(filter-out $(NON_OBJC_CFLAGS),$(WARN_CFLAGS)) $(CFLAGS) \
|
||||
$(GNU_OBJC_CFLAGS)
|
||||
ALL_CXX_CFLAGS = $(EMACS_CFLAGS) \
|
||||
$(filter-out $(NON_CXX_CFLAGS),$(WARN_CFLAGS)) $(CXXFLAGS)
|
||||
|
||||
.SUFFIXES: .m
|
||||
.SUFFIXES: .m .cc
|
||||
.c.o:
|
||||
$(AM_V_CC)$(CC) -c $(CPPFLAGS) $(ALL_CFLAGS) $(PROFILING_CFLAGS) $<
|
||||
.m.o:
|
||||
$(AM_V_CC)$(CC) -c $(CPPFLAGS) $(ALL_OBJC_CFLAGS) $(PROFILING_CFLAGS) $<
|
||||
.cc.o:
|
||||
$(AM_V_CXX)$(CXX) -c $(CPPFLAGS) $(ALL_CXX_CFLAGS) $(PROFILING_CFLAGS) $<
|
||||
|
||||
## lastfile must follow all files whose initialized data areas should
|
||||
## be dumped as pure by dump-emacs.
|
||||
|
@ -414,8 +429,10 @@ base_obj = dispnew.o frame.o scroll.o xdisp.o menu.o $(XMENU_OBJ) window.o \
|
|||
thread.o systhread.o \
|
||||
$(if $(HYBRID_MALLOC),sheap.o) \
|
||||
$(MSDOS_OBJ) $(MSDOS_X_OBJ) $(NS_OBJ) $(CYGWIN_OBJ) $(FONT_OBJ) \
|
||||
$(W32_OBJ) $(WINDOW_SYSTEM_OBJ) $(XGSELOBJ) $(JSON_OBJ)
|
||||
obj = $(base_obj) $(NS_OBJC_OBJ)
|
||||
$(W32_OBJ) $(WINDOW_SYSTEM_OBJ) $(XGSELOBJ) $(JSON_OBJ) \
|
||||
$(HAIKU_OBJ)
|
||||
doc_obj = $(base_obj) $(NS_OBJC_OBJ)
|
||||
obj = $(doc_obj) $(HAIKU_CXX_OBJ)
|
||||
|
||||
## Object files used on some machine or other.
|
||||
## These go in the DOC file on all machines in case they are needed.
|
||||
|
@ -429,7 +446,8 @@ SOME_MACHINE_OBJECTS = dosfns.o msdos.o \
|
|||
w32.o w32console.o w32cygwinx.o w32fns.o w32heap.o w32inevt.o w32notify.o \
|
||||
w32menu.o w32proc.o w32reg.o w32select.o w32term.o w32xfns.o \
|
||||
w16select.o widget.o xfont.o ftfont.o xftfont.o gtkutil.o \
|
||||
xsettings.o xgselect.o termcap.o hbfont.o
|
||||
xsettings.o xgselect.o termcap.o hbfont.o \
|
||||
haikuterm.o haikufns.o haikumenu.o haikufont.o
|
||||
|
||||
## gmalloc.o if !SYSTEM_MALLOC && !DOUG_LEA_MALLOC, else empty.
|
||||
GMALLOC_OBJ=@GMALLOC_OBJ@
|
||||
|
@ -455,7 +473,11 @@ FIRSTFILE_OBJ=@FIRSTFILE_OBJ@
|
|||
ALLOBJS = $(FIRSTFILE_OBJ) $(VMLIMIT_OBJ) $(obj) $(otherobj)
|
||||
|
||||
# Must be first, before dep inclusion!
|
||||
ifneq ($(HAVE_BE_APP),yes)
|
||||
all: emacs$(EXEEXT) $(pdmp) $(OTHER_FILES)
|
||||
else
|
||||
all: Emacs Emacs.pdmp $(OTHER_FILES)
|
||||
endif
|
||||
ifeq ($(HAVE_NATIVE_COMP):$(NATIVE_DISABLED),yes:)
|
||||
all: ../native-lisp
|
||||
endif
|
||||
|
@ -527,7 +549,7 @@ LIBES = $(LIBS) $(W32_LIBS) $(LIBS_GNUSTEP) $(LIBX_BASE) $(LIBIMAGE) \
|
|||
$(FREETYPE_LIBS) $(FONTCONFIG_LIBS) $(HARFBUZZ_LIBS) $(LIBOTF_LIBS) $(M17N_FLT_LIBS) \
|
||||
$(LIBGNUTLS_LIBS) $(LIB_PTHREAD) $(GETADDRINFO_A_LIBS) $(LCMS2_LIBS) \
|
||||
$(NOTIFY_LIBS) $(LIB_MATH) $(LIBZ) $(LIBMODULES) $(LIBSYSTEMD_LIBS) \
|
||||
$(JSON_LIBS) $(LIBGMP) $(LIBGCCJIT_LIBS) $(XINPUT_LIBS)
|
||||
$(JSON_LIBS) $(LIBGMP) $(LIBGCCJIT_LIBS) $(XINPUT_LIBS) $(HAIKU_LIBS)
|
||||
|
||||
## FORCE it so that admin/unidata can decide whether this file is
|
||||
## up-to-date. Although since charprop depends on bootstrap-emacs,
|
||||
|
@ -584,6 +606,18 @@ else
|
|||
rm -f $@ && cp -f temacs$(EXEEXT) $@
|
||||
endif
|
||||
|
||||
## On Haiku, also produce a binary named Emacs with the appropriate
|
||||
## icon set.
|
||||
|
||||
ifeq ($(HAVE_BE_APP),yes)
|
||||
Emacs: emacs$(EXEEXT)
|
||||
cp -f emacs$(EXEEXT) $@
|
||||
$(AM_V_GEN) $(libsrc)/be-resources \
|
||||
$(etc)/images/icons/hicolor/32x32/apps/emacs.png $@
|
||||
Emacs.pdmp: $(pdmp)
|
||||
$(AM_V_GEN) cp -f $(pdmp) $@
|
||||
endif
|
||||
|
||||
ifeq ($(DUMPING),pdumper)
|
||||
$(pdmp): emacs$(EXEEXT)
|
||||
LC_ALL=C $(RUN_TEMACS) -batch $(BUILD_DETAILS) -l loadup --temacs=pdump \
|
||||
|
@ -602,11 +636,11 @@ endif
|
|||
## for the first time, this prevents any variation between configurations
|
||||
## in the contents of the DOC file.
|
||||
##
|
||||
$(etc)/DOC: lisp.mk $(libsrc)/make-docfile$(EXEEXT) $(obj) $(lisp)
|
||||
$(etc)/DOC: lisp.mk $(libsrc)/make-docfile$(EXEEXT) $(doc_obj) $(lisp)
|
||||
$(AM_V_GEN)$(MKDIR_P) $(etc)
|
||||
$(AM_V_at)rm -f $(etc)/DOC
|
||||
$(AM_V_at)$(libsrc)/make-docfile -d $(srcdir) \
|
||||
$(SOME_MACHINE_OBJECTS) $(obj) > $(etc)/DOC
|
||||
$(SOME_MACHINE_OBJECTS) $(doc_obj) > $(etc)/DOC
|
||||
$(AM_V_at)$(libsrc)/make-docfile -a $(etc)/DOC -d $(lispsource) \
|
||||
$(shortlisp)
|
||||
|
||||
|
@ -624,7 +658,7 @@ buildobj.h: Makefile
|
|||
GLOBAL_SOURCES = $(base_obj:.o=.c) $(NS_OBJC_OBJ:.o=.m)
|
||||
|
||||
gl-stamp: $(libsrc)/make-docfile$(EXEEXT) $(GLOBAL_SOURCES)
|
||||
$(AM_V_GLOBALS)$(libsrc)/make-docfile -d $(srcdir) -g $(obj) > globals.tmp
|
||||
$(AM_V_GLOBALS)$(libsrc)/make-docfile -d $(srcdir) -g $(doc_obj) > globals.tmp
|
||||
$(AM_V_at)$(top_srcdir)/build-aux/move-if-change globals.tmp globals.h
|
||||
$(AM_V_at)echo timestamp > $@
|
||||
|
||||
|
@ -649,9 +683,15 @@ endif
|
|||
## to start if Vinstallation_directory has the wrong value.
|
||||
temacs$(EXEEXT): $(LIBXMENU) $(ALLOBJS) $(LIBEGNU_ARCHIVE) $(EMACSRES) \
|
||||
$(charsets) $(charscript) ${emoji-zwj} $(MAKE_PDUMPER_FINGERPRINT)
|
||||
$(AM_V_CCLD)$(CC) -o $@.tmp \
|
||||
ifeq ($(HAVE_BE_APP),yes)
|
||||
$(AM_V_CXXLD)$(CXX) -o $@.tmp \
|
||||
$(ALL_CFLAGS) $(TEMACS_LDFLAGS) $(LDFLAGS) \
|
||||
$(ALLOBJS) $(LIBEGNU_ARCHIVE) $(W32_RES_LINK) $(LIBES) -lstdc++
|
||||
else
|
||||
$(AM_V_CCLD)$(CC) -o $@.tmp \
|
||||
$(ALL_CFLAGS) $(CXXFLAGS) $(TEMACS_LDFLAGS) $(LDFLAGS) \
|
||||
$(ALLOBJS) $(LIBEGNU_ARCHIVE) $(W32_RES_LINK) $(LIBES)
|
||||
endif
|
||||
ifeq ($(HAVE_PDUMPER),yes)
|
||||
$(AM_V_at)$(MAKE_PDUMPER_FINGERPRINT) $@.tmp
|
||||
ifeq ($(DO_CODESIGN),yes)
|
||||
|
@ -736,6 +776,7 @@ ${ETAGS}: FORCE
|
|||
# to be built before we can get TAGS.
|
||||
ctagsfiles1 = $(filter-out ${srcdir}/macuvs.h, $(wildcard ${srcdir}/*.[hc]))
|
||||
ctagsfiles2 = $(wildcard ${srcdir}/*.m)
|
||||
ctagsfiles3 = $(wildcard ${srcdir}/*.cc)
|
||||
|
||||
## In out-of-tree builds, TAGS are generated in the build dir, like
|
||||
## other non-bootstrap build products (see Bug#31744).
|
||||
|
@ -750,7 +791,8 @@ TAGS: ${ETAGS} $(ctagsfiles1) $(ctagsfiles2)
|
|||
$(ctagsfiles1) \
|
||||
--regex='{objc}/[ ]*DEFVAR_[A-Z_ (]+"\([^"]+\)"/\1/' \
|
||||
--regex='{objc}/[ ]*DEFVAR_[A-Z_ (]+"[^"]+",[ ]\([A-Za-z0-9_]+\)/\1/' \
|
||||
$(ctagsfiles2)
|
||||
$(ctagsfiles2) \
|
||||
$(ctagsfiles3)
|
||||
|
||||
## Arrange to make tags tables for ../lisp and ../lwlib,
|
||||
## which the above TAGS file for the C files includes by reference.
|
||||
|
|
|
@ -6149,6 +6149,10 @@ garbage_collect (void)
|
|||
xg_mark_data ();
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_HAIKU
|
||||
mark_haiku_display ();
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_WINDOW_SYSTEM
|
||||
mark_fringe_data ();
|
||||
#endif
|
||||
|
|
|
@ -134,6 +134,13 @@ typedef Emacs_Pixmap Emacs_Pix_Context;
|
|||
#define FACE_COLOR_TO_PIXEL(face_color, frame) face_color
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_HAIKU
|
||||
#include "haikugui.h"
|
||||
typedef struct haiku_display_info Display_Info;
|
||||
typedef Emacs_Pixmap Emacs_Pix_Container;
|
||||
typedef Emacs_Pixmap Emacs_Pix_Context;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_WINDOW_SYSTEM
|
||||
# include <time.h>
|
||||
# include "fontset.h"
|
||||
|
@ -3011,7 +3018,7 @@ struct redisplay_interface
|
|||
#ifdef HAVE_WINDOW_SYSTEM
|
||||
|
||||
# if (defined USE_CAIRO || defined HAVE_XRENDER \
|
||||
|| defined HAVE_NS || defined HAVE_NTGUI)
|
||||
|| defined HAVE_NS || defined HAVE_NTGUI || defined HAVE_HAIKU)
|
||||
# define HAVE_NATIVE_TRANSFORMS
|
||||
# endif
|
||||
|
||||
|
@ -3050,6 +3057,14 @@ struct image
|
|||
#ifdef HAVE_NTGUI
|
||||
XFORM xform;
|
||||
#endif
|
||||
#ifdef HAVE_HAIKU
|
||||
/* Non-zero if the image has not yet been transformed for display. */
|
||||
int have_be_transforms_p;
|
||||
|
||||
double be_rotate;
|
||||
double be_scale_x;
|
||||
double be_scale_y;
|
||||
#endif
|
||||
|
||||
/* Colors allocated for this image, if any. Allocated via xmalloc. */
|
||||
unsigned long *colors;
|
||||
|
@ -3489,7 +3504,8 @@ bool valid_image_p (Lisp_Object);
|
|||
void prepare_image_for_display (struct frame *, struct image *);
|
||||
ptrdiff_t lookup_image (struct frame *, Lisp_Object, int);
|
||||
|
||||
#if defined HAVE_X_WINDOWS || defined USE_CAIRO || defined HAVE_NS
|
||||
#if defined HAVE_X_WINDOWS || defined USE_CAIRO || defined HAVE_NS \
|
||||
|| defined HAVE_HAIKU
|
||||
#define RGB_PIXEL_COLOR unsigned long
|
||||
#endif
|
||||
|
||||
|
|
|
@ -6146,7 +6146,7 @@ sit_for (Lisp_Object timeout, bool reading, int display_option)
|
|||
wrong_type_argument (Qnumberp, timeout);
|
||||
|
||||
|
||||
#ifdef USABLE_SIGIO
|
||||
#if defined (USABLE_SIGIO) || defined (USABLE_SIGPOLL)
|
||||
gobble_input ();
|
||||
#endif
|
||||
|
||||
|
@ -6453,6 +6453,15 @@ init_display_interactive (void)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_HAIKU
|
||||
if (!inhibit_window_system && !will_dump_p ())
|
||||
{
|
||||
Vinitial_window_system = Qhaiku;
|
||||
Vwindow_system_version = make_fixnum (1);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* If no window system has been specified, try to use the terminal. */
|
||||
if (! isatty (STDIN_FILENO))
|
||||
fatal ("standard input is not a tty");
|
||||
|
|
28
src/emacs.c
28
src/emacs.c
|
@ -109,6 +109,10 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
|||
#include "getpagesize.h"
|
||||
#include "gnutls.h"
|
||||
|
||||
#ifdef HAVE_HAIKU
|
||||
#include <kernel/OS.h>
|
||||
#endif
|
||||
|
||||
#ifdef PROFILING
|
||||
# include <sys/gmon.h>
|
||||
extern void moncontrol (int mode);
|
||||
|
@ -2207,6 +2211,18 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
|
|||
syms_of_fontset ();
|
||||
#endif /* HAVE_NS */
|
||||
|
||||
#ifdef HAVE_HAIKU
|
||||
syms_of_haikuterm ();
|
||||
syms_of_haikufns ();
|
||||
syms_of_haikumenu ();
|
||||
syms_of_haikufont ();
|
||||
syms_of_haikuselect ();
|
||||
#ifdef HAVE_NATIVE_IMAGE_API
|
||||
syms_of_haikuimage ();
|
||||
#endif
|
||||
syms_of_fontset ();
|
||||
#endif /* HAVE_HAIKU */
|
||||
|
||||
syms_of_gnutls ();
|
||||
|
||||
#ifdef HAVE_INOTIFY
|
||||
|
@ -2261,6 +2277,10 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
|
|||
#if defined WINDOWSNT || defined HAVE_NTGUI
|
||||
globals_of_w32select ();
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_HAIKU
|
||||
init_haiku_select ();
|
||||
#endif
|
||||
}
|
||||
|
||||
init_charset ();
|
||||
|
@ -2728,6 +2748,9 @@ shut_down_emacs (int sig, Lisp_Object stuff)
|
|||
/* Don't update display from now on. */
|
||||
Vinhibit_redisplay = Qt;
|
||||
|
||||
#ifdef HAVE_HAIKU
|
||||
be_app_quit ();
|
||||
#endif
|
||||
/* If we are controlling the terminal, reset terminal modes. */
|
||||
#ifndef DOS_NT
|
||||
pid_t tpgrp = tcgetpgrp (STDIN_FILENO);
|
||||
|
@ -2737,6 +2760,10 @@ shut_down_emacs (int sig, Lisp_Object stuff)
|
|||
if (sig && sig != SIGTERM)
|
||||
{
|
||||
static char const fmt[] = "Fatal error %d: %n%s\n";
|
||||
#ifdef HAVE_HAIKU
|
||||
if (haiku_debug_on_fatal_error)
|
||||
debugger ("Fatal error in Emacs");
|
||||
#endif
|
||||
char buf[max ((sizeof fmt - sizeof "%d%n%s\n"
|
||||
+ INT_STRLEN_BOUND (int) + 1),
|
||||
min (PIPE_BUF, MAX_ALLOCA))];
|
||||
|
@ -3229,6 +3256,7 @@ Special values:
|
|||
`ms-dos' compiled as an MS-DOS application.
|
||||
`windows-nt' compiled as a native W32 application.
|
||||
`cygwin' compiled using the Cygwin library.
|
||||
`haiku' compiled for a Haiku system.
|
||||
Anything else (in Emacs 26, the possibilities are: aix, berkeley-unix,
|
||||
hpux, usg-unix-v) indicates some sort of Unix system. */);
|
||||
Vsystem_type = intern_c_string (SYSTEM_TYPE);
|
||||
|
|
|
@ -6190,7 +6190,7 @@ before any other event (mouse or keypress) is handled. */)
|
|||
(void)
|
||||
{
|
||||
#if (defined USE_GTK || defined USE_MOTIF \
|
||||
|| defined HAVE_NS || defined HAVE_NTGUI)
|
||||
|| defined HAVE_NS || defined HAVE_NTGUI || defined HAVE_HAIKU)
|
||||
if ((NILP (last_nonmenu_event) || CONSP (last_nonmenu_event))
|
||||
&& use_dialog_box
|
||||
&& use_file_dialog
|
||||
|
|
|
@ -65,7 +65,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
|||
#define BOOT_TIME_FILE "/var/run/random-seed"
|
||||
#endif
|
||||
|
||||
#if !defined WTMP_FILE && !defined WINDOWSNT
|
||||
#if !defined WTMP_FILE && !defined WINDOWSNT && defined BOOT_TIME
|
||||
#define WTMP_FILE "/var/log/wtmp"
|
||||
#endif
|
||||
|
||||
|
|
|
@ -347,6 +347,21 @@ int
|
|||
double_integer_scale (double d)
|
||||
{
|
||||
int exponent = ilogb (d);
|
||||
#ifdef HAIKU
|
||||
/* On Haiku, the values returned by ilogb are nonsensical when
|
||||
confronted with tiny numbers, inf, or NaN, which breaks the trick
|
||||
used by code on other platforms, so we have to test for each case
|
||||
manually, and return the appropriate value. */
|
||||
if (exponent == FP_ILOGB0)
|
||||
{
|
||||
if (isnan (d))
|
||||
return (DBL_MANT_DIG - DBL_MIN_EXP) + 2;
|
||||
if (isinf (d))
|
||||
return (DBL_MANT_DIG - DBL_MIN_EXP) + 1;
|
||||
|
||||
return (DBL_MANT_DIG - DBL_MIN_EXP);
|
||||
}
|
||||
#endif
|
||||
return (DBL_MIN_EXP - 1 <= exponent && exponent < INT_MAX
|
||||
? DBL_MANT_DIG - 1 - exponent
|
||||
: (DBL_MANT_DIG - DBL_MIN_EXP
|
||||
|
|
|
@ -5751,6 +5751,9 @@ match. */);
|
|||
#ifdef HAVE_NTGUI
|
||||
syms_of_w32font ();
|
||||
#endif /* HAVE_NTGUI */
|
||||
#ifdef USE_BE_CAIRO
|
||||
syms_of_ftcrfont ();
|
||||
#endif
|
||||
#endif /* HAVE_WINDOW_SYSTEM */
|
||||
}
|
||||
|
||||
|
|
|
@ -965,7 +965,7 @@ extern struct font_driver const nsfont_driver;
|
|||
extern void syms_of_nsfont (void);
|
||||
extern void syms_of_macfont (void);
|
||||
#endif /* HAVE_NS */
|
||||
#ifdef USE_CAIRO
|
||||
#if defined (USE_CAIRO) || defined (USE_BE_CAIRO)
|
||||
extern struct font_driver const ftcrfont_driver;
|
||||
#ifdef HAVE_HARFBUZZ
|
||||
extern struct font_driver ftcrhbfont_driver;
|
||||
|
@ -999,7 +999,7 @@ extern void font_deferred_log (const char *, Lisp_Object, Lisp_Object);
|
|||
INLINE bool
|
||||
font_data_structures_may_be_ill_formed (void)
|
||||
{
|
||||
#ifdef USE_CAIRO
|
||||
#if defined USE_CAIRO || defined USE_BE_CAIRO
|
||||
/* Although this works around Bug#20890, it is probably not the
|
||||
right thing to do. */
|
||||
return gc_in_progress;
|
||||
|
|
|
@ -226,6 +226,7 @@ Value is:
|
|||
`w32' for an Emacs frame that is a window on MS-Windows display,
|
||||
`ns' for an Emacs frame on a GNUstep or Macintosh Cocoa display,
|
||||
`pc' for a direct-write MS-DOS frame.
|
||||
`haiku` for an Emacs frame running in Haiku.
|
||||
See also `frame-live-p'. */)
|
||||
(Lisp_Object object)
|
||||
{
|
||||
|
@ -244,6 +245,8 @@ See also `frame-live-p'. */)
|
|||
return Qpc;
|
||||
case output_ns:
|
||||
return Qns;
|
||||
case output_haiku:
|
||||
return Qhaiku;
|
||||
default:
|
||||
emacs_abort ();
|
||||
}
|
||||
|
@ -6020,6 +6023,7 @@ syms_of_frame (void)
|
|||
DEFSYM (Qw32, "w32");
|
||||
DEFSYM (Qpc, "pc");
|
||||
DEFSYM (Qns, "ns");
|
||||
DEFSYM (Qhaiku, "haiku");
|
||||
DEFSYM (Qvisible, "visible");
|
||||
DEFSYM (Qbuffer_predicate, "buffer-predicate");
|
||||
DEFSYM (Qbuffer_list, "buffer-list");
|
||||
|
|
|
@ -585,6 +585,7 @@ struct frame
|
|||
struct x_output *x; /* From xterm.h. */
|
||||
struct w32_output *w32; /* From w32term.h. */
|
||||
struct ns_output *ns; /* From nsterm.h. */
|
||||
struct haiku_output *haiku; /* From haikuterm.h. */
|
||||
}
|
||||
output_data;
|
||||
|
||||
|
@ -852,6 +853,11 @@ default_pixels_per_inch_y (void)
|
|||
#else
|
||||
#define FRAME_NS_P(f) ((f)->output_method == output_ns)
|
||||
#endif
|
||||
#ifndef HAVE_HAIKU
|
||||
#define FRAME_HAIKU_P(f) false
|
||||
#else
|
||||
#define FRAME_HAIKU_P(f) ((f)->output_method == output_haiku)
|
||||
#endif
|
||||
|
||||
/* FRAME_WINDOW_P tests whether the frame is a graphical window system
|
||||
frame. */
|
||||
|
@ -864,6 +870,9 @@ default_pixels_per_inch_y (void)
|
|||
#ifdef HAVE_NS
|
||||
#define FRAME_WINDOW_P(f) FRAME_NS_P(f)
|
||||
#endif
|
||||
#ifdef HAVE_HAIKU
|
||||
#define FRAME_WINDOW_P(f) FRAME_HAIKU_P (f)
|
||||
#endif
|
||||
#ifndef FRAME_WINDOW_P
|
||||
#define FRAME_WINDOW_P(f) ((void) (f), false)
|
||||
#endif
|
||||
|
|
|
@ -22,7 +22,13 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
|||
#include <cairo-ft.h>
|
||||
|
||||
#include "lisp.h"
|
||||
#ifdef HAVE_X_WINDOWS
|
||||
#include "xterm.h"
|
||||
#else /* Otherwise, Haiku */
|
||||
#include "haikuterm.h"
|
||||
#include "haiku_support.h"
|
||||
#include "termchar.h"
|
||||
#endif
|
||||
#include "blockinput.h"
|
||||
#include "charset.h"
|
||||
#include "composite.h"
|
||||
|
@ -30,6 +36,12 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
|||
#include "ftfont.h"
|
||||
#include "pdumper.h"
|
||||
|
||||
#ifdef USE_BE_CAIRO
|
||||
#define RED_FROM_ULONG(color) (((color) >> 16) & 0xff)
|
||||
#define GREEN_FROM_ULONG(color) (((color) >> 8) & 0xff)
|
||||
#define BLUE_FROM_ULONG(color) ((color) & 0xff)
|
||||
#endif
|
||||
|
||||
#define METRICS_NCOLS_PER_ROW (128)
|
||||
|
||||
enum metrics_status
|
||||
|
@ -513,11 +525,37 @@ ftcrfont_draw (struct glyph_string *s,
|
|||
|
||||
block_input ();
|
||||
|
||||
#ifndef USE_BE_CAIRO
|
||||
cr = x_begin_cr_clip (f, s->gc);
|
||||
#else
|
||||
BView_draw_lock (FRAME_HAIKU_VIEW (f));
|
||||
EmacsWindow_begin_cr_critical_section (FRAME_HAIKU_WINDOW (f));
|
||||
cr = haiku_begin_cr_clip (f, s);
|
||||
if (!cr)
|
||||
{
|
||||
BView_draw_unlock (FRAME_HAIKU_VIEW (f));
|
||||
EmacsWindow_end_cr_critical_section (FRAME_HAIKU_WINDOW (f));
|
||||
unblock_input ();
|
||||
return 0;
|
||||
}
|
||||
BView_cr_dump_clipping (FRAME_HAIKU_VIEW (f), cr);
|
||||
#endif
|
||||
|
||||
if (with_background)
|
||||
{
|
||||
#ifndef USE_BE_CAIRO
|
||||
x_set_cr_source_with_gc_background (f, s->gc);
|
||||
s->background_filled_p = 1;
|
||||
#else
|
||||
struct face *face = s->face;
|
||||
|
||||
uint32_t col = s->hl == DRAW_CURSOR ?
|
||||
FRAME_CURSOR_COLOR (s->f).pixel : face->background;
|
||||
|
||||
cairo_set_source_rgb (cr, RED_FROM_ULONG (col) / 255.0,
|
||||
GREEN_FROM_ULONG (col) / 255.0,
|
||||
BLUE_FROM_ULONG (col) / 255.0);
|
||||
#endif
|
||||
cairo_rectangle (cr, x, y - FONT_BASE (face->font),
|
||||
s->width, FONT_HEIGHT (face->font));
|
||||
cairo_fill (cr);
|
||||
|
@ -533,13 +571,25 @@ ftcrfont_draw (struct glyph_string *s,
|
|||
glyphs[i].index,
|
||||
NULL));
|
||||
}
|
||||
|
||||
#ifndef USE_BE_CAIRO
|
||||
x_set_cr_source_with_gc_foreground (f, s->gc);
|
||||
#else
|
||||
uint32_t col = s->hl == DRAW_CURSOR ?
|
||||
FRAME_OUTPUT_DATA (s->f)->cursor_fg : face->foreground;
|
||||
|
||||
cairo_set_source_rgb (cr, RED_FROM_ULONG (col) / 255.0,
|
||||
GREEN_FROM_ULONG (col) / 255.0,
|
||||
BLUE_FROM_ULONG (col) / 255.0);
|
||||
#endif
|
||||
cairo_set_scaled_font (cr, ftcrfont_info->cr_scaled_font);
|
||||
cairo_show_glyphs (cr, glyphs, len);
|
||||
|
||||
#ifndef USE_BE_CAIRO
|
||||
x_end_cr_clip (f);
|
||||
|
||||
#else
|
||||
haiku_end_cr_clip (cr);
|
||||
EmacsWindow_end_cr_critical_section (FRAME_HAIKU_WINDOW (f));
|
||||
BView_draw_unlock (FRAME_HAIKU_VIEW (f));
|
||||
#endif
|
||||
unblock_input ();
|
||||
|
||||
return len;
|
||||
|
|
|
@ -3108,6 +3108,10 @@ syms_of_ftfont (void)
|
|||
Fput (Qfreetype, Qfont_driver_superseded_by, Qfreetypehb);
|
||||
#endif /* HAVE_HARFBUZZ */
|
||||
|
||||
#ifdef HAVE_HAIKU
|
||||
DEFSYM (Qmono, "mono");
|
||||
#endif
|
||||
|
||||
/* Fontconfig's generic families and their aliases. */
|
||||
DEFSYM (Qmonospace, "monospace");
|
||||
DEFSYM (Qsans_serif, "sans-serif");
|
||||
|
|
|
@ -29,6 +29,10 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
|||
# include FT_BDF_H
|
||||
#endif
|
||||
|
||||
#ifdef USE_BE_CAIRO
|
||||
#include <cairo.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_HARFBUZZ
|
||||
#include <hb.h>
|
||||
#include <hb-ft.h>
|
||||
|
@ -62,7 +66,7 @@ struct font_info
|
|||
hb_font_t *hb_font;
|
||||
#endif /* HAVE_HARFBUZZ */
|
||||
|
||||
#ifdef USE_CAIRO
|
||||
#if defined (USE_CAIRO) || defined (USE_BE_CAIRO)
|
||||
cairo_scaled_font_t *cr_scaled_font;
|
||||
/* Scale factor from the bitmap strike metrics in 1/64 pixels, used
|
||||
as the hb_position_t value in HarfBuzz, to those in (scaled)
|
||||
|
|
286
src/haiku.c
Normal file
286
src/haiku.c
Normal file
|
@ -0,0 +1,286 @@
|
|||
/* Haiku subroutines that are general to the Haiku operating system.
|
||||
Copyright (C) 2021 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Emacs.
|
||||
|
||||
GNU Emacs 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.
|
||||
|
||||
GNU Emacs 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 GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "lisp.h"
|
||||
#include "process.h"
|
||||
#include "coding.h"
|
||||
|
||||
#include <kernel/OS.h>
|
||||
|
||||
#include <pwd.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
Lisp_Object
|
||||
list_system_processes (void)
|
||||
{
|
||||
team_info info;
|
||||
int32 cookie = 0;
|
||||
Lisp_Object lval = Qnil;
|
||||
|
||||
while (get_next_team_info (&cookie, &info) == B_OK)
|
||||
lval = Fcons (make_fixnum (info.team), lval);
|
||||
|
||||
return lval;
|
||||
}
|
||||
|
||||
Lisp_Object
|
||||
system_process_attributes (Lisp_Object pid)
|
||||
{
|
||||
CHECK_FIXNUM (pid);
|
||||
|
||||
team_info info;
|
||||
Lisp_Object lval = Qnil;
|
||||
thread_info inf;
|
||||
area_info area;
|
||||
team_id id = (team_id) XFIXNUM (pid);
|
||||
struct passwd *g;
|
||||
size_t mem = 0;
|
||||
|
||||
if (get_team_info (id, &info) != B_OK)
|
||||
return Qnil;
|
||||
|
||||
bigtime_t everything = 0, vsample = 0;
|
||||
bigtime_t cpu_eaten = 0, esample = 0;
|
||||
|
||||
lval = Fcons (Fcons (Qeuid, make_fixnum (info.uid)), lval);
|
||||
lval = Fcons (Fcons (Qegid, make_fixnum (info.gid)), lval);
|
||||
lval = Fcons (Fcons (Qthcount, make_fixnum (info.thread_count)), lval);
|
||||
lval = Fcons (Fcons (Qcomm, build_string_from_utf8 (info.args)), lval);
|
||||
|
||||
g = getpwuid (info.uid);
|
||||
|
||||
if (g && g->pw_name)
|
||||
lval = Fcons (Fcons (Quser, build_string (g->pw_name)), lval);
|
||||
|
||||
/* FIXME: Calculating this makes Emacs show up as using 100% CPU! */
|
||||
|
||||
for (int32 team_cookie = 0;
|
||||
get_next_team_info (&team_cookie, &info) == B_OK;)
|
||||
for (int32 thread_cookie = 0;
|
||||
get_next_thread_info (info.team, &thread_cookie, &inf) == B_OK;)
|
||||
{
|
||||
if (inf.team == id && strncmp (inf.name, "idle thread ", 12))
|
||||
cpu_eaten += inf.user_time + inf.kernel_time;
|
||||
everything += inf.user_time + inf.kernel_time;
|
||||
}
|
||||
|
||||
sleep (0.05);
|
||||
|
||||
for (int32 team_cookie = 0;
|
||||
get_next_team_info (&team_cookie, &info) == B_OK;)
|
||||
for (int32 thread_cookie = 0;
|
||||
get_next_thread_info (info.team, &thread_cookie, &inf) == B_OK;)
|
||||
{
|
||||
if (inf.team == id && strncmp (inf.name, "idle thread ", 12))
|
||||
esample += inf.user_time + inf.kernel_time;
|
||||
vsample += inf.user_time + inf.kernel_time;
|
||||
}
|
||||
|
||||
cpu_eaten = esample - cpu_eaten;
|
||||
everything = vsample - everything;
|
||||
|
||||
if (everything)
|
||||
lval = Fcons (Fcons (Qpcpu, make_float (((double) (cpu_eaten) /
|
||||
(double) (everything)) * 100)),
|
||||
lval);
|
||||
else
|
||||
lval = Fcons (Fcons (Qpcpu, make_float (0.0)), lval);
|
||||
|
||||
for (ssize_t area_cookie = 0;
|
||||
get_next_area_info (id, &area_cookie, &area) == B_OK;)
|
||||
mem += area.ram_size;
|
||||
|
||||
system_info sinfo;
|
||||
get_system_info (&sinfo);
|
||||
int64 max = (int64) sinfo.max_pages * B_PAGE_SIZE;
|
||||
|
||||
lval = Fcons (Fcons (Qpmem, make_float (((double) mem /
|
||||
(double) max) * 100)),
|
||||
lval);
|
||||
lval = Fcons (Fcons (Qrss, make_fixnum (mem / 1024)), lval);
|
||||
|
||||
return lval;
|
||||
}
|
||||
|
||||
|
||||
/* Borrowed from w32 implementation. */
|
||||
|
||||
struct load_sample
|
||||
{
|
||||
time_t sample_time;
|
||||
bigtime_t idle;
|
||||
bigtime_t kernel;
|
||||
bigtime_t user;
|
||||
};
|
||||
|
||||
/* We maintain 1-sec samples for the last 16 minutes in a circular buffer. */
|
||||
static struct load_sample samples[16*60];
|
||||
static int first_idx = -1, last_idx = -1;
|
||||
static int max_idx = ARRAYELTS (samples);
|
||||
static unsigned num_of_processors = 0;
|
||||
|
||||
static int
|
||||
buf_next (int from)
|
||||
{
|
||||
int next_idx = from + 1;
|
||||
|
||||
if (next_idx >= max_idx)
|
||||
next_idx = 0;
|
||||
|
||||
return next_idx;
|
||||
}
|
||||
|
||||
static int
|
||||
buf_prev (int from)
|
||||
{
|
||||
int prev_idx = from - 1;
|
||||
|
||||
if (prev_idx < 0)
|
||||
prev_idx = max_idx - 1;
|
||||
|
||||
return prev_idx;
|
||||
}
|
||||
|
||||
static double
|
||||
getavg (int which)
|
||||
{
|
||||
double retval = -1.0;
|
||||
double tdiff;
|
||||
int idx;
|
||||
double span = (which == 0 ? 1.0 : (which == 1 ? 5.0 : 15.0)) * 60;
|
||||
time_t now = samples[last_idx].sample_time;
|
||||
|
||||
if (first_idx != last_idx)
|
||||
{
|
||||
for (idx = buf_prev (last_idx); ; idx = buf_prev (idx))
|
||||
{
|
||||
tdiff = difftime (now, samples[idx].sample_time);
|
||||
if (tdiff >= span - 2 * DBL_EPSILON * now)
|
||||
{
|
||||
long double sys =
|
||||
(samples[last_idx].kernel + samples[last_idx].user) -
|
||||
(samples[idx].kernel + samples[idx].user);
|
||||
long double idl = samples[last_idx].idle - samples[idx].idle;
|
||||
|
||||
retval = (idl / (sys + idl)) * num_of_processors;
|
||||
break;
|
||||
}
|
||||
if (idx == first_idx)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void
|
||||
sample_sys_load (bigtime_t *idle, bigtime_t *system, bigtime_t *user)
|
||||
{
|
||||
bigtime_t i = 0, s = 0, u = 0;
|
||||
team_info info;
|
||||
thread_info inf;
|
||||
|
||||
for (int32 team_cookie = 0;
|
||||
get_next_team_info (&team_cookie, &info) == B_OK;)
|
||||
for (int32 thread_cookie = 0;
|
||||
get_next_thread_info (info.team, &thread_cookie, &inf) == B_OK;)
|
||||
{
|
||||
if (!strncmp (inf.name, "idle thread ", 12))
|
||||
i += inf.user_time + inf.kernel_time;
|
||||
else
|
||||
s += inf.kernel_time, u += inf.user_time;
|
||||
}
|
||||
|
||||
*idle = i;
|
||||
*system = s;
|
||||
*user = u;
|
||||
}
|
||||
|
||||
int
|
||||
getloadavg (double loadavg[], int nelem)
|
||||
{
|
||||
int elem;
|
||||
bigtime_t idle, kernel, user;
|
||||
time_t now = time (NULL);
|
||||
|
||||
if (num_of_processors <= 0)
|
||||
{
|
||||
system_info i;
|
||||
if (get_system_info (&i) == B_OK)
|
||||
num_of_processors = i.cpu_count;
|
||||
}
|
||||
|
||||
/* If system time jumped back for some reason, delete all samples
|
||||
whose time is later than the current wall-clock time. This
|
||||
prevents load average figures from becoming frozen for prolonged
|
||||
periods of time, when system time is reset backwards. */
|
||||
if (last_idx >= 0)
|
||||
{
|
||||
while (difftime (now, samples[last_idx].sample_time) < -1.0)
|
||||
{
|
||||
if (last_idx == first_idx)
|
||||
{
|
||||
first_idx = last_idx = -1;
|
||||
break;
|
||||
}
|
||||
last_idx = buf_prev (last_idx);
|
||||
}
|
||||
}
|
||||
|
||||
/* Store another sample. We ignore samples that are less than 1 sec
|
||||
apart. */
|
||||
if (last_idx < 0
|
||||
|| (difftime (now, samples[last_idx].sample_time)
|
||||
>= 1.0 - 2 * DBL_EPSILON * now))
|
||||
{
|
||||
sample_sys_load (&idle, &kernel, &user);
|
||||
last_idx = buf_next (last_idx);
|
||||
samples[last_idx].sample_time = now;
|
||||
samples[last_idx].idle = idle;
|
||||
samples[last_idx].kernel = kernel;
|
||||
samples[last_idx].user = user;
|
||||
/* If the buffer has more that 15 min worth of samples, discard
|
||||
the old ones. */
|
||||
if (first_idx == -1)
|
||||
first_idx = last_idx;
|
||||
while (first_idx != last_idx
|
||||
&& (difftime (now, samples[first_idx].sample_time)
|
||||
>= 15.0 * 60 + 2 * DBL_EPSILON * now))
|
||||
first_idx = buf_next (first_idx);
|
||||
}
|
||||
|
||||
for (elem = 0; elem < nelem; elem++)
|
||||
{
|
||||
double avg = getavg (elem);
|
||||
|
||||
if (avg < 0)
|
||||
break;
|
||||
loadavg[elem] = avg;
|
||||
}
|
||||
|
||||
/* Always return at least one element, otherwise load-average
|
||||
returns nil, and Lisp programs might decide we cannot measure
|
||||
system load. For example, jit-lock-stealth-load's defcustom
|
||||
might decide that feature is "unsupported". */
|
||||
if (elem == 0)
|
||||
loadavg[elem++] = 0.09; /* < display-time-load-average-threshold */
|
||||
|
||||
return elem;
|
||||
}
|
488
src/haiku_draw_support.cc
Normal file
488
src/haiku_draw_support.cc
Normal file
|
@ -0,0 +1,488 @@
|
|||
/* Haiku window system support. Hey, Emacs, this is -*- C++ -*-
|
||||
Copyright (C) 2021 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Emacs.
|
||||
|
||||
GNU Emacs 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.
|
||||
|
||||
GNU Emacs 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 GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <View.h>
|
||||
#include <Region.h>
|
||||
#include <Font.h>
|
||||
#include <Window.h>
|
||||
#include <Bitmap.h>
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include "haiku_support.h"
|
||||
|
||||
#define RGB_TO_UINT32(r, g, b) ((255 << 24) | ((r) << 16) | ((g) << 8) | (b))
|
||||
#define RED_FROM_ULONG(color) (((color) >> 16) & 0xff)
|
||||
#define GREEN_FROM_ULONG(color) (((color) >> 8) & 0xff)
|
||||
#define BLUE_FROM_ULONG(color) ((color) & 0xff)
|
||||
|
||||
#define RGB_COLOR_UINT32(r) RGB_TO_UINT32 ((r).red, (r).green, (r).blue)
|
||||
|
||||
static void
|
||||
rgb32_to_rgb_color (uint32_t rgb, rgb_color *color)
|
||||
{
|
||||
color->red = RED_FROM_ULONG (rgb);
|
||||
color->green = GREEN_FROM_ULONG (rgb);
|
||||
color->blue = BLUE_FROM_ULONG (rgb);
|
||||
color->alpha = 255;
|
||||
}
|
||||
|
||||
static BView *
|
||||
get_view (void *vw)
|
||||
{
|
||||
BView *view = (BView *) find_appropriate_view_for_draw (vw);
|
||||
return view;
|
||||
}
|
||||
|
||||
void
|
||||
BView_StartClip (void *view)
|
||||
{
|
||||
BView *vw = get_view (view);
|
||||
vw->PushState ();
|
||||
}
|
||||
|
||||
void
|
||||
BView_EndClip (void *view)
|
||||
{
|
||||
BView *vw = get_view (view);
|
||||
vw->PopState ();
|
||||
}
|
||||
|
||||
void
|
||||
BView_SetHighColor (void *view, uint32_t color)
|
||||
{
|
||||
BView *vw = get_view (view);
|
||||
rgb_color col;
|
||||
rgb32_to_rgb_color (color, &col);
|
||||
|
||||
vw->SetHighColor (col);
|
||||
}
|
||||
|
||||
void
|
||||
BView_SetLowColor (void *view, uint32_t color)
|
||||
{
|
||||
BView *vw = get_view (view);
|
||||
rgb_color col;
|
||||
rgb32_to_rgb_color (color, &col);
|
||||
|
||||
vw->SetLowColor (col);
|
||||
}
|
||||
|
||||
void
|
||||
BView_SetPenSize (void *view, int u)
|
||||
{
|
||||
BView *vw = get_view (view);
|
||||
vw->SetPenSize (u);
|
||||
}
|
||||
|
||||
void
|
||||
BView_FillRectangle (void *view, int x, int y, int width, int height)
|
||||
{
|
||||
BView *vw = get_view (view);
|
||||
BRect rect = BRect (x, y, x + width - 1, y + height - 1);
|
||||
|
||||
vw->FillRect (rect);
|
||||
}
|
||||
|
||||
void
|
||||
BView_FillRectangleAbs (void *view, int x, int y, int x1, int y1)
|
||||
{
|
||||
BView *vw = get_view (view);
|
||||
BRect rect = BRect (x, y, x1, y1);
|
||||
|
||||
vw->FillRect (rect);
|
||||
}
|
||||
|
||||
void
|
||||
BView_StrokeRectangle (void *view, int x, int y, int width, int height)
|
||||
{
|
||||
BView *vw = get_view (view);
|
||||
BRect rect = BRect (x, y, x + width - 1, y + height - 1);
|
||||
|
||||
vw->StrokeRect (rect);
|
||||
}
|
||||
|
||||
void
|
||||
BView_SetViewColor (void *view, uint32_t color)
|
||||
{
|
||||
BView *vw = get_view (view);
|
||||
rgb_color col;
|
||||
rgb32_to_rgb_color (color, &col);
|
||||
|
||||
#ifndef USE_BE_CAIRO
|
||||
vw->SetViewColor (col);
|
||||
#else
|
||||
vw->SetViewColor (B_TRANSPARENT_32_BIT);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
BView_ClipToRect (void *view, int x, int y, int width, int height)
|
||||
{
|
||||
BView *vw = get_view (view);
|
||||
BRect rect = BRect (x, y, x + width - 1, y + height - 1);
|
||||
|
||||
vw->ClipToRect (rect);
|
||||
}
|
||||
|
||||
void
|
||||
BView_ClipToInverseRect (void *view, int x, int y, int width, int height)
|
||||
{
|
||||
BView *vw = get_view (view);
|
||||
BRect rect = BRect (x, y, x + width - 1, y + height - 1);
|
||||
|
||||
vw->ClipToInverseRect (rect);
|
||||
}
|
||||
|
||||
void
|
||||
BView_StrokeLine (void *view, int sx, int sy, int tx, int ty)
|
||||
{
|
||||
BView *vw = get_view (view);
|
||||
BPoint from = BPoint (sx, sy);
|
||||
BPoint to = BPoint (tx, ty);
|
||||
|
||||
vw->StrokeLine (from, to);
|
||||
}
|
||||
|
||||
void
|
||||
BView_SetFont (void *view, void *font)
|
||||
{
|
||||
BView *vw = get_view (view);
|
||||
|
||||
vw->SetFont ((BFont *) font);
|
||||
}
|
||||
|
||||
void
|
||||
BView_MovePenTo (void *view, int x, int y)
|
||||
{
|
||||
BView *vw = get_view (view);
|
||||
BPoint pt = BPoint (x, y);
|
||||
|
||||
vw->MovePenTo (pt);
|
||||
}
|
||||
|
||||
void
|
||||
BView_DrawString (void *view, const char *chr, ptrdiff_t len)
|
||||
{
|
||||
BView *vw = get_view (view);
|
||||
|
||||
vw->DrawString (chr, len);
|
||||
}
|
||||
|
||||
void
|
||||
BView_DrawChar (void *view, char chr)
|
||||
{
|
||||
BView *vw = get_view (view);
|
||||
|
||||
vw->DrawChar (chr);
|
||||
}
|
||||
|
||||
void
|
||||
BView_CopyBits (void *view, int x, int y, int width, int height,
|
||||
int tox, int toy, int towidth, int toheight)
|
||||
{
|
||||
BView *vw = get_view (view);
|
||||
|
||||
vw->CopyBits (BRect (x, y, x + width - 1, y + height - 1),
|
||||
BRect (tox, toy, tox + towidth - 1, toy + toheight - 1));
|
||||
vw->Sync ();
|
||||
}
|
||||
|
||||
/* Convert RGB32 color color from RGB color space to its
|
||||
HSL components pointed to by H, S and L. */
|
||||
void
|
||||
rgb_color_hsl (uint32_t rgb, double *h, double *s, double *l)
|
||||
{
|
||||
rgb_color col;
|
||||
rgb32_to_rgb_color (rgb, &col);
|
||||
|
||||
double red = col.red / 255.0;
|
||||
double green = col.green / 255.0;
|
||||
double blue = col.blue / 255.0;
|
||||
|
||||
double max = std::fmax (std::fmax (red, blue), green);
|
||||
double min = std::fmin (std::fmin (red, blue), green);
|
||||
double delta = max - min;
|
||||
*l = (max + min) / 2.0;
|
||||
|
||||
if (!delta)
|
||||
{
|
||||
*h = 0;
|
||||
*s = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
*s = (*l < 0.5) ? delta / (max + min) :
|
||||
delta / (20 - max - min);
|
||||
double rc = (max - red) / delta;
|
||||
double gc = (max - green) / delta;
|
||||
double bc = (max - blue) / delta;
|
||||
|
||||
if (red == max)
|
||||
*h = bc - gc;
|
||||
else if (green == max)
|
||||
*h = 2.0 + rc + -bc;
|
||||
else
|
||||
*h = 4.0 + gc + -rc;
|
||||
*h = std::fmod (*h / 6, 1.0);
|
||||
}
|
||||
|
||||
static double
|
||||
hue_to_rgb (double v1, double v2, double h)
|
||||
{
|
||||
if (h < 1 / 6)
|
||||
return v1 + (v2 - v1) * h * 6.0;
|
||||
else if (h < 0.5)
|
||||
return v2;
|
||||
else if (h < 2.0 / 3)
|
||||
return v1 + (v2 - v1) * (2.0 / 3 - h) * 6.0;
|
||||
return v1;
|
||||
}
|
||||
|
||||
void
|
||||
hsl_color_rgb (double h, double s, double l, uint32_t *rgb)
|
||||
{
|
||||
if (!s)
|
||||
*rgb = RGB_TO_UINT32 (std::lrint (l * 255),
|
||||
std::lrint (l * 255),
|
||||
std::lrint (l * 255));
|
||||
else
|
||||
{
|
||||
double m2 = l <= 0.5 ? l * (1 + s) : l + s - l * s;
|
||||
double m1 = 2.0 * l - m2;
|
||||
|
||||
*rgb = RGB_TO_UINT32
|
||||
(std::lrint (hue_to_rgb (m1, m2,
|
||||
std::fmod (h + 1 / 3.0, 1)) * 255),
|
||||
std::lrint (hue_to_rgb (m1, m2, h) * 255),
|
||||
std::lrint (hue_to_rgb (m1, m2,
|
||||
std::fmod (h - 1 / 3.0, 1)) * 255));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
BView_DrawBitmap (void *view, void *bitmap, int x, int y,
|
||||
int width, int height, int vx, int vy, int vwidth,
|
||||
int vheight)
|
||||
{
|
||||
BView *vw = get_view (view);
|
||||
BBitmap *bm = (BBitmap *) bitmap;
|
||||
|
||||
vw->PushState ();
|
||||
vw->SetDrawingMode (B_OP_OVER);
|
||||
vw->DrawBitmap (bm, BRect (x, y, x + width - 1, y + height - 1),
|
||||
BRect (vx, vy, vx + vwidth - 1, vy + vheight - 1));
|
||||
vw->PopState ();
|
||||
}
|
||||
|
||||
void
|
||||
BView_DrawBitmapWithEraseOp (void *view, void *bitmap, int x,
|
||||
int y, int width, int height)
|
||||
{
|
||||
BView *vw = get_view (view);
|
||||
BBitmap *bm = (BBitmap *) bitmap;
|
||||
BBitmap bc (bm->Bounds (), B_RGBA32);
|
||||
BRect rect (x, y, x + width - 1, y + height - 1);
|
||||
|
||||
if (bc.InitCheck () != B_OK || bc.ImportBits (bm) != B_OK)
|
||||
return;
|
||||
|
||||
uint32_t *bits = (uint32_t *) bc.Bits ();
|
||||
size_t stride = bc.BytesPerRow ();
|
||||
|
||||
if (bm->ColorSpace () == B_GRAY1)
|
||||
{
|
||||
rgb_color low_color = vw->LowColor ();
|
||||
for (int y = 0; y <= bc.Bounds ().Height (); ++y)
|
||||
{
|
||||
for (int x = 0; x <= bc.Bounds ().Width (); ++x)
|
||||
{
|
||||
if (bits[y * (stride / 4) + x] == 0xFF000000)
|
||||
bits[y * (stride / 4) + x] = RGB_COLOR_UINT32 (low_color);
|
||||
else
|
||||
bits[y * (stride / 4) + x] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vw->PushState ();
|
||||
vw->SetDrawingMode (bm->ColorSpace () == B_GRAY1 ? B_OP_OVER : B_OP_ERASE);
|
||||
vw->DrawBitmap (&bc, rect);
|
||||
vw->PopState ();
|
||||
}
|
||||
|
||||
void
|
||||
BView_DrawMask (void *src, void *view,
|
||||
int x, int y, int width, int height,
|
||||
int vx, int vy, int vwidth, int vheight,
|
||||
uint32_t color)
|
||||
{
|
||||
BBitmap *source = (BBitmap *) src;
|
||||
BBitmap bm (source->Bounds (), B_RGBA32);
|
||||
if (bm.InitCheck () != B_OK)
|
||||
return;
|
||||
for (int y = 0; y <= bm.Bounds ().Height (); ++y)
|
||||
{
|
||||
for (int x = 0; x <= bm.Bounds ().Width (); ++x)
|
||||
{
|
||||
int bit = haiku_get_pixel ((void *) source, x, y);
|
||||
|
||||
if (!bit)
|
||||
haiku_put_pixel ((void *) &bm, x, y, ((uint32_t) 255 << 24) | color);
|
||||
else
|
||||
haiku_put_pixel ((void *) &bm, x, y, 0);
|
||||
}
|
||||
}
|
||||
BView *vw = get_view (view);
|
||||
vw->SetDrawingMode (B_OP_OVER);
|
||||
vw->DrawBitmap (&bm, BRect (x, y, x + width - 1, y + height - 1),
|
||||
BRect (vx, vy, vx + vwidth - 1, vy + vheight - 1));
|
||||
}
|
||||
|
||||
static BBitmap *
|
||||
rotate_bitmap_270 (BBitmap *bmp)
|
||||
{
|
||||
BRect r = bmp->Bounds ();
|
||||
BBitmap *bm = new BBitmap (BRect (r.top, r.left, r.bottom, r.right),
|
||||
bmp->ColorSpace (), true);
|
||||
if (bm->InitCheck () != B_OK)
|
||||
gui_abort ("Failed to init bitmap for rotate");
|
||||
int w = bmp->Bounds ().Width () + 1;
|
||||
int h = bmp->Bounds ().Height () + 1;
|
||||
|
||||
for (int y = 0; y < h; ++y)
|
||||
for (int x = 0; x < w; ++x)
|
||||
haiku_put_pixel ((void *) bm, y, w - x - 1,
|
||||
haiku_get_pixel ((void *) bmp, x, y));
|
||||
|
||||
return bm;
|
||||
}
|
||||
|
||||
static BBitmap *
|
||||
rotate_bitmap_90 (BBitmap *bmp)
|
||||
{
|
||||
BRect r = bmp->Bounds ();
|
||||
BBitmap *bm = new BBitmap (BRect (r.top, r.left, r.bottom, r.right),
|
||||
bmp->ColorSpace (), true);
|
||||
if (bm->InitCheck () != B_OK)
|
||||
gui_abort ("Failed to init bitmap for rotate");
|
||||
int w = bmp->Bounds ().Width () + 1;
|
||||
int h = bmp->Bounds ().Height () + 1;
|
||||
|
||||
for (int y = 0; y < h; ++y)
|
||||
for (int x = 0; x < w; ++x)
|
||||
haiku_put_pixel ((void *) bm, h - y - 1, x,
|
||||
haiku_get_pixel ((void *) bmp, x, y));
|
||||
|
||||
return bm;
|
||||
}
|
||||
|
||||
void *
|
||||
BBitmap_transform_bitmap (void *bitmap, void *mask, uint32_t m_color,
|
||||
double rot, int desw, int desh)
|
||||
{
|
||||
BBitmap *bm = (BBitmap *) bitmap;
|
||||
BBitmap *mk = (BBitmap *) mask;
|
||||
int copied_p = 0;
|
||||
|
||||
if (rot == 90)
|
||||
{
|
||||
copied_p = 1;
|
||||
bm = rotate_bitmap_90 (bm);
|
||||
if (mk)
|
||||
mk = rotate_bitmap_90 (mk);
|
||||
}
|
||||
|
||||
if (rot == 270)
|
||||
{
|
||||
copied_p = 1;
|
||||
bm = rotate_bitmap_270 (bm);
|
||||
if (mk)
|
||||
mk = rotate_bitmap_270 (mk);
|
||||
}
|
||||
|
||||
BRect r = bm->Bounds ();
|
||||
if (r.Width () != desw || r.Height () != desh)
|
||||
{
|
||||
BRect n = BRect (0, 0, desw - 1, desh - 1);
|
||||
BView vw (n, NULL, B_FOLLOW_NONE, 0);
|
||||
BBitmap *dst = new BBitmap (n, bm->ColorSpace (), true);
|
||||
if (dst->InitCheck () != B_OK)
|
||||
if (bm->InitCheck () != B_OK)
|
||||
gui_abort ("Failed to init bitmap for scale");
|
||||
dst->AddChild (&vw);
|
||||
|
||||
if (!vw.LockLooper ())
|
||||
gui_abort ("Failed to lock offscreen view for scale");
|
||||
|
||||
if (rot != 90 && rot != 270)
|
||||
{
|
||||
BAffineTransform tr;
|
||||
tr.RotateBy (BPoint (desw / 2, desh / 2), rot * M_PI / 180.0);
|
||||
vw.SetTransform (tr);
|
||||
}
|
||||
|
||||
vw.MovePenTo (0, 0);
|
||||
vw.DrawBitmap (bm, n);
|
||||
if (mk)
|
||||
BView_DrawMask ((void *) mk, (void *) &vw,
|
||||
0, 0, mk->Bounds ().Width (),
|
||||
mk->Bounds ().Height (),
|
||||
0, 0, desw, desh, m_color);
|
||||
vw.Sync ();
|
||||
vw.RemoveSelf ();
|
||||
|
||||
if (copied_p)
|
||||
delete bm;
|
||||
if (copied_p && mk)
|
||||
delete mk;
|
||||
return dst;
|
||||
}
|
||||
|
||||
return bm;
|
||||
}
|
||||
|
||||
void
|
||||
BView_FillTriangle (void *view, int x1, int y1,
|
||||
int x2, int y2, int x3, int y3)
|
||||
{
|
||||
BView *vw = get_view (view);
|
||||
vw->FillTriangle (BPoint (x1, y1), BPoint (x2, y2),
|
||||
BPoint (x3, y3));
|
||||
}
|
||||
|
||||
void
|
||||
BView_SetHighColorForVisibleBell (void *view, uint32_t color)
|
||||
{
|
||||
BView *vw = (BView *) view;
|
||||
rgb_color col;
|
||||
rgb32_to_rgb_color (color, &col);
|
||||
|
||||
vw->SetHighColor (col);
|
||||
}
|
||||
|
||||
void
|
||||
BView_FillRectangleForVisibleBell (void *view, int x, int y, int width, int height)
|
||||
{
|
||||
BView *vw = (BView *) view;
|
||||
BRect rect = BRect (x, y, x + width - 1, y + height - 1);
|
||||
|
||||
vw->FillRect (rect);
|
||||
}
|
596
src/haiku_font_support.cc
Normal file
596
src/haiku_font_support.cc
Normal file
|
@ -0,0 +1,596 @@
|
|||
/* Haiku window system support. Hey, Emacs, this is -*- C++ -*-
|
||||
Copyright (C) 2021 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Emacs.
|
||||
|
||||
GNU Emacs 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.
|
||||
|
||||
GNU Emacs 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 GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <Font.h>
|
||||
#include <Rect.h>
|
||||
#include <AffineTransform.h>
|
||||
|
||||
#include <cstring>
|
||||
#include <cmath>
|
||||
|
||||
#include "haiku_support.h"
|
||||
|
||||
/* Haiku doesn't expose font language data in BFont objects. Thus, we
|
||||
select a few representative characters for each supported `:lang'
|
||||
(currently Chinese, Korean and Japanese,) and test for those
|
||||
instead. */
|
||||
|
||||
static uint32_t language_code_points[MAX_LANGUAGE][4] =
|
||||
{{20154, 20754, 22996, 0}, /* Chinese. */
|
||||
{51312, 49440, 44544, 0}, /* Korean. */
|
||||
{26085, 26412, 12371, 0}, /* Japanese. */};
|
||||
|
||||
static void
|
||||
estimate_font_ascii (BFont *font, int *max_width,
|
||||
int *min_width, int *avg_width)
|
||||
{
|
||||
char ch[2];
|
||||
bool tems[1];
|
||||
int total = 0;
|
||||
int count = 0;
|
||||
int min = 0;
|
||||
int max = 0;
|
||||
|
||||
std::memset (ch, 0, sizeof ch);
|
||||
for (ch[0] = 32; ch[0] < 127; ++ch[0])
|
||||
{
|
||||
tems[0] = false;
|
||||
font->GetHasGlyphs (ch, 1, tems);
|
||||
if (tems[0])
|
||||
{
|
||||
int w = font->StringWidth (ch);
|
||||
++count;
|
||||
total += w;
|
||||
|
||||
if (!min || min > w)
|
||||
min = w;
|
||||
if (max < w)
|
||||
max = w;
|
||||
}
|
||||
}
|
||||
|
||||
*min_width = min;
|
||||
*max_width = max;
|
||||
*avg_width = total / count;
|
||||
}
|
||||
|
||||
void
|
||||
BFont_close (void *font)
|
||||
{
|
||||
if (font != (void *) be_fixed_font &&
|
||||
font != (void *) be_plain_font &&
|
||||
font != (void *) be_bold_font)
|
||||
delete (BFont *) font;
|
||||
}
|
||||
|
||||
void
|
||||
BFont_dat (void *font, int *px_size, int *min_width, int *max_width,
|
||||
int *avg_width, int *height, int *space_width, int *ascent,
|
||||
int *descent, int *underline_position, int *underline_thickness)
|
||||
{
|
||||
BFont *ft = (BFont *) font;
|
||||
struct font_height fheight;
|
||||
bool have_space_p;
|
||||
|
||||
char atem[1];
|
||||
bool otem[1];
|
||||
|
||||
ft->GetHeight (&fheight);
|
||||
atem[0] = ' ';
|
||||
otem[0] = false;
|
||||
ft->GetHasGlyphs (atem, 1, otem);
|
||||
have_space_p = otem[0];
|
||||
|
||||
estimate_font_ascii (ft, max_width, min_width, avg_width);
|
||||
*ascent = std::lrint (fheight.ascent);
|
||||
*descent = std::lrint (fheight.descent);
|
||||
*height = *ascent + *descent;
|
||||
|
||||
*space_width = have_space_p ? ft->StringWidth (" ") : 0;
|
||||
|
||||
*px_size = std::lrint (ft->Size ());
|
||||
*underline_position = 0;
|
||||
*underline_thickness = 0;
|
||||
}
|
||||
|
||||
/* Return non-null if FONT contains CHR, a Unicode code-point. */
|
||||
int
|
||||
BFont_have_char_p (void *font, int32_t chr)
|
||||
{
|
||||
BFont *ft = (BFont *) font;
|
||||
return ft->IncludesBlock (chr, chr);
|
||||
}
|
||||
|
||||
/* Return non-null if font contains a block from BEG to END. */
|
||||
int
|
||||
BFont_have_char_block (void *font, int32_t beg, int32_t end)
|
||||
{
|
||||
BFont *ft = (BFont *) font;
|
||||
return ft->IncludesBlock (beg, end);
|
||||
}
|
||||
|
||||
/* Compute bounds for MB_STR, a character in multibyte encoding,
|
||||
used with font. The width (in pixels) is returned in ADVANCE,
|
||||
the left bearing in LB, and the right bearing in RB. */
|
||||
void
|
||||
BFont_char_bounds (void *font, const char *mb_str, int *advance,
|
||||
int *lb, int *rb)
|
||||
{
|
||||
BFont *ft = (BFont *) font;
|
||||
edge_info edge_info;
|
||||
float size, escapement;
|
||||
size = ft->Size ();
|
||||
|
||||
ft->GetEdges (mb_str, 1, &edge_info);
|
||||
ft->GetEscapements (mb_str, 1, &escapement);
|
||||
*advance = std::lrint (escapement * size);
|
||||
*lb = std::lrint (edge_info.left * size);
|
||||
*rb = *advance + std::lrint (edge_info.right * size);
|
||||
}
|
||||
|
||||
/* The same, but for a variable amount of chars. */
|
||||
void
|
||||
BFont_nchar_bounds (void *font, const char *mb_str, int *advance,
|
||||
int *lb, int *rb, int32_t n)
|
||||
{
|
||||
BFont *ft = (BFont *) font;
|
||||
edge_info edge_info[n];
|
||||
float size;
|
||||
float escapement[n];
|
||||
|
||||
size = ft->Size ();
|
||||
|
||||
ft->GetEdges (mb_str, n, edge_info);
|
||||
ft->GetEscapements (mb_str, n, (float *) escapement);
|
||||
|
||||
for (int32_t i = 0; i < n; ++i)
|
||||
{
|
||||
advance[i] = std::lrint (escapement[i] * size);
|
||||
lb[i] = advance[i] - std::lrint (edge_info[i].left * size);
|
||||
rb[i] = advance[i] + std::lrint (edge_info[i].right * size);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
font_style_to_flags (char *st, struct haiku_font_pattern *pattern)
|
||||
{
|
||||
char *style = strdup (st);
|
||||
char *token;
|
||||
pattern->weight = -1;
|
||||
pattern->width = NO_WIDTH;
|
||||
pattern->slant = NO_SLANT;
|
||||
int tok = 0;
|
||||
|
||||
while ((token = std::strtok (!tok ? style : NULL, " ")) && tok < 3)
|
||||
{
|
||||
if (token && !strcmp (token, "Thin"))
|
||||
pattern->weight = HAIKU_THIN;
|
||||
else if (token && !strcmp (token, "UltraLight"))
|
||||
pattern->weight = HAIKU_ULTRALIGHT;
|
||||
else if (token && !strcmp (token, "ExtraLight"))
|
||||
pattern->weight = HAIKU_EXTRALIGHT;
|
||||
else if (token && !strcmp (token, "Light"))
|
||||
pattern->weight = HAIKU_LIGHT;
|
||||
else if (token && !strcmp (token, "SemiLight"))
|
||||
pattern->weight = HAIKU_SEMI_LIGHT;
|
||||
else if (token && !strcmp (token, "Regular"))
|
||||
{
|
||||
if (pattern->slant == NO_SLANT)
|
||||
pattern->slant = SLANT_REGULAR;
|
||||
|
||||
if (pattern->width == NO_WIDTH)
|
||||
pattern->width = NORMAL_WIDTH;
|
||||
|
||||
if (pattern->weight == -1)
|
||||
pattern->weight = HAIKU_REGULAR;
|
||||
}
|
||||
else if (token && !strcmp (token, "SemiBold"))
|
||||
pattern->weight = HAIKU_SEMI_BOLD;
|
||||
else if (token && !strcmp (token, "Bold"))
|
||||
pattern->weight = HAIKU_BOLD;
|
||||
else if (token && (!strcmp (token, "ExtraBold") ||
|
||||
/* This has actually been seen in the wild. */
|
||||
!strcmp (token, "Extrabold")))
|
||||
pattern->weight = HAIKU_EXTRA_BOLD;
|
||||
else if (token && !strcmp (token, "UltraBold"))
|
||||
pattern->weight = HAIKU_ULTRA_BOLD;
|
||||
else if (token && !strcmp (token, "Book"))
|
||||
pattern->weight = HAIKU_BOOK;
|
||||
else if (token && !strcmp (token, "Heavy"))
|
||||
pattern->weight = HAIKU_HEAVY;
|
||||
else if (token && !strcmp (token, "UltraHeavy"))
|
||||
pattern->weight = HAIKU_ULTRA_HEAVY;
|
||||
else if (token && !strcmp (token, "Black"))
|
||||
pattern->weight = HAIKU_BLACK;
|
||||
else if (token && !strcmp (token, "Medium"))
|
||||
pattern->weight = HAIKU_MEDIUM;
|
||||
else if (token && !strcmp (token, "Oblique"))
|
||||
pattern->slant = SLANT_OBLIQUE;
|
||||
else if (token && !strcmp (token, "Italic"))
|
||||
pattern->slant = SLANT_ITALIC;
|
||||
else if (token && !strcmp (token, "UltraCondensed"))
|
||||
pattern->width = ULTRA_CONDENSED;
|
||||
else if (token && !strcmp (token, "ExtraCondensed"))
|
||||
pattern->width = EXTRA_CONDENSED;
|
||||
else if (token && !strcmp (token, "Condensed"))
|
||||
pattern->width = CONDENSED;
|
||||
else if (token && !strcmp (token, "SemiCondensed"))
|
||||
pattern->width = SEMI_CONDENSED;
|
||||
else if (token && !strcmp (token, "SemiExpanded"))
|
||||
pattern->width = SEMI_EXPANDED;
|
||||
else if (token && !strcmp (token, "Expanded"))
|
||||
pattern->width = EXPANDED;
|
||||
else if (token && !strcmp (token, "ExtraExpanded"))
|
||||
pattern->width = EXTRA_EXPANDED;
|
||||
else if (token && !strcmp (token, "UltraExpanded"))
|
||||
pattern->width = ULTRA_EXPANDED;
|
||||
else
|
||||
{
|
||||
tok = 1000;
|
||||
break;
|
||||
}
|
||||
tok++;
|
||||
}
|
||||
|
||||
if (pattern->weight != -1)
|
||||
pattern->specified |= FSPEC_WEIGHT;
|
||||
if (pattern->slant != NO_SLANT)
|
||||
pattern->specified |= FSPEC_SLANT;
|
||||
if (pattern->width != NO_WIDTH)
|
||||
pattern->specified |= FSPEC_WIDTH;
|
||||
|
||||
if (tok > 3)
|
||||
{
|
||||
pattern->specified &= ~FSPEC_SLANT;
|
||||
pattern->specified &= ~FSPEC_WEIGHT;
|
||||
pattern->specified &= ~FSPEC_WIDTH;
|
||||
pattern->specified |= FSPEC_STYLE;
|
||||
std::strncpy ((char *) &pattern->style, st,
|
||||
sizeof pattern->style - 1);
|
||||
}
|
||||
|
||||
free (style);
|
||||
}
|
||||
|
||||
static bool
|
||||
font_check_wanted_chars (struct haiku_font_pattern *pattern, font_family family,
|
||||
char *style)
|
||||
{
|
||||
BFont ft;
|
||||
|
||||
if (ft.SetFamilyAndStyle (family, style) != B_OK)
|
||||
return false;
|
||||
|
||||
for (int i = 0; i < pattern->want_chars_len; ++i)
|
||||
if (!ft.IncludesBlock (pattern->wanted_chars[i],
|
||||
pattern->wanted_chars[i]))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
font_check_one_of (struct haiku_font_pattern *pattern, font_family family,
|
||||
char *style)
|
||||
{
|
||||
BFont ft;
|
||||
|
||||
if (ft.SetFamilyAndStyle (family, style) != B_OK)
|
||||
return false;
|
||||
|
||||
for (int i = 0; i < pattern->need_one_of_len; ++i)
|
||||
if (ft.IncludesBlock (pattern->need_one_of[i],
|
||||
pattern->need_one_of[i]))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool
|
||||
font_check_language (struct haiku_font_pattern *pattern, font_family family,
|
||||
char *style)
|
||||
{
|
||||
BFont ft;
|
||||
|
||||
if (ft.SetFamilyAndStyle (family, style) != B_OK)
|
||||
return false;
|
||||
|
||||
if (pattern->language == MAX_LANGUAGE)
|
||||
return false;
|
||||
|
||||
for (uint32_t *ch = (uint32_t *)
|
||||
&language_code_points[pattern->language]; *ch; ch++)
|
||||
if (!ft.IncludesBlock (*ch, *ch))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
font_family_style_matches_p (font_family family, char *style, uint32_t flags,
|
||||
struct haiku_font_pattern *pattern,
|
||||
int ignore_flags_p = 0)
|
||||
{
|
||||
struct haiku_font_pattern m;
|
||||
m.specified = 0;
|
||||
|
||||
if (style)
|
||||
font_style_to_flags (style, &m);
|
||||
|
||||
if ((pattern->specified & FSPEC_FAMILY) &&
|
||||
strcmp ((char *) &pattern->family, family))
|
||||
return false;
|
||||
|
||||
if (!ignore_flags_p && (pattern->specified & FSPEC_SPACING) &&
|
||||
!(pattern->mono_spacing_p) != !(flags & B_IS_FIXED))
|
||||
return false;
|
||||
|
||||
if (pattern->specified & FSPEC_STYLE)
|
||||
return style && !strcmp (style, pattern->style);
|
||||
|
||||
if ((pattern->specified & FSPEC_WEIGHT)
|
||||
&& (pattern->weight
|
||||
!= ((m.specified & FSPEC_WEIGHT) ? m.weight : HAIKU_REGULAR)))
|
||||
return false;
|
||||
|
||||
if ((pattern->specified & FSPEC_SLANT)
|
||||
&& (pattern->slant
|
||||
!= ((m.specified & FSPEC_SLANT) ? m.slant : SLANT_REGULAR)))
|
||||
return false;
|
||||
|
||||
if ((pattern->specified & FSPEC_WANTED)
|
||||
&& !font_check_wanted_chars (pattern, family, style))
|
||||
return false;
|
||||
|
||||
if ((pattern->specified & FSPEC_WIDTH)
|
||||
&& (pattern->width !=
|
||||
((m.specified & FSPEC_WIDTH) ? m.width : NORMAL_WIDTH)))
|
||||
return false;
|
||||
|
||||
if ((pattern->specified & FSPEC_NEED_ONE_OF)
|
||||
&& !font_check_one_of (pattern, family, style))
|
||||
return false;
|
||||
|
||||
if ((pattern->specified & FSPEC_LANGUAGE)
|
||||
&& !font_check_language (pattern, family, style))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
haiku_font_fill_pattern (struct haiku_font_pattern *pattern,
|
||||
font_family family, char *style,
|
||||
uint32_t flags)
|
||||
{
|
||||
if (style)
|
||||
font_style_to_flags (style, pattern);
|
||||
|
||||
pattern->specified |= FSPEC_FAMILY;
|
||||
std::strncpy (pattern->family, family,
|
||||
sizeof pattern->family - 1);
|
||||
pattern->specified |= FSPEC_SPACING;
|
||||
pattern->mono_spacing_p = flags & B_IS_FIXED;
|
||||
}
|
||||
|
||||
/* Delete every element of the font pattern PT. */
|
||||
void
|
||||
haiku_font_pattern_free (struct haiku_font_pattern *pt)
|
||||
{
|
||||
struct haiku_font_pattern *tem = pt;
|
||||
while (tem)
|
||||
{
|
||||
struct haiku_font_pattern *t = tem;
|
||||
tem = t->next;
|
||||
delete t;
|
||||
}
|
||||
}
|
||||
|
||||
/* Find all fonts matching the font pattern PT. */
|
||||
struct haiku_font_pattern *
|
||||
BFont_find (struct haiku_font_pattern *pt)
|
||||
{
|
||||
struct haiku_font_pattern *r = NULL;
|
||||
font_family name;
|
||||
font_style sname;
|
||||
uint32 flags;
|
||||
int sty_count;
|
||||
int fam_count = count_font_families ();
|
||||
|
||||
for (int fi = 0; fi < fam_count; ++fi)
|
||||
{
|
||||
if (get_font_family (fi, &name, &flags) == B_OK)
|
||||
{
|
||||
sty_count = count_font_styles (name);
|
||||
if (!sty_count &&
|
||||
font_family_style_matches_p (name, NULL, flags, pt))
|
||||
{
|
||||
struct haiku_font_pattern *p = new struct haiku_font_pattern;
|
||||
p->specified = 0;
|
||||
p->oblique_seen_p = 1;
|
||||
haiku_font_fill_pattern (p, name, NULL, flags);
|
||||
p->next = r;
|
||||
if (p->next)
|
||||
p->next->last = p;
|
||||
p->last = NULL;
|
||||
p->next_family = r;
|
||||
r = p;
|
||||
}
|
||||
else if (sty_count)
|
||||
{
|
||||
for (int si = 0; si < sty_count; ++si)
|
||||
{
|
||||
int oblique_seen_p = 0;
|
||||
struct haiku_font_pattern *head = r;
|
||||
struct haiku_font_pattern *p = NULL;
|
||||
|
||||
if (get_font_style (name, si, &sname, &flags) == B_OK)
|
||||
{
|
||||
if (font_family_style_matches_p (name, (char *) &sname, flags, pt))
|
||||
{
|
||||
p = new struct haiku_font_pattern;
|
||||
p->specified = 0;
|
||||
haiku_font_fill_pattern (p, name, (char *) &sname, flags);
|
||||
if (p->specified & FSPEC_SLANT &&
|
||||
((p->slant == SLANT_OBLIQUE) || (p->slant == SLANT_ITALIC)))
|
||||
oblique_seen_p = 1;
|
||||
|
||||
p->next = r;
|
||||
if (p->next)
|
||||
p->next->last = p;
|
||||
r = p;
|
||||
p->next_family = head;
|
||||
}
|
||||
}
|
||||
|
||||
if (p)
|
||||
p->last = NULL;
|
||||
|
||||
for (; head; head = head->last)
|
||||
{
|
||||
head->oblique_seen_p = oblique_seen_p;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* There's a very good chance that this result will get cached if no
|
||||
slant is specified. Thus, we look through each font that hasn't
|
||||
seen an oblique style, and add one. */
|
||||
|
||||
if (!(pt->specified & FSPEC_SLANT))
|
||||
{
|
||||
/* r->last is invalid from here onwards. */
|
||||
for (struct haiku_font_pattern *p = r; p;)
|
||||
{
|
||||
if (!p->oblique_seen_p)
|
||||
{
|
||||
struct haiku_font_pattern *n = new haiku_font_pattern;
|
||||
*n = *p;
|
||||
n->slant = SLANT_OBLIQUE;
|
||||
p->next = n;
|
||||
p = p->next_family;
|
||||
}
|
||||
else
|
||||
p = p->next_family;
|
||||
}
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Find and open a font matching the pattern PAT, which must have its
|
||||
family set. */
|
||||
int
|
||||
BFont_open_pattern (struct haiku_font_pattern *pat, void **font, float size)
|
||||
{
|
||||
int sty_count;
|
||||
font_family name;
|
||||
font_style sname;
|
||||
uint32 flags = 0;
|
||||
if (!(pat->specified & FSPEC_FAMILY))
|
||||
return 1;
|
||||
strncpy (name, pat->family, sizeof name - 1);
|
||||
sty_count = count_font_styles (name);
|
||||
|
||||
if (!sty_count &&
|
||||
font_family_style_matches_p (name, NULL, flags, pat, 1))
|
||||
{
|
||||
BFont *ft = new BFont;
|
||||
if (ft->SetFamilyAndStyle (name, NULL) != B_OK)
|
||||
{
|
||||
delete ft;
|
||||
return 1;
|
||||
}
|
||||
ft->SetSize (size);
|
||||
ft->SetEncoding (B_UNICODE_UTF8);
|
||||
ft->SetSpacing (B_BITMAP_SPACING);
|
||||
*font = (void *) ft;
|
||||
return 0;
|
||||
}
|
||||
else if (sty_count)
|
||||
{
|
||||
for (int si = 0; si < sty_count; ++si)
|
||||
{
|
||||
if (get_font_style (name, si, &sname, &flags) == B_OK &&
|
||||
font_family_style_matches_p (name, (char *) &sname, flags, pat))
|
||||
{
|
||||
BFont *ft = new BFont;
|
||||
if (ft->SetFamilyAndStyle (name, sname) != B_OK)
|
||||
{
|
||||
delete ft;
|
||||
return 1;
|
||||
}
|
||||
ft->SetSize (size);
|
||||
ft->SetEncoding (B_UNICODE_UTF8);
|
||||
ft->SetSpacing (B_BITMAP_SPACING);
|
||||
*font = (void *) ft;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pat->specified & FSPEC_SLANT && pat->slant == SLANT_OBLIQUE)
|
||||
{
|
||||
struct haiku_font_pattern copy = *pat;
|
||||
copy.slant = SLANT_REGULAR;
|
||||
int code = BFont_open_pattern (©, font, size);
|
||||
if (code)
|
||||
return code;
|
||||
BFont *ft = (BFont *) *font;
|
||||
/* XXX Font measurements don't respect shear. Haiku bug?
|
||||
This apparently worked in BeOS.
|
||||
ft->SetShear (100.0); */
|
||||
ft->SetFace (B_ITALIC_FACE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Query the family of the default fixed font. */
|
||||
void
|
||||
BFont_populate_fixed_family (struct haiku_font_pattern *ptn)
|
||||
{
|
||||
font_family f;
|
||||
font_style s;
|
||||
be_fixed_font->GetFamilyAndStyle (&f, &s);
|
||||
|
||||
ptn->specified |= FSPEC_FAMILY;
|
||||
strncpy (ptn->family, f, sizeof ptn->family - 1);
|
||||
}
|
||||
|
||||
void
|
||||
BFont_populate_plain_family (struct haiku_font_pattern *ptn)
|
||||
{
|
||||
font_family f;
|
||||
font_style s;
|
||||
be_plain_font->GetFamilyAndStyle (&f, &s);
|
||||
|
||||
ptn->specified |= FSPEC_FAMILY;
|
||||
strncpy (ptn->family, f, sizeof ptn->family - 1);
|
||||
}
|
||||
|
||||
int
|
||||
BFont_string_width (void *font, const char *utf8)
|
||||
{
|
||||
return ((BFont *) font)->StringWidth (utf8);
|
||||
}
|
207
src/haiku_io.c
Normal file
207
src/haiku_io.c
Normal file
|
@ -0,0 +1,207 @@
|
|||
/* Haiku window system support.
|
||||
Copyright (C) 2021 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Emacs.
|
||||
|
||||
GNU Emacs 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.
|
||||
|
||||
GNU Emacs 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 GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <OS.h>
|
||||
|
||||
#include "haiku_support.h"
|
||||
#include "lisp.h"
|
||||
#include "haikuterm.h"
|
||||
#include "blockinput.h"
|
||||
|
||||
#define PORT_CAP 1200
|
||||
|
||||
/* The port used to send messages from the application thread to
|
||||
Emacs. */
|
||||
port_id port_application_to_emacs;
|
||||
|
||||
void
|
||||
haiku_io_init (void)
|
||||
{
|
||||
port_application_to_emacs = create_port (PORT_CAP, "application emacs port");
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
haiku_len (enum haiku_event_type type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case QUIT_REQUESTED:
|
||||
return sizeof (struct haiku_quit_requested_event);
|
||||
case FRAME_RESIZED:
|
||||
return sizeof (struct haiku_resize_event);
|
||||
case FRAME_EXPOSED:
|
||||
return sizeof (struct haiku_expose_event);
|
||||
case KEY_DOWN:
|
||||
case KEY_UP:
|
||||
return sizeof (struct haiku_key_event);
|
||||
case ACTIVATION:
|
||||
return sizeof (struct haiku_activation_event);
|
||||
case MOUSE_MOTION:
|
||||
return sizeof (struct haiku_mouse_motion_event);
|
||||
case BUTTON_DOWN:
|
||||
case BUTTON_UP:
|
||||
return sizeof (struct haiku_button_event);
|
||||
case ICONIFICATION:
|
||||
return sizeof (struct haiku_iconification_event);
|
||||
case MOVE_EVENT:
|
||||
return sizeof (struct haiku_move_event);
|
||||
case SCROLL_BAR_VALUE_EVENT:
|
||||
return sizeof (struct haiku_scroll_bar_value_event);
|
||||
case SCROLL_BAR_DRAG_EVENT:
|
||||
return sizeof (struct haiku_scroll_bar_drag_event);
|
||||
case WHEEL_MOVE_EVENT:
|
||||
return sizeof (struct haiku_wheel_move_event);
|
||||
case MENU_BAR_RESIZE:
|
||||
return sizeof (struct haiku_menu_bar_resize_event);
|
||||
case MENU_BAR_OPEN:
|
||||
case MENU_BAR_CLOSE:
|
||||
return sizeof (struct haiku_menu_bar_state_event);
|
||||
case MENU_BAR_SELECT_EVENT:
|
||||
return sizeof (struct haiku_menu_bar_select_event);
|
||||
case FILE_PANEL_EVENT:
|
||||
return sizeof (struct haiku_file_panel_event);
|
||||
case MENU_BAR_HELP_EVENT:
|
||||
return sizeof (struct haiku_menu_bar_help_event);
|
||||
case ZOOM_EVENT:
|
||||
return sizeof (struct haiku_zoom_event);
|
||||
case REFS_EVENT:
|
||||
return sizeof (struct haiku_refs_event);
|
||||
case APP_QUIT_REQUESTED_EVENT:
|
||||
return sizeof (struct haiku_app_quit_requested_event);
|
||||
}
|
||||
|
||||
emacs_abort ();
|
||||
}
|
||||
|
||||
/* Read the size of the next message into len, returning -1 if the
|
||||
query fails or there is no next message. */
|
||||
void
|
||||
haiku_read_size (ssize_t *len)
|
||||
{
|
||||
port_id from = port_application_to_emacs;
|
||||
ssize_t size;
|
||||
|
||||
size = port_buffer_size_etc (from, B_TIMEOUT, 0);
|
||||
|
||||
if (size < B_OK)
|
||||
*len = -1;
|
||||
else
|
||||
*len = size;
|
||||
}
|
||||
|
||||
/* Read the next message into BUF, putting its type into TYPE,
|
||||
assuming the message is at most LEN long. Return 0 if successful
|
||||
and -1 if the read fails. */
|
||||
int
|
||||
haiku_read (enum haiku_event_type *type, void *buf, ssize_t len)
|
||||
{
|
||||
int32 typ;
|
||||
port_id from = port_application_to_emacs;
|
||||
|
||||
if (read_port (from, &typ, buf, len) < B_OK)
|
||||
return -1;
|
||||
|
||||
*type = (enum haiku_event_type) typ;
|
||||
eassert (len >= haiku_len (typ));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* The same as haiku_read, but time out after TIMEOUT microseconds.
|
||||
Input is blocked when an attempt to read is in progress. */
|
||||
int
|
||||
haiku_read_with_timeout (enum haiku_event_type *type, void *buf, ssize_t len,
|
||||
time_t timeout)
|
||||
{
|
||||
int32 typ;
|
||||
port_id from = port_application_to_emacs;
|
||||
|
||||
block_input ();
|
||||
if (read_port_etc (from, &typ, buf, len,
|
||||
B_TIMEOUT, (bigtime_t) timeout) < B_OK)
|
||||
{
|
||||
unblock_input ();
|
||||
return -1;
|
||||
}
|
||||
unblock_input ();
|
||||
*type = (enum haiku_event_type) typ;
|
||||
eassert (len >= haiku_len (typ));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Write a message with type TYPE into BUF. */
|
||||
int
|
||||
haiku_write (enum haiku_event_type type, void *buf)
|
||||
{
|
||||
port_id to = port_application_to_emacs;
|
||||
|
||||
if (write_port (to, (int32_t) type, buf, haiku_len (type)) < B_OK)
|
||||
return -1;
|
||||
|
||||
kill (getpid (), SIGPOLL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
haiku_write_without_signal (enum haiku_event_type type, void *buf)
|
||||
{
|
||||
port_id to = port_application_to_emacs;
|
||||
|
||||
if (write_port (to, (int32_t) type, buf, haiku_len (type)) < B_OK)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
haiku_io_init_in_app_thread (void)
|
||||
{
|
||||
sigset_t set;
|
||||
sigfillset (&set);
|
||||
|
||||
if (pthread_sigmask (SIG_BLOCK, &set, NULL))
|
||||
perror ("pthread_sigmask");
|
||||
}
|
||||
|
||||
/* Record an unwind protect from C++ code. */
|
||||
void
|
||||
record_c_unwind_protect_from_cxx (void (*fn) (void *), void *r)
|
||||
{
|
||||
record_unwind_protect_ptr (fn, r);
|
||||
}
|
||||
|
||||
/* SPECPDL_IDX that is safe from C++ code. */
|
||||
ptrdiff_t
|
||||
c_specpdl_idx_from_cxx (void)
|
||||
{
|
||||
return SPECPDL_INDEX ();
|
||||
}
|
||||
|
||||
/* unbind_to (IDX, Qnil), but safe from C++ code. */
|
||||
void
|
||||
c_unbind_to_nil_from_cxx (ptrdiff_t idx)
|
||||
{
|
||||
unbind_to (idx, Qnil);
|
||||
}
|
155
src/haiku_select.cc
Normal file
155
src/haiku_select.cc
Normal file
|
@ -0,0 +1,155 @@
|
|||
/* Haiku window system selection support. Hey Emacs, this is -*- C++ -*-
|
||||
Copyright (C) 2021 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Emacs.
|
||||
|
||||
GNU Emacs 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.
|
||||
|
||||
GNU Emacs 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 GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <Clipboard.h>
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
#include "haikuselect.h"
|
||||
|
||||
|
||||
static BClipboard *primary = NULL;
|
||||
static BClipboard *secondary = NULL;
|
||||
static BClipboard *system_clipboard = NULL;
|
||||
|
||||
int selection_state_flag;
|
||||
|
||||
static char *
|
||||
BClipboard_find_data (BClipboard *cb, const char *type, ssize_t *len)
|
||||
{
|
||||
if (!cb->Lock ())
|
||||
return 0;
|
||||
|
||||
BMessage *dat = cb->Data ();
|
||||
if (!dat)
|
||||
{
|
||||
cb->Unlock ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *ptr;
|
||||
ssize_t bt;
|
||||
dat->FindData (type, B_MIME_TYPE, (const void **) &ptr, &bt);
|
||||
|
||||
if (!ptr)
|
||||
{
|
||||
cb->Unlock ();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (len)
|
||||
*len = bt;
|
||||
|
||||
cb->Unlock ();
|
||||
|
||||
return strndup (ptr, bt);
|
||||
}
|
||||
|
||||
static void
|
||||
BClipboard_set_data (BClipboard *cb, const char *type, const char *dat,
|
||||
ssize_t len)
|
||||
{
|
||||
if (!cb->Lock ())
|
||||
return;
|
||||
cb->Clear ();
|
||||
BMessage *mdat = cb->Data ();
|
||||
if (!mdat)
|
||||
{
|
||||
cb->Unlock ();
|
||||
return;
|
||||
}
|
||||
|
||||
if (dat)
|
||||
mdat->AddData (type, B_MIME_TYPE, dat, len);
|
||||
cb->Commit ();
|
||||
cb->Unlock ();
|
||||
}
|
||||
|
||||
char *
|
||||
BClipboard_find_system_data (const char *type, ssize_t *len)
|
||||
{
|
||||
if (!system_clipboard)
|
||||
return 0;
|
||||
|
||||
return BClipboard_find_data (system_clipboard, type, len);
|
||||
}
|
||||
|
||||
char *
|
||||
BClipboard_find_primary_selection_data (const char *type, ssize_t *len)
|
||||
{
|
||||
if (!primary)
|
||||
return 0;
|
||||
|
||||
return BClipboard_find_data (primary, type, len);
|
||||
}
|
||||
|
||||
char *
|
||||
BClipboard_find_secondary_selection_data (const char *type, ssize_t *len)
|
||||
{
|
||||
if (!secondary)
|
||||
return 0;
|
||||
|
||||
return BClipboard_find_data (secondary, type, len);
|
||||
}
|
||||
|
||||
void
|
||||
BClipboard_set_system_data (const char *type, const char *data,
|
||||
ssize_t len)
|
||||
{
|
||||
if (!system_clipboard)
|
||||
return;
|
||||
|
||||
BClipboard_set_data (system_clipboard, type, data, len);
|
||||
}
|
||||
|
||||
void
|
||||
BClipboard_set_primary_selection_data (const char *type, const char *data,
|
||||
ssize_t len)
|
||||
{
|
||||
if (!primary)
|
||||
return;
|
||||
|
||||
BClipboard_set_data (primary, type, data, len);
|
||||
}
|
||||
|
||||
void
|
||||
BClipboard_set_secondary_selection_data (const char *type, const char *data,
|
||||
ssize_t len)
|
||||
{
|
||||
if (!secondary)
|
||||
return;
|
||||
|
||||
BClipboard_set_data (secondary, type, data, len);
|
||||
}
|
||||
|
||||
void
|
||||
BClipboard_free_data (void *ptr)
|
||||
{
|
||||
std::free (ptr);
|
||||
}
|
||||
|
||||
void
|
||||
init_haiku_select (void)
|
||||
{
|
||||
system_clipboard = new BClipboard ("system");
|
||||
primary = new BClipboard ("primary");
|
||||
secondary = new BClipboard ("secondary");
|
||||
}
|
2930
src/haiku_support.cc
Normal file
2930
src/haiku_support.cc
Normal file
File diff suppressed because it is too large
Load diff
869
src/haiku_support.h
Normal file
869
src/haiku_support.h
Normal file
|
@ -0,0 +1,869 @@
|
|||
/* Haiku window system support. Hey Emacs, this is -*- C++ -*-
|
||||
Copyright (C) 2021 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Emacs.
|
||||
|
||||
GNU Emacs 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.
|
||||
|
||||
GNU Emacs 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 GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef _HAIKU_SUPPORT_H
|
||||
#define _HAIKU_SUPPORT_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef HAVE_FREETYPE
|
||||
#include <ft2build.h>
|
||||
#include <fontconfig/fontconfig.h>
|
||||
#include FT_FREETYPE_H
|
||||
#include FT_SIZES_H
|
||||
#endif
|
||||
|
||||
#ifdef USE_BE_CAIRO
|
||||
#include <cairo.h>
|
||||
#endif
|
||||
|
||||
enum haiku_cursor
|
||||
{
|
||||
CURSOR_ID_NO_CURSOR = 12,
|
||||
CURSOR_ID_RESIZE_NORTH = 15,
|
||||
CURSOR_ID_RESIZE_EAST = 16,
|
||||
CURSOR_ID_RESIZE_SOUTH = 17,
|
||||
CURSOR_ID_RESIZE_WEST = 18,
|
||||
CURSOR_ID_RESIZE_NORTH_EAST = 19,
|
||||
CURSOR_ID_RESIZE_NORTH_WEST = 20,
|
||||
CURSOR_ID_RESIZE_SOUTH_EAST = 21,
|
||||
CURSOR_ID_RESIZE_SOUTH_WEST = 22,
|
||||
CURSOR_ID_RESIZE_NORTH_SOUTH = 23,
|
||||
CURSOR_ID_RESIZE_EAST_WEST = 24,
|
||||
CURSOR_ID_RESIZE_NORTH_EAST_SOUTH_WEST = 25,
|
||||
CURSOR_ID_RESIZE_NORTH_WEST_SOUTH_EAST = 26
|
||||
};
|
||||
|
||||
enum haiku_alert_type
|
||||
{
|
||||
HAIKU_EMPTY_ALERT = 0,
|
||||
HAIKU_INFO_ALERT,
|
||||
HAIKU_IDEA_ALERT,
|
||||
HAIKU_WARNING_ALERT,
|
||||
HAIKU_STOP_ALERT
|
||||
};
|
||||
|
||||
enum haiku_event_type
|
||||
{
|
||||
QUIT_REQUESTED,
|
||||
FRAME_RESIZED,
|
||||
FRAME_EXPOSED,
|
||||
KEY_DOWN,
|
||||
KEY_UP,
|
||||
ACTIVATION,
|
||||
MOUSE_MOTION,
|
||||
BUTTON_DOWN,
|
||||
BUTTON_UP,
|
||||
ICONIFICATION,
|
||||
MOVE_EVENT,
|
||||
SCROLL_BAR_VALUE_EVENT,
|
||||
SCROLL_BAR_DRAG_EVENT,
|
||||
WHEEL_MOVE_EVENT,
|
||||
MENU_BAR_RESIZE,
|
||||
MENU_BAR_OPEN,
|
||||
MENU_BAR_SELECT_EVENT,
|
||||
MENU_BAR_CLOSE,
|
||||
FILE_PANEL_EVENT,
|
||||
MENU_BAR_HELP_EVENT,
|
||||
ZOOM_EVENT,
|
||||
REFS_EVENT,
|
||||
APP_QUIT_REQUESTED_EVENT
|
||||
};
|
||||
|
||||
struct haiku_quit_requested_event
|
||||
{
|
||||
void *window;
|
||||
};
|
||||
|
||||
struct haiku_resize_event
|
||||
{
|
||||
void *window;
|
||||
float px_heightf;
|
||||
float px_widthf;
|
||||
};
|
||||
|
||||
struct haiku_expose_event
|
||||
{
|
||||
void *window;
|
||||
int x;
|
||||
int y;
|
||||
int width;
|
||||
int height;
|
||||
};
|
||||
|
||||
struct haiku_refs_event
|
||||
{
|
||||
void *window;
|
||||
int x, y;
|
||||
/* Free this with free! */
|
||||
char *ref;
|
||||
};
|
||||
|
||||
struct haiku_app_quit_requested_event
|
||||
{
|
||||
char dummy;
|
||||
};
|
||||
|
||||
#define HAIKU_MODIFIER_ALT (1)
|
||||
#define HAIKU_MODIFIER_CTRL (1 << 1)
|
||||
#define HAIKU_MODIFIER_SHIFT (1 << 2)
|
||||
#define HAIKU_MODIFIER_SUPER (1 << 3)
|
||||
|
||||
struct haiku_key_event
|
||||
{
|
||||
void *window;
|
||||
int modifiers;
|
||||
uint32_t mb_char;
|
||||
uint32_t unraw_mb_char;
|
||||
short kc;
|
||||
};
|
||||
|
||||
struct haiku_activation_event
|
||||
{
|
||||
void *window;
|
||||
int activated_p;
|
||||
};
|
||||
|
||||
struct haiku_mouse_motion_event
|
||||
{
|
||||
void *window;
|
||||
bool just_exited_p;
|
||||
int x;
|
||||
int y;
|
||||
uint32_t be_code;
|
||||
};
|
||||
|
||||
struct haiku_button_event
|
||||
{
|
||||
void *window;
|
||||
int btn_no;
|
||||
int modifiers;
|
||||
int x;
|
||||
int y;
|
||||
};
|
||||
|
||||
struct haiku_iconification_event
|
||||
{
|
||||
void *window;
|
||||
int iconified_p;
|
||||
};
|
||||
|
||||
struct haiku_move_event
|
||||
{
|
||||
void *window;
|
||||
int x;
|
||||
int y;
|
||||
};
|
||||
|
||||
struct haiku_wheel_move_event
|
||||
{
|
||||
void *window;
|
||||
int modifiers;
|
||||
float delta_x;
|
||||
float delta_y;
|
||||
};
|
||||
|
||||
struct haiku_menu_bar_select_event
|
||||
{
|
||||
void *window;
|
||||
void *ptr;
|
||||
};
|
||||
|
||||
struct haiku_file_panel_event
|
||||
{
|
||||
void *ptr;
|
||||
};
|
||||
|
||||
struct haiku_menu_bar_help_event
|
||||
{
|
||||
void *window;
|
||||
int mb_idx;
|
||||
};
|
||||
|
||||
struct haiku_zoom_event
|
||||
{
|
||||
void *window;
|
||||
int x;
|
||||
int y;
|
||||
int width;
|
||||
int height;
|
||||
};
|
||||
|
||||
#define FSPEC_FAMILY 1
|
||||
#define FSPEC_STYLE (1 << 1)
|
||||
#define FSPEC_SLANT (1 << 2)
|
||||
#define FSPEC_WEIGHT (1 << 3)
|
||||
#define FSPEC_SPACING (1 << 4)
|
||||
#define FSPEC_WANTED (1 << 5)
|
||||
#define FSPEC_NEED_ONE_OF (1 << 6)
|
||||
#define FSPEC_WIDTH (1 << 7)
|
||||
#define FSPEC_LANGUAGE (1 << 8)
|
||||
|
||||
typedef char haiku_font_family_or_style[64];
|
||||
|
||||
enum haiku_font_slant
|
||||
{
|
||||
NO_SLANT = -1,
|
||||
SLANT_OBLIQUE,
|
||||
SLANT_REGULAR,
|
||||
SLANT_ITALIC
|
||||
};
|
||||
|
||||
enum haiku_font_width
|
||||
{
|
||||
NO_WIDTH = -1,
|
||||
ULTRA_CONDENSED,
|
||||
EXTRA_CONDENSED,
|
||||
CONDENSED,
|
||||
SEMI_CONDENSED,
|
||||
NORMAL_WIDTH,
|
||||
SEMI_EXPANDED,
|
||||
EXPANDED,
|
||||
EXTRA_EXPANDED,
|
||||
ULTRA_EXPANDED
|
||||
};
|
||||
|
||||
enum haiku_font_language
|
||||
{
|
||||
LANGUAGE_CN,
|
||||
LANGUAGE_KO,
|
||||
LANGUAGE_JP,
|
||||
MAX_LANGUAGE /* This isn't a language. */
|
||||
};
|
||||
|
||||
struct haiku_font_pattern
|
||||
{
|
||||
int specified;
|
||||
struct haiku_font_pattern *next;
|
||||
/* The next two fields are only temporarily used during the font
|
||||
discovery process! Do not rely on them being correct outside
|
||||
BFont_find. */
|
||||
struct haiku_font_pattern *last;
|
||||
struct haiku_font_pattern *next_family;
|
||||
haiku_font_family_or_style family;
|
||||
haiku_font_family_or_style style;
|
||||
int weight;
|
||||
int mono_spacing_p;
|
||||
int want_chars_len;
|
||||
int need_one_of_len;
|
||||
enum haiku_font_slant slant;
|
||||
enum haiku_font_width width;
|
||||
enum haiku_font_language language;
|
||||
uint32_t *wanted_chars;
|
||||
uint32_t *need_one_of;
|
||||
|
||||
int oblique_seen_p;
|
||||
};
|
||||
|
||||
struct haiku_scroll_bar_value_event
|
||||
{
|
||||
void *scroll_bar;
|
||||
int position;
|
||||
};
|
||||
|
||||
struct haiku_scroll_bar_drag_event
|
||||
{
|
||||
void *scroll_bar;
|
||||
int dragging_p;
|
||||
};
|
||||
|
||||
struct haiku_menu_bar_resize_event
|
||||
{
|
||||
void *window;
|
||||
int width;
|
||||
int height;
|
||||
};
|
||||
|
||||
struct haiku_menu_bar_state_event
|
||||
{
|
||||
void *window;
|
||||
};
|
||||
|
||||
#define HAIKU_THIN 0
|
||||
#define HAIKU_ULTRALIGHT 20
|
||||
#define HAIKU_EXTRALIGHT 40
|
||||
#define HAIKU_LIGHT 50
|
||||
#define HAIKU_SEMI_LIGHT 75
|
||||
#define HAIKU_REGULAR 100
|
||||
#define HAIKU_SEMI_BOLD 180
|
||||
#define HAIKU_BOLD 200
|
||||
#define HAIKU_EXTRA_BOLD 205
|
||||
#define HAIKU_ULTRA_BOLD 210
|
||||
#define HAIKU_BOOK 400
|
||||
#define HAIKU_HEAVY 800
|
||||
#define HAIKU_ULTRA_HEAVY 900
|
||||
#define HAIKU_BLACK 1000
|
||||
#define HAIKU_MEDIUM 2000
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
#include <pthread.h>
|
||||
#include <OS.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
typedef void *haiku;
|
||||
|
||||
extern void
|
||||
haiku_put_pixel (haiku bitmap, int x, int y, unsigned long pixel);
|
||||
|
||||
extern unsigned long
|
||||
haiku_get_pixel (haiku bitmap, int x, int y);
|
||||
#endif
|
||||
|
||||
extern port_id port_application_to_emacs;
|
||||
|
||||
extern void haiku_io_init (void);
|
||||
extern void haiku_io_init_in_app_thread (void);
|
||||
|
||||
extern void
|
||||
haiku_read_size (ssize_t *len);
|
||||
|
||||
extern int
|
||||
haiku_read (enum haiku_event_type *type, void *buf, ssize_t len);
|
||||
|
||||
extern int
|
||||
haiku_read_with_timeout (enum haiku_event_type *type, void *buf, ssize_t len,
|
||||
time_t timeout);
|
||||
|
||||
extern int
|
||||
haiku_write (enum haiku_event_type type, void *buf);
|
||||
|
||||
extern int
|
||||
haiku_write_without_signal (enum haiku_event_type type, void *buf);
|
||||
|
||||
extern void
|
||||
rgb_color_hsl (uint32_t rgb, double *h, double *s, double *l);
|
||||
|
||||
extern void
|
||||
hsl_color_rgb (double h, double s, double l, uint32_t *rgb);
|
||||
|
||||
extern void *
|
||||
BBitmap_new (int width, int height, int mono_p);
|
||||
|
||||
extern void *
|
||||
BBitmap_data (void *bitmap);
|
||||
|
||||
extern int
|
||||
BBitmap_convert (void *bitmap, void **new_bitmap);
|
||||
|
||||
extern void
|
||||
BBitmap_free (void *bitmap);
|
||||
|
||||
extern void
|
||||
BBitmap_dimensions (void *bitmap, int *left, int *top,
|
||||
int *right, int *bottom, int32_t *bytes_per_row,
|
||||
int *mono_p);
|
||||
|
||||
extern void *
|
||||
BApplication_setup (void);
|
||||
|
||||
extern void *
|
||||
BWindow_new (void *view);
|
||||
|
||||
extern void
|
||||
BWindow_quit (void *window);
|
||||
|
||||
extern void
|
||||
BWindow_set_offset (void *window, int x, int y);
|
||||
|
||||
extern void
|
||||
BWindow_iconify (void *window);
|
||||
|
||||
extern void
|
||||
BWindow_set_visible (void *window, int visible_p);
|
||||
|
||||
extern void
|
||||
BFont_close (void *font);
|
||||
|
||||
extern void
|
||||
BFont_dat (void *font, int *px_size, int *min_width, int *max_width,
|
||||
int *avg_width, int *height, int *space_width, int *ascent,
|
||||
int *descent, int *underline_position, int *underline_thickness);
|
||||
|
||||
extern int
|
||||
BFont_have_char_p (void *font, int32_t chr);
|
||||
|
||||
extern int
|
||||
BFont_have_char_block (void *font, int32_t beg, int32_t end);
|
||||
|
||||
extern void
|
||||
BFont_char_bounds (void *font, const char *mb_str, int *advance,
|
||||
int *lb, int *rb);
|
||||
|
||||
extern void
|
||||
BFont_nchar_bounds (void *font, const char *mb_str, int *advance,
|
||||
int *lb, int *rb, int32_t n);
|
||||
|
||||
extern void
|
||||
BWindow_retitle (void *window, const char *title);
|
||||
|
||||
extern void
|
||||
BWindow_resize (void *window, int width, int height);
|
||||
|
||||
extern void
|
||||
BWindow_activate (void *window);
|
||||
|
||||
extern void
|
||||
BView_StartClip (void *view);
|
||||
|
||||
extern void
|
||||
BView_EndClip (void *view);
|
||||
|
||||
extern void
|
||||
BView_SetHighColor (void *view, uint32_t color);
|
||||
|
||||
extern void
|
||||
BView_SetHighColorForVisibleBell (void *view, uint32_t color);
|
||||
|
||||
extern void
|
||||
BView_FillRectangleForVisibleBell (void *view, int x, int y, int width,
|
||||
int height);
|
||||
|
||||
extern void
|
||||
BView_SetLowColor (void *view, uint32_t color);
|
||||
|
||||
extern void
|
||||
BView_SetPenSize (void *view, int u);
|
||||
|
||||
extern void
|
||||
BView_SetFont (void *view, void *font);
|
||||
|
||||
extern void
|
||||
BView_MovePenTo (void *view, int x, int y);
|
||||
|
||||
extern void
|
||||
BView_DrawString (void *view, const char *chr, ptrdiff_t len);
|
||||
|
||||
extern void
|
||||
BView_DrawChar (void *view, char chr);
|
||||
|
||||
extern void
|
||||
BView_FillRectangle (void *view, int x, int y, int width, int height);
|
||||
|
||||
extern void
|
||||
BView_FillRectangleAbs (void *view, int x, int y, int x1, int y1);
|
||||
|
||||
extern void
|
||||
BView_FillTriangle (void *view, int x1, int y1,
|
||||
int x2, int y2, int x3, int y3);
|
||||
|
||||
extern void
|
||||
BView_StrokeRectangle (void *view, int x, int y, int width, int height);
|
||||
|
||||
extern void
|
||||
BView_SetViewColor (void *view, uint32_t color);
|
||||
|
||||
extern void
|
||||
BView_ClipToRect (void *view, int x, int y, int width, int height);
|
||||
|
||||
extern void
|
||||
BView_ClipToInverseRect (void *view, int x, int y, int width, int height);
|
||||
|
||||
extern void
|
||||
BView_StrokeLine (void *view, int sx, int sy, int tx, int ty);
|
||||
|
||||
extern void
|
||||
BView_CopyBits (void *view, int x, int y, int width, int height,
|
||||
int tox, int toy, int towidth, int toheight);
|
||||
|
||||
extern void
|
||||
BView_DrawBitmap (void *view, void *bitmap, int x, int y,
|
||||
int width, int height, int vx, int vy, int vwidth,
|
||||
int vheight);
|
||||
|
||||
extern void
|
||||
BView_DrawBitmapWithEraseOp (void *view, void *bitmap, int x,
|
||||
int y, int width, int height);
|
||||
|
||||
extern void
|
||||
BView_DrawMask (void *src, void *view,
|
||||
int x, int y, int width, int height,
|
||||
int vx, int vy, int vwidth, int vheight,
|
||||
uint32_t color);
|
||||
|
||||
extern void *
|
||||
BBitmap_transform_bitmap (void *bitmap, void *mask, uint32_t m_color,
|
||||
double rot, int desw, int desh);
|
||||
|
||||
extern void
|
||||
BScreen_px_dim (int *width, int *height);
|
||||
|
||||
extern void
|
||||
BView_resize_to (void *view, int width, int height);
|
||||
|
||||
/* Functions for creating and freeing cursors. */
|
||||
extern void *
|
||||
BCursor_create_default (void);
|
||||
|
||||
extern void *
|
||||
BCursor_from_id (enum haiku_cursor cursor);
|
||||
|
||||
extern void *
|
||||
BCursor_create_modeline (void);
|
||||
|
||||
extern void *
|
||||
BCursor_create_i_beam (void);
|
||||
|
||||
extern void *
|
||||
BCursor_create_progress_cursor (void);
|
||||
|
||||
extern void *
|
||||
BCursor_create_grab (void);
|
||||
|
||||
extern void
|
||||
BCursor_delete (void *cursor);
|
||||
|
||||
extern void
|
||||
BView_set_view_cursor (void *view, void *cursor);
|
||||
|
||||
extern void
|
||||
BWindow_Flush (void *window);
|
||||
|
||||
extern void
|
||||
BMapKey (uint32_t kc, int *non_ascii_p, unsigned *code);
|
||||
|
||||
extern void *
|
||||
BScrollBar_make_for_view (void *view, int horizontal_p,
|
||||
int x, int y, int x1, int y1,
|
||||
void *scroll_bar_ptr);
|
||||
|
||||
extern void
|
||||
BScrollBar_delete (void *sb);
|
||||
|
||||
extern void
|
||||
BView_move_frame (void *view, int x, int y, int x1, int y1);
|
||||
|
||||
extern void
|
||||
BView_scroll_bar_update (void *sb, int portion, int whole, int position);
|
||||
|
||||
extern int
|
||||
BScrollBar_default_size (int horizontal_p);
|
||||
|
||||
extern void
|
||||
BView_invalidate (void *view);
|
||||
|
||||
extern void
|
||||
BView_draw_lock (void *view);
|
||||
|
||||
extern void
|
||||
BView_draw_unlock (void *view);
|
||||
|
||||
extern void
|
||||
BWindow_center_on_screen (void *window);
|
||||
|
||||
extern void
|
||||
BView_mouse_moved (void *view, int x, int y, uint32_t transit);
|
||||
|
||||
extern void
|
||||
BView_mouse_down (void *view, int x, int y);
|
||||
|
||||
extern void
|
||||
BView_mouse_up (void *view, int x, int y);
|
||||
|
||||
extern void
|
||||
BBitmap_import_mono_bits (void *bitmap, void *bits, int wd, int h);
|
||||
|
||||
extern void
|
||||
haiku_font_pattern_free (struct haiku_font_pattern *pt);
|
||||
|
||||
extern struct haiku_font_pattern *
|
||||
BFont_find (struct haiku_font_pattern *pt);
|
||||
|
||||
extern int
|
||||
BFont_open_pattern (struct haiku_font_pattern *pat, void **font, float size);
|
||||
|
||||
extern void
|
||||
BFont_populate_fixed_family (struct haiku_font_pattern *ptn);
|
||||
|
||||
extern void
|
||||
BFont_populate_plain_family (struct haiku_font_pattern *ptn);
|
||||
|
||||
extern void
|
||||
BView_publish_scroll_bar (void *view, int x, int y, int width, int height);
|
||||
|
||||
extern void
|
||||
BView_forget_scroll_bar (void *view, int x, int y, int width, int height);
|
||||
|
||||
extern void
|
||||
BView_get_mouse (void *view, int *x, int *y);
|
||||
|
||||
extern void
|
||||
BView_convert_to_screen (void *view, int *x, int *y);
|
||||
|
||||
extern void
|
||||
BView_convert_from_screen (void *view, int *x, int *y);
|
||||
|
||||
extern void
|
||||
BWindow_change_decoration (void *window, int decorate_p);
|
||||
|
||||
extern void
|
||||
BWindow_set_tooltip_decoration (void *window);
|
||||
|
||||
extern void
|
||||
BWindow_set_avoid_focus (void *window, int avoid_focus_p);
|
||||
|
||||
extern void
|
||||
BView_emacs_delete (void *view);
|
||||
|
||||
extern uint32_t
|
||||
haiku_current_workspace (void);
|
||||
|
||||
extern uint32_t
|
||||
BWindow_workspaces (void *window);
|
||||
|
||||
extern void *
|
||||
BPopUpMenu_new (const char *name);
|
||||
|
||||
extern void
|
||||
BMenu_add_item (void *menu, const char *label, void *ptr, bool enabled_p,
|
||||
bool marked_p, bool mbar_p, void *mbw_ptr, const char *key,
|
||||
const char *help);
|
||||
|
||||
extern void
|
||||
BMenu_add_separator (void *menu);
|
||||
|
||||
extern void *
|
||||
BMenu_new_submenu (void *menu, const char *label, bool enabled_p);
|
||||
|
||||
extern void *
|
||||
BMenu_new_menu_bar_submenu (void *menu, const char *label);
|
||||
|
||||
extern int
|
||||
BMenu_count_items (void *menu);
|
||||
|
||||
extern void *
|
||||
BMenu_item_at (void *menu, int idx);
|
||||
|
||||
extern void *
|
||||
BMenu_run (void *menu, int x, int y);
|
||||
|
||||
extern void
|
||||
BPopUpMenu_delete (void *menu);
|
||||
|
||||
extern void *
|
||||
BMenuBar_new (void *view);
|
||||
|
||||
extern void
|
||||
BMenu_delete_all (void *menu);
|
||||
|
||||
extern void
|
||||
BMenuBar_delete (void *menubar);
|
||||
|
||||
extern void
|
||||
BMenu_item_set_label (void *item, const char *label);
|
||||
|
||||
extern void *
|
||||
BMenu_item_get_menu (void *item);
|
||||
|
||||
extern void
|
||||
BMenu_delete_from (void *menu, int start, int count);
|
||||
|
||||
extern void
|
||||
haiku_ring_bell (void);
|
||||
|
||||
extern void *
|
||||
BAlert_new (const char *text, enum haiku_alert_type type);
|
||||
|
||||
extern void *
|
||||
BAlert_add_button (void *alert, const char *text);
|
||||
|
||||
extern int32_t
|
||||
BAlert_go (void *alert);
|
||||
|
||||
extern void
|
||||
BButton_set_enabled (void *button, int enabled_p);
|
||||
|
||||
extern void
|
||||
BView_set_tooltip (void *view, const char *tooltip);
|
||||
|
||||
extern void
|
||||
BAlert_delete (void *alert);
|
||||
|
||||
extern void
|
||||
BScreen_res (double *rrsx, double *rrsy);
|
||||
|
||||
extern void
|
||||
EmacsWindow_parent_to (void *window, void *other_window);
|
||||
|
||||
extern void
|
||||
EmacsWindow_unparent (void *window);
|
||||
|
||||
extern int
|
||||
BFont_string_width (void *font, const char *utf8);
|
||||
|
||||
extern void
|
||||
be_get_version_string (char *version, int len);
|
||||
|
||||
extern int
|
||||
be_get_display_planes (void);
|
||||
|
||||
extern int
|
||||
be_get_display_color_cells (void);
|
||||
|
||||
extern void
|
||||
be_warp_pointer (int x, int y);
|
||||
|
||||
extern void
|
||||
EmacsWindow_move_weak_child (void *window, void *child, int xoff, int yoff);
|
||||
|
||||
extern void
|
||||
EmacsView_set_up_double_buffering (void *vw);
|
||||
|
||||
extern void
|
||||
EmacsView_disable_double_buffering (void *vw);
|
||||
|
||||
extern void
|
||||
EmacsView_flip_and_blit (void *vw);
|
||||
|
||||
extern int
|
||||
EmacsView_double_buffered_p (void *vw);
|
||||
|
||||
extern char *
|
||||
be_popup_file_dialog (int open_p, const char *default_dir, int must_match_p,
|
||||
int dir_only_p, void *window, const char *save_text,
|
||||
const char *prompt,
|
||||
void (*block_input_function) (void),
|
||||
void (*unblock_input_function) (void));
|
||||
|
||||
extern void
|
||||
record_c_unwind_protect_from_cxx (void (*) (void *), void *);
|
||||
|
||||
extern ptrdiff_t
|
||||
c_specpdl_idx_from_cxx (void);
|
||||
|
||||
extern void
|
||||
c_unbind_to_nil_from_cxx (ptrdiff_t idx);
|
||||
|
||||
extern void
|
||||
EmacsView_do_visible_bell (void *view, uint32_t color);
|
||||
|
||||
extern void
|
||||
BWindow_zoom (void *window);
|
||||
|
||||
extern void
|
||||
EmacsWindow_make_fullscreen (void *window, int fullscreen_p);
|
||||
|
||||
extern void
|
||||
EmacsWindow_unzoom (void *window);
|
||||
|
||||
#ifdef HAVE_NATIVE_IMAGE_API
|
||||
extern int
|
||||
be_can_translate_type_to_bitmap_p (const char *mime);
|
||||
|
||||
extern void *
|
||||
be_translate_bitmap_from_file_name (const char *filename);
|
||||
|
||||
extern void *
|
||||
be_translate_bitmap_from_memory (const void *buf, size_t bytes);
|
||||
#endif
|
||||
|
||||
extern void
|
||||
BMenuBar_start_tracking (void *mbar);
|
||||
|
||||
extern size_t
|
||||
BBitmap_bytes_length (void *bitmap);
|
||||
|
||||
extern void
|
||||
BView_show_tooltip (void *view);
|
||||
|
||||
#ifdef USE_BE_CAIRO
|
||||
extern cairo_surface_t *
|
||||
EmacsView_cairo_surface (void *view);
|
||||
|
||||
extern void
|
||||
BView_cr_dump_clipping (void *view, cairo_t *ctx);
|
||||
|
||||
extern void
|
||||
EmacsWindow_begin_cr_critical_section (void *window);
|
||||
|
||||
extern void
|
||||
EmacsWindow_end_cr_critical_section (void *window);
|
||||
#endif
|
||||
|
||||
extern void
|
||||
BView_set_and_show_sticky_tooltip (void *view, const char *tooltip,
|
||||
int x, int y);
|
||||
|
||||
extern void
|
||||
BMenu_add_title (void *menu, const char *text);
|
||||
|
||||
extern int
|
||||
be_plain_font_height (void);
|
||||
|
||||
extern int
|
||||
be_string_width_with_plain_font (const char *str);
|
||||
|
||||
extern int
|
||||
be_get_display_screens (void);
|
||||
|
||||
extern void
|
||||
BWindow_set_min_size (void *window, int width, int height);
|
||||
|
||||
extern void
|
||||
BWindow_set_size_alignment (void *window, int align_width, int align_height);
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern void *
|
||||
find_appropriate_view_for_draw (void *vw);
|
||||
}
|
||||
|
||||
extern _Noreturn void
|
||||
gui_abort (const char *msg);
|
||||
#endif /* _cplusplus */
|
||||
|
||||
/* Borrowed from X.Org keysymdef.h */
|
||||
#define XK_BackSpace 0xff08 /* Back space, back char */
|
||||
#define XK_Tab 0xff09
|
||||
#define XK_Linefeed 0xff0a /* Linefeed, LF */
|
||||
#define XK_Clear 0xff0b
|
||||
#define XK_Return 0xff0d /* Return, enter */
|
||||
#define XK_Pause 0xff13 /* Pause, hold */
|
||||
#define XK_Scroll_Lock 0xff14
|
||||
#define XK_Sys_Req 0xff15
|
||||
#define XK_Escape 0xff1b
|
||||
#define XK_Delete 0xffff /* Delete, rubout */
|
||||
#define XK_Home 0xff50
|
||||
#define XK_Left 0xff51 /* Move left, left arrow */
|
||||
#define XK_Up 0xff52 /* Move up, up arrow */
|
||||
#define XK_Right 0xff53 /* Move right, right arrow */
|
||||
#define XK_Down 0xff54 /* Move down, down arrow */
|
||||
#define XK_Prior 0xff55 /* Prior, previous */
|
||||
#define XK_Page_Up 0xff55
|
||||
#define XK_Next 0xff56 /* Next */
|
||||
#define XK_Page_Down 0xff56
|
||||
#define XK_End 0xff57 /* EOL */
|
||||
#define XK_Begin 0xff58 /* BOL */
|
||||
#define XK_Select 0xff60 /* Select, mark */
|
||||
#define XK_Print 0xff61
|
||||
#define XK_Execute 0xff62 /* Execute, run, do */
|
||||
#define XK_Insert 0xff63 /* Insert, insert here */
|
||||
#define XK_Undo 0xff65
|
||||
#define XK_Redo 0xff66 /* Redo, again */
|
||||
#define XK_Menu 0xff67
|
||||
#define XK_Find 0xff68 /* Find, search */
|
||||
#define XK_Cancel 0xff69 /* Cancel, stop, abort, exit */
|
||||
#define XK_Help 0xff6a /* Help */
|
||||
#define XK_Break 0xff6b
|
||||
#define XK_Mode_switch 0xff7e /* Character set switch */
|
||||
#define XK_script_switch 0xff7e /* Alias for mode_switch */
|
||||
#define XK_Num_Lock 0xff7f
|
||||
#define XK_F1 0xffbe
|
||||
|
||||
#endif /* _HAIKU_SUPPORT_H_ */
|
2448
src/haikufns.c
Normal file
2448
src/haikufns.c
Normal file
File diff suppressed because it is too large
Load diff
1072
src/haikufont.c
Normal file
1072
src/haikufont.c
Normal file
File diff suppressed because it is too large
Load diff
106
src/haikugui.h
Normal file
106
src/haikugui.h
Normal file
|
@ -0,0 +1,106 @@
|
|||
/* Haiku window system support
|
||||
Copyright (C) 2021 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Emacs.
|
||||
|
||||
GNU Emacs 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.
|
||||
|
||||
GNU Emacs 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 GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef _HAIKU_GUI_H_
|
||||
#define _HAIKU_GUI_H_
|
||||
|
||||
#ifdef _cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
typedef struct haiku_char_struct
|
||||
{
|
||||
int rbearing;
|
||||
int lbearing;
|
||||
int width;
|
||||
int ascent;
|
||||
int descent;
|
||||
} XCharStruct;
|
||||
|
||||
struct haiku_rect
|
||||
{
|
||||
int x, y;
|
||||
int width, height;
|
||||
};
|
||||
|
||||
typedef void *haiku;
|
||||
|
||||
typedef haiku Emacs_Pixmap;
|
||||
typedef haiku Emacs_Window;
|
||||
typedef haiku Emacs_Cursor;
|
||||
typedef haiku Drawable;
|
||||
|
||||
#define NativeRectangle struct haiku_rect
|
||||
#define CONVERT_TO_EMACS_RECT(xr, nr) \
|
||||
((xr).x = (nr).x, \
|
||||
(xr).y = (nr).y, \
|
||||
(xr).width = (nr).width, \
|
||||
(xr).height = (nr).height)
|
||||
|
||||
#define CONVERT_FROM_EMACS_RECT(xr, nr) \
|
||||
((nr).x = (xr).x, \
|
||||
(nr).y = (xr).y, \
|
||||
(nr).width = (xr).width, \
|
||||
(nr).height = (xr).height)
|
||||
|
||||
#define STORE_NATIVE_RECT(nr, px, py, pwidth, pheight) \
|
||||
((nr).x = (px), \
|
||||
(nr).y = (py), \
|
||||
(nr).width = (pwidth), \
|
||||
(nr).height = (pheight))
|
||||
|
||||
#define ForgetGravity 0
|
||||
#define NorthWestGravity 1
|
||||
#define NorthGravity 2
|
||||
#define NorthEastGravity 3
|
||||
#define WestGravity 4
|
||||
#define CenterGravity 5
|
||||
#define EastGravity 6
|
||||
#define SouthWestGravity 7
|
||||
#define SouthGravity 8
|
||||
#define SouthEastGravity 9
|
||||
#define StaticGravity 10
|
||||
|
||||
#define NoValue 0x0000
|
||||
#define XValue 0x0001
|
||||
#define YValue 0x0002
|
||||
#define WidthValue 0x0004
|
||||
#define HeightValue 0x0008
|
||||
#define AllValues 0x000F
|
||||
#define XNegative 0x0010
|
||||
#define YNegative 0x0020
|
||||
|
||||
#define USPosition (1L << 0) /* user specified x, y */
|
||||
#define USSize (1L << 1) /* user specified width, height */
|
||||
#define PPosition (1L << 2) /* program specified position */
|
||||
#define PSize (1L << 3) /* program specified size */
|
||||
#define PMinSize (1L << 4) /* program specified minimum size */
|
||||
#define PMaxSize (1L << 5) /* program specified maximum size */
|
||||
#define PResizeInc (1L << 6) /* program specified resize increments */
|
||||
#define PAspect (1L << 7) /* program specified min, max aspect ratios */
|
||||
#define PBaseSize (1L << 8) /* program specified base for incrementing */
|
||||
#define PWinGravity (1L << 9) /* program specified window gravity */
|
||||
|
||||
typedef haiku Window;
|
||||
typedef int Display;
|
||||
|
||||
#ifdef _cplusplus
|
||||
};
|
||||
#endif
|
||||
#endif /* _HAIKU_GUI_H_ */
|
109
src/haikuimage.c
Normal file
109
src/haikuimage.c
Normal file
|
@ -0,0 +1,109 @@
|
|||
/* Haiku window system support.
|
||||
Copyright (C) 2021 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Emacs.
|
||||
|
||||
GNU Emacs 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.
|
||||
|
||||
GNU Emacs 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 GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "lisp.h"
|
||||
#include "dispextern.h"
|
||||
#include "haikuterm.h"
|
||||
#include "coding.h"
|
||||
|
||||
#include "haiku_support.h"
|
||||
|
||||
bool
|
||||
haiku_can_use_native_image_api (Lisp_Object type)
|
||||
{
|
||||
const char *mime_type = NULL;
|
||||
|
||||
if (EQ (type, Qnative_image))
|
||||
return 1;
|
||||
|
||||
#ifdef HAVE_RSVG
|
||||
if (EQ (type, Qsvg))
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
if (EQ (type, Qjpeg))
|
||||
mime_type = "image/jpeg";
|
||||
else if (EQ (type, Qpng))
|
||||
mime_type = "image/png";
|
||||
else if (EQ (type, Qgif))
|
||||
mime_type = "image/gif";
|
||||
else if (EQ (type, Qtiff))
|
||||
mime_type = "image/tiff";
|
||||
else if (EQ (type, Qbmp))
|
||||
mime_type = "image/bmp";
|
||||
else if (EQ (type, Qsvg))
|
||||
mime_type = "image/svg";
|
||||
else if (EQ (type, Qpbm))
|
||||
mime_type = "image/pbm";
|
||||
|
||||
if (!mime_type)
|
||||
return 0;
|
||||
|
||||
return be_can_translate_type_to_bitmap_p (mime_type);
|
||||
}
|
||||
|
||||
extern int
|
||||
haiku_load_image (struct frame *f, struct image *img,
|
||||
Lisp_Object spec_file, Lisp_Object spec_data)
|
||||
{
|
||||
eassert (valid_image_p (img->spec));
|
||||
|
||||
void *pixmap = NULL;
|
||||
|
||||
if (STRINGP (spec_file))
|
||||
{
|
||||
pixmap = be_translate_bitmap_from_file_name
|
||||
(SSDATA (ENCODE_UTF_8 (spec_file)));
|
||||
}
|
||||
else if (STRINGP (spec_data))
|
||||
{
|
||||
pixmap = be_translate_bitmap_from_memory
|
||||
(SSDATA (spec_data), SBYTES (spec_data));
|
||||
}
|
||||
|
||||
void *conv = NULL;
|
||||
|
||||
if (!pixmap || !BBitmap_convert (pixmap, &conv))
|
||||
{
|
||||
add_to_log ("Unable to load image %s", img->spec);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (conv)
|
||||
{
|
||||
BBitmap_free (pixmap);
|
||||
pixmap = conv;
|
||||
}
|
||||
|
||||
int left, top, right, bottom, stride, mono_p;
|
||||
BBitmap_dimensions (pixmap, &left, &top, &right, &bottom, &stride, &mono_p);
|
||||
|
||||
img->width = (1 + right - left);
|
||||
img->height = (1 + bottom - top);
|
||||
img->pixmap = pixmap;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
syms_of_haikuimage (void)
|
||||
{
|
||||
DEFSYM (Qbmp, "bmp");
|
||||
}
|
656
src/haikumenu.c
Normal file
656
src/haikumenu.c
Normal file
|
@ -0,0 +1,656 @@
|
|||
/* Haiku window system support
|
||||
Copyright (C) 2021 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Emacs.
|
||||
|
||||
GNU Emacs 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.
|
||||
|
||||
GNU Emacs 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 GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "lisp.h"
|
||||
#include "frame.h"
|
||||
#include "keyboard.h"
|
||||
#include "menu.h"
|
||||
#include "buffer.h"
|
||||
#include "blockinput.h"
|
||||
|
||||
#include "haikuterm.h"
|
||||
#include "haiku_support.h"
|
||||
|
||||
static Lisp_Object *volatile menu_item_selection;
|
||||
|
||||
int popup_activated_p = 0;
|
||||
|
||||
struct submenu_stack_cell
|
||||
{
|
||||
void *parent_menu;
|
||||
void *pane;
|
||||
};
|
||||
|
||||
static void
|
||||
digest_menu_items (void *first_menu, int start, int menu_items_used,
|
||||
int mbar_p)
|
||||
{
|
||||
void **menus, **panes;
|
||||
ssize_t menu_len = (menu_items_used + 1 - start) * sizeof *menus;
|
||||
ssize_t pane_len = (menu_items_used + 1 - start) * sizeof *panes;
|
||||
|
||||
menus = alloca (menu_len);
|
||||
panes = alloca (pane_len);
|
||||
|
||||
int i = start, menu_depth = 0;
|
||||
|
||||
memset (menus, 0, menu_len);
|
||||
memset (panes, 0, pane_len);
|
||||
|
||||
void *menu = first_menu;
|
||||
|
||||
menus[0] = first_menu;
|
||||
|
||||
void *window = NULL;
|
||||
if (FRAMEP (Vmenu_updating_frame) &&
|
||||
FRAME_LIVE_P (XFRAME (Vmenu_updating_frame)) &&
|
||||
FRAME_HAIKU_P (XFRAME (Vmenu_updating_frame)))
|
||||
window = FRAME_HAIKU_WINDOW (XFRAME (Vmenu_updating_frame));
|
||||
|
||||
while (i < menu_items_used)
|
||||
{
|
||||
if (NILP (AREF (menu_items, i)))
|
||||
{
|
||||
menus[++menu_depth] = menu;
|
||||
i++;
|
||||
}
|
||||
else if (EQ (AREF (menu_items, i), Qlambda))
|
||||
{
|
||||
panes[menu_depth] = NULL;
|
||||
menu = panes[--menu_depth] ? panes[menu_depth] : menus[menu_depth];
|
||||
i++;
|
||||
}
|
||||
else if (EQ (AREF (menu_items, i), Qquote))
|
||||
i += 1;
|
||||
else if (EQ (AREF (menu_items, i), Qt))
|
||||
{
|
||||
Lisp_Object pane_name, prefix;
|
||||
const char *pane_string;
|
||||
|
||||
if (menu_items_n_panes == 1)
|
||||
{
|
||||
i += MENU_ITEMS_PANE_LENGTH;
|
||||
continue;
|
||||
}
|
||||
|
||||
pane_name = AREF (menu_items, i + MENU_ITEMS_PANE_NAME);
|
||||
prefix = AREF (menu_items, i + MENU_ITEMS_PANE_PREFIX);
|
||||
|
||||
if (STRINGP (pane_name) && STRING_MULTIBYTE (pane_name))
|
||||
{
|
||||
pane_name = ENCODE_UTF_8 (pane_name);
|
||||
ASET (menu_items, i + MENU_ITEMS_PANE_NAME, pane_name);
|
||||
}
|
||||
|
||||
pane_string = (NILP (pane_name)
|
||||
? "" : SSDATA (pane_name));
|
||||
if (!NILP (prefix))
|
||||
pane_string++;
|
||||
|
||||
if (strcmp (pane_string, ""))
|
||||
{
|
||||
panes[menu_depth] =
|
||||
menu = BMenu_new_submenu (menus[menu_depth], pane_string, 1);
|
||||
}
|
||||
|
||||
i += MENU_ITEMS_PANE_LENGTH;
|
||||
}
|
||||
else
|
||||
{
|
||||
Lisp_Object item_name, enable, descrip, def, selected, help;
|
||||
item_name = AREF (menu_items, i + MENU_ITEMS_ITEM_NAME);
|
||||
enable = AREF (menu_items, i + MENU_ITEMS_ITEM_ENABLE);
|
||||
descrip = AREF (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY);
|
||||
def = AREF (menu_items, i + MENU_ITEMS_ITEM_DEFINITION);
|
||||
selected = AREF (menu_items, i + MENU_ITEMS_ITEM_SELECTED);
|
||||
help = AREF (menu_items, i + MENU_ITEMS_ITEM_HELP);
|
||||
|
||||
if (STRINGP (item_name) && STRING_MULTIBYTE (item_name))
|
||||
{
|
||||
item_name = ENCODE_UTF_8 (item_name);
|
||||
ASET (menu_items, i + MENU_ITEMS_ITEM_NAME, item_name);
|
||||
}
|
||||
|
||||
if (STRINGP (descrip) && STRING_MULTIBYTE (descrip))
|
||||
{
|
||||
descrip = ENCODE_UTF_8 (descrip);
|
||||
ASET (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY, descrip);
|
||||
}
|
||||
|
||||
if (STRINGP (help) && STRING_MULTIBYTE (help))
|
||||
{
|
||||
help = ENCODE_UTF_8 (help);
|
||||
ASET (menu_items, i + MENU_ITEMS_ITEM_HELP, help);
|
||||
}
|
||||
|
||||
if (i + MENU_ITEMS_ITEM_LENGTH < menu_items_used &&
|
||||
NILP (AREF (menu_items, i + MENU_ITEMS_ITEM_LENGTH)))
|
||||
menu = BMenu_new_submenu (menu, SSDATA (item_name), !NILP (enable));
|
||||
else if (NILP (def) && menu_separator_name_p (SSDATA (item_name)))
|
||||
BMenu_add_separator (menu);
|
||||
else if (!mbar_p)
|
||||
BMenu_add_item (menu, SSDATA (item_name),
|
||||
!NILP (def) ? aref_addr (menu_items, i) : NULL,
|
||||
!NILP (enable), !NILP (selected), 0, window,
|
||||
!NILP (descrip) ? SSDATA (descrip) : NULL,
|
||||
STRINGP (help) ? SSDATA (help) : NULL);
|
||||
else
|
||||
BMenu_add_item (menu, SSDATA (item_name),
|
||||
!NILP (def) ? (void *) (intptr_t) i : NULL,
|
||||
!NILP (enable), !NILP (selected), 1, window,
|
||||
!NILP (descrip) ? SSDATA (descrip) : NULL,
|
||||
STRINGP (help) ? SSDATA (help) : NULL);
|
||||
|
||||
i += MENU_ITEMS_ITEM_LENGTH;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static Lisp_Object
|
||||
haiku_dialog_show (struct frame *f, Lisp_Object title,
|
||||
Lisp_Object header, const char **error_name)
|
||||
{
|
||||
int i, nb_buttons = 0;
|
||||
|
||||
*error_name = NULL;
|
||||
|
||||
if (menu_items_n_panes > 1)
|
||||
{
|
||||
*error_name = "Multiple panes in dialog box";
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
Lisp_Object pane_name = AREF (menu_items, MENU_ITEMS_PANE_NAME);
|
||||
i = MENU_ITEMS_PANE_LENGTH;
|
||||
|
||||
if (STRING_MULTIBYTE (pane_name))
|
||||
pane_name = ENCODE_UTF_8 (pane_name);
|
||||
|
||||
block_input ();
|
||||
void *alert = BAlert_new (SSDATA (pane_name), NILP (header) ? HAIKU_INFO_ALERT :
|
||||
HAIKU_IDEA_ALERT);
|
||||
|
||||
Lisp_Object vals[10];
|
||||
|
||||
while (i < menu_items_used)
|
||||
{
|
||||
Lisp_Object item_name, enable, descrip, value;
|
||||
item_name = AREF (menu_items, i + MENU_ITEMS_ITEM_NAME);
|
||||
enable = AREF (menu_items, i + MENU_ITEMS_ITEM_ENABLE);
|
||||
descrip = AREF (menu_items, i + MENU_ITEMS_ITEM_EQUIV_KEY);
|
||||
value = AREF (menu_items, i + MENU_ITEMS_ITEM_VALUE);
|
||||
|
||||
if (NILP (item_name))
|
||||
{
|
||||
BAlert_delete (alert);
|
||||
*error_name = "Submenu in dialog items";
|
||||
unblock_input ();
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
if (EQ (item_name, Qquote))
|
||||
{
|
||||
i++;
|
||||
}
|
||||
|
||||
if (nb_buttons >= 9)
|
||||
{
|
||||
BAlert_delete (alert);
|
||||
*error_name = "Too many dialog items";
|
||||
unblock_input ();
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
if (STRING_MULTIBYTE (item_name))
|
||||
item_name = ENCODE_UTF_8 (item_name);
|
||||
if (!NILP (descrip) && STRING_MULTIBYTE (descrip))
|
||||
descrip = ENCODE_UTF_8 (descrip);
|
||||
|
||||
void *button = BAlert_add_button (alert, SSDATA (item_name));
|
||||
|
||||
BButton_set_enabled (button, !NILP (enable));
|
||||
if (!NILP (descrip))
|
||||
BView_set_tooltip (button, SSDATA (descrip));
|
||||
|
||||
vals[nb_buttons] = value;
|
||||
++nb_buttons;
|
||||
i += MENU_ITEMS_ITEM_LENGTH;
|
||||
}
|
||||
|
||||
int32_t val = BAlert_go (alert);
|
||||
unblock_input ();
|
||||
|
||||
if (val < 0)
|
||||
quit ();
|
||||
else
|
||||
return vals[val];
|
||||
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
Lisp_Object
|
||||
haiku_popup_dialog (struct frame *f, Lisp_Object header, Lisp_Object contents)
|
||||
{
|
||||
Lisp_Object title;
|
||||
const char *error_name = NULL;
|
||||
Lisp_Object selection;
|
||||
ptrdiff_t specpdl_count = SPECPDL_INDEX ();
|
||||
|
||||
check_window_system (f);
|
||||
|
||||
/* Decode the dialog items from what was specified. */
|
||||
title = Fcar (contents);
|
||||
CHECK_STRING (title);
|
||||
record_unwind_protect_void (unuse_menu_items);
|
||||
|
||||
if (NILP (Fcar (Fcdr (contents))))
|
||||
/* No buttons specified, add an "Ok" button so users can pop down
|
||||
the dialog. Also, the lesstif/motif version crashes if there are
|
||||
no buttons. */
|
||||
contents = list2 (title, Fcons (build_string ("Ok"), Qt));
|
||||
|
||||
list_of_panes (list1 (contents));
|
||||
|
||||
/* Display them in a dialog box. */
|
||||
block_input ();
|
||||
selection = haiku_dialog_show (f, title, header, &error_name);
|
||||
unblock_input ();
|
||||
|
||||
unbind_to (specpdl_count, Qnil);
|
||||
discard_menu_items ();
|
||||
|
||||
if (error_name)
|
||||
error ("%s", error_name);
|
||||
return selection;
|
||||
}
|
||||
|
||||
Lisp_Object
|
||||
haiku_menu_show (struct frame *f, int x, int y, int menuflags,
|
||||
Lisp_Object title, const char **error_name)
|
||||
{
|
||||
int i = 0, submenu_depth = 0;
|
||||
void *view = FRAME_HAIKU_VIEW (f);
|
||||
void *menu;
|
||||
|
||||
Lisp_Object *subprefix_stack =
|
||||
alloca (menu_items_used * sizeof (Lisp_Object));
|
||||
|
||||
eassert (FRAME_HAIKU_P (f));
|
||||
|
||||
*error_name = NULL;
|
||||
|
||||
if (menu_items_used <= MENU_ITEMS_PANE_LENGTH)
|
||||
{
|
||||
*error_name = "Empty menu";
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
block_input ();
|
||||
if (STRINGP (title) && STRING_MULTIBYTE (title))
|
||||
title = ENCODE_UTF_8 (title);
|
||||
|
||||
menu = BPopUpMenu_new (STRINGP (title) ? SSDATA (title) : NULL);
|
||||
if (STRINGP (title))
|
||||
{
|
||||
BMenu_add_title (menu, SSDATA (title));
|
||||
BMenu_add_separator (menu);
|
||||
}
|
||||
digest_menu_items (menu, 0, menu_items_used, 0);
|
||||
BView_convert_to_screen (view, &x, &y);
|
||||
unblock_input ();
|
||||
|
||||
menu_item_selection = BMenu_run (menu, x, y);
|
||||
|
||||
FRAME_DISPLAY_INFO (f)->grabbed = 0;
|
||||
|
||||
if (menu_item_selection)
|
||||
{
|
||||
Lisp_Object prefix, entry;
|
||||
|
||||
prefix = entry = Qnil;
|
||||
i = 0;
|
||||
while (i < menu_items_used)
|
||||
{
|
||||
if (NILP (AREF (menu_items, i)))
|
||||
{
|
||||
subprefix_stack[submenu_depth++] = prefix;
|
||||
prefix = entry;
|
||||
i++;
|
||||
}
|
||||
else if (EQ (AREF (menu_items, i), Qlambda))
|
||||
{
|
||||
prefix = subprefix_stack[--submenu_depth];
|
||||
i++;
|
||||
}
|
||||
else if (EQ (AREF (menu_items, i), Qt))
|
||||
{
|
||||
prefix
|
||||
= AREF (menu_items, i + MENU_ITEMS_PANE_PREFIX);
|
||||
i += MENU_ITEMS_PANE_LENGTH;
|
||||
}
|
||||
/* Ignore a nil in the item list.
|
||||
It's meaningful only for dialog boxes. */
|
||||
else if (EQ (AREF (menu_items, i), Qquote))
|
||||
i += 1;
|
||||
else
|
||||
{
|
||||
entry
|
||||
= AREF (menu_items, i + MENU_ITEMS_ITEM_VALUE);
|
||||
if (menu_item_selection == aref_addr (menu_items, i))
|
||||
{
|
||||
if (menuflags & MENU_KEYMAPS)
|
||||
{
|
||||
int j;
|
||||
|
||||
entry = list1 (entry);
|
||||
if (!NILP (prefix))
|
||||
entry = Fcons (prefix, entry);
|
||||
for (j = submenu_depth - 1; j >= 0; j--)
|
||||
if (!NILP (subprefix_stack[j]))
|
||||
entry = Fcons (subprefix_stack[j], entry);
|
||||
}
|
||||
BPopUpMenu_delete (menu);
|
||||
return entry;
|
||||
}
|
||||
i += MENU_ITEMS_ITEM_LENGTH;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!(menuflags & MENU_FOR_CLICK))
|
||||
{
|
||||
BPopUpMenu_delete (menu);
|
||||
quit ();
|
||||
}
|
||||
BPopUpMenu_delete (menu);
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
void
|
||||
free_frame_menubar (struct frame *f)
|
||||
{
|
||||
FRAME_MENU_BAR_LINES (f) = 0;
|
||||
FRAME_MENU_BAR_HEIGHT (f) = 0;
|
||||
FRAME_EXTERNAL_MENU_BAR (f) = 0;
|
||||
|
||||
block_input ();
|
||||
void *mbar = FRAME_HAIKU_MENU_BAR (f);
|
||||
if (mbar)
|
||||
BMenuBar_delete (mbar);
|
||||
if (FRAME_OUTPUT_DATA (f)->menu_bar_open_p)
|
||||
--popup_activated_p;
|
||||
FRAME_OUTPUT_DATA (f)->menu_bar_open_p = 0;
|
||||
unblock_input ();
|
||||
|
||||
adjust_frame_size (f, -1, -1, 2, false, Qmenu_bar_lines);
|
||||
}
|
||||
|
||||
void
|
||||
initialize_frame_menubar (struct frame *f)
|
||||
{
|
||||
/* This function is called before the first chance to redisplay
|
||||
the frame. It has to be, so the frame will have the right size. */
|
||||
fset_menu_bar_items (f, menu_bar_items (FRAME_MENU_BAR_ITEMS (f)));
|
||||
set_frame_menubar (f, true);
|
||||
}
|
||||
|
||||
void
|
||||
set_frame_menubar (struct frame *f, bool deep_p)
|
||||
{
|
||||
void *mbar = FRAME_HAIKU_MENU_BAR (f);
|
||||
void *view = FRAME_HAIKU_VIEW (f);
|
||||
|
||||
int first_time_p = 0;
|
||||
|
||||
if (!mbar)
|
||||
{
|
||||
mbar = FRAME_HAIKU_MENU_BAR (f) = BMenuBar_new (view);
|
||||
first_time_p = 1;
|
||||
}
|
||||
|
||||
Lisp_Object items;
|
||||
struct buffer *prev = current_buffer;
|
||||
Lisp_Object buffer;
|
||||
ptrdiff_t specpdl_count = SPECPDL_INDEX ();
|
||||
int previous_menu_items_used = f->menu_bar_items_used;
|
||||
Lisp_Object *previous_items
|
||||
= alloca (previous_menu_items_used * sizeof *previous_items);
|
||||
|
||||
XSETFRAME (Vmenu_updating_frame, f);
|
||||
|
||||
if (!deep_p)
|
||||
{
|
||||
FRAME_OUTPUT_DATA (f)->menu_up_to_date_p = 0;
|
||||
items = FRAME_MENU_BAR_ITEMS (f);
|
||||
Lisp_Object string;
|
||||
|
||||
block_input ();
|
||||
int count = BMenu_count_items (mbar);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < ASIZE (items); i += 4)
|
||||
{
|
||||
string = AREF (items, i + 1);
|
||||
|
||||
if (!STRINGP (string))
|
||||
break;
|
||||
|
||||
if (STRING_MULTIBYTE (string))
|
||||
string = ENCODE_UTF_8 (string);
|
||||
|
||||
if (i / 4 < count)
|
||||
{
|
||||
void *it = BMenu_item_at (mbar, i / 4);
|
||||
BMenu_item_set_label (it, SSDATA (string));
|
||||
}
|
||||
else
|
||||
BMenu_new_menu_bar_submenu (mbar, SSDATA (string));
|
||||
}
|
||||
|
||||
if (i / 4 < count)
|
||||
BMenu_delete_from (mbar, i / 4, count - i / 4 + 1);
|
||||
unblock_input ();
|
||||
|
||||
f->menu_bar_items_used = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If we are making a new widget, its contents are empty,
|
||||
do always reinitialize them. */
|
||||
if (first_time_p)
|
||||
previous_menu_items_used = 0;
|
||||
buffer = XWINDOW (FRAME_SELECTED_WINDOW (f))->contents;
|
||||
specbind (Qinhibit_quit, Qt);
|
||||
/* Don't let the debugger step into this code
|
||||
because it is not reentrant. */
|
||||
specbind (Qdebug_on_next_call, Qnil);
|
||||
|
||||
record_unwind_save_match_data ();
|
||||
if (NILP (Voverriding_local_map_menu_flag))
|
||||
{
|
||||
specbind (Qoverriding_terminal_local_map, Qnil);
|
||||
specbind (Qoverriding_local_map, Qnil);
|
||||
}
|
||||
|
||||
set_buffer_internal_1 (XBUFFER (buffer));
|
||||
|
||||
/* Run the Lucid hook. */
|
||||
safe_run_hooks (Qactivate_menubar_hook);
|
||||
|
||||
/* If it has changed current-menubar from previous value,
|
||||
really recompute the menubar from the value. */
|
||||
if (! NILP (Vlucid_menu_bar_dirty_flag))
|
||||
call0 (Qrecompute_lucid_menubar);
|
||||
safe_run_hooks (Qmenu_bar_update_hook);
|
||||
fset_menu_bar_items (f, menu_bar_items (FRAME_MENU_BAR_ITEMS (f)));
|
||||
|
||||
items = FRAME_MENU_BAR_ITEMS (f);
|
||||
|
||||
/* Save the frame's previous menu bar contents data. */
|
||||
if (previous_menu_items_used)
|
||||
memcpy (previous_items, xvector_contents (f->menu_bar_vector),
|
||||
previous_menu_items_used * word_size);
|
||||
|
||||
/* Fill in menu_items with the current menu bar contents.
|
||||
This can evaluate Lisp code. */
|
||||
save_menu_items ();
|
||||
menu_items = f->menu_bar_vector;
|
||||
menu_items_allocated = VECTORP (menu_items) ? ASIZE (menu_items) : 0;
|
||||
init_menu_items ();
|
||||
int i;
|
||||
int count = BMenu_count_items (mbar);
|
||||
int subitems = ASIZE (items) / 4;
|
||||
|
||||
int *submenu_start, *submenu_end, *submenu_n_panes;
|
||||
Lisp_Object *submenu_names;
|
||||
|
||||
submenu_start = alloca ((subitems + 1) * sizeof *submenu_start);
|
||||
submenu_end = alloca (subitems * sizeof *submenu_end);
|
||||
submenu_n_panes = alloca (subitems * sizeof *submenu_n_panes);
|
||||
submenu_names = alloca (subitems * sizeof (Lisp_Object));
|
||||
|
||||
for (i = 0; i < subitems; ++i)
|
||||
{
|
||||
Lisp_Object key, string, maps;
|
||||
|
||||
key = AREF (items, i * 4);
|
||||
string = AREF (items, i * 4 + 1);
|
||||
maps = AREF (items, i * 4 + 2);
|
||||
|
||||
if (NILP (string))
|
||||
break;
|
||||
|
||||
if (STRINGP (string) && STRING_MULTIBYTE (string))
|
||||
string = ENCODE_UTF_8 (string);
|
||||
|
||||
submenu_start[i] = menu_items_used;
|
||||
menu_items_n_panes = 0;
|
||||
parse_single_submenu (key, string, maps);
|
||||
submenu_n_panes[i] = menu_items_n_panes;
|
||||
submenu_end[i] = menu_items_used;
|
||||
submenu_names[i] = string;
|
||||
}
|
||||
finish_menu_items ();
|
||||
submenu_start[i] = -1;
|
||||
|
||||
block_input ();
|
||||
for (i = 0; submenu_start[i] >= 0; ++i)
|
||||
{
|
||||
void *mn = NULL;
|
||||
if (i < count)
|
||||
mn = BMenu_item_get_menu (BMenu_item_at (mbar, i));
|
||||
if (mn)
|
||||
BMenu_delete_all (mn);
|
||||
else
|
||||
mn = BMenu_new_menu_bar_submenu (mbar, SSDATA (submenu_names[i]));
|
||||
|
||||
menu_items_n_panes = submenu_n_panes[i];
|
||||
digest_menu_items (mn, submenu_start[i], submenu_end[i], 1);
|
||||
}
|
||||
unblock_input ();
|
||||
|
||||
set_buffer_internal_1 (prev);
|
||||
|
||||
FRAME_OUTPUT_DATA (f)->menu_up_to_date_p = 1;
|
||||
fset_menu_bar_vector (f, menu_items);
|
||||
f->menu_bar_items_used = menu_items_used;
|
||||
}
|
||||
unbind_to (specpdl_count, Qnil);
|
||||
}
|
||||
|
||||
void
|
||||
run_menu_bar_help_event (struct frame *f, int mb_idx)
|
||||
{
|
||||
Lisp_Object frame;
|
||||
Lisp_Object vec;
|
||||
Lisp_Object help;
|
||||
|
||||
block_input ();
|
||||
if (!FRAME_OUTPUT_DATA (f)->menu_up_to_date_p)
|
||||
{
|
||||
unblock_input ();
|
||||
return;
|
||||
}
|
||||
|
||||
XSETFRAME (frame, f);
|
||||
|
||||
if (mb_idx < 0)
|
||||
{
|
||||
kbd_buffer_store_help_event (frame, Qnil);
|
||||
unblock_input ();
|
||||
return;
|
||||
}
|
||||
|
||||
vec = f->menu_bar_vector;
|
||||
if (mb_idx >= ASIZE (vec))
|
||||
emacs_abort ();
|
||||
|
||||
help = AREF (vec, mb_idx + MENU_ITEMS_ITEM_HELP);
|
||||
if (STRINGP (help) || NILP (help))
|
||||
kbd_buffer_store_help_event (frame, help);
|
||||
unblock_input ();
|
||||
}
|
||||
|
||||
DEFUN ("menu-or-popup-active-p", Fmenu_or_popup_active_p, Smenu_or_popup_active_p,
|
||||
0, 0, 0, doc: /* SKIP: real doc in xmenu.c. */)
|
||||
(void)
|
||||
{
|
||||
return popup_activated_p ? Qt : Qnil;
|
||||
}
|
||||
|
||||
DEFUN ("haiku-menu-bar-open", Fhaiku_menu_bar_open, Shaiku_menu_bar_open, 0, 1, "i",
|
||||
doc: /* Show the menu bar in FRAME.
|
||||
|
||||
Move the mouse pointer onto the first element of FRAME's menu bar, and
|
||||
cause it to be opened. If FRAME is nil or not given, use the selected
|
||||
frame. If FRAME has no menu bar, a pop-up is displayed at the position
|
||||
of the last non-menu event instead. */)
|
||||
(Lisp_Object frame)
|
||||
{
|
||||
struct frame *f = decode_window_system_frame (frame);
|
||||
|
||||
if (FRAME_EXTERNAL_MENU_BAR (f))
|
||||
{
|
||||
if (!FRAME_OUTPUT_DATA (f)->menu_up_to_date_p)
|
||||
set_frame_menubar (f, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
return call2 (Qpopup_menu, call0 (Qmouse_menu_bar_map),
|
||||
last_nonmenu_event);
|
||||
}
|
||||
|
||||
block_input ();
|
||||
BMenuBar_start_tracking (FRAME_HAIKU_MENU_BAR (f));
|
||||
unblock_input ();
|
||||
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
void
|
||||
syms_of_haikumenu (void)
|
||||
{
|
||||
DEFSYM (Qdebug_on_next_call, "debug-on-next-call");
|
||||
DEFSYM (Qpopup_menu, "popup-menu");
|
||||
DEFSYM (Qmouse_menu_bar_map, "mouse-menu-bar-map");
|
||||
|
||||
defsubr (&Smenu_or_popup_active_p);
|
||||
defsubr (&Shaiku_menu_bar_open);
|
||||
return;
|
||||
}
|
134
src/haikuselect.c
Normal file
134
src/haikuselect.c
Normal file
|
@ -0,0 +1,134 @@
|
|||
/* Haiku window system selection support.
|
||||
Copyright (C) 2021 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Emacs.
|
||||
|
||||
GNU Emacs 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.
|
||||
|
||||
GNU Emacs 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 GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "lisp.h"
|
||||
#include "blockinput.h"
|
||||
#include "coding.h"
|
||||
#include "haikuselect.h"
|
||||
#include "haikuterm.h"
|
||||
|
||||
DEFUN ("haiku-selection-data", Fhaiku_selection_data, Shaiku_selection_data,
|
||||
2, 2, 0,
|
||||
doc: /* Retrieve content typed as NAME from the clipboard
|
||||
CLIPBOARD. CLIPBOARD is the symbol `PRIMARY', `SECONDARY' or
|
||||
`CLIPBOARD'. NAME is a MIME type denoting the type of the data to
|
||||
fetch. */)
|
||||
(Lisp_Object clipboard, Lisp_Object name)
|
||||
{
|
||||
CHECK_SYMBOL (clipboard);
|
||||
CHECK_STRING (name);
|
||||
char *dat;
|
||||
ssize_t len;
|
||||
|
||||
block_input ();
|
||||
if (EQ (clipboard, QPRIMARY))
|
||||
dat = BClipboard_find_primary_selection_data (SSDATA (name), &len);
|
||||
else if (EQ (clipboard, QSECONDARY))
|
||||
dat = BClipboard_find_secondary_selection_data (SSDATA (name), &len);
|
||||
else if (EQ (clipboard, QCLIPBOARD))
|
||||
dat = BClipboard_find_system_data (SSDATA (name), &len);
|
||||
else
|
||||
{
|
||||
unblock_input ();
|
||||
signal_error ("Bad clipboard", clipboard);
|
||||
}
|
||||
unblock_input ();
|
||||
|
||||
if (!dat)
|
||||
return Qnil;
|
||||
|
||||
Lisp_Object str = make_unibyte_string (dat, len);
|
||||
Lisp_Object lispy_type = Qnil;
|
||||
|
||||
if (!strcmp (SSDATA (name), "text/utf-8") ||
|
||||
!strcmp (SSDATA (name), "text/plain"))
|
||||
{
|
||||
if (string_ascii_p (str))
|
||||
lispy_type = QSTRING;
|
||||
else
|
||||
lispy_type = QUTF8_STRING;
|
||||
}
|
||||
|
||||
if (!NILP (lispy_type))
|
||||
Fput_text_property (make_fixnum (0), make_fixnum (len),
|
||||
Qforeign_selection, lispy_type, str);
|
||||
|
||||
block_input ();
|
||||
BClipboard_free_data (dat);
|
||||
unblock_input ();
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
DEFUN ("haiku-selection-put", Fhaiku_selection_put, Shaiku_selection_put,
|
||||
3, 3, 0,
|
||||
doc: /* Add or remove content from the clipboard CLIPBOARD.
|
||||
CLIPBOARD is the symbol `PRIMARY', `SECONDARY' or `CLIPBOARD'. NAME
|
||||
is a MIME type denoting the type of the data to add. DATA is the
|
||||
string that will be placed in the clipboard, or nil if the content is
|
||||
to be removed. If NAME is the string `text/utf-8' or the string
|
||||
`text/plain', encode it as UTF-8 before storing it into the
|
||||
clipboard. */)
|
||||
(Lisp_Object clipboard, Lisp_Object name, Lisp_Object data)
|
||||
{
|
||||
CHECK_SYMBOL (clipboard);
|
||||
CHECK_STRING (name);
|
||||
if (!NILP (data))
|
||||
CHECK_STRING (data);
|
||||
|
||||
block_input ();
|
||||
/* It seems that Haiku applications counter-intuitively expect
|
||||
UTF-8 data in both text/utf-8 and text/plain. */
|
||||
if (!NILP (data) && STRING_MULTIBYTE (data) &&
|
||||
(!strcmp (SSDATA (name), "text/utf-8") ||
|
||||
!strcmp (SSDATA (name), "text/plain")))
|
||||
data = ENCODE_UTF_8 (data);
|
||||
|
||||
char *dat = !NILP (data) ? SSDATA (data) : NULL;
|
||||
ptrdiff_t len = !NILP (data) ? SBYTES (data) : 0;
|
||||
|
||||
if (EQ (clipboard, QPRIMARY))
|
||||
BClipboard_set_primary_selection_data (SSDATA (name), dat, len);
|
||||
else if (EQ (clipboard, QSECONDARY))
|
||||
BClipboard_set_secondary_selection_data (SSDATA (name), dat, len);
|
||||
else if (EQ (clipboard, QCLIPBOARD))
|
||||
BClipboard_set_system_data (SSDATA (name), dat, len);
|
||||
else
|
||||
{
|
||||
unblock_input ();
|
||||
signal_error ("Bad clipboard", clipboard);
|
||||
}
|
||||
unblock_input ();
|
||||
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
void
|
||||
syms_of_haikuselect (void)
|
||||
{
|
||||
DEFSYM (QSECONDARY, "SECONDARY");
|
||||
DEFSYM (QCLIPBOARD, "CLIPBOARD");
|
||||
DEFSYM (QSTRING, "STRING");
|
||||
DEFSYM (QUTF8_STRING, "UTF8_STRING");
|
||||
DEFSYM (Qforeign_selection, "foreign-selection");
|
||||
|
||||
defsubr (&Shaiku_selection_data);
|
||||
defsubr (&Shaiku_selection_put);
|
||||
}
|
64
src/haikuselect.h
Normal file
64
src/haikuselect.h
Normal file
|
@ -0,0 +1,64 @@
|
|||
/* Haiku window system selection support. Hey Emacs, this is -*- C++ -*-
|
||||
Copyright (C) 2021 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Emacs.
|
||||
|
||||
GNU Emacs 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.
|
||||
|
||||
GNU Emacs 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 GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef _HAIKU_SELECT_H_
|
||||
#define _HAIKU_SELECT_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include <cstdio>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include <stdio.h>
|
||||
extern "C"
|
||||
{
|
||||
extern void init_haiku_select (void);
|
||||
#endif
|
||||
|
||||
/* Whether or not the selection was recently changed. */
|
||||
extern int selection_state_flag;
|
||||
|
||||
/* Find a string with the MIME type TYPE in the system clipboard. */
|
||||
extern char *
|
||||
BClipboard_find_system_data (const char *type, ssize_t *len);
|
||||
|
||||
/* Ditto, but for the primary selection and not clipboard. */
|
||||
extern char *
|
||||
BClipboard_find_primary_selection_data (const char *type, ssize_t *len);
|
||||
|
||||
/* Ditto, this time for the secondary selection. */
|
||||
extern char *
|
||||
BClipboard_find_secondary_selection_data (const char *type, ssize_t *len);
|
||||
|
||||
extern void
|
||||
BClipboard_set_system_data (const char *type, const char *data, ssize_t len);
|
||||
|
||||
extern void
|
||||
BClipboard_set_primary_selection_data (const char *type, const char *data,
|
||||
ssize_t len);
|
||||
|
||||
extern void
|
||||
BClipboard_set_secondary_selection_data (const char *type, const char *data,
|
||||
ssize_t len);
|
||||
|
||||
/* Free the returned data. */
|
||||
extern void BClipboard_free_data (void *ptr);
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif
|
||||
#endif /* _HAIKU_SELECT_H_ */
|
3608
src/haikuterm.c
Normal file
3608
src/haikuterm.c
Normal file
File diff suppressed because it is too large
Load diff
293
src/haikuterm.h
Normal file
293
src/haikuterm.h
Normal file
|
@ -0,0 +1,293 @@
|
|||
/* Haiku window system support
|
||||
Copyright (C) 2021 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Emacs.
|
||||
|
||||
GNU Emacs 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.
|
||||
|
||||
GNU Emacs 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 GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
#ifndef _HAIKU_TERM_H_
|
||||
#define _HAIKU_TERM_H_
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
#ifdef USE_BE_CAIRO
|
||||
#include <cairo.h>
|
||||
#endif
|
||||
|
||||
#include "haikugui.h"
|
||||
#include "frame.h"
|
||||
#include "character.h"
|
||||
#include "dispextern.h"
|
||||
#include "font.h"
|
||||
|
||||
#define C_FRAME struct frame *
|
||||
#define C_FONT struct font *
|
||||
#define C_TERMINAL struct terminal *
|
||||
|
||||
#define HAVE_CHAR_CACHE_MAX 65535
|
||||
|
||||
extern int popup_activated_p;
|
||||
|
||||
extern void be_app_quit (void);
|
||||
|
||||
struct haikufont_info
|
||||
{
|
||||
struct font font;
|
||||
haiku be_font;
|
||||
struct font_metrics **metrics;
|
||||
short metrics_nrows;
|
||||
|
||||
unsigned short **glyphs;
|
||||
};
|
||||
|
||||
struct haiku_bitmap_record
|
||||
{
|
||||
haiku img;
|
||||
char *file;
|
||||
int refcount;
|
||||
int height, width, depth;
|
||||
};
|
||||
|
||||
struct haiku_display_info
|
||||
{
|
||||
/* Chain of all haiku_display_info structures. */
|
||||
struct haiku_display_info *next;
|
||||
C_TERMINAL terminal;
|
||||
|
||||
Lisp_Object name_list_element;
|
||||
Lisp_Object color_map;
|
||||
|
||||
int n_fonts;
|
||||
|
||||
int smallest_char_width;
|
||||
int smallest_font_height;
|
||||
|
||||
struct frame *focused_frame;
|
||||
struct frame *focus_event_frame;
|
||||
struct frame *last_mouse_glyph_frame;
|
||||
|
||||
struct haiku_bitmap_record *bitmaps;
|
||||
ptrdiff_t bitmaps_size;
|
||||
ptrdiff_t bitmaps_last;
|
||||
|
||||
int grabbed;
|
||||
int n_planes;
|
||||
int color_p;
|
||||
|
||||
Window root_window;
|
||||
Lisp_Object rdb;
|
||||
|
||||
Emacs_Cursor vertical_scroll_bar_cursor;
|
||||
Emacs_Cursor horizontal_scroll_bar_cursor;
|
||||
|
||||
Mouse_HLInfo mouse_highlight;
|
||||
|
||||
C_FRAME highlight_frame;
|
||||
C_FRAME last_mouse_frame;
|
||||
C_FRAME last_mouse_motion_frame;
|
||||
|
||||
int last_mouse_motion_x;
|
||||
int last_mouse_motion_y;
|
||||
|
||||
struct haiku_rect last_mouse_glyph;
|
||||
|
||||
void *last_mouse_scroll_bar;
|
||||
|
||||
haiku display;
|
||||
|
||||
double resx, resy;
|
||||
};
|
||||
|
||||
struct haiku_output
|
||||
{
|
||||
Emacs_Cursor text_cursor;
|
||||
Emacs_Cursor nontext_cursor;
|
||||
Emacs_Cursor modeline_cursor;
|
||||
Emacs_Cursor hand_cursor;
|
||||
Emacs_Cursor hourglass_cursor;
|
||||
Emacs_Cursor horizontal_drag_cursor;
|
||||
Emacs_Cursor vertical_drag_cursor;
|
||||
Emacs_Cursor left_edge_cursor;
|
||||
Emacs_Cursor top_left_corner_cursor;
|
||||
Emacs_Cursor top_edge_cursor;
|
||||
Emacs_Cursor top_right_corner_cursor;
|
||||
Emacs_Cursor right_edge_cursor;
|
||||
Emacs_Cursor bottom_right_corner_cursor;
|
||||
Emacs_Cursor bottom_edge_cursor;
|
||||
Emacs_Cursor bottom_left_corner_cursor;
|
||||
Emacs_Cursor no_cursor;
|
||||
|
||||
Emacs_Cursor current_cursor;
|
||||
|
||||
struct haiku_display_info *display_info;
|
||||
|
||||
int baseline_offset;
|
||||
int fontset;
|
||||
|
||||
Emacs_Color cursor_color;
|
||||
|
||||
Window window_desc, parent_desc;
|
||||
char explicit_parent;
|
||||
|
||||
int titlebar_height;
|
||||
int toolbar_height;
|
||||
|
||||
haiku window;
|
||||
haiku view;
|
||||
haiku menubar;
|
||||
|
||||
int menu_up_to_date_p;
|
||||
int zoomed_p;
|
||||
|
||||
int pending_zoom_x;
|
||||
int pending_zoom_y;
|
||||
int pending_zoom_width;
|
||||
int pending_zoom_height;
|
||||
|
||||
int menu_bar_open_p;
|
||||
|
||||
C_FONT font;
|
||||
|
||||
int hourglass_p;
|
||||
uint32_t cursor_fg;
|
||||
bool dirty_p;
|
||||
|
||||
/* The pending position we're waiting for. */
|
||||
int pending_top, pending_left;
|
||||
};
|
||||
|
||||
struct x_output
|
||||
{
|
||||
/* Unused, makes term.c happy. */
|
||||
};
|
||||
|
||||
extern struct haiku_display_info *x_display_list;
|
||||
extern struct font_driver const haikufont_driver;
|
||||
|
||||
struct scroll_bar
|
||||
{
|
||||
/* These fields are shared by all vectors. */
|
||||
union vectorlike_header header;
|
||||
|
||||
/* The window we're a scroll bar for. */
|
||||
Lisp_Object window;
|
||||
|
||||
/* The next and previous in the chain of scroll bars in this frame. */
|
||||
Lisp_Object next, prev;
|
||||
|
||||
/* Fields after 'prev' are not traced by the GC. */
|
||||
|
||||
/* The position and size of the scroll bar in pixels, relative to the
|
||||
frame. */
|
||||
int top, left, width, height;
|
||||
|
||||
/* The actual scrollbar. */
|
||||
void *scroll_bar;
|
||||
|
||||
/* Non-nil if the scroll bar handle is currently being dragged by
|
||||
the user. */
|
||||
int dragging;
|
||||
|
||||
/* The update position if we are waiting for a scrollbar update, or
|
||||
-1. */
|
||||
int update;
|
||||
|
||||
/* The last known position of this scrollbar. */
|
||||
int position;
|
||||
|
||||
/* The total number of units inside this scrollbar. */
|
||||
int total;
|
||||
|
||||
/* True if the scroll bar is horizontal. */
|
||||
bool horizontal;
|
||||
};
|
||||
|
||||
#define XSCROLL_BAR(vec) ((struct scroll_bar *) XVECTOR (vec))
|
||||
|
||||
#define FRAME_DIRTY_P(f) (FRAME_OUTPUT_DATA (f)->dirty_p)
|
||||
#define MAKE_FRAME_DIRTY(f) (FRAME_DIRTY_P (f) = 1)
|
||||
#define FRAME_OUTPUT_DATA(f) ((f)->output_data.haiku)
|
||||
#define FRAME_HAIKU_WINDOW(f) (FRAME_OUTPUT_DATA (f)->window)
|
||||
#define FRAME_HAIKU_VIEW(f) ((MAKE_FRAME_DIRTY (f)), FRAME_OUTPUT_DATA (f)->view)
|
||||
#define FRAME_HAIKU_MENU_BAR(f) (FRAME_OUTPUT_DATA (f)->menubar)
|
||||
#define FRAME_DISPLAY_INFO(f) (FRAME_OUTPUT_DATA (f)->display_info)
|
||||
#define FRAME_FONT(f) (FRAME_OUTPUT_DATA (f)->font)
|
||||
#define FRAME_FONTSET(f) (FRAME_OUTPUT_DATA (f)->fontset)
|
||||
#define FRAME_NATIVE_WINDOW(f) (FRAME_OUTPUT_DATA (f)->window)
|
||||
#define FRAME_BASELINE_OFFSET(f) (FRAME_OUTPUT_DATA (f)->baseline_offset)
|
||||
#define FRAME_CURSOR_COLOR(f) (FRAME_OUTPUT_DATA (f)->cursor_color)
|
||||
|
||||
#ifdef USE_BE_CAIRO
|
||||
#define FRAME_CR_SURFACE(f) \
|
||||
(FRAME_HAIKU_VIEW (f) ? EmacsView_cairo_surface (FRAME_HAIKU_VIEW (f)) : 0);
|
||||
#endif
|
||||
|
||||
extern void syms_of_haikuterm (void);
|
||||
extern void syms_of_haikufns (void);
|
||||
extern void syms_of_haikumenu (void);
|
||||
extern void syms_of_haikufont (void);
|
||||
extern void syms_of_haikuselect (void);
|
||||
extern void init_haiku_select (void);
|
||||
|
||||
extern void haiku_iconify_frame (struct frame *);
|
||||
extern void haiku_visualize_frame (struct frame *);
|
||||
extern void haiku_unvisualize_frame (struct frame *);
|
||||
extern void haiku_set_offset (struct frame *, int, int, int);
|
||||
extern void haiku_set_frame_visible_invisible (struct frame *, bool);
|
||||
extern void haiku_free_frame_resources (struct frame *f);
|
||||
extern void haiku_scroll_bar_remove (struct scroll_bar *bar);
|
||||
extern void haiku_clear_under_internal_border (struct frame *f);
|
||||
extern void haiku_set_name (struct frame *f, Lisp_Object name, bool explicit_p);
|
||||
|
||||
extern struct haiku_display_info *haiku_term_init (void);
|
||||
|
||||
extern void mark_haiku_display (void);
|
||||
|
||||
extern int haiku_get_color (const char *name, Emacs_Color *color);
|
||||
extern void haiku_set_background_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval);
|
||||
extern void haiku_set_cursor_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval);
|
||||
extern void haiku_set_cursor_type (struct frame *f, Lisp_Object arg, Lisp_Object oldval);
|
||||
extern void haiku_set_internal_border_width (struct frame *f, Lisp_Object arg, Lisp_Object oldval);
|
||||
extern void haiku_change_tab_bar_height (struct frame *f, int height);
|
||||
extern void haiku_change_tool_bar_height (struct frame *f, int height);
|
||||
|
||||
extern void haiku_query_color (uint32_t col, Emacs_Color *color);
|
||||
|
||||
extern unsigned long haiku_get_pixel (haiku bitmap, int x, int y);
|
||||
extern void haiku_put_pixel (haiku bitmap, int x, int y, unsigned long pixel);
|
||||
|
||||
extern Lisp_Object haiku_menu_show (struct frame *f, int x, int y, int menu_flags,
|
||||
Lisp_Object title, const char **error_name);
|
||||
extern Lisp_Object haiku_popup_dialog (struct frame *f, Lisp_Object header, Lisp_Object contents);
|
||||
|
||||
extern void initialize_frame_menubar (struct frame *f);
|
||||
|
||||
extern void run_menu_bar_help_event (struct frame *f, int mb_idx);
|
||||
extern void put_xrm_resource (Lisp_Object name, Lisp_Object val);
|
||||
|
||||
#ifdef HAVE_NATIVE_IMAGE_API
|
||||
extern bool haiku_can_use_native_image_api (Lisp_Object type);
|
||||
extern int haiku_load_image (struct frame *f, struct image *img,
|
||||
Lisp_Object spec_file, Lisp_Object spec_data);
|
||||
extern void syms_of_haikuimage (void);
|
||||
#endif
|
||||
|
||||
#ifdef USE_BE_CAIRO
|
||||
extern cairo_t *
|
||||
haiku_begin_cr_clip (struct frame *f, struct glyph_string *s);
|
||||
|
||||
extern void
|
||||
haiku_end_cr_clip (cairo_t *cr);
|
||||
#endif
|
||||
#endif /* _HAIKU_TERM_H_ */
|
142
src/image.c
142
src/image.c
|
@ -20,6 +20,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
|||
#include <config.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <math.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/* Include this before including <setjmp.h> to work around bugs with
|
||||
|
@ -135,6 +136,27 @@ typedef struct ns_bitmap_record Bitmap_Record;
|
|||
# define COLOR_TABLE_SUPPORT 1
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_HAIKU
|
||||
#include "haiku_support.h"
|
||||
typedef struct haiku_bitmap_record Bitmap_Record;
|
||||
|
||||
#define GET_PIXEL(ximg, x, y) haiku_get_pixel (ximg, x, y)
|
||||
#define PUT_PIXEL haiku_put_pixel
|
||||
#define NO_PIXMAP 0
|
||||
|
||||
#define PIX_MASK_RETAIN 0
|
||||
#define PIX_MASK_DRAW 1
|
||||
|
||||
#define RGB_TO_ULONG(r, g, b) (((r) << 16) | ((g) << 8) | (b))
|
||||
#define RED_FROM_ULONG(color) (((color) >> 16) & 0xff)
|
||||
#define GREEN_FROM_ULONG(color) (((color) >> 8) & 0xff)
|
||||
#define BLUE_FROM_ULONG(color) ((color) & 0xff)
|
||||
#define RED16_FROM_ULONG(color) (RED_FROM_ULONG (color) * 0x101)
|
||||
#define GREEN16_FROM_ULONG(color) (GREEN_FROM_ULONG (color) * 0x101)
|
||||
#define BLUE16_FROM_ULONG(color) (BLUE_FROM_ULONG (color) * 0x101)
|
||||
|
||||
#endif
|
||||
|
||||
static void image_disable_image (struct frame *, struct image *);
|
||||
static void image_edge_detection (struct frame *, struct image *, Lisp_Object,
|
||||
Lisp_Object);
|
||||
|
@ -430,6 +452,11 @@ image_create_bitmap_from_data (struct frame *f, char *bits,
|
|||
return -1;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_HAIKU
|
||||
void *bitmap = BBitmap_new (width, height, 1);
|
||||
BBitmap_import_mono_bits (bitmap, bits, width, height);
|
||||
#endif
|
||||
|
||||
id = image_allocate_bitmap_record (f);
|
||||
|
||||
#ifdef HAVE_NS
|
||||
|
@ -437,6 +464,11 @@ image_create_bitmap_from_data (struct frame *f, char *bits,
|
|||
dpyinfo->bitmaps[id - 1].depth = 1;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_HAIKU
|
||||
dpyinfo->bitmaps[id - 1].img = bitmap;
|
||||
dpyinfo->bitmaps[id - 1].depth = 1;
|
||||
#endif
|
||||
|
||||
dpyinfo->bitmaps[id - 1].file = NULL;
|
||||
dpyinfo->bitmaps[id - 1].height = height;
|
||||
dpyinfo->bitmaps[id - 1].width = width;
|
||||
|
@ -465,7 +497,7 @@ image_create_bitmap_from_data (struct frame *f, char *bits,
|
|||
ptrdiff_t
|
||||
image_create_bitmap_from_file (struct frame *f, Lisp_Object file)
|
||||
{
|
||||
#ifdef HAVE_NTGUI
|
||||
#if defined (HAVE_NTGUI) || defined (HAVE_HAIKU)
|
||||
return -1; /* W32_TODO : bitmap support */
|
||||
#else
|
||||
Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f);
|
||||
|
@ -561,6 +593,10 @@ free_bitmap_record (Display_Info *dpyinfo, Bitmap_Record *bm)
|
|||
ns_release_object (bm->img);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_HAIKU
|
||||
BBitmap_free (bm->img);
|
||||
#endif
|
||||
|
||||
if (bm->file)
|
||||
{
|
||||
xfree (bm->file);
|
||||
|
@ -1834,6 +1870,11 @@ image_size_in_bytes (struct image *img)
|
|||
if (img->mask)
|
||||
size += w32_image_size (img->mask);
|
||||
|
||||
#elif defined HAVE_HAIKU
|
||||
if (img->pixmap)
|
||||
size += BBitmap_bytes_length (img->pixmap);
|
||||
if (img->mask)
|
||||
size += BBitmap_bytes_length (img->mask);
|
||||
#endif
|
||||
|
||||
return size;
|
||||
|
@ -2173,6 +2214,7 @@ compute_image_size (size_t width, size_t height,
|
|||
single step, but the maths for each element is much more complex
|
||||
and performing the steps separately makes for more readable code. */
|
||||
|
||||
#ifndef HAVE_HAIKU
|
||||
typedef double matrix3x3[3][3];
|
||||
|
||||
static void
|
||||
|
@ -2187,6 +2229,7 @@ matrix3x3_mult (matrix3x3 a, matrix3x3 b, matrix3x3 result)
|
|||
result[i][j] = sum;
|
||||
}
|
||||
}
|
||||
#endif /* not HAVE_HAIKU */
|
||||
|
||||
static void
|
||||
compute_image_rotation (struct image *img, double *rotation)
|
||||
|
@ -2244,6 +2287,7 @@ image_set_transform (struct frame *f, struct image *img)
|
|||
double rotation = 0.0;
|
||||
compute_image_rotation (img, &rotation);
|
||||
|
||||
#ifndef HAVE_HAIKU
|
||||
# if defined USE_CAIRO || defined HAVE_XRENDER || defined HAVE_NS
|
||||
/* We want scale up operations to use a nearest neighbor filter to
|
||||
show real pixels instead of munging them, but scale down
|
||||
|
@ -2414,6 +2458,34 @@ image_set_transform (struct frame *f, struct image *img)
|
|||
img->xform.eDx = matrix[2][0];
|
||||
img->xform.eDy = matrix[2][1];
|
||||
# endif
|
||||
#else
|
||||
if (rotation != 0 &&
|
||||
rotation != 90 &&
|
||||
rotation != 180 &&
|
||||
rotation != 270 &&
|
||||
rotation != 360)
|
||||
{
|
||||
image_error ("No native support for rotation by %g degrees",
|
||||
make_float (rotation));
|
||||
return;
|
||||
}
|
||||
|
||||
rotation = fmod (rotation, 360.0);
|
||||
|
||||
if (rotation == 90 || rotation == 270)
|
||||
{
|
||||
int w = width;
|
||||
width = height;
|
||||
height = w;
|
||||
}
|
||||
|
||||
img->have_be_transforms_p = rotation != 0 || (img->width != width) || (img->height != height);
|
||||
img->be_rotate = rotation;
|
||||
img->be_scale_x = 1.0 / (img->width / (double) width);
|
||||
img->be_scale_y = 1.0 / (img->height / (double) height);
|
||||
img->width = width;
|
||||
img->height = height;
|
||||
#endif /* not HAVE_HAIKU */
|
||||
}
|
||||
|
||||
#endif /* HAVE_IMAGEMAGICK || HAVE_NATIVE_TRANSFORMS */
|
||||
|
@ -2820,6 +2892,30 @@ image_create_x_image_and_pixmap_1 (struct frame *f, int width, int height, int d
|
|||
return 1;
|
||||
#endif /* HAVE_X_WINDOWS */
|
||||
|
||||
#ifdef HAVE_HAIKU
|
||||
if (depth == 0)
|
||||
depth = 24;
|
||||
|
||||
if (depth != 24 && depth != 1)
|
||||
{
|
||||
*pimg = NULL;
|
||||
image_error ("Invalid image bit depth specified");
|
||||
return 0;
|
||||
}
|
||||
|
||||
*pixmap = BBitmap_new (width, height, depth == 1);
|
||||
|
||||
if (*pixmap == NO_PIXMAP)
|
||||
{
|
||||
*pimg = NULL;
|
||||
image_error ("Unable to create pixmap", Qnil, Qnil);
|
||||
return 0;
|
||||
}
|
||||
|
||||
*pimg = *pixmap;
|
||||
return 1;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_NTGUI
|
||||
|
||||
BITMAPINFOHEADER *header;
|
||||
|
@ -2960,7 +3056,7 @@ static void
|
|||
gui_put_x_image (struct frame *f, Emacs_Pix_Container pimg,
|
||||
Emacs_Pixmap pixmap, int width, int height)
|
||||
{
|
||||
#ifdef USE_CAIRO
|
||||
#if defined USE_CAIRO || defined HAVE_HAIKU
|
||||
eassert (pimg == pixmap);
|
||||
#elif defined HAVE_X_WINDOWS
|
||||
GC gc;
|
||||
|
@ -3087,7 +3183,7 @@ image_unget_x_image_or_dc (struct image *img, bool mask_p,
|
|||
static Emacs_Pix_Container
|
||||
image_get_x_image (struct frame *f, struct image *img, bool mask_p)
|
||||
{
|
||||
#ifdef USE_CAIRO
|
||||
#if defined USE_CAIRO || defined (HAVE_HAIKU)
|
||||
return !mask_p ? img->pixmap : img->mask;
|
||||
#elif defined HAVE_X_WINDOWS
|
||||
XImage *ximg_in_img = !mask_p ? img->ximg : img->mask_img;
|
||||
|
@ -4036,7 +4132,7 @@ xbm_load (struct frame *f, struct image *img)
|
|||
#endif /* not HAVE_NTGUI */
|
||||
#endif /* HAVE_XPM */
|
||||
|
||||
#if defined HAVE_XPM || defined USE_CAIRO || defined HAVE_NS
|
||||
#if defined HAVE_XPM || defined USE_CAIRO || defined HAVE_NS || defined HAVE_HAIKU
|
||||
|
||||
/* Indices of image specification fields in xpm_format, below. */
|
||||
|
||||
|
@ -4056,7 +4152,7 @@ enum xpm_keyword_index
|
|||
XPM_LAST
|
||||
};
|
||||
|
||||
#if defined HAVE_XPM || defined HAVE_NS
|
||||
#if defined HAVE_XPM || defined HAVE_NS || defined HAVE_HAIKU
|
||||
/* Vector of image_keyword structures describing the format
|
||||
of valid XPM image specifications. */
|
||||
|
||||
|
@ -4074,7 +4170,7 @@ static const struct image_keyword xpm_format[XPM_LAST] =
|
|||
{":color-symbols", IMAGE_DONT_CHECK_VALUE_TYPE, 0},
|
||||
{":background", IMAGE_STRING_OR_NIL_VALUE, 0}
|
||||
};
|
||||
#endif /* HAVE_XPM || HAVE_NS */
|
||||
#endif /* HAVE_XPM || HAVE_NS || HAVE_HAIKU */
|
||||
|
||||
#if defined HAVE_X_WINDOWS && !defined USE_CAIRO
|
||||
|
||||
|
@ -4298,7 +4394,7 @@ init_xpm_functions (void)
|
|||
|
||||
#endif /* WINDOWSNT */
|
||||
|
||||
#if defined HAVE_XPM || defined HAVE_NS
|
||||
#if defined HAVE_XPM || defined HAVE_NS || defined HAVE_HAIKU
|
||||
/* Value is true if COLOR_SYMBOLS is a valid color symbols list
|
||||
for XPM images. Such a list must consist of conses whose car and
|
||||
cdr are strings. */
|
||||
|
@ -4334,9 +4430,9 @@ xpm_image_p (Lisp_Object object)
|
|||
&& (! fmt[XPM_COLOR_SYMBOLS].count
|
||||
|| xpm_valid_color_symbols_p (fmt[XPM_COLOR_SYMBOLS].value)));
|
||||
}
|
||||
#endif /* HAVE_XPM || HAVE_NS */
|
||||
#endif /* HAVE_XPM || HAVE_NS || HAVE_HAIKU */
|
||||
|
||||
#endif /* HAVE_XPM || USE_CAIRO || HAVE_NS */
|
||||
#endif /* HAVE_XPM || USE_CAIRO || HAVE_NS || HAVE_HAIKU */
|
||||
|
||||
#if defined HAVE_XPM && defined HAVE_X_WINDOWS && !defined USE_GTK
|
||||
ptrdiff_t
|
||||
|
@ -4705,9 +4801,10 @@ xpm_load (struct frame *f, struct image *img)
|
|||
#endif /* HAVE_XPM && !USE_CAIRO */
|
||||
|
||||
#if (defined USE_CAIRO && defined HAVE_XPM) \
|
||||
|| (defined HAVE_NS && !defined HAVE_XPM)
|
||||
|| (defined HAVE_NS && !defined HAVE_XPM) \
|
||||
|| (defined HAVE_HAIKU && !defined HAVE_XPM)
|
||||
|
||||
/* XPM support functions for NS where libxpm is not available, and for
|
||||
/* XPM support functions for NS and Haiku where libxpm is not available, and for
|
||||
Cairo. Only XPM version 3 (without any extensions) is supported. */
|
||||
|
||||
static void xpm_put_color_table_v (Lisp_Object, const char *,
|
||||
|
@ -5444,7 +5541,7 @@ lookup_rgb_color (struct frame *f, int r, int g, int b)
|
|||
{
|
||||
#ifdef HAVE_NTGUI
|
||||
return PALETTERGB (r >> 8, g >> 8, b >> 8);
|
||||
#elif defined USE_CAIRO || defined HAVE_NS
|
||||
#elif defined USE_CAIRO || defined HAVE_NS || defined HAVE_HAIKU
|
||||
return RGB_TO_ULONG (r >> 8, g >> 8, b >> 8);
|
||||
#else
|
||||
xsignal1 (Qfile_error,
|
||||
|
@ -5517,7 +5614,7 @@ image_to_emacs_colors (struct frame *f, struct image *img, bool rgb_p)
|
|||
p = colors;
|
||||
for (y = 0; y < img->height; ++y)
|
||||
{
|
||||
#if !defined USE_CAIRO && !defined HAVE_NS
|
||||
#if !defined USE_CAIRO && !defined HAVE_NS && !defined HAVE_HAIKU
|
||||
Emacs_Color *row = p;
|
||||
for (x = 0; x < img->width; ++x, ++p)
|
||||
p->pixel = GET_PIXEL (ximg, x, y);
|
||||
|
@ -5525,7 +5622,7 @@ image_to_emacs_colors (struct frame *f, struct image *img, bool rgb_p)
|
|||
{
|
||||
FRAME_TERMINAL (f)->query_colors (f, row, img->width);
|
||||
}
|
||||
#else /* USE_CAIRO || HAVE_NS */
|
||||
#else /* USE_CAIRO || HAVE_NS || HAVE_HAIKU */
|
||||
for (x = 0; x < img->width; ++x, ++p)
|
||||
{
|
||||
p->pixel = GET_PIXEL (ximg, x, y);
|
||||
|
@ -5839,6 +5936,7 @@ image_disable_image (struct frame *f, struct image *img)
|
|||
{
|
||||
#ifndef HAVE_NTGUI
|
||||
#ifndef HAVE_NS /* TODO: NS support, however this not needed for toolbars */
|
||||
#ifndef HAVE_HAIKU
|
||||
|
||||
#ifndef USE_CAIRO
|
||||
#define CrossForeground(f) BLACK_PIX_DEFAULT (f)
|
||||
|
@ -5856,6 +5954,7 @@ image_disable_image (struct frame *f, struct image *img)
|
|||
if (img->mask)
|
||||
image_pixmap_draw_cross (f, img->mask, 0, 0, img->width, img->height,
|
||||
MaskForeground (f));
|
||||
#endif /* !HAVE_HAIKU */
|
||||
#endif /* !HAVE_NS */
|
||||
#else
|
||||
HDC hdc, bmpdc;
|
||||
|
@ -6413,6 +6512,8 @@ image_can_use_native_api (Lisp_Object type)
|
|||
return w32_can_use_native_image_api (type);
|
||||
# elif defined HAVE_NS
|
||||
return ns_can_use_native_image_api (type);
|
||||
# elif defined HAVE_HAIKU
|
||||
return haiku_can_use_native_image_api (type);
|
||||
# else
|
||||
return false;
|
||||
# endif
|
||||
|
@ -6486,6 +6587,9 @@ native_image_load (struct frame *f, struct image *img)
|
|||
# elif defined HAVE_NS
|
||||
return ns_load_image (f, img, image_file,
|
||||
image_spec_value (img->spec, QCdata, NULL));
|
||||
# elif defined HAVE_HAIKU
|
||||
return haiku_load_image (f, img, image_file,
|
||||
image_spec_value (img->spec, QCdata, NULL));
|
||||
# else
|
||||
return 0;
|
||||
# endif
|
||||
|
@ -9635,7 +9739,8 @@ imagemagick_load_image (struct frame *f, struct image *img,
|
|||
|
||||
init_color_table ();
|
||||
|
||||
#if defined (HAVE_MAGICKEXPORTIMAGEPIXELS) && ! defined (HAVE_NS)
|
||||
#if defined (HAVE_MAGICKEXPORTIMAGEPIXELS) && \
|
||||
! defined (HAVE_NS) && ! defined (HAVE_HAIKU)
|
||||
if (imagemagick_render_type != 0)
|
||||
{
|
||||
/* Magicexportimage is normally faster than pixelpushing. This
|
||||
|
@ -10925,7 +11030,8 @@ The list of capabilities can include one or more of the following:
|
|||
if (FRAME_WINDOW_P (f))
|
||||
{
|
||||
#ifdef HAVE_NATIVE_TRANSFORMS
|
||||
# if defined HAVE_IMAGEMAGICK || defined (USE_CAIRO) || defined (HAVE_NS)
|
||||
# if defined HAVE_IMAGEMAGICK || defined (USE_CAIRO) || defined (HAVE_NS) \
|
||||
|| defined (HAVE_HAIKU)
|
||||
return list2 (Qscale, Qrotate90);
|
||||
# elif defined (HAVE_X_WINDOWS) && defined (HAVE_XRENDER)
|
||||
int event_basep, error_basep;
|
||||
|
@ -11015,7 +11121,7 @@ static struct image_type const image_types[] =
|
|||
{ SYMBOL_INDEX (Qjpeg), jpeg_image_p, jpeg_load, image_clear_image,
|
||||
IMAGE_TYPE_INIT (init_jpeg_functions) },
|
||||
#endif
|
||||
#if defined HAVE_XPM || defined HAVE_NS
|
||||
#if defined HAVE_XPM || defined HAVE_NS || defined HAVE_HAIKU
|
||||
{ SYMBOL_INDEX (Qxpm), xpm_image_p, xpm_load, image_clear_image,
|
||||
IMAGE_TYPE_INIT (init_xpm_functions) },
|
||||
#endif
|
||||
|
@ -11163,7 +11269,7 @@ non-numeric, there is no explicit limit on the size of images. */);
|
|||
DEFSYM (Qxbm, "xbm");
|
||||
add_image_type (Qxbm);
|
||||
|
||||
#if defined (HAVE_XPM) || defined (HAVE_NS)
|
||||
#if defined (HAVE_XPM) || defined (HAVE_NS) || defined (HAVE_HAIKU)
|
||||
DEFSYM (Qxpm, "xpm");
|
||||
add_image_type (Qxpm);
|
||||
#endif
|
||||
|
|
|
@ -3865,7 +3865,7 @@ kbd_buffer_get_event (KBOARD **kbp,
|
|||
/* One way or another, wait until input is available; then, if
|
||||
interrupt handlers have not read it, read it now. */
|
||||
|
||||
#ifdef USABLE_SIGIO
|
||||
#if defined (USABLE_SIGIO) || defined (USABLE_SIGPOLL)
|
||||
gobble_input ();
|
||||
#endif
|
||||
if (kbd_fetch_ptr != kbd_store_ptr)
|
||||
|
@ -6156,7 +6156,6 @@ make_lispy_event (struct input_event *event)
|
|||
case CONFIG_CHANGED_EVENT:
|
||||
return list3 (Qconfig_changed_event,
|
||||
event->arg, event->frame_or_window);
|
||||
|
||||
/* The 'kind' field of the event is something we don't recognize. */
|
||||
default:
|
||||
emacs_abort ();
|
||||
|
@ -7247,7 +7246,7 @@ totally_unblock_input (void)
|
|||
unblock_input_to (0);
|
||||
}
|
||||
|
||||
#ifdef USABLE_SIGIO
|
||||
#if defined (USABLE_SIGIO) || defined (USABLE_SIGPOLL)
|
||||
|
||||
void
|
||||
handle_input_available_signal (int sig)
|
||||
|
@ -7263,7 +7262,7 @@ deliver_input_available_signal (int sig)
|
|||
{
|
||||
deliver_process_signal (sig, handle_input_available_signal);
|
||||
}
|
||||
#endif /* USABLE_SIGIO */
|
||||
#endif /* defined (USABLE_SIGIO) || defined (USABLE_SIGPOLL) */
|
||||
|
||||
|
||||
/* User signal events. */
|
||||
|
@ -7333,7 +7332,7 @@ handle_user_signal (int sig)
|
|||
}
|
||||
|
||||
p->npending++;
|
||||
#ifdef USABLE_SIGIO
|
||||
#if defined (USABLE_SIGIO) || defined (USABLE_SIGPOLL)
|
||||
if (interrupt_input)
|
||||
handle_input_available_signal (sig);
|
||||
else
|
||||
|
@ -11103,7 +11102,7 @@ See also `current-input-mode'. */)
|
|||
(Lisp_Object interrupt)
|
||||
{
|
||||
bool new_interrupt_input;
|
||||
#ifdef USABLE_SIGIO
|
||||
#if defined (USABLE_SIGIO) || defined (USABLE_SIGPOLL)
|
||||
#ifdef HAVE_X_WINDOWS
|
||||
if (x_display_list != NULL)
|
||||
{
|
||||
|
@ -11114,9 +11113,9 @@ See also `current-input-mode'. */)
|
|||
else
|
||||
#endif /* HAVE_X_WINDOWS */
|
||||
new_interrupt_input = !NILP (interrupt);
|
||||
#else /* not USABLE_SIGIO */
|
||||
#else /* not USABLE_SIGIO || USABLE_SIGPOLL */
|
||||
new_interrupt_input = false;
|
||||
#endif /* not USABLE_SIGIO */
|
||||
#endif /* not USABLE_SIGIO || USABLE_SIGPOLL */
|
||||
|
||||
if (new_interrupt_input != interrupt_input)
|
||||
{
|
||||
|
@ -11545,12 +11544,16 @@ init_keyboard (void)
|
|||
sigaction (SIGQUIT, &action, 0);
|
||||
#endif /* not DOS_NT */
|
||||
}
|
||||
#ifdef USABLE_SIGIO
|
||||
#if defined (USABLE_SIGIO) || defined (USABLE_SIGPOLL)
|
||||
if (!noninteractive)
|
||||
{
|
||||
struct sigaction action;
|
||||
emacs_sigaction_init (&action, deliver_input_available_signal);
|
||||
#ifdef USABLE_SIGIO
|
||||
sigaction (SIGIO, &action, 0);
|
||||
#else
|
||||
sigaction (SIGPOLL, &action, 0);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
14
src/lisp.h
14
src/lisp.h
|
@ -138,7 +138,12 @@ verify (BITS_WORD_MAX >> (BITS_PER_BITS_WORD - 1) == 1);
|
|||
buffers and strings. Emacs never allocates objects larger than
|
||||
PTRDIFF_MAX bytes, as they cause problems with pointer subtraction.
|
||||
In C99, pD can always be "t"; configure it here for the sake of
|
||||
pre-C99 libraries such as glibc 2.0 and Solaris 8. */
|
||||
pre-C99 libraries such as glibc 2.0 and Solaris 8.
|
||||
|
||||
On Haiku, the size of ptrdiff_t is inconsistent with the value of
|
||||
PTRDIFF_MAX. In that case, "t" should be sufficient. */
|
||||
|
||||
#ifndef HAIKU
|
||||
#if PTRDIFF_MAX == INT_MAX
|
||||
# define pD ""
|
||||
#elif PTRDIFF_MAX == LONG_MAX
|
||||
|
@ -148,6 +153,9 @@ verify (BITS_WORD_MAX >> (BITS_PER_BITS_WORD - 1) == 1);
|
|||
#else
|
||||
# define pD "t"
|
||||
#endif
|
||||
#else
|
||||
# define pD "t"
|
||||
#endif
|
||||
|
||||
/* Convenience macro for rarely-used functions that do not return. */
|
||||
#define AVOID _Noreturn ATTRIBUTE_COLD void
|
||||
|
@ -3330,7 +3338,7 @@ struct frame;
|
|||
|
||||
/* Define if the windowing system provides a menu bar. */
|
||||
#if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) \
|
||||
|| defined (HAVE_NS) || defined (USE_GTK)
|
||||
|| defined (HAVE_NS) || defined (USE_GTK) || defined (HAVE_HAIKU)
|
||||
#define HAVE_EXT_MENU_BAR true
|
||||
#endif
|
||||
|
||||
|
@ -4429,7 +4437,7 @@ extern Lisp_Object menu_bar_items (Lisp_Object);
|
|||
extern Lisp_Object tab_bar_items (Lisp_Object, int *);
|
||||
extern Lisp_Object tool_bar_items (Lisp_Object, int *);
|
||||
extern void discard_mouse_events (void);
|
||||
#ifdef USABLE_SIGIO
|
||||
#if defined (USABLE_SIGIO) || defined (USABLE_SIGPOLL)
|
||||
void handle_input_available_signal (int);
|
||||
#endif
|
||||
extern Lisp_Object pending_funcalls;
|
||||
|
|
12
src/menu.c
12
src/menu.c
|
@ -50,7 +50,8 @@ extern AppendMenuW_Proc unicode_append_menu;
|
|||
static bool
|
||||
have_boxes (void)
|
||||
{
|
||||
#if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NTGUI) || defined(HAVE_NS)
|
||||
#if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NTGUI) || defined (HAVE_NS) \
|
||||
|| defined (HAVE_HAIKU)
|
||||
if (FRAME_WINDOW_P (XFRAME (Vmenu_updating_frame)))
|
||||
return 1;
|
||||
#endif
|
||||
|
@ -422,7 +423,8 @@ single_menu_item (Lisp_Object key, Lisp_Object item, Lisp_Object dummy, void *sk
|
|||
AREF (item_properties, ITEM_PROPERTY_SELECTED),
|
||||
AREF (item_properties, ITEM_PROPERTY_HELP));
|
||||
|
||||
#if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS) || defined (HAVE_NTGUI)
|
||||
#if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS) \
|
||||
|| defined (HAVE_NTGUI) || defined (HAVE_HAIKU)
|
||||
/* Display a submenu using the toolkit. */
|
||||
if (FRAME_WINDOW_P (XFRAME (Vmenu_updating_frame))
|
||||
&& ! (NILP (map) || NILP (enabled)))
|
||||
|
@ -872,6 +874,10 @@ update_submenu_strings (widget_value *first_wv)
|
|||
}
|
||||
}
|
||||
|
||||
#endif /* USE_X_TOOLKIT || USE_GTK || HAVE_NS || HAVE_NTGUI */
|
||||
#if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NS) \
|
||||
|| defined (HAVE_NTGUI) || defined (HAVE_HAIKU)
|
||||
|
||||
/* Find the menu selection and store it in the keyboard buffer.
|
||||
F is the frame the menu is on.
|
||||
MENU_BAR_ITEMS_USED is the length of VECTOR.
|
||||
|
@ -959,7 +965,7 @@ find_and_call_menu_selection (struct frame *f, int menu_bar_items_used,
|
|||
SAFE_FREE ();
|
||||
}
|
||||
|
||||
#endif /* USE_X_TOOLKIT || USE_GTK || HAVE_NS || HAVE_NTGUI */
|
||||
#endif /* USE_X_TOOLKIT || USE_GTK || HAVE_NS || HAVE_NTGUI || HAVE_HAIKU */
|
||||
|
||||
#ifdef HAVE_NS
|
||||
/* As above, but return the menu selection instead of storing in kb buffer.
|
||||
|
|
|
@ -259,7 +259,7 @@ static bool process_output_skip;
|
|||
|
||||
static void start_process_unwind (Lisp_Object);
|
||||
static void create_process (Lisp_Object, char **, Lisp_Object);
|
||||
#ifdef USABLE_SIGIO
|
||||
#if defined (USABLE_SIGIO) || defined (USABLE_SIGPOLL)
|
||||
static bool keyboard_bit_set (fd_set *);
|
||||
#endif
|
||||
static void deactivate_process (Lisp_Object);
|
||||
|
@ -5730,7 +5730,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
|
|||
if (! NILP (wait_for_cell) && ! NILP (XCAR (wait_for_cell)))
|
||||
break;
|
||||
|
||||
#ifdef USABLE_SIGIO
|
||||
#if defined (USABLE_SIGIO) || defined (USABLE_SIGPOLL)
|
||||
/* If we think we have keyboard input waiting, but didn't get SIGIO,
|
||||
go read it. This can happen with X on BSD after logging out.
|
||||
In that case, there really is no input and no SIGIO,
|
||||
|
@ -5738,7 +5738,11 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
|
|||
|
||||
if (read_kbd && interrupt_input
|
||||
&& keyboard_bit_set (&Available) && ! noninteractive)
|
||||
#ifdef USABLE_SIGIO
|
||||
handle_input_available_signal (SIGIO);
|
||||
#else
|
||||
handle_input_available_signal (SIGPOLL);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* If checking input just got us a size-change event from X,
|
||||
|
@ -7732,7 +7736,7 @@ delete_gpm_wait_descriptor (int desc)
|
|||
|
||||
# endif
|
||||
|
||||
# ifdef USABLE_SIGIO
|
||||
#if defined (USABLE_SIGIO) || defined (USABLE_SIGPOLL)
|
||||
|
||||
/* Return true if *MASK has a bit set
|
||||
that corresponds to one of the keyboard input descriptors. */
|
||||
|
|
24
src/sound.c
24
src/sound.c
|
@ -299,11 +299,15 @@ sound_perror (const char *msg)
|
|||
int saved_errno = errno;
|
||||
|
||||
turn_on_atimers (1);
|
||||
#ifdef USABLE_SIGIO
|
||||
#if defined (USABLE_SIGIO) || defined (USABLE_SIGPOLL)
|
||||
{
|
||||
sigset_t unblocked;
|
||||
sigemptyset (&unblocked);
|
||||
#ifdef USABLE_SIGIO
|
||||
sigaddset (&unblocked, SIGIO);
|
||||
#else
|
||||
sigaddset (&unblocked, SIGPOLL);
|
||||
#endif
|
||||
pthread_sigmask (SIG_UNBLOCK, &unblocked, 0);
|
||||
}
|
||||
#endif
|
||||
|
@ -698,7 +702,7 @@ static void
|
|||
vox_configure (struct sound_device *sd)
|
||||
{
|
||||
int val;
|
||||
#ifdef USABLE_SIGIO
|
||||
#if defined (USABLE_SIGIO) || defined (USABLE_SIGPOLL)
|
||||
sigset_t oldset, blocked;
|
||||
#endif
|
||||
|
||||
|
@ -708,9 +712,13 @@ vox_configure (struct sound_device *sd)
|
|||
interrupted by a signal. Block the ones we know to cause
|
||||
troubles. */
|
||||
turn_on_atimers (0);
|
||||
#ifdef USABLE_SIGIO
|
||||
#if defined (USABLE_SIGIO) || defined (USABLE_SIGPOLL)
|
||||
sigemptyset (&blocked);
|
||||
#ifdef USABLE_SIGIO
|
||||
sigaddset (&blocked, SIGIO);
|
||||
#else
|
||||
sigaddset (&blocked, SIGPOLL);
|
||||
#endif
|
||||
pthread_sigmask (SIG_BLOCK, &blocked, &oldset);
|
||||
#endif
|
||||
|
||||
|
@ -744,7 +752,7 @@ vox_configure (struct sound_device *sd)
|
|||
}
|
||||
|
||||
turn_on_atimers (1);
|
||||
#ifdef USABLE_SIGIO
|
||||
#if defined (USABLE_SIGIO) || defined (USABLE_SIGPOLL)
|
||||
pthread_sigmask (SIG_SETMASK, &oldset, 0);
|
||||
#endif
|
||||
}
|
||||
|
@ -760,10 +768,14 @@ vox_close (struct sound_device *sd)
|
|||
/* On GNU/Linux, it seems that the device driver doesn't like to
|
||||
be interrupted by a signal. Block the ones we know to cause
|
||||
troubles. */
|
||||
#ifdef USABLE_SIGIO
|
||||
#if defined (USABLE_SIGIO) || defined (USABLE_SIGPOLL)
|
||||
sigset_t blocked, oldset;
|
||||
sigemptyset (&blocked);
|
||||
#ifdef USABLE_SIGIO
|
||||
sigaddset (&blocked, SIGIO);
|
||||
#else
|
||||
sigaddset (&blocked, SIGPOLL);
|
||||
#endif
|
||||
pthread_sigmask (SIG_BLOCK, &blocked, &oldset);
|
||||
#endif
|
||||
turn_on_atimers (0);
|
||||
|
@ -772,7 +784,7 @@ vox_close (struct sound_device *sd)
|
|||
ioctl (sd->fd, SNDCTL_DSP_SYNC, NULL);
|
||||
|
||||
turn_on_atimers (1);
|
||||
#ifdef USABLE_SIGIO
|
||||
#if defined (USABLE_SIGIO) || defined (USABLE_SIGPOLL)
|
||||
pthread_sigmask (SIG_SETMASK, &oldset, 0);
|
||||
#endif
|
||||
|
||||
|
|
34
src/sysdep.c
34
src/sysdep.c
|
@ -678,6 +678,9 @@ sys_subshell (void)
|
|||
#ifdef USABLE_SIGIO
|
||||
saved_handlers[3].code = SIGIO;
|
||||
saved_handlers[4].code = 0;
|
||||
#elif defined (USABLE_SIGPOLL)
|
||||
saved_handlers[3].code = SIGPOLL;
|
||||
saved_handlers[4].code = 0;
|
||||
#else
|
||||
saved_handlers[3].code = 0;
|
||||
#endif
|
||||
|
@ -788,6 +791,7 @@ init_sigio (int fd)
|
|||
}
|
||||
|
||||
#ifndef DOS_NT
|
||||
#ifdef F_SETOWN
|
||||
static void
|
||||
reset_sigio (int fd)
|
||||
{
|
||||
|
@ -795,12 +799,13 @@ reset_sigio (int fd)
|
|||
fcntl (fd, F_SETFL, old_fcntl_flags[fd]);
|
||||
#endif
|
||||
}
|
||||
#endif /* F_SETOWN */
|
||||
#endif
|
||||
|
||||
void
|
||||
request_sigio (void)
|
||||
{
|
||||
#ifdef USABLE_SIGIO
|
||||
#if defined (USABLE_SIGIO) || defined (USABLE_SIGPOLL)
|
||||
sigset_t unblocked;
|
||||
|
||||
if (noninteractive)
|
||||
|
@ -810,7 +815,11 @@ request_sigio (void)
|
|||
# ifdef SIGWINCH
|
||||
sigaddset (&unblocked, SIGWINCH);
|
||||
# endif
|
||||
# ifdef USABLE_SIGIO
|
||||
sigaddset (&unblocked, SIGIO);
|
||||
# else
|
||||
sigaddset (&unblocked, SIGPOLL);
|
||||
# endif
|
||||
pthread_sigmask (SIG_UNBLOCK, &unblocked, 0);
|
||||
|
||||
interrupts_deferred = 0;
|
||||
|
@ -820,7 +829,7 @@ request_sigio (void)
|
|||
void
|
||||
unrequest_sigio (void)
|
||||
{
|
||||
#ifdef USABLE_SIGIO
|
||||
#if defined (USABLE_SIGIO) || defined (USABLE_SIGPOLL)
|
||||
sigset_t blocked;
|
||||
|
||||
if (noninteractive)
|
||||
|
@ -830,7 +839,11 @@ unrequest_sigio (void)
|
|||
# ifdef SIGWINCH
|
||||
sigaddset (&blocked, SIGWINCH);
|
||||
# endif
|
||||
# ifdef USABLE_SIGIO
|
||||
sigaddset (&blocked, SIGIO);
|
||||
# else
|
||||
sigaddset (&blocked, SIGPOLL);
|
||||
# endif
|
||||
pthread_sigmask (SIG_BLOCK, &blocked, 0);
|
||||
interrupts_deferred = 1;
|
||||
#endif
|
||||
|
@ -1256,9 +1269,12 @@ init_sys_modes (struct tty_display_info *tty_out)
|
|||
/* This code added to insure that, if flow-control is not to be used,
|
||||
we have an unlocked terminal at the start. */
|
||||
|
||||
#ifndef HAIKU /* On Haiku, TCXONC is a no-op and causes spurious
|
||||
compiler warnings. */
|
||||
#ifdef TCXONC
|
||||
if (!tty_out->flow_control) ioctl (fileno (tty_out->input), TCXONC, 1);
|
||||
#endif
|
||||
#endif /* HAIKU */
|
||||
#ifdef TIOCSTART
|
||||
if (!tty_out->flow_control) ioctl (fileno (tty_out->input), TIOCSTART, 0);
|
||||
#endif
|
||||
|
@ -1674,6 +1690,8 @@ emacs_sigaction_init (struct sigaction *action, signal_handler_t handler)
|
|||
sigaddset (&action->sa_mask, SIGQUIT);
|
||||
#ifdef USABLE_SIGIO
|
||||
sigaddset (&action->sa_mask, SIGIO);
|
||||
#elif defined (USABLE_SIGPOLL)
|
||||
sigaddset (&action->sa_mask, SIGPOLL);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -2772,6 +2790,7 @@ static const struct speed_struct speeds[] =
|
|||
#ifdef B150
|
||||
{ 150, B150 },
|
||||
#endif
|
||||
#ifndef HAVE_TINY_SPEED_T
|
||||
#ifdef B200
|
||||
{ 200, B200 },
|
||||
#endif
|
||||
|
@ -2859,6 +2878,7 @@ static const struct speed_struct speeds[] =
|
|||
#ifdef B4000000
|
||||
{ 4000000, B4000000 },
|
||||
#endif
|
||||
#endif /* HAVE_TINY_SPEED_T */
|
||||
};
|
||||
|
||||
/* Convert a numerical speed (e.g., 9600) to a Bnnn constant (e.g.,
|
||||
|
@ -3120,8 +3140,9 @@ list_system_processes (void)
|
|||
}
|
||||
|
||||
/* The WINDOWSNT implementation is in w32.c.
|
||||
The MSDOS implementation is in dosfns.c. */
|
||||
#elif !defined (WINDOWSNT) && !defined (MSDOS)
|
||||
The MSDOS implementation is in dosfns.c.
|
||||
The Haiku implementation is in haiku.c. */
|
||||
#elif !defined (WINDOWSNT) && !defined (MSDOS) && !defined (HAIKU)
|
||||
|
||||
Lisp_Object
|
||||
list_system_processes (void)
|
||||
|
@ -4200,8 +4221,9 @@ system_process_attributes (Lisp_Object pid)
|
|||
}
|
||||
|
||||
/* The WINDOWSNT implementation is in w32.c.
|
||||
The MSDOS implementation is in dosfns.c. */
|
||||
#elif !defined (WINDOWSNT) && !defined (MSDOS)
|
||||
The MSDOS implementation is in dosfns.c.
|
||||
The HAIKU implementation is in haiku.c. */
|
||||
#elif !defined (WINDOWSNT) && !defined (MSDOS) && !defined (HAIKU)
|
||||
|
||||
Lisp_Object
|
||||
system_process_attributes (Lisp_Object pid)
|
||||
|
|
|
@ -60,7 +60,8 @@ enum output_method
|
|||
output_x_window,
|
||||
output_msdos_raw,
|
||||
output_w32,
|
||||
output_ns
|
||||
output_ns,
|
||||
output_haiku
|
||||
};
|
||||
|
||||
/* Input queue declarations and hooks. */
|
||||
|
@ -266,7 +267,6 @@ enum event_kind
|
|||
/* File or directory was changed. */
|
||||
, FILE_NOTIFY_EVENT
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
/* Bit width of an enum event_kind tag at the start of structs and unions. */
|
||||
|
@ -447,6 +447,7 @@ struct terminal
|
|||
struct x_display_info *x; /* xterm.h */
|
||||
struct w32_display_info *w32; /* w32term.h */
|
||||
struct ns_display_info *ns; /* nsterm.h */
|
||||
struct haiku_display_info *haiku; /* haikuterm.h */
|
||||
} display_info;
|
||||
|
||||
|
||||
|
@ -835,6 +836,9 @@ extern struct terminal *terminal_list;
|
|||
#elif defined (HAVE_NS)
|
||||
#define TERMINAL_FONT_CACHE(t) \
|
||||
(t->type == output_ns ? t->display_info.ns->name_list_element : Qnil)
|
||||
#elif defined (HAVE_HAIKU)
|
||||
#define TERMINAL_FONT_CACHE(t) \
|
||||
(t->type == output_haiku ? t->display_info.haiku->name_list_element : Qnil)
|
||||
#endif
|
||||
|
||||
extern struct terminal *decode_live_terminal (Lisp_Object);
|
||||
|
|
|
@ -445,6 +445,8 @@ possible return values. */)
|
|||
return Qpc;
|
||||
case output_ns:
|
||||
return Qns;
|
||||
case output_haiku:
|
||||
return Qhaiku;
|
||||
default:
|
||||
emacs_abort ();
|
||||
}
|
||||
|
|
|
@ -23,7 +23,9 @@ ifeq (${V},1)
|
|||
AM_V_AR =
|
||||
AM_V_at =
|
||||
AM_V_CC =
|
||||
AM_V_CXX =
|
||||
AM_V_CCLD =
|
||||
AM_V_CXXLD =
|
||||
AM_V_ELC =
|
||||
AM_V_ELN =
|
||||
AM_V_GEN =
|
||||
|
@ -34,7 +36,9 @@ else
|
|||
AM_V_AR = @echo " AR " $@;
|
||||
AM_V_at = @
|
||||
AM_V_CC = @echo " CC " $@;
|
||||
AM_V_CXX = @echo " CXX " $@;
|
||||
AM_V_CCLD = @echo " CCLD " $@;
|
||||
AM_V_CXXLD = @echo " CXXLD " $@;
|
||||
ifeq ($(HAVE_NATIVE_COMP),yes)
|
||||
ifeq ($(NATIVE_DISABLED),1)
|
||||
AM_V_ELC = @echo " ELC " $@;
|
||||
|
|
15
src/xdisp.c
15
src/xdisp.c
|
@ -15657,6 +15657,11 @@ redisplay_internal (void)
|
|||
}
|
||||
#endif
|
||||
|
||||
#if defined (HAVE_HAIKU)
|
||||
if (popup_activated_p)
|
||||
return;
|
||||
#endif
|
||||
|
||||
/* I don't think this happens but let's be paranoid. */
|
||||
if (redisplaying_p)
|
||||
return;
|
||||
|
@ -25247,6 +25252,11 @@ display_menu_bar (struct window *w)
|
|||
return;
|
||||
#endif /* HAVE_NS */
|
||||
|
||||
#ifdef HAVE_HAIKU
|
||||
if (FRAME_HAIKU_P (f))
|
||||
return;
|
||||
#endif /* HAVE_HAIKU */
|
||||
|
||||
#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
|
||||
eassert (!FRAME_WINDOW_P (f));
|
||||
init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
|
||||
|
@ -33698,6 +33708,11 @@ note_mouse_highlight (struct frame *f, int x, int y)
|
|||
return;
|
||||
#endif
|
||||
|
||||
#if defined (HAVE_HAIKU)
|
||||
if (popup_activated_p)
|
||||
return;
|
||||
#endif
|
||||
|
||||
if (!f->glyphs_initialized_p
|
||||
|| f->pointer_invisible)
|
||||
return;
|
||||
|
|
|
@ -246,6 +246,10 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
|
|||
#ifdef HAVE_NS
|
||||
#define GCGraphicsExposures 0
|
||||
#endif /* HAVE_NS */
|
||||
|
||||
#ifdef HAVE_HAIKU
|
||||
#define GCGraphicsExposures 0
|
||||
#endif /* HAVE_HAIKU */
|
||||
#endif /* HAVE_WINDOW_SYSTEM */
|
||||
|
||||
#include "buffer.h"
|
||||
|
@ -555,8 +559,8 @@ x_free_gc (struct frame *f, Emacs_GC *gc)
|
|||
|
||||
#endif /* HAVE_NTGUI */
|
||||
|
||||
#ifdef HAVE_NS
|
||||
/* NS emulation of GCs */
|
||||
#if defined (HAVE_NS) || defined (HAVE_HAIKU)
|
||||
/* NS and Haiku emulation of GCs */
|
||||
|
||||
static Emacs_GC *
|
||||
x_create_gc (struct frame *f,
|
||||
|
|
|
@ -4461,7 +4461,8 @@ For GNU and Unix system, the first 2 numbers are the version of the X
|
|||
Protocol used on TERMINAL and the 3rd number is the distributor-specific
|
||||
release number. For MS Windows, the 3 numbers report the OS major and
|
||||
minor version and build number. For Nextstep, the first 2 numbers are
|
||||
hard-coded and the 3rd represents the OS version.
|
||||
hard-coded and the 3rd represents the OS version. For Haiku, all 3
|
||||
numbers are hard-coded.
|
||||
|
||||
See also the function `x-server-vendor'.
|
||||
|
||||
|
@ -7419,7 +7420,7 @@ Use a file selection dialog. Select DEFAULT-FILENAME in the dialog's file
|
|||
selection box, if specified. If MUSTMATCH is non-nil, the returned file
|
||||
or directory must exist.
|
||||
|
||||
This function is defined only on NS, MS Windows, and X Windows with the
|
||||
This function is defined only on NS, Haiku, MS Windows, and X Windows with the
|
||||
Motif or Gtk toolkits. With the Motif toolkit, ONLY-DIR-P is ignored.
|
||||
Otherwise, if ONLY-DIR-P is non-nil, the user can select only directories.
|
||||
On MS Windows 7 and later, the file selection dialog "remembers" the last
|
||||
|
|
|
@ -14959,7 +14959,7 @@ selected window or cursor position is preserved. */);
|
|||
A value of nil means Emacs doesn't use toolkit scroll bars.
|
||||
With the X Window system, the value is a symbol describing the
|
||||
X toolkit. Possible values are: gtk, motif, xaw, or xaw3d.
|
||||
With MS Windows or Nextstep, the value is t. */);
|
||||
With MS Windows, Haiku windowing or Nextstep, the value is t. */);
|
||||
#ifdef USE_TOOLKIT_SCROLL_BARS
|
||||
#ifdef USE_MOTIF
|
||||
Vx_toolkit_scroll_bars = intern_c_string ("motif");
|
||||
|
|
Loading…
Add table
Reference in a new issue