os.cpp
Go to the documentation of this file.
1 // License: Apache 2.0. See LICENSE file in root directory.
2 // Copyright(c) 2017 Intel Corporation. All Rights Reserved.
3 #ifdef _MSC_VER
4 #ifndef NOMINMAX
5 #define NOMINMAX
6 #endif
7 #endif
8 
9 #include <thread>
10 #include <algorithm>
11 #include <regex>
12 #include <cmath>
13 
14 #include <sys/types.h>
15 #include <sys/stat.h>
16 
17 #include "os.h"
18 
19 #define STB_IMAGE_WRITE_IMPLEMENTATION
20 #include <stb_image_write.h>
21 
22 #include <tinyfiledialogs.h>
23 
24 #ifdef _WIN32
25 #include <windows.h>
26 #include <wchar.h>
27 #include <KnownFolders.h>
28 #include <shlobj.h>
29 #endif
30 
31 #if (defined(_WIN32) || defined(_WIN64))
32 #include "ShellAPI.h"
33 #endif
34 
35 #if defined __linux__ || defined __APPLE__
36 #include <unistd.h>
37 #include <sys/types.h>
38 #include <pwd.h>
39 #endif
40 
41 #include <GLFW/glfw3.h>
42 
43 namespace rs2
44 {
45 
46  // Use shortcuts for long names to avoid trimming of essential data
48  {
49  if (str.length() > width)
50  {
51  std::stringstream ss;
52  ss << str.substr(0, width / 3) << "..." << str.substr(str.length() - width / 3);
53  return ss.str().c_str();
54  }
55  return str;
56  }
57 
58  void open_url(const char* url)
59  {
60 #if (defined(_WIN32) || defined(_WIN64))
61  if (reinterpret_cast<int>(ShellExecuteA(NULL, "open", url, NULL, NULL, SW_SHOW)) < 32)
62  throw std::runtime_error("Failed opening URL");
63 #elif defined __linux__ || defined(__linux__)
64  std::string command_name = "xdg-open ";
65  std::string command = command_name + url;
66  if (system(command.c_str()))
67  throw std::runtime_error("Failed opening URL");
68 #elif __APPLE__
69  std::string command_name = "open ";
70  std::string command = command_name + url;
71  if (system(command.c_str()))
72  throw std::runtime_error("Failed opening URL");
73 #else
74 #pragma message ( "\nLibrealsense couldn't establish OS/Build environment. \
75 Some auxillary functionalities might be affected. Please report this message if encountered")
76 #endif
77  }
78 
79  std::vector<std::string> split_string(std::string& input, char delim)
80  {
81  std::vector<std::string> result;
82  auto e = input.end();
83  auto i = input.begin();
84  while (i != e) {
85  i = find_if_not(i, e, [delim](char c) { return c == delim; });
86  if (i == e) break;
87  auto j = find(i, e, delim);
88  result.emplace_back(i, j);
89  i = j;
90  }
91  return result;
92  }
93 
94  // Helper function to get window rect from GLFW
96  {
97  int width, height;
98  glfwGetWindowSize(window, &width, &height);
99  int xpos, ypos;
100  glfwGetWindowPos(window, &xpos, &ypos);
101 
102  return{ (float)xpos, (float)ypos,
103  (float)width, (float)height };
104  }
105 
106  // Helper function to get monitor rect from GLFW
108  {
109  const GLFWvidmode* mode = glfwGetVideoMode(monitor);
110  int xpos, ypos;
111  glfwGetMonitorPos(monitor, &xpos, &ypos);
112 
113  return{ (float)xpos, (float)ypos,
114  (float)mode->width, (float)mode->height };
115  }
116 
117  // Select appropriate scale factor based on the display
118  // that most of the application is presented on
120  {
121  auto window_rect = get_window_rect(window);
122  int count;
124  if (count == 0) return 1; // Not sure if possible, but better be safe
125 
126  // Find the monitor that covers most of the application pixels:
127  GLFWmonitor* best = monitors[0];
128  float best_area = 0.f;
129  for (int i = 0; i < count; i++)
130  {
131  auto int_area = window_rect.intersection(
132  get_monitor_rect(monitors[i])).area();
133  if (int_area >= best_area)
134  {
135  best_area = int_area;
136  best = monitors[i];
137  }
138  }
139 
140  int widthMM = 0;
141  int heightMM = 0;
142  glfwGetMonitorPhysicalSize(best, &widthMM, &heightMM);
143 
144  // This indicates that the monitor dimentions are unknown
145  if (widthMM * heightMM == 0) return 1;
146 
147  // The actual calculation is somewhat arbitrary, but we are going for
148  // about 1cm buttons, regardless of resultion
149  // We discourage fractional scale factors
150  float how_many_pixels_in_mm =
151  get_monitor_rect(best).area() / (widthMM * heightMM);
152  float scale = sqrt(how_many_pixels_in_mm) / 5.f;
153  if (scale < 1.f) return 1;
154  return (int)(floor(scale));
155  }
156 
157  bool directory_exists(const char* dir)
158  {
159  struct stat info;
160 
161  if (stat(dir, &info ) != 0)
162  return false;
163  else if (info.st_mode & S_IFDIR)
164  return true;
165  else
166  return false;
167  }
168 
169  const char* file_dialog_open(file_dialog_mode flags, const char* filters,
170  const char* default_path, const char* default_name)
171  {
172  std::string def = "";
173  if (default_path) def += default_path;
174  if (default_name && default_path) def += "/";
175  if (default_name) def += default_name;
176  const char* def_ptr = nullptr;
177  if (default_name || default_path)
178  def_ptr = def.c_str();
179  int num_filters = filters == nullptr ? 0 : 1;
180 
181  char const * const * aFilterPatterns = nullptr;
182  char const * aSingleFilterDescription = nullptr;
183 
184  std::vector<std::string> filters_split;
185 
186  if (num_filters)
187  {
188  auto curr = filters;
189  while (*curr != '\0')
190  {
191  auto end = curr + strlen(curr);
192  filters_split.push_back({ curr, end });
193  curr = end + 1;
194  }
195  }
196 
197  std::vector<const char*> filter;
198 
199  if (filters_split.size() == 2)
200  {
201  filter.push_back(filters_split[1].c_str());
202  aFilterPatterns = filter.data();
203  aSingleFilterDescription = filters_split[0].c_str();
204  }
205 
206  if (flags == save_file)
207  {
208  return tinyfd_saveFileDialog("Save File", def_ptr, num_filters, aFilterPatterns, aSingleFilterDescription);
209  }
210  if (flags == open_file)
211  {
212  return tinyfd_openFileDialog("Open File", def_ptr, num_filters, aFilterPatterns, aSingleFilterDescription, 0);
213  }
214  return nullptr;
215  }
216 
217  int save_to_png(const char* filename,
218  size_t pixel_width, size_t pixels_height, size_t bytes_per_pixel,
219  const void* raster_data, size_t stride_bytes)
220  {
221  return stbi_write_png(filename, (int)pixel_width, (int)pixels_height, (int)bytes_per_pixel, raster_data, (int)stride_bytes);
222  }
223 
225  {
227  for (auto rit = path.rbegin(); rit != path.rend(); ++rit)
228  {
229  if (*rit == '\\' || *rit == '/')
230  break;
231  file_name += *rit;
232  }
233  std::reverse(file_name.begin(), file_name.end());
234  return file_name;
235  }
236 
238  {
239  std::time_t now = std::time(NULL);
240  std::tm * ptm = std::localtime(&now);
241  char buffer[16];
242  // Format: 20170529_205500
243  std::strftime(buffer, 16, "%Y%m%d_%H%M%S", ptm);
244  return buffer;
245  }
246 
248  {
250 #ifdef _WIN32
251  if (f == temp_folder)
252  {
253  TCHAR buf[MAX_PATH];
254  if (GetTempPath(MAX_PATH, buf) != 0)
255  {
256  char str[1024];
257  wcstombs(str, buf, 1023);
258  res = str;
259  }
260  }
261  else
262  {
263  GUID folder;
264  switch (f)
265  {
266  case user_desktop: folder = FOLDERID_Desktop;
267  break;
268  case user_documents: folder = FOLDERID_Documents;
269  break;
270  case user_pictures: folder = FOLDERID_Pictures;
271  break;
272  case user_videos: folder = FOLDERID_Videos;
273  break;
274  case app_data: folder = FOLDERID_RoamingAppData;
275  break;
276  default:
277  throw std::invalid_argument(
278  std::string("Value of f (") + std::to_string(f) + std::string(") is not supported"));
279  }
280  PWSTR folder_path = NULL;
281  HRESULT hr = SHGetKnownFolderPath(folder, KF_FLAG_DEFAULT_PATH, NULL, &folder_path);
282  if (SUCCEEDED(hr))
283  {
284  char str[1024];
285  wcstombs(str, folder_path, 1023);
286  CoTaskMemFree(folder_path);
287  res = str;
288  res += "\\";
289  }
290  else
291  {
292  throw std::runtime_error("Failed to get requested special folder");
293  }
294  }
295 #endif //_WIN32
296 #if defined __linux__ || defined __APPLE__
298  {
299  const char* tmp_dir = getenv("TMPDIR");
300  res = tmp_dir ? tmp_dir : "/tmp/";
301  }
302  else
303  {
304  const char* home_dir = getenv("HOME");
305  if (!home_dir)
306  {
307  struct passwd* pw = getpwuid(getuid());
308  home_dir = (pw && pw->pw_dir) ? pw->pw_dir : "";
309  }
310  if (home_dir)
311  {
312  res = home_dir;
313  switch (f)
314  {
315  case user_desktop: res += "/Desktop/";
316  break;
317  case user_documents: res += "/Documents/";
318  break;
319  case user_pictures: res += "/Pictures/";
320  break;
321  case user_videos: res += "/Videos/";
322  break;
323  case app_data: res += "/.";
324  break;
325  default:
326  throw std::invalid_argument(
327  std::string("Value of f (") + std::to_string(f) + std::string(") is not supported"));
328  }
329  }
330  }
331 #endif // defined __linux__ || defined __APPLE__
332  return res;
333  }
334 
335  bool ends_with(const std::string& s, const std::string& suffix)
336  {
337  auto i = s.rbegin(), j = suffix.rbegin();
338  for (; i != s.rend() && j != suffix.rend() && *i == *j;
339  i++, j++);
340  return j == suffix.rend();
341  }
342 
343  bool starts_with(const std::string& s, const std::string& prefix)
344  {
345  auto i = s.begin(), j = prefix.begin();
346  for (; i != s.end() && j != prefix.end() && *i == *j;
347  i++, j++);
348  return j == prefix.end();
349  }
350 
352  {
353 #ifdef _WIN32
354  return "Windows";
355 #else
356 #ifdef __APPLE__
357  return "Mac OS";
358 #else
359 #ifdef __linux__
360  return "Linux";
361 #else
362  return "Unknown";
363 #endif
364 #endif
365 #endif
366  }
367 
368  bool is_debug()
369  {
370 #ifndef NDEBUG
371  return false;
372 #else
373 #ifndef _DEBUG
374  return false;
375 #else
376  return true;
377 #endif
378 #endif
379  }
380 
382  {
383  // based on https://stackoverflow.com/a/17708801
384  using namespace std;
385 
386  ostringstream escaped;
387  escaped.fill('0');
388  escaped << hex;
389 
390  for (string::const_iterator i = value.begin(), n = value.end(); i != n; ++i) {
391  string::value_type c = (*i);
392 
393  // Keep alphanumeric and other accepted characters intact
394  if (isalnum(c) || c == '-' || c == '_' || c == '.' || c == '~') {
395  escaped << c;
396  continue;
397  }
398 
399  // Any other characters are percent-encoded
400  escaped << uppercase;
401  escaped << '%' << setw(2) << int((unsigned char)c);
402  escaped << nouppercase;
403  }
404 
405  return escaped.str();
406  }
407 }
GLuint GLuint end
int height
Definition: glfw3.h:1532
char const * tinyfd_saveFileDialog(char const *const aTitle, char const *const aDefaultPathAndFile, int const aNumOfFilterPatterns, char const *const *const aFilterPatterns, char const *const aSingleFilterDescription)
GLFWAPI void glfwGetWindowSize(GLFWwindow *window, int *width, int *height)
Retrieves the size of the client area of the specified window.
Definition: window.c:544
The header of the GLFW 3 API.
GLdouble s
GLenum GLenum GLenum GLenum GLenum scale
Definition: glext.h:10806
int width
Definition: glfw3.h:1529
GLsizei const GLchar *const * path
Definition: glext.h:4276
GLFWAPI const GLFWvidmode * glfwGetVideoMode(GLFWmonitor *monitor)
Returns the current mode of the specified monitor.
Definition: monitor.c:417
GLfloat value
struct GLFWmonitor GLFWmonitor
std::string get_folder_path(special_folder f)
Definition: os.cpp:247
std::string get_timestamped_file_name()
Definition: os.cpp:237
rect get_monitor_rect(GLFWmonitor *monitor)
Definition: os.cpp:107
system
Definition: file.py:10
Definition: cah-model.h:10
GLsizei const GLchar *const * string
bool is_debug()
Definition: os.cpp:368
std::vector< std::string > split_string(std::string &input, char delim)
Definition: os.cpp:79
GLdouble n
Definition: glext.h:1966
e
Definition: rmse.py:177
GLenum GLfloat * buffer
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
file_dialog_mode
Definition: os.h:39
bool ends_with(const std::string &s, const std::string &suffix)
Definition: os.cpp:335
std::string truncate_string(const std::string &str, size_t width)
Definition: os.cpp:47
bool directory_exists(const char *dir)
Definition: os.cpp:157
GLenum GLuint GLenum GLsizei const GLchar * buf
GLdouble f
GLenum mode
GLFWAPI GLFWmonitor ** glfwGetMonitors(int *count)
Returns the currently connected monitors.
Definition: monitor.c:296
const GLubyte * c
Definition: glext.h:12690
void open_url(const char *url)
Definition: os.cpp:58
std::string url_encode(const std::string &value)
Definition: os.cpp:381
GLint GLsizei GLsizei height
GLbitfield flags
def find(dir, mask)
Definition: file.py:25
GLint j
const char * file_dialog_open(file_dialog_mode flags, const char *filters, const char *default_path, const char *default_name)
Definition: os.cpp:169
GLuint * monitors
Definition: glext.h:5686
int save_to_png(const char *filename, size_t pixel_width, size_t pixels_height, size_t bytes_per_pixel, const void *raster_data, size_t stride_bytes)
Definition: os.cpp:217
int pick_scale_factor(GLFWwindow *window)
Definition: os.cpp:119
GLFWAPI void glfwGetMonitorPos(GLFWmonitor *monitor, int *xpos, int *ypos)
Returns the position of the monitor&#39;s viewport on the virtual screen.
Definition: monitor.c:318
std::string get_file_name(const std::string &path)
Definition: os.cpp:224
Video mode type.
Definition: glfw3.h:1525
char const * tinyfd_openFileDialog(char const *const aTitle, char const *const aDefaultPathAndFile, int const aNumOfFilterPatterns, char const *const *const aFilterPatterns, char const *const aSingleFilterDescription, int const aAllowMultipleSelects)
GLFWAPI void glfwGetWindowPos(GLFWwindow *window, int *xpos, int *ypos)
Retrieves the position of the client area of the specified window.
Definition: window.c:517
GLenum GLenum GLenum input
Definition: glext.h:10805
STBIWDEF int stbi_write_png(char const *filename, int w, int h, int comp, const void *data, int stride_in_bytes)
rect get_window_rect(GLFWwindow *window)
Definition: os.cpp:95
static double xpos
Definition: splitview.c:33
GLint GLsizei count
static const FGuid GUID
GLFWAPI void glfwGetMonitorPhysicalSize(GLFWmonitor *monitor, int *widthMM, int *heightMM)
Returns the physical size of the monitor.
Definition: monitor.c:333
bool starts_with(const std::string &s, const std::string &prefix)
Definition: os.cpp:343
#define NULL
Definition: tinycthread.c:47
int i
GLuint res
Definition: glext.h:8856
special_folder
Definition: os.h:51
std::string get_os_name()
Definition: os.cpp:351
float area() const
Definition: rendering.h:558
GLuint64EXT * result
Definition: glext.h:10921
static const char * default_path
Definition: model-views.h:130
struct GLFWwindow GLFWwindow
GLint GLsizei width
static double ypos
Definition: splitview.c:33
std::string to_string(T value)


librealsense2
Author(s): Sergey Dorodnicov , Doron Hirshberg , Mark Horn , Reagan Lopez , Itay Carpis
autogenerated on Mon May 3 2021 02:47:39