Home | History | Annotate | Download | only in adb
      1 /*
      2  * Copyright (C) 2007 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include <stdlib.h>
     18 #include <stdio.h>
     19 #include <unistd.h>
     20 #include <string.h>
     21 #include <fcntl.h>
     22 #include <errno.h>
     23 #include <sys/types.h>
     24 #include <sys/wait.h>
     25 
     26 #include "fdevent.h"
     27 #include "adb.h"
     28 
     29 #include <linux/fb.h>
     30 #include <sys/ioctl.h>
     31 #include <sys/mman.h>
     32 
     33 /* TODO:
     34 ** - sync with vsync to avoid tearing
     35 */
     36 /* This version number defines the format of the fbinfo struct.
     37    It must match versioning in ddms where this data is consumed. */
     38 #define DDMS_RAWIMAGE_VERSION 1
     39 struct fbinfo {
     40     unsigned int version;
     41     unsigned int bpp;
     42     unsigned int size;
     43     unsigned int width;
     44     unsigned int height;
     45     unsigned int red_offset;
     46     unsigned int red_length;
     47     unsigned int blue_offset;
     48     unsigned int blue_length;
     49     unsigned int green_offset;
     50     unsigned int green_length;
     51     unsigned int alpha_offset;
     52     unsigned int alpha_length;
     53 } __attribute__((packed));
     54 
     55 void framebuffer_service(int fd, void *cookie)
     56 {
     57     struct fbinfo fbinfo;
     58     unsigned int i;
     59     char buf[640];
     60     int fd_screencap;
     61     int w, h, f;
     62     int fds[2];
     63 
     64     if (pipe(fds) < 0) goto done;
     65 
     66     pid_t pid = fork();
     67     if (pid < 0) goto done;
     68 
     69     if (pid == 0) {
     70         dup2(fds[1], STDOUT_FILENO);
     71         close(fds[0]);
     72         close(fds[1]);
     73         const char* command = "screencap";
     74         const char *args[2] = {command, NULL};
     75         execvp(command, (char**)args);
     76         exit(1);
     77     }
     78 
     79     fd_screencap = fds[0];
     80 
     81     /* read w, h & format */
     82     if(readx(fd_screencap, &w, 4)) goto done;
     83     if(readx(fd_screencap, &h, 4)) goto done;
     84     if(readx(fd_screencap, &f, 4)) goto done;
     85 
     86     fbinfo.version = DDMS_RAWIMAGE_VERSION;
     87     /* see hardware/hardware.h */
     88     switch (f) {
     89         case 1: /* RGBA_8888 */
     90             fbinfo.bpp = 32;
     91             fbinfo.size = w * h * 4;
     92             fbinfo.width = w;
     93             fbinfo.height = h;
     94             fbinfo.red_offset = 0;
     95             fbinfo.red_length = 8;
     96             fbinfo.green_offset = 8;
     97             fbinfo.green_length = 8;
     98             fbinfo.blue_offset = 16;
     99             fbinfo.blue_length = 8;
    100             fbinfo.alpha_offset = 24;
    101             fbinfo.alpha_length = 8;
    102             break;
    103         case 2: /* RGBX_8888 */
    104             fbinfo.bpp = 32;
    105             fbinfo.size = w * h * 4;
    106             fbinfo.width = w;
    107             fbinfo.height = h;
    108             fbinfo.red_offset = 0;
    109             fbinfo.red_length = 8;
    110             fbinfo.green_offset = 8;
    111             fbinfo.green_length = 8;
    112             fbinfo.blue_offset = 16;
    113             fbinfo.blue_length = 8;
    114             fbinfo.alpha_offset = 24;
    115             fbinfo.alpha_length = 0;
    116             break;
    117         case 3: /* RGB_888 */
    118             fbinfo.bpp = 24;
    119             fbinfo.size = w * h * 3;
    120             fbinfo.width = w;
    121             fbinfo.height = h;
    122             fbinfo.red_offset = 0;
    123             fbinfo.red_length = 8;
    124             fbinfo.green_offset = 8;
    125             fbinfo.green_length = 8;
    126             fbinfo.blue_offset = 16;
    127             fbinfo.blue_length = 8;
    128             fbinfo.alpha_offset = 24;
    129             fbinfo.alpha_length = 0;
    130             break;
    131         case 4: /* RGB_565 */
    132             fbinfo.bpp = 16;
    133             fbinfo.size = w * h * 2;
    134             fbinfo.width = w;
    135             fbinfo.height = h;
    136             fbinfo.red_offset = 11;
    137             fbinfo.red_length = 5;
    138             fbinfo.green_offset = 5;
    139             fbinfo.green_length = 6;
    140             fbinfo.blue_offset = 0;
    141             fbinfo.blue_length = 5;
    142             fbinfo.alpha_offset = 0;
    143             fbinfo.alpha_length = 0;
    144             break;
    145         case 5: /* BGRA_8888 */
    146             fbinfo.bpp = 32;
    147             fbinfo.size = w * h * 4;
    148             fbinfo.width = w;
    149             fbinfo.height = h;
    150             fbinfo.red_offset = 16;
    151             fbinfo.red_length = 8;
    152             fbinfo.green_offset = 8;
    153             fbinfo.green_length = 8;
    154             fbinfo.blue_offset = 0;
    155             fbinfo.blue_length = 8;
    156             fbinfo.alpha_offset = 24;
    157             fbinfo.alpha_length = 8;
    158            break;
    159         default:
    160             goto done;
    161     }
    162 
    163     /* write header */
    164     if(writex(fd, &fbinfo, sizeof(fbinfo))) goto done;
    165 
    166     /* write data */
    167     for(i = 0; i < fbinfo.size; i += sizeof(buf)) {
    168       if(readx(fd_screencap, buf, sizeof(buf))) goto done;
    169       if(writex(fd, buf, sizeof(buf))) goto done;
    170     }
    171     if(readx(fd_screencap, buf, fbinfo.size % sizeof(buf))) goto done;
    172     if(writex(fd, buf, fbinfo.size % sizeof(buf))) goto done;
    173 
    174 done:
    175     TEMP_FAILURE_RETRY(waitpid(pid, NULL, 0));
    176 
    177     close(fds[0]);
    178     close(fds[1]);
    179     close(fd);
    180 }
    181