diff options
author | Jason A. Donenfeld <Jason@zx2c4.com> | 2019-03-11 01:51:47 +0100 |
---|---|---|
committer | Jason A. Donenfeld <Jason@zx2c4.com> | 2019-03-12 03:00:46 -0600 |
commit | 72ffcd0a79fac3112f436c3841c3ca8b3815391d (patch) | |
tree | c084e1ea8396e21706c71ef7565c98f96e09cd55 /ui/syntax | |
parent | build: allow make to skip hidden directory to reduce stats (diff) | |
download | wireguard-windows-72ffcd0a79fac3112f436c3841c3ca8b3815391d.tar.xz wireguard-windows-72ffcd0a79fac3112f436c3841c3ca8b3815391d.zip |
ui: initial stab at a better confview
Diffstat (limited to 'ui/syntax')
-rw-r--r-- | ui/syntax/confview.c | 177 | ||||
-rw-r--r-- | ui/syntax/confview.go | 155 | ||||
-rw-r--r-- | ui/syntax/confview.h | 20 |
3 files changed, 0 insertions, 352 deletions
diff --git a/ui/syntax/confview.c b/ui/syntax/confview.c deleted file mode 100644 index b7e6657b..00000000 --- a/ui/syntax/confview.c +++ /dev/null @@ -1,177 +0,0 @@ -/* SPDX-License-Identifier: MIT - * - * Copyright (C) 2019 WireGuard LLC. All Rights Reserved. - */ - -#include <stdlib.h> -#include <stdbool.h> -#include <stdint.h> -#include <string.h> -#include <assert.h> -#include <windows.h> -#include <richedit.h> -#include <richole.h> -#include <tom.h> - -#include "confview.h" -#include "highlighter.h" - -static WNDPROC parent_proc; - -static void set_rtf(HWND hWnd, const char *str) -{ - SETTEXTEX settextex = { - .flags = ST_DEFAULT, - .codepage = CP_ACP - }; - CHARRANGE orig_selection; - POINT original_scroll; - - SendMessage(hWnd, WM_SETREDRAW, FALSE, 0); - SendMessage(hWnd, EM_EXGETSEL, 0, (LPARAM)&orig_selection); - SendMessage(hWnd, EM_GETSCROLLPOS, 0, (LPARAM)&original_scroll); - SendMessage(hWnd, EM_HIDESELECTION, TRUE, 0); - SendMessage(hWnd, EM_SETTEXTEX, (WPARAM)&settextex, (LPARAM)str); - SendMessage(hWnd, EM_SETSCROLLPOS, 0, (LPARAM)&original_scroll); - SendMessage(hWnd, EM_EXSETSEL, 0, (LPARAM)&orig_selection); - SendMessage(hWnd, EM_HIDESELECTION, FALSE, 0); - SendMessage(hWnd, WM_SETREDRAW, TRUE, 0); - HideCaret(hWnd); - RedrawWindow(hWnd, NULL, NULL, RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN); -} - -static void context_menu(HWND hWnd, INT x, INT y) -{ - GETTEXTLENGTHEX gettextlengthex = { - .flags = GTL_DEFAULT, - .codepage = CP_ACP - }; - /* This disturbing hack grabs the system edit menu normally used for the EDIT control. */ - HMENU popup, menu = LoadMenuW(GetModuleHandleW(L"comctl32.dll"), MAKEINTRESOURCEW(1)); - CHARRANGE selection = { 0 }; - bool has_selection, can_selectall; - UINT cmd; - - if (!menu) - return; - - SendMessage(hWnd, EM_EXGETSEL, 0, (LPARAM)&selection); - has_selection = selection.cpMax - selection.cpMin; - can_selectall = selection.cpMin || (selection.cpMax < SendMessage(hWnd, EM_GETTEXTLENGTHEX, (WPARAM)&gettextlengthex, 0)); - - popup = GetSubMenu(menu, 0); - EnableMenuItem(popup, WM_COPY, MF_BYCOMMAND | (has_selection ? MF_ENABLED : MF_GRAYED)); - EnableMenuItem(popup, EM_SETSEL, MF_BYCOMMAND | (can_selectall ? MF_ENABLED : MF_GRAYED)); - - /* Delete items that we don't handle. */ - for (int ctl = GetMenuItemCount(popup) - 1; ctl >= 0; --ctl) { - MENUITEMINFOW menu_item = { - .cbSize = sizeof(MENUITEMINFOW), - .fMask = MIIM_FTYPE | MIIM_ID - }; - if (!GetMenuItemInfoW(popup, ctl, MF_BYPOSITION, &menu_item)) - continue; - if (menu_item.fType & MFT_SEPARATOR) - continue; - switch (menu_item.wID) { - case WM_COPY: - case EM_SETSEL: - continue; - } - DeleteMenu(popup, ctl, MF_BYPOSITION); - } - /* Delete trailing and adjacent separators. */ - for (int ctl = GetMenuItemCount(popup) - 1, end = true; ctl >= 0; --ctl) { - MENUITEMINFOW menu_item = { - .cbSize = sizeof(MENUITEMINFOW), - .fMask = MIIM_FTYPE - }; - if (!GetMenuItemInfoW(popup, ctl, MF_BYPOSITION, &menu_item)) - continue; - if (!(menu_item.fType & MFT_SEPARATOR)) { - end = false; - continue; - } - if (!end && ctl) { - if (!GetMenuItemInfoW(popup, ctl - 1, MF_BYPOSITION, &menu_item)) - continue; - if (!(menu_item.fType & MFT_SEPARATOR)) - continue; - } - DeleteMenu(popup, ctl, MF_BYPOSITION); - } - - if (x == -1 && y == -1) { - RECT rect; - GetWindowRect(hWnd, &rect); - x = rect.left + (rect.right - rect.left) / 2; - y = rect.top + (rect.bottom - rect.top) / 2; - } - - if (GetFocus() != hWnd) - SetFocus(hWnd); - - cmd = TrackPopupMenu(popup, TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD | TPM_NONOTIFY, x, y, 0, hWnd, NULL); - if (cmd) - SendMessage(hWnd, cmd, 0, cmd == EM_SETSEL ? -1 : 0); - - DestroyMenu(menu); -} - -static LRESULT CALLBACK child_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) -{ - switch (Msg) { - case WM_CREATE: - HideCaret(hWnd); - break; - case WM_LBUTTONDOWN: - case WM_SETFOCUS: { - LRESULT ret = parent_proc(hWnd, Msg, wParam, lParam); - HideCaret(hWnd); - return ret; - } - case WM_SETCURSOR: - return 0; - case PV_NEWRTF: - set_rtf(hWnd, (const char *)wParam); - return 0; - case WM_CONTEXTMENU: - context_menu(hWnd, LOWORD(lParam), HIWORD(lParam)); - return 0; - } - return parent_proc(hWnd, Msg, wParam, lParam); -} - -static long has_loaded = 0; - -bool register_conf_view(void) -{ - WNDCLASSEXW class = { .cbSize = sizeof(WNDCLASSEXW) }; - WNDPROC pp; - HANDLE lib; - - if (InterlockedCompareExchange(&has_loaded, 1, 0) != 0) - return !!parent_proc; - - lib = LoadLibraryExW(L"msftedit.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32); - if (!lib) - return false; - - if (!GetClassInfoExW(NULL, L"RICHEDIT50W", &class)) - goto err; - pp = class.lpfnWndProc; - if (!pp) - goto err; - class.cbSize = sizeof(WNDCLASSEXW); - class.hInstance = GetModuleHandleW(NULL); - class.lpszClassName = L"WgConfView"; - class.lpfnWndProc = child_proc; - if (!RegisterClassExW(&class)) - goto err; - parent_proc = pp; - return true; - -err: - FreeLibrary(lib); - return false; -} diff --git a/ui/syntax/confview.go b/ui/syntax/confview.go deleted file mode 100644 index ef1c4530..00000000 --- a/ui/syntax/confview.go +++ /dev/null @@ -1,155 +0,0 @@ -/* SPDX-License-Identifier: MIT - * - * Copyright (C) 2019 WireGuard LLC. All Rights Reserved. - */ - -package syntax - -import ( - "fmt" - "strconv" - "strings" - "unsafe" - - "github.com/lxn/walk" - "golang.zx2c4.com/wireguard/windows/conf" -) - -// #include "confview.h" -import "C" - -type ConfView struct { - walk.WidgetBase - lastRtf string -} - -func (cv *ConfView) LayoutFlags() walk.LayoutFlags { - return walk.GrowableHorz | walk.GrowableVert | walk.GreedyHorz | walk.GreedyVert -} - -func (cv *ConfView) MinSizeHint() walk.Size { - return walk.Size{20, 12} -} - -func (cv *ConfView) SizeHint() walk.Size { - return walk.Size{200, 100} -} - -func (cv *ConfView) SetConfiguration(conf *conf.Config) { - var output strings.Builder - - if conf == nil { - t := byte(0) - cv.SendMessage(C.PV_NEWRTF, uintptr(unsafe.Pointer(&t)), 0) - return - } - - escape := func(s string) string { - var o strings.Builder - for i := 0; i < len(s); i++ { - if s[i] > 127 || s[i] == '}' || s[i] == '{' || s[i] == '\\' { - o.WriteString(fmt.Sprintf("\\'%d", s[i])) - continue - } - o.WriteByte(s[i]) - } - return o.String() - } - field := func(key, value string) { - output.WriteString(fmt.Sprintf("{\\b %s:} %s\\par", escape(key), escape(value))) - } - - output.WriteString("{\\rtf1\\ansi\\fs20") - - field("Interface", conf.Name) - field("Public Key", conf.Interface.PrivateKey.Public().String()) - if conf.Interface.ListenPort > 0 { - field("Listen Port", strconv.Itoa(int(conf.Interface.ListenPort))) - } - - if conf.Interface.Mtu > 0 { - field("MTU", strconv.Itoa(int(conf.Interface.Mtu))) - } - - if len(conf.Interface.Addresses) > 0 { - addrStrings := make([]string, len(conf.Interface.Addresses)) - for i, address := range conf.Interface.Addresses { - addrStrings[i] = address.String() - } - field("Address", strings.Join(addrStrings[:], ", ")) - } - - if len(conf.Interface.Dns) > 0 { - addrStrings := make([]string, len(conf.Interface.Dns)) - for i, address := range conf.Interface.Dns { - addrStrings[i] = address.String() - } - field("DNS", strings.Join(addrStrings[:], ", ")) - } - - for _, peer := range conf.Peers { - output.WriteString("\\par") - field("Peer", peer.PublicKey.String()) - - if !peer.PresharedKey.IsZero() { - output.WriteString("{\\b Preshared Key:} {\\i enabled}\\par") - } - - if len(peer.AllowedIPs) > 0 { - addrStrings := make([]string, len(peer.AllowedIPs)) - for i, address := range peer.AllowedIPs { - addrStrings[i] = address.String() - } - field("Allowed IPs", strings.Join(addrStrings[:], ", ")) - } - - if !peer.Endpoint.IsEmpty() { - field("Endpoint", peer.Endpoint.String()) - } - - if peer.PersistentKeepalive > 0 { - field("Persistent Keepalive", strconv.Itoa(int(peer.PersistentKeepalive))) - } - - if !peer.LastHandshakeTime.IsEmpty() { - field("Latest Handshake", peer.LastHandshakeTime.String()) - } - - if peer.RxBytes > 0 || peer.TxBytes > 0 { - field("Transfer", fmt.Sprintf("%s received, %s sent", peer.RxBytes.String(), peer.TxBytes.String())) - } - } - - output.WriteString("}") - - text := output.String() - if text == cv.lastRtf { - return - } - cv.lastRtf = text - - t := C.CString(text) - cv.SendMessage(C.PV_NEWRTF, uintptr(unsafe.Pointer(t)), 0) - C.free(unsafe.Pointer(t)) -} - -func NewConfView(parent walk.Container) (*ConfView, error) { - C.register_conf_view() - cv := &ConfView{ - lastRtf: "", - } - err := walk.InitWidget( - cv, - parent, - "WgConfView", - C.CONFVIEW_STYLE, - C.CONFVIEW_EXTSTYLE, - ) - if err != nil { - return nil, err - } - - cv.GraphicsEffects().Add(walk.InteractionEffect) - cv.GraphicsEffects().Add(walk.FocusEffect) - return cv, nil -} diff --git a/ui/syntax/confview.h b/ui/syntax/confview.h deleted file mode 100644 index d415dfe8..00000000 --- a/ui/syntax/confview.h +++ /dev/null @@ -1,20 +0,0 @@ -/* SPDX-License-Identifier: MIT - * - * Copyright (C) 2019 WireGuard LLC. All Rights Reserved. - */ - -#ifndef CONFVIEW_H -#define CONFVIEW_H - -#include <stdbool.h> -#include <windows.h> -#include <richedit.h> - -#define CONFVIEW_STYLE (WS_CHILD | WS_CLIPSIBLINGS | ES_MULTILINE | WS_VISIBLE | WS_VSCROLL | ES_READONLY | WS_TABSTOP | ES_WANTRETURN | ES_NOOLEDRAGDROP) -#define CONFVIEW_EXTSTYLE (WS_EX_TRANSPARENT) - -#define PV_NEWRTF (WM_USER + 0x3200) - -extern bool register_conf_view(void); - -#endif |