Skip to content

Commit 907f028

Browse files
authored
(nut-tree/nut.js#469) Adapt changes from bolt to libnut screengrab implementation (#160)
1 parent 23493fb commit 907f028

File tree

3 files changed

+141
-67
lines changed

3 files changed

+141
-67
lines changed

Diff for: CMakeLists.txt

+53-23
Original file line numberDiff line numberDiff line change
@@ -4,30 +4,60 @@ set(CMAKE_CXX_STANDARD 17)
44
project(libnut)
55

66
# Source
7-
set(SOURCE_FILES "src/main.cc" "src/deadbeef_rand.c" "src/MMBitmap.c")
7+
set(SOURCE_FILES
8+
src/main.cc
9+
src/deadbeef_rand.c
10+
src/MMBitmap.c
11+
)
12+
813
if (UNIX AND NOT APPLE)
9-
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")
14+
list(APPEND SOURCE_FILES
15+
src/linux/keycode.c
16+
src/linux/keypress.c
17+
src/linux/mouse.c
18+
src/linux/screen.c
19+
src/linux/screengrab.c
20+
src/linux/xdisplay.c
21+
src/linux/highlightwindow.c
22+
src/linux/window_manager.cc
23+
)
1024
elseif (UNIX AND APPLE)
11-
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")
25+
list(APPEND SOURCE_FILES
26+
src/macos/keycode.c
27+
src/macos/keypress.c
28+
src/macos/mouse.c
29+
src/macos/mouse_utils.mm
30+
src/macos/screen.c
31+
src/macos/screengrab.m
32+
src/macos/highlightwindow.m
33+
src/macos/window_manager.mm
34+
)
1235
elseif (WIN32)
13-
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")
36+
list(APPEND SOURCE_FILES
37+
src/win32/keycode.c
38+
src/win32/keypress.c
39+
src/win32/mouse.c
40+
src/win32/screen.c
41+
src/win32/screengrab.c
42+
src/win32/highlightwindow.c
43+
src/win32/window_manager.cc
44+
)
1445
endif()
46+
1547
add_library(${PROJECT_NAME} SHARED ${SOURCE_FILES} ${CMAKE_JS_SRC})
1648

49+
# External libs
1750
set(LIBS "")
1851
set(INCLUDES "")
1952

20-
# External libs
2153
if (UNIX AND APPLE)
2254
message(STATUS "macOS build")
23-
set(LIBS "${LIBS}" "-framework ApplicationServices")
24-
set(LIBS "${LIBS}" "-framework Cocoa")
55+
list(APPEND LIBS "-framework ApplicationServices" "-framework Cocoa")
2556
elseif (WIN32)
2657
message(STATUS "Windows build")
2758
elseif (UNIX AND NOT APPLE)
2859
message(STATUS "Linux build")
29-
set(LIBS "${LIBS}" "-lX11")
30-
set(LIBS "${LIBS}" "-lXtst")
60+
list(APPEND LIBS "-lX11" "-lXtst")
3161
endif()
3262

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

4171
if (WIN32)
42-
# Copy runtime distributable
43-
add_custom_command(
44-
TARGET ${PROJECT_NAME} POST_BUILD
45-
COMMAND ${CMAKE_COMMAND} -E copy
46-
${CMAKE_SOURCE_DIR}/3rdparty/win32/msvcp140.dll
47-
${CMAKE_SOURCE_DIR}/3rdparty/win32/vcruntime140.dll
48-
${CMAKE_SOURCE_DIR}/3rdparty/win32/vcruntime140_1.dll
49-
${CMAKE_SOURCE_DIR}/3rdparty/win32/api-ms-win-crt-heap-l1-1-0.dll
50-
${CMAKE_SOURCE_DIR}/3rdparty/win32/api-ms-win-crt-runtime-l1-1-0.dll
51-
${CMAKE_SOURCE_DIR}/3rdparty/win32/api-ms-win-crt-string-l1-1-0.dll
52-
${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}/
53-
)
72+
# Copy runtime distributable
73+
add_custom_command(
74+
TARGET ${PROJECT_NAME} POST_BUILD
75+
COMMAND ${CMAKE_COMMAND} -E copy
76+
${CMAKE_SOURCE_DIR}/3rdparty/win32/msvcp140.dll
77+
${CMAKE_SOURCE_DIR}/3rdparty/win32/vcruntime140.dll
78+
${CMAKE_SOURCE_DIR}/3rdparty/win32/vcruntime140_1.dll
79+
${CMAKE_SOURCE_DIR}/3rdparty/win32/api-ms-win-crt-heap-l1-1-0.dll
80+
${CMAKE_SOURCE_DIR}/3rdparty/win32/api-ms-win-crt-runtime-l1-1-0.dll
81+
${CMAKE_SOURCE_DIR}/3rdparty/win32/api-ms-win-crt-string-l1-1-0.dll
82+
${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}/
83+
)
5484
endif()
5585

5686
add_compile_definitions(NAPI_CPP_EXCEPTIONS)
5787
add_compile_definitions(NAPI_VERSION=3)
5888

5989
# cmake-js
60-
set(INCLUDES ${INCLUDES} ${CMAKE_JS_INC})
90+
list(APPEND INCLUDES ${CMAKE_JS_INC})
6191
message(STATUS "Includes: ${INCLUDES}")
62-
set(LIBS ${LIBS} ${CMAKE_JS_LIB})
92+
list(APPEND LIBS ${CMAKE_JS_LIB})
6393
message(STATUS "Libs: ${LIBS}")
6494

6595
# N-API

Diff for: src/macos/screengrab.c

-44
This file was deleted.

Diff for: src/macos/screengrab.m

+88
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
#include "../screengrab.h"
2+
#include "../endian.h"
3+
#include <stdlib.h> /* malloc() */
4+
5+
#include <ApplicationServices/ApplicationServices.h>
6+
#import <Cocoa/Cocoa.h>
7+
8+
static double getPixelDensity() {
9+
@autoreleasepool
10+
{
11+
NSScreen * mainScreen = [NSScreen
12+
mainScreen];
13+
if (mainScreen) {
14+
return mainScreen.backingScaleFactor;
15+
} else {
16+
return 1.0;
17+
}
18+
}
19+
}
20+
21+
MMBitmapRef copyMMBitmapFromDisplayInRect(MMRect rect) {
22+
23+
CGDirectDisplayID displayID = CGMainDisplayID();
24+
25+
CGImageRef image = CGDisplayCreateImageForRect(displayID,
26+
CGRectMake(
27+
rect.origin.x,
28+
rect.origin.y,
29+
rect.size.width,
30+
rect.size.height
31+
)
32+
);
33+
34+
if (!image) { return NULL; }
35+
36+
CFDataRef imageData = CGDataProviderCopyData(CGImageGetDataProvider(image));
37+
38+
if (!imageData) { return NULL; }
39+
40+
long bufferSize = CFDataGetLength(imageData);
41+
size_t bytesPerPixel = (size_t) (CGImageGetBitsPerPixel(image) / 8);
42+
double pixelDensity = getPixelDensity();
43+
long expectedBufferSize = rect.size.width * pixelDensity * rect.size.height * pixelDensity * bytesPerPixel;
44+
45+
if (expectedBufferSize < bufferSize) {
46+
size_t reportedByteWidth = CGImageGetBytesPerRow(image);
47+
size_t expectedByteWidth = expectedBufferSize / (rect.size.height * pixelDensity);
48+
49+
uint8_t *buffer = malloc(expectedBufferSize);
50+
51+
const uint8_t *dataPointer = CFDataGetBytePtr(imageData);
52+
size_t parts = bufferSize / reportedByteWidth;
53+
54+
for (size_t idx = 0; idx < parts - 1; ++idx) {
55+
memcpy(buffer + (idx * expectedByteWidth),
56+
dataPointer + (idx * reportedByteWidth),
57+
expectedByteWidth
58+
);
59+
}
60+
61+
MMBitmapRef bitmap = createMMBitmap(buffer,
62+
rect.size.width * pixelDensity,
63+
rect.size.height * pixelDensity,
64+
expectedByteWidth,
65+
CGImageGetBitsPerPixel(image),
66+
CGImageGetBitsPerPixel(image) / 8);
67+
68+
CFRelease(imageData);
69+
CGImageRelease(image);
70+
71+
return bitmap;
72+
} else {
73+
uint8_t *buffer = malloc(bufferSize);
74+
CFDataGetBytes(imageData, CFRangeMake(0, bufferSize), buffer);
75+
MMBitmapRef bitmap = createMMBitmap(buffer,
76+
CGImageGetWidth(image),
77+
CGImageGetHeight(image),
78+
CGImageGetBytesPerRow(image),
79+
CGImageGetBitsPerPixel(image),
80+
CGImageGetBitsPerPixel(image) / 8);
81+
82+
CFRelease(imageData);
83+
84+
CGImageRelease(image);
85+
86+
return bitmap;
87+
}
88+
}

0 commit comments

Comments
 (0)