blob: 9680b6e78e906c7a66378c0484f6f91363c84020 [file] [log] [blame]
Pierre Ossmancbd1b2c2009-03-20 16:05:04 +00001/* Copyright 2009 Pierre Ossman for Cendio AB
2 *
3 * This is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This software is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this software; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
16 * USA.
17 */
18
19// Management class for the RFB virtual screens
20
21#ifndef __RFB_SCREENSET_INCLUDED__
22#define __RFB_SCREENSET_INCLUDED__
23
Pierre Ossman04e62db2009-03-23 16:57:07 +000024#include <stdio.h>
Pierre Ossman9018af42015-01-26 15:15:47 +010025#include <string.h>
Pierre Ossman04e62db2009-03-23 16:57:07 +000026
Pierre Ossmanc314d082012-07-13 11:18:55 +000027#include <rdr/types.h>
Pierre Ossmancbd1b2c2009-03-20 16:05:04 +000028#include <rfb/Rect.h>
29#include <list>
30#include <set>
31
32namespace rfb {
33
34 // rfb::Screen
35 //
36 // Represents a single RFB virtual screen, which includes
37 // coordinates, an id and flags.
38
39 struct Screen {
40 Screen(void) : id(0), flags(0) {};
41 Screen(rdr::U32 id_, int x_, int y_, int w_, int h_, rdr::U32 flags_) :
42 id(id_), dimensions(x_, y_, x_+w_, y_+h_), flags(flags_) {};
Pierre Ossman04e62db2009-03-23 16:57:07 +000043
44 inline bool operator==(const Screen& r) const {
45 if (id != r.id)
46 return false;
47 if (!dimensions.equals(r.dimensions))
48 return false;
49 if (flags != r.flags)
50 return false;
51 return true;
52 }
53
Pierre Ossmancbd1b2c2009-03-20 16:05:04 +000054 rdr::U32 id;
55 Rect dimensions;
56 rdr::U32 flags;
57 };
58
59 // rfb::ScreenSet
60 //
61 // Represents a complete screen configuration, excluding framebuffer
62 // dimensions.
63
64 struct ScreenSet {
65 ScreenSet(void) {};
Pierre Ossman34e62f32009-03-20 21:46:12 +000066
67 typedef std::list<Screen>::iterator iterator;
68 typedef std::list<Screen>::const_iterator const_iterator;
69
70 inline iterator begin(void) { return screens.begin(); };
71 inline const_iterator begin(void) const { return screens.begin(); };
72 inline iterator end(void) { return screens.end(); };
73 inline const_iterator end(void) const { return screens.end(); };
74
75 inline int num_screens(void) const { return screens.size(); };
76
Pierre Ossmancbd1b2c2009-03-20 16:05:04 +000077 inline void add_screen(const Screen screen) { screens.push_back(screen); };
Pierre Ossman34e62f32009-03-20 21:46:12 +000078 inline void remove_screen(rdr::U32 id) {
Adam Tkac684ca1d2010-11-22 14:53:23 +000079 std::list<Screen>::iterator iter, nextiter;
80 for (iter = screens.begin();iter != screens.end();iter = nextiter) {
Adam Tkace9e338c2010-12-01 10:11:20 +000081 nextiter = iter; nextiter++;
Pierre Ossman34e62f32009-03-20 21:46:12 +000082 if (iter->id == id)
83 screens.erase(iter);
84 }
85 }
86
Pierre Ossmancbd1b2c2009-03-20 16:05:04 +000087 inline bool validate(int fb_width, int fb_height) const {
88 std::list<Screen>::const_iterator iter;
89 std::set<rdr::U32> seen_ids;
90 Rect fb_rect;
91
92 if (screens.empty())
93 return false;
Pierre Ossman34e62f32009-03-20 21:46:12 +000094 if (num_screens() > 255)
95 return false;
Pierre Ossmancbd1b2c2009-03-20 16:05:04 +000096
97 fb_rect.setXYWH(0, 0, fb_width, fb_height);
98
99 for (iter = screens.begin();iter != screens.end();++iter) {
100 if (iter->dimensions.is_empty())
101 return false;
102 if (!iter->dimensions.enclosed_by(fb_rect))
103 return false;
104 if (seen_ids.find(iter->id) != seen_ids.end())
105 return false;
106 seen_ids.insert(iter->id);
107 }
108
109 return true;
110 };
Pierre Ossman34e62f32009-03-20 21:46:12 +0000111
Pierre Ossman9018af42015-01-26 15:15:47 +0100112 inline void print(char* str, size_t len) const {
113 char buffer[128];
Pierre Ossman04e62db2009-03-23 16:57:07 +0000114 std::list<Screen>::const_iterator iter;
Pierre Ossman9018af42015-01-26 15:15:47 +0100115 snprintf(buffer, sizeof(buffer), "%d screen(s)\n", num_screens());
116 str[0] = '\0';
117 strncat(str, buffer, len - 1 - strlen(str));
Pierre Ossman04e62db2009-03-23 16:57:07 +0000118 for (iter = screens.begin();iter != screens.end();++iter) {
Pierre Ossman9018af42015-01-26 15:15:47 +0100119 snprintf(buffer, sizeof(buffer),
120 " %10d (0x%08x): %dx%d+%d+%d (flags 0x%08x)\n",
121 (int)iter->id, (unsigned)iter->id,
122 iter->dimensions.width(), iter->dimensions.height(),
123 iter->dimensions.tl.x, iter->dimensions.tl.y,
124 (unsigned)iter->flags);
125 strncat(str, buffer, len - 1 - strlen(str));
Pierre Ossman04e62db2009-03-23 16:57:07 +0000126 }
127 };
128
Peter Åstrand (astrand)a9d70692018-05-07 09:58:59 +0200129 inline bool operator==(const ScreenSet& r) const {
130 std::list<Screen> a = screens;
131 a.sort(compare_screen);
132 std::list<Screen> b = r.screens;
133 b.sort(compare_screen);
134 return a == b;
135 };
136 inline bool operator!=(const ScreenSet& r) const { return !operator==(r); }
Pierre Ossman04e62db2009-03-23 16:57:07 +0000137
Pierre Ossmancbd1b2c2009-03-20 16:05:04 +0000138 std::list<Screen> screens;
Peter Åstrand (astrand)a9d70692018-05-07 09:58:59 +0200139
140 private:
141 static inline bool compare_screen(const Screen& first, const Screen& second)
142 {
143 return first.id < second.id;
144 }
145
Pierre Ossmancbd1b2c2009-03-20 16:05:04 +0000146 };
147
148};
149
150#endif
151