[cairo] Cairo ported to OS/2 - Suggestions

Doodle doodle at scenergy.dfmk.hu
Tue Aug 16 02:02:52 PDT 2005


Hi all,

I've managed to port Cairo to OS/2, using the OpenWatcom compiler.
While I was working on it, I've discovered some "shortcomings" of
the public header file, for which I've proposed some things to
Carl Worth, who kindly told me that the official way of modifying
anything in Cairo is to discuss it on this list. So, here I am. :)

The problem I've found is coming from the fact that it's still
common on OS/2 to use different C/C++ compilers, like GCC, OpenWatcom
or IBM VisualAge C++. The root of the problem is that the public
Cairo API and its public callback function types do not have any
calling convention defined. It means that all the functions use
and assume the default cdecl convention.

Unfortunately, the exact implementation of cdecl convention can vary
from one compiler to another (can even be different for one compiler
if some switches are used), so it makes it impossible to use my
cairo.dll (compiled with a given compiler) with applications which
are compiled with a different compiler.

The solution for this is to select a given calling convention which
is implemented the very same way on all compilers (like for example
syscall on OS/2), and define the public (exported) API to use this
convention.

It is done in most of the bigger multiplatform libraries, like for
example SDL.


So, my proposal, for which I'd like to hear your opinions, is to
modify the public API to something like this:

CAIRODECLSPEC cairo_t * CAIROCALL
cairo_create (cairo_surface_t *target);

CAIRODECLSPEC void CAIROCALL
cairo_destroy (cairo_t *cr);

typedef void (CAIROCALL *cairo_destroy_func_t) (void *data);

[...and so on...]

and have somewhere a define for CAIRODECLSPEC and CAIROCALL,
something like this:

#ifndef CAIROCALL
/* Define calling convention for Cairo */
#ifdef WIN32
/* Use __cdecl for Win32 */
#define CAIROCALL __cdecl
#else
#ifdef __OS2__
/* Use __syscall for OS/2 */
#define CAIROCALL __syscall
#else
/* Use __cdecl for all other platforms */
#define CAIROCALL __cdecl
#endif
#endif
#endif

#ifndef CAIRODECLSPEC
/* Define function import/export keywords */
#ifdef WIN32
#ifdef BUILD_CAIRO
/* Export functions (Win32) */
#define CAIRODECLSPEC __declspec(dllexport)
#else
/* Import functions (Win32) */
#define CAIRODECLSPEC __declspec(dllimport)
#else
#ifdef __OS2__
#ifdef BUILD_CAIRO
/* Export functions (OS/2) */
#define CAIRODECLSPEC __declspec(dllexport)
#else
/* Import functions (OS/2) */
#define CAIRODECLSPEC
#endif
#else
/* Export/Import functions (fallback) */
#define CAIRODECLSPEC
#endif
#endif
#endif


In addition to solving my problem, it would have one more advantage:
By using the CAIRODECLSPEC defined above, it would be controlled from
the source code which functions are exported and which are not. I think
it's always better to let others use only those functions we let them
to use.

(And being a bit of selfish here: it would save me a lot of job,
because right now I have to tell the OpenWatcom linker which
functions to export, but if the code would have these defines,
the linker would know them automatically.)


What do you think about it?

Bye,
   Doodle



More information about the cairo mailing list