sing-box-tray/win32.jai

377 lines
10 KiB
Plaintext

#import "Windows";
// DLL imports
user32 :: #system_library "user32";
gdi32 :: #system_library "gdi32";
shell32 :: #system_library "shell32";
// Structs
NOTIFYICONDATAW :: struct {
cbSize: u32;
hWnd: HWND;
uID: u32;
uFlags: u32;
uCallbackMessage: u32;
hIcon: HICON;
szTip: [128] u16;
dwState: u32;
dwStateMask: u32;
szInfo: [256] u16;
uTimeoutOrVersion: u32;
szInfoTitle: [64] u16;
dwInfoFlags: u32;
guidItem: GUID;
hBalloonIcon: HICON;
}
// Win32 constants
DEFAULT_GUI_FONT :: 17;
COLOR_WINDOW :: 5;
SS_LEFT :: 0x00000000;
ES_AUTOHSCROLL :: 0x0080;
ES_NUMBER :: 0x2000;
BS_DEFPUSHBUTTON :: 0x00000001;
BS_PUSHBUTTON :: 0x00000000;
GWLP_USERDATA :: -21;
WM_SETFONT :: 0x0030;
STARTF_USESHOWWINDOW : s32 : 0x00000001;
TPM_LEFTALIGN : u32 : 0x00000000;
TPM_RIGHTBUTTON : u32 : 0x00000002;
TPM_RETURNCMD : u32 : 0x00000100;
MF_STRING : u32 : 0x00000000;
MF_GRAYED : u32 : 0x00000001;
MF_DISABLED : u32 : 0x00000002;
MF_SEPARATOR : u32 : 0x00000800;
MF_CHECKED : u32 : 0x00000008;
MF_POPUP : u32 : 0x00000010;
MF_OWNERDRAW : u32 : 0x00000100;
ODT_MENU :: 1;
COLOR_MENU :: 4;
TRANSPARENT :: 1;
DT_SINGLELINE :: 0x00000020;
DT_VCENTER :: 0x00000004;
DI_NORMAL :: 0x0003;
PS_NULL :: 5;
COLOR_MENUTEXT :: 7;
FW_BOLD :: 700;
DEFAULT_CHARSET :: 1;
OUT_DEFAULT_PRECIS :: 0;
CLIP_DEFAULT_PRECIS :: 0;
CLEARTYPE_QUALITY :: 5;
DEFAULT_PITCH :: 0;
FF_DONTCARE :: 0;
WM_MEASUREITEM :: 0x002C;
WM_DRAWITEM :: 0x002B;
HPEN :: *void;
HFONT :: *void;
// Structs
DRAWITEMSTRUCT :: struct {
CtlType: u32;
CtlID: u32;
itemID: u32;
itemAction: u32;
itemState: u32;
hwndItem: HWND;
hDC: HDC;
rcItem: RECT;
itemData: u64;
}
MEASUREITEMSTRUCT :: struct {
CtlType: u32;
CtlID: u32;
itemID: u32;
itemWidth: u32;
itemHeight: u32;
itemData: u64;
}
// NIM constants
NIM_ADD : u32 : 0x00000000;
NIM_MODIFY : u32 : 0x00000001;
NIM_DELETE : u32 : 0x00000002;
NIF_MESSAGE : u32 : 0x00000001;
NIF_ICON : u32 : 0x00000002;
NIF_TIP : u32 : 0x00000004;
// Functions
IsDialogMessageW :: (hDlg: HWND, lpMsg: *MSG) -> BOOL #foreign user32;
GetWindowLongPtrW :: (hWnd: HWND, nIndex: s32) -> s64 #foreign user32;
Shell_NotifyIconW :: (dwMessage: u32, lpData: *NOTIFYICONDATAW) -> BOOL #foreign shell32;
CreatePopupMenu :: () -> HMENU #foreign user32;
DestroyMenu :: (hMenu: HMENU) -> BOOL #foreign user32;
AppendMenuW :: (hMenu: HMENU, uFlags: u32, uIDNewItem: s64, lpNewItem: LPCWSTR) -> BOOL #foreign user32;
TrackPopupMenu :: (hMenu: HMENU, uFlags: u32, x: s32, y: s32, nReserved: s32, hWnd: HWND, prcRect: *RECT) -> BOOL #foreign user32;
SetForegroundWindow :: (hWnd: HWND) -> BOOL #foreign user32;
EnableWindow :: (hWnd: HWND, bEnable: BOOL) -> BOOL #foreign user32;
PostMessageW :: (hWnd: HWND, Msg: u32, wParam: WPARAM, lParam: LPARAM) -> BOOL #foreign user32;
SetTextColor :: (hdc: HDC, color: u32) -> u32 #foreign gdi32;
SetBkMode :: (hdc: HDC, mode: s32) -> s32 #foreign gdi32;
DrawTextW :: (hdc: HDC, lpchText: *u16, cchText: s32, lprc: *RECT, format: u32) -> s32 #foreign user32;
GetSysColorBrush :: (nIndex: s32) -> HBRUSH #foreign user32;
FillRect :: (hDC: HDC, lprc: *RECT, hbr: HBRUSH) -> s32 #foreign user32;
DrawIconEx :: (hdc: HDC, xLeft: s32, yTop: s32, hIcon: HICON, cxWidth: s32, cyWidth: s32, istepIfAniCur: u32, hbrFlickerFreeDraw: HBRUSH, diFlags: u32) -> BOOL #foreign user32;
CreateFontW :: (
nHeight: s32,
nWidth: s32,
nEscapement: s32,
nOrientation: s32,
fnWeight: s32,
fdwItalic: DWORD,
fdwUnderline: DWORD,
fdwStrikeOut: DWORD,
fdwCharSet: DWORD,
fdwOutputPrecision: DWORD,
fdwClipPrecision: DWORD,
fdwQuality: DWORD,
fdwPitchAndFamily: DWORD,
lpszFace: *u16
) -> HFONT #foreign gdi32;
CreatePen :: (iStyle: s32, cWidth: s32, color: u32) -> HPEN #foreign gdi32;
Ellipse :: (hdc: HDC, left: s32, top: s32, right: s32, bottom: s32) -> BOOL #foreign gdi32;
GetSysColor :: (nIndex: s32) -> u32 #foreign user32;
// Custom message IDs
WM_USER :: 0x0400;
WM_TRAY_CALLBACK :: WM_USER + 1;
WM_RESTART_SINGBOX :: WM_USER + 2;
// Context menu command IDs
CMD_STATUS :: 1001;
CMD_START_STOP :: 1002;
CMD_SET_URL :: 1003;
CMD_UPDATE_NOW :: 1004;
CMD_EXIT :: 1005;
CMD_MODE_PROXY :: 1006;
CMD_MODE_SYS_PROXY :: 1007;
CMD_SET_PORT :: 1008;
CMD_TOGGLE_AUTOSTART:: 1009;
CMD_UPDATE_NEVER :: 1010;
CMD_UPDATE_30M :: 1011;
CMD_UPDATE_1H :: 1012;
CMD_UPDATE_6H :: 1013;
CMD_UPDATE_12H :: 1014;
CMD_UPDATE_DAILY :: 1015;
CMD_UPDATE_3D :: 1016;
CMD_UPDATE_WEEKLY :: 1017;
CMD_CONFIG_DIR :: 1018;
// Boolean constants
FALSE :: 0;
TRUE :: 1;
// CREATESTRUCTW definition
CREATESTRUCTW :: struct {
lpCreateParams: *void;
hInstance: HINSTANCE;
hMenu: HMENU;
hwndParent: HWND;
cy: s32;
cx: s32;
y: s32;
x: s32;
style: s32;
lpszName: LPCWSTR;
lpszClass: LPCWSTR;
dwExStyle: DWORD;
}
kernel32 :: #system_library "kernel32";
LONG_PTR :: s64;
UINT_PTR :: u64;
// Window and Message Functions
GetMessageW :: (lpMsg: *MSG, hWnd: HWND, wMsgFilterMin: u32, wMsgFilterMax: u32) -> BOOL #foreign user32;
SetTimer :: (hWnd: HWND, nIDEvent: UINT_PTR, uElapse: u32, lpTimerFunc: *void) -> UINT_PTR #foreign user32;
KillTimer :: (hWnd: HWND, uIDEvent: UINT_PTR) -> BOOL #foreign user32;
GetWindowTextW :: (hWnd: HWND, lpString: *u16, nMaxCount: s32) -> s32 #foreign user32;
GetWindowTextLengthW :: (hWnd: HWND) -> s32 #foreign user32;
SendMessageW :: (hWnd: HWND, Msg: u32, wParam: WPARAM, lParam: LPARAM) -> LRESULT #foreign user32;
SetEvent :: (hEvent: HANDLE) -> BOOL #foreign kernel32;
GetEnvironmentVariableW :: (lpName: *u16, lpBuffer: *u16, nSize: u32) -> u32 #foreign kernel32;
CreateDirectoryW :: (lpPathName: *u16, lpSecurityAttributes: *void) -> BOOL #foreign kernel32;
SetFocus :: (hWnd: HWND) -> HWND #foreign user32;
LOWORD :: (val: WPARAM) -> u16 {
return cast(u16) (val & 0xffff);
}
HIWORD :: (val: WPARAM) -> u16 {
return cast(u16) ((val >> 16) & 0xffff);
}
PostThreadMessageW :: (idThread: DWORD, Msg: u32, wParam: WPARAM, lParam: LPARAM) -> BOOL #foreign user32;
advapi32 :: #system_library "advapi32";
wininet :: #system_library "wininet";
LSTATUS :: s32;
REGSAM :: u32;
HKEY_CURRENT_USER :: cast(HKEY) 0x80000001;
KEY_WRITE :: 0x20006;
KEY_READ :: 0x20019;
INTERNET_OPTION_SETTINGS_CHANGED :: 39;
INTERNET_OPTION_REFRESH :: 37;
RegOpenKeyExW :: (hKey: HKEY, lpSubKey: LPCWSTR, ulOptions: DWORD, samDesired: REGSAM, phkResult: *HKEY) -> LSTATUS #foreign advapi32;
RegSetValueExW :: (hKey: HKEY, lpValueName: LPCWSTR, Reserved: DWORD, dwType: DWORD, lpData: *u8, cbData: DWORD) -> LSTATUS #foreign advapi32;
RegCloseKey :: (hKey: HKEY) -> LSTATUS #foreign advapi32;
RegDeleteValueW :: (hKey: HKEY, lpValueName: LPCWSTR) -> LSTATUS #foreign advapi32;
RegQueryValueExW :: (
hKey: HKEY,
lpValueName: LPCWSTR,
lpReserved: *DWORD,
lpType: *DWORD,
lpData: *u8,
lpcbData: *DWORD
) -> LSTATUS #foreign advapi32;
InternetSetOptionW :: (hInternet: HANDLE, dwOption: DWORD, lpBuffer: *void, dwBufferLength: DWORD) -> BOOL #foreign wininet;
HINTERNET :: *void;
INTERNET_OPEN_TYPE_PRECONFIG :: 0;
INTERNET_FLAG_RELOAD :: 0x80000000;
INTERNET_FLAG_SECURE :: 0x00800000;
INTERNET_FLAG_NO_CACHE_WRITE :: 0x04000000;
HTTP_QUERY_STATUS_CODE :: 19;
HTTP_QUERY_FLAG_NUMBER :: 0x20000000;
InternetOpenW :: (
lpszAgent: LPCWSTR,
dwAccessType: DWORD,
lpszProxy: LPCWSTR,
lpszProxyBypass: LPCWSTR,
dwFlags: DWORD
) -> HINTERNET #foreign wininet;
InternetOpenUrlW :: (
hInternet: HINTERNET,
lpszUrl: LPCWSTR,
lpszHeaders: LPCWSTR,
dwHeadersLength: DWORD,
dwFlags: DWORD,
dwContext: u64
) -> HINTERNET #foreign wininet;
InternetReadFile :: (
hFile: HINTERNET,
lpBuffer: *void,
dwNumberOfBytesToRead: DWORD,
lpdwNumberOfBytesRead: *DWORD
) -> BOOL #foreign wininet;
InternetCloseHandle :: (
hInternet: HINTERNET
) -> BOOL #foreign wininet;
HttpQueryInfoW :: (
hRequest: HINTERNET,
dwInfoLevel: DWORD,
lpBuffer: *void,
lpdwBufferLength: *DWORD,
lpdwIndex: *DWORD
) -> BOOL #foreign wininet;
SHSTOCKICONINFO :: struct {
cbSize: DWORD;
hIcon: HICON;
iSysImageIndex: s32;
iIcon: s32;
szPath: [260] u16;
}
SIID_DRIVENET :: 9;
SIID_WORLD :: 13;
SIID_SERVER :: 15;
SIID_ERROR :: 80;
SIID_INTERNET :: 104;
SHGSI_ICON :: 0x00000100;
SHGSI_SMALLICON :: 0x00000001;
SHGetStockIconInfo :: (
siid: s32,
uFlags: u32,
psii: *SHSTOCKICONINFO
) -> s32 #foreign shell32;
ShellExecuteW :: (
hwnd: HWND,
lpOperation: LPCWSTR,
lpFile: LPCWSTR,
lpParameters: LPCWSTR,
lpDirectory: LPCWSTR,
nShowCmd: s32
) -> HANDLE #foreign shell32;
DestroyIcon :: (hIcon: HICON) -> BOOL #foreign user32;
wcslen :: (str: *u16) -> int {
len := 0;
while str[len] != 0 {
len += 1;
}
return len;
}
set_windows_system_proxy :: (enable: bool, server: string) -> bool {
hKey: HKEY;
subkey := utf8_to_wide("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings");
status := RegOpenKeyExW(HKEY_CURRENT_USER, subkey, 0, KEY_WRITE, *hKey);
if status != 0 {
return false;
}
defer RegCloseKey(hKey);
enable_val: u32 = ifx enable then cast(u32) 1 else cast(u32) 0;
status = RegSetValueExW(hKey, utf8_to_wide("ProxyEnable"), 0, REG_DWORD, cast(*u8) *enable_val, size_of(u32));
if status != 0 return false;
if enable {
wide_server := utf8_to_wide(server);
server_len_bytes := cast(u32) ((wcslen(wide_server) + 1) * 2);
status = RegSetValueExW(hKey, utf8_to_wide("ProxyServer"), 0, REG_SZ, cast(*u8) wide_server, server_len_bytes);
if status != 0 return false;
}
InternetSetOptionW(null, INTERNET_OPTION_SETTINGS_CHANGED, null, 0);
InternetSetOptionW(null, INTERNET_OPTION_REFRESH, null, 0);
return true;
}
RGB :: (r: u32, g: u32, b: u32) -> u32 {
return r | (g << 8) | (b << 16);
}