| 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 |