framebuffer_service.c revision 0715f91223b2f7a91ea08bfa95998d846e7977cf
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
830715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian    /* for now always assume RGBX_8888 format */
84154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin    fbinfo.version = DDMS_RAWIMAGE_VERSION;
850715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian    fbinfo.bpp = 32;
860715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian    fbinfo.size = w * h * 4;
870715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian    fbinfo.width = w;
880715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian    fbinfo.height = h;
890715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian    fbinfo.red_offset = 0;
900715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian    fbinfo.red_length = 8;
910715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian    fbinfo.green_offset = 8;
920715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian    fbinfo.green_length = 8;
930715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian    fbinfo.blue_offset = 16;
940715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian    fbinfo.blue_length = 8;
950715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian    fbinfo.alpha_offset = 24;
960715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian    fbinfo.alpha_length = 8;
970715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian
980715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian    /* write header */
99154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin    if(writex(fd, &fbinfo, sizeof(fbinfo))) goto done;
100dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1010715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian    /* write data */
1020715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian    for(i = 0; i < fbinfo.size; i += sizeof(buf)) {
1030715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian      if(readx(fd_screencap, buf, sizeof(buf))) goto done;
1040715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian      if(writex(fd, buf, sizeof(buf))) goto done;
105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1060715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian    if(readx(fd_screencap, buf, fbinfo.size % sizeof(buf))) goto done;
1070715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian    if(writex(fd, buf, fbinfo.size % sizeof(buf))) goto done;
10804bee29ad979ca770677338e343869a0d5662cfbRebecca Schultz Zavin
109dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectdone:
1100715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian    close(fds[0]);
1110715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian    close(fds[1]);
112dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    close(fd);
113dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
114