LCOV - code coverage report
Current view: top level - media/webrtc/trunk/webrtc/modules/desktop_capture/x11 - shared_x_util.cc (source / functions) Hit Total Coverage
Test: output.info Lines: 0 145 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 10 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  *  Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
       3             :  *
       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
       6             :  *  tree. An additional intellectual property rights grant can be found
       7             :  *  in the file PATENTS.  All contributing project authors may
       8             :  *  be found in the AUTHORS file in the root of the source tree.
       9             :  */
      10             : 
      11             : #include "webrtc/modules/desktop_capture/x11/shared_x_util.h"
      12             : 
      13             : namespace webrtc {
      14             : 
      15           0 : WindowUtilX11::WindowUtilX11(rtc::scoped_refptr<SharedXDisplay> x_display) {
      16           0 :   x_display_ = x_display;
      17           0 :   wm_state_atom_ = XInternAtom(display(), "WM_STATE", True);
      18           0 :   window_type_atom_ = XInternAtom(display(), "_NET_WM_WINDOW_TYPE", True);
      19           0 :   normal_window_type_atom_ = XInternAtom(display(), "_NET_WM_WINDOW_TYPE_NORMAL", True);
      20           0 :   process_atom_ = XInternAtom(display(), "_NET_WM_PID", True);
      21           0 :   frame_extends_atom_ = XInternAtom(display(), "_NET_FRAME_EXTENTS", True);
      22           0 : }
      23             : 
      24           0 : WindowUtilX11::~WindowUtilX11() {
      25           0 : }
      26             : 
      27           0 : ::Window WindowUtilX11::GetApplicationWindow(::Window window) {
      28             :   // Get WM_STATE property of the window.
      29           0 :   XWindowProperty<uint32_t> window_state(display(), window, wm_state_atom_);
      30             : 
      31             :   // WM_STATE is considered to be set to WithdrawnState when it missing.
      32           0 :   int32_t state = window_state.is_valid() ? *window_state.data() : WithdrawnState;
      33             : 
      34           0 :   if (state == NormalState) {
      35             :     // Window has WM_STATE==NormalState. Return it.
      36           0 :     return window;
      37           0 :   } else if (state == IconicState) {
      38             :     // Window is in minimized. Skip it.
      39           0 :     return 0;
      40             :   }
      41             : 
      42             :   // If the window is in WithdrawnState then look at all of its children.
      43             :   ::Window root, parent;
      44             :   ::Window *children;
      45             :   unsigned int num_children;
      46           0 :   if (!XQueryTree(display(), window, &root, &parent, &children, &num_children)) {
      47           0 :     LOG(LS_ERROR) << "Failed to query for child windows although window"
      48           0 :                   << "does not have a valid WM_STATE.";
      49           0 :     return 0;
      50             :   }
      51           0 :   ::Window app_window = 0;
      52           0 :   for (unsigned int i = 0; i < num_children; ++i) {
      53           0 :     app_window = GetApplicationWindow(children[i]);
      54           0 :     if (app_window) {
      55           0 :       break;
      56             :     }
      57             :   }
      58             : 
      59           0 :   if (children) {
      60           0 :     XFree(children);
      61             :   }
      62           0 :   return app_window;
      63             : }
      64             : 
      65           0 : bool WindowUtilX11::IsDesktopElement(::Window window) {
      66           0 :   if (window == 0) {
      67           0 :     return false;
      68             :   }
      69             : 
      70             :   // First look for _NET_WM_WINDOW_TYPE. The standard
      71             :   // (http://standards.freedesktop.org/wm-spec/latest/ar01s05.html#id2760306)
      72             :   // says this hint *should* be present on all windows, and we use the existence
      73             :   // of _NET_WM_WINDOW_TYPE_NORMAL in the property to indicate a window is not
      74             :   // a desktop element (that is, only "normal" windows should be shareable).
      75           0 :   XWindowProperty<uint32_t> window_type(display(), window, window_type_atom_);
      76           0 :   if (window_type.is_valid() && window_type.size() > 0) {
      77           0 :     uint32_t* end = window_type.data() + window_type.size();
      78           0 :     bool is_normal = (end != std::find(window_type.data(), end, normal_window_type_atom_));
      79           0 :     return !is_normal;
      80             :   }
      81             : 
      82             :   // Fall back on using the hint.
      83             :   XClassHint class_hint;
      84           0 :   Status status = XGetClassHint(display(), window, &class_hint);
      85           0 :   bool result = false;
      86           0 :   if (status == 0) {
      87             :     // No hints, assume this is a normal application window.
      88           0 :     return result;
      89             :   }
      90             : 
      91           0 :   if (strcmp("gnome-panel", class_hint.res_name) == 0 ||
      92           0 :       strcmp("desktop_window", class_hint.res_name) == 0) {
      93           0 :     result = true;
      94             :   }
      95           0 :   XFree(class_hint.res_name);
      96           0 :   XFree(class_hint.res_class);
      97           0 :   return result;
      98             : }
      99             : 
     100           0 : bool WindowUtilX11::GetWindowTitle(::Window window, std::string* title) {
     101             :   int status;
     102           0 :   bool result = false;
     103             :   XTextProperty window_name;
     104           0 :   window_name.value = NULL;
     105           0 :   if (window) {
     106           0 :     char * pWinName = NULL;
     107           0 :     if(XFetchName(display(), window, &pWinName)){
     108           0 :       *title = pWinName;
     109           0 :       XFree(pWinName);
     110           0 :       result = true;
     111             :     }
     112             :     else{
     113           0 :       status = XGetWMName(display(), window, &window_name);
     114           0 :       if (status && window_name.value && window_name.nitems) {
     115             :         int cnt;
     116           0 :         char **list = NULL;
     117           0 :         status = Xutf8TextPropertyToTextList(display(), &window_name, &list,
     118           0 :                                              &cnt);
     119           0 :         if (status >= Success && cnt && *list) {
     120           0 :           if (cnt > 1) {
     121           0 :             LOG(LS_INFO) << "Window has " << cnt << " text properties, only using the first one.";
     122             :           }
     123           0 :           *title = *list;
     124           0 :           result = true;
     125             :         }
     126           0 :         if (list) {
     127           0 :           XFreeStringList(list);
     128             :         }
     129             :       }
     130           0 :       if (window_name.value) {
     131           0 :         XFree(window_name.value);
     132             :       }
     133             :     }
     134             :   }
     135           0 :   return result;
     136             : }
     137             : 
     138           0 : bool WindowUtilX11::BringWindowToFront(::Window window) {
     139           0 :   if (!window) {
     140           0 :     return false;
     141             :   }
     142             : 
     143             :   unsigned int num_children;
     144             :   ::Window* children;
     145             :   ::Window parent;
     146             :   ::Window root;
     147             :   // Find the root window to pass event to.
     148           0 :   int status = XQueryTree(display(), window, &root, &parent, &children, &num_children);
     149           0 :   if (status == 0) {
     150           0 :     LOG(LS_ERROR) << "Failed to query for the root window.";
     151           0 :     return false;
     152             :   }
     153             : 
     154           0 :   if (children) {
     155           0 :     XFree(children);
     156             :   }
     157             : 
     158           0 :   XRaiseWindow(display(), window);
     159             : 
     160             :   // Some window managers (e.g., metacity in GNOME) consider it illegal to
     161             :   // raise a window without also giving it input focus with
     162             :   // _NET_ACTIVE_WINDOW, so XRaiseWindow() on its own isn't enough.
     163           0 :   Atom atom = XInternAtom(display(), "_NET_ACTIVE_WINDOW", True);
     164           0 :   if (atom != None) {
     165             :     XEvent xev;
     166           0 :     xev.xclient.type = ClientMessage;
     167           0 :     xev.xclient.serial = 0;
     168           0 :     xev.xclient.send_event = True;
     169           0 :     xev.xclient.window = window;
     170           0 :     xev.xclient.message_type = atom;
     171             : 
     172             :     // The format member is set to 8, 16, or 32 and specifies whether the
     173             :     // data should be viewed as a list of bytes, shorts, or longs.
     174           0 :     xev.xclient.format = 32;
     175             : 
     176           0 :     memset(xev.xclient.data.l, 0, sizeof(xev.xclient.data.l));
     177             : 
     178           0 :     XSendEvent(display(),
     179             :                root,
     180             :                False,
     181             :                SubstructureRedirectMask | SubstructureNotifyMask,
     182           0 :                &xev);
     183             :   }
     184           0 :   XFlush(display());
     185           0 :   return true;
     186             : }
     187             : 
     188           0 : int WindowUtilX11::GetWindowProcessID(::Window window) {
     189             :   // Get _NET_WM_PID property of the window.
     190           0 :   XWindowProperty<uint32_t> process_id(display(), window, process_atom_);
     191             : 
     192           0 :   return process_id.is_valid() ? *process_id.data() : 0;
     193             : }
     194             : 
     195           0 : int32_t WindowUtilX11::GetWindowStatus(::Window window) {
     196             :   // Get WM_STATE property of the window.
     197           0 :   XWindowProperty<uint32_t> window_state(display(), window, wm_state_atom_);
     198             : 
     199             :   // WM_STATE is considered to be set to -1 when it missing.
     200           0 :   int32_t state = window_state.is_valid() ? *window_state.data() : -1;
     201           0 :   return state;
     202             : }
     203             : 
     204           0 : bool WindowUtilX11::GetWindowFrameExtents(::Window window,
     205             :                                           int32_t &left, int32_t &top,
     206             :                                           int32_t &right, int32_t &bottom) {
     207             :   //reset it first
     208           0 :   left = top = right = bottom =0;
     209             : 
     210             :   Atom actual_type;
     211             :   int actual_format;
     212             :   unsigned long nitems;
     213             :   unsigned long bytes_remaining;
     214             :   unsigned char *data;
     215             :   int status;
     216             : 
     217           0 :   status = XGetWindowProperty(display(),
     218             :                               window,
     219             :                               frame_extends_atom_,
     220             :                               0,      // long_offset
     221             :                               4,      // long_length - we expect 4 32-bit values for _NET_FRAME_EXTENTS
     222             :                               False,  // delete
     223             :                               AnyPropertyType,
     224             :                               &actual_type,
     225             :                               &actual_format,
     226             :                               &nitems,
     227             :                               &bytes_remaining,
     228           0 :                               &data);
     229             : 
     230           0 :   if (status == Success) {
     231           0 :     if ((nitems == 4) && (bytes_remaining == 0)) {
     232           0 :       long *data_as_long = (long *)((void *) data);
     233           0 :       left   = (int) *(data_as_long++);
     234           0 :       right  = (int) *(data_as_long++);
     235           0 :       top    = (int) *(data_as_long++);
     236           0 :       bottom = (int) *(data_as_long++);
     237           0 :       return true;
     238             :     }
     239           0 :     XFree (data);
     240             :   }
     241           0 :   return false;
     242             : }
     243             : 
     244           0 : bool WindowUtilX11::GetWindowRect(::Window window, XRectangle & rcWindow, bool bWithFrame) {
     245             :   // reset
     246           0 :   rcWindow.x = rcWindow.y = rcWindow.width =  rcWindow.height = 0;
     247             : 
     248             :   // get window info
     249             :   XWindowAttributes win_info;
     250           0 :   if (!XGetWindowAttributes(display(), window, &win_info)) {
     251           0 :     return false;
     252             :   }
     253             : 
     254             :   int absx,absy;
     255             :   ::Window temp_win;
     256           0 :   ::Window root_win = DefaultRootWindow(display());
     257           0 :   if (!XTranslateCoordinates(display(), window, root_win, 0, 0, &absx, &absy, &temp_win)) {
     258           0 :     return false;
     259             :   }
     260             : 
     261             :   // Adjust to limit in screen
     262           0 :   int nScreenCX = DisplayWidth(display(), DefaultScreen(display()));
     263           0 :   int nScreenCY = DisplayHeight(display(), DefaultScreen(display()));
     264             : 
     265           0 :   if (absx < 0) {
     266           0 :     win_info.width += absx;
     267           0 :     absx = 0;
     268           0 :   } else if ((absx + win_info.width) > nScreenCX) {
     269           0 :     win_info.width = nScreenCX - absx;
     270             :   }
     271           0 :   if (absy < 0) {
     272           0 :     win_info.height += absy;
     273           0 :     absy = 0;
     274           0 :   } else if ((absy + win_info.height) > nScreenCY) {
     275           0 :     win_info.height = nScreenCY - absy;
     276             :   }
     277             : 
     278             :   // data setting
     279           0 :   rcWindow.x = absx;
     280           0 :   rcWindow.y = absy;
     281           0 :   rcWindow.width = win_info.width;
     282           0 :   rcWindow.height = win_info.height;
     283             : 
     284           0 :   if (bWithFrame) {
     285             :     int left;
     286             :     int right;
     287             :     int top;
     288             :     int bottom;
     289           0 :     if (GetWindowFrameExtents(window, left, top, right, bottom)) {
     290           0 :       rcWindow.x -= left;
     291           0 :       rcWindow.y -= top;
     292           0 :       rcWindow.width += (left + right);
     293           0 :       rcWindow.height += (top + bottom);
     294             :     }
     295             :   }
     296           0 :   return true;
     297             : }
     298             : 
     299             : }//namespace webrtc

Generated by: LCOV version 1.13