[webkit-dev] Adobe Apollo's port of WebKit

Chris Brichford chrisb at adobe.com
Wed Mar 21 14:34:50 PDT 2007

Hi All,
	Below is a document I have written up describing the WebKit port that the Apollo team wants to build.  We'd like to know what the community thinks of the port we are proposing, what we should call such a port, and the process by which we should start submitting patches to WebKit.


===== Integrating WebKit with Apollo =====

While integrating WebKit with Apollo we created a new port of WebKit.  Right now this port of WebKit uses a hybrid of platform specific code and cross platform interfaces provided by the WebKit host( which in our case is the rest of the Apollo Runtime ).  The goals for our port are:
  * As little platform specific code in WebKit as possible.  Implementation of platform abstractions will forward to the WebKit host.
  * Same API on all platforms
  * API calling convention that can be safely implemented on a variety of platforms and that does not assume that WebKit and the WebKit host are compiled with the same compiler. 

We are asking for help from the rest of the WebKit community on how to best achieve these goals.  In most cases we can achieve these goals without changing core cross platform code.

We are also asking for help with specific mundane things like:

  * What to call our sub-directory in WebCore/platform
  * Should we make our WebKit a subdirectory in WebKit like WebKit/COM?  Should we make a new top level directory?
  * How to submit patches specific to our new platform ( do we enter a bug and attach patches to it? )
  * What to call the port.  Apollo is just a code name and will change before we ship 1.0.  We also intend that the API between the host and this port will not be specific to Apollo.

We are asking for help now, because we are starting the process of getting the latest version of WebKit integrated with Apollo.  Enough has changed that this will be a large amount of work for us.  We want to use this fact as an opportunity to provide incremental patches to WebKit.  We want to get to top of tree and stay there until we lock down for our release.  This will also enable us to contribute fixes to the core code in a more timely matter.

The rest of this document describes the concepts we want to use in this new port.  The goal is to describe enough of what we want to do so we can decide what to call this new port and where it lives in the svn repository.  For the rest of this document I'll refer to this new port of WebKit as WebKitFoo.  

==== API foundation ====
Since WebKitFoo is designed to be as cross platform as possible, the API uses a simple C API.  The API is an object oriented API where there are objects and some set of methods that can be invoked on each type of object.  An object instance is pointer to a struct that contains a single member, a pointer to a vtable structure.  The vtable structure has a member for each method of the object, which is a pointer to a function that takes a pointer to the object instances as the first argument.  Here is an example of an object's interface definition:
struct WebKitFooBitmapVTable;
struct WebKitFooBitmap;

typedef WEBKIT_FOO_PROTO1 void* ( WEBKIT_FOO_PROTO2 *t_WebKitFooBitmapGetPixelData )( struct WebKitFooBitmap* pBitmap );

typedef WEBKIT_FOO_PROTO1 unsigned long ( WEBKIT_FOO_PROTO2 *t_WebKitFooBitmapGetWidth )( struct WebKitFooBitmap* pBitmap );

typedef WEBKIT_FOO_PROTO1 unsigned long ( WEBKIT_FOO_PROTO2 *t_WebKitFooBitmapGetHeight )( struct WebKitFooBitmap* pBitmap );

typedef WEBKIT_FOO_PROTO1 unsigned long ( WEBKIT_FOO_PROTO2 *t_WebKitFooBitmapGetStride )( struct WebKitFooBitmap* pBitmap );

struct WebKitFooBitmapVTable
        unsigned long m_vTableSize;
        t_WebKitFooBitmapGetPixelData getPixelData;
        t_WebKitFooBitmapGetWidth getWidth;
        t_WebKitFooBitmapGetHeight getHeight;
        t_WebKitFooBitmapGetStride getStride;

struct WebKitFooBitmap
        const WebKitFooBitmapVTable* m_pVTable;

The WEBKIT_FOO_PROTO1 and WEBKIT_FOO_PROTO2 macros are used to control the calling convention of the functions that implement the methods of the object.  This ensures that the calling convention of the functions is specified explicitly which allows the client of WebKitFoo to be compiled with a different compiler than the compiler used to compile WebKitFoo.

WebKitFoo uses this mechanism rather than platform specific mechanisms such as COM or OBJ-C because one of the design goals of WebKitFoo was to present exactly the same interface on all supported platforms.  It should also be noted that it is not necessarily safe to perform a C++ call across a shared library boundary, which is why this interface mechanism uses pure C.  We also will disallow all forms of exceptions ( C++, Objective-C, and longjmp ) from crossing the shared library boundary.  This approach also allows for runtime dispatch and is type safe.
The WebKitFoo interface uses built-in C types where possible and avoids introducing new types that are aliases of built-in C types.

  * Booleans are represented as unsigned char with two legal values, 0 and 1.
  * Bytes are represented as unsigned char.
  * Strings are represented as arrays of bytes using the UTF-8 encoding or as arrays of uint16_t ( platform endian ) using the UTF-16 encoding.
  * Strings are length limited and NOT necessarily NULL terminated.  The length is passed as a separate argument to any function that takes a string as an argument.

==== Display ====
WebKitFoo renders each HTML window to a bitmap created by the host of WebKitFoo.  The host determines where in memory the pixel data of these bitmaps is located.  The host is responsible for drawing bitmap data to the screen if needed.  The host is given enough information to know which parts of a bitmap have been updated.  The bitmaps are always in the same format on a given platform and always use 32-bit pixels ( RGBA ).

WebKitFoo uses platform specific code internally to rasterize fonts and vector graphics to the provided bitmap.  On OSX CoreGraphics is used and on Windows Cairo is used.  In the long term the host of WebKitFoo will provide the rasterization code, removing large amounts of platform specific code in WebKitFoo.

==== Events ====
Mouse and keyboard events must be harvested by the host of WebKitFoo and forwarded into each HTML window being rendered by WebKitFoo.  In response to these events WebKitFoo may request that parts of an HTML window be repainted, the host is then responsible for arranging for those parts of the HTML window in question to be updated.

==== Network ====
Requests for images, style sheets, JavaScript's, XML ( via XMLHttpRequest ), and other resources referenced by an HTML document being rendered by WebKitFoo are forward to the host of WebKitFoo.  The host is responsible for downloading the requested resource, feeding the http response headers, and data into WebKitFoo.  WebKitFoo contains no platform specific code for downloading content from the network.

==== Form Widgets ====
WebKitFoo contains or will contain platform independent implementations of all HTML form widgets.  These widgets are rendered using the existing cross platform drawing abstractions in WebKit, namely WebCore::GraphicsContext.  The host of WebKitFoo will be required to open a new window for doing a pop-up window to render a drop down select.

==== Background Processing ====
WebKitFoo will route all requests for background processing to the host of WebKitFoo.  WebKit uses background processing to implement JavaScript timers, redirection timers, etc.  We never want WebKitFoo to execute any code unless its host is on the call stack.  We also want the host to know for which WebView it is give execution time to WebKitFoo.  This is one area where changes to the core WebCore code may be needed.

==== Modal dialogs ====
WebKitFoo routes requests to show modal dialogs to the host of WebKitFoo.  Requests to show these modal dialogs come from either JavaScript (window.alert(), etc) or the file upload form widget.

==== Other ====
Over time will want to route other operating system services thought the WebKitFoo host.  Here is a list of things that we know of and are not specifically mentioned elsewhere.

  * Changing mouse cursor
  * Security checks ( allow WebKitFoo host to participate in script and server access decisions )
  * User agent string access
  * Accessibility
  * Localized string resource loading ( "Submit", "Reset", etc. )
  * Printing
  * Plug-in loading

==== Summary ====
The basic design goal is that we want to enable people to port WebKitFoo without changing WebKitFoo.  In many cases there are already internal interfaces in WebKit or WebCore to abstract away the details of porting WebKit. Where those interfaces exist we allow the host of WebKitFoo to implement those interfaces.  In other cases, such as form widgets, new code must be added to WebCore or WebKitFoo to implement functionality in a cross platform manner.

We are not proposing any changes to the current ports nor to any of the interfaces between the core code and the current ports.  We believe that all the changes we need to make to the core code would be the same in scope as a port to a new operating environment.

What we need to know in the near future is:
  * What to call our port.  WebKitFoo is a really cool name, but.....
  * Where to put WebKitFoo ( Subdirectory of WebKit or peer of WebKit? )
  * Anything else you think is important that we know before we start submitting patches.

More information about the webkit-dev mailing list