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
33 TMouse::TMouse(Tnclip
&RefClipboard
): Clipboard(RefClipboard
) {
34 hConsole
= GetStdHandle(STD_INPUT_HANDLE
);
35 hStdout
= GetStdHandle(STD_OUTPUT_HANDLE
);
41 void TMouse::get_coords(COORD
*start_coords
, COORD
*end_coords
,
42 COORD
*first_coords
, COORD
*last_coords
) {
43 if(end_coords
->Y
< start_coords
->Y
||
44 (end_coords
->Y
== start_coords
->Y
&& end_coords
->X
< start_coords
->X
))
46 *first_coords
= *end_coords
;
47 *last_coords
= *start_coords
;
49 *first_coords
= *start_coords
;
50 *last_coords
= *end_coords
;
55 void TMouse::doMouse_init() {
56 GetConsoleScreenBufferInfo(hStdout
, &ConsoleInfo
);
57 chiBuffer
= newBuffer();
58 saveScreen(chiBuffer
);
61 void TMouse::doMouse_cleanup() {
62 restoreScreen(chiBuffer
);
66 void TMouse::move_mouse(COORD start_coords
, COORD end_coords
) {
67 COORD screen_start
= {0, 0};
68 COORD first_coords
, last_coords
;
71 FillConsoleOutputAttribute(hStdout
, normal
,
72 ConsoleInfo
.dwSize
.X
* ConsoleInfo
.dwSize
.Y
, screen_start
, &Result
);
74 get_coords(&start_coords
, &end_coords
, &first_coords
, &last_coords
);
75 FillConsoleOutputAttribute(hStdout
, inverse
, ConsoleInfo
.dwSize
.X
*
76 (last_coords
.Y
- first_coords
.Y
) + (last_coords
.X
- first_coords
.X
),
77 first_coords
, &Result
);
80 void TMouse::doClip(COORD start_coords
, COORD end_coords
) {
81 // COORD screen_start = {0, 0};
82 COORD first_coords
, last_coords
;
85 get_coords(&start_coords
, &end_coords
, &first_coords
, &last_coords
);
87 // Allocate the minimal size buffer
88 int data_size
= 3 + ConsoleInfo
.dwSize
.X
*
89 (last_coords
.Y
- first_coords
.Y
) + (last_coords
.X
- first_coords
.X
);
90 HGLOBAL clipboard_data
= GlobalAlloc(GMEM_MOVEABLE
+ GMEM_DDESHARE
,
92 LPVOID mem_ptr
= GlobalLock(clipboard_data
);
94 // Reset data_size so we can count the actual data size
97 // Read the console, put carriage returns at the end of each line if
98 // reading more than one line (Paul Brannan 9/17/98)
99 for(int j
= first_coords
.Y
; j
<= last_coords
.Y
; j
++) {
101 // Read line at (0,j)
105 int length
= ConsoleInfo
.dwSize
.X
;
107 if(j
== first_coords
.Y
) {
108 coords
.X
= first_coords
.X
;
109 length
= ConsoleInfo
.dwSize
.X
- first_coords
.X
;
111 // Add a carriage return to the end of the previous line
112 *((char *)mem_ptr
+ data_size
++) = '\r';
113 *((char *)mem_ptr
+ data_size
++) = '\n';
116 if(j
== last_coords
.Y
) {
117 length
-= (ConsoleInfo
.dwSize
.X
- last_coords
.X
);
120 // Read the next line
121 ReadConsoleOutputCharacter(hStdout
, (LPTSTR
)((char *)mem_ptr
+
122 data_size
), length
, coords
, &Result
);
125 // Strip the spaces at the end of the line
126 if((j
!= last_coords
.Y
) && (first_coords
.Y
!= last_coords
.Y
))
127 while(*((char *)mem_ptr
+ data_size
- 1) == ' ') data_size
--;
129 if(first_coords
.Y
!= last_coords
.Y
) {
130 // Add a carriage return to the end of the last line
131 *((char *)mem_ptr
+ data_size
++) = '\r';
132 *((char *)mem_ptr
+ data_size
++) = '\n';
135 *((char *)mem_ptr
+ data_size
) = 0;
136 GlobalUnlock(clipboard_data
);
138 Clipboard
.Copy(clipboard_data
);
141 void TMouse::doMouse() {
142 INPUT_RECORD InputRecord
;
144 InputRecord
.EventType
= KEY_EVENT
; // just in case
145 while(InputRecord
.EventType
!= MOUSE_EVENT
) {
146 if (!ReadConsoleInput(hConsole
, &InputRecord
, 1, &Result
))
147 return; // uh oh! we don't know the starting coordinates!
149 if(InputRecord
.Event
.MouseEvent
.dwButtonState
== 0) return;
150 if(!(InputRecord
.Event
.MouseEvent
.dwButtonState
&
151 FROM_LEFT_1ST_BUTTON_PRESSED
)) {
156 COORD screen_start
= {0, 0};
157 COORD start_coords
= InputRecord
.Event
.MouseEvent
.dwMousePosition
;
158 COORD end_coords
= start_coords
;
163 int normal_bg
= ini
.get_normal_bg();
164 int normal_fg
= ini
.get_normal_fg();
165 if(normal_bg
== -1) normal_bg
= 0; // FIX ME!! This is just a hack
166 if(normal_fg
== -1) normal_fg
= 7;
167 normal
= (normal_bg
<< 4) | normal_fg
;
168 inverse
= (normal_fg
<< 4) | normal_bg
;
170 // make screen all one attribute
171 FillConsoleOutputAttribute(hStdout
, normal
, ConsoleInfo
.dwSize
.X
*
172 ConsoleInfo
.dwSize
.Y
, screen_start
, &Result
);
176 switch (InputRecord
.EventType
) {
178 switch(InputRecord
.Event
.MouseEvent
.dwEventFlags
) {
179 case 0: // only copy if the mouse button has been released
180 if(!InputRecord
.Event
.MouseEvent
.dwButtonState
) {
181 doClip(start_coords
, end_coords
);
187 end_coords
= InputRecord
.Event
.MouseEvent
.dwMousePosition
;
188 move_mouse(start_coords
, end_coords
);
192 // If we are changing focus, we don't want to highlight anything
193 // (Paul Brannan 9/2/98)
198 WaitForSingleObject(hConsole
, INFINITE
);
199 if (!ReadConsoleInput(hConsole
, &InputRecord
, 1, &Result
))
207 void TMouse::scrollMouse() {