Initial revision
From-SVN: r102074
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
*.o
|
||||
*.a
|
||||
*.lo
|
||||
*.la
|
||||
.libs
|
||||
.deps
|
||||
Makefile
|
||||
Makefile.in
|
||||
@@ -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.
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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) */
|
||||
@@ -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) */
|
||||
@@ -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) */
|
||||
@@ -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) */
|
||||
@@ -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) */
|
||||
@@ -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) */
|
||||
@@ -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) */
|
||||
@@ -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) */
|
||||
@@ -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).
|
||||
|
||||
*/
|
||||
@@ -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__ */
|
||||
@@ -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__ */
|
||||
@@ -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) */
|
||||
@@ -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) */
|
||||
@@ -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) */
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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__ */
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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) */
|
||||
@@ -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) */
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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) */
|
||||
@@ -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) */
|
||||
@@ -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) */
|
||||
@@ -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) */
|
||||
@@ -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) */
|
||||
@@ -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) */
|
||||
@@ -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) */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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) */
|
||||
@@ -0,0 +1,8 @@
|
||||
*.o
|
||||
*.a
|
||||
*.lo
|
||||
*.la
|
||||
.libs
|
||||
.deps
|
||||
Makefile
|
||||
Makefile.in
|
||||
@@ -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__ */
|
||||
+70
@@ -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), ¤t_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
Reference in New Issue
Block a user