Example #1
0
int main(int argc, char *argv[])
{
	int fd;
	struct sockaddr_un sock_address;
	char msg[BUFSIZ], rsp[BUFSIZ];

	if (argc < 2) {
		err("No arguments given.\n");
	}

	sock_address.sun_family = AF_UNIX;
	char *sp;

	if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
		err("Failed to create the socket.\n");
	}

	sp = getenv(SOCKET_ENV_VAR);
	if (sp != NULL) {
		snprintf(sock_address.sun_path, sizeof(sock_address.sun_path), "%s", sp);
	} else {
		char *host = NULL;
		int dn = 0, sn = 0;
		if (xcb_parse_display(NULL, &host, &dn, &sn) != 0) {
			snprintf(sock_address.sun_path, sizeof(sock_address.sun_path), SOCKET_PATH_TPL, host, dn, sn);
		}
		free(host);
	}

	if (connect(fd, (struct sockaddr *) &sock_address, sizeof(sock_address)) == -1) {
		err("Failed to connect to the socket.\n");
	}

	argc--, argv++;
	int msg_len = 0;

	for (int offset = 0, rem = sizeof(msg), n = 0; argc > 0 && rem > 0; offset += n, rem -= n, argc--, argv++) {
		n = snprintf(msg + offset, rem, "%s%c", *argv, 0);
		msg_len += n;
	}

	if (send(fd, msg, msg_len, 0) == -1) {
		err("Failed to send the data.\n");
	}

	int ret = EXIT_SUCCESS, nb;
	while ((nb = recv(fd, rsp, sizeof(rsp)-1, 0)) > 0) {
		rsp[nb] = '\0';
		if (rsp[0] == FAILURE_MESSAGE[0]) {
			ret = EXIT_FAILURE;
			printf("%s", rsp + 1);
		} else {
			printf("%s", rsp);
		}
		fflush(stdout);
	}

	close(fd);
	return ret;
}
Example #2
0
File: bspc.c Project: nexec/bspwm
int main(int argc, char *argv[])
{
	int fd;
	struct sockaddr_un sock_address;
	char msg[BUFSIZ], rsp[BUFSIZ];

	if (argc < 2)
		err("No arguments given.\n");

	sock_address.sun_family = AF_UNIX;
	char *sp;

	if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
		err("Failed to create the socket.\n");

	sp = getenv(SOCKET_ENV_VAR);
	if (sp != NULL) {
		snprintf(sock_address.sun_path, sizeof(sock_address.sun_path), "%s", sp);
	} else {
		char *host = NULL;
		int dn = 0, sn = 0;
		if (xcb_parse_display(NULL, &host, &dn, &sn) != 0)
			snprintf(sock_address.sun_path, sizeof(sock_address.sun_path), SOCKET_PATH_TPL, host, dn, sn);
		free(host);
	}

	if (connect(fd, (struct sockaddr *) &sock_address, sizeof(sock_address)) == -1)
		err("Failed to connect to the socket.\n");

	argc--, argv++;
	int msg_len = 0;

	for (int offset = 0, rem = sizeof(msg), n = 0; argc > 0 && rem > 0; offset += n, rem -= n, argc--, argv++) {
		n = snprintf(msg + offset, rem, "%s%c", *argv, 0);
		msg_len += n;
	}

	if (send(fd, msg, msg_len, 0) == -1)
		err("Failed to send the data.\n");

	int ret = 0, nb;
	while ((nb = recv(fd, rsp, sizeof(rsp)-1, 0)) > 0) {
		if (nb == 1 && rsp[0] < MSG_LENGTH) {
			ret = rsp[0];
			if (ret == MSG_UNKNOWN) {
				warn("Unknown command.\n");
			} else if (ret == MSG_SYNTAX) {
				warn("Invalid syntax.\n");
			}
		} else {
			rsp[nb] = '\0';
			printf("%s", rsp);
			fflush(stdout);
		}
	}

	close(fd);
	return ret;
}
Example #3
0
// https://www.x.org/releases/current/doc/xproto/x11protocol.html#Encoding::Connection_Setup
static void read_client_setup_request_cb(EV_P_ ev_io *w, int revents) {
    ev_io_stop(EV_A_ w);
    struct connstate *connstate = (struct connstate *)w->data;

    /* Read X11 setup request in its entirety. */
    xcb_setup_request_t setup_request;
    must_read(readall_into(&setup_request, sizeof(setup_request), w->fd));

    /* Establish a connection to X11. */
    int fd = socket(AF_LOCAL, SOCK_STREAM, 0);
    if (fd == -1) {
        err(EXIT_FAILURE, "socket()");
    }

    char *host;
    int displayp;
    if (xcb_parse_display(getenv("DISPLAY"), &host, &displayp, NULL) == 0) {
        errx(EXIT_FAILURE, "Could not parse DISPLAY=%s", getenv("DISPLAY"));
    }
    free(host);

    struct sockaddr_un addr;
    memset(&addr, 0, sizeof(addr));
    addr.sun_family = AF_LOCAL;
    snprintf(addr.sun_path, sizeof(addr.sun_path), "/tmp/.X11-unix/X%d", displayp);
    if (connect(fd, (const struct sockaddr *)&addr, sizeof(struct sockaddr_un)) == -1) {
        err(EXIT_FAILURE, "connect(%s)", addr.sun_path);
    }

    /* Relay setup request. */
    must_write(writeall(fd, &setup_request, sizeof(setup_request)));

    if (setup_request.authorization_protocol_name_len > 0 ||
        setup_request.authorization_protocol_data_len > 0) {
        const size_t authlen = setup_request.authorization_protocol_name_len +
                               XCB_PAD(setup_request.authorization_protocol_name_len) +
                               setup_request.authorization_protocol_data_len +
                               XCB_PAD(setup_request.authorization_protocol_data_len);
        void *buf = smalloc(authlen);
        must_read(readall_into(buf, authlen, w->fd));
        must_write(writeall(fd, buf, authlen));
        free(buf);
    }

    /* Wait for a response from the X11 server. */
    ev_io *serverw = scalloc(1, sizeof(ev_io));
    connstate->serverw = serverw;
    serverw->data = connstate;
    ev_io_init(serverw, read_server_setup_reply_cb, fd, EV_READ);
    ev_io_start(EV_A_ serverw);
}
Example #4
0
File: core.hpp Project: jotrk/xpp
    // hostname, display, screen
    virtual
    std::tuple<std::string, int, int>
    parse_display(const std::string & name) const
    {
      int screen = 0;
      int display = 0;
      char * host = NULL;
      std::string hostname;

      xcb_parse_display(name.c_str(), &host, &display, &screen);
      if (host != NULL) {
        hostname = std::string(host);
      }

      return std::make_tuple(hostname, display, screen);
    }
Example #5
0
int main(int argc, char *argv[])
{
	char opt;
	char *fifo_path = NULL;
	char *socket_path = NULL;
	status_fifo = NULL;
	config_path = NULL;
	mapping_count = 0;
	timeout = TIMEOUT;
	grabbed = false;
	sock_address.sun_family = AF_UNIX;
	sock_address.sun_path[0] = 0;
	snprintf(motion_msg_tpl, sizeof(motion_msg_tpl), "%s", MOTION_MSG_TPL);
	unsigned int max_freq = 0;
	motion_interval = 0;
	last_motion_time = 0;
	redir_fd = -1;

	while ((opt = getopt(argc, argv, "vhm:t:c:r:s:f:o:g:")) != (char)-1) {
		switch (opt) {
			case 'v':
				printf("%s\n", VERSION);
				exit(EXIT_SUCCESS);
				break;
			case 'h':
				printf("sxhkd [-h|-v|-m COUNT|-t TIMEOUT|-c CONFIG_FILE|-r REDIR_FILE|-s STATUS_FIFO|-o MOTION_SOCKET|-g MOTION_MSG_TPL] [EXTRA_CONFIG ...]\n");
				exit(EXIT_SUCCESS);
				break;
			case 'm':
				if (sscanf(optarg, "%i", &mapping_count) != 1)
					warn("Can't parse mapping count.\n");
				break;
			case 't':
				timeout = atoi(optarg);
				break;
			case 'c':
				config_path = optarg;
				break;
			case 'r':
				redir_fd = open(optarg, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
				if (redir_fd == -1)
					warn("Failed to open the command redirection file.\n");
				break;
			case 's':
				fifo_path = optarg;
				break;
			case 'o':
				socket_path = optarg;
				break;
			case 'g':
				snprintf(motion_msg_tpl, sizeof(motion_msg_tpl), "%s", optarg);
				break;
			case 'f':
				if (sscanf(optarg, "%u", &max_freq) != 1)
					warn("Can't parse maximum pointer frequency.\n");
				break;
		}
	}

	num_extra_confs = argc - optind;
	extra_confs = argv + optind;

	if (config_path == NULL) {
		char *config_home = getenv(CONFIG_HOME_ENV);
		if (config_home != NULL)
			snprintf(config_file, sizeof(config_file), "%s/%s", config_home, CONFIG_PATH);
		else
			snprintf(config_file, sizeof(config_file), "%s/%s/%s", getenv("HOME"), ".config", CONFIG_PATH);
	} else {
		snprintf(config_file, sizeof(config_file), "%s", config_path);
	}

	if (socket_path == NULL) {
		socket_path = getenv(SOCKET_ENV);
	}

	if (socket_path == NULL) {
		char *host = NULL;
		int dn = 0, sn = 0;
		if (xcb_parse_display(NULL, &host, &dn, &sn) != 0) {
			snprintf(sock_address.sun_path, sizeof(sock_address.sun_path), SOCKET_PATH_TPL, host, dn, sn);
		} else {
			warn("Failed to set motion socket address.");
		}
		free(host);
	} else {
		snprintf(sock_address.sun_path, sizeof(sock_address.sun_path), "%s", socket_path);
	}

	if (fifo_path != NULL) {
		int fifo_fd = open(fifo_path, O_RDWR | O_NONBLOCK);
		if (fifo_fd != -1)
			status_fifo = fdopen(fifo_fd, "w");
		else
			warn("Couldn't open status fifo.\n");
	}

	if (max_freq != 0)
		motion_interval = 1000.0 / max_freq;

	signal(SIGINT, hold);
	signal(SIGHUP, hold);
	signal(SIGTERM, hold);
	signal(SIGUSR1, hold);
	signal(SIGUSR2, hold);
	signal(SIGALRM, hold);

	setup();
	get_standard_keysyms();
	get_lock_fields();
	escape_chord = make_chord(ESCAPE_KEYSYM, XCB_NONE, 0, XCB_KEY_PRESS, false, false);
	load_config(config_file);
	for (int i = 0; i < num_extra_confs; i++)
		load_config(extra_confs[i]);
	grab();

	xcb_generic_event_t *evt;
	int fd = xcb_get_file_descriptor(dpy);

	fd_set descriptors;

	reload = toggle_grab = bell = chained = locked = false;
	running = true;

	xcb_flush(dpy);

	while (running) {
		FD_ZERO(&descriptors);
		FD_SET(fd, &descriptors);

		if (select(fd + 1, &descriptors, NULL, NULL, NULL) > 0) {
			while ((evt = xcb_poll_for_event(dpy)) != NULL) {
				uint8_t event_type = XCB_EVENT_RESPONSE_TYPE(evt);
				switch (event_type) {
					case XCB_KEY_PRESS:
					case XCB_KEY_RELEASE:
					case XCB_BUTTON_PRESS:
					case XCB_BUTTON_RELEASE:
						key_button_event(evt, event_type);
						break;
					case XCB_MOTION_NOTIFY:
						motion_notify(evt);
						break;
					case XCB_MAPPING_NOTIFY:
						mapping_notify(evt);
						break;
					default:
						PRINTF("received event %u\n", event_type);
						break;
				}
				free(evt);
			}
		}

		if (reload) {
			signal(SIGUSR1, hold);
			reload_cmd();
			reload = false;
		}

		if (toggle_grab) {
			signal(SIGUSR2, hold);
			toggle_grab_cmd();
			toggle_grab = false;
		}

		if (bell) {
			signal(SIGALRM, hold);
			abort_chain();
			if (status_fifo != NULL)
				put_status(TIMEOUT_PREFIX, "Timeout reached");
			bell = false;
		}

		if (xcb_connection_has_error(dpy)) {
			warn("The server closed the connection.\n");
			running = false;
		}
	}

	if (redir_fd != -1)
		close(redir_fd);
	if (status_fifo != NULL)
		fclose(status_fifo);
	ungrab();
	cleanup();
	destroy_chord(escape_chord);
	xcb_key_symbols_free(symbols);
	xcb_disconnect(dpy);
	return EXIT_SUCCESS;
}
Example #6
0
static gboolean
_eventd_nd_xcb_start(EventdNdBackendContext *self, const gchar *target)
{
    gint r;
    gchar *h;
    gint d;

    r = xcb_parse_display(target, &h, &d, NULL);
    if ( r == 0 )
        return FALSE;
    free(h);

    const xcb_query_extension_reply_t *extension_query;
    gint screen;

    self->source = g_water_xcb_source_new(NULL, target, &screen, _eventd_nd_xcb_events_callback, self, NULL);
    if ( self->source == NULL )
    {
        g_warning("Couldn't initialize X connection for '%s'", target);
        return FALSE;
    }

    self->xcb_connection = g_water_xcb_source_get_connection(self->source);
    self->screen_number = screen;
    self->screen = xcb_aux_get_screen(self->xcb_connection, screen);

    self->bubbles = g_hash_table_new(NULL, NULL);

    if ( self->follow_focus != EVENTD_ND_XCB_FOLLOW_FOCUS_NONE )
    {
        guint32 mask[] = { XCB_EVENT_MASK_PROPERTY_CHANGE };
        xcb_change_window_attributes(self->xcb_connection, self->screen->root, XCB_CW_EVENT_MASK, mask);
    }

    xcb_intern_atom_cookie_t *ac;
    ac = xcb_ewmh_init_atoms(self->xcb_connection, &self->ewmh);
    xcb_ewmh_init_atoms_replies(&self->ewmh, ac, NULL);

    extension_query = xcb_get_extension_data(self->xcb_connection, &xcb_randr_id);
    if ( ! extension_query->present )
        g_warning("No RandR extension");
    else
    {
        self->randr = TRUE;
        self->randr_event_base = extension_query->first_event;
        xcb_randr_select_input(self->xcb_connection, self->screen->root,
                XCB_RANDR_NOTIFY_MASK_SCREEN_CHANGE |
                XCB_RANDR_NOTIFY_MASK_OUTPUT_CHANGE |
                XCB_RANDR_NOTIFY_MASK_CRTC_CHANGE |
                XCB_RANDR_NOTIFY_MASK_OUTPUT_PROPERTY);
    }

    self->custom_map = _eventd_nd_xcb_get_colormap(self);

    if ( self->custom_map )
    {
        /* We have a 32bit color map, try to support compositing */
        xcb_get_selection_owner_cookie_t oc;
        xcb_window_t owner;
        oc = xcb_ewmh_get_wm_cm_owner(&self->ewmh, self->screen_number);
        self->compositing = xcb_ewmh_get_wm_cm_owner_reply(&self->ewmh, oc, &owner, NULL) && ( owner != XCB_WINDOW_NONE );

        extension_query = xcb_get_extension_data(self->xcb_connection, &xcb_xfixes_id);
        if ( ! extension_query->present )
            g_warning("No XFixes extension");
        else
        {
            xcb_xfixes_query_version_cookie_t vc;
            xcb_xfixes_query_version_reply_t *r;
            vc = xcb_xfixes_query_version(self->xcb_connection, XCB_XFIXES_MAJOR_VERSION, XCB_XFIXES_MINOR_VERSION);
            r = xcb_xfixes_query_version_reply(self->xcb_connection, vc, NULL);
            if ( r == NULL )
                g_warning("Cannot get XFixes version");
            else
            {
                self->xfixes = TRUE;
                self->xfixes_event_base = extension_query->first_event;
                xcb_xfixes_select_selection_input_checked(self->xcb_connection, self->screen->root,
                    self->ewmh._NET_WM_CM_Sn[self->screen_number],
                    XCB_XFIXES_SELECTION_EVENT_MASK_SET_SELECTION_OWNER |
                    XCB_XFIXES_SELECTION_EVENT_MASK_SELECTION_WINDOW_DESTROY |
                    XCB_XFIXES_SELECTION_EVENT_MASK_SELECTION_CLIENT_CLOSE);
            }
        }
    }

    extension_query = xcb_get_extension_data(self->xcb_connection, &xcb_shape_id);
    if ( ! extension_query->present )
        g_warning("No Shape extension");
    else
        self->shape = TRUE;

    xcb_flush(self->xcb_connection);
    _eventd_nd_xcb_check_geometry(self);

    return TRUE;
}