40 |
#include "gnu_java_awt_peer_gtk_GtkToolkit.h" |
#include "gnu_java_awt_peer_gtk_GtkToolkit.h" |
41 |
#include "gthread-jni.h" |
#include "gthread-jni.h" |
42 |
|
|
43 |
|
#include <sys/time.h> |
44 |
|
|
45 |
#ifdef JVM_SUN |
#ifdef JVM_SUN |
46 |
struct state_table *native_state_table; |
struct state_table *native_state_table; |
47 |
struct state_table *native_global_ref_table; |
struct state_table *native_global_ref_table; |
300 |
dpi_conversion_factor = PANGO_SCALE * 72.0 / (int_dpi / PANGO_SCALE); |
dpi_conversion_factor = PANGO_SCALE * 72.0 / (int_dpi / PANGO_SCALE); |
301 |
} |
} |
302 |
|
|
303 |
|
static int |
304 |
|
within_human_latency_tolerance(struct timeval *init) |
305 |
|
{ |
306 |
|
struct timeval curr; |
307 |
|
unsigned long milliseconds_elapsed; |
308 |
|
|
309 |
|
gettimeofday(&curr, NULL); |
310 |
|
|
311 |
|
milliseconds_elapsed = (((curr.tv_sec * 1000) + (curr.tv_usec / 1000)) |
312 |
|
- ((init->tv_sec * 1000) + (init->tv_usec / 1000))); |
313 |
|
|
314 |
|
return milliseconds_elapsed < 100; |
315 |
|
} |
316 |
|
|
317 |
|
|
318 |
JNIEXPORT void JNICALL |
JNIEXPORT void JNICALL |
319 |
Java_gnu_java_awt_peer_gtk_GtkToolkit_iterateNativeQueue |
Java_gnu_java_awt_peer_gtk_GtkToolkit_iterateNativeQueue |
320 |
(JNIEnv *env, |
(JNIEnv *env, |
321 |
jobject self __attribute__((unused)), |
jobject self __attribute__((unused)), |
322 |
jobject lockedQueue) |
jobject lockedQueue, |
323 |
|
jboolean block) |
324 |
{ |
{ |
325 |
/* We're holding an EventQueue lock, and we're about to acquire the GDK |
/* We're holding an EventQueue lock, and we're about to acquire the GDK |
326 |
* lock before dropping the EventQueue lock. This can deadlock if someone |
* lock before dropping the EventQueue lock. This can deadlock if someone |
330 |
* acquiring the GDK lock and calling back into |
* acquiring the GDK lock and calling back into |
331 |
* EventQueue.getNextEvent(). |
* EventQueue.getNextEvent(). |
332 |
*/ |
*/ |
333 |
|
|
334 |
|
struct timeval init; |
335 |
|
gettimeofday(&init, NULL); |
336 |
|
|
337 |
gdk_threads_enter (); |
gdk_threads_enter (); |
338 |
(*env)->MonitorExit (env, lockedQueue); |
(*env)->MonitorExit (env, lockedQueue); |
339 |
|
|
340 |
/* It is quite important that this be a do .. while loop. The first pass |
if (block) |
|
* should do an iteration w/o a test so that it sleeps when there really |
|
|
* aren't any events; and the loop should continue for as many events as |
|
|
* there are to avoid pointless thrashing up and down through JNI (it |
|
|
* runs very slowly when this is not a loop). |
|
|
*/ |
|
|
do |
|
341 |
{ |
{ |
342 |
gtk_main_iteration(); |
|
343 |
|
/* If we're blocking-when-empty, we want a do .. while loop. */ |
344 |
|
do |
345 |
|
gtk_main_iteration (); |
346 |
|
while (within_human_latency_tolerance (&init) |
347 |
|
&& gtk_events_pending ()); |
348 |
} |
} |
349 |
while (gtk_events_pending()); |
else |
350 |
|
{ |
351 |
|
/* If we're not blocking-when-empty, we want a while loop. */ |
352 |
|
while (within_human_latency_tolerance (&init) |
353 |
|
&& gtk_events_pending ()) |
354 |
|
gtk_main_iteration (); |
355 |
|
} |
356 |
|
|
357 |
(*env)->MonitorEnter (env, lockedQueue); |
(*env)->MonitorEnter (env, lockedQueue); |
358 |
gdk_threads_leave (); |
gdk_threads_leave (); |
359 |
} |
} |