Ejemplo n.º 1
0
Archivo: x-events.cpp Proyecto: 8l/swm
/**
 * Runs a single iteration of the event loop, by capturing an X event and
 * acting upon it.
 *
 * @return true if more events can be processed, false otherwise.
 */
bool XEvents::step()
{
    // Grab the next event from X, and then dispatch upon its type
    m_xdata.next_event(m_event);

    if (m_event.type == m_randroffset + RRNotify)
        handle_rrnotify();
    
    if (m_event.type == KeyPress)
        handle_keypress();

    if (m_event.type == ButtonPress)
        handle_buttonpress();

    if (m_event.type == ButtonRelease)
        handle_buttonrelease();

    if (m_event.type == MotionNotify)
        handle_motionnotify();

    if (m_event.type == MapNotify)
        handle_mapnotify();

    if (m_event.type == Expose)
        handle_expose();

    if (m_event.type == DestroyNotify)
        handle_destroynotify();

    return !m_done;
}
Ejemplo n.º 2
0
Archivo: main.c Proyecto: stfnm/i3
/*
 * Handle button presses to make clicking on "<win>" and "<alt>" work
 *
 */
static void handle_button_press(xcb_button_press_event_t* event) {
    if (current_step != STEP_GENERATE)
        return;

    if (event->event_x >= 32 && event->event_x <= 68 &&
        event->event_y >= 45 && event->event_y <= 54) {
        modifier = MOD_Mod4;
        handle_expose();
    }

    if (event->event_x >= 32 && event->event_x <= 68 &&
        event->event_y >= 56 && event->event_y <= 70) {
        modifier = MOD_Mod1;
        handle_expose();
    }

    return;
}
Ejemplo n.º 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;
		}
	}
}
Ejemplo n.º 4
0
Archivo: main.c Proyecto: 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;
}
Ejemplo n.º 5
0
Archivo: main.c Proyecto: stfnm/i3
static int handle_key_press(void *ignored, xcb_connection_t *conn, xcb_key_press_event_t *event) {
    printf("Keypress %d, state raw = %d\n", event->detail, event->state);

    /* Remove the numlock bit, all other bits are modifiers we can bind to */
    uint16_t state_filtered = event->state & ~(xcb_numlock_mask | XCB_MOD_MASK_LOCK);
    /* Only use the lower 8 bits of the state (modifier masks) so that mouse
     * button masks are filtered out */
    state_filtered &= 0xFF;

    xcb_keysym_t sym = xcb_key_press_lookup_keysym(symbols, event, state_filtered);

    printf("sym = %c (%d)\n", sym, sym);

    if (sym == XK_Return || sym == XK_KP_Enter) {
        if (current_step == STEP_WELCOME) {
            current_step = STEP_GENERATE;
            /* Set window title */
            xcb_change_property(conn,
                XCB_PROP_MODE_REPLACE,
                win,
                A__NET_WM_NAME,
                A_UTF8_STRING,
                8,
                strlen("i3: generate config"),
                "i3: generate config");
            xcb_flush(conn);
        }
        else finish();
    }

    /* cancel any time */
    if (sym == XK_Escape)
        exit(0);

    /* Check if this is Mod1 or Mod4. The modmap contains Shift, Lock, Control,
     * Mod1, Mod2, Mod3, Mod4, Mod5 (in that order) */
    xcb_keycode_t *modmap = xcb_get_modifier_mapping_keycodes(modmap_reply);
    /* Mod1? */
    int mask = 3;
    for (int i = 0; i < modmap_reply->keycodes_per_modifier; i++) {
        xcb_keycode_t code = modmap[(mask * modmap_reply->keycodes_per_modifier) + i];
        if (code == XCB_NONE)
            continue;
        printf("Modifier keycode for Mod1: 0x%02x\n", code);
        if (code == event->detail) {
            modifier = MOD_Mod1;
            printf("This is Mod1!\n");
        }
    }

    /* Mod4? */
    mask = 6;
    for (int i = 0; i < modmap_reply->keycodes_per_modifier; i++) {
        xcb_keycode_t code = modmap[(mask * modmap_reply->keycodes_per_modifier) + i];
        if (code == XCB_NONE)
            continue;
        printf("Modifier keycode for Mod4: 0x%02x\n", code);
        if (code == event->detail) {
            modifier = MOD_Mod4;
            printf("This is Mod4!\n");
        }
    }

    handle_expose();
    return 1;
}
Ejemplo n.º 6
0
int main(int argc, char* argv[]) {
    int sockfd, oldsockfd, portno, n;
    socklen_t clilen;
    struct sockaddr_in serv_addr, cli_addr;
    struct hostent *server;
    pthread_t recv_thread;
    Colormap map;

    Display* display;
    int screen_num;
    Window win;
    unsigned int display_width, display_height;
    unsigned int width, height;
    char *display_name = getenv("DISPLAY");
    GC gc, his_gc, refresh_gc;

    if(argc == 2) { // We are server
        sending = 1;
        if(argc < 2) {
            fprintf(stderr,"ERROR, no port provided\n");
            exit(1);
        }
        oldsockfd = socket(AF_INET, SOCK_STREAM, 0);
        if(oldsockfd < 0) error("ERROR opening socket");
        bzero((char *) &serv_addr, sizeof(serv_addr));
        portno = atoi(argv[1]);
        serv_addr.sin_family = AF_INET;
        serv_addr.sin_addr.s_addr = INADDR_ANY;
        serv_addr.sin_port = htons(portno);
        int on = 1;
        if(setsockopt(oldsockfd, SOL_SOCKET, SO_REUSEADDR, (char*)&on, sizeof(on)) < 0) error("ERROR on sockopt");
        if(bind(oldsockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) error("ERROR on binding");
        listen(oldsockfd,5);
        clilen = sizeof(cli_addr);
        sockfd = accept(oldsockfd, (struct sockaddr *) &cli_addr, &clilen);
        if (sockfd < 0) error("ERROR on accept");
    }
    else if(argc == 3) { // We are client
        sending = 1;
        portno = atoi(argv[2]);
        sockfd = socket(AF_INET, SOCK_STREAM, 0);
        if (sockfd < 0) error("ERROR opening socket");
        server = gethostbyname(argv[1]);
        if(server == NULL) {
            fprintf(stderr,"ERROR, no such host\n");
            exit(0);
        }
        bzero((char *) &serv_addr, sizeof(serv_addr));
        serv_addr.sin_family = AF_INET;
        bcopy((char *)(server->h_addr), (char *)(&serv_addr.sin_addr.s_addr), server->h_length);
        serv_addr.sin_port = htons(portno);
        if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0) error("ERROR connecting");
    }
    else {
        server = 0;
    }

    display = XOpenDisplay(display_name);
    if (display == NULL) {
        fprintf(stderr, "%s: cannot connect to X server '%s'\n", argv[0], display_name);
        exit(1);
    }

    screen_num = DefaultScreen(display);
    display_width = DisplayWidth(display, screen_num);
    display_height = DisplayHeight(display, screen_num);
    width = (display_width / 3);
    height = (display_height / 3);
    Atom wm_delete;
    win = create_simple_window(display, &wm_delete, width, height, 0, 0);


    XGCValues values;
    values.graphics_exposures = 0;
    gc = create_gc(display, win);
    his_gc = create_gc(display, win);
    refresh_gc = XCreateGC(display, win, GCGraphicsExposures, &values);

    XSetForeground(display, refresh_gc, WhitePixel(display, screen_num));
    XSetBackground(display, refresh_gc, WhitePixel(display, screen_num));

    map = DefaultColormap(display, 0);
    XParseColor(display, map, "#FFFFFF", &cols[0]);
    XAllocColor(display, map, &cols[0]);
    XParseColor(display, map, "#000000", &cols[1]);
    XAllocColor(display, map, &cols[1]);
    XParseColor(display, map, "#FF0000", &cols[2]);
    XAllocColor(display, map, &cols[2]);
    XParseColor(display, map, "#00FF00", &cols[3]);
    XAllocColor(display, map, &cols[3]);
    XParseColor(display, map, "#0000FF", &cols[4]);
    XAllocColor(display, map, &cols[4]);
    XParseColor(display, map, "#FFFF00", &cols[5]);
    XAllocColor(display, map, &cols[5]);
    XParseColor(display, map, "#FF00FF", &cols[6]);
    XAllocColor(display, map, &cols[6]);
    XParseColor(display, map, "#00FFFF", &cols[7]);
    XAllocColor(display, map, &cols[7]);
    XParseColor(display, map, "#999999", &cols[8]);
    XAllocColor(display, map, &cols[8]);
    XParseColor(display, map, "#666666", &cols[9]);
    XAllocColor(display, map, &cols[9]);

    set_title(display, win);

    back_buffer = XCreatePixmap(display, win, MAX_WIDTH, MAX_HEIGHT, DefaultDepth(display, screen_num));
    XFillRectangle(display, back_buffer, refresh_gc, 0, 0, MAX_WIDTH, MAX_HEIGHT);

    if(sending) {
        recv_info_t info;
        info.display = display;
        info.window = win;
        info.gc = gc;
        info.his_gc = his_gc;
        info.refresh_gc = refresh_gc;
        info.sockfd = sockfd;
        pthread_create(&recv_thread, NULL, recv_line, &info);
    }

    XSelectInput(display, win, ExposureMask | KeyPressMask | ButtonPressMask | Button1MotionMask | StructureNotifyMask);
    XEvent an_event;
    while(1) {
        XNextEvent(display, &an_event);
        switch(an_event.type) {
        case ClientMessage:
            if(an_event.xclient.data.l[0] == wm_delete) quitme(display, gc, his_gc, refresh_gc, sockfd, 0);
            break;
        case Expose:
            handle_expose(display, refresh_gc, (XExposeEvent*)&an_event.xexpose);
            break;
        case ConfigureNotify:
            width = an_event.xconfigure.width;
            height = an_event.xconfigure.height;
            break;
        case ButtonPress:
            handle_button_down(display, gc, (XButtonEvent*)&an_event.xbutton, width, height);
            break;
        case MotionNotify:
            handle_drag(display, gc, (XButtonEvent*)&an_event.xbutton, width, height, sockfd);
            break;
        case KeyPress:
            handle_key(display, win, gc, his_gc, refresh_gc, map, (XKeyEvent*)&an_event.xkey, sockfd);
            break;
        default:
            break;
        }
    }
    quitme(display, gc, his_gc, refresh_gc, sockfd, 0);
}
Ejemplo n.º 7
0
// Handle X event on queue.  Return true if event was handled.
bool jbxvt_handle_xevents(xcb_connection_t * xc)
{
	jb_check_x(xc);
	static bool init;
	if (!init) {
		// Set up the wm_del_win property here.
		wm_del_win(xc);
	}
	xcb_generic_event_t * event = xcb_poll_for_event(xc);
	if (!event) // nothing to process
		return false;
	bool ret = true;
	switch (event->response_type & ~0x80) {
	// Put things to ignore here:
	case 0: // Unimplemented, undefined, no event
	case 150: // Undefined
	case XCB_KEY_RELEASE: // Unimplemented
	case XCB_MAP_NOTIFY:
	case XCB_NO_EXPOSURE: // Unimplemented
	case XCB_REPARENT_NOTIFY: // handle here to ensure cursor filled.
		ret = false;
		break;
	case XCB_CONFIGURE_NOTIFY:
		jbxvt_resize_window(xc);
		break;
	case XCB_KEY_PRESS:
		key_press(xc, event);
		break;
	case XCB_CLIENT_MESSAGE:
		handle_client_message(xc,
			(xcb_client_message_event_t *)event);
		break;
	case XCB_EXPOSE:
	case XCB_GRAPHICS_EXPOSURE:
		handle_expose(xc, (xcb_expose_event_t *)event);
		break;
	case XCB_ENTER_NOTIFY:
	case XCB_FOCUS_IN:
		handle_focus(true);
		break;
	case XCB_LEAVE_NOTIFY:
	case XCB_FOCUS_OUT:
		handle_focus(false);
		break;
	case XCB_SELECTION_CLEAR:
		jbxvt_clear_selection();
		break;
	case XCB_SELECTION_NOTIFY:
		handle_selection_notify(xc,
			(xcb_selection_notify_event_t *)event);
		break;
	case XCB_SELECTION_REQUEST:
		handle_selection_request(xc,
			(xcb_selection_request_event_t *)event);
		break;
	case XCB_BUTTON_PRESS:
		jbxvt_handle_button_press_event(xc,
			(xcb_button_press_event_t *)event);
		break;
	case XCB_BUTTON_RELEASE:
		jbxvt_handle_button_release_event(xc,
			(xcb_button_release_event_t *)event);
		break;
	case XCB_MOTION_NOTIFY:
		handle_motion_notify(xc,
			(xcb_motion_notify_event_t *)event);
		break;
	default:
		LOG("Unhandled event %d", event->response_type);
	}
	free(event);
	return ret;
}
Ejemplo n.º 8
0
void handle_event(XEvent *ev)
{
	switch(ev->type){
	CASE_EVENT(MapRequest)
		handle_map_request(&(ev->xmaprequest));
		break;
	CASE_EVENT(ConfigureRequest)
		handle_configure_request(&(ev->xconfigurerequest));
		break;
	CASE_EVENT(UnmapNotify)
		handle_unmap_notify(&(ev->xunmap));
		break;
	CASE_EVENT(DestroyNotify)
		handle_destroy_notify(&(ev->xdestroywindow));
		break;
	CASE_EVENT(ClientMessage)
		handle_client_message(&(ev->xclient));
		break;
	CASE_EVENT(PropertyNotify)
		handle_property(&(ev->xproperty));
		break;
	CASE_EVENT(FocusIn)
		handle_focus_in(&(ev->xfocus));
		break;
	CASE_EVENT(FocusOut)
		handle_focus_out(&(ev->xfocus));
		break;
	CASE_EVENT(EnterNotify)
		handle_enter_window(ev);
		break;
	CASE_EVENT(Expose)		
		handle_expose(&(ev->xexpose));
		break;
	CASE_EVENT(KeyPress)
		assert(wglobal.input_handler!=NULL);
		assert(wglobal.input_handler->keyboard!=NULL);
		wglobal.input_handler->keyboard(ev);
		break;
	CASE_EVENT(KeyRelease)
		assert(wglobal.input_handler!=NULL);
		assert(wglobal.input_handler->keyboard!=NULL);
		wglobal.input_handler->keyboard(ev);
		break;
	CASE_EVENT(ButtonPress)
		assert(wglobal.input_handler!=NULL);
		if(wglobal.input_handler->pointer!=NULL)
			wglobal.input_handler->pointer(ev);
		break;
	CASE_EVENT(ColormapNotify)
		handle_colormap_notify(&(ev->xcolormap));
		break;
	CASE_EVENT(MappingNotify)
		XRefreshKeyboardMapping(&(ev->xmapping));
		update_modmap();
		break;
	CASE_EVENT(SelectionClear)
		clear_selection();
		break;
	CASE_EVENT(SelectionNotify)
		receive_selection(&(ev->xselection));
		break;
	CASE_EVENT(SelectionRequest)
		send_selection(&(ev->xselectionrequest));
		break;
	}
}
Ejemplo n.º 9
0
void
main(int argc, char* argv[])
{
  Display* display;		/* pointer to X Display structure.           */
  int screen_num;		/* number of screen to place the window on.  */
  Window win;			/* pointer to the newly created window.      */
  unsigned int display_width,
               display_height;	/* height and width of the X display.        */
  unsigned int width, height;	/* height and width for the new window.      */
  char *display_name = getenv("DISPLAY");  /* address of the X display.      */
  GC gc, rev_gc;		/* GC (graphics context) used for drawing    */
				/*  in our window.			     */
  short pixels[1000][1000];	/* used to store pixels on screen that were  */
				/* explicitly drawn or erased by the user.   */

  /* initialize the 'pixels' array to contain 0 values. */
  {
    int x, y;
    for (x=0; x<1000; x++)
      for (y=0; y<1000; y++)
        pixels[x][y] = 0;
  }

  /* open connection with the X server. */
  display = XOpenDisplay(display_name);
  if (display == NULL) {
    fprintf(stderr, "%s: cannot connect to X server '%s'\n",
            argv[0], display_name);
    exit(1);
  }

  /* get the geometry of the default screen for our display. */
  screen_num = DefaultScreen(display);
  display_width = DisplayWidth(display, screen_num);
  display_height = DisplayHeight(display, screen_num);

  /* make the new window occupy 1/9 of the screen's size. */
  width = (display_width / 3);
  height = (display_height / 3);
  printf("window width - '%d'; height - '%d'\n", width, height);

  /* create a simple window, as a direct child of the screen's   */
  /* root window. Use the screen's white color as the background */
  /* color of the window. Place the new window's top-left corner */
  /* at the given 'x,y' coordinates.                             */
  win = create_simple_window(display, width, height, 0, 0);

  /* allocate two new GCs (graphics contexts) for drawing in the window. */
  /* the first is used for drawing black over white, the second is used  */
  /* for drawing white over black.                                       */
  gc = create_gc(display, win, 0);
  rev_gc = create_gc(display, win, 1);

  /* subscribe to the given set of event types. */
  XSelectInput(display, win, ExposureMask | KeyPressMask |
                     ButtonPressMask | Button1MotionMask |
		     Button2MotionMask | Button3MotionMask | StructureNotifyMask);

  /* perform an events loop */
  {
    int done = 0;
    XEvent an_event;
    while (!done) {
      XNextEvent(display, &an_event);
      switch (an_event.type) {
        case Expose:
          /* redraw our window. */
	  handle_expose(display, gc, rev_gc, (XExposeEvent*)&an_event.xexpose,
             		width, height, pixels);
          break;
  
        case ConfigureNotify:
          /* update the size of our window, for expose events. */
          width = an_event.xconfigure.width;
          height = an_event.xconfigure.height;
          break;
  
        case ButtonPress:
          /* invert the pixel under the mouse pointer. */
          handle_button_down(display, gc, rev_gc,
                             (XButtonEvent*)&an_event.xbutton,
                             width, height, pixels);
          break;
  
        case MotionNotify:
          /* invert the pixel under the mouse pointer. */
          handle_drag(display, gc, rev_gc,
                      (XButtonEvent*)&an_event.xbutton,
                      width, height, pixels);
	  break;
  
        case KeyPress:
          /* exit the application by braking out of the events loop. */
          done = 1;
          break;
  
        default: /* ignore any other event types. */
          break;
      } /* end switch on event type */
    } /* end while events handling */
  }

  /* free the GCs. */
  XFreeGC(display, gc);
  XFreeGC(display, rev_gc);

  /* close the connection to the X server. */
  XCloseDisplay(display);
}
Ejemplo n.º 10
0
/*
 * Input thread reading from device.
 * Generates events on incoming data.
 */
static void*
x11EventThread( DirectThread *thread, void *driver_data )
{
     X11InputData *data   = driver_data;
     DFBX11       *x11    = data->x11;
     DFBX11Shared *shared = x11->shared;

     while (!data->stop) {
          unsigned int  pull = 23;
          XEvent        xEvent; 
          DFBInputEvent dfbEvent;
          static int    nextKeyIsRepeat = false;

          /* FIXME: Detect key repeats, we're receiving KeyPress, KeyRelease, KeyPress, KeyRelease... !!?? */

          if (shared->window_count == 0) {
               /* no window, so no event */
               usleep( 50000 );
               continue;
          }

          usleep( 10000 );

          XLockDisplay( x11->display );

          while (!data->stop && pull-- && XPending( x11->display )) {
               XNextEvent( x11->display, &xEvent );

               /* is this key repeat? idea from GII */
               if ( (xEvent.type == KeyRelease) && (XPending( x11->display )) ) {
                    XEvent peekEvent;
                    XPeekEvent( x11->display, &peekEvent );
                    if ( (peekEvent.type == KeyPress) &&
                         (peekEvent.xkey.keycode == xEvent.xkey.keycode) &&
                         (peekEvent.xkey.time - xEvent.xkey.time < 2) ) {
                              nextKeyIsRepeat = true;
                    }
               }

               XUnlockDisplay( x11->display );

               D_DEBUG_AT( X11_Input, "Event received: %d\n", xEvent.type );

               switch (xEvent.type) {
                    case ButtonPress:
                    case ButtonRelease:
                         motion_realize( data );
                    case MotionNotify:
                         handleMouseEvent( &xEvent, data ); // crash ???
                         break;

                    case KeyPress:
                    case KeyRelease: {
                         motion_realize( data );

                         dfbEvent.type     = (xEvent.type == KeyPress) ? DIET_KEYPRESS : DIET_KEYRELEASE;
                         dfbEvent.flags    = DIEF_KEYCODE | DIEF_TIMESTAMP;
                         dfbEvent.key_code = xEvent.xkey.keycode;

                         dfbEvent.timestamp.tv_sec  =  xEvent.xkey.time / 1000;
                         dfbEvent.timestamp.tv_usec = (xEvent.xkey.time % 1000) * 1000;

                         if ( (xEvent.type == KeyPress) && nextKeyIsRepeat ) {
                              nextKeyIsRepeat = false;
                              dfbEvent.flags |= DIEF_REPEAT;
                         }

                         dfb_input_dispatch( data->device, &dfbEvent );
                         break;
                    }

                    case Expose:
                         handle_expose( &xEvent.xexpose );
                         break;

                    case DestroyNotify:
                         /* this event is mainly to unblock XNextEvent. */
                         break;

                    default:
                         break;
               }

               XLockDisplay( x11->display );
          }

          XUnlockDisplay( x11->display );

          if (!data->stop)
               motion_realize( data );
     }

     return NULL;
}
Ejemplo n.º 11
0
	int
main(int argc, char* argv[])
{
	Display* display;
	Window win;
	char *display_name = getenv("DISPLAY");
	GC gc, rev_gc;
    Atom wmDelete;
	struct CEventDescriptor event =
	{
		.Type = EVENT_NULL
	};

	InitGUIServer();
	ClearScreen();
	while (!ProcessGUIServer(&event))
		;

	display = XOpenDisplay(display_name);
	if (display == NULL) {
		fprintf(stderr, "%s: cannot connect to X server '%s'\n",
				argv[0], display_name);
		exit(1);
	}

	win = create_simple_window(display, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0);
	wmDelete = XInternAtom(display, "WM_DELETE_WINDOW", True);
	XSetWMProtocols(display, win, &wmDelete, 1);

	gc = create_gc(display, win, 0);
	rev_gc = create_gc(display, win, 1);

	XSelectInput(display, win, ExposureMask | KeyPressMask |
			ButtonPressMask | StructureNotifyMask);

	{
		int done = 0;
		XEvent an_event;
		while (!done) {
			XNextEvent(display, &an_event);
			switch (an_event.type) {
				case Expose:
					handle_expose(display, gc, rev_gc, (XExposeEvent*)&an_event.xexpose);
					break;

				case ButtonPress:
					handle_button_down(display, gc, rev_gc,
							(XButtonEvent*)&an_event.xbutton);
					break;

				case KeyPress:
					done = handle_key_down(display, gc, rev_gc,
							(XKeyEvent*)&an_event.xkey);
					break;

				case ClientMessage:
					done = True;
					break;

				default:
					break;
			}
		}
	}

	XFreeGC(display, gc);
	XFreeGC(display, rev_gc);

	XCloseDisplay(display);
	return 0;
}
Ejemplo n.º 12
0
int main(int argc, char *argv[]) {
    format = sstrdup("%s");
    char *socket_path = NULL;
    char *pattern = sstrdup("pango:monospace 8");
    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'},
        {"format", required_argument, 0, 'F'},
        {"font", required_argument, 0, 'f'},
        {"help", no_argument, 0, 'h'},
        {0, 0, 0, 0}};

    char *options_string = "s:p:P:f:l:F:vh";

    while ((o = getopt_long(argc, argv, options_string, long_options, &option_index)) != -1) {
        switch (o) {
            case 's':
                FREE(socket_path);
                socket_path = sstrdup(optarg);
                break;
            case 'v':
                printf("i3-input " I3_VERSION);
                return 0;
            case 'p':
                /* This option is deprecated, but will still work in i3 v4.1, 4.2 and 4.3 */
                fprintf(stderr, "i3-input: WARNING: the -p option is DEPRECATED in favor of the -F (format) option\n");
                FREE(format);
                sasprintf(&format, "%s%%s", optarg);
                break;
            case 'l':
                limit = atoi(optarg);
                break;
            case 'P':
                i3string_free(prompt);
                prompt = i3string_from_utf8(optarg);
                break;
            case 'f':
                FREE(pattern);
                pattern = sstrdup(optarg);
                break;
            case 'F':
                FREE(format);
                format = sstrdup(optarg);
                break;
            case 'h':
                printf("i3-input " I3_VERSION "\n");
                printf("i3-input [-s <socket>] [-F <format>] [-l <limit>] [-P <prompt>] [-f <font>] [-v]\n");
                printf("\n");
                printf("Example:\n");
                printf("    i3-input -F 'workspace \"%%s\"' -P 'Switch to workspace: '\n");
                return 0;
        }
    }

    printf("using format \"%s\"\n", format);

    int screen;
    conn = xcb_connect(NULL, &screen);
    if (!conn || xcb_connection_has_error(conn))
        die("Cannot open display\n");

    sockfd = ipc_connect(socket_path);

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

    symbols = xcb_key_symbols_alloc(conn);

    init_dpi();
    font = load_font(pattern, true);
    set_font(&font);

    if (prompt != NULL)
        prompt_offset = predict_text_width(prompt);

    const xcb_rectangle_t win_pos = get_window_position();

    /* Open an input window */
    win = xcb_generate_id(conn);
    xcb_create_window(
        conn,
        XCB_COPY_FROM_PARENT,
        win,                                                 /* the window id */
        root,                                                /* parent == root */
        win_pos.x, win_pos.y, win_pos.width, win_pos.height, /* 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_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK,
        (uint32_t[]){
            0, /* back pixel: black */
            1, /* override redirect: don’t manage this window */
            XCB_EVENT_MASK_EXPOSURE});

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

    /* Initialize the drawable surface */
    draw_util_surface_init(conn, &surface, win, get_visualtype(root_screen), win_pos.width, win_pos.height);

    /* 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;

            case XCB_KEY_RELEASE:
                handle_key_release(NULL, conn, (xcb_key_release_event_t *)event);
                break;

            case XCB_EXPOSE:
                if (((xcb_expose_event_t *)event)->count == 0) {
                    handle_expose(NULL, conn, (xcb_expose_event_t *)event);
                }

                break;
        }

        free(event);
    }

    draw_util_surface_free(conn, &surface);
    return 0;
}
Ejemplo n.º 13
0
/*
 * Handles keypresses by converting the keycodes to keysymbols, then the
 * keysymbols to UCS-2. If the conversion succeeded, the glyph is saved in the
 * internal buffers and displayed in the input window.
 *
 * Also handles backspace (deleting one character) and return (sending the
 * command to i3).
 *
 */
static int handle_key_press(void *ignored, xcb_connection_t *conn, xcb_key_press_event_t *event) {
    printf("Keypress %d, state raw = %d\n", event->detail, event->state);

    // TODO: port the input handling code from i3lock once libxkbcommon ≥ 0.5.0
    // is available in distros.

    /* See the documentation of xcb_key_symbols_get_keysym for this one.
     * Basically: We get either col 0 or col 1, depending on whether shift is
     * pressed. */
    int col = (event->state & XCB_MOD_MASK_SHIFT);

    /* If modeswitch is currently active, we need to look in group 2 or 3,
     * respectively. */
    if (modeswitch_active)
        col += 2;

    xcb_keysym_t sym = xcb_key_press_lookup_keysym(symbols, event, col);
    if (sym == XK_Mode_switch) {
        printf("Mode switch enabled\n");
        modeswitch_active = true;
        return 1;
    }

    if (sym == XK_Return)
        finish_input();

    if (sym == XK_BackSpace) {
        if (input_position == 0)
            return 1;

        input_position--;
        free(glyphs_utf8[input_position]);

        handle_expose(NULL, conn, NULL);
        return 1;
    }
    if (sym == XK_Escape) {
        exit(0);
    }

    /* TODO: handle all of these? */
    printf("is_keypad_key = %d\n", xcb_is_keypad_key(sym));
    printf("is_private_keypad_key = %d\n", xcb_is_private_keypad_key(sym));
    printf("xcb_is_cursor_key = %d\n", xcb_is_cursor_key(sym));
    printf("xcb_is_pf_key = %d\n", xcb_is_pf_key(sym));
    printf("xcb_is_function_key = %d\n", xcb_is_function_key(sym));
    printf("xcb_is_misc_function_key = %d\n", xcb_is_misc_function_key(sym));
    printf("xcb_is_modifier_key = %d\n", xcb_is_modifier_key(sym));

    if (xcb_is_modifier_key(sym) || xcb_is_cursor_key(sym))
        return 1;

    printf("sym = %c (%d)\n", sym, sym);

    /* convert the keysym to UCS */
    uint16_t ucs = keysym2ucs(sym);
    if ((int16_t)ucs == -1) {
        fprintf(stderr, "Keysym could not be converted to UCS, skipping\n");
        return 1;
    }

    xcb_char2b_t inp;
    inp.byte1 = (ucs & 0xff00) >> 2;
    inp.byte2 = (ucs & 0x00ff) >> 0;

    printf("inp.byte1 = %02x, inp.byte2 = %02x\n", inp.byte1, inp.byte2);
    /* convert it to UTF-8 */
    char *out = convert_ucs2_to_utf8(&inp, 1);
    printf("converted to %s\n", out);

    glyphs_ucs[input_position] = inp;
    glyphs_utf8[input_position] = out;
    input_position++;

    if (input_position == limit)
        finish_input();

    handle_expose(NULL, conn, NULL);
    return 1;
}