Esempio n. 1
0
/** Check  whether  the  needed   X  extensions  are  present  on  the
 *  server-side (all the data  have been previously pre-fetched in the
 *  extension  cache). Then send  requests to  check their  version by
 *  sending  QueryVersion  requests which  is  compulsory because  the
 *  client  MUST  negotiate  the   version  of  the  extension  before
 *  executing extension requests
 */
void
display_init_extensions(void)
{
  globalconf.extensions.composite = xcb_get_extension_data(globalconf.connection,
							   &xcb_composite_id);

  globalconf.extensions.xfixes = xcb_get_extension_data(globalconf.connection,
							&xcb_xfixes_id);

  globalconf.extensions.damage = xcb_get_extension_data(globalconf.connection,
							&xcb_damage_id);

  globalconf.extensions.randr = xcb_get_extension_data(globalconf.connection,
                                                       &xcb_randr_id);

  if(!globalconf.extensions.composite ||
     !globalconf.extensions.composite->present)
    fatal("No Composite extension");

  debug("Composite: major_opcode=%ju",
	(uintmax_t) globalconf.extensions.composite->major_opcode);

  if(!globalconf.extensions.xfixes ||
     !globalconf.extensions.xfixes->present)
    fatal("No XFixes extension");

  debug("XFixes: major_opcode=%ju",
	(uintmax_t) globalconf.extensions.xfixes->major_opcode);

  if(!globalconf.extensions.damage ||
     !globalconf.extensions.damage->present)
    fatal("No Damage extension");

  debug("Damage: major_opcode=%ju",
	(uintmax_t) globalconf.extensions.damage->major_opcode);

  _init_extensions_cookies.composite =
    xcb_composite_query_version_unchecked(globalconf.connection,
					  XCB_COMPOSITE_MAJOR_VERSION,
					  XCB_COMPOSITE_MINOR_VERSION);

  _init_extensions_cookies.damage =
    xcb_damage_query_version_unchecked(globalconf.connection,
				       XCB_DAMAGE_MAJOR_VERSION,
				       XCB_DAMAGE_MINOR_VERSION);

  _init_extensions_cookies.xfixes =
    xcb_xfixes_query_version_unchecked(globalconf.connection,
				       XCB_XFIXES_MAJOR_VERSION,
				       XCB_XFIXES_MINOR_VERSION);

  if(globalconf.extensions.randr && globalconf.extensions.randr->present)
    _init_extensions_cookies.randr =
      xcb_randr_query_version(globalconf.connection,
                              XCB_RANDR_MAJOR_VERSION,
                              XCB_RANDR_MINOR_VERSION);
  else
    globalconf.extensions.randr = NULL;
}
Esempio n. 2
0
int
randr_init(randr_state_t *state)
{
	/* Initialize state. */
	state->screen_num = -1;
	state->crtc_num = NULL;

	state->crtc_num_count = 0;
	state->crtc_count = 0;
	state->crtcs = NULL;

	state->preserve = 0;

	xcb_generic_error_t *error;

	/* Open X server connection */
	state->conn = xcb_connect(NULL, &state->preferred_screen);

	/* Query RandR version */
	xcb_randr_query_version_cookie_t ver_cookie =
		xcb_randr_query_version(state->conn, RANDR_VERSION_MAJOR,
					RANDR_VERSION_MINOR);
	xcb_randr_query_version_reply_t *ver_reply =
		xcb_randr_query_version_reply(state->conn, ver_cookie, &error);

	/* TODO What does it mean when both error and ver_reply is NULL?
	   Apparently, we have to check both to avoid seg faults. */
	if (error || ver_reply == NULL) {
		int ec = (error != 0) ? error->error_code : -1;
		fprintf(stderr, _("`%s' returned error %d\n"),
			"RANDR Query Version", ec);
		xcb_disconnect(state->conn);
		return -1;
	}

	if (ver_reply->major_version != RANDR_VERSION_MAJOR ||
	    ver_reply->minor_version < RANDR_VERSION_MINOR) {
		fprintf(stderr, _("Unsupported RANDR version (%u.%u)\n"),
			ver_reply->major_version, ver_reply->minor_version);
		free(ver_reply);
		xcb_disconnect(state->conn);
		return -1;
	}

	free(ver_reply);

	return 0;
}
Esempio n. 3
0
bool ScreenManager::configureRandR(xcb_connection_t *conn)
{
    const xcb_query_extension_reply_t *ext = xcb_get_extension_data(conn, &xcb_randr_id);
    if (!ext->present) {
        return false;
    }
    xcb_randr_query_version_reply_t *ver =
        xcb_randr_query_version_reply(
            conn, xcb_randr_query_version(conn, 1, 1), 0);
    if (!ver) {
        return false;
    }
    _randrBase = ext->first_event;
    xcb_randr_select_input(conn, _rootWindow,
        XCB_RANDR_NOTIFY_MASK_SCREEN_CHANGE |
       XCB_RANDR_NOTIFY_MASK_OUTPUT_CHANGE |
       XCB_RANDR_NOTIFY_MASK_CRTC_CHANGE |
       XCB_RANDR_NOTIFY_MASK_OUTPUT_PROPERTY);
    xcb_flush(conn);
    return true;
}
int x11_find_all_outputs(char*** out_outputs, size_t* out_outputs_count)
{
  xcb_generic_error_t* error = NULL;
  xcb_randr_query_version_cookie_t version_cookie;
  xcb_randr_query_version_reply_t* version_reply = NULL;
  const xcb_setup_t* setup;
  xcb_screen_iterator_t iter;
  xcb_screen_t* screen;
  xcb_randr_get_screen_resources_current_cookie_t screen_cookie;
  xcb_randr_get_output_info_cookie_t output_cookie;
  xcb_randr_output_t* outputs = NULL;
  
  *out_outputs_count = 0;
  *out_outputs = NULL;
  
  connection = xcb_connect(NULL, NULL);
  if (connection == NULL)
    goto pfail;
  
  version_cookie = xcb_randr_query_version(connection, RANDR_VERSION_MAJOR, RANDR_VERSION_MINOR);
  version_reply = xcb_randr_query_version_reply(connection, version_cookie, &error);
  
  if ((error != NULL) || (version_reply == NULL))
    {
      if ((error == NULL) && (version_reply == NULL))
	connection = NULL;
      goto pfail;
    }
  
  if ((version_reply->major_version != RANDR_VERSION_MAJOR) ||
      (version_reply->minor_version < RANDR_VERSION_MINOR))
    {
      fprintf(stderr, "%s: wrong RandR version\n", argv0);
      goto fail;
    }
  
  free(version_reply), version_reply = NULL;
  
  setup = xcb_get_setup(connection);
  if (setup == NULL)
    goto pfail;
  
  iter = xcb_setup_roots_iterator(setup);
  
  for (; iter.rem > 0; xcb_screen_next(&iter))
    {
      size_t i, n;
      
      screen = iter.data;
      if (screen == NULL)
	abort();
      
      screen_cookie = xcb_randr_get_screen_resources_current(connection, screen->root);
      screen_reply = xcb_randr_get_screen_resources_current_reply(connection, screen_cookie, &error);
      if (error != NULL)
	goto pfail;
      
      outputs = xcb_randr_get_screen_resources_current_outputs(screen_reply);
      if (outputs == NULL)
	goto pfail;
      
      for (i = 0, n = (size_t)(screen_reply->num_outputs); i < n; i++)
	{
	  uint8_t* name;
	  uint16_t length;
	  char* namez;
	  char** old;
	  
	  output_cookie = xcb_randr_get_output_info(connection, outputs[i], screen_reply->config_timestamp);
	  output_reply = xcb_randr_get_output_info_reply(connection, output_cookie, &error);
	  if (error != NULL)
	    goto pfail;
	  
	  if (output_reply->connection != XCB_RANDR_CONNECTION_CONNECTED)
	    goto next_output;
	  
	  name = xcb_randr_get_output_info_name(output_reply);
	  length = output_reply->name_len;
	  if (name == NULL)
	    goto pfail;
	  
	  *out_outputs = realloc(old = *out_outputs, (*out_outputs_count + 1) * sizeof(char*));
	  if (*out_outputs == NULL)
	    {
	      *out_outputs = old;
	      goto pfail;
	    }
	  
	  namez = malloc(((size_t)length + 1) * sizeof(char));
	  if (namez == NULL)
	    goto pfail;
	  namez[length] = '\0';
	  while (length--)
	    namez[length] = (char)(name[length]);
	  
	  (*out_outputs)[(*out_outputs_count)++] = namez;
	  
	next_output:
	  free(output_reply), output_reply = NULL;
	}
      
      free(screen_reply), screen_reply = NULL;
    }
  
  xcb_disconnect(connection);
  return 0;
  
 pfail:
  perror(argv0);
 fail:
  free(version_reply);
  free(screen_reply);
  free(output_reply);
  if (connection != NULL)
    xcb_disconnect(connection);
  return -1;
}
int x11_initialise_animation(int coarse_fine, double duration, double degrees, const char* output)
{
  xcb_generic_error_t* error = NULL;
  xcb_randr_query_version_cookie_t version_cookie;
  xcb_randr_query_version_reply_t* version_reply = NULL;
  const xcb_setup_t* setup;
  xcb_screen_iterator_t iter;
  xcb_screen_t* screen;
  xcb_randr_get_screen_resources_current_cookie_t screen_cookie;
  xcb_randr_get_output_info_cookie_t output_cookie;
  xcb_randr_crtc_t* crtcs = NULL;
  xcb_randr_output_t* outputs = NULL;
  int found_output = 0;
  size_t i, n;
  xcb_randr_get_crtc_transform_cookie_t transform_cookie;
  xcb_randr_get_crtc_transform_reply_t* transform_reply = NULL;
  
  fine = coarse_fine ? (coarse_fine == 1) : 1;
  
  connection = NULL;
  screen_reply = NULL;
  output_reply = NULL;
  
  connection = xcb_connect(NULL, NULL);
  if (connection == NULL)
    goto pfail;
  
  version_cookie = xcb_randr_query_version(connection, RANDR_VERSION_MAJOR, RANDR_VERSION_MINOR);
  version_reply = xcb_randr_query_version_reply(connection, version_cookie, &error);
  
  if ((error != NULL) || (version_reply == NULL))
    {
      if ((error == NULL) && (version_reply == NULL))
	connection = NULL;
      goto pfail;
    }
  
  if ((version_reply->major_version != RANDR_VERSION_MAJOR) ||
      (version_reply->minor_version < RANDR_VERSION_MINOR))
    {
      fprintf(stderr, "%s: wrong RandR version\n", argv0);
      goto fail;
    }
  
  free(version_reply), version_reply = NULL;
  
  setup = xcb_get_setup(connection);
  if (setup == NULL)
    goto pfail;
  
  iter = xcb_setup_roots_iterator(setup);
  
  for (; (iter.rem > 0) && !found_output; xcb_screen_next(&iter))
    {
      screen = iter.data;
      if (screen == NULL)
	abort();
      
      screen_cookie = xcb_randr_get_screen_resources_current(connection, screen->root);
      screen_reply = xcb_randr_get_screen_resources_current_reply(connection, screen_cookie, &error);
      if (error != NULL)
	goto pfail;
      
      crtcs = xcb_randr_get_screen_resources_current_crtcs(screen_reply);
      outputs = xcb_randr_get_screen_resources_current_outputs(screen_reply);
      if (outputs == NULL)
	goto pfail;
      
      for (i = 0, n = (size_t)(screen_reply->num_outputs); (i < n) && !found_output; i++)
	{
	  uint8_t* name;
	  uint16_t length;
	  char* namez = NULL;
	  uint16_t j;
	  
	  output_cookie = xcb_randr_get_output_info(connection, outputs[i], screen_reply->config_timestamp);
	  output_reply = xcb_randr_get_output_info_reply(connection, output_cookie, &error);
	  if (error != NULL)
	    goto pfail;
	  
	  if (output_reply->connection != XCB_RANDR_CONNECTION_CONNECTED)
	    goto next_output;
	  
	  name = xcb_randr_get_output_info_name(output_reply);
	  length = output_reply->name_len;
	  if (name == NULL)
	    goto pfail;
	  
	  namez = malloc(((size_t)length + 1) * sizeof(char));
	  if (namez == NULL)
	    goto pfail;
	  namez[length] = '\0';
	  while (length--)
	    namez[length] = (char)(name[length]);
	  
	  if (strcmp(namez, output))
	      goto next_output;
	  found_output = 1;
	  free(namez), namez = NULL;
	  
	  for (j = 0; j < screen_reply->num_crtcs; j++)
	    if (crtcs[j] == output_reply->crtc)
	      break;
	  if (j == screen_reply->num_crtcs)
	    {
	      fprintf(stderr, "%s: could not find CRTC associated with output: %s\n", argv0, output);
	      goto fail;
	    }
	  crtc = crtcs[j];
	  
	  goto exit_search_loop;
	  
	next_output:
	  free(namez);
	  free(output_reply), output_reply = NULL;
	}
      
      free(screen_reply), screen_reply = NULL;
    }
 exit_search_loop:
  
  if (!found_output)
    {
      fprintf(stderr, "%s: could not find output: %s\n", argv0, output);
      goto fail;
    }
  
  transform_cookie = xcb_randr_get_crtc_transform(connection, crtc);
  transform_reply = xcb_randr_get_crtc_transform_reply(connection, transform_cookie, &error);
  if (error != NULL)
    goto pfail;
  
  original_transform = transform_reply->pending_transform;
  free(transform_reply);
  
  return 0;
  
 pfail:
  perror(argv0);
 fail:
  free(version_reply);
  free(screen_reply);
  free(output_reply);
  free(transform_reply);
  if (connection != NULL)
    xcb_disconnect(connection);
  return -1;
  
  return (void)duration, (void)degrees, -1; /* TODO */
}
Esempio n. 6
0
/* Get the number of outputs */
static unsigned CountMonitors( vlc_object_t *obj )
{
    char *psz_display = var_InheritString( obj, "x11-display" );
    int snum;
    xcb_connection_t *conn = xcb_connect( psz_display, &snum );
    free( psz_display );
    if( xcb_connection_has_error( conn ) )
        return 0;

    const xcb_setup_t *setup = xcb_get_setup( conn );
    xcb_screen_t *scr = NULL;
    for( xcb_screen_iterator_t i = xcb_setup_roots_iterator( setup );
         i.rem > 0; xcb_screen_next( &i ) )
    {
         if( snum == 0 )
         {
             scr = i.data;
             break;
         }
         snum--;
    }

    unsigned n = 0;
    if( scr == NULL )
        goto error;

    xcb_randr_query_version_reply_t *v =
        xcb_randr_query_version_reply( conn,
            xcb_randr_query_version( conn, 1, 2 ), NULL );
    if( v == NULL )
        goto error;
    msg_Dbg( obj, "using X RandR extension v%"PRIu32".%"PRIu32,
             v->major_version, v->minor_version );
    free( v );

    xcb_randr_get_screen_resources_reply_t *r =
        xcb_randr_get_screen_resources_reply( conn,
            xcb_randr_get_screen_resources( conn, scr->root ), NULL );
    if( r == NULL )
        goto error;

    const xcb_randr_output_t *outputs =
        xcb_randr_get_screen_resources_outputs( r );
    for( unsigned i = 0; i < r->num_outputs; i++ )
    {
        xcb_randr_get_output_info_reply_t *output =
            xcb_randr_get_output_info_reply( conn,
                xcb_randr_get_output_info( conn, outputs[i], 0 ), NULL );
        if( output == NULL )
            continue;
        /* FIXME: do not count cloned outputs multiple times */
        /* XXX: what to do with UNKNOWN state connections? */
        n += output->connection == XCB_RANDR_CONNECTION_CONNECTED;
        free( output );
    }
    free( r );
    msg_Dbg( obj, "X randr has %u outputs", n );

error:
    xcb_disconnect( conn );
    return n;
}
Esempio n. 7
0
std::vector<VideoMode> VideoModeImpl::getFullscreenModes()
{
    std::vector<VideoMode> modes;

    // Open a connection with the X server
    xcb_connection_t* connection = OpenConnection();

    // Retrieve the default screen
    xcb_screen_t* screen = XCBDefaultScreen(connection);

    ScopedXcbPtr<xcb_generic_error_t> error(NULL);

    const xcb_query_extension_reply_t* randrExt = xcb_get_extension_data(connection, &xcb_randr_id);

    if (!randrExt || !randrExt->present)
    {
        // Randr extension is not supported: we cannot get the video modes
        err() << "Failed to use the RandR extension while trying to get the supported video modes" << std::endl;

        // Close the connection with the X server
        CloseConnection(connection);

        return modes;
    }

    // Load RandR and check its version
    ScopedXcbPtr<xcb_randr_query_version_reply_t> randrVersion(xcb_randr_query_version_reply(
        connection,
        xcb_randr_query_version(
            connection,
            1,
            1
        ),
        &error
    ));

    if (error)
    {
        err() << "Failed to load the RandR extension while trying to get the supported video modes" << std::endl;

        // Close the connection with the X server
        CloseConnection(connection);

        return modes;
    }

    // Get the current configuration
    ScopedXcbPtr<xcb_randr_get_screen_info_reply_t> config(xcb_randr_get_screen_info_reply(
        connection,
        xcb_randr_get_screen_info(
            connection,
            screen->root
        ),
        &error
    ));

    if (error)
    {
        // Failed to get the screen configuration
        err() << "Failed to retrieve the screen configuration while trying to get the supported video modes" << std::endl;

        // Close the connection with the X server
        CloseConnection(connection);

        return modes;
    }

    // Get the available screen sizes
    xcb_randr_screen_size_t* sizes = xcb_randr_get_screen_info_sizes(config.get());
    if (sizes && (config->nSizes > 0))
    {
        // Get the list of supported depths
        xcb_depth_iterator_t iter = xcb_screen_allowed_depths_iterator(screen);
        // Combine depths and sizes to fill the array of supported modes
        for (; iter.rem; xcb_depth_next(&iter))
        {
            for (int j = 0; j < config->nSizes; ++j)
            {
                // Convert to VideoMode
                VideoMode mode(sizes[j].width, sizes[j].height, iter.data->depth);

                if (config->rotation == XCB_RANDR_ROTATION_ROTATE_90 ||
                    config->rotation == XCB_RANDR_ROTATION_ROTATE_270)
                    std::swap(mode.width, mode.height);

                // Add it only if it is not already in the array
                if (std::find(modes.begin(), modes.end(), mode) == modes.end())
                    modes.push_back(mode);
            }
        }
    }

    // Close the connection with the X server
    CloseConnection(connection);

    return modes;
}
Esempio n. 8
0
VideoMode VideoModeImpl::getDesktopMode()
{
    VideoMode desktopMode;

    // Open a connection with the X server
    xcb_connection_t* connection = OpenConnection();

    // Retrieve the default screen
    xcb_screen_t* screen = XCBDefaultScreen(connection);

    ScopedXcbPtr<xcb_generic_error_t> error(NULL);

    // Check if the RandR extension is present
    const xcb_query_extension_reply_t* randrExt = xcb_get_extension_data(connection, &xcb_randr_id);

    if (!randrExt || !randrExt->present)
    {
        // Randr extension is not supported: we cannot get the video modes
        err() << "Failed to use the RandR extension while trying to get the desktop video mode" << std::endl;

        // Close the connection with the X server
        CloseConnection(connection);

        return desktopMode;
    }

    // Load RandR and check its version
    ScopedXcbPtr<xcb_randr_query_version_reply_t> randrVersion(xcb_randr_query_version_reply(
        connection,
        xcb_randr_query_version(
            connection,
            1,
            1
        ),
        &error
    ));

    if (error)
    {
        err() << "Failed to load the RandR extension while trying to get the desktop video mode" << std::endl;

        // Close the connection with the X server
        CloseConnection(connection);

        return desktopMode;
    }

    // Get the current configuration
    ScopedXcbPtr<xcb_randr_get_screen_info_reply_t> config(xcb_randr_get_screen_info_reply(
        connection,
        xcb_randr_get_screen_info(
            connection,
            screen->root
        ),
        &error
    ));

    if (error)
    {
        // Failed to get the screen configuration
        err() << "Failed to retrieve the screen configuration while trying to get the desktop video mode" << std::endl;

        // Close the connection with the X server
        CloseConnection(connection);

        return desktopMode;
    }

    // Get the current video mode
    xcb_randr_mode_t currentMode = config->sizeID;

    // Get the available screen sizes
    int nbSizes = xcb_randr_get_screen_info_sizes_length(config.get());
    xcb_randr_screen_size_t* sizes = xcb_randr_get_screen_info_sizes(config.get());
    if (sizes && (nbSizes > 0))
    {
        desktopMode = VideoMode(sizes[currentMode].width, sizes[currentMode].height, screen->root_depth);

        if (config->rotation == XCB_RANDR_ROTATION_ROTATE_90 ||
            config->rotation == XCB_RANDR_ROTATION_ROTATE_270)
            std::swap(desktopMode.width, desktopMode.height);
    }
    else
    {
        err() << "Failed to retrieve any screen sizes while trying to get the desktop video mode" << std::endl;
    }

    // Close the connection with the X server
    CloseConnection(connection);

    return desktopMode;
}
Esempio n. 9
0
int main() {

	uint8_t xrandr;
	struct pollfd poll_fd;
	fd_set set;
	int fd;
	int retval;
	int timeout;

	setlocale (LC_ALL, "");
//	bindtextdomain (PACKAGE, LOCALEDIR);
//	textdomain (PACKAGE);

	printf("TabletWM version 0.25\n");

	init_tabletwm();

	uint32_t v[]={XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY|XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT};
	xcb_change_window_attributes(conn,scr->root,XCB_CW_EVENT_MASK,v);
	support_capture_key(XCB_MOD_MASK_CONTROL,23); // Ctrl+TAB
	support_capture_key(XCB_MOD_MASK_1,23); // Alt+TAB
	support_capture_key(XCB_MOD_MASK_1,70); // Alt+F4
	support_capture_key(XCB_MOD_MASK_ANY,135); // MENU key (between the right WINDOWS key and the right Ctrl key)
	support_capture_key(XCB_MOD_MASK_ANY,124); // POWER key
	//xcb_grab_key(conn,0,scr->root,XCB_MOD_MASK_ANY,XCB_GRAB_ANY,XCB_GRAB_MODE_ASYNC,XCB_GRAB_MODE_ASYNC);

#ifdef DEBUG
	support_capture_key(XCB_MOD_MASK_1,71); // Alt+F5 for VALGRIND tests
#endif

	/* detect changes in screen size with xrandr */
	xcb_randr_query_version_reply_t *r=xcb_randr_query_version_reply(conn,xcb_randr_query_version(conn,1,1),0);
	if (r) {
		xcb_randr_select_input(conn,scr->root,XCB_RANDR_NOTIFY_MASK_SCREEN_CHANGE);

		const xcb_query_extension_reply_t *r2=xcb_get_extension_data(conn,&xcb_randr_id);
		xrandr=r2->first_event;
	}
	free(r);

	xcb_flush(conn);
	xcb_generic_event_t *e;
	
	keep_running=1;
	
	support_launch_manager();
	fd = xcb_get_file_descriptor(conn);
	while(keep_running) {
		poll_fd.fd=fd;
		poll_fd.events=POLLIN;
		poll_fd.revents=0;
		if (key_win.possition!=0) {
			retval = poll(&poll_fd,1,2000); // refresh every two seconds if the bar is visible
		} else {
			retval = poll(&poll_fd,1,-1); // just wait for an event when the bar is not visible
		}
		if (retval==0) {
			menuwin_expose(NULL); // each 10 seconds of inactivity, refresh the user bar to keep the clock and indicators updated
			continue;
		}
		while(e=xcb_poll_for_event(conn)) {
			uint8_t r=e->response_type&~0x80;
		
			if (r>=xrandr) {
				printf("XRandR\n");
				switch(r-xrandr) {
					case(XCB_RANDR_SCREEN_CHANGE_NOTIFY):
						action_xrandr_screen_change_notify(e);
					break;
					default:
						printf("XRandR unknown: %d\n",r-xrandr);
					break;
				}
			} else {
				switch(r) {
					case(XCB_KEY_RELEASE):
						action_key(e);
					break;
					case (XCB_CREATE_NOTIFY):
						//xcb_create_notify_event_t *ee=(xcb_create_notify_event_t *)e;
					break;
					case(XCB_UNMAP_NOTIFY):
						action_unmap_notify(e);
					break;
					case(XCB_DESTROY_NOTIFY):
						action_destroy_notify(e);
					break;
					case(XCB_MAP_REQUEST):
						action_map_request(e);
					break;
					case(XCB_MAP_NOTIFY):
					case(XCB_MAPPING_NOTIFY):
						support_send_dock_up(NULL,NULL); // ensure that the dock is always on top
					break;
					case(XCB_CONFIGURE_NOTIFY):
						action_configure_notify(e);
					break;
					case(XCB_CONFIGURE_REQUEST):
						action_configure_request(e);
					break;
					case(XCB_CIRCULATE_REQUEST):
						//xcb_circulate_request_event_t *ee=(xcb_circulate_request_event_t *)e;
					break;
					case(XCB_EXPOSE):
						action_expose(e);
					break;
					case(XCB_ENTER_NOTIFY):
						action_mouse_enter(e);
					break;
					case(XCB_LEAVE_NOTIFY):
						action_mouse_leave(e);
					break;
					case(XCB_BUTTON_RELEASE):
						action_mouse_click(e);
					break;
					case(0): {
						xcb_generic_error_t *ee=(xcb_generic_error_t *)e;
						printf("error event type %d\n",ee->error_code);
					}
					break;
					default:
						printf("unhandled event type %d\n",e->response_type);
					break;
				}
			}
			free(e);
		}
	}
	destroy_tabletwm();
	xcb_disconnect(conn);
	return(0);
}