1 /*
2 * synergy -- mouse and keyboard sharing utility
3 * Copyright (C) 2012-2021 Symless Ltd.
4 * Copyright (C) 2008 Volker Lanz (vl@fidra.de)
5 *
6 * This package is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * found in the file LICENSE that should have accompanied this file.
9 *
10 * This package is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18 #include "ScreenList.h"
19
20 #include <array>
21
22 namespace {
23
24 /**
25 * @brief getNeightborIndexes returns indexes for server neighbors
26 * @param serverIndex server index
27 * @param width of the grid
28 * @param size of the grid
29 * @return indexes for server neighbors
30 */
getNeighborsIndexes(int serverIndex,int width,int size)31 std::array<int, 8> getNeighborsIndexes(int serverIndex, int width, int size)
32 {
33 const int UNSET = -1;
34 const int LEFT = 0;
35 const int RIGHT = 1;
36 const int TOP = 2;
37 const int BOTTOM = 3;
38 const int TOP_LEFT = 4;
39 const int TOP_RIGHT = 5;
40 const int BOTTOM_RIGHT = 6;
41 const int BOTTOM_LEFT = 7;
42
43 std::array<int, 8> indexes = { UNSET };
44
45 if (serverIndex >= 0 && serverIndex < size)
46 {
47 indexes[LEFT] = (serverIndex - 1) % width != width - 1 ? (serverIndex - 1) : UNSET;
48 indexes[RIGHT] = (serverIndex + 1) % width != 0 ? (serverIndex + 1) : UNSET;
49 indexes[TOP] = (serverIndex - width) >= 0 ? (serverIndex - width) : UNSET;
50 indexes[BOTTOM] = (serverIndex + width) < size ? (serverIndex + width) : UNSET;
51 indexes[TOP_LEFT] = (indexes[TOP] != UNSET && indexes[LEFT] != UNSET) ? indexes[TOP] - 1 : UNSET;
52 indexes[TOP_RIGHT] = (indexes[TOP] != UNSET && indexes[RIGHT] != UNSET) ? indexes[TOP] + 1 : UNSET;
53 indexes[BOTTOM_RIGHT] = (indexes[BOTTOM] != UNSET && indexes[RIGHT] != UNSET) ? indexes[BOTTOM] + 1 : UNSET;
54 indexes[BOTTOM_LEFT] = (indexes[BOTTOM] != UNSET && indexes[LEFT] != UNSET) ? indexes[BOTTOM] - 1 : UNSET;
55 }
56
57 return indexes;
58 }
59
60 /**
61 * @brief getServerIndex finds server and returns it's index
62 * @param screens list to find server
63 * @return server index
64 */
getServerIndex(const ScreenList & screens)65 int getServerIndex(const ScreenList& screens)
66 {
67 int serverIndex = -1;
68
69 for (int i = 0; i < screens.size(); ++i)
70 {
71 if (screens[i].isServer()){
72 serverIndex = i;
73 break;
74 }
75 }
76
77 return serverIndex;
78 }
79
80 } //namespace
81
ScreenList(int width)82 ScreenList::ScreenList(int width) :
83 QList<Screen>(),
84 m_width(width)
85 {
86
87 }
88
addScreenByPriority(const Screen & newScreen)89 void ScreenList::addScreenByPriority(const Screen& newScreen)
90 {
91 int serverIndex = getServerIndex(*this);
92 auto indexes = getNeighborsIndexes(serverIndex, m_width, size());
93
94 bool isAdded = false;
95 for (const auto& index : indexes)
96 {
97 if (index >= 0 && index < size())
98 {
99 auto& screen = operator[](index);
100 if (screen.isNull())
101 {
102 screen = newScreen;
103 isAdded = true;
104 break;
105 }
106 }
107 }
108
109 if (!isAdded)
110 {
111 addScreenToFirstEmpty(newScreen);
112 }
113 }
114
addScreenToFirstEmpty(const Screen & newScreen)115 void ScreenList::addScreenToFirstEmpty(const Screen& newScreen)
116 {
117 for (int i = 0; i < size(); ++i)
118 {
119 auto& screen = operator[](i);
120 if (screen.isNull())
121 {
122 screen = newScreen;
123 break;
124 }
125 }
126 }
127
128