static int keyboard_notifier_call()

in speakup/main.c [2212:2280]


static int keyboard_notifier_call(struct notifier_block *nb,
				  unsigned long code, void *_param)
{
	struct keyboard_notifier_param *param = _param;
	struct vc_data *vc = param->vc;
	int up = !param->down;
	int ret = NOTIFY_OK;
	static int keycode;	/* to hold the current keycode */

	in_keyboard_notifier = 1;

	if (vc->vc_mode == KD_GRAPHICS)
		goto out;

	/*
	 * First, determine whether we are handling a fake keypress on
	 * the current processor.  If we are, then return NOTIFY_OK,
	 * to pass the keystroke up the chain.  This prevents us from
	 * trying to take the Speakup lock while it is held by the
	 * processor on which the simulated keystroke was generated.
	 * Also, the simulated keystrokes should be ignored by Speakup.
	 */

	if (speakup_fake_key_pressed())
		goto out;

	switch (code) {
	case KBD_KEYCODE:
		/* speakup requires keycode and keysym currently */
		keycode = param->value;
		break;
	case KBD_UNBOUND_KEYCODE:
		/* not used yet */
		break;
	case KBD_UNICODE:
		/* not used yet */
		break;
	case KBD_KEYSYM:
		if (speakup_key(vc, param->shift, keycode, param->value, up))
			ret = NOTIFY_STOP;
		else if (KTYP(param->value) == KT_CUR)
			ret = pre_handle_cursor(vc, KVAL(param->value), up);
		break;
	case KBD_POST_KEYSYM:{
			unsigned char type = KTYP(param->value) - 0xf0;
			unsigned char val = KVAL(param->value);

			switch (type) {
			case KT_SHIFT:
				do_handle_shift(vc, val, up);
				break;
			case KT_LATIN:
			case KT_LETTER:
				do_handle_latin(vc, val, up);
				break;
			case KT_CUR:
				do_handle_cursor(vc, val, up);
				break;
			case KT_SPEC:
				do_handle_spec(vc, val, up);
				break;
			}
			break;
		}
	}
out:
	in_keyboard_notifier = 0;
	return ret;
}