1/* swc: libswc/swc.h
2 *
3 * Copyright (c) 2013 Michael Forney
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 * SOFTWARE.
22 */
23
24#ifndef SWC_H
25#define SWC_H
26
27#include <stdbool.h>
28#include <stdint.h>
29#include <sys/types.h>
30
31#ifdef __cplusplus
32extern "C" {
33#endif
34
35struct libinput_device;
36struct wl_display;
37struct wl_event_loop;
38struct wld_buffer;
39
40/**
41 * Get the current cursor position.
42 *
43 * The returned coordinates are in compositor-global space, in wl_fixed_t
44 * (24.8) fixed-point units, but exposed as raw int32_t to avoid needing
45 * wayland headers.
46 *
47 */
48bool
49swc_cursor_position(int32_t *x, int32_t *y);
50
51/**
52 * Send a pointer button event to the currently focused client.
53 *
54 * This is intended for window managers which intercept button events (for
55 * example for mouse chords) but want normal clicks to still reach clients.
56 */
57void
58swc_pointer_send_button(uint32_t time, uint32_t button, uint32_t state);
59
60/**
61 * Send a pointer axis event to the currently focused client.
62 *
63 * This is intended for window managers which intercept axis events (for
64 * example for mouse chords) but want normal scrolling to still reach clients.
65 *
66 * value120 uses the wl_pointer "120 units" convention.
67 */
68void
69swc_pointer_send_axis(uint32_t time, uint32_t axis, int32_t value120);
70
71/* Cursor control (compositor-internal cursor) */
72enum swc_cursor_kind {
73 SWC_CURSOR_DEFAULT = 0,
74 SWC_CURSOR_BOX = 1,
75 SWC_CURSOR_CROSS = 2,
76 SWC_CURSOR_SIGHT = 3,
77 SWC_CURSOR_UP = 4,
78 SWC_CURSOR_DOWN = 5,
79};
80
81enum swc_cursor_mode {
82 /* Allow clients to set their own cursors (I-beam, resize, etc). */
83 SWC_CURSOR_MODE_CLIENT = 0,
84 /* Force compositor cursor; ignore client wl_pointer.set_cursor. */
85 SWC_CURSOR_MODE_COMPOSITOR = 1,
86};
87
88/**
89 * Override the compositor's internal cursor.
90 *
91 * this is intended for window managers to show mode cursors
92 * (move/resize/select) like the ones in hevel If a client has set its own
93 * cursor surface, swc may ignore the override.
94 */
95void
96swc_set_cursor(enum swc_cursor_kind kind);
97
98/**
99 * Control whether client cursor surfaces are honored.
100 */
101void
102swc_set_cursor_mode(enum swc_cursor_mode mode);
103
104/**
105 * set a custom argb8888 cursor image for a given kind
106 *
107 * `argb8888` is a pointer to `width*height` pixels in ARGB8888 order.
108 * the caller has to keep the pixel memory alive for as long as it may be used
109 */
110void
111swc_set_cursor_image(enum swc_cursor_kind kind, const uint32_t *argb8888,
112 uint32_t width, uint32_t height, int32_t hotspot_x,
113 int32_t hotspot_y);
114
115void
116swc_clear_cursor_image(enum swc_cursor_kind kind);
117
118/**
119 * draw [or update] a simple box overlay
120 *
121 * box is defined by two diagonally opposite corners in compositor-global
122 * coordinates. this draws only the border. Call swc_overlay_clear() to remove
123 * it
124 */
125void
126swc_overlay_set_box(int32_t x1, int32_t y1, int32_t x2, int32_t y2,
127 uint32_t color, uint32_t border_width);
128
129/**
130 * Clear the current overlay, if any.
131 */
132void
133swc_overlay_clear(void);
134
135/**
136 * Set the compositor zoom level.
137 *
138 * 1.0 = normal, >1.0 = zoomed in, <1.0 = zoomed out
139 * Uses software (pixman) scaling.
140 */
141void
142swc_set_zoom(float level);
143
144/**
145 * Get the current zoom level.
146 */
147float
148swc_get_zoom(void);
149
150/* Rectangles {{{ */
151
152struct swc_rectangle {
153 int32_t x, y;
154 uint32_t width, height;
155};
156
157/* }}} */
158
159/* Screens {{{ */
160
161struct swc_screen_handler {
162 /**
163 * Called when the screen is about to be destroyed.
164 *
165 * After this is called, the screen is no longer valid.
166 */
167 void (*destroy)(void *data);
168
169 /**
170 * Called when the total area of the screen has changed.
171 */
172 void (*geometry_changed)(void *data);
173
174 /**
175 * Called when the geometry of the screen available for laying out windows
176 * has changed.
177 *
178 * A window manager should respond by making sure all visible windows are
179 * within this area.
180 */
181 void (*usable_geometry_changed)(void *data);
182
183 /**
184 * Called when the pointer enters the screen.
185 */
186 void (*entered)(void *data);
187};
188
189struct swc_screen {
190 /**
191 * The total area of the screen.
192 */
193 struct swc_rectangle geometry;
194
195 /**
196 * The area of the screen available for placing windows.
197 */
198 struct swc_rectangle usable_geometry;
199};
200
201/**
202 * Set the handler associated with this screen.
203 */
204void
205swc_screen_set_handler(struct swc_screen *screen,
206 const struct swc_screen_handler *handler, void *data);
207
208/* }}} */
209
210/* Windows {{{ */
211
212struct swc_window_handler {
213 /**
214 * Called when the window is about to be destroyed.
215 *
216 * After this is called, the window is no longer valid.
217 */
218 void (*destroy)(void *data);
219
220 /**
221 * Called when the window's title changes.
222 */
223 void (*title_changed)(void *data);
224
225 /**
226 * Called when the window's application identifier changes.
227 */
228 void (*app_id_changed)(void *data);
229
230 /**
231 * Called when the window's parent changes.
232 *
233 * This can occur when the window becomes a transient for another window, or
234 * becomes a toplevel window.
235 */
236 void (*parent_changed)(void *data);
237
238 /**
239 * Called when the pointer enters the window.
240 */
241 void (*entered)(void *data);
242
243 /**
244 * Called when the window wants to initiate an interactive move, but the
245 * window is not in stacked mode.
246 *
247 * The window manager may respond by changing the window's mode, after which
248 * the interactive move will be honored.
249 */
250 void (*move)(void *data);
251
252 /**
253 * Called when the window wants to initiate an interactive resize, but the
254 * window is not in stacked mode.
255 *
256 * The window manager may respond by changing the window's mode, after which
257 * the interactive resize will be honored.
258 */
259 void (*resize)(void *data);
260};
261
262struct swc_window {
263 char *title;
264 char *app_id;
265
266 struct swc_window *parent;
267 uint32_t motion_throttle_ms;
268 uint32_t min_width;
269 uint32_t min_height;
270 uint32_t max_width;
271 uint32_t max_height;
272};
273
274/**
275 * Set the handler associated with this window.
276 */
277void
278swc_window_set_handler(struct swc_window *window,
279 const struct swc_window_handler *handler, void *data);
280
281/**
282 * Request that the specified window close.
283 */
284void
285swc_window_close(struct swc_window *window);
286
287/**
288 * Make the specified window visible.
289 */
290void
291swc_window_show(struct swc_window *window);
292
293/**
294 * Make the specified window hidden.
295 */
296void
297swc_window_hide(struct swc_window *window);
298
299/**
300 * Set the keyboard focus to the specified window.
301 *
302 * If window is NULL, the keyboard will have no focus.
303 */
304void
305swc_window_focus(struct swc_window *window);
306
307/**
308 * Sets the window to stacked mode.
309 *
310 * A window in this mode has its size specified by the client. The window's
311 * viewport will be adjusted to the size of the buffer attached by the
312 * client.
313 *
314 * Use of this mode is required to allow interactive moving and resizing.
315 */
316void
317swc_window_set_stacked(struct swc_window *window);
318
319/**
320 * Sets the window to tiled mode.
321 *
322 * A window in this mode has its size specified by the window manager.
323 * Additionally, swc will configure the window to operate in a tiled or
324 * maximized state in order to prevent the window from drawing shadows.
325 *
326 * It is invalid to interactively move or resize a window in tiled mode.
327 */
328void
329swc_window_set_tiled(struct swc_window *window);
330
331/**
332 * Sets the window to fullscreen mode.
333 */
334void
335swc_window_set_fullscreen(struct swc_window *window, struct swc_screen *screen);
336
337/**
338 * Set the window's position.
339 *
340 * The x and y coordinates refer to the top-left corner of the actual contents
341 * of the window and should be adjusted for the border size.
342 */
343void
344swc_window_set_position(struct swc_window *window, int32_t x, int32_t y);
345
346/**
347 * Set the window's size.
348 *
349 * The width and height refer to the dimension of the actual contents of the
350 * window and should be adjusted for the border size.
351 */
352void
353swc_window_set_size(struct swc_window *window, uint32_t width, uint32_t height);
354
355/**
356 * Set the window's size and position.
357 *
358 * This is a convenience function that is equivalent to calling
359 * swc_window_set_size and then swc_window_set_position.
360 */
361void
362swc_window_set_geometry(struct swc_window *window,
363 const struct swc_rectangle *geometry);
364
365/**
366 * Get the window's current geometry in compositor-global coordinates.
367 */
368bool
369swc_window_get_geometry(const struct swc_window *window,
370 struct swc_rectangle *geometry);
371
372/**
373 * Get the pid of the client that owns this window
374 *
375 * returns pid, or 0 if unavailable
376 */
377pid_t
378swc_window_get_pid(struct swc_window *window);
379
380/**
381 * Set the window's border color and width.
382 *
383 * NOTE: The window's geometry remains unchanged, and should be updated if a
384 * fixed top-left corner of the border is desired.
385 *
386 * info from dalem: unsure how much double borders break!
387 */
388void
389swc_window_set_border(struct swc_window *window, uint32_t inner_border_color,
390 uint32_t inner_border_width, uint32_t outer_border_color,
391 uint32_t outer_border_width);
392
393/*window decor things*/
394
395/**
396 * Select which decor edge a text slot is rendered on.
397 */
398enum swc_decor_edge {
399 SWC_DECOR_EDGE_TOP,
400 SWC_DECOR_EDGE_RIGHT,
401 SWC_DECOR_EDGE_BOTTOM,
402 SWC_DECOR_EDGE_LEFT,
403};
404
405/**
406 * Choose text alignment within the selected decor edge.
407 *
408 * for top and bottom edges, alignment is horizontal
409 * for left and right edges, alignment is vertical
410 */
411enum swc_decor_align {
412 SWC_DECOR_ALIGN_START,
413 SWC_DECOR_ALIGN_CENTER,
414 SWC_DECOR_ALIGN_END,
415};
416
417/**
418 * Describe a window decor text slot.
419 *
420 * if enabled is false, no text is drawn.
421 *
422 * the wm supplies some string to be rendered in this decor slot. swc
423 * copies the string when swc_window_set_decor() is called, so caller doesn't
424 * need to keep it after the call returns.
425 *
426 * for top and bottom edges, text is drawn horizontally
427 * for left and right edges, text is drawn as stacked glyphs, one glyph
428 * per row.
429 *
430 * the font field accepts some fontconfig pattern such as "sans-serif:size=10".
431 * if font is NULL, a default font is used.
432 */
433struct swc_decor_text {
434 bool enabled;
435 enum swc_decor_edge edge;
436 enum swc_decor_align align;
437 const char *string;
438 uint32_t color;
439 uint32_t padding;
440 int32_t offset_x, offset_y;
441 const char *font;
442};
443
444/**
445 * Describes one wm-supplied decor pixel block.
446 *
447 * swc copies the pixel data when swc_window_set_decor() is called, so caller
448 * doesn't need to keep it after the call returns.
449 *
450 * Pixel data is expected to be ARGB8888 with the provided stride.
451 */
452struct swc_decor_part {
453 uint32_t width, height;
454 uint32_t stride;
455 const void *data;
456};
457
458/**
459 * Describes optional pixel blocks for the outer frame of a decor.
460 *
461 * corner parts are drawn once at their matching corner
462 * edge parts are tiled to fill the remaining edge area between corners.
463 */
464struct swc_decor_parts {
465 struct swc_decor_part top_left;
466 struct swc_decor_part top;
467 struct swc_decor_part top_right;
468 struct swc_decor_part left;
469 struct swc_decor_part right;
470 struct swc_decor_part bottom_left;
471 struct swc_decor_part bottom;
472 struct swc_decor_part bottom_right;
473};
474
475/**
476 * Describe decor around a window's edges.
477 *
478 * The edge sizes extend outward from the window content geometry.
479 * if you put 0 it won't be visible.
480 *
481 * The title field controls an optional text slot rendered on one edge.
482 */
483struct swc_decor {
484 uint32_t color;
485 uint32_t top, right, bottom, left;
486 const struct swc_decor_parts *parts;
487 struct swc_decor_text title;
488};
489
490/**
491 * Set window decor around the window.
492 *
493 * the dimensions are independent for each edge and extend outward from the
494 * window content geometry.
495 *
496 * swc copies any decor text string needed by the configuration.
497 *
498 * passing NULL disables window decor.
499 */
500void
501swc_window_set_decor(struct swc_window *window, const struct swc_decor *decor);
502
503/**
504 * Begin an interactive move of the specified window.
505 */
506void
507swc_window_begin_move(struct swc_window *window);
508
509/**
510 * End an interactive move of the specified window.
511 */
512void
513swc_window_end_move(struct swc_window *window);
514
515enum {
516 SWC_WINDOW_EDGE_AUTO = 0,
517 SWC_WINDOW_EDGE_TOP = (1 << 0),
518 SWC_WINDOW_EDGE_BOTTOM = (1 << 1),
519 SWC_WINDOW_EDGE_LEFT = (1 << 2),
520 SWC_WINDOW_EDGE_RIGHT = (1 << 3)
521};
522
523/**
524 * Begin an interactive resize of the specified window.
525 */
526void
527swc_window_begin_resize(struct swc_window *window, uint32_t edges);
528
529/**
530 * End an interactive resize of the specified window.
531 */
532void
533swc_window_end_resize(struct swc_window *window);
534
535/**
536 * returns the topmost window at any given compositor global coordinates
537 *
538 * returns null if there is no window at that point
539 */
540struct swc_window *
541swc_window_at(int32_t x, int32_t y);
542
543/**
544 * move a window in the stacking order by one step
545 *
546 * direction < 0 moves the window towards the front (higher)
547 * direction > 0 moves the window towards the back (lower)
548 */
549void
550swc_window_stack(struct swc_window *window, int32_t direction);
551
552/* }}} */
553
554/* Bindings {{{ */
555
556enum {
557 SWC_MOD_CTRL = 1 << 0,
558 SWC_MOD_ALT = 1 << 1,
559 SWC_MOD_LOGO = 1 << 2,
560 SWC_MOD_SHIFT = 1 << 3,
561 SWC_MOD_ANY = ~0
562};
563
564enum swc_binding_type {
565 SWC_BINDING_KEY,
566 SWC_BINDING_BUTTON,
567};
568
569typedef void (*swc_binding_handler)(void *data, uint32_t time, uint32_t value,
570 uint32_t state);
571typedef void (*swc_axis_binding_handler)(void *data, uint32_t time,
572 uint32_t axis, int32_t value120);
573
574/**
575 * Register a new input binding.
576 *
577 * Returns 0 on success, negative error code otherwise.
578 */
579int
580swc_add_binding(enum swc_binding_type type, uint32_t modifiers, uint32_t value,
581 swc_binding_handler handler, void *data);
582
583/**
584 * Unregister a registered input binding.
585 *
586 */
587void
588swc_remove_binding(enum swc_binding_type type, uint32_t modifiers,
589 uint32_t value);
590
591/**
592 * register a new pointer axis binding
593 *
594 * this will intercept axis events from clients; use swc_pointer_send_axis()
595 * from the handler to forward events when appropriate
596 */
597int
598swc_add_axis_binding(uint32_t modifiers, uint32_t axis,
599 swc_axis_binding_handler handler, void *data);
600
601/* }}} */
602
603/**
604 * This is a user-provided structure that swc will use to notify the display
605 * server of new windows, screens and input devices.
606 */
607struct swc_manager {
608 /**
609 * Called when a new screen is created.
610 */
611 void (*new_screen)(struct swc_screen *screen);
612
613 /**
614 * Called when a new window is created.
615 */
616 void (*new_window)(struct swc_window *window);
617
618 /**
619 * Called when a new input device is detected.
620 */
621 void (*new_device)(struct libinput_device *device);
622
623 /**
624 * Called when the session gets activated (for example, startup or VT
625 * switch).
626 */
627 void (*activate)(void);
628
629 /**
630 * Called when the session gets deactivated.
631 */
632 void (*deactivate)(void);
633};
634
635/**
636 * Initializes the compositor using the specified display, event_loop, and
637 * manager.
638 */
639bool
640swc_initialize(struct wl_display *display, struct wl_event_loop *event_loop,
641 const struct swc_manager *manager);
642
643/**
644 * Stops the compositor, releasing any used resources.
645 */
646void
647swc_finalize(void);
648
649#ifdef __cplusplus
650}
651#endif
652
653#endif
654
655/* vim: set fdm=marker : */