Skip to content

Commit af94bb0

Browse files
author
duke
committed
Backport 965aace297154ab08ee41a4d988553707cae8b32
1 parent 8160986 commit af94bb0

File tree

6 files changed

+55
-20
lines changed

6 files changed

+55
-20
lines changed

src/java.desktop/unix/native/libawt_xawt/awt/fp_pipewire.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -58,7 +58,6 @@ void (*fp_pw_stream_destroy)(struct pw_stream *stream);
5858

5959

6060
void (*fp_pw_init)(int *argc, char **argv[]);
61-
void (*fp_pw_deinit)(void);
6261

6362
struct pw_core *
6463
(*fp_pw_context_connect_fd)(struct pw_context *context,

src/java.desktop/unix/native/libawt_xawt/awt/gtk3_interface.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -283,6 +283,9 @@ GtkApi* gtk3_load(JNIEnv *env, const char* lib_name)
283283

284284
fp_g_main_context_iteration =
285285
dl_symbol("g_main_context_iteration");
286+
fp_g_main_context_default = dl_symbol("g_main_context_default");
287+
fp_g_main_context_is_owner = dl_symbol("g_main_context_is_owner");
288+
286289

287290
fp_g_value_init = dl_symbol("g_value_init");
288291
fp_g_type_is_a = dl_symbol("g_type_is_a");
@@ -554,6 +557,7 @@ GtkApi* gtk3_load(JNIEnv *env, const char* lib_name)
554557
fp_g_signal_connect_data = dl_symbol("g_signal_connect_data");
555558
fp_gtk_widget_show = dl_symbol("gtk_widget_show");
556559
fp_gtk_main = dl_symbol("gtk_main");
560+
fp_gtk_main_level = dl_symbol("gtk_main_level");
557561

558562
fp_g_path_get_dirname = dl_symbol("g_path_get_dirname");
559563

@@ -3103,6 +3107,8 @@ static void gtk3_init(GtkApi* gtk) {
31033107
gtk->g_uuid_string_is_valid = fp_g_uuid_string_is_valid;
31043108

31053109
gtk->g_main_context_iteration = fp_g_main_context_iteration;
3110+
gtk->g_main_context_default = fp_g_main_context_default;
3111+
gtk->g_main_context_is_owner = fp_g_main_context_is_owner;
31063112
gtk->g_error_free = fp_g_error_free;
31073113
gtk->g_unix_fd_list_get = fp_g_unix_fd_list_get;
31083114

src/java.desktop/unix/native/libawt_xawt/awt/gtk3_interface.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,9 @@ static void (*fp_g_object_set)(gpointer object,
392392
...);
393393

394394
static gboolean (*fp_g_main_context_iteration)(GMainContext *context, gboolean may_block);
395+
static GMainContext *(*fp_g_main_context_default)();
396+
static gboolean (*fp_g_main_context_is_owner)(GMainContext* context);
397+
395398
static gboolean (*fp_g_str_has_prefix)(const gchar *str, const gchar *prefix);
396399
static gchar** (*fp_g_strsplit)(const gchar *string, const gchar *delimiter,
397400
gint max_tokens);

src/java.desktop/unix/native/libawt_xawt/awt/gtk_interface.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -792,6 +792,8 @@ typedef struct GtkApi {
792792

793793
gboolean (*g_main_context_iteration)(GMainContext *context,
794794
gboolean may_block);
795+
GMainContext *(*g_main_context_default)();
796+
gboolean (*g_main_context_is_owner)(GMainContext* context);
795797

796798
void (*g_error_free)(GError *error);
797799

src/java.desktop/unix/native/libawt_xawt/awt/screencast_pipewire.c

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ static GString *activeSessionToken;
4949

5050
struct ScreenSpace screenSpace = {0};
5151
static struct PwLoopData pw = {0};
52+
volatile bool isGtkMainThread = FALSE;
5253

5354
jclass tokenStorageClass = NULL;
5455
jmethodID storeTokenMethodID = NULL;
@@ -132,10 +133,6 @@ static void doCleanup() {
132133
screenSpace.screenCount = 0;
133134
}
134135

135-
if (!sessionClosed) {
136-
fp_pw_deinit();
137-
}
138-
139136
gtk->g_string_set_size(activeSessionToken, 0);
140137
sessionClosed = TRUE;
141138
}
@@ -581,6 +578,13 @@ static gboolean doLoop(GdkRectangle requestedArea) {
581578
if (!pw.loop && !sessionClosed) {
582579
pw.loop = fp_pw_thread_loop_new("AWT Pipewire Thread", NULL);
583580

581+
if (!pw.loop) {
582+
// in case someone called the pw_deinit before
583+
DEBUG_SCREENCAST("pw_init\n", NULL);
584+
fp_pw_init(NULL, NULL);
585+
pw.loop = fp_pw_thread_loop_new("AWT Pipewire Thread", NULL);
586+
}
587+
584588
if (!pw.loop) {
585589
DEBUG_SCREENCAST("!!! Could not create a loop\n", NULL);
586590
doCleanup();
@@ -712,7 +716,6 @@ static gboolean loadSymbols() {
712716
LOAD_SYMBOL(fp_pw_stream_disconnect, "pw_stream_disconnect");
713717
LOAD_SYMBOL(fp_pw_stream_destroy, "pw_stream_destroy");
714718
LOAD_SYMBOL(fp_pw_init, "pw_init");
715-
LOAD_SYMBOL(fp_pw_deinit, "pw_deinit");
716719
LOAD_SYMBOL(fp_pw_context_connect_fd, "pw_context_connect_fd");
717720
LOAD_SYMBOL(fp_pw_core_disconnect, "pw_core_disconnect");
718721
LOAD_SYMBOL(fp_pw_context_new, "pw_context_new");
@@ -946,9 +949,10 @@ JNIEXPORT jint JNICALL Java_sun_awt_screencast_ScreencastHelper_getRGBPixelsImpl
946949
? (*env)->GetStringUTFChars(env, jtoken, NULL)
947950
: NULL;
948951

952+
isGtkMainThread = gtk->g_main_context_is_owner(gtk->g_main_context_default());
949953
DEBUG_SCREENCAST(
950-
"taking screenshot at \n\tx: %5i y %5i w %5i h %5i with token |%s|\n",
951-
jx, jy, jwidth, jheight, token
954+
"taking screenshot at \n\tx: %5i y %5i w %5i h %5i\n\twith token |%s| isGtkMainThread %d\n",
955+
jx, jy, jwidth, jheight, token, isGtkMainThread
952956
);
953957

954958
int attemptResult = makeScreencast(

src/java.desktop/unix/native/libawt_xawt/awt/screencast_portal.c

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include "screencast_pipewire.h"
3333
#include "screencast_portal.h"
3434

35+
extern volatile bool isGtkMainThread;
3536

3637
extern struct ScreenSpace screenSpace;
3738

@@ -67,6 +68,27 @@ gboolean validateToken(const gchar *token) {
6768
return isValid;
6869
}
6970

71+
void waitForCallback(struct DBusCallbackHelper *helper) {
72+
if (!helper) {
73+
return;
74+
}
75+
76+
if (isGtkMainThread) {
77+
gtk->gtk_main();
78+
} else {
79+
while (!helper->isDone) {
80+
// do not block if there is a GTK loop running
81+
gtk->g_main_context_iteration(NULL, gtk->gtk_main_level() == 0);
82+
}
83+
}
84+
}
85+
86+
void callbackEnd() {
87+
if (isGtkMainThread) {
88+
gtk->gtk_main_quit();
89+
}
90+
}
91+
7092
/**
7193
* @return TRUE on success
7294
*/
@@ -362,6 +384,7 @@ static void callbackScreenCastCreateSession(
362384
}
363385

364386
helper->isDone = TRUE;
387+
callbackEnd();
365388
}
366389

367390
gboolean portalScreenCastCreateSession() {
@@ -426,9 +449,7 @@ gboolean portalScreenCastCreateSession() {
426449
err->message);
427450
ERR_HANDLE(err);
428451
} else {
429-
while (!helper.isDone) {
430-
gtk->g_main_context_iteration(NULL, TRUE);
431-
}
452+
waitForCallback(&helper);
432453
}
433454

434455
unregisterScreenCastCallback(&helper);
@@ -472,6 +493,8 @@ static void callbackScreenCastSelectSources(
472493
if (result) {
473494
gtk->g_variant_unref(result);
474495
}
496+
497+
callbackEnd();
475498
}
476499

477500
gboolean portalScreenCastSelectSources(const gchar *token) {
@@ -552,9 +575,7 @@ gboolean portalScreenCastSelectSources(const gchar *token) {
552575
DEBUG_SCREENCAST("Failed to call SelectSources: %s\n", err->message);
553576
ERR_HANDLE(err);
554577
} else {
555-
while (!helper.isDone) {
556-
gtk->g_main_context_iteration(NULL, TRUE);
557-
}
578+
waitForCallback(&helper);
558579
}
559580

560581
unregisterScreenCastCallback(&helper);
@@ -640,6 +661,8 @@ static void callbackScreenCastStart(
640661
if (streams) {
641662
gtk->g_variant_unref(streams);
642663
}
664+
665+
callbackEnd();
643666
}
644667

645668
ScreenCastResult portalScreenCastStart(const gchar *token) {
@@ -693,9 +716,7 @@ ScreenCastResult portalScreenCastStart(const gchar *token) {
693716
DEBUG_SCREENCAST("Failed to start session: %s\n", err->message);
694717
ERR_HANDLE(err);
695718
} else {
696-
while (!helper.isDone) {
697-
gtk->g_main_context_iteration(NULL, TRUE);
698-
}
719+
waitForCallback(&helper);
699720
}
700721

701722
unregisterScreenCastCallback(&helper);

0 commit comments

Comments
 (0)