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