// // file: osdialog_zenity.cpp // author: bsp // license: CC0 (public domain) // created: 24May2019 // changed: // // Enable / disable debug messages #define Dprintf if(1);else printf #include #include #include #include #include #include "osdialog.h" #define ZENITY_CMD "/usr/bin/zenity" #define DLG_TITLE "Rack" #define MAX_BUF_SIZE (65536) #ifndef NULL #define NULL ((void*)0) #endif // NULL /* @function psystem,String cmd,char access,String buf:int Invoke system command @arg cmd Command line @arg buf Input resp. output buffer @return Number of bytes read resp. written */ static int loc_psystem(const char *_cmd, std::string &_buf) { int r = 0; Dprintf("osdialog_zenity: loc_psystem(cmd=\'%s\')\n", _cmd); char *buf = new char[MAX_BUF_SIZE]; _buf.clear(); if(NULL != buf) { FILE *f; #ifdef _MSC_VER f=::_popen(_cmd, "r"); #else f=::popen(_cmd, "r"); #endif int fe = ferror(f); if(NULL != f) { r = (int)::fread(buf, 1, MAX_BUF_SIZE-1, f); fe = ferror(f); if( ((unsigned int)r+1) < (MAX_BUF_SIZE-1) ) { buf[r] = 0; _buf = buf; } #ifdef _MSC_VER ::_pclose(f); #else ::pclose(f); #endif } if( (0 != fe) || (NULL == f) ) { printf("[---] osdialog_zenity: psystem(%s, \'r\', ..) failed with error code %i.\n", _cmd, fe ); } delete [] buf; } // if buf return r; } static int loc_system(const char *_cmd) { Dprintf("osdialog_zenity: loc_system(cmd=\'%s\')\n", _cmd); int r = ::system(_cmd); return r; } extern "C" { int osdialog_message(osdialog_message_level level, osdialog_message_buttons buttons, const char *message) { int r = 0; std::string cmd = ZENITY_CMD; if(OSDIALOG_OK == buttons) { switch(level) { default: case OSDIALOG_INFO: cmd.append(" --info"); break; case OSDIALOG_WARNING: cmd.append(" --warning"); break; case OSDIALOG_ERROR: cmd.append(" --error"); break; } } else { cmd.append(" --question"); switch(level) { default: case OSDIALOG_INFO: cmd.append(" --icon-name \"dialog-information\""); break; case OSDIALOG_WARNING: cmd.append(" --icon-name \"dialog-warning\""); break; case OSDIALOG_ERROR: cmd.append(" --icon-name \"dialog-error\""); break; } } cmd.append(" --text=\""); cmd.append(message); cmd.append("\""); cmd.append(" --title \"" DLG_TITLE "\""); r = loc_system(cmd.c_str()); r = (256 == r) ? 0 : 1; return r; } char *osdialog_file(osdialog_file_action action, const char *path, const char *filename, osdialog_filters *filters) { char *r = NULL; std::string cmd = ZENITY_CMD; cmd.append(" --file-selection"); switch(action) { default: case OSDIALOG_OPEN: break; case OSDIALOG_OPEN_DIR: cmd.append(" --directory"); break; case OSDIALOG_SAVE: cmd.append(" --save --confirm-overwrite"); break; } osdialog_filters *cf = filters; while(NULL != cf) { cmd.append(" --file-filter \""); cmd.append(cf->name); cmd.append(" ("); osdialog_filter_patterns *cp = cf->patterns; while(NULL != cp) { if(cp != cf->patterns) cmd.append(", "); cmd.append(cp->pattern); cp = cp->next; } cmd.append(") | "); cp = cf->patterns; while(NULL != cp) { cmd.append("*."); cmd.append(cp->pattern); cp = cp->next; if(NULL != cp) cmd.append(" "); } cmd.append("\""); cf = cf->next; } cmd.append(" --filename \""); if(NULL != path) { cmd.append(path); cmd.append("/"); } if(NULL != filename) { cmd.append(filename); } cmd.append("\""); cmd.append(" --title \"" DLG_TITLE "\""); std::string buf; if(loc_psystem(cmd.c_str(), buf) > 1) { Dprintf("osdialog_zenity: file selection returned buf=\'%s\'\n", buf.c_str()); size_t bufSize = buf.size() - 1; r = (char*)malloc((bufSize + 1) * sizeof(char)); if(NULL != r) { memcpy((void*)r, (void*)buf.c_str(), bufSize); r[bufSize] = 0; } } return r; } int osdialog_color_picker(osdialog_color *color, int opacity) { int r = 0; (void)opacity; // 1=enable opacity slider std::string cmd = ZENITY_CMD; cmd.append(" --color-selection"); if(NULL != color) { cmd.append(" --color \"rgba("); char buf[10]; sprintf(buf, "%d,%d,%d,%f", color->r, color->g, color->b, color->a / 255.0f); cmd.append(buf); cmd.append(")\""); } cmd.append(" --title \"" DLG_TITLE "\""); #if 0 cmd.append(" --show-palette"); #endif std::string buf; if(loc_psystem(cmd.c_str(), buf) > 1) { Dprintf("osdialog_zenity: color selection returned buf=\'%s\'\n", buf.c_str()); { unsigned int r = 0u, g = 0u, b = 0u; float a = 1.0f; if(NULL != strstr(buf.c_str(), "rgba(")) { // (note) not supported by Zenity 3.22.0 (latest version as of 24May2019) sscanf(buf.c_str(), "rgba(%u,%u,%u,%f)", &r, &g, &b, &a); color->r = (unsigned char)(r); color->g = (unsigned char)(g); color->b = (unsigned char)(b); color->a = (unsigned char)(a * 255u); } else { sscanf(buf.c_str(), "rgb(%u,%u,%u)", &r, &g, &b); color->r = (unsigned char)(r); color->g = (unsigned char)(g); color->b = (unsigned char)(b); } } r = 1; } return r; } } // extern "C"