Exemple #1
0
static bool
parse_variable_assignment(const char *line, int ctxt)
{
	const char *arg;
	char *res1 = NULL, *res2 = NULL;
#define VAR_INVALID	-1
#define VAR_NORMAL	0
#define VAR_SUBST	1
#define VAR_APPEND	2
#define VAR_SHELL	4
#define VAR_OPT		8
	int type;
	struct Name name;

	arg = VarName_Get(line, &name, NULL, true,
	    FEATURES(FEATURE_SUNSHCMD) ? find_op1 : find_op2);

	while (isspace(*arg))
		arg++;

	type = VAR_NORMAL;

	while (*arg != '=') {
		/* Check operator type.  */
		switch (*arg++) {
		case '+':
			if (type & (VAR_OPT|VAR_APPEND))
				type = VAR_INVALID;
			else
				type |= VAR_APPEND;
			break;

		case '?':
			if (type & (VAR_OPT|VAR_APPEND))
				type = VAR_INVALID;
			else
				type |= VAR_OPT;
			break;

		case ':':
			if (FEATURES(FEATURE_SUNSHCMD) &&
			    strncmp(arg, "sh", 2) == 0) {
				type = VAR_SHELL;
				arg += 2;
				while (*arg != '=' && *arg != '\0')
					arg++;
			} else {
				if (type & VAR_SUBST)
					type = VAR_INVALID;
				else
					type |= VAR_SUBST;
			}
			break;

		case '!':
			if (type & VAR_SHELL)
				type = VAR_INVALID;
			else
				type |= VAR_SHELL;
			break;

		default:
			type = VAR_INVALID;
			break;
		}
		if (type == VAR_INVALID) {
			VarName_Free(&name);
			return false;
		}
	}

	arg++;
	while (isspace(*arg))
		arg++;
	/* If the variable already has a value, we don't do anything.  */
	if ((type & VAR_OPT) && Var_Definedi(name.s, name.e)) {
		VarName_Free(&name);
		return true;
	}
	if (type & VAR_SHELL) {
		char *err;

		if (strchr(arg, '$') != NULL) {
			char *sub;
			/* There's a dollar sign in the command, so perform
			 * variable expansion on the whole thing. */
			sub = Var_Subst(arg, NULL, true);
			res1 = Cmd_Exec(sub, &err);
			free(sub);
		} else
			res1 = Cmd_Exec(arg, &err);

		if (err)
			Parse_Error(PARSE_WARNING, err, arg);
		arg = res1;
	}
	if (type & VAR_SUBST) {
		/*
		 * Allow variables in the old value to be undefined, but leave
		 * their invocation alone -- this is done by forcing
		 * errorIsOkay to be false.
		 * XXX: This can cause recursive variables, but that's not
		 * hard to do, and this allows someone to do something like
		 *
		 *  CFLAGS = $(.INCLUDES)
		 *  CFLAGS := -I.. $(CFLAGS)
		 *
		 * And not get an error.
		 */
		bool   saved = errorIsOkay;

		errorIsOkay = false;
		/* ensure the variable is set to something to avoid `variable
		 * is recursive' errors.  */
		if (!Var_Definedi(name.s, name.e))
			Var_Seti_with_ctxt(name.s, name.e, "", ctxt);

		res2 = Var_Subst(arg, NULL, false);
		errorIsOkay = saved;

		arg = res2;
	}

	if (type & VAR_APPEND)
		Var_Appendi_with_ctxt(name.s, name.e, arg, ctxt);
	else
		Var_Seti_with_ctxt(name.s, name.e, arg, ctxt);

	VarName_Free(&name);
	free(res2);
	free(res1);
	return true;
}
int HandleEvent(SDL_Event *event)
{
	static int buttonStates[MAX_BUTTONS] = { 0 };
	int lastx=0, lasty=0;
	bool mouseEvent = false;
	int done, rawkey, key, unicode;

	done = 0;
	switch( event->type ) {
	    case SDL_ACTIVEEVENT:
			/* See what happened */
			printf( "app %s ", event->active.gain ? "gained" : "lost" );
			if ( event->active.state & SDL_APPACTIVE ) 
			{
				printf( "active " );
				/*
				if (event->active.gain)
					Cvar_SetVarValue(&gfx, 1);
				else
					Cvar_SetVarValue(&gfx, 0);
				*/
			} 
			else if ( event->active.state & SDL_APPMOUSEFOCUS ) {
				printf( "mouse " );
				hasMouseFocus = event->active.gain;
			} else if ( event->active.state & SDL_APPINPUTFOCUS ) {
				printf( "input " );
				hasMouseFocus = event->active.gain;
			}
			printf( "focus\n" );
			
			if( !event->active.gain && GL_SDL_IsFullScreen()) {
				SDL_WM_IconifyWindow();
			}
			
			break;

	    case SDL_KEYDOWN:
	    case SDL_KEYUP:
			/*if ( (event->key.keysym.unicode & 0xFF80) == 0 )
				key = event->key.keysym.unicode & 0x7F;
			else
				//international keyboard, try using the keysym
			*/
			key = event->key.keysym.sym;
			if (event->key.keysym.unicode)
				unicode = event->key.keysym.unicode & 0x7F;
			else
				unicode = key;
			rawkey = key;
			
			switch (key)
			{
				case SDLK_LSHIFT:
				case SDLK_RSHIFT:
				  			key = KEY_SHIFT;
				  			break;
				case SDLK_LCTRL:
				case SDLK_RCTRL:
				  			key = KEY_CTRL;
				  			break;
				case SDLK_LALT:
				case SDLK_RALT:
				  			key = KEY_ALT;
				  			break;
				case SDLK_ESCAPE:
							key = KEY_ESCAPE;
							break;
				case SDLK_BACKSPACE:
							key = KEY_BACKSPACE;
							break;
				case SDLK_PAUSE:
							key = KEY_PAUSE;
							break;
				case SDLK_PRINT:
							key = KEY_PRINT;
							break;
				case SDLK_HOME:
							key = KEY_HOME;
							break;
				case SDLK_END:
							key = KEY_END;
							break;
				case SDLK_DELETE:
							key = KEY_DEL;
							break;
				case SDLK_INSERT:
							key = KEY_INS;
							break;
				case SDLK_PAGEUP:
							key = KEY_PGUP;
							break;
				case SDLK_PAGEDOWN:
							key = KEY_PGDN;
							break;
				case SDLK_UP:
				  			key = KEY_UP;
				  			break;
				case SDLK_DOWN:
				  			key = KEY_DOWN;
				  			break;
				case SDLK_LEFT:
				  			key = KEY_LEFT;
				  			break;
				case SDLK_RIGHT:
				  			key = KEY_RIGHT;
				  			break;
				case SDLK_KP0:
				case SDLK_KP1:
				case SDLK_KP2:
				case SDLK_KP3:
				case SDLK_KP4:
				case SDLK_KP5:
				case SDLK_KP6:
				case SDLK_KP7:
				case SDLK_KP8:
				case SDLK_KP9:
							key = KEY_KEYPAD_0 + key - SDLK_KP0;
							break;
				case SDLK_KP_PERIOD:
							key = KEY_KEYPAD_DECIMAL;
							break;
				case SDLK_KP_DIVIDE:
							key = KEY_KEYPAD_SLASH;
							break;
				case SDLK_KP_MULTIPLY:
							key = KEY_KEYPAD_ASTERISK;
							break;
				case SDLK_KP_MINUS:
							key = KEY_KEYPAD_MINUS;
							break;
				case SDLK_KP_PLUS:
							key = KEY_KEYPAD_PLUS;
							break;
				case SDLK_KP_ENTER:
							key = KEY_KEYPAD_ENTER;
							break;
				case SDLK_LSUPER:
							key = KEY_LEFT_WINDOWS;
							break;
				case SDLK_RSUPER:
							key = KEY_RIGHT_WINDOWS;
							break;
				case SDLK_MENU:
							key = KEY_MENU;
							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_F13:
				case SDLK_F14:
				case SDLK_F15:
							key = KEY_F1 + key - SDLK_F1;
							break;
				case 132:
							key = KEY_ALT;
							break;
			}
			if (key != rawkey) //we modified the value
				unicode = key;

			//FIXME
			/*if (sys_showKeycodes.integer)
				Console_Printf("key %i (%s) (unicode %i [%s]) %s\n", key, SDL_GetKeyName(key), unicode, SDL_GetKeyName(unicode), event->type == SDL_KEYDOWN ? "pressed" : "released");*/

			if (event->type == SDL_KEYDOWN)
			{
				//alt-enter hack
				if (key == KEY_ENTER && keyDown == KEY_ALT)
				{
					Cmd_Exec("toggle vid_fullscreen; changevideo");
				}
				//alt-tab hack
				if (key == KEY_TAB && keyDown == KEY_ALT)
				{
					SDL_WM_IconifyWindow();
				}
					
				//Console_DPrintf("key %i pressed\n", key);
				keyDown = key;
				keyDownTime = System_Milliseconds();
			}
			else
			{
				if (keyDown == key)
				{
					//Console_DPrintf("key %i released\n", key);
					keyDown = -1;
				}
			}

			//printf("button %c %s\n", key, event->key.state ? "pressed" : "unpressed");
			Input_Event(key, unicode, event->key.state);
			done = 1;
			break;
		case SDL_MOUSEBUTTONDOWN:
		case SDL_MOUSEBUTTONUP:
			//fprintf(stderr, "mouse button event!  button %d is %d\n", event->button.button, event->button.state);
			if (((event->button.state && !buttonDownThisFrame[event->button.button]) 
				|| (!event->button.state && !buttonUpThisFrame[event->button.button]))
				&& event->button.state != buttonStates[event->button.button])
			{
				if (event->button.state)
					buttonDownThisFrame[event->button.button] = true;
				else
					buttonUpThisFrame[event->button.button] = true;
				buttonStates[event->button.button] = event->button.state;
				switch(event->button.button)
				{
					case SDL_BUTTON_LEFT:
						Input_Event(KEY_LBUTTON, 0, event->button.state);
						done = 1;
						break;
					case SDL_BUTTON_RIGHT:
						Input_Event(KEY_RBUTTON, 0, event->button.state);
						done = 1;
						break;
					case SDL_BUTTON_MIDDLE:
						Input_Event(KEY_MBUTTON, 0, event->button.state);
						done = 1;
						break;
					case SDL_BUTTON_WHEELUP:
						Input_Event(KEY_MWHEELUP, 0, event->button.state);
						done = 1;
						break;
					case SDL_BUTTON_WHEELDOWN:
						Input_Event(KEY_MWHEELDOWN, 0, event->button.state);
						done = 1;
						break;
					/*case SDL_BUTTON_X1:
						Input_Event(KEY_XBUTTON1, 0, event->button.state);
						done = 1;
						break;
					case SDL_BUTTON_X2:
						Input_Event(KEY_XBUTTON2, 0, event->button.state);
						done = 1;
						break;*/
					default:
						Console_DPrintf("unknown button %d\n", event->button.button);
						break;
				}
			}
			break;
		case SDL_MOUSEMOTION:
		{
			mouseEvent=true;
			lastx = event->motion.x;
			lasty = event->motion.y;
			//if(y != Vid_GetScreenH()>>1 && x != Vid_GetScreenW()>>1) {
				if (inverty.integer)
					lasty = Vid_GetScreenH() - lasty;
				//fprintf(stderr, "mouse motion event!  now (%d, %d)\n", event->motion.x, event->motion.y);
			
			//}
		}break;
		case SDL_VIDEORESIZE:
			if (vid_mode.integer == -2)
			{
				silent_vid_mode_change = true;
				Cvar_SetValue("vid_mode0_width", event->resize.w);
				Cvar_SetValue("vid_mode0_height", event->resize.h);
				Cmd_Exec("changevideo");
				silent_vid_mode_change = false;
			}
		    done = 1;
			break;
	    case SDL_QUIT:
			System_Quit();
			done = 1;
		break;
	}
	
	if(mouseEvent)
		Input_UpdateMouse(lastx, lasty);
	
	return(done);
}