/* ================== Info_SetValueForKey ================== */ qboolean Info_SetValueForKey( char *s, const char *key, const char *value ) { char newi[MAX_INFO_STRING], *v; size_t l, kl, vl; int c; // validate key kl = Info_SubValidate( key ); if( kl >= MAX_QPATH ) { return qfalse; } // validate value vl = Info_SubValidate( value ); if( vl >= MAX_QPATH ) { return qfalse; } Info_RemoveKey( s, key ); if( !vl ) { return qtrue; } l = strlen( s ); if( l + kl + vl + 2 >= MAX_INFO_STRING ) { return qfalse; } newi[0] = '\\'; memcpy( newi + 1, key, kl ); newi[kl + 1] = '\\'; memcpy( newi + kl + 2, value, vl + 1 ); // only copy ascii values s += l; v = newi; while( *v ) { c = *v++; c &= 127; // strip high bits if( Q_isprint( c ) ) *s++ = c; } *s = 0; return qtrue; }
/* ================ COM_strclr Operates inplace, normalizing high-bit and removing unprintable characters. Returns final number of characters, not including the NUL character. ================ */ size_t COM_strclr( char *s ) { char *p; int c; size_t len; p = s; len = 0; while( *s ) { c = *s++; c &= 127; if( Q_isprint( c ) ) { *p++ = c; len++; } } *p = 0; return len; }
sfxHandle_t ScrollList_Key(menulist_s *l, int key) { int x; int y; int w; int i; int j; int c; int cursorx; int cursory; int column; int index; switch (key) { case K_MOUSE1: if (l->generic.flags & QMF_HASMOUSEFOCUS) { // check scroll region x = l->generic.x; y = l->generic.y; w = ((l->width + l->seperation) * l->columns - l->seperation) * SMALLCHAR_SIZE; if (l->generic.flags & QMF_CENTER_JUSTIFY) { x -= w / 2; } if (UI_CursorInRect(x, y, w, l->height*SMALLCHAR_SIZE)) { cursorx = (uis.cursorx - x)/SMALLCHAR_SIZE; column = cursorx / (l->width + l->seperation); cursory = (uis.cursory - y)/SMALLCHAR_SIZE; index = column * l->height + cursory; if (l->top + index < l->numitems) { l->oldvalue = l->curvalue; l->curvalue = l->top + index; if (l->oldvalue != l->curvalue && l->generic.callback) { l->generic.callback(l, QM_GOTFOCUS); return (menu_move_sound); } } } // absorbed, silent sound effect return (menu_null_sound); } break; case K_KP_HOME: case K_HOME: l->oldvalue = l->curvalue; l->curvalue = 0; l->top = 0; if (l->oldvalue != l->curvalue && l->generic.callback) { l->generic.callback(l, QM_GOTFOCUS); return (menu_move_sound); } return (menu_buzz_sound); case K_KP_END: case K_END: l->oldvalue = l->curvalue; l->curvalue = l->numitems-1; if (l->columns > 1) { c = (l->curvalue / l->height + 1) * l->height; l->top = c - (l->columns * l->height); } else { l->top = l->curvalue - (l->height - 1); } if (l->top < 0) { l->top = 0; } if (l->oldvalue != l->curvalue && l->generic.callback) { l->generic.callback(l, QM_GOTFOCUS); return (menu_move_sound); } return (menu_buzz_sound); case K_PGUP: case K_KP_PGUP: if (l->columns > 1) { return menu_null_sound; } if (l->curvalue > 0) { l->oldvalue = l->curvalue; l->curvalue -= l->height-1; if (l->curvalue < 0) { l->curvalue = 0; } l->top = l->curvalue; if (l->top < 0) { l->top = 0; } if (l->generic.callback) { l->generic.callback(l, QM_GOTFOCUS); } return (menu_move_sound); } return (menu_buzz_sound); case K_PGDN: case K_KP_PGDN: if (l->columns > 1) { return menu_null_sound; } if (l->curvalue < l->numitems-1) { l->oldvalue = l->curvalue; l->curvalue += l->height-1; if (l->curvalue > l->numitems-1) { l->curvalue = l->numitems-1; } l->top = l->curvalue - (l->height-1); if (l->top < 0) { l->top = 0; } if (l->generic.callback) { l->generic.callback(l, QM_GOTFOCUS); } return (menu_move_sound); } return (menu_buzz_sound); case K_KP_UPARROW: case K_UPARROW: if (l->curvalue == 0) { return menu_buzz_sound; } l->oldvalue = l->curvalue; l->curvalue--; if (l->curvalue < l->top) { if (l->columns == 1) { l->top--; } else { l->top -= l->height; } } if (l->generic.callback) { l->generic.callback(l, QM_GOTFOCUS); } return (menu_move_sound); case K_KP_DOWNARROW: case K_DOWNARROW: if (l->curvalue == l->numitems - 1) { return menu_buzz_sound; } l->oldvalue = l->curvalue; l->curvalue++; if (l->curvalue >= l->top + l->columns * l->height) { if (l->columns == 1) { l->top++; } else { l->top += l->height; } } if (l->generic.callback) { l->generic.callback(l, QM_GOTFOCUS); } return menu_move_sound; case K_KP_LEFTARROW: case K_LEFTARROW: if (l->columns == 1) { return menu_null_sound; } if (l->curvalue < l->height) { return menu_buzz_sound; } l->oldvalue = l->curvalue; l->curvalue -= l->height; if (l->curvalue < l->top) { l->top -= l->height; } if (l->generic.callback) { l->generic.callback(l, QM_GOTFOCUS); } return menu_move_sound; case K_KP_RIGHTARROW: case K_RIGHTARROW: if (l->columns == 1) { return menu_null_sound; } c = l->curvalue + l->height; if (c >= l->numitems) { return menu_buzz_sound; } l->oldvalue = l->curvalue; l->curvalue = c; if (l->curvalue > l->top + l->columns * l->height - 1) { l->top += l->height; } if (l->generic.callback) { l->generic.callback(l, QM_GOTFOCUS); } return menu_move_sound; } // cycle look for ascii key inside list items if (!Q_isprint(key)) { return 0; } // force to lower for case insensitive compare if (Q_isupper(key)) { key -= 'A' - 'a'; } // iterate list items for (i=1; i<=l->numitems; i++) { j = (l->curvalue + i) % l->numitems; c = l->itemnames[j][0]; if (Q_isupper(c)) { c -= 'A' - 'a'; } if (c == key) { // set current item, mimic windows listbox scroll behavior if (j < l->top) { // behind top most item, set this as new top l->top = j; } else if (j > l->top+l->height-1) { // past end of list box, do page down l->top = (j+1) - l->height; } if (l->curvalue != j) { l->oldvalue = l->curvalue; l->curvalue = j; if (l->generic.callback) l->generic.callback(l, QM_GOTFOCUS); return (menu_move_sound); } return (menu_buzz_sound); } } return (menu_buzz_sound); }
/* ================== Info_Validate Some characters are illegal in info strings because they can mess up the server's parsing. Also checks the length of keys/values and the whole string. ================== */ qboolean Info_Validate( const char *s ) { size_t len, total; int c; total = 0; while( 1 ) { // // validate key // if( *s == '\\' ) { s++; if( ++total == MAX_INFO_STRING ) { return qfalse; // oversize infostring } } if( !*s ) { return qfalse; // missing key } len = 0; while( *s != '\\' ) { c = *s++; if( !Q_isprint( c ) || c == '\"' || c == ';' ) { return qfalse; // illegal characters } if( ++len == MAX_INFO_KEY ) { return qfalse; // oversize key } if( ++total == MAX_INFO_STRING ) { return qfalse; // oversize infostring } if( !*s ) { return qfalse; // missing value } } // // validate value // s++; if( ++total == MAX_INFO_STRING ) { return qfalse; // oversize infostring } if( !*s ) { return qfalse; // missing value } len = 0; while( *s != '\\' ) { c = *s++; if( !Q_isprint( c ) || c == '\"' || c == ';' ) { return qfalse; // illegal characters } if( ++len == MAX_INFO_VALUE ) { return qfalse; // oversize value } if( ++total == MAX_INFO_STRING ) { return qfalse; // oversize infostring } if( !*s ) { return qtrue; // end of string } } } return qfalse; // quiet compiler warning }