Пример #1
0
/*
 * Instead of polling the X connection socket we leave this to
 * xcb_poll_for_event() which knows better than we can ever know.
 *
 */
static void xcb_check_cb(EV_P_ ev_check *w, int revents) {
    xcb_generic_event_t *event;

    if (xcb_connection_has_error(conn))
        errx(EXIT_FAILURE, "X11 connection broke, did your server terminate?\n");

    while ((event = xcb_poll_for_event(conn)) != NULL) {
        if (event->response_type == 0) {

            xcb_generic_error_t *error = (xcb_generic_error_t *)event;
            if (debug_mode)
                fprintf(stderr, "X11 Error received! sequence 0x%x, error_code = %d\n",
                        error->sequence, error->error_code);
            free(event);
            continue;
        }
        /* Strip off the highest bit (set if the event is generated) */
        int type = (event->response_type & 0x7F);

        switch (type) {
        case XCB_BUTTON_PRESS:
            handle_button_press((xcb_button_press_event_t *)event);
            break;

        case XCB_KEY_PRESS:
            handle_key_press((xcb_key_press_event_t *)event);
            break;

        case XCB_VISIBILITY_NOTIFY:
            handle_visibility_notify(conn, (xcb_visibility_notify_event_t *)event);
            break;

        case XCB_MAP_NOTIFY:
            if (!dont_fork) {
                /* After the first MapNotify, we never fork again. We don’t
                 * expect to get another MapNotify, but better be sure… */
                dont_fork = true;

                /* In the parent process, we exit */
                if (fork() != 0)
                    exit(0);

                ev_loop_fork(EV_DEFAULT);
            }
            break;

        case XCB_CONFIGURE_NOTIFY:
            handle_screen_resize();
            break;

        default:
            if (type == xkb_base_event)
                process_xkb_event(event);
        }

        free(event);
    }
}
Пример #2
0
/***
 * Callback for polling for new input.
 */
void retro_input_poll_callback()
{
	sceCtrlPeekBufferPositive(0, pad, 1);
    uint32_t keys_down = pad->buttons;

    // first, handle (single) physical button presses
    unsigned int i;

    for (i = MAP_BUTTON_UP; i <= MAP_BUTTON_START; i++)
    {
        handle_button_press(ActiveConfig.ButtonMap[i], keys_down & PhysicalButtonMap[i]);
    }

    // next, handle multi-button presses (L + R or start + select)
    if ((keys_down & SCE_CTRL_LTRIGGER) && (keys_down & SCE_CTRL_RTRIGGER))
    {
        handle_button_press(ActiveConfig.ButtonMap[MAP_BUTTON_LRTRIGGERS], true);
    }

    if ((keys_down & SCE_CTRL_START) && (keys_down & SCE_CTRL_SELECT))
    {
        handle_button_press(ActiveConfig.ButtonMap[MAP_BUTTON_STARTSELECT], true);
    }

    // finally, handle analog sticks
    if (pad->ly < 128 - JOY_THRESHOLD) // analog up
    {
        handle_button_press(ActiveConfig.ButtonMap[MAP_ANALOG_UP], true);
    }
    else if (pad->ly > 128 + JOY_THRESHOLD) // analog down
    {
        handle_button_press(ActiveConfig.ButtonMap[MAP_ANALOG_DOWN], true);
    }

    if (pad->lx < 128 - JOY_THRESHOLD) // analog left
    {
        handle_button_press(ActiveConfig.ButtonMap[MAP_ANALOG_LEFT], true);
    }
    else if (pad->lx > 128 + JOY_THRESHOLD) // analog right
    {
        handle_button_press(ActiveConfig.ButtonMap[MAP_ANALOG_RIGHT], true);
    }
}
Пример #3
0
void default_pointer_handler(XEvent *ev)
{
	XEvent tmp;
	Window win_pressed;
	WThing *t;
	bool mouse_grab_held=FALSE;
	
	if(grab_held())
		return;
	
	win_pressed=ev->xbutton.window;
	if(!handle_button_press(&ev->xbutton))
		return;

	mouse_grab_held=TRUE;

	while(mouse_grab_held){
		XFlush(wglobal.dpy);
		get_event_mask(ev, GRAB_EV_MASK);
		
		switch(ev->type){
		CASE_EVENT(ButtonRelease)
			if(handle_button_release(&(ev->xbutton))){
				ungrab_kb_ptr();
				mouse_grab_held=FALSE;
			}
			break;
		CASE_EVENT(MotionNotify)
			handle_pointer_motion(&(ev->xmotion));
			break;
		CASE_EVENT(Expose)		
			handle_expose(&(ev->xexpose));
			break;
		}
	}
}
Пример #4
0
Файл: main.c Проект: stfnm/i3
/*
 * Creates the config file and tells i3 to reload.
 *
 */
static void finish() {
    printf("creating \"%s\"...\n", config_path);

    if (!(dpy = XOpenDisplay(NULL)))
        errx(1, "Could not connect to X11");

    FILE *kc_config = fopen(SYSCONFDIR "/i3/config.keycodes", "r");
    if (kc_config == NULL)
        err(1, "Could not open input file \"%s\"", SYSCONFDIR "/i3/config.keycodes");

    FILE *ks_config = fopen(config_path, "w");
    if (ks_config == NULL)
        err(1, "Could not open output config file \"%s\"", config_path);
    free(config_path);

    char *line = NULL;
    size_t len = 0;
#ifndef USE_FGETLN
    ssize_t read;
#endif
    bool head_of_file = true;

    /* write a header about auto-generation to the output file */
    fputs("# This file has been auto-generated by i3-config-wizard(1).\n", ks_config);
    fputs("# It will not be overwritten, so edit it as you like.\n", ks_config);
    fputs("#\n", ks_config);
    fputs("# Should you change your keyboard layout somewhen, delete\n", ks_config);
    fputs("# this file and re-run i3-config-wizard(1).\n", ks_config);
    fputs("#\n", ks_config);

#ifdef USE_FGETLN
    char *buf = NULL;
    while ((buf = fgetln(kc_config, &len)) != NULL) {
        /* fgetln does not return null-terminated strings */
        FREE(line);
        sasprintf(&line, "%.*s", len, buf);
#else
    size_t linecap = 0;
    while ((read = getline(&line, &linecap, kc_config)) != -1) {
        len = strlen(line);
#endif
        /* skip the warning block at the beginning of the input file */
        if (head_of_file &&
            strncmp("# WARNING", line, strlen("# WARNING")) == 0)
            continue;

        head_of_file = false;

        /* Skip leading whitespace */
        char *walk = line;
        while (isspace(*walk) && walk < (line + len)) {
            /* Pre-output the skipped whitespaces to keep proper indentation */
            fputc(*walk, ks_config);
            walk++;
        }

        /* Set the modifier the user chose */
        if (strncmp(walk, "set $mod ", strlen("set $mod ")) == 0) {
            if (modifier == MOD_Mod1)
                fputs("set $mod Mod1\n", ks_config);
            else fputs("set $mod Mod4\n", ks_config);
            continue;
        }

        /* Check for 'bindcode'. If it’s not a bindcode line, we
         * just copy it to the output file */
        if (strncmp(walk, "bindcode", strlen("bindcode")) != 0) {
            fputs(walk, ks_config);
            continue;
        }
        char *result = rewrite_binding(walk);
        fputs(result, ks_config);
        free(result);
    }

    /* sync to do our best in order to have the file really stored on disk */
    fflush(ks_config);
    fsync(fileno(ks_config));

#ifndef USE_FGETLN
    free(line);
#endif

    fclose(kc_config);
    fclose(ks_config);

    /* tell i3 to reload the config file */
    int sockfd = ipc_connect(socket_path);
    ipc_send_message(sockfd, strlen("reload"), 0, (uint8_t*)"reload");
    close(sockfd);

    exit(0);
}

int main(int argc, char *argv[]) {
    config_path = resolve_tilde("~/.i3/config");
    socket_path = getenv("I3SOCK");
    char *pattern = "-misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1";
    char *patternbold = "-misc-fixed-bold-r-normal--13-120-75-75-C-70-iso10646-1";
    int o, option_index = 0;

    static struct option long_options[] = {
        {"socket", required_argument, 0, 's'},
        {"version", no_argument, 0, 'v'},
        {"limit", required_argument, 0, 'l'},
        {"prompt", required_argument, 0, 'P'},
        {"prefix", required_argument, 0, 'p'},
        {"font", required_argument, 0, 'f'},
        {"help", no_argument, 0, 'h'},
        {0, 0, 0, 0}
    };

    char *options_string = "s:vh";

    while ((o = getopt_long(argc, argv, options_string, long_options, &option_index)) != -1) {
        switch (o) {
            case 's':
                FREE(socket_path);
                socket_path = strdup(optarg);
                break;
            case 'v':
                printf("i3-config-wizard " I3_VERSION "\n");
                return 0;
            case 'h':
                printf("i3-config-wizard " I3_VERSION "\n");
                printf("i3-config-wizard [-s <socket>] [-v]\n");
                return 0;
        }
    }

    /* Check if the destination config file does not exist but the path is
     * writable. If not, exit now, this program is not useful in that case. */
    struct stat stbuf;
    if (stat(config_path, &stbuf) == 0) {
        printf("The config file \"%s\" already exists. Exiting.\n", config_path);
        return 0;
    }

    /* Create ~/.i3 if it does not yet exist */
    char *config_dir = resolve_tilde("~/.i3");
    if (stat(config_dir, &stbuf) != 0)
        if (mkdir(config_dir, 0755) == -1)
            err(1, "mkdir(%s) failed", config_dir);
    free(config_dir);

    int fd;
    if ((fd = open(config_path, O_CREAT | O_RDWR, 0644)) == -1) {
        printf("Cannot open file \"%s\" for writing: %s. Exiting.\n", config_path, strerror(errno));
        return 0;
    }
    close(fd);
    unlink(config_path);

    if (socket_path == NULL)
        socket_path = root_atom_contents("I3_SOCKET_PATH");

    if (socket_path == NULL)
        socket_path = "/tmp/i3-ipc.sock";

    int screens;
    if ((conn = xcb_connect(NULL, &screens)) == NULL ||
        xcb_connection_has_error(conn))
        errx(1, "Cannot open display\n");

    xcb_get_modifier_mapping_cookie_t modmap_cookie;
    modmap_cookie = xcb_get_modifier_mapping(conn);
    symbols = xcb_key_symbols_alloc(conn);

    /* Place requests for the atoms we need as soon as possible */
    #define xmacro(atom) \
        xcb_intern_atom_cookie_t atom ## _cookie = xcb_intern_atom(conn, 0, strlen(#atom), #atom);
    #include "atoms.xmacro"
    #undef xmacro

    root_screen = xcb_aux_get_screen(conn, screens);
    root = root_screen->root;

    if (!(modmap_reply = xcb_get_modifier_mapping_reply(conn, modmap_cookie, NULL)))
        errx(EXIT_FAILURE, "Could not get modifier mapping\n");

    xcb_numlock_mask = get_mod_mask_for(XCB_NUM_LOCK, symbols, modmap_reply);

    font = load_font(pattern, true);
    bold_font = load_font(patternbold, true);

    /* Open an input window */
    win = xcb_generate_id(conn);
    xcb_create_window(
        conn,
        XCB_COPY_FROM_PARENT,
        win, /* the window id */
        root, /* parent == root */
        490, 297, 300, 205, /* dimensions */
        0, /* X11 border = 0, we draw our own */
        XCB_WINDOW_CLASS_INPUT_OUTPUT,
        XCB_WINDOW_CLASS_COPY_FROM_PARENT, /* copy visual from parent */
        XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK,
        (uint32_t[]){
            0, /* back pixel: black */
            XCB_EVENT_MASK_EXPOSURE |
            XCB_EVENT_MASK_BUTTON_PRESS
        });

    /* Map the window (make it visible) */
    xcb_map_window(conn, win);

    /* Setup NetWM atoms */
    #define xmacro(name) \
        do { \
            xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(conn, name ## _cookie, NULL); \
            if (!reply) \
                errx(EXIT_FAILURE, "Could not get atom " # name "\n"); \
            \
            A_ ## name = reply->atom; \
            free(reply); \
        } while (0);
    #include "atoms.xmacro"
    #undef xmacro

    /* Set dock mode */
    xcb_change_property(conn,
        XCB_PROP_MODE_REPLACE,
        win,
        A__NET_WM_WINDOW_TYPE,
        A_ATOM,
        32,
        1,
        (unsigned char*) &A__NET_WM_WINDOW_TYPE_DIALOG);

    /* Set window title */
    xcb_change_property(conn,
        XCB_PROP_MODE_REPLACE,
        win,
        A__NET_WM_NAME,
        A_UTF8_STRING,
        8,
        strlen("i3: first configuration"),
        "i3: first configuration");

    /* Create pixmap */
    pixmap = xcb_generate_id(conn);
    pixmap_gc = xcb_generate_id(conn);
    xcb_create_pixmap(conn, root_screen->root_depth, pixmap, win, 500, 500);
    xcb_create_gc(conn, pixmap_gc, pixmap, 0, 0);

    /* Grab the keyboard to get all input */
    xcb_flush(conn);

    /* Try (repeatedly, if necessary) to grab the keyboard. We might not
     * get the keyboard at the first attempt because of the keybinding
     * still being active when started via a wm’s keybinding. */
    xcb_grab_keyboard_cookie_t cookie;
    xcb_grab_keyboard_reply_t *reply = NULL;

    int count = 0;
    while ((reply == NULL || reply->status != XCB_GRAB_STATUS_SUCCESS) && (count++ < 500)) {
        cookie = xcb_grab_keyboard(conn, false, win, XCB_CURRENT_TIME, XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC);
        reply = xcb_grab_keyboard_reply(conn, cookie, NULL);
        usleep(1000);
    }

    if (reply->status != XCB_GRAB_STATUS_SUCCESS) {
        fprintf(stderr, "Could not grab keyboard, status = %d\n", reply->status);
        exit(-1);
    }

    xcb_flush(conn);

    xcb_generic_event_t *event;
    while ((event = xcb_wait_for_event(conn)) != NULL) {
        if (event->response_type == 0) {
            fprintf(stderr, "X11 Error received! sequence %x\n", event->sequence);
            continue;
        }

        /* Strip off the highest bit (set if the event is generated) */
        int type = (event->response_type & 0x7F);

        switch (type) {
            case XCB_KEY_PRESS:
                handle_key_press(NULL, conn, (xcb_key_press_event_t*)event);
                break;

            /* TODO: handle mappingnotify */

            case XCB_BUTTON_PRESS:
                handle_button_press((xcb_button_press_event_t*)event);
                break;

            case XCB_EXPOSE:
                handle_expose();
                break;
        }

        free(event);
    }

    return 0;
}
si_t window_manager_input_handler(struct egui_uds* uds_ptr, addr_t arg)
{
	struct input_device* input_device_ptr = (struct input_device*)arg;
	NOT_USED(uds_ptr);

	if(0 != input_device_ptr->deal_with_input(input_device_ptr, &global_wm.message_list))
	{
		EGUI_PRINT_ERROR("failed to deal with input");
	}

	/* 消息队列非空 */
	while(list_empty(&(global_wm.message_list)) == 0)
	{
		union message * message;
		/* 获得第一个消息 */
		message = list_front(&(global_wm.message_list));

		/* 消息中光标的位置 */
		message->base.cursor_position.x = global_wm.old_cursor.x;
		message->base.cursor_position.y = global_wm.old_cursor.y;

		/* 有包含窗口的用户应用程序 */
		if(global_wm.active_app_info_ptr != NULL && global_wm.active_win_info_ptr != NULL)
		{
			send_input_message(&global_wm.active_app_info_ptr->uds, message, (si_t)global_wm.active_win_info_ptr);
		}

		if(message->base.type == MESSAGE_TYPE_MOUSE_PRESS)
		{
			/**
			 * if not clicked in workspace area, send to desktop thread
			 **/
			if(!is_point_in_area(&message->base.cursor_position, &global_wm.work_area) && NULL != global_wm.desktop_app_ptr)
			{
				send_input_message(&global_wm.desktop_app_ptr->uds, message, 0);
			}
			else
			{
				/* 更新活动窗口 */
				mask_active_by_mouse_down(message);

				handle_desktop_press(message);

				handle_button_press(message);

				handle_title_bar_press(message);

				handle_frame_press(message);
			}
		}
		else if(message->base.type == MESSAGE_TYPE_MOUSE_RELEASE)
		{
			/**
			 * if not clicked in workspace area, send to desktop thread
			 **/
			if(!is_point_in_area(&message->base.cursor_position, &global_wm.work_area))
			{
				send_input_message(&global_wm.desktop_app_ptr->uds, message, 0);
			}
			else
			{
				handle_desktop_release(message);

				handle_button_release(message);

				handle_widget_move(message);

				handle_widget_resize(message);
			}
		}
		/* 绘制鼠标并且更新光标的坐标 */
		else if(message->base.type == MESSAGE_TYPE_MOUSE_MOVE ||
				message->base.type == MESSAGE_TYPE_MOUSE_MOVE_POINT)
		{
			if(message->mouse.code == INPUT_CODE_MOUSE_X_OFFSET)
			{
				if(message->base.type == MESSAGE_TYPE_MOUSE_MOVE) {
					global_wm.new_cursor.x =
						global_wm.new_cursor.x + message->mouse.value;
				} else {
					global_wm.new_cursor.x =
						(double)message->mouse.value/MOUSE_RESOLUTION*
						global_screen.width;
				}

				if(global_wm.new_cursor.x < 0)
				{
					global_wm.new_cursor.x = 0;
				}
				else if(global_wm.new_cursor.x >= (si_t)global_screen.width)
				{
					global_wm.new_cursor.x = global_screen.width - 1;
				}
			}
			else if(message->mouse.code == INPUT_CODE_MOUSE_Y_OFFSET)
			{
				if(message->base.type == MESSAGE_TYPE_MOUSE_MOVE) {
					global_wm.new_cursor.y =
						global_wm.new_cursor.y + message->mouse.value;
				} else {
					global_wm.new_cursor.y =
						(double)message->mouse.value/MOUSE_RESOLUTION*
						global_screen.height;
				}

				if(global_wm.new_cursor.y < 0)
				{
					global_wm.new_cursor.y = 0;
				}
				else if(global_wm.new_cursor.y >= (si_t)global_screen.height)
				{
					global_wm.new_cursor.y = global_screen.height - 1;
				}
			}

			accumulate_widget_move(message);
			accumulate_widget_resize(message);

			cursor_paint();

			global_wm.old_cursor = global_wm.new_cursor;
		}
		/* 删除已分发的消息 */
		list_pop_front(&(global_wm.message_list));
	}

	return 0;
}