/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#include "X11SurfaceData.h"
#include "GraphicsPrimitiveMgr.h"
#include "Region.h"
#include "Trace.h"
/* Needed to define intptr_t */
#include "gdefs.h"
#include "jni_util.h"
#include "jvm_md.h"
#include "awt_Component.h"
#include "awt_GraphicsEnv.h"
#include <dlfcn.h>
#ifndef HEADLESS
/**
* This file contains support code for loops using the SurfaceData
* interface to talk to an X11 drawable from native code.
*/
typedef struct _X11RIPrivate {
int x, y;
} X11RIPrivate;
#define MAX(a,b) ((a) > (b) ? (a) : (b))
#define MIN(a,b) ((a) < (b) ? (a) : (b))
#ifndef XAWT
extern struct MComponentPeerIDs mComponentPeerIDs;
#endif
extern AwtGraphicsConfigDataPtr
extern struct X11GraphicsConfigIDs x11GraphicsConfigIDs;
static int nativeByteOrder;
/* Cached shared image, one for all surface datas. */
#endif /* !HEADLESS */
{
#ifndef HEADLESS
union {
char c[4];
int i;
} endian;
endian.i = 0xff000000;
cachedXImage = NULL;
if (sizeof(X11RIPrivate) > SD_RASINFO_PRIVATE_SIZE) {
return JNI_FALSE;
}
#ifdef MITSHM
char * force;
if (permission != NULL) {
}
}
if(allowShmPixmaps) {
}
}
}else {
}
}
return JNI_TRUE;
#endif /* MITSHM */
#endif /* !HEADLESS */
}
/*
* Class: sun_java2d_x11_X11SurfaceData
* Method: initIDs
*/
{
#ifndef HEADLESS
{
void *lib = 0;
/* we use RTLD_NOW because of bug 4032715 */
}
AWT_LOCK();
AWT_UNLOCK();
}
if (ret == JDGA_SUCCESS) {
pJDgaInfo = &theJDgaInfo;
} else {
}
}
}
#endif /* !HEADLESS */
}
/*
* Class: sun_java2d_x11_X11SurfaceData
* Method: isDrawableValid
* Signature: ()Z
*/
{
#ifndef HEADLESS
AWT_LOCK();
}
AWT_UNLOCK();
#endif /* !HEADLESS */
return ret;
}
/*
* Class: sun_java2d_x11_X11SurfaceData
* Method: isShmPMAvailable
* Signature: ()Z
*/
{
return JNI_FALSE;
#else
return useMitShmPixmaps;
#endif /* HEADLESS, MITSHM */
}
/*
* Class: sun_java2d_x11_X11SurfaceData
* Method: isDgaAvailable
* Signature: ()Z
*/
{
return JNI_FALSE;
#else
return dgaAvailable;
#endif /* HEADLESS */
}
/*
* Class: sun_java2d_x11_X11SurfaceData
* Method: initOps
*/
{
#ifndef HEADLESS
return;
}
#ifndef XAWT
cdata = (struct ComponentData *)
return;
}
return;
}
} else {
}
#else
} else {
}
#endif
#ifdef MITSHM
#endif /* MITSHM */
"Native GraphicsConfig data block missing");
return;
}
if (depth > 12) {
} else if (depth == 12) {
} else {
}
#endif /* !HEADLESS */
}
/*
* Class: sun_java2d_x11_X11SurfaceData
* Method: flushNativeSurface
* Signature: ()V
*/
{
#ifndef HEADLESS
}
#endif /* !HEADLESS */
}
{
#ifdef HEADLESS
return NULL;
#else
}
#endif /* !HEADLESS */
}
/*
* Method for disposing X11SD-specific data
*/
static void
{
#ifndef HEADLESS
/* ops is assumed non-null as it is checked in SurfaceData_DisposeOps */
AWT_LOCK();
}
#ifdef MITSHM
}
}
}
#else
#endif /* MITSHM */
}
}
}
}
}
AWT_UNLOCK();
#endif /* !HEADLESS */
}
/*
* Class: sun_java2d_x11_X11SurfaceData
* Method: setInvalid
* Signature: ()V
*/
{
#ifndef HEADLESS
}
#endif /* !HEADLESS */
}
jboolean XShared_initSurface(JNIEnv *env, X11SDOps *xsdo, jint depth, jint width, jint height, jlong drawable)
{
#ifndef HEADLESS
/* Double-buffering */
} else {
/* REMIND: workaround for bug 4420220 on pgx32 boards:
don't use DGA with pixmaps unless USE_DGA_PIXMAPS is set.
*/
#ifdef MITSHM
if (forceSharedPixmaps) {
AWT_LOCK();
AWT_UNLOCK();
return JNI_TRUE;
}
}
#endif /* MITSHM */
AWT_LOCK();
AWT_UNLOCK();
#ifdef MITSHM
#endif /* MITSHM */
}
"Can't create offscreen surface");
return JNI_FALSE;
}
return JNI_TRUE;
#endif /* !HEADLESS */
}
/*
* Class: sun_java2d_x11_X11SurfaceData
* Method: initSurface
* Signature: ()V
*/
{
#ifndef HEADLESS
return;
}
}
/* color_data will be initialized in awtJNI_CreateColorData for
8-bit visuals */
#endif /* !HEADLESS */
}
#ifndef HEADLESS
#ifdef MITSHM
{
/* REMIND: we don't need shmctl(shminfo->shmid, IPC_RMID, 0); here. */
/* Check X11SD_CreateSharedImage() for the explanation */
}
}
{
return NULL;
}
return NULL;
}
"X11SD_SetupSharedSegment shmget has failed: %s",
return NULL;
}
"X11SD_SetupSharedSegment shmat has failed: %s",
return NULL;
}
/*
* Once the XSync round trip has finished then we
* can get rid of the id so that this segment does not stick
* around after we go away, holding system resources.
*/
if (xShmAttachResult == JNI_FALSE) {
"X11SD_SetupSharedSegment XShmAttach has failed: %s",
return NULL;
}
return img;
}
{
if (cachedXImage != NULL &&
/* sync so previous data gets flushed */
}
return retImage;
}
{
int scan;
/* only use shared mem pixmaps for relatively big images */
return 0;
}
/* need to create shared(!) image to get bytes_per_line */
return 0;
}
pixmap =
if (pixmap == 0) {
return 0;
}
return pixmap;
}
{
return;
}
/* we wouldn't be here if it's a shared pixmap, so no check
* for !usingShmPixmap.
*/
}
}
}
}
}
{
return;
}
{
}
}
}
}
} else {
}
}
/**
* Determines if the cached image can be used for current operation.
* If the image is to be used to be read into by XShmGetImage,
* it must be close enough to avoid excessive reading from the screen;
* otherwise it should just be at least the size requested.
*/
{
/* we assume here that the cached image exists */
/* doesn't fit if any of the cached image dimensions is smaller
or the depths are different */
return JNI_FALSE;
}
if (!readBits) {
/* Not reading from this image, so any image at least of the
size requested will do */
return JNI_TRUE;
}
{
* larger than requested, because the region in XShmGetImage
* can't be specified and we don't want to read too much.
* so drawables are not read out of bounds.
*/
return JNI_TRUE;
}
return JNI_FALSE;
}
#endif /* MITSHM */
{
return SD_FAILURE;
}
#ifndef XAWT
/* AWT_UNLOCK(); unlock it in caller */
return SD_FAILURE;
}
#endif
return SD_SUCCESS;
}
{
AWT_LOCK();
AWT_UNLOCK();
return SD_FAILURE;
}
#ifdef XAWT
#endif
AWT_UNLOCK();
return SD_FAILURE;
}
if ((lockflags & SD_LOCK_LUT) != 0 &&
{
AWT_UNLOCK();
return SD_FAILURE;
}
if ((lockflags & SD_LOCK_INVCOLOR) != 0 &&
{
AWT_UNLOCK();
return SD_FAILURE;
}
if ((lockflags & SD_LOCK_INVGRAY) != 0 &&
{
AWT_UNLOCK();
return SD_FAILURE;
}
int dgaret;
if (dgaret == JDGA_SUCCESS) {
return SD_SUCCESS;
} else if (dgaret == JDGA_UNAVAILABLE) {
}
}
if (lockflags & SD_LOCK_RD_WR) {
if (lockflags & SD_LOCK_FASTEST) {
ret = SD_SLOWLOCK;
}
#ifdef MITSHM
}
#endif /* MITSHM */
}
}
}
}
}
} else {
/* They didn't lock for anything - we won't give them anything */
}
return ret;
/* AWT_UNLOCK() called in Unlock */
}
{
if (xsdo->dgaAvailable &&
(lockFlags & SD_LOCK_FASTEST))
{
/* Try one more time to use DGA (now with smaller bounds)... */
int dgaret;
if (dgaret == JDGA_SUCCESS) {
} else if (dgaret == JDGA_UNAVAILABLE) {
}
}
pRasInfo->pixelBitOffset = 0;
#ifdef MITSHM
/* need to sync before using shared mem pixmap
if any x calls were issued for this pixmap */
}
pRasInfo->pixelBitOffset = 0;
#endif /* MITSHM */
int x, y, w, h;
xpriv->x = x;
xpriv->y = y;
pRasInfo->pixelBitOffset = 0;
} else {
pRasInfo->pixelStride = 0;
pRasInfo->pixelBitOffset = 0;
pRasInfo->scanStride = 0;
}
} else {
/* They didn't lock for anything - we won't give them anything */
pRasInfo->pixelStride = 0;
pRasInfo->pixelBitOffset = 0;
pRasInfo->scanStride = 0;
}
if (lockFlags & SD_LOCK_LUT) {
} else {
}
if (lockFlags & SD_LOCK_INVCOLOR) {
} else {
}
if (lockFlags & SD_LOCK_INVGRAY) {
} else {
}
}
{
{
int x = xpriv->x;
int y = xpriv->y;
}
/* switching bytes back in 24 and 32 bpp cases. */
/* For 16 bit XLib will switch for us. */
}
}
#ifdef MITSHM
} else {
}
}
#else
#endif /* MITSHM */
}
}
/* the background pixel is not valid anymore */
}
AWT_UNLOCK();
}
static int
{
#ifndef XAWT
}
if (w == NULL) {
return FALSE;
}
/*
* REMIND: We should not be offsetting here by border_width
* but for some unknown reason if we do not do that the
* results will be off exactly by border_width. We were unable
* to find cause of this.
*/
(int) w->core.border_width,
(int) w->core.border_width,
#else
if (status == 0) {
/* Failure, X window no longer valid. */
return FALSE;
}
return FALSE;
}
#endif
return FALSE;
}
return TRUE;
}
/*
* x1, y1, x2, y2 - our rectangle in the coord system of
* the widget
* px1, xy1, px2, py2 - current parent rect coords in the
* same system
*/
static int
{
#ifndef XAWT
return FALSE;
}
}
if (current_widget == NULL) {
&ignore_uint);
} else {
}
while (current_window != 0) {
&pborder, &ignore_uint)) {
return FALSE;
}
return FALSE;
}
&ignore_uint);
}
#endif
return TRUE;
}
static void
int i;
switch (depth) {
case 12:
case 15:
case 16:
{
/* AB -> BA */
unsigned short t;
for (i = 0; i < lengthInBytes/2; i++) {
t = *d;
*d++ = (t >> 8) | (t << 8);
}
break;
}
case 24:
{
/* ABC -> CBA */
if (bpp == 24) {
// 4517321: Only swap if we have a "real" ThreeByteBgr
// visual (denoted by a red_mask of 0xff). Due to ambiguity
// in the X11 spec, it appears that the swap is not required
// on Linux configurations that use 24 bits per pixel (denoted
// by a red_mask of 0xff0000).
unsigned char *d1;
unsigned int t;
int j;
d1 = d;
/* not obvious opt from XLib src */
}
}
}
break;
}
}
/* FALL THROUGH for 32-bit case */
case 32:
{
/* ABCD -> DCBA */
unsigned int t;
for (i = 0; i < lengthInBytes/4; i++) {
t = *d;
*d++ = ((t >> 24) |
((t >> 8) & 0xff00) |
((t & 0xff00) << 8) |
(t << 24));
}
break;
}
}
}
{
int scan;
#ifdef MITSHM
if (useMitShmExt == CAN_USE_MITSHM) {
if (readBits) {
X11SD_PuntPixmap(xsdo, w, h);
}
} else {
} else {
/* XGWA failed which isn't a good thing. Defaulting to using
* x,y means that after the subtraction of these we will use
* w=0, h=0 which is a reasonable default on such a failure.
*/
maxWidth = x;
maxHeight = y;
}
}
maxWidth -= x;
maxHeight -= y;
}
#endif /* MITSHM */
if (readBits) {
#ifdef MITSHM
}
}
}
}
#else
#endif /* MITSHM */
return NULL;
}
return NULL;
}
-1, ZPixmap);
if (temp_image == NULL) {
-1, ZPixmap);
}
/* Workaround for bug 5039226 */
}
if (temp_image != NULL) {
int i;
}
}
}
}
}
} else {
/*
* REMIND: This might be better to move to the Lock function
* to avoid lengthy I/O pauses inside what may be a critical
* section. This will be more critical when SD_LOCK_READ is
* implemented. Another solution is to cache the pixels
* to avoid reading for every operation.
*/
return NULL;
}
return NULL;
}
/* bytes will be swapped by XLib. */
}
}
}
return img;
}
/* REMIND: might want to check if the new image worth caching. */
/* Cache only shared images. Passed image is assumed to be non-null. */
if (cachedXImage != NULL) {
}
} else {
}
}
#ifdef MITSHM
}
#endif /* MITSHM */
}
}
static JDgaStatus
{
return JDGA_UNAVAILABLE;
}
static JDgaStatus
{
return JDGA_FAILED;
}
static void
{
}
static void
{
}
NULL,
};
AWT_LOCK();
}
AWT_UNLOCK();
}
void
{
#ifdef MITSHM
}
#endif /* MITSHM */
}
/*
* Sets transparent pixels in the pixmap to
* the specified solid background color and returns it.
* Doesn't update source pixmap unless the color of the
* transparent pixels is different from the specified color.
*
* Note: The AWT lock must be held by the current thread
* while calling into this method.
*/
static Drawable
{
/* assert AWT_CHECK_HAVE_LOCK(); */
AWT_UNLOCK();
return 0;
}
/* the image doesn't have transparency, just return it */
/* don't need to unlock here, the caller will unlock through
the release call */
}
/* Check if current color of the transparent pixels is different
from the specified one */
AWT_UNLOCK();
return 0;
}
AWT_UNLOCK();
return 0;
}
/* invert the bitmask */
AWT_UNLOCK();
return 0;
}
/* set transparent pixels in the source pm to the bg color */
/* invert the mask back */
}
}
static void
{
#ifdef MITSHM
}
#endif /* MITSHM */
}
#endif /* !HEADLESS */
/*
* Class: sun_java2d_x11_X11SurfaceData
* Method: XCreateGC
* Signature: (I)J
*/
{
#ifndef HEADLESS
return 0L;
}
#else /* !HEADLESS */
ret = 0L;
#endif /* !HEADLESS */
return ret;
}
/*
* Class: sun_java2d_x11_X11SurfaceData
* Method: XResetClip
*/
{
#ifndef HEADLESS
#endif /* !HEADLESS */
}
/*
* Class: sun_java2d_x11_X11SurfaceData
* Method: XSetClip
*/
{
#ifndef HEADLESS
int numrects;
&pRect, 256);
}
#endif /* !HEADLESS */
}
/*
* Class: sun_java2d_x11_X11SurfaceData
* Method: XSetCopyMode
* Signature: (J)V
*/
{
#ifndef HEADLESS
#endif /* !HEADLESS */
}
/*
* Class: sun_java2d_x11_X11SurfaceData
* Method: XSetXorMode
* Signature: (J)V
*/
{
#ifndef HEADLESS
#endif /* !HEADLESS */
}
/*
* Class: sun_java2d_x11_X11SurfaceData
* Method: XSetForeground
* Signature: (JI)V
*/
{
#ifndef HEADLESS
#endif /* !HEADLESS */
}
/*
* Class: sun_java2d_x11_X11SurfaceData
* Method: XSetGraphicsExposures
* Signature: (JZ)V
*/
{
#ifndef HEADLESS
#endif /* !HEADLESS */
}