Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/solaris/native/sun/java2d/x11/X11SurfaceData.c
32288 views
/*1* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425#include "X11SurfaceData.h"26#include "GraphicsPrimitiveMgr.h"27#include "Region.h"28#include "Trace.h"2930/* Needed to define intptr_t */31#include "gdefs.h"3233#include "jni_util.h"34#include "jvm_md.h"35#include "awt_Component.h"36#include "awt_GraphicsEnv.h"3738#include <dlfcn.h>3940#ifndef HEADLESS41static JDgaLibInfo DgaLibInfoStub;42static JDgaLibInfo theJDgaInfo;43static JDgaLibInfo *pJDgaInfo = &DgaLibInfoStub;444546/**47* This file contains support code for loops using the SurfaceData48* interface to talk to an X11 drawable from native code.49*/5051typedef struct _X11RIPrivate {52jint lockType;53jint lockFlags;54XImage *img;55int x, y;56} X11RIPrivate;5758#define XSD_MAX(a,b) ((a) > (b) ? (a) : (b))59#define XSD_MIN(a,b) ((a) < (b) ? (a) : (b))6061static LockFunc X11SD_Lock;62static GetRasInfoFunc X11SD_GetRasInfo;63static UnlockFunc X11SD_Unlock;64static DisposeFunc X11SD_Dispose;65static GetPixmapBgFunc X11SD_GetPixmapWithBg;66static ReleasePixmapBgFunc X11SD_ReleasePixmapWithBg;67extern int XShmAttachXErrHandler(Display *display, XErrorEvent *xerr);68extern AwtGraphicsConfigDataPtr69getGraphicsConfigFromComponentPeer(JNIEnv *env, jobject this);70extern struct X11GraphicsConfigIDs x11GraphicsConfigIDs;7172static int X11SD_FindClip(SurfaceDataBounds *b, SurfaceDataBounds *bounds,73X11SDOps *xsdo);74static int X11SD_ClipToRoot(SurfaceDataBounds *b, SurfaceDataBounds *bounds,75X11SDOps *xsdo);76static void X11SD_SwapBytes(X11SDOps *xsdo, XImage *img, int depth, int bpp);77static XImage * X11SD_GetImage(JNIEnv *env, X11SDOps *xsdo,78SurfaceDataBounds *bounds,79jint lockFlags);80static int X11SD_GetBitmapPad(int pixelStride);8182extern jfieldID validID;8384static int nativeByteOrder;85static jboolean dgaAvailable = JNI_FALSE;86static jboolean useDGAWithPixmaps = JNI_FALSE;87static jclass xorCompClass;8889jint useMitShmExt = CANT_USE_MITSHM;90jint useMitShmPixmaps = CANT_USE_MITSHM;91jint forceSharedPixmaps = JNI_FALSE;92int mitShmPermissionMask = MITSHM_PERM_OWNER;9394/* Cached shared image, one for all surface datas. */95static XImage * cachedXImage;9697#endif /* !HEADLESS */9899jboolean XShared_initIDs(JNIEnv *env, jboolean allowShmPixmaps)100{101#ifndef HEADLESS102union {103char c[4];104int i;105} endian;106107endian.i = 0xff000000;108nativeByteOrder = (endian.c[0]) ? MSBFirst : LSBFirst;109110dgaAvailable = JNI_FALSE;111112cachedXImage = NULL;113114if (sizeof(X11RIPrivate) > SD_RASINFO_PRIVATE_SIZE) {115JNU_ThrowInternalError(env, "Private RasInfo structure too large!");116return JNI_FALSE;117}118119#ifdef MITSHM120if (getenv("NO_AWT_MITSHM") == NULL &&121getenv("NO_J2D_MITSHM") == NULL) {122char * force;123char * permission = getenv("J2D_MITSHM_PERMISSION");124if (permission != NULL) {125if (strcmp(permission, "common") == 0) {126mitShmPermissionMask = MITSHM_PERM_COMMON;127}128}129130TryInitMITShm(env, &useMitShmExt, &useMitShmPixmaps);131132if(allowShmPixmaps) {133useMitShmPixmaps = (useMitShmPixmaps == CAN_USE_MITSHM);134force = getenv("J2D_PIXMAPS");135if (force != NULL) {136if (useMitShmPixmaps && (strcmp(force, "shared") == 0)) {137forceSharedPixmaps = JNI_TRUE;138} else if (strcmp(force, "server") == 0) {139useMitShmPixmaps = JNI_FALSE;140}141}142}else {143useMitShmPixmaps = JNI_FALSE;144}145}146#endif /* MITSHM */147148#endif /* !HEADLESS */149150return JNI_TRUE;151}152153154/*155* Class: sun_java2d_x11_X11SurfaceData156* Method: initIDs157* Signature: (Ljava/lang/Class;Z)V158*/159JNIEXPORT void JNICALL160Java_sun_java2d_x11_X11SurfaceData_initIDs(JNIEnv *env, jclass xsd,161jclass XORComp, jboolean tryDGA)162{163#ifndef HEADLESS164if(XShared_initIDs(env, JNI_TRUE))165{166void *lib = 0;167168xorCompClass = (*env)->NewGlobalRef(env, XORComp);169170if (tryDGA && (getenv("NO_J2D_DGA") == NULL)) {171/* we use RTLD_NOW because of bug 4032715 */172lib = dlopen(JNI_LIB_NAME("sunwjdga"), RTLD_NOW);173}174175if (lib != NULL) {176JDgaStatus ret = JDGA_FAILED;177void *sym = dlsym(lib, "JDgaLibInit");178if (sym != NULL) {179theJDgaInfo.display = awt_display;180AWT_LOCK();181ret = (*(JDgaLibInitFunc *)sym)(env, &theJDgaInfo);182AWT_UNLOCK();183}184if (ret == JDGA_SUCCESS) {185pJDgaInfo = &theJDgaInfo;186dgaAvailable = JNI_TRUE;187useDGAWithPixmaps = (getenv("USE_DGA_PIXMAPS") != NULL);188} else {189dlclose(lib);190lib = NULL;191}192}193}194#endif /* !HEADLESS */195}196197/*198* Class: sun_java2d_x11_X11SurfaceData199* Method: isDrawableValid200* Signature: ()Z201*/202JNIEXPORT jboolean JNICALL203Java_sun_java2d_x11_XSurfaceData_isDrawableValid(JNIEnv *env, jobject this)204{205jboolean ret = JNI_FALSE;206207#ifndef HEADLESS208X11SDOps *xsdo = X11SurfaceData_GetOps(env, this);209210AWT_LOCK();211if (xsdo->drawable != 0 || X11SD_InitWindow(env, xsdo) == SD_SUCCESS) {212ret = JNI_TRUE;213}214AWT_UNLOCK();215#endif /* !HEADLESS */216217return ret;218}219220/*221* Class: sun_java2d_x11_X11SurfaceData222* Method: isShmPMAvailable223* Signature: ()Z224*/225JNIEXPORT jboolean JNICALL226Java_sun_java2d_x11_X11SurfaceData_isShmPMAvailable(JNIEnv *env, jobject this)227{228#if defined(HEADLESS) || !defined(MITSHM)229return JNI_FALSE;230#else231return (jboolean)useMitShmPixmaps;232#endif /* HEADLESS, MITSHM */233}234235/*236* Class: sun_java2d_x11_X11SurfaceData237* Method: isDgaAvailable238* Signature: ()Z239*/240JNIEXPORT jboolean JNICALL241Java_sun_java2d_x11_X11SurfaceData_isDgaAvailable(JNIEnv *env, jobject this)242{243#if defined(HEADLESS) || defined(__linux__)244return JNI_FALSE;245#else246return dgaAvailable;247#endif /* HEADLESS */248}249250/*251* Class: sun_java2d_x11_X11SurfaceData252* Method: initOps253* Signature: (Ljava/lang/Object;I)V254*/255JNIEXPORT void JNICALL256Java_sun_java2d_x11_XSurfaceData_initOps(JNIEnv *env, jobject xsd,257jobject peer,258jobject graphicsConfig, jint depth)259{260#ifndef HEADLESS261X11SDOps *xsdo = (X11SDOps*)SurfaceData_InitOps(env, xsd, sizeof(X11SDOps));262jboolean hasException;263if (xsdo == NULL) {264JNU_ThrowOutOfMemoryError(env, "Initialization of SurfaceData failed.");265return;266}267xsdo->sdOps.Lock = X11SD_Lock;268xsdo->sdOps.GetRasInfo = X11SD_GetRasInfo;269xsdo->sdOps.Unlock = X11SD_Unlock;270xsdo->sdOps.Dispose = X11SD_Dispose;271xsdo->GetPixmapWithBg = X11SD_GetPixmapWithBg;272xsdo->ReleasePixmapWithBg = X11SD_ReleasePixmapWithBg;273xsdo->widget = NULL;274if (peer != NULL) {275xsdo->drawable = JNU_CallMethodByName(env, &hasException, peer, "getWindow", "()J").j;276if (hasException) {277return;278}279} else {280xsdo->drawable = 0;281}282xsdo->depth = depth;283xsdo->dgaAvailable = dgaAvailable;284xsdo->isPixmap = JNI_FALSE;285xsdo->bitmask = 0;286xsdo->bgPixel = 0;287xsdo->isBgInitialized = JNI_FALSE;288#ifdef MITSHM289xsdo->shmPMData.shmSegInfo = NULL;290xsdo->shmPMData.xRequestSent = JNI_FALSE;291xsdo->shmPMData.pmSize = 0;292xsdo->shmPMData.usingShmPixmap = JNI_FALSE;293xsdo->shmPMData.pixmap = 0;294xsdo->shmPMData.shmPixmap = 0;295xsdo->shmPMData.numBltsSinceRead = 0;296xsdo->shmPMData.pixelsReadSinceBlt = 0;297xsdo->shmPMData.numBltsThreshold = 2;298#endif /* MITSHM */299300xsdo->configData = (AwtGraphicsConfigDataPtr)301JNU_GetLongFieldAsPtr(env,302graphicsConfig,303x11GraphicsConfigIDs.aData);304if (xsdo->configData == NULL) {305JNU_ThrowNullPointerException(env,306"Native GraphicsConfig data block missing");307return;308}309if (depth > 12) {310xsdo->pixelmask = (xsdo->configData->awt_visInfo.red_mask |311xsdo->configData->awt_visInfo.green_mask |312xsdo->configData->awt_visInfo.blue_mask);313} else if (depth == 12) {314xsdo->pixelmask = 0xfff;315} else {316xsdo->pixelmask = 0xff;317}318319xsdo->xrPic = None;320#endif /* !HEADLESS */321}322323/*324* Class: sun_java2d_x11_X11SurfaceData325* Method: flushNativeSurface326* Signature: ()V327*/328JNIEXPORT void JNICALL329Java_sun_java2d_x11_XSurfaceData_flushNativeSurface(JNIEnv *env, jobject xsd)330{331#ifndef HEADLESS332SurfaceDataOps *ops = SurfaceData_GetOps(env, xsd);333334if (ops != NULL) {335X11SD_Dispose(env, ops);336}337#endif /* !HEADLESS */338}339340341JNIEXPORT X11SDOps * JNICALL342X11SurfaceData_GetOps(JNIEnv *env, jobject sData)343{344#ifdef HEADLESS345return NULL;346#else347SurfaceDataOps *ops = SurfaceData_GetOps(env, sData);348if (ops != NULL && ops->Lock != X11SD_Lock) {349SurfaceData_ThrowInvalidPipeException(env, "not an X11 SurfaceData");350ops = NULL;351}352return (X11SDOps *) ops;353#endif /* !HEADLESS */354}355356/*357* Method for disposing X11SD-specific data358*/359static void360X11SD_Dispose(JNIEnv *env, SurfaceDataOps *ops)361{362#ifndef HEADLESS363/* ops is assumed non-null as it is checked in SurfaceData_DisposeOps */364X11SDOps * xsdo = (X11SDOps*)ops;365366AWT_LOCK();367368xsdo->invalid = JNI_TRUE;369370if (xsdo->xrPic != None) {371XRenderFreePicture(awt_display, xsdo->xrPic);372xsdo->xrPic = None;373}374375if (xsdo->isPixmap == JNI_TRUE && xsdo->drawable != 0) {376#ifdef MITSHM377if (xsdo->shmPMData.shmSegInfo != NULL) {378X11SD_DropSharedSegment(xsdo->shmPMData.shmSegInfo);379xsdo->shmPMData.shmSegInfo = NULL;380}381if (xsdo->shmPMData.pixmap) {382XFreePixmap(awt_display, xsdo->shmPMData.pixmap);383xsdo->shmPMData.pixmap = 0;384}385if (xsdo->shmPMData.shmPixmap) {386XFreePixmap(awt_display, xsdo->shmPMData.shmPixmap);387xsdo->shmPMData.shmPixmap = 0;388}389#else390XFreePixmap(awt_display, xsdo->drawable);391#endif /* MITSHM */392xsdo->drawable = 0;393}394if (xsdo->bitmask != 0) {395XFreePixmap(awt_display, xsdo->bitmask);396xsdo->bitmask = 0;397}398if (xsdo->javaGC != NULL) {399XFreeGC(awt_display, xsdo->javaGC);400xsdo->javaGC = NULL;401}402if (xsdo->cachedGC != NULL) {403XFreeGC(awt_display, xsdo->cachedGC);404xsdo->cachedGC = NULL;405}406407if(xsdo->xrPic != None) {408XRenderFreePicture(awt_display, xsdo->xrPic);409}410411AWT_UNLOCK();412#endif /* !HEADLESS */413}414/*415* Class: sun_java2d_x11_X11SurfaceData416* Method: setInvalid417* Signature: ()V418*/419JNIEXPORT void JNICALL420Java_sun_java2d_x11_XSurfaceData_setInvalid(JNIEnv *env, jobject xsd)421{422#ifndef HEADLESS423X11SDOps *xsdo = (X11SDOps *) SurfaceData_GetOps(env, xsd);424425if (xsdo != NULL) {426xsdo->invalid = JNI_TRUE;427}428#endif /* !HEADLESS */429}430431432jboolean XShared_initSurface(JNIEnv *env, X11SDOps *xsdo, jint depth, jint width, jint height, jlong drawable)433{434#ifndef HEADLESS435436if (drawable != (jlong)0) {437/* Double-buffering */438xsdo->drawable = drawable;439xsdo->isPixmap = JNI_FALSE;440} else {441jboolean sizeIsInvalid = JNI_FALSE;442jlong scan = 0;443444/*445* width , height must be nonzero otherwise XCreatePixmap446* generates BadValue in error_handler447*/448if (width <= 0 || height <= 0 || width > 32767 || height > 32767) {449sizeIsInvalid = JNI_TRUE;450} else {451XImage* tmpImg = NULL;452453AWT_LOCK();454tmpImg = XCreateImage(awt_display,455xsdo->configData->awt_visInfo.visual,456depth, ZPixmap, 0, NULL, width, height,457X11SD_GetBitmapPad(xsdo->configData->pixelStride), 0);458if (tmpImg) {459scan = (jlong) tmpImg->bytes_per_line;460XDestroyImage(tmpImg);461tmpImg = NULL;462}463AWT_UNLOCK();464JNU_CHECK_EXCEPTION_RETURN(env, JNI_FALSE);465}466467if (sizeIsInvalid || (scan * height > 0x7FFFFFFFL)) {468JNU_ThrowOutOfMemoryError(env,469"Can't create offscreen surface");470return JNI_FALSE;471}472xsdo->isPixmap = JNI_TRUE;473/* REMIND: workaround for bug 4420220 on pgx32 boards:474don't use DGA with pixmaps unless USE_DGA_PIXMAPS is set.475*/476xsdo->dgaAvailable = useDGAWithPixmaps;477478xsdo->pmWidth = width;479xsdo->pmHeight = height;480481#ifdef MITSHM482xsdo->shmPMData.pmSize = (jlong) width * height * depth;483xsdo->shmPMData.pixelsReadThreshold = width * height / 8;484if (forceSharedPixmaps) {485AWT_LOCK();486xsdo->drawable = X11SD_CreateSharedPixmap(xsdo);487AWT_UNLOCK();488JNU_CHECK_EXCEPTION_RETURN(env, JNI_FALSE);489if (xsdo->drawable) {490xsdo->shmPMData.usingShmPixmap = JNI_TRUE;491xsdo->shmPMData.shmPixmap = xsdo->drawable;492return JNI_TRUE;493}494}495#endif /* MITSHM */496497AWT_LOCK();498xsdo->drawable =499XCreatePixmap(awt_display,500RootWindow(awt_display,501xsdo->configData->awt_visInfo.screen),502width, height, depth);503AWT_UNLOCK();504JNU_CHECK_EXCEPTION_RETURN(env, JNI_FALSE);505#ifdef MITSHM506xsdo->shmPMData.usingShmPixmap = JNI_FALSE;507xsdo->shmPMData.pixmap = xsdo->drawable;508#endif /* MITSHM */509}510if (xsdo->drawable == 0) {511JNU_ThrowOutOfMemoryError(env,512"Can't create offscreen surface");513return JNI_FALSE;514}515516#endif /* !HEADLESS */517return JNI_TRUE;518}519520521/*522* Class: sun_java2d_x11_X11SurfaceData523* Method: initSurface524* Signature: ()V525*/526JNIEXPORT void JNICALL527Java_sun_java2d_x11_X11SurfaceData_initSurface(JNIEnv *env, jclass xsd,528jint depth,529jint width, jint height,530jlong drawable)531{532#ifndef HEADLESS533X11SDOps *xsdo = X11SurfaceData_GetOps(env, xsd);534if (xsdo == NULL) {535return;536}537538if (xsdo->configData->awt_cmap == (Colormap)NULL) {539awtJNI_CreateColorData(env, xsdo->configData, 1);540JNU_CHECK_EXCEPTION(env);541}542/* color_data will be initialized in awtJNI_CreateColorData for5438-bit visuals */544xsdo->cData = xsdo->configData->color_data;545546XShared_initSurface(env, xsdo, depth, width, height, drawable);547xsdo->xrPic = NULL;548#endif /* !HEADLESS */549}550551#ifndef HEADLESS552553#ifdef MITSHM554555void X11SD_DropSharedSegment(XShmSegmentInfo *shminfo)556{557if (shminfo != NULL) {558XShmDetach(awt_display, shminfo);559shmdt(shminfo->shmaddr);560/* REMIND: we don't need shmctl(shminfo->shmid, IPC_RMID, 0); here. */561/* Check X11SD_CreateSharedImage() for the explanation */562}563}564565XImage* X11SD_CreateSharedImage(X11SDOps *xsdo,566jint width, jint height)567{568XImage *img = NULL;569XShmSegmentInfo *shminfo;570571shminfo = malloc(sizeof(XShmSegmentInfo));572if (shminfo == NULL) {573return NULL;574}575memset(shminfo, 0, sizeof(XShmSegmentInfo));576577img = XShmCreateImage(awt_display, xsdo->configData->awt_visInfo.visual,578xsdo->depth, ZPixmap, NULL, shminfo,579width, height);580if (img == NULL) {581free((void *)shminfo);582return NULL;583}584shminfo->shmid =585shmget(IPC_PRIVATE, (size_t) height * img->bytes_per_line,586IPC_CREAT|mitShmPermissionMask);587if (shminfo->shmid < 0) {588J2dRlsTraceLn1(J2D_TRACE_ERROR,589"X11SD_SetupSharedSegment shmget has failed: %s",590strerror(errno));591free((void *)shminfo);592XDestroyImage(img);593return NULL;594}595596shminfo->shmaddr = (char *) shmat(shminfo->shmid, 0, 0);597if (shminfo->shmaddr == ((char *) -1)) {598shmctl(shminfo->shmid, IPC_RMID, 0);599J2dRlsTraceLn1(J2D_TRACE_ERROR,600"X11SD_SetupSharedSegment shmat has failed: %s",601strerror(errno));602free((void *)shminfo);603XDestroyImage(img);604return NULL;605}606607shminfo->readOnly = False;608609resetXShmAttachFailed();610EXEC_WITH_XERROR_HANDLER(XShmAttachXErrHandler,611XShmAttach(awt_display, shminfo));612613/*614* Once the XSync round trip has finished then we615* can get rid of the id so that this segment does not stick616* around after we go away, holding system resources.617*/618shmctl(shminfo->shmid, IPC_RMID, 0);619620if (isXShmAttachFailed() == JNI_TRUE) {621J2dRlsTraceLn1(J2D_TRACE_ERROR,622"X11SD_SetupSharedSegment XShmAttach has failed: %s",623strerror(errno));624shmdt(shminfo->shmaddr);625free((void *)shminfo);626XDestroyImage(img);627return NULL;628}629630img->data = shminfo->shmaddr;631img->obdata = (char *)shminfo;632633return img;634}635636XImage* X11SD_GetSharedImage(X11SDOps *xsdo, jint width, jint height,637jint maxWidth, jint maxHeight, jboolean readBits)638{639XImage * retImage = NULL;640if (cachedXImage != NULL &&641X11SD_CachedXImageFits(width, height, maxWidth, maxHeight,642xsdo->depth, readBits)) {643/* sync so previous data gets flushed */644XSync(awt_display, False);645retImage = cachedXImage;646cachedXImage = (XImage *)NULL;647} else if ((jlong) width * height * xsdo->depth > 0x10000) {648retImage = X11SD_CreateSharedImage(xsdo, width, height);649}650return retImage;651}652653Drawable X11SD_CreateSharedPixmap(X11SDOps *xsdo)654{655XShmSegmentInfo *shminfo;656XImage *img = NULL;657Drawable pixmap;658int scan;659int width = xsdo->pmWidth;660int height = xsdo->pmHeight;661662if (xsdo->shmPMData.pmSize < 0x10000) {663/* only use shared mem pixmaps for relatively big images */664return 0;665}666667/* need to create shared(!) image to get bytes_per_line */668img = X11SD_CreateSharedImage(xsdo, width, height);669if (img == NULL) {670return 0;671}672scan = img->bytes_per_line;673shminfo = (XShmSegmentInfo*)img->obdata;674XFree(img);675676pixmap =677XShmCreatePixmap(awt_display,678RootWindow(awt_display,679xsdo->configData->awt_visInfo.screen),680shminfo->shmaddr, shminfo,681width, height, xsdo->depth);682if (pixmap == 0) {683X11SD_DropSharedSegment(shminfo);684return 0;685}686687xsdo->shmPMData.shmSegInfo = shminfo;688xsdo->shmPMData.bytesPerLine = scan;689return pixmap;690}691692void X11SD_PuntPixmap(X11SDOps *xsdo, jint width, jint height)693{694695if (useMitShmPixmaps != CAN_USE_MITSHM || forceSharedPixmaps) {696return;697}698699/* we wouldn't be here if it's a shared pixmap, so no check700* for !usingShmPixmap.701*/702703xsdo->shmPMData.numBltsSinceRead = 0;704705xsdo->shmPMData.pixelsReadSinceBlt += width * height;706if (xsdo->shmPMData.pixelsReadSinceBlt >707xsdo->shmPMData.pixelsReadThreshold) {708if (!xsdo->shmPMData.shmPixmap) {709xsdo->shmPMData.shmPixmap =710X11SD_CreateSharedPixmap(xsdo);711}712if (xsdo->shmPMData.shmPixmap) {713GC xgc = XCreateGC(awt_display, xsdo->shmPMData.shmPixmap, 0L, NULL);714if (xgc != NULL) {715xsdo->shmPMData.usingShmPixmap = JNI_TRUE;716xsdo->drawable = xsdo->shmPMData.shmPixmap;717XCopyArea(awt_display,718xsdo->shmPMData.pixmap, xsdo->drawable, xgc,7190, 0, xsdo->pmWidth, xsdo->pmHeight, 0, 0);720XSync(awt_display, False);721xsdo->shmPMData.xRequestSent = JNI_FALSE;722XFreeGC(awt_display, xgc);723}724}725}726}727728void X11SD_UnPuntPixmap(X11SDOps *xsdo)729{730if (useMitShmPixmaps != CAN_USE_MITSHM || forceSharedPixmaps) {731return;732}733xsdo->shmPMData.pixelsReadSinceBlt = 0;734if (xsdo->shmPMData.numBltsSinceRead >=735xsdo->shmPMData.numBltsThreshold)736{737if (xsdo->shmPMData.usingShmPixmap) {738if (!xsdo->shmPMData.pixmap) {739xsdo->shmPMData.pixmap =740XCreatePixmap(awt_display,741RootWindow(awt_display,742xsdo->configData->awt_visInfo.screen),743xsdo->pmWidth, xsdo->pmHeight, xsdo->depth);744}745if (xsdo->shmPMData.pixmap) {746GC xgc = XCreateGC(awt_display, xsdo->shmPMData.pixmap, 0L, NULL);747if (xgc != NULL) {748xsdo->drawable = xsdo->shmPMData.pixmap;749XCopyArea(awt_display,750xsdo->shmPMData.shmPixmap, xsdo->drawable, xgc,7510, 0, xsdo->pmWidth, xsdo->pmHeight, 0, 0);752XSync(awt_display, False);753XFreeGC(awt_display, xgc);754xsdo->shmPMData.xRequestSent = JNI_FALSE;755xsdo->shmPMData.usingShmPixmap = JNI_FALSE;756xsdo->shmPMData.numBltsThreshold *= 2;757}758}759}760} else {761xsdo->shmPMData.numBltsSinceRead++;762}763}764765/**766* Determines if the cached image can be used for current operation.767* If the image is to be used to be read into by XShmGetImage,768* it must be close enough to avoid excessive reading from the screen;769* otherwise it should just be at least the size requested.770*/771jboolean X11SD_CachedXImageFits(jint width, jint height, jint maxWidth,772jint maxHeight, jint depth, jboolean readBits)773{774/* we assume here that the cached image exists */775jint imgWidth = cachedXImage->width;776jint imgHeight = cachedXImage->height;777778if (imgWidth < width || imgHeight < height || depth != cachedXImage->depth) {779/* doesn't fit if any of the cached image dimensions is smaller780or the depths are different */781return JNI_FALSE;782}783784if (!readBits) {785/* Not reading from this image, so any image at least of the786size requested will do */787return JNI_TRUE;788}789790if ((imgWidth < width + 64) && (imgHeight < height + 64)791&& imgWidth <= maxWidth && imgHeight <= maxHeight)792{793/* Cached image's width/height shouldn't be more than 64 pixels794* larger than requested, because the region in XShmGetImage795* can't be specified and we don't want to read too much.796* Furthermore it has to be smaller than maxWidth/Height797* so drawables are not read out of bounds.798*/799return JNI_TRUE;800}801802return JNI_FALSE;803}804#endif /* MITSHM */805806jint X11SD_InitWindow(JNIEnv *env, X11SDOps *xsdo)807{808if (xsdo->isPixmap == JNI_TRUE) {809return SD_FAILURE;810}811xsdo->cData = xsdo->configData->color_data;812813return SD_SUCCESS;814}815816static jint X11SD_Lock(JNIEnv *env,817SurfaceDataOps *ops,818SurfaceDataRasInfo *pRasInfo,819jint lockflags)820{821X11SDOps *xsdo = (X11SDOps *) ops;822X11RIPrivate *xpriv = (X11RIPrivate *) &(pRasInfo->priv);823int ret = SD_SUCCESS;824825AWT_LOCK();826827if (xsdo->invalid) {828AWT_UNLOCK();829SurfaceData_ThrowInvalidPipeException(env, "bounds changed");830return SD_FAILURE;831}832xsdo->cData = xsdo->configData->color_data;833if (xsdo->drawable == 0 && X11SD_InitWindow(env, xsdo) == SD_FAILURE) {834AWT_UNLOCK();835return SD_FAILURE;836}837if ((lockflags & SD_LOCK_LUT) != 0 &&838(xsdo->cData == NULL ||839xsdo->cData->awt_icmLUT == NULL))840{841AWT_UNLOCK();842if (!(*env)->ExceptionCheck(env))843{844JNU_ThrowNullPointerException(env, "colormap lookup table");845}846return SD_FAILURE;847}848if ((lockflags & SD_LOCK_INVCOLOR) != 0 &&849(xsdo->cData == NULL ||850xsdo->cData->img_clr_tbl == NULL ||851xsdo->cData->img_oda_red == NULL ||852xsdo->cData->img_oda_green == NULL ||853xsdo->cData->img_oda_blue == NULL))854{855AWT_UNLOCK();856if (!(*env)->ExceptionCheck(env))857{858JNU_ThrowNullPointerException(env, "inverse colormap lookup table");859}860return SD_FAILURE;861}862if ((lockflags & SD_LOCK_INVGRAY) != 0 &&863(xsdo->cData == NULL ||864xsdo->cData->pGrayInverseLutData == NULL))865{866AWT_UNLOCK();867if (!(*env)->ExceptionCheck(env))868{869JNU_ThrowNullPointerException(env, "inverse gray lookup table");870}871return SD_FAILURE;872}873if (xsdo->dgaAvailable && (lockflags & (SD_LOCK_RD_WR))) {874int dgaret;875876dgaret = (*pJDgaInfo->pGetLock)(env, awt_display, &xsdo->dgaDev,877xsdo->drawable, &xsdo->surfInfo,878pRasInfo->bounds.x1,879pRasInfo->bounds.y1,880pRasInfo->bounds.x2,881pRasInfo->bounds.y2);882if (dgaret == JDGA_SUCCESS) {883int wx = xsdo->surfInfo.window.lox;884int wy = xsdo->surfInfo.window.loy;885pRasInfo->bounds.x1 = xsdo->surfInfo.visible.lox - wx;886pRasInfo->bounds.y1 = xsdo->surfInfo.visible.loy - wy;887pRasInfo->bounds.x2 = xsdo->surfInfo.visible.hix - wx;888pRasInfo->bounds.y2 = xsdo->surfInfo.visible.hiy - wy;889xpriv->lockType = X11SD_LOCK_BY_DGA;890xpriv->lockFlags = lockflags;891return SD_SUCCESS;892} else if (dgaret == JDGA_UNAVAILABLE) {893xsdo->dgaAvailable = JNI_FALSE;894}895}896if (lockflags & SD_LOCK_RD_WR) {897if (lockflags & SD_LOCK_FASTEST) {898ret = SD_SLOWLOCK;899}900xpriv->lockType = X11SD_LOCK_BY_XIMAGE;901if (xsdo->isPixmap) {902#ifdef MITSHM903if (xsdo->shmPMData.usingShmPixmap) {904xpriv->lockType = X11SD_LOCK_BY_SHMEM;905}906#endif /* MITSHM */907if (pRasInfo->bounds.x1 < 0) {908pRasInfo->bounds.x1 = 0;909}910if (pRasInfo->bounds.y1 < 0) {911pRasInfo->bounds.y1 = 0;912}913if (pRasInfo->bounds.x2 > xsdo->pmWidth) {914pRasInfo->bounds.x2 = xsdo->pmWidth;915}916if (pRasInfo->bounds.y2 > xsdo->pmHeight) {917pRasInfo->bounds.y2 = xsdo->pmHeight;918}919}920} else {921/* They didn't lock for anything - we won't give them anything */922xpriv->lockType = X11SD_LOCK_BY_NULL;923}924xpriv->lockFlags = lockflags;925xpriv->img = NULL;926927return ret;928/* AWT_UNLOCK() called in Unlock */929}930931static void X11SD_GetRasInfo(JNIEnv *env,932SurfaceDataOps *ops,933SurfaceDataRasInfo *pRasInfo)934{935X11SDOps *xsdo = (X11SDOps *) ops;936X11RIPrivate *xpriv = (X11RIPrivate *) &(pRasInfo->priv);937jint lockFlags = xpriv->lockFlags;938jint depth = xsdo->depth;939int mult = xsdo->configData->pixelStride;940941if (xsdo->dgaAvailable &&942xpriv->lockType == X11SD_LOCK_BY_XIMAGE &&943(lockFlags & SD_LOCK_FASTEST))944{945/* Try one more time to use DGA (now with smaller bounds)... */946int dgaret;947948dgaret = (*pJDgaInfo->pGetLock)(env, awt_display, &xsdo->dgaDev,949xsdo->drawable, &xsdo->surfInfo,950pRasInfo->bounds.x1,951pRasInfo->bounds.y1,952pRasInfo->bounds.x2,953pRasInfo->bounds.y2);954if (dgaret == JDGA_SUCCESS) {955int wx = xsdo->surfInfo.window.lox;956int wy = xsdo->surfInfo.window.loy;957pRasInfo->bounds.x1 = xsdo->surfInfo.visible.lox - wx;958pRasInfo->bounds.y1 = xsdo->surfInfo.visible.loy - wy;959pRasInfo->bounds.x2 = xsdo->surfInfo.visible.hix - wx;960pRasInfo->bounds.y2 = xsdo->surfInfo.visible.hiy - wy;961xpriv->lockType = X11SD_LOCK_BY_DGA;962} else if (dgaret == JDGA_UNAVAILABLE) {963xsdo->dgaAvailable = JNI_FALSE;964}965}966967if (xpriv->lockType == X11SD_LOCK_BY_DGA) {968int scan = xsdo->surfInfo.surfaceScan;969int wx = xsdo->surfInfo.window.lox;970int wy = xsdo->surfInfo.window.loy;971pRasInfo->rasBase =972(void *)(((uintptr_t) xsdo->surfInfo.basePtr) + (scan*wy + wx) * mult);973pRasInfo->pixelStride = mult;974pRasInfo->pixelBitOffset = 0;975pRasInfo->scanStride = scan * mult;976#ifdef MITSHM977} else if (xpriv->lockType == X11SD_LOCK_BY_SHMEM) {978if (xsdo->shmPMData.xRequestSent == JNI_TRUE) {979/* need to sync before using shared mem pixmap980if any x calls were issued for this pixmap */981XSync(awt_display, False);982xsdo->shmPMData.xRequestSent = JNI_FALSE;983}984xpriv->x = pRasInfo->bounds.x1;985xpriv->y = pRasInfo->bounds.y1;986pRasInfo->rasBase = xsdo->shmPMData.shmSegInfo->shmaddr;987pRasInfo->pixelStride = mult;988pRasInfo->pixelBitOffset = 0;989pRasInfo->scanStride = xsdo->shmPMData.bytesPerLine;990#endif /* MITSHM */991} else if (xpriv->lockType == X11SD_LOCK_BY_XIMAGE) {992int x, y, w, h;993x = pRasInfo->bounds.x1;994y = pRasInfo->bounds.y1;995w = pRasInfo->bounds.x2 - x;996h = pRasInfo->bounds.y2 - y;997998xpriv->img = X11SD_GetImage(env, xsdo, &pRasInfo->bounds, lockFlags);999if (xpriv->img) {1000int scan = xpriv->img->bytes_per_line;1001xpriv->x = x;1002xpriv->y = y;1003pRasInfo->rasBase = xpriv->img->data - x * mult - (intptr_t) y * scan;1004pRasInfo->pixelStride = mult;1005pRasInfo->pixelBitOffset = 0;1006pRasInfo->scanStride = scan;1007} else {1008pRasInfo->rasBase = NULL;1009pRasInfo->pixelStride = 0;1010pRasInfo->pixelBitOffset = 0;1011pRasInfo->scanStride = 0;1012}1013} else {1014/* They didn't lock for anything - we won't give them anything */1015pRasInfo->rasBase = NULL;1016pRasInfo->pixelStride = 0;1017pRasInfo->pixelBitOffset = 0;1018pRasInfo->scanStride = 0;1019}1020if (lockFlags & SD_LOCK_LUT) {1021pRasInfo->lutBase = (jint *) xsdo->cData->awt_icmLUT;1022pRasInfo->lutSize = xsdo->cData->awt_numICMcolors;1023} else {1024pRasInfo->lutBase = NULL;1025pRasInfo->lutSize = 0;1026}1027if (lockFlags & SD_LOCK_INVCOLOR) {1028pRasInfo->invColorTable = xsdo->cData->img_clr_tbl;1029pRasInfo->redErrTable = xsdo->cData->img_oda_red;1030pRasInfo->grnErrTable = xsdo->cData->img_oda_green;1031pRasInfo->bluErrTable = xsdo->cData->img_oda_blue;1032} else {1033pRasInfo->invColorTable = NULL;1034pRasInfo->redErrTable = NULL;1035pRasInfo->grnErrTable = NULL;1036pRasInfo->bluErrTable = NULL;1037}1038if (lockFlags & SD_LOCK_INVGRAY) {1039pRasInfo->invGrayTable = xsdo->cData->pGrayInverseLutData;1040} else {1041pRasInfo->invGrayTable = NULL;1042}1043}10441045static void X11SD_Unlock(JNIEnv *env,1046SurfaceDataOps *ops,1047SurfaceDataRasInfo *pRasInfo)1048{1049X11SDOps *xsdo = (X11SDOps *) ops;1050X11RIPrivate *xpriv = (X11RIPrivate *) &(pRasInfo->priv);10511052if (xpriv->lockType == X11SD_LOCK_BY_DGA) {1053(*pJDgaInfo->pReleaseLock)(env, xsdo->dgaDev, xsdo->drawable);1054} else if (xpriv->lockType == X11SD_LOCK_BY_XIMAGE &&1055xpriv->img != NULL)1056{1057if (xpriv->lockFlags & SD_LOCK_WRITE) {1058int x = xpriv->x;1059int y = xpriv->y;1060int w = pRasInfo->bounds.x2 - x;1061int h = pRasInfo->bounds.y2 - y;1062Drawable drawable = xsdo->drawable;1063GC xgc = xsdo->cachedGC;1064if (xgc == NULL) {1065xsdo->cachedGC = xgc =1066XCreateGC(awt_display, drawable, 0L, NULL);1067}10681069if (xpriv->img->byte_order != nativeByteOrder) {1070/* switching bytes back in 24 and 32 bpp cases. */1071/* For 16 bit XLib will switch for us. */1072if (xsdo->depth > 16) {1073X11SD_SwapBytes(xsdo, xpriv->img, xsdo->depth,1074xsdo->configData->awtImage->wsImageFormat.bits_per_pixel);1075}1076}10771078#ifdef MITSHM1079if (xpriv->img->obdata != NULL) {1080XShmPutImage(awt_display, drawable, xgc,1081xpriv->img, 0, 0, x, y, w, h, False);1082XFlush(awt_display);1083} else {1084XPutImage(awt_display, drawable, xgc,1085xpriv->img, 0, 0, x, y, w, h);1086}1087if (xsdo->shmPMData.usingShmPixmap) {1088xsdo->shmPMData.xRequestSent = JNI_TRUE;1089}1090#else1091XPutImage(awt_display, drawable, xgc,1092xpriv->img, 0, 0, x, y, w, h);1093#endif /* MITSHM */10941095(*pJDgaInfo->pXRequestSent)(env, xsdo->dgaDev, drawable);1096}1097X11SD_DisposeOrCacheXImage(xpriv->img);1098xpriv->img = (XImage *)NULL;1099}1100/* the background pixel is not valid anymore */1101if (xpriv->lockFlags & SD_LOCK_WRITE) {1102xsdo->isBgInitialized = JNI_FALSE;1103}1104xpriv->lockType = X11SD_LOCK_UNLOCKED;1105AWT_UNLOCK();1106}11071108static int1109X11SD_ClipToRoot(SurfaceDataBounds *b, SurfaceDataBounds *bounds,1110X11SDOps *xsdo)1111{1112Position x1=0, y1=0, x2=0, y2=0;1113int tmpx, tmpy;1114Window tmpchild;11151116Window window = (Window)(xsdo->drawable); /* is always a Window */1117XWindowAttributes winAttr;11181119Status status = XGetWindowAttributes(awt_display, window, &winAttr);1120if (status == 0) {1121/* Failure, X window no longer valid. */1122return FALSE;1123}1124if (!XTranslateCoordinates(awt_display, window,1125RootWindowOfScreen(winAttr.screen),11260, 0, &tmpx, &tmpy, &tmpchild)) {1127return FALSE;1128}11291130x1 = -(x1 + tmpx);1131y1 = -(y1 + tmpy);11321133x2 = x1 + DisplayWidth(awt_display, xsdo->configData->awt_visInfo.screen);1134y2 = y1 + DisplayHeight(awt_display, xsdo->configData->awt_visInfo.screen);11351136x1 = XSD_MAX(bounds->x1, x1);1137y1 = XSD_MAX(bounds->y1, y1);1138x2 = XSD_MIN(bounds->x2, x2);1139y2 = XSD_MIN(bounds->y2, y2);1140if ((x1 >= x2) || (y1 >= y2)) {1141return FALSE;1142}1143b->x1 = x1;1144b->y1 = y1;1145b->x2 = x2;1146b->y2 = y2;11471148return TRUE;1149}11501151/*1152* x1, y1, x2, y2 - our rectangle in the coord system of1153* the widget1154* px1, xy1, px2, py2 - current parent rect coords in the1155* same system1156*/1157static int1158X11SD_FindClip(SurfaceDataBounds *b, SurfaceDataBounds *bounds, X11SDOps *xsdo)1159{1160return TRUE;1161}11621163static void1164X11SD_SwapBytes(X11SDOps *xsdo, XImage * img, int depth, int bpp) {1165jlong lengthInBytes = (jlong) img->height * img->bytes_per_line;1166jlong i;11671168switch (depth) {1169case 12:1170case 15:1171case 16:1172{1173/* AB -> BA */1174unsigned short *d = (unsigned short *)img->data;1175unsigned short t;1176for (i = 0; i < lengthInBytes/2; i++) {1177t = *d;1178*d++ = (t >> 8) | (t << 8);1179}1180img->byte_order = nativeByteOrder;1181img->bitmap_bit_order = nativeByteOrder;1182break;1183}1184case 24:1185{1186/* ABC -> CBA */1187if (bpp == 24) {1188// 4517321: Only swap if we have a "real" ThreeByteBgr1189// visual (denoted by a red_mask of 0xff). Due to ambiguity1190// in the X11 spec, it appears that the swap is not required1191// on Linux configurations that use 24 bits per pixel (denoted1192// by a red_mask of 0xff0000).1193if (xsdo->configData->awt_visInfo.red_mask == 0xff) {1194int scan = img->bytes_per_line;1195unsigned char *d = (unsigned char *) img->data;1196unsigned char *d1;1197unsigned int t;1198int j;11991200for (i = 0; i < img->height; i++, d += scan) {1201d1 = d;1202for (j = 0; j < img->width; j++, d1 += 3) {1203/* not obvious opt from XLib src */1204t = d1[0]; d1[0] = d1[2]; d1[2] = t;1205}1206}1207}1208break;1209}1210}1211/* FALL THROUGH for 32-bit case */1212case 32:1213{1214/* ABCD -> DCBA */1215unsigned int *d = (unsigned int *) img->data;1216unsigned int t;1217for (i = 0; i < lengthInBytes/4; i++) {1218t = *d;1219*d++ = ((t >> 24) |1220((t >> 8) & 0xff00) |1221((t & 0xff00) << 8) |1222(t << 24));1223}1224break;1225}1226}1227}12281229static XImage * X11SD_GetImage(JNIEnv *env, X11SDOps *xsdo,1230SurfaceDataBounds *bounds,1231jint lockFlags)1232{1233int x, y, w, h, maxWidth, maxHeight;1234int scan;1235XImage * img = NULL;1236Drawable drawable;1237int depth = xsdo->depth;1238int mult = xsdo->configData->pixelStride;1239int pad = X11SD_GetBitmapPad(mult);1240jboolean readBits = lockFlags & SD_LOCK_NEED_PIXELS;12411242x = bounds->x1;1243y = bounds->y1;1244w = bounds->x2 - x;1245h = bounds->y2 - y;12461247#ifdef MITSHM1248if (useMitShmExt == CAN_USE_MITSHM) {1249if (xsdo->isPixmap) {1250if (readBits) {1251X11SD_PuntPixmap(xsdo, w, h);1252}1253maxWidth = xsdo->pmWidth;1254maxHeight = xsdo->pmHeight;1255} else {1256XWindowAttributes winAttr;1257if (XGetWindowAttributes(awt_display,1258(Window) xsdo->drawable, &winAttr) != 0) {1259maxWidth = winAttr.width;1260maxHeight = winAttr.height;1261} else {1262/* XGWA failed which isn't a good thing. Defaulting to using1263* x,y means that after the subtraction of these we will use1264* w=0, h=0 which is a reasonable default on such a failure.1265*/1266maxWidth = x;1267maxHeight = y;1268}1269}1270maxWidth -= x;1271maxHeight -= y;12721273img = X11SD_GetSharedImage(xsdo, w, h, maxWidth, maxHeight, readBits);1274}1275#endif /* MITSHM */1276drawable = xsdo->drawable;12771278if (readBits) {1279#ifdef MITSHM1280if (img != NULL) {1281if (!XShmGetImage(awt_display, drawable, img, x, y, -1)) {1282X11SD_DisposeOrCacheXImage(img);1283img = NULL;1284}1285}1286if (img == NULL) {1287img = XGetImage(awt_display, drawable, x, y, w, h, -1, ZPixmap);1288if (img != NULL) {1289img->obdata = NULL;1290}1291}1292#else1293img = XGetImage(awt_display, drawable, x, y, w, h, -1, ZPixmap);1294#endif /* MITSHM */1295if (img == NULL) {1296SurfaceDataBounds temp;1297img = XCreateImage(awt_display,1298xsdo->configData->awt_visInfo.visual,1299depth, ZPixmap, 0, NULL, w, h, pad, 0);1300if (img == NULL) {1301return NULL;1302}13031304scan = img->bytes_per_line;1305img->data = malloc((size_t) h * scan);1306if (img->data == NULL) {1307XFree(img);1308return NULL;1309}13101311if (xsdo->isPixmap == JNI_FALSE &&1312X11SD_ClipToRoot(&temp, bounds, xsdo)) {13131314XImage * temp_image;1315temp_image = XGetImage(awt_display, drawable,1316temp.x1, temp.y1,1317temp.x2 - temp.x1,1318temp.y2 - temp.y1,1319-1, ZPixmap);1320if (temp_image == NULL) {1321XGrabServer(awt_display);1322if (X11SD_FindClip(&temp, bounds, xsdo)) {1323temp_image =1324XGetImage(awt_display, drawable,1325temp.x1, temp.y1,1326temp.x2 - temp.x1,1327temp.y2 - temp.y1,1328-1, ZPixmap);1329}1330XUngrabServer(awt_display);1331/* Workaround for bug 5039226 */1332XSync(awt_display, False);1333}1334if (temp_image != NULL) {1335int temp_scan, bytes_to_copy;1336char * img_addr, * temp_addr;1337int i;13381339img_addr = img->data +1340(intptr_t) (temp.y1 - y) * scan + (temp.x1 - x) * mult;1341temp_scan = temp_image->bytes_per_line;1342temp_addr = temp_image->data;1343bytes_to_copy = (temp.x2 - temp.x1) * mult;1344for (i = temp.y1; i < temp.y2; i++) {1345memcpy(img_addr, temp_addr, bytes_to_copy);1346img_addr += scan;1347temp_addr += temp_scan;1348}1349XDestroyImage(temp_image);1350}1351}1352img->obdata = NULL;1353}1354if (depth > 8 && img->byte_order != nativeByteOrder) {1355X11SD_SwapBytes(xsdo, img, depth,1356xsdo->configData->awtImage->wsImageFormat.bits_per_pixel);1357}1358} else {1359/*1360* REMIND: This might be better to move to the Lock function1361* to avoid lengthy I/O pauses inside what may be a critical1362* section. This will be more critical when SD_LOCK_READ is1363* implemented. Another solution is to cache the pixels1364* to avoid reading for every operation.1365*/1366if (img == NULL) {1367img = XCreateImage(awt_display,1368xsdo->configData->awt_visInfo.visual,1369depth, ZPixmap, 0, NULL, w, h, pad, 0);1370if (img == NULL) {1371return NULL;1372}13731374img->data = malloc((size_t) h * img->bytes_per_line);1375if (img->data == NULL) {1376XFree(img);1377return NULL;1378}13791380img->obdata = NULL;13811382if (img->byte_order != nativeByteOrder &&1383(depth == 15 || depth == 16 || depth == 12)) {1384/* bytes will be swapped by XLib. */1385img->byte_order = nativeByteOrder;1386img->bitmap_bit_order = nativeByteOrder;1387}1388}1389}1390return img;1391}13921393void X11SD_DisposeOrCacheXImage(XImage * image) {1394/* REMIND: might want to check if the new image worth caching. */1395/* Cache only shared images. Passed image is assumed to be non-null. */1396if (image->obdata != NULL) {1397if (cachedXImage != NULL) {1398X11SD_DisposeXImage(cachedXImage);1399}1400cachedXImage = image;1401} else {1402X11SD_DisposeXImage(image);1403}1404}14051406void X11SD_DisposeXImage(XImage * image) {1407if (image != NULL) {1408#ifdef MITSHM1409if (image->obdata != NULL) {1410X11SD_DropSharedSegment((XShmSegmentInfo*)image->obdata);1411image->obdata = NULL;1412}1413#endif /* MITSHM */1414XDestroyImage(image);1415}1416}14171418static JDgaStatus1419GetLockStub(JNIEnv *env, Display *display, void **dgaDev,1420Drawable d, JDgaSurfaceInfo *pSurface,1421jint lox, jint loy, jint hix, jint hiy)1422{1423return JDGA_UNAVAILABLE;1424}14251426static JDgaStatus1427ReleaseLockStub(JNIEnv *env, void *dgaDev, Drawable d)1428{1429return JDGA_FAILED;1430}14311432static void1433XRequestSentStub(JNIEnv *env, void *dgaDev, Drawable d)1434{1435}14361437static void1438LibDisposeStub(JNIEnv *env)1439{1440}14411442static JDgaLibInfo DgaLibInfoStub = {1443NULL,1444GetLockStub,1445ReleaseLockStub,1446XRequestSentStub,1447LibDisposeStub,1448};14491450void X11SD_LibDispose(JNIEnv *env) {1451AWT_LOCK();1452if (pJDgaInfo != NULL) {1453pJDgaInfo->pLibDispose(env);1454pJDgaInfo = &DgaLibInfoStub;1455}1456AWT_UNLOCK();1457}14581459void1460X11SD_DirectRenderNotify(JNIEnv *env, X11SDOps *xsdo)1461{1462#ifdef MITSHM1463if (xsdo->shmPMData.usingShmPixmap) {1464xsdo->shmPMData.xRequestSent = JNI_TRUE;1465}1466#endif /* MITSHM */1467(*pJDgaInfo->pXRequestSent)(env, xsdo->dgaDev, xsdo->drawable);1468awt_output_flush();1469}14701471/*1472* Sets transparent pixels in the pixmap to1473* the specified solid background color and returns it.1474* Doesn't update source pixmap unless the color of the1475* transparent pixels is different from the specified color.1476*1477* Note: The AWT lock must be held by the current thread1478* while calling into this method.1479*/1480static Drawable1481X11SD_GetPixmapWithBg(JNIEnv *env, X11SDOps *xsdo, jint pixel)1482{1483/* assert AWT_CHECK_HAVE_LOCK(); */14841485if (xsdo->invalid) {1486AWT_UNLOCK();1487SurfaceData_ThrowInvalidPipeException(env, "bounds changed");1488return 0;1489}14901491/* the image doesn't have transparency, just return it */1492if (xsdo->bitmask == 0) {1493/* don't need to unlock here, the caller will unlock through1494the release call */1495return xsdo->drawable;1496}14971498/* Check if current color of the transparent pixels is different1499from the specified one */1500if (xsdo->isBgInitialized == JNI_FALSE || xsdo->bgPixel != pixel) {1501GC srcGC;1502GC bmGC;15031504if (xsdo->drawable == 0) {1505AWT_UNLOCK();1506return 0;1507}15081509bmGC = XCreateGC(awt_display, xsdo->bitmask, 0, NULL);1510if (bmGC == NULL) {1511AWT_UNLOCK();1512return 0;1513}15141515/* invert the bitmask */1516XSetFunction(awt_display, bmGC, GXxor);1517XSetForeground(awt_display, bmGC, 1);1518XFillRectangle(awt_display, xsdo->bitmask, bmGC,15190, 0, xsdo->pmWidth, xsdo->pmHeight);15201521srcGC = XCreateGC(awt_display, xsdo->drawable, 0L, NULL);1522if (srcGC == NULL) {1523XFreeGC(awt_display, bmGC);1524AWT_UNLOCK();1525return 0;1526}15271528/* set transparent pixels in the source pm to the bg color */1529XSetClipMask(awt_display, srcGC, xsdo->bitmask);1530XSetForeground(awt_display, srcGC, pixel);1531XFillRectangle(awt_display, xsdo->drawable, srcGC,15320, 0, xsdo->pmWidth, xsdo->pmHeight);15331534/* invert the mask back */1535XFillRectangle(awt_display, xsdo->bitmask, bmGC,15360, 0, xsdo->pmWidth, xsdo->pmHeight);15371538XFreeGC(awt_display, bmGC);1539XFreeGC(awt_display, srcGC);1540xsdo->bgPixel = pixel;1541xsdo->isBgInitialized = JNI_TRUE;1542}15431544return xsdo->drawable;1545}15461547static void1548X11SD_ReleasePixmapWithBg(JNIEnv *env, X11SDOps *xsdo)1549{1550#ifdef MITSHM1551if (xsdo->shmPMData.usingShmPixmap) {1552xsdo->shmPMData.xRequestSent = JNI_TRUE;1553}1554#endif /* MITSHM */1555}15561557static int X11SD_GetBitmapPad(int pixelStride) {1558// pad must be 8, 16, or 321559return (pixelStride == 3) ? 32 : pixelStride * 8;1560}15611562#endif /* !HEADLESS */15631564/*1565* Class: sun_java2d_x11_X11SurfaceData1566* Method: XCreateGC1567* Signature: (I)J1568*/1569JNIEXPORT jlong JNICALL1570Java_sun_java2d_x11_XSurfaceData_XCreateGC1571(JNIEnv *env, jclass xsd, jlong pXSData)1572{1573jlong ret;15741575#ifndef HEADLESS1576X11SDOps *xsdo;15771578J2dTraceLn(J2D_TRACE_INFO, "in X11SurfaceData_XCreateGC");15791580xsdo = (X11SDOps *) pXSData;1581if (xsdo == NULL) {1582return 0L;1583}15841585xsdo->javaGC = XCreateGC(awt_display, xsdo->drawable, 0, NULL);1586ret = (jlong) xsdo->javaGC;1587#else /* !HEADLESS */1588ret = 0L;1589#endif /* !HEADLESS */15901591return ret;1592}15931594/*1595* Class: sun_java2d_x11_X11SurfaceData1596* Method: XResetClip1597* Signature: (JIIIILsun/java2d/pipe/Region;)V1598*/1599JNIEXPORT void JNICALL1600Java_sun_java2d_x11_XSurfaceData_XResetClip1601(JNIEnv *env, jclass xsd, jlong xgc)1602{1603#ifndef HEADLESS1604J2dTraceLn(J2D_TRACE_INFO, "in X11SurfaceData_XResetClip");1605XSetClipMask(awt_display, (GC) xgc, None);1606#endif /* !HEADLESS */1607}16081609/*1610* Class: sun_java2d_x11_X11SurfaceData1611* Method: XSetClip1612* Signature: (JIIIILsun/java2d/pipe/Region;)V1613*/1614JNIEXPORT void JNICALL1615Java_sun_java2d_x11_XSurfaceData_XSetClip1616(JNIEnv *env, jclass xsd, jlong xgc,1617jint x1, jint y1, jint x2, jint y2,1618jobject complexclip)1619{1620#ifndef HEADLESS1621int numrects;1622XRectangle rects[256];1623XRectangle *pRect = rects;16241625J2dTraceLn(J2D_TRACE_INFO, "in X11SurfaceData_XSetClip");16261627numrects = RegionToYXBandedRectangles(env,1628x1, y1, x2, y2, complexclip,1629&pRect, 256);16301631XSetClipRectangles(awt_display, (GC) xgc, 0, 0, pRect, numrects, YXBanded);16321633if (pRect != rects) {1634free(pRect);1635}1636#endif /* !HEADLESS */1637}16381639/*1640* Class: sun_java2d_x11_X11SurfaceData1641* Method: XSetCopyMode1642* Signature: (J)V1643*/1644JNIEXPORT void JNICALL1645Java_sun_java2d_x11_X11SurfaceData_XSetCopyMode1646(JNIEnv *env, jclass xsd, jlong xgc)1647{1648#ifndef HEADLESS1649J2dTraceLn(J2D_TRACE_INFO, "in X11SurfaceData_XSetCopyMode");1650XSetFunction(awt_display, (GC) xgc, GXcopy);1651#endif /* !HEADLESS */1652}16531654/*1655* Class: sun_java2d_x11_X11SurfaceData1656* Method: XSetXorMode1657* Signature: (J)V1658*/1659JNIEXPORT void JNICALL1660Java_sun_java2d_x11_X11SurfaceData_XSetXorMode1661(JNIEnv *env, jclass xr, jlong xgc)1662{1663#ifndef HEADLESS1664J2dTraceLn(J2D_TRACE_INFO, "in X11SurfaceData_XSetXorMode");1665XSetFunction(awt_display, (GC) xgc, GXxor);1666#endif /* !HEADLESS */1667}16681669/*1670* Class: sun_java2d_x11_X11SurfaceData1671* Method: XSetForeground1672* Signature: (JI)V1673*/1674JNIEXPORT void JNICALL1675Java_sun_java2d_x11_X11SurfaceData_XSetForeground1676(JNIEnv *env, jclass xsd, jlong xgc, jint pixel)1677{1678#ifndef HEADLESS1679J2dTraceLn(J2D_TRACE_INFO, "in X11SurfaceData_XSetForeground");1680XSetForeground(awt_display, (GC) xgc, pixel);1681#endif /* !HEADLESS */1682}16831684/*1685* Class: sun_java2d_x11_X11SurfaceData1686* Method: XSetGraphicsExposures1687* Signature: (JZ)V1688*/1689JNIEXPORT void JNICALL1690Java_sun_java2d_x11_XSurfaceData_XSetGraphicsExposures1691(JNIEnv *env, jclass xsd, jlong xgc, jboolean needExposures)1692{1693#ifndef HEADLESS1694J2dTraceLn(J2D_TRACE_INFO, "in X11SurfaceData_XSetGraphicsExposures");1695XSetGraphicsExposures(awt_display, (GC) xgc, needExposures ? True : False);1696#endif /* !HEADLESS */1697}169816991700