mikaku / Fiwix

A UNIX-like kernel for the i386 architecture
https://www.fiwix.org
Other
427 stars 33 forks source link

Add required features to port a basic windowing system #94

Open mikaku opened 2 months ago

mikaku commented 2 months ago

Now that Fiwix has UNIX sockets I'd like to explore the path to add support for a light windowing system like Microwindows or Nano-X. Some comments from @ghaerr in #78 will help a lot to summarize the features needed to port his amazing Microwindows system, which is simple enough to run with UNIX sockets. Other bloated windowing systems like X11 might require a TCP/IP stack which the kernel lacks at the moment.

So, I've created this issue to help to track all the features that @ghaerr summarized:

ghaerr commented 2 months ago

After you get Microwindows and FreeType 2.10.4 (or later, that's the last version I happened to test) available on a Fiwix distribution, let me know if you need help with discussion, design or coding for the remaining items!

mikaku commented 2 months ago

Some questions:

  1. I've successfully built FreeType 2.10.4 but it only provides the /usr/lib/libfreettype.a and a lot of header files in /usr/include/freetype2/freetype/. No fonts. Do I missed something?

  2. I've changed the line HAVE_FREETYPE_2_SUPPORT = N to Y in the src/config file and recompiled Microwindows but now it fails with the following messages:

[...]
Compiling demos/mwin/mwdemo2.c ...
Linking mwdemo2 ...
/usr/lib/gcc/i386-pc-fiwix/4.7.4/../../../libfreetype.a(ftbzip2.o): In function `ft_bzip2_file_done':
/mnt/disk/freetype-2.10.4/src/bzip2/ftbzip2.c:192: undefined reference to `BZ2_bzDecompressEnd'
/usr/lib/gcc/i386-pc-fiwix/4.7.4/../../../libfreetype.a(ftbzip2.o): In function `ft_bzip2_file_fill_output':
/mnt/disk/freetype-2.10.4/src/bzip2/ftbzip2.c:303: undefined reference to `BZ2_bzDecompress'
/usr/lib/gcc/i386-pc-fiwix/4.7.4/../../../libfreetype.a(ftbzip2.o): In function `ft_bzip2_file_reset':
/mnt/disk/freetype-2.10.4/src/bzip2/ftbzip2.c:221: undefined reference to `BZ2_bzDecompressEnd'
/mnt/disk/freetype-2.10.4/src/bzip2/ftbzip2.c:232: undefined reference to `BZ2_bzDecompressInit'
/usr/lib/gcc/i386-pc-fiwix/4.7.4/../../../libfreetype.a(ftbzip2.o): In function `ft_bzip2_file_init':
/mnt/disk/freetype-2.10.4/src/bzip2/ftbzip2.c:177: undefined reference to `BZ2_bzDecompressInit'
collect2: error: ld returned 1 exit status
make[2]: *** [Makefile:114: /mnt/disk/microwindows-master/src/bin/mwdemo2] Error 1
make[1]: *** [/mnt/disk/microwindows-master/src/Makefile.rules:481: subdir-/mnt/disk/microwindows-master/src/demos/mwin/] Error 2

Looks like FreeType was compiled without Bzip2 support but the build log detected correctly the /usr/lib/libbz2.a (-lbz2) library:

FreeType build system -- automatic system detection

The following settings are used:

  platform                    unix
  compiler                    cc
  configuration directory     ./builds/unix
  configuration rules         ./builds/unix/unix.mk

If this does not correspond to your system or settings please remove the file
`config.mk' from this directory then read the INSTALL file for help.

Otherwise, simply type `make' again to build the library,
or `make refdoc' to build the API reference (this needs Python >= 3.5).

Generating modules list in ./objs/ftmodule.h...
done.
* module: truetype  (Windows/Mac font files with extension *.ttf or *.ttc)
* module: type1     (Postscript font files with extension *.pfa or *.pfb)
* module: cff       (OpenType fonts with extension *.otf)
* module: cid       (Postscript CID-keyed fonts, no known extension)
* module: pfr       (PFR/TrueDoc font files with extension *.pfr)
* module: type42    (Type 42 font files with no known extension)
* module: winfnt    (Windows bitmap fonts with extension *.fnt or *.fon)
* module: pcf       (pcf bitmap fonts)
* module: bdf       (bdf bitmap fonts)
* module: sfnt      (helper module for TrueType & OpenType formats)
* module: autofit   (automatic hinting module)
* module: pshinter  (Postscript hinter module)
* module: raster    (monochrome bitmap renderer)
* module: smooth    (anti-aliased bitmap renderer)
* module: psaux     (Postscript Type 1 & Type 2 helper module)
* module: psnames   (Postscript & Unicode Glyph name handling)
cd builds/unix; \
        ./configure  '--prefix=/usr' '--mandir=/usr/share/man'
checking build system type... i386-pc-fiwix
checking host system type... i386-pc-fiwix
checking for gcc... gcc
[...]
checking for ZLIB... yes
checking for BZIP2... no
checking for BZ2_bzDecompress in -lbz2... yes
checking bzlib.h usability... yes
checking bzlib.h presence... yes
checking for bzlib.h... yes
checking for LIBPNG... yes
checking for HARFBUZZ... no
checking for BROTLI... no
checking for library containing clock_gettime... none required
checking for python3... python3
checking for python version... 3.6.15
checking for `docwriter' Python module... no
configure: creating ./config.status
config.status: creating ftoption.h
config.status: creating unix-cc.mk
config.status: creating unix-def.mk
config.status: creating ftconfig.h
config.status: executing libtool commands
configure:

Library configuration:
  external zlib: yes (pkg-config)
  bzip2:         yes (autoconf test)
  libpng:        yes (pkg-config)
  harfbuzz:      no
  brotli:        no
[...]

Any idea?

ghaerr commented 2 months ago

No fonts. Do I missed something?

No, the fonts required for Microwindows are in its src/fonts/truetype directory. Depending on your configuration, some of these might want to be copied elsewhere, but by default that path is built in to the Microwindows demos.

Looks like FreeType was compiled without Bzip2 support but the build log detected correctly the /usr/lib/libbz2.a (-lbz2) library

Try changing the LIBZ = -lz line in config to use -lbz2 instead. In general, libz is required for a number of external Microwindows dependencies, like fonts, PNG images, etc.

mikaku commented 2 months ago

Try changing the LIBZ = -lz line in config to use -lbz2 instead. In general, libz is required for a number of external Microwindows dependencies, like fonts, PNG images, etc.

Argh!, no, this resulted in even more errors because the PNG library needs the -lz library.

I managed to solve it by adding -lbz2 in the line LIBFT2LIB = -lfreetype -lbz2. Thanks!

My fault, I should have checked first the dependencies of FreeType in the Libtool file /usr/lib/libfreetype.la before compiling Microwindows:

[...]
# Libraries that this one depends upon.
dependency_libs=' -lbz2 /usr/lib/libpng16.la -lm -lz'
[...]

Anyway :-)

Now I have a bigger mwdemo file and the rest of demo files are also bigger than before. Is there a specific demo file where I can see a visible improvement now with FreeType?

ghaerr commented 2 months ago

If you set SHAREDLIBS = Y in config, the build will attempt to use shared libraries instead of linking them all into each demo.

Is there a specific demo file where I can see a visible improvement now with FreeType?

Yes, run ./runapp demo-aafont and you should see something like this:

Screen Shot 2024-08-25 at 10 55 43 AM

The other bin/demo-nuklear* apps are also nice to look at. In general, the demo examples use Nano-X, which is likely what will be used on Fiwix, as it uses the X11-like client/server approach, versus the Win32 reimplementation in the mw demos.

mikaku commented 2 months ago

If you set SHAREDLIBS = Y in config, the build will attempt to use shared libraries instead of linking them all into each demo.

Yes, but shared libraries are not supported with the current Newlib configuration. Anyway, the big size is not a critical problem actually.

Yes, run ./runapp demo-aafont and you should see something like this:

This is what I get:

runapp: could not find nano-X server in /mnt/disk/microwindows-master/src/bin

And this is the contents of that directory:

(root):/mnt/disk/microwindows-master/src/bin# ls
convbdf                   landmine       mwopenfile    nxroach
convbmp                   landmine.ppm   mwpenstyles   nxroach.pgm
convpbm                   launcher       mwprogbar     nxscribble
demo-aafont               launcher.cnf   mwsimple      nxscribble.ppm
demo-agg                  letters.cl     mwstatictext  nxsetportrait
demo-arc                  logo.ppm       mwstretch     nxterm.ppm
demo-blit                 makebmp        mwtest        nxview
demo-composite            mwbrush        nanocal.ppm   punc.cl
demo-convimage            mwcontrols     nbreaker.ppm  screenshot-ppm
demo-dash                 mwdemo         npanel        show-font
demo-font                 mwdemo2        nsaver        show-ppm
demo-grabkey              mwdemoalpha    ntetris       slidebmp.bmp
demo-hello                mwdialog       ntetris.ppm   slider
demo-monobitmap           mwdialog.res   nxcal         slider.ppm
demo-nuklear-calculator   mwdraw         nxclock       tux
demo-nuklear-demo         mwdvetest      nxclock.pgm   tux.gif
demo-nuklear-node_editor  mwdvetest.res  nxev          tux.ppm
demo-nuklear-overview     mwhello        nxeyes        tuxchess
demo-polygon              mwlistcombo    nxeyes.pgm    uponface.ppm
demo-region               mwlogo.ppm     nxkbd         world
demo-tilestipple          mwmenu         nxkbd.pgm     world.map
demo-ttfont               mwmine         nxlsclients   world.ppm
digits.cl                 mwmsgbox       nxmag

The other bin/demo-nuklear* apps are also nice to look at

Yes, they look nice. Thanks!.

Screenshot from 2024-08-25 19-18-36

mikaku commented 2 months ago

If I try to run the demo examples with the command ./runapp bin/demo-aafont I always get:

runapp: could not find nano-X server in /mnt/disk/microwindows-master/src/bin

But if I execute them directly with bin/demo-aafont it works:

Screenshot from 2024-08-25 20-36-48

Nice. :-)

ghaerr commented 2 months ago

runapp: could not find nano-X server

runapp is just a shell script that tries to find the nano-X server, which is otherwise required to be running in order for the client applications to connect to it. This allows for multiple simultaneous connections, like X11. In your case, you're running LINK_APP_INTO_SERVER = Y which links the entire nano-X server into each executable, which is normally only used for testing or specialized embedded system. Thus, you'd just run bin/aa-demo with your configuration.

Since we got sockets working on Fiwix, you should be able to use LINK_APP_INTO_SERVER = N which will use UNIX sockets to connect. IIRC there was still a bug where on occasion the client and server would get de-synced. This would be a good time to play with that and see if you can duplicate the problem and fix it in Fiwix.

The FreeType font support looks great on Fiwix!! :)

ghaerr commented 2 months ago

But if I execute them directly with bin/demo-aafont it works:

See the text poking through just to the left of the demo-aafont window you posted, as well as the black box cursor below it? That's the "The kernel doesn't remove the fbcon cursor when calling ioctl(ttyfd, KDSETMODE, KD_GRAPHICS)" issue. In Linux, console text output is also inhibited from display in graphics mode (but not inhibited from being placed in the console text buffer), not just the cursor.

The ioctl's for those are in the driver/scr_fiwix.c screen driver, controlled by if HAVE_TEXTMODE, which in turn is enabled in config file HAVETEXTMODE = Y. This is likely set to N in your config until Fiwix does the necessary things for graphics mode on/off.

mikaku commented 2 months ago

which links the entire nano-X server into each executable, which is normally only used for testing or specialized embedded system

That clears it up, thanks.

This would be a good time to play with that and see if you can duplicate the problem and fix it in Fiwix.

Alright, I'll include this step into the list as part of required things to work.

The FreeType font support looks great on Fiwix!! :)

Yes it does! :-)

See the text poking through just to the left of the demo-aafont window you posted, as well as the black box cursor below it?

Yes, I fixed the cursor problem in the kernel but I didn't see any change when executing the test programs. Then, I saw that the file drivers/scr_fiwix.c has the line #define HAVE_TEXTMODE 0 which Linux don't. I guess this line should be removed?

Now I read your comment about HAVETEXTMODE = Y, which is set as N here, also VTSWITCH is set as N, but the kernel can switch between virtual consoles, at least it works when using the SVGAlib.

Talking about the SVGAlib, it is possible that Microwindows uses this library instead of the frame buffer?. The majority of old PCs don't has VESA BIOS extensions and cannot use the frame buffer, but they work with SVGAlib as Linux did in the 90s. FiwixOS already comes with the SVGAlib and with the program zgv to see pictures (also DOOM).

In Linux, console text output is also inhibited from display in graphics mode (but not inhibited from being placed in the console text buffer), not just the cursor.

This is interesting, I'll also check that. Thank you!

ghaerr commented 2 months ago

I guess this line should be removed?

No, you should set HAVETEXTMODE=Y and VTSWITCH=Y in config. The former handles the text/graphics ioctls and the latter deals with switching between graphics and text mode while running.

Talking about the SVGAlib, it is possible that Microwindows uses this library instead of the frame buffer?

There's an old SVGA screen driver for Microwindows in drivers/deprecated/scr_svga.c, that hasn't been compiled or tested in a while. I'll leave it to you if you want to jump into that. The problem with most older PCs is the hardware and CPUs are such that the graphics resolution is low and they're usually quite slow - meaning no one uses them anymore. I recommend staying with framebuffer but you're welcome to read up the Microwindows docs on screen drivers and play with getting it working again.

mikaku commented 2 months ago

you should set HAVETEXTMODE=Y and VTSWITCH=Y in config.

I've set HAVETEXTMODE=Y in the config file (I'll test VTSWITCH option later) and then I rebuild all Microwindows, but I still see the cursor blinking.

I think this line is overwriting the setting:

https://github.com/ghaerr/microwindows/blob/606bfb0dde0a243de6519e9ae16f4ee550dedbe7/src/drivers/scr_fiwix.c#L19

What do you think?

ghaerr commented 2 months ago

I think this line is overwriting the setting:

Yes, sorry, that should be removed. I wrote the screen driver for Fiwix kind of quickly and don't remember everything at the moment :) I am glad you're now starting to work on this and look forward to seeing all this work well on Fiwix!

mikaku commented 2 months ago

Yes, it works now!

https://github.com/user-attachments/assets/8c85ea7d-6ac2-4ce1-a4ad-ddd848bb596f

As you can see the previous screen is also restored on exit.

I am glad you're now starting to work on this and look forward to seeing all this work well on Fiwix!

I've been working on rewriting the I/O block layer and the buffer cache lately and that required a lot of attention. Now it seems pretty stable but I'm still doing some testings, but now I have a little more of spare time to dedicate it to other interesting things. ;-)

mikaku commented 2 weeks ago

@ghaerr, I think I don't understand how Nano-X works.

I've compiled Microwindows with LINK_APP_INTO_SERVER = N, so I have now the nano-X binary. If I try to execute bin/nano-X it only shows a blank screen, there is not a window manager with a simple menu. I even need to press ^C to kill it.

Then, I tried to execute ./runapp nanowm (that named suggested me some kind of window manager), but it only shows again a blank screen. Well this time it has a fixed color Turquiose or similar.

In the other hand ./runapp nxeyes works well, I can drag the eyes over the screen and the eyes follow the mouse nicely.

I mean, I don't know how to get a working window manager to have a better graphical experience, you know.

ghaerr commented 2 weeks ago

Hello @mikaku,

The way Nano-X works when using LINK_APP_INTO_SERVER=N, which is recommended, is that each application connects using a UNIX socket to the server and issues drawing commands to it. The window manager is built into the nano-X binary to make things simpler. The reason ./runapp exists is to more easily start the nano-X server and the client at the same time for demo purposes. Running nano-X itself won't do much except clear the screen to the green window manager background color.

Running ./runapp nxeyes is correct, except that's one of the few demo programs that doesn't have a window border, so the window manager doesn't frame it (you don't want a frame around xeyes, right?)

Look at the other programs in the bin directory and try running them, such as demo-composite, aa-font or some of the nuclear demos; they show off the system much better.

After you've started the server, you can run (from another terminal or watever) other clients directly and they'll connect to the server - you don't need to execute ./runapp for them.

I think there are also a number of shell scripts in the scripts/ directory that run multiple clients for demo purposes.

In general, Nano-X is not supposed to be a complete desktop environment, but rather a toolset for creating graphical applications using an X11-like (or Win32) API.

'I hope that helps.

Thank you!

mikaku commented 2 weeks ago

I hope that helps.

Yes, that helped me a lot. Thank you!