Ejemplo n.º 1
0
int main_loop(Display *display, xcb_connection_t *connection, xcb_screen_t *screen, xcb_window_t window, GLXDrawable drawable)
{
    int running = 1;
    while (running) {
        /* Wait for event */
        xcb_generic_event_t *event = xcb_wait_for_event(connection);
        if (!event) {
            fprintf(stderr, "i/o error in xcb_wait_for_event\n");
            return -1;
        }

        switch(event->response_type & ~0x80) {
            case XCB_KEY_PRESS:
                /* Quit on key press */
                running = 0;
                break;
            case XCB_EXPOSE:
                /* Handle expose event, draw and swap buffers */
                draw(connection, screen, window);
                glXSwapBuffers(display, drawable);
                break;
            default:
                break;
        }
        free(event);
    }
    return 0;
}
Ejemplo n.º 2
0
/// X event loop
void *event_loop(void*) {
  xcb_generic_event_t *event;

  // wait for X events and process them
  while((event = xcb_wait_for_event(con))) {
      switch(event->response_type & ~0x80) {
        case XCB_EXPOSE:
          {
            xcb_expose_event_t *expose_event
              = reinterpret_cast<xcb_expose_event_t*>(event);
            
            // ignore the expose event, if there are more waiting.
            if(!expose_event->count && window && window->get_window_id() ==
               expose_event->window) window->redraw();
            break;
          }
        case XCB_CONFIGURE_NOTIFY:
          {
            xcb_configure_notify_event_t *configure_notify_event
              = reinterpret_cast<xcb_configure_notify_event_t*>(event);
            
            if(window && window->get_window_id() ==
               configure_notify_event->window)
              window->resize(configure_notify_event->width,
                             configure_notify_event->height);
            break;
          }
        default:
          // ignore
          break;
        }
      free(event);
   }
   pthread_exit(0);
}
Ejemplo n.º 3
0
void event_handler(xcb_connection_t *c, xcb_drawable_t root)
{
    xcb_generic_event_t *e;

    for (;;) {
        e = xcb_wait_for_event (c);

        switch (e->response_type & ~0x80) {
            case XCB_CONFIGURE_NOTIFY:
                printf("XCB_CONFIGURE_NOTIFY\n");
                break;
            case XCB_BUTTON_PRESS:
                //xcb_button_press_event_t *press = (xcb_button_press_event_t *)e;
                printf("XCB_BUTTON_PRESS\n");
                break;
            case XCB_KEY_PRESS:
                printf("XCB_KEY_PRESS\n");
                break;
            default:
                break;
        }

        free (e);
    }
}
Ejemplo n.º 4
0
int run(config_t* config, key_handler_t key_handler)
{
    int default_screen;
    xcb_connection_t* c = xcb_connect(NULL, &default_screen);

    if(xcb_connection_has_error(c))
    {
		fprintf(stderr, "Cannot open display %s\n",
                getenv("DISPLAY") ? getenv("DISPLAY") : "<NULL>");
        return -1;
    }
    xcb_screen_t* screen;
    if(!(screen = xcb_aux_get_screen(c, default_screen)))
    {
        fprintf(stderr, "Cannot obtain default screen.\n");
        return -1;
    }

    context_t context = { config, key_handler };

    xcb_event_handlers_t eh;
    memset(&eh, 0, sizeof(xcb_event_handlers_t));
    xcb_event_handlers_init(c, &eh);
    xcb_event_set_key_press_handler(&eh, handle_keypress, &context);

    xcb_void_cookie_t* cookies = alloca(sizeof(xcb_void_cookie_t)
                                             * config->count);
    if(!cookies)
        return -1;

    int i;
    for(i = 0; i < config->count; ++i)
        cookies[i] = xcb_grab_key(c, true, screen->root,
                                  config->keys[i].is_alt ? XCB_MOD_MASK_1 : 0,
                                  config->keys[i].keysym, XCB_GRAB_MODE_ASYNC,
                                  XCB_GRAB_MODE_ASYNC);

    for(i = 0; i < config->count; ++i)
    {
        xcb_generic_error_t* e = xcb_request_check(c, cookies[i]);
        if(e)
        {
            fprintf(stderr, "WARNING: unable to grab key: %d\n", e->error_code);
            free(e);
        }
    }

    xcb_generic_event_t* e;
    while((e = xcb_wait_for_event(c)))
    {
        xcb_event_handle(&eh, e);
        free(e);
    }

    return 0;
}
Ejemplo n.º 5
0
/**
 *  \brief The main event loop to process window messages.
 *
 *  \param [in] arg The clipboard context.
 *
 *  This thread will run indefinitely until the clipboard context's window
 *  is destroyed. It *must* receive a DestroyNotify message to end.
 */
static void *x11_event_loop(void *arg) {
    clipboard_c *cb = (clipboard_c *)arg;
    xcb_generic_event_t *e;

    while ((e = xcb_wait_for_event(cb->xc))) {
        if (e->response_type == 0) {
            /* I think this cast is appropriate... */
            xcb_generic_error_t *err = (xcb_generic_error_t *) e;
            fprintf(stderr, "x11_event_loop: [Warn] Received X11 error: %d\n", err->error_code);
            free(e); /* XCB: Do not use custom allocators */
            continue;
        }

        switch (e->response_type & ~0x80) {
            case XCB_DESTROY_NOTIFY: {
                xcb_destroy_notify_event_t *evt = (xcb_destroy_notify_event_t *)e;
                if (evt->window == cb->xw) {
                    free(e); /* XCB: Do not use custom allocators */
                    return NULL;
                }
            }
            break;
            case XCB_SELECTION_CLEAR: {
                x11_clear_selection(cb, (xcb_selection_clear_event_t *)e);
            }
            break;
            case XCB_SELECTION_NOTIFY: {
                x11_retrieve_selection(cb, (xcb_selection_notify_event_t *)e);
            }
            break;
            case XCB_SELECTION_REQUEST: {
                xcb_selection_request_event_t *req = (xcb_selection_request_event_t *)e;
                xcb_selection_notify_event_t notify = {0};
                notify.response_type = XCB_SELECTION_NOTIFY;
                notify.time = XCB_CURRENT_TIME;
                notify.requestor = req->requestor;
                notify.selection = req->selection;
                notify.target = req->target;
                notify.property = x11_transmit_selection(cb, req) ? req->property : XCB_NONE;
                xcb_send_event(cb->xc, false, req->requestor, XCB_EVENT_MASK_PROPERTY_CHANGE, (char *)&notify);
                xcb_flush(cb->xc);
            }
            break;
            case XCB_PROPERTY_NOTIFY: {
            }
            break;
            default: {
                /* Ignore unknown messages */
            }
        }
        free(e); /* XCB: Do not use custom allocators */
    }

    fprintf(stderr, "x11_event_loop: [Warn] xcb_wait_for_event returned NULL\n");
    return NULL;
}
Ejemplo n.º 6
0
Archivo: event.c Proyecto: aosm/X11libs
void
xcb_event_wait_for_event_loop(xcb_event_handlers_t *evenths)
{
    xcb_generic_event_t *event;
    while((event = xcb_wait_for_event(evenths->c)))
    {
        xcb_event_handle(evenths, event);
        free(event);
    }
}
Ejemplo n.º 7
0
Archivo: towel.c Proyecto: kanru/towel
int
main(int argc, char *argv[])
{
  /* TODO: Accept DISPLAY environment or --display arguments */
  xcb_connection_t *conn = xcb_connect(NULL, NULL);
  towel_window_t *win = NULL;

  for (;;) {
    if (win == NULL) {
      win = towel_create_window(conn);
      towel_window_hide_cursor(win);
    }
    sleep(CHECK_PERIOD);
    towel_window_update_working_time(win, CHECK_PERIOD);
    if (win->idle_time > REST_TIME)
      win->working_time = 0;

    /* TODO: option processing */
    if (win->working_time > WORKING_TIME) {
      time_t prev = time(NULL);
      towel_window_map(win);
      xcb_flush(conn);
      for (;;) {
        xcb_generic_event_t *event = xcb_wait_for_event(conn);
        if ((event->response_type & ~0x80) == XCB_EXPOSE) {
#if !DEBUG
          towel_window_grab_input(win);
#endif
          towel_window_render_time(win, REST_TIME);
          xcb_flush(conn);
          break;
        }
        free(event);
      }
      for (;;) {
        int delta = time(NULL) - prev;
        towel_window_render_time(win, REST_TIME - delta);
        xcb_flush(conn);
        if (delta >= REST_TIME) {
          towel_window_unmap(win);
          towel_window_destroy(win);
          win = NULL;
          xcb_flush(conn);
          break;
        }
        sleep(1);
      }
    }
  }

  if (win)
    towel_window_destroy(win);
  xcb_disconnect(conn);
  return EXIT_SUCCESS;
}
Ejemplo n.º 8
0
int
main(void)
{
    xcb_connection_t *conn;
    xcb_screen_t *root;
    xcb_window_t window;
    uint32_t mask;
    uint32_t values[5];
    xcb_generic_event_t *event;
    struct xamine_context *ctx;
    struct xamine_conversation *conversation;

    conn = xcb_connect(NULL, NULL);
    root = xcb_setup_roots_iterator(xcb_get_setup(conn)).data;
    window = xcb_generate_id(conn);
    mask = XCB_CW_BACK_PIXEL | XCB_CW_BORDER_PIXEL | XCB_CW_BACKING_STORE | XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK;
    values[0] = root->white_pixel;
    values[1] = root->black_pixel;
    values[2] = XCB_BACKING_STORE_ALWAYS;
    values[3] = 0;
    values[4] = AllEventsMask;
    xcb_create_window(conn, 0, window, root->root, 0, 0, 256, 256, 10, XCB_WINDOW_CLASS_INPUT_OUTPUT, root->root_visual, mask, values);
    xcb_map_window(conn, window);
    xcb_flush(conn);

    ctx = xamine_context_new(0);
    conversation = xamine_conversation_new(ctx, 0);

    while ((event = xcb_wait_for_event(conn)) != NULL) {
        struct xamine_item *item = xamine_examine(conversation, XAMINE_RESPONSE, event, 32);
        free(event);

        print_tree(item, 0);

        /* Exit on ESC. */
        if (strcmp(item->definition->name, "KeyPress") == 0 &&
            item->child->next->u.unsigned_value == 9) {
            xamine_item_free(item);
            break;
        }

        xamine_item_free(item);
    }

    xamine_conversation_unref(conversation);
    xamine_context_unref(ctx);
    xcb_disconnect(conn);
    xmlCleanupParser();

    return 0;
}
Ejemplo n.º 9
0
/*
 * This function is called from a fork()ed child and will raise the i3lock
 * window when the window is obscured, even when the main i3lock process is
 * blocked due to PAM.
 *
 */
static void raise_loop(xcb_window_t window) {
    xcb_connection_t *conn;
    xcb_generic_event_t *event;
    int screens;

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

    /* We need to know about the window being obscured or getting destroyed. */
    xcb_change_window_attributes(conn, window, XCB_CW_EVENT_MASK,
                                 (uint32_t[]){XCB_EVENT_MASK_VISIBILITY_CHANGE |
                                              XCB_EVENT_MASK_STRUCTURE_NOTIFY});
    xcb_flush(conn);

    DEBUG("Watching window 0x%08x\n", window);
    while ((event = xcb_wait_for_event(conn)) != NULL) {
        if (event->response_type == 0) {
            xcb_generic_error_t *error = (xcb_generic_error_t *)event;
            DEBUG("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);
        DEBUG("Read event of type %d\n", type);
        switch (type) {
            case XCB_VISIBILITY_NOTIFY:
                handle_visibility_notify(
                    conn, (xcb_visibility_notify_event_t *)event);
                break;
            case XCB_UNMAP_NOTIFY:
                DEBUG("UnmapNotify for 0x%08x\n",
                      (((xcb_unmap_notify_event_t *)event)->window));
                if (((xcb_unmap_notify_event_t *)event)->window == window)
                    exit(EXIT_SUCCESS);
                break;
            case XCB_DESTROY_NOTIFY:
                DEBUG("DestroyNotify for 0x%08x\n",
                      (((xcb_destroy_notify_event_t *)event)->window));
                if (((xcb_destroy_notify_event_t *)event)->window == window)
                    exit(EXIT_SUCCESS);
                break;
            default:
                DEBUG("Unhandled event type %d\n", type);
                break;
        }
        free(event);
    }
}
void ShellXcb::loop_wait() {
    while (true) {
        xcb_generic_event_t *ev = xcb_wait_for_event(c_);
        if (!ev) continue;

        handle_event(ev);
        free(ev);

        if (quit_) break;

        acquire_back_buffer();
        present_back_buffer();
    }
}
Ejemplo n.º 11
0
Archivo: event.c Proyecto: nqv/nilwm
/** Events loop
 */
void recv_events() {
    xcb_generic_event_t *e;
    unsigned int type;
    while ((e = xcb_wait_for_event(nil_.con))) {
        type = e->response_type & ~0x80;
        if (type < NIL_LEN(HANDLERS_) && HANDLERS_[type] != 0) {
            (*HANDLERS_[type])(e);
        } else {
            NIL_LOG("event: unknown type %u", type);
        }
        /* Free the Generic Event */
        free(e);
    }
}
Ejemplo n.º 12
0
void NGBMainLoop()
{
	while((event = xcb_wait_for_event(con)))
	{
		switch(event->response_type & ~0x80)
		{
		case XCB_EXPOSE:
			//xcb_poly_point(con, XCB_COORD_MODE_ORIGIN, win, foreground, 4, points);
			DisplayFunc();
			xcb_flush(con);
			break;
		default:
			break;
		}
	}
}
Ejemplo n.º 13
0
void event_loop(xcb_window_t window, xcb_gcontext_t graphics_context) {
  xcb_generic_event_t *event;
  xcb_rectangle_t r = { 20, 20, 60, 60 };
  
  while(event = xcb_wait_for_event(connection)) {
    switch(event->response_type) {
    case XCB_EXPOSE:
      xcb_poly_fill_rectangle(connection, window, graphics_context, 1, &r);
      xcb_flush(connection);
      
      break;
    case XCB_KEY_PRESS:
      return;
    }
  }
}
Ejemplo n.º 14
0
void EventReader::run()
{
    Qt::MouseButtons buttons;

    xcb_generic_event_t *event;
    while (running.load() && (event = xcb_wait_for_event(m_hooks->connection()))) {
        uint response_type = event->response_type & ~0x80;
        switch (response_type) {
        case XCB_BUTTON_PRESS: {
            xcb_button_press_event_t *press = (xcb_button_press_event_t *)event;
            QPoint p(press->event_x, press->event_y);
            buttons = (buttons & ~0x7) | translateMouseButtons(press->state);
            buttons |= translateMouseButton(press->detail);
            QWindowSystemInterface::handleMouseEvent(0, press->time, p, p, buttons);
            break;
            }
        case XCB_BUTTON_RELEASE: {
            xcb_button_release_event_t *release = (xcb_button_release_event_t *)event;
            QPoint p(release->event_x, release->event_y);
            buttons = (buttons & ~0x7) | translateMouseButtons(release->state);
            buttons &= ~translateMouseButton(release->detail);
            QWindowSystemInterface::handleMouseEvent(0, release->time, p, p, buttons);
            break;
            }
        case XCB_MOTION_NOTIFY: {
            xcb_motion_notify_event_t *motion = (xcb_motion_notify_event_t *)event;
            QPoint p(motion->event_x, motion->event_y);
            QWindowSystemInterface::handleMouseEvent(0, motion->time, p, p, buttons);
            break;
            }
        case XCB_CLIENT_MESSAGE: {
            xcb_client_message_event_t *client = (xcb_client_message_event_t *) event;
            const xcb_atom_t *atoms = m_hooks->atoms();
            if (client->format == 32
                && client->type == atoms[Atoms::WM_PROTOCOLS]
                && client->data.data32[0] == atoms[Atoms::WM_DELETE_WINDOW]) {
                QWindow *window = m_hooks->platformWindow() ? m_hooks->platformWindow()->window() : 0;
                if (window)
                    QWindowSystemInterface::handleCloseEvent(window);
            }
            break;
            }
        default:
            break;
        }
    }
}
Ejemplo n.º 15
0
Archivo: wew.c Proyecto: laserswald/opt
void
handle_events(void)
{
	int i, wn;
	xcb_window_t *wc, wid = 0;
	xcb_generic_event_t *e;
	xcb_create_notify_event_t *ec;

	/*
	 * We need to get notifed of window creations, no matter what, because
	 * we need to register the event mask on all newly created windows
	 */
	register_events(scr->root, XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY);

	if (mask & XCB_EVENT_MASK_BUTTON_PRESS) {
		xcb_grab_button(conn, 0, scr->root,
		                XCB_EVENT_MASK_BUTTON_PRESS |
		                XCB_EVENT_MASK_BUTTON_RELEASE,
		                XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC,
		                scr->root, XCB_NONE, 1, XCB_NONE);
	}

	/* register the events on all mapped windows */
	wn = get_windows(conn, scr->root, &wc);
	for (i=0; i<wn; i++)
		register_events(wc[i], mask);

	xcb_flush(conn);

	for(;;) {
		e = xcb_wait_for_event(conn);

		switch (e->response_type & ~0x80)
		{
			case XCB_CREATE_NOTIFY:
				ec = (xcb_create_notify_event_t*)e;
				register_events(ec->window, mask);
			default:
				wid = get_window_id(e);
		}

		if (wid > 0) {
			printf("%d:0x%08x\n", e->response_type, wid);
			fflush(stdout);
		}
	}
}
Ejemplo n.º 16
0
int main(void)
{
	xcb_connection_t *dpy = xcb_connect(NULL, NULL);
	if (dpy == NULL) {
		fprintf(stderr, "Can't connect to X.\n");
		return EXIT_FAILURE;
	}
	xcb_atom_t WM_PROTOCOLS, WM_DELETE_WINDOW;
	if (!get_atom(dpy, "WM_PROTOCOLS", &WM_PROTOCOLS) ||
	    !get_atom(dpy, "WM_DELETE_WINDOW", &WM_DELETE_WINDOW)) {
		fprintf(stderr, "Can't get required atoms.\n");
		xcb_disconnect(dpy);
		return EXIT_FAILURE;
	}
	xcb_screen_t *screen = xcb_setup_roots_iterator(xcb_get_setup(dpy)).data;
	if (screen == NULL) {
		fprintf(stderr, "Can't get current screen.\n");
		xcb_disconnect(dpy);
		return EXIT_FAILURE;
	}
	xcb_window_t win = xcb_generate_id(dpy);
	uint32_t mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
	uint32_t values[] = {0xff111111, XCB_EVENT_MASK_EXPOSURE};
	xcb_create_window(dpy, XCB_COPY_FROM_PARENT, win, screen->root, 0, 0, 320, 240, 2,
	                  XCB_WINDOW_CLASS_INPUT_OUTPUT, XCB_COPY_FROM_PARENT, mask, values);
	xcb_icccm_set_wm_class(dpy, win, sizeof(TEST_WINDOW_IC), TEST_WINDOW_IC);
	xcb_map_window(dpy, win);
	xcb_flush(dpy);
	xcb_generic_event_t *evt;
	bool running = true;
	while (running && (evt = xcb_wait_for_event(dpy)) != NULL) {
		uint8_t rt = XCB_EVENT_RESPONSE_TYPE(evt);
		if (rt == XCB_CLIENT_MESSAGE)  {
			xcb_client_message_event_t *cme = (xcb_client_message_event_t *) evt;
			if (cme->type == WM_PROTOCOLS && cme->data.data32[0] == WM_DELETE_WINDOW) {
				running = false;
			}
		} else if (rt == XCB_EXPOSE) {
			render_text(dpy, win, 12, 24);
		}
		free(evt);
	}
	xcb_destroy_window(dpy, win);
	xcb_disconnect(dpy);
	return EXIT_SUCCESS;
}
Ejemplo n.º 17
0
int main() {

    xcb_connection_t    *conn        = xcb_connect(NULL, NULL);
    xcb_screen_t        *screen      = xcb_setup_roots_iterator(xcb_get_setup(conn)).data;
    xcb_drawable_t      win          = screen->root;
    xcb_gcontext_t      fg           = xcb_generate_id(conn);

    uint32_t    mask        = XCB_GC_FOREGROUND | XCB_GC_GRAPHICS_EXPOSURES;
    uint32_t    values[2]   = { screen->black_pixel, 0 };

    xcb_create_gc(conn, fg, win, mask, values);

    win         = xcb_generate_id(conn);
    mask        = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
    values[0]   = screen->white_pixel;
    values[1]   = XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_BUTTON_PRESS;

    xcb_create_window(conn, XCB_COPY_FROM_PARENT, win, screen->root, x, y, w, h, bw,
            XCB_WINDOW_CLASS_INPUT_OUTPUT, screen->root_visual, mask, values);

    xcb_map_window(conn, win);
    xcb_flush(conn);

    xcb_generic_event_t *event;
    // xcb_poll_for_event does not block, so this will only catch the EXPOSE event then die out.
    // If we used xcb_wait_for_event, we'd block, thus continuing the loop and would actually
    // have a window to receive a possible XCB_BUTTON_PRESS.
    while ((event = xcb_wait_for_event(conn))) {
        switch (event->response_type & ~0x80) {
            case XCB_EXPOSE:
                printf("Expose event\n");
                xcb_flush(conn);
                break;
            case XCB_BUTTON_PRESS:
                printf("Button press\n");
                xcb_flush(conn);
                break;
            default:
                printf("Some otherrr event\n");
                break;
        }
        free(event);
    }
    return 0;
}
Ejemplo n.º 18
0
void event_loop(xcb_window_t window, xcb_gcontext_t graphics_context, xcb_pixmap_t pixmap) {
  xcb_generic_event_t *event;
  
  while(event = xcb_wait_for_event(connection)) {
    switch(event->response_type) {
    case XCB_EXPOSE:
      xcb_copy_area(connection,
		    pixmap, window, graphics_context,
		    0, 0, 0, 0,
		    neko_width, neko_height);
      xcb_flush(connection);
      
      break;
    case XCB_KEY_PRESS:
      return;
    }
  }
}
Ejemplo n.º 19
0
void event_loop() {
  xcb_generic_event_t *e;
  while ((e = xcb_wait_for_event (c))) {
    switch (e->response_type & ~0x80) {

      /* ESC to exit */
    case XCB_KEY_PRESS: {
      xcb_key_press_event_t *ev;
      ev = (xcb_key_press_event_t *)e;
      if (ev->detail == 9) return;
      break;
    }

    }
    free (e);
  }
  
}
Ejemplo n.º 20
0
bool X11AppContext::dispatchLoop(LoopControl& control)
{
	X11LoopImpl loopImpl(control, xConnection(), xDummyWindow());

	while(loopImpl.run.load())
	{
		while(auto func = loopImpl.popFunction()) func();

		xcb_generic_event_t* event = xcb_wait_for_event(xConnection_);
		if(!event && !checkErrorWarn()) return false;

		processEvent(static_cast<const x11::GenericEvent&>(*event));
		free(event);
		xcb_flush(&xConnection());
	}

	return true;
}
Ejemplo n.º 21
0
void KbdStateListener::run()
{

#ifdef USE_XCB
    conn = xcb_connect(0,0);
    xcb_void_cookie_t ck = xcb_xkb_select_events(conn, XCB_XKB_ID_USE_CORE_KBD, XCB_EVENT_MASK_KEYMAP_STATE, 0,0,XCB_EVENT_MASK_KEYMAP_STATE,0,0);
    xcb_request_check(conn,ck);
    forever{ break; //something is wrong, probably xcb_xkb_select_events is not used properly (any docs somewhere???)
        xcb_wait_for_event(conn);

#else
    dpy = XOpenDisplay(0);
    XkbSelectEvents((Display *)dpy, XkbUseCoreKbd, XkbStateNotifyMask, XkbStateNotifyMask);
    forever{
        XEvent xev;
        XNextEvent((Display *)dpy,&xev);

#endif
        emit eventRecived();
    }

}
Ejemplo n.º 22
0
static void
_e_alert_run(void)
{
   xcb_generic_event_t *event = NULL;

   xcb_flush(conn);
   while ((event = xcb_wait_for_event(conn)))
     {
        switch (event->response_type & ~0x80)
          {
           case XCB_BUTTON_PRESS:
             ret = _e_alert_handle_button_press(event);
             break;

           case XCB_KEY_PRESS:
             ret = _e_alert_handle_key_press(event);
             break;

           case XCB_EXPOSE:
           {
              xcb_expose_event_t *ev;

              ev = (xcb_expose_event_t *)event;
              if (ev->window != win) break;

              _e_alert_draw();
              _e_alert_sync();

              break;
           }

           default:
             break;
          }
        free(event);
        if (ret > 0) return;
     }
}
static void process_events(xcb_connection_t *c,
			   xcb_gcontext_t g,
			   xcb_window_t w,
			   xcb_pixmap_t p,
			   uint32_t width,
			   uint32_t height) {
    xcb_generic_event_t *e;
    xcb_void_cookie_t cookie;

    while ((e = xcb_wait_for_event(c))) {
	uint32_t r = XCB_EVENT_RESPONSE_TYPE(e);
	xcb_generic_error_t *err;
	
	fprintf(stderr, "event %d\n", r);
	switch (r) {
	case XCB_EXPOSE:
	case XCB_MAP_NOTIFY:
	    cookie = xcb_copy_area_checked(c, p, w, g,
					   0, 0, 0, 0,
					   width, height);
	    assert(!xcb_request_check(c, cookie));
	    break;
	case XCB_BUTTON_PRESS:
	    exit(0);
	    break;
	case 0:
	    err = (xcb_generic_error_t *) e;
	    printf("error: %d (sequence %d)\n",
		   err->error_code, (unsigned int) err->full_sequence);
	    exit(1);
	default:
	    break;
	}
	free(e);
    }
}
Ejemplo n.º 24
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.º 25
0
int main(void)
{
	xcb_connection_t    *c;
	xcb_screen_t        *s;
	xcb_window_t         w;
	xcb_gcontext_t       g;
	xcb_generic_event_t *e;
	uint32_t             mask;
	uint32_t             values[4];
  int done =0 ;

	signal(SIGSEGV, handler);
	/* open connection with the server */
	c = xcb_connect(NULL,NULL);
	if (xcb_connection_has_error(c)) {
		printf("Cannot open display\n");
		exit(1);
	}

	/* get the first screen */
	s = xcb_setup_roots_iterator( xcb_get_setup(c) ).data;

  xcb_get_geometry_reply_t *geo;

  
  /* create sub window */
  w= xcb_generate_id(c);
	mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
	values[0] = s->black_pixel;
	values[1] = XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_KEY_PRESS;
  xcb_void_cookie_t cookie;

  int width =640;
  int height =480;
	mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
	values[0] = s->white_pixel;
	values[1] = XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_KEY_PRESS
    | XCB_EVENT_MASK_VISIBILITY_CHANGE    
    ;
	values[1] = 0xffff;
	xcb_create_window(c, s->root_depth, w, s->root,
      10, 10, width, height,
      1,
			XCB_WINDOW_CLASS_INPUT_OUTPUT, s->root_visual,
			mask, values);

  xcb_map_window(c, w); xcb_flush(c);

//  xcb_reparent_window(c, child,  G.s->root,100,100);

  values[1] |= XCB_EVENT_MASK_POINTER_MOTION |
     XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE;
  xcb_change_window_attributes_checked(c, w, mask, values); xcb_flush(c);

	G.conn = c;
	G.s = s;
  create_dri_drawable();

  printf("wait event\n");
  while (!done ) {
		//printf("\re=>(x%x)", e->response_type); fflush(stdout);
    e = xcb_wait_for_event(c);
    if(!e) { printf("wait event error\n");
    	break;}
    else{
      switch (e->response_type & ~0x80) {
        case XCB_EXPOSE:    /* draw or redraw the window */
          printf("XCB_EXPOSE\n");
   //     draw_gc(w);
          break;
        case XCB_KEY_PRESS:  /* exit on key press */
          printf("KEY\n");
        	struct xcb_key_press_event_t  *ep = e;
        	printf("key=%d\n", (char)ep->detail);
        	if(ep->detail == 9)
        		exit(1);
					draw_gc(w);
          //gwj done = 1;
          break;
			case XCB_MOTION_NOTIFY:
				{
          printf("XCB_MOTION\n");
					}
          break;
			default:
          printf("default e=%d\n",e->response_type);
					break;
      }
      free(e);
    }
  }
  xcb_unmap_window(c, w);
  xcb_destroy_window(c, w);
  return 0;
}
Ejemplo n.º 26
0
void track_pointer(coordinates_t loc, pointer_action_t pac, xcb_point_t pos)
{
	node_t *n = loc.node;
	resize_handle_t rh = get_handle(loc.node, pos, pac);

	uint16_t last_motion_x = pos.x, last_motion_y = pos.y;
	xcb_timestamp_t last_motion_time = 0;

	xcb_generic_event_t *evt = NULL;

	grabbing = true;
	grabbed_node = n;

	do {
		free(evt);
		while ((evt = xcb_wait_for_event(dpy)) == NULL) {
			xcb_flush(dpy);
		}
		uint8_t resp_type = XCB_EVENT_RESPONSE_TYPE(evt);
		if (resp_type == XCB_MOTION_NOTIFY) {
			xcb_motion_notify_event_t *e = (xcb_motion_notify_event_t*) evt;
			uint32_t dtime = e->time - last_motion_time;
			if (dtime < pointer_motion_interval) {
				continue;
			}
			last_motion_time = e->time;
			int16_t dx = e->root_x - last_motion_x;
			int16_t dy = e->root_y - last_motion_y;
			if (pac == ACTION_MOVE) {
				move_client(&loc, dx, dy);
			} else {
				resize_client(&loc, rh, e->root_x, e->root_y, false);
			}
			last_motion_x = e->root_x;
			last_motion_y = e->root_y;
			xcb_flush(dpy);
		} else if (resp_type == XCB_BUTTON_RELEASE) {
			grabbing = false;
		} else {
			handle_event(evt);
		}
	} while (grabbing && grabbed_node != NULL);
	free(evt);

	xcb_ungrab_pointer(dpy, XCB_CURRENT_TIME);

	if (grabbed_node == NULL) {
		grabbing = false;
		return;
	}

	if (pac == ACTION_MOVE) {
		put_status(SBSC_MASK_POINTER_ACTION, "pointer_action 0x%08X 0x%08X 0x%08X move end\n", loc.monitor->id, loc.desktop->id, n->id);
	} else if (pac == ACTION_RESIZE_CORNER) {
		put_status(SBSC_MASK_POINTER_ACTION, "pointer_action 0x%08X 0x%08X 0x%08X resize_corner end\n", loc.monitor->id, loc.desktop->id, n->id);
	} else if (pac == ACTION_RESIZE_SIDE) {
		put_status(SBSC_MASK_POINTER_ACTION, "pointer_action 0x%08X 0x%08X 0x%08X resize_side end\n", loc.monitor->id, loc.desktop->id, n->id);
	}

	xcb_rectangle_t r = get_rectangle(NULL, NULL, n);

	put_status(SBSC_MASK_NODE_GEOMETRY, "node_geometry 0x%08X 0x%08X 0x%08X %ux%u+%i+%i\n", loc.monitor->id, loc.desktop->id, loc.node->id, r.width, r.height, r.x, r.y);

	if ((pac == ACTION_MOVE && IS_TILED(n->client)) ||
	    ((pac == ACTION_RESIZE_CORNER || pac == ACTION_RESIZE_SIDE) &&
	     n->client->state == STATE_TILED)) {
		for (node_t *f = first_extrema(loc.desktop->root); f != NULL; f = next_leaf(f, loc.desktop->root)) {
			if (f == n || f->client == NULL || !IS_TILED(f->client)) {
				continue;
			}
			xcb_rectangle_t r = f->client->tiled_rectangle;
			put_status(SBSC_MASK_NODE_GEOMETRY, "node_geometry 0x%08X 0x%08X 0x%08X %ux%u+%i+%i\n", loc.monitor->id, loc.desktop->id, f->id, r.width, r.height, r.x, r.y);
		}
	}
}
Ejemplo n.º 27
0
xcb_window_t Select_Window(xcb_connection_t *dpy,
			   const xcb_screen_t *screen,
			   int descend)
{
    xcb_cursor_t cursor;
    xcb_generic_event_t *event;
    xcb_window_t target_win = XCB_WINDOW_NONE;
    xcb_window_t root = screen->root;
    int buttons = 0;
    xcb_generic_error_t *err;
    xcb_grab_pointer_cookie_t grab_cookie;
    xcb_grab_pointer_reply_t *grab_reply;

    /* Make the target cursor */
    cursor = Create_Font_Cursor (dpy, XC_crosshair);

    /* Grab the pointer using target cursor, letting it room all over */
    grab_cookie = xcb_grab_pointer
	(dpy, False, root,
	 XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE,
	 XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC,
	 root, cursor, XCB_TIME_CURRENT_TIME);
    grab_reply = xcb_grab_pointer_reply (dpy, grab_cookie, &err);
    if (grab_reply->status != XCB_GRAB_STATUS_SUCCESS)
	Fatal_Error ("Can't grab the mouse.");

    /* Let the user select a window... */
    while ((target_win == XCB_WINDOW_NONE) || (buttons != 0)) {
	/* allow one more event */
	xcb_allow_events (dpy, XCB_ALLOW_SYNC_POINTER, XCB_TIME_CURRENT_TIME);
	xcb_flush (dpy);
	event = xcb_wait_for_event (dpy);
	switch (event->response_type & 0x7f) {
	case XCB_BUTTON_PRESS:
	{
	    xcb_button_press_event_t *bp = (xcb_button_press_event_t *)event;

	    if (target_win == XCB_WINDOW_NONE) {
		target_win = bp->child; /* window selected */
		if (target_win == XCB_WINDOW_NONE)
		    target_win = root;
	    }
	    buttons++;
	    break;
	}
	case XCB_BUTTON_RELEASE:
	    if (buttons > 0) /* there may have been some down before we started */
		buttons--;
	    break;
	default:
	    /* just discard all other events */
	    break;
	}
	free (event);
    }

    xcb_ungrab_pointer (dpy, XCB_TIME_CURRENT_TIME); /* Done with pointer */

    if (!descend || (target_win == root))
	return (target_win);

    target_win = Find_Client (dpy, root, target_win);

    return (target_win);
}
Ejemplo n.º 28
0
void *
run_event_loop(void *thread_arg_struct)
{
    _connection_data *conn_data;
    xcwm_context_t *context;
    xcb_connection_t *event_conn;
    xcb_generic_event_t *evt;
    xcwm_event_t return_evt;
    xcwm_event_cb_t callback_ptr;

    conn_data = thread_arg_struct;
    context = conn_data->context;
    event_conn = context->conn;
    callback_ptr = conn_data->callback;

    free(thread_arg_struct);

    _xcwm_windows_adopt(context, callback_ptr);

    /* Start the event loop, and flush if first */
    xcb_flush(event_conn);

    while ((evt = xcb_wait_for_event(event_conn))) {
        uint8_t response_type = evt->response_type  & ~0x80;
        if (response_type == context->damage_event_mask) {
            xcb_damage_notify_event_t *dmgevnt =
                (xcb_damage_notify_event_t *)evt;

            /* printf("damage %d,%d @ %d,%d reported against window 0x%08x\n", */
            /*        dmgevnt->area.width, dmgevnt->area.height, dmgevnt->area.x, dmgevnt->area.y, */
            /*        dmgevnt->drawable); */

            xcwm_window_t *window = _xcwm_get_window_node_by_window_id(dmgevnt->drawable);

            return_evt.event_type = XCWM_EVENT_WINDOW_DAMAGE;
            return_evt.window = window;

            if (!window) {
                printf("damage reported against unknown window 0x%08x\n", dmgevnt->drawable);
                continue;
            }

            /* Increase the damaged area of window if new damage is
             * larger than current. */
            xcwm_event_get_thread_lock();

            /* Initial damage events for override-redirect windows are
             * reported relative to the root window, subsequent events
             * are relative to the window itself. We also catch cases
             * where the damage area is larger than the bounds of the
             * window. */
            if (window->initial_damage == 1
                || (dmgevnt->area.width > window->bounds.width)
                || (dmgevnt->area.height > window->bounds.height) ) {
                xcb_xfixes_region_t region =
                    xcb_generate_id(window->context->conn);
                xcb_rectangle_t rect;

                /* printf("initial damage on window 0x%08x\n", dmgevnt->drawable); */

                /* Remove the damage */
                xcb_xfixes_create_region(window->context->conn,
                                         region,
                                         1,
                                         &dmgevnt->area);
                xcb_damage_subtract(window->context->conn,
                                    window->damage,
                                    region,
                                    XCB_NONE);

                /* Add new damage area for entire window */
                rect.x = 0;
                rect.y = 0;
                rect.width = window->bounds.width;
                rect.height = window->bounds.height;
                xcb_xfixes_set_region(window->context->conn,
                                      region,
                                      1,
                                      &rect);
                xcb_damage_add(window->context->conn,
                               window->window_id,
                               region);

                window->initial_damage = 0;
                xcb_xfixes_destroy_region(window->context->conn,
                                          region);
                xcwm_event_release_thread_lock();
                continue;
            }

            window->dmg_bounds.x = dmgevnt->area.x;
            window->dmg_bounds.y = dmgevnt->area.y;
            window->dmg_bounds.width = dmgevnt->area.width;
            window->dmg_bounds.height = dmgevnt->area.height;

            xcwm_event_release_thread_lock();

            callback_ptr(&return_evt);

        }
        else if (response_type == context->shape_event) {
            xcb_shape_notify_event_t *shapeevnt =
                (xcb_shape_notify_event_t *)evt;

            if (shapeevnt->shape_kind == XCB_SHAPE_SK_BOUNDING) {
                xcwm_window_t *window = _xcwm_get_window_node_by_window_id(shapeevnt->affected_window);
                _xcwm_window_set_shape(window, shapeevnt->shaped);

                return_evt.event_type = XCWM_EVENT_WINDOW_SHAPE;
                return_evt.window = window;
                callback_ptr(&return_evt);
            }
        }
        else if (response_type == context->fixes_event_base + XCB_XFIXES_CURSOR_NOTIFY) {
            /* xcb_xfixes_cursor_notify_event_t *cursorevnt = */
            /*     (xcb_xfixes_cursor_notify_event_t *)evt; */

            return_evt.event_type = XCWM_EVENT_CURSOR;
            return_evt.window = NULL;
            callback_ptr(&return_evt);
        }
        else {
            switch (response_type) {
            case 0:
            {
                /* Error case. Something very bad has happened. Spit
                 * out some hopefully useful information and then
                 * die.
                 * FIXME: Decide under what circumstances we should
                 * acutally kill the application. */
                xcb_generic_error_t *err = (xcb_generic_error_t *)evt;
                fprintf(stderr, "Error received in event loop.\n"
                        "Error code: %i\n",
                        err->error_code);
                if ((err->error_code >= XCB_VALUE)
                    && (err->error_code <= XCB_FONT)) {
                    xcb_value_error_t *val_err = (xcb_value_error_t *)evt;
                    fprintf(stderr, "Bad value: %i\n"
                            "Major opcode: %i\n"
                            "Minor opcode: %i\n",
                            val_err->bad_value,
                            val_err->major_opcode,
                            val_err->minor_opcode);
                }
                break;
            }

            case XCB_EXPOSE:
            {
                xcb_expose_event_t *exevnt = (xcb_expose_event_t *)evt;

                printf(
                    "Window %u exposed. Region to be redrawn at location (%d, %d), ",
                    exevnt->window, exevnt->x, exevnt->y);
                printf("with dimensions (%d, %d).\n", exevnt->width,
                       exevnt->height);

                return_evt.event_type = XCWM_EVENT_WINDOW_EXPOSE;
                callback_ptr(&return_evt);
                break;
            }

            case XCB_CREATE_NOTIFY:
            {
                /* We don't actually allow our client to create its
                 * window here, wait until the XCB_MAP_REQUEST */
                break;
            }

            case XCB_DESTROY_NOTIFY:
            {
                // Window destroyed in root window
                xcb_destroy_notify_event_t *notify =
                    (xcb_destroy_notify_event_t *)evt;
                xcwm_window_t *window =
                    _xcwm_window_remove(event_conn, notify->window);

                if (!window) {
                    /* Not a window in the list, don't try and destroy */
                    break;
                }

                return_evt.event_type = XCWM_EVENT_WINDOW_DESTROY;
                return_evt.window = window;

                callback_ptr(&return_evt);

                // Release memory for the window
                _xcwm_window_release(window);
                break;
            }

            case XCB_MAP_NOTIFY:
            {
                xcb_map_notify_event_t *notify =
                    (xcb_map_notify_event_t *)evt;

                /* notify->event holds parent of the window */

                xcwm_window_t *window =
                    _xcwm_get_window_node_by_window_id(notify->window);
                if (!window)
                {
                    /*
                      No MAP_REQUEST for override-redirect windows, so
                      need to create the xcwm_window_t for it now
                    */
                    /* printf("MAP_NOTIFY without MAP_REQUEST\n"); */
                    window =
                        _xcwm_window_create(context, notify->window,
                                            notify->event);

                    if (window)
                    {
                        _xcwm_window_composite_pixmap_update(window);

                        return_evt.window = window;
                        return_evt.event_type = XCWM_EVENT_WINDOW_CREATE;
                        callback_ptr(&return_evt);
                    }
                }
                else
                {
                    _xcwm_window_composite_pixmap_update(window);
                }

                break;
            }

            case XCB_MAP_REQUEST:
            {
                xcb_map_request_event_t *request =
                    (xcb_map_request_event_t *)evt;

                /* Map the window */
                xcb_map_window(context->conn, request->window);
                xcb_flush(context->conn);

                return_evt.window =
                    _xcwm_window_create(context, request->window,
                                        request->parent);
                if (!return_evt.window) {
                    break;
                }

                return_evt.event_type = XCWM_EVENT_WINDOW_CREATE;
                callback_ptr(&return_evt);
                break;
            }

            case XCB_UNMAP_NOTIFY:
            {
                xcb_unmap_notify_event_t *notify =
                    (xcb_unmap_notify_event_t *)evt;

                xcwm_window_t *window =
                    _xcwm_window_remove(event_conn, notify->window);

                if (!window) {
                    /* Not a window in the list, don't try and destroy */
                    break;
                }

                return_evt.event_type = XCWM_EVENT_WINDOW_DESTROY;
                return_evt.window = window;

                callback_ptr(&return_evt);

                _xcwm_window_composite_pixmap_release(window);

                // Release memory for the window
                _xcwm_window_release(window);
                break;
            }

            case XCB_CONFIGURE_NOTIFY:
            {
                xcb_configure_notify_event_t *request =
                    (xcb_configure_notify_event_t *)evt;

                printf("CONFIGURE_NOTIFY: XID 0x%08x %dx%d @ %d,%d\n",
                       request->window, request->width, request->height,
                       request->x, request->y);

                xcwm_window_t *window =
                    _xcwm_get_window_node_by_window_id(request->window);
                if (window)
                    _xcwm_window_composite_pixmap_update(window);
                break;
            }

            case XCB_CONFIGURE_REQUEST:
            {
                xcb_configure_request_event_t *request =
                    (xcb_configure_request_event_t *)evt;

                printf("CONFIGURE_REQUEST: XID 0x%08x %dx%d @ %d,%d mask 0x%04x\n",
                       request->window, request->width, request->height,
                       request->x, request->y, request->value_mask);

                /*
                   relying on the server's idea of the current values of values not
                   in value_mask is a bad idea, we might have a configure request of
                   our own on this window in flight
                */
                if (request->value_mask &
                    (XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y | XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT))
                    _xcwm_resize_window(event_conn, request->window,
                                        request->x, request->y,
                                        request->width, request->height);

                /* Ignore requests to change stacking ? */

                break;
            }

            case XCB_PROPERTY_NOTIFY:
            {
                xcb_property_notify_event_t *notify =
                    (xcb_property_notify_event_t *)evt;
                xcwm_window_t *window =
                    _xcwm_get_window_node_by_window_id(notify->window);
                if (!window) {
                    break;
                }

                /* If this is WM_PROTOCOLS, do not send event, just
                 * handle internally */
                if (notify->atom == window->context->atoms.ewmh_conn.WM_PROTOCOLS) {
                    _xcwm_atoms_set_wm_delete(window);
                    break;
                }

                xcwm_event_type_t event;
                if (_xcwm_atom_change_to_event(notify->atom, window, &event))
                {
                    /* Send the appropriate event */
                    return_evt.event_type = event;
                    return_evt.window = window;
                    callback_ptr(&return_evt);
                }
                else {
                    printf("PROPERTY_NOTIFY for ignored property atom %d\n", notify->atom);
                    /*
                      We need a mechanism to forward properties we don't know about to WM,
                      otherwise everything needs to be in libXcwm ...?
                    */
                }

                break;
            }

            case XCB_MAPPING_NOTIFY:
                break;

            default:
            {
                printf("UNKNOWN EVENT: %i\n", (evt->response_type & ~0x80));
                break;
            }
            }
        }
        /* Free the event */
        free(evt);
    }
    return NULL;
}
Ejemplo n.º 29
0
int dispatcher::execute( void )
{
	xcb_flush( _connection );
	_exit_code = 0;

	bool done = false;
	while ( !done )
	{
		auto event = core::wrap_cptr( xcb_wait_for_event( _connection ) );
		if ( !event )
			break;
		switch ( event->response_type & ~0x80 )
		{
			case XCB_EXPOSE:
			{
				auto *ev = reinterpret_cast<xcb_expose_event_t*>( event.get() );
				if ( ev->count == 0 )
					_windows[ev->window]->exposed();
				xcb_flush( _connection );
				break;
			}

			case XCB_CONFIGURE_NOTIFY:
			{
				auto *ev = reinterpret_cast<xcb_configure_notify_event_t*>( event.get() );
				auto w = _windows[ev->window];
				if ( w->check_last_position( ev->x, ev->y ) )
					w->moved( ev->x, ev->y );
				if ( w->check_last_size( ev->width, ev->height ) )
					w->resize_canvas( ev->width, ev->height );
				break;
			}

			case XCB_DESTROY_NOTIFY:
			{
				auto *ev = reinterpret_cast<xcb_destroy_notify_event_t*>( event.get() );
				auto w = _windows[ev->window];
				w->closed();
				break;
			}

			case XCB_MAP_NOTIFY:
			{
				auto *ev = reinterpret_cast<xcb_map_notify_event_t*>( event.get() );
				auto w = _windows[ev->window];
				w->shown();
				w->restored();
				break;
			}

			case XCB_UNMAP_NOTIFY:
			{
				auto *ev = reinterpret_cast<xcb_unmap_notify_event_t*>( event.get() );
				auto w = _windows[ev->window];
				w->hidden();
				w->minimized();
				break;
			}

			case XCB_ENTER_NOTIFY:
			{
				auto *ev = reinterpret_cast<xcb_enter_notify_event_t*>( event.get() );
				auto w = _windows[ev->event];
				w->entered();
				break;
			}

			case XCB_LEAVE_NOTIFY:
			{
				auto *ev = reinterpret_cast<xcb_leave_notify_event_t*>( event.get() );
				auto w = _windows[ev->event];
				w->exited();
				break;
			}

			case XCB_KEY_PRESS:
			{
				auto *ev = reinterpret_cast<xcb_key_press_event_t*>( event.get() );
				auto w = _windows[ev->event];
				platform::scancode sc = _keyboard->get_scancode( ev->detail );
				w->key_pressed( _keyboard, sc );
				break;
			}

			case XCB_KEY_RELEASE:
			{
				auto *ev = reinterpret_cast<xcb_key_press_event_t*>( event.get() );
				auto w = _windows[ev->event];
				platform::scancode sc = _keyboard->get_scancode( ev->detail );
				w->key_released( _keyboard, sc );
				break;
			}

			case XCB_MAPPING_NOTIFY:
			{
				auto *ev = reinterpret_cast<xcb_mapping_notify_event_t*>( event.get() );
				if ( ev->request == XCB_MAPPING_MODIFIER || ev->request == XCB_MAPPING_KEYBOARD )
					_keyboard->update_mapping();
				break;
			}

			case XCB_BUTTON_PRESS:
			{
				auto *ev = reinterpret_cast<xcb_button_press_event_t*>( event.get() );
				auto w = _windows[ev->event];
				switch ( ev->detail )
				{
					case 1:
					case 2:
					case 3:
						w->mouse_pressed( _mouse, { double(ev->event_x), double(ev->event_y) }, ev->detail );
						break;

					case 4: // Mouse wheel up
					case 5: // Mouse wheel down
						break;
				}
				break;
			}

			case XCB_BUTTON_RELEASE:
			{
				auto *ev = reinterpret_cast<xcb_button_press_event_t*>( event.get() );
				auto w = _windows[ev->event];
				switch ( ev->detail )
				{
					case 1:
					case 2:
					case 3:
						w->mouse_released( _mouse, { double(ev->event_x), double(ev->event_y) }, ev->detail );
						break;

					case 4: // Mouse wheel up
					case 5: // Mouse wheel down
						break;
				}
				break;
			}

			case XCB_MOTION_NOTIFY:
			{
				auto *ev = reinterpret_cast<xcb_motion_notify_event_t*>( event.get() );
				auto w = _windows[ev->event];
				w->mouse_moved( _mouse, { double(ev->event_x), double(ev->event_y) } );
				break;
			}

			case XCB_VISIBILITY_NOTIFY:
			case XCB_REPARENT_NOTIFY:
				break;

			case XCB_CLIENT_MESSAGE:
			{
				auto *ev = reinterpret_cast<xcb_client_message_event_t*>( event.get() );
				if ( ev->data.data32[0] == _atom_delete_window )
				{
					auto w = _windows[ev->window];
					w->hide();
					_windows.erase( w->id() );
					done = _windows.empty();
				}
				break;
			}

			default:
				std::cout << "Unknown event: " << uint32_t( event->response_type & ~0x80 ) << ' ' << uint32_t( event->response_type ) << std::endl;
		}
	}

	return _exit_code;
}
Ejemplo n.º 30
0
int main() {
	xcb_connection_t 	* conn;
	xcb_screen_t 		* scrn;
	xcb_drawable_t 		win;
	xcb_gcontext_t 		foreground;
	xcb_generic_event_t	* e;
	uint32_t			mask = 0;
	uint32_t			values[2];
	
	xcb_point_t points[] = { { 10, 10 },
							 { 10, 20 },
							 { 20, 10 },
							 { 20, 20 } };
	xcb_point_t polyline[] = { { 50, 10 },
							   {  5, 20 },
							   { 25,-20 },
							   { 10, 10 } };
	xcb_segment_t segments[] = { { 100, 10, 140, 30 },
								 { 110, 25, 130, 60 } };
	xcb_rectangle_t rectangles[] = { { 10, 50, 40, 30 },
								     { 80, 50, 10, 40 } };
	xcb_arc_t arcs[] = { { 10, 100, 60, 40, 0,  90 << 6 },
						 { 90, 100, 55, 40, 0, 270 << 6 } };
	
	//initialize the connection to X
	conn = xcb_connect(NULL, &scrnNum);
	
	//get the first screen data
	scrn = get_setup_roots_iterator(xcb_get_setup(conn)).data;
	
	foreground = xcb_generate_id(conn);
	mask = XCB_GC_FOREGROUND | XCB_GC_GRAPHICS_EXPOSURES;
	values[0] = scrn->black_pixel;
	values[1] = 0;
	xcb_create_gc(conn, foreground, win, mask, values);
	
	//ask for the window's id
	win = xcb_generate_id(conn);
	
	//create the window
	mask = XCB_CW_BLACK_PIXEL | XCB_GC_GRAPHICS_EXPOSURES
	values[0] = scrn->white_pixel;
	values[1] = XCB_EVENT_MASK_EXPOSURE;
	xcb_create_window(conn,
					  XCB_COPY_FROM_PARENT,
					  win,
					  scrn->root,
					  0, 0,
					  150, 150,
					  10,
					  XCB_WINDOW_CLASS_INPUT_OUTPUT,
					  scrn->root_visual,
					  mask, values);
	
	//map the window
	xcb_map_window(conn, win);
	xcb_flush(conn);
	
	while (( e = xcb_wait_for_event(conn)) {
		switch (e->response_type & ~0x80) {
		case XCB_EXPOSE: {
			//draw things
			xcb_poly_point(conn, XCB_COORD_MODE_ORIGIN, win, foreground, 4, points);
			
			xcb_poly_line(conn, XCB_COORD_MODE_PREVIOUS, win, foreground, 4, polyline);
			
			xcb_poly_segment(conn, win, foreground, 2, segments);
			
			xcb_poly_rectangle(conn, win, foreground, 2 , rectangles);
			
			xcb_poly_arc(conn, win, foreground, 2, arcs);
			
			xcb_flush(conn);
			
			break;
		}
		default: {
			break;
		}
		}
		free(e);
	}
	return 0;
}