Skip to main content

JAWT Rendering with Native Code

3 replies [Last post]
swpalmer
Offline
Joined: 2003-06-10
Points: 0

This was a sub question of my Help with Heavyweight in Swing post.. since I resolved that main issue I figured I would ask this specific question separately as I am still interested in the answer:

If I need to do rendering with native code the support method is to use JAWT and all of the information on java.sun.com indicates I must build on a heavyweight Canvas to do this, however:

Question #1
I'm currently only using the hdc member of jawt_Win32DrawingSurfaceInfo, but how do I know which interpretation of the union of { HWND, HBITMAP, void*pbits } is valid?

Question #2
It seems that since that union holds either a native window handle, DDB, or DIB that I can somehow use the JAWT stuff on something that isn't a heavyweight, like an offscreen bitmap. �It seems that I could be asked to draw on some sort of backbuffer is that possible?

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
bino_george
Offline
Joined: 2003-06-16
Points: 0

Hi,
Typically the union will point to the hwnd, if the Graphics is
for a component and not a BufferedImage. Here is an example of how you would use it :

[code]
JNIEXPORT void JNICALL Java_MyCanvas_paint
(JNIEnv* env, jobject canvas, jobject graphics)
{
/* Get the AWT */
JAWT awt;
awt.version = JAWT_VERSION_1_4;
if (JAWT_GetAWT(env, &awt) == JNI_FALSE) {
printf("AWT Not found\n");
return;
}

/* Lock the AWT */
awt.Lock(env);

/* Unlock the AWT */
awt.Unlock(env);

/* Get the drawing surface */
JAWT_DrawingSurface* ds = awt.GetDrawingSurface(env, canvas);
if (ds == NULL) {
printf("NULL drawing surface\n");
return;
}

/* Lock the drawing surface */
jint lock = ds->Lock(ds);
printf("Lock value %d\n", (int)lock);
if((lock & JAWT_LOCK_ERROR) != 0) {
printf("Error locking surface\n");
return;
}

/* Get the drawing surface info */
JAWT_DrawingSurfaceInfo* dsi = ds->GetDrawingSurfaceInfo(ds);
if (dsi == NULL) {
printf("Error getting surface info\n");
ds->Unlock(ds);
return;
}

/* Get the platform-specific drawing info */
JAWT_Win32DrawingSurfaceInfo* dsi_win =
(JAWT_Win32DrawingSurfaceInfo*)dsi->platformInfo;

/* Now paint */
PAINTSTRUCT ps;
/* Do not use the HDC returned from BeginPaint()!! */
::BeginPaint(dsi_win->hwnd, &ps);
HBRUSH hbrush = (HBRUSH)::GetStockObject(BLACK_BRUSH);
RECT rect;
rect.left = 5;
rect.top = 5;
rect.right = 95;
rect.bottom = 95;
::FillRect(dsi_win->hdc, &rect, hbrush);
::EndPaint(dsi_win->hwnd, &ps);

jobject ref = awt.GetComponent(env, (void*)(dsi_win->hwnd));
if (!env->IsSameObject(ref, canvas)) {
printf("Error! Different objects!\n");
}

/* Free the drawing surface info */
ds->FreeDrawingSurfaceInfo(dsi);

/* Unlock the drawing surface */
ds->Unlock(ds);

/* Free the drawing surface */
awt.FreeDrawingSurface(ds);
}
[/code]

Hope this makes sense to you. If you need a better example, I could email
you one, let me know.

Regards,
Bino.

Code tags added by Admin

swpalmer
Offline
Joined: 2003-06-10
Points: 0

Thank you for the example. I am interested in something more detailed though. You say the graphics could be for a BufferedImage.. yet the JAWT documentation for GetDrawingSurface says the parameter IS a Canvas. What other options do I have, and do you have examples available that demonstrate the use of all of the different members of the union in JAWT_Win32DrawingSurfaceInfo?

My current use has always been with hwnd. I recently use these APIs simply to get the hwnd so that I can bring up native dialogs with the appropriate parent window, so the child dialog can't get hidden behind the main app window (which is Swing). I didn't need to paint on the surface at all. I needed to do this to interact with configuration dialogs that were provided for components written in C/C++.

I am interested in other possible ways to 'play nice' with Swing UIs and images coming from native code. I have a big project that runs in two modes. One as a GUI to windows only services provided by custom hardware, the other as a remote interface to these same services that can run on any Java enabled platform on the network. I'm sharing the same UI classes and in most cases simply providing a different implementation for the interface to the hardware. If I could be updating a BufferedImage instead of directly painting on a Canvas that could be useful in some areas of the UI.

Since my main "windows only" GUI is still Swing and my application is a multi-media tool I will need efficient and robust access to frames of live video. I have looked at JMF and it is not an option.

I should also mention that I'm pushing graphics to the screen for video preview.. so I don't even bother with the paint method or a Graphics object. A native thread is called once per frame and I draw directly to the HDC. I've called ignorRepaint(true); and implemented a do-nothing paint method.

If you would like to email a more complete sample please send it to Scott at digital-rapids dot com.

Thanks,

Scott

bino_george
Offline
Joined: 2003-06-16
Points: 0

Hi Scott,
The 2D folks added support for accesing the
native surface (DX7 interface, I think) of a Volatile Image
starting in 1.4.1.02. The guy who did this was Chet Haase
from the 2D team. So I would suggest posting the same question
on the 2D forum and you should get a reply from Chet (who is
usually lurking there). On Monday, I will talk to him to
find out more about this. I looked at the DrawingSurface code
and it looks like you can use JAWT to render to Volatile images, but
how much it is supported is a different question. Hopefully
I can also get some sample code that does this for you.

> I am interested in other possible ways to 'play nice'
> with Swing UIs and images coming from native code. I
> have a big project that runs in two modes. One as a
> GUI to windows only services provided by custom
> hardware, the other as a remote interface to these
> same services that can run on any Java enabled
> platform on the network. I'm sharing the same UI
> classes and in most cases simply providing a
> different implementation for the interface to the
> hardware. If I could be updating a BufferedImage
> instead of directly painting on a Canvas that could
> be useful in some areas of the UI.

Well, if JAWT rendering to VolatileImages work, this
should help, in that you could render to the VolatileImage
in your native code and then copy it to the screen, on paint.

> If you would like to email a more complete sample
> please send it to Scott at digital-rapids dot com.
>

Yes, I will send you more info on Monday, Also try
posting on the 2D forum.

Regards,
Bino.