├── Makefile ├── README.md ├── Win7AppId.cpp ├── chloc.c ├── colourscheme ├── conin.c ├── echokeys.c ├── keycodes.c ├── localejoin ├── mintheme ├── showimg ├── tek ├── terminal └── winappid.c /Makefile: -------------------------------------------------------------------------------- 1 | 2 | winappid: winappid.o 3 | cc -o $@ $^ -L/usr/lib/w32api -lole32 -luuid 4 | 5 | %.o: %.c 6 | cc -c $^ 7 | 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Mintty terminal utilities 2 | 3 | Shell scripts: 4 | 5 | ### [colourscheme](colourscheme) 6 | 7 | Display colour scheme showing 16 ANSI colours (including 8 bright versions) foreground/background. 8 | 9 | Options to arrange colours or set demo string. 10 | 11 | ### [mintheme](mintheme) 12 | 13 | List/set/query mintty themes; set graphic background. 14 | 15 | ### [showimg](showimg) 16 | 17 | Display image in terminal; options to set width or height, or aspect ratio adjustment. 18 | 19 | ### [tek](tek) 20 | 21 | Enter TEK mode, run command, or display file in TEK mode. 22 | 23 | ### [terminal](terminal) 24 | 25 | Query terminal type, name, version. 26 | 27 | -------------------------------------------------------------------------------- /Win7AppId.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Win7AppId 3 | // Author: David Roe (didroe) 4 | // The code's a bit rough and ready but it does the job 5 | // 6 | // Compile with VS 2010 express using command: 7 | // cl /EHsc /D _UNICODE Win7AppId.cpp /link ole32.lib 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | 16 | using namespace std; 17 | 18 | EXTERN_C const PROPERTYKEY DECLSPEC_SELECTANY PKEY_AppUserModel_ID = 19 | { { 0x9F4C2855, 0x9F79, 0x4B39, 20 | { 0xA8, 0xD0, 0xE1, 0xD4, 0x2D, 0xE1, 0xD5, 0xF3, } }, 5 }; 21 | 22 | void die(string message) { 23 | cout << "Error: " << message.c_str() << endl; 24 | exit(1); 25 | } 26 | 27 | void doOrDie(HRESULT hr, string message) { 28 | if (!SUCCEEDED(hr)) { 29 | die(message); 30 | } 31 | } 32 | 33 | int _tmain(int argc, _TCHAR* argv[]) 34 | { 35 | doOrDie(CoInitializeEx(NULL, COINIT_APARTMENTTHREADED), 36 | "Failed to initialise COM"); 37 | 38 | IShellLink *link; 39 | doOrDie(CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&link)), 40 | "Failed to create ShellLink object"); 41 | 42 | IPersistFile* file; 43 | doOrDie(link->QueryInterface(IID_PPV_ARGS(&file)), 44 | "Failed to obtain PersistFile interface"); 45 | 46 | if (argc > 2) { 47 | doOrDie(file->Load(argv[1], STGM_READWRITE), 48 | "Failed to load shortcut file"); 49 | } else { 50 | doOrDie(file->Load(argv[1], STGM_READ | STGM_SHARE_DENY_NONE), 51 | "Failed to load shortcut file"); 52 | } 53 | 54 | IPropertyStore* store; 55 | doOrDie(link->QueryInterface(IID_PPV_ARGS(&store)), 56 | "Failed to obtain PropertyStore interface"); 57 | 58 | PROPVARIANT pv; 59 | doOrDie(store->GetValue(PKEY_AppUserModel_ID, &pv), 60 | "Failed to retrieve AppId"); 61 | 62 | if (pv.vt != VT_EMPTY) { 63 | if (pv.vt != VT_LPWSTR) { 64 | cout << "Type: " << pv.vt << endl; 65 | die("Unexpected property value type"); 66 | } 67 | 68 | wcout << "Current AppId: " << pv.pwszVal << endl; 69 | } else { 70 | cout << "No current AppId" << endl; 71 | } 72 | PropVariantClear(&pv); 73 | 74 | if (argc > 2) { 75 | wcout << "New AppId: " << argv[2] << endl; 76 | 77 | pv.vt = VT_LPWSTR; 78 | pv.pwszVal = argv[2]; 79 | 80 | doOrDie(store->SetValue(PKEY_AppUserModel_ID, pv), 81 | "Failed to set AppId"); 82 | 83 | // Not sure if we need to do this 84 | pv.pwszVal = NULL; 85 | PropVariantClear(&pv); 86 | 87 | doOrDie(store->Commit(), 88 | "Failed to commit AppId property"); 89 | 90 | doOrDie(file->Save(NULL, TRUE), 91 | "Failed to save shortcut"); 92 | } 93 | 94 | store->Release(); 95 | file->Release(); 96 | link->Release(); 97 | 98 | return 0; 99 | } 100 | -------------------------------------------------------------------------------- /chloc.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | static const char * 7 | getlocenv(const char *name) 8 | { 9 | const char *val = getenv(name); 10 | return val && *val ? val : 0; 11 | } 12 | 13 | int 14 | main(int argc, const char *argv[]) 15 | { 16 | const char *locale = 17 | getlocenv("LC_ALL") ?: 18 | getlocenv("LC_CTYPE") ?: 19 | getlocenv("LANG") ?: 20 | setlocale(LC_CTYPE, "") ?: 21 | setlocale(LC_CTYPE, 0); 22 | 23 | puts(locale); 24 | 25 | printf("\e]7776;%s\a", locale); 26 | fflush(stdout); 27 | 28 | if (argc <= 1) 29 | return 0; 30 | 31 | spawnvp(_P_WAIT, argv[1], argv + 1); 32 | 33 | printf("\e]7776;\a"); 34 | fflush(stdout); 35 | } 36 | -------------------------------------------------------------------------------- /colourscheme: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | s="@g#5 " 4 | f=3 5 | b=4 6 | ff=9 7 | bb=10 8 | interleave=true 9 | 10 | while case "$1" in 11 | -h) cat < 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | static int pid; 26 | static HANDLE conin; 27 | 28 | struct termios orig_tattr, raw_tattr; 29 | 30 | static char prompt[256]; 31 | static int prompt_len; 32 | 33 | static bool in_readline_mode = false; 34 | 35 | static const struct { 36 | ushort cp; 37 | const char *name; 38 | } 39 | cs_names[] = { 40 | {CP_UTF8, "UTF-8"}, 41 | { 20127, "ASCII"}, 42 | { 20866, "KOI8-R"}, 43 | { 21866, "KOI8-U"}, 44 | { 936, "GBK"}, 45 | { 950, "BIG5"}, 46 | { 932, "SJIS"}, 47 | { 20932, "EUCJP"}, 48 | { 949, "EUCKR"}, 49 | }; 50 | 51 | static int 52 | cs_cp(const char *name) 53 | { 54 | uint iso; 55 | if (sscanf(name, "ISO-8859-%u", &iso) == 1) 56 | return 28590 + iso; 57 | uint cp; 58 | if (sscanf(name, "CP%u", &cp) == 1) 59 | return cp; 60 | for (uint i = 0; i < sizeof(cs_names) / sizeof(*cs_names); i++) { 61 | if (strcmp(name, cs_names[i].name) == 0) 62 | return cs_names[i].cp; 63 | } 64 | return 0; 65 | } 66 | 67 | static void 68 | sigchld(int sig) 69 | { 70 | int status; 71 | if (wait(&status) != pid) 72 | return; 73 | tcsetattr(0, TCSANOW, &orig_tattr); 74 | if (WIFEXITED(status)) 75 | exit(WEXITSTATUS(status)); 76 | else if (WIFSIGNALED(status)) { 77 | signal(SIGINT, SIG_DFL); 78 | signal(SIGHUP, SIG_DFL); 79 | signal(SIGQUIT, SIG_DFL); 80 | signal(SIGABRT, SIG_DFL); 81 | signal(SIGTERM, SIG_DFL); 82 | signal(SIGUSR1, SIG_DFL); 83 | signal(SIGUSR2, SIG_DFL); 84 | signal(SIGWINCH,SIG_DFL); 85 | raise(WTERMSIG(status)); 86 | } 87 | } 88 | 89 | static void 90 | sigfwd(int sig) 91 | { 92 | kill(pid, sig); 93 | } 94 | 95 | static void 96 | error(char *msg) 97 | { 98 | fputs(msg, stderr); 99 | exit(1); 100 | } 101 | 102 | static void 103 | sigact(int sig, void (*handler)(int), int flags) 104 | { 105 | struct sigaction action; 106 | action.sa_handler = handler; 107 | action.sa_mask = 0; 108 | action.sa_flags = flags; 109 | sigaction(sig, &action, 0); 110 | } 111 | 112 | static void 113 | forward_output(int src_fd, int dest_fd) 114 | { 115 | char buf[256]; 116 | int buf_len = read(src_fd, buf, sizeof buf); 117 | write(dest_fd, buf, buf_len); 118 | 119 | // Look for a line feed 120 | int p; 121 | for (p = buf_len; p; p--) { 122 | if (buf[p-1] == '\n') { 123 | prompt_len = buf_len - p; 124 | memcpy(prompt, buf + p, prompt_len); 125 | break; 126 | } 127 | } 128 | 129 | if (!p) { 130 | int old_prompt_len = prompt_len; 131 | prompt_len += buf_len; 132 | if (prompt_len < sizeof prompt) 133 | memcpy(prompt + old_prompt_len, buf, buf_len); 134 | } 135 | 136 | prompt[prompt_len < sizeof prompt ? prompt_len : 0] = 0; 137 | } 138 | 139 | static void 140 | trans_char(INPUT_RECORD **ppinrec, char c) 141 | { 142 | wchar_t wc; 143 | switch (mbrtowc(&wc, &c, 1, 0)) { 144 | case -2: return; 145 | case -1: 146 | mbrtowc(0, 0, 0, 0); 147 | return; 148 | } 149 | 150 | SHORT vkks = VkKeyScan(c); 151 | UCHAR vk = vkks; 152 | bool shift = vkks & 0x100, ctrl = vkks & 0x200, alt = vkks & 0x400; 153 | WORD vsc = MapVirtualKey(vk, 0 /* MAPVK_VK_TO_VSC */); 154 | (*ppinrec)[0] = (*ppinrec)[1] = (INPUT_RECORD){ 155 | .EventType = KEY_EVENT, 156 | .Event = { 157 | .KeyEvent = { 158 | .bKeyDown = false, 159 | .wRepeatCount = 1, 160 | .wVirtualKeyCode = vk, 161 | .wVirtualScanCode = vsc, 162 | .uChar = { .UnicodeChar = wc }, 163 | .dwControlKeyState = 164 | shift * SHIFT_PRESSED | 165 | ctrl * LEFT_CTRL_PRESSED | 166 | alt * RIGHT_ALT_PRESSED 167 | } 168 | } 169 | }; 170 | (*ppinrec)[0].Event.KeyEvent.bKeyDown = true; 171 | *ppinrec += 2; 172 | } 173 | 174 | static void 175 | rl_callback(char *line) 176 | { 177 | in_readline_mode = false; 178 | rl_callback_handler_remove(); 179 | 180 | if (!line) { 181 | INPUT_RECORD inrecs[2], *pinrec = inrecs; 182 | trans_char(&pinrec, 26); // ^Z 183 | WriteConsoleInputW(conin, inrecs, pinrec - inrecs, &(DWORD){0}); 184 | } 185 | else { 186 | if (*line) 187 | add_history(line); 188 | size_t len = strlen(line) + 1; 189 | line[len - 1] = '\r'; 190 | INPUT_RECORD inrecs[len * 2], *pinrec = inrecs; 191 | for (int i = 0; i < len; i++) 192 | trans_char(&pinrec, line[i]); 193 | WriteConsoleInputW(conin, inrecs, pinrec - inrecs, &(DWORD){0}); 194 | } 195 | 196 | // Fresh prompt. 197 | prompt_len = 0; 198 | *prompt = 0; 199 | } 200 | 201 | static void 202 | forward_raw_char(void) 203 | { 204 | static enum {START, SEEN_ESC, SEEN_CSI} state = START; 205 | char c = getchar(); 206 | INPUT_RECORD inrecs[2]; 207 | switch (state) { 208 | case START: 209 | if (c == '\e') { 210 | state = SEEN_ESC; 211 | return; 212 | } 213 | if (c == '\n') 214 | c = '\r'; 215 | else if (c == 0x7F) 216 | c = '\b'; 217 | INPUT_RECORD *pinrec = inrecs; 218 | trans_char(&pinrec, c); 219 | WriteConsoleInputW(conin, inrecs, pinrec - inrecs, &(DWORD){0}); 220 | return; 221 | case SEEN_ESC: 222 | state = c == '[' ? SEEN_CSI : START; 223 | return; 224 | case SEEN_CSI: 225 | state = START; 226 | UCHAR vk; 227 | switch (c) { 228 | case 'A': vk = VK_UP; break; 229 | case 'B': vk = VK_DOWN; break; 230 | case 'C': vk = VK_RIGHT; break; 231 | case 'D': vk = VK_LEFT; break; 232 | case 'F': vk = VK_END; break; 233 | case 'H': vk = VK_HOME; break; 234 | default: return; 235 | } 236 | WORD vsc = MapVirtualKey(vk, 0 /* MAPVK_VK_TO_VSC */); 237 | inrecs[0] = inrecs[1] = (INPUT_RECORD){ 238 | .EventType = KEY_EVENT, 239 | .Event = { 240 | .KeyEvent = { 241 | .bKeyDown = false, 242 | .wRepeatCount = 1, 243 | .wVirtualKeyCode = vk, 244 | .wVirtualScanCode = vsc, 245 | .uChar = { .UnicodeChar = 0 }, 246 | .dwControlKeyState = 0 247 | } 248 | } 249 | }; 250 | inrecs[0].Event.KeyEvent.bKeyDown = true; 251 | WriteConsoleInputW(conin, inrecs, 2, &(DWORD){0}); 252 | break; 253 | } 254 | } 255 | 256 | static void 257 | forward_input(void) 258 | { 259 | if (!in_readline_mode) { 260 | DWORD mode; 261 | GetConsoleMode(conin, &mode); 262 | if ((mode & 7) == 7) { // PROCESSED_INPUT, LINE_INPUT, ECHO_INPUT 263 | in_readline_mode = true; 264 | tcsetattr(0, TCSANOW, &orig_tattr); 265 | rl_already_prompted = true; 266 | rl_callback_handler_install(prompt, rl_callback); 267 | } 268 | } 269 | if (in_readline_mode) { 270 | rl_callback_read_char(); 271 | if (!in_readline_mode) 272 | tcsetattr(0, TCSANOW, &raw_tattr); 273 | } 274 | else 275 | forward_raw_char(); 276 | } 277 | 278 | int 279 | main(int argc, char *argv[]) 280 | { 281 | if (argc < 2) 282 | return 2; 283 | 284 | int pipe_fds[2]; 285 | if (pipe(pipe_fds) != 0) 286 | error("Could not create output pipe"); 287 | 288 | // This hack prompts Cygwin to allocate an invisible console for us. 289 | spawnl(_P_WAIT, "/bin/test", "/bin/test", 0); 290 | 291 | // Get hold of the console input buffer 292 | conin = 293 | CreateFile( 294 | "CONIN$", 295 | GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 296 | 0, OPEN_EXISTING, 0, 0 297 | ); 298 | if (conin == INVALID_HANDLE_VALUE) 299 | error("Could not open console input buffer"); 300 | 301 | // Configure charsets 302 | setlocale(LC_CTYPE, ""); 303 | int cp = cs_cp(nl_langinfo(CODESET)); 304 | SetConsoleCP(cp); 305 | SetConsoleOutputCP(cp); 306 | 307 | pid = fork(); 308 | if (pid < 0) 309 | error("Could not create child process"); 310 | else if (pid == 0) { 311 | setsid(); 312 | AttachConsole(-1); 313 | 314 | close(0); 315 | if (open("/dev/conin", O_RDONLY) != 0) 316 | error("Could not open /dev/conin"); 317 | 318 | close(pipe_fds[0]); 319 | int pipe_fd = pipe_fds[1]; 320 | dup2(pipe_fd, 1); 321 | dup2(pipe_fd, 2); 322 | if (pipe_fd > 2) 323 | close(pipe_fd); 324 | 325 | execvp(argv[1], argv + 1); 326 | 327 | error("Could not execute command"); 328 | } 329 | 330 | sigact(SIGCHLD, sigchld, SA_NOCLDSTOP); 331 | signal(SIGINT, sigfwd); 332 | signal(SIGHUP, sigfwd); 333 | signal(SIGQUIT, sigfwd); 334 | signal(SIGABRT, sigfwd); 335 | signal(SIGTERM, sigfwd); 336 | signal(SIGUSR1, sigfwd); 337 | signal(SIGUSR2, sigfwd); 338 | signal(SIGWINCH,sigfwd); 339 | 340 | close(pipe_fds[1]); 341 | int pipe_fd = pipe_fds[0]; 342 | 343 | tcgetattr (0, &orig_tattr); 344 | raw_tattr = orig_tattr; 345 | raw_tattr.c_lflag &= ~(ECHO|ICANON|IEXTEN); 346 | tcsetattr(0, TCSANOW, &raw_tattr); 347 | 348 | rl_catch_signals = false; 349 | rl_bind_key ('\t', rl_insert); 350 | 351 | for (;;) { 352 | fd_set fdset; 353 | FD_ZERO(&fdset); 354 | FD_SET(0, &fdset); 355 | FD_SET(pipe_fd, &fdset); 356 | 357 | if (select(pipe_fd + 1, &fdset, 0, 0, 0) > 0) { 358 | if (FD_ISSET(pipe_fd, &fdset)) 359 | forward_output(pipe_fd, 1); 360 | if (FD_ISSET(0, &fdset)) 361 | forward_input(); 362 | } 363 | } 364 | } 365 | -------------------------------------------------------------------------------- /echokeys.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | struct termios saved_tattr; 7 | 8 | void 9 | restore_tattr (void) 10 | { 11 | if (isatty (STDIN_FILENO)) 12 | tcsetattr (STDIN_FILENO, TCSANOW, &saved_tattr); 13 | } 14 | 15 | int 16 | main(int argc, char *argv[]) 17 | { 18 | unsigned char c; 19 | if (isatty (STDIN_FILENO)) { 20 | tcgetattr (STDIN_FILENO, &saved_tattr); 21 | struct termios tattr = saved_tattr; 22 | tattr.c_iflag &= 23 | ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON); 24 | tattr.c_oflag &= ~OPOST; 25 | tattr.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN); 26 | tattr.c_cflag &= ~(CSIZE|PARENB); 27 | tattr.c_cflag |= CS8; 28 | tcsetattr (STDIN_FILENO, TCSAFLUSH, &tattr); 29 | atexit (restore_tattr); 30 | } 31 | setbuf(stdout, 0); 32 | while (*++argv) 33 | fputs(*argv, stdout); 34 | while ((c = getchar()) != 4) { 35 | switch (c) { 36 | case 0x00 ... 0x1f: putchar('^'); putchar(c + 0x40); break; 37 | case '^': case '\\': putchar('\\'); putchar(c); break; 38 | case 0x7f: putchar('^'); putchar('?'); break; 39 | case 0x80 ... 0xFF: printf("\\x%2X", c); break; 40 | default: putchar(c); 41 | } 42 | } 43 | putchar ('\n'); 44 | return 0; 45 | } 46 | -------------------------------------------------------------------------------- /keycodes.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | struct termios saved_tattr; 7 | 8 | void 9 | restore_tattr (void) 10 | { 11 | if (isatty (STDIN_FILENO)) 12 | tcsetattr (STDIN_FILENO, TCSANOW, &saved_tattr); 13 | } 14 | 15 | int 16 | main (void) 17 | { 18 | if (isatty (STDIN_FILENO)) { 19 | tcgetattr (STDIN_FILENO, &saved_tattr); 20 | struct termios tattr = saved_tattr; 21 | tattr.c_iflag &= 22 | ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON); 23 | tattr.c_oflag &= ~OPOST; 24 | tattr.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN); 25 | tattr.c_cflag &= ~(CSIZE|PARENB); 26 | tattr.c_cflag |= CS8; 27 | tcsetattr (STDIN_FILENO, TCSAFLUSH, &tattr); 28 | atexit (restore_tattr); 29 | } 30 | setbuf(stdout, 0); 31 | int c; 32 | while ((c = getchar()) && c != -1) { 33 | printf("%02X ", c); 34 | } 35 | putchar ('\n'); 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /localejoin: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | ############################################################################# 4 | # determine whether there is a remote ambiguous-width mismatch 5 | 6 | pre= 7 | post= 8 | 9 | ctype="${LC_ALL:-${LC_CTYPE:-$LANG}}" 10 | case "$ctype" in 11 | *@cjk*) post="]701;$ctype" 12 | ctype="${ctype%@*}" 13 | if [ -n "$LC_ALL" ] 14 | then LC_ALL=$ctype 15 | else LC_CTYPE=$ctype 16 | fi 17 | pre="]701;$ctype" 18 | ;; 19 | esac 20 | case "$ctype" in 21 | ja_*.utf8|ja_*.UTF-8|ko_*.utf8|ko_*.UTF-8|zh_*.utf8|zh_*.UTF-8) 22 | uver=`uname -r` 23 | uver="${uver%[a-z](*}" 24 | uver="${uver//./}" 25 | if [ "$uver" -lt 320 ] 26 | then 27 | # if we have a CJK locale with UTF-8 encoding 28 | # and no explicit @cjk* modifier, 29 | # tweak terminal locale to ambiguous-width narrow for remote system 30 | pre="]701;$ctype@cjknarrow" 31 | if [ -z "$post" ] 32 | then post="]701;$ctype" 33 | fi 34 | fi 35 | ;; 36 | esac 37 | 38 | ############################################################################# 39 | # derive remote login program depending on script name 40 | 41 | basename="${0##*/}" 42 | case "$basename" in 43 | *rsh*) remote=rsh;; 44 | *rlogin*) remote=rlogin;; 45 | *rexec*) remote=rexec;; 46 | *telnet*) remote=telnet;; 47 | *ssh*) remote=ssh;; 48 | *) remote=${SHELL:-sh};; 49 | esac 50 | 51 | ############################################################################# 52 | # switch terminal locale and call (remote) program 53 | #echo LC_ALL $LC_ALL 54 | #echo LC_CTYPE $LC_CTYPE 55 | #echo pre "${pre#*;}" 56 | #echo post "${post#*;}" 57 | 58 | echo -n "$pre" 59 | "$remote" "$@" 60 | echo -n "$post" 61 | 62 | ############################################################################# 63 | # end 64 | -------------------------------------------------------------------------------- /mintheme: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | ############################################################################# 4 | # mintty theme switcher 5 | # features: 6 | # list themes from config directories 7 | # set a theme from config directories 8 | # set a theme from a file 9 | # query current colour configuration as theme 10 | # possible future features: 11 | # set a theme from a URL 12 | # load theme from a URL into config directory 13 | # store current theme into config directory 14 | 15 | help() { 16 | echo "Usage:" 17 | echo " `basename $0` [-h|-l]" 18 | echo " `basename $0` THEME" 19 | echo " `basename $0` -f THEMEFILE" 20 | echo " `basename $0` --save [THEME|THEMEFILE]" 21 | echo " `basename $0` [-t|-p|-%] IMAGE" 22 | echo " `basename $0` [-s|-S] [PATTERNS]" 23 | echo " `basename $0` [-d] -q > THEMEFILE" 24 | echo "List/set/query mintty themes in current mintty window." 25 | echo "A theme is a colour scheme to configure the 8 ANSI colours, their " 26 | echo "bright versions, and optionally the foreground/background/cursor colours." 27 | echo 28 | echo "Arguments:" 29 | echo " THEME set theme from config resources" 30 | echo " -f, --file THEMEFILE set theme from themefile" 31 | echo " --save [THEME|THEMEFILE] save theme also in config file" 32 | echo " -t, --texture FILE[,DIM] set background texture (dim 1..255)" 33 | echo " -p, --picture FILE[,DIM] set background picture (dim 1..255)" 34 | echo " -%, --picscale FILE[,DIM] like -p and scale window" 35 | echo " -q, --query query current colour configuration as theme" 36 | echo " -d, --decimal decimal query output" 37 | echo " -l, --list list available themes" 38 | echo " -s, --show [PATTERN...] show (visualize) themes [matching PATTERNs]" 39 | echo " -S, --Show [PATTERN...] show themes double-lined [matching PATTERNs]" 40 | echo " -h, --help show this" 41 | echo 42 | echo "The following directories are considered for locating configured themes:" 43 | echo ' ~/.mintty' 44 | echo ' ~/.config/mintty' 45 | echo ' $APPDATA/mintty' 46 | echo ' /usr/share/mintty' 47 | echo "Note that the command-line option --configdir cannot be considered." 48 | } 49 | 50 | terminaltype () { 51 | case "$BASH" in 52 | ?*) # try simplified query as suggested by Brian Inglis: 53 | # https://github.com/mintty/mintty/issues/776#issuecomment-475761566 54 | read -s -dc -p $'\E[>c' da < /dev/tty 55 | da=${da##$'\E'[>} 56 | set - ${da//;/ } 57 | ;; 58 | *) # other shells do not have flexible read and string operations 59 | # so it's a bit more tricky... 60 | test -t 0 && stty=`stty -g` 61 | test -t 0 && stty raw -echo min 0 time 5 62 | 63 | echo -n "[>c" > /dev/tty 64 | da=`dd < /dev/tty 2> /dev/null` 65 | 66 | test -t 0 && stty "$stty" 67 | da=${da#??} 68 | type="${da%%;*}" 69 | rest="${da#*;}" 70 | vers="${rest%%;*}" 71 | rest="${rest#*;}" 72 | rest="${rest%%c}" 73 | set - $type $vers $rest 74 | ;; 75 | esac 76 | echo $1 77 | } 78 | 79 | showtheme() { 80 | theme="$1" 81 | export theme 82 | sed \ 83 | -e 's/^\(ForegroundColour\)[ ]*=/\1=/' \ 84 | -e 's/^\(BackgroundColour\)[ ]*=/\1=/' \ 85 | -e 's/^\(CursorColour\)[ ]*=/\1=/' \ 86 | -e 's/^\(Black\)[ ]*=/\1=/' \ 87 | -e 's/^\(Red\)[ ]*=/\1=/' \ 88 | -e 's/^\(Green\)[ ]*=/\1=/' \ 89 | -e 's/^\(Yellow\)[ ]*=/\1=/' \ 90 | -e 's/^\(Blue\)[ ]*=/\1=/' \ 91 | -e 's/^\(Magenta\)[ ]*=/\1=/' \ 92 | -e 's/^\(Cyan\)[ ]*=/\1=/' \ 93 | -e 's/^\(White\)[ ]*=/\1=/' \ 94 | -e 's/^\(BoldBlack\)[ ]*=/\1=/' \ 95 | -e 's/^\(BoldRed\)[ ]*=/\1=/' \ 96 | -e 's/^\(BoldGreen\)[ ]*=/\1=/' \ 97 | -e 's/^\(BoldYellow\)[ ]*=/\1=/' \ 98 | -e 's/^\(BoldBlue\)[ ]*=/\1=/' \ 99 | -e 's/^\(BoldMagenta\)[ ]*=/\1=/' \ 100 | -e 's/^\(BoldCyan\)[ ]*=/\1=/' \ 101 | -e 's/^\(BoldWhite\)[ ]*=/\1=/' \ 102 | -e 't ok' -e d -e ': ok' -e 's/[ ]//g' \ 103 | "$1" | 104 | ( 105 | cat <<\/EOS 106 | xrgb() { 107 | sed -e "s, , ,g" /usr/share/X11/rgb.txt | 108 | sed -e "s/ *\([0-9][0-9]*\) *\([0-9][0-9]*\) *\([0-9][0-9]*\) *$1 *$/\1;\2;\3/" -e t -e d 109 | } 110 | ForegroundColour=39 111 | BackgroundColour=49 112 | CursorColour=49 113 | Black=40 114 | Red=41 115 | Green=42 116 | Yellow=43 117 | Blue=44 118 | Magenta=45 119 | Cyan=46 120 | White=47 121 | BoldBlack=100 122 | BoldRed=101 123 | BoldGreen=102 124 | BoldYellow=103 125 | BoldBlue=104 126 | BoldMagenta=105 127 | BoldCyan=106 128 | BoldWhite=107 129 | /EOS 130 | # transform colour specs: 131 | # d,d,d 132 | # d;d;d 133 | # #RRGGBB 134 | # 0xRR 135 | # rgb:RR/GG/BB 136 | # 0xRR 137 | # rgb:RRRR/GGGG/BBBB 138 | # 0xRR 139 | # cmy:C.C/M.M/Y.Y 140 | # r = (1 - c) * 255; 141 | # g = (1 - m) * 255; 142 | # b = (1 - y) * 255; 143 | # cmyk:C.C/M.M/Y.Y/K.K 144 | # r = (1 - c) * (1 - k) * 255; 145 | # g = (1 - m) * (1 - k) * 255; 146 | # b = (1 - y) * (1 - k) * 255; 147 | # X11 color names 148 | sed -e 's%=\([0-9]*\),\([0-9]*\),\([0-9]*\)%="\1;\2;\3"%' \ 149 | -e 's%=#\([0-9A-Fa-f][0-9A-Fa-f]\)\([0-9A-Fa-f][0-9A-Fa-f]\)\([0-9A-Fa-f][0-9A-Fa-f]\)%="$((0x\1));$((0x\2));$((0x\3))"%' \ 150 | -e 's%=rgb:\([0-9A-Fa-f][0-9A-Fa-f]\)/\([0-9A-Fa-f][0-9A-Fa-f]\)/\([0-9A-Fa-f][0-9A-Fa-f]\)%="$((0x\1));$((0x\2));$((0x\3))"%' \ 151 | -e 's%=rgb:\([0-9A-Fa-f][0-9A-Fa-f]\)[0-9A-Fa-f][0-9A-Fa-f]/\([0-9A-Fa-f][0-9A-Fa-f]\)[0-9A-Fa-f][0-9A-Fa-f]/\([0-9A-Fa-f][0-9A-Fa-f]\)[0-9A-Fa-f][0-9A-Fa-f]%="$((0x\1));$((0x\2));$((0x\3))"%' \ 152 | -e '/=cmy/ s%\([01]\)\.\([0-9]*\)%\1.\2000%g' \ 153 | -e '/=cmy/ s%\([01]\)\.\([0-9][0-9][0-9]\)[0-9]*%\1\2%g' \ 154 | -e '/=cmy:/ s%cmy:\([0-9/]*\)%cmyk:\1/0000%' \ 155 | -e 's%=cmyk:\([01][0-9][0-9][0-9]\)/\([01][0-9][0-9][0-9]\)/\([01][0-9][0-9][0-9]\)/\([01][0-9][0-9][0-9]\)%=cmyk:"$(( (1000 - \1) * (1000 - \4) * 255 / 1000000 ));$(( (1000 - \2) * (1000 - \4) * 255 / 1000000 ));$(( (1000 - \3) * (1000 - \4) * 255 / 1000000 ))"%' \ 156 | -e '/=cmyk:/ s%\([^0-9]\)0*\([0-9]\)%\1\2%g' -e 's%=cmyk:%=%' \ 157 | -e 's%=\([a-zA-Z][a-zA-Z ]*\)%=`xrgb "\1"`%' \ 158 | -e 't ok' -e d -e ': ok' -e 's%="%="48;2;%' 159 | if $show2 160 | then cat <<\/EOS 161 | echo -en "\e[37;${Black}mblk" 162 | echo -en "\e[30;${Red}mred" 163 | echo -en "\e[30;${Green}mgrn" 164 | echo -en "\e[30;${Yellow}mylw" 165 | echo -en "\e[30;${Blue}mblu" 166 | echo -en "\e[30;${Magenta}mmag" 167 | echo -en "\e[30;${Cyan}mcyn" 168 | echo -en "\e[30;${White}mwht" 169 | echo -en "\e[39;${CursorColour}m " 170 | echo -e "\e[m${theme}" 171 | echo -en "\e[37;${BoldBlack}mBLK" 172 | echo -en "\e[30;${BoldRed}mRED" 173 | echo -en "\e[30;${BoldGreen}mGRN" 174 | echo -en "\e[30;${BoldYellow}mYLW" 175 | echo -en "\e[30;${BoldBlue}mBLU" 176 | echo -en "\e[30;${BoldMagenta}mMAG" 177 | echo -en "\e[30;${BoldCyan}mCYN" 178 | echo -en "\e[30;${BoldWhite}mWHT" 179 | echo -en "\e[39;${CursorColour}m " 180 | echo -e "\e[${ForegroundColour};${BackgroundColour}m${theme}\e[m" 181 | /EOS 182 | else cat <<\/EOS 183 | echo -en "\e[${ForegroundColour};${BackgroundColour}mfgbg" 184 | echo -en "\e[39;${CursorColour}mC" 185 | echo -en "\e[37;${Black}mbk" 186 | echo -en "\e[30;${Red}mrd" 187 | echo -en "\e[30;${Green}mgn" 188 | echo -en "\e[30;${Yellow}myl" 189 | echo -en "\e[30;${Blue}mbl" 190 | echo -en "\e[30;${Magenta}mmg" 191 | echo -en "\e[30;${Cyan}mcy" 192 | echo -en "\e[30;${White}mwh" 193 | echo -en "\e[37;${BoldBlack}mBK" 194 | echo -en "\e[30;${BoldRed}mRD" 195 | echo -en "\e[30;${BoldGreen}mGN" 196 | echo -en "\e[30;${BoldYellow}mYL" 197 | echo -en "\e[30;${BoldBlue}mBL" 198 | echo -en "\e[30;${BoldMagenta}mMG" 199 | echo -en "\e[30;${BoldCyan}mCY" 200 | echo -en "\e[30;${BoldWhite}mWH" 201 | echo -e "\e[m $theme" 202 | /EOS 203 | fi 204 | ) | sh 205 | } 206 | 207 | showthemes() { 208 | for confdir in ~/.mintty ~/.config/mintty "$APPDATA"/mintty /usr/share/mintty 209 | do if [ -d "$confdir/themes" -a -x "$confdir/themes" -a -r "$confdir/themes" ] 210 | then echo "themes in '$confdir':" 211 | ( 212 | cd "$confdir/themes" 213 | for th in *[!~] 214 | do for pat in "${@-}" 215 | do case "$th" in 216 | *$pat*) showtheme "$th";; 217 | esac 218 | done 219 | done 220 | ) 221 | fi 222 | done 223 | } 224 | 225 | settheme() { 226 | case `terminaltype` in 227 | 83) # screen 228 | pre='P' 229 | post='\\' 230 | ;; 231 | *) pre= 232 | post= 233 | ;; 234 | esac 235 | sed \ 236 | -e 's/^\(ForegroundColour\)[ ]*=/10;/' \ 237 | -e 's/^\(BackgroundColour\)[ ]*=/11;/' \ 238 | -e 's/^\(CursorColour\)[ ]*=/12;/' \ 239 | -e 's/^\(Black\)[ ]*=/4;0;/' \ 240 | -e 's/^\(Red\)[ ]*=/4;1;/' \ 241 | -e 's/^\(Green\)[ ]*=/4;2;/' \ 242 | -e 's/^\(Yellow\)[ ]*=/4;3;/' \ 243 | -e 's/^\(Blue\)[ ]*=/4;4;/' \ 244 | -e 's/^\(Magenta\)[ ]*=/4;5;/' \ 245 | -e 's/^\(Cyan\)[ ]*=/4;6;/' \ 246 | -e 's/^\(White\)[ ]*=/4;7;/' \ 247 | -e 's/^\(BoldBlack\)[ ]*=/4;8;/' \ 248 | -e 's/^\(BoldRed\)[ ]*=/4;9;/' \ 249 | -e 's/^\(BoldGreen\)[ ]*=/4;10;/' \ 250 | -e 's/^\(BoldYellow\)[ ]*=/4;11;/' \ 251 | -e 's/^\(BoldBlue\)[ ]*=/4;12;/' \ 252 | -e 's/^\(BoldMagenta\)[ ]*=/4;13;/' \ 253 | -e 's/^\(BoldCyan\)[ ]*=/4;14;/' \ 254 | -e 's/^\(BoldWhite\)[ ]*=/4;15;/' \ 255 | -e 't ok' -e d -e ': ok' -e 's/[ ]//g' \ 256 | -e "s/^/$pre]/" -e "s/$/$post/" "$1" | 257 | tr -d '\012' 258 | #]4;A;colour set ANSI colour A=0..15 259 | #]10;colour set foreground colour 260 | #]11;colour set background colour 261 | #]12;colour set cursor colour 262 | # unused: 263 | #]104;A reset ANSI colour A=0..15 264 | #]104 reset colour palette 265 | #]110 reset foreground colour 266 | #]111 reset background colour 267 | #]112 reset cursor colour 268 | } 269 | 270 | query() { 271 | len=$(( $1 + 3 )) 272 | echo -n "]$2;?" > /dev/tty 273 | read -s -n$len -t 2 esc < /dev/tty # read ESC ] prefix and colour index 274 | read -s -n18 colour < /dev/tty # read rgb:colour spec 275 | read -s -n1 -t 2 esc < /dev/tty # read ^G suffix 276 | 277 | if $decimal 278 | then 279 | eval $( echo $colour | sed -e "s@rgb:\(..\)../\(..\)../\(..\)..@printf '$3=%d,%d,%d' 0x\1 0x\2 0x\3@" -e t -e "s,^,printf $3=," ) 280 | echo 281 | else 282 | # 4-digit hex 283 | echo $3=$colour 284 | # 2-digit hex 285 | #echo $3=$colour | sed -e "s,rgb:\(..\)../\(..\)../\(..\)..,rgb:\1/\2/\3," 286 | fi 287 | } 288 | 289 | conftheme() { 290 | if [ `uname` = "Linux" ] && type wslpath 2> /dev/null 1>&2 291 | then 292 | themefile=`wslpath -ma "$1"` 293 | elif type cygpath 2> /dev/null 1>&2 294 | then 295 | themefile=`cygpath -wa "$1"` 296 | else 297 | echo "cannot save to config file in this system environment" 298 | exit 299 | fi 300 | if [ `uname` = "Linux" ] && type wslpath 1>&2 301 | then 302 | ls "$APPDATA/mintty/config" 303 | elif type cygpath 1>&2 304 | then 305 | ls ~/.minttyrc ~/.config/mintty/config "$APPDATA/mintty/config" /etc/minttyrc 306 | fi 2> /dev/null | 307 | while read conffile 308 | do if [ -w "$conffile" ] 309 | then 310 | newconf=/tmp/minttyrc.$$ 311 | # create new config file with modified entry 312 | sed -n -e "/^ThemeFile[ ]*=/ q" -e p "$conffile" > "$newconf" 313 | echo "ThemeFile=$themefile" >> "$newconf" 314 | sed -e "1,/^ThemeFile[ ]*=/ d" "$conffile" >> "$newconf" 315 | # copy new config file back 316 | /bin/cp "$newconf" "$conffile" 317 | /bin/rm "$newconf" 318 | # feedback 319 | echo "saved theme '$themefile'" 320 | echo "in config file '$conffile'" 321 | return 322 | fi 323 | done 324 | } 325 | 326 | decimal=false 327 | show2=false 328 | case "$1" in 329 | -d|--decimal) 330 | decimal=true 331 | shift;; 332 | esac 333 | 334 | case `uname` in 335 | Linux) if [ -n "$APPDATA" ] 336 | then APPDATA=`wslpath "$APPDATA"` 337 | else echo APPDATA not set >&2 338 | exit 339 | fi;; 340 | esac 341 | 342 | case "$1" in 343 | -h|--help|'') 344 | help 345 | ;; 346 | -l|--list) 347 | for confdir in ~/.mintty ~/.config/mintty "$APPDATA"/mintty /usr/share/mintty 348 | do if [ -d "$confdir/themes" -a -x "$confdir/themes" -a -r "$confdir/themes" ] 349 | then echo "themes in '$confdir':" 350 | (cd "$confdir/themes"; ls *[!~]) 351 | fi 352 | done;; 353 | -s|--show) 354 | shift 355 | showthemes "$@";; 356 | -S|--Show|--SHOW) 357 | shift 358 | show2=true 359 | export show2 360 | showthemes "$@";; 361 | -f|--file) 362 | if [ -z "$2" ] 363 | then help 364 | elif [ -r "$2" ] 365 | then settheme "$2" 366 | else echo cannot read theme file 367 | fi;; 368 | --save) 369 | if [ -z "$2" ] 370 | then help 371 | elif [ -r "$2" ] 372 | then 373 | settheme "$2" 374 | conftheme "$2" 375 | else 376 | for confdir in ~/.mintty ~/.config/mintty "$APPDATA"/mintty /usr/share/mintty 377 | do if [ -r "$confdir/themes/$2" ] 378 | then 379 | echo setting theme from config dir "$confdir" 380 | settheme "$confdir/themes/$2" 381 | conftheme "$confdir/themes/$2" 382 | exit 383 | fi 384 | done 385 | echo theme not found 386 | fi;; 387 | -p|--picture) 388 | if [ -z "$2" ] 389 | then help 390 | elif [ -r "${2/,*/}" ] 391 | then echo "]11;_$2" 392 | else echo cannot read picture file 393 | fi;; 394 | -%|--picscale) 395 | if [ -z "$2" ] 396 | then help 397 | elif [ -r "${2/,*/}" ] 398 | then echo "]11;%$2" 399 | else echo cannot read picture file 400 | fi;; 401 | -t|--texture) 402 | if [ -z "$2" ] 403 | then help 404 | elif [ -r "${2/,*/}" ] 405 | then echo "]11;*$2" 406 | else echo cannot read texture file 407 | fi;; 408 | -q|--query) 409 | # echo "]10;?]11;?]12;?" 410 | test -t 0 && stty=`stty -g` 411 | test -t 0 && stty -echo min 0 time 5 # raw 412 | 413 | query 2 "10" ForegroundColour 414 | query 2 "11" BackgroundColour 415 | query 2 "12" CursorColour 416 | query 3 "4;0" Black 417 | query 3 "4;1" Red 418 | query 3 "4;2" Green 419 | query 3 "4;3" Yellow 420 | query 3 "4;4" Blue 421 | query 3 "4;5" Magenta 422 | query 3 "4;6" Cyan 423 | query 3 "4;7" White 424 | query 3 "4;8" BoldBlack 425 | query 3 "4;9" BoldRed 426 | query 4 "4;10" BoldGreen 427 | query 4 "4;11" BoldYellow 428 | query 4 "4;12" BoldBlue 429 | query 4 "4;13" BoldMagenta 430 | query 4 "4;14" BoldCyan 431 | query 4 "4;15" BoldWhite 432 | read -s -n1 -t 1 esc < /dev/tty # swallow final bogus '\' 433 | 434 | test -t 0 && stty "$stty" 435 | ;; 436 | -*) echo unknown argument;; 437 | *) 438 | if [ -r "$1" ] 439 | then echo setting theme from config dir "$confdir" 440 | settheme "$1" 441 | exit 442 | fi 443 | for confdir in ~/.mintty ~/.config/mintty "$APPDATA"/mintty /usr/share/mintty 444 | do if [ -r "$confdir/themes/$1" ] 445 | then 446 | echo setting theme from config dir "$confdir" 447 | settheme "$confdir/themes/$1" 448 | exit 449 | fi 450 | done 451 | echo theme not found;; 452 | esac 453 | 454 | ############################################################################# 455 | # end 456 | -------------------------------------------------------------------------------- /showimg: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | width= 4 | height= 5 | pAR= 6 | while case "$1" in 7 | -w|-width) width=";width=$2" 8 | shift; shift;; 9 | -h|-height) height=";height=$2" 10 | shift; shift;; 11 | -fit) pAR=";preserveAspectRatio=0" 12 | shift;; 13 | *) false;; 14 | esac 15 | do true 16 | done 17 | 18 | case "$*" in 19 | "") echo "Usage: `basename $0` [-w WIDTH] [-h HEIGHT] [-par] IMAGE [...]" >&2 20 | echo >&2 21 | echo "This script outputs images to the terminal for display." >&2 22 | echo "Parameters:" >&2 23 | echo " -w, -width N width in N cell units, or Npx, or N%" >&2 24 | echo " -h, -height N height in N cell units, or Npx, or N%" >&2 25 | echo " -fit with both width and height: do not preserve aspect ratio" >&2 26 | exit;; 27 | esac 28 | 29 | case "$BASH" in 30 | ?*) echo=echo;; 31 | *) echo=/bin/echo;; 32 | esac 33 | 34 | for img in "$@" 35 | do 36 | if [ -r "$img" ] 37 | then 38 | #eval $(file "$img" | sed -e 's/.*, *\([0-9]*\) *x *\([0-9]*\).*/width=\1px; height=\2px/') 39 | $echo -en "\e]1337;File=name=$(echo "$img" | base64 -w 0);inline=1" 40 | $echo -en "${width}${height}${pAR}:$(base64 -w 0 "$img")\a" 41 | else 42 | echo cannot read file "$img" >&2 43 | fi 44 | done 45 | -------------------------------------------------------------------------------- /tek: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | case "$1" in 4 | -h|--help) 5 | echo "Usage: $0 [-] [CMD PARAMS | FILES]" 6 | echo "Run shell or command, or display files in Tektronix 4014 mode." 7 | echo "Set up or adjust variables PS1, TERM, GNUTERM." 8 | echo "Resize mintty terminal window to 780x1024 pixels unless disabled." 9 | echo 10 | echo Arguments: 11 | echo " - do not resize window to Tek small resolution and aspect ratio" 12 | exit;; 13 | -) scale=false; shift;; 14 | *) scale=true;; 15 | esac 16 | 17 | ############################################################################# 18 | # configure TERM value to use 19 | 20 | TEKTERM=tek4014 21 | #TEKTERM=tek # large/default font size 22 | 23 | ############################################################################# 24 | # resize mintty 25 | 26 | if $scale 27 | then case "$TERM_PROGRAM" in 28 | mintty) h=780 29 | w=1024 30 | echo -en "\e[4;${h};${w}t" 31 | ;; 32 | esac 33 | fi 34 | 35 | ############################################################################# 36 | # switch to Tek mode 37 | 38 | echo -en "\e[?38h" 39 | 40 | ############################################################################# 41 | # set variables 42 | 43 | TERM=$TEKTERM 44 | GNUTERM=tek40xx 45 | export TERM 46 | export GNUTERM 47 | 48 | ############################################################################# 49 | # run shell (if no arguments) or command (if given) or display files 50 | 51 | case "$1" in 52 | "") ${SHELL:-sh};; 53 | *) if type "$1" > /dev/null 2> /dev/null 54 | then cmd="$1" 55 | shift 56 | "$cmd" "$@" 57 | else cat "$@" 58 | fi 59 | read x;; 60 | esac 61 | 62 | ############################################################################# 63 | # switch back to DEC mode 64 | 65 | echo -e "\e" 66 | 67 | ############################################################################# 68 | # notify parent shell of changed window size 69 | 70 | kill -WINCH $PPID 71 | 72 | ############################################################################# 73 | # end 74 | -------------------------------------------------------------------------------- /terminal: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | ############################################################################# 4 | # Detect and report terminal type, name, version. 5 | # works with bash, dash, posh, zsh, ksh->mksh 6 | # not with tcsh, fish 7 | 8 | case "$1" in 9 | -h) echo "Usage: $0 [-t|-n|-v|-p]" 10 | echo "Query and report the terminal type, using Secondary Device Attribute report." 11 | echo 12 | echo Arguments: 13 | echo " -t report numeric type" 14 | echo " -n report terminal name" 15 | echo " -v report version" 16 | echo " -p report 3rd parameter" 17 | return 18 | ;; 19 | esac 20 | 21 | ############################################################################# 22 | # query functions 23 | 24 | query () { 25 | echo -n "$*" > /dev/tty 26 | dd < /dev/tty 2> /dev/null 27 | } 28 | 29 | terminaltype () { 30 | 31 | case "$BASH" in 32 | ?*) # try simplified query as suggested by Brian Inglis: 33 | # https://github.com/mintty/mintty/issues/776#issuecomment-475761566 34 | read -s -dc -p $'\E[>c' da < /dev/tty 35 | da=${da##$'\E'[>} 36 | set - ${da//;/ } 37 | ;; 38 | *) # other shells do not have flexible read and string operations 39 | # so it's a bit more tricky... 40 | test -t 0 && stty=`stty -g` 41 | test -t 0 && stty raw -echo min 0 time 5 42 | da=`query "[>c"` 43 | test -t 0 && stty "$stty" 44 | da=${da#??} 45 | type="${da%%;*}" 46 | rest="${da#*;}" 47 | vers="${rest%%;*}" 48 | rest="${rest#*;}" 49 | rest="${rest%%c}" 50 | set - $type $vers $rest 51 | ;; 52 | esac 53 | 54 | case "$1" in 55 | 0) t=VT100 56 | case "$2" in 57 | 95) t=tmux;; 58 | 115) t=KDE-konsole;; 59 | 136) t=PuTTY;; 60 | 304) t=VT125;; 61 | esac;; 62 | 1) t=VT220 63 | case "$2" in 64 | 2) t=openwin-xterm;; 65 | 96) t=mlterm;; 66 | 304) t=VT241/VT382;; 67 | 1115) t=gnome-terminal;; 68 | esac 69 | if [ 0$2 -ge 2000 ] 70 | then t=gnome-terminal 71 | fi 72 | ;; 73 | 2) t=VT240;; 74 | 24) t=VT320;; 75 | 18) t=VT330;; 76 | 19) t=VT340;; 77 | 41) t=VT420;; 78 | 61) t=VT510;; 79 | 64) t=VT520;; 80 | 65) t=VT525;; 81 | 28) t=DECterm;; 82 | 67) t=cygwin;; 83 | 77) t=mintty;; 84 | 82) t=rxvt;; 85 | 83) t=screen;; 86 | 84) t=tmux; set - $1 200;; 87 | 85) t=rxvt-unicode;; 88 | *) t=unknown;; 89 | esac 90 | 91 | tt=$1 92 | v=$2 93 | pc=$3 94 | 95 | } 96 | 97 | ############################################################################# 98 | # invoke the query and report as requested 99 | 100 | terminaltype 101 | 102 | case "$1" in 103 | -t) echo $tt;; 104 | -n) echo $t;; 105 | -v) echo $v;; 106 | -p) echo $pc;; 107 | *) echo $tt $t $v $pc;; 108 | esac 109 | 110 | ############################################################################# 111 | # end 112 | -------------------------------------------------------------------------------- /winappid.c: -------------------------------------------------------------------------------- 1 | // winappid, adapted by Thomas Wolff 2 | // and ported to cygwin C from a Windows C++ program. 3 | // link options -L/usr/lib/w32api -lole32 -luuid 4 | // 5 | // Win7AppId 6 | // Author: David Roe (didroe) 7 | // The code's a bit rough and ready but it does the job 8 | // 9 | // Compile with VS 2010 express using command: 10 | // cl /EHsc /D _UNICODE Win7AppId.cpp /link ole32.lib 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | typedef void * * voidrefref; 22 | 23 | void die(char * message) { 24 | printf("Error: %s\n", message); 25 | exit(1); 26 | } 27 | 28 | void doOrDie(HRESULT hr, char * message) { 29 | if (!SUCCEEDED(hr)) { 30 | die(message); 31 | } 32 | } 33 | 34 | int main(int argc, char * argv[]) 35 | { 36 | setlocale (LC_CTYPE, ""); 37 | 38 | if (argc <= 1) { 39 | char * bn = strrchr(argv[0], '/'); 40 | if (bn) 41 | bn++; 42 | else 43 | bn = argv[0]; 44 | printf("Usage: %s SHORTCUT [APPID]\n", bn); 45 | printf("\n"); 46 | printf("Display the Windows AppID of a shortcut or set an AppID\n"); 47 | exit(0); 48 | } 49 | 50 | doOrDie(CoInitializeEx(NULL, COINIT_APARTMENTTHREADED), 51 | "Failed to initialise COM"); 52 | 53 | IShellLink * link; 54 | doOrDie(CoCreateInstance(&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, 55 | &IID_IShellLink, (voidrefref) &link), 56 | "Failed to create ShellLink object"); 57 | 58 | IPersistFile * file; 59 | doOrDie( 60 | link->lpVtbl->QueryInterface(link, &IID_IPersistFile, 61 | (voidrefref) &file), 62 | "Failed to obtain PersistFile interface"); 63 | 64 | char * fn = cygwin_create_path(CCP_POSIX_TO_WIN_W, argv[1]); 65 | if (!fn) 66 | die("Path conversion failed"); 67 | 68 | if (argc > 2) { 69 | doOrDie(file->lpVtbl->Load(file, (LPCOLESTR)fn, (DWORD)STGM_READWRITE), 70 | "Failed to load shortcut file"); 71 | } else { 72 | doOrDie(file->lpVtbl->Load(file, (LPCOLESTR)fn, STGM_READ | STGM_SHARE_DENY_NONE), 73 | "Failed to load shortcut file"); 74 | } 75 | 76 | IPropertyStore * store; 77 | doOrDie( 78 | link->lpVtbl->QueryInterface(link, &IID_IPropertyStore, 79 | (voidrefref) &store), 80 | "Failed to obtain PropertyStore interface"); 81 | 82 | PROPVARIANT pv; 83 | doOrDie(store->lpVtbl->GetValue(store, &PKEY_AppUserModel_ID, &pv), 84 | "Failed to retrieve AppId"); 85 | 86 | if (pv.vt != VT_EMPTY) { 87 | if (pv.vt != VT_LPWSTR) { 88 | printf("Type: %d\n", pv.vt); 89 | die("Unexpected property value type"); 90 | } 91 | 92 | printf("Current AppId: %ls\n", pv.pwszVal); 93 | } else { 94 | printf("No current AppId\n"); 95 | } 96 | PropVariantClear(&pv); 97 | 98 | if (argc > 2) { 99 | wchar_t appid[MAX_PATH]; 100 | mbstowcs(appid, argv[2], MAX_PATH); 101 | 102 | printf("New AppId: %ls\n", appid); 103 | 104 | pv.vt = VT_LPWSTR; 105 | pv.pwszVal = appid; 106 | 107 | doOrDie(store->lpVtbl->SetValue(store, &PKEY_AppUserModel_ID, &pv), 108 | "Failed to set AppId"); 109 | 110 | // Not sure if we need to do this 111 | pv.pwszVal = NULL; 112 | PropVariantClear(&pv); 113 | 114 | doOrDie(store->lpVtbl->Commit(store), 115 | "Failed to commit AppId property"); 116 | 117 | doOrDie(file->lpVtbl->Save(file, NULL, TRUE), 118 | "Failed to save shortcut"); 119 | } 120 | 121 | store->lpVtbl->Release(store); 122 | file->lpVtbl->Release(file); 123 | link->lpVtbl->Release(link); 124 | 125 | return 0; 126 | } 127 | --------------------------------------------------------------------------------