148
149
ShotScreen::paint (CompOutput::ptrList &outputs,
149
150
unsigned int mask)
151
cScreen->paint (outputs, mask);
157
int x1 = MIN (mX1, mX2);
158
int y1 = MIN (mY1, mY2);
159
int x2 = MAX (mX1, mX2);
160
int y2 = MAX (mY1, mY2);
156
/* Taking screenshot, enable full paint on
160
outputs.push_back (&screen->fullscreenOutput ());
164
cScreen->paint (outputs, mask);
169
bool paintSelectionRectangleFill (const CompRect &rect,
170
unsigned short *fillColor,
171
GLVertexBuffer *streamingBuffer,
172
const GLMatrix &transform)
174
GLfloat vertexData[12];
175
GLushort colorData[4];
182
const float MaxUShortFloat = std::numeric_limits <unsigned short>::max ();
184
/* draw filled rectangle */
185
float alpha = fillColor[3] / MaxUShortFloat;
187
colorData[0] = alpha * fillColor[0];
188
colorData[1] = alpha * fillColor[1];
189
colorData[2] = alpha * fillColor[2];
190
colorData[3] = alpha * MaxUShortFloat;
194
vertexData[2] = 0.0f;
197
vertexData[5] = 0.0f;
200
vertexData[8] = 0.0f;
203
vertexData[11] = 0.0f;
205
streamingBuffer->begin (GL_TRIANGLE_STRIP);
207
streamingBuffer->addColors (1, colorData);
208
streamingBuffer->addVertices (4, vertexData);
210
if (streamingBuffer->end ())
214
streamingBuffer->render (transform);
216
glDisable (GL_BLEND);
224
bool paintSelectionRectangleOutline (const CompRect &rect,
225
unsigned short *outlineColor,
226
GLVertexBuffer *streamingBuffer,
227
const GLMatrix &transform)
229
GLfloat vertexData[12];
230
GLushort colorData[4];
237
const float MaxUShortFloat = std::numeric_limits <unsigned short>::max ();
240
float alpha = outlineColor[3] / MaxUShortFloat;
242
colorData[0] = alpha * outlineColor[0];
243
colorData[1] = alpha * outlineColor[1];
244
colorData[2] = alpha * outlineColor[2];
245
colorData[3] = alpha * MaxUShortFloat;
249
vertexData[2] = 0.0f;
252
vertexData[5] = 0.0f;
255
vertexData[8] = 0.0f;
258
vertexData[11] = 0.0f;
260
streamingBuffer->begin (GL_LINE_LOOP);
262
streamingBuffer->addColors (1, colorData);
263
streamingBuffer->addVertices (4, vertexData);
265
if (streamingBuffer->end ())
270
streamingBuffer->render (transform);
272
glDisable (GL_BLEND);
281
ensureDirectoryForImage (CompString &directory)
283
/* If dir is empty, use user's desktop directory instead */
284
if (directory.length () == 0)
285
directory = getXDGUserDir (XDGUserDirDesktop);
289
getImageNumberFromDirectory (const CompString &directory)
291
struct dirent **namelist;
293
int n = scandir (directory.c_str (), &namelist, shotFilter, shotSort);
300
sscanf (namelist[n - 1]->d_name,
319
getImageAbsolutePath (const CompString &directory,
322
std::stringstream ss;
323
ss << directory << "/screenshot" << number << ".png";
328
saveBuffer (const boost::scoped_array <GLubyte> &buffer,
331
const CompString &path)
333
CompSize imageSize (w, h);
335
if (!::screen->writeImageToFile (const_cast <CompString &> (path),
340
compLogMessage ("screenshot", CompLogLevelError,
341
"failed to write screenshot image");
349
launchApplicationAndTakeScreenshot (const CompString &app,
350
const CompString &directory)
352
if (app.length () > 0)
354
::screen->runCommand (app + " " + directory);
362
readFromGPUBufferToCPUBuffer (const CompRect &rect,
363
boost::scoped_array <GLubyte> &buffer)
375
size_t size = w * h * 4;
376
buffer.reset (new GLubyte[size]);
168
CompString dir (optionGetDirectory ());
170
/* If dir is empty, use user's desktop directory instead */
171
if (dir.length () == 0)
172
dir = getXDGUserDir (XDGUserDirDesktop);
174
buffer = (GLubyte *)malloc (sizeof (GLubyte) * w * h * 4);
380
GLint drawBinding = 0;
381
GLint readBinding = 0;
383
/* Bind the currently bound draw framebuffer to
384
* the read framebuffer and read from it */
178
struct dirent **namelist;
180
glReadPixels (x1, ::screen->height () - y2, w, h,
181
GL_RGBA, GL_UNSIGNED_BYTE,
184
int n = scandir (dir.c_str (), &namelist, shotFilter, shotSort);
192
sscanf (namelist[n - 1]->d_name,
201
snprintf (name, 256, "screenshot%d.png", number);
203
CompString app (optionGetLaunchApp ());
204
CompString path (dir + "/" + name);
205
CompSize imageSize (w, h);
207
if (!::screen->writeImageToFile (path, "png",
209
compLogMessage ("screenshot", CompLogLevelError,
210
"failed to write screenshot image");
211
else if (app.length () > 0)
212
::screen->runCommand (app + " " + path);
215
perror (dir.c_str ());
387
glGetIntegerv (GL::DRAW_FRAMEBUFFER_BINDING, &drawBinding);
388
glGetIntegerv (GL::READ_FRAMEBUFFER_BINDING, &readBinding);
389
(GL::bindFramebuffer) (GL::READ_FRAMEBUFFER, drawBinding);
393
glReadPixels (x1, ::screen->height () - y2, w, h,
394
GL_RGBA, GL_UNSIGNED_BYTE,
395
(GLvoid *) buffer.get ());
398
(GL::bindFramebuffer) (GL::READ_FRAMEBUFFER, readBinding);
400
if (glGetError () != GL_NO_ERROR)
220
/* Disable screen capture */
221
cScreen->paintSetEnabled (this, false);
410
/* We need to take directory by copy because
411
* it may be modified later */
412
bool saveScreenshot (CompRect rect,
413
CompString directory,
414
const CompString &alternativeApplication)
416
ensureDirectoryForImage (directory);
418
int number = getImageNumberFromDirectory (directory);
419
CompString path = getImageAbsolutePath (directory, number);
421
boost::scoped_array <GLubyte> buffer;
423
bool success = readFromGPUBufferToCPUBuffer (rect,
428
success = saveBuffer (buffer,
430
rect.height (), path);
434
compLogMessage ("screenshot", CompLogLevelWarn, "glReadPixels failed");
439
launchApplicationAndTakeScreenshot (alternativeApplication,
245
459
* we are grabbed, the size has changed and the CCSM
246
460
* option to draw it is enabled. */
462
CompRect selectionRect (std::min (mX1, mX2),
464
std::abs (mX2 - mX1),
465
std::abs (mY2 - mY1));
248
467
if (mGrabIndex &&
249
468
selectionSizeChanged &&
250
469
optionGetDrawSelectionIndicator ())
252
int x1 = MIN (mX1, mX2);
253
int y1 = MIN (mY1, mY2);
254
int x2 = MAX (mX1, mX2);
255
int y2 = MAX (mY1, mY2);
257
const float MaxUShortFloat = std::numeric_limits <unsigned short>::max ();
259
/* draw filled rectangle */
260
float alpha = optionGetSelectionFillColorAlpha () / MaxUShortFloat;
261
color = optionGetSelectionFillColor ();
263
colorData[0] = alpha * color[0];
264
colorData[1] = alpha * color[1];
265
colorData[2] = alpha * color[2];
266
colorData[3] = alpha * MaxUShortFloat;
270
vertexData[2] = 0.0f;
273
vertexData[5] = 0.0f;
276
vertexData[8] = 0.0f;
279
vertexData[11] = 0.0f;
281
transform.translate (-0.5f, -0.5f, -DEFAULT_Z_CAMERA);
282
transform.scale (1.0f / output->width (),
283
-1.0f / output->height (),
285
transform.translate (-output->region ()->extents.x1,
286
-output->region ()->extents.y2,
291
streamingBuffer->begin (GL_TRIANGLE_STRIP);
293
streamingBuffer->addColors (1, colorData);
294
streamingBuffer->addVertices (4, vertexData);
296
streamingBuffer->end ();
297
streamingBuffer->render (transform);
300
alpha = optionGetSelectionOutlineColorAlpha () / MaxUShortFloat;
301
color = optionGetSelectionOutlineColor ();
303
colorData[0] = alpha * color[0];
304
colorData[1] = alpha * color[1];
305
colorData[2] = alpha * color[2];
306
colorData[3] = alpha * MaxUShortFloat;
315
streamingBuffer->begin (GL_LINE_LOOP);
317
streamingBuffer->addColors (1, colorData);
318
streamingBuffer->addVertices (4, vertexData);
320
streamingBuffer->end ();
321
streamingBuffer->render (transform);
323
glDisable (GL_BLEND);
471
GLMatrix transform (matrix);
472
GLVertexBuffer *streamingBuffer (GLVertexBuffer::streamingBuffer ());
473
transform.toScreenSpace (output, -DEFAULT_Z_CAMERA);
475
paintSelectionRectangleFill (selectionRect,
476
optionGetSelectionFillColor (),
480
paintSelectionRectangleOutline (selectionRect,
481
optionGetSelectionOutlineColor (),
325
485
/* we finished painting the selection box,
326
486
* reset selectionSizeChanged now */
327
487
selectionSizeChanged = false;
489
else if (!mGrabIndex)
491
/* Taking a screenshot */
492
saveScreenshot (selectionRect,
493
optionGetDirectory (),
494
optionGetLaunchApp ());
495
cScreen->paintSetEnabled (this, false);
496
gScreen->glPaintOutputSetEnabled (this, false);