Initial revision

From-SVN: r102074
This commit is contained in:
Tom Tromey
2005-07-16 00:30:23 +00:00
parent 6f4434b39b
commit f911ba985a
4557 changed files with 1000262 additions and 0 deletions
+8
View File
@@ -0,0 +1,8 @@
*.o
*.a
*.lo
*.la
.libs
.deps
Makefile
Makefile.in
+9
View File
@@ -0,0 +1,9 @@
## Input file for automake to generate the Makefile.in used by configure
if CREATE_JNI_LIBRARIES
JNIDIR = jni
endif
SUBDIRS = fdlibm $(JNIDIR) target
DIST_SUBDIRS = fdlibm jni target
@@ -0,0 +1,8 @@
*.o
*.a
*.lo
*.la
.libs
.deps
Makefile
Makefile.in
@@ -0,0 +1,53 @@
noinst_LTLIBRARIES = libfdlibm.la
libfdlibm_la_SOURCES = \
dtoa.c \
e_acos.c \
e_asin.c \
e_atan2.c \
e_exp.c \
e_fmod.c \
e_log.c \
e_pow.c \
e_remainder.c \
e_rem_pio2.c \
e_scalb.c \
e_sqrt.c \
fdlibm.h \
ieeefp.h \
java-assert.h \
k_cos.c \
k_rem_pio2.c \
k_sin.c \
k_tan.c \
mprec.c \
mprec.h \
s_atan.c \
s_ceil.c \
s_copysign.c \
s_cos.c \
s_fabs.c \
sf_fabs.c \
s_finite.c \
s_floor.c \
sf_rint.c \
s_rint.c \
s_scalbn.c \
s_sin.c \
s_tan.c \
strtod.c \
w_acos.c \
w_asin.c \
w_atan2.c \
w_exp.c \
w_fmod.c \
w_log.c \
w_pow.c \
w_remainder.c \
w_sqrt.c
AM_LDFLAGS = @CLASSPATH_MODULE@
# We just want the standard flags for fdlibm since it is an upstream lib
# and our normal -pedantic -Wall -Werror breaks this lib. So no AM_CFLAGS.
# We also don't need extra includes, so no AM_CPPFLAGS either.
+906
View File
@@ -0,0 +1,906 @@
/****************************************************************
*
* The author of this software is David M. Gay.
*
* Copyright (c) 1991 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
* is included in all copies of any software which is or includes a copy
* or modification of this software and in all copies of the supporting
* documentation for such software.
*
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR AT&T MAKES ANY
* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
* OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
*
***************************************************************/
/* Please send bug reports to
David M. Gay
AT&T Bell Laboratories, Room 2C-463
600 Mountain Avenue
Murray Hill, NJ 07974-2070
U.S.A.
dmg@research.att.com or research!dmg
*/
#include "mprec.h"
#include <string.h>
static int
_DEFUN (quorem,
(b, S),
_Jv_Bigint * b _AND _Jv_Bigint * S)
{
int n;
long borrow, y;
unsigned long carry, q, ys;
unsigned long *bx, *bxe, *sx, *sxe;
#ifdef Pack_32
long z;
unsigned long si, zs;
#endif
n = S->_wds;
#ifdef DEBUG
/*debug*/ if (b->_wds > n)
/*debug*/ Bug ("oversize b in quorem");
#endif
if (b->_wds < n)
return 0;
sx = S->_x;
sxe = sx + --n;
bx = b->_x;
bxe = bx + n;
q = *bxe / (*sxe + 1); /* ensure q <= true quotient */
#ifdef DEBUG
/*debug*/ if (q > 9)
/*debug*/ Bug ("oversized quotient in quorem");
#endif
if (q)
{
borrow = 0;
carry = 0;
do
{
#ifdef Pack_32
si = *sx++;
ys = (si & 0xffff) * q + carry;
zs = (si >> 16) * q + (ys >> 16);
carry = zs >> 16;
y = (*bx & 0xffff) - (ys & 0xffff) + borrow;
borrow = y >> 16;
Sign_Extend (borrow, y);
z = (*bx >> 16) - (zs & 0xffff) + borrow;
borrow = z >> 16;
Sign_Extend (borrow, z);
Storeinc (bx, z, y);
#else
ys = *sx++ * q + carry;
carry = ys >> 16;
y = *bx - (ys & 0xffff) + borrow;
borrow = y >> 16;
Sign_Extend (borrow, y);
*bx++ = y & 0xffff;
#endif
}
while (sx <= sxe);
if (!*bxe)
{
bx = b->_x;
while (--bxe > bx && !*bxe)
--n;
b->_wds = n;
}
}
if (cmp (b, S) >= 0)
{
q++;
borrow = 0;
carry = 0;
bx = b->_x;
sx = S->_x;
do
{
#ifdef Pack_32
si = *sx++;
ys = (si & 0xffff) + carry;
zs = (si >> 16) + (ys >> 16);
carry = zs >> 16;
y = (*bx & 0xffff) - (ys & 0xffff) + borrow;
borrow = y >> 16;
Sign_Extend (borrow, y);
z = (*bx >> 16) - (zs & 0xffff) + borrow;
borrow = z >> 16;
Sign_Extend (borrow, z);
Storeinc (bx, z, y);
#else
ys = *sx++ + carry;
carry = ys >> 16;
y = *bx - (ys & 0xffff) + borrow;
borrow = y >> 16;
Sign_Extend (borrow, y);
*bx++ = y & 0xffff;
#endif
}
while (sx <= sxe);
bx = b->_x;
bxe = bx + n;
if (!*bxe)
{
while (--bxe > bx && !*bxe)
--n;
b->_wds = n;
}
}
return q;
}
#ifdef DEBUG
#include <stdio.h>
void
print (_Jv_Bigint * b)
{
int i, wds;
unsigned long *x, y;
wds = b->_wds;
x = b->_x+wds;
i = 0;
do
{
x--;
fprintf (stderr, "%08x", *x);
}
while (++i < wds);
fprintf (stderr, "\n");
}
#endif
/* dtoa for IEEE arithmetic (dmg): convert double to ASCII string.
*
* Inspired by "How to Print Floating-Point Numbers Accurately" by
* Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 92-101].
*
* Modifications:
* 1. Rather than iterating, we use a simple numeric overestimate
* to determine k = floor(log10(d)). We scale relevant
* quantities using O(log2(k)) rather than O(k) multiplications.
* 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't
* try to generate digits strictly left to right. Instead, we
* compute with fewer bits and propagate the carry if necessary
* when rounding the final digit up. This is often faster.
* 3. Under the assumption that input will be rounded nearest,
* mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22.
* That is, we allow equality in stopping tests when the
* round-nearest rule will give the same floating-point value
* as would satisfaction of the stopping test with strict
* inequality.
* 4. We remove common factors of powers of 2 from relevant
* quantities.
* 5. When converting floating-point integers less than 1e16,
* we use floating-point arithmetic rather than resorting
* to multiple-precision integers.
* 6. When asked to produce fewer than 15 digits, we first try
* to get by with floating-point arithmetic; we resort to
* multiple-precision integer arithmetic only if we cannot
* guarantee that the floating-point calculation has given
* the correctly rounded result. For k requested digits and
* "uniformly" distributed input, the probability is
* something like 10^(k-15) that we must resort to the long
* calculation.
*/
char *
_DEFUN (_dtoa_r,
(ptr, _d, mode, ndigits, decpt, sign, rve, float_type),
struct _Jv_reent *ptr _AND
double _d _AND
int mode _AND
int ndigits _AND
int *decpt _AND
int *sign _AND
char **rve _AND
int float_type)
{
/*
float_type == 0 for double precision, 1 for float.
Arguments ndigits, decpt, sign are similar to those
of ecvt and fcvt; trailing zeros are suppressed from
the returned string. If not null, *rve is set to point
to the end of the return value. If d is +-Infinity or NaN,
then *decpt is set to 9999.
mode:
0 ==> shortest string that yields d when read in
and rounded to nearest.
1 ==> like 0, but with Steele & White stopping rule;
e.g. with IEEE P754 arithmetic , mode 0 gives
1e23 whereas mode 1 gives 9.999999999999999e22.
2 ==> max(1,ndigits) significant digits. This gives a
return value similar to that of ecvt, except
that trailing zeros are suppressed.
3 ==> through ndigits past the decimal point. This
gives a return value similar to that from fcvt,
except that trailing zeros are suppressed, and
ndigits can be negative.
4-9 should give the same return values as 2-3, i.e.,
4 <= mode <= 9 ==> same return as mode
2 + (mode & 1). These modes are mainly for
debugging; often they run slower but sometimes
faster than modes 2-3.
4,5,8,9 ==> left-to-right digit generation.
6-9 ==> don't try fast floating-point estimate
(if applicable).
> 16 ==> Floating-point arg is treated as single precision.
Values of mode other than 0-9 are treated as mode 0.
Sufficient space is allocated to the return value
to hold the suppressed trailing zeros.
*/
int bbits, b2, b5, be, dig, i, ieps, ilim0, j, j1, k, k0,
k_check, leftright, m2, m5, s2, s5, try_quick;
int ilim = 0, ilim1 = 0, spec_case = 0;
union double_union d, d2, eps;
long L;
#ifndef Sudden_Underflow
int denorm;
unsigned long x;
#endif
_Jv_Bigint *b, *b1, *delta, *mlo = NULL, *mhi, *S;
double ds;
char *s, *s0;
d.d = _d;
if (ptr->_result)
{
ptr->_result->_k = ptr->_result_k;
ptr->_result->_maxwds = 1 << ptr->_result_k;
Bfree (ptr, ptr->_result);
ptr->_result = 0;
}
if (word0 (d) & Sign_bit)
{
/* set sign for everything, including 0's and NaNs */
*sign = 1;
word0 (d) &= ~Sign_bit; /* clear sign bit */
}
else
*sign = 0;
#if defined(IEEE_Arith) + defined(VAX)
#ifdef IEEE_Arith
if ((word0 (d) & Exp_mask) == Exp_mask)
#else
if (word0 (d) == 0x8000)
#endif
{
/* Infinity or NaN */
*decpt = 9999;
s =
#ifdef IEEE_Arith
!word1 (d) && !(word0 (d) & 0xfffff) ? "Infinity" :
#endif
"NaN";
if (rve)
*rve =
#ifdef IEEE_Arith
s[3] ? s + 8 :
#endif
s + 3;
return s;
}
#endif
#ifdef IBM
d.d += 0; /* normalize */
#endif
if (!d.d)
{
*decpt = 1;
s = "0";
if (rve)
*rve = s + 1;
return s;
}
b = d2b (ptr, d.d, &be, &bbits);
#ifdef Sudden_Underflow
i = (int) (word0 (d) >> Exp_shift1 & (Exp_mask >> Exp_shift1));
#else
if ((i = (int) (word0 (d) >> Exp_shift1 & (Exp_mask >> Exp_shift1))))
{
#endif
d2.d = d.d;
word0 (d2) &= Frac_mask1;
word0 (d2) |= Exp_11;
#ifdef IBM
if (j = 11 - hi0bits (word0 (d2) & Frac_mask))
d2.d /= 1 << j;
#endif
/* log(x) ~=~ log(1.5) + (x-1.5)/1.5
* log10(x) = log(x) / log(10)
* ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10))
* log10(d) = (i-Bias)*log(2)/log(10) + log10(d2)
*
* This suggests computing an approximation k to log10(d) by
*
* k = (i - Bias)*0.301029995663981
* + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 );
*
* We want k to be too large rather than too small.
* The error in the first-order Taylor series approximation
* is in our favor, so we just round up the constant enough
* to compensate for any error in the multiplication of
* (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077,
* and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14,
* adding 1e-13 to the constant term more than suffices.
* Hence we adjust the constant term to 0.1760912590558.
* (We could get a more accurate k by invoking log10,
* but this is probably not worthwhile.)
*/
i -= Bias;
#ifdef IBM
i <<= 2;
i += j;
#endif
#ifndef Sudden_Underflow
denorm = 0;
}
else
{
/* d is denormalized */
i = bbits + be + (Bias + (P - 1) - 1);
x = i > 32 ? word0 (d) << (64 - i) | word1 (d) >> (i - 32)
: word1 (d) << (32 - i);
d2.d = x;
word0 (d2) -= 31 * Exp_msk1; /* adjust exponent */
i -= (Bias + (P - 1) - 1) + 1;
denorm = 1;
}
#endif
ds = (d2.d - 1.5) * 0.289529654602168 + 0.1760912590558 + i * 0.301029995663981;
k = (int) ds;
if (ds < 0. && ds != k)
k--; /* want k = floor(ds) */
k_check = 1;
if (k >= 0 && k <= Ten_pmax)
{
if (d.d < tens[k])
k--;
k_check = 0;
}
j = bbits - i - 1;
if (j >= 0)
{
b2 = 0;
s2 = j;
}
else
{
b2 = -j;
s2 = 0;
}
if (k >= 0)
{
b5 = 0;
s5 = k;
s2 += k;
}
else
{
b2 -= k;
b5 = -k;
s5 = 0;
}
if (mode < 0 || mode > 9)
mode = 0;
try_quick = 1;
if (mode > 5)
{
mode -= 4;
try_quick = 0;
}
leftright = 1;
switch (mode)
{
case 0:
case 1:
ilim = ilim1 = -1;
i = 18;
ndigits = 0;
break;
case 2:
leftright = 0;
/* no break */
case 4:
if (ndigits <= 0)
ndigits = 1;
ilim = ilim1 = i = ndigits;
break;
case 3:
leftright = 0;
/* no break */
case 5:
i = ndigits + k + 1;
ilim = i;
ilim1 = i - 1;
if (i <= 0)
i = 1;
}
j = sizeof (unsigned long);
for (ptr->_result_k = 0; (int) (sizeof (_Jv_Bigint) - sizeof (unsigned long)) + j <= i;
j <<= 1)
ptr->_result_k++;
ptr->_result = Balloc (ptr, ptr->_result_k);
s = s0 = (char *) ptr->_result;
if (ilim >= 0 && ilim <= Quick_max && try_quick)
{
/* Try to get by with floating-point arithmetic. */
i = 0;
d2.d = d.d;
k0 = k;
ilim0 = ilim;
ieps = 2; /* conservative */
if (k > 0)
{
ds = tens[k & 0xf];
j = k >> 4;
if (j & Bletch)
{
/* prevent overflows */
j &= Bletch - 1;
d.d /= bigtens[n_bigtens - 1];
ieps++;
}
for (; j; j >>= 1, i++)
if (j & 1)
{
ieps++;
ds *= bigtens[i];
}
d.d /= ds;
}
else if ((j1 = -k))
{
d.d *= tens[j1 & 0xf];
for (j = j1 >> 4; j; j >>= 1, i++)
if (j & 1)
{
ieps++;
d.d *= bigtens[i];
}
}
if (k_check && d.d < 1. && ilim > 0)
{
if (ilim1 <= 0)
goto fast_failed;
ilim = ilim1;
k--;
d.d *= 10.;
ieps++;
}
eps.d = ieps * d.d + 7.;
word0 (eps) -= (P - 1) * Exp_msk1;
if (ilim == 0)
{
S = mhi = 0;
d.d -= 5.;
if (d.d > eps.d)
goto one_digit;
if (d.d < -eps.d)
goto no_digits;
goto fast_failed;
}
#ifndef No_leftright
if (leftright)
{
/* Use Steele & White method of only
* generating digits needed.
*/
eps.d = 0.5 / tens[ilim - 1] - eps.d;
for (i = 0;;)
{
L = d.d;
d.d -= L;
*s++ = '0' + (int) L;
if (d.d < eps.d)
goto ret1;
if (1. - d.d < eps.d)
goto bump_up;
if (++i >= ilim)
break;
eps.d *= 10.;
d.d *= 10.;
}
}
else
{
#endif
/* Generate ilim digits, then fix them up. */
eps.d *= tens[ilim - 1];
for (i = 1;; i++, d.d *= 10.)
{
L = d.d;
d.d -= L;
*s++ = '0' + (int) L;
if (i == ilim)
{
if (d.d > 0.5 + eps.d)
goto bump_up;
else if (d.d < 0.5 - eps.d)
{
while (*--s == '0');
s++;
goto ret1;
}
break;
}
}
#ifndef No_leftright
}
#endif
fast_failed:
s = s0;
d.d = d2.d;
k = k0;
ilim = ilim0;
}
/* Do we have a "small" integer? */
if (be >= 0 && k <= Int_max)
{
/* Yes. */
ds = tens[k];
if (ndigits < 0 && ilim <= 0)
{
S = mhi = 0;
if (ilim < 0 || d.d <= 5 * ds)
goto no_digits;
goto one_digit;
}
for (i = 1;; i++)
{
L = d.d / ds;
d.d -= L * ds;
#ifdef Check_FLT_ROUNDS
/* If FLT_ROUNDS == 2, L will usually be high by 1 */
if (d.d < 0)
{
L--;
d.d += ds;
}
#endif
*s++ = '0' + (int) L;
if (i == ilim)
{
d.d += d.d;
if (d.d > ds || (d.d == ds && L & 1))
{
bump_up:
while (*--s == '9')
if (s == s0)
{
k++;
*s = '0';
break;
}
++*s++;
}
break;
}
if (!(d.d *= 10.))
break;
}
goto ret1;
}
m2 = b2;
m5 = b5;
mhi = mlo = 0;
if (leftright)
{
if (mode < 2)
{
i =
#ifndef Sudden_Underflow
denorm ? be + (Bias + (P - 1) - 1 + 1) :
#endif
#ifdef IBM
1 + 4 * P - 3 - bbits + ((bbits + be - 1) & 3);
#else
1 + P - bbits;
#endif
}
else
{
j = ilim - 1;
if (m5 >= j)
m5 -= j;
else
{
s5 += j -= m5;
b5 += j;
m5 = 0;
}
if ((i = ilim) < 0)
{
m2 -= i;
i = 0;
}
}
b2 += i;
s2 += i;
mhi = i2b (ptr, 1);
}
if (m2 > 0 && s2 > 0)
{
i = m2 < s2 ? m2 : s2;
b2 -= i;
m2 -= i;
s2 -= i;
}
if (b5 > 0)
{
if (leftright)
{
if (m5 > 0)
{
mhi = pow5mult (ptr, mhi, m5);
b1 = mult (ptr, mhi, b);
Bfree (ptr, b);
b = b1;
}
if ((j = b5 - m5))
b = pow5mult (ptr, b, j);
}
else
b = pow5mult (ptr, b, b5);
}
S = i2b (ptr, 1);
if (s5 > 0)
S = pow5mult (ptr, S, s5);
/* Check for special case that d is a normalized power of 2. */
if (mode < 2)
{
if (!word1 (d) && !(word0 (d) & Bndry_mask)
#ifndef Sudden_Underflow
&& word0(d) & Exp_mask
#endif
)
{
/* The special case */
b2 += Log2P;
s2 += Log2P;
spec_case = 1;
}
else
spec_case = 0;
}
/* Arrange for convenient computation of quotients:
* shift left if necessary so divisor has 4 leading 0 bits.
*
* Perhaps we should just compute leading 28 bits of S once
* and for all and pass them and a shift to quorem, so it
* can do shifts and ors to compute the numerator for q.
*/
#ifdef Pack_32
if ((i = ((s5 ? 32 - hi0bits (S->_x[S->_wds - 1]) : 1) + s2) & 0x1f))
i = 32 - i;
#else
if ((i = ((s5 ? 32 - hi0bits (S->_x[S->_wds - 1]) : 1) + s2) & 0xf))
i = 16 - i;
#endif
if (i > 4)
{
i -= 4;
b2 += i;
m2 += i;
s2 += i;
}
else if (i < 4)
{
i += 28;
b2 += i;
m2 += i;
s2 += i;
}
if (b2 > 0)
b = lshift (ptr, b, b2);
if (s2 > 0)
S = lshift (ptr, S, s2);
if (k_check)
{
if (cmp (b, S) < 0)
{
k--;
b = multadd (ptr, b, 10, 0); /* we botched the k estimate */
if (leftright)
mhi = multadd (ptr, mhi, 10, 0);
ilim = ilim1;
}
}
if (ilim <= 0 && mode > 2)
{
if (ilim < 0 || cmp (b, S = multadd (ptr, S, 5, 0)) <= 0)
{
/* no digits, fcvt style */
no_digits:
k = -1 - ndigits;
goto ret;
}
one_digit:
*s++ = '1';
k++;
goto ret;
}
if (leftright)
{
if (m2 > 0)
mhi = lshift (ptr, mhi, m2);
/* Single precision case, */
if (float_type)
mhi = lshift (ptr, mhi, 29);
/* Compute mlo -- check for special case
* that d is a normalized power of 2.
*/
mlo = mhi;
if (spec_case)
{
mhi = Balloc (ptr, mhi->_k);
Bcopy (mhi, mlo);
mhi = lshift (ptr, mhi, Log2P);
}
for (i = 1;; i++)
{
dig = quorem (b, S) + '0';
/* Do we yet have the shortest decimal string
* that will round to d?
*/
j = cmp (b, mlo);
delta = diff (ptr, S, mhi);
j1 = delta->_sign ? 1 : cmp (b, delta);
Bfree (ptr, delta);
#ifndef ROUND_BIASED
if (j1 == 0 && !mode && !(word1 (d) & 1))
{
if (dig == '9')
goto round_9_up;
if (j > 0)
dig++;
*s++ = dig;
goto ret;
}
#endif
if (j < 0 || (j == 0 && !mode
#ifndef ROUND_BIASED
&& !(word1 (d) & 1)
#endif
))
{
if (j1 > 0)
{
b = lshift (ptr, b, 1);
j1 = cmp (b, S);
if ((j1 > 0 || (j1 == 0 && dig & 1))
&& dig++ == '9')
goto round_9_up;
}
*s++ = dig;
goto ret;
}
if (j1 > 0)
{
if (dig == '9')
{ /* possible if i == 1 */
round_9_up:
*s++ = '9';
goto roundoff;
}
*s++ = dig + 1;
goto ret;
}
*s++ = dig;
if (i == ilim)
break;
b = multadd (ptr, b, 10, 0);
if (mlo == mhi)
mlo = mhi = multadd (ptr, mhi, 10, 0);
else
{
mlo = multadd (ptr, mlo, 10, 0);
mhi = multadd (ptr, mhi, 10, 0);
}
}
}
else
for (i = 1;; i++)
{
*s++ = dig = quorem (b, S) + '0';
if (i >= ilim)
break;
b = multadd (ptr, b, 10, 0);
}
/* Round off last digit */
b = lshift (ptr, b, 1);
j = cmp (b, S);
if (j > 0 || (j == 0 && dig & 1))
{
roundoff:
while (*--s == '9')
if (s == s0)
{
k++;
*s++ = '1';
goto ret;
}
++*s++;
}
else
{
while (*--s == '0');
s++;
}
ret:
Bfree (ptr, S);
if (mhi)
{
if (mlo && mlo != mhi)
Bfree (ptr, mlo);
Bfree (ptr, mhi);
}
ret1:
Bfree (ptr, b);
*s = 0;
*decpt = k + 1;
if (rve)
*rve = s;
return s0;
}
_VOID
_DEFUN (_dtoa,
(_d, mode, ndigits, decpt, sign, rve, buf, float_type),
double _d _AND
int mode _AND
int ndigits _AND
int *decpt _AND
int *sign _AND
char **rve _AND
char *buf _AND
int float_type)
{
struct _Jv_reent reent;
char *p;
memset (&reent, 0, sizeof reent);
p = _dtoa_r (&reent, _d, mode, ndigits, decpt, sign, rve, float_type);
strcpy (buf, p);
return;
}
+111
View File
@@ -0,0 +1,111 @@
/* @(#)e_acos.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
/* __ieee754_acos(x)
* Method :
* acos(x) = pi/2 - asin(x)
* acos(-x) = pi/2 + asin(x)
* For |x|<=0.5
* acos(x) = pi/2 - (x + x*x^2*R(x^2)) (see asin.c)
* For x>0.5
* acos(x) = pi/2 - (pi/2 - 2asin(sqrt((1-x)/2)))
* = 2asin(sqrt((1-x)/2))
* = 2s + 2s*z*R(z) ...z=(1-x)/2, s=sqrt(z)
* = 2f + (2c + 2s*z*R(z))
* where f=hi part of s, and c = (z-f*f)/(s+f) is the correction term
* for f so that f+c ~ sqrt(z).
* For x<-0.5
* acos(x) = pi - 2asin(sqrt((1-|x|)/2))
* = pi - 0.5*(s+s*z*R(z)), where z=(1-|x|)/2,s=sqrt(z)
*
* Special cases:
* if x is NaN, return x itself;
* if |x|>1, return NaN with invalid signal.
*
* Function needed: sqrt
*/
#include "fdlibm.h"
#ifndef _DOUBLE_IS_32BITS
#ifdef __STDC__
static const double
#else
static double
#endif
one= 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */
pi = 3.14159265358979311600e+00, /* 0x400921FB, 0x54442D18 */
pio2_hi = 1.57079632679489655800e+00, /* 0x3FF921FB, 0x54442D18 */
pio2_lo = 6.12323399573676603587e-17, /* 0x3C91A626, 0x33145C07 */
pS0 = 1.66666666666666657415e-01, /* 0x3FC55555, 0x55555555 */
pS1 = -3.25565818622400915405e-01, /* 0xBFD4D612, 0x03EB6F7D */
pS2 = 2.01212532134862925881e-01, /* 0x3FC9C155, 0x0E884455 */
pS3 = -4.00555345006794114027e-02, /* 0xBFA48228, 0xB5688F3B */
pS4 = 7.91534994289814532176e-04, /* 0x3F49EFE0, 0x7501B288 */
pS5 = 3.47933107596021167570e-05, /* 0x3F023DE1, 0x0DFDF709 */
qS1 = -2.40339491173441421878e+00, /* 0xC0033A27, 0x1C8A2D4B */
qS2 = 2.02094576023350569471e+00, /* 0x40002AE5, 0x9C598AC8 */
qS3 = -6.88283971605453293030e-01, /* 0xBFE6066C, 0x1B8D0159 */
qS4 = 7.70381505559019352791e-02; /* 0x3FB3B8C5, 0xB12E9282 */
#ifdef __STDC__
double __ieee754_acos(double x)
#else
double __ieee754_acos(x)
double x;
#endif
{
double z,p,q,r,w,s,c,df;
int32_t hx,ix;
GET_HIGH_WORD(hx,x);
ix = hx&0x7fffffff;
if(ix>=0x3ff00000) { /* |x| >= 1 */
uint32_t lx;
GET_LOW_WORD(lx,x);
if(((ix-0x3ff00000)|lx)==0) { /* |x|==1 */
if(hx>0) return 0.0; /* acos(1) = 0 */
else return pi+2.0*pio2_lo; /* acos(-1)= pi */
}
return (x-x)/(x-x); /* acos(|x|>1) is NaN */
}
if(ix<0x3fe00000) { /* |x| < 0.5 */
if(ix<=0x3c600000) return pio2_hi+pio2_lo;/*if|x|<2**-57*/
z = x*x;
p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5)))));
q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4)));
r = p/q;
return pio2_hi - (x - (pio2_lo-x*r));
} else if (hx<0) { /* x < -0.5 */
z = (one+x)*0.5;
p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5)))));
q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4)));
s = __ieee754_sqrt(z);
r = p/q;
w = r*s-pio2_lo;
return pi - 2.0*(s+w);
} else { /* x > 0.5 */
z = (one-x)*0.5;
s = __ieee754_sqrt(z);
df = s;
SET_LOW_WORD(df,0);
c = (z-df*df)/(s+df);
p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5)))));
q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4)));
r = p/q;
w = r*s+c;
return 2.0*(df+w);
}
}
#endif /* defined(_DOUBLE_IS_32BITS) */
+120
View File
@@ -0,0 +1,120 @@
/* @(#)e_asin.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
/* __ieee754_asin(x)
* Method :
* Since asin(x) = x + x^3/6 + x^5*3/40 + x^7*15/336 + ...
* we approximate asin(x) on [0,0.5] by
* asin(x) = x + x*x^2*R(x^2)
* where
* R(x^2) is a rational approximation of (asin(x)-x)/x^3
* and its remez error is bounded by
* |(asin(x)-x)/x^3 - R(x^2)| < 2^(-58.75)
*
* For x in [0.5,1]
* asin(x) = pi/2-2*asin(sqrt((1-x)/2))
* Let y = (1-x), z = y/2, s := sqrt(z), and pio2_hi+pio2_lo=pi/2;
* then for x>0.98
* asin(x) = pi/2 - 2*(s+s*z*R(z))
* = pio2_hi - (2*(s+s*z*R(z)) - pio2_lo)
* For x<=0.98, let pio4_hi = pio2_hi/2, then
* f = hi part of s;
* c = sqrt(z) - f = (z-f*f)/(s+f) ...f+c=sqrt(z)
* and
* asin(x) = pi/2 - 2*(s+s*z*R(z))
* = pio4_hi+(pio4-2s)-(2s*z*R(z)-pio2_lo)
* = pio4_hi+(pio4-2f)-(2s*z*R(z)-(pio2_lo+2c))
*
* Special cases:
* if x is NaN, return x itself;
* if |x|>1, return NaN with invalid signal.
*
*/
#include "fdlibm.h"
#ifndef _DOUBLE_IS_32BITS
#ifdef __STDC__
static const double
#else
static double
#endif
one = 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */
huge = 1.000e+300,
pio2_hi = 1.57079632679489655800e+00, /* 0x3FF921FB, 0x54442D18 */
pio2_lo = 6.12323399573676603587e-17, /* 0x3C91A626, 0x33145C07 */
pio4_hi = 7.85398163397448278999e-01, /* 0x3FE921FB, 0x54442D18 */
/* coefficient for R(x^2) */
pS0 = 1.66666666666666657415e-01, /* 0x3FC55555, 0x55555555 */
pS1 = -3.25565818622400915405e-01, /* 0xBFD4D612, 0x03EB6F7D */
pS2 = 2.01212532134862925881e-01, /* 0x3FC9C155, 0x0E884455 */
pS3 = -4.00555345006794114027e-02, /* 0xBFA48228, 0xB5688F3B */
pS4 = 7.91534994289814532176e-04, /* 0x3F49EFE0, 0x7501B288 */
pS5 = 3.47933107596021167570e-05, /* 0x3F023DE1, 0x0DFDF709 */
qS1 = -2.40339491173441421878e+00, /* 0xC0033A27, 0x1C8A2D4B */
qS2 = 2.02094576023350569471e+00, /* 0x40002AE5, 0x9C598AC8 */
qS3 = -6.88283971605453293030e-01, /* 0xBFE6066C, 0x1B8D0159 */
qS4 = 7.70381505559019352791e-02; /* 0x3FB3B8C5, 0xB12E9282 */
#ifdef __STDC__
double __ieee754_asin(double x)
#else
double __ieee754_asin(x)
double x;
#endif
{
double t = 0., w, p, q, c, r, s;
int32_t hx,ix;
GET_HIGH_WORD(hx,x);
ix = hx&0x7fffffff;
if(ix>= 0x3ff00000) { /* |x|>= 1 */
uint32_t lx;
GET_LOW_WORD(lx,x);
if(((ix-0x3ff00000)|lx)==0)
/* asin(1)=+-pi/2 with inexact */
return x*pio2_hi+x*pio2_lo;
return (x-x)/(x-x); /* asin(|x|>1) is NaN */
} else if (ix<0x3fe00000) { /* |x|<0.5 */
if(ix<0x3e400000) { /* if |x| < 2**-27 */
if(huge+x>one) return x;/* return x with inexact if x!=0*/
} else
t = x*x;
p = t*(pS0+t*(pS1+t*(pS2+t*(pS3+t*(pS4+t*pS5)))));
q = one+t*(qS1+t*(qS2+t*(qS3+t*qS4)));
w = p/q;
return x+x*w;
}
/* 1> |x|>= 0.5 */
w = one-fabs(x);
t = w*0.5;
p = t*(pS0+t*(pS1+t*(pS2+t*(pS3+t*(pS4+t*pS5)))));
q = one+t*(qS1+t*(qS2+t*(qS3+t*qS4)));
s = __ieee754_sqrt(t);
if(ix>=0x3FEF3333) { /* if |x| > 0.975 */
w = p/q;
t = pio2_hi-(2.0*(s+s*w)-pio2_lo);
} else {
w = s;
SET_LOW_WORD(w,0);
c = (t-w*w)/(s+w);
r = p/q;
p = 2.0*s*r-(pio2_lo-2.0*c);
q = pio4_hi-2.0*w;
t = pio4_hi-(p-q);
}
if(hx>0) return t; else return -t;
}
#endif /* defined(_DOUBLE_IS_32BITS) */
+131
View File
@@ -0,0 +1,131 @@
/* @(#)e_atan2.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*
*/
/* __ieee754_atan2(y,x)
* Method :
* 1. Reduce y to positive by atan2(y,x)=-atan2(-y,x).
* 2. Reduce x to positive by (if x and y are unexceptional):
* ARG (x+iy) = arctan(y/x) ... if x > 0,
* ARG (x+iy) = pi - arctan[y/(-x)] ... if x < 0,
*
* Special cases:
*
* ATAN2((anything), NaN ) is NaN;
* ATAN2(NAN , (anything) ) is NaN;
* ATAN2(+-0, +(anything but NaN)) is +-0 ;
* ATAN2(+-0, -(anything but NaN)) is +-pi ;
* ATAN2(+-(anything but 0 and NaN), 0) is +-pi/2;
* ATAN2(+-(anything but INF and NaN), +INF) is +-0 ;
* ATAN2(+-(anything but INF and NaN), -INF) is +-pi;
* ATAN2(+-INF,+INF ) is +-pi/4 ;
* ATAN2(+-INF,-INF ) is +-3pi/4;
* ATAN2(+-INF, (anything but,0,NaN, and INF)) is +-pi/2;
*
* Constants:
* The hexadecimal values are the intended ones for the following
* constants. The decimal values may be used, provided that the
* compiler will convert from decimal to binary accurately enough
* to produce the hexadecimal values shown.
*/
#include "fdlibm.h"
#ifndef _DOUBLE_IS_32BITS
#ifdef __STDC__
static const double
#else
static double
#endif
tiny = 1.0e-300,
zero = 0.0,
pi_o_4 = 7.8539816339744827900E-01, /* 0x3FE921FB, 0x54442D18 */
pi_o_2 = 1.5707963267948965580E+00, /* 0x3FF921FB, 0x54442D18 */
pi = 3.1415926535897931160E+00, /* 0x400921FB, 0x54442D18 */
pi_lo = 1.2246467991473531772E-16; /* 0x3CA1A626, 0x33145C07 */
#ifdef __STDC__
double __ieee754_atan2(double y, double x)
#else
double __ieee754_atan2(y,x)
double y,x;
#endif
{
double z;
int32_t k,m,hx,hy,ix,iy;
uint32_t lx,ly;
EXTRACT_WORDS(hx,lx,x);
ix = hx&0x7fffffff;
EXTRACT_WORDS(hy,ly,y);
iy = hy&0x7fffffff;
if(((ix|((lx|-lx)>>31))>0x7ff00000)||
((iy|((ly|-ly)>>31))>0x7ff00000)) /* x or y is NaN */
return x+y;
if(((hx-0x3ff00000)|lx)==0) return atan(y); /* x=1.0 */
m = ((hy>>31)&1)|((hx>>30)&2); /* 2*sign(x)+sign(y) */
/* when y = 0 */
if((iy|ly)==0) {
switch(m) {
case 0:
case 1: return y; /* atan(+-0,+anything)=+-0 */
case 2: return pi+tiny;/* atan(+0,-anything) = pi */
case 3: return -pi-tiny;/* atan(-0,-anything) =-pi */
}
}
/* when x = 0 */
if((ix|lx)==0) return (hy<0)? -pi_o_2-tiny: pi_o_2+tiny;
/* when x is INF */
if(ix==0x7ff00000) {
if(iy==0x7ff00000) {
switch(m) {
case 0: return pi_o_4+tiny;/* atan(+INF,+INF) */
case 1: return -pi_o_4-tiny;/* atan(-INF,+INF) */
case 2: return 3.0*pi_o_4+tiny;/*atan(+INF,-INF)*/
case 3: return -3.0*pi_o_4-tiny;/*atan(-INF,-INF)*/
}
} else {
switch(m) {
case 0: return zero ; /* atan(+...,+INF) */
case 1: return -zero ; /* atan(-...,+INF) */
case 2: return pi+tiny ; /* atan(+...,-INF) */
case 3: return -pi-tiny ; /* atan(-...,-INF) */
}
}
}
/* when y is INF */
if(iy==0x7ff00000) return (hy<0)? -pi_o_2-tiny: pi_o_2+tiny;
/* compute y/x */
k = (iy-ix)>>20;
if(k > 60) z=pi_o_2+0.5*pi_lo; /* |y/x| > 2**60 */
else if(hx<0&&k<-60) z=0.0; /* |y|/x < -2**60 */
else z=atan(fabs(y/x)); /* safe to do y/x */
switch (m) {
case 0: return z ; /* atan(+,+) */
case 1: {
uint32_t zh;
GET_HIGH_WORD(zh,z);
SET_HIGH_WORD(z,zh ^ 0x80000000);
}
return z ; /* atan(-,+) */
case 2: return pi-(z-pi_lo);/* atan(+,-) */
default: /* case 3 */
return (z-pi_lo)-pi;/* atan(-,-) */
}
}
#endif /* defined(_DOUBLE_IS_32BITS) */
+167
View File
@@ -0,0 +1,167 @@
/* @(#)e_exp.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
/* __ieee754_exp(x)
* Returns the exponential of x.
*
* Method
* 1. Argument reduction:
* Reduce x to an r so that |r| <= 0.5*ln2 ~ 0.34658.
* Given x, find r and integer k such that
*
* x = k*ln2 + r, |r| <= 0.5*ln2.
*
* Here r will be represented as r = hi-lo for better
* accuracy.
*
* 2. Approximation of exp(r) by a special rational function on
* the interval [0,0.34658]:
* Write
* R(r**2) = r*(exp(r)+1)/(exp(r)-1) = 2 + r*r/6 - r**4/360 + ...
* We use a special Reme algorithm on [0,0.34658] to generate
* a polynomial of degree 5 to approximate R. The maximum error
* of this polynomial approximation is bounded by 2**-59. In
* other words,
* R(z) ~ 2.0 + P1*z + P2*z**2 + P3*z**3 + P4*z**4 + P5*z**5
* (where z=r*r, and the values of P1 to P5 are listed below)
* and
* | 5 | -59
* | 2.0+P1*z+...+P5*z - R(z) | <= 2
* | |
* The computation of exp(r) thus becomes
* 2*r
* exp(r) = 1 + -------
* R - r
* r*R1(r)
* = 1 + r + ----------- (for better accuracy)
* 2 - R1(r)
* where
* 2 4 10
* R1(r) = r - (P1*r + P2*r + ... + P5*r ).
*
* 3. Scale back to obtain exp(x):
* From step 1, we have
* exp(x) = 2^k * exp(r)
*
* Special cases:
* exp(INF) is INF, exp(NaN) is NaN;
* exp(-INF) is 0, and
* for finite argument, only exp(0)=1 is exact.
*
* Accuracy:
* according to an error analysis, the error is always less than
* 1 ulp (unit in the last place).
*
* Misc. info.
* For IEEE double
* if x > 7.09782712893383973096e+02 then exp(x) overflow
* if x < -7.45133219101941108420e+02 then exp(x) underflow
*
* Constants:
* The hexadecimal values are the intended ones for the following
* constants. The decimal values may be used, provided that the
* compiler will convert from decimal to binary accurately enough
* to produce the hexadecimal values shown.
*/
#include "fdlibm.h"
#ifndef _DOUBLE_IS_32BITS
#ifdef __STDC__
static const double
#else
static double
#endif
one = 1.0,
halF[2] = {0.5,-0.5,},
huge = 1.0e+300,
twom1000= 9.33263618503218878990e-302, /* 2**-1000=0x01700000,0*/
o_threshold= 7.09782712893383973096e+02, /* 0x40862E42, 0xFEFA39EF */
u_threshold= -7.45133219101941108420e+02, /* 0xc0874910, 0xD52D3051 */
ln2HI[2] ={ 6.93147180369123816490e-01, /* 0x3fe62e42, 0xfee00000 */
-6.93147180369123816490e-01,},/* 0xbfe62e42, 0xfee00000 */
ln2LO[2] ={ 1.90821492927058770002e-10, /* 0x3dea39ef, 0x35793c76 */
-1.90821492927058770002e-10,},/* 0xbdea39ef, 0x35793c76 */
invln2 = 1.44269504088896338700e+00, /* 0x3ff71547, 0x652b82fe */
P1 = 1.66666666666666019037e-01, /* 0x3FC55555, 0x5555553E */
P2 = -2.77777777770155933842e-03, /* 0xBF66C16C, 0x16BEBD93 */
P3 = 6.61375632143793436117e-05, /* 0x3F11566A, 0xAF25DE2C */
P4 = -1.65339022054652515390e-06, /* 0xBEBBBD41, 0xC5D26BF1 */
P5 = 4.13813679705723846039e-08; /* 0x3E663769, 0x72BEA4D0 */
#ifdef __STDC__
double __ieee754_exp(double x) /* default IEEE double exp */
#else
double __ieee754_exp(x) /* default IEEE double exp */
double x;
#endif
{
double y,hi = 0., lo = 0.,c,t;
int32_t k = 0, xsb;
uint32_t hx;
GET_HIGH_WORD(hx,x);
xsb = (hx>>31)&1; /* sign bit of x */
hx &= 0x7fffffff; /* high word of |x| */
/* filter out non-finite argument */
if(hx >= 0x40862E42) { /* if |x|>=709.78... */
if(hx>=0x7ff00000) {
uint32_t lx;
GET_LOW_WORD(lx,x);
if(((hx&0xfffff)|lx)!=0)
return x+x; /* NaN */
else return (xsb==0)? x:0.0; /* exp(+-inf)={inf,0} */
}
if(x > o_threshold) return huge*huge; /* overflow */
if(x < u_threshold) return twom1000*twom1000; /* underflow */
}
/* argument reduction */
if(hx > 0x3fd62e42) { /* if |x| > 0.5 ln2 */
if(hx < 0x3FF0A2B2) { /* and |x| < 1.5 ln2 */
hi = x-ln2HI[xsb]; lo=ln2LO[xsb]; k = 1-xsb-xsb;
} else {
k = invln2*x+halF[xsb];
t = k;
hi = x - t*ln2HI[0]; /* t*ln2HI is exact here */
lo = t*ln2LO[0];
}
x = hi - lo;
}
else if(hx < 0x3e300000) { /* when |x|<2**-28 */
if(huge+x>one) return one+x;/* trigger inexact */
}
else k = 0;
/* x is now in primary range */
t = x*x;
c = x - t*(P1+t*(P2+t*(P3+t*(P4+t*P5))));
if(k==0) return one-((x*c)/(c-2.0)-x);
else y = one-((lo-(x*c)/(2.0-c))-hi);
if(k >= -1021) {
uint32_t hy;
GET_HIGH_WORD(hy,y);
SET_HIGH_WORD(y,hy+(k<<20)); /* add k to y's exponent */
return y;
} else {
uint32_t hy;
GET_HIGH_WORD(hy,y);
SET_HIGH_WORD(y,hy+((k+1000)<<20)); /* add k to y's exponent */
return y*twom1000;
}
}
#endif /* defined(_DOUBLE_IS_32BITS) */
+140
View File
@@ -0,0 +1,140 @@
/* @(#)e_fmod.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
/*
* __ieee754_fmod(x,y)
* Return x mod y in exact arithmetic
* Method: shift and subtract
*/
#include "fdlibm.h"
#ifndef _DOUBLE_IS_32BITS
#ifdef __STDC__
static const double one = 1.0, Zero[] = {0.0, -0.0,};
#else
static double one = 1.0, Zero[] = {0.0, -0.0,};
#endif
#ifdef __STDC__
double __ieee754_fmod(double x, double y)
#else
double __ieee754_fmod(x,y)
double x,y ;
#endif
{
int32_t n,hx,hy,hz,ix,iy,sx,i;
uint32_t lx,ly,lz;
EXTRACT_WORDS(hx,lx,x);
EXTRACT_WORDS(hy,ly,y);
sx = hx&0x80000000; /* sign of x */
hx ^=sx; /* |x| */
hy &= 0x7fffffff; /* |y| */
/* purge off exception values */
if((hy|ly)==0||(hx>=0x7ff00000)|| /* y=0,or x not finite */
((hy|((ly|-ly)>>31))>0x7ff00000)) /* or y is NaN */
return (x*y)/(x*y);
if(hx<=hy) {
if((hx<hy)||(lx<ly)) return x; /* |x|<|y| return x */
if(lx==ly)
return Zero[(uint32_t)sx>>31]; /* |x|=|y| return x*0*/
}
/* determine ix = ilogb(x) */
if(hx<0x00100000) { /* subnormal x */
if(hx==0) {
for (ix = -1043, i=lx; i>0; i<<=1) ix -=1;
} else {
for (ix = -1022,i=(hx<<11); i>0; i<<=1) ix -=1;
}
} else ix = (hx>>20)-1023;
/* determine iy = ilogb(y) */
if(hy<0x00100000) { /* subnormal y */
if(hy==0) {
for (iy = -1043, i=ly; i>0; i<<=1) iy -=1;
} else {
for (iy = -1022,i=(hy<<11); i>0; i<<=1) iy -=1;
}
} else iy = (hy>>20)-1023;
/* set up {hx,lx}, {hy,ly} and align y to x */
if(ix >= -1022)
hx = 0x00100000|(0x000fffff&hx);
else { /* subnormal x, shift x to normal */
n = -1022-ix;
if(n<=31) {
hx = (hx<<n)|(lx>>(32-n));
lx <<= n;
} else {
hx = lx<<(n-32);
lx = 0;
}
}
if(iy >= -1022)
hy = 0x00100000|(0x000fffff&hy);
else { /* subnormal y, shift y to normal */
n = -1022-iy;
if(n<=31) {
hy = (hy<<n)|(ly>>(32-n));
ly <<= n;
} else {
hy = ly<<(n-32);
ly = 0;
}
}
/* fix point fmod */
n = ix - iy;
while(n--) {
hz=hx-hy;lz=lx-ly; if(lx<ly) hz -= 1;
if(hz<0){hx = hx+hx+(lx>>31); lx = lx+lx;}
else {
if((hz|lz)==0) /* return sign(x)*0 */
return Zero[(uint32_t)sx>>31];
hx = hz+hz+(lz>>31); lx = lz+lz;
}
}
hz=hx-hy;lz=lx-ly; if(lx<ly) hz -= 1;
if(hz>=0) {hx=hz;lx=lz;}
/* convert back to floating value and restore the sign */
if((hx|lx)==0) /* return sign(x)*0 */
return Zero[(uint32_t)sx>>31];
while(hx<0x00100000) { /* normalize x */
hx = hx+hx+(lx>>31); lx = lx+lx;
iy -= 1;
}
if(iy>= -1022) { /* normalize output */
hx = ((hx-0x00100000)|((iy+1023)<<20));
INSERT_WORDS(x,hx|sx,lx);
} else { /* subnormal output */
n = -1022 - iy;
if(n<=20) {
lx = (lx>>n)|((uint32_t)hx<<(32-n));
hx >>= n;
} else if (n<=31) {
lx = (hx<<(32-n))|(lx>>n); hx = sx;
} else {
lx = hx>>(n-32); hx = sx;
}
INSERT_WORDS(x,hx|sx,lx);
x *= one; /* create necessary signal */
}
return x; /* exact output */
}
#endif /* defined(_DOUBLE_IS_32BITS) */
+152
View File
@@ -0,0 +1,152 @@
/* @(#)e_log.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
/* __ieee754_log(x)
* Return the logrithm of x
*
* Method :
* 1. Argument Reduction: find k and f such that
* x = 2^k * (1+f),
* where sqrt(2)/2 < 1+f < sqrt(2) .
*
* 2. Approximation of log(1+f).
* Let s = f/(2+f) ; based on log(1+f) = log(1+s) - log(1-s)
* = 2s + 2/3 s**3 + 2/5 s**5 + .....,
* = 2s + s*R
* We use a special Reme algorithm on [0,0.1716] to generate
* a polynomial of degree 14 to approximate R The maximum error
* of this polynomial approximation is bounded by 2**-58.45. In
* other words,
* 2 4 6 8 10 12 14
* R(z) ~ Lg1*s +Lg2*s +Lg3*s +Lg4*s +Lg5*s +Lg6*s +Lg7*s
* (the values of Lg1 to Lg7 are listed in the program)
* and
* | 2 14 | -58.45
* | Lg1*s +...+Lg7*s - R(z) | <= 2
* | |
* Note that 2s = f - s*f = f - hfsq + s*hfsq, where hfsq = f*f/2.
* In order to guarantee error in log below 1ulp, we compute log
* by
* log(1+f) = f - s*(f - R) (if f is not too large)
* log(1+f) = f - (hfsq - s*(hfsq+R)). (better accuracy)
*
* 3. Finally, log(x) = k*ln2 + log(1+f).
* = k*ln2_hi+(f-(hfsq-(s*(hfsq+R)+k*ln2_lo)))
* Here ln2 is split into two floating point number:
* ln2_hi + ln2_lo,
* where n*ln2_hi is always exact for |n| < 2000.
*
* Special cases:
* log(x) is NaN with signal if x < 0 (including -INF) ;
* log(+INF) is +INF; log(0) is -INF with signal;
* log(NaN) is that NaN with no signal.
*
* Accuracy:
* according to an error analysis, the error is always less than
* 1 ulp (unit in the last place).
*
* Constants:
* The hexadecimal values are the intended ones for the following
* constants. The decimal values may be used, provided that the
* compiler will convert from decimal to binary accurately enough
* to produce the hexadecimal values shown.
*/
#include "fdlibm.h"
#ifndef _DOUBLE_IS_32BITS
#ifdef __STDC__
static const double
#else
static double
#endif
ln2_hi = 6.93147180369123816490e-01, /* 3fe62e42 fee00000 */
ln2_lo = 1.90821492927058770002e-10, /* 3dea39ef 35793c76 */
two54 = 1.80143985094819840000e+16, /* 43500000 00000000 */
Lg1 = 6.666666666666735130e-01, /* 3FE55555 55555593 */
Lg2 = 3.999999999940941908e-01, /* 3FD99999 9997FA04 */
Lg3 = 2.857142874366239149e-01, /* 3FD24924 94229359 */
Lg4 = 2.222219843214978396e-01, /* 3FCC71C5 1D8E78AF */
Lg5 = 1.818357216161805012e-01, /* 3FC74664 96CB03DE */
Lg6 = 1.531383769920937332e-01, /* 3FC39A09 D078C69F */
Lg7 = 1.479819860511658591e-01; /* 3FC2F112 DF3E5244 */
#ifdef __STDC__
static const double zero = 0.0;
#else
static double zero = 0.0;
#endif
#ifdef __STDC__
double __ieee754_log(double x)
#else
double __ieee754_log(x)
double x;
#endif
{
double hfsq,f,s,z,R,w,t1,t2,dk;
int32_t k,hx,i,j;
uint32_t lx;
EXTRACT_WORDS(hx,lx,x);
k=0;
if (hx < 0x00100000) { /* x < 2**-1022 */
if (((hx&0x7fffffff)|lx)==0)
return -two54/zero; /* log(+-0)=-inf */
if (hx<0) return (x-x)/zero; /* log(-#) = NaN */
k -= 54; x *= two54; /* subnormal number, scale up x */
GET_HIGH_WORD(hx,x);
}
if (hx >= 0x7ff00000) return x+x;
k += (hx>>20)-1023;
hx &= 0x000fffff;
i = (hx+0x95f64)&0x100000;
SET_HIGH_WORD(x,hx|(i^0x3ff00000)); /* normalize x or x/2 */
k += (i>>20);
f = x-1.0;
if((0x000fffff&(2+hx))<3) { /* |f| < 2**-20 */
if(f==zero) {
if(k==0)
return zero;
else {
dk=(double)k;
return dk*ln2_hi+dk*ln2_lo;
}
}
R = f*f*(0.5-0.33333333333333333*f);
if(k==0) return f-R; else {dk=(double)k;
return dk*ln2_hi-((R-dk*ln2_lo)-f);}
}
s = f/(2.0+f);
dk = (double)k;
z = s*s;
i = hx-0x6147a;
w = z*z;
j = 0x6b851-hx;
t1= w*(Lg2+w*(Lg4+w*Lg6));
t2= z*(Lg1+w*(Lg3+w*(Lg5+w*Lg7)));
i |= j;
R = t2+t1;
if(i>0) {
hfsq=0.5*f*f;
if(k==0) return f-(hfsq-s*(hfsq+R)); else
return dk*ln2_hi-((hfsq-(s*(hfsq+R)+dk*ln2_lo))-f);
} else {
if(k==0) return f-s*(f-R); else
return dk*ln2_hi-((s*(f-R)-dk*ln2_lo)-f);
}
}
#endif /* defined(_DOUBLE_IS_32BITS) */
+312
View File
@@ -0,0 +1,312 @@
/* @(#)e_pow.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
/* __ieee754_pow(x,y) return x**y
*
* n
* Method: Let x = 2 * (1+f)
* 1. Compute and return log2(x) in two pieces:
* log2(x) = w1 + w2,
* where w1 has 53-24 = 29 bit trailing zeros.
* 2. Perform y*log2(x) = n+y' by simulating muti-precision
* arithmetic, where |y'|<=0.5.
* 3. Return x**y = 2**n*exp(y'*log2)
*
* Special cases:
* 1. (anything) ** 0 is 1
* 2. (anything) ** 1 is itself
* 3. (anything) ** NAN is NAN
* 4. NAN ** (anything except 0) is NAN
* 5. +-(|x| > 1) ** +INF is +INF
* 6. +-(|x| > 1) ** -INF is +0
* 7. +-(|x| < 1) ** +INF is +0
* 8. +-(|x| < 1) ** -INF is +INF
* 9. +-1 ** +-INF is NAN
* 10. +0 ** (+anything except 0, NAN) is +0
* 11. -0 ** (+anything except 0, NAN, odd integer) is +0
* 12. +0 ** (-anything except 0, NAN) is +INF
* 13. -0 ** (-anything except 0, NAN, odd integer) is +INF
* 14. -0 ** (odd integer) = -( +0 ** (odd integer) )
* 15. +INF ** (+anything except 0,NAN) is +INF
* 16. +INF ** (-anything except 0,NAN) is +0
* 17. -INF ** (anything) = -0 ** (-anything)
* 18. (-anything) ** (integer) is (-1)**(integer)*(+anything**integer)
* 19. (-anything except 0 and inf) ** (non-integer) is NAN
*
* Accuracy:
* pow(x,y) returns x**y nearly rounded. In particular
* pow(integer,integer)
* always returns the correct integer provided it is
* representable.
*
* Constants :
* The hexadecimal values are the intended ones for the following
* constants. The decimal values may be used, provided that the
* compiler will convert from decimal to binary accurately enough
* to produce the hexadecimal values shown.
*/
#include "fdlibm.h"
#ifndef _DOUBLE_IS_32BITS
#ifdef __STDC__
static const double
#else
static double
#endif
bp[] = {1.0, 1.5,},
dp_h[] = { 0.0, 5.84962487220764160156e-01,}, /* 0x3FE2B803, 0x40000000 */
dp_l[] = { 0.0, 1.35003920212974897128e-08,}, /* 0x3E4CFDEB, 0x43CFD006 */
zero = 0.0,
one = 1.0,
two = 2.0,
two53 = 9007199254740992.0, /* 0x43400000, 0x00000000 */
huge = 1.0e300,
tiny = 1.0e-300,
/* poly coefs for (3/2)*(log(x)-2s-2/3*s**3 */
L1 = 5.99999999999994648725e-01, /* 0x3FE33333, 0x33333303 */
L2 = 4.28571428578550184252e-01, /* 0x3FDB6DB6, 0xDB6FABFF */
L3 = 3.33333329818377432918e-01, /* 0x3FD55555, 0x518F264D */
L4 = 2.72728123808534006489e-01, /* 0x3FD17460, 0xA91D4101 */
L5 = 2.30660745775561754067e-01, /* 0x3FCD864A, 0x93C9DB65 */
L6 = 2.06975017800338417784e-01, /* 0x3FCA7E28, 0x4A454EEF */
P1 = 1.66666666666666019037e-01, /* 0x3FC55555, 0x5555553E */
P2 = -2.77777777770155933842e-03, /* 0xBF66C16C, 0x16BEBD93 */
P3 = 6.61375632143793436117e-05, /* 0x3F11566A, 0xAF25DE2C */
P4 = -1.65339022054652515390e-06, /* 0xBEBBBD41, 0xC5D26BF1 */
P5 = 4.13813679705723846039e-08, /* 0x3E663769, 0x72BEA4D0 */
lg2 = 6.93147180559945286227e-01, /* 0x3FE62E42, 0xFEFA39EF */
lg2_h = 6.93147182464599609375e-01, /* 0x3FE62E43, 0x00000000 */
lg2_l = -1.90465429995776804525e-09, /* 0xBE205C61, 0x0CA86C39 */
ovt = 8.0085662595372944372e-0017, /* -(1024-log2(ovfl+.5ulp)) */
cp = 9.61796693925975554329e-01, /* 0x3FEEC709, 0xDC3A03FD =2/(3ln2) */
cp_h = 9.61796700954437255859e-01, /* 0x3FEEC709, 0xE0000000 =(float)cp */
cp_l = -7.02846165095275826516e-09, /* 0xBE3E2FE0, 0x145B01F5 =tail of cp_h*/
ivln2 = 1.44269504088896338700e+00, /* 0x3FF71547, 0x652B82FE =1/ln2 */
ivln2_h = 1.44269502162933349609e+00, /* 0x3FF71547, 0x60000000 =24b 1/ln2*/
ivln2_l = 1.92596299112661746887e-08; /* 0x3E54AE0B, 0xF85DDF44 =1/ln2 tail*/
#ifdef __STDC__
double __ieee754_pow(double x, double y)
#else
double __ieee754_pow(x,y)
double x, y;
#endif
{
double z,ax,z_h,z_l,p_h,p_l;
double y1,t1,t2,r,s,t,u,v,w;
int32_t i,j,k,yisint,n;
int32_t hx,hy,ix,iy;
uint32_t lx,ly;
EXTRACT_WORDS(hx,lx,x);
EXTRACT_WORDS(hy,ly,y);
ix = hx&0x7fffffff; iy = hy&0x7fffffff;
/* y==zero: x**0 = 1 */
if((iy|ly)==0) return one;
/* +-NaN return x+y */
if(ix > 0x7ff00000 || ((ix==0x7ff00000)&&(lx!=0)) ||
iy > 0x7ff00000 || ((iy==0x7ff00000)&&(ly!=0)))
return x+y;
/* determine if y is an odd int when x < 0
* yisint = 0 ... y is not an integer
* yisint = 1 ... y is an odd int
* yisint = 2 ... y is an even int
*/
yisint = 0;
if(hx<0) {
if(iy>=0x43400000) yisint = 2; /* even integer y */
else if(iy>=0x3ff00000) {
k = (iy>>20)-0x3ff; /* exponent */
if(k>20) {
j = ly>>(52-k);
if((uint32_t)(j<<(52-k))==ly) yisint = 2-(j&1);
} else if(ly==0) {
j = iy>>(20-k);
if((j<<(20-k))==iy) yisint = 2-(j&1);
}
}
}
/* special value of y */
if(ly==0) {
if (iy==0x7ff00000) { /* y is +-inf */
if(((ix-0x3ff00000)|lx)==0)
return y - y; /* inf**+-1 is NaN */
else if (ix >= 0x3ff00000)/* (|x|>1)**+-inf = inf,0 */
return (hy>=0)? y: zero;
else /* (|x|<1)**-,+inf = inf,0 */
return (hy<0)?-y: zero;
}
if(iy==0x3ff00000) { /* y is +-1 */
if(hy<0) return one/x; else return x;
}
if(hy==0x40000000) return x*x; /* y is 2 */
if(hy==0x3fe00000) { /* y is 0.5 */
if(hx>=0) /* x >= +0 */
return __ieee754_sqrt(x);
}
}
ax = fabs(x);
/* special value of x */
if(lx==0) {
if(ix==0x7ff00000||ix==0||ix==0x3ff00000){
z = ax; /*x is +-0,+-inf,+-1*/
if(hy<0) z = one/z; /* z = (1/|x|) */
if(hx<0) {
if(((ix-0x3ff00000)|yisint)==0) {
z = (z-z)/(z-z); /* (-1)**non-int is NaN */
} else if(yisint==1)
z = -z; /* (x<0)**odd = -(|x|**odd) */
}
return z;
}
}
/* (x<0)**(non-int) is NaN */
/* GCJ LOCAL: This used to be
if((((hx>>31)+1)|yisint)==0) return (x-x)/(x-x);
but ANSI C says a right shift of a signed negative quantity is
implementation defined. */
if(((((uint32_t)hx>>31)-1)|yisint)==0) return (x-x)/(x-x);
/* |y| is huge */
if(iy>0x41e00000) { /* if |y| > 2**31 */
if(iy>0x43f00000){ /* if |y| > 2**64, must o/uflow */
if(ix<=0x3fefffff) return (hy<0)? huge*huge:tiny*tiny;
if(ix>=0x3ff00000) return (hy>0)? huge*huge:tiny*tiny;
}
/* over/underflow if x is not close to one */
if(ix<0x3fefffff) return (hy<0)? huge*huge:tiny*tiny;
if(ix>0x3ff00000) return (hy>0)? huge*huge:tiny*tiny;
/* now |1-x| is tiny <= 2**-20, suffice to compute
log(x) by x-x^2/2+x^3/3-x^4/4 */
t = x-1; /* t has 20 trailing zeros */
w = (t*t)*(0.5-t*(0.3333333333333333333333-t*0.25));
u = ivln2_h*t; /* ivln2_h has 21 sig. bits */
v = t*ivln2_l-w*ivln2;
t1 = u+v;
SET_LOW_WORD(t1,0);
t2 = v-(t1-u);
} else {
double s2,s_h,s_l,t_h,t_l;
n = 0;
/* take care subnormal number */
if(ix<0x00100000)
{ax *= two53; n -= 53; GET_HIGH_WORD(ix,ax); }
n += ((ix)>>20)-0x3ff;
j = ix&0x000fffff;
/* determine interval */
ix = j|0x3ff00000; /* normalize ix */
if(j<=0x3988E) k=0; /* |x|<sqrt(3/2) */
else if(j<0xBB67A) k=1; /* |x|<sqrt(3) */
else {k=0;n+=1;ix -= 0x00100000;}
SET_HIGH_WORD(ax,ix);
/* compute s = s_h+s_l = (x-1)/(x+1) or (x-1.5)/(x+1.5) */
u = ax-bp[k]; /* bp[0]=1.0, bp[1]=1.5 */
v = one/(ax+bp[k]);
s = u*v;
s_h = s;
SET_LOW_WORD(s_h,0);
/* t_h=ax+bp[k] High */
t_h = zero;
SET_HIGH_WORD(t_h,((ix>>1)|0x20000000)+0x00080000+(k<<18));
t_l = ax - (t_h-bp[k]);
s_l = v*((u-s_h*t_h)-s_h*t_l);
/* compute log(ax) */
s2 = s*s;
r = s2*s2*(L1+s2*(L2+s2*(L3+s2*(L4+s2*(L5+s2*L6)))));
r += s_l*(s_h+s);
s2 = s_h*s_h;
t_h = 3.0+s2+r;
SET_LOW_WORD(t_h,0);
t_l = r-((t_h-3.0)-s2);
/* u+v = s*(1+...) */
u = s_h*t_h;
v = s_l*t_h+t_l*s;
/* 2/(3log2)*(s+...) */
p_h = u+v;
SET_LOW_WORD(p_h,0);
p_l = v-(p_h-u);
z_h = cp_h*p_h; /* cp_h+cp_l = 2/(3*log2) */
z_l = cp_l*p_h+p_l*cp+dp_l[k];
/* log2(ax) = (s+..)*2/(3*log2) = n + dp_h + z_h + z_l */
t = (double)n;
t1 = (((z_h+z_l)+dp_h[k])+t);
SET_LOW_WORD(t1,0);
t2 = z_l-(((t1-t)-dp_h[k])-z_h);
}
s = one; /* s (sign of result -ve**odd) = -1 else = 1 */
if(((((uint32_t)hx>>31)-1)|(yisint-1))==0)
s = -one;/* (-ve)**(odd int) */
/* split up y into y1+y2 and compute (y1+y2)*(t1+t2) */
y1 = y;
SET_LOW_WORD(y1,0);
p_l = (y-y1)*t1+y*t2;
p_h = y1*t1;
z = p_l+p_h;
EXTRACT_WORDS(j,i,z);
if (j>=0x40900000) { /* z >= 1024 */
if(((j-0x40900000)|i)!=0) /* if z > 1024 */
return s*huge*huge; /* overflow */
else {
if(p_l+ovt>z-p_h) return s*huge*huge; /* overflow */
}
} else if((j&0x7fffffff)>=0x4090cc00 ) { /* z <= -1075 */
if(((j-0xc090cc00)|i)!=0) /* z < -1075 */
return s*tiny*tiny; /* underflow */
else {
if(p_l<=z-p_h) return s*tiny*tiny; /* underflow */
}
}
/*
* compute 2**(p_h+p_l)
*/
i = j&0x7fffffff;
k = (i>>20)-0x3ff;
n = 0;
if(i>0x3fe00000) { /* if |z| > 0.5, set n = [z+0.5] */
n = j+(0x00100000>>(k+1));
k = ((n&0x7fffffff)>>20)-0x3ff; /* new k for n */
t = zero;
SET_HIGH_WORD(t,n&~(0x000fffff>>k));
n = ((n&0x000fffff)|0x00100000)>>(20-k);
if(j<0) n = -n;
p_h -= t;
}
t = p_l+p_h;
SET_LOW_WORD(t,0);
u = t*lg2_h;
v = (p_l-(t-p_h))*lg2+t*lg2_l;
z = u+v;
w = v-(z-u);
t = z*z;
t1 = z - t*(P1+t*(P2+t*(P3+t*(P4+t*P5))));
r = (z*t1)/(t1-two)-(w+z*w);
z = one-(r-z);
GET_HIGH_WORD(j,z);
j += (n<<20);
if((j>>20)<=0) z = scalbn(z,(int)n); /* subnormal output */
else SET_HIGH_WORD(z,j);
return s*z;
}
#endif /* defined(_DOUBLE_IS_32BITS) */
@@ -0,0 +1,185 @@
/* @(#)e_rem_pio2.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*
*/
/* __ieee754_rem_pio2(x,y)
*
* return the remainder of x rem pi/2 in y[0]+y[1]
* use __kernel_rem_pio2()
*/
#include "fdlibm.h"
#ifndef _DOUBLE_IS_32BITS
/*
* Table of constants for 2/pi, 396 Hex digits (476 decimal) of 2/pi
*/
#ifdef __STDC__
static const int32_t two_over_pi[] = {
#else
static int32_t two_over_pi[] = {
#endif
0xA2F983, 0x6E4E44, 0x1529FC, 0x2757D1, 0xF534DD, 0xC0DB62,
0x95993C, 0x439041, 0xFE5163, 0xABDEBB, 0xC561B7, 0x246E3A,
0x424DD2, 0xE00649, 0x2EEA09, 0xD1921C, 0xFE1DEB, 0x1CB129,
0xA73EE8, 0x8235F5, 0x2EBB44, 0x84E99C, 0x7026B4, 0x5F7E41,
0x3991D6, 0x398353, 0x39F49C, 0x845F8B, 0xBDF928, 0x3B1FF8,
0x97FFDE, 0x05980F, 0xEF2F11, 0x8B5A0A, 0x6D1F6D, 0x367ECF,
0x27CB09, 0xB74F46, 0x3F669E, 0x5FEA2D, 0x7527BA, 0xC7EBE5,
0xF17B3D, 0x0739F7, 0x8A5292, 0xEA6BFB, 0x5FB11F, 0x8D5D08,
0x560330, 0x46FC7B, 0x6BABF0, 0xCFBC20, 0x9AF436, 0x1DA9E3,
0x91615E, 0xE61B08, 0x659985, 0x5F14A0, 0x68408D, 0xFFD880,
0x4D7327, 0x310606, 0x1556CA, 0x73A8C9, 0x60E27B, 0xC08C6B,
};
#ifdef __STDC__
static const int32_t npio2_hw[] = {
#else
static int32_t npio2_hw[] = {
#endif
0x3FF921FB, 0x400921FB, 0x4012D97C, 0x401921FB, 0x401F6A7A, 0x4022D97C,
0x4025FDBB, 0x402921FB, 0x402C463A, 0x402F6A7A, 0x4031475C, 0x4032D97C,
0x40346B9C, 0x4035FDBB, 0x40378FDB, 0x403921FB, 0x403AB41B, 0x403C463A,
0x403DD85A, 0x403F6A7A, 0x40407E4C, 0x4041475C, 0x4042106C, 0x4042D97C,
0x4043A28C, 0x40446B9C, 0x404534AC, 0x4045FDBB, 0x4046C6CB, 0x40478FDB,
0x404858EB, 0x404921FB,
};
/*
* invpio2: 53 bits of 2/pi
* pio2_1: first 33 bit of pi/2
* pio2_1t: pi/2 - pio2_1
* pio2_2: second 33 bit of pi/2
* pio2_2t: pi/2 - (pio2_1+pio2_2)
* pio2_3: third 33 bit of pi/2
* pio2_3t: pi/2 - (pio2_1+pio2_2+pio2_3)
*/
#ifdef __STDC__
static const double
#else
static double
#endif
zero = 0.00000000000000000000e+00, /* 0x00000000, 0x00000000 */
half = 5.00000000000000000000e-01, /* 0x3FE00000, 0x00000000 */
two24 = 1.67772160000000000000e+07, /* 0x41700000, 0x00000000 */
invpio2 = 6.36619772367581382433e-01, /* 0x3FE45F30, 0x6DC9C883 */
pio2_1 = 1.57079632673412561417e+00, /* 0x3FF921FB, 0x54400000 */
pio2_1t = 6.07710050650619224932e-11, /* 0x3DD0B461, 0x1A626331 */
pio2_2 = 6.07710050630396597660e-11, /* 0x3DD0B461, 0x1A600000 */
pio2_2t = 2.02226624879595063154e-21, /* 0x3BA3198A, 0x2E037073 */
pio2_3 = 2.02226624871116645580e-21, /* 0x3BA3198A, 0x2E000000 */
pio2_3t = 8.47842766036889956997e-32; /* 0x397B839A, 0x252049C1 */
#ifdef __STDC__
int32_t __ieee754_rem_pio2(double x, double *y)
#else
int32_t __ieee754_rem_pio2(x,y)
double x,y[];
#endif
{
double z = 0., w, t, r, fn;
double tx[3];
int32_t i,j,n,ix,hx;
int e0,nx;
uint32_t low;
GET_HIGH_WORD(hx,x); /* high word of x */
ix = hx&0x7fffffff;
if(ix<=0x3fe921fb) /* |x| ~<= pi/4 , no need for reduction */
{y[0] = x; y[1] = 0; return 0;}
if(ix<0x4002d97c) { /* |x| < 3pi/4, special case with n=+-1 */
if(hx>0) {
z = x - pio2_1;
if(ix!=0x3ff921fb) { /* 33+53 bit pi is good enough */
y[0] = z - pio2_1t;
y[1] = (z-y[0])-pio2_1t;
} else { /* near pi/2, use 33+33+53 bit pi */
z -= pio2_2;
y[0] = z - pio2_2t;
y[1] = (z-y[0])-pio2_2t;
}
return 1;
} else { /* negative x */
z = x + pio2_1;
if(ix!=0x3ff921fb) { /* 33+53 bit pi is good enough */
y[0] = z + pio2_1t;
y[1] = (z-y[0])+pio2_1t;
} else { /* near pi/2, use 33+33+53 bit pi */
z += pio2_2;
y[0] = z + pio2_2t;
y[1] = (z-y[0])+pio2_2t;
}
return -1;
}
}
if(ix<=0x413921fb) { /* |x| ~<= 2^19*(pi/2), medium size */
t = fabs(x);
n = (int32_t) (t*invpio2+half);
fn = (double)n;
r = t-fn*pio2_1;
w = fn*pio2_1t; /* 1st round good to 85 bit */
if(n<32&&ix!=npio2_hw[n-1]) {
y[0] = r-w; /* quick check no cancellation */
} else {
uint32_t high;
j = ix>>20;
y[0] = r-w;
GET_HIGH_WORD(high,y[0]);
i = j-((high>>20)&0x7ff);
if(i>16) { /* 2nd iteration needed, good to 118 */
t = r;
w = fn*pio2_2;
r = t-w;
w = fn*pio2_2t-((t-r)-w);
y[0] = r-w;
GET_HIGH_WORD(high,y[0]);
i = j-((high>>20)&0x7ff);
if(i>49) { /* 3rd iteration need, 151 bits acc */
t = r; /* will cover all possible cases */
w = fn*pio2_3;
r = t-w;
w = fn*pio2_3t-((t-r)-w);
y[0] = r-w;
}
}
}
y[1] = (r-y[0])-w;
if(hx<0) {y[0] = -y[0]; y[1] = -y[1]; return -n;}
else return n;
}
/*
* all other (large) arguments
*/
if(ix>=0x7ff00000) { /* x is inf or NaN */
y[0]=y[1]=x-x; return 0;
}
/* set z = scalbn(|x|,ilogb(x)-23) */
GET_LOW_WORD(low,x);
SET_LOW_WORD(z,low);
e0 = (int)((ix>>20)-1046); /* e0 = ilogb(z)-23; */
SET_HIGH_WORD(z, ix - ((int32_t)e0<<20));
for(i=0;i<2;i++) {
tx[i] = (double)((int32_t)(z));
z = (z-tx[i])*two24;
}
tx[2] = z;
nx = 3;
while(tx[nx-1]==zero) nx--; /* skip zero term */
n = __kernel_rem_pio2(tx,y,e0,nx,2,two_over_pi);
if(hx<0) {y[0] = -y[0]; y[1] = -y[1]; return -n;}
return n;
}
#endif /* defined(_DOUBLE_IS_32BITS) */
@@ -0,0 +1,80 @@
/* @(#)e_remainder.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
/* __ieee754_remainder(x,p)
* Return :
* returns x REM p = x - [x/p]*p as if in infinite
* precise arithmetic, where [x/p] is the (infinite bit)
* integer nearest x/p (in half way case choose the even one).
* Method :
* Based on fmod() return x-[x/p]chopped*p exactlp.
*/
#include "fdlibm.h"
#ifndef _DOUBLE_IS_32BITS
#ifdef __STDC__
static const double zero = 0.0;
#else
static double zero = 0.0;
#endif
#ifdef __STDC__
double __ieee754_remainder(double x, double p)
#else
double __ieee754_remainder(x,p)
double x,p;
#endif
{
int32_t hx,hp;
uint32_t sx,lx,lp;
double p_half;
EXTRACT_WORDS(hx,lx,x);
EXTRACT_WORDS(hp,lp,p);
sx = hx&0x80000000;
hp &= 0x7fffffff;
hx &= 0x7fffffff;
/* purge off exception values */
if((hp|lp)==0) return (x*p)/(x*p); /* p = 0 */
if((hx>=0x7ff00000)|| /* x not finite */
((hp>=0x7ff00000)&& /* p is NaN */
(((hp-0x7ff00000)|lp)!=0)))
return (x*p)/(x*p);
if (hp<=0x7fdfffff) x = __ieee754_fmod(x,p+p); /* now x < 2p */
if (((hx-hp)|(lx-lp))==0) return zero*x;
x = fabs(x);
p = fabs(p);
if (hp<0x00200000) {
if(x+x>p) {
x-=p;
if(x+x>=p) x -= p;
}
} else {
p_half = 0.5*p;
if(x>p_half) {
x-=p;
if(x>=p_half) x -= p;
}
}
GET_HIGH_WORD(hx,x);
SET_HIGH_WORD(x,hx^sx);
return x;
}
#endif /* defined(_DOUBLE_IS_32BITS) */
+55
View File
@@ -0,0 +1,55 @@
/* @(#)e_scalb.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
/*
* __ieee754_scalb(x, fn) is provide for
* passing various standard test suite. One
* should use scalbn() instead.
*/
#include "fdlibm.h"
#ifndef _DOUBLE_IS_32BITS
#ifdef _SCALB_INT
#ifdef __STDC__
double __ieee754_scalb(double x, int fn)
#else
double __ieee754_scalb(x,fn)
double x; int fn;
#endif
#else
#ifdef __STDC__
double __ieee754_scalb(double x, double fn)
#else
double __ieee754_scalb(x,fn)
double x, fn;
#endif
#endif
{
#ifdef _SCALB_INT
return scalbn(x,fn);
#else
if (isnan(x)||isnan(fn)) return x*fn;
if (!finite(fn)) {
if(fn>0.0) return x*fn;
else return x/(-fn);
}
if (rint(fn)!=fn) return (fn-fn)/(fn-fn);
if ( fn > 65000.0) return scalbn(x, 65000);
if (-fn > 65000.0) return scalbn(x,-65000);
return scalbn(x,(int)fn);
#endif
}
#endif /* defined(_DOUBLE_IS_32BITS) */
+452
View File
@@ -0,0 +1,452 @@
/* @(#)e_sqrt.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
/* __ieee754_sqrt(x)
* Return correctly rounded sqrt.
* ------------------------------------------
* | Use the hardware sqrt if you have one |
* ------------------------------------------
* Method:
* Bit by bit method using integer arithmetic. (Slow, but portable)
* 1. Normalization
* Scale x to y in [1,4) with even powers of 2:
* find an integer k such that 1 <= (y=x*2^(2k)) < 4, then
* sqrt(x) = 2^k * sqrt(y)
* 2. Bit by bit computation
* Let q = sqrt(y) truncated to i bit after binary point (q = 1),
* i 0
* i+1 2
* s = 2*q , and y = 2 * ( y - q ). (1)
* i i i i
*
* To compute q from q , one checks whether
* i+1 i
*
* -(i+1) 2
* (q + 2 ) <= y. (2)
* i
* -(i+1)
* If (2) is false, then q = q ; otherwise q = q + 2 .
* i+1 i i+1 i
*
* With some algebric manipulation, it is not difficult to see
* that (2) is equivalent to
* -(i+1)
* s + 2 <= y (3)
* i i
*
* The advantage of (3) is that s and y can be computed by
* i i
* the following recurrence formula:
* if (3) is false
*
* s = s , y = y ; (4)
* i+1 i i+1 i
*
* otherwise,
* -i -(i+1)
* s = s + 2 , y = y - s - 2 (5)
* i+1 i i+1 i i
*
* One may easily use induction to prove (4) and (5).
* Note. Since the left hand side of (3) contain only i+2 bits,
* it does not necessary to do a full (53-bit) comparison
* in (3).
* 3. Final rounding
* After generating the 53 bits result, we compute one more bit.
* Together with the remainder, we can decide whether the
* result is exact, bigger than 1/2ulp, or less than 1/2ulp
* (it will never equal to 1/2ulp).
* The rounding mode can be detected by checking whether
* huge + tiny is equal to huge, and whether huge - tiny is
* equal to huge for some floating point number "huge" and "tiny".
*
* Special cases:
* sqrt(+-0) = +-0 ... exact
* sqrt(inf) = inf
* sqrt(-ve) = NaN ... with invalid signal
* sqrt(NaN) = NaN ... with invalid signal for signaling NaN
*
* Other methods : see the appended file at the end of the program below.
*---------------
*/
#include "fdlibm.h"
#ifndef _DOUBLE_IS_32BITS
#ifdef __STDC__
static const double one = 1.0, tiny=1.0e-300;
#else
static double one = 1.0, tiny=1.0e-300;
#endif
#ifdef __STDC__
double __ieee754_sqrt(double x)
#else
double __ieee754_sqrt(x)
double x;
#endif
{
double z;
int32_t sign = (int)0x80000000;
uint32_t r,t1,s1,ix1,q1;
int32_t ix0,s0,q,m,t,i;
EXTRACT_WORDS(ix0,ix1,x);
/* take care of Inf and NaN */
if((ix0&0x7ff00000)==0x7ff00000) {
return x*x+x; /* sqrt(NaN)=NaN, sqrt(+inf)=+inf
sqrt(-inf)=sNaN */
}
/* take care of zero */
if(ix0<=0) {
if(((ix0&(~sign))|ix1)==0) return x;/* sqrt(+-0) = +-0 */
else if(ix0<0)
return (x-x)/(x-x); /* sqrt(-ve) = sNaN */
}
/* normalize x */
m = (ix0>>20);
if(m==0) { /* subnormal x */
while(ix0==0) {
m -= 21;
ix0 |= (ix1>>11); ix1 <<= 21;
}
for(i=0;(ix0&0x00100000)==0;i++) ix0<<=1;
m -= i-1;
ix0 |= (ix1>>(32-i));
ix1 <<= i;
}
m -= 1023; /* unbias exponent */
ix0 = (ix0&0x000fffff)|0x00100000;
if(m&1){ /* odd m, double x to make it even */
ix0 += ix0 + ((ix1&sign)>>31);
ix1 += ix1;
}
m >>= 1; /* m = [m/2] */
/* generate sqrt(x) bit by bit */
ix0 += ix0 + ((ix1&sign)>>31);
ix1 += ix1;
q = q1 = s0 = s1 = 0; /* [q,q1] = sqrt(x) */
r = 0x00200000; /* r = moving bit from right to left */
while(r!=0) {
t = s0+r;
if(t<=ix0) {
s0 = t+r;
ix0 -= t;
q += r;
}
ix0 += ix0 + ((ix1&sign)>>31);
ix1 += ix1;
r>>=1;
}
r = sign;
while(r!=0) {
t1 = s1+r;
t = s0;
if((t<ix0)||((t==ix0)&&(t1<=ix1))) {
s1 = t1+r;
if(((t1&sign)==(uint32_t)sign)&&(s1&sign)==0) s0 += 1;
ix0 -= t;
if (ix1 < t1) ix0 -= 1;
ix1 -= t1;
q1 += r;
}
ix0 += ix0 + ((ix1&sign)>>31);
ix1 += ix1;
r>>=1;
}
/* use floating add to find out rounding direction */
if((ix0|ix1)!=0) {
z = one-tiny; /* trigger inexact flag */
if (z>=one) {
z = one+tiny;
if (q1==(uint32_t)0xffffffff) { q1=0; q += 1;}
else if (z>one) {
if (q1==(uint32_t)0xfffffffe) q+=1;
q1+=2;
} else
q1 += (q1&1);
}
}
ix0 = (q>>1)+0x3fe00000;
ix1 = q1>>1;
if ((q&1)==1) ix1 |= sign;
ix0 += (m <<20);
INSERT_WORDS(z,ix0,ix1);
return z;
}
#endif /* defined(_DOUBLE_IS_32BITS) */
/*
Other methods (use floating-point arithmetic)
-------------
(This is a copy of a drafted paper by Prof W. Kahan
and K.C. Ng, written in May, 1986)
Two algorithms are given here to implement sqrt(x)
(IEEE double precision arithmetic) in software.
Both supply sqrt(x) correctly rounded. The first algorithm (in
Section A) uses newton iterations and involves four divisions.
The second one uses reciproot iterations to avoid division, but
requires more multiplications. Both algorithms need the ability
to chop results of arithmetic operations instead of round them,
and the INEXACT flag to indicate when an arithmetic operation
is executed exactly with no roundoff error, all part of the
standard (IEEE 754-1985). The ability to perform shift, add,
subtract and logical AND operations upon 32-bit words is needed
too, though not part of the standard.
A. sqrt(x) by Newton Iteration
(1) Initial approximation
Let x0 and x1 be the leading and the trailing 32-bit words of
a floating point number x (in IEEE double format) respectively
1 11 52 ...widths
------------------------------------------------------
x: |s| e | f |
------------------------------------------------------
msb lsb msb lsb ...order
------------------------ ------------------------
x0: |s| e | f1 | x1: | f2 |
------------------------ ------------------------
By performing shifts and subtracts on x0 and x1 (both regarded
as integers), we obtain an 8-bit approximation of sqrt(x) as
follows.
k := (x0>>1) + 0x1ff80000;
y0 := k - T1[31&(k>>15)]. ... y ~ sqrt(x) to 8 bits
Here k is a 32-bit integer and T1[] is an integer array containing
correction terms. Now magically the floating value of y (y's
leading 32-bit word is y0, the value of its trailing word is 0)
approximates sqrt(x) to almost 8-bit.
Value of T1:
static int T1[32]= {
0, 1024, 3062, 5746, 9193, 13348, 18162, 23592,
29598, 36145, 43202, 50740, 58733, 67158, 75992, 85215,
83599, 71378, 60428, 50647, 41945, 34246, 27478, 21581,
16499, 12183, 8588, 5674, 3403, 1742, 661, 130,};
(2) Iterative refinement
Apply Heron's rule three times to y, we have y approximates
sqrt(x) to within 1 ulp (Unit in the Last Place):
y := (y+x/y)/2 ... almost 17 sig. bits
y := (y+x/y)/2 ... almost 35 sig. bits
y := y-(y-x/y)/2 ... within 1 ulp
Remark 1.
Another way to improve y to within 1 ulp is:
y := (y+x/y) ... almost 17 sig. bits to 2*sqrt(x)
y := y - 0x00100006 ... almost 18 sig. bits to sqrt(x)
2
(x-y )*y
y := y + 2* ---------- ...within 1 ulp
2
3y + x
This formula has one division fewer than the one above; however,
it requires more multiplications and additions. Also x must be
scaled in advance to avoid spurious overflow in evaluating the
expression 3y*y+x. Hence it is not recommended uless division
is slow. If division is very slow, then one should use the
reciproot algorithm given in section B.
(3) Final adjustment
By twiddling y's last bit it is possible to force y to be
correctly rounded according to the prevailing rounding mode
as follows. Let r and i be copies of the rounding mode and
inexact flag before entering the square root program. Also we
use the expression y+-ulp for the next representable floating
numbers (up and down) of y. Note that y+-ulp = either fixed
point y+-1, or multiply y by nextafter(1,+-inf) in chopped
mode.
I := FALSE; ... reset INEXACT flag I
R := RZ; ... set rounding mode to round-toward-zero
z := x/y; ... chopped quotient, possibly inexact
If(not I) then { ... if the quotient is exact
if(z=y) {
I := i; ... restore inexact flag
R := r; ... restore rounded mode
return sqrt(x):=y.
} else {
z := z - ulp; ... special rounding
}
}
i := TRUE; ... sqrt(x) is inexact
If (r=RN) then z=z+ulp ... rounded-to-nearest
If (r=RP) then { ... round-toward-+inf
y = y+ulp; z=z+ulp;
}
y := y+z; ... chopped sum
y0:=y0-0x00100000; ... y := y/2 is correctly rounded.
I := i; ... restore inexact flag
R := r; ... restore rounded mode
return sqrt(x):=y.
(4) Special cases
Square root of +inf, +-0, or NaN is itself;
Square root of a negative number is NaN with invalid signal.
B. sqrt(x) by Reciproot Iteration
(1) Initial approximation
Let x0 and x1 be the leading and the trailing 32-bit words of
a floating point number x (in IEEE double format) respectively
(see section A). By performing shifs and subtracts on x0 and y0,
we obtain a 7.8-bit approximation of 1/sqrt(x) as follows.
k := 0x5fe80000 - (x0>>1);
y0:= k - T2[63&(k>>14)]. ... y ~ 1/sqrt(x) to 7.8 bits
Here k is a 32-bit integer and T2[] is an integer array
containing correction terms. Now magically the floating
value of y (y's leading 32-bit word is y0, the value of
its trailing word y1 is set to zero) approximates 1/sqrt(x)
to almost 7.8-bit.
Value of T2:
static int T2[64]= {
0x1500, 0x2ef8, 0x4d67, 0x6b02, 0x87be, 0xa395, 0xbe7a, 0xd866,
0xf14a, 0x1091b,0x11fcd,0x13552,0x14999,0x15c98,0x16e34,0x17e5f,
0x18d03,0x19a01,0x1a545,0x1ae8a,0x1b5c4,0x1bb01,0x1bfde,0x1c28d,
0x1c2de,0x1c0db,0x1ba73,0x1b11c,0x1a4b5,0x1953d,0x18266,0x16be0,
0x1683e,0x179d8,0x18a4d,0x19992,0x1a789,0x1b445,0x1bf61,0x1c989,
0x1d16d,0x1d77b,0x1dddf,0x1e2ad,0x1e5bf,0x1e6e8,0x1e654,0x1e3cd,
0x1df2a,0x1d635,0x1cb16,0x1be2c,0x1ae4e,0x19bde,0x1868e,0x16e2e,
0x1527f,0x1334a,0x11051,0xe951, 0xbe01, 0x8e0d, 0x5924, 0x1edd,};
(2) Iterative refinement
Apply Reciproot iteration three times to y and multiply the
result by x to get an approximation z that matches sqrt(x)
to about 1 ulp. To be exact, we will have
-1ulp < sqrt(x)-z<1.0625ulp.
... set rounding mode to Round-to-nearest
y := y*(1.5-0.5*x*y*y) ... almost 15 sig. bits to 1/sqrt(x)
y := y*((1.5-2^-30)+0.5*x*y*y)... about 29 sig. bits to 1/sqrt(x)
... special arrangement for better accuracy
z := x*y ... 29 bits to sqrt(x), with z*y<1
z := z + 0.5*z*(1-z*y) ... about 1 ulp to sqrt(x)
Remark 2. The constant 1.5-2^-30 is chosen to bias the error so that
(a) the term z*y in the final iteration is always less than 1;
(b) the error in the final result is biased upward so that
-1 ulp < sqrt(x) - z < 1.0625 ulp
instead of |sqrt(x)-z|<1.03125ulp.
(3) Final adjustment
By twiddling y's last bit it is possible to force y to be
correctly rounded according to the prevailing rounding mode
as follows. Let r and i be copies of the rounding mode and
inexact flag before entering the square root program. Also we
use the expression y+-ulp for the next representable floating
numbers (up and down) of y. Note that y+-ulp = either fixed
point y+-1, or multiply y by nextafter(1,+-inf) in chopped
mode.
R := RZ; ... set rounding mode to round-toward-zero
switch(r) {
case RN: ... round-to-nearest
if(x<= z*(z-ulp)...chopped) z = z - ulp; else
if(x<= z*(z+ulp)...chopped) z = z; else z = z+ulp;
break;
case RZ:case RM: ... round-to-zero or round-to--inf
R:=RP; ... reset rounding mod to round-to-+inf
if(x<z*z ... rounded up) z = z - ulp; else
if(x>=(z+ulp)*(z+ulp) ...rounded up) z = z+ulp;
break;
case RP: ... round-to-+inf
if(x>(z+ulp)*(z+ulp)...chopped) z = z+2*ulp; else
if(x>z*z ...chopped) z = z+ulp;
break;
}
Remark 3. The above comparisons can be done in fixed point. For
example, to compare x and w=z*z chopped, it suffices to compare
x1 and w1 (the trailing parts of x and w), regarding them as
two's complement integers.
...Is z an exact square root?
To determine whether z is an exact square root of x, let z1 be the
trailing part of z, and also let x0 and x1 be the leading and
trailing parts of x.
If ((z1&0x03ffffff)!=0) ... not exact if trailing 26 bits of z!=0
I := 1; ... Raise Inexact flag: z is not exact
else {
j := 1 - [(x0>>20)&1] ... j = logb(x) mod 2
k := z1 >> 26; ... get z's 25-th and 26-th
fraction bits
I := i or (k&j) or ((k&(j+j+1))!=(x1&3));
}
R:= r ... restore rounded mode
return sqrt(x):=z.
If multiplication is cheaper then the foregoing red tape, the
Inexact flag can be evaluated by
I := i;
I := (z*z!=x) or I.
Note that z*z can overwrite I; this value must be sensed if it is
True.
Remark 4. If z*z = x exactly, then bit 25 to bit 0 of z1 must be
zero.
--------------------
z1: | f2 |
--------------------
bit 31 bit 0
Further more, bit 27 and 26 of z1, bit 0 and 1 of x1, and the odd
or even of logb(x) have the following relations:
-------------------------------------------------
bit 27,26 of z1 bit 1,0 of x1 logb(x)
-------------------------------------------------
00 00 odd and even
01 01 even
10 10 odd
10 00 even
11 01 even
-------------------------------------------------
(4) Special cases (see (4) of Section A).
*/
+354
View File
@@ -0,0 +1,354 @@
/* @(#)fdlibm.h 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993, 2000 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
#ifndef __CLASSPATH_FDLIBM_H__
#define __CLASSPATH_FDLIBM_H__
/* AIX needs _XOPEN_SOURCE */
#ifdef _AIX
#define _XOPEN_SOURCE
#endif
#include <config.h>
#include <stdlib.h>
/* GCJ LOCAL: Include files. */
#include "ieeefp.h"
#include "mprec.h"
/* CYGNUS LOCAL: Default to XOPEN_MODE. */
#define _XOPEN_MODE
#ifdef __P
#undef __P
#endif
#ifdef __STDC__
#define __P(p) p
#else
#define __P(p) ()
#endif
#ifndef HUGE
#define HUGE ((float)3.40282346638528860e+38)
#endif
/*
* set X_TLOSS = pi*2**52, which is possibly defined in <values.h>
* (one may replace the following line by "#include <values.h>")
*/
#define X_TLOSS 1.41484755040568800000e+16
/* These typedefs are true for the targets running Java. */
#define _IEEE_LIBM
#ifdef __cplusplus
extern "C" {
#endif
/*
* ANSI/POSIX
*/
extern double acos __P((double));
extern double asin __P((double));
extern double atan __P((double));
extern double atan2 __P((double, double));
extern double cos __P((double));
extern double sin __P((double));
extern double tan __P((double));
extern double cosh __P((double));
extern double sinh __P((double));
extern double tanh __P((double));
extern double exp __P((double));
extern double frexp __P((double, int *));
extern double ldexp __P((double, int));
extern double log __P((double));
extern double log10 __P((double));
extern double modf __P((double, double *));
extern double pow __P((double, double));
extern double sqrt __P((double));
extern double ceil __P((double));
extern double fabs __P((double));
extern double floor __P((double));
extern double fmod __P((double, double));
extern double erf __P((double));
extern double erfc __P((double));
extern double gamma __P((double));
extern double hypot __P((double, double));
extern int isnan __P((double));
extern int finite __P((double));
extern double j0 __P((double));
extern double j1 __P((double));
extern double jn __P((int, double));
extern double lgamma __P((double));
extern double y0 __P((double));
extern double y1 __P((double));
extern double yn __P((int, double));
extern double acosh __P((double));
extern double asinh __P((double));
extern double atanh __P((double));
extern double cbrt __P((double));
extern double logb __P((double));
extern double nextafter __P((double, double));
extern double remainder __P((double, double));
/* Functions that are not documented, and are not in <math.h>. */
extern double logb __P((double));
#ifdef _SCALB_INT
extern double scalb __P((double, int));
#else
extern double scalb __P((double, double));
#endif
extern double significand __P((double));
/* ieee style elementary functions */
extern double __ieee754_sqrt __P((double));
extern double __ieee754_acos __P((double));
extern double __ieee754_acosh __P((double));
extern double __ieee754_log __P((double));
extern double __ieee754_atanh __P((double));
extern double __ieee754_asin __P((double));
extern double __ieee754_atan2 __P((double,double));
extern double __ieee754_exp __P((double));
extern double __ieee754_cosh __P((double));
extern double __ieee754_fmod __P((double,double));
extern double __ieee754_pow __P((double,double));
extern double __ieee754_lgamma_r __P((double,int *));
extern double __ieee754_gamma_r __P((double,int *));
extern double __ieee754_log10 __P((double));
extern double __ieee754_sinh __P((double));
extern double __ieee754_hypot __P((double,double));
extern double __ieee754_j0 __P((double));
extern double __ieee754_j1 __P((double));
extern double __ieee754_y0 __P((double));
extern double __ieee754_y1 __P((double));
extern double __ieee754_jn __P((int,double));
extern double __ieee754_yn __P((int,double));
extern double __ieee754_remainder __P((double,double));
extern int32_t __ieee754_rem_pio2 __P((double,double*));
#ifdef _SCALB_INT
extern double __ieee754_scalb __P((double,int));
#else
extern double __ieee754_scalb __P((double,double));
#endif
/* fdlibm kernel function */
extern double __kernel_standard __P((double,double,int));
extern double __kernel_sin __P((double,double,int));
extern double __kernel_cos __P((double,double));
extern double __kernel_tan __P((double,double,int));
extern int __kernel_rem_pio2 __P((double*,double*,int,int,int,const int32_t*));
/* Undocumented float functions. */
extern float logbf __P((float));
#ifdef _SCALB_INT
extern float scalbf __P((float, int));
#else
extern float scalbf __P((float, float));
#endif
extern float significandf __P((float));
/*
* Functions callable from C, intended to support IEEE arithmetic.
*/
extern double copysign __P((double, double));
extern int ilogb __P((double));
extern double rint __P((double));
extern float rintf __P((float));
extern double scalbn __P((double, int));
/* ieee style elementary float functions */
extern float __ieee754_sqrtf __P((float));
extern float __ieee754_acosf __P((float));
extern float __ieee754_acoshf __P((float));
extern float __ieee754_logf __P((float));
extern float __ieee754_atanhf __P((float));
extern float __ieee754_asinf __P((float));
extern float __ieee754_atan2f __P((float,float));
extern float __ieee754_expf __P((float));
extern float __ieee754_coshf __P((float));
extern float __ieee754_fmodf __P((float,float));
extern float __ieee754_powf __P((float,float));
extern float __ieee754_lgammaf_r __P((float,int *));
extern float __ieee754_gammaf_r __P((float,int *));
extern float __ieee754_log10f __P((float));
extern float __ieee754_sinhf __P((float));
extern float __ieee754_hypotf __P((float,float));
extern float __ieee754_j0f __P((float));
extern float __ieee754_j1f __P((float));
extern float __ieee754_y0f __P((float));
extern float __ieee754_y1f __P((float));
extern float __ieee754_jnf __P((int,float));
extern float __ieee754_ynf __P((int,float));
extern float __ieee754_remainderf __P((float,float));
extern int32_t __ieee754_rem_pio2f __P((float,float*));
#ifdef _SCALB_INT
extern float __ieee754_scalbf __P((float,int));
#else
extern float __ieee754_scalbf __P((float,float));
#endif
/* float versions of fdlibm kernel functions */
extern float __kernel_sinf __P((float,float,int));
extern float __kernel_cosf __P((float,float));
extern float __kernel_tanf __P((float,float,int));
extern int __kernel_rem_pio2f __P((float*,float*,int,int,int,const int32_t*));
/* The original code used statements like
n0 = ((*(int*)&one)>>29)^1; * index of high word *
ix0 = *(n0+(int*)&x); * high word of x *
ix1 = *((1-n0)+(int*)&x); * low word of x *
to dig two 32 bit words out of the 64 bit IEEE floating point
value. That is non-ANSI, and, moreover, the gcc instruction
scheduler gets it wrong. We instead use the following macros.
Unlike the original code, we determine the endianness at compile
time, not at run time; I don't see much benefit to selecting
endianness at run time. */
#ifndef __IEEE_BIG_ENDIAN
#ifndef __IEEE_LITTLE_ENDIAN
#error Must define endianness
#endif
#endif
/* A union which permits us to convert between a double and two 32 bit
ints. */
#ifdef __IEEE_BIG_ENDIAN
typedef union
{
double value;
struct
{
uint32_t msw;
uint32_t lsw;
} parts;
} ieee_double_shape_type;
#endif
#ifdef __IEEE_LITTLE_ENDIAN
typedef union
{
double value;
struct
{
uint32_t lsw;
uint32_t msw;
} parts;
} ieee_double_shape_type;
#endif
/* Get two 32 bit ints from a double. */
#define EXTRACT_WORDS(ix0,ix1,d) \
do { \
ieee_double_shape_type ew_u; \
ew_u.value = (d); \
(ix0) = ew_u.parts.msw; \
(ix1) = ew_u.parts.lsw; \
} while (0)
/* Get the more significant 32 bit int from a double. */
#define GET_HIGH_WORD(i,d) \
do { \
ieee_double_shape_type gh_u; \
gh_u.value = (d); \
(i) = gh_u.parts.msw; \
} while (0)
/* Get the less significant 32 bit int from a double. */
#define GET_LOW_WORD(i,d) \
do { \
ieee_double_shape_type gl_u; \
gl_u.value = (d); \
(i) = gl_u.parts.lsw; \
} while (0)
/* Set a double from two 32 bit ints. */
#define INSERT_WORDS(d,ix0,ix1) \
do { \
ieee_double_shape_type iw_u; \
iw_u.parts.msw = (ix0); \
iw_u.parts.lsw = (ix1); \
(d) = iw_u.value; \
} while (0)
/* Set the more significant 32 bits of a double from an int. */
#define SET_HIGH_WORD(d,v) \
do { \
ieee_double_shape_type sh_u; \
sh_u.value = (d); \
sh_u.parts.msw = (v); \
(d) = sh_u.value; \
} while (0)
/* Set the less significant 32 bits of a double from an int. */
#define SET_LOW_WORD(d,v) \
do { \
ieee_double_shape_type sl_u; \
sl_u.value = (d); \
sl_u.parts.lsw = (v); \
(d) = sl_u.value; \
} while (0)
/* A union which permits us to convert between a float and a 32 bit
int. */
typedef union
{
float value;
uint32_t word;
} ieee_float_shape_type;
/* Get a 32 bit int from a float. */
#define GET_FLOAT_WORD(i,d) \
do { \
ieee_float_shape_type gf_u; \
gf_u.value = (d); \
(i) = gf_u.word; \
} while (0)
/* Set a float from a 32 bit int. */
#define SET_FLOAT_WORD(d,i) \
do { \
ieee_float_shape_type sf_u; \
sf_u.word = (i); \
(d) = sf_u.value; \
} while (0)
#ifdef __cplusplus
}
#endif
#endif /* __CLASSPATH_FDLIBM_H__ */
+167
View File
@@ -0,0 +1,167 @@
#ifndef __CLASSPATH_IEEEFP_H__
#define __CLASSPATH_IEEEFP_H__
#ifndef __IEEE_BIG_ENDIAN
#ifndef __IEEE_LITTLE_ENDIAN
#ifdef __alpha__
#define __IEEE_LITTLE_ENDIAN
#endif
#if defined(__arm__) || defined(__thumb__)
/* ARM traditionally used big-endian words; and within those words the
byte ordering was big or little endian depending upon the target.
Modern floating-point formats are naturally ordered; in this case
__VFP_FP__ will be defined, even if soft-float. */
#ifdef __VFP_FP__
#ifdef __ARMEL__
#define __IEEE_LITTLE_ENDIAN
#else
#define __IEEE_BIG_ENDIAN
#endif
#else
#define __IEEE_BIG_ENDIAN
#ifdef __ARMEL__
#define __IEEE_BYTES_LITTLE_ENDIAN
#endif
#endif
#endif
#ifdef __hppa__
#define __IEEE_BIG_ENDIAN
#endif
#if defined (__sparc) || defined (__sparc__)
#define __IEEE_BIG_ENDIAN
#endif
#ifdef __m32r__
#ifdef __LITTLE_ENDIAN__
#define __IEEE_LITTLE_ENDIAN
#else
#define __IEEE_BIG_ENDIAN
#endif
#endif
#if defined(__m68k__) || defined(__mc68000__)
#define __IEEE_BIG_ENDIAN
#endif
#if defined (__H8300__) || defined (__H8300H__)
#define __IEEE_BIG_ENDIAN
#define __SMALL_BITFIELDS
#define _DOUBLE_IS_32BITS
#endif
#ifdef __H8500__
#define __IEEE_BIG_ENDIAN
#define __SMALL_BITFIELDS
#define _DOUBLE_IS_32BITS
#endif
#ifdef __sh__
#ifdef __LITTLE_ENDIAN__
#define __IEEE_LITTLE_ENDIAN
#else
#define __IEEE_BIG_ENDIAN
#endif
#ifdef __SH3E__
#define _DOUBLE_IS_32BITS
#endif
#endif
#ifdef _AM29K
#define __IEEE_BIG_ENDIAN
#endif
#ifdef __i386__
#define __IEEE_LITTLE_ENDIAN
#endif
#ifdef __x86_64__
#define __IEEE_LITTLE_ENDIAN
#endif
#ifdef __i960__
#define __IEEE_LITTLE_ENDIAN
#endif
#ifdef __MIPSEL__
#define __IEEE_LITTLE_ENDIAN
#endif
#ifdef __MIPSEB__
#define __IEEE_BIG_ENDIAN
#endif
#ifdef __pj__
#ifdef __pjl__
#define __IEEE_LITTLE_ENDIAN
#else
#define __IEEE_BIG_ENDIAN
#endif
#endif
/* necv70 was __IEEE_LITTLE_ENDIAN. */
#ifdef __W65__
#define __IEEE_LITTLE_ENDIAN
#define __SMALL_BITFIELDS
#define _DOUBLE_IS_32BITS
#endif
#if defined(__Z8001__) || defined(__Z8002__)
#define __IEEE_BIG_ENDIAN
#endif
#ifdef __m88k__
#define __IEEE_BIG_ENDIAN
#endif
#ifdef __v800
#define __IEEE_LITTLE_ENDIAN
#endif
#if defined (__PPC__) || defined (__ppc__) || defined (__ppc64__)
#if (defined(_BIG_ENDIAN) && _BIG_ENDIAN) || (defined(_AIX) && _AIX) \
|| defined (__APPLE__)
#define __IEEE_BIG_ENDIAN
#else
#if (defined(_LITTLE_ENDIAN) && _LITTLE_ENDIAN) || (defined(__sun__) && __sun__) || (defined(__WIN32__) && __WIN32__)
#define __IEEE_LITTLE_ENDIAN
#endif
#endif
#endif
#ifdef __fr30__
#define __IEEE_BIG_ENDIAN
#endif
#ifdef __mcore__
#define __IEEE_BIG_ENDIAN
#endif
#ifdef __ia64__
#ifdef __BIG_ENDIAN__
#define __IEEE_BIG_ENDIAN
#else
#define __IEEE_LITTLE_ENDIAN
#endif
#endif
#ifdef __s390__
#define __IEEE_BIG_ENDIAN
#endif
#ifndef __IEEE_BIG_ENDIAN
#ifndef __IEEE_LITTLE_ENDIAN
#error Endianess not declared!!
#endif /* not __IEEE_LITTLE_ENDIAN */
#endif /* not __IEEE_BIG_ENDIAN */
#endif /* not __IEEE_LITTLE_ENDIAN */
#endif /* not __IEEE_BIG_ENDIAN */
#endif /* __CLASSPATH_IEEEFP_H__ */
@@ -0,0 +1,38 @@
// java-assert.h - Header file holding assertion definitions. -*- c++ -*-
/* Copyright (C) 1998, 1999 Free Software Foundation
This file is part of libgcj.
This software is copyrighted work licensed under the terms of the
Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
details. */
#ifndef __JAVA_ASSERT_H__
#define __JAVA_ASSERT_H__
// This is a libgcj implementation header.
void _Jv_Abort (const char *, const char *, int, const char *)
__attribute__ ((__noreturn__));
#ifdef DEBUG
#define _Jv_AssertDoCall(Message) _Jv_Abort (__FUNCTION__, __FILE__, __LINE__, Message)
#define JvAssertMessage(Expr, Message) \
do { if (! (Expr)) _Jv_AssertDoCall (Message); } while (0)
#define JvAssert(Expr) \
do { if (! (Expr)) _Jv_AssertDoCall (# Expr); } while (0)
#define JvFail(Message) _Jv_AssertDoCall (Message)
#else /* DEBUG */
#define _Jv_AssertDoCall(Message)
#define JvAssertMessage(Expr, Message)
#define JvAssert(Expr)
#define JvFail(Message) _Jv_Abort (0, 0, 0, Message)
#endif /* not DEBUG */
#endif /* __JAVA_ASSERT_H__ */
+96
View File
@@ -0,0 +1,96 @@
/* @(#)k_cos.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
/*
* __kernel_cos( x, y )
* kernel cos function on [-pi/4, pi/4], pi/4 ~ 0.785398164
* Input x is assumed to be bounded by ~pi/4 in magnitude.
* Input y is the tail of x.
*
* Algorithm
* 1. Since cos(-x) = cos(x), we need only to consider positive x.
* 2. if x < 2^-27 (hx<0x3e400000 0), return 1 with inexact if x!=0.
* 3. cos(x) is approximated by a polynomial of degree 14 on
* [0,pi/4]
* 4 14
* cos(x) ~ 1 - x*x/2 + C1*x + ... + C6*x
* where the remez error is
*
* | 2 4 6 8 10 12 14 | -58
* |cos(x)-(1-.5*x +C1*x +C2*x +C3*x +C4*x +C5*x +C6*x )| <= 2
* | |
*
* 4 6 8 10 12 14
* 4. let r = C1*x +C2*x +C3*x +C4*x +C5*x +C6*x , then
* cos(x) = 1 - x*x/2 + r
* since cos(x+y) ~ cos(x) - sin(x)*y
* ~ cos(x) - x*y,
* a correction term is necessary in cos(x) and hence
* cos(x+y) = 1 - (x*x/2 - (r - x*y))
* For better accuracy when x > 0.3, let qx = |x|/4 with
* the last 32 bits mask off, and if x > 0.78125, let qx = 0.28125.
* Then
* cos(x+y) = (1-qx) - ((x*x/2-qx) - (r-x*y)).
* Note that 1-qx and (x*x/2-qx) is EXACT here, and the
* magnitude of the latter is at least a quarter of x*x/2,
* thus, reducing the rounding error in the subtraction.
*/
#include "fdlibm.h"
#ifndef _DOUBLE_IS_32BITS
#ifdef __STDC__
static const double
#else
static double
#endif
one = 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */
C1 = 4.16666666666666019037e-02, /* 0x3FA55555, 0x5555554C */
C2 = -1.38888888888741095749e-03, /* 0xBF56C16C, 0x16C15177 */
C3 = 2.48015872894767294178e-05, /* 0x3EFA01A0, 0x19CB1590 */
C4 = -2.75573143513906633035e-07, /* 0xBE927E4F, 0x809C52AD */
C5 = 2.08757232129817482790e-09, /* 0x3E21EE9E, 0xBDB4B1C4 */
C6 = -1.13596475577881948265e-11; /* 0xBDA8FAE9, 0xBE8838D4 */
#ifdef __STDC__
double __kernel_cos(double x, double y)
#else
double __kernel_cos(x, y)
double x,y;
#endif
{
double a,hz,z,r,qx;
int32_t ix;
GET_HIGH_WORD(ix,x);
ix &= 0x7fffffff; /* ix = |x|'s high word*/
if(ix<0x3e400000) { /* if x < 2**27 */
if(((int)x)==0) return one; /* generate inexact */
}
z = x*x;
r = z*(C1+z*(C2+z*(C3+z*(C4+z*(C5+z*C6)))));
if(ix < 0x3FD33333) /* if |x| < 0.3 */
return one - (0.5*z - (z*r - x*y));
else {
if(ix > 0x3fe90000) { /* x > 0.78125 */
qx = 0.28125;
} else {
INSERT_WORDS(qx,ix-0x00200000,0); /* x/4 */
}
hz = 0.5*z-qx;
a = one-qx;
return a - (hz - (z*r-x*y));
}
}
#endif /* defined(_DOUBLE_IS_32BITS) */
@@ -0,0 +1,320 @@
/* @(#)k_rem_pio2.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
/*
* __kernel_rem_pio2(x,y,e0,nx,prec,ipio2)
* double x[],y[]; int e0,nx,prec; int ipio2[];
*
* __kernel_rem_pio2 return the last three digits of N with
* y = x - N*pi/2
* so that |y| < pi/2.
*
* The method is to compute the integer (mod 8) and fraction parts of
* (2/pi)*x without doing the full multiplication. In general we
* skip the part of the product that are known to be a huge integer (
* more accurately, = 0 mod 8 ). Thus the number of operations are
* independent of the exponent of the input.
*
* (2/pi) is represented by an array of 24-bit integers in ipio2[].
*
* Input parameters:
* x[] The input value (must be positive) is broken into nx
* pieces of 24-bit integers in double precision format.
* x[i] will be the i-th 24 bit of x. The scaled exponent
* of x[0] is given in input parameter e0 (i.e., x[0]*2^e0
* match x's up to 24 bits.
*
* Example of breaking a double positive z into x[0]+x[1]+x[2]:
* e0 = ilogb(z)-23
* z = scalbn(z,-e0)
* for i = 0,1,2
* x[i] = floor(z)
* z = (z-x[i])*2**24
*
*
* y[] ouput result in an array of double precision numbers.
* The dimension of y[] is:
* 24-bit precision 1
* 53-bit precision 2
* 64-bit precision 2
* 113-bit precision 3
* The actual value is the sum of them. Thus for 113-bit
* precison, one may have to do something like:
*
* long double t,w,r_head, r_tail;
* t = (long double)y[2] + (long double)y[1];
* w = (long double)y[0];
* r_head = t+w;
* r_tail = w - (r_head - t);
*
* e0 The exponent of x[0]
*
* nx dimension of x[]
*
* prec an integer indicating the precision:
* 0 24 bits (single)
* 1 53 bits (double)
* 2 64 bits (extended)
* 3 113 bits (quad)
*
* ipio2[]
* integer array, contains the (24*i)-th to (24*i+23)-th
* bit of 2/pi after binary point. The corresponding
* floating value is
*
* ipio2[i] * 2^(-24(i+1)).
*
* External function:
* double scalbn(), floor();
*
*
* Here is the description of some local variables:
*
* jk jk+1 is the initial number of terms of ipio2[] needed
* in the computation. The recommended value is 2,3,4,
* 6 for single, double, extended,and quad.
*
* jz local integer variable indicating the number of
* terms of ipio2[] used.
*
* jx nx - 1
*
* jv index for pointing to the suitable ipio2[] for the
* computation. In general, we want
* ( 2^e0*x[0] * ipio2[jv-1]*2^(-24jv) )/8
* is an integer. Thus
* e0-3-24*jv >= 0 or (e0-3)/24 >= jv
* Hence jv = max(0,(e0-3)/24).
*
* jp jp+1 is the number of terms in PIo2[] needed, jp = jk.
*
* q[] double array with integral value, representing the
* 24-bits chunk of the product of x and 2/pi.
*
* q0 the corresponding exponent of q[0]. Note that the
* exponent for q[i] would be q0-24*i.
*
* PIo2[] double precision array, obtained by cutting pi/2
* into 24 bits chunks.
*
* f[] ipio2[] in floating point
*
* iq[] integer array by breaking up q[] in 24-bits chunk.
*
* fq[] final product of x*(2/pi) in fq[0],..,fq[jk]
*
* ih integer. If >0 it indicates q[] is >= 0.5, hence
* it also indicates the *sign* of the result.
*
*/
/*
* Constants:
* The hexadecimal values are the intended ones for the following
* constants. The decimal values may be used, provided that the
* compiler will convert from decimal to binary accurately enough
* to produce the hexadecimal values shown.
*/
#include "fdlibm.h"
#ifndef _DOUBLE_IS_32BITS
#ifdef __STDC__
static const int init_jk[] = {2,3,4,6}; /* initial value for jk */
#else
static int init_jk[] = {2,3,4,6};
#endif
#ifdef __STDC__
static const double PIo2[] = {
#else
static double PIo2[] = {
#endif
1.57079625129699707031e+00, /* 0x3FF921FB, 0x40000000 */
7.54978941586159635335e-08, /* 0x3E74442D, 0x00000000 */
5.39030252995776476554e-15, /* 0x3CF84698, 0x80000000 */
3.28200341580791294123e-22, /* 0x3B78CC51, 0x60000000 */
1.27065575308067607349e-29, /* 0x39F01B83, 0x80000000 */
1.22933308981111328932e-36, /* 0x387A2520, 0x40000000 */
2.73370053816464559624e-44, /* 0x36E38222, 0x80000000 */
2.16741683877804819444e-51, /* 0x3569F31D, 0x00000000 */
};
#ifdef __STDC__
static const double
#else
static double
#endif
zero = 0.0,
one = 1.0,
two24 = 1.67772160000000000000e+07, /* 0x41700000, 0x00000000 */
twon24 = 5.96046447753906250000e-08; /* 0x3E700000, 0x00000000 */
#ifdef __STDC__
int __kernel_rem_pio2(double *x, double *y, int e0, int nx, int prec, const int32_t *ipio2)
#else
int __kernel_rem_pio2(x,y,e0,nx,prec,ipio2)
double x[], y[]; int e0,nx,prec; int32_t ipio2[];
#endif
{
int32_t jz,jx,jv,jp,jk,carry,n,iq[20],i,j,k,m,q0,ih;
double z,fw,f[20],fq[20],q[20];
/* initialize jk*/
jk = init_jk[prec];
jp = jk;
/* determine jx,jv,q0, note that 3>q0 */
jx = nx-1;
jv = (e0-3)/24; if(jv<0) jv=0;
q0 = e0-24*(jv+1);
/* set up f[0] to f[jx+jk] where f[jx+jk] = ipio2[jv+jk] */
j = jv-jx; m = jx+jk;
for(i=0;i<=m;i++,j++) f[i] = (j<0)? zero : (double) ipio2[j];
/* compute q[0],q[1],...q[jk] */
for (i=0;i<=jk;i++) {
for(j=0,fw=0.0;j<=jx;j++) fw += x[j]*f[jx+i-j]; q[i] = fw;
}
jz = jk;
recompute:
/* distill q[] into iq[] reversingly */
for(i=0,j=jz,z=q[jz];j>0;i++,j--) {
fw = (double)((int32_t)(twon24* z));
iq[i] = (int32_t)(z-two24*fw);
z = q[j-1]+fw;
}
/* compute n */
z = scalbn(z,(int)q0); /* actual value of z */
z -= 8.0*floor(z*0.125); /* trim off integer >= 8 */
n = (int32_t) z;
z -= (double)n;
ih = 0;
if(q0>0) { /* need iq[jz-1] to determine n */
i = (iq[jz-1]>>(24-q0)); n += i;
iq[jz-1] -= i<<(24-q0);
ih = iq[jz-1]>>(23-q0);
}
else if(q0==0) ih = iq[jz-1]>>23;
else if(z>=0.5) ih=2;
if(ih>0) { /* q > 0.5 */
n += 1; carry = 0;
for(i=0;i<jz ;i++) { /* compute 1-q */
j = iq[i];
if(carry==0) {
if(j!=0) {
carry = 1; iq[i] = 0x1000000- j;
}
} else iq[i] = 0xffffff - j;
}
if(q0>0) { /* rare case: chance is 1 in 12 */
switch(q0) {
case 1:
iq[jz-1] &= 0x7fffff; break;
case 2:
iq[jz-1] &= 0x3fffff; break;
}
}
if(ih==2) {
z = one - z;
if(carry!=0) z -= scalbn(one,(int)q0);
}
}
/* check if recomputation is needed */
if(z==zero) {
j = 0;
for (i=jz-1;i>=jk;i--) j |= iq[i];
if(j==0) { /* need recomputation */
for(k=1;iq[jk-k]==0;k++); /* k = no. of terms needed */
for(i=jz+1;i<=jz+k;i++) { /* add q[jz+1] to q[jz+k] */
f[jx+i] = (double) ipio2[jv+i];
for(j=0,fw=0.0;j<=jx;j++) fw += x[j]*f[jx+i-j];
q[i] = fw;
}
jz += k;
goto recompute;
}
}
/* chop off zero terms */
if(z==0.0) {
jz -= 1; q0 -= 24;
while(iq[jz]==0) { jz--; q0-=24;}
} else { /* break z into 24-bit if necessary */
z = scalbn(z,-(int)q0);
if(z>=two24) {
fw = (double)((int32_t)(twon24*z));
iq[jz] = (int32_t)(z-two24*fw);
jz += 1; q0 += 24;
iq[jz] = (int32_t) fw;
} else iq[jz] = (int32_t) z ;
}
/* convert integer "bit" chunk to floating-point value */
fw = scalbn(one,(int)q0);
for(i=jz;i>=0;i--) {
q[i] = fw*(double)iq[i]; fw*=twon24;
}
/* compute PIo2[0,...,jp]*q[jz,...,0] */
for(i=jz;i>=0;i--) {
for(fw=0.0,k=0;k<=jp&&k<=jz-i;k++) fw += PIo2[k]*q[i+k];
fq[jz-i] = fw;
}
/* compress fq[] into y[] */
switch(prec) {
case 0:
fw = 0.0;
for (i=jz;i>=0;i--) fw += fq[i];
y[0] = (ih==0)? fw: -fw;
break;
case 1:
case 2:
fw = 0.0;
for (i=jz;i>=0;i--) fw += fq[i];
y[0] = (ih==0)? fw: -fw;
fw = fq[0]-fw;
for (i=1;i<=jz;i++) fw += fq[i];
y[1] = (ih==0)? fw: -fw;
break;
case 3: /* painful */
for (i=jz;i>0;i--) {
fw = fq[i-1]+fq[i];
fq[i] += fq[i-1]-fw;
fq[i-1] = fw;
}
for (i=jz;i>1;i--) {
fw = fq[i-1]+fq[i];
fq[i] += fq[i-1]-fw;
fq[i-1] = fw;
}
for (fw=0.0,i=jz;i>=2;i--) fw += fq[i];
if(ih==0) {
y[0] = fq[0]; y[1] = fq[1]; y[2] = fw;
} else {
y[0] = -fq[0]; y[1] = -fq[1]; y[2] = -fw;
}
}
return n&7;
}
#endif /* defined(_DOUBLE_IS_32BITS) */
+79
View File
@@ -0,0 +1,79 @@
/* @(#)k_sin.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
/* __kernel_sin( x, y, iy)
* kernel sin function on [-pi/4, pi/4], pi/4 ~ 0.7854
* Input x is assumed to be bounded by ~pi/4 in magnitude.
* Input y is the tail of x.
* Input iy indicates whether y is 0. (if iy=0, y assume to be 0).
*
* Algorithm
* 1. Since sin(-x) = -sin(x), we need only to consider positive x.
* 2. if x < 2^-27 (hx<0x3e400000 0), return x with inexact if x!=0.
* 3. sin(x) is approximated by a polynomial of degree 13 on
* [0,pi/4]
* 3 13
* sin(x) ~ x + S1*x + ... + S6*x
* where
*
* |sin(x) 2 4 6 8 10 12 | -58
* |----- - (1+S1*x +S2*x +S3*x +S4*x +S5*x +S6*x )| <= 2
* | x |
*
* 4. sin(x+y) = sin(x) + sin'(x')*y
* ~ sin(x) + (1-x*x/2)*y
* For better accuracy, let
* 3 2 2 2 2
* r = x *(S2+x *(S3+x *(S4+x *(S5+x *S6))))
* then 3 2
* sin(x) = x + (S1*x + (x *(r-y/2)+y))
*/
#include "fdlibm.h"
#ifndef _DOUBLE_IS_32BITS
#ifdef __STDC__
static const double
#else
static double
#endif
half = 5.00000000000000000000e-01, /* 0x3FE00000, 0x00000000 */
S1 = -1.66666666666666324348e-01, /* 0xBFC55555, 0x55555549 */
S2 = 8.33333333332248946124e-03, /* 0x3F811111, 0x1110F8A6 */
S3 = -1.98412698298579493134e-04, /* 0xBF2A01A0, 0x19C161D5 */
S4 = 2.75573137070700676789e-06, /* 0x3EC71DE3, 0x57B1FE7D */
S5 = -2.50507602534068634195e-08, /* 0xBE5AE5E6, 0x8A2B9CEB */
S6 = 1.58969099521155010221e-10; /* 0x3DE5D93A, 0x5ACFD57C */
#ifdef __STDC__
double __kernel_sin(double x, double y, int iy)
#else
double __kernel_sin(x, y, iy)
double x,y; int iy; /* iy=0 if y is zero */
#endif
{
double z,r,v;
int32_t ix;
GET_HIGH_WORD(ix,x);
ix &= 0x7fffffff; /* high word of x */
if(ix<0x3e400000) /* |x| < 2**-27 */
{if((int)x==0) return x;} /* generate inexact */
z = x*x;
v = z*x;
r = S2+z*(S3+z*(S4+z*(S5+z*S6)));
if(iy==0) return x+v*(S1+z*r);
else return x-((z*(half*y-v*r)-y)-v*S1);
}
#endif /* defined(_DOUBLE_IS_32BITS) */
+132
View File
@@ -0,0 +1,132 @@
/* @(#)k_tan.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
/* __kernel_tan( x, y, k )
* kernel tan function on [-pi/4, pi/4], pi/4 ~ 0.7854
* Input x is assumed to be bounded by ~pi/4 in magnitude.
* Input y is the tail of x.
* Input k indicates whether tan (if k=1) or
* -1/tan (if k= -1) is returned.
*
* Algorithm
* 1. Since tan(-x) = -tan(x), we need only to consider positive x.
* 2. if x < 2^-28 (hx<0x3e300000 0), return x with inexact if x!=0.
* 3. tan(x) is approximated by a odd polynomial of degree 27 on
* [0,0.67434]
* 3 27
* tan(x) ~ x + T1*x + ... + T13*x
* where
*
* |tan(x) 2 4 26 | -59.2
* |----- - (1+T1*x +T2*x +.... +T13*x )| <= 2
* | x |
*
* Note: tan(x+y) = tan(x) + tan'(x)*y
* ~ tan(x) + (1+x*x)*y
* Therefore, for better accuracy in computing tan(x+y), let
* 3 2 2 2 2
* r = x *(T2+x *(T3+x *(...+x *(T12+x *T13))))
* then
* 3 2
* tan(x+y) = x + (T1*x + (x *(r+y)+y))
*
* 4. For x in [0.67434,pi/4], let y = pi/4 - x, then
* tan(x) = tan(pi/4-y) = (1-tan(y))/(1+tan(y))
* = 1 - 2*(tan(y) - (tan(y)^2)/(1+tan(y)))
*/
#include "fdlibm.h"
#ifndef _DOUBLE_IS_32BITS
#ifdef __STDC__
static const double
#else
static double
#endif
one = 1.00000000000000000000e+00, /* 0x3FF00000, 0x00000000 */
pio4 = 7.85398163397448278999e-01, /* 0x3FE921FB, 0x54442D18 */
pio4lo= 3.06161699786838301793e-17, /* 0x3C81A626, 0x33145C07 */
T[] = {
3.33333333333334091986e-01, /* 0x3FD55555, 0x55555563 */
1.33333333333201242699e-01, /* 0x3FC11111, 0x1110FE7A */
5.39682539762260521377e-02, /* 0x3FABA1BA, 0x1BB341FE */
2.18694882948595424599e-02, /* 0x3F9664F4, 0x8406D637 */
8.86323982359930005737e-03, /* 0x3F8226E3, 0xE96E8493 */
3.59207910759131235356e-03, /* 0x3F6D6D22, 0xC9560328 */
1.45620945432529025516e-03, /* 0x3F57DBC8, 0xFEE08315 */
5.88041240820264096874e-04, /* 0x3F4344D8, 0xF2F26501 */
2.46463134818469906812e-04, /* 0x3F3026F7, 0x1A8D1068 */
7.81794442939557092300e-05, /* 0x3F147E88, 0xA03792A6 */
7.14072491382608190305e-05, /* 0x3F12B80F, 0x32F0A7E9 */
-1.85586374855275456654e-05, /* 0xBEF375CB, 0xDB605373 */
2.59073051863633712884e-05, /* 0x3EFB2A70, 0x74BF7AD4 */
};
#ifdef __STDC__
double __kernel_tan(double x, double y, int iy)
#else
double __kernel_tan(x, y, iy)
double x,y; int iy;
#endif
{
double z,r,v,w,s;
int32_t ix,hx;
GET_HIGH_WORD(hx,x);
ix = hx&0x7fffffff; /* high word of |x| */
if(ix<0x3e300000) /* x < 2**-28 */
{if((int)x==0) { /* generate inexact */
uint32_t low;
GET_LOW_WORD(low,x);
if(((ix|low)|(iy+1))==0) return one/fabs(x);
else return (iy==1)? x: -one/x;
}
}
if(ix>=0x3FE59428) { /* |x|>=0.6744 */
if(hx<0) {x = -x; y = -y;}
z = pio4-x;
w = pio4lo-y;
x = z+w; y = 0.0;
}
z = x*x;
w = z*z;
/* Break x^5*(T[1]+x^2*T[2]+...) into
* x^5(T[1]+x^4*T[3]+...+x^20*T[11]) +
* x^5(x^2*(T[2]+x^4*T[4]+...+x^22*[T12]))
*/
r = T[1]+w*(T[3]+w*(T[5]+w*(T[7]+w*(T[9]+w*T[11]))));
v = z*(T[2]+w*(T[4]+w*(T[6]+w*(T[8]+w*(T[10]+w*T[12])))));
s = z*x;
r = y + z*(s*(r+v)+y);
r += T[0]*s;
w = x+r;
if(ix>=0x3FE59428) {
v = (double)iy;
return (double)(1-((hx>>30)&2))*(v-2.0*(x-(w*w/(w+v)-r)));
}
if(iy==1) return w;
else { /* if allow error up to 2 ulp,
simply return -1.0/(x+r) here */
/* compute -1.0/(x+r) accurately */
double a,t;
z = w;
SET_LOW_WORD(z,0);
v = r-(z - x); /* z+v = r+x */
t = a = -1.0/w; /* a = -1.0/w */
SET_LOW_WORD(t,0);
s = 1.0+t*z;
return t+a*(s+t*v);
}
}
#endif /* defined(_DOUBLE_IS_32BITS) */
+958
View File
@@ -0,0 +1,958 @@
/****************************************************************
*
* The author of this software is David M. Gay.
*
* Copyright (c) 1991 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
* is included in all copies of any software which is or includes a copy
* or modification of this software and in all copies of the supporting
* documentation for such software.
*
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR AT&T MAKES ANY
* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
* OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
*
***************************************************************/
/* Please send bug reports to
David M. Gay
AT&T Bell Laboratories, Room 2C-463
600 Mountain Avenue
Murray Hill, NJ 07974-2070
U.S.A.
dmg@research.att.com or research!dmg
*/
/* strtod for IEEE-, VAX-, and IBM-arithmetic machines.
*
* This strtod returns a nearest machine number to the input decimal
* string (or sets errno to ERANGE). With IEEE arithmetic, ties are
* broken by the IEEE round-even rule. Otherwise ties are broken by
* biased rounding (add half and chop).
*
* Inspired loosely by William D. Clinger's paper "How to Read Floating
* Point Numbers Accurately" [Proc. ACM SIGPLAN '90, pp. 92-101].
*
* Modifications:
*
* 1. We only require IEEE, IBM, or VAX double-precision
* arithmetic (not IEEE double-extended).
* 2. We get by with floating-point arithmetic in a case that
* Clinger missed -- when we're computing d * 10^n
* for a small integer d and the integer n is not too
* much larger than 22 (the maximum integer k for which
* we can represent 10^k exactly), we may be able to
* compute (d*10^k) * 10^(e-k) with just one roundoff.
* 3. Rather than a bit-at-a-time adjustment of the binary
* result in the hard case, we use floating-point
* arithmetic to determine the adjustment to within
* one bit; only in really hard cases do we need to
* compute a second residual.
* 4. Because of 3., we don't need a large table of powers of 10
* for ten-to-e (just some small tables, e.g. of 10^k
* for 0 <= k <= 22).
*/
/*
* #define IEEE_8087 for IEEE-arithmetic machines where the least
* significant byte has the lowest address.
* #define IEEE_MC68k for IEEE-arithmetic machines where the most
* significant byte has the lowest address.
* #define Sudden_Underflow for IEEE-format machines without gradual
* underflow (i.e., that flush to zero on underflow).
* #define IBM for IBM mainframe-style floating-point arithmetic.
* #define VAX for VAX-style floating-point arithmetic.
* #define Unsigned_Shifts if >> does treats its left operand as unsigned.
* #define No_leftright to omit left-right logic in fast floating-point
* computation of dtoa.
* #define Check_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3.
* #define RND_PRODQUOT to use rnd_prod and rnd_quot (assembly routines
* that use extended-precision instructions to compute rounded
* products and quotients) with IBM.
* #define ROUND_BIASED for IEEE-format with biased rounding.
* #define Inaccurate_Divide for IEEE-format with correctly rounded
* products but inaccurate quotients, e.g., for Intel i860.
* #define Just_16 to store 16 bits per 32-bit long when doing high-precision
* integer arithmetic. Whether this speeds things up or slows things
* down depends on the machine and the number being converted.
*/
#include <stdlib.h>
#include <string.h>
#include <java-assert.h>
#include "mprec.h"
/* reent.c knows this value */
#define _Kmax 15
#include <stdio.h>
_Jv_Bigint *
_DEFUN (Balloc, (ptr, k), struct _Jv_reent *ptr _AND int k)
{
_Jv_Bigint *rv = NULL;
int i = 0;
int j = 1;
JvAssert ((1 << k) < MAX_BIGNUM_WDS);
while ((ptr->_allocation_map & j) && i < MAX_BIGNUMS)
i++, j <<= 1;
JvAssert (i < MAX_BIGNUMS);
if (i >= MAX_BIGNUMS)
return NULL;
ptr->_allocation_map |= j;
rv = &ptr->_freelist[i];
rv->_k = k;
rv->_maxwds = 32;
return rv;
}
void
_DEFUN (Bfree, (ptr, v), struct _Jv_reent *ptr _AND _Jv_Bigint * v)
{
long i;
i = v - ptr->_freelist;
JvAssert (i >= 0 && i < MAX_BIGNUMS);
if (i >= 0 && i < MAX_BIGNUMS)
ptr->_allocation_map &= ~ (1 << i);
}
_Jv_Bigint *
_DEFUN (multadd, (ptr, b, m, a),
struct _Jv_reent *ptr _AND
_Jv_Bigint * b _AND
int m _AND
int a)
{
int i, wds;
unsigned long *x, y;
#ifdef Pack_32
unsigned long xi, z;
#endif
_Jv_Bigint *b1;
wds = b->_wds;
x = b->_x;
i = 0;
do
{
#ifdef Pack_32
xi = *x;
y = (xi & 0xffff) * m + a;
z = (xi >> 16) * m + (y >> 16);
a = (int) (z >> 16);
*x++ = (z << 16) + (y & 0xffff);
#else
y = *x * m + a;
a = (int) (y >> 16);
*x++ = y & 0xffff;
#endif
}
while (++i < wds);
if (a)
{
if (wds >= b->_maxwds)
{
b1 = Balloc (ptr, b->_k + 1);
Bcopy (b1, b);
Bfree (ptr, b);
b = b1;
}
b->_x[wds++] = a;
b->_wds = wds;
}
return b;
}
_Jv_Bigint *
_DEFUN (s2b, (ptr, s, nd0, nd, y9),
struct _Jv_reent * ptr _AND
_CONST char *s _AND
int nd0 _AND
int nd _AND
unsigned long y9)
{
_Jv_Bigint *b;
int i, k;
long x, y;
x = (nd + 8) / 9;
for (k = 0, y = 1; x > y; y <<= 1, k++);
#ifdef Pack_32
b = Balloc (ptr, k);
b->_x[0] = y9;
b->_wds = 1;
#else
b = Balloc (ptr, k + 1);
b->_x[0] = y9 & 0xffff;
b->_wds = (b->_x[1] = y9 >> 16) ? 2 : 1;
#endif
i = 9;
if (9 < nd0)
{
s += 9;
do
b = multadd (ptr, b, 10, *s++ - '0');
while (++i < nd0);
s++;
}
else
s += 10;
for (; i < nd; i++)
b = multadd (ptr, b, 10, *s++ - '0');
return b;
}
int
_DEFUN (hi0bits,
(x), register unsigned long x)
{
register int k = 0;
if (!(x & 0xffff0000))
{
k = 16;
x <<= 16;
}
if (!(x & 0xff000000))
{
k += 8;
x <<= 8;
}
if (!(x & 0xf0000000))
{
k += 4;
x <<= 4;
}
if (!(x & 0xc0000000))
{
k += 2;
x <<= 2;
}
if (!(x & 0x80000000))
{
k++;
if (!(x & 0x40000000))
return 32;
}
return k;
}
int
_DEFUN (lo0bits, (y), unsigned long *y)
{
register int k;
register unsigned long x = *y;
if (x & 7)
{
if (x & 1)
return 0;
if (x & 2)
{
*y = x >> 1;
return 1;
}
*y = x >> 2;
return 2;
}
k = 0;
if (!(x & 0xffff))
{
k = 16;
x >>= 16;
}
if (!(x & 0xff))
{
k += 8;
x >>= 8;
}
if (!(x & 0xf))
{
k += 4;
x >>= 4;
}
if (!(x & 0x3))
{
k += 2;
x >>= 2;
}
if (!(x & 1))
{
k++;
x >>= 1;
if (!(x & 1))
return 32;
}
*y = x;
return k;
}
_Jv_Bigint *
_DEFUN (i2b, (ptr, i), struct _Jv_reent * ptr _AND int i)
{
_Jv_Bigint *b;
b = Balloc (ptr, 1);
b->_x[0] = i;
b->_wds = 1;
return b;
}
_Jv_Bigint *
_DEFUN (mult, (ptr, a, b), struct _Jv_reent * ptr _AND _Jv_Bigint * a _AND _Jv_Bigint * b)
{
_Jv_Bigint *c;
int k, wa, wb, wc;
unsigned long carry, y, z;
unsigned long *x, *xa, *xae, *xb, *xbe, *xc, *xc0;
#ifdef Pack_32
unsigned long z2;
#endif
if (a->_wds < b->_wds)
{
c = a;
a = b;
b = c;
}
k = a->_k;
wa = a->_wds;
wb = b->_wds;
wc = wa + wb;
if (wc > a->_maxwds)
k++;
c = Balloc (ptr, k);
for (x = c->_x, xa = x + wc; x < xa; x++)
*x = 0;
xa = a->_x;
xae = xa + wa;
xb = b->_x;
xbe = xb + wb;
xc0 = c->_x;
#ifdef Pack_32
for (; xb < xbe; xb++, xc0++)
{
if ((y = *xb & 0xffff))
{
x = xa;
xc = xc0;
carry = 0;
do
{
z = (*x & 0xffff) * y + (*xc & 0xffff) + carry;
carry = z >> 16;
z2 = (*x++ >> 16) * y + (*xc >> 16) + carry;
carry = z2 >> 16;
Storeinc (xc, z2, z);
}
while (x < xae);
*xc = carry;
}
if ((y = *xb >> 16))
{
x = xa;
xc = xc0;
carry = 0;
z2 = *xc;
do
{
z = (*x & 0xffff) * y + (*xc >> 16) + carry;
carry = z >> 16;
Storeinc (xc, z, z2);
z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry;
carry = z2 >> 16;
}
while (x < xae);
*xc = z2;
}
}
#else
for (; xb < xbe; xc0++)
{
if ((y = *xb++))
{
x = xa;
xc = xc0;
carry = 0;
do
{
z = *x++ * y + *xc + carry;
carry = z >> 16;
*xc++ = z & 0xffff;
}
while (x < xae);
*xc = carry;
}
}
#endif
for (xc0 = c->_x, xc = xc0 + wc; wc > 0 && !*--xc; --wc);
c->_wds = wc;
return c;
}
_Jv_Bigint *
_DEFUN (pow5mult,
(ptr, b, k), struct _Jv_reent * ptr _AND _Jv_Bigint * b _AND int k)
{
_Jv_Bigint *b1, *p5, *p51;
int i;
static _CONST int p05[3] = {5, 25, 125};
if ((i = k & 3))
b = multadd (ptr, b, p05[i - 1], 0);
if (!(k >>= 2))
return b;
if (!(p5 = ptr->_p5s))
{
/* first time */
p5 = ptr->_p5s = i2b (ptr, 625);
p5->_next = 0;
}
for (;;)
{
if (k & 1)
{
b1 = mult (ptr, b, p5);
Bfree (ptr, b);
b = b1;
}
if (!(k >>= 1))
break;
if (!(p51 = p5->_next))
{
p51 = p5->_next = mult (ptr, p5, p5);
p51->_next = 0;
}
p5 = p51;
}
return b;
}
_Jv_Bigint *
_DEFUN (lshift, (ptr, b, k), struct _Jv_reent * ptr _AND _Jv_Bigint * b _AND int k)
{
int i, k1, n, n1;
_Jv_Bigint *b1;
unsigned long *x, *x1, *xe, z;
#ifdef Pack_32
n = k >> 5;
#else
n = k >> 4;
#endif
k1 = b->_k;
n1 = n + b->_wds + 1;
for (i = b->_maxwds; n1 > i; i <<= 1)
k1++;
b1 = Balloc (ptr, k1);
x1 = b1->_x;
for (i = 0; i < n; i++)
*x1++ = 0;
x = b->_x;
xe = x + b->_wds;
#ifdef Pack_32
if (k &= 0x1f)
{
k1 = 32 - k;
z = 0;
do
{
*x1++ = *x << k | z;
z = *x++ >> k1;
}
while (x < xe);
if ((*x1 = z))
++n1;
}
#else
if (k &= 0xf)
{
k1 = 16 - k;
z = 0;
do
{
*x1++ = (*x << k & 0xffff) | z;
z = *x++ >> k1;
}
while (x < xe);
if ((*x1 = z))
++n1;
}
#endif
else
do
*x1++ = *x++;
while (x < xe);
b1->_wds = n1 - 1;
Bfree (ptr, b);
return b1;
}
int
_DEFUN (cmp, (a, b), _Jv_Bigint * a _AND _Jv_Bigint * b)
{
unsigned long *xa, *xa0, *xb, *xb0;
int i, j;
i = a->_wds;
j = b->_wds;
#ifdef DEBUG
if (i > 1 && !a->_x[i - 1])
Bug ("cmp called with a->_x[a->_wds-1] == 0");
if (j > 1 && !b->_x[j - 1])
Bug ("cmp called with b->_x[b->_wds-1] == 0");
#endif
if (i -= j)
return i;
xa0 = a->_x;
xa = xa0 + j;
xb0 = b->_x;
xb = xb0 + j;
for (;;)
{
if (*--xa != *--xb)
return *xa < *xb ? -1 : 1;
if (xa <= xa0)
break;
}
return 0;
}
_Jv_Bigint *
_DEFUN (diff, (ptr, a, b), struct _Jv_reent * ptr _AND
_Jv_Bigint * a _AND _Jv_Bigint * b)
{
_Jv_Bigint *c;
int i, wa, wb;
long borrow, y; /* We need signed shifts here. */
unsigned long *xa, *xae, *xb, *xbe, *xc;
#ifdef Pack_32
long z;
#endif
i = cmp (a, b);
if (!i)
{
c = Balloc (ptr, 0);
c->_wds = 1;
c->_x[0] = 0;
return c;
}
if (i < 0)
{
c = a;
a = b;
b = c;
i = 1;
}
else
i = 0;
c = Balloc (ptr, a->_k);
c->_sign = i;
wa = a->_wds;
xa = a->_x;
xae = xa + wa;
wb = b->_wds;
xb = b->_x;
xbe = xb + wb;
xc = c->_x;
borrow = 0;
#ifdef Pack_32
do
{
y = (*xa & 0xffff) - (*xb & 0xffff) + borrow;
borrow = y >> 16;
Sign_Extend (borrow, y);
z = (*xa++ >> 16) - (*xb++ >> 16) + borrow;
borrow = z >> 16;
Sign_Extend (borrow, z);
Storeinc (xc, z, y);
}
while (xb < xbe);
while (xa < xae)
{
y = (*xa & 0xffff) + borrow;
borrow = y >> 16;
Sign_Extend (borrow, y);
z = (*xa++ >> 16) + borrow;
borrow = z >> 16;
Sign_Extend (borrow, z);
Storeinc (xc, z, y);
}
#else
do
{
y = *xa++ - *xb++ + borrow;
borrow = y >> 16;
Sign_Extend (borrow, y);
*xc++ = y & 0xffff;
}
while (xb < xbe);
while (xa < xae)
{
y = *xa++ + borrow;
borrow = y >> 16;
Sign_Extend (borrow, y);
*xc++ = y & 0xffff;
}
#endif
while (!*--xc)
wa--;
c->_wds = wa;
return c;
}
double
_DEFUN (ulp, (_x), double _x)
{
union double_union x, a;
register long L;
x.d = _x;
L = (word0 (x) & Exp_mask) - (P - 1) * Exp_msk1;
#ifndef Sudden_Underflow
if (L > 0)
{
#endif
#ifdef IBM
L |= Exp_msk1 >> 4;
#endif
word0 (a) = L;
#ifndef _DOUBLE_IS_32BITS
word1 (a) = 0;
#endif
#ifndef Sudden_Underflow
}
else
{
L = -L >> Exp_shift;
if (L < Exp_shift)
{
word0 (a) = 0x80000 >> L;
#ifndef _DOUBLE_IS_32BITS
word1 (a) = 0;
#endif
}
else
{
word0 (a) = 0;
L -= Exp_shift;
#ifndef _DOUBLE_IS_32BITS
word1 (a) = L >= 31 ? 1 : 1 << (31 - L);
#endif
}
}
#endif
return a.d;
}
double
_DEFUN (b2d, (a, e),
_Jv_Bigint * a _AND int *e)
{
unsigned long *xa, *xa0, w, y, z;
int k;
union double_union d;
#ifdef VAX
unsigned long d0, d1;
#else
#define d0 word0(d)
#define d1 word1(d)
#endif
xa0 = a->_x;
xa = xa0 + a->_wds;
y = *--xa;
#ifdef DEBUG
if (!y)
Bug ("zero y in b2d");
#endif
k = hi0bits (y);
*e = 32 - k;
#ifdef Pack_32
if (k < Ebits)
{
d0 = Exp_1 | y >> (Ebits - k);
w = xa > xa0 ? *--xa : 0;
#ifndef _DOUBLE_IS_32BITS
d1 = y << (32 - Ebits + k) | w >> (Ebits - k);
#endif
goto ret_d;
}
z = xa > xa0 ? *--xa : 0;
if (k -= Ebits)
{
d0 = Exp_1 | y << k | z >> (32 - k);
y = xa > xa0 ? *--xa : 0;
#ifndef _DOUBLE_IS_32BITS
d1 = z << k | y >> (32 - k);
#endif
}
else
{
d0 = Exp_1 | y;
#ifndef _DOUBLE_IS_32BITS
d1 = z;
#endif
}
#else
if (k < Ebits + 16)
{
z = xa > xa0 ? *--xa : 0;
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);
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);
y = xa > xa0 ? *--xa : 0;
d1 = w << (k + 16) | y << k;
#endif
ret_d:
#ifdef VAX
word0 (d) = d0 >> 16 | d0 << 16;
word1 (d) = d1 >> 16 | d1 << 16;
#else
#undef d0
#undef d1
#endif
return d.d;
}
_Jv_Bigint *
_DEFUN (d2b,
(ptr, _d, e, bits),
struct _Jv_reent * ptr _AND
double _d _AND
int *e _AND
int *bits)
{
union double_union d;
_Jv_Bigint *b;
int de, i, k;
unsigned long *x, y, z;
#ifdef VAX
unsigned long d0, d1;
d.d = _d;
d0 = word0 (d) >> 16 | word0 (d) << 16;
d1 = word1 (d) >> 16 | word1 (d) << 16;
#else
#define d0 word0(d)
#define d1 word1(d)
d.d = _d;
#endif
#ifdef Pack_32
b = Balloc (ptr, 1);
#else
b = Balloc (ptr, 2);
#endif
x = b->_x;
z = d0 & Frac_mask;
d0 &= 0x7fffffff; /* clear sign bit, which we ignore */
#ifdef Sudden_Underflow
de = (int) (d0 >> Exp_shift);
#ifndef IBM
z |= Exp_msk11;
#endif
#else
if ((de = (int) (d0 >> Exp_shift)))
z |= Exp_msk1;
#endif
#ifdef Pack_32
#ifndef _DOUBLE_IS_32BITS
if ((y = d1))
{
if ((k = lo0bits (&y)))
{
x[0] = y | z << (32 - k);
z >>= k;
}
else
x[0] = y;
i = b->_wds = (x[1] = z) ? 2 : 1;
}
else
#endif
{
#ifdef DEBUG
if (!z)
Bug ("Zero passed to d2b");
#endif
k = lo0bits (&z);
x[0] = z;
i = b->_wds = 1;
#ifndef _DOUBLE_IS_32BITS
k += 32;
#endif
}
#else
if ((y = d1))
{
if ((k = lo0bits (&y)))
if (k >= 16)
{
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[2] = z >> k & 0xffff;
x[3] = z >> (k + 16);
i = 3;
}
else
{
x[0] = y & 0xffff;
x[1] = y >> 16;
x[2] = z & 0xffff;
x[3] = z >> 16;
i = 3;
}
}
else
{
#ifdef DEBUG
if (!z)
Bug ("Zero passed to d2b");
#endif
k = lo0bits (&z);
if (k >= 16)
{
x[0] = z;
i = 0;
}
else
{
x[0] = z & 0xffff;
x[1] = z >> 16;
i = 1;
}
k += 32;
}
while (!x[i])
--i;
b->_wds = i + 1;
#endif
#ifndef Sudden_Underflow
if (de)
{
#endif
#ifdef IBM
*e = (de - Bias - (P - 1) << 2) + k;
*bits = 4 * P + 8 - k - hi0bits (word0 (d) & Frac_mask);
#else
*e = de - Bias - (P - 1) + k;
*bits = P - k;
#endif
#ifndef Sudden_Underflow
}
else
{
*e = de - Bias - (P - 1) + 1 + k;
#ifdef Pack_32
*bits = 32 * i - hi0bits (x[i - 1]);
#else
*bits = (i + 2) * 16 - hi0bits (x[i]);
#endif
}
#endif
return b;
}
#undef d0
#undef d1
double
_DEFUN (ratio, (a, b), _Jv_Bigint * a _AND _Jv_Bigint * b)
{
union double_union da, db;
int k, ka, kb;
da.d = b2d (a, &ka);
db.d = b2d (b, &kb);
#ifdef Pack_32
k = ka - kb + 32 * (a->_wds - b->_wds);
#else
k = ka - kb + 16 * (a->_wds - b->_wds);
#endif
#ifdef IBM
if (k > 0)
{
word0 (da) += (k >> 2) * Exp_msk1;
if (k &= 3)
da.d *= 1 << k;
}
else
{
k = -k;
word0 (db) += (k >> 2) * Exp_msk1;
if (k &= 3)
db.d *= 1 << k;
}
#else
if (k > 0)
word0 (da) += k * Exp_msk1;
else
{
k = -k;
word0 (db) += k * Exp_msk1;
}
#endif
return da.d / db.d;
}
_CONST double
tens[] =
{
1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
1e20, 1e21, 1e22, 1e23, 1e24
};
#if !defined(_DOUBLE_IS_32BITS) && !defined(__v800)
_CONST double bigtens[] =
{1e16, 1e32, 1e64, 1e128, 1e256};
_CONST double tinytens[] =
{1e-16, 1e-32, 1e-64, 1e-128, 1e-256};
#else
_CONST double bigtens[] =
{1e16, 1e32};
_CONST double tinytens[] =
{1e-16, 1e-32};
#endif
+402
View File
@@ -0,0 +1,402 @@
/****************************************************************
*
* The author of this software is David M. Gay.
*
* Copyright (c) 1991, 2000 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
* is included in all copies of any software which is or includes a copy
* or modification of this software and in all copies of the supporting
* documentation for such software.
*
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR AT&T MAKES ANY
* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
* OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
*
***************************************************************/
/* Please send bug reports to
David M. Gay
AT&T Bell Laboratories, Room 2C-463
600 Mountain Avenue
Murray Hill, NJ 07974-2070
U.S.A.
dmg@research.att.com or research!dmg
*/
#ifndef __CLASSPATH_MPREC_H__
#define __CLASSPATH_MPREC_H__
#include <config.h>
#include "ieeefp.h"
#if defined HAVE_STDINT_H
#include <stdint.h>
#elif defined HAVE_INTTYPES_H
#include <inttypes.h>
#endif
#if defined HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#if defined HAVE_SYS_CONFIG_H
#include <sys/config.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
/* ISO C99 int type declarations */
#if !defined HAVE_INT32_DEFINED && defined HAVE_BSD_INT32_DEFINED
typedef u_int32_t uint32_t;
#endif
#if !defined HAVE_BSD_INT32_DEFINED && !defined HAVE_INT32_DEFINED
/* FIXME this could have problems with systems that don't define SI to be 4 */
typedef int int32_t __attribute__((mode(SI)));
/* This is a blatant hack: on Solaris 2.5, pthread.h defines uint32_t
in pthread.h, which we sometimes include. We protect our
definition the same way Solaris 2.5 does, to avoid redefining it. */
# ifndef _UINT32_T
typedef unsigned int uint32_t __attribute__((mode(SI)));
# endif
#endif
/* These typedefs are true for the targets running Java. */
#ifdef __IEEE_LITTLE_ENDIAN
#define IEEE_8087
#endif
#ifdef __IEEE_BIG_ENDIAN
#define IEEE_MC68k
#endif
#ifdef __Z8000__
#define Just_16
#endif
#ifdef DEBUG
#include "stdio.h"
#define Bug(x) {fprintf(stderr, "%s\n", x); exit(1);}
#endif
#ifdef Unsigned_Shifts
#define Sign_Extend(a,b) if (b < 0) a |= (uint32_t)0xffff0000;
#else
#define Sign_Extend(a,b) /*no-op*/
#endif
#if defined(IEEE_8087) + defined(IEEE_MC68k) + defined(VAX) + defined(IBM) != 1
Exactly one of IEEE_8087, IEEE_MC68k, VAX, or IBM should be defined.
#endif
/* If we are going to examine or modify specific bits in a double using
the word0 and/or word1 macros, then we must wrap the double inside
a union. This is necessary to avoid undefined behavior according to
the ANSI C spec. */
union double_union
{
double d;
uint32_t i[2];
};
#ifdef IEEE_8087
#define word0(x) (x.i[1])
#define word1(x) (x.i[0])
#else
#define word0(x) (x.i[0])
#define word1(x) (x.i[1])
#endif
/* The following definition of Storeinc is appropriate for MIPS processors.
* An alternative that might be better on some machines is
* #define Storeinc(a,b,c) (*a++ = b << 16 | c & 0xffff)
*/
#if defined(IEEE_8087) + defined(VAX)
#define Storeinc(a,b,c) (((unsigned short *)a)[1] = (unsigned short)b, \
((unsigned short *)a)[0] = (unsigned short)c, a++)
#else
#define Storeinc(a,b,c) (((unsigned short *)a)[0] = (unsigned short)b, \
((unsigned short *)a)[1] = (unsigned short)c, a++)
#endif
/* #define P DBL_MANT_DIG */
/* Ten_pmax = floor(P*log(2)/log(5)) */
/* Bletch = (highest power of 2 < DBL_MAX_10_EXP) / 16 */
/* Quick_max = floor((P-1)*log(FLT_RADIX)/log(10) - 1) */
/* Int_max = floor(P*log(FLT_RADIX)/log(10) - 1) */
#if defined(IEEE_8087) + defined(IEEE_MC68k)
#if defined (_DOUBLE_IS_32BITS)
#define Exp_shift 23
#define Exp_shift1 23
#define Exp_msk1 ((uint32_t)0x00800000L)
#define Exp_msk11 ((uint32_t)0x00800000L)
#define Exp_mask ((uint32_t)0x7f800000L)
#define P 24
#define Bias 127
#if 0
#define IEEE_Arith /* it is, but the code doesn't handle IEEE singles yet */
#endif
#define Emin (-126)
#define Exp_1 ((uint32_t)0x3f800000L)
#define Exp_11 ((uint32_t)0x3f800000L)
#define Ebits 8
#define Frac_mask ((uint32_t)0x007fffffL)
#define Frac_mask1 ((uint32_t)0x007fffffL)
#define Ten_pmax 10
#define Sign_bit ((uint32_t)0x80000000L)
#define Ten_pmax 10
#define Bletch 2
#define Bndry_mask ((uint32_t)0x007fffffL)
#define Bndry_mask1 ((uint32_t)0x007fffffL)
#define LSB 1
#define Sign_bit ((uint32_t)0x80000000L)
#define Log2P 1
#define Tiny0 0
#define Tiny1 1
#define Quick_max 5
#define Int_max 6
#define Infinite(x) (word0(x) == ((uint32_t)0x7f800000L))
#undef word0
#undef word1
#define word0(x) (x.i[0])
#define word1(x) 0
#else
#define Exp_shift 20
#define Exp_shift1 20
#define Exp_msk1 ((uint32_t)0x100000L)
#define Exp_msk11 ((uint32_t)0x100000L)
#define Exp_mask ((uint32_t)0x7ff00000L)
#define P 53
#define Bias 1023
#define IEEE_Arith
#define Emin (-1022)
#define Exp_1 ((uint32_t)0x3ff00000L)
#define Exp_11 ((uint32_t)0x3ff00000L)
#define Ebits 11
#define Frac_mask ((uint32_t)0xfffffL)
#define Frac_mask1 ((uint32_t)0xfffffL)
#define Ten_pmax 22
#define Bletch 0x10
#define Bndry_mask ((uint32_t)0xfffffL)
#define Bndry_mask1 ((uint32_t)0xfffffL)
#define LSB 1
#define Sign_bit ((uint32_t)0x80000000L)
#define Log2P 1
#define Tiny0 0
#define Tiny1 1
#define Quick_max 14
#define Int_max 14
#define Infinite(x) (word0(x) == ((uint32_t)0x7ff00000L)) /* sufficient test for here */
#endif
#else
#undef Sudden_Underflow
#define Sudden_Underflow
#ifdef IBM
#define Exp_shift 24
#define Exp_shift1 24
#define Exp_msk1 ((uint32_t)0x1000000L)
#define Exp_msk11 ((uint32_t)0x1000000L)
#define Exp_mask ((uint32_t)0x7f000000L)
#define P 14
#define Bias 65
#define Exp_1 ((uint32_t)0x41000000L)
#define Exp_11 ((uint32_t)0x41000000L)
#define Ebits 8 /* exponent has 7 bits, but 8 is the right value in b2d */
#define Frac_mask ((uint32_t)0xffffffL)
#define Frac_mask1 ((uint32_t)0xffffffL)
#define Bletch 4
#define Ten_pmax 22
#define Bndry_mask ((uint32_t)0xefffffL)
#define Bndry_mask1 ((uint32_t)0xffffffL)
#define LSB 1
#define Sign_bit ((uint32_t)0x80000000L)
#define Log2P 4
#define Tiny0 ((uint32_t)0x100000L)
#define Tiny1 0
#define Quick_max 14
#define Int_max 15
#else /* VAX */
#define Exp_shift 23
#define Exp_shift1 7
#define Exp_msk1 0x80
#define Exp_msk11 ((uint32_t)0x800000L)
#define Exp_mask ((uint32_t)0x7f80L)
#define P 56
#define Bias 129
#define Exp_1 ((uint32_t)0x40800000L)
#define Exp_11 ((uint32_t)0x4080L)
#define Ebits 8
#define Frac_mask ((uint32_t)0x7fffffL)
#define Frac_mask1 ((uint32_t)0xffff007fL)
#define Ten_pmax 24
#define Bletch 2
#define Bndry_mask ((uint32_t)0xffff007fL)
#define Bndry_mask1 ((uint32_t)0xffff007fL)
#define LSB ((uint32_t)0x10000L)
#define Sign_bit ((uint32_t)0x8000L)
#define Log2P 1
#define Tiny0 0x80
#define Tiny1 0
#define Quick_max 15
#define Int_max 15
#endif
#endif
#ifndef IEEE_Arith
#define ROUND_BIASED
#endif
#ifdef RND_PRODQUOT
#define rounded_product(a,b) a = rnd_prod(a, b)
#define rounded_quotient(a,b) a = rnd_quot(a, b)
#ifdef KR_headers
extern double rnd_prod(), rnd_quot();
#else
extern double rnd_prod(double, double), rnd_quot(double, double);
#endif
#else
#define rounded_product(a,b) a *= b
#define rounded_quotient(a,b) a /= b
#endif
#define Big0 (Frac_mask1 | Exp_msk1*(DBL_MAX_EXP+Bias-1))
#define Big1 ((uint32_t)0xffffffffL)
#ifndef Just_16
/* When Pack_32 is not defined, we store 16 bits per 32-bit long.
* This makes some inner loops simpler and sometimes saves work
* during multiplications, but it often seems to make things slightly
* slower. Hence the default is now to store 32 bits per long.
*/
#ifndef Pack_32
#if SIZEOF_VOID_P != 8
#define Pack_32
#endif
#endif
#endif
#define MAX_BIGNUMS 16
#define MAX_BIGNUM_WDS 32
struct _Jv_Bigint
{
struct _Jv_Bigint *_next;
int _k, _maxwds, _sign, _wds;
unsigned long _x[MAX_BIGNUM_WDS];
};
#define _PTR void *
#define _AND ,
#define _NOARGS void
#define _CONST const
#define _VOLATILE volatile
#define _SIGNED signed
#define _DOTS , ...
#define _VOID void
#define _EXFUN(name, proto) name proto
#define _DEFUN(name, arglist, args) name(args)
#define _DEFUN_VOID(name) name(_NOARGS)
#define _CAST_VOID (void)
struct _Jv_reent
{
/* local copy of errno */
int _errno;
/* used by mprec routines */
struct _Jv_Bigint *_result;
int _result_k;
struct _Jv_Bigint *_p5s;
struct _Jv_Bigint _freelist[MAX_BIGNUMS];
int _allocation_map;
int num;
};
typedef struct _Jv_Bigint _Jv_Bigint;
#define Balloc _Jv_Balloc
#define Bfree _Jv_Bfree
#define multadd _Jv_multadd
#define s2b _Jv_s2b
#define lo0bits _Jv_lo0bits
#define hi0bits _Jv_hi0bits
#define i2b _Jv_i2b
#define mult _Jv_mult
#define pow5mult _Jv_pow5mult
#define lshift _Jv_lshift
#define cmp _Jv__mcmp
#define diff _Jv__mdiff
#define ulp _Jv_ulp
#define b2d _Jv_b2d
#define d2b _Jv_d2b
#define ratio _Jv_ratio
#define tens _Jv__mprec_tens
#define bigtens _Jv__mprec_bigtens
#define tinytens _Jv__mprec_tinytens
#define _dtoa _Jv_dtoa
#define _dtoa_r _Jv_dtoa_r
#define _strtod_r _Jv_strtod_r
extern double _EXFUN(_strtod_r, (struct _Jv_reent *ptr, const char *s00, char **se));
extern char* _EXFUN(_dtoa_r, (struct _Jv_reent *ptr, double d,
int mode, int ndigits, int *decpt, int *sign,
char **rve, int float_type));
void _EXFUN(_dtoa, (double d, int mode, int ndigits, int *decpt, int *sign,
char **rve, char *buf, int float_type));
double _EXFUN(ulp,(double x));
double _EXFUN(b2d,(_Jv_Bigint *a , int *e));
_Jv_Bigint * _EXFUN(Balloc,(struct _Jv_reent *p, int k));
void _EXFUN(Bfree,(struct _Jv_reent *p, _Jv_Bigint *v));
_Jv_Bigint * _EXFUN(multadd,(struct _Jv_reent *p, _Jv_Bigint *, int, int));
_Jv_Bigint * _EXFUN(s2b,(struct _Jv_reent *, const char*, int, int, unsigned long));
_Jv_Bigint * _EXFUN(i2b,(struct _Jv_reent *,int));
_Jv_Bigint * _EXFUN(mult, (struct _Jv_reent *, _Jv_Bigint *, _Jv_Bigint *));
_Jv_Bigint * _EXFUN(pow5mult, (struct _Jv_reent *, _Jv_Bigint *, int k));
int _EXFUN(hi0bits,(unsigned long));
int _EXFUN(lo0bits,(unsigned long *));
_Jv_Bigint * _EXFUN(d2b,(struct _Jv_reent *p, double d, int *e, int *bits));
_Jv_Bigint * _EXFUN(lshift,(struct _Jv_reent *p, _Jv_Bigint *b, int k));
_Jv_Bigint * _EXFUN(diff,(struct _Jv_reent *p, _Jv_Bigint *a, _Jv_Bigint *b));
int _EXFUN(cmp,(_Jv_Bigint *a, _Jv_Bigint *b));
double _EXFUN(ratio,(_Jv_Bigint *a, _Jv_Bigint *b));
#define Bcopy(x,y) memcpy((char *)&x->_sign, (char *)&y->_sign, y->_wds*sizeof(long) + 2*sizeof(int))
#if defined(_DOUBLE_IS_32BITS) && defined(__v800)
#define n_bigtens 2
#else
#define n_bigtens 5
#endif
extern _CONST double tinytens[];
extern _CONST double bigtens[];
extern _CONST double tens[];
#ifdef __cplusplus
}
#endif
#endif /* __CLASSPATH_MPREC_H__ */
+181
View File
@@ -0,0 +1,181 @@
/* @(#)s_atan.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*
*/
/*
FUNCTION
<<atan>>, <<atanf>>---arc tangent
INDEX
atan
INDEX
atanf
ANSI_SYNOPSIS
#include <math.h>
double atan(double <[x]>);
float atanf(float <[x]>);
TRAD_SYNOPSIS
#include <math.h>
double atan(<[x]>);
double <[x]>;
float atanf(<[x]>);
float <[x]>;
DESCRIPTION
<<atan>> computes the inverse tangent (arc tangent) of the input value.
<<atanf>> is identical to <<atan>>, save that it operates on <<floats>>.
RETURNS
@ifinfo
<<atan>> returns a value in radians, in the range of -pi/2 to pi/2.
@end ifinfo
@tex
<<atan>> returns a value in radians, in the range of $-\pi/2$ to $\pi/2$.
@end tex
PORTABILITY
<<atan>> is ANSI C. <<atanf>> is an extension.
*/
/* atan(x)
* Method
* 1. Reduce x to positive by atan(x) = -atan(-x).
* 2. According to the integer k=4t+0.25 chopped, t=x, the argument
* is further reduced to one of the following intervals and the
* arctangent of t is evaluated by the corresponding formula:
*
* [0,7/16] atan(x) = t-t^3*(a1+t^2*(a2+...(a10+t^2*a11)...)
* [7/16,11/16] atan(x) = atan(1/2) + atan( (t-0.5)/(1+t/2) )
* [11/16.19/16] atan(x) = atan( 1 ) + atan( (t-1)/(1+t) )
* [19/16,39/16] atan(x) = atan(3/2) + atan( (t-1.5)/(1+1.5t) )
* [39/16,INF] atan(x) = atan(INF) + atan( -1/t )
*
* Constants:
* The hexadecimal values are the intended ones for the following
* constants. The decimal values may be used, provided that the
* compiler will convert from decimal to binary accurately enough
* to produce the hexadecimal values shown.
*/
#include "fdlibm.h"
#ifndef _DOUBLE_IS_32BITS
#ifdef __STDC__
static const double atanhi[] = {
#else
static double atanhi[] = {
#endif
4.63647609000806093515e-01, /* atan(0.5)hi 0x3FDDAC67, 0x0561BB4F */
7.85398163397448278999e-01, /* atan(1.0)hi 0x3FE921FB, 0x54442D18 */
9.82793723247329054082e-01, /* atan(1.5)hi 0x3FEF730B, 0xD281F69B */
1.57079632679489655800e+00, /* atan(inf)hi 0x3FF921FB, 0x54442D18 */
};
#ifdef __STDC__
static const double atanlo[] = {
#else
static double atanlo[] = {
#endif
2.26987774529616870924e-17, /* atan(0.5)lo 0x3C7A2B7F, 0x222F65E2 */
3.06161699786838301793e-17, /* atan(1.0)lo 0x3C81A626, 0x33145C07 */
1.39033110312309984516e-17, /* atan(1.5)lo 0x3C700788, 0x7AF0CBBD */
6.12323399573676603587e-17, /* atan(inf)lo 0x3C91A626, 0x33145C07 */
};
#ifdef __STDC__
static const double aT[] = {
#else
static double aT[] = {
#endif
3.33333333333329318027e-01, /* 0x3FD55555, 0x5555550D */
-1.99999999998764832476e-01, /* 0xBFC99999, 0x9998EBC4 */
1.42857142725034663711e-01, /* 0x3FC24924, 0x920083FF */
-1.11111104054623557880e-01, /* 0xBFBC71C6, 0xFE231671 */
9.09088713343650656196e-02, /* 0x3FB745CD, 0xC54C206E */
-7.69187620504482999495e-02, /* 0xBFB3B0F2, 0xAF749A6D */
6.66107313738753120669e-02, /* 0x3FB10D66, 0xA0D03D51 */
-5.83357013379057348645e-02, /* 0xBFADDE2D, 0x52DEFD9A */
4.97687799461593236017e-02, /* 0x3FA97B4B, 0x24760DEB */
-3.65315727442169155270e-02, /* 0xBFA2B444, 0x2C6A6C2F */
1.62858201153657823623e-02, /* 0x3F90AD3A, 0xE322DA11 */
};
#ifdef __STDC__
static const double
#else
static double
#endif
one = 1.0,
huge = 1.0e300;
#ifdef __STDC__
double atan(double x)
#else
double atan(x)
double x;
#endif
{
double w,s1,s2,z;
int32_t ix,hx,id;
GET_HIGH_WORD(hx,x);
ix = hx&0x7fffffff;
if(ix>=0x44100000) { /* if |x| >= 2^66 */
uint32_t low;
GET_LOW_WORD(low,x);
if(ix>0x7ff00000||
(ix==0x7ff00000&&(low!=0)))
return x+x; /* NaN */
if(hx>0) return atanhi[3]+atanlo[3];
else return -atanhi[3]-atanlo[3];
} if (ix < 0x3fdc0000) { /* |x| < 0.4375 */
if (ix < 0x3e200000) { /* |x| < 2^-29 */
if(huge+x>one) return x; /* raise inexact */
}
id = -1;
} else {
x = fabs(x);
if (ix < 0x3ff30000) { /* |x| < 1.1875 */
if (ix < 0x3fe60000) { /* 7/16 <=|x|<11/16 */
id = 0; x = (2.0*x-one)/(2.0+x);
} else { /* 11/16<=|x|< 19/16 */
id = 1; x = (x-one)/(x+one);
}
} else {
if (ix < 0x40038000) { /* |x| < 2.4375 */
id = 2; x = (x-1.5)/(one+1.5*x);
} else { /* 2.4375 <= |x| < 2^66 */
id = 3; x = -1.0/x;
}
}}
/* end of argument reduction */
z = x*x;
w = z*z;
/* break sum from i=0 to 10 aT[i]z**(i+1) into odd and even poly */
s1 = z*(aT[0]+w*(aT[2]+w*(aT[4]+w*(aT[6]+w*(aT[8]+w*aT[10])))));
s2 = w*(aT[1]+w*(aT[3]+w*(aT[5]+w*(aT[7]+w*aT[9]))));
if (id<0) return x - x*(s1+s2);
else {
z = atanhi[id] - ((x*(s1+s2) - atanlo[id]) - x);
return (hx<0)? -z:z;
}
}
#endif /* _DOUBLE_IS_32BITS */
+80
View File
@@ -0,0 +1,80 @@
/* @(#)s_ceil.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
/*
* ceil(x)
* Return x rounded toward -inf to integral value
* Method:
* Bit twiddling.
* Exception:
* Inexact flag raised if x not equal to ceil(x).
*/
#include "fdlibm.h"
#ifndef _DOUBLE_IS_32BITS
#ifdef __STDC__
static const double huge = 1.0e300;
#else
static double huge = 1.0e300;
#endif
#ifdef __STDC__
double ceil(double x)
#else
double ceil(x)
double x;
#endif
{
int32_t i0,i1,j0;
uint32_t i,j;
EXTRACT_WORDS(i0,i1,x);
j0 = ((i0>>20)&0x7ff)-0x3ff;
if(j0<20) {
if(j0<0) { /* raise inexact if x != 0 */
if(huge+x>0.0) {/* return 0*sign(x) if |x|<1 */
if(i0<0) {i0=0x80000000;i1=0;}
else if((i0|i1)!=0) { i0=0x3ff00000;i1=0;}
}
} else {
i = (0x000fffff)>>j0;
if(((i0&i)|i1)==0) return x; /* x is integral */
if(huge+x>0.0) { /* raise inexact flag */
if(i0>0) i0 += (0x00100000)>>j0;
i0 &= (~i); i1=0;
}
}
} else if (j0>51) {
if(j0==0x400) return x+x; /* inf or NaN */
else return x; /* x is integral */
} else {
i = ((uint32_t)(0xffffffff))>>(j0-20);
if((i1&i)==0) return x; /* x is integral */
if(huge+x>0.0) { /* raise inexact flag */
if(i0>0) {
if(j0==20) i0+=1;
else {
j = i1 + (1<<(52-j0));
if(j<(uint32_t)i1) i0+=1; /* got a carry */
i1 = j;
}
}
i1 &= (~i);
}
}
INSERT_WORDS(x,i0,i1);
return x;
}
#endif /* _DOUBLE_IS_32BITS */
@@ -0,0 +1,82 @@
/* @(#)s_copysign.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
/*
FUNCTION
<<copysign>>, <<copysignf>>---sign of <[y]>, magnitude of <[x]>
INDEX
copysign
INDEX
copysignf
ANSI_SYNOPSIS
#include <math.h>
double copysign (double <[x]>, double <[y]>);
float copysignf (float <[x]>, float <[y]>);
TRAD_SYNOPSIS
#include <math.h>
double copysign (<[x]>, <[y]>)
double <[x]>;
double <[y]>;
float copysignf (<[x]>, <[y]>)
float <[x]>;
float <[y]>;
DESCRIPTION
<<copysign>> constructs a number with the magnitude (absolute value)
of its first argument, <[x]>, and the sign of its second argument,
<[y]>.
<<copysignf>> does the same thing; the two functions differ only in
the type of their arguments and result.
RETURNS
<<copysign>> returns a <<double>> with the magnitude of
<[x]> and the sign of <[y]>.
<<copysignf>> returns a <<float>> with the magnitude of
<[x]> and the sign of <[y]>.
PORTABILITY
<<copysign>> is not required by either ANSI C or the System V Interface
Definition (Issue 2).
*/
/*
* copysign(double x, double y)
* copysign(x,y) returns a value with the magnitude of x and
* with the sign bit of y.
*/
#include "fdlibm.h"
#ifndef _DOUBLE_IS_32BITS
#ifdef __STDC__
double copysign(double x, double y)
#else
double copysign(x,y)
double x,y;
#endif
{
uint32_t hx,hy;
GET_HIGH_WORD(hx,x);
GET_HIGH_WORD(hy,y);
SET_HIGH_WORD(x,(hx&0x7fffffff)|(hy&0x80000000));
return x;
}
#endif /* _DOUBLE_IS_32BITS */
+82
View File
@@ -0,0 +1,82 @@
/* @(#)s_cos.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
/* cos(x)
* Return cosine function of x.
*
* kernel function:
* __kernel_sin ... sine function on [-pi/4,pi/4]
* __kernel_cos ... cosine function on [-pi/4,pi/4]
* __ieee754_rem_pio2 ... argument reduction routine
*
* Method.
* Let S,C and T denote the sin, cos and tan respectively on
* [-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2
* in [-pi/4 , +pi/4], and let n = k mod 4.
* We have
*
* n sin(x) cos(x) tan(x)
* ----------------------------------------------------------
* 0 S C T
* 1 C -S -1/T
* 2 -S -C T
* 3 -C S -1/T
* ----------------------------------------------------------
*
* Special cases:
* Let trig be any of sin, cos, or tan.
* trig(+-INF) is NaN, with signals;
* trig(NaN) is that NaN;
*
* Accuracy:
* TRIG(x) returns trig(x) nearly rounded
*/
#include "fdlibm.h"
#ifndef _DOUBLE_IS_32BITS
#ifdef __STDC__
double cos(double x)
#else
double cos(x)
double x;
#endif
{
double y[2],z=0.0;
int32_t n,ix;
/* High word of x. */
GET_HIGH_WORD(ix,x);
/* |x| ~< pi/4 */
ix &= 0x7fffffff;
if(ix <= 0x3fe921fb) return __kernel_cos(x,z);
/* cos(Inf or NaN) is NaN */
else if (ix>=0x7ff00000) return x-x;
/* argument reduction needed */
else {
n = __ieee754_rem_pio2(x,y);
switch(n&3) {
case 0: return __kernel_cos(y[0],y[1]);
case 1: return -__kernel_sin(y[0],y[1],1);
case 2: return -__kernel_cos(y[0],y[1]);
default:
return __kernel_sin(y[0],y[1],1);
}
}
}
#endif /* _DOUBLE_IS_32BITS */
+73
View File
@@ -0,0 +1,73 @@
/* @(#)s_fabs.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
/*
FUNCTION
<<fabs>>, <<fabsf>>---absolute value (magnitude)
INDEX
fabs
INDEX
fabsf
ANSI_SYNOPSIS
#include <math.h>
double fabs(double <[x]>);
float fabsf(float <[x]>);
TRAD_SYNOPSIS
#include <math.h>
double fabs(<[x]>)
double <[x]>;
float fabsf(<[x]>)
float <[x]>;
DESCRIPTION
<<fabs>> and <<fabsf>> calculate
@tex
$|x|$,
@end tex
the absolute value (magnitude) of the argument <[x]>, by direct
manipulation of the bit representation of <[x]>.
RETURNS
The calculated value is returned. No errors are detected.
PORTABILITY
<<fabs>> is ANSI.
<<fabsf>> is an extension.
*/
/*
* fabs(x) returns the absolute value of x.
*/
#include "fdlibm.h"
#ifndef _DOUBLE_IS_32BITS
#ifdef __STDC__
double fabs(double x)
#else
double fabs(x)
double x;
#endif
{
uint32_t high;
GET_HIGH_WORD(high,x);
SET_HIGH_WORD(x,high&0x7fffffff);
return x;
}
#endif /* _DOUBLE_IS_32BITS */
@@ -0,0 +1,31 @@
/* @(#)s_finite.c 1.3 95/01/18 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunSoft, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
/*
* finite(x) returns 1 is x is finite, else 0;
* no branching!
*/
#include "fdlibm.h"
#ifdef __STDC__
int finite(double x)
#else
int finite(x)
double x;
#endif
{
uint32_t high;
GET_HIGH_WORD(high,x);
return (unsigned)((high&0x7fffffff)-0x7ff00000)>>31;
}
+134
View File
@@ -0,0 +1,134 @@
/* @(#)s_floor.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
/*
FUNCTION
<<floor>>, <<floorf>>, <<ceil>>, <<ceilf>>---floor and ceiling
INDEX
floor
INDEX
floorf
INDEX
ceil
INDEX
ceilf
ANSI_SYNOPSIS
#include <math.h>
double floor(double <[x]>);
float floorf(float <[x]>);
double ceil(double <[x]>);
float ceilf(float <[x]>);
TRAD_SYNOPSIS
#include <math.h>
double floor(<[x]>)
double <[x]>;
float floorf(<[x]>)
float <[x]>;
double ceil(<[x]>)
double <[x]>;
float ceilf(<[x]>)
float <[x]>;
DESCRIPTION
<<floor>> and <<floorf>> find
@tex
$\lfloor x \rfloor$,
@end tex
the nearest integer less than or equal to <[x]>.
<<ceil>> and <<ceilf>> find
@tex
$\lceil x\rceil$,
@end tex
the nearest integer greater than or equal to <[x]>.
RETURNS
<<floor>> and <<ceil>> return the integer result as a double.
<<floorf>> and <<ceilf>> return the integer result as a float.
PORTABILITY
<<floor>> and <<ceil>> are ANSI.
<<floorf>> and <<ceilf>> are extensions.
*/
/*
* floor(x)
* Return x rounded toward -inf to integral value
* Method:
* Bit twiddling.
* Exception:
* Inexact flag raised if x not equal to floor(x).
*/
#include "fdlibm.h"
#ifndef _DOUBLE_IS_32BITS
#ifdef __STDC__
static const double huge = 1.0e300;
#else
static double huge = 1.0e300;
#endif
#ifdef __STDC__
double floor(double x)
#else
double floor(x)
double x;
#endif
{
int32_t i0,i1,j0;
uint32_t i,j;
EXTRACT_WORDS(i0,i1,x);
j0 = ((i0>>20)&0x7ff)-0x3ff;
if(j0<20) {
if(j0<0) { /* raise inexact if x != 0 */
if(huge+x>0.0) {/* return 0*sign(x) if |x|<1 */
if(i0>=0) {i0=i1=0;}
else if(((i0&0x7fffffff)|i1)!=0)
{ i0=0xbff00000;i1=0;}
}
} else {
i = (0x000fffff)>>j0;
if(((i0&i)|i1)==0) return x; /* x is integral */
if(huge+x>0.0) { /* raise inexact flag */
if(i0<0) i0 += (0x00100000)>>j0;
i0 &= (~i); i1=0;
}
}
} else if (j0>51) {
if(j0==0x400) return x+x; /* inf or NaN */
else return x; /* x is integral */
} else {
i = ((uint32_t)(0xffffffff))>>(j0-20);
if((i1&i)==0) return x; /* x is integral */
if(huge+x>0.0) { /* raise inexact flag */
if(i0<0) {
if(j0==20) i0+=1;
else {
j = i1+(1<<(52-j0));
if(j<(uint32_t)i1) i0 +=1 ; /* got a carry */
i1=j;
}
}
i1 &= (~i);
}
}
INSERT_WORDS(x,i0,i1);
return x;
}
#endif /* _DOUBLE_IS_32BITS */
+87
View File
@@ -0,0 +1,87 @@
/* @(#)s_rint.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
/*
* rint(x)
* Return x rounded to integral value according to the prevailing
* rounding mode.
* Method:
* Using floating addition.
* Exception:
* Inexact flag raised if x not equal to rint(x).
*/
#include "fdlibm.h"
#ifndef _DOUBLE_IS_32BITS
#ifdef __STDC__
static const double
#else
static double
#endif
TWO52[2]={
4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */
-4.50359962737049600000e+15, /* 0xC3300000, 0x00000000 */
};
#ifdef __STDC__
double rint(double x)
#else
double rint(x)
double x;
#endif
{
int32_t i0,j0,sx;
uint32_t i,i1;
double t;
volatile double w;
EXTRACT_WORDS(i0,i1,x);
sx = (i0>>31)&1;
j0 = ((i0>>20)&0x7ff)-0x3ff;
if(j0<20) {
if(j0<0) {
if(((i0&0x7fffffff)|i1)==0) return x;
i1 |= (i0&0x0fffff);
i0 &= 0xfffe0000;
i0 |= ((i1|-i1)>>12)&0x80000;
SET_HIGH_WORD(x,i0);
w = TWO52[sx]+x;
t = w-TWO52[sx];
GET_HIGH_WORD(i0,t);
SET_HIGH_WORD(t,(i0&0x7fffffff)|(sx<<31));
return t;
} else {
i = (0x000fffff)>>j0;
if(((i0&i)|i1)==0) return x; /* x is integral */
i>>=1;
if(((i0&i)|i1)!=0) {
if(j0==19) i1 = 0x40000000; else
i0 = (i0&(~i))|((0x20000)>>j0);
}
}
} else if (j0>51) {
if(j0==0x400) return x+x; /* inf or NaN */
else return x; /* x is integral */
} else {
i = ((uint32_t)(0xffffffff))>>(j0-20);
if((i1&i)==0) return x; /* x is integral */
i>>=1;
if((i1&i)!=0) i1 = (i1&(~i))|((0x40000000)>>(j0-20));
}
INSERT_WORDS(x,i0,i1);
w = TWO52[sx]+x;
return w-TWO52[sx];
}
#endif /* _DOUBLE_IS_32BITS */
+104
View File
@@ -0,0 +1,104 @@
/* @(#)s_scalbn.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
/*
FUNCTION
<<scalbn>>, <<scalbnf>>---scale by integer
INDEX
scalbn
INDEX
scalbnf
ANSI_SYNOPSIS
#include <math.h>
double scalbn(double <[x]>, int <[y]>);
float scalbnf(float <[x]>, int <[y]>);
TRAD_SYNOPSIS
#include <math.h>
double scalbn(<[x]>,<[y]>)
double <[x]>;
int <[y]>;
float scalbnf(<[x]>,<[y]>)
float <[x]>;
int <[y]>;
DESCRIPTION
<<scalbn>> and <<scalbnf>> scale <[x]> by <[n]>, returning <[x]> times
2 to the power <[n]>. The result is computed by manipulating the
exponent, rather than by actually performing an exponentiation or
multiplication.
RETURNS
<[x]> times 2 to the power <[n]>.
PORTABILITY
Neither <<scalbn>> nor <<scalbnf>> is required by ANSI C or by the System V
Interface Definition (Issue 2).
*/
/*
* scalbn (double x, int n)
* scalbn(x,n) returns x* 2**n computed by exponent
* manipulation rather than by actually performing an
* exponentiation or a multiplication.
*/
#include "fdlibm.h"
#ifndef _DOUBLE_IS_32BITS
#ifdef __STDC__
static const double
#else
static double
#endif
two54 = 1.80143985094819840000e+16, /* 0x43500000, 0x00000000 */
twom54 = 5.55111512312578270212e-17, /* 0x3C900000, 0x00000000 */
huge = 1.0e+300,
tiny = 1.0e-300;
#ifdef __STDC__
double scalbn (double x, int n)
#else
double scalbn (x,n)
double x; int n;
#endif
{
int32_t k,hx,lx;
EXTRACT_WORDS(hx,lx,x);
k = (hx&0x7ff00000)>>20; /* extract exponent */
if (k==0) { /* 0 or subnormal x */
if ((lx|(hx&0x7fffffff))==0) return x; /* +-0 */
x *= two54;
GET_HIGH_WORD(hx,x);
k = ((hx&0x7ff00000)>>20) - 54;
if (n< -50000) return tiny*x; /*underflow*/
}
if (k==0x7ff) return x+x; /* NaN or Inf */
k = k+n;
if (k > 0x7fe) return huge*copysign(huge,x); /* overflow */
if (k > 0) /* normal result */
{SET_HIGH_WORD(x,(hx&0x800fffff)|(k<<20)); return x;}
if (k <= -54) {
if (n > 50000) /* in case integer overflow in n+k */
return huge*copysign(huge,x); /*overflow*/
else return tiny*copysign(tiny,x); /*underflow*/
}
k += 54; /* subnormal result */
SET_HIGH_WORD(x,(hx&0x800fffff)|(k<<20));
return x*twom54;
}
#endif /* _DOUBLE_IS_32BITS */
+132
View File
@@ -0,0 +1,132 @@
/* @(#)s_sin.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
/*
FUNCTION
<<sin>>, <<sinf>>, <<cos>>, <<cosf>>---sine or cosine
INDEX
sin
INDEX
sinf
INDEX
cos
INDEX
cosf
ANSI_SYNOPSIS
#include <math.h>
double sin(double <[x]>);
float sinf(float <[x]>);
double cos(double <[x]>);
float cosf(float <[x]>);
TRAD_SYNOPSIS
#include <math.h>
double sin(<[x]>)
double <[x]>;
float sinf(<[x]>)
float <[x]>;
double cos(<[x]>)
double <[x]>;
float cosf(<[x]>)
float <[x]>;
DESCRIPTION
<<sin>> and <<cos>> compute (respectively) the sine and cosine
of the argument <[x]>. Angles are specified in radians.
<<sinf>> and <<cosf>> are identical, save that they take and
return <<float>> values.
RETURNS
The sine or cosine of <[x]> is returned.
PORTABILITY
<<sin>> and <<cos>> are ANSI C.
<<sinf>> and <<cosf>> are extensions.
QUICKREF
sin ansi pure
sinf - pure
*/
/* sin(x)
* Return sine function of x.
*
* kernel function:
* __kernel_sin ... sine function on [-pi/4,pi/4]
* __kernel_cos ... cose function on [-pi/4,pi/4]
* __ieee754_rem_pio2 ... argument reduction routine
*
* Method.
* Let S,C and T denote the sin, cos and tan respectively on
* [-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2
* in [-pi/4 , +pi/4], and let n = k mod 4.
* We have
*
* n sin(x) cos(x) tan(x)
* ----------------------------------------------------------
* 0 S C T
* 1 C -S -1/T
* 2 -S -C T
* 3 -C S -1/T
* ----------------------------------------------------------
*
* Special cases:
* Let trig be any of sin, cos, or tan.
* trig(+-INF) is NaN, with signals;
* trig(NaN) is that NaN;
*
* Accuracy:
* TRIG(x) returns trig(x) nearly rounded
*/
#include "fdlibm.h"
#ifndef _DOUBLE_IS_32BITS
#ifdef __STDC__
double sin(double x)
#else
double sin(x)
double x;
#endif
{
double y[2],z=0.0;
int32_t n,ix;
/* High word of x. */
GET_HIGH_WORD(ix,x);
/* |x| ~< pi/4 */
ix &= 0x7fffffff;
if(ix <= 0x3fe921fb) return __kernel_sin(x,z,0);
/* sin(Inf or NaN) is NaN */
else if (ix>=0x7ff00000) return x-x;
/* argument reduction needed */
else {
n = __ieee754_rem_pio2(x,y);
switch(n&3) {
case 0: return __kernel_sin(y[0],y[1],1);
case 1: return __kernel_cos(y[0],y[1]);
case 2: return -__kernel_sin(y[0],y[1],1);
default:
return -__kernel_cos(y[0],y[1]);
}
}
}
#endif /* _DOUBLE_IS_32BITS */
+114
View File
@@ -0,0 +1,114 @@
/* @(#)s_tan.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
/*
FUNCTION
<<tan>>, <<tanf>>---tangent
INDEX
tan
INDEX
tanf
ANSI_SYNOPSIS
#include <math.h>
double tan(double <[x]>);
float tanf(float <[x]>);
TRAD_SYNOPSIS
#include <math.h>
double tan(<[x]>)
double <[x]>;
float tanf(<[x]>)
float <[x]>;
DESCRIPTION
<<tan>> computes the tangent of the argument <[x]>.
Angles are specified in radians.
<<tanf>> is identical, save that it takes and returns <<float>> values.
RETURNS
The tangent of <[x]> is returned.
PORTABILITY
<<tan>> is ANSI. <<tanf>> is an extension.
*/
/* tan(x)
* Return tangent function of x.
*
* kernel function:
* __kernel_tan ... tangent function on [-pi/4,pi/4]
* __ieee754_rem_pio2 ... argument reduction routine
*
* Method.
* Let S,C and T denote the sin, cos and tan respectively on
* [-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2
* in [-pi/4 , +pi/4], and let n = k mod 4.
* We have
*
* n sin(x) cos(x) tan(x)
* ----------------------------------------------------------
* 0 S C T
* 1 C -S -1/T
* 2 -S -C T
* 3 -C S -1/T
* ----------------------------------------------------------
*
* Special cases:
* Let trig be any of sin, cos, or tan.
* trig(+-INF) is NaN, with signals;
* trig(NaN) is that NaN;
*
* Accuracy:
* TRIG(x) returns trig(x) nearly rounded
*/
#include "fdlibm.h"
#ifndef _DOUBLE_IS_32BITS
#ifdef __STDC__
double tan(double x)
#else
double tan(x)
double x;
#endif
{
double y[2],z=0.0;
int32_t n,ix;
/* High word of x. */
GET_HIGH_WORD(ix,x);
/* |x| ~< pi/4 */
ix &= 0x7fffffff;
if(ix <= 0x3fe921fb) return __kernel_tan(x,z,1);
/* tan(Inf or NaN) is NaN */
else if (ix>=0x7ff00000) return x-x; /* NaN */
/* argument reduction needed */
else {
n = __ieee754_rem_pio2(x,y);
return __kernel_tan(y[0],y[1],1-((n&1)<<1)); /* 1 -- n even
-1 -- n odd */
}
}
#endif /* _DOUBLE_IS_32BITS */
+47
View File
@@ -0,0 +1,47 @@
/* sf_fabs.c -- float version of s_fabs.c.
* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
/*
* fabsf(x) returns the absolute value of x.
*/
#include "fdlibm.h"
#ifdef __STDC__
float fabsf(float x)
#else
float fabsf(x)
float x;
#endif
{
uint32_t ix;
GET_FLOAT_WORD(ix,x);
SET_FLOAT_WORD(x,ix&0x7fffffff);
return x;
}
#ifdef _DOUBLE_IS_32BITS
#ifdef __STDC__
double fabs(double x)
#else
double fabs(x)
double x;
#endif
{
return (double) fabsf((float) x);
}
#endif /* defined(_DOUBLE_IS_32BITS) */
+80
View File
@@ -0,0 +1,80 @@
/* sf_rint.c -- float version of s_rint.c.
* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
#include "fdlibm.h"
#ifdef __STDC__
static const float
#else
static float
#endif
TWO23[2]={
8.3886080000e+06, /* 0x4b000000 */
-8.3886080000e+06, /* 0xcb000000 */
};
#ifdef __STDC__
float rintf(float x)
#else
float rintf(x)
float x;
#endif
{
int32_t i0,j0,sx;
uint32_t i,i1;
float w,t;
GET_FLOAT_WORD(i0,x);
sx = (i0>>31)&1;
j0 = ((i0>>23)&0xff)-0x7f;
if(j0<23) {
if(j0<0) {
if((i0&0x7fffffff)==0) return x;
i1 = (i0&0x07fffff);
i0 &= 0xfff00000;
i0 |= ((i1|-i1)>>9)&0x400000;
SET_FLOAT_WORD(x,i0);
w = TWO23[sx]+x;
t = w-TWO23[sx];
GET_FLOAT_WORD(i0,t);
SET_FLOAT_WORD(t,(i0&0x7fffffff)|(sx<<31));
return t;
} else {
i = (0x007fffff)>>j0;
if((i0&i)==0) return x; /* x is integral */
i>>=1;
if((i0&i)!=0) i0 = (i0&(~i))|((0x100000)>>j0);
}
} else {
if(j0==0x80) return x+x; /* inf or NaN */
else return x; /* x is integral */
}
SET_FLOAT_WORD(x,i0);
w = TWO23[sx]+x;
return w-TWO23[sx];
}
#ifdef _DOUBLE_IS_32BITS
#ifdef __STDC__
double rint(double x)
#else
double rint(x)
double x;
#endif
{
return (double) rintf((float) x);
}
#endif /* defined(_DOUBLE_IS_32BITS) */
+719
View File
@@ -0,0 +1,719 @@
/*
FUNCTION
<<strtod>>, <<strtodf>>---string to double or float
INDEX
strtod
INDEX
_strtod_r
INDEX
strtodf
ANSI_SYNOPSIS
#include <stdlib.h>
double strtod(const char *<[str]>, char **<[tail]>);
float strtodf(const char *<[str]>, char **<[tail]>);
double _strtod_r(void *<[reent]>,
const char *<[str]>, char **<[tail]>);
TRAD_SYNOPSIS
#include <stdlib.h>
double strtod(<[str]>,<[tail]>)
char *<[str]>;
char **<[tail]>;
float strtodf(<[str]>,<[tail]>)
char *<[str]>;
char **<[tail]>;
double _strtod_r(<[reent]>,<[str]>,<[tail]>)
char *<[reent]>;
char *<[str]>;
char **<[tail]>;
DESCRIPTION
The function <<strtod>> parses the character string <[str]>,
producing a substring which can be converted to a double
value. The substring converted is the longest initial
subsequence of <[str]>, beginning with the first
non-whitespace character, that has the format:
.[+|-]<[digits]>[.][<[digits]>][(e|E)[+|-]<[digits]>]
The substring contains no characters if <[str]> is empty, consists
entirely of whitespace, or if the first non-whitespace
character is something other than <<+>>, <<->>, <<.>>, or a
digit. If the substring is empty, no conversion is done, and
the value of <[str]> is stored in <<*<[tail]>>>. Otherwise,
the substring is converted, and a pointer to the final string
(which will contain at least the terminating null character of
<[str]>) is stored in <<*<[tail]>>>. If you want no
assignment to <<*<[tail]>>>, pass a null pointer as <[tail]>.
<<strtodf>> is identical to <<strtod>> except for its return type.
This implementation returns the nearest machine number to the
input decimal string. Ties are broken by using the IEEE
round-even rule.
The alternate function <<_strtod_r>> is a reentrant version.
The extra argument <[reent]> is a pointer to a reentrancy structure.
RETURNS
<<strtod>> returns the converted substring value, if any. If
no conversion could be performed, 0 is returned. If the
correct value is out of the range of representable values,
plus or minus <<HUGE_VAL>> is returned, and <<ERANGE>> is
stored in errno. If the correct value would cause underflow, 0
is returned and <<ERANGE>> is stored in errno.
Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>,
<<lseek>>, <<read>>, <<sbrk>>, <<write>>.
*/
/****************************************************************
*
* The author of this software is David M. Gay.
*
* Copyright (c) 1991 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
* is included in all copies of any software which is or includes a copy
* or modification of this software and in all copies of the supporting
* documentation for such software.
*
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR AT&T MAKES ANY
* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
* OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
*
***************************************************************/
/* Please send bug reports to
David M. Gay
AT&T Bell Laboratories, Room 2C-463
600 Mountain Avenue
Murray Hill, NJ 07974-2070
U.S.A.
dmg@research.att.com or research!dmg
*/
#include <string.h>
#include <float.h>
#include <errno.h>
#include "mprec.h"
double
_DEFUN (_strtod_r, (ptr, s00, se),
struct _Jv_reent *ptr _AND
_CONST char *s00 _AND
char **se)
{
int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign, e1, esign, i, j,
k, nd, nd0, nf, nz, nz0, sign;
int digits = 0; /* Number of digits found in fraction part. */
long e;
_CONST char *s, *s0, *s1;
double aadj, aadj1, adj;
long L;
unsigned long y, z;
union double_union rv, rv0;
_Jv_Bigint *bb = NULL, *bb1, *bd = NULL, *bd0, *bs = NULL, *delta = NULL;
sign = nz0 = nz = 0;
rv.d = 0.;
for (s = s00;; s++)
switch (*s)
{
case '-':
sign = 1;
/* no break */
case '+':
if (*++s)
goto break2;
/* no break */
case 0:
s = s00;
goto ret;
case '\t':
case '\n':
case '\v':
case '\f':
case '\r':
case ' ':
continue;
default:
goto break2;
}
break2:
if (*s == '0')
{
digits++;
nz0 = 1;
while (*++s == '0')
digits++;
if (!*s)
goto ret;
}
s0 = s;
y = z = 0;
for (nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++)
{
digits++;
if (nd < 9)
y = 10 * y + c - '0';
else if (nd < 16)
z = 10 * z + c - '0';
}
nd0 = nd;
if (c == '.')
{
c = *++s;
if (!nd)
{
for (; c == '0'; c = *++s)
{
digits++;
nz++;
}
if (c > '0' && c <= '9')
{
digits++;
s0 = s;
nf += nz;
nz = 0;
goto have_dig;
}
goto dig_done;
}
for (; c >= '0' && c <= '9'; c = *++s)
{
digits++;
have_dig:
nz++;
if (c -= '0')
{
nf += nz;
for (i = 1; i < nz; i++)
if (nd++ < 9)
y *= 10;
else if (nd <= DBL_DIG + 1)
z *= 10;
if (nd++ < 9)
y = 10 * y + c;
else if (nd <= DBL_DIG + 1)
z = 10 * z + c;
nz = 0;
}
}
}
dig_done:
e = 0;
if (c == 'e' || c == 'E')
{
if (!nd && !nz && !nz0)
{
s = s00;
goto ret;
}
s00 = s;
esign = 0;
switch (c = *++s)
{
case '-':
esign = 1;
case '+':
c = *++s;
}
if (c >= '0' && c <= '9')
{
while (c == '0')
c = *++s;
if (c > '0' && c <= '9')
{
e = c - '0';
s1 = s;
while ((c = *++s) >= '0' && c <= '9')
e = 10 * e + c - '0';
if (s - s1 > 8)
/* Avoid confusion from exponents
* so large that e might overflow.
*/
e = 9999999L;
if (esign)
e = -e;
}
}
else
{
/* No exponent after an 'E' : that's an error. */
ptr->_errno = EINVAL;
e = 0;
s = s00;
goto ret;
}
}
if (!nd)
{
if (!nz && !nz0)
s = s00;
goto ret;
}
e1 = e -= nf;
/* Now we have nd0 digits, starting at s0, followed by a
* decimal point, followed by nd-nd0 digits. The number we're
* after is the integer represented by those digits times
* 10**e */
if (!nd0)
nd0 = nd;
k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1;
rv.d = y;
if (k > 9)
rv.d = tens[k - 9] * rv.d + z;
bd0 = 0;
if (nd <= DBL_DIG
#ifndef RND_PRODQUOT
&& FLT_ROUNDS == 1
#endif
)
{
if (!e)
goto ret;
if (e > 0)
{
if (e <= Ten_pmax)
{
#ifdef VAX
goto vax_ovfl_check;
#else
/* rv.d = */ rounded_product (rv.d, tens[e]);
goto ret;
#endif
}
i = DBL_DIG - nd;
if (e <= Ten_pmax + i)
{
/* A fancier test would sometimes let us do
* this for larger i values.
*/
e -= i;
rv.d *= tens[i];
#ifdef VAX
/* VAX exponent range is so narrow we must
* worry about overflow here...
*/
vax_ovfl_check:
word0 (rv) -= P * Exp_msk1;
/* rv.d = */ rounded_product (rv.d, tens[e]);
if ((word0 (rv) & Exp_mask)
> Exp_msk1 * (DBL_MAX_EXP + Bias - 1 - P))
goto ovfl;
word0 (rv) += P * Exp_msk1;
#else
/* rv.d = */ rounded_product (rv.d, tens[e]);
#endif
goto ret;
}
}
#ifndef Inaccurate_Divide
else if (e >= -Ten_pmax)
{
/* rv.d = */ rounded_quotient (rv.d, tens[-e]);
goto ret;
}
#endif
}
e1 += nd - k;
/* Get starting approximation = rv.d * 10**e1 */
if (e1 > 0)
{
if ((i = e1 & 15))
rv.d *= tens[i];
if (e1 &= ~15)
{
if (e1 > DBL_MAX_10_EXP)
{
ovfl:
ptr->_errno = ERANGE;
/* Force result to IEEE infinity. */
word0 (rv) = Exp_mask;
word1 (rv) = 0;
if (bd0)
goto retfree;
goto ret;
}
if (e1 >>= 4)
{
for (j = 0; e1 > 1; j++, e1 >>= 1)
if (e1 & 1)
rv.d *= bigtens[j];
/* The last multiplication could overflow. */
word0 (rv) -= P * Exp_msk1;
rv.d *= bigtens[j];
if ((z = word0 (rv) & Exp_mask)
> Exp_msk1 * (DBL_MAX_EXP + Bias - P))
goto ovfl;
if (z > Exp_msk1 * (DBL_MAX_EXP + Bias - 1 - P))
{
/* set to largest number */
/* (Can't trust DBL_MAX) */
word0 (rv) = Big0;
#ifndef _DOUBLE_IS_32BITS
word1 (rv) = Big1;
#endif
}
else
word0 (rv) += P * Exp_msk1;
}
}
}
else if (e1 < 0)
{
e1 = -e1;
if ((i = e1 & 15))
rv.d /= tens[i];
if (e1 &= ~15)
{
e1 >>= 4;
if (e1 >= 1 << n_bigtens)
goto undfl;
for (j = 0; e1 > 1; j++, e1 >>= 1)
if (e1 & 1)
rv.d *= tinytens[j];
/* The last multiplication could underflow. */
rv0.d = rv.d;
rv.d *= tinytens[j];
if (!rv.d)
{
rv.d = 2. * rv0.d;
rv.d *= tinytens[j];
if (!rv.d)
{
undfl:
rv.d = 0.;
ptr->_errno = ERANGE;
if (bd0)
goto retfree;
goto ret;
}
#ifndef _DOUBLE_IS_32BITS
word0 (rv) = Tiny0;
word1 (rv) = Tiny1;
#else
word0 (rv) = Tiny1;
#endif
/* The refinement below will clean
* this approximation up.
*/
}
}
}
/* Now the hard part -- adjusting rv to the correct value.*/
/* Put digits into bd: true value = bd * 10^e */
bd0 = s2b (ptr, s0, nd0, nd, y);
for (;;)
{
bd = Balloc (ptr, bd0->_k);
Bcopy (bd, bd0);
bb = d2b (ptr, rv.d, &bbe, &bbbits); /* rv.d = bb * 2^bbe */
bs = i2b (ptr, 1);
if (e >= 0)
{
bb2 = bb5 = 0;
bd2 = bd5 = e;
}
else
{
bb2 = bb5 = -e;
bd2 = bd5 = 0;
}
if (bbe >= 0)
bb2 += bbe;
else
bd2 -= bbe;
bs2 = bb2;
#ifdef Sudden_Underflow
#ifdef IBM
j = 1 + 4 * P - 3 - bbbits + ((bbe + bbbits - 1) & 3);
#else
j = P + 1 - bbbits;
#endif
#else
i = bbe + bbbits - 1; /* logb(rv.d) */
if (i < Emin) /* denormal */
j = bbe + (P - Emin);
else
j = P + 1 - bbbits;
#endif
bb2 += j;
bd2 += j;
i = bb2 < bd2 ? bb2 : bd2;
if (i > bs2)
i = bs2;
if (i > 0)
{
bb2 -= i;
bd2 -= i;
bs2 -= i;
}
if (bb5 > 0)
{
bs = pow5mult (ptr, bs, bb5);
bb1 = mult (ptr, bs, bb);
Bfree (ptr, bb);
bb = bb1;
}
if (bb2 > 0)
bb = lshift (ptr, bb, bb2);
if (bd5 > 0)
bd = pow5mult (ptr, bd, bd5);
if (bd2 > 0)
bd = lshift (ptr, bd, bd2);
if (bs2 > 0)
bs = lshift (ptr, bs, bs2);
delta = diff (ptr, bb, bd);
dsign = delta->_sign;
delta->_sign = 0;
i = cmp (delta, bs);
if (i < 0)
{
/* Error is less than half an ulp -- check for
* special case of mantissa a power of two.
*/
if (dsign || word1 (rv) || word0 (rv) & Bndry_mask)
break;
delta = lshift (ptr, delta, Log2P);
if (cmp (delta, bs) > 0)
goto drop_down;
break;
}
if (i == 0)
{
/* exactly half-way between */
if (dsign)
{
if ((word0 (rv) & Bndry_mask1) == Bndry_mask1
&& word1 (rv) == 0xffffffff)
{
/*boundary case -- increment exponent*/
word0 (rv) = (word0 (rv) & Exp_mask)
+ Exp_msk1
#ifdef IBM
| Exp_msk1 >> 4
#endif
;
#ifndef _DOUBLE_IS_32BITS
word1 (rv) = 0;
#endif
break;
}
}
else if (!(word0 (rv) & Bndry_mask) && !word1 (rv))
{
drop_down:
/* boundary case -- decrement exponent */
#ifdef Sudden_Underflow
L = word0 (rv) & Exp_mask;
#ifdef IBM
if (L < Exp_msk1)
#else
if (L <= Exp_msk1)
#endif
goto undfl;
L -= Exp_msk1;
#else
L = (word0 (rv) & Exp_mask) - Exp_msk1;
#endif
word0 (rv) = L | Bndry_mask1;
#ifndef _DOUBLE_IS_32BITS
word1 (rv) = 0xffffffff;
#endif
#ifdef IBM
goto cont;
#else
break;
#endif
}
#ifndef ROUND_BIASED
if (!(word1 (rv) & LSB))
break;
#endif
if (dsign)
rv.d += ulp (rv.d);
#ifndef ROUND_BIASED
else
{
rv.d -= ulp (rv.d);
#ifndef Sudden_Underflow
if (!rv.d)
goto undfl;
#endif
}
#endif
break;
}
if ((aadj = ratio (delta, bs)) <= 2.)
{
if (dsign)
aadj = aadj1 = 1.;
else if (word1 (rv) || word0 (rv) & Bndry_mask)
{
#ifndef Sudden_Underflow
if (word1 (rv) == Tiny1 && !word0 (rv))
goto undfl;
#endif
aadj = 1.;
aadj1 = -1.;
}
else
{
/* special case -- power of FLT_RADIX to be */
/* rounded down... */
if (aadj < 2. / FLT_RADIX)
aadj = 1. / FLT_RADIX;
else
aadj *= 0.5;
aadj1 = -aadj;
}
}
else
{
aadj *= 0.5;
aadj1 = dsign ? aadj : -aadj;
#ifdef Check_FLT_ROUNDS
switch (FLT_ROUNDS)
{
case 2: /* towards +infinity */
aadj1 -= 0.5;
break;
case 0: /* towards 0 */
case 3: /* towards -infinity */
aadj1 += 0.5;
}
#else
if (FLT_ROUNDS == 0)
aadj1 += 0.5;
#endif
}
y = word0 (rv) & Exp_mask;
/* Check for overflow */
if (y == Exp_msk1 * (DBL_MAX_EXP + Bias - 1))
{
rv0.d = rv.d;
word0 (rv) -= P * Exp_msk1;
adj = aadj1 * ulp (rv.d);
rv.d += adj;
if ((word0 (rv) & Exp_mask) >=
Exp_msk1 * (DBL_MAX_EXP + Bias - P))
{
if (word0 (rv0) == Big0 && word1 (rv0) == Big1)
goto ovfl;
#ifdef _DOUBLE_IS_32BITS
word0 (rv) = Big1;
#else
word0 (rv) = Big0;
word1 (rv) = Big1;
#endif
goto cont;
}
else
word0 (rv) += P * Exp_msk1;
}
else
{
#ifdef Sudden_Underflow
if ((word0 (rv) & Exp_mask) <= P * Exp_msk1)
{
rv0.d = rv.d;
word0 (rv) += P * Exp_msk1;
adj = aadj1 * ulp (rv.d);
rv.d += adj;
#ifdef IBM
if ((word0 (rv) & Exp_mask) < P * Exp_msk1)
#else
if ((word0 (rv) & Exp_mask) <= P * Exp_msk1)
#endif
{
if (word0 (rv0) == Tiny0
&& word1 (rv0) == Tiny1)
goto undfl;
word0 (rv) = Tiny0;
word1 (rv) = Tiny1;
goto cont;
}
else
word0 (rv) -= P * Exp_msk1;
}
else
{
adj = aadj1 * ulp (rv.d);
rv.d += adj;
}
#else
/* Compute adj so that the IEEE rounding rules will
* correctly round rv.d + adj in some half-way cases.
* If rv.d * ulp(rv.d) is denormalized (i.e.,
* y <= (P-1)*Exp_msk1), we must adjust aadj to avoid
* trouble from bits lost to denormalization;
* example: 1.2e-307 .
*/
if (y <= (P - 1) * Exp_msk1 && aadj >= 1.)
{
aadj1 = (double) (int) (aadj + 0.5);
if (!dsign)
aadj1 = -aadj1;
}
adj = aadj1 * ulp (rv.d);
rv.d += adj;
#endif
}
z = word0 (rv) & Exp_mask;
if (y == z)
{
/* Can we stop now? */
L = aadj;
aadj -= L;
/* The tolerances below are conservative. */
if (dsign || word1 (rv) || word0 (rv) & Bndry_mask)
{
if (aadj < .4999999 || aadj > .5000001)
break;
}
else if (aadj < .4999999 / FLT_RADIX)
break;
}
cont:
Bfree (ptr, bb);
Bfree (ptr, bd);
Bfree (ptr, bs);
Bfree (ptr, delta);
}
retfree:
Bfree (ptr, bb);
Bfree (ptr, bd);
Bfree (ptr, bs);
Bfree (ptr, bd0);
Bfree (ptr, delta);
ret:
if (se)
*se = (char *) s;
if (digits == 0)
ptr->_errno = EINVAL;
return sign ? -rv.d : rv.d;
}
+118
View File
@@ -0,0 +1,118 @@
/* @(#)w_acos.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
/*
FUNCTION
<<acos>>, <<acosf>>---arc cosine
INDEX
acos
INDEX
acosf
ANSI_SYNOPSIS
#include <math.h>
double acos(double <[x]>);
float acosf(float <[x]>);
TRAD_SYNOPSIS
#include <math.h>
double acos(<[x]>)
double <[x]>;
float acosf(<[x]>)
float <[x]>;
DESCRIPTION
<<acos>> computes the inverse cosine (arc cosine) of the input value.
Arguments to <<acos>> must be in the range @minus{}1 to 1.
<<acosf>> is identical to <<acos>>, except that it performs
its calculations on <<floats>>.
RETURNS
@ifinfo
<<acos>> and <<acosf>> return values in radians, in the range of 0 to pi.
@end ifinfo
@tex
<<acos>> and <<acosf>> return values in radians, in the range of <<0>> to $\pi$.
@end tex
If <[x]> is not between @minus{}1 and 1, the returned value is NaN
(not a number) the global variable <<errno>> is set to <<EDOM>>, and a
<<DOMAIN error>> message is sent as standard error output.
You can modify error handling for these functions using <<matherr>>.
QUICKREF ANSI SVID POSIX RENTRANT
acos y,y,y,m
acosf n,n,n,m
MATHREF
acos, [-1,1], acos(arg),,,
acos, NAN, arg,DOMAIN,EDOM
MATHREF
acosf, [-1,1], acosf(arg),,,
acosf, NAN, argf,DOMAIN,EDOM
*/
/*
* wrap_acos(x)
*/
#include "fdlibm.h"
#include <errno.h>
#ifndef _DOUBLE_IS_32BITS
#ifdef __STDC__
double acos(double x) /* wrapper acos */
#else
double acos(x) /* wrapper acos */
double x;
#endif
{
#ifdef _IEEE_LIBM
return __ieee754_acos(x);
#else
double z;
struct exception exc;
z = __ieee754_acos(x);
if(_LIB_VERSION == _IEEE_ || isnan(x)) return z;
if(fabs(x)>1.0) {
/* acos(|x|>1) */
exc.type = DOMAIN;
exc.name = "acos";
exc.err = 0;
exc.arg1 = exc.arg2 = x;
exc.retval = 0.0;
if (_LIB_VERSION == _POSIX_)
errno = EDOM;
else if (!matherr(&exc)) {
errno = EDOM;
}
if (exc.err != 0)
errno = exc.err;
return exc.retval;
} else
return z;
#endif
}
#endif /* defined(_DOUBLE_IS_32BITS) */
+121
View File
@@ -0,0 +1,121 @@
/* @(#)w_asin.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*
*/
/*
FUNCTION
<<asin>>, <<asinf>>---arc sine
INDEX
asin
INDEX
asinf
ANSI_SYNOPSIS
#include <math.h>
double asin(double <[x]>);
float asinf(float <[x]>);
TRAD_SYNOPSIS
#include <math.h>
double asin(<[x]>)
double <[x]>;
float asinf(<[x]>)
float <[x]>;
DESCRIPTION
<<asin>> computes the inverse sine (arc sine) of the argument <[x]>.
Arguments to <<asin>> must be in the range @minus{}1 to 1.
<<asinf>> is identical to <<asin>>, other than taking and
returning floats.
You can modify error handling for these routines using <<matherr>>.
RETURNS
@ifinfo
<<asin>> returns values in radians, in the range of -pi/2 to pi/2.
@end ifinfo
@tex
<<asin>> returns values in radians, in the range of $-\pi/2$ to $\pi/2$.
@end tex
If <[x]> is not in the range @minus{}1 to 1, <<asin>> and <<asinf>>
return NaN (not a number), set the global variable <<errno>> to
<<EDOM>>, and issue a <<DOMAIN error>> message.
You can change this error treatment using <<matherr>>.
QUICKREF ANSI SVID POSIX RENTRANT
asin y,y,y,m
asinf n,n,n,m
MATHREF
asin, -1<=arg<=1, asin(arg),,,
asin, NAN, arg,EDOM, DOMAIN
MATHREF
asinf, -1<=arg<=1, asin(arg),,,
asinf, NAN, arg,EDOM, DOMAIN
*/
/*
* wrapper asin(x)
*/
#include "fdlibm.h"
#include <errno.h>
#ifndef _DOUBLE_IS_32BITS
#ifdef __STDC__
double asin(double x) /* wrapper asin */
#else
double asin(x) /* wrapper asin */
double x;
#endif
{
#ifdef _IEEE_LIBM
return __ieee754_asin(x);
#else
double z;
struct exception exc;
z = __ieee754_asin(x);
if(_LIB_VERSION == _IEEE_ || isnan(x)) return z;
if(fabs(x)>1.0) {
/* asin(|x|>1) */
exc.type = DOMAIN;
exc.name = "asin";
exc.err = 0;
exc.arg1 = exc.arg2 = x;
exc.retval = 0.0;
if(_LIB_VERSION == _POSIX_)
errno = EDOM;
else if (!matherr(&exc)) {
errno = EDOM;
}
if (exc.err != 0)
errno = exc.err;
return exc.retval;
} else
return z;
#endif
}
#endif /* defined(_DOUBLE_IS_32BITS) */
+117
View File
@@ -0,0 +1,117 @@
/* @(#)w_atan2.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*
*/
/*
FUNCTION
<<atan2>>, <<atan2f>>---arc tangent of y/x
INDEX
atan2
INDEX
atan2f
ANSI_SYNOPSIS
#include <math.h>
double atan2(double <[y]>,double <[x]>);
float atan2f(float <[y]>,float <[x]>);
TRAD_SYNOPSIS
#include <math.h>
double atan2(<[y]>,<[x]>);
double <[y]>;
double <[x]>;
float atan2f(<[y]>,<[x]>);
float <[y]>;
float <[x]>;
DESCRIPTION
<<atan2>> computes the inverse tangent (arc tangent) of <[y]>/<[x]>.
<<atan2>> produces the correct result even for angles near
@ifinfo
pi/2 or -pi/2
@end ifinfo
@tex
$\pi/2$ or $-\pi/2$
@end tex
(that is, when <[x]> is near 0).
<<atan2f>> is identical to <<atan2>>, save that it takes and returns
<<float>>.
RETURNS
<<atan2>> and <<atan2f>> return a value in radians, in the range of
@ifinfo
-pi to pi.
@end ifinfo
@tex
$-\pi$ to $\pi$.
@end tex
If both <[x]> and <[y]> are 0.0, <<atan2>> causes a <<DOMAIN>> error.
You can modify error handling for these functions using <<matherr>>.
PORTABILITY
<<atan2>> is ANSI C. <<atan2f>> is an extension.
*/
/*
* wrapper atan2(y,x)
*/
#include "fdlibm.h"
#include <errno.h>
#ifndef _DOUBLE_IS_32BITS
#ifdef __STDC__
double atan2(double y, double x) /* wrapper atan2 */
#else
double atan2(y,x) /* wrapper atan2 */
double y,x;
#endif
{
#ifdef _IEEE_LIBM
return __ieee754_atan2(y,x);
#else
double z;
struct exception exc;
z = __ieee754_atan2(y,x);
if(_LIB_VERSION == _IEEE_||isnan(x)||isnan(y)) return z;
if(x==0.0&&y==0.0) {
/* atan2(+-0,+-0) */
exc.arg1 = y;
exc.arg2 = x;
exc.type = DOMAIN;
exc.name = "atan2";
exc.err = 0;
exc.retval = 0.0;
if(_LIB_VERSION == _POSIX_)
errno = EDOM;
else if (!matherr(&exc)) {
errno = EDOM;
}
if (exc.err != 0)
errno = exc.err;
return exc.retval;
} else
return z;
#endif
}
#endif /* defined(_DOUBLE_IS_32BITS) */
+140
View File
@@ -0,0 +1,140 @@
/* @(#)w_exp.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
/*
FUNCTION
<<exp>>, <<expf>>---exponential
INDEX
exp
INDEX
expf
ANSI_SYNOPSIS
#include <math.h>
double exp(double <[x]>);
float expf(float <[x]>);
TRAD_SYNOPSIS
#include <math.h>
double exp(<[x]>);
double <[x]>;
float expf(<[x]>);
float <[x]>;
DESCRIPTION
<<exp>> and <<expf>> calculate the exponential of <[x]>, that is,
@ifinfo
e raised to the power <[x]> (where e
@end ifinfo
@tex
$e^x$ (where $e$
@end tex
is the base of the natural system of logarithms, approximately 2.71828).
You can use the (non-ANSI) function <<matherr>> to specify
error handling for these functions.
RETURNS
On success, <<exp>> and <<expf>> return the calculated value.
If the result underflows, the returned value is <<0>>. If the
result overflows, the returned value is <<HUGE_VAL>>. In
either case, <<errno>> is set to <<ERANGE>>.
PORTABILITY
<<exp>> is ANSI C. <<expf>> is an extension.
*/
/*
* wrapper exp(x)
*/
#include "fdlibm.h"
#include <errno.h>
#ifndef _DOUBLE_IS_32BITS
#ifndef _IEEE_LIBM
#ifdef __STDC__
static const double
#else
static double
#endif
o_threshold= 7.09782712893383973096e+02, /* 0x40862E42, 0xFEFA39EF */
u_threshold= -7.45133219101941108420e+02; /* 0xc0874910, 0xD52D3051 */
#endif
#ifdef __STDC__
double exp(double x) /* wrapper exp */
#else
double exp(x) /* wrapper exp */
double x;
#endif
{
#ifdef _IEEE_LIBM
return __ieee754_exp(x);
#else
double z;
struct exception exc;
z = __ieee754_exp(x);
if(_LIB_VERSION == _IEEE_) return z;
if(finite(x)) {
if(x>o_threshold) {
/* exp(finite) overflow */
#ifndef HUGE_VAL
#define HUGE_VAL inf
double inf = 0.0;
SET_HIGH_WORD(inf,0x7ff00000); /* set inf to infinite */
#endif
exc.type = OVERFLOW;
exc.name = "exp";
exc.err = 0;
exc.arg1 = exc.arg2 = x;
if (_LIB_VERSION == _SVID_)
exc.retval = HUGE;
else
exc.retval = HUGE_VAL;
if (_LIB_VERSION == _POSIX_)
errno = ERANGE;
else if (!matherr(&exc)) {
errno = ERANGE;
}
if (exc.err != 0)
errno = exc.err;
return exc.retval;
} else if(x<u_threshold) {
/* exp(finite) underflow */
exc.type = UNDERFLOW;
exc.name = "exp";
exc.err = 0;
exc.arg1 = exc.arg2 = x;
exc.retval = 0.0;
if (_LIB_VERSION == _POSIX_)
errno = ERANGE;
else if (!matherr(&exc)) {
errno = ERANGE;
}
if (exc.err != 0)
errno = exc.err;
return exc.retval;
}
}
return z;
#endif
}
#endif /* defined(_DOUBLE_IS_32BITS) */
+107
View File
@@ -0,0 +1,107 @@
/* @(#)w_fmod.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
/*
FUNCTION
<<fmod>>, <<fmodf>>---floating-point remainder (modulo)
INDEX
fmod
INDEX
fmodf
ANSI_SYNOPSIS
#include <math.h>
double fmod(double <[x]>, double <[y]>)
float fmodf(float <[x]>, float <[y]>)
TRAD_SYNOPSIS
#include <math.h>
double fmod(<[x]>, <[y]>)
double (<[x]>, <[y]>);
float fmodf(<[x]>, <[y]>)
float (<[x]>, <[y]>);
DESCRIPTION
The <<fmod>> and <<fmodf>> functions compute the floating-point
remainder of <[x]>/<[y]> (<[x]> modulo <[y]>).
RETURNS
The <<fmod>> function returns the value
@ifinfo
<[x]>-<[i]>*<[y]>,
@end ifinfo
@tex
$x-i\times y$,
@end tex
for the largest integer <[i]> such that, if <[y]> is nonzero, the
result has the same sign as <[x]> and magnitude less than the
magnitude of <[y]>.
<<fmod(<[x]>,0)>> returns NaN, and sets <<errno>> to <<EDOM>>.
You can modify error treatment for these functions using <<matherr>>.
PORTABILITY
<<fmod>> is ANSI C. <<fmodf>> is an extension.
*/
/*
* wrapper fmod(x,y)
*/
#include "fdlibm.h"
#include <errno.h>
#ifndef _DOUBLE_IS_32BITS
#ifdef __STDC__
double fmod(double x, double y) /* wrapper fmod */
#else
double fmod(x,y) /* wrapper fmod */
double x,y;
#endif
{
#ifdef _IEEE_LIBM
return __ieee754_fmod(x,y);
#else
double z;
struct exception exc;
z = __ieee754_fmod(x,y);
if(_LIB_VERSION == _IEEE_ ||isnan(y)||isnan(x)) return z;
if(y==0.0) {
/* fmod(x,0) */
exc.type = DOMAIN;
exc.name = "fmod";
exc.arg1 = x;
exc.arg2 = y;
exc.err = 0;
if (_LIB_VERSION == _SVID_)
exc.retval = x;
else
exc.retval = 0.0/0.0;
if (_LIB_VERSION == _POSIX_)
errno = EDOM;
else if (!matherr(&exc)) {
errno = EDOM;
}
if (exc.err != 0)
errno = exc.err;
return exc.retval;
} else
return z;
#endif
}
#endif /* defined(_DOUBLE_IS_32BITS) */
+115
View File
@@ -0,0 +1,115 @@
/* @(#)w_log.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
/*
FUNCTION
<<log>>, <<logf>>---natural logarithms
INDEX
log
INDEX
logf
ANSI_SYNOPSIS
#include <math.h>
double log(double <[x]>);
float logf(float <[x]>);
TRAD_SYNOPSIS
#include <math.h>
double log(<[x]>);
double <[x]>;
float logf(<[x]>);
float <[x]>;
DESCRIPTION
Return the natural logarithm of <[x]>, that is, its logarithm base e
(where e is the base of the natural system of logarithms, 2.71828@dots{}).
<<log>> and <<logf>> are identical save for the return and argument types.
You can use the (non-ANSI) function <<matherr>> to specify error
handling for these functions.
RETURNS
Normally, returns the calculated value. When <[x]> is zero, the
returned value is <<-HUGE_VAL>> and <<errno>> is set to <<ERANGE>>.
When <[x]> is negative, the returned value is <<-HUGE_VAL>> and
<<errno>> is set to <<EDOM>>. You can control the error behavior via
<<matherr>>.
PORTABILITY
<<log>> is ANSI, <<logf>> is an extension.
*/
/*
* wrapper log(x)
*/
#include "fdlibm.h"
#include <errno.h>
#ifndef _DOUBLE_IS_32BITS
#ifdef __STDC__
double log(double x) /* wrapper log */
#else
double log(x) /* wrapper log */
double x;
#endif
{
#ifdef _IEEE_LIBM
return __ieee754_log(x);
#else
double z;
struct exception exc;
z = __ieee754_log(x);
if(_LIB_VERSION == _IEEE_ || isnan(x) || x > 0.0) return z;
#ifndef HUGE_VAL
#define HUGE_VAL inf
double inf = 0.0;
SET_HIGH_WORD(inf,0x7ff00000); /* set inf to infinite */
#endif
exc.name = "log";
exc.err = 0;
exc.arg1 = x;
exc.arg2 = x;
if (_LIB_VERSION == _SVID_)
exc.retval = -HUGE;
else
exc.retval = -HUGE_VAL;
if(x==0.0) {
/* log(0) */
exc.type = SING;
if (_LIB_VERSION == _POSIX_)
errno = ERANGE;
else if (!matherr(&exc)) {
errno = EDOM;
}
} else {
/* log(x<0) */
exc.type = DOMAIN;
if (_LIB_VERSION == _POSIX_)
errno = EDOM;
else if (!matherr(&exc)) {
errno = EDOM;
}
}
if (exc.err != 0)
errno = exc.err;
return exc.retval;
#endif
}
#endif /* defined(_DOUBLE_IS_32BITS) */
+231
View File
@@ -0,0 +1,231 @@
/* @(#)w_pow.c 5.2 93/10/01 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
/*
FUNCTION
<<pow>>, <<powf>>---x to the power y
INDEX
pow
INDEX
powf
ANSI_SYNOPSIS
#include <math.h>
double pow(double <[x]>, double <[y]>);
float pow(float <[x]>, float <[y]>);
TRAD_SYNOPSIS
#include <math.h>
double pow(<[x]>, <[y]>);
double <[x]>, <[y]>;
float pow(<[x]>, <[y]>);
float <[x]>, <[y]>;
DESCRIPTION
<<pow>> and <<powf>> calculate <[x]> raised to the exp1.0nt <[y]>.
@tex
(That is, $x^y$.)
@end tex
RETURNS
On success, <<pow>> and <<powf>> return the value calculated.
When the argument values would produce overflow, <<pow>>
returns <<HUGE_VAL>> and set <<errno>> to <<ERANGE>>. If the
argument <[x]> passed to <<pow>> or <<powf>> is a negative
noninteger, and <[y]> is also not an integer, then <<errno>>
is set to <<EDOM>>. If <[x]> and <[y]> are both 0, then
<<pow>> and <<powf>> return <<1>>.
You can modify error handling for these functions using <<matherr>>.
PORTABILITY
<<pow>> is ANSI C. <<powf>> is an extension. */
/*
* wrapper pow(x,y) return x**y
*/
#include "fdlibm.h"
#include <errno.h>
#ifndef _DOUBLE_IS_32BITS
#ifdef __STDC__
double pow(double x, double y) /* wrapper pow */
#else
double pow(x,y) /* wrapper pow */
double x,y;
#endif
{
#ifdef _IEEE_LIBM
return __ieee754_pow(x,y);
#else
double z;
#ifndef HUGE_VAL
#define HUGE_VAL inf
double inf = 0.0;
SET_HIGH_WORD(inf,0x7ff00000); /* set inf to infinite */
#endif
struct exception exc;
z=__ieee754_pow(x,y);
if(_LIB_VERSION == _IEEE_|| isnan(y)) return z;
if(isnan(x)) {
if(y==0.0) {
/* pow(NaN,0.0) */
/* error only if _LIB_VERSION == _SVID_ & _XOPEN_ */
exc.type = DOMAIN;
exc.name = "pow";
exc.err = 0;
exc.arg1 = x;
exc.arg2 = y;
exc.retval = x;
if (_LIB_VERSION == _IEEE_ ||
_LIB_VERSION == _POSIX_) exc.retval = 1.0;
else if (!matherr(&exc)) {
errno = EDOM;
}
if (exc.err != 0)
errno = exc.err;
return exc.retval;
} else
return z;
}
if(x==0.0){
if(y==0.0) {
/* pow(0.0,0.0) */
/* error only if _LIB_VERSION == _SVID_ */
exc.type = DOMAIN;
exc.name = "pow";
exc.err = 0;
exc.arg1 = x;
exc.arg2 = y;
exc.retval = 0.0;
if (_LIB_VERSION != _SVID_) exc.retval = 1.0;
else if (!matherr(&exc)) {
errno = EDOM;
}
if (exc.err != 0)
errno = exc.err;
return exc.retval;
}
if(finite(y)&&y<0.0) {
/* 0**neg */
exc.type = DOMAIN;
exc.name = "pow";
exc.err = 0;
exc.arg1 = x;
exc.arg2 = y;
if (_LIB_VERSION == _SVID_)
exc.retval = 0.0;
else
exc.retval = -HUGE_VAL;
if (_LIB_VERSION == _POSIX_)
errno = EDOM;
else if (!matherr(&exc)) {
errno = EDOM;
}
if (exc.err != 0)
errno = exc.err;
return exc.retval;
}
return z;
}
if(!finite(z)) {
if(finite(x)&&finite(y)) {
if(isnan(z)) {
/* neg**non-integral */
exc.type = DOMAIN;
exc.name = "pow";
exc.err = 0;
exc.arg1 = x;
exc.arg2 = y;
if (_LIB_VERSION == _SVID_)
exc.retval = 0.0;
else
exc.retval = 0.0/0.0; /* X/Open allow NaN */
if (_LIB_VERSION == _POSIX_)
errno = EDOM;
else if (!matherr(&exc)) {
errno = EDOM;
}
if (exc.err != 0)
errno = exc.err;
return exc.retval;
} else {
/* pow(x,y) overflow */
exc.type = OVERFLOW;
exc.name = "pow";
exc.err = 0;
exc.arg1 = x;
exc.arg2 = y;
if (_LIB_VERSION == _SVID_) {
exc.retval = HUGE;
y *= 0.5;
if(x<0.0&&rint(y)!=y) exc.retval = -HUGE;
} else {
exc.retval = HUGE_VAL;
y *= 0.5;
if(x<0.0&&rint(y)!=y) exc.retval = -HUGE_VAL;
}
if (_LIB_VERSION == _POSIX_)
errno = ERANGE;
else if (!matherr(&exc)) {
errno = ERANGE;
}
if (exc.err != 0)
errno = exc.err;
return exc.retval;
}
}
}
if(z==0.0&&finite(x)&&finite(y)) {
/* pow(x,y) underflow */
exc.type = UNDERFLOW;
exc.name = "pow";
exc.err = 0;
exc.arg1 = x;
exc.arg2 = y;
exc.retval = 0.0;
if (_LIB_VERSION == _POSIX_)
errno = ERANGE;
else if (!matherr(&exc)) {
errno = ERANGE;
}
if (exc.err != 0)
errno = exc.err;
return exc.retval;
}
return z;
#endif
}
#endif /* defined(_DOUBLE_IS_32BITS) */
@@ -0,0 +1,119 @@
/* @(#)w_remainder.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
/*
FUNCTION
<<rint>>, <<rintf>>, <<remainder>>, <<remainderf>>---round and remainder
INDEX
rint
INDEX
rintf
INDEX
remainder
INDEX
remainderf
ANSI_SYNOPSIS
#include <math.h>
double rint(double <[x]>);
float rintf(float <[x]>);
double remainder(double <[x]>, double <[y]>);
float remainderf(float <[x]>, float <[y]>);
TRAD_SYNOPSIS
#include <math.h>
double rint(<[x]>)
double <[x]>;
float rintf(<[x]>)
float <[x]>;
double remainder(<[x]>,<[y]>)
double <[x]>, <[y]>;
float remainderf(<[x]>,<[y]>)
float <[x]>, <[y]>;
DESCRIPTION
<<rint>> and <<rintf>> returns their argument rounded to the nearest
integer. <<remainder>> and <<remainderf>> find the remainder of
<[x]>/<[y]>; this value is in the range -<[y]>/2 .. +<[y]>/2.
RETURNS
<<rint>> and <<remainder>> return the integer result as a double.
PORTABILITY
<<rint>> and <<remainder>> are System V release 4. <<rintf>> and
<<remainderf>> are extensions.
*/
/*
* wrapper remainder(x,p)
*/
#include "fdlibm.h"
#include <errno.h>
#ifndef _DOUBLE_IS_32BITS
#ifdef __STDC__
double remainder(double x, double y) /* wrapper remainder */
#else
double remainder(x,y) /* wrapper remainder */
double x,y;
#endif
{
#ifdef _IEEE_LIBM
return __ieee754_remainder(x,y);
#else
double z;
struct exception exc;
z = __ieee754_remainder(x,y);
if(_LIB_VERSION == _IEEE_ || isnan(y)) return z;
if(y==0.0) {
/* remainder(x,0) */
exc.type = DOMAIN;
exc.name = "remainder";
exc.err = 0;
exc.arg1 = x;
exc.arg2 = y;
exc.retval = 0.0/0.0;
if (_LIB_VERSION == _POSIX_)
errno = EDOM;
else if (!matherr(&exc)) {
errno = EDOM;
}
if (exc.err != 0)
errno = exc.err;
return exc.retval;
} else
return z;
#endif
}
#endif /* defined(_DOUBLE_IS_32BITS) */
+93
View File
@@ -0,0 +1,93 @@
/* @(#)w_sqrt.c 5.1 93/09/24 */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
/*
FUNCTION
<<sqrt>>, <<sqrtf>>---positive square root
INDEX
sqrt
INDEX
sqrtf
ANSI_SYNOPSIS
#include <math.h>
double sqrt(double <[x]>);
float sqrtf(float <[x]>);
TRAD_SYNOPSIS
#include <math.h>
double sqrt(<[x]>);
float sqrtf(<[x]>);
DESCRIPTION
<<sqrt>> computes the positive square root of the argument.
You can modify error handling for this function with
<<matherr>>.
RETURNS
On success, the square root is returned. If <[x]> is real and
positive, then the result is positive. If <[x]> is real and
negative, the global value <<errno>> is set to <<EDOM>> (domain error).
PORTABILITY
<<sqrt>> is ANSI C. <<sqrtf>> is an extension.
*/
/*
* wrapper sqrt(x)
*/
#include "fdlibm.h"
#include <errno.h>
#ifndef _DOUBLE_IS_32BITS
#ifdef __STDC__
double sqrt(double x) /* wrapper sqrt */
#else
double sqrt(x) /* wrapper sqrt */
double x;
#endif
{
#ifdef _IEEE_LIBM
return __ieee754_sqrt(x);
#else
struct exception exc;
double z;
z = __ieee754_sqrt(x);
if(_LIB_VERSION == _IEEE_ || isnan(x)) return z;
if(x<0.0) {
exc.type = DOMAIN;
exc.name = "sqrt";
exc.err = 0;
exc.arg1 = exc.arg2 = x;
if (_LIB_VERSION == _SVID_)
exc.retval = 0.0;
else
exc.retval = 0.0/0.0;
if (_LIB_VERSION == _POSIX_)
errno = EDOM;
else if (!matherr(&exc)) {
errno = EDOM;
}
if (exc.err != 0)
errno = exc.err;
return exc.retval;
} else
return z;
#endif
}
#endif /* defined(_DOUBLE_IS_32BITS) */
+8
View File
@@ -0,0 +1,8 @@
*.o
*.a
*.lo
*.la
.libs
.deps
Makefile
Makefile.in
+20
View File
@@ -0,0 +1,20 @@
## Input file for automake to generate the Makefile.in used by configure
if CREATE_CORE_JNI_LIBRARIES
JNIDIRS = java-io java-lang java-net java-nio java-util
endif
if CREATE_GTK_PEER_LIBRARIES
GTKDIR = gtk-peer
endif
if CREATE_XMLJ_LIBRARY
XMLJDIR = xmlj
endif
SUBDIRS = classpath $(JNIDIRS) $(GTKDIR) $(XMLJDIR)
DIST_SUBDIRS = classpath java-io java-lang java-net java-nio java-util \
gtk-peer xmlj
all-local:
cd $(top_srcdir) && scripts/check_jni_methods.sh
@@ -0,0 +1,8 @@
*.o
*.a
*.lo
*.la
.libs
.deps
Makefile
Makefile.in
@@ -0,0 +1,10 @@
noinst_LTLIBRARIES = libclasspath.la
libclasspath_la_SOURCES = jcl.c jcl.h \
jnilink.c jnilink.h \
primlib.c primlib.h \
native_state.c native_state.h
AM_LDFLAGS = @CLASSPATH_MODULE@
AM_CPPFLAGS = @CLASSPATH_INCLUDES@
AM_CFLAGS = @WARNING_CFLAGS@ @STRICT_WARNING_CFLAGS@ @ERROR_CFLAGS@
@@ -0,0 +1,64 @@
/* classpath_awt.h -- libjawt's interface to the peer library
Copyright (C) 2005 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., 59 Temple Place, Suite 330, Boston, MA
02111-1307 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. */
/*
* libjawt.so is linked directly to the peer library with -l. This
* header declares all the functions that libjawt.so needs -- X-based
* peer libraries wanting to support libjawt.so must implement these
* functions.
*/
#ifndef __classpath_jawt_h__
#define __classpath_jawt_h__
#include <jni.h>
#include <X11/Xlib.h>
#define CLASSPATH_JAWT_VERSION 0x10004
jint classpath_jawt_get_awt_version ();
Display* classpath_jawt_get_default_display (JNIEnv* env, jobject canvas);
Drawable classpath_jawt_get_drawable (JNIEnv* env, jobject canvas);
VisualID classpath_jawt_get_visualID (JNIEnv* env, jobject canvas);
jint classpath_jawt_object_lock (jobject lock);
void classpath_jawt_object_unlock (jobject lock);
jint classpath_jawt_lock ();
void classpath_jawt_unlock ();
jobject classpath_jawt_create_lock ();
void classpath_jawt_destroy_lock (jobject lock);
#endif /* __classpath_jawt_h__ */
@@ -0,0 +1,180 @@
/* jcl.c
Copyright (C) 1998 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. */
/* do not move; needed here because of some macro definitions */
#include "config.h"
#include <stdlib.h>
#include <stdio.h>
#include <jcl.h>
#ifndef __GNUC__
#define __attribute__(x) /* nothing */
#endif
JNIEXPORT void JNICALL
JCL_ThrowException (JNIEnv * env, const char *className, const char *errMsg)
{
jclass excClass;
if ((*env)->ExceptionOccurred (env))
{
(*env)->ExceptionClear (env);
}
excClass = (*env)->FindClass (env, className);
if (excClass == NULL)
{
jclass errExcClass;
errExcClass =
(*env)->FindClass (env, "java/lang/ClassNotFoundException");
if (errExcClass == NULL)
{
errExcClass = (*env)->FindClass (env, "java/lang/InternalError");
if (errExcClass == NULL)
{
fprintf (stderr, "JCL: Utterly failed to throw exeption ");
fprintf (stderr, className);
fprintf (stderr, " with message ");
fprintf (stderr, errMsg);
return;
}
}
/* Removed this (more comprehensive) error string to avoid the need for
* a static variable or allocation of a buffer for this message in this
* (unlikely) error case. --Fridi.
*
* sprintf(errstr,"JCL: Failed to throw exception %s with message %s: could not find exception class.", className, errMsg);
*/
(*env)->ThrowNew (env, errExcClass, className);
}
(*env)->ThrowNew (env, excClass, errMsg);
}
JNIEXPORT void *JNICALL
JCL_malloc (JNIEnv * env, size_t size)
{
void *mem = malloc (size);
if (mem == NULL)
{
JCL_ThrowException (env, "java/lang/OutOfMemoryError",
"malloc() failed.");
return NULL;
}
return mem;
}
JNIEXPORT void *JNICALL
JCL_realloc (JNIEnv * env, void *ptr, size_t size)
{
ptr = realloc (ptr, size);
if (ptr == 0)
{
JCL_ThrowException (env, "java/lang/OutOfMemoryError",
"malloc() failed.");
return NULL;
}
return (ptr);
}
JNIEXPORT void JNICALL
JCL_free (JNIEnv * env __attribute__ ((unused)), void *p)
{
if (p != NULL)
{
free (p);
}
}
JNIEXPORT const char *JNICALL
JCL_jstring_to_cstring (JNIEnv * env, jstring s)
{
const char *cstr;
if (s == NULL)
{
JCL_ThrowException (env, "java/lang/NullPointerException",
"Null string");
return NULL;
}
cstr = (const char *) (*env)->GetStringUTFChars (env, s, NULL);
if (cstr == NULL)
{
JCL_ThrowException (env, "java/lang/InternalError",
"GetStringUTFChars() failed.");
return NULL;
}
return cstr;
}
JNIEXPORT void JNICALL
JCL_free_cstring (JNIEnv * env, jstring s, const char *cstr)
{
(*env)->ReleaseStringUTFChars (env, s, cstr);
}
JNIEXPORT jint JNICALL
JCL_MonitorEnter (JNIEnv * env, jobject o)
{
jint retval = (*env)->MonitorEnter (env, o);
if (retval != 0)
{
JCL_ThrowException (env, "java/lang/InternalError",
"MonitorEnter() failed.");
}
return retval;
}
JNIEXPORT jint JNICALL
JCL_MonitorExit (JNIEnv * env, jobject o)
{
jint retval = (*env)->MonitorExit (env, o);
if (retval != 0)
{
JCL_ThrowException (env, "java/lang/InternalError",
"MonitorExit() failed.");
}
return retval;
}
JNIEXPORT jclass JNICALL
JCL_FindClass (JNIEnv * env, const char *className)
{
jclass retval = (*env)->FindClass (env, className);
if (retval == NULL)
{
JCL_ThrowException (env, "java/lang/ClassNotFoundException", className);
}
return retval;
}
@@ -0,0 +1,68 @@
/* jcl.h
Copyright (C) 1998 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 __JCL_H__
#define __JCL_H__
#include <stddef.h>
#include <jni.h>
#include <config.h>
JNIEXPORT jclass JNICALL JCL_FindClass (JNIEnv * env, const char *className);
JNIEXPORT void JNICALL JCL_ThrowException (JNIEnv * env,
const char *className,
const char *errMsg);
JNIEXPORT void *JNICALL JCL_malloc (JNIEnv * env, size_t size);
JNIEXPORT void *JNICALL JCL_realloc (JNIEnv * env, void *ptr, size_t size);
JNIEXPORT void JNICALL JCL_free (JNIEnv * env, void *p);
JNIEXPORT const char *JNICALL JCL_jstring_to_cstring (JNIEnv * env,
jstring s);
JNIEXPORT void JNICALL JCL_free_cstring (JNIEnv * env, jstring s,
const char *cstr);
JNIEXPORT jint JNICALL JCL_MonitorEnter (JNIEnv * env, jobject o);
JNIEXPORT jint JNICALL JCL_MonitorExit (JNIEnv * env, jobject o);
#define JCL_RETHROW_EXCEPTION(env) if((*(env))->ExceptionOccurred((env)) != NULL) return NULL;
/* Simple debug macro */
#ifdef DEBUG
#define DBG(x) fprintf(stderr, (x));
#else
#define DBG(x)
#endif
#endif
@@ -0,0 +1,125 @@
/* JNILINK 1.1: JNI version.
Copyright (C) 1998 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 <stdlib.h>
#include <string.h>
#include <jcl.h>
#include "jnilink.h"
#define GETCLASS(c) *(jclass*)(c)
JNIEXPORT jclass JNICALL
LINK_RelinkClass (JNIEnv * env, linkedClass * c, const char *name)
{
jclass found;
LINK_UnlinkClass (env, *c);
found = (*env)->FindClass (env, name);
if (found == NULL)
return NULL;
*c = JCL_malloc (env, sizeof (jclass));
if (*c == NULL)
return NULL;
GETCLASS (*c) = (*env)->NewGlobalRef (env, found);
return GETCLASS (*c);
}
JNIEXPORT jclass JNICALL
LINK_RelinkKnownClass (JNIEnv * env, linkedClass * c, jclass newClass)
{
LINK_UnlinkClass (env, *c);
*c = JCL_malloc (env, sizeof (jclass));
if (*c == NULL)
return NULL;
GETCLASS (*c) = (*env)->NewGlobalRef (env, newClass);
return newClass;
}
JNIEXPORT jmethodID JNICALL
LINK_RelinkMethod (JNIEnv * env, jmethodID * m, linkedClass c,
const char *name, const char *sig)
{
*m = (*env)->GetMethodID (env, GETCLASS (c), name, sig);
return *m;
}
JNIEXPORT jmethodID JNICALL
LINK_RelinkStaticMethod (JNIEnv * env, jmethodID * m, linkedClass c,
const char *name, const char *sig)
{
*m = (*env)->GetStaticMethodID (env, GETCLASS (c), name, sig);
return *m;
}
JNIEXPORT jfieldID JNICALL
LINK_RelinkField (JNIEnv * env, jfieldID * f, linkedClass c,
const char *name, const char *sig)
{
*f = (*env)->GetFieldID (env, GETCLASS (c), name, sig);
return *f;
}
JNIEXPORT jfieldID JNICALL
LINK_RelinkStaticField (JNIEnv * env, jfieldID * f, linkedClass c,
const char *name, const char *sig)
{
*f = (*env)->GetStaticFieldID (env, GETCLASS (c), name, sig);
return *f;
}
/* These are for when the class referencing the symbols is unloaded; it
destroys any object references
* the linker might have kept around.
*/
JNIEXPORT void JNICALL
LINK_UnlinkClass (JNIEnv * env, linkedClass * c)
{
if (*c != NULL)
{
if (GETCLASS (*c) != NULL)
(*env)->DeleteGlobalRef (env, GETCLASS (*c));
JCL_free (env, *c);
*c = NULL;
}
}
@@ -0,0 +1,82 @@
/* JNILINK 1.1: JNI version.
Copyright (C) 1998 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 __JNILINK_H__
#define __JNILINK_H__
#include <jni.h>
typedef void *linkedClass;
#define LINK_LinkClass(env,c,name) ((c)==NULL ? LINK_ReallyLinkClass((env),&(c),(name)) : (c))
#define LINK_LinkKnownClass(env,c,newClass) ((c)==NULL ? LINK_ReallyLinkKnownClass((env),&(c),(newClass)) : (c))
#define LINK_LinkMethod(env,m,c,name,sig) ((m)==NULL ? LINK_RelinkMethod((env),&(m),(c),(name),(sig)) : (m))
#define LINK_LinkStaticMethod(env,m,c,name,sig) ((m)==NULL ? LINK_RelinkStaticMethod((env),&(m),(c),(name),(sig)) : (m))
#define LINK_LinkField(env,f,c,name,sig) ((m)==NULL ? LINK_RelinkField((env),&(f),(c),(name),(sig)) : (f))
#define LINK_LinkStaticField(env,f,c,name,sig) ((m)==NULL ? LINK_RelinkStaticField((env),&(f),(c),(name),(sig)) : (f))
#define LINK_LinkConstructor(env,m,c,sig) ((m)==NULL ? LINK_RelinkMethod((env),&(m),(c),"<init>",(sig)) : (m))
JNIEXPORT jclass JNICALL
LINK_ReallyLinkClass (JNIEnv * env, linkedClass * c, const char *name);
JNIEXPORT jclass JNICALL
LINK_ReallyLinkKnownClass (JNIEnv * env, linkedClass * c, jclass newClass);
JNIEXPORT jclass JNICALL
LINK_RelinkClass (JNIEnv * env, linkedClass * c, const char *name);
JNIEXPORT jclass JNICALL
LINK_RelinkKnownClass (JNIEnv * env, linkedClass * c, jclass newClass);
JNIEXPORT jmethodID JNICALL
LINK_RelinkMethod (JNIEnv * env, jmethodID * m, linkedClass c,
const char *name, const char *sig);
JNIEXPORT jmethodID JNICALL
LINK_RelinkStaticMethod (JNIEnv * env, jmethodID * m, linkedClass c,
const char *name, const char *sig);
JNIEXPORT jfieldID JNICALL
LINK_RelinkField (JNIEnv * env, jfieldID * f, linkedClass c,
const char *name, const char *sig);
JNIEXPORT jfieldID JNICALL
LINK_RelinkStaticField (JNIEnv * env, jfieldID * f, linkedClass c,
const char *name, const char *sig);
/* These are for when the class referencing the symbols is unloaded; it
destroys any object references
* the linker might have kept around.
*/
JNIEXPORT void JNICALL LINK_UnlinkClass (JNIEnv * env, linkedClass * c);
#endif
@@ -0,0 +1,248 @@
/* Magical NSA API -- Associate a C ptr with an instance of an object
Copyright (C) 1998, 2002 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 <stdlib.h>
#include <jni.h>
#include "native_state.h"
#define DEFAULT_TABLE_SIZE 97
struct state_table *
cp_gtk_init_state_table_with_size (JNIEnv * env, jclass clazz, jint size)
{
struct state_table *table;
jfieldID hash;
jclass clazz_g;
hash = (*env)->GetFieldID (env, clazz, "native_state", "I");
if (hash == NULL)
return NULL;
clazz_g = (*env)->NewGlobalRef (env, clazz);
if (clazz_g == NULL)
return NULL;
table = (struct state_table *) malloc (sizeof (struct state_table));
table->size = size;
table->head = (struct state_node **) calloc (sizeof (struct state_node *),
table->size);
table->hash = hash;
table->clazz = clazz_g;
return table;
}
struct state_table *
cp_gtk_init_state_table (JNIEnv * env, jclass clazz)
{
return cp_gtk_init_state_table_with_size (env, clazz, DEFAULT_TABLE_SIZE);
}
static void *
remove_node (struct state_node **head, jint obj_id)
{
struct state_node *back_ptr = NULL;
struct state_node *node = *head;
while (node != NULL)
{
if (node->key == obj_id)
{
void *return_value;
if (back_ptr == NULL)
*head = node->next;
else
back_ptr->next = node->next;
return_value = node->c_state;
free (node);
return return_value;
}
back_ptr = node;
node = node->next;
}
return NULL;
}
static void *
get_node (struct state_node **head, jint obj_id)
{
struct state_node *back_ptr = NULL;
struct state_node *node = *head;
while (node != NULL)
{
if (node->key == obj_id)
{
/* Move the node we found to the front of the list. */
if (back_ptr != NULL)
{
back_ptr->next = node->next;
node->next = *head;
*head = node;
}
/* Return the match. */
return node->c_state;
}
back_ptr = node;
node = node->next;
}
return NULL;
}
static void
add_node (struct state_node **head, jint obj_id, void *state)
{
struct state_node *node = *head;
struct state_node *back_ptr = NULL;
struct state_node *new_node;
if (node != NULL)
{
while (node->next != NULL && obj_id != node->key)
{
back_ptr = node;
node = node->next;
}
if (node->key == obj_id)
{
/* If we're updating a node, move it to the front of the
list. */
if (back_ptr != NULL)
{
back_ptr->next = node->next;
node->next = *head;
*head = node;
}
node->c_state = state;
return;
}
}
new_node = (struct state_node *) malloc (sizeof (struct state_node));
new_node->key = obj_id;
new_node->c_state = state;
new_node->next = *head;
*head = new_node;
}
void
cp_gtk_set_state_oid (JNIEnv * env, jobject lock, struct state_table *table,
jint obj_id, void *state)
{
jint hash;
hash = obj_id % table->size;
(*env)->MonitorEnter (env, lock);
add_node (&table->head[hash], obj_id, state);
(*env)->MonitorExit (env, lock);
}
void *
cp_gtk_get_state_oid (JNIEnv * env, jobject lock, struct state_table *table,
jint obj_id)
{
jint hash;
void *return_value;
hash = obj_id % table->size;
(*env)->MonitorEnter (env, lock);
return_value = get_node (&table->head[hash], obj_id);
(*env)->MonitorExit (env, lock);
return return_value;
}
void *
cp_gtk_remove_state_oid (JNIEnv * env, jobject lock, struct state_table *table,
jint obj_id)
{
jint hash;
void *return_value;
hash = obj_id % table->size;
(*env)->MonitorEnter (env, lock);
return_value = remove_node (&table->head[hash], obj_id);
(*env)->MonitorExit (env, lock);
return return_value;
}
int
cp_gtk_set_state (JNIEnv * env, jobject obj, struct state_table *table, void *state)
{
jint obj_id;
obj_id = (*env)->GetIntField (env, obj, table->hash);
if ((*env)->ExceptionOccurred (env) != NULL)
return -1;
cp_gtk_set_state_oid (env, table->clazz, table, obj_id, state);
return 0;
}
void *
cp_gtk_get_state (JNIEnv * env, jobject obj, struct state_table *table)
{
jint obj_id;
obj_id = (*env)->GetIntField (env, obj, table->hash);
if ((*env)->ExceptionOccurred (env) != NULL)
return NULL;
return cp_gtk_get_state_oid (env, table->clazz, table, obj_id);
}
void *
cp_gtk_remove_state_slot (JNIEnv * env, jobject obj, struct state_table *table)
{
jint obj_id;
obj_id = (*env)->GetIntField (env, obj, table->hash);
if ((*env)->ExceptionOccurred (env) != NULL)
return NULL;
return cp_gtk_remove_state_oid (env, table->clazz, table, obj_id);
}
@@ -0,0 +1,71 @@
/* Magical NSA API -- Associate a C ptr with an instance of an object
Copyright (C) 1998 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 JCL_NATIVE_STATE
#define JCL_NATIVE_STATE
#include <jni.h>
struct state_table
{
jint size; /* number of slots, should be prime */
jfieldID hash; /* field containing System.identityHashCode(this) */
jclass clazz; /* lock aquired for reading/writing nodes */
struct state_node **head;
};
struct state_node
{
jint key;
void *c_state;
struct state_node *next;
};
struct state_table *cp_gtk_init_state_table_with_size (JNIEnv *, jclass, jint);
struct state_table *cp_gtk_init_state_table (JNIEnv *, jclass);
/* lowlevel api */
void cp_gtk_set_state_oid (JNIEnv *, jobject, struct state_table *, jint, void *);
void *cp_gtk_get_state_oid (JNIEnv *, jobject, struct state_table *, jint);
void *cp_gtk_remove_state_oid (JNIEnv *, jobject, struct state_table *, jint);
/* highlevel api */
int cp_gtk_set_state (JNIEnv *, jobject, struct state_table *, void *);
void *cp_gtk_get_state (JNIEnv *, jobject, struct state_table *);
void *cp_gtk_remove_state_slot (JNIEnv *, jobject, struct state_table *);
#endif
@@ -0,0 +1,724 @@
/* primlib.c
Copyright (C) 1998 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 <jnilink.h>
#include <primlib.h>
#include <jcl.h>
static jclass nativeWrapClass[PRIMLIB_NUMTYPES] =
{ NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL
};
static jclass nativeTypeClass[PRIMLIB_NUMTYPES] =
{ NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL
};
static jmethodID nativeWrapClassConstructor[PRIMLIB_NUMTYPES] =
{ NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL
};
static jmethodID nativeWrapClassAccessor[PRIMLIB_NUMTYPES] =
{ NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL
};
static const char *nativeWrapClassName[PRIMLIB_NUMTYPES] = {
NULL,
NULL,
"java/lang/Boolean",
"java/lang/Byte",
"java/lang/Character",
"java/lang/Short",
"java/lang/Integer",
"java/lang/Long",
"java/lang/Float",
"java/lang/Double",
"java/lang/Void",
NULL
};
static const char *nativeWrapClassConstructorSig[PRIMLIB_NUMTYPES] = {
NULL,
NULL,
"(Z)V",
"(B)V",
"(C)V",
"(S)V",
"(I)V",
"(J)V",
"(F)V",
"(D)V",
"()V",
NULL
};
static const char *nativeWrapClassAccessorName[PRIMLIB_NUMTYPES] = {
NULL,
NULL,
"booleanValue",
"byteValue",
"charValue",
"shortValue",
"intValue",
"longValue",
"floatValue",
"doubleValue",
NULL,
NULL
};
static const char *nativeWrapClassAccessorSig[PRIMLIB_NUMTYPES] = {
NULL,
NULL,
"()Z",
"()B",
"()C",
"()S",
"()I",
"()J",
"()F",
"()D",
NULL,
NULL
};
JNIEXPORT jclass JNICALL
PRIMLIB_GetNativeWrapClass (JNIEnv * env, int reflectType)
{
return LINK_LinkClass (env, nativeWrapClass[reflectType],
nativeWrapClassName[reflectType]);
}
static jclass
ActuallyGetNativeTypeClass (JNIEnv * env, int reflectType)
{
jclass wrapClass;
jfieldID typeField;
wrapClass = PRIMLIB_GetNativeWrapClass (env, reflectType);
if (wrapClass == NULL)
return NULL;
typeField =
(*env)->GetStaticFieldID (env, wrapClass, "TYPE", "Ljava/lang/Class");
if (typeField == NULL)
return NULL;
return (*env)->GetStaticObjectField (env, wrapClass, typeField);
}
JNIEXPORT jclass JNICALL
PRIMLIB_GetNativeTypeClass (JNIEnv * env, int reflectType)
{
return LINK_LinkKnownClass (env, nativeTypeClass[reflectType],
ActuallyGetNativeTypeClass (env, reflectType));
}
JNIEXPORT jmethodID JNICALL
PRIMLIB_GetNativeWrapClassConstructor (JNIEnv * env, int reflectType)
{
PRIMLIB_GetNativeWrapClass (env, reflectType);
return LINK_LinkConstructor (env, nativeWrapClassConstructor[reflectType],
nativeWrapClass[reflectType],
nativeWrapClassConstructorSig[reflectType]);
}
JNIEXPORT jmethodID JNICALL
PRIMLIB_GetNativeWrapClassAccessor (JNIEnv * env, int reflectType)
{
PRIMLIB_GetNativeWrapClass (env, reflectType);
return LINK_LinkMethod (env, nativeWrapClassAccessor[reflectType],
nativeWrapClass[reflectType],
nativeWrapClassAccessorName[reflectType],
nativeWrapClassAccessorSig[reflectType]);
}
JNIEXPORT jobject JNICALL
PRIMLIB_WrapBoolean (JNIEnv * env, jboolean b)
{
jmethodID construct =
PRIMLIB_GetNativeWrapClassConstructor (env, PRIMLIB_BOOLEAN);
JCL_RETHROW_EXCEPTION (env);
return (*env)->NewObject (env,
PRIMLIB_GetNativeWrapClass (env, PRIMLIB_BOOLEAN),
construct, b);
}
JNIEXPORT jobject JNICALL
PRIMLIB_WrapByte (JNIEnv * env, jbyte b)
{
jmethodID construct =
PRIMLIB_GetNativeWrapClassConstructor (env, PRIMLIB_BYTE);
JCL_RETHROW_EXCEPTION (env);
return (*env)->NewObject (env,
PRIMLIB_GetNativeWrapClass (env, PRIMLIB_BYTE),
construct, b);
}
JNIEXPORT jobject JNICALL
PRIMLIB_WrapChar (JNIEnv * env, jchar c)
{
jmethodID construct =
PRIMLIB_GetNativeWrapClassConstructor (env, PRIMLIB_CHAR);
JCL_RETHROW_EXCEPTION (env);
return (*env)->NewObject (env,
PRIMLIB_GetNativeWrapClass (env, PRIMLIB_CHAR),
construct, c);
}
JNIEXPORT jobject JNICALL
PRIMLIB_WrapShort (JNIEnv * env, jshort s)
{
jmethodID construct =
PRIMLIB_GetNativeWrapClassConstructor (env, PRIMLIB_SHORT);
JCL_RETHROW_EXCEPTION (env);
return (*env)->NewObject (env,
PRIMLIB_GetNativeWrapClass (env, PRIMLIB_SHORT),
construct, s);
}
JNIEXPORT jobject JNICALL
PRIMLIB_WrapInt (JNIEnv * env, jint i)
{
jmethodID construct =
PRIMLIB_GetNativeWrapClassConstructor (env, PRIMLIB_INT);
JCL_RETHROW_EXCEPTION (env);
return (*env)->NewObject (env,
PRIMLIB_GetNativeWrapClass (env, PRIMLIB_INT),
construct, i);
}
JNIEXPORT jobject JNICALL
PRIMLIB_WrapLong (JNIEnv * env, jlong l)
{
jmethodID construct =
PRIMLIB_GetNativeWrapClassConstructor (env, PRIMLIB_LONG);
JCL_RETHROW_EXCEPTION (env);
return (*env)->NewObject (env,
PRIMLIB_GetNativeWrapClass (env, PRIMLIB_LONG),
construct, l);
}
JNIEXPORT jobject JNICALL
PRIMLIB_WrapFloat (JNIEnv * env, jfloat f)
{
jmethodID construct =
PRIMLIB_GetNativeWrapClassConstructor (env, PRIMLIB_FLOAT);
JCL_RETHROW_EXCEPTION (env);
return (*env)->NewObject (env,
PRIMLIB_GetNativeWrapClass (env, PRIMLIB_FLOAT),
construct, f);
}
JNIEXPORT jobject JNICALL
PRIMLIB_WrapDouble (JNIEnv * env, jdouble d)
{
jmethodID construct =
PRIMLIB_GetNativeWrapClassConstructor (env, PRIMLIB_DOUBLE);
JCL_RETHROW_EXCEPTION (env);
return (*env)->NewObject (env,
PRIMLIB_GetNativeWrapClass (env, PRIMLIB_DOUBLE),
construct, d);
}
JNIEXPORT jboolean JNICALL
PRIMLIB_UnwrapBoolean (JNIEnv * env, jobject obj)
{
if ((*env)->
IsInstanceOf (env, obj,
PRIMLIB_GetNativeWrapClass (env, PRIMLIB_BOOLEAN)))
{
return PRIMLIB_GetBooleanObjectValue (env, obj);
}
else
{
JCL_ThrowException (env, "java/lang/IllegalArgumentException",
"Argument not of correct type.");
return JNI_FALSE;
}
}
JNIEXPORT jbyte JNICALL
PRIMLIB_UnwrapByte (JNIEnv * env, jobject obj)
{
if ((*env)->
IsInstanceOf (env, obj, PRIMLIB_GetNativeWrapClass (env, PRIMLIB_BYTE)))
{
return PRIMLIB_GetByteObjectValue (env, obj);
}
else
{
JCL_ThrowException (env, "java/lang/IllegalArgumentException",
"Argument not of correct type.");
return 0;
}
}
JNIEXPORT jshort JNICALL
PRIMLIB_UnwrapShort (JNIEnv * env, jobject obj)
{
if ((*env)->
IsInstanceOf (env, obj,
PRIMLIB_GetNativeWrapClass (env, PRIMLIB_SHORT)))
{
return PRIMLIB_GetShortObjectValue (env, obj);
}
else if ((*env)->
IsInstanceOf (env, obj,
PRIMLIB_GetNativeWrapClass (env, PRIMLIB_BYTE)))
{
return (jshort) PRIMLIB_GetByteObjectValue (env, obj);
}
else
{
JCL_ThrowException (env, "java/lang/IllegalArgumentException",
"Argument not of correct type.");
return 0;
}
}
JNIEXPORT jchar JNICALL
PRIMLIB_UnwrapChar (JNIEnv * env, jobject obj)
{
if ((*env)->
IsInstanceOf (env, obj, PRIMLIB_GetNativeWrapClass (env, PRIMLIB_CHAR)))
{
return PRIMLIB_GetCharObjectValue (env, obj);
}
else
{
JCL_ThrowException (env, "java/lang/IllegalArgumentException",
"Argument not of correct type.");
return 0;
}
}
JNIEXPORT jint JNICALL
PRIMLIB_UnwrapInt (JNIEnv * env, jobject obj)
{
if ((*env)->
IsInstanceOf (env, obj, PRIMLIB_GetNativeWrapClass (env, PRIMLIB_INT)))
{
return PRIMLIB_GetIntObjectValue (env, obj);
}
else if ((*env)->
IsInstanceOf (env, obj,
PRIMLIB_GetNativeWrapClass (env, PRIMLIB_SHORT)))
{
return (jint) PRIMLIB_GetShortObjectValue (env, obj);
}
else if ((*env)->
IsInstanceOf (env, obj,
PRIMLIB_GetNativeWrapClass (env, PRIMLIB_CHAR)))
{
return (jint) PRIMLIB_GetCharObjectValue (env, obj);
}
else if ((*env)->
IsInstanceOf (env, obj,
PRIMLIB_GetNativeWrapClass (env, PRIMLIB_BYTE)))
{
return (jint) PRIMLIB_GetByteObjectValue (env, obj);
}
else
{
JCL_ThrowException (env, "java/lang/IllegalArgumentException",
"Argument not of correct type.");
return 0;
}
}
JNIEXPORT jlong JNICALL
PRIMLIB_UnwrapLong (JNIEnv * env, jobject obj)
{
if ((*env)->
IsInstanceOf (env, obj, PRIMLIB_GetNativeWrapClass (env, PRIMLIB_LONG)))
{
return PRIMLIB_GetLongObjectValue (env, obj);
}
else if ((*env)->
IsInstanceOf (env, obj,
PRIMLIB_GetNativeWrapClass (env, PRIMLIB_INT)))
{
return (jlong) PRIMLIB_GetIntObjectValue (env, obj);
}
else if ((*env)->
IsInstanceOf (env, obj,
PRIMLIB_GetNativeWrapClass (env, PRIMLIB_SHORT)))
{
return (jlong) PRIMLIB_GetShortObjectValue (env, obj);
}
else if ((*env)->
IsInstanceOf (env, obj,
PRIMLIB_GetNativeWrapClass (env, PRIMLIB_CHAR)))
{
return (jlong) PRIMLIB_GetCharObjectValue (env, obj);
}
else if ((*env)->
IsInstanceOf (env, obj,
PRIMLIB_GetNativeWrapClass (env, PRIMLIB_BYTE)))
{
return (jlong) PRIMLIB_GetByteObjectValue (env, obj);
}
else
{
JCL_ThrowException (env, "java/lang/IllegalArgumentException",
"Argument not of correct type.");
return 0;
}
}
JNIEXPORT jfloat JNICALL
PRIMLIB_UnwrapFloat (JNIEnv * env, jobject obj)
{
if ((*env)->
IsInstanceOf (env, obj,
PRIMLIB_GetNativeWrapClass (env, PRIMLIB_FLOAT)))
{
return PRIMLIB_GetFloatObjectValue (env, obj);
}
else if ((*env)->
IsInstanceOf (env, obj,
PRIMLIB_GetNativeWrapClass (env, PRIMLIB_LONG)))
{
return (jfloat) PRIMLIB_GetLongObjectValue (env, obj);
}
else if ((*env)->
IsInstanceOf (env, obj,
PRIMLIB_GetNativeWrapClass (env, PRIMLIB_INT)))
{
return (jfloat) PRIMLIB_GetIntObjectValue (env, obj);
}
else if ((*env)->
IsInstanceOf (env, obj,
PRIMLIB_GetNativeWrapClass (env, PRIMLIB_SHORT)))
{
return (jfloat) PRIMLIB_GetShortObjectValue (env, obj);
}
else if ((*env)->
IsInstanceOf (env, obj,
PRIMLIB_GetNativeWrapClass (env, PRIMLIB_CHAR)))
{
return (jfloat) PRIMLIB_GetCharObjectValue (env, obj);
}
else if ((*env)->
IsInstanceOf (env, obj,
PRIMLIB_GetNativeWrapClass (env, PRIMLIB_BYTE)))
{
return (jfloat) PRIMLIB_GetByteObjectValue (env, obj);
}
else
{
JCL_ThrowException (env, "java/lang/IllegalArgumentException",
"Argument not of correct type.");
return 0;
}
}
JNIEXPORT jdouble JNICALL
PRIMLIB_UnwrapDouble (JNIEnv * env, jobject obj)
{
if ((*env)->
IsInstanceOf (env, obj,
PRIMLIB_GetNativeWrapClass (env, PRIMLIB_DOUBLE)))
{
return PRIMLIB_GetDoubleObjectValue (env, obj);
}
else if ((*env)->
IsInstanceOf (env, obj,
PRIMLIB_GetNativeWrapClass (env, PRIMLIB_FLOAT)))
{
return (jdouble) PRIMLIB_GetFloatObjectValue (env, obj);
}
else if ((*env)->
IsInstanceOf (env, obj,
PRIMLIB_GetNativeWrapClass (env, PRIMLIB_LONG)))
{
return (jdouble) PRIMLIB_GetLongObjectValue (env, obj);
}
else if ((*env)->
IsInstanceOf (env, obj,
PRIMLIB_GetNativeWrapClass (env, PRIMLIB_INT)))
{
return (jdouble) PRIMLIB_GetIntObjectValue (env, obj);
}
else if ((*env)->
IsInstanceOf (env, obj,
PRIMLIB_GetNativeWrapClass (env, PRIMLIB_SHORT)))
{
return (jdouble) PRIMLIB_GetShortObjectValue (env, obj);
}
else if ((*env)->
IsInstanceOf (env, obj,
PRIMLIB_GetNativeWrapClass (env, PRIMLIB_CHAR)))
{
return (jdouble) PRIMLIB_GetCharObjectValue (env, obj);
}
else if ((*env)->
IsInstanceOf (env, obj,
PRIMLIB_GetNativeWrapClass (env, PRIMLIB_BYTE)))
{
return (jdouble) PRIMLIB_GetByteObjectValue (env, obj);
}
else
{
JCL_ThrowException (env, "java/lang/IllegalArgumentException",
"Argument not of correct type.");
return 0;
}
}
JNIEXPORT jint JNICALL
PRIMLIB_GetReflectiveWrapperType (JNIEnv * env, jobject obj)
{
jclass typeClass;
if (obj == NULL)
{
return PRIMLIB_NULL;
}
typeClass = PRIMLIB_GetNativeWrapClass (env, PRIMLIB_DOUBLE);
if ((*env)->IsInstanceOf (env, obj, typeClass))
{
return PRIMLIB_DOUBLE;
}
typeClass = PRIMLIB_GetNativeWrapClass (env, PRIMLIB_FLOAT);
if ((*env)->IsInstanceOf (env, obj, typeClass))
{
return PRIMLIB_FLOAT;
}
typeClass = PRIMLIB_GetNativeWrapClass (env, PRIMLIB_LONG);
if ((*env)->IsInstanceOf (env, obj, typeClass))
{
return PRIMLIB_LONG;
}
typeClass = PRIMLIB_GetNativeWrapClass (env, PRIMLIB_INT);
if ((*env)->IsInstanceOf (env, obj, typeClass))
{
return PRIMLIB_INT;
}
typeClass = PRIMLIB_GetNativeWrapClass (env, PRIMLIB_CHAR);
if ((*env)->IsInstanceOf (env, obj, typeClass))
{
return PRIMLIB_CHAR;
}
typeClass = PRIMLIB_GetNativeWrapClass (env, PRIMLIB_SHORT);
if ((*env)->IsInstanceOf (env, obj, typeClass))
{
return PRIMLIB_SHORT;
}
typeClass = PRIMLIB_GetNativeWrapClass (env, PRIMLIB_BYTE);
if ((*env)->IsInstanceOf (env, obj, typeClass))
{
return PRIMLIB_BYTE;
}
typeClass = PRIMLIB_GetNativeWrapClass (env, PRIMLIB_BOOLEAN);
if ((*env)->IsInstanceOf (env, obj, typeClass))
{
return PRIMLIB_BOOLEAN;
}
typeClass = PRIMLIB_GetNativeWrapClass (env, PRIMLIB_VOID);
if ((*env)->IsInstanceOf (env, obj, typeClass))
{
return PRIMLIB_VOID;
}
return PRIMLIB_OBJECT;
}
JNIEXPORT jint JNICALL
PRIMLIB_GetReflectiveType (JNIEnv * env, jclass returnType)
{
jclass typeClass = PRIMLIB_GetNativeTypeClass (env, PRIMLIB_DOUBLE);
if ((*env)->IsAssignableFrom (env, returnType, typeClass))
{
return PRIMLIB_DOUBLE;
}
typeClass = PRIMLIB_GetNativeTypeClass (env, PRIMLIB_FLOAT);
if ((*env)->IsAssignableFrom (env, returnType, typeClass))
{
return PRIMLIB_FLOAT;
}
typeClass = PRIMLIB_GetNativeTypeClass (env, PRIMLIB_LONG);
if ((*env)->IsAssignableFrom (env, returnType, typeClass))
{
return PRIMLIB_LONG;
}
typeClass = PRIMLIB_GetNativeTypeClass (env, PRIMLIB_INT);
if ((*env)->IsAssignableFrom (env, returnType, typeClass))
{
return PRIMLIB_INT;
}
typeClass = PRIMLIB_GetNativeTypeClass (env, PRIMLIB_CHAR);
if ((*env)->IsAssignableFrom (env, returnType, typeClass))
{
return PRIMLIB_CHAR;
}
typeClass = PRIMLIB_GetNativeTypeClass (env, PRIMLIB_SHORT);
if ((*env)->IsAssignableFrom (env, returnType, typeClass))
{
return PRIMLIB_SHORT;
}
typeClass = PRIMLIB_GetNativeTypeClass (env, PRIMLIB_BYTE);
if ((*env)->IsAssignableFrom (env, returnType, typeClass))
{
return PRIMLIB_BYTE;
}
typeClass = PRIMLIB_GetNativeTypeClass (env, PRIMLIB_BOOLEAN);
if ((*env)->IsAssignableFrom (env, returnType, typeClass))
{
return PRIMLIB_BOOLEAN;
}
typeClass = PRIMLIB_GetNativeTypeClass (env, PRIMLIB_VOID);
if ((*env)->IsAssignableFrom (env, returnType, typeClass))
{
return PRIMLIB_VOID;
}
return PRIMLIB_OBJECT;
}
JNIEXPORT jboolean JNICALL
PRIMLIB_GetBooleanObjectValue (JNIEnv * env, jobject obj)
{
jmethodID acc = PRIMLIB_GetNativeWrapClassAccessor (env, PRIMLIB_BOOLEAN);
return (*env)->CallBooleanMethod (env, obj, acc);
}
JNIEXPORT jbyte JNICALL
PRIMLIB_GetByteObjectValue (JNIEnv * env, jobject obj)
{
jmethodID acc = PRIMLIB_GetNativeWrapClassAccessor (env, PRIMLIB_BYTE);
return (*env)->CallByteMethod (env, obj, acc);
}
JNIEXPORT jshort JNICALL
PRIMLIB_GetShortObjectValue (JNIEnv * env, jobject obj)
{
jmethodID acc = PRIMLIB_GetNativeWrapClassAccessor (env, PRIMLIB_SHORT);
return (*env)->CallShortMethod (env, obj, acc);
}
JNIEXPORT jchar JNICALL
PRIMLIB_GetCharObjectValue (JNIEnv * env, jobject obj)
{
jmethodID acc = PRIMLIB_GetNativeWrapClassAccessor (env, PRIMLIB_CHAR);
return (*env)->CallCharMethod (env, obj, acc);
}
JNIEXPORT jint JNICALL
PRIMLIB_GetIntObjectValue (JNIEnv * env, jobject obj)
{
jmethodID acc = PRIMLIB_GetNativeWrapClassAccessor (env, PRIMLIB_INT);
return (*env)->CallIntMethod (env, obj, acc);
}
JNIEXPORT jlong JNICALL
PRIMLIB_GetLongObjectValue (JNIEnv * env, jobject obj)
{
jmethodID acc = PRIMLIB_GetNativeWrapClassAccessor (env, PRIMLIB_LONG);
return (*env)->CallLongMethod (env, obj, acc);
}
JNIEXPORT jfloat JNICALL
PRIMLIB_GetFloatObjectValue (JNIEnv * env, jobject obj)
{
jmethodID acc = PRIMLIB_GetNativeWrapClassAccessor (env, PRIMLIB_FLOAT);
return (*env)->CallFloatMethod (env, obj, acc);
}
JNIEXPORT jdouble JNICALL
PRIMLIB_GetDoubleObjectValue (JNIEnv * env, jobject obj)
{
jmethodID acc = PRIMLIB_GetNativeWrapClassAccessor (env, PRIMLIB_DOUBLE);
return (*env)->CallDoubleMethod (env, obj, acc);
}
JNIEXPORT jvalue JNICALL
PRIMLIB_UnwrapJValue (JNIEnv * env, jobject obj, jclass classType)
{
jvalue retval;
jint objType = PRIMLIB_GetReflectiveType (env, classType);
if (objType == PRIMLIB_BOOLEAN)
{
retval.z = PRIMLIB_UnwrapBoolean (env, obj);
}
else if (objType == PRIMLIB_BYTE)
{
retval.b = PRIMLIB_UnwrapByte (env, obj);
}
else if (objType == PRIMLIB_CHAR)
{
retval.c = PRIMLIB_UnwrapChar (env, obj);
}
else if (objType == PRIMLIB_SHORT)
{
retval.s = PRIMLIB_UnwrapShort (env, obj);
}
else if (objType == PRIMLIB_INT)
{
retval.i = PRIMLIB_UnwrapInt (env, obj);
}
else if (objType == PRIMLIB_LONG)
{
retval.j = PRIMLIB_UnwrapLong (env, obj);
}
else if (objType == PRIMLIB_FLOAT)
{
retval.f = PRIMLIB_UnwrapFloat (env, obj);
}
else if (objType == PRIMLIB_DOUBLE)
{
retval.d = PRIMLIB_UnwrapDouble (env, obj);
}
else
{
if (obj != NULL && !(*env)->IsInstanceOf (env, obj, classType))
{
JCL_ThrowException (env, "java/lang/IllegalArgumentException",
"Argument not of correct object type.");
return retval;
}
retval.l = obj;
}
return retval;
}
@@ -0,0 +1,119 @@
/* primlib.h
Copyright (C) 1998 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 __PRIMLIB_H__
#define __PRIMLIB_H__
#include <jni.h>
#define PRIMLIB_UNKNOWN 0
#define PRIMLIB_OBJECT 1
#define PRIMLIB_BOOLEAN 2
#define PRIMLIB_BYTE 3
#define PRIMLIB_CHAR 4
#define PRIMLIB_SHORT 5
#define PRIMLIB_INT 6
#define PRIMLIB_LONG 7
#define PRIMLIB_FLOAT 8
#define PRIMLIB_DOUBLE 9
#define PRIMLIB_VOID 10
#define PRIMLIB_NULL 11
#define PRIMLIB_NUMTYPES 12
/* Low-level primitive class accessor functions. */
JNIEXPORT jclass JNICALL PRIMLIB_GetNativeWrapClass (JNIEnv * env,
int reflectType);
JNIEXPORT jclass JNICALL PRIMLIB_GetNativeTypeClass (JNIEnv * env,
int reflectType);
JNIEXPORT jmethodID JNICALL PRIMLIB_GetNativeWrapClassConstructor (JNIEnv *
env,
int
reflectType);
JNIEXPORT jmethodID JNICALL PRIMLIB_GetNativeWrapClassAccessor (JNIEnv * env,
int
reflectType);
/* Type discovery functions: WrapperType finds out j.l.Boolean/Byte/etc., and
Type finds out j.l.Boolean.TYPE, etc.
*/
JNIEXPORT jint JNICALL PRIMLIB_GetReflectiveWrapperType (JNIEnv * env,
jobject obj);
JNIEXPORT jint JNICALL PRIMLIB_GetReflectiveType (JNIEnv * env,
jclass returnType);
/* Constructor functions. */
JNIEXPORT jobject JNICALL PRIMLIB_WrapBoolean (JNIEnv * env, jboolean b);
JNIEXPORT jobject JNICALL PRIMLIB_WrapByte (JNIEnv * env, jbyte b);
JNIEXPORT jobject JNICALL PRIMLIB_WrapChar (JNIEnv * env, jchar c);
JNIEXPORT jobject JNICALL PRIMLIB_WrapShort (JNIEnv * env, jshort s);
JNIEXPORT jobject JNICALL PRIMLIB_WrapInt (JNIEnv * env, jint i);
JNIEXPORT jobject JNICALL PRIMLIB_WrapLong (JNIEnv * env, jlong l);
JNIEXPORT jobject JNICALL PRIMLIB_WrapFloat (JNIEnv * env, jfloat f);
JNIEXPORT jobject JNICALL PRIMLIB_WrapDouble (JNIEnv * env, jdouble d);
/* Widening conversion unwrapping functions. */
JNIEXPORT jboolean JNICALL PRIMLIB_UnwrapBoolean (JNIEnv * env, jobject obj);
JNIEXPORT jbyte JNICALL PRIMLIB_UnwrapByte (JNIEnv * env, jobject obj);
JNIEXPORT jshort JNICALL PRIMLIB_UnwrapShort (JNIEnv * env, jobject obj);
JNIEXPORT jchar JNICALL PRIMLIB_UnwrapChar (JNIEnv * env, jobject obj);
JNIEXPORT jint JNICALL PRIMLIB_UnwrapInt (JNIEnv * env, jobject obj);
JNIEXPORT jlong JNICALL PRIMLIB_UnwrapLong (JNIEnv * env, jobject obj);
JNIEXPORT jfloat JNICALL PRIMLIB_UnwrapFloat (JNIEnv * env, jobject obj);
JNIEXPORT jdouble JNICALL PRIMLIB_UnwrapDouble (JNIEnv * env, jobject obj);
/* Simple unwrapping functions. Objects *must* be of correct type. */
JNIEXPORT jboolean JNICALL PRIMLIB_GetBooleanObjectValue (JNIEnv * env,
jobject obj);
JNIEXPORT jbyte JNICALL PRIMLIB_GetByteObjectValue (JNIEnv * env,
jobject obj);
JNIEXPORT jshort JNICALL PRIMLIB_GetShortObjectValue (JNIEnv * env,
jobject obj);
JNIEXPORT jchar JNICALL PRIMLIB_GetCharObjectValue (JNIEnv * env,
jobject obj);
JNIEXPORT jint JNICALL PRIMLIB_GetIntObjectValue (JNIEnv * env, jobject obj);
JNIEXPORT jlong JNICALL PRIMLIB_GetLongObjectValue (JNIEnv * env,
jobject obj);
JNIEXPORT jfloat JNICALL PRIMLIB_GetFloatObjectValue (JNIEnv * env,
jobject obj);
JNIEXPORT jdouble JNICALL PRIMLIB_GetDoubleObjectValue (JNIEnv * env,
jobject obj);
/* jvalue conversion: Unwrap obj to the type of classType, with widening conversion. */
JNIEXPORT jvalue JNICALL PRIMLIB_UnwrapJValue (JNIEnv * env, jobject obj,
jclass classType);
#endif
@@ -0,0 +1,8 @@
*.o
*.a
*.lo
*.la
.libs
.deps
Makefile
Makefile.in
@@ -0,0 +1,61 @@
pkglib_LTLIBRARIES = libgtkpeer.la
# Gtk/Cairo JNI sources.
if GTK_CAIRO
gtk_cairo_c_source_files = \
gnu_java_awt_peer_gtk_GdkGraphics2D.c
else
gtk_cairo_c_source_files =
endif
libgtkpeer_la_SOURCES = $(gtk_cairo_c_source_files) \
gnu_java_awt_peer_gtk_GThreadNativeMethodRunner.c \
gnu_java_awt_peer_gtk_GdkFontPeer.c \
gnu_java_awt_peer_gtk_GdkGraphics.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_GdkTextLayout.c \
gnu_java_awt_peer_gtk_GtkButtonPeer.c \
gnu_java_awt_peer_gtk_GtkCanvasPeer.c \
gnu_java_awt_peer_gtk_GtkCheckboxGroupPeer.c \
gnu_java_awt_peer_gtk_GtkCheckboxMenuItemPeer.c \
gnu_java_awt_peer_gtk_GtkCheckboxPeer.c \
gnu_java_awt_peer_gtk_GtkChoicePeer.c \
gnu_java_awt_peer_gtk_GtkClipboard.c \
gnu_java_awt_peer_gtk_GtkComponentPeer.c \
gnu_java_awt_peer_gtk_GtkEmbeddedWindowPeer.c \
gnu_java_awt_peer_gtk_GtkFileDialogPeer.c \
gnu_java_awt_peer_gtk_GtkFramePeer.c \
gnu_java_awt_peer_gtk_GtkGenericPeer.c \
gnu_java_awt_peer_gtk_GtkImage.c \
gnu_java_awt_peer_gtk_GtkLabelPeer.c \
gnu_java_awt_peer_gtk_GtkListPeer.c \
gnu_java_awt_peer_gtk_GtkMenuBarPeer.c \
gnu_java_awt_peer_gtk_GtkMenuComponentPeer.c \
gnu_java_awt_peer_gtk_GtkMenuItemPeer.c \
gnu_java_awt_peer_gtk_GtkMenuPeer.c \
gnu_java_awt_peer_gtk_GtkPanelPeer.c \
gnu_java_awt_peer_gtk_GtkPopupMenuPeer.c \
gnu_java_awt_peer_gtk_GtkScrollbarPeer.c \
gnu_java_awt_peer_gtk_GtkScrollPanePeer.c \
gnu_java_awt_peer_gtk_GtkTextAreaPeer.c \
gnu_java_awt_peer_gtk_GtkTextFieldPeer.c \
gnu_java_awt_peer_gtk_GtkToolkit.c \
gnu_java_awt_peer_gtk_GtkWindowPeer.c \
gthread-jni.c \
gdkfont.h \
gthread-jni.h \
gtkcairopeer.h \
gtkpeer.h
libgtkpeer_la_LIBADD = $(top_builddir)/native/jni/classpath/native_state.lo \
$(top_builddir)/native/jni/classpath/jcl.lo
AM_LDFLAGS = @CLASSPATH_MODULE@ @GTK_LIBS@ @CAIRO_LIBS@ @PANGOFT2_LIBS@ @X_LIBS@ -lXtst
AM_CPPFLAGS = @CLASSPATH_INCLUDES@
# Just the WARNING_CFLAGS. We cannot use the strict flags since the gtk
# headers contain broken prototypes (by design, see gtkitemfactory.h).
AM_CFLAGS = @WARNING_CFLAGS@ @ERROR_CFLAGS@ \
@GTK_CFLAGS@ @CAIRO_CFLAGS@ @PANGOFT2_CFLAGS@
@@ -0,0 +1,142 @@
#ifndef __GDKFONT_H__
#define __GDKFONT_H__
/* gdkfont.h -- Some global stuff related to fonts and glyphs
Copyright (C) 2003 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"
#include <pango/pango.h>
#include <pango/pango-context.h>
#include <pango/pango-fontmap.h>
#include <pango/pangoft2.h>
extern struct state_table *cp_gtk_native_font_state_table;
extern struct state_table *native_glyphvector_state_table;
extern struct state_table *cp_gtk_native_text_layout_state_table;
#define NSA_FONT_INIT(env, clazz) \
cp_gtk_native_font_state_table = cp_gtk_init_state_table (env, clazz)
#define NSA_GET_FONT_PTR(env, obj) \
cp_gtk_get_state (env, obj, cp_gtk_native_font_state_table)
#define NSA_SET_FONT_PTR(env, obj, ptr) \
cp_gtk_set_state (env, obj, cp_gtk_native_font_state_table, (void *)ptr)
#define NSA_DEL_FONT_PTR(env, obj) \
cp_gtk_remove_state_slot (env, obj, cp_gtk_native_font_state_table)
#define NSA_GV_INIT(env, clazz) \
native_glyphvector_state_table = cp_gtk_init_state_table (env, clazz)
#define NSA_GET_GV_PTR(env, obj) \
cp_gtk_get_state (env, obj, native_glyphvector_state_table)
#define NSA_SET_GV_PTR(env, obj, ptr) \
cp_gtk_set_state (env, obj, native_glyphvector_state_table, (void *)ptr)
#define NSA_DEL_GV_PTR(env, obj) \
cp_gtk_remove_state_slot (env, obj, native_glyphvector_state_table)
#define NSA_TEXT_LAYOUT_INIT(env, clazz) \
cp_gtk_native_text_layout_state_table = cp_gtk_init_state_table (env, clazz)
#define NSA_GET_TEXT_LAYOUT_PTR(env, obj) \
cp_gtk_get_state (env, obj, cp_gtk_native_text_layout_state_table)
#define NSA_SET_TEXT_LAYOUT_PTR(env, obj, ptr) \
cp_gtk_set_state (env, obj, cp_gtk_native_text_layout_state_table, (void *)ptr)
#define NSA_DEL_TEXT_LAYOUT_PTR(env, obj) \
cp_gtk_remove_state_slot (env, obj, cp_gtk_native_text_layout_state_table)
#define FONT_METRICS_ASCENT 0
#define FONT_METRICS_MAX_ASCENT 1
#define FONT_METRICS_DESCENT 2
#define FONT_METRICS_MAX_DESCENT 3
#define FONT_METRICS_MAX_ADVANCE 4
#define NUM_FONT_METRICS 5
#define TEXT_METRICS_X_BEARING 0
#define TEXT_METRICS_Y_BEARING 1
#define TEXT_METRICS_WIDTH 2
#define TEXT_METRICS_HEIGHT 3
#define TEXT_METRICS_X_ADVANCE 4
#define TEXT_METRICS_Y_ADVANCE 5
#define NUM_TEXT_METRICS 6
#define NUM_GLYPH_METRICS 10
#define GLYPH_LOG_X(i) (NUM_GLYPH_METRICS * (i) )
#define GLYPH_LOG_Y(i) (NUM_GLYPH_METRICS * (i) + 1)
#define GLYPH_LOG_WIDTH(i) (NUM_GLYPH_METRICS * (i) + 2)
#define GLYPH_LOG_HEIGHT(i) (NUM_GLYPH_METRICS * (i) + 3)
#define GLYPH_INK_X(i) (NUM_GLYPH_METRICS * (i) + 4)
#define GLYPH_INK_Y(i) (NUM_GLYPH_METRICS * (i) + 5)
#define GLYPH_INK_WIDTH(i) (NUM_GLYPH_METRICS * (i) + 6)
#define GLYPH_INK_HEIGHT(i) (NUM_GLYPH_METRICS * (i) + 7)
#define GLYPH_POS_X(i) (NUM_GLYPH_METRICS * (i) + 8)
#define GLYPH_POS_Y(i) (NUM_GLYPH_METRICS * (i) + 9)
struct peerfont
{
PangoFont *font;
PangoFontDescription *desc;
PangoContext *ctx;
PangoLayout *layout;
/*
* The GdkGraphics2D (using cairo) may store a pointer to a
* cairo_font_t here; since we want to work equally well with
* the GdkGraphics class (using GDK) we do not explicitly mention
* cairo types here; it is up to the higher level driver routine
* in GdkClasspathFontPeer.java to decide which backend functions
* to invoke.
*/
void *graphics_resource;
};
struct textlayout
{
PangoLayout *pango_layout;
};
#endif /* __GDKFONT_H__ */
@@ -0,0 +1,70 @@
/* Native implementation of functions in GThreadNativeMethodRunner
Copyright (C) 2004 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 "gnu_java_awt_peer_gtk_GThreadNativeMethodRunner.h"
#include "gthread-jni.h"
/*
* Class: GThreadNativeMethodRunner
* Method: nativeRun
* Signature: (J)V
*
* Purpose: Run the C function whose function pointer is
*
*/
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GThreadNativeMethodRunner_nativeRun
(JNIEnv *env __attribute__((unused)),
jobject lcl_obj __attribute__((unused)),
jlong funcAddr, jlong funcArg)
{
/* Convert the function's address back into a pointer to a C function. */
void *(*funcPtr)(void *) = (void *(*)(void *)) (size_t)funcAddr;
/* We do not need to worry about the return value from funcPtr(); it's
just thrown away. That is part of the g_threads spec, so no reason
to worry about returning it. */
(void) funcPtr((void *) (size_t)funcArg);
/* Fall off the end and terminate the thread of control. */
}
/* Local Variables: */
/* c-file-style: "gnu" */
/* End: */
@@ -0,0 +1,418 @@
/* gnu_java_awt_GdkFont.c
Copyright (C) 2003, 2004 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 "gdkfont.h"
#include "gnu_java_awt_peer_gtk_GdkFontPeer.h"
struct state_table *cp_gtk_native_font_state_table;
enum java_awt_font_style {
java_awt_font_PLAIN = 0,
java_awt_font_BOLD = 1,
java_awt_font_ITALIC = 2
};
enum java_awt_font_baseline {
java_awt_font_ROMAN_BASELINE = 0,
java_awt_font_CENTER_BASELINE = 1,
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_ctor = (*env)->GetMethodID
(env, glyphVector_class, "<init>",
"([D[ILjava/awt/Font;Ljava/awt/font/FontRenderContext;)V");
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkFontPeer_initState
(JNIEnv *env, jobject self)
{
struct peerfont *pfont = NULL;
gdk_threads_enter ();
g_assert (self != NULL);
pfont = (struct peerfont *) g_malloc0 (sizeof (struct peerfont));
g_assert (pfont != NULL);
NSA_SET_FONT_PTR (env, self, pfont);
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkFontPeer_dispose
(JNIEnv *env, jobject self)
{
struct peerfont *pfont = NULL;
gdk_threads_enter ();
pfont = (struct peerfont *)NSA_DEL_FONT_PTR (env, self);
g_assert (pfont != NULL);
if (pfont->layout != NULL)
g_object_unref (pfont->font);
if (pfont->font != NULL)
g_object_unref (pfont->font);
if (pfont->ctx != NULL)
g_object_unref (pfont->ctx);
if (pfont->desc != NULL)
pango_font_description_free (pfont->desc);
g_free (pfont);
gdk_threads_leave ();
}
JNIEXPORT jobject JNICALL
Java_gnu_java_awt_peer_gtk_GdkFontPeer_getGlyphVector
(JNIEnv *env, jobject self,
jstring chars,
jobject font,
jobject fontRenderContext)
{
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 ();
pfont = (struct peerfont *)NSA_GET_FONT_PTR (env, self);
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)
{
gdk_threads_leave ();
java_extents = (*env)->NewDoubleArray (env, 0);
java_codes = (*env)->NewIntArray (env, 0);
gdk_threads_enter ();
}
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);
gdk_threads_leave ();
java_extents = (*env)->NewDoubleArray (env, glyphs->num_glyphs * NUM_GLYPH_METRICS);
java_codes = (*env)->NewIntArray (env, glyphs->num_glyphs);
gdk_threads_enter ();
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);
}
(*env)->ReleaseStringUTFChars (env, chars, str);
for (i = g_list_first (items); i != NULL; i = g_list_next (i))
g_free (i->data);
g_list_free (items);
gdk_threads_leave ();
return (*env)->NewObject (env,
glyphVector_class,
glyphVector_ctor,
java_extents, java_codes,
font, fontRenderContext);
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkFontPeer_getFontMetrics
(JNIEnv *env, jobject java_font, jdoubleArray java_metrics)
{
struct peerfont *pfont = NULL;
jdouble *native_metrics = NULL;
PangoFontMetrics *pango_metrics = NULL;
gdk_threads_enter();
pfont = (struct peerfont *) NSA_GET_FONT_PTR (env, java_font);
g_assert (pfont != NULL);
pango_metrics
= pango_context_get_metrics (pfont->ctx, pfont->desc,
gtk_get_default_language ());
native_metrics
= (*env)->GetDoubleArrayElements (env, java_metrics, NULL);
g_assert (native_metrics != NULL);
native_metrics[FONT_METRICS_ASCENT]
= PANGO_PIXELS (pango_font_metrics_get_ascent (pango_metrics));
native_metrics[FONT_METRICS_MAX_ASCENT]
= native_metrics[FONT_METRICS_ASCENT];
native_metrics[FONT_METRICS_DESCENT]
= PANGO_PIXELS (pango_font_metrics_get_descent (pango_metrics));
if (native_metrics[FONT_METRICS_DESCENT] < 0)
native_metrics[FONT_METRICS_DESCENT]
= - native_metrics[FONT_METRICS_DESCENT];
native_metrics[FONT_METRICS_MAX_DESCENT]
= native_metrics[FONT_METRICS_DESCENT];
native_metrics[FONT_METRICS_MAX_ADVANCE]
= PANGO_PIXELS (pango_font_metrics_get_approximate_char_width
(pango_metrics));
(*env)->ReleaseDoubleArrayElements (env,
java_metrics,
native_metrics, 0);
pango_font_metrics_unref (pango_metrics);
gdk_threads_leave();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkFontPeer_getTextMetrics
(JNIEnv *env, jobject java_font, jstring str, jdoubleArray java_metrics)
{
struct peerfont *pfont = NULL;
const char *cstr = NULL;
jdouble *native_metrics = NULL;
PangoRectangle log;
gdk_threads_enter();
pfont = (struct peerfont *)NSA_GET_FONT_PTR (env, java_font);
g_assert (pfont != NULL);
cstr = (*env)->GetStringUTFChars (env, str, NULL);
g_assert(cstr != NULL);
pango_layout_set_text (pfont->layout, cstr, -1);
pango_layout_get_extents (pfont->layout, NULL, &log);
(*env)->ReleaseStringUTFChars (env, str, cstr);
pango_layout_set_text (pfont->layout, "", -1);
native_metrics = (*env)->GetDoubleArrayElements (env, java_metrics, NULL);
g_assert (native_metrics != NULL);
native_metrics[TEXT_METRICS_X_BEARING]
= PANGO_PIXELS( ((double)log.x) );
native_metrics[TEXT_METRICS_Y_BEARING]
= PANGO_PIXELS( ((double)log.y) );
native_metrics[TEXT_METRICS_WIDTH]
= PANGO_PIXELS( ((double)log.width) );
native_metrics[TEXT_METRICS_HEIGHT]
= PANGO_PIXELS( ((double)log.height) );
native_metrics[TEXT_METRICS_X_ADVANCE]
= PANGO_PIXELS( ((double) (log.x + log.width)) );
native_metrics[TEXT_METRICS_Y_ADVANCE]
= PANGO_PIXELS( ((double) (log.y + log.height)) );
(*env)->ReleaseDoubleArrayElements (env, java_metrics, native_metrics, 0);
gdk_threads_leave();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkFontPeer_setFont
(JNIEnv *env, jobject self, jstring family_name_str, jint style_int, jint size, jboolean useGraphics2D)
{
struct peerfont *pfont = NULL;
char const *family_name = NULL;
enum java_awt_font_style style;
PangoFT2FontMap *ft2_map = NULL;
gdk_threads_enter ();
style = (enum java_awt_font_style) style_int;
g_assert (self != NULL);
pfont = (struct peerfont *)NSA_GET_FONT_PTR (env, self);
g_assert (pfont != NULL);
if (pfont->ctx != NULL)
g_object_unref (pfont->ctx);
if (pfont->font != NULL)
g_object_unref (pfont->font);
if (pfont->desc != NULL)
pango_font_description_free (pfont->desc);
pfont->desc = pango_font_description_new ();
g_assert (pfont->desc != NULL);
family_name = (*env)->GetStringUTFChars(env, family_name_str, 0);
g_assert (family_name != NULL);
pango_font_description_set_family (pfont->desc, family_name);
(*env)->ReleaseStringUTFChars(env, family_name_str, family_name);
if (style & java_awt_font_BOLD)
pango_font_description_set_weight (pfont->desc, PANGO_WEIGHT_BOLD);
if (style & java_awt_font_ITALIC)
pango_font_description_set_style (pfont->desc, PANGO_STYLE_ITALIC);
if (useGraphics2D)
{
pango_font_description_set_size (pfont->desc, size * PANGO_SCALE);
if (pfont->ctx == NULL)
{
ft2_map = PANGO_FT2_FONT_MAP(pango_ft2_font_map_for_display ());
pfont->ctx = pango_ft2_font_map_create_context (ft2_map);
}
}
else
{
/* GDK uses a slightly different DPI setting. */
pango_font_description_set_size (pfont->desc,
size * cp_gtk_dpi_conversion_factor);
if (pfont->ctx == NULL)
pfont->ctx = gdk_pango_context_get();
}
g_assert (pfont->ctx != NULL);
if (pfont->font != NULL)
{
g_object_unref (pfont->font);
pfont->font = NULL;
}
pango_context_set_font_description (pfont->ctx, pfont->desc);
pango_context_set_language (pfont->ctx, gtk_get_default_language());
pfont->font = pango_context_load_font (pfont->ctx, pfont->desc);
g_assert (pfont->font != NULL);
if (pfont->layout == NULL)
pfont->layout = pango_layout_new (pfont->ctx);
g_assert (pfont->layout != NULL);
gdk_threads_leave ();
}
@@ -0,0 +1,642 @@
/* gdkgraphics.c
Copyright (C) 1999 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"
#include "gdkfont.h"
#include "gnu_java_awt_peer_gtk_GdkGraphics.h"
#include <gdk/gdkprivate.h>
#include <gdk/gdkx.h>
static jmethodID initComponentGraphicsID;
void
cp_gtk_graphics_init_jni (void)
{
jclass gdkgraphics;
gdkgraphics = (*cp_gtk_gdk_env())->FindClass (cp_gtk_gdk_env(),
"gnu/java/awt/peer/gtk/GdkGraphics");
initComponentGraphicsID = (*cp_gtk_gdk_env())->GetMethodID (cp_gtk_gdk_env(), gdkgraphics,
"initComponentGraphics",
"()V");
}
#define GDK_STABLE_IS_PIXMAP(d) (GDK_IS_PIXMAP(d))
static GdkPoint *translate_points (JNIEnv *env, jintArray xpoints,
jintArray ypoints, jint npoints,
jint x_offset, jint y_offset);
static void realize_cb (GtkWidget *widget, jobject jgraphics);
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkGraphics_copyState
(JNIEnv *env, jobject obj, jobject old)
{
struct graphics *g = NULL;
struct graphics *g_old = NULL;
gdk_threads_enter ();
g = (struct graphics *) g_malloc (sizeof (struct graphics));
g_old = (struct graphics *) NSA_GET_PTR (env, old);
*g = *g_old;
g->gc = gdk_gc_new (g->drawable);
gdk_gc_copy (g->gc, g_old->gc);
if (GDK_STABLE_IS_PIXMAP (g->drawable))
gdk_pixmap_ref (g->drawable);
else /* GDK_IS_WINDOW (g->drawable) */
gdk_window_ref (g->drawable);
gdk_colormap_ref (g->cm);
NSA_SET_PTR (env, obj, g);
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkGraphics_initState__II
(JNIEnv *env, jobject obj, jint width, jint height)
{
struct graphics *g = NULL;
gdk_threads_enter ();
g = (struct graphics *) g_malloc (sizeof (struct graphics));
g->x_offset = g->y_offset = 0;
g->drawable = (GdkDrawable *) gdk_pixmap_new (NULL, width, height,
gdk_rgb_get_visual ()->depth);
g->cm = gdk_rgb_get_cmap ();
gdk_colormap_ref (g->cm);
g->gc = gdk_gc_new (g->drawable);
NSA_SET_PTR (env, obj, g);
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkGraphics_initFromImage
(JNIEnv *env, jobject obj, jobject source)
{
struct graphics *g = NULL;
GdkPixmap *pixmap = NULL;
gdk_threads_enter ();
pixmap = cp_gtk_image_get_pixmap (env, source);
g_assert(pixmap != NULL);
gdk_pixmap_ref (pixmap);
g = (struct graphics *) g_malloc (sizeof (struct graphics));
g->x_offset = g->y_offset = 0;
g->drawable = (GdkDrawable *)pixmap;
g->cm = gdk_drawable_get_colormap (g->drawable);
gdk_colormap_ref (g->cm);
g->gc = gdk_gc_new (g->drawable);
NSA_SET_PTR (env, obj, g);
gdk_threads_leave ();
}
/* copy the native state of the peer (GtkWidget *) to the native state
of the graphics object */
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkGraphics_initState__Lgnu_java_awt_peer_gtk_GtkComponentPeer_2
(JNIEnv *env, jobject obj, jobject peer)
{
struct graphics *g = NULL;
void *ptr = NULL;
GtkWidget *widget = NULL;
GdkColor color;
gdk_threads_enter ();
g = (struct graphics *) g_malloc (sizeof (struct graphics));
ptr = NSA_GET_PTR (env, peer);
g->x_offset = 0;
g->y_offset = 0;
widget = GTK_WIDGET (ptr);
g->drawable = (GdkDrawable *) widget->window;
gdk_window_ref (g->drawable);
g->cm = gtk_widget_get_colormap (widget);
gdk_colormap_ref (g->cm);
g->gc = gdk_gc_new (g->drawable);
gdk_gc_copy (g->gc, widget->style->fg_gc[GTK_STATE_NORMAL]);
color = widget->style->fg[GTK_STATE_NORMAL];
NSA_SET_PTR (env, obj, g);
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkGraphics_connectSignals
(JNIEnv *env, jobject obj, jobject peer)
{
void *ptr = NULL;
jobject *gref = NULL;
gdk_threads_enter ();
NSA_SET_GLOBAL_REF (env, obj);
gref = NSA_GET_GLOBAL_REF (env, obj);
ptr = NSA_GET_PTR (env, peer);
g_signal_connect_after (G_OBJECT (ptr), "realize",
G_CALLBACK (realize_cb), *gref);
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkGraphics_dispose
(JNIEnv *env, jobject obj)
{
struct graphics *g = NULL;
gdk_threads_enter ();
g = (struct graphics *) NSA_DEL_PTR (env, obj);
/* check if dispose has been called already */
if (!g)
{
gdk_threads_leave ();
return;
}
XFlush (GDK_DISPLAY ());
gdk_gc_destroy (g->gc);
if (GDK_STABLE_IS_PIXMAP (g->drawable))
gdk_pixmap_unref (g->drawable);
else /* GDK_IS_WINDOW (g->drawable) */
gdk_window_unref (g->drawable);
gdk_colormap_unref (g->cm);
g_free (g);
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkGraphics_translateNative
(JNIEnv *env, jobject obj, jint x, jint y)
{
struct graphics *g = NULL;
gdk_threads_enter ();
g = (struct graphics *) NSA_GET_PTR (env, obj);
g->x_offset += x;
g->y_offset += y;
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkGraphics_drawString
(JNIEnv *env, jobject obj, jobject font, jstring str, jint x, jint y)
{
struct peerfont *pfont = NULL;
struct graphics *g = NULL;
const char *cstr = NULL;
int baseline_y = 0;
PangoLayoutIter *iter = NULL;
gdk_threads_enter ();
g = (struct graphics *) NSA_GET_PTR (env, obj);
g_assert (g != NULL);
pfont = (struct peerfont *)NSA_GET_FONT_PTR (env, font);
g_assert (pfont != NULL);
cstr = (*env)->GetStringUTFChars (env, str, NULL);
pango_layout_set_font_description (pfont->layout, pfont->desc);
pango_layout_set_text (pfont->layout, cstr, -1);
iter = pango_layout_get_iter (pfont->layout);
baseline_y = pango_layout_iter_get_baseline (iter);
gdk_draw_layout (g->drawable, g->gc,
x + g->x_offset,
y + g->y_offset - PANGO_PIXELS (baseline_y),
pfont->layout);
pango_layout_iter_free (iter);
pango_layout_set_text (pfont->layout, "", -1);
gdk_flush ();
(*env)->ReleaseStringUTFChars (env, str, cstr);
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkGraphics_drawLine
(JNIEnv *env, jobject obj, jint x, jint y, jint x2, jint y2)
{
struct graphics *g = NULL;
gdk_threads_enter ();
g = (struct graphics *) NSA_GET_PTR (env, obj);
gdk_draw_line (g->drawable, g->gc,
x + g->x_offset, y + g->y_offset,
x2 + g->x_offset, y2 + g->y_offset);
gdk_flush ();
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkGraphics_fillRect
(JNIEnv *env, jobject obj, jint x, jint y, jint width, jint height)
{
struct graphics *g = NULL;
gdk_threads_enter ();
g = (struct graphics *) NSA_GET_PTR (env, obj);
gdk_draw_rectangle (g->drawable, g->gc, TRUE,
x + g->x_offset, y + g->y_offset, width, height);
gdk_flush ();
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkGraphics_drawRect
(JNIEnv *env, jobject obj, jint x, jint y, jint width, jint height)
{
struct graphics *g = NULL;
gdk_threads_enter ();
g = (struct graphics *) NSA_GET_PTR (env, obj);
gdk_draw_rectangle (g->drawable, g->gc, FALSE,
x + g->x_offset, y + g->y_offset, width, height);
gdk_flush ();
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkGraphics_copyArea
(JNIEnv *env, jobject obj, jint x, jint y,
jint width, jint height, jint dx, jint dy)
{
struct graphics *g = NULL;
gdk_threads_enter ();
g = (struct graphics *) NSA_GET_PTR (env, obj);
gdk_window_copy_area ((GdkWindow *)g->drawable,
g->gc,
x + g->x_offset + dx, y + g->y_offset + dy,
(GdkWindow *)g->drawable,
x + g->x_offset, y + g->y_offset,
width, height);
gdk_flush ();
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkGraphics_clearRect
(JNIEnv *env, jobject obj, jint x, jint y, jint width, jint height)
{
struct graphics *g = NULL;
GdkGCValues saved;
GtkWidget *widget = NULL;
union widget_union w;
gdk_threads_enter ();
g = (struct graphics *) NSA_GET_PTR (env, obj);
if (!g)
{
gdk_threads_leave ();
return;
}
if (GDK_IS_WINDOW (g->drawable))
{
w.widget = &widget;
gdk_window_get_user_data (GDK_WINDOW (g->drawable), w.void_widget);
if (widget == NULL || !GTK_IS_EVENT_BOX (widget))
gdk_window_clear_area ((GdkWindow *) g->drawable,
x + g->x_offset, y + g->y_offset,
width, height);
}
else
{
gdk_gc_get_values (g->gc, &saved);
gdk_gc_set_foreground (g->gc, &(saved.background));
gdk_draw_rectangle (g->drawable, g->gc, TRUE,
x + g->x_offset, y + g->y_offset, width, height);
gdk_gc_set_foreground (g->gc, &(saved.foreground));
}
gdk_flush ();
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkGraphics_setFunction
(JNIEnv *env, jobject obj, jint func)
{
struct graphics *g = NULL;
gdk_threads_enter ();
g = (struct graphics *) NSA_GET_PTR (env, obj);
gdk_gc_set_function (g->gc, func);
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkGraphics_setFGColor
(JNIEnv *env, jobject obj, jint red, jint green, jint blue)
{
GdkColor color;
struct graphics *g = NULL;
gdk_threads_enter ();
color.red = red << 8;
color.green = green << 8;
color.blue = blue << 8;
g = (struct graphics *) NSA_GET_PTR (env, obj);
gdk_color_alloc (g->cm, &color);
gdk_gc_set_foreground (g->gc, &color);
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkGraphics_drawArc
(JNIEnv *env, jobject obj, jint x, jint y, jint width, jint height,
jint angle1, jint angle2)
{
struct graphics *g = NULL;
gdk_threads_enter ();
g = (struct graphics *) NSA_GET_PTR (env, obj);
gdk_draw_arc (g->drawable, g->gc, FALSE,
x + g->x_offset, y + g->y_offset,
width, height, angle1 << 6, angle2 << 6);
gdk_flush ();
gdk_threads_leave ();
}
static GdkPoint *
translate_points (JNIEnv *env, jintArray xpoints, jintArray ypoints,
jint npoints, jint x_offset, jint y_offset)
{
GdkPoint *points;
jint *x, *y;
int i;
/* allocate one more point than necessary, in case we need to tack
on an extra due to the semantics of Java polygons. */
points = g_malloc (sizeof (GdkPoint) * (npoints + 1));
x = (*env)->GetIntArrayElements (env, xpoints, NULL);
y = (*env)->GetIntArrayElements (env, ypoints, NULL);
for (i = 0; i < npoints; i++)
{
points[i].x = x[i] + x_offset;
points[i].y = y[i] + y_offset;
}
(*env)->ReleaseIntArrayElements (env, xpoints, x, JNI_ABORT);
(*env)->ReleaseIntArrayElements (env, ypoints, y, JNI_ABORT);
return points;
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkGraphics_drawPolyline
(JNIEnv *env, jobject obj, jintArray xpoints, jintArray ypoints,
jint npoints)
{
struct graphics *g = NULL;
GdkPoint *points = NULL;
gdk_threads_enter ();
g = (struct graphics *) NSA_GET_PTR (env, obj);
points = translate_points (env, xpoints, ypoints, npoints,
g->x_offset, g->y_offset);
gdk_draw_lines (g->drawable, g->gc, points, npoints);
gdk_flush ();
g_free (points);
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkGraphics_drawPolygon
(JNIEnv *env, jobject obj, jintArray xpoints, jintArray ypoints,
jint npoints)
{
struct graphics *g = NULL;
GdkPoint *points = NULL;
gdk_threads_enter ();
g = (struct graphics *) NSA_GET_PTR (env, obj);
points = translate_points (env, xpoints, ypoints, npoints,
g->x_offset, g->y_offset);
/* make sure the polygon is closed, per Java semantics.
if it's not, we close it. */
if (points[0].x != points[npoints-1].x || points[0].y != points[npoints-1].y)
points[npoints++] = points[0];
gdk_draw_lines (g->drawable, g->gc, points, npoints);
gdk_flush ();
g_free (points);
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkGraphics_fillPolygon
(JNIEnv *env, jobject obj, jintArray xpoints, jintArray ypoints,
jint npoints)
{
struct graphics *g = NULL;
GdkPoint *points = NULL;
gdk_threads_enter ();
g = (struct graphics *) NSA_GET_PTR (env, obj);
points = translate_points (env, xpoints, ypoints, npoints,
g->x_offset, g->y_offset);
gdk_draw_polygon (g->drawable, g->gc, TRUE, points, npoints);
gdk_flush ();
g_free (points);
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkGraphics_fillArc
(JNIEnv *env, jobject obj, jint x, jint y, jint width, jint height,
jint angle1, jint angle2)
{
struct graphics *g = NULL;
gdk_threads_enter ();
g = (struct graphics *) NSA_GET_PTR (env, obj);
gdk_draw_arc (g->drawable, g->gc, TRUE,
x + g->x_offset, y + g->y_offset,
width, height, angle1 << 6, angle2 << 6);
gdk_flush ();
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkGraphics_drawOval
(JNIEnv *env, jobject obj, jint x, jint y, jint width, jint height)
{
struct graphics *g = NULL;
gdk_threads_enter ();
g = (struct graphics *) NSA_GET_PTR (env, obj);
gdk_draw_arc (g->drawable, g->gc, FALSE,
x + g->x_offset, y + g->y_offset,
width, height, 0, 23040);
gdk_flush ();
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkGraphics_fillOval
(JNIEnv *env, jobject obj, jint x, jint y, jint width, jint height)
{
struct graphics *g = NULL;
gdk_threads_enter ();
g = (struct graphics *) NSA_GET_PTR (env, obj);
gdk_draw_arc (g->drawable, g->gc, TRUE,
x + g->x_offset, y + g->y_offset,
width, height, 0, 23040);
gdk_flush ();
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkGraphics_setClipRectangle
(JNIEnv *env, jobject obj, jint x, jint y, jint width, jint height)
{
struct graphics *g = NULL;
GdkRectangle rectangle;
gdk_threads_enter ();
g = (struct graphics *) NSA_GET_PTR (env, obj);
rectangle.x = x + g->x_offset;
rectangle.y = y + g->y_offset;
rectangle.width = width;
rectangle.height = height;
gdk_gc_set_clip_rectangle (g->gc, &rectangle);
gdk_threads_leave ();
}
static void
realize_cb (GtkWidget *widget __attribute__ ((unused)), jobject jgraphics)
{
gdk_threads_leave ();
(*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), jgraphics, initComponentGraphicsID);
NSA_DEL_GLOBAL_REF (cp_gtk_gdk_env(), jgraphics);
gdk_threads_enter ();
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,102 @@
/* gnu_java_awt_peer_gtk_GdkGraphicsEnvironment.c
Copyright (C) 2004 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 "gdkfont.h"
#include "gnu_java_awt_peer_gtk_GdkGraphicsEnvironment.h"
static gint
cmp_families (const void *a, const void *b)
{
const char *a_name = pango_font_family_get_name (*(PangoFontFamily **)a);
const char *b_name = pango_font_family_get_name (*(PangoFontFamily **)b);
return g_utf8_collate (a_name, b_name);
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkGraphicsEnvironment_nativeGetFontFamilies
(JNIEnv *env, jobject self __attribute__((unused)), jobjectArray family_name)
{
PangoContext *context = NULL;
PangoFontFamily **families = NULL;
int n_families = 0;
int idx = 0;
gdk_threads_enter ();
context = gdk_pango_context_get();
g_assert (context != NULL);
pango_context_list_families (context, &families, &n_families);
qsort (families, n_families, sizeof (PangoFontFamily *), cmp_families);
for (idx = 0; idx < n_families; idx++)
{
const char *name_tmp = pango_font_family_get_name (families[idx]);
jstring name = (*env)->NewStringUTF (env, name_tmp);
(*env)->SetObjectArrayElement (env, family_name, idx, name);
}
g_free (families);
gdk_threads_leave ();
}
JNIEXPORT jint JNICALL
Java_gnu_java_awt_peer_gtk_GdkGraphicsEnvironment_nativeGetNumFontFamilies
(JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)))
{
PangoContext *context = NULL;
PangoFontFamily **families = NULL;
gint n_families = 0;
gint num = 0;
gdk_threads_enter ();
context = gdk_pango_context_get();
g_assert (context != NULL);
pango_context_list_families (context, &families, &n_families);
num = n_families;
g_free (families);
gdk_threads_leave ();
return num;
}
@@ -0,0 +1,515 @@
/* gdkpixbufdecoder.c
Copyright (C) 1999, 2003, 2004, 2005 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>
#include <gdk/gdk.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <gdk-pixbuf/gdk-pixbuf-loader.h>
#include <jni.h>
#include <jcl.h>
#include "native_state.h"
#include "gnu_java_awt_peer_gtk_GdkPixbufDecoder.h"
#include <string.h>
#include <stdlib.h>
static struct state_table *native_pixbufdecoder_state_table;
#define NSA_PB_INIT(env, clazz) \
native_pixbufdecoder_state_table = cp_gtk_init_state_table (env, clazz)
#define NSA_GET_PB_PTR(env, obj) \
cp_gtk_get_state (env, obj, native_pixbufdecoder_state_table)
#define NSA_SET_PB_PTR(env, obj, ptr) \
cp_gtk_set_state (env, obj, native_pixbufdecoder_state_table, (void *)ptr)
#define NSA_DEL_PB_PTR(env, obj) \
cp_gtk_remove_state_slot (env, obj, native_pixbufdecoder_state_table)
/* Union used for type punning. */
union env_union
{
void **void_env;
JNIEnv **jni_env;
};
static JavaVM *vm;
static jmethodID areaPreparedID;
static jmethodID areaUpdatedID;
static jmethodID dataOutputWriteID;
static jmethodID registerFormatID;
static void
area_prepared_cb (GdkPixbufLoader *loader,
jobject *decoder)
{
JNIEnv *env = NULL;
union env_union e;
jint width = 0;
jint height = 0;
GdkPixbuf *pixbuf = NULL;
pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
g_assert (pixbuf != NULL);
width = gdk_pixbuf_get_width (pixbuf);
height = gdk_pixbuf_get_height (pixbuf);
g_assert (decoder != NULL);
e.jni_env = &env;
(*vm)->GetEnv (vm, e.void_env, JNI_VERSION_1_1);
gdk_threads_leave ();
(*env)->CallVoidMethod (env,
*decoder,
areaPreparedID,
width, height);
gdk_threads_enter ();
}
static void
area_updated_cb (GdkPixbufLoader *loader,
gint x, gint y,
gint width, gint height,
jobject *decoder)
{
JNIEnv *env;
union env_union e;
jint stride_bytes, stride_pixels, n_channels, n_pixels;
jintArray jpixels;
jint *java_pixels;
guchar *gdk_pixels;
GdkPixbuf *pixbuf_no_alpha = NULL;
GdkPixbuf *pixbuf = NULL;
#ifndef WORDS_BIGENDIAN
int i;
#endif
pixbuf_no_alpha = gdk_pixbuf_loader_get_pixbuf (loader);
if (pixbuf_no_alpha == NULL)
return;
pixbuf = gdk_pixbuf_add_alpha(pixbuf_no_alpha, FALSE, 0, 0, 0);
g_assert (gdk_pixbuf_get_has_alpha (pixbuf));
stride_bytes = gdk_pixbuf_get_rowstride (pixbuf);
n_channels = gdk_pixbuf_get_n_channels (pixbuf);
stride_pixels = stride_bytes / n_channels;
n_pixels = height * stride_pixels;
gdk_pixels = gdk_pixbuf_get_pixels (pixbuf);
e.jni_env = &env;
(*vm)->GetEnv (vm, e.void_env, JNI_VERSION_1_1);
gdk_threads_leave ();
jpixels = (*env)->NewIntArray (env, n_pixels);
gdk_threads_enter ();
java_pixels = (*env)->GetIntArrayElements (env, jpixels, NULL);
memcpy (java_pixels,
gdk_pixels + (y * stride_bytes),
(height * stride_bytes));
#ifndef WORDS_BIGENDIAN
/* convert pixels from 0xBBGGRRAA to 0xAARRGGBB */
for (i = 0; i < n_pixels; ++i)
{
java_pixels[i] = SWAPU32 ((unsigned)java_pixels[i]);
}
#endif
g_object_unref (pixbuf);
gdk_threads_leave ();
(*env)->ReleaseIntArrayElements (env, jpixels, java_pixels, 0);
(*env)->CallVoidMethod (env,
*decoder,
areaUpdatedID,
(jint) x, (jint) y,
(jint) width, (jint) height,
jpixels,
stride_pixels);
(*env)->DeleteLocalRef(env, jpixels);
gdk_threads_enter ();
}
static void
closed_cb (GdkPixbufLoader *loader __attribute__((unused)), jobject *decoder)
{
JNIEnv *env;
union env_union e;
e.jni_env = &env;
(*vm)->GetEnv (vm, e.void_env, JNI_VERSION_1_1);
gdk_threads_leave ();
(*env)->DeleteGlobalRef (env, *decoder);
g_free (decoder);
gdk_threads_enter ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkPixbufDecoder_initState
(JNIEnv *env, jobject obj)
{
GdkPixbufLoader *loader = NULL;
jobject *decoder = NULL;
gdk_threads_enter ();
decoder = (jobject *) g_malloc (sizeof (jobject));
g_assert (decoder != NULL);
*decoder = (*env)->NewGlobalRef (env, obj);
loader = gdk_pixbuf_loader_new ();
g_assert (loader != NULL);
g_signal_connect (loader, "area-prepared", G_CALLBACK (area_prepared_cb), decoder);
g_signal_connect (loader, "area-updated", G_CALLBACK (area_updated_cb), decoder);
g_signal_connect (loader, "closed", G_CALLBACK (closed_cb), decoder);
NSA_SET_PB_PTR (env, obj, loader);
gdk_threads_leave ();
}
static void
query_formats (JNIEnv *env, jclass clazz)
{
jobject jformat;
GSList *formats, *f;
GdkPixbufFormat *format;
char **ch, *name;
jclass formatClass;
jmethodID addExtensionID;
jmethodID addMimeTypeID;
jobject string;
formatClass = (*env)->FindClass
(env, "gnu/java/awt/peer/gtk/GdkPixbufDecoder$ImageFormatSpec");
g_assert(formatClass != NULL);
addExtensionID = (*env)->GetMethodID (env, formatClass,
"addExtension",
"(Ljava/lang/String;)V");
addMimeTypeID = (*env)->GetMethodID (env, formatClass,
"addMimeType",
"(Ljava/lang/String;)V");
formats = gdk_pixbuf_get_formats ();
for (f = formats; f; f = f->next)
{
format = (GdkPixbufFormat *) f->data;
name = gdk_pixbuf_format_get_name(format);
string = (*env)->NewStringUTF(env, name);
g_assert(string != NULL);
jformat = (*env)->CallStaticObjectMethod
(env, clazz, registerFormatID, string,
(jboolean) gdk_pixbuf_format_is_writable(format));
(*env)->DeleteLocalRef(env, string);
g_assert(jformat != NULL);
ch = gdk_pixbuf_format_get_extensions(format);
while (*ch)
{
string = (*env)->NewStringUTF(env, *ch);
g_assert(string != NULL);
(*env)->CallVoidMethod (env, jformat, addExtensionID, string);
(*env)->DeleteLocalRef(env, string);
++ch;
}
ch = gdk_pixbuf_format_get_mime_types(format);
while (*ch)
{
string = (*env)->NewStringUTF(env, *ch);
g_assert(string != NULL);
(*env)->CallVoidMethod (env, jformat, addMimeTypeID, string);
(*env)->DeleteLocalRef(env, string);
++ch;
}
}
g_slist_free(formats);
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkPixbufDecoder_initStaticState
(JNIEnv *env, jclass clazz)
{
jclass dataOutputClass;
(*env)->GetJavaVM(env, &vm);
areaPreparedID = (*env)->GetMethodID (env, clazz,
"areaPrepared",
"(II)V");
areaUpdatedID = (*env)->GetMethodID (env, clazz,
"areaUpdated",
"(IIII[II)V");
registerFormatID = (*env)->GetStaticMethodID
(env, clazz,
"registerFormat",
"(Ljava/lang/String;Z)"
"Lgnu/java/awt/peer/gtk/GdkPixbufDecoder$ImageFormatSpec;");
dataOutputClass = (*env)->FindClass(env, "java/io/DataOutput");
dataOutputWriteID = (*env)->GetMethodID (env, dataOutputClass,
"write", "([B)V");
query_formats (env, clazz);
NSA_PB_INIT (env, clazz);
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkPixbufDecoder_finish
(JNIEnv *env, jobject obj, jboolean needs_close)
{
GdkPixbufLoader *loader = NULL;
gdk_threads_enter ();
loader = (GdkPixbufLoader *)NSA_DEL_PB_PTR (env, obj);
if (loader == NULL)
return;
if (needs_close)
gdk_pixbuf_loader_close (loader, NULL);
g_object_unref (loader);
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkPixbufDecoder_pumpDone
(JNIEnv *env, jobject obj)
{
GError *err = NULL;
GdkPixbufLoader *loader = NULL;
gdk_threads_enter ();
loader = (GdkPixbufLoader *)NSA_GET_PB_PTR (env, obj);
g_assert (loader != NULL);
gdk_pixbuf_loader_close (loader, &err);
if (err != NULL)
{
JCL_ThrowException (env, "java/io/IOException", err->message);
g_error_free (err);
}
gdk_threads_leave ();
}
struct stream_save_request
{
JNIEnv *env;
jobject *stream;
};
static gboolean
save_to_stream(const gchar *buf,
gsize count,
GError **error __attribute__((unused)),
gpointer data)
{
struct stream_save_request *ssr = (struct stream_save_request *)data;
jbyteArray jbuf;
jbyte *cbuf;
gdk_threads_leave ();
jbuf = (*(ssr->env))->NewByteArray ((ssr->env), count);
cbuf = (*(ssr->env))->GetByteArrayElements ((ssr->env), jbuf, NULL);
memcpy (cbuf, buf, count);
(*(ssr->env))->ReleaseByteArrayElements ((ssr->env), jbuf, cbuf, 0);
(*(ssr->env))->CallVoidMethod ((ssr->env), *(ssr->stream),
dataOutputWriteID, jbuf);
gdk_threads_enter ();
return TRUE;
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkPixbufDecoder_streamImage
(JNIEnv *env, jclass clazz __attribute__((unused)),
jintArray jarr, jstring jenctype, jint width, jint height,
jboolean hasAlpha, jobject stream)
{
GdkPixbuf* pixbuf;
jint *ints;
guchar a, r, g, b, *pix, *p;
GError *err = NULL;
const char *enctype;
int i;
struct stream_save_request ssr;
gdk_threads_enter ();
ssr.stream = &stream;
ssr.env = env;
ints = (*env)->GetIntArrayElements (env, jarr, NULL);
pix = g_malloc(width * height * (hasAlpha ? 4 : 3));
enctype = (*env)->GetStringUTFChars (env, jenctype, NULL);
g_assert(enctype != NULL);
g_assert (pix != NULL);
g_assert (ints != NULL);
p = pix;
for (i = 0; i < width*height; ++i)
{
/*
* Java encodes pixels as integers in a predictable arithmetic order:
* 0xAARRGGBB. Since these are jints, JNI has already byte-swapped
* them for us if necessary, so they're in "our" endianness, whatever
* that is. It uses 4 bytes per pixel whether or not there's an alpha
* channel.
*/
a = 0xff & (ints[i] >> 24);
r = 0xff & (ints[i] >> 16);
g = 0xff & (ints[i] >> 8);
b = 0xff & ints[i];
/*
* GDK-pixbuf has a very different storage model:
*
* - A different alpha order (alpha after colors).
* - A different packing model (no alpha -> 3-bytes-per-pixel).
* - A different "RGB" order (host memory order, not endian-neutral).
*/
*p++ = r;
*p++ = g;
*p++ = b;
if (hasAlpha)
*p++ = a;
}
pixbuf = gdk_pixbuf_new_from_data (pix,
GDK_COLORSPACE_RGB,
(gboolean) hasAlpha,
8, width, height,
width * (hasAlpha ? 4 : 3), /* rowstride */
NULL, NULL);
g_assert (pixbuf != NULL);
g_assert(gdk_pixbuf_save_to_callback (pixbuf,
&save_to_stream,
&ssr,
enctype,
&err, NULL));
g_object_unref (pixbuf);
g_free(pix);
(*env)->ReleaseStringUTFChars (env, jenctype, enctype);
(*env)->ReleaseIntArrayElements (env, jarr, ints, 0);
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkPixbufDecoder_pumpBytes
(JNIEnv *env, jobject obj, jbyteArray jarr, jint len)
{
GdkPixbufLoader *loader = NULL;
jbyte *bytes = NULL;
GError *err = NULL;
gdk_threads_enter ();
g_assert (len >= 1);
g_assert (jarr != NULL);
bytes = (*env)->GetByteArrayElements (env, jarr, NULL);
g_assert (bytes != NULL);
loader = (GdkPixbufLoader *)NSA_GET_PB_PTR (env, obj);
g_assert (loader != NULL);
gdk_pixbuf_loader_write (loader, (const guchar *) bytes, len, &err);
(*env)->ReleaseByteArrayElements (env, jarr, bytes, 0);
if (err != NULL)
{
JCL_ThrowException (env, "java/io/IOException", err->message);
g_error_free (err);
}
gdk_threads_leave ();
}
@@ -0,0 +1,341 @@
/* gdkrobotpeer.c
Copyright (C) 2004 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"
#include "gnu_java_awt_peer_gtk_GdkRobotPeer.h"
#include <gdk/gdkx.h>
#include <X11/extensions/XTest.h>
static int
awt_button_mask_to_num (int buttons)
{
switch (buttons)
{
case AWT_BUTTON1_MASK:
return 1;
case AWT_BUTTON2_MASK:
return 2;
case AWT_BUTTON3_MASK:
return 3;
}
return 0;
}
JNIEXPORT jboolean JNICALL
Java_gnu_java_awt_peer_gtk_GdkRobotPeer_initXTest
(JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)))
{
GdkDisplay *display;
Display *xdisplay;
int event_basep;
int error_basep;
int majorp;
int minorp;
jboolean result;
gdk_threads_enter ();
display = gdk_display_get_default ();
xdisplay = GDK_DISPLAY_XDISPLAY (display);
result = XTestQueryExtension (xdisplay,
&event_basep,
&error_basep,
&majorp,
&minorp);
gdk_threads_leave ();
return result;
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkRobotPeer_mouseMove
(JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)), jint x, jint y)
{
GdkDisplay *display;
Display *xdisplay;
int result;
gdk_threads_enter ();
display = gdk_display_get_default ();
xdisplay = GDK_DISPLAY_XDISPLAY (display);
result = XTestFakeMotionEvent (xdisplay,
-1,
x, y, CurrentTime);
XFlush (xdisplay);
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkRobotPeer_mousePress
(JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)), jint buttons)
{
GdkDisplay *display;
Display *xdisplay;
int result;
gdk_threads_enter ();
display = gdk_display_get_default ();
xdisplay = GDK_DISPLAY_XDISPLAY (display);
result = XTestFakeButtonEvent (xdisplay,
awt_button_mask_to_num (buttons),
True, CurrentTime);
XFlush (xdisplay);
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkRobotPeer_mouseRelease
(JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)), jint buttons)
{
GdkDisplay *display;
Display *xdisplay;
int result;
gdk_threads_enter ();
display = gdk_display_get_default ();
xdisplay = GDK_DISPLAY_XDISPLAY (display);
result = XTestFakeButtonEvent (xdisplay,
awt_button_mask_to_num (buttons),
False, CurrentTime);
XFlush (xdisplay);
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkRobotPeer_mouseWheel
(JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)), jint wheelAmt)
{
GdkDisplay *display;
Display *xdisplay;
int i = 0;
gdk_threads_enter ();
display = gdk_display_get_default ();
xdisplay = GDK_DISPLAY_XDISPLAY (display);
if (wheelAmt < 0)
for (i = 0; i < -wheelAmt; i++)
{
XTestFakeButtonEvent (xdisplay,
4,
True, CurrentTime);
XTestFakeButtonEvent (xdisplay,
4,
False, CurrentTime);
}
else
for (i = 0; i < wheelAmt; i++)
{
XTestFakeButtonEvent (xdisplay,
5,
True, CurrentTime);
XTestFakeButtonEvent (xdisplay,
5,
False, CurrentTime);
}
XFlush (xdisplay);
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkRobotPeer_keyPress
(JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)), jint keycode)
{
GdkDisplay *display;
Display *xdisplay;
GdkKeymapKey *keymap_keys = NULL;
gint n_keys = 0;
guint lookup_keyval = 0;
int result;
gdk_threads_enter ();
display = gdk_display_get_default ();
xdisplay = GDK_DISPLAY_XDISPLAY (display);
lookup_keyval = cp_gtk_awt_keycode_to_keysym (keycode,
AWT_KEY_LOCATION_LEFT);
if (!gdk_keymap_get_entries_for_keyval (gdk_keymap_get_default (),
lookup_keyval,
&keymap_keys,
&n_keys))
{
/* No matching keymap entry was found. */
g_printerr ("No matching keymap entries were found\n");
gdk_threads_leave ();
return;
}
/* If n_keys > 1 then there are multiple hardware keycodes that
translate to lookup_keyval. We arbitrarily choose the first
hardware keycode from the list returned by
gdk_keymap_get_entries_for_keyval. */
result = XTestFakeKeyEvent (xdisplay,
keymap_keys[0].keycode,
True, CurrentTime);
g_free (keymap_keys);
XFlush (xdisplay);
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkRobotPeer_keyRelease
(JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)), jint keycode)
{
GdkDisplay *display;
Display *xdisplay;
GdkKeymapKey *keymap_keys = NULL;
gint n_keys = 0;
guint lookup_keyval = 0;
int result;
gdk_threads_enter ();
display = gdk_display_get_default ();
xdisplay = GDK_DISPLAY_XDISPLAY (display);
lookup_keyval = cp_gtk_awt_keycode_to_keysym (keycode,
AWT_KEY_LOCATION_LEFT);
if (!gdk_keymap_get_entries_for_keyval (gdk_keymap_get_default (),
lookup_keyval,
&keymap_keys,
&n_keys))
{
/* No matching keymap entry was found. */
g_printerr ("No matching keymap entries were found\n");
gdk_threads_leave ();
return;
}
/* If n_keys > 1 then there are multiple hardware keycodes that
translate to lookup_keyval. We arbitrarily choose the first
hardware keycode from the list returned by
gdk_keymap_get_entries_for_keyval. */
result = XTestFakeKeyEvent (xdisplay,
keymap_keys[0].keycode,
False, CurrentTime);
g_free (keymap_keys);
XFlush (xdisplay);
gdk_threads_leave ();
}
JNIEXPORT jintArray JNICALL
Java_gnu_java_awt_peer_gtk_GdkRobotPeer_nativeGetRGBPixels
(JNIEnv *env, jobject obj __attribute__((unused)), jint x, jint y,
jint width, jint height)
{
jint stride_bytes, stride_pixels, n_channels, n_pixels;
jintArray jpixels;
jint *java_pixels;
guchar *gdk_pixels;
GdkPixbuf *pixbuf_no_alpha = NULL;
GdkPixbuf *pixbuf = NULL;
#ifndef WORDS_BIGENDIAN
int i;
#endif
gdk_threads_enter ();
pixbuf_no_alpha = gdk_pixbuf_get_from_drawable (NULL,
gdk_get_default_root_window (),
NULL, x, y, 0, 0,
width, height);
pixbuf = gdk_pixbuf_add_alpha(pixbuf_no_alpha, FALSE, 0, 0, 0);
g_assert (gdk_pixbuf_get_has_alpha (pixbuf));
stride_bytes = gdk_pixbuf_get_rowstride (pixbuf);
n_channels = gdk_pixbuf_get_n_channels (pixbuf);
stride_pixels = stride_bytes / n_channels;
n_pixels = height * stride_pixels;
gdk_pixels = gdk_pixbuf_get_pixels (pixbuf);
gdk_threads_leave ();
jpixels = (*env)->NewIntArray (env, n_pixels);
gdk_threads_enter ();
java_pixels = (*env)->GetIntArrayElements (env, jpixels, NULL);
memcpy (java_pixels,
gdk_pixels,
(height * stride_bytes));
#ifndef WORDS_BIGENDIAN
/* convert pixels from 0xBBGGRRAA to 0xAARRGGBB */
for (i = 0; i < n_pixels; ++i)
{
java_pixels[i] = SWAPU32 ((unsigned)java_pixels[i]);
}
#endif
g_object_unref (pixbuf);
(*env)->ReleaseIntArrayElements (env, jpixels, java_pixels, 0);
gdk_threads_leave ();
return jpixels;
}
@@ -0,0 +1,192 @@
/* gnu_java_awt_GdkTextLayout.c
Copyright (C) 2004 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 "native_state.h"
#include "gdkfont.h"
#include "gnu_java_awt_peer_gtk_GdkTextLayout.h"
struct state_table *cp_gtk_native_text_layout_state_table;
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkTextLayout_initStaticState
(JNIEnv *env, jclass clazz)
{
NSA_TEXT_LAYOUT_INIT (env, clazz);
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkTextLayout_initState
(JNIEnv *env, jobject self)
{
struct textlayout *tl;
gdk_threads_enter ();
g_assert(self != NULL);
tl = g_malloc0 (sizeof (struct textlayout));
g_assert(tl != NULL);
tl->pango_layout = pango_layout_new(gdk_pango_context_get());
g_assert(tl->pango_layout != NULL);
NSA_SET_TEXT_LAYOUT_PTR (env, self, tl);
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkTextLayout_setText
(JNIEnv *env, jobject self, jstring text)
{
struct textlayout *tl;
gchar *str = NULL;
gint len = 0;
gdk_threads_enter ();
g_assert(self != NULL);
g_assert(text != NULL);
tl = (struct textlayout *)NSA_GET_TEXT_LAYOUT_PTR (env, self);
g_assert(tl != NULL);
g_assert(tl->pango_layout != NULL);
len = (*env)->GetStringUTFLength (env, text);
str = (gchar *)(*env)->GetStringUTFChars (env, text, NULL);
g_assert (str != NULL);
pango_layout_set_text (tl->pango_layout, text, len);
(*env)->ReleaseStringUTFChars (env, text, str);
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkTextLayout_indexToPos
(JNIEnv *env, jobject self, jint idx, jdoubleArray javaPos)
{
struct textlayout *tl;
PangoRectangle pangoPos;
jdouble *nativePos;
gdk_threads_enter ();
g_assert(self != NULL);
g_assert(javaPos != NULL);
tl = (struct textlayout *)NSA_GET_TEXT_LAYOUT_PTR (env, self);
g_assert(tl != NULL);
g_assert(tl->pango_layout != NULL);
g_assert((*env)->GetArrayLength (env, javaPos) == 4);
nativePos = (*env)->GetDoubleArrayElements (env, javaPos, NULL);
pango_layout_index_to_pos (tl->pango_layout, idx, &pangoPos);
nativePos[0] = (jdouble) pangoPos.x;
nativePos[1] = (jdouble) pangoPos.y;
nativePos[2] = (jdouble) pangoPos.width;
nativePos[3] = (jdouble) pangoPos.height;
(*env)->ReleaseDoubleArrayElements (env, javaPos, nativePos, 0);
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkTextLayout_getExtents
(JNIEnv *env, jobject self, jdoubleArray javaInkExtents, jdoubleArray javaLogExtents)
{
struct textlayout *tl;
PangoRectangle pangoInkExtents, pangoLogExtents;
jdouble *nativeInkExtents, *nativeLogExtents;
gdk_threads_enter ();
g_assert(self != NULL);
g_assert(javaInkExtents != NULL);
g_assert(javaLogExtents != NULL);
tl = (struct textlayout *)NSA_GET_TEXT_LAYOUT_PTR (env, self);
g_assert(tl != NULL);
g_assert(tl->pango_layout != NULL);
g_assert((*env)->GetArrayLength (env, javaInkExtents) == 4);
g_assert((*env)->GetArrayLength (env, javaLogExtents) == 4);
nativeInkExtents = (*env)->GetDoubleArrayElements (env, javaInkExtents, NULL);
nativeLogExtents = (*env)->GetDoubleArrayElements (env, javaLogExtents, NULL);
pango_layout_get_extents (tl->pango_layout,
&pangoInkExtents, &pangoLogExtents);
nativeInkExtents[0] = (jdouble) pangoInkExtents.x;
nativeInkExtents[1] = (jdouble) pangoInkExtents.y;
nativeInkExtents[2] = (jdouble) pangoInkExtents.width;
nativeInkExtents[3] = (jdouble) pangoInkExtents.height;
nativeLogExtents[0] = (jdouble) pangoLogExtents.x;
nativeLogExtents[1] = (jdouble) pangoLogExtents.y;
nativeLogExtents[2] = (jdouble) pangoLogExtents.width;
nativeLogExtents[3] = (jdouble) pangoLogExtents.height;
(*env)->ReleaseDoubleArrayElements (env, javaInkExtents, nativeInkExtents, 0);
(*env)->ReleaseDoubleArrayElements (env, javaLogExtents, nativeLogExtents, 0);
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GdkTextLayout_dispose
(JNIEnv *env, jobject self)
{
struct textlayout *tl;
gdk_threads_enter ();
g_assert(self != NULL);
tl = (struct textlayout *) NSA_DEL_TEXT_LAYOUT_PTR (env, self);
g_assert(tl != NULL);
if (tl->pango_layout != NULL)
g_object_unref (tl->pango_layout);
g_free(tl);
gdk_threads_leave ();
}
@@ -0,0 +1,338 @@
/* gtkbuttonpeer.c -- Native implementation of GtkButtonPeer
Copyright (C) 1998, 1999 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"
#include "gnu_java_awt_peer_gtk_GtkButtonPeer.h"
static jmethodID beginNativeRepaintID;
static jmethodID endNativeRepaintID;
void
cp_gtk_button_init_jni (void)
{
jclass gtkbuttonpeer;
gtkbuttonpeer = (*cp_gtk_gdk_env())->FindClass (cp_gtk_gdk_env(),
"gnu/java/awt/peer/gtk/GtkButtonPeer");
beginNativeRepaintID = (*cp_gtk_gdk_env())->GetMethodID (cp_gtk_gdk_env(), gtkbuttonpeer,
"beginNativeRepaint",
"()V");
endNativeRepaintID = (*cp_gtk_gdk_env())->GetMethodID (cp_gtk_gdk_env(), gtkbuttonpeer,
"endNativeRepaint", "()V");
}
static void block_expose_event_cb (GtkWidget *widget,
jobject peer);
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkButtonPeer_create
(JNIEnv *env, jobject obj, jstring label)
{
const char *c_label;
GtkWidget *eventbox;
GtkWidget *button;
gdk_threads_enter ();
NSA_SET_GLOBAL_REF (env, obj);
c_label = (*env)->GetStringUTFChars (env, label, NULL);
eventbox = gtk_event_box_new ();
button = gtk_button_new_with_label (c_label);
gtk_container_add (GTK_CONTAINER (eventbox), button);
gtk_widget_show (button);
(*env)->ReleaseStringUTFChars (env, label, c_label);
NSA_SET_PTR (env, obj, eventbox);
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkButtonPeer_connectSignals
(JNIEnv *env, jobject obj)
{
void *ptr;
jobject *gref;
GtkWidget *button;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
gref = NSA_GET_GLOBAL_REF (env, obj);
button = gtk_bin_get_child (GTK_BIN (ptr));
/* Button signals */
g_signal_connect_after (G_OBJECT (button), "pressed",
G_CALLBACK (block_expose_event_cb), *gref);
g_signal_connect_after (G_OBJECT (button), "released",
G_CALLBACK (block_expose_event_cb), *gref);
/* Component signals */
cp_gtk_component_connect_signals (G_OBJECT (button), gref);
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkButtonPeer_gtkSetLabel
(JNIEnv *env, jobject obj, jstring jtext)
{
const char *text;
GtkWidget *button;
GtkWidget *label;
void *ptr;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
text = (*env)->GetStringUTFChars (env, jtext, NULL);
button = gtk_bin_get_child (GTK_BIN (ptr));
label = gtk_bin_get_child (GTK_BIN (button));
gtk_label_set_text (GTK_LABEL (label), text);
(*env)->ReleaseStringUTFChars (env, jtext, text);
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkButtonPeer_gtkWidgetModifyFont
(JNIEnv *env, jobject obj, jstring name, jint style, jint size)
{
const char *font_name;
void *ptr;
GtkWidget *button;
GtkWidget *label;
PangoFontDescription *font_desc;
gdk_threads_enter();
ptr = NSA_GET_PTR (env, obj);
font_name = (*env)->GetStringUTFChars (env, name, NULL);
button = gtk_bin_get_child (GTK_BIN (ptr));
label = gtk_bin_get_child (GTK_BIN (button));
font_desc = pango_font_description_from_string (font_name);
pango_font_description_set_size (font_desc,
size * cp_gtk_dpi_conversion_factor);
if (style & AWT_STYLE_BOLD)
pango_font_description_set_weight (font_desc, PANGO_WEIGHT_BOLD);
if (style & AWT_STYLE_ITALIC)
pango_font_description_set_style (font_desc, PANGO_STYLE_OBLIQUE);
gtk_widget_modify_font (GTK_WIDGET(label), font_desc);
pango_font_description_free (font_desc);
(*env)->ReleaseStringUTFChars (env, name, font_name);
gdk_threads_leave();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkButtonPeer_gtkWidgetSetBackground
(JNIEnv *env, jobject obj, jint red, jint green, jint blue)
{
GdkColor normal_color;
GdkColor prelight_color;
GdkColor active_color;
int prelight_red;
int prelight_blue;
int prelight_green;
GtkWidget *button;
void *ptr;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
normal_color.red = (red / 255.0) * 65535;
normal_color.green = (green / 255.0) * 65535;
normal_color.blue = (blue / 255.0) * 65535;
/* This calculation only approximate the active color produced by
Sun's AWT. */
active_color.red = 0.85 * (red / 255.0) * 65535;
active_color.green = 0.85 * (green / 255.0) * 65535;
active_color.blue = 0.85 * (blue / 255.0) * 65535;
/* There is no separate prelight color in Motif. */
prelight_red = 1.15 * (red / 255.0) * 65535;
prelight_green = 1.15 * (green / 255.0) * 65535;
prelight_blue = 1.15 * (blue / 255.0) * 65535;
prelight_color.red = prelight_red > 65535 ? 65535 : prelight_red;
prelight_color.green = prelight_green > 65535 ? 65535 : prelight_green;
prelight_color.blue = prelight_blue > 65535 ? 65535 : prelight_blue;
button = gtk_bin_get_child (GTK_BIN (ptr));
gtk_widget_modify_bg (button, GTK_STATE_NORMAL, &normal_color);
gtk_widget_modify_bg (button, GTK_STATE_ACTIVE, &active_color);
gtk_widget_modify_bg (button, GTK_STATE_PRELIGHT, &prelight_color);
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkButtonPeer_gtkWidgetSetForeground
(JNIEnv *env, jobject obj, jint red, jint green, jint blue)
{
GdkColor color;
GtkWidget *button;
GtkWidget *label;
void *ptr;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
color.red = (red / 255.0) * 65535;
color.green = (green / 255.0) * 65535;
color.blue = (blue / 255.0) * 65535;
button = gtk_bin_get_child (GTK_BIN (ptr));
label = gtk_bin_get_child (GTK_BIN (button));
gtk_widget_modify_fg (label, GTK_STATE_NORMAL, &color);
gtk_widget_modify_fg (label, GTK_STATE_ACTIVE, &color);
gtk_widget_modify_fg (label, GTK_STATE_PRELIGHT, &color);
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkButtonPeer_gtkActivate
(JNIEnv *env, jobject obj)
{
GtkWidget *button;
void *ptr;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
button = gtk_bin_get_child (GTK_BIN (ptr));
gtk_widget_activate (GTK_WIDGET (button));
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkButtonPeer_gtkWidgetRequestFocus
(JNIEnv *env, jobject obj)
{
void *ptr;
GtkWidget *button;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
button = gtk_bin_get_child (GTK_BIN (ptr));
gtk_widget_grab_focus (button);
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkButtonPeer_setNativeBounds
(JNIEnv *env, jobject obj, jint x, jint y, jint width, jint height)
{
GtkWidget *widget, *child;
void *ptr;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
widget = GTK_WIDGET (ptr);
/* We assume that -1 is a width or height and not a request for the
widget's natural size. */
width = width < 0 ? 0 : width;
height = height < 0 ? 0 : height;
child = gtk_bin_get_child (GTK_BIN (widget));
if (!(width == 0 && height == 0))
{
/* Set the event box's size request... */
gtk_widget_set_size_request (widget, width, height);
/* ...and the button's size request... */
gtk_widget_set_size_request (child, width, height);
/* ...and the label's size request. */
gtk_widget_set_size_request (gtk_bin_get_child (GTK_BIN (child)), width,
height);
if (widget->parent != NULL)
gtk_fixed_move (GTK_FIXED (widget->parent), widget, x, y);
}
gdk_threads_leave ();
}
static void
block_expose_event_cb (GtkWidget *widget, jobject peer)
{
gdk_threads_leave ();
(*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer,
beginNativeRepaintID);
gdk_threads_enter ();
gdk_window_process_updates (widget->window, TRUE);
gdk_threads_leave ();
(*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer,
endNativeRepaintID);
gdk_threads_enter ();
}
@@ -0,0 +1,58 @@
/* gtkcanvaspeer.c -- Native implementation of GtkCanvasPeer
Copyright (C) 1999 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"
#include "gnu_java_awt_peer_gtk_GtkCanvasPeer.h"
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkCanvasPeer_create
(JNIEnv *env, jobject obj)
{
gpointer widget;
gdk_threads_enter ();
/* Create global reference and save it for future use */
NSA_SET_GLOBAL_REF (env, obj);
widget = gtk_type_new (gtk_drawing_area_get_type ());
NSA_SET_PTR (env, obj, widget);
gdk_threads_leave ();
}
@@ -0,0 +1,77 @@
/* gtkcheckboxgrouppeer.c -- Native implementation of GtkCheckboxGroupPeer
Copyright (C) 2004 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"
#include "gnu_java_awt_peer_gtk_GtkCheckboxGroupPeer.h"
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkCheckboxGroupPeer_dispose
(JNIEnv *env, jobject obj)
{
/* The actual underlying widget is owned by a different class. So
we just clean up the hash table here. */
NSA_DEL_PTR (env, obj);
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkCheckboxGroupPeer_remove
(JNIEnv *env, jobject obj, jobject checkbox)
{
GtkRadioButton *button;
void *ptr;
GSList *list;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, checkbox);
button = GTK_RADIO_BUTTON (ptr);
/* Update the group to point to some other widget in the group. We
have to do this because Gtk doesn't have a separate object to
represent a radio button's group. */
for (list = gtk_radio_button_group (button); list != NULL;
list = list->next)
{
if (list->data != button)
break;
}
NSA_SET_PTR (env, obj, list ? list->data : NULL);
gdk_threads_leave ();
}
@@ -0,0 +1,78 @@
/* gtkmenuitempeer.c -- Native implementation of GtkMenuItemPeer
Copyright (C) 1999 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"
#include "gnu_java_awt_peer_gtk_GtkCheckboxMenuItemPeer.h"
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkCheckboxMenuItemPeer_create
(JNIEnv *env, jobject obj, jstring label)
{
GtkWidget *widget;
const char *str;
gdk_threads_enter ();
NSA_SET_GLOBAL_REF (env, obj);
str = (*env)->GetStringUTFChars (env, label, NULL);
widget = gtk_check_menu_item_new_with_label (str);
gtk_widget_show (widget);
(*env)->ReleaseStringUTFChars (env, label, str);
NSA_SET_PTR (env, obj, widget);
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkCheckboxMenuItemPeer_setState
(JNIEnv *env, jobject obj, jboolean state)
{
void *ptr;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (ptr), state);
gdk_threads_leave ();
}
@@ -0,0 +1,240 @@
/* gtkcheckboxpeer.c -- Native implementation of GtkCheckboxPeer
Copyright (C) 1998, 1999, 2002, 2003, 2004 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"
#include "gnu_java_awt_peer_gtk_GtkCheckboxPeer.h"
#include "gnu_java_awt_peer_gtk_GtkComponentPeer.h"
static jmethodID postItemEventID;
void
cp_gtk_checkbox_init_jni (void)
{
jclass gtkcheckboxpeer;
gtkcheckboxpeer = (*cp_gtk_gdk_env())->FindClass (cp_gtk_gdk_env(),
"gnu/java/awt/peer/gtk/GtkCheckboxPeer");
postItemEventID = (*cp_gtk_gdk_env())->GetMethodID (cp_gtk_gdk_env(), gtkcheckboxpeer,
"postItemEvent",
"(Ljava/lang/Object;I)V");
}
static void item_toggled_cb (GtkToggleButton *item, jobject peer);
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkCheckboxPeer_create
(JNIEnv *env, jobject obj, jobject group)
{
GtkWidget *button;
gdk_threads_enter ();
NSA_SET_GLOBAL_REF (env, obj);
if (group == NULL)
button = gtk_check_button_new_with_label ("");
else
{
void *native_group = NSA_GET_PTR (env, group);
button = gtk_radio_button_new_with_label_from_widget (native_group, "");
if (native_group == NULL)
{
/* Set the native group so we can use the correct value the
next time around. FIXME: this doesn't work! */
NSA_SET_PTR (env, group, button);
}
}
NSA_SET_PTR (env, obj, button);
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkCheckboxPeer_connectSignals
(JNIEnv *env, jobject obj)
{
void *ptr = NULL;
jobject *gref = NULL;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
gref = NSA_GET_GLOBAL_REF (env, obj);
/* Checkbox signals */
g_signal_connect (G_OBJECT (ptr), "toggled",
G_CALLBACK (item_toggled_cb), *gref);
/* Component signals */
cp_gtk_component_connect_signals (G_OBJECT (ptr), gref);
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkCheckboxPeer_nativeSetCheckboxGroup
(JNIEnv *env, jobject obj, jobject group)
{
GtkRadioButton *button;
void *native_group, *ptr;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
/* FIXME: we can't yet switch between a checkbutton and a
radiobutton. However, AWT requires this. For now we just
crash. */
button = GTK_RADIO_BUTTON (ptr);
native_group = NSA_GET_PTR (env, group);
if (native_group == NULL)
gtk_radio_button_set_group (button, NULL);
else
gtk_radio_button_set_group (button,
gtk_radio_button_group
(GTK_RADIO_BUTTON (native_group)));
/* If the native group wasn't set on the new CheckboxGroup, then set
it now so that the right thing will happen with the next
radiobutton. The native state for a CheckboxGroup is a pointer
to one of the widgets in the group. We are careful to keep this
always pointing at a live widget; whenever a widget is destroyed
(or otherwise removed from the group), the CheckboxGroup peer is
notified. */
if (native_group == NULL)
NSA_SET_PTR (env, group, native_group);
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkCheckboxPeer_gtkToggleButtonSetActive
(JNIEnv *env, jobject obj, jboolean is_active)
{
void *ptr;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ptr), is_active);
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkCheckboxPeer_gtkWidgetModifyFont
(JNIEnv *env, jobject obj, jstring name, jint style, jint size)
{
const char *font_name;
void *ptr;
GtkWidget *button;
GtkWidget *label;
PangoFontDescription *font_desc;
gdk_threads_enter();
ptr = NSA_GET_PTR (env, obj);
button = GTK_WIDGET (ptr);
label = gtk_bin_get_child (GTK_BIN(button));
if (!label)
return;
font_name = (*env)->GetStringUTFChars (env, name, NULL);
font_desc = pango_font_description_from_string (font_name);
pango_font_description_set_size (font_desc,
size * cp_gtk_dpi_conversion_factor);
if (style & AWT_STYLE_BOLD)
pango_font_description_set_weight (font_desc, PANGO_WEIGHT_BOLD);
if (style & AWT_STYLE_ITALIC)
pango_font_description_set_style (font_desc, PANGO_STYLE_OBLIQUE);
gtk_widget_modify_font (GTK_WIDGET(label), font_desc);
pango_font_description_free (font_desc);
(*env)->ReleaseStringUTFChars (env, name, font_name);
gdk_threads_leave();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkCheckboxPeer_gtkButtonSetLabel
(JNIEnv *env, jobject obj, jstring label)
{
const char *c_label;
GtkWidget *label_widget;
void *ptr;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
c_label = (*env)->GetStringUTFChars (env, label, NULL);
label_widget = gtk_bin_get_child (GTK_BIN (ptr));
gtk_label_set_text (GTK_LABEL (label_widget), c_label);
(*env)->ReleaseStringUTFChars (env, label, c_label);
gdk_threads_leave ();
}
static void
item_toggled_cb (GtkToggleButton *item, jobject peer)
{
gdk_threads_leave ();
(*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer,
postItemEventID,
peer,
item->active ?
(jint) AWT_ITEM_SELECTED :
(jint) AWT_ITEM_DESELECTED);
gdk_threads_enter ();
}
@@ -0,0 +1,248 @@
/* gtkchoicepeer.c -- Native implementation of GtkChoicePeer
Copyright (C) 1998, 1999 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"
#include "gnu_java_awt_peer_gtk_GtkChoicePeer.h"
static jmethodID postChoiceItemEventID;
void
cp_gtk_choice_init_jni (void)
{
jclass gtkchoicepeer;
gtkchoicepeer = (*cp_gtk_gdk_env())->FindClass (cp_gtk_gdk_env(),
"gnu/java/awt/peer/gtk/GtkChoicePeer");
postChoiceItemEventID = (*cp_gtk_gdk_env())->GetMethodID (cp_gtk_gdk_env(), gtkchoicepeer,
"postChoiceItemEvent",
"(Ljava/lang/String;I)V");
}
static void selection_changed_cb (GtkComboBox *combobox, jobject peer);
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkChoicePeer_create
(JNIEnv *env, jobject obj)
{
GtkWidget *combobox;
jobject *gref;
gdk_threads_enter ();
NSA_SET_GLOBAL_REF (env, obj);
gref = NSA_GET_GLOBAL_REF (env, obj);
combobox = gtk_combo_box_new_text ();
NSA_SET_PTR (env, obj, combobox);
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkChoicePeer_connectSignals
(JNIEnv *env, jobject obj)
{
void *ptr = NULL;
jobject *gref = NULL;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
gref = NSA_GET_GLOBAL_REF (env, obj);
/* Choice signals */
g_signal_connect (G_OBJECT (ptr), "changed",
G_CALLBACK (selection_changed_cb), *gref);
/* Component signals */
cp_gtk_component_connect_signals (G_OBJECT (ptr), gref);
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkChoicePeer_append
(JNIEnv *env, jobject obj, jobjectArray items)
{
gpointer ptr;
jsize count, i;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
count = (*env)->GetArrayLength (env, items);
for (i = 0; i < count; i++)
{
jobject item;
const char *label;
item = (*env)->GetObjectArrayElement (env, items, i);
label = (*env)->GetStringUTFChars (env, item, NULL);
gtk_combo_box_append_text (GTK_COMBO_BOX (ptr), label);
(*env)->ReleaseStringUTFChars (env, item, label);
}
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkChoicePeer_nativeAdd
(JNIEnv *env, jobject obj, jstring item, jint index)
{
void *ptr;
const char *label;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
label = (*env)->GetStringUTFChars (env, item, 0);
gtk_combo_box_insert_text (GTK_COMBO_BOX (ptr), index, label);
(*env)->ReleaseStringUTFChars (env, item, label);
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkChoicePeer_nativeRemove
(JNIEnv *env, jobject obj, jint index)
{
void *ptr;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
gtk_combo_box_remove_text (GTK_COMBO_BOX (ptr), index);
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkChoicePeer_nativeRemoveAll
(JNIEnv *env, jobject obj)
{
void *ptr;
GtkTreeModel *model;
gint count, i;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
model = gtk_combo_box_get_model (GTK_COMBO_BOX (ptr));
count = gtk_tree_model_iter_n_children (model, NULL);
/* First, unselect everything, to avoid problems when removing items. */
gtk_combo_box_set_active (GTK_COMBO_BOX (ptr), -1);
for (i = count - 1; i >= 0; i--) {
gtk_combo_box_remove_text (GTK_COMBO_BOX (ptr), i);
}
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkChoicePeer_select
(JNIEnv *env, jobject obj, jint index)
{
void *ptr;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
gtk_combo_box_set_active (GTK_COMBO_BOX (ptr), index);
gdk_threads_leave ();
}
JNIEXPORT jint JNICALL
Java_gnu_java_awt_peer_gtk_GtkChoicePeer_nativeGetSelected
(JNIEnv *env, jobject obj)
{
void *ptr;
int index;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
index = gtk_combo_box_get_active (GTK_COMBO_BOX (ptr));
gdk_threads_leave ();
return index;
}
static void selection_changed_cb (GtkComboBox *combobox, jobject peer)
{
jstring label;
GtkTreeModel *model;
GtkTreeIter iter;
gchar *selected;
gint index;
index = gtk_combo_box_get_active(combobox);
if (index >= 0)
{
model = gtk_combo_box_get_model (combobox);
gtk_combo_box_get_active_iter (combobox, &iter);
gtk_tree_model_get (model, &iter, 0, &selected, -1);
label = (*cp_gtk_gdk_env())->NewStringUTF (cp_gtk_gdk_env(), selected);
gdk_threads_leave ();
(*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer,
postChoiceItemEventID,
label,
(jint) AWT_ITEM_SELECTED);
gdk_threads_enter ();
}
}
@@ -0,0 +1,204 @@
/* gtkclipboard.c
Copyright (C) 1998, 1999 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"
#include "gnu_java_awt_peer_gtk_GtkClipboard.h"
static jmethodID stringSelectionReceivedID;
static jmethodID stringSelectionHandlerID;
static jmethodID selectionClearID;
static void selection_received_cb (GtkWidget *, GtkSelectionData *,
guint, gpointer);
static void selection_get_cb (GtkWidget *, GtkSelectionData *, guint,
guint, gpointer);
static gint selection_clear_cb (GtkWidget *, GdkEventSelection *);
static GtkWidget *clipboard;
static jobject cb_obj;
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkClipboard_initNativeState (JNIEnv *env,
jobject obj)
{
gdk_threads_enter ();
if (!stringSelectionReceivedID)
{
jclass gtkclipboard;
gtkclipboard = (*env)->FindClass (env,
"gnu/java/awt/peer/gtk/GtkClipboard");
stringSelectionReceivedID = (*env)->GetMethodID (env, gtkclipboard,
"stringSelectionReceived",
"(Ljava/lang/String;)V");
stringSelectionHandlerID = (*env)->GetMethodID (env, gtkclipboard,
"stringSelectionHandler",
"()Ljava/lang/String;");
selectionClearID = (*env)->GetMethodID (env, gtkclipboard,
"selectionClear", "()V");
}
cb_obj = (*env)->NewGlobalRef (env, obj);
clipboard = gtk_window_new (GTK_WINDOW_TOPLEVEL);
g_signal_connect (G_OBJECT(clipboard), "selection_received",
G_CALLBACK (selection_received_cb), NULL);
g_signal_connect (G_OBJECT(clipboard), "selection_clear_event",
G_CALLBACK (selection_clear_cb), NULL);
gtk_selection_add_target (clipboard, GDK_SELECTION_PRIMARY,
GDK_TARGET_STRING, 0);
g_signal_connect (G_OBJECT(clipboard), "selection_get",
G_CALLBACK (selection_get_cb), NULL);
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkClipboard_requestStringConversion
(JNIEnv *env __attribute__((unused)), jclass clazz __attribute__((unused)))
{
gdk_threads_enter ();
gtk_selection_convert (clipboard, GDK_SELECTION_PRIMARY,
GDK_TARGET_STRING, GDK_CURRENT_TIME);
gdk_threads_leave ();
}
static void
selection_received_cb (GtkWidget *widget __attribute__((unused)),
GtkSelectionData *selection_data __attribute__((unused)),
guint time __attribute__((unused)),
gpointer data __attribute__((unused)))
{
/* Check to see if retrieval succeeded */
if (selection_data->length < 0
|| selection_data->type != GDK_SELECTION_TYPE_STRING)
{
gdk_threads_leave ();
(*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), cb_obj, stringSelectionReceivedID,
NULL);
gdk_threads_enter ();
}
else
{
char *str = (char *) selection_data->data;
gdk_threads_leave ();
(*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), cb_obj, stringSelectionReceivedID,
(*cp_gtk_gdk_env())->NewStringUTF (cp_gtk_gdk_env(), str));
gdk_threads_enter ();
}
return;
}
static void
selection_get_cb (GtkWidget *widget __attribute__((unused)),
GtkSelectionData *selection_data,
guint info __attribute__((unused)),
guint time __attribute__((unused)),
gpointer data __attribute__((unused)))
{
jstring jstr;
const char *utf;
jsize utflen;
gdk_threads_leave ();
jstr = (*cp_gtk_gdk_env())->CallObjectMethod (cp_gtk_gdk_env(), cb_obj,
stringSelectionHandlerID);
gdk_threads_enter ();
if (!jstr)
{
gtk_selection_data_set (selection_data,
GDK_TARGET_STRING, 8, NULL, 0);
return;
}
utflen = (*cp_gtk_gdk_env())->GetStringUTFLength (cp_gtk_gdk_env(), jstr);
utf = (*cp_gtk_gdk_env())->GetStringUTFChars (cp_gtk_gdk_env(), jstr, NULL);
gtk_selection_data_set (selection_data, GDK_TARGET_STRING, 8,
(const unsigned char*)utf, utflen);
(*cp_gtk_gdk_env())->ReleaseStringUTFChars (cp_gtk_gdk_env(), jstr, utf);
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkClipboard_selectionGet
(JNIEnv *env, jclass clazz __attribute__((unused)))
{
GdkWindow *owner;
gdk_threads_enter ();
/* if we already own the clipboard, we need to tell the old data object
that we're no longer going to be using him */
owner = gdk_selection_owner_get (GDK_SELECTION_PRIMARY);
if (owner && owner == clipboard->window)
(*env)->CallVoidMethod (env, cb_obj, selectionClearID);
gtk_selection_owner_set (clipboard, GDK_SELECTION_PRIMARY, GDK_CURRENT_TIME);
gdk_threads_leave ();
}
static gint
selection_clear_cb (GtkWidget *widget __attribute__((unused)),
GdkEventSelection *event __attribute__((unused)))
{
gdk_threads_leave ();
(*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), cb_obj, selectionClearID);
gdk_threads_enter ();
return TRUE;
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,82 @@
/* gnu_java_awt_peer_gtk_GtkEmbeddedWindowPeer.c -- Native
implementation of GtkEmbeddedWindowPeer
Copyright (C) 2003 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"
#include "gnu_java_awt_peer_gtk_GtkEmbeddedWindowPeer.h"
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkEmbeddedWindowPeer_create
(JNIEnv *env, jobject obj, jlong socket_id)
{
GtkWidget *window;
GtkWidget *fixed;
gdk_threads_enter ();
NSA_SET_GLOBAL_REF (env, obj);
window = gtk_plug_new ((GdkNativeWindow) socket_id);
fixed = gtk_fixed_new ();
gtk_container_add (GTK_CONTAINER (window), fixed);
gtk_widget_show (fixed);
NSA_SET_PTR (env, obj, window);
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkEmbeddedWindowPeer_construct
(JNIEnv *env, jobject obj, jlong socket_id)
{
void *ptr;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
if (GTK_WIDGET_REALIZED (GTK_WIDGET (ptr)))
g_printerr ("ERROR: GtkPlug is already realized\n");
gtk_plug_construct (GTK_PLUG (ptr), (GdkNativeWindow) socket_id);
gdk_threads_leave ();
}
@@ -0,0 +1,281 @@
/* gtkfiledialogpeer.c -- Native implementation of GtkFileDialogPeer
Copyright (C) 1998, 1999, 2002, 2004 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"
#include "gnu_java_awt_peer_gtk_GtkComponentPeer.h"
#include "gnu_java_awt_peer_gtk_GtkFileDialogPeer.h"
static void handle_response_cb (GtkDialog *dialog,
gint responseId,
jobject peer_obj);
/*
* Make a new file selection dialog
*/
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkFileDialogPeer_create
(JNIEnv *env, jobject obj, jobject parent)
{
void *parentp;
gpointer widget;
gdk_threads_enter ();
/* Create global reference and save it for future use */
NSA_SET_GLOBAL_REF (env, obj);
parentp = NSA_GET_PTR(env, parent);
/* FIXME: we should be using the default gnome-vfs backend but it is
not currently thread-safe. See:
http://bugzilla.gnome.org/show_bug.cgi?id=166852 */
widget = gtk_file_chooser_dialog_new_with_backend
("Open File",
GTK_WINDOW(parentp),
GTK_FILE_CHOOSER_ACTION_OPEN,
"gtk+",
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
NULL);
/* GtkFileSelect is not modal by default */
gtk_window_set_modal (GTK_WINDOW (widget), TRUE);
/* We must add this window to the group so input in the others are
disable while it is being shown */
gtk_window_group_add_window (cp_gtk_global_window_group,
GTK_WINDOW (widget));
NSA_SET_PTR (env, obj, widget);
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkFileDialogPeer_connectSignals
(JNIEnv *env, jobject obj)
{
void *ptr = NULL;
jobject *gref = NULL;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
gref = NSA_GET_GLOBAL_REF (env, obj);
/* FileDialog signals */
g_signal_connect (G_OBJECT (ptr), "response",
G_CALLBACK (handle_response_cb), *gref);
/* Component signals */
cp_gtk_component_connect_signals (G_OBJECT (ptr), gref);
gdk_threads_leave ();
}
JNIEXPORT jstring JNICALL
Java_gnu_java_awt_peer_gtk_GtkFileDialogPeer_nativeGetDirectory
(JNIEnv *env, jobject obj)
{
void *ptr;
const char *str;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
str = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER(ptr));
gdk_threads_leave ();
return (*env)->NewStringUTF(env, str);
}
/* This function interfaces with the Java callback method of the same name.
This function extracts the filename from the GtkFileFilterInfo object,
and passes it to the Java method. The Java method will call the filter's
accept() method and will give back the return value. */
static gboolean filenameFilterCallback (const GtkFileFilterInfo *filter_info,
gpointer obj)
{
jclass cx;
jmethodID id;
jstring *filename;
gboolean accepted;
cx = (*cp_gtk_gdk_env())->GetObjectClass (cp_gtk_gdk_env(), (jobject) obj);
id = (*cp_gtk_gdk_env())->GetMethodID (cp_gtk_gdk_env(), cx, "filenameFilterCallback",
"(Ljava/lang/String;)Z");
filename = (*cp_gtk_gdk_env())->NewStringUTF(cp_gtk_gdk_env(), filter_info->filename);
gdk_threads_leave();
accepted = (*cp_gtk_gdk_env())->CallBooleanMethod(cp_gtk_gdk_env(), obj, id, filename);
gdk_threads_enter();
return accepted;
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkFileDialogPeer_nativeSetFilenameFilter
(JNIEnv *env, jobject obj, jobject filter_obj __attribute__((unused)))
{
void *ptr;
GtkFileFilter *filter;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
filter = gtk_file_filter_new();
gtk_file_filter_add_custom(filter, GTK_FILE_FILTER_FILENAME,
filenameFilterCallback, obj, NULL);
gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(ptr), filter);
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkFileDialogPeer_nativeSetDirectory
(JNIEnv *env, jobject obj, jstring directory)
{
void *ptr;
const char *str;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
str = (*env)->GetStringUTFChars (env, directory, 0);
gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER(ptr), str);
(*env)->ReleaseStringUTFChars (env, directory, str);
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkFileDialogPeer_nativeSetFile
(JNIEnv *env, jobject obj, jstring filename)
{
void *ptr;
const char *str;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
str = (*env)->GetStringUTFChars (env, filename, 0);
gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (ptr), str);
(*env)->ReleaseStringUTFChars (env, filename, str);
gdk_threads_leave ();
}
static void
handle_response_cb (GtkDialog *dialog __attribute__((unused)),
gint responseId,
jobject peer_obj)
{
static int isDisposeIDSet = 0;
static int isIDSet = 0;
static jmethodID gtkSetFilenameID;
static jmethodID hideID;
static jmethodID disposeID;
void *ptr;
G_CONST_RETURN gchar *fileName;
jstring str_fileName = NULL;
/* We only need this for the case when the user closed the window,
or clicked ok or cancel. */
if (responseId != GTK_RESPONSE_DELETE_EVENT
&& responseId != GTK_RESPONSE_ACCEPT
&& responseId != GTK_RESPONSE_CANCEL)
return;
ptr = NSA_GET_PTR (cp_gtk_gdk_env(), peer_obj);
if (responseId == GTK_RESPONSE_DELETE_EVENT)
{
if (!isDisposeIDSet)
{
jclass cx = (*cp_gtk_gdk_env())->GetObjectClass (cp_gtk_gdk_env(), peer_obj);
disposeID = (*cp_gtk_gdk_env())->GetMethodID (cp_gtk_gdk_env(), cx, "gtkDisposeFileDialog", "()V");
isDisposeIDSet = 1;
}
/* We can dispose of the dialog now (and unblock show) */
gdk_threads_leave ();
(*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer_obj, disposeID);
gdk_threads_enter ();
return;
}
if (responseId == GTK_RESPONSE_ACCEPT) {
fileName = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (GTK_WIDGET (ptr)));
str_fileName = (*cp_gtk_gdk_env())->NewStringUTF (cp_gtk_gdk_env(), fileName);
}
if (!isIDSet)
{
jclass cx = (*cp_gtk_gdk_env())->GetObjectClass (cp_gtk_gdk_env(), peer_obj);
hideID = (*cp_gtk_gdk_env())->GetMethodID (cp_gtk_gdk_env(), cx, "gtkHideFileDialog", "()V");
gtkSetFilenameID = (*cp_gtk_gdk_env())->GetMethodID (cp_gtk_gdk_env(), cx,
"gtkSetFilename", "(Ljava/lang/String;)V");
isIDSet = 1;
}
/* Set the Java object field 'file' with this value. */
gdk_threads_leave ();
(*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer_obj, gtkSetFilenameID, str_fileName);
/* We can hide the dialog now (and unblock show) */
(*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer_obj, hideID);
gdk_threads_enter ();
}
@@ -0,0 +1,180 @@
/* gtkframepeer.c -- Native implementation of GtkFramePeer
Copyright (C) 1998, 1999, 2002 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"
#include "gnu_java_awt_peer_gtk_GtkFramePeer.h"
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkFramePeer_removeMenuBarPeer
(JNIEnv *env, jobject obj)
{
void *ptr;
void *mptr;
void *fixed;
GList* children;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
fixed = gtk_container_get_children (GTK_CONTAINER (ptr))->data;
children = gtk_container_get_children (GTK_CONTAINER (fixed));
while (children != NULL && !GTK_IS_MENU_SHELL (children->data))
{
children = children->next;
}
/* If there's a menu bar, remove it. */
if (children != NULL)
{
mptr = children->data;
/* This will actually destroy the MenuBar. By removing it from
its parent, the reference count for the MenuBar widget will
decrement to 0. The widget will be automatically destroyed by
GTK. */
gtk_container_remove (GTK_CONTAINER (fixed), GTK_WIDGET (mptr));
}
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkFramePeer_setMenuBarPeer
(JNIEnv *env, jobject obj, jobject menubar)
{
void *ptr;
void *mptr;
void *fixed;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
mptr = NSA_GET_PTR (env, menubar);
fixed = gtk_container_get_children (GTK_CONTAINER (ptr))->data;
gtk_fixed_put (GTK_FIXED (fixed), mptr, 0, 0);
gtk_widget_show (mptr);
gdk_threads_leave ();
}
JNIEXPORT jint JNICALL
Java_gnu_java_awt_peer_gtk_GtkFramePeer_getMenuBarHeight
(JNIEnv *env, jobject obj __attribute__((unused)), jobject menubar)
{
GtkWidget *ptr;
GtkRequisition requisition;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, menubar);
gtk_widget_size_request (ptr, &requisition);
gdk_threads_leave ();
return requisition.height;
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkFramePeer_setMenuBarWidth
(JNIEnv *env, jobject obj __attribute__((unused)), jobject menubar, jint width)
{
GtkWidget *ptr;
GtkRequisition natural_req;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, menubar);
/* Get the menubar's natural size request. */
gtk_widget_set_size_request (GTK_WIDGET (ptr), -1, -1);
gtk_widget_size_request (GTK_WIDGET (ptr), &natural_req);
/* Set the menubar's size request to width by natural_req.height. */
gtk_widget_set_size_request (GTK_WIDGET (ptr),
width, natural_req.height);
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkFramePeer_gtkFixedSetVisible
(JNIEnv *env, jobject obj, jboolean visible)
{
void *ptr;
void *fixed;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
fixed = gtk_container_get_children (GTK_CONTAINER (ptr))->data;
if (visible)
gtk_widget_show (GTK_WIDGET (fixed));
else
gtk_widget_hide (GTK_WIDGET (fixed));
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkFramePeer_nativeSetIconImage
(JNIEnv *env, jobject obj, jobject gtkimage)
{
void *ptr;
GdkPixbuf *pixbuf = NULL;
gdk_threads_enter ();
pixbuf = cp_gtk_image_get_pixbuf (env, gtkimage);
g_assert (pixbuf != NULL);
ptr = NSA_GET_PTR (env, obj);
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 ();
}
@@ -0,0 +1,101 @@
/* gtkgenericpeer.c -- Native implementation of GtkGenericPeer
Copyright (C) 1998, 1999, 2002, 2004 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"
#include "gnu_java_awt_peer_gtk_GtkGenericPeer.h"
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkGenericPeer_dispose
(JNIEnv *env, jobject obj)
{
void *ptr;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
/* For now the native state for any object must be a widget.
However, a subclass could override dispose() if required. */
gtk_widget_destroy (GTK_WIDGET (ptr));
/* Remove entries from state tables */
NSA_DEL_GLOBAL_REF (env, obj);
NSA_DEL_PTR (env, obj);
gdk_threads_leave ();
/*
* Wake up the main thread, to make sure it re-checks the window
* destruction condition.
*/
g_main_context_wakeup (NULL);
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkGenericPeer_gtkWidgetModifyFont
(JNIEnv *env, jobject obj, jstring name, jint style, jint size)
{
const char *font_name;
void *ptr;
PangoFontDescription *font_desc;
gdk_threads_enter();
ptr = NSA_GET_PTR (env, obj);
font_name = (*env)->GetStringUTFChars (env, name, NULL);
font_desc = pango_font_description_from_string (font_name);
pango_font_description_set_size (font_desc,
size * cp_gtk_dpi_conversion_factor);
if (style & AWT_STYLE_BOLD)
pango_font_description_set_weight (font_desc, PANGO_WEIGHT_BOLD);
if (style & AWT_STYLE_ITALIC)
pango_font_description_set_style (font_desc, PANGO_STYLE_OBLIQUE);
gtk_widget_modify_font (GTK_WIDGET(ptr), font_desc);
pango_font_description_free (font_desc);
(*env)->ReleaseStringUTFChars (env, name, font_name);
gdk_threads_leave();
}
@@ -0,0 +1,621 @@
/* gtkimage.c
Copyright (C) 2005 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"
#include "gnu_java_awt_peer_gtk_GtkImage.h"
#include <gdk-pixbuf/gdk-pixbuf.h>
/* The constant fields in java.awt.Image */
#define SCALE_DEFAULT 1
#define SCALE_FAST 2
#define SCALE_SMOOTH 4
#define SCALE_REPLICATE 8
#define SCALE_AREA_AVERAGING 16
/* 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.
*/
JNIEXPORT jboolean JNICALL
Java_gnu_java_awt_peer_gtk_GtkImage_loadPixbuf
(JNIEnv *env, jobject obj, jstring name)
{
const char *filename;
int width, height;
GdkPixbuf *pixbuf;
gdk_threads_enter ();
/* Don't use the JCL convert function because it throws an exception
on failure */
filename = (*env)->GetStringUTFChars (env, name, 0);
if (filename == NULL)
{
gdk_threads_leave ();
return JNI_FALSE;
}
pixbuf = gdk_pixbuf_new_from_file (filename, NULL);
if (pixbuf == NULL)
{
(*env)->ReleaseStringUTFChars (env, name, filename);
gdk_threads_leave ();
return JNI_FALSE;
}
width = gdk_pixbuf_get_width (pixbuf);
height = gdk_pixbuf_get_height (pixbuf);
createRawData (env, obj, pixbuf);
setWidthHeight(env, obj, width, height);
(*env)->ReleaseStringUTFChars (env, name, filename);
gdk_threads_leave ();
return JNI_TRUE;
}
/**
* Returns a copy of the pixel data as a java array.
*/
JNIEXPORT jintArray JNICALL
Java_gnu_java_awt_peer_gtk_GtkImage_getPixels(JNIEnv *env, jobject obj)
{
GdkPixbuf *pixbuf;
int width, height, rowstride;
guchar *pixeldata;
jintArray result_array;
jint *result_array_iter, *dst;
int i,j;
gdk_threads_enter ();
pixbuf = cp_gtk_image_get_pixbuf (env, obj);
width = gdk_pixbuf_get_width (pixbuf);
height = gdk_pixbuf_get_height (pixbuf);
rowstride = gdk_pixbuf_get_rowstride (pixbuf);
/* Must release the GDK lock before allocating memory through the
JVM, since some JVMs use the same lock for allocations and
finalization. Deadlock can occur on those JVMs. */
gdk_threads_leave ();
result_array = (*env)->NewIntArray (env, (width * height));
gdk_threads_enter ();
dst = result_array_iter =
(*env)->GetIntArrayElements (env, result_array, NULL);
pixeldata = gdk_pixbuf_get_pixels (pixbuf);
g_assert (gdk_pixbuf_get_bits_per_sample (pixbuf) == 8);
if (gdk_pixbuf_get_has_alpha (pixbuf))
{
for(i = 0 ; i < height; i++)
{
memcpy(dst, (void *)pixeldata, width * 4);
dst += width;
pixeldata += rowstride;
}
} else {
for(i = 0; i < height; i++)
{
for(j = 0; j < width; j++)
dst[j] = 0xFF000000 |
(pixeldata[j*3 + 2] & 0xFF) << 16 |
(pixeldata[j*3 + 1] & 0xFF) << 8 |
(pixeldata[j*3] & 0xFF);
dst += width;
pixeldata += rowstride;
}
}
if (offScreen (env, obj) == JNI_TRUE)
gdk_pixbuf_unref (pixbuf);
(*env)->ReleaseIntArrayElements (env, result_array, result_array_iter, 0);
gdk_threads_leave ();
return result_array;
}
/**
* Returns a copy of the pixel data as a java array.
* (GdkPixbuf only)
*/
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkImage_setPixels(JNIEnv *env, jobject obj,
jintArray pixels)
{
GdkPixbuf *pixbuf = (GdkPixbuf *)getData (env, obj);
int width, height, rowstride;
guchar *pixeldata;
jint *src_array_iter, *src;
int i;
gdk_threads_enter ();
width = gdk_pixbuf_get_width (pixbuf);
height = gdk_pixbuf_get_height (pixbuf);
rowstride = gdk_pixbuf_get_rowstride (pixbuf);
src = src_array_iter =
(*env)->GetIntArrayElements (env, pixels, NULL);
pixeldata = gdk_pixbuf_get_pixels (pixbuf);
for(i = 0 ; i < height; i++)
{
memcpy((void *)pixeldata, (void *)src, width * 4);
src += width;
pixeldata += rowstride;
}
(*env)->ReleaseIntArrayElements (env, pixels, src_array_iter, 0);
gdk_threads_leave ();
}
/**
* Allocates a Gtk Pixbuf or Pixmap.
*/
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkImage_createPixmap(JNIEnv *env, jobject obj)
{
int width, height;
jclass cls;
jfieldID field;
gdk_threads_enter ();
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);
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));
gdk_threads_leave ();
}
/**
* Frees the Gtk Pixmap.
*/
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkImage_freePixmap(JNIEnv *env, jobject obj)
{
gdk_threads_enter ();
if (offScreen (env, obj) == JNI_FALSE)
gdk_pixbuf_unref ((GdkPixbuf *)getData (env, obj));
else
gdk_pixmap_unref ((GdkPixmap *)getData (env, obj));
gdk_threads_leave ();
}
/**
* Sets this pixmap to a scaled version of the source pixmap.
* width and height of the destination GtkImage must be set.
*/
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkImage_createScaledPixmap(JNIEnv *env,
jobject destination,
jobject source,
jint hints)
{
GdkPixbuf* dst;
int width, height;
jclass cls;
jfieldID field;
GdkPixbuf *pixbuf;
gdk_threads_enter ();
cls = (*env)->GetObjectClass (env, destination);
field = (*env)->GetFieldID (env, cls, "width", "I");
g_assert (field != 0);
width = (*env)->GetIntField (env, destination, field);
field = (*env)->GetFieldID (env, cls, "height", "I");
g_assert (field != 0);
height = (*env)->GetIntField (env, destination, field);
pixbuf = cp_gtk_image_get_pixbuf (env, source);
dst = gdk_pixbuf_scale_simple(pixbuf,
width, height,
mapHints(hints));
if (offScreen (env, source) == JNI_TRUE)
gdk_pixbuf_unref (pixbuf);
createRawData (env, destination, (void *)dst);
gdk_threads_leave ();
}
/**
* 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 graphics *g;
guint32 bgColor;
gdk_threads_enter ();
bgColor = ((bg_red & 0xFF) << 16) |
((bg_green & 0xFF) << 8) | (bg_blue & 0xFF);
g = (struct graphics *) NSA_GET_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_draw_pixbuf (g->drawable,
g->gc,
dst,
0, 0,
x + g->x_offset, y + g->y_offset,
width, height,
GDK_RGB_DITHER_NORMAL, 0, 0);
gdk_pixbuf_unref (dst);
} else {
/* Get a pixmap */
GdkPixmap* pixmap = (GdkPixmap *)getData (env, obj);
gdk_draw_drawable (g->drawable,
g->gc,
pixmap,
0, 0, /* src x,y */
x + g->x_offset, y + g->y_offset,
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,
jboolean flipx, jboolean flipy,
jint srcx, jint srcy, jint srcwidth, jint srcheight,
jint dstx, jint dsty, jint dstwidth, jint dstheight,
jboolean composite)
{
GdkPixbuf *pixbuf;
GdkPixbuf *tmp, *dst;
struct graphics *g;
guint32 bgColor;
gdk_threads_enter ();
bgColor = ((bg_red & 0xFF) << 16) |
((bg_green & 0xFF) << 8) | (bg_blue & 0xFF);
g = (struct graphics *) NSA_GET_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_draw_pixbuf (g->drawable,
g->gc,
dst,
0, 0,
dstx + g->x_offset, dsty + g->y_offset,
dstwidth, dstheight,
GDK_RGB_DITHER_NORMAL, 0, 0);
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);
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);
}
jboolean cp_gtk_image_is_offscreen (JNIEnv *env, jobject obj)
{
return offScreen(env, obj);
}
/**
* Maps java.awt.Image scaling hints to the native GDK ones.
*/
static GdkInterpType mapHints(jint hints)
{
switch ( hints )
{
/* For FAST, we use the nearest-neighbor. Fastest and lowest quality. */
case SCALE_FAST:
case SCALE_REPLICATE:
return GDK_INTERP_NEAREST;
/* Hyperbolic for smooth. Slowest too. */
case SCALE_SMOOTH:
return GDK_INTERP_HYPER;
/* the inbetweenish method */
case SCALE_AREA_AVERAGING:
return GDK_INTERP_TILES;
/* default to bilinear */
}
return GDK_INTERP_BILINEAR;
}
/* Sets the width and height fields of a GtkImage object. */
static void setWidthHeight (JNIEnv * env, jobject obj, int width, int height)
{
jclass cls;
jfieldID field;
cls = (*env)->GetObjectClass (env, obj);
g_assert (cls != 0);
field = (*env)->GetFieldID (env, cls, "width", "I");
g_assert (field != 0);
(*env)->SetIntField (env, obj, field, (jint)width);
field = (*env)->GetFieldID (env, cls, "height", "I");
g_assert (field != 0);
(*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)
{
jclass cls;
jmethodID method;
jobject data;
jfieldID data_fid;
cls = (*env)->GetObjectClass (env, obj);
data_fid = (*env)->GetFieldID (env, cls, "pixmap",
"Lgnu/classpath/RawData;");
g_assert (data_fid != 0);
#if SIZEOF_VOID_P == 8
cls = (*env)->FindClass (env, "gnu/classpath/RawData64");
method = (*env)->GetMethodID (env, cls, "<init>", "(J)V");
data = (*env)->NewObject (env, cls, method, (jlong) ptr);
#else
cls = (*env)->FindClass (env, "gnu/classpath/RawData32");
method = (*env)->GetMethodID (env, cls, "<init>", "(I)V");
data = (*env)->NewObject (env, cls, method, (jint) ptr);
#endif
(*env)->SetObjectField (env, obj, data_fid, data);
}
static void *
getData (JNIEnv * env, jobject obj)
{
jclass cls;
jfieldID field;
jfieldID data_fid;
jobject data;
cls = (*env)->GetObjectClass (env, obj);
data_fid = (*env)->GetFieldID (env, cls, "pixmap",
"Lgnu/classpath/RawData;");
g_assert (data_fid != 0);
data = (*env)->GetObjectField (env, obj, data_fid);
#if SIZEOF_VOID_P == 8
cls = (*env)->FindClass (env, "gnu/classpath/RawData64");
field = (*env)->GetFieldID (env, cls, "data", "J");
return (void *) (*env)->GetLongField (env, data, field);
#else
cls = (*env)->FindClass (env, "gnu/classpath/RawData32");
field = (*env)->GetFieldID (env, cls, "data", "I");
return (void *) (*env)->GetIntField (env, data, field);
#endif
}
@@ -0,0 +1,183 @@
/* gtklabelpeer.c -- Native implementation of GtkLabelPeer
Copyright (C) 1998, 1999 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"
#include "gnu_java_awt_peer_gtk_GtkLabelPeer.h"
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkLabelPeer_create
(JNIEnv *env, jobject obj, jstring text, jfloat xalign)
{
GtkWidget *label;
GtkWidget *eventbox;
const char *str;
gdk_threads_enter ();
NSA_SET_GLOBAL_REF (env, obj);
str = (*env)->GetStringUTFChars (env, text, 0);
eventbox = gtk_event_box_new ();
label = gtk_label_new (str);
gtk_misc_set_alignment (GTK_MISC (label), xalign, 0.5);
gtk_container_add (GTK_CONTAINER (eventbox), label);
gtk_widget_show (label);
(*env)->ReleaseStringUTFChars (env, text, str);
NSA_SET_PTR (env, obj, eventbox);
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkLabelPeer_gtkWidgetModifyFont
(JNIEnv *env, jobject obj, jstring name, jint style, jint size)
{
const char *font_name;
void *ptr;
GtkWidget *label;
PangoFontDescription *font_desc;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
font_name = (*env)->GetStringUTFChars (env, name, NULL);
label = gtk_bin_get_child (GTK_BIN (ptr));
if (!label)
{
gdk_threads_leave ();
return;
}
font_desc = pango_font_description_from_string (font_name);
pango_font_description_set_size (font_desc,
size * cp_gtk_dpi_conversion_factor);
if (style & AWT_STYLE_BOLD)
pango_font_description_set_weight (font_desc, PANGO_WEIGHT_BOLD);
if (style & AWT_STYLE_ITALIC)
pango_font_description_set_style (font_desc, PANGO_STYLE_OBLIQUE);
gtk_widget_modify_font (GTK_WIDGET (label), font_desc);
pango_font_description_free (font_desc);
(*env)->ReleaseStringUTFChars (env, name, font_name);
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkLabelPeer_setText
(JNIEnv *env, jobject obj, jstring text)
{
const char *str;
void *ptr;
GtkWidget *label;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
str = (*env)->GetStringUTFChars (env, text, 0);
label = gtk_bin_get_child (GTK_BIN (ptr));
gtk_label_set_label (GTK_LABEL (label), str);
(*env)->ReleaseStringUTFChars (env, text, str);
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkLabelPeer_nativeSetAlignment
(JNIEnv *env, jobject obj, jfloat xalign)
{
void *ptr;
GtkWidget *label;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
label = gtk_bin_get_child (GTK_BIN(ptr));
gtk_misc_set_alignment (GTK_MISC (label), xalign, 0.5);
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkLabelPeer_setNativeBounds
(JNIEnv *env, jobject obj, jint x, jint y, jint width, jint height)
{
GtkWidget *widget;
void *ptr;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
widget = GTK_WIDGET (ptr);
/* We assume that -1 is a width or height and not a request for the
widget's natural size. */
width = width < 0 ? 0 : width;
height = height < 0 ? 0 : height;
if (!(width == 0 && height == 0))
{
/* Set the event box's size request... */
gtk_widget_set_size_request (widget, width, height);
/* ...and the label's size request. */
gtk_widget_set_size_request (gtk_bin_get_child (GTK_BIN (widget)),
width, height);
if (widget->parent != NULL)
gtk_fixed_move (GTK_FIXED (widget->parent), widget, x, y);
}
gdk_threads_leave ();
}
@@ -0,0 +1,539 @@
/* GtkListPeer.c -- implements GtkListPeer's native methods
Copyright (C) 1998, 1999, 2003, 2004 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"
#include "gnu_java_awt_peer_gtk_GtkListPeer.h"
static jmethodID postListItemEventID;
void
cp_gtk_list_init_jni (void)
{
jclass gtklistpeer;
gtklistpeer = (*cp_gtk_gdk_env())->FindClass (cp_gtk_gdk_env(),
"gnu/java/awt/peer/gtk/GtkListPeer");
postListItemEventID = (*cp_gtk_gdk_env())->GetMethodID (cp_gtk_gdk_env(), gtklistpeer,
"postItemEvent",
"(II)V");
}
enum
{
COLUMN_STRING,
N_COLUMNS
};
static gboolean item_highlighted_cb (GtkTreeSelection *selection,
GtkTreeModel *model,
GtkTreePath *path,
gboolean path_currently_selected,
jobject peer);
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkListPeer_create
(JNIEnv *env, jobject obj, jint rows)
{
GtkWidget *sw;
GtkWidget *list;
GtkCellRenderer *renderer;
GtkTreeViewColumn *column;
GtkListStore *list_store;
GtkTreeIter iter;
GtkRequisition req;
gint i;
gdk_threads_enter ();
/* Create global reference and save it for future use */
NSA_SET_GLOBAL_REF (env, obj);
list_store = gtk_list_store_new (N_COLUMNS, G_TYPE_STRING);
/* Add the number of rows so that we can calculate the tree view's
size request. */
for (i = 0; i < rows; i++)
{
gtk_list_store_append (list_store, &iter);
gtk_list_store_set (list_store, &iter,
COLUMN_STRING, "",
-1);
}
list = gtk_tree_view_new_with_model (GTK_TREE_MODEL (list_store));
renderer = gtk_cell_renderer_text_new ();
column = gtk_tree_view_column_new_with_attributes (NULL,
renderer,
"text",
COLUMN_STRING,
NULL);
sw = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
GTK_POLICY_AUTOMATIC,
GTK_POLICY_AUTOMATIC);
gtk_tree_view_append_column (GTK_TREE_VIEW (list), column);
gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (list), FALSE);
gtk_widget_size_request (GTK_WIDGET (list), &req);
gtk_widget_set_size_request (GTK_WIDGET (list), req.width, req.height);
gtk_container_add (GTK_CONTAINER (sw), list);
/* Remove the blank rows. */
gtk_list_store_clear (list_store);
gtk_widget_show (list);
gtk_widget_show (sw);
NSA_SET_PTR (env, obj, sw);
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkListPeer_connectSignals
(JNIEnv *env, jobject obj)
{
void *ptr;
jobject *gref;
GtkWidget *list;
GtkTreeSelection *selection;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
gref = NSA_GET_GLOBAL_REF (env, obj);
list = gtk_bin_get_child (GTK_BIN (ptr));
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (list));
gtk_tree_selection_set_select_function (selection, item_highlighted_cb,
*gref, NULL);
cp_gtk_component_connect_signals (G_OBJECT (list), gref);
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkListPeer_gtkWidgetModifyFont
(JNIEnv *env, jobject obj, jstring name, jint style, jint size)
{
const char *font_name;
void *ptr;
GtkWidget *list;
PangoFontDescription *font_desc;
gdk_threads_enter();
ptr = NSA_GET_PTR (env, obj);
list = gtk_bin_get_child (GTK_BIN (ptr));
font_name = (*env)->GetStringUTFChars (env, name, NULL);
font_desc = pango_font_description_from_string (font_name);
pango_font_description_set_size (font_desc,
size * cp_gtk_dpi_conversion_factor);
if (style & AWT_STYLE_BOLD)
pango_font_description_set_weight (font_desc, PANGO_WEIGHT_BOLD);
if (style & AWT_STYLE_ITALIC)
pango_font_description_set_style (font_desc, PANGO_STYLE_OBLIQUE);
gtk_widget_modify_font (GTK_WIDGET (list), font_desc);
pango_font_description_free (font_desc);
(*env)->ReleaseStringUTFChars (env, name, font_name);
gdk_threads_leave();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkListPeer_gtkWidgetRequestFocus
(JNIEnv *env, jobject obj)
{
void *ptr;
GtkWidget *list;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
list = gtk_bin_get_child (GTK_BIN (ptr));
gtk_widget_grab_focus (list);
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkListPeer_append
(JNIEnv *env, jobject obj, jobjectArray items)
{
void *ptr;
GtkWidget *list;
GtkTreeIter iter;
GtkTreeModel *list_store;
jint count;
jint i;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
count = (*env)->GetArrayLength (env, items);
list = gtk_bin_get_child (GTK_BIN (ptr));
list_store = gtk_tree_view_get_model (GTK_TREE_VIEW (list));
for (i = 0; i < count; i++)
{
const char *text;
jobject item;
item = (*env)->GetObjectArrayElement (env, items, i);
text = (*env)->GetStringUTFChars (env, item, NULL);
gtk_list_store_append (GTK_LIST_STORE (list_store), &iter);
gtk_list_store_set (GTK_LIST_STORE (list_store), &iter,
COLUMN_STRING, text,
-1);
(*env)->ReleaseStringUTFChars (env, item, text);
}
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkListPeer_add
(JNIEnv *env, jobject obj, jstring text, jint index)
{
void *ptr;
const char *str;
GtkWidget *list;
GtkTreeIter iter;
GtkTreeModel *list_store;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
str = (*env)->GetStringUTFChars (env, text, NULL);
list = gtk_bin_get_child (GTK_BIN (ptr));
list_store = gtk_tree_view_get_model (GTK_TREE_VIEW (list));
if (index == -1)
gtk_list_store_append (GTK_LIST_STORE (list_store), &iter);
else
gtk_list_store_insert (GTK_LIST_STORE (list_store), &iter, index);
gtk_list_store_set (GTK_LIST_STORE (list_store), &iter,
COLUMN_STRING, str, -1);
(*env)->ReleaseStringUTFChars (env, text, str);
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkListPeer_delItems
(JNIEnv *env, jobject obj, jint start, jint end)
{
void *ptr;
GtkWidget *list;
GtkTreeIter iter;
GtkTreeModel *list_store;
jint i;
jint num_items;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
list = gtk_bin_get_child (GTK_BIN (ptr));
list_store = gtk_tree_view_get_model (GTK_TREE_VIEW (list));
/* Special case: remove all rows. */
if (end == -1)
gtk_list_store_clear (GTK_LIST_STORE (list_store));
else
{
i = 0;
num_items = end - start + 1;
gtk_tree_model_iter_nth_child (list_store, &iter, NULL, start);
while (i < num_items)
{
gtk_list_store_remove (GTK_LIST_STORE (list_store), &iter);
i++;
}
}
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkListPeer_select
(JNIEnv *env, jobject obj, jint index)
{
void *ptr;
GtkWidget *list;
GtkTreePath *path;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
list = gtk_bin_get_child (GTK_BIN (ptr));
path = gtk_tree_path_new_from_indices (index, -1);
gtk_tree_view_set_cursor (GTK_TREE_VIEW (list), path, NULL, FALSE);
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkListPeer_deselect
(JNIEnv *env, jobject obj, jint index)
{
void *ptr;
GtkWidget *list;
GtkTreeSelection *selection;
GtkTreePath *path;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
list = gtk_bin_get_child (GTK_BIN (ptr));
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (list));
path = gtk_tree_path_new_from_indices (index, -1);
gtk_tree_selection_unselect_path (selection, path);
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkListPeer_getSize
(JNIEnv *env, jobject obj, jint rows, jint visible_rows, jintArray jdims)
{
void *ptr;
jint *dims;
GtkRequisition current_req;
GtkRequisition natural_req;
gdk_threads_enter ();
dims = (*env)->GetIntArrayElements (env, jdims, NULL);
dims[0] = dims[1] = 0;
ptr = NSA_GET_PTR (env, obj);
/* Save the widget's current size request. */
gtk_widget_size_request (GTK_WIDGET (ptr), &current_req);
/* Get the widget's "natural" size request. */
gtk_widget_set_size_request (GTK_WIDGET (ptr), -1, -1);
gtk_widget_size_request (GTK_WIDGET (ptr), &natural_req);
/* Reset the widget's size request. */
gtk_widget_set_size_request (GTK_WIDGET (ptr),
current_req.width, current_req.height);
dims[0] = natural_req.width;
/* Calculate the final height, by comparing the number of rows
in the list to the number of rows requested by the caller.
FIXME: Is there a GTK method that counts the number of rows
in the list? If so, we don't need to bring visible_rows from
the Java peer. */
if (rows == visible_rows)
dims[1] = natural_req.height;
else
dims[1] = natural_req.height / visible_rows * rows;
(*env)->ReleaseIntArrayElements (env, jdims, dims, 0);
gdk_threads_leave ();
}
JNIEXPORT jintArray JNICALL
Java_gnu_java_awt_peer_gtk_GtkListPeer_getSelectedIndexes
(JNIEnv *env, jobject obj)
{
void *ptr;
GtkWidget *list;
GtkTreeSelection *selection;
jintArray result_array;
jint *result_array_iter;
GList *current_row;
GList *rows;
gint *indices;
jint count;
jint i;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
list = gtk_bin_get_child (GTK_BIN (ptr));
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (list));
count = gtk_tree_selection_count_selected_rows (selection);
if (count > 0)
{
current_row = rows = gtk_tree_selection_get_selected_rows (selection, NULL);
gdk_threads_leave ();
result_array = (*env)->NewIntArray (env, count);
gdk_threads_enter ();
result_array_iter = (*env)->GetIntArrayElements (env, result_array, NULL);
for (i = 0; i < count; i++)
{
indices = gtk_tree_path_get_indices (current_row->data);
result_array_iter[i] = indices ? indices[0] : -1;
current_row = g_list_next (current_row);
}
if (rows)
{
g_list_foreach (rows, (GFunc) gtk_tree_path_free, NULL);
g_list_free (rows);
}
(*env)->ReleaseIntArrayElements (env, result_array, result_array_iter, 0);
}
else
result_array = NULL;
gdk_threads_leave ();
return result_array;
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkListPeer_makeVisible
(JNIEnv *env, jobject obj, jint index)
{
void *ptr;
GtkWidget *list;
GtkTreePath *path;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
list = gtk_bin_get_child (GTK_BIN (ptr));
path = gtk_tree_path_new_from_indices (index, -1);
gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (list), path,
NULL, FALSE, 0.0, 0.0);
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkListPeer_setMultipleMode
(JNIEnv *env, jobject obj, jboolean mode)
{
void *ptr;
GtkWidget *list;
GtkTreeSelection *selection;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
list = gtk_bin_get_child (GTK_BIN (ptr));
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (list));
gtk_tree_selection_set_mode (selection,
mode ? GTK_SELECTION_MULTIPLE
: GTK_SELECTION_SINGLE);
gdk_threads_leave ();
}
static gboolean
item_highlighted_cb (GtkTreeSelection *selection __attribute__((unused)),
GtkTreeModel *model,
GtkTreePath *path,
gboolean path_currently_selected,
jobject peer)
{
GtkTreeIter iter;
jint row;
gint *indices;
if (gtk_tree_model_get_iter (model, &iter, path))
{
indices = gtk_tree_path_get_indices (path);
row = indices ? indices[0] : -1;
if (!path_currently_selected)
{
gdk_threads_leave ();
(*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer,
postListItemEventID,
row,
(jint) AWT_ITEM_SELECTED);
gdk_threads_enter ();
}
else
{
gdk_threads_leave ();
(*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer,
postListItemEventID,
row,
(jint) AWT_ITEM_DESELECTED);
gdk_threads_enter ();
}
}
return TRUE;
}
@@ -0,0 +1,118 @@
/* gtkmenubarpeer.c -- Native implementation of GtkMenuBarPeer
Copyright (C) 1999 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"
#include "gnu_java_awt_peer_gtk_GtkMenuBarPeer.h"
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkMenuBarPeer_create
(JNIEnv *env, jobject obj)
{
GtkWidget *widget;
gdk_threads_enter ();
NSA_SET_GLOBAL_REF (env, obj);
widget = gtk_menu_bar_new ();
gtk_widget_show (widget);
NSA_SET_PTR (env, obj, widget);
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkMenuBarPeer_addMenu
(JNIEnv *env, jobject obj, jobject menupeer)
{
void *mbar, *menu;
gdk_threads_enter ();
mbar = NSA_GET_PTR (env, obj);
menu = NSA_GET_PTR (env, menupeer);
gtk_menu_shell_append (GTK_MENU_SHELL (mbar), GTK_WIDGET (menu));
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkMenuBarPeer_nativeSetHelpMenu
(JNIEnv *env, jobject obj, jobject menupeer)
{
static void *helpmenu;
void *mbar, *menu;
GList *list;
gdk_threads_enter ();
mbar = NSA_GET_PTR (env, obj);
menu = NSA_GET_PTR (env, menupeer);
if (helpmenu != NULL)
{
list = gtk_container_children (GTK_CONTAINER (mbar));
while (list != NULL && list->data != helpmenu)
list = list->next;
if (list != NULL && list->data == helpmenu)
gtk_container_remove (GTK_CONTAINER (mbar), GTK_WIDGET (list->data));
}
helpmenu = menu;
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkMenuBarPeer_delMenu
(JNIEnv *env, jobject obj, jint index)
{
void *ptr;
GList *list;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
list = gtk_container_children (GTK_CONTAINER (ptr));
list = g_list_nth (list, index);
gtk_container_remove (GTK_CONTAINER (ptr), GTK_WIDGET (list->data));
gdk_threads_leave ();
}
@@ -0,0 +1,56 @@
/* gtkmenucomponentpeer.c -- Native implementation of GtkMenuComponentPeer
Copyright (C) 2004 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"
#include "gnu_java_awt_peer_gtk_GtkMenuComponentPeer.h"
JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkMenuComponentPeer_dispose
(JNIEnv *env, jobject obj)
{
/* For MenuComponents and its subclasses, the widgets are
automatically destroyed by Gtk when the parent MenuBar
is removed from the Frame. So we avoid the widget
destruction in GtkGenericPeer dispose() by overriding
it here. */
/* However, references to the Java objects still exist in the
state tables, so we still have to remove those. */
NSA_DEL_GLOBAL_REF (env, obj);
NSA_DEL_PTR (env, obj);
}
@@ -0,0 +1,193 @@
/* gtkmenuitempeer.c -- Native implementation of GtkMenuItemPeer
Copyright (C) 1999 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"
#include "gnu_java_awt_peer_gtk_GtkMenuItemPeer.h"
#include "gnu_java_awt_peer_gtk_GtkComponentPeer.h"
static jmethodID postMenuActionEventID;
void
cp_gtk_menuitem_init_jni (void)
{
jclass gtkmenuitempeer;
gtkmenuitempeer = (*cp_gtk_gdk_env())->FindClass (cp_gtk_gdk_env(),
"gnu/java/awt/peer/gtk/GtkMenuItemPeer");
postMenuActionEventID = (*cp_gtk_gdk_env())->GetMethodID (cp_gtk_gdk_env(),
gtkmenuitempeer,
"postMenuActionEvent",
"()V");
}
static void item_activate_cb (GtkMenuItem *item __attribute__((unused)),
jobject peer_obj);
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkMenuItemPeer_create
(JNIEnv *env, jobject obj, jstring label)
{
GtkWidget *widget;
const char *str;
gdk_threads_enter ();
NSA_SET_GLOBAL_REF (env, obj);
str = (*env)->GetStringUTFChars (env, label, NULL);
/* "-" signals that we need a separator. */
if (strcmp (str, "-") == 0)
widget = gtk_menu_item_new ();
else
widget = gtk_menu_item_new_with_label (str);
gtk_widget_show (widget);
(*env)->ReleaseStringUTFChars (env, label, str);
NSA_SET_PTR (env, obj, widget);
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkMenuItemPeer_connectSignals
(JNIEnv *env, jobject obj)
{
void *ptr;
jobject *gref;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
gref = NSA_GET_GLOBAL_REF (env, obj);
g_signal_connect (G_OBJECT (ptr), "activate",
G_CALLBACK (item_activate_cb), *gref);
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkMenuItemPeer_gtkWidgetModifyFont
(JNIEnv *env, jobject obj, jstring name, jint style, jint size)
{
const char *font_name;
void *ptr;
GtkWidget *label;
PangoFontDescription *font_desc;
gdk_threads_enter();
ptr = NSA_GET_PTR (env, obj);
font_name = (*env)->GetStringUTFChars (env, name, NULL);
label = gtk_bin_get_child (GTK_BIN (ptr));
if (label)
{
font_desc = pango_font_description_from_string (font_name);
pango_font_description_set_size (font_desc,
size * cp_gtk_dpi_conversion_factor);
if (style & AWT_STYLE_BOLD)
pango_font_description_set_weight (font_desc, PANGO_WEIGHT_BOLD);
if (style & AWT_STYLE_ITALIC)
pango_font_description_set_style (font_desc, PANGO_STYLE_OBLIQUE);
gtk_widget_modify_font (GTK_WIDGET(label), font_desc);
pango_font_description_free (font_desc);
}
(*env)->ReleaseStringUTFChars (env, name, font_name);
gdk_threads_leave();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkMenuItemPeer_setEnabled
(JNIEnv *env, jobject obj, jboolean enabled)
{
void *ptr;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
gtk_widget_set_sensitive (GTK_WIDGET (ptr), enabled);
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkMenuItemPeer_setLabel
(JNIEnv *env, jobject obj, jstring label)
{
void *ptr;
const char *str;
GtkAccelLabel *accel_label;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
str = (*env)->GetStringUTFChars (env, label, NULL);
accel_label = GTK_ACCEL_LABEL (GTK_BIN (ptr)->child);
gtk_label_set_text (GTK_LABEL (accel_label), str);
gtk_accel_label_refetch (accel_label);
(*env)->ReleaseStringUTFChars (env, label, str);
gdk_threads_leave ();
}
static void
item_activate_cb (GtkMenuItem *item __attribute__((unused)), jobject peer_obj)
{
gdk_threads_leave ();
(*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer_obj,
postMenuActionEventID);
gdk_threads_enter ();
}
@@ -0,0 +1,173 @@
/* gtkmenupeer.c -- Native implementation of GtkMenuPeer
Copyright (C) 1999, 2004 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"
#include "gnu_java_awt_peer_gtk_GtkMenuPeer.h"
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkMenuPeer_setupAccelGroup
(JNIEnv *env, jobject obj, jobject parent)
{
void *ptr1, *ptr2;
gdk_threads_enter ();
ptr1 = NSA_GET_PTR (env, obj);
if (!parent)
{
gtk_menu_set_accel_group (GTK_MENU (GTK_MENU_ITEM (ptr1)->submenu),
gtk_accel_group_new ());
}
else
{
GtkAccelGroup *parent_accel;
ptr2 = NSA_GET_PTR (env, parent);
parent_accel = gtk_menu_get_accel_group (GTK_MENU (GTK_MENU_ITEM (ptr2)->submenu));
gtk_menu_set_accel_group (GTK_MENU (GTK_MENU_ITEM (ptr1)->submenu),
parent_accel);
}
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkMenuPeer_create
(JNIEnv *env, jobject obj, jstring label)
{
GtkWidget *menu_title, *menu, *toplevel;
const char *str;
gdk_threads_enter ();
NSA_SET_GLOBAL_REF (env, obj);
str = (*env)->GetStringUTFChars (env, label, NULL);
menu = gtk_menu_new ();
if (str != NULL)
menu_title = gtk_menu_item_new_with_label (str);
else
menu_title = gtk_menu_item_new();
gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_title), menu);
/* Allow this menu to grab the pointer. */
toplevel = gtk_widget_get_toplevel (menu);
if (GTK_IS_WINDOW (toplevel))
{
gtk_window_group_add_window (cp_gtk_global_window_group,
GTK_WINDOW(toplevel));
}
gtk_widget_show (menu_title);
NSA_SET_PTR (env, obj, menu_title);
(*env)->ReleaseStringUTFChars (env, label, str);
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkMenuPeer_addTearOff
(JNIEnv *env, jobject obj)
{
void *ptr1;
GtkWidget *menu, *item;
gdk_threads_enter ();
ptr1 = NSA_GET_PTR (env, obj);
menu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (ptr1));
item = gtk_tearoff_menu_item_new ();
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
gtk_widget_show (item);
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkMenuPeer_addItem
(JNIEnv *env, jobject obj, jobject menuitempeer, jint key, jboolean shift)
{
void *ptr1, *ptr2;
GtkWidget *menu;
gdk_threads_enter ();
ptr1 = NSA_GET_PTR (env, obj);
ptr2 = NSA_GET_PTR (env, menuitempeer);
menu = gtk_menu_item_get_submenu(GTK_MENU_ITEM(ptr1));
gtk_menu_shell_append (GTK_MENU_SHELL(menu), GTK_WIDGET (ptr2));
if (key)
{
gtk_widget_add_accelerator (GTK_WIDGET (ptr2), "activate",
gtk_menu_get_accel_group (GTK_MENU (menu)), key,
(GDK_CONTROL_MASK
| ((shift) ? GDK_SHIFT_MASK : 0)),
GTK_ACCEL_VISIBLE);
}
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkMenuPeer_delItem
(JNIEnv *env, jobject obj, jint index)
{
void *ptr;
GList *list;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
list = gtk_container_children (GTK_CONTAINER (ptr));
list = g_list_nth (list, index);
gtk_container_remove (GTK_CONTAINER (ptr), GTK_WIDGET (list->data));
gdk_threads_leave ();
}
@@ -0,0 +1,112 @@
/* gtkpanelpeer.c -- Native implementation of GtkPanelPeer
Copyright (C) 1998, 1999, 2002 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"
#include "gnu_java_awt_peer_gtk_GtkComponentPeer.h"
#include "gnu_java_awt_peer_gtk_GtkPanelPeer.h"
static gboolean panel_focus_in_cb (GtkWidget * widget,
GdkEventFocus *event,
jobject peer);
static gboolean panel_focus_out_cb (GtkWidget * widget,
GdkEventFocus *event,
jobject peer);
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkPanelPeer_create
(JNIEnv *env, jobject obj)
{
GtkWidget *widget;
gdk_threads_enter ();
NSA_SET_GLOBAL_REF (env, obj);
widget = gtk_fixed_new ();
gtk_fixed_set_has_window (GTK_FIXED (widget), TRUE);
GTK_WIDGET_SET_FLAGS (widget, GTK_CAN_FOCUS);
NSA_SET_PTR (env, obj, widget);
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkPanelPeer_connectSignals
(JNIEnv *env, jobject obj)
{
void *ptr;
jobject *gref;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
gref = NSA_GET_GLOBAL_REF (env, obj);
/* Panel signals. These callbacks prevent expose events being
delivered to the panel when it is focused. */
g_signal_connect (G_OBJECT (ptr), "focus-in-event",
G_CALLBACK (panel_focus_in_cb), *gref);
g_signal_connect (G_OBJECT (ptr), "focus-out-event",
G_CALLBACK (panel_focus_out_cb), *gref);
/* Component signals. Exclude focus signals. */
cp_gtk_component_connect_expose_signals (ptr, gref);
cp_gtk_component_connect_mouse_signals (ptr, gref);
gdk_threads_leave ();
}
static gboolean
panel_focus_in_cb (GtkWidget * widget __attribute__((unused)),
GdkEventFocus *event __attribute__((unused)),
jobject peer __attribute__((unused)))
{
return TRUE;
}
static gboolean
panel_focus_out_cb (GtkWidget * widget __attribute__((unused)),
GdkEventFocus *event __attribute__((unused)),
jobject peer __attribute__((unused)))
{
return TRUE;
}
@@ -0,0 +1,105 @@
/* gtkpopupmenupeer.c -- Native implementation of GtkPopupMenuPeer
Copyright (C) 1999, 2004 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"
#include "gnu_java_awt_peer_gtk_GtkPopupMenuPeer.h"
struct pos
{
gint x;
gint y;
};
static void
menu_pos (GtkMenu *menu __attribute__((unused)),
gint *x, gint *y,
gboolean *push_in,
gpointer user_data)
{
struct pos *p = (struct pos *) user_data;
*x = p->x;
*y = p->y;
*push_in = TRUE;
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkPopupMenuPeer_show
(JNIEnv *env, jobject obj, jint x, jint y, jlong time)
{
void *ptr;
struct pos *p;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
p = g_malloc (sizeof (struct pos));
p->x = x;
p->y = y;
gtk_menu_popup (GTK_MENU (GTK_MENU_ITEM (ptr)->submenu),
NULL, NULL, menu_pos, p, 0, time);
g_free (p);
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkPopupMenuPeer_setupAccelGroup
(JNIEnv *env, jobject obj, jobject parent)
{
void *ptr1, *ptr2;
GtkMenu *menu;
gdk_threads_enter ();
ptr1 = NSA_GET_PTR (env, obj);
ptr2 = NSA_GET_PTR (env, parent);
menu = GTK_MENU (GTK_MENU_ITEM (ptr1)->submenu);
gtk_menu_set_accel_group (menu, gtk_accel_group_new ());
/* FIXME: update this to use GTK-2.4 GtkActions. */
#if 0
_gtk_accel_group_attach (gtk_menu_get_accel_group (menu),
G_OBJECT (gtk_widget_get_toplevel (ptr2)));
#endif
gdk_threads_leave ();
}
@@ -0,0 +1,205 @@
/* gtkscrollpanepeer.c -- Native implementation of GtkScrollPanePeer
Copyright (C) 1998, 1999, 2002 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"
#include "gnu_java_awt_peer_gtk_GtkScrollPanePeer.h"
#define AWT_SCROLLPANE_SCROLLBARS_AS_NEEDED 0
#define AWT_SCROLLPANE_SCROLLBARS_ALWAYS 1
#define AWT_SCROLLPANE_SCROLLBARS_NEVER 2
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkScrollPanePeer_create
(JNIEnv *env, jobject obj, int width, int height)
{
GtkWidget *sw;
gdk_threads_enter ();
/* Create global reference and save it for future use */
NSA_SET_GLOBAL_REF (env, obj);
sw = gtk_scrolled_window_new (NULL, NULL);
gtk_widget_set_size_request (sw, width, height);
NSA_SET_PTR (env, obj, sw);
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkScrollPanePeer_setScrollPosition
(JNIEnv *env, jobject obj, jint x, jint y)
{
GtkAdjustment *hadj, *vadj;
GtkScrolledWindow *sw;
void *ptr;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
sw = GTK_SCROLLED_WINDOW (ptr);
hadj = gtk_scrolled_window_get_hadjustment (sw);
vadj = gtk_scrolled_window_get_vadjustment (sw);
gtk_adjustment_set_value (hadj, x);
gtk_adjustment_set_value (vadj, y);
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkScrollPanePeer_gtkScrolledWindowSetHScrollIncrement
(JNIEnv *env, jobject obj, jint u)
{
GtkAdjustment *hadj;
GtkScrolledWindow *sw;
void *ptr;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
sw = GTK_SCROLLED_WINDOW(ptr);
hadj = gtk_scrolled_window_get_hadjustment (sw);
hadj->step_increment = u;
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkScrollPanePeer_gtkScrolledWindowSetVScrollIncrement
(JNIEnv *env, jobject obj, jint u)
{
GtkAdjustment *vadj;
GtkScrolledWindow *sw;
void *ptr;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
sw = GTK_SCROLLED_WINDOW(ptr);
vadj = gtk_scrolled_window_get_hadjustment (sw);
vadj->step_increment = u;
gdk_threads_leave ();
}
JNIEXPORT jint JNICALL
Java_gnu_java_awt_peer_gtk_GtkScrollPanePeer_getHScrollbarHeight
(JNIEnv *env, jobject obj)
{
void *ptr;
GtkScrolledWindow *sw;
GtkRequisition requisition;
jint height = 0;
jint spacing = 0;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
sw = GTK_SCROLLED_WINDOW (ptr);
gtk_widget_size_request (sw->hscrollbar, &requisition);
gtk_widget_style_get (GTK_WIDGET (sw), "scrollbar_spacing", &spacing, NULL);
height = requisition.height + spacing;
gdk_threads_leave ();
return height;
}
JNIEXPORT jint JNICALL
Java_gnu_java_awt_peer_gtk_GtkScrollPanePeer_getVScrollbarWidth
(JNIEnv *env, jobject obj)
{
void *ptr;
GtkScrolledWindow *sw;
GtkRequisition requisition;
jint width = 0;
jint spacing = 0;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
sw = GTK_SCROLLED_WINDOW (ptr);
gtk_widget_size_request (sw->vscrollbar, &requisition);
gtk_widget_style_get (GTK_WIDGET (sw), "scrollbar_spacing", &spacing, NULL);
width = requisition.width + spacing;
gdk_threads_leave ();
return width;
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkScrollPanePeer_setPolicy
(JNIEnv *env, jobject obj, jint policy)
{
void *ptr;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
switch (policy)
{
case AWT_SCROLLPANE_SCROLLBARS_AS_NEEDED:
policy = GTK_POLICY_AUTOMATIC;
break;
case AWT_SCROLLPANE_SCROLLBARS_ALWAYS:
policy = GTK_POLICY_ALWAYS;
break;
case AWT_SCROLLPANE_SCROLLBARS_NEVER:
policy = GTK_POLICY_NEVER;
break;
}
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (ptr), policy, policy);
gdk_threads_leave ();
}
@@ -0,0 +1,258 @@
/* gtkscrollbarpeer.c -- Native implementation of GtkScrollbarPeer
Copyright (C) 1998, 1999 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 <math.h>
#include "gtkpeer.h"
#include "gnu_java_awt_peer_gtk_GtkComponentPeer.h"
#include "gnu_java_awt_peer_gtk_GtkScrollbarPeer.h"
#define AWT_ADJUSTMENT_UNIT_INCREMENT 1
#define AWT_ADJUSTMENT_UNIT_DECREMENT 2
#define AWT_ADJUSTMENT_BLOCK_DECREMENT 3
#define AWT_ADJUSTMENT_BLOCK_INCREMENT 4
#define AWT_ADJUSTMENT_TRACK 5
static jmethodID postAdjustmentEventID;
void
cp_gtk_scrollbar_init_jni (void)
{
jclass gtkscrollbarpeer;
gtkscrollbarpeer = (*cp_gtk_gdk_env())->FindClass (cp_gtk_gdk_env(),
"gnu/java/awt/peer/gtk/GtkScrollbarPeer");
postAdjustmentEventID = (*cp_gtk_gdk_env())->GetMethodID (cp_gtk_gdk_env(),
gtkscrollbarpeer,
"postAdjustmentEvent",
"(II)V");
}
#if GTK_MINOR_VERSION > 4
static gboolean slider_moved_cb (GtkRange *range,
GtkScrollType scroll,
gdouble value,
jobject obj);
#else
static void post_change_event_cb (GtkRange *range,
jobject peer);
#endif
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkScrollbarPeer_create
(JNIEnv *env, jobject obj, jint orientation, jint value,
jint min, jint max, jint step_incr, jint page_incr, jint visible_amount)
{
GtkWidget *scrollbar;
GtkObject *adj;
/* Create global reference and save it for future use */
NSA_SET_GLOBAL_REF (env, obj);
gdk_threads_enter ();
adj = gtk_adjustment_new ((gdouble) value,
(gdouble) min,
(gdouble) max,
(gdouble) step_incr,
(gdouble) page_incr,
(gdouble) visible_amount);
scrollbar = orientation
? gtk_vscrollbar_new (GTK_ADJUSTMENT (adj))
: gtk_hscrollbar_new (GTK_ADJUSTMENT (adj));
GTK_RANGE (scrollbar)->round_digits = 0;
/* These calls seem redundant but they are not. They clamp values
so that the slider's entirety is always between the two
steppers. */
gtk_range_set_range (GTK_RANGE (scrollbar), (gdouble) min, (gdouble) max);
gtk_range_set_value (GTK_RANGE (scrollbar), (gdouble) value);
gdk_threads_leave ();
NSA_SET_PTR (env, obj, scrollbar);
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkScrollbarPeer_connectSignals
(JNIEnv *env, jobject obj)
{
void *ptr = NSA_GET_PTR (env, obj);
jobject *gref = NSA_GET_GLOBAL_REF (env, obj);
g_assert (gref);
gdk_threads_enter ();
/* Scrollbar signals */
#if GTK_MINOR_VERSION > 4
g_signal_connect (G_OBJECT (ptr), "change-value",
G_CALLBACK (slider_moved_cb), *gref);
#else
g_signal_connect (G_OBJECT (ptr), "value-changed",
G_CALLBACK (post_change_event_cb), *gref);
#endif
/* Component signals */
cp_gtk_component_connect_signals (G_OBJECT (ptr), gref);
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkScrollbarPeer_setLineIncrement
(JNIEnv *env, jobject obj, jint amount)
{
void *ptr;
GtkAdjustment *adj;
ptr = NSA_GET_PTR (env, obj);
gdk_threads_enter ();
adj = gtk_range_get_adjustment (GTK_RANGE (ptr));
adj->step_increment = (gdouble) amount;
gtk_adjustment_changed (adj);
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkScrollbarPeer_setPageIncrement
(JNIEnv *env, jobject obj, jint amount)
{
void *ptr;
GtkAdjustment *adj;
ptr = NSA_GET_PTR (env, obj);
gdk_threads_enter ();
adj = gtk_range_get_adjustment (GTK_RANGE (ptr));
adj->page_increment = (gdouble) amount;
gtk_adjustment_changed (adj);
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkScrollbarPeer_setValues
(JNIEnv *env, jobject obj, jint value, jint visible, jint min, jint max)
{
void *ptr;
GtkAdjustment *adj;
ptr = NSA_GET_PTR (env, obj);
gdk_threads_enter ();
adj = gtk_range_get_adjustment (GTK_RANGE (ptr));
adj->page_size = (gdouble) visible;
gtk_range_set_range (GTK_RANGE (ptr), (gdouble) min, (gdouble) max);
gtk_range_set_value (GTK_RANGE (ptr), (gdouble) value);
gdk_threads_leave ();
}
#if GTK_MINOR_VERSION > 4
static gboolean
slider_moved_cb (GtkRange *range,
GtkScrollType scroll,
gdouble value,
jobject obj)
{
GtkAdjustment *adj = gtk_range_get_adjustment (GTK_RANGE (range));
value = CLAMP (value, adj->lower,
(adj->upper - adj->page_size));
if (range->round_digits >= 0)
{
gdouble power;
gint i;
i = range->round_digits;
power = 1;
while (i--)
power *= 10;
value = floor ((value * power) + 0.5) / power;
}
switch (scroll)
{
case GTK_SCROLL_STEP_BACKWARD:
(*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), obj, postAdjustmentEventID,
AWT_ADJUSTMENT_UNIT_DECREMENT,
(jint) value);
break;
case GTK_SCROLL_STEP_FORWARD:
(*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), obj, postAdjustmentEventID,
AWT_ADJUSTMENT_UNIT_INCREMENT,
(jint) value);
break;
case GTK_SCROLL_PAGE_BACKWARD:
(*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), obj, postAdjustmentEventID,
AWT_ADJUSTMENT_BLOCK_DECREMENT,
(jint) value);
break;
case GTK_SCROLL_PAGE_FORWARD:
(*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), obj, postAdjustmentEventID,
AWT_ADJUSTMENT_BLOCK_INCREMENT,
(jint) value);
break;
default:
/* GTK_SCROLL_JUMP: */
(*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), obj, postAdjustmentEventID,
AWT_ADJUSTMENT_TRACK,
(jint) value);
break;
}
return FALSE;
}
#else
static void
post_change_event_cb (GtkRange *range, jobject peer)
{
GtkAdjustment *adj;
adj = gtk_range_get_adjustment (range);
(*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer, postAdjustmentEventID,
AWT_ADJUSTMENT_TRACK, (jint) adj->value);
}
#endif
@@ -0,0 +1,522 @@
/* gtktextareapeer.c -- Native implementation of GtkTextAreaPeer
Copyright (C) 1998, 1999, 2003 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"
#include "gnu_java_awt_peer_gtk_GtkTextAreaPeer.h"
#define AWT_TEXTAREA_SCROLLBARS_BOTH 0
#define AWT_TEXTAREA_SCROLLBARS_VERTICAL_ONLY 1
#define AWT_TEXTAREA_SCROLLBARS_HORIZONTAL_ONLY 2
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_create
(JNIEnv *env, jobject obj,
jint textview_width, jint textview_height, jint scroll)
{
GtkWidget *text, *sw;
gdk_threads_enter ();
/* Create global reference and save it for future use */
NSA_SET_GLOBAL_REF (env, obj);
text = gtk_text_view_new ();
gtk_widget_set_size_request (text, textview_width, textview_height);
gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW (text), TRUE);
gtk_widget_show (text);
sw = gtk_scrolled_window_new (NULL, NULL);
gtk_container_add (GTK_CONTAINER (sw), text);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
/* horizontal scrollbar */
(scroll == AWT_TEXTAREA_SCROLLBARS_BOTH
|| scroll == AWT_TEXTAREA_SCROLLBARS_HORIZONTAL_ONLY) ?
GTK_POLICY_ALWAYS : GTK_POLICY_NEVER,
/* vertical scrollbar */
(scroll == AWT_TEXTAREA_SCROLLBARS_BOTH
|| scroll == AWT_TEXTAREA_SCROLLBARS_VERTICAL_ONLY) ?
GTK_POLICY_ALWAYS : GTK_POLICY_NEVER);
gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (text),
(scroll == AWT_TEXTAREA_SCROLLBARS_BOTH
|| scroll == AWT_TEXTAREA_SCROLLBARS_HORIZONTAL_ONLY)
? GTK_WRAP_NONE : GTK_WRAP_WORD);
NSA_SET_PTR (env, obj, sw);
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_connectSignals
(JNIEnv *env, jobject obj)
{
GtkWidget *text = NULL;
GtkTextBuffer *buf;
void *ptr;
jobject *gref;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
gref = NSA_GET_GLOBAL_REF (env, obj);
/* Unwrap the text view from the scrolled window */
text = gtk_bin_get_child (GTK_BIN (ptr));
buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text));
/* TextComponent signals */
cp_gtk_textcomponent_connect_signals (G_OBJECT (buf), gref);
/* Component signals */
cp_gtk_component_connect_signals (G_OBJECT (text), gref);
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_insert
(JNIEnv *env, jobject obj, jstring contents, jint position)
{
GtkTextBuffer *buf;
GtkTextIter iter;
GtkWidget *text;
void *ptr;
const char *str;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
str = (*env)->GetStringUTFChars (env, contents, NULL);
text = gtk_bin_get_child (GTK_BIN (ptr));
buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text));
gtk_text_buffer_get_iter_at_offset (buf, &iter, position);
gtk_text_buffer_insert (buf, &iter, str, strlen (str));
(*env)->ReleaseStringUTFChars (env, contents, str);
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_replaceRange
(JNIEnv *env, jobject obj, jstring contents, jint start, jint end)
{
GtkWidget *text;
GtkTextBuffer *buf;
GtkTextIter iter, startIter, endIter;
void *ptr;
const char *str;
int mystart = start;
int myend = end;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
str = (*env)->GetStringUTFChars (env, contents, NULL);
text = gtk_bin_get_child (GTK_BIN (ptr));
buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text));
gtk_text_buffer_get_iter_at_offset (buf, &startIter, mystart);
gtk_text_buffer_get_iter_at_offset (buf, &endIter, myend);
gtk_text_buffer_delete (buf, &startIter, &endIter);
gtk_text_buffer_get_iter_at_offset (buf, &iter, mystart);
gtk_text_buffer_insert(buf, &iter, str, strlen (str));
(*env)->ReleaseStringUTFChars (env, contents, str);
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_gtkWidgetModifyFont
(JNIEnv *env, jobject obj, jstring name, jint style, jint size)
{
const char *font_name;
void *ptr;
GtkWidget *text;
PangoFontDescription *font_desc;
gdk_threads_enter();
ptr = NSA_GET_PTR (env, obj);
text = gtk_bin_get_child (GTK_BIN (ptr));
font_name = (*env)->GetStringUTFChars (env, name, NULL);
font_desc = pango_font_description_from_string (font_name);
pango_font_description_set_size (font_desc,
size * cp_gtk_dpi_conversion_factor);
if (style & AWT_STYLE_BOLD)
pango_font_description_set_weight (font_desc, PANGO_WEIGHT_BOLD);
if (style & AWT_STYLE_ITALIC)
pango_font_description_set_style (font_desc, PANGO_STYLE_OBLIQUE);
gtk_widget_modify_font (GTK_WIDGET (text), font_desc);
pango_font_description_free (font_desc);
(*env)->ReleaseStringUTFChars (env, name, font_name);
gdk_threads_leave();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_gtkWidgetRequestFocus
(JNIEnv *env, jobject obj)
{
void *ptr;
GtkWidget *text;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
text = gtk_bin_get_child (GTK_BIN (ptr));
gtk_widget_grab_focus (text);
gdk_threads_leave ();
}
JNIEXPORT jint JNICALL
Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_getHScrollbarHeight
(JNIEnv *env, jobject obj)
{
void *ptr;
GtkScrolledWindow *sw;
GtkRequisition requisition;
jint height = 0;
jint spacing = 0;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
sw = GTK_SCROLLED_WINDOW (ptr);
if (sw)
{
gtk_widget_size_request (sw->hscrollbar, &requisition);
gtk_widget_style_get (GTK_WIDGET (sw), "scrollbar_spacing", &spacing, NULL);
height = requisition.height + spacing;
}
gdk_threads_leave ();
return height;
}
JNIEXPORT jint JNICALL
Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_getVScrollbarWidth
(JNIEnv *env, jobject obj)
{
void *ptr;
GtkScrolledWindow *sw;
GtkRequisition requisition;
jint width = 0;
jint spacing = 0;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
sw = GTK_SCROLLED_WINDOW (ptr);
if (sw)
{
gtk_widget_size_request (sw->vscrollbar, &requisition);
gtk_widget_style_get (GTK_WIDGET (sw), "scrollbar_spacing", &spacing, NULL);
width = requisition.width + spacing;
}
gdk_threads_leave ();
return width;
}
JNIEXPORT jint JNICALL
Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_getCaretPosition
(JNIEnv *env, jobject obj)
{
void *ptr;
int pos = 0;
GtkWidget *text = NULL;
GtkTextBuffer *buf;
GtkTextMark *mark;
GtkTextIter iter;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
text = gtk_bin_get_child (GTK_BIN (ptr));
buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text));
mark = gtk_text_buffer_get_insert (buf);
gtk_text_buffer_get_iter_at_mark (buf, &iter, mark);
pos = gtk_text_iter_get_offset (&iter);
gdk_threads_leave ();
return pos;
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_setCaretPosition
(JNIEnv *env, jobject obj, jint pos)
{
void *ptr;
GtkWidget *text = NULL;
GtkTextBuffer *buf;
GtkTextIter iter;
GtkTextMark *oldmark;
GtkTextIter olditer;
int oldpos;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
text = gtk_bin_get_child (GTK_BIN (ptr));
buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text));
/* Save old position. */
oldmark = gtk_text_buffer_get_insert (buf);
gtk_text_buffer_get_iter_at_mark (buf, &olditer, oldmark);
oldpos = gtk_text_iter_get_offset (&olditer);
/* Move to new position. */
gtk_text_buffer_get_iter_at_offset (buf, &iter, pos);
gtk_text_buffer_place_cursor (buf, &iter);
/* Scroll to new position. Alignment is determined
comparing the new position to the old position. */
if (oldpos > pos)
gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (text),
&iter, 0, TRUE, 0, 0);
else if (oldpos < pos)
gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (text),
&iter, 0, TRUE, 1, 1);
gdk_threads_leave ();
}
JNIEXPORT jint JNICALL
Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_getSelectionStart
(JNIEnv *env, jobject obj)
{
void *ptr;
int pos = 0;
GtkWidget *text = NULL;
GtkTextBuffer *buf;
GtkTextIter start;
GtkTextIter end;
GtkTextMark *mark;
GtkTextIter iter;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
text = gtk_bin_get_child (GTK_BIN (ptr));
buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text));
if (gtk_text_buffer_get_selection_bounds (buf, &start, &end))
{
pos = gtk_text_iter_get_offset (&start);
}
else
{
mark = gtk_text_buffer_get_insert (buf);
gtk_text_buffer_get_iter_at_mark (buf, &iter, mark);
pos = gtk_text_iter_get_offset (&iter);
}
gdk_threads_leave ();
return pos;
}
JNIEXPORT jint JNICALL
Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_getSelectionEnd
(JNIEnv *env, jobject obj)
{
void *ptr;
int pos = 0;
GtkWidget *text = NULL;
GtkTextBuffer *buf;
GtkTextIter start;
GtkTextIter end;
GtkTextMark *mark;
GtkTextIter iter;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
text = gtk_bin_get_child (GTK_BIN (ptr));
buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text));
if (gtk_text_buffer_get_selection_bounds (buf, &start, &end))
{
pos = gtk_text_iter_get_offset (&end);
}
else
{
mark = gtk_text_buffer_get_insert (buf);
gtk_text_buffer_get_iter_at_mark (buf, &iter, mark);
pos = gtk_text_iter_get_offset (&iter);
}
gdk_threads_leave ();
return pos;
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_select
(JNIEnv *env, jobject obj, jint start, jint end)
{
void *ptr;
GtkWidget *text = NULL;
GtkTextBuffer *buf;
GtkTextIter iter;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
text = gtk_bin_get_child (GTK_BIN (ptr));
buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text));
gtk_text_buffer_get_iter_at_offset (buf, &iter, start);
/* quickly move both 'insert' and 'selection_bound' to the
same position */
gtk_text_buffer_place_cursor (buf, &iter);
gtk_text_buffer_get_iter_at_offset (buf, &iter, end);
gtk_text_buffer_move_mark_by_name (buf, "selection_bound", &iter);
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_setEditable
(JNIEnv *env, jobject obj, jboolean state)
{
void *ptr;
GtkWidget *text = NULL;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
text = gtk_bin_get_child (GTK_BIN (ptr));
gtk_text_view_set_editable (GTK_TEXT_VIEW (text), state);
gdk_threads_leave ();
}
JNIEXPORT jstring JNICALL
Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_getText
(JNIEnv *env, jobject obj)
{
void *ptr;
char *contents = NULL;
jstring jcontents;
GtkWidget *text = NULL;
GtkTextBuffer *buf;
GtkTextIter start, end;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
text = gtk_bin_get_child (GTK_BIN (ptr));
buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text));
gtk_text_buffer_get_start_iter (buf, &start);
gtk_text_buffer_get_end_iter (buf, &end);
contents = gtk_text_buffer_get_text (buf, &start, &end, FALSE);
jcontents = (*env)->NewStringUTF (env, contents);
g_free (contents);
gdk_threads_leave ();
return jcontents;
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkTextAreaPeer_setText
(JNIEnv *env, jobject obj, jstring contents)
{
void *ptr;
const char *str;
GtkWidget *text = NULL;
GtkTextBuffer *buf;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
str = (*env)->GetStringUTFChars (env, contents, NULL);
text = gtk_bin_get_child (GTK_BIN (ptr));
buf = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text));
gtk_text_buffer_set_text (buf, str, strlen (str));
(*env)->ReleaseStringUTFChars (env, contents, str);
gdk_threads_leave ();
}
@@ -0,0 +1,423 @@
/* gtktextfieldpeer.c -- Native implementation of GtkTextFieldPeer
Copyright (C) 1998, 1999, 2002 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"
#include "gnu_java_awt_peer_gtk_GtkTextFieldPeer.h"
/* the color used for highlighting when the foreground is black,
since black highlights aren't a Good Idea. */
#define BB_RED 16962
#define BB_GREEN 26985
#define BB_BLUE 31611
static jmethodID postTextEventID;
void
cp_gtk_textcomponent_init_jni (void)
{
jclass gtkcomponentpeer;
gtkcomponentpeer = (*cp_gtk_gdk_env())->FindClass (cp_gtk_gdk_env(),
"gnu/java/awt/peer/gtk/GtkComponentPeer");
postTextEventID = (*cp_gtk_gdk_env())->GetMethodID (cp_gtk_gdk_env(), gtkcomponentpeer,
"postTextEvent",
"()V");
}
static void textcomponent_changed_cb (GtkEditable *editable, jobject peer);
static jint get_border_width (GtkWidget *entry);
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkTextFieldPeer_create
(JNIEnv *env, jobject obj, jint text_width)
{
GtkWidget *entry;
gdk_threads_enter ();
/* Create global reference and save it for future use */
NSA_SET_GLOBAL_REF (env, obj);
entry = gtk_entry_new ();
gtk_widget_set_size_request (entry,
text_width + 2 * get_border_width (entry), -1);
NSA_SET_PTR (env, obj, entry);
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkTextFieldPeer_connectSignals
(JNIEnv *env, jobject obj)
{
void *ptr;
jobject *gref;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
gref = NSA_GET_GLOBAL_REF (env, obj);
/* TextComponent signals */
cp_gtk_textcomponent_connect_signals (G_OBJECT (ptr), gref);
/* Component signals */
cp_gtk_component_connect_signals (G_OBJECT (ptr), gref);
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkTextFieldPeer_gtkWidgetSetBackground
(JNIEnv *env, jobject obj, jint red, jint green, jint blue)
{
GdkColor color;
void *ptr;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
color.red = (red / 255.0) * 65535;
color.green = (green / 255.0) * 65535;
color.blue = (blue / 255.0) * 65535;
gtk_widget_modify_base (GTK_WIDGET (ptr), GTK_STATE_NORMAL, &color);
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkTextFieldPeer_gtkWidgetSetForeground
(JNIEnv *env, jobject obj, jint red, jint green, jint blue)
{
GdkColor color;
void *ptr;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
color.red = (red / 255.0) * 65535;
color.green = (green / 255.0) * 65535;
color.blue = (blue / 255.0) * 65535;
gtk_widget_modify_text (GTK_WIDGET (ptr), GTK_STATE_NORMAL, &color);
if ( red == 0 && green == 0 && blue == 0)
{
color.red = BB_RED;
color.green = BB_GREEN;
color.blue = BB_BLUE;
}
gtk_widget_modify_base (GTK_WIDGET (ptr), GTK_STATE_SELECTED, &color);
gdk_threads_leave ();
}
JNIEXPORT jint JNICALL
Java_gnu_java_awt_peer_gtk_GtkTextFieldPeer_gtkEntryGetBorderWidth
(JNIEnv *env, jobject obj)
{
void *ptr;
int border_width = 0;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
border_width = get_border_width (GTK_WIDGET (ptr));
gdk_threads_leave ();
return border_width;
}
/* GTK hard-codes this value. It is the space between a GtkEntry's
frame and its text. */
#define INNER_BORDER 2
static jint
get_border_width (GtkWidget *entry)
{
gint focus_width;
gboolean interior_focus;
int x_border_width = INNER_BORDER;
gtk_widget_style_get (entry,
"interior-focus", &interior_focus,
"focus-line-width", &focus_width,
NULL);
if (GTK_ENTRY (entry)->has_frame)
x_border_width += entry->style->xthickness;
if (!interior_focus)
x_border_width += focus_width;
return x_border_width;
}
#undef INNER_BORDER
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkTextFieldPeer_setEchoChar
(JNIEnv *env, jobject obj, jchar c)
{
void *ptr;
GtkEntry *entry;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
entry = GTK_ENTRY (ptr);
if (c != 0)
{
/* FIXME: use gtk_entry_set_invisible_char (GtkEntry *entry,
gunichar ch) here. That means we must convert from jchar
(utf16) to gunichar (ucs4). */
gtk_entry_set_visibility (entry, FALSE);
}
else
gtk_entry_set_visibility (entry, TRUE);
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkTextFieldPeer_gtkWidgetModifyFont
(JNIEnv *env, jobject obj, jstring name, jint style, jint size)
{
const char *font_name;
void *ptr;
PangoFontDescription *font_desc;
gdk_threads_enter();
ptr = NSA_GET_PTR (env, obj);
font_name = (*env)->GetStringUTFChars (env, name, NULL);
font_desc = pango_font_description_from_string (font_name);
pango_font_description_set_size (font_desc,
size * cp_gtk_dpi_conversion_factor);
if (style & AWT_STYLE_BOLD)
pango_font_description_set_weight (font_desc, PANGO_WEIGHT_BOLD);
if (style & AWT_STYLE_ITALIC)
pango_font_description_set_style (font_desc, PANGO_STYLE_OBLIQUE);
gtk_widget_modify_font (GTK_WIDGET (ptr), font_desc);
pango_font_description_free (font_desc);
(*env)->ReleaseStringUTFChars (env, name, font_name);
gdk_threads_leave();
}
JNIEXPORT jint JNICALL
Java_gnu_java_awt_peer_gtk_GtkTextFieldPeer_getCaretPosition
(JNIEnv *env, jobject obj)
{
void *ptr;
int pos = 0;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
pos = gtk_editable_get_position (GTK_EDITABLE (ptr));
gdk_threads_leave ();
return pos;
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkTextFieldPeer_setCaretPosition
(JNIEnv *env, jobject obj, jint pos)
{
void *ptr;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
gtk_editable_set_position (GTK_EDITABLE (ptr), pos);
gdk_threads_leave ();
}
JNIEXPORT jint JNICALL
Java_gnu_java_awt_peer_gtk_GtkTextFieldPeer_getSelectionStart
(JNIEnv *env, jobject obj)
{
void *ptr;
int pos = 0;
int starti, endi;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
if (gtk_editable_get_selection_bounds (GTK_EDITABLE (ptr), &starti, &endi))
pos = starti;
else
pos = gtk_editable_get_position (GTK_EDITABLE (ptr));
gdk_threads_leave ();
return pos;
}
JNIEXPORT jint JNICALL
Java_gnu_java_awt_peer_gtk_GtkTextFieldPeer_getSelectionEnd
(JNIEnv *env, jobject obj)
{
void *ptr;
int pos = 0;
int starti, endi;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
if (gtk_editable_get_selection_bounds (GTK_EDITABLE (ptr), &starti, &endi))
pos = endi;
else
pos = gtk_editable_get_position (GTK_EDITABLE (ptr));
gdk_threads_leave ();
return pos;
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkTextFieldPeer_select
(JNIEnv *env, jobject obj, jint start, jint end)
{
void *ptr;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
gtk_editable_select_region (GTK_EDITABLE (ptr), start, end);
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkTextFieldPeer_setEditable
(JNIEnv *env, jobject obj, jboolean state)
{
void *ptr;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
gtk_editable_set_editable (GTK_EDITABLE (ptr), state);
gdk_threads_leave ();
}
JNIEXPORT jstring JNICALL
Java_gnu_java_awt_peer_gtk_GtkTextFieldPeer_getText
(JNIEnv *env, jobject obj)
{
void *ptr;
char *contents = NULL;
jstring jcontents;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
contents = gtk_editable_get_chars (GTK_EDITABLE (ptr), 0, -1);
jcontents = (*env)->NewStringUTF (env, contents);
g_free (contents);
gdk_threads_leave ();
return jcontents;
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkTextFieldPeer_setText
(JNIEnv *env, jobject obj, jstring contents)
{
void *ptr;
const char *str;
gdk_threads_enter ();
ptr = NSA_GET_PTR (env, obj);
str = (*env)->GetStringUTFChars (env, contents, NULL);
gtk_entry_set_text (GTK_ENTRY (ptr), str);
(*env)->ReleaseStringUTFChars (env, contents, str);
gdk_threads_leave ();
}
void
cp_gtk_textcomponent_connect_signals (GObject *ptr, jobject *gref)
{
g_signal_connect (G_OBJECT(ptr), "changed",
G_CALLBACK (textcomponent_changed_cb), *gref);
}
static void
textcomponent_changed_cb (GtkEditable *editable __attribute__((unused)),
jobject peer)
{
gdk_threads_leave ();
(*cp_gtk_gdk_env())->CallVoidMethod (cp_gtk_gdk_env(), peer, postTextEventID);
gdk_threads_enter ();
}
@@ -0,0 +1,524 @@
/* gtktoolkit.c -- Native portion of GtkToolkit
Copyright (C) 1998, 1999, 2005 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"
#include "gnu_java_awt_peer_gtk_GtkToolkit.h"
#include "gthread-jni.h"
#include "jcl.h"
#include <sys/time.h>
#define RC_FILE ".classpath-gtkrc"
/* From java.awt.SystemColor */
#define AWT_DESKTOP 0
#define AWT_ACTIVE_CAPTION 1
#define AWT_ACTIVE_CAPTION_TEXT 2
#define AWT_ACTIVE_CAPTION_BORDER 3
#define AWT_INACTIVE_CAPTION 4
#define AWT_INACTIVE_CAPTION_TEXT 5
#define AWT_INACTIVE_CAPTION_BORDER 6
#define AWT_WINDOW 7
#define AWT_WINDOW_BORDER 8
#define AWT_WINDOW_TEXT 9
#define AWT_MENU 10
#define AWT_MENU_TEXT 11
#define AWT_TEXT 12
#define AWT_TEXT_TEXT 13
#define AWT_TEXT_HIGHLIGHT 14
#define AWT_TEXT_HIGHLIGHT_TEXT 15
#define AWT_TEXT_INACTIVE_TEXT 16
#define AWT_CONTROL 17
#define AWT_CONTROL_TEXT 18
#define AWT_CONTROL_HIGHLIGHT 19
#define AWT_CONTROL_LT_HIGHLIGHT 20
#define AWT_CONTROL_SHADOW 21
#define AWT_CONTROL_DK_SHADOW 22
#define AWT_SCROLLBAR 23
#define AWT_INFO 24
#define AWT_INFO_TEXT 25
#define AWT_NUM_COLORS 26
struct state_table *cp_gtk_native_state_table;
struct state_table *cp_gtk_native_global_ref_table;
static jclass gtkgenericpeer;
static JavaVM *java_vm;
static jmethodID printCurrentThreadID;
union env_union
{
void *void_env;
JNIEnv *jni_env;
};
JNIEnv *
cp_gtk_gdk_env()
{
union env_union tmp;
g_assert((*java_vm)->GetEnv(java_vm, &tmp.void_env, JNI_VERSION_1_2) == JNI_OK);
return tmp.jni_env;
}
GtkWindowGroup *cp_gtk_global_window_group;
double cp_gtk_dpi_conversion_factor;
static void init_glib_threads(JNIEnv *, jint);
static void init_dpi_conversion_factor (void);
static void dpi_changed_cb (GtkSettings *settings,
GParamSpec *pspec);
#if GTK_MINOR_VERSION > 4
static GLogFunc old_glog_func;
static void glog_func (const gchar *log_domain,
GLogLevelFlags log_level,
const gchar *message,
gpointer user_data);
#endif
/*
* Call gtk_init. It is very important that this happen before any other
* gtk calls.
*
* The portableNativeSync argument may have the values:
* 1 if the Java property gnu.classpath.awt.gtk.portable.native.sync
* is set to "true".
* 0 if it is set to "false"
* -1 if unset.
*/
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkToolkit_gtkInit (JNIEnv *env,
jclass clazz __attribute__((unused)),
jint portableNativeSync)
{
int argc = 1;
char **argv;
char *homedir, *rcpath = NULL;
gtkgenericpeer = (*env)->FindClass(env, "gnu/java/awt/peer/gtk/GtkGenericPeer");
printCurrentThreadID = (*env)->GetStaticMethodID (env, gtkgenericpeer,
"printCurrentThread", "()V");
NSA_INIT (env, gtkgenericpeer);
g_assert((*env)->GetJavaVM(env, &java_vm) == 0);
/* GTK requires a program's argc and argv variables, and requires that they
be valid. Set it up. */
argv = (char **) g_malloc (sizeof (char *) * 2);
argv[0] = (char *) g_malloc(1);
argv[0][0] = '\0';
argv[1] = NULL;
init_glib_threads(env, portableNativeSync);
/* From GDK 2.0 onwards we have to explicitly call gdk_threads_init */
gdk_threads_init();
gtk_init (&argc, &argv);
gdk_rgb_init ();
gtk_widget_set_default_colormap (gdk_rgb_get_cmap ());
gtk_widget_set_default_visual (gdk_rgb_get_visual ());
/* Make sure queued calls don't get sent to GTK/GDK while
we're shutting down. */
atexit (gdk_threads_enter);
if ((homedir = getenv ("HOME")))
{
rcpath = (char *) g_malloc (strlen (homedir) + strlen (RC_FILE) + 2);
sprintf (rcpath, "%s/%s", homedir, RC_FILE);
}
gtk_rc_parse ((rcpath) ? rcpath : RC_FILE);
g_free (rcpath);
g_free (argv[0]);
g_free (argv);
/* On errors or warning print a whole stacktrace. */
#if GTK_MINOR_VERSION > 4
old_glog_func = g_log_set_default_handler (&glog_func, NULL);
#endif
#if GTK_CAIRO
cp_gtk_graphics2d_init_jni ();
#endif
cp_gtk_graphics_init_jni ();
cp_gtk_button_init_jni ();
cp_gtk_checkbox_init_jni ();
cp_gtk_choice_init_jni ();
cp_gtk_component_init_jni ();
cp_gtk_list_init_jni ();
cp_gtk_menuitem_init_jni ();
cp_gtk_scrollbar_init_jni ();
cp_gtk_textcomponent_init_jni ();
cp_gtk_window_init_jni ();
cp_gtk_global_window_group = gtk_window_group_new ();
init_dpi_conversion_factor ();
}
/** Initialize GLIB's threads properly, based on the value of the
gnu.classpath.awt.gtk.portable.native.sync Java system property. If
that's unset, use the PORTABLE_NATIVE_SYNC config.h macro. (TODO:
In some release following 0.10, that config.h macro will go away.)
*/
static void
init_glib_threads(JNIEnv *env, jint portableNativeSync)
{
if (portableNativeSync < 0)
{
#ifdef PORTABLE_NATIVE_SYNC /* Default value, if not set by the Java system
property */
portableNativeSync = 1;
#else
portableNativeSync = 0;
#endif
}
(*env)->GetJavaVM( env, &cp_gtk_the_vm );
if (!g_thread_supported ())
{
if (portableNativeSync)
g_thread_init ( &cp_gtk_portable_native_sync_jni_functions );
else
g_thread_init ( NULL );
}
else
{
/* Warn if portable native sync is desired but the threading
system is already initialized. In that case we can't
override the threading implementation with our portable
native sync functions. */
if (portableNativeSync)
g_printerr ("peer warning: portable native sync disabled.\n");
}
/* Debugging progress message; uncomment if needed: */
/* printf("called gthread init\n"); */
}
void
cp_gtk_print_current_thread (void)
{
(*cp_gtk_gdk_env())->CallStaticVoidMethod (cp_gtk_gdk_env(), gtkgenericpeer, printCurrentThreadID);
}
/* This is a big hack, needed until this pango bug is resolved:
http://bugzilla.gnome.org/show_bug.cgi?id=119081.
See: http://mail.gnome.org/archives/gtk-i18n-list/2003-August/msg00001.html
for details. */
static void
init_dpi_conversion_factor ()
{
GtkSettings *settings = gtk_settings_get_default ();
GObjectClass *klass;
klass = G_OBJECT_CLASS (GTK_SETTINGS_GET_CLASS (settings));
if (g_object_class_find_property (klass, "gtk-xft-dpi"))
{
int int_dpi;
g_object_get (settings, "gtk-xft-dpi", &int_dpi, NULL);
/* If int_dpi == -1 gtk-xft-dpi returns the default value. So we
have to do approximate calculation here. */
if (int_dpi < 0)
cp_gtk_dpi_conversion_factor = PANGO_SCALE * 72.0 / 96.;
else
cp_gtk_dpi_conversion_factor =
PANGO_SCALE * 72.0 / (int_dpi / PANGO_SCALE);
g_signal_connect (settings, "notify::gtk-xft-dpi",
G_CALLBACK (dpi_changed_cb), NULL);
}
else
/* Approximate. */
cp_gtk_dpi_conversion_factor = PANGO_SCALE * 72.0 / 96.;
}
static void
dpi_changed_cb (GtkSettings *settings,
GParamSpec *pspec __attribute__((unused)))
{
int int_dpi;
g_object_get (settings, "gtk-xft-dpi", &int_dpi, NULL);
if (int_dpi < 0)
cp_gtk_dpi_conversion_factor = PANGO_SCALE * 72.0 / 96.;
else
cp_gtk_dpi_conversion_factor =
PANGO_SCALE * 72.0 / (int_dpi / PANGO_SCALE);
}
static int
within_human_latency_tolerance(struct timeval *init)
{
struct timeval curr;
unsigned long milliseconds_elapsed;
gettimeofday(&curr, NULL);
milliseconds_elapsed = (((curr.tv_sec * 1000) + (curr.tv_usec / 1000))
- ((init->tv_sec * 1000) + (init->tv_usec / 1000)));
return milliseconds_elapsed < 100;
}
#if GTK_MINOR_VERSION > 4
static void
glog_func (const gchar *log_domain,
GLogLevelFlags log_level,
const gchar *message,
gpointer user_data)
{
old_glog_func (log_domain, log_level, message, user_data);
if (log_level & (G_LOG_LEVEL_ERROR
| G_LOG_LEVEL_CRITICAL
| G_LOG_LEVEL_WARNING))
{
JNIEnv *env = cp_gtk_gdk_env ();
jthrowable *exc = (*env)->ExceptionOccurred(env);
gchar *detail = g_strconcat (log_domain, ": ", message, NULL);
JCL_ThrowException (env, "java/lang/InternalError", detail);
g_free (detail);
(*env)->ExceptionDescribe (env);
if (exc != NULL)
(*env)->Throw (env, exc);
else
(*env)->ExceptionClear (env);
}
}
#endif
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkToolkit_iterateNativeQueue
(JNIEnv *env,
jobject self __attribute__((unused)),
jobject lockedQueue,
jboolean block)
{
/* We're holding an EventQueue lock, and we're about to acquire the GDK
* lock before dropping the EventQueue lock. This can deadlock if someone
* holds the GDK lock and wants to acquire the EventQueue lock; however
* all callbacks from GTK happen with the GDK lock released, so this
* would only happen in an odd case such as some JNI helper code
* acquiring the GDK lock and calling back into
* EventQueue.getNextEvent().
*/
struct timeval init;
gettimeofday(&init, NULL);
gdk_threads_enter ();
(*env)->MonitorExit (env, lockedQueue);
if (block)
{
/* If we're blocking-when-empty, we want a do .. while loop. */
do
gtk_main_iteration ();
while (within_human_latency_tolerance (&init)
&& gtk_events_pending ());
}
else
{
/* If we're not blocking-when-empty, we want a while loop. */
while (within_human_latency_tolerance (&init)
&& gtk_events_pending ())
gtk_main_iteration ();
}
(*env)->MonitorEnter (env, lockedQueue);
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkToolkit_wakeNativeQueue
(JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)))
{
g_main_context_wakeup (NULL);
}
JNIEXPORT jboolean JNICALL
Java_gnu_java_awt_peer_gtk_GtkToolkit_nativeQueueEmpty
(JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)))
{
jboolean empty = FALSE;
gdk_threads_enter ();
empty = ! gtk_events_pending();
gdk_threads_leave ();
return empty;
}
static jint gdk_color_to_java_color (GdkColor color);
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkToolkit_beep
(JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)))
{
gdk_threads_enter ();
gdk_beep ();
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkToolkit_sync
(JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)))
{
gdk_threads_enter ();
gdk_flush ();
gdk_threads_leave ();
}
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkToolkit_getScreenSizeDimensions
(JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)),
jintArray jdims)
{
jint *dims = (*env)->GetIntArrayElements (env, jdims, 0);
gdk_threads_enter ();
dims[0] = gdk_screen_width ();
dims[1] = gdk_screen_height ();
gdk_threads_leave ();
(*env)->ReleaseIntArrayElements(env, jdims, dims, 0);
}
JNIEXPORT jint JNICALL
Java_gnu_java_awt_peer_gtk_GtkToolkit_getScreenResolution
(JNIEnv *env __attribute__((unused)), jobject obj __attribute__((unused)))
{
jint res;
gdk_threads_enter ();
res = gdk_screen_width () / (gdk_screen_width_mm () / 25.4);
gdk_threads_leave ();
return res;
}
#define CONVERT(type, state) \
gdk_color_to_java_color (style->type[GTK_STATE_ ## state])
JNIEXPORT void JNICALL
Java_gnu_java_awt_peer_gtk_GtkToolkit_loadSystemColors
(JNIEnv *env, jobject obj __attribute__((unused)),
jintArray jcolors)
{
jint *colors;
GtkStyle *style;
gdk_threads_enter ();
colors = (*env)->GetIntArrayElements (env, jcolors, 0);
style = gtk_widget_get_default_style ();
colors[AWT_DESKTOP] = CONVERT (bg, SELECTED);
colors[AWT_ACTIVE_CAPTION] = CONVERT (bg, SELECTED);
colors[AWT_ACTIVE_CAPTION_TEXT] = CONVERT (text, SELECTED);
colors[AWT_ACTIVE_CAPTION_BORDER] = CONVERT (fg, NORMAL);
colors[AWT_INACTIVE_CAPTION] = CONVERT (base, INSENSITIVE);
colors[AWT_INACTIVE_CAPTION_TEXT] = CONVERT (fg, INSENSITIVE);
colors[AWT_INACTIVE_CAPTION_BORDER] = CONVERT (fg, INSENSITIVE);
colors[AWT_WINDOW] = CONVERT (bg, NORMAL);
colors[AWT_WINDOW_BORDER] = CONVERT (fg, NORMAL);
colors[AWT_WINDOW_TEXT] = CONVERT (fg, NORMAL);
colors[AWT_MENU] = CONVERT (bg, NORMAL);
colors[AWT_MENU_TEXT] = CONVERT (fg, NORMAL);
colors[AWT_TEXT] = CONVERT (bg, NORMAL);
colors[AWT_TEXT_TEXT] = CONVERT (fg, NORMAL);
colors[AWT_TEXT_HIGHLIGHT] = CONVERT (bg, SELECTED);
colors[AWT_TEXT_HIGHLIGHT_TEXT] = CONVERT (fg, SELECTED);
colors[AWT_TEXT_INACTIVE_TEXT] = CONVERT (bg, INSENSITIVE);
colors[AWT_CONTROL] = CONVERT (bg, NORMAL);
colors[AWT_CONTROL_TEXT] = CONVERT (fg, NORMAL);
colors[AWT_CONTROL_HIGHLIGHT] = CONVERT (base, ACTIVE);
colors[AWT_CONTROL_LT_HIGHLIGHT] = CONVERT (bg, PRELIGHT);
colors[AWT_CONTROL_SHADOW] = CONVERT (bg, ACTIVE);
colors[AWT_CONTROL_DK_SHADOW] = CONVERT (fg, INSENSITIVE);
colors[AWT_SCROLLBAR] = CONVERT (base, INSENSITIVE);
colors[AWT_INFO] = CONVERT (bg, NORMAL);
colors[AWT_INFO_TEXT] = CONVERT (fg, NORMAL);
(*env)->ReleaseIntArrayElements(env, jcolors, colors, 0);
gdk_threads_leave ();
}
#undef CONVERT
static jint
gdk_color_to_java_color (GdkColor gdk_color)
{
guchar red;
guchar green;
guchar blue;
float factor;
factor = 255.0 / 65535.0;
red = (float) gdk_color.red * factor;
green = (float) gdk_color.green * factor;
blue = (float) gdk_color.blue * factor;
return (jint) (0xff000000 | (red << 16) | (green << 8) | blue);
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More