Skip to content

Instantly share code, notes, and snippets.

@icywind
Last active December 3, 2021 03:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save icywind/0fd26481dd6884821d7f917944ec0042 to your computer and use it in GitHub Desktop.
Save icywind/0fd26481dd6884821d7f917944ec0042 to your computer and use it in GitHub Desktop.
A library source to return a list of screen ids
//
// ShareScreenMac.mm
// ShareScreenLib
//
// Created by Rick Cheng on 4/17/20.
// Copyright © 2020 Agora. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <AppKit/AppKit.h>
#import <CoreGraphics/CoreGraphics.h>
#if _MSC_VER // this is defined when compiling with Visual Studio
#define EXPORT_API __declspec(dllexport) // Visual Studio needs annotating exported functions with this
#else
#define EXPORT_API // XCode does not need annotating exported functions, so define is empty
#endif
// ------------------------------------------------------------------------
// Plugin itself
// Link following functions C-style (required for plugins)
extern "C"
{
// Just a test
EXPORT_API int PrintANumber(){
return 7;
}
/// Obtain a list of DisplayIds
/// @param d - managed array passed from C# layer
/// @param size - assigned elements in the array
/// @param length - array length
EXPORT_API void GetDisplayIds(unsigned int * d, int * size, int length)
{
int count = 0;
for(NSScreen *screen in [NSScreen screens])
{
NSDictionary * dict = [screen deviceDescription];
NSNumber * ddd = (NSNumber *) dict[@"NSScreenNumber"];
if (ddd != nil)
{
UInt displayId = [ddd unsignedIntValue];
d[count] = displayId;
}
count++;
if (count > length) break;
}
*size = count;
}
/// Obtain a list of Windows information
/// @param output - A preallocated memory buffer to hold string data, represents windows list array in JSON format
/// @param capacity - the length of the output allocated
EXPORT_API void GetWindows(char * output, int capacity)
{
NSArray* windows = (NSArray*)CFBridgingRelease(CGWindowListCopyWindowInfo(
kCGWindowListOptionOnScreenOnly | kCGWindowListExcludeDesktopElements, kCGNullWindowID));
// NSLog(@"All on screen windows: %lu\n", (unsigned long)windows.count);
// The windows filled, but we should filter out anything below the dock area
// Find window ID of "Dock" window
NSNumber *dockWindowNumber = nil;
for (NSDictionary *window in windows) {
if ([(NSString *)window[(__bridge NSString *)kCGWindowName] isEqualToString:@"Dock"]) {
dockWindowNumber = window[(__bridge NSString *)kCGWindowNumber];
break;
}
}
// NSLog(@"dockWindowNumber: %@\n", dockWindowNumber);
if (dockWindowNumber) {
// Fetch on screen windows again, filtering to those "below" the Dock window
// This filters out all but the "standard" application windows
CFArrayRef windowListArray = CGWindowListCreate(kCGWindowListOptionOnScreenBelowWindow|kCGWindowListExcludeDesktopElements, [dockWindowNumber unsignedIntValue]);
windows = CFBridgingRelease(CGWindowListCreateDescriptionFromArray(windowListArray));
// NSLog(@"On screen application windows: %@", windows);
CFRelease(windowListArray);
}
else {
// NSLog(@"Could not find Dock window description");
}
// Turn the list into a JSON string to return
NSError *error = nil;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:windows options:0 error:&error];
NSString *jsonString = [[NSString alloc] initWithData:jsonData
encoding:NSUTF8StringEncoding];
// NSLog(@"JSON: %@\n", jsonString);
NSUInteger length = [jsonString lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
if ( length >0 && length < capacity) {
strcpy(output, jsonString.UTF8String);
} else {
NSLog(@"The output string can't hold the JSON:%ld", length);
}
}
} // end of export C block
#if UNITY_STANDALONE_OSX || UNITY_EDITOR_OSX
[DllImport("ShareScreenLib")]
private static extern int PrintANumber();
[DllImport("ShareScreenLib")]
public static extern void GetDisplayIds([In, Out] uint[] displays, ref int size, int length);
void TestMacBridge()
{
int k = PrintANumber();
Debug.LogWarning("ver number = " + k);
uint[] ids = new uint[10];
int size = 0; // how much of array filled
int length = 10; // length of the allocated array
GetDisplayIds(ids, ref size, length);
Debug.LogWarning("Size = " + size);
if (size > 0)
{
for (int i = 0; i < size; i++)
{
Debug.LogWarning("Id = " + ids[i]);
}
}
}
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment