static const char *Con_LineToString( int lineno, qboolean lf ) { const conChar_t *line = consoleState.text + CON_LINE( lineno ); int s, d; for ( s = d = 0; line[ s ].ch && s < consoleState.textWidthInChars; ++s ) { if ( line[ s ].ch < 0x80 ) { lineString[ d++ ] = (char) line[ s ].ch; } else { strcpy( lineString + d, Q_UTF8_Encode( line[ s ].ch ) ); while ( lineString[ d ] ) { ++d; } } } if ( lf ) { #ifdef _WIN32 lineString[ d++ ] = '\r'; #endif lineString[ d++ ] = '\n'; } lineString[ d ] = '\0'; return lineString; }
static const char *Con_LineToColouredString( int lineno, qboolean lf ) { const conChar_t *line = consoleState.text + CON_LINE( lineno ); int s, d, colour = 7; for ( s = d = 0; line[ s ].ch && s < consoleState.textWidthInChars; ++s ) { if ( line[ s ].ink != colour ) { colour = line[ s ].ink; lineString[ d++ ] = '^'; lineString[ d++ ] = '0' + colour; } if ( line[ s ].ch < 0x80 ) { lineString[ d++ ] = (char) line[ s ].ch; } else { strcpy( lineString + d, Q_UTF8_Encode( line[ s ].ch ) ); while ( lineString[ d ] ) { ++d; } } } if ( lf ) { lineString[ d++ ] = '\n'; } lineString[ d ] = '\0'; return lineString; }
/* ================ MField_Buffer Returns a UTF-8 encoded string. ================ */ const char *MField_Buffer( mfield_t *edit ) { static char str[MAX_STRING_CHARS]; int i; str[0] = 0; for ( i = 0; i < edit->len; i++ ) { Q_strcat( str, sizeof( str ), Q_UTF8_Encode( edit->buffer[i] ) ); } return str; }
/* =================== MField_Draw Handles horizontal scrolling and cursor blinking x, y, charWidth, charHeight, are in 640*480 virtual screen size =================== */ void MField_Draw( mfield_t *edit, int x, int y, int style, vec4_t color, qboolean drawCursor ) { int i; int len; int drawLen; int prestep; int cursorChar; char str[MAX_STRING_CHARS]; drawLen = edit->widthInChars; len = edit->len + 1; // guarantee that cursor will be visible if ( len <= drawLen ) { prestep = 0; } else { if ( edit->scroll + drawLen > len ) { edit->scroll = len - drawLen; if ( edit->scroll < 0 ) { edit->scroll = 0; } } prestep = edit->scroll; } if ( prestep + drawLen > len ) { drawLen = len - prestep; } // extract <drawLen> characters from the field at <prestep> str[0] = 0; for ( i = 0; i < drawLen; i++ ) { Q_strcat( str, sizeof( str ), Q_UTF8_Encode( edit->buffer[prestep+i] ) ); } if ( drawCursor ) { // if overstrike and not at end of buffer if ( trap_Key_GetOverstrikeMode() && edit->cursor != edit->len ) { cursorChar = GLYPH_OVERSTRIKE; } else { cursorChar = GLYPH_INSERT; } } else { cursorChar = -1; } CG_DrawStringWithCursor( x, y, str, style, color, ( edit->cursor - prestep ), cursorChar ); }
/* =============== IN_ProcessEvents =============== */ static void IN_ProcessEvents( qboolean dropInput ) { SDL_Event e; keyNum_t key = (keyNum_t) 0; static keyNum_t lastKeyDown = (keyNum_t) 0; if ( !SDL_WasInit( SDL_INIT_VIDEO ) ) { return; } #if !SDL_VERSION_ATLEAST( 2, 0, 0 ) if ( cls.keyCatchers == 0 && keyRepeatEnabled ) { SDL_EnableKeyRepeat( 0, 0 ); keyRepeatEnabled = qfalse; } else if ( !keyRepeatEnabled ) { SDL_EnableKeyRepeat( SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL ); keyRepeatEnabled = qtrue; } #endif while ( SDL_PollEvent( &e ) ) { switch ( e.type ) { case SDL_KEYDOWN: #if SDL_VERSION_ATLEAST( 2, 0, 0 ) if ( !dropInput && ( !e.key.repeat || cls.keyCatchers ) ) #else if ( !dropInput ) #endif { key = IN_TranslateSDLToQ3Key( &e.key.keysym, qtrue ); if ( key ) { Com_QueueEvent( 0, SE_KEY, key, qtrue, 0, NULL ); #if !SDL_VERSION_ATLEAST( 2, 0, 0 ) if ( key != K_CONSOLE ) { Com_QueueEvent( 0, SE_CHAR, Q_UTF8_Store( Q_UTF8_Encode( e.key.keysym.unicode ) ), 0, 0, NULL ); } #endif } lastKeyDown = key; } break; case SDL_KEYUP: if ( !dropInput ) { key = IN_TranslateSDLToQ3Key( &e.key.keysym, qfalse ); if ( key ) { Com_QueueEvent( 0, SE_KEY, key, qfalse, 0, NULL ); } lastKeyDown = (keyNum_t) 0; } break; #if SDL_VERSION_ATLEAST( 2, 0, 0 ) case SDL_TEXTINPUT: if ( lastKeyDown != K_CONSOLE ) { char *c = e.text.text; while ( *c ) { int width = Q_UTF8_Width( c ); int sc = Q_UTF8_Store( c ); Com_QueueEvent( 0, SE_CHAR, sc, 0, 0, NULL ); c += width; } } break; #endif case SDL_MOUSEMOTION: if ( !dropInput ) { if ( mouseActive ) { Com_QueueEvent( 0, SE_MOUSE, e.motion.xrel, e.motion.yrel, 0, NULL ); #if ( defined( __linux__ ) || defined( __BSD__ ) ) && SDL_VERSION_ATLEAST( 2, 0, 0 ) { // work around X window managers and edge-based workspace flipping // - without this, we get LeaveNotify, no mouse button events, EnterNotify; // we would likely miss some button presses and releases. int w, h; SDL_GetWindowSize( window, &w, &h ); SDL_WarpMouseInWindow( window, w / 2, h / 2 ); } #endif } else if ( uivm ) { // TODO (after no compatibility needed with alpha 8): remove argument int mousepos = VM_Call( uivm, UI_MOUSE_POSITION, 0 ); int cursorx = mousepos & 0xFFFF; int cursory = mousepos >> 16; VM_Call( uivm, UI_MOUSE_EVENT, e.motion.x - cursorx, e.motion.y - cursory ); } } break; case SDL_MOUSEBUTTONDOWN: case SDL_MOUSEBUTTONUP: if ( !dropInput ) { unsigned char b; switch ( e.button.button ) { case SDL_BUTTON_LEFT: b = K_MOUSE1; break; case SDL_BUTTON_MIDDLE: b = K_MOUSE3; break; case SDL_BUTTON_RIGHT: b = K_MOUSE2; break; #if !SDL_VERSION_ATLEAST( 2, 0, 0 ) case SDL_BUTTON_WHEELUP: b = K_MWHEELUP; break; case SDL_BUTTON_WHEELDOWN: b = K_MWHEELDOWN; break; #endif case SDL_BUTTON_X1: b = K_MOUSE4; break; case SDL_BUTTON_X2: b = K_MOUSE5; break; default: b = K_AUX1 + ( e.button.button - ( SDL_BUTTON_X2 + 1 ) ) % 16; break; } Com_QueueEvent( 0, SE_KEY, b, ( e.type == SDL_MOUSEBUTTONDOWN ? qtrue : qfalse ), 0, NULL ); } break; #if SDL_VERSION_ATLEAST( 2, 0, 0 ) case SDL_MOUSEWHEEL: // FIXME: mouse wheel support shouldn't use keys! if ( e.wheel.y > 0 ) { Com_QueueEvent( 0, SE_KEY, K_MWHEELUP, qtrue, 0, NULL ); Com_QueueEvent( 0, SE_KEY, K_MWHEELUP, qfalse, 0, NULL ); } else { Com_QueueEvent( 0, SE_KEY, K_MWHEELDOWN, qtrue, 0, NULL ); Com_QueueEvent( 0, SE_KEY, K_MWHEELDOWN, qfalse, 0, NULL ); } break; case SDL_WINDOWEVENT: switch( e.window.event ) { case SDL_WINDOWEVENT_RESIZED: { char width[32], height[32]; Com_sprintf( width, sizeof( width ), "%d", e.window.data1 ); Com_sprintf( height, sizeof( height ), "%d", e.window.data2 ); Cvar_Set( "r_customwidth", width ); Cvar_Set( "r_customheight", height ); Cvar_Set( "r_mode", "-1" ); } break; case SDL_WINDOWEVENT_MINIMIZED: Cvar_SetValue( "com_minimized", 1 ); break; case SDL_WINDOWEVENT_RESTORED: case SDL_WINDOWEVENT_MAXIMIZED: Cvar_SetValue( "com_minimized", 0 ); break; case SDL_WINDOWEVENT_FOCUS_LOST: Cvar_SetValue( "com_unfocused", 1 ); break; case SDL_WINDOWEVENT_FOCUS_GAINED: Cvar_SetValue( "com_unfocused", 0 ); break; } break; #else case SDL_VIDEORESIZE: { char width[32], height[32]; Com_sprintf( width, sizeof( width ), "%d", e.resize.w ); Com_sprintf( height, sizeof( height ), "%d", e.resize.h ); Cvar_Set( "r_customwidth", width ); Cvar_Set( "r_customheight", height ); Cvar_Set( "r_mode", "-1" ); } break; case SDL_ACTIVEEVENT: if ( e.active.state & SDL_APPINPUTFOCUS ) { Cvar_SetValue( "com_unfocused", !e.active.gain ); } if ( e.active.state & SDL_APPACTIVE ) { Cvar_SetValue( "com_minimized", !e.active.gain ); } break; #endif case SDL_QUIT: Cmd::ExecuteCommand("quit Closed window"); break; default: break; } } }