os_dep.c
来自「this is the file used to browse web」· C语言 代码 · 共 1,957 行 · 第 1/3 页
C
1,957 行
if (is_xterm()) return -1; if (get_terminal_size(1, &old_x, &old_y)) return -1; x1 = GETSHELL; if (!x1) x1 = DEFAULT_SHELL; if (!is_winnt()) { ct = GetConsoleTitle(buffer, sizeof buffer); } call_resize(x1, x, y); if (!is_winnt()) { int new_x, new_y; /* If we resize console on Win98 in fullscreen mode, it won't be notified by Cygwin (it is valid for all Cygwin apps). So we must switch to windowed mode, resize it again (twice, because resizing to the same size won't have an effect) and switch back to full-screen mode. */ /* I'm not sure what's the behavior on WinNT 4. Anybody wants to test? */ if (!fullscreen && !get_terminal_size(1, &new_x, &new_y) && (new_x != x || new_y != y)) { fullscreen = 1; keybd_event(VK_MENU, 0x38, 0, 0); keybd_event(VK_RETURN, 0x1c, 0, 0); keybd_event(VK_RETURN, 0x1c, KEYEVENTF_KEYUP, 0); keybd_event(VK_MENU, 0x38, KEYEVENTF_KEYUP, 0); if (y != 25) call_resize(x1, 80, 25); else call_resize(x1, 80, 50); call_resize(x1, x, y); if (get_terminal_size(1, &new_x, &new_y) || new_x != x || new_y != y) call_resize(x1, old_x, old_y); keybd_event(VK_MENU, 0x38, 0, 0); keybd_event(VK_RETURN, 0x1c, 0, 0); keybd_event(VK_RETURN, 0x1c, KEYEVENTF_KEYUP, 0); keybd_event(VK_MENU, 0x38, KEYEVENTF_KEYUP, 0); } if (ct) SetConsoleTitle(buffer); } return 0;}#elif defined(OS2)int exe(char *path){ int flags = P_SESSION; pid_t pid; int ret; char *shell; if (!(shell = GETSHELL)) shell = DEFAULT_SHELL; if (is_xterm()) flags |= P_BACKGROUND; if ((pid = spawnlp(flags, shell, shell, "/c", path, NULL)) != -1) waitpid(pid, &ret, 0); else ret = -1; return ret;}char *get_clipboard_text(){ PTIB tib; PPIB pib; HAB hab; HMQ hmq; ULONG oldType; char *ret = NULL; DosGetInfoBlocks(&tib, &pib); oldType = pib->pib_ultype; pib->pib_ultype = 3; if ((hab = WinInitialize(0)) != NULLHANDLE) { if ((hmq = WinCreateMsgQueue(hab, 0)) != NULLHANDLE) { if (WinOpenClipbrd(hab)) { ULONG fmtInfo = 0; if (WinQueryClipbrdFmtInfo(hab, CF_TEXT, &fmtInfo)!=FALSE) { ULONG selClipText = WinQueryClipbrdData(hab, CF_TEXT); if (selClipText) { char *u; PCHAR pchClipText = (PCHAR)selClipText; ret = mem_alloc(strlen(pchClipText)+1); strcpy(ret, pchClipText); while ((u = strchr(ret, 13))) memmove(u, u + 1, strlen(u + 1) + 1); } } WinCloseClipbrd(hab); } WinDestroyMsgQueue(hmq); } WinTerminate(hab); } pib->pib_ultype = oldType; return ret;}void set_clipboard_text(char *data){ PTIB tib; PPIB pib; HAB hab; HMQ hmq; ULONG oldType; DosGetInfoBlocks(&tib, &pib); oldType = pib->pib_ultype; pib->pib_ultype = 3; if ((hab = WinInitialize(0)) != NULLHANDLE) { if ((hmq = WinCreateMsgQueue(hab, 0)) != NULLHANDLE) { if(WinOpenClipbrd(hab)) { PVOID pvShrObject = NULL; if (DosAllocSharedMem(&pvShrObject, NULL, strlen(data)+1, PAG_COMMIT | PAG_WRITE | OBJ_GIVEABLE) == NO_ERROR) { strcpy(pvShrObject, data); WinSetClipbrdData(hab, (ULONG)pvShrObject, CF_TEXT, CFI_POINTER); } WinCloseClipbrd(hab); } WinDestroyMsgQueue(hmq); } WinTerminate(hab); } pib->pib_ultype = oldType;}unsigned char *get_window_title(){#ifndef OS2_DEBUG /*char *org_switch_title;*/ char *org_win_title = NULL; static PTIB tib = NULL; static PPIB pib = NULL; ULONG oldType; HSWITCH hSw = NULLHANDLE; SWCNTRL swData; HAB hab; HMQ hmq; /* save current process title */ if (!pib) DosGetInfoBlocks(&tib, &pib); oldType = pib->pib_ultype; memset(&swData, 0, sizeof swData); if (hSw == NULLHANDLE) hSw = WinQuerySwitchHandle(0, pib->pib_ulpid); if (hSw!=NULLHANDLE && !WinQuerySwitchEntry(hSw, &swData)) { /*org_switch_title = mem_alloc(strlen(swData.szSwtitle)+1); strcpy(org_switch_title, swData.szSwtitle);*/ /* Go to PM */ pib->pib_ultype = 3; if ((hab = WinInitialize(0)) != NULLHANDLE) { if ((hmq = WinCreateMsgQueue(hab, 0)) != NULLHANDLE) { org_win_title = mem_alloc(MAXNAMEL+1); WinQueryWindowText(swData.hwnd, MAXNAMEL+1, org_win_title); org_win_title[MAXNAMEL] = 0; /* back From PM */ WinDestroyMsgQueue(hmq); } WinTerminate(hab); } pib->pib_ultype = oldType; } return org_win_title;#else return NULL;#endif}void set_window_title(unsigned char *title){#ifndef OS2_DEBUG static PTIB tib; static PPIB pib; ULONG oldType; static HSWITCH hSw; SWCNTRL swData; HAB hab; HMQ hmq; if (!title) return; if (!pib) DosGetInfoBlocks(&tib, &pib); oldType = pib->pib_ultype; memset(&swData, 0, sizeof swData); if (hSw == NULLHANDLE) hSw = WinQuerySwitchHandle(0, pib->pib_ulpid); if (hSw!=NULLHANDLE && !WinQuerySwitchEntry(hSw, &swData)) { strncpy(swData.szSwtitle, title, MAXNAMEL-1); swData.szSwtitle[MAXNAMEL-1] = 0; WinChangeSwitchEntry(hSw, &swData); /* Go to PM */ pib->pib_ultype = 3; if ((hab = WinInitialize(0)) != NULLHANDLE) { if ((hmq = WinCreateMsgQueue(hab, 0)) != NULLHANDLE) { if(swData.hwnd) WinSetWindowText(swData.hwnd, title); /* back From PM */ WinDestroyMsgQueue(hmq); } WinTerminate(hab); } } pib->pib_ultype = oldType;#endif}/*void set_window_title(int init, const char *url){ static char *org_switch_title; static char *org_win_title; static PTIB tib; static PPIB pib; static ULONG oldType; static HSWITCH hSw; static SWCNTRL swData; HAB hab; HMQ hmq; char new_title[MAXNAMEL]; switch(init) { case 1: DosGetInfoBlocks( &tib, &pib ); oldType = pib->pib_ultype; memset( &swData, 0, sizeof swData ); hSw = WinQuerySwitchHandle( 0, pib->pib_ulpid ); if( hSw!=NULLHANDLE && !WinQuerySwitchEntry( hSw, &swData ) ) { org_switch_title = mem_alloc( strlen( swData.szSwtitle )+1 ); strcpy( org_switch_title, swData.szSwtitle ); pib->pib_ultype = 3; hab = WinInitialize( 0 ); hmq = WinCreateMsgQueue( hab, 0 ); if( hab!=NULLHANDLE && hmq!=NULLHANDLE ) { org_win_title = mem_alloc( MAXNAMEL+1 ); WinQueryWindowText( swData.hwnd, MAXNAMEL+1, org_win_title ); WinDestroyMsgQueue( hmq ); WinTerminate( hab ); } pib->pib_ultype = oldType; } break; case -1: pib->pib_ultype = 3; hab = WinInitialize( 0 ); hmq = WinCreateMsgQueue( hab, 0 ); if( hSw!=NULLHANDLE && hab!=NULLHANDLE && hmq!=NULLHANDLE ) { strncpy( swData.szSwtitle, org_switch_title, MAXNAMEL ); swData.szSwtitle[MAXNAMEL] = 0; WinChangeSwitchEntry( hSw, &swData ); if( swData.hwnd ) WinSetWindowText( swData.hwnd, org_win_title ); WinDestroyMsgQueue( hmq ); WinTerminate( hab ); } pib->pib_ultype = oldType; mem_free(org_switch_title); mem_free(org_win_title); break; case 0: if ( url != NULL && *url ) { strncpy(new_title, url, MAXNAMEL-10); new_title[MAXNAMEL-10] = 0; strcat(new_title, " - Links"); pib->pib_ultype = 3; hab = WinInitialize( 0 ); hmq = WinCreateMsgQueue( hab, 0 ); if( hSw!=NULLHANDLE && hab!=NULLHANDLE && hmq!=NULLHANDLE ) { strncpy( swData.szSwtitle, new_title, MAXNAMEL ); swData.szSwtitle[MAXNAMEL] = 0; WinChangeSwitchEntry( hSw, &swData ); if( swData.hwnd ) WinSetWindowText( swData.hwnd, new_title ); WinDestroyMsgQueue( hmq ); WinTerminate( hab ); } pib->pib_ultype = oldType; } break; }}*/int resize_window(int x, int y){ int xfont, yfont; A_DECL(VIOMODEINFO, vmi); resize_count++; if (is_xterm()) return -1; vmi->cb = sizeof(*vmi); if (VioGetMode(vmi, 0)) return -1; vmi->col = x; vmi->row = y; /*debug("%d %d %d", vmi->buf_length, vmi->full_length, vmi->partial_length);*/ for (xfont = 9; xfont >= 8; xfont--) for (yfont = 16; yfont >= 8; yfont--) { vmi->hres = x * xfont; vmi->vres = y * yfont; if (vmi->vres <= 400) vmi->vres = 400; else if (vmi->vres <= 480) vmi->vres = 480; vmi->buf_length = vmi->full_length = vmi->partial_length = x * ((vmi->vres + yfont - 1) / yfont) * 2; vmi->full_length = (vmi->full_length + 4095) & ~4095; vmi->partial_length = (vmi->partial_length + 4095) & ~4095; if (!VioSetMode(vmi, 0)) return 0; } return -1;}#endif/* Threads */#if defined(HAVE_BEGINTHREAD) || defined(BEOS) || defined(HAVE_PTHREADS)struct tdata { void (*fn)(void *, int); int h; unsigned char data[1];};void bgt(struct tdata *t){ signal(SIGPIPE, SIG_IGN); t->fn(t->data, t->h); write(t->h, "x", 1); close(t->h); free(t);}#ifdef HAVE_PTHREADSvoid *bgpt(struct tdata *t){ bgt(t); return NULL;}#endif#endif#if defined(UNIX) || defined(OS2) || defined(RISCOS) || defined(SPAD) || defined(WIN32)void terminate_osdep() {}#endif#ifndef BEOSvoid block_stdin() {}void unblock_stdin() {}#endif#if defined(BEOS)#include <be/kernel/OS.h>int thr_sem_init = 0;sem_id thr_sem;struct list_head active_threads = { &active_threads, &active_threads };struct active_thread { struct active_thread *next; struct active_thread *prev; thread_id tid; void (*fn)(void *); void *data;};int32 started_thr(void *data){ struct active_thread *thrd = data; thrd->fn(thrd->data); if (acquire_sem(thr_sem) < B_NO_ERROR) return 0; del_from_list(thrd); free(thrd); release_sem(thr_sem); return 0;}int start_thr(void (*fn)(void *), void *data, unsigned char *name){ struct active_thread *thrd; int tid; if (!thr_sem_init) { if ((thr_sem = create_sem(0, "thread_sem")) < B_NO_ERROR) return -1; thr_sem_init = 1; } else if (acquire_sem(thr_sem) < B_NO_ERROR) return -1; if (!(thrd = malloc(sizeof(struct active_thread)))) goto rel; thrd->fn = fn; thrd->data = data; if ((tid = thrd->tid = spawn_thread(started_thr, name, B_NORMAL_PRIORITY, thrd)) < B_NO_ERROR) { free(thrd); rel: release_sem(thr_sem); return -1; } resume_thread(thrd->tid); add_to_list(active_threads, thrd); release_sem(thr_sem); return tid;}void terminate_osdep(){ struct list_head *p; struct active_thread *thrd; if (acquire_sem(thr_sem) < B_NO_ERROR) return; foreach(thrd, active_threads) kill_thread(thrd->tid); while ((p = active_threads.next) != &active_threads) { del_from_list(p); free(p); } release_sem(thr_sem);}int start_thread(void (*fn)(void *, int), void *ptr, int l){ int p[2]; struct tdata *t; if (c_pipe(p) < 0) return -1; if (!(t = malloc(sizeof(struct tdata) + l))) return -1; t->fn = fn; t->h = p[1]; memcpy(t->data, ptr, l); if (start_thr((void (*)(void *))bgt, t, "links_thread") < 0) { close(p[0]); close(p[1]); mem_free(t); return -1; } return p[0];}#elif defined(HAVE_BEGINTHREAD)int start_thread(void (*fn)(void *, int), void *ptr, int l){ int p[2]; struct tdata *t; if (c_pipe(p) < 0) return -1; fcntl(p[0], F_SETFL, O_NONBLOCK); fcntl(p[1], F_SETFL, O_NONBLOCK); if (!(t = malloc(sizeof(struct tdata) + l))) return -1; t->fn = fn; t->h = p[1]; memcpy(t->data, ptr, l); if (_beginthread((void (*)(void *))bgt, NULL, 65536, t) == -1) { close(p[0]); close(p[1]); mem_free(t); return -1; } return p[0];}#ifdef HAVE_READ_KBDint tp = -1;int ti = -1;void input_thread(void *p){ char c[2]; int h = (int)p; signal(SIGPIPE, SIG_IGN); while (1) { /*c[0] = _read_kbd(0, 1, 1); if (c[0]) if (write(h, c, 1) <= 0) break; else { int w; printf("1");fflush(stdout); c[1] = _read_kbd(0, 1, 1); printf("2");fflush(stdout); w = write(h, c, 2); printf("3");fflush(stdout); if (w <= 0) break; if (w == 1) if (write(h, c+1, 1) <= 0) break; printf("4");fflush(stdout); }*/ /* for the records: _read_kbd(0, 1, 1) will read a char, don't echo it, wait for one available and accept CTRL-C. Knowing that, I suggest we replace this call completly! */ *c = _read_kbd(0, 1, 1); write(h, c, 1); } close(h);}#endif /* #ifdef HAVE_READ_KBD */#if defined(HAVE_MOUOPEN) && !defined(USE_GPM)#define USING_OS2_MOUSE#ifdef HAVE_SYS_FMUTEX_H_fmutex mouse_mutex;int mouse_mutex_init = 0;#endifint mouse_h = -1;struct os2_mouse_spec { int p[2]; void (*fn)(void *, unsigned char *, int); void *data; unsigned char buffer[sizeof(struct event)]; int bufptr; int terminate;};void mouse_thread(void *p){ int status; struct os2_mouse_spec *oms = p; A_DECL(HMOU, mh); A_DECL(MOUEVENTINFO, ms); A_DECL(USHORT, rd); A_DECL(USHORT, mask); struct event ev; signal(SIGPIPE, SIG_IGN); ev.ev = EV_MOUSE; if (MouOpen(NULL, mh)) goto ret; mouse_h = *mh; *mask = MOUSE_MOTION_WITH_BN1_DOWN | MOUSE_BN1_DOWN | MOUSE_MOTION_WITH_BN2_DOWN | MOUSE_BN2_DOWN | MOUSE_MOTION_WITH_BN3_DOWN | MOUSE_BN3_DOWN | MOUSE_MOTION; MouSetEventMask(mask, *mh); *rd = MOU_WAIT; status = -1; while (1) { if (MouReadEventQue(ms, rd, *mh)) break;#ifdef HAVE_SYS_FMUTEX_H _fmutex_request(&mouse_mutex, _FMR_IGNINT);#endif if (!oms->terminate) MouDrawPtr(*mh);#ifdef HAVE_SYS_FMUTEX_H _fmutex_release(&mouse_mutex);#endif ev.x = ms->col; ev.y = ms->row; /*debug("status: %d %d %d", ms->col, ms->row, ms->fs);*/ 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); else if (ms->fs & (MOUSE_MOTION_WITH_BN1_DOWN | MOUSE_MOTION_WITH_BN2_DOWN | MOUSE_MOTION_WITH_BN3_DOWN)) { int b = ms->fs & MOUSE_MOTION_WITH_BN1_DOWN ? B_LEFT : ms->fs & MOUSE_MOTION_WITH_BN2_DOWN ? B_MIDDLE : B_RIGHT; if (status == -1) b |= B_DOWN; else b |= B_DRAG; ev.b = status = b; } else { if (status == -1) continue; ev.b = (status & BM_BUTT) | B_UP; status = -1; } if (hard_write(oms->p[1], (unsigned char *)&ev, sizeof(struct event)) != sizeof(struct event)) break; }#ifdef HAVE_SYS_FMUTEX_H _fmutex_request(&mouse_mutex, _FMR_IGNINT);#endif mouse_h = -1; MouClose(*mh);#ifdef HAVE_SYS_FMUTEX_H _fmutex_release(&mouse_mutex);#endif ret: close(oms->p[1]); /*free(oms);*/}void mouse_handle(struct os2_mouse_spec *oms){ int r; if ((r = read(oms->p[0], oms->buffer + oms->bufptr, sizeof(struct event) - oms->bufptr)) <= 0) { unhandle_mouse(oms); return; } if ((oms->bufptr += r) == sizeof(struct event)) { oms->bufptr = 0; oms->fn(oms->data, oms->buffer, sizeof(struct event)); }}void *handle_mouse(int cons, void (*fn)(void *, unsigned char *, int), void *data){ struct os2_mouse_spec *oms; if (is_xterm()) return NULL;#ifdef HAVE_SYS_FMUTEX_H if (!mouse_mutex_init) { if (_fmutex_create(&mouse_mutex, 0)) return NULL; mouse_mutex_init = 1; }#endif /* This is never freed but it's allocated only once */ if (!(oms = malloc(sizeof(struct os2_mouse_spec)))) return NULL; oms->fn = fn; oms->data = data; oms->bufptr = 0; oms->terminate = 0; if (c_pipe(oms->p)) { free(oms); return NULL; } _beginthread(mouse_thread, NULL, 0x10000, (void *)oms); set_handlers(oms->p[0], (void (*)(void *))mouse_handle, NULL, NULL, oms); return oms;}void unhandle_mouse(void *om){ struct os2_mouse_spec *oms = om; want_draw(); oms->terminate = 1; set_handlers(oms->p[0], NULL, NULL, NULL, NULL); close(oms->p[0]); done_draw();}void want_draw(){ A_DECL(NOPTRRECT, pa);#ifdef HAVE_SYS_FMUTEX_H if (mouse_mutex_init) _fmutex_request(&mouse_mutex, _FMR_IGNINT);#endif if (mouse_h != -1) { static int x = -1, y = -1; static tcount c = -1; if (x == -1 || y == -1 || (c != resize_count)) get_terminal_size(1, &x, &y), c = resize_count; pa->row = 0; pa->col = 0; pa->cRow = y - 1; pa->cCol = x - 1; MouRemovePtr(pa, mouse_h); }}void done_draw(){#ifdef HAVE_SYS_FMUTEX_H
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?