blob: dcea96840cf0d4b90917ae11d926505d3b58e26a [file] [log] [blame]
Mathias Agopian88a5df92010-09-26 18:49:45 -07001/*
2 * Copyright (C) 2010 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
Joe Onorato5cff0632010-12-03 16:01:57 -080017#include <errno.h>
Mathias Agopian88a5df92010-09-26 18:49:45 -070018#include <unistd.h>
Joe Onorato5cff0632010-12-03 16:01:57 -080019#include <stdio.h>
Mathias Agopian88a5df92010-09-26 18:49:45 -070020#include <fcntl.h>
21
Mathias Agopian88a5df92010-09-26 18:49:45 -070022#include <binder/IMemory.h>
Mathias Agopian38ed2e32010-09-29 13:02:36 -070023#include <surfaceflinger/SurfaceComposerClient.h>
Mathias Agopian88a5df92010-09-26 18:49:45 -070024
Joe Onorato5cff0632010-12-03 16:01:57 -080025#include <SkImageEncoder.h>
26#include <SkBitmap.h>
27#include <SkStream.h>
28
Mathias Agopian88a5df92010-09-26 18:49:45 -070029using namespace android;
30
Joe Onorato5cff0632010-12-03 16:01:57 -080031static void usage()
32{
33 fprintf(stderr,
34 "usage: screenshot [-hp] [FILENAME]\n"
35 " -h: this message\n"
36 " -p: save the file as a png.\n"
37 "If FILENAME ends with .png it will be saved as a png.\n"
38 "If FILENAME is not given, the results will be printed to stdout.\n"
39 );
40}
41
42static SkBitmap::Config flinger2skia(PixelFormat f)
43{
44 switch (f) {
45 case PIXEL_FORMAT_A_8:
46 case PIXEL_FORMAT_L_8:
47 return SkBitmap::kA8_Config;
48 case PIXEL_FORMAT_RGB_565:
49 return SkBitmap::kRGB_565_Config;
50 case PIXEL_FORMAT_RGBA_4444:
51 return SkBitmap::kARGB_4444_Config;
52 default:
53 return SkBitmap::kARGB_8888_Config;
54 }
55}
56
Mathias Agopian88a5df92010-09-26 18:49:45 -070057int main(int argc, char** argv)
58{
Joe Onorato5cff0632010-12-03 16:01:57 -080059 bool png = false;
60 int c;
61 while ((c = getopt(argc, argv, "ph")) != -1) {
62 switch (c) {
63 case 'p':
64 png = true;
65 break;
66 case '?':
67 case 'h':
68 usage();
69 return 1;
70 }
71 }
72 argc -= optind;
73 argv += optind;
74
75 int fd = -1;
76 if (argc == 0) {
77 fd = dup(STDOUT_FILENO);
78 } else if (argc == 1) {
79 const char* fn = argv[0];
80 fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, 0664);
81 if (fd == -1) {
82 fprintf(stderr, "Error opening file: (%d) %s\n", errno, strerror(errno));
83 return 1;
84 }
85 const int len = strlen(fn);
86 if (len >= 4 && 0 == strcmp(fn+len-4, ".png")) {
87 png = true;
88 }
89 }
90
91 if (fd == -1) {
92 usage();
93 return 1;
94 }
95
Mathias Agopian38ed2e32010-09-29 13:02:36 -070096 ScreenshotClient screenshot;
Joe Onorato5cff0632010-12-03 16:01:57 -080097 if (screenshot.update() != NO_ERROR) {
Mathias Agopian88a5df92010-09-26 18:49:45 -070098 return 0;
Joe Onorato5cff0632010-12-03 16:01:57 -080099 }
Mathias Agopian88a5df92010-09-26 18:49:45 -0700100
Mathias Agopian38ed2e32010-09-29 13:02:36 -0700101 void const* base = screenshot.getPixels();
102 uint32_t w = screenshot.getWidth();
103 uint32_t h = screenshot.getHeight();
104 uint32_t f = screenshot.getFormat();
Joe Onorato5cff0632010-12-03 16:01:57 -0800105
106 if (png) {
107 SkBitmap b;
108 b.setConfig(flinger2skia(f), w, h);
109 b.setPixels((void*)base);
110 SkDynamicMemoryWStream stream;
111 SkImageEncoder::EncodeStream(&stream, b,
112 SkImageEncoder::kPNG_Type, SkImageEncoder::kDefaultQuality);
113 write(fd, stream.getStream(), stream.getOffset());
114 } else {
115 write(fd, &w, 4);
116 write(fd, &h, 4);
117 write(fd, &f, 4);
118 write(fd, base, w*h*4);
119 }
Mathias Agopian88a5df92010-09-26 18:49:45 -0700120 close(fd);
121 return 0;
122}