Skip to content

Commit

Permalink
(nut-tree/nut.js#469) Adapt changes from bolt to libnut screengrab im…
Browse files Browse the repository at this point in the history
…plementation (#160)
  • Loading branch information
s1hofmann authored Jun 5, 2023
1 parent 23493fb commit 907f028
Show file tree
Hide file tree
Showing 3 changed files with 141 additions and 67 deletions.
76 changes: 53 additions & 23 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,60 @@ set(CMAKE_CXX_STANDARD 17)
project(libnut)

# Source
set(SOURCE_FILES "src/main.cc" "src/deadbeef_rand.c" "src/MMBitmap.c")
set(SOURCE_FILES
src/main.cc
src/deadbeef_rand.c
src/MMBitmap.c
)

if (UNIX AND NOT APPLE)
set(SOURCE_FILES "${SOURCE_FILES}" "src/linux/keycode.c" "src/linux/keypress.c" "src/linux/mouse.c" "src/linux/screen.c" "src/linux/screengrab.c" "src/linux/xdisplay.c" "src/linux/highlightwindow.c" "src/linux/window_manager.cc")
list(APPEND SOURCE_FILES
src/linux/keycode.c
src/linux/keypress.c
src/linux/mouse.c
src/linux/screen.c
src/linux/screengrab.c
src/linux/xdisplay.c
src/linux/highlightwindow.c
src/linux/window_manager.cc
)
elseif (UNIX AND APPLE)
set(SOURCE_FILES "${SOURCE_FILES}" "src/macos/keycode.c" "src/macos/keypress.c" "src/macos/mouse.c" "src/macos/mouse_utils.mm" "src/macos/screen.c" "src/macos/screengrab.c" "src/macos/highlightwindow.m" "src/macos/window_manager.mm")
list(APPEND SOURCE_FILES
src/macos/keycode.c
src/macos/keypress.c
src/macos/mouse.c
src/macos/mouse_utils.mm
src/macos/screen.c
src/macos/screengrab.m
src/macos/highlightwindow.m
src/macos/window_manager.mm
)
elseif (WIN32)
set(SOURCE_FILES "${SOURCE_FILES}" "src/win32/keycode.c" "src/win32/keypress.c" "src/win32/mouse.c" "src/win32/screen.c" "src/win32/screengrab.c" "src/win32/highlightwindow.c" "src/win32/window_manager.cc")
list(APPEND SOURCE_FILES
src/win32/keycode.c
src/win32/keypress.c
src/win32/mouse.c
src/win32/screen.c
src/win32/screengrab.c
src/win32/highlightwindow.c
src/win32/window_manager.cc
)
endif()

add_library(${PROJECT_NAME} SHARED ${SOURCE_FILES} ${CMAKE_JS_SRC})

# External libs
set(LIBS "")
set(INCLUDES "")

# External libs
if (UNIX AND APPLE)
message(STATUS "macOS build")
set(LIBS "${LIBS}" "-framework ApplicationServices")
set(LIBS "${LIBS}" "-framework Cocoa")
list(APPEND LIBS "-framework ApplicationServices" "-framework Cocoa")
elseif (WIN32)
message(STATUS "Windows build")
elseif (UNIX AND NOT APPLE)
message(STATUS "Linux build")
set(LIBS "${LIBS}" "-lX11")
set(LIBS "${LIBS}" "-lXtst")
list(APPEND LIBS "-lX11" "-lXtst")
endif()

if (NOT "${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
Expand All @@ -39,27 +69,27 @@ else()
endif()

if (WIN32)
# Copy runtime distributable
add_custom_command(
TARGET ${PROJECT_NAME} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
${CMAKE_SOURCE_DIR}/3rdparty/win32/msvcp140.dll
${CMAKE_SOURCE_DIR}/3rdparty/win32/vcruntime140.dll
${CMAKE_SOURCE_DIR}/3rdparty/win32/vcruntime140_1.dll
${CMAKE_SOURCE_DIR}/3rdparty/win32/api-ms-win-crt-heap-l1-1-0.dll
${CMAKE_SOURCE_DIR}/3rdparty/win32/api-ms-win-crt-runtime-l1-1-0.dll
${CMAKE_SOURCE_DIR}/3rdparty/win32/api-ms-win-crt-string-l1-1-0.dll
${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}/
)
# Copy runtime distributable
add_custom_command(
TARGET ${PROJECT_NAME} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
${CMAKE_SOURCE_DIR}/3rdparty/win32/msvcp140.dll
${CMAKE_SOURCE_DIR}/3rdparty/win32/vcruntime140.dll
${CMAKE_SOURCE_DIR}/3rdparty/win32/vcruntime140_1.dll
${CMAKE_SOURCE_DIR}/3rdparty/win32/api-ms-win-crt-heap-l1-1-0.dll
${CMAKE_SOURCE_DIR}/3rdparty/win32/api-ms-win-crt-runtime-l1-1-0.dll
${CMAKE_SOURCE_DIR}/3rdparty/win32/api-ms-win-crt-string-l1-1-0.dll
${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}/
)
endif()

add_compile_definitions(NAPI_CPP_EXCEPTIONS)
add_compile_definitions(NAPI_VERSION=3)

# cmake-js
set(INCLUDES ${INCLUDES} ${CMAKE_JS_INC})
list(APPEND INCLUDES ${CMAKE_JS_INC})
message(STATUS "Includes: ${INCLUDES}")
set(LIBS ${LIBS} ${CMAKE_JS_LIB})
list(APPEND LIBS ${CMAKE_JS_LIB})
message(STATUS "Libs: ${LIBS}")

# N-API
Expand Down
44 changes: 0 additions & 44 deletions src/macos/screengrab.c

This file was deleted.

88 changes: 88 additions & 0 deletions src/macos/screengrab.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#include "../screengrab.h"
#include "../endian.h"
#include <stdlib.h> /* malloc() */

#include <ApplicationServices/ApplicationServices.h>
#import <Cocoa/Cocoa.h>

static double getPixelDensity() {
@autoreleasepool
{
NSScreen * mainScreen = [NSScreen
mainScreen];
if (mainScreen) {
return mainScreen.backingScaleFactor;
} else {
return 1.0;
}
}
}

MMBitmapRef copyMMBitmapFromDisplayInRect(MMRect rect) {

CGDirectDisplayID displayID = CGMainDisplayID();

CGImageRef image = CGDisplayCreateImageForRect(displayID,
CGRectMake(
rect.origin.x,
rect.origin.y,
rect.size.width,
rect.size.height
)
);

if (!image) { return NULL; }

CFDataRef imageData = CGDataProviderCopyData(CGImageGetDataProvider(image));

if (!imageData) { return NULL; }

long bufferSize = CFDataGetLength(imageData);
size_t bytesPerPixel = (size_t) (CGImageGetBitsPerPixel(image) / 8);
double pixelDensity = getPixelDensity();
long expectedBufferSize = rect.size.width * pixelDensity * rect.size.height * pixelDensity * bytesPerPixel;

if (expectedBufferSize < bufferSize) {
size_t reportedByteWidth = CGImageGetBytesPerRow(image);
size_t expectedByteWidth = expectedBufferSize / (rect.size.height * pixelDensity);

uint8_t *buffer = malloc(expectedBufferSize);

const uint8_t *dataPointer = CFDataGetBytePtr(imageData);
size_t parts = bufferSize / reportedByteWidth;

for (size_t idx = 0; idx < parts - 1; ++idx) {
memcpy(buffer + (idx * expectedByteWidth),
dataPointer + (idx * reportedByteWidth),
expectedByteWidth
);
}

MMBitmapRef bitmap = createMMBitmap(buffer,
rect.size.width * pixelDensity,
rect.size.height * pixelDensity,
expectedByteWidth,
CGImageGetBitsPerPixel(image),
CGImageGetBitsPerPixel(image) / 8);

CFRelease(imageData);
CGImageRelease(image);

return bitmap;
} else {
uint8_t *buffer = malloc(bufferSize);
CFDataGetBytes(imageData, CFRangeMake(0, bufferSize), buffer);
MMBitmapRef bitmap = createMMBitmap(buffer,
CGImageGetWidth(image),
CGImageGetHeight(image),
CGImageGetBytesPerRow(image),
CGImageGetBitsPerPixel(image),
CGImageGetBitsPerPixel(image) / 8);

CFRelease(imageData);

CGImageRelease(image);

return bitmap;
}
}

0 comments on commit 907f028

Please sign in to comment.