Add an android display server drawing through cairo - #234
Conversation
| AndroidServer.h | ||
|
|
||
| Copyright (C) 2026 Free Software Foundation, Inc. | ||
|
|
There was a problem hiding this comment.
You should put your name here
There was a problem hiding this comment.
Added, and to the other files this adds. Source/android/GNUmakefile and its preamble come from the x11 backend's, so they keep Adam Fedor as well.
|
As I am no Android expert I would like to see @triplef comments on this PR. |
|
While we use GNUstep on Android, we only use libs-base (and libs-corebase) but leave the UI part to Qt, so I have no experience with libs-back or low-level graphics on Android and don’t feel in a position to comment on this implementation. That being said it’s great to see this. Once it’s integrated we should add libs-back to tools-android as well (behind a |
|
The reason I went down this rabbit hole was to try to address the Issue in libs-base asking for a CI Runner for Android. That is done, though it adds a lot of work to the CI which is another issue which @rfm rightly has pointed out needs solving. That said, I presumed the point of doing so was to allow an iOS app to be ported to Android with API parity, and that of course would require a libs-gui / libs-back component, and so I went... libs-back itself has received some changes now that makes each backend pretty much at functional parity with Cairo, and so having this done, it was fairly easy to cut and paste a template for Android, and subclass and implement the GState code, AndroidServer, etc. What I can say is that if this really isn't something the project would want to actively support going forward, it is best to park it. The challenge is that the libs-back and libs-gui parts compile and run fine on Android now (the test suites) based on my changes, but there are a number of dependencies and environmental setups that are tricky for actual deployment. I had to build an actual app to really test this and the app is running easily, but the setup to deploy an APK without using Android Studio, Java,etc. and their tools is a fair bit of work, and while I think it can be automated with scripts, it is an effort not worth anybody's time unless it would be actually used. If Qt is adequate, and there are no other users looking for direct iOS to Android porting solution, then we can let it be. If it is something we collectively think is worth it I will submit the harnesses for app building. We still will need to address the CI issue, as in whether we even test it in CI, maybe leaving it to a make check on install. |
b206822 to
1d0a40e
Compare
libs-back has no display server for Android, and the headless one does not stand in for it: every drawing primitive is an empty body, the screen is a fixed 400x400 and every window has the number 1. AndroidServer is a GSDisplayServer subclass holding a window table, screen metrics and window ordering, on the wayland pattern; AndroidCairoSurface is a CairoSurface subclass. configure takes android in --enable-server and errors, as wayland does, rather than falling back to xlib when cairo or freetype is missing, and it links fontconfig's own libraries, which a static fontconfig keeps private. An activity is given one surface, so the server owns it and writes every window on screen into it in turn, back to front, which is what puts a menu or a panel over the window it belongs to. A press goes to the window it lands in and a key to the window that has the screen. The screen is the surface less what the system bars and the input method take, as the x11 server reports the work area rather than the whole display. Those are not settled when the first window is made, so a change is noticed and NSApplicationDidChangeScreenParametersNotification is posted, and the window that has the screen is given the new one. A wheel, a hover, a second and third button, a click count and a modifier key all become the events AppKit names. The input method is shown while something is being edited: a press in the view being edited goes on editing, and a press anywhere else ends it. Tests/cairo drives real ANativeWindows through AImageReader, so they need no activity. Documentation/install.texi says how an application is packaged.
c9647cb to
d2dd7ed
Compare
This branch carried the android backend as it was before gnustep#234 was squashed, 1473 lines behind it across 9 files, so the suite it exercised was not the suite that will run once gnustep#234 merges. Every android file is taken from gnustep#234, and configure is regenerated from its configure.ac rather than resolved by hand. Tests/cairo gains androidrebind.m and androidrepaint.m, which the older copy did not have.
This adds an android server over the existing cairo graphics path, on the
Wayland pattern.
AndroidServer is a GSDisplayServer subclass holding a window
table, screen metrics and window ordering; AndroidCairoSurface is a
CairoSurface subclass.
configure takes android in --enable-server and errors,
as wayland does, rather than falling back to xlib when cairo or freetype is
missing, and it links fontconfig's own libraries, which a static fontconfig
keeps private.
The surface draws into an image and posts it to the window an activity is
given, asking the window which region has to be redrawn. The window bound to
that surface is given the screen, since a smaller one would sit in a corner.
Touches and keys become NSEvents. The surface is given up and taken back with
the activity.
The screen size is read from the bound window, or from GSAndroidScreenSize
where there is none.
Tests/cairo/androidpost and androidrepaint drive a real ANativeWindow through
AImageReader, so they need no activity.