SWT Step 1. Initial moves

Objective

Start our work by setting up a working environment (cvs) and creating a skeleton of the SWT with the least possible functionality, that can be successfully compiled and tested with the simplest dummy example (creation of the Display object).

Task notes

The one of the basics of SWT is o.e.swt.widgets.Display class that represents an SWT session. It represents a connection between SWT an the underlying platform's GUI and manages the platform event loop. It is created by the application's main thread (UI thread) which runs the event loop and dispatches events directly from it. Every (?) SWT program creates a Display object so it's a good place to begin. The minimum functionality to implement is the message queue creation/deletion, readAndDispatch() method and internal_new_GC(), intermal_dispose_GC() methods (including their native representations) which leads to a partial implementation of o.e.swt.OS class and also few others (see checklist). All other stuff should be temporarily commented. Of course, without any visible window (which is represented by the Shell class) we cannot get keyboard and mouse messages from the system but there should be a couple of system events that we can get and write their info to the log file. As a criteria of the step completion will be a simplified SWT example HelloWorld1 (with the Shell code ripped off).

Step checklist

Operation Status Remarks
Create the initial directory structure in cvs, initially checkin common SWT parts as rel-2-0-1 on the eclipse-team branch Done [dmik] Common native C code from [Base] (\src\plugins\org.eclipse.swt\Eclipse SWT\common\library) and o.e.swt.internal.Library [PI] are checked in.
Include o.e.swt.Drawable [Base] in compilation Done [dmik]
Add o.e.swt.graphics.Device, DeviceData, GCData [Base] and comment all unnecessary parts Done [dmik]
Create o.e.swt.internal.pm.QMSG [PI] Done [eli] [QMSG]
Create o.e.swt.internal.pm.MPARAM [PI] Done [eli] Now it's uncomplete and not used.
Create o.e.swt.internal.pm.POINTL [PI] Done [eli] Now it's not used.
Add o.e.swt.widgets.Display [PI] and comment unnecessary parts Done [dmik]
Create o.e.swt.internal.pm.OS [PI] Done [dmik]
Port o.e.swt.internal.Library [PI] Done [dmik] OS/2 (or Java under OS/2) is unable to handle DLL files with long names, only 8.3 format is allowed (see Q&A #2). So, SWT DLL file name will be constructed as swtpNNNN.dll (where NNNN is the SWT version number). Revision number will be ignored.
Create dummy (empty) C natives [PI], port callback.h [Base] and setup VAC4 compilation Done [dmik] At this moment the build of natives is done by \src\plugins\org.eclipse.swt\Eclipse SWT PI\pm\library\build.cmd (later will be called from the main build file). The native callback stuff seems to be compiled ok. Not properly tested, but o.e.swt.SWT.getPlatform() (that uses o.e.swt.internal.Callback.getPlatform()) works.
Implement OS.WinAlarm() (swt.c) as an example of native mappings and OS.WA_* constants for it; implement Display.beep() Done [dmik] This is an analogue of Win32's MessageBeep(). [WinAlarm] (see Q&A #6).
Add OS.HWND_DESKTOP (=1) and OS.NULLHANDLE (=0) constants. Done [dmik] See Q&A #6.
Implement OS.WinGetLastError() for debugging purposes Done [dmik]
Add Display.hab field (together with hmq) and add its initialization and cleanup (OS.WinInitialize() and OS.WinTerminate(), OS.WinCreateMsgQueue() and OS.WinDestroyMsgQueue()) to init() and release() (actually releaseDisplay()) methods Done [dmik] See O&A #7. An attempt to create a msg queue in the program started by java.exe will lead to PMERR_NOT_IN_A_PM_SESSION (0x1051) error. Execution under javaw.exe is ok => see O&A #8.
Implement OS.DosGetInfoBlocks() to make it possible to get the current thread and process id and create wrapper classes for the corresponding structures: o.e.swt.internal.pm.TIB, o.e.swt.internal.pm.TIB2, o.e.swt.internal.pm.PIB, and getters/setters for them (structs.h/structs.c). Done [dmik] Curently, PIB.pib_pchcmd and PIB.pib_pchenv are not implemented.
Note: Useful information about the implementation of native methods can be found here.
Change OS.DosGetInfoBlocks() implementation. Done [dmik] Since DosGetInfoBlocks()returns pointers to its internal data rather than fills structures provided by the caller and since we need the direct access to that data from Java, it will be more "native" and useful to change arguments of the wrapper to arrays of int with one element to return this pointers to Java caller and then use OS.objcpy to excahge data between the memory they point to and Java TIB/PIB structure wrappers.
Implement OS.DosQuerySysInfo() and OS.QSV_* constants to get the OS/2 version and revision, define OS.IsWarp3, OS.IsWarp4, OS.IsAurora constants. Done [dmik]
Implement OS.PSZ wrapper and C helpers for it to handle ASCIIZ strings. Done [dmik] See conventions about ASCIIZ strings.
Finish the preliminary Display imlementation to get a working message queue and add the following OS natives for this:
  • WinRegisterClass (and CS_* constants)
  • WinCreateWindow (and WS_* constants)
  • WinDestroyWindow
  • WinDefWinProc
  • WinPeekMsg
  • WinDispatchMsg
  • WinPostQueueMsg
  • WinWaitMsg
Also include some common classes in compilation (see classes.inc).
Done [dmik] The last objective in the test example (SWT001.java) shows the same behavior as its C equvivalent. Nonvisible message-only window receives WM_CREATE upon creation, then WM_ADJUSTWINDOWPOS, then a locale message, then the message loop terminates and the window receives a WM_CLOSE message upon destroying. This behavior does not depend on whether the test is run in PM mode or in VIO. Everything seems to be working correctly.