FreeRDP
mf_info.c
1 
20 #include <freerdp/config.h>
21 
22 #include <stdlib.h>
23 #include <errno.h>
24 
25 #include "mf_info.h"
26 #include "mf_mountain_lion.h"
27 
28 #define MF_INFO_DEFAULT_FPS 30
29 #define MF_INFO_MAXPEERS 32
30 
31 static mfInfo* mfInfoInstance = NULL;
32 
33 int mf_info_lock(mfInfo* mfi)
34 {
35  int status = pthread_mutex_lock(&mfi->mutex);
36 
37  switch (status)
38  {
39  case 0:
40  return TRUE;
41  break;
42 
43  default:
44  return -1;
45  break;
46  }
47 
48  return 1;
49 }
50 
51 int mf_info_try_lock(mfInfo* mfi, UINT32 ms)
52 {
53  int status = pthread_mutex_trylock(&mfi->mutex);
54 
55  switch (status)
56  {
57  case 0:
58  return TRUE;
59  break;
60 
61  case EBUSY:
62  return FALSE;
63  break;
64 
65  default:
66  return -1;
67  break;
68  }
69 
70  return 1;
71 }
72 
73 int mf_info_unlock(mfInfo* mfi)
74 {
75  int status = pthread_mutex_unlock(&mfi->mutex);
76 
77  switch (status)
78  {
79  case 0:
80  return TRUE;
81  break;
82 
83  default:
84  return -1;
85  break;
86  }
87 
88  return 1;
89 }
90 
91 static mfInfo* mf_info_init(void)
92 {
93  mfInfo* mfi;
94 
95  mfi = (mfInfo*)calloc(1, sizeof(mfInfo));
96 
97  if (mfi != NULL)
98  {
99  pthread_mutex_init(&mfi->mutex, NULL);
100 
101  mfi->peers = (freerdp_peer**)calloc(MF_INFO_MAXPEERS, sizeof(freerdp_peer*));
102  if (!mfi->peers)
103  {
104  free(mfi);
105  return NULL;
106  }
107 
108  mfi->framesPerSecond = MF_INFO_DEFAULT_FPS;
109  mfi->input_disabled = FALSE;
110  }
111 
112  return mfi;
113 }
114 
115 mfInfo* mf_info_get_instance(void)
116 {
117  if (mfInfoInstance == NULL)
118  mfInfoInstance = mf_info_init();
119 
120  return mfInfoInstance;
121 }
122 
123 void mf_info_peer_register(mfInfo* mfi, mfPeerContext* context)
124 {
125  if (mf_info_lock(mfi) > 0)
126  {
127  int peerId;
128 
129  if (mfi->peerCount == MF_INFO_MAXPEERS)
130  {
131  mf_info_unlock(mfi);
132  return;
133  }
134 
135  context->info = mfi;
136 
137  if (mfi->peerCount == 0)
138  {
139  mf_mlion_display_info(&mfi->servscreen_width, &mfi->servscreen_height, &mfi->scale);
140  mf_mlion_screen_updates_init();
141  mf_mlion_start_getting_screen_updates();
142  }
143 
144  peerId = 0;
145 
146  for (int i = 0; i < MF_INFO_MAXPEERS; ++i)
147  {
148  // empty index will be our peer id
149  if (mfi->peers[i] == NULL)
150  {
151  peerId = i;
152  break;
153  }
154  }
155 
156  mfi->peers[peerId] = ((rdpContext*)context)->peer;
157  mfi->peers[peerId]->pId = peerId;
158  mfi->peerCount++;
159 
160  mf_info_unlock(mfi);
161  }
162 }
163 
164 void mf_info_peer_unregister(mfInfo* mfi, mfPeerContext* context)
165 {
166  if (mf_info_lock(mfi) > 0)
167  {
168  int peerId;
169 
170  peerId = ((rdpContext*)context)->peer->pId;
171  mfi->peers[peerId] = NULL;
172  mfi->peerCount--;
173 
174  if (mfi->peerCount == 0)
175  mf_mlion_stop_getting_screen_updates();
176 
177  mf_info_unlock(mfi);
178  }
179 }
180 
181 BOOL mf_info_have_updates(mfInfo* mfi)
182 {
183  if (mfi->framesWaiting == 0)
184  return FALSE;
185 
186  return TRUE;
187 }
188 
189 void mf_info_update_changes(mfInfo* mfi)
190 {
191 }
192 
193 void mf_info_find_invalid_region(mfInfo* mfi)
194 {
195  mf_mlion_get_dirty_region(&mfi->invalid);
196 }
197 
198 void mf_info_clear_invalid_region(mfInfo* mfi)
199 {
200  mf_mlion_clear_dirty_region();
201  mfi->invalid.height = 0;
202  mfi->invalid.width = 0;
203 }
204 
205 void mf_info_invalidate_full_screen(mfInfo* mfi)
206 {
207  mfi->invalid.x = 0;
208  mfi->invalid.y = 0;
209  mfi->invalid.height = mfi->servscreen_height;
210  mfi->invalid.width = mfi->servscreen_width;
211 }
212 
213 BOOL mf_info_have_invalid_region(mfInfo* mfi)
214 {
215  if (mfi->invalid.width * mfi->invalid.height == 0)
216  return FALSE;
217 
218  return TRUE;
219 }
220 
221 void mf_info_getScreenData(mfInfo* mfi, long* width, long* height, BYTE** pBits, int* pitch)
222 {
223  *width = mfi->invalid.width / mfi->scale;
224  *height = mfi->invalid.height / mfi->scale;
225  *pitch = mfi->servscreen_width * mfi->scale * 4;
226 
227  mf_mlion_get_pixelData(mfi->invalid.x / mfi->scale, mfi->invalid.y / mfi->scale, *width,
228  *height, pBits);
229 
230  *pBits = *pBits + (mfi->invalid.x * 4) + (*pitch * mfi->invalid.y);
231 }