summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/display.c44
-rw-r--r--src/options.c2
-rw-r--r--src/options.h1
-rw-r--r--src/scan.c23
-rw-r--r--src/xdg/x11spice/x11spice.conf11
5 files changed, 61 insertions, 20 deletions
diff --git a/src/display.c b/src/display.c
index f78c54b..931a314 100644
--- a/src/display.c
+++ b/src/display.c
@@ -408,23 +408,29 @@ int display_open(display_t *d, session_t *session)
return X11SPICE_ERR_NODAMAGE;
}
- dcookie = xcb_damage_query_version(d->c, XCB_DAMAGE_MAJOR_VERSION, XCB_DAMAGE_MINOR_VERSION);
- damage_version = xcb_damage_query_version_reply(d->c, dcookie, &error);
- if (error) {
- fprintf(stderr, "Error: Could not query damage; type %d; code %d; major %d; minor %d\n",
- error->response_type, error->error_code, error->major_code, error->minor_code);
- return X11SPICE_ERR_NODAMAGE;
- }
- free(damage_version);
-
- d->damage = xcb_generate_id(d->c);
- cookie =
- xcb_damage_create_checked(d->c, d->damage, d->root, XCB_DAMAGE_REPORT_LEVEL_RAW_RECTANGLES);
- error = xcb_request_check(d->c, cookie);
- if (error) {
- fprintf(stderr, "Error: Could not create damage; type %d; code %d; major %d; minor %d\n",
- error->response_type, error->error_code, error->major_code, error->minor_code);
- return X11SPICE_ERR_NODAMAGE;
+ if (session->options.full_screen_fps == 0) {
+ dcookie =
+ xcb_damage_query_version(d->c, XCB_DAMAGE_MAJOR_VERSION, XCB_DAMAGE_MINOR_VERSION);
+ damage_version = xcb_damage_query_version_reply(d->c, dcookie, &error);
+ if (error) {
+ fprintf(stderr,
+ "Error: Could not query damage; type %d; code %d; major %d; minor %d\n",
+ error->response_type, error->error_code, error->major_code, error->minor_code);
+ return X11SPICE_ERR_NODAMAGE;
+ }
+ free(damage_version);
+
+ d->damage = xcb_generate_id(d->c);
+ cookie =
+ xcb_damage_create_checked(d->c, d->damage, d->root,
+ XCB_DAMAGE_REPORT_LEVEL_RAW_RECTANGLES);
+ error = xcb_request_check(d->c, cookie);
+ if (error) {
+ fprintf(stderr,
+ "Error: Could not create damage; type %d; code %d; major %d; minor %d\n",
+ error->response_type, error->error_code, error->major_code, error->minor_code);
+ return X11SPICE_ERR_NODAMAGE;
+ }
}
d->shm_ext = xcb_get_extension_data(d->c, &xcb_shm_id);
@@ -741,7 +747,9 @@ void display_close(display_t *d)
{
shm_cache_destroy(d);
g_mutex_clear(&d->shm_cache_mutex);
- xcb_damage_destroy(d->c, d->damage);
+ if (d->session->options.full_screen_fps == 0) {
+ xcb_damage_destroy(d->c, d->damage);
+ }
display_destroy_screen_images(d);
xcb_disconnect(d->c);
}
diff --git a/src/options.c b/src/options.c
index ef817bb..90442f8 100644
--- a/src/options.c
+++ b/src/options.c
@@ -395,6 +395,8 @@ static void options_from_config(options_t *options)
options->trust_damage = NEVER_TRUST;
g_free(trust_damage);
+ options->full_screen_fps = int_option(userkey, systemkey, "spice", "full-screen-fps");
+
#if defined(HAVE_LIBAUDIT_H)
/* Pick an arbitrary default in the user range. CodeWeavers was founed in 1996, so 1196 it is... */
if (options->audit_message_type == 0)
diff --git a/src/options.h b/src/options.h
index 19e22e4..343da2c 100644
--- a/src/options.h
+++ b/src/options.h
@@ -65,6 +65,7 @@ typedef struct {
int audit;
int audit_message_type;
damage_trust_t trust_damage;
+ int full_screen_fps;
/* file names of config files */
char *user_config_file;
diff --git a/src/scan.c b/src/scan.c
index 7b6d8f5..69a8b04 100644
--- a/src/scan.c
+++ b/src/scan.c
@@ -113,6 +113,9 @@ static QXLDrawable *shm_image_to_drawable(spice_t *s, shm_image_t *shmi, int x,
static guint64 get_timeout(scanner_t *scanner)
{
+ if (scanner->session->options.full_screen_fps > 0) {
+ return G_USEC_PER_SEC / scanner->session->options.full_screen_fps;
+ }
return G_USEC_PER_SEC / scanner->target_fps / NUM_SCANLINES;
}
@@ -384,6 +387,18 @@ static gpointer g_async_queue_timeout_pop(GAsyncQueue *queue, guint64 t)
}
#endif
+static void scanner_push_screen(scanner_t *scanner)
+{
+ scan_report_t whole_screen = {
+ .type = SCANLINE_SCAN_REPORT,
+ .x = 0,.y = 0,
+ .w = scanner->session->display.width,
+ .h = scanner->session->display.height
+ };
+
+ handle_scan_report(scanner->session, &whole_screen);
+}
+
static void *scanner_run(void *opaque)
{
scanner_t *scanner = (scanner_t *) opaque;
@@ -391,8 +406,12 @@ static void *scanner_run(void *opaque)
scan_report_t *r;
r = (scan_report_t *) g_async_queue_timeout_pop(scanner->queue, get_timeout(scanner));
if (!r) {
- scan_update_fps(scanner, -1);
- scanner_periodic(scanner);
+ if (scanner->session->options.full_screen_fps > 0) {
+ scanner_push_screen(scanner);
+ } else {
+ scan_update_fps(scanner, -1);
+ scanner_periodic(scanner);
+ }
continue;
}
diff --git a/src/xdg/x11spice/x11spice.conf b/src/xdg/x11spice/x11spice.conf
index 6b1ee8d..8bb2996 100644
--- a/src/xdg/x11spice/x11spice.conf
+++ b/src/xdg/x11spice/x11spice.conf
@@ -101,6 +101,17 @@
#trust-damage=auto
#-----------------------------------------------------------------------------
+# full-screen-fps
+# There are use cases where the most effective thing we can
+# do is simply transmit the whole screen periodically, and
+# trust the spice server and the video codecs to optimize.
+# 0 disables; otherwise the number indicates how often to
+# transmit the full screen
+# Default 0.
+#-----------------------------------------------------------------------------
+#full-screen-fps=0
+
+#-----------------------------------------------------------------------------
# minimize Starts the x11spice gui minimized. Default false.
#-----------------------------------------------------------------------------
#minimize=false