runned cargo fmt on crate code
This commit is contained in:
parent
4a943c124e
commit
223b353101
@ -2,39 +2,56 @@
|
||||
<project version="4">
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="310aeab2-4737-4e8e-b7eb-0aac10d104a3" name="Default" comment="">
|
||||
<change afterPath="$PROJECT_DIR$/examples/Crossterm 0.2.2 - New Version (Not finished)/program_examples/first_depth_search/map.rs" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/examples/Crossterm 0.2.2 - New Version (Not finished)/program_examples/first_depth_search/mod.rs" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/examples/Crossterm 0.2.2 - New Version (Not finished)/program_examples/first_depth_search/variables.rs" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/examples/Crossterm 0.2.2 - New Version (Not finished)/program_examples/mod.rs" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/src/shared/environment.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/examples/Crossterm 0.2.2 - New Version (Not finished)/bin.rs" beforeDir="false" afterPath="$PROJECT_DIR$/examples/Crossterm 0.2.2 - New Version (Not finished)/bin.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/examples/Crossterm 0.2.2 - New Version (Not finished)/color/mod.rs" beforeDir="false" afterPath="$PROJECT_DIR$/examples/Crossterm 0.2.2 - New Version (Not finished)/color/mod.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/examples/Crossterm 0.2.2 - New Version (Not finished)/cursor/mod.rs" beforeDir="false" afterPath="$PROJECT_DIR$/examples/Crossterm 0.2.2 - New Version (Not finished)/cursor/mod.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/examples/Crossterm 0.2.2 - New Version (Not finished)/program_examples/mod.rs" beforeDir="false" afterPath="$PROJECT_DIR$/examples/Crossterm 0.2.2 - New Version (Not finished)/program_examples/mod.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/examples/Crossterm 0.2.2 - New Version (Not finished)/terminal/alternate_screen.rs" beforeDir="false" afterPath="$PROJECT_DIR$/examples/Crossterm 0.2.2 - New Version (Not finished)/terminal/alternate_screen.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/examples/Crossterm 0.2.2 - New Version (Not finished)/terminal/mod.rs" beforeDir="false" afterPath="$PROJECT_DIR$/examples/Crossterm 0.2.2 - New Version (Not finished)/terminal/mod.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/examples/Crossterm 0.2.2 - New Version (Not finished)/terminal/raw_mode.rs" beforeDir="false" afterPath="$PROJECT_DIR$/examples/Crossterm 0.2.2 - New Version (Not finished)/terminal/raw_mode.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/examples/Crossterm 0.2.2 - New Version (Not finished)/terminal/terminal.rs" beforeDir="false" afterPath="$PROJECT_DIR$/examples/Crossterm 0.2.2 - New Version (Not finished)/terminal/terminal.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/cursor/ansi_cursor.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/cursor/ansi_cursor.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/cursor/cursor.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/cursor/cursor.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/cursor/mod.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/cursor/mod.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/cursor/winapi_cursor.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/cursor/winapi_cursor.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/kernel/mod.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/kernel/mod.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/kernel/unix_kernel/mod.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/kernel/unix_kernel/mod.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/kernel/unix_kernel/terminal.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/kernel/unix_kernel/terminal.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/kernel/windows_kernel/ansi_support.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/kernel/windows_kernel/ansi_support.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/kernel/windows_kernel/cursor.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/kernel/windows_kernel/cursor.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/kernel/windows_kernel/kernel.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/kernel/windows_kernel/kernel.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/kernel/windows_kernel/mod.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/kernel/windows_kernel/mod.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/kernel/windows_kernel/terminal.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/kernel/windows_kernel/terminal.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/lib.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/lib.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/manager/ansi_manager.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/manager/ansi_manager.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/manager/manager.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/manager/manager.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/manager/mod.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/manager/mod.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/manager/win_manager.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/manager/win_manager.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/shared/environment.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/shared/environment.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/shared/functions.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/shared/functions.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/shared/macros.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/shared/macros.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/shared/mod.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/shared/mod.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/shared/raw.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/shared/raw.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/shared/screen.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/shared/screen.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/shared/traits.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/shared/traits.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/state/command_manager.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/state/command_manager.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/state/commands/mod.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/state/commands/mod.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/state/commands/shared_commands.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/state/commands/shared_commands.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/state/commands/unix_command.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/state/commands/unix_command.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/state/commands/win_commands.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/state/commands/win_commands.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/state/context.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/state/context.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/state/mod.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/state/mod.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/state/state_manager.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/state/state_manager.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/style/color/ansi_color.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/style/color/ansi_color.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/style/color/color.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/style/color/color.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/style/color/mod.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/style/color/mod.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/style/color/winapi_color.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/style/color/winapi_color.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/style/mod.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/style/mod.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/style/styles/mod.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/style/styles/mod.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/style/styles/objectstyle.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/style/styles/objectstyle.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/style/styles/styledobject.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/style/styles/styledobject.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/terminal/ansi_terminal.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/terminal/ansi_terminal.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/terminal/mod.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/terminal/mod.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/terminal/terminal.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/terminal/terminal.rs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/src/terminal/winapi_terminal.rs" beforeDir="false" afterPath="$PROJECT_DIR$/src/terminal/winapi_terminal.rs" afterDir="false" />
|
||||
</list>
|
||||
@ -47,88 +64,11 @@
|
||||
</component>
|
||||
<component name="FileEditorManager">
|
||||
<leaf SIDE_TABS_SIZE_LIMIT_KEY="300">
|
||||
<file leaf-file-name="cursor.rs" pinned="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/src/cursor/cursor.rs">
|
||||
<file leaf-file-name="raw.rs" pinned="false" current-in-tab="true">
|
||||
<entry file="file://$PROJECT_DIR$/src/shared/raw.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="408">
|
||||
<caret line="313" column="11" selection-start-line="313" selection-start-column="11" selection-end-line="313" selection-end-column="11" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
<file leaf-file-name="bin.rs" pinned="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/examples/Crossterm 0.2.2 - New Version (Not finished)/bin.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="459">
|
||||
<caret line="27" column="61" selection-start-line="27" selection-start-column="61" selection-end-line="27" selection-end-column="61" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
<file leaf-file-name="winapi_cursor.rs" pinned="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/src/cursor/winapi_cursor.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="498">
|
||||
<caret line="66" column="25" selection-start-line="66" selection-start-column="25" selection-end-line="66" selection-end-column="25" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
<file leaf-file-name="alternate_screen.rs" pinned="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/examples/Crossterm 0.2.2 - New Version (Not finished)/terminal/alternate_screen.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="204">
|
||||
<caret line="18" column="13" selection-start-line="18" selection-start-column="13" selection-end-line="18" selection-end-column="13" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
<file leaf-file-name="screen.rs" pinned="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/src/shared/screen.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="340">
|
||||
<caret line="26" column="11" selection-start-line="26" selection-start-column="11" selection-end-line="26" selection-end-column="11" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
<file leaf-file-name="terminal.rs" pinned="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/src/terminal/terminal.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="742">
|
||||
<caret line="197" column="11" selection-start-line="197" selection-start-column="11" selection-end-line="197" selection-end-column="11" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
<file leaf-file-name="kernel.rs" pinned="false" current-in-tab="true">
|
||||
<entry file="file://$PROJECT_DIR$/src/kernel/windows_kernel/kernel.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="540">
|
||||
<caret line="203" column="5" selection-start-line="203" selection-start-column="5" selection-end-line="203" selection-end-column="5" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
<file leaf-file-name="mod.rs" pinned="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/src/kernel/mod.rs">
|
||||
<provider selected="true" editor-type-id="text-editor" />
|
||||
</entry>
|
||||
</file>
|
||||
<file leaf-file-name="winapi_color.rs" pinned="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/src/style/color/winapi_color.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="158">
|
||||
<caret line="64" column="69" selection-start-line="64" selection-start-column="69" selection-end-line="64" selection-end-column="69" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
</file>
|
||||
<file leaf-file-name="ansi_terminal.rs" pinned="false" current-in-tab="false">
|
||||
<entry file="file://$PROJECT_DIR$/src/terminal/ansi_terminal.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="391">
|
||||
<caret line="45" column="66" selection-start-line="45" selection-start-column="66" selection-end-line="45" selection-end-column="66" />
|
||||
<state relative-caret-position="357">
|
||||
<caret line="53" lean-forward="true" selection-start-line="53" selection-end-line="53" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
@ -209,7 +149,6 @@
|
||||
<option value="$PROJECT_DIR$/src/terminal/mod.rs" />
|
||||
<option value="$PROJECT_DIR$/examples/Crossterm 0.2.2 - New Version (Not finished)/terminal/terminal.rs" />
|
||||
<option value="$PROJECT_DIR$/src/style/styles/styledobject.rs" />
|
||||
<option value="$PROJECT_DIR$/src/shared/raw.rs" />
|
||||
<option value="$PROJECT_DIR$/examples/Crossterm 0.2.2 - New Version (Not finished)/terminal/mod.rs" />
|
||||
<option value="$PROJECT_DIR$/examples/Crossterm 0.2.2 - New Version (Not finished)/color/mod.rs" />
|
||||
<option value="$PROJECT_DIR$/examples/Crossterm 0.2.2 - New Version (Not finished)/cursor/mod.rs" />
|
||||
@ -248,6 +187,7 @@
|
||||
<option value="$PROJECT_DIR$/src/terminal/ansi_terminal.rs" />
|
||||
<option value="$PROJECT_DIR$/examples/Crossterm 0.2.2 - New Version (Not finished)/terminal/alternate_screen.rs" />
|
||||
<option value="$PROJECT_DIR$/src/kernel/windows_kernel/kernel.rs" />
|
||||
<option value="$PROJECT_DIR$/src/shared/raw.rs" />
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
@ -622,12 +562,12 @@
|
||||
<workItem from="1530289442537" duration="10502000" />
|
||||
<workItem from="1530344478032" duration="18289000" />
|
||||
<workItem from="1530446561530" duration="7222000" />
|
||||
<workItem from="1530473645162" duration="3874000" />
|
||||
<workItem from="1530473645162" duration="4134000" />
|
||||
</task>
|
||||
<servers />
|
||||
</component>
|
||||
<component name="TimeTrackingManager">
|
||||
<option name="totallyTimeSpent" value="681698000" />
|
||||
<option name="totallyTimeSpent" value="681958000" />
|
||||
</component>
|
||||
<component name="ToolWindowManager">
|
||||
<frame x="-8" y="-8" width="2576" height="1056" extended-state="6" />
|
||||
@ -699,27 +639,6 @@
|
||||
<option name="myLimit" value="2678400000" />
|
||||
</component>
|
||||
<component name="editorHistoryManager">
|
||||
<entry file="file://$PROJECT_DIR$/examples/Crossterm 0.2.2 - New Version (Not finished)/terminal/mod.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="17">
|
||||
<caret line="1" column="114" selection-start-line="1" selection-start-column="114" selection-end-line="1" selection-end-column="114" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/src/manager/mod.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="408">
|
||||
<caret line="24" column="47" selection-start-line="24" selection-start-column="47" selection-end-line="24" selection-end-column="47" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$USER_HOME$/.rustup/toolchains/stable-x86_64-pc-windows-msvc/lib/rustlib/src/rust/src/libcore/ops/drop.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="204">
|
||||
<caret line="94" column="10" selection-start-line="94" selection-start-column="10" selection-end-line="94" selection-end-column="10" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/src/state/state_manager.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="442">
|
||||
@ -862,13 +781,6 @@
|
||||
<state relative-caret-position="-255" />
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/src/kernel/windows_kernel/ansi_support.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="187">
|
||||
<caret line="11" column="31" selection-start-line="11" selection-start-column="31" selection-end-line="11" selection-end-column="31" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$USER_HOME$/.rustup/toolchains/stable-x86_64-pc-windows-msvc/lib/rustlib/src/rust/src/liballoc/rc.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="275">
|
||||
@ -918,17 +830,6 @@
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/src/kernel/windows_kernel/terminal.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="17">
|
||||
<caret line="1" column="7" selection-start-line="1" selection-start-column="7" selection-end-line="1" selection-end-column="7" />
|
||||
<folding>
|
||||
<element signature="e#346#347#0" expanded="true" />
|
||||
<element signature="e#379#380#0" expanded="true" />
|
||||
</folding>
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/src/terminal/winapi_terminal.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="424">
|
||||
@ -936,13 +837,6 @@
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/src/kernel/unix_kernel/terminal.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="297">
|
||||
<caret line="43" column="7" selection-start-line="43" selection-start-column="7" selection-end-line="43" selection-end-column="7" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/src/shared/functions.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="228">
|
||||
@ -950,13 +844,6 @@
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/src/kernel/windows_kernel/cursor.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="544">
|
||||
<caret line="32" column="23" selection-start-line="32" selection-start-column="23" selection-end-line="32" selection-end-column="23" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/src/manager/manager.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="408">
|
||||
@ -973,25 +860,22 @@
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/src/style/color/winapi_color.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="158">
|
||||
<caret line="64" column="69" selection-start-line="64" selection-start-column="69" selection-end-line="64" selection-end-column="69" />
|
||||
<state relative-caret-position="141">
|
||||
<caret line="63" column="69" selection-start-line="63" selection-start-column="69" selection-end-line="63" selection-end-column="69" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/src/terminal/ansi_terminal.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="391">
|
||||
<caret line="45" column="66" selection-start-line="45" selection-start-column="66" selection-end-line="45" selection-end-column="66" />
|
||||
<state relative-caret-position="357">
|
||||
<caret line="43" column="66" selection-start-line="43" selection-start-column="66" selection-end-line="43" selection-end-column="66" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/src/kernel/mod.rs">
|
||||
<provider selected="true" editor-type-id="text-editor" />
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/examples/Crossterm 0.2.2 - New Version (Not finished)/bin.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="459">
|
||||
<caret line="27" column="61" selection-start-line="27" selection-start-column="61" selection-end-line="27" selection-end-column="61" />
|
||||
<state relative-caret-position="442">
|
||||
<caret line="26" column="61" selection-start-line="26" selection-start-column="61" selection-end-line="26" selection-end-column="61" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
@ -1004,36 +888,80 @@
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/src/terminal/terminal.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="742">
|
||||
<caret line="197" column="11" selection-start-line="197" selection-start-column="11" selection-end-line="197" selection-end-column="11" />
|
||||
<state relative-caret-position="844">
|
||||
<caret line="200" column="11" selection-start-line="200" selection-start-column="11" selection-end-line="200" selection-end-column="11" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/examples/Crossterm 0.2.2 - New Version (Not finished)/terminal/alternate_screen.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="204">
|
||||
<caret line="18" column="13" selection-start-line="18" selection-start-column="13" selection-end-line="18" selection-end-column="13" />
|
||||
<state relative-caret-position="187">
|
||||
<caret line="17" column="13" selection-start-line="17" selection-start-column="13" selection-end-line="17" selection-end-column="13" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/src/cursor/cursor.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="408">
|
||||
<caret line="313" column="11" selection-start-line="313" selection-start-column="11" selection-end-line="313" selection-end-column="11" />
|
||||
<state relative-caret-position="459">
|
||||
<caret line="316" column="11" selection-start-line="316" selection-start-column="11" selection-end-line="316" selection-end-column="11" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/src/cursor/winapi_cursor.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="498">
|
||||
<caret line="66" column="25" selection-start-line="66" selection-start-column="25" selection-end-line="66" selection-end-column="25" />
|
||||
<state relative-caret-position="566">
|
||||
<caret line="60" column="25" selection-start-line="60" selection-start-column="25" selection-end-line="60" selection-end-column="25" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/src/kernel/unix_kernel/terminal.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="246">
|
||||
<caret line="79" column="13" lean-forward="true" selection-start-line="79" selection-start-column="13" selection-end-line="79" selection-end-column="13" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/src/kernel/mod.rs">
|
||||
<provider selected="true" editor-type-id="text-editor" />
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/src/kernel/windows_kernel/terminal.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="17">
|
||||
<caret line="1" column="7" selection-start-line="1" selection-start-column="7" selection-end-line="1" selection-end-column="7" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/src/kernel/windows_kernel/kernel.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="540">
|
||||
<caret line="203" column="5" selection-start-line="203" selection-start-column="5" selection-end-line="203" selection-end-column="5" />
|
||||
<state relative-caret-position="98">
|
||||
<caret line="204" column="18" selection-start-line="204" selection-start-column="18" selection-end-line="204" selection-end-column="18" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/src/kernel/windows_kernel/cursor.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="544">
|
||||
<caret line="32" column="23" selection-start-line="32" selection-start-column="23" selection-end-line="32" selection-end-column="23" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/src/kernel/windows_kernel/ansi_support.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="187">
|
||||
<caret line="11" column="31" selection-start-line="11" selection-start-column="31" selection-end-line="11" selection-end-column="31" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/examples/Crossterm 0.2.2 - New Version (Not finished)/cursor/mod.rs">
|
||||
<provider selected="true" editor-type-id="text-editor" />
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/src/shared/macros.rs">
|
||||
<provider selected="true" editor-type-id="text-editor" />
|
||||
</entry>
|
||||
<entry file="file://$PROJECT_DIR$/src/shared/raw.rs">
|
||||
<provider selected="true" editor-type-id="text-editor">
|
||||
<state relative-caret-position="357">
|
||||
<caret line="53" lean-forward="true" selection-start-line="53" selection-end-line="53" />
|
||||
</state>
|
||||
</provider>
|
||||
</entry>
|
||||
|
@ -13,13 +13,12 @@
|
||||
|
||||
extern crate crossterm;
|
||||
|
||||
mod terminal;
|
||||
mod cursor;
|
||||
mod color;
|
||||
mod cursor;
|
||||
mod program_examples;
|
||||
mod terminal;
|
||||
|
||||
fn main() {
|
||||
|
||||
use crossterm::Context;
|
||||
|
||||
{
|
||||
|
@ -4,13 +4,12 @@
|
||||
|
||||
extern crate crossterm;
|
||||
|
||||
use self::crossterm::style::{ Color };
|
||||
use self::crossterm::style::Color;
|
||||
use self::crossterm::terminal;
|
||||
use self::crossterm::Context;
|
||||
|
||||
/// print some red font | demonstration.
|
||||
pub fn paint_foreground()
|
||||
{
|
||||
pub fn paint_foreground() {
|
||||
let context = Context::new();
|
||||
let terminal = terminal::terminal(context.clone());
|
||||
|
||||
@ -27,8 +26,7 @@ pub fn paint_foreground()
|
||||
}
|
||||
|
||||
/// print some font on red background | demonstration.
|
||||
pub fn paint_background()
|
||||
{
|
||||
pub fn paint_background() {
|
||||
let context = Context::new();
|
||||
let terminal = terminal::terminal(context.clone());
|
||||
|
||||
@ -45,8 +43,7 @@ pub fn paint_background()
|
||||
}
|
||||
|
||||
/// print font with fore- background color | demonstration.
|
||||
pub fn paint_foreground_and_background()
|
||||
{
|
||||
pub fn paint_foreground_and_background() {
|
||||
let context = Context::new();
|
||||
let terminal = terminal::terminal(context.clone());
|
||||
|
||||
@ -67,35 +64,60 @@ pub fn paint_foreground_and_background()
|
||||
println!("{}", styledobject);
|
||||
|
||||
// Crossterm provides method chaining so that the above points can be inlined.
|
||||
println!("{}", terminal.paint("Red font on blue background color").with(Color::Red).on(Color::Blue));
|
||||
println!(
|
||||
"{}",
|
||||
terminal
|
||||
.paint("Red font on blue background color")
|
||||
.with(Color::Red)
|
||||
.on(Color::Blue)
|
||||
);
|
||||
}
|
||||
|
||||
/// Print all available foreground colors | demonstration.
|
||||
pub fn print_all_foreground_colors()
|
||||
{
|
||||
pub fn print_all_foreground_colors() {
|
||||
let context = Context::new();
|
||||
let terminal = terminal::terminal(context.clone());
|
||||
|
||||
println!("Black : \t {}", terminal.paint("■").with(Color::Black));
|
||||
println!("Red : \t\t {}", terminal.paint("■").with(Color::Red));
|
||||
println!("Dark Red: \t {}", terminal.paint("■").with(Color::DarkRed));
|
||||
println!(
|
||||
"Dark Red: \t {}",
|
||||
terminal.paint("■").with(Color::DarkRed)
|
||||
);
|
||||
println!("Green : \t {}", terminal.paint("■").with(Color::Green));
|
||||
println!("Dark Green : \t {}", terminal.paint("■").with(Color::DarkGreen));
|
||||
println!(
|
||||
"Dark Green : \t {}",
|
||||
terminal.paint("■").with(Color::DarkGreen)
|
||||
);
|
||||
println!("Yellow : \t {}", terminal.paint("■").with(Color::Yellow));
|
||||
println!("Dark Yellow : \t {}", terminal.paint("■").with(Color::DarkYellow));
|
||||
println!(
|
||||
"Dark Yellow : \t {}",
|
||||
terminal.paint("■").with(Color::DarkYellow)
|
||||
);
|
||||
println!("Blue : \t\t {}", terminal.paint("■").with(Color::Blue));
|
||||
println!("Dark Blue : \t {}", terminal.paint("■").with(Color::DarkBlue));
|
||||
println!("Magenta : \t {}", terminal.paint("■").with(Color::Magenta));
|
||||
println!("Dark Magenta : \t {}", terminal.paint("■").with(Color::DarkMagenta));
|
||||
println!(
|
||||
"Dark Blue : \t {}",
|
||||
terminal.paint("■").with(Color::DarkBlue)
|
||||
);
|
||||
println!(
|
||||
"Magenta : \t {}",
|
||||
terminal.paint("■").with(Color::Magenta)
|
||||
);
|
||||
println!(
|
||||
"Dark Magenta : \t {}",
|
||||
terminal.paint("■").with(Color::DarkMagenta)
|
||||
);
|
||||
println!("Cyan : \t\t {}", terminal.paint("■").with(Color::Cyan));
|
||||
println!("Dark Cyan : \t {}", terminal.paint("■").with(Color::DarkCyan));
|
||||
println!(
|
||||
"Dark Cyan : \t {}",
|
||||
terminal.paint("■").with(Color::DarkCyan)
|
||||
);
|
||||
println!("Grey : \t\t {}", terminal.paint("■").with(Color::Grey));
|
||||
println!("White : \t {}", terminal.paint("■").with(Color::White));
|
||||
}
|
||||
|
||||
/// Print all available foreground colors | demonstration.
|
||||
pub fn print_all_background_colors()
|
||||
{
|
||||
pub fn print_all_background_colors() {
|
||||
let context = Context::new();
|
||||
let terminal = terminal::terminal(context.clone());
|
||||
|
||||
@ -103,27 +125,51 @@ pub fn print_all_background_colors()
|
||||
println!("Red : \t\t {}", terminal.paint(" ").on(Color::Red));
|
||||
println!("Dark Red: \t {}", terminal.paint(" ").on(Color::DarkRed));
|
||||
println!("Green : \t {}", terminal.paint(" ").on(Color::Green));
|
||||
println!("Dark Green : \t {}", terminal.paint(" ").on(Color::DarkGreen));
|
||||
println!(
|
||||
"Dark Green : \t {}",
|
||||
terminal.paint(" ").on(Color::DarkGreen)
|
||||
);
|
||||
println!("Yellow : \t {}", terminal.paint(" ").on(Color::Yellow));
|
||||
println!("Dark Yellow : \t {}", terminal.paint(" ").on(Color::DarkYellow));
|
||||
println!(
|
||||
"Dark Yellow : \t {}",
|
||||
terminal.paint(" ").on(Color::DarkYellow)
|
||||
);
|
||||
println!("Blue : \t\t {}", terminal.paint(" ").on(Color::Blue));
|
||||
println!("Dark Blue : \t {}", terminal.paint(" ").on(Color::DarkBlue));
|
||||
println!(
|
||||
"Dark Blue : \t {}",
|
||||
terminal.paint(" ").on(Color::DarkBlue)
|
||||
);
|
||||
println!("Magenta : \t {}", terminal.paint(" ").on(Color::Magenta));
|
||||
println!("Dark Magenta : \t {}", terminal.paint(" ").on(Color::DarkMagenta));
|
||||
println!(
|
||||
"Dark Magenta : \t {}",
|
||||
terminal.paint(" ").on(Color::DarkMagenta)
|
||||
);
|
||||
println!("Cyan : \t\t {}", terminal.paint(" ").on(Color::Cyan));
|
||||
println!("Dark Cyan : \t {}", terminal.paint(" ").on(Color::DarkCyan));
|
||||
println!(
|
||||
"Dark Cyan : \t {}",
|
||||
terminal.paint(" ").on(Color::DarkCyan)
|
||||
);
|
||||
println!("Grey : \t\t {}", terminal.paint(" ").on(Color::Grey));
|
||||
println!("White : \t {}", terminal.paint(" ").on(Color::White));
|
||||
#[cfg(unix)]
|
||||
println!("RGB (10,10,10): \t {}", terminal.paint(" ").on(Color::Rgb {r: 10, g: 10, b: 10}));
|
||||
println!(
|
||||
"RGB (10,10,10): \t {}",
|
||||
terminal.paint(" ").on(Color::Rgb {
|
||||
r: 10,
|
||||
g: 10,
|
||||
b: 10
|
||||
})
|
||||
);
|
||||
#[cfg(unix)]
|
||||
println!("RGB (10,10,10): \t {}", terminal.paint(" ").on(Color::AnsiValue(50)));
|
||||
println!(
|
||||
"RGB (10,10,10): \t {}",
|
||||
terminal.paint(" ").on(Color::AnsiValue(50))
|
||||
);
|
||||
}
|
||||
|
||||
/// Print font with all available attributes. Note that this can only be used at unix systems and that some are not supported widely | demonstration..
|
||||
#[cfg(unix)]
|
||||
pub fn print_font_with_attributes()
|
||||
{
|
||||
pub fn print_font_with_attributes() {
|
||||
let context = Context::new();
|
||||
let terminal = terminal::terminal(context.clone());
|
||||
|
||||
@ -141,15 +187,20 @@ pub fn print_font_with_attributes()
|
||||
|
||||
/// Print all supported rgb colors | demonstration.
|
||||
#[cfg(unix)]
|
||||
pub fn print_supported_colors()
|
||||
{
|
||||
pub fn print_supported_colors() {
|
||||
let context = Context::new();
|
||||
let terminal = terminal::terminal(context.clone());
|
||||
|
||||
let count = crossterm::style::color(context.clone()).get_available_color_count().unwrap();
|
||||
let count = crossterm::style::color(context.clone())
|
||||
.get_available_color_count()
|
||||
.unwrap();
|
||||
|
||||
for i in 0..count
|
||||
{
|
||||
println!("{}", terminal.paint(format!("Color: {}",i)).with(Color::AnsiValue(i as u8)));
|
||||
for i in 0..count {
|
||||
println!(
|
||||
"{}",
|
||||
terminal
|
||||
.paint(format!("Color: {}", i))
|
||||
.with(Color::AnsiValue(i as u8))
|
||||
);
|
||||
}
|
||||
}
|
@ -7,30 +7,27 @@ use self::crossterm::cursor::{cursor, TerminalCursor};
|
||||
use self::crossterm::Context;
|
||||
|
||||
/// Set the cursor to position X: 10, Y: 5 in the terminal.
|
||||
pub fn goto()
|
||||
{
|
||||
pub fn goto() {
|
||||
let context = Context::new();
|
||||
|
||||
// Get the cursor
|
||||
let mut cursor = cursor(context.clone());
|
||||
// Set the cursor to position X: 10, Y: 5 in the terminal
|
||||
cursor.goto(10,5);
|
||||
cursor.goto(10, 5);
|
||||
}
|
||||
|
||||
/// get the cursor position
|
||||
pub fn pos()
|
||||
{
|
||||
pub fn pos() {
|
||||
let context = Context::new();
|
||||
|
||||
// Get the cursor
|
||||
let mut cursor = cursor(context.clone());
|
||||
// get the cursor position.
|
||||
let (x,y) = cursor.pos();
|
||||
let (x, y) = cursor.pos();
|
||||
}
|
||||
|
||||
/// Move the cursor 3 up | demonstration.
|
||||
pub fn move_up()
|
||||
{
|
||||
pub fn move_up() {
|
||||
let context = Context::new();
|
||||
|
||||
// Get the cursor
|
||||
@ -40,8 +37,7 @@ pub fn move_up()
|
||||
}
|
||||
|
||||
/// Move the cursor 3 to the right | demonstration.
|
||||
pub fn move_right()
|
||||
{
|
||||
pub fn move_right() {
|
||||
let context = Context::new();
|
||||
|
||||
// Get the cursor
|
||||
@ -51,8 +47,7 @@ pub fn move_right()
|
||||
}
|
||||
|
||||
/// Move the cursor 3 down | demonstration.
|
||||
pub fn move_down()
|
||||
{
|
||||
pub fn move_down() {
|
||||
let context = Context::new();
|
||||
|
||||
// Get the cursor
|
||||
@ -62,8 +57,7 @@ pub fn move_down()
|
||||
}
|
||||
|
||||
/// Move the cursor 3 to the left | demonstration.
|
||||
pub fn move_left()
|
||||
{
|
||||
pub fn move_left() {
|
||||
let context = Context::new();
|
||||
|
||||
// Get the cursor
|
||||
@ -73,8 +67,7 @@ pub fn move_left()
|
||||
}
|
||||
|
||||
/// Print character at X: 10 Y: 5 | demonstration.
|
||||
pub fn print()
|
||||
{
|
||||
pub fn print() {
|
||||
let context = Context::new();
|
||||
|
||||
// To print an some displayable content on an certain position.
|
||||
@ -82,7 +75,7 @@ pub fn print()
|
||||
// Get the cursor
|
||||
let mut cursor = cursor(context.clone());
|
||||
// Set the cursor to position X: 10, Y: 5 in the terminal
|
||||
cursor.goto(10,5);
|
||||
cursor.goto(10, 5);
|
||||
// Print the @ symbol at position X: 10, Y: 5 in the terminal
|
||||
print!("@");
|
||||
// Rust is line buffered inorder to print at an certain position we need to clear the buffer first.
|
||||
@ -96,22 +89,21 @@ pub fn print()
|
||||
Crossterm provides method chaining so that the above points can be inlined.
|
||||
*/
|
||||
|
||||
cursor.goto(10,5).print("@");
|
||||
cursor.goto(10, 5).print("@");
|
||||
}
|
||||
|
||||
/// Save and reset cursor position | demonstration..
|
||||
pub fn safe_and_reset_position()
|
||||
{
|
||||
pub fn safe_and_reset_position() {
|
||||
let context = Context::new();
|
||||
|
||||
let mut cursor = cursor(context.clone());
|
||||
|
||||
// Goto X: 5 Y: 5
|
||||
cursor.goto(5,5);
|
||||
cursor.goto(5, 5);
|
||||
// Safe cursor position: X: 5 Y: 5
|
||||
cursor.save_position();
|
||||
// Goto X: 5 Y: 20
|
||||
cursor.goto(5,20);
|
||||
cursor.goto(5, 20);
|
||||
// Print at X: 5 Y: 20.
|
||||
println!("Yea!");
|
||||
// Reset back to X: 5 Y: 5.
|
||||
@ -123,8 +115,7 @@ pub fn safe_and_reset_position()
|
||||
}
|
||||
|
||||
/// Hide cursor display | demonstration.
|
||||
pub fn hide_cursor()
|
||||
{
|
||||
pub fn hide_cursor() {
|
||||
let context = Context::new();
|
||||
|
||||
let cursor = cursor(context.clone());
|
||||
@ -132,8 +123,7 @@ pub fn hide_cursor()
|
||||
}
|
||||
|
||||
/// Show cursor display | demonstration.
|
||||
pub fn show_cursor()
|
||||
{
|
||||
pub fn show_cursor() {
|
||||
let context = Context::new();
|
||||
|
||||
let cursor = cursor(context.clone());
|
||||
@ -141,32 +131,10 @@ pub fn show_cursor()
|
||||
}
|
||||
|
||||
/// Show cursor display, only works on certain terminals.| demonstration
|
||||
pub fn blink_cursor()
|
||||
{
|
||||
pub fn blink_cursor() {
|
||||
let context = Context::new();
|
||||
|
||||
let cursor = cursor(context.clone());
|
||||
cursor.blink(false);
|
||||
cursor.blink(false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,42 +1,42 @@
|
||||
extern crate crossterm;
|
||||
|
||||
use crossterm::Context;
|
||||
use crossterm::screen::AlternateScreen;
|
||||
use crossterm::cursor::cursor;
|
||||
use crossterm::screen::AlternateScreen;
|
||||
use crossterm::terminal::{self, ClearType};
|
||||
use crossterm::Context;
|
||||
|
||||
use std::io::{Write, stdout};
|
||||
use std::{time, thread};
|
||||
use std::io::{stdout, Write};
|
||||
use std::rc::Rc;
|
||||
use std::{thread, time};
|
||||
|
||||
fn print_wait_screen(context: Rc<Context>)
|
||||
{
|
||||
fn print_wait_screen(context: Rc<Context>) {
|
||||
let mut terminal = terminal::terminal(context.clone());
|
||||
terminal.clear(ClearType::All);
|
||||
|
||||
let mut cursor = cursor(context.clone());
|
||||
cursor.goto(0,0);
|
||||
cursor.goto(0, 0);
|
||||
cursor.hide();
|
||||
|
||||
terminal.write("Welcome to the wait screen.\n\
|
||||
terminal.write(
|
||||
"Welcome to the wait screen.\n\
|
||||
Please wait a few seconds until we arrive back at the main screen.\n\
|
||||
Progress: ");
|
||||
Progress: ",
|
||||
);
|
||||
|
||||
// print some progress example.
|
||||
for i in 1..5
|
||||
{
|
||||
for i in 1..5 {
|
||||
// print the current counter at the line of `Seconds to Go: {counter}`
|
||||
cursor.goto(10,2).print(format!("{} of the 5 items processed", i));
|
||||
cursor
|
||||
.goto(10, 2)
|
||||
.print(format!("{} of the 5 items processed", i));
|
||||
|
||||
// 1 second delay
|
||||
thread::sleep(time::Duration::from_secs(1));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// print wait screen on alternate screen, then swich back.
|
||||
pub fn print_wait_screen_on_alternate_window(context: Rc<Context>)
|
||||
{
|
||||
pub fn print_wait_screen_on_alternate_window(context: Rc<Context>) {
|
||||
// create scope. If this scope ends the screen will be switched back to mainscreen.
|
||||
// because `AlternateScreen` switches back to main screen when switching back.
|
||||
{
|
||||
@ -49,15 +49,14 @@ pub fn print_wait_screen_on_alternate_window(context: Rc<Context>)
|
||||
}
|
||||
|
||||
/// some stress test switch from and to alternate screen.
|
||||
pub fn switch_between_main_and_alternate_screen()
|
||||
{
|
||||
pub fn switch_between_main_and_alternate_screen() {
|
||||
let context = Context::new();
|
||||
let mut cursor = cursor(context.clone());
|
||||
|
||||
{
|
||||
// create new alternate screen instance and switch to the alternate screen.
|
||||
let mut screen = AlternateScreen::from(context.clone());
|
||||
cursor.goto(0,0);
|
||||
cursor.goto(0, 0);
|
||||
write!(screen, "we are at the alternate screen!");
|
||||
screen.flush();
|
||||
thread::sleep(time::Duration::from_secs(3));
|
||||
|
@ -1,39 +1,40 @@
|
||||
extern crate crossterm;
|
||||
|
||||
use crossterm::Context;
|
||||
use crossterm::screen::AlternateScreen;
|
||||
use crossterm::cursor::cursor;
|
||||
use crossterm::screen::AlternateScreen;
|
||||
use crossterm::terminal::{self, ClearType};
|
||||
use crossterm::Context;
|
||||
|
||||
use std::io::{Write, stdout};
|
||||
use std::{time, thread};
|
||||
use std::io::{stdout, Write};
|
||||
use std::rc::Rc;
|
||||
use std::{thread, time};
|
||||
|
||||
use crossterm::raw::IntoRawMode;
|
||||
|
||||
// raw screen is not working correctly currently
|
||||
fn print_wait_screen(context: Rc<Context>)
|
||||
{
|
||||
fn print_wait_screen(context: Rc<Context>) {
|
||||
terminal::terminal(context.clone()).clear(ClearType::All);
|
||||
|
||||
let mut cursor = cursor(context.clone());
|
||||
cursor.goto(0,0).print("Welcome to the wait screen.");
|
||||
cursor.goto(0,1).print("Please wait a few seconds until we arrive back at the main screen.");
|
||||
cursor.goto(0,2).print("Progress: ");
|
||||
cursor.goto(0, 0).print("Welcome to the wait screen.");
|
||||
cursor
|
||||
.goto(0, 1)
|
||||
.print("Please wait a few seconds until we arrive back at the main screen.");
|
||||
cursor.goto(0, 2).print("Progress: ");
|
||||
|
||||
// print some progress example.
|
||||
for i in 1..5
|
||||
{
|
||||
for i in 1..5 {
|
||||
// print the current counter at the line of `Seconds to Go: {counter}`
|
||||
cursor.goto(10,2).print(format!("{} of the 5 items processed", i));
|
||||
cursor
|
||||
.goto(10, 2)
|
||||
.print(format!("{} of the 5 items processed", i));
|
||||
|
||||
// 1 second delay
|
||||
thread::sleep(time::Duration::from_secs(1));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn print_wait_screen_on_alternate_window()
|
||||
{
|
||||
pub fn print_wait_screen_on_alternate_window() {
|
||||
let context = Context::new();
|
||||
|
||||
// create scope. If this scope ends the screen will be switched back to mainscreen.
|
||||
|
@ -4,20 +4,18 @@
|
||||
|
||||
extern crate crossterm;
|
||||
|
||||
use crossterm::Context;
|
||||
use crossterm::terminal::{ ClearType, terminal };
|
||||
use crossterm::cursor;
|
||||
use crossterm::terminal::{terminal, ClearType};
|
||||
use crossterm::Context;
|
||||
|
||||
fn print_test_data()
|
||||
{
|
||||
fn print_test_data() {
|
||||
for i in 0..100 {
|
||||
println!("Test data to test terminal: {}",i);
|
||||
println!("Test data to test terminal: {}", i);
|
||||
}
|
||||
}
|
||||
|
||||
/// Clear all lines in terminal | demonstration
|
||||
pub fn clear_all_lines()
|
||||
{
|
||||
pub fn clear_all_lines() {
|
||||
let context = Context::new();
|
||||
|
||||
// Get terminal
|
||||
@ -30,8 +28,7 @@ pub fn clear_all_lines()
|
||||
}
|
||||
|
||||
/// Clear all lines from cursor position X:4, Y:4 down | demonstration
|
||||
pub fn clear_from_cursor_down()
|
||||
{
|
||||
pub fn clear_from_cursor_down() {
|
||||
let context = Context::new();
|
||||
|
||||
// Get terminal
|
||||
@ -40,15 +37,14 @@ pub fn clear_from_cursor_down()
|
||||
print_test_data();
|
||||
|
||||
// Set terminal cursor position (see example for more info).
|
||||
cursor::cursor(context.clone()).goto(4,8);
|
||||
cursor::cursor(context.clone()).goto(4, 8);
|
||||
|
||||
// Clear all cells from current cursor position down.
|
||||
terminal.clear(ClearType::FromCursorDown);
|
||||
}
|
||||
|
||||
/// Clear all lines from cursor position X:4, Y:4 up | demonstration
|
||||
pub fn clear_from_cursor_up()
|
||||
{
|
||||
pub fn clear_from_cursor_up() {
|
||||
let context = Context::new();
|
||||
|
||||
// Get terminal
|
||||
@ -57,15 +53,14 @@ pub fn clear_from_cursor_up()
|
||||
print_test_data();
|
||||
|
||||
// Set terminal cursor position (see example for more info).
|
||||
cursor::cursor(context.clone()).goto(4,4);
|
||||
cursor::cursor(context.clone()).goto(4, 4);
|
||||
|
||||
// Clear all cells from current cursor position down.
|
||||
terminal.clear(ClearType::FromCursorUp);
|
||||
}
|
||||
|
||||
/// Clear all lines from cursor position X:4, Y:4 up | demonstration
|
||||
pub fn clear_current_line()
|
||||
{
|
||||
pub fn clear_current_line() {
|
||||
let context = Context::new();
|
||||
|
||||
// Get terminal
|
||||
@ -74,15 +69,14 @@ pub fn clear_current_line()
|
||||
print_test_data();
|
||||
|
||||
// Set terminal cursor position (see example for more info).
|
||||
cursor::cursor(context.clone()).goto(4,4);
|
||||
cursor::cursor(context.clone()).goto(4, 4);
|
||||
|
||||
// Clear current line cells.
|
||||
terminal.clear(ClearType::CurrentLine);
|
||||
}
|
||||
|
||||
/// Clear all lines from cursor position X:4, Y:7 up | demonstration
|
||||
pub fn clear_until_new_line()
|
||||
{
|
||||
pub fn clear_until_new_line() {
|
||||
let context = Context::new();
|
||||
|
||||
// Get terminal
|
||||
@ -91,15 +85,14 @@ pub fn clear_until_new_line()
|
||||
print_test_data();
|
||||
|
||||
// Set terminal cursor position (see example for more info).
|
||||
cursor::cursor(context.clone()).goto(4,20);
|
||||
cursor::cursor(context.clone()).goto(4, 20);
|
||||
|
||||
// Clear all the cells until next line.
|
||||
terminal.clear(ClearType::UntilNewLine);
|
||||
}
|
||||
|
||||
/// Print the the current terminal size | demonstration.
|
||||
pub fn print_terminal_size()
|
||||
{
|
||||
pub fn print_terminal_size() {
|
||||
let context = Context::new();
|
||||
|
||||
// Get terminal
|
||||
@ -111,18 +104,16 @@ pub fn print_terminal_size()
|
||||
}
|
||||
|
||||
/// Set the terminal size to width 10, height: 10 | demonstration.
|
||||
pub fn set_terminal_size()
|
||||
{
|
||||
pub fn set_terminal_size() {
|
||||
let context = Context::new();
|
||||
|
||||
let mut terminal = terminal(context);
|
||||
|
||||
terminal.set_size(10,10);
|
||||
terminal.set_size(10, 10);
|
||||
}
|
||||
|
||||
/// Scroll down 10 lines | demonstration.
|
||||
pub fn scroll_down()
|
||||
{
|
||||
pub fn scroll_down() {
|
||||
let context = Context::new();
|
||||
|
||||
print_test_data();
|
||||
@ -133,8 +124,7 @@ pub fn scroll_down()
|
||||
}
|
||||
|
||||
/// Scroll down 10 lines | demonstration.
|
||||
pub fn scroll_up()
|
||||
{
|
||||
pub fn scroll_up() {
|
||||
let context = Context::new();
|
||||
|
||||
print_test_data();
|
||||
@ -146,19 +136,17 @@ pub fn scroll_up()
|
||||
}
|
||||
|
||||
/// Resize the terminal to X: 10, Y: 10 | demonstration.
|
||||
pub fn resize_terminal()
|
||||
{
|
||||
pub fn resize_terminal() {
|
||||
let context = Context::new();
|
||||
|
||||
// Get terminal
|
||||
let mut terminal = terminal(context.clone());
|
||||
// Get terminal size
|
||||
terminal.set_size(10,10);
|
||||
terminal.set_size(10, 10);
|
||||
}
|
||||
|
||||
/// exit the current proccess.
|
||||
pub fn exit()
|
||||
{
|
||||
pub fn exit() {
|
||||
let context = Context::new();
|
||||
|
||||
// Get terminal
|
||||
|
@ -2,14 +2,13 @@
|
||||
//! This module is used for windows 10 terminals and unix terminals by default.
|
||||
//! Note that the cursor position is 0 based. This means that we start counting at 0 when setting the cursor position ect.
|
||||
|
||||
use Context;
|
||||
use shared::functions;
|
||||
use super::*;
|
||||
use shared::functions;
|
||||
use Context;
|
||||
|
||||
/// This struct is an ansi implementation for cursor related actions.
|
||||
pub struct AnsiCursor
|
||||
{
|
||||
context: Rc<Context>
|
||||
pub struct AnsiCursor {
|
||||
context: Rc<Context>,
|
||||
}
|
||||
|
||||
impl AnsiCursor {
|
||||
@ -19,8 +18,7 @@ impl AnsiCursor {
|
||||
}
|
||||
|
||||
impl ITerminalCursor for AnsiCursor {
|
||||
fn goto(&self, x: u16, y: u16)
|
||||
{
|
||||
fn goto(&self, x: u16, y: u16) {
|
||||
let mut screen = self.context.screen_manager.lock().unwrap();
|
||||
{
|
||||
screen.write_ansi(format!(csi!("{};{}H"), y + 1, x + 1));
|
||||
@ -59,47 +57,40 @@ impl ITerminalCursor for AnsiCursor {
|
||||
}
|
||||
}
|
||||
|
||||
fn save_position(&mut self)
|
||||
{
|
||||
fn save_position(&mut self) {
|
||||
let mut screen = self.context.screen_manager.lock().unwrap();
|
||||
{
|
||||
screen.write_ansi_str(csi!("s"));
|
||||
}
|
||||
}
|
||||
|
||||
fn reset_position(&self)
|
||||
{
|
||||
fn reset_position(&self) {
|
||||
let mut screen = self.context.screen_manager.lock().unwrap();
|
||||
{
|
||||
screen.write_ansi_str(csi!("u"));
|
||||
}
|
||||
}
|
||||
|
||||
fn hide(&self)
|
||||
{
|
||||
fn hide(&self) {
|
||||
let mut screen = self.context.screen_manager.lock().unwrap();
|
||||
{
|
||||
screen.write_ansi_str(csi!("?25l"));
|
||||
}
|
||||
}
|
||||
|
||||
fn show(&self)
|
||||
{
|
||||
fn show(&self) {
|
||||
let mut screen = self.context.screen_manager.lock().unwrap();
|
||||
{
|
||||
screen.write_ansi_str(csi!("?25h"));
|
||||
}
|
||||
}
|
||||
|
||||
fn blink(&self, blink: bool)
|
||||
{
|
||||
fn blink(&self, blink: bool) {
|
||||
let mut screen = self.context.screen_manager.lock().unwrap();
|
||||
{
|
||||
if blink
|
||||
{
|
||||
if blink {
|
||||
screen.write_ansi_str(csi!("?12h"));
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
screen.write_ansi_str(csi!("?12l"));
|
||||
}
|
||||
}
|
||||
|
@ -3,10 +3,10 @@
|
||||
//!
|
||||
//! Note that positions of the cursor are 0 -based witch means that the coordinates (cells) starts counting from 0
|
||||
|
||||
use super::*;
|
||||
use Context;
|
||||
use super::super::shared::functions;
|
||||
use super::*;
|
||||
use std::io::Write;
|
||||
use Context;
|
||||
|
||||
use std::fmt::Display;
|
||||
use std::rc::Rc;
|
||||
@ -17,17 +17,22 @@ pub struct TerminalCursor {
|
||||
terminal_cursor: Option<Box<ITerminalCursor>>,
|
||||
}
|
||||
|
||||
impl TerminalCursor
|
||||
{
|
||||
impl TerminalCursor {
|
||||
/// Create new cursor instance whereon cursor related actions can be performed.
|
||||
pub fn new(context: Rc<Context>) -> TerminalCursor {
|
||||
#[cfg(target_os = "windows")]
|
||||
let cursor = functions::get_module::<Box<ITerminalCursor>>(WinApiCursor::new(context.screen_manager.clone()), AnsiCursor::new(context.clone()));
|
||||
let cursor = functions::get_module::<Box<ITerminalCursor>>(
|
||||
WinApiCursor::new(context.screen_manager.clone()),
|
||||
AnsiCursor::new(context.clone()),
|
||||
);
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
let cursor = Some(AnsiCursor::new(context.clone()) as Box<ITerminalCursor>);
|
||||
|
||||
TerminalCursor { terminal_cursor: cursor, context}
|
||||
TerminalCursor {
|
||||
terminal_cursor: cursor,
|
||||
context,
|
||||
}
|
||||
}
|
||||
|
||||
/// Goto some position (x,y) in the terminal.
|
||||
@ -267,8 +272,7 @@ impl TerminalCursor
|
||||
/// cursor::cursor(&context).safe_position();
|
||||
///
|
||||
/// ```
|
||||
pub fn save_position(&mut self)
|
||||
{
|
||||
pub fn save_position(&mut self) {
|
||||
if let Some(ref mut terminal_cursor) = self.terminal_cursor {
|
||||
terminal_cursor.save_position();
|
||||
}
|
||||
@ -290,8 +294,7 @@ impl TerminalCursor
|
||||
/// cursor(&context).reset_position();
|
||||
///
|
||||
/// ```
|
||||
pub fn reset_position(&mut self)
|
||||
{
|
||||
pub fn reset_position(&mut self) {
|
||||
if let Some(ref terminal_cursor) = self.terminal_cursor {
|
||||
terminal_cursor.reset_position();
|
||||
}
|
||||
@ -311,8 +314,7 @@ impl TerminalCursor
|
||||
/// cursor(&context).hide();
|
||||
///
|
||||
/// ```
|
||||
pub fn hide(&self)
|
||||
{
|
||||
pub fn hide(&self) {
|
||||
if let Some(ref terminal_cursor) = self.terminal_cursor {
|
||||
terminal_cursor.hide();
|
||||
}
|
||||
@ -332,8 +334,7 @@ impl TerminalCursor
|
||||
/// cursor(&context).show();
|
||||
///
|
||||
/// ```
|
||||
pub fn show(&self)
|
||||
{
|
||||
pub fn show(&self) {
|
||||
if let Some(ref terminal_cursor) = self.terminal_cursor {
|
||||
terminal_cursor.show();
|
||||
}
|
||||
@ -357,8 +358,7 @@ impl TerminalCursor
|
||||
/// cursor.blink(false);
|
||||
///
|
||||
/// ```
|
||||
pub fn blink(&self, blink: bool)
|
||||
{
|
||||
pub fn blink(&self, blink: bool) {
|
||||
if let Some(ref terminal_cursor) = self.terminal_cursor {
|
||||
terminal_cursor.blink(blink);
|
||||
}
|
||||
|
@ -10,15 +10,15 @@
|
||||
|
||||
pub mod cursor;
|
||||
|
||||
mod ansi_cursor;
|
||||
#[cfg(target_os = "windows")]
|
||||
mod winapi_cursor;
|
||||
mod ansi_cursor;
|
||||
|
||||
use self::ansi_cursor::AnsiCursor;
|
||||
#[cfg(target_os = "windows")]
|
||||
use self::winapi_cursor::WinApiCursor;
|
||||
use self::ansi_cursor::AnsiCursor;
|
||||
|
||||
pub use self::cursor::{ cursor, TerminalCursor };
|
||||
pub use self::cursor::{cursor, TerminalCursor};
|
||||
|
||||
use std::rc::Rc;
|
||||
|
||||
|
@ -1,18 +1,17 @@
|
||||
//! This is an WINAPI specific implementation for cursor related action.
|
||||
//! This module is used for windows terminals that do not support ANSI escape codes.
|
||||
//! Note that the cursor position is 0 based. This means that we start counting at 0 when setting the cursor position ect.
|
||||
use super::super::manager::{IScreenManager, ScreenManager, WinApiScreenManager};
|
||||
use super::ITerminalCursor;
|
||||
use super::super::manager::{IScreenManager, ScreenManager, WinApiScreenManager };
|
||||
|
||||
use kernel::windows_kernel::{kernel, cursor};
|
||||
use kernel::windows_kernel::{cursor, kernel};
|
||||
|
||||
use std::rc::Rc;
|
||||
use std::sync::Mutex;
|
||||
|
||||
/// This struct is an windows implementation for cursor related actions.
|
||||
pub struct WinApiCursor
|
||||
{
|
||||
screen_manager: Rc<Mutex<ScreenManager>>
|
||||
pub struct WinApiCursor {
|
||||
screen_manager: Rc<Mutex<ScreenManager>>,
|
||||
}
|
||||
|
||||
impl WinApiCursor {
|
||||
@ -21,10 +20,8 @@ impl WinApiCursor {
|
||||
}
|
||||
}
|
||||
|
||||
impl ITerminalCursor for WinApiCursor
|
||||
{
|
||||
impl ITerminalCursor for WinApiCursor {
|
||||
fn goto(&self, x: u16, y: u16) {
|
||||
|
||||
kernel::set_console_cursor_position(x as i16, y as i16, &self.screen_manager);
|
||||
}
|
||||
|
||||
@ -33,47 +30,40 @@ impl ITerminalCursor for WinApiCursor
|
||||
}
|
||||
|
||||
fn move_up(&self, count: u16) {
|
||||
let (xpos,ypos) = self.pos();
|
||||
let (xpos, ypos) = self.pos();
|
||||
self.goto(xpos, ypos - count);
|
||||
}
|
||||
|
||||
fn move_right(&self, count: u16) {
|
||||
let (xpos,ypos) = self.pos();
|
||||
let (xpos, ypos) = self.pos();
|
||||
self.goto(xpos + count, ypos);
|
||||
}
|
||||
|
||||
fn move_down(&self, count: u16) {
|
||||
let (xpos,ypos) = self.pos();
|
||||
let (xpos, ypos) = self.pos();
|
||||
self.goto(xpos, ypos + count);
|
||||
}
|
||||
|
||||
fn move_left(&self, count: u16) {
|
||||
let (xpos,ypos) = self.pos();
|
||||
let (xpos, ypos) = self.pos();
|
||||
self.goto(xpos - count, ypos);
|
||||
}
|
||||
|
||||
fn save_position(&mut self)
|
||||
{
|
||||
fn save_position(&mut self) {
|
||||
cursor::save_cursor_pos(&self.screen_manager);
|
||||
}
|
||||
|
||||
fn reset_position(&self)
|
||||
{
|
||||
fn reset_position(&self) {
|
||||
cursor::reset_to_saved_position(&self.screen_manager);
|
||||
}
|
||||
|
||||
fn hide(&self)
|
||||
{
|
||||
fn hide(&self) {
|
||||
kernel::cursor_visibility(false, &self.screen_manager);
|
||||
}
|
||||
|
||||
fn show(&self)
|
||||
{
|
||||
fn show(&self) {
|
||||
kernel::cursor_visibility(true, &self.screen_manager);
|
||||
}
|
||||
|
||||
fn blink(&self, blink: bool)
|
||||
{
|
||||
|
||||
}
|
||||
fn blink(&self, blink: bool) {}
|
||||
}
|
||||
|
@ -4,4 +4,3 @@
|
||||
pub mod unix_kernel;
|
||||
#[cfg(windows)]
|
||||
pub mod windows_kernel;
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
//! This module contains all the specific `unix` code.
|
||||
|
||||
pub mod terminal;
|
||||
|
||||
|
@ -1,14 +1,14 @@
|
||||
//! This module contains all `unix` specific terminal related logic.
|
||||
|
||||
use {libc, StateManager, Context, CommandManager};
|
||||
pub use self::libc::termios;
|
||||
use self::libc::{c_int, c_ushort, ioctl, STDOUT_FILENO, TIOCGWINSZ};
|
||||
use state::commands::{IStateCommand, NoncanonicalModeCommand};
|
||||
use termios::Termios;
|
||||
pub use self::libc::{termios};
|
||||
use self::libc::{STDOUT_FILENO, TIOCGWINSZ, c_ushort, ioctl, c_int};
|
||||
use state::commands::{ NoncanonicalModeCommand, IStateCommand} ;
|
||||
use {libc, CommandManager, Context, StateManager};
|
||||
|
||||
use std::io::Error;
|
||||
use std::{ io, mem };
|
||||
use std::rc::Rc;
|
||||
use std::{io, mem};
|
||||
|
||||
/// A representation of the size of the current terminal.
|
||||
#[repr(C)]
|
||||
@ -23,7 +23,7 @@ pub struct UnixSize {
|
||||
}
|
||||
|
||||
/// Get the current terminal size.
|
||||
pub fn terminal_size() -> (u16,u16) {
|
||||
pub fn terminal_size() -> (u16, u16) {
|
||||
// http://rosettacode.org/wiki/Terminal_control/Dimensions#Library:_BSD_libc
|
||||
let us = UnixSize {
|
||||
rows: 0,
|
||||
@ -34,16 +34,15 @@ pub fn terminal_size() -> (u16,u16) {
|
||||
let r = unsafe { ioctl(STDOUT_FILENO, TIOCGWINSZ, &us) };
|
||||
if r == 0 {
|
||||
// because crossterm works starts counting at 0 and unix terminal starts at cell 1 you have subtract one to get 0-based results.
|
||||
(us.cols -1, us.rows -1)
|
||||
(us.cols - 1, us.rows - 1)
|
||||
} else {
|
||||
(0,0)
|
||||
(0, 0)
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the current cursor position.
|
||||
pub fn pos(context: Rc<Context>) -> (u16, u16)
|
||||
{
|
||||
use std::io::{ Write,Read };
|
||||
pub fn pos(context: Rc<Context>) -> (u16, u16) {
|
||||
use std::io::{Read, Write};
|
||||
|
||||
let mut command_id = NoncanonicalModeCommand::new(&context.state_manager);
|
||||
|
||||
@ -95,7 +94,11 @@ pub fn pos(context: Rc<Context>) -> (u16, u16)
|
||||
let (cols, c) = read_num();
|
||||
|
||||
// Expect `R`
|
||||
let res = if c == 'R' { (cols as u16, rows as u16) } else { return (0, 0) };
|
||||
let res = if c == 'R' {
|
||||
(cols as u16, rows as u16)
|
||||
} else {
|
||||
return (0, 0);
|
||||
};
|
||||
|
||||
CommandManager::undo(context.clone(), command_id);
|
||||
|
||||
@ -103,8 +106,7 @@ pub fn pos(context: Rc<Context>) -> (u16, u16)
|
||||
}
|
||||
|
||||
/// Set the terminal mode to the given mode.
|
||||
pub fn set_terminal_mode(termios: &Termios) -> io::Result<()>
|
||||
{
|
||||
pub fn set_terminal_mode(termios: &Termios) -> io::Result<()> {
|
||||
extern "C" {
|
||||
pub fn tcsetattr(fd: c_int, opt: c_int, termptr: *const Termios) -> c_int;
|
||||
}
|
||||
@ -120,8 +122,7 @@ pub fn make_raw(termios: &mut Termios) {
|
||||
}
|
||||
|
||||
/// Get the current terminal mode.
|
||||
pub fn get_terminal_mode() -> io::Result<Termios>
|
||||
{
|
||||
pub fn get_terminal_mode() -> io::Result<Termios> {
|
||||
extern "C" {
|
||||
pub fn tcgetattr(fd: c_int, termptr: *mut Termios) -> c_int;
|
||||
}
|
||||
@ -132,16 +133,13 @@ pub fn get_terminal_mode() -> io::Result<Termios>
|
||||
}
|
||||
}
|
||||
|
||||
pub fn exit()
|
||||
{
|
||||
pub fn exit() {
|
||||
::std::process::exit(0);
|
||||
}
|
||||
|
||||
/// Is the return value true?
|
||||
fn is_true(value: i32) -> Result<(), Error>
|
||||
{
|
||||
match value
|
||||
{
|
||||
fn is_true(value: i32) -> Result<(), Error> {
|
||||
match value {
|
||||
-1 => Err(io::Error::last_os_error()),
|
||||
0 => Ok(()),
|
||||
_ => Err(io::Error::last_os_error()),
|
||||
|
@ -1,7 +1,7 @@
|
||||
//! This module handles the enabling `ANSI escape codes` for windows terminals.
|
||||
|
||||
use IStateCommand;
|
||||
use std::sync::{Once, ONCE_INIT};
|
||||
use IStateCommand;
|
||||
|
||||
static mut HAS_BEEN_TRYED_TO_ENABLE: bool = false;
|
||||
static mut IS_ANSI_ON_WINDOWS_ENABLED: Option<bool> = None;
|
||||
@ -9,8 +9,7 @@ static mut DOES_WINDOWS_SUPPORT_ANSI: Option<bool> = None;
|
||||
static START: Once = ONCE_INIT;
|
||||
|
||||
/// Try enable `ANSI escape codes` and return the result.
|
||||
pub fn try_enable_ansi_support() -> bool
|
||||
{
|
||||
pub fn try_enable_ansi_support() -> bool {
|
||||
START.call_once(|| {
|
||||
use state::commands::win_commands::EnableAnsiCommand;
|
||||
let mut command = EnableAnsiCommand::new();
|
||||
@ -25,49 +24,39 @@ pub fn try_enable_ansi_support() -> bool
|
||||
}
|
||||
|
||||
/// Get whether ansi has been enabled.
|
||||
pub fn ansi_enabled() -> bool
|
||||
{
|
||||
unsafe { IS_ANSI_ON_WINDOWS_ENABLED.unwrap_or_else(| | false) }
|
||||
pub fn ansi_enabled() -> bool {
|
||||
unsafe { IS_ANSI_ON_WINDOWS_ENABLED.unwrap_or_else(|| false) }
|
||||
}
|
||||
|
||||
/// Get whether windows supports ansi
|
||||
pub fn windows_supportable() -> bool
|
||||
{
|
||||
unsafe { DOES_WINDOWS_SUPPORT_ANSI.unwrap_or_else(| | false)}
|
||||
pub fn windows_supportable() -> bool {
|
||||
unsafe { DOES_WINDOWS_SUPPORT_ANSI.unwrap_or_else(|| false) }
|
||||
}
|
||||
|
||||
/// Get whether ansi has been tried to enable before.
|
||||
pub fn has_been_tried_to_enable_ansi() -> bool
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
pub fn has_been_tried_to_enable_ansi() -> bool {
|
||||
unsafe {
|
||||
return HAS_BEEN_TRYED_TO_ENABLE;
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the is ansi escape property enabled or disabled. So whe can determine if the ansi escape codes are enabled.
|
||||
pub fn set_ansi_enabled(is_enabled :bool)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
pub fn set_ansi_enabled(is_enabled: bool) {
|
||||
unsafe {
|
||||
IS_ANSI_ON_WINDOWS_ENABLED = Some(is_enabled);
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the is_windows_ansi_supportable property. So whe can determine whether windows supports ansi.
|
||||
fn set_is_windows_ansi_supportable(is_enabled :bool)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
fn set_is_windows_ansi_supportable(is_enabled: bool) {
|
||||
unsafe {
|
||||
DOES_WINDOWS_SUPPORT_ANSI = Some(is_enabled);
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the has_been_tried_to_enable property. So we can determine whether ansi has been tried to enable before.
|
||||
fn has_been_tried_to_enable(has_been_tried: bool)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
fn has_been_tried_to_enable(has_been_tried: bool) {
|
||||
unsafe {
|
||||
HAS_BEEN_TRYED_TO_ENABLE = has_been_tried;
|
||||
}
|
||||
}
|
@ -1,25 +1,27 @@
|
||||
//! This module handles some logic for cursor interaction in the windows console.
|
||||
|
||||
use super::kernel;
|
||||
use super::super::super::manager::{ScreenManager, WinApiScreenManager};
|
||||
use super::kernel;
|
||||
|
||||
use std::rc::Rc;
|
||||
use std::sync::Mutex;
|
||||
|
||||
/// This stores the cursor pos, at program level. So it can be recalled later.
|
||||
static mut SAVED_CURSOR_POS:(u16,u16) = (0,0);
|
||||
static mut SAVED_CURSOR_POS: (u16, u16) = (0, 0);
|
||||
|
||||
/// Reset to saved cursor position
|
||||
pub fn reset_to_saved_position(screen_manager: &Rc<Mutex<ScreenManager>>)
|
||||
{
|
||||
pub fn reset_to_saved_position(screen_manager: &Rc<Mutex<ScreenManager>>) {
|
||||
unsafe {
|
||||
kernel::set_console_cursor_position(SAVED_CURSOR_POS.0 as i16, SAVED_CURSOR_POS.1 as i16, screen_manager);
|
||||
kernel::set_console_cursor_position(
|
||||
SAVED_CURSOR_POS.0 as i16,
|
||||
SAVED_CURSOR_POS.1 as i16,
|
||||
screen_manager,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Save current cursor position to recall later.
|
||||
pub fn save_cursor_pos(screen_manager: &Rc<Mutex<ScreenManager>>)
|
||||
{
|
||||
pub fn save_cursor_pos(screen_manager: &Rc<Mutex<ScreenManager>>) {
|
||||
let position = pos(screen_manager);
|
||||
|
||||
unsafe {
|
||||
@ -28,8 +30,10 @@ pub fn save_cursor_pos(screen_manager: &Rc<Mutex<ScreenManager>>)
|
||||
}
|
||||
|
||||
/// get the current cursor position.
|
||||
pub fn pos(screen_manager: &Rc<Mutex<ScreenManager>>) -> (u16,u16)
|
||||
{
|
||||
pub fn pos(screen_manager: &Rc<Mutex<ScreenManager>>) -> (u16, u16) {
|
||||
let csbi = kernel::get_console_screen_buffer_info(screen_manager);
|
||||
( csbi.dwCursorPosition.X as u16, csbi.dwCursorPosition.Y as u16 )
|
||||
(
|
||||
csbi.dwCursorPosition.X as u16,
|
||||
csbi.dwCursorPosition.Y as u16,
|
||||
)
|
||||
}
|
@ -1,29 +1,27 @@
|
||||
//! This module is the core of all the `WINAPI` actions. All unsafe `WINAPI` function call are done here.
|
||||
use Context;
|
||||
use std::rc::Rc;
|
||||
use Context;
|
||||
|
||||
use winapi::um::winnt::HANDLE;
|
||||
use winapi::um::winbase::{STD_OUTPUT_HANDLE, STD_INPUT_HANDLE };
|
||||
use winapi::um::handleapi::INVALID_HANDLE_VALUE;
|
||||
use winapi::um::processenv::{GetStdHandle};
|
||||
use winapi::um::consoleapi::{SetConsoleMode,GetConsoleMode, };
|
||||
use winapi::shared::ntdef::{NULL};
|
||||
use winapi::shared::minwindef::{TRUE, FALSE};
|
||||
use winapi::um::wincon;
|
||||
use winapi::shared::minwindef::{FALSE, TRUE};
|
||||
use winapi::shared::ntdef::NULL;
|
||||
use winapi::um::consoleapi::WriteConsoleW;
|
||||
use winapi::um::wincon::
|
||||
{
|
||||
ENABLE_PROCESSED_INPUT,
|
||||
WriteConsoleOutputW,
|
||||
WriteConsoleOutputCharacterA,
|
||||
WriteConsoleOutputCharacterW,
|
||||
SetConsoleWindowInfo, SetConsoleCursorPosition, SetConsoleTextAttribute, SetConsoleScreenBufferSize, CreateConsoleScreenBuffer,SetConsoleActiveScreenBuffer, SetConsoleCursorInfo,
|
||||
GetLargestConsoleWindowSize, GetConsoleScreenBufferInfo,
|
||||
FillConsoleOutputCharacterA, FillConsoleOutputAttribute,WriteConsoleOutputAttribute,
|
||||
CONSOLE_SCREEN_BUFFER_INFO, SMALL_RECT, COORD, CHAR_INFO, PSMALL_RECT, CONSOLE_CURSOR_INFO
|
||||
use winapi::um::consoleapi::{GetConsoleMode, SetConsoleMode};
|
||||
use winapi::um::handleapi::INVALID_HANDLE_VALUE;
|
||||
use winapi::um::processenv::GetStdHandle;
|
||||
use winapi::um::winbase::{STD_INPUT_HANDLE, STD_OUTPUT_HANDLE};
|
||||
use winapi::um::wincon;
|
||||
use winapi::um::wincon::{
|
||||
CreateConsoleScreenBuffer, FillConsoleOutputAttribute, FillConsoleOutputCharacterA,
|
||||
GetConsoleScreenBufferInfo, GetLargestConsoleWindowSize, SetConsoleActiveScreenBuffer,
|
||||
SetConsoleCursorInfo, SetConsoleCursorPosition, SetConsoleScreenBufferSize,
|
||||
SetConsoleTextAttribute, SetConsoleWindowInfo, WriteConsoleOutputAttribute,
|
||||
WriteConsoleOutputCharacterA, WriteConsoleOutputCharacterW, WriteConsoleOutputW, CHAR_INFO,
|
||||
CONSOLE_CURSOR_INFO, CONSOLE_SCREEN_BUFFER_INFO, COORD, ENABLE_PROCESSED_INPUT, PSMALL_RECT,
|
||||
SMALL_RECT,
|
||||
};
|
||||
use winapi::um::winnt::HANDLE;
|
||||
|
||||
use super::{Empty};
|
||||
use super::Empty;
|
||||
static mut CONSOLE_OUTPUT_HANDLE: Option<HANDLE> = None;
|
||||
static mut CONSOLE_INPUT_HANDLE: Option<HANDLE> = None;
|
||||
|
||||
@ -31,8 +29,7 @@ use super::super::super::manager::{ScreenManager, WinApiScreenManager};
|
||||
use std::sync::Mutex;
|
||||
|
||||
/// Get the global stored handle.
|
||||
pub fn get_current_handle(screen_manager: &mut WinApiScreenManager) -> &HANDLE
|
||||
{
|
||||
pub fn get_current_handle(screen_manager: &mut WinApiScreenManager) -> &HANDLE {
|
||||
return screen_manager.get_handle();
|
||||
}
|
||||
|
||||
@ -44,8 +41,7 @@ pub fn get_output_handle() -> HANDLE {
|
||||
} else {
|
||||
let handle = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
|
||||
if !is_valid_handle(&handle)
|
||||
{
|
||||
if !is_valid_handle(&handle) {
|
||||
panic!("Cannot get output handle")
|
||||
}
|
||||
|
||||
@ -63,8 +59,7 @@ pub fn get_input_handle() -> HANDLE {
|
||||
} else {
|
||||
let handle = GetStdHandle(STD_INPUT_HANDLE);
|
||||
|
||||
if !is_valid_handle(&handle)
|
||||
{
|
||||
if !is_valid_handle(&handle) {
|
||||
panic!("Cannot get input handle")
|
||||
}
|
||||
|
||||
@ -83,12 +78,16 @@ fn is_valid_handle(handle: &HANDLE) -> bool {
|
||||
}
|
||||
}
|
||||
/// Create a new console screen buffer info struct.
|
||||
pub fn get_console_screen_buffer_info(screen_manager: &Rc<Mutex<ScreenManager>>) -> CONSOLE_SCREEN_BUFFER_INFO {
|
||||
|
||||
pub fn get_console_screen_buffer_info(
|
||||
screen_manager: &Rc<Mutex<ScreenManager>>,
|
||||
) -> CONSOLE_SCREEN_BUFFER_INFO {
|
||||
let mut screen_manager = screen_manager.lock().unwrap();
|
||||
let winapi_screen_manager: &mut WinApiScreenManager = match screen_manager.as_any().downcast_mut::<WinApiScreenManager>() {
|
||||
Some(win_api) => { win_api },
|
||||
None => panic!("")
|
||||
let winapi_screen_manager: &mut WinApiScreenManager = match screen_manager
|
||||
.as_any()
|
||||
.downcast_mut::<WinApiScreenManager>()
|
||||
{
|
||||
Some(win_api) => win_api,
|
||||
None => panic!(""),
|
||||
};
|
||||
|
||||
let output_handle = get_current_handle(winapi_screen_manager);
|
||||
@ -106,7 +105,6 @@ pub fn get_console_screen_buffer_info(screen_manager: &Rc<Mutex<ScreenManager>>)
|
||||
|
||||
/// Create a new console screen buffer info struct.
|
||||
pub fn get_console_screen_buffer_info_from_handle(handle: &HANDLE) -> CONSOLE_SCREEN_BUFFER_INFO {
|
||||
|
||||
let mut csbi = CONSOLE_SCREEN_BUFFER_INFO::empty();
|
||||
let success;
|
||||
|
||||
@ -120,13 +118,10 @@ pub fn get_console_screen_buffer_info_from_handle(handle: &HANDLE) -> CONSOLE_SC
|
||||
}
|
||||
|
||||
/// Get the larged console window size posible.
|
||||
pub fn get_largest_console_window_size() -> COORD
|
||||
{
|
||||
pub fn get_largest_console_window_size() -> COORD {
|
||||
let output_handle = get_output_handle();
|
||||
|
||||
unsafe {
|
||||
GetLargestConsoleWindowSize(output_handle)
|
||||
}
|
||||
unsafe { GetLargestConsoleWindowSize(output_handle) }
|
||||
}
|
||||
|
||||
/// Get the original color of the terminal.
|
||||
@ -136,8 +131,7 @@ pub fn get_original_console_color(screen_manager: &Rc<Mutex<ScreenManager>>) ->
|
||||
}
|
||||
|
||||
/// Set the console mode to the given console mode.
|
||||
pub fn set_console_mode(handle: &HANDLE, console_mode: u32) -> bool
|
||||
{
|
||||
pub fn set_console_mode(handle: &HANDLE, console_mode: u32) -> bool {
|
||||
unsafe {
|
||||
let success = SetConsoleMode(*handle, console_mode);
|
||||
return is_true(success);
|
||||
@ -145,8 +139,7 @@ pub fn set_console_mode(handle: &HANDLE, console_mode: u32) -> bool
|
||||
}
|
||||
|
||||
/// Get the console mode.
|
||||
pub fn get_console_mode(handle: &HANDLE, current_mode: &mut u32) -> bool
|
||||
{
|
||||
pub fn get_console_mode(handle: &HANDLE, current_mode: &mut u32) -> bool {
|
||||
unsafe {
|
||||
let success = GetConsoleMode(*handle, &mut *current_mode);
|
||||
return is_true(success);
|
||||
@ -154,8 +147,7 @@ pub fn get_console_mode(handle: &HANDLE, current_mode: &mut u32) -> bool
|
||||
}
|
||||
|
||||
/// Set the cursor position to the given x and y. Note that this is 0 based.
|
||||
pub fn set_console_cursor_position(x: i16, y: i16, screen_manager: &Rc<Mutex<ScreenManager>>)
|
||||
{
|
||||
pub fn set_console_cursor_position(x: i16, y: i16, screen_manager: &Rc<Mutex<ScreenManager>>) {
|
||||
if x < 0 || x >= <i16>::max_value() {
|
||||
panic!("X: {}, Argument Out of Range Exception", x);
|
||||
}
|
||||
@ -165,9 +157,12 @@ pub fn set_console_cursor_position(x: i16, y: i16, screen_manager: &Rc<Mutex<Scr
|
||||
}
|
||||
|
||||
let mut screen_manager = screen_manager.lock().unwrap();
|
||||
let winapi_screen_manager: &mut WinApiScreenManager = match screen_manager.as_any().downcast_mut::<WinApiScreenManager>() {
|
||||
Some(win_api) => { win_api },
|
||||
None => panic!("")
|
||||
let winapi_screen_manager: &mut WinApiScreenManager = match screen_manager
|
||||
.as_any()
|
||||
.downcast_mut::<WinApiScreenManager>()
|
||||
{
|
||||
Some(win_api) => win_api,
|
||||
None => panic!(""),
|
||||
};
|
||||
|
||||
let handle = get_current_handle(winapi_screen_manager);
|
||||
@ -184,31 +179,30 @@ pub fn set_console_cursor_position(x: i16, y: i16, screen_manager: &Rc<Mutex<Scr
|
||||
}
|
||||
|
||||
/// change the cursor visibility.
|
||||
pub fn cursor_visibility(visable: bool, screen_manager: &Rc<Mutex<ScreenManager>>)
|
||||
{
|
||||
pub fn cursor_visibility(visable: bool, screen_manager: &Rc<Mutex<ScreenManager>>) {
|
||||
let mut screen_manager = screen_manager.lock().unwrap();
|
||||
let winapi_screen_manager: &mut WinApiScreenManager = match screen_manager.as_any().downcast_mut::<WinApiScreenManager>() {
|
||||
Some(win_api) => { win_api },
|
||||
None => panic!("")
|
||||
let winapi_screen_manager: &mut WinApiScreenManager = match screen_manager
|
||||
.as_any()
|
||||
.downcast_mut::<WinApiScreenManager>()
|
||||
{
|
||||
Some(win_api) => win_api,
|
||||
None => panic!(""),
|
||||
};
|
||||
|
||||
let handle = get_current_handle(winapi_screen_manager);
|
||||
|
||||
let cursor_info = CONSOLE_CURSOR_INFO
|
||||
{
|
||||
let cursor_info = CONSOLE_CURSOR_INFO {
|
||||
dwSize: 100,
|
||||
bVisible: if visable { TRUE } else {FALSE}
|
||||
bVisible: if visable { TRUE } else { FALSE },
|
||||
};
|
||||
|
||||
unsafe
|
||||
{
|
||||
unsafe {
|
||||
SetConsoleCursorInfo(*handle, &cursor_info);
|
||||
}
|
||||
}
|
||||
|
||||
/// Change the console text attribute.
|
||||
pub fn set_console_text_attribute(value: u16, screen_manager: &Rc<Mutex<ScreenManager>>)
|
||||
{
|
||||
pub fn set_console_text_attribute(value: u16, screen_manager: &Rc<Mutex<ScreenManager>>) {
|
||||
let output_handle = get_output_handle();
|
||||
|
||||
unsafe {
|
||||
@ -217,56 +211,75 @@ pub fn set_console_text_attribute(value: u16, screen_manager: &Rc<Mutex<ScreenMa
|
||||
}
|
||||
|
||||
/// Change console info.
|
||||
pub fn set_console_info(absolute: bool, rect: &SMALL_RECT, screen_manager: &Rc<Mutex<ScreenManager>>) -> bool
|
||||
{
|
||||
pub fn set_console_info(
|
||||
absolute: bool,
|
||||
rect: &SMALL_RECT,
|
||||
screen_manager: &Rc<Mutex<ScreenManager>>,
|
||||
) -> bool {
|
||||
let mut screen_manager = screen_manager.lock().unwrap();
|
||||
let winapi_screen_manager: &mut WinApiScreenManager = match screen_manager.as_any().downcast_mut::<WinApiScreenManager>() {
|
||||
Some(win_api) => { win_api },
|
||||
None => panic!("")
|
||||
let winapi_screen_manager: &mut WinApiScreenManager = match screen_manager
|
||||
.as_any()
|
||||
.downcast_mut::<WinApiScreenManager>()
|
||||
{
|
||||
Some(win_api) => win_api,
|
||||
None => panic!(""),
|
||||
};
|
||||
|
||||
let handle = get_current_handle(winapi_screen_manager);
|
||||
|
||||
let absolute = match absolute { true => 1, false => 0, };
|
||||
unsafe
|
||||
{
|
||||
let success = SetConsoleWindowInfo(*handle,absolute ,rect);
|
||||
let absolute = match absolute {
|
||||
true => 1,
|
||||
false => 0,
|
||||
};
|
||||
unsafe {
|
||||
let success = SetConsoleWindowInfo(*handle, absolute, rect);
|
||||
is_true(success)
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the console screen buffer size
|
||||
pub fn set_console_screen_buffer_size( size: COORD, screen_manager: &Rc<Mutex<ScreenManager>>) -> bool
|
||||
{
|
||||
pub fn set_console_screen_buffer_size(
|
||||
size: COORD,
|
||||
screen_manager: &Rc<Mutex<ScreenManager>>,
|
||||
) -> bool {
|
||||
let mut screen_manager = screen_manager.lock().unwrap();
|
||||
let winapi_screen_manager: &mut WinApiScreenManager = match screen_manager.as_any().downcast_mut::<WinApiScreenManager>() {
|
||||
Some(win_api) => { win_api },
|
||||
None => panic!("")
|
||||
let winapi_screen_manager: &mut WinApiScreenManager = match screen_manager
|
||||
.as_any()
|
||||
.downcast_mut::<WinApiScreenManager>()
|
||||
{
|
||||
Some(win_api) => win_api,
|
||||
None => panic!(""),
|
||||
};
|
||||
|
||||
let handle = get_current_handle(winapi_screen_manager);
|
||||
|
||||
unsafe
|
||||
{
|
||||
unsafe {
|
||||
let success = SetConsoleScreenBufferSize(*handle, size);
|
||||
is_true(success)
|
||||
}
|
||||
}
|
||||
|
||||
/// Fill a certain block with characters.
|
||||
pub fn fill_console_output_character(cells_written: &mut u32, start_location: COORD, cells_to_write: u32, screen_manager: &Rc<Mutex<ScreenManager>>) -> bool
|
||||
{
|
||||
pub fn fill_console_output_character(
|
||||
cells_written: &mut u32,
|
||||
start_location: COORD,
|
||||
cells_to_write: u32,
|
||||
screen_manager: &Rc<Mutex<ScreenManager>>,
|
||||
) -> bool {
|
||||
let mut screen_manager = screen_manager.lock().unwrap();
|
||||
let winapi_screen_manager: &mut WinApiScreenManager = match screen_manager.as_any().downcast_mut::<WinApiScreenManager>() {
|
||||
Some(win_api) => { win_api },
|
||||
None => panic!("")
|
||||
let winapi_screen_manager: &mut WinApiScreenManager = match screen_manager
|
||||
.as_any()
|
||||
.downcast_mut::<WinApiScreenManager>()
|
||||
{
|
||||
Some(win_api) => win_api,
|
||||
None => panic!(""),
|
||||
};
|
||||
|
||||
let handle = get_current_handle(winapi_screen_manager);
|
||||
|
||||
unsafe {
|
||||
// fill the cells in console with blanks
|
||||
let success = FillConsoleOutputCharacterA (
|
||||
let success = FillConsoleOutputCharacterA(
|
||||
*handle,
|
||||
' ' as i8,
|
||||
cells_to_write,
|
||||
@ -278,16 +291,22 @@ pub fn fill_console_output_character(cells_written: &mut u32, start_location: CO
|
||||
}
|
||||
|
||||
/// Set console ouput attribute for certain block.
|
||||
pub fn fill_console_output_attribute(cells_written: &mut u32, start_location: COORD, cells_to_write: u32,screen_manager: &Rc<Mutex<ScreenManager>>) -> bool
|
||||
{
|
||||
|
||||
pub fn fill_console_output_attribute(
|
||||
cells_written: &mut u32,
|
||||
start_location: COORD,
|
||||
cells_to_write: u32,
|
||||
screen_manager: &Rc<Mutex<ScreenManager>>,
|
||||
) -> bool {
|
||||
// Get the position of the current console window
|
||||
let csbi = get_console_screen_buffer_info(screen_manager);
|
||||
|
||||
let mut screen_manager = screen_manager.lock().unwrap();
|
||||
let winapi_screen_manager: &mut WinApiScreenManager = match screen_manager.as_any().downcast_mut::<WinApiScreenManager>() {
|
||||
Some(win_api) => { win_api },
|
||||
None => panic!("")
|
||||
let winapi_screen_manager: &mut WinApiScreenManager = match screen_manager
|
||||
.as_any()
|
||||
.downcast_mut::<WinApiScreenManager>()
|
||||
{
|
||||
Some(win_api) => win_api,
|
||||
None => panic!(""),
|
||||
};
|
||||
|
||||
let handle = get_current_handle(winapi_screen_manager);
|
||||
@ -295,7 +314,7 @@ pub fn fill_console_output_attribute(cells_written: &mut u32, start_location: CO
|
||||
let success;
|
||||
|
||||
unsafe {
|
||||
success = FillConsoleOutputAttribute (
|
||||
success = FillConsoleOutputAttribute(
|
||||
*handle,
|
||||
csbi.wAttributes,
|
||||
cells_to_write,
|
||||
@ -308,107 +327,108 @@ pub fn fill_console_output_attribute(cells_written: &mut u32, start_location: CO
|
||||
}
|
||||
|
||||
/// Create new console screen buffer. This can be used for alternate screen.
|
||||
pub fn create_console_screen_buffer() -> HANDLE
|
||||
{
|
||||
use winapi::shared::ntdef::NULL;
|
||||
use winapi::um::wincon::CONSOLE_TEXTMODE_BUFFER;
|
||||
use winapi::um::winnt::{GENERIC_READ, GENERIC_WRITE, FILE_SHARE_READ, FILE_SHARE_WRITE};
|
||||
use winapi::um::minwinbase::SECURITY_ATTRIBUTES;
|
||||
pub fn create_console_screen_buffer() -> HANDLE {
|
||||
use std::mem::size_of;
|
||||
use winapi::shared::ntdef::NULL;
|
||||
use winapi::um::minwinbase::SECURITY_ATTRIBUTES;
|
||||
use winapi::um::wincon::CONSOLE_TEXTMODE_BUFFER;
|
||||
use winapi::um::winnt::{FILE_SHARE_READ, FILE_SHARE_WRITE, GENERIC_READ, GENERIC_WRITE};
|
||||
|
||||
unsafe
|
||||
{
|
||||
let mut security_attr: SECURITY_ATTRIBUTES = SECURITY_ATTRIBUTES
|
||||
{
|
||||
unsafe {
|
||||
let mut security_attr: SECURITY_ATTRIBUTES = SECURITY_ATTRIBUTES {
|
||||
nLength: size_of::<SECURITY_ATTRIBUTES>() as u32,
|
||||
lpSecurityDescriptor: NULL,
|
||||
bInheritHandle: TRUE
|
||||
bInheritHandle: TRUE,
|
||||
};
|
||||
|
||||
let new_screen_buffer = CreateConsoleScreenBuffer(
|
||||
GENERIC_READ | // read/write access
|
||||
GENERIC_WRITE,
|
||||
FILE_SHARE_READ |
|
||||
FILE_SHARE_WRITE, // shared
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE, // shared
|
||||
&mut security_attr, // default security attributes
|
||||
CONSOLE_TEXTMODE_BUFFER, // must be TEXTMODE
|
||||
NULL
|
||||
NULL,
|
||||
);
|
||||
new_screen_buffer
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the active screen buffer to the given handle. This can be used for alternate screen.
|
||||
pub fn set_active_screen_buffer(new_buffer: HANDLE)
|
||||
{
|
||||
unsafe
|
||||
{
|
||||
if !is_true(SetConsoleActiveScreenBuffer(new_buffer))
|
||||
{
|
||||
pub fn set_active_screen_buffer(new_buffer: HANDLE) {
|
||||
unsafe {
|
||||
if !is_true(SetConsoleActiveScreenBuffer(new_buffer)) {
|
||||
panic!("Cannot set active screen buffer");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Read the console outptut.
|
||||
pub fn read_console_output(read_buffer: &HANDLE, copy_buffer: &mut [CHAR_INFO;160], buffer_size: COORD, buffer_coord: COORD, source_buffer: PSMALL_RECT)
|
||||
{
|
||||
pub fn read_console_output(
|
||||
read_buffer: &HANDLE,
|
||||
copy_buffer: &mut [CHAR_INFO; 160],
|
||||
buffer_size: COORD,
|
||||
buffer_coord: COORD,
|
||||
source_buffer: PSMALL_RECT,
|
||||
) {
|
||||
use self::wincon::ReadConsoleOutputA;
|
||||
|
||||
unsafe
|
||||
{
|
||||
if !is_true(ReadConsoleOutputA(
|
||||
unsafe {
|
||||
if !is_true(
|
||||
ReadConsoleOutputA(
|
||||
*read_buffer, // screen buffer to read from
|
||||
copy_buffer.as_mut_ptr(), // buffer to copy into
|
||||
buffer_size, // col-row size of chiBuffer
|
||||
buffer_coord, // top left dest. cell in chiBuffer
|
||||
source_buffer) // screen buffer source rectangle
|
||||
){
|
||||
|
||||
source_buffer,
|
||||
), // screen buffer source rectangle
|
||||
) {
|
||||
panic!("Cannot read console output");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Write console output.
|
||||
pub fn write_console_output(write_buffer: &HANDLE, copy_buffer: &mut [CHAR_INFO;160], buffer_size: COORD, buffer_coord: COORD, source_buffer: PSMALL_RECT)
|
||||
{
|
||||
pub fn write_console_output(
|
||||
write_buffer: &HANDLE,
|
||||
copy_buffer: &mut [CHAR_INFO; 160],
|
||||
buffer_size: COORD,
|
||||
buffer_coord: COORD,
|
||||
source_buffer: PSMALL_RECT,
|
||||
) {
|
||||
use self::wincon::WriteConsoleOutputA;
|
||||
|
||||
unsafe
|
||||
{
|
||||
if !is_true(WriteConsoleOutputA(
|
||||
unsafe {
|
||||
if !is_true(
|
||||
WriteConsoleOutputA(
|
||||
*write_buffer, // screen buffer to write to
|
||||
copy_buffer.as_mut_ptr(), // buffer to copy into
|
||||
buffer_size, // col-row size of chiBuffer
|
||||
buffer_coord, // top left dest. cell in chiBuffer
|
||||
source_buffer)// screen buffer source rectangle
|
||||
){
|
||||
|
||||
source_buffer,
|
||||
), // screen buffer source rectangle
|
||||
) {
|
||||
panic!("Cannot write to console output");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
use std::ffi::OsStr;
|
||||
use std::os::windows::ffi::OsStrExt;
|
||||
use std::iter::once;
|
||||
use std::os::windows::ffi::OsStrExt;
|
||||
|
||||
fn win32_string( value : &str ) -> Vec<u16> {
|
||||
OsStr::new( value ).encode_wide().chain( once( 0 ) ).collect()
|
||||
fn win32_string(value: &str) -> Vec<u16> {
|
||||
OsStr::new(value).encode_wide().chain(once(0)).collect()
|
||||
}
|
||||
|
||||
//use std::os::raw::c_void;
|
||||
use winapi::ctypes::c_void;
|
||||
use std::mem::transmute;
|
||||
use std::str;
|
||||
use winapi::ctypes::c_void;
|
||||
|
||||
/// Write utf8 buffer to console.
|
||||
pub fn write_char_buffer(handle: HANDLE, buf: &[u8])
|
||||
{
|
||||
pub fn write_char_buffer(handle: HANDLE, buf: &[u8]) {
|
||||
// get string from u8[] and parse it to an c_str
|
||||
let mut utf8 = match str::from_utf8(buf)
|
||||
{
|
||||
let mut utf8 = match str::from_utf8(buf) {
|
||||
Ok(string) => string,
|
||||
Err(_) => "123",
|
||||
};
|
||||
@ -420,24 +440,30 @@ pub fn write_char_buffer(handle: HANDLE, buf: &[u8])
|
||||
let csbi = get_console_screen_buffer_info_from_handle(&handle);
|
||||
|
||||
// get current position
|
||||
let current_pos = COORD {X: csbi.dwCursorPosition.X, Y: csbi.dwCursorPosition.Y};
|
||||
let current_pos = COORD {
|
||||
X: csbi.dwCursorPosition.X,
|
||||
Y: csbi.dwCursorPosition.Y,
|
||||
};
|
||||
|
||||
let mut cells_written: u32 = 0;
|
||||
|
||||
// write to console
|
||||
unsafe
|
||||
{
|
||||
WriteConsoleW(handle, utf16_ptr, utf16.len() as u32, &mut cells_written, NULL);
|
||||
unsafe {
|
||||
WriteConsoleW(
|
||||
handle,
|
||||
utf16_ptr,
|
||||
utf16.len() as u32,
|
||||
&mut cells_written,
|
||||
NULL,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Parse integer to an bool
|
||||
fn is_true(value: i32) -> bool
|
||||
{
|
||||
if value == 0{
|
||||
fn is_true(value: i32) -> bool {
|
||||
if value == 0 {
|
||||
return false;
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +1,13 @@
|
||||
//! This module contains the `windows` specific logic.
|
||||
|
||||
pub mod kernel;
|
||||
pub mod cursor;
|
||||
pub mod terminal;
|
||||
pub mod ansi_support;
|
||||
pub mod cursor;
|
||||
pub mod kernel;
|
||||
pub mod terminal;
|
||||
|
||||
use winapi;
|
||||
use self::winapi::um::wincon::{CONSOLE_SCREEN_BUFFER_INFO, COORD, SMALL_RECT};
|
||||
use shared::traits::Empty;
|
||||
use self::winapi::um::wincon::{COORD, CONSOLE_SCREEN_BUFFER_INFO, SMALL_RECT};
|
||||
use winapi;
|
||||
|
||||
impl Empty for COORD {
|
||||
fn empty() -> COORD {
|
||||
|
@ -1,7 +1,6 @@
|
||||
use ScreenManager;
|
||||
use std::sync::Mutex;
|
||||
use std::rc::Rc;
|
||||
|
||||
use std::sync::Mutex;
|
||||
use ScreenManager;
|
||||
|
||||
/// Get the terminal size
|
||||
pub fn terminal_size(screen_manager: &Rc<Mutex<ScreenManager>>) -> (u16, u16) {
|
||||
@ -13,7 +12,6 @@ pub fn terminal_size(screen_manager: &Rc<Mutex<ScreenManager>>) -> (u16, u16) {
|
||||
}
|
||||
|
||||
/// Exit the current process.
|
||||
pub fn exit()
|
||||
{
|
||||
pub fn exit() {
|
||||
::std::process::exit(256);
|
||||
}
|
14
src/lib.rs
14
src/lib.rs
@ -9,22 +9,22 @@ mod kernel;
|
||||
mod state;
|
||||
|
||||
pub mod cursor;
|
||||
pub mod manager;
|
||||
pub mod style;
|
||||
pub mod terminal;
|
||||
pub mod manager;
|
||||
|
||||
pub use shared::{screen};
|
||||
pub use shared::environment::Environment;
|
||||
pub use shared::screen;
|
||||
pub use state::context::Context;
|
||||
|
||||
use state::commands::IStateCommand;
|
||||
use state::command_manager::CommandManager;
|
||||
use state::state_manager::StateManager;
|
||||
use manager::ScreenManager;
|
||||
use state::command_manager::CommandManager;
|
||||
use state::commands::IStateCommand;
|
||||
use state::state_manager::StateManager;
|
||||
|
||||
#[cfg(windows)]
|
||||
extern crate winapi;
|
||||
#[cfg(unix)]
|
||||
extern crate libc;
|
||||
#[cfg(unix)]
|
||||
extern crate termios;
|
||||
#[cfg(windows)]
|
||||
extern crate winapi;
|
||||
|
@ -2,32 +2,27 @@
|
||||
//! This module is used for windows 10 terminals and unix terminals by default.
|
||||
//! This module uses the stdout to write to the console.
|
||||
|
||||
use std::io::{self, Write};
|
||||
use std::any::Any;
|
||||
use std::io::{self, Write};
|
||||
|
||||
use super::IScreenManager;
|
||||
|
||||
pub struct AnsiScreenManager
|
||||
{
|
||||
pub struct AnsiScreenManager {
|
||||
pub is_alternate_screen: bool,
|
||||
output: Box<Write>,
|
||||
}
|
||||
|
||||
impl IScreenManager for AnsiScreenManager
|
||||
{
|
||||
fn toggle_is_alternate_screen(&mut self, is_alternate_screen: bool)
|
||||
{
|
||||
impl IScreenManager for AnsiScreenManager {
|
||||
fn toggle_is_alternate_screen(&mut self, is_alternate_screen: bool) {
|
||||
self.is_alternate_screen = is_alternate_screen;
|
||||
}
|
||||
|
||||
fn write_ansi(&mut self, string: String)
|
||||
{
|
||||
fn write_ansi(&mut self, string: String) {
|
||||
write!(self.output, "{}", string);
|
||||
self.flush();
|
||||
}
|
||||
|
||||
fn write_ansi_str(&mut self, string: &str)
|
||||
{
|
||||
fn write_ansi_str(&mut self, string: &str) {
|
||||
write!(self.output, "{}", string);
|
||||
self.flush();
|
||||
}
|
||||
@ -40,8 +35,7 @@ impl IScreenManager for AnsiScreenManager
|
||||
self.output.flush()
|
||||
}
|
||||
|
||||
fn as_any(&mut self) -> &mut Any
|
||||
{
|
||||
fn as_any(&mut self) -> &mut Any {
|
||||
self
|
||||
}
|
||||
}
|
||||
@ -50,7 +44,7 @@ impl AnsiScreenManager {
|
||||
pub fn new() -> Self {
|
||||
AnsiScreenManager {
|
||||
output: (Box::from(io::stdout()) as Box<Write>),
|
||||
is_alternate_screen: false
|
||||
is_alternate_screen: false,
|
||||
}
|
||||
}
|
||||
}
|
@ -1,66 +1,64 @@
|
||||
//! This module provides an interface for working with the screen. With that I mean that you can get or wirte to the handle of the current screen. stdout.
|
||||
//! Because crossterm can work with alternate screen, we need a place that holds the handle to the current screen so we can write to that screen.
|
||||
|
||||
use super::*;
|
||||
use super::super::shared::functions;
|
||||
use super::*;
|
||||
use std::any::Any;
|
||||
|
||||
use std::fmt::Display;
|
||||
use std::io::{ self, Write };
|
||||
use std::io::{self, Write};
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
use winapi::um::winnt::HANDLE;
|
||||
|
||||
/// Struct that stores an specific platform implementation for screen related actions.
|
||||
pub struct ScreenManager
|
||||
{
|
||||
screen_manager: Box<IScreenManager>
|
||||
pub struct ScreenManager {
|
||||
screen_manager: Box<IScreenManager>,
|
||||
}
|
||||
|
||||
impl ScreenManager
|
||||
{
|
||||
impl ScreenManager {
|
||||
/// Create new screen manager instance whereon screen related actions can be performed.
|
||||
pub fn new() -> ScreenManager {
|
||||
#[cfg(target_os = "windows")]
|
||||
let screen_manager = functions::get_module::<Box<IScreenManager>>(Box::from(WinApiScreenManager::new()), Box::from(AnsiScreenManager::new())).unwrap();
|
||||
let screen_manager = functions::get_module::<Box<IScreenManager>>(
|
||||
Box::from(WinApiScreenManager::new()),
|
||||
Box::from(AnsiScreenManager::new()),
|
||||
).unwrap();
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
let screen_manager = Box::from(AnsiScreenManager::new()) as Box<IScreenManager>;
|
||||
|
||||
ScreenManager
|
||||
{
|
||||
screen_manager: screen_manager
|
||||
ScreenManager {
|
||||
screen_manager: screen_manager,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn toggle_is_alternate_screen(&mut self, is_alternate_screen: bool)
|
||||
{
|
||||
self.screen_manager.toggle_is_alternate_screen(is_alternate_screen);
|
||||
pub fn toggle_is_alternate_screen(&mut self, is_alternate_screen: bool) {
|
||||
self.screen_manager
|
||||
.toggle_is_alternate_screen(is_alternate_screen);
|
||||
}
|
||||
|
||||
/// Write an ANSI code as String.
|
||||
pub fn write_ansi(&mut self, string: String)
|
||||
{
|
||||
pub fn write_ansi(&mut self, string: String) {
|
||||
self.screen_manager.write_ansi(string);
|
||||
}
|
||||
|
||||
/// Write an ANSI code as &str
|
||||
pub fn write_ansi_str(&mut self, string: &str)
|
||||
{
|
||||
pub fn write_ansi_str(&mut self, string: &str) {
|
||||
self.screen_manager.write_ansi_str(string);
|
||||
}
|
||||
|
||||
/// Can be used to get an specific implementation used for the current platform.
|
||||
pub fn as_any(&mut self) -> &mut Any { self.screen_manager.as_any() }
|
||||
pub fn as_any(&mut self) -> &mut Any {
|
||||
self.screen_manager.as_any()
|
||||
}
|
||||
|
||||
pub fn write_val(&mut self, value: String)
|
||||
{
|
||||
pub fn write_val(&mut self, value: String) {
|
||||
self.screen_manager.write(value.as_bytes());
|
||||
}
|
||||
}
|
||||
|
||||
impl Write for ScreenManager
|
||||
{
|
||||
impl Write for ScreenManager {
|
||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||
self.write(buf)
|
||||
}
|
||||
|
@ -3,20 +3,19 @@
|
||||
|
||||
pub mod manager;
|
||||
|
||||
mod ansi_manager;
|
||||
#[cfg(target_os = "windows")]
|
||||
mod win_manager;
|
||||
mod ansi_manager;
|
||||
|
||||
pub use self::ansi_manager::AnsiScreenManager;
|
||||
#[cfg(target_os = "windows")]
|
||||
pub use self::win_manager::WinApiScreenManager;
|
||||
pub use self::ansi_manager::AnsiScreenManager;
|
||||
|
||||
pub use self::manager::{ ScreenManager };
|
||||
use std::io;
|
||||
pub use self::manager::ScreenManager;
|
||||
use std::any::Any;
|
||||
use std::io;
|
||||
|
||||
pub trait IScreenManager
|
||||
{
|
||||
pub trait IScreenManager {
|
||||
/// Toggle the value if alternatescreen is on.
|
||||
fn toggle_is_alternate_screen(&mut self, is_alternate_screen: bool);
|
||||
/// Write ansi code as String to the current stdout.
|
||||
|
@ -1,38 +1,31 @@
|
||||
use super::IScreenManager;
|
||||
use kernel::windows_kernel::kernel;
|
||||
use winapi::um::winnt::HANDLE;
|
||||
use winapi::um::wincon::ENABLE_PROCESSED_OUTPUT;
|
||||
use winapi::um::winnt::HANDLE;
|
||||
|
||||
use std::io::{self,Write};
|
||||
use std::any::Any;
|
||||
use std::io::{self, Write};
|
||||
use std::rc::Rc;
|
||||
|
||||
pub struct WinApiScreenManager
|
||||
{
|
||||
pub struct WinApiScreenManager {
|
||||
pub is_alternate_screen: bool,
|
||||
output: HANDLE,
|
||||
alternate_handle: HANDLE
|
||||
alternate_handle: HANDLE,
|
||||
}
|
||||
|
||||
impl IScreenManager for WinApiScreenManager
|
||||
{
|
||||
fn toggle_is_alternate_screen(&mut self, is_alternate_screen: bool)
|
||||
{
|
||||
impl IScreenManager for WinApiScreenManager {
|
||||
fn toggle_is_alternate_screen(&mut self, is_alternate_screen: bool) {
|
||||
self.is_alternate_screen = is_alternate_screen;
|
||||
}
|
||||
|
||||
fn write_ansi(&mut self, string: String)
|
||||
{ }
|
||||
fn write_ansi(&mut self, string: String) {}
|
||||
|
||||
fn write_ansi_str(&mut self, string: &str)
|
||||
{ }
|
||||
fn write_ansi_str(&mut self, string: &str) {}
|
||||
|
||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||
if self.is_alternate_screen
|
||||
{
|
||||
if self.is_alternate_screen {
|
||||
kernel::write_char_buffer(self.alternate_handle, buf);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
kernel::write_char_buffer(self.output, buf);
|
||||
}
|
||||
Ok(0)
|
||||
@ -42,8 +35,7 @@ impl IScreenManager for WinApiScreenManager
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn as_any(&mut self) -> &mut Any
|
||||
{
|
||||
fn as_any(&mut self) -> &mut Any {
|
||||
self
|
||||
}
|
||||
}
|
||||
@ -57,21 +49,17 @@ impl WinApiScreenManager {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_alternate_handle(&mut self, alternate_handle: HANDLE)
|
||||
{
|
||||
pub fn set_alternate_handle(&mut self, alternate_handle: HANDLE) {
|
||||
self.alternate_handle = alternate_handle;
|
||||
|
||||
// needs to be turned on so that escape characters like \n and \t will be processed.
|
||||
kernel::set_console_mode(&self.alternate_handle, ENABLE_PROCESSED_OUTPUT as u32);
|
||||
}
|
||||
|
||||
pub fn get_handle(&mut self) -> &HANDLE
|
||||
{
|
||||
if self.is_alternate_screen
|
||||
{
|
||||
pub fn get_handle(&mut self) -> &HANDLE {
|
||||
if self.is_alternate_screen {
|
||||
return &self.alternate_handle;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
return &self.output;
|
||||
}
|
||||
}
|
||||
|
@ -1,66 +1,60 @@
|
||||
use Context;
|
||||
use super::super::cursor;
|
||||
use super::super::terminal::terminal;
|
||||
use super::super::style;
|
||||
use super::super::terminal::terminal;
|
||||
use Context;
|
||||
|
||||
use std::fmt::Display;
|
||||
use std::mem;
|
||||
use std::rc::Rc;
|
||||
use std::fmt::Display;
|
||||
use std::sync::{ONCE_INIT, Once};
|
||||
use std::sync::{Once, ONCE_INIT};
|
||||
static START: Once = ONCE_INIT;
|
||||
|
||||
pub struct Environment
|
||||
{
|
||||
pub struct Environment {
|
||||
context: Rc<Context>,
|
||||
terminal: Box<terminal::Terminal>,
|
||||
cursor: Box<cursor::TerminalCursor>,
|
||||
color: Box<style::TerminalColor>
|
||||
color: Box<style::TerminalColor>,
|
||||
}
|
||||
|
||||
impl Environment
|
||||
{
|
||||
pub fn new() -> Environment
|
||||
{
|
||||
return Environment { context: Context::new(), terminal: unsafe{ mem::zeroed()}, cursor: unsafe{ mem::zeroed()}, color: unsafe{ mem::zeroed() }}
|
||||
impl Environment {
|
||||
pub fn new() -> Environment {
|
||||
return Environment {
|
||||
context: Context::new(),
|
||||
terminal: unsafe { mem::zeroed() },
|
||||
cursor: unsafe { mem::zeroed() },
|
||||
color: unsafe { mem::zeroed() },
|
||||
};
|
||||
}
|
||||
|
||||
pub fn terminal(&mut self) -> &Box<terminal::Terminal>
|
||||
{
|
||||
pub fn terminal(&mut self) -> &Box<terminal::Terminal> {
|
||||
START.call_once(|| {
|
||||
self.terminal = terminal::terminal(self.context.clone());
|
||||
|
||||
});
|
||||
|
||||
&self.terminal
|
||||
}
|
||||
|
||||
pub fn cursor(&mut self) -> &Box<cursor::TerminalCursor>
|
||||
{
|
||||
pub fn cursor(&mut self) -> &Box<cursor::TerminalCursor> {
|
||||
START.call_once(|| {
|
||||
self.cursor = cursor::cursor(self.context.clone());
|
||||
|
||||
});
|
||||
|
||||
&self.cursor
|
||||
}
|
||||
|
||||
pub fn color(&mut self) -> &Box<style::TerminalColor>
|
||||
{
|
||||
pub fn color(&mut self) -> &Box<style::TerminalColor> {
|
||||
START.call_once(|| {
|
||||
self.color = style::color(self.context.clone());
|
||||
|
||||
});
|
||||
|
||||
&self.color
|
||||
}
|
||||
|
||||
pub fn paint<D: Display>(&mut self, value: D) -> style::StyledObject<D>
|
||||
{
|
||||
pub fn paint<D: Display>(&mut self, value: D) -> style::StyledObject<D> {
|
||||
self.terminal().paint(value)
|
||||
}
|
||||
|
||||
pub fn context(&self) -> Rc<Context>
|
||||
{
|
||||
return self.context.clone()
|
||||
pub fn context(&self) -> Rc<Context> {
|
||||
return self.context.clone();
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
//! Some actions need to preformed platform independently since they can not be solved `ANSI escape codes`.
|
||||
|
||||
use Context;
|
||||
use ScreenManager;
|
||||
use std::rc::Rc;
|
||||
use std::sync::Mutex;
|
||||
use Context;
|
||||
use ScreenManager;
|
||||
|
||||
#[cfg(windows)]
|
||||
use kernel::windows_kernel::terminal::{exit, terminal_size};
|
||||
@ -12,11 +12,10 @@ use kernel::windows_kernel::terminal::{exit, terminal_size};
|
||||
use kernel::windows_kernel::cursor::pos;
|
||||
|
||||
#[cfg(unix)]
|
||||
use kernel::unix_kernel::terminal::{pos, exit,terminal_size };
|
||||
use kernel::unix_kernel::terminal::{exit, pos, terminal_size};
|
||||
|
||||
/// Get the terminal size based on the current platform.
|
||||
pub fn get_terminal_size(screen_manager: &Rc<Mutex<ScreenManager>>) -> (u16, u16)
|
||||
{
|
||||
pub fn get_terminal_size(screen_manager: &Rc<Mutex<ScreenManager>>) -> (u16, u16) {
|
||||
#[cfg(unix)]
|
||||
return terminal_size(screen_manager);
|
||||
|
||||
@ -25,8 +24,7 @@ pub fn get_terminal_size(screen_manager: &Rc<Mutex<ScreenManager>>) -> (u16, u16
|
||||
}
|
||||
|
||||
/// Get the cursor position based on the current platform.
|
||||
pub fn get_cursor_position(context: Rc<Context>) -> (u16, u16)
|
||||
{
|
||||
pub fn get_cursor_position(context: Rc<Context>) -> (u16, u16) {
|
||||
#[cfg(unix)]
|
||||
return pos(context.clone());
|
||||
|
||||
@ -35,8 +33,7 @@ pub fn get_cursor_position(context: Rc<Context>) -> (u16, u16)
|
||||
}
|
||||
|
||||
/// exit the current terminal.
|
||||
pub fn exit_terminal()
|
||||
{
|
||||
pub fn exit_terminal() {
|
||||
#[cfg(unix)]
|
||||
exit();
|
||||
|
||||
@ -46,27 +43,24 @@ pub fn exit_terminal()
|
||||
|
||||
#[cfg(windows)]
|
||||
/// Get an module specific implementation based on the current platform.
|
||||
pub fn get_module<T>(winapi_impl: T, unix_impl: T) -> Option<T>
|
||||
{
|
||||
pub fn get_module<T>(winapi_impl: T, unix_impl: T) -> Option<T> {
|
||||
let mut term: Option<T> = None;
|
||||
let mut does_support = true;
|
||||
|
||||
if cfg!(target_os = "windows") {
|
||||
// #[cfg(windows)]
|
||||
// use kernel::windows_kernel::ansi_support::try_enable_ansi_support;
|
||||
// #[cfg(windows)]
|
||||
// use kernel::windows_kernel::ansi_support::try_enable_ansi_support;
|
||||
|
||||
// Try to enable ansi on windows if not than use WINAPI.
|
||||
// does_support = try_enable_ansi_support();
|
||||
// does_support = try_enable_ansi_support();
|
||||
|
||||
does_support = false;
|
||||
if !does_support
|
||||
{
|
||||
if !does_support {
|
||||
term = Some(winapi_impl);
|
||||
}
|
||||
}
|
||||
|
||||
if does_support
|
||||
{
|
||||
if does_support {
|
||||
println!("Does support");
|
||||
term = Some(unix_impl);
|
||||
}
|
||||
|
@ -2,10 +2,10 @@
|
||||
|
||||
#[macro_use]
|
||||
pub mod macros;
|
||||
pub mod traits;
|
||||
pub mod environment;
|
||||
pub mod functions;
|
||||
pub mod screen;
|
||||
pub mod environment;
|
||||
pub mod traits;
|
||||
|
||||
#[cfg(target_os = "unix")]
|
||||
pub mod raw;
|
@ -26,27 +26,24 @@ use super::super::state::commands::unix_command::EnableRawModeCommand;
|
||||
#[cfg(windows)]
|
||||
use state::commands::win_commands::EnableRawModeCommand;
|
||||
|
||||
use {Context, CommandManager };
|
||||
use state::commands::IStateCommand;
|
||||
use {CommandManager, Context};
|
||||
|
||||
use std::io::{ self, Write};
|
||||
use std::io::{self, Write};
|
||||
use std::rc::Rc;
|
||||
|
||||
/// A wrapper for the raw terminal state. Which can be used to write to.
|
||||
pub struct RawTerminal
|
||||
{
|
||||
context : Rc<Context>,
|
||||
pub struct RawTerminal {
|
||||
context: Rc<Context>,
|
||||
command_id: u16,
|
||||
}
|
||||
|
||||
/// Trait withs contains a method for switching into raw mode.
|
||||
pub trait IntoRawMode: Write + Sized
|
||||
{
|
||||
fn into_raw_mode(&self, context:Rc<Context>) -> io::Result<RawTerminal>;
|
||||
pub trait IntoRawMode: Write + Sized {
|
||||
fn into_raw_mode(&self, context: Rc<Context>) -> io::Result<RawTerminal>;
|
||||
}
|
||||
|
||||
impl <W: Write> IntoRawMode for W
|
||||
{
|
||||
impl<W: Write> IntoRawMode for W {
|
||||
/// Raw mode means that input (stdin) won't be printed it will instead have to be written manually by
|
||||
/// the program. The input isn't canonicalised or line buffered (that is, you can
|
||||
/// read from input(stdin) one byte of a time).
|
||||
@ -55,10 +52,14 @@ impl <W: Write> IntoRawMode for W
|
||||
|
||||
let success = CommandManager::execute(context.clone(), command_id);
|
||||
|
||||
if success
|
||||
{
|
||||
Ok(RawTerminal { context: context.clone(), command_id: command_id})
|
||||
}else { panic!("cannot move into raw mode") }
|
||||
if success {
|
||||
Ok(RawTerminal {
|
||||
context: context.clone(),
|
||||
command_id: command_id,
|
||||
})
|
||||
} else {
|
||||
panic!("cannot move into raw mode")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -79,10 +80,8 @@ impl Write for RawTerminal {
|
||||
}
|
||||
|
||||
/// If an instance of `RawTerminal` will be dropped all terminal changes that are made will be undone.
|
||||
impl Drop for RawTerminal
|
||||
{
|
||||
fn drop(&mut self)
|
||||
{
|
||||
impl Drop for RawTerminal {
|
||||
fn drop(&mut self) {
|
||||
let success = CommandManager::undo(self.context.clone(), self.command_id);
|
||||
}
|
||||
}
|
@ -8,16 +8,16 @@
|
||||
//! !! Note: this module is only working for unix and windows 10 terminals only. If you are using windows 10 or lower do not implement this functionality. Work in progress...
|
||||
//!
|
||||
|
||||
use Context;
|
||||
use state::commands::*;
|
||||
use shared::functions;
|
||||
use state::commands::*;
|
||||
use Context;
|
||||
|
||||
use std::io::{self, Write};
|
||||
use std::rc::Rc;
|
||||
|
||||
pub struct AlternateScreen {
|
||||
context: Rc<Context>,
|
||||
command_id: u16
|
||||
command_id: u16,
|
||||
}
|
||||
|
||||
impl AlternateScreen {
|
||||
@ -27,14 +27,16 @@ impl AlternateScreen {
|
||||
pub fn from(context: Rc<Context>) -> Self {
|
||||
let command_id = get_to_alternate_screen_command(context.clone());
|
||||
|
||||
let screen = AlternateScreen { context: context, command_id: command_id };
|
||||
let screen = AlternateScreen {
|
||||
context: context,
|
||||
command_id: command_id,
|
||||
};
|
||||
screen.to_alternate();
|
||||
return screen;
|
||||
}
|
||||
|
||||
/// Change the current screen to the mainscreen.
|
||||
pub fn to_main(&self)
|
||||
{
|
||||
pub fn to_main(&self) {
|
||||
let mut mutex = &self.context.state_manager;
|
||||
{
|
||||
let mut state_manager = mutex.lock().unwrap();
|
||||
@ -48,8 +50,7 @@ impl AlternateScreen {
|
||||
}
|
||||
|
||||
/// Change the current screen to alternate screen.
|
||||
pub fn to_alternate(&self)
|
||||
{
|
||||
pub fn to_alternate(&self) {
|
||||
let mut mutex = &self.context.state_manager;
|
||||
{
|
||||
let mut state_manager = mutex.lock().unwrap();
|
||||
@ -79,10 +80,8 @@ impl Write for AlternateScreen {
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for AlternateScreen
|
||||
{
|
||||
fn drop(&mut self)
|
||||
{
|
||||
impl Drop for AlternateScreen {
|
||||
fn drop(&mut self) {
|
||||
use CommandManager;
|
||||
|
||||
CommandManager::undo(self.context.clone(), self.command_id);
|
||||
@ -90,10 +89,12 @@ impl Drop for AlternateScreen
|
||||
}
|
||||
|
||||
// Get the alternate screen command to enable and disable alternate screen based on the current platform
|
||||
fn get_to_alternate_screen_command(context: Rc<Context>) -> u16
|
||||
{
|
||||
fn get_to_alternate_screen_command(context: Rc<Context>) -> u16 {
|
||||
#[cfg(target_os = "windows")]
|
||||
let command_id = functions::get_module::<u16>(win_commands::ToAlternateScreenBufferCommand::new(context.clone()), shared_commands::ToAlternateScreenBufferCommand::new(context.clone())).unwrap();
|
||||
let command_id = functions::get_module::<u16>(
|
||||
win_commands::ToAlternateScreenBufferCommand::new(context.clone()),
|
||||
shared_commands::ToAlternateScreenBufferCommand::new(context.clone()),
|
||||
).unwrap();
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
let command_id = shared_commands::ToAlternateScreenBufferCommand::new(context.clone());
|
||||
|
@ -2,4 +2,3 @@
|
||||
pub trait Empty {
|
||||
fn empty() -> Self;
|
||||
}
|
||||
|
||||
|
@ -1,16 +1,14 @@
|
||||
use super::commands::IStateCommand;
|
||||
use std::rc::Rc;
|
||||
use std::sync::Mutex;
|
||||
use Context;
|
||||
use super::commands::IStateCommand;
|
||||
|
||||
/// Simple wrapper for executing an command.
|
||||
pub struct CommandManager;
|
||||
|
||||
impl CommandManager
|
||||
{
|
||||
impl CommandManager {
|
||||
/// execute an certain command by id.
|
||||
pub fn execute(context: Rc<Context>, command_id: u16) -> bool
|
||||
{
|
||||
pub fn execute(context: Rc<Context>, command_id: u16) -> bool {
|
||||
let mut mutex: Rc<Mutex<Box<IStateCommand>>>;
|
||||
|
||||
let mut state = context.state_manager.lock().unwrap();
|
||||
@ -24,8 +22,7 @@ impl CommandManager
|
||||
}
|
||||
|
||||
/// undo an certain command by id.
|
||||
pub fn undo(context: Rc<Context>, command_id: u16) -> bool
|
||||
{
|
||||
pub fn undo(context: Rc<Context>, command_id: u16) -> bool {
|
||||
let mut mutex: Rc<Mutex<Box<IStateCommand>>>;
|
||||
|
||||
let mut state = context.state_manager.lock().unwrap();
|
||||
|
@ -9,8 +9,8 @@
|
||||
//!
|
||||
//! See the `StateManager` struct where we store the commands for more info.
|
||||
|
||||
use std::sync::Mutex;
|
||||
use std::rc::Rc;
|
||||
use std::sync::Mutex;
|
||||
|
||||
#[cfg(unix)]
|
||||
pub mod unix_command;
|
||||
@ -25,11 +25,9 @@ pub use self::unix_command::*;
|
||||
#[cfg(windows)]
|
||||
pub use self::win_commands::*;
|
||||
|
||||
|
||||
/// This command is used for complex commands whits change the terminal state.
|
||||
/// By passing an `Context` instance this command will register it self to notify the terminal state change.
|
||||
pub trait IStateCommand
|
||||
{
|
||||
pub trait IStateCommand {
|
||||
fn execute(&mut self) -> bool;
|
||||
fn undo(&mut self) -> bool;
|
||||
}
|
@ -1,38 +1,34 @@
|
||||
//! This module contains the commands that can be used for both unix and windows systems. Or else said terminals that support ansi codes.
|
||||
use super::IStateCommand;
|
||||
use Context;
|
||||
use super::{IStateCommand};
|
||||
|
||||
use std::rc::Rc;
|
||||
|
||||
pub struct EmptyCommand;
|
||||
|
||||
impl IStateCommand for EmptyCommand
|
||||
{
|
||||
fn execute(&mut self) -> bool
|
||||
{
|
||||
return false
|
||||
impl IStateCommand for EmptyCommand {
|
||||
fn execute(&mut self) -> bool {
|
||||
return false;
|
||||
}
|
||||
|
||||
fn undo(&mut self) -> bool
|
||||
{
|
||||
fn undo(&mut self) -> bool {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// This command is used for switching to alternate screen and back to main screen.
|
||||
pub struct ToAlternateScreenBufferCommand
|
||||
{
|
||||
context: Rc<Context>
|
||||
pub struct ToAlternateScreenBufferCommand {
|
||||
context: Rc<Context>,
|
||||
}
|
||||
|
||||
impl ToAlternateScreenBufferCommand
|
||||
{
|
||||
impl ToAlternateScreenBufferCommand {
|
||||
pub fn new(context: Rc<Context>) -> u16 {
|
||||
|
||||
let mut state = context.state_manager.lock().unwrap();
|
||||
{
|
||||
let key = state.get_changes_count();
|
||||
let command = ToAlternateScreenBufferCommand {context: context.clone()};
|
||||
let command = ToAlternateScreenBufferCommand {
|
||||
context: context.clone(),
|
||||
};
|
||||
|
||||
state.register_change(Box::from(command), key);
|
||||
key
|
||||
@ -40,11 +36,8 @@ impl ToAlternateScreenBufferCommand
|
||||
}
|
||||
}
|
||||
|
||||
impl IStateCommand for ToAlternateScreenBufferCommand
|
||||
{
|
||||
fn execute(&mut self) -> bool
|
||||
{
|
||||
|
||||
impl IStateCommand for ToAlternateScreenBufferCommand {
|
||||
fn execute(&mut self) -> bool {
|
||||
println!("asdfasdf");
|
||||
let mut screen = self.context.screen_manager.lock().unwrap();
|
||||
{
|
||||
@ -53,8 +46,7 @@ impl IStateCommand for ToAlternateScreenBufferCommand
|
||||
}
|
||||
}
|
||||
|
||||
fn undo(&mut self) -> bool
|
||||
{
|
||||
fn undo(&mut self) -> bool {
|
||||
let mut screen = self.context.screen_manager.lock().unwrap();
|
||||
{
|
||||
screen.write_ansi_str(csi!("?1049l"));
|
||||
|
@ -1,26 +1,23 @@
|
||||
//! This module contains the commands that can be used for unix systems.
|
||||
|
||||
use {Context, StateManager, CommandManager};
|
||||
use super::IStateCommand;
|
||||
use kernel::unix_kernel::terminal;
|
||||
use termios::{Termios, tcsetattr, TCSAFLUSH, ICANON, ECHO, CREAD};
|
||||
use termios::{tcsetattr, Termios, CREAD, ECHO, ICANON, TCSAFLUSH};
|
||||
use {CommandManager, Context, StateManager};
|
||||
|
||||
const FD_STDIN: ::std::os::unix::io::RawFd = 1;
|
||||
|
||||
use std::sync::Mutex;
|
||||
use std::rc::Rc;
|
||||
use std::sync::Mutex;
|
||||
|
||||
/// This command is used for switching to NoncanonicalMode.
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct NoncanonicalModeCommand
|
||||
{
|
||||
key: u16
|
||||
pub struct NoncanonicalModeCommand {
|
||||
key: u16,
|
||||
}
|
||||
|
||||
impl NoncanonicalModeCommand
|
||||
{
|
||||
pub fn new(state_manager: &Mutex<StateManager>) -> u16
|
||||
{
|
||||
impl NoncanonicalModeCommand {
|
||||
pub fn new(state_manager: &Mutex<StateManager>) -> u16 {
|
||||
let mut state = state_manager.lock().unwrap();
|
||||
{
|
||||
let key = state.get_changes_count();
|
||||
@ -32,63 +29,56 @@ impl NoncanonicalModeCommand
|
||||
}
|
||||
}
|
||||
|
||||
impl IStateCommand for NoncanonicalModeCommand
|
||||
{
|
||||
fn execute(&mut self) -> bool
|
||||
{
|
||||
impl IStateCommand for NoncanonicalModeCommand {
|
||||
fn execute(&mut self) -> bool {
|
||||
// Set noncanonical mode
|
||||
if let Ok(orig) = Termios::from_fd(FD_STDIN)
|
||||
{
|
||||
if let Ok(orig) = Termios::from_fd(FD_STDIN) {
|
||||
let mut noncan = orig.clone();
|
||||
noncan.c_lflag &= !ICANON;
|
||||
noncan.c_lflag &= !ECHO;
|
||||
noncan.c_lflag &= !CREAD;
|
||||
match tcsetattr(FD_STDIN, TCSAFLUSH, &noncan)
|
||||
{
|
||||
match tcsetattr(FD_STDIN, TCSAFLUSH, &noncan) {
|
||||
Ok(_) => return true,
|
||||
Err(_) => return false,
|
||||
};
|
||||
}else {
|
||||
return false
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
fn undo(&mut self) -> bool
|
||||
{
|
||||
fn undo(&mut self) -> bool {
|
||||
// Disable noncanonical mode
|
||||
if let Ok(orig) = Termios::from_fd(FD_STDIN)
|
||||
{
|
||||
if let Ok(orig) = Termios::from_fd(FD_STDIN) {
|
||||
let mut noncan = orig.clone();
|
||||
noncan.c_lflag &= ICANON;
|
||||
noncan.c_lflag &= ECHO;
|
||||
noncan.c_lflag &= CREAD;
|
||||
|
||||
match tcsetattr(FD_STDIN, TCSAFLUSH, &noncan)
|
||||
{
|
||||
match tcsetattr(FD_STDIN, TCSAFLUSH, &noncan) {
|
||||
Ok(_) => return true,
|
||||
Err(_) => return false,
|
||||
};
|
||||
}else {
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// This command is used for enabling and disabling raw mode for the terminal.
|
||||
pub struct EnableRawModeCommand
|
||||
{
|
||||
pub struct EnableRawModeCommand {
|
||||
original_mode: Option<Box<Termios>>,
|
||||
command_id: u16
|
||||
command_id: u16,
|
||||
}
|
||||
|
||||
impl EnableRawModeCommand
|
||||
{
|
||||
pub fn new(state_manager: &Mutex<StateManager>) -> u16{
|
||||
|
||||
impl EnableRawModeCommand {
|
||||
pub fn new(state_manager: &Mutex<StateManager>) -> u16 {
|
||||
let mut state = state_manager.lock().unwrap();
|
||||
{
|
||||
let key = state.get_changes_count();
|
||||
let command = EnableRawModeCommand { original_mode: None, command_id: key };
|
||||
let command = EnableRawModeCommand {
|
||||
original_mode: None,
|
||||
command_id: key,
|
||||
};
|
||||
|
||||
state.register_change(Box::from(command), key);
|
||||
key
|
||||
@ -96,37 +86,30 @@ impl EnableRawModeCommand
|
||||
}
|
||||
}
|
||||
|
||||
impl IStateCommand for EnableRawModeCommand
|
||||
{
|
||||
fn execute(&mut self) -> bool
|
||||
{
|
||||
impl IStateCommand for EnableRawModeCommand {
|
||||
fn execute(&mut self) -> bool {
|
||||
let original_mode = terminal::get_terminal_mode();
|
||||
|
||||
if let Ok(original_mode) = original_mode
|
||||
{
|
||||
if let Ok(original_mode) = original_mode {
|
||||
self.original_mode = Some(Box::from(original_mode));
|
||||
let mut new_mode = original_mode;
|
||||
terminal::make_raw(&mut new_mode);
|
||||
terminal::set_terminal_mode(&new_mode);
|
||||
true
|
||||
|
||||
}else {
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
fn undo(&mut self) -> bool
|
||||
{
|
||||
if let Some(ref original_mode) = self.original_mode
|
||||
{
|
||||
fn undo(&mut self) -> bool {
|
||||
if let Some(ref original_mode) = self.original_mode {
|
||||
let result = terminal::set_terminal_mode(&original_mode);
|
||||
|
||||
match result
|
||||
{
|
||||
match result {
|
||||
Ok(()) => true,
|
||||
Err(_) => false
|
||||
Err(_) => false,
|
||||
}
|
||||
}else {
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +1,13 @@
|
||||
//! This module contains the commands that can be used for windows systems.
|
||||
|
||||
use super::IStateCommand;
|
||||
use {StateManager, Context};
|
||||
use {Context, StateManager};
|
||||
|
||||
use kernel::windows_kernel::{kernel, ansi_support};
|
||||
use kernel::windows_kernel::{ansi_support, kernel};
|
||||
use std::mem;
|
||||
use winapi::shared::minwindef::DWORD;
|
||||
use winapi::um::wincon;
|
||||
use winapi::um::wincon::{ENABLE_VIRTUAL_TERMINAL_PROCESSING, SMALL_RECT, COORD, CHAR_INFO};
|
||||
use std::mem;
|
||||
use winapi::um::wincon::{CHAR_INFO, COORD, ENABLE_VIRTUAL_TERMINAL_PROCESSING, SMALL_RECT};
|
||||
|
||||
use std::rc::Rc;
|
||||
use std::sync::Mutex;
|
||||
@ -15,40 +15,34 @@ use std::sync::Mutex;
|
||||
/// This command is used for enabling and disabling ANSI code support for windows systems,
|
||||
/// For more info check: https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences.
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct EnableAnsiCommand
|
||||
{
|
||||
pub struct EnableAnsiCommand {
|
||||
mask: DWORD,
|
||||
}
|
||||
|
||||
impl EnableAnsiCommand
|
||||
{
|
||||
impl EnableAnsiCommand {
|
||||
pub fn new() -> Box<EnableAnsiCommand> {
|
||||
let command = EnableAnsiCommand { mask: ENABLE_VIRTUAL_TERMINAL_PROCESSING };
|
||||
let command = EnableAnsiCommand {
|
||||
mask: ENABLE_VIRTUAL_TERMINAL_PROCESSING,
|
||||
};
|
||||
Box::from(command)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl IStateCommand for EnableAnsiCommand
|
||||
{
|
||||
fn execute(&mut self) -> bool
|
||||
{
|
||||
impl IStateCommand for EnableAnsiCommand {
|
||||
fn execute(&mut self) -> bool {
|
||||
// we need to check whether we tried to enable ansi before. If we have we can just return if that had succeeded.
|
||||
if ansi_support::has_been_tried_to_enable_ansi() && ansi_support::ansi_enabled()
|
||||
{
|
||||
if ansi_support::has_been_tried_to_enable_ansi() && ansi_support::ansi_enabled() {
|
||||
return ansi_support::windows_supportable();
|
||||
} else {
|
||||
let output_handle = kernel::get_output_handle();
|
||||
|
||||
let mut dw_mode: DWORD = 0;
|
||||
if !kernel::get_console_mode(&output_handle, &mut dw_mode)
|
||||
{
|
||||
if !kernel::get_console_mode(&output_handle, &mut dw_mode) {
|
||||
return false;
|
||||
}
|
||||
|
||||
dw_mode |= self.mask;
|
||||
if !kernel::set_console_mode(&output_handle, dw_mode)
|
||||
{
|
||||
if !kernel::set_console_mode(&output_handle, dw_mode) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -56,21 +50,17 @@ impl IStateCommand for EnableAnsiCommand
|
||||
}
|
||||
}
|
||||
|
||||
fn undo(&mut self) -> bool
|
||||
{
|
||||
if ansi_support::ansi_enabled()
|
||||
{
|
||||
fn undo(&mut self) -> bool {
|
||||
if ansi_support::ansi_enabled() {
|
||||
let output_handle = kernel::get_output_handle();
|
||||
|
||||
let mut dw_mode: DWORD = 0;
|
||||
if !kernel::get_console_mode(&output_handle, &mut dw_mode)
|
||||
{
|
||||
if !kernel::get_console_mode(&output_handle, &mut dw_mode) {
|
||||
return false;
|
||||
}
|
||||
|
||||
dw_mode &= !self.mask;
|
||||
if !kernel::set_console_mode(&output_handle, dw_mode)
|
||||
{
|
||||
if !kernel::set_console_mode(&output_handle, dw_mode) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -83,63 +73,57 @@ impl IStateCommand for EnableAnsiCommand
|
||||
/// This command is used for enabling and disabling raw mode for windows systems.
|
||||
/// For more info check: https://docs.microsoft.com/en-us/windows/console/high-level-console-modes.
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct EnableRawModeCommand
|
||||
{
|
||||
pub struct EnableRawModeCommand {
|
||||
mask: DWORD,
|
||||
key: u16,
|
||||
}
|
||||
|
||||
impl EnableRawModeCommand
|
||||
{
|
||||
impl EnableRawModeCommand {
|
||||
pub fn new(state_manager: &Mutex<StateManager>) -> u16 {
|
||||
use self::wincon::{ENABLE_LINE_INPUT, ENABLE_PROCESSED_INPUT, ENABLE_ECHO_INPUT};
|
||||
use self::wincon::{ENABLE_ECHO_INPUT, ENABLE_LINE_INPUT, ENABLE_PROCESSED_INPUT};
|
||||
|
||||
let mut state = state_manager.lock().unwrap();
|
||||
{
|
||||
let key = state.get_changes_count();
|
||||
let command = EnableRawModeCommand { mask: ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT | ENABLE_ECHO_INPUT, key: key };
|
||||
let command = EnableRawModeCommand {
|
||||
mask: ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT | ENABLE_ECHO_INPUT,
|
||||
key: key,
|
||||
};
|
||||
state.register_change(Box::from(command), key);
|
||||
key
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl IStateCommand for EnableRawModeCommand
|
||||
{
|
||||
fn execute(&mut self) -> bool
|
||||
{
|
||||
impl IStateCommand for EnableRawModeCommand {
|
||||
fn execute(&mut self) -> bool {
|
||||
let input_handle = kernel::get_input_handle();
|
||||
|
||||
let mut dw_mode: DWORD = 0;
|
||||
if !kernel::get_console_mode(&input_handle, &mut dw_mode)
|
||||
{
|
||||
if !kernel::get_console_mode(&input_handle, &mut dw_mode) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let new_mode = dw_mode & !self.mask;
|
||||
|
||||
if !kernel::set_console_mode(&input_handle, new_mode)
|
||||
{
|
||||
if !kernel::set_console_mode(&input_handle, new_mode) {
|
||||
return false;
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
fn undo(&mut self) -> bool
|
||||
{
|
||||
fn undo(&mut self) -> bool {
|
||||
let output_handle = kernel::get_output_handle();
|
||||
|
||||
let mut dw_mode: DWORD = 0;
|
||||
if !kernel::get_console_mode(&output_handle, &mut dw_mode)
|
||||
{
|
||||
if !kernel::get_console_mode(&output_handle, &mut dw_mode) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let new_mode = dw_mode | self.mask;
|
||||
|
||||
if !kernel::set_console_mode(&output_handle, new_mode)
|
||||
{
|
||||
if !kernel::set_console_mode(&output_handle, new_mode) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -149,19 +133,18 @@ impl IStateCommand for EnableRawModeCommand
|
||||
|
||||
/// This command is used for switching to alternate screen and back to main screen.
|
||||
/// check https://docs.microsoft.com/en-us/windows/console/reading-and-writing-blocks-of-characters-and-attributes for more info
|
||||
pub struct ToAlternateScreenBufferCommand
|
||||
{
|
||||
context: Rc<Context>
|
||||
pub struct ToAlternateScreenBufferCommand {
|
||||
context: Rc<Context>,
|
||||
}
|
||||
|
||||
impl ToAlternateScreenBufferCommand
|
||||
{
|
||||
pub fn new(context: Rc<Context>) -> u16
|
||||
{
|
||||
impl ToAlternateScreenBufferCommand {
|
||||
pub fn new(context: Rc<Context>) -> u16 {
|
||||
let mut state = context.state_manager.lock().unwrap();
|
||||
{
|
||||
let key = state.get_changes_count();
|
||||
let command = ToAlternateScreenBufferCommand { context: context.clone() };
|
||||
let command = ToAlternateScreenBufferCommand {
|
||||
context: context.clone(),
|
||||
};
|
||||
|
||||
state.register_change(Box::from(command), key);
|
||||
key
|
||||
@ -169,10 +152,8 @@ impl ToAlternateScreenBufferCommand
|
||||
}
|
||||
}
|
||||
|
||||
impl IStateCommand for ToAlternateScreenBufferCommand
|
||||
{
|
||||
fn execute(&mut self) -> bool
|
||||
{
|
||||
impl IStateCommand for ToAlternateScreenBufferCommand {
|
||||
fn execute(&mut self) -> bool {
|
||||
use super::super::super::manager::WinApiScreenManager;
|
||||
|
||||
let mut chi_buffer: [CHAR_INFO; 160] = unsafe { mem::zeroed() };
|
||||
@ -188,9 +169,12 @@ impl IStateCommand for ToAlternateScreenBufferCommand
|
||||
let mut screen_manager = self.context.screen_manager.lock().unwrap();
|
||||
screen_manager.toggle_is_alternate_screen(true);
|
||||
|
||||
let b: &mut WinApiScreenManager = match screen_manager.as_any().downcast_mut::<WinApiScreenManager>() {
|
||||
Some(b) => { b }
|
||||
None => panic!("")
|
||||
let b: &mut WinApiScreenManager = match screen_manager
|
||||
.as_any()
|
||||
.downcast_mut::<WinApiScreenManager>()
|
||||
{
|
||||
Some(b) => b,
|
||||
None => panic!(""),
|
||||
};
|
||||
|
||||
b.set_alternate_handle(new_handle);
|
||||
@ -198,8 +182,7 @@ impl IStateCommand for ToAlternateScreenBufferCommand
|
||||
true
|
||||
}
|
||||
|
||||
fn undo(&mut self) -> bool
|
||||
{
|
||||
fn undo(&mut self) -> bool {
|
||||
let handle = kernel::get_output_handle();
|
||||
kernel::set_active_screen_buffer(handle);
|
||||
|
||||
|
@ -1,19 +1,17 @@
|
||||
//! This module contains the code for the context of the terminal.
|
||||
|
||||
use { StateManager, ScreenManager };
|
||||
use {ScreenManager, StateManager};
|
||||
|
||||
use std::sync::Mutex;
|
||||
use std::rc::Rc;
|
||||
use std::sync::Mutex;
|
||||
|
||||
/// This type contains the context of the current terminal. The context surrounds the changed states of the terminal and can be used for managing the output of the terminal.
|
||||
pub struct Context
|
||||
{
|
||||
pub struct Context {
|
||||
pub screen_manager: Rc<Mutex<ScreenManager>>,
|
||||
pub state_manager: Mutex<StateManager>
|
||||
pub state_manager: Mutex<StateManager>,
|
||||
}
|
||||
|
||||
impl Context
|
||||
{
|
||||
impl Context {
|
||||
/// Create new Context instance so that you can provide it to other modules like terminal, cursor and color
|
||||
///
|
||||
/// This context type is just an wrapper that crossterm uses for managing the state the terminal.
|
||||
@ -36,21 +34,18 @@ impl Context
|
||||
/// let color = terminal::color(&context);
|
||||
///
|
||||
/// ```
|
||||
pub fn new() -> Rc<Context>
|
||||
{
|
||||
pub fn new() -> Rc<Context> {
|
||||
Rc::new(Context {
|
||||
screen_manager: Rc::new(Mutex::new(ScreenManager::new())),
|
||||
state_manager: Mutex::new(StateManager::new())
|
||||
state_manager: Mutex::new(StateManager::new()),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
use std::io::Write;
|
||||
|
||||
impl Drop for Context
|
||||
{
|
||||
fn drop(&mut self)
|
||||
{
|
||||
impl Drop for Context {
|
||||
fn drop(&mut self) {
|
||||
panic!();
|
||||
let mut changes = self.state_manager.lock().unwrap();
|
||||
changes.restore_changes();
|
||||
|
@ -3,7 +3,7 @@
|
||||
//! If `crossterm` changes some core state of the terminal like: enabling ANSI or enabling raw mode it should be reverted when the current process ends.
|
||||
//! It would be a little lame to let the terminal in raw mode after the the current process ends for the user of this library.
|
||||
|
||||
pub mod state_manager;
|
||||
pub mod commands;
|
||||
pub mod command_manager;
|
||||
pub mod commands;
|
||||
pub mod context;
|
||||
pub mod state_manager;
|
||||
|
@ -1,33 +1,28 @@
|
||||
//! This module is used for registering, storing an restoring the terminal state changes.
|
||||
|
||||
use super::commands::IStateCommand;
|
||||
use super::commands::shared_commands::EmptyCommand;
|
||||
use super::commands::IStateCommand;
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::rc::Rc;
|
||||
use std::sync::Mutex;
|
||||
use std::collections::HashMap;
|
||||
|
||||
/// Struct that stores the changed states of the terminal.
|
||||
pub struct StateManager
|
||||
{
|
||||
pub struct StateManager {
|
||||
changed_states: HashMap<u16, Rc<Mutex<Box<IStateCommand>>>>,
|
||||
}
|
||||
|
||||
impl StateManager
|
||||
{
|
||||
impl StateManager {
|
||||
/// Create new Context where the terminals states can be handled.
|
||||
pub fn new() -> StateManager
|
||||
{
|
||||
pub fn new() -> StateManager {
|
||||
StateManager {
|
||||
changed_states: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Restore all changes that are made to the terminal.
|
||||
pub fn restore_changes(&mut self)
|
||||
{
|
||||
for (id, item) in self.changed_states.iter_mut()
|
||||
{
|
||||
pub fn restore_changes(&mut self) {
|
||||
for (id, item) in self.changed_states.iter_mut() {
|
||||
let mut item = item.lock().unwrap();
|
||||
item.undo();
|
||||
|
||||
@ -36,27 +31,20 @@ impl StateManager
|
||||
}
|
||||
|
||||
/// Register new changed state with the given key.
|
||||
pub fn register_change(&mut self, change: Box<IStateCommand>, key: u16)
|
||||
{
|
||||
pub fn register_change(&mut self, change: Box<IStateCommand>, key: u16) {
|
||||
self.changed_states.insert(key, Rc::new(Mutex::new(change)));
|
||||
}
|
||||
|
||||
/// Get an state command from storage by id.
|
||||
pub fn get(&mut self, state_key: u16) -> Rc<Mutex<Box<IStateCommand>>>
|
||||
{
|
||||
if self.changed_states.contains_key(&state_key)
|
||||
{
|
||||
return self.changed_states[&state_key].clone()
|
||||
pub fn get(&mut self, state_key: u16) -> Rc<Mutex<Box<IStateCommand>>> {
|
||||
if self.changed_states.contains_key(&state_key) {
|
||||
return self.changed_states[&state_key].clone();
|
||||
}
|
||||
|
||||
return Rc::new(Mutex::new(Box::new(EmptyCommand)))
|
||||
return Rc::new(Mutex::new(Box::new(EmptyCommand)));
|
||||
}
|
||||
|
||||
pub fn get_changes_count(&self) -> u16
|
||||
{
|
||||
return self.changed_states.len() as u16
|
||||
pub fn get_changes_count(&self) -> u16 {
|
||||
return self.changed_states.len() as u16;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -1,9 +1,9 @@
|
||||
//! This is an ANSI specific implementation for styling related action.
|
||||
//! This module is used for windows 10 terminals and unix terminals by default.
|
||||
|
||||
use ScreenManager;
|
||||
use super::ITerminalColor;
|
||||
use super::super::{Color, ColorType};
|
||||
use super::ITerminalColor;
|
||||
use ScreenManager;
|
||||
|
||||
use std::rc::Rc;
|
||||
use std::sync::Mutex;
|
||||
@ -20,17 +20,22 @@ impl AnsiColor {
|
||||
|
||||
impl ITerminalColor for AnsiColor {
|
||||
fn set_fg(&self, fg_color: Color, screen_manager: Rc<Mutex<ScreenManager>>) {
|
||||
|
||||
let mut screen = screen_manager.lock().unwrap();
|
||||
{
|
||||
screen.write_ansi(format!(csi!("{}m"),self.color_value(fg_color, ColorType::Foreground)));
|
||||
screen.write_ansi(format!(
|
||||
csi!("{}m"),
|
||||
self.color_value(fg_color, ColorType::Foreground)
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
fn set_bg(&self, bg_color: Color, screen_manager: Rc<Mutex<ScreenManager>>) {
|
||||
let mut screen = screen_manager.lock().unwrap();
|
||||
{
|
||||
screen.write_ansi(format!(csi!("{}m"),self.color_value(bg_color, ColorType::Background)));
|
||||
screen.write_ansi(format!(
|
||||
csi!("{}m"),
|
||||
self.color_value(bg_color, ColorType::Background)
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@ -42,17 +47,11 @@ impl ITerminalColor for AnsiColor {
|
||||
}
|
||||
|
||||
fn color_value(&self, color: Color, color_type: ColorType) -> String {
|
||||
|
||||
let mut ansi_value = String::new();
|
||||
|
||||
match color_type
|
||||
{
|
||||
ColorType::Foreground => {
|
||||
ansi_value.push_str("38;")
|
||||
},
|
||||
ColorType::Background => {
|
||||
ansi_value.push_str("48;")
|
||||
},
|
||||
match color_type {
|
||||
ColorType::Foreground => ansi_value.push_str("38;"),
|
||||
ColorType::Background => ansi_value.push_str("48;"),
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
@ -61,7 +60,7 @@ impl ITerminalColor for AnsiColor {
|
||||
let color_val = match color {
|
||||
Color::Black => "5;0",
|
||||
Color::Red => "5;9",
|
||||
Color::DarkRed =>"5;1",
|
||||
Color::DarkRed => "5;1",
|
||||
Color::Green => "5;10",
|
||||
Color::DarkGreen => "5;2",
|
||||
Color::Yellow => "5;11",
|
||||
@ -75,9 +74,15 @@ impl ITerminalColor for AnsiColor {
|
||||
Color::Grey => "5;15",
|
||||
Color::White => "5;7",
|
||||
#[cfg(unix)]
|
||||
Color::Rgb{r,g,b} => { rgb_val = format!("2;{};{};{}", r,g,b); rgb_val.as_str()},
|
||||
Color::Rgb { r, g, b } => {
|
||||
rgb_val = format!("2;{};{};{}", r, g, b);
|
||||
rgb_val.as_str()
|
||||
}
|
||||
#[cfg(unix)]
|
||||
Color::AnsiValue(val) => { rgb_val = format!("5;{}",val); rgb_val.as_str() }
|
||||
Color::AnsiValue(val) => {
|
||||
rgb_val = format!("5;{}", val);
|
||||
rgb_val.as_str()
|
||||
}
|
||||
};
|
||||
|
||||
ansi_value.push_str(color_val);
|
||||
|
@ -1,30 +1,36 @@
|
||||
//! With this module you can perform actions that are color related.
|
||||
//! Like styling the font, foreground color and background.
|
||||
|
||||
use {ScreenManager, Context};
|
||||
use super::super::super::shared::functions;
|
||||
use super::*;
|
||||
use style::Color;
|
||||
use std::io;
|
||||
use std::rc::Rc;
|
||||
use std::sync::Mutex;
|
||||
use super::super::super::shared::functions;
|
||||
use style::Color;
|
||||
use {Context, ScreenManager};
|
||||
|
||||
/// Struct that stores an specific platform implementation for color related actions.
|
||||
pub struct TerminalColor {
|
||||
color: Option<Box<ITerminalColor>>,
|
||||
screen_manager: Rc<Mutex<ScreenManager>>
|
||||
screen_manager: Rc<Mutex<ScreenManager>>,
|
||||
}
|
||||
|
||||
impl TerminalColor {
|
||||
/// Create new instance whereon color related actions can be performed.
|
||||
pub fn new(context: Rc<Context>) -> TerminalColor {
|
||||
#[cfg(target_os = "windows")]
|
||||
let color = functions::get_module::<Box<ITerminalColor>>(WinApiColor::new(context.screen_manager.clone()), AnsiColor::new());
|
||||
let color = functions::get_module::<Box<ITerminalColor>>(
|
||||
WinApiColor::new(context.screen_manager.clone()),
|
||||
AnsiColor::new(),
|
||||
);
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
let color = Some(AnsiColor::new() as Box<ITerminalColor>);
|
||||
|
||||
TerminalColor { color: color, screen_manager: context.screen_manager.clone() }
|
||||
TerminalColor {
|
||||
color: color,
|
||||
screen_manager: context.screen_manager.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the foreground color to the given color.
|
||||
@ -106,8 +112,7 @@ impl TerminalColor {
|
||||
}
|
||||
|
||||
/// Get available color count.
|
||||
pub fn get_available_color_count(&self) -> io::Result<u16>
|
||||
{
|
||||
pub fn get_available_color_count(&self) -> io::Result<u16> {
|
||||
use std::env;
|
||||
|
||||
Ok(match env::var_os("TERM") {
|
||||
|
@ -1,15 +1,15 @@
|
||||
pub mod color;
|
||||
|
||||
mod ansi_color;
|
||||
#[cfg(target_os = "windows")]
|
||||
mod winapi_color;
|
||||
mod ansi_color;
|
||||
|
||||
use self::ansi_color::AnsiColor;
|
||||
#[cfg(target_os = "windows")]
|
||||
use self::winapi_color::WinApiColor;
|
||||
use self::ansi_color::AnsiColor;
|
||||
|
||||
use { ScreenManager };
|
||||
use super::{Color, ColorType};
|
||||
use ScreenManager;
|
||||
|
||||
use std::rc::Rc;
|
||||
use std::sync::Mutex;
|
||||
@ -28,7 +28,7 @@ pub trait ITerminalColor {
|
||||
/// Set the background color to the given color.
|
||||
fn set_bg(&self, fg_color: Color, screen_manager: Rc<Mutex<ScreenManager>>);
|
||||
/// Reset the terminal color to default.
|
||||
fn reset(&self,screen_manager: Rc<Mutex<ScreenManager>>);
|
||||
fn reset(&self, screen_manager: Rc<Mutex<ScreenManager>>);
|
||||
/// Gets an value that represents an color from the given `Color` and `ColorType`.
|
||||
fn color_value(&self, color: Color, color_type: ColorType) -> String;
|
||||
}
|
@ -1,29 +1,28 @@
|
||||
use super::super::{Color, ColorType};
|
||||
use super::ITerminalColor;
|
||||
use super::super::{ColorType, Color};
|
||||
use winapi::um::wincon;
|
||||
use kernel::windows_kernel::kernel;
|
||||
use winapi::um::wincon;
|
||||
use ScreenManager;
|
||||
|
||||
use std::sync::Mutex;
|
||||
use std::rc::Rc;
|
||||
use std::sync::Mutex;
|
||||
|
||||
/// This struct is an windows implementation for color related actions.
|
||||
pub struct WinApiColor {
|
||||
original_console_color: u16,
|
||||
screen_manager: Rc<Mutex<ScreenManager>>
|
||||
screen_manager: Rc<Mutex<ScreenManager>>,
|
||||
}
|
||||
|
||||
impl WinApiColor {
|
||||
pub fn new(screen_manager: Rc<Mutex<ScreenManager>>) -> Box<WinApiColor> {
|
||||
Box::from(WinApiColor {
|
||||
original_console_color: kernel::get_original_console_color(&screen_manager),
|
||||
screen_manager: screen_manager
|
||||
screen_manager: screen_manager,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl ITerminalColor for WinApiColor {
|
||||
|
||||
fn set_fg(&self, fg_color: Color, screen_manager: Rc<Mutex<ScreenManager>>) {
|
||||
let color_value = &self.color_value(fg_color, ColorType::Foreground);
|
||||
|
||||
@ -42,7 +41,7 @@ impl ITerminalColor for WinApiColor {
|
||||
color = color | wincon::BACKGROUND_INTENSITY as u16;
|
||||
}
|
||||
|
||||
kernel::set_console_text_attribute(color,&self.screen_manager);
|
||||
kernel::set_console_text_attribute(color, &self.screen_manager);
|
||||
}
|
||||
|
||||
fn set_bg(&self, bg_color: Color, screen_manager: Rc<Mutex<ScreenManager>>) {
|
||||
@ -62,16 +61,15 @@ impl ITerminalColor for WinApiColor {
|
||||
color = color | wincon::FOREGROUND_INTENSITY as u16;
|
||||
}
|
||||
|
||||
kernel::set_console_text_attribute(color,&self.screen_manager);
|
||||
kernel::set_console_text_attribute(color, &self.screen_manager);
|
||||
}
|
||||
|
||||
fn reset(&self, screen_manager: Rc<Mutex<ScreenManager>>) {
|
||||
kernel::set_console_text_attribute(self.original_console_color,&self.screen_manager);
|
||||
kernel::set_console_text_attribute(self.original_console_color, &self.screen_manager);
|
||||
}
|
||||
|
||||
/// This will get the winapi color value from the Color and ColorType struct
|
||||
fn color_value(&self, color: Color, color_type: ColorType) -> String {
|
||||
|
||||
use style::{Color, ColorType};
|
||||
|
||||
let winapi_color: u16;
|
||||
|
@ -4,7 +4,7 @@
|
||||
mod color;
|
||||
mod styles;
|
||||
|
||||
pub use self::color::color::{color, TerminalColor };
|
||||
pub use self::color::color::{color, TerminalColor};
|
||||
pub use self::styles::objectstyle::ObjectStyle;
|
||||
pub use self::styles::styledobject::StyledObject;
|
||||
|
||||
@ -21,7 +21,7 @@ pub enum Attribute {
|
||||
RapidBlink = 6,
|
||||
Reverse = 7,
|
||||
Hidden = 8,
|
||||
CrossedOut = 9
|
||||
CrossedOut = 9,
|
||||
}
|
||||
|
||||
/// Colors that are available for coloring the termainal font.
|
||||
@ -51,9 +51,13 @@ pub enum Color {
|
||||
White,
|
||||
|
||||
#[cfg(unix)]
|
||||
Rgb { r: u8, g: u8, b:u8 },
|
||||
Rgb {
|
||||
r: u8,
|
||||
g: u8,
|
||||
b: u8,
|
||||
},
|
||||
#[cfg(unix)]
|
||||
AnsiValue(u8)
|
||||
AnsiValue(u8),
|
||||
}
|
||||
|
||||
/// Color types that can be used to determine if the Color enum is an Fore- or Background Color
|
||||
|
@ -1,7 +1,7 @@
|
||||
//! This module contains the `object style` that can be applied to an `styled object`.
|
||||
|
||||
use Context;
|
||||
use style::{Color, StyledObject};
|
||||
use Context;
|
||||
|
||||
use std::fmt::Display;
|
||||
use std::rc::Rc;
|
||||
@ -16,7 +16,7 @@ pub struct ObjectStyle {
|
||||
pub bg_color: Option<Color>,
|
||||
|
||||
#[cfg(unix)]
|
||||
pub attrs: Vec<Attribute>
|
||||
pub attrs: Vec<Attribute>,
|
||||
}
|
||||
|
||||
impl Default for ObjectStyle {
|
||||
@ -25,7 +25,7 @@ impl Default for ObjectStyle {
|
||||
fg_color: Some(Color::White),
|
||||
bg_color: Some(Color::Black),
|
||||
#[cfg(unix)]
|
||||
attrs: Vec::new()
|
||||
attrs: Vec::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -49,7 +49,7 @@ impl ObjectStyle {
|
||||
fg_color: None,
|
||||
bg_color: None,
|
||||
#[cfg(unix)]
|
||||
attrs: Vec::new()
|
||||
attrs: Vec::new(),
|
||||
};
|
||||
}
|
||||
|
||||
@ -66,8 +66,7 @@ impl ObjectStyle {
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
pub fn add_attr(&mut self, attr: Attribute)
|
||||
{
|
||||
pub fn add_attr(&mut self, attr: Attribute) {
|
||||
self.attrs.push(attr);
|
||||
}
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ use style::{Color, ObjectStyle};
|
||||
pub struct StyledObject<D> {
|
||||
pub object_style: ObjectStyle,
|
||||
pub content: D,
|
||||
pub context: Rc<Context>
|
||||
pub context: Rc<Context>,
|
||||
}
|
||||
|
||||
impl<D> StyledObject<D> {
|
||||
@ -82,51 +82,82 @@ impl<D> StyledObject<D> {
|
||||
///
|
||||
/// ```
|
||||
#[cfg(unix)]
|
||||
pub fn attr(mut self, attr: Attribute) -> StyledObject<D>
|
||||
{
|
||||
pub fn attr(mut self, attr: Attribute) -> StyledObject<D> {
|
||||
&self.object_style.add_attr(attr);
|
||||
self
|
||||
}
|
||||
|
||||
/// Increase the font intensity.
|
||||
#[cfg(unix)]#[inline(always)] pub fn bold(self) -> StyledObject<D> { self.attr(Attribute::Bold) }
|
||||
#[cfg(unix)]
|
||||
#[inline(always)]
|
||||
pub fn bold(self) -> StyledObject<D> {
|
||||
self.attr(Attribute::Bold)
|
||||
}
|
||||
/// Faint (decreased intensity) (Not widely supported).
|
||||
#[cfg(unix)]#[inline(always)] pub fn dim(self) -> StyledObject<D> { self.attr(Attribute::Dim) }
|
||||
#[cfg(unix)]
|
||||
#[inline(always)]
|
||||
pub fn dim(self) -> StyledObject<D> {
|
||||
self.attr(Attribute::Dim)
|
||||
}
|
||||
/// Make the font italic (Not widely supported; Sometimes treated as inverse).
|
||||
#[cfg(unix)]#[inline(always)] pub fn italic(self) -> StyledObject<D> { self.attr(Attribute::Italic) }
|
||||
#[cfg(unix)]
|
||||
#[inline(always)]
|
||||
pub fn italic(self) -> StyledObject<D> {
|
||||
self.attr(Attribute::Italic)
|
||||
}
|
||||
/// Underline font.
|
||||
#[cfg(unix)]#[inline(always)] pub fn underlined(self) -> StyledObject<D> { self.attr(Attribute::Underlined) }
|
||||
#[cfg(unix)]
|
||||
#[inline(always)]
|
||||
pub fn underlined(self) -> StyledObject<D> {
|
||||
self.attr(Attribute::Underlined)
|
||||
}
|
||||
/// Slow Blink (less than 150 per minute; not widely supported).
|
||||
#[cfg(unix)]#[inline(always)] pub fn slow_blink(self) -> StyledObject<D> { self.attr(Attribute::SlowBlink) }
|
||||
#[cfg(unix)]
|
||||
#[inline(always)]
|
||||
pub fn slow_blink(self) -> StyledObject<D> {
|
||||
self.attr(Attribute::SlowBlink)
|
||||
}
|
||||
/// Rapid Blink (MS-DOS ANSI.SYS; 150+ per minute; not widely supported).
|
||||
#[cfg(unix)]#[inline(always)] pub fn rapid_blink(self) -> StyledObject<D> { self.attr(Attribute::RapidBlink) }
|
||||
#[cfg(unix)]
|
||||
#[inline(always)]
|
||||
pub fn rapid_blink(self) -> StyledObject<D> {
|
||||
self.attr(Attribute::RapidBlink)
|
||||
}
|
||||
/// Swap foreground and background colors.
|
||||
#[cfg(unix)]#[inline(always)] pub fn reverse(self) -> StyledObject<D> { self.attr(Attribute::Reverse) }
|
||||
#[cfg(unix)]
|
||||
#[inline(always)]
|
||||
pub fn reverse(self) -> StyledObject<D> {
|
||||
self.attr(Attribute::Reverse)
|
||||
}
|
||||
/// Hide text (Not widely supported).
|
||||
#[cfg(unix)]#[inline(always)] pub fn hidden(self) -> StyledObject<D> { self.attr(Attribute::Hidden) }
|
||||
#[cfg(unix)]
|
||||
#[inline(always)]
|
||||
pub fn hidden(self) -> StyledObject<D> {
|
||||
self.attr(Attribute::Hidden)
|
||||
}
|
||||
/// Characters legible, but marked for deletion. Not widely supported.
|
||||
#[cfg(unix)]#[inline(always)] pub fn crossed_out(self) -> StyledObject<D> { self.attr(Attribute::CrossedOut) }
|
||||
#[cfg(unix)]
|
||||
#[inline(always)]
|
||||
pub fn crossed_out(self) -> StyledObject<D> {
|
||||
self.attr(Attribute::CrossedOut)
|
||||
}
|
||||
}
|
||||
|
||||
/// This is used to make StyledObject able to be displayed.
|
||||
/// This macro will set the styles stored in Styled Object
|
||||
macro_rules! impl_fmt
|
||||
{
|
||||
macro_rules! impl_fmt {
|
||||
($name:ident) => {
|
||||
impl<D: fmt::$name> fmt::$name for StyledObject<D> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result
|
||||
{
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let mut colored_terminal = super::super::color(self.context.clone());
|
||||
let mut reset = true;
|
||||
|
||||
if let Some(bg) = self.object_style.bg_color
|
||||
{
|
||||
if let Some(bg) = self.object_style.bg_color {
|
||||
colored_terminal.set_bg(bg);
|
||||
reset = true;
|
||||
}
|
||||
|
||||
if let Some(fg) = self.object_style.fg_color
|
||||
{
|
||||
if let Some(fg) = self.object_style.fg_color {
|
||||
colored_terminal.set_fg(fg);
|
||||
reset = true;
|
||||
}
|
||||
@ -149,15 +180,14 @@ macro_rules! impl_fmt
|
||||
screen.flush();
|
||||
}
|
||||
|
||||
if reset
|
||||
{
|
||||
if reset {
|
||||
colored_terminal.reset();
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl_fmt!(Debug);
|
||||
|
@ -1,43 +1,41 @@
|
||||
//! This is an `ANSI escape code` specific implementation for terminal related action.
|
||||
//! This module is used for windows 10 terminals and unix terminals by default.
|
||||
|
||||
use Context;
|
||||
use shared::functions;
|
||||
use super::{ClearType, ITerminal, Rc};
|
||||
use shared::functions;
|
||||
use Context;
|
||||
|
||||
/// This struct is an ansi implementation for terminal related actions.
|
||||
pub struct AnsiTerminal
|
||||
{
|
||||
context: Rc<Context>
|
||||
pub struct AnsiTerminal {
|
||||
context: Rc<Context>,
|
||||
}
|
||||
|
||||
impl AnsiTerminal {
|
||||
pub fn new(context: Rc<Context>) -> Box<AnsiTerminal> {
|
||||
Box::from(AnsiTerminal {context: context})
|
||||
Box::from(AnsiTerminal { context: context })
|
||||
}
|
||||
}
|
||||
|
||||
impl ITerminal for AnsiTerminal {
|
||||
fn clear(&self, clear_type: ClearType)
|
||||
{
|
||||
fn clear(&self, clear_type: ClearType) {
|
||||
let mut screen_manager = self.context.screen_manager.lock().unwrap();
|
||||
{
|
||||
match clear_type {
|
||||
ClearType::All => {
|
||||
screen_manager.write_ansi_str(csi!("2J"));
|
||||
},
|
||||
}
|
||||
ClearType::FromCursorDown => {
|
||||
screen_manager.write_ansi_str(csi!("J"));
|
||||
},
|
||||
}
|
||||
ClearType::FromCursorUp => {
|
||||
screen_manager.write_ansi_str(csi!("1J"));
|
||||
},
|
||||
}
|
||||
ClearType::CurrentLine => {
|
||||
screen_manager.write_ansi_str(csi!("2K"));
|
||||
},
|
||||
}
|
||||
ClearType::UntilNewLine => {
|
||||
screen_manager.write_ansi_str(csi!("K"));
|
||||
},
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -67,8 +65,7 @@ impl ITerminal for AnsiTerminal {
|
||||
}
|
||||
}
|
||||
|
||||
fn exit(&self)
|
||||
{
|
||||
fn exit(&self) {
|
||||
functions::exit_terminal();
|
||||
}
|
||||
}
|
||||
|
@ -8,17 +8,17 @@
|
||||
|
||||
pub mod terminal;
|
||||
|
||||
mod ansi_terminal;
|
||||
#[cfg(target_os = "windows")]
|
||||
mod winapi_terminal;
|
||||
mod ansi_terminal;
|
||||
|
||||
use self::ansi_terminal::AnsiTerminal;
|
||||
#[cfg(target_os = "windows")]
|
||||
use self::winapi_terminal::WinApiTerminal;
|
||||
use self::ansi_terminal::AnsiTerminal;
|
||||
use std::rc::Rc;
|
||||
|
||||
pub use self::terminal::terminal;
|
||||
use Context;
|
||||
pub use self::terminal::{ terminal};
|
||||
|
||||
/// Enum that can be used for the kind of clearing that can be done in the terminal.
|
||||
pub enum ClearType {
|
||||
@ -47,7 +47,7 @@ pub trait ITerminal {
|
||||
/// Scroll `n` lines down in the current terminal.
|
||||
fn scroll_down(&self, count: i16);
|
||||
/// Resize terminal to the given width and height.
|
||||
fn set_size(&self,width: i16, height: i16);
|
||||
fn set_size(&self, width: i16, height: i16);
|
||||
/// Close the current terminal
|
||||
fn exit(&self);
|
||||
}
|
||||
|
@ -1,32 +1,37 @@
|
||||
//! With this module you can perform actions that are terminal related.
|
||||
//! Like clearing and scrolling in the terminal or getting the size of the terminal.
|
||||
|
||||
use super::super::shared::functions;
|
||||
use super::super::style;
|
||||
use super::*;
|
||||
use Context;
|
||||
use super::super::style;
|
||||
use super::super::shared::functions;
|
||||
|
||||
use std::fmt::Write;
|
||||
use std::fmt;
|
||||
use std::fmt::Write;
|
||||
use std::rc::Rc;
|
||||
|
||||
/// Struct that stores an specific platform implementation for terminal related actions.
|
||||
pub struct Terminal {
|
||||
terminal: Option<Box<ITerminal>>,
|
||||
context: Rc<Context>
|
||||
context: Rc<Context>,
|
||||
}
|
||||
|
||||
impl Terminal {
|
||||
/// Create new terminal instance whereon terminal related actions can be performed.
|
||||
pub fn new(context: Rc<Context>) -> Terminal {
|
||||
#[cfg(target_os = "windows")]
|
||||
let terminal = functions::get_module::<Box<ITerminal>>(WinApiTerminal::new(context.clone()), AnsiTerminal::new(context.clone()));
|
||||
let terminal = functions::get_module::<Box<ITerminal>>(
|
||||
WinApiTerminal::new(context.clone()),
|
||||
AnsiTerminal::new(context.clone()),
|
||||
);
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
let terminal = Some(AnsiTerminal::new(context.clone()) as Box<ITerminal>);
|
||||
|
||||
Terminal { terminal, context: context }
|
||||
|
||||
Terminal {
|
||||
terminal,
|
||||
context: context,
|
||||
}
|
||||
}
|
||||
|
||||
/// Clear the current cursor by specifying the clear type
|
||||
@ -79,9 +84,9 @@ impl Terminal {
|
||||
/// ```
|
||||
pub fn terminal_size(&mut self) -> (u16, u16) {
|
||||
if let Some(ref terminal) = self.terminal {
|
||||
return terminal.terminal_size()
|
||||
return terminal.terminal_size();
|
||||
}
|
||||
(0,0)
|
||||
(0, 0)
|
||||
}
|
||||
|
||||
/// Scroll `n` lines up in the current terminal.
|
||||
@ -147,10 +152,9 @@ impl Terminal {
|
||||
/// let size = term.set_size(10,10);
|
||||
///
|
||||
/// ```
|
||||
pub fn set_size(&mut self, width: i16, height: i16)
|
||||
{
|
||||
if let Some (ref terminal) = self.terminal {
|
||||
terminal.set_size(width,height);
|
||||
pub fn set_size(&mut self, width: i16, height: i16) {
|
||||
if let Some(ref terminal) = self.terminal {
|
||||
terminal.set_size(width, height);
|
||||
}
|
||||
}
|
||||
|
||||
@ -188,15 +192,13 @@ impl Terminal {
|
||||
style::ObjectStyle::new().apply_to(val, self.context.clone())
|
||||
}
|
||||
|
||||
pub fn exit(&self)
|
||||
{
|
||||
if let Some (ref terminal) = self.terminal {
|
||||
pub fn exit(&self) {
|
||||
if let Some(ref terminal) = self.terminal {
|
||||
terminal.exit();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn write<D: fmt::Display>(&mut self, value: D)
|
||||
{
|
||||
pub fn write<D: fmt::Display>(&mut self, value: D) {
|
||||
let mut mutex = &self.context.screen_manager;
|
||||
{
|
||||
let mut screen_manager = mutex.lock().unwrap();
|
||||
|
@ -1,20 +1,19 @@
|
||||
//! This is an `WINAPI` specific implementation for terminal related action.
|
||||
//! This module is used for non supporting `ANSI` windows terminals.
|
||||
|
||||
use Context;
|
||||
use cursor::cursor;
|
||||
use super::{ClearType, ITerminal, Rc};
|
||||
use winapi::um::wincon::{SMALL_RECT, COORD, CONSOLE_SCREEN_BUFFER_INFO,};
|
||||
use kernel::windows_kernel::{kernel, terminal};
|
||||
use super::super::shared::functions;
|
||||
use super::super::ScreenManager;
|
||||
use super::{ClearType, ITerminal, Rc};
|
||||
use cursor::cursor;
|
||||
use kernel::windows_kernel::{kernel, terminal};
|
||||
use winapi::um::wincon::{CONSOLE_SCREEN_BUFFER_INFO, COORD, SMALL_RECT};
|
||||
use Context;
|
||||
|
||||
use std::sync::Mutex;
|
||||
|
||||
/// This struct is an windows implementation for terminal related actions.
|
||||
pub struct WinApiTerminal
|
||||
{
|
||||
context: Rc<Context>
|
||||
pub struct WinApiTerminal {
|
||||
context: Rc<Context>,
|
||||
}
|
||||
|
||||
impl WinApiTerminal {
|
||||
@ -24,15 +23,13 @@ impl WinApiTerminal {
|
||||
}
|
||||
|
||||
impl ITerminal for WinApiTerminal {
|
||||
|
||||
fn clear(&self, clear_type: ClearType) {
|
||||
let csbi = kernel::get_console_screen_buffer_info(&self.context.screen_manager);
|
||||
let pos = cursor(self.context.clone()).pos();
|
||||
|
||||
match clear_type
|
||||
{
|
||||
match clear_type {
|
||||
ClearType::All => clear_entire_screen(csbi, &self.context),
|
||||
ClearType::FromCursorDown => clear_after_cursor(pos,csbi, &self.context),
|
||||
ClearType::FromCursorDown => clear_after_cursor(pos, csbi, &self.context),
|
||||
ClearType::FromCursorUp => clear_before_cursor(pos, csbi, &self.context),
|
||||
ClearType::CurrentLine => clear_current_line(pos, csbi, &self.context),
|
||||
ClearType::UntilNewLine => clear_until_line(pos, csbi, &self.context),
|
||||
@ -59,7 +56,8 @@ impl ITerminal for WinApiTerminal {
|
||||
srct_window.Top += count; // move top down
|
||||
srct_window.Bottom += count; // move bottom down
|
||||
|
||||
let success = kernel::set_console_info(true, &mut srct_window, &self.context.screen_manager);
|
||||
let success =
|
||||
kernel::set_console_info(true, &mut srct_window, &self.context.screen_manager);
|
||||
if success {
|
||||
panic!("Something went wrong when scrolling down");
|
||||
}
|
||||
@ -68,13 +66,11 @@ impl ITerminal for WinApiTerminal {
|
||||
|
||||
/// Set the current terminal size
|
||||
fn set_size(&self, width: i16, height: i16) {
|
||||
if width <= 0
|
||||
{
|
||||
if width <= 0 {
|
||||
panic!("Cannot set the terminal width lower than 1");
|
||||
}
|
||||
|
||||
if height <= 0
|
||||
{
|
||||
if height <= 0 {
|
||||
panic!("Cannot set the terminal height lower then 1")
|
||||
}
|
||||
|
||||
@ -85,12 +81,13 @@ impl ITerminal for WinApiTerminal {
|
||||
// If the buffer is smaller than this new window size, resize the
|
||||
// buffer to be large enough. Include window position.
|
||||
let mut resize_buffer = false;
|
||||
let mut size = COORD { X: csbi.dwSize.X, Y: csbi.dwSize.Y };
|
||||
let mut size = COORD {
|
||||
X: csbi.dwSize.X,
|
||||
Y: csbi.dwSize.Y,
|
||||
};
|
||||
|
||||
if csbi.dwSize.X < csbi.srWindow.Left + width
|
||||
{
|
||||
if csbi.srWindow.Left >= i16::max_value() - width
|
||||
{
|
||||
if csbi.dwSize.X < csbi.srWindow.Left + width {
|
||||
if csbi.srWindow.Left >= i16::max_value() - width {
|
||||
panic!("Argument out of range when setting terminal width.");
|
||||
}
|
||||
|
||||
@ -98,8 +95,7 @@ impl ITerminal for WinApiTerminal {
|
||||
resize_buffer = true;
|
||||
}
|
||||
if csbi.dwSize.Y < csbi.srWindow.Top + height {
|
||||
if csbi.srWindow.Top >= i16::max_value() - height
|
||||
{
|
||||
if csbi.srWindow.Top >= i16::max_value() - height {
|
||||
panic!("Argument out of range when setting terminal height");
|
||||
}
|
||||
|
||||
@ -110,8 +106,7 @@ impl ITerminal for WinApiTerminal {
|
||||
if resize_buffer {
|
||||
success = kernel::set_console_screen_buffer_size(size, &self.context.screen_manager);
|
||||
|
||||
if !success
|
||||
{
|
||||
if !success {
|
||||
panic!("Something went wrong when setting screen buffer size.");
|
||||
}
|
||||
}
|
||||
@ -131,43 +126,56 @@ impl ITerminal for WinApiTerminal {
|
||||
|
||||
let bounds = kernel::get_largest_console_window_size();
|
||||
|
||||
if width > bounds.X
|
||||
{
|
||||
panic!("Argument width: {} out of range when setting terminal width.", width);
|
||||
if width > bounds.X {
|
||||
panic!(
|
||||
"Argument width: {} out of range when setting terminal width.",
|
||||
width
|
||||
);
|
||||
}
|
||||
if height > bounds.Y
|
||||
{
|
||||
panic!("Argument height: {} out of range when setting terminal height", height);
|
||||
if height > bounds.Y {
|
||||
panic!(
|
||||
"Argument height: {} out of range when setting terminal height",
|
||||
height
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn exit(&self)
|
||||
{
|
||||
fn exit(&self) {
|
||||
functions::exit_terminal();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn clear_after_cursor(pos: (u16,u16), csbi: CONSOLE_SCREEN_BUFFER_INFO, context: &Rc<Context>) {
|
||||
let (mut x,mut y) = pos;
|
||||
pub fn clear_after_cursor(
|
||||
pos: (u16, u16),
|
||||
csbi: CONSOLE_SCREEN_BUFFER_INFO,
|
||||
context: &Rc<Context>,
|
||||
) {
|
||||
let (mut x, mut y) = pos;
|
||||
|
||||
// if cursor position is at the outer right position
|
||||
if x as i16 > csbi.dwSize.X
|
||||
{
|
||||
if x as i16 > csbi.dwSize.X {
|
||||
y += 1;
|
||||
x = 0;
|
||||
}
|
||||
|
||||
// location where to start clearing
|
||||
let start_location = COORD { X: x as i16, Y: y as i16};
|
||||
let start_location = COORD {
|
||||
X: x as i16,
|
||||
Y: y as i16,
|
||||
};
|
||||
// get sum cells before cursor
|
||||
let cells_to_write = csbi.dwSize.X as u32 * csbi.dwSize.Y as u32;
|
||||
|
||||
clear(start_location,cells_to_write, &context.screen_manager);
|
||||
clear(start_location, cells_to_write, &context.screen_manager);
|
||||
}
|
||||
|
||||
pub fn clear_before_cursor(pos: (u16,u16), csbi: CONSOLE_SCREEN_BUFFER_INFO, context: &Rc<Context>) {
|
||||
let (xpos,ypos) = pos;
|
||||
pub fn clear_before_cursor(
|
||||
pos: (u16, u16),
|
||||
csbi: CONSOLE_SCREEN_BUFFER_INFO,
|
||||
context: &Rc<Context>,
|
||||
) {
|
||||
let (xpos, ypos) = pos;
|
||||
|
||||
// one cell after cursor position
|
||||
let x = 0;
|
||||
@ -175,7 +183,10 @@ pub fn clear_before_cursor(pos: (u16,u16), csbi: CONSOLE_SCREEN_BUFFER_INFO, con
|
||||
let y = 0;
|
||||
|
||||
// location where to start clearing
|
||||
let start_location = COORD { X: x as i16, Y: y as i16};
|
||||
let start_location = COORD {
|
||||
X: x as i16,
|
||||
Y: y as i16,
|
||||
};
|
||||
// get sum cells before cursor
|
||||
let cells_to_write = (csbi.dwSize.X as u32 * ypos as u32) + (xpos as u32 + 1);
|
||||
|
||||
@ -189,26 +200,35 @@ pub fn clear_entire_screen(csbi: CONSOLE_SCREEN_BUFFER_INFO, context: &Rc<Contex
|
||||
let y = 0;
|
||||
|
||||
// location where to start clearing
|
||||
let start_location = COORD { X: x as i16, Y: y as i16};
|
||||
let start_location = COORD {
|
||||
X: x as i16,
|
||||
Y: y as i16,
|
||||
};
|
||||
// get sum cells before cursor
|
||||
|
||||
let cells_to_write = csbi.dwSize.X as u32 * csbi.dwSize.Y as u32;
|
||||
|
||||
clear( start_location, cells_to_write, &context.screen_manager);
|
||||
clear(start_location, cells_to_write, &context.screen_manager);
|
||||
|
||||
// put the cursor back at (0, 0)
|
||||
cursor(context.clone()).goto(0, 0);
|
||||
}
|
||||
|
||||
pub fn clear_current_line(pos: (u16,u16), csbi: CONSOLE_SCREEN_BUFFER_INFO, context: &Rc<Context>)
|
||||
{
|
||||
pub fn clear_current_line(
|
||||
pos: (u16, u16),
|
||||
csbi: CONSOLE_SCREEN_BUFFER_INFO,
|
||||
context: &Rc<Context>,
|
||||
) {
|
||||
// position x at start
|
||||
let x = 0;
|
||||
// position y at start
|
||||
let y = pos.1;
|
||||
|
||||
// location where to start clearing
|
||||
let start_location = COORD { X: x as i16, Y: y as i16};
|
||||
let start_location = COORD {
|
||||
X: x as i16,
|
||||
Y: y as i16,
|
||||
};
|
||||
// get sum cells before cursor
|
||||
|
||||
let cells_to_write = csbi.dwSize.X as u32;
|
||||
@ -219,39 +239,46 @@ pub fn clear_current_line(pos: (u16,u16), csbi: CONSOLE_SCREEN_BUFFER_INFO, cont
|
||||
cursor(context.clone()).goto(0, y);
|
||||
}
|
||||
|
||||
pub fn clear_until_line(pos: (u16,u16), csbi: CONSOLE_SCREEN_BUFFER_INFO, context: &Rc<Context>)
|
||||
{
|
||||
let (x,y) = pos;
|
||||
pub fn clear_until_line(pos: (u16, u16), csbi: CONSOLE_SCREEN_BUFFER_INFO, context: &Rc<Context>) {
|
||||
let (x, y) = pos;
|
||||
|
||||
// location where to start clearing
|
||||
let start_location = COORD { X: x as i16, Y: y as i16};
|
||||
let start_location = COORD {
|
||||
X: x as i16,
|
||||
Y: y as i16,
|
||||
};
|
||||
// get sum cells before cursor
|
||||
let cells_to_write = (csbi.dwSize.X - x as i16) as u32;
|
||||
|
||||
clear(start_location, cells_to_write, &context.screen_manager);
|
||||
|
||||
// put the cursor back at original cursor position
|
||||
cursor(context.clone()).goto(x,y);
|
||||
cursor(context.clone()).goto(x, y);
|
||||
}
|
||||
|
||||
fn clear(
|
||||
start_loaction: COORD,
|
||||
cells_to_write: u32,
|
||||
screen_manager: &Rc<Mutex<ScreenManager>>
|
||||
) {
|
||||
fn clear(start_loaction: COORD, cells_to_write: u32, screen_manager: &Rc<Mutex<ScreenManager>>) {
|
||||
let mut cells_written = 0;
|
||||
let mut success = false;
|
||||
|
||||
success = kernel::fill_console_output_character(&mut cells_written, start_loaction, cells_to_write, screen_manager);
|
||||
success = kernel::fill_console_output_character(
|
||||
&mut cells_written,
|
||||
start_loaction,
|
||||
cells_to_write,
|
||||
screen_manager,
|
||||
);
|
||||
|
||||
if !success
|
||||
{
|
||||
if !success {
|
||||
panic!("Could not clear screen after cursor");
|
||||
}
|
||||
|
||||
cells_written = 0;
|
||||
|
||||
success = kernel::fill_console_output_attribute(&mut cells_written, start_loaction, cells_to_write, screen_manager);
|
||||
success = kernel::fill_console_output_attribute(
|
||||
&mut cells_written,
|
||||
start_loaction,
|
||||
cells_to_write,
|
||||
screen_manager,
|
||||
);
|
||||
|
||||
if !success {
|
||||
panic!("Couldnot reset attributes after cursor");
|
||||
|
Loading…
Reference in New Issue
Block a user