Fix build.
[reactos.git] / base / applications / network / telnet / src / tmouse.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 //Telnet Win32 : an ANSI telnet client.
3 //Copyright (C) 1998 Paul Brannan
4 //Copyright (C) 1998 I.Ioannou
5 //Copyright (C) 1997 Brad Johnson
6 //
7 //This program is free software; you can redistribute it and/or
8 //modify it under the terms of the GNU General Public License
9 //as published by the Free Software Foundation; either version 2
10 //of the License, or (at your option) any later version.
11 //
12 //This program is distributed in the hope that it will be useful,
13 //but WITHOUT ANY WARRANTY; without even the implied warranty of
14 //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 //GNU General Public License for more details.
16 //
17 //You should have received a copy of the GNU General Public License
18 //along with this program; if not, write to the Free Software
19 //Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 //
21 //I.Ioannou
22 //roryt@hol.gr
23 //
24 ///////////////////////////////////////////////////////////////////////////
25
26 // TMouse.cpp
27 // A simple class for handling mouse events
28 // Written by Paul Brannan <pbranna@clemson.edu>
29 // Last modified August 30, 1998
30
31 #include "tmouse.h"
32 #include "tconsole.h"
33
34 TMouse::TMouse(Tnclip &RefClipboard): Clipboard(RefClipboard) {
35 hConsole = GetStdHandle(STD_INPUT_HANDLE);
36 hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
37 }
38
39 TMouse::~TMouse() {
40 }
41
42 void TMouse::get_coords(COORD *start_coords, COORD *end_coords,
43 COORD *first_coords, COORD *last_coords) {
44 if(end_coords->Y < start_coords->Y ||
45 (end_coords->Y == start_coords->Y && end_coords->X < start_coords->X))
46 {
47 *first_coords = *end_coords;
48 *last_coords = *start_coords;
49 } else {
50 *first_coords = *start_coords;
51 *last_coords = *end_coords;
52 }
53 last_coords->X++;
54 }
55
56 void TMouse::doMouse_init() {
57 GetConsoleScreenBufferInfo(hStdout, &ConsoleInfo);
58 chiBuffer = newBuffer();
59 saveScreen(chiBuffer);
60 }
61
62 void TMouse::doMouse_cleanup() {
63 restoreScreen(chiBuffer);
64 delete[] chiBuffer;
65 }
66
67 void TMouse::move_mouse(COORD start_coords, COORD end_coords) {
68 COORD screen_start = {0, 0};
69 COORD first_coords, last_coords;
70 DWORD Result;
71
72 FillConsoleOutputAttribute(hStdout, normal,
73 ConsoleInfo.dwSize.X * ConsoleInfo.dwSize.Y, screen_start, &Result);
74
75 get_coords(&start_coords, &end_coords, &first_coords, &last_coords);
76 FillConsoleOutputAttribute(hStdout, inverse, ConsoleInfo.dwSize.X *
77 (last_coords.Y - first_coords.Y) + (last_coords.X - first_coords.X),
78 first_coords, &Result);
79 }
80
81 void TMouse::doClip(COORD start_coords, COORD end_coords) {
82 // COORD screen_start = {0, 0};
83 COORD first_coords, last_coords;
84 DWORD Result;
85
86 get_coords(&start_coords, &end_coords, &first_coords, &last_coords);
87
88 // Allocate the minimal size buffer
89 int data_size = 3 + ConsoleInfo.dwSize.X *
90 (last_coords.Y - first_coords.Y) + (last_coords.X - first_coords.X);
91 HGLOBAL clipboard_data = GlobalAlloc(GMEM_MOVEABLE + GMEM_DDESHARE,
92 data_size);
93 LPVOID mem_ptr = GlobalLock(clipboard_data);
94
95 // Reset data_size so we can count the actual data size
96 data_size = 0;
97
98 // Read the console, put carriage returns at the end of each line if
99 // reading more than one line (Paul Brannan 9/17/98)
100 for(int j = first_coords.Y; j <= last_coords.Y; j++) {
101
102 // Read line at (0,j)
103 COORD coords;
104 coords.X = 0;
105 coords.Y = j;
106 int length = ConsoleInfo.dwSize.X;
107
108 if(j == first_coords.Y) {
109 coords.X = first_coords.X;
110 length = ConsoleInfo.dwSize.X - first_coords.X;
111 } else {
112 // Add a carriage return to the end of the previous line
113 *((char *)mem_ptr + data_size++) = '\r';
114 *((char *)mem_ptr + data_size++) = '\n';
115 }
116
117 if(j == last_coords.Y) {
118 length -= (ConsoleInfo.dwSize.X - last_coords.X);
119 }
120
121 // Read the next line
122 ReadConsoleOutputCharacter(hStdout, (LPTSTR)((char *)mem_ptr +
123 data_size), length, coords, &Result);
124 data_size += Result;
125
126 // Strip the spaces at the end of the line
127 if((j != last_coords.Y) && (first_coords.Y != last_coords.Y))
128 while(*((char *)mem_ptr + data_size - 1) == ' ') data_size--;
129 }
130 if(first_coords.Y != last_coords.Y) {
131 // Add a carriage return to the end of the last line
132 *((char *)mem_ptr + data_size++) = '\r';
133 *((char *)mem_ptr + data_size++) = '\n';
134 }
135
136 *((char *)mem_ptr + data_size) = 0;
137 GlobalUnlock(clipboard_data);
138
139 Clipboard.Copy(clipboard_data);
140 }
141
142 void TMouse::doMouse() {
143 INPUT_RECORD InputRecord;
144 DWORD Result;
145 InputRecord.EventType = KEY_EVENT; // just in case
146 while(InputRecord.EventType != MOUSE_EVENT) {
147 if (!ReadConsoleInput(hConsole, &InputRecord, 1, &Result))
148 return; // uh oh! we don't know the starting coordinates!
149 }
150 if(InputRecord.Event.MouseEvent.dwButtonState == 0) return;
151 if(!(InputRecord.Event.MouseEvent.dwButtonState &
152 FROM_LEFT_1ST_BUTTON_PRESSED)) {
153 Clipboard.Paste();
154 return;
155 }
156
157 COORD screen_start = {0, 0};
158 COORD start_coords = InputRecord.Event.MouseEvent.dwMousePosition;
159 COORD end_coords = start_coords;
160 BOOL done = FALSE;
161
162 // init vars
163 doMouse_init();
164 int normal_bg = ini.get_normal_bg();
165 int normal_fg = ini.get_normal_fg();
166 if(normal_bg == -1) normal_bg = 0; // FIX ME!! This is just a hack
167 if(normal_fg == -1) normal_fg = 7;
168 normal = (normal_bg << 4) | normal_fg;
169 inverse = (normal_fg << 4) | normal_bg;
170
171 // make screen all one attribute
172 FillConsoleOutputAttribute(hStdout, normal, ConsoleInfo.dwSize.X *
173 ConsoleInfo.dwSize.Y, screen_start, &Result);
174
175 while(!done) {
176
177 switch (InputRecord.EventType) {
178 case MOUSE_EVENT:
179 switch(InputRecord.Event.MouseEvent.dwEventFlags) {
180 case 0: // only copy if the mouse button has been released
181 if(!InputRecord.Event.MouseEvent.dwButtonState) {
182 doClip(start_coords, end_coords);
183 done = TRUE;
184 }
185 break;
186
187 case MOUSE_MOVED:
188 end_coords = InputRecord.Event.MouseEvent.dwMousePosition;
189 move_mouse(start_coords, end_coords);
190 break;
191 }
192 break;
193 // If we are changing focus, we don't want to highlight anything
194 // (Paul Brannan 9/2/98)
195 case FOCUS_EVENT:
196 return;
197 }
198
199 WaitForSingleObject(hConsole, INFINITE);
200 if (!ReadConsoleInput(hConsole, &InputRecord, 1, &Result))
201 done = TRUE;
202
203 }
204
205 doMouse_cleanup();
206 }
207
208 void TMouse::scrollMouse() {
209 doMouse();
210 }