49 #ifndef TINYFILEDIALOGS_H
50 #define TINYFILEDIALOGS_H
64 extern int tinyfd_winUtf8;
68 char *tinyfd_utf8toMbcs(
char const *aUtf8string);
69 char *tinyfd_utf16toMbcs(
wchar_t const *aUtf16string);
70 wchar_t *tinyfd_mbcsTo16(
char const *aMbcsString);
71 char *tinyfd_mbcsTo8(
char const *aMbcsString);
72 wchar_t *tinyfd_utf8to16(
char const *aUtf8string);
73 char *tinyfd_utf16to8(
wchar_t const *aUtf16string);
125 char const *aMessage,
126 char const *aIconType);
131 char const *aMessage,
132 char const *aDialogType,
133 char const *aIconType,
134 int aDefaultButton) ;
139 char const *aMessage,
140 char const *aDefaultInput) ;
145 char const *aDefaultPathAndFile,
146 int aNumOfFilterPatterns,
147 char const *
const *aFilterPatterns,
148 char const *aSingleFilterDescription) ;
153 char const *aDefaultPathAndFile,
154 int aNumOfFilterPatterns,
155 char const *
const *aFilterPatterns,
156 char const *aSingleFilterDescription,
157 int aAllowMultipleSelects) ;
163 char const *aDefaultPath);
168 char const *aDefaultHexRGB,
169 unsigned char const aDefaultRGB[3],
170 unsigned char aoResultRGB[3]) ;
187 int tinyfd_notifyPopupW(
188 wchar_t const *aTitle,
189 wchar_t const *aMessage,
190 wchar_t const *aIconType);
193 int tinyfd_messageBoxW(
194 wchar_t const *aTitle,
195 wchar_t const *aMessage,
196 wchar_t const *aDialogType,
197 wchar_t const *aIconType,
202 wchar_t *tinyfd_inputBoxW(
203 wchar_t const *aTitle,
204 wchar_t const *aMessage,
205 wchar_t const *aDefaultInput);
208 wchar_t *tinyfd_saveFileDialogW(
209 wchar_t const *aTitle,
210 wchar_t const *aDefaultPathAndFile,
211 int aNumOfFilterPatterns,
212 wchar_t const *
const *aFilterPatterns,
213 wchar_t const *aSingleFilterDescription);
217 wchar_t *tinyfd_openFileDialogW(
218 wchar_t const *aTitle,
219 wchar_t const *aDefaultPathAndFile,
220 int aNumOfFilterPatterns,
221 wchar_t const *
const *aFilterPatterns,
222 wchar_t const *aSingleFilterDescription,
223 int aAllowMultipleSelects) ;
228 wchar_t *tinyfd_selectFolderDialogW(
229 wchar_t const *aTitle,
230 wchar_t const *aDefaultPath);
234 wchar_t *tinyfd_colorChooserW(
235 wchar_t const *aTitle,
236 wchar_t const *aDefaultHexRGB,
237 unsigned char const aDefaultRGB[3],
238 unsigned char aoResultRGB[3]);
363 #ifndef _POSIX_C_SOURCE
364 #define _POSIX_C_SOURCE 2
368 #if !defined(_WIN32) && ( defined(__GNUC__) || defined(__clang__) )
369 #if !defined(_GNU_SOURCE)
378 #include <sys/stat.h>
385 #define _WIN32_WINNT 0x0500
392 #define TINYFD_NOCCSUNICODE
399 #include <sys/utsname.h>
404 #define MAX_PATH_OR_CMD 1024
406 #ifndef MAX_MULTIPLE_FILES
407 #define MAX_MULTIPLE_FILES 1024
409 #define LOW_MULTIPLE_FILES 32
419 int tinyfd_winUtf8 = 1;
457 static char gTitle[] =
"missing software! (we will try basic console input)";
467 \ntiny file dialogs on Windows needs:\
468 \n a graphic display\
469 \nor dialog.exe (curses console mode)\
470 \nor a console for basic input";
479 \ntiny file dialogs on UNIX needs:\
480 \n applescript or kdialog or yad or Xdialog\
481 \nor zenity (or matedialog or shellementary or qarma)\
482 \nor python (2 or 3) + tkinter + python-dbus (optional)\
483 \nor dialog (opens console if needed)\
484 \nor xterm + bash (opens console for basic input)\
485 \nor existing console for basic input";
489 #pragma warning(disable:4996)
490 #pragma warning(disable:4100)
491 #pragma warning(disable:4706)
503 return getcwd(lCurDir,
sizeof(lCurDir));
513 lTmp = strrchr(aSource,
'/');
515 lTmp = strrchr(aSource,
'\\');
518 strncpy(aoDestination, aSource, lTmp - aSource);
519 aoDestination[lTmp - aSource] =
'\0';
521 * aoDestination =
'\0';
524 * aoDestination =
'\0';
526 return aoDestination;
537 lTmp = strrchr(aSource,
'/');
539 lTmp = strrchr(aSource,
'\\');
542 strcpy(aoDestination, lTmp + 1);
544 strcpy(aoDestination, aSource);
547 * aoDestination =
'\0';
549 return aoDestination;
555 if (aioString && strlen(aioString)) {
556 char *lastcar = aioString + strlen(aioString) - 1 ;
557 if (strncmp(lastcar,
SLASH, 1)) {
558 strcat(lastcar,
SLASH) ;
564 static void Hex2RGB(
char const aHexRGB[8],
unsigned char aoResultRGB[3])
566 char lColorChannel[8] ;
569 strcpy(lColorChannel, aHexRGB) ;
570 aoResultRGB[2] = (
unsigned char)strtoul(lColorChannel + 5, NULL, 16);
571 lColorChannel[5] =
'\0';
572 aoResultRGB[1] = (
unsigned char)strtoul(lColorChannel + 3, NULL, 16);
573 lColorChannel[3] =
'\0';
574 aoResultRGB[0] = (
unsigned char)strtoul(lColorChannel + 1, NULL, 16);
584 static void RGB2Hex(
unsigned char const aRGB[3],
char aoResultHexRGB[8])
586 if (aoResultHexRGB) {
588 #if (defined(__cplusplus ) && __cplusplus >= 201103L) || (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__clang__)
589 sprintf(aoResultHexRGB,
"#%02hhx%02hhx%02hhx", aRGB[0], aRGB[1], aRGB[2]);
591 sprintf(aoResultHexRGB,
"#%02hx%02hx%02hx", aRGB[0], aRGB[1], aRGB[2]);
595 aoResultHexRGB[0] = 0;
596 aoResultHexRGB[1] = 0;
597 aoResultHexRGB[2] = 0;
604 char const *aNewSubStr,
char *aoDestination)
606 char const *pOccurence ;
608 char const *lNewSubStr =
"" ;
609 size_t lOldSubLen = strlen(aOldSubStr) ;
612 * aoDestination =
'\0' ;
616 strcpy(aoDestination, aSource) ;
620 lNewSubStr = aNewSubStr ;
623 * aoDestination =
'\0' ;
624 while ((pOccurence = strstr(p, aOldSubStr)) != NULL) {
625 strncat(aoDestination, p, pOccurence - p) ;
626 strcat(aoDestination, lNewSubStr) ;
627 p = pOccurence + lOldSubLen ;
629 strcat(aoDestination, p) ;
635 if (! aFileNameWithoutPath
636 || ! strlen(aFileNameWithoutPath)
637 || strpbrk(aFileNameWithoutPath,
"\\/:*?\"<>|")) {
648 if (! aFilePathAndName || ! strlen(aFilePathAndName)) {
651 lIn = fopen(aFilePathAndName,
"r") ;
668 if (stat(aFilename, &st) == 0) {
669 if ((lIn = fopen(aFilename,
"w"))) {
670 for (i = 0; i < st.st_size; i++) {
683 if (!aString) {
return 0; }
686 while ((p = strchr(p,
'\''))) {
691 while ((p = strchr(p,
'\"'))) {
701 if (!aCharVariableName || !strlen(aCharVariableName)) {
return NULL; }
702 else if (!strcmp(aCharVariableName,
"tinyfd_version")) {
return tinyfd_version; }
703 else if (!strcmp(aCharVariableName,
"tinyfd_needs")) {
return tinyfd_needs; }
704 else if (!strcmp(aCharVariableName,
"tinyfd_response")) {
return tinyfd_response; }
705 else {
return NULL ; }
711 if (!aIntVariableName || !strlen(aIntVariableName)) {
return -1 ; }
712 else if (!strcmp(aIntVariableName,
"tinyfd_verbose")) {
return tinyfd_verbose ; }
713 else if (!strcmp(aIntVariableName,
"tinyfd_silent")) {
return tinyfd_silent ; }
715 else if (!strcmp(aIntVariableName,
"tinyfd_forceConsole")) {
return tinyfd_forceConsole ; }
718 else if (!strcmp(aIntVariableName,
"tinyfd_winUtf8")) {
return tinyfd_winUtf8 ; }
726 if (!aIntVariableName || !strlen(aIntVariableName)) {
return -1 ; }
733 else if (!strcmp(aIntVariableName,
"tinyfd_winUtf8")) { tinyfd_winUtf8 = aValue;
return tinyfd_winUtf8; }
740 static int powershellPresent(
void)
743 static int lPowershellPresent = -1;
746 char const *lString =
"powershell.exe";
748 if (lPowershellPresent < 0) {
749 if (!(lIn = _popen(
"where powershell.exe",
"r"))) {
750 lPowershellPresent = 0;
753 while (fgets(lBuff,
sizeof(lBuff), lIn) != NULL) {
756 if (lBuff[strlen(lBuff) - 1] ==
'\n') {
757 lBuff[strlen(lBuff) - 1] =
'\0';
759 if (strcmp(lBuff + strlen(lBuff) - strlen(lString), lString)) {
760 lPowershellPresent = 0;
762 lPowershellPresent = 1;
765 return lPowershellPresent;
768 static int windowsVersion(
void)
770 #if !defined(__MINGW32__) || defined(__MINGW64_VERSION_MAJOR)
771 typedef LONG NTSTATUS ;
772 typedef NTSTATUS(WINAPI * RtlGetVersionPtr)(PRTL_OSVERSIONINFOW);
774 RtlGetVersionPtr lFxPtr;
775 RTL_OSVERSIONINFOW lRovi = { 0 };
777 hMod = GetModuleHandleW(L
"ntdll.dll");
779 lFxPtr = (RtlGetVersionPtr)GetProcAddress(hMod,
"RtlGetVersion");
781 lRovi.dwOSVersionInfoSize =
sizeof(lRovi);
782 if (!lFxPtr(&lRovi)) {
783 return lRovi.dwMajorVersion;
788 if (powershellPresent()) {
return 6; }
793 static void replaceChr(
char *aString,
char aOldChr,
char aNewChr)
797 if (!aString) {
return; }
798 if (aOldChr == aNewChr) {
return; }
801 while ((p = strchr(p, aOldChr))) {
809 #if !defined(WC_ERR_INVALID_CHARS)
811 #define WC_ERR_INVALID_CHARS 0x00000000
814 static int sizeUtf16From8(
char const *aUtf8string)
816 return MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS,
817 aUtf8string, -1, NULL, 0);
821 static int sizeUtf16FromMbcs(
char const *aMbcsString)
823 return MultiByteToWideChar(CP_ACP, MB_ERR_INVALID_CHARS,
824 aMbcsString, -1, NULL, 0);
828 static int sizeUtf8(
wchar_t const *aUtf16string)
830 return WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS,
831 aUtf16string, -1, NULL, 0, NULL, NULL);
835 static int sizeMbcs(
wchar_t const *aMbcsString)
837 int lRes = WideCharToMultiByte(CP_ACP, 0,
838 aMbcsString, -1, NULL, 0, NULL, NULL);
844 wchar_t *tinyfd_mbcsTo16(
char const *aMbcsString)
846 static wchar_t *lMbcsString = NULL;
850 if (!aMbcsString) { lMbcsString = NULL;
return NULL; }
851 lSize = sizeUtf16FromMbcs(aMbcsString);
853 lMbcsString = (
wchar_t *)malloc(lSize *
sizeof(
wchar_t));
854 lSize = MultiByteToWideChar(CP_ACP, 0, aMbcsString, -1, lMbcsString, lSize);
855 }
else { wcscpy(lMbcsString, L
""); }
860 wchar_t *tinyfd_utf8to16(
char const *aUtf8string)
862 static wchar_t *lUtf16string = NULL;
866 if (!aUtf8string) {lUtf16string = NULL;
return NULL;}
867 lSize = sizeUtf16From8(aUtf8string);
869 lUtf16string = (
wchar_t *)malloc(lSize *
sizeof(
wchar_t));
870 lSize = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS,
871 aUtf8string, -1, lUtf16string, lSize);
876 return tinyfd_mbcsTo16(aUtf8string);
881 char *tinyfd_utf16toMbcs(
wchar_t const *aUtf16string)
883 static char *lMbcsString = NULL;
887 if (!aUtf16string) { lMbcsString = NULL;
return NULL; }
888 lSize = sizeMbcs(aUtf16string);
890 lMbcsString = (
char *)malloc(lSize);
891 lSize = WideCharToMultiByte(CP_ACP, 0, aUtf16string, -1, lMbcsString, lSize, NULL, NULL);
892 }
else { strcpy(lMbcsString,
""); }
897 char *tinyfd_utf8toMbcs(
char const *aUtf8string)
899 wchar_t const *lUtf16string;
900 lUtf16string = tinyfd_utf8to16(aUtf8string);
901 return tinyfd_utf16toMbcs(lUtf16string);
905 char *tinyfd_utf16to8(
wchar_t const *aUtf16string)
907 static char *lUtf8string = NULL;
911 if (!aUtf16string) { lUtf8string = NULL;
return NULL; }
912 lSize = sizeUtf8(aUtf16string);
914 lUtf8string = (
char *)malloc(lSize);
915 lSize = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, aUtf16string, -1, lUtf8string, lSize, NULL, NULL);
916 }
else { strcpy(lUtf8string,
""); }
921 char *tinyfd_mbcsTo8(
char const *aMbcsString)
923 wchar_t const *lUtf16string;
924 lUtf16string = tinyfd_mbcsTo16(aMbcsString);
925 return tinyfd_utf16to8(lUtf16string);
931 if (windowsVersion() > 5) { Beep(440, 300); }
932 else { MessageBeep(-1); }
936 static void wipefileW(
wchar_t const *aFilename)
940 #if defined(__MINGW32_MAJOR_VERSION) && !defined(__MINGW64__) && (__MINGW32_MAJOR_VERSION <= 3)
942 if (_wstat(aFilename, &st) == 0)
945 if (_wstat64(aFilename, &st) == 0)
948 if ((lIn = _wfopen(aFilename, L
"w"))) {
949 for (i = 0; i < st.st_size; i++) {
958 static wchar_t *getPathWithoutFinalSlashW(
959 wchar_t *aoDestination,
960 wchar_t const *aSource)
964 lTmp = wcsrchr(aSource, L
'/');
966 lTmp = wcsrchr(aSource, L
'\\');
969 wcsncpy(aoDestination, aSource, lTmp - aSource);
970 aoDestination[lTmp - aSource] = L
'\0';
972 *aoDestination = L
'\0';
975 *aoDestination = L
'\0';
977 return aoDestination;
981 static wchar_t *getLastNameW(
982 wchar_t *aoDestination,
983 wchar_t const *aSource)
988 lTmp = wcsrchr(aSource, L
'/');
990 lTmp = wcsrchr(aSource, L
'\\');
993 wcscpy(aoDestination, lTmp + 1);
995 wcscpy(aoDestination, aSource);
998 *aoDestination = L
'\0';
1000 return aoDestination;
1004 static void Hex2RGBW(
wchar_t const aHexRGB[8],
unsigned char aoResultRGB[3])
1006 wchar_t lColorChannel[8];
1009 wcscpy(lColorChannel, aHexRGB);
1010 aoResultRGB[2] = (
unsigned char)wcstoul(lColorChannel + 5, NULL, 16);
1011 lColorChannel[5] =
'\0';
1012 aoResultRGB[1] = (
unsigned char)wcstoul(lColorChannel + 3, NULL, 16);
1013 lColorChannel[3] =
'\0';
1014 aoResultRGB[0] = (
unsigned char)wcstoul(lColorChannel + 1, NULL, 16);
1025 static void RGB2HexW(
unsigned char const aRGB[3],
wchar_t aoResultHexRGB[8])
1027 #if (defined(__cplusplus ) && __cplusplus >= 201103L) || (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__clang__)
1028 wchar_t const *
const lPrintFormat = L
"#%02hhx%02hhx%02hhx";
1030 wchar_t const *
const lPrintFormat = L
"#%02hx%02hx%02hx";
1033 if (aoResultHexRGB) {
1036 #if !defined(__BORLANDC__) && !defined(__TINYC__) && !(defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR))
1037 swprintf(aoResultHexRGB, 8, lPrintFormat, aRGB[0], aRGB[1], aRGB[2]);
1039 swprintf(aoResultHexRGB, lPrintFormat, aRGB[0], aRGB[1], aRGB[2]);
1043 aoResultHexRGB[0] = 0;
1044 aoResultHexRGB[1] = 0;
1045 aoResultHexRGB[2] = 0;
1051 static int dirExists(
char const *aDirPath)
1053 #if defined(__MINGW32_MAJOR_VERSION) && !defined(__MINGW64__) && (__MINGW32_MAJOR_VERSION <= 3)
1056 struct __stat64 lInfo;
1065 lDirLen = strlen(aDirPath);
1069 if ((lDirLen == 2) && (aDirPath[1] ==
':')) {
1073 if (tinyfd_winUtf8) {
1074 lTmpWChar = tinyfd_utf8to16(aDirPath);
1075 #if defined(__MINGW32_MAJOR_VERSION) && !defined(__MINGW64__) && (__MINGW32_MAJOR_VERSION <= 3)
1076 lStatRet = _wstat(lTmpWChar, &lInfo);
1078 lStatRet = _wstat64(lTmpWChar, &lInfo);
1080 if (lStatRet != 0) {
1082 }
else if (lInfo.st_mode & S_IFDIR) {
1088 #if defined(__MINGW32_MAJOR_VERSION) && !defined(__MINGW64__) && (__MINGW32_MAJOR_VERSION <= 3)
1089 else if (_stat(aDirPath, &lInfo) != 0)
1091 else if (_stat64(aDirPath, &lInfo) != 0)
1094 else if (lInfo.st_mode & S_IFDIR) {
1102 static int fileExists(
char const *aFilePathAndName)
1104 #if defined(__MINGW32_MAJOR_VERSION) && !defined(__MINGW64__) && (__MINGW32_MAJOR_VERSION <= 3)
1107 struct __stat64 lInfo;
1113 if (!aFilePathAndName || !strlen(aFilePathAndName)) {
1117 if (tinyfd_winUtf8) {
1118 lTmpWChar = tinyfd_utf8to16(aFilePathAndName);
1119 #if defined(__MINGW32_MAJOR_VERSION) && !defined(__MINGW64__) && (__MINGW32_MAJOR_VERSION <= 3)
1120 lStatRet = _wstat(lTmpWChar, &lInfo);
1122 lStatRet = _wstat64(lTmpWChar, &lInfo);
1125 if (lStatRet != 0) {
1127 }
else if (lInfo.st_mode & _S_IFREG) {
1133 lIn = fopen(aFilePathAndName,
"r");
1142 static void replaceWchar(
wchar_t *aString,
1152 if (aOldChr == aNewChr) {
1157 while ((p = wcsrchr(p, aOldChr))) {
1159 #ifdef TINYFD_NOCCSUNICODE
1168 static int quoteDetectedW(
wchar_t const *aString)
1172 if (!aString) {
return 0; }
1175 while ((p = wcsrchr(p, L
'\''))) {
1180 while ((p = wcsrchr(p, L
'\"'))) {
1191 char const *aSourcePathsAndNames)
1193 char *lDestination = aDestination;
1198 if (!aSourcePathsAndNames) {
1201 lLen = strlen(aSourcePathsAndNames);
1206 p = aSourcePathsAndNames;
1207 while ((p2 = strchr(p,
'|')) != NULL) {
1209 memmove(lDestination, p, lLen);
1210 lDestination[lLen] =
'\0';
1212 lDestination += lLen;
1213 *lDestination =
'|';
1220 memmove(lDestination, p, lLen);
1221 lDestination[lLen] =
'\0';
1223 *(lDestination - 1) =
'\0';
1225 return aDestination;
1230 static int __stdcall EnumThreadWndProc(HWND hwnd, LPARAM lParam)
1232 wchar_t lTitleName[MAX_PATH];
1233 GetWindowTextW(hwnd, lTitleName, MAX_PATH);
1235 if (wcscmp(L
"tinyfiledialogsTopWindow", lTitleName) == 0) {
1236 SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
1243 static void hiddenConsoleW(
wchar_t const *aString,
wchar_t const *aDialogTitle,
int aInFront)
1245 STARTUPINFOW StartupInfo;
1246 PROCESS_INFORMATION ProcessInfo;
1248 if (!aString || !wcslen(aString)) {
return; }
1250 memset(&StartupInfo, 0,
sizeof(StartupInfo));
1251 StartupInfo.cb =
sizeof(STARTUPINFOW);
1252 StartupInfo.dwFlags = STARTF_USESHOWWINDOW;
1253 StartupInfo.wShowWindow = SW_HIDE;
1255 if (!CreateProcessW(NULL, (LPWSTR)aString, NULL, NULL, FALSE,
1256 CREATE_NEW_CONSOLE, NULL, NULL,
1257 &StartupInfo, &ProcessInfo)) {
1261 WaitForInputIdle(ProcessInfo.hProcess, INFINITE);
1263 while (EnumWindows(EnumThreadWndProc, (LPARAM)NULL)) {}
1264 SetWindowTextW(GetForegroundWindow(), aDialogTitle);
1266 WaitForSingleObject(ProcessInfo.hProcess, INFINITE);
1267 CloseHandle(ProcessInfo.hThread);
1268 CloseHandle(ProcessInfo.hProcess);
1272 int tinyfd_messageBoxW(
1273 wchar_t const *aTitle,
1274 wchar_t const *aMessage,
1275 wchar_t const *aDialogType,
1276 wchar_t const *aIconType,
1279 int lBoxReturnValue;
1282 if (aTitle && !wcscmp(aTitle, L
"tinyfd_query")) { strcpy(
tinyfd_response,
"windows_wchar");
return 1; }
1284 if (quoteDetectedW(aTitle)) {
return tinyfd_messageBoxW(L
"INVALID TITLE WITH QUOTES", aMessage, aDialogType, aIconType, aDefaultButton); }
1285 if (quoteDetectedW(aMessage)) {
return tinyfd_messageBoxW(aTitle, L
"INVALID MESSAGE WITH QUOTES", aDialogType, aIconType, aDefaultButton); }
1287 if (aIconType && !wcscmp(L
"warning", aIconType)) {
1288 aCode = MB_ICONWARNING;
1289 }
else if (aIconType && !wcscmp(L
"error", aIconType)) {
1290 aCode = MB_ICONERROR;
1291 }
else if (aIconType && !wcscmp(L
"question", aIconType)) {
1292 aCode = MB_ICONQUESTION;
1294 aCode = MB_ICONINFORMATION;
1297 if (aDialogType && !wcscmp(L
"okcancel", aDialogType)) {
1298 aCode += MB_OKCANCEL;
1299 if (!aDefaultButton) {
1300 aCode += MB_DEFBUTTON2;
1302 }
else if (aDialogType && !wcscmp(L
"yesno", aDialogType)) {
1304 if (!aDefaultButton) {
1305 aCode += MB_DEFBUTTON2;
1311 aCode += MB_TOPMOST;
1313 lBoxReturnValue = MessageBoxW(GetForegroundWindow(), aMessage, aTitle, aCode);
1315 && wcscmp(L
"okcancel", aDialogType)
1316 && wcscmp(L
"yesno", aDialogType)))
1317 || (lBoxReturnValue == IDOK)
1318 || (lBoxReturnValue == IDYES)) {
1327 int tinyfd_notifyPopupW(
1328 wchar_t const *aTitle,
1329 wchar_t const *aMessage,
1330 wchar_t const *aIconType)
1332 wchar_t *lDialogString;
1335 size_t lDialogStringLen;
1337 if (aTitle && !wcscmp(aTitle, L
"tinyfd_query")) { strcpy(
tinyfd_response,
"windows_wchar");
return 1; }
1339 if (quoteDetectedW(aTitle)) {
return tinyfd_notifyPopupW(L
"INVALID TITLE WITH QUOTES", aMessage, aIconType); }
1340 if (quoteDetectedW(aMessage)) {
return tinyfd_notifyPopupW(aTitle, L
"INVALID MESSAGE WITH QUOTES", aIconType); }
1342 lTitleLen = aTitle ? wcslen(aTitle) : 0;
1343 lMessageLen = aMessage ? wcslen(aMessage) : 0;
1345 lDialogString = (
wchar_t *)malloc(2 * lDialogStringLen);
1346 if (!lDialogString) {
return 0; }
1348 wcscpy(lDialogString, L
"powershell.exe -command \"\
1349 function Show-BalloonTip {\
1352 [string]$Title = ' ', \
1353 [string]$Message = ' ', \
1354 [ValidateSet('info', 'warning', 'error')] \
1355 [string]$IconType = 'info');\
1356 [system.Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms') | Out-Null ; \
1357 $balloon = New-Object System.Windows.Forms.NotifyIcon ; \
1358 $path = Get-Process -id $pid | Select-Object -ExpandProperty Path ; \
1359 $icon = [System.Drawing.Icon]::ExtractAssociatedIcon($path) ;");
1361 wcscat(lDialogString, L
"\
1362 $balloon.Icon = $icon ; \
1363 $balloon.BalloonTipIcon = $IconType ; \
1364 $balloon.BalloonTipText = $Message ; \
1365 $balloon.BalloonTipTitle = $Title ; \
1366 $balloon.Text = 'tinyfiledialogs' ; \
1367 $balloon.Visible = $true ; \
1368 $balloon.ShowBalloonTip(5000)};\
1371 if (aTitle && wcslen(aTitle)) {
1372 wcscat(lDialogString, L
" -Title '");
1373 wcscat(lDialogString, aTitle);
1374 wcscat(lDialogString, L
"'");
1376 if (aMessage && wcslen(aMessage)) {
1377 wcscat(lDialogString, L
" -Message '");
1378 wcscat(lDialogString, aMessage);
1379 wcscat(lDialogString, L
"'");
1381 if (aMessage && wcslen(aIconType)) {
1382 wcscat(lDialogString, L
" -IconType '");
1383 wcscat(lDialogString, aIconType);
1384 wcscat(lDialogString, L
"'");
1386 wcscat(lDialogString, L
"\"");
1390 hiddenConsoleW(lDialogString, aTitle, 0);
1391 free(lDialogString);
1396 wchar_t *tinyfd_inputBoxW(
1397 wchar_t const *aTitle,
1398 wchar_t const *aMessage,
1399 wchar_t const *aDefaultInput)
1402 wchar_t *lDialogString;
1408 size_t lDialogStringLen;
1410 if (aTitle && !wcscmp(aTitle, L
"tinyfd_query")) { strcpy(
tinyfd_response,
"windows_wchar");
return (
wchar_t *)1; }
1412 if (quoteDetectedW(aTitle)) {
return tinyfd_inputBoxW(L
"INVALID TITLE WITH QUOTES", aMessage, aDefaultInput); }
1413 if (quoteDetectedW(aMessage)) {
return tinyfd_inputBoxW(aTitle, L
"INVALID MESSAGE WITH QUOTES", aDefaultInput); }
1414 if (quoteDetectedW(aDefaultInput)) {
return tinyfd_inputBoxW(aTitle, aMessage, L
"INVALID DEFAULT_INPUT WITH QUOTES"); }
1416 lTitleLen = aTitle ? wcslen(aTitle) : 0 ;
1417 lMessageLen = aMessage ? wcslen(aMessage) : 0 ;
1419 lDialogString = (
wchar_t *)malloc(2 * lDialogStringLen);
1421 if (aDefaultInput) {
1422 swprintf(lDialogString,
1423 #
if !defined(__BORLANDC__) && !defined(__TINYC__) && !(defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR))
1426 L
"%ls\\tinyfd.vbs", _wgetenv(L
"TEMP"));
1428 swprintf(lDialogString,
1429 #
if !defined(__BORLANDC__) && !defined(__TINYC__) && !(defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR))
1432 L
"%ls\\tinyfd.hta", _wgetenv(L
"TEMP"));
1434 lIn = _wfopen(lDialogString, L
"w");
1436 free(lDialogString);
1440 if (aDefaultInput) {
1441 wcscpy(lDialogString, L
"Dim result:result=InputBox(\"");
1442 if (aMessage && wcslen(aMessage)) {
1443 wcscpy(lBuff, aMessage);
1444 replaceWchar(lBuff, L
'\n', L
' ');
1445 wcscat(lDialogString, lBuff);
1447 wcscat(lDialogString, L
"\",\"tinyfiledialogsTopWindow\",\"");
1448 if (aDefaultInput && wcslen(aDefaultInput)) {
1449 wcscpy(lBuff, aDefaultInput);
1450 replaceWchar(lBuff, L
'\n', L
' ');
1451 wcscat(lDialogString, lBuff);
1453 wcscat(lDialogString, L
"\"):If IsEmpty(result) then:WScript.Echo 0");
1454 wcscat(lDialogString, L
":Else: WScript.Echo \"1\" & result : End If");
1456 wcscpy(lDialogString, L
"\n\
1461 wcscat(lDialogString, L
"tinyfiledialogsTopWindow");
1462 wcscat(lDialogString, L
"</title>\n\
1465 APPLICATIONNAME = 'tinyfd_inputBox'\n\
1466 MINIMIZEBUTTON = 'no'\n\
1467 MAXIMIZEBUTTON = 'no'\n\
1468 BORDER = 'dialog'\n\
1470 SINGLEINSTANCE = 'yes'\n\
1471 WINDOWSTATE = 'hidden'>\n\
1473 <script language = 'VBScript'>\n\
1475 intWidth = Screen.Width/4\n\
1476 intHeight = Screen.Height/6\n\
1477 ResizeTo intWidth, intHeight\n\
1478 MoveTo((Screen.Width/2)-(intWidth/2)),((Screen.Height/2)-(intHeight/2))\n\
1481 Sub Window_onLoad\n\
1486 wcscat(lDialogString, L
"\
1487 Sub Window_onUnload\n\
1488 Set objFSO = CreateObject(\"Scripting.FileSystemObject\")\n\
1489 Set oShell = CreateObject(\"WScript.Shell\")\n\
1490 strTempFolder = oShell.ExpandEnvironmentStrings(\"%TEMP%\")\n\
1491 Set objFile = objFSO.CreateTextFile(strTempFolder & \"\\tinyfd.txt\",True,True)\n\
1492 If result = 1 Then\n\
1493 objFile.Write 1 & txt_input.Value\n\
1500 Sub Run_ProgramOK\n\
1505 Sub Run_ProgramCancel\n\
1510 wcscat(lDialogString, L
"Sub Default_Buttons\n\
1511 If Window.Event.KeyCode = 13 Then\n\
1513 ElseIf Window.Event.KeyCode = 27 Then\n\
1520 <body style = 'background-color:#EEEEEE' onkeypress = 'vbs:Default_Buttons' align = 'top'>\n\
1521 <table width = '100%' height = '80%' align = 'center' border = '0'>\n\
1522 <tr border = '0'>\n\
1523 <td align = 'left' valign = 'middle' style='Font-Family:Arial'>\n");
1525 wcscat(lDialogString, aMessage ? aMessage : L
"");
1527 wcscat(lDialogString, L
"\n\
1529 <td align = 'right' valign = 'middle' style = 'margin-top: 0em'>\n\
1530 <table align = 'right' style = 'margin-right: 0em;'>\n\
1531 <tr align = 'right' style = 'margin-top: 5em;'>\n\
1532 <input type = 'button' value = 'OK' name = 'btn_OK' onClick = 'vbs:Run_ProgramOK' style = 'width: 5em; margin-top: 2em;'><br>\n\
1533 <input type = 'button' value = 'Cancel' name = 'btn_Cancel' onClick = 'vbs:Run_ProgramCancel' style = 'width: 5em;'><br><br>\n\
1540 wcscat(lDialogString, L
"<table width = '100%' height = '100%' align = 'center' border = '0'>\n\
1542 <td align = 'left' valign = 'top'>\n\
1543 <input type = 'password' id = 'txt_input'\n\
1544 name = 'txt_input' value = '' style = 'float:left;width:100%' ><BR>\n\
1552 fputws(lDialogString, lIn);
1555 if (aDefaultInput) {
1556 swprintf(lDialogString,
1557 #
if !defined(__BORLANDC__) && !defined(__TINYC__) && !(defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR))
1560 L
"%ls\\tinyfd.txt", _wgetenv(L
"TEMP"));
1562 #ifdef TINYFD_NOCCSUNICODE
1563 lFile = _wfopen(lDialogString, L
"w");
1567 lFile = _wfopen(lDialogString, L
"wt, ccs=UNICODE");
1571 wcscpy(lDialogString, L
"cmd.exe /c cscript.exe //U //Nologo ");
1572 wcscat(lDialogString, L
"\"%TEMP%\\tinyfd.vbs\" ");
1573 wcscat(lDialogString, L
">> \"%TEMP%\\tinyfd.txt\"");
1575 wcscpy(lDialogString,
1576 L
"cmd.exe /c mshta.exe \"%TEMP%\\tinyfd.hta\"");
1581 hiddenConsoleW(lDialogString, aTitle, 1);
1583 swprintf(lDialogString,
1584 #
if !defined(__BORLANDC__) && !defined(__TINYC__) && !(defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR))
1587 L
"%ls\\tinyfd.txt", _wgetenv(L
"TEMP"));
1589 #ifdef TINYFD_NOCCSUNICODE
1590 if (!(lIn = _wfopen(lDialogString, L
"r")))
1592 if (!(lIn = _wfopen(lDialogString, L
"rt, ccs=UNICODE")))
1595 _wremove(lDialogString);
1596 free(lDialogString);
1602 #ifdef TINYFD_NOCCSUNICODE
1608 wipefileW(lDialogString);
1609 _wremove(lDialogString);
1611 if (aDefaultInput) {
1612 swprintf(lDialogString,
1613 #
if !defined(__BORLANDC__) && !defined(__TINYC__) && !(defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR))
1616 L
"%ls\\tinyfd.vbs", _wgetenv(L
"TEMP"));
1618 swprintf(lDialogString,
1619 #
if !defined(__BORLANDC__) && !defined(__TINYC__) && !(defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR))
1622 L
"%ls\\tinyfd.hta", _wgetenv(L
"TEMP"));
1624 _wremove(lDialogString);
1625 free(lDialogString);
1627 #ifdef TINYFD_NOCCSUNICODE
1628 lResult = !wcsncmp(lBuff + 1, L
"1", 1);
1630 lResult = !wcsncmp(lBuff, L
"1", 1);
1640 #ifdef TINYFD_NOCCSUNICODE
1641 if (aDefaultInput) {
1642 lDialogStringLen = wcslen(lBuff) ;
1643 lBuff[lDialogStringLen - 1] = L
'\0';
1644 lBuff[lDialogStringLen - 2] = L
'\0';
1648 if (aDefaultInput) { lBuff[wcslen(lBuff) - 1] = L
'\0'; }
1654 wchar_t *tinyfd_saveFileDialogW(
1655 wchar_t const *aTitle,
1656 wchar_t const *aDefaultPathAndFile,
1657 int aNumOfFilterPatterns,
1658 wchar_t const *
const *aFilterPatterns,
1659 wchar_t const *aSingleFilterDescription)
1667 wchar_t const *ldefExt = NULL;
1670 OPENFILENAMEW ofn = {0};
1672 if (aTitle && !wcscmp(aTitle, L
"tinyfd_query")) { strcpy(
tinyfd_response,
"windows_wchar");
return (
wchar_t *)1; }
1674 if (quoteDetectedW(aTitle)) {
return tinyfd_saveFileDialogW(L
"INVALID TITLE WITH QUOTES", aDefaultPathAndFile, aNumOfFilterPatterns, aFilterPatterns, aSingleFilterDescription); }
1675 if (quoteDetectedW(aDefaultPathAndFile)) {
return tinyfd_saveFileDialogW(aTitle, L
"INVALID DEFAULT_PATH WITH QUOTES", aNumOfFilterPatterns, aFilterPatterns, aSingleFilterDescription); }
1676 if (quoteDetectedW(aSingleFilterDescription)) {
return tinyfd_saveFileDialogW(aTitle, aDefaultPathAndFile, aNumOfFilterPatterns, aFilterPatterns, L
"INVALID FILTER_DESCRIPTION WITH QUOTES"); }
1677 for (i = 0; i < aNumOfFilterPatterns; i++) {
1678 if (quoteDetectedW(aFilterPatterns[i])) {
return tinyfd_saveFileDialogW(L
"INVALID FILTER_PATTERN WITH QUOTES", aDefaultPathAndFile, 0, NULL, NULL); }
1681 lHResult = CoInitializeEx(NULL, 0);
1683 getPathWithoutFinalSlashW(lDirname, aDefaultPathAndFile);
1684 getLastNameW(lBuff, aDefaultPathAndFile);
1686 if (aNumOfFilterPatterns > 0) {
1687 ldefExt = aFilterPatterns[0];
1689 if (aSingleFilterDescription && wcslen(aSingleFilterDescription)) {
1690 wcscpy(lFilterPatterns, aSingleFilterDescription);
1691 wcscat(lFilterPatterns, L
"\n");
1693 wcscat(lFilterPatterns, aFilterPatterns[0]);
1694 for (i = 1; i < aNumOfFilterPatterns; i++) {
1695 wcscat(lFilterPatterns, L
";");
1696 wcscat(lFilterPatterns, aFilterPatterns[i]);
1698 wcscat(lFilterPatterns, L
"\n");
1699 if (!(aSingleFilterDescription && wcslen(aSingleFilterDescription))) {
1700 wcscpy(lDialogString, lFilterPatterns);
1701 wcscat(lFilterPatterns, lDialogString);
1703 wcscat(lFilterPatterns, L
"All Files\n*.*\n");
1704 p = lFilterPatterns;
1705 while ((p = wcschr(p, L
'\n')) != NULL) {
1711 ofn.lStructSize =
sizeof(OPENFILENAMEW);
1712 ofn.hwndOwner = GetForegroundWindow();
1714 ofn.lpstrFilter = wcslen(lFilterPatterns) ? lFilterPatterns : NULL;
1715 ofn.lpstrCustomFilter = NULL;
1716 ofn.nMaxCustFilter = 0;
1717 ofn.nFilterIndex = 1;
1718 ofn.lpstrFile = lBuff;
1721 ofn.lpstrFileTitle = NULL;
1723 ofn.lpstrInitialDir = wcslen(lDirname) ? lDirname : NULL;
1724 ofn.lpstrTitle = aTitle && wcslen(aTitle) ? aTitle : NULL;
1725 ofn.Flags = OFN_OVERWRITEPROMPT | OFN_NOCHANGEDIR | OFN_PATHMUSTEXIST ;
1726 ofn.nFileOffset = 0;
1727 ofn.nFileExtension = 0;
1728 ofn.lpstrDefExt = ldefExt;
1730 ofn.lpfnHook = NULL;
1731 ofn.lpTemplateName = NULL;
1733 if (GetSaveFileNameW(&ofn) == 0) {
1739 if (lHResult == S_OK || lHResult == S_FALSE) {
1746 wchar_t *tinyfd_openFileDialogW(
1747 wchar_t const *aTitle,
1748 wchar_t const *aDefaultPathAndFile,
1749 int aNumOfFilterPatterns,
1750 wchar_t const *
const *aFilterPatterns,
1751 wchar_t const *aSingleFilterDescription,
1752 int aAllowMultipleSelects)
1764 OPENFILENAMEW ofn = { 0 };
1765 static wchar_t *lBuff = NULL;
1769 if (aAllowMultipleSelects < 0) {
return (
wchar_t *)0; }
1771 if (aTitle && !wcscmp(aTitle, L
"tinyfd_query")) { strcpy(
tinyfd_response,
"windows_wchar");
return (
wchar_t *)1; }
1773 if (quoteDetectedW(aTitle)) {
return tinyfd_openFileDialogW(L
"INVALID TITLE WITH QUOTES", aDefaultPathAndFile, aNumOfFilterPatterns, aFilterPatterns, aSingleFilterDescription, aAllowMultipleSelects); }
1774 if (quoteDetectedW(aDefaultPathAndFile)) {
return tinyfd_openFileDialogW(aTitle, L
"INVALID DEFAULT_PATH WITH QUOTES", aNumOfFilterPatterns, aFilterPatterns, aSingleFilterDescription, aAllowMultipleSelects); }
1775 if (quoteDetectedW(aSingleFilterDescription)) {
return tinyfd_openFileDialogW(aTitle, aDefaultPathAndFile, aNumOfFilterPatterns, aFilterPatterns, L
"INVALID FILTER_DESCRIPTION WITH QUOTES", aAllowMultipleSelects); }
1776 for (i = 0; i < aNumOfFilterPatterns; i++) {
1777 if (quoteDetectedW(aFilterPatterns[i])) {
return tinyfd_openFileDialogW(L
"INVALID FILTER_PATTERN WITH QUOTES", aDefaultPathAndFile, 0, NULL, NULL, aAllowMultipleSelects); }
1780 if (aAllowMultipleSelects) {
1782 lBuff = (
wchar_t *)(malloc(lFullBuffLen *
sizeof(
wchar_t)));
1785 lBuff = (
wchar_t *)(malloc(lFullBuffLen *
sizeof(
wchar_t)));
1789 lBuff = (
wchar_t *)(malloc(lFullBuffLen *
sizeof(
wchar_t)));
1791 if (!lBuff) {
return NULL; }
1793 lHResult = CoInitializeEx(NULL, 0);
1795 getPathWithoutFinalSlashW(lDirname, aDefaultPathAndFile);
1796 getLastNameW(lBuff, aDefaultPathAndFile);
1798 if (aNumOfFilterPatterns > 0) {
1799 if (aSingleFilterDescription && wcslen(aSingleFilterDescription)) {
1800 wcscpy(lFilterPatterns, aSingleFilterDescription);
1801 wcscat(lFilterPatterns, L
"\n");
1803 wcscat(lFilterPatterns, aFilterPatterns[0]);
1804 for (i = 1; i < aNumOfFilterPatterns; i++) {
1805 wcscat(lFilterPatterns, L
";");
1806 wcscat(lFilterPatterns, aFilterPatterns[i]);
1808 wcscat(lFilterPatterns, L
"\n");
1809 if (!(aSingleFilterDescription && wcslen(aSingleFilterDescription))) {
1810 wcscpy(lDialogString, lFilterPatterns);
1811 wcscat(lFilterPatterns, lDialogString);
1813 wcscat(lFilterPatterns, L
"All Files\n*.*\n");
1814 p = lFilterPatterns;
1815 while ((p = wcschr(p, L
'\n')) != NULL) {
1821 ofn.lStructSize =
sizeof(OPENFILENAME);
1822 ofn.hwndOwner = GetForegroundWindow();
1824 ofn.lpstrFilter = wcslen(lFilterPatterns) ? lFilterPatterns : NULL;
1825 ofn.lpstrCustomFilter = NULL;
1826 ofn.nMaxCustFilter = 0;
1827 ofn.nFilterIndex = 1;
1828 ofn.lpstrFile = lBuff;
1829 ofn.nMaxFile = lFullBuffLen;
1830 ofn.lpstrFileTitle = NULL;
1832 ofn.lpstrInitialDir = wcslen(lDirname) ? lDirname : NULL;
1833 ofn.lpstrTitle = aTitle && wcslen(aTitle) ? aTitle : NULL;
1834 ofn.Flags = OFN_EXPLORER | OFN_NOCHANGEDIR | OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
1835 ofn.nFileOffset = 0;
1836 ofn.nFileExtension = 0;
1837 ofn.lpstrDefExt = NULL;
1839 ofn.lpfnHook = NULL;
1840 ofn.lpTemplateName = NULL;
1842 if (aAllowMultipleSelects) {
1843 ofn.Flags |= OFN_ALLOWMULTISELECT;
1846 if (GetOpenFileNameW(&ofn) == 0) {
1850 lBuffLen = wcslen(lBuff);
1851 lPointers[0] = lBuff + lBuffLen + 1;
1852 if (aAllowMultipleSelects && (lPointers[0][0] != L
'\0')) {
1855 lLengths[i] = wcslen(lPointers[i]);
1856 lPointers[i + 1] = lPointers[i] + lLengths[i] + 1;
1864 p = lBuff + lFullBuffLen - 1;
1866 for (j = i; j >= 0; j--) {
1868 memmove(p, lPointers[j], lLengths[j] *
sizeof(
wchar_t));
1872 memmove(p, lBuff, lBuffLen *
sizeof(
wchar_t));
1878 lBuffLen = wcslen(lBuff);
1881 if (lBuff) { lBuff = (
wchar_t *)(realloc(lBuff, (lBuffLen + 1) *
sizeof(
wchar_t))); }
1884 if (lHResult == S_OK || lHResult == S_FALSE) {
1891 BOOL CALLBACK BrowseCallbackProcW_enum(HWND hWndChild, LPARAM lParam)
1894 GetClassNameW(hWndChild, buf,
sizeof(buf));
1895 if (wcscmp(buf, L
"SysTreeView32") == 0) {
1896 HTREEITEM hNode = TreeView_GetSelection(hWndChild);
1897 TreeView_EnsureVisible(hWndChild, hNode);
1904 static int __stdcall BrowseCallbackProcW(HWND hwnd, UINT uMsg, LPARAM lp, LPARAM pData)
1907 case BFFM_INITIALIZED:
1908 SendMessage(hwnd, BFFM_SETSELECTIONW, TRUE, (LPARAM)pData);
1910 case BFFM_SELCHANGED:
1911 EnumChildWindows(hwnd, BrowseCallbackProcW_enum, 0);
1916 wchar_t *tinyfd_selectFolderDialogW(
1917 wchar_t const *aTitle,
1918 wchar_t const *aDefaultPath)
1924 LPITEMIDLIST lpItem;
1927 if (aTitle && !wcscmp(aTitle, L
"tinyfd_query")) { strcpy(
tinyfd_response,
"windows_wchar");
return (
wchar_t *)1; }
1929 if (quoteDetectedW(aTitle)) {
return tinyfd_selectFolderDialogW(L
"INVALID TITLE WITH QUOTES", aDefaultPath); }
1930 if (quoteDetectedW(aDefaultPath)) {
return tinyfd_selectFolderDialogW(aTitle, L
"INVALID DEFAULT_PATH WITH QUOTES"); }
1932 lHResult = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
1934 bInfo.hwndOwner = GetForegroundWindow();
1935 bInfo.pidlRoot = NULL;
1936 bInfo.pszDisplayName = lBuff;
1937 bInfo.lpszTitle = aTitle && wcslen(aTitle) ? aTitle : NULL;
1938 if (lHResult == S_OK || lHResult == S_FALSE) {
1939 bInfo.ulFlags = BIF_USENEWUI;
1941 bInfo.lpfn = BrowseCallbackProcW;
1942 bInfo.lParam = (LPARAM)aDefaultPath;
1945 lpItem = SHBrowseForFolderW(&bInfo);
1949 SHGetPathFromIDListW(lpItem, lBuff);
1953 if (lHResult == S_OK || lHResult == S_FALSE) {
1960 wchar_t *tinyfd_colorChooserW(
1961 wchar_t const *aTitle,
1962 wchar_t const *aDefaultHexRGB,
1963 unsigned char const aDefaultRGB[3],
1964 unsigned char aoResultRGB[3])
1966 static wchar_t lResultHexRGB[8];
1968 COLORREF crCustColors[16];
1969 unsigned char lDefaultRGB[3];
1974 if (aTitle && !wcscmp(aTitle, L
"tinyfd_query")) { strcpy(
tinyfd_response,
"windows_wchar");
return (
wchar_t *)1; }
1976 if (quoteDetectedW(aTitle)) {
return tinyfd_colorChooserW(L
"INVALID TITLE WITH QUOTES", aDefaultHexRGB, aDefaultRGB, aoResultRGB); }
1977 if (quoteDetectedW(aDefaultHexRGB)) {
return tinyfd_colorChooserW(aTitle, L
"INVALID DEFAULT_HEX_RGB WITH QUOTES", aDefaultRGB, aoResultRGB); }
1979 lHResult = CoInitializeEx(NULL, 0);
1981 if (aDefaultHexRGB) {
1982 Hex2RGBW(aDefaultHexRGB, lDefaultRGB);
1984 lDefaultRGB[0] = aDefaultRGB[0];
1985 lDefaultRGB[1] = aDefaultRGB[1];
1986 lDefaultRGB[2] = aDefaultRGB[2];
1990 cc.lStructSize =
sizeof(CHOOSECOLOR);
1991 cc.hwndOwner = GetForegroundWindow();
1992 cc.hInstance = NULL;
1993 cc.rgbResult = RGB(lDefaultRGB[0], lDefaultRGB[1], lDefaultRGB[2]);
1994 cc.lpCustColors = crCustColors;
1995 cc.Flags = CC_RGBINIT | CC_FULLOPEN | CC_ANYCOLOR ;
1998 cc.lpTemplateName = NULL;
2000 lRet = ChooseColorW(&cc);
2006 aoResultRGB[0] = GetRValue(cc.rgbResult);
2007 aoResultRGB[1] = GetGValue(cc.rgbResult);
2008 aoResultRGB[2] = GetBValue(cc.rgbResult);
2010 RGB2HexW(aoResultRGB, lResultHexRGB);
2012 if (lHResult == S_OK || lHResult == S_FALSE) {
2016 return lResultHexRGB;
2020 static int messageBoxWinGui(
2022 char const *aMessage,
2023 char const *aDialogType,
2024 char const *aIconType,
2028 wchar_t lTitle[128] = L
"";
2029 wchar_t *lMessage = NULL;
2030 wchar_t lDialogType[16] = L
"";
2031 wchar_t lIconType[16] = L
"";
2035 if (tinyfd_winUtf8) { lTmpWChar = tinyfd_utf8to16(aTitle); }
2036 else { lTmpWChar = tinyfd_mbcsTo16(aTitle); }
2037 wcscpy(lTitle, lTmpWChar);
2040 if (tinyfd_winUtf8) { lTmpWChar = tinyfd_utf8to16(aMessage); }
2041 else { lTmpWChar = tinyfd_mbcsTo16(aMessage); }
2042 lMessage = (
wchar_t *) malloc((wcslen(lTmpWChar) + 1) *
sizeof(wchar_t));
2043 if (lMessage) { wcscpy(lMessage, lTmpWChar); }
2046 if (tinyfd_winUtf8) { lTmpWChar = tinyfd_utf8to16(aDialogType); }
2047 else { lTmpWChar = tinyfd_mbcsTo16(aDialogType); }
2048 wcscpy(lDialogType, lTmpWChar);
2051 if (tinyfd_winUtf8) { lTmpWChar = tinyfd_utf8to16(aIconType); }
2052 else { lTmpWChar = tinyfd_mbcsTo16(aIconType); }
2053 wcscpy(lIconType, lTmpWChar);
2056 lIntRetVal = tinyfd_messageBoxW(lTitle, lMessage, lDialogType, lIconType, aDefaultButton);
2064 static int notifyWinGui(
2066 char const *aMessage,
2067 char const *aIconType)
2069 wchar_t lTitle[128] = L
"";
2070 wchar_t *lMessage = NULL;
2071 wchar_t lIconType[16] = L
"";
2075 if (tinyfd_winUtf8) { lTmpWChar = tinyfd_utf8to16(aTitle); }
2076 else { lTmpWChar = tinyfd_mbcsTo16(aTitle); }
2077 wcscpy(lTitle, lTmpWChar);
2080 if (tinyfd_winUtf8) { lTmpWChar = tinyfd_utf8to16(aMessage); }
2081 else { lTmpWChar = tinyfd_mbcsTo16(aMessage); }
2082 lMessage = (
wchar_t *) malloc((wcslen(lTmpWChar) + 1) *
sizeof(wchar_t));
2083 if (lMessage) { wcscpy(lMessage, lTmpWChar); }
2086 if (tinyfd_winUtf8) { lTmpWChar = tinyfd_utf8to16(aIconType); }
2087 else { lTmpWChar = tinyfd_mbcsTo16(aIconType); }
2088 wcscpy(lIconType, lTmpWChar);
2091 tinyfd_notifyPopupW(lTitle, lMessage, lIconType);
2099 static int inputBoxWinGui(
2102 char const *aMessage,
2103 char const *aDefaultInput)
2105 wchar_t lTitle[128] = L
"";
2106 wchar_t *lMessage = NULL;
2112 if (tinyfd_winUtf8) { lTmpWChar = tinyfd_utf8to16(aTitle); }
2113 else { lTmpWChar = tinyfd_mbcsTo16(aTitle); }
2114 wcscpy(lTitle, lTmpWChar);
2117 if (tinyfd_winUtf8) { lTmpWChar = tinyfd_utf8to16(aMessage); }
2118 else { lTmpWChar = tinyfd_mbcsTo16(aMessage); }
2119 lMessage = (
wchar_t *) malloc((wcslen(lTmpWChar) + 1) *
sizeof(wchar_t));
2120 if (lMessage) { wcscpy(lMessage, lTmpWChar); }
2122 if (aDefaultInput) {
2123 if (tinyfd_winUtf8) { lTmpWChar = tinyfd_utf8to16(aDefaultInput); }
2124 else { lTmpWChar = tinyfd_mbcsTo16(aDefaultInput); }
2125 wcscpy(lDefaultInput, lTmpWChar);
2126 lTmpWChar = tinyfd_inputBoxW(lTitle, lMessage, lDefaultInput);
2127 }
else { lTmpWChar = tinyfd_inputBoxW(lTitle, lMessage, NULL); }
2136 if (tinyfd_winUtf8) { lTmpChar = tinyfd_utf16to8(lTmpWChar); }
2137 else { lTmpChar = tinyfd_utf16toMbcs(lTmpWChar); }
2139 strcpy(aoBuff, lTmpChar);
2145 static char *saveFileDialogWinGui(
2148 char const *aDefaultPathAndFile,
2149 int aNumOfFilterPatterns,
2150 char const *
const *aFilterPatterns,
2151 char const *aSingleFilterDescription)
2153 wchar_t lTitle[128] = L
"";
2155 wchar_t lSingleFilterDescription[128] = L
"";
2156 wchar_t * * lFilterPatterns;
2161 lFilterPatterns = (
wchar_t **)malloc(aNumOfFilterPatterns *
sizeof(
wchar_t *));
2162 for (i = 0; i < aNumOfFilterPatterns; i++) {
2163 if (tinyfd_winUtf8) { lTmpWChar = tinyfd_utf8to16(aFilterPatterns[i]); }
2164 else { lTmpWChar = tinyfd_mbcsTo16(aFilterPatterns[i]); }
2165 lFilterPatterns[i] = (
wchar_t *)malloc((wcslen(lTmpWChar) + 1) *
sizeof(
wchar_t *));
2166 if (lFilterPatterns[i]) { wcscpy(lFilterPatterns[i], lTmpWChar); }
2170 if (tinyfd_winUtf8) { lTmpWChar = tinyfd_utf8to16(aTitle); }
2171 else { lTmpWChar = tinyfd_mbcsTo16(aTitle); }
2172 wcscpy(lTitle, lTmpWChar);
2174 if (aDefaultPathAndFile) {
2175 if (tinyfd_winUtf8) { lTmpWChar = tinyfd_utf8to16(aDefaultPathAndFile); }
2176 else { lTmpWChar = tinyfd_mbcsTo16(aDefaultPathAndFile); }
2177 wcscpy(lDefaultPathAndFile, lTmpWChar);
2179 if (aSingleFilterDescription) {
2180 if (tinyfd_winUtf8) { lTmpWChar = tinyfd_utf8to16(aSingleFilterDescription); }
2181 else { lTmpWChar = tinyfd_mbcsTo16(aSingleFilterDescription); }
2182 wcscpy(lSingleFilterDescription, lTmpWChar);
2185 lTmpWChar = tinyfd_saveFileDialogW(
2187 lDefaultPathAndFile,
2188 aNumOfFilterPatterns,
2189 (
wchar_t const **) lFilterPatterns,
2190 lSingleFilterDescription);
2192 for (i = 0; i < aNumOfFilterPatterns; i++) {
2193 free(lFilterPatterns[i]);
2195 free(lFilterPatterns);
2201 if (tinyfd_winUtf8) { lTmpChar = tinyfd_utf16to8(lTmpWChar); }
2202 else { lTmpChar = tinyfd_utf16toMbcs(lTmpWChar); }
2203 strcpy(aoBuff, lTmpChar);
2204 if (tinyfd_winUtf8) { (
void)tinyfd_utf16to8(NULL); }
2205 else { (
void)tinyfd_utf16toMbcs(NULL); }
2211 static char *openFileDialogWinGui(
2213 char const *aDefaultPathAndFile,
2214 int aNumOfFilterPatterns,
2215 char const *
const *aFilterPatterns,
2216 char const *aSingleFilterDescription,
2217 int aAllowMultipleSelects)
2219 wchar_t lTitle[128] = L
"";
2221 wchar_t lSingleFilterDescription[128] = L
"";
2222 wchar_t * * lFilterPatterns;
2227 lFilterPatterns = (
wchar_t * *)malloc(aNumOfFilterPatterns *
sizeof(
wchar_t *));
2228 for (i = 0; i < aNumOfFilterPatterns; i++) {
2229 if (tinyfd_winUtf8) { lTmpWChar = tinyfd_utf8to16(aFilterPatterns[i]); }
2230 else { lTmpWChar = tinyfd_mbcsTo16(aFilterPatterns[i]); }
2231 lFilterPatterns[i] = (
wchar_t *)malloc((wcslen(lTmpWChar) + 1) *
sizeof(
wchar_t *));
2232 if (lFilterPatterns[i]) { wcscpy(lFilterPatterns[i], lTmpWChar); }
2236 if (tinyfd_winUtf8) { lTmpWChar = tinyfd_utf8to16(aTitle); }
2237 else { lTmpWChar = tinyfd_mbcsTo16(aTitle); }
2238 wcscpy(lTitle, lTmpWChar);
2240 if (aDefaultPathAndFile) {
2241 if (tinyfd_winUtf8) { lTmpWChar = tinyfd_utf8to16(aDefaultPathAndFile); }
2242 else { lTmpWChar = tinyfd_mbcsTo16(aDefaultPathAndFile); }
2243 wcscpy(lDefaultPathAndFile, lTmpWChar);
2245 if (aSingleFilterDescription) {
2246 if (tinyfd_winUtf8) { lTmpWChar = tinyfd_utf8to16(aSingleFilterDescription); }
2247 else { lTmpWChar = tinyfd_mbcsTo16(aSingleFilterDescription); }
2248 wcscpy(lSingleFilterDescription, lTmpWChar);
2251 lTmpWChar = tinyfd_openFileDialogW(
2253 lDefaultPathAndFile,
2254 aNumOfFilterPatterns,
2255 (
wchar_t const **) lFilterPatterns,
2256 lSingleFilterDescription,
2257 aAllowMultipleSelects);
2259 for (i = 0; i < aNumOfFilterPatterns; i++) {
2260 free(lFilterPatterns[i]);
2262 free(lFilterPatterns);
2264 if (!lTmpWChar) {
return NULL; }
2266 if (tinyfd_winUtf8) { lTmpChar = tinyfd_utf16to8(lTmpWChar); }
2267 else { lTmpChar = tinyfd_utf16toMbcs(lTmpWChar); }
2268 (
void)tinyfd_openFileDialogW(NULL, NULL, 0, NULL, NULL, -1);
2274 static char *selectFolderDialogWinGui(
2277 char const *aDefaultPath)
2279 wchar_t lTitle[128] = L
"";
2285 if (tinyfd_winUtf8) { lTmpWChar = tinyfd_utf8to16(aTitle); }
2286 else { lTmpWChar = tinyfd_mbcsTo16(aTitle); }
2287 wcscpy(lTitle, lTmpWChar);
2290 if (tinyfd_winUtf8) { lTmpWChar = tinyfd_utf8to16(aDefaultPath); }
2291 else { lTmpWChar = tinyfd_mbcsTo16(aDefaultPath); }
2292 wcscpy(lDefaultPath, lTmpWChar);
2295 lTmpWChar = tinyfd_selectFolderDialogW(
2303 if (tinyfd_winUtf8) { lTmpChar = tinyfd_utf16to8(lTmpWChar); }
2304 else { lTmpChar = tinyfd_utf16toMbcs(lTmpWChar); }
2305 strcpy(aoBuff, lTmpChar);
2311 static char *colorChooserWinGui(
2313 char const *aDefaultHexRGB,
2314 unsigned char const aDefaultRGB[3],
2315 unsigned char aoResultRGB[3])
2317 static char lResultHexRGB[8];
2319 wchar_t lTitle[128];
2320 wchar_t lDefaultHexRGB[16];
2325 if (tinyfd_winUtf8) { lTmpWChar = tinyfd_utf8to16(aTitle); }
2326 else { lTmpWChar = tinyfd_mbcsTo16(aTitle); }
2327 wcscpy(lTitle, lTmpWChar);
2329 if (aDefaultHexRGB) {
2330 if (tinyfd_winUtf8) { lTmpWChar = tinyfd_utf8to16(aDefaultHexRGB); }
2331 else { lTmpWChar = tinyfd_mbcsTo16(aDefaultHexRGB); }
2332 wcscpy(lDefaultHexRGB, lTmpWChar);
2335 lTmpWChar = tinyfd_colorChooserW(
2345 if (tinyfd_winUtf8) { lTmpChar = tinyfd_utf16to8(lTmpWChar); }
2346 else { lTmpChar = tinyfd_utf16toMbcs(lTmpWChar); }
2347 strcpy(lResultHexRGB, lTmpChar);
2349 return lResultHexRGB;
2353 static int dialogPresent(
void)
2355 static int lDialogPresent = -1 ;
2358 char const *lString =
"dialog.exe";
2360 if (lDialogPresent < 0) {
2361 if (!(lIn = _popen(
"where dialog.exe",
"r"))) {
2362 lDialogPresent = 0 ;
2365 while (fgets(lBuff,
sizeof(lBuff), lIn) != NULL)
2368 if (lBuff[strlen(lBuff) - 1] ==
'\n') {
2369 lBuff[strlen(lBuff) - 1] =
'\0' ;
2371 if (strcmp(lBuff + strlen(lBuff) - strlen(lString), lString)) {
2372 lDialogPresent = 0 ;
2374 lDialogPresent = 1 ;
2377 return lDialogPresent;
2381 static int messageBoxWinConsole(
2383 char const *aMessage,
2384 char const *aDialogType,
2385 char const *aIconType,
2393 strcpy(lDialogString,
"dialog ");
2394 if (aTitle && strlen(aTitle)) {
2395 strcat(lDialogString,
"--title \"") ;
2396 strcat(lDialogString, aTitle) ;
2397 strcat(lDialogString,
"\" ") ;
2400 if (aDialogType && (!strcmp(
"okcancel", aDialogType)
2401 || !strcmp(
"yesno", aDialogType) || !strcmp(
"yesnocancel", aDialogType))) {
2402 strcat(lDialogString,
"--backtitle \"") ;
2403 strcat(lDialogString,
"tab: move focus") ;
2404 strcat(lDialogString,
"\" ") ;
2407 if (aDialogType && ! strcmp(
"okcancel", aDialogType)) {
2408 if (! aDefaultButton) {
2409 strcat(lDialogString,
"--defaultno ") ;
2411 strcat(lDialogString,
2412 "--yes-label \"Ok\" --no-label \"Cancel\" --yesno ") ;
2413 }
else if (aDialogType && ! strcmp(
"yesno", aDialogType)) {
2414 if (! aDefaultButton) {
2415 strcat(lDialogString,
"--defaultno ") ;
2417 strcat(lDialogString,
"--yesno ") ;
2418 }
else if (aDialogType && !strcmp(
"yesnocancel", aDialogType)) {
2419 if (!aDefaultButton) {
2420 strcat(lDialogString,
"--defaultno ");
2422 strcat(lDialogString,
"--menu ");
2424 strcat(lDialogString,
"--msgbox ") ;
2427 strcat(lDialogString,
"\"") ;
2428 if (aMessage && strlen(aMessage)) {
2430 strcat(lDialogString, lBuff) ;
2433 strcat(lDialogString,
"\" ");
2435 if (aDialogType && !strcmp(
"yesnocancel", aDialogType)) {
2436 strcat(lDialogString,
"0 60 0 Yes \"\" No \"\"");
2437 strcat(lDialogString,
"2>>");
2439 strcat(lDialogString,
"10 60");
2440 strcat(lDialogString,
" && echo 1 > ");
2443 strcpy(lDialogFile, getenv(
"TEMP"));
2444 strcat(lDialogFile,
"\\tinyfd.txt");
2445 strcat(lDialogString, lDialogFile);
2448 system(lDialogString) ;
2450 if (!(lIn = fopen(lDialogFile,
"r"))) {
2451 remove(lDialogFile);
2454 while (fgets(lBuff,
sizeof(lBuff), lIn) != NULL)
2457 remove(lDialogFile);
2458 if (lBuff[strlen(lBuff) - 1] ==
'\n') {
2459 lBuff[strlen(lBuff) - 1] =
'\0' ;
2463 if (! strlen(lBuff)) {
2467 if (aDialogType && !strcmp(
"yesnocancel", aDialogType)) {
2468 if (lBuff[0] ==
'Y') {
return 1; }
2476 static int inputBoxWinConsole(
2479 char const *aMessage,
2480 char const *aDefaultInput)
2487 strcpy(lDialogFile, getenv(
"TEMP"));
2488 strcat(lDialogFile,
"\\tinyfd.txt");
2489 strcpy(lDialogString,
"echo|set /p=1 >") ;
2490 strcat(lDialogString, lDialogFile);
2491 strcat(lDialogString,
" & ") ;
2493 strcat(lDialogString,
"dialog ") ;
2494 if (aTitle && strlen(aTitle)) {
2495 strcat(lDialogString,
"--title \"") ;
2496 strcat(lDialogString, aTitle) ;
2497 strcat(lDialogString,
"\" ") ;
2500 strcat(lDialogString,
"--backtitle \"") ;
2501 strcat(lDialogString,
"tab: move focus") ;
2502 if (! aDefaultInput) {
2503 strcat(lDialogString,
" (sometimes nothing, no blink nor star, is shown in text field)") ;
2506 strcat(lDialogString,
"\" ") ;
2508 if (! aDefaultInput) {
2509 strcat(lDialogString,
"--insecure --passwordbox") ;
2511 strcat(lDialogString,
"--inputbox") ;
2513 strcat(lDialogString,
" \"") ;
2514 if (aMessage && strlen(aMessage)) {
2515 strcat(lDialogString, aMessage) ;
2517 strcat(lDialogString,
"\" 10 60 ") ;
2518 if (aDefaultInput && strlen(aDefaultInput)) {
2519 strcat(lDialogString,
"\"") ;
2520 strcat(lDialogString, aDefaultInput) ;
2521 strcat(lDialogString,
"\" ") ;
2524 strcat(lDialogString,
"2>>");
2525 strcpy(lDialogFile, getenv(
"TEMP"));
2526 strcat(lDialogFile,
"\\tinyfd.txt");
2527 strcat(lDialogString, lDialogFile);
2528 strcat(lDialogString,
" || echo 0 > ");
2529 strcat(lDialogString, lDialogFile);
2532 system(lDialogString) ;
2534 if (!(lIn = fopen(lDialogFile,
"r"))) {
2535 remove(lDialogFile);
2544 remove(lDialogFile);
2545 if (aoBuff[strlen(aoBuff) - 1] ==
'\n') {
2546 aoBuff[strlen(aoBuff) - 1] =
'\0' ;
2551 lResult = strncmp(aoBuff,
"1", 1) ? 0 : 1 ;
2558 strcpy(aoBuff, aoBuff + 3);
2563 static char *saveFileDialogWinConsole(
2566 char const *aDefaultPathAndFile)
2572 strcpy(lDialogString,
"dialog ") ;
2573 if (aTitle && strlen(aTitle)) {
2574 strcat(lDialogString,
"--title \"") ;
2575 strcat(lDialogString, aTitle) ;
2576 strcat(lDialogString,
"\" ") ;
2579 strcat(lDialogString,
"--backtitle \"") ;
2580 strcat(lDialogString,
2581 "tab: focus | /: populate | spacebar: fill text field | ok: TEXT FIELD ONLY") ;
2582 strcat(lDialogString,
"\" ") ;
2584 strcat(lDialogString,
"--fselect \"") ;
2585 if (aDefaultPathAndFile && strlen(aDefaultPathAndFile)) {
2587 strcpy(lPathAndFile, aDefaultPathAndFile);
2588 replaceChr(lPathAndFile,
'\\',
'/') ;
2592 if (! strchr(lPathAndFile,
'/')) {
2593 strcat(lDialogString,
"./") ;
2595 strcat(lDialogString, lPathAndFile) ;
2596 strcat(lDialogString,
"\" 0 60 2>");
2597 strcpy(lPathAndFile, getenv(
"TEMP"));
2598 strcat(lPathAndFile,
"\\tinyfd.txt");
2599 strcat(lDialogString, lPathAndFile);
2602 system(lDialogString) ;
2604 if (!(lIn = fopen(lPathAndFile,
"r"))) {
2605 remove(lPathAndFile);
2611 remove(lPathAndFile);
2612 replaceChr(aoBuff,
'/',
'\\') ;
2615 if (! strlen(lDialogString)) {
2622 static char *openFileDialogWinConsole(
2624 char const *aDefaultPathAndFile)
2632 strcpy(lDialogString,
"dialog ") ;
2633 if (aTitle && strlen(aTitle)) {
2634 strcat(lDialogString,
"--title \"") ;
2635 strcat(lDialogString, aTitle) ;
2636 strcat(lDialogString,
"\" ") ;
2639 strcat(lDialogString,
"--backtitle \"") ;
2640 strcat(lDialogString,
2641 "tab: focus | /: populate | spacebar: fill text field | ok: TEXT FIELD ONLY") ;
2642 strcat(lDialogString,
"\" ") ;
2644 strcat(lDialogString,
"--fselect \"") ;
2645 if (aDefaultPathAndFile && strlen(aDefaultPathAndFile)) {
2647 strcpy(lFilterPatterns, aDefaultPathAndFile);
2648 replaceChr(lFilterPatterns,
'\\',
'/') ;
2652 if (! strchr(lFilterPatterns,
'/')) {
2653 strcat(lDialogString,
"./") ;
2655 strcat(lDialogString, lFilterPatterns) ;
2656 strcat(lDialogString,
"\" 0 60 2>");
2657 strcpy(lFilterPatterns, getenv(
"TEMP"));
2658 strcat(lFilterPatterns,
"\\tinyfd.txt");
2659 strcat(lDialogString, lFilterPatterns);
2662 system(lDialogString) ;
2664 if (!(lIn = fopen(lFilterPatterns,
"r"))) {
2665 remove(lFilterPatterns);
2671 remove(lFilterPatterns);
2672 replaceChr(aoBuff,
'/',
'\\') ;
2678 static char *selectFolderDialogWinConsole(
2681 char const *aDefaultPath)
2687 strcpy(lDialogString,
"dialog ") ;
2688 if (aTitle && strlen(aTitle)) {
2689 strcat(lDialogString,
"--title \"") ;
2690 strcat(lDialogString, aTitle) ;
2691 strcat(lDialogString,
"\" ") ;
2694 strcat(lDialogString,
"--backtitle \"") ;
2695 strcat(lDialogString,
2696 "tab: focus | /: populate | spacebar: fill text field | ok: TEXT FIELD ONLY") ;
2697 strcat(lDialogString,
"\" ") ;
2699 strcat(lDialogString,
"--dselect \"") ;
2700 if (aDefaultPath && strlen(aDefaultPath)) {
2702 strcpy(lString, aDefaultPath) ;
2704 replaceChr(lString,
'\\',
'/') ;
2705 strcat(lDialogString, lString) ;
2708 strcat(lDialogString,
"./") ;
2710 strcat(lDialogString,
"\" 0 60 2>");
2711 strcpy(lString, getenv(
"TEMP"));
2712 strcat(lString,
"\\tinyfd.txt");
2713 strcat(lDialogString, lString);
2716 system(lDialogString) ;
2718 if (!(lIn = fopen(lString,
"r"))) {
2726 replaceChr(aoBuff,
'/',
'\\') ;
2731 static void writeUtf8(
char const *aUtf8String)
2734 void *lConsoleHandle;
2737 lConsoleHandle = GetStdHandle(STD_OUTPUT_HANDLE);
2738 lTmpWChar = tinyfd_utf8to16(aUtf8String);
2739 (
void)WriteConsoleW(lConsoleHandle, lTmpWChar, (DWORD) wcslen(lTmpWChar), &lNum, NULL);
2745 char const *aMessage,
2746 char const *aDialogType,
2747 char const *aIconType,
2751 UINT lOriginalCP = 0;
2752 UINT lOriginalOutputCP = 0;
2759 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) { strcpy(
tinyfd_response,
"windows");
return 1; }
2760 return messageBoxWinGui(aTitle, aMessage, aDialogType, aIconType, aDefaultButton);
2761 }
else if (dialogPresent()) {
2762 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) { strcpy(
tinyfd_response,
"dialog");
return 0; }
2763 return messageBoxWinConsole(
2764 aTitle, aMessage, aDialogType, aIconType, aDefaultButton);
2766 if (!tinyfd_winUtf8) {
2767 lOriginalCP = GetConsoleCP();
2768 lOriginalOutputCP = GetConsoleOutputCP();
2769 (
void)SetConsoleCP(GetACP());
2770 (
void)SetConsoleOutputCP(GetACP());
2773 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) { strcpy(
tinyfd_response,
"basicinput");
return 0; }
2776 printf(
"\n\n%s\n",
gTitle);
2780 if (aTitle && strlen(aTitle)) {
2782 if (tinyfd_winUtf8) { writeUtf8(aTitle); }
2783 else { printf(
"%s", aTitle); }
2786 if (aDialogType && !strcmp(
"yesno", aDialogType)) {
2788 if (aMessage && strlen(aMessage)) {
2789 if (tinyfd_winUtf8) { writeUtf8(aMessage); }
2790 else { printf(
"%s", aMessage); }
2794 lChar = (char)tolower(_getch());
2796 }
while (lChar !=
'y' && lChar !=
'n');
2797 if (!tinyfd_winUtf8) { (
void)SetConsoleCP(lOriginalCP); (
void)SetConsoleOutputCP(lOriginalOutputCP); }
2798 return lChar ==
'y' ? 1 : 0;
2799 }
else if (aDialogType && !strcmp(
"okcancel", aDialogType)) {
2801 if (aMessage && strlen(aMessage)) {
2802 if (tinyfd_winUtf8) { writeUtf8(aMessage); }
2803 else { printf(
"%s", aMessage); }
2806 printf(
"[O]kay/[C]ancel: ");
2807 lChar = (char)tolower(_getch());
2809 }
while (lChar !=
'o' && lChar !=
'c');
2810 if (!tinyfd_winUtf8) { (
void)SetConsoleCP(lOriginalCP); (
void)SetConsoleOutputCP(lOriginalOutputCP); }
2811 return lChar ==
'o' ? 1 : 0;
2812 }
else if (aDialogType && !strcmp(
"yesnocancel", aDialogType)) {
2814 if (aMessage && strlen(aMessage)) {
2815 if (tinyfd_winUtf8) { writeUtf8(aMessage); }
2816 else { printf(
"%s", aMessage); }
2819 printf(
"[Y]es/[N]o/[C]ancel: ");
2820 lChar = (char)tolower(_getch());
2822 }
while (lChar !=
'y' && lChar !=
'n' && lChar !=
'c');
2823 if (!tinyfd_winUtf8) { (
void)SetConsoleCP(lOriginalCP); (
void)SetConsoleOutputCP(lOriginalOutputCP); }
2824 return (lChar ==
'y') ? 1 : (lChar ==
'n') ? 2 : 0;
2826 if (aMessage && strlen(aMessage)) {
2827 if (tinyfd_winUtf8) { writeUtf8(aMessage); }
2828 else { printf(
"%s", aMessage); }
2831 printf(
"press enter to continue ");
2832 lChar = (char)_getch();
2834 if (!tinyfd_winUtf8) { (
void)SetConsoleCP(lOriginalCP); (
void)SetConsoleOutputCP(lOriginalOutputCP); }
2844 char const *aMessage,
2845 char const *aIconType)
2851 GetConsoleWindow() ||
2854 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"windows");
return 1;}
2855 return notifyWinGui(aTitle, aMessage, aIconType);
2865 char const *aMessage,
2866 char const *aDefaultInput)
2872 HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);
2875 void *lConsoleHandle;
2877 wchar_t lBuffW[1024];
2879 UINT lOriginalCP = 0;
2880 UINT lOriginalOutputCP = 0;
2882 if (!aTitle && !aMessage && !aDefaultInput) {
return lBuff; }
2889 hStdin = GetStdHandle(STD_INPUT_HANDLE);
2892 GetConsoleWindow() ||
2895 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"windows");
return (
char *)1;}
2897 if (inputBoxWinGui(lBuff, aTitle, aMessage, aDefaultInput)) {
return lBuff; }
2898 else {
return NULL; }
2899 }
else if (dialogPresent()) {
2900 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"dialog");
return (
char *)0;}
2902 if (inputBoxWinConsole(lBuff, aTitle, aMessage, aDefaultInput)) {
return lBuff; }
2903 else {
return NULL; }
2905 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"basicinput");
return (
char *)0;}
2909 printf(
"\n\n%s\n",
gTitle);
2913 if (!tinyfd_winUtf8) {
2914 lOriginalCP = GetConsoleCP();
2915 lOriginalOutputCP = GetConsoleOutputCP();
2916 (
void)SetConsoleCP(GetACP());
2917 (
void)SetConsoleOutputCP(GetACP());
2920 if (aTitle && strlen(aTitle)) {
2922 if (tinyfd_winUtf8) { writeUtf8(aTitle); }
2923 else { printf(
"%s", aTitle); }
2926 if (aMessage && strlen(aMessage)) {
2927 if (tinyfd_winUtf8) { writeUtf8(aMessage); }
2928 else { printf(
"%s", aMessage); }
2931 printf(
"(ctrl-Z + enter to cancel): ");
2932 if (! aDefaultInput) {
2933 (
void) GetConsoleMode(hStdin, &mode);
2934 (
void) SetConsoleMode(hStdin, mode & (~ENABLE_ECHO_INPUT));
2936 if (tinyfd_winUtf8) {
2937 lConsoleHandle = GetStdHandle(STD_INPUT_HANDLE);
2939 if (!aDefaultInput) {
2940 (
void)SetConsoleMode(hStdin, mode);
2943 lBuffW[lNum] =
'\0';
2944 if (lBuffW[wcslen(lBuffW) - 1] ==
'\n') { lBuffW[wcslen(lBuffW) - 1] =
'\0'; }
2945 if (lBuffW[wcslen(lBuffW) - 1] ==
'\r') { lBuffW[wcslen(lBuffW) - 1] =
'\0'; }
2946 lTmpChar = tinyfd_utf16to8(lBuffW);
2948 strcpy(lBuff, lTmpChar);
2955 if (!aDefaultInput) {
2956 (
void)SetConsoleMode(hStdin, mode);
2960 if (!tinyfd_winUtf8) {
2961 (
void)SetConsoleCP(lOriginalCP);
2962 (
void)SetConsoleOutputCP(lOriginalOutputCP);
2969 if (strchr(lBuff, 27)) {
2972 if (lBuff[strlen(lBuff) - 1] ==
'\n') {
2973 lBuff[strlen(lBuff) - 1] =
'\0';
2983 char const *aDefaultPathAndFile,
2984 int aNumOfFilterPatterns,
2985 char const *
const *aFilterPatterns,
2986 char const *aSingleFilterDescription)
2991 char *lPointerInputBox;
2997 if (
tfd_quoteDetected(aDefaultPathAndFile)) {
return tinyfd_saveFileDialog(aTitle,
"INVALID DEFAULT_PATH WITH QUOTES", aNumOfFilterPatterns, aFilterPatterns, aSingleFilterDescription); }
2998 if (
tfd_quoteDetected(aSingleFilterDescription)) {
return tinyfd_saveFileDialog(aTitle, aDefaultPathAndFile, aNumOfFilterPatterns, aFilterPatterns,
"INVALID FILTER_DESCRIPTION WITH QUOTES"); }
2999 for (i = 0; i < aNumOfFilterPatterns; i++) {
3006 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"windows");
return (
char *)1;}
3007 p = saveFileDialogWinGui(lBuff,
3008 aTitle, aDefaultPathAndFile, aNumOfFilterPatterns, (
char const *
const *)aFilterPatterns, aSingleFilterDescription);
3009 }
else if (dialogPresent()) {
3010 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) { strcpy(
tinyfd_response,
"dialog");
return (
char *)0; }
3011 p = saveFileDialogWinConsole(lBuff, aTitle, aDefaultPathAndFile);
3013 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) { strcpy(
tinyfd_response,
"basicinput");
return (
char *)0; }
3014 strcpy(lBuff,
"Save file in ");
3018 if (lPointerInputBox) { strcpy(lString, lPointerInputBox); }
3020 if (p) { strcpy(lBuff, p); }
else { lBuff[0] =
'\0'; }
3021 if (lPointerInputBox) { strcpy(lPointerInputBox, lString); }
3025 if (! p || ! strlen(p)) {
3029 if (strlen(lString) && !
dirExists(lString)) {
3043 char const *aDefaultPathAndFile,
3044 int aNumOfFilterPatterns,
3045 char const *
const *aFilterPatterns,
3046 char const *aSingleFilterDescription,
3047 int aAllowMultipleSelects)
3052 char *lPointerInputBox;
3055 if (
tfd_quoteDetected(aTitle)) {
return tinyfd_openFileDialog(
"INVALID TITLE WITH QUOTES", aDefaultPathAndFile, aNumOfFilterPatterns, aFilterPatterns, aSingleFilterDescription, aAllowMultipleSelects); }
3056 if (
tfd_quoteDetected(aDefaultPathAndFile)) {
return tinyfd_openFileDialog(aTitle,
"INVALID DEFAULT_PATH WITH QUOTES", aNumOfFilterPatterns, aFilterPatterns, aSingleFilterDescription, aAllowMultipleSelects); }
3057 if (
tfd_quoteDetected(aSingleFilterDescription)) {
return tinyfd_openFileDialog(aTitle, aDefaultPathAndFile, aNumOfFilterPatterns, aFilterPatterns,
"INVALID FILTER_DESCRIPTION WITH QUOTES", aAllowMultipleSelects); }
3058 for (i = 0; i < aNumOfFilterPatterns; i++) {
3064 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"windows");
return (
char *)1;}
3065 p = openFileDialogWinGui(aTitle, aDefaultPathAndFile, aNumOfFilterPatterns,
3066 (
char const *
const *)aFilterPatterns, aSingleFilterDescription, aAllowMultipleSelects);
3067 }
else if (dialogPresent()) {
3068 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) { strcpy(
tinyfd_response,
"dialog");
return (
char *)0; }
3069 p = openFileDialogWinConsole(aTitle, aDefaultPathAndFile);
3071 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) { strcpy(
tinyfd_response,
"basicinput");
return (
char *)0; }
3072 strcpy(lBuff,
"Open file from ");
3075 if (lPointerInputBox) { strcpy(lString, lPointerInputBox); }
3077 if (p) { strcpy(lBuff, p); }
else { lBuff[0] =
'\0'; }
3078 if (lPointerInputBox) { strcpy(lPointerInputBox, lString); }
3082 if (! p || ! strlen(p)) {
3085 if (aAllowMultipleSelects && strchr(p,
'|')) {
3097 char const *aDefaultPath)
3101 char *lPointerInputBox;
3109 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"windows");
return (
char *)1;}
3110 p = selectFolderDialogWinGui(lBuff, aTitle, aDefaultPath);
3111 }
else if (dialogPresent()) {
3112 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) { strcpy(
tinyfd_response,
"dialog");
return (
char *)0; }
3113 p = selectFolderDialogWinConsole(lBuff, aTitle, aDefaultPath);
3115 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) { strcpy(
tinyfd_response,
"basicinput");
return (
char *)0; }
3116 strcpy(lBuff,
"Select folder from ");
3119 if (lPointerInputBox) { strcpy(lString, lPointerInputBox); }
3121 if (p) { strcpy(lBuff, p); }
else { lBuff[0] =
'\0'; }
3122 if (lPointerInputBox) { strcpy(lPointerInputBox, lString); }
3126 if (! p || ! strlen(p) || !
dirExists(p)) {
3139 char const *aDefaultHexRGB,
3140 unsigned char const aDefaultRGB[3],
3141 unsigned char aoResultRGB[3])
3143 static char lDefaultHexRGB[16];
3146 char *lPointerInputBox;
3149 lDefaultHexRGB[0] =
'\0';
3156 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"windows");
return (
char *)1;}
3157 p = colorChooserWinGui(aTitle, aDefaultHexRGB, aDefaultRGB, aoResultRGB);
3159 strcpy(lDefaultHexRGB, p);
3160 return lDefaultHexRGB;
3163 }
else if (dialogPresent()) {
3164 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) { strcpy(
tinyfd_response,
"dialog");
return (
char *)0; }
3166 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) { strcpy(
tinyfd_response,
"basicinput");
return (
char *)0; }
3169 if (aDefaultHexRGB) {
3170 strncpy(lDefaultHexRGB, aDefaultHexRGB, 7);
3171 lDefaultHexRGB[7] =
'\0';
3173 RGB2Hex(aDefaultRGB, lDefaultHexRGB);
3177 if (lPointerInputBox) { strcpy(lString, lPointerInputBox); }
3178 p =
tinyfd_inputBox(aTitle,
"Enter hex rgb color (i.e. #f5ca20)", lDefaultHexRGB);
3180 if (!p || (strlen(p) != 7) || (p[0] !=
'#')) {
3183 for (i = 1 ; i < 7 ; i ++) {
3184 if (! isxdigit((
int) p[i])) {
3190 strcpy(lDefaultHexRGB, p);
3192 if (lPointerInputBox) { strcpy(lPointerInputBox, lString); }
3194 return lDefaultHexRGB;
3206 static int lsIsDarwin = -1 ;
3207 struct utsname lUtsname ;
3208 if (lsIsDarwin < 0) {
3209 lsIsDarwin = !uname(&lUtsname) && !strcmp(lUtsname.sysname,
"Darwin") ;
3218 if (! aDirPath || ! strlen(aDirPath)) {
3221 lDir = opendir(aDirPath) ;
3236 char *lAllocatedCharString;
3237 int lSubstringUndetected;
3240 strcat(lTestedString, aExecutable) ;
3241 strcat(lTestedString,
" 2>/dev/null ");
3242 lIn = popen(lTestedString,
"r") ;
3243 if ((fgets(lBuff,
sizeof(lBuff), lIn) != NULL)
3244 && (! strchr(lBuff,
':')) && (strncmp(lBuff,
"no ", 3))) {
3249 if (lBuff[strlen(lBuff) - 1] ==
'\n') { lBuff[strlen(lBuff) - 1] =
'\0' ; }
3250 lAllocatedCharString = realpath(lBuff, NULL);
3251 lSubstringUndetected = ! strstr(lAllocatedCharString, aExecutable);
3252 free(lAllocatedCharString);
3253 if (lSubstringUndetected) {
3254 if (
tinyfd_verbose) { printf(
"detectPresence %s %d\n", aExecutable, 0); }
3259 if (
tinyfd_verbose) { printf(
"detectPresence %s %d\n", aExecutable, 1); }
3263 if (
tinyfd_verbose) { printf(
"detectPresence %s %d\n", aExecutable, 0); }
3276 strcpy(lTestedString, aExecutable) ;
3277 strcat(lTestedString,
" --version") ;
3279 lIn = popen(lTestedString,
"r") ;
3280 lTmp = fgets(lBuff,
sizeof(lBuff), lIn) ;
3283 lTmp += strcspn(lTmp,
"0123456789");
3291 static int lArray[3] ;
3295 lArray[0] = atoi(strtok(lTmp,
" ,.-")) ;
3297 lArray[1] = atoi(strtok(0,
" ,.-")) ;
3299 lArray[2] = atoi(strtok(0,
" ,.-")) ;
3302 if (!lArray[0] && !lArray[1] && !lArray[2]) {
return NULL; }
3312 lIn = popen(aCommand,
"r") ;
3313 if (fgets(lBuff,
sizeof(lBuff), lIn) == NULL) {
3327 static int lIsTerminalRunning = -1 ;
3328 if (lIsTerminalRunning < 0) {
3329 lIsTerminalRunning = isatty(1);
3330 if (
tinyfd_verbose) { printf(
"isTerminalRunning %d\n", lIsTerminalRunning); }
3332 return lIsTerminalRunning;
3338 static char lDialogName[128] =
"*" ;
3339 if (lDialogName[0] ==
'*') {
3341 strcpy(lDialogName,
"");
3342 }
else if (
tfd_isDarwin() && * strcpy(lDialogName,
"/opt/local/bin/dialog")
3345 else if (* strcpy(lDialogName,
"dialog")
3349 strcpy(lDialogName,
"");
3352 return lDialogName ;
3358 char const *lDialogName ;
3371 if (! strlen(lDialogName) || !(lVersion = (
char *)
getVersion(lDialogName))) {
return 0 ; }
3374 strcpy(lBuff, lVersion);
3375 lMajor = atoi(strtok(lVersion,
" ,.-")) ;
3377 lMinorP = strtok(0,
" ,.-abcdefghijklmnopqrstuvxyz");
3378 lMinor = atoi(lMinorP) ;
3380 lDate = atoi(strtok(0,
" ,.-")) ;
3381 if (lDate < 0) { lDate = - lDate; }
3383 lLetter = lMinorP + strlen(lMinorP) ;
3384 strcpy(lVersion, lBuff);
3385 strtok(lLetter,
" ,.-");
3387 lResult = (lMajor > 0) || ((lMinor == 9) && (*lLetter ==
'b') && (lDate >= 20031126));
3395 static int lWhiptailPresent = -1 ;
3397 if (lWhiptailPresent < 0) {
3400 return lWhiptailPresent ;
3406 static char lTerminalName[128] =
"*" ;
3407 char lShellName[64] =
"*" ;
3410 if (lTerminalName[0] ==
'*') {
3412 strcpy(lShellName,
"bash -c ") ;
3414 strcpy(lShellName,
"sh -c ") ;
3416 strcpy(lTerminalName,
"") ;
3421 if (* strcpy(lTerminalName,
"/opt/X11/bin/xterm")
3423 strcat(lTerminalName,
" -fa 'DejaVu Sans Mono' -fs 10 -title tinyfiledialogs -e ") ;
3424 strcat(lTerminalName, lShellName) ;
3426 strcpy(lTerminalName,
"") ;
3428 }
else if (* strcpy(lTerminalName,
"xterm")
3430 strcat(lTerminalName,
" -fa 'DejaVu Sans Mono' -fs 10 -title tinyfiledialogs -e ") ;
3431 strcat(lTerminalName, lShellName) ;
3432 }
else if (* strcpy(lTerminalName,
"terminator")
3434 strcat(lTerminalName,
" -x ") ;
3435 strcat(lTerminalName, lShellName) ;
3436 }
else if (* strcpy(lTerminalName,
"lxterminal")
3438 strcat(lTerminalName,
" -e ") ;
3439 strcat(lTerminalName, lShellName) ;
3440 }
else if (* strcpy(lTerminalName,
"konsole")
3442 strcat(lTerminalName,
" -e ") ;
3443 strcat(lTerminalName, lShellName) ;
3444 }
else if (* strcpy(lTerminalName,
"kterm")
3446 strcat(lTerminalName,
" -e ") ;
3447 strcat(lTerminalName, lShellName) ;
3448 }
else if (* strcpy(lTerminalName,
"tilix")
3450 strcat(lTerminalName,
" -e ") ;
3451 strcat(lTerminalName, lShellName) ;
3452 }
else if (* strcpy(lTerminalName,
"xfce4-terminal")
3454 strcat(lTerminalName,
" -x ") ;
3455 strcat(lTerminalName, lShellName) ;
3456 }
else if (* strcpy(lTerminalName,
"mate-terminal")
3458 strcat(lTerminalName,
" -x ") ;
3459 strcat(lTerminalName, lShellName) ;
3460 }
else if (* strcpy(lTerminalName,
"Eterm")
3462 strcat(lTerminalName,
" -e ") ;
3463 strcat(lTerminalName, lShellName) ;
3464 }
else if (* strcpy(lTerminalName,
"evilvte")
3466 strcat(lTerminalName,
" -e ") ;
3467 strcat(lTerminalName, lShellName) ;
3468 }
else if (* strcpy(lTerminalName,
"pterm")
3470 strcat(lTerminalName,
" -e ") ;
3471 strcat(lTerminalName, lShellName) ;
3472 }
else if (* strcpy(lTerminalName,
"gnome-terminal")
3474 && ((lArray[0] < 3) || (lArray[0] == 3 && lArray[1] <= 6))) {
3475 strcat(lTerminalName,
" --disable-factory -x ") ;
3476 strcat(lTerminalName, lShellName) ;
3478 strcpy(lTerminalName,
"") ;
3484 if (strlen(lTerminalName)) {
3485 return lTerminalName ;
3497 return lDialogName ;
3506 int lWhiptailPresent ;
3509 return lWhiptailPresent ;
3527 static int lPactlPresent = -1 ;
3528 if (lPactlPresent < 0) {
3531 return lPactlPresent ;
3537 static int lSpeakertestPresent = -1 ;
3538 if (lSpeakertestPresent < 0) {
3541 return lSpeakertestPresent ;
3547 static int lPlayPresent = -1;
3548 if (lPlayPresent < 0) {
3551 return lPlayPresent;
3557 static int lBeepexePresent = -1;
3558 if (lBeepexePresent < 0) {
3561 return lBeepexePresent;
3567 static int lBeepPresent = -1 ;
3568 if (lBeepPresent < 0) {
3571 return lBeepPresent ;
3577 static int lXmessagePresent = -1 ;
3578 if (lXmessagePresent < 0) {
3587 static int lGxmessagePresent = -1 ;
3588 if (lGxmessagePresent < 0) {
3597 static int lGmessagePresent = -1 ;
3598 if (lGmessagePresent < 0) {
3607 static int lNotifysendPresent = -1 ;
3608 if (lNotifysendPresent < 0) {
3617 static int lPerlPresent = -1 ;
3621 if (lPerlPresent < 0) {
3624 lIn = popen(
"perl -MNet::DBus -e \"Net::DBus->session->get_service('org.freedesktop.Notifications')\" 2>&1",
"r");
3625 if (fgets(lBuff,
sizeof(lBuff), lIn) == NULL) {
3638 static int lAfplayPresent = -1 ;
3642 if (lAfplayPresent < 0) {
3644 if (lAfplayPresent) {
3645 lIn = popen(
"test -e /System/Library/Sounds/Ping.aiff || echo Ping",
"r") ;
3646 if (fgets(lBuff,
sizeof(lBuff), lIn) == NULL) {
3647 lAfplayPresent = 2 ;
3659 static int lXdialogPresent = -1 ;
3660 if (lXdialogPresent < 0) {
3669 static int lGdialoglPresent = -1 ;
3670 if (lGdialoglPresent < 0) {
3679 static int lOsascriptPresent = -1 ;
3680 if (lOsascriptPresent < 0) {
3684 return lOsascriptPresent &&
graphicMode() && !getenv(
"SSH_TTY") ;
3690 static int lQarmaPresent = -1 ;
3691 if (lQarmaPresent < 0) {
3700 static int lMatedialogPresent = -1 ;
3701 if (lMatedialogPresent < 0) {
3710 static int lShellementaryPresent = -1 ;
3711 if (lShellementaryPresent < 0) {
3712 lShellementaryPresent = 0 ;
3720 static int lXpropPresent = -1 ;
3721 if (lXpropPresent < 0) {
3730 static int lZenityPresent = -1 ;
3731 if (lZenityPresent < 0) {
3740 static int lYadPresent = -1;
3741 if (lYadPresent < 0) {
3750 static int lZenity3Present = -1 ;
3755 if (lZenity3Present < 0) {
3756 lZenity3Present = 0 ;
3758 lIn = popen(
"zenity --version",
"r") ;
3759 if (fgets(lBuff,
sizeof(lBuff), lIn) != NULL) {
3760 if (atoi(lBuff) >= 3) {
3761 lZenity3Present = 3 ;
3762 lIntTmp = atoi(strtok(lBuff,
".") + 2) ;
3763 if (lIntTmp >= 18) {
3764 lZenity3Present = 5 ;
3765 }
else if (lIntTmp >= 10) {
3766 lZenity3Present = 4 ;
3768 }
else if ((atoi(lBuff) == 2) && (atoi(strtok(lBuff,
".") + 2) >= 32)) {
3769 lZenity3Present = 2 ;
3771 if (
tinyfd_verbose) { printf(
"zenity type %d\n", lZenity3Present); }
3782 static int lKdialogPresent = -1 ;
3787 if (lKdialogPresent < 0) {
3789 lDesktop = getenv(
"XDG_SESSION_DESKTOP");
3790 if (!lDesktop || (strcmp(lDesktop,
"KDE") && strcmp(lDesktop,
"lxqt"))) {
3791 lKdialogPresent = 0 ;
3792 return lKdialogPresent ;
3797 if (lKdialogPresent && !getenv(
"SSH_TTY")) {
3798 lIn = popen(
"kdialog --attach 2>&1",
"r") ;
3799 if (fgets(lBuff,
sizeof(lBuff), lIn) != NULL) {
3800 if (! strstr(
"Unknown", lBuff)) {
3801 lKdialogPresent = 2 ;
3802 if (
tinyfd_verbose) { printf(
"kdialog-attach %d\n", lKdialogPresent); }
3807 if (lKdialogPresent == 2) {
3808 lKdialogPresent = 1 ;
3809 lIn = popen(
"kdialog --passivepopup 2>&1",
"r") ;
3810 if (fgets(lBuff,
sizeof(lBuff), lIn) != NULL) {
3811 if (! strstr(
"Unknown", lBuff)) {
3812 lKdialogPresent = 2 ;
3813 if (
tinyfd_verbose) { printf(
"kdialog-popup %d\n", lKdialogPresent); }
3826 static int lOsx9orBetter = -1 ;
3831 if (lOsx9orBetter < 0) {
3833 lIn = popen(
"osascript -e 'set osver to system version of (system info)'",
"r") ;
3834 if ((fgets(lBuff,
sizeof(lBuff), lIn) != NULL)
3835 && (2 == sscanf(lBuff,
"%d.%d", &V, &v))) {
3842 if (
tinyfd_verbose) { printf(
"Osx10 = %d, %d = %s\n", lOsx9orBetter, V, lBuff) ; }
3844 return lOsx9orBetter ;
3850 static int lPython3Present = -1 ;
3853 if (lPython3Present < 0) {
3854 lPython3Present = 0 ;
3858 for (i = 9 ; i >= 0 ; i --) {
3861 lPython3Present = 1;
3866 if (
tinyfd_verbose) { printf(
"lPython3Present %d\n", lPython3Present) ; }
3869 return lPython3Present ;
3875 static int lPython2Present = -1 ;
3878 if (lPython2Present < 0) {
3879 lPython2Present = 0 ;
3883 for (i = 9 ; i >= 0 ; i --) {
3886 lPython2Present = 1;
3891 if (
tinyfd_verbose) { printf(
"lPython2Present %d\n", lPython2Present) ; }
3894 return lPython2Present ;
3900 static int lTkinter3Present = -1 ;
3901 char lPythonCommand[256];
3902 char lPythonParams[128] =
3903 "-S -c \"try:\n\timport tkinter;\nexcept:\n\tprint(0);\"";
3905 if (lTkinter3Present < 0) {
3906 lTkinter3Present = 0 ;
3908 sprintf(lPythonCommand,
"%s %s",
gPython3Name, lPythonParams) ;
3909 lTkinter3Present =
tryCommand(lPythonCommand) ;
3911 if (
tinyfd_verbose) { printf(
"lTkinter3Present %d\n", lTkinter3Present) ; }
3919 static int lTkinter2Present = -1 ;
3920 char lPythonCommand[256];
3921 char lPythonParams[128] =
3922 "-S -c \"try:\n\timport Tkinter;\nexcept:\n\tprint 0;\"";
3924 if (lTkinter2Present < 0) {
3925 lTkinter2Present = 0 ;
3927 sprintf(lPythonCommand,
"%s %s",
gPython2Name, lPythonParams) ;
3928 lTkinter2Present =
tryCommand(lPythonCommand) ;
3930 if (
tinyfd_verbose) { printf(
"lTkinter2Present %d\n", lTkinter2Present) ; }
3938 static int lPythonDbusPresent = -1 ;
3939 char lPythonCommand[384];
3940 char lPythonParams[256] =
3941 "-c \"try:\n\timport dbus;bus=dbus.SessionBus();\
3942 notif=bus.get_object('org.freedesktop.Notifications','/org/freedesktop/Notifications');\
3943 notify=dbus.Interface(notif,'org.freedesktop.Notifications');\nexcept:\n\tprint(0);\"";
3945 if (lPythonDbusPresent < 0) {
3946 lPythonDbusPresent = 0 ;
3949 sprintf(lPythonCommand,
"%s %s",
gPythonName, lPythonParams) ;
3950 lPythonDbusPresent =
tryCommand(lPythonCommand) ;
3955 sprintf(lPythonCommand,
"%s %s",
gPythonName, lPythonParams) ;
3956 lPythonDbusPresent =
tryCommand(lPythonCommand) ;
3959 if (
tinyfd_verbose) { printf(
"lPythonDbusPresent %d\n", lPythonDbusPresent) ; }
3969 if ((lIn = popen(
"pactl unload-module module-sine",
"r"))) {
3972 if (
tinyfd_verbose) { printf(
"tinyfiledialogs caught signal %d\n", signum); }
3977 char lDialogString[256] ;
3982 strcpy(lDialogString,
"afplay /System/Library/Sounds/Ping.aiff") ;
3984 strcpy(lDialogString,
"osascript -e 'tell application \"System Events\" to beep'") ;
3989 strcpy(lDialogString,
"thnum=$(pactl load-module module-sine frequency=440);sleep .3;pactl unload-module $thnum") ;
3992 strcpy(lDialogString,
"( speaker-test -t sine -f 440 > /dev/tty )& pid=$!;sleep .4; kill -9 $pid") ;
3994 strcpy(lDialogString,
"beep.exe 440 300");
3996 strcpy(lDialogString,
"play -q -n synth .3 sine 440");
3998 strcpy(lDialogString,
"beep -f 440 -l 300") ;
4000 strcpy(lDialogString,
"printf '\a' > /dev/tty") ;
4003 if (
tinyfd_verbose) { printf(
"lDialogString: %s\n", lDialogString) ; }
4005 if ((lIn = popen(lDialogString,
"r"))) {
4010 signal(SIGINT, SIG_DFL);
4017 char const *aMessage,
4018 char const *aDialogType,
4019 char const *aIconType,
4023 char *lDialogString = NULL ;
4024 char *lpDialogString;
4026 int lWasGraphicDialog = 0 ;
4030 struct termios infoOri;
4031 struct termios info;
4033 size_t lMessageLen ;
4040 lTitleLen = aTitle ? strlen(aTitle) : 0 ;
4041 lMessageLen = aMessage ? strlen(aMessage) : 0 ;
4042 if (!aTitle || strcmp(aTitle,
"tinyfd_query")) {
4043 lDialogString = (
char *) malloc(
MAX_PATH_OR_CMD + lTitleLen + lMessageLen);
4047 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"applescript");
return 1;}
4049 strcpy(lDialogString,
"osascript ");
4050 if (!
osx9orBetter()) { strcat(lDialogString,
" -e 'tell application \"System Events\"' -e 'Activate'"); }
4051 strcat(lDialogString,
" -e 'try' -e 'set {vButton} to {button returned} of ( display dialog \"") ;
4052 if (aMessage && strlen(aMessage)) {
4053 strcat(lDialogString, aMessage) ;
4055 strcat(lDialogString,
"\" ") ;
4056 if (aTitle && strlen(aTitle)) {
4057 strcat(lDialogString,
"with title \"") ;
4058 strcat(lDialogString, aTitle) ;
4059 strcat(lDialogString,
"\" ") ;
4061 strcat(lDialogString,
"with icon ") ;
4062 if (aIconType && ! strcmp(
"error", aIconType)) {
4063 strcat(lDialogString,
"stop ") ;
4064 }
else if (aIconType && ! strcmp(
"warning", aIconType)) {
4065 strcat(lDialogString,
"caution ") ;
4067 strcat(lDialogString,
"note ") ;
4069 if (aDialogType && ! strcmp(
"okcancel", aDialogType)) {
4070 if (! aDefaultButton) {
4071 strcat(lDialogString,
"default button \"Cancel\" ") ;
4073 }
else if (aDialogType && ! strcmp(
"yesno", aDialogType)) {
4074 strcat(lDialogString,
"buttons {\"No\", \"Yes\"} ") ;
4075 if (aDefaultButton) {
4076 strcat(lDialogString,
"default button \"Yes\" ") ;
4078 strcat(lDialogString,
"default button \"No\" ") ;
4080 strcat(lDialogString,
"cancel button \"No\"") ;
4081 }
else if (aDialogType && ! strcmp(
"yesnocancel", aDialogType)) {
4082 strcat(lDialogString,
"buttons {\"No\", \"Yes\", \"Cancel\"} ") ;
4083 switch (aDefaultButton) {
4084 case 1: strcat(lDialogString,
"default button \"Yes\" ") ;
break;
4085 case 2: strcat(lDialogString,
"default button \"No\" ") ;
break;
4086 case 0: strcat(lDialogString,
"default button \"Cancel\" ") ;
break;
4088 strcat(lDialogString,
"cancel button \"Cancel\"") ;
4090 strcat(lDialogString,
"buttons {\"OK\"} ") ;
4091 strcat(lDialogString,
"default button \"OK\" ") ;
4093 strcat(lDialogString,
")' ") ;
4095 strcat(lDialogString,
4096 "-e 'if vButton is \"Yes\" then' -e 'return 1'\
4097 -e 'else if vButton is \"OK\" then' -e 'return 1'\
4098 -e 'else if vButton is \"No\" then' -e 'return 2'\
4099 -e 'else' -e 'return 0' -e 'end if' ");
4101 strcat(lDialogString,
"-e 'on error number -128' ") ;
4102 strcat(lDialogString,
"-e '0' ");
4104 strcat(lDialogString,
"-e 'end try'") ;
4105 if (!
osx9orBetter()) { strcat(lDialogString,
" -e 'end tell'") ; }
4107 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"kdialog");
return 1;}
4109 strcpy(lDialogString,
"kdialog") ;
4111 strcat(lDialogString,
" --attach=$(xprop -root 32x '\t$0' _NET_ACTIVE_WINDOW | cut -f 2)");
4114 strcat(lDialogString,
" --") ;
4115 if (aDialogType && (! strcmp(
"okcancel", aDialogType)
4116 || ! strcmp(
"yesno", aDialogType) || ! strcmp(
"yesnocancel", aDialogType))) {
4117 if (aIconType && (! strcmp(
"warning", aIconType)
4118 || ! strcmp(
"error", aIconType))) {
4119 strcat(lDialogString,
"warning") ;
4121 if (! strcmp(
"yesnocancel", aDialogType)) {
4122 strcat(lDialogString,
"yesnocancel") ;
4124 strcat(lDialogString,
"yesno") ;
4126 }
else if (aIconType && ! strcmp(
"error", aIconType)) {
4127 strcat(lDialogString,
"error") ;
4128 }
else if (aIconType && ! strcmp(
"warning", aIconType)) {
4129 strcat(lDialogString,
"sorry") ;
4131 strcat(lDialogString,
"msgbox") ;
4133 strcat(lDialogString,
" \"") ;
4135 strcat(lDialogString, aMessage) ;
4137 strcat(lDialogString,
"\"") ;
4138 if (aDialogType && ! strcmp(
"okcancel", aDialogType)) {
4139 strcat(lDialogString,
4140 " --yes-label Ok --no-label Cancel") ;
4142 if (aTitle && strlen(aTitle)) {
4143 strcat(lDialogString,
" --title \"") ;
4144 strcat(lDialogString, aTitle) ;
4145 strcat(lDialogString,
"\"") ;
4148 if (! strcmp(
"yesnocancel", aDialogType)) {
4149 strcat(lDialogString,
"; x=$? ;if [ $x = 0 ] ;then echo 1;elif [ $x = 1 ] ;then echo 2;else echo 0;fi");
4151 strcat(lDialogString,
";if [ $? = 0 ];then echo 1;else echo 0;fi");
4155 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"zenity");
return 1;}
4156 strcpy(lDialogString,
"szAnswer=$(zenity") ;
4158 strcat(lDialogString,
" --attach=$(sleep .01;xprop -root 32x '\t$0' _NET_ACTIVE_WINDOW | cut -f 2)");
4161 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"matedialog");
return 1;}
4162 strcpy(lDialogString,
"szAnswer=$(matedialog") ;
4164 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"shellementary");
return 1;}
4165 strcpy(lDialogString,
"szAnswer=$(shellementary") ;
4167 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"qarma");
return 1;}
4168 strcpy(lDialogString,
"szAnswer=$(qarma") ;
4170 strcat(lDialogString,
" --attach=$(xprop -root 32x '\t$0' _NET_ACTIVE_WINDOW | cut -f 2)");
4173 strcat(lDialogString,
" --");
4175 if (aDialogType && ! strcmp(
"okcancel", aDialogType)) {
4176 strcat(lDialogString,
4177 "question --ok-label=Ok --cancel-label=Cancel") ;
4178 }
else if (aDialogType && ! strcmp(
"yesno", aDialogType)) {
4179 strcat(lDialogString,
"question") ;
4180 }
else if (aDialogType && ! strcmp(
"yesnocancel", aDialogType)) {
4181 strcat(lDialogString,
"list --column \"\" --hide-header \"Yes\" \"No\"") ;
4182 }
else if (aIconType && ! strcmp(
"error", aIconType)) {
4183 strcat(lDialogString,
"error") ;
4184 }
else if (aIconType && ! strcmp(
"warning", aIconType)) {
4185 strcat(lDialogString,
"warning") ;
4187 strcat(lDialogString,
"info") ;
4189 if (aTitle && strlen(aTitle)) {
4190 strcat(lDialogString,
" --title=\"") ;
4191 strcat(lDialogString, aTitle) ;
4192 strcat(lDialogString,
"\"") ;
4194 if (aMessage && strlen(aMessage)) {
4195 if (strcmp(
"yesnocancel", aDialogType)) { strcat(lDialogString,
" --no-wrap"); }
4196 strcat(lDialogString,
" --text=\"") ;
4197 strcat(lDialogString, aMessage) ;
4198 strcat(lDialogString,
"\"") ;
4201 strcat(lDialogString,
" --icon-name=dialog-") ;
4202 if (aIconType && (! strcmp(
"question", aIconType)
4203 || ! strcmp(
"error", aIconType)
4204 || ! strcmp(
"warning", aIconType))) {
4205 strcat(lDialogString, aIconType) ;
4207 strcat(lDialogString,
"information") ;
4211 if (
tinyfd_silent) { strcat(lDialogString,
" 2>/dev/null "); }
4213 if (! strcmp(
"yesnocancel", aDialogType)) {
4214 strcat(lDialogString,
4215 ");if [ $? = 1 ];then echo 0;elif [ $szAnswer = \"No\" ];then echo 2;else echo 1;fi");
4217 strcat(lDialogString,
");if [ $? = 0 ];then echo 1;else echo 0;fi");
4222 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) { strcpy(
tinyfd_response,
"yad");
return 1; }
4223 strcpy(lDialogString,
"szAnswer=$(yad --");
4224 if (aDialogType && !strcmp(
"ok", aDialogType)) {
4225 strcat(lDialogString,
"button=Ok:1");
4226 }
else if (aDialogType && !strcmp(
"okcancel", aDialogType)) {
4227 strcat(lDialogString,
"button=Ok:1 --button=Cancel:0");
4228 }
else if (aDialogType && !strcmp(
"yesno", aDialogType)) {
4229 strcat(lDialogString,
"button=Yes:1 --button=No:0");
4230 }
else if (aDialogType && !strcmp(
"yesnocancel", aDialogType)) {
4231 strcat(lDialogString,
"button=Yes:1 --button=No:2 --button=Cancel:0");
4232 }
else if (aIconType && !strcmp(
"error", aIconType)) {
4233 strcat(lDialogString,
"error");
4234 }
else if (aIconType && !strcmp(
"warning", aIconType)) {
4235 strcat(lDialogString,
"warning");
4237 strcat(lDialogString,
"info");
4239 if (aTitle && strlen(aTitle)) {
4240 strcat(lDialogString,
" --title=\"");
4241 strcat(lDialogString, aTitle);
4242 strcat(lDialogString,
"\"");
4244 if (aMessage && strlen(aMessage)) {
4245 strcat(lDialogString,
" --text=\"");
4246 strcat(lDialogString, aMessage);
4247 strcat(lDialogString,
"\"");
4250 strcat(lDialogString,
" --icon-name=dialog-");
4251 if (aIconType && (!strcmp(
"question", aIconType)
4252 || !strcmp(
"error", aIconType)
4253 || !strcmp(
"warning", aIconType))) {
4254 strcat(lDialogString, aIconType);
4256 strcat(lDialogString,
"information");
4259 if (
tinyfd_silent) { strcat(lDialogString,
" 2>/dev/null "); }
4260 strcat(lDialogString,
");echo $?");
4264 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"python3-tkinter");
return 1;}
4267 strcat(lDialogString,
4268 " -S -c \"import tkinter;from tkinter import messagebox;root=tkinter.Tk();root.withdraw();");
4270 strcat(lDialogString,
"res=messagebox.") ;
4271 if (aDialogType && ! strcmp(
"okcancel", aDialogType)) {
4272 strcat(lDialogString,
"askokcancel(") ;
4273 if (aDefaultButton) {
4274 strcat(lDialogString,
"default=messagebox.OK,") ;
4276 strcat(lDialogString,
"default=messagebox.CANCEL,") ;
4278 }
else if (aDialogType && ! strcmp(
"yesno", aDialogType)) {
4279 strcat(lDialogString,
"askyesno(") ;
4280 if (aDefaultButton) {
4281 strcat(lDialogString,
"default=messagebox.YES,") ;
4283 strcat(lDialogString,
"default=messagebox.NO,") ;
4285 }
else if (aDialogType && ! strcmp(
"yesnocancel", aDialogType)) {
4286 strcat(lDialogString,
"askyesnocancel(") ;
4287 switch (aDefaultButton) {
4288 case 1: strcat(lDialogString,
"default=messagebox.YES,");
break;
4289 case 2: strcat(lDialogString,
"default=messagebox.NO,");
break;
4290 case 0: strcat(lDialogString,
"default=messagebox.CANCEL,");
break;
4293 strcat(lDialogString,
"showinfo(") ;
4296 strcat(lDialogString,
"icon='") ;
4297 if (aIconType && (! strcmp(
"question", aIconType)
4298 || ! strcmp(
"error", aIconType)
4299 || ! strcmp(
"warning", aIconType))) {
4300 strcat(lDialogString, aIconType) ;
4302 strcat(lDialogString,
"info") ;
4305 strcat(lDialogString,
"',") ;
4306 if (aTitle && strlen(aTitle)) {
4307 strcat(lDialogString,
"title='") ;
4308 strcat(lDialogString, aTitle) ;
4309 strcat(lDialogString,
"',") ;
4311 if (aMessage && strlen(aMessage)) {
4312 strcat(lDialogString,
"message='") ;
4313 lpDialogString = lDialogString + strlen(lDialogString);
4315 strcat(lDialogString,
"'") ;
4318 if (aDialogType && ! strcmp(
"yesnocancel", aDialogType)) {
4319 strcat(lDialogString,
");\n\
4320 if res is None :\n\tprint(0)\n\
4321 elif res is False :\n\tprint(2)\n\
4322 else :\n\tprint (1)\n\"") ;
4324 strcat(lDialogString,
");\n\
4325 if res is False :\n\tprint(0)\n\
4326 else :\n\tprint(1)\n\"") ;
4329 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"python2-tkinter");
return 1;}
4330 strcpy(lDialogString,
"export PYTHONIOENCODING=utf-8;") ;
4333 strcat(lDialogString,
" -i") ;
4336 strcat(lDialogString,
4337 " -S -c \"import Tkinter,tkMessageBox;root=Tkinter.Tk();root.withdraw();");
4340 strcat(lDialogString,
4341 "import os;os.system('''/usr/bin/osascript -e 'tell app \\\"Finder\\\" to set \
4342 frontmost of process \\\"Python\\\" to true' ''');");
4345 strcat(lDialogString,
"res=tkMessageBox.") ;
4346 if (aDialogType && ! strcmp(
"okcancel", aDialogType)) {
4347 strcat(lDialogString,
"askokcancel(") ;
4348 if (aDefaultButton) {
4349 strcat(lDialogString,
"default=tkMessageBox.OK,") ;
4351 strcat(lDialogString,
"default=tkMessageBox.CANCEL,") ;
4353 }
else if (aDialogType && ! strcmp(
"yesno", aDialogType)) {
4354 strcat(lDialogString,
"askyesno(") ;
4355 if (aDefaultButton) {
4356 strcat(lDialogString,
"default=tkMessageBox.YES,") ;
4358 strcat(lDialogString,
"default=tkMessageBox.NO,") ;
4360 }
else if (aDialogType && ! strcmp(
"yesnocancel", aDialogType)) {
4361 strcat(lDialogString,
"askyesnocancel(") ;
4362 switch (aDefaultButton) {
4363 case 1: strcat(lDialogString,
"default=tkMessageBox.YES,");
break;
4364 case 2: strcat(lDialogString,
"default=tkMessageBox.NO,");
break;
4365 case 0: strcat(lDialogString,
"default=tkMessageBox.CANCEL,");
break;
4368 strcat(lDialogString,
"showinfo(") ;
4371 strcat(lDialogString,
"icon='") ;
4372 if (aIconType && (! strcmp(
"question", aIconType)
4373 || ! strcmp(
"error", aIconType)
4374 || ! strcmp(
"warning", aIconType))) {
4375 strcat(lDialogString, aIconType) ;
4377 strcat(lDialogString,
"info") ;
4380 strcat(lDialogString,
"',") ;
4381 if (aTitle && strlen(aTitle)) {
4382 strcat(lDialogString,
"title='") ;
4383 strcat(lDialogString, aTitle) ;
4384 strcat(lDialogString,
"',") ;
4386 if (aMessage && strlen(aMessage)) {
4387 strcat(lDialogString,
"message='") ;
4388 lpDialogString = lDialogString + strlen(lDialogString);
4390 strcat(lDialogString,
"'") ;
4393 if (aDialogType && ! strcmp(
"yesnocancel", aDialogType)) {
4394 strcat(lDialogString,
");\n\
4395 if res is None :\n\tprint 0\n\
4396 elif res is False :\n\tprint 2\n\
4397 else :\n\tprint 1\n\"") ;
4399 strcat(lDialogString,
");\n\
4400 if res is False :\n\tprint 0\n\
4401 else :\n\tprint 1\n\"") ;
4405 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"gxmessage");
return 1;}
4406 strcpy(lDialogString,
"gxmessage");
4408 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"gmessage");
return 1;}
4409 strcpy(lDialogString,
"gmessage");
4411 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"xmessage");
return 1;}
4412 strcpy(lDialogString,
"xmessage");
4415 if (aDialogType && ! strcmp(
"okcancel", aDialogType)) {
4416 strcat(lDialogString,
" -buttons Ok:1,Cancel:0");
4417 switch (aDefaultButton) {
4418 case 1: strcat(lDialogString,
" -default Ok");
break;
4419 case 0: strcat(lDialogString,
" -default Cancel");
break;
4421 }
else if (aDialogType && ! strcmp(
"yesno", aDialogType)) {
4422 strcat(lDialogString,
" -buttons Yes:1,No:0");
4423 switch (aDefaultButton) {
4424 case 1: strcat(lDialogString,
" -default Yes");
break;
4425 case 0: strcat(lDialogString,
" -default No");
break;
4427 }
else if (aDialogType && ! strcmp(
"yesnocancel", aDialogType)) {
4428 strcat(lDialogString,
" -buttons Yes:1,No:2,Cancel:0");
4429 switch (aDefaultButton) {
4430 case 1: strcat(lDialogString,
" -default Yes");
break;
4431 case 2: strcat(lDialogString,
" -default No");
break;
4432 case 0: strcat(lDialogString,
" -default Cancel");
break;
4435 strcat(lDialogString,
" -buttons Ok:1");
4436 strcat(lDialogString,
" -default Ok");
4439 strcat(lDialogString,
" -center \"");
4440 if (aMessage && strlen(aMessage)) {
4441 strcat(lDialogString, aMessage) ;
4443 strcat(lDialogString,
"\"") ;
4444 if (aTitle && strlen(aTitle)) {
4445 strcat(lDialogString,
" -title \"");
4446 strcat(lDialogString, aTitle) ;
4447 strcat(lDialogString,
"\"") ;
4449 strcat(lDialogString,
" ; echo $? ");
4452 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"gdialog");
return 1;}
4453 lWasGraphicDialog = 1 ;
4454 strcpy(lDialogString,
"(gdialog ") ;
4456 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"xdialog");
return 1;}
4457 lWasGraphicDialog = 1 ;
4458 strcpy(lDialogString,
"(Xdialog ") ;
4460 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"dialog");
return 0;}
4462 strcpy(lDialogString,
"(dialog ") ;
4466 strcat(lDialogString,
"'(") ;
4468 strcat(lDialogString,
" ") ;
4471 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"whiptail");
return 0;}
4472 strcpy(lDialogString,
"(whiptail ") ;
4474 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"whiptail");
return 0;}
4477 strcat(lDialogString,
"'(whiptail ") ;
4480 if (aTitle && strlen(aTitle)) {
4481 strcat(lDialogString,
"--title \"") ;
4482 strcat(lDialogString, aTitle) ;
4483 strcat(lDialogString,
"\" ") ;
4487 if (aDialogType && (!strcmp(
"okcancel", aDialogType) || !strcmp(
"yesno", aDialogType)
4488 || !strcmp(
"yesnocancel", aDialogType))) {
4489 strcat(lDialogString,
"--backtitle \"") ;
4490 strcat(lDialogString,
"tab: move focus") ;
4491 strcat(lDialogString,
"\" ") ;
4495 if (aDialogType && ! strcmp(
"okcancel", aDialogType)) {
4496 if (! aDefaultButton) {
4497 strcat(lDialogString,
"--defaultno ") ;
4499 strcat(lDialogString,
4500 "--yes-label \"Ok\" --no-label \"Cancel\" --yesno ") ;
4501 }
else if (aDialogType && ! strcmp(
"yesno", aDialogType)) {
4502 if (! aDefaultButton) {
4503 strcat(lDialogString,
"--defaultno ") ;
4505 strcat(lDialogString,
"--yesno ") ;
4506 }
else if (aDialogType && !strcmp(
"yesnocancel", aDialogType)) {
4507 if (!aDefaultButton) {
4508 strcat(lDialogString,
"--defaultno ");
4510 strcat(lDialogString,
"--menu ");
4512 strcat(lDialogString,
"--msgbox ") ;
4515 strcat(lDialogString,
"\"") ;
4516 if (aMessage && strlen(aMessage)) {
4517 strcat(lDialogString, aMessage) ;
4519 strcat(lDialogString,
"\" ");
4521 if (lWasGraphicDialog) {
4522 if (aDialogType && !strcmp(
"yesnocancel", aDialogType)) {
4523 strcat(lDialogString,
"0 60 0 Yes \"\" No \"\") 2>/tmp/tinyfd.txt;\
4524 if [ $? = 0 ];then tinyfdBool=1;else tinyfdBool=0;fi;\
4525 tinyfdRes=$(cat /tmp/tinyfd.txt);echo $tinyfdBool$tinyfdRes") ;
4527 strcat(lDialogString,
4528 "10 60 ) 2>&1;if [ $? = 0 ];then echo 1;else echo 0;fi");
4531 if (aDialogType && !strcmp(
"yesnocancel", aDialogType)) {
4532 strcat(lDialogString,
"0 60 0 Yes \"\" No \"\" >/dev/tty ) 2>/tmp/tinyfd.txt;\
4533 if [ $? = 0 ];then tinyfdBool=1;else tinyfdBool=0;fi;\
4534 tinyfdRes=$(cat /tmp/tinyfd.txt);echo $tinyfdBool$tinyfdRes") ;
4537 strcat(lDialogString,
" >/tmp/tinyfd0.txt';cat /tmp/tinyfd0.txt");
4539 strcat(lDialogString,
"; clear >/dev/tty") ;
4542 strcat(lDialogString,
"10 60 >/dev/tty) 2>&1;if [ $? = 0 ];");
4544 strcat(lDialogString,
4545 "then\n\techo 1\nelse\n\techo 0\nfi >/tmp/tinyfd.txt';cat /tmp/tinyfd.txt;rm /tmp/tinyfd.txt");
4547 strcat(lDialogString,
4548 "then echo 1;else echo 0;fi;clear >/dev/tty");
4553 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"basicinput");
return 0;}
4555 strcat(lDialogString,
"'") ;
4558 strcat(lDialogString,
"echo \"") ;
4559 strcat(lDialogString,
gTitle) ;
4560 strcat(lDialogString,
"\";") ;
4561 strcat(lDialogString,
"echo \"") ;
4563 strcat(lDialogString,
"\";echo;echo;") ;
4565 if (aTitle && strlen(aTitle)) {
4566 strcat(lDialogString,
"echo \"") ;
4567 strcat(lDialogString, aTitle) ;
4568 strcat(lDialogString,
"\";echo;") ;
4570 if (aMessage && strlen(aMessage)) {
4571 strcat(lDialogString,
"echo \"") ;
4572 strcat(lDialogString, aMessage) ;
4573 strcat(lDialogString,
"\"; ") ;
4575 if (aDialogType && !strcmp(
"yesno", aDialogType)) {
4576 strcat(lDialogString,
"echo -n \"y/n: \"; ") ;
4577 strcat(lDialogString,
"stty sane -echo;") ;
4578 strcat(lDialogString,
4579 "answer=$( while ! head -c 1 | grep -i [ny];do true ;done);");
4580 strcat(lDialogString,
4581 "if echo \"$answer\" | grep -iq \"^y\";then\n");
4582 strcat(lDialogString,
"\techo 1\nelse\n\techo 0\nfi") ;
4583 }
else if (aDialogType && !strcmp(
"okcancel", aDialogType)) {
4584 strcat(lDialogString,
"echo -n \"[O]kay/[C]ancel: \"; ") ;
4585 strcat(lDialogString,
"stty sane -echo;") ;
4586 strcat(lDialogString,
4587 "answer=$( while ! head -c 1 | grep -i [oc];do true ;done);");
4588 strcat(lDialogString,
4589 "if echo \"$answer\" | grep -iq \"^o\";then\n");
4590 strcat(lDialogString,
"\techo 1\nelse\n\techo 0\nfi") ;
4591 }
else if (aDialogType && !strcmp(
"yesnocancel", aDialogType)) {
4592 strcat(lDialogString,
"echo -n \"[Y]es/[N]o/[C]ancel: \"; ") ;
4593 strcat(lDialogString,
"stty sane -echo;") ;
4594 strcat(lDialogString,
4595 "answer=$( while ! head -c 1 | grep -i [nyc];do true ;done);");
4596 strcat(lDialogString,
4597 "if echo \"$answer\" | grep -iq \"^y\";then\n\techo 1\n");
4598 strcat(lDialogString,
"elif echo \"$answer\" | grep -iq \"^n\";then\n\techo 2\n") ;
4599 strcat(lDialogString,
"else\n\techo 0\nfi") ;
4601 strcat(lDialogString,
"echo -n \"press enter to continue \"; ");
4602 strcat(lDialogString,
"stty sane -echo;") ;
4603 strcat(lDialogString,
4604 "answer=$( while ! head -c 1;do true ;done);echo 1");
4606 strcat(lDialogString,
4607 " >/tmp/tinyfd.txt';cat /tmp/tinyfd.txt;rm /tmp/tinyfd.txt");
4609 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"python-dbus");
return 1;}
4611 strcat(lDialogString,
" -c \"import dbus;bus=dbus.SessionBus();");
4612 strcat(lDialogString,
"notif=bus.get_object('org.freedesktop.Notifications','/org/freedesktop/Notifications');") ;
4613 strcat(lDialogString,
"notify=dbus.Interface(notif,'org.freedesktop.Notifications');") ;
4614 strcat(lDialogString,
"notify.Notify('',0,'") ;
4615 if (aIconType && strlen(aIconType)) {
4616 strcat(lDialogString, aIconType) ;
4618 strcat(lDialogString,
"','") ;
4619 if (aTitle && strlen(aTitle)) {
4620 strcat(lDialogString, aTitle) ;
4622 strcat(lDialogString,
"','") ;
4623 if (aMessage && strlen(aMessage)) {
4624 lpDialogString = lDialogString + strlen(lDialogString);
4627 strcat(lDialogString,
"','','',5000)\"") ;
4629 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"perl-dbus");
return 1;}
4631 strcpy(lDialogString,
"perl -e \"use Net::DBus;\
4632 my \\$sessionBus = Net::DBus->session;\
4633 my \\$notificationsService = \\$sessionBus->get_service('org.freedesktop.Notifications');\
4634 my \\$notificationsObject = \\$notificationsService->get_object('/org/freedesktop/Notifications',\
4635 'org.freedesktop.Notifications');");
4637 sprintf(lDialogString + strlen(lDialogString),
4638 "my \\$notificationId;\\$notificationId = \\$notificationsObject->Notify(shift, 0, '%s', '%s', '%s', [], {}, -1);\" ",
4639 aIconType ? aIconType :
"", aTitle ? aTitle :
"", aMessage ? aMessage :
"") ;
4642 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"notifysend");
return 1;}
4643 strcpy(lDialogString,
"notify-send") ;
4644 if (aIconType && strlen(aIconType)) {
4645 strcat(lDialogString,
" -i '") ;
4646 strcat(lDialogString, aIconType) ;
4647 strcat(lDialogString,
"'") ;
4649 strcat(lDialogString,
" \"") ;
4650 if (aTitle && strlen(aTitle)) {
4651 strcat(lDialogString, aTitle) ;
4652 strcat(lDialogString,
" | ") ;
4654 if (aMessage && strlen(aMessage)) {
4658 strcat(lDialogString, lBuff) ;
4660 strcat(lDialogString,
"\"") ;
4662 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"basicinput");
return 0;}
4665 printf(
"\n\n%s\n",
gTitle);
4668 if (aTitle && strlen(aTitle)) {
4669 printf(
"\n%s\n", aTitle);
4672 tcgetattr(0, &infoOri);
4673 tcgetattr(0, &info);
4674 info.c_lflag &= ~ICANON;
4675 info.c_cc[VMIN] = 1;
4676 info.c_cc[VTIME] = 0;
4677 tcsetattr(0, TCSANOW, &info);
4678 if (aDialogType && !strcmp(
"yesno", aDialogType)) {
4680 if (aMessage && strlen(aMessage)) {
4681 printf(
"\n%s\n", aMessage);
4683 printf(
"y/n: "); fflush(stdout);
4684 lChar = tolower(getchar()) ;
4686 }
while (lChar !=
'y' && lChar !=
'n');
4687 lResult = lChar ==
'y' ? 1 : 0 ;
4688 }
else if (aDialogType && !strcmp(
"okcancel", aDialogType)) {
4690 if (aMessage && strlen(aMessage)) {
4691 printf(
"\n%s\n", aMessage);
4693 printf(
"[O]kay/[C]ancel: "); fflush(stdout);
4694 lChar = tolower(getchar()) ;
4696 }
while (lChar !=
'o' && lChar !=
'c');
4697 lResult = lChar ==
'o' ? 1 : 0 ;
4698 }
else if (aDialogType && !strcmp(
"yesnocancel", aDialogType)) {
4700 if (aMessage && strlen(aMessage)) {
4701 printf(
"\n%s\n", aMessage);
4703 printf(
"[Y]es/[N]o/[C]ancel: "); fflush(stdout);
4704 lChar = tolower(getchar()) ;
4706 }
while (lChar !=
'y' && lChar !=
'n' && lChar !=
'c');
4707 lResult = (lChar ==
'y') ? 1 : (lChar ==
'n') ? 2 : 0 ;
4709 if (aMessage && strlen(aMessage)) {
4710 printf(
"\n%s\n\n", aMessage);
4712 printf(
"press enter to continue "); fflush(stdout);
4717 tcsetattr(0, TCSANOW, &infoOri);
4718 free(lDialogString);
4722 if (
tinyfd_verbose) { printf(
"lDialogString: %s\n", lDialogString) ; }
4724 if (!(lIn = popen(lDialogString,
"r"))) {
4725 free(lDialogString);
4728 while (fgets(lBuff,
sizeof(lBuff), lIn) != NULL)
4734 if (lBuff[strlen(lBuff) - 1] ==
'\n') {
4735 lBuff[strlen(lBuff) - 1] =
'\0' ;
4739 if (aDialogType && !strcmp(
"yesnocancel", aDialogType)) {
4740 if (lBuff[0] ==
'1') {
4741 if (!strcmp(lBuff + 1,
"Yes")) { strcpy(lBuff,
"1"); }
4742 else if (!strcmp(lBuff + 1,
"No")) { strcpy(lBuff,
"2"); }
4747 lResult = !strcmp(lBuff,
"2") ? 2 : !strcmp(lBuff,
"1") ? 1 : 0;
4750 free(lDialogString);
4758 char const *aMessage,
4759 char const *aIconType)
4762 char *lDialogString = NULL ;
4763 char *lpDialogString ;
4766 size_t lMessageLen ;
4771 if (getenv(
"SSH_TTY")) {
4775 lTitleLen = aTitle ? strlen(aTitle) : 0 ;
4776 lMessageLen = aMessage ? strlen(aMessage) : 0 ;
4777 if (!aTitle || strcmp(aTitle,
"tinyfd_query")) {
4778 lDialogString = (
char *) malloc(
MAX_PATH_OR_CMD + lTitleLen + lMessageLen);
4782 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"applescript");
return 1;}
4784 strcpy(lDialogString,
"osascript ");
4785 if (!
osx9orBetter()) { strcat(lDialogString,
" -e 'tell application \"System Events\"' -e 'Activate'"); }
4786 strcat(lDialogString,
" -e 'try' -e 'display notification \"") ;
4787 if (aMessage && strlen(aMessage)) {
4788 strcat(lDialogString, aMessage) ;
4790 strcat(lDialogString,
" \" ") ;
4791 if (aTitle && strlen(aTitle)) {
4792 strcat(lDialogString,
"with title \"") ;
4793 strcat(lDialogString, aTitle) ;
4794 strcat(lDialogString,
"\" ") ;
4797 strcat(lDialogString,
"' -e 'end try'") ;
4798 if (!
osx9orBetter()) { strcat(lDialogString,
" -e 'end tell'") ; }
4800 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"kdialog");
return 1;}
4801 strcpy(lDialogString,
"kdialog") ;
4803 if (aIconType && strlen(aIconType)) {
4804 strcat(lDialogString,
" --icon '") ;
4805 strcat(lDialogString, aIconType) ;
4806 strcat(lDialogString,
"'") ;
4808 if (aTitle && strlen(aTitle)) {
4809 strcat(lDialogString,
" --title \"") ;
4810 strcat(lDialogString, aTitle) ;
4811 strcat(lDialogString,
"\"") ;
4814 strcat(lDialogString,
" --passivepopup") ;
4815 strcat(lDialogString,
" \"") ;
4817 strcat(lDialogString, aMessage) ;
4819 strcat(lDialogString,
" \" 5") ;
4824 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"zenity");
return 1;}
4825 strcpy(lDialogString,
"zenity") ;
4828 strcat(lDialogString,
" --notification");
4830 if (aIconType && strlen(aIconType)) {
4831 strcat(lDialogString,
" --window-icon '");
4832 strcat(lDialogString, aIconType) ;
4833 strcat(lDialogString,
"'") ;
4836 strcat(lDialogString,
" --text \"") ;
4837 if (aTitle && strlen(aTitle)) {
4838 strcat(lDialogString, aTitle) ;
4839 strcat(lDialogString,
"\n") ;
4841 if (aMessage && strlen(aMessage)) {
4842 strcat(lDialogString, aMessage) ;
4844 strcat(lDialogString,
" \"") ;
4846 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"perl-dbus");
return 1;}
4848 strcpy(lDialogString,
"perl -e \"use Net::DBus;\
4849 my \\$sessionBus = Net::DBus->session;\
4850 my \\$notificationsService = \\$sessionBus->get_service('org.freedesktop.Notifications');\
4851 my \\$notificationsObject = \\$notificationsService->get_object('/org/freedesktop/Notifications',\
4852 'org.freedesktop.Notifications');");
4854 sprintf(lDialogString + strlen(lDialogString),
4855 "my \\$notificationId;\\$notificationId = \\$notificationsObject->Notify(shift, 0, '%s', '%s', '%s', [], {}, -1);\" ",
4856 aIconType ? aIconType :
"", aTitle ? aTitle :
"", aMessage ? aMessage :
"") ;
4858 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"python-dbus");
return 1;}
4860 strcat(lDialogString,
" -c \"import dbus;bus=dbus.SessionBus();");
4861 strcat(lDialogString,
"notif=bus.get_object('org.freedesktop.Notifications','/org/freedesktop/Notifications');") ;
4862 strcat(lDialogString,
"notify=dbus.Interface(notif,'org.freedesktop.Notifications');") ;
4863 strcat(lDialogString,
"notify.Notify('',0,'") ;
4864 if (aIconType && strlen(aIconType)) {
4865 strcat(lDialogString, aIconType) ;
4867 strcat(lDialogString,
"','") ;
4868 if (aTitle && strlen(aTitle)) {
4869 strcat(lDialogString, aTitle) ;
4871 strcat(lDialogString,
"','") ;
4872 if (aMessage && strlen(aMessage)) {
4873 lpDialogString = lDialogString + strlen(lDialogString);
4876 strcat(lDialogString,
"','','',5000)\"") ;
4878 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"notifysend");
return 1;}
4879 strcpy(lDialogString,
"notify-send") ;
4880 if (aIconType && strlen(aIconType)) {
4881 strcat(lDialogString,
" -i '") ;
4882 strcat(lDialogString, aIconType) ;
4883 strcat(lDialogString,
"'") ;
4885 strcat(lDialogString,
" \"") ;
4886 if (aTitle && strlen(aTitle)) {
4887 strcat(lDialogString, aTitle) ;
4888 strcat(lDialogString,
" | ") ;
4890 if (aMessage && strlen(aMessage)) {
4894 strcat(lDialogString, lBuff) ;
4896 strcat(lDialogString,
"\"") ;
4901 if (
tinyfd_verbose) { printf(
"lDialogString: %s\n", lDialogString) ; }
4903 if (!(lIn = popen(lDialogString,
"r"))) {
4904 free(lDialogString);
4909 free(lDialogString);
4917 char const *aMessage,
4918 char const *aDefaultInput)
4921 char *lDialogString = NULL;
4922 char *lpDialogString;
4925 int lWasGdialog = 0 ;
4926 int lWasGraphicDialog = 0 ;
4928 int lWasBasicXterm = 0 ;
4929 struct termios oldt ;
4930 struct termios newt ;
4933 size_t lMessageLen ;
4935 if (!aTitle && !aMessage && !aDefaultInput) {
return lBuff; }
4943 lTitleLen = aTitle ? strlen(aTitle) : 0 ;
4944 lMessageLen = aMessage ? strlen(aMessage) : 0 ;
4945 if (!aTitle || strcmp(aTitle,
"tinyfd_query")) {
4946 lDialogString = (
char *) malloc(
MAX_PATH_OR_CMD + lTitleLen + lMessageLen);
4950 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"applescript");
return (
char *)1;}
4951 strcpy(lDialogString,
"osascript ");
4952 if (!
osx9orBetter()) { strcat(lDialogString,
" -e 'tell application \"System Events\"' -e 'Activate'"); }
4953 strcat(lDialogString,
" -e 'try' -e 'display dialog \"") ;
4954 if (aMessage && strlen(aMessage)) {
4955 strcat(lDialogString, aMessage) ;
4957 strcat(lDialogString,
"\" ") ;
4958 strcat(lDialogString,
"default answer \"") ;
4959 if (aDefaultInput && strlen(aDefaultInput)) {
4960 strcat(lDialogString, aDefaultInput) ;
4962 strcat(lDialogString,
"\" ") ;
4963 if (! aDefaultInput) {
4964 strcat(lDialogString,
"hidden answer true ") ;
4966 if (aTitle && strlen(aTitle)) {
4967 strcat(lDialogString,
"with title \"") ;
4968 strcat(lDialogString, aTitle) ;
4969 strcat(lDialogString,
"\" ") ;
4971 strcat(lDialogString,
"with icon note' ") ;
4972 strcat(lDialogString,
"-e '\"1\" & text returned of result' ");
4973 strcat(lDialogString,
"-e 'on error number -128' ") ;
4974 strcat(lDialogString,
"-e '0' ");
4975 strcat(lDialogString,
"-e 'end try'") ;
4976 if (!
osx9orBetter()) { strcat(lDialogString,
" -e 'end tell'") ; }
4978 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"kdialog");
return (
char *)1;}
4979 strcpy(lDialogString,
"szAnswer=$(kdialog") ;
4982 strcat(lDialogString,
" --attach=$(xprop -root 32x '\t$0' _NET_ACTIVE_WINDOW | cut -f 2)");
4985 if (! aDefaultInput) {
4986 strcat(lDialogString,
" --password ") ;
4988 strcat(lDialogString,
" --inputbox ") ;
4991 strcat(lDialogString,
"\"") ;
4992 if (aMessage && strlen(aMessage)) {
4993 strcat(lDialogString, aMessage) ;
4995 strcat(lDialogString,
"\" \"") ;
4996 if (aDefaultInput && strlen(aDefaultInput)) {
4997 strcat(lDialogString, aDefaultInput) ;
4999 strcat(lDialogString,
"\"") ;
5000 if (aTitle && strlen(aTitle)) {
5001 strcat(lDialogString,
" --title \"") ;
5002 strcat(lDialogString, aTitle) ;
5003 strcat(lDialogString,
"\"") ;
5005 strcat(lDialogString,
5006 ");if [ $? = 0 ];then echo 1$szAnswer;else echo 0$szAnswer;fi");
5009 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"zenity");
return (
char *)1;}
5010 strcpy(lDialogString,
"szAnswer=$(zenity") ;
5012 strcat(lDialogString,
" --attach=$(sleep .01;xprop -root 32x '\t$0' _NET_ACTIVE_WINDOW | cut -f 2)");
5015 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"matedialog");
return (
char *)1;}
5016 strcpy(lDialogString,
"szAnswer=$(matedialog") ;
5018 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"shellementary");
return (
char *)1;}
5019 strcpy(lDialogString,
"szAnswer=$(shellementary") ;
5021 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"qarma");
return (
char *)1;}
5022 strcpy(lDialogString,
"szAnswer=$(qarma") ;
5024 strcat(lDialogString,
" --attach=$(xprop -root 32x '\t$0' _NET_ACTIVE_WINDOW | cut -f 2)");
5027 strcat(lDialogString,
" --entry") ;
5029 if (aTitle && strlen(aTitle)) {
5030 strcat(lDialogString,
" --title=\"") ;
5031 strcat(lDialogString, aTitle) ;
5032 strcat(lDialogString,
"\"") ;
5034 if (aMessage && strlen(aMessage)) {
5035 strcat(lDialogString,
" --text=\"") ;
5036 strcat(lDialogString, aMessage) ;
5037 strcat(lDialogString,
"\"") ;
5039 if (aDefaultInput && strlen(aDefaultInput)) {
5040 strcat(lDialogString,
" --entry-text=\"") ;
5041 strcat(lDialogString, aDefaultInput) ;
5042 strcat(lDialogString,
"\"") ;
5044 strcat(lDialogString,
" --hide-text") ;
5046 if (
tinyfd_silent) { strcat(lDialogString,
" 2>/dev/null "); }
5047 strcat(lDialogString,
5048 ");if [ $? = 0 ];then echo 1$szAnswer;else echo 0$szAnswer;fi");
5050 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) { strcpy(
tinyfd_response,
"yad");
return (
char *)1; }
5051 strcpy(lDialogString,
"szAnswer=$(yad --entry");
5052 if (aTitle && strlen(aTitle)) {
5053 strcat(lDialogString,
" --title=\"");
5054 strcat(lDialogString, aTitle);
5055 strcat(lDialogString,
"\"");
5057 if (aMessage && strlen(aMessage)) {
5058 strcat(lDialogString,
" --text=\"");
5059 strcat(lDialogString, aMessage);
5060 strcat(lDialogString,
"\"");
5062 if (aDefaultInput && strlen(aDefaultInput)) {
5063 strcat(lDialogString,
" --entry-text=\"");
5064 strcat(lDialogString, aDefaultInput);
5065 strcat(lDialogString,
"\"");
5067 strcat(lDialogString,
" --hide-text");
5069 if (
tinyfd_silent) { strcat(lDialogString,
" 2>/dev/null "); }
5070 strcat(lDialogString,
5071 ");if [ $? = 0 ];then echo 1$szAnswer;else echo 0$szAnswer;fi");
5074 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"gxmessage");
return (
char *)1;}
5075 strcpy(lDialogString,
"szAnswer=$(gxmessage -buttons Ok:1,Cancel:0 -center \"");
5077 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"gmessage");
return (
char *)1;}
5078 strcpy(lDialogString,
"szAnswer=$(gmessage -buttons Ok:1,Cancel:0 -center \"");
5081 if (aMessage && strlen(aMessage)) {
5082 strcat(lDialogString, aMessage) ;
5084 strcat(lDialogString,
"\"") ;
5085 if (aTitle && strlen(aTitle)) {
5086 strcat(lDialogString,
" -title \"");
5087 strcat(lDialogString, aTitle) ;
5088 strcat(lDialogString,
"\" ") ;
5090 strcat(lDialogString,
" -entrytext \"") ;
5091 if (aDefaultInput && strlen(aDefaultInput)) {
5092 strcat(lDialogString, aDefaultInput) ;
5094 strcat(lDialogString,
"\"") ;
5095 strcat(lDialogString,
");echo $?$szAnswer");
5097 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"python3-tkinter");
return (
char *)1;}
5099 strcat(lDialogString,
5100 " -S -c \"import tkinter; from tkinter import simpledialog;root=tkinter.Tk();root.withdraw();");
5101 strcat(lDialogString,
"res=simpledialog.askstring(") ;
5102 if (aTitle && strlen(aTitle)) {
5103 strcat(lDialogString,
"title='") ;
5104 strcat(lDialogString, aTitle) ;
5105 strcat(lDialogString,
"',") ;
5107 if (aMessage && strlen(aMessage)) {
5109 strcat(lDialogString,
"prompt='") ;
5110 lpDialogString = lDialogString + strlen(lDialogString);
5112 strcat(lDialogString,
"',") ;
5114 if (aDefaultInput) {
5115 if (strlen(aDefaultInput)) {
5116 strcat(lDialogString,
"initialvalue='") ;
5117 strcat(lDialogString, aDefaultInput) ;
5118 strcat(lDialogString,
"',") ;
5121 strcat(lDialogString,
"show='*'") ;
5123 strcat(lDialogString,
");\nif res is None :\n\tprint(0)");
5124 strcat(lDialogString,
"\nelse :\n\tprint('1'+res)\n\"") ;
5126 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"python2-tkinter");
return (
char *)1;}
5127 strcpy(lDialogString,
"export PYTHONIOENCODING=utf-8;") ;
5130 strcat(lDialogString,
" -i") ;
5133 strcat(lDialogString,
5134 " -S -c \"import Tkinter,tkSimpleDialog;root=Tkinter.Tk();root.withdraw();");
5137 strcat(lDialogString,
5138 "import os;os.system('''/usr/bin/osascript -e 'tell app \\\"Finder\\\" to set \
5139 frontmost of process \\\"Python\\\" to true' ''');");
5142 strcat(lDialogString,
"res=tkSimpleDialog.askstring(") ;
5143 if (aTitle && strlen(aTitle)) {
5144 strcat(lDialogString,
"title='") ;
5145 strcat(lDialogString, aTitle) ;
5146 strcat(lDialogString,
"',") ;
5148 if (aMessage && strlen(aMessage)) {
5150 strcat(lDialogString,
"prompt='") ;
5151 lpDialogString = lDialogString + strlen(lDialogString);
5153 strcat(lDialogString,
"',") ;
5155 if (aDefaultInput) {
5156 if (strlen(aDefaultInput)) {
5157 strcat(lDialogString,
"initialvalue='") ;
5158 strcat(lDialogString, aDefaultInput) ;
5159 strcat(lDialogString,
"',") ;
5162 strcat(lDialogString,
"show='*'") ;
5164 strcat(lDialogString,
");\nif res is None :\n\tprint 0");
5165 strcat(lDialogString,
"\nelse :\n\tprint '1'+res\n\"") ;
5168 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"gdialog");
return (
char *)1;}
5169 lWasGraphicDialog = 1 ;
5171 strcpy(lDialogString,
"(gdialog ") ;
5173 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"xdialog");
return (
char *)1;}
5174 lWasGraphicDialog = 1 ;
5175 strcpy(lDialogString,
"(Xdialog ") ;
5177 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"dialog");
return (
char *)0;}
5179 strcpy(lDialogString,
"(dialog ") ;
5183 strcat(lDialogString,
"'(") ;
5185 strcat(lDialogString,
" ") ;
5188 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"whiptail");
return (
char *)0;}
5189 strcpy(lDialogString,
"(whiptail ") ;
5191 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"whiptail");
return (
char *)0;}
5194 strcat(lDialogString,
"'(whiptail ") ;
5197 if (aTitle && strlen(aTitle)) {
5198 strcat(lDialogString,
"--title \"") ;
5199 strcat(lDialogString, aTitle) ;
5200 strcat(lDialogString,
"\" ") ;
5204 strcat(lDialogString,
"--backtitle \"") ;
5205 strcat(lDialogString,
"tab: move focus") ;
5206 if (! aDefaultInput && !lWasGdialog) {
5207 strcat(lDialogString,
" (sometimes nothing, no blink nor star, is shown in text field)") ;
5209 strcat(lDialogString,
"\" ") ;
5212 if (aDefaultInput || lWasGdialog) {
5213 strcat(lDialogString,
"--inputbox") ;
5216 strcat(lDialogString,
"--insecure ") ;
5218 strcat(lDialogString,
"--passwordbox") ;
5220 strcat(lDialogString,
" \"") ;
5221 if (aMessage && strlen(aMessage)) {
5222 strcat(lDialogString, aMessage) ;
5224 strcat(lDialogString,
"\" 10 60 ") ;
5225 if (aDefaultInput && strlen(aDefaultInput)) {
5226 strcat(lDialogString,
"\"") ;
5227 strcat(lDialogString, aDefaultInput) ;
5228 strcat(lDialogString,
"\" ") ;
5230 if (lWasGraphicDialog) {
5231 strcat(lDialogString,
") 2>/tmp/tinyfd.txt;\
5232 if [ $? = 0 ];then tinyfdBool=1;else tinyfdBool=0;fi;\
5233 tinyfdRes=$(cat /tmp/tinyfd.txt);echo $tinyfdBool$tinyfdRes") ;
5235 strcat(lDialogString,
">/dev/tty ) 2>/tmp/tinyfd.txt;\
5236 if [ $? = 0 ];then tinyfdBool=1;else tinyfdBool=0;fi;\
5237 tinyfdRes=$(cat /tmp/tinyfd.txt);echo $tinyfdBool$tinyfdRes") ;
5240 strcat(lDialogString,
" >/tmp/tinyfd0.txt';cat /tmp/tinyfd0.txt");
5242 strcat(lDialogString,
"; clear >/dev/tty") ;
5246 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"basicinput");
return (
char *)0;}
5247 lWasBasicXterm = 1 ;
5249 strcat(lDialogString,
"'") ;
5255 strcat(lDialogString,
"echo \"") ;
5256 strcat(lDialogString, aTitle) ;
5257 strcat(lDialogString,
"\";echo;") ;
5260 strcat(lDialogString,
"echo \"") ;
5261 if (aMessage && strlen(aMessage)) {
5262 strcat(lDialogString, aMessage) ;
5264 strcat(lDialogString,
"\";read ") ;
5265 if (! aDefaultInput) {
5266 strcat(lDialogString,
"-s ") ;
5268 strcat(lDialogString,
"-p \"") ;
5269 strcat(lDialogString,
"(esc+enter to cancel): \" ANSWER ") ;
5270 strcat(lDialogString,
";echo 1$ANSWER >/tmp/tinyfd.txt';") ;
5271 strcat(lDialogString,
"cat -v /tmp/tinyfd.txt");
5275 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"no_solution");
return (
char *)0;}
5276 free(lDialogString);
5279 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"basicinput");
return (
char *)0;}
5284 if (aTitle && strlen(aTitle)) {
5285 printf(
"\n%s\n", aTitle);
5287 if (aMessage && strlen(aMessage)) {
5288 printf(
"\n%s\n", aMessage);
5290 printf(
"(esc+enter to cancel): "); fflush(stdout);
5291 if (! aDefaultInput) {
5292 tcgetattr(STDIN_FILENO, & oldt) ;
5294 newt.c_lflag &= ~ECHO ;
5295 tcsetattr(STDIN_FILENO, TCSANOW, & newt);
5300 if (! lEOF || (lBuff[0] ==
'\0')) {
5301 free(lDialogString);
5305 if (lBuff[0] ==
'\n') {
5308 if (! lEOF || (lBuff[0] ==
'\0')) {
5309 free(lDialogString);
5314 if (! aDefaultInput) {
5315 tcsetattr(STDIN_FILENO, TCSANOW, & oldt);
5319 if (strchr(lBuff, 27)) {
5320 free(lDialogString);
5323 if (lBuff[strlen(lBuff) - 1] ==
'\n') {
5324 lBuff[strlen(lBuff) - 1] =
'\0' ;
5326 free(lDialogString);
5330 if (
tinyfd_verbose) { printf(
"lDialogString: %s\n", lDialogString) ; }
5331 lIn = popen(lDialogString,
"r");
5335 remove(
"/tmp/tinyfd.txt");
5339 remove(
"/tmp/tinyfd0.txt");
5341 free(lDialogString);
5344 while (fgets(lBuff,
sizeof(lBuff), lIn) != NULL)
5351 remove(
"/tmp/tinyfd.txt");
5355 remove(
"/tmp/tinyfd0.txt");
5360 if (lBuff[strlen(lBuff) - 1] ==
'\n') {
5361 lBuff[strlen(lBuff) - 1] =
'\0' ;
5364 if (lWasBasicXterm) {
5365 if (strstr(lBuff,
"^[")) {
5366 free(lDialogString);
5371 lResult = strncmp(lBuff,
"1", 1) ? 0 : 1 ;
5374 free(lDialogString);
5379 free(lDialogString);
5386 char const *aDefaultPathAndFile,
5387 int aNumOfFilterPatterns,
5388 char const *
const *aFilterPatterns,
5389 char const *aSingleFilterDescription)
5395 int lWasGraphicDialog = 0 ;
5398 char *lPointerInputBox ;
5403 if (
tfd_quoteDetected(aDefaultPathAndFile)) {
return tinyfd_saveFileDialog(aTitle,
"INVALID DEFAULT_PATH WITH QUOTES", aNumOfFilterPatterns, aFilterPatterns, aSingleFilterDescription); }
5404 if (
tfd_quoteDetected(aSingleFilterDescription)) {
return tinyfd_saveFileDialog(aTitle, aDefaultPathAndFile, aNumOfFilterPatterns, aFilterPatterns,
"INVALID FILTER_DESCRIPTION WITH QUOTES"); }
5405 for (i = 0; i < aNumOfFilterPatterns; i++) {
5410 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"applescript");
return (
char *)1;}
5411 strcpy(lDialogString,
"osascript ");
5412 if (!
osx9orBetter()) { strcat(lDialogString,
" -e 'tell application \"Finder\"' -e 'Activate'"); }
5413 strcat(lDialogString,
" -e 'try' -e 'POSIX path of ( choose file name ");
5414 if (aTitle && strlen(aTitle)) {
5415 strcat(lDialogString,
"with prompt \"") ;
5416 strcat(lDialogString, aTitle) ;
5417 strcat(lDialogString,
"\" ") ;
5420 if (strlen(lString)) {
5421 strcat(lDialogString,
"default location \"") ;
5422 strcat(lDialogString, lString) ;
5423 strcat(lDialogString,
"\" ") ;
5426 if (strlen(lString)) {
5427 strcat(lDialogString,
"default name \"") ;
5428 strcat(lDialogString, lString) ;
5429 strcat(lDialogString,
"\" ") ;
5431 strcat(lDialogString,
")' ") ;
5432 strcat(lDialogString,
"-e 'on error number -128' ") ;
5433 strcat(lDialogString,
"-e 'end try'") ;
5434 if (!
osx9orBetter()) { strcat(lDialogString,
" -e 'end tell'") ; }
5436 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"kdialog");
return (
char *)1;}
5438 strcpy(lDialogString,
"kdialog") ;
5440 strcat(lDialogString,
" --attach=$(xprop -root 32x '\t$0' _NET_ACTIVE_WINDOW | cut -f 2)");
5442 strcat(lDialogString,
" --getsavefilename ") ;
5444 if (aDefaultPathAndFile && strlen(aDefaultPathAndFile)) {
5445 if (aDefaultPathAndFile[0] !=
'/') {
5446 strcat(lDialogString,
"$PWD/") ;
5448 strcat(lDialogString,
"\"") ;
5449 strcat(lDialogString, aDefaultPathAndFile) ;
5450 strcat(lDialogString,
"\"") ;
5452 strcat(lDialogString,
"$PWD/") ;
5455 if (aNumOfFilterPatterns > 0) {
5456 strcat(lDialogString,
" \"") ;
5457 strcat(lDialogString, aFilterPatterns[0]) ;
5458 for (i = 1 ; i < aNumOfFilterPatterns ; i ++) {
5459 strcat(lDialogString,
" ") ;
5460 strcat(lDialogString, aFilterPatterns[i]) ;
5462 if (aSingleFilterDescription && strlen(aSingleFilterDescription)) {
5463 strcat(lDialogString,
" | ") ;
5464 strcat(lDialogString, aSingleFilterDescription) ;
5466 strcat(lDialogString,
"\"") ;
5468 if (aTitle && strlen(aTitle)) {
5469 strcat(lDialogString,
" --title \"") ;
5470 strcat(lDialogString, aTitle) ;
5471 strcat(lDialogString,
"\"") ;
5475 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"zenity");
return (
char *)1;}
5476 strcpy(lDialogString,
"zenity") ;
5478 strcat(lDialogString,
" --attach=$(sleep .01;xprop -root 32x '\t$0' _NET_ACTIVE_WINDOW | cut -f 2)");
5481 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"matedialog");
return (
char *)1;}
5482 strcpy(lDialogString,
"matedialog") ;
5484 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"shellementary");
return (
char *)1;}
5485 strcpy(lDialogString,
"shellementary") ;
5487 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"qarma");
return (
char *)1;}
5488 strcpy(lDialogString,
"qarma") ;
5490 strcat(lDialogString,
" --attach=$(xprop -root 32x '\t$0' _NET_ACTIVE_WINDOW | cut -f 2)");
5493 strcat(lDialogString,
" --file-selection --save --confirm-overwrite") ;
5495 if (aTitle && strlen(aTitle)) {
5496 strcat(lDialogString,
" --title=\"") ;
5497 strcat(lDialogString, aTitle) ;
5498 strcat(lDialogString,
"\"") ;
5500 if (aDefaultPathAndFile && strlen(aDefaultPathAndFile)) {
5501 strcat(lDialogString,
" --filename=\"") ;
5502 strcat(lDialogString, aDefaultPathAndFile) ;
5503 strcat(lDialogString,
"\"") ;
5505 if (aNumOfFilterPatterns > 0) {
5506 strcat(lDialogString,
" --file-filter='") ;
5507 if (aSingleFilterDescription && strlen(aSingleFilterDescription)) {
5508 strcat(lDialogString, aSingleFilterDescription) ;
5509 strcat(lDialogString,
" |") ;
5511 for (i = 0 ; i < aNumOfFilterPatterns ; i ++) {
5512 strcat(lDialogString,
" ") ;
5513 strcat(lDialogString, aFilterPatterns[i]) ;
5515 strcat(lDialogString,
"' --file-filter='All files | *'") ;
5517 if (
tinyfd_silent) { strcat(lDialogString,
" 2>/dev/null "); }
5519 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) { strcpy(
tinyfd_response,
"yad");
return (
char *)1; }
5520 strcpy(lDialogString,
"yad --file-selection --save --confirm-overwrite");
5521 if (aTitle && strlen(aTitle)) {
5522 strcat(lDialogString,
" --title=\"");
5523 strcat(lDialogString, aTitle);
5524 strcat(lDialogString,
"\"");
5526 if (aDefaultPathAndFile && strlen(aDefaultPathAndFile)) {
5527 strcat(lDialogString,
" --filename=\"");
5528 strcat(lDialogString, aDefaultPathAndFile);
5529 strcat(lDialogString,
"\"");
5531 if (aNumOfFilterPatterns > 0) {
5532 strcat(lDialogString,
" --file-filter='");
5533 if (aSingleFilterDescription && strlen(aSingleFilterDescription)) {
5534 strcat(lDialogString, aSingleFilterDescription);
5535 strcat(lDialogString,
" |");
5537 for (i = 0; i < aNumOfFilterPatterns; i++) {
5538 strcat(lDialogString,
" ");
5539 strcat(lDialogString, aFilterPatterns[i]);
5541 strcat(lDialogString,
"' --file-filter='All files | *'");
5543 if (
tinyfd_silent) { strcat(lDialogString,
" 2>/dev/null "); }
5545 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"python3-tkinter");
return (
char *)1;}
5547 strcat(lDialogString,
5548 " -S -c \"import tkinter;from tkinter import filedialog;root=tkinter.Tk();root.withdraw();");
5549 strcat(lDialogString,
"res=filedialog.asksaveasfilename(");
5550 if (aTitle && strlen(aTitle)) {
5551 strcat(lDialogString,
"title='") ;
5552 strcat(lDialogString, aTitle) ;
5553 strcat(lDialogString,
"',") ;
5555 if (aDefaultPathAndFile && strlen(aDefaultPathAndFile)) {
5557 if (strlen(lString)) {
5558 strcat(lDialogString,
"initialdir='") ;
5559 strcat(lDialogString, lString) ;
5560 strcat(lDialogString,
"',") ;
5563 if (strlen(lString)) {
5564 strcat(lDialogString,
"initialfile='") ;
5565 strcat(lDialogString, lString) ;
5566 strcat(lDialogString,
"',") ;
5569 if ((aNumOfFilterPatterns > 1)
5570 || ((aNumOfFilterPatterns == 1)
5571 && (aFilterPatterns[0][strlen(aFilterPatterns[0]) - 1] !=
'*'))) {
5572 strcat(lDialogString,
"filetypes=(") ;
5573 strcat(lDialogString,
"('") ;
5574 if (aSingleFilterDescription && strlen(aSingleFilterDescription)) {
5575 strcat(lDialogString, aSingleFilterDescription) ;
5577 strcat(lDialogString,
"',(") ;
5578 for (i = 0 ; i < aNumOfFilterPatterns ; i ++) {
5579 strcat(lDialogString,
"'") ;
5580 strcat(lDialogString, aFilterPatterns[i]) ;
5581 strcat(lDialogString,
"',") ;
5583 strcat(lDialogString,
")),") ;
5584 strcat(lDialogString,
"('All files','*'))") ;
5586 strcat(lDialogString,
");\nif not isinstance(res, tuple):\n\tprint(res)\n\"") ;
5588 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"python2-tkinter");
return (
char *)1;}
5589 strcpy(lDialogString,
"export PYTHONIOENCODING=utf-8;") ;
5592 strcat(lDialogString,
" -i") ;
5594 strcat(lDialogString,
5595 " -S -c \"import Tkinter,tkFileDialog;root=Tkinter.Tk();root.withdraw();");
5598 strcat(lDialogString,
5599 "import os;os.system('''/usr/bin/osascript -e 'tell app \\\"Finder\\\" to set\
5600 frontmost of process \\\"Python\\\" to true' ''');");
5603 strcat(lDialogString,
"res=tkFileDialog.asksaveasfilename(");
5604 if (aTitle && strlen(aTitle)) {
5605 strcat(lDialogString,
"title='") ;
5606 strcat(lDialogString, aTitle) ;
5607 strcat(lDialogString,
"',") ;
5609 if (aDefaultPathAndFile && strlen(aDefaultPathAndFile)) {
5611 if (strlen(lString)) {
5612 strcat(lDialogString,
"initialdir='") ;
5613 strcat(lDialogString, lString) ;
5614 strcat(lDialogString,
"',") ;
5617 if (strlen(lString)) {
5618 strcat(lDialogString,
"initialfile='") ;
5619 strcat(lDialogString, lString) ;
5620 strcat(lDialogString,
"',") ;
5623 if ((aNumOfFilterPatterns > 1)
5624 || ((aNumOfFilterPatterns == 1)
5625 && (aFilterPatterns[0][strlen(aFilterPatterns[0]) - 1] !=
'*'))) {
5626 strcat(lDialogString,
"filetypes=(") ;
5627 strcat(lDialogString,
"('") ;
5628 if (aSingleFilterDescription && strlen(aSingleFilterDescription)) {
5629 strcat(lDialogString, aSingleFilterDescription) ;
5631 strcat(lDialogString,
"',(") ;
5632 for (i = 0 ; i < aNumOfFilterPatterns ; i ++) {
5633 strcat(lDialogString,
"'") ;
5634 strcat(lDialogString, aFilterPatterns[i]) ;
5635 strcat(lDialogString,
"',") ;
5637 strcat(lDialogString,
")),") ;
5638 strcat(lDialogString,
"('All files','*'))") ;
5640 strcat(lDialogString,
");\nif not isinstance(res, tuple):\n\tprint res \n\"") ;
5643 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"xdialog");
return (
char *)1;}
5644 lWasGraphicDialog = 1 ;
5645 strcpy(lDialogString,
"(Xdialog ") ;
5647 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"dialog");
return (
char *)0;}
5648 strcpy(lDialogString,
"(dialog ") ;
5650 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"dialog");
return (
char *)0;}
5653 strcat(lDialogString,
"'(") ;
5655 strcat(lDialogString,
" ") ;
5658 if (aTitle && strlen(aTitle)) {
5659 strcat(lDialogString,
"--title \"") ;
5660 strcat(lDialogString, aTitle) ;
5661 strcat(lDialogString,
"\" ") ;
5665 strcat(lDialogString,
"--backtitle \"") ;
5666 strcat(lDialogString,
5667 "tab: focus | /: populate | spacebar: fill text field | ok: TEXT FIELD ONLY") ;
5668 strcat(lDialogString,
"\" ") ;
5671 strcat(lDialogString,
"--fselect \"") ;
5672 if (aDefaultPathAndFile && strlen(aDefaultPathAndFile)) {
5673 if (! strchr(aDefaultPathAndFile,
'/')) {
5674 strcat(lDialogString,
"./") ;
5676 strcat(lDialogString, aDefaultPathAndFile) ;
5678 strcat(lDialogString, getenv(
"HOME")) ;
5679 strcat(lDialogString,
"/") ;
5681 strcat(lDialogString,
"./") ;
5684 if (lWasGraphicDialog) {
5685 strcat(lDialogString,
"\" 0 60 ) 2>&1 ") ;
5687 strcat(lDialogString,
"\" 0 60 >/dev/tty) ") ;
5689 strcat(lDialogString,
5690 "2>/tmp/tinyfd.txt';cat /tmp/tinyfd.txt;rm /tmp/tinyfd.txt");
5692 strcat(lDialogString,
"2>&1 ; clear >/dev/tty") ;
5696 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {
return tinyfd_inputBox(aTitle, NULL, NULL);}
5697 strcpy(lBuff,
"Save file in ");
5700 if (lPointerInputBox) { strcpy(lString, lPointerInputBox); }
5702 if (p) { strcpy(lBuff, p); }
else { lBuff[0] =
'\0'; }
5703 if (lPointerInputBox) { strcpy(lPointerInputBox, lString); }
5707 if (strlen(lString) && !
dirExists(lString)) {
5711 if (! strlen(lString)) {
5717 if (
tinyfd_verbose) { printf(
"lDialogString: %s\n", lDialogString) ; }
5718 if (!(lIn = popen(lDialogString,
"r"))) {
5721 while (fgets(lBuff,
sizeof(lBuff), lIn) != NULL)
5724 if (lBuff[strlen(lBuff) - 1] ==
'\n') {
5725 lBuff[strlen(lBuff) - 1] =
'\0' ;
5728 if (! strlen(lBuff)) {
5732 if (strlen(lString) && !
dirExists(lString)) {
5746 char const *aDefaultPathAndFile,
5747 int aNumOfFilterPatterns,
5748 char const *
const *aFilterPatterns,
5749 char const *aSingleFilterDescription,
5750 int aAllowMultipleSelects)
5757 char *lPointerInputBox ;
5758 int lWasKdialog = 0 ;
5759 int lWasGraphicDialog = 0 ;
5761 size_t lFullBuffLen ;
5762 static char *lBuff = NULL;
5764 if (
tfd_quoteDetected(aTitle)) {
return tinyfd_openFileDialog(
"INVALID TITLE WITH QUOTES", aDefaultPathAndFile, aNumOfFilterPatterns, aFilterPatterns, aSingleFilterDescription, aAllowMultipleSelects); }
5765 if (
tfd_quoteDetected(aDefaultPathAndFile)) {
return tinyfd_openFileDialog(aTitle,
"INVALID DEFAULT_PATH WITH QUOTES", aNumOfFilterPatterns, aFilterPatterns, aSingleFilterDescription, aAllowMultipleSelects); }
5766 if (
tfd_quoteDetected(aSingleFilterDescription)) {
return tinyfd_openFileDialog(aTitle, aDefaultPathAndFile, aNumOfFilterPatterns, aFilterPatterns,
"INVALID FILTER_DESCRIPTION WITH QUOTES", aAllowMultipleSelects); }
5767 for (i = 0; i < aNumOfFilterPatterns; i++) {
5772 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {
5775 if (aAllowMultipleSelects) {
5777 lBuff = (
char *)(malloc(lFullBuffLen *
sizeof(
char)));
5780 lBuff = (
char *)(malloc(lFullBuffLen *
sizeof(
char)));
5784 lBuff = (
char *)(malloc(lFullBuffLen *
sizeof(
char)));
5786 if (!lBuff) {
return NULL; }
5791 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"applescript");
return (
char *)1;}
5792 strcpy(lDialogString,
"osascript ");
5793 if (!
osx9orBetter()) { strcat(lDialogString,
" -e 'tell application \"System Events\"' -e 'Activate'"); }
5794 strcat(lDialogString,
" -e 'try' -e '");
5795 if (! aAllowMultipleSelects) {
5798 strcat(lDialogString,
"POSIX path of ( ");
5800 strcat(lDialogString,
"set mylist to ");
5802 strcat(lDialogString,
"choose file ");
5803 if (aTitle && strlen(aTitle)) {
5804 strcat(lDialogString,
"with prompt \"") ;
5805 strcat(lDialogString, aTitle) ;
5806 strcat(lDialogString,
"\" ") ;
5809 if (strlen(lString)) {
5810 strcat(lDialogString,
"default location \"") ;
5811 strcat(lDialogString, lString) ;
5812 strcat(lDialogString,
"\" ") ;
5814 if (aNumOfFilterPatterns > 0) {
5815 strcat(lDialogString,
"of type {\"");
5816 strcat(lDialogString, aFilterPatterns[0] + 2) ;
5817 strcat(lDialogString,
"\"") ;
5818 for (i = 1 ; i < aNumOfFilterPatterns ; i ++) {
5819 strcat(lDialogString,
",\"") ;
5820 strcat(lDialogString, aFilterPatterns[i] + 2) ;
5821 strcat(lDialogString,
"\"") ;
5823 strcat(lDialogString,
"} ") ;
5825 if (aAllowMultipleSelects) {
5826 strcat(lDialogString,
"multiple selections allowed true ' ") ;
5827 strcat(lDialogString,
5828 "-e 'set mystring to POSIX path of item 1 of mylist' ");
5829 strcat(lDialogString,
5830 "-e 'repeat with i from 2 to the count of mylist' ");
5831 strcat(lDialogString,
"-e 'set mystring to mystring & \"|\"' ");
5832 strcat(lDialogString,
5833 "-e 'set mystring to mystring & POSIX path of item i of mylist' ");
5834 strcat(lDialogString,
"-e 'end repeat' ");
5835 strcat(lDialogString,
"-e 'mystring' ");
5837 strcat(lDialogString,
")' ") ;
5839 strcat(lDialogString,
"-e 'on error number -128' ") ;
5840 strcat(lDialogString,
"-e 'end try'") ;
5841 if (!
osx9orBetter()) { strcat(lDialogString,
" -e 'end tell'") ; }
5843 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"kdialog");
return (
char *)1;}
5846 strcpy(lDialogString,
"kdialog") ;
5848 strcat(lDialogString,
" --attach=$(xprop -root 32x '\t$0' _NET_ACTIVE_WINDOW | cut -f 2)");
5850 strcat(lDialogString,
" --getopenfilename ") ;
5852 if (aDefaultPathAndFile && strlen(aDefaultPathAndFile)) {
5853 if (aDefaultPathAndFile[0] !=
'/') {
5854 strcat(lDialogString,
"$PWD/") ;
5856 strcat(lDialogString,
"\"") ;
5857 strcat(lDialogString, aDefaultPathAndFile) ;
5858 strcat(lDialogString,
"\"") ;
5860 strcat(lDialogString,
"$PWD/") ;
5863 if (aNumOfFilterPatterns > 0) {
5864 strcat(lDialogString,
" \"") ;
5865 strcat(lDialogString, aFilterPatterns[0]) ;
5866 for (i = 1 ; i < aNumOfFilterPatterns ; i ++) {
5867 strcat(lDialogString,
" ") ;
5868 strcat(lDialogString, aFilterPatterns[i]) ;
5870 if (aSingleFilterDescription && strlen(aSingleFilterDescription)) {
5871 strcat(lDialogString,
" | ") ;
5872 strcat(lDialogString, aSingleFilterDescription) ;
5874 strcat(lDialogString,
"\"") ;
5876 if (aAllowMultipleSelects) {
5877 strcat(lDialogString,
" --multiple --separate-output") ;
5879 if (aTitle && strlen(aTitle)) {
5880 strcat(lDialogString,
" --title \"") ;
5881 strcat(lDialogString, aTitle) ;
5882 strcat(lDialogString,
"\"") ;
5886 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"zenity");
return (
char *)1;}
5887 strcpy(lDialogString,
"zenity") ;
5889 strcat(lDialogString,
" --attach=$(sleep .01;xprop -root 32x '\t$0' _NET_ACTIVE_WINDOW | cut -f 2)");
5892 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"matedialog");
return (
char *)1;}
5893 strcpy(lDialogString,
"matedialog") ;
5895 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"shellementary");
return (
char *)1;}
5896 strcpy(lDialogString,
"shellementary") ;
5898 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"qarma");
return (
char *)1;}
5899 strcpy(lDialogString,
"qarma") ;
5901 strcat(lDialogString,
" --attach=$(xprop -root 32x '\t$0' _NET_ACTIVE_WINDOW | cut -f 2)");
5904 strcat(lDialogString,
" --file-selection") ;
5906 if (aAllowMultipleSelects) {
5907 strcat(lDialogString,
" --multiple") ;
5909 if (aTitle && strlen(aTitle)) {
5910 strcat(lDialogString,
" --title=\"") ;
5911 strcat(lDialogString, aTitle) ;
5912 strcat(lDialogString,
"\"") ;
5914 if (aDefaultPathAndFile && strlen(aDefaultPathAndFile)) {
5915 strcat(lDialogString,
" --filename=\"") ;
5916 strcat(lDialogString, aDefaultPathAndFile) ;
5917 strcat(lDialogString,
"\"") ;
5919 if (aNumOfFilterPatterns > 0) {
5920 strcat(lDialogString,
" --file-filter='") ;
5921 if (aSingleFilterDescription && strlen(aSingleFilterDescription)) {
5922 strcat(lDialogString, aSingleFilterDescription) ;
5923 strcat(lDialogString,
" |") ;
5925 for (i = 0 ; i < aNumOfFilterPatterns ; i ++) {
5926 strcat(lDialogString,
" ") ;
5927 strcat(lDialogString, aFilterPatterns[i]) ;
5929 strcat(lDialogString,
"' --file-filter='All files | *'") ;
5931 if (
tinyfd_silent) { strcat(lDialogString,
" 2>/dev/null "); }
5933 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) { strcpy(
tinyfd_response,
"yad");
return (
char *)1; }
5934 strcpy(lDialogString,
"yad --file-selection");
5935 if (aAllowMultipleSelects) {
5936 strcat(lDialogString,
" --multiple");
5938 if (aTitle && strlen(aTitle)) {
5939 strcat(lDialogString,
" --title=\"");
5940 strcat(lDialogString, aTitle);
5941 strcat(lDialogString,
"\"");
5943 if (aDefaultPathAndFile && strlen(aDefaultPathAndFile)) {
5944 strcat(lDialogString,
" --filename=\"");
5945 strcat(lDialogString, aDefaultPathAndFile);
5946 strcat(lDialogString,
"\"");
5948 if (aNumOfFilterPatterns > 0) {
5949 strcat(lDialogString,
" --file-filter='");
5950 if (aSingleFilterDescription && strlen(aSingleFilterDescription)) {
5951 strcat(lDialogString, aSingleFilterDescription);
5952 strcat(lDialogString,
" |");
5954 for (i = 0; i < aNumOfFilterPatterns; i++) {
5955 strcat(lDialogString,
" ");
5956 strcat(lDialogString, aFilterPatterns[i]);
5958 strcat(lDialogString,
"' --file-filter='All files | *'");
5960 if (
tinyfd_silent) { strcat(lDialogString,
" 2>/dev/null "); }
5962 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"python3-tkinter");
return (
char *)1;}
5964 strcat(lDialogString,
5965 " -S -c \"import tkinter;from tkinter import filedialog;root=tkinter.Tk();root.withdraw();");
5966 strcat(lDialogString,
"lFiles=filedialog.askopenfilename(");
5967 if (aAllowMultipleSelects) {
5968 strcat(lDialogString,
"multiple=1,") ;
5970 if (aTitle && strlen(aTitle)) {
5971 strcat(lDialogString,
"title='") ;
5972 strcat(lDialogString, aTitle) ;
5973 strcat(lDialogString,
"',") ;
5975 if (aDefaultPathAndFile && strlen(aDefaultPathAndFile)) {
5977 if (strlen(lString)) {
5978 strcat(lDialogString,
"initialdir='") ;
5979 strcat(lDialogString, lString) ;
5980 strcat(lDialogString,
"',") ;
5983 if (strlen(lString)) {
5984 strcat(lDialogString,
"initialfile='") ;
5985 strcat(lDialogString, lString) ;
5986 strcat(lDialogString,
"',") ;
5989 if ((aNumOfFilterPatterns > 1)
5990 || ((aNumOfFilterPatterns == 1)
5991 && (aFilterPatterns[0][strlen(aFilterPatterns[0]) - 1] !=
'*'))) {
5992 strcat(lDialogString,
"filetypes=(") ;
5993 strcat(lDialogString,
"('") ;
5994 if (aSingleFilterDescription && strlen(aSingleFilterDescription)) {
5995 strcat(lDialogString, aSingleFilterDescription) ;
5997 strcat(lDialogString,
"',(") ;
5998 for (i = 0 ; i < aNumOfFilterPatterns ; i ++) {
5999 strcat(lDialogString,
"'") ;
6000 strcat(lDialogString, aFilterPatterns[i]) ;
6001 strcat(lDialogString,
"',") ;
6003 strcat(lDialogString,
")),") ;
6004 strcat(lDialogString,
"('All files','*'))") ;
6006 strcat(lDialogString,
");\
6007 \nif not isinstance(lFiles, tuple):\n\tprint(lFiles)\nelse:\
6008 \n\tlFilesString=''\n\tfor lFile in lFiles:\n\t\tlFilesString+=str(lFile)+'|'\
6009 \n\tprint(lFilesString[:-1])\n\"") ;
6011 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"python2-tkinter");
return (
char *)1;}
6012 strcpy(lDialogString,
"export PYTHONIOENCODING=utf-8;") ;
6015 strcat(lDialogString,
" -i") ;
6017 strcat(lDialogString,
6018 " -S -c \"import Tkinter,tkFileDialog;root=Tkinter.Tk();root.withdraw();");
6021 strcat(lDialogString,
6022 "import os;os.system('''/usr/bin/osascript -e 'tell app \\\"Finder\\\" to set \
6023 frontmost of process \\\"Python\\\" to true' ''');");
6025 strcat(lDialogString,
"lFiles=tkFileDialog.askopenfilename(");
6026 if (aAllowMultipleSelects) {
6027 strcat(lDialogString,
"multiple=1,") ;
6029 if (aTitle && strlen(aTitle)) {
6030 strcat(lDialogString,
"title='") ;
6031 strcat(lDialogString, aTitle) ;
6032 strcat(lDialogString,
"',") ;
6034 if (aDefaultPathAndFile && strlen(aDefaultPathAndFile)) {
6036 if (strlen(lString)) {
6037 strcat(lDialogString,
"initialdir='") ;
6038 strcat(lDialogString, lString) ;
6039 strcat(lDialogString,
"',") ;
6042 if (strlen(lString)) {
6043 strcat(lDialogString,
"initialfile='") ;
6044 strcat(lDialogString, lString) ;
6045 strcat(lDialogString,
"',") ;
6048 if ((aNumOfFilterPatterns > 1)
6049 || ((aNumOfFilterPatterns == 1)
6050 && (aFilterPatterns[0][strlen(aFilterPatterns[0]) - 1] !=
'*'))) {
6051 strcat(lDialogString,
"filetypes=(") ;
6052 strcat(lDialogString,
"('") ;
6053 if (aSingleFilterDescription && strlen(aSingleFilterDescription)) {
6054 strcat(lDialogString, aSingleFilterDescription) ;
6056 strcat(lDialogString,
"',(") ;
6057 for (i = 0 ; i < aNumOfFilterPatterns ; i ++) {
6058 strcat(lDialogString,
"'") ;
6059 strcat(lDialogString, aFilterPatterns[i]) ;
6060 strcat(lDialogString,
"',") ;
6062 strcat(lDialogString,
")),") ;
6063 strcat(lDialogString,
"('All files','*'))") ;
6065 strcat(lDialogString,
");\
6066 \nif not isinstance(lFiles, tuple):\n\tprint lFiles\nelse:\
6067 \n\tlFilesString=''\n\tfor lFile in lFiles:\n\t\tlFilesString+=str(lFile)+'|'\
6068 \n\tprint lFilesString[:-1]\n\"") ;
6071 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"xdialog");
return (
char *)1;}
6072 lWasGraphicDialog = 1 ;
6073 strcpy(lDialogString,
"(Xdialog ") ;
6075 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"dialog");
return (
char *)0;}
6076 strcpy(lDialogString,
"(dialog ") ;
6078 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"dialog");
return (
char *)0;}
6081 strcat(lDialogString,
"'(") ;
6083 strcat(lDialogString,
" ") ;
6086 if (aTitle && strlen(aTitle)) {
6087 strcat(lDialogString,
"--title \"") ;
6088 strcat(lDialogString, aTitle) ;
6089 strcat(lDialogString,
"\" ") ;
6093 strcat(lDialogString,
"--backtitle \"") ;
6094 strcat(lDialogString,
6095 "tab: focus | /: populate | spacebar: fill text field | ok: TEXT FIELD ONLY") ;
6096 strcat(lDialogString,
"\" ") ;
6099 strcat(lDialogString,
"--fselect \"") ;
6100 if (aDefaultPathAndFile && strlen(aDefaultPathAndFile)) {
6101 if (! strchr(aDefaultPathAndFile,
'/')) {
6102 strcat(lDialogString,
"./") ;
6104 strcat(lDialogString, aDefaultPathAndFile) ;
6106 strcat(lDialogString, getenv(
"HOME")) ;
6107 strcat(lDialogString,
"/");
6109 strcat(lDialogString,
"./") ;
6112 if (lWasGraphicDialog) {
6113 strcat(lDialogString,
"\" 0 60 ) 2>&1 ") ;
6115 strcat(lDialogString,
"\" 0 60 >/dev/tty) ") ;
6117 strcat(lDialogString,
6118 "2>/tmp/tinyfd.txt';cat /tmp/tinyfd.txt;rm /tmp/tinyfd.txt");
6120 strcat(lDialogString,
"2>&1 ; clear >/dev/tty") ;
6124 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {
return tinyfd_inputBox(aTitle, NULL, NULL);}
6125 strcpy(lBuff,
"Open file from ");
6128 if (lPointerInputBox) { strcpy(lDialogString, lPointerInputBox); }
6130 if (p) { strcpy(lBuff, p); }
else { lBuff[0] =
'\0'; }
6131 if (lPointerInputBox) { strcpy(lPointerInputBox, lDialogString); }
6136 lBuff = (
char *)(realloc(lBuff, (strlen(lBuff) + 1) *
sizeof(
char)));
6141 if (
tinyfd_verbose) { printf(
"lDialogString: %s\n", lDialogString) ; }
6142 if (!(lIn = popen(lDialogString,
"r"))) {
6149 while (fgets(p,
sizeof(lBuff), lIn) != NULL) {
6153 if (lBuff[strlen(lBuff) - 1] ==
'\n') {
6154 lBuff[strlen(lBuff) - 1] =
'\0' ;
6157 if (lWasKdialog && aAllowMultipleSelects) {
6159 while ((p = strchr(p,
'\n'))) {
6164 if (! strlen(lBuff)) {
6169 if (aAllowMultipleSelects && strchr(lBuff,
'|')) {
6181 lBuff = (
char *)(realloc(lBuff, (strlen(lBuff) + 1) *
sizeof(
char)));
6190 char const *aDefaultPath)
6196 char *lPointerInputBox ;
6197 int lWasGraphicDialog = 0 ;
6205 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"applescript");
return (
char *)1;}
6206 strcpy(lDialogString,
"osascript ");
6207 if (!
osx9orBetter()) { strcat(lDialogString,
" -e 'tell application \"System Events\"' -e 'Activate'"); }
6208 strcat(lDialogString,
" -e 'try' -e 'POSIX path of ( choose folder ");
6209 if (aTitle && strlen(aTitle)) {
6210 strcat(lDialogString,
"with prompt \"") ;
6211 strcat(lDialogString, aTitle) ;
6212 strcat(lDialogString,
"\" ") ;
6214 if (aDefaultPath && strlen(aDefaultPath)) {
6215 strcat(lDialogString,
"default location \"") ;
6216 strcat(lDialogString, aDefaultPath) ;
6217 strcat(lDialogString,
"\" ") ;
6219 strcat(lDialogString,
")' ") ;
6220 strcat(lDialogString,
"-e 'on error number -128' ") ;
6221 strcat(lDialogString,
"-e 'end try'") ;
6222 if (!
osx9orBetter()) { strcat(lDialogString,
" -e 'end tell'") ; }
6224 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"kdialog");
return (
char *)1;}
6225 strcpy(lDialogString,
"kdialog") ;
6227 strcat(lDialogString,
" --attach=$(xprop -root 32x '\t$0' _NET_ACTIVE_WINDOW | cut -f 2)");
6229 strcat(lDialogString,
" --getexistingdirectory ") ;
6231 if (aDefaultPath && strlen(aDefaultPath)) {
6232 if (aDefaultPath[0] !=
'/') {
6233 strcat(lDialogString,
"$PWD/") ;
6235 strcat(lDialogString,
"\"") ;
6236 strcat(lDialogString, aDefaultPath) ;
6237 strcat(lDialogString,
"\"") ;
6239 strcat(lDialogString,
"$PWD/") ;
6242 if (aTitle && strlen(aTitle)) {
6243 strcat(lDialogString,
" --title \"") ;
6244 strcat(lDialogString, aTitle) ;
6245 strcat(lDialogString,
"\"") ;
6249 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"zenity");
return (
char *)1;}
6250 strcpy(lDialogString,
"zenity") ;
6252 strcat(lDialogString,
" --attach=$(sleep .01;xprop -root 32x '\t$0' _NET_ACTIVE_WINDOW | cut -f 2)");
6255 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"matedialog");
return (
char *)1;}
6256 strcpy(lDialogString,
"matedialog") ;
6258 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"shellementary");
return (
char *)1;}
6259 strcpy(lDialogString,
"shellementary") ;
6261 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"qarma");
return (
char *)1;}
6262 strcpy(lDialogString,
"qarma") ;
6264 strcat(lDialogString,
" --attach=$(xprop -root 32x '\t$0' _NET_ACTIVE_WINDOW | cut -f 2)");
6267 strcat(lDialogString,
" --file-selection --directory") ;
6269 if (aTitle && strlen(aTitle)) {
6270 strcat(lDialogString,
" --title=\"") ;
6271 strcat(lDialogString, aTitle) ;
6272 strcat(lDialogString,
"\"") ;
6274 if (aDefaultPath && strlen(aDefaultPath)) {
6275 strcat(lDialogString,
" --filename=\"") ;
6276 strcat(lDialogString, aDefaultPath) ;
6277 strcat(lDialogString,
"\"") ;
6279 if (
tinyfd_silent) { strcat(lDialogString,
" 2>/dev/null "); }
6281 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) { strcpy(
tinyfd_response,
"yad");
return (
char *)1; }
6282 strcpy(lDialogString,
"yad --file-selection --directory");
6283 if (aTitle && strlen(aTitle)) {
6284 strcat(lDialogString,
" --title=\"");
6285 strcat(lDialogString, aTitle);
6286 strcat(lDialogString,
"\"");
6288 if (aDefaultPath && strlen(aDefaultPath)) {
6289 strcat(lDialogString,
" --filename=\"");
6290 strcat(lDialogString, aDefaultPath);
6291 strcat(lDialogString,
"\"");
6293 if (
tinyfd_silent) { strcat(lDialogString,
" 2>/dev/null "); }
6295 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"python3-tkinter");
return (
char *)1;}
6297 strcat(lDialogString,
6298 " -S -c \"import tkinter;from tkinter import filedialog;root=tkinter.Tk();root.withdraw();");
6299 strcat(lDialogString,
"res=filedialog.askdirectory(");
6300 if (aTitle && strlen(aTitle)) {
6301 strcat(lDialogString,
"title='") ;
6302 strcat(lDialogString, aTitle) ;
6303 strcat(lDialogString,
"',") ;
6305 if (aDefaultPath && strlen(aDefaultPath)) {
6306 strcat(lDialogString,
"initialdir='") ;
6307 strcat(lDialogString, aDefaultPath) ;
6308 strcat(lDialogString,
"'") ;
6310 strcat(lDialogString,
");\nif not isinstance(res, tuple):\n\tprint(res)\n\"") ;
6312 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"python2-tkinter");
return (
char *)1;}
6313 strcpy(lDialogString,
"export PYTHONIOENCODING=utf-8;") ;
6316 strcat(lDialogString,
" -i") ;
6318 strcat(lDialogString,
6319 " -S -c \"import Tkinter,tkFileDialog;root=Tkinter.Tk();root.withdraw();");
6322 strcat(lDialogString,
6323 "import os;os.system('''/usr/bin/osascript -e 'tell app \\\"Finder\\\" to set \
6324 frontmost of process \\\"Python\\\" to true' ''');");
6327 strcat(lDialogString,
"print tkFileDialog.askdirectory(");
6328 if (aTitle && strlen(aTitle)) {
6329 strcat(lDialogString,
"title='") ;
6330 strcat(lDialogString, aTitle) ;
6331 strcat(lDialogString,
"',") ;
6333 if (aDefaultPath && strlen(aDefaultPath)) {
6334 strcat(lDialogString,
"initialdir='") ;
6335 strcat(lDialogString, aDefaultPath) ;
6336 strcat(lDialogString,
"'") ;
6338 strcat(lDialogString,
")\"") ;
6341 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"xdialog");
return (
char *)1;}
6342 lWasGraphicDialog = 1 ;
6343 strcpy(lDialogString,
"(Xdialog ") ;
6345 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"dialog");
return (
char *)0;}
6346 strcpy(lDialogString,
"(dialog ") ;
6348 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"dialog");
return (
char *)0;}
6351 strcat(lDialogString,
"'(") ;
6353 strcat(lDialogString,
" ") ;
6356 if (aTitle && strlen(aTitle)) {
6357 strcat(lDialogString,
"--title \"") ;
6358 strcat(lDialogString, aTitle) ;
6359 strcat(lDialogString,
"\" ") ;
6363 strcat(lDialogString,
"--backtitle \"") ;
6364 strcat(lDialogString,
6365 "tab: focus | /: populate | spacebar: fill text field | ok: TEXT FIELD ONLY") ;
6366 strcat(lDialogString,
"\" ") ;
6369 strcat(lDialogString,
"--dselect \"") ;
6370 if (aDefaultPath && strlen(aDefaultPath)) {
6371 strcat(lDialogString, aDefaultPath) ;
6374 strcat(lDialogString, getenv(
"HOME")) ;
6375 strcat(lDialogString,
"/");
6377 strcat(lDialogString,
"./") ;
6380 if (lWasGraphicDialog) {
6381 strcat(lDialogString,
"\" 0 60 ) 2>&1 ") ;
6383 strcat(lDialogString,
"\" 0 60 >/dev/tty) ") ;
6385 strcat(lDialogString,
6386 "2>/tmp/tinyfd.txt';cat /tmp/tinyfd.txt;rm /tmp/tinyfd.txt");
6388 strcat(lDialogString,
"2>&1 ; clear >/dev/tty") ;
6392 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {
return tinyfd_inputBox(aTitle, NULL, NULL);}
6393 strcpy(lBuff,
"Select folder from ");
6396 if (lPointerInputBox) { strcpy(lDialogString, lPointerInputBox); }
6398 if (p) { strcpy(lBuff, p); }
else { lBuff[0] =
'\0'; }
6399 if (lPointerInputBox) { strcpy(lPointerInputBox, lDialogString); }
6402 if (!p || ! strlen(p) || !
dirExists(p)) {
6407 if (
tinyfd_verbose) { printf(
"lDialogString: %s\n", lDialogString) ; }
6408 if (!(lIn = popen(lDialogString,
"r"))) {
6411 while (fgets(lBuff,
sizeof(lBuff), lIn) != NULL)
6414 if (lBuff[strlen(lBuff) - 1] ==
'\n') {
6415 lBuff[strlen(lBuff) - 1] =
'\0' ;
6418 if (! strlen(lBuff) || !
dirExists(lBuff)) {
6431 char const *aDefaultHexRGB,
6432 unsigned char const aDefaultRGB[3],
6433 unsigned char aoResultRGB[3])
6435 static char lDefaultHexRGB[16];
6439 #if !((defined(__cplusplus ) && __cplusplus >= 201103L) || (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__clang__))
6443 unsigned char lDefaultRGB[3];
6445 char *lPointerInputBox;
6448 int lWasZenity3 = 0 ;
6449 int lWasOsascript = 0 ;
6450 int lWasXdialog = 0 ;
6456 if (aDefaultHexRGB) {
6457 Hex2RGB(aDefaultHexRGB, lDefaultRGB);
6458 strcpy(lDefaultHexRGB, aDefaultHexRGB);
6460 lDefaultRGB[0] = aDefaultRGB[0];
6461 lDefaultRGB[1] = aDefaultRGB[1];
6462 lDefaultRGB[2] = aDefaultRGB[2];
6463 RGB2Hex(aDefaultRGB, lDefaultHexRGB);
6467 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"applescript");
return (
char *)1;}
6469 strcpy(lDialogString,
"osascript");
6472 strcat(lDialogString,
" -e 'tell application \"System Events\"' -e 'Activate'");
6473 strcat(lDialogString,
" -e 'try' -e 'set mycolor to choose color default color {");
6475 strcat(lDialogString,
6476 " -e 'try' -e 'tell app (path to frontmost application as Unicode text) \
6477 to set mycolor to choose color default color {");
6480 sprintf(lTmp,
"%d", 256 * lDefaultRGB[0]) ;
6481 strcat(lDialogString, lTmp) ;
6482 strcat(lDialogString,
",") ;
6483 sprintf(lTmp,
"%d", 256 * lDefaultRGB[1]) ;
6484 strcat(lDialogString, lTmp) ;
6485 strcat(lDialogString,
",") ;
6486 sprintf(lTmp,
"%d", 256 * lDefaultRGB[2]) ;
6487 strcat(lDialogString, lTmp) ;
6488 strcat(lDialogString,
"}' ") ;
6489 strcat(lDialogString,
6490 "-e 'set mystring to ((item 1 of mycolor) div 256 as integer) as string' ");
6491 strcat(lDialogString,
6492 "-e 'repeat with i from 2 to the count of mycolor' ");
6493 strcat(lDialogString,
6494 "-e 'set mystring to mystring & \" \" & ((item i of mycolor) div 256 as integer) as string' ");
6495 strcat(lDialogString,
"-e 'end repeat' ");
6496 strcat(lDialogString,
"-e 'mystring' ");
6497 strcat(lDialogString,
"-e 'on error number -128' ") ;
6498 strcat(lDialogString,
"-e 'end try'") ;
6499 if (!
osx9orBetter()) { strcat(lDialogString,
" -e 'end tell'") ; }
6501 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"kdialog");
return (
char *)1;}
6502 strcpy(lDialogString,
"kdialog") ;
6504 strcat(lDialogString,
" --attach=$(xprop -root 32x '\t$0' _NET_ACTIVE_WINDOW | cut -f 2)");
6506 sprintf(lDialogString + strlen(lDialogString),
" --getcolor --default '%s'", lDefaultHexRGB) ;
6508 if (aTitle && strlen(aTitle)) {
6509 strcat(lDialogString,
" --title \"") ;
6510 strcat(lDialogString, aTitle) ;
6511 strcat(lDialogString,
"\"") ;
6516 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"zenity3");
return (
char *)1;}
6517 strcpy(lDialogString,
"zenity");
6519 strcat(lDialogString,
" --attach=$(sleep .01;xprop -root 32x '\t$0' _NET_ACTIVE_WINDOW | cut -f 2)");
6522 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"matedialog");
return (
char *)1;}
6523 strcpy(lDialogString,
"matedialog") ;
6525 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"shellementary");
return (
char *)1;}
6526 strcpy(lDialogString,
"shellementary") ;
6528 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"qarma");
return (
char *)1;}
6529 strcpy(lDialogString,
"qarma") ;
6531 strcat(lDialogString,
" --attach=$(xprop -root 32x '\t$0' _NET_ACTIVE_WINDOW | cut -f 2)");
6534 strcat(lDialogString,
" --color-selection --show-palette") ;
6535 sprintf(lDialogString + strlen(lDialogString),
" --color=%s", lDefaultHexRGB) ;
6537 if (aTitle && strlen(aTitle)) {
6538 strcat(lDialogString,
" --title=\"") ;
6539 strcat(lDialogString, aTitle) ;
6540 strcat(lDialogString,
"\"") ;
6542 if (
tinyfd_silent) { strcat(lDialogString,
" 2>/dev/null "); }
6544 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) { strcpy(
tinyfd_response,
"yad");
return (
char *)1; }
6545 strcpy(lDialogString,
"yad --color");
6546 sprintf(lDialogString + strlen(lDialogString),
" --init-color=%s", lDefaultHexRGB);
6547 if (aTitle && strlen(aTitle)) {
6548 strcat(lDialogString,
" --title=\"");
6549 strcat(lDialogString, aTitle);
6550 strcat(lDialogString,
"\"");
6552 if (
tinyfd_silent) { strcat(lDialogString,
" 2>/dev/null "); }
6554 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"xdialog");
return (
char *)1;}
6556 strcpy(lDialogString,
"Xdialog --colorsel \"") ;
6557 if (aTitle && strlen(aTitle)) {
6558 strcat(lDialogString, aTitle) ;
6560 strcat(lDialogString,
"\" 0 60 ") ;
6561 #if (defined(__cplusplus ) && __cplusplus >= 201103L) || (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__clang__)
6562 sprintf(lTmp,
"%hhu %hhu %hhu", lDefaultRGB[0], lDefaultRGB[1], lDefaultRGB[2]);
6564 sprintf(lTmp,
"%hu %hu %hu", lDefaultRGB[0], lDefaultRGB[1], lDefaultRGB[2]);
6566 strcat(lDialogString, lTmp) ;
6567 strcat(lDialogString,
" 2>&1");
6569 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"python3-tkinter");
return (
char *)1;}
6571 strcat(lDialogString,
6572 " -S -c \"import tkinter;from tkinter import colorchooser;root=tkinter.Tk();root.withdraw();");
6573 strcat(lDialogString,
"res=colorchooser.askcolor(color='") ;
6574 strcat(lDialogString, lDefaultHexRGB) ;
6575 strcat(lDialogString,
"'") ;
6577 if (aTitle && strlen(aTitle)) {
6578 strcat(lDialogString,
",title='") ;
6579 strcat(lDialogString, aTitle) ;
6580 strcat(lDialogString,
"'") ;
6582 strcat(lDialogString,
");\
6583 \nif res[1] is not None:\n\tprint(res[1])\"") ;
6585 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {strcpy(
tinyfd_response,
"python2-tkinter");
return (
char *)1;}
6586 strcpy(lDialogString,
"export PYTHONIOENCODING=utf-8;") ;
6589 strcat(lDialogString,
" -i") ;
6592 strcat(lDialogString,
6593 " -S -c \"import Tkinter,tkColorChooser;root=Tkinter.Tk();root.withdraw();");
6596 strcat(lDialogString,
6597 "import os;os.system('''osascript -e 'tell app \\\"Finder\\\" to set \
6598 frontmost of process \\\"Python\\\" to true' ''');");
6601 strcat(lDialogString,
"res=tkColorChooser.askcolor(color='") ;
6602 strcat(lDialogString, lDefaultHexRGB) ;
6603 strcat(lDialogString,
"'") ;
6606 if (aTitle && strlen(aTitle)) {
6607 strcat(lDialogString,
",title='") ;
6608 strcat(lDialogString, aTitle) ;
6609 strcat(lDialogString,
"'") ;
6611 strcat(lDialogString,
");\
6612 \nif res[1] is not None:\n\tprint res[1]\"") ;
6614 if (aTitle && !strcmp(aTitle,
"tinyfd_query")) {
return tinyfd_inputBox(aTitle, NULL, NULL);}
6616 if (lPointerInputBox) { strcpy(lDialogString, lPointerInputBox); }
6617 p =
tinyfd_inputBox(aTitle,
"Enter hex rgb color (i.e. #f5ca20)", lDefaultHexRGB);
6619 if (!p || (strlen(p) != 7) || (p[0] !=
'#')) {
6622 for (i = 1 ; i < 7 ; i ++) {
6623 if (! isxdigit((
int) p[i])) {
6628 strcpy(lDefaultHexRGB, p);
6629 if (lPointerInputBox) { strcpy(lPointerInputBox, lDialogString); }
6630 return lDefaultHexRGB;
6633 if (
tinyfd_verbose) { printf(
"lDialogString: %s\n", lDialogString) ; }
6634 if (!(lIn = popen(lDialogString,
"r"))) {
6637 while (fgets(lBuff,
sizeof(lBuff), lIn) != NULL) {
6640 if (! strlen(lBuff)) {
6645 if (lBuff[strlen(lBuff) - 1] ==
'\n') {
6646 lBuff[strlen(lBuff) - 1] =
'\0' ;
6650 if (lBuff[0] ==
'#') {
6651 if (strlen(lBuff) > 7) {
6652 lBuff[3] = lBuff[5];
6653 lBuff[4] = lBuff[6];
6654 lBuff[5] = lBuff[9];
6655 lBuff[6] = lBuff[10];
6659 }
else if (lBuff[3] ==
'(') {
6660 #if (defined(__cplusplus ) && __cplusplus >= 201103L) || (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__clang__)
6661 sscanf(lBuff,
"rgb(%hhu,%hhu,%hhu", & aoResultRGB[0], & aoResultRGB[1], & aoResultRGB[2]);
6663 aoResultRGB[0] = strtol(lBuff + 4, & lTmp2, 10);
6664 aoResultRGB[1] = strtol(lTmp2 + 1, & lTmp2, 10);
6665 aoResultRGB[2] = strtol(lTmp2 + 1, NULL, 10);
6668 }
else if (lBuff[4] ==
'(') {
6669 #if (defined(__cplusplus ) && __cplusplus >= 201103L) || (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__clang__)
6670 sscanf(lBuff,
"rgba(%hhu,%hhu,%hhu", & aoResultRGB[0], & aoResultRGB[1], & aoResultRGB[2]);
6672 aoResultRGB[0] = strtol(lBuff + 5, & lTmp2, 10);
6673 aoResultRGB[1] = strtol(lTmp2 + 1, & lTmp2, 10);
6674 aoResultRGB[2] = strtol(lTmp2 + 1, NULL, 10);
6678 }
else if (lWasOsascript || lWasXdialog) {
6680 #if (defined(__cplusplus ) && __cplusplus >= 201103L) || (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__clang__)
6681 sscanf(lBuff,
"%hhu %hhu %hhu", & aoResultRGB[0], & aoResultRGB[1], & aoResultRGB[2]);
6683 aoResultRGB[0] = strtol(lBuff, & lTmp2, 10);
6684 aoResultRGB[1] = strtol(lTmp2 + 1, & lTmp2, 10);
6685 aoResultRGB[2] = strtol(lTmp2 + 1, NULL, 10);
6694 strcpy(lDefaultHexRGB, lBuff);
6695 return lDefaultHexRGB ;
6867 #pragma warning(default:4996)
6868 #pragma warning(default:4100)
6869 #pragma warning(default:4706)