Skip to content

LinuxPort

Ivan Denisov edited this page Apr 4, 2019 · 1 revision

BlackBox on Linux

From file in archive BlackBox.Linux.20050512.zip

Overview

Installation Requirements To Install Screen Height Command Line Parameters

Linux Design

Documentation Internal External

Ported Modules System Lin Host

Creating a New Reference Version

Differences in Implementations (BB Windows vs. BB Linux) Startup Message Loops vs. Signal/Event Handlers Interface Modules Typefaces

Differences in Abstractions (MS Windows vs. Linux/Gnome) GUI vs. Non-GUI X Windows Windows Controls vs. GtkWidgets Pictures Cursors

Left to Do Printing Drag'n Drop HostCFrames Images SQL and ODBC HostRegistry

Porting Experiences Use of Directory Objects Host Imports in Portable Modules Dialog.platform HostFiles.appName Menus Fonts and Controls

Future

Overview

This document describes the Linux implementation of BlackBox. The port to Linux is not completely finished, but most things work. In particular most things that are needed for using BlackBox as a development tool are already implemented and working. And, of course, ObxCubes runs.

The things that still need some fixing are listed in the section Left to Do below. That section describes the state as of the 22 of February 2002.

Installation

Requirements

The Linux version has been developped on RedHat Linux 7.1, this release uses version 2.4.2-2 of the Linux kernel and Libc. It also comes with Gnome 1.0 installed, which in turn uses version 1.2 of the Gtk, Gdk and GLib libraries.

BlackBox has not been tested on other Linux distributions than RedHat, but it should only depend on the Libc, Gnome, Gtk, Gdk and GLib versions. Any distribution where Gnome is available should work with the BlackBox port.

To find out the versions of a Linux system, the following commands can be used:

Kernel and Libc version: uname -r Gtk and Gdk version: gtk-config --version Glib vesion: glib-config --version

BlackBox can also be run without a user interface, in which case only the Libc library is needed.

To Install

The current reference version is available on Granit. It is in the directory Oberon/Projects/Linux/LinRef. To install it, copy the file linref.tar.gz to your home directory on Linux.

Tip: On Granit an FTP-Server is running, so the easiest way to get the file to your computer is probably using FTP. To do that, use the following steps:

cd (* gets you to your home directory ) ftp 194.56.220.2 ( requires login ) cd Oberon cd Projects cd Linux cd LinRef bin ( binary mode to copy files *) get linref.tar.gz bye

Once you have the file in the directory you want it, you need to unpack it. The file is a zipped tar-archive. To unpack it, use the following steps:

gunzip linref.tar.gz (* unzips and renames the file to linref.tar *) tar -xvf linref.tar

Now a subdirectory called linref has been created. To start BlackBox, simply cd into the linref directory and execute the program called blackbox:

cd linref ./blackbox &

It is possible to have a shortcut on the desktop to start BlackBox. You can even connect a BlackBox icon to this shortcut (Lin/Rsrc/applogo.png). But for development it is better to start BlackBox from the command line, since Gtk+ writes error messages to standard out, and these messages get lost if you start BlackBox by clicking on an icon.

Screen Height

The X-Windows system used on Unix is usually very bad at guessing how big the screen is in the real world, e.g. how many millimeters high the screen actually is. There is a library function to request this information, but most X-servers give an errornous value back. The problem is that BlackBox needs this information to make coordinate transformations between universal coordinates and absolute messures, such as Ports.mm and Ports.point.

As a work-around the module HostGnome reads a file called screenheight in the BlackBox root directory. If this file is present and if the first bytes in it represents an INTEGER, then the value of the integer is used as the number of millimeters for the screen height instead of the value returned by the X-server.

This is not strictly needed, but a correct value makes fonts and drawing routines perform much more accurate. To create a file with the correct values for your screen, simply messure the height of your screen and save the value (in millimeters) in a file called screenheight. This is easy to do with the echo command. If your screen, for example, is 215 mm high, then this command can be executed in the BlackBox root directory:

echo 215 > screenheight

Command Line Parameters

The following command line parameters are implemented. They have the same syntax and meaning as the command line parameters for the Windows version. Maybe the syntax should be changed from "/" to "-" to be more Unix-like.

/O opens the file specified by fileName /USE server version /LOAD loads the module specified by modName /LTRB use l, t, r and b as coordinates for the next window to open /LANG use lang as language for this session /PAR command line parameters saved in Dialog.commanLinePars

The /USE option is parsed in HostFiles, all others are parsed in HostMenus.

Linux Design

To ease the understanding of why certain things are done differently on Linux than on Windows, here's a short description of the Linux and Gnome designs.

Basically Linux (Unix) is command line oriented. Many programs are written with the intent to be used from a command line and therefore they do not make any use of graphical user interfaces. To make graphical user interfaces possible the X-Windows system was created. This is a very generic and extensible windowing toolkit. It leaves, however, many things up to the application programmer. There is nothing that allows an application to make sure that it has the same look and feel as another application.

To solve this problem different, so called, "desktops" have been created. For Linux KDE and Gnome are the two major ones. BlackBox uses the Gnome libraries for its graphical user interface. This does not mean that BlackBox wouldn't run if KDE is used, it just means that the Gnome libraries has to be installed for BlackBox to run.

Gnome, in turn, is internally split up into four parts: Gnome, Gtk, Gdk, GLib. The lowest of these libraries is GLib, it more or less provides portable wrappers for the Libc library. Gdk is the drawing kit and Gtk is a high level tool kit. In Gtk Widgets are used as GUI elements. Example of widgets are Windows, Buttons, Tree Controls et.c. Together, the Gtk, Gdk and GLib libraries are often called Gtk+.

On the highest level are the Gnome libraries themselves. These libraries control startup of applications, supports different themes and more.

In short it can be said that the command line support is mostly implemented in libc, the graphical user interfaces in the X-libraries and the gtk- and gdk- libraries, and the application coordination support in the Gnome libraries.

Window managers is another interesteing feature of the X-Windows system. This is an extension mechanism for providing different look and feel for the windows. A window manager has control over things like, window positions, window activation, window focus et.c. This is very flexable, but it also means that an application can't control which window is to be focused, for example.

Documentation

Internal

Most of the Linux specific modules, LinLinker and the Host modules, have a section called Implementation docu at the very top of the module. These sections describe the general concepts for the module. More general documentation can be found in the folders Granit/Oberon/Projects/Linux/Docu/Stan and Granit/Oberon/Projects/Linux/Docu/Treutwein.

External

For the Libc-functions the best documentation are the "man pages" on Linux. Most functions are well described there.

Documentation about Gnome can be found on http://developer.gnome.org/doc/. Gtk, Gdk and GLib are documented on http://www.gtk.org/api/. The Gnome API is used to a very little extent in BlackBox - the Gtk and Gdk APIs are the most used ones.

The API documentation for Gnome, Gtk, Gdk and GLib can also be found on Granit (Oberon/Projects/Linux/Docu). Both as tar-files and as sets of HTML-files. In the same folder there is also a postscript file describing the XLFD format that is used for describing fonts on Unix.

Ported Modules

System

In the System subsystem, only the module Kernel has been changed. The module has many portable parts, but many things also needed changes. Thus, the Kernel module on Linux is similar to the Windows version in many respects. One notable difference is that on Linux the standard scheeme for allocating memory is the same as the one that on Windows is only used for DLLs.

Lin

Lin is a new Linux specific subsystem (similar to Win for Windows). All modules in this subsytem are new and they are only useful under Linux. This subsystem mostly contain interface modules. No interface modules has been automatically generated, they were all made by hand, so they are not complete, but they contain everything that BlackBox is using at the moment.

Lin/Mod/tool.odc Tool for building the Linux part of BlackBox LinLinker Links a Linux executable Lin/Rsrc/exe.img Image file for the LinLinker Lin/Rsrc/blackbox.c C-program to create the exe.img Lin/Rsrc/Makefile Makefile for blackbox.c LinLog Implements the Log.Hook interface and logs to standard out LinLibc Interface module for the libc library LinSockets Interface module for the libc library (TCP/IP communication) LinX11 Interface module for the libx11 library LinDl Interface module for the libdl library (dynamic loading of libraries) LinGLib Interface module for the libglib library LinGdk Interface module for the libgdk library LinGdkImlib Interface module for the libgdk_imlib library (pictures) LinGtk Interface module for the libgtk library LinGnome Interface module for the libgnome library LinGnomeUI Interface module for the libgnomeui library LinGnomeSupport Interface module for the libgnomesupport library LinTestPic Shows how to use gdk_imlib to load pictures Lin/Rsrc/applogo.png BlackBox icon Lin/Rsrc/file.xpm Icon used in the Tree control Lin/Rsrc/folder.xpm Icon used in the Tree control Lin/Rsrc/openfolder.xpm Icon used in the Tree control Lin/Docu/LinuxPort This document

Host

All modules in the Host subsystem needs changes. So far the following modules have been ported. The list is split up into categories depending on how much still needs to be done with the modules, for details about what needs to be done, see Left to Do below.

90% (or more) Complete

HostFiles, HostGnome, HostWindows, HostMenus, HostPorts, HostFonts, HostDialog, HostPackedFiles

70% Complete

HostCFrames, HostCmds, HostTextConv

50% Complete

HostClipboard, HostMechanisms

Dummy implementations

HostRegistry, HostTabFrames

Worth noting is that HostGnome is a new module. When this module is linked into the application it enables the graphical user interface. Without this module only command line applications can be created with BlackBox.

Creating a New Reference Version

Since all portable module (by definition) are the same on Windows and Linux, it is fairly easy to create a new reference version based on a Windows reference version. The basic idea is to copy the complete Windows version to Linux, remove the Windows specific modules and replace them with the Linux specific modules. To do this you obviously need both a complete Windows version and at least all Linux specific modules. The easiest way to get a Windows version is to copy it from Granit/Oberon/BlackBox/14Ref. The same way, it is easiest to find the Linux specific modules in the Linux reference version on Granit/Oberon/Projects/Linux/LinRef.

How to install the Linux version has been described above, but here are the steps to get the Windows version over to Linux:

Pack the files in the directory Granit/Oberon/BlackBox/14Ref into a zip file using WinZip. For this example it is assumed that the zip file is called 14Ref.zip. Then copy the file over to Linux using ftp:

ftp 194.56.220.2 cd directory (* cd to the directory where the zip file was saved ) bin ( binary mode *) get 14Ref.zip bye

Copy or move the file to the directory where you want it. To extract the file use unzip:

unzip 14Ref.zip

The files are extracted and the Windows version is now present on Linux. Some of the Windows specific things can be removed:

rm .exe ( Windows executables are not userful on Linux ) rm -R Win ( The Win subsystem only contains Windows specific things ) rm -R Com ( The Com subsystem only contains Windows specific things ) rm -R Ole ( The Ole subsystem only contains Windows specific things ) rm -R Ctl ( The Ctl subsystem only contains Windows specific things *)

No subsystems has to be removed but the Windows specific ones are unnecessary on Linux so it makes sense to remove them. Just like for any other BlackBox installation, it might be good to remove some other subsystems as well, for example Mac, Dtf, Ominc...

The only subsystem that really needs to be removed is the Host subsystem, since it should be replaced by the Host subsystem for the Linux version. For development it is better to rename the Host subsystem than to delete it. This makes it is possible to open the mod-files and see how a particular module is implemented on Windows. Thus, renaming the Host subsystem is recommended:

mv Host WHost

Now it is time to copy the Linux Host subsystem into the reference version. Assuming that you are in the reference version directory and that the directory of the Linux version is ../linux, the following command can be used:

cp -R ../linux/Host .

Then the Linux specific subsystem Lin is needed:

cp -R ../linux/Lin .

The Kernel needs to be copied, both the source code and the code and symbol files. Remember that the code and symbol files might not be in the System directory:

cp ../linux/System/Mod/Kernel.odc System/Mod/Kernel.odc cp ../linux/Code/Kernel.ocf System/Code/Kernel.ocf cp ../linux/Sym/Kernel.osf System/Sym/Kernel.osf

Since the Config module imports modules from the Ole subsystem, we need the Linux specific version:

cp ../linux/System/Mod/Config.odc System/Mod/Config.odc cp ../linux/Code/Config.ocf System/Code/Config.ocf cp ../linux/Sym/Config.osf System/Sym/Config.osf

And of course the Linux executable:

cp ../linux/blackbox .

To make sure that the correct screen size is used. Messure the screen and create a file called screenheight. If the screen is 215 mm high, then use this command:

echo 215 > screenheight

Now BlackBox can be started:

./blackbox &

To completely rebuild the Linux parts of BlackBox, you first need to recompile the C-program:

cd Lin/Rsrc/ make

In BlackBox you should then open the document Lin/Mod/tool.odc. This document contains a compile command for all Linux specific modules. Compile all modules and use the linking command to link a new BlackBox version.

To pack the new reference version togther, the following commands can be used - assuming that the new version is in the directory linref.

cd .. tar -cf linref.tar linref gzip -c linref.tar > linref.tar.gz

The current Windows reference version does not contain the most current versions of Documents, StdFolds and DevRBrowser, so at the current state these modules need to be copied from the Linux version as well. But the next Windows reference version will contain the correct modules.

Differences in Implementations (BB Windows vs. BB Linux)

Startup

The startup of BlackBox is done with a small C-program. This program basically loads the linked modules into memory and calls the BEGIN-section of the Kernel module. The C-Program is very small and the source is stored in Lin/Rsrc/blackbox.c.

An important feature of the C-program is that the linked modules are appended to it. This means that for it to know where to start reading the linked modules it needs to know exactly how big the program itself is. For this reason the constant exeSize is defined in the C-program. Whenever a change is made to the C-program this constant has to be updated with the new size of the executable.

In Lin/Rsrc there is also a Makefile for the C-program, so to compile a new version of the program, only these steps are needed:

cd Lin/Rsrc/ make

Linking a Linux version of BlackBox is done with LinLinker. It works very similar to DevLinker, but it does less checks on the input. Basically the LinLinker.Link command copies the executable image saved in Lin/Rsrc/exe.img and appends the linked modules to this copy.

The standard linking command to link BlackBox is:

LinLinker.Link blackbox := Kernel$+ Files HostFiles HostGnome StdLoader

This is very similar to the linking command on Windows. There are two differences: LinLinker is used instead of DevLinker and HostGnome is linked. HostGnome is the module that initializes the graphical user interface for BlackBox. If this module is not linked, the libraries for the GUI will not be loaded. This makes it possible to write small non-GUI applications that do not require any GUI libraries to run. To do this, you simply don't link HostGnome.

Message Loops vs. Signal/Event Handlers

On Windows every window has a window handler that recieves all messages and dispatches them. Gnome turns the concept around and uses call backs, called signals or events (strictly events are implemented using signals, but otherwise the concepts (signals and events) are quite different).

Basically message handling and call backs are equivalent, but since Gtk+ allows you to install more than one procedure to be called for each event you get some more possiblities to extend already finished controls. In Gtk+ it is possible to take a finished control (called Widget) and connect a call back function to catch for example mouse events. This can be done in several ways, either the new function can be called before or after the default function, and, if it is called before the default function then the new function can stop the event to prevent the default function to run. This type of control over the controls is not easy to achieve on Windows. On the other hand it means that the call back functions get spread out over the module and they are no longer all put together in one big message handler.

Interface Modules

The interface modules on Linux have not been automatically generated. This means that they are not complete. If functions are needed that are not already definied in the interface modules, then they need to be added. To add a function it is first needed to find the documentation for the function. This can be done in several ways: For the Gtk+ libraries the Gtk+ documentation is a good source. For other functions the man-pages might give some information, or if a header file is present then the definition of the function can be found there.

From headerfiles and documentation it is normally very difficult to find out in which library the function is implemented. For Gtk+ it is normally fairly easy to guess in which library a function is. A Gtk function is probably in libgtk.so and a Gdk function in libgdk.so. For other functions it is more difficult, but a lot of the basic functions are implemented in libc.so. To check whether a library actually implements a function, a small program called readelf can be used. This program reads the library and displays its content. To for example see if printf is implemented in libc.so.6, try this:

readelf -s /lib/libc.so.6 | grep printf

Typefaces

The Linux version of BlackBox saves the foundry in the typeface name for a font. This because the family is not unique. The same family can exist with different foundaries. However, to be more protable the foundry name is only saved when there really are more than one foundry installed on the current system.

Differences in Abstractions (MS Windows vs. Linux/Gnome)

GUI vs. non-GUI

The biggest conceptual difference between Windows and Linux/Gnome is that on Linux there is a clear distinction between GUI applications and non-GUI applications. On Windows you can always pop up a message box, but on Linux that is only possible when the GUI libraries are loaded.

For this reason some changes had to be made to the Kernel module and other modules that can be used in non-GUI as well as GUI applications (i.e. HostFiles). One such change is that Kernel now definies a GuiHook, which is used for Beep and MessageBox calls. If a GUI library is present then these hook allows for the library to install useful handlers for these type of calls. If no hook has been installed, these calls use standard out. This would actually be a meaningful change also for Windows, since a server written in BlackBox probably shouldn't pop up modal message boxes.

Another difference is the registry. On Windows module HostRegitstry uses the Windows registry. On Linux it would be tempting to use the GnomeConfig library, but then module HostRegistry could not be used with non-GUI applications.

X Windows

A different concept that comes with the X Window System is window managers. They have more control over the displayed windows than the shell on Windows has. For example, they control which window is currently on top and this probably makes it impossible for an application to implement anything like always-on-top.

Window managers also control many other things for the windows and this seems to rule out MDI windows in the sence that Windows uses them.

X also defines a format for describing fonts, xlfd. This format has no concept of underline or striketrhough, and since most font servers use this format these features are not available on X. BlackBox simulates underline and strikethrough by drawing a line in Ports.Draw(S)String, but this looks very different than true underline or strikethrough.

Windows Controls vs. GtkWidgets

Windows uses the "&" sign to indicate that a menu item or a label can be selected by pressing the alt-key and the character following the "&" sign. In Gnome the "_" character is used for this purpose and there is no automatic support for the alt-key. On top of that it sometimes look pretty bad since the fonts don't support underline.

The problem is that BlackBox uses "&" in the menu and string resources. The current implementation converst "&" to "" but this can probaly lead to inconsistencies, if for example the string already contains "" characters.

On Windows a menu item can be checked or not. Gnome uses a so called GtkCheckMenuItem, that displays a check box infront of the text. The check box is always there and can be checked or unchecked. The BlackBox abstraction is much closer to Windows and in a guard any menu item can be checked. There is no way for HostMenus to know if it should put a normal menu item or a GtkCheckMenuItem in the menu for a given menu item. The current implementation simply prepends a "*" to the text of a menu item when it has been checked by a guard.

A radiobutton can on Windows be checked or unchecked independent of other radiobuttons. BlackBox uses this, and module Controls keeps track of which radiobutton should be checked and which not. Gnome lets you create a group of radiobuttons and it then takes over the resposibility of making sure that only one radiobutton is checked at the time. If the group only contains one radiobutton it is always checked. Since HostCFrames can't know which radiobuttons belong together it has no chance of creating a reasonable group. The current implemnetation uses check boxes instead of radiobuttons, since they can be check and uncheck indepened of other check boxes.

The TreeControls in BlackBox have too many attributes that are only available on Windows. Things like icons or lines are also available in the GtkCTree widget, but to turn off the lines only at the root or to turn on or off the so called buttons is not possible. The current implementation just ignores the attributes it does not understand.

The background of a form is the color Ports.dialogBackground. Gnome allows themes that use bitmaps as background and this can't be handled with only a color as abstraction. This leads to that the widgets use the bitmap as background but a FormViews.View only uses the color.

Pictures

Gdk has a separate library for loading and saving pictures, calld libgdk_imlib. This libaray handle several formats, including jpeg, gif and bmp. But even if it is possible to display bmp-pictures using this library it is not possible to use the HostBitmaps views in BlackBox since this saves a complete Windows specific structure to file in externalize. It seems like pictures have to be incompatilbe between Windows and Linux because of this. The current version has no picture support at all, but there is an example of how to use libgdk_imlib in Lin/Mod/TestPic.odc.

Cursors

The cursors that BlackBox uses are definied in Ports and HostPorts. Many of the cursors definied in HostPorts seem to be portable and could be moved up to Ports. One difference between Windows and Gnome is that Windows only uses four different cursors for resizing whereas Gnome has six different ones. BlackBox only defines four resize cursors and this maps well to Windows, but for Gnome it is not clear which cursors to map to these four cursors. This could be solved by defining six cursors in BlackBox and letting the Windows version map two of the cursors to the same constants.

Left to Do

Each of the ported modules have a section called TODO at the top of the module. That section describes what is not yet implemented in that particular module. So, for details about what is left to do, the best sources of information are the ported modules themselfs. However, there are some particular things that are worth mentioning:

Printing

There is no support at all for printing at the moment. Module HostPrinters does not exist for Linux yet.

Drag'n Drop

Also not implemented. This should be implemented in HostMechanisms, and when this is done, it is a good idea to verify that the copy and paste implementation is ok. The current implementation of copy and past can probably be improved.

HostCFrames

Mostly implemented, but three things are missing:

All widgets, except buttons, do not recieve mouse events when they are disabled. This means that BlackBox doesn't notice that someone clicks on a disabled widget. For forms in layout mode this is a problem - disabled widgets can't be selected.

TimeField, DateField and ColorField are not implemented. UpDownField is implemented and maybe the same widget can be used for TimeFields and DateFields.

The group box control should probably be implemented with a GtkFrame, but can this widget be made transparent in the middle as a BlackBox group box is suppost to be? HostTabViews has the same problem.

Images

No image support is present in the current implementation.

SQL and ODBC

For the Sql subsystem, some kind of database connectivity support is needed. Does ODBC exist for Linux or are there any other possibilities?

HostRegistry

No support for persistant options is impelemented. Maybe a StdRegistry module should be implemented on top of a file based HostRegistry.

Porting Experiences

All in all it was surprisingly easy to port BlackBox to Linux. After just porting some of the most basic modules most frameworks within BlackBox already start working. Only the modules Kernel, HostFiles, HostPorts and HostWindows are needed to display a view. By adding HostMenus already ObxCube runs. And this without any of the mentioned modules being complete.

Even if the BlackBox parts of the port was easy, there was some things that could have been easier:

Use of Directory Objects

BlackBox makes extensive use of directory objects. The directories are normally implemented by some Host module. This means that if a particular Host module is not present then use of the corresponding directory object results in a NIL-trap.

In many cases a module can't live without a directory object and then a NIL-trap is just as good as a precondition. But when there is a reasonable way to handle a missing directory object it makes the life of someone trying to port all the Host modules much easier if this is done properly.

One such example is the use of Printers.dir in module Documents. Opening a document in BlackBox traps if Printers.dir is NIL, even though all this means is that it is not possible to print the document. By simply adding one IF statement before using Printers.dir in Documents, there was suddenly no need to port HostPrinters before a document could be opened in BlackBox. This new verision of Documents will be included in future reference versions also on Windows.

Host Imports in Portable Modules

Some module in the Std subsystem imports Host modules. This is not that appealing, since parts of the Host modules interfaces might not be protable, which means that the Std module using that Host module is not portable even though it is in the Std-subsystem. As an exampel StdTables uses cursors definied in HostPorts. If BlackBox is ported to a system that doesn't have these cursors, then StdTables cannot be loaded.

The only Std modules that uses Host modules are StdLog, StdTables and StdMenuTool. What they use are probably things that are mostly portable, so one solution would be to move these parts to some portable module, i.e. move some of the cursors definied in HostPorts to Ports and thus eleminating the need to import HostPorts.

A similar problem is HostRegistry. This is used for example in DevAnalyzer to save the settings for the analyzer. This means that a port of HostRegistry is needed before you can use DevAnalyzer, even though it would work fine also with default values for the settings.

Dialog.platform

In some places the variable Dialog.platform is used to let a module react differently on different platforms. When writing an IF or CASE statement using Dialog.platform you have no chance of knowing what future platforms will be supported. Thus, anybody doing a port must use "Search in Sources" to find all places where Dialog.platform is used and look closely at every such case to see what this means for the new platform.

The conclusion here is that Dialog.platform should not be used unless it is absolutely necessary. And if it is used it should be used together with the constants defined for it. In many places a value is calculated from the Dialog.platform to for example find out if it is any of the Windows platforms, i.e.:

IF Dialog.platform DIV 10 = 1 THEN it is Windows END

This is not very portable since it for example limits the number of possible Windows platforms to 10, and 6 are already definied, not including Windows ME, Windows XP or Windows CE.

Some Host modules use Dialog.platform. This is relatively safe, since these modules have to be looked at for any new platform anyway. But Dialog.platform is also used in:

DevRBrowser, TextFntTools, StdFold, StdLinks, DevDebug, DevRemDebug and MillStdFileProcessors.

Of these only DevRBrowser and StdFolds have been changed for the Linux port, but the others have not been closely looked at.

HostFiles.appName

HostFiles.appName is defined to not contain the ".exe" extension on Windows. This is only used in HostRegistry. HostPackedFiles would be portable betweeen Windows and Linux if the ".exe" extension would be included in teh definition. Would it be a good idea to move the truncation of the ".exe" extension from HostFiles to HostPackedFiles?

Menus

As mentioned in the section Windows Controls vs. GtkWidgets above the "&" characters in the menu resources need to be converted into "_" to work with the Linux version. Another problem is the Text subsystem menu. It contains some commands, for examle Insert non-Brk Space, that does not use the normal shortcuts. Instead the shortcut, in this case Shift-Alt-Space, is hard coded into the HostMenus key handling.

So far so good. The same kind of hard coded handling has been implemented in the Linux version, but the menu resource for the Text menu is more difficult. On Windows a menu item with a shortcut is displayed with the menu item text, then a tab and then the shortcut. So, by adding a tab and the text "Shift-Alt-Space" in the menu resource for Insert non-Brk Space it looks like a normal shortcut. This works completely different in Gnome and therefore the text menu looks pretty bad.

Fonts and Controls

The most difficult parts of the port were the fonts and the controls (widgets). The fonts were difficult because they were different than on Windows and the controls were difficult because they were so similar to the BlackBox controls.

A font discription on Unix (xlfd) seems to be much more detailed than on Windows. This makes it difficult to map the xlfd-descriptions to the BlackBox font abstractions. Finally we found a good solutions, and the fonts seem to work fairly good. The major problem is that underline and strike-through are not available on Unix.

Controls in Gtk are called widgets. Gtk is a toolkit for building applications with graphical user interfaces, so it wants to solve many of the same problems as BlackBox does. As an example BlackBox makes sure that a disabled control does not get any mouse messages. Unfortunately Gtk does exactly that too, which leads to that BlackBox does not notice that someone clicked on a disabled control/widget.

This would be alright if BlackBox only tried to prevent mouse events from coming to a disabled control. But this is not the case. When a form is in layout mode BlackBox needs to know if user clicks on a control even if it is disabled, since this means that the control should be selected.

In general, many other problems surface when BlackBox and Gtk tries to solve the same problems in very similar but slightly different ways. See the comments about radiobuttons and checked menu items above (section: Windows Controls vs. GtkWidgets).

Future

There is a new version of Gnome (2.0) coming. The interfaces for this version are already frozen, but the final implementation is not out. It would be interesting to know if the new version is backwards compatible or if many changes are necessary for BlackBox to run on Gnome 2.0.

Another interesting aspect is that Gtk+ is available for Windows. If this would be efficient enough, then only one set of Host modules would be needed for Linux and Windows.

Clone this wiki locally