123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653 |
- /* $Id$
- * MegaZeux
- *
- * Copyright (C) 1996 Greg Janson
- * Copyright (C) 1998 Matthew D. Williams - dbwilli@scsn.net
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
- // Code to the intake function, which inputs text with friendliness.
- #include <string.h>
- #include "event.h"
- #include "intake.h"
- #include "graphics.h"
- #include "window.h"
- #include "hexchar.h"
- // Global status of insert
- char insert_on = 1;
- // (returns the key used to exit) String points to your memory for storing
- // the new string. The current "value" is used- clear the string before
- // calling intake if you need a blank string. Max_len is the maximum length
- // of the string. X, y, segment, and color are self-explanitory. Exit_type
- // determines when intake exits- 0 means exit only on Enter, 1 on Enter or
- // ESC, 2 on any non-display char except the editing keys. Filter_type is
- // bits to turn on filters- 1 changes all alpha to upper, 2 changes all
- // alpha to lower, 4 blocks all numbers, 8 blocks all alpha, 16 blocks
- // spaces, 32 blocks graphics, (ascii>126) 64 blocks punctuation that isn't
- // allowed in a filename/path/drive combo, 128 blocks punctuation that isn't
- // allowed in a filename only combo (use w/64), 256 blocks all punctuation.
- // (IE non-alphanumerics and spaces) The editing keys supported are as
- // follows- Keys to enter characters, Enter/ESC to exit, Home/End to move to
- // the front/back of the line, Insert to toggle insert/overwrite, Left/Right
- // to move within the line, Bkspace/Delete to delete as usual, and Alt-Bksp
- // to clear the entire line. No screen saving is performed. After this
- // function, the cursor is automatically off. If password is set, all
- // characters appear as x.
- // Password character
- #define PW_CHAR 42
- // Mouse support- Clicking inside string sends cursor there. Clicking
- // outside string returns a MOUSE_EVENT to caller without acknowledging
- // the event.
- // Returns a backspace if attempted at start of line. (and exit_type==2)
- // Returns a delete if attempted at end of line. (and exit_type==2)
- // If robo_intk is set, only 76 chars are shown and symbols are altered
- // on the left/right if there is more to the left/right. Scrolling
- // of the line is supported. The current character (1 on) is shown at
- // x = 32, y = 0, in color 79, min. 3 chars.
- // Also, if robo_intk is set, then ANY line consisting of ONLY semicolons,
- // commas, and spaces is returned as a blank line (0 length)
- int intake(char *string, int max_len, char x, char y,
- unsigned char color, char exit_type, int filter_type,
- char password, int *return_x_pos, char robo_intk, char *macro)
- {
- int currx, key, curr_len, t1, ret;
- int macro_position = -1;
- int done = 0, place;
- char cur_char = 0;
- char temp_char;
- int in_macro;
- static unsigned char ch_sel = 219;
- if(macro != NULL)
- macro_position = 0;
- // Activate cursor
- if(insert_on)
- cursor_underline();
- else
- cursor_solid();
- // Put cursor at the end of the string...
- currx = curr_len = strlen(string);
- // ...unless return_x_pos says not to.
- if((return_x_pos) && (*return_x_pos < currx))
- currx = *return_x_pos;
- if(robo_intk && (currx > 75))
- move_cursor(77, y);
- else
- move_cursor(x + currx, y);
- if(insert_on)
- cursor_underline();
- else
- cursor_solid();
- do
- {
- // Draw current string
- if(password)
- {
- fill_line(curr_len, x, y, PW_CHAR, color);
- }
- else
- if(!robo_intk)
- {
- write_string(string, x, y, color, 0);
- }
- else
- {
- draw_char('', color, 79, y);
- if((curr_len < 76) || (currx < 76))
- {
- draw_char('', color, 0, y);
- if(curr_len < 76)
- {
- write_line(string, x, y, color, 0);
- fill_line(76 - curr_len, x + curr_len, y, 32, color);
- }
- else
- {
- temp_char = string[76];
- string[76] = 0;
- write_line(string, x, y, color, 0);
- string[76] = temp_char;
- draw_char('¯', color, 79, y);
- }
- }
- else
- {
- draw_char(' ', color, 77, y);
- if(strlen(string + currx - 75) > 78)
- {
- temp_char = string[currx + 1];
- string[currx + 1] = 0;
- write_line(string + currx - 75, x, y, color, 0);
- string[currx + 1] = temp_char;
- }
- else
- {
- write_line(string + currx - 75, x, y, color, 0);
- }
- draw_char('®', color, 0, y);
- if(currx < curr_len)
- draw_char('¯', color, 79, y);
- }
- draw_char(' ', color, 78, y);
- }
- if(!robo_intk)
- {
- fill_line(max_len + 1 - curr_len, x + curr_len, y, 32, color);
- }
- else
- {
- write_number(currx + 1, 79, 37, 0, 3);
- write_number(curr_len + 1, 79, 41, 0, 3);
- }
- in_macro = 0;
- // Get key
- if(macro_position != -1)
- {
- key = macro[macro_position];
- cur_char = key;
- macro_position++;
- if(macro[macro_position] == 0)
- macro_position = -1;
- if(key == '^')
- key = SDLK_RETURN;
- }
- else
- {
- update_screen();
- update_event_status_delay();
- key = get_key(keycode_SDL);
- place = 0;
- cur_char = get_key(keycode_unicode);
- }
- if(get_mouse_press())
- {
- int mouse_x, mouse_y;
- get_mouse_position(&mouse_x, &mouse_y);
- if((mouse_y == y) && (mouse_x >= x) && (mouse_x <= (x + max_len)))
- {
- // Yep, reposition cursor.
- currx = mouse_x - x;
- if(currx > curr_len)
- currx = curr_len;
- }
- else
- {
- key = -1;
- done = 1;
- }
- }
- // Handle key cases
- switch(key)
- {
- case SDLK_ESCAPE:
- {
- // ESC
- if(exit_type > 0)
- {
- done = 1;
- }
- break;
- }
- case SDLK_KP_ENTER:
- case SDLK_RETURN:
- {
- // Enter
- done = 1;
- break;
- }
- case SDLK_HOME:
- {
- if(get_alt_status(keycode_SDL) && robo_intk)
- {
- done = 1;
- }
- else
- {
- // Home
- currx = 0;
- }
- break;
- }
- case SDLK_END:
- {
- if(get_alt_status(keycode_SDL) && robo_intk)
- {
- done = 1;
- }
- else
- {
- // End
- currx = curr_len;
- }
- break;
- }
- case SDLK_LEFT:
- {
- if(get_ctrl_status(keycode_SDL))
- {
- // Find nearest space to the left
- if(currx)
- {
- char *current_position = string + currx;
- do
- {
- current_position--;
- currx--;
- } while(currx && (*current_position != ' '));
- }
- }
- else
- {
- // Left
- if(currx > 0)
- currx--;
- }
- break;
- }
- case SDLK_RIGHT:
- {
- if(get_ctrl_status(keycode_SDL))
- {
- // Find nearest space to the right
- if(currx < curr_len)
- {
- char *current_position = string + currx;
- char current_char;
- do
- {
- current_position++;
- currx++;
- current_char = *current_position;
- } while(current_char && (current_char != ' '));
- }
- }
- else
- {
- // Right
- if(currx < curr_len)
- currx++;
- }
- break;
- }
- case SDLK_F1:
- case SDLK_F2:
- case SDLK_F3:
- case SDLK_F4:
- case SDLK_F5:
- case SDLK_F6:
- case SDLK_F7:
- case SDLK_F8:
- case SDLK_F9:
- case SDLK_F10:
- case SDLK_F11:
- case SDLK_F12:
- case SDLK_UP:
- case SDLK_DOWN:
- case SDLK_TAB:
- case SDLK_PAGEUP:
- case SDLK_PAGEDOWN:
- {
- done = 1;
- break;
- }
- case SDLK_INSERT:
- {
- if(get_alt_status(keycode_SDL) && robo_intk)
- {
- done = 1;
- }
- else
- {
- // Insert
- if(insert_on)
- cursor_solid();
- else
- cursor_underline();
- insert_on ^= 1;
- }
- break;
- }
- case SDLK_BACKSPACE:
- {
- // Backspace, at 0 it might exit
- if(get_alt_status(keycode_SDL))
- {
- // Alt-backspace, erase input
- curr_len = currx = 0;
- string[0] = 0;
- }
- else
- if(currx == 0)
- {
- if(exit_type == 2)
- {
- done = 1;
- }
- }
- else
- {
- // Move all back 1, decreasing string length
- memmove(string + currx - 1, string + currx, curr_len - currx + 1);
- curr_len--;
- // Cursor back one
- currx--;
- }
- break;
- }
- case SDLK_DELETE:
- {
- // Delete, at the end might exit
- if(currx == curr_len)
- {
- if(exit_type == 2)
- done = 1;
- }
- else
- {
- if(curr_len)
- {
- // Move all back 1, decreasing string length
- memmove(string + currx, string + currx + 1, curr_len - currx);
- curr_len--;
- }
- }
- break;
- }
- case SDLK_c:
- {
- if(get_ctrl_status(keycode_SDL) && robo_intk)
- {
- done = 1;
- }
- else
- if(get_alt_status(keycode_SDL) && !filter_type)
- {
- // If alt - C is pressed, choose character
- int new_char = char_selection(cur_char);
- if(new_char >= 32)
- {
- cur_char = new_char;
- place = 1;
- }
- else
- {
- place = 0;
- }
- }
- else
- {
- place = 1;
- }
- break;
- }
- case SDLK_t:
- {
- if(get_alt_status(keycode_SDL))
- {
- done = 1;
- }
- else
- {
- place = 1;
- }
- break;
- }
- case SDLK_l:
- case SDLK_g:
- case SDLK_d:
- {
- if(get_ctrl_status(keycode_SDL) && robo_intk)
- {
- done = 1;
- }
- else
- {
- place = 1;
- }
- break;
- }
- case SDLK_i:
- {
- if((get_ctrl_status(keycode_SDL) ||
- get_alt_status(keycode_SDL)) && robo_intk)
- {
- done = 1;
- }
- else
- {
- place = 1;
- }
- break;
- }
- case SDLK_u:
- case SDLK_o:
- case SDLK_x:
- case SDLK_b:
- case SDLK_s:
- case SDLK_e:
- case SDLK_v:
- case SDLK_p:
- {
- if(get_alt_status(keycode_SDL) && robo_intk)
- {
- done = 1;
- }
- else
- {
- place = 1;
- }
- break;
- }
- case SDLK_LSHIFT:
- case SDLK_RSHIFT:
- case 0:
- {
- place = 0;
- break;
- }
- default:
- {
- // Place the char
- place = 1;
- break;
- }
- }
- if(place)
- {
- if((cur_char < 32) && (exit_type == 2))
- {
- done = 1;
- key = cur_char;
- }
- else
- // Keycode.. Filter.
- if(filter_type & 1)
- {
- if((cur_char >= 'a') && (cur_char <= 'z'))
- cur_char -= 32;
- }
- if(filter_type & 2)
- {
- if((cur_char >= 'A') && (cur_char <= 'Z'))
- cur_char += 32;
- }
- // Block numbers
- if((filter_type & 4) && ((cur_char >= '0') && (cur_char <= '9')))
- {
- place = 0;
- }
- // Block alpha
- if((filter_type & 8) &&
- (((cur_char >= 'a') && (cur_char <= 'z')) ||
- ((cur_char >= 'A') && (cur_char <= 'Z'))))
- {
- place = 0;
- }
- // Block spaces
- if((filter_type & 16) && (cur_char == ' '))
- {
- place = 0;
- }
- // Block high-ASCII
- if((filter_type & 32) && (cur_char > 126))
- {
- place = 0;
- }
- // Block these chars
- if((filter_type & 64) &&
- ((cur_char == '*') || (cur_char == '[') ||
- (cur_char == ']') || (cur_char == '>') ||
- (cur_char == '<') || (cur_char == ',') ||
- (cur_char == '|') || (cur_char == '?') ||
- (cur_char == '=') || (cur_char == ';') ||
- (cur_char == '\"') || (cur_char =='/')))
- {
- place = 0;
- }
- // Block these chars
- if((filter_type & 128) &&
- ((cur_char == ':') || (cur_char == '\\')))
- {
- place = 0;
- }
- // Block these chars
- if((filter_type & 256) &&
- (((cur_char > ' ') && (cur_char < '0')) ||
- ((cur_char > '9') && (cur_char < 'A')) ||
- ((cur_char > 'Z') && (cur_char < 'a')) ||
- ((cur_char > 'z') && (cur_char < 127))))
- {
- place = 0;
- }
- // Now, can it still be placed?
- if(place && (curr_len != max_len) && (!done) && cur_char)
- {
- // Overwrite or insert?
- if((insert_on) || (currx == curr_len))
- {
- // Insert- Move all ahead 1, increasing string length
- curr_len++;
- memmove(string + currx + 1, string + currx, curr_len - currx);
- }
- // Add character and move forward one
- string[currx++] = cur_char;
- }
- }
- // Move cursor
- if(robo_intk && (currx > 75))
- move_cursor(77, y);
- else
- move_cursor(x + currx, y);
- if(insert_on)
- cursor_underline();
- else
- cursor_solid();
- // Loop
- } while(!done);
- cursor_off();
- if(return_x_pos)
- *return_x_pos = currx;
- // Return ret. If robo_intk, verify that the string is valid
- if(robo_intk)
- {
- curr_len = strlen(string);
- if(curr_len)
- {
- for(t1 = 0; t1 < curr_len; t1++)
- {
- if((string[t1] != ';') && (string[t1] != ',') &&
- (string[t1] != ' '))
- break;
- }
- if(t1 >= curr_len)
- {
- string[0] = 0; // Become an empty string
- if(return_x_pos)
- *return_x_pos = 0;
- }
- }
- }
- return key;
- }
|