1 /* 2 * This an unstable interface of wlroots. No guarantees are made regarding the 3 * future consistency of this API. 4 */ 5 #ifndef WLR_USE_UNSTABLE 6 #error "Add -DWLR_USE_UNSTABLE to enable unstable wlroots features" 7 #endif 8 9 #ifndef WLR_TYPES_WLR_SURFACE_H 10 #define WLR_TYPES_WLR_SURFACE_H 11 12 #include <pixman.h> 13 #include <stdbool.h> 14 #include <stdint.h> 15 #include <time.h> 16 #include <wayland-server-core.h> 17 #include <wlr/types/wlr_box.h> 18 #include <wlr/types/wlr_output.h> 19 20 enum wlr_surface_state_field { 21 WLR_SURFACE_STATE_BUFFER = 1 << 0, 22 WLR_SURFACE_STATE_SURFACE_DAMAGE = 1 << 1, 23 WLR_SURFACE_STATE_BUFFER_DAMAGE = 1 << 2, 24 WLR_SURFACE_STATE_OPAQUE_REGION = 1 << 3, 25 WLR_SURFACE_STATE_INPUT_REGION = 1 << 4, 26 WLR_SURFACE_STATE_TRANSFORM = 1 << 5, 27 WLR_SURFACE_STATE_SCALE = 1 << 6, 28 WLR_SURFACE_STATE_FRAME_CALLBACK_LIST = 1 << 7, 29 WLR_SURFACE_STATE_VIEWPORT = 1 << 8, 30 }; 31 32 struct wlr_surface_state { 33 uint32_t committed; // enum wlr_surface_state_field 34 35 struct wl_resource *buffer_resource; 36 int32_t dx, dy; // relative to previous position 37 pixman_region32_t surface_damage, buffer_damage; // clipped to bounds 38 pixman_region32_t opaque, input; 39 enum wl_output_transform transform; 40 int32_t scale; 41 struct wl_list frame_callback_list; // wl_resource 42 43 int width, height; // in surface-local coordinates 44 int buffer_width, buffer_height; 45 46 /** 47 * The viewport is applied after the surface transform and scale. 48 * 49 * If has_src is true, the surface content is cropped to the provided 50 * rectangle. If has_dst is true, the surface content is scaled to the 51 * provided rectangle. 52 */ 53 struct { 54 bool has_src, has_dst; 55 // In coordinates after scale/transform are applied, but before the 56 // destination rectangle is applied 57 struct wlr_fbox src; 58 int dst_width, dst_height; // in surface-local coordinates 59 } viewport; 60 61 struct wl_listener buffer_destroy; 62 }; 63 64 struct wlr_surface_role { 65 const char *name; 66 void (*commit)(struct wlr_surface *surface); 67 void (*precommit)(struct wlr_surface *surface); 68 }; 69 70 struct wlr_surface { 71 struct wl_resource *resource; 72 struct wlr_renderer *renderer; 73 /** 74 * The surface's buffer, if any. A surface has an attached buffer when it 75 * commits with a non-null buffer in its pending state. A surface will not 76 * have a buffer if it has never committed one, has committed a null buffer, 77 * or something went wrong with uploading the buffer. 78 */ 79 struct wlr_client_buffer *buffer; 80 /** 81 * The buffer position, in surface-local units. 82 */ 83 int sx, sy; 84 /** 85 * The last commit's buffer damage, in buffer-local coordinates. This 86 * contains both the damage accumulated by the client via 87 * `wlr_surface_state.surface_damage` and `wlr_surface_state.buffer_damage`. 88 * If the buffer has been resized, the whole buffer is damaged. 89 * 90 * This region needs to be scaled and transformed into output coordinates, 91 * just like the buffer's texture. In addition, if the buffer has shrunk the 92 * old size needs to be damaged and if the buffer has moved the old and new 93 * positions need to be damaged. 94 */ 95 pixman_region32_t buffer_damage; 96 /** 97 * The current opaque region, in surface-local coordinates. It is clipped to 98 * the surface bounds. If the surface's buffer is using a fully opaque 99 * format, this is set to the whole surface. 100 */ 101 pixman_region32_t opaque_region; 102 /** 103 * The current input region, in surface-local coordinates. It is clipped to 104 * the surface bounds. 105 */ 106 pixman_region32_t input_region; 107 /** 108 * `current` contains the current, committed surface state. `pending` 109 * accumulates state changes from the client between commits and shouldn't 110 * be accessed by the compositor directly. `previous` contains the state of 111 * the previous commit. 112 */ 113 struct wlr_surface_state current, pending, previous; 114 115 const struct wlr_surface_role *role; // the lifetime-bound role or NULL 116 void *role_data; // role-specific data 117 118 struct { 119 struct wl_signal commit; 120 struct wl_signal new_subsurface; 121 struct wl_signal destroy; 122 } events; 123 124 struct wl_list subsurfaces; // wlr_subsurface::parent_link 125 126 // wlr_subsurface::parent_pending_link 127 struct wl_list subsurface_pending_list; 128 129 struct wl_listener renderer_destroy; 130 131 void *data; 132 }; 133 134 struct wlr_subsurface_state { 135 int32_t x, y; 136 }; 137 138 struct wlr_subsurface { 139 struct wl_resource *resource; 140 struct wlr_surface *surface; 141 struct wlr_surface *parent; 142 143 struct wlr_subsurface_state current, pending; 144 145 struct wlr_surface_state cached; 146 bool has_cache; 147 148 bool synchronized; 149 bool reordered; 150 bool mapped; 151 152 struct wl_list parent_link; 153 struct wl_list parent_pending_link; 154 155 struct wl_listener surface_destroy; 156 struct wl_listener parent_destroy; 157 158 struct { 159 struct wl_signal destroy; 160 struct wl_signal map; 161 struct wl_signal unmap; 162 } events; 163 164 void *data; 165 }; 166 167 typedef void (*wlr_surface_iterator_func_t)(struct wlr_surface *surface, 168 int sx, int sy, void *data); 169 170 struct wlr_renderer; 171 172 /** 173 * Create a new surface resource with the provided new ID. If `resource_list` 174 * is non-NULL, adds the surface's resource to the list. 175 */ 176 struct wlr_surface *wlr_surface_create(struct wl_client *client, 177 uint32_t version, uint32_t id, struct wlr_renderer *renderer, 178 struct wl_list *resource_list); 179 180 /** 181 * Set the lifetime role for this surface. Returns 0 on success or -1 if the 182 * role cannot be set. 183 */ 184 bool wlr_surface_set_role(struct wlr_surface *surface, 185 const struct wlr_surface_role *role, void *role_data, 186 struct wl_resource *error_resource, uint32_t error_code); 187 188 /** 189 * Whether or not this surface currently has an attached buffer. A surface has 190 * an attached buffer when it commits with a non-null buffer in its pending 191 * state. A surface will not have a buffer if it has never committed one, has 192 * committed a null buffer, or something went wrong with uploading the buffer. 193 */ 194 bool wlr_surface_has_buffer(struct wlr_surface *surface); 195 196 /** 197 * Get the texture of the buffer currently attached to this surface. Returns 198 * NULL if no buffer is currently attached or if something went wrong with 199 * uploading the buffer. 200 */ 201 struct wlr_texture *wlr_surface_get_texture(struct wlr_surface *surface); 202 203 /** 204 * Create a new subsurface resource with the provided new ID. If `resource_list` 205 * is non-NULL, adds the subsurface's resource to the list. 206 */ 207 struct wlr_subsurface *wlr_subsurface_create(struct wlr_surface *surface, 208 struct wlr_surface *parent, uint32_t version, uint32_t id, 209 struct wl_list *resource_list); 210 211 /** 212 * Get the root of the subsurface tree for this surface. 213 */ 214 struct wlr_surface *wlr_surface_get_root_surface(struct wlr_surface *surface); 215 216 /** 217 * Check if the surface accepts input events at the given surface-local 218 * coordinates. Does not check the surface's subsurfaces. 219 */ 220 bool wlr_surface_point_accepts_input(struct wlr_surface *surface, 221 double sx, double sy); 222 223 /** 224 * Find a surface in this surface's tree that accepts input events at the given 225 * surface-local coordinates. Returns the surface and coordinates in the leaf 226 * surface coordinate system or NULL if no surface is found at that location. 227 */ 228 struct wlr_surface *wlr_surface_surface_at(struct wlr_surface *surface, 229 double sx, double sy, double *sub_x, double *sub_y); 230 231 void wlr_surface_send_enter(struct wlr_surface *surface, 232 struct wlr_output *output); 233 234 void wlr_surface_send_leave(struct wlr_surface *surface, 235 struct wlr_output *output); 236 237 void wlr_surface_send_frame_done(struct wlr_surface *surface, 238 const struct timespec *when); 239 240 /** 241 * Get the bounding box that contains the surface and all subsurfaces in 242 * surface coordinates. 243 * X and y may be negative, if there are subsurfaces with negative position. 244 */ 245 void wlr_surface_get_extends(struct wlr_surface *surface, struct wlr_box *box); 246 247 struct wlr_surface *wlr_surface_from_resource(struct wl_resource *resource); 248 249 /** 250 * Call `iterator` on each surface in the surface tree, with the surface's 251 * position relative to the root surface. The function is called from root to 252 * leaves (in rendering order). 253 */ 254 void wlr_surface_for_each_surface(struct wlr_surface *surface, 255 wlr_surface_iterator_func_t iterator, void *user_data); 256 257 /** 258 * Get the effective damage to the surface in terms of surface local 259 * coordinates. This includes damage induced by resizing and moving the 260 * surface. The damage is not expected to be bounded by the surface itself. 261 */ 262 void wlr_surface_get_effective_damage(struct wlr_surface *surface, 263 pixman_region32_t *damage); 264 265 /** 266 * Get the source rectangle describing the region of the buffer that needs to 267 * be sampled to render this surface's current state. The box is in 268 * buffer-local coordinates. 269 * 270 * If the viewport's source rectangle is unset, the position is zero and the 271 * size is the buffer's. 272 */ 273 void wlr_surface_get_buffer_source_box(struct wlr_surface *surface, 274 struct wlr_fbox *box); 275 276 #endif 277