1/* swc: libswc/view.c
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#include "view.h"
25#include "event.h"
26#include "internal.h"
27#include "screen.h"
28#include "util.h"
29
30#include <wld/wld.h>
31
32#define HANDLE(view, handler, method, ...) \
33 do { \
34 wl_list_for_each(handler, &view->handlers, link) \
35 { \
36 if (handler->impl->method) \
37 handler->impl->method(handler, ##__VA_ARGS__); \
38 } \
39 } while (0)
40
41void
42view_initialize(struct view *view, const struct view_impl *impl)
43{
44 view->impl = impl;
45 view->geometry.x = 0;
46 view->geometry.y = 0;
47 view->geometry.width = 0;
48 view->geometry.height = 0;
49 view->buffer = NULL;
50 view->screens = 0;
51 wl_list_init(&view->handlers);
52}
53
54void
55view_finalize(struct view *view)
56{
57 if (view->buffer) {
58 wld_buffer_unreference(view->buffer);
59 }
60}
61
62int
63view_attach(struct view *view, struct wld_buffer *buffer)
64{
65 int ret;
66 struct view_handler *handler;
67
68 if ((ret = view->impl->attach(view, buffer)) < 0) {
69 return ret;
70 }
71
72 if (view->buffer) {
73 wld_buffer_unreference(view->buffer);
74 }
75
76 if (buffer) {
77 wld_buffer_reference(buffer);
78 }
79
80 view->buffer = buffer;
81 HANDLE(view, handler, attach);
82
83 return 0;
84}
85
86bool
87view_update(struct view *view)
88{
89 return view->impl->update(view);
90}
91
92bool
93view_move(struct view *view, int32_t x, int32_t y)
94{
95 return view->impl->move(view, x, y);
96}
97
98bool
99view_set_position(struct view *view, int32_t x, int32_t y)
100{
101 struct view_handler *handler;
102
103 if (x == view->geometry.x && y == view->geometry.y) {
104 return false;
105 }
106
107 view->geometry.x = x;
108 view->geometry.y = y;
109 HANDLE(view, handler, move);
110
111 return true;
112}
113
114bool
115view_set_size(struct view *view, uint32_t width, uint32_t height)
116{
117 struct view_handler *handler;
118
119 if (view->geometry.width == width && view->geometry.height == height) {
120 return false;
121 }
122
123 uint32_t old_width = view->geometry.width,
124 old_height = view->geometry.height;
125
126 view->geometry.width = width;
127 view->geometry.height = height;
128 HANDLE(view, handler, resize, old_width, old_height);
129
130 return true;
131}
132
133bool
134view_set_size_from_buffer(struct view *view, struct wld_buffer *buffer)
135{
136 return view_set_size(view, buffer ? buffer->width : 0,
137 buffer ? buffer->height : 0);
138}
139
140void
141view_set_screens(struct view *view, uint32_t screens)
142{
143 if (view->screens == screens) {
144 return;
145 }
146
147 uint32_t entered = screens & ~view->screens,
148 left = view->screens & ~screens;
149 struct view_handler *handler;
150
151 view->screens = screens;
152 HANDLE(view, handler, screens, entered, left);
153}
154
155void
156view_update_screens(struct view *view)
157{
158 uint32_t screens = 0;
159 struct screen *screen;
160
161 wl_list_for_each(screen, &swc.screens, link)
162 {
163 if (rectangle_overlap(&screen->base.geometry, &view->geometry)) {
164 screens |= screen_mask(screen);
165 }
166 }
167
168 view_set_screens(view, screens);
169}
170
171void
172view_frame(struct view *view, uint32_t time)
173{
174 struct view_handler *handler;
175 HANDLE(view, handler, frame, time);
176}