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 23 #include "fdevent.h" 24 #include "adb.h" 25 26 #include <linux/fb.h> 27 #include <sys/ioctl.h> 28 #include <sys/mman.h> 29 30 /* TODO: 31 ** - sync with vsync to avoid tearing 32 */ 33 /* This version number defines the format of the fbinfo struct. 34 It must match versioning in ddms where this data is consumed. */ 35 #define DDMS_RAWIMAGE_VERSION 1 36 struct fbinfo { 37 unsigned int version; 38 unsigned int bpp; 39 unsigned int size; 40 unsigned int width; 41 unsigned int height; 42 unsigned int red_offset; 43 unsigned int red_length; 44 unsigned int blue_offset; 45 unsigned int blue_length; 46 unsigned int green_offset; 47 unsigned int green_length; 48 unsigned int alpha_offset; 49 unsigned int alpha_length; 50 } __attribute__((packed)); 51 52 void framebuffer_service(int fd, void *cookie) 53 { 54 struct fbinfo fbinfo; 55 unsigned int i; 56 char buf[640]; 57 int fd_screencap; 58 int w, h, f; 59 int fds[2]; 60 61 if (pipe(fds) < 0) goto done; 62 63 pid_t pid = fork(); 64 if (pid < 0) goto done; 65 66 if (pid == 0) { 67 dup2(fds[1], STDOUT_FILENO); 68 close(fds[0]); 69 close(fds[1]); 70 const char* command = "screencap"; 71 const char *args[2] = {command, NULL}; 72 execvp(command, (char**)args); 73 exit(1); 74 } 75 76 fd_screencap = fds[0]; 77 78 /* read w, h & format */ 79 if(readx(fd_screencap, &w, 4)) goto done; 80 if(readx(fd_screencap, &h, 4)) goto done; 81 if(readx(fd_screencap, &f, 4)) goto done; 82 83 fbinfo.version = DDMS_RAWIMAGE_VERSION; 84 /* see hardware/hardware.h */ 85 switch (f) { 86 case 1: /* RGBA_8888 */ 87 fbinfo.bpp = 32; 88 fbinfo.size = w * h * 4; 89 fbinfo.width = w; 90 fbinfo.height = h; 91 fbinfo.red_offset = 0; 92 fbinfo.red_length = 8; 93 fbinfo.green_offset = 8; 94 fbinfo.green_length = 8; 95 fbinfo.blue_offset = 16; 96 fbinfo.blue_length = 8; 97 fbinfo.alpha_offset = 24; 98 fbinfo.alpha_length = 8; 99 break; 100 case 2: /* RGBX_8888 */ 101 fbinfo.bpp = 32; 102 fbinfo.size = w * h * 4; 103 fbinfo.width = w; 104 fbinfo.height = h; 105 fbinfo.red_offset = 0; 106 fbinfo.red_length = 8; 107 fbinfo.green_offset = 8; 108 fbinfo.green_length = 8; 109 fbinfo.blue_offset = 16; 110 fbinfo.blue_length = 8; 111 fbinfo.alpha_offset = 24; 112 fbinfo.alpha_length = 0; 113 break; 114 case 3: /* RGB_888 */ 115 fbinfo.bpp = 24; 116 fbinfo.size = w * h * 3; 117 fbinfo.width = w; 118 fbinfo.height = h; 119 fbinfo.red_offset = 0; 120 fbinfo.red_length = 8; 121 fbinfo.green_offset = 8; 122 fbinfo.green_length = 8; 123 fbinfo.blue_offset = 16; 124 fbinfo.blue_length = 8; 125 fbinfo.alpha_offset = 24; 126 fbinfo.alpha_length = 0; 127 break; 128 case 4: /* RGB_565 */ 129 fbinfo.bpp = 16; 130 fbinfo.size = w * h * 2; 131 fbinfo.width = w; 132 fbinfo.height = h; 133 fbinfo.red_offset = 11; 134 fbinfo.red_length = 5; 135 fbinfo.green_offset = 5; 136 fbinfo.green_length = 6; 137 fbinfo.blue_offset = 0; 138 fbinfo.blue_length = 5; 139 fbinfo.alpha_offset = 0; 140 fbinfo.alpha_length = 0; 141 break; 142 case 5: /* BGRA_8888 */ 143 fbinfo.bpp = 32; 144 fbinfo.size = w * h * 4; 145 fbinfo.width = w; 146 fbinfo.height = h; 147 fbinfo.red_offset = 16; 148 fbinfo.red_length = 8; 149 fbinfo.green_offset = 8; 150 fbinfo.green_length = 8; 151 fbinfo.blue_offset = 0; 152 fbinfo.blue_length = 8; 153 fbinfo.alpha_offset = 24; 154 fbinfo.alpha_length = 8; 155 break; 156 default: 157 goto done; 158 } 159 160 /* write header */ 161 if(writex(fd, &fbinfo, sizeof(fbinfo))) goto done; 162 163 /* write data */ 164 for(i = 0; i < fbinfo.size; i += sizeof(buf)) { 165 if(readx(fd_screencap, buf, sizeof(buf))) goto done; 166 if(writex(fd, buf, sizeof(buf))) goto done; 167 } 168 if(readx(fd_screencap, buf, fbinfo.size % sizeof(buf))) goto done; 169 if(writex(fd, buf, fbinfo.size % sizeof(buf))) goto done; 170 171 done: 172 close(fds[0]); 173 close(fds[1]); 174 close(fd); 175 } 176