You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

282 lines
5.9KB

  1. //
  2. // file: osdialog_zenity.cpp
  3. // author: bsp
  4. // license: CC0 (public domain)
  5. // created: 24May2019
  6. // changed:
  7. //
  8. // Enable / disable debug messages
  9. #define Dprintf if(1);else printf
  10. #include <string>
  11. #include <assert.h>
  12. #include <stdlib.h>
  13. #include <string.h>
  14. #include <stdio.h>
  15. #include "osdialog.h"
  16. #define ZENITY_CMD "/usr/bin/zenity"
  17. #define DLG_TITLE "Rack"
  18. #define MAX_BUF_SIZE (65536)
  19. #ifndef NULL
  20. #define NULL ((void*)0)
  21. #endif // NULL
  22. /* @function psystem,String cmd,char access,String buf:int
  23. Invoke system command
  24. @arg cmd Command line
  25. @arg buf Input resp. output buffer
  26. @return Number of bytes read resp. written
  27. */
  28. static int loc_psystem(const char *_cmd, std::string &_buf) {
  29. int r = 0;
  30. Dprintf("osdialog_zenity: loc_psystem(cmd=\'%s\')\n", _cmd);
  31. char *buf = new char[MAX_BUF_SIZE];
  32. _buf.clear();
  33. if(NULL != buf)
  34. {
  35. FILE *f;
  36. #ifdef _MSC_VER
  37. f=::_popen(_cmd, "r");
  38. #else
  39. f=::popen(_cmd, "r");
  40. #endif
  41. int fe = ferror(f);
  42. if(NULL != f)
  43. {
  44. r = (int)::fread(buf, 1, MAX_BUF_SIZE-1, f);
  45. fe = ferror(f);
  46. if( ((unsigned int)r+1) < (MAX_BUF_SIZE-1) )
  47. {
  48. buf[r] = 0;
  49. _buf = buf;
  50. }
  51. #ifdef _MSC_VER
  52. ::_pclose(f);
  53. #else
  54. ::pclose(f);
  55. #endif
  56. }
  57. if( (0 != fe) || (NULL == f) )
  58. {
  59. printf("[---] osdialog_zenity: psystem(%s, \'r\', ..) failed with error code %i.\n",
  60. _cmd,
  61. fe
  62. );
  63. }
  64. delete [] buf;
  65. } // if buf
  66. return r;
  67. }
  68. static int loc_system(const char *_cmd) {
  69. Dprintf("osdialog_zenity: loc_system(cmd=\'%s\')\n", _cmd);
  70. int r = ::system(_cmd);
  71. return r;
  72. }
  73. extern "C" {
  74. int osdialog_message(osdialog_message_level level, osdialog_message_buttons buttons, const char *message) {
  75. int r = 0;
  76. std::string cmd = ZENITY_CMD;
  77. if(OSDIALOG_OK == buttons)
  78. {
  79. switch(level)
  80. {
  81. default:
  82. case OSDIALOG_INFO:
  83. cmd.append(" --info");
  84. break;
  85. case OSDIALOG_WARNING:
  86. cmd.append(" --warning");
  87. break;
  88. case OSDIALOG_ERROR:
  89. cmd.append(" --error");
  90. break;
  91. }
  92. }
  93. else
  94. {
  95. cmd.append(" --question");
  96. switch(level)
  97. {
  98. default:
  99. case OSDIALOG_INFO:
  100. cmd.append(" --icon-name \"dialog-information\"");
  101. break;
  102. case OSDIALOG_WARNING:
  103. cmd.append(" --icon-name \"dialog-warning\"");
  104. break;
  105. case OSDIALOG_ERROR:
  106. cmd.append(" --icon-name \"dialog-error\"");
  107. break;
  108. }
  109. }
  110. cmd.append(" --text=\"");
  111. cmd.append(message);
  112. cmd.append("\"");
  113. cmd.append(" --title \"" DLG_TITLE "\"");
  114. r = loc_system(cmd.c_str());
  115. r = (256 == r) ? 0 : 1;
  116. return r;
  117. }
  118. char *osdialog_file(osdialog_file_action action, const char *path, const char *filename, osdialog_filters *filters) {
  119. char *r = NULL;
  120. std::string cmd = ZENITY_CMD;
  121. cmd.append(" --file-selection");
  122. switch(action)
  123. {
  124. default:
  125. case OSDIALOG_OPEN:
  126. break;
  127. case OSDIALOG_OPEN_DIR:
  128. cmd.append(" --directory");
  129. break;
  130. case OSDIALOG_SAVE:
  131. cmd.append(" --save --confirm-overwrite");
  132. break;
  133. }
  134. osdialog_filters *cf = filters;
  135. while(NULL != cf)
  136. {
  137. cmd.append(" --file-filter \"");
  138. cmd.append(cf->name);
  139. cmd.append(" (");
  140. osdialog_filter_patterns *cp = cf->patterns;
  141. while(NULL != cp)
  142. {
  143. if(cp != cf->patterns)
  144. cmd.append(", ");
  145. cmd.append(cp->pattern);
  146. cp = cp->next;
  147. }
  148. cmd.append(") | ");
  149. cp = cf->patterns;
  150. while(NULL != cp)
  151. {
  152. cmd.append("*.");
  153. cmd.append(cp->pattern);
  154. cp = cp->next;
  155. if(NULL != cp)
  156. cmd.append(" ");
  157. }
  158. cmd.append("\"");
  159. cf = cf->next;
  160. }
  161. cmd.append(" --filename \"");
  162. if(NULL != path)
  163. {
  164. cmd.append(path);
  165. cmd.append("/");
  166. }
  167. if(NULL != filename)
  168. {
  169. cmd.append(filename);
  170. }
  171. cmd.append("\"");
  172. cmd.append(" --title \"" DLG_TITLE "\"");
  173. std::string buf;
  174. if(loc_psystem(cmd.c_str(), buf) > 1)
  175. {
  176. Dprintf("osdialog_zenity: file selection returned buf=\'%s\'\n", buf.c_str());
  177. size_t bufSize = buf.size() - 1;
  178. r = (char*)malloc((bufSize + 1) * sizeof(char));
  179. if(NULL != r)
  180. {
  181. memcpy((void*)r, (void*)buf.c_str(), bufSize);
  182. r[bufSize] = 0;
  183. }
  184. }
  185. return r;
  186. }
  187. int osdialog_color_picker(osdialog_color *color, int opacity) {
  188. int r = 0;
  189. (void)opacity; // 1=enable opacity slider
  190. std::string cmd = ZENITY_CMD;
  191. cmd.append(" --color-selection");
  192. if(NULL != color)
  193. {
  194. cmd.append(" --color \"rgba(");
  195. char buf[10];
  196. sprintf(buf, "%d,%d,%d,%f", color->r, color->g, color->b, color->a / 255.0f);
  197. cmd.append(buf);
  198. cmd.append(")\"");
  199. }
  200. cmd.append(" --title \"" DLG_TITLE "\"");
  201. #if 0
  202. cmd.append(" --show-palette");
  203. #endif
  204. std::string buf;
  205. if(loc_psystem(cmd.c_str(), buf) > 1)
  206. {
  207. Dprintf("osdialog_zenity: color selection returned buf=\'%s\'\n", buf.c_str());
  208. {
  209. unsigned int r = 0u, g = 0u, b = 0u;
  210. float a = 1.0f;
  211. if(NULL != strstr(buf.c_str(), "rgba("))
  212. {
  213. // (note) not supported by Zenity 3.22.0 (latest version as of 24May2019)
  214. sscanf(buf.c_str(), "rgba(%u,%u,%u,%f)", &r, &g, &b, &a);
  215. color->r = (unsigned char)(r);
  216. color->g = (unsigned char)(g);
  217. color->b = (unsigned char)(b);
  218. color->a = (unsigned char)(a * 255u);
  219. }
  220. else
  221. {
  222. sscanf(buf.c_str(), "rgb(%u,%u,%u)", &r, &g, &b);
  223. color->r = (unsigned char)(r);
  224. color->g = (unsigned char)(g);
  225. color->b = (unsigned char)(b);
  226. }
  227. }
  228. r = 1;
  229. }
  230. return r;
  231. }
  232. } // extern "C"