OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2010 The WebRTC Project Authors. All rights reserved. | 2 * Copyright 2010 The WebRTC Project Authors. All rights reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
270 xev.xclient.data.l[4] = 0; | 270 xev.xclient.data.l[4] = 0; |
271 | 271 |
272 event_mask = SubstructureRedirectMask | SubstructureNotifyMask; | 272 event_mask = SubstructureRedirectMask | SubstructureNotifyMask; |
273 | 273 |
274 XSendEvent(display_, root, False, event_mask, &xev); | 274 XSendEvent(display_, root, False, event_mask, &xev); |
275 } | 275 } |
276 XFlush(display_); | 276 XFlush(display_); |
277 return true; | 277 return true; |
278 } | 278 } |
279 | 279 |
280 uint8* GetWindowIcon(const WindowId& id, int* width, int* height) { | 280 uint8_t* GetWindowIcon(const WindowId& id, int* width, int* height) { |
281 if (!Init()) { | 281 if (!Init()) { |
282 return NULL; | 282 return NULL; |
283 } | 283 } |
284 XErrorSuppressor error_suppressor(display_); | 284 XErrorSuppressor error_suppressor(display_); |
285 Atom ret_type; | 285 Atom ret_type; |
286 int format; | 286 int format; |
287 unsigned long length, bytes_after, size; | 287 unsigned long length, bytes_after, size; |
288 unsigned char* data = NULL; | 288 unsigned char* data = NULL; |
289 | 289 |
290 // Find out the size of the icon data. | 290 // Find out the size of the icon data. |
291 if (XGetWindowProperty( | 291 if (XGetWindowProperty( |
292 display_, id.id(), net_wm_icon_, 0, 0, False, XA_CARDINAL, | 292 display_, id.id(), net_wm_icon_, 0, 0, False, XA_CARDINAL, |
293 &ret_type, &format, &length, &size, &data) == Success && | 293 &ret_type, &format, &length, &size, &data) == Success && |
294 data) { | 294 data) { |
295 XFree(data); | 295 XFree(data); |
296 } else { | 296 } else { |
297 LOG(LS_ERROR) << "Failed to get size of the icon."; | 297 LOG(LS_ERROR) << "Failed to get size of the icon."; |
298 return NULL; | 298 return NULL; |
299 } | 299 } |
300 // Get the icon data, the format is one uint32 each for width and height, | 300 // Get the icon data, the format is one uint32_t each for width and height, |
301 // followed by the actual pixel data. | 301 // followed by the actual pixel data. |
302 if (size >= 2 && | 302 if (size >= 2 && |
303 XGetWindowProperty( | 303 XGetWindowProperty( |
304 display_, id.id(), net_wm_icon_, 0, size, False, XA_CARDINAL, | 304 display_, id.id(), net_wm_icon_, 0, size, False, XA_CARDINAL, |
305 &ret_type, &format, &length, &bytes_after, &data) == Success && | 305 &ret_type, &format, &length, &bytes_after, &data) == Success && |
306 data) { | 306 data) { |
307 uint32* data_ptr = reinterpret_cast<uint32*>(data); | 307 uint32_t* data_ptr = reinterpret_cast<uint32_t*>(data); |
308 int w, h; | 308 int w, h; |
309 w = data_ptr[0]; | 309 w = data_ptr[0]; |
310 h = data_ptr[1]; | 310 h = data_ptr[1]; |
311 if (size < static_cast<unsigned long>(w * h + 2)) { | 311 if (size < static_cast<unsigned long>(w * h + 2)) { |
312 XFree(data); | 312 XFree(data); |
313 LOG(LS_ERROR) << "Not a vaild icon."; | 313 LOG(LS_ERROR) << "Not a vaild icon."; |
314 return NULL; | 314 return NULL; |
315 } | 315 } |
316 uint8* rgba = | 316 uint8_t* rgba = ArgbToRgba(&data_ptr[2], 0, 0, w, h, w, h, true); |
317 ArgbToRgba(&data_ptr[2], 0, 0, w, h, w, h, true); | |
318 XFree(data); | 317 XFree(data); |
319 *width = w; | 318 *width = w; |
320 *height = h; | 319 *height = h; |
321 return rgba; | 320 return rgba; |
322 } else { | 321 } else { |
323 LOG(LS_ERROR) << "Failed to get window icon data."; | 322 LOG(LS_ERROR) << "Failed to get window icon data."; |
324 return NULL; | 323 return NULL; |
325 } | 324 } |
326 } | 325 } |
327 | 326 |
328 uint8* GetWindowThumbnail(const WindowId& id, int width, int height) { | 327 uint8_t* GetWindowThumbnail(const WindowId& id, int width, int height) { |
329 if (!Init()) { | 328 if (!Init()) { |
330 return NULL; | 329 return NULL; |
331 } | 330 } |
332 | 331 |
333 if (!has_composite_extension_) { | 332 if (!has_composite_extension_) { |
334 // Without the Xcomposite extension we would only get a good thumbnail if | 333 // Without the Xcomposite extension we would only get a good thumbnail if |
335 // the whole window is visible on screen and not covered by any | 334 // the whole window is visible on screen and not covered by any |
336 // other window. This is not something we want so instead, just | 335 // other window. This is not something we want so instead, just |
337 // bail out. | 336 // bail out. |
338 LOG(LS_INFO) << "No Xcomposite extension detected."; | 337 LOG(LS_INFO) << "No Xcomposite extension detected."; |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
383 // If we get to here, then composite is in use for this window and it has a | 382 // If we get to here, then composite is in use for this window and it has a |
384 // valid backing pixmap. | 383 // valid backing pixmap. |
385 | 384 |
386 XWindowAttributes attr; | 385 XWindowAttributes attr; |
387 if (!XGetWindowAttributes(display_, id.id(), &attr)) { | 386 if (!XGetWindowAttributes(display_, id.id(), &attr)) { |
388 LOG(LS_ERROR) << "XGetWindowAttributes() failed"; | 387 LOG(LS_ERROR) << "XGetWindowAttributes() failed"; |
389 XFreePixmap(display_, src_pixmap); | 388 XFreePixmap(display_, src_pixmap); |
390 return NULL; | 389 return NULL; |
391 } | 390 } |
392 | 391 |
393 uint8* data = GetDrawableThumbnail(src_pixmap, | 392 uint8_t* data = GetDrawableThumbnail(src_pixmap, attr.visual, src_width, |
394 attr.visual, | 393 src_height, width, height); |
395 src_width, | |
396 src_height, | |
397 width, | |
398 height); | |
399 XFreePixmap(display_, src_pixmap); | 394 XFreePixmap(display_, src_pixmap); |
400 return data; | 395 return data; |
401 } | 396 } |
402 | 397 |
403 int GetNumDesktops() { | 398 int GetNumDesktops() { |
404 if (!Init()) { | 399 if (!Init()) { |
405 return -1; | 400 return -1; |
406 } | 401 } |
407 | 402 |
408 return XScreenCount(display_); | 403 return XScreenCount(display_); |
409 } | 404 } |
410 | 405 |
411 uint8* GetDesktopThumbnail(const DesktopId& id, int width, int height) { | 406 uint8_t* GetDesktopThumbnail(const DesktopId& id, int width, int height) { |
412 if (!Init()) { | 407 if (!Init()) { |
413 return NULL; | 408 return NULL; |
414 } | 409 } |
415 XErrorSuppressor error_suppressor(display_); | 410 XErrorSuppressor error_suppressor(display_); |
416 | 411 |
417 Window root_window = id.id(); | 412 Window root_window = id.id(); |
418 XWindowAttributes attr; | 413 XWindowAttributes attr; |
419 if (!XGetWindowAttributes(display_, root_window, &attr)) { | 414 if (!XGetWindowAttributes(display_, root_window, &attr)) { |
420 LOG(LS_ERROR) << "XGetWindowAttributes() failed"; | 415 LOG(LS_ERROR) << "XGetWindowAttributes() failed"; |
421 return NULL; | 416 return NULL; |
(...skipping 16 matching lines...) Expand all Loading... |
438 if (!XGetWindowAttributes(display_, id.id(), &attr)) { | 433 if (!XGetWindowAttributes(display_, id.id(), &attr)) { |
439 LOG(LS_ERROR) << "XGetWindowAttributes() failed"; | 434 LOG(LS_ERROR) << "XGetWindowAttributes() failed"; |
440 return false; | 435 return false; |
441 } | 436 } |
442 *width = attr.width; | 437 *width = attr.width; |
443 *height = attr.height; | 438 *height = attr.height; |
444 return true; | 439 return true; |
445 } | 440 } |
446 | 441 |
447 private: | 442 private: |
448 uint8* GetDrawableThumbnail(Drawable src_drawable, | 443 uint8_t* GetDrawableThumbnail(Drawable src_drawable, |
449 Visual* visual, | 444 Visual* visual, |
450 int src_width, | 445 int src_width, |
451 int src_height, | 446 int src_height, |
452 int dst_width, | 447 int dst_width, |
453 int dst_height) { | 448 int dst_height) { |
454 if (!has_render_extension_) { | 449 if (!has_render_extension_) { |
455 // Without the Xrender extension we would have to read the full window and | 450 // Without the Xrender extension we would have to read the full window and |
456 // scale it down in our process. Xrender is over a decade old so we aren't | 451 // scale it down in our process. Xrender is over a decade old so we aren't |
457 // going to expend effort to support that situation. We still need to | 452 // going to expend effort to support that situation. We still need to |
458 // check though because probably some virtual VNC displays are in this | 453 // check though because probably some virtual VNC displays are in this |
459 // category. | 454 // category. |
460 LOG(LS_INFO) << "No Xrender extension detected."; | 455 LOG(LS_INFO) << "No Xrender extension detected."; |
461 return NULL; | 456 return NULL; |
462 } | 457 } |
463 | 458 |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
554 | 549 |
555 // Get the pixel data from the X server. TODO: XGetImage | 550 // Get the pixel data from the X server. TODO: XGetImage |
556 // might be slow here, compare with ShmGetImage. | 551 // might be slow here, compare with ShmGetImage. |
557 XImage* image = XGetImage(display_, | 552 XImage* image = XGetImage(display_, |
558 dst_pixmap, | 553 dst_pixmap, |
559 0, | 554 0, |
560 0, | 555 0, |
561 dst_width, | 556 dst_width, |
562 dst_height, | 557 dst_height, |
563 AllPlanes, ZPixmap); | 558 AllPlanes, ZPixmap); |
564 uint8* data = ArgbToRgba(reinterpret_cast<uint32*>(image->data), | 559 uint8_t* data = ArgbToRgba(reinterpret_cast<uint32_t*>(image->data), |
565 centered_x, | 560 centered_x, centered_y, scaled_width, |
566 centered_y, | 561 scaled_height, dst_width, dst_height, false); |
567 scaled_width, | |
568 scaled_height, | |
569 dst_width, | |
570 dst_height, | |
571 false); | |
572 XDestroyImage(image); | 562 XDestroyImage(image); |
573 XRenderFreePicture(display_, dst); | 563 XRenderFreePicture(display_, dst); |
574 XFreePixmap(display_, dst_pixmap); | 564 XFreePixmap(display_, dst_pixmap); |
575 XRenderFreePicture(display_, src); | 565 XRenderFreePicture(display_, src); |
576 return data; | 566 return data; |
577 } | 567 } |
578 | 568 |
579 uint8* ArgbToRgba(uint32* argb_data, int x, int y, int w, int h, | 569 uint8_t* ArgbToRgba(uint32_t* argb_data, |
580 int stride_x, int stride_y, bool has_alpha) { | 570 int x, |
581 uint8* p; | 571 int y, |
| 572 int w, |
| 573 int h, |
| 574 int stride_x, |
| 575 int stride_y, |
| 576 bool has_alpha) { |
| 577 uint8_t* p; |
582 int len = stride_x * stride_y * 4; | 578 int len = stride_x * stride_y * 4; |
583 uint8* data = new uint8[len]; | 579 uint8_t* data = new uint8_t[len]; |
584 memset(data, 0, len); | 580 memset(data, 0, len); |
585 p = data + 4 * (y * stride_x + x); | 581 p = data + 4 * (y * stride_x + x); |
586 for (int i = 0; i < h; ++i) { | 582 for (int i = 0; i < h; ++i) { |
587 for (int j = 0; j < w; ++j) { | 583 for (int j = 0; j < w; ++j) { |
588 uint32 argb; | 584 uint32_t argb; |
589 uint32 rgba; | 585 uint32_t rgba; |
590 argb = argb_data[stride_x * (y + i) + x + j]; | 586 argb = argb_data[stride_x * (y + i) + x + j]; |
591 rgba = (argb << 8) | (argb >> 24); | 587 rgba = (argb << 8) | (argb >> 24); |
592 *p = rgba >> 24; | 588 *p = rgba >> 24; |
593 ++p; | 589 ++p; |
594 *p = (rgba >> 16) & 0xff; | 590 *p = (rgba >> 16) & 0xff; |
595 ++p; | 591 ++p; |
596 *p = (rgba >> 8) & 0xff; | 592 *p = (rgba >> 8) & 0xff; |
597 ++p; | 593 ++p; |
598 *p = has_alpha ? rgba & 0xFF : 0xFF; | 594 *p = has_alpha ? rgba & 0xFF : 0xFF; |
599 ++p; | 595 ++p; |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
684 int ret = XGetWindowProperty(display_, window, | 680 int ret = XGetWindowProperty(display_, window, |
685 wm_state_, 0L, 2, | 681 wm_state_, 0L, 2, |
686 False, wm_state_, &type, &format, | 682 False, wm_state_, &type, &format, |
687 &nitems, &after, &data); | 683 &nitems, &after, &data); |
688 if (ret != Success) { | 684 if (ret != Success) { |
689 LOG(LS_ERROR) << "XGetWindowProperty failed with return code " << ret | 685 LOG(LS_ERROR) << "XGetWindowProperty failed with return code " << ret |
690 << " for window " << window << "."; | 686 << " for window " << window << "."; |
691 return 0; | 687 return 0; |
692 } | 688 } |
693 if (type != None) { | 689 if (type != None) { |
694 int64 state = static_cast<int64>(*data); | 690 int64_t state = static_cast<int64_t>(*data); |
695 XFree(data); | 691 XFree(data); |
696 return state == NormalState ? window : 0; | 692 return state == NormalState ? window : 0; |
697 } | 693 } |
698 XFree(data); | 694 XFree(data); |
699 if (!XQueryTree(display_, window, &root, &parent, &children, | 695 if (!XQueryTree(display_, window, &root, &parent, &children, |
700 &num_children)) { | 696 &num_children)) { |
701 LOG(LS_ERROR) << "Failed to query for child windows although window" | 697 LOG(LS_ERROR) << "Failed to query for child windows although window" |
702 << "does not have a valid WM_STATE."; | 698 << "does not have a valid WM_STATE."; |
703 return 0; | 699 return 0; |
704 } | 700 } |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
782 } | 778 } |
783 | 779 |
784 bool X11WindowPicker::IsVisible(const WindowId& id) { | 780 bool X11WindowPicker::IsVisible(const WindowId& id) { |
785 return enumerator_->IsVisible(id); | 781 return enumerator_->IsVisible(id); |
786 } | 782 } |
787 | 783 |
788 bool X11WindowPicker::MoveToFront(const WindowId& id) { | 784 bool X11WindowPicker::MoveToFront(const WindowId& id) { |
789 return enumerator_->MoveToFront(id); | 785 return enumerator_->MoveToFront(id); |
790 } | 786 } |
791 | 787 |
792 | 788 uint8_t* X11WindowPicker::GetWindowIcon(const WindowId& id, |
793 uint8* X11WindowPicker::GetWindowIcon(const WindowId& id, int* width, | 789 int* width, |
794 int* height) { | 790 int* height) { |
795 return enumerator_->GetWindowIcon(id, width, height); | 791 return enumerator_->GetWindowIcon(id, width, height); |
796 } | 792 } |
797 | 793 |
798 uint8* X11WindowPicker::GetWindowThumbnail(const WindowId& id, int width, | 794 uint8_t* X11WindowPicker::GetWindowThumbnail(const WindowId& id, |
| 795 int width, |
799 int height) { | 796 int height) { |
800 return enumerator_->GetWindowThumbnail(id, width, height); | 797 return enumerator_->GetWindowThumbnail(id, width, height); |
801 } | 798 } |
802 | 799 |
803 int X11WindowPicker::GetNumDesktops() { | 800 int X11WindowPicker::GetNumDesktops() { |
804 return enumerator_->GetNumDesktops(); | 801 return enumerator_->GetNumDesktops(); |
805 } | 802 } |
806 | 803 |
807 uint8* X11WindowPicker::GetDesktopThumbnail(const DesktopId& id, | 804 uint8_t* X11WindowPicker::GetDesktopThumbnail(const DesktopId& id, |
808 int width, | 805 int width, |
809 int height) { | 806 int height) { |
810 return enumerator_->GetDesktopThumbnail(id, width, height); | 807 return enumerator_->GetDesktopThumbnail(id, width, height); |
811 } | 808 } |
812 | 809 |
813 bool X11WindowPicker::GetDesktopDimensions(const DesktopId& id, int* width, | 810 bool X11WindowPicker::GetDesktopDimensions(const DesktopId& id, int* width, |
814 int* height) { | 811 int* height) { |
815 return enumerator_->GetDesktopDimensions(id, width, height); | 812 return enumerator_->GetDesktopDimensions(id, width, height); |
816 } | 813 } |
817 | 814 |
818 } // namespace rtc | 815 } // namespace rtc |
OLD | NEW |