FreeRDP
Loading...
Searching...
No Matches
Utils.m
1/*
2 Utility functions
3
4 Copyright 2013 Thincast Technologies GmbH, Authors: Martin Fleisz, Dorian Johnson
5
6 This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
7 If a copy of the MPL was not distributed with this file, You can obtain one at
8 http://mozilla.org/MPL/2.0/.
9 */
10
11#import "Utils.h"
12#import "OrderedDictionary.h"
13#import "TSXAdditions.h"
14
15#import <freerdp/input.h>
16#import <freerdp/version.h>
17#import <freerdp/config.h>
18
19#include <sys/types.h>
20#include <sys/sysctl.h>
21#include <sys/socket.h>
22#include <ifaddrs.h>
23#include <net/if_dl.h>
24
25BOOL ScanHostNameAndPort(NSString *address, NSString **host, unsigned short *port)
26{
27 *host = @"";
28 *port = 0;
29
30 if (![address length])
31 return NO;
32
33 NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"rdp://%@", address]];
34
35 if (!url || ![[url host] length])
36 return NO;
37
38 *host = [url host];
39 *port = [[url port] unsignedShortValue];
40 return YES;
41}
42
43#pragma mark -
44#pragma mark Working with Screen Resolutions
45
46NSString *LocalizedFitScreen()
47{
48 return NSLocalizedString(@"Automatic", @"Screen resolution selector: Automatic resolution "
49 @"(Full Screen on iPad, reasonable size on iPhone)");
50}
51
52NSString *LocalizedCustom()
53{
54 return NSLocalizedString(@"Custom", @"Screen resolution selector: Custom");
55}
56
57BOOL ScanScreenResolution(NSString *description, int *width, int *height, TSXScreenOptions *type)
58{
59 *height = 0;
60 *width = 0;
61 *type = TSXScreenOptionFixed;
62
63 if ([description isEqualToString:LocalizedFitScreen()])
64 {
65 *type = TSXScreenOptionFitScreen;
66 return YES;
67 }
68 else if ([description isEqualToString:LocalizedCustom()])
69 {
70 *type = TSXScreenOptionCustom;
71 return YES;
72 }
73
74 NSArray *resolution_components = [description
75 componentsSeparatedByCharactersInSet:[NSCharacterSet
76 characterSetWithCharactersInString:@"x*×"]];
77
78 if ([resolution_components count] != 2)
79 return NO;
80
81 *width = [[resolution_components objectAtIndex:0] intValue];
82 *height = [[resolution_components objectAtIndex:1] intValue];
83 return YES;
84}
85
86NSString *ScreenResolutionDescription(TSXScreenOptions type, int width, int height)
87{
88 if (type == TSXScreenOptionFitScreen)
89 return LocalizedFitScreen();
90 else if (type == TSXScreenOptionCustom)
91 return LocalizedCustom();
92
93 return [NSString stringWithFormat:@"%dx%d", width, height];
94}
95
96NSDictionary *SelectionForColorSetting()
97{
98 OrderedDictionary *dict = [OrderedDictionary dictionaryWithCapacity:3];
99 [dict setValue:[NSNumber numberWithInt:8]
100 forKey:NSLocalizedString(@"Palette Color (8 Bit)", @"8 bit color selection")];
101 [dict setValue:[NSNumber numberWithInt:15]
102 forKey:NSLocalizedString(@"High Color (15 Bit)", @"15 bit color selection")];
103 [dict setValue:[NSNumber numberWithInt:16]
104 forKey:NSLocalizedString(@"High Color (16 Bit)", @"16 bit color selection")];
105 [dict setValue:[NSNumber numberWithInt:24]
106 forKey:NSLocalizedString(@"True Color (24 Bit)", @"24 bit color selection")];
107 [dict setValue:[NSNumber numberWithInt:32]
108 forKey:NSLocalizedString(@"Highest Quality (32 Bit)", @"32 bit color selection")];
109 return dict;
110}
111
112NSArray *ResolutionModes()
113{
114 NSArray *array =
115 [NSArray arrayWithObjects:ScreenResolutionDescription(TSXScreenOptionFitScreen, 0, 0),
116 ScreenResolutionDescription(TSXScreenOptionFixed, 640, 480),
117 ScreenResolutionDescription(TSXScreenOptionFixed, 800, 600),
118 ScreenResolutionDescription(TSXScreenOptionFixed, 1024, 768),
119 ScreenResolutionDescription(TSXScreenOptionFixed, 1280, 1024),
120 ScreenResolutionDescription(TSXScreenOptionFixed, 1440, 900),
121 ScreenResolutionDescription(TSXScreenOptionFixed, 1440, 1050),
122 ScreenResolutionDescription(TSXScreenOptionFixed, 1600, 1200),
123 ScreenResolutionDescription(TSXScreenOptionFixed, 1920, 1080),
124 ScreenResolutionDescription(TSXScreenOptionFixed, 1920, 1200),
125 ScreenResolutionDescription(TSXScreenOptionCustom, 0, 0), nil];
126 return array;
127}
128
129#pragma mark Working with Security Protocols
130
131NSString *LocalizedAutomaticSecurity()
132{
133 return NSLocalizedString(@"Automatic", @"Automatic protocol security selection");
134}
135
136NSString *ProtocolSecurityDescription(TSXProtocolSecurityOptions type)
137{
138 if (type == TSXProtocolSecurityNLA)
139 return @"NLA";
140 else if (type == TSXProtocolSecurityTLS)
141 return @"TLS";
142 else if (type == TSXProtocolSecurityRDP)
143 return @"RDP";
144
145 return LocalizedAutomaticSecurity();
146}
147
148BOOL ScanProtocolSecurity(NSString *description, TSXProtocolSecurityOptions *type)
149{
150 *type = TSXProtocolSecurityRDP;
151
152 if ([description isEqualToString:@"NLA"])
153 {
154 *type = TSXProtocolSecurityNLA;
155 return YES;
156 }
157 else if ([description isEqualToString:@"TLS"])
158 {
159 *type = TSXProtocolSecurityTLS;
160 return YES;
161 }
162 else if ([description isEqualToString:@"RDP"])
163 {
164 *type = TSXProtocolSecurityRDP;
165 return YES;
166 }
167 else if ([description isEqualToString:LocalizedAutomaticSecurity()])
168 {
169 *type = TSXProtocolSecurityAutomatic;
170 return YES;
171 }
172
173 return NO;
174}
175
176NSDictionary *SelectionForSecuritySetting()
177{
178 OrderedDictionary *dict = [OrderedDictionary dictionaryWithCapacity:4];
179 [dict setValue:[NSNumber numberWithInt:TSXProtocolSecurityAutomatic]
180 forKey:ProtocolSecurityDescription(TSXProtocolSecurityAutomatic)];
181 [dict setValue:[NSNumber numberWithInt:TSXProtocolSecurityRDP]
182 forKey:ProtocolSecurityDescription(TSXProtocolSecurityRDP)];
183 [dict setValue:[NSNumber numberWithInt:TSXProtocolSecurityTLS]
184 forKey:ProtocolSecurityDescription(TSXProtocolSecurityTLS)];
185 [dict setValue:[NSNumber numberWithInt:TSXProtocolSecurityNLA]
186 forKey:ProtocolSecurityDescription(TSXProtocolSecurityNLA)];
187 return dict;
188}
189
190#pragma mark -
191#pragma mark Bookmarks
192
193#import "Bookmark.h"
194
195NSMutableArray *FilterBookmarks(NSArray *bookmarks, NSArray *filter_words)
196{
197 NSMutableArray *matching_items = [NSMutableArray array];
198 NSArray *searched_keys = [NSArray
199 arrayWithObjects:@"label", @"params.hostname", @"params.username", @"params.domain", nil];
200
201 for (ComputerBookmark *cur_bookmark in bookmarks)
202 {
203 double match_score = 0.0;
204
205 for (int i = 0; i < [searched_keys count]; i++)
206 {
207 NSString *val = [cur_bookmark valueForKeyPath:[searched_keys objectAtIndex:i]];
208
209 if (![val isKindOfClass:[NSString class]] || ![val length])
210 continue;
211
212 for (NSString *word in filter_words)
213 if ([val rangeOfString:word
214 options:(NSCaseInsensitiveSearch | NSWidthInsensitiveSearch)]
215 .location != NSNotFound)
216 match_score += (1.0 / [filter_words count]) * pow(2, [searched_keys count] - i);
217 }
218
219 if (match_score > 0.001)
220 [matching_items
221 addObject:[NSDictionary
222 dictionaryWithObjectsAndKeys:cur_bookmark, @"bookmark",
223 [NSNumber numberWithFloat:match_score],
224 @"score", nil]];
225 }
226
227 [matching_items
228 sortUsingComparator:^NSComparisonResult(NSDictionary *obj1, NSDictionary *obj2) {
229 return [[obj2 objectForKey:@"score"] compare:[obj1 objectForKey:@"score"]];
230 }];
231 return matching_items;
232}
233
234NSMutableArray *FilterHistory(NSArray *history, NSString *filterStr)
235{
236 NSMutableArray *result = [NSMutableArray array];
237
238 for (NSString *item in history)
239 {
240 if ([item rangeOfString:filterStr].location != NSNotFound)
241 [result addObject:item];
242 }
243
244 return result;
245}
246
247#pragma mark Version Info
248NSString *TSXAppFullVersion()
249{
250 return [NSString stringWithUTF8String:FREERDP_GIT_REVISION];
251}
252
253#pragma mark iPad/iPhone detection
254
255BOOL IsPad()
256{
257 return ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad);
258}
259
260BOOL IsPhone()
261{
262 return ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone);
263}
264
265// set mouse buttons swapped flag
266static BOOL g_swap_mouse_buttons = NO;
267void SetSwapMouseButtonsFlag(BOOL swapped)
268{
269 g_swap_mouse_buttons = swapped;
270}
271
272// set invert scrolling flag
273static BOOL g_invert_scrolling = NO;
274void SetInvertScrollingFlag(BOOL invert)
275{
276 g_invert_scrolling = invert;
277}
278
279// return event value for left mouse button
280int GetLeftMouseButtonClickEvent(BOOL down)
281{
282 if (g_swap_mouse_buttons)
283 return (PTR_FLAGS_BUTTON2 | (down ? PTR_FLAGS_DOWN : 0));
284 else
285 return (PTR_FLAGS_BUTTON1 | (down ? PTR_FLAGS_DOWN : 0));
286}
287
288// return event value for right mouse button
289int GetRightMouseButtonClickEvent(BOOL down)
290{
291 if (g_swap_mouse_buttons)
292 return (PTR_FLAGS_BUTTON1 | (down ? PTR_FLAGS_DOWN : 0));
293 else
294 return (PTR_FLAGS_BUTTON2 | (down ? PTR_FLAGS_DOWN : 0));
295}
296
297// get mouse move event
298int GetMouseMoveEvent()
299{
300 return (PTR_FLAGS_MOVE);
301}
302
303// return mouse wheel event
304int GetMouseWheelEvent(BOOL down)
305{
306 if (g_invert_scrolling)
307 down = !down;
308
309 if (down)
310 return (PTR_FLAGS_WHEEL | PTR_FLAGS_WHEEL_NEGATIVE | (0x0088));
311 else
312 return (PTR_FLAGS_WHEEL | (0x0078));
313}
314
315// scrolling gesture detection delta
316CGFloat GetScrollGestureDelta()
317{
318 return 10.0f;
319}
320
321#pragma mark System Info functions
322
323NSString *TSXGetPrimaryMACAddress(NSString *sep)
324{
325 NSString *macaddress = @"";
326 struct ifaddrs *addrs;
327
328 if (getifaddrs(&addrs) < 0)
329 {
330 NSLog(@"getPrimaryMACAddress: getifaddrs failed.");
331 return macaddress;
332 }
333
334 for (struct ifaddrs *cursor = addrs; cursor != nullptr; cursor = cursor->ifa_next)
335 {
336 if (strcmp(cursor->ifa_name, "en0"))
337 continue;
338
339 if ((cursor->ifa_addr->sa_family == AF_LINK) &&
340 (((struct sockaddr_dl *)cursor->ifa_addr)->sdl_type == 0x6 /*IFT_ETHER*/))
341 {
342 struct sockaddr_dl *dlAddr = (struct sockaddr_dl *)cursor->ifa_addr;
343
344 if (dlAddr->sdl_alen != 6)
345 continue;
346
347 unsigned char *base = (unsigned char *)&dlAddr->sdl_data[dlAddr->sdl_nlen];
348 macaddress = [NSString hexStringFromData:base
349 ofSize:6
350 withSeparator:sep
351 afterNthChar:1];
352 break;
353 }
354 }
355
356 freeifaddrs(addrs);
357 return macaddress;
358}
359
360BOOL TSXDeviceHasJailBreak()
361{
362 if ([[NSFileManager defaultManager] fileExistsAtPath:@"/Applications/Cydia.app/"])
363 return YES;
364
365 if ([[NSFileManager defaultManager] fileExistsAtPath:@"/etc/apt/"])
366 return YES;
367
368 return NO;
369}
370
371NSString *TSXGetPlatform()
372{
373 size_t size;
374 sysctlbyname("hw.machine", nullptr, &size, nullptr, 0);
375 char *machine = malloc(size);
376 sysctlbyname("hw.machine", machine, &size, nullptr, 0);
377 NSString *platform = [NSString stringWithCString:machine encoding:NSASCIIStringEncoding];
378 free(machine);
379 return platform;
380}