Screenshot application enhancements:
- Remove the options panel, and the "-o, --options" switch, put all options
inside the main panel as discussed in ticket #3831.
- Add a "Copy to clipboard" button, as discussed in ticket #3831.
- Add a "-c, --clipboard" switch to quickly copy a screenshot to the clipboard
without launching the GUI.
- All settings apply directly to the current schreenshot as well as new
Screenshots, as discussed in ticket #4100.
- Separate executables for the CLI (Screenshot) and GUI (ScreenshotApp).
When "Screenshot" is launched it runs in the background, and launches the
GUI (if not run with the -s or -c switch) before quiting itself. When a new
screenshot is requested through the ScreenshotApp GUI interface,
ScreenshotApp launches Screenshot before quiting itself, after which
Screenshot re-launches ScreenshotApp. This fixes ticket #4100.
Note that because of this change the deskbar entry will show "ScreenshotApp"
and not "Screenshot" as might be expected. I am not sure if this is a
problem.
- Fixed the code that determines the active window because it was just finding
the top most window. This change fixes tickets #3112, #4878, and #4423.
- Hide the cursor by calling BApplication::HideCursor().
This fixes ticket #2988 (but *not* #2997).
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@37017 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -66,7 +66,8 @@ SYSTEM_APPS = AboutSystem ActivityMonitor CharacterMap CodyCam DeskCalc Devices
|
|||||||
DiskProbe DiskUsage DriveSetup CDPlayer Expander Icon-O-Matic Installer
|
DiskProbe DiskUsage DriveSetup CDPlayer Expander Icon-O-Matic Installer
|
||||||
LaunchBox Magnify Mail MediaConverter MediaPlayer MidiPlayer NetworkStatus
|
LaunchBox Magnify Mail MediaConverter MediaPlayer MidiPlayer NetworkStatus
|
||||||
PackageInstaller People PoorMan PowerStatus ProcessController Screenshot
|
PackageInstaller People PoorMan PowerStatus ProcessController Screenshot
|
||||||
ShowImage SoundRecorder StyledEdit Terminal TextSearch TV Workspaces
|
ScreenshotApp ShowImage SoundRecorder StyledEdit Terminal TextSearch TV
|
||||||
|
Workspaces
|
||||||
;
|
;
|
||||||
SYSTEM_PREFERENCES = Appearance Backgrounds CPUFrequency DataTranslations
|
SYSTEM_PREFERENCES = Appearance Backgrounds CPUFrequency DataTranslations
|
||||||
<preference>Deskbar E-mail FileTypes Fonts Keyboard Keymap Locale Media
|
<preference>Deskbar E-mail FileTypes Fonts Keyboard Keymap Locale Media
|
||||||
|
|||||||
+17
-10
@@ -1,19 +1,26 @@
|
|||||||
SubDir HAIKU_TOP src apps screenshot ;
|
SubDir HAIKU_TOP src apps screenshot ;
|
||||||
|
|
||||||
UseLibraryHeaders zlib ;
|
|
||||||
UsePrivateHeaders interface ;
|
UsePrivateHeaders interface ;
|
||||||
|
|
||||||
Application Screenshot :
|
Application ScreenshotApp :
|
||||||
main.cpp
|
ScreenshotApp.cpp
|
||||||
PreviewView.cpp
|
|
||||||
Screenshot.cpp
|
|
||||||
ScreenshotWindow.cpp
|
ScreenshotWindow.cpp
|
||||||
: be tracker translation libz.so liblocale.so $(TARGET_LIBSUPC++)
|
PreviewView.cpp
|
||||||
: Screenshot.rdef
|
Utility.cpp
|
||||||
|
: be locale tracker translation $(TARGET_LIBSUPC++)
|
||||||
|
: ScreenshotApp.rdef
|
||||||
;
|
;
|
||||||
|
|
||||||
DoCatalogs Screenshot :
|
DoCatalogs ScreenshotApp :
|
||||||
x-vnd.Haiku-Screenshot
|
x-vnd.Haiku-ScreenshotApp
|
||||||
:
|
:
|
||||||
ScreenshotWindow.cpp
|
ScreenshotWindow.cpp
|
||||||
|
Utility.cpp
|
||||||
|
;
|
||||||
|
|
||||||
|
Application Screenshot :
|
||||||
|
Screenshot.cpp
|
||||||
|
Utility.cpp
|
||||||
|
: be locale translation $(TARGET_LIBSUPC++)
|
||||||
|
: Screenshot.rdef
|
||||||
;
|
;
|
||||||
|
|||||||
+316
-107
@@ -1,35 +1,39 @@
|
|||||||
/*
|
/*
|
||||||
|
* Copyright 2010 Wim van der Meer <[email protected]>
|
||||||
* Copyright Karsten Heimrich, [email protected]. All rights reserved.
|
* Copyright Karsten Heimrich, [email protected]. All rights reserved.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
* Karsten Heimrich
|
* Karsten Heimrich
|
||||||
* Fredrik Modéen
|
* Fredrik Modéen
|
||||||
|
* Christophe Huriaux
|
||||||
|
* Wim van der Meer
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "Screenshot.h"
|
#include "Screenshot.h"
|
||||||
|
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <Catalog.h>
|
|
||||||
|
#include <AppDefs.h>
|
||||||
|
#include <Bitmap.h>
|
||||||
#include <Locale.h>
|
#include <Locale.h>
|
||||||
|
#include <Roster.h>
|
||||||
|
#include <Screen.h>
|
||||||
#include <TranslatorFormats.h>
|
#include <TranslatorFormats.h>
|
||||||
|
|
||||||
|
#include <WindowInfo.h>
|
||||||
|
|
||||||
#include "ScreenshotWindow.h"
|
#include "Utility.h"
|
||||||
|
|
||||||
|
|
||||||
Screenshot::Screenshot()
|
Screenshot::Screenshot()
|
||||||
:
|
:
|
||||||
BApplication("application/x-vnd.Haiku-Screenshot"),
|
BApplication("application/x-vnd.Haiku-Screenshot"),
|
||||||
fArgvReceived(false),
|
fUtility(new Utility()),
|
||||||
fRefsReceived(false),
|
fLaunchGui(true)
|
||||||
fImageFileType(B_PNG_FORMAT)
|
|
||||||
{
|
{
|
||||||
be_locale->GetAppCatalog(&fCatalog);
|
be_locale->GetAppCatalog(&fCatalog);
|
||||||
}
|
}
|
||||||
@@ -37,45 +41,7 @@ Screenshot::Screenshot()
|
|||||||
|
|
||||||
Screenshot::~Screenshot()
|
Screenshot::~Screenshot()
|
||||||
{
|
{
|
||||||
}
|
delete fUtility;
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
Screenshot::ReadyToRun()
|
|
||||||
{
|
|
||||||
if (!fArgvReceived && !fRefsReceived)
|
|
||||||
new ScreenshotWindow();
|
|
||||||
|
|
||||||
fArgvReceived = false;
|
|
||||||
fRefsReceived = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
Screenshot::RefsReceived(BMessage* message)
|
|
||||||
{
|
|
||||||
int32 delay = 0;
|
|
||||||
message->FindInt32("delay", &delay);
|
|
||||||
|
|
||||||
bool includeBorder = false;
|
|
||||||
message->FindBool("border", &includeBorder);
|
|
||||||
|
|
||||||
bool includeMouse = false;
|
|
||||||
message->FindBool("border", &includeMouse);
|
|
||||||
|
|
||||||
bool grabActiveWindow = false;
|
|
||||||
message->FindBool("window", &grabActiveWindow);
|
|
||||||
|
|
||||||
bool saveScreenshotSilent = false;
|
|
||||||
message->FindBool("silent", &saveScreenshotSilent);
|
|
||||||
|
|
||||||
bool showConfigureWindow = false;
|
|
||||||
message->FindBool("configure", &showConfigureWindow);
|
|
||||||
|
|
||||||
new ScreenshotWindow(delay * 1000000, includeBorder, includeMouse,
|
|
||||||
grabActiveWindow, showConfigureWindow, saveScreenshotSilent);
|
|
||||||
|
|
||||||
fRefsReceived = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -83,13 +49,13 @@ void
|
|||||||
Screenshot::ArgvReceived(int32 argc, char** argv)
|
Screenshot::ArgvReceived(int32 argc, char** argv)
|
||||||
{
|
{
|
||||||
bigtime_t delay = 0;
|
bigtime_t delay = 0;
|
||||||
|
|
||||||
const char* outputFilename = NULL;
|
const char* outputFilename = NULL;
|
||||||
bool includeBorder = false;
|
bool includeBorder = false;
|
||||||
bool includeMouse = false;
|
bool includeCursor = false;
|
||||||
bool grabActiveWindow = false;
|
bool grabActiveWindow = false;
|
||||||
bool showConfigureWindow = false;
|
|
||||||
bool saveScreenshotSilent = false;
|
bool saveScreenshotSilent = false;
|
||||||
|
bool copyToClipboard = false;
|
||||||
|
uint32 imageFileType = B_PNG_FORMAT;
|
||||||
|
|
||||||
for (int32 i = 0; i < argc; i++) {
|
for (int32 i = 0; i < argc; i++) {
|
||||||
if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0)
|
if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0)
|
||||||
@@ -99,21 +65,18 @@ Screenshot::ArgvReceived(int32 argc, char** argv)
|
|||||||
includeBorder = true;
|
includeBorder = true;
|
||||||
else if (strcmp(argv[i], "-m") == 0
|
else if (strcmp(argv[i], "-m") == 0
|
||||||
|| strcmp(argv[i], "--mouse-pointer") == 0)
|
|| strcmp(argv[i], "--mouse-pointer") == 0)
|
||||||
includeMouse = true;
|
includeCursor = true;
|
||||||
else if (strcmp(argv[i], "-w") == 0
|
else if (strcmp(argv[i], "-w") == 0
|
||||||
|| strcmp(argv[i], "--window") == 0)
|
|| strcmp(argv[i], "--window") == 0)
|
||||||
grabActiveWindow = true;
|
grabActiveWindow = true;
|
||||||
else if (strcmp(argv[i], "-s") == 0
|
else if (strcmp(argv[i], "-s") == 0
|
||||||
|| strcmp(argv[i], "--silent") == 0)
|
|| strcmp(argv[i], "--silent") == 0)
|
||||||
saveScreenshotSilent = true;
|
saveScreenshotSilent = true;
|
||||||
else if (strcmp(argv[i], "-o") == 0
|
|
||||||
|| strcmp(argv[i], "--options") == 0)
|
|
||||||
showConfigureWindow = true;
|
|
||||||
else if (strcmp(argv[i], "-f") == 0
|
else if (strcmp(argv[i], "-f") == 0
|
||||||
|| strncmp(argv[i], "--format", 6) == 0
|
|| strncmp(argv[i], "--format", 6) == 0
|
||||||
|| strncmp(argv[i], "--format=", 7) == 0) {
|
|| strncmp(argv[i], "--format=", 7) == 0)
|
||||||
_SetImageTypeSilence(argv[i + 1]);
|
imageFileType = _GetImageType(argv[i + 1]);
|
||||||
} else if (strcmp(argv[i], "-d") == 0
|
else if (strcmp(argv[i], "-d") == 0
|
||||||
|| strncmp(argv[i], "--delay", 7) == 0
|
|| strncmp(argv[i], "--delay", 7) == 0
|
||||||
|| strncmp(argv[i], "--delay=", 8) == 0) {
|
|| strncmp(argv[i], "--delay=", 8) == 0) {
|
||||||
int32 seconds = -1;
|
int32 seconds = -1;
|
||||||
@@ -123,60 +86,306 @@ Screenshot::ArgvReceived(int32 argc, char** argv)
|
|||||||
delay = seconds * 1000000;
|
delay = seconds * 1000000;
|
||||||
i++;
|
i++;
|
||||||
} else {
|
} else {
|
||||||
printf("Screenshot: option requires an argument -- %s\n"
|
printf("Screenshot: option requires an argument -- %s\n",
|
||||||
, argv[i]);
|
argv[i]);
|
||||||
exit(0);
|
fLaunchGui = false;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
} else if (i == argc - 1)
|
} else if (strcmp(argv[i], "-c") == 0
|
||||||
|
|| strcmp(argv[i], "--clipboard") == 0)
|
||||||
|
copyToClipboard = true;
|
||||||
|
else if (i == argc - 1)
|
||||||
outputFilename = argv[i];
|
outputFilename = argv[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (argc > 1)
|
||||||
|
_New(delay);
|
||||||
|
|
||||||
|
if (copyToClipboard || saveScreenshotSilent) {
|
||||||
|
fLaunchGui = false;
|
||||||
|
|
||||||
|
BBitmap* screenshot = fUtility->MakeScreenshot(includeCursor,
|
||||||
|
grabActiveWindow, includeBorder);
|
||||||
|
|
||||||
|
if (screenshot == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (copyToClipboard)
|
||||||
|
fUtility->CopyToClipboard(*screenshot);
|
||||||
|
|
||||||
fArgvReceived = true;
|
if (saveScreenshotSilent)
|
||||||
|
fUtility->Save(&screenshot, outputFilename, imageFileType);
|
||||||
new ScreenshotWindow(delay, includeBorder, includeMouse, grabActiveWindow,
|
|
||||||
showConfigureWindow, saveScreenshotSilent, fImageFileType,
|
|
||||||
outputFilename);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
delete screenshot;
|
||||||
void
|
|
||||||
Screenshot::_ShowHelp() const
|
|
||||||
{
|
|
||||||
printf("Screenshot [OPTIONS] [FILE] Creates a bitmap of the current screen\n\n");
|
|
||||||
printf("FILE is the optional output path / filename used in silent mode. If FILE is not given, a default filename will be generated in the prefered directory.\n\n");
|
|
||||||
printf("OPTIONS\n");
|
|
||||||
printf(" -o, --options Show options window first\n");
|
|
||||||
printf(" -m, --mouse-pointer Include the mouse pointer\n");
|
|
||||||
printf(" -b, --border Include the window border\n");
|
|
||||||
printf(" -w, --window Capture the active window instead of the entire screen\n");
|
|
||||||
printf(" -d, --delay=seconds Take screenshot after specified delay [in seconds]\n");
|
|
||||||
printf(" -s, --silent Saves the screenshot without showing the app window\n");
|
|
||||||
printf(" overrides --options\n");
|
|
||||||
printf(" -f, --format=image Write the image format you like to save as\n");
|
|
||||||
printf(" [bmp], [gif], [jpg], [png], [ppm], [targa], [tiff]\n");
|
|
||||||
printf("\n");
|
|
||||||
printf("Note: OPTION -b, --border takes only effect when used with -w, --window\n");
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
Screenshot::_SetImageTypeSilence(const char* name)
|
|
||||||
{
|
|
||||||
if (strcmp(name, "bmp") == 0)
|
|
||||||
fImageFileType = B_BMP_FORMAT;
|
|
||||||
else if (strcmp(name, "gif") == 0)
|
|
||||||
fImageFileType = B_GIF_FORMAT;
|
|
||||||
else if (strcmp(name, "jpg") == 0 || strcmp(name, "jpeg") == 0)
|
|
||||||
fImageFileType = B_JPEG_FORMAT;
|
|
||||||
else if (strcmp(name, "ppm") == 0)
|
|
||||||
fImageFileType = B_PPM_FORMAT;
|
|
||||||
else if (strcmp(name, "targa") == 0 || strcmp(name, "tga") == 0)
|
|
||||||
fImageFileType = B_TGA_FORMAT;
|
|
||||||
else if (strcmp(name, "tif") == 0 || strcmp(name, "tiff") == 0)
|
|
||||||
fImageFileType = B_TIFF_FORMAT;
|
|
||||||
else {
|
|
||||||
// Default to PNG.
|
|
||||||
fImageFileType = B_PNG_FORMAT;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Screenshot::ReadyToRun()
|
||||||
|
{
|
||||||
|
if (fLaunchGui) {
|
||||||
|
// Launch the GUI application
|
||||||
|
if (fUtility->wholeScreen == NULL) {
|
||||||
|
// No command line parameters were given
|
||||||
|
be_roster->Launch("application/x-vnd.Haiku-ScreenshotApp");
|
||||||
|
} else {
|
||||||
|
// Send the utility data and the command line settings to the GUI
|
||||||
|
BMessage message;
|
||||||
|
message.what = SS_UTILITY_DATA;
|
||||||
|
|
||||||
|
BMessage* bitmap = new BMessage();
|
||||||
|
fUtility->wholeScreen->Archive(bitmap);
|
||||||
|
message.AddMessage("wholeScreen", bitmap);
|
||||||
|
|
||||||
|
bitmap = new BMessage();
|
||||||
|
fUtility->cursorBitmap->Archive(bitmap);
|
||||||
|
message.AddMessage("cursorBitmap", bitmap);
|
||||||
|
|
||||||
|
bitmap = new BMessage();
|
||||||
|
fUtility->cursorAreaBitmap->Archive(bitmap);
|
||||||
|
message.AddMessage("cursorAreaBitmap", bitmap);
|
||||||
|
|
||||||
|
message.AddPoint("cursorPosition", fUtility->cursorPosition);
|
||||||
|
message.AddRect("activeWindowFrame", fUtility->activeWindowFrame);
|
||||||
|
message.AddRect("tabFrame", fUtility->tabFrame);
|
||||||
|
message.AddFloat("borderSize", fUtility->borderSize);
|
||||||
|
|
||||||
|
be_roster->Launch("application/x-vnd.Haiku-ScreenshotApp",
|
||||||
|
&message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
be_app->PostMessage(B_QUIT_REQUESTED);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Screenshot::_ShowHelp()
|
||||||
|
{
|
||||||
|
printf("Screenshot [OPTIONS] [FILE] Creates a bitmap of the current "
|
||||||
|
"screen\n\n");
|
||||||
|
printf("FILE is the optional output path / filename used in silent mode. "
|
||||||
|
"An exisiting\nfile with the same name will be overwritten without "
|
||||||
|
"warning. If FILE is not\ngiven the screenshot will be saved to a "
|
||||||
|
"file with the default filename in the\nuser's home directory.\n\n");
|
||||||
|
printf("OPTIONS\n");
|
||||||
|
printf(" -m, --mouse-pointer Include the mouse pointer\n");
|
||||||
|
printf(" -b, --border Include the window border\n");
|
||||||
|
printf(" -w, --window Capture the active window instead of the "
|
||||||
|
"entire screen\n");
|
||||||
|
printf(" -d, --delay=seconds Take screenshot after the specified delay "
|
||||||
|
"[in seconds]\n");
|
||||||
|
printf(" -s, --silent Saves the screenshot without showing the "
|
||||||
|
"application\n window\n");
|
||||||
|
printf(" -f, --format=image Give the image format you like to save "
|
||||||
|
"as\n");
|
||||||
|
printf(" [bmp], [gif], [jpg], [png], [ppm], "
|
||||||
|
"[tga], [tif]\n");
|
||||||
|
printf(" -c, --clipboard Copies the screenshot to the system "
|
||||||
|
"clipboard without\n showing the application "
|
||||||
|
"window\n");
|
||||||
|
printf("\n");
|
||||||
|
printf("Note: OPTION -b, --border takes only effect when used with -w, "
|
||||||
|
"--window\n");
|
||||||
|
|
||||||
|
fLaunchGui = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Screenshot::_New(bigtime_t delay)
|
||||||
|
{
|
||||||
|
delete fUtility->wholeScreen;
|
||||||
|
delete fUtility->cursorBitmap;
|
||||||
|
delete fUtility->cursorAreaBitmap;
|
||||||
|
|
||||||
|
if (delay > 0)
|
||||||
|
snooze(delay);
|
||||||
|
|
||||||
|
_GetActiveWindowFrame();
|
||||||
|
|
||||||
|
// There is a bug in the drawEngine code that prevents the drawCursor
|
||||||
|
// flag from hiding the cursor when GetBitmap is called, so we need to hide
|
||||||
|
// the cursor by ourselves. Refer to trac tickets #2988 and #2997
|
||||||
|
bool cursorIsHidden = IsCursorHidden();
|
||||||
|
if (!cursorIsHidden)
|
||||||
|
HideCursor();
|
||||||
|
if (BScreen().GetBitmap(&fUtility->wholeScreen, false) != B_OK)
|
||||||
|
return;
|
||||||
|
if (!cursorIsHidden)
|
||||||
|
ShowCursor();
|
||||||
|
|
||||||
|
// Get the current cursor position, bitmap, and hotspot
|
||||||
|
BPoint cursorHotSpot;
|
||||||
|
get_mouse(&fUtility->cursorPosition, NULL);
|
||||||
|
get_mouse_bitmap(&fUtility->cursorBitmap, &cursorHotSpot);
|
||||||
|
fUtility->cursorPosition -= cursorHotSpot;
|
||||||
|
|
||||||
|
// Put the mouse area in a bitmap
|
||||||
|
BRect bounds = fUtility->cursorBitmap->Bounds();
|
||||||
|
int cursorWidth = bounds.IntegerWidth() + 1;
|
||||||
|
int cursorHeight = bounds.IntegerHeight() + 1;
|
||||||
|
fUtility->cursorAreaBitmap = new BBitmap(bounds, B_RGBA32);
|
||||||
|
|
||||||
|
fUtility->cursorAreaBitmap->ImportBits(fUtility->wholeScreen->Bits(),
|
||||||
|
fUtility->wholeScreen->BitsLength(),
|
||||||
|
fUtility->wholeScreen->BytesPerRow(),
|
||||||
|
fUtility->wholeScreen->ColorSpace(),
|
||||||
|
fUtility->cursorPosition, BPoint(0, 0),
|
||||||
|
cursorWidth, cursorHeight);
|
||||||
|
|
||||||
|
// Fill in the background of the mouse bitmap
|
||||||
|
uint8* bits = (uint8*)fUtility->cursorBitmap->Bits();
|
||||||
|
uint8* areaBits = (uint8*)fUtility->cursorAreaBitmap->Bits();
|
||||||
|
for (int32 i = 0; i < cursorHeight; i++) {
|
||||||
|
for (int32 j = 0; j < cursorWidth; j++) {
|
||||||
|
uint8 alpha = 255 - bits[3];
|
||||||
|
bits[0] = ((areaBits[0] * alpha) >> 8) + bits[0];
|
||||||
|
bits[1] = ((areaBits[1] * alpha) >> 8) + bits[1];
|
||||||
|
bits[2] = ((areaBits[2] * alpha) >> 8) + bits[2];
|
||||||
|
bits[3] = 255;
|
||||||
|
areaBits += 4;
|
||||||
|
bits += 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
Screenshot::_GetActiveWindowFrame()
|
||||||
|
{
|
||||||
|
fUtility->activeWindowFrame.Set(0, 0, -1, -1);
|
||||||
|
|
||||||
|
// Create a messenger to communicate with the active application
|
||||||
|
app_info appInfo;
|
||||||
|
status_t status = be_roster->GetActiveAppInfo(&appInfo);
|
||||||
|
if (status != B_OK)
|
||||||
|
return status;
|
||||||
|
BMessenger messenger(appInfo.signature, appInfo.team);
|
||||||
|
if (!messenger.IsValid())
|
||||||
|
return B_ERROR;
|
||||||
|
|
||||||
|
// Loop through the windows of the active application to find out which
|
||||||
|
// window is active
|
||||||
|
int32 tokenCount;
|
||||||
|
int32* tokens = get_token_list(appInfo.team, &tokenCount);
|
||||||
|
bool foundActiveWindow = false;
|
||||||
|
BMessage message;
|
||||||
|
BMessage reply;
|
||||||
|
int32 index = 0;
|
||||||
|
int32 token = -1;
|
||||||
|
client_window_info* windowInfo = NULL;
|
||||||
|
bool modalWindow = false;
|
||||||
|
while (true) {
|
||||||
|
message.MakeEmpty();
|
||||||
|
reply.MakeEmpty();
|
||||||
|
|
||||||
|
message.what = B_GET_PROPERTY;
|
||||||
|
message.AddSpecifier("Active");
|
||||||
|
message.AddSpecifier("Window", index);
|
||||||
|
messenger.SendMessage(&message, &reply, B_INFINITE_TIMEOUT, 50000);
|
||||||
|
|
||||||
|
if (reply.what == B_MESSAGE_NOT_UNDERSTOOD)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (!reply.what) {
|
||||||
|
// Reply timout, this probably means that we have a modal window
|
||||||
|
// so we'll just get the window frame of the top most window
|
||||||
|
modalWindow = true;
|
||||||
|
free(tokens);
|
||||||
|
status_t status = BPrivate::get_window_order(current_workspace(),
|
||||||
|
&tokens, &tokenCount);
|
||||||
|
if (status != B_OK || !tokens || tokenCount < 1)
|
||||||
|
return B_ERROR;
|
||||||
|
foundActiveWindow = true;
|
||||||
|
} else if (reply.FindBool("result", &foundActiveWindow) != B_OK)
|
||||||
|
foundActiveWindow = false;
|
||||||
|
|
||||||
|
if (foundActiveWindow) {
|
||||||
|
// Get the client_window_info of the active window
|
||||||
|
foundActiveWindow = false;
|
||||||
|
for (int i = 0; i < tokenCount; i++) {
|
||||||
|
token = tokens[i];
|
||||||
|
windowInfo = get_window_info(token);
|
||||||
|
if (!windowInfo->is_mini && !windowInfo->show_hide_level > 0) {
|
||||||
|
foundActiveWindow = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
free(windowInfo);
|
||||||
|
}
|
||||||
|
if (foundActiveWindow)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
free(tokens);
|
||||||
|
|
||||||
|
if (!foundActiveWindow)
|
||||||
|
return B_ERROR;
|
||||||
|
|
||||||
|
// Get the TabFrame using the scripting interface
|
||||||
|
if (!modalWindow) {
|
||||||
|
message.MakeEmpty();
|
||||||
|
message.what = B_GET_PROPERTY;
|
||||||
|
message.AddSpecifier("TabFrame");
|
||||||
|
message.AddSpecifier("Window", index);
|
||||||
|
reply.MakeEmpty();
|
||||||
|
messenger.SendMessage(&message, &reply);
|
||||||
|
|
||||||
|
if (reply.FindRect("result", &fUtility->tabFrame) != B_OK)
|
||||||
|
return B_ERROR;
|
||||||
|
} else
|
||||||
|
fUtility->tabFrame.Set(0, 0, 0, 0);
|
||||||
|
|
||||||
|
// Get the active window frame from the client_window_info
|
||||||
|
fUtility->activeWindowFrame.left = windowInfo->window_left;
|
||||||
|
fUtility->activeWindowFrame.top = windowInfo->window_top;
|
||||||
|
fUtility->activeWindowFrame.right = windowInfo->window_right;
|
||||||
|
fUtility->activeWindowFrame.bottom = windowInfo->window_bottom;
|
||||||
|
fUtility->borderSize = windowInfo->border_size;
|
||||||
|
|
||||||
|
free(windowInfo);
|
||||||
|
|
||||||
|
// Make sure that fActiveWindowFrame doesn't extend beyond the screen frame
|
||||||
|
BRect screenFrame(BScreen().Frame());
|
||||||
|
if (fUtility->activeWindowFrame.left < screenFrame.left)
|
||||||
|
fUtility->activeWindowFrame.left = screenFrame.left;
|
||||||
|
if (fUtility->activeWindowFrame.top < screenFrame.top)
|
||||||
|
fUtility->activeWindowFrame.top = screenFrame.top;
|
||||||
|
if (fUtility->activeWindowFrame.right > screenFrame.right)
|
||||||
|
fUtility->activeWindowFrame.right = screenFrame.right;
|
||||||
|
if (fUtility->activeWindowFrame.bottom > screenFrame.bottom)
|
||||||
|
fUtility->activeWindowFrame.bottom = screenFrame.bottom;
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int32
|
||||||
|
Screenshot::_GetImageType(const char* name) const
|
||||||
|
{
|
||||||
|
if (strcmp(name, "bmp") == 0)
|
||||||
|
return B_BMP_FORMAT;
|
||||||
|
else if (strcmp(name, "gif") == 0)
|
||||||
|
return B_GIF_FORMAT;
|
||||||
|
else if (strcmp(name, "jpg") == 0 || strcmp(name, "jpeg") == 0)
|
||||||
|
return B_JPEG_FORMAT;
|
||||||
|
else if (strcmp(name, "ppm") == 0)
|
||||||
|
return B_PPM_FORMAT;
|
||||||
|
else if (strcmp(name, "tga") == 0 || strcmp(name, "targa") == 0)
|
||||||
|
return B_TGA_FORMAT;
|
||||||
|
else if (strcmp(name, "tif") == 0 || strcmp(name, "tiff") == 0)
|
||||||
|
return B_TIFF_FORMAT;
|
||||||
|
else {
|
||||||
|
return B_PNG_FORMAT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
main()
|
||||||
|
{
|
||||||
|
Screenshot screenshot;
|
||||||
|
return screenshot.Run();
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,10 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright Karsten Heimrich, [email protected]. All rights reserved.
|
* Copyright 2010 Wim van der Meer <[email protected]>
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
|
||||||
* Authors:
|
|
||||||
* Karsten Heimrich
|
|
||||||
* Fredrik Modéen
|
|
||||||
*/
|
*/
|
||||||
#ifndef SCREENSHOT_H
|
#ifndef SCREENSHOT_H
|
||||||
#define SCREENSHOT_H
|
#define SCREENSHOT_H
|
||||||
@@ -14,23 +10,29 @@
|
|||||||
#include <Catalog.h>
|
#include <Catalog.h>
|
||||||
|
|
||||||
|
|
||||||
|
class BBitmap;
|
||||||
|
class Utility;
|
||||||
|
|
||||||
|
|
||||||
class Screenshot : public BApplication {
|
class Screenshot : public BApplication {
|
||||||
public:
|
public:
|
||||||
Screenshot();
|
Screenshot();
|
||||||
virtual ~Screenshot();
|
~Screenshot();
|
||||||
|
|
||||||
virtual void ReadyToRun();
|
void ReadyToRun();
|
||||||
virtual void RefsReceived(BMessage* message);
|
void ArgvReceived(int32 argc, char** argv);
|
||||||
virtual void ArgvReceived(int32 argc, char** argv);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void _ShowHelp() const;
|
void _ShowHelp();
|
||||||
void _SetImageTypeSilence(const char* name);
|
void _New(bigtime_t delay);
|
||||||
|
status_t _GetActiveWindowFrame();
|
||||||
|
int32 _GetImageType(const char* name) const;
|
||||||
|
|
||||||
bool fArgvReceived;
|
Utility* fUtility;
|
||||||
bool fRefsReceived;
|
BCatalog fCatalog;
|
||||||
int32 fImageFileType;
|
|
||||||
BCatalog fCatalog;
|
bool fLaunchGui;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* SCREENSHOT_H */
|
|
||||||
|
#endif // SCREENSHOT_H
|
||||||
|
|||||||
@@ -1,20 +1,15 @@
|
|||||||
|
|
||||||
resource app_signature "application/x-vnd.Haiku-Screenshot";
|
resource app_signature "application/x-vnd.Haiku-Screenshot";
|
||||||
|
|
||||||
resource app_flags B_MULTIPLE_LAUNCH;
|
resource app_flags B_MULTIPLE_LAUNCH | B_BACKGROUND_APP;
|
||||||
|
|
||||||
resource app_version {
|
resource app_version {
|
||||||
major = 1,
|
major = 1,
|
||||||
middle = 0,
|
middle = 0,
|
||||||
minor = 0,
|
minor = 0,
|
||||||
|
variety = B_APPV_BETA,
|
||||||
/* 0 = development 1 = alpha 2 = beta
|
|
||||||
3 = gamma 4 = golden master 5 = final */
|
|
||||||
variety = 2,
|
|
||||||
internal = 0,
|
internal = 0,
|
||||||
|
|
||||||
short_info = "Screenshot",
|
short_info = "Screenshot",
|
||||||
long_info = "Screenshot ©2008-2009 Haiku"
|
long_info = "Screenshot ©2008-2010 Haiku"
|
||||||
};
|
};
|
||||||
|
|
||||||
resource vector_icon {
|
resource vector_icon {
|
||||||
@@ -48,4 +43,3 @@ resource vector_icon {
|
|||||||
$"0B73BD11333F6C1B4A6724C968940A0D010D02B8307E3A7163BA7600B82C644A"
|
$"0B73BD11333F6C1B4A6724C968940A0D010D02B8307E3A7163BA7600B82C644A"
|
||||||
$"AAA84832F80A0D010E023EE2433C8C01BC90D03EDCDB4A6EE0C86667"
|
$"AAA84832F80A0D010E023EE2433C8C01BC90D03EDCDB4A6EE0C86667"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,106 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010 Wim van der Meer <[email protected]>
|
||||||
|
* All rights reserved. Distributed under the terms of the MIT license.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Wim van der Meer
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "ScreenshotApp.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <Bitmap.h>
|
||||||
|
#include <Locale.h>
|
||||||
|
#include <Roster.h>
|
||||||
|
|
||||||
|
#include "ScreenshotWindow.h"
|
||||||
|
#include "Utility.h"
|
||||||
|
|
||||||
|
|
||||||
|
ScreenshotApp::ScreenshotApp()
|
||||||
|
:
|
||||||
|
BApplication("application/x-vnd.Haiku-ScreenshotApp"),
|
||||||
|
fUtility(new Utility)
|
||||||
|
{
|
||||||
|
be_locale->GetAppCatalog(&fCatalog);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ScreenshotApp::~ScreenshotApp()
|
||||||
|
{
|
||||||
|
delete fUtility;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
ScreenshotApp::MessageReceived(BMessage* message)
|
||||||
|
{
|
||||||
|
status_t status = B_OK;
|
||||||
|
switch (message->what) {
|
||||||
|
case SS_UTILITY_DATA:
|
||||||
|
{
|
||||||
|
BMessage bitmap;
|
||||||
|
status = message->FindMessage("wholeScreen", &bitmap);
|
||||||
|
if (status != B_OK)
|
||||||
|
break;
|
||||||
|
|
||||||
|
fUtility->wholeScreen = new BBitmap(&bitmap);
|
||||||
|
|
||||||
|
status = message->FindMessage("cursorBitmap", &bitmap);
|
||||||
|
if (status != B_OK)
|
||||||
|
break;
|
||||||
|
|
||||||
|
fUtility->cursorBitmap = new BBitmap(&bitmap);
|
||||||
|
|
||||||
|
status = message->FindMessage("cursorAreaBitmap", &bitmap);
|
||||||
|
if (status != B_OK)
|
||||||
|
break;
|
||||||
|
|
||||||
|
fUtility->cursorAreaBitmap = new BBitmap(&bitmap);
|
||||||
|
|
||||||
|
status = message->FindPoint("cursorPosition",
|
||||||
|
&fUtility->cursorPosition);
|
||||||
|
if (status != B_OK)
|
||||||
|
break;
|
||||||
|
|
||||||
|
status = message->FindRect("activeWindowFrame",
|
||||||
|
&fUtility->activeWindowFrame);
|
||||||
|
if (status != B_OK)
|
||||||
|
break;
|
||||||
|
|
||||||
|
status = message->FindRect("tabFrame", &fUtility->tabFrame);
|
||||||
|
if (status != B_OK)
|
||||||
|
break;
|
||||||
|
|
||||||
|
status = message->FindFloat("borderSize", &fUtility->borderSize);
|
||||||
|
if (status != B_OK)
|
||||||
|
break;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
BApplication::MessageReceived(message);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status != B_OK)
|
||||||
|
be_app->PostMessage(B_QUIT_REQUESTED);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
ScreenshotApp::ReadyToRun()
|
||||||
|
{
|
||||||
|
new ScreenshotWindow(*fUtility);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
main()
|
||||||
|
{
|
||||||
|
ScreenshotApp app;
|
||||||
|
return app.Run();
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010 Wim van der Meer <[email protected]>
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Wim van der Meer
|
||||||
|
*/
|
||||||
|
#ifndef SCREENSHOT_APP_H
|
||||||
|
#define SCREENSHOT_APP_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <Application.h>
|
||||||
|
#include <Catalog.h>
|
||||||
|
|
||||||
|
|
||||||
|
class Utility;
|
||||||
|
|
||||||
|
|
||||||
|
class ScreenshotApp : public BApplication {
|
||||||
|
public:
|
||||||
|
ScreenshotApp();
|
||||||
|
~ScreenshotApp();
|
||||||
|
|
||||||
|
void MessageReceived(BMessage* message);
|
||||||
|
void ReadyToRun();
|
||||||
|
|
||||||
|
private:
|
||||||
|
BCatalog fCatalog;
|
||||||
|
Utility* fUtility;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // SCREENSHOT_APP_H
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
resource app_signature "application/x-vnd.Haiku-ScreenshotApp";
|
||||||
|
|
||||||
|
resource app_flags B_MULTIPLE_LAUNCH;
|
||||||
|
|
||||||
|
resource app_version {
|
||||||
|
major = 1,
|
||||||
|
middle = 0,
|
||||||
|
minor = 0,
|
||||||
|
variety = B_APPV_BETA,
|
||||||
|
internal = 0,
|
||||||
|
short_info = "ScreenshotApp",
|
||||||
|
long_info = "ScreenshotApp ©2008-2010 Haiku"
|
||||||
|
};
|
||||||
|
|
||||||
|
resource vector_icon {
|
||||||
|
$"6E6369660E050102000603399E0F3D9C0ABF82B23B84A84B88504910C900A5B1"
|
||||||
|
$"FFBCEAF1FFFFB3B8FF020106023E49240000000000003CAAAA4940004A80007C"
|
||||||
|
$"896EFFFFC0D5FF0401920332669805D803FFCB0005FF020016023CC7ED389BBF"
|
||||||
|
$"BA16553E39B04A41E44546E300FFFFD3020016023C529D3753A2B8966F3D9D07"
|
||||||
|
$"4AF244490EAF005EFFC502001602BCDCFABCCC663C90D9BCA00D47B5864B0A2A"
|
||||||
|
$"0090FFF4020006023CC0000000000000003D000047C00048A0001F010101FFC1"
|
||||||
|
$"ACAC020106023A26EC38CA29B828213953DA48968D4B2BC600434A68FF0F1238"
|
||||||
|
$"05FF0F0606AE0BB40BC14A33C5ACB75CC370BDEFC804C13ECA02CA27BF80C117"
|
||||||
|
$"BB1EC51BBD3EBF06BA053AB8BA0606AE0BB40BC14A33C5ACB75CC370BDEFC804"
|
||||||
|
$"C13ECA02CA27BF80C117BB1EC51BBD3EBF06BA053AB8BA0605AE02B57D43B9B9"
|
||||||
|
$"C5EDB7BB49BBB756BD75CB34CA8DC3AE40340605AE02B57D43B9B9C5EDB7BB49"
|
||||||
|
$"BBB756BD75CB34CA8DC3AE40340A093B5E3D60BFCDCB3B4560C516C7EE604B5B"
|
||||||
|
$"485D4A44560606AA0B27444054523FC074BC08C072BC07C073BC07BEE7BB113A"
|
||||||
|
$"3208022E4733420A062C3E2C50485E4E584E44323C0A042C3E48484E44323C0A"
|
||||||
|
$"044848485E4E584E440A042C3E2C50485E48480A04363E54505E43393A0204C0"
|
||||||
|
$"80C3B945C4F0BF41C281BC4DC353BD60C254BB39C452BC9BC754BB5DC61DBDDA"
|
||||||
|
$"C88CC0CEC7BABFBBC8B9C1E2C6BB0204B7E1C43BB8D9C34DB6EAC52BB893C86B"
|
||||||
|
$"B73BC70BB9EAC9CEBCBFC936BBC7CA26BDB5C848BC0FC507BD66C668BAB7C3A6"
|
||||||
|
$"0604EE3355BC43C7D1BBDDC837BCA9C76B3851BC83C828BCE9C7C2BC1DC88E17"
|
||||||
|
$"0A030104000A0001021001178400040A020103000A0001001001178400040A01"
|
||||||
|
$"0101000A0001051001178200040A040105000A050105023E2E8B000000000000"
|
||||||
|
$"3E2E8B472E8B48945D0A06010630212001178300040A070106123FFC76B8A84F"
|
||||||
|
$"38A84F3FFC7642069D437F0F01178200040A07010630282401178200040A0701"
|
||||||
|
$"06302B2601178200040A070106302E2801178200040A03010B000A0001073028"
|
||||||
|
$"A92301178400040A0801082028A9230A0901092028A9230A0A010A2028A9230A"
|
||||||
|
$"070106123CE1EA3F79B7BE878F3DF5DD4ADA30C89CFA01178200040A0B010D12"
|
||||||
|
$"BEE243BC8C013C90D0BEDCDB4A31144BF5A201178400040A0C010D023F72923D"
|
||||||
|
$"0B73BD11333F6C1B4A6724C968940A0D010D02B8307E3A7163BA7600B82C644A"
|
||||||
|
$"AAA84832F80A0D010E023EE2433C8C01BC90D03EDCDB4A6EE0C86667"
|
||||||
|
};
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,88 +1,65 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright Karsten Heimrich, [email protected]. All rights reserved.
|
* Copyright 2010 Wim van der Meer <[email protected]>
|
||||||
* Distributed under the terms of the MIT License.
|
* Copyright Karsten Heimrich, [email protected]e.
|
||||||
|
* All rights reserved. Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
* Karsten Heimrich
|
* Karsten Heimrich
|
||||||
* Fredrik Modéen
|
* Fredrik Modéen
|
||||||
* Wim van der Meer, [email protected]
|
* Wim van der Meer
|
||||||
*/
|
*/
|
||||||
#ifndef SCREENSHOT_WINDOW_H
|
#ifndef SCREENSHOT_WINDOW_H
|
||||||
#define SCREENSHOT_WINDOW_H
|
#define SCREENSHOT_WINDOW_H
|
||||||
|
|
||||||
|
|
||||||
#include <String.h>
|
#include <String.h>
|
||||||
#include <Window.h>
|
|
||||||
#include <TranslationDefs.h>
|
#include <TranslationDefs.h>
|
||||||
#include <TranslatorFormats.h>
|
#include <TranslatorFormats.h>
|
||||||
|
#include <Window.h>
|
||||||
|
|
||||||
|
|
||||||
class BBitmap;
|
class BBitmap;
|
||||||
class BButton;
|
|
||||||
class BCardLayout;
|
|
||||||
class BCheckBox;
|
class BCheckBox;
|
||||||
class BFilePanel;
|
class BFilePanel;
|
||||||
class BMenu;
|
class BMenu;
|
||||||
class BRadioButton;
|
class BPath;
|
||||||
class BTextControl;
|
class BTextControl;
|
||||||
class BTextView;
|
class BTextView;
|
||||||
class BPath;
|
|
||||||
class PreviewView;
|
class PreviewView;
|
||||||
|
class Utility;
|
||||||
|
|
||||||
|
|
||||||
class ScreenshotWindow : public BWindow {
|
class ScreenshotWindow : public BWindow {
|
||||||
public:
|
public:
|
||||||
ScreenshotWindow();
|
ScreenshotWindow(const Utility& utility);
|
||||||
ScreenshotWindow(bigtime_t delay,
|
~ScreenshotWindow();
|
||||||
bool includeBorder,
|
|
||||||
bool includeMouse,
|
|
||||||
bool grabActiveWindow,
|
|
||||||
bool showConfigWindow,
|
|
||||||
bool saveScreenshotSilent,
|
|
||||||
int32 imageFileType = B_PNG_FORMAT,
|
|
||||||
const char* outputFilename = NULL);
|
|
||||||
virtual ~ScreenshotWindow();
|
|
||||||
|
|
||||||
virtual void MessageReceived(BMessage* message);
|
void MessageReceived(BMessage* message);
|
||||||
|
void Quit();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void _InitWindow(const BMessage& settings);
|
void _NewScreenshot();
|
||||||
BPath _GetDirectory();
|
void _UpdatePreviewPanel();
|
||||||
void _SetupFirstLayoutItem(BCardLayout* layout);
|
|
||||||
void _SetupSecondLayoutItem(BCardLayout* layout,
|
|
||||||
const BMessage& settings);
|
|
||||||
void _DisallowChar(BTextView* textView);
|
void _DisallowChar(BTextView* textView);
|
||||||
void _SetupTranslatorMenu(BMenu* translatorMenu);
|
void _SetupOutputPathMenu(const BMessage& settings);
|
||||||
void _SetupOutputPathMenu(BMenu* outputPathMenu,
|
|
||||||
const BMessage& settings);
|
|
||||||
void _AddItemToPathMenu(const char* path,
|
void _AddItemToPathMenu(const char* path,
|
||||||
BString& label, int32 index, bool markItem);
|
BString& label, int32 index, bool markItem);
|
||||||
|
|
||||||
void _UpdatePreviewPanel();
|
|
||||||
void _UpdateFilenameSelection();
|
void _UpdateFilenameSelection();
|
||||||
BString _FindValidFileName(const char* name);
|
void _SetupTranslatorMenu();
|
||||||
int32 _PathIndexInMenu(const BString& path) const;
|
|
||||||
|
|
||||||
BMessage _ReadSettings() const;
|
|
||||||
void _WriteSettings() const;
|
|
||||||
|
|
||||||
void _TakeScreenshot(bigtime_t delay);
|
|
||||||
status_t _GetActiveWindowFrame(BRect* frame);
|
|
||||||
void _MakeTabSpaceTransparent(BRect* frame);
|
|
||||||
|
|
||||||
status_t _SaveScreenshot();
|
status_t _SaveScreenshot();
|
||||||
|
BString _FindValidFileName(const char* name);
|
||||||
|
BPath _GetDirectory();
|
||||||
|
void _ReadSettings();
|
||||||
|
void _WriteSettings();
|
||||||
|
|
||||||
status_t _FindTranslator(uint32 imageType, translator_id* id);
|
const Utility& fUtility;
|
||||||
|
|
||||||
PreviewView* fPreview;
|
PreviewView* fPreview;
|
||||||
BRadioButton* fActiveWindow;
|
BCheckBox* fActiveWindow;
|
||||||
BRadioButton* fWholeDesktop;
|
|
||||||
BTextControl* fDelayControl;
|
BTextControl* fDelayControl;
|
||||||
BCheckBox* fWindowBorder;
|
BCheckBox* fWindowBorder;
|
||||||
BCheckBox* fShowMouse;
|
BCheckBox* fShowCursor;
|
||||||
BButton* fBackToSave;
|
|
||||||
BButton* fTakeScreenshot;
|
|
||||||
BButton* fSaveScreenshot;
|
|
||||||
BTextControl* fNameControl;
|
BTextControl* fNameControl;
|
||||||
BMenu* fTranslatorMenu;
|
BMenu* fTranslatorMenu;
|
||||||
BMenu* fOutputPathMenu;
|
BMenu* fOutputPathMenu;
|
||||||
@@ -91,17 +68,13 @@ private:
|
|||||||
BMenuItem* fLastSelectedPath;
|
BMenuItem* fLastSelectedPath;
|
||||||
|
|
||||||
bigtime_t fDelay;
|
bigtime_t fDelay;
|
||||||
float fTabHeight;
|
|
||||||
|
|
||||||
bool fIncludeBorder;
|
bool fIncludeBorder;
|
||||||
bool fIncludeMouse;
|
bool fIncludeCursor;
|
||||||
bool fGrabActiveWindow;
|
bool fGrabActiveWindow;
|
||||||
bool fShowConfigWindow;
|
|
||||||
bool fSaveScreenshotSilent;
|
|
||||||
BString fOutputFilename;
|
BString fOutputFilename;
|
||||||
BString fExtension;
|
BString fExtension;
|
||||||
|
|
||||||
int32 fImageFileType;
|
int32 fImageFileType;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* SCREENSHOT_WINDOW_H */
|
|
||||||
|
#endif // SCREENSHOT_WINDOW_H
|
||||||
|
|||||||
@@ -0,0 +1,267 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010 Wim van der Meer <[email protected]>
|
||||||
|
* Copyright Karsten Heimrich, [email protected]. All rights reserved.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Karsten Heimrich
|
||||||
|
* Fredrik Modéen
|
||||||
|
* Christophe Huriaux
|
||||||
|
* Wim van der Meer
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "Utility.h"
|
||||||
|
|
||||||
|
#include <Bitmap.h>
|
||||||
|
#include <BitmapStream.h>
|
||||||
|
#include <Catalog.h>
|
||||||
|
#include <Clipboard.h>
|
||||||
|
#include <Entry.h>
|
||||||
|
#include <File.h>
|
||||||
|
#include <FindDirectory.h>
|
||||||
|
#include <Looper.h>
|
||||||
|
#include <MimeType.h>
|
||||||
|
#include <NodeInfo.h>
|
||||||
|
#include <Path.h>
|
||||||
|
#include <Region.h>
|
||||||
|
#include <Screen.h>
|
||||||
|
#include <String.h>
|
||||||
|
#include <Translator.h>
|
||||||
|
#include <View.h>
|
||||||
|
|
||||||
|
|
||||||
|
#undef B_TRANSLATE_CONTEXT
|
||||||
|
#define B_TRANSLATE_CONTEXT "Screenshot"
|
||||||
|
|
||||||
|
|
||||||
|
const char* Utility::sDefaultFileNameBase =
|
||||||
|
B_TRANSLATE_MARK_COMMENT("screenshot",
|
||||||
|
"Base filename of screenshot files");
|
||||||
|
|
||||||
|
|
||||||
|
Utility::Utility()
|
||||||
|
:
|
||||||
|
wholeScreen(NULL),
|
||||||
|
cursorBitmap(NULL),
|
||||||
|
cursorAreaBitmap(NULL)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Utility::~Utility()
|
||||||
|
{
|
||||||
|
delete wholeScreen;
|
||||||
|
delete cursorBitmap;
|
||||||
|
delete cursorAreaBitmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Utility::CopyToClipboard(const BBitmap& screenshot) const
|
||||||
|
{
|
||||||
|
if (be_clipboard->Lock()) {
|
||||||
|
be_clipboard->Clear();
|
||||||
|
BMessage* clipboard = be_clipboard->Data();
|
||||||
|
if (clipboard) {
|
||||||
|
BMessage* bitmap = new BMessage();
|
||||||
|
screenshot.Archive(bitmap);
|
||||||
|
clipboard->AddMessage("image/bitmap", bitmap);
|
||||||
|
be_clipboard->Commit();
|
||||||
|
}
|
||||||
|
be_clipboard->Unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Save the screenshot to the file with the specified filename and type.
|
||||||
|
Note that any existing file with the same filename will be overwritten
|
||||||
|
without warning.
|
||||||
|
*/
|
||||||
|
status_t
|
||||||
|
Utility::Save(BBitmap** screenshot, const char* fileName, uint32 imageType)
|
||||||
|
const
|
||||||
|
{
|
||||||
|
BString fileNameString(fileName);
|
||||||
|
|
||||||
|
// Generate a default filename when none is given
|
||||||
|
if (fileNameString.Compare("") == 0) {
|
||||||
|
BPath homePath;
|
||||||
|
if (find_directory(B_USER_DIRECTORY, &homePath) != B_OK)
|
||||||
|
return B_ERROR;
|
||||||
|
|
||||||
|
BEntry entry;
|
||||||
|
int32 index = 1;
|
||||||
|
BString extension = GetFileNameExtension(imageType);
|
||||||
|
do {
|
||||||
|
fileNameString.SetTo(homePath.Path());
|
||||||
|
fileNameString << "/" << sDefaultFileNameBase << index++
|
||||||
|
<< extension;
|
||||||
|
entry.SetTo(fileNameString.String());
|
||||||
|
} while (entry.Exists());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the file
|
||||||
|
BFile file(fileNameString, B_CREATE_FILE | B_ERASE_FILE | B_WRITE_ONLY);
|
||||||
|
if (file.InitCheck() != B_OK)
|
||||||
|
return B_ERROR;
|
||||||
|
|
||||||
|
// Write the screenshot bitmap to the file
|
||||||
|
BBitmapStream stream(*screenshot);
|
||||||
|
BTranslatorRoster* roster = BTranslatorRoster::Default();
|
||||||
|
roster->Translate(&stream, NULL, NULL, &file, imageType,
|
||||||
|
B_TRANSLATOR_BITMAP);
|
||||||
|
*screenshot = NULL;
|
||||||
|
|
||||||
|
// Set the file MIME attribute
|
||||||
|
BNodeInfo nodeInfo(&file);
|
||||||
|
if (nodeInfo.InitCheck() != B_OK)
|
||||||
|
return B_ERROR;
|
||||||
|
|
||||||
|
nodeInfo.SetType(_GetMimeString(imageType));
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BBitmap*
|
||||||
|
Utility::MakeScreenshot(bool includeMouse, bool activeWindow,
|
||||||
|
bool includeBorder) const
|
||||||
|
{
|
||||||
|
if (wholeScreen == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
BRect bounds = cursorBitmap->Bounds();
|
||||||
|
int cursorWidth = bounds.IntegerWidth() + 1;
|
||||||
|
int cursorHeight = bounds.IntegerHeight() + 1;
|
||||||
|
|
||||||
|
if (includeMouse && cursorBitmap != NULL) {
|
||||||
|
// Import the cursor bitmap into wholeScreen
|
||||||
|
wholeScreen->ImportBits(cursorBitmap->Bits(),
|
||||||
|
cursorBitmap->BitsLength(), cursorBitmap->BytesPerRow(),
|
||||||
|
cursorBitmap->ColorSpace(), BPoint(0, 0), cursorPosition,
|
||||||
|
cursorWidth, cursorHeight);
|
||||||
|
|
||||||
|
} else if (cursorAreaBitmap != NULL) {
|
||||||
|
// Import the cursor area bitmap into wholeScreen
|
||||||
|
wholeScreen->ImportBits(cursorAreaBitmap->Bits(),
|
||||||
|
cursorAreaBitmap->BitsLength(), cursorAreaBitmap->BytesPerRow(),
|
||||||
|
cursorAreaBitmap->ColorSpace(), BPoint(0, 0), cursorPosition,
|
||||||
|
cursorWidth, cursorHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
BBitmap* screenshot = NULL;
|
||||||
|
|
||||||
|
if (activeWindow && activeWindowFrame.IsValid()) {
|
||||||
|
|
||||||
|
BRect frame(activeWindowFrame);
|
||||||
|
if (includeBorder) {
|
||||||
|
frame.InsetBy(-borderSize, -borderSize);
|
||||||
|
frame.top -= tabFrame.bottom - tabFrame.top;
|
||||||
|
}
|
||||||
|
|
||||||
|
screenshot = new BBitmap(frame.OffsetToCopy(B_ORIGIN), B_RGBA32, true);
|
||||||
|
|
||||||
|
if (screenshot->ImportBits(wholeScreen->Bits(),
|
||||||
|
wholeScreen->BitsLength(), wholeScreen->BytesPerRow(),
|
||||||
|
wholeScreen->ColorSpace(), frame.LeftTop(),
|
||||||
|
BPoint(0, 0), frame.IntegerWidth() + 1,
|
||||||
|
frame.IntegerHeight() + 1) != B_OK) {
|
||||||
|
delete screenshot;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (includeBorder)
|
||||||
|
_MakeTabSpaceTransparent(screenshot, frame);
|
||||||
|
} else
|
||||||
|
screenshot = new BBitmap(wholeScreen);
|
||||||
|
|
||||||
|
return screenshot;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const char*
|
||||||
|
Utility::GetFileNameExtension(uint32 imageType) const
|
||||||
|
{
|
||||||
|
BMimeType mimeType(_GetMimeString(imageType));
|
||||||
|
BString extension("");
|
||||||
|
|
||||||
|
BMessage message;
|
||||||
|
if (mimeType.GetFileExtensions(&message) == B_OK) {
|
||||||
|
const char* ext;
|
||||||
|
if (message.FindString("extensions", 0, &ext) == B_OK) {
|
||||||
|
extension.SetTo(ext);
|
||||||
|
extension.Prepend(".");
|
||||||
|
} else
|
||||||
|
extension.SetTo("");
|
||||||
|
}
|
||||||
|
|
||||||
|
return extension.String();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const char*
|
||||||
|
Utility::_GetMimeString(uint32 imageType) const
|
||||||
|
{
|
||||||
|
char dummy[] = "";
|
||||||
|
translator_id* translators = NULL;
|
||||||
|
int32 numTranslators = 0;
|
||||||
|
BTranslatorRoster* roster = BTranslatorRoster::Default();
|
||||||
|
status_t status = roster->GetAllTranslators(&translators, &numTranslators);
|
||||||
|
if (status != B_OK)
|
||||||
|
return dummy;
|
||||||
|
|
||||||
|
for (int32 x = 0; x < numTranslators; x++) {
|
||||||
|
const translation_format* formats = NULL;
|
||||||
|
int32 numFormats;
|
||||||
|
|
||||||
|
if (roster->GetOutputFormats(x, &formats, &numFormats) == B_OK) {
|
||||||
|
for (int32 i = 0; i < numFormats; ++i) {
|
||||||
|
if (formats[i].type == imageType) {
|
||||||
|
delete [] translators;
|
||||||
|
return formats[i].MIME;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete [] translators;
|
||||||
|
return dummy;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Utility::_MakeTabSpaceTransparent(BBitmap* screenshot, BRect frame) const
|
||||||
|
{
|
||||||
|
if (!frame.IsValid() || screenshot->ColorSpace() != B_RGBA32)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!frame.Contains(tabFrame))
|
||||||
|
return;
|
||||||
|
|
||||||
|
float tabHeight = tabFrame.bottom - tabFrame.top;
|
||||||
|
|
||||||
|
BRegion tabSpace(frame);
|
||||||
|
frame.OffsetBy(0, tabHeight);
|
||||||
|
tabSpace.Exclude(frame);
|
||||||
|
tabSpace.Exclude(tabFrame);
|
||||||
|
frame.OffsetBy(0, -tabHeight);
|
||||||
|
tabSpace.OffsetBy(-frame.left, -frame.top);
|
||||||
|
BScreen screen;
|
||||||
|
BRect screenFrame = screen.Frame();
|
||||||
|
tabSpace.OffsetBy(-screenFrame.left, -screenFrame.top);
|
||||||
|
|
||||||
|
BView view(screenshot->Bounds(), "bitmap", B_FOLLOW_ALL_SIDES, 0);
|
||||||
|
screenshot->AddChild(&view);
|
||||||
|
if (view.Looper() && view.Looper()->Lock()) {
|
||||||
|
view.SetDrawingMode(B_OP_COPY);
|
||||||
|
view.SetHighColor(B_TRANSPARENT_32_BIT);
|
||||||
|
|
||||||
|
for (int i = 0; i < tabSpace.CountRects(); i++)
|
||||||
|
view.FillRect(tabSpace.RectAt(i));
|
||||||
|
|
||||||
|
view.Sync();
|
||||||
|
view.Looper()->Unlock();
|
||||||
|
}
|
||||||
|
screenshot->RemoveChild(&view);
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010 Wim van der Meer <[email protected]>
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
#ifndef UTILITY_H
|
||||||
|
#define UTILITY_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <Point.h>
|
||||||
|
#include <Rect.h>
|
||||||
|
|
||||||
|
|
||||||
|
class BBitmap;
|
||||||
|
|
||||||
|
|
||||||
|
// Command constant for sending utility data to the GUI app
|
||||||
|
const int32 SS_UTILITY_DATA = 'SSUD';
|
||||||
|
|
||||||
|
|
||||||
|
class Utility {
|
||||||
|
public:
|
||||||
|
Utility();
|
||||||
|
~Utility();
|
||||||
|
|
||||||
|
void CopyToClipboard(const BBitmap& screenshot) const;
|
||||||
|
status_t Save(BBitmap** screenshot, const char* fileName,
|
||||||
|
uint32 imageType) const;
|
||||||
|
BBitmap* MakeScreenshot(bool includeCursor, bool activeWindow,
|
||||||
|
bool includeBorder) const;
|
||||||
|
const char* GetFileNameExtension(uint32 imageType) const;
|
||||||
|
|
||||||
|
BBitmap* wholeScreen;
|
||||||
|
BBitmap* cursorBitmap;
|
||||||
|
BBitmap* cursorAreaBitmap;
|
||||||
|
BPoint cursorPosition;
|
||||||
|
BRect activeWindowFrame;
|
||||||
|
BRect tabFrame;
|
||||||
|
float borderSize;
|
||||||
|
|
||||||
|
static const char* sDefaultFileNameBase;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void _MakeTabSpaceTransparent(BBitmap* screenshot,
|
||||||
|
BRect frame) const;
|
||||||
|
const char* _GetMimeString(uint32 imageType) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // UTILITY_H
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright Karsten Heimrich, [email protected]. All rights reserved.
|
|
||||||
* Distributed under the terms of the MIT License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "Screenshot.h"
|
|
||||||
|
|
||||||
|
|
||||||
int
|
|
||||||
main(int argc, char* argv[])
|
|
||||||
{
|
|
||||||
Screenshot screenshot;
|
|
||||||
return screenshot.Run();
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user