Skip to content

Commit df43057

Browse files
author
BoboTiG
committed
[test] GNU/Linux fully functional + add test-raw.py
1 parent c2c1871 commit df43057

File tree

5 files changed

+154
-19
lines changed

5 files changed

+154
-19
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ tests/
44
MANIFEST*
55
*.png
66
*.png.old
7+
*.raw

mss.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,11 @@ def debug(self, method='', scalar=None, value=None):
134134
print('{}() {} {} {}'.format(method, scalar,
135135
type(value).__name__, value))
136136

137+
def init(self):
138+
''' OS dependent initialiations. '''
139+
140+
pass
141+
137142
def enum_display_monitors(self):
138143
''' Get positions of all monitors.
139144

test/test-linux

1 KB
Binary file not shown.

test/test-linux.c

Lines changed: 90 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
/*
33
* This is the MSS python's module implementation in C.
44
*
5-
* Build: gcc -O3 -lX11 test-linux.c -o test-linux
6-
* Test : python test-raw.py test-linux.raw largeur hauteur
5+
* Build: gcc -O3 -lX11 -lXrandr test-linux.c -o test-linux
6+
* Test : python test-raw.py data.raw width height
77
*
88
* http://cgit.freedesktop.org/xorg/lib/libX11/tree/src/ImUtil.c#n444
99
*
@@ -13,8 +13,9 @@
1313
#include <stdio.h>
1414
#include <time.h>
1515
#include <X11/Xlib.h>
16+
#include <X11/extensions/Xrandr.h>
1617

17-
int main(void) {
18+
void full_screen(void) {
1819
struct timeval start, end;
1920
Display *display;
2021
Window screen, root;
@@ -39,20 +40,20 @@ int main(void) {
3940
image = XGetImage(display, root, left, top, width, height, allplanes, ZPixmap);
4041
pixels = malloc(sizeof(unsigned char) * width * height * 3);
4142

42-
//~ printf("display = %d\n", display);
43-
//~ printf("screen = %d\n", screen);
44-
//~ printf("root = %d\n", root);
45-
//~ printf("left = %d\n", left);
46-
//~ printf("top = %d\n", top);
47-
//~ printf("width = %d\n", width);
48-
//~ printf("height = %d\n", height);
49-
//~ printf("allplanes = %u\n", allplanes);
50-
//~ printf("bits_per_pixel = %d\n", image->bits_per_pixel);
51-
//~ printf("bytes_per_line = %d\n", image->bytes_per_line);
52-
//~ printf("depth = %d\n", image->depth);
43+
/*printf("display = %d\n", display);
44+
printf("screen = %d\n", screen);
45+
printf("root = %d\n", root);
46+
printf("left = %d\n", left);
47+
printf("top = %d\n", top);
48+
printf("width = %d\n", width);
49+
printf("height = %d\n", height);
50+
printf("allplanes = %u\n", allplanes);
51+
printf("bits_per_pixel = %d\n", image->bits_per_pixel);
52+
printf("bytes_per_line = %d\n", image->bytes_per_line);
53+
printf("depth = %d\n", image->depth);
54+
*/
5355

5456
// Processus habituel
55-
//~ /*
5657
for ( x = 0; x < width; ++x ) {
5758
for ( y = 0; y < height; ++y ) {
5859
pixel = XGetPixel(image, x, y);
@@ -62,7 +63,6 @@ int main(void) {
6263
pixels[x * 3 + offset + 2] = pixel & image->blue_mask;
6364
}
6465
}
65-
//~ */
6666

6767
// Processus sans passer par XGetPixel (pas vraiment mieux...)
6868
/*
@@ -90,16 +90,87 @@ int main(void) {
9090
pixels[x * 3 + offset + 2] = pixel & image->blue_mask;
9191
}
9292
}
93-
//~ */
93+
*/
9494

9595
XFree(image);
9696
XCloseDisplay(display);
9797

9898
gettimeofday(&end, NULL);
99-
printf("Time : %u msec\n", (1000000 * end.tv_sec + end.tv_usec) - (1000000 * start.tv_sec + start.tv_usec));
99+
printf("Fullscreen: %dx%d %u msec\n", width, height, (1000000 * end.tv_sec + end.tv_usec) - (1000000 * start.tv_sec + start.tv_usec));
100100

101-
FILE* fh = fopen("test-linux.raw", "wb");
101+
FILE* fh = fopen("test-linux_fullscreen.raw", "wb");
102102
fwrite(pixels, sizeof(unsigned char), sizeof(unsigned char) * width * height * 3, fh);
103103
fclose(fh);
104+
return;
105+
}
106+
107+
void each_screen(void) {
108+
struct timeval start, end;
109+
Display *display;
110+
Window root;
111+
XRRScreenResources *monitors;
112+
XRRCrtcInfo *crtc_info;
113+
XWindowAttributes gwa;
114+
XImage *image;
115+
int left, top;
116+
unsigned int n, x, y, width, height, offset;
117+
unsigned long allplanes, pixel;
118+
unsigned char *pixels;
119+
120+
display = XOpenDisplay(NULL);
121+
root = XDefaultRootWindow(display);
122+
monitors = XRRGetScreenResources(display, root);
123+
for ( n = 0; n < monitors->noutput - 1; ++n ) {
124+
gettimeofday(&start, NULL);
125+
crtc_info = XRRGetCrtcInfo(display, monitors, monitors->crtcs[n]);
126+
127+
/*printf("motior n°%d\n", n);
128+
printf(" x = %d\n", crtc_info->x);
129+
printf(" y = %d\n", crtc_info->y);
130+
printf(" width = %d\n", crtc_info->width);
131+
printf(" height = %d\n", crtc_info->height);
132+
printf(" mode = %d\n", crtc_info->mode);
133+
printf(" rotation = %d\n", crtc_info->rotation);*/
134+
135+
XGetWindowAttributes(display, root, &gwa);
136+
left = crtc_info->x;
137+
top = crtc_info->y;
138+
width = crtc_info->width;
139+
height = crtc_info->height;
140+
allplanes = XAllPlanes();
141+
image = XGetImage(display, root, left, top, width, height, allplanes, ZPixmap);
142+
pixels = malloc(sizeof(unsigned char) * width * height * 3);
143+
144+
for ( x = 0; x < width; ++x ) {
145+
for ( y = 0; y < height; ++y ) {
146+
pixel = XGetPixel(image, x, y);
147+
offset = width * y * 3;
148+
pixels[x * 3 + offset] = (pixel & image->red_mask) >> 16;
149+
pixels[x * 3 + offset + 1] = (pixel & image->green_mask) >> 8;
150+
pixels[x * 3 + offset + 2] = pixel & image->blue_mask;
151+
}
152+
}
153+
XFree(image);
154+
155+
gettimeofday(&end, NULL);
156+
printf("Screen %d: %dx%d @ %u msec\n", n, width, height, (1000000 * end.tv_sec + end.tv_usec) - (1000000 * start.tv_sec + start.tv_usec));
157+
158+
char output[128];
159+
sprintf(output, "test-linux_screen-%d.raw", n);
160+
FILE* fh = fopen(output, "wb");
161+
fwrite(pixels, sizeof(unsigned char), sizeof(unsigned char) * width * height * 3, fh);
162+
fclose(fh);
163+
}
164+
XCloseDisplay(display);
165+
166+
return;
167+
}
168+
169+
int main(void) {
170+
printf("To test raw data: python test-raw.py data.raw width height\n\n");
171+
/* The full screen capture */
172+
full_screen();
173+
/* A capture for each screen */
174+
each_screen();
104175
return 0;
105176
}

test/test-raw.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
#!/usr/bin/env python
2+
# -*- coding: utf-8 -*-
3+
4+
# Test raw data.
5+
6+
from struct import pack
7+
import os.path
8+
import zlib
9+
import sys
10+
11+
12+
def save_img(data, width, height, output):
13+
''' Dump data to the image file.
14+
Pure python PNG implementation.
15+
Image represented as RGB tuples, no interlacing.
16+
http://inaps.org/journal/comment-fonctionne-le-png
17+
'''
18+
19+
to_take = (width * 3 + 3) & -4
20+
padding = 0 if to_take % 8 == 0 else (to_take % 8) // 2
21+
scanlines = b''.join(
22+
[b'0' + data[(y * to_take):(y * to_take) + to_take - padding]
23+
for y in range(height)])
24+
25+
magic = pack(b'>8B', 137, 80, 78, 71, 13, 10, 26, 10)
26+
27+
# Header: size, marker, data, CRC32
28+
ihdr = [b'', b'IHDR', b'', b'']
29+
ihdr[2] = pack(b'>2I5B', width, height, 8, 2, 0, 0, 0)
30+
ihdr[3] = pack(b'>I', zlib.crc32(b''.join(ihdr[1:3])) & 0xffffffff)
31+
ihdr[0] = pack(b'>I', len(ihdr[2]))
32+
33+
# Data: size, marker, data, CRC32
34+
idat = [b'', b'IDAT', b'', b'']
35+
idat[2] = zlib.compress(scanlines, 9)
36+
idat[3] = pack(b'>I', zlib.crc32(b''.join(idat[1:3])) & 0xffffffff)
37+
idat[0] = pack(b'>I', len(idat[2]))
38+
39+
# Footer: size, marker, None, CRC32
40+
iend = [b'', b'IEND', b'', b'']
41+
iend[3] = pack(b'>I', zlib.crc32(iend[1]) & 0xffffffff)
42+
iend[0] = pack(b'>I', len(iend[2]))
43+
44+
with open(output, 'wb') as fileh:
45+
fileh.write(
46+
magic + b''.join(ihdr) + b''.join(idat) + b''.join(iend))
47+
if not os.path.isfile(output):
48+
msg = 'Impossible to write data to file "{}".'.format(output)
49+
raise ScreenshotError(msg)
50+
51+
if len(sys.argv) < 4:
52+
print('python {0} data.raw width height'.format(sys.argv[0]))
53+
else:
54+
with open(sys.argv[1], 'rb') as f:
55+
data = f.read()
56+
width = int(sys.argv[2])
57+
height = int(sys.argv[3])
58+
save_img(data, width, height, sys.argv[1] + '.png')

0 commit comments

Comments
 (0)