Line data Source code
1 : /* This Source Code Form is subject to the terms of the Mozilla Public
2 : * License, v. 2.0. If a copy of the MPL was not distributed with this file,
3 : * You can obtain one at http://mozilla.org/MPL/2.0/. */
4 :
5 : #include "webrtc/modules/desktop_capture/x11/desktop_device_info_x11.h"
6 : #include "webrtc/system_wrappers/include/logging.h"
7 : #include <inttypes.h>
8 : #include <unistd.h>
9 : #include <stdio.h>
10 : #include "webrtc/modules/desktop_capture/x11/shared_x_util.h"
11 : #include "webrtc/modules/desktop_capture/x11/x_error_trap.h"
12 : #include "webrtc/modules/desktop_capture/x11/x_server_pixel_buffer.h"
13 :
14 : namespace webrtc {
15 :
16 0 : DesktopDeviceInfo * DesktopDeviceInfoImpl::Create() {
17 0 : DesktopDeviceInfoX11 * pDesktopDeviceInfo = new DesktopDeviceInfoX11();
18 0 : if (pDesktopDeviceInfo && pDesktopDeviceInfo->Init() != 0){
19 0 : delete pDesktopDeviceInfo;
20 0 : pDesktopDeviceInfo = NULL;
21 : }
22 0 : return pDesktopDeviceInfo;
23 : }
24 :
25 0 : DesktopDeviceInfoX11::DesktopDeviceInfoX11() {
26 0 : }
27 :
28 0 : DesktopDeviceInfoX11::~DesktopDeviceInfoX11() {
29 0 : }
30 :
31 0 : void DesktopDeviceInfoX11::MultiMonitorScreenshare()
32 : {
33 0 : DesktopDisplayDevice* desktop_device_info = new DesktopDisplayDevice;
34 0 : if (desktop_device_info) {
35 0 : desktop_device_info->setScreenId(webrtc::kFullDesktopScreenId);
36 0 : desktop_device_info->setDeviceName("Primary Monitor");
37 :
38 : char idStr[64];
39 0 : snprintf(idStr, sizeof(idStr), "%" PRIdPTR, desktop_device_info->getScreenId());
40 0 : desktop_device_info->setUniqueIdName(idStr);
41 0 : desktop_display_list_[desktop_device_info->getScreenId()] = desktop_device_info;
42 : }
43 0 : }
44 :
45 0 : void DesktopDeviceInfoX11::InitializeScreenList() {
46 0 : MultiMonitorScreenshare();
47 0 : }
48 :
49 0 : void DesktopDeviceInfoX11::InitializeApplicationList() {
50 : //List all running applications exclude background process.
51 0 : rtc::scoped_refptr<SharedXDisplay> SharedDisplay = SharedXDisplay::CreateDefault();
52 0 : XErrorTrap error_trap(SharedDisplay->display());
53 :
54 0 : WindowUtilX11 window_util_x11(SharedDisplay);
55 0 : int num_screens = XScreenCount(SharedDisplay->display());
56 0 : for (int screen = 0; screen < num_screens; ++screen) {
57 0 : ::Window root_window = XRootWindow(SharedDisplay->display(), screen);
58 : ::Window parent;
59 : ::Window *children;
60 : unsigned int num_children;
61 0 : int status = XQueryTree(SharedDisplay->display(), root_window, &root_window, &parent,
62 0 : &children, &num_children);
63 0 : if (status == 0) {
64 0 : LOG(LS_ERROR) << "Failed to query for child windows for screen " << screen;
65 0 : continue;
66 : }
67 :
68 0 : for (unsigned int i = 0; i < num_children; ++i) {
69 0 : ::Window app_window = window_util_x11.GetApplicationWindow(children[num_children - 1 - i]);
70 :
71 0 : if (!app_window
72 0 : || window_util_x11.IsDesktopElement(app_window)
73 0 : || window_util_x11.GetWindowStatus(app_window) == WithdrawnState) {
74 0 : continue;
75 : }
76 :
77 0 : unsigned int processId = window_util_x11.GetWindowProcessID(app_window);
78 : // filter out non-process
79 0 : if (processId == 0) {
80 0 : continue;
81 : }
82 : // filter out current process
83 0 : if (processId == getpid()) {
84 0 : continue;
85 : }
86 :
87 : // filter out existing applications, after incrementing its window count
88 0 : DesktopApplicationList::iterator itr = desktop_application_list_.find(processId);
89 0 : if (itr != desktop_application_list_.end()) {
90 0 : itr->second->setWindowCount(itr->second->getWindowCount() + 1);
91 0 : continue;
92 : }
93 :
94 : // Add one application
95 0 : DesktopApplication *pDesktopApplication = new DesktopApplication;
96 0 : if (!pDesktopApplication) {
97 0 : continue;
98 : }
99 :
100 : // process id
101 0 : pDesktopApplication->setProcessId(processId);
102 : // initialize count to 1
103 0 : pDesktopApplication->setWindowCount(1);
104 :
105 : // process path name
106 0 : pDesktopApplication->setProcessPathName("");
107 :
108 : // application name
109 0 : std::string strAppName;
110 0 : window_util_x11.GetWindowTitle(app_window, &strAppName);
111 0 : pDesktopApplication->setProcessAppName(strAppName.c_str());
112 :
113 : // unique id name
114 : char idStr[64];
115 0 : snprintf(idStr, sizeof(idStr), "%ld", pDesktopApplication->getProcessId());
116 0 : pDesktopApplication->setUniqueIdName(idStr);
117 0 : desktop_application_list_[processId] = pDesktopApplication;
118 : }
119 :
120 : // re-walk the application list, prepending the window count to the application name
121 0 : DesktopApplicationList::iterator itr;
122 0 : for (itr = desktop_application_list_.begin(); itr != desktop_application_list_.end(); itr++) {
123 0 : DesktopApplication *pApp = itr->second;
124 : // localized name can be *VERY* large
125 : char nameStr[BUFSIZ];
126 0 : snprintf(nameStr, sizeof(nameStr), "%d\x1e%s",
127 0 : pApp->getWindowCount(), pApp->getProcessAppName());
128 0 : pApp->setProcessAppName(nameStr);
129 : }
130 :
131 0 : if (children) {
132 0 : XFree(children);
133 : }
134 : }
135 0 : }
136 :
137 : } //namespace webrtc
|