| steven fan 2006-09-28, 2:31 am |
| All,
I am doing a project which need to show opaque window in solaris,linux and mac. The shape of the window depends on image. I load the image in java and use JNI to call .so lib.
I hava complete a .so lib which work fine in linux, but it does not work in soalris.
Could you help me to find the cause? Maybe i need more knowledge on XShape.
The c file is:
JNIEXPORT void JNICALL Java_com_lucent_lps_client_user_shape_Wi
ndowShape_setNativeWindowShape
(JNIEnv * env, jclass cls, jobject win, jintArray j_img_arr, jint width, jint height, jboolean redraw)
{
JAWT awt;
JAWT_DrawingSurface* ds;
JAWT_DrawingSurfaceInfo* dsi;
JAWT_X11DrawingSurfaceInfo* dsi_win;
jboolean result;
jint lock;
int img_size;
int * img_arr;
Region region;
XRectangle stripe;
int img_idx;
int x,y;
GC win_gc;
XGCValues xgcv;
awt.version = JAWT_VERSION_1_3;
result = JAWT_GetAWT(env, &awt);
assert(result != JNI_FALSE);
// Get the drawing surface
ds = awt.GetDrawingSurface(env, win);
assert(ds != NULL);
// Lock the drawing surface
lock = ds->Lock(ds);
assert((lock & JAWT_LOCK_ERROR) == 0);
// Get the drawing surface info
dsi = ds->GetDrawingSurfaceInfo(ds);
// Get the platform-specific drawing info
dsi_win = (JAWT_X11DrawingSurfaceInfo*)dsi->platformInfo;
// Extract the image array from the jvm
img_size = (*env)->GetArrayLength(env, j_img_arr);
img_arr = (int*)(*env)->GetIntArrayElements(env, j_img_arr, 0);
xgcv.foreground = BlackPixel(dsi_win->display, DefaultScreen(dsi_win->display));
xgcv.line_width = 1;
xgcv.line_style = LineSolid;
win_gc = XCreateGC(dsi_win->display,dsi_win->drawable,GCForeground | GCLineWidth | GCLineStyle, &xgcv);
XSetBackground(dsi_win->display,win_gc,0);
XSetForeground(dsi_win->display,win_gc,0);
// Create the region to set this window to - but don't
// put any pixels in it yet - we will build it up stripe
// by stripe.
region = XCreateRegion();
img_idx = 0;
for (y=0; y<height; y++)
{
int inprogress = 0;
int startx = 0;
for (x=0; x<width; x++)
{
// Test if the alpha byte is non-zero
if ((img_arr[img_idx] & 0xFF000000) == 0)
{
// We're at a transparent pixel
if (inprogress == 1)
{
stripe.x=startx;
stripe.y=y;
stripe.width=x-startx;
stripe.height=1;
XUnionRectWithRegion(&stripe, region, region);
inprogress = 0;
}
}
else
{
// We've got a non-transparent pixel
if (inprogress == 0)
{
startx = x;
inprogress = 1;
}
}
img_idx += 1;
}
if (inprogress)
{
stripe.x=startx;
stripe.y=y;
stripe.width=x+1-startx;
stripe.height=1;
XUnionRectWithRegion(&stripe, region, region);
}
}
// Assign the newly created region to the window
XShapeCombineRegion(dsi_win->display,dsi_win-> drawable,ShapeBounding,0,0,region,ShapeS
et);
// Free the stripe, but not the region, since the system
// now owns the region
XDestroyRegion(region);
// Release the JVM resources
(*env)->ReleaseIntArrayElements(env, j_img_arr, img_arr, JNI_ABORT);
// Free the drawing surface info
ds->FreeDrawingSurfaceInfo(dsi);
// Unlock the drawing surface
ds->Unlock(ds); // Free the drawing surface
awt.FreeDrawingSurface(ds);
}
The java file is:
 |