Commit 43f41e3a authored by Robert Sprowson's avatar Robert Sprowson

Switch from ArcEdit style model to clipboard cut & paste model

edit.c:
 Register clipboard wimp messages on startup.
 Mark local functions as static.
message.c:
 Let the task window accept clipboard pastes too.
 This is tied to the 'Ignore ctrl' menu option. When enabled (default) then ^C ^V are filtered out to for clipboard typing to the task, and filters control characters from the task too (as before). When disabled, ^C ^V are passed raw to the task, and all VDU is displayed raw from the task. Cut & paste can still be performed in the disabled case by using the Edit->Select menu.
Messages:
 Remove TaskInput from Task menu, add clipboard keys to Select menu, add swap case to Select menu.
 Slim down the Misc menu which was too wide in system font.
 Update interactive help.
 Use some more of the escape code tokens in interactive help.
 Declare the previously secret Ctrl-Shift-F1 hotkey for Expand tabs.
Templates:
 Line use magic search character '\n' in the dialogue.
New documentation 'ClipKeys' is a complete survey of the hotkeys for !Edit and !SrcEdit with reference to the RISC OS 3.70 welcome manual and a few hidden ones, compared with the current implementation.
Requires RISC_OSLib-5_85.

Version 1.72. Tagged as 'Edit-1_72'
parent e6409798
ClipKeys
========
Survey of keypresses with detail of changes made to support clipboard cut'n'paste (see 1309,419/FS) instead of !ArcEdit style selection block with moveable caret. This allows testing of all the key combinations to check the behaviour matches the expected result, given the weird way the txt component of RISC_OSLib is written.
Column 'CS?' denotes whether this key combination clears the selection.
The PageUp/PageDown keys use the same key codes as the shift inverted Up/Down keys, so are omitted for brevity. Note that the RISC OS 3.70 User Guide was incorrect in its description of Ctrl+PageUp/Ctrl+PageDown and Shift+PageUp/Shift+PageDown.
A couple of extra keys are trapped by !SrcEdit, but otherwise it follows the same set as !Edit.
---------------+----------------------------------------------+-----+---------------------------------------
SrcEdit Key | Desktop Tools Manual Issue 1 | CS? | Clipboard model
---------------+----------------------------------------------+-----+---------------------------------------
F10 | Highlight matching bracket | No | As issue 1
Ctrl+L | Load file whose name is selected | No | As issue 1
Shift+F9 | Save modified files, close all windows | No | As issue 1
F1 | Lookup language help on a selected keyword | No | As issue 1
---------------+----------------------------------------------+-----+---------------------------------------
Key | RISC OS 3.70 User Guide | CS? | Clipboard model
---------------+----------------------------------------------+-----+---------------------------------------
Left | Move left 1 char | Yes | As 3.70
Right | Move right 1 char | Yes | As 3.70
Up | Move up 1 line | Yes | As 3.70
Down | Move down 1 line | Yes | As 3.70
Sh+Left | Move left 1 word | Yes | As 3.70
Sh+Right | Move right 1 word | Yes | As 3.70
Sh+Up | Page up | Yes | As 3.70
Sh+Down | Page down | Yes | As 3.70
Ctrl+Left | Start of line | Yes | As 3.70
Ctrl+Right | End of Line | Yes | As 3.70
Ctrl+Up | Start of file | Yes | As 3.70
Ctrl+Down | End of file | Yes | As 3.70
Ctrl+Sh+Left | Scroll all documents down 1 line | - | -
Ctrl+Sh+Right | Scroll all documents up 1 line | - | -
Ctrl+Sh+Up | Scroll up 1 line, no caret move | Yes | As 3.70
Ctrl+Sh+Down | Scroll down 1 line, no caret move | Yes | As 3.70
Backspace | Delete 1 char to left | Yes | Cut selection, or delete 1 char to left if none
Delete | Delete 1 char to left | Yes | Cut selection, or delete 1 char to right if none
End | Delete 1 char to right | Yes | End of file
Shift+End | Delete 1 word to right | Yes | As 3.70
Ctrl+End | Delete 1 caret line | Yes | As 3.70
Home | Start of file | Yes | As 3.70
Insert | Insert 1 space to the caret right | Yes | Paste from clipboard, replacing selection
Escape | - | Yes | Clear selection
Tab | Move caret to next word/insert column spaces | Yes | Move caret to next word/delete selection then insert column spaces
Print | Print dialogue | No | As 3.70
Ctrl+A | - | No | Select all
Ctrl+Z | Clear selection | Yes | As 3.70
Ctrl+X | Delete selection | Yes | Cut selection to clipboard
Ctrl+C | Copy selection to caret | No | Copy selection to clipboard
Ctrl+V | Move selection to caret | Yes | Paste from clipboard, replacing selection
Ctrl+K | - | Yes | Delete selection
Ctrl+S | - | No | Swap case of text under the selection
Ctrl+F0 | Send to back (undocumented!) | - | -
Sh+F1 | Toggle overwrite mode | No | As 3.70
Ctrl+Sh+F1 | Expand tabs | No | As 3.70
Ctrl+F2 | Close window | No | As 3.70
F2 | Load new file dialogue | No | As 3.70
Sh+F2 | Insert new file dialogue | Yes | Delete selection, insert file in its place
F3 | Save dialogue | No | As 3.70
Sh+F3 | Toggle column tab mode | No | As 3.70
F4 | Find dialogue | No | As 3.70
Ctrl+F4 | Indent selected block dialogue | No | As 3.70
F5 | Goto dialogue | Yes | As 3.70
Ctrl+F5 | Toggle word wrap mode | No | As 3.70
F6 | Select 1 char to right, or extend selection | - | -
Sh+F6 | Clear the current selection | Yes | As 3.70
Ctrl+F6 | Format text block | No | As 3.70
Ctrl+F7 | Swap selection and caret positions | - | -
F7 | Copy selection to caret | - | -
Sh+F7 | Move selection to caret | - | -
F8 | Undo last action | May | As 3.70
Ctrl+F8 | Toggle CR and LF | No | As 3.70
F9 | Redo last action | May | As 3.70
Others | Add character to text | Yes | Delete selection, insert character to text
No preview for this file type
......@@ -11,13 +11,13 @@
GBLS Module_HelpVersion
GBLS Module_ComponentName
GBLS Module_ComponentPath
Module_MajorVersion SETS "1.71"
Module_Version SETA 171
Module_MajorVersion SETS "1.72"
Module_Version SETA 172
Module_MinorVersion SETS ""
Module_Date SETS "31 Jul 2014"
Module_ApplicationDate SETS "31-Jul-14"
Module_Date SETS "03 Apr 2015"
Module_ApplicationDate SETS "03-Apr-15"
Module_ComponentName SETS "Edit"
Module_ComponentPath SETS "castle/RiscOS/Sources/Apps/Edit"
Module_FullVersion SETS "1.71"
Module_HelpVersion SETS "1.71 (31 Jul 2014)"
Module_FullVersion SETS "1.72"
Module_HelpVersion SETS "1.72 (03 Apr 2015)"
END
/* (1.71)
/* (1.72)
*
* This file is automatically maintained by srccommit, do not edit manually.
* Last processed by srccommit version: 1.1.
*
*/
#define Module_MajorVersion_CMHG 1.71
#define Module_MajorVersion_CMHG 1.72
#define Module_MinorVersion_CMHG
#define Module_Date_CMHG 31 Jul 2014
#define Module_Date_CMHG 03 Apr 2015
#define Module_MajorVersion "1.71"
#define Module_Version 171
#define Module_MajorVersion "1.72"
#define Module_Version 172
#define Module_MinorVersion ""
#define Module_Date "31 Jul 2014"
#define Module_Date "03 Apr 2015"
#define Module_ApplicationDate "31-Jul-14"
#define Module_ApplicationDate "03-Apr-15"
#define Module_ComponentName "Edit"
#define Module_ComponentPath "castle/RiscOS/Sources/Apps/Edit"
#define Module_FullVersion "1.71"
#define Module_HelpVersion "1.71 (31 Jul 2014)"
#define Module_LibraryVersionInfo "1:71"
#define Module_FullVersion "1.72"
#define Module_HelpVersion "1.72 (03 Apr 2015)"
#define Module_LibraryVersionInfo "1:72"
......@@ -123,7 +123,7 @@ static int cistrcmp(const char *s1, const char *s2)
/* On the icon bar we provide a text file icon. Clicking on it gets
a blank document. Menu on it provides a cut-down menu. */
void arcedit__clickproc(wimp_i i) {
static void arcedit__clickproc(wimp_i i) {
i=i;
txtedit_new("",0xfff); }
......@@ -148,7 +148,7 @@ void arcedit__clickproc(wimp_i i) {
#define MExec 4
#define MWrite 5
void arcedit__iconmenuproc(void *handle, char *hit) {
static void arcedit__iconmenuproc(void *handle, char *hit) {
txtedit_state *s;
#if CTL
......@@ -303,7 +303,7 @@ static menu edit__main_menu_maker(void *handle)
return Edit_Menu;
}
void arcedit__createicon(void)
static void arcedit__createicon(void)
{
/* OSS Look sprite name up in Messages file. */
......@@ -377,8 +377,8 @@ static os_error * save_desktop(int handle)
/* -------- Background sink for all unclaimed events. -------- */
void arcedit_bkg_events(wimp_eventstr *e, void *handle) {
tracef1("arcedit_bkg_events %i.\n", e->e);
static void arcedit__bkg_events(wimp_eventstr *e, void *handle) {
tracef1("arcedit__bkg_events %i.\n", e->e);
handle=handle;
switch(e->e) {
......@@ -546,6 +546,8 @@ static const wimp_msgaction edit_messages[] = {
wimp_MPREQUIT,
wimp_SAVEDESK,
wimp_MDATASAVED,
wimp_MCLAIMENTITY,
wimp_MDATAREQUEST,
wimp_MMENUWARN,
wimp_MMODECHANGE,
wimp_MHELPREQUEST,
......@@ -744,7 +746,7 @@ this at the moment... */
if (filename != NULL) txtedit_new(filename, 0);
};
win_register_event_handler(win_ICONBARLOAD, arcedit_bkg_events, 0);
win_register_event_handler(win_ICONBARLOAD, arcedit__bkg_events, 0);
win_claim_unknown_events(win_ICONBARLOAD);
message_init();
atexit(killalltasks);
......
......@@ -53,6 +53,7 @@
#include "wimp.h"
#include "wimpt.h"
#include "win.h"
#include "xferrecv.h"
#include "taskwin.h"
#include "slist.h"
#include "msgs.h"
......@@ -61,26 +62,23 @@
#define TASKWINDOW_FIX 1
#define round(i) (((i)+3) & 0xFFFFFFFC)
#define MArcEdit_Select 3
#define MArcEdit_Select_Mask ((1<<2) | (1<<3) | (1<<4) | (1<<7))
#define MArcEdit_Select_Paste 7
#define MArcEdit_Edit 4
#define MAXLINE 80
#define round(i) (((i)+3) & 0xFFFFFFFC)
typedef enum {
MNone,
MKill,
MKill = 1,
MReconnect,
MSuspend,
MResume,
MUnlink,
MLink,
MTaskInput,
MIgnoreCtl,
/*
MInfo,
*/
MArcEdit
} message_menuopts;
/* Note menu options start at 1 really */
/* Linked list of blocks to be sent to the task */
typedef struct selbuffer {
......@@ -95,7 +93,6 @@ int ref, /* The associated reference */
typedef struct mstate {
struct mstate *next;
int readline; /* 1 if reading command, 0 if passing input to task */
char line[MAXLINE+2]; /* The line we're reading, valid iff readline = 1 */
wimp_t child; /* The taskid of the child */
int sentcli; /* 1 <=> a command has been sent but not replied to */
int suspended; /* 1 <=> current task is suspended */
......@@ -109,45 +106,26 @@ selbuffer_t *buff; /* Stuff pending to the task module */
static menu message_menu; /* = NULL */
static message_state_t *states; /* = NULL */
static int ignoreCtl = 1; /* Default ignore control chars from task */
static BOOL ignoreCtl = TRUE; /* Default ignore control chars from task */
static int message_paste_ref = -1; /* Wimp msg reference for task input pastes */
static message_state_t *message_importinput; /* Current state for xferrecv transaction */
static const struct {
int errnum;
char errmess[6];
} start_error = {100, "NoMem" };
static void makehex(char *hex, unsigned int val)
{
unsigned int i,
j;
*hex = ' ';
for (i = 1; i <= 8; i++)
{
j = val >> 28;
*++hex = (j >=10) ? j + 'A'-10 : j + '0';
val <<= 4;
}; /* End for */
hex[1] = ' ';
hex[2] = 0;
} /* End procedure */
static os_error * message_starttask(char *comname, /* Command by which to start task module */
txt t, /* The txt of this window */
wimp_t me /* My task handle, passed to the task in STR$~ form */)
{
char * cliline;
char hex[11];
int mylength = strlen(comname);
cliline = malloc(mylength + 21);
cliline = malloc(mylength + 1+8 + 1+8 + 1 + 1);
if (!cliline) return msgtrans_error_lookup(&start_error, 0, 0, 0, 0, 0, 0, 0);
/* Failure message */
strcpy(cliline, comname);
makehex(hex, me);
strcpy(cliline + mylength, hex); /* Started task knows taskid of caller */
makehex(hex, (unsigned int)t);
strcpy(cliline + mylength + 10, hex); /* Started task knows txt of caller */
sprintf(cliline, "%s %08X %08X ", comname, (int)me, (int)t); /* Started task knows taskid & txt of caller */
return wimp_starttask(cliline);
} /* End procedure */
......@@ -173,6 +151,25 @@ return wimp_sendmessage(wimp_ESEND, &msg, dest);
} /* End procedure */
static void message_datarequest(message_state_t *s, int x, int y)
{
wimp_msgstr msg;
int *types = msg.data.datarequest.types;
msg.hdr.size = sizeof(wimp_msghdr) + sizeof(wimp_msgdatarequest) + sizeof(int);
msg.hdr.your_ref = 0;
msg.hdr.action = wimp_MDATAREQUEST;
msg.data.datarequest.w = txt_syshandle(s->t); /* As though dropped into that window */
msg.data.datarequest.h = s; /* Handle back to state, might be useful */
msg.data.datarequest.x = x;
msg.data.datarequest.y = y;
msg.data.datarequest.flags = wimp_MDATAREQUEST_flags_clipboard;
types[0] = 0xfff; /* Our one preferred type */
types[1] = wimp_MDATAREQUEST_types_end;
wimpt_noerr(wimp_sendmessage(wimp_ESENDWANTACK, &msg, 0));
message_paste_ref = msg.hdr.my_ref; /* Picked by Wimp */
}
static void message_menu_help_handler(void *handle, char *hit)
{
handle = handle;
......@@ -194,16 +191,45 @@ static void message_menu_help_handler(void *handle, char *hit)
static menu message_menumaker(void *a)
{
message_state_t *s = (message_state_t *) a;
txt t;
menu m;
wimp_menustr *mstr, *smstr;
wimp_menuitem *entry;
int i;
txtwin_setcurrentwindow(s->t);
if (message_menu == NULL)
{
message_menu = menu_new(msgs_lookup("ME3"), msgs_lookup("ME4"));
/* "Task", "Kill,Reconnect,Suspend,Resume,Unlink,Link,TaskInput,Ignore Ctl,Edit" */
/* "Task", "Kill,Reconnect,Suspend,Resume,Unlink,Link,Ignore Ctl,Edit" */
menu_submenu(message_menu, MArcEdit, txtedit_menu(s->edstate));
}; /* End if */
txtedit_menu(s->edstate); /* set the flags right. */
m = txtedit_menu(s->edstate); /* set the flags right. */
mstr = menu_syshandle(m);
if (!s->linked || s->suspended || (s->child == 0))
{
/* Task->Edit->Select->'Swap case','Indent','Cut','Delete'
are reevaluated based on the selection in txtedit_menu() */
/* Task->Edit->Edit */
entry = ((wimp_menuitem *)(mstr + 1)) + (MArcEdit_Edit - 1);
entry->iconflags &= ~wimp_INOSELECT;
} else
{
/* Task->Edit->Select->'Swap case','Indent','Cut','Delete' */
entry = ((wimp_menuitem *)(mstr + 1)) + (MArcEdit_Select - 1);
smstr = entry->submenu;
for (i = 0; i < 32; i++)
{
entry = ((wimp_menuitem *)(smstr + 1)) + i;
if ((1<<i) & MArcEdit_Select_Mask)
entry->iconflags |= wimp_INOSELECT;
}
/* Task->Edit->Edit */
entry = ((wimp_menuitem *)(mstr + 1)) + (MArcEdit_Edit - 1);
entry->iconflags |= wimp_INOSELECT;
}
/* Set my flags here */
menu_setflags(message_menu, MKill, 0, !s->child);
menu_setflags(message_menu, MSuspend, 0, !s->child || s->suspended);
......@@ -211,18 +237,11 @@ menu_setflags(message_menu, MResume, 0, !s->child || !s->suspended);
menu_setflags(message_menu, MReconnect, 0, s->child);
menu_setflags(message_menu, MUnlink, 0, !s->linked);
menu_setflags(message_menu, MLink, 0, s->linked);
t = txtscrap_selectowner();
/*
i = (!t) ? 1 : (t != s->t) ? 0 : !(s->readline || s->suspended || !s->linked);
*/
menu_setflags(message_menu, MTaskInput, 0, !t); /* Can always send selection
if it exists */
menu_setflags(message_menu, MIgnoreCtl, ignoreCtl, 0);
menu_setflags(message_menu, MArcEdit, 0, 0);
/*
!(s->readline || s->suspended || !s->linked));
*/
help_register_handler(message_menu_help_handler, 0);
return message_menu;
}
......@@ -266,6 +285,44 @@ wimpt_noerr(wimp_sendmessage(wimp_ESENDWANTACK, &data, task));
buffer->ref = data.hdr.my_ref;
} /* End procedure */
static void *queuetaskinput(const char *txtdata, message_state_t *s, int n)
{
selbuffer_t *buffer;
int i;
buffer = (selbuffer_t *)malloc(sizeof(selbuffer_t));
if (buffer == NULL) return NULL;
buffer->next = NULL;
buffer->size = n;
buffer->bsize = 0; /* Not extensible */
buffer->pos = 0;
buffer->buffer = (char *)malloc(n);
if (buffer->buffer == NULL)
{
free(buffer);
return NULL;
}
/* Copy in the data */
for (i = 0; i < n; i++) buffer->buffer[i] = txtdata[i];
if (s->buff)
{
/* Already some pending stuff, so add mine to the end */
buffer->ref = 0; /* No reference yet */
s->buff = slist_addend(s->buff, buffer);
} else
{
/* Nothing pending, so send straight away */
s->buff = buffer; /* The only buffer so far */
message_datasave(buffer, s->child);
}
return (void *)buffer;
}
static BOOL queueimportinput(char **buffer, int *size)
{
return queuetaskinput(*buffer, message_importinput, *size) != NULL;
}
static message_state_t *findstatefromtask(wimp_t task)
{
/* Search the linked list of states for one with the given child */
......@@ -326,7 +383,7 @@ static BOOL message_bkg_events(wimp_eventstr *e, void *handle)
return 1;
/* These must all identify the correct state with which to run */
case message_output:
case message_output:
data = (message_data *)&e->data.msg.data;
if (s)
{
......@@ -452,6 +509,7 @@ static BOOL message_bkg_events(wimp_eventstr *e, void *handle)
default:
tracef1("Unknown message action %i\n", e->data.msg.hdr.action);
} /* end message number switch */
break;
} /* End event type switch */
return 0;
}
......@@ -501,65 +559,16 @@ switch (*cmd)
s->linked = 1;
break;
case MTaskInput:
{ txt t = txtscrap_selectowner();
int start,
end;
if (t)
{
int n;
/* new version using RAMTransmit */
selbuffer_t *buffer;
int i;
char * txtdata;
start = txt_selectstart(t);
end = txt_selectend(t);
while (start < end)
{
txt_arrayseg(t, start, &txtdata, &n);
/* Get first segment */
if (n > end-start) n = end-start;
start += n;
buffer = (selbuffer_t *)malloc(sizeof(selbuffer_t));
if (!buffer) { werr(0, msgs_lookup("ME1")); return; };
buffer->next = NULL;
buffer->size = n;
buffer->bsize = 0; /* Not extensible */
buffer->pos = 0;
buffer->buffer = (char *)malloc(n);
if (!buffer->buffer) { werr(0, msgs_lookup("ME1")); return; };
/* Copy in the data */
for (i = 0; i < n; i++) (buffer->buffer)[i] = *(txtdata++);
if (s->buff)
{
/* Already some pending stuff, so add mine to the end */
buffer->ref = 0; /* No reference yet */
s->buff = slist_addend(s->buff, buffer);
} else
{
/* Nothing pending, so send straight away */
s->buff = buffer; /* The only buffer so far */
message_datasave(buffer, s->child);
}; /* End if */
}; /* End while */
}; /* End if */
} /* End block */
break;
/* Not done yet
case MInfo:
break;
*/
case MIgnoreCtl:
ignoreCtl = !ignoreCtl;
break;
case MArcEdit:
/*
if (s->readline || s->suspended || !s->linked)
*/
if ((cmd[1] == MArcEdit_Select) && (cmd[2] == MArcEdit_Select_Paste) &&
s->linked && !s->suspended)
{
message_datarequest(s, 0, 0); /* Paste to task instead */
} else
{
int newNumber,
numberOfWindows = txtwin_number(s->t);
......@@ -607,7 +616,7 @@ static BOOL message_win_unknowns(wimp_eventstr *e, void *handle)
case wimp_EGAINCARET:
/* --- check that we really do have the caret still! --- */
wimp_get_caret_pos(&caret);
if (caret.w == txt_syshandle(t))
if ((caret.w == txt_syshandle(t)) && !txt_selectset(t))
txt_setcharoptions(t, txt_CARET, txt_CARET);
return TRUE;
break;
......@@ -624,7 +633,7 @@ static void message_obeyeventcode(txt t, message_state_t *s, txt_eventcode e)
{
switch (e)
{
case txt_EXTRACODE + akbd_Fn + 127:
case txt_EXTRACODE + akbd_Fn + 127: /* From wimp_CLOSE */
{
int numberOfWindows = txtwin_number(s->t);
if (numberOfWindows-- > 1)
......@@ -665,6 +674,77 @@ switch (e)
} /* End case */
break;
case txt_EXTRACODE + akbd_Sh + akbd_Fn + 2:
{
wimp_eventstr *ee = wimpt_last_event();
if (ee->data.msg.hdr.your_ref == message_paste_ref)
{
/* Reply from message_datarequest() to paste as task input */
selbuffer_t *b = NULL;
char *filename;
char input[128];
if (0xfff == xferrecv_checkinsert(&filename))
{
os_regset f;
os_gbpbstr g;
os_error *err;
/* From file */
f.r[0] = 0x40 | 8; /* OPENIN, error if not there */
f.r[1] = (int)filename;
err = os_find(&f);
if (err == NULL)
{
g.action = 4; /* Read bytes from PTR */
g.file_handle = f.r[0];
do
{
g.data_addr = input;
g.number = sizeof(input);
err = os_gbpb(&g);
if (err == NULL)
{
b = queuetaskinput(input, s, sizeof(input) - g.number);
if (b == NULL) werr(0, msgs_lookup("ME1"));
}
} while ((err == NULL) && (b != NULL) && (g.number == 0));
f.r[0] = 0; /* CLOSE */
f.r[1] = g.file_handle;
os_find(&f);
}
xferrecv_insertfileok();
if (err != NULL) werr(0, err->errmess);
} else
{
int estsize, last;
if (0xfff == xferrecv_checkimport(&estsize))
{
/* From RAM */
message_importinput = s;
last = xferrecv_doimport(input, sizeof(input), queueimportinput);
if (last != -1)
{
b = queuetaskinput(input, s, last);
if (b == NULL) werr(0, msgs_lookup("ME1"));
} else
{
/* Import failed, wait for a potential scrap transfer instead */
message_paste_ref = xferrecv_last_ref();
}
} else
{
/* Not text, ignore it */
}
}
break;
}
passtotxtedit(t, s, e);
}
break;
default:
if (s->readline || s->suspended || !s->linked)
{
......@@ -680,11 +760,6 @@ switch (e)
if ((e < 0) || (e & txt_EXTRACODE))
{
/* Mouse button events in window come back -ve */
if (e & txt_MSELECT)
{
txt_setcharoptions(t, txt_CARET, 0);
txt_setcharoptions(t, txt_CARET, txt_CARET);
};
passtotxtedit(t, s, e);
break;
} else
......@@ -699,6 +774,18 @@ switch (e)
break;
}
/* If 'Ignore ctrl' is enabled filter ^C ^V to copy/paste into linked task windows */
if (s->linked && !s->suspended && s->child && ignoreCtl)
{
if (e == 22 /* control-V */) { message_datarequest(s, 0, 0); break; }
if (e == 3 /* control-C */) { passtotxtedit(t, s, e); break; }
}
/* Ordinarily typed characters should replace the selection, but in the context of
live task window we'll just clear the selection so the caret comes back. A live
task window here means !killed && !suspended && linked. */
txtscrap_setselect(t, 0, 0);
n = 0;
chbuff[n++] = e & 0xff;
if ((e & ~0xff) || !e)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment