Compare commits

...

261 commits

Author SHA1 Message Date
rfm
e59d923e90 New release
Some checks failed
/ ci (push) Has been cancelled
2025-02-11 18:52:08 +00:00
Fred Kiefer
e63ad3c1d2 Update news.texi for upcoming release
Some checks are pending
/ ci (push) Waiting to run
2025-02-10 22:40:35 +01:00
rfm
b9038250e6 Fix use of deallocated memory 2024-12-31 08:42:22 +00:00
Frederik Carlier
03a2e7e152
Enable default interpolation due to pixelated screen drawing (#53)
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/back/branches/gnustep_testplant_branch@40163 72102866-910b-0410-8b05-ffd578937521

Co-authored-by: Marcian Lytwyn <gna@advcsi.com>
2024-11-05 18:30:47 +01:00
Riccardo
4e3ca27c0b
instead of just getting Latin1 we practically see getting 2 or 3 bytes (even for characters that representable in Latin1) so try our best to interpret them (#50) 2024-09-19 08:32:46 +02:00
Frederik Carlier
ba1c582024
Define WINBOOL on non-MinGW platforms (#52)
The Windows SDK declares BOOL as an int.  Objective C defines BOOl as a char.
Those two types clash.  MinGW's implementation of the Windows SDK uses the WINBOOL
type to avoid this clash.  When compiling natively on Windows, we need to manually
define WINBOOL.
MinGW will define _DEF_WINBOOL_ if it has defined WINBOOL so we can use the same trick
here.
See https://github.com/mingw-w64/mingw-w64/blob/master/mingw-w64-headers/include/ntdef.h#L355
2024-09-17 21:19:25 +02:00
Frederik Carlier
6e05e1e65e
Support building natively on Windows (#51)
When building for Windows using a native toolchain (i.e. not MinGW or MSYS), `<unistd.h>` is not available.  Include `<io.h>` instead and define `strcasecmp`.
2024-09-14 00:23:01 +02:00
Joe Maloney
d27af6af10
Fix build errors with Wayland on Debian 13 (trixie) using Clang 16 (#48)
* Solve an undelcared close function

* Fix xdgshell protocol handling and resolve compile errors

* Fixing build errors in WaylandServer+Cursor

* Revert changes except wl_cursor_destroy to fix build and avoid regressions

* Fix selector warnings and method call type issues

* Use window parameter directly

* Comments removed

* Include NSGraphics to eliminate redundant declaration.

* Remove NSWindow include that was replaced by NSGraphics
2024-08-28 23:03:03 +02:00
Fred Kiefer
e03ddf7b2b Update for new release 2024-05-26 22:14:27 +02:00
rfm
be85eb8ae6 add postscript pasteboard type 2024-03-07 09:50:42 +00:00
rfm
085082a6cc Add URL/URI-list support (without insisting on trailing cr-lf) 2024-03-06 20:47:04 +00:00
rfm
0d60ea2935 add html clipboard support 2024-03-06 20:39:29 +00:00
rfm
4fea5f4dae Add pdf support 2024-03-06 19:04:12 +00:00
Riccardo Mottola
c787d26af2 PNG support in copy and paste; NSPasteboardTypePNG XG_MIME_PNG 2024-03-05 18:00:30 +01:00
rfm
707c5239e3 Improve debug loging showing method entry/exit informmation 2024-03-05 12:48:21 +00:00
rfm
b8933e4610 Add support for text/plain;charset=utf8 and improve debug logging for available types 2024-03-05 11:36:45 +00:00
rfm
145ee71f5c iimprove formatting 2024-03-04 21:36:05 +00:00
rfm
6a221b4dc7 Report all available types in debug 2024-03-04 21:21:45 +00:00
rfm
e66906ef38 Optimisation for reading large properties: avoid memory reallocation and copying data. 2024-03-01 19:29:01 +00:00
rfm
f6707b897a Merge branch 'master' of ssh://github.com/gnustep/libs-back 2024-03-01 18:54:34 +00:00
Riccardo Mottola
9c31a7e016 debug which types are found available 2024-02-29 22:41:14 +01:00
rfm
ae6529e24f Add some debug for target types sent to X 2024-02-27 10:23:22 +00:00
rfm
bfbe4d8b57 Clean up new Incremental class and add mechanism to cancel old operations. 2024-02-27 05:36:10 +00:00
rfm
daf081b888 Rewrite code providing X selection property value using INCR. 2024-02-26 21:24:11 +00:00
rfm
a0a45faaea Add a lot of debug and rewrite to support sending using the INCR protocol 2024-02-26 17:07:39 +00:00
rfm
0a32e7284e fix minor leak and avoid inefficient memory reallocation with long properties. 2024-02-25 10:20:43 +00:00
rfm
d8c05939b4 fix leaks in last update 2024-02-20 08:19:01 +00:00
rfm
e781a3ae03 reduce x library traffic and memory footprint during large transfers 2024-02-19 22:06:55 +00:00
rfm
85bad5ded7 added more logging 2024-02-19 21:17:27 +00:00
Riccardo Mottola
d0a2376e92 try to make logging a bit more verbose 2024-02-19 22:12:26 +01:00
Riccardo Mottola
895fdbcf39 reshuffle code, compact name calculation and return NSString and not NSMutableString 2023-11-21 23:40:49 +01:00
Riccardo Mottola
4bb1370086 fix compiler warning with some code cleanup 2023-11-21 23:26:40 +01:00
Fred Kiefer
519f57d85a
Merge pull request #43 from qmfrederik/fixes/access-violation
Avoid AV in Win32FontInfo setupAttributes
2023-10-11 17:46:37 +02:00
Frederik Carlier
421c09dac2 Avoid AV in Win32FontInfo setupAttributes 2023-10-11 12:50:29 +02:00
Fred Kiefer
9ab65edd14
Merge pull request #42 from qmfrederik/features/headless-pr
Add headless backend
2023-10-01 23:30:01 +02:00
Frederik Carlier
8f0146f50d Update copyright headers
- Use GNU Lesser General Public License
- Streamline attributions in the form of "based on work by:"
- Streamline names of preprocessor variables
2023-10-01 23:01:55 +02:00
Frederik Carlier
feb28c4d84 Avoid instance variables on msvc 2023-09-30 22:00:00 +02:00
Frederik Carlier
3c1b5e1397 Build multiple configurations 2023-09-30 00:23:02 +02:00
Frederik Carlier
e9c633abf7 Add font enumerator, font info, and other classes 2023-09-30 00:23:02 +02:00
Frederik Carlier
bc1d726f41 Run autoreconf -i 2023-09-30 00:21:14 +02:00
Frederik Carlier
64f685db1c Filter out duplicates from subprojects 2023-09-30 00:21:14 +02:00
Frederik Carlier
f56d4cfce2 Skaffold headless backend 2023-09-30 00:21:14 +02:00
Frederik Carlier
1ec7eb6ecb Run autoreconf -i 2023-09-29 08:16:28 +00:00
Fred Kiefer
7c0c511674
Merge pull request #41 from qmfrederik/features/ci
Add GitHub Actions
2023-09-28 23:54:43 +02:00
Frederik Carlier
af84372398 Add GitHub Actions 2023-09-28 08:13:45 +00:00
Richard Frith-Macdonald
909bd06688 Update for new release 2022-12-29 16:50:36 +00:00
Riccardo Mottola
ecfb42a893 Delete property on begin and at every Notify to start and continue transfer of INCR. 2022-02-22 00:09:00 +01:00
Fred Kiefer
db40d23ed6
Merge pull request #38 from anthonyc-r/scale_factor_font_advancement
Cairo: Disable font hinting when GSScaleFactor is not 1 to fix text d…
2022-01-24 20:03:00 +01:00
anthony
20182c8ec8 Cairo: Default font hinting to off when GSScaleFactor is set to values other than 1.0 2022-01-24 09:56:03 +00:00
Fred Kiefer
d7cfebe169
Merge pull request #37 from nongio/wayland-cursor-fix
wayland: use GSStandardWindowDecorationView to hit-test cursor clicks
2021-12-29 14:44:03 +01:00
Riccardo Canalicchio
977b375feb wayland: use GSStandardWindowDecorationView to hit-test cursor clicks 2021-12-29 14:29:44 +01:00
Fred Kiefer
9c7c878717
Merge pull request #35 from nongio/wayland-pointer
Wayland backend pointer events and cursor images
2021-12-27 17:52:47 +01:00
Riccardo Canalicchio
89280c0e3e code formatting 2021-12-27 15:21:03 +01:00
Fred Kiefer
06be91b267
Merge pull request #34 from nongio/wayland-shm-surface
Wayland shm surface
2021-12-27 13:29:36 +01:00
Fred Kiefer
cb3a8d1501
Merge pull request #36 from nongio/wayland-menu-api-change
wayland backend: libs-gui api change _menu
2021-12-27 13:18:48 +01:00
Riccardo Canalicchio
ec500d2bfb wayland backend: libs-gui api change _menu 2021-12-27 10:00:02 +01:00
Riccardo Canalicchio
cc7af18075 wayland backendL capture mouse bugfix 2021-12-27 09:53:15 +01:00
Riccardo Canalicchio
a240d1b4d8 wayland cursor: capture and release methods 2021-12-22 07:50:34 +01:00
Riccardo Canalicchio
2683cdd8ab Wayland backend: cursor event serial 2021-12-20 00:12:13 +01:00
Riccardo Canalicchio
54b2b172d8 Wayland backend: cursor icon functions 2021-12-20 00:11:48 +01:00
Riccardo Canalicchio
5db58c071d Wayland backend: window ignoreMouse 2021-12-20 00:11:41 +01:00
Riccardo Canalicchio
00b7183f84 Wayland backend: cursor handlers 2021-12-20 00:11:32 +01:00
Gregory Casamento
e106932ae0
Merge pull request #33 from nongio/wayland 2021-12-14 12:47:06 -05:00
Riccardo Canalicchio
79be4acfba WaylandCairoShmSurface: fix memory leak, handling buffer release 2021-12-13 22:27:31 +01:00
Riccardo Canalicchio
317ca762a3 rename WaylandCairoShmSurface 2021-12-13 22:27:22 +01:00
Riccardo Canalicchio
96f07c13f7 Wayland server: remove attach calls from server, surface attach is delegated to cairo surface 2021-12-13 22:23:59 +01:00
Riccardo Mottola
637baa2d91 make cast to float explicit 2021-12-03 02:04:47 +01:00
Riccardo Canalicchio
91a1479193 Wayland server: code formatting
using clang-format from:
https://github.com/gnustep/libs-base/blob/master/.clang-format
2021-11-23 14:00:01 -05:00
Riccardo Canalicchio
114743a5d0 wayland backend: refactor logs 2021-11-09 03:23:08 -05:00
Riccardo Canalicchio
5967015078 wayland backend: window move/resize 2021-11-06 08:09:26 -04:00
Riccardo Canalicchio
502dde25f5 wayland backend: surface roles based on window level 2021-11-06 08:07:44 -04:00
Riccardo Canalicchio
6a9e97660d wayland backend: change logs to debuglog 2021-10-28 02:35:31 -04:00
Riccardo Canalicchio
30ceacc90d wayland backend: refactor code, split into categories 2021-10-25 07:38:15 -04:00
Riccardo Canalicchio
7b87b268e3 wayland backend: layer shell 2021-10-25 03:13:35 -04:00
Riccardo Canalicchio
1d74e36258 wayland backend:re-attach surface on ExposeRect 2021-10-19 02:10:45 -04:00
Riccardo Canalicchio
e7ab056264 wayland backend:implement xdg ping/pong handler
this prevents the client from being considered unresponsive
2021-10-18 13:39:58 -04:00
Riccardo Canalicchio
c6ce795898 wayland backend: delayed toplevel creation 2021-10-18 03:37:02 -04:00
Ivan Vučica
3227b39c58 release-chore: Release 0.29.0. 2021-04-26 23:28:18 +01:00
Fred Kiefer
6556ff6dd8 Correct date of last ChangeLog entry 2021-03-12 18:22:58 +01:00
Fred Kiefer
9299fa1f93 * Source/x11/XGServerWindow.m (-styleoffsets:...:): Change NSLog
statement on guessing the offset into a NSDebugLLog statement.
2021-03-12 17:40:08 +01:00
Fred Kiefer
3b90116f44
Merge pull request #31 from gnustep/win64-fixes
Win64 fixes
2021-03-05 11:14:15 +01:00
rmottola
c40aa45ea6 Merge branch 'win64-fixes' of https://github.com/gnustep/libs-back into win64-fixes 2021-03-04 15:13:01 +01:00
rmottola
8640bfafe3 use consistently GetWindowLongPtr also for Cairo on Windows 2021-03-04 15:12:34 +01:00
Riccardo Mottola
60f2cb4235 update changelog 2021-03-04 00:04:09 +01:00
rmottola
d5abf2ff1c actually store in a LONG_PTR the result of GetWindowLongPtr 2021-03-03 20:58:05 +01:00
rmottola
aad896a260 use consistently GetWindowLongPtr also for Cairo on Windows 2021-03-03 20:53:01 +01:00
rmottola
da9e53c608 upgrade consistently [Set,Get]WindowLong to [Set,Get]WindowLongPtr 2021-03-02 22:13:22 +01:00
Sergii Stoian
e5cdc1747b * Source/x11/XGServerWindow.m (_checkStyle:): do not set application
name and WindowGroupHint to temporary window. Created window designed
to help get window frame offsets only - appicon window will be created
later. This change prevents appicon flickering on WindowMaker at
application start.
(_createWMAppiconHack, _setupRootWindow): WindowMaker hack removed in
favour of solution introduced in _checkStyle:.
2021-01-27 15:37:27 +02:00
Sergii Stoian
3f3c1305a9 2021-01-24 Sergii Stoian <stoyan255@gmail.com>
* Source/x11/XGServerWindow.m: WindowMaker doesn't support
  _NET_REQUEST_FRAME_EXTENTS message andthe only way to determine offsets
  is creating and mapping window. In this case first mapped window of
  application is not appicon window.
  Early appicon creating inserted back as _createWMAppiconHack method and
  called only if no other way to determine window's offsets (before call to
  _checkStyle);appicon window size is set to size icon;
2021-01-24 02:45:29 +02:00
fredkiefer
aa9ae34916 Fill in some details for pending release. 2021-01-16 20:47:10 +01:00
Sergii Stoian
6c53486617
Merge pull request #29 from trunkmaster/master
x11/XGServerWindow.m: removed WindowMaker appicon hack
2020-09-19 01:51:00 +03:00
Sergii Stoian
0bbb7a0915 Author: Sergii Stoian <stoyan255@gmail.com>
--- log message follows this line --
* Source/x11/XGServerWindow.m: removed code commented out in
  previous commit.
2020-09-19 01:48:00 +03:00
Sergii Stoian
31b7c4ed2f * Source/x11/XGServerWindow.m
(_setupRootWindow, window::::): removed WindowMaker appicon hack and
  - now unused - _wmAppIcon variable.

  Description: The removed code removed creates and maps zero-sized
  window in hope that WindowMaker will recognize app by this event and
  create app icon window. Although when application requests window
  for appicon through the `-window::::` method call, it returns newly
  created and mapped window. This actually happens but application icon
  flickers between WM icon creation and application icon window appearance.

  This fix based on the fact that root application window (ROOT) is mapped
  in `-orderwindow:::` and this is the event of application recognition
  by WindowMaker because it is a first application window that is
  mapped.
2020-09-18 16:15:14 +03:00
Sergii Stoian
d221c98e95
Merge pull request #28 from trunkmaster/master
XGServerEvent.m: unhide app if WindowMaker sends WM_TAKE_FOCUS to window
2020-09-17 18:12:55 +03:00
Sergii Stoian
fa4549e522 * Source/x11/XGServerEvent.m (_handleTakeFocusAtom:forContext:):
space before argument was added.
2020-09-17 12:00:38 +03:00
Sergii Stoian
df32af71fc * Source/x11/XGServerEvent.m
(_handleTakeFocusAtom:forContext:): if application (window) receives
  WM_TAKE_FOCUS in hidden state it means WindowMaker wants us to be
  unhidden.

  Description: There are 2 protocols defined in XGServerWindow.h:
  WMFHideApplication and WMFHideOtherApplications. These protocols exist
  to help GNUstep application and WindowMaker notify each other
  about "Hide" and "Hide Others" actions. There are no protocols for
  "unhide" action.

  Test case steps:
  1. Open application with window opened.
  2. Hide application with "Hide" menu item.
  3. Open WindowMaker's "Windows" menu (middle-click on desktop).
  4. Select hidden application window.
  Application unhides, activates, restored window is focused (receives) input
  and "Hide" menu item unselected.
2020-09-17 01:42:32 +03:00
Sergii Stoian
d970554391 * Source/x11/XGServerWindow.m
(hideApplication:): send application's root window to WindowMaker (WM)
  because it's a "group leader" that clearly identifies application
  inside WM. WM uses XFindContext to get WApplication structure and
  "group leader" window ID is a key to find it.
2020-09-16 09:24:48 +00:00
Riccardo Mottola
9a46ea9160 If the Library directory is not found, create one for the user. 2020-06-18 07:58:01 +00:00
Riccardo Mottola
c5990ed022 Fix return value of width to CGFloat 2020-06-18 00:55:50 +02:00
Riccardo Mottola
95f8546eec Match return value in case of error (nil instead of NO) 2020-06-18 00:54:32 +02:00
fredkiefer
e929b48e0b * Headers/fontconfig/FCFaceInfo.h: Add instancevariable _patternIsResolved.
* Source/fontconfig/FCFaceInfo.m (-matchedPattern): Cache the
resolved pattern and return this. The method characterSet now uses
this cached pattern.
Patch by Josh Freeman <gnustep_lists@twilightedge.com>
2020-06-10 18:24:51 +02:00
Fred Kiefer
efe22e8557
Merge pull request #27 from pgeorgi/typo-fixes
Fix a bunch of typos
2020-05-29 18:11:47 +02:00
Patrick Georgi
aebcc4b7fe Fix a bunch of typos
Taken from the Debian "gnustep-back" package sources, which attribute
these changes to:

Author: Eric Heintzmann <heintzmann.eric@free.fr>
Author: Yavor Doganov <yavor@gnu.org>
2020-05-29 08:21:55 +02:00
Ivan Vučica
4ab5a69383
wayland: Mention the new README in the changelog. 2020-04-25 18:25:08 +01:00
Ivan Vučica
bf4efe9d36
wayland: Added a small readme noting some backend-specific information. 2020-04-25 18:23:49 +01:00
Ivan Vučica
2bbcb043ef
wayland: Update the changelog for the merge. 2020-04-25 18:12:43 +01:00
Ivan Vučica
8f0cc1b0ca
wayland: Write down TODOs for cairo_surface doublebuffering to itself and for mouse wheel axis_source. 2020-04-25 18:12:43 +01:00
Ivan Vučica
f8b8609e70
wayland: Implement -[WaylandServer mouselocation]. 2020-04-25 18:12:42 +01:00
Ivan Vučica
67e352b83e
wayland: Deleted the useless override of -[GSDisplayServer windowlist]. 2020-04-25 18:12:42 +01:00
Ivan Vučica
c6e9ee857f
wayland: Support mouse middle click and smooth scroll wheel events. 2020-04-25 18:12:41 +01:00
Ivan Vučica
12f1d48772
wayland: Remove the 'fake drawing' branch. 2020-04-25 18:12:41 +01:00
Ivan Vučica
de9a8b36c3
wayland: Performed some investigation into freeing WaylandCairoSurface memory. 2020-04-25 18:12:40 +01:00
Ivan Vučica
b294b7f1b9
wayland: In case *stable* XDG Shell protocol isn't supported, be more informative.
The exception was not very informative about why exactly the
error message may occur. Weston in Debian buster doesn't
support the stable XDG Shell protocol, for instance, and
triaging this took some effort.
2020-04-25 18:12:40 +01:00
Ivan Vučica
84f71f5c3e
wayland: Additional interface registration NSDebugLog() output. 2020-04-25 18:12:39 +01:00
Ivan Vučica
359aa9e639
wayland: Additional clean up for license headers. 2020-04-25 16:14:07 +01:00
Ivan Vučica
41b2d294ed
wayland: Checking whether the surface is configured before committing.
This now results in windows being painted on the screen. However, input is
still ending up in all the wrong places, and there is a lot of garbage content
being painted outside the actual windows.

Right clicking on a window seems to trigger rotate behavior, which needs to
be evaluated and likely removed (or prevented, if this is done by Weston).

Interestingly, checking for ->configured on first surface commit also seems to
break the backend.
2020-04-17 01:19:26 +01:00
Ivan Vučica
36eefc981e
wayland: Assortment of fixes noticed during code review.
Rearranging order of the code, freeing some memory, writing a note
that additional work is required, returning a value through pointer
passed as argument, etc.
2020-04-15 00:36:37 +01:00
Ivan Vučica
80cc4121ae
wayland: Additional license header fixes noticed during PR. 2020-04-15 00:35:47 +01:00
Ivan Vučica
e8e615548a
wayland: Update license headers and copyright statement.
For contributions, we generally ask that copyright is assigned
to FSF. I believe this has been done by Sergio.
2020-04-15 00:19:53 +01:00
Ivan Vučica
24cbc5a198 wayland: Include a script for regenerating protocol headers/source. 2020-04-15 00:00:40 +01:00
Ivan Vučica
3db7a6fbd4 wayland: Split the check for compositor and wm_base into two checks. 2020-04-15 00:00:40 +01:00
Ladislav Michl
c1cce2ad67 wayland: WIP 2020-04-15 00:00:40 +01:00
Ladislav Michl
4311a8191b wayland: Use memfd_create 2020-04-15 00:00:40 +01:00
Ladislav Michl
e805a4a6c0 wayland: Whitespace fixes 2020-04-15 00:00:40 +01:00
Ladislav Michl
05f362d528 wayland: Add wayland integration and use stable protocol.
non functional, all changes just make it compile again. Configure changes
by Ivan Vučica.
2020-04-15 00:00:40 +01:00
Sergio L. Pascual
81456203b2 Dirty Wayland backend implementation. 2020-04-15 00:00:40 +01:00
Fred Kiefer
ecfa661d7a
Merge pull request #26 from ivucica/ivucica-normalize-announce
Normalize annoucement file between core libraries
2020-04-14 08:37:46 +02:00
Ivan Vučica
427e50df1e
documentation: Regenerate the announcement file. 2020-04-13 23:26:00 +01:00
Ivan Vučica
67b7f637e5
documentation: Standardize announcement file text.
Normalize the accompanying text for the release announcement across
core packages: standardize chapter name and GPG information.
2020-04-13 23:25:48 +01:00
Ivan Vučica
de2a207cf5
release-chore: Update documentation for the 0.28.0 release. 2020-04-05 21:21:59 +01:00
fredkiefer
6f8887cf58 * Documentation/news.texi: Fill in some details for pending release. 2020-03-27 20:20:15 +01:00
Sergii Stoian
05986c15da * Source/art/GNUmakefile.preamble,
* Source/gsc/GNUmakefile.preamble: do not overwrite ADDITIONAL_INCLUDE_DIRS
  value to help RPM build. In spec file ADDITIONAL_INCLUDE_DIRS can be sat
  to subdirectories which are create by RPM build tool.
2020-03-12 11:43:39 +02:00
Sergii Stoian
83f1caccc9
Merge pull request #24 from gnustep/randr
placewindow:: fix frame check for multi-monitor layout
2020-03-05 22:51:33 +02:00
Sergii Stoian
fc68da6be2 * Source/x11/XGServerWindow.m (placewindow::): check window frame
in OpenStep and Xlib coordinate systems to decide if it was changed.
  Rename `xVal` into more meaninful `xFrame` (holds temporary value of
  window frame in Xlib coordiante system).
2020-03-05 02:10:23 +02:00
Sergii Stoian
8f580a86f7
Merge pull request #23 from gnustep/randr
Fix for broken DnD on vertically aligned monitors
2020-03-03 12:08:54 +02:00
Sergii Stoian
db1079b5e3 * Headers/x11/XGServer.h,
* Source/x11/XGServer.m (xScreenSize): new primitive method.

* Source/x11/XGDragView.m (XY): use new primitive method to get Xlib
  screen height. Fixes broken DnD on vertically aligned monitors.
2020-03-03 01:59:04 +02:00
Sergii Stoian
da144f3bdc * Source/x11/XGServerWindow.m (placewindow::): call XMoveResizeWindow
even if specified frame is equal current. No events will be send to
  -gui for this case but X11 window position will be refreshed. It fixes
  misplacement of image in slideImage:from:to: (second and all subsequent
  calls).
2020-03-01 02:17:32 +02:00
Sergii Stoian
2a0e305a4f * Headers/x11/XGServerWindow.h (_gswindow_device_t): new structure
memeber was added - `osframe`. This member intended to hold cached frame
  of windows in OpenStep coordinate system. This makes backend more
  reliable to the cases when gui changes NSWindow's _frame ivar before
  call to backend methods which make windows placement.

* Source/x11/XGServerWindow.m (placewindow::): use `osframe` structure
  member to decide if window change position or size. Removed usage of
  temporary `frame` (used only for making desicion).
2020-02-26 01:53:01 +02:00
Sergii Stoian
0e811399dc * Source/x11/XGServerEvent.m (mouseLocationOnScreen🪟): use xScreenSize
instead of DisplayHeight. Fixes mouse events handling on multi-monitor
  configuration with vertical layout.
2020-02-26 01:45:47 +02:00
Sergii Stoian
983035a7a6
Merge pull request #22 from gnustep/randr
Window positionning: rely on internal variable not the GUI's one
2020-02-24 23:56:44 +02:00
Sergii Stoian
70e4222ece * Source/x11/XGServerWindow.m (placewindow::): move NSWindow fetching
code closer to its usage.
2020-02-24 23:53:57 +02:00
Sergii Stoian
f080ecdf78 Merge branch 'master' into randr
Conflicts:
	ChangeLog
2020-02-24 01:35:28 +02:00
Sergii Stoian
4c9ca90eac * Source/x11/XGServerWindow.m (placewindow::): use window->xframe
as current window frame instead of NSWindow's frame because
  `_frame` ivar may be already changed to target value.
2020-02-24 01:20:54 +02:00
fredkiefer
4924e11a0b * Source/x11/XGServerWindow.m (-_createAppIconPixmaps): Made
preconditions of new code explicit.
* Source/x11/XGServerWindow.m (-orderwindow:::): Set icon pixmap
only for WindowMaker.
2020-02-21 16:35:04 +01:00
Sergii Stoian
638940fb28 * Headers/x11/XGServer.h (GSDisplayServer): added new ivar xScreenSize
to hold Xlib screen size dimensions.

* Source/x11/XGServerWindow.m: 
  (_OSFrameToXFrame:for:): use xScreenSize instead of DisplayHeight.
  (_OSFrameToXHints:for:): ditto.
  (_XFrameToOSFrame:for:): ditto.
  (movewindow::): ditto.
  (_screenSize): new static function to get dimensions of Xlib screen from
  root window.
  (screenList): use xScreenSize instead of DisplayHeight/DisplayWidth.
2020-02-20 19:13:06 +02:00
fredkiefer
bf2b88f16e * Source/x11/XGServerWindow.m (screenList): Clean up implementation again. 2020-02-14 17:05:36 +01:00
Sergii Stoian
c3e7b37ac0 ChangeLog: update. 2020-02-12 00:36:18 +02:00
Sergii Stoian
00a79638cf * Source/x11/XGServerWindow.m (screenList): revert back to old code
logic: if XRandR available but can't get screens info for some reasons,
  return array with one element (Xlib screen info).
2020-02-12 00:35:45 +02:00
Fred Kiefer
6923a62820
Merge pull request #21 from gnustep/randr
Align screens origin to OpenStep coordinate system.
2020-02-11 23:19:17 +01:00
Sergii Stoian
230006323d * Source/x11/XGServerWindow.m (screeList): remove usage of intermediate frame variable. 2020-02-11 23:56:39 +02:00
Sergii Stoian
2fdced823c Merge branch 'master' into randr
Conflicts:
	ChangeLog
	Source/x11/XGServerWindow.m
2020-02-11 23:38:52 +02:00
Sergii Stoian
9c4f9ce7fc * Source/x11/XGServerWindow.m (screenList): Transform screen
origin into unflipped (OpenStep) coordinate system for XRandR capable
  systems. After this change windows and screen will use the same start
  of coordinate system for their origins.
2020-02-11 18:21:34 +02:00
fredkiefer
2c99cfc730 Fixes after Xrandr change to get xlib backend to compile again. 2020-02-08 21:30:54 +01:00
fredkiefer
f9d3dd7f96 * Source/x11/XGServerWindow.m (screenList): Clean up implementation. 2020-02-08 13:35:43 +01:00
Sergii Stoian
74bab329ba
Merge pull request #19 from gnustep/randr
Screens handling with RandR fixes
2020-02-08 02:51:58 +02:00
Sergii Stoian
519d267d60 * Source/x11/XGServerWindow.m (resolutionForScreen:): fixed parameter
name in comment.
2020-02-08 01:54:18 +02:00
Sergii Stoian
e6108e05f7 * Source/x11/XGServerWindow.m (_XFrameToOSFrame:for:): use Xlib
screen height instead of monitor's because we convert coordinates
  from Xlib area.
  (movewindow::): use Xlib screen height because we're operating in
  Xlib coordinate system.
  (screenList): fill monitor depth with value returned by
  windowPathForScreen with monitor at index 0 (screen_id already set so
  method will get correct screen_id).

* Source/x11/XGServerEvent.m (processEvent:): fixed indentaion.
2020-02-07 19:00:27 +02:00
Sergii Stoian
bcf71f2302 Merge remote-tracking branch 'origin/master' into randr
Conflicts:
	ChangeLog
	Source/x11/XGServerWindow.m
2020-02-07 16:30:52 +02:00
Sergii Stoian
82931a4a61 * Source/x11/XGServerWindow.m (_OSFrameToXFrame:for:):,
(_OSFrameToXHints:for:): use Xlib screen height instead of monitor's
  because we convert coordinates to Xlib area.

* Source/x11/XGServerEvent.m (processEvent:): update monitor_id from
  NSWindow's screen number (it could change after event processing).
  (mouseLocationOnScreen🪟): use Xlib screen height instead of
  monitor's. Added comment to code that should be probably removed
  later.
2020-02-07 16:01:03 +02:00
fredkiefer
c79b2a7b09 * Source/x11/XGServerWindow.m (swapColors): Made code more
explicit and removed additional copy before calling this function.
This function should now do what the comment above it says.
(alphaMaskForImage): Slightly cleaner code.
2020-02-07 10:13:48 +01:00
Sergii Stoian
84ec2f0110 * Source/x11/XGServerWindow.m (screenList): do not create monitors as
sparse array. This is usefull when -boundsToScreen: called with paramter
  value `0` and there is no monitor connected to first RandR ouput.
2020-02-04 02:45:14 +02:00
Sergii Stoian
1065e45869 * Source/x11/XGServerWindow.m (screenList): fixed comment.
(resolutionForScreen:): parameter renamed.
2020-02-03 23:25:03 +02:00
Sergii Stoian
6a1c1600a2 * Source/x11/XGServerWindow.m (screenList): insert primary (main)
monitor index into index 0 of returned array.
2020-02-03 18:24:54 +02:00
Sergii Stoian
e3da99fb5e * Source/x11/XGServerWindow.m (screenList): call windowDepthForScreen:
with monitor index, not screen ID (screen_id field has already set
  to defScreen above).
  (windowDepthForScreen:): get Xlib screen with screen_id from monitor
  lit.
2020-02-03 15:27:40 +02:00
Sergii Stoian
904739eb0c * Source/x11/XGServerWindow.m (screenList): update comment.
(nativeWindow:::::): assign `*screen` to `screen_id`, `monitor_id` is
set to `0`.
2020-02-03 14:29:25 +02:00
Sergii Stoian
87da2f0a28 * Source/x11/XGServer.m: use #pragma clang only if clang
compiler is used.
2020-02-03 13:56:18 +02:00
Sergii Stoian
8b66164d88 * Source/x11/XGServer.m (getForScreen:pixelFormat:masks:::):
removed unused code.
2020-02-03 13:31:27 +02:00
Sergii Stoian
c1ab242c9e * gswindow_device_t structure element screen was renamed to
`screen_id`; `monitor_id` element was added. Made use of
  `screen_id` and `monitor_id` where it's appropriate.

* Removed `screen` parameter from methods which contains it in name.
  Methods were renamed to remove `Screen` and `FromScreen`.

* Source/x11/XGServerWindow.m (screenList): change with assumption
  that Xlib screen is one per application.
  Failback code to RandR-related always creates arrays with one element
  (no enumeration needed). Create `monitor` structure in failback (non-RandR)
  code. Use `screen_id` MonitorDevice structure element to hold	Xlib screen
  ID.
  (windowDepthForScreen:): assume that `screen` parameter is a Xlib screen ID,
  simplify code - `screen` will be used with RandR or not.
  (availableDepthsForScreen:): changed with assumption that `screen` is a index
  of element in `monitors` structure.

* Source/x11/XGServer.m (_initXContext): initialize `monitors` array
  early here before first use (calls to XGServerWindow methods).
2020-02-03 01:21:52 +02:00
Sergii Stoian
3e53e04c58 * Source/x11/XGServerWindow.m (screenList): join RandR and non-RandR
code. Failback to Xlib generic method if any no RandR available or
  RandR function call was unsuccessful. In Xlib generic method fill in
  monitors array with values.
  (boundsForScreen:): use values from cached `monitors` array since
  -screenList fills it on both cases with or without RandR available.
2020-01-31 19:28:32 +02:00
Sergii Stoian
022a988e97 * Source/x11/XGServerWindow.m (boundsForScreen:): check for number of
XRandR's ouputs.
2020-01-31 18:59:49 +02:00
Riccardo Mottola
ae3510f385 Check if Xrandr did not succeed and provide fallback. 2020-01-31 16:29:01 +01:00
Sergii Stoian
7e6dfa39e8 * Source/x11/XGServerWindow.m (screenList): fixed missed rename count
into `monitorsCount` on non-RandR code.
2020-01-30 14:08:59 +02:00
Sergii Stoian
c4631e0fc3 * Source/x11/XGServerWindow.m:
(windowDepthForScreen:): renamed method parameter; append `x_` prefix to
  `Screen *` internal variable; validate `screen` parameter value; use
  `defScreen` for RandR enabled code.
  (availableDepthsForScreen:): ditto.
  (resolutionForScreen:): renamed method parameter; validate `screen`
  parameter value.
  (boundsForScreen:): renamed method parameter.
2020-01-30 13:58:34 +02:00
Sergii Stoian
66f1e75c50 ChangeLog: fix date in last change. 2020-01-30 01:29:56 +02:00
Sergii Stoian
62bef72ac0 * Headers/x11/XGServer.h: monitorsCount ivar was added to hold
`monitors` array items.
* Source/x11/XGServerWindow.m: use `monitorsCount` instead of local
  variable `count` or ScreenCount() value.
* ChangeLog: update to the latest changes.
Mark methods where usage of X Screen as parameter is correct and where isn't.
2020-01-30 01:27:11 +02:00
Sergii Stoian
7ebd2468b1 * Headers/x11/XGServer.h,
* Source/x11/XGServer.m,
* Source/x11/XGServerWindow.m: hold the cache of connected monitor devices
  parameters - `monitors` - a an array structures.
2020-01-29 19:23:52 +02:00
Sergii Stoian
88bc2a4efd
Merge pull request #18 from gnustep/randr
Dynamic screen resolution change support
2020-01-29 14:55:09 +02:00
Sergii Stoian
f38d8a33bd * Source/x11/XGServerEvent.m (processEvent:): add space after comma in
XSync call.
* Source/x11/XGServerWindow.m (boundsForScreen:): use NSZeroRect.
2020-01-28 12:04:03 +02:00
Sergii Stoian
8d9223aa1e Merge branch 'randr' of https://github.com/gnustep/libs-back into randr 2020-01-28 11:53:11 +02:00
Sergii Stoian
6947c49951 * Headers/x11/XGServer.h: split RandR variables defintion into separate
lines.
2020-01-28 11:52:24 +02:00
Fred Kiefer
f0395f07ce
Merge branch 'master' into randr 2020-01-27 23:19:03 +01:00
Sergii Stoian
b5c563a400 * Source/x11/XGServerWindow.m (boundsForScreen:): use screen variable
to identify output in RandR screen resources. Use `boundsRect` local
  variable as return vaalue storage. Cleanup.
2020-01-26 23:56:00 +02:00
Sergii Stoian
111add7ec2
Merge pull request #16 from trunkmaster/master
Clang warnings fix for ART backend
2020-01-26 22:52:55 +02:00
Sergii Stoian
72284c1d37 * Source/art/ftont-old.m: is unused, so removed. 2020-01-26 22:51:22 +02:00
Sergii Stoian
78a5f6a380 * Source/x11/XGServerEvent.m (processEvent:),
* Source/x11/XGServer.m (_initXContext): catch and process RandR event
  on default screen.
2020-01-26 02:55:34 +02:00
Sergii Stoian
7f24ad7d89 * Source/x11/XGServerWindow.m (_OSFrameToXFrame:for:): use
-boundsForScreen: to get correct screen dimensions if RandR is supported.
(_OSFrameToXHints:for:): ditto.
(_XFrameToOSFrame:for:): ditto.
(movewindow::): ditto.
(windowbounds:): ditto.
(setMouseLocation:onScreen:): ditto.
* Source/x11/XGDragView.m: ditto.

* Source/x11/XGServerEvent.m (processEvent:): destroy NSScreen screens
list to be regenereated on next call. This change updates ivars of
NSScreen (_frame, _depth) by recreating NSScreen instances.
(mouseLocationOnScreen🪟): use -boundsForScreen: to get correct
screen dimensions if RandR is supported.
2020-01-24 19:43:09 +02:00
Sergii Stoian
64335397b5 * Headers/x11/XGServer.h (GSDisplayServer): RandR event and error base
ivars were added.
* Source/x11/XGServer.m (_initXContext): get RandR event and error base.
* Source/x11/XGServerEvent.m (processEvent:): pack several RandR events
  into one notification post.
2020-01-23 19:03:34 +02:00
Sergii Stoian
501c6eb018 * Source/x11/XGServerWindow.m (boundsForScreen:): if Xrandr support
enabled get screen dimensions using Xrandr objects.
* Source/x11/XGServerEvent.m (processEvent:): process Xrandr event and
  send NSApplicationDidChangeScreenParametersNotification.
* Source/x11/XGServer.m	(_initXContext): subscribe to the Xrandr event.
2020-01-23 02:02:52 +02:00
Sergii Stoian
2085ea4a9a * configure.ac: check for availability of Xrandr library.
* config.h.in: added default value for Xrandr usage.
* configure: regenerate.
2020-01-22 12:58:17 +02:00
Marcus Müller
df63d305ac Fix ALPHA_THRESHOLD typo 2020-01-21 23:59:26 +01:00
Sergii Stoian
19a68d2d85 * Source/art/ftfont.m: removed commented out #include and #include
moved into ftfont.h.
2020-01-19 01:31:21 +02:00
Sergii Stoian
2657c4437c * Source/art/shfill.m:,
* Source/art/path.m:,
* Source/art/image.m (DPSimage:::::::::::):
  fixed type formatting specifiers.

* Source/art/ftfont.m: removed include to ftfont-old.m.
  (drawString:at::to::::::::color::::transform:deltas:::widthChar:drawinfo:):,
  (drawGlyphs::at::to::::::color::::transform:drawinfo:):,
  (drawGlyphs::at::to::::::alpha::color::::transform:drawinfo:):,
  (bezierpath_funcs):,
  fixed type formatting specifiers; moved interface declaration of FTFontInfo
  to ftfont.h; removed GCCism.

* Source/art/ftfont.h: moved interface declaration of FTFontInfo here.
* Source/art/composite.m: fixed type formatting specifiers.
* Source/art/FTFontEnumerator.m (load_font_configuration): fixed type
  formatting specifiers.
2020-01-17 17:23:07 +02:00
Sergii Stoian
a890577b76
Merge pull request #15 from trunkmaster/master
TakeFocus request handling fix
2020-01-16 19:52:23 +02:00
Sergii Stoian
9cc708e9e8 * Source/x11/XGServerEvent.m (_handleTakeFocusAtom:forContext:): key_window
definition moved to the `if` block where it's used.
2020-01-16 19:47:48 +02:00
Sergii Stoian
a1f08ad8ca * Source/x11/XGServerEvent.m (_handleTakeFocusAtom:forContext:): tiny
formatting fix.
2020-01-16 11:44:28 +02:00
Sergii Stoian
4e5f2ddbb1 * Source/x11/XGServerEvent.m (_handleTakeFocusAtom:forContext:): use
`cWin` instead of `this_window`
* ChangeLog: updated.
2020-01-16 11:41:02 +02:00
Sergii Stoian
124a18f026 * Source/x11/XGServerEvent.m (_handleTakeFocusAtom:forContext:):
- use lowerCamelCase for objects and underscores for primitive types;
  - added and used `this_window` variable - represents window that has
    received TakeFocus event - instead of `cWin` (last used window by
    backend);
  - do not ignore TakeFocus request if now key window was set
    and if main application menu received request.
2020-01-16 00:54:34 +02:00
Sergii Stoian
09bf6067c2
Merge pull request #14 from trunkmaster/master
Correct application icon images in WM
2020-01-14 10:55:29 +02:00
Sergii Stoian
d1dd3f0f5c * Source/x11/XGServerWindow.m (ALPHA_THRESHOLD): removed duplicate of
definition.
2020-01-14 10:52:59 +02:00
Sergii Stoian
9e298b2142 * Source/x11/XGServerWindow.m (alphaMaskForImage):
(imagecursor:::): renamed missed image_mask() call.
2020-01-14 02:05:07 +02:00
Sergii Stoian
f9a9d6679b * Source/x11/XGServerWindow.m (alphaMaskForImage): renamed from
image_mask().
  (swapColors): new function to convert colors from ARGB order into RGBA
  (big-endian systems) or BGRA (little-endian systems).
  (_createAppIconPixmaps): use swapColors() and remove unused code.
  (restrictWindow:toImage:): use alphaMaskForImage().
  (imagecursor:::): use swapColors() and remove unused code.
2020-01-14 01:58:30 +02:00
Sergii Stoian
528660834c * Source/x11/XGServerWindow.m (_createNetIcon:result:size:): fixed
off-by-one mistake during alpha handling. Enable disabled code and
  remove temprorary one.
  (window::::): set NetWM icon to window for all EWMH capable WMs even
  it's WindowMaker.
  (image_mask): new function to create alpha mask for image. It's based
  on xgps_cursor_mask() code with additional argument `alpha_treshold`.
  This function may be used for images (alpha_treshold == 0) with real
  alpha mask and for cursors (if no Xcursor library is used - no alpha
  is used, no shadows in cursors, alpha_treshold == 158 is used to cut
  transparent pixels).
  (_createAppIconPixmaps): icon pixmap creation rewritten to support
  images with alpha channel using wraster functions. Use image_mask().
  (restrictWindow:toImage:): use image_mask() instead of
  xgps_cursor_mask().
  (xgps_cursor_mask): removed as image_mask() replaced it.
  Guard xgps_cursor_image( with #if - will not be compiled if Xcursor
  is used.
  (imagecursor:::): use image_mask() instead of xgps_cursor_mask().
2020-01-13 01:34:11 +02:00
fredkiefer
de86246567 * Source/cairo/CairoFontInfo.m: Revert to the old defaults for
hinting and allow for all possible values to be set.
2019-12-24 14:10:02 +01:00
Fred Kiefer
f409903fb4
Merge pull request #12 from gnustep/ivucica-codeowners-1
Add CODEOWNERS.
2019-11-04 09:08:11 +01:00
Ivan Vučica
3acbb83ef1
Add CODEOWNERS. 2019-11-03 22:54:07 +00:00
Gregory John Casamento
c6919519c6 Update version 2019-09-13 23:35:48 -04:00
fredkiefer
36283735ab * Source/cairo/CairoFontInfo.m,
* Source/fontconfig/FCFontEnumerator.m: Small cleanup of last pull
request.
2019-05-19 22:56:48 +02:00
fredkiefer
5362c305bc Add ChangeLog to merged pull request. 2019-05-19 21:13:29 +02:00
Fred Kiefer
8691c48537
Merge pull request #5 from Deek/deek
Font system revamp
2019-05-19 18:06:46 +02:00
Fred Kiefer
d2d0e6650a
Merge pull request #11 from trunkmaster/master
Mouse cursor images handling fix and cleanup
2019-05-01 14:15:14 +02:00
Gregory John Casamento
d5f2097261 Add changes to address 16 bit support in Xlib. Need to test 2019-04-20 11:17:57 -04:00
Sergii Stoian
00a1180684 * Source/x11/XGServerWindow.m (standardcursor::): Getting of
XC_fleur as GSCloseHandCursor was removed because it loads in
NSCursor as image.
2019-04-20 02:01:40 +03:00
Sergii Stoian
39e2e16bec * Source/x11/XGServerWindow.m (standardcursor::): revert resizing
cursor names to the old values upon request of project owner.
2019-04-18 01:22:57 +03:00
Sergii Stoian
d4a4888b9d * Source/x11/XGServerWindow.m (getStandardBitmap): send bitmapFormat
to _convertToFormatBitsPerSample::::::::. Fixes display of colored
mouse cursor images.
(standardcursor::): cleanup in Xlib cursors handling. Additional
cursor types were added: GSClosedHandCursor, GSOpenHandCursor.
Removed GSDisappearingItemCursor type handling - it loads in NSCursor
from image.
2019-04-17 18:06:19 +03:00
Fred Kiefer
9f750d2c4f
Merge pull request #10 from trunkmaster/master
Support for configurable mouse properties
2019-04-12 16:11:18 +02:00
Sergii Stoian
b5003272a7 * Source/x11/XGServerEvent.m (mouseOptionsChanged:): change double-click
minimum value to 200 and default to 300.
2019-04-12 15:45:39 +03:00
Sergii Stoian
59b1f51e5f * Source/x11/XGServerEvent.m (processEvent:): do not send event if
disabled menu mouse button was released.
2019-04-11 13:15:09 +03:00
Sergii Stoian
7981c3e41c * Source/x11/XGServerEvent.m (initializeMouse): new method. Calls -mouseOptionsChanged:
and setups observer for defaults changes.
(mouseOptionsChanged:): new method. Read mouse properties from user defaults.
(processEvent:): respect mouse options on ButtonPress and ButtonRelease events.

* Source/x11/XGServer.m (dealloc): remove notification observer.
2019-04-11 01:50:30 +03:00
Fred Kiefer
6f69fdcc2f
Merge pull request #9 from trunkmaster/master
Added support for WindowMaker's WMFHideApplication action.
2019-04-06 23:32:22 +02:00
Sergii Stoian
2f4c96f9d1 hidewindow method was renamed to hideApplication. 2019-04-06 22:32:29 +03:00
Sergii Stoian
b492ac87cd Added support for WindowMaker's WMFHideApplication action. 2019-04-05 14:46:05 +03:00
Fred Kiefer
ba2d592083
Merge pull request #8 from trunkmaster/master
Send double-click on appicon to WindowMaker
2019-04-04 16:41:11 +02:00
Sergii Stoian
f9958176db Do not send NSEvent only for single-click on appicon and minindow in WindowMaker environment. 2019-04-04 12:10:47 +03:00
Sergii Stoian
21f38f8060 Send double-click on appicon to the WindowMaker. Old code sent to WM only single-click. 2019-04-04 01:22:25 +03:00
Fred Kiefer
ee865548bf
Merge pull request #7 from trunkmaster/master
Handle `-autolaunch YES` application argument
2019-04-03 22:36:13 +02:00
Sergii Stoian
233c129a5c WM_IGNORE_FOCUS_EVENTS atom was added. Use new atom in orderwindow::: code added in last commit. 2019-04-03 19:13:30 +03:00
Sergii Stoian
a6595e320d Map application icon window without focus switch for applications executed with argument -autolaunch YES in WindowMaker environment. 2019-04-02 19:38:44 +03:00
Fred Kiefer
41e57d8d5f
Merge pull request #6 from trunkmaster/master
Set `Utility` window type for NSFloatingWindowLevel.
2019-03-26 22:26:41 +01:00
Sergii Stoian
f4d01bab0c Added ChangeLog entry to Source/x11/XGServerWindow.m change. 2019-03-26 23:23:25 +02:00
Sergii Stoian
0374820172 Set Utility window type for NSFloatingWindowLevel. 2019-03-26 17:12:55 +02:00
Jeff Teunissen
f87842d08a Turn on hinting and subpixel rendering for Cairo.
There's no good reason not to enable subpixel rendering and hinting.
Leaving it off makes GNUstep apps look worse than everything else, in
exchange for having -advancementForGlyph: be totally consistent, which
may not even be necessary.

So, yeah, let's just turn this stuff on. I reused the subpixel default
from back-art to preserve configs, and added a GSFontHinting default to
control text hinting.

Use 0 for whatever Cairo defaults to, 1 for off, 2 for slight hinting,
3 for medium hinting, or 4 for full hinting.
2019-03-26 03:58:18 -04:00
Jeff Teunissen
0578a7d915 Add some generated files to .gitignore 2019-03-26 03:58:18 -04:00
Jeff Teunissen
d519e8542b Stub code for SFNT access
Some simple code for getting access to the main SFNT tables used for
drawing the right glyphs in the right ways. It's hidden with an "#if 0" for
future use.
2019-03-26 03:58:18 -04:00
Jeff Teunissen
8f19df1949 Support named glyphs, encodings in Cairo
Implement a method for accessing named glyphs and character codings from
Cairo.

This is a necessary first step for complex glyph substitution, and even
simple things like standard ligatures.
2019-03-26 03:58:18 -04:00
Jeff Teunissen
1b23bfe1fd Better sorting of fonts
Rather than sorting fonts by the integer value of "traits", let's sort by
the traits we are looking for specifically. Again, like many other things,
totally correct handling of this stuff will have to wait for a good method
of inspecting and correctly processing SFNT tables.
2019-03-26 03:58:18 -04:00
Jeff Teunissen
d0a9f5b943 Handle "strange" font weights
Fontconfig's font weights are almost but not entirely defined by the
constants found in its source code. Things like FC_WEIGHT_LIGHT are not,
as we had presumed, a list of definitive weights. As such, it seems there
are a goodly number of fonts that have weights not appearing in the list.

For example, say there's a font that is heavier than Medium (weight 100 for
fontconfig, and 6 for us) but not as heavy as Demibold (FC: 180, GS: 7),
then it might tell Fontconfig it has a weight of 130.

When this happens, we _could_ assign its NSWeight to be 6 or 7, but it's
possible that there will be another face in that font that ALSO fits there,
which might throw off the sorting. Instead, what I suggest is to do what
I have done...assign an NSWeight with a weight class that represents the
numeric distance _between_ the two defined values.

So the GS weight for this font face becomes something like:

NSWeight = 6 + ((FCWeight - Medium) * (1.0 / (Demibold - Medium)))

or, in numeric terms, 6 + 0.375

In service of this change, I have switched the actual Weight value within
the font dictionary from int to float. This is an attempt to translate this
situation into a sortable form we can work with, compressing an approximate
range of possible FC font weights into our 0-15 system.

There may well be a better way to go about this, such as figuring out where
fontconfig gets this info in the first place and converting from the source
directly, but accessing the SFNT tables (which will almost certainly be
required) is something for a later day.
2019-03-26 03:58:18 -04:00
Jeff Teunissen
5737e249f5 fix 'italic' detection
Don't check for italic, check for slant greater than roman. That way, we
catch oblique (which is more slanted than 'italic') too.
2019-03-26 03:58:18 -04:00
Jeff Teunissen
8df5bb1064 More postscriptname support
Support reading the PS name from a pattern.
2019-03-26 03:58:18 -04:00
Jeff Teunissen
325c927814 fontconfig: use fullname for displayName (most of the time)
Can't use fullname ALL the time, because some (mostly Adobe) fonts store
a duplicate of their PostScript name in the fullname field (and for that
case, we can just do what we already did), but it works well for just about
everything else.
2019-03-26 03:58:18 -04:00
Jeff Teunissen
ecba94053d sort font faces
GNUstep's font architecture makes it extremely difficult and annoying to
have a properly sorted font panel (or even one that makes any sense at all).

This might not be the best place to implement font sorting, but I'll be
damned if I can find a better one. The font enumerator knows where to look,
and has all the information needed to do it.

So, once we've enumerated all the fonts, sort them with a function that's
only slightly more clever than alphabetizing them. We sort by these
criteria, in order of importance:

1. font weight
2. traits (numeric ordering)
3. style name, with special cases so "Regular"/"Normal"/"Roman" sort
   earlier than other stuff (caption, titling, etc.)

This sorting function seems to work about as well as can be expected,
producing the obvious "Regular"/"Italic"/"Bold"/"Bold Italic" for
undemanding families, while getting more advanced ones (like, say, the 168
font faces of Kepler Std) pretty close.
2019-03-26 03:58:18 -04:00
Jeff Teunissen
233e44dc4c Support fontconfig 2.11's new 'postscriptname' attribute.
GNUstep has been bending over backwards to deal with fontconfig's baffling
lack of support for PostScript-style font names, just as it bent over
backwards to deal with XLFD's lack of same. Luckily, the fontconfig guys
have done us (and let's be honest, ghostscript and every pdf reader in
creation) a solid, and now that it's here it would be downright criminal
to not use it.

Implement it. :)
2019-03-26 03:58:18 -04:00
Jeff Teunissen
016f5eda25 Cairo: Reduce the hilarity of the font panel
Use many more weights and widths when generating the (still extremely
stupid) synthetic PostScript font names.
2019-03-26 03:58:18 -04:00
Jeff Teunissen
390f82f064 make displayName work 2019-03-26 03:58:18 -04:00
Ivan Vučica
390be8237c
release-chore: Update to 0.27.0. 2019-01-06 22:23:49 +00:00
fredkiefer
9b43c1d568 * Documentation/news.texi: Fill in some details for pending release. 2019-01-03 23:26:21 +01:00
fredkiefer
fd84d377f2 * Source/opal/OpalGState.m: Add colour handling for all the different
colour spaces.
2019-01-03 23:06:51 +01:00
Fred Kiefer
059f42a869
Merge pull request #4 from shlyakpavel/patch-2
Fix memory leaks in convert.c
2019-01-01 14:58:03 +01:00
Pavel Shlyak
8b41047eae
Update ChangeLog 2019-01-01 17:30:53 +04:00
Pavel Shlyak
3b7f8f0e84
Fix memory leaks in convert.c 2018-12-31 23:42:17 +04:00
fredkiefer
d9bc28c4ca * Source/gsc/GSGState.m (-setColor:state:): Don't copy values onto themselves. 2018-12-02 12:36:28 +01:00
fredkiefer
442eb2515e * Source/opal/OpalContext.m (-initWithGraphicsPort:flipped:): Implement.
* Source/opal/OpalContext.m (-GSSetDevice:::): Get height form
surface if no y value is given.
* Source/opal/OpalSurface.m: Rewrite to handle the case where
device is not set.
2018-09-16 17:27:48 +02:00
fredkiefer
7ee9b40793 * Source/x11/XGServerWindow.m (_setupRootWindow): Make sure the
root name variable is null terminated.
2018-07-16 08:39:55 +02:00
fredkiefer
6e797c9e6d * Source/x11/XGServerWindow.m: Check for bytes_after_ret in
PropGetCheckProperty. Attempt to improve the window border detection.
Based on idea by Tom MacSween <Tom.MacSween@crins-sinrc.ca>
2018-06-20 07:49:36 +02:00
fredkiefer
b9e9f461ab Restructure Atom handling to get all atoms at once.
Add new method on XGServer to get the name of the window manager.
2018-05-01 23:08:35 +02:00
Riccardo Mottola
75adf6130a Be consistent in prepending flags to existing LDFLAGS and CPPLFLAGS 2018-03-03 19:58:03 +01:00
fredkiefer
f41d8b26fa Commit patch by Yavor Doganov to not build font_cacher when the xlib backend wont use it.
Deprecate art, xlib and xdps.
2018-02-25 18:53:42 +01:00
fredkiefer
969b77a6c1 * Source/x11/XGServer.m (_initXContext): Call XInitThreads to
enable drawing in secondary threads.
2018-02-09 21:56:01 +01:00
fredkiefer
1a15d0393e Replace xlib specific font enumerator with the shared one for fontconfig.
Add glyph cache for GSXftFontInfo.
2018-02-05 20:50:48 +01:00
fredkiefer
738ed900d5 * configure.ac: Add FREETYPE_LIBS to LIBS when building xlib.
* configure: Regenerate
2018-01-21 16:46:40 +01:00
fredkiefer
18440736e1 * configure.ac: Detect freetype with PKG_CHECK_MODULES.
* configure: Regenerate.
2018-01-21 16:40:41 +01:00
fredkiefer
5293511f03 Patch by Yavor Doganov to improve autoreconf.
Add .gitignore file.
2018-01-07 14:33:33 +01:00
109 changed files with 15437 additions and 8207 deletions

47
.github/workflows/main.yml vendored Normal file
View file

@ -0,0 +1,47 @@
on:
push:
pull_request:
jobs:
########### Linux ###########
linux:
name: ci
runs-on: ubuntu-latest
container:
image: ubuntu:22.04
# don't run pull requests from local branches twice
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.repository
strategy:
matrix:
include:
- server: x11
graphics: cairo
- server: x11
graphics: xlib
- server: headless
graphics: headless
env:
DEBIAN_FRONTEND: noninteractive
steps:
- uses: actions/checkout@v3
- name: Install packages
run: |
apt-get -q -y update
apt-get -q -y install libgnustep-gui-dev libfreetype-dev libcairo2-dev libxt-dev pkg-config build-essential
- name: Build source
run: |
. /usr/share/GNUstep/Makefiles/GNUstep.sh
./configure --enable-server=${{ matrix.server }} --enable-graphics=${{ matrix.graphics }}
make && make install
- name: Run tests
run: |
. /usr/share/GNUstep/Makefiles/GNUstep.sh
make check

16
.gitignore vendored Normal file
View file

@ -0,0 +1,16 @@
obj
*.log
*.sum
*.bundle
*.service
autom4te.cache
config.h
config.log
config.status
config.cache
config.make
back.make
Source/config.h
Source/libgnustep*Info.plist
Tools/XGCommonFont.m
Tools/xdnd.c

View file

@ -1,7 +1,7 @@
1 ANNOUNCE
**********
1 Announcement
**************
This is version 0.26.2 of the GNUstep GUI Backend ('gnustep-back').
This is version 0.32.0 of the GNUstep GUI Backend (gnustep-back).
1.1 What is the GNUstep GUI Backend?
====================================
@ -20,44 +20,27 @@ easily ported to other display systems.
Window's Systems. It works via a DPS emulation engine to emulate the
DPS functions required by the front-end system.
1.2 Noteworthy changes in version '0.26.2'
1.2 Noteworthy changes in version 0.32.0
==========================================
This release contains no changes since 0.26.1. It is released to
coincide with gnustep-gui 0.26.2, which has important bugfixes related
to printing.
The release includes mostly bug fixes.
1.3 Noteworthy changes in version '0.26.1'
==========================================
• Make window termination saver.
• Use default interpolation in Cairo.
• Allow UTF-8 input from XLookupString.
• Improve building on MS Windows.
This release contains no changes since 0.26.0. It is released to
coincide with gnustep-gui 0.26.1, released to mark gnustep-base 1.25.1
as the requirement for gnustep-gui.
1.4 Noteworthy changes in version '0.26.0'
==========================================
This release includes a few bugfixes, as well as compatibility
improvements as a result of GSoC 2017 project.
* opal: Bridging categories between Opal and GNUstep GUI. Added onto
NSColor, NSImage and NSImageRep.
* cairo: Get -DPSshow: to work on scaled windows.
* opal: Allow creating a NSGraphicsContext with a custom graphics
port, other than a CGContext.
* misc: Fix reported static analyser warnings.
1.5 Where can you get it? How can you compile it?
1.3 Where can you get it? How can you compile it?
=================================================
The gnustep-back-0.26.2.tar.gz distribution file has been placed at
The gnustep-back-0.32.0.tar.gz distribution file has been placed at
<ftp://ftp.gnustep.org/pub/gnustep/core>.
It is accompanied by gnustep-back-0.26.2.tar.gz.sig, a PGP signature
It is accompanied by gnustep-back-0.32.0.tar.gz.sig, a PGP signature
which you can validate by putting both files in the same directory and
using:
gpg --verify gnustep-back-0.26.2.tar.gz.sig
gpg --verify gnustep-back-0.32.0.tar.gz.sig
Signature has been created using the key with the following
fingerprint:
@ -67,13 +50,15 @@ fingerprint:
Read the INSTALL file or the GNUstep-HOWTO for installation
instructions.
1.6 Where do I send bug reports?
1.4 Where do I send bug reports?
================================
Bug reports can be sent to the GNUstep bug list <bug-gnustep@gnu.org>
Please log bug reports on the GNUstep project page
<http://savannah.gnu.org/bugs/?group=gnustep> or send bug reports to
<bug-gnustep@gnu.org>.
1.7 Obtaining GNU Software
==========================
1.5 Obtaining GNUstep Software
==============================
Check out the GNUstep web site. (<http://www.gnustep.org/>) and the GNU
web site. (<http://www.gnu.org/>)

7
CODEOWNERS Normal file
View file

@ -0,0 +1,7 @@
# These owners will be the default owners for everything in
# the repo. Unless a later match takes precedence,
# @global-owner1 and @global-owner2 will be requested for
# review when someone opens a pull request.
* @fredkiefer
Source/opal/* @ivucica @fredkiefer
Headers/opal/* @ivucica @fredkiefer

746
ChangeLog
View file

@ -1,3 +1,745 @@
2025-02-11 Richard Frith-Macdonald <rfm@gnu.org>
* ANNOUNCE:
* INSTALL:
* NEWS:
* README:
* Version: bump to 0.32.0
New release
2024-05-26 Fred Kiefer <FredKiefer@gmx.de>
* ChangeLog: Update for new release
* ANNOUNCE:
* NEWS:
* Documentation/news.texi: Update of release notes for 0.31.0.
* Version: bump to 0.31.0
2022-12-29 Richard Frith-Macdonald <rfm@gnu.org>
* ChangeLog: Update for new release
* ANNOUNCE:
* NEWS:
* Documentation/news.texi: Update of release notes for 0.30.0 by Fred.
* Version: bump to 0.30.0
2022-02-22 Riccardo Mottola <rm@gnu.org>
* Tools/xpbs.m (xSelectionNotify:):
Delete property on begin and at every Notify to start and continue
transfer of INCR.
2020-04-26 Ivan Vucica <ivan@vucica.net>
* ANNOUNCE:
* NEWS:
* README:
Updating documentation for the 0.29.0 release.
2021-03-12 Fred Kiefer <FredKiefer@gmx.de>
* Source/x11/XGServerWindow.m (-styleoffsets:...:): Change NSLog
statement on guessing the offset into a NSDebugLLog statement.
2021-03-03 Riccardo Mottola <rm@gnu.org>
* Source/win32/WIN32Server.m:
actually store in a LONG_PTR the result of GetWindowLongPtr
2021-03-02 Riccardo Mottola <rm@gnu.org>
* Source/win32/WIN32Server.m
* Source/win32/w32_create.m
* Source/win32/w32_general.m
* Source/win32/w32_movesize.m
* Source/win32/w32_windowdisplay.m
* Source/winlib/WIN32GState.m
* Source/cairo/Win32CairoGlitzSurface.m:
Consistently use 64bit safe SetWindowLongPtr/GetWindowLongPtr instead
of a mix with old 32bit versions.
2021-01-27 Sergii Stoian <stoyan255@gmail.com>
* Source/x11/XGServerWindow.m (_checkStyle:): do not set application
name and WindowGroupHint to temporary window. Created window designed
to help get window frame offsets only - appicon window will be created
later. This change prevents appicon flickering on WindowMaker at
application start.
(_createWMAppiconHack, _setupRootWindow): WindowMaker hack removed in
favour of solution introduced in _checkStyle:.
2021-01-24 Sergii Stoian <stoyan255@gmail.com>
* Source/x11/XGServerWindow.m: WindowMaker doesn't support
_NET_REQUEST_FRAME_EXTENTS message andthe only way to determine offsets
is creating and mapping window. In this case first mapped window of
application is not appicon window.
Early appicon creating inserted back as _createWMAppiconHack method and
called only if no other way to determine window's offsets (before call to
_checkStyle);appicon window size is set to size icon;
2021-01-16 Fred Kiefer <FredKiefer@gmx.de>
* Documentation/news.texi: Fill in some details for pending release.
* Version: Inclease version number.
2020-09-18 Sergii Stoian <stoyan255@gmail.com>
* Source/x11/XGServerWindow.m
(_setupRootWindow, window::::): removed WindowMaker appicon hack and
- now unused - _wmAppIcon variable.
Description: The removed code removed creates and maps zero-sized
window in hope that WindowMaker will recognize app by this event and
create app icon window. Although when application requests window
for appicon through the `-window::::` method call, it returns newly
created and mapped window. This actually happens but application icon
flickers between WM icon creation and application icon window appearance.
This fix based on the fact that root application window (ROOT) is mapped
in `-orderwindow:::` and this is the event of application recognition
by WindowMaker because it is a first application window that is
mapped.
2020-09-17 Sergii Stoian <stoyan255@gmail.com>
* Source/x11/XGServerEvent.m
(_handleTakeFocusAtom:forContext:): if application (window) receives
WM_TAKE_FOCUS in hidden state it means WindowMaker wants us to be
unhidden.
Description: There are 2 protocols defined in XGServerWindow.h:
WMFHideApplication and WMFHideOtherApplications. These protocols exist
to help GNUstep application and WindowMaker notify each other
about "Hide" and "Hide Others" actions. There are no protocols for
"unhide" action.
Test case steps:
1. Open application with window opened.
2. Hide application with "Hide" menu item.
3. Open WindowMaker's "Windows" menu (middle-click on desktop).
4. Select hidden application window.
Application unhides, activates, restored window is focused (receives) input
and "Hide" menu item unselected.
2020-09-16 Sergii Stoian <stoyan255@gmail.com>
* Source/x11/XGServerWindow.m
(hideApplication:): send application's root window to WindowMaker(WM)
because it's a "group leader" that clearly identifies application
inside WM. WM uses XFindContext to get WApplication structure and
"group leader" window ID is a key to find it.
2020-06-18 Riccardo Mottola <rm@gnu.org>
* Tools/font_cacher.m:
If the Library directory is not found, create one for the user.
2020-06-18 Riccardo Mottola <rm@gnu.org>
* Source/xlib/XGFontManager.m
Match return value in case of error (nil instead of NO)
* Headers/xlib/XGPrivate.h
Fix return value of width to CGFloat
2020-06-10 Fred Kiefer <FredKiefer@gmx.de>
* Headers/fontconfig/FCFaceInfo.h: Add instancevariable _patternIsResolved.
* Source/fontconfig/FCFaceInfo.m (-matchedPattern): Cache the
resolved pattern and return this. The method characterSet now uses
this cached pattern.
Patch by Josh Freeman <gnustep_lists@twilightedge.com>
2020-04-25 Ivan Vucica <ivan@vucica.net>
* Source/GSBackend.m:
* Source/cairo/GNUmakefile:
* Source/cairo/CairoContext.m:
* Source/cairo/WaylandCairoSurface.m:
* Source/wayland/GNUmakefile:
* Source/wayland/GNUmakefile.preamble:
* Source/wayland/WaylandServer.m:
* Source/wayland/xdg-shell-protocol.c:
* Source/wayland/README.md:
* Headers/cairo/WaylandCairoSurface.h:
* Headers/wayland/WaylandServer.h:
* Headers/wayland/xdg-shell-client-protocol.h:
* wayland-regenerate.h:
* configure:
* configure.ac:
Initial merge of the Wayland backend into the master branch.
2020-04-13 Ivan Vucica <ivan@vucica.net>
* Documentation/announce.texi:
* ANNOUNCE:
Normalize the accompanying text for the release announcement across
core packages: standardize chapter name and GPG information.
2020-04-05 Ivan Vucica <ivan@vucica.net>
* ANNOUNCE:
* NEWS:
* README:
Updating documentation for the 0.28.0 release.
2020-03-27 Fred Kiefer <FredKiefer@gmx.de>
* Documentation/news.texi: Fill in some details for pending release.
2020-03-12 Sergii Stoian <stoyan255@gmail.com>
* Source/art/GNUmakefile.preamble,
* Source/gsc/GNUmakefile.preamble: do not overwrite ADDITIONAL_INCLUDE_DIRS
value to help RPM build. In spec file ADDITIONAL_INCLUDE_DIRS can be sat
to subdirectories which are create by RPM build tool.
2020-03-05 Sergii Stoian <stoyan255@gmail.com>
* Source/x11/XGServerWindow.m (placewindow::): check window frame
in OpenStep and Xlib coordinate systems to decide if it was changed.
Rename `xVal` into more meaninful `xFrame` (holds temporary value of
window frame in Xlib coordiante system).
2020-03-03 Sergii Stoian <stoyan255@gmail.com>
* Headers/x11/XGServer.h,
* Source/x11/XGServer.m (xScreenSize): new primitive method.
* Source/x11/XGDragView.m (XY): use new primitive method to get Xlib
screen height. Fixes broken DnD on vertically aligned monitors.
2020-03-01 Sergii Stoian <stoyan255@gmail.com>
* Source/x11/XGServerWindow.m (placewindow::): call XMoveResizeWindow
even if specified frame is equal current. No events will be send to
-gui for this case but X11 window position will be refreshed. It fixes
misplacement of image in slideImage:from:to: (second and all subsequent
calls).
2020-02-26 Sergii Stoian <stoyan255@gmail.com>
* Headers/x11/XGServerWindow.h (_gswindow_device_t): new structure
memeber was added - `osframe`. This member intended to hold cached frame
of windows in OpenStep coordinate system. This makes backend more
reliable to the cases when gui changes NSWindow's _frame ivar before
call to backend methods which make windows placement.
* Source/x11/XGServerWindow.m (placewindow::): use `osframe` structure
member to decide if window change position or size. Removed usage of
temporary `frame` (used only for making desicion).
2020-02-24 Sergii Stoian <stoyan255@gmail.com>
* Source/x11/XGServerWindow.m (placewindow::): use window->xframe
as current window frame instead of NSWindow's frame because
`_frame` ivar may be already changed to desired value.
2020-02-21 Fred Kiefer <FredKiefer@gmx.de>
* Source/x11/XGServerWindow.m (-_createAppIconPixmaps): Made
preconditions of new code explicit.
* Source/x11/XGServerWindow.m (-orderwindow:::): Set icon pixmap
only for WindowMaker.
2020-02-20 Sergii Stoian <stoyan255@gmail.com>
* Headers/x11/XGServer.h (GSDisplayServer): added new ivar xScreenSize
to hold Xlib screen size dimensions.
* Source/x11/XGServerWindow.m:
(_OSFrameToXFrame:for:): use xScreenSize instead of DisplayHeight.
(_OSFrameToXHints:for:): ditto.
(_XFrameToOSFrame:for:): ditto.
(movewindow::): ditto.
(_screenSize): new static function to get dimensions of Xlib screen from
root window.
(screenList): use xScreenSize instead of DisplayHeight/DisplayWidth.
2020-02-14 Fred Kiefer <FredKiefer@gmx.de>
* Source/x11/XGServerWindow.m (screenList): Clean up
implementation again.
2020-02-12 Sergii Stoian <stoyan255@gmail.com>
* Source/x11/XGServerWindow.m (screenList): revert back to old code
logic: if XRandR available but can't get screens info for some reasons,
return array with one element (Xlib screen).
2020-02-11 Sergii Stoian <stoyan255@gmail.com>
* Source/x11/XGServerWindow.m (screenList): Transform screen
origin into unflipped (OpenStep) coordinate system for XRandR capable
systems. After this change windows and screen will use the same start
of coordinate system for their origins.
2020-02-08 Fred Kiefer <FredKiefer@gmx.de>
* Source/xlib/GSXftFontInfo.m,
* Source/xlib/XGFont.m,
* Source/xlib/XGFontManager.m,
* Source/xlib/XGFontSetFontInfo.m,
* Source/xlib/XGGState.m,
* Source/xlib/XGGeometry.m : Fixes after Xrandr change to get xlib
backend to compile again.
2020-02-08 Fred Kiefer <FredKiefer@gmx.de>
* Source/x11/XGServerWindow.m (screenList): Clean up implementation.
2020-02-07 Sergii Stoian <stoyan255@gmail.com>
* Source/x11/XGServerWindow.m (_XFrameToOSFrame:for:): use Xlib
screen height instead of monitor's because we convert coordinates
from Xlib area.
(movewindow::): use Xlib screen height because we're operating in
Xlib coordinate system.
(screenList): fill monitor depth with value returned by
windowPathForScreen with monitor at index 0 (screen_id already set so
method will get correct screen_id).
* Source/x11/XGServerEvent.m (processEvent:): fixed indentaion.
2020-02-07 Fred Kiefer <FredKiefer@gmx.de>
* Source/x11/XGServerWindow.m (swapColors): Made code more
explicit and removed additional copy before calling this function.
This function should now do what the comment above it says.
(alphaMaskForImage): Slightly cleaner code.
* Source/x11/XGServerEvent.m: Prevent compiler warning by moving method.
2020-02-07 Sergii Stoian <stoyan255@gmail.com>
* Source/x11/XGServerWindow.m (_OSFrameToXFrame:for:):,
(_OSFrameToXHints:for:): use Xlib screen height instead of monitor's
because we convert coordinates to Xlib area.
* Source/x11/XGServerEvent.m (processEvent:): update monitor_id from
NSWindow's screen number (it could change after event processing).
(mouseLocationOnScreen:window:): use Xlib screen height instead of
monitor's. Added comment to code that should be probably removed
later.
2020-02-03 Sergii Stoian <stoyan255@gmail.com>
* Source/x11/XWindowBuffer.m (windowBufferForWindow:depthInfo:): use
renamed XGServer's `screenVisual` and `screenDepth` methods.
* Source/x11/XIMInputServer.m (initWithDelegate:name:):
use `+xDisplay` instead of `xCurrentDisplay`.
(clientWindowRect:): ditto.
* Headers/x11/XGServerWindow.h (_gswindow_device_t):
renamed `screen` to `screen_id`. `monitor_id` element was added -
this is an index of element in MonitorDevice array.
* Source/x11/XGServerWindow.m:
Removed `screen` parameter from methods which contains it in name.
Methods were renamed to remove `Screen` and `FromScreen`.
(_OSFrameToXFrame:for:): use `monitor_id` instead of `screen`.
(_OSFrameToXHints:for:): ditto.
(_XFrameToOSFrame:for:): ditto.
(_checkStyle:): use renamed methods and `screen_id` window structure
element.
(_rootWindow): renamed from _rootWindowForScreen:, use `defScreen`
instead of removed parameter `screen`, set window structure element
`monitor_id` to 0.
(_createBuffer:): use `screen_id` window structure.
(window::::): use renamed methods, `defScreen`, `screen_id` and
`monitor_id` window scructure elements.
(nativeWindow:::::): ditto.
(setbackgroundcolor::): ditto.
(miniwindow:): ditto.
(_createAppIconPixmaps): removed unused `screen` local variable, use
renamed `screenRContext` method.
(orderwindow:::): use `screen_id` window structure element.
(movewindow::): use `screen_id` window structure element as a parameter
to `boundsForScreen`.
(windowbounds:): ditto.
(windowlist): use renamed `_rootWindow` method.
(setMouseLocation:onScreen:): user renamed methods.
(_blankCursor): ditto.
(imagecursor:::): ditto
(recolorcursor:::): ditto.
(screenList): change with assumption that Xlib screen is one per application.
Failback code to RandR-related always creates arrays with one element (no
enumeration needed). Create `monitor` structure in failback (non-RandR) code.
Use `screen_id` MonitorDevice structure element to hold Xlib screen ID.
(windowDepthForScreen:): assume that `screen` parameter is a Xlib screen ID,
simplify code - `screen` will be used with RandR or not.
(availableDepthsForScreen:): changed with assumption that `screen` is a index
of element in `monitors` structure.
* Source/x11/XGServerEvent.m:
use renamed methods and `screen_id` window structure element.
* Headers/x11/XGServer.h
Removed `screen` parameter from methods which contains it in name.
Methods were renamed to remove `Screen` and `FromScreen`.
(MonitorDevice): `screen_id` was added.
* Source/x11/XGServer.m:
use `screen_id` and rename mathods according to XGServer,h.
(_initXContext): initialize `monitors` array early here before first
use (calls to XGServerWindow methods).
* Source/x11/XGDragView.m (XDPY): use `monitor_id` in `boundForScreen:`
call.
* Source/cairo/XGCairoSurface.m: use `xDisplayRootWindow` XGServer's method.
* Source/art/ARTContext.m (setupDrawInfo:): use `xDisplayRootWindow`
XGServer's method.
2020-01-31 Sergii Stoian <stoyan255@gmail.com>
* Source/x11/XGServerWindow.m (boundsForScreen:): check for number of
XRandR's ouputs.
2020-01-31 Riccardo Mottola <rm@gnu.org>
* Source/x11/XGServerWindow.m (boundsForScreen:):
Check if Xrandr did not succeed and provide fallback.
2020-01-31 Sergii Stoian <stoyan255@gmail.com>
* Source/x11/XGServerWindow.m (screenList): join RandR and non-RandR
code. Failback to Xlib generic method if any no RandR available or
RandR function call was unsuccessful. In Xlib generic method fill in
monitors array with values.
(boundsForScreen:): use values from cached `monitors` array since
-screenList fills it on both cases with or without RandR available.
2020-01-30 Sergii Stoian <stoyan255@gmail.com>
* Headers/x11/XGServer.h: new structure `MonitorDevice` and ivar
`monitors`for holding cache of monitor's parameters (depth, resolution,
frame). New ivar `monitorsCount` - holds number of items in `monitors` for
RandR or X11 screen count otherwise.
* Source/x11/XGServerWindow.m (screenList): new method for RandR mode -
enumerates monitors and caches their parameters. Returns array of monitors'
indices to get access to monitors` items.
(boundsForScreen:): use cached `frame` parameter of specified monitor.
Use `monitorsCount` instead of ScreenCount().
(windowDepthForScreen:): renamed method parameter; append `x_` prefix to
`Screen *` internal variable; validate `screen` parameter value; use
`defScreen` for RandR enabled code.
(availableDepthsForScreen:): ditto.
(resolutionForScreen:): renamed method parameter; validate `screen`
parameter value.
(boundsForScreen:): renamed method parameter.
* Source/x11/XGServer.m (dealloc): free `monitors` if it was used.
2020-01-26 Sergii Stoian <stoyan255@gmail.com>
* Source/x11/XGServerWindow.m (boundsForScreen:): use `screen` variable
to identify output in RandR screen resources. Use `boundsRect` local
variable as return vaalue storage. Cleanup.
* Source/x11/XGServerEvent.m (processEvent:),
* Source/x11/XGServer.m (_initXContext): catch and process RandR event
on default screen.
2020-01-24 Sergii Stoian <stoyan255@gmail.com>
* Source/x11/XGServerWindow.m (_OSFrameToXFrame:for:): use
-boundsForScreen: to get correct screen dimensions if RandR is supported.
(_OSFrameToXHints:for:): ditto.
(_XFrameToOSFrame:for:): ditto.
(movewindow::): ditto.
(windowbounds:): ditto.
(setMouseLocation:onScreen:): ditto.
* Source/x11/XGDragView.m: ditto.
* Source/x11/XGServerEvent.m (processEvent:): destroy NSScreen screens
list to be regenereated on next call. This change updates ivars of
NSScreen (_frame, _depth) by recreating NSScreen instances.
(mouseLocationOnScreen:window:): use -boundsForScreen: to get correct
screen dimensions if RandR is supported.
2020-01-23 Sergii Stoian <stoyan255@gmail.com>
* Headers/x11/XGServer.h (GSDisplayServer): RandR event and error base
ivars were added.
* Source/x11/XGServer.m (_initXContext): get RandR event and error base.
* Source/x11/XGServerWindow.m (boundsForScreen:): if Xrandr support
enabled get screen dimensions using Xrandr objects.
* Source/x11/XGServerEvent.m (processEvent:): process Xrandr event and
send NSApplicationDidChangeScreenParametersNotification.
* Source/x11/XGServer.m (_initXContext): subscribe to the Xrandr event.
2020-01-22 Sergii Stoian <stoyan255@gmail.com>
* configure.ac: check for availability of Xrandr library.
* config.h.in: added default value for Xrandr usage.
* configure: regenerate.
2020-01-17 Sergii Stoian <stoyan255@gmail.com>
* Source/art/shfill.m:,
* Source/art/path.m:,
* Source/art/image.m (DPSimage:::::::::::):
fixed type formatting specifiers.
* Source/art/ftfont.m: removed include to ftfont-old.m.
(drawString:at::to::::::::color::::transform:deltas:::widthChar:drawinfo:):,
(drawGlyphs::at::to::::::color::::transform:drawinfo:):,
(drawGlyphs::at::to::::::alpha::color::::transform:drawinfo:):,
(bezierpath_funcs):,
fixed type formatting specifiers; moved interface declaration of FTFontInfo
to ftfont.h; removed GCCism.
* Source/art/ftfont.h: moved interface declaration of FTFontInfo here.
* Source/art/composite.m: fixed type formatting specifiers.
* Source/art/FTFontEnumerator.m (load_font_configuration): fixed type
formatting specifiers.
2020-01-16 Sergii Stoian <stoyan255@gmail.com>
* Source/x11/XGServerEvent.m (_handleTakeFocusAtom:forContext:): use
lowerCamelCase for objects and underscores for primitive types;
do not ignore TakeFocus request if no key window was set
and main application menu receives request.
2020-01-14 Sergii Stoian <stoyan255@gmail.com>
* Source/x11/XGServerWindow.m (alphaMaskForImage): renamed from
image_mask().
(swapColors): new function to convert colors from ARGB order into RGBA
(big-endian systems) or BGRA (little-endian systems).
(_createAppIconPixmaps): use swapColors() and remove unused code.
(restrictWindow:toImage:): use alphaMaskForImage().
(imagecursor:::): use swapColors() and remove unused code.
(ALPHA_THRESHOLD): removed duplicate of definition.
2020-01-13 Sergii Stoian <stoyan255@gmail.com>
* Source/x11/XGServerWindow.m (_createNetIcon:result:size:): fixed
off-by-one mistake during alpha handling. Enable disabled code and
remove temprorary one.
(window::::): set NetWM icon to window for all EWMH capable WMs even
it's WindowMaker.
(image_mask): new function to create alpha mask for image. It's based
on xgps_cursor_mask() code with additional argument `alpha_treshold`.
This function may be used for images (alpha_treshold == 0) with real
alpha mask and for cursors (if no Xcursor library is used - no alpha
is used, no shadows in cursors, alpha_treshold == 158 is used to cut
transparent pixels).
(_createAppIconPixmaps): icon pixmap creation rewritten to support
images with alpha channel using wraster functions. Use image_mask().
(restrictWindow:toImage:): use image_mask() instead of
xgps_cursor_mask().
(xgps_cursor_mask): removed as image_mask() replaced it.
Guard xgps_cursor_image( with #if - will not be compiled if Xcursor
is used.
(imagecursor:::): use image_mask() instead of xgps_cursor_mask().
2019-12-24 Fred Kiefer <FredKiefer@gmx.de>
* Source/cairo/CairoFontInfo.m: Revert to the old defaults for
hinting and allow for all possible values to be set.
2019-05-19 Fred Kiefer <FredKiefer@gmx.de>
* Source/cairo/CairoFontInfo.m,
* Source/fontconfig/FCFontEnumerator.m: Small cleanup of last pull
request.
2019-05-19 Fred Kiefer <FredKiefer@gmx.de>
* .gitignore: Add copied files as they should never be commited.
* Headers/fontconfig/FCFaceInfo.h: Add method displaName.
* Source/art/FTFontEnumerator.m: Retain the display name.
* Source/fontconfig/FCFaceInfo.m,
* Source/fontconfig/FCFontInfo.m,
* Source/art/ftfont.m: Implement the method displayName.
* Source/cairo/CairoFontInfo.m: Enable font hinting and use
subpixel antialias if the variable back-art-subpixel-text is set.
* Source/fontconfig/FCFontEnumerator.m: Better handling of font
names, weight and the order of fonts.
Merged huge pull request by Jeff Teunissen <deek@d2dc.net>
2019-04-20 Sergii Stoian <stoyan255@ukr.net>
* Source/x11/XGServerWindow.m (standardcursor::): Getting of
XC_fleur as GSCloseHandCursor was removed because it loads in
NSCursor as image.
2019-04-18 Sergii Stoian <stoyan255@gmail.com>
* Source/x11/XGServerWindow.m (standardcursor::): revert resizing
cursor names to the old values upon request of project owner.
2019-04-17 Sergii Stoian <stoyan255@gmail.com>
* Source/x11/XGServerWindow.m (getStandardBitmap): send `bitmapFormat`
to _convertToFormatBitsPerSample::::::::. Fixes display of colored
mouse cursor images.
(standardcursor::): cleanup in Xlib cursors handling. Additional
cursor types were added: GSClosedHandCursor, GSOpenHandCursor.
Removed GSDisappearingItemCursor type handling - it loads in NSCursor
from image.
2019-04-12 Sergii Stoian <stoyan255@gmail.com>
* Source/x11/XGServerEvent.m (mouseOptionsChanged:): change double-click
minimum value to 200 and default to 300.
2019-04-11 Sergii Stoian <stoyan255@gmail.com>
* Source/x11/XGServerEvent.m (processEvent:): do not send event if
disabled menu mouse button was released.
2019-04-11 Sergii Stoian <stoyan255@ukr.net>
* Source/x11/XGServerEvent.m (initializeMouse): new method. Calls
-mouseOptionsChanged: and setups observer for defaults changes.
(mouseOptionsChanged:): new method. Read mouse properties from user
defaults.
(processEvent:): respect mouse options on ButtonPress and
ButtonRelease events.
* Source/x11/XGServer.m (dealloc): remove notification observer.
2019-04-06 Sergii Stoian <stoyan255@ukr.net>
* Source/x11/XGServerWindow.m (hideApplication:): new method name for
`hidewindow`.
2019-04-05 Sergii Stoian <stoyan255@gmail.com>
* Headers/x11/XGServerWindow.h (GSMaxWMProtocols): increased number to support
WMFHideApplication.
* Headers/x11/XGGeneric.h: Atoms _WINDOWMAKER_WM_FUNCTION, _GNUSTEP_WM_HIDE_APP
were added.
* Source/x11/XGServerWindow.m (_setSupportedWMProtocols:): added
_GNUSTEP_WM_HIDE_APP protocol suport to the window protocols.
(hidewindow:): implementation of GSDisplayServer method.
* Source/x11/XGServerEvent.m (processEvent:): process _GNUSTEP_WM_HIDE_APP
client message.
2019-04-04 Sergii Stoian <stoyan255@ukr.net>
* Source/x11/XGServerEvent.m (processEvent:):
Send double-click on appicon to the WindowMaker.
2019-04-02 Sergii Stoian <stoyan255@gmail.com>
* Source/x11/XGServerWindow.m:
(orderwindow:::) Map application icon window without focus flickering
for applications executed with argument `-autolaunch YES` in WindowMaker
environment.
2019-03-26 Sergii Stoian <stoyan255@gmail.com>
* Source/x11/XGServerWindow.m:
(setwindowlevel::) Set `Utility` window type for NSFloatingWindowLevel.
2019-01-04 Fred Kiefer <FredKiefer@gmx.de>
* Documentation/news.texi: Fill in some details for pending release.
2019-01-04 Fred Kiefer <FredKiefer@gmx.de>
* Source/opal/OpalGState.m: Add colour handling for all the
different colour spaces.
2018-12-31 Pavel Shlyak <pvshlyak@edu.hse.ru>
* Source/x11/convert.c: Don't leak memory on error handling
2018-12-02 Fred Kiefer <FredKiefer@gmx.de>
* Source/gsc/GSGState.m (-setColor:state:): Don't copy values onto themselves.
2018-09-16 Fred Kiefer <FredKiefer@gmx.de>
* Source/opal/OpalContext.m (-initWithGraphicsPort:flipped:): Implement.
* Source/opal/OpalContext.m (-GSSetDevice:::): Get height from
surface if no y value is given.
* Source/opal/OpalSurface.m: Rewrite to handle the case where
device is not set.
2018-07-16 Fred Kiefer <FredKiefer@gmx.de>
* Source/x11/XGServerWindow.m (_setupRootWindow): Make sure the
root name variable is null terminated.
2018-06-20 Fred Kiefer <FredKiefer@gmx.de>
* Source/x11/XGServerWindow.m: Check for bytes_after_ret in
PropGetCheckProperty. Attempt to improve the window border detection.
Based on idea by Tom MacSween <Tom.MacSween@crins-sinrc.ca>
2018-05-01 Fred Kiefer <FredKiefer@gmx.de>
* Headers/x11/XGGeneric.h: Move all atoms in XGGeneric data structure.
* Source/x11/XGServerEvent.m,
* Source/x11/XGServerWindow.m: Use atoms from XGGeneric.
* Headers/x11/XGServer.h,
* Source/x11/XGServerEvent.m (-windowManagerName): New method to
get the name of the window manager.
2018-03-03 Riccardo Mottola <rm@gnu.org>
* configure.ac
* configure
Be consistent in prepending flags to existing LDFLAGS and CPPLFLAGS.
2018-02-25 Yavor Doganov <yavor@gnu.org>
* Tools/font_cacher.1: New file.
* Tools/GNUmakefile: Build font_cacher only if WITH_XFT=no.
Install the manpage conditionally.
* configure.ac: Add deprecation warning for art/xlib/xdps.
* configure: Regenerate.
2018-02-09 Yavor Doganov <yavor@gnu.org>
* Source/x11/XGServer.m (_initXContext): Call XInitThreads to
enable drawing in secondary threads.
2018-02-05 Yavor Doganov <yavor@gnu.org>
* Headers/xlib/GSXftFontInfo.h (GSXftFontInfo): Inherit from
the FCFontInfo class.
(GSXftFaceInfo, GSXftFontEnumerator): New classes inheriting from
FCFaceInfo and FCFontEnumerator.
* Source/xlib/GSXftFontInfo.m: Assume fontconfig is available;
remove HAVE_FC define and !HAVE_FC code.
(allFonts): Remove.
(FcFont, FcFontEnumerator): Remove implementations.
(GSXftFontEnumerator): Override +faceInfoClass and +fontWithName:.
(Ones, coveredCharacterSet): Remove, not needed anymore.
(advancementForGlyph:): Add support for glyph caching.
(setupAttributes): Obtain pattern from the GSXftFaceInfo
instance. Remove unnecessary code for setting ivars already set
by the superclass. Set lineHeight to capHeight.
* Source/xlib/XGContext.m (initializeBackend) [HAVE_XFT]: Remove
HAVE_FC conditional. Set fontEnumerator to GSXftFontEnumerator.
* Source/xlib/GNUmakefile (xlib_OBJC_FILES): Add fontconfig files
in the WITH_XFT conditional.
2018-01-21 Yavor Doganov <yavor@gnu.org>
* configure.ac: Add FREETYPE_LIBS to LIBS when building xlib.
* configure: Regenerate
2018-01-20 Yavor Doganov <yavor@gnu.org>
* configure.ac: Detect freetype with PKG_CHECK_MODULES.
* configure: Regenerate.
2018-01-03 Yavor Doganov <yavor@gnu.org>
* pkg.m4: Update to serial 12.
* configure.ac: Use PKG_PROG_PKG_CONFIG to detect pkg-config.
Remove all PKG_* shell variables.
* configure: Regenerate.
2018-01-01 Ivan Vucica <ivan@vucica.net>
* ANNOUNCE
@ -35,7 +777,7 @@
2017-07-17 Daniel Ferreira <dtf@stanford.edu>
* Source/opal/GNUmakefile: add OpalBridge.m to project.
* Source/opal/OpalBridge.m:
* Source/opal/OpalBridge.m:
Implement a bridge between NSColor and CGColorRef and a stub for a
bridge between NSImage and CGImageRef. This improves compatibility with
Quartz.
@ -44,7 +786,7 @@
* Headers/opal/OpalSurface.h
* Source/opal/OpalContext.m
* Source/opal/OpalSurface.m:
* Source/opal/OpalSurface.m:
In Quartz, the "graphics port" bound to an NSGraphicsContext (subclassed
by OpalContext) is a CGContext. We currently initialize one in
OpalSurface if it does not exist, however we do not allow the client to

View file

@ -1,10 +1,10 @@
@c -*- texinfo -*-
@chapter ANNOUNCE
@chapter Announcement
@ifset TEXT-ONLY
@include version.texi
@end ifset
This is version @value{GNUSTEP-BACK-VERSION} of the GNUstep GUI Backend
This is version @value{GNUSTEP-BACK-VERSION} of the GNUstep GUI Backend
(@samp{gnustep-back}).
@section What is the GNUstep GUI Backend?
@ -32,9 +32,10 @@ emulate the DPS functions required by the front-end system.
@ifset GNUSTEP-BACK-FTP-MACHINE
The gnustep-back-@value{GNUSTEP-BACK-VERSION}.tar.gz distribution
file has been placed at @url{ftp://@value{GNUSTEP-BACK-FTP-MACHINE}/@value{GNUSTEP-BACK-FTP-DIRECTORY}}.
@end ifset
It is accompanied by gnustep-back-@value{GNUSTEP-BACK-VERSION}.tar.gz.sig, a PGP signature which you can validate by putting both files in the same directory and using:
It is accompanied by gnustep-back-@value{GNUSTEP-BACK-VERSION}.tar.gz.sig, a
PGP signature which you can validate by putting both files in the same
directory and using:
@example
gpg --verify gnustep-back-@value{GNUSTEP-BACK-VERSION}.tar.gz.sig
@ -45,15 +46,18 @@ Signature has been created using the key with the following fingerprint:
@example
83AA E47C E829 A414 6EF8 3420 CA86 8D4C 9914 9679
@end example
@end ifset
Read the INSTALL file or the GNUstep-HOWTO for installation instructions.
@section Where do I send bug reports?
Bug reports can be sent to the GNUstep bug list
@email{bug-gnustep@@gnu.org}
Please log bug reports on the GNUstep project page
@url{http://savannah.gnu.org/bugs/?group=gnustep} or send
bug reports to @email{bug-gnustep@@gnu.org}.
@section Obtaining GNU Software
@section Obtaining GNUstep Software
Check out the GNUstep web site. (@url{http://www.gnustep.org/}) and the
GNU web site. (@url{http://www.gnu.org/})

View file

@ -7,6 +7,83 @@
@include version.texi
@end ifset
@section Noteworthy changes in version @samp{0.32.0}
The release includes mostly bug fixes.
@itemize @bullet
@item Make window termination saver.
@item Use default interpolation in Cairo.
@item Allow UTF-8 input from XLookupString.
@item Improve building on MS Windows.
@end itemize
@ifclear ANNOUNCE-ONLY
@section Noteworthy changes in version @samp{0.31.0}
The release includes mostly improvements for pasteboard handling and a few bug fixes.
@itemize @bullet
@item Improve font name creation.
@item Add headless backend.
@item Add CI pipeline.
@end itemize
@section Noteworthy changes in version @samp{0.30.0}
The release includes mostly improvements for the new Wayland backend and a few bug fixes.
@itemize @bullet
@item Improvements for the wayland backend.
@item Don't use font hinting for cauro, when using scaling.
@item Fix pasteboard transfer of huge data by deleting property on begin
and at every Notify.
@end itemize
@section Noteworthy changes in version @samp{0.29.0}
The release includes an alpha version of the wayland backend and a few
bug fixes.
@itemize @bullet
@item Alpha version of the wayland backend.
@item Improved focus handling for WindowMaker interaction.
@item Speed up for font pattern resolving.
@item Improved appicon behavior under WindowMaker.
@item Prevent appicon flickering on WindowMaker at application start.
@item On Windows, consistently use @code{GetWindowLongPtr} and
@code{SetWindowLongPtr} in place of @code{GetWindowLong} and
@code{SetWindowLong} for win32 and cairo for various win64 fixes.
@end itemize
@section Noteworthy changes in version @samp{0.28.0}
This release includes a few bugfixes and a huge rework of multi monitor handling.
@itemize @bullet
@item Improved focus handling for WindowMaker interaction.
@item Cursor improvements.
@item Better handling of fonts with fontconfig.
@item Simplify code that converts images for X11.
@item art: Remove ftfont-old.m.
@item Use Xrandr for multi monitor support.
@end itemize
@section Noteworthy changes in version @samp{0.27.0}
This release includes a few bugfixes.
@itemize @bullet
@item configure: Improve configuration.
@item xlib: Improve xft font classes.
@item x11: Enable drawing in secondary threads.
@item x11: Better handling of atoms. Method to get the window manager.
@item opal: Improve colour handling
@end itemize
@section Noteworthy changes in version @samp{0.26.2}
This release contains no changes since 0.26.1. It is released to coincide
@ -30,7 +107,6 @@ as a result of GSoC 2017 project.
@item misc: Fix reported static analyser warnings.
@end itemize
@ifclear ANNOUNCE-ONLY
@section Noteworthy changes in version @samp{0.25.1}
Small fixes and cleanups.

View file

@ -0,0 +1,54 @@
/*
WaylandCairoShmSurface.h
Copyright (C) 2020 Free Software Foundation, Inc.
Author: Sergio L. Pascual <slp@sinrega.org>
Date: February 2016
This file is part of GNUstep.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; see the file COPYING.LIB.
If not, see <http://www.gnu.org/licenses/> or write to the
Free Software Foundation, 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef WaylandCairoShmSurface_h
#define WaylandCairoShmSurface_h
#include "cairo/CairoSurface.h"
struct pool_buffer
{
int poolfd;
struct wl_shm_pool *pool;
struct wl_buffer *buffer;
cairo_surface_t *surface;
uint32_t width, height;
void *data;
size_t size;
bool busy;
};
struct pool_buffer *
createShmBuffer(int width, int height, struct wl_shm *shm);
@interface WaylandCairoShmSurface : CairoSurface
{
}
- (void)destroySurface;
@end
#endif

View file

@ -46,6 +46,7 @@
NSString *_familyName;
NSCharacterSet *_characterSet;
BOOL _hasNoCharacterSet;
BOOL _patternIsResolved;
}
- (id) initWithfamilyName: (NSString *)familyName
@ -63,6 +64,8 @@
- (NSString *) familyName;
- (void) setFamilyName: (NSString *)name;
- (NSString *) displayName;
- (void *) fontFace;
- (FcPattern *) matchedPattern;

View file

@ -0,0 +1,33 @@
/*
HeadlessContext.h
Copyright (C) 2003 Free Software Foundation, Inc.
This file is part of GNUstep.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; see the file COPYING.LIB.
If not, see <http://www.gnu.org/licenses/> or write to the
Free Software Foundation, 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef HeadlessContext_h
#define HeadlessContext_h
#include "gsc/GSContext.h"
@interface HeadlessContext : GSContext
@end
#endif /* HeadlessContext_h */

View file

@ -0,0 +1,42 @@
/*
HeadlessFaceInfo.h
Copyright (C) 2003, 2023 Free Software Foundation, Inc.
Based on work by: Banlu Kemiyatorn <object at gmail dot com>
Based on work by: Alexander Malmberg <alexander@malmberg.org>
Based on work by: Fred Kiefer <fredkiefer@gmx.de>
This file is part of GNUstep.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; see the file COPYING.LIB.
If not, see <http://www.gnu.org/licenses/> or write to the
Free Software Foundation, 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef HeadlessFaceInfo_h
#define HeadlessFaceInfo_h
#include <Foundation/NSObject.h>
@interface HeadlessFaceInfo : NSObject
{
void *_fontFace;
}
- (void *)fontFace;
@end
#endif /* HeadlessFaceInfo_h */

View file

@ -0,0 +1,41 @@
/*
HeadlessFontEnumeartorInfo.h
Copyright (C) 2003 Free Software Foundation, Inc.
Based on work by: Banlu Kemiyatorn <object at gmail dot com>
This file is part of GNUstep.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; see the file COPYING.LIB.
If not, see <http://www.gnu.org/licenses/> or write to the
Free Software Foundation, 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef HeadlessFontEnumerator_h
#define HeadlessFontEnumerator_h
#include <GNUstepGUI/GSFontInfo.h>
#include "headless/HeadlessFaceInfo.h"
@interface HeadlessFontEnumerator : GSFontEnumerator
{
}
+ (Class) faceInfoClass;
+ (HeadlessFaceInfo *) fontWithName: (NSString *)name;
@end
#endif /* HeadlessFontEnumerator_h */

View file

@ -0,0 +1,35 @@
/*
HeadlessFontInfo.h
Copyright (C) 2003 Free Software Foundation, Inc.
Based on work by: Banlu Kemiyatorn <object at gmail dot com>
This file is part of GNUstep.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; see the file COPYING.LIB.
If not, see <http://www.gnu.org/licenses/> or write to the
Free Software Foundation, 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef HeadlessFontInfo_h
#define HeadlessFontInfo_h
#include <GNUstepGUI/GSFontInfo.h>
@interface HeadlessFontInfo : GSFontInfo
@end
#endif /* HeadlessFontInfo_h */

View file

@ -0,0 +1,37 @@
/*
HeadlessGState.h
Copyright (C) 2004 Free Software Foundation, Inc.
Based on work by: Banlu Kemiyatorn <object at gmail dot com>
This file is part of GNUstep.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; see the file COPYING.LIB.
If not, see <http://www.gnu.org/licenses/> or write to the
Free Software Foundation, 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef HeadlessGState_h
#define HeadlessGState_h
#include "gsc/GSGState.h"
@interface HeadlessGState : GSGState
{
}
@end
#endif /* HeadlessGState_h */

View file

@ -0,0 +1,37 @@
/*
HeadlessServer.h
Copyright (C) 2002-2015 Free Software Foundation, Inc.
This file is part of GNUstep.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; see the file COPYING.LIB.
If not, see <http://www.gnu.org/licenses/> or write to the
Free Software Foundation, 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef HeadlessServer_h
#define HeadlessServer_h
#include "config.h"
#include <GNUstepGUI/GSDisplayServer.h>
@interface HeadlessServer : GSDisplayServer
{
}
@end
#endif /* HeadlessServer_h */

187
Headers/wayland/WaylandServer.h Executable file
View file

@ -0,0 +1,187 @@
/* <title>WaylandServer</title>
<abstract>Backend server using Wayland.</abstract>
Copyright (C) 2020 Free Software Foundation, Inc.
Author: Sergio L. Pascual <slp@sinrega.org>
Rewrite: Riccardo Canalicchio <riccardo.canalicchio(at)gmail.com>
Date: February 2016
This file is part of the GNUstep Backend.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; see the file COPYING.LIB.
If not, see <http://www.gnu.org/licenses/> or write to the
Free Software Foundation, 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef _WaylandServer_h_INCLUDE
#define _WaylandServer_h_INCLUDE
#include "config.h"
#include <GNUstepGUI/GSDisplayServer.h>
#include <wayland-client.h>
#include <wayland-cursor.h>
#include <cairo/cairo.h>
#include <xkbcommon/xkbcommon.h>
#include "cairo/CairoSurface.h"
#include "wayland/xdg-shell-client-protocol.h"
#include "wayland/wlr-layer-shell-client-protocol.h"
struct pointer
{
struct wl_pointer *wlpointer;
float x;
float y;
uint32_t last_click_button;
uint32_t last_click_time;
float last_click_x;
float last_click_y;
uint32_t button;
NSTimeInterval last_timestamp;
enum wl_pointer_button_state button_state;
uint32_t axis_source;
uint32_t serial;
struct window *focus;
struct window *captured;
};
struct cursor
{
struct wl_cursor *cursor;
struct wl_surface *surface;
struct wl_cursor_image *image;
struct wl_buffer *buffer;
};
typedef struct _WaylandConfig
{
struct wl_display *display;
struct wl_registry *registry;
struct wl_compositor *compositor;
struct wl_shell *shell;
struct wl_shm *shm;
struct wl_seat *seat;
struct wl_keyboard *keyboard;
struct xdg_wm_base *wm_base;
struct zwlr_layer_shell_v1 *layer_shell;
int seat_version;
struct wl_list output_list;
int output_count;
struct wl_list window_list;
int window_count;
int last_window_id;
// last event serial from pointer or keyboard
uint32_t event_serial;
// cursor
struct wl_cursor_theme *cursor_theme;
struct cursor *cursor;
struct wl_surface *cursor_surface;
// pointer
struct pointer pointer;
float mouse_scroll_multiplier;
// keyboard
struct xkb_context *xkb_context;
struct
{
struct xkb_keymap *keymap;
struct xkb_state *state;
xkb_mod_mask_t control_mask;
xkb_mod_mask_t alt_mask;
xkb_mod_mask_t shift_mask;
} xkb;
int modifiers;
} WaylandConfig;
struct output
{
WaylandConfig *wlconfig;
struct wl_output *output;
uint32_t server_output_id;
struct wl_list link;
int alloc_x;
int alloc_y;
int width;
int height;
int transform;
int scale;
char *make;
char *model;
void *user_data;
};
struct window
{
WaylandConfig *wlconfig;
id instance;
int window_id;
struct wl_list link;
BOOL configured; // surface has been configured once
BOOL buffer_needs_attach; // there is a new buffer avaialble for the surface
BOOL terminated;
BOOL moving;
BOOL resizing;
BOOL ignoreMouse;
float pos_x;
float pos_y;
float width;
float height;
float saved_pos_x;
float saved_pos_y;
int is_out;
int level;
struct wl_surface *surface;
struct xdg_surface *xdg_surface;
struct xdg_toplevel *toplevel;
struct xdg_popup *popup;
struct xdg_positioner *positioner;
struct zwlr_layer_surface_v1 *layer_surface;
struct output *output;
CairoSurface *wcs;
};
struct window *get_window_with_id(WaylandConfig *wlconfig, int winid);
@interface WaylandServer : GSDisplayServer
{
WaylandConfig *wlconfig;
BOOL _mouseInitialized;
}
@end
@interface
WaylandServer (Cursor)
- (void)initializeMouseIfRequired;
@end
#endif /* _WaylandServer_h_INCLUDE */

View file

@ -0,0 +1,597 @@
/* Generated by wayland-scanner 1.18.0 */
#ifndef WLR_LAYER_SHELL_UNSTABLE_V1_CLIENT_PROTOCOL_H
#define WLR_LAYER_SHELL_UNSTABLE_V1_CLIENT_PROTOCOL_H
#include <stdint.h>
#include <stddef.h>
#include "wayland-client.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @page page_wlr_layer_shell_unstable_v1 The wlr_layer_shell_unstable_v1 protocol
* @section page_ifaces_wlr_layer_shell_unstable_v1 Interfaces
* - @subpage page_iface_zwlr_layer_shell_v1 - create surfaces that are layers of the desktop
* - @subpage page_iface_zwlr_layer_surface_v1 - layer metadata interface
* @section page_copyright_wlr_layer_shell_unstable_v1 Copyright
* <pre>
*
* Copyright © 2017 Drew DeVault
*
* Permission to use, copy, modify, distribute, and sell this
* software and its documentation for any purpose is hereby granted
* without fee, provided that the above copyright notice appear in
* all copies and that both that copyright notice and this permission
* notice appear in supporting documentation, and that the name of
* the copyright holders not be used in advertising or publicity
* pertaining to distribution of the software without specific,
* written prior permission. The copyright holders make no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied
* warranty.
*
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
* THIS SOFTWARE.
* </pre>
*/
struct wl_output;
struct wl_surface;
struct xdg_popup;
struct zwlr_layer_shell_v1;
struct zwlr_layer_surface_v1;
/**
* @page page_iface_zwlr_layer_shell_v1 zwlr_layer_shell_v1
* @section page_iface_zwlr_layer_shell_v1_desc Description
*
* Clients can use this interface to assign the surface_layer role to
* wl_surfaces. Such surfaces are assigned to a "layer" of the output and
* rendered with a defined z-depth respective to each other. They may also be
* anchored to the edges and corners of a screen and specify input handling
* semantics. This interface should be suitable for the implementation of
* many desktop shell components, and a broad number of other applications
* that interact with the desktop.
* @section page_iface_zwlr_layer_shell_v1_api API
* See @ref iface_zwlr_layer_shell_v1.
*/
/**
* @defgroup iface_zwlr_layer_shell_v1 The zwlr_layer_shell_v1 interface
*
* Clients can use this interface to assign the surface_layer role to
* wl_surfaces. Such surfaces are assigned to a "layer" of the output and
* rendered with a defined z-depth respective to each other. They may also be
* anchored to the edges and corners of a screen and specify input handling
* semantics. This interface should be suitable for the implementation of
* many desktop shell components, and a broad number of other applications
* that interact with the desktop.
*/
extern const struct wl_interface zwlr_layer_shell_v1_interface;
/**
* @page page_iface_zwlr_layer_surface_v1 zwlr_layer_surface_v1
* @section page_iface_zwlr_layer_surface_v1_desc Description
*
* An interface that may be implemented by a wl_surface, for surfaces that
* are designed to be rendered as a layer of a stacked desktop-like
* environment.
*
* Layer surface state (layer, size, anchor, exclusive zone,
* margin, interactivity) is double-buffered, and will be applied at the
* time wl_surface.commit of the corresponding wl_surface is called.
* @section page_iface_zwlr_layer_surface_v1_api API
* See @ref iface_zwlr_layer_surface_v1.
*/
/**
* @defgroup iface_zwlr_layer_surface_v1 The zwlr_layer_surface_v1 interface
*
* An interface that may be implemented by a wl_surface, for surfaces that
* are designed to be rendered as a layer of a stacked desktop-like
* environment.
*
* Layer surface state (layer, size, anchor, exclusive zone,
* margin, interactivity) is double-buffered, and will be applied at the
* time wl_surface.commit of the corresponding wl_surface is called.
*/
extern const struct wl_interface zwlr_layer_surface_v1_interface;
#ifndef ZWLR_LAYER_SHELL_V1_ERROR_ENUM
#define ZWLR_LAYER_SHELL_V1_ERROR_ENUM
enum zwlr_layer_shell_v1_error {
/**
* wl_surface has another role
*/
ZWLR_LAYER_SHELL_V1_ERROR_ROLE = 0,
/**
* layer value is invalid
*/
ZWLR_LAYER_SHELL_V1_ERROR_INVALID_LAYER = 1,
/**
* wl_surface has a buffer attached or committed
*/
ZWLR_LAYER_SHELL_V1_ERROR_ALREADY_CONSTRUCTED = 2,
};
#endif /* ZWLR_LAYER_SHELL_V1_ERROR_ENUM */
#ifndef ZWLR_LAYER_SHELL_V1_LAYER_ENUM
#define ZWLR_LAYER_SHELL_V1_LAYER_ENUM
/**
* @ingroup iface_zwlr_layer_shell_v1
* available layers for surfaces
*
* These values indicate which layers a surface can be rendered in. They
* are ordered by z depth, bottom-most first. Traditional shell surfaces
* will typically be rendered between the bottom and top layers.
* Fullscreen shell surfaces are typically rendered at the top layer.
* Multiple surfaces can share a single layer, and ordering within a
* single layer is undefined.
*/
enum zwlr_layer_shell_v1_layer {
ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND = 0,
ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM = 1,
ZWLR_LAYER_SHELL_V1_LAYER_TOP = 2,
ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY = 3,
};
#endif /* ZWLR_LAYER_SHELL_V1_LAYER_ENUM */
#define ZWLR_LAYER_SHELL_V1_GET_LAYER_SURFACE 0
#define ZWLR_LAYER_SHELL_V1_DESTROY 1
/**
* @ingroup iface_zwlr_layer_shell_v1
*/
#define ZWLR_LAYER_SHELL_V1_GET_LAYER_SURFACE_SINCE_VERSION 1
/**
* @ingroup iface_zwlr_layer_shell_v1
*/
#define ZWLR_LAYER_SHELL_V1_DESTROY_SINCE_VERSION 3
/** @ingroup iface_zwlr_layer_shell_v1 */
static inline void
zwlr_layer_shell_v1_set_user_data(struct zwlr_layer_shell_v1 *zwlr_layer_shell_v1, void *user_data)
{
wl_proxy_set_user_data((struct wl_proxy *) zwlr_layer_shell_v1, user_data);
}
/** @ingroup iface_zwlr_layer_shell_v1 */
static inline void *
zwlr_layer_shell_v1_get_user_data(struct zwlr_layer_shell_v1 *zwlr_layer_shell_v1)
{
return wl_proxy_get_user_data((struct wl_proxy *) zwlr_layer_shell_v1);
}
static inline uint32_t
zwlr_layer_shell_v1_get_version(struct zwlr_layer_shell_v1 *zwlr_layer_shell_v1)
{
return wl_proxy_get_version((struct wl_proxy *) zwlr_layer_shell_v1);
}
/**
* @ingroup iface_zwlr_layer_shell_v1
*
* Create a layer surface for an existing surface. This assigns the role of
* layer_surface, or raises a protocol error if another role is already
* assigned.
*
* Creating a layer surface from a wl_surface which has a buffer attached
* or committed is a client error, and any attempts by a client to attach
* or manipulate a buffer prior to the first layer_surface.configure call
* must also be treated as errors.
*
* You may pass NULL for output to allow the compositor to decide which
* output to use. Generally this will be the one that the user most
* recently interacted with.
*
* Clients can specify a namespace that defines the purpose of the layer
* surface.
*/
static inline struct zwlr_layer_surface_v1 *
zwlr_layer_shell_v1_get_layer_surface(struct zwlr_layer_shell_v1 *zwlr_layer_shell_v1, struct wl_surface *surface, struct wl_output *output, uint32_t layer, const char *namespace)
{
struct wl_proxy *id;
id = wl_proxy_marshal_constructor((struct wl_proxy *) zwlr_layer_shell_v1,
ZWLR_LAYER_SHELL_V1_GET_LAYER_SURFACE, &zwlr_layer_surface_v1_interface, NULL, surface, output, layer, namespace);
return (struct zwlr_layer_surface_v1 *) id;
}
/**
* @ingroup iface_zwlr_layer_shell_v1
*
* This request indicates that the client will not use the layer_shell
* object any more. Objects that have been created through this instance
* are not affected.
*/
static inline void
zwlr_layer_shell_v1_destroy(struct zwlr_layer_shell_v1 *zwlr_layer_shell_v1)
{
wl_proxy_marshal((struct wl_proxy *) zwlr_layer_shell_v1,
ZWLR_LAYER_SHELL_V1_DESTROY);
wl_proxy_destroy((struct wl_proxy *) zwlr_layer_shell_v1);
}
#ifndef ZWLR_LAYER_SURFACE_V1_ERROR_ENUM
#define ZWLR_LAYER_SURFACE_V1_ERROR_ENUM
enum zwlr_layer_surface_v1_error {
/**
* provided surface state is invalid
*/
ZWLR_LAYER_SURFACE_V1_ERROR_INVALID_SURFACE_STATE = 0,
/**
* size is invalid
*/
ZWLR_LAYER_SURFACE_V1_ERROR_INVALID_SIZE = 1,
/**
* anchor bitfield is invalid
*/
ZWLR_LAYER_SURFACE_V1_ERROR_INVALID_ANCHOR = 2,
};
#endif /* ZWLR_LAYER_SURFACE_V1_ERROR_ENUM */
#ifndef ZWLR_LAYER_SURFACE_V1_ANCHOR_ENUM
#define ZWLR_LAYER_SURFACE_V1_ANCHOR_ENUM
enum zwlr_layer_surface_v1_anchor {
/**
* the top edge of the anchor rectangle
*/
ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP = 1,
/**
* the bottom edge of the anchor rectangle
*/
ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM = 2,
/**
* the left edge of the anchor rectangle
*/
ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT = 4,
/**
* the right edge of the anchor rectangle
*/
ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT = 8,
};
#endif /* ZWLR_LAYER_SURFACE_V1_ANCHOR_ENUM */
/**
* @ingroup iface_zwlr_layer_surface_v1
* @struct zwlr_layer_surface_v1_listener
*/
struct zwlr_layer_surface_v1_listener {
/**
* suggest a surface change
*
* The configure event asks the client to resize its surface.
*
* Clients should arrange their surface for the new states, and
* then send an ack_configure request with the serial sent in this
* configure event at some point before committing the new surface.
*
* The client is free to dismiss all but the last configure event
* it received.
*
* The width and height arguments specify the size of the window in
* surface-local coordinates.
*
* The size is a hint, in the sense that the client is free to
* ignore it if it doesn't resize, pick a smaller size (to satisfy
* aspect ratio or resize in steps of NxM pixels). If the client
* picks a smaller size and is anchored to two opposite anchors
* (e.g. 'top' and 'bottom'), the surface will be centered on this
* axis.
*
* If the width or height arguments are zero, it means the client
* should decide its own window dimension.
*/
void (*configure)(void *data,
struct zwlr_layer_surface_v1 *zwlr_layer_surface_v1,
uint32_t serial,
uint32_t width,
uint32_t height);
/**
* surface should be closed
*
* The closed event is sent by the compositor when the surface
* will no longer be shown. The output may have been destroyed or
* the user may have asked for it to be removed. Further changes to
* the surface will be ignored. The client should destroy the
* resource after receiving this event, and create a new surface if
* they so choose.
*/
void (*closed)(void *data,
struct zwlr_layer_surface_v1 *zwlr_layer_surface_v1);
};
/**
* @ingroup iface_zwlr_layer_surface_v1
*/
static inline int
zwlr_layer_surface_v1_add_listener(struct zwlr_layer_surface_v1 *zwlr_layer_surface_v1,
const struct zwlr_layer_surface_v1_listener *listener, void *data)
{
return wl_proxy_add_listener((struct wl_proxy *) zwlr_layer_surface_v1,
(void (**)(void)) listener, data);
}
#define ZWLR_LAYER_SURFACE_V1_SET_SIZE 0
#define ZWLR_LAYER_SURFACE_V1_SET_ANCHOR 1
#define ZWLR_LAYER_SURFACE_V1_SET_EXCLUSIVE_ZONE 2
#define ZWLR_LAYER_SURFACE_V1_SET_MARGIN 3
#define ZWLR_LAYER_SURFACE_V1_SET_KEYBOARD_INTERACTIVITY 4
#define ZWLR_LAYER_SURFACE_V1_GET_POPUP 5
#define ZWLR_LAYER_SURFACE_V1_ACK_CONFIGURE 6
#define ZWLR_LAYER_SURFACE_V1_DESTROY 7
#define ZWLR_LAYER_SURFACE_V1_SET_LAYER 8
/**
* @ingroup iface_zwlr_layer_surface_v1
*/
#define ZWLR_LAYER_SURFACE_V1_CONFIGURE_SINCE_VERSION 1
/**
* @ingroup iface_zwlr_layer_surface_v1
*/
#define ZWLR_LAYER_SURFACE_V1_CLOSED_SINCE_VERSION 1
/**
* @ingroup iface_zwlr_layer_surface_v1
*/
#define ZWLR_LAYER_SURFACE_V1_SET_SIZE_SINCE_VERSION 1
/**
* @ingroup iface_zwlr_layer_surface_v1
*/
#define ZWLR_LAYER_SURFACE_V1_SET_ANCHOR_SINCE_VERSION 1
/**
* @ingroup iface_zwlr_layer_surface_v1
*/
#define ZWLR_LAYER_SURFACE_V1_SET_EXCLUSIVE_ZONE_SINCE_VERSION 1
/**
* @ingroup iface_zwlr_layer_surface_v1
*/
#define ZWLR_LAYER_SURFACE_V1_SET_MARGIN_SINCE_VERSION 1
/**
* @ingroup iface_zwlr_layer_surface_v1
*/
#define ZWLR_LAYER_SURFACE_V1_SET_KEYBOARD_INTERACTIVITY_SINCE_VERSION 1
/**
* @ingroup iface_zwlr_layer_surface_v1
*/
#define ZWLR_LAYER_SURFACE_V1_GET_POPUP_SINCE_VERSION 1
/**
* @ingroup iface_zwlr_layer_surface_v1
*/
#define ZWLR_LAYER_SURFACE_V1_ACK_CONFIGURE_SINCE_VERSION 1
/**
* @ingroup iface_zwlr_layer_surface_v1
*/
#define ZWLR_LAYER_SURFACE_V1_DESTROY_SINCE_VERSION 1
/**
* @ingroup iface_zwlr_layer_surface_v1
*/
#define ZWLR_LAYER_SURFACE_V1_SET_LAYER_SINCE_VERSION 2
/** @ingroup iface_zwlr_layer_surface_v1 */
static inline void
zwlr_layer_surface_v1_set_user_data(struct zwlr_layer_surface_v1 *zwlr_layer_surface_v1, void *user_data)
{
wl_proxy_set_user_data((struct wl_proxy *) zwlr_layer_surface_v1, user_data);
}
/** @ingroup iface_zwlr_layer_surface_v1 */
static inline void *
zwlr_layer_surface_v1_get_user_data(struct zwlr_layer_surface_v1 *zwlr_layer_surface_v1)
{
return wl_proxy_get_user_data((struct wl_proxy *) zwlr_layer_surface_v1);
}
static inline uint32_t
zwlr_layer_surface_v1_get_version(struct zwlr_layer_surface_v1 *zwlr_layer_surface_v1)
{
return wl_proxy_get_version((struct wl_proxy *) zwlr_layer_surface_v1);
}
/**
* @ingroup iface_zwlr_layer_surface_v1
*
* Sets the size of the surface in surface-local coordinates. The
* compositor will display the surface centered with respect to its
* anchors.
*
* If you pass 0 for either value, the compositor will assign it and
* inform you of the assignment in the configure event. You must set your
* anchor to opposite edges in the dimensions you omit; not doing so is a
* protocol error. Both values are 0 by default.
*
* Size is double-buffered, see wl_surface.commit.
*/
static inline void
zwlr_layer_surface_v1_set_size(struct zwlr_layer_surface_v1 *zwlr_layer_surface_v1, uint32_t width, uint32_t height)
{
wl_proxy_marshal((struct wl_proxy *) zwlr_layer_surface_v1,
ZWLR_LAYER_SURFACE_V1_SET_SIZE, width, height);
}
/**
* @ingroup iface_zwlr_layer_surface_v1
*
* Requests that the compositor anchor the surface to the specified edges
* and corners. If two orthogonal edges are specified (e.g. 'top' and
* 'left'), then the anchor point will be the intersection of the edges
* (e.g. the top left corner of the output); otherwise the anchor point
* will be centered on that edge, or in the center if none is specified.
*
* Anchor is double-buffered, see wl_surface.commit.
*/
static inline void
zwlr_layer_surface_v1_set_anchor(struct zwlr_layer_surface_v1 *zwlr_layer_surface_v1, uint32_t anchor)
{
wl_proxy_marshal((struct wl_proxy *) zwlr_layer_surface_v1,
ZWLR_LAYER_SURFACE_V1_SET_ANCHOR, anchor);
}
/**
* @ingroup iface_zwlr_layer_surface_v1
*
* Requests that the compositor avoids occluding an area with other
* surfaces. The compositor's use of this information is
* implementation-dependent - do not assume that this region will not
* actually be occluded.
*
* A positive value is only meaningful if the surface is anchored to one
* edge or an edge and both perpendicular edges. If the surface is not
* anchored, anchored to only two perpendicular edges (a corner), anchored
* to only two parallel edges or anchored to all edges, a positive value
* will be treated the same as zero.
*
* A positive zone is the distance from the edge in surface-local
* coordinates to consider exclusive.
*
* Surfaces that do not wish to have an exclusive zone may instead specify
* how they should interact with surfaces that do. If set to zero, the
* surface indicates that it would like to be moved to avoid occluding
* surfaces with a positive exclusive zone. If set to -1, the surface
* indicates that it would not like to be moved to accommodate for other
* surfaces, and the compositor should extend it all the way to the edges
* it is anchored to.
*
* For example, a panel might set its exclusive zone to 10, so that
* maximized shell surfaces are not shown on top of it. A notification
* might set its exclusive zone to 0, so that it is moved to avoid
* occluding the panel, but shell surfaces are shown underneath it. A
* wallpaper or lock screen might set their exclusive zone to -1, so that
* they stretch below or over the panel.
*
* The default value is 0.
*
* Exclusive zone is double-buffered, see wl_surface.commit.
*/
static inline void
zwlr_layer_surface_v1_set_exclusive_zone(struct zwlr_layer_surface_v1 *zwlr_layer_surface_v1, int32_t zone)
{
wl_proxy_marshal((struct wl_proxy *) zwlr_layer_surface_v1,
ZWLR_LAYER_SURFACE_V1_SET_EXCLUSIVE_ZONE, zone);
}
/**
* @ingroup iface_zwlr_layer_surface_v1
*
* Requests that the surface be placed some distance away from the anchor
* point on the output, in surface-local coordinates. Setting this value
* for edges you are not anchored to has no effect.
*
* The exclusive zone includes the margin.
*
* Margin is double-buffered, see wl_surface.commit.
*/
static inline void
zwlr_layer_surface_v1_set_margin(struct zwlr_layer_surface_v1 *zwlr_layer_surface_v1, int32_t top, int32_t right, int32_t bottom, int32_t left)
{
wl_proxy_marshal((struct wl_proxy *) zwlr_layer_surface_v1,
ZWLR_LAYER_SURFACE_V1_SET_MARGIN, top, right, bottom, left);
}
/**
* @ingroup iface_zwlr_layer_surface_v1
*
* Set to 1 to request that the seat send keyboard events to this layer
* surface. For layers below the shell surface layer, the seat will use
* normal focus semantics. For layers above the shell surface layers, the
* seat will always give exclusive keyboard focus to the top-most layer
* which has keyboard interactivity set to true.
*
* Layer surfaces receive pointer, touch, and tablet events normally. If
* you do not want to receive them, set the input region on your surface
* to an empty region.
*
* Events is double-buffered, see wl_surface.commit.
*/
static inline void
zwlr_layer_surface_v1_set_keyboard_interactivity(struct zwlr_layer_surface_v1 *zwlr_layer_surface_v1, uint32_t keyboard_interactivity)
{
wl_proxy_marshal((struct wl_proxy *) zwlr_layer_surface_v1,
ZWLR_LAYER_SURFACE_V1_SET_KEYBOARD_INTERACTIVITY, keyboard_interactivity);
}
/**
* @ingroup iface_zwlr_layer_surface_v1
*
* This assigns an xdg_popup's parent to this layer_surface. This popup
* should have been created via xdg_surface::get_popup with the parent set
* to NULL, and this request must be invoked before committing the popup's
* initial state.
*
* See the documentation of xdg_popup for more details about what an
* xdg_popup is and how it is used.
*/
static inline void
zwlr_layer_surface_v1_get_popup(struct zwlr_layer_surface_v1 *zwlr_layer_surface_v1, struct xdg_popup *popup)
{
wl_proxy_marshal((struct wl_proxy *) zwlr_layer_surface_v1,
ZWLR_LAYER_SURFACE_V1_GET_POPUP, popup);
}
/**
* @ingroup iface_zwlr_layer_surface_v1
*
* When a configure event is received, if a client commits the
* surface in response to the configure event, then the client
* must make an ack_configure request sometime before the commit
* request, passing along the serial of the configure event.
*
* If the client receives multiple configure events before it
* can respond to one, it only has to ack the last configure event.
*
* A client is not required to commit immediately after sending
* an ack_configure request - it may even ack_configure several times
* before its next surface commit.
*
* A client may send multiple ack_configure requests before committing, but
* only the last request sent before a commit indicates which configure
* event the client really is responding to.
*/
static inline void
zwlr_layer_surface_v1_ack_configure(struct zwlr_layer_surface_v1 *zwlr_layer_surface_v1, uint32_t serial)
{
wl_proxy_marshal((struct wl_proxy *) zwlr_layer_surface_v1,
ZWLR_LAYER_SURFACE_V1_ACK_CONFIGURE, serial);
}
/**
* @ingroup iface_zwlr_layer_surface_v1
*
* This request destroys the layer surface.
*/
static inline void
zwlr_layer_surface_v1_destroy(struct zwlr_layer_surface_v1 *zwlr_layer_surface_v1)
{
wl_proxy_marshal((struct wl_proxy *) zwlr_layer_surface_v1,
ZWLR_LAYER_SURFACE_V1_DESTROY);
wl_proxy_destroy((struct wl_proxy *) zwlr_layer_surface_v1);
}
/**
* @ingroup iface_zwlr_layer_surface_v1
*
* Change the layer that the surface is rendered on.
*
* Layer is double-buffered, see wl_surface.commit.
*/
static inline void
zwlr_layer_surface_v1_set_layer(struct zwlr_layer_surface_v1 *zwlr_layer_surface_v1, uint32_t layer)
{
wl_proxy_marshal((struct wl_proxy *) zwlr_layer_surface_v1,
ZWLR_LAYER_SURFACE_V1_SET_LAYER, layer);
}
#ifdef __cplusplus
}
#endif
#endif

File diff suppressed because it is too large Load diff

View file

@ -34,45 +34,159 @@ typedef enum {
XGWM_UNKNOWN = 0,
XGWM_WINDOWMAKER = 1,
XGWM_GNOME = 2,
XGWM_KDE = 4,
XGWM_EWMH = 8
} XGWMProtocols;
typedef struct {
Atom win_type_atom;
Atom win_desktop_atom;
Atom win_normal_atom;
Atom win_floating_atom;
Atom win_menu_atom;
Atom win_dock_atom;
Atom win_modal_atom;
Atom win_utility_atom;
Atom win_splash_atom;
Atom win_override_atom;
Atom _dummy1;
Atom win_popup_menu_atom;
Atom win_dropdown_menu_atom;
Atom win_tooltip_atom;
Atom win_notification_atom;
Atom win_combo_atom;
Atom win_dnd_atom;
} XGWMWinTypes;
static char *atom_names[] = {
"TEXT",
"UTF8_STRING",
"WM_PROTOCOLS",
"WM_TAKE_FOCUS",
"WM_DELETE_WINDOW",
"WM_STATE",
"_NET_WM_PING",
"_NET_WM_SYNC_REQUEST",
"_NET_WM_SYNC_REQUEST_COUNTER",
"_NET_WM_WINDOW_TYPE",
"_NET_WM_WINDOW_TYPE_DESKTOP",
"_NET_WM_WINDOW_TYPE_DOCK",
"_NET_WM_WINDOW_TYPE_TOOLBAR",
"_NET_WM_WINDOW_TYPE_MENU",
"_NET_WM_WINDOW_TYPE_DIALOG",
"_NET_WM_WINDOW_TYPE_NORMAL",
// New in wmspec 1.2
"_NET_WM_WINDOW_TYPE_UTILITY",
"_NET_WM_WINDOW_TYPE_SPLASH",
// New in wmspec 1.4
"_NET_WM_WINDOW_TYPE_POPUP_MENU",
"_NET_WM_WINDOW_TYPE_DROPDOWN_MENU",
"_NET_WM_WINDOW_TYPE_TOOLTIP",
"_NET_WM_WINDOW_TYPE_NOTIFICATION",
"_NET_WM_WINDOW_TYPE_COMBO",
"_NET_WM_WINDOW_TYPE_DND",
//KDE extensions
"_KDE_NET_WM_WINDOW_TYPE_OVERRIDE",
// Window state
"_NET_WM_STATE",
"_NET_WM_STATE_MODAL",
"_NET_WM_STATE_STICKY",
"_NET_WM_STATE_MAXIMIZED_VERT",
"_NET_WM_STATE_MAXIMIZED_HORZ",
"_NET_WM_STATE_SHADED",
"_NET_WM_STATE_SKIP_TASKBAR",
"_NET_WM_STATE_SKIP_PAGER",
"_NET_WM_STATE_HIDDEN",
"_NET_WM_STATE_FULLSCREEN",
"_NET_WM_STATE_ABOVE",
"_NET_WM_STATE_BELOW",
"_NET_WM_STATE_DEMANDS_ATTENTION",
"_NET_WM_NAME",
"_NET_WM_PID",
"_NET_WM_ICON",
"_NET_WM_ICON_NAME",
"_NET_WM_DESKTOP",
"_NET_WM_WINDOW_SHADOW",
"_NET_WM_USER_TIME",
"_NET_WM_WINDOW_OPACITY",
"_MOTIF_WM_HINTS",
"_NET_SUPPORTED",
"_NET_FRAME_EXTENTS",
"_NET_REQUEST_FRAME_EXTENTS",
"_KDE_NET_WM_FRAME_STRUT",
"_WIN_SUPPORTING_WM_CHECK",
"_NET_SUPPORTING_WM_CHECK",
"_NET_DESKTOP_NAMES",
"_NET_CURRENT_DESKTOP",
"_NET_NUMBER_OF_DESKTOPS",
"_NET_CLIENT_LIST_STACKING",
"_NET_ACTIVE_WINDOW",
"_WIN_LAYER",
"_WINDOWMAKER_WM_PROTOCOLS",
"_WINDOWMAKER_NOTICEBOARD",
"_WINDOWMAKER_ICON_TILE",
"_WINDOWMAKER_WM_FUNCTION",
"_RGBA_IMAGE",
"_GNUSTEP_WM_MINIATURIZE_WINDOW",
"_GNUSTEP_WM_HIDE_APP",
"_GNUSTEP_WM_ATTR",
"_GNUSTEP_TITLEBAR_STATE",
"_GNUSTEP_FRAME_OFFSETS",
"WM_IGNORE_FOCUS_EVENTS"
};
typedef struct {
Atom net_wm_state_atom;
Atom net_wm_state_modal_atom;
Atom net_wm_state_sticky_atom;
Atom net_wm_state_maximized_vert_atom;
Atom net_wm_state_maximized_horz_atom;
Atom net_wm_state_shaded_atom;
Atom net_wm_state_skip_taskbar_atom;
Atom net_wm_state_skip_pager_atom;
Atom net_wm_state_hidden_atom;
Atom net_wm_state_fullscreen_atom;
Atom net_wm_state_above_atom;
Atom net_wm_state_below_atom;
Atom net_wm_state_demands_attention_atom;
} XGWMNetStates;
/*
* Macros to access elements in atom_names array.
*/
#define TEXT_ATOM atoms[0]
#define UTF8_STRING_ATOM atoms[1]
#define WM_PROTOCOLS_ATOM atoms[2]
#define WM_TAKE_FOCUS_ATOM atoms[3]
#define WM_DELETE_WINDOW_ATOM atoms[4]
#define WM_STATE_ATOM atoms[5]
#define _NET_WM_PING_ATOM atoms[6]
#define _NET_WM_SYNC_REQUEST_ATOM atoms[7]
#define _NET_WM_SYNC_REQUEST_COUNTER_ATOM atoms[8]
#define _NET_WM_WINDOW_TYPE_ATOM atoms[9]
#define _NET_WM_WINDOW_TYPE_DESKTOP_ATOM atoms[10]
#define _NET_WM_WINDOW_TYPE_DOCK_ATOM atoms[11]
#define _NET_WM_WINDOW_TYPE_TOOLBAR_ATOM atoms[12]
#define _NET_WM_WINDOW_TYPE_MENU_ATOM atoms[13]
#define _NET_WM_WINDOW_TYPE_DIALOG_ATOM atoms[14]
#define _NET_WM_WINDOW_TYPE_NORMAL_ATOM atoms[15]
#define _NET_WM_WINDOW_TYPE_UTILITY_ATOM atoms[16]
#define _NET_WM_WINDOW_TYPE_SPLASH_ATOM atoms[17]
#define _NET_WM_WINDOW_TYPE_POPUP_MENU_ATOM atoms[18]
#define _NET_WM_WINDOW_TYPE_DROPDOWN_MENU_ATOM atoms[19]
#define _NET_WM_WINDOW_TYPE_TOOLTIP_ATOM atoms[20]
#define _NET_WM_WINDOW_TYPE_NOTIFICATION_ATOM atoms[21]
#define _NET_WM_WINDOW_TYPE_COMBO_ATOM atoms[22]
#define _NET_WM_WINDOW_TYPE_DND_ATOM atoms[23]
#define _KDE_NET_WM_WINDOW_TYPE_OVERRIDE_ATOM atoms[24]
#define _NET_WM_STATE_ATOM atoms[25]
#define _NET_WM_STATE_MODAL_ATOM atoms[26]
#define _NET_WM_STATE_STICKY_ATOM atoms[27]
#define _NET_WM_STATE_MAXIMIZED_VERT_ATOM atoms[28]
#define _NET_WM_STATE_MAXIMIZED_HORZ_ATOM atoms[29]
#define _NET_WM_STATE_SHADED_ATOM atoms[30]
#define _NET_WM_STATE_SKIP_TASKBAR_ATOM atoms[31]
#define _NET_WM_STATE_SKIP_PAGER_ATOM atoms[32]
#define _NET_WM_STATE_HIDDEN_ATOM atoms[33]
#define _NET_WM_STATE_FULLSCREEN_ATOM atoms[34]
#define _NET_WM_STATE_ABOVE_ATOM atoms[35]
#define _NET_WM_STATE_BELOW_ATOM atoms[36]
#define _NET_WM_STATE_DEMANDS_ATTENTION_ATOM atoms[37]
#define _NET_WM_NAME_ATOM atoms[38]
#define _NET_WM_PID_ATOM atoms[39]
#define _NET_WM_ICON_ATOM atoms[40]
#define _NET_WM_ICON_NAME_ATOM atoms[41]
#define _NET_WM_DESKTOP_ATOM atoms[42]
#define _NET_WM_WINDOW_SHADOW_ATOM atoms[43]
#define _NET_WM_USER_TIME_ATOM atoms[44]
#define _NET_WM_WINDOW_OPACITY_ATOM atoms[45]
#define _MOTIF_WM_HINTS_ATOM atoms[46]
#define _NET_SUPPORTED_ATOM atoms[47]
#define _NET_FRAME_EXTENTS_ATOM atoms[48]
#define _NET_REQUEST_FRAME_EXTENTS_ATOM atoms[49]
#define _KDE_NET_WM_FRAME_STRUT_ATOM atoms[50]
#define _WIN_SUPPORTING_WM_CHECK_ATOM atoms[51]
#define _NET_SUPPORTING_WM_CHECK_ATOM atoms[52]
#define _NET_DESKTOP_NAMES_ATOM atoms[53]
#define _NET_CURRENT_DESKTOP_ATOM atoms[54]
#define _NET_NUMBER_OF_DESKTOPS_ATOM atoms[55]
#define _NET_CLIENT_LIST_STACKING_ATOM atoms[56]
#define _NET_ACTIVE_WINDOW_ATOM atoms[57]
#define _WIN_LAYER_ATOM atoms[58]
#define _WINDOWMAKER_WM_PROTOCOLS_ATOM atoms[59]
#define _WINDOWMAKER_NOTICEBOARD_ATOM atoms[60]
#define _WINDOWMAKER_ICON_TILE_ATOM atoms[61]
#define _WINDOWMAKER_WM_FUNCTION_ATOM atoms[62]
#define _RGBA_IMAGE_ATOM atoms[63]
#define _GNUSTEP_WM_MINIATURIZE_WINDOW_ATOM atoms[64]
#define _GNUSTEP_WM_HIDE_APP_ATOM atoms[65]
#define _GNUSTEP_WM_ATTR_ATOM atoms[66]
#define _GNUSTEP_TITLEBAR_STATE_ATOM atoms[67]
#define _GNUSTEP_FRAME_OFFSETS_ATOM atoms[68]
#define WM_IGNORE_FOCUS_EVENTS_ATOM atoms[69]
/*
* Frame offsets for window inside parent decoration window.
@ -108,16 +222,7 @@ struct XGGeneric {
int lastClickX;
int lastClickY;
Time lastMotion;
Atom protocols_atom;
Atom delete_win_atom;
Atom take_focus_atom;
Atom wm_state_atom;
Atom net_wm_ping_atom;
Atom net_wm_sync_request_atom;
Atom net_wm_sync_request_counter_atom;
Atom miniaturize_atom;
Atom win_decor_atom;
Atom titlebar_state_atom;
// Name for application root window.
char *rootName;
long currentFocusWindow;
long desiredFocusWindow;
@ -135,8 +240,7 @@ struct XGGeneric {
Window appRootWindow;
void *cachedWindow; // last gswindow_device_t used.
Offsets offsets[16];
XGWMWinTypes wintypes;
XGWMNetStates netstates;
Atom atoms[sizeof(atom_names)/sizeof(char*)];
};
/* GNOME Window layers */

View file

@ -52,29 +52,42 @@ typedef enum {
XGDM_PORTABLE
} XGDrawMechanism;
typedef struct MonitorDevice {
int screen_id;
NSWindowDepth depth;
NSSize resolution;
NSRect frame;
} MonitorDevice;
@interface XGServer : GSDisplayServer
{
Display *dpy;
int defScreen;
NSSize xScreenSize;
NSMapTable *screenList;
Window grabWindow;
struct XGGeneric generic;
id inputServer;
int randrEventBase;
int randrErrorBase;
MonitorDevice *monitors;
unsigned monitorsCount;
}
+ (Display*) currentXDisplay;
- (Display*) xDisplay;
+ (Display *) xDisplay;
- (Display *) xDisplay;
- (Window) xDisplayRootWindow;
- (Window) xAppRootWindow;
- (NSSize) xScreenSize;
- (void *) xrContextForScreen: (int)screen_number;
- (Visual *) visualForScreen: (int)screen_number;
- (int) depthForScreen: (int)screen_number;
- (void *) screenRContext;
- (Visual *) screenVisual;
- (int) screenDepth;
- (XGDrawMechanism) screenDrawMechanism;
- (XGDrawMechanism) drawMechanismForScreen: (int)screen_number;
- (void) getForScreen: (int)screen_number pixelFormat: (int *)bpp_number
masks: (int *)red_mask : (int *)green_mask : (int *)blue_mask;
- (Window) xDisplayRootWindowForScreen: (int)screen_number;
- (XColor) xColorFromColor: (XColor)color forScreen: (int)screen_number;
- (XColor) xColorFromColor: (XColor)color;
+ (void) waitAllContexts;
@end
@ -92,6 +105,8 @@ typedef enum {
- (NSRect) _OSFrameToXHints: (NSRect)o for: (void*)window;
- (NSRect) _XFrameToOSFrame: (NSRect)x for: (void*)window;
- (NSRect) _XFrameToXHints: (NSRect)o for: (void*)window;
- (NSString *) windowManagerName;
@end
// Public interface for the input methods.

View file

@ -72,7 +72,7 @@ typedef struct {
#define WMFHideOtherApplications 10
#define WMFHideApplication 12
#define GSMaxWMProtocols 5
#define GSMaxWMProtocols 6
/* Graphics Driver protocol. Setup in [NSGraphicsContext-contextDevice:] */
enum {
@ -84,8 +84,9 @@ typedef struct _gswindow_device_t {
Display *display; /* Display this window is on */
Window ident; /* Window handle */
Window root; /* Handle of root window */
Window parent; /* Handle of parent window */
int screen; /* Screeen this window is on */
Window parent; /* Handle of parent window */
int screen_id; /* Screeen this window is on */
int monitor_id; /* Physical monitor this window is on */
GC gc; /* GC for drawing */
long number; /* Globally unique identifier */
unsigned int depth; /* Window depth */
@ -94,7 +95,8 @@ typedef struct _gswindow_device_t {
int visibility; /* X visibility */
int wm_state; /* X WM state */
NSBackingStoreType type; /* Backing type */
NSRect xframe; /* Window frame */
NSRect xframe; /* Window frame in X11 coordinates */
NSRect osframe; /* Window frame in OpenStep coordinates */
unsigned int buffer_width; /* Size in pixels of the current buffers. */
unsigned int buffer_height;

View file

@ -33,14 +33,18 @@
#include <X11/Xft/Xft.h>
#undef id
#import <GNUstepGUI/GSFontInfo.h>
#import "fontconfig/FCFontInfo.h"
#import "fontconfig/FCFontEnumerator.h"
@interface FcFontEnumerator : GSFontEnumerator
{
}
@interface GSXftFaceInfo : FCFaceInfo
@end
@interface GSXftFontInfo : GSFontInfo
@interface GSXftFontEnumerator : FCFontEnumerator
+ (Class) faceInfoClass;
+ (GSXftFaceInfo *) fontWithName: (NSString *)name;
@end
@interface GSXftFontInfo : FCFontInfo
{
XftFont *font_info;
}

View file

@ -73,13 +73,13 @@ extern unsigned long XGFontPropULong(Display *dpy, XFontStruct *font_struct,
- (void) draw: (const char*) s length: (int) len
onDisplay: (Display*) xdpy drawable: (Drawable) draw
with: (GC) xgcntxt at: (XPoint) xp;
- (float) widthOf: (const char*) s length: (int) len;
- (CGFloat) widthOf: (const char*) s length: (int) len;
- (void) setActiveFor: (Display*) xdpy gc: (GC) xgcntxt;
- (void) drawGlyphs: (const NSGlyph *) glyphs length: (int) len
onDisplay: (Display*) xdpy drawable: (Drawable) draw
with: (GC) xgcntxt at: (XPoint) xp;
- (float) widthOfGlyphs: (const NSGlyph *) glyphs length: (int) len;
- (CGFloat) widthOfGlyphs: (const NSGlyph *) glyphs length: (int) len;
@end

12
INSTALL
View file

@ -5,7 +5,7 @@
================
This file documents the installation of the GNUstep Backend Library,
'gnustep-back'. If you are installing this package as part of the
gnustep-back. If you are installing this package as part of the
GNUstep core package, read the file GNUstep-HOWTO for more complete
instructions on how to install the entire GNUstep package (including
this library). GNUstep-HOWTO is located at <http://www.gnustep.org>
@ -15,9 +15,9 @@ this library). GNUstep-HOWTO is located at <http://www.gnustep.org>
1.2 Configuration
=================
Configuration is performed by running the 'configure' program at a shell
Configuration is performed by running the configure program at a shell
prompt. You may want to use some of the optional arguments to the
'configure' program. Type 'configure --help' for a list. GNUstep
configure program. Type configure --help for a list. GNUstep
specific options are at the end of this list (if any).
The backend comes with several different window server and graphics
@ -27,7 +27,7 @@ choose the art graphical drawing implementation, run
configure --enable-graphics=art
Type 'configure --help' for a list of graphical drawing
Type configure --help for a list of graphical drawing
implementations.
You can also change the name of the backend when configuring it.
@ -52,8 +52,8 @@ program:
To compile this library, type make. After this is complete, type make
install (make sure you are the root user). Some additional options you
can use with make are 'debug=yes' to make a debugging version of the
library and 'shared=no' to make a static version of the library. See
can use with make are debug=yes to make a debugging version of the
library and shared=no to make a static version of the library. See
the gstep-make package for more information on these options.
1.4 Installing

216
NEWS
View file

@ -1,40 +1,110 @@
1 NEWS
******
1.1 Noteworthy changes in version '0.26.2'
1.1 Noteworthy changes in version 0.32.0
==========================================
The release includes mostly bug fixes.
• Make window termination saver.
• Use default interpolation in Cairo.
• Allow UTF-8 input from XLookupString.
• Improve building on MS Windows.
1.2 Noteworthy changes in version 0.31.0
==========================================
The release includes mostly improvements for pasteboard handling and a
few bug fixes.
• Improve font name creation.
• Add headless backend.
• Add CI pipeline.
1.3 Noteworthy changes in version 0.30.0
==========================================
The release includes mostly improvements for the new Wayland backend and
a few bug fixes.
• Improvements for the wayland backend.
• Don't use font hinting for cauro, when using scaling.
• Fix pasteboard transfer of huge data by deleting property on begin
and at every Notify.
1.4 Noteworthy changes in version 0.29.0
==========================================
The release includes an alpha version of the wayland backend and a few
bug fixes.
• Alpha version of the wayland backend.
• Improved focus handling for WindowMaker interaction.
• Speed up for font pattern resolving.
• Improved appicon behavior under WindowMaker.
• Prevent appicon flickering on WindowMaker at application start.
• On Windows, consistently use GetWindowLongPtr and
SetWindowLongPtr in place of GetWindowLong and SetWindowLong
for win32 and cairo for various win64 fixes.
1.5 Noteworthy changes in version 0.28.0
==========================================
This release includes a few bugfixes and a huge rework of multi monitor
handling.
• Improved focus handling for WindowMaker interaction.
• Cursor improvements.
• Better handling of fonts with fontconfig.
• Simplify code that converts images for X11.
• art: Remove ftfont-old.m.
• Use Xrandr for multi monitor support.
1.6 Noteworthy changes in version 0.27.0
==========================================
This release includes a few bugfixes.
• configure: Improve configuration.
• xlib: Improve xft font classes.
• x11: Enable drawing in secondary threads.
• x11: Better handling of atoms. Method to get the window manager.
• opal: Improve colour handling
1.7 Noteworthy changes in version 0.26.2
==========================================
This release contains no changes since 0.26.1. It is released to
coincide with gnustep-gui 0.26.2, which has important bugfixes related
to printing.
1.2 Noteworthy changes in version '0.26.1'
1.8 Noteworthy changes in version 0.26.1
==========================================
This release contains no changes since 0.26.0. It is released to
coincide with gnustep-gui 0.26.1, released to mark gnustep-base 1.25.1
as the requirement for gnustep-gui.
1.3 Noteworthy changes in version '0.26.0'
1.9 Noteworthy changes in version 0.26.0
==========================================
This release includes a few bugfixes, as well as compatibility
improvements as a result of GSoC 2017 project.
* opal: Bridging categories between Opal and GNUstep GUI. Added onto
opal: Bridging categories between Opal and GNUstep GUI. Added onto
NSColor, NSImage and NSImageRep.
* cairo: Get -DPSshow: to work on scaled windows.
* opal: Allow creating a NSGraphicsContext with a custom graphics
cairo: Get -DPSshow: to work on scaled windows.
opal: Allow creating a NSGraphicsContext with a custom graphics
port, other than a CGContext.
* misc: Fix reported static analyser warnings.
misc: Fix reported static analyser warnings.
1.4 Noteworthy changes in version '0.25.1'
==========================================
1.10 Noteworthy changes in version 0.25.1
===========================================
Small fixes and cleanups.
1.5 Noteworthy changes in version '0.25.0'
==========================================
1.11 Noteworthy changes in version 0.25.0
===========================================
Support for pattern phase, compositing operation, image interpolation
and antialiasing per gstate.
@ -45,29 +115,29 @@ and antialiasing per gstate.
Various fixes.
1.6 Noteworthy changes in version '0.24.1'
==========================================
1.12 Noteworthy changes in version 0.24.1
===========================================
Improvements in win32 display and mouse tracking.
Various minor bugfixes and cleanups.
1.7 Noteworthy changes in version '0.24.0'
==========================================
1.13 Noteworthy changes in version 0.24.0
===========================================
Added experimental Opal backend.
Allow for ARGB visual for OpenGL.
1.8 Noteworthy changes in version '0.23.0'
==========================================
1.14 Noteworthy changes in version 0.23.0
===========================================
Added cairo support for ms-windows.
Updated for NSInteger/CGFloat support
1.9 Noteworthy changes in version '0.22.0'
==========================================
1.15 Noteworthy changes in version 0.22.0
===========================================
Added new user defaults to make app icons and mini windows sticky
(omnipresent)
@ -75,7 +145,7 @@ Added new user defaults to make app icons and mini windows sticky
Many improvements to Cairo rendering, including buffering, glyphs and
DPI scaling.
1.10 Noteworthy changes in version '0.20.0'
1.16 Noteworthy changes in version 0.20.0
===========================================
Cairo is now the default backend, but falls back to art and xlib
@ -85,37 +155,37 @@ gracefully.
More Windows improvements.
1.11 Noteworthy changes in version '0.19.0'
1.17 Noteworthy changes in version 0.19.0
===========================================
This is an (unstable) copy of the 0.18.0 release
1.12 Noteworthy changes in version '0.18.0'
1.18 Noteworthy changes in version 0.18.0
===========================================
Many Windows improvements
Implement pattern colours for all backends.
1.13 Noteworthy changes in version '0.17.1'
1.19 Noteworthy changes in version 0.17.1
===========================================
Use DejaVu as another fallback font.
1.14 Noteworthy changes in version '0.17.0'
1.20 Noteworthy changes in version 0.17.0
===========================================
Key repeat support implemented in X11.
OpenGL fixes and improvements.
1.15 Noteworthy changes in version '0.16.0'
1.21 Noteworthy changes in version 0.16.0
===========================================
Transparent windows implemented in WIN32 backend, better position and
scaling of images. General cleanup of code.
1.16 Noteworthy changes in version '0.14.0'
1.22 Noteworthy changes in version 0.14.0
===========================================
Added code to automatically make any window which uses the
@ -123,7 +193,7 @@ NSDesktopWindowLevel also be omnipresent.
Many glyph drawing improvements.
1.17 Noteworthy changes in version '0.13.2'
1.23 Noteworthy changes in version 0.13.2
===========================================
Added basic implementation of window levels on Windows. In general a
@ -137,24 +207,24 @@ bunch of improvements in the Windows backend.
frontend. This version or greater of the backend needs to be used with
gui 0.13.2
1.18 Noteworthy changes in version '0.13.1'
1.24 Noteworthy changes in version 0.13.1
===========================================
Minor improvements.
1.19 Noteworthy changes in version '0.13.0'
1.25 Noteworthy changes in version 0.13.0
===========================================
Many improvements to the cairo backend. Add DPSshfill for all backends.
Better handling of X event times.
1.20 Noteworthy changes in version '0.12.0'
1.26 Noteworthy changes in version 0.12.0
===========================================
Big improvements to the cairo graphics and Window backend. Also better
support for OpenGL.
1.21 Noteworthy changes in version '0.11.0'
1.27 Noteworthy changes in version 0.11.0
===========================================
Bugfixes to art and xlib.
@ -162,17 +232,17 @@ Bugfixes to art and xlib.
There was some work on the Windows backend for the GDI interface by
Christopher Armstrong.
1.22 Noteworthy changes in version '0.10.3'
1.28 Noteworthy changes in version 0.10.3
===========================================
Fixes. A lot of Cairo backend work.
1.23 Noteworthy changes in version '0.10.2'
1.29 Noteworthy changes in version 0.10.2
===========================================
The Backend can set UTF8 window titles where this is allowed.
1.24 Noteworthy changes in version '0.10.1'
1.30 Noteworthy changes in version 0.10.1
===========================================
The art graphics module is the default now. As was previously the case,
@ -189,69 +259,69 @@ Cairo library before it will work with GNUstep. Due to this, this
module is still considered beta. Ask on the mailing lists for help with
this.
1.25 Noteworthy changes in version '0.10.0'
1.31 Noteworthy changes in version 0.10.0
===========================================
The installed name of the backend now includes an interface version
number. This avoids the potential version mismatch between the frontend
(GUI) library and the backend.
* Alpha blending was implemented for Windows, although it does not
Alpha blending was implemented for Windows, although it does not
seem to work on some machines.
1.26 Noteworthy changes in version '0.9.5'
1.32 Noteworthy changes in version 0.9.5
==========================================
* Added support for window alpha on X servers.
* Add support for old and new freetype libs.
* Some improvements to the Windows backend.
Added support for window alpha on X servers.
Add support for old and new freetype libs.
Some improvements to the Windows backend.
1.27 Noteworthy changes in version '0.9.4'
1.33 Noteworthy changes in version 0.9.4
==========================================
* Fast drawing on 8 bit displays was added (although it might only
Fast drawing on 8 bit displays was added (although it might only
speed things up on old X11 servers and/or remote servers).
* GNUstep modifier keys are mapped to KeySyms instead of KeyCodes
* Added a Cairo backend, although it is probably non-functional.
GNUstep modifier keys are mapped to KeySyms instead of KeyCodes
Added a Cairo backend, although it is probably non-functional.
Anyone is invited to contribute to making it work.
* art backend supports reading from a window.
* Add internal window decoration handling.
art backend supports reading from a window.
Add internal window decoration handling.
1.28 Noteworthy changes in version '0.9.3'
1.34 Noteworthy changes in version 0.9.3
==========================================
* A number of W32 window event enhancements
* art backend glyph drawing with alpha enhancements.
* libwraster is no longer checked for - image functions now in
A number of W32 window event enhancements
art backend glyph drawing with alpha enhancements.
libwraster is no longer checked for - image functions now in
frontend
1.29 Noteworthy changes in version '0.9.2'
1.35 Noteworthy changes in version 0.9.2
==========================================
* Art backend added support for grayscale, one-isblack colorspaces.
* Windows pasteboard interaction handling added.
* Better focus handling on Windows.
* Better font and draw handling on Windows.
Art backend added support for grayscale, one-isblack colorspaces.
Windows pasteboard interaction handling added.
Better focus handling on Windows.
Better font and draw handling on Windows.
1.30 Noteworthy changes in version '0.9.1'
1.36 Noteworthy changes in version 0.9.1
==========================================
Color on 8 bit displays works correctly now. WindowMaker properties are
always set now in case another manager is emulating WindowMaker styles.
1.31 Noteworthy changes in version '0.9.0'
1.37 Noteworthy changes in version 0.9.0
==========================================
Some more improvements to copy/paste support following ICCCM
specifications (like COMPOUND_TEXT support).
1.32 Noteworthy changes in version '0.8.9'
1.38 Noteworthy changes in version 0.8.9
==========================================
* Much improved pasting support between X apps and GNUstep apps.
* Backend headers are no longer installed (now private).
Much improved pasting support between X apps and GNUstep apps.
Backend headers are no longer installed (now private).
1.33 Noteworthy changes in version '0.8.8'
1.39 Noteworthy changes in version 0.8.8
==========================================
Full multi-byte/unicode support for East Asian languages was added to
@ -259,60 +329,60 @@ the xlib backend. The X11 server now supports use of the XIM input
method for entering non-keyboard characters. Both contributions thanks
to Kazunobu Kuriyama.
* Also added slightly better EWMH support.
* Art backend works with more versions of freetype.
Also added slightly better EWMH support.
Art backend works with more versions of freetype.
1.34 Noteworthy changes in version '0.8.7'
1.40 Noteworthy changes in version 0.8.7
==========================================
Handle NSBezierPath glyph drawing in art backend. art backend compiles
with all freetype except 2.1.3 via ifdefs.
1.35 Noteworthy changes in version '0.8.6'
1.41 Noteworthy changes in version 0.8.6
==========================================
Bug fixes. See the gnustep-gui NEWS for changes.
1.36 Noteworthy changes in version '0.8.5'
1.42 Noteworthy changes in version 0.8.5
==========================================
Text system improvements. See the gnustep-gui NEWS for changes.
1.37 Noteworthy changes in version '0.8.3'
1.43 Noteworthy changes in version 0.8.3
==========================================
See the gnustep-gui NEWS for changes.
1.38 Noteworthy changes in version '0.8.2'
1.44 Noteworthy changes in version 0.8.2
==========================================
Improved font handling in art backend. Improved compositing with
transformations and clipping in art backend.
1.39 Noteworthy changes in version '0.8.1'
1.45 Noteworthy changes in version 0.8.1
==========================================
art (libart-based) backend added. Use ./configure -enable-graphics=art
to choose this backend.
1.40 Noteworthy changes in version '0.8.0'
1.46 Noteworthy changes in version 0.8.0
==========================================
Bug fixes.
1.41 Noteworthy changes in version '0.7.9'
1.47 Noteworthy changes in version 0.7.9
==========================================
Bug fixes.
1.42 Noteworthy changes in version '0.7.8'
1.48 Noteworthy changes in version 0.7.8
==========================================
Simplified backend selection using -enable-server and -enable-graphics.
Add -with-library-flags and -with-include-flags for adding additonal
flags. Set name with -with-name
1.43 Noteworthy changes in version '0.7.7'
1.49 Noteworthy changes in version 0.7.7
==========================================
First release. Most components extracted from xgps. The old backends,

10
README
View file

@ -1,23 +1,23 @@
1 README
********
This is version 0.26.2 of the GNUstep GUI Backend ('gnustep-back').
This is version 0.32.0 of the GNUstep GUI Backend (gnustep-back).
Here is some introductory info to get you started:
1.1 Initial reading
===================
* The file 'ANNOUNCE' contains a very brief overview of the library.
• The file ANNOUNCE contains a very brief overview of the library.
It also tells you where to get the most recent version.
* The file 'NEWS' has the library's feature history.
• The file NEWS has the library's feature history.
* The file 'INSTALL' gives instructions for installing the library.
• The file INSTALL gives instructions for installing the library.
1.2 How can you help?
=====================
* Give us feedback! Tell us what you like; tell us what you think
Give us feedback! Tell us what you like; tell us what you think
could be better. Send us bug reports at <bug-gnustep@gnu.org>.

View file

@ -43,7 +43,7 @@ endif
#
# The list of subproject directories
#
SUBPROJECTS = gsc $(BUILD_SERVER) $(BUILD_GRAPHICS)
SUBPROJECTS = $(sort gsc $(BUILD_SERVER) $(BUILD_GRAPHICS))
libgnustep-$(BACKEND_FULL)_SUBPROJECTS=$(SUBPROJECTS)

View file

@ -45,6 +45,16 @@
@interface WIN32Server (Initialize)
+ (void) initializeBackend;
@end
#elif BUILD_SERVER == SERVER_wayland
#include <wayland/WaylandServer.h>
@interface WaylandServer (Initialize)
+ (void) initializeBackend;
@end
#elif BUILD_SERVER == SERVER_headless
#include <headless/HeadlessServer.h>
@interface HeadlessServer (Initialize)
+ (void) initializeBackend;
@end
#endif
/* Call the correct initalization routines for the choosen
@ -63,6 +73,10 @@
[XGServer initializeBackend];
#elif BUILD_SERVER == SERVER_win32
[WIN32Server initializeBackend];
#elif BUILD_SERVER == SERVER_wayland
[WaylandServer initializeBackend];
#elif BUILD_SERVER == SERVER_headless
[HeadlessServer initializeBackend];
#else
[NSException raise: NSInternalInconsistencyException
format: @"No Window Server configured in backend"];
@ -89,6 +103,8 @@
context = @"CairoContext";
#elif (BUILD_GRAPHICS==GRAPHICS_opal)
context = @"OpalContext";
#elif (BUILD_GRAPHICS==GRAPHICS_headless)
context = @"HeadlessContext";
#else
#error INVALID build graphics type
#endif

View file

@ -70,7 +70,7 @@
gswindow_device_t *gs_win;
gs_win = device;
[(XGServer *)server getForScreen: gs_win->screen pixelFormat: &bpp
[(XGServer *)server getForScreen: gs_win->screen_id pixelFormat: &bpp
masks: &red_mask : &green_mask : &blue_mask];
#endif
artcontext_setup_draw_info(&DI, red_mask, green_mask, blue_mask, bpp);

View file

@ -245,8 +245,7 @@ static void add_face(NSString *family, int family_weight,
return;
}
fi->displayName = [[family stringByAppendingString: @" "]
stringByAppendingString: faceName];
fi->displayName = [[NSString stringWithFormat: @"%@ %@", family, faceName] retain];
weight = family_weight;
@ -445,7 +444,7 @@ static void load_font_configuration(void)
[families_pending removeAllObjects];
}
NSDebugLLog(@"ftfont", @"got %i fonts in %i families",
NSDebugLLog(@"ftfont", @"got %lu fonts in %lu families",
[fcfg_allFontNames count], [fcfg_allFontFamilies count]);
if (![fcfg_allFontNames count])

View file

@ -37,7 +37,7 @@ ADDITIONAL_CPPFLAGS += -Wall $(CONFIG_SYSTEM_DEFS)
#ADDITIONAL_CFLAGS =
# Additional include directories the compiler should search
ADDITIONAL_INCLUDE_DIRS = -I../../Headers \
ADDITIONAL_INCLUDE_DIRS += -I../../Headers \
-I../$(GNUSTEP_TARGET_DIR) $(GRAPHIC_CFLAGS) \
# Additional LDFLAGS to pass to the linker

View file

@ -1505,7 +1505,7 @@ static BOOL _rect_advance(rect_trace_t *t, int *x0, int *x1)
}
else
{
NSLog(@"unimplemented compositerect: (%g %g)+(%g %g) op: %i",
NSLog(@"unimplemented compositerect: (%g %g)+(%g %g) op: %lu",
aRect.origin.x, aRect.origin.y,
aRect.size.width, aRect.size.height,
op);

File diff suppressed because it is too large Load diff

View file

@ -25,6 +25,8 @@
#ifndef ftfont_h
#define ftfont_h
#import "blit.h"
@class NSAffineTransform;
@protocol FTFontInfo
@ -66,7 +68,40 @@
+(void) initializeBackend;
@end
@class FTFontInfo;
#import <ft2build.h>
#import FT_CACHE_H
#import <GNUstepGUI/GSFontInfo.h>
#import "FTFaceInfo.h"
#define CACHE_SIZE 257
@interface FTFontInfo : GSFontInfo <FTFontInfo>
{
@public
int pix_width, pix_height;
FTC_FaceID faceId;
FTC_ImageTypeRec imageType;
FTC_ScalerRec scaler;
int unicodeCmap;
BOOL screenFont;
FTFaceInfo *face_info;
FT_Size ft_size;
/*
Profiling (2003-11-14) shows that calls to -advancementForGlyph: accounted
for roughly 20% of layout time. This cache reduces it to (currently)
insignificant levels.
*/
unsigned int cachedGlyph[CACHE_SIZE];
NSSize cachedSize[CACHE_SIZE];
CGFloat lineHeight;
}
@end
#endif

View file

@ -22,17 +22,6 @@
Boston, MA 02110-1301, USA.
*/
#include <ft2build.h>
#include FT_FREETYPE_H
#if (FREETYPE_MAJOR==2) && ((FREETYPE_MINOR<1) || ((FREETYPE_MINOR==1) && (FREETYPE_PATCH<8)))
#import "ftfont-old.m"
#else
#include <math.h>
#import <Foundation/NSObject.h>
@ -56,17 +45,12 @@
#import "ftfont.h"
#import "FTFontEnumerator.h"
#import "FTFaceInfo.h"
#import "blit.h"
#define DI (*di)
/** font handling interface **/
#include FT_CACHE_H
#include FT_FREETYPE_H
#include FT_CACHE_IMAGE_H
#include FT_CACHE_SMALL_BITMAPS_H
@ -86,42 +70,9 @@ from the back-art-subpixel-text defaults key
*/
static int subpixel_text;
#define CACHE_SIZE 257
@interface FTFontInfo : GSFontInfo <FTFontInfo>
{
@public
int pix_width, pix_height;
FTC_FaceID faceId;
FTC_ImageTypeRec imageType;
FTC_ScalerRec scaler;
int unicodeCmap;
BOOL screenFont;
FTFaceInfo *face_info;
FT_Size ft_size;
/*
Profiling (2003-11-14) shows that calls to -advancementForGlyph: accounted
for roughly 20% of layout time. This cache reduces it to (currently)
insignificant levels.
*/
unsigned int cachedGlyph[CACHE_SIZE];
NSSize cachedSize[CACHE_SIZE];
CGFloat lineHeight;
}
@end
@interface FTFontInfo_subpixel : FTFontInfo
@end
static FT_Library ft_library;
static FTC_Manager ftc_manager;
static FTC_ImageCache ftc_imagecache;
@ -352,6 +303,11 @@ static FT_Error ft_get_face(FTC_FaceID fid, FT_Library lib,
return self;
}
- (NSString*) displayName
{
return face_info->displayName;
}
- (void) set
{
NSLog(@"ignore -set method of font '%@'", fontName);
@ -416,7 +372,7 @@ static FT_Error ft_get_face(FTC_FaceID fid, FT_Library lib,
return lineHeight;
}
- (unsigned) numberOfGlyphs
- (NSUInteger) numberOfGlyphs
{
if (coveredCharacterSet == nil)
{
@ -524,7 +480,7 @@ static FT_Error ft_get_face(FTC_FaceID fid, FT_Library lib,
real size, just a matrix. Thus, we average pix_width and
pix_height; we'll get the right answer for normal cases, and
we can't really do anything about the weird cases. */
f = fabs(pix_width) + fabs(pix_height);
f = abs(pix_width) + abs(pix_height);
if (f > 1)
f = f / 2.0;
else
@ -610,7 +566,7 @@ static FT_Error ft_get_face(FTC_FaceID fid, FT_Library lib,
{
NSLog(@"FTC_SBitCache_Lookup() failed with error %08x "
@"(%08x, %08x, %ix%i, %08x)",
error, glyph, imageType.face_id, imageType.width,
error, glyph, (unsigned)imageType.face_id, imageType.width,
imageType.height, imageType.flags);
continue;
}
@ -1010,7 +966,7 @@ static FT_Error ft_get_face(FTC_FaceID fid, FT_Library lib,
float f;
use_sbit = 0;
f = fabs(pix_width) + fabs(pix_height);
f = abs(pix_width) + abs(pix_height);
if (f > 1)
f = f / 2.0;
else
@ -1040,7 +996,7 @@ static FT_Error ft_get_face(FTC_FaceID fid, FT_Library lib,
{
NSLog(@"FTC_SBitCache_Lookup() failed with error %08x "
@"(%08x, %08x, %ix%i, %08x)",
error, glyph, imageType.face_id,
error, glyph, (unsigned)imageType.face_id,
imageType.width, imageType.height,
imageType.flags);
continue;
@ -1331,7 +1287,7 @@ static FT_Error ft_get_face(FTC_FaceID fid, FT_Library lib,
float f;
use_sbit = 0;
f = fabs(pix_width) + fabs(pix_height);
f = abs(pix_width) + abs(pix_height);
if (f > 1)
f = f / 2.0;
else
@ -1360,7 +1316,7 @@ static FT_Error ft_get_face(FTC_FaceID fid, FT_Library lib,
{
if (glyph != 0xffffffff)
NSLog(@"FTC_SBitCache_Lookup() failed with error %08x (%08x, %08x, %ix%i, %08x)",
error, glyph, imageType.face_id, imageType.width, imageType.height,
error, glyph, (unsigned)imageType.face_id, imageType.width, imageType.height,
imageType.flags
);
continue;
@ -1628,7 +1584,7 @@ static FT_Error ft_get_face(FTC_FaceID fid, FT_Library lib,
if ((error = FTC_SBitCache_Lookup(ftc_sbitcache, &imageType, glyph, &sbit, NULL)))
{
NSLog(@"FTC_SBitCache_Lookup() failed with error %08x (%08x, %08x, %ix%i, %08x)",
error, glyph, imageType.face_id,
error, glyph, (unsigned)imageType.face_id,
imageType.width, imageType.height,
imageType.flags
);
@ -2020,12 +1976,12 @@ static int bezierpath_cubic_to(const FT_Vector *c1, const FT_Vector *c2,
}
static FT_Outline_Funcs bezierpath_funcs = {
move_to:bezierpath_move_to,
line_to:bezierpath_line_to,
conic_to:bezierpath_conic_to,
cubic_to:bezierpath_cubic_to,
shift:10,
delta:0,
.move_to = bezierpath_move_to,
.line_to = bezierpath_line_to,
.conic_to = bezierpath_conic_to,
.cubic_to = bezierpath_cubic_to,
.shift = 10,
.delta = 0,
};
@ -2654,5 +2610,3 @@ static char buf[1024]; /* !!TODO!! */
}
@end
#endif /* freetype version check, >=2.1.8 */

View file

@ -759,7 +759,7 @@ seem to cause edges to be off by a pixel
return;
}
NSLog(@"unimplemented DPSimage %ix%i |%@| bips=%i spp=%i bipp=%i bypr=%i planar=%i alpha=%i\n",
NSLog(@"unimplemented DPSimage %lix%li |%@| bips=%li spp=%li bipp=%li bypr=%li planar=%i alpha=%i\n",
pixelsWide, pixelsHigh, matrix,
bitsPerSample, samplesPerPixel, bitsPerPixel, bytesPerRow, isPlanar,
hasAlpha);

View file

@ -731,7 +731,7 @@ static void clip_svp_callback(void *data, int y, int start,
ci.index = malloc(sizeof(unsigned int) * (clip_sy + 1));
if (!ci.index)
{
NSLog(@"Warning: out of memory calculating clipping spans (%i bytes)",
NSLog(@"Warning: out of memory calculating clipping spans (%lu bytes)",
sizeof(unsigned int) * (clip_sy + 1));
return;
}

View file

@ -502,7 +502,7 @@ static BOOL function_setup(NSDictionary * d, function_t *f)
f->encode = NULL;
free(f->decode);
f->decode = NULL;
NSDebugLLog(@"GSArt -shfill", @"Need %i bytes of data, DataSource only has %i bytes.",
NSDebugLLog(@"GSArt -shfill", @"Need %i bytes of data, DataSource only has %lu bytes.",
j, [data length]);
return NO;
}

View file

@ -70,6 +70,12 @@
# define _CAIRO_SURFACE_CLASSNAME Win32CairoSurface
# include "cairo/Win32CairoSurface.h"
# endif /* USE_GLITZ */
#elif BUILD_SERVER == SERVER_wayland
# include "wayland/WaylandServer.h"
# include "cairo/CairoGState.h"
# include "cairo/WaylandCairoShmSurface.h"
# define _CAIRO_GSTATE_CLASSNAME CairoGState
# define _CAIRO_SURFACE_CLASSNAME WaylandCairoShmSurface
#else
# error Invalid server for Cairo backend : non implemented
#endif /* BUILD_SERVER */
@ -99,6 +105,16 @@
return YES;
}
- (id) initWithContextInfo: (NSDictionary *)info
{
self = [super initWithContextInfo: info];
if (self)
{
[self setImageInterpolation: NSImageInterpolationDefault];
}
return self;
}
- (BOOL) isDrawingToScreen
{
CairoSurface *surface = nil;

View file

@ -35,6 +35,99 @@
#include <math.h>
#include <cairo-ft.h>
#include FT_FREETYPE_H
#include FT_SFNT_NAMES_H
#include FT_TRUETYPE_TABLES_H
#include FT_TYPE1_TABLES_H
#include <fontconfig/fontconfig.h>
#include <fontconfig/fcfreetype.h>
void set_font_options(cairo_font_options_t *options)
{
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
cairo_hint_metrics_t metrics = CAIRO_HINT_METRICS_ON;
cairo_hint_style_t style = CAIRO_HINT_STYLE_NONE;
int hinting = [ud integerForKey: @"GSFontHinting"];
float scale = [ud floatForKey: @"GSScaleFactor"];
int subpixel = 0;
if (hinting == 0)
{
/*
* This could be on purpose or a missing value.
* In the later case use the defaults.
*/
if (nil == [ud objectForKey: @"GSFontHinting"])
{
/*
* Default hinting to off if scale is set to something other than 1.0. As
* hinting + scaling breaks assumptions about glyph advancement made in gui.
*/
if (scale == 0.0f || scale == 1.0f)
{
hinting = 33;
}
else
{
hinting = 17;
}
}
}
/*
* This part is only here to debug disabling the use of hinting for
* metrics, because doing so causes menus to get cut off on the right.
*/
switch (hinting >> 4)
{
case 0:
metrics = CAIRO_HINT_METRICS_DEFAULT;
break;
case 1:
metrics = CAIRO_HINT_METRICS_OFF;
break;
case 2:
metrics = CAIRO_HINT_METRICS_ON;
break;
}
switch (hinting & 0x0f)
{
case 0:
style = CAIRO_HINT_STYLE_DEFAULT;
break;
case 1:
style = CAIRO_HINT_STYLE_NONE;
break;
case 2:
style = CAIRO_HINT_STYLE_SLIGHT;
break;
case 3:
style = CAIRO_HINT_STYLE_MEDIUM;
break;
case 4:
style = CAIRO_HINT_STYLE_FULL;
break;
}
cairo_font_options_set_hint_metrics(options, metrics);
cairo_font_options_set_hint_style(options, style);
if ((subpixel = [ud integerForKey: @"back-art-subpixel-text"]))
{
cairo_font_options_set_antialias(options, CAIRO_ANTIALIAS_SUBPIXEL);
if (subpixel == 2)
{
cairo_font_options_set_subpixel_order(options, CAIRO_SUBPIXEL_ORDER_BGR);
}
else
{
cairo_font_options_set_subpixel_order(options, CAIRO_SUBPIXEL_ORDER_RGB);
}
}
}
@implementation CairoFontInfo
- (BOOL) setupAttributes
@ -70,17 +163,8 @@
{
return NO;
}
// We must not leave the hinting settings as their defaults,
// because if we did, that would mean using the surface defaults
// which might or might not use hinting (xlib does by default.)
//
// Since we make measurements outside of the context of a surface
// (-advancementForGlyph:), we need to ensure that the same
// hinting settings are used there as when we draw. For now,
// just force hinting to be off.
cairo_font_options_set_hint_metrics(options, CAIRO_HINT_METRICS_ON);
cairo_font_options_set_hint_style(options, CAIRO_HINT_STYLE_NONE);
set_font_options(options);
_scaled = cairo_scaled_font_create(face, &font_matrix, &ctm, options);
cairo_font_options_destroy(options);
@ -159,15 +243,38 @@
- (BOOL) glyphIsEncoded: (NSGlyph)glyph
{
/* FIXME: There is no proper way to determine with the toy font API,
whether a glyph is supported or not. We will just ignore ligatures
and report all other glyph as existing.
return !NSEqualSizes([self advancementForGlyph: glyph], NSZeroSize);
*/
if ((glyph >= 0xFB00) && (glyph <= 0xFB05))
return NO;
else
return YES;
BOOL val = NO;
if (_scaled)
{
FT_Face face = cairo_ft_scaled_font_lock_face(_scaled);
if (FT_Get_Char_Index (face, glyph) != 0)
{
val = YES;
}
cairo_ft_scaled_font_unlock_face(_scaled);
}
return val;
}
- (NSGlyph) glyphWithName: (NSString *)glyphName
{
NSGlyph val = NSNullGlyph;
FT_String *name = (FT_String *)[glyphName UTF8String];
if (_scaled)
{
FT_Face face = cairo_ft_scaled_font_lock_face(_scaled);
if (FT_Has_PS_Glyph_Names(face))
{
val = (NSGlyph) FT_Get_Name_Index(face, name);
}
cairo_ft_scaled_font_unlock_face(_scaled);
}
return val;
}
static
@ -241,6 +348,12 @@ BOOL _cairo_extents_for_NSGlyph(cairo_scaled_font_t *scaled_font, NSGlyph glyph,
return NSZeroRect;
}
- (NSString *) displayName
{
return [_faceInfo displayName];
}
- (CGFloat) widthOfString: (NSString *)string
{
cairo_text_extents_t ctext;

View file

@ -49,12 +49,16 @@ ifeq ($(BUILD_SERVER),x11)
cairo_OBJC_FILES += XGCairoSurface.m XGCairoXImageSurface.m XGCairoModernSurface.m
endif
else
ifeq ($(BUILD_GRAPHICS),cairo)
ifeq ($(WITH_GLITZ),yes)
cairo_OBJC_FILES += Win32CairoGlitzSurface.m
else
cairo_OBJC_FILES += Win32CairoSurface.m Win32CairoGState.m
# Win32CairoXImageSurface.m
ifeq ($(BUILD_SERVER),wayland)
cairo_OBJC_FILES += WaylandCairoShmSurface.m
else
ifeq ($(BUILD_GRAPHICS),cairo)
ifeq ($(WITH_GLITZ),yes)
cairo_OBJC_FILES += Win32CairoGlitzSurface.m
else
cairo_OBJC_FILES += Win32CairoSurface.m Win32CairoGState.m
# Win32CairoXImageSurface.m
endif
endif
endif
endif

View file

@ -0,0 +1,270 @@
/* WaylandCairoSurface
WaylandCairoShmSurface - A cairo surface backed by a wayland
shared memory buffer.
After the wayland surface is configured, the buffer needs to be
attached to the surface. Subsequent changes to the cairo surface
needs to be notified to the wayland server using wl_surface_damage
and wl_surface_commit. The buffer is freed after the compositor
releases it and the cairo surface is not in use.
Copyright (C) 2020 Free Software Foundation, Inc.
Author: Sergio L. Pascual <slp@sinrega.org>
Rewrite: Riccardo Canalicchio <riccardo.canalicchio(at)gmail.com>
Date: November 2021
This file is part of the GNU Objective C Backend Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; see the file COPYING.LIB.
If not, see <http://www.gnu.org/licenses/> or write to the
Free Software Foundation, 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#define _GNU_SOURCE
#include "wayland/WaylandServer.h"
#include "cairo/WaylandCairoShmSurface.h"
#include <cairo/cairo.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
static const enum wl_shm_format wl_fmt = WL_SHM_FORMAT_ARGB8888;
static const cairo_format_t cairo_fmt = CAIRO_FORMAT_ARGB32;
static void
finishBuffer(struct pool_buffer *buf)
{
// The buffer can be deleted if it has been released by the compositor
// and if not used by the cairo surface
if(buf == NULL || buf->busy || buf->surface != NULL)
{
return;
}
if (buf->buffer)
{
wl_buffer_destroy(buf->buffer);
}
if (buf->data)
{
munmap(buf->data, buf->size);
}
free(buf);
return;
}
static void
buffer_handle_release(void *data, struct wl_buffer *wl_buffer)
{
struct pool_buffer *buffer = data;
buffer->busy = false;
// If the buffer was not released before dealloc
finishBuffer(buffer);
}
static const struct wl_buffer_listener buffer_listener = {
// Sent by the compositor when it's no longer using a buffer
.release = buffer_handle_release,
};
// Creates a file descriptor for the compositor to share pixel buffers
static int
createPoolFile(off_t size)
{
static const char template[] = "/gnustep-shared-XXXXXX";
const char *path;
char *name;
int fd;
path = getenv("XDG_RUNTIME_DIR");
if (!path)
{
errno = ENOENT;
return -1;
}
name = malloc(strlen(path) + sizeof(template));
if (!name)
{
return -1;
}
strcpy(name, path);
strcat(name, template);
fd = memfd_create(name, MFD_CLOEXEC);
free(name);
if (fd < 0)
return -1;
if (ftruncate(fd, size) != 0)
{
close(fd);
return -1;
}
return fd;
}
struct pool_buffer *
createShmBuffer(int width, int height, struct wl_shm *shm)
{
uint32_t stride = cairo_format_stride_for_width(cairo_fmt, width);
size_t size = stride * height;
struct pool_buffer * buf = malloc(sizeof(struct pool_buffer));
void *data = NULL;
if (size > 0)
{
buf->poolfd = createPoolFile(size);
if (buf->poolfd == -1)
{
return NULL;
}
data
= mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, buf->poolfd, 0);
if (data == MAP_FAILED)
{
return NULL;
}
buf->pool = wl_shm_create_pool(shm, buf->poolfd, size);
buf->buffer = wl_shm_pool_create_buffer(buf->pool, 0, width, height,
stride, wl_fmt);
wl_buffer_add_listener(buf->buffer, &buffer_listener, buf);
}
else
{
return NULL;
}
buf->data = data;
buf->size = size;
buf->width = width;
buf->height = height;
buf->surface = cairo_image_surface_create_for_data(data, cairo_fmt, width, height, stride);
if(buf->pool)
{
wl_shm_pool_destroy(buf->pool);
}
return buf;
}
@implementation WaylandCairoShmSurface
{
struct pool_buffer *pbuffer;
}
- (id)initWithDevice:(void *)device
{
struct window *window = (struct window *) device;
NSDebugLog(@"WaylandCairoShmSurface: initWithDevice win=%d",
window->window_id);
gsDevice = device;
pbuffer = createShmBuffer(window->width, window->height, window->wlconfig->shm);
if (pbuffer == NULL)
{
NSDebugLog(@"failed to obtain buffer");
return nil;
}
_surface = pbuffer->surface;
window->buffer_needs_attach = YES;
if (_surface == NULL)
{
NSDebugLog(@"can't create cairo surface");
return nil;
}
if (window->configured)
{
// we can attach a buffer to the surface only if the surface is configured
// this is usually done in the configure event handler
// in case of resize of an already configured surface
// we should reattach the new allocated buffer
NSDebugLog(@"wl_surface_attach: win=%d",
window->window_id);
window->buffer_needs_attach = NO;
wl_surface_attach(window->surface, pbuffer->buffer, 0, 0);
wl_surface_commit(window->surface);
}
window->wcs = self;
return self;
}
- (void)dealloc
{
struct window *window = (struct window *) gsDevice;
NSDebugLog(@"WaylandCairoSurface: dealloc win=%d", window->window_id);
cairo_surface_destroy(_surface);
_surface = NULL;
pbuffer->surface = NULL;
// try to free the buffer if already released by the compositor
finishBuffer(pbuffer);
[super dealloc];
}
- (NSSize)size
{
if (_surface == NULL)
{
return NSZeroSize;
}
return NSMakeSize(cairo_image_surface_get_width(_surface),
cairo_image_surface_get_height(_surface));
}
- (void)handleExposeRect:(NSRect)rect
{
struct window *window = (struct window *) gsDevice;
NSDebugLog(@"[CairoSurface handleExposeRect] %d", window->window_id);
window->buffer_needs_attach = YES;
if (window->configured)
{
window->buffer_needs_attach = NO;
wl_surface_attach(window->surface, pbuffer->buffer, 0, 0);
NSDebugLog(@"[%d] updating region: %d,%d %fx%f", window->window_id, 0, 0,
window->width, window->height);
// FIXME we should update only the damaged area defined as x,y,width,
// height at the moment it doesnt work
wl_surface_damage(window->surface, 0, 0, window->width, window->height);
wl_surface_commit(window->surface);
wl_display_dispatch_pending(window->wlconfig->display);
wl_display_flush(window->wlconfig->display);
}
}
- (void)destroySurface
{
// noop this is an offscreen surface
// no need to destroy it when not visible
}
@end

View file

@ -57,7 +57,7 @@
gsDevice = device;
GetClientRect(GSWINDEVICE, &sz);
win = (WIN_INTERN *)GetWindowLong(GSWINDEVICE, GWL_USERDATA);
win = (WIN_INTERN *)GetWindowLongPtr(GSWINDEVICE, GWLP_USERDATA);
if (win && win->useHDC)
{
HGDIOBJ old;

View file

@ -39,7 +39,7 @@
{
if (self)
{
WIN_INTERN *win = (WIN_INTERN *)GetWindowLong((HWND)device, GWL_USERDATA);
WIN_INTERN *win = (WIN_INTERN *)GetWindowLongPtr((HWND)device, GWLP_USERDATA);
HDC hDC = GetDC((HWND)device);
// Save/set initial state...

View file

@ -95,7 +95,7 @@
Window win;
XWindowAttributes attrs;
win = [self xDisplayRootWindowForScreen: screen];
win = [self xDisplayRootWindow];
if (XGetWindowAttributes(dpy, win, &attrs))
{

View file

@ -67,6 +67,39 @@
return _familyName;
}
- (NSString *) displayName
{
char *fcname;
#ifdef FC_POSTSCRIPT_NAME
char *fcpsname;
#endif
/*
If fullname && fullname != psname, use fullname as displayname.
This works around some weird Adobe OpenType fonts which contain their
PostScript name in their "human-readable name" field.
So, set the fullname as displayName (now AKA VisibleName) only
if it's not the same as whatever the postscript name is.
*/
if (FcPatternGetString(_pattern, FC_FULLNAME, 0, (FcChar8 **)&fcname) == FcResultMatch
#ifdef FC_POSTSCRIPT_NAME
&& FcPatternGetString(_pattern, FC_POSTSCRIPT_NAME, 0, (FcChar8 **)&fcpsname) == FcResultMatch
&& strcmp (fcpsname, fcname)
#endif
)
{
return [NSString stringWithUTF8String: fcname];
}
else if (FcPatternGetString(_pattern, FC_STYLE, 0, (FcChar8 **)&fcname) == FcResultMatch)
{
return [NSString stringWithFormat: @"%@ %@", _familyName,
[NSString stringWithUTF8String: fcname]];
}
return _familyName;
}
- (int) weight
{
return _weight;
@ -100,27 +133,32 @@
- (FcPattern *) matchedPattern
{
FcResult result;
FcPattern *resolved;
FcConfigSubstitute(NULL, _pattern, FcMatchPattern);
FcDefaultSubstitute(_pattern);
resolved = FcFontMatch(NULL, _pattern, &result);
return resolved;
}
- (NSCharacterSet*)characterSet
{
if (_characterSet == nil && !_hasNoCharacterSet)
if (!_patternIsResolved)
{
FcResult result;
FcPattern *resolved;
FcCharSet *charset;
FcConfigSubstitute(NULL, _pattern, FcMatchPattern);
FcDefaultSubstitute(_pattern);
resolved = FcFontMatch(NULL, _pattern, &result);
FcPatternDestroy(_pattern);
_pattern = resolved;
_patternIsResolved = YES;
}
// The caller expects ownership of returned pattern and will destroy it
FcPatternReference(_pattern);
return _pattern;
}
- (NSCharacterSet*) characterSet
{
if (_characterSet == nil && !_hasNoCharacterSet)
{
FcPattern *resolved;
FcCharSet *charset;
resolved = [self matchedPattern];
if (FcResultMatch == FcPatternGetCharSet(resolved, FC_CHARSET, 0, &charset))
{

View file

@ -53,6 +53,87 @@
#define FC_WEIGHT_ULTRABLACK FC_WEIGHT_BLACK
#endif
static float
convertWeight (int fcWeight, int bottomValue, int topValue)
{
/*
This is the distance between topValue and bottomValue expressed as a
fraction between zero and one. We do this to express the range of
fontconfig font weights in a useful manner.
*/
if (fcWeight <= bottomValue)
{
return 0.0;
}
else if (fcWeight >= topValue)
{
return 1.0;
}
else
{
return (float) (fcWeight - bottomValue) * (1.0f / (topValue - bottomValue));
}
}
static NSComparisonResult
sortFontFacesArray(id fontArr1, id fontArr2, void *context)
{
/*
Order of array:
0: Font name
1: Font style
2: Font weight
3: Font traits
*/
NSString *style1 = [fontArr1 objectAtIndex: 1];
NSString *style2 = [fontArr2 objectAtIndex: 1];
float weight1 = [[fontArr1 objectAtIndex: 2] floatValue];
float weight2 = [[fontArr2 objectAtIndex: 2] floatValue];
unsigned int traits1 = [[fontArr1 objectAtIndex: 3] unsignedIntValue];
unsigned int traits2 = [[fontArr2 objectAtIndex: 3] unsignedIntValue];
// order first by weight
if (weight1 < weight2)
return NSOrderedAscending;
if (weight1 > weight2)
return NSOrderedDescending;
// Italic next
if ((traits1 & NSItalicFontMask) < (traits2 & NSItalicFontMask))
return NSOrderedAscending;
if ((traits1 & NSItalicFontMask) > (traits2 & NSItalicFontMask))
return NSOrderedDescending;
// now do condensed
if ((traits1 & NSCondensedFontMask) < (traits2 & NSCondensedFontMask))
return NSOrderedAscending;
if ((traits1 & NSCondensedFontMask) > (traits2 & NSCondensedFontMask))
return NSOrderedDescending;
// ...and expanded
if ((traits1 & NSExpandedFontMask) < (traits2 & NSExpandedFontMask))
return NSOrderedAscending;
if ((traits1 & NSExpandedFontMask) > (traits2 & NSExpandedFontMask))
return NSOrderedDescending;
// Special case: "Regular" sorts before non-Regular, for many reasons.
if ([style1 isEqualToString: @"Regular"] && ![style2 isEqualToString: @"Regular"])
return NSOrderedAscending;
if ([style2 isEqualToString: @"Regular"] && ![style1 isEqualToString: @"Regular"])
return NSOrderedDescending;
if ([style1 isEqualToString: @"Normal"] && ![style2 isEqualToString: @"Normal"])
return NSOrderedAscending;
if ([style2 isEqualToString: @"Normal"] && ![style1 isEqualToString: @"Normal"])
return NSOrderedDescending;
if ([style1 isEqualToString: @"Roman"] && ![style2 isEqualToString: @"Roman"])
return NSOrderedAscending;
if ([style2 isEqualToString: @"Roman"] && ![style1 isEqualToString: @"Roman"])
return NSOrderedDescending;
// Otherwise, alphabetize
return [style1 compare: style2];
}
@implementation FCFontEnumerator
NSMutableDictionary * __allFonts;
@ -78,50 +159,137 @@ NSMutableDictionary * __allFonts;
// Make a GNUstep style font descriptor from a FcPattern
static NSArray *faFromFc(FcPattern *pat)
{
int weight, slant, spacing, nsweight;
int weight, slant, spacing, width;
float nsweight;
unsigned int nstraits = 0;
char *family;
NSMutableString *name, *style;
char *fcfamily, *fcstyle;
NSString *styleStr = nil;
NSString *name = nil;
NSMutableString *family, *style;
#ifdef FC_POSTSCRIPT_NAME
char *fcname;
#endif
if (FcPatternGetString(pat, FC_STYLE, 0, (FcChar8 **)&fcstyle) == FcResultMatch)
{
styleStr = [NSString stringWithUTF8String: fcstyle];
}
// NSLog (@"family: %@, style: %s/%@", name, fcstyle, style);
if (FcPatternGetInteger(pat, FC_WEIGHT, 0, &weight) != FcResultMatch
|| FcPatternGetInteger(pat, FC_SLANT, 0, &slant) != FcResultMatch
|| FcPatternGetString(pat, FC_FAMILY, 0, (FcChar8 **)&family)
|| FcPatternGetString(pat, FC_FAMILY, 0, (FcChar8 **)&fcfamily)
!= FcResultMatch)
return nil;
if (FcPatternGetInteger(pat, FC_SPACING, 0, &spacing) == FcResultMatch)
if (spacing==FC_MONO || spacing==FC_CHARCELL)
nstraits |= NSFixedPitchFontMask;
name = [NSMutableString stringWithCapacity: 100];
style = [NSMutableString stringWithCapacity: 100];
[name appendString: [NSString stringWithUTF8String: family]];
switch (weight)
family = [NSMutableString stringWithUTF8String: fcfamily];
style = [NSMutableString stringWithCapacity: 100];
if (weight < FC_WEIGHT_ULTRALIGHT)
{
case FC_WEIGHT_LIGHT:
[style appendString: @"Light"];
nsweight = 3;
break;
case FC_WEIGHT_MEDIUM:
nsweight = 6;
break;
case FC_WEIGHT_DEMIBOLD:
[style appendString: @"Demibold"];
nsweight = 7;
break;
case FC_WEIGHT_BOLD:
[style appendString: @"Bold"];
nsweight = 9;
nstraits |= NSBoldFontMask;
break;
case FC_WEIGHT_BLACK:
[style appendString: @"Black"];
nsweight = 12;
nstraits |= NSBoldFontMask;
break;
default:
nsweight = 6;
[style appendString: @"Thin"];
nsweight = 1 + convertWeight (weight, FC_WEIGHT_THIN, FC_WEIGHT_ULTRALIGHT);
}
else if (weight < FC_WEIGHT_LIGHT)
{
[style appendString: @"Ultralight"];
nsweight = 2 + convertWeight (weight, FC_WEIGHT_ULTRALIGHT, FC_WEIGHT_LIGHT);
}
else if (weight < FC_WEIGHT_BOOK)
{
[style appendString: @"Light"];
nsweight = 3 + convertWeight (weight, FC_WEIGHT_LIGHT, FC_WEIGHT_BOOK);
}
else if (weight < FC_WEIGHT_REGULAR)
{
[style appendString: @"Book"];
nsweight = 4 + convertWeight (weight, FC_WEIGHT_BOOK, FC_WEIGHT_REGULAR);
}
else if (weight < FC_WEIGHT_MEDIUM)
{
nsweight = 5 + convertWeight (weight, FC_WEIGHT_REGULAR, FC_WEIGHT_MEDIUM);
}
else if (weight < FC_WEIGHT_DEMIBOLD)
{
[style appendString: @"Medium"];
nsweight = 6 + convertWeight (weight, FC_WEIGHT_MEDIUM, FC_WEIGHT_DEMIBOLD);
}
else if (weight < FC_WEIGHT_BOLD)
{
[style appendString: @"Demibold"];
nsweight = 7 + convertWeight (weight, FC_WEIGHT_DEMIBOLD, FC_WEIGHT_BOLD);
}
else if (weight < FC_WEIGHT_ULTRABOLD)
{
[style appendString: @"Bold"];
nsweight = 9 + convertWeight (weight, FC_WEIGHT_BOLD, FC_WEIGHT_ULTRABOLD);
nstraits |= NSBoldFontMask;
}
else if (weight < FC_WEIGHT_BLACK)
{
[style appendString: @"Ultrabold"];
nsweight = 11 + convertWeight (weight, FC_WEIGHT_ULTRABOLD, FC_WEIGHT_BLACK);
nstraits |= NSBoldFontMask;
}
else if (weight < FC_WEIGHT_ULTRABLACK)
{
[style appendString: @"Black"];
nsweight = 12 + convertWeight (weight, FC_WEIGHT_BLACK, FC_WEIGHT_ULTRABLACK);
nstraits |= NSBoldFontMask;
}
else
{
[style appendString: @"Ultrablack"];
nsweight = 13 + convertWeight (weight, FC_WEIGHT_ULTRABLACK, FC_WEIGHT_ULTRABLACK + 20);
nstraits |= NSBoldFontMask;
}
if (FcPatternGetInteger(pat, FC_WIDTH, 0, &width) == FcResultMatch)
{
if (width < FC_WIDTH_EXTRACONDENSED)
{
[style appendString: @"Ultracondensed"];
nstraits |= NSCondensedFontMask;
}
else if (width < FC_WIDTH_CONDENSED)
{
[style appendString: @"Extracondensed"];
nstraits |= NSCondensedFontMask;
}
else if (width < FC_WIDTH_SEMICONDENSED)
{
[style appendString: @"Condensed"];
nstraits |= NSCondensedFontMask;
}
else if (width < FC_WIDTH_SEMIEXPANDED)
{
// do nothing, this is "regular"
}
else if (width < FC_WIDTH_EXPANDED)
{
[style appendString: @"Semiexpanded"];
nstraits |= NSExpandedFontMask;
}
else if (width < FC_WIDTH_EXTRAEXPANDED)
{
[style appendString: @"Expanded"];
nstraits |= NSExpandedFontMask;
}
else if (width < FC_WIDTH_ULTRAEXPANDED)
{
[style appendString: @"Extraexpanded"];
nstraits |= NSExpandedFontMask;
}
else
{
[style appendString: @"Ultraexpanded"];
nstraits |= NSExpandedFontMask;
}
}
switch (slant)
@ -138,19 +306,41 @@ static NSArray *faFromFc(FcPattern *pat)
break;
}
if ([style length] > 0)
if (styleStr == nil)
{
[name appendString: @"-"];
[name appendString: style];
styleStr = (NSString *)style;
}
else
if (![styleStr length])
{
[style appendString: @"Roman"];
styleStr = @"Regular";
}
#ifdef FC_POSTSCRIPT_NAME
if (FcPatternGetString(pat, FC_POSTSCRIPT_NAME, 0, (FcChar8 **)&fcname) == FcResultMatch)
{
name = [NSString stringWithUTF8String: fcname];
}
#endif
if (!name || ![name length]) // no psname
{
NSMutableString *tmpStr;
tmpStr = [NSMutableString stringWithCapacity: 100];
NSDebugLLog(@"NSFont", @"Warning: synthesizing PSName for '%@ %@'", family, styleStr);
[tmpStr appendString: family];
if ([styleStr length] > 0 && ![styleStr isEqualToString: @"Regular"])
{
[tmpStr appendString: @"-"];
[tmpStr appendString: styleStr];
}
name = [NSString stringWithString: tmpStr];
}
return [NSArray arrayWithObjects: name,
style,
[NSNumber numberWithInt: nsweight],
styleStr,
[NSNumber numberWithFloat: nsweight],
[NSNumber numberWithUnsignedInt: nstraits],
nil];
}
@ -164,7 +354,11 @@ static NSArray *faFromFc(FcPattern *pat)
Class faceInfoClass = [[self class] faceInfoClass];
FcPattern *pat = FcPatternCreate();
FcObjectSet *os = FcObjectSetBuild(FC_FAMILY, FC_SLANT, FC_WEIGHT,
FcObjectSet *os = FcObjectSetBuild(FC_FAMILY, FC_STYLE, FC_FULLNAME,
#ifdef FC_POSTSCRIPT_NAME
FC_POSTSCRIPT_NAME,
#endif
FC_SLANT, FC_WEIGHT, FC_WIDTH,
FC_SPACING, NULL);
FcFontSet *fs = FcFontList(NULL, pat, os);
@ -182,30 +376,36 @@ static NSArray *faFromFc(FcPattern *pat)
if ((fontArray = faFromFc(fs->fonts[i])))
{
NSString *familyString;
NSMutableArray *familyArray;
FCFaceInfo *aFont;
NSString *name = [fontArray objectAtIndex: 0];
familyString = [NSString stringWithUTF8String: family];
familyArray = [fcxft_allFontFamilies objectForKey: familyString];
if (familyArray == nil)
if (![fcxft_allFontNames containsObject: name])
{
NSDebugLLog(@"NSFont", @"Found font family %@", familyString);
familyArray = [[NSMutableArray alloc] init];
[fcxft_allFontFamilies setObject: familyArray
forKey: familyString];
RELEASE(familyArray);
NSString *familyString;
NSMutableArray *familyArray;
FCFaceInfo *aFont;
familyString = [NSString stringWithUTF8String: family];
familyArray = [fcxft_allFontFamilies objectForKey: familyString];
if (familyArray == nil)
{
NSDebugLLog(@"NSFont", @"Found font family %@", familyString);
familyArray = [[NSMutableArray alloc] init];
[fcxft_allFontFamilies setObject: familyArray
forKey: familyString];
RELEASE(familyArray);
}
NSDebugLLog(@"NSFont", @"fc enumerator: adding font: %@", name);
[familyArray addObject: fontArray];
[fcxft_allFontNames addObject: name];
aFont = [[faceInfoClass alloc] initWithfamilyName: familyString
weight: [[fontArray objectAtIndex: 2] floatValue]
traits: [[fontArray objectAtIndex: 3] unsignedIntValue]
pattern: fs->fonts[i]];
[fcxft_allFonts setObject: aFont forKey: name];
RELEASE(aFont);
}
NSDebugLLog(@"NSFont", @"fc enumerator: adding font: %@", name);
[familyArray addObject: fontArray];
[fcxft_allFontNames addObject: name];
aFont = [[faceInfoClass alloc] initWithfamilyName: familyString
weight: [[fontArray objectAtIndex: 2] intValue]
traits: [[fontArray objectAtIndex: 3] unsignedIntValue]
pattern: fs->fonts[i]];
[fcxft_allFonts setObject: aFont forKey: name];
RELEASE(aFont);
}
}
}
@ -214,75 +414,87 @@ static NSArray *faFromFc(FcPattern *pat)
allFontNames = fcxft_allFontNames;
allFontFamilies = fcxft_allFontFamilies;
__allFonts = fcxft_allFonts;
// Sort font families
{
NSComparisonResult (*fontSort)(id, id, void *) = sortFontFacesArray;
NSEnumerator *e = [allFontFamilies keyEnumerator];
id key;
while ((key = [e nextObject]))
{
[[allFontFamilies objectForKey: key] sortUsingFunction: fontSort context: NULL];
}
}
}
- (NSString *) defaultSystemFontName
{
if ([allFontNames containsObject: @"Bitstream Vera Sans"])
if ([allFontNames containsObject: @"DejaVuSans"])
{
return @"Bitstream Vera Sans";
return @"DejaVuSans";
}
if ([allFontNames containsObject: @"BitstreamVeraSans-Roman"])
{
return @"BitstreamVeraSans-Roman";
}
if ([allFontNames containsObject: @"FreeSans"])
{
return @"FreeSans";
}
if ([allFontNames containsObject: @"DejaVu Sans"])
{
return @"DejaVu Sans";
}
if ([allFontNames containsObject: @"Tahoma"])
{
return @"Tahoma";
}
if ([allFontNames containsObject: @"Arial"])
if ([allFontNames containsObject: @"ArialMT"])
{
return @"Arial";
return @"ArialMT";
}
return @"Helvetica";
}
- (NSString *) defaultBoldSystemFontName
{
if ([allFontNames containsObject: @"Bitstream Vera Sans-Bold"])
if ([allFontNames containsObject: @"DejaVuSans-Bold"])
{
return @"Bitstream Vera Sans-Bold";
return @"DejaVuSans-Bold";
}
if ([allFontNames containsObject: @"BitstreamVeraSans-Bold"])
{
return @"BitstreamVeraSans-Bold";
}
if ([allFontNames containsObject: @"FreeSans-Bold"])
{
return @"FreeSans-Bold";
}
if ([allFontNames containsObject: @"DejaVu Sans-Bold"])
{
return @"DejaVu Sans-Bold";
}
if ([allFontNames containsObject: @"Tahoma-Bold"])
{
return @"Tahoma-Bold";
}
if ([allFontNames containsObject: @"Arial-Bold"])
if ([allFontNames containsObject: @"Arial-BoldMT"])
{
return @"Arial-Bold";
return @"Arial-BoldMT";
}
return @"Helvetica-Bold";
}
- (NSString *) defaultFixedPitchFontName
{
if ([allFontNames containsObject: @"Bitstream Vera Sans Mono"])
if ([allFontNames containsObject: @"DejaVuSansMono"])
{
return @"Bitstream Vera Sans Mono";
return @"DejaVuSansMono";
}
if ([allFontNames containsObject: @"BitstreamVeraSansMono-Roman"])
{
return @"BitstreamVeraSansMono-Roman";
}
if ([allFontNames containsObject: @"FreeMono"])
{
return @"FreeMono";
}
if ([allFontNames containsObject: @"DejaVu Sans Mono"])
if ([allFontNames containsObject: @"CourierNewPSMT"])
{
return @"DejaVu Sans Mono";
}
if ([allFontNames containsObject: @"Courier New"])
{
return @"Courier New";
return @"CourierNewPSMT";
}
return @"Courier";
}
@ -347,18 +559,19 @@ static NSArray *faFromFc(FcPattern *pat)
@end
@implementation FontconfigPatternGenerator
- (void)addName: (NSString*)name
{
#ifdef FC_POSTSCRIPT_NAME
FcPatternAddString(_pat, FC_POSTSCRIPT_NAME, (const FcChar8 *)[name UTF8String]);
#else
// FIXME: Fontconfig ignores PostScript names of fonts; we need
// https://bugs.freedesktop.org/show_bug.cgi?id=18095 fixed.
// This is a heuristic to try to 'parse' a PostScript font name,
// however, since they are just unique identifiers for fonts and
// don't need to follow any naming convention, this may fail
NSRange dash = [name rangeOfString: @"-"];
if (dash.location == NSNotFound)
{
@ -410,6 +623,7 @@ static NSArray *faFromFc(FcPattern *pat)
FcPatternAddInteger(_pat, FC_WIDTH, FC_WIDTH_EXPANDED);
}
}
#endif
}
- (void)addVisibleName: (NSString*)name
@ -467,7 +681,7 @@ static NSArray *faFromFc(FcPattern *pat)
}
if (symTraits & NSFontVerticalTrait)
{
// FIXME: What is this supposed to mean?
// Fontconfig can't express this (it means sideways letters)
}
if (symTraits & NSFontUIOptimizedTrait)
{
@ -683,20 +897,27 @@ static NSArray *faFromFc(FcPattern *pat)
- (NSString*)readNameFromPattern: (FcPattern*)pat
{
// FIXME: Hack which generates a PostScript-style name from the
// family name and style
#ifdef FC_POSTSCRIPT_NAME
NSString *name = [self readFontconfigString: FC_POSTSCRIPT_NAME fromPattern: pat];
#endif
NSString *family = [self readFontconfigString: FC_FAMILY fromPattern: pat];
NSString *style = [self readFontconfigString: FC_STYLE fromPattern: pat];
if (style)
{
return [NSString stringWithFormat: @"%@-%@", family, style];
}
#ifdef FC_POSTSCRIPT_NAME
if (name)
return name;
else
{
return family;
}
#endif
if (style)
{
return [NSString stringWithFormat: @"%@-%@", family, style];
}
else
{
return family;
}
}
- (NSString*)readVisibleNameFromPattern: (FcPattern*)pat
{
// FIXME: try to get the localized one
@ -721,7 +942,7 @@ static NSArray *faFromFc(FcPattern *pat)
int value;
if (FcResultMatch == FcPatternGetInteger(pat, FC_SLANT, 0, &value))
{
if (value == FC_SLANT_ITALIC)
if (value > FC_SLANT_ROMAN)
{
symTraits |= NSFontItalicTrait;
}

View file

@ -149,6 +149,11 @@
return NSZeroRect;
}
- (NSString *) displayName
{
return [_faceInfo displayName];
}
- (CGFloat) widthOfString: (NSString *)string
{
[self subclassResponsibility: _cmd];

View file

@ -37,7 +37,7 @@ ADDITIONAL_CPPFLAGS += -Wall $(CONFIG_SYSTEM_DEFS)
#ADDITIONAL_CFLAGS =
# Additional include directories the compiler should search
ADDITIONAL_INCLUDE_DIRS = -I../../Headers -I../$(GNUSTEP_TARGET_DIR)
ADDITIONAL_INCLUDE_DIRS += -I../../Headers -I../$(GNUSTEP_TARGET_DIR)
# Additional LDFLAGS to pass to the linker
#ADDITIONAL_LDFLAGS =

View file

@ -130,10 +130,14 @@
in the current color */
- (void) setColor: (device_color_t *)color state: (color_state_t)cState
{
if (cState & COLOR_FILL)
fillColor = *color;
if (cState & COLOR_STROKE)
strokeColor = *color;
if ((cState & COLOR_FILL) && (&fillColor != color))
{
fillColor = *color;
}
if ((cState & COLOR_STROKE) && (&strokeColor != color))
{
strokeColor = *color;
}
cstate = cState;
DESTROY(pattern);
}

View file

@ -0,0 +1,48 @@
#
# Main makefile for GNUstep Headless Backend
#
# Copyright (C) 2002 Free Software Foundation, Inc.
#
# Author: Adam Fedor <fedor@gnu.org>
#
# This file is part of the GNUstep Backend.
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This library 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
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; see the file COPYING.LIB.
# If not, see <http://www.gnu.org/licenses/> or write to the
# Free Software Foundation, 51 Franklin Street, Fifth Floor,
PACKAGE_NAME = gnustep-back
GNUSTEP_LOCAL_ADDITIONAL_MAKEFILES=../../back.make
include $(GNUSTEP_MAKEFILES)/common.make
include ../../config.make
# The library to be compiled, as a library or as a bundle
SUBPROJECT_NAME=headless
# The Objective-C source files to be compiled
headless_OBJC_FILES = \
HeadlessContext.m \
HeadlessServer.m \
HeadlessFontInfo.m \
HeadlessFontEnumerator.m \
HeadlessFaceInfo.m \
HeadlessGState.m
-include GNUmakefile.preamble
include $(GNUSTEP_MAKEFILES)/subproject.make
-include GNUmakefile.postamble

View file

@ -0,0 +1,51 @@
#
# GNUmakefile.preamble
#
# Copyright (C) 2002 Free Software Foundation, Inc.
#
# Author: Adam Fedor <fedor@gnu.org>
#
# This file is part of the GNUstep Backend.
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This library 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
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; see the file COPYING.LIB.
# If not, see <http://www.gnu.org/licenses/> or write to the
# Free Software Foundation, 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301, USA.
#
# Flags dealing with compiling and linking
#
# Additional flags to pass to the preprocessor
ADDITIONAL_CPPFLAGS += -Wall $(CONFIG_SYSTEM_DEFS)
# Additional flags to pass to the Objective-C compiler
ADDITIONAL_OBJCFLAGS =
# Additional flags to pass to the C compiler
ADDITIONAL_CFLAGS =
# Additional include directories the compiler should search
ADDITIONAL_INCLUDE_DIRS += -I../../Headers \
-I../$(GNUSTEP_TARGET_DIR) $(GRAPHIC_CFLAGS)
# Additional LDFLAGS to pass to the linker
ADDITIONAL_LDFLAGS =
# Additional library directories the linker should search
ADDITIONAL_LIB_DIRS =
#
# Flags dealing with installing and uninstalling
#

View file

@ -0,0 +1,45 @@
/*
HeadlessContext.m
Copyright (C) 2003, 2023 Free Software Foundation, Inc.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; see the file COPYING.LIB.
If not, see <http://www.gnu.org/licenses/> or write to the
Free Software Foundation, 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "config.h"
#include "headless/HeadlessContext.h"
#include "headless/HeadlessFontInfo.h"
#include "headless/HeadlessFontEnumerator.h"
#include "headless/HeadlessGState.h"
@implementation HeadlessContext
+ (void) initializeBackend
{
[NSGraphicsContext setDefaultContextClass: self];
[GSFontEnumerator setDefaultClass: [HeadlessFontEnumerator class]];
[GSFontInfo setDefaultClass: [HeadlessFontInfo class]];
}
+ (Class) GStateClass
{
return [HeadlessGState class];
}
@end

View file

@ -0,0 +1,44 @@
/*
HeadlessFaceInfo.m
Copyright (C) 2003, 2023 Free Software Foundation, Inc.
Based on work by: Marcian Lytwyn <gnustep@advcsi.com> for Keysight
Based on work by: Banlu Kemiyatorn <object at gmail dot com>
Based on work by: Alex Malmberg
Based on work by: Fred Kiefer <fredkiefer@gmx.de>
This file is part of GNUstep.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; see the file COPYING.LIB.
If not, see <http://www.gnu.org/licenses/> or write to the
Free Software Foundation, 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "headless/HeadlessFaceInfo.h"
@implementation HeadlessFaceInfo
- (void) dealloc
{
[super dealloc];
}
- (void *)fontFace
{
return _fontFace;
}
@end

View file

@ -0,0 +1,47 @@
/*
HeadlessFontEnumerator.m
Copyright (C) 2003, 2023 Free Software Foundation, Inc.
Based on work by: Marcian Lytwyn <gnustep@advcsi.com> for Keysight
Based on work by: Banlu Kemiyatorn <object at gmail dot com>
Based on work by: Alex Malmberg
Based on work by: Fred Kiefer <fredkiefer@gmx.de>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; see the file COPYING.LIB.
If not, see <http://www.gnu.org/licenses/> or write to the
Free Software Foundation, 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "headless/HeadlessFontEnumerator.h"
#include "headless/HeadlessFontInfo.h"
@implementation HeadlessFontEnumerator
+ (Class) faceInfoClass
{
return [HeadlessFaceInfo class];
}
+ (HeadlessFaceInfo *) fontWithName: (NSString *) name
{
return (HeadlessFaceInfo *) [super fontWithName: name];
}
- (void)enumerateFontsAndFamilies
{
}
@end

View file

@ -0,0 +1,87 @@
/*
HeadlessFontInfo.m
Copyright (C) 2003, 2023 Free Software Foundation, Inc.
Based on work by: Marcian Lytwyn <gnustep@advcsi.com> for Keysight
Based on work by: Banlu Kemiyatorn <object at gmail dot com>
Based on work by: Alex Malmberg
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; see the file COPYING.LIB.
If not, see <http://www.gnu.org/licenses/> or write to the
Free Software Foundation, 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "GNUstepBase/Unicode.h"
#include <AppKit/NSAffineTransform.h>
#include <AppKit/NSBezierPath.h>
#include "headless/HeadlessFontInfo.h"
#include "headless/HeadlessFontEnumerator.h"
#include <math.h>
@implementation HeadlessFontInfo
- (id) initWithFontName: (NSString *)name
matrix: (const CGFloat *)fmatrix
screenFont: (BOOL)p_screenFont
{
self = [super init];
if (!self)
return nil;
#ifndef _MSC_VER
// Accessing instance variables across module boundaries is not supported by the Visual Studio
// toolchain; this could be implemented using e.g. setFontName: and setMatrix: method on the
// base case.
fontName = [name copy];
memcpy(matrix, fmatrix, sizeof(matrix));
#endif
return self;
}
- (void) dealloc
{
[super dealloc];
}
- (BOOL) glyphIsEncoded: (NSGlyph)glyph
{
return NO;
}
- (NSSize) advancementForGlyph: (NSGlyph)glyph
{
return NSZeroSize;
}
- (NSRect) boundingRectForGlyph: (NSGlyph)glyph
{
return NSZeroRect;
}
- (CGFloat) widthOfString: (NSString *)string
{
return 0.0;
}
- (void) appendBezierPathWithGlyphs: (NSGlyph *)glyphs
count: (int)length
toBezierPath: (NSBezierPath *)path
{
}
@end

View file

@ -0,0 +1,72 @@
/*
HeadlessGState.m
Copyright (C) 2003, 2023 Free Software Foundation, Inc.
Based on work by: Marcian Lytwyn <gnustep@advcsi.com> for Keysight
Based on work by: Banlu Kemiyatorn <object at gmail dot com>
Based on work by: Fred Kiefer <fredkiefer@gmx.de>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; see the file COPYING.LIB.
If not, see <http://www.gnu.org/licenses/> or write to the
Free Software Foundation, 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "headless/HeadlessGState.h"
@implementation HeadlessGState
- (void) DPSclip
{
}
- (void) DPSfill
{
}
- (void) DPSsetlinewidth: (CGFloat)width
{
}
- (void) DPSsetdash: (const CGFloat *)pat : (NSInteger)size : (CGFloat)foffset
{
}
- (void) DPSimage: (NSAffineTransform *)matrix : (NSInteger)pixelsWide
: (NSInteger)pixelsHigh : (NSInteger)bitsPerSample
: (NSInteger)samplesPerPixel : (NSInteger)bitsPerPixel
: (NSInteger)bytesPerRow : (BOOL)isPlanar
: (BOOL)hasAlpha : (NSString *)colorSpaceName
: (const unsigned char *const[5])data
{
}
- (void) DPSstroke
{
}
- (void) compositerect: (NSRect)aRect op: (NSCompositingOperation)op
{
}
- (void) compositeGState: (HeadlessGState *)source
fromRect: (NSRect)srcRect
toPoint: (NSPoint)destPoint
op: (NSCompositingOperation)op
fraction: (CGFloat)delta
{
}
@end

View file

@ -0,0 +1,115 @@
/*
HeadlessServer.m
Copyright (C) 1998,2002,2023 Free Software Foundation, Inc.
Based on work by: Marcian Lytwyn <gnustep@advcsi.com> for Keysight
Based on work by: Adam Fedor <fedor@gnu.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; see the file COPYING.LIB.
If not, see <http://www.gnu.org/licenses/> or write to the
Free Software Foundation, 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "config.h"
#include <AppKit/NSApplication.h>
#include <Foundation/NSDebug.h>
#include <Foundation/NSValue.h>
#include "headless/HeadlessServer.h"
/* Terminate cleanly if we get a signal to do so */
static void
terminate(int sig)
{
if (nil != NSApp)
{
[NSApp terminate: NSApp];
}
else
{
exit(1);
}
}
@implementation HeadlessServer
/* Initialize AppKit backend */
+ (void) initializeBackend
{
NSDebugLog(@"Initializing GNUstep headless backend.\n");
[GSDisplayServer setDefaultServerClass: [HeadlessServer class]];
signal(SIGTERM, terminate);
signal(SIGINT, terminate);
}
- (NSArray *)screenList
{
NSDebugLog(@"GNUstep headless - fetching screen list");
NSMutableArray *screens = [NSMutableArray arrayWithCapacity: 1];
[screens addObject: [NSNumber numberWithInt: 1]];
return screens;
}
- (NSRect) boundsForScreen: (int)screen
{
return NSMakeRect(0, 0, 400, 400);
}
- (NSWindowDepth) windowDepthForScreen: (int) screen_num
{
return 0;
}
- (void) styleoffsets: (float *) l : (float *) r : (float *) t : (float *) b
: (unsigned int) style
{
}
- (void) standardcursor: (int)style : (void **)cid
{
}
- (int) window: (NSRect)frame
: (NSBackingStoreType)type
: (unsigned int)style
: (int)screen
{
return 1;
}
- (void) setwindowlevel: (int)level : (int)win
{
}
- (void) setWindowdevice: (int)win forContext: (NSGraphicsContext *)ctxt
{
}
- (void) orderwindow: (int)op : (int)otherWin : (int)winNum
{
}
- (void) setinputfocus: (int)win
{
}
- (void) imagecursor: (NSPoint)hotp : (NSImage *)image : (void **)cid
{
}
@end

View file

@ -115,9 +115,21 @@
#endif // XSHM
#endif // BUILD_SERVER = SERVER_x11
@end
- (id) initWithGraphicsPort: (void *)port
flipped: (BOOL)flag;
{
self = [super initWithGraphicsPort: port
flipped: flag];
if (self != nil)
{
[self GSSetDevice: NULL : -1 : -1];
}
return self;
}
@implementation OpalContext (Ops)
@end
@implementation OpalContext (Ops)
- (BOOL) isCompatibleBitmap: (NSBitmapImageRep*)bitmap
{
@ -167,7 +179,7 @@
: (int)y
{
OpalSurface *surface;
/*
* The "graphics port" associated to an OpalContext is necessarily a
* CGContextRef supplied by the client to back the OpalContext, instead
@ -181,6 +193,12 @@
CGContextRef suppliedContext = self->_graphicsPort;
surface = [[OpalSurface alloc] initWithDevice: device
context: suppliedContext];
if (x == -1 && y == -1)
{
NSSize size = [surface size];
x = 0;
y = size.height;
}
[OGSTATE GSSetSurface: surface
: x

View file

@ -55,6 +55,13 @@ static inline NSPoint _NSPointFromCGPoint(CGPoint cgpoint)
@implementation OpalGState
- (void) dealloc
{
RELEASE(_opalSurface);
RELEASE(_opGState);
[super dealloc];
}
- (id)copyWithZone: (NSZone *)zone
{
NSDebugLLog(@"OpalGState", @"%p (%@): %s", self, [self class], __PRETTY_FUNCTION__);
@ -82,65 +89,64 @@ static inline NSPoint _NSPointFromCGPoint(CGPoint cgpoint)
[super setOffset: theOffset];
}
- (void) setColor: (device_color_t *)color state: (color_state_t)cState
{
CGContextRef cgctx = CGCTX;
NSDebugLLog(@"OpalGState", @"%p (%@): %s", self, [self class], __PRETTY_FUNCTION__);
if (cgctx)
{
if (color->space == hsb_colorspace)
{
gsColorToRGB(color);
}
if (color->space == gray_colorspace)
{
if (cState & COLOR_STROKE)
{
CGContextSetGrayStrokeColor(cgctx, color->field[0], color->field[AINDEX]);
}
if (cState & COLOR_FILL)
{
CGContextSetGrayFillColor(cgctx, color->field[0], color->field[AINDEX]);
}
}
else if (color->space == rgb_colorspace)
{
if (cState & COLOR_STROKE)
{
CGContextSetRGBStrokeColor(cgctx, color->field[0], color->field[1],
color->field[2], color->field[AINDEX]);
}
if (cState & COLOR_FILL)
{
CGContextSetRGBFillColor(cgctx, color->field[0], color->field[1],
color->field[2], color->field[AINDEX]);
}
}
else if (color->space == cmyk_colorspace)
{
if (cState & COLOR_STROKE)
{
CGContextSetCMYKStrokeColor(cgctx, color->field[0], color->field[1],
color->field[2], color->field[3], color->field[AINDEX]);
}
if (cState & COLOR_FILL)
{
CGContextSetCMYKFillColor(cgctx, color->field[0], color->field[1],
color->field[2], color->field[3], color->field[AINDEX]);
}
}
}
[super setColor: color state: cState];
}
@end
@implementation OpalGState (Ops)
- (void) DPSsetalpha: (CGFloat)a
{
NSDebugLLog(@"OpalGState", @"%p (%@): %s - alpha %g", self, [self class], __PRETTY_FUNCTION__, a);
CGContextRef cgctx = CGCTX;
if (cgctx)
{
CGContextSetAlpha(cgctx, a);
}
[super DPSsetalpha: a];
}
- (void) DPSsetgray: (CGFloat)gray
{
NSDebugLLog(@"OpalGState", @"%p (%@): %s", self, [self class], __PRETTY_FUNCTION__);
CGContextRef cgctx = CGCTX;
const CGFloat alpha = 1.0; // TODO: is this correct?
if (cgctx)
{
CGContextSetGrayStrokeColor(cgctx, gray, alpha);
CGContextSetGrayFillColor(cgctx, gray, alpha);
}
[super DPSsetgray: gray];
}
- (void) DPSsetrgbcolor: (CGFloat)r : (CGFloat)g : (CGFloat)b
{
NSDebugLLog(@"OpalGState", @"%p (%@): %s", self, [self class], __PRETTY_FUNCTION__);
CGContextRef cgctx = CGCTX;
const CGFloat alpha = 1.0; // TODO: is this correct?
if (cgctx)
{
CGContextSetRGBStrokeColor(cgctx, r, g, b, alpha);
CGContextSetRGBFillColor(cgctx, r, g, b, alpha);
}
[super DPSsetrgbcolor: r : g : b];
}
- (void) DPSsetcmykcolor: (CGFloat)c : (CGFloat)m : (CGFloat)y : (CGFloat)k
{
NSDebugLLog(@"OpalGState", @"%p (%@): %s", self, [self class], __PRETTY_FUNCTION__);
CGContextRef cgctx = CGCTX;
const CGFloat alpha = 1.0; // TODO: is this correct?
if (cgctx)
{
CGContextSetCMYKFillColor(cgctx, c, m, y, k, alpha);
CGContextSetCMYKStrokeColor(cgctx, c, m, y, k, alpha);
}
[super DPSsetcmykcolor: c : m : y : k];
}
- (void) DPSshow: (const char *)s
{
NSDebugLLog(@"OpalGState", @"%p (%@): %s", self, [self class], __PRETTY_FUNCTION__);
@ -1081,16 +1087,20 @@ doesn't support to use the receiver cairo target as the source. */
- (void *) saveClip
{
NSDebugLLog(@"OpalGState", @"%p (%@): %s", self, [self class], __PRETTY_FUNCTION__);
CGRect * r = calloc(sizeof(CGRect), 1);
CGRect *r = calloc(sizeof(CGRect), 1);
*r = CGContextGetClipBoundingBox(CGCTX);
return r;
}
- (void) restoreClip: (void *)savedClip
{
CGRect *r = (CGRect *)savedClip;
NSDebugLLog(@"OpalGState", @"%p (%@): %s", self, [self class], __PRETTY_FUNCTION__);
OPContextResetClip(CGCTX);
CGContextClipToRect(CGCTX, *(CGRect *)savedClip);
if (!CGRectIsNull(*r))
{
CGContextClipToRect(CGCTX, *r);
}
free(savedClip);
}

View file

@ -72,6 +72,8 @@ static CGContextRef createCGBitmapContext(int pixelsWide,
- (void) createCGContextsWithSuppliedBackingContext: (CGContextRef)ctx
{
int pixelsWide;
int pixelsHigh;
// FIXME: this method and class presumes we are being passed
// a window device.
@ -80,10 +82,26 @@ static CGContextRef createCGBitmapContext(int pixelsWide,
NSLog(@"FIXME: Replacement of OpalSurface %p's CGContexts (x11=%p,backing=%p) without transfer of gstate", self, _x11CGContext, _backingCGContext);
}
Display * display = _gsWindowDevice->display;
Window window = _gsWindowDevice->ident;
if (ctx)
{
_x11CGContext = ctx;
pixelsWide = CGBitmapContextGetWidth(ctx);
pixelsHigh = CGBitmapContextGetHeight(ctx);
}
else
{
Display * display = _gsWindowDevice->display;
Window window = _gsWindowDevice->ident;
_x11CGContext = ctx ?: OPX11ContextCreate(display, window);
_x11CGContext = OPX11ContextCreate(display, window);
pixelsWide = _gsWindowDevice->buffer_width;
pixelsHigh = _gsWindowDevice->buffer_height;
// Ask XGServerWindow to call +[OpalContext handleExposeRect:forDriver:]
// to let us handle the back buffer -> front buffer copy using Opal.
_gsWindowDevice->gdriverProtocol |= GDriverHandlesExpose | GDriverHandlesBacking;
_gsWindowDevice->gdriver = self;
}
#if 0
if (_gsWindowDevice->type == NSBackingStoreNonretained)
@ -98,19 +116,11 @@ static CGContextRef createCGBitmapContext(int pixelsWide,
{
// Do double-buffer:
// Create a similar surface to the window which supports alpha
// Ask XGServerWindow to call +[OpalContext handleExposeRect:forDriver:]
// to let us handle the back buffer -> front buffer copy using Opal.
_gsWindowDevice->gdriverProtocol |= GDriverHandlesExpose | GDriverHandlesBacking;
_gsWindowDevice->gdriver = self;
_backingCGContext = createCGBitmapContext(
_gsWindowDevice->buffer_width,
_gsWindowDevice->buffer_height);
_backingCGContext = createCGBitmapContext(pixelsWide, pixelsHigh);
}
NSDebugLLog(@"OpalSurface", @"Created CGContexts: X11=%p, backing=%p, width=%d height=%d",
_x11CGContext, _backingCGContext, _gsWindowDevice->buffer_width, _gsWindowDevice->buffer_height);
_x11CGContext, _backingCGContext, pixelsWide, pixelsHigh);
}
@ -155,6 +165,11 @@ static CGContextRef createCGBitmapContext(int pixelsWide,
{
NSDebugLLog(@"OpalSurface", @"handleExposeRect %@", NSStringFromRect(rect));
if (!_backingCGContext)
{
return;
}
CGImageRef backingImage = CGBitmapContextCreateImage(_backingCGContext);
if (!backingImage) // FIXME: writing a nil image fails with Opal
return;
@ -222,8 +237,8 @@ static CGContextRef createCGBitmapContext(int pixelsWide,
- (NSSize) size
{
return NSMakeSize(_gsWindowDevice->buffer_width,
_gsWindowDevice->buffer_height);
return NSMakeSize(CGBitmapContextGetWidth(_backingCGContext),
CGBitmapContextGetHeight(_backingCGContext));
}
@end

View file

@ -0,0 +1,59 @@
#
# Main makefile for GNUstep Backend wayland
#
# Copyright (C) 2020 Free Software Foundation, Inc.
#
# Author: Adam Fedor <fedor@gnu.org>
# Author: Sergio L. Pascual <slp@sinrega.org>
# Author: Ladislav Michl <ladis@linux-mips.org>
#
# This file is part of the GNUstep Backend.
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This library 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
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; see the file COPYING.LIB.
# If not, see <http://www.gnu.org/licenses/> or write to the
# Free Software Foundation, 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301, USA.
PACKAGE_NAME = gnustep-back
GNUSTEP_LOCAL_ADDITIONAL_MAKEFILES=../../back.make
include $(GNUSTEP_MAKEFILES)/common.make
include ../../config.make
# The library to be compiled, as a library or as a bundle
SUBPROJECT_NAME=wayland
wayland_LOCALIZED_RESOURCE_FILES = \
# The C source files to be compiled
wayland_C_FILES = \
xdg-shell-protocol.c \
wlr-layer-shell-protocol.c \
# The Objective-C source files to be compiled
wayland_OBJC_FILES = \
WaylandServer.m \
WaylandServer+Output.m \
WaylandServer+Cursor.m \
WaylandServer+Keyboard.m \
WaylandServer+Seat.m \
WaylandServer+Xdgshell.m \
WaylandServer+Layershell.m \
-include GNUmakefile.preamble
include $(GNUSTEP_MAKEFILES)/subproject.make
-include GNUmakefile.postamble

View file

@ -0,0 +1,52 @@
#
# GNUmakefile.preamble
#
# Copyright (C) 2020 Free Software Foundation, Inc.
#
# Author: Adam Fedor <fedor@gnu.org>
# Author: Sergio L. Pascual <slp@sinrega.org>
#
# This file is part of the GNUstep Backend.
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This library 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
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; see the file COPYING.LIB.
# If not, see <http://www.gnu.org/licenses/> or write to the
# Free Software Foundation, 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301, USA.
#
# Flags dealing with compiling and linking
#
# Additional flags to pass to the preprocessor
ADDITIONAL_CPPFLAGS += -Wall $(CONFIG_SYSTEM_DEFS)
# Additional flags to pass to the Objective-C compiler
ADDITIONAL_OBJCFLAGS =
# Additional flags to pass to the C compiler
ADDITIONAL_CFLAGS =
# Additional include directories the compiler should search
ADDITIONAL_INCLUDE_DIRS += -I../../Headers \
-I../$(GNUSTEP_TARGET_DIR) $(GRAPHIC_CFLAGS)
# Additional LDFLAGS to pass to the linker
ADDITIONAL_LDFLAGS =
# Additional library directories the linker should search
ADDITIONAL_LIB_DIRS =
#
# Flags dealing with installing and uninstalling
#

37
Source/wayland/README.md Normal file
View file

@ -0,0 +1,37 @@
# Wayland backend for GNUstep
This directory (along with `Headers/wayland/`, and a file in `Source/cairo/`
and `Headers/cairo`) contains the Wayland backend for GNUstep GUI. This
display server backend depends on Cairo graphics backend; it will currently
not work with any other combination.
As of April 2020, it is incomplete and broken. Help getting it functional will
be appreciated.
## Known issues
Last updated 25 April 2020:
* Under Weston, some backing Cairo surfaces, which should not be visible in
the compositor, are nonetheless drawn randomly onto the screen.
* Backing view surfaces may never get blitted onto the main window.
* After a while, Weston assumes that the application is not responding (there
is a spinner when hovering over the windows, and the surfaces can be
rotated by holding the right mouse button). Some events still get
delivered, visible in the debug output, but otherwise the application
appears frozen.
## Use on Debian
As of April 2020, it requires the stable XDG Shell protocol to be available in
the compositor you may be using. Weston included in Debian buster does _not_
include the stable XDG Shell protocol; this was only checked into Weston in
February 2019, and seemingly released with Weston 6, which does not ship in
Debian buster.
## Regenerating protocol files
To regenerate protocol sources from protocol IDLs in XML format, please use
`wayland-regenerate.sh`. Paths to the XML files are hardcoded to the values on
a Debian testing system.

View file

@ -0,0 +1,857 @@
/*
WaylandServer - Cursor Handling
Copyright (C) 2020 Free Software Foundation, Inc.
Author: Riccardo Canalicchio <riccardo.canalicchio(at)gmail.com>
Date: November 2021
This file is part of the GNU Objective C Backend Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; see the file COPYING.LIB.
If not, see <http://www.gnu.org/licenses/> or write to the
Free Software Foundation, 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "wayland/WaylandServer.h"
#include "cairo/WaylandCairoShmSurface.h"
#import <AppKit/NSEvent.h>
#import <AppKit/NSView.h>
#import <AppKit/NSWindow.h>
#import <AppKit/NSCursor.h>
#import <AppKit/NSGraphics.h>
#import <AppKit/NSBitmapImageRep.h>
#import <GNUstepGUI/GSWindowDecorationView.h>
#import <GNUstepGUI/GSTheme.h>
#include <linux/input.h>
#include "wayland-cursor.h"
extern void wl_cursor_destroy(struct wl_cursor *cursor);
// XXX should this be configurable by the user?
#define DOUBLECLICK_DELAY 300
#define DOUBLECLICK_MOVE_THREASHOLD 3
static void
pointer_handle_enter(void *data, struct wl_pointer *pointer, uint32_t serial,
struct wl_surface *surface, wl_fixed_t sx_w,
wl_fixed_t sy_w)
{
WaylandConfig *wlconfig = data;
struct window *window = wl_surface_get_user_data(surface);
if (window->ignoreMouse)
{
return;
}
wlconfig->pointer.focus = window;
if (wlconfig->pointer.captured)
{
return;
}
[(WaylandServer *)GSCurrentServer() initializeMouseIfRequired];
NSDebugLog(@"[%d] pointer_handle_enter",window->window_id);
float sx = wl_fixed_to_double(sx_w);
float sy = wl_fixed_to_double(sy_w);
if (window && wlconfig->pointer.serial)
{
NSEvent *event;
NSPoint eventLocation;
NSGraphicsContext *gcontext;
float deltaX = sx - wlconfig->pointer.x;
float deltaY = sy - wlconfig->pointer.y;
gcontext = GSCurrentContext();
eventLocation = NSMakePoint(sx, window->height - sy);
event = [NSEvent mouseEventWithType:NSMouseEntered
location:eventLocation
modifierFlags:wlconfig->modifiers
timestamp:wlconfig->pointer.last_timestamp
windowNumber:window->window_id
context:gcontext
eventNumber:serial
clickCount:0
pressure:0.0
buttonNumber:0
deltaX:deltaX
deltaY:deltaY
deltaZ:0.];
[GSCurrentServer() postEvent:event atStart:NO];
}
wlconfig->pointer.x = sx;
wlconfig->pointer.y = sy;
wlconfig->pointer.serial = serial;
wlconfig->event_serial = serial;
}
static void
pointer_handle_leave(void *data, struct wl_pointer *pointer, uint32_t serial,
struct wl_surface *surface)
{
WaylandConfig *wlconfig = data;
struct window *window = wl_surface_get_user_data(surface);
if (window->ignoreMouse)
{
return;
}
if (wlconfig->pointer.focus == NULL)
{
return;
}
[(WaylandServer *)GSCurrentServer() initializeMouseIfRequired];
if (wlconfig->pointer.focus->window_id == window->window_id
&& wlconfig->pointer.serial)
{
if (wlconfig->pointer.captured == NULL)
{
window = wlconfig->pointer.focus;
NSEvent *event;
NSPoint eventLocation;
NSGraphicsContext *gcontext;
gcontext = GSCurrentContext();
eventLocation = NSMakePoint(wlconfig->pointer.x, wlconfig->pointer.y);
event = [NSEvent mouseEventWithType:NSMouseExited
location:eventLocation
modifierFlags:0
timestamp:wlconfig->pointer.last_timestamp
windowNumber:window->window_id
context:gcontext
eventNumber:serial
clickCount:0
pressure:0.0
buttonNumber:0
deltaX:0
deltaY:0
deltaZ:0.];
[GSCurrentServer() postEvent:event atStart:NO];
}
wlconfig->pointer.focus = NULL;
wlconfig->pointer.serial = serial;
wlconfig->event_serial = serial;
}
}
// triggered when the cursor is over a surface
static void
pointer_handle_motion(void *data, struct wl_pointer *pointer, uint32_t time,
wl_fixed_t sx_w, wl_fixed_t sy_w)
{
WaylandConfig *wlconfig = data;
struct window *focused_window = wlconfig->pointer.focus;
if (wlconfig->pointer.captured)
{
focused_window = wlconfig->pointer.captured;
}
if (focused_window == NULL || focused_window->ignoreMouse)
{
return;
}
float sx = wl_fixed_to_double(sx_w);
float sy = wl_fixed_to_double(sy_w);
wlconfig->pointer.last_timestamp = (NSTimeInterval) time / 1000.0;
[(WaylandServer *)GSCurrentServer() initializeMouseIfRequired];
if (focused_window && wlconfig->pointer.serial)
{
NSEvent *event;
NSEventType eventType;
NSPoint eventLocation;
NSGraphicsContext *gcontext;
unsigned int eventFlags;
float deltaX = sx - wlconfig->pointer.x;
float deltaY = sy - wlconfig->pointer.y;
gcontext = GSCurrentContext();
eventLocation = NSMakePoint(sx, focused_window->height - sy);
eventFlags = wlconfig->modifiers;
eventType = NSMouseMoved;
if (wlconfig->pointer.button_state == WL_POINTER_BUTTON_STATE_PRESSED)
{
switch (wlconfig->pointer.button)
{
case BTN_LEFT:
eventType = NSLeftMouseDragged;
break;
case BTN_RIGHT:
eventType = NSRightMouseDragged;
break;
case BTN_MIDDLE:
eventType = NSOtherMouseDragged;
break;
}
}
event = [NSEvent mouseEventWithType:eventType
location:eventLocation
modifierFlags:eventFlags
timestamp:wlconfig->pointer.last_timestamp
windowNumber:(int) focused_window->window_id
context:gcontext
eventNumber:time
clickCount:0
pressure:1.0 // XXX should this be 0 when no button is pressed?
buttonNumber:wlconfig->pointer.button
deltaX:deltaX
deltaY:deltaY
deltaZ:0.];
[GSCurrentServer() postEvent:event atStart:NO];
}
wlconfig->pointer.x = sx;
wlconfig->pointer.y = sy;
}
static void
pointer_handle_button(void *data, struct wl_pointer *pointer, uint32_t serial,
uint32_t time, uint32_t button, uint32_t state_w)
{
WaylandConfig *wlconfig = data;
NSEvent *event;
NSEventType eventType;
NSPoint eventLocation;
NSGraphicsContext *gcontext;
unsigned int eventFlags;
float deltaX = 0.0;
float deltaY = 0.0;
int clickCount = 1;
int tick;
int buttonNumber;
enum wl_pointer_button_state state = state_w;
struct window *window = wlconfig->pointer.focus;
if (wlconfig->pointer.captured)
{
window = wlconfig->pointer.captured;
}
if (window == NULL || window->ignoreMouse)
{
return;
}
[(WaylandServer *)GSCurrentServer() initializeMouseIfRequired];
gcontext = GSCurrentContext();
eventLocation
= NSMakePoint(wlconfig->pointer.x, window->height - wlconfig->pointer.y);
eventFlags = wlconfig->modifiers;
NSTimeInterval timestamp = (NSTimeInterval) time / 1000.0;
if (state == WL_POINTER_BUTTON_STATE_PRESSED)
{
wlconfig->pointer.button = button;
if (window->toplevel)
{
// if the window is a toplevel we check if the event is for resizing or
// moving the window these actions are delegated to the compositor and
// therefore we skip forwarding the events to the NSWindow / NSView
NSWindow *nswindow = GSWindowWithNumber(window->window_id);
if (nswindow != nil)
{
GSStandardWindowDecorationView * wd = [nswindow _windowView];
if ([wd pointInTitleBarRect:eventLocation])
{
xdg_toplevel_move(window->toplevel, wlconfig->seat, serial);
window->moving = YES;
return;
}
if ([wd pointInResizeBarRect:eventLocation])
{
GSResizeEdgeMode mode = [wd resizeModeForPoint:eventLocation];
uint32_t edges = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_RIGHT;
if (mode == GSResizeEdgeBottomLeftMode)
{
edges = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_LEFT;
}
else if (mode == GSResizeEdgeBottomRightMode)
{
edges = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_RIGHT;
}
else if (mode == GSResizeEdgeBottomMode)
{
edges = XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM;
}
xdg_toplevel_resize(window->toplevel, wlconfig->seat, serial,
edges);
window->resizing = YES;
return;
}
} // endif nswindow != nil
} // endif window->toplevel
if (button == wlconfig->pointer.last_click_button
&& time - wlconfig->pointer.last_click_time < DOUBLECLICK_DELAY
&& fabsf(wlconfig->pointer.x - wlconfig->pointer.last_click_x)
< DOUBLECLICK_MOVE_THREASHOLD
&& fabsf(wlconfig->pointer.y - wlconfig->pointer.last_click_y)
< DOUBLECLICK_MOVE_THREASHOLD)
{
wlconfig->pointer.last_click_time = 0;
clickCount++;
}
else
{
wlconfig->pointer.last_click_button = button;
wlconfig->pointer.last_click_time = time;
wlconfig->pointer.last_click_x = wlconfig->pointer.x;
wlconfig->pointer.last_click_y = wlconfig->pointer.y;
}
wlconfig->pointer.serial = serial;
switch (button)
{
case BTN_LEFT:
eventType = NSLeftMouseDown;
break;
case BTN_RIGHT:
eventType = NSRightMouseDown;
break;
case BTN_MIDDLE:
eventType = NSOtherMouseDown;
break;
// TODO: handle BTN_SIDE, BTN_EXTRA, BTN_FORWARD, BTN_BACK and other
// constants in libinput.
// We may just want to send NSOtherMouseDown and populate buttonNumber
// with the libinput constant?
}
}
else if (state == WL_POINTER_BUTTON_STATE_RELEASED)
{
wlconfig->pointer.serial = 0;
wlconfig->pointer.button = 0;
if (window->moving)
{
window->moving = NO;
return;
}
if (window->resizing)
{
window->resizing = NO;
return;
}
switch (button)
{
case BTN_LEFT:
eventType = NSLeftMouseUp;
break;
case BTN_RIGHT:
eventType = NSRightMouseUp;
break;
case BTN_MIDDLE:
eventType = NSOtherMouseUp;
break;
}
}
else
{
return;
}
/* FIXME: unlike in _motion and _axis handlers, the argument used in _button
is the "serial" of the event, not passed and unavailable in _motion and
_axis handlers. Is it allowed to pass "serial" as the eventNumber: in
_button handler, but "time" as the eventNumber: in the _motion and _axis
handlers? */
tick = serial;
/* FIXME: X11 backend uses the XGetPointerMapping()-returned values from
its map_return argument as constants for buttonNumber. As the variant
with buttonNumber: seems to be a GNUstep extension, and the value
internal, it might be ok to just provide libinput constant as we're doing
here. If this is truly correct, please update this comment to document
the correctness of doing so. */
buttonNumber = button;
event = [NSEvent mouseEventWithType:eventType
location:eventLocation
modifierFlags:eventFlags
timestamp:timestamp
windowNumber:(int) window->window_id
context:gcontext
eventNumber:tick
clickCount:clickCount
pressure:1.0
buttonNumber:buttonNumber
deltaX:deltaX /* FIXME unused */
deltaY:deltaY /* FIXME unused */
deltaZ:0.];
[GSCurrentServer() postEvent:event atStart:NO];
// store button state for mouse move handlers
wlconfig->pointer.button_state = state;
wlconfig->pointer.last_timestamp = timestamp;
wlconfig->pointer.serial = serial;
wlconfig->event_serial = serial;
}
// Discrete step information for scroll and other axes.
static void
pointer_handle_frame(void *data, struct wl_pointer *pointer)
{}
// Source information for scroll and other axes.
static void
pointer_handle_axis_source(void *data, struct wl_pointer *pointer,
uint32_t axis_source)
{
WaylandConfig *wlconfig = data;
wlconfig->pointer.axis_source = axis_source;
}
// Stop notification for scroll and other axes.
static void
pointer_handle_axis_stop(void *data, struct wl_pointer *pointer, uint32_t time,
uint32_t axis)
{}
// Discrete step information for scroll and other axes.
static void
pointer_handle_axis_discrete(void *data, struct wl_pointer *pointer,
uint32_t axis, int discrete)
{}
// Scroll and other axis notifications.
static void
pointer_handle_axis(void *data, struct wl_pointer *pointer, uint32_t time,
uint32_t axis, wl_fixed_t value)
{
WaylandConfig *wlconfig = data;
NSEvent *event;
NSEventType eventType;
NSPoint eventLocation;
NSGraphicsContext *gcontext;
unsigned int eventFlags;
float deltaX = 0.0;
float deltaY = 0.0;
int clickCount = 1;
int buttonNumber;
struct window *window = wlconfig->pointer.focus;
if (window->ignoreMouse)
{
return;
}
[(WaylandServer *)GSCurrentServer() initializeMouseIfRequired];
gcontext = GSCurrentContext();
eventLocation
= NSMakePoint(wlconfig->pointer.x, window->height - wlconfig->pointer.y);
eventFlags = wlconfig->modifiers;
if (wlconfig->pointer.axis_source != WL_POINTER_AXIS_SOURCE_WHEEL)
{
//axis_source == WL POINTER AXIS SOURCE FINGER
//axis_source == WL POINTER AXIS SOURCE CONTINUOUS
// XXX the scroll is from trackpad we should calculate
// the momentumPhase
NSDebugLog(@"touch scroll");
}
//float mouse_scroll_multiplier = wlconfig->mouse_scroll_multiplier;
/* For smooth-scroll events, we're not doing any cross-event or delta
calculations, as is done in button event handling. */
switch (axis)
{
case WL_POINTER_AXIS_VERTICAL_SCROLL:
eventType = NSScrollWheel;
deltaY = wl_fixed_to_double(value) * wlconfig->mouse_scroll_multiplier;
case WL_POINTER_AXIS_HORIZONTAL_SCROLL:
eventType = NSScrollWheel;
deltaX = wl_fixed_to_double(value) * wlconfig->mouse_scroll_multiplier;
}
/* FIXME: X11 backend uses the XGetPointerMapping()-returned values from
its map_return argument as constants for buttonNumber. As the variant
with buttonNumber: seems to be a GNUstep extension, and the value
internal, it might be ok to just not provide any value here.
If this is truly correct, please update this comment to document
the correctness of doing so. */
buttonNumber = 0;
event = [NSEvent mouseEventWithType:eventType
location:eventLocation
modifierFlags:eventFlags
timestamp:(NSTimeInterval) time / 1000.0
windowNumber:(int) window->window_id
context:gcontext
eventNumber:time
clickCount:clickCount
pressure:1.0
buttonNumber:buttonNumber
deltaX:deltaX
deltaY:deltaY
deltaZ:0.];
[GSCurrentServer() postEvent:event atStart:NO];
}
// the Seat category uses this listener
const struct wl_pointer_listener pointer_listener
= {pointer_handle_enter, pointer_handle_leave,
pointer_handle_motion, pointer_handle_button,
pointer_handle_axis, pointer_handle_frame,
pointer_handle_axis_source, pointer_handle_axis_stop,
pointer_handle_axis_discrete};
@implementation
WaylandServer (Cursor)
- (NSPoint)mouselocation
{
int aScreen = -1;
if (wl_list_length(&wlconfig->output_list) == 0)
{
return NSZeroPoint;
}
struct output *output = (struct output *)wlconfig->output_list.next;
aScreen = output->server_output_id;
if (aScreen < 0)
{
// No outputs in the wl_list.
return NSZeroPoint;
}
return [self mouseLocationOnScreen:aScreen window:NULL];
}
- (NSPoint)mouseLocationOnScreen:(int)aScreen window:(int *)win
{
struct window *window = wlconfig->pointer.focus;
struct output *output;
float x;
float y;
x = wlconfig->pointer.x;
y = wlconfig->pointer.y;
if (window)
{
x += window->pos_x;
y += window->pos_y;
if (win)
{
*win = window->window_id;
}
}
wl_list_for_each(output, &wlconfig->output_list, link)
{
if (output->server_output_id == aScreen)
{
y = output->height - y;
break;
}
}
return NSMakePoint(x, y);
}
- (BOOL)capturemouse:(int)win
{
struct window *window = get_window_with_id(wlconfig, win);
wlconfig->pointer.captured = window;
return YES;
}
- (void)releasemouse
{
wlconfig->pointer.captured = NULL;
}
- (void)setMouseLocation:(NSPoint)mouseLocation onScreen:(int)aScreen
{
NSDebugLog(@"setMouseLocation: not supported");
}
- (void)hidecursor
{
// to hide the cursor we set a NULL surface
wl_pointer_set_cursor(wlconfig->pointer.wlpointer, wlconfig->pointer.serial,
NULL, 0, 0);
}
- (void)showcursor
{
// restore the previous surface
wl_pointer_set_cursor(wlconfig->pointer.wlpointer, wlconfig->pointer.serial,
wlconfig->cursor->surface,
wlconfig->cursor->image->hotspot_x,
wlconfig->cursor->image->hotspot_y);
}
- (void)standardcursor:(int)style :(void **)cid
{
[self initializeMouseIfRequired];
char * cursor_name = "";
switch (style)
{
case GSArrowCursor:
cursor_name = "left_ptr";
break;
case GSIBeamCursor:
cursor_name = "xterm";
break;
case GSDragLinkCursor:
cursor_name = "dnd-link";
break;
case GSOperationNotAllowedCursor:
cursor_name = "X_cursor";
break;
case GSDragCopyCursor:
cursor_name = "dnd-copy";
break;
case GSPointingHandCursor:
cursor_name = "hand";
break;
case GSResizeLeftCursor:
cursor_name = "left_side";
break;
case GSResizeRightCursor:
cursor_name = "right_side";
break;
case GSResizeLeftRightCursor:
cursor_name = "sb_h_double_arrow";
break;
case GSCrosshairCursor:
cursor_name = "crosshair";
break;
case GSResizeUpCursor:
cursor_name = "top_side";
break;
case GSResizeDownCursor:
cursor_name = "bottom_side";
break;
case GSResizeUpDownCursor:
cursor_name = "sb_v_double_arrow";
break;
case GSDisappearingItemCursor:
cursor_name = "pirate";
break;
case GSContextualMenuCursor:
break;
case GSGreenArrowCursor:
break;
case GSClosedHandCursor:
break;
case GSOpenHandCursor:
break;
}
if (strlen(cursor_name) != 0)
{
NSDebugLog(@"load cursor from theme for style %d: %s", style,
cursor_name);
struct cursor *wayland_cursor = malloc(sizeof(struct cursor));
wayland_cursor->cursor
= wl_cursor_theme_get_cursor(wlconfig->cursor_theme, cursor_name);
wayland_cursor->image = wayland_cursor->cursor->images[0];
wayland_cursor->buffer
= wl_cursor_image_get_buffer(wayland_cursor->image);
*cid = wayland_cursor;
}
else
{
NSDebugLog(@"unable to load cursor from theme for style %d", style);
}
}
- (void)imagecursor:(NSPoint)hotp :(NSImage *)image :(void **)cid
{
NSBitmapImageRep* raw_img = [NSBitmapImageRep imageRepWithData:[image TIFFRepresentation]];
unsigned char *data = [raw_img bitmapData];
NSSize imageSize = NSMakeSize(raw_img.pixelsWide, raw_img.pixelsHigh);
int width = imageSize.width;
int height = imageSize.height;
struct pool_buffer *pbuffer
= createShmBuffer(width, height, wlconfig->shm);
// TODO should check if the bitmaprep format is compatible
memcpy(pbuffer->data, data, [raw_img bytesPerPlane]);
struct cursor * wayland_cursor = malloc(sizeof(struct cursor));
struct wl_cursor * cursor = malloc(sizeof(struct wl_cursor));
cursor->image_count = 1;
cursor->name = "custom";
struct wl_cursor_image * cursor_image = malloc(sizeof(struct wl_cursor_image));
cursor->images = malloc(sizeof *cursor->images);
cursor->images[0] = cursor_image;
cursor_image->width = width;
cursor_image->height = height;
cursor_image->hotspot_x = hotp.x;
cursor_image->hotspot_y = hotp.y;
wayland_cursor->cursor = cursor;
wayland_cursor->image = cursor_image;
wayland_cursor->buffer = pbuffer->buffer;
*cid = wayland_cursor;
}
- (void)setcursorcolor:(NSColor *)fg :(NSColor *)bg :(void *)cid
{
NSLog(@"Call to obsolete method -setcursorcolor:::");
[self recolorcursor:fg:bg:cid];
[self setcursor:cid];
}
- (void) recolorcursor:(NSColor *)fg :(NSColor *)bg :(void*) cid
{
// TODO recolorcursor
NSDebugLog(@"recolorcursor");
}
- (void)setcursor:(void *)cid
{
struct cursor *wayland_cursor = cid;
if (wayland_cursor == NULL)
{
return;
}
if (wayland_cursor->cursor == NULL)
{
return;
}
if (wayland_cursor->image == NULL)
{
return;
}
if (wayland_cursor->buffer == NULL)
{
return;
}
if (wayland_cursor->surface)
{
wl_surface_destroy(wayland_cursor->surface);
}
wl_pointer_set_cursor(wlconfig->pointer.wlpointer, wlconfig->event_serial,
wlconfig->cursor_surface,
wayland_cursor->image->hotspot_x,
wayland_cursor->image->hotspot_y);
wl_surface_attach(wlconfig->cursor_surface, wayland_cursor->buffer, 0, 0);
wl_surface_damage(wlconfig->cursor_surface, 0, 0,
wayland_cursor->image->width, wayland_cursor->image->height);
wl_surface_commit(wlconfig->cursor_surface);
wlconfig->cursor = wayland_cursor;
}
- (void)freecursor:(void *)cid
{
// the cursor should be deallocated
struct cursor * c = cid;
wl_cursor_destroy(c->cursor);
wl_buffer_destroy(c->buffer);
free(cid);
}
- (void)setIgnoreMouse:(BOOL)ignoreMouse :(int)win
{
struct window *window = get_window_with_id(wlconfig, win);
if (window)
{
window->ignoreMouse = ignoreMouse;
}
}
- (void)initializeMouseIfRequired
{
if (!_mouseInitialized)
{
[self initializeMouse];
}
}
- (void)initializeMouse
{
_mouseInitialized = YES;
wlconfig->cursor_theme =
wl_cursor_theme_load(NULL, 24, wlconfig->shm);
wlconfig->cursor_surface
= wl_compositor_create_surface(wlconfig->compositor);
// default cursor used for show/hide
struct cursor *wayland_cursor;
[self standardcursor:GSArrowCursor :(void **)&wayland_cursor];
[self setcursor:wayland_cursor];
[self mouseOptionsChanged:nil];
[[NSDistributedNotificationCenter defaultCenter]
addObserver:self
selector:@selector(mouseOptionsChanged:)
name:NSUserDefaultsDidChangeNotification
object:nil];
}
- (void)mouseOptionsChanged:(NSNotification *)aNotif
{
NSUserDefaults *defs = [NSUserDefaults standardUserDefaults];
wlconfig->mouse_scroll_multiplier =
[defs integerForKey:@"GSMouseScrollMultiplier"];
if (wlconfig->mouse_scroll_multiplier < 0.0001f)
{
wlconfig->mouse_scroll_multiplier = 1.0f;
}
}
@end

View file

@ -0,0 +1,230 @@
/*
WaylandServer - Keyboard Handling
Copyright (C) 2020 Free Software Foundation, Inc.
Author: Riccardo Canalicchio <riccardo.canalicchio(at)gmail.com>
Date: November 2021
This file is part of the GNU Objective C Backend Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; see the file COPYING.LIB.
If not, see <http://www.gnu.org/licenses/> or write to the
Free Software Foundation, 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "wayland/WaylandServer.h"
#include <AppKit/NSEvent.h>
#include <AppKit/NSApplication.h>
#include <linux/input.h>
#include <AppKit/NSText.h>
#include <sys/mman.h>
#include <unistd.h>
static void
keyboard_handle_keymap(void *data, struct wl_keyboard *keyboard,
uint32_t format, int fd, uint32_t size)
{
NSDebugLog(@"keyboard_handle_keymap");
WaylandConfig *wlconfig = data;
struct xkb_keymap *keymap;
struct xkb_state *state;
char *map_str;
if (!data)
{
close(fd);
return;
}
if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1)
{
close(fd);
return;
}
map_str = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
if (map_str == MAP_FAILED)
{
close(fd);
return;
}
wlconfig->xkb_context = xkb_context_new(0);
if (wlconfig->xkb_context == NULL)
{
fprintf(stderr, "Failed to create XKB context\n");
return;
}
keymap = xkb_keymap_new_from_string(wlconfig->xkb_context, map_str,
XKB_KEYMAP_FORMAT_TEXT_V1, 0);
munmap(map_str, size);
close(fd);
if (!keymap)
{
fprintf(stderr, "failed to compile keymap\n");
return;
}
state = xkb_state_new(keymap);
if (!state)
{
fprintf(stderr, "failed to create XKB state\n");
xkb_keymap_unref(keymap);
return;
}
xkb_keymap_unref(wlconfig->xkb.keymap);
xkb_state_unref(wlconfig->xkb.state);
wlconfig->xkb.keymap = keymap;
wlconfig->xkb.state = state;
wlconfig->xkb.control_mask
= 1 << xkb_keymap_mod_get_index(wlconfig->xkb.keymap, "Control");
wlconfig->xkb.alt_mask
= 1 << xkb_keymap_mod_get_index(wlconfig->xkb.keymap, "Mod1");
wlconfig->xkb.shift_mask
= 1 << xkb_keymap_mod_get_index(wlconfig->xkb.keymap, "Shift");
}
static void
keyboard_handle_enter(void *data, struct wl_keyboard *keyboard, uint32_t serial,
struct wl_surface *surface, struct wl_array *keys)
{
// NSDebugLog(@"keyboard_handle_enter");
WaylandConfig *wlconfig = data;
wlconfig->event_serial = serial;
}
static void
keyboard_handle_leave(void *data, struct wl_keyboard *keyboard, uint32_t serial,
struct wl_surface *surface)
{
WaylandConfig *wlconfig = data;
wlconfig->event_serial = serial;
// NSDebugLog(@"keyboard_handle_leave");
}
static void
keyboard_handle_modifiers(void *data, struct wl_keyboard *keyboard,
uint32_t serial, uint32_t mods_depressed,
uint32_t mods_latched, uint32_t mods_locked,
uint32_t group)
{
// NSDebugLog(@"keyboard_handle_modifiers");
WaylandConfig *wlconfig = data;
wlconfig->event_serial = serial;
xkb_mod_mask_t mask;
/* If we're not using a keymap, then we don't handle PC-style modifiers */
if (!wlconfig->xkb.keymap)
return;
xkb_state_update_mask(wlconfig->xkb.state, mods_depressed, mods_latched,
mods_locked, 0, 0, group);
mask
= xkb_state_serialize_mods(wlconfig->xkb.state, XKB_STATE_MODS_DEPRESSED
| XKB_STATE_MODS_LATCHED);
wlconfig->modifiers = 0;
if (mask & wlconfig->xkb.control_mask)
wlconfig->modifiers |= NSCommandKeyMask;
if (mask & wlconfig->xkb.alt_mask)
wlconfig->modifiers |= NSAlternateKeyMask;
if (mask & wlconfig->xkb.shift_mask)
wlconfig->modifiers |= NSShiftKeyMask;
}
static void
keyboard_handle_key(void *data, struct wl_keyboard *keyboard, uint32_t serial,
uint32_t time, uint32_t key, uint32_t state_w)
{
// NSDebugLog(@"keyboard_handle_key: %d", key);
WaylandConfig *wlconfig = data;
wlconfig->event_serial = serial;
uint32_t code, num_syms;
enum wl_keyboard_key_state state = state_w;
const xkb_keysym_t *syms;
xkb_keysym_t sym;
struct window *window = wlconfig->pointer.focus;
if (!window)
return;
code = 0;
if (key == 28)
{
sym = NSCarriageReturnCharacter;
}
else if (key == 14)
{
sym = NSDeleteCharacter;
}
else
{
code = key + 8;
num_syms = xkb_state_key_get_syms(wlconfig->xkb.state, code, &syms);
sym = XKB_KEY_NoSymbol;
if (num_syms == 1)
sym = syms[0];
}
NSString *s = [NSString stringWithUTF8String:&sym];
NSEventType eventType;
if (state == WL_KEYBOARD_KEY_STATE_PRESSED)
{
eventType = NSKeyDown;
}
else
{
eventType = NSKeyUp;
}
NSEvent *ev = [NSEvent keyEventWithType:eventType
location:NSZeroPoint
modifierFlags:wlconfig->modifiers
timestamp:time / 1000.0
windowNumber:window->window_id
context:GSCurrentContext()
characters:s
charactersIgnoringModifiers:s
isARepeat:NO
keyCode:code];
[GSCurrentServer() postEvent:ev atStart:NO];
// NSDebugLog(@"keyboard_handle_key: %@", s);
}
static void
keyboard_handle_repeat_info(void *data, struct wl_keyboard *keyboard,
int32_t rate, int32_t delay)
{
// NSDebugLog(@"keyboard_handle_repeat_info");
}
const struct wl_keyboard_listener keyboard_listener
= {keyboard_handle_keymap, keyboard_handle_enter,
keyboard_handle_leave, keyboard_handle_key,
keyboard_handle_modifiers, keyboard_handle_repeat_info};
@implementation
WaylandServer (KeyboardOps)
@end

View file

@ -0,0 +1,65 @@
/*
WaylandServer - LayerShell Protocol Handling
Copyright (C) 2020 Free Software Foundation, Inc.
Author: Riccardo Canalicchio <riccardo.canalicchio(at)gmail.com>
Date: November 2021
This file is part of the GNU Objective C Backend Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; see the file COPYING.LIB.
If not, see <http://www.gnu.org/licenses/> or write to the
Free Software Foundation, 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "wayland/WaylandServer.h"
#include <AppKit/NSEvent.h>
#include <AppKit/NSApplication.h>
static void
layer_surface_configure(void *data, struct zwlr_layer_surface_v1 *surface,
uint32_t serial, uint32_t w, uint32_t h)
{
struct window *window = data;
NSDebugLog(@"[%d] layer_surface_configure", window->window_id);
WaylandConfig *wlconfig = window->wlconfig;
zwlr_layer_surface_v1_ack_configure(surface, serial);
window->configured = YES;
if (window->buffer_needs_attach)
{
[window->instance flushwindowrect:NSMakeRect(window->pos_x, window->pos_y,
window->width, window->height
):window->window_id];
}
}
static void
layer_surface_closed(void *data, struct zwlr_layer_surface_v1 *surface)
{
struct window *window = data;
WaylandConfig *wlconfig = window->wlconfig;
NSDebugLog(@"layer_surface_closed %d", window->window_id);
// zwlr_layer_surface_v1_destroy(surface);
wl_surface_destroy(window->surface);
window->surface = NULL;
window->configured = NO;
window->layer_surface = NULL;
}
const struct zwlr_layer_surface_v1_listener layer_surface_listener = {
.configure = layer_surface_configure,
.closed = layer_surface_closed,
};

View file

@ -0,0 +1,88 @@
/*
WaylandServer - Output Handling
Copyright (C) 2020 Free Software Foundation, Inc.
Author: Riccardo Canalicchio <riccardo.canalicchio(at)gmail.com>
Date: November 2021
This file is part of the GNU Objective C Backend Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; see the file COPYING.LIB.
If not, see <http://www.gnu.org/licenses/> or write to the
Free Software Foundation, 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "wayland/WaylandServer.h"
static void
handle_geometry(void *data, struct wl_output *wl_output, int x, int y,
int physical_width, int physical_height, int subpixel,
const char *make, const char *model, int transform)
{
NSDebugLog(@"handle_geometry");
struct output *output = data;
output->alloc_x = x;
output->alloc_y = y;
output->transform = transform;
if (output->make)
free(output->make);
output->make = strdup(make);
if (output->model)
free(output->model);
output->model = strdup(model);
}
static void
handle_done(void *data, struct wl_output *wl_output)
{
NSDebugLog(@"handle_done");
}
static void
handle_scale(void *data, struct wl_output *wl_output, int32_t scale)
{
NSDebugLog(@"handle_scale");
struct output *output = data;
output->scale = scale;
}
static void
handle_mode(void *data, struct wl_output *wl_output, uint32_t flags, int width,
int height, int refresh)
{
NSDebugLog(@"handle_mode");
struct output *output = data;
if (flags & WL_OUTPUT_MODE_CURRENT)
{
output->width = width;
output->height = height /*- 30*/;
NSDebugLog(@"handle_mode output=%dx%d", width, height);
// XXX - Should we implement this?
// if (display->output_configure_handler)
// (*display->output_configure_handler)
// (output, display->user_data);
//
}
}
const struct wl_output_listener output_listener
= {handle_geometry, handle_mode, handle_done, handle_scale};

View file

@ -0,0 +1,92 @@
/*
WaylandServer - Seat Handling
Copyright (C) 2020 Free Software Foundation, Inc.
Author: Riccardo Canalicchio <riccardo.canalicchio(at)gmail.com>
Date: November 2021
This file is part of the GNU Objective C Backend Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; see the file COPYING.LIB.
If not, see <http://www.gnu.org/licenses/> or write to the
Free Software Foundation, 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "wayland/WaylandServer.h"
extern const struct wl_keyboard_listener keyboard_listener;
extern const struct wl_pointer_listener pointer_listener;
static void
seat_handle_capabilities(void *data, struct wl_seat *seat,
enum wl_seat_capability caps)
{
WaylandConfig *wlconfig = data;
if ((caps & WL_SEAT_CAPABILITY_POINTER) && !wlconfig->pointer.wlpointer)
{
wlconfig->pointer.wlpointer = wl_seat_get_pointer(seat);
wl_pointer_set_user_data(wlconfig->pointer.wlpointer, wlconfig);
wl_pointer_add_listener(wlconfig->pointer.wlpointer, &pointer_listener,
wlconfig);
}
else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && wlconfig->pointer.wlpointer)
{
if (wlconfig->seat_version >= WL_POINTER_RELEASE_SINCE_VERSION)
wl_pointer_release(wlconfig->pointer.wlpointer);
else
wl_pointer_destroy(wlconfig->pointer.wlpointer);
wlconfig->pointer.wlpointer = NULL;
}
wl_display_dispatch_pending(wlconfig->display);
wl_display_flush(wlconfig->display);
if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && !wlconfig->keyboard)
{
wlconfig->keyboard = wl_seat_get_keyboard(seat);
wl_keyboard_set_user_data(wlconfig->keyboard, wlconfig);
wl_keyboard_add_listener(wlconfig->keyboard, &keyboard_listener,
wlconfig);
}
else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && wlconfig->keyboard)
{
if (wlconfig->seat_version >= WL_KEYBOARD_RELEASE_SINCE_VERSION)
wl_keyboard_release(wlconfig->keyboard);
else
wl_keyboard_destroy(wlconfig->keyboard);
wlconfig->keyboard = NULL;
}
#if 0
if ((caps & WL_SEAT_CAPABILITY_TOUCH) && !input->touch) {
input->touch = wl_seat_get_touch(seat);
wl_touch_set_user_data(input->touch, input);
wl_touch_add_listener(input->touch, &touch_listener, input);
} else if (!(caps & WL_SEAT_CAPABILITY_TOUCH) && input->touch) {
if (input->seat_version >= WL_TOUCH_RELEASE_SINCE_VERSION)
wl_touch_release(input->touch);
else
wl_touch_destroy(input->touch);
input->touch = NULL;
}
#endif
}
const struct wl_seat_listener seat_listener = {
seat_handle_capabilities,
};

View file

@ -0,0 +1,167 @@
/*
WaylandServer - XdgShell Protocol Handling
Copyright (C) 2020 Free Software Foundation, Inc.
Author: Riccardo Canalicchio <riccardo.canalicchio(at)gmail.com>
Date: November 2021
This file is part of the GNU Objective C Backend Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; see the file COPYING.LIB.
If not, see <http://www.gnu.org/licenses/> or write to the
Free Software Foundation, 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "wayland/WaylandServer.h"
#include <AppKit/NSEvent.h>
#include <AppKit/NSApplication.h>
#include <AppKit/NSGraphics.h>
static void
xdg_surface_on_configure(void *data, struct xdg_surface *xdg_surface,
uint32_t serial)
{
struct window *window = data;
NSDebugLog(@"xdg_surface_on_configure: win=%d", window->window_id);
if (window->terminated == YES)
{
NSDebugLog(@"deleting window win=%d", window->window_id);
free(window);
return;
}
NSEvent *ev = nil;
NSWindow *nswindow = GSWindowWithNumber(window->window_id);
// NSDebugLog(@"Acknowledging surface configure %p %d (window_id=%d)",
// xdg_surface, serial, window->window_id);
xdg_surface_ack_configure(xdg_surface, serial);
window->configured = YES;
if (window->buffer_needs_attach)
{
[window->instance flushwindowrect:NSMakeRect(window->pos_x, window->pos_y,
window->width, window->height)
:window->window_id];
}
if (window->wlconfig->pointer.focus
&& window->wlconfig->pointer.focus->window_id == window->window_id)
{
ev = [NSEvent otherEventWithType:NSAppKitDefined
location:NSZeroPoint
modifierFlags:0
timestamp:0
windowNumber:(int) window->window_id
context:GSCurrentContext()
subtype:GSAppKitWindowFocusIn
data1:0
data2:0];
[nswindow sendEvent:ev];
}
}
static void
xdg_toplevel_configure(void *data, struct xdg_toplevel *xdg_toplevel,
int32_t width, int32_t height, struct wl_array *states)
{
struct window *window = data;
NSDebugLog(@"[%d] xdg_toplevel_configure %dx%d", window->window_id, width,
height);
// The compositor can send 0x0
if (width == 0 || height == 0)
{
return;
}
if (window->width != width || window->height != height)
{
window->width = width;
window->height = height;
xdg_surface_set_window_geometry(window->xdg_surface, 0, 0, window->width,
window->height);
NSEvent *ev = [NSEvent otherEventWithType:NSAppKitDefined
location:NSMakePoint(0.0, 0.0)
modifierFlags:0
timestamp:0
windowNumber:window->window_id
context:GSCurrentContext()
subtype:GSAppKitWindowResized
data1:window->width
data2:window->height];
[(GSWindowWithNumber(window->window_id)) sendEvent:ev];
}
NSDebugLog(@"[%d] notify resize from backend=%dx%d", window->window_id,
width, height);
}
static void
xdg_toplevel_close_handler(void *data, struct xdg_toplevel *xdg_toplevel)
{
NSDebugLog(@"xdg_toplevel_close_handler");
}
static void
xdg_popup_configure(void *data, struct xdg_popup *xdg_popup, int32_t x,
int32_t y, int32_t width, int32_t height)
{
struct window *window = data;
NSDebugLog(@"[%d] xdg_popup_configure [%d,%d %dx%d]", window->window_id, x, y,
width, height);
}
static void
xdg_popup_done(void *data, struct xdg_popup *xdg_popup)
{
struct window *window = data;
window->terminated = YES;
xdg_popup_destroy(xdg_popup);
wl_surface_destroy(window->surface);
}
static void
wm_base_handle_ping(void *data, struct xdg_wm_base *xdg_wm_base,
uint32_t serial)
{
NSDebugLog(@"wm_base_handle_ping");
xdg_wm_base_pong(xdg_wm_base, serial);
}
const struct xdg_surface_listener xdg_surface_listener = {
xdg_surface_on_configure,
};
const struct xdg_wm_base_listener wm_base_listener = {
.ping = wm_base_handle_ping,
};
const struct xdg_popup_listener xdg_popup_listener = {
.configure = xdg_popup_configure,
.popup_done = xdg_popup_done,
};
const struct xdg_toplevel_listener xdg_toplevel_listener = {
.configure = xdg_toplevel_configure,
.close = xdg_toplevel_close_handler,
};

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,311 @@
<?xml version="1.0" encoding="UTF-8"?>
<protocol name="wlr_layer_shell_unstable_v1">
<copyright>
Copyright © 2017 Drew DeVault
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in
all copies and that both that copyright notice and this permission
notice appear in supporting documentation, and that the name of
the copyright holders not be used in advertising or publicity
pertaining to distribution of the software without specific,
written prior permission. The copyright holders make no
representations about the suitability of this software for any
purpose. It is provided "as is" without express or implied
warranty.
THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
</copyright>
<interface name="zwlr_layer_shell_v1" version="3">
<description summary="create surfaces that are layers of the desktop">
Clients can use this interface to assign the surface_layer role to
wl_surfaces. Such surfaces are assigned to a "layer" of the output and
rendered with a defined z-depth respective to each other. They may also be
anchored to the edges and corners of a screen and specify input handling
semantics. This interface should be suitable for the implementation of
many desktop shell components, and a broad number of other applications
that interact with the desktop.
</description>
<request name="get_layer_surface">
<description summary="create a layer_surface from a surface">
Create a layer surface for an existing surface. This assigns the role of
layer_surface, or raises a protocol error if another role is already
assigned.
Creating a layer surface from a wl_surface which has a buffer attached
or committed is a client error, and any attempts by a client to attach
or manipulate a buffer prior to the first layer_surface.configure call
must also be treated as errors.
You may pass NULL for output to allow the compositor to decide which
output to use. Generally this will be the one that the user most
recently interacted with.
Clients can specify a namespace that defines the purpose of the layer
surface.
</description>
<arg name="id" type="new_id" interface="zwlr_layer_surface_v1"/>
<arg name="surface" type="object" interface="wl_surface"/>
<arg name="output" type="object" interface="wl_output" allow-null="true"/>
<arg name="layer" type="uint" enum="layer" summary="layer to add this surface to"/>
<arg name="namespace" type="string" summary="namespace for the layer surface"/>
</request>
<enum name="error">
<entry name="role" value="0" summary="wl_surface has another role"/>
<entry name="invalid_layer" value="1" summary="layer value is invalid"/>
<entry name="already_constructed" value="2" summary="wl_surface has a buffer attached or committed"/>
</enum>
<enum name="layer">
<description summary="available layers for surfaces">
These values indicate which layers a surface can be rendered in. They
are ordered by z depth, bottom-most first. Traditional shell surfaces
will typically be rendered between the bottom and top layers.
Fullscreen shell surfaces are typically rendered at the top layer.
Multiple surfaces can share a single layer, and ordering within a
single layer is undefined.
</description>
<entry name="background" value="0"/>
<entry name="bottom" value="1"/>
<entry name="top" value="2"/>
<entry name="overlay" value="3"/>
</enum>
<!-- Version 3 additions -->
<request name="destroy" type="destructor" since="3">
<description summary="destroy the layer_shell object">
This request indicates that the client will not use the layer_shell
object any more. Objects that have been created through this instance
are not affected.
</description>
</request>
</interface>
<interface name="zwlr_layer_surface_v1" version="3">
<description summary="layer metadata interface">
An interface that may be implemented by a wl_surface, for surfaces that
are designed to be rendered as a layer of a stacked desktop-like
environment.
Layer surface state (layer, size, anchor, exclusive zone,
margin, interactivity) is double-buffered, and will be applied at the
time wl_surface.commit of the corresponding wl_surface is called.
</description>
<request name="set_size">
<description summary="sets the size of the surface">
Sets the size of the surface in surface-local coordinates. The
compositor will display the surface centered with respect to its
anchors.
If you pass 0 for either value, the compositor will assign it and
inform you of the assignment in the configure event. You must set your
anchor to opposite edges in the dimensions you omit; not doing so is a
protocol error. Both values are 0 by default.
Size is double-buffered, see wl_surface.commit.
</description>
<arg name="width" type="uint"/>
<arg name="height" type="uint"/>
</request>
<request name="set_anchor">
<description summary="configures the anchor point of the surface">
Requests that the compositor anchor the surface to the specified edges
and corners. If two orthogonal edges are specified (e.g. 'top' and
'left'), then the anchor point will be the intersection of the edges
(e.g. the top left corner of the output); otherwise the anchor point
will be centered on that edge, or in the center if none is specified.
Anchor is double-buffered, see wl_surface.commit.
</description>
<arg name="anchor" type="uint" enum="anchor"/>
</request>
<request name="set_exclusive_zone">
<description summary="configures the exclusive geometry of this surface">
Requests that the compositor avoids occluding an area with other
surfaces. The compositor's use of this information is
implementation-dependent - do not assume that this region will not
actually be occluded.
A positive value is only meaningful if the surface is anchored to one
edge or an edge and both perpendicular edges. If the surface is not
anchored, anchored to only two perpendicular edges (a corner), anchored
to only two parallel edges or anchored to all edges, a positive value
will be treated the same as zero.
A positive zone is the distance from the edge in surface-local
coordinates to consider exclusive.
Surfaces that do not wish to have an exclusive zone may instead specify
how they should interact with surfaces that do. If set to zero, the
surface indicates that it would like to be moved to avoid occluding
surfaces with a positive exclusive zone. If set to -1, the surface
indicates that it would not like to be moved to accommodate for other
surfaces, and the compositor should extend it all the way to the edges
it is anchored to.
For example, a panel might set its exclusive zone to 10, so that
maximized shell surfaces are not shown on top of it. A notification
might set its exclusive zone to 0, so that it is moved to avoid
occluding the panel, but shell surfaces are shown underneath it. A
wallpaper or lock screen might set their exclusive zone to -1, so that
they stretch below or over the panel.
The default value is 0.
Exclusive zone is double-buffered, see wl_surface.commit.
</description>
<arg name="zone" type="int"/>
</request>
<request name="set_margin">
<description summary="sets a margin from the anchor point">
Requests that the surface be placed some distance away from the anchor
point on the output, in surface-local coordinates. Setting this value
for edges you are not anchored to has no effect.
The exclusive zone includes the margin.
Margin is double-buffered, see wl_surface.commit.
</description>
<arg name="top" type="int"/>
<arg name="right" type="int"/>
<arg name="bottom" type="int"/>
<arg name="left" type="int"/>
</request>
<request name="set_keyboard_interactivity">
<description summary="requests keyboard events">
Set to 1 to request that the seat send keyboard events to this layer
surface. For layers below the shell surface layer, the seat will use
normal focus semantics. For layers above the shell surface layers, the
seat will always give exclusive keyboard focus to the top-most layer
which has keyboard interactivity set to true.
Layer surfaces receive pointer, touch, and tablet events normally. If
you do not want to receive them, set the input region on your surface
to an empty region.
Events is double-buffered, see wl_surface.commit.
</description>
<arg name="keyboard_interactivity" type="uint"/>
</request>
<request name="get_popup">
<description summary="assign this layer_surface as an xdg_popup parent">
This assigns an xdg_popup's parent to this layer_surface. This popup
should have been created via xdg_surface::get_popup with the parent set
to NULL, and this request must be invoked before committing the popup's
initial state.
See the documentation of xdg_popup for more details about what an
xdg_popup is and how it is used.
</description>
<arg name="popup" type="object" interface="xdg_popup"/>
</request>
<request name="ack_configure">
<description summary="ack a configure event">
When a configure event is received, if a client commits the
surface in response to the configure event, then the client
must make an ack_configure request sometime before the commit
request, passing along the serial of the configure event.
If the client receives multiple configure events before it
can respond to one, it only has to ack the last configure event.
A client is not required to commit immediately after sending
an ack_configure request - it may even ack_configure several times
before its next surface commit.
A client may send multiple ack_configure requests before committing, but
only the last request sent before a commit indicates which configure
event the client really is responding to.
</description>
<arg name="serial" type="uint" summary="the serial from the configure event"/>
</request>
<request name="destroy" type="destructor">
<description summary="destroy the layer_surface">
This request destroys the layer surface.
</description>
</request>
<event name="configure">
<description summary="suggest a surface change">
The configure event asks the client to resize its surface.
Clients should arrange their surface for the new states, and then send
an ack_configure request with the serial sent in this configure event at
some point before committing the new surface.
The client is free to dismiss all but the last configure event it
received.
The width and height arguments specify the size of the window in
surface-local coordinates.
The size is a hint, in the sense that the client is free to ignore it if
it doesn't resize, pick a smaller size (to satisfy aspect ratio or
resize in steps of NxM pixels). If the client picks a smaller size and
is anchored to two opposite anchors (e.g. 'top' and 'bottom'), the
surface will be centered on this axis.
If the width or height arguments are zero, it means the client should
decide its own window dimension.
</description>
<arg name="serial" type="uint"/>
<arg name="width" type="uint"/>
<arg name="height" type="uint"/>
</event>
<event name="closed">
<description summary="surface should be closed">
The closed event is sent by the compositor when the surface will no
longer be shown. The output may have been destroyed or the user may
have asked for it to be removed. Further changes to the surface will be
ignored. The client should destroy the resource after receiving this
event, and create a new surface if they so choose.
</description>
</event>
<enum name="error">
<entry name="invalid_surface_state" value="0" summary="provided surface state is invalid"/>
<entry name="invalid_size" value="1" summary="size is invalid"/>
<entry name="invalid_anchor" value="2" summary="anchor bitfield is invalid"/>
</enum>
<enum name="anchor" bitfield="true">
<entry name="top" value="1" summary="the top edge of the anchor rectangle"/>
<entry name="bottom" value="2" summary="the bottom edge of the anchor rectangle"/>
<entry name="left" value="4" summary="the left edge of the anchor rectangle"/>
<entry name="right" value="8" summary="the right edge of the anchor rectangle"/>
</enum>
<!-- Version 2 additions -->
<request name="set_layer" since="2">
<description summary="change the layer of the surface">
Change the layer that the surface is rendered on.
Layer is double-buffered, see wl_surface.commit.
</description>
<arg name="layer" type="uint" enum="zwlr_layer_shell_v1.layer" summary="layer to move this surface to"/>
</request>
</interface>
</protocol>

View file

@ -0,0 +1,83 @@
/* Generated by wayland-scanner 1.18.0 */
/*
* Copyright © 2017 Drew DeVault
*
* Permission to use, copy, modify, distribute, and sell this
* software and its documentation for any purpose is hereby granted
* without fee, provided that the above copyright notice appear in
* all copies and that both that copyright notice and this permission
* notice appear in supporting documentation, and that the name of
* the copyright holders not be used in advertising or publicity
* pertaining to distribution of the software without specific,
* written prior permission. The copyright holders make no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied
* warranty.
*
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
* THIS SOFTWARE.
*/
#include <stdlib.h>
#include <stdint.h>
#include "wayland-util.h"
extern const struct wl_interface wl_output_interface;
extern const struct wl_interface wl_surface_interface;
extern const struct wl_interface xdg_popup_interface;
extern const struct wl_interface zwlr_layer_surface_v1_interface;
static const struct wl_interface *wlr_layer_shell_unstable_v1_types[] = {
NULL,
NULL,
NULL,
NULL,
&zwlr_layer_surface_v1_interface,
&wl_surface_interface,
&wl_output_interface,
NULL,
NULL,
&xdg_popup_interface,
};
static const struct wl_message zwlr_layer_shell_v1_requests[] = {
{ "get_layer_surface", "no?ous", wlr_layer_shell_unstable_v1_types + 4 },
{ "destroy", "3", wlr_layer_shell_unstable_v1_types + 0 },
};
WL_EXPORT const struct wl_interface zwlr_layer_shell_v1_interface = {
"zwlr_layer_shell_v1", 3,
2, zwlr_layer_shell_v1_requests,
0, NULL,
};
static const struct wl_message zwlr_layer_surface_v1_requests[] = {
{ "set_size", "uu", wlr_layer_shell_unstable_v1_types + 0 },
{ "set_anchor", "u", wlr_layer_shell_unstable_v1_types + 0 },
{ "set_exclusive_zone", "i", wlr_layer_shell_unstable_v1_types + 0 },
{ "set_margin", "iiii", wlr_layer_shell_unstable_v1_types + 0 },
{ "set_keyboard_interactivity", "u", wlr_layer_shell_unstable_v1_types + 0 },
{ "get_popup", "o", wlr_layer_shell_unstable_v1_types + 9 },
{ "ack_configure", "u", wlr_layer_shell_unstable_v1_types + 0 },
{ "destroy", "", wlr_layer_shell_unstable_v1_types + 0 },
{ "set_layer", "2u", wlr_layer_shell_unstable_v1_types + 0 },
};
static const struct wl_message zwlr_layer_surface_v1_events[] = {
{ "configure", "uuu", wlr_layer_shell_unstable_v1_types + 0 },
{ "closed", "", wlr_layer_shell_unstable_v1_types + 0 },
};
WL_EXPORT const struct wl_interface zwlr_layer_surface_v1_interface = {
"zwlr_layer_surface_v1", 3,
9, zwlr_layer_surface_v1_requests,
2, zwlr_layer_surface_v1_events,
};

View file

@ -0,0 +1,171 @@
/* Generated by wayland-scanner 1.18.0 */
/*
* Copyright © 2008-2013 Kristian Høgsberg
* Copyright © 2013 Rafael Antognolli
* Copyright © 2013 Jasper St. Pierre
* Copyright © 2010-2013 Intel Corporation
* Copyright © 2015-2017 Samsung Electronics Co., Ltd
* Copyright © 2015-2017 Red Hat Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include <stdlib.h>
#include <stdint.h>
#include "wayland-util.h"
extern const struct wl_interface wl_output_interface;
extern const struct wl_interface wl_seat_interface;
extern const struct wl_interface wl_surface_interface;
extern const struct wl_interface xdg_popup_interface;
extern const struct wl_interface xdg_positioner_interface;
extern const struct wl_interface xdg_surface_interface;
extern const struct wl_interface xdg_toplevel_interface;
static const struct wl_interface *xdg_shell_types[] = {
NULL,
NULL,
NULL,
NULL,
&xdg_positioner_interface,
&xdg_surface_interface,
&wl_surface_interface,
&xdg_toplevel_interface,
&xdg_popup_interface,
&xdg_surface_interface,
&xdg_positioner_interface,
&xdg_toplevel_interface,
&wl_seat_interface,
NULL,
NULL,
NULL,
&wl_seat_interface,
NULL,
&wl_seat_interface,
NULL,
NULL,
&wl_output_interface,
&wl_seat_interface,
NULL,
&xdg_positioner_interface,
NULL,
};
static const struct wl_message xdg_wm_base_requests[] = {
{ "destroy", "", xdg_shell_types + 0 },
{ "create_positioner", "n", xdg_shell_types + 4 },
{ "get_xdg_surface", "no", xdg_shell_types + 5 },
{ "pong", "u", xdg_shell_types + 0 },
};
static const struct wl_message xdg_wm_base_events[] = {
{ "ping", "u", xdg_shell_types + 0 },
};
WL_EXPORT const struct wl_interface xdg_wm_base_interface = {
"xdg_wm_base", 3,
4, xdg_wm_base_requests,
1, xdg_wm_base_events,
};
static const struct wl_message xdg_positioner_requests[] = {
{ "destroy", "", xdg_shell_types + 0 },
{ "set_size", "ii", xdg_shell_types + 0 },
{ "set_anchor_rect", "iiii", xdg_shell_types + 0 },
{ "set_anchor", "u", xdg_shell_types + 0 },
{ "set_gravity", "u", xdg_shell_types + 0 },
{ "set_constraint_adjustment", "u", xdg_shell_types + 0 },
{ "set_offset", "ii", xdg_shell_types + 0 },
{ "set_reactive", "3", xdg_shell_types + 0 },
{ "set_parent_size", "3ii", xdg_shell_types + 0 },
{ "set_parent_configure", "3u", xdg_shell_types + 0 },
};
WL_EXPORT const struct wl_interface xdg_positioner_interface = {
"xdg_positioner", 3,
10, xdg_positioner_requests,
0, NULL,
};
static const struct wl_message xdg_surface_requests[] = {
{ "destroy", "", xdg_shell_types + 0 },
{ "get_toplevel", "n", xdg_shell_types + 7 },
{ "get_popup", "n?oo", xdg_shell_types + 8 },
{ "set_window_geometry", "iiii", xdg_shell_types + 0 },
{ "ack_configure", "u", xdg_shell_types + 0 },
};
static const struct wl_message xdg_surface_events[] = {
{ "configure", "u", xdg_shell_types + 0 },
};
WL_EXPORT const struct wl_interface xdg_surface_interface = {
"xdg_surface", 3,
5, xdg_surface_requests,
1, xdg_surface_events,
};
static const struct wl_message xdg_toplevel_requests[] = {
{ "destroy", "", xdg_shell_types + 0 },
{ "set_parent", "?o", xdg_shell_types + 11 },
{ "set_title", "s", xdg_shell_types + 0 },
{ "set_app_id", "s", xdg_shell_types + 0 },
{ "show_window_menu", "ouii", xdg_shell_types + 12 },
{ "move", "ou", xdg_shell_types + 16 },
{ "resize", "ouu", xdg_shell_types + 18 },
{ "set_max_size", "ii", xdg_shell_types + 0 },
{ "set_min_size", "ii", xdg_shell_types + 0 },
{ "set_maximized", "", xdg_shell_types + 0 },
{ "unset_maximized", "", xdg_shell_types + 0 },
{ "set_fullscreen", "?o", xdg_shell_types + 21 },
{ "unset_fullscreen", "", xdg_shell_types + 0 },
{ "set_minimized", "", xdg_shell_types + 0 },
};
static const struct wl_message xdg_toplevel_events[] = {
{ "configure", "iia", xdg_shell_types + 0 },
{ "close", "", xdg_shell_types + 0 },
};
WL_EXPORT const struct wl_interface xdg_toplevel_interface = {
"xdg_toplevel", 3,
14, xdg_toplevel_requests,
2, xdg_toplevel_events,
};
static const struct wl_message xdg_popup_requests[] = {
{ "destroy", "", xdg_shell_types + 0 },
{ "grab", "ou", xdg_shell_types + 22 },
{ "reposition", "3ou", xdg_shell_types + 24 },
};
static const struct wl_message xdg_popup_events[] = {
{ "configure", "iiii", xdg_shell_types + 0 },
{ "popup_done", "", xdg_shell_types + 0 },
{ "repositioned", "3u", xdg_shell_types + 0 },
};
WL_EXPORT const struct wl_interface xdg_popup_interface = {
"xdg_popup", 3,
3, xdg_popup_requests,
3, xdg_popup_events,
};

View file

@ -63,6 +63,18 @@
#include <math.h>
// The Windows SDK declares BOOL as an int. Objective C defines BOOl as a char.
// Those two types clash. MinGW's implementation of the Windows SDK uses the WINBOOL
// type to avoid this clash. When compiling natively on Windows, we need to manually
// define WINBOOL.
// MinGW will define _DEF_WINBOOL_ if it has defined WINBOOL so we can use the same trick
// here.
// See https://github.com/mingw-w64/mingw-w64/blob/master/mingw-w64-headers/include/ntdef.h#L355
#ifndef _DEF_WINBOOL_
#define _DEF_WINBOOL_
typedef int WINBOOL;
#endif
// To update the cursor..
static BOOL update_cursor = NO;
static BOOL should_handle_cursor = NO;
@ -700,7 +712,7 @@ LRESULT CALLBACK windowEnumCallback(HWND hwnd, LPARAM lParam)
- (void) resizeBackingStoreFor: (HWND)hwnd
{
#if (BUILD_GRAPHICS==GRAPHICS_winlib)
WIN_INTERN *win = (WIN_INTERN *)GetWindowLong((HWND)hwnd, GWL_USERDATA);
WIN_INTERN *win = (WIN_INTERN *)GetWindowLongPtr((HWND)hwnd, GWLP_USERDATA);
// FIXME: We should check if the size really did change.
if (win->useHDC)
@ -1635,10 +1647,10 @@ LRESULT CALLBACK windowEnumCallback(HWND hwnd, LPARAM lParam)
// Borderless window request...
if (wstyle & WS_POPUP)
{
LONG wstyleOld = GetWindowLong(hwnd, GWL_STYLE);
LONG estyleOld = GetWindowLong(hwnd, GWL_EXSTYLE);
LONG wstyleNew = (wstyleOld & ~WS_OVERLAPPEDWINDOW);
LONG estyleNew = estyleOld | WS_EX_TOOLWINDOW;
LONG_PTR wstyleOld = GetWindowLongPtr(hwnd, GWL_STYLE);
LONG_PTR estyleOld = GetWindowLongPtr(hwnd, GWL_EXSTYLE);
LONG_PTR wstyleNew = (wstyleOld & ~WS_OVERLAPPEDWINDOW);
LONG_PTR estyleNew = estyleOld | WS_EX_TOOLWINDOW;
NSDebugMLLog(@"WCTrace", @"wstyles - old: %8.8X new: %8.8X\n",
wstyleOld, wstyleNew);
@ -1646,8 +1658,8 @@ LRESULT CALLBACK windowEnumCallback(HWND hwnd, LPARAM lParam)
estyleOld, estyleNew);
// Modify window style parameters and update the window information...
SetWindowLong(hwnd, GWL_STYLE, wstyleNew);
SetWindowLong(hwnd, GWL_EXSTYLE, estyleNew);
SetWindowLongPtr(hwnd, GWL_STYLE, wstyleNew);
SetWindowLongPtr(hwnd, GWL_EXSTYLE, estyleNew);
SetWindowPos(hwnd, NULL, 0, 0, 0, 0,
SWP_FRAMECHANGED | SWP_NOSENDCHANGING | SWP_NOREPOSITION |
SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
@ -1678,8 +1690,8 @@ LRESULT CALLBACK windowEnumCallback(HWND hwnd, LPARAM lParam)
@"-stylewindow: : called when [self handlesWindowDecorations] == NO");
NSDebugLLog(@"WTrace", @"stylewindow: %d : %d", style, winNum);
SetWindowLong((HWND)winNum, GWL_STYLE, wstyle);
SetWindowLong((HWND)winNum, GWL_EXSTYLE, estyle);
SetWindowLongPtr((HWND)winNum, GWL_STYLE, wstyle);
SetWindowLongPtr((HWND)winNum, GWL_EXSTYLE, estyle);
}
- (void) setbackgroundcolor: (NSColor *)color : (int)win
@ -1689,7 +1701,7 @@ LRESULT CALLBACK windowEnumCallback(HWND hwnd, LPARAM lParam)
/** Changes window's the backing store to type */
- (void) windowbacking: (NSBackingStoreType)type : (int) winNum
{
WIN_INTERN *win = (WIN_INTERN *)GetWindowLong((HWND)winNum, GWL_USERDATA);
WIN_INTERN *win = (WIN_INTERN *)GetWindowLongPtr((HWND)winNum, GWLP_USERDATA);
NSDebugLLog(@"WTrace", @"windowbacking: %d : %d", type, winNum);
#if (BUILD_GRAPHICS==GRAPHICS_winlib)
@ -1817,7 +1829,7 @@ LRESULT CALLBACK windowEnumCallback(HWND hwnd, LPARAM lParam)
if (op == NSWindowOut)
{
SetWindowLong((HWND)winNum, OFF_ORDERED, 0);
SetWindowLongPtr((HWND)winNum, OFF_ORDERED, 0);
ShowWindow((HWND)winNum, SW_HIDE);
return;
}
@ -1835,10 +1847,10 @@ LRESULT CALLBACK windowEnumCallback(HWND hwnd, LPARAM lParam)
}
ShowWindow((HWND)winNum, flag);
SetWindowLong((HWND)winNum, OFF_ORDERED, 1);
SetWindowLongPtr((HWND)winNum, OFF_ORDERED, 1);
// Process window leveling...
level = GetWindowLong((HWND)winNum, OFF_LEVEL);
level = GetWindowLongPtr((HWND)winNum, OFF_LEVEL);
if (otherWin <= 0)
{
@ -1863,14 +1875,14 @@ LRESULT CALLBACK windowEnumCallback(HWND hwnd, LPARAM lParam)
/* Put this on the same window level as the window we are ordering
* it against.
*/
otherLevel = GetWindowLong((HWND)otherWin, OFF_LEVEL);
otherLevel = GetWindowLongPtr((HWND)otherWin, OFF_LEVEL);
if (level != otherLevel)
{
NSDebugLLog(@"WTrace",
@"orderwindow: implicitly set level of %d (%d) to that of %d (%d)",
winNum, level, otherWin, otherLevel);
level = otherLevel;
SetWindowLong((HWND)winNum, OFF_LEVEL, level);
SetWindowLongPtr((HWND)winNum, OFF_LEVEL, level);
}
}
@ -1917,9 +1929,9 @@ LRESULT CALLBACK windowEnumCallback(HWND hwnd, LPARAM lParam)
&& GetClassName((HWND)otherWin, buf, 32) == 18
&& strncmp(buf, "GNUstepWindowClass", 18) == 0)
{
if (GetWindowLong((HWND)otherWin, OFF_ORDERED) == 1)
if (GetWindowLongPtr((HWND)otherWin, OFF_ORDERED) == 1)
{
otherLevel = GetWindowLong((HWND)otherWin, OFF_LEVEL);
otherLevel = GetWindowLongPtr((HWND)otherWin, OFF_LEVEL);
NSDebugLLog(@"WTrace", @"orderwindow: found gnustep window %d (%d)",
otherWin, otherLevel);
if (otherLevel >= level)
@ -2000,9 +2012,9 @@ LRESULT CALLBACK windowEnumCallback(HWND hwnd, LPARAM lParam)
&& GetClassName((HWND)otherWin, buf, 32) == 18
&& strncmp(buf, "GNUstepWindowClass", 18) == 0)
{
if (GetWindowLong((HWND)otherWin, OFF_ORDERED) == 1)
if (GetWindowLongPtr((HWND)otherWin, OFF_ORDERED) == 1)
{
otherLevel = GetWindowLong((HWND)otherWin, OFF_LEVEL);
otherLevel = GetWindowLongPtr((HWND)otherWin, OFF_LEVEL);
s = [s stringByAppendingFormat:
@"%d (%d)\n", otherWin, otherLevel];
}
@ -2039,7 +2051,7 @@ LRESULT CALLBACK windowEnumCallback(HWND hwnd, LPARAM lParam)
SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOSENDCHANGING);
#if (BUILD_GRAPHICS==GRAPHICS_winlib)
WIN_INTERN *win = (WIN_INTERN *)GetWindowLong((HWND)winNum, GWL_USERDATA);
WIN_INTERN *win = (WIN_INTERN *)GetWindowLongPtr((HWND)winNum, GWLP_USERDATA);
if ((win->useHDC)
&& (r.right - r.left != r2.right - r2.left)
@ -2084,10 +2096,10 @@ LRESULT CALLBACK windowEnumCallback(HWND hwnd, LPARAM lParam)
- (void) setwindowlevel: (int) level : (int) winNum
{
NSDebugLLog(@"WTrace", @"setwindowlevel: %d : %d", level, winNum);
if (GetWindowLong((HWND)winNum, OFF_LEVEL) != level)
if (GetWindowLongPtr((HWND)winNum, OFF_LEVEL) != level)
{
SetWindowLong((HWND)winNum, OFF_LEVEL, level);
if (GetWindowLong((HWND)winNum, OFF_ORDERED) == YES)
SetWindowLongPtr((HWND)winNum, OFF_LEVEL, level);
if (GetWindowLongPtr((HWND)winNum, OFF_ORDERED) == YES)
{
[self orderwindow: NSWindowAbove : 0 : winNum];
}
@ -2096,7 +2108,7 @@ LRESULT CALLBACK windowEnumCallback(HWND hwnd, LPARAM lParam)
- (int) windowlevel: (int) winNum
{
return GetWindowLong((HWND)winNum, OFF_LEVEL);
return GetWindowLongPtr((HWND)winNum, OFF_LEVEL);
}
- (NSArray *) windowlist
@ -2144,7 +2156,7 @@ LRESULT CALLBACK windowEnumCallback(HWND hwnd, LPARAM lParam)
/** Set the maximum size of the window */
- (void) setmaxsize: (NSSize)size : (int) winNum
{
WIN_INTERN *win = (WIN_INTERN *)GetWindowLong((HWND)winNum, GWL_USERDATA);
WIN_INTERN *win = (WIN_INTERN *)GetWindowLongPtr((HWND)winNum, GWLP_USERDATA);
POINT p;
p.x = size.width;
@ -2154,20 +2166,20 @@ LRESULT CALLBACK windowEnumCallback(HWND hwnd, LPARAM lParam)
// Disable the maximize box if a maximum size is set
if (size.width < 10000 || size.height < 10000)
{
SetWindowLong((HWND)winNum, GWL_STYLE,
GetWindowLong((HWND)winNum, GWL_STYLE) ^ WS_MAXIMIZEBOX);
SetWindowLongPtr((HWND)winNum, GWL_STYLE,
GetWindowLongPtr((HWND)winNum, GWL_STYLE) ^ WS_MAXIMIZEBOX);
}
else
{
SetWindowLong((HWND)winNum, GWL_STYLE,
GetWindowLong((HWND)winNum, GWL_STYLE) | WS_MAXIMIZEBOX);
SetWindowLongPtr((HWND)winNum, GWL_STYLE,
GetWindowLongPtr((HWND)winNum, GWL_STYLE) | WS_MAXIMIZEBOX);
}
}
/** Set the minimum size of the window */
- (void) setminsize: (NSSize)size : (int) winNum
{
WIN_INTERN *win = (WIN_INTERN *)GetWindowLong((HWND)winNum, GWL_USERDATA);
WIN_INTERN *win = (WIN_INTERN *)GetWindowLongPtr((HWND)winNum, GWLP_USERDATA);
POINT p;
p.x = size.width;
@ -2183,7 +2195,7 @@ LRESULT CALLBACK windowEnumCallback(HWND hwnd, LPARAM lParam)
- (void) flushwindowrect: (NSRect)rect : (int)winNum
{
HWND hwnd = (HWND)winNum;
WIN_INTERN *win = (WIN_INTERN *)GetWindowLong(hwnd, GWL_USERDATA);
WIN_INTERN *win = (WIN_INTERN *)GetWindowLongPtr(hwnd, GWLP_USERDATA);
if (win)
{
@ -2290,15 +2302,15 @@ LRESULT CALLBACK windowEnumCallback(HWND hwnd, LPARAM lParam)
{
if (alpha > 0.99)
{
SetWindowLong((HWND)win, GWL_EXSTYLE,
GetWindowLong((HWND)win, GWL_EXSTYLE) & ~WS_EX_LAYERED);
SetWindowLongPtr((HWND)win, GWL_EXSTYLE,
GetWindowLongPtr((HWND)win, GWL_EXSTYLE) & ~WS_EX_LAYERED);
RedrawWindow((HWND)win, NULL, NULL,
RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN);
}
else
{
SetWindowLong((HWND)win, GWL_EXSTYLE,
GetWindowLong((HWND)win, GWL_EXSTYLE) | WS_EX_LAYERED);
SetWindowLongPtr((HWND)win, GWL_EXSTYLE,
GetWindowLongPtr((HWND)win, GWL_EXSTYLE) | WS_EX_LAYERED);
SetLayeredWindowAttributes((HWND)win, 0, 255 * alpha, LWA_ALPHA);
}
}
@ -2430,15 +2442,15 @@ LRESULT CALLBACK windowEnumCallback(HWND hwnd, LPARAM lParam)
- (void) setIgnoreMouse: (BOOL)ignoreMouse : (int)win
{
int extendedStyle = GetWindowLong((HWND)win, GWL_EXSTYLE);
int extendedStyle = GetWindowLongPtr((HWND)win, GWL_EXSTYLE);
if (ignoreMouse)
{
SetWindowLong((HWND)win, GWL_EXSTYLE, extendedStyle | WS_EX_TRANSPARENT);
SetWindowLongPtr((HWND)win, GWL_EXSTYLE, extendedStyle | WS_EX_TRANSPARENT);
}
else
{
SetWindowLong((HWND)win, GWL_EXSTYLE, extendedStyle & ~WS_EX_TRANSPARENT);
SetWindowLongPtr((HWND)win, GWL_EXSTYLE, extendedStyle & ~WS_EX_TRANSPARENT);
}
}

View file

@ -68,8 +68,8 @@
win->useHDC = NO;
// Save win internals structure pointer for window handle...
SetWindowLong(hwnd, GWL_USERDATA, (int)win);
SetWindowLongPtr(hwnd, IME_INFO, (LONG)ime);
SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)win);
SetWindowLongPtr(hwnd, IME_INFO, (LONG_PTR)ime);
[self windowbacking: type : (int)hwnd];

View file

@ -63,7 +63,7 @@
- (void) decodeWM_DESTROYParams: (WPARAM)wParam : (LPARAM)lParam : (HWND)hwnd
{
WIN_INTERN *win = (WIN_INTERN *)GetWindowLong(hwnd, GWL_USERDATA);
WIN_INTERN *win = (WIN_INTERN *)GetWindowLongPtr(hwnd, GWLP_USERDATA);
// Clean up window-specific data objects.

View file

@ -170,9 +170,9 @@
&& GetClassName(hi, buf, 32) == 18
&& strncmp(buf, "GNUstepWindowClass", 18) == 0)
{
if (GetWindowLong(hi, OFF_ORDERED) == 1)
if (GetWindowLongPtr(hi, OFF_ORDERED) == 1)
{
hl = GetWindowLong(hi, OFF_LEVEL);
hl = GetWindowLongPtr(hi, OFF_LEVEL);
s = [s stringByAppendingFormat: @"%d (%d)\n", hi, hl];
}
}
@ -200,8 +200,8 @@
{
if (GetClassName(hi, buf, 32) == 18
&& strncmp(buf, "GNUstepWindowClass", 18) == 0
&& GetWindowLong(hi, OFF_ORDERED) == 1
&& (hl = GetWindowLong(hi, OFF_LEVEL))
&& GetWindowLongPtr(hi, OFF_ORDERED) == 1
&& (hl = GetWindowLongPtr(hi, OFF_LEVEL))
> NSDesktopWindowLevel)
{
break;
@ -220,8 +220,8 @@
{
if (GetClassName(lo, buf, 32) == 18
&& strncmp(buf, "GNUstepWindowClass", 18) == 0
&& GetWindowLong(lo, OFF_ORDERED) == 1
&& (ll = GetWindowLong(lo, OFF_LEVEL))
&& GetWindowLongPtr(lo, OFF_ORDERED) == 1
&& (ll = GetWindowLongPtr(lo, OFF_LEVEL))
> NSDesktopWindowLevel)
{
break;
@ -275,7 +275,7 @@
* to ensure that they are at the bottom unless another
* desktop level window is inserted below them.
*/
if (GetWindowLong(hwnd, OFF_LEVEL) <= NSDesktopWindowLevel)
if (GetWindowLongPtr(hwnd, OFF_LEVEL) <= NSDesktopWindowLevel)
{
inf->hwndInsertAfter = HWND_BOTTOM;
}
@ -284,7 +284,7 @@
- (LRESULT) decodeWM_GETMINMAXINFOParams: (WPARAM)wParam : (LPARAM)lParam : (HWND)hwnd
{
WIN_INTERN *win = (WIN_INTERN *)GetWindowLong(hwnd, GWL_USERDATA);
WIN_INTERN *win = (WIN_INTERN *)GetWindowLongPtr(hwnd, GWLP_USERDATA);
MINMAXINFO *mm;
if (win != NULL)

View file

@ -33,10 +33,22 @@
#include "win32/WIN32Server.h"
#include "win32/WIN32Geometry.h"
// The Windows SDK declares BOOL as an int. Objective C defines BOOl as a char.
// Those two types clash. MinGW's implementation of the Windows SDK uses the WINBOOL
// type to avoid this clash. When compiling natively on Windows, we need to manually
// define WINBOOL.
// MinGW will define _DEF_WINBOOL_ if it has defined WINBOOL so we can use the same trick
// here.
// See https://github.com/mingw-w64/mingw-w64/blob/master/mingw-w64-headers/include/ntdef.h#L355
#ifndef _DEF_WINBOOL_
#define _DEF_WINBOOL_
typedef int WINBOOL;
#endif
static void
invalidateWindow(WIN32Server *svr, HWND hwnd, RECT rect)
{
WIN_INTERN *win = (WIN_INTERN *)GetWindowLong((HWND)hwnd, GWL_USERDATA);
WIN_INTERN *win = (WIN_INTERN *)GetWindowLongPtr((HWND)hwnd, GWLP_USERDATA);
if (!win->useHDC || win->backingStoreEmpty)
{

View file

@ -453,9 +453,14 @@ NSLog(@"No glyph for U%d", c);
logfont.lfItalic = 1;
logfont.lfQuality = DEFAULT_QUALITY;
wcsncpy(logfont.lfFaceName,
(const unichar*)[familyName cStringUsingEncoding: NSUnicodeStringEncoding],
LF_FACESIZE);
if (familyName)
{
wcsncpy(logfont.lfFaceName,
(const unichar*)[familyName cStringUsingEncoding: NSUnicodeStringEncoding],
LF_FACESIZE);
}
hFont = CreateFontIndirectW(&logfont);
if (!hFont)
{

View file

@ -1449,7 +1449,7 @@ HBITMAP GSCreateBitmap(HDC hDC, NSInteger pixelsWide, NSInteger pixelsHigh,
return NULL;
}
win = (WIN_INTERN *)GetWindowLong((HWND)window, GWL_USERDATA);
win = (WIN_INTERN *)GetWindowLongPtr((HWND)window, GWLP_USERDATA);
if (win && win->useHDC)
{
hDC = win->hdc;
@ -1482,7 +1482,7 @@ HBITMAP GSCreateBitmap(HDC hDC, NSInteger pixelsWide, NSInteger pixelsHigh,
}
[self restoreStyle: hDC];
win = (WIN_INTERN *)GetWindowLong((HWND)window, GWL_USERDATA);
win = (WIN_INTERN *)GetWindowLongPtr((HWND)window, GWLP_USERDATA);
if (win && !win->useHDC)
ReleaseDC((HWND)window, hDC);
}

View file

@ -47,14 +47,14 @@
/* Size of the dragged window */
#define DWZ 48
#define XDPY [XGServer currentXDisplay]
#define XDPY [XGServer xDisplay]
#define SLIDE_TIME_STEP .02 /* in seconds */
#define SLIDE_NR_OF_STEPS 20
#define DRAGWINDEV [XGServer _windowWithTag: [_window windowNumber]]
#define XX(P) (P.x)
#define XY(P) (DisplayHeight(XDPY, DRAGWINDEV->screen) - P.y)
#define XY(P) ([(XGServer *)GSCurrentServer() xScreenSize].height - P.y)
@interface XGRawWindow : NSWindow
@end

View file

@ -40,6 +40,7 @@
#include <Foundation/NSString.h>
#include <Foundation/NSUserDefaults.h>
#include <Foundation/NSDebug.h>
#include <Foundation/NSDistributedNotificationCenter.h>
#include <signal.h>
/* Terminate cleanly if we get a signal to do so */
@ -68,6 +69,10 @@ terminate(int sig)
#include "x11/XGOpenGL.h"
#endif
#ifdef HAVE_XRANDR
#include <X11/extensions/Xrandr.h>
#endif
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/keysym.h>
@ -136,7 +141,7 @@ _parse_display_name(NSString *name, int *dn, int *sn)
XGDrawMechanism drawMechanism;
}
- initForDisplay: (Display *)dpy screen: (int)screen_number;
- initForDisplay: (Display *)dpy screen: (int)screen_id;
- (XGDrawMechanism) drawMechanism;
- (RContext *) context;
@end
@ -168,7 +173,7 @@ _parse_display_name(NSString *name, int *dn, int *sn)
return attribs;
}
- initForDisplay: (Display *)dpy screen: (int)screen_number
- initForDisplay: (Display *)dpy screen: (int)screen_id
{
RContextAttributes *attribs;
XColor testColor;
@ -177,7 +182,7 @@ _parse_display_name(NSString *name, int *dn, int *sn)
/* Get the visual information */
attribs = NULL;
//attribs = [self _getXDefaults];
rcontext = RCreateContext(dpy, screen_number, attribs);
rcontext = RCreateContext(dpy, screen_id, attribs);
/*
* If we have shared memory available, only use it when the XGPS-Shm
@ -286,7 +291,7 @@ _parse_display_name(NSString *name, int *dn, int *sn)
drawMechanism = XGDM_PORTABLE;
}
NSDebugLLog(@"XGTrace", @"Draw mech %d for screen %d", drawMechanism,
screen_number);
screen_id);
return self;
}
@ -372,14 +377,14 @@ _parse_display_name(NSString *name, int *dn, int *sn)
Returns a pointer to the current X-Windows display variable for
the current context.
*/
+ (Display*) currentXDisplay
+ (Display *) xDisplay
{
return [(XGServer*)GSCurrentServer() xDisplay];
}
- (id) _initXContext
{
int screen_number, display_number;
int screen_id, display_id;
NSString *display_name;
display_name = [server_info objectForKey: GSDisplayName];
@ -411,6 +416,8 @@ _parse_display_name(NSString *name, int *dn, int *sn)
}
}
XInitThreads();
if (display_name)
{
dpy = XOpenDisplay([display_name cString]);
@ -429,13 +436,13 @@ _parse_display_name(NSString *name, int *dn, int *sn)
}
/* Parse display information */
_parse_display_name(display_name, &display_number, &screen_number);
_parse_display_name(display_name, &display_id, &screen_id);
NSDebugLog(@"Opened display %@, display %d screen %d",
display_name, display_number, screen_number);
display_name, display_id, screen_id);
[server_info setObject: display_name forKey: GSDisplayName];
[server_info setObject: [NSNumber numberWithInt: display_number]
[server_info setObject: [NSNumber numberWithInt: display_id]
forKey: GSDisplayNumber];
[server_info setObject: [NSNumber numberWithInt: screen_number]
[server_info setObject: [NSNumber numberWithInt: screen_id]
forKey: GSScreenNumber];
/* Setup screen*/
@ -443,7 +450,11 @@ _parse_display_name(NSString *name, int *dn, int *sn)
screenList = NSCreateMapTable(NSIntMapKeyCallBacks,
NSObjectMapValueCallBacks, 20);
defScreen = screen_number;
defScreen = screen_id;
/* Enumerate monitors */
if (monitors == NULL)
[self screenList];
XSetErrorHandler(XGErrorHandler);
@ -462,6 +473,11 @@ _parse_display_name(NSString *name, int *dn, int *sn)
[self _setupRootWindow];
inputServer = [[XIMInputServer allocWithZone: [self zone]]
initWithDelegate: nil display: dpy name: @"XIM"];
#ifdef HAVE_XRANDR
XRRQueryExtension(dpy, &randrEventBase, &randrErrorBase);
XRRSelectInput(dpy, RootWindow(dpy, defScreen), RRScreenChangeNotifyMask);
#endif
return self;
}
@ -487,9 +503,14 @@ _parse_display_name(NSString *name, int *dn, int *sn)
- (void) dealloc
{
NSDebugLog(@"Destroying X11 Server");
[[NSDistributedNotificationCenter defaultCenter] removeObserver:self];
DESTROY(inputServer);
[self _destroyServerWindows];
NSFreeMapTable(screenList);
if (monitors != NULL)
{
NSZoneFree([self zone], monitors);
}
XCloseDisplay(dpy);
[super dealloc];
}
@ -502,46 +523,62 @@ _parse_display_name(NSString *name, int *dn, int *sn)
return dpy;
}
- (XGScreenContext *) _screenContextForScreen: (int)screen_number
/**
Returns the root window of the display
*/
- (Window) xDisplayRootWindow;
{
int count = ScreenCount(dpy);
XGScreenContext *screen;
if (screen_number >= count)
{
[NSException raise: NSInvalidArgumentException
format: @"Request for invalid screen"];
}
screen = NSMapGet(screenList, (void *)(uintptr_t)screen_number);
if (screen == NULL)
{
screen = [[XGScreenContext alloc]
initForDisplay: dpy screen: screen_number];
NSMapInsert(screenList, (void *)(uintptr_t)screen_number, (void *)screen);
RELEASE(screen);
}
return screen;
return RootWindow(dpy, defScreen);
}
/**
Returns the application root window, which is used for many things
such as window hints
*/
- (Window) xAppRootWindow
{
return generic.appRootWindow;
}
- (NSSize) xScreenSize
{
return xScreenSize;
}
- (XGScreenContext *) _defaultScreenContext
{
XGScreenContext *screenCtxt;
screenCtxt = NSMapGet(screenList, (void *)(uintptr_t)defScreen);
if (screenCtxt == NULL)
{
screenCtxt = [[XGScreenContext alloc] initForDisplay: dpy
screen: defScreen];
NSMapInsert(screenList, (void *)(uintptr_t)defScreen, (void *)screenCtxt);
RELEASE(screenCtxt);
}
return screenCtxt;
}
/**
Returns a pointer to a structure which describes aspects of the
X windows display
*/
- (void *) xrContextForScreen: (int)screen_number
- (void *) screenRContext
{
return [[self _screenContextForScreen: screen_number] context];
return [[self _defaultScreenContext] context];
}
- (Visual *) visualForScreen: (int)screen_number
- (Visual *) screenVisual
{
return [[self _screenContextForScreen: screen_number] context]->visual;
return [[self _defaultScreenContext] context]->visual;
}
- (int) depthForScreen: (int)screen_number
- (int) screenDepth
{
return [[self _screenContextForScreen: screen_number] context]->depth;
return [[self _defaultScreenContext] context]->depth;
}
/**
@ -549,9 +586,9 @@ _parse_display_name(NSString *name, int *dn, int *sn)
the screen and how pixels should be drawn to the screen for maximum
speed.
*/
- (XGDrawMechanism) drawMechanismForScreen: (int)screen_number
- (XGDrawMechanism) screenDrawMechanism
{
return [[self _screenContextForScreen: screen_number] drawMechanism];
return [[self _defaultScreenContext] drawMechanism];
}
// Could use NSSwapInt() instead
@ -583,48 +620,18 @@ static int byte_order(void)
/**
* Used by the art backend to determine the drawing mechanism.
*/
- (void) getForScreen: (int)screen_number pixelFormat: (int *)bpp_number
- (void) getForScreen: (int)screen_id pixelFormat: (int *)bpp_number
masks: (int *)red_mask : (int *)green_mask : (int *)blue_mask
{
Visual *visual;
XImage *i;
int bpp;
#if 0
XVisualInfo template;
XVisualInfo *visualInfo;
int numMatches;
/*
We need a visual that we can generate pixel values for by ourselves.
Thus, we try to find a DirectColor or TrueColor visual. If that fails,
we use the default visual and hope that it's usable.
*/
template.class = DirectColor;
visualInfo = XGetVisualInfo(dpy, VisualClassMask, &template, &numMatches);
if (!visualInfo)
{
template.class = TrueColor;
visualInfo = XGetVisualInfo(dpy, VisualClassMask, &template, &numMatches);
}
if (visualInfo)
{
visual = visualInfo->visual;
bpp = visualInfo->depth;
XFree(visualInfo);
}
else
{
visual = DefaultVisual(dpy, DefaultScreen(dpy));
bpp = DefaultDepth(dpy, DefaultScreen(dpy));
}
#else
RContext *context;
// Better to get the used visual from the context.
context = [self xrContextForScreen: screen_number];
context = [self screenRContext];
visual = context->visual;
bpp = context->depth;
#endif
i = XCreateImage(dpy, visual, bpp, ZPixmap, 0, NULL, 8, 8, 8, 0);
bpp = i->bits_per_pixel;
@ -660,44 +667,28 @@ static int byte_order(void)
}
}
/**
Returns the root window of the display
*/
- (Window) xDisplayRootWindowForScreen: (int)screen_number;
{
return RootWindow(dpy, screen_number);
}
/**
Returns the closest color in the current colormap to the indicated
X color
*/
- (XColor) xColorFromColor: (XColor)color forScreen: (int)screen_number
- (XColor) xColorFromColor: (XColor)color
{
Status ret;
RColor rcolor;
RContext *context = [self xrContextForScreen: screen_number];
RContext *context = [self screenRContext];
XAllocColor(dpy, context->cmap, &color);
rcolor.red = color.red / 256;
rcolor.green = color.green / 256;
rcolor.blue = color.blue / 256;
ret = RGetClosestXColor(context, &rcolor, &color);
if (ret == False)
NSLog(@"Failed to alloc color (%d,%d,%d)\n",
(int)rcolor.red, (int)rcolor.green, (int)rcolor.blue);
{
NSLog(@"Failed to alloc color (%d,%d,%d)\n",
(int)rcolor.red, (int)rcolor.green, (int)rcolor.blue);
}
return color;
}
/**
Returns the application root window, which is used for many things
such as window hints
*/
- (Window) xAppRootWindow
{
return generic.appRootWindow;
}
/**
Wait for all contexts to finish processing. Only used with XDPS graphics.
*/
@ -788,7 +779,6 @@ static int byte_order(void)
@end // XGServer (InputMethod)
//==== Additional code for NSTextView =========================================
//
// WARNING This section is not genuine part of the XGServer implementation.
@ -806,6 +796,11 @@ static int byte_order(void)
#include <AppKit/NSClipView.h>
#include <AppKit/NSTextView.h>
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wobjc-protocol-method-implementation"
#endif
@implementation NSTextView (InputMethod)
- (void) _updateInputMethodState
@ -918,4 +913,8 @@ static int byte_order(void)
}
@end // NSTextView
#if defined(__clang__)
#pragma clang diagnostic pop
#endif
//==== End: Additional Code for NSTextView ====================================

View file

@ -32,6 +32,7 @@
#include <AppKit/NSMenu.h>
#include <AppKit/NSPasteboard.h>
#include <AppKit/NSWindow.h>
#include <AppKit/NSScreen.h>
#include <Foundation/NSException.h>
#include <Foundation/NSArray.h>
#include <Foundation/NSDictionary.h>
@ -42,6 +43,7 @@
#include <Foundation/NSUserDefaults.h>
#include <Foundation/NSRunLoop.h>
#include <Foundation/NSDebug.h>
#include <Foundation/NSDistributedNotificationCenter.h>
#include "x11/XGServerWindow.h"
#include "x11/XGInputServer.h"
@ -54,6 +56,9 @@
#else
#include "x11/wraster.h"
#endif
#ifdef HAVE_XRANDR
#include <X11/extensions/Xrandr.h>
#endif
#include "math.h"
#include <X11/keysym.h>
@ -89,6 +94,16 @@ static KeySym _help_keysyms[2];
static BOOL _is_keyboard_initialized = NO;
static BOOL _mod_ignore_shift = NO;
/*
Mouse properties. In comments below specified defaults key and default value.
*/
static NSInteger clickTime; // "GSDoubleClickTime" - milisecond (250)
static NSInteger clickMove; // "GSMouseMoveThreshold" - in pixels (3)
static NSInteger mouseScrollMultiplier; // "GSMouseScrollMultiplier" - times (1)
static NSEventType menuMouseButton; // "GSMenuButtonEvent" - (NSRightMouseButon)
static BOOL menuButtonEnabled; // "GSMenuButtonEnabled" - BOOL
static BOOL swapMouseButtons; // YES if "GSMenuButtonEvent" == NSLeftMouseButton
void __objc_xgcontextevent_linking (void)
{
}
@ -328,6 +343,52 @@ posixFileDescriptor: (NSPosixFileDescriptor*)fileDescriptor
return o;
}
- (void) mouseOptionsChanged: (NSNotification *)aNotif
{
NSUserDefaults *defs = [NSUserDefaults standardUserDefaults];
clickTime = [defs integerForKey:@"GSDoubleClickTime"];
if (clickTime < 200)
clickTime = 300;
clickMove = [defs integerForKey:@"GSMouseMoveThreshold"];
if (clickMove < 3)
clickMove = 3;
mouseScrollMultiplier = [defs integerForKey:@"GSMouseScrollMultiplier"];
if (mouseScrollMultiplier == 0)
mouseScrollMultiplier = 1;
if ([defs objectForKey:@"GSMenuButtonEnabled"])
menuButtonEnabled = [defs boolForKey:@"GSMenuButtonEnabled"];
else
menuButtonEnabled = YES;
if ([defs objectForKey:@"GSMenuButtonEvent"])
menuMouseButton = [defs integerForKey:@"GSMenuButtonEvent"];
else
menuMouseButton = NSRightMouseDown;
switch (menuMouseButton)
{
case NSLeftMouseDown:
swapMouseButtons = YES;
break;
default:
swapMouseButtons = NO;
break;
}
}
- (void) initializeMouse
{
[self mouseOptionsChanged: nil];
[[NSDistributedNotificationCenter defaultCenter]
addObserver: self
selector: @selector(mouseOptionsChanged:)
name: NSUserDefaultsDidChangeNotification
object: nil];
}
- (void) processEvent: (XEvent *) event
{
@ -366,21 +427,21 @@ posixFileDescriptor: (NSPosixFileDescriptor*)fileDescriptor
*/
{
BOOL incrementCount = YES;
#define CLICK_TIME 300
#define CLICK_MOVE 3
if (clickTime == 0) [self initializeMouse];
if (xEvent.xbutton.time
>= (unsigned long)(generic.lastClick + CLICK_TIME))
>= (unsigned long)(generic.lastClick + clickTime))
incrementCount = NO;
else if (generic.lastClickWindow != xEvent.xbutton.window)
incrementCount = NO;
else if ((generic.lastClickX - xEvent.xbutton.x) > CLICK_MOVE)
else if ((generic.lastClickX - xEvent.xbutton.x) > clickMove)
incrementCount = NO;
else if ((generic.lastClickX - xEvent.xbutton.x) < -CLICK_MOVE)
else if ((generic.lastClickX - xEvent.xbutton.x) < -clickMove)
incrementCount = NO;
else if ((generic.lastClickY - xEvent.xbutton.y) > CLICK_MOVE)
else if ((generic.lastClickY - xEvent.xbutton.y) > clickMove)
incrementCount = NO;
else if ((generic.lastClickY - xEvent.xbutton.y) < -CLICK_MOVE)
else if ((generic.lastClickY - xEvent.xbutton.y) < -clickMove)
incrementCount = NO;
if (incrementCount == YES)
@ -407,46 +468,62 @@ posixFileDescriptor: (NSPosixFileDescriptor*)fileDescriptor
if (xEvent.xbutton.button == generic.lMouse)
{
eventType = NSLeftMouseDown;
buttonNumber = generic.lMouse;
if (swapMouseButtons)
{
eventType = NSRightMouseDown;
buttonNumber = generic.rMouse;
}
else
{
eventType = NSLeftMouseDown;
buttonNumber = generic.lMouse;
}
}
else if (xEvent.xbutton.button == generic.rMouse
&& generic.rMouse != 0)
&& generic.rMouse != 0)
{
eventType = NSRightMouseDown;
buttonNumber = generic.rMouse;
if (swapMouseButtons)
{
eventType = NSLeftMouseDown;
buttonNumber = generic.lMouse;
}
else
{
eventType = NSRightMouseDown;
buttonNumber = generic.rMouse;
}
}
else if (xEvent.xbutton.button == generic.mMouse
&& generic.mMouse != 0)
&& generic.mMouse != 0)
{
eventType = NSOtherMouseDown;
buttonNumber = generic.mMouse;
}
else if (xEvent.xbutton.button == generic.upMouse
&& generic.upMouse != 0)
&& generic.upMouse != 0)
{
deltaY = 1.;
deltaY = 1. * mouseScrollMultiplier;
eventType = NSScrollWheel;
buttonNumber = generic.upMouse;
}
else if (xEvent.xbutton.button == generic.downMouse
&& generic.downMouse != 0)
&& generic.downMouse != 0)
{
deltaY = -1.;
deltaY = -1. * mouseScrollMultiplier;
eventType = NSScrollWheel;
buttonNumber = generic.downMouse;
}
else if (xEvent.xbutton.button == generic.scrollLeftMouse
&& generic.scrollLeftMouse != 0)
&& generic.scrollLeftMouse != 0)
{
deltaX = -1.;
deltaX = -1. * mouseScrollMultiplier;
eventType = NSScrollWheel;
buttonNumber = generic.scrollLeftMouse;
}
else if (xEvent.xbutton.button == generic.scrollRightMouse
&& generic.scrollRightMouse != 0)
&& generic.scrollRightMouse != 0)
{
deltaX = 1.;
deltaX = 1. * mouseScrollMultiplier;
eventType = NSScrollWheel;
buttonNumber = generic.scrollRightMouse;
}
@ -455,6 +532,9 @@ posixFileDescriptor: (NSPosixFileDescriptor*)fileDescriptor
break; /* Unknown button */
}
if (menuButtonEnabled == NO && eventType == menuMouseButton)
break; // disabled menu button was pressed
eventFlags = process_modifier_flags(xEvent.xbutton.state);
// if pointer is grabbed use grab window
xWin = (grabWindow == 0) ? xEvent.xbutton.window : grabWindow;
@ -472,10 +552,10 @@ posixFileDescriptor: (NSPosixFileDescriptor*)fileDescriptor
/*
* We must hand over control of our icon/miniwindow
* to Window Maker.
*/
*/
if ((cWin->win_attrs.window_style
& (NSMiniWindowMask | NSIconWindowMask)) != 0
&& eventType == NSLeftMouseDown && clickCount == 1)
& (NSMiniWindowMask | NSIconWindowMask)) != 0
&& eventType == NSLeftMouseDown)
{
if (cWin->parent == None)
break;
@ -484,7 +564,8 @@ posixFileDescriptor: (NSPosixFileDescriptor*)fileDescriptor
XSendEvent(dpy, cWin->parent, True,
ButtonPressMask, &xEvent);
XFlush(dpy);
break;
if (clickCount == 1)
break;
}
}
@ -510,17 +591,33 @@ posixFileDescriptor: (NSPosixFileDescriptor*)fileDescriptor
[self setLastTime: xEvent.xbutton.time];
if (xEvent.xbutton.button == generic.lMouse)
{
eventType = NSLeftMouseUp;
buttonNumber = generic.lMouse;
if (swapMouseButtons)
{
eventType = NSRightMouseUp;
buttonNumber = generic.rMouse;
}
else
{
eventType = NSLeftMouseUp;
buttonNumber = generic.lMouse;
}
}
else if (xEvent.xbutton.button == generic.rMouse
&& generic.rMouse != 0)
&& generic.rMouse != 0)
{
eventType = NSRightMouseUp;
buttonNumber = generic.rMouse;
if (swapMouseButtons)
{
eventType = NSLeftMouseUp;
buttonNumber = generic.lMouse;
}
else
{
eventType = NSRightMouseUp;
buttonNumber = generic.rMouse;
}
}
else if (xEvent.xbutton.button == generic.mMouse
&& generic.mMouse != 0)
&& generic.mMouse != 0)
{
eventType = NSOtherMouseUp;
buttonNumber = generic.mMouse;
@ -530,6 +627,9 @@ posixFileDescriptor: (NSPosixFileDescriptor*)fileDescriptor
// we ignore release of scrollUp or scrollDown
break; /* Unknown button */
}
if (menuButtonEnabled == NO && eventType == menuMouseButton)
break; // disabled menu button was released
eventFlags = process_modifier_flags(xEvent.xbutton.state);
// if pointer is grabbed use grab window
@ -583,13 +683,13 @@ posixFileDescriptor: (NSPosixFileDescriptor*)fileDescriptor
}
if (cWin == 0)
break;
if (xEvent.xclient.message_type == generic.protocols_atom)
if (xEvent.xclient.message_type == generic.WM_PROTOCOLS_ATOM)
{
[self setLastTime: (Time)xEvent.xclient.data.l[1]];
NSDebugLLog(@"NSEvent", @"WM Protocol - %s\n",
XGetAtomName(dpy, xEvent.xclient.data.l[0]));
if ((Atom)xEvent.xclient.data.l[0] == generic.delete_win_atom)
if ((Atom)xEvent.xclient.data.l[0] == generic.WM_DELETE_WINDOW_ATOM)
{
/*
* WM is asking us to close a window
@ -606,7 +706,7 @@ posixFileDescriptor: (NSPosixFileDescriptor*)fileDescriptor
data2: 0];
}
else if ((Atom)xEvent.xclient.data.l[0]
== generic.miniaturize_atom)
== generic._GNUSTEP_WM_MINIATURIZE_WINDOW_ATOM)
{
NSDebugLLog(@"Miniaturize", @"%lu miniaturized", cWin->number);
eventLocation = NSMakePoint(0,0);
@ -621,22 +721,37 @@ posixFileDescriptor: (NSPosixFileDescriptor*)fileDescriptor
data2: 0];
}
else if ((Atom)xEvent.xclient.data.l[0]
== generic.take_focus_atom)
== generic._GNUSTEP_WM_HIDE_APP_ATOM)
{
NSDebugLLog(@"Hide", @"%lu application will be hidden", cWin->number);
eventLocation = NSMakePoint(0,0);
e = [NSEvent otherEventWithType: NSAppKitDefined
location: eventLocation
modifierFlags: 0
timestamp: 0
windowNumber: cWin->number
context: gcontext
subtype: GSAppKitAppHide
data1: 0
data2: 0];
}
else if ((Atom)xEvent.xclient.data.l[0]
== generic.WM_TAKE_FOCUS_ATOM)
{
e = [self _handleTakeFocusAtom: xEvent
forContext: gcontext];
}
else if ((Atom)xEvent.xclient.data.l[0]
== generic.net_wm_ping_atom)
== generic._NET_WM_PING_ATOM)
{
xEvent.xclient.window = RootWindow(dpy, cWin->screen);
xEvent.xclient.window = RootWindow(dpy, cWin->screen_id);
XSendEvent(dpy, xEvent.xclient.window, False,
(SubstructureRedirectMask | SubstructureNotifyMask),
&xEvent);
}
#ifdef HAVE_X11_EXTENSIONS_SYNC_H
else if ((Atom)xEvent.xclient.data.l[0]
== generic.net_wm_sync_request_atom)
== generic._NET_WM_SYNC_REQUEST_ATOM)
{
cWin->net_wm_sync_request_counter_value_low = (Atom)xEvent.xclient.data.l[2];
cWin->net_wm_sync_request_counter_value_high = (Atom)xEvent.xclient.data.l[3];
@ -681,7 +796,7 @@ posixFileDescriptor: (NSPosixFileDescriptor*)fileDescriptor
send ConfigureNotify events for app icons.
*/
XTranslateCoordinates(dpy, xEvent.xclient.window,
RootWindow(dpy, cWin->screen),
RootWindow(dpy, cWin->screen_id),
0, 0,
&root_x, &root_y,
&root_child);
@ -850,7 +965,7 @@ posixFileDescriptor: (NSPosixFileDescriptor*)fileDescriptor
int root_x, root_y;
Window root_child;
XTranslateCoordinates(dpy, xEvent.xconfigure.window,
RootWindow(dpy, cWin->screen),
RootWindow(dpy, cWin->screen_id),
0, 0,
&root_x, &root_y,
&root_child);
@ -914,6 +1029,7 @@ posixFileDescriptor: (NSPosixFileDescriptor*)fileDescriptor
if (!NSEqualPoints(r.origin, x.origin))
{
NSEvent *r;
NSWindow *window;
r = [NSEvent otherEventWithType: NSAppKitDefined
location: eventLocation
@ -930,7 +1046,12 @@ posixFileDescriptor: (NSPosixFileDescriptor*)fileDescriptor
* the programa can move/resize the window while we send
* this event, causing a confusion.
*/
[[NSApp windowWithWindowNumber: cWin->number] sendEvent: r];
window = [NSApp windowWithWindowNumber: cWin->number];
[window sendEvent: r];
/* Update monitor_id of the backend window.
NSWindow may change screen pointer while processing
the event. */
cWin->monitor_id = [[window screen] screenNumber];
}
}
break;
@ -1470,7 +1591,7 @@ posixFileDescriptor: (NSPosixFileDescriptor*)fileDescriptor
NSDebugLLog(@"NSEvent", @"%lu PropertyNotify - '%s'\n",
xEvent.xproperty.window,
XGetAtomName(dpy, xEvent.xproperty.atom));
if (xEvent.xproperty.atom == generic.wm_state_atom)
if (xEvent.xproperty.atom == generic.WM_STATE_ATOM)
{
if (cWin == 0 || xEvent.xproperty.window != cWin->ident)
{
@ -1505,7 +1626,7 @@ posixFileDescriptor: (NSPosixFileDescriptor*)fileDescriptor
[self _ewmh_isHidden: xEvent.xproperty.window] == YES))
{
/* Same event as when we get ClientMessage with the
* atom equal to generic.miniaturize_atom
* atom equal to generic._GNUSTEP_WM_MINIATURIZE_WINDOW_ATOM
*/
NSDebugLLog(@"Miniaturize", @"%lu miniaturized",
cWin->number);
@ -1710,8 +1831,8 @@ posixFileDescriptor: (NSPosixFileDescriptor*)fileDescriptor
* of type 'long' or 'unsigned long' even on machines where those types
* hold 64bit values.
*/
XChangeProperty(dpy, cWin->ident, generic.win_decor_atom,
generic.win_decor_atom, 32, PropModeReplace,
XChangeProperty(dpy, cWin->ident, generic._GNUSTEP_WM_ATTR_ATOM,
generic._GNUSTEP_WM_ATTR_ATOM, 32, PropModeReplace,
(unsigned char *)&cWin->win_attrs,
sizeof(GNUstepWMAttributes)/sizeof(CARD32));
}
@ -1743,27 +1864,19 @@ posixFileDescriptor: (NSPosixFileDescriptor*)fileDescriptor
NSArray *types = [pb types];
NSData *data = nil;
Atom xType = xEvent.xselectionrequest.target;
static Atom XG_UTF8_STRING = None;
static Atom XG_TEXT = None;
if (XG_UTF8_STRING == None)
{
XG_UTF8_STRING = XInternAtom(dpy, "UTF8_STRING", False);
XG_TEXT = XInternAtom(dpy, "TEXT", False);
}
if (((xType == XG_UTF8_STRING) ||
if (((xType == generic.UTF8_STRING_ATOM) ||
(xType == XA_STRING) ||
(xType == XG_TEXT)) &&
(xType == generic.TEXT_ATOM)) &&
[types containsObject: NSStringPboardType])
{
NSString *s = [pb stringForType: NSStringPboardType];
if (xType == XG_UTF8_STRING)
if (xType == generic.UTF8_STRING_ATOM)
{
data = [s dataUsingEncoding: NSUTF8StringEncoding];
}
else if ((xType == XA_STRING) || (xType == XG_TEXT))
else if ((xType == XA_STRING) || (xType == generic.TEXT_ATOM))
{
data = [s dataUsingEncoding: NSISOLatin1StringEncoding];
}
@ -1791,6 +1904,25 @@ posixFileDescriptor: (NSPosixFileDescriptor*)fileDescriptor
((XShmCompletionEvent *)&xEvent)->drawable];
break;
}
#endif
#ifdef HAVE_XRANDR
int randr_event_type = randrEventBase + RRScreenChangeNotify;
if (xEvent.type == randr_event_type
&& (xEvent.xconfigure.window == RootWindow(dpy, defScreen)))
{
// Check if other RandR events are waiting in the queue.
XSync(dpy, 0);
while (XCheckTypedEvent(dpy, randr_event_type, &xEvent)) {;}
XRRUpdateConfiguration(event);
// Regenerate NSScreens
[NSScreen resetScreens];
// Notify application about screen parameters change
[[NSNotificationCenter defaultCenter]
postNotificationName: NSApplicationDidChangeScreenParametersNotification
object: NSApp];
}
break;
#endif
NSLog(@"Received an untrapped event\n");
break;
@ -1808,21 +1940,15 @@ posixFileDescriptor: (NSPosixFileDescriptor*)fileDescriptor
- (NSEvent *)_handleTakeFocusAtom: (XEvent)xEvent
forContext: (NSGraphicsContext *)gcontext
{
int key_num;
NSWindow *key_win;
NSWindow *keyWindow = [NSApp keyWindow];
int key_num = [keyWindow windowNumber];
NSEvent *e = nil;
key_win = [NSApp keyWindow];
key_num = [key_win windowNumber];
NSDebugLLog(@"Focus", @"take focus:%lu (current=%lu key=%d)",
cWin->number, generic.currentFocusWindow, key_num);
/* Sometimes window managers lose the setinputfocus on the key window
* e.g. when ordering out a window with focus then ordering in the key window.
* it might search for a window until one accepts its take focus request.
*/
if (key_num == cWin->number)
cWin->ignore_take_focus = NO;
NSDebugLLog(@"Focus",
@"TakeFocus received by: %li (%lu) (focused = %lu, key = %d)",
cWin->number, xEvent.xfocus.window,
generic.currentFocusWindow, key_num);
/* Invalidate the previous request. It's possible the app lost focus
before this request was fufilled and we are being focused again,
or ??? */
@ -1830,6 +1956,20 @@ posixFileDescriptor: (NSPosixFileDescriptor*)fileDescriptor
generic.focusRequestNumber = 0;
generic.desiredFocusWindow = 0;
}
/* Sometimes window managers lose the setinputfocus on the key window
* e.g. when ordering out a window with focus then ordering in the key window.
* it might search for a window until one accepts its take focus request.
*/
if (key_num == 0)
{
cWin->ignore_take_focus = NO;
}
else if (cWin->number == [[[NSApp mainMenu] window] windowNumber])
{
cWin->ignore_take_focus = NO;
}
/* We'd like to send this event directly to the front-end to handle,
but the front-end polls events so slowly compared the speed at
which X events could potentially come that we could easily get
@ -1837,10 +1977,21 @@ posixFileDescriptor: (NSPosixFileDescriptor*)fileDescriptor
events */
if ([NSApp isHidden])
{
/* This often occurs when hidding an app, since a bunch of
windows get hidden at once, and the WM is searching for a
window to take focus after each one gets hidden. */
NSDebugLLog(@"Focus", @"WM take focus while hiding");
if (generic.wm & XGWM_WINDOWMAKER)
{
/* If window receives WM_TAKE_FOCUS and application is in hidden
state - it's time to unhide. There's no other method to
tell us to unhide. */
NSDebugLLog(@"Focus", @"WM take focus while hidden - unhiding.");
[NSApp unhide: nil];
}
else
{
/* This often occurs when hidding an app, since a bunch of
windows get hidden at once, and the WM is searching for a
window to take focus after each one gets hidden. */
NSDebugLLog(@"Focus", @"WM take focus while hiding");
}
}
else if (cWin->ignore_take_focus == YES)
{
@ -1850,23 +2001,31 @@ posixFileDescriptor: (NSPosixFileDescriptor*)fileDescriptor
else if (cWin->number == key_num)
{
NSDebugLLog(@"Focus", @"Reasserting key window");
[GSServerForWindow(key_win) setinputfocus: key_num];
[GSServerForWindow(keyWindow) setinputfocus: key_num];
}
else if (key_num
&& cWin->number == [[[NSApp mainMenu] window] windowNumber])
{
gswindow_device_t *key_window = [XGServer _windowWithTag:key_num];
/* This might occur when the window manager just wants someone
to become key, so it tells the main menu (typically the first
menu in the list), but since we already have a window that
was key before, use that instead */
NSDebugLLog(@"Focus", @"Key window is already %d", key_num);
[GSServerForWindow(key_win) setinputfocus: key_num];
if (key_window->map_state == IsUnmapped) {
/* `key_window` was unmapped by window manager.
this window and `key_window` are on the different workspace. */
[GSServerForWindow(keyWindow) setinputfocus: cWin->number];
}
else {
[GSServerForWindow(keyWindow) setinputfocus: key_num];
}
}
else
{
NSPoint eventLocation;
/*
* Here the app asked for this (if key_win==nil) or there was a
* Here the app asked for this (if keyWindow==nil) or there was a
* click on the title bar or some other reason (window mapped,
* etc). We don't necessarily want to forward the event for the
* last reason but we just have to deal with that since we can
@ -1924,7 +2083,7 @@ static void
initialize_keyboard (void)
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
Display *display = [XGServer currentXDisplay];
Display *display = [XGServer xDisplay];
// Below must be stored and checked as keysyms, not keycodes, since
// more than one keycode may be mapped t the same keysym
@ -1998,7 +2157,7 @@ set_up_num_lock (void)
ShiftMask, LockMask, ControlMask, Mod1Mask,
Mod2Mask, Mod3Mask, Mod4Mask, Mod5Mask
};
Display *display = [XGServer currentXDisplay];
Display *display = [XGServer xDisplay];
KeyCode _num_lock_keycode;
// Get NumLock keycode
@ -2526,12 +2685,16 @@ process_modifier_flags(unsigned int state)
BOOL ok;
NSPoint p;
int height;
int screen_number;
screen_number = (screen >= 0) ? screen : defScreen;
ok = XQueryPointer (dpy, [self xDisplayRootWindowForScreen: screen_number],
&rootWin, &childWin, &currentX, &currentY, &winX, &winY, &mask);
int screen_id;
ok = XQueryPointer (dpy, [self xDisplayRootWindow],
&rootWin, &childWin, &currentX, &currentY,
&winX, &winY, &mask);
p = NSMakePoint(-1,-1);
/* FIXME: After multi-monitor support will be implemented `screen` method
parameter doesn't make sense. The `if{}` block should be removed since
we have only one screen and mouse can't be placed on "wrong" screen.
Also actually we need `height` of the whole Xlib screen (defScreen). */
if (ok == False)
{
/* Mouse not on the specified screen_number */
@ -2541,8 +2704,8 @@ process_modifier_flags(unsigned int state)
{
return p;
}
screen_number = XScreenNumberOfScreen(attribs.screen);
if (screen >= 0 && screen != screen_number)
screen_id = XScreenNumberOfScreen(attribs.screen);
if (screen >= 0 && screen != screen_id)
{
/* Mouse not on the requred screen, return an invalid point */
return p;
@ -2550,7 +2713,9 @@ process_modifier_flags(unsigned int state)
height = attribs.height;
}
else
height = DisplayHeight(dpy, screen_number);
{
height = xScreenSize.height;
}
p = NSMakePoint(currentX, height - currentY);
if (win)
{

File diff suppressed because it is too large Load diff

View file

@ -61,7 +61,7 @@
- (id) initWithDelegate: (id)aDelegate
name: (NSString *)name
{
Display *dpy = [XGServer currentXDisplay];
Display *dpy = [XGServer xDisplay];
return [self initWithDelegate: aDelegate display: dpy name: name];
}
@ -151,12 +151,18 @@
{
/* Always returns a Latin-1 string according to the manpage */
count = XLookupString (event, buf, BUF_LEN, &keysym, NULL);
if (count)
if (count == 1)
{
keys = [[[NSString alloc] initWithBytes: buf
length: count
encoding: NSISOLatin1StringEncoding] autorelease];
}
else if (count > 1) // manpage lies and we suppose UTF-8
{
keys = [[[NSString alloc] initWithBytes: buf
length: count
encoding: NSUTF8StringEncoding] autorelease];
}
if (keysymptr)
*keysymptr = keysym;
@ -380,7 +386,7 @@ betterStyle(XIMStyle a, XIMStyle b, XIMStyle xim_requested_style)
}
else if (xim_style == OffTheSpotStyle || xim_style == OverTheSpotStyle)
{
Display *dpy = [XGServer currentXDisplay];
Display *dpy = [XGServer xDisplay];
XFontSet font_set;
char **missing_charset;
int num_missing_charset;
@ -556,7 +562,7 @@ finish:
if (XGetICValues(xics[num_xics - 1], XNClientWindow, &win, NULL))
return NO;
dpy = [XGServer currentXDisplay];
dpy = [XGServer xDisplay];
if (XTranslateCoordinates(dpy, win, DefaultRootWindow(dpy), 0, 0,
&abs_x, &abs_y, &dummy) == 0)
return NO;

View file

@ -222,8 +222,8 @@ no_xshm:
visual = DefaultVisual(wi->display, DefaultScreen(wi->display));
#else
// Better to get the used visual from the XGServer.
visual = [(XGServer*)GSCurrentServer() visualForScreen: awindow->screen];
drawing_depth = [(XGServer*)GSCurrentServer() depthForScreen: awindow->screen];
visual = [(XGServer*)GSCurrentServer() screenVisual];
drawing_depth = [(XGServer*)GSCurrentServer() screenDepth];
#endif
/* TODO: resolve properly.

View file

@ -351,6 +351,8 @@ image2TrueColor(RContext *ctx, RImage *image)
if (!err || !nerr) {
if (nerr)
free(nerr);
if (err)
free(err);
RErrorCode = RERR_NOMEMORY;
RDestroyXImage(ctx, ximg);
return NULL;
@ -522,6 +524,8 @@ image2PseudoColor(RContext *ctx, RImage *image)
if (!err || !nerr) {
if (nerr)
free(nerr);
if (err)
free(err);
RErrorCode = RERR_NOMEMORY;
RDestroyXImage(ctx, ximg);
return NULL;
@ -757,6 +761,8 @@ image2GrayScale(RContext *ctx, RImage *image)
if (!gerr || !ngerr) {
if (ngerr)
free(ngerr);
if (gerr)
free(gerr);
RErrorCode = RERR_NOMEMORY;
RDestroyXImage(ctx, ximg);
return NULL;

View file

@ -44,7 +44,10 @@ XGFontSetFontInfo.m \
linking.m
ifeq ($(WITH_XFT),yes)
xlib_OBJC_FILES += GSXftFontInfo.m
xlib_OBJC_FILES += GSXftFontInfo.m \
../fontconfig/FCFontInfo.m \
../fontconfig/FCFontEnumerator.m \
../fontconfig/FCFaceInfo.m
endif
-include GNUmakefile.preamble

View file

@ -44,7 +44,6 @@
#include <AppKit/NSBezierPath.h>
#include "xlib/GSXftFontInfo.h"
#ifdef HAVE_FC
#define id _gs_avoid_id_collision
#include <fontconfig/fontconfig.h>
#undef id
@ -54,212 +53,20 @@
#include FT_GLYPH_H
#include FT_OUTLINE_H
/*
* class global dictionary of existing fonts
*/
static NSMutableDictionary *allFonts = nil;
// just a warpper around a FcPattern, to make it a NSObject
@interface FcFont : NSObject
{
FcPattern *aFont;
}
- initWithPattern:(FcPattern *)aFace;
- (FcPattern *)font;
@implementation GSXftFaceInfo
@end
@implementation FcFont
- initWithPattern:(FcPattern *)aFace
@implementation GSXftFontEnumerator
+ (Class) faceInfoClass
{
[super init];
aFont = aFace;
FcPatternReference(aFace);
return self;
return [GSXftFaceInfo class];
}
- (FcPattern *)font
+ (GSXftFaceInfo *) fontWithName: (NSString *) name
{
return aFont;
}
- (void) dealloc
{
FcPatternDestroy(aFont);
[super dealloc];
return (GSXftFaceInfo *) [super fontWithName: name];
}
@end
@implementation FcFontEnumerator
// Make a GNUStep style font descriptor from a FcPattern
static NSArray *faFromFc(FcPattern *pat)
{
int weight, slant, spacing, nsweight;
unsigned int nstraits = 0;
char *family;
NSMutableString *name, *style;
if (FcPatternGetInteger(pat, FC_WEIGHT, 0, &weight) != FcResultMatch ||
FcPatternGetInteger(pat, FC_SLANT, 0, &slant) != FcResultMatch ||
FcPatternGetString(pat, FC_FAMILY, 0, (FcChar8 **)&family) != FcResultMatch)
return nil;
if (FcPatternGetInteger(pat, FC_SPACING, 0, &spacing) == FcResultMatch)
if (spacing==FC_MONO || spacing==FC_CHARCELL)
nstraits |= NSFixedPitchFontMask;
name = [NSMutableString stringWithCapacity: 100];
style = [NSMutableString stringWithCapacity: 100];
[name appendString: [NSString stringWithUTF8String: family]];
switch (weight)
{
case FC_WEIGHT_LIGHT:
[style appendString: @"Light"];
nsweight = 3;
break;
case FC_WEIGHT_MEDIUM:
nsweight = 6;
break;
case FC_WEIGHT_DEMIBOLD:
[style appendString: @"Demibold"];
nsweight = 7;
break;
case FC_WEIGHT_BOLD:
[style appendString: @"Bold"];
nsweight = 9;
nstraits |= NSBoldFontMask;
break;
case FC_WEIGHT_BLACK:
[style appendString: @"Black"];
nsweight = 12;
nstraits |= NSBoldFontMask;
break;
default:
nsweight = 6;
}
switch (slant)
{
case FC_SLANT_ROMAN:
break;
case FC_SLANT_ITALIC:
[style appendString: @"Italic"];
nstraits |= NSItalicFontMask;
break;
case FC_SLANT_OBLIQUE:
[style appendString: @"Oblique"];
nstraits |= NSItalicFontMask;
break;
}
if ([style length] > 0)
{
[name appendString: @"-"];
[name appendString: style];
}
else
{
[style appendString: @"Roman"];
}
return [NSArray arrayWithObjects: name,
style,
[NSNumber numberWithInt: nsweight],
[NSNumber numberWithUnsignedInt: nstraits],
nil];
}
- (void) enumerateFontsAndFamilies
{
int i;
NSMutableDictionary *fcxft_allFontFamilies = [[NSMutableDictionary alloc] init];
NSMutableDictionary *fcxft_allFonts = [[NSMutableDictionary alloc] init];
NSMutableArray *fcxft_allFontNames = [[NSMutableArray alloc] init];
FcPattern *pat = FcPatternCreate();
FcObjectSet *os = FcObjectSetBuild(FC_FAMILY, FC_SLANT, FC_WEIGHT,
FC_SPACING, NULL);
FcFontSet *fs = FcFontList(0, pat, os);
FcPatternDestroy(pat);
FcObjectSetDestroy(os);
for (i=0; i < fs->nfont; i++)
{
char *family;
if (FcPatternGetString(fs->fonts[i], FC_FAMILY, 0, (FcChar8 **)&family) == FcResultMatch)
{
NSArray *fontArray;
if ((fontArray = faFromFc(fs->fonts[i])))
{
NSString *familyString;
NSMutableArray *familyArray;
FcFont *aFont;
NSString *name = [fontArray objectAtIndex: 0];
familyString = [NSString stringWithUTF8String: family];
if (!(familyArray = [fcxft_allFontFamilies objectForKey: familyString]))
{
familyArray = [[NSMutableArray alloc] init];
[fcxft_allFontFamilies setObject: familyArray forKey: familyString];
RELEASE(familyArray);
}
NSDebugLLog(@"NSFont", @"fc enumerator: adding font: %@", name);
[familyArray addObject: fontArray];
[fcxft_allFontNames addObject: name];
aFont = [[FcFont alloc] initWithPattern: fs->fonts[i]];
[fcxft_allFonts setObject: aFont forKey: name];
RELEASE(aFont);
}
}
}
FcFontSetDestroy (fs);
allFontNames = fcxft_allFontNames;
allFontFamilies = fcxft_allFontFamilies;
allFonts = fcxft_allFonts;
}
-(NSString *) defaultSystemFontName
{
if ([allFontNames containsObject: @"Bitstream Vera Sans"])
return @"Bitstream Vera Sans";
if ([allFontNames containsObject: @"FreeSans"])
return @"FreeSans";
if ([allFontNames containsObject: @"DejaVu Sans"])
return @"DejaVu Sans";
return @"Helvetica";
}
-(NSString *) defaultBoldSystemFontName
{
if ([allFontNames containsObject: @"Bitstream Vera Sans-Bold"])
return @"Bitstream Vera Sans-Bold";
if ([allFontNames containsObject: @"FreeSans-Bold"])
return @"FreeSans-Bold";
if ([allFontNames containsObject: @"DejaVu Sans-Bold"])
return @"DejaVu Sans-Bold";
return @"Helvetica-Bold";
}
-(NSString *) defaultFixedPitchFontName
{
if ([allFontNames containsObject: @"Bitstream Vera Sans Mono"])
return @"Bitstream Vera Sans Mono";
if ([allFontNames containsObject: @"FreeMono"])
return @"FreeMono";
if ([allFontNames containsObject: @"DejaVu Sans Mono"])
return @"DejaVu Sans Mono";
return @"Courier";
}
@end
#endif
@interface GSXftFontInfo (Private)
- (BOOL) setupAttributes;
@ -295,86 +102,10 @@ static NSArray *faFromFc(FcPattern *pat)
- (void) dealloc
{
if (font_info != NULL)
XftFontClose([XGServer currentXDisplay], (XftFont *)font_info);
XftFontClose([XGServer xDisplay], (XftFont *)font_info);
[super dealloc];
}
#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
#if __INT_MIN__ == 0x7fffffff
#define Ones(mask) __builtin_popcount(mask)
#else
#define Ones(mask) __builtin_popcountl((mask) & 0xffffffff)
#endif
#else
/* Otherwise fall back on HACKMEM 169. */
static int
Ones(unsigned int n)
{
register unsigned int tmp;
tmp = n - ((n >> 1) & 033333333333)
- ((n >> 2) & 011111111111);
return ((tmp + (tmp >> 3)) & 030707070707) % 63;
}
#endif
- (NSCharacterSet*) coveredCharacterSet
{
if (coveredCharacterSet == nil)
{
if (!((XftFont *)font_info)->charset)
return nil;
else
{
NSMutableData *d = [NSMutableData new];
unsigned count = 0;
FcCharSet *charset = ((XftFont *)font_info)->charset;
FcChar32 ucs4;
FcChar32 map[FC_CHARSET_MAP_SIZE];
FcChar32 next;
BOOL swap = NSHostByteOrder() == NS_BigEndian;
if (!d)
return nil;
for (ucs4 = FcCharSetFirstPage(charset, map, &next);
ucs4 != FC_CHARSET_DONE;
ucs4 = FcCharSetNextPage(charset, map, &next))
{
unsigned int i;
NSRange aRange;
unsigned int max;
aRange = NSMakeRange(ucs4, FC_CHARSET_MAP_SIZE * sizeof(FcChar32));
max = NSMaxRange(aRange);
// Round up to a suitable plane size
max = ((max + 8191) >> 13) << 13;
[d setLength: max];
for (i = 0; i < FC_CHARSET_MAP_SIZE; i++)
if (map[i])
{
// Do some byte swapping, if needed.
if (swap)
{
map[i] = NSSwapInt(map[i]);
}
count += Ones(map[i]);
}
[d replaceBytesInRange: aRange withBytes: map];
}
ASSIGN(coveredCharacterSet,
[NSCharacterSet characterSetWithBitmapRepresentation: d]);
numberOfGlyphs = count;
RELEASE(d);
}
}
return coveredCharacterSet;
}
- (CGFloat) widthOfString: (NSString*)string
{
XGlyphInfo extents;
@ -382,7 +113,7 @@ Ones(unsigned int n)
XftChar16 str[len];
[string getCharacters: (unichar*)str];
XftTextExtents16 ([XGServer currentXDisplay],
XftTextExtents16 ([XGServer xDisplay],
font_info,
str,
len,
@ -402,7 +133,7 @@ Ones(unsigned int n)
buf[i] = glyphs[i];
}
XftTextExtents16 ([XGServer currentXDisplay],
XftTextExtents16 ([XGServer xDisplay],
font_info,
buf,
len,
@ -418,6 +149,24 @@ Ones(unsigned int n)
- (NSSize) advancementForGlyph: (NSGlyph)glyph
{
if (_cachedSizes)
{
int entry = glyph % _cacheSize;
if (_cachedGlyphs[entry] == glyph)
return _cachedSizes[entry];
XGlyphInfo *pc = [self xGlyphInfo: glyph];
if (!pc)
return NSMakeSize((float)(font_info)->max_advance_width, 0);
_cachedGlyphs[entry] = glyph;
_cachedSizes[entry] = NSMakeSize((float)pc->xOff, (float)pc->yOff);
return _cachedSizes[entry];
}
XGlyphInfo *pc = [self xGlyphInfo: glyph];
// if per_char is NULL assume max bounds
@ -444,7 +193,7 @@ Ones(unsigned int n)
- (BOOL) glyphIsEncoded: (NSGlyph)glyph
{
return XftGlyphExists([XGServer currentXDisplay],
return XftGlyphExists([XGServer xDisplay],
(XftFont *)font_info, glyph);
}
@ -480,7 +229,7 @@ Ones(unsigned int n)
/*
- (CGFloat) pointSize
{
Display *xdpy = [XGServer currentXDisplay];
Display *xdpy = [XGServer xDisplay];
return XGFontPointSize(xdpy, font_info);
}
@ -553,14 +302,14 @@ Ones(unsigned int n)
#ifdef HAVE_UTF8
if (mostCompatibleStringEncoding == NSUTF8StringEncoding)
XftTextExtentsUtf8([XGServer currentXDisplay],
XftTextExtentsUtf8([XGServer xDisplay],
font_info,
(XftChar8 *)s,
len,
&extents);
else
#endif
XftTextExtents8([XGServer currentXDisplay],
XftTextExtents8([XGServer xDisplay],
font_info,
(XftChar8*)s,
len,
@ -689,7 +438,7 @@ static FT_Outline_Funcs bezierpath_funcs = {
glyph = glyphs[i];
// FIXME: Should do this conversion in the glyph creation!
glyph = XftCharIndex([XGServer currentXDisplay],
glyph = XftCharIndex([XGServer xDisplay],
(XftFont *)font_info, glyph);
if (FT_Load_Glyph(face, glyph, load_flags))
@ -728,16 +477,16 @@ static FT_Outline_Funcs bezierpath_funcs = {
- (BOOL) setupAttributes
{
Display *xdpy = [XGServer currentXDisplay];
Display *xdpy = [XGServer xDisplay];
int defaultScreen = DefaultScreen(xdpy);
#ifdef HAVE_FC
FcFont *realFont = [allFonts objectForKey: fontName];
GSXftFaceInfo *realFont = [GSXftFontEnumerator fontWithName: fontName];
FcPattern *fontPattern;
FcPattern *pattern;
FcResult fc_result;
char *family;
int fcspacing, fcweight, fcslant;
if (![super setupAttributes])
return NO;
if (!realFont)
{
@ -747,7 +496,7 @@ static FT_Outline_Funcs bezierpath_funcs = {
if (!xdpy)
return NO;
fontPattern = FcPatternDuplicate([realFont font]);
fontPattern = FcPatternDuplicate([realFont matchedPattern]);
// the only thing needs customization here is the size
// FIXME: It would be correcter to use FC_SIZE as GNUstep should be
@ -759,55 +508,6 @@ static FT_Outline_Funcs bezierpath_funcs = {
pattern = XftFontMatch(xdpy, defaultScreen, fontPattern, &fc_result);
// tide up
FcPatternDestroy(fontPattern);
if (FcPatternGetString(pattern, FC_FAMILY, 0, (FcChar8 **)&family) == FcResultMatch)
{
ASSIGN(familyName, [NSString stringWithUTF8String: (const char*)family]);
}
if (FcPatternGetInteger(pattern, FC_SPACING, 0, &fcspacing) == FcResultMatch)
{
isFixedPitch = (fcspacing == FC_MONO || fcspacing == FC_CHARCELL);
}
if (FcPatternGetInteger(pattern, FC_WEIGHT, 0, &fcweight) == FcResultMatch)
{
switch (fcweight)
{
case FC_WEIGHT_LIGHT:
weight = 3;
break;
case FC_WEIGHT_MEDIUM:
weight = 6;
break;
case FC_WEIGHT_DEMIBOLD:
weight = 7;
break;
case FC_WEIGHT_BOLD:
weight = 9;
break;
case FC_WEIGHT_BLACK:
weight = 12;
break;
default:
// Don't know
weight = 6;
}
}
if (FcPatternGetInteger(pattern, FC_SLANT, 0, &fcslant) == FcResultMatch)
{
switch (fcslant)
{
case FC_SLANT_ROMAN:
traits |= NSUnitalicFontMask;
break;
case FC_SLANT_ITALIC:
traits |= NSItalicFontMask;
break;
case FC_SLANT_OBLIQUE:
traits |= NSItalicFontMask;
break;
}
}
// Derek Zhou claims that this takes over the ownership of the pattern
if ((font_info = XftFontOpenPattern(xdpy, pattern)))
@ -820,119 +520,13 @@ static FT_Outline_Funcs bezierpath_funcs = {
return NO;
}
/* TODO: somehow make gnustep-gui send unicode our way. utf8? ugly, but it works */
mostCompatibleStringEncoding = NSUTF8StringEncoding;
encodingScheme = @"iso10646-1";
#else
NSString *reg;
XftPattern *pattern;
XftResult result;
NSString *xfontname;
char *xftTypeString;
int xftTypeInt;
NSArray *encoding;
if (!xdpy)
return NO;
// Retrieve the XLFD matching the given fontName. DPS->X.
xfontname = XGXFontName(fontName, matrix[0]);
// Load Xft font and get font info structure.
if ((xfontname == nil) ||
(font_info = XftFontOpenXlfd(xdpy, defaultScreen, [xfontname UTF8String])) == NULL)
{
NSLog(@"Unable to open fixed font %@", xfontname);
return NO;
}
else
NSDebugLog(@"Loaded font: %@", xfontname);
pattern = font_info->pattern;
result = XftPatternGetString(pattern, XFT_FAMILY, 0, &xftTypeString);
if (result != XftResultTypeMismatch)
{
ASSIGN(familyName,
[NSString stringWithUTF8String: (const char*)xftTypeString]);
}
result = XftPatternGetInteger(pattern, XFT_SPACING, 0, &xftTypeInt);
if (result != XftResultTypeMismatch)
{
isFixedPitch = (xftTypeInt != 0);
}
result = XftPatternGetInteger(pattern, XFT_WEIGHT, 0, &xftTypeInt);
if (result != XftResultTypeMismatch)
{
switch (xftTypeInt)
{
case 0:
weight = 3;
break;
case 100:
weight = 6;
break;
case 180:
weight = 7;
break;
case 200:
weight = 9;
break;
case 210:
weight = 12;
break;
default:
// Don't know
weight = 6;;
}
}
result = XftPatternGetInteger(pattern, XFT_SLANT, 0, &xftTypeInt);
if (result != XftResultTypeMismatch)
{
if (xftTypeInt != 0)
traits |= NSItalicFontMask;
else
traits |= NSUnitalicFontMask;
}
XftPatternGetString(pattern, XFT_ENCODING, 0, &xftTypeString);
encodingScheme = [NSString stringWithUTF8String: xftTypeString];
encoding = [encodingScheme componentsSeparatedByString: @"-"];
reg = [encoding objectAtIndex: 0];
if (reg != nil)
{
if ([encoding count] > 1)
{
NSString *enc = [encoding lastObject];
mostCompatibleStringEncoding = GSEncodingForRegistry(reg, enc);
if (mostCompatibleStringEncoding == GSUndefinedEncoding)
mostCompatibleStringEncoding = NSASCIIStringEncoding;
if (mostCompatibleStringEncoding == NSUnicodeStringEncoding)
mostCompatibleStringEncoding = NSUTF8StringEncoding;
RETAIN(encodingScheme);
}
}
else
encodingScheme = nil;
// FIXME: italicAngle, underlinePosition, underlineThickness are not set.
// Should use XA_ITALIC_ANGLE, XA_UNDERLINE_POSITION, XA_UNDERLINE_THICKNESS
#endif
// Fill the ivars
if (weight >= 9)
traits |= NSBoldFontMask;
else
traits |= NSUnboldFontMask;
if (isFixedPitch)
traits |= NSFixedPitchFontMask;
isBaseFont = NO;
ascender = font_info->ascent;
descender = -(font_info->descent);
capHeight = ascender - descender; // TODO
xHeight = capHeight*0.6; //Errr... TODO
lineHeight = capHeight;
fontBBox = NSMakeRect(
(float)(0),
(float)(-font_info->descent),
@ -953,7 +547,7 @@ static FT_Outline_Funcs bezierpath_funcs = {
{
static XGlyphInfo glyphInfo;
XftTextExtents32 ([XGServer currentXDisplay],
XftTextExtents32 ([XGServer xDisplay],
(XftFont *)font_info,
&glyph,
1,

View file

@ -778,6 +778,7 @@ _bitmap_combine_alpha(RContext *context,
*/
switch (bits_per_sample)
{
case 16:
case 8:
img.pro_mul = 1;
break;
@ -803,7 +804,7 @@ _bitmap_combine_alpha(RContext *context,
img.pro_mul = 255;
break;
default:
NSLog(@"Bizzare number of bits per sample %d", bits_per_sample);
NSLog(@"Bizarre number of bits per sample %d", bits_per_sample);
return -1;
}

View file

@ -88,9 +88,7 @@
([ud boolForKey: @"GSFontAntiAlias"]))
{
fontClass = [GSXftFontInfo class];
#ifdef HAVE_FC
fontEnumerator = [FcFontEnumerator class];
#endif
fontEnumerator = [GSXftFontEnumerator class];
}
#endif
enableFontSet = [ud boolForKey: @"GSXEnableFontSet"];

View file

@ -129,7 +129,7 @@ static BOOL XGInitAtoms(Display *dpy)
{
if (font_info != NULL)
{
XFreeFont([XGServer currentXDisplay], font_info);
XFreeFont([XGServer xDisplay], font_info);
}
[super dealloc];
}
@ -272,7 +272,7 @@ static BOOL XGInitAtoms(Display *dpy)
- (BOOL) setupAttributes
{
Display *xdpy = [XGServer currentXDisplay];
Display *xdpy = [XGServer xDisplay];
NSString *reg;
long height;
NSString *xfontname;

View file

@ -80,7 +80,7 @@ cache_name()
{
NSFileManager *mgr;
BOOL flag;
Display *dpy = [XGServer currentXDisplay];
Display *dpy = [XGServer xDisplay];
NSString *file_name;
NSArray *paths;
NSString *path = nil;
@ -106,7 +106,7 @@ cache_name()
if ([mgr fileExistsAtPath: path isDirectory: &flag] == NO || flag == NO)
{
NSLog(@"Library directory '%@' not available!", path);
return NO;
return nil;
}
path = [path stringByAppendingPathComponent: @"Fonts"];
if ([mgr fileExistsAtPath: path] == NO)
@ -116,7 +116,7 @@ cache_name()
if ([mgr fileExistsAtPath: path isDirectory: &flag] == NO || flag == NO)
{
NSLog(@"Fonts directory '%@' not available!", path);
return NO;
return nil;
}
path = [path stringByAppendingPathComponent: @"Cache"];
if ([mgr fileExistsAtPath: path] == NO)
@ -126,7 +126,7 @@ cache_name()
if ([mgr fileExistsAtPath: path isDirectory: &flag] == NO || flag == NO)
{
NSLog(@"Fonts directory '%@' not available!", path);
return NO;
return nil;
}
cacheName = [path stringByAppendingPathComponent: file_name];
RETAIN(cacheName);

View file

@ -32,7 +32,7 @@
#ifdef X_HAVE_UTF8_STRING
#define XSERVER [XGServer currentXDisplay]
#define XSERVER [XGServer xDisplay]
typedef struct _UTF8Str {
char *data;

View file

@ -186,8 +186,8 @@ static Region emptyRegion;
/* We know the current server sent us this */
srv = (XGServer *)GSCurrentServer();
context = [srv xrContextForScreen: gs_win->screen];
drawMechanism = [srv drawMechanismForScreen: gs_win->screen];
context = [srv screenRContext];
drawMechanism = [srv screenDrawMechanism];
if (gs_win != NULL && gs_win->alpha_buffer != 0)
{

View file

@ -46,7 +46,7 @@
XRectangle
accessibleRectForWindow (gswindow_device_t* win)
{
Display* xdpy = [XGServer currentXDisplay];
Display* xdpy = [XGServer xDisplay];
Window root;
Window ignoreWindow;
int x, y;
@ -62,7 +62,7 @@ accessibleRectForWindow (gswindow_device_t* win)
&ignoreUInt,
&ignoreUInt))
{
NSDebugLLog (@"XGGeometry", @"invalide Drawable in gswindow_device");
NSDebugLLog (@"XGGeometry", @"invalid Drawable in gswindow_device");
return XGMakeRect (0, 0, 0, 0);
}

View file

@ -37,8 +37,13 @@ TOOL_NAME = gpbs
gpbs_OBJC_FILES = gpbs.m
font_cacher_OBJC_FILES = font_cacher.m
MAN1_PAGES = gpbs.1
ifeq ($(BUILD_GRAPHICS),xlib)
ifeq ($(WITH_XFT),no)
TOOL_NAME += font_cacher
MAN1_PAGES += font_cacher.1
endif
endif
ifeq ($(BUILD_SERVER),x11)
@ -53,8 +58,6 @@ ifeq ($(BUILD_SERVER),win32)
gpbs_OBJC_FILES += win32pbs.m
endif
MAN1_PAGES = gpbs.1
-include GNUmakefile.preamble
include $(GNUSTEP_MAKEFILES)/tool.make

69
Tools/font_cacher.1 Normal file
View file

@ -0,0 +1,69 @@
.\"font_cacher(1) man page
.\"Written by Yavor Doganov <yavor@gnu.org>
.\"Copyright (C) 2018 Free Software Foundation, Inc.
.\"License: GPL-3+
.TH FONT_CACHER 1 "February 2018" GNUstep "GNUstep System Manual"
.SH NAME
font_cacher \- font cacher for the GNUstep xlib Backend
.SH SYNOPSIS
\fBfont_cacher\fR [\fIoptions\fR]
.PP
.SH DESCRIPTION
The
.B font_cacher
program generates a cache from all available X fonts. The cache is
stored in
.I $HOME/GNUstep/Library/Fonts/Cache
and is used only by the GNUstep xlib backend. The xlib backend will
automatically launch
.B font_cacher
if the cache is not available or cannot be accessed. This can cause
some slowness when a GNUstep application is started for the first
time with xlib configured as backend.
.PP
Normally, the
.B font_cacher
program is used without options.
.PP
.SH OPTIONS
.TP
\fB\--version\fR
Displays version information. (Not implemented.)
.TP
\fB\--help\fR
Prints the exact location of the file where the font cache will be
written.
.TP
\fB\--GNU-Debug=\fR\fIdflt\fR
Displays progress and other debugging information while generating the
cache. (This is a global
.I GNUstep
option.)
.PP
.SH BUGS AND LIMITATIONS
If
.I $HOME/GNUstep/Library
does not exist,
.B font_cacher
will fail and the directory must be created manually.
.PP
When fonts are installed or removed, the program must be invoked
explicitly to update the cache. There is no way to handle this
automatically.
.PP
.SH SEE ALSO
Defaults related to the GNUstep Backend:
.I $GNUSTEP_DOC/Developer/Back/General/DefaultsSummary.html
.PP
.SH AUTHORS
.B font_cacher
was written by Fred Kiefer <FredKiefer@gmx.de> and Richard
Frith-Macdonald <rfm@gnu.org>.
.PP
This manual page was written by Yavor Doganov <yavor@gnu.org>.
.SH COPYING
\(co 2018 Free Software Foundation, Inc.
.PP
This manual page is distributed under the same license as the
.B font_cacher
program.

View file

@ -191,9 +191,20 @@
}
mgr = [NSFileManager defaultManager];
if ([mgr fileExistsAtPath: path] == NO)
{
NSError *err;
BOOL r;
r = [mgr createDirectoryAtPath: path
withIntermediateDirectories: YES
attributes: nil
error: &err];
if (r == NO)
NSLog(@"font_cacher: Library directory creation error: %@", err);
}
if ([mgr fileExistsAtPath: path isDirectory: &flag] == NO || flag == NO)
{
NSLog(@"Library directory '%@' not available!", path);
NSLog(@"font_cacher: Library directory '%@' not available!", path);
return nil;
}
path = [path stringByAppendingPathComponent: @"Fonts"];

Some files were not shown because too many files have changed in this diff Show more