/**
* toolkit.h -
*
* Copyright (c) 1998
* Transvirtual Technologies, Inc. All rights reserved.
*
* See the file "license.terms" for information on usage and redistribution
* of this file.
*/
#ifndef __toolkit_h
#define __toolkit_h
extern "C" {
#include "config.h"
#include "config-std.h"
#include "config-mem.h"
#include <native.h> /* needed for enter/leaveUnsafeRegion */
/* !!!
#include "../../../../kaffe/kaffevm/gtypes.h"
#include "../../../../kaffe/kaffevm/gc.h"
#include "../../../../kaffe/kaffevm/thread.h"
*/
#include "../../../../kaffe/kaffevm/debug.h"
}
#include <InterfaceKit.h>
/* !!! added */
#include <stdio.h>
#define UNIMPLEMENTED(block) printf("unimplemented statements @ %s:%d\n", __FILE__ , __LINE__)
#define TOFIX() printf("incomplete function called @ %s:%d\n", __FILE__ , __LINE__)
#undef __cplusplus /* !!! RISKY BUSINESS */
#include <jni.h>
#if defined(HAVE_STRING_H)
#include <string.h>
#endif
/* native BeOS AWT is compiled as C++ but linked by VM as C */
#define AWT_EXPORT extern "C"
/*******************************************************************************
* color conversion structures
*/
#define N_DIRECT 256
typedef struct _Rgb2Direct {
unsigned char red[N_DIRECT];
unsigned char redPix[N_DIRECT];
int redShift;
int nRed;
unsigned char green[N_DIRECT];
unsigned char greenPix[N_DIRECT];
int greenShift;
int nGreen;
unsigned char blue[N_DIRECT];
unsigned char bluePix[N_DIRECT];
int blueShift;
int nBlue;
} Rgb2Direct;
typedef struct _Rgb2True {
unsigned int redMask;
unsigned int greenMask;
unsigned int blueMask;
int blueShift;
int redShift;
int greenShift;
} Rgb2True;
typedef struct _RgbColor {
unsigned char r;
unsigned char g;
unsigned char b;
} RgbColor;
typedef struct _Rgb2Pseudo {
RgbColor rgb[256];
unsigned char pix[8][8][8];
} Rgb2Pseudo;
/*******************************************************************************
* image handling structures
*/
typedef struct _AlphaImage { /* storage for full alpha channel images */
unsigned char *buf;
int width, height;
} AlphaImage;
#define NO_SHM 0 /* we don't have MIT-Shm support in the X server */
#define USE_SHM 1 /* we have support, use it */
#define SUSPEND_SHM 2 /* we have support, but it ran out of space */
typedef struct _Image {
BBitmap *bitmap; /* native bitmap image */
#if TODO
Pixmap pix; /* pixmap for screen images */
XImage *xImg; /* "real" image */
XShmSegmentInfo *shmiImg; /* Shm info for shared mem real image */
XImage *xMask; /* mask image for reduced alpha (on/off) images */
XShmSegmentInfo *shmiMask; /* Shm info for shared mem mask image */
AlphaImage *alpha; /* full alpha channel (for alpha != 0x00 or 0xff) */
#endif
int trans; /* transparent index */
int width, height; /* we need this in case we are a pixmap */
int latency; /* between image flips, for "gif-movies" */
struct _Image *next; /* next movie-frame */
int frame;
} Image;
/*********************************************************************/
typedef class JavaWindow * Window;
typedef void * Cursor;
/*******************************************************************************
* structure to store guessed and computed Frame/Dialog insets (titlebar, borders)
*/
typedef struct _DecoInset {
int left;
int top;
int right;
int bottom;
char guess;
} DecoInset;
/*******************************************************************************
* We use our own structure instead of directly storing X window handles, to
* enable us to attach and query attributes (owners, states, flags..) to particular
* X window instances. We could do this by means of X properties, but this might
* end up in costly round-trips and even more memory (than we trade for speed here).
* It's a must have for our popup key/focus event forwarding (see wnd.c)
*/
typedef struct _WindowRec {
Window w;
unsigned flags;
Window owner;
} WindowRec;
/*******************************************************************************
* this is the master AWT structure (singleton object), glueing it al together
*/
typedef struct _Toolkit {
BApplication *app;
/* !!!
Display *dsp;
Window root;
*/
char *buf;
unsigned int nBuf;
int colorMode; /* refers to CM_xx constants, not X visuals */
Rgb2True *tclr;
Rgb2Pseudo *pclr;
Rgb2Direct *dclr;
/*
int shm;
int shmThreshold;
*/
Cursor cursors[14];
DecoInset frameInsets;
DecoInset dialogInsets;
BMessage *event;
// BMessageQueue *queue;
char preFetched;
char blocking;
int pending;
int evtId;
Window lastWindow;
int srcIdx;
Window *windows;
unsigned int nWindows;
/* !!!
Window cbdOwner;
Window wakeUp;
Window newWindow;
*/
} Toolkit;
/*******************************************************************************
* global data def/decl
*/
#ifdef MAIN
Toolkit theTk;
Toolkit *Tlk = &theTk;
/* !!!
Atom WM_PROTOCOLS;
Atom WM_DELETE_WINDOW;
Atom WM_TAKE_FOCUS;
Atom WAKEUP;
Atom RETRY_FOCUS;
Atom SELECTION_DATA;
Atom JAVA_OBJECT;
*/
jclass AWTError;
JNIEnv *JniEnv;
#else
extern Toolkit* Tlk;
/* !!!
extern Atom WM_PROTOCOLS;
extern Atom WM_DELETE_WINDOW;
extern Atom WM_TAKE_FOCUS;
extern Atom WAKEUP;
extern Atom RETRY_FOCUS;
extern Atom SELECTION_DATA;
extern Atom JAVA_OBJECT;
*/
extern jclass AWTError;
extern JNIEnv* JniEnv;
#endif /* MAIN */
/*****************************************************************************************
* heap wrapper macros
*/
static __inline__ void* _awt_malloc_wrapper ( size_t size )
{
void *adr;
enterUnsafeRegion();
adr = malloc( size);
leaveUnsafeRegion();
DBG( AWT_MEM, printf("malloc: %ld -> %p\n", size, adr));
return adr;
}
static __inline__ void* _awt_calloc_wrapper ( int n, size_t size )
{
void *adr;
enterUnsafeRegion();
adr = calloc( n, size);
leaveUnsafeRegion();
DBG( AWT_MEM, printf("calloc: %d,%ld -> %p\n", n, size, adr));
return adr;
}
static __inline__ void _awt_free_wrapper ( void* adr )
{
DBG( AWT_MEM, printf("free: %p\n", adr));
enterUnsafeRegion();
free( adr);
leaveUnsafeRegion();
}
#define AWT_MALLOC(_n) \
_awt_malloc_wrapper( _n)
#define AWT_CALLOC(_n,_sz) \
_awt_calloc_wrapper( _n, _sz)
#define AWT_FREE(_adr) \
_awt_free_wrapper( _adr);
/*******************************************************************************
*
*/
static __inline__ char* java2CString ( JNIEnv *env, Toolkit* Tlk, jstring jstr ) {
// !!! NOW DIFFERENT FROM X VERSION
jboolean isCopy;
register unsigned int i;
unsigned int n = (*env)->GetStringLength( env, jstr);
const jchar *jc = (*env)->GetStringChars( env, jstr, &isCopy);
if ( n >= Tlk->nBuf ) {
if ( Tlk->buf )
AWT_FREE( Tlk->buf);
Tlk->buf = (char *) AWT_MALLOC( n+1);
Tlk->nBuf = n+1;
}
for ( i=0; i<n; i++ ) Tlk->buf[i] = (char) jc[i];
Tlk->buf[i] = 0;
(*env)->ReleaseStringChars( env, jstr, jc);
return Tlk->buf;
}
class Java2CString {
char *cstring ;
public:
Java2CString( JNIEnv *env, jstring jstr )
{
jboolean isCopy;
unsigned int len = (*env)->GetStringLength( env, jstr );
const jchar *jc = (*env)->GetStringChars( env, jstr, &isCopy );
cstring = (char*)malloc(len+1);
unsigned int i;
for(i=0;i<len;i++) {
cstring[i] = (char)jc[i];
}
cstring[i] = 0 ;
(*env)->ReleaseStringChars( env, jstr, jc );
}
~Java2CString()
{
free(cstring) ;
}
char *toChars()
{
return cstring ;
}
} ;
static __inline__ char* jchar2CString ( Toolkit* Tlk, jchar* jc, int len ) {
register int i;
unsigned int n = len+1;
if ( n > Tlk->nBuf ) {
if ( Tlk->buf )
AWT_FREE( Tlk->buf);
Tlk->buf = (char *) AWT_MALLOC( n);
Tlk->nBuf = n;
}
for ( i=0; i<len; i++ ) Tlk->buf[i] = (char) jc[i];
Tlk->buf[i] = 0;
return Tlk->buf;
}
static __inline__ void* getBuffer ( Toolkit* Tlk, unsigned int nBytes ) {
if ( nBytes > Tlk->nBuf ) {
if ( Tlk->buf )
AWT_FREE( Tlk->buf);
Tlk->buf = (char *) AWT_MALLOC( nBytes);
Tlk->nBuf = nBytes;
}
return Tlk->buf;
}
/*****************************************************************************************
* color functions & defines
*/
/*
* These are our directly supported visuals / color modes. Note that there is
* no more 1-1 correspondence to X visuals, since we do a categorisation with
* respect to our internal RGB <-> pixel conversion. All visuals not listed
* explicitly are handled via the generic XAllocColor/XQueryColor (which might
* slow down images considerably)
*
* NOTE: these values have to be != 0, since '0' is used to trigger color init
*/
#define CM_PSEUDO_256 1 /* PseudoColor visual */
#define CM_TRUE 2 /* general TrueColor visual */
#define CM_TRUE_888 3 /* special 8-8-8 bit TrueColor visual */
#define CM_DIRECT 4
#define CM_GENERIC 5 /* grays, DirectColor (packed) etc. */
void initColorMapping ( JNIEnv* env, Toolkit* Tlk);
AWT_EXPORT jlong Java_java_awt_Toolkit_clrBright ( JNIEnv* env, jclass clazz, jint rgb );
AWT_EXPORT jlong Java_java_awt_Toolkit_clrDark ( JNIEnv* env, jclass clazz, jint rgb );
#define JRGB(_r,_g,_b) (_r<<16 | _g<<8 | _b)
#define JRED(_rgb) ((_rgb & 0xff0000) >> 16)
#define JGREEN(_rgb) ((_rgb & 0x00ff00) >> 8)
#define JBLUE(_rgb) (_rgb & 0x0000ff)
#define D8 36.43 /* 255 / 7 */
#define D16 18.21
#define JI8(_v) (int)((_v + D16) / D8)
#define XI8(_v) (int)(((_v>>8) + D16) / D8)
#define ROUND_SHORT2CHAR(_n) \
((unsigned short)_n >= 0xff70 ) ? 0xff : (unsigned char)(((unsigned short)_n + 0x80) >> 8)
/* shift ops with negative values have undefined results */
#define SIGNED_RSHIFT(_var,_val,_shift) \
_var = _val; \
if ( _shift > 0 ) _var >>= _shift; \
else _var <<= -_shift;
#define SIGNED_LSHIFT(_var,_val,_shift) \
_var = _val; \
if ( _shift > 0 ) _var <<= _shift; \
else _var >>= -_shift;
static __inline__ jint
pixelValue ( Toolkit* Tlk, jint rgb )
{
int r,g,b;
// XColor xclr;
switch ( Tlk->colorMode ) {
case CM_PSEUDO_256:
UNIMPLEMENTED((
return Tlk->pclr->pix [JI8(JRED(rgb))] [JI8(JGREEN(rgb))] [JI8(JBLUE(rgb))];
));
case CM_TRUE:
UNIMPLEMENTED((
SIGNED_RSHIFT( b, (rgb & Tlk->tclr->blueMask), Tlk->tclr->blueShift);
SIGNED_RSHIFT( g, (rgb & Tlk->tclr->greenMask), Tlk->tclr->greenShift);
SIGNED_RSHIFT( r, (rgb & Tlk->tclr->redMask), Tlk->tclr->redShift);
));
return ( b | g | r );
case CM_TRUE_888:
return (rgb & 0xffffff);
case CM_DIRECT:
UNIMPLEMENTED((
return (((jint)Tlk->dclr->redPix[JRED(rgb)] << Tlk->dclr->redShift) |
((jint)Tlk->dclr->greenPix[JGREEN(rgb)] << Tlk->dclr->greenShift) |
((jint)Tlk->dclr->bluePix[JBLUE(rgb)] << Tlk->dclr->blueShift));
));
default:
#if 0 // !!! SHOULD USE A NON-GENERIC VALID COLOR MODE
/*
* this is a generic fallback for "exotic" visuals and might be *awefully*
* slow (esp. for images) because XAllocColor is a roundtrip
*/
xclr.red = (rgb & 0xff0000) >> 8;
xclr.green = (rgb & 0xff00);
xclr.blue = (rgb & 0xff) << 8;
xclr.flags = DoRed | DoGreen | DoBlue;
XAllocColor( X->dsp, DefaultColormapOfScreen( DefaultScreenOfDisplay( X->dsp)), &xclr);
return xclr.pixel;
#endif
return (rgb & 0xffffff);
}
}
static __inline__ void
rgbValues ( Toolkit* Tlk, unsigned long pixel, int* r, int* g, int* b )
{
/*
Visual *v;
XColor xclr;
*/
switch ( Tlk->colorMode ) {
case CM_PSEUDO_256:
UNIMPLEMENTED((
*r = Tlk->pclr->rgb[(unsigned char)pixel].r;
*g = Tlk->pclr->rgb[(unsigned char)pixel].g;
*b = Tlk->pclr->rgb[(unsigned char)pixel].b;
));
break;
case CM_TRUE:
UNIMPLEMENTED((
v = DefaultVisual( X->dsp, DefaultScreen( X->dsp));
SIGNED_LSHIFT( *r, (pixel & v->red_mask), Tlk->tclr->redShift);
SIGNED_LSHIFT( *g, (pixel & v->green_mask), Tlk->tclr->greenShift);
SIGNED_LSHIFT( *b, (pixel & v->blue_mask), Tlk->tclr->blueShift);
*r >>= 16;
*g >>= 8;
));
break;
/*
*r = ((pixel & v->red_mask) << Tlk->tclr->redShift) >> 16;
*g = ((pixel & v->green_mask) << Tlk->tclr->greenShift) >> 8;
*b = ((pixel & v->blue_mask) << Tlk->tclr->blueShift);
break;
*/
case CM_TRUE_888:
*r = JRED( pixel);
*g = JGREEN( pixel);
*b = JBLUE( pixel);
break;
case CM_DIRECT:
UNIMPLEMENTED((
v = DefaultVisual( X->dsp, DefaultScreen( X->dsp));
*r = Tlk->dclr->red[ ((pixel & v->red_mask) >> Tlk->dclr->redShift) ];
*g = Tlk->dclr->green[ ((pixel & v->green_mask) >> Tlk->dclr->greenShift) ];
*b = Tlk->dclr->blue[ ((pixel & v->blue_mask) >> Tlk->dclr->blueShift) ];
));
break;
default:
UNIMPLEMENTED((
/*
* this is a generic fallback for "exotic" visuals and might be *awefully*
* slow (esp. for images) because XAllocColor is a roundtrip
*/
xclr.pixel = pixel;
XQueryColor( X->dsp, DefaultColormapOfScreen( DefaultScreenOfDisplay( X->dsp)), &xclr);
*r = xclr.red >> 8;
*g = xclr.green >> 8;
*b = xclr.blue >> 8;
));
break;
}
}
/* Java is aarrggbb, BeOS little endian is aabbggrr */
inline
rgb_color NATIVERGB(jint jCol)
{
jCol = JBLUE(jCol)<<16 | JGREEN(jCol)<<8 | JRED(jCol);
return *(rgb_color *)&jCol;
}
/*****************************************************************************************
* image functions
*/
Image* createImage ( int width, int height);
void createXMaskImage ( Toolkit* Tlk, Image* img );
void createXImage ( Toolkit* Tlk, Image* img );
void createAlphaImage ( Toolkit* Tlk, Image* img );
int needsFullAlpha ( Toolkit* Tlk, Image *img, double threshold );
void initScaledImage ( Toolkit* Tlk, Image *tgt, Image *src,
int dx0, int dy0, int dx1, int dy1,
int sx0, int sy0, int sx1, int sy1 );
AWT_EXPORT void Java_java_awt_Toolkit_imgFreeImage( JNIEnv* env, jclass clazz, Image * img);
static __inline__ void
PutAlpha ( AlphaImage* img, int col, int row, unsigned char alpha )
{
img->buf[ row*img->width + col ] = alpha;
}
static __inline__ int
GetAlpha ( AlphaImage* img, int col, int row )
{
return img->buf[ row*img->width + col];
}
/*****************************************************************************************
* clipboard functions
*/
jobject selectionClear ( JNIEnv* env, Toolkit* Tlk );
jobject selectionRequest ( JNIEnv* env, Toolkit* Tlk );
/*****************************************************************************************
* async (multithreaded) macros
* this can be used to solve the problem of deferred drawing requests, not being
* flushed because of infrequent (non-polled) XNextEvent calls.
* (for now, we go with a backgound flush thread)
*/
#define XFLUSH(_X,_force)
/*****************************************************************************************
* file io wrapper macros (for image production)
*/
#define AWT_OPEN(_file) open(_file, 0)
#define AWT_REWIND(_fd) lseek(_fd, 0, SEEK_SET)
#define AWT_SETPOS(_fd,_off) lseek(_fd, _off, SEEK_CUR)
#define AWT_READ(_fd,_buf,_count) read(_fd,_buf,_count)
#define AWT_CLOSE(_fd) close(_fd)
/*****************************************************************************************
* macros to manage the source table (conversion of X windows to/from indices, which
* are consistent with the AWTEvent.sources array)
*/
#define WND_FRAME 0x01
#define WND_WINDOW 0x02
#define WND_DIALOG 0x04
#define WND_MAPPED 0x08
#define WND_DESTROYED 0x10
static __inline__ int getFreeSourceIdx ( Toolkit* Tlk, Window wnd ) {
register unsigned int i, n;
/*
* we don't use a double hashing here because collisions are very unlikely
* (window IDs usually already are hashed, so it does not make sense to
* hash them again - we just could make it worse
*/
for ( i = (unsigned long)wnd, n=0; n < Tlk->nWindows; i++, n++ ) {
i %= Tlk->nWindows;
// !!! if ( (int)(Tlk->windows[i].w) <= 0 ) {
if ( (int)(Tlk->windows[i]) == -1 ) {
Tlk->srcIdx = i;
Tlk->lastWindow = wnd;
return i;
}
}
return -1;
}
static __inline__ int getSourceIdx ( Toolkit* Tlk, Window w )
{
unsigned int n;
register unsigned int i;
if ( w == Tlk->lastWindow ){
return Tlk->srcIdx;
}
else {
for ( i = (unsigned long) w, n=0; n < Tlk->nWindows; i++, n++ ) {
i %= Tlk->nWindows;
// !!! if ( Tlk->windows[i].w == w ){
if ( Tlk->windows[i] == w ){
Tlk->srcIdx = i;
Tlk->lastWindow = w;
return Tlk->srcIdx;
}
else
// !!! if ( Tlk->windows[i].w == 0 ){
if ( Tlk->windows[i] == (void *)-1 ){
return -1;
}
}
return -1;
}
}
static __inline__ int checkSource ( Toolkit* Tlk, int idx )
{
// !!! return ( (idx >= 0) && (idx < Tlk->nWindows) && (Tlk->windows[idx].w) );
return ( (idx >= 0) && (idx < (int)Tlk->nWindows) && (Tlk->windows[idx] != (void *)-1) );
}
/*****************************************************************************************
*/
#define USE_POLLING_AWT 1
#endif /* __toolkit_h */