main neuswc / libswc / view.c
  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}