📄 overrides.c
字号:
/* $Id: overrides.c,v 1.3.2.1 2005/02/28 01:20:29 jonas Exp $ *//* Elinks overrides for Win32 (MSVC + MingW) * Loosely based on osdep/beos/overrides.c by Mikulas Patocka. * * By G. Vanem <giva@bgnett.no> 2004 */#ifdef HAVE_CONFIG_H#include "config.h"#endif#define WIN32_OVERRIDES_SELF#include "osdep/system.h"#include <stdio.h>#include <stdlib.h>#include <stdarg.h>#include <fcntl.h>#include <errno.h>#include <sys/types.h>#include "elinks.h"#include "config/options.h"#include "intl/gettext/libintl.h"#include "osdep/osdep.h"#include "osdep/win32/overrides.h"#include "osdep/win32/win32.h"#include "terminal/mouse.h"#include "terminal/terminal.h"#define SOCK_SHIFT 1024enum fd_types { FDT_FILE = 1, FDT_SOCKET, FDT_TERMINAL, FDT_PIPE};static BOOL console_nbio = FALSE;static const char *keymap[] = { "\E[5~", /* VK_PRIOR */ "\E[6~", /* VK_NEXT */ "\E[F", /* VK_END */ "\E[H", /* VK_HOME */ "\E[D", /* VK_LEFT */ "\E[A", /* VK_UP */ "\E[C", /* VK_RIGHT */ "\E[B", /* VK_DOWN */ "", /* VK_SELECT */ "", /* VK_PRINT */ "", /* VK_EXECUTE */ "", /* VK_SNAPSHOT */ "\E[2~", /* VK_INSERT */ "\E[3~" /* VK_DELETE */};#define TRACE(m...) \ do { \ if (get_cmd_opt_int("verbose") == 2) \ DBG(m); \ } while (0)static enum fd_typeswhat_fd_type(int *fd){ if (*fd == (int)GetStdHandle(STD_INPUT_HANDLE) || *fd == (int)GetStdHandle(STD_OUTPUT_HANDLE) || *fd == (int)GetStdHandle(STD_ERROR_HANDLE)) return FDT_TERMINAL; if (GetFileType((HANDLE) *fd) == FILE_TYPE_PIPE) return FDT_PIPE; if (*fd >= SOCK_SHIFT) { *fd -= SOCK_SHIFT; return FDT_SOCKET; } return FDT_FILE;}static intconsole_key_read(const KEY_EVENT_RECORD *ker, char *buf, int max){ char c; int vkey; if (!ker->bKeyDown) return 0; c = ker->uChar.AsciiChar; if (c) { *buf = c; return 1; } vkey = ker->wVirtualKeyCode; if (vkey < VK_PRIOR || vkey > VK_DELETE) return 0; strncpy(buf, keymap[vkey-VK_PRIOR], max); return strlen(buf);}#ifdef CONFIG_MOUSEstatic intconsole_mouse_read(const MOUSE_EVENT_RECORD *mer, char *buf, int max){ struct term_event ev; int len; if (mer->dwEventFlags || !mer->dwButtonState) /* not mouse down, or shifts */ return 0; ev.ev = EVENT_MOUSE; ev.info.mouse.x = 1 + mer->dwMousePosition.X; ev.info.mouse.y = 1 + mer->dwMousePosition.Y; ev.info.mouse.button = B_DOWN; len = int_min(max, sizeof(ev)); memcpy(buf, &ev, len); return len;}#endifstatic intconsole_read(HANDLE hnd, void *buf, int max, INPUT_RECORD *irp){ INPUT_RECORD ir; const KEY_EVENT_RECORD *ker = &ir.Event.KeyEvent; const MOUSE_EVENT_RECORD *mer = &ir.Event.MouseEvent; DWORD num_events; ReadConsoleInput (hnd, &ir, 1, &num_events); if (irp) *irp = ir; switch (ir.EventType) { case KEY_EVENT: TRACE ("KEY_EVENT: ch '%c', %s", ker->uChar.AsciiChar, ker->bKeyDown ? "down" : "up"); return console_key_read (ker, buf, max);#ifdef CONFIG_MOUSE case MOUSE_EVENT: TRACE("MOUSE_EVENT: flg %d, button-state %d, x %lu, y %lu", mer->dwEventFlags, mer->dwButtonState, mer->dwMousePosition.X, mer->dwMousePosition.Y); return console_mouse_read(mer, buf, max);#endif case WINDOW_BUFFER_SIZE_EVENT: strncpy(buf, "\E[R", max); return int_min(max, 3); } return 0;}static intconsole_peek(HANDLE hnd){ DWORD num = 0; char buf[10]; int rc = 0; if (!GetNumberOfConsoleInputEvents(hnd, &num) || num == 0) return 0; while (num--) { INPUT_RECORD ir; DWORD written; if (console_read(hnd, buf, sizeof(buf), &ir) > 0) { /* Put the record back */ WriteConsoleInput(hnd, &ir, 1, &written); rc++; } } return rc;}intwin32_write(int fd, const void *buf, unsigned len){ DWORD written = 0; int rc = -1; int orig_fd = fd; switch (what_fd_type(&fd)) { case FDT_FILE: rc = write(fd, buf, len); break; case FDT_PIPE: WriteFile((HANDLE) fd, buf, len, &written, NULL); rc = written; if (rc != len) errno = GetLastError(); break; case FDT_TERMINAL: if (isatty(STDOUT_FILENO) > 0) { /* TODO: pass to VT100 decoder */ WriteConsole ((HANDLE) fd, buf, len, &written, NULL); rc = written; } else { /* stdout redirected */ rc = write(STDOUT_FILENO, buf, len); } break; case FDT_SOCKET: rc = send(fd, buf, len, 0); if (rc != len) errno = WSAGetLastError(); break; } TRACE("fd %d, buf 0x%p, len %u -> rc %d; %s", orig_fd, buf, len, rc, rc < 0 ? win32_strerror(errno) : "okay"); return rc;}intwin32_read(int fd, void *buf, unsigned len){ int rc = -1; int orig_fd = fd; DWORD Read; switch (what_fd_type(&fd)) { case FDT_FILE: rc = read(fd, buf, len); break; case FDT_PIPE: if (!ReadFile((HANDLE) fd, buf, len, &Read, NULL)) rc = -1; else rc = Read; break; case FDT_TERMINAL: rc = console_read((HANDLE) fd, buf, len, NULL); if (rc == 0) TRACE("read 0 !!"); break; case FDT_SOCKET: rc = recv(fd, buf, len, 0); if (rc < 0) errno = WSAGetLastError(); break; } TRACE("fd %d, buf 0x%p, len %u -> rc %d; %s", orig_fd, buf, len, rc, rc < 0 ? win32_strerror(errno) : "okay"); return rc;}intwin32_close(int fd){ int rc = -1; int orig_fd = fd; switch (what_fd_type(&fd)) { case FDT_FILE: rc = close(fd); break; case FDT_PIPE: if (CloseHandle((HANDLE)fd)) rc = 0; break; case FDT_TERMINAL: rc = 0; /* nop */ break; case FDT_SOCKET: rc = closesocket(fd); if (rc < 0) errno = WSAGetLastError(); break; } TRACE("fd %d -> rc %d; %s", orig_fd, rc, rc < 0 ? win32_strerror(errno) : "okay"); return rc;}intwin32_ioctl(int fd, long option, int *flag){ char cmd[20]; int rc = 0, orig_fd = fd, flg = *flag; DWORD mode; switch (what_fd_type(&fd)) { case FDT_TERMINAL: if (option == FIONBIO) console_nbio = flg; break; case FDT_PIPE: assert(option == FIONBIO); mode = flg ? PIPE_NOWAIT : PIPE_WAIT; mode |= PIPE_READMODE_BYTE; SetNamedPipeHandleState((HANDLE) fd, &mode, NULL, NULL); rc = 0; break; case FDT_SOCKET: rc = ioctlsocket(fd, option, (unsigned long *) flag); if (rc < 0) errno = WSAGetLastError(); break; default: rc = 0; break; } if (option == FIONBIO) strcpy (cmd, "FIONBIO"); else snprintf (cmd, sizeof(cmd), "0x%08lX", option); TRACE("fd %d, cmd %s, flag %d -> flag %d, rc %d; %s", orig_fd, cmd, flg, *flag, rc, rc < 0 ? win32_strerror(errno) : "okay"); return rc;}intwin32_socket(int family, int type, int protocol){ SOCKET s = socket(family, type, protocol); int rc; if (s == INVALID_SOCKET) { rc = -1; errno = WSAGetLastError(); } else { rc = s + SOCK_SHIFT; } TRACE("family %d, type %d, proto %d -> rc %u", family, type, protocol, rc); return rc;}intwin32_connect(int fd, struct sockaddr *addr, int addr_len){ int rc = connect(fd - SOCK_SHIFT, addr, addr_len); if (rc < 0) errno = WSAGetLastError(); TRACE("fd %d -> rc %d; %s", fd, rc, rc < 0 ? win32_strerror(errno) : "okay"); return rc;}intwin32_getpeername (int fd, struct sockaddr *addr, int *addr_len){ int rc = getpeername(fd - SOCK_SHIFT, addr, addr_len); if (rc < 0) errno = WSAGetLastError(); TRACE("fd %d -> rc %d; %s", fd, rc, rc < 0 ? win32_strerror(errno) : "okay"); return rc;}intwin32_getsockname(int fd, struct sockaddr *addr, int *addr_len){ int rc = getsockname(fd - SOCK_SHIFT, addr, addr_len); if (rc < 0) errno = WSAGetLastError(); TRACE("fd %d -> rc %d; %s", fd, rc, rc < 0 ? win32_strerror(errno) : "okay"); return rc;}intwin32_accept(int fd, struct sockaddr *addr, int *addr_len){ int rc = accept(fd - SOCK_SHIFT, addr, addr_len); if (rc < 0) errno = WSAGetLastError(); TRACE("fd %d -> rc %d; %s", fd, rc, rc < 0 ? win32_strerror(errno) : "okay"); return rc;}intwin32_listen(int fd, int backlog){ int rc = listen(fd - SOCK_SHIFT, backlog); if (rc < 0) errno = WSAGetLastError(); TRACE("fd %d, backlog %d -> rc %d %s", fd, backlog, rc, rc < 0 ? win32_strerror(errno) : "okay"); return rc;}intwin32_bind(int fd, struct sockaddr *addr, int addr_len){ int rc = bind(fd-SOCK_SHIFT, addr, addr_len); if (rc < 0) errno = WSAGetLastError(); TRACE("fd %d -> rc %d; %s", fd, rc, rc < 0 ? win32_strerror(errno) : "okay"); return rc;}intwin32_getsockopt(int fd, int level, int option, void *optval, int *optlen)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -