blob: afd54cada39e7f300bad05526a39d48ae8dff11e [file] [log] [blame]
Talustus3019a912013-04-06 11:50:07 +02001/*
2 * -- http://android-fb2png.googlecode.com/svn/trunk/adb_screenshoot.c --
3 *
4 * Copyright 2011, Kyan He <kyan.ql.he@gmail.com>
5 *
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#include <stdio.h>
22#include <stdlib.h>
23#include <string.h>
24#include <errno.h>
25#include <netdb.h>
26#include <netinet/in.h>
27
28#include "fb.h"
29#include "log.h"
30
31#define DEFAULT_SAVE_PATH "fbdump.png"
32
33/* defined in $T/system/core/adb/framebuffer_service.c */
34#define DDMS_RAWIMAGE_VERSION 1
35struct fbinfo {
36 unsigned int version;
37 unsigned int bpp;
38 unsigned int size;
39 unsigned int width;
40 unsigned int height;
41 unsigned int red_offset;
42 unsigned int red_length;
43 unsigned int blue_offset;
44 unsigned int blue_length;
45 unsigned int green_offset;
46 unsigned int green_length;
47 unsigned int alpha_offset;
48 unsigned int alpha_length;
49} __attribute__((packed));
50
51static int remote_socket(const char *host, int port)
52{
53 struct sockaddr_in sa;
54 struct hostent *hp;
55 int s;
56
57 if(!(hp = gethostbyname(host))){ return -1; }
58
59 memset(&sa, 0, sizeof(sa));
60 sa.sin_port = htons(port);
61 sa.sin_family = hp->h_addrtype;
62 memcpy((void*) &sa.sin_addr, (void*) hp->h_addr, hp->h_length);
63
64 if((s = socket(hp->h_addrtype, SOCK_STREAM, 0)) < 0) {
65 return -1;
66 }
67
68 if(connect(s, (struct sockaddr*) &sa, sizeof(sa)) != 0){
69 close(s);
70 return -1;
71 }
72
73 return s;
74}
75
76char *target = "usb";
77static int adb_fd;
78
79/**
80 * Write command through adb protocol.
81 * Return
82 * Bytes have been wrote.
83 */
84static int adb_write(const char *cmd)
85{
86 char buf[1024];
87 int sz;
88
89 /* Construct command. */
90 sz = sprintf(buf, "%04x%s", strlen(cmd), cmd);
91
92 write(adb_fd, buf, sz);
93
94#if 0
95 D("<< %s", buf);
96#endif
97 return sz;
98}
99
100/**
101 * Read data through adb protocol.
102 * Return
103 * Bytes have been read.
104 */
105static int adb_read(char *buf, int sz)
106{
107 sz = read(adb_fd, buf, sz);
108 if (sz < 0) {
109 E("Fail to read from adb socket, %s", strerror(errno));
110 }
111 buf[sz] = '\0';
112#if 0
113 D(">> %d", sz);
114#endif
115 return sz;
116}
117
118static int get_fb_from_adb(struct fb *fb)
119{
120 char buf[1024];
121 const struct fbinfo* fbinfo;
122
123 /* Init socket */
124 adb_fd = remote_socket("localhost", 5037);
125 if (adb_fd < 0) {
126 E("Fail to create socket, %s", strerror(errno));
127 }
128
129 adb_write("host:transport-");
130 adb_read(buf, 1024);
131
132 adb_write("framebuffer:");
133 adb_read(buf, 1024);
134
135 /* Parse FB header. */
136 adb_read(buf, sizeof(struct fbinfo));
137 fbinfo = (struct fbinfo*) buf;
138
139 if (fbinfo->version != DDMS_RAWIMAGE_VERSION) {
140 E("unspport adb version");
141 }
142
143 /* Assemble struct fb */
144 memcpy(fb, &fbinfo->bpp, sizeof(struct fbinfo) - 4);
145 fb_dump(fb);
146
147 fb->data = malloc(fb->size);
148 if (!fb->data) return -1;
149
150 /* Read out the whole framebuffer */
151 int bytes_read = 0;
152 while (bytes_read < fb->size) {
153 bytes_read += adb_read(fb->data + bytes_read, fb->size - bytes_read);
154 }
155
156 return 0;
157}
158
159int fb2png(const char* path)
160{
161 struct fb fb;
162
163 if (get_fb_from_adb(&fb)) {
164 D("cannot get framebuffer.");
165 return -1;
166 }
167
168 return fb_save_png(&fb, path);
169}
170
171int main(int argc, char *argv[])
172{
173 char fn[128];
174
175 if (argc == 2) {
176 //if (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")) {
177 if (argv[1][0] == '-') {
178 printf(
179 "Usage: fb2png [path/to/output.png]\n"
180 " The default output path is ./fbdump.png\n"
181 );
182 exit(0);
183 } else {
184 sprintf(fn, "%s", argv[1]);
185 }
186 } else {
187 sprintf(fn, "%s", DEFAULT_SAVE_PATH);
188 }
189
190 return fb2png(fn);
191}