VIOAPI Status mni_input_line( FILE *file, STRING *string ) { Status status; char ch; *string = create_string( NULL ); status = input_character( file, &ch ); while( status == OK && ch != '\n' ) { if (ch != '\r') { /* Always ignore carriage returns */ concat_char_to_string( string, ch ); } status = input_character( file, &ch ); } if( status != OK ) { delete_string( *string ); *string = NULL; } return( status ); }
VIOAPI Status mni_get_nonwhite_character( FILE *file, char *ch ) { BOOLEAN in_comment; Status status; in_comment = FALSE; do { status = input_character( file, ch ); if( status == OK ) { if( *ch == COMMENT_CHAR1 || *ch == COMMENT_CHAR2 ) { in_comment = TRUE; } else if( *ch == '\n' ) { in_comment = FALSE; } } } while( status == OK && (in_comment || *ch == ' ' || *ch == '\t' || *ch == '\n' || *ch == '\r') ); /* ignore carriage returns */ if( status == ERROR ) status = END_OF_FILE; return( status ); }
void menu_selector::handle() { // process the menu const event *menu_event = process(0); if (menu_event != nullptr && menu_event->itemref != nullptr) { if (menu_event->iptkey == IPT_UI_SELECT) { for (size_t idx = 0; idx < m_str_items.size(); ++idx) if ((void*)&m_str_items[idx] == menu_event->itemref) m_selector = idx; switch (m_category) { case INIFILE: mame_machine_manager::instance()->inifile().set_file(m_selector); mame_machine_manager::instance()->inifile().set_cat(0); reset_parent(reset_options::REMEMBER_REF); break; case CATEGORY: mame_machine_manager::instance()->inifile().set_cat(m_selector); reset_parent(reset_options::REMEMBER_REF); break; case GAME: main_filters::actual = m_hover; reset_parent(reset_options::SELECT_FIRST); break; case SOFTWARE: sw_filters::actual = m_hover; reset_parent(reset_options::SELECT_FIRST); break; default: reset_parent(reset_options::REMEMBER_REF); break; } ui_globals::switch_image = true; stack_pop(); } else if (menu_event->iptkey == IPT_SPECIAL) { if (input_character(m_search, menu_event->unichar, uchar_is_printable)) reset(reset_options::SELECT_FIRST); } // escape pressed with non-empty text clears the text else if (menu_event->iptkey == IPT_UI_CANCEL && m_search[0] != 0) { m_search.clear(); reset(reset_options::SELECT_FIRST); } } }
void simple_menu_select_game::inkey_special(const event *menu_event) { // typed characters append to the buffer size_t old_size = m_search.size(); if (input_character(m_search, menu_event->unichar, uchar_is_printable)) { if (m_search.size() < old_size) m_rerandomize = true; reset(reset_options::SELECT_FIRST); } }
/* Process all the characters in INPUTQ as if they had just been read. */ void rescan_inputq () { short *buf; int i, n; n = qsize (inputq); buf = alloca (n * sizeof (quoted_char)); memcpy (buf, inputq->cs, n * sizeof (quoted_char)); clear_queue (inputq); for (i = 0; i < n; i++) input_character (unquote_char (buf[i])); }
VIOAPI Status mni_input_string( FILE *file, STRING *string, char termination_char1, char termination_char2 ) { Status status; char ch; BOOLEAN quoted; *string = create_string( NULL ); status = mni_get_nonwhite_character( file, &ch ); if( status == OK && ch == '"' ) { quoted = TRUE; status = mni_get_nonwhite_character( file, &ch ); termination_char1 = '"'; termination_char2 = '"'; } else quoted = FALSE; while( status == OK && ch != termination_char1 && ch != termination_char2 && ch != '\n' ) { if (ch != '\r') { /* Always ignore carriage returns */ concat_char_to_string( string, ch ); } status = input_character( file, &ch ); } if( !quoted ) (void) unget_character( file, ch ); while( string_length(*string) > 0 && (*string)[string_length(*string)-1] == ' ' ) (*string)[string_length(*string)-1] = END_OF_STRING; if( status != OK ) { delete_string( *string ); *string = NULL; } return( status ); }
/* Read and enqueue input characters. Is also responsible to assert the DTR if necessary. */ static any_t hurdio_reader_loop (any_t arg) { /* XXX The input buffer has 256 bytes. */ #define BUFFER_SIZE 256 char buffer[BUFFER_SIZE]; char *data; size_t datalen; error_t err; mutex_lock (&global_lock); reader_thread = mach_thread_self (); while (1) { /* We can only start when the DTR has been asserted. */ while (ioport == MACH_PORT_NULL) wait_for_dtr (); mutex_unlock (&global_lock); data = buffer; datalen = BUFFER_SIZE; err = io_read (ioport, &data, &datalen, -1, BUFFER_SIZE); mutex_lock (&global_lock); /* Error or EOF can mean the carrier has been dropped. */ if (err || !datalen) hurdio_desert_dtr (); else { if (termstate.c_cflag & CREAD) { int i; for (i = 0; i < datalen; i++) if (input_character (data[i])) break; } if (data != buffer) vm_deallocate (mach_task_self(), (vm_address_t) data, datalen); } } #undef BUFFER_SIZE return 0; }
void ui_menu_file_create::handle() { // process the menu const ui_menu_event *event = process(0); // process the event if (event != NULL) { // handle selections switch(event->iptkey) { case IPT_UI_SELECT: if ((event->itemref == ITEMREF_CREATE) || (event->itemref == ITEMREF_NEW_IMAGE_NAME)) { std::string tmp_file(m_filename_buffer); if (tmp_file.find(".") != -1 && tmp_file.find(".") < tmp_file.length() - 1) { m_current_file.append(m_filename_buffer); ui_menu::stack_pop(machine()); } else machine().ui().popup_time(1, "Please enter a file extension too"); } break; case IPT_SPECIAL: if (get_selection() == ITEMREF_NEW_IMAGE_NAME) { input_character( m_filename_buffer, ARRAY_LENGTH(m_filename_buffer), event->unichar, is_valid_filename_char); reset(UI_MENU_RESET_REMEMBER_POSITION); } break; case IPT_UI_CANCEL: *m_ok = false; break; } } }
void menu_file_selector::type_search_char(char32_t ch) { std::string const current(m_filename); if (input_character(m_filename, ch, uchar_is_printable)) { ui().popup_time(ERROR_MESSAGE_TIME, "%s", m_filename.c_str()); file_selector_entry const *const cur_selected(reinterpret_cast<file_selector_entry const *>(get_selection_ref())); // if it's a perfect match for the current selection, don't move it if (!cur_selected || core_strnicmp(cur_selected->basename.c_str(), m_filename.c_str(), m_filename.size())) { std::string::size_type bestmatch(0); file_selector_entry const *selected_entry(cur_selected); for (auto &entry : m_entrylist) { // TODO: more efficient "common prefix" code std::string::size_type match(0); for (std::string::size_type i = 1; m_filename.size() >= i; ++i) { if (!core_strnicmp(entry.basename.c_str(), m_filename.c_str(), i)) match = i; else break; } if (match > bestmatch) { bestmatch = match; selected_entry = &entry; } } if (selected_entry && (selected_entry != cur_selected)) { set_selection((void *)selected_entry); centre_selection(); } } } }
int get_file_name( char *file_name, char *default_name, int flag ) { char buffer[127 + 2]; /* 127 is the biggest positive char */ int status = 0; /* If no default file name then supply the standard name */ if ( default_name[0] == '\0' ) { if ( flag == GAME_SCRIPT ) strcpy( default_name, SCRIPT_NAME ); else if ( flag == GAME_RECORD || flag == GAME_PLAYBACK ) strcpy( default_name, RECORD_NAME ); else if ( flag == GAME_SAVE_AUX || flag == GAME_LOAD_AUX ) strcpy( default_name, AUXILARY_NAME ); else /* (flag == GAME_SAVE || flag == GAME_RESTORE) */ strcpy( default_name, SAVE_NAME ); } /* Prompt for the file name */ output_line( "Enter a file name." ); output_string( "(Default is \"" ); output_string( default_name ); output_string( "\"): " ); buffer[0] = 127; buffer[1] = 0; ( void ) get_line( buffer, 0, 0 ); /* Copy file name from the input buffer */ if ( h_type > V4 ) { unsigned char len = buffer[1]; memcpy( file_name, &buffer[2], len ); file_name[len] = '\0'; } else strcpy( file_name, &buffer[1] ); /* If nothing typed then use the default name */ if ( file_name[0] == '\0' ) strcpy( file_name, default_name ); #if !defined(VMS) /* VMS has file version numbers, so cannot overwrite */ /* Check if we are going to overwrite the file */ if ( flag == GAME_SAVE || flag == GAME_SCRIPT || flag == GAME_RECORD || flag == GAME_SAVE_AUX ) { FILE *tfp; #if defined BUFFER_FILES char tfpbuffer[BUFSIZ]; #endif char c; /* Try to access the file */ tfp = fopen( file_name, "r" ); if ( tfp != NULL ) { /* If it succeeded then prompt to overwrite */ #if defined BUFFER_FILES setbuf( tfp, tfpbuffer ); #endif output_line( "You are about to write over an existing file." ); output_string( "Proceed? (Y/N) " ); do { c = ( char ) input_character( 0 ); c = ( char ) toupper( c ); } while ( c != 'Y' && c != 'N' ); output_char( c ); output_new_line( ); /* If no overwrite then fail the routine */ if ( c == 'N' ) status = 1; fclose( tfp ); } } #endif /* !defined(VMS) */ /* Record the file name if it was OK */ if ( status == 0 ) record_line( file_name ); return ( status ); } /* get_file_name */
void menu_software_list::handle() { const entry_info *selected_entry = nullptr; int bestmatch = 0; // process the menu const event *event = process(0); if (event && event->itemref) { if ((uintptr_t)event->itemref == 1 && event->iptkey == IPT_UI_SELECT) { m_ordered_by_shortname = !m_ordered_by_shortname; // reset the char buffer if we change ordering criterion m_filename_buffer.clear(); // reload the menu with the new order reset(reset_options::REMEMBER_REF); machine().popmessage(_("Switched Order: entries now ordered by %s"), m_ordered_by_shortname ? _("shortname") : _("description")); } // handle selections else if (event->iptkey == IPT_UI_SELECT) { entry_info *info = (entry_info *) event->itemref; m_result = info->short_name; stack_pop(); } else if (event->iptkey == IPT_SPECIAL) { if (input_character(m_filename_buffer, event->unichar, &is_valid_softlist_part_char)) { // display the popup ui().popup_time(ERROR_MESSAGE_TIME, "%s", m_filename_buffer); // identify the selected entry entry_info const *const cur_selected = (uintptr_t(event->itemref) != 1) ? reinterpret_cast<entry_info const *>(get_selection_ref()) : nullptr; // loop through all entries for (auto &entry : m_entrylist) { // is this entry the selected entry? if (cur_selected != &entry) { auto &compare_name = m_ordered_by_shortname ? entry.short_name : entry.long_name; int match = 0; for (int i = 0; i < m_filename_buffer.size() + 1; i++) { if (core_strnicmp(compare_name.c_str(), m_filename_buffer.c_str(), i) == 0) match = i; } if (match > bestmatch) { bestmatch = match; selected_entry = &entry; } } } if (selected_entry != nullptr && selected_entry != cur_selected) { set_selection((void *)selected_entry); centre_selection(); } } } else if (event->iptkey == IPT_UI_CANCEL) { // reset the char buffer also in this case m_filename_buffer.clear(); m_result = m_filename_buffer; stack_pop(); } } }
void menu_file_selector::handle() { osd_file::error err; const file_selector_entry *selected_entry = nullptr; int bestmatch = 0; // process the menu const event *event = process(0); if (event != nullptr && event->itemref != nullptr) { // handle selections if (event->iptkey == IPT_UI_SELECT) { auto entry = (const file_selector_entry *) event->itemref; switch (entry->type) { case SELECTOR_ENTRY_TYPE_EMPTY: // empty slot - unload m_result = result::EMPTY; stack_pop(); break; case SELECTOR_ENTRY_TYPE_CREATE: // create m_result = result::CREATE; stack_pop(); break; case SELECTOR_ENTRY_TYPE_SOFTWARE_LIST: m_result = result::SOFTLIST; stack_pop(); break; case SELECTOR_ENTRY_TYPE_DRIVE: case SELECTOR_ENTRY_TYPE_DIRECTORY: // drive/directory - first check the path err = util::zippath_opendir(entry->fullpath, nullptr); if (err != osd_file::error::NONE) { // this path is problematic; present the user with an error and bail ui().popup_time(1, "Error accessing %s", entry->fullpath); break; } m_current_directory.assign(entry->fullpath); reset(reset_options::SELECT_FIRST); break; case SELECTOR_ENTRY_TYPE_FILE: // file m_current_file.assign(entry->fullpath); m_result = result::FILE; stack_pop(); break; } // reset the char buffer when pressing IPT_UI_SELECT m_filename.clear(); } else if (event->iptkey == IPT_SPECIAL) { // if it's any other key and we're not maxed out, update if (input_character(m_filename, event->unichar, uchar_is_printable)) { ui().popup_time(ERROR_MESSAGE_TIME, "%s", m_filename.c_str()); file_selector_entry const *const cur_selected(reinterpret_cast<file_selector_entry const *>(get_selection_ref())); // check for entries which matches our m_filename_buffer: for (auto &entry : m_entrylist) { if (cur_selected != &entry) { int match = 0; for (int i = 0; i < m_filename.size() + 1; i++) { if (core_strnicmp(entry.basename.c_str(), m_filename.c_str(), i) == 0) match = i; } if (match > bestmatch) { bestmatch = match; selected_entry = &entry; } } } if (selected_entry != nullptr && selected_entry != cur_selected) { set_selection((void *)selected_entry); centre_selection(); } } } else if (event->iptkey == IPT_UI_CANCEL) { // reset the char buffer also in this case m_filename.clear(); } } }
//***************************************************************************** // // This function reads a line of text from the player. // //***************************************************************************** int input_line(int buflen, char *buffer, int timeout, int *read_size) { int iRow, iColumn; long lChar; // // Loop forever. This loop will be explicitly when appropriate. // while(1) { // // Read a character. // lChar = input_character(timeout); // // If the ZIP interpreter has been halted, then return immediately. // if(halt) { return('\n'); } // // See if a backsapce or delete character was read. // if((lChar == '\b') || (lChar == 0x7f)) { // // See if there are any characters in the buffer. // if(*read_size != 0) { // // Decrement the number of characters in the buffer. // (*read_size)--; // // Get the cursor position. // get_cursor_position(&iRow, &iColumn); // // Move the cursor one character to the left. // move_cursor(iRow, --iColumn); // // Display a space to erase the previous character. // display_char(' '); // // Move the cursor back to the left. // move_cursor(iRow, iColumn); } } // // See if this a carriage return or newline character. // else if((lChar == '\n') || (lChar == '\r')) { // // Ignore this character if the previous character was the opposite // of the CR/LF pair. // if(((lChar == '\n') && (g_lPrevChar != '\r')) || ((lChar == '\r') && (g_lPrevChar != '\n'))) { // // Save this character as the previous character. // g_lPrevChar = lChar; // // Scroll the screen. // scroll_line(); // // Return the most recently read character. // return(lChar); } } // // See if there is space in the buffer for another character. // else if(*read_size != (buflen - 1)) { // // Save this character in the buffer. // buffer[(*read_size)++] = lChar; // // Display this character. // display_char(lChar); } // // Save this character as the previous character. // g_lPrevChar = lChar; } }
void menu_add_change_folder::handle() { // process the menu const event *menu_event = process(0); if (menu_event != nullptr && menu_event->itemref != nullptr) { if (menu_event->iptkey == IPT_UI_SELECT) { int index = (uintptr_t)menu_event->itemref - 1; const menu_item &pitem = item[index]; // go up to the parent path if (!strcmp(pitem.text.c_str(), "..")) { size_t first_sep = m_current_path.find_first_of(PATH_SEPARATOR[0]); size_t last_sep = m_current_path.find_last_of(PATH_SEPARATOR[0]); if (first_sep != last_sep) m_current_path.erase(++last_sep); } else { // if isn't a drive, appends the directory if (strcmp(pitem.subtext.c_str(), "[DRIVE]") != 0) { if (m_current_path[m_current_path.length() - 1] == PATH_SEPARATOR[0]) m_current_path.append(pitem.text); else m_current_path.append(PATH_SEPARATOR).append(pitem.text); } else m_current_path = pitem.text; } // reset the char buffer also in this case m_search[0] = '\0'; reset(reset_options::SELECT_FIRST); } else if (menu_event->iptkey == IPT_SPECIAL) { bool update_selected = false; if (menu_event->unichar == 0x09) { // Tab key, save current path std::string error_string; if (m_change) { if (ui().options().exists(s_folders[m_ref].option)) ui().options().set_value(s_folders[m_ref].option, m_current_path.c_str(), OPTION_PRIORITY_CMDLINE, error_string); else if (strcmp(machine().options().value(s_folders[m_ref].option), m_current_path.c_str()) != 0) { machine().options().set_value(s_folders[m_ref].option, m_current_path.c_str(), OPTION_PRIORITY_CMDLINE, error_string); machine().options().mark_changed(s_folders[m_ref].option); } } else { m_folders.push_back(m_current_path); std::string tmppath; for (int x = 0; x < m_folders.size(); ++x) { tmppath.append(m_folders[x]); if (x != m_folders.size() - 1) tmppath.append(";"); } if (ui().options().exists(s_folders[m_ref].option)) ui().options().set_value(s_folders[m_ref].option, tmppath.c_str(), OPTION_PRIORITY_CMDLINE, error_string); else if (strcmp(machine().options().value(s_folders[m_ref].option), tmppath.c_str()) != 0) { machine().options().set_value(s_folders[m_ref].option, tmppath.c_str(), OPTION_PRIORITY_CMDLINE, error_string); machine().options().mark_changed(s_folders[m_ref].option); } } reset_parent(reset_options::SELECT_FIRST); stack_pop(); } else { // if it's any other key and we're not maxed out, update update_selected = input_character(m_search, menu_event->unichar, uchar_is_printable); } // check for entries which matches our search buffer if (update_selected) { const int cur_selected = selected_index(); int entry, bestmatch = 0; // from current item to the end for (entry = cur_selected; entry < item.size(); entry++) if (item[entry].ref != nullptr && !m_search.empty()) { int match = 0; for (int i = 0; i < m_search.size() + 1; i++) { if (core_strnicmp(item[entry].text.c_str(), m_search.data(), i) == 0) match = i; } if (match > bestmatch) { bestmatch = match; selected = entry; } } // and from the first item to current one for (entry = 0; entry < cur_selected; entry++) { if (item[entry].ref != nullptr && !m_search.empty()) { int match = 0; for (int i = 0; i < m_search.size() + 1; i++) { if (core_strnicmp(item[entry].text.c_str(), m_search.data(), i) == 0) match = i; } if (match > bestmatch) { bestmatch = match; selected = entry; } } } centre_selection(); } } else if (menu_event->iptkey == IPT_UI_CANCEL) { // reset the char buffer also in this case m_search.clear(); } } }