1 /* vi:set ts=8 sts=4 sw=4:
3 * VIM - Vi IMproved by Bram Moolenaar
5 * Do ":help uganda" in Vim to read copying and usage conditions.
6 * Do ":help credits" in Vim to see a list of people who contributed.
7 * See README.txt for an overview of the Vim source code.
16 * Thomas Leonard <tal197@ecs.soton.ac.uk>
17 * Updated by Andy Wingate <andy@sparse.net>
20 extern int time_of_last_poll
;
22 int task_handle
= 0; /* Zero means we are not yet a Wimp task */
23 int child_handle
= 0; /* Task handle of our child process (zero if none). */
24 int *wimp_menu
= (int *) -1; /* Pointer to a Wimp menu structure (or -1) */
25 int save_window
= -1; /* Save As window handle */
27 int *redraw_block
= NULL
; /* NULL means not in a redraw loop. */
28 int ro_return_early
= FALSE
; /* Break out of gui_mch_wait_for_chars() */
30 int leaf_ref
= 0; /* Wimp message number - send via Wimp$Scrap */
31 char_u
*leaf_name
= NULL
; /* Leaf name from DataSave */
33 int default_columns
= 120; /* These values are used if the --rows and --columns */
34 int default_rows
= 32; /* options aren't used on startup. */
37 #define DRAG_SELECTION 1
38 #define DRAG_RESIZE_WINDOW 2
39 int ro_dragging
= DRAG_FALSE
;
45 int nested_wimp
= FALSE
; /* Bool - can we use the new wimp? */
47 int changed_mode
= FALSE
;
51 /* If ro_current_font is non-zero then use the outline font with that handle,
52 * otherwise, if zap_redraw is TRUE then use ZapRedraw, otherwise use the
55 * If zap_redraw is TRUE then zap_file[] contains valid Zap font file
56 * pointers (or NULLs).
58 int ro_current_font
= 0; /* 0 is system font, or ZapRedraw */
59 int font_x_offset
= 0; /* Where to position each char in its box */
60 int font_y_offset
= 0;
62 int zap_redraw
= FALSE
;
63 int double_height
= FALSE
; /* Plot each line twice? */
65 #define grgb(r,g,b) ((b<<16) + (g<<8) + (r))
66 #define UNUSED_COLOUR (gui.back_pixel)
68 #define RO_LOAD_CLIPBOARD -2 /* Internal handle for DataSave message. */
70 /* Changes by John Kortink, 22-23 July 1998
72 * Stuff to make redraw a lot faster. Almost all of it is right here below,
73 * elsewhere changes are marked with 'JK230798'. Apart from a small change in
74 * 'gui.c' all changes are limited to this file, 'gui_riscos.c'. The change in
75 * 'gui.c' is to make Vim stop being 'smart' not redrawing characters that are
76 * 'already there' (i.e. from the previous line, by coincidence). This caused a
77 * lot more calls to the redraw code, which we want to avoid because a few nice
78 * big strings at a time is a lot faster than a truckload of small ones. ('Dear
82 /* The ZapRedraw structure */
117 static int zap_redraw_initialised
= FALSE
;
118 static int zap_redraw_update_colours
;
119 static int zap_redraw_colours
[2];
120 static int zap_redraw_palette
[16];
122 /* Holds the current Zap font file(s).
123 * The font is recreated from this block on a mode change.
124 * When using zap, element ZAP_NORMAL is always valid, but
125 * the others can be NULL.
131 #define ZAP_BITALIC 3
134 /* Zap font file format data */
135 static char *zap_file
[ZAP_STYLES
] = {NULL
, NULL
, NULL
, NULL
};
137 /* r_caddr format for current mode */
138 static char *zap_caddr
[ZAP_STYLES
] = {NULL
, NULL
, NULL
, NULL
};
140 static void ro_remove_menu(int *menu
);
143 * Initialise all the ZapRedraw stuff.
144 * Call this when changing font and after each mode change.
145 * zap_redraw_bitmap must contain a valid Zap font file (possibly
146 * created from the system font).
148 * Return FAIL to revert to system font (if we can't use ZapRedraw).
151 ro_zap_redraw_initialise()
153 int bytes_per_bitmap_char
;
157 /* Can't have initialisers for struct members :-(, ok, this way then ... */
158 if (!zap_redraw_initialised
)
160 zap_redraw_block
.r_workarea
= NULL
;
161 zap_redraw_initialised
= TRUE
;
164 /* We redraw in DSA mode */
165 zap_redraw_block
.r_flags
= 0x0;
167 /* Let ZapRedraw get the screen address for us */
168 zap_redraw_block
.r_screen
= 0;
170 /* Read the font width and height from the font file header.
171 * Assume that all styles are the same size.
172 * ZAP_NORMAL is always present.
174 zap_redraw_block
.r_charw
= ((int *) zap_file
[ZAP_NORMAL
])[2];
175 zap_redraw_block
.r_charh
= ((int *) zap_file
[ZAP_NORMAL
])[3];
177 /* We have no linespacing */
178 zap_redraw_block
.r_linesp
= 0;
180 /* Fix foreground = colour 1 */
181 zap_redraw_block
.r_for
= 1;
183 /* Fix background = colour 0 */
184 zap_redraw_block
.r_bac
= 0;
186 /* Colour mask buffer */
187 zap_redraw_block
.r_palette
= zap_redraw_palette
;
189 /* Allocate local workspace (for the few calls following here) */
190 if (zap_redraw_block
.r_workarea
!= NULL
)
191 free(zap_redraw_block
.r_workarea
);
192 zap_redraw_block
.r_workarea
= (char*) malloc(128);
193 if (!zap_redraw_block
.r_workarea
)
194 return FAIL
; /* Out of memory */
196 /* Fill in VDU variables */
197 if (xswi(ZapRedraw_ReadVduVars
, 0, &zap_redraw_block
) & v_flag
)
198 return FAIL
; /* Can't find ZapRedraw module - use VDU instead */
200 /* Determine cbpl and cbpc */
201 swi(ZapRedraw_CachedCharSize
, zap_redraw_block
.r_bpp
, 0,
202 zap_redraw_block
.r_charw
, zap_redraw_block
.r_charh
);
203 zap_redraw_block
.r_cbpl
= r2
;
204 zap_redraw_block
.r_cbpc
= r3
;
206 /* Allocate general workspace (for the calls outside) */
207 if (zap_redraw_block
.r_workarea
!= NULL
)
208 free(zap_redraw_block
.r_workarea
);
209 zap_redraw_block
.r_workarea
= (char*) malloc(128 + zap_redraw_block
.r_cbpl
);
210 if (!zap_redraw_block
.r_workarea
)
211 return FAIL
; /* Out of memory */
213 /* Now convert the 1 bpp character data ready for the current mode */
215 bytes_per_bitmap_char
= (zap_redraw_block
.r_charw
* zap_redraw_block
.r_charh
+ 7) / 8;
217 /* Convert the fonts from 1bpp to a format suitable for the
220 for (i
= 0; i
< ZAP_STYLES
; i
++)
222 first
= ((int *) zap_file
[i
])[4];
223 last
= ((int *) zap_file
[i
])[5];
226 last
= 255; /* Don't convert cursors (overwrites memory!) */
228 /* Allocate the font cache */
229 vim_free(zap_caddr
[i
]);
231 zap_caddr
[i
] = (char*) malloc(zap_redraw_block
.r_cbpc
* 256);
233 zap_caddr
[i
] = NULL
; /* No file for this style */
237 zap_redraw_block
.r_caddr
= zap_caddr
[i
];
239 swi(ZapRedraw_ConvertBitmap
, 0, &zap_redraw_block
,
240 first
, last
, /* Range of characters to convert */
241 zap_file
[i
] + 0x20 /* Addr of first char provided by font */
242 - first
* bytes_per_bitmap_char
);
246 if (!zap_caddr
[ZAP_NORMAL
])
248 zap_redraw
= FALSE
; /* Out of memory */
252 /* Next time we need them, we have to update the colour masks */
253 zap_redraw_update_colours
= TRUE
;
259 * Redraw a string at OS coordinates <x,y> (top-left, x inclusive, y exclusive).
260 * Graphics clip window is window[0..3] as in R1+28..40 of Wimp_RedrawWindow.
261 * Returns (possibly modified) flags.
264 ro_zap_redraw_draw_string(x
, y
, string
, length
, flags
, clip
)
269 int flags
; /* DRAW_TRANSP, DRAW_BOLD, DRAW_UNDERL, DRAW_ITALIC */
272 char redraw_data
[1024];
277 int os_xshift
= zap_redraw_block
.r_magx
;
278 int os_yshift
= zap_redraw_block
.r_magy
;
280 if (flags
& DRAW_TRANSP
)
281 return flags
; /* We don't do transparent plotting yet. */
283 if (flags
& DRAW_BOLD
)
285 if (flags
& DRAW_ITALIC
&& zap_caddr
[ZAP_BITALIC
])
286 zap_redraw_block
.r_caddr
= zap_caddr
[ZAP_BITALIC
];
288 zap_redraw_block
.r_caddr
= zap_caddr
[ZAP_BOLD
];
292 if (flags
& DRAW_ITALIC
)
293 zap_redraw_block
.r_caddr
= zap_caddr
[ZAP_ITALIC
];
295 zap_redraw_block
.r_caddr
= zap_caddr
[ZAP_NORMAL
];
297 if (!zap_redraw_block
.r_caddr
)
299 zap_redraw_block
.r_caddr
= zap_caddr
[ZAP_NORMAL
];
300 flags
|= DRAW_UNDERL
; /* Style missing - we can always underline */
303 /* Set the vertical scaling flag */
305 zap_redraw_block
.r_flags
= 1 << 1;
307 zap_redraw_block
.r_flags
= 0;
309 /* Update the colour masks (if needed) */
310 if (zap_redraw_update_colours
)
312 swi(ZapRedraw_CreatePalette
, 2,
315 zap_redraw_block
.r_palette
, 2);
316 zap_redraw_update_colours
= FALSE
;
319 /* Target rectangle in ZapRedraw rectangle coordinates (pixels, Y-min/max reversed !!!) */
320 zap_redraw_block
.r_minx
= x
>> os_xshift
; /* inclusive */
321 zap_redraw_block
.r_miny
= zap_redraw_block
.r_ysize
- (y
>> os_yshift
); /* inclusive */
322 zap_redraw_block
.r_maxx
= (x
+ length
* gui
.char_width
) >> os_xshift
; /* exclusive */
323 zap_redraw_block
.r_maxy
= zap_redraw_block
.r_ysize
- ((y
- gui
.char_height
) >> os_yshift
);
326 /* Clip rectangle in ZapRedraw rectangle coordinates (pixels, Y-min/max reversed !!!) */
327 clip_minx
= clip
[0] >> os_xshift
; /* inclusive */
328 clip_miny
= zap_redraw_block
.r_ysize
- (clip
[3] >> os_yshift
); /* inclusive */
329 clip_maxx
= clip
[2] >> os_xshift
; /* exclusive */
330 clip_maxy
= zap_redraw_block
.r_ysize
- (clip
[1] >> os_yshift
); /* exclusive */
332 /* Clip target rectangle against the current graphics window */
333 if (zap_redraw_block
.r_minx
< clip_minx
)
335 zap_redraw_block
.r_scrollx
= clip_minx
- zap_redraw_block
.r_minx
;
336 zap_redraw_block
.r_minx
= clip_minx
;
339 zap_redraw_block
.r_scrollx
= 0;
340 if (zap_redraw_block
.r_miny
< clip_miny
)
342 zap_redraw_block
.r_scrolly
= clip_miny
- zap_redraw_block
.r_miny
;
343 zap_redraw_block
.r_miny
= clip_miny
;
346 zap_redraw_block
.r_scrolly
= 0;
347 if (zap_redraw_block
.r_maxx
> clip_maxx
)
348 zap_redraw_block
.r_maxx
= clip_maxx
;
349 if (zap_redraw_block
.r_maxy
> clip_maxy
)
350 zap_redraw_block
.r_maxy
= clip_maxy
;
352 /* Fill in the character data structure */
353 if (length
> (sizeof(redraw_data
) - 2 * 4 - 2))
354 length
= sizeof(redraw_data
) - 2 * 4 - 2;
355 ((int*) redraw_data
)[0] = 2 * 4;
356 ((int*) redraw_data
)[1] = 0;
357 strncpy(redraw_data
+ 2 * 4, string
, length
);
358 redraw_data
[2 * 4 + length
+ 0] = '\0';
359 redraw_data
[2 * 4 + length
+ 1] = '\x2';
360 zap_redraw_block
.r_data
= (int) redraw_data
;
362 /* Perform the draw */
363 swi(ZapRedraw_RedrawArea
, 0, &zap_redraw_block
);
369 * Okay that was it from me, back to Thomas ...
373 * Parse the GUI related command-line arguments. Any arguments used are
374 * deleted from argv, and *argc is decremented accordingly. This is called
375 * when vim is started, whether or not the GUI has been started.
378 gui_mch_prepare(int *argc
, char **argv
)
382 while (arg
< *argc
- 1)
384 if (strcmp(argv
[arg
], "--rows") == 0 || strcmp(argv
[arg
], "--columns") == 0)
388 value
= atoi(argv
[arg
+ 1]);
390 if (argv
[arg
][2] == 'r')
391 default_rows
= value
;
393 default_columns
= value
;
395 /* Delete argument from argv[]. (hope this is read/write!) */
399 mch_memmove(&argv
[arg
], &argv
[arg
+ 2], (*argc
- arg
)
407 /* Fatal error on initialisation - report it and die. */
410 char_u
*error
; /* RISC OS error block */
412 swi(Wimp_ReportError
, error
, 5, "GVim");
416 /* Find the sizes of the window tools:
418 * Create a test window.
419 * Find inner and outer sizes.
420 * Find the difference.
423 * While we're here, find the eigen values too.
429 int vdu
[] = { 4, 5, -1};
432 -100, -100, /* Visible area : min X,Y */
433 -50, -50, /* max X,Y */
434 0, 0, /* Scroll offsets */
435 -1, /* Window in front */
436 0xd0800150, /* Window flags */
437 0xff070207, /* Colours */
438 0x000c0103, /* More colours */
439 0, -0x4000, /* Workarea extent */
440 0x4000, 0, /* max X,Y */
441 0x00000000, /* No title */
442 0 << 12, /* No workarea button type */
443 1, /* Wimp sprite area */
444 0x00010001, /* Minimum width, height */
445 0, 0, 0, /* Title data (none) */
448 int inner_max_x
, inner_min_y
;
450 swi(Wimp_CreateWindow
, 0, test_window
);
453 /* Open the window (and read state).
454 * GetWindowOutline needs it too if the wimp isn't nested.
456 swi(Wimp_OpenWindow
, 0, block
);
457 inner_max_x
= block
[3];
458 inner_min_y
= block
[2];
460 swi(Wimp_GetWindowOutline
, 0, block
);
462 gui
.scrollbar_width
= block
[3] - inner_max_x
;
463 gui
.scrollbar_height
= inner_min_y
- block
[2];
465 swi(Wimp_DeleteWindow
, 0, block
);
467 /* Read the size of one pixel. */
468 swi(OS_ReadVduVariables
, vdu
, vdu
);
469 x_eigen_factor
= vdu
[0];
470 y_eigen_factor
= vdu
[1];
473 /* Load a template from the current templates file.
474 * Create the window and return its handle.
477 ro_load_template(str_name
, title
, title_size
)
478 char_u
*str_name
; /* Identifier of window in file (max 12 chars) */
479 char_u
**title
; /* If not NULL then return pointer to title here */
480 int *title_size
; /* If not NULL then return the title length here */
486 strcpy( (char *) name
, str_name
);
488 /* Find how big we must make the buffers */
490 if (xswi(Wimp_LoadTemplate
, 0, 0, 0, 0, -1, name
, 0) & v_flag
)
491 ro_die( (char *) r0
);
493 window
= malloc(r1
); /* Don't print text messages from alloc() */
495 if (window
== NULL
|| data
== NULL
)
496 ro_die("\0\0\0\0Out of memory - Can't load templates");
498 /* Load the template into the buffers */
500 swi(Wimp_LoadTemplate
, 0,
501 window
, /* Temp block */
502 data
, /* Icon data */
503 data
+ r2
+ 1, /* End of icon data */
505 name
, 0); /* First match */
507 ro_die("\0\0\0\0Can't find window in Templates file");
509 /* Create the window */
511 if (xswi(Wimp_CreateWindow
, 0, window
) & v_flag
)
512 ro_die( (char *) r0
);
515 *title
= (char_u
*) window
[18];
517 *title_size
= window
[20];
519 free(window
); /* Free temp block */
520 return r0
; /* Return the window handle */
524 * Check if the GUI can be started. Called before gvimrc is sourced.
530 return OK
; /* TODO: GUI can always be started? */
534 * Initialise the RISC OS GUI.
535 * Create all the windows.
536 * Returns OK for success, FAIL when the GUI can't be started.
542 1, 2, 3, 4, /* DataSave, DataSaveAck, DataLoad, DataLoadAck */
544 0xf, /* ClaimEntity (for clipboard) */
545 0x10, /* DataRequest (for clipboard) */
546 0x400c1, /* Mode change */
547 0x400c3, /* TaskCloseDown */
548 0x400c9, /* MenusDeleted */
549 0x808c1, /* TW_Output */
550 0x808c2, /* TW_Ego */
551 0x808c3, /* TW_Morio */
552 0x808c4, /* TW_Morite */
553 0}; /* End-of-list. */
556 /* There may have been some errors reported in the
557 * command window before we get here. Wait if so.
559 swi(Wimp_ReadSysInfo
, 3);
561 swi(Wimp_CommandWindow
, 0); /* Window opened - close with prompt */
563 if (xswi(Wimp_Initialise
, 310, 0x4b534154, "GVim", messages
) & v_flag
)
565 nested_wimp
= r0
>= 397;
568 /* Load the templates. */
570 if (xswi(Wimp_OpenTemplate
, 0, "Vim:Templates") & v_flag
)
571 ro_die( (char *) r0
);
573 gui
.window_handle
= ro_load_template("editor",
575 &gui
.window_title_size
);
577 save_window
= ro_load_template("save", NULL
, NULL
);
579 swi(Wimp_CloseTemplate
);
581 /* Set default foreground and background colours. */
583 gui
.norm_pixel
= gui
.def_norm_pixel
;
584 gui
.back_pixel
= gui
.def_back_pixel
;
586 /* Get the colours from the "Normal" and "Menu" group (set in syntax.c or
587 * in a vimrc file) */
592 * Check that none of the colors are the same as the background color
597 /* Get the colours for the highlight groups (gui_check_colors() might have
600 highlight_gui_started(); /* re-init colours and fonts */
602 /* Set geometry based on values read on initialisation. */
604 gui
.num_cols
= Columns
= default_columns
;
605 gui
.num_rows
= Rows
= default_rows
;
607 /* Get some information about our environment. */
615 * Called when the foreground or background colour has been changed.
623 * Open the GUI window which was created by a call to gui_mch_init().
630 block
[0] = gui
.window_handle
;
631 swi(Wimp_GetWindowState
, 0, block
);
632 block
[7] = -1; /* Open at the top of the stack */
633 swi(Wimp_OpenWindow
, 0, block
);
635 /* Give the new window the input focus */
636 swi(Wimp_SetCaretPosition
, gui
.window_handle
, -1, 0, 0, -1, -1);
638 if (gui_win_x
!= -1 && gui_win_y
!= -1)
639 gui_mch_set_winpos(gui_win_x
, gui_win_y
);
649 /* Close window. Stops us from getting troublesome events
650 * if we take a while to die.
652 block
[0] = gui
.window_handle
;
653 swi(Wimp_CloseWindow
, 0, block
);
657 /* We still have a sub-task running - kill it */
660 block
[4] = 0; /* Quit */
661 if ((xswi(Wimp_SendMessage
, 17, block
, child_handle
) & v_flag
) == 0)
663 /* Idle until child dies. */
666 process_event(wimp_poll(1, block
), block
);
675 * Get the position of the top left corner of the window.
678 gui_mch_get_winpos(int *x
, int *y
)
685 * Set the position of the top left corner of the window to the given
689 gui_mch_set_winpos(int x
, int y
)
695 gui_mch_set_shellsize(width
, height
, min_width
, min_height
, base_width
, base_height
, direction
)
696 int width
; /* In OS units */
698 int min_width
; /* Smallest permissible window size (ignored) */
700 int base_width
; /* Space for scroll bars, etc */
704 int s_width
, s_height
;
712 gui_mch_get_screen_dimensions(&s_width
, &s_height
);
713 s_width
-= base_width
;
714 s_height
-= base_height
; /* Underestimate - ignores titlebar */
716 swi(Wimp_GetWindowState
, 0, block
);
717 block
[3] = block
[1] + width
;
718 block
[2] = block
[4] - height
;
719 if (block
[3] > s_width
)
722 block
[1] = block
[3] - width
;
724 if (block
[2] < gui
.scrollbar_height
)
726 block
[2] = gui
.scrollbar_height
;
727 block
[4] = block
[2] + height
;
729 swi(Wimp_OpenWindow
, 0, block
);
730 swi(Wimp_ForceRedraw
, gui
.window_handle
, 0, -height
, width
, 0);
734 gui_mch_get_screen_dimensions(int *screen_w
, int *screen_h
)
736 int block
[] = {4, 5, 11, 12, -1};
738 swi(OS_ReadVduVariables
, block
, block
);
739 *screen_w
= (block
[2] + 1) << block
[0];
740 *screen_h
= (block
[3] + 1) << block
[1];
743 /* Take a font name with options and return a font handle, or
745 * Replace extension with 'Bold' or 'Italic' depending on modifiers.
748 ro_get_font(fullname
, weight
)
750 int weight
; /* Initial weights:
767 if (c
== ':' || c
== NUL
|| c
== '.')
772 /* find the first modifier, NULL if none */
773 arg
= strchr(fullname
+ i
, ':');
780 height
= strtol(arg
+ 1, (char **) &arg
, 10);
783 width
= strtol(arg
+ 1, (char **) &arg
, 10);
794 arg
= strchr(arg
, ':');
797 if ((weight
& 1) && i
< 35)
799 /* Bold goes instead of given suffix */
800 strncpy(font
+ i
, ".Bold", 5);
805 /* Copy rest of name unless we are using Bold */
809 if (c
== ':' || c
== NUL
)
814 if ((weight
& 2) && i
< 32)
816 strncpy(font
+ i
, ".Oblique", 8);
822 if (height
< 1 && width
< 1)
823 height
= width
= 10; /* Default to 10pt */
829 if (xswi(Font_FindFont
, 0, font
, width
<< 4, height
<< 4, 0, 0) & v_flag
)
830 return NOFONT
; /* Can't find font */
835 /* Load a file into allocated memory and check it is valid.
836 * Return a pointer to the allocated block on success.
839 zap_load_file(name
, style
)
840 char_u
*name
; /* Name of directory containing styles */
841 char_u
*style
; /* Name of style within directory */
846 if (strlen(name
) + strlen(style
) > 254)
847 return NULL
; /* Names too long */
849 sprintf(fname
, "%s.%s", name
, style
);
851 /* Load the named font in 1bpp format. */
852 if (xswi(OS_File
, 13, fname
, 0, 0, "VimFonts:") & v_flag
|| r0
!= 1)
853 return NULL
; /* Error reading file info, or not a file */
855 /* Allocate enough memory to load the whole file */
856 file
= (char *) alloc(r4
);
858 return NULL
; /* Out of memory */
860 if (xswi(OS_File
, 12, fname
, file
, 0, "VimFonts:") & v_flag
)
861 return NULL
; /* Unable to load file */
863 if (strncmp(file
, "ZapFont\015", 8) == 0)
864 return file
; /* Loaded OK! */
867 return NULL
; /* Not a valid font file */
870 /* Load and convert the named font.
871 * If name is NULL or a null string then convert the system font.
872 * Return OK on success; FAIL and we revert to using the VDU drivers.
874 * 'name' is the name of a directory.
875 * Tries to load 'name.0', 'name.B', 'name.I' and 'name.IB'.
883 /* Free the existing font files, if any */
884 for (i
= 0; i
< ZAP_STYLES
; i
++)
886 vim_free(zap_file
[i
]);
890 if (name
&& *name
== '!')
893 double_height
= TRUE
;
896 double_height
= FALSE
;
900 zap_file
[ZAP_NORMAL
] = zap_load_file(name
, "0");
901 if (!zap_file
[ZAP_NORMAL
])
902 return FAIL
; /* Can't load the 'normal' style - error */
904 zap_file
[ZAP_BOLD
] = zap_load_file(name
, "B");
905 zap_file
[ZAP_ITALIC
] = zap_load_file(name
, "I");
906 zap_file
[ZAP_BITALIC
] = zap_load_file(name
, "IB");
914 /* Allocate memory for system font (8 x 8 x 256 bits, plus header) */
915 header
= (int *) alloc(0x20 + 8 * 256);
918 zap_file
[ZAP_NORMAL
] = (char *) header
;
920 /* Store details about the system font */
921 header
[2] = 8; /* Width */
922 header
[3] = 8; /* Height */
923 header
[4] = 0; /* First char */
924 header
[5] = 255; /* Last char */
925 header
[6] = header
[7] = 0; /* Reserved */
927 /* Get system font bitmap */
928 old_wa
= zap_redraw_block
.r_workarea
;
929 zap_redraw_block
.r_workarea
= workarea
;
930 swi(ZapRedraw_ReadSystemChars
, zap_file
[ZAP_NORMAL
] + 0x20, &zap_redraw_block
);
931 zap_redraw_block
.r_workarea
= old_wa
;
934 return ro_zap_redraw_initialise();
938 * Initialise vim to use the font with the given name.
939 * Return FAIL if the font could not be loaded, OK otherwise.
942 gui_mch_init_font(char_u
*font_name
, int fontset
)
944 int new_handle
= 0; /* Use the system font by default */
946 if (font_name
[0] == '!')
948 /* Select a ZapRedraw font */
949 if (zap_load_font(font_name
+ 1))
953 EMSG2(_("E610: Can't load Zap font '%s'"), font_name
);
954 font_name
= "System"; /* Error - use system font */
964 /* Extract any extra details about the font */
965 new_handle
= ro_get_font(font_name
, 0);
970 font_name
= "System";
973 /* Free the previous font, if any */
974 gui_mch_free_font(gui
.norm_font
);
975 gui
.norm_font
= new_handle
;
980 /* Read details about the chosen font */
981 swi(Font_ReadInfo
, new_handle
);
983 gui
.char_width
= r3
- r1
;
984 gui
.char_height
= r4
- r2
;
986 font_x_offset
= -r1
; /* Where to position each char in its box */
989 /* Try to load other fonts for bold, italic, and bold-italic */
990 gui_mch_free_font(gui
.bold_font
);
991 gui
.bold_font
= ro_get_font(font_name
, 1);
992 gui_mch_free_font(gui
.ital_font
);
993 gui
.ital_font
= ro_get_font(font_name
, 2);
994 gui_mch_free_font(gui
.boldital_font
);
995 gui
.boldital_font
= ro_get_font(font_name
, 3);
999 /* Use the system font or ZapRedraw. */
1002 gui
.char_width
= zap_redraw_block
.r_charw
<< zap_redraw_block
.r_magx
;
1003 gui
.char_height
= zap_redraw_block
.r_charh
<< zap_redraw_block
.r_magy
;
1005 gui
.char_height
<<= 1;
1009 gui
.char_width
= 16;
1010 gui
.char_height
= 32;
1013 gui_mch_free_font(gui
.bold_font
);
1015 gui_mch_free_font(gui
.ital_font
);
1017 gui_mch_free_font(gui
.boldital_font
);
1018 gui
.boldital_font
= 0;
1020 hl_set_font_name(font_name
);
1022 must_redraw
= CLEAR
;
1027 * Adjust gui.char_height (after 'linespace' was changed).
1030 gui_mch_adjust_charheight()
1036 * Get a font structure for highlighting.
1039 gui_mch_get_font(name
, giveErrorIfMissing
)
1041 int giveErrorIfMissing
;
1046 return NOFONT
; /* System font if no name */
1048 handle
= ro_get_font(name
, 0);
1051 if (giveErrorIfMissing
)
1052 EMSG2(_("E611: Can't use font %s"), name
);
1059 #if defined(FEAT_EVAL) || defined(PROTO)
1061 * Return the name of font "font" in allocated memory.
1062 * Don't know how to get the actual name, thus use the provided name.
1065 gui_mch_get_fontname(font
, name
)
1071 return vim_strsave(name
);
1076 * Set the current text font.
1079 gui_mch_set_font(GuiFont font
)
1081 ro_current_font
= font
;
1085 /* Not the system font or ZapRedraw font - select it */
1086 swi(Font_SetFont
, font
);
1091 * If a font is not going to be used, free its structure.
1094 gui_mch_free_font(GuiFont font
)
1097 swi(Font_LoseFont
, font
);
1101 * Return the Pixel value (colour) for the given colour name.
1102 * Return INVALCOLOR for error.
1103 * NB: I've changed Green for now, since it looked really sick
1106 gui_mch_get_color(char_u
*name
)
1115 { "Red", grgb(255, 0, 0) },
1116 { "LightRed", grgb(255, 0, 0) },
1117 { "DarkRed", grgb(139, 0, 0) },
1119 { "Green", grgb(50, 200, 50) },
1120 { "LightGreen", grgb(144, 238, 144) },
1121 { "DarkGreen", grgb(0, 100, 0) },
1122 { "SeaGreen", grgb(46, 139, 87) },
1124 { "Blue", grgb(0, 0, 255) },
1125 { "LightBlue", grgb(173, 216, 230) },
1126 { "DarkBlue", grgb(0, 0, 139) },
1127 { "SlateBlue", grgb(160, 90, 205) },
1129 { "Cyan", grgb(0, 255, 255) },
1130 { "LightCyan", grgb(224, 255, 255) },
1131 { "DarkCyan", grgb(0, 139, 139) },
1133 { "Magenta", grgb(255, 0, 255) },
1134 { "LightMagenta", grgb(255, 224, 255) },
1135 { "DarkMagenta", grgb(139, 0, 139) },
1137 { "Yellow", grgb(255, 255, 0) },
1138 { "LightYellow", grgb(255, 255, 224) },
1139 { "DarkYellow", grgb(139, 139, 0) },
1140 { "Brown", grgb(165, 42, 42) },
1142 { "Gray", grgb(190, 190, 190) },
1143 { "Grey", grgb(190, 190, 190) },
1144 { "LightGray", grgb(211, 211, 211) },
1145 { "LightGrey", grgb(211, 211, 211) },
1146 { "DarkGray", grgb(169, 169, 169) },
1147 { "DarkGrey", grgb(169, 169, 169) },
1148 { "Gray10", grgb(26, 26, 26) },
1149 { "Grey10", grgb(26, 26, 26) },
1150 { "Gray20", grgb(51, 51, 51) },
1151 { "Grey20", grgb(51, 51, 51) },
1152 { "Gray30", grgb(77, 77, 77) },
1153 { "Grey30", grgb(77, 77, 77) },
1154 { "Gray40", grgb(102, 102, 102) },
1155 { "Grey40", grgb(102, 102, 102) },
1156 { "Gray50", grgb(127, 127, 127) },
1157 { "Grey50", grgb(127, 127, 127) },
1158 { "Gray60", grgb(153, 153, 153) },
1159 { "Grey60", grgb(153, 153, 153) },
1160 { "Gray70", grgb(179, 179, 179) },
1161 { "Grey70", grgb(179, 179, 179) },
1162 { "Gray80", grgb(204, 204, 204) },
1163 { "Grey80", grgb(204, 204, 204) },
1164 { "Gray90", grgb(229, 229, 229) },
1165 { "Grey90", grgb(229, 229, 229) },
1167 { "Black", grgb(0, 0, 0) },
1168 { "White", grgb(255, 255, 255) },
1170 { "Orange", grgb(255, 165, 0) },
1171 { "Purple", grgb(160, 32, 240) },
1172 { "Violet", grgb(238, 130, 238) },
1181 c
= strtol(name
+ 1, &end
, 16);
1182 return (guicolor_T
) ((c
>> 16) & 0xff) | (c
& 0xff00) | ((c
& 0xff) << 16);
1185 for (i
= 0; colours
[i
].name
!= NULL
; i
++)
1187 if (STRICMP(name
, colours
[i
].name
) == 0)
1188 return colours
[i
].value
;
1190 if (strnicmp(name
, "grey", 4) == 0 || strnicmp(name
, "gray", 4) == 0)
1192 int level
= (255 * atoi(name
+ 4)) / 100;
1193 return (guicolor_T
) grgb(level
, level
, level
);
1199 * Set the current text colours.
1200 * If we are using fonts then set the antialiasing colours too.
1203 gui_mch_set_colors(guicolor_T fg
, guicolor_T bg
)
1205 zap_redraw_colours
[0] = bg
<< 8; /* JK230798, register new background colour */
1206 zap_redraw_colours
[1] = fg
<< 8; /* JK230798, register new foreground colour */
1207 zap_redraw_update_colours
= TRUE
; /* JK230798, need update of colour masks */
1209 swi(ColourTrans_ReturnGCOL
, fg
<< 8);
1211 swi(ColourTrans_ReturnGCOL
, bg
<< 8);
1214 if (ro_current_font
)
1215 swi(ColourTrans_SetFontColours
, 0, bg
<< 8, fg
<< 8, 14);
1219 ro_draw_string(x
, y
, s
, len
, flags
, clip
)
1220 int x
; /* Top-left coord to plot at (x incl, y excl) */
1221 int y
; /* (screen coords) */
1222 char_u
*s
; /* String to plot */
1223 int len
; /* Length of string */
1224 int flags
; /* DRAW_TRANSP, DRAW_BOLD, DRAW_UNDERL */
1225 int* clip
; /* JK230798, added clip window */
1227 if (ro_current_font
)
1230 int flen
= len
; /* Preserve for underline */
1232 /* Use the Font manager to paint the string.
1233 * Must do one char at a time to get monospacing.
1236 if (flags
& DRAW_ITALIC
&& !gui
.ital_font
)
1237 flags
|= DRAW_UNDERL
; /* No italic - underline instead */
1239 if ((flags
& DRAW_TRANSP
) == 0)
1241 swi(ColourTrans_SetColour
, gui
.bg_colour
, 0, 0, 0, 0);
1242 swi(OS_Plot
, 4, x
, y
- gui
.char_height
);
1243 swi(OS_Plot
, 96 + 5, x
+ len
* gui
.char_width
- 1, y
- 1);
1246 fx
= x
+ font_x_offset
;
1249 swi(Font_Paint
, 0, s
++, 0x90, fx
, y
+ font_y_offset
, 0, 0, 1);
1250 fx
+= gui
.char_width
;
1257 /* Using fast Zap redraw. */
1258 flags
= ro_zap_redraw_draw_string(x
, y
, s
, len
, flags
, clip
);
1262 /* Using the system font */
1263 if (flags
& DRAW_ITALIC
)
1264 flags
|= DRAW_UNDERL
;
1266 if ((flags
& DRAW_TRANSP
) == 0)
1268 swi(ColourTrans_SetColour
, gui
.bg_colour
, 0, 0, 0, 0);
1269 swi(OS_Plot
, 4, x
, y
- gui
.char_height
);
1270 swi(OS_Plot
, 96 + 5, x
+ len
* gui
.char_width
- 1, y
- 1);
1272 swi(OS_Plot
, 4, /* Move the drawing cursor */
1275 swi(ColourTrans_SetColour
, gui
.fg_colour
, 0, 0, 0, 0);
1276 swi(OS_WriteN
, s
, len
);
1278 if (flags
& DRAW_BOLD
)
1280 swi(OS_Plot
, 4, x
+ (1 << x_eigen_factor
), y
- 1);
1281 swi(OS_WriteN
, s
, len
);
1286 if (flags
& DRAW_UNDERL
)
1288 if (ro_current_font
|| zap_redraw
)
1289 swi(ColourTrans_SetColour
, gui
.fg_colour
, 0, 0, 0, 0);
1290 /* Underlined is the same with all plotting methods */
1291 swi(OS_Plot
, 4, x
, y
- gui
.char_height
);
1292 swi(OS_Plot
, 1, gui
.char_width
* len
, 0);
1297 gui_mch_draw_string(int row
, int col
, char_u
*s
, int len
, int flags
)
1299 int x
, y
; /* Workarea x,y */
1300 x
= col
* gui
.char_width
;
1301 y
= -row
* gui
.char_height
;
1305 ro_draw_string(x
+ redraw_block
[1], y
+ redraw_block
[4],
1306 s
, len
, flags
, &redraw_block
[7]); /* JK230798, added clip window */
1311 block
[0] = gui
.window_handle
;
1313 block
[2] = y
- gui
.char_height
;
1314 block
[3] = (col
+ len
) * gui
.char_width
;
1316 swi(Wimp_UpdateWindow
, 0, block
);
1319 ro_draw_string(x
+ block
[1], y
+ block
[4],
1320 s
, len
, flags
, &block
[7]); /* JK230798, added clip window */
1321 swi(Wimp_GetRectangle
, 0, block
);
1327 * Return OK if the key with the termcap name "name" is supported.
1330 gui_mch_haskey(char_u
*name
)
1345 gui_mch_flash(int msec
)
1352 * Plot a solid rectangle using the given plot action and colour.
1353 * Coordinates are inclusive and window-relative.
1356 plot_rectangle(plot
, colour
, minx
, miny
, maxx
, maxy
)
1357 int plot
; /* OS_Plot action */
1366 swi(ColourTrans_SetColour
, colour
, 0, 0, 0, 0);
1367 swi(OS_Plot
, 4, minx
+ redraw_block
[1], miny
+ redraw_block
[4]);
1368 swi(OS_Plot
, plot
, maxx
+ redraw_block
[1], maxy
+ redraw_block
[4]);
1373 block
[0] = gui
.window_handle
;
1376 block
[3] = maxx
+ 1;
1377 block
[4] = maxy
+ 1;
1378 swi(Wimp_UpdateWindow
, 0, block
);
1381 swi(ColourTrans_SetColour
, colour
, 0, 0, 0, 0);
1382 swi(OS_Plot
, 4, minx
+ block
[1], miny
+ block
[4]);
1383 swi(OS_Plot
, plot
, maxx
+ block
[1], maxy
+ block
[4]);
1384 swi(Wimp_GetRectangle
, 0, block
);
1390 * Invert a rectangle from row r, column c, for nr rows and nc columns.
1393 gui_mch_invert_rectangle(int r
, int c
, int nr
, int nc
)
1395 plot_rectangle(96 + 6, 0, FILL_X(c
), -FILL_Y(r
+ nr
), FILL_X(c
+ nc
), -FILL_Y(r
));
1399 * Iconify the GUI window.
1402 gui_mch_iconify(void)
1406 #if defined(FEAT_EVAL) || defined(PROTO)
1408 * Bring the Vim window to the foreground.
1411 gui_mch_set_foreground()
1417 /* Draw a hollow rectangle relative to the current
1418 * graphics cursor position, with the given width
1419 * and height. Start position is top-left.
1426 swi(OS_Plot
, 1, w
- 1, 0);
1427 swi(OS_Plot
, 1, 0, 1 - h
);
1428 swi(OS_Plot
, 1, 1 - w
, 0);
1429 swi(OS_Plot
, 1, 0, h
- 1);
1433 * Draw a cursor without focus.
1436 gui_mch_draw_hollow_cursor(guicolor_T colour
)
1438 int x
= FILL_X(gui
.cursor_col
); /* Window relative, top-left */
1439 int y
= -FILL_Y(gui
.cursor_row
);
1440 if (redraw_block
== NULL
)
1444 block
[0] = gui
.window_handle
;
1446 block
[2] = y
- gui
.char_height
;
1447 block
[3] = x
+ gui
.char_width
;
1449 swi(Wimp_UpdateWindow
, 0, block
);
1452 swi(ColourTrans_SetGCOL
, colour
<< 8, 0, 0, 0, 0);
1454 swi(OS_Plot
, 4, x
+ block
[1], y
+ block
[4] - 1);
1455 draw_hollow(gui
.char_width
, gui
.char_height
);
1457 swi(Wimp_GetRectangle
, 0, block
);
1462 swi(ColourTrans_SetGCOL
, colour
<< 8, 0, 0, 0, 0);
1464 swi(OS_Plot
, 4, x
+ redraw_block
[1], y
+ redraw_block
[4] - 1);
1465 draw_hollow(gui
.char_width
, gui
.char_height
);
1470 * Draw part of a cursor, "w" pixels wide, and "h" pixels high, using
1474 gui_mch_draw_part_cursor(w
, h
, colour
)
1479 int x
= FILL_X(gui
.cursor_col
);
1480 int y
= -FILL_Y(gui
.cursor_row
);
1481 swi(ColourTrans_ReturnGCOL
, colour
<< 8);
1482 plot_rectangle(96 + 5, r0
, x
, y
- h
, x
+ w
- 1, y
- 1);
1486 * Catch up with any queued events. This may put keyboard input into the
1487 * input buffer, call resize call-backs, trigger timers etc.
1488 * If there is nothing in the event queue(& no timers pending), then we return
1489 * immediately (well, after a Wimp_Poll).
1492 gui_mch_update(void)
1497 swi(OS_ReadMonotonicTime
);
1498 if ((r0
- time_of_last_poll
) < 50)
1499 return; /* Don't return too often */
1501 reason
= wimp_poll(0, block
);
1503 process_event(reason
, block
);
1504 ro_return_early
= FALSE
; /* We're returning anyway. */
1508 redraw_window(block
)
1511 int x
, y
; /* Vim workarea coords */
1515 swi(ColourTrans_ReturnGCOL
, UNUSED_COLOUR
<< 8, 0, 0, 1<<7, 0);
1518 swi(Wimp_RedrawWindow
, 0, block
);
1519 redraw_block
= block
;
1522 x
= block
[7] - block
[1];
1523 y
= block
[4] - block
[10];
1524 width
= block
[9] - block
[7];
1525 height
= block
[10] - block
[8];
1527 if (height
+ y
> Rows
* gui
.char_height
)
1529 /* Blank everything off the bottom. */
1530 plot_rectangle(96 + 5, blank_col
,
1531 0, block
[8] - block
[4],
1532 block
[9] - block
[1], -FILL_Y(Rows
) - 1);
1533 height
= Rows
* gui
.char_height
;
1535 if (width
+ x
> Columns
* gui
.char_width
)
1537 /* Blank everything off to the right. */
1538 plot_rectangle(96 + 5, blank_col
,
1539 FILL_X(Columns
), block
[8] - block
[4],
1540 block
[9] - block
[1], 0);
1541 width
= Columns
* gui
.char_width
;
1543 gui_redraw(x
, y
, width
, height
);
1544 swi(Wimp_GetRectangle
, 0, block
);
1546 redraw_block
= NULL
;
1549 /* Check if we have modified data.
1550 * If we do then ack the message to stop the shutdown.
1551 * Otherwise, ignore the message.
1557 if (!ro_ok_to_quit())
1559 /* Not OK to quit - stop shutdown */
1560 block
[3] = block
[2];
1561 swi(Wimp_SendMessage
, 19, block
, block
[1]);
1563 /* Do nothing. We may get a Message_Quit later. */
1566 /* If there is unsaved data then ask the user if they mind losing it.
1567 * Return TRUE if we can quit without saving, FALSE to halt the
1573 int old_confirm
= cmdmod
.confirm
;
1575 cmdmod
.confirm
= FALSE
; /* Use our own, single tasking, box */
1577 if (check_changed_any(FALSE
))
1579 swi(Wimp_ReportError
,
1580 "\0\0\0\0Vim contains unsaved data - quit anyway?",
1583 cmdmod
.confirm
= old_confirm
;
1587 cmdmod
.confirm
= old_confirm
;
1591 /* Quit without checking for unsaved data. */
1598 exiting
= FALSE
; /* probably can't get here */
1599 setcursor(); /* position cursor */
1603 /* Insent the given vim special code into the input buffer */
1605 ro_press(a
, b
, modifier
)
1608 int modifier
; /* %<Ctrl><Shift> 0000 0000 */
1615 /* Convert RISC OS modifier to Vim modifier. */
1616 vim_mod
= ((modifier
& 0x10) ? MOD_MASK_SHIFT
: 0)
1617 | ((modifier
& 0x20) ? MOD_MASK_CTRL
: 0);
1618 key
= simplify_key(TERMCAP2KEY(a
, b
), &vim_mod
);
1621 buf
[4] = KEY2TERMCAP0(key
);
1622 buf
[5] = KEY2TERMCAP1(key
);
1626 buf
[1] = KS_MODIFIER
;
1628 add_to_input_buf(buf
, 6);
1631 add_to_input_buf(buf
+ 3, 3);
1634 /* Take a wimp key code and insert the vim equivalent
1635 * into vim's input buffer.
1636 * CTRL-C also sets got_int.
1640 char_u
*code
; /* Wimp_ProcessKey code (4 bytes) */
1646 if (a
== 3 && ctrl_c_interrupts
)
1649 /* Is it a normal key? */
1650 if (a
> 31 && a
< 127)
1652 add_to_input_buf(code
, 1);
1656 /* We should pass any unrecognised keys on, but
1657 * for now just pass on F12 combinations.
1662 /* Home and Delete are the only special cases */
1666 ro_press('k','h', 0); /* Home */
1669 ro_press('k','D', 0); /* Delete */
1673 /* Turn CSI into K_CSI. Untested! */
1674 char_u string
[3] = {CSI
, KS_EXTRA
, KE_CSI
};
1676 add_to_input_buf(string
, 3);
1680 add_to_input_buf(code
, 1);
1684 if ((a
& 0xcf) == 0xcc)
1686 /* F12 pressed - pass it on (quick hack) */
1687 swi(Wimp_ProcessKey
, a
| 0x100);
1691 modifier
= a
& 0x30;
1694 case 0x8a: /* Tab */
1695 add_to_input_buf("\011", 1);
1697 case 0x8b: /* Copy (End) */
1698 return ro_press('@', '7', modifier
);
1699 case 0x8c: /* Left */
1700 return ro_press('k', 'l', modifier
);
1701 case 0x8d: /* Right */
1702 return ro_press('k', 'r', modifier
);
1703 case 0x8e: /* Down */
1704 if (modifier
& 0x10)
1705 return ro_press('k', 'N', modifier
^ 0x10);
1707 return ro_press('k', 'd', modifier
);
1709 if (modifier
& 0x10)
1710 return ro_press('k', 'P', modifier
^ 0x10);
1712 return ro_press('k', 'u', modifier
);
1713 case 0xca: /* F10 */
1714 return ro_press('k', ';', modifier
);
1715 case 0xcb: /* F11 */
1716 return ro_press('F', '1', modifier
);
1717 case 0xcd: /* Insert */
1718 return ro_press('k', 'I', modifier
);
1720 if (base
> 0x80 && base
< 0x18a)
1722 /* One of the other function keys */
1723 return ro_press('k', '0' + (base
& 15), modifier
);
1729 /* Process a mouse event. */
1734 int x
, y
, button
, vim_button
;
1736 int min_x
, min_y
; /* Visible area of editor window */
1739 if (block
[3] != gui
.window_handle
|| ro_dragging
)
1740 return; /* Not our window or ignoring clicks*/
1742 x
= block
[0]; /* Click position - screen coords */
1746 block
[0] = gui
.window_handle
;
1747 swi(Wimp_GetWindowState
, 0, block
);
1753 if (block
[3] - x
< gui
.scrollbar_width
)
1755 /* Click in that blank area under the scrollbars */
1759 int front_block
[10];
1760 /* Dragging with Select - bring window to front first */
1761 front_block
[0] = gui
.window_handle
;
1762 swi(Wimp_GetWindowState
, 0, front_block
);
1763 front_block
[7] = -1;
1764 ro_open_main(front_block
);
1767 block
[0] = gui
.window_handle
;
1768 block
[1] = 7; /* Drag point */
1769 block
[2] = block
[4] = 0; /* Coords of point. */
1770 block
[3] = block
[5] = 0;
1771 drag_x_offset
= max_x
- x
;
1772 drag_y_offset
= min_y
- y
;
1776 gui
.scrollbar_width
* 2 +
1777 MIN_COLUMNS
* gui
.char_width
;
1779 gui_mch_get_screen_dimensions(&block
[8], &block
[9]);
1781 4 * gui
.char_height
-
1782 gui
.scrollbar_height
;
1784 swi(Wimp_DragBox
, 0, block
);
1785 ro_dragging
= DRAG_RESIZE_WINDOW
;
1786 drag_button
= vim_button
;
1787 drag_modifiers
= modifiers
;
1792 vim_button
= MOUSE_RIGHT
;
1793 else if (button
& 0x222)
1794 vim_button
= MOUSE_MIDDLE
;
1796 vim_button
= MOUSE_LEFT
;
1798 swi(OS_Byte
, 121, 0x80);
1800 modifiers
|= MOUSE_SHIFT
;
1801 swi(OS_Byte
, 121, 0x81);
1803 modifiers
|= MOUSE_CTRL
;
1804 swi(OS_Byte
, 121, 0x82);
1806 modifiers
|= MOUSE_ALT
;
1811 * If shift was pressed then do the paste action.
1812 * If not, then open the pop-up menu.
1814 modifiers
^= MOUSE_SHIFT
;
1815 if (modifiers
&& MOUSE_SHIFT
)
1818 /* Shift was NOT pressed - show menu */
1819 main
.dname
= (char_u
*) "Vim";
1820 main
.children
= root_menu
;
1821 gui_mch_show_popupmenu(&main
);
1826 /* Gain the input focus */
1827 swi(Wimp_SetCaretPosition
, gui
.window_handle
, -1, 0, 0, -1, -1);
1833 * Tell the Wimp to start a drag.
1834 * Monitor null events.
1836 block
[1] = 7; /* Drag a point. */
1837 block
[2] = block
[4] = x
; /* Coords of point. */
1838 block
[3] = block
[5] = y
;
1839 block
[6] = 0; /* Coords of bounding box. */
1841 gui_mch_get_screen_dimensions(&block
[8], &block
[9]);
1843 drag_x_offset
= drag_y_offset
= 0;
1845 swi(Wimp_DragBox
, 0, block
);
1846 ro_dragging
= DRAG_SELECTION
;
1847 drag_button
= vim_button
;
1848 drag_modifiers
= modifiers
;
1850 vim_button
|= MOUSE_DRAG
;
1853 gui_send_mouse_event(
1857 button
& 0xf ? TRUE
: FALSE
, /* dclick */
1862 ro_continue_drag(block
)
1863 int *block
; /* Just used as scrap. */
1867 /* Get screen coords of pointer. */
1868 swi(Wimp_GetPointerInfo
, 0, block
);
1869 x
= block
[0] + drag_x_offset
;
1870 y
= block
[1] + drag_y_offset
;
1872 block
[0] = gui
.window_handle
;
1873 swi(Wimp_GetWindowState
, 0, block
);
1875 if (ro_dragging
== DRAG_RESIZE_WINDOW
)
1877 /* Resizeing the main window. */
1880 ro_open_main(block
);
1884 /* Selecting some text. */
1885 gui_send_mouse_event(
1886 drag_button
| MOUSE_DRAG
, /* Always report the same button */
1889 FALSE
, /* Not a double click. */
1894 /* User has released all mouse buttons, marking the end of a drag. */
1896 ro_drag_finished(block
)
1903 /* I don't trust the box returned by Wimp_Poll; look at the pointer
1906 swi(Wimp_GetPointerInfo
, 0, block
);
1907 x
= block
[0] + drag_x_offset
;
1908 y
= block
[1] + drag_y_offset
;
1910 if (ro_dragging
== DRAG_RESIZE_WINDOW
)
1912 block
[0] = gui
.window_handle
;
1913 swi(Wimp_GetWindowState
, 0, block
);
1916 ro_open_main(block
);
1918 width
= (block
[3] - block
[1]);
1919 height
= (block
[4] - block
[2]);
1921 swi(Wimp_ForceRedraw
, gui
.window_handle
, 0, -height
, width
, 0);
1922 gui_resize_shell(width
, height
);
1926 block
[0] = gui
.window_handle
;
1927 swi(Wimp_GetWindowState
, 0, block
);
1928 gui_send_mouse_event(
1932 FALSE
, /* not a double click */
1935 ro_dragging
= DRAG_FALSE
;
1938 /* Load the file/pathname given in block into a [new] buffer.
1942 * None :confirm e <file>
1946 * Insert into typebuf, at the start.
1947 * If loading from !Scrap then use saved leafname instead, and
1948 * delete the scrap file. Also, ignore shift key.
1950 * NB: Doesn't send DataLoadAck (other app might delete temp file?).
1956 char_u new_path
[MAXPATHL
];
1957 char_u
*path
= ((char_u
*) block
) + 44;
1960 if (block
[3] == leaf_ref
&& leaf_name
)
1963 switch (get_real_state() & 0xff)
1967 case CMDLINE
+LANGMAP
:
1968 /* For insert mode we can only insert the pathname (currently)
1969 * Make sure Shift is pressed.
1971 swi(OS_Byte
, 121, 0x80); /* Is Shift pressed? */
1974 ins_typebuf(" ", REMAP_NONE
, 0, TRUE
, FALSE
);
1975 ins_typebuf(path
, REMAP_NONE
, 0, TRUE
, FALSE
);
1976 ro_return_early
= TRUE
; /* Return even though nothing was typed. */
1979 swi(Wimp_ReportError
,
1980 "\0\0\0\0Sorry, you can only load text in normal mode", 5, "Vim");
1984 ro_return_early
= TRUE
; /* Return even though nothing was typed. */
1986 if (scrap
) /* Remove <Wimp$Scrap>. Later. */
1987 ins_typebuf(":!~remove <Wimp$Scrap>\r", REMAP_NONE
, 0, TRUE
, FALSE
);
1989 /* Insert {:sp ,:confirm e }[+f\ <leaf> ]<file><CR> */
1990 ins_typebuf("\r", REMAP_NONE
, 0, TRUE
, FALSE
);
1991 ins_typebuf(path
, REMAP_NONE
, 0, TRUE
, FALSE
);
1992 ins_typebuf(" ", REMAP_NONE
, 0, TRUE
, FALSE
);
1996 /* Loading via !Scrap - change pathname to stored leafname */
1997 ins_typebuf(leaf_name
, REMAP_NONE
, 0, TRUE
, FALSE
);
1998 ins_typebuf(" +f\\ ", REMAP_NONE
, 0, TRUE
, FALSE
);
2000 vim_free(leaf_name
);
2004 swi(OS_Byte
, 121, 0x81); /* Is Ctrl pressed? */
2006 /* Yes, split window */
2007 ins_typebuf(":sp", REMAP_NONE
, 0, TRUE
, FALSE
);
2009 ins_typebuf(":confirm e", REMAP_NONE
, 0, TRUE
, FALSE
);
2013 swi(Wimp_ReportError
, "\0\0\0\0You can only load text in normal mode.", 5, "Vim");
2015 /* Send DataSaveAck so other program doesn't think we died
2016 * and delete <Wimp$Scrap>.
2018 block
[3] = block
[2];
2020 swi(Wimp_SendMessage
, 17, block
, block
[1]);
2027 char_u
*path
= ((char_u
*) block
) + 44;
2029 /* Preserve the name given so we can use it, not <Wimp$Scrap> */
2031 vim_free(leaf_name
);
2032 leaf_name
= vim_strsave(path
);
2034 block
[9] = -1; /* File is unsafe. */
2035 strcpy(path
, "<Wimp$Scrap>");
2037 block
[3] = block
[2];
2039 swi(Wimp_SendMessage
, 17, block
, block
[1]);
2041 leaf_ref
= block
[2];
2051 if (block
[1] == task_handle
)
2052 return; /* Don't talk to ourself! */
2059 case 1: /* DataSave */
2062 case 2: /* DataSaveAck. */
2063 if (clip_convert_selection(&buffer
, &len
, &clip_star
) == -1)
2066 /* Save the clipboard contents to a file. */
2067 swi(OS_File
, 10, ((char_u
*) block
) + 44, 0xfff, 0, buffer
, buffer
+ len
);
2069 /* Ack with DataLoad message. */
2070 block
[3] = block
[2];
2073 swi(Wimp_SendMessage
, 17, block
, block
[1]);
2077 case 3: /* DataLoad */
2080 case 8: /* PreQuit */
2083 case 0xf: /* Lose clipboard. */
2086 clip_free_selection(&clip_star
);
2087 clip_star
.owned
= FALSE
;
2090 case 0x10: /* DataRequest (clip_star) */
2091 if (clip_star
.owned
)
2095 /* Tell other program that we have the clipboard. */
2097 block
[3] = block
[2]; /* Copy myref to yourref. */
2098 block
[4] = 1; /* DataSave message. */
2099 /* Create an estimate for the size (larger or same as true
2101 rows
= clip_star
.end
.lnum
- clip_star
.start
.lnum
;
2104 block
[9] = (rows
+ 1) * Columns
+ 1; /* Add one for possible
2106 block
[10] = 0xfff; /* Clipboard is text. */
2107 strcpy( ((char_u
*) block
) + 44, "VimClip");
2108 swi(Wimp_SendMessage
, 17, block
, block
[1]);
2111 case 0x400c1: /* Mode change */
2112 changed_mode
= TRUE
; /* Flag - update on next OpenWindow */
2115 /* JK230798, re-initialise ZapRedraw stuff */
2116 if (ro_zap_redraw_initialise() == FAIL
)
2120 case 0x400c3: /* TaskCloseDown */
2121 if (block
[1] == child_handle
)
2128 * Converts a scrollbar's window handle into a scrollbar pointer.
2137 if (gui
.bottom_sbar
.id
== id
)
2138 return &gui
.bottom_sbar
;
2141 if (wp
->w_scrollbars
[SBAR_LEFT
].id
== id
)
2142 return &wp
->w_scrollbars
[SBAR_LEFT
];
2143 if (wp
->w_scrollbars
[SBAR_RIGHT
].id
== id
)
2144 return &wp
->w_scrollbars
[SBAR_RIGHT
];
2151 int sb
; /* Scrollbar number */
2156 /* Don't put events in the input queue now. */
2157 if (hold_gui_events
)
2160 /* Send a scroll event:
2162 * A scrollbar event is CSI (NOT K_SPECIAL), KS_VER_SCROLLBAR,
2163 * KE_FILLER followed by:
2164 * one byte representing the scrollbar number, and then four bytes
2165 * representing a long_u which is the new value of the scrollbar.
2168 code
[1] = KS_VER_SCROLLBAR
;
2169 code
[2] = KE_FILLER
;
2171 code
[4] = line
>> 24;
2172 code
[5] = line
>> 16;
2173 code
[6] = line
>> 8;
2175 add_to_input_buf(code
, 8);
2184 /* Don't put events in the input queue now. */
2185 if (hold_gui_events
)
2188 /* Send a scroll event:
2190 * A scrollbar event is CSI (NOT K_SPECIAL)
2192 * A horizontal scrollbar event is K_SPECIAL, KS_HOR_SCROLLBAR,
2193 * KE_FILLER followed by four bytes representing a long_u which is the
2194 * new value of the scrollbar.
2197 code
[1] = KS_HOR_SCROLLBAR
;
2198 code
[2] = KE_FILLER
;
2199 code
[4] = col
>> 24;
2200 code
[5] = col
>> 16;
2203 add_to_input_buf(code
, 8);
2214 /* Block is ready for Wimp_OpenWindow, and also contains:
2216 * +32 = scroll X direction (-2 .. +2)
2217 * +36 = scroll Y direction (-2 .. +2)
2220 sb
= ro_find_sbar(block
[0]);
2222 return; /* Window not found (error). */
2228 /* Horizontal bar. */
2231 offset
= (block
[1] - block
[3]) / gui
.char_width
;
2232 else if (offset
== 2)
2233 offset
= (block
[3] - block
[1]) / gui
.char_width
;
2235 block
[5] += offset
* gui
.char_width
;
2237 gui_drag_scrollbar(sb
, block
[5] / gui
.char_width
, FALSE
);
2239 swi(Wimp_OpenWindow
, 0, block
);
2245 offset
= -(wp
-> w_height
- 1);
2246 else if (offset
== 2)
2247 offset
= wp
-> w_height
- 1;
2249 /* Possibly we should reposition the scrollbar?
2250 * Vim seems to update the bar anyway...
2252 gui_drag_scrollbar(sb
, offset
- (block
[6] / gui
.char_height
), FALSE
);
2256 /* Move a window by a given offset. Used to simulate the function of the
2260 ro_move_child(window
, x
, y
, pos_wanted
, pos_got
)
2262 int x
,y
; /* offset to move by */
2263 int pos_wanted
, pos_got
;
2268 swi(Wimp_GetWindowState
, 0, block
);
2273 if (pos_wanted
== -1)
2275 else if (pos_wanted
== -2)
2277 swi(Wimp_OpenWindow
, 0, block
);
2280 /* Open the main window. Also updates scrollbars if we are not
2281 * using the nested Wimp.
2282 * If we have just changed mode then re-read all values.
2290 /* Find out if the user clicked on the toggle size icon. */
2291 block
[20] = block
[0];
2292 swi(Wimp_GetWindowState
, 0, block
+ 20);
2293 toggle_size
= block
[28] & (1 << 19);
2297 swi(Wimp_OpenWindow
, 0, block
);
2302 int x_offset
, y_offset
; /* Move children same as parent. */
2303 int pos_wanted
, pos_got
;
2304 int left_bar
= gui
.which_scrollbars
[SBAR_LEFT
];
2305 int right_bar
= gui
.which_scrollbars
[SBAR_RIGHT
];
2308 /* Three cases to think about:
2309 * 1) Move to top. Open each window at the top.
2310 * 2) Same stack position. Open each with same position.
2311 * 3) Open at bottom. Open children with parent's new position.
2315 swi(Wimp_GetWindowState
, 0, old
);
2316 pos_wanted
= block
[7];
2317 swi(Wimp_OpenWindow
, 0, block
);
2318 /* Block updated by OpenWindow? I don't think so! */
2319 swi(Wimp_GetWindowState
, 0, block
);
2322 x_offset
= block
[1] - old
[1];
2323 y_offset
= block
[4] - old
[4];
2324 if (x_offset
|| y_offset
|| pos_wanted
== -1 || pos_wanted
== -2)
2326 /* If parent has moved, re-open all the child windows. */
2329 /* Reopen scrollbars for this window. */
2331 ro_move_child(wp
-> w_scrollbars
[SBAR_LEFT
].id
,
2333 pos_wanted
, pos_got
);
2335 ro_move_child(wp
-> w_scrollbars
[SBAR_RIGHT
].id
,
2337 pos_wanted
, pos_got
);
2341 if (changed_mode
|| toggle_size
)
2347 block
[0] = gui
.window_handle
;
2348 swi(Wimp_GetWindowState
, 0, block
);
2350 width
= block
[3] - block
[1];
2351 height
= block
[4] - block
[2];
2352 swi(Wimp_ForceRedraw
, gui
.window_handle
, 0, -height
, width
, 0);
2353 gui_resize_shell(width
, height
);
2354 changed_mode
= FALSE
;
2359 ro_open_window(block
)
2365 if (block
[0] == gui
.window_handle
)
2366 ro_open_main(block
);
2369 swi(Wimp_OpenWindow
, 0, block
);
2370 if (block
[0] != gui
.window_handle
)
2372 sb
= ro_find_sbar(block
[0]);
2375 if (sb
-> wp
!= NULL
)
2376 gui_drag_scrollbar(sb
, -block
[6] / gui
.char_height
, FALSE
);
2378 gui_drag_scrollbar(sb
, block
[5] / gui
.char_width
, FALSE
);
2385 ro_menu_selection(block
)
2388 int *item
= wimp_menu
+ 7;
2390 /* wimp_menu points to a wimp menu structure */
2398 item
= ((int *) item
[1]) + 7;
2401 /* item points to the wimp menu item structure chosen */
2402 menu
= (vimmenu_T
*) item
[5];
2404 swi(Wimp_GetPointerInfo
, 0, block
);
2406 /* Adjust used - keep menu open */
2407 swi(Wimp_CreateMenu
, 0, wimp_menu
);
2417 char_u
*i
= curbuf
-> b_ffname
;
2424 head
= i
- curbuf
-> b_ffname
;
2427 /* Append head chars to buffer */
2428 if (head
< 240 && curbuf
-> b_ffname
&& head
)
2430 strcpy(buffer
, "%filer_opendir ");
2431 strncpy(buffer
+ 15, curbuf
-> b_ffname
, head
);
2432 buffer
[15 + head
] = '\0';
2433 swi(OS_CLI
, buffer
);
2438 process_event(event
, block
)
2444 case 0: /* Nothing - update drag state. */
2446 ro_continue_drag(block
);
2448 case 1: /* Redraw window. */
2449 redraw_window(block
);
2451 case 2: /* Open window. */
2452 ro_open_window(block
);
2454 case 3: /* Close window. */
2455 swi(Wimp_GetPointerInfo
, 0, block
+ 1);
2459 if (ro_ok_to_quit())
2462 case 6: /* Mouse click. */
2465 case 7: /* Finished drag. */
2466 ro_drag_finished(block
);
2468 case 8: /* Key pressed. */
2469 ro_insert_key((char_u
*) &block
[6]);
2472 ro_menu_selection(block
);
2474 case 10: /* Scroll request. */
2477 case 11: /* Lose caret. */
2478 if (block
[0] == gui
.window_handle
)
2479 gui_focus_change(FALSE
);
2481 case 12: /* Gain caret. */
2482 if (block
[0] == gui
.window_handle
)
2483 gui_focus_change(TRUE
);
2485 case 17: /* User message. */
2486 case 18: /* User message recorded. */
2493 * GUI input routine called by gui_wait_for_chars(). Waits for a character
2494 * from the keyboard.
2495 * wtime == -1 Wait forever.
2496 * wtime == 0 This should never happen.
2497 * wtime > 0 Wait wtime milliseconds for a character.
2498 * Returns OK if a character was found to be available within the given time,
2499 * or FAIL otherwise.
2502 gui_mch_wait_for_chars(long wtime
)
2506 int start_time
= -1;
2507 int ctime
= wtime
/ 10; /* delay in cs */
2511 swi(OS_ReadMonotonicTime
);
2518 reason
= wimp_poll(0, block
); /* Always return immediately */
2519 else if (wtime
== -1)
2520 reason
= wimp_poll(1, block
);
2522 reason
= wimp_pollidle(0, block
, start_time
+ ctime
);
2524 process_event(reason
, block
);
2526 if (input_available() || ro_return_early
)
2528 ro_return_early
= FALSE
;
2529 return OK
; /* There is something to process (key / menu event) */
2534 swi(OS_ReadMonotonicTime
);
2535 if (r0
- start_time
> ctime
)
2536 return FAIL
; /* We've been waiting too long - return failure */
2541 /* Flush any output to the screen */
2548 * Clear a rectangular region of the screen from text pos(row1, col1) to
2549 * (row2, col2) inclusive.
2552 gui_mch_clear_block(int row1
, int col1
, int row2
, int col2
)
2554 swi(ColourTrans_ReturnGCOL
, gui
.back_pixel
<< 8, 0, 0, 1<<7, 0);
2555 plot_rectangle(96 + 5, r0
,
2556 FILL_X(col1
), -FILL_Y(row2
+ 1),
2557 FILL_X(col2
+ 1), -FILL_Y(row1
));
2561 gui_mch_clear_all(void)
2565 swi(ColourTrans_SetGCOL
, gui
.back_pixel
<< 8, 0, 0, 1<<7, 0);
2566 swi(OS_WriteI
+ 16);
2571 block
[0] = gui
.window_handle
;
2573 block
[2] = -gui
.num_rows
* gui
.char_height
;
2574 block
[3] = gui
.num_cols
* gui
.char_width
;
2576 swi(Wimp_UpdateWindow
, 0, block
);
2579 swi(ColourTrans_SetGCOL
, gui
.back_pixel
<< 8, 0, 0, 1<<7, 0);
2580 swi(OS_WriteI
+ 16);
2581 swi(Wimp_GetRectangle
, 0, block
);
2587 * Delete the given number of lines from the given row, scrolling up any
2588 * text further down within the scroll region.
2591 gui_mch_delete_lines(int row
, int num_lines
)
2593 int top_from
= -row
- num_lines
;
2594 int bot_from
= -gui
.scroll_region_bot
- 1;
2595 int bot_to
= bot_from
+ num_lines
;
2597 swi(ColourTrans_SetGCOL
, gui
.back_pixel
<< 8, 0, 0, 0x80, 0);
2599 /* Changed without checking! */
2600 swi(Wimp_BlockCopy
, gui
.window_handle
,
2601 gui
.scroll_region_left
* gui
.char_width
,
2602 bot_from
* gui
.char_height
,
2603 (gui
.scroll_region_right
- gui
.scroll_region_left
2604 + 1) * gui
.char_width
,
2605 top_from
* gui
.char_height
,
2607 gui
.scroll_region_left
* gui
.char_width
,
2608 bot_to
* gui
.char_height
);
2610 gui_clear_block(gui
.scroll_region_bot
- num_lines
+ 1,
2611 gui
.scroll_region_left
,
2612 gui
.scroll_region_bot
, gui
.scroll_region_right
);
2616 * Insert the given number of lines before the given row, scrolling down any
2617 * following text within the scroll region.
2620 gui_mch_insert_lines(int row
, int num_lines
)
2622 int top_from
= -row
;
2623 int bot_to
= -gui
.scroll_region_bot
- 1;
2624 int bot_from
= bot_to
+ num_lines
;
2626 swi(ColourTrans_SetGCOL
, gui
.back_pixel
<< 8, 0, 0, 0x80, 0);
2628 swi(Wimp_BlockCopy
, gui
.window_handle
,
2629 gui
.scroll_region_left
* gui
.char_width
,
2630 bot_from
* gui
.char_height
,
2631 (gui
.scroll_region_right
- gui
.scroll_region_left
2632 + 1) * gui
.char_width
,
2633 top_from
* gui
.char_height
,
2635 gui
.scroll_region_left
* gui
.char_width
,
2636 bot_to
* gui
.char_height
);
2638 gui_clear_block(row
, gui
.scroll_region_left
,
2639 row
+ num_lines
- 1, gui
.scroll_region_right
);
2642 /* Put selection in clipboard buffer.
2643 * Should we become the new owner?
2646 clip_mch_request_selection(VimClipboard
*cbd
)
2648 int block
[64]; /* Will be used in Wimp_Poll. */
2653 block
[0] = 48; /* Size of block. */
2654 block
[3] = 0; /* Orinial message. */
2655 block
[4] = 0x10; /* Data request. */
2656 block
[5] = gui
.window_handle
;
2657 block
[6] = RO_LOAD_CLIPBOARD
; /* Internal handle. */
2658 block
[7] = block
[8] = 0; /* (x,y) not used. */
2660 block
[10] = 0xfff; /* We want text files if possible, I think. */
2661 block
[11] = -1; /* End of list. */
2662 swi(Wimp_SendMessage
, 17, block
, 0); /* Broadcast request. */
2664 /* OK, we've sent the request. Poll until we get a null poll (failure) or
2665 * we load the clipboard.
2666 * If we receive a DataSave event with icon handle = -2 then put it on the
2667 * clipboard. RISC OS should ensure that key events will not be delivered
2668 * until the clipboard operation completes (unless the owner starts idling
2669 * - we can't wait forever!).
2673 reason
= wimp_poll(0, block
);
2675 return; /* Failed to get clipboard. */
2676 if ((reason
== 17 || reason
== 18) &&
2677 block
[4] == 1 && block
[6] == RO_LOAD_CLIPBOARD
)
2678 break; /* Got it - stop waiting. */
2679 process_event(reason
, block
);
2680 if (ro_return_early
)
2683 /* Tell owner to save data in <Wimp$Scrap>. */
2685 block
[3] = block
[2]; /* Copy myref -> yourref */
2686 block
[4] = 2; /* DataSaveAck. */
2687 block
[9] = -1; /* Data is unsafe. */
2688 strcpy( ((char_u
*) block
) + 44, "<Wimp$Scrap>");
2689 swi(Wimp_SendMessage
, 17, block
, block
[1]);
2691 /* Wait again for reply. */
2694 reason
= wimp_poll(0, block
);
2696 return; /* Other program has given up! */
2697 if ((reason
== 17 || reason
== 18) && block
[4] == 3 && block
[6] == RO_LOAD_CLIPBOARD
)
2698 break; /* Clipboard data saved to <Wimp$Scrap> */
2699 process_event(reason
, block
);
2700 if (ro_return_early
)
2704 /* <Wimp$Scrap> contains clipboard - load it. */
2705 if (xswi(OS_File
, 17, "<Wimp$Scrap>") & v_flag
)
2706 return; /* Error! */
2707 if (r0
!= 1 && r0
!= 3)
2711 buffer
= lalloc(length
, TRUE
); /* Claim memory (and report errors). */
2715 if (xswi(OS_File
, 16, "<Wimp$Scrap>", buffer
, 0) & v_flag
)
2718 clip_yank_selection(MCHAR
, buffer
, length
, cbd
);
2722 swi(OS_FSControl
, 27, "<Wimp$Scrap>", 0, 0); /* Delete temp file. */
2724 block
[4] = 4; /* Send DataLoadAck. */
2725 block
[3] = block
[2]; /* Copy myref -> yourref. */
2726 swi(Wimp_SendMessage
, 17, block
, block
[1]);
2729 /* Not sure what this means under RISC OS. */
2731 clip_mch_lose_selection(VimClipboard
*cbd
)
2735 /* Tell everyone that we now own the clipboard.
2736 * Return OK if our claim is accepted (always, under RISC OS)
2739 clip_mch_own_selection(VimClipboard
*cbd
)
2742 block
[0] = 24; /* Length of block. */
2743 block
[3] = 0; /* Original message. */
2744 block
[4] = 0xf; /* ClaimEntity. */
2745 block
[5] = 0x4; /* Claim clipboard only. */
2746 swi(Wimp_SendMessage
, 17, block
, 0);
2751 * Send the current selection to the clipboard. Do nothing for X because we
2752 * will fill in the selection only when requested by another app. Sounds good
2756 clip_mch_set_selection(VimClipboard
*cbd
)
2758 clip_get_selection(cbd
);
2762 * Make a menu either grey or not grey.
2765 gui_mch_menu_grey(vimmenu_T
*menu
, int grey
)
2767 menu
-> greyed_out
= grey
;
2771 * Make menu item hidden or not hidden
2774 gui_mch_menu_hidden(vimmenu_T
*menu
, int hidden
)
2776 menu
-> hidden
= hidden
;
2780 * This is called after setting all the menus to grey/hidden or not.
2783 gui_mch_draw_menubar(void)
2785 swi(Wimp_CreateMenu
, 0, -1);
2786 if (wimp_menu
!= (int *) -1)
2788 ro_remove_menu(wimp_menu
);
2789 wimp_menu
= (int *) -1;
2793 /* Add or remove a scrollbar. Note that this is only called when
2794 * the scrollbar state is changing.
2795 * The scroll bar window has already been created.
2796 * We can't do anything except remove the scroll bar
2797 * until we know what size to use.
2800 gui_mch_enable_scrollbar(sb
, flag
)
2805 swi(Wimp_CloseWindow
, 0, & (sb
->id
) );
2810 gui_mch_set_blinking(long waittime
, long on
, long off
)
2815 * Stop the cursor blinking. Show the cursor if it wasn't shown.
2818 gui_mch_stop_blink(void)
2823 * Start the cursor blinking. If it was already blinking, this restarts the
2824 * waiting time and shows the cursor.
2827 gui_mch_start_blink(void)
2832 * Return the RGB value of a pixel as a long.
2835 gui_mch_get_rgb(guicolor_T pixel
)
2837 return (long_u
)pixel
;
2841 gui_mch_set_text_area_pos(int x
, int y
, int w
, int h
)
2846 gui_mch_enable_menu(int flag
)
2851 gui_mch_set_menu_pos(int x
, int y
, int w
, int h
)
2856 gui_mch_add_menu(vimmenu_T
*menu
, int idx
)
2861 gui_mch_add_menu_item(vimmenu_T
*menu
, int idx
)
2866 gui_mch_new_menu_colors(void)
2871 gui_mch_destroy_menu(vimmenu_T
*menu
)
2875 /* Size of buffer has changed.
2876 * Add one to max since gui.c subtracts one more than it should!
2879 gui_mch_set_scrollbar_thumb(sb
, val
, size
, max
)
2885 int block
[10], width
, height
;
2887 width
= (max
+ 1) * gui
.char_width
;
2888 height
= (max
+ 1 + W_STATUS_HEIGHT(sb
->wp
)) * gui
.char_height
;
2890 block
[0] = block
[3] = 0;
2891 block
[1] = -height
+ (1 << y_eigen_factor
);
2894 swi(Wimp_SetExtent
, sb
-> id
, block
);
2896 block
[0] = sb
-> id
;
2897 swi(Wimp_GetWindowState
, 0, block
);
2898 block
[5] = val
* gui
.char_width
;
2899 block
[6] = -val
* gui
.char_height
;
2900 swi(Wimp_OpenWindow
, 0, block
, 0x4b534154,
2901 gui
.window_handle
, /* Parent window handle. */
2902 (CHILD_FIX_TO_RIGHT
<< CHILD_LEFT
) |
2903 (CHILD_FIX_TO_RIGHT
<< CHILD_RIGHT
) |
2904 (CHILD_FIX_TO_BOTTOM
<< CHILD_TOP
) |
2905 (CHILD_FIX_TO_BOTTOM
<< CHILD_BOTTOM
) |
2906 (CHILD_SELF_SCROLL
<< CHILD_SCROLL_X
) |
2907 (CHILD_SELF_SCROLL
<< CHILD_SCROLL_Y
)
2911 /* Set the position of the scrollbar within the editor
2912 * window. Note that, for vertical scrollbars, x and w
2913 * are ignored. For horizontal bars y and h are ignored.
2916 gui_mch_set_scrollbar_pos(sb
, x
, y
, w
, h
)
2918 int x
; /* Horizontal sb position */
2919 int y
; /* Top of scroll bar */
2924 int px1
, py1
; /* Parent window min coords */
2925 int px2
, py2
; /* Parent window max coords */
2927 /* Find where the parent window is. */
2928 block
[0] = gui
.window_handle
;
2929 swi(Wimp_GetWindowState
, 0, block
);
2935 block
[0] = sb
-> id
;
2937 /* Find out how big the scroll window is at the moment. */
2938 swi(Wimp_GetWindowInfo
, 0, ((char_u
*)block
) + 1);
2940 if (block
[13] < w
|| block
[12] > -h
)
2942 /* Current window is too small! */
2947 swi(Wimp_SetExtent
, block
[0], block
+ 11);
2950 /* This works better on the nested_wimp. */
2953 /* This is a vertical scrollbar. */
2954 block
[1] = block
[3] = px2
- gui
.scrollbar_width
+ (1 << x_eigen_factor
);
2955 block
[2] = 1 + py2
- (y
+ h
) + (1 << y_eigen_factor
);
2956 block
[4] = 1 + py2
- y
;
2960 /* This is a horizontal scrollbar. */
2961 block
[2] = block
[4] = py1
+ gui
.scrollbar_height
;
2963 block
[3] = px2
- gui
.scrollbar_width
;
2970 swi(Wimp_OpenWindow
, 0, block
, 0x4b534154,
2971 gui
.window_handle
, /* Parent window handle. */
2972 (CHILD_FIX_TO_RIGHT
<< CHILD_LEFT
) |
2973 (CHILD_FIX_TO_RIGHT
<< CHILD_RIGHT
) |
2974 (CHILD_FIX_TO_BOTTOM
<< CHILD_TOP
) |
2975 (CHILD_FIX_TO_BOTTOM
<< CHILD_BOTTOM
) |
2976 (CHILD_SELF_SCROLL
<< CHILD_SCROLL_X
) |
2977 (CHILD_SELF_SCROLL
<< CHILD_SCROLL_Y
)
2981 /* Create a window with no workarea to place inside editor window.
2982 * (what happens without the nested wimp?)
2983 * Data for scrollbar is invalid.
2986 gui_mch_create_scrollbar(sb
, orient
)
2988 int orient
; /* orient is SBAR_HORIZ or SBAR_VERT */
2992 0, 0, /* Visible area : min X,Y */
2993 100, 100, /* max X,Y */
2994 0, 0, /* Scroll offsets */
2995 -1, /* Window in front */
2996 0x80800150 | (orient
== SBAR_HORIZ
? (1 << 30) : (1 << 28)),
2997 0xff070207, /* Colours */
2998 0x000c0103, /* More colours */
2999 0, -0x4000, /* Workarea extent */
3000 0x4000, 0, /* max X,Y */
3001 0x00000000, /* No title */
3002 0 << 12, /* No workarea button type */
3003 1, /* Wimp sprite area */
3004 0x00010001, /* Minimum width, height */
3005 0, 0, 0, /* Title data (none) */
3008 swi(Wimp_CreateWindow
, 0, bar
);
3012 #if defined(FEAT_WINDOWS) || defined(PROTO)
3014 gui_mch_destroy_scrollbar(scrollbar_T
*sb
)
3016 swi(Wimp_DeleteWindow
, 0, & (sb
->id
));
3022 gui_mch_set_scrollbar_colors(scrollbar_T
*sb
)
3024 /* Always use default RO colour scheme. */
3028 * Get current mouse coordinates in text window.
3029 * Note: (0,0) is the bottom left corner, positive y is UP.
3032 gui_mch_getmouse(x
, y
)
3040 block
[0] = gui
.window_handle
;
3041 swi(Wimp_GetWindowState
, 0, block
);
3045 swi(Wimp_GetPointerInfo
, 0, block
);
3046 *x
= block
[0] - left
;
3047 *y
= top
- block
[1];
3052 gui_mch_setmouse(x
, y
)
3059 gui_mch_toggle_tearoffs(enable
)
3062 /* no tearoff menus */
3065 /* Redraw a window's title.
3066 * For the nested wimp we use the new 'redraw-title-bar' reason code.
3067 * For older wimps we mark the area of the screen where the title bar
3071 ro_redraw_title(window
)
3076 swi(Wimp_ForceRedraw
, window
, 0x4b534154, 3);
3084 swi(Wimp_GetWindowState
, 0, block
);
3086 swi(Wimp_GetWindowOutline
, 0, block
);
3087 swi(Wimp_ForceRedraw
, -1,
3089 block
[3], block
[4]);
3093 /* Turn a vimmenu_T structure into a wimp menu structure.
3094 * -1 if resulting menu is empty.
3095 * Only the children and dname items in the root menu are used.
3108 /* Find out how big the menu is so we can allocate memory for it */
3109 for (item
= menu
-> children
; item
; item
= item
-> next
)
3111 if (item
-> hidden
== FALSE
&& !menu_is_separator(item
->name
))
3116 return (int *) -1; /* No children - shouldn't happen */
3118 wimp_menu
= (int *) alloc(size
);
3120 wimp_menu
[0] = (int) menu
-> dname
;
3123 wimp_menu
[3] = 0x00070207;
3127 wimp_item
= wimp_menu
+ 7;
3129 for (item
= menu
-> children
; item
; item
= item
-> next
)
3131 if (menu_is_separator(item
-> name
))
3133 /* This menu entry is actually a separator. If it is not the first
3134 * menu entry then mark the previous menu item as needing a dotted
3137 if (wimp_item
> wimp_menu
+ 7)
3138 wimp_item
[-6] |= 0x2;
3140 else if (item
-> hidden
== FALSE
)
3143 wimp_item
[1] = item
-> children
? (int) ro_build_menu(item
) : -1;
3144 wimp_item
[2] = 0x07009131 | (item
-> greyed_out
<< 22);
3145 wimp_item
[3] = (int) item
-> dname
;
3147 wimp_item
[5] = (int) item
; /* Stuff the menu address in this unused space */
3149 w
= strlen(item
-> dname
) + 1;
3156 wimp_menu
[4] = (width
+ 2) * 16;
3157 wimp_menu
[7] |= 0x100; /* Menu title is indirected */
3158 wimp_item
[-6] |= 0x080; /* Last entry in menu */
3163 ro_remove_menu(menu
)
3166 int *item
= menu
+ 7;
3168 if (menu
== NULL
|| menu
== (int *) -1)
3174 ro_remove_menu((int *) item
[1]); /* Remove sub-menu */
3176 break; /* This was the last entry */
3183 gui_mch_show_popupmenu(menu
)
3188 /* Remove the existing menu, if any */
3189 if (wimp_menu
!= (int *) -1)
3191 swi(Wimp_CreateMenu
, 0, -1);
3192 ro_remove_menu(wimp_menu
);
3193 wimp_menu
= (int *) -1;
3196 wimp_menu
= ro_build_menu(menu
);
3197 if (wimp_menu
!= (int *) -1)
3199 swi(Wimp_GetPointerInfo
, 0, block
);
3200 swi(Wimp_CreateMenu
, 0, wimp_menu
, block
[0] - 64, block
[1] + 64);
3204 /* Run a command using the TaskWindow module.
3205 * If SHELL_FILTER is set then output is not echoed to the screen,
3206 * If it is not set, then \r is not sent to the output file.
3209 gui_mch_call_shell(cmd
, options
)
3211 int options
; /* SHELL_FILTER if called by do_filter() */
3212 /* SHELL_COOKED if term needs cooked mode */
3214 char_u task_cmd
[256]; /* Contains *TaskWindow command. */
3222 FILE *out_file
= NULL
;
3224 out_redir
= strstr(cmd
, " > ");
3225 if (out_redir
== NULL
)
3226 length
= strlen(cmd
); /* No redirection. */
3229 length
= out_redir
- cmd
;
3230 out_file
= fopen(out_redir
+ 3, "wb");
3231 if (out_file
== NULL
)
3232 smsg("WARNING : Can't open file %s for writing\n", out_redir
+ 3);
3239 return FAIL
; /* Command too long. */
3242 strcpy(task_cmd
, "TaskWindow \"");
3243 strncpy(task_cmd
+ 12, cmd
, length
);
3244 sprintf(task_cmd
+ 12 + length
,
3245 "\" -task &%08x -ctrl -quit -name \"Vim command\"",
3248 if (options
& SHELL_COOKED
)
3249 settmode(TMODE_COOK
);
3251 if (xswi(Wimp_StartTask
, task_cmd
) & v_flag
)
3253 /* Failed to even start a new task (out of memory?) */
3254 settmode(TMODE_RAW
);
3260 /* Wait for the child process to initialise. */
3262 while (!child_handle
)
3264 reason
= wimp_poll(0, block
);
3265 if ((reason
== 17 || reason
== 18) && block
[4] == 0x808c2)
3266 child_handle
= block
[1];
3268 process_event(reason
, block
);
3271 /* Block until finished */
3272 while (child_handle
)
3274 reason
= wimp_poll(1, block
);
3275 if (reason
== 3 || (reason
== 8 && block
[6] == 3))
3277 /* Close window request or CTRL-C - kill child task. */
3280 block
[4] = 0x808c4; /* Morite */
3281 swi(Wimp_SendMessage
, 17, block
, child_handle
);
3282 MSG_PUTS(_("\nSending message to terminate child process.\n"));
3285 else if (reason
== 8)
3289 block
[4] = 0x808c0; /* Input */
3291 /* Block[6] is OK as it is! */
3292 swi(Wimp_SendMessage
, 17, block
, child_handle
);
3295 else if (reason
== 17 || reason
== 18)
3297 if (block
[4] == 0x808c1)
3300 block
[3] = block
[2];
3301 swi(Wimp_SendMessage
, 19, block
, block
[1]);
3302 out
= (char_u
*)block
+ 24;
3303 old_msg_col
= msg_col
;
3307 if (out_file
&& (c
!= '\r' || (options
& SHELL_FILTER
)))
3309 if ((options
& SHELL_FILTER
) == 0)
3317 lines_left
= 8; /* Don't do More prompt! */
3322 /* Flush output to the screen. */
3323 windgoto(msg_row
, msg_col
);
3328 process_event(reason
, block
);
3331 settmode(TMODE_RAW
);
3337 /* Like strsave(), but stops at any control char */
3344 while (str
[strlen
] > 31)
3346 retval
= alloc(strlen
+ 1);
3349 memcpy(retval
, str
, strlen
);
3350 retval
[strlen
] = '\0';
3355 /* If we are saving then pop up a standard RISC OS save box.
3356 * Otherwise, open a directory viewer on the given directory (and return NULL)
3357 * The string we return will be freed later.
3360 gui_mch_browse(saving
, title
, dflt
, ext
, initdir
, filter
)
3361 int saving
; /* write action */
3362 char_u
*title
; /* title for the window */
3363 char_u
*dflt
; /* default file name */
3364 char_u
*ext
; /* extension added */
3365 char_u
*initdir
; /* initial directory, NULL for current dir */
3366 char_u
*filter
; /* file name filter */
3375 int done_save
= FALSE
;
3376 char_u
*retval
= NULL
;
3379 int dragging_icon
= FALSE
;
3385 block
[0] = save_window
;
3387 swi(Wimp_GetIconState
, 0, block
);
3388 sprname
= ((char_u
*) block
[7]);
3390 swi(Wimp_GetIconState
, 0, block
);
3391 fname
= ((char *) block
[7]);
3392 strncpy(fname
, dflt
, 255);
3394 if (xswi(OS_FSControl
, 31, curbuf
->b_p_oft
) & v_flag
)
3397 strcpy(sprname
+ 5, "xxx");
3402 sprintf(sprname
+ 5, "%03x", filetype
);
3405 /* Open the save box */
3407 swi(Wimp_GetPointerInfo
, 0, block
);
3408 swi(Wimp_CreateMenu
, 0, save_window
, block
[0] - 64, block
[1] + 64);
3409 swi(Wimp_SetCaretPosition
, save_window
, 1, 0, 0, -1, -1);
3413 reason
= wimp_poll(1, block
);
3417 redraw_window(block
);
3420 if (block
[0] == save_window
)
3421 swi(Wimp_OpenWindow
, 0, block
);
3423 ro_open_window(block
);
3429 if (block
[3] != save_window
)
3438 case 0: /* Start drag */
3439 block
[0] = save_window
;
3440 swi(Wimp_GetWindowState
, 0, block
);
3444 swi(Wimp_GetIconState
, 0, block
);
3445 drag_box
[0] = block
[2] + min_x
;
3446 drag_box
[1] = block
[3] + max_y
;
3447 drag_box
[2] = block
[4] + min_x
;
3448 drag_box
[3] = block
[5] + max_y
;
3450 swi(DragASprite_Start
,
3455 dragging_icon
= TRUE
;
3458 retval
= wimp_strsave(fname
);
3461 case 3: /* Cancel */
3472 dragging_icon
= FALSE
;
3473 swi(Wimp_GetPointerInfo
, 0, block
);
3474 block
[5] = block
[3];
3475 block
[6] = block
[4];
3476 block
[7] = block
[0];
3477 block
[8] = block
[1];
3478 block
[9] = 0; /* Don't know the size */
3479 block
[10] = filetype
;
3481 while (fname
[len
] > 31)
3483 if (fname
[len
] == '.')
3494 memcpy(((char_u
*) block
) + 44, fname
, len
);
3495 ((char_u
*)block
)[44 + len
] = '\0';
3497 block
[0] = (len
+ 48) & 0xfc;
3499 block
[4] = 1; /* DataSave */
3501 swi(Wimp_SendMessage
, 17, block
, block
[5], block
[6]);
3504 ro_drag_finished(block
);
3509 retval
= wimp_strsave(fname
);
3512 else if (block
[6] == 0x1b)
3515 swi(Wimp_ProcessKey
, block
[6]);
3519 if (block
[4] == 2 && block
[9] != -1)
3521 /* DataSaveAck from dragging icon. */
3522 retval
= wimp_strsave(((char_u
*) block
) + 44);
3525 else if (block
[4] == 0x400c9)
3535 block
[0] = save_window
;
3536 swi(Wimp_CloseWindow
, 0, block
);
3537 swi(Wimp_GetCaretPosition
, 0, block
);
3539 swi(Wimp_SetCaretPosition
, gui
.window_handle
, -1, 0, 0, -1, -1);
3545 /* Open a directory viewer */
3546 length
= strlen(initdir
);
3549 return NULL
; /* Path too long! */
3551 length
= sprintf(command
, "Filer_OpenDir %s", initdir
);
3552 while (command
[length
- 1] == '.')
3554 command
[length
] = '\0';
3555 swi(OS_CLI
, command
);