1dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
2dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
3dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *
4dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * you may not use this file except in compliance with the License.
6dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * You may obtain a copy of the License at
7dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *
8dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *
10dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * See the License for the specific language governing permissions and
14dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * limitations under the License.
15dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
16dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
177664901a355b959f312e9acff5a0fd31b7139623Dan Albert#include <errno.h>
187664901a355b959f312e9acff5a0fd31b7139623Dan Albert#include <fcntl.h>
197664901a355b959f312e9acff5a0fd31b7139623Dan Albert#include <linux/fb.h>
20dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdio.h>
217664901a355b959f312e9acff5a0fd31b7139623Dan Albert#include <stdlib.h>
22dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <string.h>
237664901a355b959f312e9acff5a0fd31b7139623Dan Albert#include <sys/ioctl.h>
247664901a355b959f312e9acff5a0fd31b7139623Dan Albert#include <sys/mman.h>
255a536efa5b5f5d973232846d5fe6818df84ab5dcYuriy Zabroda#include <sys/types.h>
265a536efa5b5f5d973232846d5fe6818df84ab5dcYuriy Zabroda#include <sys/wait.h>
277664901a355b959f312e9acff5a0fd31b7139623Dan Albert#include <unistd.h>
28dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
297664901a355b959f312e9acff5a0fd31b7139623Dan Albert#include "sysdeps.h"
30dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
317664901a355b959f312e9acff5a0fd31b7139623Dan Albert#include "adb.h"
32cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert#include "adb_io.h"
337664901a355b959f312e9acff5a0fd31b7139623Dan Albert#include "fdevent.h"
34dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
35dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* TODO:
36dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** - sync with vsync to avoid tearing
37dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project*/
38154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin/* This version number defines the format of the fbinfo struct.
39154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin   It must match versioning in ddms where this data is consumed. */
40154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin#define DDMS_RAWIMAGE_VERSION 1
41154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavinstruct fbinfo {
42154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin    unsigned int version;
43154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin    unsigned int bpp;
44154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin    unsigned int size;
45154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin    unsigned int width;
46154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin    unsigned int height;
47154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin    unsigned int red_offset;
48154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin    unsigned int red_length;
49154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin    unsigned int blue_offset;
50154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin    unsigned int blue_length;
51154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin    unsigned int green_offset;
52154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin    unsigned int green_length;
53154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin    unsigned int alpha_offset;
54154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin    unsigned int alpha_length;
55154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin} __attribute__((packed));
56dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
57dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid framebuffer_service(int fd, void *cookie)
58dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
59154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin    struct fbinfo fbinfo;
6085373f42803f86e3295afd5031a0e42e0b3bef33Chris Dearman    unsigned int i, bsize;
610715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian    char buf[640];
620715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian    int fd_screencap;
630715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian    int w, h, f;
640715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian    int fds[2];
65bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert    pid_t pid;
660715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian
678fcb631389123ab7f5d795ae3a36a67842b3028cNick Kralevich    if (pipe2(fds, O_CLOEXEC) < 0) goto pipefail;
680715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian
69bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert    pid = fork();
700715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian    if (pid < 0) goto done;
710715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian
720715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian    if (pid == 0) {
730715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian        dup2(fds[1], STDOUT_FILENO);
747664901a355b959f312e9acff5a0fd31b7139623Dan Albert        adb_close(fds[0]);
757664901a355b959f312e9acff5a0fd31b7139623Dan Albert        adb_close(fds[1]);
760715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian        const char* command = "screencap";
770715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian        const char *args[2] = {command, NULL};
780715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian        execvp(command, (char**)args);
790715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian        exit(1);
800715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian    }
81dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
827664901a355b959f312e9acff5a0fd31b7139623Dan Albert    adb_close(fds[1]);
830715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian    fd_screencap = fds[0];
84dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
850715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian    /* read w, h & format */
86cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert    if(!ReadFdExactly(fd_screencap, &w, 4)) goto done;
87cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert    if(!ReadFdExactly(fd_screencap, &h, 4)) goto done;
88cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert    if(!ReadFdExactly(fd_screencap, &f, 4)) goto done;
8904bee29ad979ca770677338e343869a0d5662cfbRebecca Schultz Zavin
90154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin    fbinfo.version = DDMS_RAWIMAGE_VERSION;
91c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian    /* see hardware/hardware.h */
92c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian    switch (f) {
93c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian        case 1: /* RGBA_8888 */
94c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.bpp = 32;
95c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.size = w * h * 4;
96c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.width = w;
97c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.height = h;
98c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.red_offset = 0;
99c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.red_length = 8;
100c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.green_offset = 8;
101c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.green_length = 8;
102c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.blue_offset = 16;
103c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.blue_length = 8;
104c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.alpha_offset = 24;
105c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.alpha_length = 8;
106c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            break;
107c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian        case 2: /* RGBX_8888 */
108c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.bpp = 32;
109c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.size = w * h * 4;
110c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.width = w;
111c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.height = h;
112c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.red_offset = 0;
113c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.red_length = 8;
114c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.green_offset = 8;
115c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.green_length = 8;
116c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.blue_offset = 16;
117c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.blue_length = 8;
118c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.alpha_offset = 24;
119c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.alpha_length = 0;
120c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            break;
121c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian        case 3: /* RGB_888 */
122c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.bpp = 24;
123c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.size = w * h * 3;
124c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.width = w;
125c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.height = h;
126c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.red_offset = 0;
127c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.red_length = 8;
128c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.green_offset = 8;
129c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.green_length = 8;
130c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.blue_offset = 16;
131c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.blue_length = 8;
132c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.alpha_offset = 24;
133c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.alpha_length = 0;
134c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            break;
135c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian        case 4: /* RGB_565 */
136c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.bpp = 16;
137c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.size = w * h * 2;
138c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.width = w;
139c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.height = h;
140c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.red_offset = 11;
141c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.red_length = 5;
142c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.green_offset = 5;
143c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.green_length = 6;
144c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.blue_offset = 0;
145c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.blue_length = 5;
146c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.alpha_offset = 0;
147c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.alpha_length = 0;
148c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            break;
149c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian        case 5: /* BGRA_8888 */
150c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.bpp = 32;
151c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.size = w * h * 4;
152c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.width = w;
153c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.height = h;
154c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.red_offset = 16;
155c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.red_length = 8;
156c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.green_offset = 8;
157c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.green_length = 8;
158c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.blue_offset = 0;
159c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.blue_length = 8;
160c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.alpha_offset = 24;
161c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.alpha_length = 8;
162c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian           break;
163c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian        default:
164c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            goto done;
165c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian    }
1660715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian
1670715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian    /* write header */
168cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert    if(!WriteFdExactly(fd, &fbinfo, sizeof(fbinfo))) goto done;
169dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1700715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian    /* write data */
17185373f42803f86e3295afd5031a0e42e0b3bef33Chris Dearman    for(i = 0; i < fbinfo.size; i += bsize) {
17285373f42803f86e3295afd5031a0e42e0b3bef33Chris Dearman      bsize = sizeof(buf);
17385373f42803f86e3295afd5031a0e42e0b3bef33Chris Dearman      if (i + bsize > fbinfo.size)
17485373f42803f86e3295afd5031a0e42e0b3bef33Chris Dearman        bsize = fbinfo.size - i;
175cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert      if(!ReadFdExactly(fd_screencap, buf, bsize)) goto done;
176cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert      if(!WriteFdExactly(fd, buf, bsize)) goto done;
177dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
17804bee29ad979ca770677338e343869a0d5662cfbRebecca Schultz Zavin
179dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectdone:
1807664901a355b959f312e9acff5a0fd31b7139623Dan Albert    adb_close(fds[0]);
181cdb1b1b84daa528d078379a7f343177b94e5976eBao Haojun
182cdb1b1b84daa528d078379a7f343177b94e5976eBao Haojun    TEMP_FAILURE_RETRY(waitpid(pid, NULL, 0));
18385373f42803f86e3295afd5031a0e42e0b3bef33Chris Dearmanpipefail:
1847664901a355b959f312e9acff5a0fd31b7139623Dan Albert    adb_close(fd);
185dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
186