forked from michael/leanshot
screen layout detection
This commit is contained in:
parent
77393ca68c
commit
8dc13a1ad6
12 changed files with 328 additions and 74 deletions
135
Cargo.lock
generated
135
Cargo.lock
generated
|
@ -20,11 +20,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
|
||||
[[package]]
|
||||
name = "atty"
|
||||
version = "0.2.14"
|
||||
version = "0.2.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"hermit-abi 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"termion 1.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
|
@ -53,13 +53,23 @@ name = "cfg-if"
|
|||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "chrono"
|
||||
version = "0.4.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"num-integer 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num-traits 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"time 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "2.33.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -206,6 +216,11 @@ dependencies = [
|
|||
"rayon 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "0.2.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
|
@ -218,7 +233,9 @@ dependencies = [
|
|||
"anyhow 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"image 0.23.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"leanshot_x11 0.2.0",
|
||||
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"png 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"stderrlog 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"structopt 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
|
@ -236,6 +253,14 @@ name = "libc"
|
|||
version = "0.2.71"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lzw"
|
||||
version = "0.10.0"
|
||||
|
@ -308,6 +333,11 @@ dependencies = [
|
|||
"libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "numtoa"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.17"
|
||||
|
@ -390,6 +420,19 @@ dependencies = [
|
|||
"num_cpus 1.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.1.56"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "redox_termios"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scoped_threadpool"
|
||||
version = "0.1.9"
|
||||
|
@ -400,6 +443,18 @@ name = "scopeguard"
|
|||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "stderrlog"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"chrono 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"termcolor 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"thread_local 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.8.0"
|
||||
|
@ -445,6 +500,25 @@ dependencies = [
|
|||
"unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "termcolor"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"winapi-util 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "termion"
|
||||
version = "1.5.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"numtoa 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "textwrap"
|
||||
version = "0.11.0"
|
||||
|
@ -471,6 +545,15 @@ dependencies = [
|
|||
"syn 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thread_local"
|
||||
version = "0.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tiff"
|
||||
version = "0.5.0"
|
||||
|
@ -481,6 +564,15 @@ dependencies = [
|
|||
"miniz_oxide 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time"
|
||||
version = "0.1.43"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-segmentation"
|
||||
version = "1.6.0"
|
||||
|
@ -501,11 +593,24 @@ name = "unicode-xid"
|
|||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "unreachable"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "vec_map"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "void"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.8"
|
||||
|
@ -520,6 +625,14 @@ name = "winapi-i686-pc-windows-gnu"
|
|||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-util"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
|
@ -538,12 +651,13 @@ dependencies = [
|
|||
"checksum adler32 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "567b077b825e468cc974f0020d4082ee6e03132512f207ef1a02fd5d00d1f32d"
|
||||
"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
|
||||
"checksum anyhow 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)" = "85bb70cc08ec97ca5450e6eba421deeea5f172c0fc61f78b5357b2a8e8be195f"
|
||||
"checksum atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
|
||||
"checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652"
|
||||
"checksum autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d"
|
||||
"checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
||||
"checksum bytemuck 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "37fa13df2292ecb479ec23aa06f4507928bef07839be9ef15281411076629431"
|
||||
"checksum byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"
|
||||
"checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
||||
"checksum chrono 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "80094f509cf8b5ae86a4966a39b3ff66cd7e2a3e594accec3743ff3fabeab5b2"
|
||||
"checksum clap 2.33.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bdfa80d47f954d53a35a64987ca1422f495b8d6483c0fe9f7117b36c2a792129"
|
||||
"checksum color_quant 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0dbbb57365263e881e805dc77d94697c9118fd94d8da011240555aa7b23445bd"
|
||||
"checksum crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1"
|
||||
|
@ -560,8 +674,10 @@ dependencies = [
|
|||
"checksum image 0.23.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d534e95ad8b9d5aa614322d02352b4f1bf962254adcf02ac6f2def8be18498e8"
|
||||
"checksum inflate 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "1cdb29978cc5797bd8dcc8e5bf7de604891df2a8dc576973d71a281e916db2ff"
|
||||
"checksum jpeg-decoder 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)" = "5b47b4c4e017b01abdc5bcc126d2d1002e5a75bbe3ce73f9f4f311a916363704"
|
||||
"checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73"
|
||||
"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
"checksum libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)" = "9457b06509d27052635f90d6466700c65095fdf75409b3fbdd903e988b886f49"
|
||||
"checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
|
||||
"checksum lzw 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7d947cbb889ed21c2a84be6ffbaebf5b4e0f4340638cba0444907e38b56be084"
|
||||
"checksum maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00"
|
||||
"checksum memoffset 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b4fc2c02a7e374099d4ee95a193111f72d2110197fe200272371758f6c3643d8"
|
||||
|
@ -571,6 +687,7 @@ dependencies = [
|
|||
"checksum num-rational 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5c000134b5dbf44adc5cb772486d335293351644b801551abe8f75c84cfa4aef"
|
||||
"checksum num-traits 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)" = "ac267bcc07f48ee5f8935ab0d24f316fb722d7a1292e2913f0cc196b29ffd611"
|
||||
"checksum num_cpus 1.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3"
|
||||
"checksum numtoa 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b8f8bdf33df195859076e54ab11ee78a1b208382d3a26ec40d142ffc1ecc49ef"
|
||||
"checksum pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)" = "05da548ad6865900e60eaba7f589cc0783590a92e940c26953ff81ddbab2d677"
|
||||
"checksum png 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)" = "63daf481fdd0defa2d1d2be15c674fbfa1b0fd71882c303a91f9a79b3252c359"
|
||||
"checksum png 0.16.5 (registry+https://github.com/rust-lang/crates.io-index)" = "34ccdd66f6fe4b2433b07e4728e9a013e43233120427046e93ceb709c3a439bf"
|
||||
|
@ -580,23 +697,33 @@ dependencies = [
|
|||
"checksum quote 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37"
|
||||
"checksum rayon 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "62f02856753d04e03e26929f820d0a0a337ebe71f849801eea335d464b349080"
|
||||
"checksum rayon-core 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e92e15d89083484e11353891f1af602cc661426deb9564c298b270c726973280"
|
||||
"checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84"
|
||||
"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
|
||||
"checksum scoped_threadpool 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8"
|
||||
"checksum scopeguard 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
||||
"checksum stderrlog 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "32e5ee9b90a5452c570a0b0ac1c99ae9498db7e56e33d74366de7f2a7add7f25"
|
||||
"checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
|
||||
"checksum structopt 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "16c2cdbf9cc375f15d1b4141bc48aeef444806655cd0e904207edc8d68d86ed7"
|
||||
"checksum structopt-derive 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "53010261a84b37689f9ed7d395165029f9cc7abb9f56bbfe86bee2597ed25107"
|
||||
"checksum syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)" = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5"
|
||||
"checksum syn 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)" = "b5304cfdf27365b7585c25d4af91b35016ed21ef88f17ced89c7093b43dba8b6"
|
||||
"checksum termcolor 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb6bfa289a4d7c5766392812c0a1f4c1ba45afa1ad47803c11e1f407d846d75f"
|
||||
"checksum termion 1.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "c22cec9d8978d906be5ac94bceb5a010d885c626c4c8855721a4dbd20e3ac905"
|
||||
"checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
|
||||
"checksum thiserror 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)" = "7dfdd070ccd8ccb78f4ad66bf1982dc37f620ef696c6b5028fe2ed83dd3d0d08"
|
||||
"checksum thiserror-impl 1.0.20 (registry+https://github.com/rust-lang/crates.io-index)" = "bd80fc12f73063ac132ac92aceea36734f04a1d93c1240c6944e23a3b8841793"
|
||||
"checksum thread_local 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1697c4b57aeeb7a536b647165a2825faddffb1d3bad386d507709bd51a90bb14"
|
||||
"checksum tiff 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3f3b8a87c4da944c3f27e5943289171ac71a6150a79ff6bacfff06d159dfff2f"
|
||||
"checksum time 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438"
|
||||
"checksum unicode-segmentation 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0"
|
||||
"checksum unicode-width 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "caaa9d531767d1ff2150b9332433f32a24622147e5ebb1f26409d5da67afd479"
|
||||
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
|
||||
"checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
|
||||
"checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56"
|
||||
"checksum vec_map 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
|
||||
"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
|
||||
"checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6"
|
||||
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
"checksum winapi-util 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
|
||||
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
"checksum x11 2.18.2 (registry+https://github.com/rust-lang/crates.io-index)" = "77ecd092546cb16f25783a5451538e73afc8d32e242648d54f4ae5459ba1e773"
|
||||
|
|
|
@ -24,4 +24,6 @@ structopt = "0.2"
|
|||
anyhow = "1.0.31"
|
||||
image = "0.23.5"
|
||||
|
||||
leanshot_x11 = { version = "0.2", path = "x11", optional = true, features = ["xlib"] }
|
||||
leanshot_x11 = { version = "0.2", path = "x11", optional = true, features = ["xlib", "xinerama"] }
|
||||
log = "0.4.8"
|
||||
stderrlog = "0.4.3"
|
||||
|
|
47
src/lib.rs
47
src/lib.rs
|
@ -4,39 +4,34 @@
|
|||
|
||||
#[macro_use]
|
||||
extern crate anyhow;
|
||||
#[macro_use]
|
||||
extern crate structopt;
|
||||
extern crate leanshot_x11 as x11;
|
||||
extern crate structopt;
|
||||
|
||||
mod options;
|
||||
mod platform;
|
||||
|
||||
use anyhow::Result;
|
||||
|
||||
pub use crate::options::{Options, Region};
|
||||
use crate::platform::{x11::X11, Platform};
|
||||
pub use crate::platform::{x11::X11, Platform};
|
||||
|
||||
type Rectangle = x11::Rectangle;
|
||||
|
||||
/// The main capture routine
|
||||
pub fn capture(opt: &Options) -> Result<()> {
|
||||
let gui = X11::new()?;
|
||||
|
||||
let image = match opt.region {
|
||||
Region::ActiveWindow => {
|
||||
let window = gui.get_active_window()?;
|
||||
let image = gui.capture_window(window);
|
||||
}
|
||||
Region::Fullscreen | Region::Selection => {
|
||||
let mut image = gui.capture_full_screen()?;
|
||||
if let Region::Fullscreen = opt.region {
|
||||
let rect = gui.show_interactive_selection(image)?;
|
||||
// TODO: crop the image
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
unimplemented!("leanshot::capture")
|
||||
// imlib2::context_set_image(&capture);
|
||||
// capture.save_image(&opt.outfile)?;
|
||||
/// A region option
|
||||
#[allow(missing_docs)]
|
||||
pub enum Region {
|
||||
Fullscreen,
|
||||
ActiveWindow,
|
||||
Selection,
|
||||
}
|
||||
|
||||
impl Region {
|
||||
/// Convert string to Region enum
|
||||
// TODO: use FromStr trait
|
||||
pub fn from_str(x: &str) -> Result<Self> {
|
||||
match x {
|
||||
"fullscreen" => Ok(Region::Fullscreen),
|
||||
"window" => Ok(Region::ActiveWindow),
|
||||
"select" | "selection" => Ok(Region::Selection),
|
||||
_ => bail!("please choose a region from 'fullscreen', 'window', or 'select'"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
44
src/main.rs
44
src/main.rs
|
@ -1,9 +1,49 @@
|
|||
use std::path::PathBuf;
|
||||
|
||||
use anyhow::Result;
|
||||
use leanshot::{capture, Options};
|
||||
use leanshot::{Platform, Region, X11};
|
||||
use structopt::StructOpt;
|
||||
|
||||
#[allow(missing_docs)]
|
||||
pub fn main() -> Result<()> {
|
||||
stderrlog::new().module(module_path!()).init().unwrap();
|
||||
|
||||
let opt = Options::from_args();
|
||||
capture(&opt)
|
||||
|
||||
let gui = X11::new()?;
|
||||
|
||||
let screen_layout = gui.get_screen_layout()?;
|
||||
println!("{:?}", screen_layout);
|
||||
|
||||
let image = match opt.region {
|
||||
Region::ActiveWindow => {
|
||||
let window = gui.get_active_window()?;
|
||||
let image = gui.capture_window(window);
|
||||
}
|
||||
Region::Fullscreen | Region::Selection => {
|
||||
let mut image = gui.capture_full_screen()?;
|
||||
if let Region::Fullscreen = opt.region {
|
||||
let rect = gui.show_interactive_selection(image)?;
|
||||
// TODO: crop the image
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
unimplemented!("leanshot::capture")
|
||||
}
|
||||
|
||||
/// Options for screenshot
|
||||
#[derive(StructOpt)]
|
||||
pub struct Options {
|
||||
/// The region to select (fullscreen | window | select)
|
||||
#[structopt(parse(try_from_str = "Region::from_str"))]
|
||||
pub region: Region,
|
||||
|
||||
/// The file to save the screenshot to
|
||||
#[structopt(short = "o", long = "out", parse(from_os_str))]
|
||||
pub outfile: PathBuf,
|
||||
|
||||
/// Whether or not to also copy it to the clipboard
|
||||
#[structopt(short = "c")]
|
||||
pub clipboard: bool,
|
||||
}
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
use std::path::PathBuf;
|
||||
|
||||
use anyhow::Result;
|
||||
|
||||
/// A region option
|
||||
#[allow(missing_docs)]
|
||||
pub enum Region {
|
||||
Fullscreen,
|
||||
ActiveWindow,
|
||||
Selection,
|
||||
}
|
||||
|
||||
/// Options for screenshot
|
||||
#[derive(StructOpt)]
|
||||
pub struct Options {
|
||||
/// The region to select (fullscreen | window | select)
|
||||
#[structopt(parse(try_from_str = "Region::from_str"))]
|
||||
pub region: Region,
|
||||
|
||||
/// The file to save the screenshot to
|
||||
#[structopt(short = "o", long = "out", parse(from_os_str))]
|
||||
pub outfile: PathBuf,
|
||||
|
||||
/// Whether or not to also copy it to the clipboard
|
||||
#[structopt(short = "c")]
|
||||
pub clipboard: bool,
|
||||
}
|
||||
|
||||
impl Region {
|
||||
pub(self) fn from_str(x: &str) -> Result<Self> {
|
||||
match x {
|
||||
"fullscreen" => Ok(Region::Fullscreen),
|
||||
"window" => Ok(Region::ActiveWindow),
|
||||
"select" | "selection" => Ok(Region::Selection),
|
||||
_ => bail!("please choose a region from 'fullscreen', 'window', or 'select'"),
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,21 +1,50 @@
|
|||
#[cfg(feature = "x11")]
|
||||
pub mod x11;
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::hash::Hash;
|
||||
|
||||
use anyhow::Result;
|
||||
use image::RgbaImage;
|
||||
|
||||
use crate::Rectangle;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ScreenInfo {
|
||||
pub width: u16,
|
||||
pub height: u16,
|
||||
pub x: i16,
|
||||
pub y: i16,
|
||||
}
|
||||
|
||||
/// Set of functions that all platforms must implement
|
||||
pub trait Platform {
|
||||
/// Type of window handles
|
||||
type Window;
|
||||
|
||||
/// Type of images
|
||||
type Image: Image;
|
||||
|
||||
/// Type of screen handles
|
||||
type ScreenId: Hash;
|
||||
|
||||
/// Get a handle to the currently active window
|
||||
fn get_active_window(&self) -> Result<Self::Window>;
|
||||
|
||||
/// Capture a specific window by handle
|
||||
fn capture_window(&self, window: Self::Window) -> Result<Self::Image>;
|
||||
|
||||
/// Get the screen layout (list of screens, where they are)
|
||||
fn get_screen_layout(&self) -> Result<HashMap<Self::ScreenId, ScreenInfo>>;
|
||||
|
||||
/// Capture full screen
|
||||
fn capture_full_screen(&self) -> Result<Self::Image>;
|
||||
|
||||
/// Open the interactive selection interface
|
||||
fn show_interactive_selection(&self, image: Self::Image) -> Result<Rectangle>;
|
||||
}
|
||||
|
||||
/// Set of functions platform-specific images must implement
|
||||
pub trait Image {
|
||||
fn into_rgba_image(self) -> RgbaImage;
|
||||
}
|
||||
|
|
|
@ -1,17 +1,26 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
use anyhow::Result;
|
||||
use image::RgbaImage;
|
||||
use x11::xlib::{Display, Window};
|
||||
use x11::{
|
||||
xinerama::ScreensInfo,
|
||||
xlib::{Display, Window},
|
||||
};
|
||||
|
||||
use crate::platform::{Image as ImageT, Platform};
|
||||
use crate::platform::{Image as ImageT, Platform, ScreenInfo};
|
||||
use crate::Rectangle;
|
||||
|
||||
/// Interface to x11
|
||||
pub struct X11 {
|
||||
inner: Display,
|
||||
}
|
||||
|
||||
impl X11 {
|
||||
/// Create a new x11 instace
|
||||
pub fn new() -> Result<Self> {
|
||||
// TODO: configure connection string
|
||||
let display = Display::connect(":0")?;
|
||||
|
||||
Ok(X11 { inner: display })
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +28,7 @@ impl X11 {
|
|||
impl Platform for X11 {
|
||||
type Window = Window;
|
||||
type Image = Image;
|
||||
type ScreenId = i32;
|
||||
|
||||
fn get_active_window(&self) -> Result<Self::Window> {
|
||||
let (window, _) = self.inner.get_input_focus()?;
|
||||
|
@ -35,6 +45,24 @@ impl Platform for X11 {
|
|||
unimplemented!()
|
||||
}
|
||||
|
||||
fn get_screen_layout(&self) -> Result<HashMap<Self::ScreenId, ScreenInfo>> {
|
||||
let screens_info = ScreensInfo::query(&self.inner)?;
|
||||
Ok(screens_info
|
||||
.iter()
|
||||
.map(|(num, screen)| {
|
||||
(
|
||||
num,
|
||||
ScreenInfo {
|
||||
x: screen.x,
|
||||
y: screen.y,
|
||||
width: screen.width as u16,
|
||||
height: screen.height as u16,
|
||||
},
|
||||
)
|
||||
})
|
||||
.collect())
|
||||
}
|
||||
|
||||
fn show_interactive_selection(&self, image: Self::Image) -> Result<Rectangle> {
|
||||
let window = Window::create(&self.inner, None, Rectangle::new(0, 0, 500, 500))?;
|
||||
window.map();
|
||||
|
|
|
@ -9,6 +9,7 @@ authors = ["Michael Zhang <failed.down@gmail.com>"]
|
|||
default = []
|
||||
xlib = ["x11/xlib"]
|
||||
xrender = ["x11/xrender"]
|
||||
xinerama = ["x11/xlib", "x11/xinerama"]
|
||||
|
||||
[dependencies]
|
||||
libc = "0.2"
|
||||
|
|
|
@ -11,6 +11,9 @@ pub mod xlib;
|
|||
#[cfg(feature = "xrender")]
|
||||
pub mod xrender;
|
||||
|
||||
#[cfg(feature = "xinerama")]
|
||||
pub mod xinerama;
|
||||
|
||||
mod errors;
|
||||
mod rect;
|
||||
|
||||
|
|
3
x11/src/xinerama/mod.rs
Normal file
3
x11/src/xinerama/mod.rs
Normal file
|
@ -0,0 +1,3 @@
|
|||
mod screen_info;
|
||||
|
||||
pub use self::screen_info::ScreensInfo;
|
64
x11/src/xinerama/screen_info.rs
Normal file
64
x11/src/xinerama/screen_info.rs
Normal file
|
@ -0,0 +1,64 @@
|
|||
use x11::xinerama;
|
||||
|
||||
use crate::errors::Result;
|
||||
use crate::xlib::Display;
|
||||
|
||||
pub struct ScreensInfo {
|
||||
inner: *mut xinerama::XineramaScreenInfo,
|
||||
heads: isize,
|
||||
}
|
||||
|
||||
impl ScreensInfo {
|
||||
pub fn query(display: &Display) -> Result<Self> {
|
||||
let mut heads = 0;
|
||||
let inner = unsafe { xinerama::XineramaQueryScreens(display.inner, &mut heads as *mut _) };
|
||||
// TODO: check for error
|
||||
Ok(ScreensInfo {
|
||||
inner,
|
||||
heads: heads as isize,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn iter(&self) -> ScreenInfoIter {
|
||||
ScreenInfoIter(self, 0)
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for ScreensInfo {
|
||||
fn drop(&mut self) {
|
||||
unsafe { x11::xlib::XFree(self.inner as *mut _) };
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ScreenInfoIter<'a>(&'a ScreensInfo, isize);
|
||||
|
||||
pub struct ScreenInfo {
|
||||
pub x: i16,
|
||||
pub y: i16,
|
||||
pub width: i16,
|
||||
pub height: i16,
|
||||
}
|
||||
|
||||
impl<'a> Iterator for ScreenInfoIter<'a> {
|
||||
type Item = (i32, ScreenInfo);
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
if self.1 >= self.0.heads {
|
||||
return None;
|
||||
}
|
||||
|
||||
let screen = unsafe { self.0.inner.offset(self.1) };
|
||||
self.1 += 1;
|
||||
|
||||
unsafe {
|
||||
Some((
|
||||
(*screen).screen_number as i32,
|
||||
ScreenInfo {
|
||||
x: (*screen).x_org as i16,
|
||||
y: (*screen).y_org as i16,
|
||||
width: (*screen).width as i16,
|
||||
height: (*screen).height as i16,
|
||||
},
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
|
@ -11,7 +11,7 @@ use super::window::Window;
|
|||
|
||||
/// A connection to an X server.
|
||||
pub struct Display {
|
||||
inner: *mut xlib::Display,
|
||||
pub(crate) inner: *mut xlib::Display,
|
||||
}
|
||||
|
||||
pub struct Grab(pub(crate) *mut xlib::Display);
|
||||
|
|
Loading…
Reference in a new issue