summaryrefslogtreecommitdiff
path: root/native
diff options
context:
space:
mode:
authorAndrew John Hughes <gnu_andrew@member.fsf.org>2006-06-11 18:23:15 +0000
committerAndrew John Hughes <gnu_andrew@member.fsf.org>2006-06-11 18:23:15 +0000
commit35d18ccf396a6cfdcbe5bbdf38df7d01852250bc (patch)
tree562e6d161a8957db8a46900b46f661c5e52e1a34 /native
parentc5877847749d21bdf84e33929ffa52a56e5c6ca0 (diff)
downloadclasspath-35d18ccf396a6cfdcbe5bbdf38df7d01852250bc.tar.gz
2006-06-11 Andrew John Hughes <gnu_andrew@member.fsf.org>
* Merge of HEAD-->generics between 2006/05/29 and 2006/06/11.
Diffstat (limited to 'native')
-rw-r--r--native/fdlibm/dtoa.c17
-rw-r--r--native/fdlibm/mprec.c275
-rw-r--r--native/fdlibm/mprec.h8
-rw-r--r--native/jawt/Makefile.am2
-rw-r--r--native/jni/classpath/jcl.h6
-rw-r--r--native/jni/gtk-peer/Makefile.am14
-rw-r--r--native/jni/gtk-peer/cairographics2d.h116
-rw-r--r--native/jni/gtk-peer/gdkdisplay.h67
-rw-r--r--native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoGraphics2D.c706
-rw-r--r--native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoSurface.c302
-rw-r--r--native/jni/gtk-peer/gnu_java_awt_peer_gtk_ComponentGraphics.c311
-rw-r--r--native/jni/gtk-peer/gnu_java_awt_peer_gtk_ComponentGraphicsCopy.c132
-rw-r--r--native/jni/gtk-peer/gnu_java_awt_peer_gtk_FreetypeGlyphVector.c348
-rw-r--r--native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkFontPeer.c132
-rw-r--r--native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c1898
-rw-r--r--native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphicsEnvironment.c142
-rw-r--r--native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkScreenGraphicsDevice.c354
-rw-r--r--native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkTextLayout.c153
-rw-r--r--native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkClipboard.c9
-rw-r--r--native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkFramePeer.c5
-rw-r--r--native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkImage.c332
-rw-r--r--native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkVolatileImage.c195
-rw-r--r--native/jni/gtk-peer/gtkpeer.h55
-rw-r--r--native/jni/java-io/java_io_VMFile.c236
-rw-r--r--native/jni/midi-dssi/dssi_data.h7
-rw-r--r--native/jni/qt-peer/qtmenupeer.cpp47
-rw-r--r--native/plugin/Makefile.am14
-rw-r--r--native/plugin/gcjwebplugin.cc575
28 files changed, 3820 insertions, 2638 deletions
diff --git a/native/fdlibm/dtoa.c b/native/fdlibm/dtoa.c
index 6d5ad3b42..5fb6aae2c 100644
--- a/native/fdlibm/dtoa.c
+++ b/native/fdlibm/dtoa.c
@@ -2,7 +2,7 @@
*
* The author of this software is David M. Gay.
*
- * Copyright (c) 1991 by AT&T.
+ * Copyright (c) 1991, 2006 by AT&T.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose without fee is hereby granted, provided that this entire notice
@@ -897,10 +897,23 @@ _DEFUN (_dtoa,
{
struct _Jv_reent reent;
char *p;
+ int i;
+
memset (&reent, 0, sizeof reent);
p = _dtoa_r (&reent, _d, mode, ndigits, decpt, sign, rve, float_type);
strcpy (buf, p);
- return;
+ for (i = 0; i < reent._result_k; ++i)
+ {
+ struct _Jv_Bigint *l = reent._freelist[i];
+ while (l)
+ {
+ struct _Jv_Bigint *next = l->_next;
+ free (l);
+ l = next;
+ }
+ }
+ if (reent._freelist)
+ free (reent._freelist);
}
diff --git a/native/fdlibm/mprec.c b/native/fdlibm/mprec.c
index 0badf60c4..e53722f7b 100644
--- a/native/fdlibm/mprec.c
+++ b/native/fdlibm/mprec.c
@@ -80,72 +80,112 @@
* down depends on the machine and the number being converted.
*/
+/*#include <_ansi.h>*/
#include <assert.h>
#include <stdlib.h>
#include <string.h>
+/* #include <reent.h> */
#include "mprec.h"
/* reent.c knows this value */
-#define _Kmax 15
-#include <stdio.h>
+/* #define _Kmax 15 */
-_Jv_Bigint *
-_DEFUN (Balloc, (ptr, k), struct _Jv_reent *ptr _AND int k)
-{
- _Jv_Bigint *rv = NULL;
+#define _reent _Jv_reent
+#define _Bigint _Jv_Bigint
- int i = 0;
- int j = 1;
+#define _REENT_CHECK_MP(x)
+#define _REENT_MP_FREELIST(x) ((x)->_freelist)
+#define _REENT_MP_P5S(x) ((x)->_p5s)
- /* FIXME - assert disabled because of PR classpath/23863
- * assert ((1 << k) < MAX_BIGNUM_WDS);
- */
+typedef unsigned long __ULong;
+typedef long __Long;
- while ((ptr->_allocation_map & j) && i < MAX_BIGNUMS)
- i++, j <<= 1;
+static void *
+_calloc_r (void *ignore, size_t x1, size_t x2)
+{
+ char *result = (char *) malloc (x1 * x2);
+ memset (result, 0, x1 * x2);
+ return result;
+}
- assert (i < MAX_BIGNUMS);
+_Bigint *
+_DEFUN (Balloc, (ptr, k), struct _reent *ptr _AND int k)
+{
+ int x;
+ _Bigint *rv ;
+ int new_k = k + 1;
+
+ _REENT_CHECK_MP(ptr);
+ if (_REENT_MP_FREELIST(ptr) == NULL)
+ {
+ /* Allocate a list of pointers to the mprec objects */
+ _REENT_MP_FREELIST(ptr) = (struct _Bigint **) _calloc_r (ptr,
+ sizeof (struct _Bigint *),
+ new_k);
+ if (_REENT_MP_FREELIST(ptr) == NULL)
+ {
+ return NULL;
+ }
+ ptr->_max_k = new_k;
+ }
+ else if (new_k > ptr->_max_k)
+ {
+ struct _Bigint **new_list
+ = (struct _Bigint **) realloc (ptr->_freelist,
+ new_k * sizeof (struct _Bigint *));
+ memset (&new_list[ptr->_max_k], 0,
+ (new_k - ptr->_max_k) * sizeof (struct _Bigint *));
+ ptr->_freelist = new_list;
+ ptr->_max_k = new_k;
- if (i >= MAX_BIGNUMS)
- return NULL;
+ }
- ptr->_allocation_map |= j;
- rv = &ptr->_freelist[i];
-
- rv->_k = k;
- rv->_maxwds = 32;
+ assert (k <= ptr->_max_k);
+ if ((rv = _REENT_MP_FREELIST(ptr)[k]) != 0)
+ {
+ _REENT_MP_FREELIST(ptr)[k] = rv->_next;
+ }
+ else
+ {
+ x = 1 << k;
+ /* Allocate an mprec Bigint and stick in in the freelist */
+ rv = (_Bigint *) _calloc_r (ptr,
+ 1,
+ sizeof (_Bigint) +
+ (x-1) * sizeof(rv->_x));
+ if (rv == NULL) return NULL;
+ rv->_k = k;
+ rv->_maxwds = x;
+ }
+ rv->_sign = rv->_wds = 0;
return rv;
}
-
void
-_DEFUN (Bfree, (ptr, v), struct _Jv_reent *ptr _AND _Jv_Bigint * v)
+_DEFUN (Bfree, (ptr, v), struct _reent *ptr _AND _Bigint * v)
{
- long i;
-
- i = v - ptr->_freelist;
-
- assert (i >= 0 && i < MAX_BIGNUMS);
-
- if (i >= 0 && i < MAX_BIGNUMS)
- ptr->_allocation_map &= ~ (1 << i);
+ _REENT_CHECK_MP(ptr);
+ if (v)
+ {
+ v->_next = _REENT_MP_FREELIST(ptr)[v->_k];
+ _REENT_MP_FREELIST(ptr)[v->_k] = v;
+ }
}
-
-_Jv_Bigint *
+_Bigint *
_DEFUN (multadd, (ptr, b, m, a),
- struct _Jv_reent *ptr _AND
- _Jv_Bigint * b _AND
+ struct _reent *ptr _AND
+ _Bigint * b _AND
int m _AND
int a)
{
int i, wds;
- unsigned long *x, y;
+ __ULong *x, y;
#ifdef Pack_32
- unsigned long xi, z;
+ __ULong xi, z;
#endif
- _Jv_Bigint *b1;
+ _Bigint *b1;
wds = b->_wds;
x = b->_x;
@@ -180,17 +220,17 @@ _DEFUN (multadd, (ptr, b, m, a),
return b;
}
-_Jv_Bigint *
+_Bigint *
_DEFUN (s2b, (ptr, s, nd0, nd, y9),
- struct _Jv_reent * ptr _AND
+ struct _reent * ptr _AND
_CONST char *s _AND
int nd0 _AND
int nd _AND
- unsigned long y9)
+ __ULong y9)
{
- _Jv_Bigint *b;
+ _Bigint *b;
int i, k;
- long x, y;
+ __Long x, y;
x = (nd + 8) / 9;
for (k = 0, y = 1; x > y; y <<= 1, k++);
@@ -222,7 +262,7 @@ _DEFUN (s2b, (ptr, s, nd0, nd, y9),
int
_DEFUN (hi0bits,
- (x), register unsigned long x)
+ (x), register __ULong x)
{
register int k = 0;
@@ -256,10 +296,10 @@ _DEFUN (hi0bits,
}
int
-_DEFUN (lo0bits, (y), unsigned long *y)
+_DEFUN (lo0bits, (y), __ULong *y)
{
register int k;
- register unsigned long x = *y;
+ register __ULong x = *y;
if (x & 7)
{
@@ -298,17 +338,17 @@ _DEFUN (lo0bits, (y), unsigned long *y)
{
k++;
x >>= 1;
- if (!(x & 1))
+ if (!x & 1)
return 32;
}
*y = x;
return k;
}
-_Jv_Bigint *
-_DEFUN (i2b, (ptr, i), struct _Jv_reent * ptr _AND int i)
+_Bigint *
+_DEFUN (i2b, (ptr, i), struct _reent * ptr _AND int i)
{
- _Jv_Bigint *b;
+ _Bigint *b;
b = Balloc (ptr, 1);
b->_x[0] = i;
@@ -316,15 +356,15 @@ _DEFUN (i2b, (ptr, i), struct _Jv_reent * ptr _AND int i)
return b;
}
-_Jv_Bigint *
-_DEFUN (mult, (ptr, a, b), struct _Jv_reent * ptr _AND _Jv_Bigint * a _AND _Jv_Bigint * b)
+_Bigint *
+_DEFUN (mult, (ptr, a, b), struct _reent * ptr _AND _Bigint * a _AND _Bigint * b)
{
- _Jv_Bigint *c;
+ _Bigint *c;
int k, wa, wb, wc;
- unsigned long carry, y, z;
- unsigned long *x, *xa, *xae, *xb, *xbe, *xc, *xc0;
+ __ULong carry, y, z;
+ __ULong *x, *xa, *xae, *xb, *xbe, *xc, *xc0;
#ifdef Pack_32
- unsigned long z2;
+ __ULong z2;
#endif
if (a->_wds < b->_wds)
@@ -350,7 +390,7 @@ _DEFUN (mult, (ptr, a, b), struct _Jv_reent * ptr _AND _Jv_Bigint * a _AND _Jv_B
#ifdef Pack_32
for (; xb < xbe; xb++, xc0++)
{
- if ((y = *xb & 0xffff))
+ if ((y = *xb & 0xffff) != 0)
{
x = xa;
xc = xc0;
@@ -366,7 +406,7 @@ _DEFUN (mult, (ptr, a, b), struct _Jv_reent * ptr _AND _Jv_Bigint * a _AND _Jv_B
while (x < xae);
*xc = carry;
}
- if ((y = *xb >> 16))
+ if ((y = *xb >> 16) != 0)
{
x = xa;
xc = xc0;
@@ -387,7 +427,7 @@ _DEFUN (mult, (ptr, a, b), struct _Jv_reent * ptr _AND _Jv_Bigint * a _AND _Jv_B
#else
for (; xb < xbe; xc0++)
{
- if ((y = *xb++))
+ if (y = *xb++)
{
x = xa;
xc = xc0;
@@ -408,23 +448,24 @@ _DEFUN (mult, (ptr, a, b), struct _Jv_reent * ptr _AND _Jv_Bigint * a _AND _Jv_B
return c;
}
-_Jv_Bigint *
+_Bigint *
_DEFUN (pow5mult,
- (ptr, b, k), struct _Jv_reent * ptr _AND _Jv_Bigint * b _AND int k)
+ (ptr, b, k), struct _reent * ptr _AND _Bigint * b _AND int k)
{
- _Jv_Bigint *b1, *p5, *p51;
+ _Bigint *b1, *p5, *p51;
int i;
static _CONST int p05[3] = {5, 25, 125};
- if ((i = k & 3))
+ if ((i = k & 3) != 0)
b = multadd (ptr, b, p05[i - 1], 0);
if (!(k >>= 2))
return b;
- if (!(p5 = ptr->_p5s))
+ _REENT_CHECK_MP(ptr);
+ if (!(p5 = _REENT_MP_P5S(ptr)))
{
/* first time */
- p5 = ptr->_p5s = i2b (ptr, 625);
+ p5 = _REENT_MP_P5S(ptr) = i2b (ptr, 625);
p5->_next = 0;
}
for (;;)
@@ -447,12 +488,12 @@ _DEFUN (pow5mult,
return b;
}
-_Jv_Bigint *
-_DEFUN (lshift, (ptr, b, k), struct _Jv_reent * ptr _AND _Jv_Bigint * b _AND int k)
+_Bigint *
+_DEFUN (lshift, (ptr, b, k), struct _reent * ptr _AND _Bigint * b _AND int k)
{
int i, k1, n, n1;
- _Jv_Bigint *b1;
- unsigned long *x, *x1, *xe, z;
+ _Bigint *b1;
+ __ULong *x, *x1, *xe, z;
#ifdef Pack_32
n = k >> 5;
@@ -480,7 +521,7 @@ _DEFUN (lshift, (ptr, b, k), struct _Jv_reent * ptr _AND _Jv_Bigint * b _AND int
z = *x++ >> k1;
}
while (x < xe);
- if ((*x1 = z))
+ if ((*x1 = z) != 0)
++n1;
}
#else
@@ -490,11 +531,11 @@ _DEFUN (lshift, (ptr, b, k), struct _Jv_reent * ptr _AND _Jv_Bigint * b _AND int
z = 0;
do
{
- *x1++ = (*x << k & 0xffff) | z;
+ *x1++ = *x << k & 0xffff | z;
z = *x++ >> k1;
}
while (x < xe);
- if ((*x1 = z))
+ if (*x1 = z)
++n1;
}
#endif
@@ -508,9 +549,9 @@ _DEFUN (lshift, (ptr, b, k), struct _Jv_reent * ptr _AND _Jv_Bigint * b _AND int
}
int
-_DEFUN (cmp, (a, b), _Jv_Bigint * a _AND _Jv_Bigint * b)
+_DEFUN (cmp, (a, b), _Bigint * a _AND _Bigint * b)
{
- unsigned long *xa, *xa0, *xb, *xb0;
+ __ULong *xa, *xa0, *xb, *xb0;
int i, j;
i = a->_wds;
@@ -537,16 +578,16 @@ _DEFUN (cmp, (a, b), _Jv_Bigint * a _AND _Jv_Bigint * b)
return 0;
}
-_Jv_Bigint *
-_DEFUN (diff, (ptr, a, b), struct _Jv_reent * ptr _AND
- _Jv_Bigint * a _AND _Jv_Bigint * b)
+_Bigint *
+_DEFUN (diff, (ptr, a, b), struct _reent * ptr _AND
+ _Bigint * a _AND _Bigint * b)
{
- _Jv_Bigint *c;
+ _Bigint *c;
int i, wa, wb;
- long borrow, y; /* We need signed shifts here. */
- unsigned long *xa, *xae, *xb, *xbe, *xc;
+ __Long borrow, y; /* We need signed shifts here. */
+ __ULong *xa, *xae, *xb, *xbe, *xc;
#ifdef Pack_32
- long z;
+ __Long z;
#endif
i = cmp (a, b);
@@ -625,7 +666,7 @@ double
_DEFUN (ulp, (_x), double _x)
{
union double_union x, a;
- register long L;
+ register __Long L;
x.d = _x;
@@ -659,7 +700,7 @@ _DEFUN (ulp, (_x), double _x)
word0 (a) = 0;
L -= Exp_shift;
#ifndef _DOUBLE_IS_32BITS
- word1 (a) = L >= 31 ? 1 : 1 << (31 - L);
+ word1 (a) = L >= 31 ? 1 : 1 << (31 - L);
#endif
}
}
@@ -669,13 +710,13 @@ _DEFUN (ulp, (_x), double _x)
double
_DEFUN (b2d, (a, e),
- _Jv_Bigint * a _AND int *e)
+ _Bigint * a _AND int *e)
{
- unsigned long *xa, *xa0, w, y, z;
+ __ULong *xa, *xa0, w, y, z;
int k;
union double_union d;
#ifdef VAX
- unsigned long d0, d1;
+ __ULong d0, d1;
#else
#define d0 word0(d)
#define d1 word1(d)
@@ -696,7 +737,7 @@ _DEFUN (b2d, (a, e),
d0 = Exp_1 | y >> (Ebits - k);
w = xa > xa0 ? *--xa : 0;
#ifndef _DOUBLE_IS_32BITS
- d1 = y << (32 - Ebits + k) | w >> (Ebits - k);
+ d1 = y << ((32 - Ebits) + k) | w >> (Ebits - k);
#endif
goto ret_d;
}
@@ -720,18 +761,18 @@ _DEFUN (b2d, (a, e),
if (k < Ebits + 16)
{
z = xa > xa0 ? *--xa : 0;
- d0 = Exp_1 | y << (k - Ebits) | z >> (Ebits + 16 - k);
+ d0 = Exp_1 | y << k - Ebits | z >> Ebits + 16 - k;
w = xa > xa0 ? *--xa : 0;
y = xa > xa0 ? *--xa : 0;
- d1 = z << (k + 16 - Ebits) | w << (k - Ebits) | y >> (16 + Ebits - k);
+ d1 = z << k + 16 - Ebits | w << k - Ebits | y >> 16 + Ebits - k;
goto ret_d;
}
z = xa > xa0 ? *--xa : 0;
w = xa > xa0 ? *--xa : 0;
k -= Ebits + 16;
- d0 = Exp_1 | y << (k + 16) | z << k | w >> (16 - k);
+ d0 = Exp_1 | y << k + 16 | z << k | w >> 16 - k;
y = xa > xa0 ? *--xa : 0;
- d1 = w << (k + 16) | y << k;
+ d1 = w << k + 16 | y << k;
#endif
ret_d:
#ifdef VAX
@@ -744,22 +785,24 @@ ret_d:
return d.d;
}
-_Jv_Bigint *
+_Bigint *
_DEFUN (d2b,
(ptr, _d, e, bits),
- struct _Jv_reent * ptr _AND
+ struct _reent * ptr _AND
double _d _AND
int *e _AND
int *bits)
{
union double_union d;
- _Jv_Bigint *b;
+ _Bigint *b;
int de, i, k;
- unsigned long *x, y, z;
+ __ULong *x, y, z;
#ifdef VAX
- unsigned long d0, d1;
+ __ULong d0, d1;
+#endif
d.d = _d;
+#ifdef VAX
d0 = word0 (d) >> 16 | word0 (d) << 16;
d1 = word1 (d) >> 16 | word1 (d) << 16;
#else
@@ -783,16 +826,18 @@ _DEFUN (d2b,
z |= Exp_msk11;
#endif
#else
- if ((de = (int) (d0 >> Exp_shift)))
+ if ((de = (int) (d0 >> Exp_shift)) != 0)
z |= Exp_msk1;
#endif
#ifdef Pack_32
#ifndef _DOUBLE_IS_32BITS
- if ((y = d1))
+ if (d1)
{
- if ((k = lo0bits (&y)))
+ y = d1;
+ k = lo0bits (&y);
+ if (k)
{
- x[0] = y | z << (32 - k);
+ x[0] = y | z << (32 - k);
z >>= k;
}
else
@@ -814,22 +859,24 @@ _DEFUN (d2b,
#endif
}
#else
- if ((y = d1))
+ if (d1)
{
- if ((k = lo0bits (&y)))
+ y = d1;
+ k = lo0bits (&y);
+ if (k)
if (k >= 16)
{
- x[0] = y | (z << (32 - k) & 0xffff);
- x[1] = z >> (k - 16) & 0xffff;
+ x[0] = y | z << 32 - k & 0xffff;
+ x[1] = z >> k - 16 & 0xffff;
x[2] = z >> k;
i = 2;
}
else
{
x[0] = y & 0xffff;
- x[1] = (y >> 16 | z << (16 - k)) & 0xffff;
+ x[1] = y >> 16 | z << 16 - k & 0xffff;
x[2] = z >> k & 0xffff;
- x[3] = z >> (k + 16);
+ x[3] = z >> k + 16;
i = 3;
}
else
@@ -894,7 +941,7 @@ _DEFUN (d2b,
#undef d1
double
-_DEFUN (ratio, (a, b), _Jv_Bigint * a _AND _Jv_Bigint * b)
+_DEFUN (ratio, (a, b), _Bigint * a _AND _Bigint * b)
{
union double_union da, db;
@@ -958,3 +1005,17 @@ _CONST double tinytens[] =
#endif
+double
+_DEFUN (_mprec_log10, (dig),
+ int dig)
+{
+ double v = 1.0;
+ if (dig < 24)
+ return tens[dig];
+ while (dig > 0)
+ {
+ v *= 10;
+ dig--;
+ }
+ return v;
+}
diff --git a/native/fdlibm/mprec.h b/native/fdlibm/mprec.h
index cd8f928a8..7c7471bc8 100644
--- a/native/fdlibm/mprec.h
+++ b/native/fdlibm/mprec.h
@@ -282,7 +282,7 @@ struct _Jv_Bigint
{
struct _Jv_Bigint *_next;
int _k, _maxwds, _sign, _wds;
- unsigned long _x[MAX_BIGNUM_WDS];
+ unsigned long _x[1];
};
@@ -310,10 +310,8 @@ struct _Jv_reent
int _result_k;
struct _Jv_Bigint *_p5s;
- struct _Jv_Bigint _freelist[MAX_BIGNUMS];
- int _allocation_map;
-
- int num;
+ struct _Jv_Bigint **_freelist;
+ int _max_k;
};
diff --git a/native/jawt/Makefile.am b/native/jawt/Makefile.am
index 30e5a345b..01abf3bb9 100644
--- a/native/jawt/Makefile.am
+++ b/native/jawt/Makefile.am
@@ -3,7 +3,7 @@ nativeexeclib_LTLIBRARIES = libjawt.la
libjawt_la_SOURCES = jawt.c
libjawt_la_LIBADD = $(top_builddir)/native/jni/gtk-peer/libgtkpeer.la
-AM_LDFLAGS = @CLASSPATH_MODULE@ @GTK_LIBS@ @PANGOFT2_LIBS@ @X_LIBS@ -lXtst
+AM_LDFLAGS = @CLASSPATH_MODULE@ @GTK_LIBS@ @PANGOFT2_LIBS@ @X_LIBS@ @XTEST_LIBS@
AM_CPPFLAGS = @CLASSPATH_INCLUDES@
# Just the WARNING_CFLAGS. We cannot use the strict flags since the gtk
diff --git a/native/jni/classpath/jcl.h b/native/jni/classpath/jcl.h
index 514b78262..d358aeb9c 100644
--- a/native/jni/classpath/jcl.h
+++ b/native/jni/classpath/jcl.h
@@ -1,5 +1,5 @@
/* jcl.h
- Copyright (C) 1998 Free Software Foundation, Inc.
+ Copyright (C) 1998, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -50,6 +50,10 @@ typedef jlong jpointer;
#error "Unknown pointer size"
#endif
+/* Helper macros for going between pointers and jlongs. */
+#define JLONG_TO_PTR(T,P) ((T *)(long)P)
+#define PTR_TO_JLONG(P) ((jlong)(long)P)
+
JNIEXPORT jclass JNICALL JCL_FindClass (JNIEnv * env, const char *className);
JNIEXPORT void JNICALL JCL_ThrowException (JNIEnv * env,
const char *className,
diff --git a/native/jni/gtk-peer/Makefile.am b/native/jni/gtk-peer/Makefile.am
index 4b113c978..8a39f34fe 100644
--- a/native/jni/gtk-peer/Makefile.am
+++ b/native/jni/gtk-peer/Makefile.am
@@ -1,12 +1,17 @@
nativeexeclib_LTLIBRARIES = libgtkpeer.la
# GTK JNI sources.
-libgtkpeer_la_SOURCES = gnu_java_awt_peer_gtk_GThreadNativeMethodRunner.c \
+libgtkpeer_la_SOURCES = gnu_java_awt_peer_gtk_CairoSurface.c \
+ gnu_java_awt_peer_gtk_CairoGraphics2D.c \
+ gnu_java_awt_peer_gtk_ComponentGraphics.c \
+ gnu_java_awt_peer_gtk_ComponentGraphicsCopy.c \
+ gnu_java_awt_peer_gtk_FreetypeGlyphVector.c \
+ gnu_java_awt_peer_gtk_GThreadNativeMethodRunner.c \
gnu_java_awt_peer_gtk_GdkFontPeer.c \
- gnu_java_awt_peer_gtk_GdkGraphics2D.c \
gnu_java_awt_peer_gtk_GdkGraphicsEnvironment.c \
gnu_java_awt_peer_gtk_GdkPixbufDecoder.c \
gnu_java_awt_peer_gtk_GdkRobotPeer.c \
+ gnu_java_awt_peer_gtk_GdkScreenGraphicsDevice.c \
gnu_java_awt_peer_gtk_GdkTextLayout.c \
gnu_java_awt_peer_gtk_GtkButtonPeer.c \
gnu_java_awt_peer_gtk_GtkCanvasPeer.c \
@@ -36,7 +41,10 @@ libgtkpeer_la_SOURCES = gnu_java_awt_peer_gtk_GThreadNativeMethodRunner.c \
gnu_java_awt_peer_gtk_GtkTextFieldPeer.c \
gnu_java_awt_peer_gtk_GtkToolkit.c \
gnu_java_awt_peer_gtk_GtkWindowPeer.c \
+ gnu_java_awt_peer_gtk_GtkVolatileImage.c \
+ cairographics2d.h \
gthread-jni.c \
+ gdkdisplay.h \
gdkfont.h \
gthread-jni.h \
gtk_jawt.c \
@@ -46,7 +54,7 @@ libgtkpeer_la_LIBADD = $(top_builddir)/native/jni/classpath/native_state.lo \
$(top_builddir)/native/jni/classpath/jcl.lo
AM_LDFLAGS = @CLASSPATH_MODULE@ @GTK_LIBS@ @FREETYPE2_LIBS@ \
- @PANGOFT2_LIBS@ @X_PRE_LIBS@ @X_LIBS@ @X_EXTRA_LIBS@ -lX11 -lXtst
+ @PANGOFT2_LIBS@ @X_PRE_LIBS@ @X_LIBS@ @X_EXTRA_LIBS@ @XTEST_LIBS@
AM_CPPFLAGS = @CLASSPATH_INCLUDES@
# Just the WARNING_CFLAGS. We cannot use the strict flags since the gtk
diff --git a/native/jni/gtk-peer/cairographics2d.h b/native/jni/gtk-peer/cairographics2d.h
new file mode 100644
index 000000000..675bc0b17
--- /dev/null
+++ b/native/jni/gtk-peer/cairographics2d.h
@@ -0,0 +1,116 @@
+/* cairographics2d.h --
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+#ifndef CAIROGRAPHICS2D_H
+#define CAIROGRAPHICS2D_H
+
+
+#include <cairo.h>
+#include <gtk/gtk.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <config.h>
+#include "native_state.h"
+#include <gdk-pixbuf/gdk-pixbuf.h>
+
+#include <jni.h>
+
+/*
+ * These public final constants are part of the java2d public API, so we
+ * write them explicitly here to save fetching them from the constant pool
+ * all the time.
+ */
+enum java_awt_alpha_composite_rule
+ {
+ java_awt_alpha_composite_CLEAR = 1,
+ java_awt_alpha_composite_SRC = 2,
+ java_awt_alpha_composite_SRC_OVER = 3,
+ java_awt_alpha_composite_DST_OVER = 4,
+ java_awt_alpha_composite_SRC_IN = 5,
+ java_awt_alpha_composite_DST_IN = 6,
+ java_awt_alpha_composite_SRC_OUT = 7,
+ java_awt_alpha_composite_DST_OUT = 8,
+ java_awt_alpha_composite_DST = 9,
+ java_awt_alpha_composite_SRC_ATOP = 10,
+ java_awt_alpha_composite_DST_ATOP = 11,
+ java_awt_alpha_composite_XOR = 12
+ };
+
+enum java_awt_basic_stroke_join_rule
+ {
+ java_awt_basic_stroke_JOIN_MITER = 0,
+ java_awt_basic_stroke_JOIN_ROUND = 1,
+ java_awt_basic_stroke_JOIN_BEVEL = 2
+ };
+
+enum java_awt_basic_stroke_cap_rule
+ {
+ java_awt_basic_stroke_CAP_BUTT = 0,
+ java_awt_basic_stroke_CAP_ROUND = 1,
+ java_awt_basic_stroke_CAP_SQUARE = 2
+ };
+
+enum java_awt_geom_path_iterator_winding_rule
+ {
+ java_awt_geom_path_iterator_WIND_EVEN_ODD = 0,
+ java_awt_geom_path_iterator_WIND_NON_ZERO = 1
+ };
+
+enum java_awt_rendering_hints_filter
+ {
+ java_awt_rendering_hints_VALUE_INTERPOLATION_NEAREST_NEIGHBOR = 0,
+ java_awt_rendering_hints_VALUE_INTERPOLATION_BILINEAR = 1,
+ java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_SPEED = 2,
+ java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_QUALITY = 3,
+ java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_DEFAULT = 4
+
+ };
+
+/**
+ * A structure which basically contains the cairo_t pointer.
+ * The rest is for gradient and texture fills.
+ */
+struct cairographics2d
+{
+ cairo_t *cr;
+ cairo_surface_t *pattern_surface;
+ cairo_pattern_t *pattern;
+ char *pattern_pixels;
+};
+
+#endif
diff --git a/native/jni/gtk-peer/gdkdisplay.h b/native/jni/gtk-peer/gdkdisplay.h
new file mode 100644
index 000000000..238ff9e26
--- /dev/null
+++ b/native/jni/gtk-peer/gdkdisplay.h
@@ -0,0 +1,67 @@
+#ifndef __GDKDISPLAY_H__
+#define __GDKDISPLAY_H__
+
+/* gdkdisplay.h -- Some global stuff related to displays & screens
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+ This file is part of GNU Classpath.
+
+ GNU Classpath is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GNU Classpath is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNU Classpath; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301 USA.
+
+ Linking this library statically or dynamically with other modules is
+ making a combined work based on this library. Thus, the terms and
+ conditions of the GNU General Public License cover the whole
+ combination.
+
+ As a special exception, the copyright holders of this library give you
+ permission to link this library with independent modules to produce an
+ executable, regardless of the license terms of these independent
+ modules, and to copy and distribute the resulting executable under
+ terms of your choice, provided that you also meet, for each linked
+ independent module, the terms and conditions of the license of that
+ module. An independent module is a module which is not derived from
+ or based on this library. If you modify this library, you may extend
+ this exception to your version of the library, but you are not
+ obligated to do so. If you do not wish to do so, delete this
+ exception statement from your version. */
+
+#include "gtkpeer.h"
+
+/* Allows storing GdkDisplay pointers in GdkGraphicsEnvironment instances. */
+extern struct state_table *cp_gtk_native_display_state_table;
+
+/* Allows storing GdkScreen pointers in GdkScreenGraphicsDevice instances. */
+extern struct state_table *cp_gtk_native_screen_state_table;
+
+#define NSA_DISPLAY_INIT(env, clazz) \
+ cp_gtk_native_display_state_table = cp_gtk_init_state_table (env, clazz)
+
+#define NSA_GET_DISPLAY_PTR(env, obj) \
+ cp_gtk_get_state (env, obj, cp_gtk_native_display_state_table)
+
+#define NSA_SET_DISPLAY_PTR(env, obj, ptr) \
+ cp_gtk_set_state (env, obj, cp_gtk_native_display_state_table, (void *)ptr)
+
+#define NSA_SCREEN_INIT(env, clazz) \
+ cp_gtk_native_screen_state_table = cp_gtk_init_state_table (env, clazz)
+
+#define NSA_GET_SCREEN_PTR(env, obj) \
+ cp_gtk_get_state (env, obj, cp_gtk_native_screen_state_table)
+
+#define NSA_SET_SCREEN_PTR(env, obj, ptr) \
+ cp_gtk_set_state (env, obj, cp_gtk_native_screen_state_table, (void *)ptr)
+
+#endif /* __GDKDISPLAY_H__ */
diff --git a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoGraphics2D.c b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoGraphics2D.c
new file mode 100644
index 000000000..8ac89cffe
--- /dev/null
+++ b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoGraphics2D.c
@@ -0,0 +1,706 @@
+/* gnu_java_awt_peer_gtk_CairoGraphics2d.c
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+#include "jcl.h"
+#include "gdkfont.h"
+#include "cairographics2d.h"
+#include "gnu_java_awt_peer_gtk_CairoGraphics2D.h"
+#include <gdk/gdktypes.h>
+#include <gdk/gdkprivate.h>
+#include <gdk/gdkx.h>
+
+#include <cairo-ft.h>
+#include <cairo-xlib.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+static void install_font_peer(cairo_t *cr, struct peerfont *pfont);
+static void update_pattern_transform (struct cairographics2d *gr);
+
+/**
+ * Allocates the cairographics2d structure.
+ */
+JNIEXPORT jlong JNICALL
+Java_gnu_java_awt_peer_gtk_CairoGraphics2D_init
+ (JNIEnv *env __attribute__ ((unused)),
+ jobject obj __attribute__ ((unused)),
+ jlong cairo_t_pointer)
+{
+ struct cairographics2d *g = NULL;
+ cairo_t *cr = JLONG_TO_PTR(cairo_t, cairo_t_pointer);
+ g_assert(cr != NULL);
+
+ g = (struct cairographics2d *) g_malloc (sizeof (struct cairographics2d));
+
+ g_assert (g != NULL);
+ memset (g, 0, sizeof(struct cairographics2d));
+ g->cr = cr;
+
+ return PTR_TO_JLONG(g);
+}
+
+/**
+ * Disposes of the cairographics2d structure.
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_CairoGraphics2D_disposeNative
+ (JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)),
+ jlong pointer)
+{
+ struct cairographics2d *gr = JLONG_TO_PTR(struct cairographics2d, pointer);
+
+ if (gr == NULL)
+ return;
+
+ if (gr->cr)
+ cairo_destroy (gr->cr);
+
+ if (gr->pattern)
+ cairo_pattern_destroy (gr->pattern);
+ gr->pattern = NULL;
+
+ if (gr->pattern_surface)
+ cairo_surface_destroy (gr->pattern_surface);
+ gr->pattern_surface = NULL;
+
+ if (gr->pattern_pixels)
+ g_free(gr->pattern_pixels);
+ gr->pattern_pixels = NULL;
+
+ g_free( gr );
+}
+
+/**
+ * Set the gradient.
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_CairoGraphics2D_setGradient
+ (JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)),
+ jlong pointer,
+ jdouble x1, jdouble y1,
+ jdouble x2, jdouble y2,
+ jint r1, jint g1, jint b1, jint a1,
+ jint r2, jint g2, jint b2, jint a2,
+ jboolean cyclic)
+{
+ struct cairographics2d *gr = NULL;
+ cairo_pattern_t* pattern;
+ cairo_extend_t extend;
+
+ gr = JLONG_TO_PTR(struct cairographics2d, pointer);
+ g_assert( gr != NULL );
+
+ pattern = cairo_pattern_create_linear(x1, y1, x2, y2);
+ g_assert( pattern != NULL );
+
+ cairo_pattern_add_color_stop_rgba(pattern, 0.0, r1 / 255.0, g1 / 255.0,
+ b1 / 255.0, a1 / 255.0);
+
+ cairo_pattern_add_color_stop_rgba(pattern, 1.0, r2 / 255.0, g2 / 255.0,
+ b2 / 255.0, a2 / 255.0);
+
+ extend = (cyclic == JNI_TRUE) ? CAIRO_EXTEND_REFLECT : CAIRO_EXTEND_NONE;
+
+ cairo_pattern_set_extend( pattern, extend );
+
+ gr->pattern = pattern;
+ cairo_set_source(gr->cr, gr->pattern);
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_CairoGraphics2D_setTexturePixels
+ (JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)),
+ jlong pointer, jintArray jarr, jint w, jint h, jint stride)
+{
+ struct cairographics2d *gr = NULL;
+ jint *jpixels = NULL;
+
+ gr = JLONG_TO_PTR(struct cairographics2d, pointer);
+ g_assert (gr != NULL);
+
+ if (gr->pattern)
+ cairo_pattern_destroy (gr->pattern);
+
+ if (gr->pattern_surface)
+ cairo_surface_destroy (gr->pattern_surface);
+
+ if (gr->pattern_pixels)
+ g_free (gr->pattern_pixels);
+
+ gr->pattern = NULL;
+ gr->pattern_surface = NULL;
+ gr->pattern_pixels = NULL;
+
+ gr->pattern_pixels = (char *) g_malloc (h * stride * 4);
+ g_assert (gr->pattern_pixels != NULL);
+
+ jpixels = (*env)->GetIntArrayElements (env, jarr, NULL);
+ g_assert (jpixels != NULL);
+ memcpy (gr->pattern_pixels, jpixels, h * stride * 4);
+ (*env)->ReleaseIntArrayElements (env, jarr, jpixels, 0);
+
+ gr->pattern_surface = cairo_image_surface_create_for_data ((unsigned char *)gr->pattern_pixels,
+ CAIRO_FORMAT_ARGB32,
+ w, h, stride * 4);
+ g_assert (gr->pattern_surface != NULL);
+ gr->pattern = cairo_pattern_create_for_surface (gr->pattern_surface);
+ g_assert (gr->pattern != NULL);
+ cairo_pattern_set_extend (gr->pattern, CAIRO_EXTEND_REPEAT);
+ cairo_set_source (gr->cr, gr->pattern);
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_CairoGraphics2D_drawPixels
+(JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)),
+ jlong pointer, jintArray java_pixels,
+ jint w, jint h, jint stride, jdoubleArray java_matrix)
+{
+ jint *native_pixels = NULL;
+ jdouble *native_matrix = NULL;
+ struct cairographics2d *gr = JLONG_TO_PTR(struct cairographics2d, pointer);
+ g_assert (gr != NULL);
+
+ native_pixels = (*env)->GetIntArrayElements (env, java_pixels, NULL);
+ native_matrix = (*env)->GetDoubleArrayElements (env, java_matrix, NULL);
+ g_assert (native_pixels != NULL);
+ g_assert (native_matrix != NULL);
+ g_assert ((*env)->GetArrayLength (env, java_matrix) == 6);
+
+ {
+ cairo_matrix_t mat;
+ cairo_pattern_t *p;
+ cairo_surface_t *surf = cairo_image_surface_create_for_data ((unsigned char *)native_pixels,
+ CAIRO_FORMAT_ARGB32,
+ w, h, stride * 4);
+ cairo_matrix_init_identity (&mat);
+ cairo_matrix_init (&mat,
+ native_matrix[0], native_matrix[1],
+ native_matrix[2], native_matrix[3],
+ native_matrix[4], native_matrix[5]);
+
+ p = cairo_pattern_create_for_surface (surf);
+ cairo_pattern_set_matrix (p, &mat);
+ if (gr->pattern)
+ cairo_pattern_set_filter (p, cairo_pattern_get_filter (gr->pattern));
+ cairo_set_source (gr->cr, p);
+ cairo_paint (gr->cr);
+ cairo_pattern_destroy (p);
+ cairo_surface_destroy (surf);
+ }
+
+ (*env)->ReleaseIntArrayElements (env, java_pixels, native_pixels, 0);
+ (*env)->ReleaseDoubleArrayElements (env, java_matrix, native_matrix, 0);
+}
+
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoSetMatrix
+(JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)),
+ jlong pointer, jdoubleArray java_matrix)
+{
+ jdouble *native_matrix = NULL;
+ struct cairographics2d *gr = JLONG_TO_PTR(struct cairographics2d, pointer);
+ g_assert (obj != NULL);
+ g_assert (gr != NULL);
+
+ native_matrix = (*env)->GetDoubleArrayElements (env, java_matrix, NULL);
+ g_assert (native_matrix != NULL);
+ g_assert ((*env)->GetArrayLength (env, java_matrix) == 6);
+
+ {
+ cairo_matrix_t mat;
+
+ cairo_matrix_init_identity (&mat);
+ cairo_matrix_init (&mat,
+ native_matrix[0], native_matrix[1],
+ native_matrix[2], native_matrix[3],
+ native_matrix[4], native_matrix[5]);
+ g_assert (gr != NULL);
+ cairo_set_matrix (gr->cr, &mat);
+ }
+
+ (*env)->ReleaseDoubleArrayElements (env, java_matrix, native_matrix, 0);
+ update_pattern_transform (gr);
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoDrawGlyphVector
+(JNIEnv *env, jobject obj, jlong pointer,
+ jobject font,
+ jfloat x, jfloat y, jint n,
+ jintArray java_codes,
+ jfloatArray java_positions)
+{
+
+ struct cairographics2d *gr = NULL;
+ struct peerfont *pfont = NULL;
+ cairo_glyph_t *glyphs = NULL;
+ int *native_codes;
+ float *native_positions;
+ jint i = 0;
+
+ g_assert (obj != NULL);
+ g_assert (java_codes != NULL);
+ g_assert (java_positions != NULL);
+
+ gr = JLONG_TO_PTR(struct cairographics2d, pointer);
+ g_assert (gr != NULL);
+
+ pfont = (struct peerfont *)NSA_GET_FONT_PTR (env, font);
+ g_assert (pfont != NULL);
+
+ install_font_peer(gr->cr, pfont);
+
+ glyphs = g_malloc( sizeof(cairo_glyph_t) * n);
+ g_assert (glyphs != NULL);
+
+ native_codes = (*env)->GetIntArrayElements (env, java_codes, NULL);
+ native_positions = (*env)->GetFloatArrayElements (env, java_positions, NULL);
+
+ for (i = 0; i < n; ++i)
+ {
+ glyphs[i].index = native_codes[i];
+ glyphs[i].x = x + native_positions[ 2*i ];
+ glyphs[i].y = y + native_positions[ 2*i + 1];
+ }
+
+ (*env)->ReleaseFloatArrayElements (env, java_positions, native_positions, 0);
+ (*env)->ReleaseIntArrayElements (env, java_codes, native_codes, 0);
+
+ cairo_show_glyphs (gr->cr, glyphs, n);
+
+ g_free(glyphs);
+}
+
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoSetOperator
+(JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)),
+ jlong pointer, jint op)
+{
+ struct cairographics2d *gr = JLONG_TO_PTR(struct cairographics2d, pointer);
+ g_assert (gr != NULL);
+
+ switch ((enum java_awt_alpha_composite_rule) op)
+ {
+ case java_awt_alpha_composite_CLEAR:
+ cairo_set_operator (gr->cr, CAIRO_OPERATOR_CLEAR);
+ break;
+
+ case java_awt_alpha_composite_SRC:
+ cairo_set_operator (gr->cr, CAIRO_OPERATOR_SOURCE);
+ break;
+
+ case java_awt_alpha_composite_SRC_OVER:
+ cairo_set_operator (gr->cr, CAIRO_OPERATOR_OVER);
+ break;
+
+ case java_awt_alpha_composite_DST_OVER:
+ cairo_set_operator (gr->cr, CAIRO_OPERATOR_DEST_OVER);
+ break;
+
+ case java_awt_alpha_composite_SRC_IN:
+ cairo_set_operator (gr->cr, CAIRO_OPERATOR_IN);
+ break;
+
+ case java_awt_alpha_composite_DST_IN:
+ cairo_set_operator (gr->cr, CAIRO_OPERATOR_DEST_IN);
+ break;
+
+ case java_awt_alpha_composite_SRC_OUT:
+ cairo_set_operator (gr->cr, CAIRO_OPERATOR_OUT);
+ break;
+
+ case java_awt_alpha_composite_DST_OUT:
+ cairo_set_operator (gr->cr, CAIRO_OPERATOR_DEST_OUT);
+ break;
+
+ case java_awt_alpha_composite_DST:
+ cairo_set_operator (gr->cr, CAIRO_OPERATOR_DEST);
+ break;
+
+ case java_awt_alpha_composite_SRC_ATOP:
+ cairo_set_operator (gr->cr, CAIRO_OPERATOR_ATOP);
+ break;
+
+ case java_awt_alpha_composite_DST_ATOP:
+ cairo_set_operator (gr->cr, CAIRO_OPERATOR_DEST_ATOP);
+ break;
+
+ case java_awt_alpha_composite_XOR:
+ cairo_set_operator (gr->cr, CAIRO_OPERATOR_XOR);
+ break;
+ }
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoSetRGBAColor
+(JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)),
+ jlong pointer, jdouble r, jdouble g, jdouble b, jdouble a)
+{
+ struct cairographics2d *gr = JLONG_TO_PTR(struct cairographics2d, pointer);
+ g_assert (gr != NULL);
+
+ cairo_set_source_rgba (gr->cr, r, g, b, a);
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoSetFillRule
+(JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)),
+ jlong pointer, jint rule)
+{
+ struct cairographics2d *gr = JLONG_TO_PTR(struct cairographics2d, pointer);
+ g_assert (gr != NULL);
+
+ switch ((enum java_awt_geom_path_iterator_winding_rule) rule)
+ {
+ case java_awt_geom_path_iterator_WIND_NON_ZERO:
+ cairo_set_fill_rule (gr->cr, CAIRO_FILL_RULE_WINDING);
+ break;
+ case java_awt_geom_path_iterator_WIND_EVEN_ODD:
+ cairo_set_fill_rule (gr->cr, CAIRO_FILL_RULE_EVEN_ODD);
+ break;
+ }
+}
+
+/**
+ * Set the line style, except for dashes.
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoSetLine
+(JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)),
+ jlong pointer, jdouble width, int cap, int join, double miterLimit)
+{
+ struct cairographics2d *gr = JLONG_TO_PTR(struct cairographics2d, pointer);
+ g_assert (gr != NULL);
+
+ /* set width */
+ cairo_set_line_width (gr->cr, width);
+
+ /* set cap */
+ switch ((enum java_awt_basic_stroke_cap_rule) cap)
+ {
+ case java_awt_basic_stroke_CAP_BUTT:
+ cairo_set_line_cap (gr->cr, CAIRO_LINE_CAP_BUTT);
+ break;
+
+ case java_awt_basic_stroke_CAP_ROUND:
+ cairo_set_line_cap (gr->cr, CAIRO_LINE_CAP_ROUND);
+ break;
+
+ case java_awt_basic_stroke_CAP_SQUARE:
+ cairo_set_line_cap (gr->cr, CAIRO_LINE_CAP_SQUARE);
+ break;
+ }
+
+ /* set join */
+ switch ((enum java_awt_basic_stroke_join_rule) join)
+ {
+ case java_awt_basic_stroke_JOIN_MITER:
+ cairo_set_line_join (gr->cr, CAIRO_LINE_JOIN_MITER);
+ break;
+
+ case java_awt_basic_stroke_JOIN_ROUND:
+ cairo_set_line_join (gr->cr, CAIRO_LINE_JOIN_ROUND);
+ break;
+
+ case java_awt_basic_stroke_JOIN_BEVEL:
+ cairo_set_line_join (gr->cr, CAIRO_LINE_JOIN_BEVEL);
+ break;
+ }
+
+ /* set miter */
+ cairo_set_miter_limit (gr->cr, miterLimit);
+}
+
+/**
+ * Set the line dashes
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoSetDash
+(JNIEnv *env, jobject obj __attribute__((unused)),
+ jlong pointer, jdoubleArray dashes, jint ndash, jdouble offset)
+{
+ jdouble *dasharr = NULL;
+ struct cairographics2d *gr = JLONG_TO_PTR(struct cairographics2d, pointer);
+ g_assert (gr != NULL);
+
+ dasharr = (*env)->GetDoubleArrayElements (env, dashes, NULL);
+ g_assert (dasharr != NULL);
+
+ cairo_set_dash (gr->cr, dasharr, ndash, offset);
+
+ (*env)->ReleaseDoubleArrayElements (env, dashes, dasharr, 0);
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoNewPath
+(JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)),
+ jlong pointer)
+{
+ struct cairographics2d *gr = JLONG_TO_PTR(struct cairographics2d, pointer);
+ g_assert (gr != NULL);
+
+ cairo_new_path (gr->cr);
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoMoveTo
+(JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)),
+ jlong pointer, jdouble x, jdouble y)
+{
+ struct cairographics2d *gr = JLONG_TO_PTR(struct cairographics2d, pointer);
+ g_assert (gr != NULL);
+
+ cairo_move_to (gr->cr, x, y);
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoLineTo
+(JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)),
+ jlong pointer, jdouble x, jdouble y)
+{
+ struct cairographics2d *gr = JLONG_TO_PTR(struct cairographics2d, pointer);
+ g_assert (gr != NULL);
+
+ cairo_line_to (gr->cr, x, y);
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoCurveTo
+(JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)),
+ jlong pointer, jdouble x1, jdouble y1,
+ jdouble x2, jdouble y2, jdouble x3, jdouble y3)
+{
+ struct cairographics2d *gr = JLONG_TO_PTR(struct cairographics2d, pointer);
+ g_assert (gr != NULL);
+ cairo_curve_to (gr->cr, x1, y1, x2, y2, x3, y3);
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoRelMoveTo
+(JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)),
+ jlong pointer, jdouble dx, jdouble dy)
+{
+ struct cairographics2d *gr = JLONG_TO_PTR(struct cairographics2d, pointer);
+ g_assert (gr != NULL);
+
+ cairo_rel_move_to (gr->cr, dx, dy);
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoRelLineTo
+(JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)),
+ jlong pointer, jdouble dx, jdouble dy)
+{
+ struct cairographics2d *gr = JLONG_TO_PTR(struct cairographics2d, pointer);
+ g_assert (gr != NULL);
+
+ cairo_rel_line_to (gr->cr, dx, dy);
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoRelCurveTo
+(JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)),
+ jlong pointer, jdouble dx1, jdouble dy1,
+ jdouble dx2, jdouble dy2, jdouble dx3, jdouble dy3)
+{
+ struct cairographics2d *gr = JLONG_TO_PTR(struct cairographics2d, pointer);
+ g_assert (gr != NULL);
+
+ cairo_rel_curve_to (gr->cr, dx1, dy1, dx2, dy2, dx3, dy3);
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoRectangle
+(JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)),
+ jlong pointer, jdouble x, jdouble y, jdouble width, jdouble height)
+{
+ struct cairographics2d *gr = JLONG_TO_PTR(struct cairographics2d, pointer);
+
+ cairo_rectangle (gr->cr, x, y, width, height);
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoClosePath
+(JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)),
+ jlong pointer)
+{
+ struct cairographics2d *gr = JLONG_TO_PTR(struct cairographics2d, pointer);
+ g_assert (gr != NULL);
+
+ cairo_close_path (gr->cr);
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoStroke
+(JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)),
+ jlong pointer)
+{
+ struct cairographics2d *gr = JLONG_TO_PTR(struct cairographics2d, pointer);
+ g_assert (gr != NULL);
+
+ cairo_stroke (gr->cr);
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoFill
+(JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)),
+ jlong pointer)
+{
+ struct cairographics2d *gr = JLONG_TO_PTR(struct cairographics2d, pointer);
+ g_assert (gr != NULL);
+
+ cairo_fill (gr->cr);
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoClip
+(JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)),
+ jlong pointer)
+{
+ struct cairographics2d *gr = JLONG_TO_PTR(struct cairographics2d, pointer);
+ g_assert( gr != NULL );
+
+ cairo_clip( gr->cr );
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoResetClip
+(JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)),
+ jlong pointer)
+{
+ struct cairographics2d *gr = JLONG_TO_PTR(struct cairographics2d, pointer);
+ g_assert (gr != NULL);
+
+ cairo_reset_clip( gr->cr );
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoPreserveClip
+(JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)),
+ jlong pointer)
+{
+ struct cairographics2d *gr = JLONG_TO_PTR(struct cairographics2d, pointer);
+ g_assert (gr != NULL);
+
+ cairo_clip_preserve( gr->cr );
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_CairoGraphics2D_cairoSurfaceSetFilter
+(JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)),
+ jlong pointer, jint filter)
+{
+ struct cairographics2d *gr = JLONG_TO_PTR(struct cairographics2d, pointer);
+ g_assert (gr != NULL);
+
+ if (gr->pattern == NULL)
+ return;
+
+ switch ((enum java_awt_rendering_hints_filter) filter)
+ {
+ case java_awt_rendering_hints_VALUE_INTERPOLATION_NEAREST_NEIGHBOR:
+ cairo_pattern_set_filter (gr->pattern, CAIRO_FILTER_NEAREST);
+ break;
+ case java_awt_rendering_hints_VALUE_INTERPOLATION_BILINEAR:
+ cairo_pattern_set_filter (gr->pattern, CAIRO_FILTER_BILINEAR);
+ break;
+ case java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_SPEED:
+ cairo_pattern_set_filter (gr->pattern, CAIRO_FILTER_FAST);
+ break;
+ case java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_DEFAULT:
+ cairo_pattern_set_filter (gr->pattern, CAIRO_FILTER_NEAREST);
+ break;
+ case java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_QUALITY:
+ cairo_pattern_set_filter (gr->pattern, CAIRO_FILTER_BEST);
+ break;
+ }
+}
+
+/************************** FONT STUFF ****************************/
+static void
+install_font_peer(cairo_t *cr,
+ struct peerfont *pfont)
+{
+ cairo_font_face_t *ft;
+ FT_Face face = NULL;
+
+ g_assert(cr != NULL);
+ g_assert(pfont != NULL);
+
+ if (pfont->graphics_resource == NULL)
+ {
+ face = pango_ft2_font_get_face (pfont->font);
+ g_assert (face != NULL);
+
+ ft = cairo_ft_font_face_create_for_ft_face (face, 0);
+ g_assert (ft != NULL);
+
+ cairo_set_font_face (cr, ft);
+ cairo_font_face_destroy (ft);
+ cairo_set_font_size (cr,
+ (pango_font_description_get_size (pfont->desc) /
+ (double)PANGO_SCALE));
+ ft = cairo_get_font_face (cr);
+ pfont->graphics_resource = ft;
+ }
+ else
+ {
+ ft = (cairo_font_face_t *) pfont->graphics_resource;
+ cairo_set_font_face (cr, ft);
+ cairo_set_font_size (cr,
+ (pango_font_description_get_size (pfont->desc) /
+ (double)PANGO_SCALE));
+ }
+}
+
+static void
+update_pattern_transform (struct cairographics2d *gr)
+{
+ cairo_matrix_t mat;
+
+ g_assert (gr != NULL);
+ if (gr->pattern == NULL)
+ return;
+
+ cairo_get_matrix (gr->cr, &mat);
+ cairo_pattern_set_matrix (gr->pattern, &mat);
+}
+
+
diff --git a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoSurface.c b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoSurface.c
new file mode 100644
index 000000000..3efa60d62
--- /dev/null
+++ b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoSurface.c
@@ -0,0 +1,302 @@
+/* gnu_java_awt_peer_gtk_CairoSurface.c
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+#include "jcl.h"
+#include "gtkpeer.h"
+#include <cairo-xlib.h>
+#include <gdk/gdkx.h>
+
+#include "gnu_java_awt_peer_gtk_CairoSurface.h"
+#include "cairographics2d.h"
+
+/**
+ * Field names in CairoSurface.java
+ */
+#define SURFACE "surfacePointer"
+#define BUFFER "bufferPointer"
+
+/* prototypes */
+static void setNativeObject( JNIEnv *env, jobject obj, void *ptr, const char *pointer );
+
+/**
+ * Creates a cairo surface, ARGB32, native ordering, premultiplied alpha.
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_CairoSurface_create (JNIEnv *env, jobject obj, jint width, jint height, jint stride)
+{
+ cairo_surface_t* surface;
+ void *data = g_malloc(stride * height * 4);
+ memset(data, 0, stride * height * 4);
+ setNativeObject(env, obj, data, BUFFER);
+
+ surface = cairo_image_surface_create_for_data
+ (data, CAIRO_FORMAT_ARGB32, width, height, stride);
+
+ setNativeObject(env, obj, surface, SURFACE);
+}
+
+/**
+ * Destroy the surface
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_CairoSurface_destroy
+(JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)),
+ jlong surfacePointer, jlong bufferPointer)
+{
+ void *buffer;
+ cairo_surface_t* surface = JLONG_TO_PTR(void, surfacePointer);
+ if( surface != NULL )
+ cairo_surface_destroy(surface);
+
+ buffer = JLONG_TO_PTR(void, bufferPointer);
+ if( buffer != NULL )
+ g_free(buffer);
+}
+
+/**
+ * Gets a pixel
+ */
+JNIEXPORT jint JNICALL
+Java_gnu_java_awt_peer_gtk_CairoSurface_nativeGetElem
+(JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)),
+ jlong bufferPointer, jint i)
+{
+ jint *pixeldata = JLONG_TO_PTR(void, bufferPointer);
+
+ if( pixeldata == NULL )
+ return 0;
+
+ return pixeldata[i];
+}
+
+/**
+ * Sets a pixel
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_CairoSurface_nativeSetElem
+(JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)),
+ jlong bufferPointer, jint i, jint val)
+{
+ jint *pixeldata = JLONG_TO_PTR(void, bufferPointer);
+
+ if( pixeldata == NULL )
+ return;
+
+ pixeldata[i] = val;
+}
+
+/**
+ * Gets all pixels in an array
+ */
+JNIEXPORT jintArray JNICALL
+Java_gnu_java_awt_peer_gtk_CairoSurface_nativeGetPixels
+(JNIEnv *env __attribute((unused)), jobject obj __attribute((unused)),
+ jlong bufferPointer, int size)
+{
+ jint *pixeldata, *jpixdata;
+ jintArray jpixels;
+
+ pixeldata = JLONG_TO_PTR(void, bufferPointer);
+ g_assert(pixeldata != NULL);
+
+ jpixels = (*env)->NewIntArray (env, size);
+ jpixdata = (*env)->GetIntArrayElements (env, jpixels, NULL);
+ memcpy (jpixdata, pixeldata, size * sizeof( jint ));
+
+ (*env)->ReleaseIntArrayElements (env, jpixels, jpixdata, 0);
+ return jpixels;
+}
+
+/**
+ * Sets all pixels by an array.
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_CairoSurface_nativeSetPixels
+(JNIEnv *env, jobject obj, jlong bufferPointer, jintArray jpixels)
+{
+ jint *pixeldata, *jpixdata;
+ int size;
+ int width, height;
+ jclass cls;
+ jfieldID field;
+
+ if( jpixels == NULL )
+ return;
+
+ cls = (*env)->GetObjectClass (env, obj);
+ field = (*env)->GetFieldID (env, cls, "width", "I");
+ g_assert (field != 0);
+ width = (*env)->GetIntField (env, obj, field);
+
+ field = (*env)->GetFieldID (env, cls, "height", "I");
+ g_assert (field != 0);
+ height = (*env)->GetIntField (env, obj, field);
+
+ pixeldata = JLONG_TO_PTR(void, bufferPointer);
+ g_assert(pixeldata != NULL);
+
+ jpixdata = (*env)->GetIntArrayElements (env, jpixels, NULL);
+ size = (*env)->GetArrayLength( env, jpixels );
+ if( size > width * height ) size = width * height; /* stop overflows. */
+
+ memcpy (pixeldata, jpixdata, size * sizeof( jint ));
+
+ (*env)->ReleaseIntArrayElements (env, jpixels, jpixdata, 0);
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_CairoSurface_nativeDrawSurface
+(JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)),
+ jlong surfacePointer, jlong context, jdoubleArray java_matrix)
+{
+ struct cairographics2d *gr = JLONG_TO_PTR(struct cairographics2d, context);
+ cairo_t *cr = gr->cr;
+ jdouble *native_matrix = NULL;
+ cairo_surface_t* surface = JLONG_TO_PTR(void, surfacePointer);
+ g_assert(surface != NULL);
+ g_assert(cr != NULL);
+
+ native_matrix = (*env)->GetDoubleArrayElements (env, java_matrix, NULL);
+ g_assert (native_matrix != NULL);
+ g_assert ((*env)->GetArrayLength (env, java_matrix) == 6);
+
+ {
+ cairo_matrix_t mat;
+ cairo_pattern_t *p;
+ cairo_matrix_init_identity (&mat);
+ cairo_matrix_init (&mat,
+ native_matrix[0], native_matrix[1],
+ native_matrix[2], native_matrix[3],
+ native_matrix[4], native_matrix[5]);
+
+ p = cairo_pattern_create_for_surface (surface);
+ cairo_pattern_set_matrix (p, &mat);
+
+ cairo_set_source(cr, p);
+ cairo_paint(cr);
+ cairo_pattern_destroy(p);
+ }
+
+ (*env)->ReleaseDoubleArrayElements (env, java_matrix, native_matrix, 0);
+}
+
+JNIEXPORT jlong JNICALL
+Java_gnu_java_awt_peer_gtk_CairoSurface_getFlippedBuffer
+(JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)),
+ jlong bufferPointer, jint size)
+{
+ jint *dst;
+ jint *src = JLONG_TO_PTR(void, bufferPointer);
+ int i;
+ int t;
+
+ g_assert( src != NULL );
+ dst = g_malloc( size * sizeof( jint ) );
+
+ for(i = 0; i < size; i++ )
+ {
+ t = (src[i] & 0x0000FF) << 16;
+ dst[i] = (src[i] & 0x00FF0000) >> 16;
+ dst[i] |= (src[i] & 0xFF00FF00);
+ dst[i] |= t;
+ }
+
+ return PTR_TO_JLONG(dst);
+}
+
+/**
+ * Create and return a cairo context for drawing to the surface.
+ */
+JNIEXPORT jlong JNICALL
+Java_gnu_java_awt_peer_gtk_CairoSurface_nativeNewCairoContext
+(JNIEnv *env __attribute((unused)), jobject obj __attribute((unused)),
+ jlong surfacePointer)
+{
+ cairo_surface_t* surface = JLONG_TO_PTR(cairo_surface_t, surfacePointer);
+ cairo_t *ptr;
+ g_assert(surface != NULL);
+ ptr = cairo_create(surface);
+ g_assert(ptr != NULL);
+
+ return PTR_TO_JLONG(ptr);
+}
+
+/**
+ * copyArea.
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_CairoSurface_copyAreaNative2
+(JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)),
+ jlong bufferPointer,
+ jint x, jint y, jint w, jint h, jint dx, jint dy, jint stride)
+{
+ int row;
+ int srcOffset, dstOffset;
+ jint *temp;
+ jint *pixeldata = JLONG_TO_PTR(jint, bufferPointer);
+ g_assert( pixeldata != NULL );
+
+ temp = g_malloc( h * w * 4 );
+ g_assert( temp != NULL );
+
+ srcOffset = x + (y * stride);
+ dstOffset = (x + dx) + ((y + dy) * stride);
+
+ for( row = 0; row < h; row++ )
+ memcpy( temp + (w * row), pixeldata + srcOffset + (stride * row), w * 4 );
+
+ for( row = 0; row < h; row++ )
+ memcpy( pixeldata + dstOffset + (stride * row), temp + (w * row), w * 4 );
+
+ g_free( temp );
+}
+
+/*
+ * Sets the native object field.
+ */
+static void
+setNativeObject( JNIEnv *env, jobject obj, void *ptr, const char *pointer )
+{
+ jclass cls;
+ jlong value;
+ jfieldID nofid;
+ cls = (*env)->GetObjectClass( env, obj );
+ value = PTR_TO_JLONG(ptr);
+ nofid = (*env)->GetFieldID( env, cls, pointer, "J" );
+ (*env)->SetLongField( env, obj, nofid, value );
+ (*env)->DeleteLocalRef( env, cls );
+}
diff --git a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_ComponentGraphics.c b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_ComponentGraphics.c
new file mode 100644
index 000000000..d85ba326f
--- /dev/null
+++ b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_ComponentGraphics.c
@@ -0,0 +1,311 @@
+/* gnu_java_awt_peer_gtk_ComponentGraphics.c
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+#include "jcl.h"
+#include "gtkpeer.h"
+#include <cairo-xlib.h>
+#include <gdk/gdktypes.h>
+#include <gdk/gdkprivate.h>
+#include <gdk/gdkx.h>
+#include <X11/extensions/Xrender.h>
+
+#include <gdk-pixbuf/gdk-pixbuf.h>
+#include <gdk-pixbuf/gdk-pixdata.h>
+
+#include <cairo-ft.h>
+#include <cairo-xlib.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "gnu_java_awt_peer_gtk_ComponentGraphics.h"
+
+#include "cairographics2d.h"
+
+static short flush_scheduled = 0;
+
+static gboolean flush (gpointer data __attribute__((unused)))
+{
+ gdk_threads_enter ();
+
+ XFlush (GDK_DISPLAY ());
+ flush_scheduled = 0;
+
+ gdk_threads_leave ();
+
+ return FALSE;
+}
+
+/* The minimum time period between calls to XFlush, in
+ milliseconds. */
+#define MINIMUM_FLUSH_PERIOD 20
+
+/* schedule_flush must be called with the GDK lock held. */
+static void
+schedule_flush ()
+{
+ if (!flush_scheduled)
+ {
+ g_timeout_add (MINIMUM_FLUSH_PERIOD, flush, NULL);
+ flush_scheduled = 1;
+ }
+}
+
+void cp_gtk_grab_current_drawable(GtkWidget *widget, GdkDrawable **draw,
+ GdkWindow **win)
+{
+ g_assert (widget != NULL);
+ g_assert (draw != NULL);
+ g_assert (win != NULL);
+
+ *win = widget->window;
+
+ *draw = *win;
+ gdk_window_get_internal_paint_info (*win, draw, 0, 0);
+}
+
+/**
+ * Returns whether the XRender extension is supported
+ */
+JNIEXPORT jboolean JNICALL
+Java_gnu_java_awt_peer_gtk_ComponentGraphics_hasXRender
+ (JNIEnv *env __attribute__ ((unused)), jclass cls __attribute__ ((unused)))
+{
+#if HAVE_XRENDER
+ int ev = 0, err = 0;
+ if( XRenderQueryExtension (GDK_DISPLAY (), &ev, &err) )
+ return JNI_TRUE;
+#endif
+ return JNI_FALSE;
+}
+
+
+JNIEXPORT jlong JNICALL
+Java_gnu_java_awt_peer_gtk_ComponentGraphics_initState
+ (JNIEnv *env, jobject obj __attribute__ ((unused)), jobject peer)
+{
+ Drawable draw;
+ Display * dpy;
+ Visual * vis;
+ GdkDrawable *drawable;
+ cairo_surface_t *surface;
+ GdkWindow *win;
+ GtkWidget *widget = NULL;
+ void *ptr = NULL;
+ int width, height;
+ cairo_t *cr;
+
+ gdk_threads_enter();
+
+ ptr = NSA_GET_PTR (env, peer);
+ g_assert (ptr != NULL);
+
+ widget = GTK_WIDGET (ptr);
+ g_assert (widget != NULL);
+
+ cp_gtk_grab_current_drawable (widget, &drawable, &win);
+ g_assert (drawable != NULL);
+
+ width = widget->allocation.width;
+ height = widget->allocation.height;
+
+ g_assert (drawable != NULL);
+
+ draw = gdk_x11_drawable_get_xid(drawable);
+ g_assert (draw != (XID) 0);
+
+ dpy = gdk_x11_drawable_get_xdisplay(drawable);
+ g_assert (dpy != NULL);
+
+ vis = gdk_x11_visual_get_xvisual(gdk_drawable_get_visual(drawable));
+ g_assert (vis != NULL);
+
+ surface = cairo_xlib_surface_create (dpy, draw, vis, width, height);
+ g_assert (surface != NULL);
+
+ cr = cairo_create (surface);
+ g_assert(cr != NULL);
+
+ gdk_threads_leave();
+
+ return PTR_TO_JLONG(cr);
+}
+
+/**
+ * Disposes of the surface
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_ComponentGraphics_disposeSurface
+ (JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)),
+ jlong value)
+{
+ struct cairographics2d *gr;
+ cairo_surface_t *surface;
+
+ gr = JLONG_TO_PTR(struct cairographics2d, value);
+
+ if (gr == NULL)
+ return;
+
+ if (gr->cr == NULL)
+ return;
+
+ surface = cairo_get_target (gr->cr);
+ if (surface != NULL)
+ {
+ gdk_threads_enter();
+ cairo_surface_destroy (surface);
+ gdk_threads_leave();
+ }
+}
+
+JNIEXPORT jlong JNICALL
+Java_gnu_java_awt_peer_gtk_ComponentGraphics_initFromVolatile
+ (JNIEnv *env __attribute__ ((unused)), jobject obj __attribute__ ((unused)),
+ jlong ptr, jint width, jint height)
+{
+ Drawable draw;
+ Display * dpy;
+ Visual * vis;
+ GdkDrawable *drawable;
+ cairo_surface_t *surface;
+ cairo_t *cr;
+
+ gdk_threads_enter();
+
+ drawable = JLONG_TO_PTR(GdkDrawable, ptr);
+ g_assert (drawable != NULL);
+
+ draw = gdk_x11_drawable_get_xid(drawable);
+ g_assert (draw != (XID) 0);
+
+ dpy = gdk_x11_drawable_get_xdisplay(drawable);
+ g_assert (dpy != NULL);
+
+ vis = gdk_x11_visual_get_xvisual(gdk_drawable_get_visual(drawable));
+ g_assert (vis != NULL);
+
+ surface = cairo_xlib_surface_create (dpy, draw, vis, width, height);
+ g_assert (surface != NULL);
+
+ cr = cairo_create (surface);
+ g_assert(cr != NULL);
+
+ gdk_threads_leave();
+
+ return PTR_TO_JLONG(cr);
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_ComponentGraphics_start_1gdk_1drawing
+ (JNIEnv *env __attribute__ ((unused)), jobject obj __attribute__ ((unused)))
+{
+ gdk_threads_enter();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_ComponentGraphics_end_1gdk_1drawing
+ (JNIEnv *env __attribute__ ((unused)), jobject obj __attribute__ ((unused)))
+{
+ schedule_flush ();
+ gdk_threads_leave();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_ComponentGraphics_copyAreaNative
+ (JNIEnv *env, jobject obj __attribute__((unused)), jobject peer,
+ jint x, jint y, jint w, jint h, jint dx, jint dy)
+{
+ GdkPixbuf *pixbuf;
+ GdkDrawable *drawable;
+ GdkWindow *win;
+ GtkWidget *widget = NULL;
+ void *ptr = NULL;
+
+ gdk_threads_enter();
+
+ ptr = NSA_GET_PTR (env, peer);
+ g_assert (ptr != NULL);
+
+ widget = GTK_WIDGET (ptr);
+ g_assert (widget != NULL);
+
+ cp_gtk_grab_current_drawable (widget, &drawable, &win);
+ g_assert (drawable != NULL);
+
+ pixbuf = gdk_pixbuf_new( GDK_COLORSPACE_RGB, TRUE, 8, w, h );
+ gdk_pixbuf_get_from_drawable( pixbuf, drawable, NULL, x, y, 0, 0, w, h );
+ gdk_draw_pixbuf (drawable, NULL, pixbuf,
+ 0, 0, x + dx, y + dy,
+ w, h,
+ GDK_RGB_DITHER_NORMAL, 0, 0);
+ gdk_threads_leave();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_ComponentGraphics_drawVolatile
+(JNIEnv *env, jobject obj __attribute__ ((unused)), jobject peer,
+ jlong img, jint x, jint y, jint w, jint h)
+{
+ GdkPixmap *pixmap;
+ GtkWidget *widget = NULL;
+ void *ptr = NULL;
+ GdkGC *gc;
+
+ gdk_threads_enter();
+ ptr = NSA_GET_PTR (env, peer);
+ g_assert (ptr != NULL);
+
+ widget = GTK_WIDGET (ptr);
+ g_assert (widget != NULL);
+
+ pixmap = JLONG_TO_PTR(GdkPixmap, img);
+
+ gc = gdk_gc_new(widget->window);
+ gdk_draw_drawable(widget->window,
+ gc,
+ pixmap,
+ 0, 0,
+ x, y,
+ w, h);
+
+ g_object_unref( gc );
+
+ schedule_flush ();
+
+ gdk_threads_leave();
+}
diff --git a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_ComponentGraphicsCopy.c b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_ComponentGraphicsCopy.c
new file mode 100644
index 000000000..76caa5d0c
--- /dev/null
+++ b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_ComponentGraphicsCopy.c
@@ -0,0 +1,132 @@
+/* gnu_java_awt_peer_gtk_ComponentGraphicsCopy.c
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+#include "jcl.h"
+#include "gtkpeer.h"
+#include <cairo-xlib.h>
+#include <gdk/gdktypes.h>
+#include <gdk/gdkprivate.h>
+#include <gdk/gdkx.h>
+
+#include <gdk-pixbuf/gdk-pixbuf.h>
+#include <gdk-pixbuf/gdk-pixdata.h>
+
+#include <cairo-ft.h>
+#include <cairo-xlib.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "gnu_java_awt_peer_gtk_ComponentGraphicsCopy.h"
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_ComponentGraphicsCopy_getPixbuf
+ (JNIEnv *env, jobject obj __attribute__((unused)),
+ jobject peer, jobject image)
+{
+ gint width, height;
+ GdkPixbuf *pixbuf;
+ GdkDrawable *drawable;
+ GdkWindow *win;
+ GtkWidget *widget = NULL;
+ void *ptr = NULL;
+
+ gdk_threads_enter();
+
+ ptr = NSA_GET_PTR (env, peer);
+ g_assert (ptr != NULL);
+
+ widget = GTK_WIDGET (ptr);
+ g_assert (widget != NULL);
+
+ cp_gtk_grab_current_drawable (widget, &drawable, &win);
+ g_assert (drawable != NULL);
+
+ pixbuf = cp_gtk_image_get_pixbuf( env, image );
+ g_assert( pixbuf != NULL);
+
+ width = gdk_pixbuf_get_width( pixbuf );
+ height = gdk_pixbuf_get_height( pixbuf );
+
+ gdk_pixbuf_get_from_drawable( pixbuf, /* destination pixbuf */
+ drawable,
+ NULL, /* colormap */
+ 0, 0, 0, 0,
+ width, height );
+ gdk_threads_leave();
+}
+
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_ComponentGraphicsCopy_copyPixbuf
+ (JNIEnv *env, jobject obj __attribute__((unused)),
+ jobject peer, jobject image,
+ int x __attribute__((unused)), int y __attribute__((unused)),
+ int width __attribute__((unused)), int height __attribute__((unused)))
+{
+ gint pwidth, pheight;
+ GdkPixbuf *pixbuf;
+ GdkDrawable *drawable;
+ GdkWindow *win;
+ GtkWidget *widget = NULL;
+ void *ptr = NULL;
+
+ gdk_threads_enter();
+
+ ptr = NSA_GET_PTR (env, peer);
+ g_assert (ptr != NULL);
+
+ widget = GTK_WIDGET (ptr);
+ g_assert (widget != NULL);
+
+ cp_gtk_grab_current_drawable (widget, &drawable, &win);
+ g_assert (drawable != NULL);
+
+ pixbuf = cp_gtk_image_get_pixbuf( env, image );
+ g_assert( pixbuf != NULL);
+
+ pwidth = gdk_pixbuf_get_width( pixbuf );
+ pheight = gdk_pixbuf_get_height( pixbuf );
+
+ gdk_draw_pixbuf (drawable, NULL, pixbuf,
+ 0, 0, 0, 0,
+ pwidth, pheight,
+ GDK_RGB_DITHER_NORMAL, 0, 0);
+
+ gdk_threads_leave();
+}
+
diff --git a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_FreetypeGlyphVector.c b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_FreetypeGlyphVector.c
new file mode 100644
index 000000000..c8b74d207
--- /dev/null
+++ b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_FreetypeGlyphVector.c
@@ -0,0 +1,348 @@
+/* gnu_java_awt_FreetypeGlyphVector.c
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+#include <jni.h>
+#include <gtk/gtk.h>
+#include <string.h>
+#include <pango/pango.h>
+#include <pango/pangoft2.h>
+#include <pango/pangofc-font.h>
+#include <freetype/ftglyph.h>
+#include <freetype/ftoutln.h>
+#include "native_state.h"
+#include "gdkfont.h"
+#include "gnu_java_awt_peer_gtk_FreetypeGlyphVector.h"
+#include "cairographics2d.h"
+
+typedef struct gp
+{
+ JNIEnv *env;
+ jobject obj;
+ double px;
+ double py;
+ double sx;
+ double sy;
+} generalpath ;
+
+static PangoFcFont *
+getFont(JNIEnv *env, jobject obj)
+{
+ jfieldID fid;
+ jobject data;
+ jclass cls;
+ struct peerfont *pfont;
+
+ cls = (*env)->GetObjectClass (env, obj);
+ fid = (*env)->GetFieldID (env, cls, "peer",
+ "Lgnu/java/awt/peer/gtk/GdkFontPeer;");
+ g_assert (fid != 0);
+
+ data = (*env)->GetObjectField (env, obj, fid);
+ g_assert (data != NULL);
+
+ pfont = (struct peerfont *)NSA_GET_FONT_PTR (env, data);
+ g_assert (pfont != NULL);
+ g_assert (pfont->font != NULL);
+
+ return (PangoFcFont *)pfont->font;
+}
+
+JNIEXPORT jintArray JNICALL
+Java_gnu_java_awt_peer_gtk_FreetypeGlyphVector_getGlyphs
+ (JNIEnv *env, jobject obj, jintArray codepoints)
+{
+ FT_Face ft_face;
+ jintArray retArray;
+ PangoFcFont *font;
+ jint *values, *cpvals;
+ jint length;
+ int i;
+
+ font = getFont(env, obj);
+
+ ft_face = pango_fc_font_lock_face( font );
+ g_assert (ft_face != NULL);
+
+ length = (*env)->GetArrayLength (env, codepoints);
+ cpvals = (*env)->GetIntArrayElements (env, codepoints, NULL);
+
+ retArray = (*env)->NewIntArray (env, length);
+ values = (*env)->GetIntArrayElements (env, retArray, NULL);
+
+ for( i = 0; i < length; i++ )
+ values[i] = FT_Get_Char_Index( ft_face, cpvals[i] );
+
+ (*env)->ReleaseIntArrayElements (env, retArray, values, 0);
+ (*env)->ReleaseIntArrayElements (env, codepoints, cpvals, 0);
+
+ pango_fc_font_unlock_face (font);
+
+ return retArray;
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_java_awt_peer_gtk_FreetypeGlyphVector_getKerning
+(JNIEnv *env, jobject obj, jint rightGlyph, jint leftGlyph)
+{
+ FT_Face ft_face;
+ FT_Vector kern;
+ jclass cls;
+ jmethodID method;
+ jvalue values[2];
+ PangoFcFont *font;
+
+ font = getFont(env, obj);
+ ft_face = pango_fc_font_lock_face( font );
+ g_assert (ft_face != NULL);
+ FT_Get_Kerning( ft_face, rightGlyph, leftGlyph, FT_KERNING_DEFAULT, &kern );
+
+ pango_fc_font_unlock_face( font );
+
+ values[0].d = (jdouble)kern.x/64.0;
+ values[1].d = (jdouble)kern.y/64.0;
+
+ cls = (*env)->FindClass (env, "java/awt/geom/Point2D$Double");
+ method = (*env)->GetMethodID (env, cls, "<init>", "(DD)V");
+ return (*env)->NewObjectA(env, cls, method, values);
+}
+
+JNIEXPORT jdoubleArray JNICALL
+Java_gnu_java_awt_peer_gtk_FreetypeGlyphVector_getMetricsNative
+(JNIEnv *env, jobject obj, jint glyphIndex )
+{
+ FT_Face ft_face;
+ jdouble *values;
+ jdoubleArray retArray = NULL;
+ PangoFcFont *font;
+
+ font = getFont(env, obj);
+ ft_face = pango_fc_font_lock_face( font );
+
+ g_assert (ft_face != NULL);
+
+ FT_Set_Transform( ft_face, NULL, NULL );
+
+ if( FT_Load_Glyph( ft_face, glyphIndex, FT_LOAD_NO_BITMAP ) != 0 )
+ {
+ pango_fc_font_unlock_face( font );
+ printf("Couldn't load glyph %i\n", glyphIndex);
+ return NULL;
+ }
+
+ retArray = (*env)->NewDoubleArray (env, 8);
+ values = (*env)->GetDoubleArrayElements (env, retArray, NULL);
+
+ values[0] = 0;
+ values[1] = (jdouble)ft_face->glyph->advance.x/64.0;
+ values[2] = (jdouble)ft_face->glyph->advance.y/64.0;
+ values[3] = (jdouble)ft_face->glyph->metrics.horiBearingX/64.0;
+ values[4] = -(jdouble)ft_face->glyph->metrics.horiBearingY/64.0;
+ values[5] = (jdouble)ft_face->glyph->metrics.width/64.0;
+ values[6] = (jdouble)ft_face->glyph->metrics.height/64.0;
+ values[7] = 0;
+
+ (*env)->ReleaseDoubleArrayElements (env, retArray, values, 0);
+ pango_fc_font_unlock_face( font );
+
+ return retArray;
+}
+
+/* GetOutline code follows ****************************/
+/********* Freetype callback functions *****************************/
+
+static int _moveTo( const FT_Vector* to,
+ void *p)
+{
+ JNIEnv *env;
+ jobject obj;
+ jclass cls;
+ jmethodID method;
+ jvalue values[2];
+ generalpath *path = (generalpath *) p;
+
+ env = path->env;
+ obj = path->obj;
+
+ values[0].f = (jfloat)(to->x * path->sx + path->px);
+ values[1].f = (jfloat)(to->y * path->sy + path->py);
+
+ cls = (*env)->FindClass (env, "java/awt/geom/GeneralPath");
+ method = (*env)->GetMethodID (env, cls, "moveTo", "(FF)V");
+ (*env)->CallVoidMethodA(env, obj, method, values );
+
+ return 0;
+}
+
+static int _lineTo( const FT_Vector* to,
+ void *p)
+{
+ JNIEnv *env;
+ jobject obj;
+ jclass cls;
+ jmethodID method;
+ jvalue values[2];
+ generalpath *path = (generalpath *) p;
+
+ env = path->env;
+ obj = path->obj;
+ values[0].f = (jfloat)(to->x * path->sx + path->px);
+ values[1].f = (jfloat)(to->y * path->sy + path->py);
+
+ cls = (*env)->FindClass (env, "java/awt/geom/GeneralPath");
+ method = (*env)->GetMethodID (env, cls, "lineTo", "(FF)V");
+ (*env)->CallVoidMethodA(env, obj, method, values );
+
+ return 0;
+}
+
+static int _quadTo( const FT_Vector* cp,
+ const FT_Vector* to,
+ void *p)
+{
+ JNIEnv *env;
+ jobject obj;
+ jclass cls;
+ jmethodID method;
+ jvalue values[4];
+ generalpath *path = (generalpath *) p;
+
+ env = path->env;
+ obj = path->obj;
+ values[0].f = (jfloat)(cp->x * path->sx + path->px);
+ values[1].f = (jfloat)(cp->y * path->sy + path->py);
+ values[2].f = (jfloat)(to->x * path->sx + path->px);
+ values[3].f = (jfloat)(to->y * path->sy + path->py);
+
+ cls = (*env)->FindClass (env, "java/awt/geom/GeneralPath");
+ method = (*env)->GetMethodID (env, cls, "quadTo", "(FFFF)V");
+ (*env)->CallVoidMethodA(env, obj, method, values );
+
+ return 0;
+}
+
+static int _curveTo( const FT_Vector* cp1,
+ const FT_Vector* cp2,
+ const FT_Vector* to,
+ void *p)
+{
+ JNIEnv *env;
+ jobject obj;
+ jclass cls;
+ jmethodID method;
+ jvalue values[6];
+ generalpath *path = (generalpath *) p;
+
+ env = path->env;
+ obj = path->obj;
+ values[0].f = (jfloat)(cp1->x * path->sx + path->px);
+ values[1].f = (jfloat)(cp1->y * path->sy + path->py);
+ values[2].f = (jfloat)(cp2->x * path->sx + path->px);
+ values[3].f = (jfloat)(cp2->y * path->sy + path->py);
+ values[4].f = (jfloat)(to->x * path->sx + path->px);
+ values[5].f = (jfloat)(to->y * path->sy + path->py);
+
+ cls = (*env)->FindClass (env, "java/awt/geom/GeneralPath");
+ method = (*env)->GetMethodID (env, cls, "curveTo", "(FFFFFF)V");
+ (*env)->CallVoidMethodA(env, obj, method, values );
+
+ return 0;
+}
+
+
+JNIEXPORT jobject JNICALL
+Java_gnu_java_awt_peer_gtk_FreetypeGlyphVector_getGlyphOutlineNative
+ (JNIEnv *env, jobject obj, jint glyphIndex)
+{
+ generalpath *path;
+ jobject gp;
+ FT_Outline_Funcs ftCallbacks =
+ {
+ (FT_Outline_MoveToFunc) _moveTo,
+ (FT_Outline_LineToFunc) _lineTo,
+ (FT_Outline_ConicToFunc) _quadTo,
+ (FT_Outline_CubicToFunc) _curveTo,
+ 0,
+ 0
+ };
+ PangoFcFont *font;
+ FT_Face ft_face;
+ FT_Glyph glyph;
+
+ font = getFont(env, obj);
+ ft_face = pango_fc_font_lock_face( font );
+
+ g_assert (ft_face != NULL);
+
+ path = g_malloc0 (sizeof (generalpath));
+ g_assert(path != NULL);
+ path->env = env;
+
+ path->px = path->py = 0.0;
+ path->sx = 1.0/64.0;
+ path->sy = -1.0/64.0;
+
+ { /* create a GeneralPath instance */
+ jclass cls;
+ jmethodID method;
+
+ cls = (*env)->FindClass (env, "java/awt/geom/GeneralPath");
+ method = (*env)->GetMethodID (env, cls, "<init>", "()V");
+ gp = path->obj = (*env)->NewObject (env, cls, method);
+ }
+
+ if(FT_Load_Glyph(ft_face,
+ (FT_UInt)(glyphIndex),
+ FT_LOAD_DEFAULT | FT_LOAD_NO_BITMAP) != 0)
+ {
+ pango_fc_font_unlock_face( font );
+ g_free(path);
+ return NULL;
+ }
+
+ FT_Get_Glyph( ft_face->glyph, &glyph );
+ FT_Outline_Decompose (&(((FT_OutlineGlyph)glyph)->outline),
+ &ftCallbacks, path);
+ FT_Done_Glyph( glyph );
+
+ pango_fc_font_unlock_face( font );
+
+ g_free(path);
+
+ return gp;
+}
+
+
diff --git a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkFontPeer.c b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkFontPeer.c
index c0f776b20..ddaece1b2 100644
--- a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkFontPeer.c
+++ b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkFontPeer.c
@@ -59,25 +59,11 @@ enum java_awt_font_baseline {
java_awt_font_HANGING_BASELINE = 2
};
-static jmethodID glyphVector_ctor;
-static jclass glyphVector_class;
-static PangoAttrList *attrs = NULL;
-
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkFontPeer_initStaticState
(JNIEnv *env, jclass clazz)
{
NSA_FONT_INIT (env, clazz);
-
- glyphVector_class = (*env)->FindClass
- (env, "gnu/java/awt/peer/gtk/GdkGlyphVector");
-
- glyphVector_class = (*env)->NewGlobalRef
- (env, glyphVector_class);
-
- glyphVector_ctor = (*env)->GetMethodID
- (env, glyphVector_class, "<init>",
- "([D[ILjava/awt/Font;Ljava/awt/font/FontRenderContext;)V");
}
JNIEXPORT void JNICALL
@@ -121,124 +107,26 @@ Java_gnu_java_awt_peer_gtk_GdkFontPeer_dispose
}
-JNIEXPORT jobject JNICALL
-Java_gnu_java_awt_peer_gtk_GdkFontPeer_getGlyphVector
- (JNIEnv *env, jobject self,
- jstring chars,
- jobject font,
- jobject fontRenderContext)
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkFontPeer_releasePeerGraphicsResource
+ (JNIEnv *env, jobject java_font)
{
struct peerfont *pfont = NULL;
- GList *items = NULL;
- GList *i = NULL;
- gchar *str = NULL;
- int len = 0;
- int j = 0;
- double *native_extents = NULL;
- int *native_codes = NULL;
- jintArray java_codes = NULL;
- jdoubleArray java_extents = NULL;
- gdk_threads_enter ();
+ gdk_threads_enter();
- pfont = (struct peerfont *)NSA_GET_FONT_PTR (env, self);
+ pfont = (struct peerfont *) NSA_GET_FONT_PTR (env, java_font);
g_assert (pfont != NULL);
-
- len = (*cp_gtk_gdk_env())->GetStringUTFLength (env, chars);
- str = (gchar *)(*env)->GetStringUTFChars (env, chars, NULL);
- g_assert (str != NULL);
-
- if (attrs == NULL)
- attrs = pango_attr_list_new ();
-
- if (len > 0 && str[len-1] == '\0')
- len--;
-
- items = pango_itemize (pfont->ctx, str, 0, len, attrs, NULL);
-
- i = g_list_first (items);
-
- if (i == NULL)
+ if (pfont->graphics_resource != NULL)
{
- java_extents = (*env)->NewDoubleArray (env, 0);
- java_codes = (*env)->NewIntArray (env, 0);
- }
- else
- {
- PangoGlyphString *glyphs;
- PangoItem *item = (PangoItem *)i->data;
-
- pango_context_set_font_description (pfont->ctx, pfont->desc);
- pango_context_set_language (pfont->ctx, gtk_get_default_language());
- pango_context_load_font (pfont->ctx, pfont->desc);
-
- glyphs = pango_glyph_string_new ();
- g_assert (glyphs != NULL);
-
- pango_shape (str + item->offset, item->length,
- &(item->analysis), glyphs);
-
- if (glyphs->num_glyphs > 0)
- {
- int x = 0;
- double scale = ((double) PANGO_SCALE);
-
- java_extents = (*env)->NewDoubleArray (env, glyphs->num_glyphs * NUM_GLYPH_METRICS);
- java_codes = (*env)->NewIntArray (env, glyphs->num_glyphs);
-
- native_extents = (*env)->GetDoubleArrayElements (env, java_extents, NULL);
- native_codes = (*env)->GetIntArrayElements (env, java_codes, NULL);
-
- for (j = 0; j < glyphs->num_glyphs; ++j)
- {
- PangoRectangle ink;
- PangoRectangle logical;
- PangoGlyphGeometry *geom = &glyphs->glyphs[j].geometry;
-
- pango_font_get_glyph_extents (pfont->font,
- glyphs->glyphs[j].glyph,
- &ink, &logical);
-
- native_codes[j] = glyphs->glyphs[j].glyph;
-
- native_extents[ GLYPH_LOG_X(j) ] = (logical.x) / scale;
- native_extents[ GLYPH_LOG_Y(j) ] = (- logical.y) / scale;
- native_extents[ GLYPH_LOG_WIDTH(j) ] = (logical.width) / scale;
- native_extents[ GLYPH_LOG_HEIGHT(j) ] = (logical.height) / scale;
-
- native_extents[ GLYPH_INK_X(j) ] = (ink.x) / scale;
- native_extents[ GLYPH_INK_Y(j) ] = (- ink.y) / scale;
- native_extents[ GLYPH_INK_WIDTH(j) ] = (ink.width) / scale;
- native_extents[ GLYPH_INK_HEIGHT(j) ] = (ink.height) / scale;
-
- native_extents[ GLYPH_POS_X(j) ] = (x + geom->x_offset) / scale;
- native_extents[ GLYPH_POS_Y(j) ] = ( - geom->y_offset) / scale;
-
- x += geom->width;
- }
- (*env)->ReleaseDoubleArrayElements (env, java_extents, native_extents, 0);
- (*env)->ReleaseIntArrayElements (env, java_codes, native_codes, 0);
- }
-
- pango_glyph_string_free (glyphs);
+ cairo_font_face_destroy ((cairo_font_face_t *) pfont->graphics_resource);
+ pfont->graphics_resource = NULL;
}
- (*env)->ReleaseStringUTFChars (env, chars, str);
-
- for (i = g_list_first (items); i != NULL; i = g_list_next (i))
- pango_item_free(i->data);
-
- g_list_free (items);
-
- gdk_threads_leave ();
-
- return (*env)->NewObject (env,
- glyphVector_class,
- glyphVector_ctor,
- java_extents, java_codes,
- font, fontRenderContext);
+ gdk_threads_leave();
}
+
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkFontPeer_getFontMetrics
(JNIEnv *env, jobject java_font, jdoubleArray java_metrics)
diff --git a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c
deleted file mode 100644
index 56c13b6c1..000000000
--- a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c
+++ /dev/null
@@ -1,1898 +0,0 @@
-/* gnu_java_awt_peer_gtk_GdkGraphics2d.c
- Copyright (C) 2003, 2005, 2006 Free Software Foundation, Inc.
-
-This file is part of GNU Classpath.
-
-GNU Classpath is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU Classpath is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU Classpath; see the file COPYING. If not, write to the
-Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301 USA.
-
-Linking this library statically or dynamically with other modules is
-making a combined work based on this library. Thus, the terms and
-conditions of the GNU General Public License cover the whole
-combination.
-
-As a special exception, the copyright holders of this library give you
-permission to link this library with independent modules to produce an
-executable, regardless of the license terms of these independent
-modules, and to copy and distribute the resulting executable under
-terms of your choice, provided that you also meet, for each linked
-independent module, the terms and conditions of the license of that
-module. An independent module is a module which is not derived from
-or based on this library. If you modify this library, you may extend
-this exception to your version of the library, but you are not
-obligated to do so. If you do not wish to do so, delete this
-exception statement from your version. */
-
-#include "jcl.h"
-#include "gdkfont.h"
-#include "gnu_java_awt_peer_gtk_GdkGraphics2D.h"
-#include <gdk/gdktypes.h>
-#include <gdk/gdkprivate.h>
-#include <gdk/gdkx.h>
-#include <X11/extensions/Xrender.h>
-
-#include <gdk-pixbuf/gdk-pixbuf.h>
-#include <gdk-pixbuf/gdk-pixdata.h>
-
-#include <cairo-ft.h>
-#include <cairo-xlib.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-
-struct state_table *cp_gtk_native_graphics2d_state_table;
-
-/*
- * AWT applications may call Graphics methods from threads other than
- * the GDK main thread, so we must call XFlush after each batch of
- * drawing operations, otherwise animations flicker. Flushing after
- * every graphics operation is excessive and negatively affects
- * performance (PR 26486). We set the maximum frequency to 50 times
- * per second, or a minimum period of 20 milliseconds between calls to
- * XFlush. See gnu.classpath.examples.awt.AnimationApplet for an
- * example applet that requires these XFlush calls.
- */
-
-static short flush_scheduled = 0;
-
-static gboolean flush (gpointer data __attribute__((unused)))
-{
- gdk_threads_enter ();
-
- XFlush (GDK_DISPLAY ());
- flush_scheduled = 0;
-
- gdk_threads_leave ();
-
- return FALSE;
-}
-
-/* The minimum time period between calls to XFlush, in
- milliseconds. */
-#define MINIMUM_FLUSH_PERIOD 20
-
-/* schedule_flush must be called with the GDK lock held. */
-static void
-schedule_flush ()
-{
- if (!flush_scheduled)
- {
- g_timeout_add (MINIMUM_FLUSH_PERIOD, flush, NULL);
- flush_scheduled = 1;
- }
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_initStaticState
- (JNIEnv *env, jclass clazz)
-{
- gdk_threads_enter();
-
- NSA_G2D_INIT (env, clazz);
-
- gdk_threads_leave();
-}
-
-/* these public final constants are part of the java2d public API, so we
- write them explicitly here to save fetching them from the constant pool
- all the time. */
-
-#ifndef min
-#define min(x,y) ((x) < (y) ? (x) : (y))
-#endif
-
-enum java_awt_alpha_composite_rule
- {
- java_awt_alpha_composite_CLEAR = 1,
- java_awt_alpha_composite_SRC = 2,
- java_awt_alpha_composite_SRC_OVER = 3,
- java_awt_alpha_composite_DST_OVER = 4,
- java_awt_alpha_composite_SRC_IN = 5,
- java_awt_alpha_composite_DST_IN = 6,
- java_awt_alpha_composite_SRC_OUT = 7,
- java_awt_alpha_composite_DST_OUT = 8,
- java_awt_alpha_composite_DST = 9,
- java_awt_alpha_composite_SRC_ATOP = 10,
- java_awt_alpha_composite_DST_ATOP = 11,
- java_awt_alpha_composite_XOR = 12
- };
-
-enum java_awt_basic_stroke_join_rule
- {
- java_awt_basic_stroke_JOIN_MITER = 0,
- java_awt_basic_stroke_JOIN_ROUND = 1,
- java_awt_basic_stroke_JOIN_BEVEL = 2
- };
-
-enum java_awt_basic_stroke_cap_rule
- {
- java_awt_basic_stroke_CAP_BUTT = 0,
- java_awt_basic_stroke_CAP_ROUND = 1,
- java_awt_basic_stroke_CAP_SQUARE = 2
- };
-
-enum java_awt_geom_path_iterator_winding_rule
- {
- java_awt_geom_path_iterator_WIND_EVEN_ODD = 0,
- java_awt_geom_path_iterator_WIND_NON_ZERO = 1
- };
-
-enum java_awt_rendering_hints_filter
- {
- java_awt_rendering_hints_VALUE_INTERPOLATION_NEAREST_NEIGHBOR = 0,
- java_awt_rendering_hints_VALUE_INTERPOLATION_BILINEAR = 1,
- java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_SPEED = 2,
- java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_QUALITY = 3,
- java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_DEFAULT = 4
-
- };
-
-static int
-peer_is_disposed(JNIEnv *env, jobject obj)
-{
- static jfieldID fid = NULL;
- jclass cls;
- jobject peer;
-
- if (fid == NULL)
- {
- cls = (*env)->GetObjectClass(env, obj);
- fid = (*env)->GetFieldID(env, cls, "component",
- "Lgnu/java/awt/peer/gtk/GtkComponentPeer;");
- }
- g_assert(fid != NULL);
- peer = (*env)->GetObjectField(env, obj, fid);
- if (peer == NULL || NSA_GET_PTR (env, peer) != NULL)
- return 0;
- else
- return 1;
-}
-
-static void
-grab_current_drawable (GtkWidget *widget, GdkDrawable **draw, GdkWindow **win)
-{
- g_assert (widget != NULL);
- g_assert (draw != NULL);
- g_assert (win != NULL);
-
- *win = widget->window;
-
- *draw = *win;
- gdk_window_get_internal_paint_info (*win, draw, 0, 0);
- g_object_ref (*draw);
-}
-
-
-static int
-x_server_has_render_extension (void)
-{
- int ev = 0, err = 0;
- return (int) XRenderQueryExtension (GDK_DISPLAY (), &ev, &err);
-}
-
-static void
-init_graphics2d_as_pixbuf (struct graphics2d *gr)
-{
- gint width, height;
- gint bits_per_sample = 8;
- gint total_channels = 4;
- gboolean has_alpha = TRUE;
-
- g_assert (gr != NULL);
- g_assert (gr->drawable != NULL);
-
- if (gr->debug) printf ("initializing graphics2d as pixbuf\n");
- gdk_drawable_get_size (gr->drawable, &width, &height);
- gr->drawbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
- has_alpha, bits_per_sample,
- width, height);
- g_assert (gr->drawbuf != NULL);
- g_assert (gdk_pixbuf_get_bits_per_sample (gr->drawbuf) == bits_per_sample);
- g_assert (gdk_pixbuf_get_n_channels (gr->drawbuf) == total_channels);
-
- gr->surface = cairo_image_surface_create_for_data (gdk_pixbuf_get_pixels (gr->drawbuf),
- CAIRO_FORMAT_ARGB32,
- gdk_pixbuf_get_width (gr->drawbuf),
- gdk_pixbuf_get_height (gr->drawbuf),
- gdk_pixbuf_get_rowstride (gr->drawbuf));
- g_assert (gr->surface != NULL);
- gr->mode = MODE_DRAWABLE_NO_RENDER;
- if (gr->cr != NULL)
- cairo_destroy (gr->cr);
- gr->cr = cairo_create (gr->surface);
-}
-
-static void
-init_graphics2d_as_renderable (struct graphics2d *gr)
-{
- Drawable draw;
- Display * dpy;
- Visual * vis;
-
- g_assert (gr != NULL);
- g_assert (gr->drawable != NULL);
-
- gr->drawbuf = NULL;
-
- if (gr->debug) printf ("initializing graphics2d as renderable\n");
- draw = gdk_x11_drawable_get_xid (gr->drawable);
-
- dpy = gdk_x11_drawable_get_xdisplay (gr->drawable);
- g_assert (dpy != NULL);
-
- vis = gdk_x11_visual_get_xvisual (gdk_drawable_get_visual (gr->drawable));
- g_assert (vis != NULL);
-
- gr->surface = cairo_xlib_surface_create (dpy, draw, vis, gr->width, gr->height);
- g_assert (gr->surface != NULL);
- gr->mode = MODE_DRAWABLE_WITH_RENDER;
- if (gr->cr != NULL)
- cairo_destroy (gr->cr);
- gr->cr = cairo_create (gr->surface);
-}
-
-static void
-begin_drawing_operation (JNIEnv *env, struct graphics2d * gr)
-{
- cairo_status_t cst = cairo_status (gr->cr);
- if (cst != CAIRO_STATUS_SUCCESS)
- {
- const char *detail = cairo_status_to_string (cst);
- JCL_ThrowException (env, "java/lang/InternalError", detail);
- (*env)->ExceptionDescribe (env);
- return;
- }
-
- switch (gr->mode)
- {
- case MODE_DRAWABLE_WITH_RENDER:
- break;
-
- case MODE_DRAWABLE_NO_RENDER:
- {
-
- gint drawable_width, drawable_height;
- gint pixbuf_width, pixbuf_height;
- gint width, height;
-
- gdk_drawable_get_size (gr->drawable, &drawable_width, &drawable_height);
- pixbuf_width = gdk_pixbuf_get_width (gr->drawbuf);
- pixbuf_height = gdk_pixbuf_get_height (gr->drawbuf);
- width = min (drawable_width, pixbuf_width);
- height = min (drawable_height, pixbuf_height);
-
- gdk_pixbuf_get_from_drawable (gr->drawbuf, /* destination pixbuf */
- gr->drawable,
- NULL, /* colormap */
- 0, 0, 0, 0,
- width, height);
-
- if (gr->debug) printf ("copied (%d, %d) pixels from GDK drawable to pixbuf\n",
- width, height);
- }
- break;
-
- case MODE_JAVA_ARRAY:
- {
- jboolean isCopy;
- gr->javabuf = (*env)->GetPrimitiveArrayCritical (env, gr->jarray, &isCopy);
- gr->isCopy |= isCopy;
- if (gr->isCopy)
- {
- /* Make sure that the pixel buffer copy is already initalized,
- i.e. we already failed to get direct access in initState. */
- g_assert (gr->javabuf_copy != NULL);
- memcpy (gr->javabuf_copy, gr->javabuf, gr->width * gr->height * 4);
- }
- }
- break;
- }
-}
-
-static void
-end_drawing_operation (JNIEnv *env, struct graphics2d * gr)
-{
- cairo_status_t cst = cairo_status (gr->cr);
- if (cst != CAIRO_STATUS_SUCCESS)
- {
- /* Report error. */
- const char *detail = cairo_status_to_string (cst);
- JCL_ThrowException (env, "java/lang/InternalError", detail);
- (*env)->ExceptionDescribe (env);
-
- /* Recreate cairo status. */
- cairo_destroy (gr->cr);
- gr->cr = cairo_create (gr->surface);
- return;
- }
-
- switch (gr->mode)
- {
- case MODE_DRAWABLE_WITH_RENDER:
- break;
-
- case MODE_DRAWABLE_NO_RENDER:
- {
-
- gint drawable_width, drawable_height;
- gint pixbuf_width, pixbuf_height;
- gint width, height;
-
- gdk_drawable_get_size (gr->drawable, &drawable_width, &drawable_height);
- pixbuf_width = gdk_pixbuf_get_width (gr->drawbuf);
- pixbuf_height = gdk_pixbuf_get_height (gr->drawbuf);
- width = min (drawable_width, pixbuf_width);
- height = min (drawable_height, pixbuf_height);
-
- gdk_draw_pixbuf (gr->drawable, NULL, gr->drawbuf,
- 0, 0, 0, 0,
- width, height,
- GDK_RGB_DITHER_NORMAL, 0, 0);
-
- if (gr->debug) printf ("copied (%d, %d) pixels from pixbuf to GDK drawable\n",
- width, height);
- }
- break;
-
- case MODE_JAVA_ARRAY:
- if (gr->isCopy)
- memcpy (gr->javabuf, gr->javabuf_copy, gr->width * gr->height * 4);
- (*env)->ReleasePrimitiveArrayCritical (env, gr->jarray, gr->javabuf, JNI_COMMIT);
- }
-
- schedule_flush ();
-}
-
-
-static void
-update_pattern_transform (struct graphics2d *gr)
-{
- cairo_matrix_t mat;
-
- g_assert (gr != NULL);
- if (gr->pattern == NULL)
- return;
-
- cairo_get_matrix (gr->cr, &mat);
- cairo_pattern_set_matrix (gr->pattern, &mat);
-}
-
-static void
-check_for_debug (struct graphics2d *gr)
-{
- gr->debug = (gboolean)(getenv("DEBUGJ2D") != NULL);
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_copyState
- (JNIEnv *env, jobject obj, jobject old)
-{
- struct graphics2d *g = NULL, *g_old = NULL;
-
- gdk_threads_enter();
-
- g = (struct graphics2d *) g_malloc (sizeof (struct graphics2d));
- g_assert (g != NULL);
- memset (g, 0, sizeof(struct graphics2d));
-
- g_old = (struct graphics2d *) NSA_GET_G2D_PTR (env, old);
- g_assert (g_old != NULL);
-
- if (g_old->debug) printf ("copying state from existing graphics2d\n");
-
- g->debug = g_old->debug;
- g->mode = g_old->mode;
-
- g->width = g_old->width;
- g->height = g_old->height;
-
- if (g_old->mode == MODE_JAVA_ARRAY)
- {
- jint size = g->width * g->height * 4;
-
- g->jarray = (*env)->NewGlobalRef (env, g_old->jarray);
- g->javabuf = (*env)->GetIntArrayElements (env, g->jarray, &g->isCopy);
- g->isCopy = JNI_TRUE;
- g->javabuf_copy = (jint *) g_malloc (size);
- memcpy (g->javabuf_copy, g->javabuf, size);
- g->surface = cairo_image_surface_create_for_data ((unsigned char *) g->javabuf,
- CAIRO_FORMAT_ARGB32,
- g->width,
- g->height,
- g->width * 4);
- g_assert (g->surface != NULL);
- g->cr = cairo_create (g->surface);
- g_assert (g->cr != NULL);
- (*env)->ReleaseIntArrayElements (env, g->jarray, g->javabuf, JNI_ABORT);
- }
- else
- {
- g->drawable = g_old->drawable;
- g_object_ref (g->drawable);
-
- if (x_server_has_render_extension ())
- init_graphics2d_as_renderable (g);
- else
- init_graphics2d_as_pixbuf (g);
- }
-
- if (g->pattern)
- cairo_pattern_set_filter (g->pattern, CAIRO_FILTER_FAST);
-
- NSA_SET_G2D_PTR (env, obj, g);
-
- gdk_threads_leave();
-}
-
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_initState___3III
-(JNIEnv *env, jobject obj, jintArray jarr, jint width, jint height)
-{
- struct graphics2d *gr = NULL;
- jint *cairobuf = NULL;
-
- gdk_threads_enter();
-
- gr = (struct graphics2d *) g_malloc (sizeof (struct graphics2d));
- g_assert (gr != NULL);
- memset (gr, 0, sizeof(struct graphics2d));
-
- check_for_debug (gr);
-
- if (gr->debug) printf ("constructing java-backed image of size (%d,%d)\n",
- width, height);
-
- gr->width = width;
- gr->height = height;
- gr->jarray = (*env)->NewGlobalRef(env, jarr);
- gr->javabuf = (*env)->GetPrimitiveArrayCritical (env, gr->jarray, &gr->isCopy);
- if (gr->isCopy)
- {
- /* We didn't get direct access to the pixel buffer, so we'll have to
- maintain a separate copy for Cairo. */
- jint size = gr->width * gr->height * 4;
- gr->javabuf_copy = (jint *) g_malloc (size);
- memcpy (gr->javabuf_copy, gr->javabuf, size);
- cairobuf = gr->javabuf_copy;
- }
- else
- {
- /* Have Cairo write directly to the Java array. */
- cairobuf = gr->javabuf;
- }
- gr->surface = cairo_image_surface_create_for_data ((unsigned char *) cairobuf,
- CAIRO_FORMAT_ARGB32,
- gr->width,
- gr->height,
- gr->width * 4);
- g_assert (gr->surface != NULL);
- gr->cr = cairo_create (gr->surface);
- g_assert (gr->cr != NULL);
- (*env)->ReleasePrimitiveArrayCritical (env, gr->jarray, gr->javabuf, JNI_COMMIT);
-
- gr->mode = MODE_JAVA_ARRAY;
-
- if (gr->debug) printf ("constructed java-backed image of size (%d,%d)\n",
- width, height);
-
- NSA_SET_G2D_PTR (env, obj, gr);
-
- gdk_threads_leave();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_initState__II
- (JNIEnv *env, jobject obj, jint width, jint height)
-{
- struct graphics2d *gr = NULL;
-
- gdk_threads_enter();
-
- gr = (struct graphics2d *) g_malloc (sizeof (struct graphics2d));
- g_assert (gr != NULL);
- memset (gr, 0, sizeof(struct graphics2d));
-
- check_for_debug (gr);
-
- if (gr->debug) printf ("constructing offscreen drawable of size (%d,%d)\n",
- width, height);
-
- gr->drawable = (GdkDrawable *) gdk_pixmap_new (NULL, width, height,
- gdk_rgb_get_visual ()->depth);
- g_assert (gr->drawable != NULL);
-
- gr->width = width;
- gr->height = height;
-
- if (x_server_has_render_extension ())
- init_graphics2d_as_renderable (gr);
- else
- init_graphics2d_as_pixbuf (gr);
-
- if (gr->debug) printf ("constructed offscreen drawable of size (%d,%d)\n",
- width, height);
- NSA_SET_G2D_PTR (env, obj, gr);
-
- gdk_threads_leave();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_gdkDrawDrawable
- (JNIEnv *env, jobject obj, jobject other, jint x, jint y)
-{
- struct graphics2d *src = NULL;
- struct graphics2d *dst = NULL;
- gint s_height;
- gint s_width;
- gint d_height;
- gint d_width;
- gint height;
- gint width;
- cairo_matrix_t matrix;
- cairo_operator_t tmp_op;
-
- gdk_threads_enter();
-
- if (peer_is_disposed(env, obj))
- {
- gdk_threads_leave();
- return;
- }
-
- src = (struct graphics2d *)NSA_GET_G2D_PTR (env, other);
- dst = (struct graphics2d *)NSA_GET_G2D_PTR (env, obj);
- g_assert (src != NULL);
- g_assert (dst != NULL);
-
- if (src->debug) printf ("copying from offscreen drawable\n");
-
- begin_drawing_operation(env, dst);
-
- /* gdk_flush(); */
-
- if (!GDK_IS_DRAWABLE (src->drawable) ||
- !GDK_IS_DRAWABLE (dst->drawable))
- {
- gdk_threads_leave ();
- return;
- }
-
- gdk_drawable_get_size (src->drawable, &s_width, &s_height);
- gdk_drawable_get_size (dst->drawable, &d_width, &d_height);
- width = min (s_width, d_width);
- height = min (s_height, d_height);
-
- cairo_get_matrix (src->cr, &matrix);
- cairo_matrix_translate (&matrix, (double)-x, (double)-y);
- if (src->pattern)
- cairo_pattern_set_matrix (src->pattern, &matrix);
- tmp_op = cairo_get_operator (dst->cr);
- cairo_set_operator(dst->cr, CAIRO_OPERATOR_SOURCE);
- cairo_set_source_surface (dst->cr, src->surface, 0, 0);
- cairo_paint (dst->cr);
- cairo_set_operator(dst->cr, tmp_op);
-
- cairo_matrix_translate (&matrix, (double)x, (double)y);
- if (src->pattern)
- cairo_pattern_set_matrix (src->pattern, &matrix);
-
- end_drawing_operation(env, dst);
-
- if (src->debug) printf ("copied %d x %d pixels from offscreen drawable\n", width, height);
-
- gdk_threads_leave();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_initState__Lgnu_java_awt_peer_gtk_GtkComponentPeer_2
- (JNIEnv *env, jobject obj, jobject peer)
-{
- struct graphics2d *gr = NULL;
- GtkWidget *widget = NULL;
- void *ptr = NULL;
-
- gdk_threads_enter();
-
- if (peer_is_disposed(env, obj))
- {
- gdk_threads_leave();
- return;
- }
-
- ptr = NSA_GET_PTR (env, peer);
- g_assert (ptr != NULL);
-
- gr = (struct graphics2d *) g_malloc (sizeof (struct graphics2d));
- g_assert (gr != NULL);
- memset (gr, 0, sizeof(struct graphics2d));
-
- check_for_debug (gr);
-
- widget = GTK_WIDGET (ptr);
- g_assert (widget != NULL);
-
- grab_current_drawable (widget, &(gr->drawable), &(gr->win));
- g_assert (gr->drawable != NULL);
-
- gr->width = widget->allocation.width;
- gr->height = widget->allocation.height;
-
- if (x_server_has_render_extension ())
- init_graphics2d_as_renderable (gr);
- else
- init_graphics2d_as_pixbuf (gr);
-
- NSA_SET_G2D_PTR (env, obj, gr);
-
- gdk_threads_leave();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_dispose
- (JNIEnv *env, jobject obj)
-{
- struct graphics2d *gr = NULL;
-
- gr = (struct graphics2d *) NSA_DEL_G2D_PTR (env, obj);
-
- /* dispose has been called more than once */
- if (gr == NULL)
- return;
-
- gdk_threads_enter();
-
- if (peer_is_disposed(env, obj))
- {
- gdk_threads_leave();
- return;
- }
-
- if (gr->surface)
- cairo_surface_destroy (gr->surface);
- gr->surface = NULL;
-
- cairo_destroy (gr->cr);
- gr->cr = NULL;
-
- if (gr->drawbuf)
- g_object_unref (gr->drawbuf);
- gr->drawbuf = NULL;
-
- if (gr->drawable)
- g_object_unref (gr->drawable);
- gr->drawable = NULL;
-
- if (gr->pattern)
- cairo_pattern_destroy (gr->pattern);
- gr->pattern = NULL;
-
- if (gr->pattern_surface)
- cairo_surface_destroy (gr->pattern_surface);
- gr->pattern_surface = NULL;
-
- if (gr->pattern_pixels)
- g_free (gr->pattern_pixels);
- gr->pattern_pixels = NULL;
-
- if (gr->mode == MODE_JAVA_ARRAY)
- {
- (*env)->DeleteGlobalRef (env, gr->jarray);
- if (gr->javabuf_copy)
- g_free (gr->javabuf_copy);
- gr->javabuf_copy = NULL;
- }
-
- if (gr->debug) printf ("disposed of graphics2d\n");
-
- g_free (gr);
-
- gdk_threads_leave();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_setGradient
- (JNIEnv *env, jobject obj,
- jdouble x1, jdouble y1,
- jdouble x2, jdouble y2,
- jint r1, jint g1, jint b1, jint a1,
- jint r2, jint g2, jint b2, jint a2,
- jboolean cyclic)
-{
- struct graphics2d *gr = NULL;
- cairo_surface_t *surf = NULL;
- cairo_t *cr2 = NULL;
- cairo_matrix_t mat;
-
- gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
- g_assert (gr != NULL);
-
- gdk_threads_enter();
-
- if (peer_is_disposed(env, obj))
- {
- gdk_threads_leave();
- return;
- }
-
- if (gr->debug)
- printf ("setGradient (%f,%f) -> (%f,%f); (%d,%d,%d,%d) -> (%d,%d,%d,%d)\n",
- x1, y1,
- x2, y2,
- r1, g1, b1, a1,
- r2, g2, b2, a2);
-
- if (cyclic)
- surf = cairo_surface_create_similar (gr->surface, CAIRO_FORMAT_ARGB32, 3, 2);
- else
- surf = cairo_surface_create_similar (gr->surface, CAIRO_FORMAT_ARGB32, 2, 2);
- g_assert (surf != NULL);
-
- cr2 = cairo_create (surf);
-
- cairo_identity_matrix (cr2);
-
- cairo_set_source_rgba (cr2, r1 / 255.0, g1 / 255.0, b1 / 255.0, a1 / 255.0);
- cairo_rectangle (cr2, 0, 0, 1, 2);
- cairo_fill (cr2);
-
- cairo_set_source_rgba (cr2, r2 / 255.0, g2 / 255.0, b2 / 255.0, a2 / 255.0);
- cairo_rectangle (cr2, 1, 0, 1, 2);
- cairo_fill (cr2);
-
- if (cyclic)
- {
- cairo_set_source_rgba (cr2, r1 / 255.0, g1 / 255.0, b1 / 255.0, a1 / 255.0);
- cairo_rectangle (cr2, 2, 0, 1, 2);
- cairo_fill (cr2);
- }
-
- cairo_matrix_init_identity (&mat);
-
- /*
- consider the vector [x2 - x1, y2 - y1] = [p,q]
-
- this is a line in space starting at an 'origin' x1, y1.
-
- it can also be thought of as a "transformed" unit vector in either the
- x or y directions. we have just *drawn* our gradient as a unit vector
- (well, a 2-3x unit vector) in the x dimension. so what we want to know
- is which transformation turns our existing unit vector into [p,q].
-
- which means solving for M in
-
- [p,q] = M[1,0]
-
- [p,q] = |a b| [1,0]
- |c d|
-
- [p,q] = [a,c], with b = d = 0.
-
- what does this mean? it means that our gradient is 1-dimensional; as
- you move through the x axis of our 2 or 3 pixel gradient from logical
- x positions 0 to 1, the transformation of your x coordinate under the
- matrix M causes you to accumulate both x and y values in fill
- space. the y value of a gradient coordinate is ignored, since the
- gradient is one dimensional. which is correct.
-
- unfortunately we want the opposite transformation, it seems, because of
- the way cairo is going to use this transformation. I'm a bit confused by
- that, but it seems to work right, so we take reciprocals of values and
- negate offsets. oh well.
-
- */
- {
- double a = (x2 - x1 == 0.) ? 0. : ((cyclic ? 3.0 : 2.0) / (x2 - x1));
- double c = (y2 - y1 == 0.) ? 0. : (1. / (y2 - y1));
- double dx = (x1 == 0.) ? 0. : 1. / x1;
- double dy = (y1 == 0.) ? 0. : 1. / y1;
- cairo_pattern_t *p;
-
- cairo_matrix_init (&mat,
- a, 0.,
- c, 0.,
- dx, dy);
-
- p = cairo_pattern_create_for_surface (surf);
- cairo_pattern_set_matrix (p, &mat);
- cairo_pattern_set_filter (p, CAIRO_FILTER_BILINEAR);
- }
-
- /* FIXME: repeating gradients (not to mention hold gradients) don't seem to work. */
- /* cairo_surface_set_repeat (surf, cyclic ? 1 : 0); */
-
- if (gr->pattern)
- cairo_pattern_destroy (gr->pattern);
-
- if (gr->pattern_surface)
- cairo_surface_destroy (gr->pattern_surface);
-
- if (gr->pattern_pixels)
- g_free (gr->pattern_pixels);
-
- gr->pattern_pixels = NULL;
- gr->pattern_surface = surf;
- gr->pattern = cairo_pattern_create_for_surface(surf);
-
- cairo_set_source (gr->cr, gr->pattern);
-
- gdk_threads_leave();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_setTexturePixels
- (JNIEnv *env, jobject obj, jintArray jarr, jint w, jint h, jint stride)
-{
- struct graphics2d *gr = NULL;
- jint *jpixels = NULL;
-
- gdk_threads_enter();
-
- if (peer_is_disposed(env, obj))
- {
- gdk_threads_leave();
- return;
- }
-
- gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
- g_assert (gr != NULL);
-
- if (gr->debug)
- printf ("setTexturePixels (%d pixels, %dx%d, stride: %d)\n",
- (*env)->GetArrayLength (env, jarr), w, h, stride);
-
- if (gr->pattern)
- cairo_pattern_destroy (gr->pattern);
-
- if (gr->pattern_surface)
- cairo_surface_destroy (gr->pattern_surface);
-
- if (gr->pattern_pixels)
- g_free (gr->pattern_pixels);
-
- gr->pattern = NULL;
- gr->pattern_surface = NULL;
- gr->pattern_pixels = NULL;
-
- gr->pattern_pixels = (char *) g_malloc (h * stride * 4);
- g_assert (gr->pattern_pixels != NULL);
-
- jpixels = (*env)->GetIntArrayElements (env, jarr, NULL);
- g_assert (jpixels != NULL);
- memcpy (gr->pattern_pixels, jpixels, h * stride * 4);
- (*env)->ReleaseIntArrayElements (env, jarr, jpixels, 0);
-
- gr->pattern_surface = cairo_image_surface_create_for_data ((unsigned char *)gr->pattern_pixels,
- CAIRO_FORMAT_ARGB32,
- w, h, stride * 4);
- g_assert (gr->pattern_surface != NULL);
- gr->pattern = cairo_pattern_create_for_surface (gr->pattern_surface);
- g_assert (gr->pattern != NULL);
- cairo_pattern_set_extend (gr->pattern, CAIRO_EXTEND_REPEAT);
- cairo_set_source (gr->cr, gr->pattern);
-
- gdk_threads_leave();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_drawPixels
- (JNIEnv *env, jobject obj, jintArray java_pixels,
- jint w, jint h, jint stride, jdoubleArray java_matrix)
-{
- struct graphics2d *gr = NULL;
- jint *native_pixels = NULL;
- jdouble *native_matrix = NULL;
-
- gdk_threads_enter();
-
- if (peer_is_disposed(env, obj))
- {
- gdk_threads_leave();
- return;
- }
-
- gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
- g_assert (gr != NULL);
-
- if (gr->debug)
- printf ("drawPixels (%d pixels, %dx%d, stride: %d)\n",
- (*env)->GetArrayLength (env, java_pixels), w, h, stride);
-
- native_pixels = (*env)->GetIntArrayElements (env, java_pixels, NULL);
- native_matrix = (*env)->GetDoubleArrayElements (env, java_matrix, NULL);
- g_assert (native_pixels != NULL);
- g_assert (native_matrix != NULL);
- g_assert ((*env)->GetArrayLength (env, java_matrix) == 6);
-
- begin_drawing_operation (env, gr);
-
- {
- cairo_matrix_t mat;
- cairo_pattern_t *p;
- cairo_surface_t *surf = cairo_image_surface_create_for_data ((unsigned char *)native_pixels,
- CAIRO_FORMAT_ARGB32,
- w, h, stride * 4);
- cairo_matrix_init_identity (&mat);
- cairo_matrix_init (&mat,
- native_matrix[0], native_matrix[1],
- native_matrix[2], native_matrix[3],
- native_matrix[4], native_matrix[5]);
-
- p = cairo_pattern_create_for_surface (surf);
- cairo_pattern_set_matrix (p, &mat);
- if (gr->pattern)
- cairo_pattern_set_filter (p, cairo_pattern_get_filter (gr->pattern));
- cairo_set_source (gr->cr, p);
- cairo_paint (gr->cr);
- cairo_pattern_destroy (p);
- cairo_surface_destroy (surf);
- }
-
- end_drawing_operation (env, gr);
-
- (*env)->ReleaseIntArrayElements (env, java_pixels, native_pixels, 0);
- (*env)->ReleaseDoubleArrayElements (env, java_matrix, native_matrix, 0);
-
- gdk_threads_leave();
-}
-
-/* passthrough methods to cairo */
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSave
- (JNIEnv *env, jobject obj)
-{
- struct graphics2d *gr = NULL;
-
- gdk_threads_enter();
-
- if (peer_is_disposed(env, obj))
- {
- gdk_threads_leave();
- return;
- }
-
- gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
- g_assert (gr != NULL);
- if (gr->debug) printf ("cairo_save\n");
- cairo_save (gr->cr);
-
- gdk_threads_leave();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoRestore
- (JNIEnv *env, jobject obj)
-{
- struct graphics2d *gr = NULL;
-
- gdk_threads_enter();
-
- if (peer_is_disposed(env, obj))
- {
- gdk_threads_leave();
- return;
- }
-
- gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
- g_assert (gr != NULL);
- if (gr->debug) printf ("cairo_restore\n");
- cairo_restore (gr->cr);
- update_pattern_transform (gr);
-
- gdk_threads_leave();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetMatrix
- (JNIEnv *env, jobject obj, jdoubleArray java_matrix)
-{
- struct graphics2d *gr = NULL;
- jdouble *native_matrix = NULL;
-
- gdk_threads_enter();
-
- if (peer_is_disposed(env, obj))
- {
- gdk_threads_leave();
- return;
- }
-
- gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
-
- native_matrix = (*env)->GetDoubleArrayElements (env, java_matrix, NULL);
- g_assert (native_matrix != NULL);
- g_assert ((*env)->GetArrayLength (env, java_matrix) == 6);
-
- if (gr->debug)
- printf ("cairo_matrix_init [ %f, %f, %f, %f, %f, %f ]\n",
- native_matrix[0], native_matrix[1],
- native_matrix[2], native_matrix[3],
- native_matrix[4], native_matrix[5]);
-
- {
- cairo_matrix_t mat;
-
- cairo_matrix_init_identity (&mat);
- cairo_matrix_init (&mat,
- native_matrix[0], native_matrix[1],
- native_matrix[2], native_matrix[3],
- native_matrix[4], native_matrix[5]);
- cairo_set_matrix (gr->cr, &mat);
- }
-
- (*env)->ReleaseDoubleArrayElements (env, java_matrix, native_matrix, 0);
- update_pattern_transform (gr);
-
- gdk_threads_leave();
-}
-
-static void
-install_font_peer(cairo_t *cr,
- struct peerfont *pfont,
- int debug)
-{
- cairo_font_face_t *ft;
- FT_Face face = NULL;
-
- g_assert(cr != NULL);
- g_assert(pfont != NULL);
-
- if (pfont->graphics_resource == NULL)
- {
- face = pango_ft2_font_get_face (pfont->font);
- g_assert (face != NULL);
-
- ft = cairo_ft_font_face_create_for_ft_face (face, 0);
- g_assert (ft != NULL);
-
- if (debug) printf ("install_font_peer made new cairo font for '%s' at %f\n",
- face->family_name,
- (pango_font_description_get_size (pfont->desc) /
- (double)PANGO_SCALE));
-
- cairo_set_font_face (cr, ft);
- cairo_font_face_destroy (ft);
- cairo_set_font_size (cr,
- (pango_font_description_get_size (pfont->desc) /
- (double)PANGO_SCALE));
- ft = cairo_get_font_face (cr);
- pfont->graphics_resource = ft;
- }
- else
- {
- if (debug) printf ("install_font_peer reused existing font resource"
- " for '%s' at %f\n",
- pango_font_description_get_family(pfont->desc),
- (pango_font_description_get_size (pfont->desc) /
- (double)PANGO_SCALE));
- ft = (cairo_font_face_t *) pfont->graphics_resource;
- cairo_set_font_face (cr, ft);
- cairo_set_font_size (cr,
- (pango_font_description_get_size (pfont->desc) /
- (double)PANGO_SCALE));
- }
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_releasePeerGraphicsResource
- (JNIEnv *env, jclass clazz __attribute__ ((unused)), jobject java_font)
-{
- struct peerfont *pfont = NULL;
-
- gdk_threads_enter();
-
- g_assert(java_font != NULL);
-
- pfont = (struct peerfont *) NSA_GET_FONT_PTR (env, java_font);
- g_assert (pfont != NULL);
- if (pfont->graphics_resource != NULL)
- {
- cairo_font_face_destroy ((cairo_font_face_t *) pfont->graphics_resource);
- pfont->graphics_resource = NULL;
- }
-
- gdk_threads_leave();
-}
-
-static void
-paint_glyph_run(JNIEnv *env,
- struct graphics2d *gr,
- cairo_glyph_t **glyphs,
- gint *n_glyphs,
- PangoLayoutRun *run)
-{
- gint i = 0;
- gint x = 0, y = 0;
-
- g_assert (gr != NULL);
- g_assert (glyphs != NULL);
- g_assert (n_glyphs != NULL);
- g_assert (run != NULL);
-
- if (run->glyphs != NULL && run->glyphs->num_glyphs > 0)
- {
- if (*n_glyphs < run->glyphs->num_glyphs)
- {
- *glyphs = g_realloc(*glyphs,
- (sizeof(cairo_glyph_t)
- * run->glyphs->num_glyphs));
- *n_glyphs = run->glyphs->num_glyphs;
- }
-
- g_assert (*glyphs != NULL);
-
- if (gr->debug) printf ("painting %d glyphs: ", run->glyphs->num_glyphs);
-
- for (i = 0; i < run->glyphs->num_glyphs; ++i)
- {
- (*glyphs)[i].index = run->glyphs->glyphs[i].glyph;
-
- (*glyphs)[i].x =
- ((double) (x + run->glyphs->glyphs[i].geometry.x_offset))
- / ((double) PANGO_SCALE);
-
- (*glyphs)[i].y =
- ((double) (y + run->glyphs->glyphs[i].geometry.y_offset))
- / ((double) PANGO_SCALE);
-
- if (gr->debug) printf(" (%ld @ %f,%f)",
- (*glyphs)[i].index,
- (*glyphs)[i].x,
- (*glyphs)[i].y);
-
- x += run->glyphs->glyphs[i].geometry.width;
- }
-
- if (gr->debug) printf("\n");
- begin_drawing_operation (env, gr);
- cairo_show_glyphs (gr->cr, *glyphs, run->glyphs->num_glyphs);
- end_drawing_operation (env, gr);
- }
-}
-
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoDrawGlyphVector
- (JNIEnv *env, jobject obj,
- jobject font,
- jfloat x, jfloat y, jint n,
- jintArray java_codes,
- jfloatArray java_positions)
-{
-
- struct graphics2d *gr = NULL;
- struct peerfont *pfont = NULL;
- cairo_glyph_t *glyphs = NULL;
- int *native_codes;
- float *native_positions;
- jint i = 0;
-
- gdk_threads_enter ();
-
- if (peer_is_disposed(env, obj))
- {
- gdk_threads_leave();
- return;
- }
-
- g_assert (obj != NULL);
- g_assert (java_codes != NULL);
- g_assert (java_positions != NULL);
-
- gr = (struct graphics2d *)NSA_GET_G2D_PTR (env, obj);
- g_assert (gr != NULL);
-
- pfont = (struct peerfont *)NSA_GET_FONT_PTR (env, font);
- g_assert (pfont != NULL);
-
- install_font_peer(gr->cr, pfont, gr->debug);
-
- glyphs = g_malloc( sizeof(cairo_glyph_t) * n);
- g_assert (glyphs != NULL);
-
- native_codes = (*env)->GetIntArrayElements (env, java_codes, NULL);
- native_positions = (*env)->GetFloatArrayElements (env, java_positions, NULL);
-
- for (i = 0; i < n; ++i)
- {
- glyphs[i].index = native_codes[i];
- glyphs[i].x = x + native_positions[ 2*i ];
- glyphs[i].y = y + native_positions[ 2*i + 1];
- }
-
- (*env)->ReleaseFloatArrayElements (env, java_positions, native_positions, 0);
- (*env)->ReleaseIntArrayElements (env, java_codes, native_codes, 0);
-
- begin_drawing_operation (env, gr);
- cairo_show_glyphs (gr->cr, glyphs, n);
- end_drawing_operation (env, gr);
-
- g_free(glyphs);
-
- gdk_threads_leave ();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoDrawGdkTextLayout
- (JNIEnv *env, jobject obj, jobject java_layout, jfloat x, jfloat y)
-{
- /*
- * FIXME: Some day we expect either cairo or pango will know how to make
- * a pango layout paint to a cairo surface. that day is not yet here.
- */
-
- struct graphics2d *gr = NULL;
- struct textlayout *tl = NULL;
- PangoLayoutIter *i = NULL;
- PangoLayoutRun *run = NULL;
- cairo_glyph_t *glyphs = NULL;
- gint n_glyphs = 0;
-
- g_assert (obj != NULL);
- g_assert (java_layout != NULL);
-
- gr = (struct graphics2d *)NSA_GET_G2D_PTR (env, obj);
- tl = (struct textlayout *)NSA_GET_TEXT_LAYOUT_PTR (env, java_layout);
-
- g_assert (gr != NULL);
- g_assert (tl != NULL);
- g_assert (tl->pango_layout != NULL);
-
- if (gr->debug) printf ("painting pango layout\n");
-
- gdk_threads_enter ();
-
- if (peer_is_disposed(env, obj))
- {
- gdk_threads_leave();
- return;
- }
-
- i = pango_layout_get_iter (tl->pango_layout);
- g_assert (i != NULL);
-
- cairo_translate (gr->cr, x, y);
-
- do
- {
- run = pango_layout_iter_get_run (i);
- if (run != NULL)
- paint_glyph_run (env, gr, &glyphs, &n_glyphs, run);
- }
- while (pango_layout_iter_next_run (i));
-
- if (glyphs != NULL)
- g_free (glyphs);
-
- cairo_translate (gr->cr, -x, -y);
-
- pango_layout_iter_free (i);
-
- gdk_threads_leave ();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetOperator
- (JNIEnv *env, jobject obj, jint op)
-{
- struct graphics2d *gr = NULL;
-
- gdk_threads_enter();
-
- if (peer_is_disposed(env, obj))
- {
- gdk_threads_leave();
- return;
- }
-
- gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
- g_assert (gr != NULL);
- if (gr->debug) printf ("cairo_set_operator %d\n", op);
- switch ((enum java_awt_alpha_composite_rule) op)
- {
- case java_awt_alpha_composite_CLEAR:
- cairo_set_operator (gr->cr, CAIRO_OPERATOR_CLEAR);
- break;
-
- case java_awt_alpha_composite_SRC:
- cairo_set_operator (gr->cr, CAIRO_OPERATOR_SOURCE);
- break;
-
- case java_awt_alpha_composite_SRC_OVER:
- cairo_set_operator (gr->cr, CAIRO_OPERATOR_OVER);
- break;
-
- case java_awt_alpha_composite_DST_OVER:
- cairo_set_operator (gr->cr, CAIRO_OPERATOR_DEST_OVER);
- break;
-
- case java_awt_alpha_composite_SRC_IN:
- cairo_set_operator (gr->cr, CAIRO_OPERATOR_IN);
- break;
-
- case java_awt_alpha_composite_DST_IN:
- cairo_set_operator (gr->cr, CAIRO_OPERATOR_DEST_IN);
- break;
-
- case java_awt_alpha_composite_SRC_OUT:
- cairo_set_operator (gr->cr, CAIRO_OPERATOR_OUT);
- break;
-
- case java_awt_alpha_composite_DST_OUT:
- cairo_set_operator (gr->cr, CAIRO_OPERATOR_DEST_OUT);
- break;
-
- case java_awt_alpha_composite_DST:
- cairo_set_operator (gr->cr, CAIRO_OPERATOR_DEST);
- break;
-
- case java_awt_alpha_composite_SRC_ATOP:
- cairo_set_operator (gr->cr, CAIRO_OPERATOR_ATOP);
- break;
-
- case java_awt_alpha_composite_DST_ATOP:
- cairo_set_operator (gr->cr, CAIRO_OPERATOR_DEST_ATOP);
- break;
-
- case java_awt_alpha_composite_XOR:
- cairo_set_operator (gr->cr, CAIRO_OPERATOR_XOR);
- break;
- }
-
- gdk_threads_leave();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetRGBAColor
- (JNIEnv *env, jobject obj, jdouble r, jdouble g, jdouble b, jdouble a)
-{
- struct graphics2d *gr = NULL;
-
- gdk_threads_enter();
-
- if (peer_is_disposed(env, obj))
- {
- gdk_threads_leave();
- return;
- }
-
- gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
- g_assert (gr != NULL);
-
- /* this is a very weird fact: GDK Pixbufs and RENDER drawables consider
- colors in opposite pixel order. I have no idea why. thus when you
- draw to a PixBuf, you must exchange the R and B components of your
- color. */
-
- if (gr->debug)
- printf ("cairo_set_source_rgba (%f, %f, %f, %f)\n", r, g, b, a);
-
- if (gr->drawbuf)
- cairo_set_source_rgba (gr->cr, b, g, r, a);
- else
- cairo_set_source_rgba (gr->cr, r, g, b, a);
-
- gdk_threads_leave();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetFillRule
- (JNIEnv *env, jobject obj, jint rule)
-{
- struct graphics2d *gr = NULL;
-
- gdk_threads_enter();
-
- if (peer_is_disposed(env, obj))
- {
- gdk_threads_leave();
- return;
- }
-
- gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
- if (gr->debug) printf ("cairo_set_fill_rule %d\n", rule);
- g_assert (gr != NULL);
- switch ((enum java_awt_geom_path_iterator_winding_rule) rule)
- {
- case java_awt_geom_path_iterator_WIND_NON_ZERO:
- cairo_set_fill_rule (gr->cr, CAIRO_FILL_RULE_WINDING);
- break;
- case java_awt_geom_path_iterator_WIND_EVEN_ODD:
- cairo_set_fill_rule (gr->cr, CAIRO_FILL_RULE_EVEN_ODD);
- break;
- }
-
- gdk_threads_leave();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetLineWidth
- (JNIEnv *env, jobject obj, jdouble width)
-{
- struct graphics2d *gr = NULL;
-
- gdk_threads_enter();
-
- if (peer_is_disposed(env, obj))
- {
- gdk_threads_leave();
- return;
- }
-
- gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
- g_assert (gr != NULL);
- if (gr->debug) printf ("cairo_set_line_width %f\n", width);
- cairo_set_line_width (gr->cr, width);
-
- gdk_threads_leave();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetLineCap
- (JNIEnv *env, jobject obj, jint cap)
-{
- struct graphics2d *gr = NULL;
-
- gdk_threads_enter();
-
- if (peer_is_disposed(env, obj))
- {
- gdk_threads_leave();
- return;
- }
-
- gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
- g_assert (gr != NULL);
- if (gr->debug) printf ("cairo_set_line_cap %d\n", cap);
- switch ((enum java_awt_basic_stroke_cap_rule) cap)
- {
- case java_awt_basic_stroke_CAP_BUTT:
- cairo_set_line_cap (gr->cr, CAIRO_LINE_CAP_BUTT);
- break;
-
- case java_awt_basic_stroke_CAP_ROUND:
- cairo_set_line_cap (gr->cr, CAIRO_LINE_CAP_ROUND);
- break;
-
- case java_awt_basic_stroke_CAP_SQUARE:
- cairo_set_line_cap (gr->cr, CAIRO_LINE_CAP_SQUARE);
- break;
- }
-
- gdk_threads_leave();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetLineJoin
- (JNIEnv *env, jobject obj, jint join)
-{
- struct graphics2d *gr = NULL;
-
- gdk_threads_enter();
-
- if (peer_is_disposed(env, obj))
- {
- gdk_threads_leave();
- return;
- }
-
- gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
- g_assert (gr != NULL);
- if (gr->debug) printf ("cairo_set_line_join %d\n", join);
- switch ((enum java_awt_basic_stroke_join_rule) join)
- {
- case java_awt_basic_stroke_JOIN_MITER:
- cairo_set_line_join (gr->cr, CAIRO_LINE_JOIN_MITER);
- break;
-
- case java_awt_basic_stroke_JOIN_ROUND:
- cairo_set_line_join (gr->cr, CAIRO_LINE_JOIN_ROUND);
- break;
-
- case java_awt_basic_stroke_JOIN_BEVEL:
- cairo_set_line_join (gr->cr, CAIRO_LINE_JOIN_BEVEL);
- break;
- }
-
- gdk_threads_leave();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetDash
- (JNIEnv *env, jobject obj, jdoubleArray dashes, jint ndash, jdouble offset)
-{
- struct graphics2d *gr = NULL;
- jdouble *dasharr = NULL;
-
- gdk_threads_enter();
-
- if (peer_is_disposed(env, obj))
- {
- gdk_threads_leave();
- return;
- }
-
- gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
- g_assert (gr != NULL);
- if (gr->debug) printf ("cairo_set_dash\n");
- dasharr = (*env)->GetDoubleArrayElements (env, dashes, NULL);
- g_assert (dasharr != NULL);
- cairo_set_dash (gr->cr, dasharr, ndash, offset);
- (*env)->ReleaseDoubleArrayElements (env, dashes, dasharr, 0);
-
- gdk_threads_leave();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetMiterLimit
- (JNIEnv *env, jobject obj, jdouble miter)
-{
- struct graphics2d *gr = NULL;
-
- gdk_threads_enter();
-
- if (peer_is_disposed(env, obj))
- {
- gdk_threads_leave();
- return;
- }
-
- gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
- g_assert (gr != NULL);
- if (gr->debug) printf ("cairo_set_miter_limit %f\n", miter);
- cairo_set_miter_limit (gr->cr, miter);
-
- gdk_threads_leave();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoNewPath
- (JNIEnv *env, jobject obj)
-{
- struct graphics2d *gr = NULL;
-
- gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
-
- gdk_threads_enter();
-
- if (peer_is_disposed(env, obj))
- {
- gdk_threads_leave();
- return;
- }
-
- if (gr->debug) printf ("cairo_new_path\n");
- cairo_new_path (gr->cr);
-
- gdk_threads_leave();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoMoveTo
- (JNIEnv *env, jobject obj, jdouble x, jdouble y)
-{
- struct graphics2d *gr = NULL;
-
- gdk_threads_enter();
-
- if (peer_is_disposed(env, obj))
- {
- gdk_threads_leave();
- return;
- }
-
- gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
- g_assert (gr != NULL);
- if (gr->debug) printf ("cairo_move_to (%f, %f)\n", x, y);
- cairo_move_to (gr->cr, x, y);
-
- gdk_threads_leave();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoLineTo
- (JNIEnv *env, jobject obj, jdouble x, jdouble y)
-{
- struct graphics2d *gr = NULL;
-
- gdk_threads_enter();
-
- if (peer_is_disposed(env, obj))
- {
- gdk_threads_leave();
- return;
- }
-
- gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
- g_assert (gr != NULL);
- if (gr->debug) printf ("cairo_line_to (%f, %f)\n", x, y);
- cairo_line_to (gr->cr, x, y);
-
- gdk_threads_leave();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoCurveTo
- (JNIEnv *env, jobject obj, jdouble x1, jdouble y1, jdouble x2, jdouble y2, jdouble x3, jdouble y3)
-{
- struct graphics2d *gr = NULL;
-
- gdk_threads_enter();
-
- if (peer_is_disposed(env, obj))
- {
- gdk_threads_leave();
- return;
- }
-
- gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
- g_assert (gr != NULL);
- if (gr->debug)
- printf ("cairo_curve_to (%f, %f), (%f, %f), (%f, %f)\n",
- x1, y1, x2, y2, x3, y3);
- cairo_curve_to (gr->cr, x1, y1, x2, y2, x3, y3);
-
- gdk_threads_leave();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoRelMoveTo
- (JNIEnv *env, jobject obj, jdouble dx, jdouble dy)
-{
- struct graphics2d *gr = NULL;
-
- gdk_threads_enter();
-
- if (peer_is_disposed(env, obj))
- {
- gdk_threads_leave();
- return;
- }
-
- gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
- g_assert (gr != NULL);
- if (gr->debug) printf ("cairo_rel_move_to (%f, %f)\n", dx, dy);
- cairo_rel_move_to (gr->cr, dx, dy);
-
- gdk_threads_leave();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoRelLineTo
- (JNIEnv *env, jobject obj, jdouble dx, jdouble dy)
-{
- struct graphics2d *gr = NULL;
-
- gdk_threads_enter();
-
- if (peer_is_disposed(env, obj))
- {
- gdk_threads_leave();
- return;
- }
-
- gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
- g_assert (gr != NULL);
- if (gr->debug) printf ("cairo_rel_line_to (%f, %f)\n", dx, dy);
- cairo_rel_line_to (gr->cr, dx, dy);
-
- gdk_threads_leave();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoRelCurveTo
- (JNIEnv *env, jobject obj, jdouble dx1, jdouble dy1, jdouble dx2, jdouble dy2, jdouble dx3, jdouble dy3)
-{
- struct graphics2d *gr = NULL;
-
- gdk_threads_enter();
-
- if (peer_is_disposed(env, obj))
- {
- gdk_threads_leave();
- return;
- }
-
- gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
- g_assert (gr != NULL);
- if (gr->debug)
- printf ("cairo_rel_curve_to (%f, %f), (%f, %f), (%f, %f)\n",
- dx1, dy1, dx2, dy2, dx3, dy3);
- cairo_rel_curve_to (gr->cr, dx1, dy1, dx2, dy2, dx3, dy3);
-
- gdk_threads_leave();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoRectangle
- (JNIEnv *env, jobject obj, jdouble x, jdouble y, jdouble width, jdouble height)
-{
- struct graphics2d *gr = NULL;
-
- gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
-
- gdk_threads_enter();
-
- if (peer_is_disposed(env, obj))
- {
- gdk_threads_leave();
- return;
- }
-
- if (gr->debug)
- printf ("cairo_rectangle (%f, %f) (%f, %f)\n", x, y, width, height);
- cairo_rectangle (gr->cr, x, y, width, height);
-
- gdk_threads_leave();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoClosePath
- (JNIEnv *env, jobject obj)
-{
- struct graphics2d *gr = NULL;
-
- gdk_threads_enter();
-
- if (peer_is_disposed(env, obj))
- {
- gdk_threads_leave();
- return;
- }
-
- gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
- g_assert (gr != NULL);
- if (gr->debug) printf ("cairo_close_path\n");
- cairo_close_path (gr->cr);
-
- gdk_threads_leave();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoStroke
- (JNIEnv *env, jobject obj)
-{
- struct graphics2d *gr = NULL;
-
- gdk_threads_enter();
-
- if (peer_is_disposed(env, obj))
- {
- gdk_threads_leave();
- return;
- }
-
- gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
- g_assert (gr != NULL);
- if (gr->debug) printf ("cairo_stroke\n");
- begin_drawing_operation (env, gr);
- cairo_stroke (gr->cr);
- end_drawing_operation (env, gr);
-
- gdk_threads_leave();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoFill
- (JNIEnv *env, jobject obj)
-{
- struct graphics2d *gr = NULL;
-
- gdk_threads_enter();
-
- if (peer_is_disposed(env, obj))
- {
- gdk_threads_leave();
- return;
- }
-
- gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
- g_assert (gr != NULL);
- if (gr->debug) printf ("cairo_fill\n");
- begin_drawing_operation (env, gr);
- cairo_fill (gr->cr);
- end_drawing_operation (env, gr);
-
- gdk_threads_leave();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoClip
- (JNIEnv *env, jobject obj)
-{
- struct graphics2d *gr = NULL;
-
- gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
-
- gdk_threads_enter();
-
- if (peer_is_disposed(env, obj))
- {
- gdk_threads_leave();
- return;
- }
-
- if (gr->debug) printf ("cairo_clip\n");
- begin_drawing_operation (env, gr);
- cairo_reset_clip (gr->cr);
- cairo_clip (gr->cr);
- end_drawing_operation (env, gr);
-
- gdk_threads_leave();
-}
-
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSurfaceSetFilter
- (JNIEnv *env, jobject obj, jint filter)
-{
- struct graphics2d *gr = NULL;
-
- gdk_threads_enter();
-
- if (peer_is_disposed(env, obj))
- {
- gdk_threads_leave();
- return;
- }
-
- gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
- g_assert (gr != NULL);
-
- if (gr->pattern == NULL)
- return;
-
- if (gr->debug) printf ("cairo_pattern_set_filter %d\n", filter);
- switch ((enum java_awt_rendering_hints_filter) filter)
- {
- case java_awt_rendering_hints_VALUE_INTERPOLATION_NEAREST_NEIGHBOR:
- cairo_pattern_set_filter (gr->pattern, CAIRO_FILTER_NEAREST);
- break;
- case java_awt_rendering_hints_VALUE_INTERPOLATION_BILINEAR:
- cairo_pattern_set_filter (gr->pattern, CAIRO_FILTER_BILINEAR);
- break;
- case java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_SPEED:
- cairo_pattern_set_filter (gr->pattern, CAIRO_FILTER_FAST);
- break;
- case java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_DEFAULT:
- cairo_pattern_set_filter (gr->pattern, CAIRO_FILTER_NEAREST);
- break;
- case java_awt_rendering_hints_VALUE_ALPHA_INTERPOLATION_QUALITY:
- cairo_pattern_set_filter (gr->pattern, CAIRO_FILTER_BEST);
- break;
- }
-
- gdk_threads_leave();
-}
diff --git a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphicsEnvironment.c b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphicsEnvironment.c
index 7662800f0..89adcd1e5 100644
--- a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphicsEnvironment.c
+++ b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphicsEnvironment.c
@@ -1,5 +1,5 @@
/* gnu_java_awt_peer_gtk_GdkGraphicsEnvironment.c
- Copyright (C) 2004 Free Software Foundation, Inc.
+ Copyright (C) 2004, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -35,9 +35,43 @@
obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
+#include <glib.h>
+#include <gdk/gdk.h>
+
#include "gdkfont.h"
+#include "gdkdisplay.h"
#include "gnu_java_awt_peer_gtk_GdkGraphicsEnvironment.h"
+struct state_table *cp_gtk_native_display_state_table;
+
+jclass gdkGraphicsEnvironment_class;
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkGraphicsEnvironment_initStaticState
+(JNIEnv *env, jclass klazz __attribute__((unused)))
+{
+ gdkGraphicsEnvironment_class = (*env)->NewGlobalRef
+ (env, klazz);
+
+ NSA_DISPLAY_INIT(env, gdkGraphicsEnvironment_class);
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkGraphicsEnvironment_nativeInitState
+(JNIEnv *env, jobject obj)
+{
+ GdkDisplay *defaultDisplay;
+
+ gdk_threads_enter();
+
+ /* Retrieve the default display. */
+ defaultDisplay = gdk_display_get_default();
+
+ gdk_threads_leave();
+
+ /* Store display pointer in GdkGraphicsEnvironment instance. */
+ NSA_SET_DISPLAY_PTR(env, obj, (void *) defaultDisplay);
+}
static gint
cmp_families (const void *a, const void *b)
@@ -101,3 +135,109 @@ Java_gnu_java_awt_peer_gtk_GdkGraphicsEnvironment_nativeGetNumFontFamilies
return num;
}
+
+JNIEXPORT jobjectArray JNICALL
+Java_gnu_java_awt_peer_gtk_GdkGraphicsEnvironment_nativeGetScreenDevices
+(JNIEnv *env, jobject obj)
+{
+ jmethodID gdkScreenGraphicsDevice_ctor, gdkScreenGraphicsDevice_init;
+ jclass gdkScreenGraphicsDevice_class;
+ int numScreens = 0, i = 0;
+ GdkDisplay *display;
+ jobjectArray array;
+ jobject instance;
+
+ gdkScreenGraphicsDevice_class = (*env)->FindClass
+ (env, "gnu/java/awt/peer/gtk/GdkScreenGraphicsDevice");
+
+ gdkScreenGraphicsDevice_ctor = (*env)->GetMethodID
+ (env, gdkScreenGraphicsDevice_class, "<init>",
+ "(Lgnu/java/awt/peer/gtk/GdkGraphicsEnvironment;)V");
+
+ gdkScreenGraphicsDevice_init = (*env)->GetMethodID
+ (env, gdkScreenGraphicsDevice_class, "init", "()V");
+
+ display = (GdkDisplay *) NSA_GET_DISPLAY_PTR(env, obj);
+
+ gdk_threads_enter();
+
+ numScreens = gdk_display_get_n_screens(display);
+
+
+ /* Create a suitably sized array. */
+ array = (*env)->NewObjectArray(env,
+ numScreens,
+ gdkScreenGraphicsDevice_class,
+ NULL);
+
+ /* Create GdkScreenGraphicsDevice instances, store the native pointer to
+ * the GScreen object with them, run a 2nd initialization phase and
+ * put the new instance into the result array.
+ */
+ for ( ; i < numScreens ; i++)
+ {
+ instance = (*env)->NewObject (env,
+ gdkScreenGraphicsDevice_class,
+ gdkScreenGraphicsDevice_ctor,
+ obj);
+
+ NSA_SET_SCREEN_PTR(env,
+ instance,
+ gdk_display_get_screen(display, i));
+
+ gdk_threads_leave();
+ (*env)->CallVoidMethod(env,
+ instance,
+ gdkScreenGraphicsDevice_init);
+ gdk_threads_enter();
+
+ (*env)->SetObjectArrayElement(env, array, i, instance);
+ }
+
+ gdk_threads_leave();
+
+ return array;
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_java_awt_peer_gtk_GdkGraphicsEnvironment_nativeGetDefaultScreenDevice
+(JNIEnv *env, jobject obj)
+{
+ jclass gdkScreenGraphicsDevice_class;
+ jmethodID gdkScreenGraphicsDevice_ctor, gdkScreenGraphicsDevice_init;
+ jobject defaultDevice;
+ GdkScreen *defaultScreen;
+
+ gdkScreenGraphicsDevice_class = (*env)->FindClass
+ (env, "gnu/java/awt/peer/gtk/GdkScreenGraphicsDevice");
+
+ gdkScreenGraphicsDevice_ctor = (*env)->GetMethodID
+ (env, gdkScreenGraphicsDevice_class, "<init>",
+ "(Lgnu/java/awt/peer/gtk/GdkGraphicsEnvironment;)V");
+
+ gdkScreenGraphicsDevice_init = (*env)->GetMethodID
+ (env, gdkScreenGraphicsDevice_class, "init", "()V");
+
+ /* Create the GdkScreenGraphicsDevice instance. */
+ defaultDevice = (*env)->NewObject (env,
+ gdkScreenGraphicsDevice_class,
+ gdkScreenGraphicsDevice_ctor,
+ obj);
+
+ gdk_threads_enter();
+
+ defaultScreen = gdk_screen_get_default();
+
+ gdk_threads_leave();
+
+ /* Class initialization will have set up the native_state storage
+ * mechanism for GdkScreenGraphicsDevice.
+ */
+ NSA_SET_SCREEN_PTR(env, defaultDevice, defaultScreen);
+
+ (*env)->CallVoidMethod(env,
+ defaultDevice,
+ gdkScreenGraphicsDevice_init);
+
+ return defaultDevice;
+}
diff --git a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkScreenGraphicsDevice.c b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkScreenGraphicsDevice.c
new file mode 100644
index 000000000..965fb5a23
--- /dev/null
+++ b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkScreenGraphicsDevice.c
@@ -0,0 +1,354 @@
+/* gnu_java_awt_peer_gtk_GdkScreenGraphicsDevice.c
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+ This file is part of GNU Classpath.
+
+ GNU Classpath is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GNU Classpath is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNU Classpath; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301 USA.
+
+ Linking this library statically or dynamically with other modules is
+ making a combined work based on this library. Thus, the terms and
+ conditions of the GNU General Public License cover the whole
+ combination.
+
+ As a special exception, the copyright holders of this library give you
+ permission to link this library with independent modules to produce an
+ executable, regardless of the license terms of these independent
+ modules, and to copy and distribute the resulting executable under
+ terms of your choice, provided that you also meet, for each linked
+ independent module, the terms and conditions of the license of that
+ module. An independent module is a module which is not derived from
+ or based on this library. If you modify this library, you may extend
+ this exception to your version of the library, but you are not
+ obligated to do so. If you do not wish to do so, delete this
+ exception statement from your version. */
+
+#include <jcl.h>
+
+#include <gdk/gdk.h>
+#include <gdk/gdkx.h>
+
+#ifdef HAVE_XRANDR
+#include <X11/Xlib.h>
+#include <X11/extensions/Xrandr.h>
+#endif
+
+#include "gdkdisplay.h"
+
+#include "gnu_java_awt_peer_gtk_GdkScreenGraphicsDevice.h"
+
+struct state_table *cp_gtk_native_screen_state_table;
+
+jclass gdkScreenGraphicsDevice_class;
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkScreenGraphicsDevice_initStaticState
+(JNIEnv *env, jclass klazz)
+{
+ gdkScreenGraphicsDevice_class = (*env)->NewGlobalRef
+ (env, klazz);
+
+ NSA_SCREEN_INIT(env, gdkScreenGraphicsDevice_class);
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_java_awt_peer_gtk_GdkScreenGraphicsDevice_nativeGetFixedDisplayMode
+(JNIEnv *env, jobject obj, jobject gdkGraphicsEnv __attribute__((unused)))
+{
+ jclass displayMode_class;
+ jmethodID displayMode_ctor;
+ GdkScreen *screen;
+ jobject fixedDisplayMode = NULL;
+#ifdef HAVE_XRANDR
+ int temp1, temp2;
+ GdkDisplay *display;
+
+ display = (GdkDisplay *) NSA_GET_DISPLAY_PTR(env, gdkGraphicsEnv);
+
+ gdk_threads_enter();
+
+ if (!XRRQueryExtension(GDK_DISPLAY_XDISPLAY(display), &temp1, &temp2))
+ {
+ displayMode_class = (*env)->FindClass(env, "java/awt/DisplayMode");
+ displayMode_ctor = (*env)->GetMethodID(env,
+ displayMode_class,
+ "<init>",
+ "(IIII)V");
+
+ screen = (GdkScreen *) NSA_GET_SCREEN_PTR(env, obj);
+
+ fixedDisplayMode = (*env)->NewObject(env,
+ displayMode_class,
+ displayMode_ctor,
+ gdk_screen_get_width(screen),
+ gdk_screen_get_height(screen),
+ -1,
+ 0);
+ }
+
+ gdk_threads_leave();
+
+#else
+
+ displayMode_class = (*env)->FindClass(env, "java/awt/DisplayMode");
+ displayMode_ctor = (*env)->GetMethodID(env,
+ displayMode_class,
+ "<init>",
+ "(IIII)V");
+
+ screen = (GdkScreen *) NSA_GET_SCREEN_PTR(env, obj);
+
+ fixedDisplayMode = (*env)->NewObject(env,
+ displayMode_class,
+ displayMode_ctor,
+ gdk_screen_get_width(screen),
+ gdk_screen_get_height(screen),
+ -1,
+ 0);
+
+#endif
+ return fixedDisplayMode;
+}
+
+JNIEXPORT jstring JNICALL
+Java_gnu_java_awt_peer_gtk_GdkScreenGraphicsDevice_nativeGetIDString
+(JNIEnv *env, jobject obj)
+{
+ GdkScreen *screen;
+ gchar* displayName;
+ jstring string;
+
+ screen = (GdkScreen *) NSA_GET_SCREEN_PTR(env, obj);
+
+ gdk_threads_enter();
+
+ displayName = gdk_screen_make_display_name(screen);
+
+ gdk_threads_leave();
+
+ string = (*env)->NewStringUTF(env, displayName);
+
+ g_free(displayName);
+
+ return string;
+}
+
+JNIEXPORT jint JNICALL
+Java_gnu_java_awt_peer_gtk_GdkScreenGraphicsDevice_nativeGetDisplayModeRate
+(JNIEnv *env, jobject obj __attribute__((unused)), jobject gdkGraphicsEnv __attribute__((unused)))
+{
+#ifdef HAVE_XRANDR
+
+ GdkDisplay *display;
+ XRRScreenConfiguration *config;
+ int rate;
+
+ display = (GdkDisplay *) NSA_GET_DISPLAY_PTR(env, gdkGraphicsEnv);
+
+ gdk_threads_enter();
+
+ config = XRRGetScreenInfo (GDK_DISPLAY_XDISPLAY(display), GDK_ROOT_WINDOW());
+
+ rate = (int) XRRConfigCurrentRate (config);
+
+ XRRFreeScreenConfigInfo (config);
+
+ gdk_threads_leave();
+
+ return rate;
+#else
+ JCL_ThrowException(env,
+ "java/lang/InternalError",
+ "Method should not have been invoked.");
+
+ return -1;
+#endif
+}
+
+JNIEXPORT jint JNICALL
+Java_gnu_java_awt_peer_gtk_GdkScreenGraphicsDevice_nativeGetDisplayModeIndex
+(JNIEnv *env, jobject obj __attribute__((unused)), jobject gdkGraphicsEnv __attribute__((unused)))
+{
+#ifdef HAVE_XRANDR
+
+ GdkDisplay *display;
+ XRRScreenConfiguration *config;
+ SizeID index;
+ Rotation rotation;
+
+ display = (GdkDisplay *) NSA_GET_DISPLAY_PTR(env, gdkGraphicsEnv);
+
+ gdk_threads_enter();
+
+ config = XRRGetScreenInfo (GDK_DISPLAY_XDISPLAY(display), GDK_ROOT_WINDOW());
+
+ index = XRRConfigCurrentConfiguration (config, &rotation);
+
+ XRRFreeScreenConfigInfo (config);
+
+ gdk_threads_leave();
+
+ return (int) index;
+
+#else
+
+ JCL_ThrowException(env,
+ "java/lang/InternalError",
+ "Method should not have been invoked.");
+
+ return -1;
+
+#endif
+}
+
+JNIEXPORT jobjectArray JNICALL
+Java_gnu_java_awt_peer_gtk_GdkScreenGraphicsDevice_nativeGetDisplayModes
+(JNIEnv *env, jobject obj __attribute__((unused)), jobject gdkGraphicsEnv __attribute__((unused)))
+{
+#ifdef HAVE_XRANDR
+ GdkDisplay *display;
+ XRRScreenConfiguration *config;
+ XRRScreenSize *screenSizes;
+ int nsizes = 0, nrates = 0, i = 0;
+ jclass x11DisplayMode_class;
+ jmethodID x11DisplayMode_ctor;
+ jobjectArray array;
+ jobject instance;
+ short *rates;
+ jshortArray shortArray;
+
+ display = (GdkDisplay *) NSA_GET_DISPLAY_PTR(env, gdkGraphicsEnv);
+
+ gdk_threads_enter();
+
+ config = XRRGetScreenInfo (GDK_DISPLAY_XDISPLAY(display), GDK_ROOT_WINDOW());
+
+ screenSizes = XRRConfigSizes(config, &nsizes);
+
+ x11DisplayMode_class = (*env)->FindClass(env, "gnu/java/awt/peer/gtk/GdkScreenGraphicsDevice$X11DisplayMode");
+
+ x11DisplayMode_ctor = (*env)->GetMethodID(env, x11DisplayMode_class, "<init>", "(II[S)V");
+
+ array = (*env)->NewObjectArray(env, nsizes, x11DisplayMode_class, NULL);
+
+ for (; i < nsizes ; i++)
+ {
+ /* Retrieves refresh rate information. */
+ rates = XRRConfigRates(config, i, &nrates);
+
+ /* Create a Java int array and put them in. */
+ shortArray = (*env)->NewIntArray(env, nrates);
+ (*env)->SetShortArrayRegion(env, shortArray, 0, nrates, (jshort *) rates);
+
+ /* Create a GdkScreenGraphicsDevice.X11DisplayMode instance. */
+ instance = (*env)->NewObject(env,
+ x11DisplayMode_class,
+ x11DisplayMode_ctor,
+ screenSizes[i].width,
+ screenSizes[i].height,
+ shortArray);
+
+ /* Put it into the result array. */
+ (*env)->SetObjectArrayElement(env, array, i, instance);
+ }
+
+ /* Free everything acquired by xlib. */
+ XRRFreeScreenConfigInfo (config);
+
+ gdk_threads_leave();
+
+ return array;
+#else
+ JCL_ThrowException(env,
+ "java/lang/InternalError",
+ "Method should not have been invoked.");
+
+ return NULL;
+
+#endif
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkScreenGraphicsDevice_nativeSetDisplayMode
+(JNIEnv *env, jobject obj __attribute__((unused)), jobject gdkGraphicsEnv __attribute__((unused)), jint index __attribute__((unused)), jshort rate __attribute__((unused)))
+{
+#ifdef HAVE_XRANDR
+ GdkDisplay *display;
+ XRRScreenConfiguration *config;
+ Rotation rotation;
+
+ display = (GdkDisplay *) NSA_GET_DISPLAY_PTR(env, gdkGraphicsEnv);
+
+ gdk_threads_enter();
+
+ config = XRRGetScreenInfo (GDK_DISPLAY_XDISPLAY(display), GDK_ROOT_WINDOW());
+
+ /* The rotation is not exposed to the Java API. So we retrieve its current
+ * value and set it to the same when switching resolution.
+ */
+ XRRConfigCurrentConfiguration (config, &rotation);
+
+ XRRSetScreenConfigAndRate (GDK_DISPLAY_XDISPLAY(display),
+ config,
+ GDK_ROOT_WINDOW(),
+ index,
+ rotation,
+ rate,
+ CurrentTime);
+
+ XRRFreeScreenConfigInfo(config);
+
+ gdk_threads_leave();
+
+#else
+ JCL_ThrowException(env,
+ "java/lang/InternalError",
+ "Method should not have been invoked.");
+#endif
+}
+
+JNIEXPORT jobject JNICALL
+Java_gnu_java_awt_peer_gtk_GdkScreenGraphicsDevice_nativeGetBounds
+(JNIEnv *env, jobject obj)
+{
+ jclass rectangle_class;
+ jmethodID rectangle_ctor;
+ GdkScreen *screen;
+ GdkWindow *window;
+ int x, y, w, h;
+ jobject instance;
+
+ rectangle_class = (*env)->FindClass(env, "java/awt/Rectangle");
+
+ rectangle_ctor = (*env)->GetMethodID
+ (env, rectangle_class, "<init>", "(IIII)V");
+
+ screen = (GdkScreen *) NSA_GET_SCREEN_PTR(env, obj);
+
+ gdk_threads_enter();
+
+ window = gdk_screen_get_root_window(screen);
+
+ gdk_window_get_geometry(window, &x, &y, &w, &h, NULL);
+
+ gdk_threads_leave();
+
+ instance = (*env)->NewObject(env,
+ rectangle_class,
+ rectangle_ctor,
+ x, y, w, h);
+
+ return instance;
+}
diff --git a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkTextLayout.c b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkTextLayout.c
index edce3917d..849998791 100644
--- a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkTextLayout.c
+++ b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkTextLayout.c
@@ -1,5 +1,5 @@
/* gnu_java_awt_GdkTextLayout.c
- Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -44,9 +44,11 @@
#include <pango/pangofc-font.h>
#include <freetype/ftglyph.h>
#include <freetype/ftoutln.h>
+#include "jcl.h"
#include "native_state.h"
#include "gdkfont.h"
#include "gnu_java_awt_peer_gtk_GdkTextLayout.h"
+#include "cairographics2d.h"
struct state_table *cp_gtk_native_text_layout_state_table;
@@ -60,6 +62,9 @@ typedef struct gp
double sy;
} generalpath ;
+static void paint_glyph_run(cairo_t *cr, cairo_glyph_t **glyphs,
+ gint *n_glyphs, PangoLayoutRun *run);
+
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkTextLayout_initStaticState
(JNIEnv *env, jclass clazz)
@@ -93,8 +98,6 @@ Java_gnu_java_awt_peer_gtk_GdkTextLayout_setText
gchar *str = NULL;
gint len = 0;
- gdk_threads_enter ();
-
g_assert(self != NULL);
g_assert(text != NULL);
@@ -106,13 +109,37 @@ Java_gnu_java_awt_peer_gtk_GdkTextLayout_setText
str = (gchar *)(*env)->GetStringUTFChars (env, text, NULL);
g_assert (str != NULL);
- pango_layout_set_text (tl->pango_layout, text, len);
+ gdk_threads_enter ();
+
+ pango_layout_set_text (tl->pango_layout, str, len);
(*env)->ReleaseStringUTFChars (env, text, str);
gdk_threads_leave ();
}
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkTextLayout_setFont (JNIEnv *env, jobject obj, jobject font)
+{
+ struct textlayout *tl;
+ struct peerfont *pf;
+
+ g_assert(obj != NULL);
+ g_assert(font != NULL);
+
+ tl = (struct textlayout *)NSA_GET_TEXT_LAYOUT_PTR (env, obj);
+ g_assert(tl != NULL);
+ g_assert(tl->pango_layout != NULL);
+ pf = (struct peerfont *)NSA_GET_FONT_PTR (env, font);
+ g_assert(pf != NULL);
+
+ gdk_threads_enter ();
+
+ pango_layout_set_font_description(tl->pango_layout, pf->desc);
+
+ gdk_threads_leave ();
+}
+
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkTextLayout_indexToPos
(JNIEnv *env, jobject self, jint idx, jdoubleArray javaPos)
@@ -207,10 +234,106 @@ Java_gnu_java_awt_peer_gtk_GdkTextLayout_dispose
gdk_threads_leave ();
}
+/**
+ * Draw this textlayout on a cairo surface
+ * FIXME: Seems completely broken.
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GdkTextLayout_cairoDrawGdkTextLayout
+ (JNIEnv *env, jobject obj, jlong cg2d, jfloat x, jfloat y)
+{
+ /*
+ * FIXME: Some day we expect either cairo or pango will know how to make
+ * a pango layout paint to a cairo surface. that day is not yet here.
+ */
+
+ struct cairographics2d *gr = JLONG_TO_PTR(struct cairographics2d, cg2d);
+ cairo_t *cr = gr->cr;
+ struct textlayout *tl = NULL;
+ PangoLayoutIter *i = NULL;
+ PangoLayoutRun *run = NULL;
+ cairo_glyph_t *glyphs = NULL;
+ gint n_glyphs = 0;
+
+ tl = (struct textlayout *)NSA_GET_TEXT_LAYOUT_PTR (env, obj);
+
+ g_assert (cr != NULL);
+ g_assert (tl != NULL);
+ g_assert (tl->pango_layout != NULL);
+
+ gdk_threads_enter ();
+
+ i = pango_layout_get_iter (tl->pango_layout);
+ g_assert (i != NULL);
+
+ cairo_translate (cr, x, y);
+
+ do
+ {
+ run = pango_layout_iter_get_run (i);
+ if (run != NULL)
+ paint_glyph_run (cr, &glyphs, &n_glyphs, run);
+ }
+ while (pango_layout_iter_next_run (i));
+
+ if (glyphs != NULL)
+ g_free (glyphs);
+
+ cairo_translate (cr, -x, -y);
+
+ pango_layout_iter_free (i);
+
+ gdk_threads_leave ();
+}
+
+static void
+paint_glyph_run(cairo_t *cr,
+ cairo_glyph_t **glyphs,
+ gint *n_glyphs,
+ PangoLayoutRun *run)
+{
+ gint i = 0;
+ gint x = 0, y = 0;
+
+ g_assert (cr != NULL);
+ g_assert (glyphs != NULL);
+ g_assert (n_glyphs != NULL);
+ g_assert (run != NULL);
+
+ if (run->glyphs != NULL && run->glyphs->num_glyphs > 0)
+ {
+ if (*n_glyphs < run->glyphs->num_glyphs)
+ {
+ *glyphs = g_realloc(*glyphs,
+ (sizeof(cairo_glyph_t)
+ * run->glyphs->num_glyphs));
+ *n_glyphs = run->glyphs->num_glyphs;
+ }
+
+ g_assert (*glyphs != NULL);
+
+ for (i = 0; i < run->glyphs->num_glyphs; ++i)
+ {
+ (*glyphs)[i].index = run->glyphs->glyphs[i].glyph;
+
+ (*glyphs)[i].x =
+ ((double) (x + run->glyphs->glyphs[i].geometry.x_offset))
+ / ((double) PANGO_SCALE);
+
+ (*glyphs)[i].y =
+ ((double) (y + run->glyphs->glyphs[i].geometry.y_offset))
+ / ((double) PANGO_SCALE);
+
+ x += run->glyphs->glyphs[i].geometry.width;
+ }
+ cairo_show_glyphs (cr, *glyphs, run->glyphs->num_glyphs);
+ }
+}
+
/* GetOutline code follows ****************************/
/********* Freetype callback functions *****************************/
-static int _moveTo( FT_Vector* to,
+static int _moveTo( const FT_Vector* to,
void *p)
{
JNIEnv *env;
@@ -233,7 +356,7 @@ static int _moveTo( FT_Vector* to,
return 0;
}
-static int _lineTo( FT_Vector* to,
+static int _lineTo( const FT_Vector* to,
void *p)
{
JNIEnv *env;
@@ -255,8 +378,8 @@ static int _lineTo( FT_Vector* to,
return 0;
}
-static int _quadTo( FT_Vector* cp,
- FT_Vector* to,
+static int _quadTo( const FT_Vector* cp,
+ const FT_Vector* to,
void *p)
{
JNIEnv *env;
@@ -280,9 +403,9 @@ static int _quadTo( FT_Vector* cp,
return 0;
}
-static int _curveTo( FT_Vector* cp1,
- FT_Vector* cp2,
- FT_Vector* to,
+static int _curveTo( const FT_Vector* cp1,
+ const FT_Vector* cp2,
+ const FT_Vector* to,
void *p)
{
JNIEnv *env;
@@ -320,10 +443,10 @@ Java_gnu_java_awt_peer_gtk_GdkTextLayout_getOutline
PangoLayoutLine *current_line;
FT_Outline_Funcs ftCallbacks =
{
- _moveTo,
- _lineTo,
- _quadTo,
- _curveTo,
+ (FT_Outline_MoveToFunc) _moveTo,
+ (FT_Outline_LineToFunc) _lineTo,
+ (FT_Outline_ConicToFunc) _quadTo,
+ (FT_Outline_CubicToFunc) _curveTo,
0,
0
};
diff --git a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkClipboard.c b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkClipboard.c
index cb2c87238..7ce1185a4 100644
--- a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkClipboard.c
+++ b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkClipboard.c
@@ -242,14 +242,7 @@ clipboard_get_func (GtkClipboard *clipboard,
pixbuf = cp_gtk_image_get_pixbuf (env, gtkimage);
if (pixbuf != NULL)
- {
- gtk_selection_data_set_pixbuf (selection, pixbuf);
-
- /* if the GtkImage is offscreen, this is a temporary pixbuf
- which should be thrown out. */
- if(cp_gtk_image_is_offscreen (env, gtkimage) == JNI_TRUE)
- gdk_pixbuf_unref (pixbuf);
- }
+ gtk_selection_data_set_pixbuf (selection, pixbuf);
}
else if (info == URI_TARGET)
{
diff --git a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkFramePeer.c b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkFramePeer.c
index c60f48f51..766964314 100644
--- a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkFramePeer.c
+++ b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkFramePeer.c
@@ -186,10 +186,5 @@ Java_gnu_java_awt_peer_gtk_GtkFramePeer_nativeSetIconImage
gtk_window_set_icon (GTK_WINDOW (ptr), pixbuf);
- /* if the GtkImage is offscreen, this is a temporary pixbuf which should
- be thrown out. */
- if(cp_gtk_image_is_offscreen (env, gtkimage) == JNI_TRUE)
- gdk_pixbuf_unref (pixbuf);
-
gdk_threads_leave ();
}
diff --git a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkImage.c b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkImage.c
index dad6a1182..ff3fbe896 100644
--- a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkImage.c
+++ b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkImage.c
@@ -51,13 +51,11 @@ exception statement from your version. */
/* local stuff */
static GdkInterpType mapHints(jint hints);
-static jboolean offScreen (JNIEnv * env, jobject obj);
-static void *getData (JNIEnv * env, jobject obj);
static void createRawData (JNIEnv * env, jobject obj, void *ptr);
static void setWidthHeight (JNIEnv * env, jobject obj, int width, int height);
/**
- * Loads a pixmap from a file.
+ * Loads a pixbuf from a file.
*/
JNIEXPORT jboolean JNICALL
Java_gnu_java_awt_peer_gtk_GtkImage_loadPixbuf
@@ -119,10 +117,14 @@ Java_gnu_java_awt_peer_gtk_GtkImage_loadImageFromData
if (pixbuf == NULL)
{
+ g_object_unref (loader);
createRawData (env, obj, NULL);
return JNI_FALSE;
}
+ g_object_ref (pixbuf);
+ g_object_unref (loader);
+
width = gdk_pixbuf_get_width (pixbuf);
height = gdk_pixbuf_get_height (pixbuf);
@@ -137,7 +139,7 @@ Java_gnu_java_awt_peer_gtk_GtkImage_createFromPixbuf
(JNIEnv *env, jobject obj)
{
int width, heigth;
- GdkPixbuf *pixbuf = (GdkPixbuf *) getData (env, obj);
+ GdkPixbuf *pixbuf = cp_gtk_image_get_pixbuf (env, obj);
width = gdk_pixbuf_get_width (pixbuf);
heigth = gdk_pixbuf_get_height (pixbuf);
setWidthHeight(env, obj, width, heigth);
@@ -194,9 +196,6 @@ Java_gnu_java_awt_peer_gtk_GtkImage_getPixels(JNIEnv *env, jobject obj)
}
}
- if (offScreen (env, obj) == JNI_TRUE)
- gdk_pixbuf_unref (pixbuf);
-
(*env)->ReleaseIntArrayElements (env, result_array, result_array_iter, 0);
gdk_threads_leave ();
@@ -211,7 +210,7 @@ JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkImage_setPixels(JNIEnv *env, jobject obj,
jintArray pixels)
{
- GdkPixbuf *pixbuf = (GdkPixbuf *)getData (env, obj);
+ GdkPixbuf *pixbuf = cp_gtk_image_get_pixbuf (env, obj);
int width, height, rowstride;
guchar *pixeldata;
jint *src_array_iter, *src;
@@ -236,10 +235,10 @@ Java_gnu_java_awt_peer_gtk_GtkImage_setPixels(JNIEnv *env, jobject obj,
}
/**
- * Allocates a Gtk Pixbuf or Pixmap.
+ * Allocates a Gtk Pixbuf
*/
JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GtkImage_createPixmap(JNIEnv *env, jobject obj)
+Java_gnu_java_awt_peer_gtk_GtkImage_createPixbuf(JNIEnv *env, jobject obj)
{
int width, height;
jclass cls;
@@ -254,35 +253,58 @@ Java_gnu_java_awt_peer_gtk_GtkImage_createPixmap(JNIEnv *env, jobject obj)
g_assert (field != 0);
height = (*env)->GetIntField (env, obj, field);
- if (offScreen (env, obj) == JNI_FALSE)
- createRawData (env, obj, gdk_pixbuf_new (GDK_COLORSPACE_RGB,
- TRUE,
- 8,
- width,
- height));
- else
- createRawData (env, obj, gdk_pixmap_new (NULL, width, height,
- gdk_rgb_get_visual ()->depth));
+ createRawData (env, obj, gdk_pixbuf_new (GDK_COLORSPACE_RGB,
+ TRUE,
+ 8,
+ width,
+ height));
+}
+
+/**
+ * Allocates a Gtk Pixbuf
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkImage_initFromBuffer(JNIEnv *env, jobject obj,
+ jlong bufferPointer)
+{
+ int width, height;
+ jclass cls;
+ jfieldID field;
+ GdkPixbuf *pixbuf;
+ const guchar *bp = JLONG_TO_PTR(const guchar, bufferPointer);
+
+ g_assert(bp != NULL);
+ cls = (*env)->GetObjectClass( env, obj );
+ field = (*env)->GetFieldID( env, cls, "width", "I" );
+ g_assert( field != 0 );
+ width = (*env)->GetIntField( env, obj, field );
+
+ field = (*env)->GetFieldID( env, cls, "height", "I" );
+ g_assert( field != 0 );
+ height = (*env)->GetIntField( env, obj, field );
+
+ pixbuf = gdk_pixbuf_new_from_data( bp,
+ GDK_COLORSPACE_RGB, TRUE, 8,
+ width, height, width * 4, NULL, NULL );
+ g_assert( pixbuf != NULL );
+ createRawData( env, obj, pixbuf );
}
/**
- * Frees the Gtk Pixmap.
+ * Frees the Gtk Pixbuf.
*/
JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GtkImage_freePixmap(JNIEnv *env, jobject obj)
+Java_gnu_java_awt_peer_gtk_GtkImage_freePixbuf(JNIEnv *env, jobject obj)
{
- if (offScreen (env, obj) == JNI_FALSE)
- gdk_pixbuf_unref ((GdkPixbuf *)getData (env, obj));
- else
- g_object_unref ((GdkPixmap *)getData (env, obj));
+ gdk_pixbuf_unref (cp_gtk_image_get_pixbuf (env, obj));
}
/**
- * Sets this pixmap to a scaled version of the source pixmap.
+ * Sets this to a scaled version of the original pixbuf
* width and height of the destination GtkImage must be set.
*/
JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GtkImage_createScaledPixmap(JNIEnv *env,
+Java_gnu_java_awt_peer_gtk_GtkImage_createScaledPixbuf(JNIEnv *env,
jobject destination,
jobject source,
jint hints)
@@ -309,238 +331,25 @@ Java_gnu_java_awt_peer_gtk_GtkImage_createScaledPixmap(JNIEnv *env,
width, height,
mapHints(hints));
- if (offScreen (env, source) == JNI_TRUE)
- gdk_pixbuf_unref (pixbuf);
-
createRawData (env, destination, (void *)dst);
}
/**
- * Draws the pixbuf at x, y, scaled to width and height and
- * optionally composited with a given background color.
- */
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GtkImage_drawPixelsScaled
- (JNIEnv *env, jobject obj, jobject gc_obj,
- jint bg_red, jint bg_green, jint bg_blue,
- jint x, jint y, jint width, jint height, jboolean composite)
-{
- GdkPixbuf* dst;
- struct graphics2d *g;
- guint32 bgColor;
-
- gdk_threads_enter ();
-
- if (width <= 0 || height <= 0)
- {
- gdk_threads_leave ();
- return;
- }
-
- bgColor = ((bg_red & 0xFF) << 16) |
- ((bg_green & 0xFF) << 8) | (bg_blue & 0xFF);
-
- g = (struct graphics2d *) NSA_GET_G2D_PTR (env, gc_obj);
-
- if (!g || !GDK_IS_DRAWABLE (g->drawable))
- {
- gdk_threads_leave ();
- return;
- }
-
- if (offScreen (env, obj) == JNI_FALSE)
- {
- GdkPixbuf* pixbuf = (GdkPixbuf *)getData (env, obj);
-
- /* Scale and composite the image */
- if (composite == JNI_TRUE)
- dst = gdk_pixbuf_composite_color_simple (pixbuf,
- width,
- height,
- GDK_INTERP_BILINEAR,
- 255,
- width,
- bgColor,
- bgColor);
- else
- dst = gdk_pixbuf_scale_simple(pixbuf,
- width, height,
- GDK_INTERP_BILINEAR);
-
- gdk_cairo_set_source_pixbuf (g->cr, dst, (double) x, (double) y);
- gdk_pixbuf_unref (dst);
-
- } else {
- /* Get a pixmap */
- GdkPixmap* pixmap = (GdkPixmap *)getData (env, obj);
- cairo_xlib_surface_set_drawable (g->surface,
- GDK_PIXMAP_XID(pixmap),
- width,
- height);
- }
-
- gdk_threads_leave ();
-}
-
-/**
- * Draws the pixbuf at x, y, scaled to width and height and
- * optionally composited and/or flipped with a given background color.
- */
-JNIEXPORT void JNICALL
-Java_gnu_java_awt_peer_gtk_GtkImage_drawPixelsScaledFlipped
-(JNIEnv *env, jobject obj, jobject gc_obj,
- jint bg_red, jint bg_green, jint bg_blue,
-#if GTK_MINOR_VERSION > 4
- jboolean flipx, jboolean flipy,
-#else
- jboolean flipx __attribute__((unused)),
- jboolean flipy __attribute__((unused)),
-#endif
- jint srcx, jint srcy, jint srcwidth, jint srcheight,
- jint dstx, jint dsty, jint dstwidth, jint dstheight,
- jboolean composite)
-{
- GdkPixbuf *pixbuf;
- GdkPixbuf *tmp, *dst;
- struct graphics2d *g;
- guint32 bgColor;
-
- gdk_threads_enter ();
-
- if (srcwidth <= 0 || srcheight <= 0
- || dstwidth <= 0 || dstheight <= 0)
- {
- gdk_threads_leave ();
- return;
- }
-
- bgColor = ((bg_red & 0xFF) << 16) |
- ((bg_green & 0xFF) << 8) | (bg_blue & 0xFF);
-
- g = (struct graphics2d *) NSA_GET_G2D_PTR (env, gc_obj);
-
- if (!g || !GDK_IS_DRAWABLE (g->drawable))
- {
- gdk_threads_leave ();
- return;
- }
-
- if (offScreen (env, obj) == JNI_FALSE)
- {
- pixbuf = (GdkPixbuf *)getData (env, obj);
-
- /* Get the source area */
- tmp = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
- TRUE,
- 8,
- srcwidth,
- srcheight);
-
- gdk_pixbuf_copy_area (pixbuf,
- srcx, srcy,
- srcwidth, srcheight,
- tmp,
- 0, 0); /* dst x , dst y */
- } else {
- /* Get a pixbuf from the pixmap */
- GdkDrawable *pixmap = (GdkDrawable *)getData(env, obj);
- tmp = gdk_pixbuf_get_from_drawable (NULL,
- pixmap,
- gdk_drawable_get_colormap( pixmap ),
- srcx, srcy,
- 0, 0, /* dst x , dst y */
- srcwidth, srcheight);
- }
-
- /* FIXME: This #if should be discarded once I feel comfortable about
- GTK 2.6 dependence */
-#if GTK_MINOR_VERSION > 4
- /* Flip it if necessary. */
- if (flipx == JNI_TRUE)
- {
- GdkPixbuf *tmp2 = gdk_pixbuf_flip (tmp, TRUE);
- gdk_pixbuf_unref (tmp);
- tmp = tmp2;
- }
- if (flipy == JNI_TRUE)
- {
- GdkPixbuf *tmp2 = gdk_pixbuf_flip (tmp, FALSE);
- gdk_pixbuf_unref (tmp);
- tmp = tmp2;
- }
-#endif
-
- /* Scale and composite the image */
- if (composite == JNI_TRUE)
- dst = gdk_pixbuf_composite_color_simple (tmp,
- dstwidth,
- dstheight,
- GDK_INTERP_BILINEAR,
- 255,
- dstwidth,
- bgColor,
- bgColor);
- else
- dst = gdk_pixbuf_scale_simple(tmp,
- dstwidth, dstheight,
- GDK_INTERP_BILINEAR);
- gdk_pixbuf_unref (tmp);
-
- gdk_cairo_set_source_pixbuf (g->cr, dst, (double) dstx,
- (double) dsty);
- gdk_pixbuf_unref (dst);
-
- gdk_threads_leave ();
-}
-
-/**
* Used by GtkFramePeer
*/
GdkPixbuf *cp_gtk_image_get_pixbuf (JNIEnv *env, jobject obj)
{
- int width, height;
- GdkPixbuf *pixbuf;
- GdkPixmap* pixmap;
jclass cls;
- jfieldID field;
-
- if (offScreen (env, obj) == JNI_FALSE)
- return (GdkPixbuf *)getData (env, obj);
+ jfieldID data_fid;
+ jobject data;
cls = (*env)->GetObjectClass (env, obj);
- field = (*env)->GetFieldID (env, cls, "width", "I");
- g_assert (field != 0);
- width = (*env)->GetIntField (env, obj, field);
-
- field = (*env)->GetFieldID (env, cls, "height", "I");
- g_assert (field != 0);
- height = (*env)->GetIntField (env, obj, field);
-
- /* Get a pixmap */
- pixmap = (GdkPixmap *)getData (env, obj);
-
- pixbuf = gdk_pixbuf_get_from_drawable (NULL,
- pixmap,
- gdk_drawable_get_colormap( pixmap ),
- 0, 0, /* src x , src y */
- 0, 0, /* dst x , dst y */
- width, height);
- return pixbuf;
-}
-
-/**
- * Used by GdkGraphics
- */
-GdkPixmap *cp_gtk_image_get_pixmap (JNIEnv *env, jobject obj)
-{
- if (offScreen (env, obj) == JNI_FALSE)
- return NULL;
- return (GdkPixmap *)getData (env, obj);
-}
+ data_fid = (*env)->GetFieldID (env, cls, "pixbuf",
+ "Lgnu/classpath/Pointer;");
+ g_assert (data_fid != 0);
+ data = (*env)->GetObjectField (env, obj, data_fid);
-jboolean cp_gtk_image_is_offscreen (JNIEnv *env, jobject obj)
-{
- return offScreen(env, obj);
+ return (GdkPixbuf *)JCL_GetRawData (env, data);
}
/**
@@ -585,18 +394,6 @@ static void setWidthHeight (JNIEnv * env, jobject obj, int width, int height)
(*env)->SetIntField (env, obj, field, (jint)height);
}
-/* Returns the value of the offScreen field. */
-static jboolean offScreen (JNIEnv *env, jobject obj)
-{
- jclass cls;
- jfieldID field;
-
- cls = (*env)->GetObjectClass (env, obj);
- field = (*env)->GetFieldID (env, cls, "offScreen", "Z");
- g_assert (field != 0);
- return (*env)->GetBooleanField (env, obj, field);
-}
-
/* Store and get the pixbuf pointer */
static void
createRawData (JNIEnv * env, jobject obj, void *ptr)
@@ -606,7 +403,7 @@ createRawData (JNIEnv * env, jobject obj, void *ptr)
jfieldID data_fid;
cls = (*env)->GetObjectClass (env, obj);
- data_fid = (*env)->GetFieldID (env, cls, "pixmap",
+ data_fid = (*env)->GetFieldID (env, cls, "pixbuf",
"Lgnu/classpath/Pointer;");
g_assert (data_fid != 0);
@@ -615,18 +412,3 @@ createRawData (JNIEnv * env, jobject obj, void *ptr)
(*env)->SetObjectField (env, obj, data_fid, data);
}
-static void *
-getData (JNIEnv * env, jobject obj)
-{
- jclass cls;
- jfieldID data_fid;
- jobject data;
-
- cls = (*env)->GetObjectClass (env, obj);
- data_fid = (*env)->GetFieldID (env, cls, "pixmap",
- "Lgnu/classpath/Pointer;");
- g_assert (data_fid != 0);
- data = (*env)->GetObjectField (env, obj, data_fid);
-
- return JCL_GetRawData (env, data);
-}
diff --git a/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkVolatileImage.c b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkVolatileImage.c
new file mode 100644
index 000000000..d7ef474e0
--- /dev/null
+++ b/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkVolatileImage.c
@@ -0,0 +1,195 @@
+/* gnu_java_awt_peer_gtk_VolatileImage.c
+ Copyright (C) 2006 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+#include "jcl.h"
+#include "gtkpeer.h"
+#include <gdk/gdkx.h>
+#include <gdk/gdktypes.h>
+#include <gdk/gdkprivate.h>
+#include <gdk/gdkx.h>
+#include <gdk-pixbuf/gdk-pixbuf.h>
+#include <gdk-pixbuf/gdk-pixdata.h>
+
+#include "gnu_java_awt_peer_gtk_GtkVolatileImage.h"
+#include "cairographics2d.h"
+
+
+/**
+ * Creates a cairo surface, ARGB32, native ordering, premultiplied alpha.
+ */
+JNIEXPORT jlong JNICALL
+Java_gnu_java_awt_peer_gtk_GtkVolatileImage_init (JNIEnv *env,
+ jobject obj __attribute__ ((__unused__)),
+ jobject peer,
+ jint width, jint height)
+{
+ GtkWidget *widget = NULL;
+ GdkPixmap* pixmap;
+ void *ptr = NULL;
+
+ gdk_threads_enter();
+
+ if( peer != NULL )
+ {
+ ptr = NSA_GET_PTR (env, peer);
+ g_assert (ptr != NULL);
+
+ widget = GTK_WIDGET (ptr);
+ g_assert (widget != NULL);
+ pixmap = gdk_pixmap_new( widget->window, width, height, -1 );
+ }
+ else
+ pixmap = gdk_pixmap_new( NULL, width, height, 16 );
+
+ gdk_threads_leave();
+
+ g_assert( pixmap != NULL );
+
+ return PTR_TO_JLONG( pixmap );
+}
+
+/**
+ * Destroy the surface
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkVolatileImage_destroy
+(JNIEnv *env __attribute__((unused)), jobject obj __attribute((unused)),
+ jlong pointer)
+{
+ GdkPixmap* pixmap = JLONG_TO_PTR(GdkPixmap, pointer);
+ if( pixmap != NULL )
+ {
+ gdk_threads_enter();
+ g_object_unref( pixmap );
+ gdk_threads_leave();
+ }
+}
+
+/**
+ * Gets all pixels in an array
+ */
+JNIEXPORT jintArray JNICALL
+Java_gnu_java_awt_peer_gtk_GtkVolatileImage_nativeGetPixels
+(JNIEnv *env, jobject obj, jlong pointer)
+{
+ /* jint *pixeldata, *jpixdata; */
+ jint *jpixdata;
+ GdkPixmap *pixmap;
+ jintArray jpixels;
+ int width, height, depth, size;
+ jclass cls;
+ jfieldID field;
+
+ cls = (*env)->GetObjectClass (env, obj);
+ field = (*env)->GetFieldID (env, cls, "width", "I");
+ g_assert (field != 0);
+ width = (*env)->GetIntField (env, obj, field);
+
+ field = (*env)->GetFieldID (env, cls, "height", "I");
+ g_assert (field != 0);
+ height = (*env)->GetIntField (env, obj, field);
+
+ pixmap = JLONG_TO_PTR(GdkPixmap, pointer);
+ g_assert(pixmap != NULL);
+
+ gdk_threads_enter();
+
+ /* get depth in bytes */
+ depth = gdk_drawable_get_depth( pixmap ) >> 3;
+ size = width * height * 4;
+ jpixels = (*env)->NewIntArray ( env, size );
+ jpixdata = (*env)->GetIntArrayElements (env, jpixels, NULL);
+ /* memcpy (jpixdata, pixeldata, size * sizeof( jint )); */
+
+ (*env)->ReleaseIntArrayElements (env, jpixels, jpixdata, 0);
+
+ gdk_threads_leave();
+
+ return jpixels;
+}
+
+/**
+ * Copy area
+ */
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkVolatileImage_nativeCopyArea
+(JNIEnv *env __attribute__((unused)), jobject obj __attribute((unused)),
+ jlong pointer, jint x, jint y, jint w, jint h, jint dx, jint dy)
+{
+ GdkPixbuf *pixbuf;
+ GdkPixmap* pixmap = JLONG_TO_PTR(GdkPixmap, pointer);
+
+ g_assert (pixmap != NULL);
+
+ gdk_threads_enter();
+
+ pixbuf = gdk_pixbuf_new( GDK_COLORSPACE_RGB, TRUE, 8, w, h );
+ gdk_pixbuf_get_from_drawable( pixbuf, pixmap, NULL, x, y, 0, 0, w, h );
+ gdk_draw_pixbuf (pixmap, NULL, pixbuf,
+ 0, 0, x + dx, y + dy,
+ w, h,
+ GDK_RGB_DITHER_NORMAL, 0, 0);
+ gdk_threads_leave();
+}
+
+JNIEXPORT void JNICALL
+Java_gnu_java_awt_peer_gtk_GtkVolatileImage_nativeDrawVolatile
+(JNIEnv *env __attribute__((unused)), jobject obj __attribute((unused)),
+ jlong pointer, jlong srcptr, jint x, jint y, jint w, jint h)
+{
+ GdkPixmap *dst, *src;
+ GdkGC *gc;
+
+ src = JLONG_TO_PTR(GdkPixmap, srcptr);
+ dst = JLONG_TO_PTR(GdkPixmap, pointer);
+ g_assert (src != NULL);
+ g_assert (dst != NULL);
+
+ gdk_threads_enter();
+
+ gc = gdk_gc_new( dst );
+ gdk_draw_drawable(dst,
+ gc,
+ src,
+ 0, 0,
+ x, y,
+ w, h);
+ g_object_unref( gc );
+
+ gdk_threads_leave();
+}
+
diff --git a/native/jni/gtk-peer/gtkpeer.h b/native/jni/gtk-peer/gtkpeer.h
index 6ae7b06ae..065d20608 100644
--- a/native/jni/gtk-peer/gtkpeer.h
+++ b/native/jni/gtk-peer/gtkpeer.h
@@ -101,53 +101,6 @@ extern struct state_table *cp_gtk_native_graphics2d_state_table;
#define SWAPU32(w) \
(((w) << 24) | (((w) & 0xff00) << 8) | (((w) >> 8) & 0xff00) | ((w) >> 24))
-/*
- A graphics2d struct is both simpler and uglier than a graphics
- struct.
-
- Most of the graphics2d drawing state is held in the referenced cairo_t
- and corresponding cairo_surface_t, so we can ignore it.
-
- In addition to the cairo_t, we need to hold an extra reference to the
- underlying GdkDrawable so its refcount matches the lifecycle of the java
- Graphics object which is peering with us; also a reference to a byte
- buffer and cairo_surface_t which contain the pattern you're drawing from
- (if it exists).
-
- Finally, it is possible that we are using a non-RENDER capable X server,
- therefore we will be drawing to an cairo_surface_t which is actually a
- pixbuf. When this is the case, the pointer to a GdkPixbuf will be
- non-NULL and any drawing operation needs to be bracketed by pixbuf
- load/save operations. If the GdkPixbuf pointer is NULL, we will treat
- the cairo_surface_t as RENDER-capable.
- */
-struct graphics2d
-{
- cairo_t *cr;
- cairo_surface_t *surface;
- GdkDrawable *drawable;
- GdkWindow *win;
- GdkPixbuf *drawbuf;
- char *pattern_pixels;
- cairo_surface_t *pattern_surface;
- cairo_pattern_t *pattern;
- gboolean debug;
- enum
- {
- MODE_DRAWABLE_WITH_RENDER,
- MODE_DRAWABLE_NO_RENDER,
- MODE_JAVA_ARRAY
- }
- mode;
-
- /* Support for MODE_JAVA_ARRAY */
- jintArray jarray;
- jint width, height;
- jint *javabuf;
- jint *javabuf_copy;
- jboolean isCopy;
-};
-
/* New-style event masks. */
#define AWT_BUTTON1_DOWN_MASK (1 << 10)
#define AWT_BUTTON2_DOWN_MASK (1 << 11)
@@ -229,8 +182,10 @@ jint cp_gtk_state_to_awt_mods (guint state);
/* Image helpers */
GdkPixbuf *cp_gtk_image_get_pixbuf (JNIEnv *env, jobject obj);
-GdkPixmap *cp_gtk_image_get_pixmap (JNIEnv *env, jobject obj);
-jboolean cp_gtk_image_is_offscreen (JNIEnv *env, jobject obj);
+
+/* Component Graphics helpers */
+void cp_gtk_grab_current_drawable(GtkWidget *widget, GdkDrawable **draw,
+ GdkWindow **win);
/* JNI initialization functions */
void cp_gtk_button_init_jni (void);
@@ -254,6 +209,8 @@ void cp_gtk_textcomponent_connect_signals (GObject *ptr, jobject *gref);
/* Debugging */
void cp_gtk_print_current_thread (void);
+GdkPixmap *cp_gtk_get_pixmap( JNIEnv *env, jobject obj);
+
#define SYNCHRONIZE_GDK 0
#define DEBUG_LOCKING 0
diff --git a/native/jni/java-io/java_io_VMFile.c b/native/jni/java-io/java_io_VMFile.c
index 354df04ed..7a3fdaf43 100644
--- a/native/jni/java-io/java_io_VMFile.c
+++ b/native/jni/java-io/java_io_VMFile.c
@@ -1,5 +1,5 @@
/* java_io_VMFile.c - Native methods for java.io.File class
- Copyright (C) 1998, 2004 Free Software Foundation, Inc.
+ Copyright (C) 1998, 2004, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -730,3 +730,237 @@ Java_java_io_VMFile_list (JNIEnv * env, jobject obj
return (0);
#endif /* not WITHOUT_FILESYSTEM */
}
+
+/*************************************************************************/
+
+/*
+ * These two methods are used to maintain dynamically allocated
+ * buffers for getCanonicalPath without the overhead of calling
+ * realloc every time a buffer is modified. Buffers are sized
+ * at the smallest multiple of CHUNKSIZ that is greater than or
+ * equal to the desired length. The default CHUNKSIZ is 256,
+ * longer than most paths, so in most cases a getCanonicalPath
+ * will require only one malloc per buffer.
+ */
+
+#define CHUNKLOG 8
+#define CHUNKSIZ (1 << CHUNKLOG)
+
+static int
+nextChunkSize (int size)
+{
+ return ((size >> CHUNKLOG) + ((size & (CHUNKSIZ - 1)) ? 1 : 0)) << CHUNKLOG;
+}
+
+static char *
+maybeGrowBuf (JNIEnv *env, char *buf, int *size, int required)
+{
+ if (required > *size)
+ {
+ *size = nextChunkSize (required);
+ buf = JCL_realloc (env, buf, *size);
+ }
+ return buf;
+}
+
+/*************************************************************************/
+
+/*
+ * This method converts a path to canonical form on GNU/Posix systems.
+ * This involves the removal of redundant separators, references to
+ * "." and "..", and symbolic links.
+ *
+ * The conversion proceeds on a component-by-component basis: symbolic
+ * links and references to ".." are resolved as and when they occur.
+ * This means that if "/foo/bar" is a symbolic link to "/baz" then the
+ * canonical form of "/foo/bar/.." is "/" and not "/foo".
+ *
+ * In order to mimic the behaviour of proprietary JVMs, non-existant
+ * path components are allowed (a departure from the normal GNU system
+ * convention). This means that if "/foo/bar" is a symbolic link to
+ * "/baz", the canonical form of "/non-existant-directory/../foo/bar"
+ * is "/baz".
+ *
+ * Class: java_io_VMFile
+ * Method: toCanonicalForm
+ * Signature: (Ljava/lang/String)Ljava/lang/String
+ */
+
+JNIEXPORT jstring JNICALL
+Java_java_io_VMFile_toCanonicalForm (JNIEnv *env,
+ jclass class __attribute__ ((__unused__)),
+ jstring jpath)
+{
+#ifndef WITHOUT_FILESYSTEM
+ const char *path;
+ char *src, *dst;
+ int srci, dsti;
+ int srcl, dstl;
+ int len;
+ int fschecks;
+#if defined (HAVE_LSTAT) && defined (HAVE_READLINK)
+ struct stat sb;
+#endif /* HAVE_LSTAT && HAVE_READLINK */
+
+ path = JCL_jstring_to_cstring (env, jpath);
+ if (path == NULL)
+ return NULL;
+
+ /* It is the caller's responsibility to ensure the path is absolute. */
+ if (path[0] == 0 || path[0] != '/')
+ {
+ JCL_free_cstring (env, jpath, path);
+ JCL_ThrowException (env, "java/lang/RuntimeException", "Not absolute");
+ return NULL;
+ }
+
+ len = strlen (path);
+ srcl = nextChunkSize (len + 1);
+ src = JCL_malloc (env, srcl);
+ if (src == NULL)
+ {
+ JCL_free_cstring (env, jpath, path);
+ return NULL;
+ }
+ strcpy (src, path);
+ JCL_free_cstring (env, jpath, path);
+ srci = 1;
+
+ dstl = nextChunkSize (2);
+ dst = JCL_malloc (env, dstl);
+ if (dst == NULL)
+ {
+ JCL_free (env, src);
+ return NULL;
+ }
+ dst[0] = '/';
+ dsti = 1;
+
+ fschecks = JNI_TRUE;
+
+ while (src[srci] != '\0')
+ {
+ int tmpi, dsti_save;
+
+ /* Skip slashes. */
+ while (src[srci] == '/')
+ srci++;
+ tmpi = srci;
+ /* Find next slash. */
+ while (src[srci] != '/' && src[srci] != '\0')
+ srci++;
+ if (srci == tmpi)
+ /* We hit the end. */
+ break;
+ len = srci - tmpi;
+
+ /* Handle "." and "..". */
+ if (len == 1 && src[tmpi] == '.')
+ continue;
+ if (len == 2 && src[tmpi] == '.' && src[tmpi + 1] == '.')
+ {
+ while (dsti > 1 && dst[dsti - 1] != '/')
+ dsti--;
+ if (dsti != 1)
+ dsti--;
+ /* Reenable filesystem checking if disabled, as we might
+ * have reversed over whatever caused the problem before.
+ * At least one proprietary JVM has inconsistencies because
+ * it does not do this.
+ */
+ fschecks = JNI_TRUE;
+ continue;
+ }
+
+ /* Handle real path components. */
+ dst = maybeGrowBuf (env,
+ dst, &dstl, dsti + (dsti > 1 ? 1 : 0) + len + 1);
+ if (dst == NULL)
+ {
+ JCL_free (env, src);
+ return NULL;
+ }
+ dsti_save = dsti;
+ if (dsti > 1)
+ dst[dsti++] = '/';
+ strncpy (&dst[dsti], &src[tmpi], len);
+ dsti += len;
+ if (fschecks == JNI_FALSE)
+ continue;
+
+#if defined (HAVE_LSTAT) && defined (HAVE_READLINK)
+ dst[dsti] = '\0';
+ if (lstat (dst, &sb) == 0)
+ {
+ if (S_ISLNK (sb.st_mode))
+ {
+ int tmpl = CHUNKSIZ;
+ char *tmp = JCL_malloc (env, tmpl);
+ if (tmp == NULL)
+ {
+ JCL_free (env, src);
+ JCL_free (env, dst);
+ return NULL;
+ }
+
+ while (1)
+ {
+ tmpi = readlink (dst, tmp, tmpl);
+ if (tmpi < 1)
+ {
+ JCL_free (env, src);
+ JCL_free (env, dst);
+ JCL_free (env, tmp);
+ JCL_ThrowException (env, "java/io/IOException",
+ "readlink failed");
+ return NULL;
+ }
+ if (tmpi < tmpl)
+ break;
+ tmpl += CHUNKSIZ;
+ tmp = JCL_realloc (env, tmp, tmpl);
+ }
+
+ /* Prepend the link's path to src. */
+ tmp = maybeGrowBuf (env,
+ tmp, &tmpl, tmpi + strlen (&src[srci]) + 1);
+ if (tmp == NULL)
+ {
+ JCL_free (env, src);
+ JCL_free (env, dst);
+ return NULL;
+ }
+
+ strcpy (&tmp[tmpi], &src[srci]);
+ JCL_free (env, src);
+ src = tmp;
+ srcl = tmpl;
+ srci = 0;
+
+ /* Either replace or append dst depending on whether the
+ * link is relative or absolute.
+ */
+ dsti = src[0] == '/' ? 1 : dsti_save;
+ }
+ }
+ else
+ {
+ /* Something doesn't exist, or we don't have permission to
+ * read it, or a previous path component is a directory, or
+ * a symlink is looped. Whatever, we can't check the
+ * filesystem any more.
+ */
+ fschecks = JNI_FALSE;
+ }
+#endif /* HAVE_LSTAT && HAVE_READLINK */
+ }
+ dst[dsti] = '\0';
+
+ jpath = (*env)->NewStringUTF (env, dst);
+ JCL_free (env, src);
+ JCL_free (env, dst);
+ return jpath;
+#else /* not WITHOUT_FILESYSTEM */
+ return NULL;
+#endif /* not WITHOUT_FILESYSTEM */
+}
diff --git a/native/jni/midi-dssi/dssi_data.h b/native/jni/midi-dssi/dssi_data.h
index 8278f7b9e..27a4e2831 100644
--- a/native/jni/midi-dssi/dssi_data.h
+++ b/native/jni/midi-dssi/dssi_data.h
@@ -1,5 +1,5 @@
/* dssi_data.h - DSSI data
- Copyright (C) 2005 Free Software Foundation, Inc.
+ Copyright (C) 2005, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -55,11 +55,6 @@ exception statement from your version. */
1/40th of a second). */
#define EVENT_BUFFER_SIZE 1024
-/* Helper macros for going between pointers and jlongs. */
-#define JLONG_TO_PTR(T,P) ((T *)(long)P)
-#define PTR_TO_JLONG(P) ((jlong)(long)P)
-
-
/* Every DSSI Synthesizer has one of these associated with it. The
Java class sees it as a "long" handle. */
diff --git a/native/jni/qt-peer/qtmenupeer.cpp b/native/jni/qt-peer/qtmenupeer.cpp
index 1ac17145c..6f35c89b9 100644
--- a/native/jni/qt-peer/qtmenupeer.cpp
+++ b/native/jni/qt-peer/qtmenupeer.cpp
@@ -44,9 +44,11 @@ exception statement from your version. */
#include "slotcallbacks.h"
#include "componentevent.h"
-#define ADDMENU 0
-#define ADDITEM 1
-#define ADDSEPA 2
+typedef enum ActionType {
+ ActionMenu,
+ ActionItem,
+ ActionSeparator
+} ActionType;
// Sets the title, but also tear-off.
class MenuTitleEvent : public AWTEvent {
@@ -81,18 +83,18 @@ class MenuAction : public AWTEvent {
private:
QMenu *menu;
QAction *action;
- int isMenu; // 0 to add a menu, 1 to add an item, 2 to add a seperator
+ ActionType actionType; // type of action to add
JavaVM *vm;
jobject menuPeer;
jobject itemPeer;
public:
MenuAction(JNIEnv *env, jobject mp, jobject ip, QMenu *m, QAction *a,
- bool ismenu) : AWTEvent()
+ ActionType actionType) : AWTEvent()
{
menu = m;
action = a;
- isMenu = ismenu;
+ this->actionType = actionType;
env->GetJavaVM( &vm );
menuPeer = env->NewGlobalRef( mp );
if( ip != NULL )
@@ -104,35 +106,22 @@ public:
void runEvent()
{
JNIEnv *env;
- QAction *newAction; // adding an action creates a new duplicate.
vm->GetEnv((void **)&env, JNI_VERSION_1_1);
-
- switch(isMenu)
- {
- case ADDMENU:
- newAction = menu->addMenu( (QMenu *)action );
- break;
- case ADDITEM:
- newAction = menu->addAction(action->text());
- newAction->setSeparator(action->isSeparator());
- newAction->setCheckable(action->isCheckable());
- // delete action;
- break;
- case ADDSEPA:
- newAction = menu->addSeparator();
- break;
- }
+ if (actionType == ActionMenu)
+ menu->addMenu ((QMenu *) action);
+ else
+ menu->addAction (action);
jclass menuCls = env->GetObjectClass( menuPeer );
jmethodID mid = env->GetMethodID(menuCls, "add", "(J)V");
env->DeleteLocalRef(menuCls);
- env->CallVoidMethod( menuPeer, mid, (jlong)newAction );
+ env->CallVoidMethod( menuPeer, mid, (jlong)action );
env->DeleteGlobalRef( menuPeer );
if( itemPeer != NULL )
{
- setNativeObject( env, itemPeer, newAction );
- connectAction(newAction, env, itemPeer);
+ setNativeObject( env, itemPeer, action );
+ connectAction(action, env, itemPeer);
env->DeleteGlobalRef( itemPeer );
}
}
@@ -190,7 +179,7 @@ JNIEXPORT void JNICALL Java_gnu_java_awt_peer_qt_QtMenuPeer_insertSeperator
QMenu *menu = (QMenu *)getNativeObject( env, obj );
assert( menu );
mainThread->postEventToMain( new MenuAction( env, obj, NULL,
- menu, NULL, ADDSEPA ) );
+ menu, NULL, ActionSeparator ) );
}
/*
@@ -205,7 +194,7 @@ JNIEXPORT void JNICALL Java_gnu_java_awt_peer_qt_QtMenuPeer_insertItem
QAction *action = (QAction *)getNativeObject( env, item );
assert( action );
- mainThread->postEventToMain( new MenuAction( env, obj, item, menu, action, ADDITEM ));
+ mainThread->postEventToMain( new MenuAction( env, obj, item, menu, action, ActionItem ));
}
/*
@@ -220,7 +209,7 @@ JNIEXPORT void JNICALL Java_gnu_java_awt_peer_qt_QtMenuPeer_insertMenu
QMenu *insMenu = (QMenu *)getNativeObject(env, menu);
assert( insMenu );
- mainThread->postEventToMain( new MenuAction( env, obj, menu, thisMenu, (QAction *)insMenu, ADDMENU ) );
+ mainThread->postEventToMain( new MenuAction( env, obj, menu, thisMenu, (QAction *)insMenu, ActionMenu ) );
}
/*
diff --git a/native/plugin/Makefile.am b/native/plugin/Makefile.am
index 7358381eb..e1331fe45 100644
--- a/native/plugin/Makefile.am
+++ b/native/plugin/Makefile.am
@@ -4,15 +4,15 @@ libgcjwebplugin_la_SOURCES = gcjwebplugin.cc
libgcjwebplugin_la_CXXFLAGS = \
-Wall -DAPPLETVIEWER_EXECUTABLE="\"$(bindir)/appletviewer\"" \
- $(MOZILLA_CFLAGS) $(GLIB_CFLAGS)
+ $(MOZILLA_CFLAGS) $(GLIB_CFLAGS) $(GTK_CFLAGS)
libgcjwebplugin_la_LDFLAGS = -avoid-version \
- $(GLIB_LIBS) \
+ $(GLIB_LIBS) $(GTK_LIBS) \
-lstdc++
-install-libLTLIBRARIES: $(lib_LTLIBRARIES)
- $(INSTALL) -d -m0755 $(DESTDIR)@PLUGIN_DIR@
- $(INSTALL) .libs/libgcjwebplugin.so $(DESTDIR)@PLUGIN_DIR@
+install-plugin: $(lib_LTLIBRARIES)
+ $(INSTALL) -d -m0755 $(DESTDIR)$(PLUGIN_DIR)
+ $(INSTALL) .libs/libgcjwebplugin.so $(DESTDIR)$(PLUGIN_DIR)
-uninstall-libLTLIBRARIES:
- rm -f $(DESTDIR)@PLUGIN_DIR@/libgcjwebplugin.so
+uninstall-plugin:
+ rm -f $(DESTDIR)$(PLUGIN_DIR)/libgcjwebplugin.so
diff --git a/native/plugin/gcjwebplugin.cc b/native/plugin/gcjwebplugin.cc
index bbb9809be..ad65c7ef1 100644
--- a/native/plugin/gcjwebplugin.cc
+++ b/native/plugin/gcjwebplugin.cc
@@ -49,6 +49,10 @@ exception statement from your version. */
// GLib includes.
#include <glib.h>
+#include <glib/gstdio.h>
+
+// GTK includes.
+#include <gtk/gtk.h>
// gcjwebplugin includes.
#include "config.h"
@@ -75,6 +79,10 @@ exception statement from your version. */
g_printerr ("%s:%d: thread %p: Error: %s: %s\n", __FILE__, __LINE__, \
g_thread_self (), first, second)
+#define PLUGIN_ERROR_THREE(first, second, third) \
+ g_printerr ("%s:%d: thread %p: Error: %s: %s: %s\n", __FILE__, \
+ __LINE__, g_thread_self (), first, second, third)
+
// Plugin information passed to about:plugins.
#define PLUGIN_NAME "GCJ Web Browser Plugin"
#define PLUGIN_DESC "The " PLUGIN_NAME " executes Java applets."
@@ -113,8 +121,25 @@ exception statement from your version. */
#define PLUGIN_FILE_EXTS "class,jar,zip"
#define PLUGIN_MIME_COUNT 1
-// Directory in which named pipes are created.
-#define PIPE_DIRECTORY "/tmp"
+// Security dialog messages.
+#define RESPONSE_TRUST_APPLET "Trust Applet"
+#define RESPONSE_TRUST_APPLET_ADD_TO_LIST "Trust Applet and Add to Whitelist"
+#define SECURITY_WARNING \
+ "%s wants to load an applet.\n" \
+ "GNU Classpath's security implementation is not complete.\n" \
+ "HOSTILE APPLETS WILL STEAL AND/OR DESTROY YOUR DATA!\n"
+#define SECURITY_DESCRIPTION \
+ "Click \"Cancel\" if you do not trust the source of this applet.\n" \
+ "Click \"Trust Applet\" to load and run this applet now.\n" \
+ "Click \"Trust Applet and Add To Whitelist\" to always load" \
+ " and run this applet from now on, without asking.\n" \
+ "The whitelist is a list of the URLs from which you trust" \
+ " applets.\n" \
+ "Your whitelist file is \" %s \"."
+#define FAILURE_MESSAGE \
+ "This page wants to load an applet.\n" \
+ "The appletviewer is missing or not installed properly in \"" \
+ APPLETVIEWER_EXECUTABLE "\"."
// Documentbase retrieval required definition.
static NS_DEFINE_IID (kIPluginTagInfo2IID, NS_IPLUGINTAGINFO2_IID);
@@ -122,6 +147,16 @@ static NS_DEFINE_IID (kIPluginTagInfo2IID, NS_IPLUGINTAGINFO2_IID);
// Browser function table.
static NPNetscapeFuncs browserFunctions;
+// Data directory for plugin.
+static gchar* data_directory;
+
+// Whitelist filename
+static gchar* whitelist_filename;
+
+// Keeps track of initialization. NP_Initialize should only be
+// called once.
+gboolean initialized = false;
+
// GCJPluginData stores all the data associated with a single plugin
// instance. A separate plugin instance is created for each <APPLET>
// tag. For now, each plugin instance spawns its own applet viewer
@@ -173,6 +208,12 @@ typedef union
static void plugin_data_new (GCJPluginData** data);
// Documentbase retrieval.
static gchar* plugin_get_documentbase (NPP instance);
+// plugin failure handling.
+static bool plugin_failed ();
+// Whitelist handling.
+static bool plugin_user_trusts_documentbase (char* documentbase);
+static bool plugin_ask_user_about_documentbase (char* documentbase);
+static void plugin_add_documentbase_to_whitelist (char* documentbase);
// Callback used to monitor input pipe status.
static gboolean plugin_in_pipe_callback (GIOChannel* source,
GIOCondition condition,
@@ -181,7 +222,7 @@ static gboolean plugin_in_pipe_callback (GIOChannel* source,
static gboolean plugin_out_pipe_callback (GIOChannel* source,
GIOCondition condition,
gpointer plugin_data);
-static void plugin_start_appletviewer (GCJPluginData* data);
+static NPError plugin_start_appletviewer (GCJPluginData* data);
static gchar* plugin_create_applet_tag (int16 argc, char* argn[],
char* argv[]);
static void plugin_send_message_to_appletviewer (GCJPluginData* data,
@@ -195,6 +236,11 @@ static void plugin_data_destroy (GCJPluginData** data);
static GMutex* plugin_instance_mutex = NULL;
// A counter used to create uniquely named pipes.
static gulong plugin_instance_counter = 0;
+// The user's documentbase whitelist.
+static GIOChannel* whitelist_file = NULL;
+// A global variable for reporting GLib errors. This must be free'd
+// and set to NULL after each use.
+static GError* channel_error = NULL;
// Functions prefixed by GCJ_ are instance functions. They are called
// by the browser and operate on instances of GCJPluginData.
@@ -224,7 +270,7 @@ GCJ_New (NPMIMEType pluginType, NPP instance, uint16 mode,
NPError np_error = NPERR_NO_ERROR;
GCJPluginData* data = NULL;
- GError* channel_error = NULL;
+
gchar* documentbase = NULL;
gchar* read_message = NULL;
gchar* applet_tag = NULL;
@@ -278,13 +324,19 @@ GCJ_New (NPMIMEType pluginType, NPP instance, uint16 mode,
goto cleanup_appletviewer_mutex;
}
+ if (!plugin_user_trusts_documentbase (documentbase))
+ {
+ PLUGIN_ERROR ("User does not trust applet.");
+ np_error = NPERR_GENERIC_ERROR;
+ goto cleanup_appletviewer_mutex;
+ }
+
// Create appletviewer-to-plugin pipe which we refer to as the input
// pipe.
// data->in_pipe_name
- data->in_pipe_name = g_strdup_printf (PIPE_DIRECTORY
- "/gcj-%s-appletviewer-to-plugin",
- data->instance_string);
+ data->in_pipe_name = g_strdup_printf ("%s/gcj-%s-appletviewer-to-plugin",
+ data_directory, data->instance_string);
if (!data->in_pipe_name)
{
PLUGIN_ERROR ("Failed to create input pipe name.");
@@ -305,9 +357,8 @@ GCJ_New (NPMIMEType pluginType, NPP instance, uint16 mode,
// output pipe.
// data->out_pipe_name
- data->out_pipe_name = g_strdup_printf (PIPE_DIRECTORY
- "/gcj-%s-plugin-to-appletviewer",
- data->instance_string);
+ data->out_pipe_name = g_strdup_printf ("%s/gcj-%s-plugin-to-appletviewer",
+ data_directory, data->instance_string);
if (!data->out_pipe_name)
{
@@ -332,9 +383,17 @@ GCJ_New (NPMIMEType pluginType, NPP instance, uint16 mode,
// appletviewer, create the IO channels and install the channel
// watch callbacks.
g_mutex_lock (data->appletviewer_mutex);
-
- plugin_start_appletviewer (data);
-
+
+ np_error = plugin_start_appletviewer (data);
+
+ // If the appletviewer is not installed, then a dialog box will
+ // show up and the plugin will be killed.
+ if (np_error != NPERR_NO_ERROR)
+ {
+ if (plugin_failed ())
+ goto cleanup_applet_failure;
+ }
+
// Create plugin-to-appletviewer channel. The default encoding for
// the file is UTF-8.
// data->out_to_appletviewer
@@ -342,16 +401,19 @@ GCJ_New (NPMIMEType pluginType, NPP instance, uint16 mode,
"w", &channel_error);
if (!data->out_to_appletviewer)
{
- PLUGIN_ERROR_TWO ("Failed to create output channel",
- channel_error->message);
+ if (channel_error)
+ {
+ PLUGIN_ERROR_TWO ("Failed to create output channel",
+ channel_error->message);
+ g_error_free (channel_error);
+ channel_error = NULL;
+ }
+ else
+ PLUGIN_ERROR ("Failed to create output channel");
+
np_error = NPERR_GENERIC_ERROR;
goto cleanup_out_to_appletviewer;
}
- if (channel_error)
- {
- g_error_free (channel_error);
- channel_error = NULL;
- }
// Watch for hangup and error signals on the output pipe.
data->out_watch_source =
@@ -366,16 +428,19 @@ GCJ_New (NPMIMEType pluginType, NPP instance, uint16 mode,
"r", &channel_error);
if (!data->in_from_appletviewer)
{
- PLUGIN_ERROR_TWO ("Failed to create input channel",
- channel_error->message);
+ if (channel_error)
+ {
+ PLUGIN_ERROR_TWO ("Failed to create input channel",
+ channel_error->message);
+ g_error_free (channel_error);
+ channel_error = NULL;
+ }
+ else
+ PLUGIN_ERROR ("Failed to create input channel");
+
np_error = NPERR_GENERIC_ERROR;
goto cleanup_in_from_appletviewer;
}
- if (channel_error)
- {
- g_error_free (channel_error);
- channel_error = NULL;
- }
// Watch for hangup and error signals on the input pipe.
data->in_watch_source =
@@ -390,16 +455,19 @@ GCJ_New (NPMIMEType pluginType, NPP instance, uint16 mode,
&channel_error)
!= G_IO_STATUS_NORMAL)
{
- PLUGIN_ERROR_TWO ("Receiving confirmation from appletviewer failed",
- channel_error->message);
+ if (channel_error)
+ {
+ PLUGIN_ERROR_TWO ("Receiving confirmation from appletviewer failed",
+ channel_error->message);
+ g_error_free (channel_error);
+ channel_error = NULL;
+ }
+ else
+ PLUGIN_ERROR ("Receiving confirmation from appletviewer failed");
+
np_error = NPERR_GENERIC_ERROR;
goto cleanup_in_watch_source;
}
- if (channel_error)
- {
- g_error_free (channel_error);
- channel_error = NULL;
- }
PLUGIN_DEBUG ("GCJ_New: got confirmation that appletviewer is running.");
data->appletviewer_alive = TRUE;
@@ -448,7 +516,8 @@ GCJ_New (NPMIMEType pluginType, NPP instance, uint16 mode,
// cleanup_out_pipe:
// Delete output pipe.
unlink (data->out_pipe_name);
-
+
+ cleanup_applet_failure:
cleanup_out_pipe_name:
g_free (data->out_pipe_name);
data->out_pipe_name = NULL;
@@ -480,7 +549,6 @@ GCJ_New (NPMIMEType pluginType, NPP instance, uint16 mode,
instance->pdata = NULL;
cleanup_done:
-
g_free (tag_message);
tag_message = NULL;
g_free (applet_tag);
@@ -602,6 +670,7 @@ GCJ_SetWindow (NPP instance, NPWindow* window)
window->width);
plugin_send_message_to_appletviewer (data, width_message);
g_free (width_message);
+ width_message = NULL;
// Store the new width.
data->window_width = window->width;
@@ -619,6 +688,7 @@ GCJ_SetWindow (NPP instance, NPWindow* window)
window->height);
plugin_send_message_to_appletviewer (data, height_message);
g_free (height_message);
+ height_message = NULL;
// Store the new height.
data->window_height = window->height;
@@ -651,6 +721,7 @@ GCJ_SetWindow (NPP instance, NPWindow* window)
(gulong) window->window);
plugin_send_message_to_appletviewer (data, window_message);
g_free (window_message);
+ window_message = NULL;
g_mutex_unlock (data->appletviewer_mutex);
@@ -833,6 +904,201 @@ plugin_get_documentbase (NPP instance)
return documentbase_copy;
}
+// This function shows a error message if the appletviewer has
+// not been installed. It returns true, if the user presses the
+// ok button.
+static bool
+plugin_failed ()
+{
+ GtkWidget* dialog = NULL;
+ GtkWidget* ok_button = NULL;
+
+ dialog = gtk_message_dialog_new (NULL,
+ GTK_DIALOG_MODAL,
+ GTK_MESSAGE_WARNING,
+ GTK_BUTTONS_NONE,
+ FAILURE_MESSAGE);
+ ok_button = gtk_dialog_add_button (GTK_DIALOG (dialog),
+ GTK_STOCK_OK,
+ GTK_RESPONSE_OK);
+ gtk_widget_show_all (dialog);
+ if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK)
+ {
+ gtk_widget_destroy (dialog);
+ return true;
+ }
+ return false;
+}
+
+// plugin_user_trusts_documentbase returns true if the given
+// documentbase is in the documentbase whitelist. Otherwise it asks
+// the user if he trusts the given documentbase by calling
+// plugin_ask_user_about_documentbase.
+static bool
+plugin_user_trusts_documentbase (char* documentbase)
+{
+ bool applet_in_whitelist = false;
+
+ // Check if documentbase is in whitelist.
+ while (true)
+ {
+ gchar* whitelist_entry = NULL;
+ gchar* newline_documentbase = NULL;
+
+ // If reading fails, break out of this loop with
+ // applet_in_whitelist still set to false.
+ if (g_io_channel_read_line (whitelist_file, &whitelist_entry,
+ NULL, NULL, &channel_error)
+ != G_IO_STATUS_NORMAL)
+ {
+ if (channel_error)
+ {
+ PLUGIN_ERROR_TWO ("Failed to read line from whitelist file",
+ channel_error->message);
+ g_error_free (channel_error);
+ channel_error = NULL;
+ }
+ else
+ PLUGIN_ERROR ("Failed to open whitelist file.");
+ g_free (whitelist_entry);
+ whitelist_entry = NULL;
+ break;
+ }
+
+ newline_documentbase = g_strdup_printf ("%s\n", documentbase);
+ if (!strcmp (newline_documentbase, whitelist_entry))
+ {
+ applet_in_whitelist = true;
+ g_free (newline_documentbase);
+ newline_documentbase = NULL;
+ g_free (whitelist_entry);
+ whitelist_entry = NULL;
+ break;
+ }
+ g_free (whitelist_entry);
+ whitelist_entry = NULL;
+ g_free (newline_documentbase);
+ newline_documentbase = NULL;
+ }
+
+ return applet_in_whitelist ? true
+ : plugin_ask_user_about_documentbase (documentbase);
+}
+
+// plugin_add_documentbase_to_whitelist adds the given documentbase to
+// the user's documentbase whitelist.
+static void
+plugin_add_documentbase_to_whitelist (char* documentbase)
+{
+ gsize bytes_written = 0;
+ char* newline_documentbase = NULL;
+ GIOStatus status = G_IO_STATUS_NORMAL;
+
+ newline_documentbase = g_strdup_printf ("%s\n", documentbase);
+ status = g_io_channel_write_chars (whitelist_file,
+ newline_documentbase, -1, &bytes_written,
+ &channel_error);
+ g_free (newline_documentbase);
+ newline_documentbase = NULL;
+
+ if (status != G_IO_STATUS_NORMAL)
+ {
+ if (channel_error)
+ {
+ PLUGIN_ERROR_TWO ("Error writing to whitelist file",
+ channel_error->message);
+ g_error_free (channel_error);
+ channel_error = NULL;
+ }
+ else
+ PLUGIN_ERROR ("Error writing to whitelist file.");
+ }
+
+ if (g_io_channel_flush (whitelist_file, &channel_error)
+ != G_IO_STATUS_NORMAL)
+ {
+ if (channel_error)
+ {
+ PLUGIN_ERROR_TWO ("Failed to write whitelist file",
+ channel_error->message);
+ g_error_free (channel_error);
+ channel_error = NULL;
+ }
+ else
+ PLUGIN_ERROR ("Failed to write whitelist file.");
+ }
+
+ if (g_io_channel_shutdown (whitelist_file, TRUE, &channel_error)
+ != G_IO_STATUS_NORMAL)
+ {
+ if (channel_error)
+ {
+ PLUGIN_ERROR_TWO ("Failed to close whitelist file",
+ channel_error->message);
+ g_error_free (channel_error);
+ channel_error = NULL;
+ }
+ else
+ PLUGIN_ERROR ("Failed to close whitelist file.");
+ }
+}
+
+// plugin_ask_user_about_documentbase puts up a dialog box that asks if the
+// user trusts applets from this documentbase. The user has three
+// options: "Cancel", "Trust Applet" and "Trust Applet and Add to
+// Whitelist". If the user selects Cancel (the default) then a
+// generic error code is returned from GCJ_New, telling the browser
+// that the applet failed to load. If the user selects "Trust Applet"
+// then plugin loading proceeds. If the user selects "Trust Applet
+// and Add to Whitelist" then this documentbase is added to the user's
+// applet whitelist and plugin loading proceeds.
+static bool
+plugin_ask_user_about_documentbase (char* documentbase)
+{
+ GtkWidget* dialog = NULL;
+ GtkWidget* ok_button = NULL;
+ GtkWidget* cancel_button = NULL;
+ GtkWidget* whitelist_button = NULL;
+ gint dialog_response = GTK_RESPONSE_NONE;
+
+ dialog = gtk_message_dialog_new (NULL,
+ GTK_DIALOG_MODAL,
+ GTK_MESSAGE_WARNING,
+ GTK_BUTTONS_NONE,
+ SECURITY_WARNING,
+ documentbase);
+ gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
+ SECURITY_DESCRIPTION, whitelist_filename);
+
+ cancel_button = gtk_dialog_add_button (GTK_DIALOG (dialog),
+ GTK_STOCK_CANCEL,
+ GTK_RESPONSE_CANCEL);
+ ok_button = gtk_dialog_add_button (GTK_DIALOG (dialog),
+ RESPONSE_TRUST_APPLET,
+ GTK_RESPONSE_OK);
+ whitelist_button = gtk_dialog_add_button (GTK_DIALOG (dialog),
+ RESPONSE_TRUST_APPLET_ADD_TO_LIST,
+ GTK_RESPONSE_APPLY);
+ gtk_widget_grab_focus (cancel_button);
+
+ gtk_widget_show_all (dialog);
+ dialog_response = gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
+ if (dialog_response == GTK_RESPONSE_CANCEL)
+ {
+ // The user does not trust this documentbase.
+ return false;
+ }
+ else if (dialog_response == GTK_RESPONSE_APPLY)
+ {
+ // The user wants this documentbase added to his documentbase
+ // whitelist.
+ plugin_add_documentbase_to_whitelist (documentbase);
+ }
+ // The user trusts this documentbase.
+ return true;
+}
+
// plugin_in_pipe_callback is called when data is available on the
// input pipe, or when the appletviewer crashes or is killed. It may
// be called after data has been destroyed in which case it simply
@@ -858,7 +1124,6 @@ plugin_in_pipe_callback (GIOChannel* source,
if (condition & G_IO_IN)
{
- GError* channel_error = NULL;
gchar* message = NULL;
if (g_io_channel_read_line (data->in_from_appletviewer,
@@ -866,8 +1131,15 @@ plugin_in_pipe_callback (GIOChannel* source,
&channel_error)
!= G_IO_STATUS_NORMAL)
{
- PLUGIN_ERROR_TWO ("Failed to read line from input channel",
- channel_error->message);
+ if (channel_error)
+ {
+ PLUGIN_ERROR_TWO ("Failed to read line from input channel",
+ channel_error->message);
+ g_error_free (channel_error);
+ channel_error = NULL;
+ }
+ else
+ PLUGIN_ERROR ("Failed to read line from input channel");
}
else
{
@@ -899,12 +1171,6 @@ plugin_in_pipe_callback (GIOChannel* source,
g_print (" PIPE: plugin read %s\n", message);
}
- if (channel_error)
- {
- g_error_free (channel_error);
- channel_error = NULL;
- }
-
g_free (message);
message = NULL;
@@ -958,14 +1224,14 @@ plugin_out_pipe_callback (GIOChannel* source,
return FALSE;
}
-static void
+static NPError
plugin_start_appletviewer (GCJPluginData* data)
{
PLUGIN_DEBUG ("plugin_start_appletviewer");
-
+ NPError error = NPERR_NO_ERROR;
+
if (!data->appletviewer_alive)
{
- GError* spawn_error = NULL;
gchar* command_line[3] = { NULL, NULL, NULL };
command_line[0] = g_strdup (APPLETVIEWER_EXECUTABLE);
@@ -977,25 +1243,32 @@ plugin_start_appletviewer (GCJPluginData* data)
command_line[2] = NULL;
if (!g_spawn_async (NULL, command_line, NULL, (GSpawnFlags) 0,
- NULL, NULL, NULL, &spawn_error))
+ NULL, NULL, NULL, &channel_error))
{
- PLUGIN_ERROR_TWO ("Failed to spawn applet viewer",
- spawn_error->message);
+ if (channel_error)
+ {
+ PLUGIN_ERROR_TWO ("Failed to spawn applet viewer",
+ channel_error->message);
+ g_error_free (channel_error);
+ channel_error = NULL;
+ }
+ else
+ PLUGIN_ERROR ("Failed to spawn applet viewer");
+ error = NPERR_GENERIC_ERROR;
goto cleanup;
}
cleanup:
g_free (command_line[0]);
+ command_line[0] = NULL;
g_free (command_line[1]);
+ command_line[1] = NULL;
g_free (command_line[2]);
- if (spawn_error)
- {
- g_error_free (spawn_error);
- spawn_error = NULL;
- }
+ command_line[2] = NULL;
}
PLUGIN_DEBUG ("plugin_start_appletviewer return");
+ return error;
}
// Build up the applet tag string that we'll send to the applet
@@ -1015,30 +1288,35 @@ plugin_create_applet_tag (int16 argc, char* argn[], char* argv[])
gchar* code = g_strdup_printf ("CODE=\"%s\" ", argv[i]);
applet_tag = g_strconcat (applet_tag, code, NULL);
g_free (code);
+ code = NULL;
}
else if (!g_ascii_strcasecmp (argn[i], "codebase"))
{
gchar* codebase = g_strdup_printf ("CODEBASE=\"%s\" ", argv[i]);
applet_tag = g_strconcat (applet_tag, codebase, NULL);
g_free (codebase);
+ codebase = NULL;
}
else if (!g_ascii_strcasecmp (argn[i], "archive"))
{
gchar* archive = g_strdup_printf ("ARCHIVE=\"%s\" ", argv[i]);
applet_tag = g_strconcat (applet_tag, archive, NULL);
g_free (archive);
+ archive = NULL;
}
else if (!g_ascii_strcasecmp (argn[i], "width"))
{
gchar* width = g_strdup_printf ("WIDTH=\"%s\" ", argv[i]);
applet_tag = g_strconcat (applet_tag, width, NULL);
g_free (width);
+ width = NULL;
}
else if (!g_ascii_strcasecmp (argn[i], "height"))
{
gchar* height = g_strdup_printf ("HEIGHT=\"%s\" ", argv[i]);
applet_tag = g_strconcat (applet_tag, height, NULL);
g_free (height);
+ height = NULL;
}
else
{
@@ -1046,10 +1324,14 @@ plugin_create_applet_tag (int16 argc, char* argn[], char* argv[])
// characters will pass through the pipe.
if (argv[i] != '\0')
{
- gchar* escaped = g_strescape (argv[i], NULL);
+ gchar* escaped = NULL;
+
+ escaped = g_strescape (argv[i], NULL);
parameters = g_strconcat (parameters, "<PARAM NAME=\"", argn[i],
"\" VALUE=\"", escaped, "\">", NULL);
+
g_free (escaped);
+ escaped = NULL;
}
}
}
@@ -1073,7 +1355,6 @@ plugin_send_message_to_appletviewer (GCJPluginData* data, gchar const* message)
if (data->appletviewer_alive)
{
- GError* channel_error = NULL;
gchar* newline_message = NULL;
gsize bytes_written = 0;
@@ -1086,27 +1367,34 @@ plugin_send_message_to_appletviewer (GCJPluginData* data, gchar const* message)
if (g_io_channel_write_chars (data->out_to_appletviewer,
newline_message, -1, &bytes_written,
&channel_error)
- != G_IO_STATUS_NORMAL)
- PLUGIN_ERROR_TWO ("Failed to write bytes to output channel",
- channel_error->message);
-
- if (channel_error)
+ != G_IO_STATUS_NORMAL)
{
- g_error_free (channel_error);
- channel_error = NULL;
- }
+ if (channel_error)
+ {
+ PLUGIN_ERROR_TWO ("Failed to write bytes to output channel",
+ channel_error->message);
+ g_error_free (channel_error);
+ channel_error = NULL;
+ }
+ else
+ PLUGIN_ERROR ("Failed to write bytes to output channel");
+ }
if (g_io_channel_flush (data->out_to_appletviewer, &channel_error)
!= G_IO_STATUS_NORMAL)
- PLUGIN_ERROR_TWO ("Failed to flush bytes to output channel",
- channel_error->message);
-
- if (channel_error)
{
- g_error_free (channel_error);
- channel_error = NULL;
+ if (channel_error)
+ {
+ PLUGIN_ERROR_TWO ("Failed to flush bytes to output channel",
+ channel_error->message);
+ g_error_free (channel_error);
+ channel_error = NULL;
+ }
+ else
+ PLUGIN_ERROR ("Failed to flush bytes to output channel");
}
g_free (newline_message);
+ newline_message = NULL;
g_print (" PIPE: plugin wrote %s\n", message);
}
@@ -1135,7 +1423,6 @@ plugin_stop_appletviewer (GCJPluginData* data)
if (data->appletviewer_alive)
{
// Shut down the appletviewer.
- GError* channel_error = NULL;
gsize bytes_written = 0;
if (data->out_to_appletviewer)
@@ -1143,36 +1430,45 @@ plugin_stop_appletviewer (GCJPluginData* data)
if (g_io_channel_write_chars (data->out_to_appletviewer, "shutdown",
-1, &bytes_written, &channel_error)
!= G_IO_STATUS_NORMAL)
- PLUGIN_ERROR_TWO ("Failed to write shutdown message to"
- " appletviewer", channel_error->message);
-
- if (channel_error)
{
- g_error_free (channel_error);
- channel_error = NULL;
+ if (channel_error)
+ {
+ PLUGIN_ERROR_TWO ("Failed to write shutdown message to"
+ " appletviewer", channel_error->message);
+ g_error_free (channel_error);
+ channel_error = NULL;
+ }
+ else
+ PLUGIN_ERROR ("Failed to write shutdown message to");
}
if (g_io_channel_flush (data->out_to_appletviewer, &channel_error)
!= G_IO_STATUS_NORMAL)
- PLUGIN_ERROR_TWO ("Failed to write shutdown message to"
- " appletviewer", channel_error->message);
-
- if (channel_error)
{
- g_error_free (channel_error);
- channel_error = NULL;
+ if (channel_error)
+ {
+ PLUGIN_ERROR_TWO ("Failed to write shutdown message to"
+ " appletviewer", channel_error->message);
+ g_error_free (channel_error);
+ channel_error = NULL;
+ }
+ else
+ PLUGIN_ERROR ("Failed to write shutdown message to");
}
if (g_io_channel_shutdown (data->out_to_appletviewer,
TRUE, &channel_error)
!= G_IO_STATUS_NORMAL)
- PLUGIN_ERROR_TWO ("Failed to shut down appletviewer"
- " output channel", channel_error->message);
-
- if (channel_error)
{
- g_error_free (channel_error);
- channel_error = NULL;
+ if (channel_error)
+ {
+ PLUGIN_ERROR_TWO ("Failed to shut down appletviewer"
+ " output channel", channel_error->message);
+ g_error_free (channel_error);
+ channel_error = NULL;
+ }
+ else
+ PLUGIN_ERROR ("Failed to shut down appletviewer");
}
}
@@ -1181,13 +1477,16 @@ plugin_stop_appletviewer (GCJPluginData* data)
if (g_io_channel_shutdown (data->in_from_appletviewer,
TRUE, &channel_error)
!= G_IO_STATUS_NORMAL)
- PLUGIN_ERROR_TWO ("Failed to shut down appletviewer"
- " input channel", channel_error->message);
-
- if (channel_error)
{
- g_error_free (channel_error);
- channel_error = NULL;
+ if (channel_error)
+ {
+ PLUGIN_ERROR_TWO ("Failed to shut down appletviewer"
+ " input channel", channel_error->message);
+ g_error_free (channel_error);
+ channel_error = NULL;
+ }
+ else
+ PLUGIN_ERROR ("Failed to shut down appletviewer");
}
}
}
@@ -1267,18 +1566,25 @@ plugin_data_destroy (GCJPluginData** data)
// implement and initializes a local table with browser functions that
// we may wish to call. Called once, after browser startup and before
// the first plugin instance is created.
+// The field 'initialized' is set to true once this function has
+// finished. If 'initialized' is already true at the beginning of
+// this function, then it is evident that NP_Initialize has already
+// been called. There is no need to call this function more than once and
+// this workaround avoids any duplicate calls.
NPError
NP_Initialize (NPNetscapeFuncs* browserTable, NPPluginFuncs* pluginTable)
{
PLUGIN_DEBUG ("NP_Initialize");
-
- if ((browserTable == NULL) || (pluginTable == NULL))
+
+ if (initialized)
+ return NPERR_NO_ERROR;
+ else if ((browserTable == NULL) || (pluginTable == NULL))
{
PLUGIN_ERROR ("Browser or plugin function table is NULL.");
return NPERR_INVALID_FUNCTABLE_ERROR;
}
-
+
// Ensure that the major version of the plugin API that the browser
// expects is not more recent than the major version of the API that
// we've implemented.
@@ -1307,6 +1613,45 @@ NP_Initialize (NPNetscapeFuncs* browserTable, NPPluginFuncs* pluginTable)
return NPERR_INVALID_FUNCTABLE_ERROR;
}
+ data_directory = g_strconcat(getenv("HOME"), "/.gcjwebplugin", NULL);
+ whitelist_filename = g_strconcat (data_directory, "/whitelist.txt", NULL);
+ // Make sure the plugin data directory exists, creating it if
+ // necessary.
+ if (!g_file_test (data_directory,
+ (GFileTest) (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)))
+ {
+ int file_error = 0;
+
+ file_error = g_mkdir (data_directory, 0700);
+ if (file_error != 0)
+ {
+ PLUGIN_ERROR_THREE ("Failed to create data directory",
+ data_directory,
+ strerror (errno));
+ return NPERR_GENERIC_ERROR;
+ }
+ }
+
+ // Open the user's documentbase whitelist.
+ whitelist_file = g_io_channel_new_file (whitelist_filename,
+ "a+", &channel_error);
+ if (!whitelist_file)
+ {
+ if (channel_error)
+ {
+ PLUGIN_ERROR_THREE ("Failed to open whitelist file",
+ whitelist_filename,
+ channel_error->message);
+ g_error_free (channel_error);
+ channel_error = NULL;
+ }
+ else
+ PLUGIN_ERROR_TWO ("Failed to open whitelist file",
+ whitelist_filename);
+
+ return NPERR_GENERIC_ERROR;
+ }
+
// Store in a local table the browser functions that we may use.
browserFunctions.version = browserTable->version;
browserFunctions.size = browserTable->size;
@@ -1339,7 +1684,8 @@ NP_Initialize (NPNetscapeFuncs* browserTable, NPPluginFuncs* pluginTable)
pluginTable->print = NewNPP_PrintProc (GCJ_Print);
pluginTable->urlnotify = NewNPP_URLNotifyProc (GCJ_URLNotify);
pluginTable->getvalue = NewNPP_GetValueProc (GCJ_GetValue);
-
+
+ initialized = true;
plugin_instance_mutex = g_mutex_new ();
PLUGIN_DEBUG ("NP_Initialize: using " APPLETVIEWER_EXECUTABLE ".");
@@ -1402,9 +1748,32 @@ NP_Shutdown (void)
PLUGIN_DEBUG ("NP_Shutdown");
// Free mutex.
- g_mutex_free (plugin_instance_mutex);
- plugin_instance_mutex = NULL;
+ if (plugin_instance_mutex)
+ {
+ g_mutex_free (plugin_instance_mutex);
+ plugin_instance_mutex = NULL;
+ }
+ if (whitelist_file)
+ {
+ g_io_channel_close (whitelist_file);
+ whitelist_file = NULL;
+ }
+
+ if (data_directory)
+ {
+ g_free (data_directory);
+ data_directory = NULL;
+ }
+
+ if (whitelist_filename)
+ {
+ g_free (whitelist_filename);
+ whitelist_filename = NULL;
+ }
+
+ initialized = false;
+
PLUGIN_DEBUG ("NP_Shutdown return");
return NPERR_NO_ERROR;