Exemple #1
0
int KeyParse(const char* str)
{
    unsigned char c;
    int i;

    if (str[0] == ':') {
        // numerical character
        sscanf(str, ":%c", &c);
        i = (unsigned char)c;
    } else {
        // read from string
        int X;

        for (X = 0; X <= TETRIS_MAX_KEYCODE; X++) {
            char buffer[TETRIS_BUFSIZE];

            // keyname(3X) sucks.
            if (keyname(X) != NULL) {
                strncpy(buffer, keyname(X), TETRIS_BUFSIZE);
                if (! strcmp(str, buffer)) {
                    // we found the key code!
                    i = X;
                    break;
                }
            }
        }

        if (X > TETRIS_MAX_KEYCODE) {
            // we could not find the key code. :(
            i = 0;
        }
    }

    return i;
}
static void
really_define_key(WINDOW *win, const char *new_string, int code)
{
    int rc;
    const char *code_name = keyname(code);
    char *old_string;
    char *vis_string = 0;
    char temp[80];

    if (code_name == 0) {
	sprintf(temp, "Keycode %d", code);
	code_name = temp;
    }

    if ((old_string = keybound(code, 0)) != 0) {
	wprintw(win, "%s is %s\n",
		code_name,
		vis_string = visible(old_string));
    } else {
	wprintw(win, "%s is not bound\n",
		code_name);
    }
    log_last_line(win);

    if (vis_string != 0) {
	free(vis_string);
	vis_string = 0;
    }

    vis_string = visible(new_string);
    if ((rc = key_defined(new_string)) > 0) {
	wprintw(win, "%s was bound to %s\n", vis_string, keyname(rc));
	log_last_line(win);
    } else if (new_string != 0 && rc < 0) {
	wprintw(win, "%s conflicts with longer strings\n", vis_string);
	log_last_line(win);
    }
    rc = define_key(new_string, code);
    if (rc == ERR) {
	wprintw(win, "%s unchanged\n", code_name);
	log_last_line(win);
    } else if (new_string != 0) {
	wprintw(win, "%s is now bound to %s\n",
		vis_string,
		code_name);
	log_last_line(win);
    } else if (old_string != 0) {
	wprintw(win, "%s deleted\n", code_name);
	log_last_line(win);
    }
    if (vis_string != 0)
	free(vis_string);
    if (old_string != 0)
	free(old_string);
}
Exemple #3
0
void
dogetkey()
{
    int c, len;

    goraw();
    c = nmgetch();
    deraw(0);

    if (c < 256) {
	sprintf(line, "%c", c);
	len = 1;
    } else if (c >= KEY_MIN && c <= KEY_MAX) {
	int i, j;
	line[0] = '\0';
	sprintf(line + 1, "%s\n", keyname(c));
	for (i = 1, j = 5; line[j-1]; ) {
	    if (line[j] == '(' || line[j] == ')')
		j++;
	    else
		line[i++] = line[j++];
	}
	len = strlen(line + 1) + 1;
    } else {
	line[0] = '0';
	sprintf(line + 1, "UNKNOWN KEY");
	len = strlen(line + 1) + 1;
    }


    write(macrofd, line, len);
}
Exemple #4
0
static void RemoveOwnRegistryKeys()
{
    HKEY keys[] = { HKEY_LOCAL_MACHINE, HKEY_CURRENT_USER };
    // remove all keys from both HKLM and HKCU (wherever they exist)
    for (int i = 0; i < dimof(keys); i++) {
        UnregisterFromBeingDefaultViewer(keys[i]);
        DeleteRegKey(keys[i], REG_CLASSES_APP);
        DeleteRegKey(keys[i], REG_CLASSES_APPS);
        SHDeleteValue(keys[i], REG_CLASSES_PDF L"\\OpenWithProgids", TAPP);

        for (int j = 0; NULL != gSupportedExts[j]; j++) {
            ScopedMem<WCHAR> keyname(str::Join(L"Software\\Classes\\", gSupportedExts[j], L"\\OpenWithProgids"));
            SHDeleteValue(keys[i], keyname, TAPP);
            DeleteEmptyRegKey(keys[i], keyname);

            keyname.Set(str::Join(L"Software\\Classes\\", gSupportedExts[j], L"\\OpenWithList\\" EXENAME));
            if (!DeleteRegKey(keys[i], keyname))
                continue;
            // remove empty keys that the installer might have created
            *(WCHAR *)str::FindCharLast(keyname, '\\') = '\0';
            if (!DeleteEmptyRegKey(keys[i], keyname))
                continue;
            *(WCHAR *)str::FindCharLast(keyname, '\\') = '\0';
            DeleteEmptyRegKey(keys[i], keyname);
        }
    }
}
Exemple #5
0
// cf. http://msdn.microsoft.com/en-us/library/cc144148(v=vs.85).aspx
static bool WriteExtendedFileExtensionInfo(HKEY hkey)
{
    bool success = true;

    ScopedMem<WCHAR> exePath(GetInstalledExePath());
    if (HKEY_LOCAL_MACHINE == hkey)
        success &= WriteRegStr(hkey, L"Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\" EXENAME, NULL, exePath);

    // mirroring some of what DoAssociateExeWithPdfExtension() does (cf. AppTools.cpp)
    ScopedMem<WCHAR> iconPath(str::Join(exePath, L",1"));
    success &= WriteRegStr(hkey, REG_CLASSES_APPS L"\\DefaultIcon", NULL, iconPath);
    ScopedMem<WCHAR> cmdPath(str::Format(L"\"%s\" \"%%1\" %%*", exePath));
    success &= WriteRegStr(hkey, REG_CLASSES_APPS L"\\Shell\\Open\\Command", NULL, cmdPath);
    ScopedMem<WCHAR> printPath(str::Format(L"\"%s\" -print-to-default \"%%1\"", exePath));
    success &= WriteRegStr(hkey, REG_CLASSES_APPS L"\\Shell\\Print\\Command", NULL, printPath);
    ScopedMem<WCHAR> printToPath(str::Format(L"\"%s\" -print-to \"%%2\" \"%%1\"", exePath));
    success &= WriteRegStr(hkey, REG_CLASSES_APPS L"\\Shell\\PrintTo\\Command", NULL, printToPath);
    // don't add REG_CLASSES_APPS L"\\SupportedTypes", as that prevents SumatraPDF.exe to
    // potentially appear in the Open With lists for other filetypes (such as single images)

    // add the installed SumatraPDF.exe to the Open With lists of the supported file extensions
    for (int i = 0; NULL != gSupportedExts[i]; i++) {
        ScopedMem<WCHAR> keyname(str::Join(L"Software\\Classes\\", gSupportedExts[i], L"\\OpenWithList\\" EXENAME));
        success &= CreateRegKey(hkey, keyname);
        // TODO: stop removing this after version 1.8 (was wrongly created for version 1.6)
        keyname.Set(str::Join(L"Software\\Classes\\", gSupportedExts[i], L"\\OpenWithList\\" APP_NAME_STR));
        DeleteRegKey(hkey, keyname);
    }

    // in case these values don't exist yet (we won't delete these at uninstallation)
    success &= WriteRegStr(hkey, REG_CLASSES_PDF, L"Content Type", L"application/pdf");
    success &= WriteRegStr(hkey, L"Software\\Classes\\MIME\\Database\\Content Type\\application/pdf", L"Extension", L".pdf");

    return success;
}
int e4crypt_delete_user_key(const char *user_handle) {
    SLOGD("e4crypt_delete_user_key(\"%s\")", user_handle);
    auto key_path = get_key_path(DATA_MNT_POINT, user_handle);
    auto key = e4crypt_get_key(key_path, false);
    auto ext4_key = fill_key(key);
    auto ref = keyname(generate_key_ref(ext4_key.raw, ext4_key.size));
    auto key_serial = keyctl_search(e4crypt_keyring(), "logon", ref.c_str(), 0);
    if (keyctl_revoke(key_serial) == 0) {
        SLOGD("Revoked key with serial %ld ref %s\n", key_serial, ref.c_str());
    } else {
        SLOGE("Failed to revoke key with serial %ld ref %s: %s\n",
            key_serial, ref.c_str(), strerror(errno));
    }
    int pid = fork();
    if (pid < 0) {
        SLOGE("Unable to fork: %s", strerror(errno));
        return -1;
    }
    if (pid == 0) {
        SLOGD("Forked for secdiscard");
        execl("/system/bin/secdiscard",
            "/system/bin/secdiscard",
            key_path.c_str(),
            NULL);
        SLOGE("Unable to launch secdiscard on %s: %s\n", key_path.c_str(),
            strerror(errno));
        exit(-1);
    }
    // ext4enc:TODO reap the zombie
    return 0;
}
Exemple #7
0
void input::print()
{

	for (int i=0; i< KEY_CONFIG_TOTAL; i++) {
		printf("%s: %s\n", keyTags[i], keyname(keys[i]->binding));
	}



}
// Install password into global keyring
// Return raw key reference for use in policy
static std::string e4crypt_install_key(const std::string &key)
{
    auto ext4_key = fill_key(key);
    auto raw_ref = generate_key_ref(ext4_key.raw, ext4_key.size);
    auto ref = keyname(raw_ref);
    if (e4crypt_install_key(ext4_key, ref) == -1) {
        return "";
    }
    return raw_ref;
}
Exemple #9
0
void
curses_debug_key(int i)
{
	char b[256];
	
	move(1, 0);
	sprintf(b, "[%06d] %s", i, keyname(i));
	addstr(b);
	refresh();
}
Exemple #10
0
void
dlg_trace_chr(int ch, int fkey)
{
    if (myFP != 0) {
	const char *fkey_name = "?";
	if (fkey) {
	    if (fkey > KEY_MAX || (fkey_name = keyname(fkey)) == 0) {
#define CASE(name) case name: fkey_name = #name; break
		switch ((DLG_KEYS_ENUM) fkey) {
		    CASE(DLGK_MIN);
		    CASE(DLGK_OK);
		    CASE(DLGK_CANCEL);
		    CASE(DLGK_EXTRA);
		    CASE(DLGK_HELP);
		    CASE(DLGK_ESC);
		    CASE(DLGK_PAGE_FIRST);
		    CASE(DLGK_PAGE_LAST);
		    CASE(DLGK_PAGE_NEXT);
		    CASE(DLGK_PAGE_PREV);
		    CASE(DLGK_ITEM_FIRST);
		    CASE(DLGK_ITEM_LAST);
		    CASE(DLGK_ITEM_NEXT);
		    CASE(DLGK_ITEM_PREV);
		    CASE(DLGK_FIELD_FIRST);
		    CASE(DLGK_FIELD_LAST);
		    CASE(DLGK_FIELD_NEXT);
		    CASE(DLGK_FIELD_PREV);
		    CASE(DLGK_GRID_UP);
		    CASE(DLGK_GRID_DOWN);
		    CASE(DLGK_GRID_LEFT);
		    CASE(DLGK_GRID_RIGHT);
		    CASE(DLGK_DELETE_LEFT);
		    CASE(DLGK_DELETE_RIGHT);
		    CASE(DLGK_DELETE_ALL);
		    CASE(DLGK_ENTER);
		    CASE(DLGK_BEGIN);
		    CASE(DLGK_FINAL);
		    CASE(DLGK_SELECT);
		    CASE(DLGK_HELPFILE);
		    CASE(DLGK_TRACE);
		}
	    }
	} else if (ch == ERR) {
	    fkey_name = "ERR";
	} else {
	    fkey_name = unctrl((chtype) ch);
	    if (fkey_name == 0)
		fkey_name = "UNKNOWN";
	}
	fprintf(myFP, "chr %s (ch=%#x, fkey=%d)\n",
		fkey_name,
		ch, fkey);
	fflush(myFP);
    }
}
Exemple #11
0
char *resolve_binding (int scope, int action)
{
	int no = 0;

	while (no < ui_binding_count[scope]) {
		if (action == ui_binding[scope][no].action)
			return tidy_keyname (keyname (ui_binding[scope][no].key));
		no++;
	}
	return unboundstr;
}
Exemple #12
0
/*
 * key_name --
 *	Return name of key or NULL;
 */
char *
key_name(wchar_t key)
{
	(void) keyname((int) key);

	if (!strncmp(name, "M-", 2)) {
		/* Remove the "M-" */
		name[0] = name[2];
		name[1] = '\0';
	}
	return name;
}
Exemple #13
0
/*
 * Add the sequence of characters given in sequence as the key mapping
 * for the given key symbol.
 */
void
add_key_sequence(SCREEN *screen, char *sequence, int key_type)
{
	key_entry_t *tmp_key;
	keymap_t *current;
	int length, j, key_ent;

#ifdef DEBUG
	__CTRACE(__CTRACE_MISC, "add_key_sequence: add key sequence: %s(%s)\n",
	    sequence, keyname(key_type));
#endif /* DEBUG */
	current = screen->base_keymap;	/* always start with
					 * base keymap. */
	length = (int) strlen(sequence);

	/*
	 * OK - we really should never get a zero length string here, either
	 * the terminfo entry is there and it has a value or we are not called
	 * at all.  Unfortunately, if someone assigns a terminfo string to the
	 * ^@ value we get passed a null string which messes up our length.
	 * So, if we get a null string then just insert a leaf value in
	 * the 0th char position of the root keymap.  Note that we are
	 * totally screwed if someone terminates a multichar sequence
	 * with ^@... oh well.
	 */
	if (length == 0)
		length = 1;

	for (j = 0; j < length - 1; j++) {
		  /* add the entry to the struct */
		tmp_key = add_new_key(current, sequence[j], KEYMAP_MULTI, 0);

		  /* index into the key array - it's
		     clearer if we stash this */
		key_ent = current->mapping[(unsigned char) sequence[j]];

		current->key[key_ent] = tmp_key;

		  /* next key uses this map... */
		current = current->key[key_ent]->value.next;
	}

	/*
	 * This is the last key in the sequence (it may have been the
	 * only one but that does not matter) this means it is a leaf
	 * key and should have a symbol associated with it.
	 */
	tmp_key = add_new_key(current, sequence[length - 1], KEYMAP_LEAF,
			      key_type);
	current->key[current->mapping[(int)sequence[length - 1]]] = tmp_key;
}
Exemple #14
0
void
SQLTableListManager::commitSpatial()
{
/* for index|key name (field) split name from field
*/
	std::string::size_type first = tempcontents_.find_first_of('('),
	  last = tempcontents_.find_last_of(')'),
	  space = tempcontents_.find_first_of(' ');

	std::string fieldname(tempcontents_.substr(first + 1, last - first - 1));
	std::string keyname((space == std::string::npos)?"":tempcontents_.substr(0, space));

	temptable_.spatial.insert(std::make_pair<std::string, std::string>(fieldname, keyname));
}
Exemple #15
0
PUBLIC void mapping_dmp(void)
{
	int h;

	printf(
"Function key mappings for debug dumps in IS server.\n"
"        Key   Description\n"
"-------------------------------------------------------------------------\n");
	for(h = 0; h < NHOOKS; h++)
		printf(" %10s.  %s\n", keyname(hooks[h].key), hooks[h].name);

	printf("\n");

	return;
}
Exemple #16
0
void bind_key (const char* _arg)
{
  if (!_arg)
  {
    csKeyMap* map = mapping;
    while (map)
    {
      Sys->Report (CS_REPORTER_SEVERITY_NOTIFY,
      	"Key %s bound to %s.", CS::Quote::Single (keyname (map)),
	CS::Quote::Single (map->cmd));
      map = map->next;
    }
    return;
  }
  char* arg = new char[strlen(_arg) + 1];
  strcpy (arg, _arg);
  char* space = strchr (arg, ' ');
  if (space)
  {
    *space = 0;
    csKeyMap* map = find_mapping (arg);
    if (map)
    {
      delete [] map->cmd;
    }
    else
    {
      map = new csKeyMap ();
      map->next = mapping;
      map->prev = 0;
      if (mapping) mapping->prev = map;
      mapping = map;
      map_key (arg, map);
    }
    map->cmd = new char [strlen (space+1)+1];
    strcpy (map->cmd, space+1);
    *space = ' ';
  }
  else
  {
    csKeyMap* map = find_mapping (arg);
    if (map) Sys->Report (CS_REPORTER_SEVERITY_NOTIFY,
    	"Key bound to %s!", CS::Quote::Single (map->cmd));
    else Sys->Report (CS_REPORTER_SEVERITY_NOTIFY, "Key not bound!");
  }
  delete[] arg;
}
static void recur_tries(struct tries *tree, unsigned level)
{
	if (level > len)
		buffer = (unsigned char *)realloc(buffer, len = (level + 1) * 4);

	while (tree != 0) {
		if ((buffer[level] = tree->ch) == 0)
			buffer[level] = 128;
		buffer[level+1] = 0;
		if (tree->value != 0) {
			_tracef("%5d: %s (%s)", tree->value, _nc_visbuf((char *)buffer), keyname(tree->value));
		}
		if (tree->child)
			recur_tries(tree->child, level+1);
		tree = tree->sibling;
	}
}
Exemple #18
0
// cf. http://msdn.microsoft.com/en-us/library/cc144148(v=vs.85).aspx
static bool WriteExtendedFileExtensionInfo(HKEY hkey)
{
    bool ok = true;

    ScopedMem<WCHAR> exePath(GetInstalledExePath());
    if (HKEY_LOCAL_MACHINE == hkey)
        ok &= WriteRegStr(hkey, L"Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\" EXENAME, nullptr, exePath);

    // mirroring some of what DoAssociateExeWithPdfExtension() does (cf. AppTools.cpp)
    ScopedMem<WCHAR> iconPath(str::Join(exePath, L",1"));
    ok &= WriteRegStr(hkey, REG_CLASSES_APPS L"\\DefaultIcon", nullptr, iconPath);
    ScopedMem<WCHAR> cmdPath(str::Format(L"\"%s\" \"%%1\" %%*", exePath));
    ok &= WriteRegStr(hkey, REG_CLASSES_APPS L"\\Shell\\Open\\Command", nullptr, cmdPath);
    ScopedMem<WCHAR> printPath(str::Format(L"\"%s\" -print-to-default \"%%1\"", exePath));
    ok &= WriteRegStr(hkey, REG_CLASSES_APPS L"\\Shell\\Print\\Command", nullptr, printPath);
    ScopedMem<WCHAR> printToPath(str::Format(L"\"%s\" -print-to \"%%2\" \"%%1\"", exePath));
    ok &= WriteRegStr(hkey, REG_CLASSES_APPS L"\\Shell\\PrintTo\\Command", nullptr, printToPath);
    // don't add REG_CLASSES_APPS L"\\SupportedTypes", as that prevents SumatraPDF.exe to
    // potentially appear in the Open With lists for other filetypes (such as single images)

    // add the installed SumatraPDF.exe to the Open With lists of the supported file extensions
    // TODO: per http://msdn.microsoft.com/en-us/library/cc144148(v=vs.85).aspx we shouldn't be
    // using OpenWithList but OpenWithProgIds. Also, it doesn't seem to work on my win7 32bit
    // (HKLM\Software\Classes\.mobi\OpenWithList\SumatraPDF.exe key is present but "Open With"
    // menu item doesn't even exist for .mobi files
    // It's not so easy, though, because if we just set it to SumatraPDF,
    // all gSupportedExts will be reported as "PDF Document" by Explorer, so this needs
    // to be more intelligent. We should probably mimic Windows Media Player scheme i.e.
    // set OpenWithProgIds to SumatraPDF.AssocFile.Mobi etc. and create apropriate
    // \SOFTWARE\Classes\CLSID\{GUID}\ProgID etc. entries
    // Also, if Sumatra is the only program handling those docs, our
    // PDF icon will be shown (we need icons and properly configure them)
    for (int i = 0; nullptr != gSupportedExts[i]; i++) {
        ScopedMem<WCHAR> keyname(str::Join(L"Software\\Classes\\", gSupportedExts[i], L"\\OpenWithList\\" EXENAME));
        ok &= CreateRegKey(hkey, keyname);
    }

    // in case these values don't exist yet (we won't delete these at uninstallation)
    ok &= WriteRegStr(hkey, REG_CLASSES_PDF, L"Content Type", L"application/pdf");
    ok &= WriteRegStr(hkey, L"Software\\Classes\\MIME\\Database\\Content Type\\application/pdf", L"Extension", L".pdf");

    return ok;
}
Exemple #19
0
void
SQLTableListManager::commitIndex()
{
/* for index|key name (field) split name from field
*/
	std::string::size_type first = tempcontents_.find_first_of('('),
	  last = tempcontents_.find_last_of(')'),
	  space = tempcontents_.find_first_of(' ');

	std::string fieldname(tempcontents_.substr(first + 1, last - first - 1));
	std::string keyname((space == std::string::npos)?"":tempcontents_.substr(0, space));

/* Let's check if we are to add the index as we might have already encountered a foreign key on this field
*/
	TableIndexList::iterator it = temptable_.noindex.find(std::make_pair<std::string, std::string>(fieldname, ""));
	if (it == temptable_.noindex.end())
	{
		temptable_.index.insert(std::make_pair<std::string, std::string>(fieldname, keyname));
	}
}
Exemple #20
0
int main () {
	int c;
	char *s;

	initscr ();
	cbreak ();
	noecho ();
	start_color ();
	keypad (stdscr, TRUE);
	curs_set(0);

	if (!has_colors ()) {
		endwin ();
		fputs ("No colors!", stderr); 
		exit (1);
	}

	init_pair (COLOR1, COLOR_RED, COLOR_BLUE);
	init_pair (COLOR2, COLOR_YELLOW, COLOR_BLACK);

	attron (COLOR_PAIR( COLOR1 ));
	mvaddstr (2, 5, "Red on blue.");

	attron (COLOR_PAIR( COLOR2 ));
	mvaddstr (3, 5, "Yellow on black.");

	mvaddstr (LINES-1, COLS-20, "Press F10 for end.");

	while ( (c=getch()) != KEY_F(10)) {
		s = (char *) keyname(c);
		if (s)
			mvprintw (10, 20, "'%s'", s);
		else
			mvprintw (10, 20, "'%c'", (isprint(c) ? c : '.'));
	}

	erase ();
	refresh ();
	endwin ();
	return 0;
}
Exemple #21
0
static void
show_help(WINDOW *current)
{
    /* *INDENT-OFF* */
    static struct {
	int	key;
	CONST_FMT char * msg;
    } help[] = {
	{ '?',		"Show this screen" },
	{ 'b',		"Draw a box inside the current window" },
	{ 'c',		"Create a new window" },
	{ 'd',		"Create a new derived window" },
	{ 'D',		"Move derived window (moves viewport)" },
	{ 'f',		"Fill the current window with the next character" },
	{ 'F',		"Fill the current window with a pattern" },
	{ 'm',		"Move the current window" },
	{ 'M',		"Move the current window (and its children)" },
	{ 'q',		"Quit" },
	{ 's',		"Create a new subwindow" },
	{ CTRL('L'),	"Repaint all windows, doing current one last" },
	{ CTRL('N'),	"Cursor to next window" },
	{ CTRL('P'),	"Cursor to previous window" },
    };
    /* *INDENT-ON* */

    WINDOW *mywin = newwin(LINES, COLS, 0, 0);
    int row;

    for (row = 0; row < LINES - 2 && row < (int) SIZEOF(help); ++row) {
	wmove(mywin, row + 1, 1);
	wprintw(mywin, "%s", keyname(help[row].key));
	wmove(mywin, row + 1, 20);
	wprintw(mywin, "%s", help[row].msg);
    }
    box_inside(mywin);
    wmove(mywin, 1, 1);
    wgetch(mywin);
    delwin(mywin);
    refresh_all(current);
}
Exemple #22
0
/**
The GUI loop. Handles SDL events and network communication.
*/
void UserFace::theGui(){

    init();

        while (!quit){

                SDL_Event event;
                while(SDL_PollEvent(&event)){
					if (event.type==SDL_QUIT) quit = true;
					else if (setkey && (event.type==SDL_KEYDOWN)){
						*(mSettings->cControls->setKey) = event.key.keysym.sym;
						mSettings->cControls->setButton->setCaption(keyname(event.key.keysym.sym));
						mSettings->cControls->setButton->adjustSize();
						userface.setkey = false;
					}else if (!setkey) ((SDLInput*)(gui->getInput()))->pushInput(event);
				}

                gui->logic();

                if (!gameplay.local){
                    network.recv(false);
                    if (network.status < 0){
                        switchTo(mConnect);
                        showMessage("Connection to server lost");
                    }
                }
                if (gameplay.approved) launchGame();

                gui->draw();
                SDL_Flip(gfx.screen);

                SDL_Delay(DELAY);

        }

}
Exemple #23
0
void printpressed()
{
   int index;
   static char keystring[80] = "";
   char newstring[80];
   char *dest;

   strcpy( newstring, "" );
   dest = newstring;

   for( index = 0; index < 128; index++ )
      if( ispressed( index ) )
      {
         sprintf( dest, "[%s]", keyname( index ) );
         dest += strlen( dest );
      }

   if( strcmp( newstring, keystring ) )
   {
      strcpy( keystring, newstring );
      clrscr();
      puts( newstring );
   }
}
_tracechar(int ch)
{
    NCURSES_CONST char *name;

    if (ch > KEY_MIN || ch < 0) {
        name = keyname(ch);
        if (name == 0 || *name == '\0')
            name = "NULL";
        (void) sprintf(MyBuffer, "'%.30s' = %#03o", name, ch);
    } else if (!is8bits(ch) || !isprint(UChar(ch))) {
        /*
         * workaround for glibc bug:
         * sprintf changes the result from unctrl() to an empty string if it
         * does not correspond to a valid multibyte sequence.
         */
        (void) sprintf(MyBuffer, "%#03o", ch);
    } else {
        name = unctrl((chtype) ch);
        if (name == 0 || *name == 0)
            name = "null";	/* shouldn't happen */
        (void) sprintf(MyBuffer, "'%.30s' = %#03o", name, ch);
    }
    return (MyBuffer);
}
Exemple #25
0
/* Among other things,  'newtest' demonstrates how to make a Win32a
PDCurses app that is a for-real,  "pure Windows" version (instead of
a console application).  Doing this is quite easy,  and has certain
advantages.  If the app is invoked from a command prompt,  the only
difference you'll see is that the app runs separately (that is,  you
can continue to use the command prompt,  switching between it,  your
PDCurses/Win32a app,  and other processes).  Which is the main reason
I did it;  it meant that I could invoke a PDCurses-based text editor,
for example,  and still have use of the command line.

   (NOTE that,  for reasons I don't actually understand,  this happens
when the Visual C++ compiler is used.  With MinGW or OpenWatcom,  it's
still "really" a console app.)

   To do it,  we ensure that the usual main() function has an alternative
dummy_main() form,  taking the same arguments as main().  We add a
WinMain() function,  whose sole purpose is to reformulate lpszCmdLine
into argc/argv form,  and pass it on to dummy_main().  And,  of course,
we can switch back to a "normal" console app by removing the above
#define PURE_WINDOWS_VERSION line.             */

#ifdef PURE_WINDOWS_VERSION
#undef MOUSE_MOVED
#include <windows.h>

int dummy_main( int argc, char **argv);

int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    LPSTR lpszCmdLine, int nCmdShow)
{
   char *argv[30];
   int i, argc = 1;

   argv[0] = "newtest";
   for( i = 0; lpszCmdLine[i]; i++)
       if( lpszCmdLine[i] != ' ' && (!i || lpszCmdLine[i - 1] == ' '))
          argv[argc++] = lpszCmdLine + i;

   for( i = 0; lpszCmdLine[i]; i++)
       if( lpszCmdLine[i] == ' ')
          lpszCmdLine[i] = '\0';

   return dummy_main( argc, (char **)argv);
}

int dummy_main( int argc, char **argv)
#else       /* "usual",  console-app version: */
int main( int argc, char **argv)
#endif
{
    int quit = 0, i, fmt = 0xa, use_slk = 1;
    bool blink_state = FALSE;
    int cursor_state_1 = 2, cursor_state_2 = 3;
    int show_slk_index_line = 0;
    int redraw = 1;

//  setlocale(LC_ALL, ".utf8");
    ttytype[0] = 25;   ttytype[1] = 90;         /* Allow 25 to 90 lines... */
    ttytype[2] = 80;   ttytype[3] = (char)200;  /* ...and 80 to 200 columns */
         /* (This program gets weird artifacts when smaller than 25x80.) */
    for( i = 1; i < argc; i++)
        if( argv[i][0] == '-')
            switch( argv[i][1])
            {
                case 's':
                    use_slk = 0;
                    break;
                case 'l':
                    setlocale( LC_ALL, argv[i] + 2);
                    break;
                case 'f':
                    sscanf( argv[i] + 2, "%x", &fmt);
                    break;
                case 'i':
                    show_slk_index_line = 1;
                    break;
                case 'r':     /* allow user-resizable windows */
                    {
                        int min_lines, max_lines, min_cols, max_cols;

                        if( sscanf( argv[i] + 2, "%d,%d,%d,%d",
                                       &min_lines, &max_lines,
                                       &min_cols, &max_cols) == 4)
                        {
                            ttytype[0] = min_lines;
                            ttytype[1] = max_lines;
                            ttytype[2] = min_cols;
                            ttytype[3] = max_cols;
                        }
                    }
                    break;
                default:
                    printf( "Option '%s' unrecognized\n", argv[i]);
                    break;
            }
    if( use_slk)
       slk_init( show_slk_index_line ? 3 : 0);
    Xinitscr(argc, argv);
    if( use_slk)
       slk_setup( show_slk_index_line ? -fmt : fmt);

    start_color();

# if defined(NCURSES_VERSION) || (defined(PDC_BUILD) && PDC_BUILD > 3000)
    use_default_colors();
# endif
    cbreak();
    noecho();
    clear();
    refresh();
#ifdef __PDCURSES__
    PDC_set_title( "NewTest: tests various PDCurses features");
#endif
    keypad( stdscr, TRUE);
    init_pair( 1, 15, COLOR_BLACK);
    init_pair( 2, COLOR_BLACK, COLOR_YELLOW);

    mousemask( ALL_MOUSE_EVENTS, NULL);
    attrset( COLOR_PAIR( 1));
    while( !quit)
    {
        char buff[40];
        const int color_block_start = 52;
        const int color_block_size = 14;
        int c;
        const char *cursor_state_text[N_CURSORS] = {
                  "Invisible (click to change) ",
                  "Underscore (click to change)",
                  "Block (click to change)     ",
                  "Outline (click to change)   ",
                  "Caret (click to change)     ",
                  "Half-block (click to change)",
                  "Central (click to change)   ",
                  "Cross (click to change)     ",
                  "Heavy box (click to change) " };
        if( redraw)
        {
            mvaddstr( 1, COL1, "'Normal' white-on-black");
#ifdef WACS_S1
            mvaddwstr( 2, COL1, L"'Normal' text,  but wide");
#endif
            attron( A_BLINK);
            mvaddstr( 6, 40, "Blinking");
            attron( A_BOLD);
            mvaddstr( 8, 40, "BlinkBold");
            attron( A_ITALIC);
            mvaddstr( 0, COL2, "BlinkBoldItalic");
            attrset( COLOR_PAIR( 3));
            attron( A_UNDERLINE);
#ifdef WACS_S1
            mvaddstr( 2, COL1, "Underlined");
            addwstr( L"WideUnder");
#endif
            attrset( COLOR_PAIR( 1));
            attron( A_UNDERLINE | A_ITALIC);
            mvaddstr( 2, COL2, "UnderlinedItalic");
            attrset( COLOR_PAIR( 2));
            attron( A_BLINK);
            mvaddstr( 4, COL1, "Black-on-yellow blinking");

            attrset( COLOR_PAIR( 1));
            move( 4, COL2);
            text_in_a_box( "Text in a box");

            attrset( COLOR_PAIR( 6));
            attron( A_STRIKEOUT);
            mvaddstr( 10, 40, "Strikeout");
            attrset( COLOR_PAIR( 1));
            for( i = 0; i < 128; i++)
            {                 /* Show extended characters: */
                char buff[5];

                sprintf( buff, "%2x %c", i + 128, (char)(i + 128));
                mvaddstr( 5 + i % 16, (i / 16) * 5, buff);
            }

#if(CHTYPE_LONG >= 2)       /* "non-standard" 64-bit chtypes     */
            for( i = 0; i < 3; i++)
            {                 /* Demonstrate full RGB color control: */
                int j;
                const char *output_text[3] = {
                    "Red on green to white on black   | (you can get full RGB colors when desired,",
                    "Blue on yellow to black on red | with palette coloring still being available)",
                    "White on red to green on blue,  underlined and italic" };
                const int len = strlen( output_text[i]);

                move( 21 + i, 1);
                for( j = 0; j < len; j++)
                {
                    attr_t output_color;
                    const int oval = j * 31 / len;
                    const int reverse = 31 - oval;

                    if( !i)
                        output_color = A_RGB( 31, oval, oval, 0, reverse, 0);
                    else if( i == 1)
                        output_color = A_RGB( 0, 0, reverse, 31, reverse, 0);
                    else
                    {
                        output_color = A_RGB( reverse, 31, reverse,
                               reverse, 0, oval);
                        output_color |= A_UNDERLINE | A_ITALIC;
                    }
                    attrset( output_color);
                    addch( output_text[i][j]);
                }
            }
#endif         /* #if(CHTYPE_LONG >= 2) */
            redraw = 0;
        }
        attrset( COLOR_PAIR( 1));

#ifdef MAYBE_TRY_THIS_SOMEWHERE_ELSE
        mvaddstr(  1, COL3, "Click on cursor descriptions to");
        mvaddstr(  2, COL3, "cycle through possible cursors");
        mvaddstr(  3, COL3, "Click on colors at left to change");
        mvaddstr(  4, COL3, "colors used for under/over/outlining");
        mvaddstr(  5, COL3, "Click 'Blink' at bottom to toggle");
        mvaddstr(  6, COL3, "'real' blinking vs. 'highlit' blink");
#endif

        mvaddstr( 19, color_block_start, cursor_state_text[cursor_state_1]);
        mvaddstr( 20, color_block_start, cursor_state_text[cursor_state_2]);
        curs_set( (cursor_state_1 << 8) | cursor_state_2);
        for( i = 0; i < 256; i++)
        {
            attrset( COLOR_PAIR( i));
            if( i > 2)
               init_pair((short)i, (short)i, COLOR_BLACK);
            if( !(i % color_block_size))
               move( i / color_block_size, color_block_start);
            attron( A_REVERSE);
            addstr( "  ");
        }
        move( 18, 77);
        refresh();
        c = getch( );
        attrset( COLOR_PAIR( 1));
        if( c == KEY_RESIZE)
        {
            redraw = 1;
            resize_term( 0, 0);
        }
        else if( c == KEY_F(1) || c == 27)
            quit = 1;
        else if( c == KEY_F(2))
        {
            blink_state ^= 1;
            PDC_set_blink( blink_state);
        }
        else if( c == KEY_F(3))   /* toggle SLKs */
        {
            use_slk ^= 1;
            if( use_slk)
                slk_restore( );
            else
                slk_clear( );
        }
        else if( c >= KEY_F(4) && c < KEY_F(12))
        {
            sscanf( labels[c - KEY_F(1)], "%x", &fmt);
            if( use_slk)
                slk_setup( show_slk_index_line ? -fmt : fmt);
        }
        if( c != KEY_MOUSE)
        {
            sprintf( buff, "Key %s hit          ", keyname( c));
            mvaddstr( 0, COL1, buff);
        }
        else
        {
            MEVENT mouse_event;
#ifdef __PDCURSES__
            nc_getmouse( &mouse_event);
#else
            getmouse( &mouse_event);
#endif
            sprintf( buff, "Mouse at %d x %d: %x  ", mouse_event.x,
                              mouse_event.y, (unsigned)mouse_event.bstate);
            mvaddstr( 0, COL1, buff);
            if( mouse_event.x >= color_block_start
                            && mouse_event.y <= 256 / color_block_size)
            {
                int new_color = (mouse_event.x - color_block_start) / 2
                              + mouse_event.y * color_block_size;

                if( new_color >= 256)
                    new_color = -1;
                PDC_set_line_color( (short)new_color);
            }
            else if( mouse_event.x >= color_block_start)
            {
                if( mouse_event.y == 19)  /* blink/non-blink toggle */
                    cursor_state_1 = (cursor_state_1 + 1) % N_CURSORS;
                else if( mouse_event.y == 20)  /* cycle cursor state */
                    cursor_state_2 = (cursor_state_2 + 1) % N_CURSORS;
            }
        }
    }

    endwin();

    return 0;
}
Exemple #26
0
static void
test_redraw(WINDOW *win)
{
    WINDOW *win1;
    WINDOW *win2;
    bool done = FALSE;
    int ch, y, x;
    int max_y, max_x;
    int beg_y, beg_x;

    assert(win != 0);

    scrollok(win, TRUE);
    keypad(win, TRUE);
    getmaxyx(win, max_y, max_x);
    getbegyx(win, beg_y, beg_x);
    while (!done && win != 0) {
	ch = wgetch(win);
	getyx(win, y, x);
	switch (ch) {
	case 'q':
	    /* FALLTHRU */
	case ESCAPE:
	    done = TRUE;
	    break;
	case 'w':
	    win1 = newwin(max_y, max_x,
			  beg_y, beg_x);
	    win2 = newwin(max_y - 2, max_x - 2,
			  beg_y + 1, beg_x + 1);
	    box(win1, 0, 0);
	    wrefresh(win1);

	    test_redraw(win2);

	    delwin(win2);
	    delwin(win1);

	    touchwin(win);
	    break;

	case '!':
	    /*
	     * redrawwin() and wredrawln() do not take into account the
	     * possibility that the cursor may have moved.  That makes them
	     * cumbersome for using with a shell command.  So we simply
	     * trash the current line of the window using backspace/overwrite.
	     */
	    trash(beg_x, max_x, x + beg_x);
	    break;

#ifdef NCURSES_VERSION
	case '@':
	    /*
	     * For a shell command, we can work around the problem noted above
	     * using mvcur().  It is ifdef'd for NCURSES, since X/Open does
	     * not define the case where the old location is unknown. 
	     */
	    IGNORE_RC(system("date"));
	    mvcur(-1, -1, y, x);
	    break;
#endif

	case CTRL('W'):
	    redrawwin(win);
	    break;

	case CTRL('L'):
	    wredrawln(win, y, 1);
	    break;

	case KEY_UP:
	    if (y > 0)
		wmove(win, y - 1, x);
	    break;

	case KEY_DOWN:
	    if (y < max_y)
		wmove(win, y + 1, x);
	    break;

	case KEY_LEFT:
	    if (x > 0)
		wmove(win, y, x - 1);
	    break;

	case KEY_RIGHT:
	    if (x < max_x)
		wmove(win, y, x + 1);
	    break;

	default:
	    if (ch > KEY_MIN) {
		waddstr(win, keyname(ch));
	    } else {
		waddstr(win, unctrl(UChar(ch)));
	    }
	    break;
	}
	wnoutrefresh(win);
	doupdate();
    }
}
Exemple #27
0
void inputTest(WINDOW *win)
{
    int w, h, bx, by, sw, sh, i, c, num = 0;
    int line_to_use = 3;
    char buffer[80];
    WINDOW *subWin;
    static const char spinner[4] = "/-\\|";
    int spinner_count = 0;

    wclear(win);

    getmaxyx(win, h, w);
    getbegyx(win, by, bx);

    sw = w / 3;
    sh = h / 3;

    if ((subWin = subwin(win, sh, sw, by + h - sh - 2, bx + w - sw - 2))
        == NULL)
        return;

#ifdef A_COLOR
    if (has_colors())
    {
        init_pair(2, COLOR_WHITE, COLOR_RED);
        wbkgd(subWin, COLOR_PAIR(2) | A_BOLD);
    }
    else
#endif
        wbkgd(subWin, A_BOLD);

    box(subWin, ACS_VLINE, ACS_HLINE);
    wrefresh(win);

    nocbreak();

    wclear (win);
    mvwaddstr(win, 1, 1,
        "Press keys (or mouse buttons) to show their names");
    mvwaddstr(win, 2, 1, "Press spacebar to finish");
    wrefresh(win);

    keypad(win, TRUE);
    raw();
    noecho();

    wtimeout(win, 200);

#ifdef PDCURSES
    mouse_set(ALL_MOUSE_EVENTS | REPORT_MOUSE_POSITION);
    PDC_save_key_modifiers(TRUE);
//  PDC_return_key_modifiers(TRUE);
#endif
    curs_set(0);        /* turn cursor off */

    while (1)
    {
        while (1)
        {
            c = wgetch(win);

            if (c == ERR)
            {
                spinner_count++;
                if (spinner_count == 4)
                    spinner_count = 0;
                mvwaddch(win, line_to_use, 3, spinner[spinner_count]);
                wrefresh(win);
            }
            else
                break;
        }
#ifdef PDCURSES
//      wmove(win, line_to_use + 1, 18);
//      wclrtoeol(win);
#endif
        mvwaddstr(win, line_to_use, 5, "Key Pressed: ");
        wclrtoeol(win);

        wprintw( win, "(%x) ", c);
        if( has_key( c))
            wprintw(win, "%s", keyname(c));
        else if (isprint(c) || c > 0xff)
            waddch( win, c);
        else
            wprintw(win, "%s", unctrl(c));
#ifdef PDCURSES
        if (c == KEY_MOUSE)
        {
            int button = 0, status = 0;
            request_mouse_pos();

            if (BUTTON_CHANGED(1))
                button = 1;
            else if (BUTTON_CHANGED(2))
                button = 2;
            else if (BUTTON_CHANGED(3))
                button = 3;
            else if (BUTTON_CHANGED(4))   /* added 21 Jan 2011: BJG */
                button = 4;
            else if (BUTTON_CHANGED(5))
                button = 5;
            if( button)
                status = (button > 3 ? Mouse_status.xbutton[(button) - 4] :
                                       Mouse_status.button[(button) - 1]);

            wmove(win, line_to_use, 5);
            wclrtoeol(win);
            wprintw(win, "Button %d: ", button);

            if (MOUSE_MOVED)
                waddstr(win, "moved: ");
            else if (MOUSE_WHEEL_UP)
                waddstr(win, "wheel up: ");
            else if (MOUSE_WHEEL_DOWN)
                waddstr(win, "wheel dn: ");
            else if (MOUSE_WHEEL_LEFT)
                waddstr(win, "wheel lt: ");
            else if (MOUSE_WHEEL_RIGHT)
                waddstr(win, "wheel rt: ");
            else if ((status & BUTTON_ACTION_MASK) == BUTTON_PRESSED)
                waddstr(win, "pressed: ");
            else if ((status & BUTTON_ACTION_MASK) == BUTTON_CLICKED)
                waddstr(win, "clicked: ");
            else if ((status & BUTTON_ACTION_MASK) == BUTTON_DOUBLE_CLICKED)
                waddstr(win, "double: ");
            else if ((status & BUTTON_ACTION_MASK) == BUTTON_TRIPLE_CLICKED)
                waddstr(win, "triple: ");
            else
                waddstr(win, "released: ");

            wprintw(win, "Posn: Y: %d X: %d", MOUSE_Y_POS, MOUSE_X_POS);
            if (button && (status & BUTTON_MODIFIER_MASK))
            {
                if (status & BUTTON_SHIFT)
                    waddstr(win, " SHIFT");

                if (status & BUTTON_CONTROL)
                    waddstr(win, " CONTROL");

                if (status & BUTTON_ALT)
                    waddstr(win, " ALT");
            }

        }
        else if (PDC_get_key_modifiers())
        {
            waddstr(win, " Modifier(s):");
            if (PDC_get_key_modifiers() & PDC_KEY_MODIFIER_SHIFT)
                waddstr(win, " SHIFT");

            if (PDC_get_key_modifiers() & PDC_KEY_MODIFIER_CONTROL)
                waddstr(win, " CONTROL");

            if (PDC_get_key_modifiers() & PDC_KEY_MODIFIER_ALT)
                waddstr(win, " ALT");

            if (PDC_get_key_modifiers() & PDC_KEY_MODIFIER_NUMLOCK)
                waddstr(win, " NUMLOCK");
        }
#endif
        wrefresh(win);

        if (c == ' ')
            break;
        line_to_use++;
        if( line_to_use == 10)
           line_to_use = 3;
    }

    wtimeout(win, -1);  /* turn off timeout() */
    curs_set(1);        /* turn cursor back on */

#ifdef PDCURSES
    mouse_set(0L);
    PDC_save_key_modifiers(FALSE);
//  PDC_return_key_modifiers(FALSE);
#endif
    wclear(win);
    mvwaddstr(win, 2, 1, "Press some keys for 5 seconds");
    mvwaddstr(win, 1, 1, "Pressing ^C should do nothing");
    wrefresh(win);

    werase(subWin);
    box(subWin, ACS_VLINE, ACS_HLINE);

    for (i = 0; i < 5; i++)
    {
        mvwprintw(subWin, 1, 1, "Time = %d", i);
        wrefresh(subWin);
        napms(1000);
        flushinp();
    }

    delwin(subWin);
    werase(win);
    flash();
    wrefresh(win);
    napms(500);
    flushinp();

    mvwaddstr(win, 2, 1, "Press a key, followed by ENTER");
    wmove(win, 9, 10);
    wrefresh(win);
    echo();

    keypad(win, TRUE);
    raw();
    wgetnstr(win, buffer, 3);
    flushinp();

    wmove(win, 9, 10);
    wdelch(win);
    mvwaddstr(win, 4, 1, "The character should now have been deleted");
    Continue(win);

    refresh();
    wclear(win);
    echo();
    buffer[0] = '\0';
    mvwaddstr(win, 3, 2, "The window should have moved");
    mvwaddstr(win, 4, 2,
              "This text should have appeared without you pressing a key");
    mvwaddstr(win, 6, 2, "Enter a number then a string separated by space");
    mvwin(win, 2, 1);
    wrefresh(win);
    mvwscanw(win, 7, 6, "%d %s", &num, buffer);
    mvwprintw(win, 8, 6, "String: %s Number: %d", buffer, num);
    Continue(win);

    refresh();
    wclear(win);
    echo();
    mvwaddstr(win, 3, 2, "Enter a 5 character string: ");
    wgetnstr(win, buffer, 5);
    mvwprintw(win, 4, 2, "String: %s", buffer);
    Continue(win);
}
Exemple #28
0
char *key_name(wchar_t c)
{
    PDC_LOG(("key_name() - called\n"));

    return keyname((int)c);
}
/*
 * Display a temporary window listing the keystroke-commands we recognize.
 */
void
help_edit_field(void)
{
    int x0 = 4;
    int y0 = 2;
    int y1 = 0;
    int y2 = 0;
    int wide = COLS - ((x0 + 1) * 2);
    int high = LINES - ((y0 + 1) * 2);
    WINDOW *help = newwin(high, wide, y0, x0);
    WINDOW *data = newpad(2 + SIZEOF(commands), wide - 4);
    unsigned n;
    int ch = ERR;

    begin_popup();

    keypad(help, TRUE);
    keypad(data, TRUE);
    waddstr(data, "Defined form edit/traversal keys:\n");
    for (n = 0; n < SIZEOF(commands); ++n) {
	const char *name;
#ifdef NCURSES_VERSION
	if ((name = form_request_name(commands[n].result)) == 0)
#endif
	    name = commands[n].help;
	wprintw(data, "%s -- %s\n",
		keyname(commands[n].code),
		name != 0 ? name : commands[n].help);
    }
    waddstr(data, "Arrow keys move within a field as you would expect.");
    y2 = getcury(data);

    do {
	switch (ch) {
	case KEY_HOME:
	    y1 = 0;
	    break;
	case KEY_END:
	    y1 = y2;
	    break;
	case KEY_PREVIOUS:
	case KEY_PPAGE:
	    if (y1 > 0) {
		y1 -= high / 2;
		if (y1 < 0)
		    y1 = 0;
	    } else {
		beep();
	    }
	    break;
	case KEY_NEXT:
	case KEY_NPAGE:
	    if (y1 < y2) {
		y1 += high / 2;
		if (y1 >= y2)
		    y1 = y2;
	    } else {
		beep();
	    }
	    break;
	case CTRL('P'):
	case KEY_UP:
	    if (y1 > 0)
		--y1;
	    else
		beep();
	    break;
	case CTRL('N'):
	case KEY_DOWN:
	    if (y1 < y2)
		++y1;
	    else
		beep();
	    break;
	default:
	    beep();
	    break;
	case ERR:
	    break;
	}
	werase(help);
	box(help, 0, 0);
	wnoutrefresh(help);
	pnoutrefresh(data, y1, 0, y0 + 1, x0 + 1, high, wide);
	doupdate();
    } while ((ch = wgetch(data)) != ERR && ch != QUIT && ch != ESCAPE);
    werase(help);
    wrefresh(help);
    delwin(help);
    delwin(data);

    end_popup();
}
static void
test_redraw(WINDOW *win)
{
    static const char *help[] =
    {
	"Commands:",
	"  ^Q/ESC/q   - quit",
	"  w          - recur in a new window",
	"  !          - overwrite current line using stdio outside curses.",
#ifdef NCURSES_VERSION
	"  @          - run \"date\" command, to put its output on screen.",
#endif
	"  ^L         - call redrawwin() for current window.",
	"  ^W         - call wredrawln() for current line/current window.",
	"  arrow-keys - move cursor on the screen",
	"",
	"Other control characters are added to the screen in printable form.",
	"Other printable characters are added to the screen as is.",
	0
    };

    WINDOW *win1;
    WINDOW *win2;
    bool done = FALSE;
    int ch, y, x;
    int max_y, max_x;
    int beg_y, beg_x;

    assert(win != 0);

    scrollok(win, TRUE);
    keypad(win, TRUE);
    getmaxyx(win, max_y, max_x);
    getbegyx(win, beg_y, beg_x);
    while (!done) {
	ch = wgetch(win);
	getyx(win, y, x);
	switch (ch) {
	case 'q':
	    /* FALLTHRU */
	case QUIT:
	case ESCAPE:
	    done = TRUE;
	    break;
	case 'w':
	    win1 = newwin(max_y, max_x,
			  beg_y, beg_x);
	    win2 = newwin(max_y - 2, max_x - 2,
			  beg_y + 1, beg_x + 1);
	    box(win1, 0, 0);
	    wrefresh(win1);

	    test_redraw(win2);

	    delwin(win2);
	    delwin(win1);

	    touchwin(win);
	    break;

	case '!':
	    /*
	     * redrawwin() and wredrawln() do not take into account the
	     * possibility that the cursor may have moved.  That makes them
	     * cumbersome for using with a shell command.  So we simply
	     * trash the current line of the window using backspace/overwrite.
	     */
	    trash(beg_x, max_x, x + beg_x);
	    break;

#ifdef NCURSES_VERSION
	case '@':
	    /*
	     * For a shell command, we can work around the problem noted above
	     * using mvcur().  It is ifdef'd for NCURSES, since X/Open does
	     * not define the case where the old location is unknown. 
	     */
	    IGNORE_RC(system("date"));
	    mvcur(-1, -1, y, x);
	    break;
#endif

	case CTRL('W'):
	    redrawwin(win);
	    break;

	case CTRL('L'):
	    wredrawln(win, y, 1);
	    break;

	case KEY_UP:
	    if (y > 0)
		wmove(win, y - 1, x);
	    break;

	case KEY_DOWN:
	    if (y < max_y)
		wmove(win, y + 1, x);
	    break;

	case KEY_LEFT:
	    if (x > 0)
		wmove(win, y, x - 1);
	    break;

	case KEY_RIGHT:
	    if (x < max_x)
		wmove(win, y, x + 1);
	    break;

	case HELP_KEY_1:
	    popup_msg(win, help);
	    break;

	default:
	    if (ch > KEY_MIN) {
		waddstr(win, keyname(ch));
		waddch(win, '\n');
	    } else {
		waddstr(win, unctrl(UChar(ch)));
	    }
	    break;
	}
	wnoutrefresh(win);
	doupdate();
    }
}