framebuffer_service.c revision c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435
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
17dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdlib.h>
18dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdio.h>
19dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <unistd.h>
20dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <string.h>
21dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <fcntl.h>
22dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
23414ff7d98ac8d7610a26206335954ad15f43f3acDavid 'Digit' Turner#include "fdevent.h"
24dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "adb.h"
25dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
26dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <linux/fb.h>
27dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/ioctl.h>
28dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/mman.h>
29dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
30dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* TODO:
31dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** - sync with vsync to avoid tearing
32dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project*/
33154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin/* This version number defines the format of the fbinfo struct.
34154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin   It must match versioning in ddms where this data is consumed. */
35154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin#define DDMS_RAWIMAGE_VERSION 1
36154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavinstruct fbinfo {
37154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin    unsigned int version;
38154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin    unsigned int bpp;
39154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin    unsigned int size;
40154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin    unsigned int width;
41154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin    unsigned int height;
42154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin    unsigned int red_offset;
43154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin    unsigned int red_length;
44154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin    unsigned int blue_offset;
45154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin    unsigned int blue_length;
46154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin    unsigned int green_offset;
47154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin    unsigned int green_length;
48154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin    unsigned int alpha_offset;
49154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin    unsigned int alpha_length;
50154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin} __attribute__((packed));
51dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
52dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid framebuffer_service(int fd, void *cookie)
53dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
54154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin    struct fbinfo fbinfo;
550715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian    unsigned int i;
560715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian    char buf[640];
570715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian    int fd_screencap;
580715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian    int w, h, f;
590715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian    int fds[2];
600715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian
610715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian    if (pipe(fds) < 0) goto done;
620715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian
630715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian    pid_t pid = fork();
640715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian    if (pid < 0) goto done;
650715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian
660715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian    if (pid == 0) {
670715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian        dup2(fds[1], STDOUT_FILENO);
680715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian        close(fds[0]);
690715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian        close(fds[1]);
700715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian        const char* command = "screencap";
710715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian        const char *args[2] = {command, NULL};
720715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian        execvp(command, (char**)args);
730715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian        exit(1);
740715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian    }
75dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
760715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian    fd_screencap = fds[0];
77dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
780715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian    /* read w, h & format */
790715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian    if(readx(fd_screencap, &w, 4)) goto done;
800715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian    if(readx(fd_screencap, &h, 4)) goto done;
810715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian    if(readx(fd_screencap, &f, 4)) goto done;
8204bee29ad979ca770677338e343869a0d5662cfbRebecca Schultz Zavin
83154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin    fbinfo.version = DDMS_RAWIMAGE_VERSION;
84c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian    /* see hardware/hardware.h */
85c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian    switch (f) {
86c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian        case 1: /* RGBA_8888 */
87c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.bpp = 32;
88c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.size = w * h * 4;
89c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.width = w;
90c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.height = h;
91c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.red_offset = 0;
92c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.red_length = 8;
93c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.green_offset = 8;
94c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.green_length = 8;
95c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.blue_offset = 16;
96c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.blue_length = 8;
97c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.alpha_offset = 24;
98c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.alpha_length = 8;
99c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            break;
100c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian        case 2: /* RGBX_8888 */
101c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.bpp = 32;
102c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.size = w * h * 4;
103c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.width = w;
104c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.height = h;
105c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.red_offset = 0;
106c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.red_length = 8;
107c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.green_offset = 8;
108c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.green_length = 8;
109c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.blue_offset = 16;
110c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.blue_length = 8;
111c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.alpha_offset = 24;
112c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.alpha_length = 0;
113c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            break;
114c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian        case 3: /* RGB_888 */
115c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.bpp = 24;
116c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.size = w * h * 3;
117c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.width = w;
118c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.height = h;
119c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.red_offset = 0;
120c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.red_length = 8;
121c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.green_offset = 8;
122c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.green_length = 8;
123c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.blue_offset = 16;
124c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.blue_length = 8;
125c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.alpha_offset = 24;
126c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.alpha_length = 0;
127c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            break;
128c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian        case 4: /* RGB_565 */
129c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.bpp = 16;
130c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.size = w * h * 2;
131c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.width = w;
132c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.height = h;
133c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.red_offset = 11;
134c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.red_length = 5;
135c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.green_offset = 5;
136c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.green_length = 6;
137c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.blue_offset = 0;
138c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.blue_length = 5;
139c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.alpha_offset = 0;
140c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.alpha_length = 0;
141c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            break;
142c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian        case 5: /* BGRA_8888 */
143c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.bpp = 32;
144c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.size = w * h * 4;
145c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.width = w;
146c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.height = h;
147c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.red_offset = 16;
148c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.red_length = 8;
149c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.green_offset = 8;
150c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.green_length = 8;
151c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.blue_offset = 0;
152c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.blue_length = 8;
153c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.alpha_offset = 24;
154c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            fbinfo.alpha_length = 8;
155c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian           break;
156c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian        default:
157c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian            goto done;
158c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian    }
1590715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian
1600715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian    /* write header */
161154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin    if(writex(fd, &fbinfo, sizeof(fbinfo))) goto done;
162dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1630715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian    /* write data */
1640715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian    for(i = 0; i < fbinfo.size; i += sizeof(buf)) {
1650715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian      if(readx(fd_screencap, buf, sizeof(buf))) goto done;
1660715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian      if(writex(fd, buf, sizeof(buf))) goto done;
167dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1680715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian    if(readx(fd_screencap, buf, fbinfo.size % sizeof(buf))) goto done;
1690715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian    if(writex(fd, buf, fbinfo.size % sizeof(buf))) goto done;
17004bee29ad979ca770677338e343869a0d5662cfbRebecca Schultz Zavin
171dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectdone:
1720715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian    close(fds[0]);
1730715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian    close(fds[1]);
174dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    close(fd);
175dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
176