xref: /haiku/src/preferences/keymap/KeymapWindow.cpp (revision 2f470aec1c92ce6917b8a903e343795dc77af41f)
1 // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
2 //
3 //	Copyright (c) 2004, Haiku
4 //
5 //  This software is part of the Haiku distribution and is covered
6 //  by the Haiku license.
7 //
8 //
9 //  File:        KeymapWindow.cpp
10 //  Author:      Sandor Vroemisse, Jérôme Duval
11 //  Description: Keymap Preferences
12 //  Created :    July 12, 2004
13 //
14 // ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
15 
16 #include <Alert.h>
17 #include <Application.h>
18 #include <Box.h>
19 #include <Button.h>
20 #include <Clipboard.h>
21 #include <Debug.h>
22 #include <Directory.h>
23 #include <FindDirectory.h>
24 #include <GraphicsDefs.h>
25 #include <ListView.h>
26 #include <MenuItem.h>
27 #include <Path.h>
28 #include <ScrollView.h>
29 #include <StringView.h>
30 #include <TextView.h>
31 #include <View.h>
32 #include <string.h>
33 #include "KeymapWindow.h"
34 #include "KeymapListItem.h"
35 #include "KeymapApplication.h"
36 
37 #define MENU_FILE_OPEN		'mMFO'
38 #define MENU_FILE_SAVE		'mMFS'
39 #define MENU_FILE_SAVE_AS	'mMFA'
40 #define MENU_EDIT_UNDO		'mMEU'
41 #define MENU_EDIT_CUT		'mMEX'
42 #define MENU_EDIT_COPY		'mMEC'
43 #define MENU_EDIT_PASTE		'mMEV'
44 #define MENU_EDIT_CLEAR		'mMEL'
45 #define MENU_EDIT_SELECT_ALL 'mMEA'
46 #define MENU_FONT_CHANGED	'mMFC'
47 #define SYSTEM_MAP_SELECTED	'SmST'
48 #define USER_MAP_SELECTED	'UmST'
49 #define	USE_KEYMAP			'UkyM'
50 #define REVERT				'Rvrt'
51 
52 KeymapWindow::KeymapWindow()
53 	:	BWindow(BRect(80,25,692,281), "Keymap", B_TITLED_WINDOW,
54 			B_NOT_ZOOMABLE|B_NOT_RESIZABLE|B_ASYNCHRONOUS_CONTROLS )
55 {
56 	// Add the menu bar
57 	BMenuBar *menubar = AddMenuBar();
58 
59 	// The view to hold all but the menu bar
60 	BRect bounds = Bounds();
61 	bounds.top = menubar->Bounds().bottom + 1;
62 	BBox *placeholderView = new BBox(bounds, "placeholderView",
63 		B_FOLLOW_ALL);
64 	placeholderView->SetBorder(B_NO_BORDER);
65 	AddChild( placeholderView );
66 
67 	// Create the Maps box and contents
68 	AddMaps(placeholderView);
69 
70 	fMapView = new MapView(BRect(150,9,600,189), "mapView", &fCurrentMap);
71 	placeholderView->AddChild(fMapView);
72 	SetPulseRate(10000);
73 
74 	BMenuItem *item = fFontMenu->FindMarked();
75 	if (item) {
76 		fMapView->SetFontFamily(item->Label());
77 	}
78 
79 	// The 'Use' button
80 	fUseButton = new BButton(BRect(527,200, 600,220), "useButton", "Use",
81 		new BMessage( USE_KEYMAP ));
82 	placeholderView->AddChild( fUseButton );
83 
84 	// The 'Revert' button
85 	fRevertButton = new BButton(BRect(442,200, 515,220), "revertButton", "Revert",
86 		new BMessage( REVERT ));
87 	placeholderView->AddChild( fRevertButton );
88 
89 	BPath path;
90 	find_directory(B_USER_SETTINGS_DIRECTORY, &path);
91 	path.Append("Keymap");
92 
93 	entry_ref ref;
94 	get_ref_for_path(path.Path(), &ref);
95 
96 	fOpenPanel = new BFilePanel(B_OPEN_PANEL, new BMessenger(this), &ref,
97 		B_FILE_NODE, false, NULL);
98 	fSavePanel = new BFilePanel(B_SAVE_PANEL, new BMessenger(this), &ref,
99 		B_FILE_NODE, false, NULL);
100 }
101 
102 
103 KeymapWindow::~KeymapWindow(void)
104 {
105 	delete fOpenPanel;
106 	delete fSavePanel;
107 }
108 
109 
110 BMenuBar *
111 KeymapWindow::AddMenuBar()
112 {
113 	BRect		bounds;
114 	BMenu		*menu;
115 	BMenuItem	*currentItem;
116 	BMenuBar	*menubar;
117 
118 	bounds = Bounds();
119 	menubar = new BMenuBar( bounds, "menubar" );
120 	AddChild( menubar );
121 
122 	// Create the File menu
123 	menu = new BMenu( "File" );
124 	menu->AddItem( new BMenuItem( "Open" B_UTF8_ELLIPSIS,
125 		new BMessage( MENU_FILE_OPEN ), 'O' ) );
126 	menu->AddSeparatorItem();
127 	currentItem = new BMenuItem( "Save",
128 		new BMessage( MENU_FILE_SAVE ), 'S' );
129 	currentItem->SetEnabled( false );
130 	menu->AddItem( currentItem );
131 	menu->AddItem( new BMenuItem( "Save As" B_UTF8_ELLIPSIS,
132 		new BMessage( MENU_FILE_SAVE_AS )));
133 	menu->AddSeparatorItem();
134 	menu->AddItem( new BMenuItem( "Quit",
135 		new BMessage( B_QUIT_REQUESTED ), 'Q' ));
136 	menubar->AddItem( menu );
137 
138 	// Create the Edit menu
139 	menu = new BMenu( "Edit" );
140 	currentItem = new BMenuItem( "Undo",
141 		new BMessage( MENU_EDIT_UNDO ), 'Z' );
142 	currentItem->SetEnabled( false );
143 	menu->AddItem( currentItem );
144 	menu->AddSeparatorItem();
145 	menu->AddItem( new BMenuItem( "Cut",
146 		new BMessage( MENU_EDIT_CUT ), 'X' ));
147 	menu->AddItem( new BMenuItem( "Copy",
148 		new BMessage( MENU_EDIT_COPY ), 'C' ));
149 	menu->AddItem( new BMenuItem( "Paste",
150 		new BMessage( MENU_EDIT_PASTE ), 'V' ));
151 	menu->AddItem( new BMenuItem( "Clear",
152 		new BMessage( MENU_EDIT_CLEAR )));
153 	menu->AddSeparatorItem();
154 	menu->AddItem( new BMenuItem( "Select All",
155 		new BMessage( MENU_EDIT_SELECT_ALL ), 'A' ));
156 	menubar->AddItem( menu );
157 
158 	// Create the Font menu
159 	fFontMenu = new BMenu( "Font" );
160 	fFontMenu->SetRadioMode(true);
161 	int32 numFamilies = count_font_families();
162 	font_family family, current_family;
163 	font_style current_style;
164 	uint32 flags;
165 
166 	be_plain_font->GetFamilyAndStyle(&current_family, &current_style);
167 
168 	for (int32 i = 0; i < numFamilies; i++ )
169 		if ( get_font_family(i, &family, &flags) == B_OK ) {
170 			BMenuItem *item =
171 				new BMenuItem(family, new BMessage( MENU_FONT_CHANGED));
172 			fFontMenu->AddItem(item);
173 			if(strcmp(family, current_family) == 0)
174 				item->SetMarked(true);
175 		}
176 	menubar->AddItem( fFontMenu );
177 
178 	return menubar;
179 }
180 
181 
182 void
183 KeymapWindow::AddMaps(BView *placeholderView)
184 {
185 	// The Maps box
186 	BRect bounds = BRect(9,11,140,226);
187 	BBox *mapsBox = new BBox(bounds);
188 	mapsBox->SetLabel("Maps");
189 	placeholderView->AddChild( mapsBox );
190 
191 	// The System list
192 	BStringView *systemLabel = new BStringView(BRect(13,13,113,33), "system", "System");
193 	mapsBox->AddChild(systemLabel);
194 
195 	bounds = BRect( 13,35, 103,105 );
196 	fSystemListView = new BListView( bounds, "systemList" );
197 
198 	mapsBox->AddChild( new BScrollView( "systemScrollList", fSystemListView,
199 		B_FOLLOW_LEFT | B_FOLLOW_TOP, 0, false, true ));
200 	fSystemListView->SetSelectionMessage( new BMessage( SYSTEM_MAP_SELECTED ));
201 
202 	// The User list
203 	BStringView *userLabel = new BStringView(BRect(13,110,113,128), "user", "User");
204 	mapsBox->AddChild(userLabel);
205 
206 	bounds = BRect(13,130,103,200);
207 	fUserListView = new BListView( bounds, "userList" );
208 	// '(Current)'
209 	KeymapListItem *currentKeymapItem = (KeymapListItem*)fUserListView->FirstItem();
210 	if( currentKeymapItem != NULL )
211 		fUserListView->AddItem( currentKeymapItem );
212 	// Saved keymaps
213 	mapsBox->AddChild( new BScrollView( "userScrollList", fUserListView,
214 		B_FOLLOW_LEFT | B_FOLLOW_TOP, 0, false, true ));
215 	fUserListView->SetSelectionMessage( new BMessage( USER_MAP_SELECTED ));
216 
217 	FillSystemMaps();
218 
219 	FillUserMaps();
220 }
221 
222 
223 bool
224 KeymapWindow::QuitRequested()
225 {
226 	if (!IsActive())
227 		return false;
228 	be_app->PostMessage( B_QUIT_REQUESTED );
229 	return true;
230 }
231 
232 
233 void
234 KeymapWindow::MessageReceived( BMessage* message )
235 {
236 	switch( message->what ) {
237 		case B_SIMPLE_DATA:
238 		case B_REFS_RECEIVED:
239 		{
240 			entry_ref ref;
241 			int32 i = 0;
242 			while (message->FindRef("refs", i++, &ref) == B_OK) {
243 				fCurrentMap.Load(ref);
244 			}
245 			fMapView->Invalidate();
246 			fSystemListView->DeselectAll();
247 			fUserListView->DeselectAll();
248 		}
249 			break;
250 		case B_SAVE_REQUESTED:
251 		{
252 			entry_ref ref;
253 			const char *name;
254 			if ((message->FindRef("directory", &ref) == B_OK)
255 				&& (message->FindString("name", &name) == B_OK)) {
256 
257 				BDirectory directory(&ref);
258 				BEntry entry(&directory, name);
259 				entry.GetRef(&ref);
260 				fCurrentMap.Save(ref);
261 
262 				FillUserMaps();
263 			}
264 		}
265 			break;
266 		case MENU_FILE_OPEN:
267 			fOpenPanel->Show();
268 			break;
269 		case MENU_FILE_SAVE:
270 			break;
271 		case MENU_FILE_SAVE_AS:
272 			fSavePanel->Show();
273 			break;
274 		case MENU_EDIT_UNDO:
275 		case MENU_EDIT_CUT:
276 		case MENU_EDIT_COPY:
277 		case MENU_EDIT_PASTE:
278 		case MENU_EDIT_CLEAR:
279 		case MENU_EDIT_SELECT_ALL:
280 			fMapView->MessageReceived(message);
281 			break;
282 		case MENU_FONT_CHANGED:
283 		{
284 			BMenuItem *item = fFontMenu->FindMarked();
285 			if (item) {
286 				fMapView->SetFontFamily(item->Label());
287 				fMapView->Invalidate();
288 			}
289 		}
290 			break;
291 		case SYSTEM_MAP_SELECTED:
292 		{
293 			KeymapListItem *keymapListItem =
294 				(KeymapListItem*)fSystemListView->ItemAt(fSystemListView->CurrentSelection());
295 			if (keymapListItem) {
296 				fCurrentMap.Load(keymapListItem->KeymapEntry());
297 				fMapView->Invalidate();
298 
299 				// Deselect item in other BListView
300 				fUserListView->DeselectAll();
301 			}
302 		}
303 			break;
304 		case USER_MAP_SELECTED:
305 		{
306 			KeymapListItem *keymapListItem =
307 				(KeymapListItem*)fUserListView->ItemAt(fUserListView->CurrentSelection());
308 			if (keymapListItem) {
309 				fCurrentMap.Load(keymapListItem->KeymapEntry());
310 				fMapView->Invalidate();
311 
312 				// Deselect item in other BListView
313 				fSystemListView->DeselectAll();
314 			}
315 		}
316 			break;
317 		case USE_KEYMAP:
318 			UseKeymap();
319 			break;
320 		case REVERT:	// do nothing, just like the original
321 			break;
322 		default:
323 			BWindow::MessageReceived( message );
324 			break;
325 	}
326 }
327 
328 
329 void
330 KeymapWindow::UseKeymap()
331 {
332 	BPath path;
333 	if (find_directory(B_USER_SETTINGS_DIRECTORY, &path)!=B_OK)
334 		return;
335 
336 	path.Append("Key_map");
337 
338 	entry_ref ref;
339 	get_ref_for_path(path.Path(), &ref);
340 
341 	status_t err;
342 	if ((err = fCurrentMap.Save(ref)) != B_OK) {
343 		printf("error when saving : %s", strerror(err));
344 		return;
345 	}
346 	fCurrentMap.Use();
347 
348 	fUserListView->Select(0);
349 }
350 
351 
352 void
353 KeymapWindow::FillSystemMaps()
354 {
355 	BListItem *item;
356 	while ((item = fSystemListView->RemoveItem((int32)0)))
357 		delete item;
358 
359 	BPath path;
360 	if (find_directory(B_BEOS_ETC_DIRECTORY, &path)!=B_OK)
361 		return;
362 
363 	path.Append("Keymap");
364 
365 	BDirectory directory;
366 	entry_ref ref;
367 
368 	if (directory.SetTo(path.Path()) == B_OK)
369 		while( directory.GetNextRef(&ref) == B_OK ) {
370 			fSystemListView->AddItem(new KeymapListItem(ref));
371 		}
372 }
373 
374 
375 void
376 KeymapWindow::FillUserMaps()
377 {
378 	BListItem *item;
379 	while ((item = fUserListView->RemoveItem((int32)0)))
380 		delete item;
381 
382 	BPath path;
383 	if (find_directory(B_USER_SETTINGS_DIRECTORY, &path)!=B_OK)
384 		return;
385 
386 	path.Append("Key_map");
387 
388 	entry_ref ref;
389 	get_ref_for_path(path.Path(), &ref);
390 
391 	fUserListView->AddItem(new KeymapListItem(ref, "(Current)"));
392 
393 	if (find_directory(B_USER_SETTINGS_DIRECTORY, &path)!=B_OK)
394 		return;
395 
396 	path.Append("Keymap");
397 
398 	BDirectory directory;
399 
400 	if (directory.SetTo(path.Path()) == B_OK)
401 		while( directory.GetNextRef(&ref) == B_OK ) {
402 			fUserListView->AddItem(new KeymapListItem(ref));
403 		}
404 
405 	fUserListView->Select(0);
406 }
407 
408 
409 BEntry*
410 KeymapWindow::CurrentMap()
411 {
412 	return NULL;
413 }
414 
415 
416 MapView::MapView(BRect rect, const char *name, Keymap* keymap)
417 	: BControl(rect, name, NULL, NULL, B_FOLLOW_LEFT|B_FOLLOW_TOP, B_WILL_DRAW|B_PULSE_NEEDED),
418 		fCurrentFont(*be_plain_font),
419 		fCurrentMap(keymap),
420 		fCurrentMouseKey(0)
421 {
422 	// TODO: Properly handle font sensitivity in drawing the keys.
423 	// This at least prevents the app from looking horrible until the font sensitivity for this app
424 	// can be done the Right Way.
425 	if(fCurrentFont.Size() > 14)
426 		fCurrentFont.SetSize(14);
427 
428 	SetViewColor(B_TRANSPARENT_COLOR);
429 
430 	BRect frameRect = BRect(14, 16, Bounds().right-12, 30);
431 	BRect textRect = frameRect;
432 	textRect.OffsetTo(B_ORIGIN);
433 	textRect.InsetBy(1,1);
434 	fTextView = new KeymapTextView(frameRect, "testzone", textRect,
435 		B_FOLLOW_LEFT | B_FOLLOW_TOP, B_WILL_DRAW | B_FRAME_EVENTS);
436 	fTextView->MakeEditable(true);
437 	fTextView->MakeSelectable(true);
438 
439 	AddChild(fTextView);
440 
441 	for (uint32 j = 0; j<128; j++)
442 		fKeysToDraw[j] = false;
443 
444 	BRect keyRect = BRect(11,50,29,68);
445 	uint32 i = 1;
446 	fKeysRect[i] = keyRect;
447 	fKeysToDraw[i] = true;
448 
449 	// Fx keys
450 	i++;
451 	keyRect.OffsetBySelf(36,0);
452 	fKeysRect[i] = keyRect;
453 	fKeysToDraw[i] = true;
454 	i++;
455 	keyRect.OffsetBySelf(18,0);
456 	fKeysRect[i] = keyRect;
457 	fKeysToDraw[i] = true;
458 	i++;
459 	keyRect.OffsetBySelf(18,0);
460 	fKeysRect[i] = keyRect;
461 	fKeysToDraw[i] = true;
462 	i++;
463 	keyRect.OffsetBySelf(18,0);
464 	fKeysRect[i] = keyRect;
465 	fKeysToDraw[i] = true;
466 
467 	i++;
468 	keyRect.OffsetBySelf(27,0);
469 	fKeysRect[i] = keyRect;
470 	fKeysToDraw[i] = true;
471 	i++;
472 	keyRect.OffsetBySelf(18,0);
473 	fKeysRect[i] = keyRect;
474 	fKeysToDraw[i] = true;
475 	i++;
476 	keyRect.OffsetBySelf(18,0);
477 	fKeysRect[i] = keyRect;
478 	fKeysToDraw[i] = true;
479 	i++;
480 	keyRect.OffsetBySelf(18,0);
481 	fKeysRect[i] = keyRect;
482 	fKeysToDraw[i] = true;
483 
484 	i++;
485 	keyRect.OffsetBySelf(27,0);
486 	fKeysRect[i] = keyRect;
487 	fKeysToDraw[i] = true;
488 	i++;
489 	keyRect.OffsetBySelf(18,0);
490 	fKeysRect[i] = keyRect;
491 	fKeysToDraw[i] = true;
492 	i++;
493 	keyRect.OffsetBySelf(18,0);
494 	fKeysRect[i] = keyRect;
495 	fKeysToDraw[i] = true;
496 	i++;
497 	keyRect.OffsetBySelf(18,0);
498 	fKeysRect[i] = keyRect;
499 	fKeysToDraw[i] = true;
500 
501 	// Pause, PrintScreen, ...
502 	i++;
503 	keyRect.OffsetBySelf(35,0);
504 	fKeysRect[i] = keyRect;
505 	fKeysToDraw[i] = true;
506 	i++;
507 	keyRect.OffsetBySelf(18,0);
508 	fKeysRect[i] = keyRect;
509 	fKeysToDraw[i] = true;
510 	i++;
511 	keyRect.OffsetBySelf(18,0);
512 	fKeysRect[i] = keyRect;
513 	fKeysToDraw[i] = true;
514 
515 	// 1st line : numbers and backspace
516 	i++;
517 	keyRect = BRect(11,78,29,96);
518 	fKeysRect[i] = keyRect;
519 	fKeysToDraw[i] = true;
520 	i++;
521 	keyRect.OffsetBySelf(18,0);
522 	fKeysRect[i] = keyRect;
523 	fKeysToDraw[i] = true;
524 	i++;
525 	keyRect.OffsetBySelf(18,0);
526 	fKeysRect[i] = keyRect;
527 	fKeysToDraw[i] = true;
528 	i++;
529 	keyRect.OffsetBySelf(18,0);
530 	fKeysRect[i] = keyRect;
531 	fKeysToDraw[i] = true;
532 	i++;
533 	keyRect.OffsetBySelf(18,0);
534 	fKeysRect[i] = keyRect;
535 	fKeysToDraw[i] = true;
536 	i++;
537 	keyRect.OffsetBySelf(18,0);
538 	fKeysRect[i] = keyRect;
539 	fKeysToDraw[i] = true;
540 	i++;
541 	keyRect.OffsetBySelf(18,0);
542 	fKeysRect[i] = keyRect;
543 	fKeysToDraw[i] = true;
544 	i++;
545 	keyRect.OffsetBySelf(18,0);
546 	fKeysRect[i] = keyRect;
547 	fKeysToDraw[i] = true;
548 	i++;
549 	keyRect.OffsetBySelf(18,0);
550 	fKeysRect[i] = keyRect;
551 	fKeysToDraw[i] = true;
552 	i++;
553 	keyRect.OffsetBySelf(18,0);
554 	fKeysRect[i] = keyRect;
555 	fKeysToDraw[i] = true;
556 	i++;
557 	keyRect.OffsetBySelf(18,0);
558 	fKeysRect[i] = keyRect;
559 	fKeysToDraw[i] = true;
560 	i++;
561 	keyRect.OffsetBySelf(18,0);
562 	fKeysRect[i] = keyRect;
563 	fKeysToDraw[i] = true;
564 	i++;
565 	keyRect.OffsetBySelf(18,0);
566 	fKeysRect[i] = keyRect;
567 	fKeysToDraw[i] = true;
568 	i++;
569 	keyRect.OffsetBySelf(18,0);
570 	keyRect.right += 18;
571 	fKeysRect[i] = keyRect;
572 	fKeysToDraw[i] = true;
573 	keyRect.left += 18;
574 
575 	// Insert, pg up ...
576 	i++;
577 	keyRect.OffsetBySelf(35,0);
578 	fKeysRect[i] = keyRect;
579 	fKeysToDraw[i] = true;
580 	i++;
581 	keyRect.OffsetBySelf(18,0);
582 	fKeysRect[i] = keyRect;
583 	fKeysToDraw[i] = true;
584 	i++;
585 	keyRect.OffsetBySelf(18,0);
586 	fKeysRect[i] = keyRect;
587 	fKeysToDraw[i] = true;
588 
589 	// 2nd line : tab and azerty ...
590 	i = 0x26;
591 	keyRect = BRect(11,96,38,114);
592 	fKeysRect[i] = keyRect;
593 	fKeysToDraw[i] = true;
594 	i++;
595 	keyRect.OffsetBySelf(27,0);
596 	keyRect.right -= 9;
597 	fKeysRect[i] = keyRect;
598 	fKeysToDraw[i] = true;
599 	i++;
600 	keyRect.OffsetBySelf(18,0);
601 	fKeysRect[i] = keyRect;
602 	fKeysToDraw[i] = true;
603 	i++;
604 	keyRect.OffsetBySelf(18,0);
605 	fKeysRect[i] = keyRect;
606 	fKeysToDraw[i] = true;
607 	i++;
608 	keyRect.OffsetBySelf(18,0);
609 	fKeysRect[i] = keyRect;
610 	fKeysToDraw[i] = true;
611 	i++;
612 	keyRect.OffsetBySelf(18,0);
613 	fKeysRect[i] = keyRect;
614 	fKeysToDraw[i] = true;
615 	i++;
616 	keyRect.OffsetBySelf(18,0);
617 	fKeysRect[i] = keyRect;
618 	fKeysToDraw[i] = true;
619 	i++;
620 	keyRect.OffsetBySelf(18,0);
621 	fKeysRect[i] = keyRect;
622 	fKeysToDraw[i] = true;
623 	i++;
624 	keyRect.OffsetBySelf(18,0);
625 	fKeysRect[i] = keyRect;
626 	fKeysToDraw[i] = true;
627 	i++;
628 	keyRect.OffsetBySelf(18,0);
629 	fKeysRect[i] = keyRect;
630 	fKeysToDraw[i] = true;
631 	i++;
632 	keyRect.OffsetBySelf(18,0);
633 	fKeysRect[i] = keyRect;
634 	fKeysToDraw[i] = true;
635 	i++;
636 	keyRect.OffsetBySelf(18,0);
637 	fKeysRect[i] = keyRect;
638 	fKeysToDraw[i] = true;
639 	i++;
640 	keyRect.OffsetBySelf(18,0);
641 	fKeysRect[i] = keyRect;
642 	fKeysToDraw[i] = true;
643 	i++;
644 	keyRect.OffsetBySelf(18,0);
645 	keyRect.right += 9;
646 	fKeysRect[i] = keyRect;
647 	fKeysToDraw[i] = true;
648 	keyRect.left += 9;
649 
650 	// Suppr, pg down ...
651 	i++;
652 	keyRect.OffsetBySelf(35,0);
653 	fKeysRect[i] = keyRect;
654 	fKeysToDraw[i] = true;
655 	i++;
656 	keyRect.OffsetBySelf(18,0);
657 	fKeysRect[i] = keyRect;
658 	fKeysToDraw[i] = true;
659 	i++;
660 	keyRect.OffsetBySelf(18,0);
661 	fKeysRect[i] = keyRect;
662 	fKeysToDraw[i] = true;
663 
664 	// 3rd line : caps and qsdfg ...
665 	i = 0x3b;
666 	keyRect = BRect(11,114,47,132);
667 	fKeysRect[i] = keyRect;
668 	fKeysToDraw[i] = true;
669 	i++;
670 	keyRect.OffsetBySelf(36,0);
671 	keyRect.right -= 18;
672 	fKeysRect[i] = keyRect;
673 	fKeysToDraw[i] = true;
674 	i++;
675 	keyRect.OffsetBySelf(18,0);
676 	fKeysRect[i] = keyRect;
677 	fKeysToDraw[i] = true;
678 	i++;
679 	keyRect.OffsetBySelf(18,0);
680 	fKeysRect[i] = keyRect;
681 	fKeysToDraw[i] = true;
682 	i++;
683 	keyRect.OffsetBySelf(18,0);
684 	fKeysRect[i] = keyRect;
685 	fKeysToDraw[i] = true;
686 	i++;
687 	keyRect.OffsetBySelf(18,0);
688 	fKeysRect[i] = keyRect;
689 	fKeysToDraw[i] = true;
690 	i++;
691 	keyRect.OffsetBySelf(18,0);
692 	fKeysRect[i] = keyRect;
693 	fKeysToDraw[i] = true;
694 	i++;
695 	keyRect.OffsetBySelf(18,0);
696 	fKeysRect[i] = keyRect;
697 	fKeysToDraw[i] = true;
698 	i++;
699 	keyRect.OffsetBySelf(18,0);
700 	fKeysRect[i] = keyRect;
701 	fKeysToDraw[i] = true;
702 	i++;
703 	keyRect.OffsetBySelf(18,0);
704 	fKeysRect[i] = keyRect;
705 	fKeysToDraw[i] = true;
706 	i++;
707 	keyRect.OffsetBySelf(18,0);
708 	fKeysRect[i] = keyRect;
709 	fKeysToDraw[i] = true;
710 	i++;
711 	keyRect.OffsetBySelf(18,0);
712 	fKeysRect[i] = keyRect;
713 	fKeysToDraw[i] = true;
714 	i++;
715 	keyRect.OffsetBySelf(18,0);
716 	keyRect.right += 18;
717 	fKeysRect[i] = keyRect;
718 	fKeysToDraw[i] = true;
719 	keyRect.left += 18;
720 
721 	// 4th line : shift and wxcv ...
722 	i = 0x4b;
723 	keyRect = BRect(11,132,56,150);
724 	fKeysRect[i] = keyRect;
725 	fKeysToDraw[i] = true;
726 	i++;
727 	keyRect.OffsetBySelf(45,0);
728 	keyRect.right -= 27;
729 	fKeysRect[i] = keyRect;
730 	fKeysToDraw[i] = true;
731 	i++;
732 	keyRect.OffsetBySelf(18,0);
733 	fKeysRect[i] = keyRect;
734 	fKeysToDraw[i] = true;
735 	i++;
736 	keyRect.OffsetBySelf(18,0);
737 	fKeysRect[i] = keyRect;
738 	fKeysToDraw[i] = true;
739 	i++;
740 	keyRect.OffsetBySelf(18,0);
741 	fKeysRect[i] = keyRect;
742 	fKeysToDraw[i] = true;
743 	i++;
744 	keyRect.OffsetBySelf(18,0);
745 	fKeysRect[i] = keyRect;
746 	fKeysToDraw[i] = true;
747 	i++;
748 	keyRect.OffsetBySelf(18,0);
749 	fKeysRect[i] = keyRect;
750 	fKeysToDraw[i] = true;
751 	i++;
752 	keyRect.OffsetBySelf(18,0);
753 	fKeysRect[i] = keyRect;
754 	fKeysToDraw[i] = true;
755 	i++;
756 	keyRect.OffsetBySelf(18,0);
757 	fKeysRect[i] = keyRect;
758 	fKeysToDraw[i] = true;
759 	i++;
760 	keyRect.OffsetBySelf(18,0);
761 	fKeysRect[i] = keyRect;
762 	fKeysToDraw[i] = true;
763 	i++;
764 	keyRect.OffsetBySelf(18,0);
765 	fKeysRect[i] = keyRect;
766 	fKeysToDraw[i] = true;
767 	i++;
768 	keyRect.OffsetBySelf(18,0);
769 	keyRect.right += 27;
770 	fKeysRect[i] = keyRect;
771 	fKeysToDraw[i] = true;
772 	keyRect.left += 27;
773 
774 	//5th line : Ctrl, Alt, Space ...
775 	i = 0x5c;
776 	keyRect = BRect(11,150,38,168);
777 	fKeysRect[i] = keyRect;
778 	fKeysToDraw[i] = true;
779 	i++;
780 	keyRect.OffsetBySelf(27,0);
781 	keyRect.OffsetBySelf(26,0);
782 	fKeysRect[i] = keyRect;
783 	fKeysToDraw[i] = true;
784 	i++;
785 	keyRect.OffsetBySelf(27,0);
786 	keyRect.right += 92;
787 	fKeysRect[i] = keyRect;
788 	fKeysToDraw[i] = true;
789 	i++;
790 	keyRect.right -= 92;
791 	keyRect.OffsetBySelf(92,0);
792 	keyRect.OffsetBySelf(27,0);
793 	fKeysRect[i] = keyRect;
794 	fKeysToDraw[i] = true;
795 	i++;
796 	keyRect.OffsetBySelf(26,0);
797 	keyRect.OffsetBySelf(18,0);
798 	fKeysRect[i] = keyRect;
799 	fKeysToDraw[i] = true;
800 
801 	// Arrows
802 	i++;
803 	keyRect = BRect(298,150,316,168);
804 	fKeysRect[i] = keyRect;
805 	fKeysToDraw[i] = true;
806 	i++;
807 	keyRect.OffsetBySelf(18,0);
808 	fKeysRect[i] = keyRect;
809 	fKeysToDraw[i] = true;
810 	i++;
811 	keyRect.OffsetBySelf(18,0);
812 	fKeysRect[i] = keyRect;
813 	fKeysToDraw[i] = true;
814 	i = 0x57;
815 	keyRect.OffsetBySelf(-18,-18);
816 	fKeysRect[i] = keyRect;
817 	fKeysToDraw[i] = true;
818 
819 	// numkeys
820 	i = 0x22;
821 	keyRect = BRect(369,78,387,96);
822 	fKeysRect[i] = keyRect;
823 	fKeysToDraw[i] = true;
824 	i++;
825 	keyRect.OffsetBySelf(18,0);
826 	fKeysRect[i] = keyRect;
827 	fKeysToDraw[i] = true;
828 	i++;
829 	keyRect.OffsetBySelf(18,0);
830 	fKeysRect[i] = keyRect;
831 	fKeysToDraw[i] = true;
832 	i++;
833 	keyRect.OffsetBySelf(18,0);
834 	fKeysRect[i] = keyRect;
835 	fKeysToDraw[i] = true;
836 	i = 0x37;
837 	keyRect.OffsetBySelf(-54, 18);
838 	fKeysRect[i] = keyRect;
839 	fKeysToDraw[i] = true;
840 	i++;
841 	keyRect.OffsetBySelf(18,0);
842 	fKeysRect[i] = keyRect;
843 	fKeysToDraw[i] = true;
844 	i++;
845 	keyRect.OffsetBySelf(18,0);
846 	fKeysRect[i] = keyRect;
847 	fKeysToDraw[i] = true;
848 	i++;
849 	keyRect.OffsetBySelf(18,0);
850 	keyRect.bottom += 18;
851 	fKeysRect[i] = keyRect;
852 	fKeysToDraw[i] = true;
853 	i = 0x48;
854 	keyRect.bottom -= 18;
855 	keyRect.OffsetBySelf(-54, 18);
856 	fKeysRect[i] = keyRect;
857 	fKeysToDraw[i] = true;
858 	i++;
859 	keyRect.OffsetBySelf(18,0);
860 	fKeysRect[i] = keyRect;
861 	fKeysToDraw[i] = true;
862 	i++;
863 	keyRect.OffsetBySelf(18,0);
864 	fKeysRect[i] = keyRect;
865 	fKeysToDraw[i] = true;
866 	i = 0x58;
867 	keyRect.OffsetBySelf(-36, 18);
868 	fKeysRect[i] = keyRect;
869 	fKeysToDraw[i] = true;
870 	i++;
871 	keyRect.OffsetBySelf(18,0);
872 	fKeysRect[i] = keyRect;
873 	fKeysToDraw[i] = true;
874 	i++;
875 	keyRect.OffsetBySelf(18,0);
876 	fKeysRect[i] = keyRect;
877 	fKeysToDraw[i] = true;
878 	i++;
879 	keyRect.OffsetBySelf(18,0);
880 	keyRect.bottom += 18;
881 	fKeysRect[i] = keyRect;
882 	fKeysToDraw[i] = true;
883 	i = 0x64;
884 	keyRect.bottom -= 18;
885 	keyRect.OffsetBySelf(-54, 18);
886 	keyRect.right += 18;
887 	fKeysRect[i] = keyRect;
888 	fKeysToDraw[i] = true;
889 	i++;
890 	keyRect.right -= 18;
891 	keyRect.OffsetBySelf(36,0);
892 	fKeysRect[i] = keyRect;
893 	fKeysToDraw[i] = true;
894 
895 	for (uint32 j = 0; j<128; j++)
896 		fKeysVertical[j] = false;
897 
898 	fKeysVertical[0x5e] = true;
899 
900 	fActiveDeadKey = 0;
901 
902 	for (int8 j=0; j<16; j++)
903 		fOldKeyInfo.key_states[j] = 0;
904 	fOldKeyInfo.modifiers = 0;
905 }
906 
907 
908 void
909 MapView::AttachedToWindow()
910 {
911 	SetEventMask(B_KEYBOARD_EVENTS, 0);
912 	fTextView->SetViewColor(255,255,255);
913 	BView::AttachedToWindow();
914 }
915 
916 
917 void
918 MapView::Draw(BRect rect)
919 {
920 	BRect r = Bounds();
921 	SetHighColor(0,0,0);
922 	StrokeRect(r);
923 
924 	r.InsetBySelf(1,1);
925 	SetHighColor(168,168,168);
926 	StrokeRect(r);
927 	SetHighColor(80,80,80);
928 	StrokeLine(BPoint(r.left+2, r.bottom), r.RightBottom());
929 	StrokeLine(r.RightTop());
930 
931 	r.InsetBySelf(1,1);
932 	SetHighColor(255,255,255);
933 	StrokeRect(r);
934 	SetHighColor(112,112,112);
935 	StrokeLine(BPoint(r.left+1, r.bottom), r.RightBottom());
936 	StrokeLine(r.RightTop());
937 
938 	r.InsetBySelf(1,1);
939 	SetHighColor(168,168,168);
940 	FillRect(r);
941 
942 	SetHighColor(255,255,255);
943 	FillRect(BRect(r.right-1, r.bottom-1, r.right, r.bottom));
944 	SetHighColor(184,184,184);
945 	StrokeLine(BPoint(r.right-9, r.bottom), BPoint(r.right-2, r.bottom));
946 	StrokeLine(BPoint(r.right, r.bottom-9), BPoint(r.right, r.bottom-2));
947 
948 	InvalidateKeys();
949 
950 	// Esc key
951 	DrawBorder(BRect(10,49,30,69));
952 
953 	// Fx keys
954 	DrawBorder(BRect(46, 49, 120, 69));
955 
956 	DrawBorder(BRect(127, 49, 201, 69));
957 
958 	DrawBorder(BRect(208, 49, 282, 69));
959 
960 	// Pause, PrintScreen, ...
961 	DrawBorder(BRect(297, 49, 353, 69));
962 
963 	// Insert, pg up ...
964 	DrawBorder(BRect(297, 77, 353, 115));
965 
966 	SetHighColor(80,80,80);
967 	StrokeLine(BPoint(10,169), BPoint(10,77));
968 	StrokeLine(BPoint(282,77));
969 	SetHighColor(255,255,255);
970 	StrokeLine(BPoint(282,169));
971 	StrokeLine(BPoint(253,169));
972 	SetHighColor(80,80,80);
973 	StrokeLine(BPoint(253,151));
974 	SetHighColor(255,255,255);
975 	StrokeLine(BPoint(238,151));
976 	StrokeLine(BPoint(238,169));
977 	StrokeLine(BPoint(63,169));
978 	SetHighColor(80,80,80);
979 	StrokeLine(BPoint(63,151));
980 	SetHighColor(255,255,255);
981 	StrokeLine(BPoint(39,151));
982 	StrokeLine(BPoint(39,169));
983 	StrokeLine(BPoint(11,169));
984 
985 	// Arrows
986 	SetHighColor(80,80,80);
987 	StrokeLine(BPoint(297,169), BPoint(297,149));
988 	StrokeLine(BPoint(315,149));
989 	StrokeLine(BPoint(315,131));
990 	StrokeLine(BPoint(335,131));
991 	StrokeLine(BPoint(336,149), BPoint(353,149));
992 	SetHighColor(255,255,255);
993 	StrokeLine(BPoint(335,132), BPoint(335,149));
994 	StrokeLine(BPoint(353,150), BPoint(353,169));
995 	StrokeLine(BPoint(298,169));
996 
997 	// numkeys
998 	DrawBorder(BRect(368, 77, 442, 169));
999 
1000 	DrawLocks();
1001 
1002 	// the line separator
1003 	r = BRect(11, 40, 353, 43);
1004 	SetHighColor(255,255,255);
1005 	StrokeLine(r.LeftBottom(), r.LeftTop());
1006 	StrokeLine(r.RightTop());
1007 	SetHighColor(80,80,80);
1008 	StrokeLine(r.RightBottom());
1009 	StrokeLine(r.LeftBottom());
1010 	r.OffsetBySelf(2,4);
1011 	r.bottom = r.top + 1;
1012 	SetHighColor(136,136,136);
1013 	FillRect(r);
1014 	FillRect(BRect(354,41,355,43));
1015 
1016 	// around the textview
1017 	SetHighColor(0,0,0);
1018 	r = BRect(11, 13, Bounds().right-11, 31);
1019 	StrokeLine(r.LeftBottom(), r.LeftTop());
1020 	StrokeLine(r.RightTop());
1021 	SetHighColor(80,80,80);
1022 	StrokeLine(r.LeftBottom()+BPoint(1,0), r.LeftTop()+BPoint(1,1));
1023 	StrokeLine(r.RightTop()+BPoint(0,1));
1024 	SetHighColor(136,136,136);
1025 	StrokeLine(r.LeftBottom()+BPoint(2,-1), r.LeftTop()+BPoint(2,2));
1026 	StrokeLine(r.RightTop()+BPoint(0,2));
1027 	StrokeLine(r.LeftBottom()+BPoint(1,0), r.LeftBottom()+BPoint(1,0));
1028 	SetHighColor(255,255,255);
1029 	StrokeLine(r.RightTop()+BPoint(0,1), r.RightBottom());
1030 	StrokeLine(r.LeftBottom()+BPoint(2,0));
1031 	BView::Draw(rect);
1032 }
1033 
1034 
1035 void
1036 MapView::DrawLocks()
1037 {
1038 	// lights
1039 #define isLighted(i) (fOldKeyInfo.modifiers & i)
1040 
1041 	DrawBorder(BRect(368, 49, 442, 69));
1042 
1043 	escapement_delta delta;
1044 	delta.nonspace = 0.0;
1045 	BFont font(be_plain_font);
1046 	font.SetSize(9.0);
1047 	font.SetFlags(B_DISABLE_ANTIALIASING);
1048 	font.SetSpacing(B_CHAR_SPACING);
1049 	SetFont(&font);
1050 	BRect lightRect = BRect(372,53,386,56);
1051 
1052 	SetHighColor(80,80,80);
1053 	StrokeLine(lightRect.LeftBottom(), lightRect.RightBottom());
1054 	StrokeLine(lightRect.RightTop());
1055 	SetHighColor(255,255,255);
1056 	StrokeLine(BPoint(lightRect.right-1, lightRect.top), lightRect.LeftTop());
1057 	StrokeLine(BPoint(lightRect.left, lightRect.bottom-1));
1058 	SetHighColor(0,55,0);
1059 	if (isLighted(B_NUM_LOCK))
1060 		SetHighColor(0,178,0);
1061 	FillRect(lightRect.InsetByCopy(1,1));
1062 	SetHighColor(64,64,64);
1063 	DrawString("num", BPoint(lightRect.left-2, 65), &delta);
1064 
1065 	lightRect.OffsetBy(26,0);
1066 	SetHighColor(80,80,80);
1067 	StrokeLine(lightRect.LeftBottom(), lightRect.RightBottom());
1068 	StrokeLine(lightRect.RightTop());
1069 	SetHighColor(255,255,255);
1070 	StrokeLine(BPoint(lightRect.right-1, lightRect.top), lightRect.LeftTop());
1071 	StrokeLine(BPoint(lightRect.left, lightRect.bottom-1));
1072 	SetHighColor(0,55,0);
1073 	if (isLighted(B_CAPS_LOCK))
1074 		SetHighColor(0,178,0);
1075 	FillRect(lightRect.InsetByCopy(1,1));
1076 	SetHighColor(64,64,64);
1077 	DrawString("caps", BPoint(lightRect.left-3, 65), &delta);
1078 
1079 	lightRect.OffsetBy(26,0);
1080 	SetHighColor(80,80,80);
1081 	StrokeLine(lightRect.LeftBottom(), lightRect.RightBottom());
1082 	StrokeLine(lightRect.RightTop());
1083 	SetHighColor(255,255,255);
1084 	StrokeLine(BPoint(lightRect.right-1, lightRect.top), lightRect.LeftTop());
1085 	StrokeLine(BPoint(lightRect.left, lightRect.bottom-1));
1086 	SetHighColor(0,55,0);
1087 	if (isLighted(B_SCROLL_LOCK))
1088 		SetHighColor(0,178,0);
1089 	FillRect(lightRect.InsetByCopy(1,1));
1090 	SetHighColor(64,64,64);
1091 	DrawString("scroll", BPoint(lightRect.left-4, 65), &delta);
1092 }
1093 
1094 
1095 void
1096 MapView::InvalidateKeys()
1097 {
1098 	for (uint32 i=0; i<128; i++)
1099 		if (fKeysToDraw[i+1])
1100 			DrawKey(i+1);
1101 }
1102 
1103 
1104 void
1105 MapView::DrawKey(uint32 keyCode)
1106 {
1107 	BRect r = fKeysRect[keyCode];
1108 	if (!r.IsValid())
1109 		return;
1110 	SetHighColor(0,0,0);
1111 	StrokeRect(r);
1112 
1113 	bool pressed = (fOldKeyInfo.key_states[keyCode>>3] & (1 << (7 - keyCode%8))) || (keyCode == fCurrentMouseKey);
1114 	bool vertical = fKeysVertical[keyCode];
1115 	int32 deadKey = fCurrentMap->IsDeadKey(keyCode, fOldKeyInfo.modifiers);
1116 	bool secondDeadKey = fCurrentMap->IsDeadSecondKey(keyCode, fOldKeyInfo.modifiers, fActiveDeadKey);
1117 
1118 	if (!pressed) {
1119 		r.InsetBySelf(1,1);
1120 		if (secondDeadKey) {
1121 			SetHighColor(255,0,0);
1122 			StrokeRect(r);
1123 			r.InsetBySelf(1,1);
1124 			StrokeRect(r);
1125 		} else if (deadKey>0) {
1126 			SetHighColor(255,255,0);
1127 			StrokeRect(r);
1128 			r.InsetBySelf(1,1);
1129 			StrokeRect(r);
1130 		} else {
1131 
1132 			SetHighColor(64,64,64);
1133 			StrokeRect(r);
1134 
1135 			BeginLineArray(14);
1136 			rgb_color color1 = {200,200,200};
1137 			AddLine(BPoint(r.left, r.bottom-1), r.LeftTop(), color1);
1138 			AddLine(r.LeftTop(), BPoint(r.left+3, r.top), color1);
1139 			rgb_color color2 = {184,184,184};
1140 			AddLine(BPoint(r.left+3, r.top), BPoint(r.left+6, r.top), color2);
1141 			rgb_color color3 = {168,168,168};
1142 			AddLine(BPoint(r.left+6, r.top), BPoint(r.left+9, r.top), color3);
1143 			rgb_color color4 = {152,152,152};
1144 			AddLine(BPoint(r.left+9, r.top), BPoint(r.right-1, r.top), color4);
1145 
1146 			r.InsetBySelf(1,1);
1147 			SetHighColor(255,255,255);
1148 			StrokeRect(r);
1149 
1150 			rgb_color color6 = {96,96,96};
1151 			AddLine(r.LeftBottom(), r.RightBottom(), color6);
1152 			rgb_color color5 = {160,160,160};
1153 			AddLine(r.LeftBottom(), r.LeftBottom(), color5);
1154 			rgb_color color7 = {64,64,64};
1155 			AddLine(r.RightBottom(), BPoint(r.right, r.bottom-1), color7);
1156 			AddLine(BPoint(r.right, r.bottom-1), BPoint(r.right, r.top-1), color6);
1157 			AddLine(BPoint(r.right, r.top-1), r.RightTop(), color5);
1158 			rgb_color color8 = {255,255,255};
1159 			AddLine(BPoint(r.left+1, r.bottom-1), BPoint(r.left+2, r.bottom-1), color8);
1160 			AddLine(BPoint(r.left+2, r.bottom-1), BPoint(r.right-1, r.bottom-1), color1);
1161 			AddLine(BPoint(r.right-1, r.bottom-1), BPoint(r.right-1, r.bottom-2), color5);
1162 			AddLine(BPoint(r.right-1, r.bottom-2), BPoint(r.right-1, r.top+1), color1);
1163 			EndLineArray();
1164 		}
1165 
1166 		r.InsetBySelf(1,1);
1167 		r.bottom -= 1;
1168 		BRect fillRect = r;
1169 
1170 		if (!vertical) {
1171 			int32 w1 = 4;
1172 			int32 w2 = 3;
1173 			if(fKeysRect[keyCode].Width() > 20) {
1174 				w1 = 6;
1175 				w2 = 6;
1176 			}
1177 
1178 			fillRect.right = fillRect.left + w1;
1179 			SetHighColor(152,152,152);
1180 			FillRect(fillRect);
1181 			fillRect.left += w1;
1182 			fillRect.right = fillRect.left + w2;
1183 			SetHighColor(168,168,168);
1184 			FillRect(fillRect);
1185 			fillRect.left += w2;
1186 			fillRect.right = r.right-1;
1187 			SetHighColor(184,184,184);
1188 			FillRect(fillRect);
1189 		} else {
1190 			SetHighColor(200,200,200);
1191 			fillRect.right -= 1;
1192 			fillRect.bottom = fillRect.top + 2;
1193 			FillRect(fillRect);
1194 			SetHighColor(184,184,184);
1195 			fillRect.OffsetBySelf(0,3);
1196 			FillRect(fillRect);
1197 			SetHighColor(168,168,168);
1198 			fillRect.OffsetBySelf(0,3);
1199 			FillRect(fillRect);
1200 			SetHighColor(152,152,152);
1201 			fillRect.OffsetBySelf(0,3);
1202 			FillRect(fillRect);
1203 		}
1204 	} else {
1205 		r.InsetBySelf(1,1);
1206 
1207 		if (secondDeadKey) {
1208 			SetHighColor(255,0,0);
1209 			StrokeRect(r);
1210 			r.InsetBySelf(1,1);
1211 			StrokeRect(r);
1212 		} else if (deadKey>0) {
1213 			SetHighColor(255,255,0);
1214 			StrokeRect(r);
1215 			r.InsetBySelf(1,1);
1216 			StrokeRect(r);
1217 		} else {
1218 			SetHighColor(48,48,48);
1219 			StrokeRect(r);
1220 
1221 			BeginLineArray(2);
1222 			rgb_color color1 = {136,136,136};
1223 			AddLine(BPoint(r.left+1, r.bottom), r.RightBottom(), color1);
1224 			AddLine(r.RightBottom(), BPoint(r.right, r.top+1), color1);
1225 			EndLineArray();
1226 
1227 			r.InsetBySelf(1,1);
1228 			SetHighColor(72,72,72);
1229 			StrokeRect(r);
1230 
1231 			BeginLineArray(4);
1232 			rgb_color color2 = {48,48,48};
1233 			AddLine(r.LeftTop(), r.LeftTop(), color2);
1234 			rgb_color color3 = {152,152,152};
1235 			AddLine(BPoint(r.left+1, r.bottom), r.RightBottom(), color3);
1236 			AddLine(r.RightBottom(), r.RightTop(), color3);
1237 			rgb_color color4 = {160,160,160};
1238 			AddLine(r.RightTop(), r.RightTop(), color4);
1239 			EndLineArray();
1240 		}
1241 
1242 		r.InsetBySelf(1,1);
1243 		SetHighColor(112,112,112);
1244 		FillRect(r);
1245 		SetHighColor(136,136,136);
1246 		StrokeLine(r.LeftTop(), r.LeftTop());
1247 
1248 	}
1249 
1250 	char *str = NULL;
1251 	int32 numBytes;
1252 	fCurrentMap->GetChars(keyCode, fOldKeyInfo.modifiers, fActiveDeadKey, &str, &numBytes);
1253 	if (str) {
1254 		bool hasGlyphs;
1255 		if (deadKey>0) {
1256 			delete str;
1257 			switch (deadKey) {
1258 				case 1: str = strdup("'"); break;
1259 				case 2: str = strdup("`"); break;
1260 				case 3: str = strdup("^"); break;
1261 				case 4: str = strdup("\""); break;
1262 				case 5: str = strdup("~"); break;
1263 			}
1264 		}
1265 		fCurrentFont.GetHasGlyphs(str, 1, &hasGlyphs);
1266 
1267 		if (hasGlyphs) {
1268 			SetFont(&fCurrentFont);
1269 			SetDrawingMode(B_OP_COPY);
1270 			SetHighColor(0,0,0);
1271 			SetLowColor(184,184,184);
1272 			BPoint point = fKeysRect[keyCode].LeftBottom();
1273 			point.x += 4;
1274 			point.y -= 5;
1275 			DrawString(str, point);
1276 			SetDrawingMode(B_OP_OVER);
1277 		}
1278 		delete str;
1279 	}
1280 }
1281 
1282 
1283 void
1284 MapView::DrawBorder(BRect bRect)
1285 {
1286 	rgb_color gray = {80,80,80};
1287 	rgb_color white = {255,255,255};
1288 
1289 	BeginLineArray(4);
1290 	AddLine(bRect.LeftTop(), bRect.LeftBottom(), gray);
1291 	AddLine(bRect.LeftTop(), bRect.RightTop(), gray);
1292 	AddLine(BPoint(bRect.left + 1, bRect.bottom), bRect.RightBottom(), white);
1293 	AddLine(bRect.RightBottom(), BPoint(bRect.right, bRect.top + 1), white);
1294 	EndLineArray();
1295 }
1296 
1297 
1298 void
1299 MapView::MessageReceived(BMessage *msg)
1300 {
1301 	switch (msg->what) {
1302 		case MENU_EDIT_UNDO:
1303 			fTextView->Undo(be_clipboard);
1304 			break;
1305 		case MENU_EDIT_CUT:
1306 			fTextView->Cut(be_clipboard);
1307 			break;
1308 		case MENU_EDIT_COPY:
1309 			fTextView->Copy(be_clipboard);
1310 			break;
1311 		case MENU_EDIT_PASTE:
1312 			fTextView->Paste(be_clipboard);
1313 			break;
1314 		case MENU_EDIT_CLEAR:
1315 			fTextView->Clear();
1316 			break;
1317 		case MENU_EDIT_SELECT_ALL:
1318 			fTextView->SelectAll();
1319 			break;
1320 		case B_KEY_DOWN:
1321 		case B_KEY_UP:
1322 		case B_UNMAPPED_KEY_DOWN:
1323 		case B_UNMAPPED_KEY_UP:
1324 		case B_MODIFIERS_CHANGED: {
1325 			key_info info;
1326 			const uint8 *states;
1327 			ssize_t size;
1328 
1329 			if ((msg->FindData("states", B_UINT8_TYPE, (const void **)&states, &size)!=B_OK)
1330 				|| (msg->FindInt32("modifiers", (int32 *)&info.modifiers)!=B_OK))
1331 				break;
1332 
1333 			if (fOldKeyInfo.modifiers != info.modifiers) {
1334 				fOldKeyInfo.modifiers = info.modifiers;
1335 				for (int8 i=0; i<16; i++)
1336 					fOldKeyInfo.key_states[i] = states[i];
1337 				InvalidateKeys();
1338 				DrawLocks();
1339 			} else {
1340 
1341 				int32 keyCode = -1;
1342 				for (int8 i=0; i<16; i++)
1343 					if (fOldKeyInfo.key_states[i] != states[i]) {
1344 						uint8 stbits = fOldKeyInfo.key_states[i] ^ states[i];
1345 						fOldKeyInfo.key_states[i] = states[i];
1346 						for (int8 j=7; stbits; j--,stbits>>=1)
1347 							if (stbits & 1) {
1348 								keyCode = i*8 + j;
1349 								DrawKey(keyCode);
1350 							}
1351 
1352 					}
1353 
1354 				if (keyCode<0)
1355 					for (int8 i=0; i<16; i++) {
1356 						uint8 stbits = states[i];
1357 						for (int8 j=7; stbits; j--,stbits>>=1)
1358 							if (stbits & 1) {
1359 								keyCode = i*8 + j;
1360 								if (!fCurrentMap->IsModifierKey(keyCode)) {
1361 									i = 16;
1362 									break;
1363 								}
1364 							}
1365 					}
1366 
1367 
1368 				if (Window()->IsActive()
1369 					&& msg->what == B_KEY_DOWN) {
1370 					fTextView->MakeFocus();
1371 					char *str = NULL;
1372 					int32 numBytes;
1373 					if (fActiveDeadKey) {
1374 						fCurrentMap->GetChars(keyCode, fOldKeyInfo.modifiers, fActiveDeadKey, &str, &numBytes);
1375 						if (numBytes>0) {
1376 							fTextView->FakeKeyDown(str, numBytes);
1377 						}
1378 						fActiveDeadKey = 0;
1379 						InvalidateKeys();
1380 					} else {
1381 						fCurrentMap->GetChars(keyCode, fOldKeyInfo.modifiers, fActiveDeadKey, &str, &numBytes);
1382 						fActiveDeadKey = fCurrentMap->IsDeadKey(keyCode, fOldKeyInfo.modifiers);
1383 						if (fActiveDeadKey)
1384 							InvalidateKeys();
1385 						else if (numBytes>0) {
1386 							fTextView->FakeKeyDown(str, numBytes);
1387 						}
1388 					}
1389 					delete str;
1390 				}
1391 			}
1392 			break;
1393 		}
1394 		default:
1395 			BView::MessageReceived(msg);
1396 	}
1397 
1398 }
1399 
1400 
1401 void
1402 MapView::KeyDown(const char* bytes, int32 numBytes)
1403 {
1404 	MessageReceived(Window()->CurrentMessage());
1405 }
1406 
1407 
1408 void
1409 MapView::KeyUp(const char* bytes, int32 numBytes)
1410 {
1411 	MessageReceived(Window()->CurrentMessage());
1412 }
1413 
1414 
1415 void
1416 MapView::MouseDown(BPoint point)
1417 {
1418 	uint32 buttons;
1419 	GetMouse(&point, &buttons);
1420 	if(buttons & B_PRIMARY_MOUSE_BUTTON) {
1421 		fCurrentMouseKey = 0;
1422 		for (int32 i=0; i<128; i++) {
1423 			if (fKeysRect[i].IsValid() && fKeysRect[i].Contains(point)) {
1424 				fCurrentMouseKey = i;
1425 				DrawKey(fCurrentMouseKey);
1426 				char *str = NULL;
1427 				int32 numBytes;
1428 				fCurrentMap->GetChars(fCurrentMouseKey, fOldKeyInfo.modifiers, fActiveDeadKey, &str, &numBytes);
1429 				if (numBytes>0) {
1430 					fTextView->FakeKeyDown(str, numBytes);
1431 					delete str;
1432 				}
1433 				SetTracking(true);
1434 				SetMouseEventMask(B_POINTER_EVENTS,
1435 					B_LOCK_WINDOW_FOCUS | B_NO_POINTER_HISTORY);
1436 				break;
1437 			}
1438 		}
1439 	}
1440 }
1441 
1442 
1443 void
1444 MapView::MouseUp(BPoint point)
1445 {
1446 	if (IsTracking())
1447 		SetTracking(false);
1448 	uint32 value = fCurrentMouseKey;
1449 	fCurrentMouseKey = 0;
1450 	DrawKey(value);
1451 }
1452 
1453 
1454 void
1455 MapView::MouseMoved(BPoint point, uint32 transit, const BMessage *msg)
1456 {
1457 	if (IsTracking()) {
1458 		uint32 value = fCurrentMouseKey;
1459 		for (int32 i=0; i<128; i++) {
1460 			if (fKeysRect[i].Contains(point) && !fKeysRect[value].Contains(point)) {
1461 				fCurrentMouseKey = i;
1462 				DrawKey(value);
1463 				DrawKey(fCurrentMouseKey);
1464 				char *str = NULL;
1465 				int32 numBytes;
1466 				fCurrentMap->GetChars(fCurrentMouseKey, fOldKeyInfo.modifiers, fActiveDeadKey, &str, &numBytes);
1467 				if (numBytes>0) {
1468 					fTextView->FakeKeyDown(str, numBytes);
1469 					delete str;
1470 				}
1471 				break;
1472 			}
1473 		}
1474 	}
1475 	BControl::MouseMoved(point, transit, msg);
1476 }
1477 
1478 
1479 void
1480 MapView::SetFontFamily(const font_family family)
1481 {
1482 	fCurrentFont.SetFamilyAndStyle(family, NULL);
1483 	fTextView->SetFontAndColor(&fCurrentFont);
1484 };
1485