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
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.
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.
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.
24 ///////////////////////////////////////////////////////////////////////////
27 // A simple class for handling mouse events
28 // Written by Paul Brannan <pbranna@clemson.edu>
29 // Last modified August 30, 1998
34 TMouse::TMouse(Tnclip
&RefClipboard
): Clipboard(RefClipboard
) {
35 hConsole
= GetStdHandle(STD_INPUT_HANDLE
);
36 hStdout
= GetStdHandle(STD_OUTPUT_HANDLE
);
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
))
47 *first_coords
= *end_coords
;
48 *last_coords
= *start_coords
;
50 *first_coords
= *start_coords
;
51 *last_coords
= *end_coords
;
56 void TMouse::doMouse_init() {
57 GetConsoleScreenBufferInfo(hStdout
, &ConsoleInfo
);
58 chiBuffer
= newBuffer();
59 saveScreen(chiBuffer
);
62 void TMouse::doMouse_cleanup() {
63 restoreScreen(chiBuffer
);
67 void TMouse::move_mouse(COORD start_coords
, COORD end_coords
) {
68 COORD screen_start
= {0, 0};
69 COORD first_coords
, last_coords
;
72 FillConsoleOutputAttribute(hStdout
, normal
,
73 ConsoleInfo
.dwSize
.X
* ConsoleInfo
.dwSize
.Y
, screen_start
, &Result
);
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
);
81 void TMouse::doClip(COORD start_coords
, COORD end_coords
) {
82 // COORD screen_start = {0, 0};
83 COORD first_coords
, last_coords
;
86 get_coords(&start_coords
, &end_coords
, &first_coords
, &last_coords
);
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
,
93 LPVOID mem_ptr
= GlobalLock(clipboard_data
);
95 // Reset data_size so we can count the actual data size
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
++) {
102 // Read line at (0,j)
106 int length
= ConsoleInfo
.dwSize
.X
;
108 if(j
== first_coords
.Y
) {
109 coords
.X
= first_coords
.X
;
110 length
= ConsoleInfo
.dwSize
.X
- first_coords
.X
;
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';
117 if(j
== last_coords
.Y
) {
118 length
-= (ConsoleInfo
.dwSize
.X
- last_coords
.X
);
121 // Read the next line
122 ReadConsoleOutputCharacter(hStdout
, (LPTSTR
)((char *)mem_ptr
+
123 data_size
), length
, coords
, &Result
);
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
--;
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';
136 *((char *)mem_ptr
+ data_size
) = 0;
137 GlobalUnlock(clipboard_data
);
139 Clipboard
.Copy(clipboard_data
);
142 void TMouse::doMouse() {
143 INPUT_RECORD InputRecord
;
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!
150 if(InputRecord
.Event
.MouseEvent
.dwButtonState
== 0) return;
151 if(!(InputRecord
.Event
.MouseEvent
.dwButtonState
&
152 FROM_LEFT_1ST_BUTTON_PRESSED
)) {
157 COORD screen_start
= {0, 0};
158 COORD start_coords
= InputRecord
.Event
.MouseEvent
.dwMousePosition
;
159 COORD end_coords
= start_coords
;
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
;
171 // make screen all one attribute
172 FillConsoleOutputAttribute(hStdout
, normal
, ConsoleInfo
.dwSize
.X
*
173 ConsoleInfo
.dwSize
.Y
, screen_start
, &Result
);
177 switch (InputRecord
.EventType
) {
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
);
188 end_coords
= InputRecord
.Event
.MouseEvent
.dwMousePosition
;
189 move_mouse(start_coords
, end_coords
);
193 // If we are changing focus, we don't want to highlight anything
194 // (Paul Brannan 9/2/98)
199 WaitForSingleObject(hConsole
, INFINITE
);
200 if (!ReadConsoleInput(hConsole
, &InputRecord
, 1, &Result
))
208 void TMouse::scrollMouse() {