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> 225a536efa5b5f5d973232846d5fe6818df84ab5dcYuriy Zabroda#include <errno.h> 235a536efa5b5f5d973232846d5fe6818df84ab5dcYuriy Zabroda#include <sys/types.h> 245a536efa5b5f5d973232846d5fe6818df84ab5dcYuriy Zabroda#include <sys/wait.h> 25dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 26414ff7d98ac8d7610a26206335954ad15f43f3acDavid 'Digit' Turner#include "fdevent.h" 27dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "adb.h" 28dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 29dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <linux/fb.h> 30dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/ioctl.h> 31dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/mman.h> 32dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 33dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* TODO: 34dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** - sync with vsync to avoid tearing 35dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project*/ 36154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin/* This version number defines the format of the fbinfo struct. 37154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin It must match versioning in ddms where this data is consumed. */ 38154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin#define DDMS_RAWIMAGE_VERSION 1 39154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavinstruct fbinfo { 40154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin unsigned int version; 41154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin unsigned int bpp; 42154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin unsigned int size; 43154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin unsigned int width; 44154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin unsigned int height; 45154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin unsigned int red_offset; 46154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin unsigned int red_length; 47154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin unsigned int blue_offset; 48154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin unsigned int blue_length; 49154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin unsigned int green_offset; 50154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin unsigned int green_length; 51154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin unsigned int alpha_offset; 52154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin unsigned int alpha_length; 53154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin} __attribute__((packed)); 54dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 55dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid framebuffer_service(int fd, void *cookie) 56dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 57154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin struct fbinfo fbinfo; 5885373f42803f86e3295afd5031a0e42e0b3bef33Chris Dearman unsigned int i, bsize; 590715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian char buf[640]; 600715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian int fd_screencap; 610715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian int w, h, f; 620715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian int fds[2]; 630715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian 648fcb631389123ab7f5d795ae3a36a67842b3028cNick Kralevich if (pipe2(fds, O_CLOEXEC) < 0) goto pipefail; 650715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian 660715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian pid_t pid = fork(); 670715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian if (pid < 0) goto done; 680715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian 690715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian if (pid == 0) { 700715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian dup2(fds[1], STDOUT_FILENO); 710715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian close(fds[0]); 720715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian close(fds[1]); 730715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian const char* command = "screencap"; 740715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian const char *args[2] = {command, NULL}; 750715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian execvp(command, (char**)args); 760715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian exit(1); 770715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian } 78dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 790715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian fd_screencap = fds[0]; 80dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 810715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian /* read w, h & format */ 820715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian if(readx(fd_screencap, &w, 4)) goto done; 830715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian if(readx(fd_screencap, &h, 4)) goto done; 840715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian if(readx(fd_screencap, &f, 4)) goto done; 8504bee29ad979ca770677338e343869a0d5662cfbRebecca Schultz Zavin 86154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin fbinfo.version = DDMS_RAWIMAGE_VERSION; 87c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian /* see hardware/hardware.h */ 88c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian switch (f) { 89c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian case 1: /* RGBA_8888 */ 90c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian fbinfo.bpp = 32; 91c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian fbinfo.size = w * h * 4; 92c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian fbinfo.width = w; 93c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian fbinfo.height = h; 94c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian fbinfo.red_offset = 0; 95c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian fbinfo.red_length = 8; 96c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian fbinfo.green_offset = 8; 97c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian fbinfo.green_length = 8; 98c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian fbinfo.blue_offset = 16; 99c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian fbinfo.blue_length = 8; 100c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian fbinfo.alpha_offset = 24; 101c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian fbinfo.alpha_length = 8; 102c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian break; 103c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian case 2: /* RGBX_8888 */ 104c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian fbinfo.bpp = 32; 105c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian fbinfo.size = w * h * 4; 106c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian fbinfo.width = w; 107c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian fbinfo.height = h; 108c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian fbinfo.red_offset = 0; 109c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian fbinfo.red_length = 8; 110c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian fbinfo.green_offset = 8; 111c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian fbinfo.green_length = 8; 112c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian fbinfo.blue_offset = 16; 113c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian fbinfo.blue_length = 8; 114c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian fbinfo.alpha_offset = 24; 115c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian fbinfo.alpha_length = 0; 116c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian break; 117c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian case 3: /* RGB_888 */ 118c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian fbinfo.bpp = 24; 119c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian fbinfo.size = w * h * 3; 120c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian fbinfo.width = w; 121c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian fbinfo.height = h; 122c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian fbinfo.red_offset = 0; 123c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian fbinfo.red_length = 8; 124c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian fbinfo.green_offset = 8; 125c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian fbinfo.green_length = 8; 126c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian fbinfo.blue_offset = 16; 127c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian fbinfo.blue_length = 8; 128c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian fbinfo.alpha_offset = 24; 129c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian fbinfo.alpha_length = 0; 130c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian break; 131c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian case 4: /* RGB_565 */ 132c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian fbinfo.bpp = 16; 133c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian fbinfo.size = w * h * 2; 134c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian fbinfo.width = w; 135c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian fbinfo.height = h; 136c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian fbinfo.red_offset = 11; 137c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian fbinfo.red_length = 5; 138c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian fbinfo.green_offset = 5; 139c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian fbinfo.green_length = 6; 140c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian fbinfo.blue_offset = 0; 141c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian fbinfo.blue_length = 5; 142c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian fbinfo.alpha_offset = 0; 143c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian fbinfo.alpha_length = 0; 144c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian break; 145c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian case 5: /* BGRA_8888 */ 146c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian fbinfo.bpp = 32; 147c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian fbinfo.size = w * h * 4; 148c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian fbinfo.width = w; 149c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian fbinfo.height = h; 150c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian fbinfo.red_offset = 16; 151c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian fbinfo.red_length = 8; 152c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian fbinfo.green_offset = 8; 153c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian fbinfo.green_length = 8; 154c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian fbinfo.blue_offset = 0; 155c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian fbinfo.blue_length = 8; 156c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian fbinfo.alpha_offset = 24; 157c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian fbinfo.alpha_length = 8; 158c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian break; 159c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian default: 160c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian goto done; 161c1fbf7c1638cb4f1f139edf74562fcfbaa6f3435Mathias Agopian } 1620715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian 1630715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian /* write header */ 164154b7d7de4071ed73cde81eef3af47d1a24d7c6bRebecca Schultz Zavin if(writex(fd, &fbinfo, sizeof(fbinfo))) goto done; 165dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1660715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian /* write data */ 16785373f42803f86e3295afd5031a0e42e0b3bef33Chris Dearman for(i = 0; i < fbinfo.size; i += bsize) { 16885373f42803f86e3295afd5031a0e42e0b3bef33Chris Dearman bsize = sizeof(buf); 16985373f42803f86e3295afd5031a0e42e0b3bef33Chris Dearman if (i + bsize > fbinfo.size) 17085373f42803f86e3295afd5031a0e42e0b3bef33Chris Dearman bsize = fbinfo.size - i; 17185373f42803f86e3295afd5031a0e42e0b3bef33Chris Dearman if(readx(fd_screencap, buf, bsize)) goto done; 17285373f42803f86e3295afd5031a0e42e0b3bef33Chris Dearman if(writex(fd, buf, bsize)) goto done; 173dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 17404bee29ad979ca770677338e343869a0d5662cfbRebecca Schultz Zavin 175dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectdone: 1765a536efa5b5f5d973232846d5fe6818df84ab5dcYuriy Zabroda TEMP_FAILURE_RETRY(waitpid(pid, NULL, 0)); 1775a536efa5b5f5d973232846d5fe6818df84ab5dcYuriy Zabroda 1780715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian close(fds[0]); 1790715f91223b2f7a91ea08bfa95998d846e7977cfMathias Agopian close(fds[1]); 18085373f42803f86e3295afd5031a0e42e0b3bef33Chris Dearmanpipefail: 181dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project close(fd); 182dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 183