-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
d37bd27
commit c6198a1
Showing
5 changed files
with
337 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,175 @@ | ||
/* | ||
* Copyright (c) 2023 Xuesong Peng <pengxuesong.cn@gmail.com> | ||
* | ||
* This program is free software: you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by | ||
* the Free Software Foundation, either version 3 of the License, or | ||
* (at your option) any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
* | ||
*/ | ||
|
||
WCHAR_SIZE() { | ||
return 2 | ||
} | ||
|
||
global CCHDEVICENAME := 32 | ||
global MONITOR_DEFAULTTONULL := 0 | ||
global MONITOR_DEFAULTTOPRIMARY := 1 | ||
global MONITOR_DEFAULTTONEAREST := 2 | ||
|
||
class Point extends Class { | ||
__New(x := 0, y := 0) { | ||
this.buff := Buffer(Point.struct_size(), 0) | ||
this.x := x | ||
this.y := y | ||
} | ||
|
||
static x_offset := (*) => 0 | ||
static y_offset := (*) => Point.x_offset() + INT_SIZE() | ||
static struct_size := (*) => Point.y_offset() + INT_SIZE() | ||
|
||
struct_ptr := (*) => this.buff.Ptr | ||
|
||
x { | ||
get => NumGet(this.struct_ptr(), Point.x_offset(), "Int") | ||
set => NumPut("Int", Value, this.struct_ptr(), Point.x_offset()) | ||
} | ||
y { | ||
get => NumGet(this.struct_ptr(), Point.y_offset(), "Int") | ||
set => NumPut("Int", Value, this.struct_ptr(), Point.y_offset()) | ||
} | ||
} | ||
|
||
class Rect extends Class { | ||
__New(left := 0, top := 0, right := 0, bottom := 0) { | ||
this.buff := Buffer(Rect.struct_size(), 0) | ||
this.left := left | ||
this.top := top | ||
this.right := right | ||
this.bottom := bottom | ||
} | ||
|
||
static left_offset := (*) => 0 | ||
static top_offset := (*) => Rect.left_offset() + INT_SIZE() | ||
static right_offset := (*) => Rect.top_offset() + INT_SIZE() | ||
static bottom_offset := (*) => Rect.right_offset() + INT_SIZE() | ||
static struct_size := (*) => Rect.bottom_offset() + INT_SIZE() | ||
|
||
struct_ptr := (*) => this.buff.Ptr | ||
|
||
left { | ||
get => NumGet(this.struct_ptr(), Rect.left_offset(), "Int") | ||
set => NumPut("Int", Value, this.struct_ptr(), Rect.left_offset()) | ||
} | ||
top { | ||
get => NumGet(this.struct_ptr(), Rect.top_offset(), "Int") | ||
set => NumPut("Int", Value, this.struct_ptr(), Rect.top_offset()) | ||
} | ||
right { | ||
get => NumGet(this.struct_ptr(), Rect.right_offset(), "Int") | ||
set => NumPut("Int", Value, this.struct_ptr(), Rect.right_offset()) | ||
} | ||
bottom { | ||
get => NumGet(this.struct_ptr(), Rect.bottom_offset(), "Int") | ||
set => NumPut("Int", Value, this.struct_ptr(), Rect.bottom_offset()) | ||
} | ||
|
||
width() { | ||
return this.right - this.left | ||
} | ||
height() { | ||
return this.bottom - this.top | ||
} | ||
} ; Rect | ||
|
||
class MonitorInfo extends Class { | ||
__New() { | ||
this.buff := Buffer(MonitorInfo.struct_size(), 0) | ||
NumPut("Int", MonitorInfo.struct_size(), this.struct_ptr()) | ||
} | ||
|
||
static size_offset := (*) => 0 | ||
static monitor_offset := (*) => MonitorInfo.size_offset() + INT_SIZE() | ||
static work_offset := (*) => MonitorInfo.monitor_offset() + Rect.struct_size() | ||
static flags_offset := (*) => MonitorInfo.work_offset() + Rect.struct_size() | ||
static struct_size := (*) => MonitorInfo.flags_offset() + INT_SIZE() | ||
|
||
struct_ptr := (*) => this.buff.Ptr | ||
|
||
size { | ||
get => NumGet(this.struct_ptr(), MonitorInfo.size_offset(), "Int") | ||
} | ||
monitor { | ||
get => Rect( | ||
NumGet(this.struct_ptr(), MonitorInfo.monitor_offset(), "Int"), | ||
NumGet(this.struct_ptr(), MonitorInfo.monitor_offset() + INT_SIZE(), "Int"), | ||
NumGet(this.struct_ptr(), MonitorInfo.monitor_offset() + INT_SIZE() * 2, "Int"), | ||
NumGet(this.struct_ptr(), MonitorInfo.monitor_offset() + INT_SIZE() * 3, "Int") | ||
) | ||
} | ||
work { | ||
get => Rect( | ||
NumGet(this.struct_ptr(), MonitorInfo.work_offset(), "Int"), | ||
NumGet(this.struct_ptr(), MonitorInfo.work_offset() + INT_SIZE(), "Int"), | ||
NumGet(this.struct_ptr(), MonitorInfo.work_offset() + INT_SIZE() * 2, "Int"), | ||
NumGet(this.struct_ptr(), MonitorInfo.work_offset() + INT_SIZE() * 3, "Int") | ||
) | ||
} | ||
flags { | ||
get => NumGet(this.struct_ptr(), MonitorInfo.flags_offset(), "Int") | ||
} | ||
} ; MonitorInfo | ||
|
||
class MonitorInfoEx extends MonitorInfo { | ||
__New() { | ||
this.buff := Buffer(MonitorInfoEx.struct_size(), 0) | ||
NumPut("Int", MonitorInfoEx.struct_size(), this.struct_ptr()) | ||
} | ||
|
||
static device_offset := (*) => MonitorInfoEx.flags_offset() + INT_SIZE() | ||
static struct_size := (*) => MonitorInfoEx.device_offset() + WCHAR_SIZE() * CCHDEVICENAME | ||
|
||
device { | ||
get => StrGet(this.struct_ptr() + MonitorInfoEx.device_offset(), CCHDEVICENAME) | ||
} | ||
} ; MonitorInfoEx | ||
|
||
class MonitorManage extends Class { | ||
static monitors := Map() | ||
|
||
static MonitorEnumProc(hMon, hDC, rect, data) { | ||
MonitorManage.monitors[hMon] := MonitorManage.GetMonitorInfo(hMon) | ||
return true | ||
} | ||
|
||
static EnumDisplayMonitors() { | ||
MonitorManage.monitors := Map() | ||
return DllCall("EnumDisplayMonitors", "Ptr", 0, "Ptr", 0, "Ptr", CallbackCreate(ObjBindMethod(MonitorManage, "MonitorEnumProc"), , 4), "Ptr", 0) | ||
} | ||
|
||
static MonitorFromWindow(hWnd, flags := MONITOR_DEFAULTTONULL) { | ||
return DllCall("MonitorFromWindow", "Ptr", hWnd, "UInt", flags) | ||
} | ||
|
||
static MonitorFromPoint(point, flags := MONITOR_DEFAULTTONULL) { | ||
return DllCall("MonitorFromPoint", "Int64", (point.x & 0xFFFFFFFF) | (point.y << 32), "UInt", flags) | ||
} | ||
|
||
static MonitorFromRect(rect, flags := MONITOR_DEFAULTTONULL) { | ||
return DllCall("MonitorFromRect", "Ptr", rect.struct_ptr(), "UInt", flags) | ||
} | ||
|
||
static GetMonitorInfo(hMon) { | ||
info := MonitorInfoEx() | ||
res := DllCall("GetMonitorInfo", "Ptr", hMon, "Ptr", info.struct_ptr()) | ||
return res ? info : 0 | ||
} | ||
} ; MonitorManage |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
/* | ||
* Copyright (c) 2023 Xuesong Peng <pengxuesong.cn@gmail.com> | ||
* | ||
* This program is free software: you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by | ||
* the Free Software Foundation, either version 3 of the License, or | ||
* (at your option) any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
* | ||
*/ | ||
#Requires AutoHotkey v2.0 32-bit | ||
; #NoTrayIcon | ||
|
||
#Include <RabbitCommon> | ||
#Include <librime-ahk\rime_levers_api> | ||
|
||
global rime | ||
global ERROR_ALREADY_EXISTS := 183 | ||
global INVALID_FILE_ATTRIBUTES := -1 | ||
global FILE_ATTRIBUTE_DIRECTORY := 0x00000010 | ||
|
||
arg := A_Args.Length > 0 ? A_Args[1] : "" | ||
RunDeployer(arg) | ||
|
||
RunDeployer(command) { | ||
conf := Configurator() | ||
conf.Initialize() | ||
deployment_scheduled := command == "deploy" | ||
if deployment_scheduled | ||
return conf.UpdateWorkspace() | ||
dict_management := command == "dict" | ||
if dict_management | ||
return 0 ; return conf.DictManagement() | ||
sync_user_dict := command == "sync" | ||
if sync_user_dict | ||
return conf.SyncUserData() | ||
installing := command == "install" | ||
return conf.Run(installing) | ||
} | ||
|
||
CreateFileIfNotExist(filename) { | ||
user_data_dir := A_ScriptDir . "\Rime\" | ||
if not InStr(DirExist(user_data_dir), "D") | ||
DirCreate(user_data_dir) | ||
filepath := user_data_dir . filename | ||
if not InStr(FileExist(filepath), "N") | ||
FileAppend("", filepath) | ||
} | ||
|
||
ConfigureSwitcher(levers, switcher_settings, reconfigured) { | ||
if not levers.load_settings(switcher_settings) | ||
return false | ||
; | ||
} | ||
|
||
class Configurator extends Class { | ||
__New() { | ||
CreateFileIfNotExist("default.custom.yaml") | ||
CreateFileIfNotExist("rabbit.custom.yaml") | ||
} | ||
|
||
Initialize() { | ||
rabbit_traits := CreateTraits() | ||
rime.setup(rabbit_traits) | ||
rime.deployer_initialize(0) | ||
} | ||
|
||
Run(installing) { | ||
levers := RimeLeversApi() | ||
if not levers | ||
return 1 | ||
|
||
switcher_settings := levers.switcher_settings_init() | ||
skip_switcher_settings := installing && !levers.is_first_run(switcher_settings) | ||
|
||
if installing | ||
this.UpdateWorkspace() | ||
|
||
return 0 | ||
} | ||
|
||
UpdateWorkspace(report_errors := false) { | ||
hMutex := DllCall("CreateMutex", "Ptr", 0, "Int", true, "Str", "RabbitDeployerMutex") | ||
if not hMutex { | ||
return 1 | ||
} | ||
if DllCall("GetLastError") == ERROR_ALREADY_EXISTS { | ||
DllCall("CloseHandle", "Ptr", hMutex) | ||
return 1 | ||
} | ||
|
||
{ | ||
rime.deploy() | ||
; rime.deploy_config_file("rabbit.yaml", "config_version") | ||
} | ||
|
||
DllCall("CloseHandle", "Ptr", hMutex) | ||
|
||
return 0 | ||
} | ||
|
||
; DictManagement() | ||
|
||
SyncUserData() { | ||
hMutex := DllCall("CreateMutex", "Ptr", 0, "Int", true, "Str", "RabbitDeployerMutex") | ||
if not hMutex { | ||
return 1 | ||
} | ||
if DllCall("GetLastError") == ERROR_ALREADY_EXISTS { | ||
DllCall("CloseHandle", "Ptr", hMutex) | ||
return 1 | ||
} | ||
|
||
{ | ||
if not rime.sync_user_data() { | ||
DllCall("CloseHandle", "Ptr", hMutex) | ||
return 1 | ||
} | ||
rime.join_maintenance_thread() | ||
} | ||
|
||
DllCall("CloseHandle", "Ptr", hMutex) | ||
|
||
return 0 | ||
} | ||
} |