aboutsummaryrefslogtreecommitdiffstats
path: root/src/x11_cairo.c
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2023-02-10 12:33:23 -0500
committerDavid Robillard <d@drobilla.net>2023-02-10 12:34:16 -0500
commit22988036924c706860d6155e5f728ff927ecca5b (patch)
treee1067fc19b9faaeaeb5ff18cc1f236561e92d266 /src/x11_cairo.c
parent929509da52da29ce4d211ad488e580761885bfb0 (diff)
downloadpugl-22988036924c706860d6155e5f728ff927ecca5b.tar.gz
pugl-22988036924c706860d6155e5f728ff927ecca5b.tar.bz2
pugl-22988036924c706860d6155e5f728ff927ecca5b.zip
Fix partial exposure in X11 Cairo backend
Diffstat (limited to 'src/x11_cairo.c')
-rw-r--r--src/x11_cairo.c45
1 files changed, 35 insertions, 10 deletions
diff --git a/src/x11_cairo.c b/src/x11_cairo.c
index be9ae09..eabf46f 100644
--- a/src/x11_cairo.c
+++ b/src/x11_cairo.c
@@ -1,6 +1,7 @@
-// Copyright 2012-2022 David Robillard <d@drobilla.net>
+// Copyright 2012-2023 David Robillard <d@drobilla.net>
// SPDX-License-Identifier: ISC
+#include "macros.h"
#include "types.h"
#include "x11.h"
@@ -11,7 +12,6 @@
#include <cairo-xlib.h>
#include <cairo.h>
-#include <math.h>
#include <stdlib.h>
typedef struct {
@@ -20,6 +20,24 @@ typedef struct {
cairo_t* cr;
} PuglX11CairoSurface;
+static PuglViewSize
+puglX11CairoGetViewSize(const PuglView* const view)
+{
+ PuglViewSize size = {0U, 0U};
+
+ if (view->lastConfigure.type == PUGL_CONFIGURE) {
+ // Use the size of the last configured frame
+ size.width = view->lastConfigure.width;
+ size.height = view->lastConfigure.height;
+ } else {
+ // Use the default size
+ size.width = view->sizeHints[PUGL_DEFAULT_SIZE].width;
+ size.height = view->sizeHints[PUGL_DEFAULT_SIZE].height;
+ }
+
+ return size;
+}
+
static void
puglX11CairoClose(PuglView* view)
{
@@ -32,14 +50,10 @@ puglX11CairoClose(PuglView* view)
}
static PuglStatus
-puglX11CairoOpen(PuglView* view,
- const double expose_width,
- const double expose_height)
+puglX11CairoOpen(PuglView* view, const PuglSpan width, const PuglSpan height)
{
PuglInternals* const impl = view->impl;
PuglX11CairoSurface* const surface = (PuglX11CairoSurface*)impl->surface;
- const int width = (int)ceil(expose_width);
- const int height = (int)ceil(expose_height);
surface->back = cairo_xlib_surface_create(
view->world->impl->display, impl->win, impl->vi->visual, width, height);
@@ -83,9 +97,20 @@ puglX11CairoEnter(PuglView* view, const PuglExposeEvent* expose)
PuglX11CairoSurface* const surface = (PuglX11CairoSurface*)impl->surface;
PuglStatus st = PUGL_SUCCESS;
- if (expose && !(st = puglX11CairoOpen(view, expose->width, expose->height))) {
- surface->cr = cairo_create(surface->front);
- st = cairo_status(surface->cr) ? PUGL_CREATE_CONTEXT_FAILED : PUGL_SUCCESS;
+ if (expose) {
+ const PuglViewSize viewSize = puglX11CairoGetViewSize(view);
+ const PuglSpan right = expose->x + expose->width;
+ const PuglSpan bottom = expose->y + expose->height;
+ const PuglSpan surfaceWidth = MAX(right, viewSize.width);
+ const PuglSpan surfaceHeight = MAX(bottom, viewSize.height);
+ if (!(st = puglX11CairoOpen(view, surfaceWidth, surfaceHeight))) {
+ surface->cr = cairo_create(surface->front);
+ if (cairo_status(surface->cr)) {
+ cairo_destroy(surface->cr);
+ surface->cr = NULL;
+ st = PUGL_CREATE_CONTEXT_FAILED;
+ }
+ }
}
return st;