summaryrefslogtreecommitdiffstats
path: root/sway/render.c
diff options
context:
space:
mode:
Diffstat (limited to 'sway/render.c')
-rw-r--r--sway/render.c111
1 files changed, 87 insertions, 24 deletions
diff --git a/sway/render.c b/sway/render.c
index a5ba2f4c..9388c1d0 100644
--- a/sway/render.c
+++ b/sway/render.c
@@ -2,6 +2,8 @@
2#include <wlc/wlc-render.h> 2#include <wlc/wlc-render.h>
3#include <cairo/cairo.h> 3#include <cairo/cairo.h>
4#include <stdlib.h> 4#include <stdlib.h>
5#include <stdio.h>
6#include "container.h"
5 7
6void cairo_set_source_u32(cairo_t *cairo, uint32_t color) { 8void cairo_set_source_u32(cairo_t *cairo, uint32_t color) {
7 cairo_set_source_rgba(cairo, 9 cairo_set_source_rgba(cairo,
@@ -11,40 +13,101 @@ void cairo_set_source_u32(cairo_t *cairo, uint32_t color) {
11 (color >> (0*8) & 0xFF) / 255.0); 13 (color >> (0*8) & 0xFF) / 255.0);
12} 14}
13 15
14cairo_t *create_cairo_context(int width, int height, int channels, 16cairo_t *create_border_buffer(swayc_t *view, struct wlc_geometry geo,
15 cairo_surface_t **surf, unsigned char **buf) { 17 cairo_surface_t **surface) {
18 const int channels = 4;
16 cairo_t *cr; 19 cairo_t *cr;
17 *buf = calloc(channels * width * height, sizeof(unsigned char)); 20 view->border_geometry = geo;
18 if (!*buf) { 21 view->border = calloc(channels * geo.size.w * geo.size.h,
22 sizeof(unsigned char));
23 if (!view->border) {
24 sway_log(L_DEBUG, "Unable to allocate buffer");
19 return NULL; 25 return NULL;
20 } 26 }
21 *surf = cairo_image_surface_create_for_data(*buf, CAIRO_FORMAT_ARGB32, 27 *surface = cairo_image_surface_create_for_data(view->border,
22 width, height, channels * width); 28 CAIRO_FORMAT_ARGB32, geo.size.w, geo.size.h, channels * geo.size.w);
23 if (cairo_surface_status(*surf) != CAIRO_STATUS_SUCCESS) { 29 if (cairo_surface_status(*surface) != CAIRO_STATUS_SUCCESS) {
24 free(*buf); 30 free(view->border);
31 view->border = NULL;
32 sway_log(L_DEBUG, "Unable to allocate surface");
25 return NULL; 33 return NULL;
26 } 34 }
27 cr = cairo_create(*surf); 35 cr = cairo_create(*surface);
28 if (cairo_status(cr) != CAIRO_STATUS_SUCCESS) { 36 if (cairo_status(cr) != CAIRO_STATUS_SUCCESS) {
29 free(*buf); 37 cairo_surface_destroy(*surface);
38 free(view->border);
39 view->border = NULL;
40 sway_log(L_DEBUG, "Unable to create cairo context");
30 return NULL; 41 return NULL;
31 } 42 }
32 return cr; 43 return cr;
33} 44}
34 45
46void update_view_border(swayc_t *view) {
47 struct wlc_geometry geo;
48 wlc_view_get_visible_geometry(view->handle, &geo);
49 cairo_t *cr = NULL;
50 cairo_surface_t *surface = NULL;
51
52 if (view->border) {
53 free(view->border);
54 view->border = NULL;
55 }
56
57 switch (view->border_type) {
58 case B_NONE:
59 view->border_geometry = geo;
60 break;
61 case B_PIXEL:
62 geo.origin.x -= view->border_thickness;
63 geo.origin.y -= view->border_thickness;
64 geo.size.w += view->border_thickness * 2;
65 geo.size.h += view->border_thickness * 2;
66 if (geo.size.w <= 0 || geo.size.h <= 0) {
67 view->border = NULL;
68 break;
69 }
70 cr = create_border_buffer(view, geo, &surface);
71 if (!cr) {
72 break;
73 }
74 cairo_set_source_u32(cr, 0x0000FFFF);
75 cairo_paint(cr);
76 break;
77 case B_NORMAL:
78 // TODO
79 break;
80 }
81 if (surface) {
82 cairo_surface_flush(surface);
83 cairo_surface_destroy(surface);
84 }
85 if (cr) {
86 cairo_destroy(cr);
87 sway_log(L_DEBUG, "Created border for %p (%dx%d+%d,%d)", view,
88 geo.size.w, geo.size.h, geo.origin.x, geo.origin.y);
89 }
90 view->border_geometry = geo;
91}
92
35void render_view_borders(wlc_handle view) { 93void render_view_borders(wlc_handle view) {
36 const int bw = 2; 94 swayc_t *c = swayc_by_handle(view);
37 unsigned char *surf_data; 95 if (!c || c->border_type == B_NONE) {
38 cairo_surface_t *surf; 96 return;
39 struct wlc_geometry geo = *wlc_view_get_geometry(view); 97 }
40 cairo_t *cr = create_cairo_context(geo.size.w + bw * 2, geo.size.h + bw * 2, 4, &surf, &surf_data); 98 struct wlc_geometry geo;
41 cairo_set_source_u32(cr, 0x0000FFFF); 99 wlc_view_get_visible_geometry(view, &geo);
42 cairo_paint(cr); 100 if (geo.size.w != c->presumed_geometry.size.w
43 geo.origin.x -= bw; 101 || geo.size.h != c->presumed_geometry.size.h
44 geo.origin.y -= bw; 102 || geo.origin.x != c->presumed_geometry.origin.x
45 geo.size.w += bw * 2; 103 || geo.origin.y != c->presumed_geometry.origin.y) {
46 geo.size.h += bw * 2; 104 update_view_border(c);
47 wlc_pixels_write(WLC_RGBA8888, &geo, surf_data); 105 c->presumed_geometry = geo;
48 cairo_destroy(cr); 106 }
49 free(surf_data); 107 if (c->border) {
108 geo = c->border_geometry;
109 sway_log(L_DEBUG, "Rendering border for %p (%dx%d+%d,%d)", c,
110 geo.size.w, geo.size.h, geo.origin.x, geo.origin.y);
111 wlc_pixels_write(WLC_RGBA8888, &c->border_geometry, c->border);
112 }
50} 113}