Пример #1
0
static __inline void process_key_pressed(uint64_t timestamp, KBDLLHOOKSTRUCT *kbhook) {
	// Check and setup modifiers.
	if		(kbhook->vkCode == VK_LSHIFT)	{ set_modifier_mask(MASK_SHIFT_L);	}
	else if (kbhook->vkCode == VK_RSHIFT)	{ set_modifier_mask(MASK_SHIFT_R);	}
	else if (kbhook->vkCode == VK_LCONTROL)	{ set_modifier_mask(MASK_CTRL_L);	}
	else if (kbhook->vkCode == VK_RCONTROL)	{ set_modifier_mask(MASK_CTRL_R);	}
	else if (kbhook->vkCode == VK_LMENU)	{ set_modifier_mask(MASK_ALT_L);	}
	else if (kbhook->vkCode == VK_RMENU)	{ set_modifier_mask(MASK_ALT_R);	}
	else if (kbhook->vkCode == VK_LWIN)		{ set_modifier_mask(MASK_META_L);	}
	else if (kbhook->vkCode == VK_RWIN)		{ set_modifier_mask(MASK_META_R);	}

	
	// Populate key pressed event.
	event.time = timestamp;
	event.reserved = 0x00;

	event.type = EVENT_KEY_PRESSED;
	event.mask = get_modifiers();

	event.data.keyboard.keycode = keycode_to_scancode(kbhook->vkCode);
	event.data.keyboard.rawcode = kbhook->vkCode;
	event.data.keyboard.keychar = CHAR_UNDEFINED;

	logger(LOG_LEVEL_INFO, "%s [%u]: Key %#X pressed. (%#X)\n",
		__FUNCTION__, __LINE__, event.data.keyboard.keycode, event.data.keyboard.rawcode);
	if (wants_to_hook_event(EVENT_KEY_PRESSED)){
		// Populate key pressed event.
		dispatch_event(&event);
	}

	if (!wants_to_hook_event(EVENT_KEY_TYPED))
		return;

	// If the pressed event was not consumed...
	if (event.reserved ^ 0x01) {
		// Buffer for unicode typed chars. No more than 2 needed.
		WCHAR buffer[2]; // = { WCH_NONE };

		// If the pressed event was not consumed and a unicode char exists...
		SIZE_T count = keycode_to_unicode(kbhook->vkCode, buffer, sizeof(buffer));
		for (unsigned int i = 0; i < count; i++) {
			// Populate key typed event.
			event.time = timestamp;
			event.reserved = 0x00;

			event.type = EVENT_KEY_TYPED;
			event.mask = get_modifiers();

			event.data.keyboard.keycode = keycode_to_scancode(kbhook->vkCode);
			event.data.keyboard.rawcode = kbhook->vkCode;
			event.data.keyboard.keychar = buffer[i];

			logger(LOG_LEVEL_INFO, "%s [%u]: Key %#X typed. (%lc)\n",
					__FUNCTION__, __LINE__, event.data.keyboard.keycode, (wint_t) event.data.keyboard.keychar);

			// Fire key typed event.
			dispatch_event(&event);
		}
	}
}
Пример #2
0
static __inline void process_button_released(uint64_t timestamp, MSLLHOOKSTRUCT *mshook, uint16_t button) {

	if (wants_to_hook_event(EVENT_MOUSE_RELEASED)){
		// Populate mouse released event.
		event.time = timestamp;
		event.reserved = 0x00;

		event.type = EVENT_MOUSE_RELEASED;
		event.mask = get_modifiers();

		event.data.mouse.button = button;
		event.data.mouse.clicks = click_count;

		event.data.mouse.x = mshook->pt.x;
		event.data.mouse.y = mshook->pt.y;

		logger(LOG_LEVEL_INFO, "%s [%u]: Button %u released %u time(s). (%u, %u)\n",
			__FUNCTION__, __LINE__, event.data.mouse.button,
			event.data.mouse.clicks,
			event.data.mouse.x, event.data.mouse.y);

		// Fire mouse released event.
		dispatch_event(&event);
	}

	if (!wants_to_hook_event(EVENT_MOUSE_CLICKED))
		return;

	// If the pressed event was not consumed...
	if (event.reserved ^ 0x01
			&& last_click.x == mshook->pt.x && last_click.y == mshook->pt.y) {
		// Populate mouse clicked event.
		event.time = timestamp;
		event.reserved = 0x00;

		event.type = EVENT_MOUSE_CLICKED;
		event.mask = get_modifiers();

		event.data.mouse.button = button;
		event.data.mouse.clicks = click_count;
		event.data.mouse.x = mshook->pt.x;
		event.data.mouse.y = mshook->pt.y;

		logger(LOG_LEVEL_INFO, "%s [%u]: Button %u clicked %u time(s). (%u, %u)\n",
				__FUNCTION__, __LINE__, event.data.mouse.button, event.data.mouse.clicks,
				event.data.mouse.x, event.data.mouse.y);

		// Fire mouse clicked event.
		dispatch_event(&event);
	}
}
Пример #3
0
static void process_button_released(MSLLHOOKSTRUCT *mshook, uint16_t button) {
	// Populate mouse released event.
	event.time = GetMessageTime();
	event.reserved = 0x00;

	event.type = EVENT_MOUSE_RELEASED;
	event.mask = get_modifiers();

	event.data.mouse.button = button;
	event.data.mouse.clicks = click_count;

	event.data.mouse.x = mshook->pt.x;
	event.data.mouse.y = mshook->pt.y;

	logger(LOG_LEVEL_INFO, "%s [%u]: Button %u released %u time(s). (%u, %u)\n",
			__FUNCTION__, __LINE__, event.data.mouse.button,
			event.data.mouse.clicks,
			event.data.mouse.x, event.data.mouse.y);

	// Fire mouse released event.
	dispatch_event(&event);

	// If the pressed event was not consumed...
	if (event.reserved ^ 0x01 && last_click.x == mshook->pt.x && last_click.y == mshook->pt.y) {
		// Populate mouse clicked event.
		event.time = GetMessageTime();
		event.reserved = 0x00;

		event.type = EVENT_MOUSE_CLICKED;
		event.mask = get_modifiers();

		event.data.mouse.button = button;
		event.data.mouse.clicks = click_count;
		event.data.mouse.x = mshook->pt.x;
		event.data.mouse.y = mshook->pt.y;

		logger(LOG_LEVEL_INFO, "%s [%u]: Button %u clicked %u time(s). (%u, %u)\n",
				__FUNCTION__, __LINE__, event.data.mouse.button, event.data.mouse.clicks,
				event.data.mouse.x, event.data.mouse.y);

		// Fire mouse clicked event.
		dispatch_event(&event);
	}

	// Reset the number of clicks.
	if (button == click_button && (long int) (event.time - click_time) > hook_get_multi_click_time()) {
		// Reset the click count.
		click_count = 0;
	}
}
Пример #4
0
static void process_key_released(KBDLLHOOKSTRUCT *kbhook) {
	// Check and setup modifiers.
	if		(kbhook->vkCode == VK_LSHIFT)	{ unset_modifier_mask(MASK_SHIFT_L);		}
	else if (kbhook->vkCode == VK_RSHIFT)	{ unset_modifier_mask(MASK_SHIFT_R);		}
	else if (kbhook->vkCode == VK_LCONTROL)	{ unset_modifier_mask(MASK_CTRL_L);			}
	else if (kbhook->vkCode == VK_RCONTROL)	{ unset_modifier_mask(MASK_CTRL_R);			}
	else if (kbhook->vkCode == VK_LMENU)	{ unset_modifier_mask(MASK_ALT_L);			}
	else if (kbhook->vkCode == VK_RMENU)	{ unset_modifier_mask(MASK_ALT_R);			}
	else if (kbhook->vkCode == VK_LWIN)		{ unset_modifier_mask(MASK_META_L);			}
	else if (kbhook->vkCode == VK_RWIN)		{ unset_modifier_mask(MASK_META_R);			}
	else if (kbhook->vkCode == VK_NUMLOCK)	{ unset_modifier_mask(MASK_NUM_LOCK);		}
	else if (kbhook->vkCode == VK_CAPITAL)	{ unset_modifier_mask(MASK_CAPS_LOCK);		}
	else if (kbhook->vkCode == VK_SCROLL)	{ unset_modifier_mask(MASK_SCROLL_LOCK);	}

	// Populate key pressed event.
	event.time = kbhook->time;
	event.reserved = 0x00;

	event.type = EVENT_KEY_RELEASED;
	event.mask = get_modifiers();

	event.data.keyboard.keycode = keycode_to_scancode(kbhook->vkCode, kbhook->flags);
	event.data.keyboard.rawcode = kbhook->vkCode;
	event.data.keyboard.keychar = CHAR_UNDEFINED;

	logger(LOG_LEVEL_INFO,	"%s [%u]: Key %#X released. (%#X)\n",
			__FUNCTION__, __LINE__, event.data.keyboard.keycode, event.data.keyboard.rawcode);

	// Fire key released event.
	dispatch_event(&event);
}
Пример #5
0
void parse_result_modifiers(char *line, InstructionModifiers *modifiers) {
	char *p = strchr(line, '|');
	int i = 0;
	char param[128];
	char func[64];
	char args[64];
	memset(&param,0,sizeof(param));
	if(p != NULL) {
		*p = 0;
		p++;
		while(true) {
			find_nth(p, i++, param, sizeof(param));
			memset(&func,0,sizeof(func));
			memset(&args,0,sizeof(args));
			if(strlen(param) == 0) break;
			char *x = strchr(param, '(');
			if(x == NULL) break;
			char *x1 = strchr(x,')');
			strncpy(func,param,x-param);
			strncpy(args,x+1,x1-x-1);
			get_modifiers((char *)&func, (char *)&args, modifiers);
			//printf("%s %s\n",func, args);
		}		
	}
}
Пример #6
0
static __inline void process_key_released(uint64_t timestamp, KBDLLHOOKSTRUCT *kbhook) {
	// Check and setup modifiers.
	if		(kbhook->vkCode == VK_LSHIFT)	{ unset_modifier_mask(MASK_SHIFT_L);	}
	else if (kbhook->vkCode == VK_RSHIFT)	{ unset_modifier_mask(MASK_SHIFT_R);	}
	else if (kbhook->vkCode == VK_LCONTROL)	{ unset_modifier_mask(MASK_CTRL_L);		}
	else if (kbhook->vkCode == VK_RCONTROL)	{ unset_modifier_mask(MASK_CTRL_R);		}
	else if (kbhook->vkCode == VK_LMENU)	{ unset_modifier_mask(MASK_ALT_L);		}
	else if (kbhook->vkCode == VK_RMENU)	{ unset_modifier_mask(MASK_ALT_R);		}
	else if (kbhook->vkCode == VK_LWIN)		{ unset_modifier_mask(MASK_META_L);		}
	else if (kbhook->vkCode == VK_RWIN)		{ unset_modifier_mask(MASK_META_R);		}

	if (!wants_to_hook_event(EVENT_KEY_RELEASED))
		return;

	// Populate key released event.
	event.time = timestamp;
	event.reserved = 0x00;

	event.type = EVENT_KEY_RELEASED;
	event.mask = get_modifiers();

	event.data.keyboard.keycode = keycode_to_scancode(kbhook->vkCode);
	event.data.keyboard.rawcode = kbhook->vkCode;
	event.data.keyboard.keychar = CHAR_UNDEFINED;

	logger(LOG_LEVEL_INFO,	"%s [%u]: Key %#X released. (%#X)\n",
			__FUNCTION__, __LINE__, event.data.keyboard.keycode, event.data.keyboard.rawcode);

	// Fire key released event.
	dispatch_event(&event);
}
Пример #7
0
static inline void process_mouse_wheel(uint64_t timestamp, MSLLHOOKSTRUCT *mshook) {
	// Track the number of clicks.
	// Reset the click count and previous button.
	click_count = 1;
	click_button = MOUSE_NOBUTTON;

	// Populate mouse wheel event.
	event.time = timestamp;
	event.reserved = 0x00;

	event.type = EVENT_MOUSE_WHEEL;
	event.mask = get_modifiers();

	event.data.wheel.clicks = click_count;
	event.data.wheel.x = mshook->pt.x;
	event.data.wheel.y = mshook->pt.y;

	event.data.wheel.type = get_scroll_wheel_type();
	event.data.wheel.amount = get_scroll_wheel_amount();

	/* Delta HIWORD(mshook->mouseData)
	 * A positive value indicates that the wheel was rotated
	 * forward, away from the user; a negative value indicates that
	 * the wheel was rotated backward, toward the user. One wheel
	 * click is defined as WHEEL_DELTA, which is 120. */
	event.data.wheel.rotation = ((int16_t) HIWORD(mshook->mouseData) / WHEEL_DELTA) * -1;

	logger(LOG_LEVEL_INFO, "%s [%u]: Mouse wheel type %u, rotated %i units at %u, %u.\n",
			__FUNCTION__, __LINE__, event.data.wheel.type, event.data.wheel.amount *
			event.data.wheel.rotation, event.data.wheel.x, event.data.wheel.y);

	// Fire mouse wheel event.
	dispatch_event(&event);
}
Пример #8
0
static void set_property_info(Array &ret, ClassInfo::PropertyInfo *info,
                              const ClassInfo *cls) {
  ret.set("name", info->name);
  set_access(ret, info->attribute);
  ret.set("modifiers", get_modifiers(info->attribute, false));
  ret.set("static", (bool)(info->attribute & ClassInfo::IsStatic));
  ret.set("class", cls->getName());
  set_doc_comment(ret, info->docComment);
}
Пример #9
0
void GlutViewer::glut_keyboard(unsigned char key, int x, int y)
{
  get_modifiers();
  if (self->keyPress(key, x, y)) glutPostRedisplay();

  if (self->quitProgram)
  {
    exit(0);
  }
}
Пример #10
0
static void set_method_info(Array &ret, ClassInfo::MethodInfo *info,
                            const ClassInfo *cls) {
  ret.set("name", info->name);
  set_access(ret, info->attribute);
  ret.set("modifiers", get_modifiers(info->attribute, false));
  ret.set("static",   (bool)(info->attribute & ClassInfo::IsStatic));
  ret.set("final",    (bool)(info->attribute & ClassInfo::IsFinal));
  ret.set("abstract", (bool)(info->attribute & ClassInfo::IsAbstract));
  ret.set("internal", (bool)(cls->getAttribute() & ClassInfo::IsSystem));
  ret.set("class", cls->getName());
  set_function_info(ret, info, cls->getName());
}
Пример #11
0
static __inline void process_button_pressed(uint64_t timestamp, MSLLHOOKSTRUCT *mshook, uint16_t button) {
	if (!wants_to_hook_event(EVENT_MOUSE_PRESSED))
		return;
	// Track the number of clicks, the button must match the previous button.
	if (button == click_button && (long int) (timestamp - click_time) <= hook_get_multi_click_time()) {
		if (click_count < USHRT_MAX) {
			click_count++;
		}
		else {
			logger(LOG_LEVEL_WARN, "%s [%u]: Click count overflow detected!\n",
					__FUNCTION__, __LINE__);
		}
	}
	else {
		// Reset the click count.
		click_count = 1;

		// Set the previous button.
		click_button = button;
	}

	// Save this events time to calculate the click_count.
	click_time = timestamp;

	// Store the last click point.
	last_click.x = mshook->pt.x;
	last_click.y = mshook->pt.y;

	// Populate mouse pressed event.
	event.time = timestamp;
	event.reserved = 0x00;

	event.type = EVENT_MOUSE_PRESSED;
	event.mask = get_modifiers();

	event.data.mouse.button = button;
	event.data.mouse.clicks = click_count;

	event.data.mouse.x = mshook->pt.x;
	event.data.mouse.y = mshook->pt.y;

	logger(LOG_LEVEL_INFO, "%s [%u]: Button %u  pressed %u time(s). (%u, %u)\n",
			__FUNCTION__, __LINE__, event.data.mouse.button, event.data.mouse.clicks,
			event.data.mouse.x, event.data.mouse.y);

	// Fire mouse pressed event.
	dispatch_event(&event);
}
Пример #12
0
void input_manager::check_touch_bindings(int x, int y)
{
    uint32_t mods = get_modifiers();
    std::vector<touch_callback*> calls;
    for (auto& binding : bindings[WF_BINDING_TOUCH])
    {
        if (binding->value->as_cached_key().matches({mods, 0}) &&
            binding->output == core->get_active_output())
        {
            calls.push_back(binding->call.touch);
        }
    }

    for (auto call : calls)
        (*call)(x, y);
}
Пример #13
0
static int
drm_atomic_get_modifiers(struct drm *drm)
{
	unsigned int i, j, format_index = 0;

	for (i = 0; i < drm->plane->plane->count_formats; i++) {
		if (drm->plane->plane->formats[i] == DRM_FORMAT_XRGB8888)
			format_index = i;
	}

	for (i = 0; i < drm->plane->props->count_props; i++) {
		if (!strcmp(drm->plane->props_info[i]->name, "IN_FORMATS")) {
			struct drm_format_modifier *mods;
			drmModePropertyBlobPtr blob;
			unsigned int count;

			blob = drmModeGetPropertyBlob(drm->fd,
						      drm->plane->props->prop_values[i]);
			if (!blob) {
				printf("failed to get blob for property %s\n",
				       drm->plane->props_info[i]->name);
				return -ENOMEM;
			}

			count = get_modifiers(blob, &mods);

			for (j = 0; j < count; j++) {
				if (mods[j].formats & (1ULL << format_index))
					drm->num_modifiers++;
			}

			drm->modifiers = calloc(drm->num_modifiers,
					        sizeof(uint64_t));
			if (!drm->modifiers) {
				printf("failed to allocate modifiers\n");
				return -ENOMEM;
			}

			for (j = 0; j < count; j++) {
				if (mods[j].formats & (1ULL << format_index))
					drm->modifiers[j] = mods[j].modifier;
			}
		}
	}

	return 0;
}
Пример #14
0
void GlutViewer::glut_mouseclick(int btn, int state, int x, int y)
{
  get_modifiers();
  MouseButton button = MouseButton(btn+1);
  if (state == 0)
  {
    // XOR state of three mouse buttons to the mouseState variable
    if (button <= RightButton) self->mouseState ^= (int)pow(2,button+1);
    self->mousePress(button, true, x, y);
  }
  else
  {
    // Release
    self->mouseState = 0;
    self->mousePress(button, false, x, y);
  }
  glutPostRedisplay();
}
Пример #15
0
static __inline void process_mouse_moved(uint64_t timestamp, MSLLHOOKSTRUCT *mshook) {
	// Reset the click count.
	if (click_count != 0 && (long) (event.time - click_time) > hook_get_multi_click_time()) {
		click_count = 0;
	}

	// We received a mouse move event with the mouse actually moving.
	// This verifies that the mouse was moved after being depressed.
	if (last_click.x != mshook->pt.x || last_click.y != mshook->pt.y) {
		// Populate mouse move event.
		event.time = timestamp;
		event.reserved = 0x00;

		event.mask = get_modifiers();

		// Check the modifier mask range for MASK_BUTTON1 - 5.
		bool mouse_dragged = event.mask & (MASK_BUTTON1 | MASK_BUTTON2 | MASK_BUTTON3 | MASK_BUTTON4 | MASK_BUTTON5);
		if (mouse_dragged) {
			// Create Mouse Dragged event.
			event.type = EVENT_MOUSE_DRAGGED;
		}
		else {
			// Create a Mouse Moved event.
			event.type = EVENT_MOUSE_MOVED;
		}

		if (!wants_to_hook_event(event.type))
			return;

		event.data.mouse.button = MOUSE_NOBUTTON;
		event.data.mouse.clicks = click_count;
		event.data.mouse.x = mshook->pt.x;
		event.data.mouse.y = mshook->pt.y;

		logger(LOG_LEVEL_INFO, "%s [%u]: Mouse %s to %u, %u.\n",
				__FUNCTION__, __LINE__,  mouse_dragged ? "dragged" : "moved",
				event.data.mouse.x, event.data.mouse.y);

		// Fire mouse move event.
		dispatch_event(&event);
	}
}
Пример #16
0
void GlutViewer::glut_keyboard_ext(int code, int x, int y)
{
  unsigned char key;
  get_modifiers();
  switch (code)
  {
  case GLUT_KEY_LEFT:
    key = KEY_LEFT;
    break;
  case GLUT_KEY_RIGHT:
    key = KEY_RIGHT;
    break;
  case GLUT_KEY_DOWN:
    key = KEY_DOWN;
    break;
  case GLUT_KEY_UP:
    key = KEY_UP;
    break;
  case GLUT_KEY_PAGE_UP:
    key = KEY_PAGEUP;
    break;
  case GLUT_KEY_PAGE_DOWN:
    key = KEY_PAGEDOWN;
    break;
  case GLUT_KEY_HOME:
    key = KEY_HOME;
    break;
  case GLUT_KEY_END:
    key = KEY_END;
    break;
  default:
    return;
  }

  if (self->keyPress(key, x, y)) glutPostRedisplay();
}
Пример #17
0
static LRESULT CALLBACK window_procedure(HWND window,
					 UINT message,
					 WPARAM wParam,
					 LPARAM lParam)
{
    static int n_saved_key_events = 0;
    static struct event *saved_key_events[MAX_SAVED_KEY_EVENTS];
    static WPARAM last_dead_character = '\0';
    static int append_character_instead_of_replacing = 0;
    static utf8 character_buffer[13] = { '\0' };
    static int click_button = -1;
    static uint64_t click_start_time = 0;
    static int click_count = 1;
    static struct drawable *mouse_drawable = NULL;

    struct drawable *drawable = NULL;
    for(size_t i = 0; i < n_drawables; i++) {
	if(all_drawables[i]->window == window) {
	    drawable = all_drawables[i];
	    break;
	}
    }
    
    switch(message) {
    case WM_CREATE:
	return 0;
	
    case WM_CLOSE:
	if(drawable) {
	    ef_drawable_delete((EF_Drawable) drawable);
	    PostQuitMessage(0);
	}
	return 0;
	
    case WM_DESTROY:
	return 0;

    case WM_PAINT:
	{
	    PAINTSTRUCT paint;
	    BeginPaint(window, &paint);
	    if(drawable) {
		if(drawable->draw_callback) {
		ef_drawable_make_current((EF_Drawable) drawable);
		drawable->draw_callback((EF_Drawable) drawable,
					drawable->draw_callback_context);
		}
	    }
	    EndPaint(window, &paint);
	    return 0;
	}
	
    case WM_KEYDOWN:
    case WM_SYSKEYDOWN:
	if(!is_modifier_keycode(wParam)) {
	    struct event *event = NULL;
	    for(int i = 0; i < n_saved_key_events; i++) {
		if(saved_key_events[i]->data.key_event.keycode == wParam) {
		    event = saved_key_events[i];
		    break;
		}
	    }

	    if(event) {
		event->timestamp = ef_time_unix_epoch();
		event->modifiers = get_modifiers();
		event->data.key_event.string = NULL;
		event->data.key_event.has_fired_for_key_down = 0;
	    } else {
		event = malloc(sizeof(struct event));
		event->timestamp = ef_time_unix_epoch();
		event->modifiers = get_modifiers();
		event->data.key_event.keycode
		    = (EF_Keycode) wParam;
		    //= (EF_Keycode) MapVirtualKey(wParam, MAPVK_VK_TO_VSC);
		event->data.key_event.string = NULL;
		event->data.key_event.has_fired_for_key_down = 0;
		
		if(n_saved_key_events < MAX_SAVED_KEY_EVENTS) {
		    n_saved_key_events++;
		    saved_key_events[n_saved_key_events-1] = event;
		}
	    }
	    
	    if(is_noncharacter_keycode(wParam)) {
		event->data.key_event.has_fired_for_key_down = 1;
		
		if(drawable && drawable->key_down_callback) {
		    drawable->key_down_callback(drawable,
						(EF_Event) event,
						drawable->key_down_callback_context);
		}
	    }
	}
	if(message == WM_SYSKEYDOWN) {
	    return DefWindowProc(window, message, wParam, lParam);
	} else {
	    return 0;
	}

    case WM_KEYUP:
    case WM_SYSKEYUP:
	{
	    struct event *saved_key_event = NULL;
	    for(int i = 0; i < n_saved_key_events; i++) {
		if(saved_key_events[i]->data.key_event.keycode == wParam) {
		    saved_key_event = saved_key_events[i];
		    break;
		}
	    }
	    
	    if(saved_key_event && drawable && drawable->key_up_callback
	       && !is_modifier_keycode(wParam) && !last_dead_character)
	    {
		saved_key_event->timestamp = ef_time_unix_epoch();
		saved_key_event->data.key_event.string = character_buffer;
		drawable->key_up_callback(drawable,
					  (EF_Event) saved_key_event,
					  drawable->key_up_callback_context);
		
		for(int i = 0; i < n_saved_key_events; i++) {
		    if(saved_key_events[i] == saved_key_event) {
			for(int j = i; j < n_saved_key_events-1; j++)
			    saved_key_events[j] = saved_key_events[j+1];
			n_saved_key_events--;
			break;
		    }
		}
		free(saved_key_event);
	    }
	    
	    if(message == WM_SYSKEYUP) {
		return DefWindowProc(window, message, wParam, lParam);
	    } else {
		return 0;
	    }
	}
	
    case WM_CHAR:
    case WM_SYSCHAR:
	{
	    utf8 *point = character_buffer;
	    if(append_character_instead_of_replacing) {
		while(*point) point++;
	    }
	    utf16 temp16[2];
	    temp16[0] = wParam;
	    temp16[1] = '\0';
	    utf8 *temp8 = utf16_to_utf8(temp16);
	    utf8_cpy(point, temp8);
	    free(temp8);
	}
	
	if(last_dead_character == wParam) {
	    append_character_instead_of_replacing = 1;
	} else {
	    append_character_instead_of_replacing = 0;
	    
	    struct event *saved_key_event = NULL;
	    if(n_saved_key_events) {
		struct event *event = saved_key_events[n_saved_key_events-1];
		if(!event->data.key_event.has_fired_for_key_down)
		    saved_key_event = event;
	    }
	    
	    if(saved_key_event) {
		saved_key_event->data.key_event.has_fired_for_key_down = 1;
		
		if(drawable && drawable->key_down_callback) {
		    saved_key_event->data.key_event.string = character_buffer;
		    drawable->key_down_callback(drawable,
						(EF_Event) saved_key_event,
						drawable->key_down_callback_context);
		}
	    }
	}
	last_dead_character = '\0';
	
	return 0;
	
    case WM_DEADCHAR:
    case WM_SYSDEADCHAR:
	last_dead_character = wParam;
	return 0;

    case WM_LBUTTONDOWN:
    case WM_RBUTTONDOWN:
    case WM_MBUTTONDOWN:
    case WM_XBUTTONDOWN:
	{
	    SetCapture(window);
	    
	    struct event *event = malloc(sizeof(struct event));
	    
	    event->timestamp = ef_time_unix_epoch();
	    event->modifiers = get_modifiers();
	    
	    switch(message) {
	    case WM_LBUTTONDOWN:
		event->data.mouse_event.button_number = 0;
		break;
	    case WM_RBUTTONDOWN:
		event->data.mouse_event.button_number = 1;
		break;
	    case WM_MBUTTONDOWN:
		event->data.mouse_event.button_number = 2;
		break;
	    case WM_XBUTTONDOWN:
		switch((wParam >> 16) & 0xFFFF) {
		case XBUTTON1:
		    event->data.mouse_event.button_number = 3;
		    break;
		case XBUTTON2:
		    event->data.mouse_event.button_number = 4;
		    break;
		default:
		    event->data.mouse_event.button_number = 5;
		    break;
		}
		break;
	    }

	    int starts_a_click;
	    if(click_button == -1) {
		starts_a_click = 1;
		click_button = event->data.mouse_event.button_number;
	    } else {
		starts_a_click = 0;
	    }
	    
	    if(event->timestamp - click_start_time < GetDoubleClickTime())
		click_count++;
	    else
		click_count = 1;
	    click_start_time = event->timestamp;
	    event->data.mouse_event.click_count = click_count;
	    
	    RECT client_rect;
	    GetClientRect(window, &client_rect);

	    event->data.mouse_event.x = (lParam & 0xFFFF);
	    event->data.mouse_event.y = client_rect.bottom - ((lParam >> 16) & 0xFFFF);
	    
	    if(starts_a_click && drawable && drawable->mouse_down_callback) {
		drawable->mouse_down_callback(drawable,
					      (EF_Event) event,
					      drawable->mouse_down_callback_context);
	    }
	    
	    free(event);
	}
	return 0;
	
    case WM_LBUTTONUP:
    case WM_RBUTTONUP:
    case WM_MBUTTONUP:
    case WM_XBUTTONUP:
	{
	    ReleaseCapture();
	    
	    struct event *event = malloc(sizeof(struct event));
	    
	    event->timestamp = ef_time_unix_epoch();
	    event->modifiers = get_modifiers();
	    
	    switch(message) {
	    case WM_LBUTTONUP:
		event->data.mouse_event.button_number = 0;
		break;
	    case WM_RBUTTONUP:
		event->data.mouse_event.button_number = 1;
		break;
	    case WM_MBUTTONUP:
		event->data.mouse_event.button_number = 2;
		break;
	    case WM_XBUTTONUP:
		switch((wParam >> 16) & 0xFFFF) {
		case XBUTTON1:
		    event->data.mouse_event.button_number = 3;
		    break;
		case XBUTTON2:
		    event->data.mouse_event.button_number = 4;
		    break;
		default:
		    event->data.mouse_event.button_number = 5;
		    break;
		}
		break;
	    }
	    
	    int ends_a_click;
	    if(click_button == event->data.mouse_event.button_number) {
		ends_a_click = 1;
		click_button = -1;
	    } else {
		ends_a_click = 0;
	    }
	    
	    event->data.mouse_event.click_count = click_count;
	    
	    RECT client_rect;
	    GetClientRect(window, &client_rect);
	    
	    event->data.mouse_event.x = (lParam & 0xFFFF);
	    event->data.mouse_event.y = client_rect.bottom - ((lParam >> 16) & 0xFFFF);
	    
	    if(ends_a_click && drawable && drawable->mouse_up_callback) {
		drawable->mouse_up_callback(drawable,
					    (EF_Event) event,
					    drawable->mouse_up_callback_context);
	    }
	    
	    free(event);
	}
	return 0;

    case WM_MOUSEMOVE:
	{
	    click_start_time = 0;

	    struct event *event = malloc(sizeof(struct event));
	    
	    event->timestamp = ef_time_unix_epoch();
	    event->modifiers = get_modifiers();
	    event->data.mouse_event.button_number = 0;
	    event->data.mouse_event.click_count = 0;

	    RECT client_rect;
	    GetClientRect(window, &client_rect);
	    
	    event->data.mouse_event.x = (lParam & 0xFFFF);
	    event->data.mouse_event.y = client_rect.bottom - ((lParam >> 16) & 0xFFFF);

	    if(mouse_drawable != drawable) {
		TRACKMOUSEEVENT trackmouseevent;
		trackmouseevent.cbSize = sizeof(trackmouseevent);
		trackmouseevent.dwFlags = TME_LEAVE;
		trackmouseevent.hwndTrack = drawable->window;
		trackmouseevent.dwHoverTime = 0;
		TrackMouseEvent(&trackmouseevent);
		
		if(drawable && drawable->mouse_enter_callback) {
		    drawable->mouse_enter_callback(drawable,
						   (EF_Event) event,
						 drawable->mouse_enter_callback_context);
		}
		
		mouse_drawable = drawable;
	    }
	    
	    if(drawable && drawable->mouse_move_callback) {
		drawable->mouse_move_callback(drawable,
					      (EF_Event) event,
					      drawable->mouse_move_callback_context);
	    }
	    
	    free(event);
	}
	return 0;
	
    case WM_MOUSELEAVE:
	if(drawable && drawable->mouse_exit_callback) {
	    struct event *event = malloc(sizeof(struct event));
	    
	    event->timestamp = ef_time_unix_epoch();
	    event->modifiers = get_modifiers();
	    event->data.mouse_event.button_number = 0;
	    event->data.mouse_event.click_count = 0;
	    event->data.mouse_event.x = 0;
	    event->data.mouse_event.y = 0;
	    
	    drawable->mouse_exit_callback(drawable,
					  (EF_Event) event,
					  drawable->mouse_exit_callback_context);

	    free(event);
	}
	mouse_drawable = NULL;
	return 0;
	
    default:
	return DefWindowProc(window, message, wParam, lParam);
    }
}
Пример #18
0
/* @brief Processes an entered key by:
 *
 * 1) Adding the key to the query buffer (backspace will remove a character).
 * 2) Drawing the updated query to the screen if necessary.
 * 3) Writing the updated query to the child process if necessary.
 *
 * @param query_buffer The string of the current query (what is typed).
 * @param query_index A reference to the current length of the query.
 * @param query_cursor_index A reference to the current index of the cursor
          in the query.
 * @param key The key enetered.
 * @param connection A connection to the Xorg server.
 * @param cairo_context A cairo context for drawing to the screen.
 * @param cairo_surface A cairo surface for drawing to the screen.
 * @param to_write A descriptor to write to the child process.
 * @return 0 on success and 1 on failure.
 */
static inline int32_t process_key_stroke(xcb_window_t window, char *query_buffer, uint32_t *query_index, uint32_t *query_cursor_index, xcb_keysym_t key, uint16_t modifier_mask, xcb_connection_t *connection, cairo_t *cairo_context, cairo_surface_t *cairo_surface, FILE *to_write) {
  pthread_mutex_lock(&global.result_mutex);

  /* Check when we should update. */
  int32_t redraw = 0;
  int32_t resend = 0;

  uint8_t mod_key = get_modifiers(modifier_mask);

  debug("key: %u, modifier: %u\n", key, mod_key);

  uint32_t highlight = global.result_highlight;
  uint32_t old_pos;
  if (global.result_count && key == 100 && mod_key == 3) {
    /* CTRL-D
     * GO down to the next title
     */
    next_title(&highlight);
    draw_result_text(connection, window, cairo_context, cairo_surface, global.results);
  } else if (global.result_count && key == 117 && mod_key == 3) {
    /* CTRL-U
     * GO up to the next title
     */
    previous_title(&highlight);
    draw_result_text(connection, window, cairo_context, cairo_surface, global.results);
  } else {
  switch (key) {
    case 65293: /* Enter. */
      if (global.results && global.result_highlight < global.result_count) {
		char *title = global.results[global.result_highlight].text;
		char *action = global.results[global.result_highlight].action;

		char command[255] = "echo '";
		strcat(command, query_buffer);
		strcat(command, " {");
		char titleParsed[255];
		str_replace(strcpy(titleParsed, title), "'", "'\\''");
		strcat(command, titleParsed);
		strcat(command, " | ");
		char actionParsed[255];
		str_replace(strcpy(actionParsed, action), "'", "'\\''");
		strcat(command, actionParsed);
		strcat(command, "}");
		strcat(command, "' >> /home/olli/.local/share/lighthouse_queries && ");
        printf("%s", command);

        printf("%s", action);
        goto cleanup;
      }
      break;
    case 65471: /* F2 */
      next_title(&highlight);
      draw_result_text(connection, window, cairo_context, cairo_surface, global.results);
      break;
    case 65472: /* F3 */
      previous_title(&highlight);
      draw_result_text(connection, window, cairo_context, cairo_surface, global.results);
      break;
    case 65361: /* Left. */
      if (*query_cursor_index > 0) {
        (*query_cursor_index)--;
        redraw = 1;
      }
      break;
    case 65363: /* Right. */
      if (*query_cursor_index < *query_index) {
        (*query_cursor_index)++;
        redraw = 1;
      }
      break;
    case 65362: /* Up. */
      if (!global.result_count)
          break;
      if (highlight) { /* Avoid segfault when highlight on the top. */
        old_pos = highlight;
        get_previous_non_title(&highlight);
        if (!global.results[highlight].action) {
            /* If it's a title it mean the get_previous_non_title function
            * found nothing and hit the top.
            */
            highlight = old_pos; /* To not let the highlight point on a title. */
            if (global.result_offset)
                global.result_offset--;
        }
        global.result_highlight = highlight;
        draw_result_text(connection, window, cairo_context, cairo_surface, global.results);
      }
      break;
    case 65364: /* Down. */
      if (!global.result_count)
          break;
      if (highlight < global.result_count - 1) {
       old_pos = highlight;
       get_next_non_title(&highlight);
       if (highlight == global.result_count) {
           /* If no other result with an action can be found, it just inc the
            * the offset so it can show the hidden title and make the highlight to the
            * previous non_title.
            * NB: If the offset limit is exceed, it's handled by the draw_result_text function.
            */
            highlight = old_pos;
            global.result_offset++;
       }
       global.result_highlight = highlight;
       draw_result_text(connection, window, cairo_context, cairo_surface, global.results);
      }
      break;
    case 65289: /* Tab. */
      if (!global.result_count)
          break;
      get_next_line(&highlight);
      draw_result_text(connection, window, cairo_context, cairo_surface, global.results);
      break;
    case 65056: /* Shift Tab */
      if (!global.result_count)
          break;
      get_previous_line(&highlight);
      draw_result_text(connection, window, cairo_context, cairo_surface, global.results);
      break;
    case 65307: /* Escape. */
      goto cleanup;
    case 65288: /* Backspace. */
      if (*query_index > 0 && *query_cursor_index > 0) {
          memmove(&query_buffer[(*query_cursor_index) - 1], &query_buffer[*query_cursor_index], *query_index - *query_cursor_index + 1);
          (*query_cursor_index)--;
          (*query_index)--;
          query_buffer[(*query_index)] = 0;
          redraw = 1;
          resend = 1;
      } else if (*query_index == 0 && settings.backspace_exit) { /* Backspace with nothing */
          goto cleanup;
      }
      break;
    default:
      if (isprint((char)key) && *query_index < MAX_QUERY) {
          memmove(&query_buffer[(*query_cursor_index) + 1], &query_buffer[*query_cursor_index], *query_index - *query_cursor_index + 1);
          query_buffer[(*query_cursor_index)++] = key;
          (*query_index)++;
          redraw = 1;
          resend = 1;
      }
      break;
  }
  }

  if (redraw) {
    draw_query_text(cairo_context, cairo_surface, query_buffer, *query_cursor_index);
    xcb_flush(connection);
  }

  if (resend) {
    if (write_to_remote(to_write, "%s\n", query_buffer)) {
      fprintf(stderr, "Failed to write.\n");
    }
  }

  pthread_mutex_unlock(&global.result_mutex);
  return 1;

cleanup:
  pthread_mutex_unlock(&global.result_mutex);
  return 0;
}
Пример #19
0
bool Window_mac::handleEvent(const SDL_Event& event) {
    switch (event.type) {
        case SDL_WINDOWEVENT:
            if (SDL_WINDOWEVENT_EXPOSED == event.window.event) {
                this->onPaint();
            } else if (SDL_WINDOWEVENT_RESIZED == event.window.event) {
                this->onResize(event.window.data1, event.window.data2);
            }
            break;

        case SDL_MOUSEBUTTONDOWN:
            if (event.button.button == SDL_BUTTON_LEFT) {
                this->onMouse(event.button.x, event.button.y,
                              Window::kDown_InputState, get_modifiers(event));
            }
            break;

        case SDL_MOUSEBUTTONUP:
            if (event.button.button == SDL_BUTTON_LEFT) {
                this->onMouse(event.button.x, event.button.y,
                              Window::kUp_InputState, get_modifiers(event));
            }
            break;

        case SDL_MOUSEMOTION:
            this->onMouse(event.motion.x, event.motion.y,
                          Window::kMove_InputState, get_modifiers(event));
            break;

        case SDL_MOUSEWHEEL:
            this->onMouseWheel(event.wheel.y, get_modifiers(event));
            break;

        case SDL_KEYDOWN: {
            Window::Key key = get_key(event.key.keysym);
            if (key != Window::Key::kNONE) {
                if (!this->onKey(key, Window::kDown_InputState, get_modifiers(event))) {
                    if (event.key.keysym.sym == SDLK_ESCAPE) {
                        return true;
                    }
                }
            }
        } break;

        case SDL_KEYUP: {
            Window::Key key = get_key(event.key.keysym);
            if (key != Window::Key::kNONE) {
                (void) this->onKey(key, Window::kUp_InputState,
                                   get_modifiers(event));
            }
        } break;

        case SDL_TEXTINPUT: {
            const char* textIter = &event.text.text[0];
            while (SkUnichar c = SkUTF8_NextUnichar(&textIter)) {
                (void) this->onChar(c, get_modifiers(event));
            }
        } break;

        default:
            break;
    }

    return false;
}
Пример #20
0
void setup_modifiers(){
	for(int i=0;i<sizeof(keybindings)/sizeof(event_t);i++){
		keybindings[i].modifiers=get_modifiers(keybindings[i].keycode);
	}
}
Пример #21
0
bool Window_mac::handleEvent(const XEvent& event) {
    switch (event.type) {
        case MapNotify:
            if (!fGC) {
                fGC = XCreateGC(fDisplay, fWindow, 0, nullptr);
            }
            break;

        case ClientMessage:
            if ((Atom)event.xclient.data.l[0] == fWmDeleteMessage &&
                gWindowMap.count() == 1) {
                return true;
            }
            break;

        case ButtonPress:
            if (event.xbutton.button == Button1) {
                this->onMouse(event.xbutton.x, event.xbutton.y,
                              Window::kDown_InputState, get_modifiers(event));
            }
            break;

        case ButtonRelease:
            if (event.xbutton.button == Button1) {
                this->onMouse(event.xbutton.x, event.xbutton.y,
                              Window::kUp_InputState, get_modifiers(event));
            }
            break;

        case MotionNotify:
            // only track if left button is down
            if (event.xmotion.state & Button1Mask) {
                this->onMouse(event.xmotion.x, event.xmotion.y, 
                              Window::kMove_InputState, get_modifiers(event));
            }
            break;

        case KeyPress: {
            int shiftLevel = (event.xkey.state & ShiftMask) ? 1 : 0;
            KeySym keysym = XkbKeycodeToKeysym(fDisplay, event.xkey.keycode,
                                               0, shiftLevel);
            if (keysym == XK_Escape) {
                return true;
            }
            Window::Key key = get_key(keysym);
            if (key != Window::Key::kNONE) {
                (void) this->onKey(key, Window::kDown_InputState, 
                                   get_modifiers(event));
            } else {
                long uni = keysym2ucs(keysym);
                if (uni != -1) {
                    (void) this->onChar((SkUnichar) uni, 
                                        get_modifiers(event));
                }
            }
        } break;

        case KeyRelease: {
            int shiftLevel = (event.xkey.state & ShiftMask) ? 1 : 0;
            KeySym keysym = XkbKeycodeToKeysym(fDisplay, event.xkey.keycode,
                                               0, shiftLevel);
            Window::Key key = get_key(keysym);
            (void) this->onKey(key, Window::kUp_InputState, 
                               get_modifiers(event));
        } break;
        

        default:
            // these events should be handled in the main event loop
            SkASSERT(event.type != Expose && event.type != ConfigureNotify);
            break;
    }

    return false;
}
Пример #22
0
Array f_hphp_get_class_info(CVarRef name) {
  String className;
  if (name.isObject()) {
    className = name.toObject()->o_getClassName();
  } else {
    className = name.toString();
  }

  const ClassInfo *cls = ClassInfo::FindClass(className);
  if (cls == NULL) {
    cls = ClassInfo::FindInterface(className);
  }
  if (cls == NULL) {
    cls = ClassInfo::FindTrait(className);
  }

  Array ret;
  if (cls == NULL) {
    return ret;
  }

  ret.set("name",       cls->getName());
  ret.set("extension",  "");
  ret.set("parent",     cls->getParentClass());

  // interfaces
  {
    Array arr = Array::Create();
    const ClassInfo::InterfaceVec &interfaces = cls->getInterfacesVec();
    for (ClassInfo::InterfaceVec::const_iterator iter = interfaces.begin();
         iter != interfaces.end(); ++iter) {
      arr.set(*iter, 1);
    }
    ret.set("interfaces", arr);
  }

  // traits
  {
    Array arr = Array::Create();
    const ClassInfo::TraitVec &traits = cls->getTraitsVec();
    for (ClassInfo::TraitVec::const_iterator iter = traits.begin();
         iter != traits.end(); ++iter) {
      arr.set(*iter, 1);
    }
    ret.set("traits", arr);
  }

  // trait aliases
  {
    Array arr = Array::Create();
    const ClassInfo::TraitAliasVec &aliases = cls->getTraitAliasesVec();
    for (ClassInfo::TraitAliasVec::const_iterator iter = aliases.begin();
         iter != aliases.end(); ++iter) {
      arr.set(iter->first, iter->second);
    }
    ret.set("trait_aliases", arr);
  }

  // attributes
  {
    int attribute = cls->getAttribute();
    ret.set("internal",   (bool)(attribute & ClassInfo::IsSystem));
    ret.set("hphp",       (bool)(attribute & ClassInfo::HipHopSpecific));
    ret.set("abstract",   (bool)(attribute & ClassInfo::IsAbstract));
    ret.set("interface",  (bool)(attribute & ClassInfo::IsInterface));
    ret.set("final",      (bool)(attribute & ClassInfo::IsFinal));
    ret.set("trait",      (bool)(attribute & ClassInfo::IsTrait));
    ret.set("modifiers",  get_modifiers(attribute, true));
  }

  // methods
  {
    Array arr = Array::Create();
    const ClassInfo::MethodVec &methods = cls->getMethodsVec();
    for (ClassInfo::MethodVec::const_iterator iter = methods.begin();
         iter != methods.end(); ++iter) {
      ClassInfo::MethodInfo *m = *iter;
      if ((m->attribute & ClassInfo::IsInherited) == 0) {
        Array info = Array::Create();
        set_method_info(info, m, cls);
        arr.set(StringUtil::ToLower(m->name), info);
      }
    }
    ret.set("methods", arr);
  }

  // properties
  {
    Array arr = Array::Create();
    const ClassInfo::PropertyVec &properties = cls->getPropertiesVec();
    for (ClassInfo::PropertyVec::const_iterator iter = properties.begin();
         iter != properties.end(); ++iter) {
      ClassInfo::PropertyInfo *prop = *iter;
      Array info = Array::Create();
      set_property_info(info, prop, cls);
      arr.set(prop->name, info);
    }
    ret.set("properties", arr);
  }

  // constants
  {
    Array arr = Array::Create();
    const ClassInfo::ConstantVec &constants = cls->getConstantsVec();
    for (ClassInfo::ConstantVec::const_iterator iter = constants.begin();
         iter != constants.end(); ++iter) {
      ClassInfo::ConstantInfo *info = *iter;
      if (info->valueText && *info->valueText) {
        arr.set(info->name, info->getValue());
      } else {
        arr.set(info->name, get_class_constant(className, info->name));
      }
    }
    ret.set("constants", arr);
  }

  { // source info
    if (!set_source_info(ret, cls->getFile(), cls->getLine1(),
                         cls->getLine2())) {
      int line = 0;
      const char *file = SourceInfo::TheSourceInfo.
        getClassDeclaringFile(className, &line);
      set_source_info(ret, file, line, line);
    }
    set_doc_comment(ret, cls->getDocComment());
  }

  return ret;
}
Пример #23
0
Array f_hphp_get_class_info(CVarRef name) {
  String className;
  if (name.isObject()) {
    className = name.toObject()->o_getClassName();
  } else {
    className = name.toString();
  }

  const ClassInfo *cls = ClassInfo::FindClass(className.data());
  if (cls == NULL) {
    cls = ClassInfo::FindInterface(className.data());
  }

  Array ret;
  if (cls == NULL) {
    return ret;
  }

  ret.set("name",       cls->getName());
  ret.set("extension",  "");
  ret.set("parent",     cls->getParentClass());

  // interfaces
  {
    Array arr = Array::Create();
    const ClassInfo::InterfaceMap &interfaces = cls->getInterfaces();
    for (ClassInfo::InterfaceMap::const_iterator iter = interfaces.begin();
         iter != interfaces.end(); ++iter) {
      arr.set(*iter, 1);
    }
    ret.set("interfaces", arr);
  }

  // attributes
  {
    int attribute = cls->getAttribute();
    ret.set("internal",   (bool)(attribute & ClassInfo::IsSystem));
    ret.set("abstract",   (bool)(attribute & ClassInfo::IsAbstract));
    ret.set("interface",  (bool)(attribute & ClassInfo::IsInterface));
    ret.set("final",      (bool)(attribute & ClassInfo::IsFinal));
    ret.set("modifiers",  get_modifiers(attribute, true));
  }

  // methods
  {
    Array arr = Array::Create();
    const ClassInfo::MethodVec &methods = cls->getMethodsVec();
    for (ClassInfo::MethodVec::const_iterator iter = methods.begin();
         iter != methods.end(); ++iter) {
      ClassInfo::MethodInfo *m = *iter;
      if ((m->attribute & ClassInfo::IsInherited) == 0) {
        Array info = Array::Create();
        set_method_info(info, m, cls);
        arr.set(StringUtil::ToLower(m->name), info);
      }
    }
    ret.set("methods", arr);
  }

  // properties
  {
    Array arr = Array::Create();
    const ClassInfo::PropertyMap &properties = cls->getProperties();
    for (ClassInfo::PropertyMap::const_iterator iter = properties.begin();
         iter != properties.end(); ++iter) {
      Array info = Array::Create();
      set_property_info(info, iter->second, cls);
      arr.set(iter->first, info);
    }
    ret.set("properties", arr);
  }

  // constants
  {
    Array arr = Array::Create();
    const ClassInfo::ConstantMap &constants = cls->getConstants();
    for (ClassInfo::ConstantMap::const_iterator iter = constants.begin();
         iter != constants.end(); ++iter) {
      if (iter->second->valueText && *iter->second->valueText) {
        arr.set(iter->second->name, iter->second->value);
      } else {
        arr.set(iter->second->name,
                get_class_constant(className.data(), iter->second->name));
      }
    }
    ret.set("constants", arr);
  }

  { // source info
    const char *file =
      SourceInfo::TheSourceInfo.getClassDeclaringFile(className.data());
    if (!file) file = "";
    if (file[0] != '/') {
      ret.set("file", String(RuntimeOption::SourceRoot + file));
    } else {
      ret.set("file", file);
    }
    ret.set("line1", 0);
    ret.set("line2", 0);
    const char *dc = cls->getDocComment();
    if (dc) {
      ret.set("doc", dc);
    } else {
      ret.set("doc", false);
    }
  }

  return ret;
}
Пример #24
0
void hook_event_proc(XPointer closeure, XRecordInterceptData *recorded_data) {
	uint64_t timestamp = (uint64_t) recorded_data->server_time;

	if (recorded_data->category == XRecordStartOfData) {
		// Populate the hook start event.
		event.time = timestamp;
		event.reserved = 0x00;

		event.type = EVENT_HOOK_ENABLED;
		event.mask = 0x00;

		// Fire the hook start event.
		dispatch_event(&event);
	}
	else if (recorded_data->category == XRecordEndOfData) {
		// Populate the hook stop event.
		event.time = timestamp;
		event.reserved = 0x00;

		event.type = EVENT_HOOK_DISABLED;
		event.mask = 0x00;

		// Fire the hook stop event.
		dispatch_event(&event);
	}
	else if (recorded_data->category == XRecordFromServer || recorded_data->category == XRecordFromClient) {
		// Get XRecord data.
		XRecordDatum *data = (XRecordDatum *) recorded_data->data;

		if (data->type == KeyPress) {
			// The X11 KeyCode associated with this event.
			KeyCode keycode = (KeyCode) data->event.u.u.detail;
            KeySym keysym = 0x00;
			#if defined(USE_XKBCOMMON)
		   	if (state != NULL) {
				keysym = xkb_state_key_get_one_sym(state, keycode);
			}
			#else
			keysym = keycode_to_keysym(keycode, data->event.u.keyButtonPointer.state);
			#endif

			unsigned short int scancode = keycode_to_scancode(keycode);

			// TODO If you have a better suggestion for this ugly, let me know.
			if		(scancode == VC_SHIFT_L)		{ set_modifier_mask(MASK_SHIFT_L);		}
			else if (scancode == VC_SHIFT_R)		{ set_modifier_mask(MASK_SHIFT_R);		}
			else if (scancode == VC_CONTROL_L)		{ set_modifier_mask(MASK_CTRL_L);		}
			else if (scancode == VC_CONTROL_R)		{ set_modifier_mask(MASK_CTRL_R);		}
			else if (scancode == VC_ALT_L)			{ set_modifier_mask(MASK_ALT_L);		}
			else if (scancode == VC_ALT_R)			{ set_modifier_mask(MASK_ALT_R);		}
			else if (scancode == VC_META_L)			{ set_modifier_mask(MASK_META_L);		}
			else if (scancode == VC_META_R)			{ set_modifier_mask(MASK_META_R);		}
			xkb_state_update_key(state, keycode, XKB_KEY_DOWN);
			initialize_locks();

			if ((get_modifiers() & MASK_NUM_LOCK) == 0) {
                switch (scancode) {
					case VC_KP_SEPARATOR:
					case VC_KP_1:
					case VC_KP_2:
					case VC_KP_3:
					case VC_KP_4:
					case VC_KP_5:
					case VC_KP_6:
					case VC_KP_7:
					case VC_KP_8:
					case VC_KP_0:
					case VC_KP_9:
						scancode |= 0xEE00;
						break;
                }
			}

			// Populate key pressed event.
			event.time = timestamp;
			event.reserved = 0x00;

			event.type = EVENT_KEY_PRESSED;
			event.mask = get_modifiers();

			event.data.keyboard.keycode = scancode;
			event.data.keyboard.rawcode = keysym;
			event.data.keyboard.keychar = CHAR_UNDEFINED;

			logger(LOG_LEVEL_INFO,	"%s [%u]: Key %#X pressed. (%#X)\n",
					__FUNCTION__, __LINE__, event.data.keyboard.keycode, event.data.keyboard.rawcode);

			// Fire key pressed event.
			dispatch_event(&event);

			// If the pressed event was not consumed...
			if (event.reserved ^ 0x01) {
				uint16_t buffer[2];
			    size_t count =  0;

				// Check to make sure the key is printable.
				#ifdef USE_XKBCOMMON
				if (state != NULL) {
					count = keycode_to_unicode(state, keycode, buffer, sizeof(buffer) / sizeof(uint16_t));
				}
				#else
				count = keysym_to_unicode(keysym, buffer, sizeof(buffer) / sizeof(uint16_t));
				#endif

				for (unsigned int i = 0; i < count; i++) {
					// Populate key typed event.
					event.time = timestamp;
					event.reserved = 0x00;

					event.type = EVENT_KEY_TYPED;
					event.mask = get_modifiers();

					event.data.keyboard.keycode = VC_UNDEFINED;
					event.data.keyboard.rawcode = keysym;
					event.data.keyboard.keychar = buffer[i];

					logger(LOG_LEVEL_INFO,	"%s [%u]: Key %#X typed. (%lc)\n",
							__FUNCTION__, __LINE__, event.data.keyboard.keycode, (uint16_t) event.data.keyboard.keychar);

					// Fire key typed event.
					dispatch_event(&event);
				}
			}
		}
		else if (data->type == KeyRelease) {
			// The X11 KeyCode associated with this event.
			KeyCode keycode = (KeyCode) data->event.u.u.detail;
			KeySym keysym = 0x00;
			#ifdef USE_XKBCOMMON
			if (state != NULL) {
				keysym = xkb_state_key_get_one_sym(state, keycode);
			}
			#else
			keysym = keycode_to_keysym(keycode, data->event.u.keyButtonPointer.state);
			#endif

			unsigned short int scancode = keycode_to_scancode(keycode);

			// TODO If you have a better suggestion for this ugly, let me know.
			if		(scancode == VC_SHIFT_L)		{ unset_modifier_mask(MASK_SHIFT_L);		}
			else if (scancode == VC_SHIFT_R)		{ unset_modifier_mask(MASK_SHIFT_R);		}
			else if (scancode == VC_CONTROL_L)		{ unset_modifier_mask(MASK_CTRL_L);			}
			else if (scancode == VC_CONTROL_R)		{ unset_modifier_mask(MASK_CTRL_R);			}
			else if (scancode == VC_ALT_L)			{ unset_modifier_mask(MASK_ALT_L);			}
			else if (scancode == VC_ALT_R)			{ unset_modifier_mask(MASK_ALT_R);			}
			else if (scancode == VC_META_L)			{ unset_modifier_mask(MASK_META_L);			}
			else if (scancode == VC_META_R)			{ unset_modifier_mask(MASK_META_R);			}
			xkb_state_update_key(state, keycode, XKB_KEY_UP);
			initialize_locks();

			if ((get_modifiers() & MASK_NUM_LOCK) == 0) {
                switch (scancode) {
					case VC_KP_SEPARATOR:
					case VC_KP_1:
					case VC_KP_2:
					case VC_KP_3:
					case VC_KP_4:
					case VC_KP_5:
					case VC_KP_6:
					case VC_KP_7:
					case VC_KP_8:
					case VC_KP_0:
					case VC_KP_9:
						scancode |= 0xEE00;
						break;
                }
			}

			// Populate key released event.
			event.time = timestamp;
			event.reserved = 0x00;

			event.type = EVENT_KEY_RELEASED;
			event.mask = get_modifiers();

			event.data.keyboard.keycode = scancode;
			event.data.keyboard.rawcode = keysym;
			event.data.keyboard.keychar = CHAR_UNDEFINED;

			logger(LOG_LEVEL_INFO, "%s [%u]: Key %#X released. (%#X)\n",
					__FUNCTION__, __LINE__, event.data.keyboard.keycode, event.data.keyboard.rawcode);

			// Fire key released event.
			dispatch_event(&event);
		}
		else if (data->type == ButtonPress) {
			// X11 handles wheel events as button events.
			if (data->event.u.u.detail == WheelUp || data->event.u.u.detail == WheelDown
					|| data->event.u.u.detail == WheelLeft || data->event.u.u.detail == WheelRight) {

				// Reset the click count and previous button.
				hook->input.mouse.click.count = 1;
				hook->input.mouse.click.button = MOUSE_NOBUTTON;

				/* Scroll wheel release events.
				 * Scroll type: WHEEL_UNIT_SCROLL
				 * Scroll amount: 3 unit increments per notch
				 * Units to scroll: 3 unit increments
				 * Vertical unit increment: 15 pixels
				 */

				// Populate mouse wheel event.
				event.time = timestamp;
				event.reserved = 0x00;

				event.type = EVENT_MOUSE_WHEEL;
				event.mask = get_modifiers();

				event.data.wheel.clicks = hook->input.mouse.click.count;
				event.data.wheel.x = data->event.u.keyButtonPointer.rootX;
				event.data.wheel.y = data->event.u.keyButtonPointer.rootY;

				#if defined(USE_XINERAMA) || defined(USE_XRANDR)
				uint8_t count;
				screen_data *screens = hook_create_screen_info(&count);
				if (count > 1) {
					event.data.wheel.x -= screens[0].x;
					event.data.wheel.y -= screens[0].y;
				}

				if (screens != NULL) {
					free(screens);
				}
				#endif

				/* X11 does not have an API call for acquiring the mouse scroll type.  This
				 * maybe part of the XInput2 (XI2) extention but I will wont know until it
				 * is available on my platform.  For the time being we will just use the
				 * unit scroll value.
				 */
				event.data.wheel.type = WHEEL_UNIT_SCROLL;

				/* Some scroll wheel properties are available via the new XInput2 (XI2)
				 * extension.  Unfortunately the extension is not available on my
				 * development platform at this time.  For the time being we will just
				 * use the Windows default value of 3.
				 */
				event.data.wheel.amount = 3;

				if (data->event.u.u.detail == WheelUp || data->event.u.u.detail == WheelLeft) {
					// Wheel Rotated Up and Away.
					event.data.wheel.rotation = -1;
				}
				else { // data->event.u.u.detail == WheelDown
					// Wheel Rotated Down and Towards.
					event.data.wheel.rotation = 1;
				}

				if (data->event.u.u.detail == WheelUp || data->event.u.u.detail == WheelDown) {
					// Wheel Rotated Up or Down.
					event.data.wheel.direction = WHEEL_VERTICAL_DIRECTION;
				}
				else { // data->event.u.u.detail == WheelLeft || data->event.u.u.detail == WheelRight
					// Wheel Rotated Left or Right.
					event.data.wheel.direction = WHEEL_HORIZONTAL_DIRECTION;
				}

				logger(LOG_LEVEL_INFO,	"%s [%u]: Mouse wheel type %u, rotated %i units in the %u direction at %u, %u.\n",
						__FUNCTION__, __LINE__, event.data.wheel.type,
						event.data.wheel.amount * event.data.wheel.rotation,
                        event.data.wheel.direction,
						event.data.wheel.x, event.data.wheel.y);

				// Fire mouse wheel event.
				dispatch_event(&event);
			}
			else {
				/* This information is all static for X11, its up to the WM to
				 * decide how to interpret the wheel events.
				 */
				uint16_t button = MOUSE_NOBUTTON;
				switch (data->event.u.u.detail) {
					// FIXME This should use a lookup table to handle button remapping.
					case Button1:
						button = MOUSE_BUTTON1;
						set_modifier_mask(MASK_BUTTON1);
						break;

					case Button2:
						button = MOUSE_BUTTON2;
						set_modifier_mask(MASK_BUTTON2);
						break;

					case Button3:
						button = MOUSE_BUTTON3;
						set_modifier_mask(MASK_BUTTON3);
						break;

					case XButton1:
						button = MOUSE_BUTTON4;
						set_modifier_mask(MASK_BUTTON5);
						break;

					case XButton2:
						button = MOUSE_BUTTON5;
						set_modifier_mask(MASK_BUTTON5);
						break;

					default:
						// Do not set modifier masks past button MASK_BUTTON5.
						break;
				}


				// Track the number of clicks, the button must match the previous button.
				if (button == hook->input.mouse.click.button && (long int) (timestamp - hook->input.mouse.click.time) <= hook_get_multi_click_time()) {
					if (hook->input.mouse.click.count < USHRT_MAX) {
						hook->input.mouse.click.count++;
					}
					else {
						logger(LOG_LEVEL_WARN, "%s [%u]: Click count overflow detected!\n",
								__FUNCTION__, __LINE__);
					}
				}
				else {
					// Reset the click count.
					hook->input.mouse.click.count = 1;

					// Set the previous button.
					hook->input.mouse.click.button = button;
				}

				// Save this events time to calculate the hook->input.mouse.click.count.
				hook->input.mouse.click.time = timestamp;


				// Populate mouse pressed event.
				event.time = timestamp;
				event.reserved = 0x00;

				event.type = EVENT_MOUSE_PRESSED;
				event.mask = get_modifiers();

				event.data.mouse.button = button;
				event.data.mouse.clicks = hook->input.mouse.click.count;
				event.data.mouse.x = data->event.u.keyButtonPointer.rootX;
				event.data.mouse.y = data->event.u.keyButtonPointer.rootY;

				#if defined(USE_XINERAMA) || defined(USE_XRANDR)
				uint8_t count;
				screen_data *screens = hook_create_screen_info(&count);
				if (count > 1) {
					event.data.mouse.x -= screens[0].x;
					event.data.mouse.y -= screens[0].y;
				}

				if (screens != NULL) {
					free(screens);
				}
				#endif

				logger(LOG_LEVEL_INFO,	"%s [%u]: Button %u  pressed %u time(s). (%u, %u)\n",
						__FUNCTION__, __LINE__, event.data.mouse.button, event.data.mouse.clicks,
						event.data.mouse.x, event.data.mouse.y);

				// Fire mouse pressed event.
				dispatch_event(&event);
			}
		}
		else if (data->type == ButtonRelease) {
			// X11 handles wheel events as button events.
			if (data->event.u.u.detail != WheelUp && data->event.u.u.detail != WheelDown) {
				/* This information is all static for X11, its up to the WM to
				 * decide how to interpret the wheel events.
				 */
				uint16_t button = MOUSE_NOBUTTON;
				switch (data->event.u.u.detail) {
					// FIXME This should use a lookup table to handle button remapping.
					case Button1:
						button = MOUSE_BUTTON1;
						unset_modifier_mask(MASK_BUTTON1);
						break;

					case Button2:
						button = MOUSE_BUTTON2;
						unset_modifier_mask(MASK_BUTTON2);
						break;

					case Button3:
						button = MOUSE_BUTTON3;
						unset_modifier_mask(MASK_BUTTON3);
						break;

					case XButton1:
						button = MOUSE_BUTTON4;
						unset_modifier_mask(MASK_BUTTON5);
						break;

					case XButton2:
						button = MOUSE_BUTTON5;
						unset_modifier_mask(MASK_BUTTON5);
						break;

					default:
						// Do not set modifier masks past button MASK_BUTTON5.
						break;
				}

				// Populate mouse released event.
				event.time = timestamp;
				event.reserved = 0x00;

				event.type = EVENT_MOUSE_RELEASED;
				event.mask = get_modifiers();

				event.data.mouse.button = button;
				event.data.mouse.clicks = hook->input.mouse.click.count;
				event.data.mouse.x = data->event.u.keyButtonPointer.rootX;
				event.data.mouse.y = data->event.u.keyButtonPointer.rootY;

				#if defined(USE_XINERAMA) || defined(USE_XRANDR)
				uint8_t count;
				screen_data *screens = hook_create_screen_info(&count);
				if (count > 1) {
					event.data.mouse.x -= screens[0].x;
					event.data.mouse.y -= screens[0].y;
				}

				if (screens != NULL) {
					free(screens);
				}
				#endif

				logger(LOG_LEVEL_INFO,	"%s [%u]: Button %u released %u time(s). (%u, %u)\n",
						__FUNCTION__, __LINE__, event.data.mouse.button,
						event.data.mouse.clicks,
						event.data.mouse.x, event.data.mouse.y);

				// Fire mouse released event.
				dispatch_event(&event);

				// If the pressed event was not consumed...
				if (event.reserved ^ 0x01 && hook->input.mouse.is_dragged != true) {
					// Populate mouse clicked event.
					event.time = timestamp;
					event.reserved = 0x00;

					event.type = EVENT_MOUSE_CLICKED;
					event.mask = get_modifiers();

					event.data.mouse.button = button;
					event.data.mouse.clicks = hook->input.mouse.click.count;
					event.data.mouse.x = data->event.u.keyButtonPointer.rootX;
					event.data.mouse.y = data->event.u.keyButtonPointer.rootY;

					#if defined(USE_XINERAMA) || defined(USE_XRANDR)
					uint8_t count;
					screen_data *screens = hook_create_screen_info(&count);
					if (count > 1) {
						event.data.mouse.x -= screens[0].x;
						event.data.mouse.y -= screens[0].y;
					}

					if (screens != NULL) {
						free(screens);
					}
					#endif

					logger(LOG_LEVEL_INFO,	"%s [%u]: Button %u clicked %u time(s). (%u, %u)\n",
							__FUNCTION__, __LINE__, event.data.mouse.button,
							event.data.mouse.clicks,
							event.data.mouse.x, event.data.mouse.y);

					// Fire mouse clicked event.
					dispatch_event(&event);
				}

				// Reset the number of clicks.
				if (button == hook->input.mouse.click.button && (long int) (event.time - hook->input.mouse.click.time) > hook_get_multi_click_time()) {
					// Reset the click count.
					hook->input.mouse.click.count = 0;
				}
			}
		}
		else if (data->type == MotionNotify) {
			// Reset the click count.
			if (hook->input.mouse.click.count != 0 && (long int) (timestamp - hook->input.mouse.click.time) > hook_get_multi_click_time()) {
				hook->input.mouse.click.count = 0;
			}
			
			// Populate mouse move event.
			event.time = timestamp;
			event.reserved = 0x00;

			event.mask = get_modifiers();

			// Check the upper half of virtual modifiers for non-zero
			// values and set the mouse dragged flag.
			hook->input.mouse.is_dragged = (event.mask >> 8 > 0);
			if (hook->input.mouse.is_dragged) {
				// Create Mouse Dragged event.
				event.type = EVENT_MOUSE_DRAGGED;
			}
			else {
				// Create a Mouse Moved event.
				event.type = EVENT_MOUSE_MOVED;
			}

			event.data.mouse.button = MOUSE_NOBUTTON;
			event.data.mouse.clicks = hook->input.mouse.click.count;
			event.data.mouse.x = data->event.u.keyButtonPointer.rootX;
			event.data.mouse.y = data->event.u.keyButtonPointer.rootY;

			#if defined(USE_XINERAMA) || defined(USE_XRANDR)
			uint8_t count;
			screen_data *screens = hook_create_screen_info(&count);
			if (count > 1) {
				event.data.mouse.x -= screens[0].x;
				event.data.mouse.y -= screens[0].y;
			}

			if (screens != NULL) {
				free(screens);
			}
			#endif

			logger(LOG_LEVEL_INFO,	"%s [%u]: Mouse %s to %i, %i. (%#X)\n",
					__FUNCTION__, __LINE__, hook->input.mouse.is_dragged ? "dragged" : "moved",
					event.data.mouse.x, event.data.mouse.y, event.mask);

			// Fire mouse move event.
			dispatch_event(&event);
		}
		else {