Path: blob/master/src/java.desktop/unix/native/common/java2d/x11/X11SurfaceData.c
41159 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 HEADLESS4142/**43* This file contains support code for loops using the SurfaceData44* interface to talk to an X11 drawable from native code.45*/4647typedef struct _X11RIPrivate {48jint lockType;49jint lockFlags;50XImage *img;51int x, y;52} X11RIPrivate;5354#define XSD_MAX(a,b) ((a) > (b) ? (a) : (b))55#define XSD_MIN(a,b) ((a) < (b) ? (a) : (b))5657static LockFunc X11SD_Lock;58static GetRasInfoFunc X11SD_GetRasInfo;59static UnlockFunc X11SD_Unlock;60static DisposeFunc X11SD_Dispose;61static GetPixmapBgFunc X11SD_GetPixmapWithBg;62static ReleasePixmapBgFunc X11SD_ReleasePixmapWithBg;63extern int XShmAttachXErrHandler(Display *display, XErrorEvent *xerr);64extern AwtGraphicsConfigDataPtr65getGraphicsConfigFromComponentPeer(JNIEnv *env, jobject this);66extern struct X11GraphicsConfigIDs x11GraphicsConfigIDs;6768static int X11SD_FindClip(SurfaceDataBounds *b, SurfaceDataBounds *bounds,69X11SDOps *xsdo);70static int X11SD_ClipToRoot(SurfaceDataBounds *b, SurfaceDataBounds *bounds,71X11SDOps *xsdo);72static void X11SD_SwapBytes(X11SDOps *xsdo, XImage *img, int depth, int bpp);73static XImage * X11SD_GetImage(JNIEnv *env, X11SDOps *xsdo,74SurfaceDataBounds *bounds,75jint lockFlags);76static int X11SD_GetBitmapPad(int pixelStride);7778extern jfieldID validID;7980static int nativeByteOrder;81static jclass xorCompClass;8283jint useMitShmExt = CANT_USE_MITSHM;84jint useMitShmPixmaps = CANT_USE_MITSHM;85jint forceSharedPixmaps = JNI_FALSE;8687#ifdef MITSHM88int mitShmPermissionMask = MITSHM_PERM_OWNER;89#endif9091/* Cached shared image, one for all surface datas. */92static XImage * cachedXImage;9394#endif /* !HEADLESS */9596jboolean XShared_initIDs(JNIEnv *env, jboolean allowShmPixmaps)97{98#ifndef HEADLESS99union {100char c[4];101int i;102} endian;103104endian.i = 0xff000000;105nativeByteOrder = (endian.c[0]) ? MSBFirst : LSBFirst;106107cachedXImage = NULL;108109if (sizeof(X11RIPrivate) > SD_RASINFO_PRIVATE_SIZE) {110JNU_ThrowInternalError(env, "Private RasInfo structure too large!");111return JNI_FALSE;112}113114#ifdef MITSHM115if (getenv("NO_AWT_MITSHM") == NULL &&116getenv("NO_J2D_MITSHM") == NULL) {117char * force;118char * permission = getenv("J2D_MITSHM_PERMISSION");119if (permission != NULL) {120if (strcmp(permission, "common") == 0) {121mitShmPermissionMask = MITSHM_PERM_COMMON;122}123}124125TryInitMITShm(env, &useMitShmExt, &useMitShmPixmaps);126127if(allowShmPixmaps) {128useMitShmPixmaps = (useMitShmPixmaps == CAN_USE_MITSHM);129force = getenv("J2D_PIXMAPS");130if (force != NULL) {131if (useMitShmPixmaps && (strcmp(force, "shared") == 0)) {132forceSharedPixmaps = JNI_TRUE;133} else if (strcmp(force, "server") == 0) {134useMitShmPixmaps = JNI_FALSE;135}136}137}else {138useMitShmPixmaps = JNI_FALSE;139}140}141#endif /* MITSHM */142143#endif /* !HEADLESS */144145return JNI_TRUE;146}147148149/*150* Class: sun_java2d_x11_X11SurfaceData151* Method: initIDs152* Signature: (Ljava/lang/Class;Z)V153*/154JNIEXPORT void JNICALL155Java_sun_java2d_x11_X11SurfaceData_initIDs(JNIEnv *env, jclass xsd,156jclass XORComp)157{158#ifndef HEADLESS159if(XShared_initIDs(env, JNI_TRUE))160{161xorCompClass = (*env)->NewGlobalRef(env, XORComp);162}163#endif /* !HEADLESS */164}165166/*167* Class: sun_java2d_x11_X11SurfaceData168* Method: isDrawableValid169* Signature: ()Z170*/171JNIEXPORT jboolean JNICALL172Java_sun_java2d_x11_XSurfaceData_isDrawableValid(JNIEnv *env, jobject this)173{174jboolean ret = JNI_FALSE;175176#ifndef HEADLESS177X11SDOps *xsdo = X11SurfaceData_GetOps(env, this);178179AWT_LOCK();180if (xsdo->drawable != 0 || X11SD_InitWindow(env, xsdo) == SD_SUCCESS) {181ret = JNI_TRUE;182}183AWT_UNLOCK();184#endif /* !HEADLESS */185186return ret;187}188189/*190* Class: sun_java2d_x11_X11SurfaceData191* Method: isShmPMAvailable192* Signature: ()Z193*/194JNIEXPORT jboolean JNICALL195Java_sun_java2d_x11_X11SurfaceData_isShmPMAvailable(JNIEnv *env, jobject this)196{197#if defined(HEADLESS) || !defined(MITSHM)198return JNI_FALSE;199#else200return (jboolean)useMitShmPixmaps;201#endif /* HEADLESS, MITSHM */202}203204/*205* Class: sun_java2d_x11_X11SurfaceData206* Method: initOps207* Signature: (Ljava/lang/Object;I)V208*/209JNIEXPORT void JNICALL210Java_sun_java2d_x11_XSurfaceData_initOps(JNIEnv *env, jobject xsd,211jobject peer,212jobject graphicsConfig, jint depth)213{214#ifndef HEADLESS215X11SDOps *xsdo = (X11SDOps*)SurfaceData_InitOps(env, xsd, sizeof(X11SDOps));216jboolean hasException;217if (xsdo == NULL) {218JNU_ThrowOutOfMemoryError(env, "Initialization of SurfaceData failed.");219return;220}221xsdo->sdOps.Lock = X11SD_Lock;222xsdo->sdOps.GetRasInfo = X11SD_GetRasInfo;223xsdo->sdOps.Unlock = X11SD_Unlock;224xsdo->sdOps.Dispose = X11SD_Dispose;225xsdo->GetPixmapWithBg = X11SD_GetPixmapWithBg;226xsdo->ReleasePixmapWithBg = X11SD_ReleasePixmapWithBg;227if (peer != NULL) {228xsdo->drawable = JNU_CallMethodByName(env, &hasException, peer, "getWindow", "()J").j;229if (hasException) {230return;231}232} else {233xsdo->drawable = 0;234}235xsdo->depth = depth;236xsdo->isPixmap = JNI_FALSE;237xsdo->bitmask = 0;238xsdo->bgPixel = 0;239xsdo->isBgInitialized = JNI_FALSE;240#ifdef MITSHM241xsdo->shmPMData.shmSegInfo = NULL;242xsdo->shmPMData.xRequestSent = JNI_FALSE;243xsdo->shmPMData.pmSize = 0;244xsdo->shmPMData.usingShmPixmap = JNI_FALSE;245xsdo->shmPMData.pixmap = 0;246xsdo->shmPMData.shmPixmap = 0;247xsdo->shmPMData.numBltsSinceRead = 0;248xsdo->shmPMData.pixelsReadSinceBlt = 0;249xsdo->shmPMData.numBltsThreshold = 2;250#endif /* MITSHM */251252xsdo->configData = (AwtGraphicsConfigDataPtr)253JNU_GetLongFieldAsPtr(env,254graphicsConfig,255x11GraphicsConfigIDs.aData);256if (xsdo->configData == NULL) {257JNU_ThrowNullPointerException(env,258"Native GraphicsConfig data block missing");259return;260}261if (depth > 12) {262xsdo->pixelmask = (xsdo->configData->awt_visInfo.red_mask |263xsdo->configData->awt_visInfo.green_mask |264xsdo->configData->awt_visInfo.blue_mask);265} else if (depth == 12) {266xsdo->pixelmask = 0xfff;267} else {268xsdo->pixelmask = 0xff;269}270271xsdo->xrPic = None;272#endif /* !HEADLESS */273}274275/*276* Class: sun_java2d_x11_X11SurfaceData277* Method: flushNativeSurface278* Signature: ()V279*/280JNIEXPORT void JNICALL281Java_sun_java2d_x11_XSurfaceData_flushNativeSurface(JNIEnv *env, jobject xsd)282{283#ifndef HEADLESS284SurfaceDataOps *ops = SurfaceData_GetOps(env, xsd);285286if (ops != NULL) {287X11SD_Dispose(env, ops);288}289#endif /* !HEADLESS */290}291292293JNIEXPORT X11SDOps * JNICALL294X11SurfaceData_GetOps(JNIEnv *env, jobject sData)295{296#ifdef HEADLESS297return NULL;298#else299SurfaceDataOps *ops = SurfaceData_GetOps(env, sData);300if (ops != NULL && ops->Lock != X11SD_Lock) {301SurfaceData_ThrowInvalidPipeException(env, "not an X11 SurfaceData");302ops = NULL;303}304return (X11SDOps *) ops;305#endif /* !HEADLESS */306}307308/*309* Method for disposing X11SD-specific data310*/311static void312X11SD_Dispose(JNIEnv *env, SurfaceDataOps *ops)313{314#ifndef HEADLESS315/* ops is assumed non-null as it is checked in SurfaceData_DisposeOps */316X11SDOps * xsdo = (X11SDOps*)ops;317318AWT_LOCK();319320xsdo->invalid = JNI_TRUE;321322if (xsdo->xrPic != None) {323XRenderFreePicture(awt_display, xsdo->xrPic);324xsdo->xrPic = None;325}326327if (xsdo->isPixmap == JNI_TRUE && xsdo->drawable != 0) {328#ifdef MITSHM329if (xsdo->shmPMData.shmSegInfo != NULL) {330X11SD_DropSharedSegment(xsdo->shmPMData.shmSegInfo);331xsdo->shmPMData.shmSegInfo = NULL;332}333if (xsdo->shmPMData.pixmap) {334XFreePixmap(awt_display, xsdo->shmPMData.pixmap);335xsdo->shmPMData.pixmap = 0;336}337if (xsdo->shmPMData.shmPixmap) {338XFreePixmap(awt_display, xsdo->shmPMData.shmPixmap);339xsdo->shmPMData.shmPixmap = 0;340}341#else342XFreePixmap(awt_display, xsdo->drawable);343#endif /* MITSHM */344xsdo->drawable = 0;345}346if (xsdo->bitmask != 0) {347XFreePixmap(awt_display, xsdo->bitmask);348xsdo->bitmask = 0;349}350if (xsdo->javaGC != NULL) {351XFreeGC(awt_display, xsdo->javaGC);352xsdo->javaGC = NULL;353}354if (xsdo->cachedGC != NULL) {355XFreeGC(awt_display, xsdo->cachedGC);356xsdo->cachedGC = NULL;357}358359if(xsdo->xrPic != None) {360XRenderFreePicture(awt_display, xsdo->xrPic);361}362363AWT_UNLOCK();364#endif /* !HEADLESS */365}366/*367* Class: sun_java2d_x11_X11SurfaceData368* Method: setInvalid369* Signature: ()V370*/371JNIEXPORT void JNICALL372Java_sun_java2d_x11_XSurfaceData_setInvalid(JNIEnv *env, jobject xsd)373{374#ifndef HEADLESS375X11SDOps *xsdo = (X11SDOps *) SurfaceData_GetOps(env, xsd);376377if (xsdo != NULL) {378xsdo->invalid = JNI_TRUE;379}380#endif /* !HEADLESS */381}382383384jboolean XShared_initSurface(JNIEnv *env, X11SDOps *xsdo, jint depth, jint width, jint height, jlong drawable)385{386#ifndef HEADLESS387388if (drawable != (jlong)0) {389/* Double-buffering */390xsdo->drawable = drawable;391xsdo->isPixmap = JNI_FALSE;392} else {393jboolean sizeIsInvalid = JNI_FALSE;394jlong scan = 0;395396/*397* width , height must be nonzero otherwise XCreatePixmap398* generates BadValue in error_handler399*/400if (width <= 0 || height <= 0 || width > 32767 || height > 32767) {401sizeIsInvalid = JNI_TRUE;402} else {403XImage* tmpImg = NULL;404405AWT_LOCK();406tmpImg = XCreateImage(awt_display,407xsdo->configData->awt_visInfo.visual,408depth, ZPixmap, 0, NULL, width, height,409X11SD_GetBitmapPad(xsdo->configData->pixelStride), 0);410if (tmpImg) {411scan = (jlong) tmpImg->bytes_per_line;412XDestroyImage(tmpImg);413tmpImg = NULL;414}415AWT_UNLOCK();416JNU_CHECK_EXCEPTION_RETURN(env, JNI_FALSE);417}418419if (sizeIsInvalid || (scan * height > 0x7FFFFFFFL)) {420JNU_ThrowOutOfMemoryError(env,421"Can't create offscreen surface");422return JNI_FALSE;423}424xsdo->isPixmap = JNI_TRUE;425426xsdo->pmWidth = width;427xsdo->pmHeight = height;428429#ifdef MITSHM430xsdo->shmPMData.pmSize = (jlong) width * height * depth;431xsdo->shmPMData.pixelsReadThreshold = width * height / 8;432if (forceSharedPixmaps) {433AWT_LOCK();434xsdo->drawable = X11SD_CreateSharedPixmap(xsdo);435AWT_UNLOCK();436JNU_CHECK_EXCEPTION_RETURN(env, JNI_FALSE);437if (xsdo->drawable) {438xsdo->shmPMData.usingShmPixmap = JNI_TRUE;439xsdo->shmPMData.shmPixmap = xsdo->drawable;440return JNI_TRUE;441}442}443#endif /* MITSHM */444445AWT_LOCK();446xsdo->drawable =447XCreatePixmap(awt_display,448RootWindow(awt_display,449xsdo->configData->awt_visInfo.screen),450width, height, depth);451AWT_UNLOCK();452JNU_CHECK_EXCEPTION_RETURN(env, JNI_FALSE);453#ifdef MITSHM454xsdo->shmPMData.usingShmPixmap = JNI_FALSE;455xsdo->shmPMData.pixmap = xsdo->drawable;456#endif /* MITSHM */457}458if (xsdo->drawable == 0) {459JNU_ThrowOutOfMemoryError(env,460"Can't create offscreen surface");461return JNI_FALSE;462}463464#endif /* !HEADLESS */465return JNI_TRUE;466}467468469/*470* Class: sun_java2d_x11_X11SurfaceData471* Method: initSurface472* Signature: ()V473*/474JNIEXPORT void JNICALL475Java_sun_java2d_x11_X11SurfaceData_initSurface(JNIEnv *env, jclass xsd,476jint depth,477jint width, jint height,478jlong drawable)479{480#ifndef HEADLESS481X11SDOps *xsdo = X11SurfaceData_GetOps(env, xsd);482if (xsdo == NULL) {483return;484}485486if (xsdo->configData->awt_cmap == (Colormap)NULL) {487awtJNI_CreateColorData(env, xsdo->configData, 1);488JNU_CHECK_EXCEPTION(env);489}490/* color_data will be initialized in awtJNI_CreateColorData for4918-bit visuals */492xsdo->cData = xsdo->configData->color_data;493494XShared_initSurface(env, xsdo, depth, width, height, drawable);495xsdo->xrPic = None;496#endif /* !HEADLESS */497}498499#ifndef HEADLESS500501#ifdef MITSHM502503void X11SD_DropSharedSegment(XShmSegmentInfo *shminfo)504{505if (shminfo != NULL) {506XShmDetach(awt_display, shminfo);507shmdt(shminfo->shmaddr);508/* REMIND: we don't need shmctl(shminfo->shmid, IPC_RMID, 0); here. */509/* Check X11SD_CreateSharedImage() for the explanation */510}511}512513XImage* X11SD_CreateSharedImage(X11SDOps *xsdo,514jint width, jint height)515{516XImage *img = NULL;517XShmSegmentInfo *shminfo;518519shminfo = malloc(sizeof(XShmSegmentInfo));520if (shminfo == NULL) {521return NULL;522}523memset(shminfo, 0, sizeof(XShmSegmentInfo));524525img = XShmCreateImage(awt_display, xsdo->configData->awt_visInfo.visual,526xsdo->depth, ZPixmap, NULL, shminfo,527width, height);528if (img == NULL) {529free((void *)shminfo);530return NULL;531}532shminfo->shmid =533shmget(IPC_PRIVATE, (size_t) height * img->bytes_per_line,534IPC_CREAT|mitShmPermissionMask);535if (shminfo->shmid < 0) {536J2dRlsTraceLn1(J2D_TRACE_ERROR,537"X11SD_SetupSharedSegment shmget has failed: %s",538strerror(errno));539free((void *)shminfo);540XDestroyImage(img);541return NULL;542}543544shminfo->shmaddr = (char *) shmat(shminfo->shmid, 0, 0);545if (shminfo->shmaddr == ((char *) -1)) {546shmctl(shminfo->shmid, IPC_RMID, 0);547J2dRlsTraceLn1(J2D_TRACE_ERROR,548"X11SD_SetupSharedSegment shmat has failed: %s",549strerror(errno));550free((void *)shminfo);551XDestroyImage(img);552return NULL;553}554555shminfo->readOnly = False;556557resetXShmAttachFailed();558EXEC_WITH_XERROR_HANDLER(XShmAttachXErrHandler,559XShmAttach(awt_display, shminfo));560561/*562* Once the XSync round trip has finished then we563* can get rid of the id so that this segment does not stick564* around after we go away, holding system resources.565*/566shmctl(shminfo->shmid, IPC_RMID, 0);567568if (isXShmAttachFailed() == JNI_TRUE) {569J2dRlsTraceLn1(J2D_TRACE_ERROR,570"X11SD_SetupSharedSegment XShmAttach has failed: %s",571strerror(errno));572shmdt(shminfo->shmaddr);573free((void *)shminfo);574XDestroyImage(img);575return NULL;576}577578img->data = shminfo->shmaddr;579img->obdata = (char *)shminfo;580581return img;582}583584XImage* X11SD_GetSharedImage(X11SDOps *xsdo, jint width, jint height,585jint maxWidth, jint maxHeight, jboolean readBits)586{587XImage * retImage = NULL;588if (cachedXImage != NULL &&589X11SD_CachedXImageFits(width, height, maxWidth, maxHeight,590xsdo->depth, readBits)) {591/* sync so previous data gets flushed */592XSync(awt_display, False);593retImage = cachedXImage;594cachedXImage = (XImage *)NULL;595} else if ((jlong) width * height * xsdo->depth > 0x10000) {596retImage = X11SD_CreateSharedImage(xsdo, width, height);597}598return retImage;599}600601Drawable X11SD_CreateSharedPixmap(X11SDOps *xsdo)602{603XShmSegmentInfo *shminfo;604XImage *img = NULL;605Drawable pixmap;606int scan;607int width = xsdo->pmWidth;608int height = xsdo->pmHeight;609610if (xsdo->shmPMData.pmSize < 0x10000) {611/* only use shared mem pixmaps for relatively big images */612return 0;613}614615/* need to create shared(!) image to get bytes_per_line */616img = X11SD_CreateSharedImage(xsdo, width, height);617if (img == NULL) {618return 0;619}620scan = img->bytes_per_line;621shminfo = (XShmSegmentInfo*)img->obdata;622XFree(img);623624pixmap =625XShmCreatePixmap(awt_display,626RootWindow(awt_display,627xsdo->configData->awt_visInfo.screen),628shminfo->shmaddr, shminfo,629width, height, xsdo->depth);630if (pixmap == 0) {631X11SD_DropSharedSegment(shminfo);632return 0;633}634635xsdo->shmPMData.shmSegInfo = shminfo;636xsdo->shmPMData.bytesPerLine = scan;637return pixmap;638}639640void X11SD_PuntPixmap(X11SDOps *xsdo, jint width, jint height)641{642643if (useMitShmPixmaps != CAN_USE_MITSHM || forceSharedPixmaps) {644return;645}646647/* we wouldn't be here if it's a shared pixmap, so no check648* for !usingShmPixmap.649*/650651xsdo->shmPMData.numBltsSinceRead = 0;652653xsdo->shmPMData.pixelsReadSinceBlt += width * height;654if (xsdo->shmPMData.pixelsReadSinceBlt >655xsdo->shmPMData.pixelsReadThreshold) {656if (!xsdo->shmPMData.shmPixmap) {657xsdo->shmPMData.shmPixmap =658X11SD_CreateSharedPixmap(xsdo);659}660if (xsdo->shmPMData.shmPixmap) {661GC xgc = XCreateGC(awt_display, xsdo->shmPMData.shmPixmap, 0L, NULL);662if (xgc != NULL) {663xsdo->shmPMData.usingShmPixmap = JNI_TRUE;664xsdo->drawable = xsdo->shmPMData.shmPixmap;665XCopyArea(awt_display,666xsdo->shmPMData.pixmap, xsdo->drawable, xgc,6670, 0, xsdo->pmWidth, xsdo->pmHeight, 0, 0);668XSync(awt_display, False);669xsdo->shmPMData.xRequestSent = JNI_FALSE;670XFreeGC(awt_display, xgc);671}672}673}674}675676void X11SD_UnPuntPixmap(X11SDOps *xsdo)677{678if (useMitShmPixmaps != CAN_USE_MITSHM || forceSharedPixmaps) {679return;680}681xsdo->shmPMData.pixelsReadSinceBlt = 0;682if (xsdo->shmPMData.numBltsSinceRead >=683xsdo->shmPMData.numBltsThreshold)684{685if (xsdo->shmPMData.usingShmPixmap) {686if (!xsdo->shmPMData.pixmap) {687xsdo->shmPMData.pixmap =688XCreatePixmap(awt_display,689RootWindow(awt_display,690xsdo->configData->awt_visInfo.screen),691xsdo->pmWidth, xsdo->pmHeight, xsdo->depth);692}693if (xsdo->shmPMData.pixmap) {694GC xgc = XCreateGC(awt_display, xsdo->shmPMData.pixmap, 0L, NULL);695if (xgc != NULL) {696xsdo->drawable = xsdo->shmPMData.pixmap;697XCopyArea(awt_display,698xsdo->shmPMData.shmPixmap, xsdo->drawable, xgc,6990, 0, xsdo->pmWidth, xsdo->pmHeight, 0, 0);700XSync(awt_display, False);701XFreeGC(awt_display, xgc);702xsdo->shmPMData.xRequestSent = JNI_FALSE;703xsdo->shmPMData.usingShmPixmap = JNI_FALSE;704xsdo->shmPMData.numBltsThreshold *= 2;705}706}707}708} else {709xsdo->shmPMData.numBltsSinceRead++;710}711}712713/**714* Determines if the cached image can be used for current operation.715* If the image is to be used to be read into by XShmGetImage,716* it must be close enough to avoid excessive reading from the screen;717* otherwise it should just be at least the size requested.718*/719jboolean X11SD_CachedXImageFits(jint width, jint height, jint maxWidth,720jint maxHeight, jint depth, jboolean readBits)721{722/* we assume here that the cached image exists */723jint imgWidth = cachedXImage->width;724jint imgHeight = cachedXImage->height;725726if (imgWidth < width || imgHeight < height || depth != cachedXImage->depth) {727/* doesn't fit if any of the cached image dimensions is smaller728or the depths are different */729return JNI_FALSE;730}731732if (!readBits) {733/* Not reading from this image, so any image at least of the734size requested will do */735return JNI_TRUE;736}737738if ((imgWidth < width + 64) && (imgHeight < height + 64)739&& imgWidth <= maxWidth && imgHeight <= maxHeight)740{741/* Cached image's width/height shouldn't be more than 64 pixels742* larger than requested, because the region in XShmGetImage743* can't be specified and we don't want to read too much.744* Furthermore it has to be smaller than maxWidth/Height745* so drawables are not read out of bounds.746*/747return JNI_TRUE;748}749750return JNI_FALSE;751}752#endif /* MITSHM */753754jint X11SD_InitWindow(JNIEnv *env, X11SDOps *xsdo)755{756if (xsdo->isPixmap == JNI_TRUE) {757return SD_FAILURE;758}759xsdo->cData = xsdo->configData->color_data;760761return SD_SUCCESS;762}763764static jint X11SD_Lock(JNIEnv *env,765SurfaceDataOps *ops,766SurfaceDataRasInfo *pRasInfo,767jint lockflags)768{769X11SDOps *xsdo = (X11SDOps *) ops;770X11RIPrivate *xpriv = (X11RIPrivate *) &(pRasInfo->priv);771int ret = SD_SUCCESS;772773AWT_LOCK();774775if (xsdo->invalid) {776AWT_UNLOCK();777SurfaceData_ThrowInvalidPipeException(env, "bounds changed");778return SD_FAILURE;779}780xsdo->cData = xsdo->configData->color_data;781if (xsdo->drawable == 0 && X11SD_InitWindow(env, xsdo) == SD_FAILURE) {782AWT_UNLOCK();783return SD_FAILURE;784}785if ((lockflags & SD_LOCK_LUT) != 0 &&786(xsdo->cData == NULL ||787xsdo->cData->awt_icmLUT == NULL))788{789AWT_UNLOCK();790if (!(*env)->ExceptionCheck(env))791{792JNU_ThrowNullPointerException(env, "colormap lookup table");793}794return SD_FAILURE;795}796if ((lockflags & SD_LOCK_INVCOLOR) != 0 &&797(xsdo->cData == NULL ||798xsdo->cData->img_clr_tbl == NULL ||799xsdo->cData->img_oda_red == NULL ||800xsdo->cData->img_oda_green == NULL ||801xsdo->cData->img_oda_blue == NULL))802{803AWT_UNLOCK();804if (!(*env)->ExceptionCheck(env))805{806JNU_ThrowNullPointerException(env, "inverse colormap lookup table");807}808return SD_FAILURE;809}810if ((lockflags & SD_LOCK_INVGRAY) != 0 &&811(xsdo->cData == NULL ||812xsdo->cData->pGrayInverseLutData == NULL))813{814AWT_UNLOCK();815if (!(*env)->ExceptionCheck(env))816{817JNU_ThrowNullPointerException(env, "inverse gray lookup table");818}819return SD_FAILURE;820}821if (lockflags & SD_LOCK_RD_WR) {822if (lockflags & SD_LOCK_FASTEST) {823ret = SD_SLOWLOCK;824}825xpriv->lockType = X11SD_LOCK_BY_XIMAGE;826if (xsdo->isPixmap) {827#ifdef MITSHM828if (xsdo->shmPMData.usingShmPixmap) {829xpriv->lockType = X11SD_LOCK_BY_SHMEM;830}831#endif /* MITSHM */832if (pRasInfo->bounds.x1 < 0) {833pRasInfo->bounds.x1 = 0;834}835if (pRasInfo->bounds.y1 < 0) {836pRasInfo->bounds.y1 = 0;837}838if (pRasInfo->bounds.x2 > xsdo->pmWidth) {839pRasInfo->bounds.x2 = xsdo->pmWidth;840}841if (pRasInfo->bounds.y2 > xsdo->pmHeight) {842pRasInfo->bounds.y2 = xsdo->pmHeight;843}844}845} else {846/* They didn't lock for anything - we won't give them anything */847xpriv->lockType = X11SD_LOCK_BY_NULL;848}849xpriv->lockFlags = lockflags;850xpriv->img = NULL;851852return ret;853/* AWT_UNLOCK() called in Unlock */854}855856static void X11SD_GetRasInfo(JNIEnv *env,857SurfaceDataOps *ops,858SurfaceDataRasInfo *pRasInfo)859{860X11SDOps *xsdo = (X11SDOps *) ops;861X11RIPrivate *xpriv = (X11RIPrivate *) &(pRasInfo->priv);862jint lockFlags = xpriv->lockFlags;863jint depth = xsdo->depth;864int mult = xsdo->configData->pixelStride;865866867#ifdef MITSHM868if (xpriv->lockType == X11SD_LOCK_BY_SHMEM) {869if (xsdo->shmPMData.xRequestSent == JNI_TRUE) {870/* need to sync before using shared mem pixmap871if any x calls were issued for this pixmap */872XSync(awt_display, False);873xsdo->shmPMData.xRequestSent = JNI_FALSE;874}875xpriv->x = pRasInfo->bounds.x1;876xpriv->y = pRasInfo->bounds.y1;877pRasInfo->rasBase = xsdo->shmPMData.shmSegInfo->shmaddr;878pRasInfo->pixelStride = mult;879pRasInfo->pixelBitOffset = 0;880pRasInfo->scanStride = xsdo->shmPMData.bytesPerLine;881} else882#endif /* MITSHM */883if (xpriv->lockType == X11SD_LOCK_BY_XIMAGE) {884int x, y, w, h;885x = pRasInfo->bounds.x1;886y = pRasInfo->bounds.y1;887w = pRasInfo->bounds.x2 - x;888h = pRasInfo->bounds.y2 - y;889890xpriv->img = X11SD_GetImage(env, xsdo, &pRasInfo->bounds, lockFlags);891if (xpriv->img) {892int scan = xpriv->img->bytes_per_line;893xpriv->x = x;894xpriv->y = y;895pRasInfo->rasBase = xpriv->img->data - x * mult - (intptr_t) y * scan;896pRasInfo->pixelStride = mult;897pRasInfo->pixelBitOffset = 0;898pRasInfo->scanStride = scan;899} else {900pRasInfo->rasBase = NULL;901pRasInfo->pixelStride = 0;902pRasInfo->pixelBitOffset = 0;903pRasInfo->scanStride = 0;904}905} else {906/* They didn't lock for anything - we won't give them anything */907pRasInfo->rasBase = NULL;908pRasInfo->pixelStride = 0;909pRasInfo->pixelBitOffset = 0;910pRasInfo->scanStride = 0;911}912if (lockFlags & SD_LOCK_LUT) {913pRasInfo->lutBase = (jint *) xsdo->cData->awt_icmLUT;914pRasInfo->lutSize = xsdo->cData->awt_numICMcolors;915} else {916pRasInfo->lutBase = NULL;917pRasInfo->lutSize = 0;918}919if (lockFlags & SD_LOCK_INVCOLOR) {920pRasInfo->invColorTable = xsdo->cData->img_clr_tbl;921pRasInfo->redErrTable = xsdo->cData->img_oda_red;922pRasInfo->grnErrTable = xsdo->cData->img_oda_green;923pRasInfo->bluErrTable = xsdo->cData->img_oda_blue;924} else {925pRasInfo->invColorTable = NULL;926pRasInfo->redErrTable = NULL;927pRasInfo->grnErrTable = NULL;928pRasInfo->bluErrTable = NULL;929}930if (lockFlags & SD_LOCK_INVGRAY) {931pRasInfo->invGrayTable = xsdo->cData->pGrayInverseLutData;932} else {933pRasInfo->invGrayTable = NULL;934}935}936937static void X11SD_Unlock(JNIEnv *env,938SurfaceDataOps *ops,939SurfaceDataRasInfo *pRasInfo)940{941X11SDOps *xsdo = (X11SDOps *) ops;942X11RIPrivate *xpriv = (X11RIPrivate *) &(pRasInfo->priv);943944if (xpriv->lockType == X11SD_LOCK_BY_XIMAGE &&945xpriv->img != NULL)946{947if (xpriv->lockFlags & SD_LOCK_WRITE) {948int x = xpriv->x;949int y = xpriv->y;950int w = pRasInfo->bounds.x2 - x;951int h = pRasInfo->bounds.y2 - y;952Drawable drawable = xsdo->drawable;953GC xgc = xsdo->cachedGC;954if (xgc == NULL) {955xsdo->cachedGC = xgc =956XCreateGC(awt_display, drawable, 0L, NULL);957}958959if (xpriv->img->byte_order != nativeByteOrder) {960/* switching bytes back in 24 and 32 bpp cases. */961/* For 16 bit XLib will switch for us. */962if (xsdo->depth > 16) {963X11SD_SwapBytes(xsdo, xpriv->img, xsdo->depth,964xsdo->configData->awtImage->wsImageFormat.bits_per_pixel);965}966}967968#ifdef MITSHM969if (xpriv->img->obdata != NULL) {970XShmPutImage(awt_display, drawable, xgc,971xpriv->img, 0, 0, x, y, w, h, False);972XFlush(awt_display);973} else {974XPutImage(awt_display, drawable, xgc,975xpriv->img, 0, 0, x, y, w, h);976}977if (xsdo->shmPMData.usingShmPixmap) {978xsdo->shmPMData.xRequestSent = JNI_TRUE;979}980#else981XPutImage(awt_display, drawable, xgc,982xpriv->img, 0, 0, x, y, w, h);983#endif /* MITSHM */984985}986X11SD_DisposeOrCacheXImage(xpriv->img);987xpriv->img = (XImage *)NULL;988}989/* the background pixel is not valid anymore */990if (xpriv->lockFlags & SD_LOCK_WRITE) {991xsdo->isBgInitialized = JNI_FALSE;992}993xpriv->lockType = X11SD_LOCK_UNLOCKED;994AWT_UNLOCK();995}996997static int998X11SD_ClipToRoot(SurfaceDataBounds *b, SurfaceDataBounds *bounds,999X11SDOps *xsdo)1000{1001short x1=0, y1=0, x2=0, y2=0;1002int tmpx, tmpy;1003Window tmpchild;10041005Window window = (Window)(xsdo->drawable); /* is always a Window */1006XWindowAttributes winAttr;10071008Status status = XGetWindowAttributes(awt_display, window, &winAttr);1009if (status == 0) {1010/* Failure, X window no longer valid. */1011return FALSE;1012}1013if (!XTranslateCoordinates(awt_display, window,1014RootWindowOfScreen(winAttr.screen),10150, 0, &tmpx, &tmpy, &tmpchild)) {1016return FALSE;1017}10181019x1 = -(x1 + tmpx);1020y1 = -(y1 + tmpy);10211022x2 = x1 + DisplayWidth(awt_display, xsdo->configData->awt_visInfo.screen);1023y2 = y1 + DisplayHeight(awt_display, xsdo->configData->awt_visInfo.screen);10241025x1 = XSD_MAX(bounds->x1, x1);1026y1 = XSD_MAX(bounds->y1, y1);1027x2 = XSD_MIN(bounds->x2, x2);1028y2 = XSD_MIN(bounds->y2, y2);1029if ((x1 >= x2) || (y1 >= y2)) {1030return FALSE;1031}1032b->x1 = x1;1033b->y1 = y1;1034b->x2 = x2;1035b->y2 = y2;10361037return TRUE;1038}10391040/*1041* x1, y1, x2, y2 - our rectangle in the coord system of1042* the widget1043* px1, xy1, px2, py2 - current parent rect coords in the1044* same system1045*/1046static int1047X11SD_FindClip(SurfaceDataBounds *b, SurfaceDataBounds *bounds, X11SDOps *xsdo)1048{1049return TRUE;1050}10511052static void1053X11SD_SwapBytes(X11SDOps *xsdo, XImage * img, int depth, int bpp) {1054jlong lengthInBytes = (jlong) img->height * img->bytes_per_line;1055jlong i;10561057switch (depth) {1058case 12:1059case 15:1060case 16:1061{1062/* AB -> BA */1063unsigned short *d = (unsigned short *)img->data;1064unsigned short t;1065for (i = 0; i < lengthInBytes/2; i++) {1066t = *d;1067*d++ = (t >> 8) | (t << 8);1068}1069img->byte_order = nativeByteOrder;1070img->bitmap_bit_order = nativeByteOrder;1071break;1072}1073case 24:1074{1075/* ABC -> CBA */1076if (bpp == 24) {1077// 4517321: Only swap if we have a "real" ThreeByteBgr1078// visual (denoted by a red_mask of 0xff). Due to ambiguity1079// in the X11 spec, it appears that the swap is not required1080// on Linux configurations that use 24 bits per pixel (denoted1081// by a red_mask of 0xff0000).1082if (xsdo->configData->awt_visInfo.red_mask == 0xff) {1083int scan = img->bytes_per_line;1084unsigned char *d = (unsigned char *) img->data;1085unsigned char *d1;1086unsigned int t;1087int j;10881089for (i = 0; i < img->height; i++, d += scan) {1090d1 = d;1091for (j = 0; j < img->width; j++, d1 += 3) {1092/* not obvious opt from XLib src */1093t = d1[0]; d1[0] = d1[2]; d1[2] = t;1094}1095}1096}1097break;1098}1099}1100/* FALL THROUGH for 32-bit case */1101case 32:1102{1103/* ABCD -> DCBA */1104unsigned int *d = (unsigned int *) img->data;1105unsigned int t;1106for (i = 0; i < lengthInBytes/4; i++) {1107t = *d;1108*d++ = ((t >> 24) |1109((t >> 8) & 0xff00) |1110((t & 0xff00) << 8) |1111(t << 24));1112}1113break;1114}1115}1116}11171118static XImage * X11SD_GetImage(JNIEnv *env, X11SDOps *xsdo,1119SurfaceDataBounds *bounds,1120jint lockFlags)1121{1122int x, y, w, h, maxWidth, maxHeight;1123int scan;1124XImage * img = NULL;1125Drawable drawable;1126int depth = xsdo->depth;1127int mult = xsdo->configData->pixelStride;1128int pad = X11SD_GetBitmapPad(mult);1129jboolean readBits = lockFlags & SD_LOCK_NEED_PIXELS;11301131x = bounds->x1;1132y = bounds->y1;1133w = bounds->x2 - x;1134h = bounds->y2 - y;11351136#ifdef MITSHM1137if (useMitShmExt == CAN_USE_MITSHM) {1138if (xsdo->isPixmap) {1139if (readBits) {1140X11SD_PuntPixmap(xsdo, w, h);1141}1142maxWidth = xsdo->pmWidth;1143maxHeight = xsdo->pmHeight;1144} else {1145XWindowAttributes winAttr;1146if (XGetWindowAttributes(awt_display,1147(Window) xsdo->drawable, &winAttr) != 0) {1148maxWidth = winAttr.width;1149maxHeight = winAttr.height;1150} else {1151/* XGWA failed which isn't a good thing. Defaulting to using1152* x,y means that after the subtraction of these we will use1153* w=0, h=0 which is a reasonable default on such a failure.1154*/1155maxWidth = x;1156maxHeight = y;1157}1158}1159maxWidth -= x;1160maxHeight -= y;11611162img = X11SD_GetSharedImage(xsdo, w, h, maxWidth, maxHeight, readBits);1163}1164#endif /* MITSHM */1165drawable = xsdo->drawable;11661167if (readBits) {1168#ifdef MITSHM1169if (img != NULL) {1170if (!XShmGetImage(awt_display, drawable, img, x, y, -1)) {1171X11SD_DisposeOrCacheXImage(img);1172img = NULL;1173}1174}1175if (img == NULL) {1176img = XGetImage(awt_display, drawable, x, y, w, h, -1, ZPixmap);1177if (img != NULL) {1178img->obdata = NULL;1179}1180}1181#else1182img = XGetImage(awt_display, drawable, x, y, w, h, -1, ZPixmap);1183#endif /* MITSHM */1184if (img == NULL) {1185SurfaceDataBounds temp;1186img = XCreateImage(awt_display,1187xsdo->configData->awt_visInfo.visual,1188depth, ZPixmap, 0, NULL, w, h, pad, 0);1189if (img == NULL) {1190return NULL;1191}11921193scan = img->bytes_per_line;1194img->data = malloc((size_t) h * scan);1195if (img->data == NULL) {1196XFree(img);1197return NULL;1198}11991200if (xsdo->isPixmap == JNI_FALSE &&1201X11SD_ClipToRoot(&temp, bounds, xsdo)) {12021203XImage * temp_image;1204temp_image = XGetImage(awt_display, drawable,1205temp.x1, temp.y1,1206temp.x2 - temp.x1,1207temp.y2 - temp.y1,1208-1, ZPixmap);1209if (temp_image == NULL) {1210XGrabServer(awt_display);1211if (X11SD_FindClip(&temp, bounds, xsdo)) {1212temp_image =1213XGetImage(awt_display, drawable,1214temp.x1, temp.y1,1215temp.x2 - temp.x1,1216temp.y2 - temp.y1,1217-1, ZPixmap);1218}1219XUngrabServer(awt_display);1220/* Workaround for bug 5039226 */1221XSync(awt_display, False);1222}1223if (temp_image != NULL) {1224int temp_scan, bytes_to_copy;1225char * img_addr, * temp_addr;1226int i;12271228img_addr = img->data +1229(intptr_t) (temp.y1 - y) * scan + (temp.x1 - x) * mult;1230temp_scan = temp_image->bytes_per_line;1231temp_addr = temp_image->data;1232bytes_to_copy = (temp.x2 - temp.x1) * mult;1233for (i = temp.y1; i < temp.y2; i++) {1234memcpy(img_addr, temp_addr, bytes_to_copy);1235img_addr += scan;1236temp_addr += temp_scan;1237}1238XDestroyImage(temp_image);1239}1240}1241img->obdata = NULL;1242}1243if (depth > 8 && img->byte_order != nativeByteOrder) {1244X11SD_SwapBytes(xsdo, img, depth,1245xsdo->configData->awtImage->wsImageFormat.bits_per_pixel);1246}1247} else {1248/*1249* REMIND: This might be better to move to the Lock function1250* to avoid lengthy I/O pauses inside what may be a critical1251* section. This will be more critical when SD_LOCK_READ is1252* implemented. Another solution is to cache the pixels1253* to avoid reading for every operation.1254*/1255if (img == NULL) {1256img = XCreateImage(awt_display,1257xsdo->configData->awt_visInfo.visual,1258depth, ZPixmap, 0, NULL, w, h, pad, 0);1259if (img == NULL) {1260return NULL;1261}12621263img->data = malloc((size_t) h * img->bytes_per_line);1264if (img->data == NULL) {1265XFree(img);1266return NULL;1267}12681269img->obdata = NULL;12701271if (img->byte_order != nativeByteOrder &&1272(depth == 15 || depth == 16 || depth == 12)) {1273/* bytes will be swapped by XLib. */1274img->byte_order = nativeByteOrder;1275img->bitmap_bit_order = nativeByteOrder;1276}1277}1278}1279return img;1280}12811282void X11SD_DisposeOrCacheXImage(XImage * image) {1283/* REMIND: might want to check if the new image worth caching. */1284/* Cache only shared images. Passed image is assumed to be non-null. */1285if (image->obdata != NULL) {1286if (cachedXImage != NULL) {1287X11SD_DisposeXImage(cachedXImage);1288}1289cachedXImage = image;1290} else {1291X11SD_DisposeXImage(image);1292}1293}12941295void X11SD_DisposeXImage(XImage * image) {1296if (image != NULL) {1297#ifdef MITSHM1298if (image->obdata != NULL) {1299X11SD_DropSharedSegment((XShmSegmentInfo*)image->obdata);1300image->obdata = NULL;1301}1302#endif /* MITSHM */1303XDestroyImage(image);1304}1305}13061307void1308X11SD_DirectRenderNotify(JNIEnv *env, X11SDOps *xsdo)1309{1310#ifdef MITSHM1311if (xsdo->shmPMData.usingShmPixmap) {1312xsdo->shmPMData.xRequestSent = JNI_TRUE;1313}1314#endif /* MITSHM */1315awt_output_flush();1316}13171318/*1319* Sets transparent pixels in the pixmap to1320* the specified solid background color and returns it.1321* Doesn't update source pixmap unless the color of the1322* transparent pixels is different from the specified color.1323*1324* Note: The AWT lock must be held by the current thread1325* while calling into this method.1326*/1327static Drawable1328X11SD_GetPixmapWithBg(JNIEnv *env, X11SDOps *xsdo, jint pixel)1329{1330/* assert AWT_CHECK_HAVE_LOCK(); */13311332if (xsdo->invalid) {1333AWT_UNLOCK();1334SurfaceData_ThrowInvalidPipeException(env, "bounds changed");1335return 0;1336}13371338/* the image doesn't have transparency, just return it */1339if (xsdo->bitmask == 0) {1340/* don't need to unlock here, the caller will unlock through1341the release call */1342return xsdo->drawable;1343}13441345/* Check if current color of the transparent pixels is different1346from the specified one */1347if (xsdo->isBgInitialized == JNI_FALSE || xsdo->bgPixel != pixel) {1348GC srcGC;1349GC bmGC;13501351if (xsdo->drawable == 0) {1352AWT_UNLOCK();1353return 0;1354}13551356bmGC = XCreateGC(awt_display, xsdo->bitmask, 0, NULL);1357if (bmGC == NULL) {1358AWT_UNLOCK();1359return 0;1360}13611362/* invert the bitmask */1363XSetFunction(awt_display, bmGC, GXxor);1364XSetForeground(awt_display, bmGC, 1);1365XFillRectangle(awt_display, xsdo->bitmask, bmGC,13660, 0, xsdo->pmWidth, xsdo->pmHeight);13671368srcGC = XCreateGC(awt_display, xsdo->drawable, 0L, NULL);1369if (srcGC == NULL) {1370XFreeGC(awt_display, bmGC);1371AWT_UNLOCK();1372return 0;1373}13741375/* set transparent pixels in the source pm to the bg color */1376XSetClipMask(awt_display, srcGC, xsdo->bitmask);1377XSetForeground(awt_display, srcGC, pixel);1378XFillRectangle(awt_display, xsdo->drawable, srcGC,13790, 0, xsdo->pmWidth, xsdo->pmHeight);13801381/* invert the mask back */1382XFillRectangle(awt_display, xsdo->bitmask, bmGC,13830, 0, xsdo->pmWidth, xsdo->pmHeight);13841385XFreeGC(awt_display, bmGC);1386XFreeGC(awt_display, srcGC);1387xsdo->bgPixel = pixel;1388xsdo->isBgInitialized = JNI_TRUE;1389}13901391return xsdo->drawable;1392}13931394static void1395X11SD_ReleasePixmapWithBg(JNIEnv *env, X11SDOps *xsdo)1396{1397#ifdef MITSHM1398if (xsdo->shmPMData.usingShmPixmap) {1399xsdo->shmPMData.xRequestSent = JNI_TRUE;1400}1401#endif /* MITSHM */1402}14031404static int X11SD_GetBitmapPad(int pixelStride) {1405// pad must be 8, 16, or 321406return (pixelStride == 3) ? 32 : pixelStride * 8;1407}14081409#endif /* !HEADLESS */14101411/*1412* Class: sun_java2d_x11_X11SurfaceData1413* Method: XCreateGC1414* Signature: (I)J1415*/1416JNIEXPORT jlong JNICALL1417Java_sun_java2d_x11_XSurfaceData_XCreateGC1418(JNIEnv *env, jclass xsd, jlong pXSData)1419{1420jlong ret;14211422#ifndef HEADLESS1423X11SDOps *xsdo;14241425J2dTraceLn(J2D_TRACE_INFO, "in X11SurfaceData_XCreateGC");14261427xsdo = (X11SDOps *) pXSData;1428if (xsdo == NULL) {1429return 0L;1430}14311432xsdo->javaGC = XCreateGC(awt_display, xsdo->drawable, 0, NULL);1433ret = (jlong) xsdo->javaGC;1434#else /* !HEADLESS */1435ret = 0L;1436#endif /* !HEADLESS */14371438return ret;1439}14401441/*1442* Class: sun_java2d_x11_X11SurfaceData1443* Method: XResetClip1444* Signature: (JIIIILsun/java2d/pipe/Region;)V1445*/1446JNIEXPORT void JNICALL1447Java_sun_java2d_x11_XSurfaceData_XResetClip1448(JNIEnv *env, jclass xsd, jlong xgc)1449{1450#ifndef HEADLESS1451J2dTraceLn(J2D_TRACE_INFO, "in X11SurfaceData_XResetClip");1452XSetClipMask(awt_display, (GC) xgc, None);1453#endif /* !HEADLESS */1454}14551456/*1457* Class: sun_java2d_x11_X11SurfaceData1458* Method: XSetClip1459* Signature: (JIIIILsun/java2d/pipe/Region;)V1460*/1461JNIEXPORT void JNICALL1462Java_sun_java2d_x11_XSurfaceData_XSetClip1463(JNIEnv *env, jclass xsd, jlong xgc,1464jint x1, jint y1, jint x2, jint y2,1465jobject complexclip)1466{1467#ifndef HEADLESS1468int numrects;1469XRectangle rects[256];1470XRectangle *pRect = rects;14711472J2dTraceLn(J2D_TRACE_INFO, "in X11SurfaceData_XSetClip");14731474numrects = RegionToYXBandedRectangles(env,1475x1, y1, x2, y2, complexclip,1476&pRect, 256);14771478XSetClipRectangles(awt_display, (GC) xgc, 0, 0, pRect, numrects, YXBanded);14791480if (pRect != rects) {1481free(pRect);1482}1483#endif /* !HEADLESS */1484}14851486/*1487* Class: sun_java2d_x11_X11SurfaceData1488* Method: XSetCopyMode1489* Signature: (J)V1490*/1491JNIEXPORT void JNICALL1492Java_sun_java2d_x11_X11SurfaceData_XSetCopyMode1493(JNIEnv *env, jclass xsd, jlong xgc)1494{1495#ifndef HEADLESS1496J2dTraceLn(J2D_TRACE_INFO, "in X11SurfaceData_XSetCopyMode");1497XSetFunction(awt_display, (GC) xgc, GXcopy);1498#endif /* !HEADLESS */1499}15001501/*1502* Class: sun_java2d_x11_X11SurfaceData1503* Method: XSetXorMode1504* Signature: (J)V1505*/1506JNIEXPORT void JNICALL1507Java_sun_java2d_x11_X11SurfaceData_XSetXorMode1508(JNIEnv *env, jclass xr, jlong xgc)1509{1510#ifndef HEADLESS1511J2dTraceLn(J2D_TRACE_INFO, "in X11SurfaceData_XSetXorMode");1512XSetFunction(awt_display, (GC) xgc, GXxor);1513#endif /* !HEADLESS */1514}15151516/*1517* Class: sun_java2d_x11_X11SurfaceData1518* Method: XSetForeground1519* Signature: (JI)V1520*/1521JNIEXPORT void JNICALL1522Java_sun_java2d_x11_X11SurfaceData_XSetForeground1523(JNIEnv *env, jclass xsd, jlong xgc, jint pixel)1524{1525#ifndef HEADLESS1526J2dTraceLn(J2D_TRACE_INFO, "in X11SurfaceData_XSetForeground");1527XSetForeground(awt_display, (GC) xgc, pixel);1528#endif /* !HEADLESS */1529}15301531/*1532* Class: sun_java2d_x11_X11SurfaceData1533* Method: XSetGraphicsExposures1534* Signature: (JZ)V1535*/1536JNIEXPORT void JNICALL1537Java_sun_java2d_x11_XSurfaceData_XSetGraphicsExposures1538(JNIEnv *env, jclass xsd, jlong xgc, jboolean needExposures)1539{1540#ifndef HEADLESS1541J2dTraceLn(J2D_TRACE_INFO, "in X11SurfaceData_XSetGraphicsExposures");1542XSetGraphicsExposures(awt_display, (GC) xgc, needExposures ? True : False);1543#endif /* !HEADLESS */1544}154515461547