The main idea of the SWT library is such that its internal implementation on the certain platform is made in the terms of that platform, directly using its native API through the JNI interface, so the look'n'feel comes close to the regular platform applications (i.e. usability; other important benefits of such approach are: easiness, stability, performance). This means that there is a different implementation of the basics of SWT for each supported platform; only the public interface of SWT classes is, of course, the same. So the term "porting" in this case means rewriting the most part of the internal logic from scratch (sometimes including the whole classes) rather than just correcting it for the specific OS. Therefore we have chosen to start from the very beginning and go possibly like original Eclipse developers did, from the basics (the top of the class hierarchy) to details, creating the java and the native code in parallel. The best way to do it is to divide our work into little steps (tasks): every of them is the next level of the implementation and can be tested regardless of other parts that are to be implemented on the next levels.
Technically, SWT sources consist of two parts: one is written in Java, another is written in C and contains native methods that communicate with Java code through JNI.
The table below represents basic subcomponents of SWT as they were
    defined by the original developers. There's a separate directory for each
    subcomponent in the structure of the Eclipse sources. Packages with names
    in bold are platform specific (i.e. have their own implementation
    on each platform), other are common for all platforms (but may require
    some adaptation for a certain OS). o.e.swt here and further
    is a short form of org.eclipse.swt, for convenience.
| Name | Description | Packages | Prognosis | 
|---|---|---|---|
| SWT Base | SWT Base. Contains the major part of all public classes and interfaces. Implementations of many basic classes (Display, Widget etc.) are individual for each supported platform. | o.e.swt.events o.e.swt.graphics o.e.swt.internal o.e.swt.internal.image o.e.swt.layout o.e.swt.widgetsefwef o.e.swt.graphics o.e.swt.internal o.e.swt.widgets | Platform dependent parts need to be almost fully rewritten for OS/2 | 
| SWT PI | SWT Platform Implementation. Contains platform dependent internal implementations of SWT interface, including Java wrappers for platform native API data structures. | o.e.swt.internal o.e.swt.internal.<xxx> | Needs to be almost fully rewritten for OS/2 | 
| SWT AWT | It's an experimental class (works currently only on Win32 and has some limitations) to make it possible to embed AWT widgets to SWT layout. | o.e.s.internal.awt.<xxx> | Can be implemented in the future? | 
| SWT Accessibility | Accessibility support. | o.s.swt.accessibility o.s.swt.accessibility | Is it supported natively by OS/2 or should be emulated? | 
| SWT Custom Widgets | Standard custom widgets library | o.e.swt.custom | Does not contain any platform dependent code? | 
| SWT Drag and Drop | Public interface for D'n'D support | o.e.swt.dnd o.e.swt.dnd | Platform dependent implementations need to be rewritten (partially ported from Win32?) for OS/2 | 
| SWT Printing | SWT printing capabilities | o.e.swt.printing o.e.swt.printing | Needs to be almost fully rewritten for OS/2 (not a lot of work to do) | 
| SWT Program | OS specific program launching aspects | o.e.swt.program | Just one single class <) | 
| SWT OLE | OLE support | o.e.swt.ole.win32 o.e.swt.internal.ole.win32 | Can the similar one be implemented for OS/2 in the future? | 
C sources of native methods are organized in the following way:
org.eclipse.swt.internal.Callback
      class, that allows using regular Java methods as callback functions by
      the platform native API.Native methods serve as a bridge between SWT and underlying platform
    API. One of Eclipse principles is that such mapping should be transparent
    as much as it possible. It means that Java methods have exactly the same
    name and behavior as their native counterparts, including the type and the
    list of arguments and the return value. For that purposes there are Java
    wrappers exist for native structures used by platform API functions to
    exchange information with the application. These wrapper classes are
    defined in the SWT PI part as well as the o.e.swt.internal.OS
    class containing (almost?) all of native API-to-Java mappers. But due to
    the fact that Java semantics differ from C there cannot be the full
    equivalence between C and Java types, so some considerations about mapping
    should be taken into account.
[unsigned] int,
      [unsigned] long and derived) are mapped to Java
      int type.boolean type.[unsigned] short (and derived) is
      mapped to Java short type.[unsigned] char (and derived) is
      mapped to Java byte type....
int*
      is mapped to int[]). There's one exception with ASCIIZ
      strings (see below).int type.int array (see below).There's a special case with pointers to arrays and ASCIIZ strings, which are returned by some platform API calls to represent some data of variable length. There are few situations when such data is not copied to the storage area provided by the caller, but the pointer to the internal storage area is returned. In these situations we cannot allocate the storage for that data in Java before a call to a native method, because we don't know its size. The solution can be to create the corresponding Java array object inside of the C implementation of the native method after an API call (when we already know the size of the data returned) fill it and return the reference to this object to the Java caller.
Also there are sutiations when an API call returns a pointer to a
    structure from its internal storage and the user should be able to access
    this data directly to change some value (the good example is
    DosGetInfoBlocks()). Since a Java structure wrapper class
    contains a copy of the original data it doesn't make sence to use it as a
    parameter to call such API -- it's better to return a pointer to the
    caller "as is" using a reference to one-element array of int
    type to use it for the direct access. But Java cannot read/write directly
    to the specified memory address, so we need some helper functions to copy
    data from a wrapper class directly to a given memory location and back.
    These functions are overloaded versions of
    o.e.swt.internal.pm.OS.objcpy(). They take two arguments: the
    destination (the first one) and the source (the second one) of data to be
    copied. One of them is a reference to a wrapper class and another is an
    int value containing the address of (the pointer to) the
    corresponding C structure. So, to the sequence of operations to get the
    required result can be:
int arrayOS.objcpy() to copy data to the object of the
      wrapper classOS.objcpy() to copy data back from the object to
      the memoryNote. These helper functions are potentionally dangerous and
    should be used very carefully since there's no way to check whether a
    given pointer really points to the structure of the appropriate type or
    not. However, if zero or null is passed as one of arguments,
    an SWTError exception will be thrown (this behavior depends
    on the DEBUG_CHECK_NULL_EXCEPTIONS macro definition during
    compilation of the SWT DLL).
ASCIIZ strings are mapped using references to the special Java wrapper
    class: o.e.swt.internal.pm.PSZ. String data is actually
    stored in its bytes field which is of byte[]
    type. This class provides automatic appending of zero byte to the array
    when constructed from Java String type and removing that byte
    when converted back to String. Convertion between Unicode and
    8-byte ASCII characters is done using the default system codepage. There
    are helper functions to handle this wrapper in C:
    getPSZArray(), getPSZBytes() and
    releasePSZBytes(), see their description at the top of
    structs.h.
C structures are mapped to Java classes (wrappers) with the same name
    and fields (their order and names). Primitive fields' types are mapped
    according to the rules above. For every structure the following C helper
    functions are defined: cacheXXXFids() (and the correspondig
    XXX_FID_CACHE structure) to cache Java field IDs,
    getXXXFields() to fill the native C structure with values
    from the Java wrapper structure before a call to platform API routine and
    setXXXFields() for backward operation after a call.
If some field of the structure is itself a structure or a pointer to a structure, there are two ways to handle this situation:
xxx_yyy, where xxx is the
      name of the field representing the nested structure and yyy
      is substituted with field names of that nested structure. It's useful
      when the structure has few fields. As an example, see the
      o.e.swt.internal.pm.QMSG wrapper class.getXXXFields() and
      setXXXFields() must correctly handle this case. For
      example, see TIB and TIB2 wrappers and their
      getters/setters (though TIB2 does not actually need to be
      used as a whole, it was done so for clarity). Note that such nested
      wrapper is newed (via the initializer expression) in the parent
      wrapper's implicit constructor.Some structures have the special field (cb or
    cbFix) that should be set to the length of the structure
    before passing it to a function. In Win32 version this is achieved by
    adding an extra field (sizeof) to Java wrapper of every
    structure and then assigning its value to the length field when using the
    structure from Java code. In OS/2, this is done not at the Java level, but
    in the code of the structure's getter function. Therefore, the need in the
    sizeof field is eliminated (tough,some strucrures will have
    this field because there are some cases when arrays of that structures are
    given us as a pointer from the C code and we need to know the address of
    the particular structure in the array). Also, Java wrappers in OS/2 do not
    contain the cb or cbFix field since it's useless
    from the point of view of data the structure represents.
Since it's too complicated (in particular, requires two transformations
    and two times more memory) to convert arrays of C structures to arrays of
    their Java wrappers and back, such arrays are mapped to arrays of Java
    int type, where every one or more elements of that array
    correspond to a field from the structure, consequtively. Of course, it's
    suitable only for structure types where all fields have the size which is
    multiple of 32-bit int type, such as POINTL and
    RECTL. This is primarily used in Gpi* API calls.
    Hopefully, at the present time there is no need to work with other types
    of structures.
For convenience, parameter names in the declaration (in Java) and in the definition (in C) of native methods should be the same as in the toolkit documentation.
SWT compilation is driven by the build.xml located in the src\plugins\org.eclipse.swt.pm directory of the repository. It should not be used directly since there are some prerequisites that are set up from the main build file.
Ant includes in compilation every .java file it finds in the specified source directory. Since we go class by class, but use complete common source directories from the original distribution, we need a way to narrow a list of files to compile. Otherwise we will get many errors because of missing platform dependent classes (which are not yet ready) referenced from common sources during compilation. To exclude temporarily the whole common directory is not a good idea because we might need some classes from there. So, there is a special file called classes.inc in the same directory as the SWT build file that contains a list of all files to be compiled. Paths there are relative to the source directories, so every entry there is just a full name of a class but with dots replaced by slashes in the package name. Although file masks can be used there it should be done carefully because file mask will apply to every source directory (we cannot change this behavior in Ant) and unnecessary files can be included.
Below is the plan and the progress of the SWT porting process. Each step number and objective is a link to the corresponding step description. The names of classes here, in the step descriptions and in some other places follow the rule: the text in [square brackets] after the class name shows the name of the SWT part the class belongs to (according to the table above) and the sharp (#) sign before it means that the class is platform specific, otherwise it is common.
| # | Objective | Started | To be done | Actually done | 
|---|---|---|---|---|
| 1 | Initial moves. CVS setup, dummy Device[#Base] implementation. | 2002-10-21 | 2003-01-15 | 2003-01-21 | 
| 2 | Basics of GUI, part 1. Partially
        implement the basic hierarchy from the WidgettoShell. | 2003-01-24 | 2003-02-24 | 2003-03-11 | 
| 3 | Basics of GUI, part 2. Implement drawing facilities | 2003-03-12 | 2003-04-15 | 2003-07-11 | 
| 4 | Layout basics. Implement the basics of the layout management. | 2003-03-12 | 2003-04-15 | 2003-07-11 | 
| 5 | Font handling. Implement font handling. | 2003-07-12 | 2003-08-01 | 2004-02-29 | 
| 6 | Image handling. Implement Image handling | 2003-07-22 | 2003-08-15 | 2003-11-24 | 
| 7 | Buttons. Finish the implementation of
        the Buttonwidget | 2004-03-01 | 2004-03-10 | 2004-10-31 | 
| 8 | Standard dialogs. Implement standard
        dialogs ( Dialogderivants). | 2004-12-09 | ?? | |
| 9 | Labels. Implement the Labelclass. | 2004-12-09 | ?? |