~ubuntu-branches/ubuntu/saucy/links2/saucy-proposed

« back to all changes in this revision

Viewing changes to .pc/x-terminal-emulator-instead-of-xterm.diff/os_dep.c

  • Committer: Bazaar Package Importer
  • Author(s): Axel Beckert
  • Date: 2011-08-18 23:35:41 UTC
  • mfrom: (3.1.5 sid)
  • Revision ID: james.westby@ubuntu.com-20110818233541-3x10px37rwkortla
Tags: 2.3-1
* New upstream release.
  + Refreshed patches links2-instead-of-links.diff and ipv6.diff
  + Fixes downloads of files larger than 4GB (Closes: #610418)
* Fix debian/watch so that upstream versions are sorted properly; add
  and prefer bzip2 compressed upstream tarballs.
* Add missing bug number for IPv6 patch in the previous changelog entry.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* os_dep.c
 
2
 * (c) 2002 Mikulas Patocka
 
3
 * This file is a part of the Links program, released under GPL.
 
4
 */
 
5
 
 
6
#include "links.h"
 
7
 
 
8
#ifdef HAVE_SYS_IOCTL_H
 
9
#include <sys/ioctl.h>
 
10
#endif
 
11
 
 
12
#if defined(HAVE_LIBGPM) && defined(HAVE_GPM_H)
 
13
#define USE_GPM
 
14
#endif
 
15
 
 
16
#ifdef USE_GPM
 
17
#include <gpm.h>
 
18
#endif
 
19
 
 
20
 
 
21
int is_safe_in_shell(unsigned char c)
 
22
{
 
23
        return c == '@' || c == '+' || c == '-' || c == '.' || c == ',' || c == '=' || (c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || c == '_' || (c >= 'a' && c <= 'z');
 
24
}
 
25
 
 
26
int is_safe_in_url(unsigned char c)
 
27
{
 
28
        return is_safe_in_shell(c) || c == ':' || c == '/' || c >= 0x80;
 
29
}
 
30
 
 
31
void check_shell_security(unsigned char **cmd)
 
32
{
 
33
        unsigned char *c = *cmd;
 
34
        while (*c) {
 
35
                if (!is_safe_in_shell(*c)) *c = '_';
 
36
                c++;
 
37
        }
 
38
}
 
39
 
 
40
int check_shell_url(unsigned char *url)
 
41
{
 
42
        while (*url) {
 
43
                if (!is_safe_in_url(*url)) return -1;
 
44
                url++;
 
45
        }
 
46
        return 0;
 
47
}
 
48
 
 
49
unsigned char *escape_path(unsigned char *path)
 
50
{
 
51
        unsigned char *result;
 
52
        size_t i;
 
53
        if (strchr(path, '"')) return stracpy(path);
 
54
        for (i = 0; path[i]; i++) if (!is_safe_in_url(path[i])) goto do_esc;
 
55
        return stracpy(path);
 
56
        do_esc:
 
57
        result = stracpy("\"");
 
58
        add_to_strn(&result, path);
 
59
        add_to_strn(&result, "\"");
 
60
        return result;
 
61
}
 
62
 
 
63
static int get_e(char *env)
 
64
{
 
65
        char *v;
 
66
        if ((v = getenv(env))) return atoi(v);
 
67
        return 0;
 
68
}
 
69
 
 
70
void ignore_signals(void)
 
71
{
 
72
        signal(SIGPIPE, SIG_IGN);
 
73
#ifdef SIGXFSZ
 
74
        signal(SIGXFSZ, SIG_IGN);
 
75
#endif
 
76
}
 
77
 
 
78
unsigned char *clipboard = NULL;
 
79
 
 
80
#if defined(WIN32)
 
81
#include <windows.h>
 
82
#endif
 
83
 
 
84
#if defined(OS2)
 
85
 
 
86
#define INCL_MOU
 
87
#define INCL_VIO
 
88
#define INCL_DOSPROCESS
 
89
#define INCL_DOSERRORS
 
90
#define INCL_DOSMODULEMGR
 
91
#define INCL_WIN
 
92
#define INCL_WINCLIPBOARD
 
93
#define INCL_WINSWITCHLIST
 
94
#include <os2.h>
 
95
#include <io.h>
 
96
#include <process.h>
 
97
#include <sys/video.h>
 
98
#ifdef HAVE_SYS_FMUTEX_H
 
99
#include <sys/builtin.h>
 
100
#include <sys/fmutex.h>
 
101
#endif
 
102
 
 
103
#ifdef X2
 
104
/* from xf86sup - XFree86 OS/2 support driver */
 
105
#include <pty.h>
 
106
#endif
 
107
 
 
108
#endif
 
109
 
 
110
#if defined(O_SIZE) && defined(__EMX__)
 
111
 
 
112
int open_prealloc(char *name, int flags, int mode, off_t siz)
 
113
{
 
114
        return open(name, flags | O_SIZE, mode, (unsigned long)siz);
 
115
}
 
116
 
 
117
void prealloc_truncate(int h, off_t siz)
 
118
{
 
119
        ftruncate(h, siz);
 
120
}
 
121
 
 
122
#endif
 
123
 
 
124
/* Terminal size */
 
125
 
 
126
#ifdef WIN32
 
127
 
 
128
/* Cygwin has a bug and loses SIGWINCH sometimes, so poll it */
 
129
 
 
130
static void winch_thread(void *p, int l)
 
131
{
 
132
        static int old_xsize, old_ysize;
 
133
        static int cur_xsize, cur_ysize;
 
134
        if (get_terminal_size(0, &old_xsize, &old_ysize)) return;
 
135
        while (1) {
 
136
                if (get_terminal_size(1, &cur_xsize, &cur_ysize)) return;
 
137
                if ((old_xsize != cur_xsize) || (old_ysize != cur_ysize)) {
 
138
                        old_xsize = cur_xsize;
 
139
                        old_ysize = cur_ysize;
 
140
                        raise(SIGWINCH);
 
141
                }
 
142
                sleep(1);
 
143
        }
 
144
}
 
145
 
 
146
static void win32_resize_poll(void)
 
147
{
 
148
        static int winch_thread_running = 0;
 
149
        if (!winch_thread_running) {
 
150
                if (start_thread(winch_thread, NULL, 0) >= 0)
 
151
                        winch_thread_running = 1;
 
152
        }
 
153
}
 
154
 
 
155
#endif
 
156
 
 
157
#if defined(UNIX) || defined(BEOS) || defined(RISCOS) || defined(ATHEOS) || defined(WIN32) || defined(SPAD)
 
158
 
 
159
static void sigwinch(void *s)
 
160
{
 
161
        ((void (*)(void))s)();
 
162
}
 
163
 
 
164
void handle_terminal_resize(int fd, void (*fn)(void))
 
165
{
 
166
        install_signal_handler(SIGWINCH, sigwinch, fn, 0);
 
167
#ifdef WIN32
 
168
        win32_resize_poll();
 
169
#endif
 
170
}
 
171
 
 
172
void unhandle_terminal_resize(int fd)
 
173
{
 
174
        install_signal_handler(SIGWINCH, NULL, NULL, 0);
 
175
}
 
176
 
 
177
int get_terminal_size(int fd, int *x, int *y)
 
178
{
 
179
        struct winsize ws;
 
180
        if (!x || !y) return -1;
 
181
        if (ioctl(1, TIOCGWINSZ, &ws) != -1) {
 
182
                if (!(*x = ws.ws_col) && !(*x = get_e("COLUMNS"))) *x = 80;
 
183
                if (!(*y = ws.ws_row) && !(*y = get_e("LINES"))) *y = 24;
 
184
                return 0;
 
185
        } else {
 
186
                if (!(*x = get_e("COLUMNS"))) *x = 80;
 
187
                if (!(*y = get_e("LINES"))) *y = 24;
 
188
        }
 
189
        return 0;
 
190
}
 
191
 
 
192
#elif defined(OS2)
 
193
 
 
194
#define A_DECL(type, var) type var##1, var##2, *var = _THUNK_PTR_STRUCT_OK(&var##1) ? &var##1 : &var##2
 
195
 
 
196
int is_xterm(void)
 
197
{
 
198
        static int xt = -1;
 
199
        if (xt == -1) xt = !!getenv("WINDOWID");
 
200
        return xt;
 
201
}
 
202
 
 
203
int winch_pipe[2];
 
204
int winch_thread_running = 0;
 
205
 
 
206
#define WINCH_SLEEPTIME 500 /* time in ms for winch thread to sleep */
 
207
 
 
208
static void winch_thread(void)
 
209
{
 
210
        /* A thread which regularly checks whether the size of 
 
211
           window has changed. Then raise SIGWINCH or notifiy
 
212
           the thread responsible to handle this. */
 
213
        static int old_xsize, old_ysize;
 
214
        static int cur_xsize, cur_ysize;
 
215
 
 
216
        ignore_signals();
 
217
        if (get_terminal_size(1, &old_xsize, &old_ysize)) return;
 
218
        while (1) {
 
219
                if (get_terminal_size(1, &cur_xsize, &cur_ysize)) return;
 
220
                if ((old_xsize != cur_xsize) || (old_ysize != cur_ysize)) {
 
221
                        old_xsize = cur_xsize;
 
222
                        old_ysize = cur_ysize;
 
223
                        write(winch_pipe[1], "x", 1);
 
224
                        /* Resizing may take some time. So don't send a flood
 
225
                     of requests?! */
 
226
                        _sleep2(2*WINCH_SLEEPTIME);   
 
227
                }
 
228
                else
 
229
                        _sleep2(WINCH_SLEEPTIME);
 
230
        }
 
231
}
 
232
 
 
233
static void winch(void *s)
 
234
{
 
235
        char c;
 
236
        while (can_read(winch_pipe[0]) && read(winch_pipe[0], &c, 1) == 1);
 
237
        ((void (*)(void))s)();
 
238
}
 
239
 
 
240
void handle_terminal_resize(int fd, void (*fn)(void))
 
241
{
 
242
        if (!is_xterm()) return;
 
243
        if (!winch_thread_running) {
 
244
                if (c_pipe(winch_pipe) < 0) return;
 
245
                winch_thread_running = 1;
 
246
                _beginthread((void (*)(void *))winch_thread, NULL, 0x32000, NULL);
 
247
        }
 
248
        set_handlers(winch_pipe[0], winch, NULL, NULL, fn);
 
249
}
 
250
 
 
251
void unhandle_terminal_resize(int fd)
 
252
{
 
253
        set_handlers(winch_pipe[0], NULL, NULL, NULL, NULL);
 
254
}
 
255
 
 
256
int get_terminal_size(int fd, int *x, int *y)
 
257
{
 
258
        if (!x || !y) return -1;
 
259
        if (is_xterm()) {
 
260
#ifdef X2
 
261
                /* int fd; */
 
262
                int arc;
 
263
                struct winsize win;
 
264
 
 
265
                /* fd = STDIN_FILENO; */
 
266
                arc = ptioctl(1, TIOCGWINSZ, &win);
 
267
                if (arc) {
 
268
                        *x = 80;
 
269
                        *y = 24;
 
270
                        return 0;
 
271
                }
 
272
                *y = win.ws_row;
 
273
                *x = win.ws_col;
 
274
                goto set_default;
 
275
#else
 
276
                *x = 80; *y = 24;
 
277
                return 0;
 
278
#endif
 
279
        } else {
 
280
                int a[2] = { 0, 0 };
 
281
                _scrsize(a);
 
282
                *x = a[0];
 
283
                *y = a[1];
 
284
                set_default:
 
285
                if (*x == 0) {
 
286
                        *x = get_e("COLUMNS");
 
287
                        if (*x == 0) *x = 80;
 
288
                }
 
289
                if (*y == 0) {
 
290
                        *y = get_e("LINES");
 
291
                        if (*y == 0) *y = 24;
 
292
                }
 
293
        }
 
294
        return 0;
 
295
}
 
296
 
 
297
#elif defined(WIN32)
 
298
 
 
299
#endif
 
300
 
 
301
/* Pipe */
 
302
 
 
303
#if defined(UNIX) || defined(BEOS) || defined(RISCOS) || defined(ATHEOS) || defined(SPAD)
 
304
 
 
305
void set_bin(int fd)
 
306
{
 
307
}
 
308
 
 
309
int c_pipe(int *fd)
 
310
{
 
311
        return pipe(fd);
 
312
}
 
313
 
 
314
#elif defined(OS2) || defined(WIN32)
 
315
 
 
316
void set_bin(int fd)
 
317
{
 
318
        setmode(fd, O_BINARY);
 
319
}
 
320
 
 
321
int c_pipe(int *fd)
 
322
{
 
323
        int r = pipe(fd);
 
324
        if (!r) set_bin(fd[0]), set_bin(fd[1]);
 
325
        return r;
 
326
}
 
327
 
 
328
#endif
 
329
 
 
330
/* Filename */
 
331
 
 
332
int check_file_name(unsigned char *file)
 
333
{
 
334
        return 1;               /* !!! FIXME */
 
335
}
 
336
 
 
337
/* Exec */
 
338
 
 
339
int can_twterm(void) /* Check if it make sense to call a twterm. */
 
340
{
 
341
        static int xt = -1;
 
342
        if (xt == -1) xt = !!getenv("TWDISPLAY");
 
343
        return xt;
 
344
}
 
345
 
 
346
 
 
347
#if defined(UNIX) || defined(SPAD)
 
348
 
 
349
int is_xterm(void)
 
350
{
 
351
        static int xt = -1;
 
352
        if (xt == -1) xt = getenv("DISPLAY") && *getenv("DISPLAY");
 
353
        return xt;
 
354
}
 
355
 
 
356
#elif defined(BEOS) || defined(ATHEOS)
 
357
 
 
358
int is_xterm(void)
 
359
{
 
360
        return 0;
 
361
}
 
362
 
 
363
#elif defined(WIN32)
 
364
 
 
365
int is_xterm(void)
 
366
{
 
367
        static int xt = -1;
 
368
        if (xt == -1) xt = !!getenv("WINDOWID");
 
369
        return xt;
 
370
}
 
371
 
 
372
#elif defined(RISCOS)
 
373
 
 
374
int is_xterm(void)
 
375
{
 
376
       return 1;
 
377
}
 
378
 
 
379
#endif
 
380
 
 
381
tcount resize_count = 0;
 
382
 
 
383
void close_fork_tty(void)
 
384
{
 
385
        struct terminal *t;
 
386
        struct download *d;
 
387
        struct connection *c;
 
388
        struct k_conn *k;
 
389
        foreach (t, terminals) if (t->fdin > 0) close(t->fdin);
 
390
        foreach (d, downloads) if (d->handle > 0) close(d->handle);
 
391
        foreach (c, queue) close_socket(&c->sock1), close_socket(&c->sock2);
 
392
        foreach (k, keepalive_connections) close(k->conn);
 
393
}
 
394
 
 
395
#if defined(WIN32)
 
396
 
 
397
void get_path_to_exe(void)
 
398
{
 
399
        /* Standard method (argv[0]) doesn't work, if links is executed from
 
400
           symlink --- it returns symlink name and cmd.exe is unable to start
 
401
           it */
 
402
        unsigned r;
 
403
        static unsigned char path[4096];
 
404
        r = GetModuleFileName(NULL, path, sizeof path);
 
405
        if (r <= 0 || r >= sizeof path) {
 
406
                path_to_exe = g_argv[0];
 
407
                return;
 
408
        }
 
409
        path_to_exe = path;
 
410
}
 
411
 
 
412
#elif defined(OS2)
 
413
 
 
414
void get_path_to_exe(void)
 
415
{
 
416
        /* If you spawn links with quotation marks from cmd.exe,
 
417
           the quotation marks will be present in g_argv[0] ... and will
 
418
           prevent executing it */
 
419
        static char path[270];
 
420
        PPIB pib = NULL;
 
421
        path_to_exe = g_argv[0];
 
422
        /*if (!strchr(path_to_exe, ' ') && !strchr(path_to_exe, '"')) return;*/
 
423
        DosGetInfoBlocks(NULL, &pib);
 
424
        if (!pib) return;
 
425
        if (DosQueryModuleName(pib->pib_hmte, sizeof path, path)) return;
 
426
        path_to_exe = path;
 
427
}
 
428
 
 
429
#else
 
430
 
 
431
void get_path_to_exe(void)
 
432
{
 
433
        path_to_exe = g_argv[0];
 
434
}
 
435
 
 
436
#endif
 
437
 
 
438
#if defined(UNIX) || defined(BEOS) || defined(RISCOS) || defined(ATHEOS) || defined(SPAD)
 
439
 
 
440
#if defined(BEOS) && defined(HAVE_SETPGID)
 
441
 
 
442
int exe(char *path, int fg)
 
443
{
 
444
        pid_t p;
 
445
        int s;
 
446
        fg=fg;  /* ignore flag */
 
447
        if (!(p = fork())) {
 
448
                setpgid(0, 0);
 
449
                system(path);
 
450
                _exit(0);
 
451
        }
 
452
        if (p > 0) waitpid(p, &s, 0);
 
453
        else return system(path);
 
454
        return 0;
 
455
}
 
456
 
 
457
#else
 
458
 
 
459
/* UNIX */
 
460
int exe(char *path, int fg)
 
461
{
 
462
#ifdef G
 
463
        if (F && drv->exec) return drv->exec(path, fg);
 
464
#endif
 
465
#ifdef SIGTSTP
 
466
        signal(SIGTSTP, SIG_DFL);
 
467
#endif
 
468
#ifdef SIGCONT
 
469
        signal(SIGCONT, SIG_DFL);
 
470
#endif
 
471
#ifdef SIGWINCH
 
472
        signal(SIGWINCH, SIG_DFL);
 
473
#endif
 
474
        return system(path);
 
475
}
 
476
 
 
477
#endif
 
478
 
 
479
/* clipboard -> links */
 
480
unsigned char *get_clipboard_text(struct terminal *term)
 
481
{
 
482
#ifdef GRDRV_X
 
483
        if(term && term->dev && term->dev->drv && !strcmp(term->dev->drv->name,"x")) {
 
484
                return x_get_clipboard_text();
 
485
        }
 
486
#endif
 
487
        return stracpy(clipboard);
 
488
}
 
489
 
 
490
/* links -> clipboard */
 
491
void set_clipboard_text(struct terminal *term, unsigned char *data)
 
492
{
 
493
#ifdef GRDRV_X
 
494
        if(term && term->dev && term->dev->drv && !strcmp(term->dev->drv->name,"x")) {
 
495
                x_set_clipboard_text(term->dev, data);
 
496
                return;
 
497
        }
 
498
#endif
 
499
        if (clipboard) mem_free(clipboard);
 
500
        clipboard = stracpy(data);
 
501
}
 
502
 
 
503
int clipboard_support(struct terminal *term)
 
504
{
 
505
#ifdef GRDRV_X
 
506
        if(term && term->dev && term->dev->drv && !strcmp(term->dev->drv->name,"x")) {
 
507
                return 1;
 
508
        }
 
509
#endif
 
510
        return 0;
 
511
}
 
512
 
 
513
void set_window_title(unsigned char *title)
 
514
{
 
515
        /* !!! FIXME */
 
516
}
 
517
 
 
518
unsigned char *get_window_title(void)
 
519
{
 
520
        /* !!! FIXME */
 
521
        return NULL;
 
522
}
 
523
 
 
524
int resize_window(int x, int y)
 
525
{
 
526
        return -1;
 
527
}
 
528
 
 
529
#elif defined(WIN32)
 
530
 
 
531
static int is_winnt(void)
 
532
{
 
533
        OSVERSIONINFO v;
 
534
        v.dwOSVersionInfoSize = sizeof v;
 
535
        if (!GetVersionEx(&v)) return 0;
 
536
        return v.dwPlatformId >= VER_PLATFORM_WIN32_NT;
 
537
}
 
538
 
 
539
#define WIN32_START_STRING      "start /wait "
 
540
 
 
541
int exe(char *path, int fg)
 
542
{
 
543
        /* This is very tricky. We must have exactly 3 arguments, the first
 
544
           one shell and the second one "/c", otherwise Cygwin would quote
 
545
           the arguments and trash them */
 
546
        int ct;
 
547
        char buffer[1024];
 
548
        char buffer2[1024];
 
549
        pid_t pid;
 
550
        unsigned char *x1;
 
551
        char *arg;
 
552
        x1 = GETSHELL;
 
553
        if (!x1) x1 = DEFAULT_SHELL;
 
554
        arg = alloca(strlen(WIN32_START_STRING) + 3 + strlen(path) + 1);
 
555
        strcpy(arg, WIN32_START_STRING);
 
556
        if (*path == '"' && strlen(x1) >= 7 && !strcasecmp(x1 + strlen(x1) - 7, "cmd.exe")) strcat(arg, "\"\" ");
 
557
        strcat(arg, path);
 
558
        ct = GetConsoleTitle(buffer, sizeof buffer);
 
559
        if (!(pid = fork())) {
 
560
                int i;
 
561
        /* Win98 crashes if we spawn command.com and have some sockets open */
 
562
                for (i = 0; i < FD_SETSIZE; i++) close(i);
 
563
                open("nul", O_RDONLY);
 
564
                open("nul", O_WRONLY);
 
565
                open("nul", O_WRONLY);
 
566
                execlp(x1, x1, "/c", arg, NULL);
 
567
                _exit(1);
 
568
        }
 
569
        if (!is_winnt()) {
 
570
                sleep(1);
 
571
                if (ct && GetConsoleTitle(buffer2, sizeof buffer2) && !casecmp(buffer2, "start", 5)) {
 
572
                        SetConsoleTitle(buffer);
 
573
                }
 
574
        }
 
575
        if (pid != -1) waitpid(pid, NULL, 0);
 
576
        return 0;
 
577
}
 
578
 
 
579
unsigned char *get_clipboard_text(struct terminal *term)
 
580
{
 
581
        char buffer[256];
 
582
        unsigned char *str, *s, *d;
 
583
        int l;
 
584
        int r;
 
585
        int h = open("/dev/clipboard", O_RDONLY);
 
586
        if (h == -1) return stracpy(clipboard);
 
587
        set_bin(h);     /* O_TEXT doesn't work on clipboard handle */
 
588
        str = init_str();
 
589
        l = 0;
 
590
        while ((r = hard_read(h, buffer, sizeof buffer)) > 0)
 
591
                add_bytes_to_str(&str, &l, buffer, r);
 
592
        close(h);
 
593
        for (s = str, d = str; *s; s++)
 
594
                if (!(s[0] == '\r' && s[1] == '\n')) *d++ = *s;
 
595
        *d = 0;
 
596
        return str;
 
597
}
 
598
 
 
599
/* Putting Czech characters to clipboard doesn't work, but it should be fixed
 
600
   rather in Cygwin than here */
 
601
void set_clipboard_text(struct terminal *term, unsigned char *data)
 
602
{
 
603
        unsigned char *conv_data;
 
604
        int l;
 
605
        int h;
 
606
        if (clipboard) mem_free(clipboard);
 
607
        clipboard = stracpy(data);
 
608
        h = open("/dev/clipboard", O_WRONLY);
 
609
        if (h == -1) return;
 
610
        set_bin(h);     /* O_TEXT doesn't work on clipboard handle */
 
611
        conv_data = init_str();
 
612
        l = 0;
 
613
        for (; *data; data++)
 
614
                if (*data == '\n') add_to_str(&conv_data, &l, "\r\n");
 
615
                else add_chr_to_str(&conv_data, &l, *data);
 
616
        hard_write(h, conv_data, l);
 
617
        mem_free(conv_data);
 
618
        close(h);
 
619
}
 
620
 
 
621
int clipboard_support(struct terminal *term)
 
622
{
 
623
        return 1;
 
624
}
 
625
 
 
626
 
 
627
static int get_windows_cp(void)
 
628
{
 
629
        char str[6];
 
630
        int cp, idx;
 
631
        static int win_cp_idx = -1;
 
632
        if (win_cp_idx != -1) return win_cp_idx;
 
633
        cp = GetConsoleOutputCP();
 
634
        if (cp <= 0 || cp >= 100000) return 0;
 
635
        sprintf(str, "%d", cp);
 
636
        if ((idx = get_cp_index(str)) < 0) return 0;
 
637
        win_cp_idx = idx;
 
638
        return idx;
 
639
}
 
640
 
 
641
static int get_utf8_cp(void)
 
642
{
 
643
        static int idx = -1;
 
644
        return idx >= 0 ? idx : (idx = get_cp_index("utf-8"));
 
645
}
 
646
 
 
647
void set_window_title(unsigned char *title)
 
648
{
 
649
        unsigned char *t;
 
650
        struct conv_table *ct;
 
651
        if (is_xterm()) return;
 
652
        ct = get_translation_table(get_utf8_cp(), get_windows_cp());
 
653
        t = convert_string(ct, title, strlen(title), NULL);
 
654
        SetConsoleTitle(t);
 
655
        mem_free(t);
 
656
}
 
657
 
 
658
unsigned char *get_window_title(void)
 
659
{
 
660
        struct conv_table *ct;
 
661
        int r;
 
662
        char buffer[1024];
 
663
        if (is_xterm()) return NULL;
 
664
        if (!(r = GetConsoleTitle(buffer, sizeof buffer))) return NULL;
 
665
        ct = get_translation_table(get_windows_cp(), get_utf8_cp());
 
666
        return convert_string(ct, buffer, r, NULL);
 
667
}
 
668
 
 
669
static void call_resize(unsigned char *x1, int x, int y)
 
670
{
 
671
        pid_t pid;
 
672
        unsigned char arg[40];
 
673
        sprintf(arg, "mode %d,%d", x, y);
 
674
        if (!(pid = fork())) {
 
675
                int i;
 
676
        /* Win98 crashes if we spawn command.com and have some sockets open */
 
677
                for (i = 0; i < FD_SETSIZE; i++) if (i != 1 && i != 2) close(i);
 
678
                open("nul", O_WRONLY);
 
679
                execlp(x1, x1, "/c", arg, NULL);
 
680
                _exit(1);
 
681
        }
 
682
        if (pid != -1) waitpid(pid, NULL, 0);
 
683
}
 
684
 
 
685
int resize_window(int x, int y)
 
686
{
 
687
        int old_x, old_y;
 
688
        int ct = 0, fullscreen = 0;
 
689
        char buffer[1024];
 
690
        unsigned char *x1;
 
691
        if (is_xterm()) return -1;
 
692
        if (get_terminal_size(1, &old_x, &old_y)) return -1;
 
693
        x1 = GETSHELL;
 
694
        if (!x1) x1 = DEFAULT_SHELL;
 
695
        if (!is_winnt()) {
 
696
                ct = GetConsoleTitle(buffer, sizeof buffer);
 
697
        }
 
698
 
 
699
        call_resize(x1, x, y);
 
700
        if (!is_winnt()) {
 
701
                int new_x, new_y;
 
702
        /* If we resize console on Win98 in fullscreen mode, it won't be
 
703
           notified by Cygwin (it is valid for all Cygwin apps). So we must
 
704
           switch to windowed mode, resize it again (twice, because resizing
 
705
           to the same size won't have an effect) and switch back to full-screen
 
706
           mode. */
 
707
        /* I'm not sure what's the behavior on WinNT 4. Anybody wants to test?
 
708
           */
 
709
                if (!fullscreen && !get_terminal_size(1, &new_x, &new_y) && (new_x != x || new_y != y)) {
 
710
                        fullscreen = 1;
 
711
                        keybd_event(VK_MENU, 0x38, 0, 0);
 
712
                        keybd_event(VK_RETURN, 0x1c, 0, 0);
 
713
                        keybd_event(VK_RETURN, 0x1c, KEYEVENTF_KEYUP, 0);
 
714
                        keybd_event(VK_MENU, 0x38, KEYEVENTF_KEYUP, 0);
 
715
                        if (y != 25) call_resize(x1, 80, 25);
 
716
                        else call_resize(x1, 80, 50);
 
717
                        call_resize(x1, x, y);
 
718
                        if (get_terminal_size(1, &new_x, &new_y) || new_x != x || new_y != y) call_resize(x1, old_x, old_y);
 
719
                        keybd_event(VK_MENU, 0x38, 0, 0);
 
720
                        keybd_event(VK_RETURN, 0x1c, 0, 0);
 
721
                        keybd_event(VK_RETURN, 0x1c, KEYEVENTF_KEYUP, 0);
 
722
                        keybd_event(VK_MENU, 0x38, KEYEVENTF_KEYUP, 0);
 
723
                }
 
724
                if (ct) SetConsoleTitle(buffer);
 
725
        }
 
726
        return 0;
 
727
}
 
728
 
 
729
#elif defined(OS2)
 
730
 
 
731
#ifdef G
 
732
_fmutex fd_mutex;
 
733
int fd_mutex_init = 0;
 
734
#endif
 
735
 
 
736
int exe(char *path, int fg)
 
737
{
 
738
        int flags = P_SESSION;
 
739
        pid_t pid;
 
740
        int ret;
 
741
#ifdef G
 
742
        int old0 = 0, old1 = 1, old2 = 2;
 
743
#endif
 
744
        char *shell;
 
745
        fg=fg; /* ignore flag */
 
746
        if (!(shell = GETSHELL)) shell = DEFAULT_SHELL;
 
747
        if (is_xterm()) flags |= P_BACKGROUND;
 
748
#ifdef G
 
749
        if (F) {
 
750
                if (!fd_mutex_init) {
 
751
                        if (_fmutex_create(&fd_mutex, 0)) return -1;
 
752
                        fd_mutex_init = 1;
 
753
                }
 
754
                _fmutex_request(&fd_mutex, _FMR_IGNINT);
 
755
                old0 = dup(0);
 
756
                old1 = dup(1);
 
757
                old2 = dup(2);
 
758
                close(0);
 
759
                close(1);
 
760
                close(2);
 
761
                open("con", O_RDONLY);
 
762
                open("con", O_WRONLY);
 
763
                open("con", O_WRONLY);
 
764
        }
 
765
#endif
 
766
        pid = spawnlp(flags, shell, shell, "/c", path, NULL);
 
767
#ifdef G
 
768
        if (F) {
 
769
                dup2(old0, 0);
 
770
                dup2(old1, 1);
 
771
                dup2(old2, 2);
 
772
                close(old0);
 
773
                close(old1);
 
774
                close(old2);
 
775
                _fmutex_release(&fd_mutex);
 
776
        }
 
777
#endif
 
778
        if (pid != -1) waitpid(pid, &ret, 0);
 
779
        else ret = -1;
 
780
        return ret;
 
781
}
 
782
 
 
783
unsigned char *get_clipboard_text(struct terminal *term)
 
784
{
 
785
        PTIB tib;
 
786
        PPIB pib;
 
787
        HAB hab;
 
788
        HMQ hmq;
 
789
        ULONG oldType;
 
790
        char *ret = NULL;
 
791
 
 
792
        DosGetInfoBlocks(&tib, &pib);
 
793
 
 
794
        oldType = pib->pib_ultype;
 
795
 
 
796
        pib->pib_ultype = 3;
 
797
 
 
798
        if ((hab = WinInitialize(0)) != NULLHANDLE) {
 
799
                if ((hmq = WinCreateMsgQueue(hab, 0)) != NULLHANDLE) {
 
800
 
 
801
                        if (WinOpenClipbrd(hab)) {
 
802
                                ULONG fmtInfo = 0;
 
803
 
 
804
                                if (WinQueryClipbrdFmtInfo(hab, CF_TEXT, &fmtInfo)!=FALSE)
 
805
                                {
 
806
                                        ULONG selClipText = WinQueryClipbrdData(hab, CF_TEXT);
 
807
 
 
808
                                        if (selClipText)
 
809
                                        {
 
810
                                                char *u;
 
811
                                                PCHAR pchClipText = (PCHAR)selClipText;
 
812
                                                ret = mem_alloc(strlen(pchClipText)+1);
 
813
                                                strcpy(ret, pchClipText);
 
814
                                                while ((u = strchr(ret, 13))) memmove(u, u + 1, strlen(u + 1) + 1);
 
815
                                        }
 
816
                                }
 
817
 
 
818
                                WinCloseClipbrd(hab);
 
819
                        }
 
820
 
 
821
#ifdef G
 
822
                        if (F && ret) {
 
823
                                static int cp = -1;
 
824
                                struct conv_table *ct;
 
825
                                unsigned char *d;
 
826
                                if (cp == -1) {
 
827
                                        int c = WinQueryCp(hmq);
 
828
                                        unsigned char a[64];
 
829
                                        snprintf(a, 64, "%d", c);
 
830
                                        if ((cp = get_cp_index(a)) < 0 || is_cp_special(cp)) cp = 0;
 
831
                                }
 
832
                                ct = get_translation_table(cp, get_cp_index("utf-8"));
 
833
                                d = convert_string(ct, ret, strlen(ret), NULL);
 
834
                                mem_free(ret);
 
835
                                ret = d;
 
836
                        }
 
837
#endif
 
838
                        WinDestroyMsgQueue(hmq);
 
839
                }
 
840
                WinTerminate(hab);
 
841
        }
 
842
 
 
843
        pib->pib_ultype = oldType;
 
844
 
 
845
        return ret;
 
846
}
 
847
 
 
848
void set_clipboard_text(struct terminal * term, unsigned char *data)
 
849
{
 
850
        PTIB tib;
 
851
        PPIB pib;
 
852
        HAB hab;
 
853
        HMQ hmq;
 
854
        ULONG oldType;
 
855
 
 
856
        unsigned char *d = NULL;
 
857
        
 
858
        DosGetInfoBlocks(&tib, &pib);
 
859
 
 
860
        oldType = pib->pib_ultype;
 
861
 
 
862
        pib->pib_ultype = 3;
 
863
 
 
864
        if ((hab = WinInitialize(0)) != NULLHANDLE) {
 
865
                if ((hmq = WinCreateMsgQueue(hab, 0)) != NULLHANDLE) {
 
866
#ifdef G
 
867
                        if (F) {
 
868
                                static int cp = -1;
 
869
                                struct conv_table *ct;
 
870
                                if (cp == -1) {
 
871
                                        int c = WinQueryCp(hmq);
 
872
                                        unsigned char a[64];
 
873
                                        snprintf(a, 64, "%d", c);
 
874
                                        if ((cp = get_cp_index(a)) < 0 || is_cp_special(cp)) cp = 0;
 
875
                                }
 
876
                                ct = get_translation_table(get_cp_index("utf-8"), cp);
 
877
                                d = convert_string(ct, data, strlen(data), NULL);
 
878
                                data = d;
 
879
                        }
 
880
#endif
 
881
                        if(WinOpenClipbrd(hab)) {
 
882
                                PVOID pvShrObject = NULL;
 
883
                                if (DosAllocSharedMem(&pvShrObject, NULL, strlen(data)+1, PAG_COMMIT | PAG_WRITE | OBJ_GIVEABLE) == NO_ERROR) {
 
884
                                        strcpy(pvShrObject, data);
 
885
                                        WinEmptyClipbrd(hab);
 
886
                                        WinSetClipbrdData(hab, (ULONG)pvShrObject, CF_TEXT, CFI_POINTER);
 
887
                                }
 
888
                                WinCloseClipbrd(hab);
 
889
                        }
 
890
                        WinDestroyMsgQueue(hmq);
 
891
                }
 
892
                WinTerminate(hab);
 
893
        }
 
894
 
 
895
        pib->pib_ultype = oldType;
 
896
 
 
897
        if (d) mem_free(d);
 
898
}
 
899
 
 
900
int clipboard_support(struct terminal *term)
 
901
{
 
902
        return 1;
 
903
}
 
904
 
 
905
unsigned char *get_window_title(void)
 
906
{
 
907
#ifndef OS2_DEBUG
 
908
        /*char *org_switch_title;*/
 
909
        char *org_win_title = NULL;
 
910
        static PTIB tib = NULL;
 
911
        static PPIB pib = NULL;
 
912
        ULONG oldType;
 
913
        HSWITCH hSw = NULLHANDLE;
 
914
        SWCNTRL swData;
 
915
        HAB hab;
 
916
        HMQ hmq;
 
917
 
 
918
        /* save current process title */
 
919
 
 
920
        if (!pib) DosGetInfoBlocks(&tib, &pib);
 
921
        oldType = pib->pib_ultype;
 
922
        memset(&swData, 0, sizeof swData);
 
923
        if (hSw == NULLHANDLE) hSw = WinQuerySwitchHandle(0, pib->pib_ulpid);
 
924
        if (hSw!=NULLHANDLE && !WinQuerySwitchEntry(hSw, &swData)) {
 
925
                /*org_switch_title = mem_alloc(strlen(swData.szSwtitle)+1);
 
926
                strcpy(org_switch_title, swData.szSwtitle);*/
 
927
                /* Go to PM */
 
928
                pib->pib_ultype = 3;
 
929
                if ((hab = WinInitialize(0)) != NULLHANDLE) {
 
930
                        if ((hmq = WinCreateMsgQueue(hab, 0)) != NULLHANDLE) {
 
931
                                org_win_title = mem_alloc(MAXNAMEL+1);
 
932
                                WinQueryWindowText(swData.hwnd, MAXNAMEL+1, org_win_title);
 
933
                                org_win_title[MAXNAMEL] = 0;
 
934
                                /* back From PM */
 
935
                                WinDestroyMsgQueue(hmq);
 
936
                        }
 
937
                        WinTerminate(hab);
 
938
                }
 
939
                pib->pib_ultype = oldType;
 
940
        }
 
941
        return org_win_title;
 
942
#else
 
943
        return NULL;
 
944
#endif
 
945
}
 
946
 
 
947
void set_window_title(unsigned char *title)
 
948
{
 
949
#ifndef OS2_DEBUG
 
950
        static PTIB tib;
 
951
        static PPIB pib;
 
952
        ULONG oldType;
 
953
        static HSWITCH hSw;
 
954
        SWCNTRL swData;
 
955
        HAB hab;
 
956
        HMQ hmq;
 
957
        if (!title) return;
 
958
        if (!pib) DosGetInfoBlocks(&tib, &pib);
 
959
        oldType = pib->pib_ultype;
 
960
        memset(&swData, 0, sizeof swData);
 
961
        if (hSw == NULLHANDLE) hSw = WinQuerySwitchHandle(0, pib->pib_ulpid);
 
962
        if (hSw!=NULLHANDLE && !WinQuerySwitchEntry(hSw, &swData)) {
 
963
                strncpy(swData.szSwtitle, title, MAXNAMEL-1);
 
964
                swData.szSwtitle[MAXNAMEL-1] = 0;
 
965
                WinChangeSwitchEntry(hSw, &swData);
 
966
                /* Go to PM */
 
967
                pib->pib_ultype = 3;
 
968
                if ((hab = WinInitialize(0)) != NULLHANDLE) {
 
969
                        if ((hmq = WinCreateMsgQueue(hab, 0)) != NULLHANDLE) {
 
970
                                if(swData.hwnd)
 
971
                                        WinSetWindowText(swData.hwnd, title);
 
972
                                        /* back From PM */
 
973
                                WinDestroyMsgQueue(hmq);
 
974
                        }
 
975
                        WinTerminate(hab);
 
976
                }
 
977
        }
 
978
        pib->pib_ultype = oldType;
 
979
#endif
 
980
}
 
981
 
 
982
int resize_window(int x, int y)
 
983
{
 
984
        int xfont, yfont;
 
985
        A_DECL(VIOMODEINFO, vmi);
 
986
        resize_count++;
 
987
        if (is_xterm()) return -1;
 
988
        vmi->cb = sizeof(*vmi);
 
989
        if (VioGetMode(vmi, 0)) return -1;
 
990
        vmi->col = x;
 
991
        vmi->row = y;
 
992
        /*debug("%d %d %d", vmi->buf_length, vmi->full_length, vmi->partial_length);*/
 
993
        for (xfont = 9; xfont >= 8; xfont--)
 
994
                for (yfont = 16; yfont >= 8; yfont--) {
 
995
                        vmi->hres = x * xfont;
 
996
                        vmi->vres = y * yfont;
 
997
                        if (vmi->vres <= 400) vmi->vres = 400;
 
998
                        else if (vmi->vres <= 480) vmi->vres = 480;
 
999
                        vmi->buf_length = vmi->full_length = vmi->partial_length = x * ((vmi->vres + yfont - 1) / yfont) * 2;
 
1000
                        vmi->full_length = (vmi->full_length + 4095) & ~4095;
 
1001
                        vmi->partial_length = (vmi->partial_length + 4095) & ~4095;
 
1002
                        if (!VioSetMode(vmi, 0)) return 0;
 
1003
                }
 
1004
        return -1;
 
1005
}
 
1006
 
 
1007
#endif
 
1008
 
 
1009
/* Threads */
 
1010
 
 
1011
struct tdata {
 
1012
        void (*fn)(void *, int);
 
1013
        int h;
 
1014
        unsigned char data[1];
 
1015
};
 
1016
 
 
1017
#if defined(HAVE_BEGINTHREAD) || defined(BEOS) || defined(HAVE_PTHREADS) || defined(HAVE_ATHEOS_THREADS_H)
 
1018
 
 
1019
static void bgt(struct tdata *t)
 
1020
{
 
1021
        ignore_signals();
 
1022
        t->fn(t->data, t->h);
 
1023
        write(t->h, "x", 1);
 
1024
        close(t->h);
 
1025
        free(t);
 
1026
}
 
1027
 
 
1028
#ifdef HAVE_PTHREADS
 
1029
static void *bgpt(struct tdata *t)
 
1030
{
 
1031
        bgt(t);
 
1032
        return NULL;
 
1033
}
 
1034
#endif
 
1035
 
 
1036
#ifdef HAVE_ATHEOS_THREADS_H
 
1037
#include <atheos/threads.h>
 
1038
static uint32 abgt(void *t)
 
1039
{
 
1040
        bgt(t);
 
1041
        return 0;
 
1042
}
 
1043
#endif
 
1044
 
 
1045
#endif
 
1046
 
 
1047
#if defined(UNIX) || defined(OS2) || defined(RISCOS) || defined(ATHEOS) || defined(SPAD) || defined(WIN32)
 
1048
 
 
1049
void terminate_osdep(void) {}
 
1050
 
 
1051
#endif
 
1052
 
 
1053
#ifndef BEOS
 
1054
 
 
1055
void block_stdin(void) {}
 
1056
void unblock_stdin(void) {}
 
1057
 
 
1058
#endif
 
1059
 
 
1060
#if defined(BEOS)
 
1061
 
 
1062
#include <be/kernel/OS.h>
 
1063
 
 
1064
int thr_sem_init = 0;
 
1065
sem_id thr_sem;
 
1066
 
 
1067
struct list_head active_threads = { &active_threads, &active_threads };
 
1068
 
 
1069
struct active_thread {
 
1070
        struct active_thread *next;
 
1071
        struct active_thread *prev;
 
1072
        thread_id tid;
 
1073
        void (*fn)(void *);
 
1074
        void *data;
 
1075
};
 
1076
 
 
1077
int32 started_thr(void *data)
 
1078
{
 
1079
        struct active_thread *thrd = data;
 
1080
        thrd->fn(thrd->data);
 
1081
        if (acquire_sem(thr_sem) < B_NO_ERROR) return 0;
 
1082
        del_from_list(thrd);
 
1083
        free(thrd);
 
1084
        release_sem(thr_sem);
 
1085
        return 0;
 
1086
}
 
1087
 
 
1088
int start_thr(void (*fn)(void *), void *data, unsigned char *name)
 
1089
{
 
1090
        struct active_thread *thrd;
 
1091
        int tid;
 
1092
        if (!thr_sem_init) {
 
1093
                if ((thr_sem = create_sem(0, "thread_sem")) < B_NO_ERROR) return -1;
 
1094
                thr_sem_init = 1;
 
1095
        } else if (acquire_sem(thr_sem) < B_NO_ERROR) return -1;
 
1096
        if (!(thrd = malloc(sizeof(struct active_thread)))) goto rel;
 
1097
        thrd->fn = fn;
 
1098
        thrd->data = data;
 
1099
        if ((tid = thrd->tid = spawn_thread(started_thr, name, B_NORMAL_PRIORITY, thrd)) < B_NO_ERROR) {
 
1100
                free(thrd);
 
1101
                rel:
 
1102
                release_sem(thr_sem);
 
1103
                return -1;
 
1104
        }
 
1105
        resume_thread(thrd->tid);
 
1106
        add_to_list(active_threads, thrd);
 
1107
        release_sem(thr_sem);
 
1108
        return tid;
 
1109
}
 
1110
 
 
1111
void terminate_osdep(void)
 
1112
{
 
1113
        struct list_head *p;
 
1114
        struct active_thread *thrd;
 
1115
        if (acquire_sem(thr_sem) < B_NO_ERROR) return;
 
1116
        foreach(thrd, active_threads) kill_thread(thrd->tid);
 
1117
        while ((p = active_threads.next) != &active_threads) {
 
1118
                del_from_list(p);
 
1119
                free(p);
 
1120
        }
 
1121
        release_sem(thr_sem);
 
1122
}
 
1123
 
 
1124
int start_thread(void (*fn)(void *, int), void *ptr, int l)
 
1125
{
 
1126
        int p[2];
 
1127
        struct tdata *t;
 
1128
        if (c_pipe(p) < 0) return -1;
 
1129
        if (!(t = malloc(sizeof(struct tdata) + l))) return -1;
 
1130
        t->fn = fn;
 
1131
        t->h = p[1];
 
1132
        memcpy(t->data, ptr, l);
 
1133
        if (start_thr((void (*)(void *))bgt, t, "links_thread") < 0) {
 
1134
                close(p[0]);
 
1135
                close(p[1]);
 
1136
                mem_free(t);
 
1137
                return -1;
 
1138
        }
 
1139
        return p[0];
 
1140
}
 
1141
 
 
1142
 
 
1143
#elif defined(HAVE_BEGINTHREAD)
 
1144
 
 
1145
int start_thread(void (*fn)(void *, int), void *ptr, int l)
 
1146
{
 
1147
        int p[2];
 
1148
        struct tdata *t;
 
1149
        if (c_pipe(p) < 0) return -1;
 
1150
        fcntl(p[0], F_SETFL, O_NONBLOCK);
 
1151
        fcntl(p[1], F_SETFL, O_NONBLOCK);
 
1152
        if (!(t = malloc(sizeof(struct tdata) + l))) return -1;
 
1153
        t->fn = fn;
 
1154
        t->h = p[1];
 
1155
        memcpy(t->data, ptr, l);
 
1156
        if (_beginthread((void (*)(void *))bgt, NULL, 65536, t) == -1) {
 
1157
                close(p[0]);
 
1158
                close(p[1]);
 
1159
                mem_free(t);
 
1160
                return -1;
 
1161
        }
 
1162
        return p[0];
 
1163
}
 
1164
 
 
1165
#ifdef HAVE_READ_KBD
 
1166
 
 
1167
int tp = -1;
 
1168
int ti = -1;
 
1169
 
 
1170
static void input_thread(void *p)
 
1171
{
 
1172
        char c[2];
 
1173
        int h = (int)p;
 
1174
        ignore_signals();
 
1175
        while (1) {
 
1176
                /*c[0] = _read_kbd(0, 1, 1);
 
1177
                if (c[0]) if (write(h, c, 1) <= 0) break;
 
1178
                else {
 
1179
                        int w;
 
1180
                        printf("1");fflush(stdout);
 
1181
                        c[1] = _read_kbd(0, 1, 1);
 
1182
                        printf("2");fflush(stdout);
 
1183
                        w = write(h, c, 2);
 
1184
                        printf("3");fflush(stdout);
 
1185
                        if (w <= 0) break;
 
1186
                        if (w == 1) if (write(h, c+1, 1) <= 0) break;
 
1187
                        printf("4");fflush(stdout);
 
1188
                }*/
 
1189
           /* for the records: 
 
1190
                 _read_kbd(0, 1, 1) will
 
1191
                 read a char, don't echo it, wait for one available and
 
1192
                 accept CTRL-C.
 
1193
                 Knowing that, I suggest we replace this call completly!
 
1194
            */
 
1195
                *c = _read_kbd(0, 1, 1);
 
1196
                write(h, c, 1);
 
1197
        }
 
1198
        close(h);
 
1199
}
 
1200
#endif /* #ifdef HAVE_READ_KBD */
 
1201
 
 
1202
#if defined(HAVE_MOUOPEN) && !defined(USE_GPM)
 
1203
 
 
1204
#define USING_OS2_MOUSE
 
1205
 
 
1206
#ifdef HAVE_SYS_FMUTEX_H
 
1207
_fmutex mouse_mutex;
 
1208
int mouse_mutex_init = 0;
 
1209
#endif
 
1210
int mouse_h = -1;
 
1211
 
 
1212
struct os2_mouse_spec {
 
1213
        int p[2];
 
1214
        void (*fn)(void *, unsigned char *, int);
 
1215
        void *data;
 
1216
        unsigned char buffer[sizeof(struct event)];
 
1217
        int bufptr;
 
1218
        int terminate;
 
1219
};
 
1220
 
 
1221
static void mouse_thread(void *p)
 
1222
{
 
1223
        int status;
 
1224
        struct os2_mouse_spec *oms = p;
 
1225
        A_DECL(HMOU, mh);
 
1226
        A_DECL(MOUEVENTINFO, ms);
 
1227
        A_DECL(USHORT, rd);
 
1228
        A_DECL(USHORT, mask);
 
1229
        struct event ev;
 
1230
        ignore_signals();
 
1231
        ev.ev = EV_MOUSE;
 
1232
        if (MouOpen(NULL, mh)) goto ret;
 
1233
        mouse_h = *mh;
 
1234
        *mask = MOUSE_MOTION_WITH_BN1_DOWN | MOUSE_BN1_DOWN |
 
1235
                MOUSE_MOTION_WITH_BN2_DOWN | MOUSE_BN2_DOWN |
 
1236
                MOUSE_MOTION_WITH_BN3_DOWN | MOUSE_BN3_DOWN |
 
1237
                MOUSE_MOTION;
 
1238
        MouSetEventMask(mask, *mh);
 
1239
        *rd = MOU_WAIT;
 
1240
        status = -1;
 
1241
        while (1) {
 
1242
                /*int w, ww;*/
 
1243
                if (MouReadEventQue(ms, rd, *mh)) break;
 
1244
#ifdef HAVE_SYS_FMUTEX_H
 
1245
                _fmutex_request(&mouse_mutex, _FMR_IGNINT);
 
1246
#endif
 
1247
                if (!oms->terminate) MouDrawPtr(*mh);
 
1248
#ifdef HAVE_SYS_FMUTEX_H
 
1249
                _fmutex_release(&mouse_mutex);
 
1250
#endif
 
1251
                ev.x = ms->col;
 
1252
                ev.y = ms->row;
 
1253
                /*debug("status: %d %d %d", ms->col, ms->row, ms->fs);*/
 
1254
                if (ms->fs & (MOUSE_BN1_DOWN | MOUSE_BN2_DOWN | MOUSE_BN3_DOWN)) ev.b = status = B_DOWN | (ms->fs & MOUSE_BN1_DOWN ? B_LEFT : ms->fs & MOUSE_BN2_DOWN ? B_MIDDLE : B_RIGHT);
 
1255
                else if (ms->fs & (MOUSE_MOTION_WITH_BN1_DOWN | MOUSE_MOTION_WITH_BN2_DOWN | MOUSE_MOTION_WITH_BN3_DOWN)) {
 
1256
                        int b = ms->fs & MOUSE_MOTION_WITH_BN1_DOWN ? B_LEFT : ms->fs & MOUSE_MOTION_WITH_BN2_DOWN ? B_MIDDLE : B_RIGHT;
 
1257
                        if (status == -1) b |= B_DOWN;
 
1258
                        else b |= B_DRAG;
 
1259
                        ev.b = status = b;
 
1260
                }
 
1261
                else {
 
1262
                        if (status == -1) continue;
 
1263
                        ev.b = (status & BM_BUTT) | B_UP;
 
1264
                        status = -1;
 
1265
                }
 
1266
                if (hard_write(oms->p[1], (unsigned char *)&ev, sizeof(struct event)) != sizeof(struct event)) break;
 
1267
        }
 
1268
#ifdef HAVE_SYS_FMUTEX_H
 
1269
        _fmutex_request(&mouse_mutex, _FMR_IGNINT);
 
1270
#endif
 
1271
        mouse_h = -1;
 
1272
        MouClose(*mh);
 
1273
#ifdef HAVE_SYS_FMUTEX_H
 
1274
        _fmutex_release(&mouse_mutex);
 
1275
#endif
 
1276
        ret:
 
1277
        close(oms->p[1]);
 
1278
        /*free(oms);*/
 
1279
}
 
1280
 
 
1281
static void mouse_handle(struct os2_mouse_spec *oms)
 
1282
{
 
1283
        int r;
 
1284
        if ((r = read(oms->p[0], oms->buffer + oms->bufptr, sizeof(struct event) - oms->bufptr)) <= 0) {
 
1285
                unhandle_mouse(oms);
 
1286
                return;
 
1287
        }
 
1288
        if ((oms->bufptr += r) == sizeof(struct event)) {
 
1289
                oms->bufptr = 0;
 
1290
                oms->fn(oms->data, oms->buffer, sizeof(struct event));
 
1291
        }
 
1292
}
 
1293
 
 
1294
void *handle_mouse(int cons, void (*fn)(void *, unsigned char *, int), void *data)
 
1295
{
 
1296
        struct os2_mouse_spec *oms;
 
1297
        if (is_xterm()) return NULL;
 
1298
#ifdef HAVE_SYS_FMUTEX_H
 
1299
        if (!mouse_mutex_init) {
 
1300
                if (_fmutex_create(&mouse_mutex, 0)) return NULL;
 
1301
                mouse_mutex_init = 1;
 
1302
        }
 
1303
#endif
 
1304
                /* This is never freed but it's allocated only once */
 
1305
        if (!(oms = malloc(sizeof(struct os2_mouse_spec)))) return NULL;
 
1306
        oms->fn = fn;
 
1307
        oms->data = data;
 
1308
        oms->bufptr = 0;
 
1309
        oms->terminate = 0;
 
1310
        if (c_pipe(oms->p)) {
 
1311
                free(oms);
 
1312
                return NULL;
 
1313
        }
 
1314
        _beginthread(mouse_thread, NULL, 0x10000, (void *)oms);
 
1315
        set_handlers(oms->p[0], (void (*)(void *))mouse_handle, NULL, NULL, oms);
 
1316
        return oms;
 
1317
}
 
1318
 
 
1319
void unhandle_mouse(void *om)
 
1320
{
 
1321
        struct os2_mouse_spec *oms = om;
 
1322
        want_draw();
 
1323
        oms->terminate = 1;
 
1324
        set_handlers(oms->p[0], NULL, NULL, NULL, NULL);
 
1325
        close(oms->p[0]);
 
1326
        done_draw();
 
1327
}
 
1328
 
 
1329
void want_draw(void)
 
1330
{
 
1331
        A_DECL(NOPTRRECT, pa);
 
1332
#ifdef HAVE_SYS_FMUTEX_H
 
1333
        if (mouse_mutex_init) _fmutex_request(&mouse_mutex, _FMR_IGNINT);
 
1334
#endif
 
1335
        if (mouse_h != -1) {
 
1336
                static int x = -1, y = -1;
 
1337
                static tcount c = -1;
 
1338
                if (x == -1 || y == -1 || (c != resize_count)) get_terminal_size(1, &x, &y), c = resize_count;
 
1339
                pa->row = 0;
 
1340
                pa->col = 0;
 
1341
                pa->cRow = y - 1;
 
1342
                pa->cCol = x - 1;
 
1343
                MouRemovePtr(pa, mouse_h);
 
1344
        }
 
1345
}
 
1346
 
 
1347
void done_draw(void)
 
1348
{
 
1349
#ifdef HAVE_SYS_FMUTEX_H
 
1350
        if (mouse_mutex_init) _fmutex_release(&mouse_mutex);
 
1351
#endif
 
1352
}
 
1353
 
 
1354
#endif /* if HAVE_MOUOPEN */
 
1355
 
 
1356
#elif defined(HAVE_CLONE)
 
1357
 
 
1358
/* This is maybe buggy... */
 
1359
 
 
1360
#include <sched.h>
 
1361
 
 
1362
struct thread_stack {
 
1363
        struct thread_stack *next;
 
1364
        struct thread_stack *prev;
 
1365
        int pid;
 
1366
        void *stack;
 
1367
        void (*fn)(void *, int);
 
1368
        int h;
 
1369
        int l;
 
1370
        unsigned char data[1];
 
1371
};
 
1372
 
 
1373
void bglt(struct thread_stack *ts)
 
1374
{
 
1375
        ts->fn(ts->data, ts->h);
 
1376
        write(ts->h, "x", 1);
 
1377
        close(ts->h);
 
1378
}
 
1379
 
 
1380
struct list_head thread_stacks = { &thread_stacks, &thread_stacks };
 
1381
 
 
1382
int start_thread(void (*fn)(void *, int), void *ptr, int l)
 
1383
{
 
1384
        struct thread_stack *ts;
 
1385
        int p[2];
 
1386
        int f;
 
1387
        if (c_pipe(p) < 0) return -1;
 
1388
        fcntl(p[0], F_SETFL, O_NONBLOCK);
 
1389
        fcntl(p[1], F_SETFL, O_NONBLOCK);
 
1390
        /*if (!(t = malloc(sizeof(struct tdata) + l))) return -1;
 
1391
        t->fn = fn;
 
1392
        t->h = p[1];
 
1393
        memcpy(t->data, ptr, l);*/
 
1394
        foreach(ts, thread_stacks) {
 
1395
                if (ts->pid == -1 || kill(ts->pid, 0)) {
 
1396
                        if (ts->l >= l) goto ts_ok;
 
1397
                        else {
 
1398
                                struct thread_stack *tts = ts;
 
1399
                                ts = ts->prev;
 
1400
                                del_from_list(tts); free(tts->stack); free(tts);
 
1401
                        }
 
1402
                }
 
1403
        }
 
1404
        if (!(ts = malloc(sizeof(struct thread_stack) + l))) goto fail;
 
1405
        if (!(ts->stack = malloc(0x10000))) {
 
1406
                free(ts);
 
1407
                goto fail;
 
1408
        }
 
1409
        ts->l = l;
 
1410
        add_to_list(thread_stacks, ts);
 
1411
        ts_ok:
 
1412
        ts->fn = fn;
 
1413
        ts->h = p[1];
 
1414
        memcpy(ts->data, ptr, l);
 
1415
        if ((ts->pid = __clone((int (*)(void *))bglt, (char *)ts->stack + 0x8000, CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | SIGCHLD, ts)) == -1) {
 
1416
                fail:
 
1417
                close(p[0]);
 
1418
                close(p[1]);
 
1419
                return -1;
 
1420
        }
 
1421
        return p[0];
 
1422
}
 
1423
 
 
1424
#elif defined(HAVE_PTHREADS)
 
1425
 
 
1426
#include <pthread.h>
 
1427
 
 
1428
int start_thread(void (*fn)(void *, int), void *ptr, int l)
 
1429
{
 
1430
        pthread_t thread;
 
1431
        struct tdata *t;
 
1432
        int p[2];
 
1433
        if (c_pipe(p) < 0) return -1;
 
1434
        fcntl(p[0], F_SETFL, O_NONBLOCK);
 
1435
        fcntl(p[1], F_SETFL, O_NONBLOCK);
 
1436
        if (!(t = malloc(sizeof(struct tdata) + l))) return -1;
 
1437
        t->fn = fn;
 
1438
        t->h = p[1];
 
1439
        memcpy(t->data, ptr, l);
 
1440
        if (pthread_create(&thread, NULL, (void *(*)(void *))bgpt, t)) {
 
1441
                close(p[0]);
 
1442
                close(p[1]);
 
1443
                mem_free(t);
 
1444
                return -1;
 
1445
        }
 
1446
        return p[0];
 
1447
}
 
1448
 
 
1449
#elif defined(HAVE_ATHEOS_THREADS_H) && defined(HAVE_SPAWN_THREAD) && defined(HAVE_RESUME_THREAD)
 
1450
 
 
1451
#include <atheos/threads.h>
 
1452
 
 
1453
int start_thread(void (*fn)(void *, int), void *ptr, int l)
 
1454
{
 
1455
        int p[2];
 
1456
        thread_id f;
 
1457
        struct tdata *t;
 
1458
        if (c_pipe(p) < 0) return -1;
 
1459
        fcntl(p[0], F_SETFL, O_NONBLOCK);
 
1460
        fcntl(p[1], F_SETFL, O_NONBLOCK);
 
1461
        if (!(t = malloc(sizeof(struct tdata) + l))) return -1;
 
1462
        t->fn = fn;
 
1463
        t->h = p[1];
 
1464
        memcpy(t->data, ptr, l);
 
1465
        if ((f = spawn_thread("links_lookup", abgt, 0, 0, t)) == -1) {
 
1466
                close(p[0]);
 
1467
                close(p[1]);
 
1468
                mem_free(t);
 
1469
                return -1;
 
1470
        }
 
1471
        resume_thread(f);
 
1472
        return p[0];
 
1473
}
 
1474
 
 
1475
#else /* HAVE_BEGINTHREAD */
 
1476
 
 
1477
int start_thread(void (*fn)(void *, int), void *ptr, int l)
 
1478
{
 
1479
        int p[2];
 
1480
        pid_t f;
 
1481
        if (c_pipe(p) < 0) return -1;
 
1482
        fcntl(p[0], F_SETFL, O_NONBLOCK);
 
1483
        fcntl(p[1], F_SETFL, O_NONBLOCK);
 
1484
        if (!(f = fork())) {
 
1485
                close_fork_tty();
 
1486
                close(p[0]);
 
1487
                fn(ptr, p[1]);
 
1488
                write(p[1], "x", 1);
 
1489
                close(p[1]);
 
1490
                _exit(0);
 
1491
        }
 
1492
        if (f == -1) {
 
1493
                close(p[0]);
 
1494
                close(p[1]);
 
1495
                return -1;
 
1496
        }
 
1497
        close(p[1]);
 
1498
        return p[0];
 
1499
}
 
1500
 
 
1501
#endif
 
1502
 
 
1503
#ifndef USING_OS2_MOUSE
 
1504
void want_draw(void) {}
 
1505
void done_draw(void) {}
 
1506
#endif
 
1507
 
 
1508
int get_output_handle(void) { return 1; }
 
1509
 
 
1510
#if defined(OS2)
 
1511
 
 
1512
int get_ctl_handle(void) { return get_input_handle(); }
 
1513
 
 
1514
#else
 
1515
 
 
1516
int get_ctl_handle(void) { return 0; }
 
1517
 
 
1518
#endif
 
1519
 
 
1520
#if defined(BEOS)
 
1521
 
 
1522
#elif defined(HAVE_BEGINTHREAD) && defined(HAVE_READ_KBD)
 
1523
int get_input_handle(void)
 
1524
{
 
1525
        int fd[2];
 
1526
        if (ti != -1) return ti;
 
1527
        if (is_xterm()) return 0;
 
1528
        if (c_pipe(fd) < 0) return 0;
 
1529
        ti = fd[0];
 
1530
        tp = fd[1];
 
1531
        _beginthread(input_thread, NULL, 0x10000, (void *)tp);
 
1532
/*
 
1533
#if defined(HAVE_MOUOPEN) && !defined(USE_GPM)
 
1534
        _beginthread(mouse_thread, NULL, 0x10000, (void *)tp);
 
1535
#endif
 
1536
*/
 
1537
        return fd[0];
 
1538
}
 
1539
 
 
1540
#else
 
1541
 
 
1542
int get_input_handle(void)
 
1543
{
 
1544
        return 0;
 
1545
}
 
1546
 
 
1547
#endif /* defined(HAVE_BEGINTHREAD) && defined(HAVE_READ_KBD) */
 
1548
 
 
1549
 
 
1550
void os_cfmakeraw(struct termios *t)
 
1551
{
 
1552
#ifdef HAVE_CFMAKERAW
 
1553
        cfmakeraw(t);
 
1554
#ifdef VMIN
 
1555
        t->c_cc[VMIN] = 1;
 
1556
#endif
 
1557
#else
 
1558
        t->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
 
1559
        t->c_oflag &= ~OPOST;
 
1560
        t->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
 
1561
        t->c_cflag &= ~(CSIZE|PARENB);
 
1562
        t->c_cflag |= CS8;
 
1563
        t->c_cc[VMIN] = 1;
 
1564
        t->c_cc[VTIME] = 0;
 
1565
#endif
 
1566
}
 
1567
 
 
1568
#ifdef USE_GPM
 
1569
 
 
1570
struct gpm_mouse_spec {
 
1571
        int h;
 
1572
        void (*fn)(void *, unsigned char *, int);
 
1573
        void *data;
 
1574
};
 
1575
 
 
1576
/* GPM installs its own signal handlers and we don't want them */
 
1577
 
 
1578
sigset_t gpm_sigset;
 
1579
char gpm_sigset_valid;
 
1580
#ifdef SIGWINCH
 
1581
struct sigaction gpm_winch;
 
1582
char gpm_winch_valid;
 
1583
#endif
 
1584
#ifdef SIGTSTP
 
1585
struct sigaction gpm_tstp;
 
1586
char gpm_tstp_valid;
 
1587
#endif
 
1588
 
 
1589
static void save_gpm_signals(void)
 
1590
{
 
1591
        sigset_t sig;
 
1592
        sigemptyset(&sig);
 
1593
#ifdef SIGWINCH
 
1594
        sigaddset(&sig, SIGWINCH);
 
1595
#endif
 
1596
#ifdef SIGTSTP
 
1597
        sigaddset(&sig, SIGTSTP);
 
1598
#endif
 
1599
        gpm_sigset_valid = !sigprocmask(SIG_BLOCK, &sig, &gpm_sigset);
 
1600
#ifdef SIGWINCH
 
1601
        gpm_winch_valid = !sigaction(SIGWINCH, NULL, &gpm_winch);
 
1602
#endif
 
1603
#ifdef SIGTSTP
 
1604
        gpm_tstp_valid = !sigaction(SIGTSTP, NULL, &gpm_tstp);
 
1605
#endif
 
1606
}
 
1607
 
 
1608
static void restore_gpm_signals(void)
 
1609
{
 
1610
#ifdef SIGWINCH
 
1611
        if (gpm_winch_valid) sigaction(SIGWINCH, &gpm_winch, NULL);
 
1612
#endif
 
1613
#ifdef SIGTSTP
 
1614
        if (gpm_tstp_valid) sigaction(SIGTSTP, &gpm_tstp, NULL);
 
1615
#endif
 
1616
        if (gpm_sigset_valid) sigprocmask(SIG_SETMASK, &gpm_sigset, NULL);
 
1617
}
 
1618
 
 
1619
static void gpm_mouse_in(struct gpm_mouse_spec *gms)
 
1620
{
 
1621
        int g;
 
1622
        Gpm_Event gev;
 
1623
        struct event ev;
 
1624
        save_gpm_signals();
 
1625
        g = Gpm_GetEvent(&gev);
 
1626
        restore_gpm_signals();
 
1627
        if (g <= 0) {
 
1628
                set_handlers(gms->h, NULL, NULL, NULL, NULL);
 
1629
                gms->h = -1;
 
1630
                return;
 
1631
        }
 
1632
        ev.ev = EV_MOUSE;
 
1633
        ev.x = gev.x - 1;
 
1634
        ev.y = gev.y - 1;
 
1635
        if (ev.x < 0) ev.x = 0;
 
1636
        if (ev.y < 0) ev.y = 0;
 
1637
        if (gev.buttons & GPM_B_LEFT) ev.b = B_LEFT;
 
1638
        else if (gev.buttons & GPM_B_MIDDLE) ev.b = B_MIDDLE;
 
1639
        else if (gev.buttons & GPM_B_RIGHT) ev.b = B_RIGHT;
 
1640
        else return;
 
1641
        if (gev.type & GPM_DOWN) ev.b |= B_DOWN;
 
1642
        else if (gev.type & GPM_UP) ev.b |= B_UP;
 
1643
        else if (gev.type & GPM_DRAG) ev.b |= B_DRAG;
 
1644
        else return;
 
1645
        gms->fn(gms->data, (char *)&ev, sizeof(struct event));
 
1646
}
 
1647
 
 
1648
void *handle_mouse(int cons, void (*fn)(void *, unsigned char *, int), void *data)
 
1649
{
 
1650
        int h;
 
1651
        Gpm_Connect conn;
 
1652
        struct gpm_mouse_spec *gms;
 
1653
        conn.eventMask = ~GPM_MOVE;
 
1654
        conn.defaultMask = GPM_MOVE;
 
1655
        conn.minMod = 0;
 
1656
        conn.maxMod = 0;
 
1657
        save_gpm_signals();
 
1658
        h = Gpm_Open(&conn, cons);
 
1659
        restore_gpm_signals();
 
1660
        if (h < 0) return NULL;
 
1661
        gms = mem_alloc(sizeof(struct gpm_mouse_spec));
 
1662
        gms->h = h;
 
1663
        gms->fn = fn;
 
1664
        gms->data = data;
 
1665
        set_handlers(h, (void (*)(void *))gpm_mouse_in, NULL, NULL, gms);
 
1666
        return gms;
 
1667
}
 
1668
 
 
1669
void unhandle_mouse(void *h)
 
1670
{
 
1671
        struct gpm_mouse_spec *gms = h;
 
1672
        if (gms->h != -1) set_handlers(gms->h, NULL, NULL, NULL, NULL);
 
1673
        save_gpm_signals();
 
1674
        Gpm_Close();
 
1675
        restore_gpm_signals();
 
1676
        mem_free(gms);
 
1677
}
 
1678
 
 
1679
#elif !defined(USING_OS2_MOUSE)
 
1680
 
 
1681
void *handle_mouse(int cons, void (*fn)(void *, unsigned char *, int), void *data) { return NULL; }
 
1682
void unhandle_mouse(void *data) { }
 
1683
 
 
1684
#endif /* #ifdef USE_GPM */
 
1685
 
 
1686
#if defined(OS2)
 
1687
 
 
1688
int get_system_env(void)
 
1689
{
 
1690
        if (is_xterm()) return 0;
 
1691
        return ENV_OS2VIO;              /* !!! FIXME: telnet */
 
1692
}
 
1693
 
 
1694
#elif defined(BEOS)
 
1695
 
 
1696
int get_system_env(void)
 
1697
{
 
1698
        unsigned char *term = getenv("TERM");
 
1699
        if (!term || (upcase(term[0]) == 'B' && upcase(term[1]) == 'E')) return ENV_BE;
 
1700
        return 0;
 
1701
}
 
1702
 
 
1703
#elif defined(WIN32)
 
1704
 
 
1705
int get_system_env(void)
 
1706
{
 
1707
        if (is_xterm()) return 0;
 
1708
        return ENV_WIN32;
 
1709
}
 
1710
 
 
1711
#else
 
1712
 
 
1713
int get_system_env(void)
 
1714
{
 
1715
        return 0;
 
1716
}
 
1717
 
 
1718
#endif
 
1719
 
 
1720
static void exec_new_links(struct terminal *term, unsigned char *xterm, unsigned char *exe, unsigned char *param)
 
1721
{
 
1722
        unsigned char *str;
 
1723
        str = mem_alloc(strlen(xterm) + 1 + strlen(exe) + 1 + strlen(param) + 1);
 
1724
        if (*xterm) sprintf(str, "%s %s %s", xterm, exe, param);
 
1725
        else sprintf(str, "%s %s", exe, param);
 
1726
        exec_on_terminal(term, str, "", 2);
 
1727
        mem_free(str);
 
1728
}
 
1729
 
 
1730
static void open_in_new_twterm(struct terminal *term, unsigned char *exe, unsigned char *param)
 
1731
{
 
1732
        unsigned char *twterm;
 
1733
        if (!(twterm = getenv("LINKS_TWTERM"))) twterm = "twterm -e";
 
1734
        exec_new_links(term, twterm, exe, param);
 
1735
}
 
1736
 
 
1737
static void open_in_new_xterm(struct terminal *term, unsigned char *exe, unsigned char *param)
 
1738
{
 
1739
        unsigned char *xterm;
 
1740
        if (!(xterm = getenv("LINKS_XTERM"))) xterm = "xterm -e";
 
1741
        exec_new_links(term, xterm, exe, param);
 
1742
}
 
1743
 
 
1744
static void open_in_new_screen(struct terminal *term, unsigned char *exe, unsigned char *param)
 
1745
{
 
1746
        exec_new_links(term, "screen", exe, param);
 
1747
}
 
1748
 
 
1749
#ifdef OS2
 
1750
static void open_in_new_vio(struct terminal *term, unsigned char *exe, unsigned char *param)
 
1751
{
 
1752
        unsigned char *x = stracpy("\"");
 
1753
        add_to_strn(&x, exe);
 
1754
        add_to_strn(&x, "\"");
 
1755
        exec_new_links(term, "start \"Links\" /c /f /win", x, param);
 
1756
        mem_free(x);
 
1757
}
 
1758
 
 
1759
static void open_in_new_fullscreen(struct terminal *term, unsigned char *exe, unsigned char *param)
 
1760
{
 
1761
        unsigned char *x = stracpy("\"");
 
1762
        add_to_strn(&x, exe);
 
1763
        add_to_strn(&x, "\"");
 
1764
        exec_new_links(term, "start \"Links\" /c /f /fs", x, param);
 
1765
        mem_free(x);
 
1766
}
 
1767
#endif
 
1768
 
 
1769
#ifdef WIN32
 
1770
static void open_in_new_win32(struct terminal *term, unsigned char *exe, unsigned char *param)
 
1771
{
 
1772
        exec_new_links(term, "", exe, param);
 
1773
}
 
1774
#endif
 
1775
 
 
1776
#ifdef BEOS
 
1777
static void open_in_new_be(struct terminal *term, unsigned char *exe, unsigned char *param)
 
1778
{
 
1779
        exec_new_links(term, "Terminal", exe, param);
 
1780
}
 
1781
#endif
 
1782
 
 
1783
#ifdef G
 
1784
static void open_in_new_g(struct terminal *term, unsigned char *exe, unsigned char *param)
 
1785
{
 
1786
        void *info;
 
1787
        unsigned char *target=NULL;
 
1788
        int len;
 
1789
        int base = 0;
 
1790
        unsigned char *url = "";
 
1791
        if (!cmpbeg(param, "-target "))
 
1792
        {
 
1793
                unsigned char *p;
 
1794
                target=param+strlen("-target ");
 
1795
                for (p=target;*p!=' '&&*p;p++);
 
1796
                *p=0;
 
1797
                param=p+1;
 
1798
        }       
 
1799
        if (!cmpbeg(param, "-base-session ")) {
 
1800
                base = atoi(param + strlen("-base-session "));
 
1801
        } else {
 
1802
                url = param;
 
1803
        }
 
1804
        if ((info = create_session_info(base, url, target, &len))) attach_g_terminal(info, len);
 
1805
}
 
1806
#endif
 
1807
 
 
1808
struct {
 
1809
        int env;
 
1810
        void (*fn)(struct terminal *term, unsigned char *, unsigned char *);
 
1811
        unsigned char *text;
 
1812
        unsigned char *hk;
 
1813
} oinw[] = {
 
1814
        {ENV_XWIN, open_in_new_xterm, TEXT_(T_XTERM), TEXT_(T_HK_XTERM)},
 
1815
        {ENV_TWIN, open_in_new_twterm, TEXT_(T_TWTERM), TEXT_(T_HK_TWTERM)},
 
1816
        {ENV_SCREEN, open_in_new_screen, TEXT_(T_SCREEN), TEXT_(T_HK_SCREEN)},
 
1817
#ifdef OS2
 
1818
        {ENV_OS2VIO, open_in_new_vio, TEXT_(T_WINDOW), TEXT_(T_HK_WINDOW)},
 
1819
        {ENV_OS2VIO, open_in_new_fullscreen, TEXT_(T_FULL_SCREEN), TEXT_(T_HK_FULL_SCREEN)},
 
1820
#endif
 
1821
#ifdef WIN32
 
1822
        {ENV_WIN32, open_in_new_win32, TEXT_(T_WINDOW), TEXT_(T_HK_WINDOW)},
 
1823
#endif
 
1824
#ifdef BEOS
 
1825
        {ENV_BE, open_in_new_be, TEXT_(T_BEOS_TERMINAL), TEXT_(T_HK_BEOS_TERMINAL)},
 
1826
#endif
 
1827
#ifdef G
 
1828
        {ENV_G, open_in_new_g, TEXT_(T_WINDOW), TEXT_(T_HK_WINDOW)},
 
1829
#endif
 
1830
        {0, NULL, NULL, NULL}
 
1831
};
 
1832
 
 
1833
struct open_in_new *get_open_in_new(int environment)
 
1834
{
 
1835
        int i;
 
1836
        struct open_in_new *oin = DUMMY;
 
1837
        int noin = 0;
 
1838
        if (anonymous) return NULL;
 
1839
        if (environment & ENV_G) environment = ENV_G;
 
1840
        for (i = 0; oinw[i].env; i++) if ((environment & oinw[i].env) == oinw[i].env) {
 
1841
                if ((unsigned)noin > MAXINT / sizeof(struct open_in_new) - 2) overalloc();
 
1842
                oin = mem_realloc(oin, (noin + 2) * sizeof(struct open_in_new));
 
1843
                oin[noin].text = oinw[i].text;
 
1844
                oin[noin].hk = oinw[i].hk;
 
1845
                oin[noin].fn = oinw[i].fn;
 
1846
                noin++;
 
1847
                oin[noin].text = NULL;
 
1848
                oin[noin].hk = NULL;
 
1849
                oin[noin].fn = NULL;
 
1850
        }
 
1851
        if (oin == DUMMY) return NULL;
 
1852
        return oin;
 
1853
}
 
1854
 
 
1855
int can_resize_window(int environment)
 
1856
{
 
1857
        if (environment & (ENV_OS2VIO | ENV_WIN32)) return 1;
 
1858
        return 0;
 
1859
}
 
1860
 
 
1861
int can_open_os_shell(int environment)
 
1862
{
 
1863
#ifdef OS2
 
1864
        if (environment & ENV_XWIN) return 0;
 
1865
#endif
 
1866
        return 1;
 
1867
}
 
1868
 
 
1869
#ifndef OS2
 
1870
void set_highpri(void)
 
1871
{
 
1872
}
 
1873
#else
 
1874
void set_highpri(void)
 
1875
{
 
1876
        DosSetPriority(PRTYS_PROCESS, PRTYC_FOREGROUNDSERVER, 0, 0);
 
1877
}
 
1878
#endif
 
1879
 
 
1880
#ifndef HAVE_SNPRINTF
 
1881
 
 
1882
#define B_SZ    65536
 
1883
 
 
1884
char snprtintf_buffer[B_SZ];
 
1885
 
 
1886
int my_snprintf(char *str, int n, char *f, ...)
 
1887
{
 
1888
        int i;
 
1889
        va_list l;
 
1890
        if (!n) return -1;
 
1891
        va_start(l, f);
 
1892
        vsprintf(snprtintf_buffer, f, l);
 
1893
        va_end(l);
 
1894
        i = strlen(snprtintf_buffer);
 
1895
        if (i >= B_SZ) {
 
1896
                error("String size too large!");
 
1897
                va_end(l);
 
1898
                fatal_tty_exit();
 
1899
                exit(RET_FATAL);
 
1900
        }
 
1901
        if (i >= n) {
 
1902
                memcpy(str, snprtintf_buffer, n);
 
1903
                str[n - 1] = 0;
 
1904
                va_end(l);
 
1905
                return -1;
 
1906
        }
 
1907
        strcpy(str, snprtintf_buffer);
 
1908
        va_end(l);
 
1909
        return i;
 
1910
}
 
1911
 
 
1912
#endif
 
1913
 
 
1914
#ifndef HAVE_MEMMOVE
 
1915
 
 
1916
#define MEMMOVE
 
1917
 
 
1918
typedef long word;              /* "word" used for optimal copy speed */
 
1919
 
 
1920
#define wsize   sizeof(word)
 
1921
#define wmask   (wsize - 1)
 
1922
 
 
1923
/*
 
1924
 * Copy a block of memory, handling overlap.
 
1925
 * This is the routine that actually implements
 
1926
 * (the portable versions of) bcopy, memcpy, and memmove.
 
1927
 */
 
1928
void *
 
1929
memmove(dst0, src0, length)
 
1930
        void *dst0;
 
1931
        const void *src0;
 
1932
        size_t length;
 
1933
{
 
1934
        char *dst = dst0;
 
1935
        const char *src = src0;
 
1936
        size_t t;
 
1937
        unsigned long u;
 
1938
 
 
1939
        if (length == 0 || dst == src)          /* nothing to do */
 
1940
                goto done;
 
1941
 
 
1942
        /*
 
1943
         * Macros: loop-t-times; and loop-t-times, t>0
 
1944
         */
 
1945
#define TLOOP(s) if (t) TLOOP1(s)
 
1946
#define TLOOP1(s) do { s; } while (--t)
 
1947
 
 
1948
        if ((unsigned long)dst < (unsigned long)src) {
 
1949
                /*
 
1950
                 * Copy forward.
 
1951
                 */
 
1952
                u = (unsigned long)src; /* only need low bits */
 
1953
                if ((u | (unsigned long)dst) & wmask) {
 
1954
                        /*
 
1955
                         * Try to align operands.  This cannot be done
 
1956
                         * unless the low bits match.
 
1957
                         */
 
1958
                        if ((u ^ (unsigned long)dst) & wmask || length < wsize)
 
1959
                                t = length;
 
1960
                        else
 
1961
                                t = wsize - (size_t)(u & wmask);
 
1962
                        length -= t;
 
1963
                        TLOOP1(*dst++ = *src++);
 
1964
                }
 
1965
                /*
 
1966
                 * Copy whole words, then mop up any trailing bytes.
 
1967
                 */
 
1968
                t = length / wsize;
 
1969
                TLOOP(*(word *)(void *)dst = *(const word *)(const void *)src; src += wsize; dst += wsize);
 
1970
                t = length & wmask;
 
1971
                TLOOP(*dst++ = *src++);
 
1972
        } else {
 
1973
                /*
 
1974
                 * Copy backwards.  Otherwise essentially the same.
 
1975
                 * Alignment works as before, except that it takes
 
1976
                 * (t&wmask) bytes to align, not wsize-(t&wmask).
 
1977
                 */
 
1978
                src += length;
 
1979
                dst += length;
 
1980
                u = (unsigned long)src;
 
1981
                if ((u | (unsigned long)dst) & wmask) {
 
1982
                        if ((u ^ (unsigned long)dst) & wmask || length <= wsize)
 
1983
                                t = length;
 
1984
                        else
 
1985
                                t = (size_t)(u & wmask);
 
1986
                        length -= t;
 
1987
                        TLOOP1(*--dst = *--src);
 
1988
                }
 
1989
                t = length / wsize;
 
1990
                TLOOP(src -= wsize; dst -= wsize; *(word *)(void *)dst = *(const word *)(const void *)src);
 
1991
                t = length & wmask;
 
1992
                TLOOP(*--dst = *--src);
 
1993
        }
 
1994
done:
 
1995
#if defined(MEMCOPY) || defined(MEMMOVE)
 
1996
        return (dst0);
 
1997
#else
 
1998
        return;
 
1999
#endif
 
2000
}
 
2001
 
 
2002
#endif
 
2003
 
 
2004
#ifndef HAVE_RAISE
 
2005
 
 
2006
int
 
2007
raise(s)
 
2008
        int s;
 
2009
        {
 
2010
#ifdef HAVE_GETPID
 
2011
                return(kill(getpid(), s));
 
2012
#else
 
2013
                return 0;
 
2014
#endif
 
2015
};
 
2016
 
 
2017
#endif
 
2018
 
 
2019
#ifndef HAVE_STRTOUL
 
2020
 
 
2021
/****yes bad fix***/
 
2022
unsigned long strtoul(const char *nptr, char **endptr, int base) {
 
2023
 return (unsigned long)strtol(nptr,endptr,base);
 
2024
 };
 
2025
 
 
2026
#endif
 
2027
 
 
2028
#ifndef HAVE_STRERROR
 
2029
 
 
2030
char **sys_errlist;
 
2031
char *strerror(int errnum) { return sys_errlist[errnum];};
 
2032
 
 
2033
#endif
 
2034
 
 
2035
#ifndef HAVE_GETTIMEOFDAY
 
2036
int gettimeofday(struct timeval *tv, struct timezone *tz)
 
2037
{
 
2038
        if (tv) tv->tv_sec = time(NULL), tv->tv_usec = 0;
 
2039
        if (tz) tz->tz_minuteswest = tz->tz_dsttime = 0;
 
2040
        return 0;
 
2041
}
 
2042
#endif
 
2043
#ifndef HAVE_STRCSPN
 
2044
size_t strcspn(const char *s, const char *reject)
 
2045
{
 
2046
        size_t r;
 
2047
        for (r = 0; *s; r++, s++) {
 
2048
                const char *rj;
 
2049
                for (rj = reject; *rj; rj++) if (*s == *rj) goto brk;
 
2050
        }
 
2051
        brk:
 
2052
        return r;
 
2053
}
 
2054
#endif
 
2055
#ifndef HAVE_STRSTR
 
2056
char *strstr(const char *haystack, const char *needle)
 
2057
{
 
2058
        size_t hs = strlen(haystack);
 
2059
        size_t ns = strlen(needle);
 
2060
        while (hs >= ns) {
 
2061
                if (!memcmp(haystack, needle, ns)) return haystack;
 
2062
                haystack++, hs--;
 
2063
        }
 
2064
        return NULL;
 
2065
}
 
2066
#endif
 
2067
#ifndef HAVE_TEMPNAM
 
2068
char *tempnam(const char *dir, const char *pfx)
 
2069
{
 
2070
        static int counter = 0;
 
2071
        unsigned char *d, *s, *a;
 
2072
        int l;
 
2073
        if (!(d = getenv("TMPDIR"))) {
 
2074
                if (dir) d = (unsigned char *)dir;
 
2075
                else if (!(d = getenv("TMP")) && !(d = getenv("TEMP"))) {
 
2076
#ifdef P_tmpdir
 
2077
                        d = P_tmpdir;
 
2078
#else
 
2079
                        d = "/tmp";
 
2080
#endif
 
2081
                }
 
2082
        }
 
2083
        l = 0;
 
2084
        s = init_str();
 
2085
        add_to_str(&s, &l, d);
 
2086
        if (s[0] && s[strlen(s) - 1] != '/') add_chr_to_str(&s, &l, '/');
 
2087
        add_to_str(&s, &l, (unsigned char *)pfx);
 
2088
        add_num_to_str(&s, &l, counter++);
 
2089
        a = strdup(s);
 
2090
        mem_free(s);
 
2091
        return a;
 
2092
}
 
2093
#endif