blob: 0b76245fd4e80934e55aacea4e70bf02d2270548 [file] [log] [blame]
Bram Moolenaar071d4272004-06-13 20:20:40 +00001/* vi:set ts=8 sts=4 sw=4:
2 *
3 * VIM - Vi IMproved by Bram Moolenaar
4 * Amiga GUI support by Michael Nielsen
5 *
6 * Do ":help uganda" in Vim to read copying and usage conditions.
7 * Do ":help credits" in Vim to see a list of people who contributed.
8 * See README.txt for an overview of the Vim source code.
9 */
10
11#include <stdlib.h>
12#include <string.h>
13#include <exec/types.h>
14#include <intuition/intuition.h>
15#include <utility/tagitem.h>
16#include <graphics/text.h>
17#include <graphics/rastport.h>
18#include <graphics/layers.h>
19#include <proto/intuition.h>
20#include <proto/graphics.h>
21#include <proto/layers.h>
22#include <devices/timer.h>
23#include <assert.h>
24#include "vim.h"
25#include "gui_amiga.h"
26#include <math.h>
27#include <limits.h>
28
29#ifdef __AROS__
30#include <aros/debug.h>
31#endif
32
33#include "version.h"
34
35#if defined(FEAT_GUI_AMIGA) || defined(PROTO)
36
37#define KEYUP 76
38#define KEYDOWN 77
39#define KEYRIGHT 78
40#define KEYLEFT 79
41#define KEYBACKSPACE 0x41
42#define KEYDELETE 0x46
43#define KEYINSERT 0x47
44#define KEYHOME 0x70
45#define KEYEND 0x71
46#define KEYWHEELUP 0x7A
47#define KEYWHEELDOWN 0x7B
48
49/* When generating prototypes on Unix, these need to be defined */
50#ifdef PROTO
51# define STRPTR char *
52# define BOOL int
53# define UBYTE int
54#endif
55
56static struct PropInfo Gadget2SInfo = { AUTOKNOB+PROPBORDERLESS+FREEVERT+PROPNEWLOOK, 0, 0, MAXBODY, MAXBODY, };
57//static struct Image Image1 = { 0, 0, 10, 397, 0, NULL, 0x0000, 0x0000, NULL };
58static struct Gadget propGadget = { NULL, -12, 15, 10, -28,
59 GFLG_RELRIGHT+GFLG_RELHEIGHT,
60 GACT_RELVERIFY+GACT_RIGHTBORDER+GACT_IMMEDIATE,
61 GTYP_PROPGADGET+GTYP_GZZGADGET,
62 NULL, NULL,
63 NULL, NULL, (APTR)&Gadget2SInfo, NULL, NULL };
64
65static struct timerequest *TimerIO;
66static struct MsgPort *TimerMP;
67static BOOL TimerSent;
68
69struct GFXBase *gfxBase;
70struct ExecBase *execBase;
71struct LayersBase *layersBase;
72
73struct MyColor
74{
75 WORD pen;
76 BOOL alloced;
77};
78
79struct MyColor MyColorTable[256];
80
81struct TagItem tags[] =
82{
83 {WA_Left, 0},
84 {WA_Top, 0},
85 {WA_Width, 400},
86 {WA_Height, 400},
87 {WA_Title, (ULONG)VIM_VERSION_SHORT},
88 {WA_ScreenTitle, (ULONG)VIM_VERSION_LONG},
89 {WA_DragBar, TRUE}, /* enable dragging of the window */
90 {WA_DepthGadget, TRUE}, /* enable the depth gadget */
91 {WA_CloseGadget, TRUE}, /* enable the close gadget*/
92 {WA_SizeGadget, TRUE}, /* enable the size gadget */
93 {WA_SizeBBottom, TRUE}, /* sizegadget contained in bottom border */
94 {WA_SmartRefresh, TRUE}, /* choose smart refresh, saves us doing a lot of work */
95 {WA_ReportMouse, TRUE}, /* Report the position of the mouse */
96 {WA_GimmeZeroZero, TRUE},
97 {WA_Activate, TRUE}, /* Activate window on startup */
98 {WA_Activate, TRUE}, /* Activate window on startup */
99 {WA_NoCareRefresh, TRUE}, /* Refresh screen, don't tell us */
100 {WA_NewLookMenus, TRUE}, /* use the new options for the menu */
101 {WA_AutoAdjust, TRUE}, /* If window is too big for screen adjust size*/
102 {WA_NoCareRefresh, TRUE}, /* If window is too big for screen adjust size*/
103 {WA_MouseQueue, 1}, /* Limit number of pending mouse movement*/
104 {WA_RptQueue, 10}, /* Limit number of pending keystrokes*/
105 {WA_IDCMP, /* IDCMP, what events interest us */
106 IDCMP_NEWSIZE /* Notify us about size change of window*/
107 |IDCMP_REFRESHWINDOW /* Notify us when the window needs refreshing */
108 |IDCMP_MOUSEBUTTONS /* Notify us when the mouse buttons have been used */
109 |IDCMP_MOUSEMOVE /* Notify us when the mouse is moving */
110 |IDCMP_GADGETDOWN /* Notify us when a gadget has been selected */
111 |IDCMP_GADGETUP /* Notify us when a gadget has been released */
112 |IDCMP_MENUPICK /* Notify us when a menu has been picked */
113 |IDCMP_CLOSEWINDOW /* Notify us when the user tries to close the window */
114 |IDCMP_VANILLAKEY /* Notify us about keystrokes */
115 |IDCMP_RAWKEY /* Notify us when raw key events have been used, ie cursor*/
116 |IDCMP_INTUITICKS /* Simpler timer for the blink option */
117 |IDCMP_MENUHELP /* Allow the help key to be used during menu events */
118 |IDCMP_GADGETHELP /* Allow the help key to be used during gadget events */
119 |IDCMP_INACTIVEWINDOW /* notify of inactive window */
120 |IDCMP_ACTIVEWINDOW /* notify of inactive window */
121 },
122 {TAG_DONE, NULL}
123};
124
125#if defined(D)
126#undef D
127#endif
128
129/*#define D(_msg) fprintf(stderr, "%s\n", _msg)*/
130
131#define D(_A)
132#define kprintf(s, ...)
133
134static void AmigaError(const char *string);
135
136void HandleEvent(unsigned long * object);
137static UBYTE getrealcolor(guicolor_T i);
138
139static struct NewWindow vimNewWindow =
140{
141 0, 0, /* window XY origin relative to TopLeft of screen */
142 0, 0, /* window width and height */
143 0, 1, /* detail and block pens */
144 NULL, /* IDCMP flags */
145 NULL, /* other window flags */
146 &propGadget, /* first gadget in gadget list */
147 NULL, /* custom CHECKMARK imagery */
148 "Amiga Vim gui", /* window title */
149 NULL, /* custom screen pointer */
150 NULL, /* custom bitmap */
151 50, 50, /* minimum width and height */
152 (unsigned short)-1, (unsigned short)-1, /* maximum width and height */
153 WBENCHSCREEN /* destination screen type */
154};
155
156static struct
157{
158 unsigned int key_sym;
159 char_u vim_code0;
160 char_u vim_code1;
161} special_keys[] =
162{
163 {0, 0, 0}
164};
165
166#if 0
167 /* not used? */
168 static int
169hex_digit(int c)
170{
171 if (isdigit(c))
172 return c - '0';
173 c = TOLOWER_ASC(c);
174 if (c >= 'a' && c <= 'f')
175 return c - 'a' + 10;
176 return -1000;
177}
178#endif
179
180static int characterWidth = -1;
181static int characterHeight = -1;
182static struct
183{
184 BOOL active;
185 enum
186 {
187 CursorOff,
188 CursorOn,
189 CursorWait
190 } state;
191 int onTime;
192 int offTime;
193 int waitTime;
194 int current;
195} cursor =
196{
197 TRUE,
198 CursorWait,
199 10,
200 10,
201 7,
202 0
203};
204
205enum DrawBoxMode
206{
207 DB_Filled,
208 DB_NotFilled
209};
210
211 static void
212TextDimensions(void)
213{
214 struct TextExtent textExt;
215
216 TextExtent(gui.window->RPort, "s", 1, &textExt);
217
218 characterWidth = textExt.te_Width;
219 characterHeight = textExt.te_Height;
220}
221
222 static int
223posWidthCharToPoint(int width)
224{
225 return (width)*characterWidth;
226}
227
228 static int
229posHeightCharToPoint(int height)
230{
231 return (int)(height)*characterHeight;
232}
233
234 static int
235posWidthPointToChar(int width)
236{
237 //return (int)floor((float)width/(float)characterWidth)-1;
238 return width /characterWidth;
239}
240
241 static int
242posHeightPointToChar(int height)
243{
244 //return (int)floor((float)height/(float)characterHeight)-2;
245 return height / characterHeight;
246}
247
248 static int
249widthCharToPoint(int width)
250{
251 return (width)*(characterWidth);
252}
253
254 static int
255heightCharToPoint(int height)
256{
257 return (height)*characterHeight;
258}
259
260 static int
261widthPointToChar(int width)
262{
263 return (width)/characterWidth;
264}
265
266 static int
267heightPointToChar(int height)
268{
269 return (height)/characterHeight;
270}
271
272 static void
273refreshBorder(void)
274{
275 /*WaitBOVP(gui.window->);*/
276 RefreshWindowFrame(gui.window);
277}
278
279 static void
280drawBox(enum DrawBoxMode mode, unsigned short col, unsigned short row, int w, int h, guicolor_T color)
281{
282 LONG apen = GetAPen(gui.window->RPort);
283 LONG x1, y1, x2, y2;
284
285kprintf(" drawbox %d,%d color %d\n", col, row, color);
286
287 SetAPen(gui.window->RPort, getrealcolor(color));
288
289 x1 = posWidthCharToPoint(col);
290 y1 = posHeightCharToPoint(row + 1) - h;
291 x2 = x1 + w - 1;
292 y2 = posHeightCharToPoint(row + 1) - 1;
293
294 switch(mode)
295 {
296 case DB_Filled:
297 RectFill(gui.window->RPort, x1, y1, x2, y2);
298 break;
299
300 case DB_NotFilled:
301 Move(gui.window->RPort, x1, y1);
302 Draw(gui.window->RPort, x2, y1);
303 Draw(gui.window->RPort, x2, y2);
304 Draw(gui.window->RPort, x1, y2);
305 Draw(gui.window->RPort, x1, y1);
306 break;
307 }
308
309 SetAPen(gui.window->RPort, apen);
310
311}
312
313 static enum event
314EventHandler(void)
315{
316 struct IntuiMessage *msg;
317 enum event returnEvent = ev_Ignore;
318 int class, code;
319 static int dragging = 0;
320 static int mouseX, mouseY;
321 char_u string[40];
322 BOOL quit_request = FALSE;
323
324 msg = (struct IntuiMessage *)GetMsg(gui.window->UserPort);
325
326 if (!msg)
327 {
328 returnEvent = ev_NullEvent;
329 }
330 else
331 {
332
333 class = msg->Class;
334 code = msg->Code;
335
336 switch(class)
337 {
338 case IDCMP_INTUITICKS:
339 /*
340 if (cursor.active)
341 {
342 cursor.current ++;
343 if (cursor.state == CursorOff)
344 {
345 printf("cursor turned on\n");
346 if (cursor.offTime < cursor.current)
347 {
348 gui_undraw_cursor();
349 cursor.state = CursorOn;
350 cursor.current = 0;
351 }
352 }
353 else if (cursor.state == CursorOn)
354 {
355 printf("cursor turned off\n");
356 if (cursor.onTime < cursor.current)
357 {
358 cursor.state = CursorOff;
359 gui_update_cursor(FALSE);
360 cursor.current = 0;
361 }
362 }
363 else if (cursor.state == CursorWait)
364 {
365 printf("cursor turned Wait\n");
366 if (cursor.waitTime < cursor.current)
367 {
368 cursor.state = CursorOn;
369 cursor.current = 0;
370 }
371 }
372 }
373 else
374 {
375 }
376 returnEvent = ev_IntuiTicks;
377 */
378 break;
379
380 case IDCMP_MOUSEBUTTONS:
381 {
382 int vim_modifiers=0;
383 D("Mouse button event detected");
384 switch (msg->Qualifier )
385 {
386 case IEQUALIFIER_LALT:
387 case IEQUALIFIER_RALT:
388 D("detected a Alt key");
389 vim_modifiers|=MOUSE_ALT;
390 break;
391
392 case IEQUALIFIER_LSHIFT:
393 case IEQUALIFIER_RSHIFT:
394 D("detected a Shift key");
395 vim_modifiers|=MOUSE_SHIFT;
396 break;
397 case IEQUALIFIER_CONTROL:
398 D("detected a Control key");
399 vim_modifiers |= MOUSE_CTRL;
400 break;
401 }
402 if (code == SELECTDOWN)
403 {
404 D("Select Down detected\n");
405 dragging = 1;
406 gui_send_mouse_event(MOUSE_LEFT,
407 mouseX = msg->MouseX - gui.window->BorderLeft,
408 mouseY = msg->MouseY - gui.window->BorderTop,
409 FALSE,
410 vim_modifiers);
411 /*gui_start_highlight(HL_ALL);*/
412 }
413 else if (code == SELECTUP)
414 {
415 D("Select UP detected\n");
416 dragging = 0;
417 gui_send_mouse_event(MOUSE_RELEASE,
418 msg->MouseX - gui.window->BorderLeft,
419 msg->MouseY - gui.window->BorderTop,
420 FALSE, vim_modifiers);
421 /*gui_stop_highlight(mask);*/
422 }
423 returnEvent = ev_MouseButtons;
424 break;
425 }
426 case IDCMP_MOUSEMOVE:
427 if ((abs(mouseX-(msg->MouseX - gui.window->BorderLeft)) > characterWidth) ||
428 (abs(mouseY-(msg->MouseY - gui.window->BorderTop))>characterHeight))
429 {
430 int vim_modifiers=0;
431
432 switch (msg->Qualifier )
433 {
434 case IEQUALIFIER_LALT:
435 case IEQUALIFIER_RALT:
436 D("detected a Alt key");
437 vim_modifiers|=MOUSE_ALT;
438 break;
439
440 case IEQUALIFIER_LSHIFT:
441 case IEQUALIFIER_RSHIFT:
442 D("detected a Shift key");
443 vim_modifiers|=MOUSE_SHIFT;
444 break;
445 case IEQUALIFIER_CONTROL:
446 D("detected a Control key");
447 vim_modifiers |= MOUSE_CTRL;
448 break;
449 }
450
451 mouseX = msg->MouseX - gui.window->BorderLeft;
452 mouseY = msg->MouseY - gui.window->BorderTop;
453 if (!dragging)
454 {
455 gui_send_mouse_event(MOUSE_SETPOS, mouseX, mouseY, FALSE, vim_modifiers);
456 break;
457 }
458 else
459 {
460 D("dragging\n");
461 gui_send_mouse_event(MOUSE_DRAG, mouseX, mouseY, FALSE, vim_modifiers);
462 }
463 }
464 returnEvent = ev_MouseMove;
465 break;
466 case IDCMP_VANILLAKEY:
467kprintf("===vanillakey %d\n", code);
468 {
469 string[0] = (char_u)code;
470 if (code == CSI)
471 {
472 /* Insert CSI as K_CSI. Untested! */
473 string[1] = KS_EXTRA;
474 string[2] = (int)KE_CSI;
475 add_to_input_buf(string, 3);
476 }
477 else if (code == 8)
478 {
479 string[0] = CSI;
480 string[1] = 'k';
481 string[2] = 'b';
482 add_to_input_buf(string, 3);
483 }
484 else if (code == 127)
485 {
486 string[0] = CSI;
487 string[1] = 'k';
488 string[2] = 'D';
489 add_to_input_buf(string, 3);
490 }
491 else
492 {
493 int len = 1;
494
495 if (input_conv.vc_type != CONV_NONE)
496 len = convert_input(string, 1, sizeof(string));
497 add_to_input_buf(string, len);
498 }
499 returnEvent = ev_KeyStroke;
500 break;
501
502 case IDCMP_RAWKEY:
503 if (msg->Qualifier & IEQUALIFIER_LSHIFT)
504 {
505 }
506 else if (msg->Qualifier & IEQUALIFIER_RSHIFT)
507 {
508 }
509 else if (msg->Qualifier & IEQUALIFIER_CONTROL)
510 {
511 if (code == 33)
512 {
513 trash_input_buf();
514 }
515 }
516 else if (msg->Code == KEYUP)
517 {
518 string[0] = CSI;
519 string[1] = 'k';
520 string[2] = 'u';
521 add_to_input_buf(string, 3);
522 }
523 else if (msg->Code == KEYLEFT)
524 {
525 string[0] = CSI;
526 string[1] = 'k';
527 string[2] = 'l';
528 add_to_input_buf(string, 3);
529 }
530 else if (msg->Code == KEYRIGHT)
531 {
532kprintf("## keyright");
533 string[0] = CSI;
534 string[1] = 'k';
535 string[2] = 'r';
536 add_to_input_buf(string, 3);
537 }
538 else if (msg->Code == KEYDOWN)
539 {
540 string[0] = CSI;
541 string[1] = 'k';
542 string[2] = 'd';
543 add_to_input_buf(string, 3);
544 }
545 else if (msg->Code == KEYBACKSPACE)
546 {
547 string[0] = CSI;
548 string[1] = 'k';
549 string[2] = 'b';
550 add_to_input_buf(string, 3);
551 }
552 else if (msg->Code == KEYDELETE)
553 {
554 string[0] = CSI;
555 string[1] = 'k';
556 string[2] = 'D';
557 add_to_input_buf(string, 3);
558 }
559 else if (msg->Code == KEYINSERT)
560 {
561 string[0] = CSI;
562 string[1] = 'k';
563 string[2] = 'I';
564 add_to_input_buf(string, 3);
565 }
566 else if (msg->Code == KEYHOME)
567 {
568 string[0] = CSI;
569 string[1] = 'k';
570 string[2] = 'h';
571 add_to_input_buf(string, 3);
572 }
573 else if (msg->Code == KEYEND)
574 {
575 string[0] = CSI;
576 string[1] = '@';
577 string[2] = '7';
578 add_to_input_buf(string, 3);
579 }
580 else if (msg->Code == KEYWHEELUP)
581 {
582 int vim_modifiers=0;
583
584 switch (msg->Qualifier )
585 {
586 case IEQUALIFIER_LALT:
587 case IEQUALIFIER_RALT:
588 D("detected a Alt key");
589 vim_modifiers|=MOUSE_ALT;
590 break;
591
592 case IEQUALIFIER_LSHIFT:
593 case IEQUALIFIER_RSHIFT:
594 D("detected a Shift key");
595 vim_modifiers|=MOUSE_SHIFT;
596 break;
597 case IEQUALIFIER_CONTROL:
598 D("detected a Control key");
599 vim_modifiers |= MOUSE_CTRL;
600 break;
601 }
602 gui_send_mouse_event(MOUSE_4, 0, 1, FALSE, vim_modifiers);
603
604 }
605 else if (msg->Code == KEYWHEELDOWN)
606 {
607 int vim_modifiers=0;
608
609 switch (msg->Qualifier )
610 {
611 case IEQUALIFIER_LALT:
612 case IEQUALIFIER_RALT:
613 D("detected a Alt key");
614 vim_modifiers|=MOUSE_ALT;
615 break;
616
617 case IEQUALIFIER_LSHIFT:
618 case IEQUALIFIER_RSHIFT:
619 D("detected a Shift key");
620 vim_modifiers|=MOUSE_SHIFT;
621 break;
622 case IEQUALIFIER_CONTROL:
623 D("detected a Control key");
624 vim_modifiers |= MOUSE_CTRL;
625 break;
626 }
627 gui_send_mouse_event(MOUSE_5, 0, 1, FALSE, vim_modifiers);
628 }
629
630 returnEvent = ev_KeyStroke;
631 break;
632 }
633 case IDCMP_MENUVERIFY:
634 returnEvent = ev_MenuVerify;
635 /* Menu verification requested */
636 switch (code)
637 {
638 case MENUWAITING:
639 /*
640 ** It's not for us, the user is accessing another
641 ** programs menu, this is a good time to do some
642 ** cleanup etc
643 */
644 break;
645 case MENUHOT:
646 /*
647 ** It is our menu that is going hot, we have kontrol
648 ** Menu action can be cancelled by
649 ** msg->Code = MENUCANCEL;
650 */
651 break;
652 default:
653 break;
654 }
655 break;
656 case IDCMP_MENUPICK:
657 returnEvent = ev_MenuPick;
658 {
659 /*
660 ** one of our menu's have been selected, let's find out which
661 */
662 union myMenuItemUnion *item;
663 int menuNumber;
664
665 menuNumber = code;
666
667 item = (union myMenuItemUnion *) ItemAddress(gui.menu, menuNumber);
668
669
670 if (item)
671 {
672 gui_menu_cb(item->myMenuItem.guiMenu);
673 }
674 }
675 break;
676 case IDCMP_CLOSEWINDOW:
677 quit_request = TRUE;
678 break;
679
680 case IDCMP_NEWSIZE:
681 {
682 int cx, cy;
683 //cx = widthPointToChar(gui.window->GZZWidth);
684 //cy = heightPointToChar(gui.window->GZZHeight);
685
686 cx = gui.window->GZZWidth;
687 cy = gui.window->GZZHeight - characterHeight;
688
689 gui_resize_shell(cx, cy);
690
691 returnEvent = ev_NewSize;
692 break;
693 }
694 case IDCMP_REFRESHWINDOW:
695 refreshBorder();
696 returnEvent = ev_RefreshWindow;
697 break;
698 case IDCMP_GADGETDOWN:
699 returnEvent = ev_GadgetDown;
700 break;
701 case IDCMP_GADGETUP:
702 returnEvent = ev_GadgetUp;
703 break;
704 case IDCMP_MENUHELP:
705 returnEvent = ev_MenuHelp;
706 break;
707 case IDCMP_GADGETHELP:
708 returnEvent = ev_GadgetHelp;
709 break;
710 case IDCMP_INACTIVEWINDOW:
711 gui.in_focus = FALSE;
712 gui_update_cursor(TRUE, FALSE);
713 break;
714
715 case IDCMP_ACTIVEWINDOW:
716 gui.in_focus = TRUE;
717 gui_update_cursor(TRUE, FALSE);
718 break;
719 default:
720 break;
721 }
722 ReplyMsg((struct Message*)msg);
723 }
724
725 if (quit_request)
726 {
727 getout(0); // gui_mch_exit(1);
728 }
729
730 return returnEvent;
731 /* mouse positin gui.window->MoseY, gui.window->MouseX) */
732}
733
734 static int
735checkEventHandler(void)
736{
737 enum event happened;
738
739 do
740 {
741 happened = EventHandler() ;
742 }
743 while (happened != ev_NullEvent);
744
745 return OK;
746}
747
748 static int
749charEventHandler(int wtime)
750{
751 enum event happened;
752 int rc;
753
754 do
755 {
756 Wait(1<<gui.window->UserPort->mp_SigBit);
757
758 happened = EventHandler() ;
759 }
760 while ((happened != ev_IntuiTicks) && (happened != ev_KeyStroke) && (happened != ev_MenuPick) && (happened != ev_MouseMove) &&(happened != ev_MouseButtons) );
761
762 if (happened == ev_KeyStroke || happened == ev_MenuPick)
763 rc = OK;
764 else
765 rc = FAIL;
766
767 return rc;
768}
769
770
771/*
772 * add primary menu
773 */
774 void
775gui_mch_add_menu_item(vimmenu_T *menu, int idx)
776{
777 union myMenuItemUnion *menuItemUnion = NULL;
778 struct IntuiText *menutext = NULL;
779 vimmenu_T *parent;
780
781 assert(menu != NULL);
782 assert(menu->parent != NULL);
783 parent = menu->parent;
784
785 /* Don't add menu separator */
786 if (menu_is_separator(menu->name))
787 return;
788
789 if (parent->menuItemPtr == NULL)
790 return;
791
792 /* TODO: use menu->mnemonic and menu->actext */
793 menutext = (struct IntuiText *) malloc(sizeof(struct IntuiText));
794
795 SetAttrib(menutext, FrontPen, 3);
796 SetAttrib(menutext, BackPen, 1);
797 SetAttrib(menutext, DrawMode, COMPLEMENT);
798 SetAttrib(menutext, LeftEdge, 0);
799 SetAttrib(menutext, TopEdge, 0);
800 SetAttrib(menutext, ITextFont, NULL);
801 SetAttrib(menutext, NextText, NULL);
802
803 menuItemUnion = malloc(sizeof(*menuItemUnion));
804
805 SetAttrib(&menuItemUnion->menuItem, NextItem, parent->menuItemPtr);
806 SetAttrib(&menuItemUnion->menuItem, LeftEdge, 0);
807 SetAttrib(&menuItemUnion->menuItem, Width, characterWidth*strlen(menu->dname));
808 SetAttrib(&menuItemUnion->menuItem, Height, characterHeight+2);
809 SetAttrib(&menuItemUnion->menuItem, Flags, ITEMTEXT+ITEMENABLED+HIGHCOMP);
810 SetAttrib(&menuItemUnion->menuItem, MutualExclude, 0);
811 SetAttrib(&menuItemUnion->menuItem, ItemFill, (APTR)menutext);
812 SetAttrib(&menuItemUnion->menuItem, SelectFill, NULL);
813 SetAttrib(&menuItemUnion->menuItem, Command, NULL);
814 SetAttrib(&menuItemUnion->menuItem, SubItem, NULL);
815 SetAttrib(&menuItemUnion->menuItem, NextSelect, MENUNULL);
816
817 menutext->IText = malloc(strlen(menu->dname) + 1);
818
819 strcpy(menutext->IText, menu->dname);
820
821 menuItemUnion->menuItem.NextItem = NULL;
822
823
824 if (parent)
825 {
826 if (!parent->menuItemPtr)
827 {
828 D("Adding first subElement");
829 SetAttrib(&menuItemUnion->menuItem, TopEdge, 0);
830 parent->menuPtr->FirstItem = &menuItemUnion->menuItem;
831 parent->menuItemPtr = &menuItemUnion->menuItem;
832 }
833 else
834 {
835 struct MenuItem *tmpMenuItem;
836 tmpMenuItem = parent->menuItemPtr;
837 while (tmpMenuItem->NextItem)
838 {
839 tmpMenuItem = tmpMenuItem->NextItem;
840 }
841 tmpMenuItem->NextItem = &menuItemUnion->menuItem;
842 SetAttrib(&menuItemUnion->menuItem, TopEdge, tmpMenuItem->TopEdge+tmpMenuItem->Height);
843 }
844 }
845 menu->menuPtr= NULL;
846 menu->menuItemPtr = &menuItemUnion->menuItem;
847 menuItemUnion->myMenuItem.guiMenu = menu;
848}
849
850
851 static struct Menu *
852getMenu(struct RastPort *rast, int left, STRPTR name)
853{
854 struct Menu *menu;
855 struct TextExtent textExt;
856
857 menu = malloc(sizeof(*menu));
858 menu->NextMenu = NULL;
859 menu->LeftEdge = left;
860
861 TextExtent(rast, name, strlen(name), &textExt);
862
863 menu->TopEdge = 0;
864 menu->Width = textExt.te_Width;
865 menu->Height = textExt.te_Height;
866 menu->Flags = ITEMTEXT+HIGHCOMP+MENUENABLED;
867 menu->MenuName = name;
868 menu->FirstItem = NULL;
869
870 return menu;
871}
872
873/*
874 * add 1st level submenu item
875 */
876 void
877gui_mch_add_menu(vimmenu_T *menu, int idx)
878{
879 struct Menu *newMenu;
880 int pos = 0;
881
882 if (!menu_is_menubar(menu->name))
883 return;
884
885 menu->menuPtr = newMenu = getMenu(gui.window->RPort, 0, menu->dname);
886 menu->menuItemPtr = NULL;
887 newMenu->NextMenu = NULL;
888
889 if (!gui.menu)
890 {
891 D("Adding head menu");
892 gui.menu = newMenu ;
893 }
894 else
895 {
896 struct Menu *tmpMenu;
897
898 tmpMenu = gui.menu;
899 while (tmpMenu->NextMenu)
900 tmpMenu = tmpMenu->NextMenu;
901 tmpMenu->NextMenu = newMenu;
902 pos = tmpMenu->LeftEdge +
903 TextLength(gui.window->RPort, tmpMenu->MenuName,
904 strlen(tmpMenu->MenuName));
905 newMenu->LeftEdge = pos;
906 }
907}
908
909 void
910gui_mch_toggle_tearoffs(enable)
911 int enable;
912{
913 /* no tearoff menus */
914}
915
916 int
917gui_mch_set_blinking(long wait, long on, long off)
918{
919 cursor.waitTime = wait/100;
920 cursor.onTime = on/100;
921 cursor.offTime = off/100;
922 return OK;
923}
924
925 void
926gui_mch_prepare(int *argc, char **argv)
927{
928 D("gui_mch_prepare");
929
930 execBase = (struct ExecBase *)OpenLibrary("exec.library", NULL);
931 gfxBase = (struct GFXBase *)OpenLibrary("graphics.library", NULL);
932 layersBase = (struct LayersBase *)OpenLibrary("layers.library", NULL);
933
934 if (!execBase)
935 {
936 D("Cannot open exec.library, aborting");
937 }
938 if (!gfxBase)
939 {
940 D("Cannot open graphics.library, aborting");
941 }
942 if (!layersBase)
943 {
944 D("Cannot open graphics.library, aborting");
945 }
946 D("gui_mch_prepare done ");
947}
948
949 void
950atexitDoThis(void)
951{
952kprintf("atexitdothis###\n");
953 gui_mch_exit(-1);
954}
955
956/*
957 * Check if the GUI can be started. Called before gvimrc is sourced.
958 * Return OK or FAIL.
959 */
960 int
961gui_mch_init_check(void)
962{
963 if (execBase && gfxBase && layersBase)
964 return OK;
965 return FAIL;
966}
967
968 int
969gui_mch_init(void)
970{
971 int returnCode = FAIL; /* assume failure*/
972
973 TimerMP = CreateMsgPort();
974 if (!TimerMP) return FAIL;
975
976 TimerIO = (struct timerequest *)CreateIORequest(TimerMP, sizeof(*TimerIO));
977 if (!TimerIO) return FAIL;
978
979 if (OpenDevice("timer.device", UNIT_VBLANK, &TimerIO->tr_node, 0)) return FAIL;
980
981 gui.window = OpenWindowTagList(&vimNewWindow, tags);
982 if (gui.window)
983 {
984 gui.in_use = TRUE;
985 gui.in_focus=TRUE;
986 gui.norm_pixel = gui.def_norm_pixel = 1;
987 gui.back_pixel = gui.def_back_pixel = 0;
988
989 set_normal_colors();
990 gui_check_colors();
991
992 SetDrMd(gui.window->RPort, JAM2);
993 gui_mch_set_colors(gui.norm_pixel, gui.back_pixel);
994
995 atexit(atexitDoThis);
996
997 TextDimensions();
998 returnCode = OK; /* we've had success */
999 if (gui_win_x != -1 && gui_win_y != -1)
1000 gui_mch_set_winpos(gui_win_x, gui_win_y);
1001
1002 gui_mch_clear_all();
1003
1004 }
1005 gui.menu = NULL;
1006
1007 return returnCode;
1008}
1009
1010 void
1011gui_mch_new_colors(void)
1012{
1013kprintf("### gui_mch_new_colors\n");
1014 SetAPen(gui.window->RPort, getrealcolor(gui.norm_pixel));
1015 SetBPen(gui.window->RPort, getrealcolor(gui.back_pixel));
1016
1017 D("gui_mch_new_colors");
1018}
1019
1020 int
1021gui_mch_open(void)
1022{
1023 D("gui_mch_open");
1024
1025 highlight_gui_started();
1026 return OK;
1027}
1028
1029 void
1030gui_mch_exit(int returnCode)
1031{
1032kprintf("###gui_mch_exit\n");
1033 D("****gui_mch_exit");
1034
1035 if (TimerSent)
1036 {
1037 if (!CheckIO(&TimerIO->tr_node)) AbortIO(&TimerIO->tr_node);
1038 WaitIO(&TimerIO->tr_node);
1039 TimerSent = FALSE;
1040 }
1041
1042 if (TimerIO)
1043 {
1044 CloseDevice(&TimerIO->tr_node);
1045 DeleteIORequest(&TimerIO->tr_node);
1046 TimerIO = NULL;
1047 }
1048
1049 if (TimerMP)
1050 {
1051 DeleteMsgPort(TimerMP);
1052 TimerMP = NULL;
1053 }
1054
1055 if (gui.window)
1056 {
1057 int i;
1058
1059 for(i = 0; i < sizeof(MyColorTable) / sizeof(MyColorTable[0]); i++)
1060 {
1061 if (MyColorTable[i].alloced)
1062 {
1063 ReleasePen(gui.window->WScreen->ViewPort.ColorMap, MyColorTable[i].pen);
1064 MyColorTable[i].alloced = FALSE;
1065 }
1066 }
1067
1068 D("Closeing window ");
1069 CloseWindow(gui.window);
1070 CloseLibrary((struct Library*)execBase);
1071 CloseLibrary((struct Library*)gfxBase);
1072 gui.window = NULL;
1073 gui.in_use = FALSE;
1074 //getout(1);
1075 }
1076}
1077
1078/*
1079 * Get the position of the top left corner of the window.
1080 */
1081 int
1082gui_mch_get_winpos(int *x, int *y)
1083{
1084 if (gui.window)
1085 {
1086 *x = gui.window->LeftEdge;
1087 *y = gui.window->TopEdge;
1088 }
1089 else
1090 {
1091 return FAIL;
1092 }
1093
1094 return OK;
1095}
1096
1097/*
1098 * Set the position of the top left corner of the window to the given
1099 * coordinates.
1100 */
1101 void
1102gui_mch_set_winpos(int x, int y)
1103{
1104 if (gui.window)
1105 {
1106 ChangeWindowBox(gui.window, x, y, gui.window->Width, gui.window->Height);
1107 }
1108}
1109
1110 void
1111gui_mch_set_shellsize(int width, int height,
1112 int min_width, int min_height, int base_width, int base_height)
1113{
1114 D("gui_mch_set_shellsize");
1115
1116 ChangeWindowBox(gui.window, gui.window->LeftEdge,
1117 gui.window->TopEdge, widthCharToPoint(width) + gui.window->BorderLeft + gui.window->BorderRight,
1118 heightCharToPoint(height) + gui.window->BorderTop + gui.window->BorderBottom);
1119 checkEventHandler();
1120}
1121
1122 void
1123gui_mch_get_screen_dimensions(int *screen_w, int *screen_h)
1124{
1125// *screen_w = widthPointToChar(gui.window->GZZWidth);
1126// *screen_h = heightPointToChar(gui.window->GZZHeight);
1127 *screen_w = gui.window->GZZWidth;
1128 *screen_h = gui.window->GZZHeight - characterHeight;
1129
1130
1131kprintf("=== get_screen_dimensions: screen %d,%d character %d,%d console %d,%d\n",
1132gui.window->GZZWidth,
1133gui.window->GZZHeight,
1134characterWidth,
1135characterHeight,
1136*screen_w,
1137*screen_h);
1138
1139}
1140
1141 void
1142gui_mch_set_text_area_pos(int x, int y, int w, int h)
1143{
1144 D("gui_mch_set_text_area_pos");
1145}
1146
1147 void
1148gui_mch_enable_scrollbar(scrollbar_T *sb, int flag)
1149{
1150 /* done by default */
1151 /* TODO: disable scrollbar when it's too small */
1152}
1153
1154 void
1155gui_mch_set_scrollbar_thumb(scrollbar_T *sb, long val, long size, long max)
1156{
1157 ULONG total = max;
1158 ULONG visible = size;
1159 ULONG top = val;
1160 ULONG hidden;
1161 ULONG overlap = 0;
1162 UWORD body, pot;
1163
1164kprintf("__set_scrollbar_thumb val %d size %d max %d\n", val, size, max);
1165
1166 if (total > visible)
1167 hidden = total - visible;
1168 else
1169 hidden = 0;
1170
1171 if (top > hidden)
1172 top = hidden;
1173
1174 body = (hidden > 0) ?
1175 (UWORD)(((ULONG)(visible - overlap) * MAXBODY) / (total - overlap)) :
1176 MAXBODY;
1177
1178 pot = (hidden > 0) ? (UWORD)(((ULONG) top * MAXPOT) / hidden) : 0;
1179
1180kprintf("__pot %x body %x\n", pot, body);
1181
1182 NewModifyProp(&propGadget, gui.window, NULL,
1183 Gadget2SInfo.Flags,
1184 MAXPOT, pot,
1185 MAXBODY, body,
1186 1);
1187 return;
1188
1189}
1190
1191 void
1192gui_mch_set_scrollbar_pos(scrollbar_T *sb, int x, int y, int w, int h)
1193{
1194 D("gui_mch_set_scrollbar_pos");
1195 /*NewModifyProp(&propGadget, gui.window, NULL, MAXPOT, MAXPOT/sb->max*y, MAXPOT, MAXBODY/sb->max/sb->size, 1);*/
1196}
1197
1198 void
1199gui_mch_create_scrollbar(scrollbar_T *sb, int orient)
1200{
1201 /* this is done by default */
1202}
1203
1204#if defined(FEAT_WINDOWS) || defined(PROTO)
1205 void
1206gui_mch_destroy_scrollbar(scrollbar_T *sb)
1207{
1208 /* this is done by default */
1209}
1210#endif
1211
Bram Moolenaard8b0cf12004-12-12 11:33:30 +00001212char_u *gui_mch_getfontname(GuiFont font)
1213{
1214 return vim_strsave((char_u *)"default");
1215}
1216
Bram Moolenaar071d4272004-06-13 20:20:40 +00001217int gui_mch_init_font(char_u *font_name, int fontset)
1218{
1219 /*D("gui_mch_init_font");*/
1220
1221 gui.char_width = characterWidth;
1222 gui.char_height = characterHeight;
1223 gui.char_ascent = gui.window->RPort->TxBaseline;
1224
1225 return OK;
1226}
1227
1228 int
1229gui_mch_adjust_charsize()
1230{
1231 return FAIL;
1232}
1233
1234 GuiFont
Bram Moolenaard8b0cf12004-12-12 11:33:30 +00001235gui_mch_get_font(char_u *name, int giveErrorIfMissing)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001236{
1237 /*D("gui_mch_get_font");*/
1238 return NULL;
1239}
1240
Bram Moolenaardfccaf02004-12-31 20:56:11 +00001241#if defined(FEAT_EVAL) || defined(PROTO)
Bram Moolenaard8b0cf12004-12-12 11:33:30 +00001242/*
1243 * Return the name of font "font" in allocated memory.
1244 * We always use the default font.
1245 */
1246 char_u *
1247gui_mch_get_fontname(GuiFont font, char_u *name)
1248{
1249 return vim_strsave((char_u *)"default");
1250}
Bram Moolenaardfccaf02004-12-31 20:56:11 +00001251#endif
Bram Moolenaard8b0cf12004-12-12 11:33:30 +00001252
Bram Moolenaar071d4272004-06-13 20:20:40 +00001253 void
1254gui_mch_set_font(GuiFont font)
1255{
1256 /*D("gui_mch_set_font");*/
1257}
1258
1259#if 0 /* not used */
1260 int
1261gui_mch_same_font(GuiFont f1, GuiFont f2)
1262{
1263 D("gui_mch_same_font");
1264}
1265#endif
1266
1267 void
1268gui_mch_free_font(GuiFont font)
1269{
1270 if (font)
1271 D("gui_mch_free_font");
1272}
1273
1274#define RGB(a, b, c) ((a && 0xff) * 0x10000 + (b * 0xff) * 0x100 + (c & 0xff))
1275
1276/*
1277 * Get color handle for color "name".
1278 * Return INVALCOLOR when not possible.
1279 */
1280
1281 typedef struct guicolor_tTable
1282 {
1283 char *name;
1284 unsigned long color;
1285 UBYTE red;
1286 UBYTE green;
1287 UBYTE blue;
1288 } guicolor_tTable;
1289
1290 static guicolor_tTable table[] =
1291 {
1292 {"Grey", 0, 190,190,190},
1293 {"Black", 1, 0, 0, 0},
1294 {"DarkBlue", 2, 0, 0, 139},
1295 {"DarkGreen", 3, 0, 100, 0},
1296 {"DarkCyan", 4, 0, 139, 139},
1297 {"DarkRed", 5, 139, 0, 0},
1298 {"DarkMagenta", 6, 139, 0, 139},
1299 {"Brown", 7, 165, 42, 42},
1300 {"Gray", 8, 190, 190, 190},
1301 {"Grey", 9, 190, 190, 190},
1302 {"LightGray", 10, 211, 211, 211},
1303 {"LightGrey", 11, 211, 211, 211},
1304 {"DarkGray", 12, 169, 169, 169},
1305 {"DarkGrey", 13, 169, 169, 169},
1306 {"Blue", 14, 0, 0, 255},
1307 {"LightBlue", 15, 173, 216, 230},
1308 {"Green", 16, 0, 255, 0},
1309 {"LightGreen", 17, 144, 238, 144},
1310 {"Cyan", 18, 0, 255, 255},
1311 {"LightCyan", 19, 224, 255, 255},
1312 {"Red", 20, 255, 0, 0},
1313 {"LightRed", 21, 255, 0, 0}, /*?*/
1314 {"Magenta", 22, 255, 0, 255},
1315 {"LightMagenta",23, 255, 0, 255}, /*?*/
1316 {"Yellow", 24, 255, 255, 0},
1317 {"LightYellow", 25, 255, 255, 224}, /* TODO: add DarkYellow */
1318 {"White", 26, 255, 255, 255},
1319 {"SeaGreen", 27, 46, 139, 87},
1320 {"Orange", 28, 255, 165, 0},
1321 {"Purple", 30, 160, 32, 240},
1322 {"SlateBlue", 31, 106, 90, 205},
1323 {"grey90", 32, 229, 229, 229},
1324 {"grey95", 33, 242, 242, 242},
1325 {"grey80", 34, 204, 204, 204},
1326 {NULL, NULL},
1327 };
1328
1329 guicolor_T
1330gui_mch_get_color(char_u *name)
1331{
1332
1333 guicolor_T color = INVALCOLOR;
1334
1335 int i;
1336
1337 for (i = 0; table[i].name != NULL;i++)
1338 {
1339 if (stricmp(name, table[i].name) == 0)
1340 {
1341 //color = table[i].color;
1342 color = i;
1343 }
1344 }
1345
1346#if 0
1347 if (color == INVALCOLOR)
1348 {
1349 char *looky = NULL;
1350
1351 color = strtol((char*)name, &looky, 10);
1352 if (*looky != NUL)
1353 color = INVALCOLOR;
1354 }
1355#endif
1356
1357 kprintf("gui_mch_get_color[%s] = %s\n", name, table[color].name);
1358
1359 return color;
1360}
1361
1362static UBYTE getrealcolor(guicolor_T i)
1363{
1364 if (!MyColorTable[i].alloced)
1365 {
1366 MyColorTable[i].pen = ObtainBestPen(gui.window->WScreen->ViewPort.ColorMap,
1367 table[i].red * 0x01010101,
1368 table[i].green * 0x01010101,
1369 table[i].blue * 0x01010101,
1370 OBP_FailIfBad, FALSE,
1371 OBP_Precision, PRECISION_GUI,
1372 TAG_DONE);
1373 if (MyColorTable[i].pen != -1)
1374 {
1375 MyColorTable[i].alloced = TRUE;
1376 }
1377 }
1378
1379 return MyColorTable[i].pen;
1380}
1381
1382
1383 void
1384gui_mch_set_colors(guicolor_T fg, guicolor_T bg)
1385{
1386#if 0
1387 if (fg == 0)
1388 {
1389 fg = 1;
1390 }
1391#endif
1392 SetABPenDrMd(gui.window->RPort, getrealcolor(fg), getrealcolor(bg), JAM2);
1393
1394kprintf("gui_mch_set_colors %s,%s\n", table[fg].name, table[bg].name);
1395}
1396
1397 void
1398gui_mch_set_fg_color(guicolor_T color)
1399{
1400#if 0
1401 if (color == 0)
1402 {
1403 color = 1; /* vim sends 0 as default color which is ALWAYS the
1404 background on the amiga scrolling with colours as the
1405 background is a very bad idea on slow machines*/
1406 }
1407#endif
1408 SetAPen(gui.window->RPort, getrealcolor(color));
1409 SetDrMd(gui.window->RPort, JAM2);
1410
1411kprintf("gui_mch_set_fg_color %s\n", table[color].name);
1412
1413}
1414
1415 void
1416gui_mch_set_bg_color(guicolor_T color)
1417{
1418 SetBPen(gui.window->RPort, getrealcolor(color));
1419kprintf("gui_mch_set_bg_color %s\n", table[color].name);
1420
1421}
1422
1423 void
1424gui_mch_draw_string(int row, int col, char_u *s, int len, int flags)
1425{
1426#if 1
1427 char tempstring[300];
1428
1429 memcpy(tempstring, s, len);
1430 tempstring[len] = '\0';
1431
1432 kprintf("gui_mch_draw_string(%s) flags %x\n", tempstring, flags);
1433#endif
1434
1435 if (flags & DRAW_TRANSP)
1436 {
1437 SetDrMd(gui.window->RPort, JAM1);
1438 Move(gui.window->RPort, posWidthCharToPoint(col), posHeightCharToPoint(row) + gui.window->RPort->TxBaseline);
1439 Text(gui.window->RPort, s, len);
1440 }
1441 else
1442 {
1443 SetDrMd(gui.window->RPort, JAM2);
1444 Move(gui.window->RPort, posWidthCharToPoint(col), posHeightCharToPoint(row) + gui.window->RPort->TxBaseline);
1445 Text(gui.window->RPort, s, len);
1446 }
1447
1448 if (flags & DRAW_BOLD)
1449 {
1450 SetDrMd(gui.window->RPort, JAM1);
1451 Move(gui.window->RPort, posWidthCharToPoint(col)+1, posHeightCharToPoint(row) + gui.window->RPort->TxBaseline);
1452 Text(gui.window->RPort, s, len);
1453 }
1454
1455 if (flags & DRAW_UNDERL)
1456 {
1457 Move(gui.window->RPort, posWidthCharToPoint(col), posHeightCharToPoint(row + 1) - 1);
1458 Draw(gui.window->RPort, posWidthCharToPoint(col+len) - 1, posHeightCharToPoint(row + 1) - 1);
1459 }
1460
1461 SetDrMd(gui.window->RPort, JAM2);
1462}
1463
1464 int
1465gui_mch_haskey(char_u *name)
1466{
1467 int i;
1468
1469 D("gui_mch_haskey");
1470
1471 for (i = 0; special_keys[i].vim_code1 != NUL; i++)
1472 if (name[0] == special_keys[i].vim_code0 &&
1473 name[1] == special_keys[i].vim_code1)
1474 return OK;
1475 return FAIL;
1476}
1477
1478 void
1479gui_mch_beep(void)
1480{
1481 D("gui_mch_beep");
1482}
1483
1484 void
1485gui_mch_flash(int msec)
1486{
1487 D("gui_mch_flash");
1488
1489 SetDrMd(gui.window->RPort, COMPLEMENT);
1490 RectFill(gui.window->RPort, 0, 0, gui.window->GZZWidth - 1, gui.window->GZZHeight - 1);
1491 Delay(msec * 50 / 1000);
1492 RectFill(gui.window->RPort, 0, 0, gui.window->GZZWidth - 1, gui.window->GZZHeight - 1);
1493 SetDrMd(gui.window->RPort, JAM2);
1494}
1495
1496 void
1497gui_mch_invert_rectangle( int r, int c, int nr, int nc)
1498{
1499 printf("gui_mch_invert_rectangle %d %d %d %d\n", r, c, nr, nc);
1500}
1501
1502 void
1503gui_mch_iconify(void)
1504{
1505 D("gui_mch_iconify");
1506}
1507
1508#if defined(FEAT_EVAL) || defined(PROTO)
1509/*
1510 * Bring the Vim window to the foreground.
1511 */
1512 void
1513gui_mch_set_foreground()
1514{
1515 WindowToFront(gui.window);
1516 D("gui_mch_set_foreground");
1517}
1518#endif
1519
1520 void
1521gui_mch_settitle(char_u *title, char_u *icon)
1522{
1523 SetWindowTitles(gui.window, title, (STRPTR)~0);
1524 D("gui_mch_settitle");
1525}
1526
1527 void
1528gui_mch_stop_blink(void)
1529{
1530 gui_undraw_cursor();
1531 D("gui_mch_stop_blink");
1532}
1533
1534 void
1535gui_mch_start_blink(void)
1536{
1537 gui_update_cursor(FALSE, FALSE);
1538 D("gui_mch_start_blink");
1539}
1540
1541 void
1542gui_mch_draw_hollow_cursor(guicolor_T color)
1543{
1544 drawBox(DB_NotFilled, gui.col, gui.row, characterWidth, characterHeight, color);
1545}
1546
1547 void
1548gui_mch_draw_part_cursor( int w, int h, guicolor_T color)
1549{
1550 D("gui_mch_part_cursor");
1551 drawBox(DB_Filled, gui.col, gui.row, w, h, color);
1552}
1553
1554 void
1555gui_mch_update(void)
1556{
1557 checkEventHandler();
1558 return ;
1559}
1560
1561 int
1562gui_mch_wait_for_chars(int wtime)
1563{
1564 ULONG timermask = 1L << TimerMP->mp_SigBit;
1565 ULONG winmask = 1L << gui.window->UserPort->mp_SigBit;
1566 int retval = FAIL;
1567
1568 kprintf("========== gui_mch_wait_for_chars %d\n", wtime);
1569
1570 if (wtime == -1) wtime = 1000000000;
1571 if (wtime < 20) wtime = 20;
1572
1573 SetSignal(0, timermask);
1574 TimerIO->tr_node.io_Command = TR_ADDREQUEST;
1575 TimerIO->tr_time.tv_secs = wtime / 1000;
1576 TimerIO->tr_time.tv_micro = (wtime % 1000) * 1000;
1577 SendIO(&TimerIO->tr_node);
1578 TimerSent = TRUE;
1579
1580 for(;;)
1581 {
1582 ULONG sigs = Wait(winmask | timermask);
1583
1584 if (sigs & winmask)
1585 {
1586 checkEventHandler();
1587 if (!vim_is_input_buf_empty())
1588 {
1589 retval = OK;
1590 if (!CheckIO(&TimerIO->tr_node)) AbortIO(&TimerIO->tr_node);
1591 WaitIO(&TimerIO->tr_node);
1592 TimerSent = FALSE;
1593 break;
1594 }
1595 }
1596
1597 if (sigs & timermask)
1598 {
1599 struct Message *msg;
1600
1601 if ((msg = GetMsg(TimerMP)))
1602 {
1603 ReplyMsg(msg);
1604 TimerSent = FALSE;
1605 retval = FAIL;
1606 break;
1607 }
1608 }
1609 }
1610
1611 return retval;
1612
1613// assert(wtime != 0);
1614// return charEventHandler(wtime);
1615}
1616
1617 void
1618gui_mch_flush(void)
1619{
1620}
1621
1622 void
1623gui_mch_clear_block(int row1, int col1, int row2, int col2)
1624{
1625 UBYTE apen = GetAPen(gui.window->RPort);
1626
1627 SetAPen(gui.window->RPort, getrealcolor(gui.back_pixel));
1628 RectFill(gui.window->RPort,
1629 posWidthCharToPoint(col1),
1630 posHeightCharToPoint(row1),
1631 posWidthCharToPoint(col2 + 1) - 1,
1632 posHeightCharToPoint(row2 + 1) - 1);
1633 SetAPen(gui.window->RPort, apen);
1634
1635}
1636
1637 void
1638gui_mch_clear_all(void)
1639{
1640 SetRast(gui.window->RPort, GetBPen(gui.window->RPort));
1641 refreshBorder();
1642 D("gui_mch_clear_all");
1643}
1644
1645 void
1646gui_mch_delete_lines(int row, int num_lines)
1647{
1648 ScrollWindowRaster(gui.window,
1649 0,
1650 characterHeight * num_lines,
1651 posWidthCharToPoint(gui.scroll_region_left),
1652 posHeightCharToPoint(row),
1653 posWidthCharToPoint(gui.scroll_region_right + 1) - 1,
1654 posHeightCharToPoint(gui.scroll_region_bot + 1) - 1);
1655
1656 gui_clear_block(gui.scroll_region_bot - num_lines + 1,
1657 gui.scroll_region_left,
1658 gui.scroll_region_bot,
1659 gui.scroll_region_right);
1660
1661}
1662
1663 void
1664gui_mch_insert_lines(int row, int num_lines)
1665{
1666 ScrollWindowRaster(gui.window,
1667 0,
1668 -characterHeight*num_lines,
1669 posWidthCharToPoint(gui.scroll_region_left),
1670 posHeightCharToPoint(row),
1671 posWidthCharToPoint(gui.scroll_region_right + 1) - 1,
1672 posHeightCharToPoint(gui.scroll_region_bot +1 ) - 1);
1673
1674 gui_clear_block(row, gui.scroll_region_left,
1675 row + num_lines - 1, gui.scroll_region_right);
1676
1677}
1678
1679 void
1680gui_mch_enable_menu(int flag)
1681{
1682 D("gui_mch_enable_menu");
1683}
1684
1685 void
1686gui_mch_set_menu_pos(int x, int y, int w, int h)
1687{
1688 D("gui_mch_set_menu_pos");
1689}
1690
1691 void
1692gui_mch_destroy_menu(vimmenu_T *menu)
1693{
1694 D("gui_mch_destroy_menu");
1695 ClearMenuStrip(gui.window);
1696}
1697
1698 void
1699gui_mch_menu_grey(vimmenu_T *menu, int grey)
1700{
1701 D("gui_mch_menu_grey");
1702}
1703
1704 void
1705gui_mch_menu_hidden(vimmenu_T *menu, int hidden)
1706{
1707 D("gui_mch_menu_hidden");
1708 ClearMenuStrip(gui.window);
1709}
1710
1711 void
1712gui_mch_draw_menubar(void)
1713{
1714 D("gui_mch_draw_menubar");
1715 SetMenuStrip(gui.window, gui.menu);
1716}
1717
1718 static void
1719AmigaError(const char *string)
1720{
1721 static struct IntuiText pos = { 3, 0, JAM2, 17, 5, NULL, "Cancel", NULL} ;
1722 static struct IntuiText neg = { 3, 0, JAM2, 17, 5, NULL, "Cancel", NULL} ;
1723 static struct IntuiText message = { 3, 0, JAM2, 17, 5, NULL, NULL, NULL} ;
1724 static char *strptr = 0;
1725
1726 if (strptr)
1727 free(strptr);
1728 strptr = malloc(strlen(string)+1);
1729
1730 message.IText = strptr;
1731 strcpy(strptr, string);
1732
1733 AutoRequest(NULL, &message, &pos, &neg, 0, 0, 300, 300);
1734}
1735
1736 int
1737clip_mch_own_selection(VimClipboard *cbd)
1738{
1739 D("clib_mch_own_selection");
1740 return OK;
1741}
1742
1743 void
1744mch_setmouse(int on)
1745{
1746}
1747
1748/*
1749 * Get current y mouse coordinate in text window.
1750 * Return -1 when unknown.
1751 */
1752 int
1753gui_mch_get_mouse_x()
1754{
1755 return gui.window->GZZMouseX;
1756}
1757
1758 int
1759gui_mch_get_mouse_y()
1760{
1761 return gui.window->GZZMouseY;
1762}
1763
1764 void
1765gui_mch_setmouse(x, y)
1766 int x;
1767 int y;
1768{
1769 /* TODO */
1770}
1771
1772 void
1773gui_mch_show_popupmenu(vimmenu_T *menu)
1774{
1775 /* TODO */
1776}
1777
1778 void
1779clip_mch_lose_selection(VimClipboard *cbd)
1780{
1781 D("clip_mch_lose_selecction");
1782}
1783
1784 void
1785clip_mch_request_selection(VimClipboard *cbd)
1786{
1787 D("clip_mch_requst_selection");
1788}
1789
1790 void
1791clip_mch_set_selection(VimClipboard *cbd)
1792{
1793}
1794
1795 long_u
1796gui_mch_get_rgb(guicolor_T pixel)
1797{
1798 ULONG coltable[3], color;
1799
1800 GetRGB32(gui.window->WScreen->ViewPort.ColorMap,
1801 getrealcolor(pixel),
1802 1,
1803 coltable);
1804
1805 color = ((coltable[0] & 0xFF000000) >> 8) |
1806 ((coltable[1] & 0xFF000000) >> 16) |
1807 ((coltable[2] & 0xFF000000) >> 24);
1808
1809 return color;
1810}
1811
1812#endif /* USE_AMIGA_GUI*/