int GetXI2OpCode()
{
  Display *dpy = nux::GetGraphicsDisplay()->GetX11Display();

  int opcode, event_base, error_base;
  if (!XQueryExtension(dpy, "XFIXES",
                       &opcode,
                       &event_base,
                       &error_base))
  {
    LOG_ERROR(logger) << "Missing XFixes";
    return -1;
  }

  if (!XQueryExtension (dpy, "XInputExtension",
                        &opcode,
                        &event_base,
                        &error_base))
  {
    LOG_ERROR(logger) << "Missing XInput";
    return -1;
  }

  int maj = MAJOR;
  int min = MINOR;

  if (XIQueryVersion(dpy, &maj, &min) == BadRequest)
  {
    LOG_ERROR(logger) << "Need XInput version 2.3";
    return -1;
  }

  return opcode;
}
Exemple #2
0
/**
 * Initialises appropriate X extensions.
 */
static void
initialise_extensions (void)
{
  int major = 2, minor = 0;
  if (XIQueryVersion(gdk_x11_get_default_xdisplay (), &major, &minor) == BadRequest) {
    g_error("XI2 not available. Server supports %d.%d\n", major, minor);
  }
}
Exemple #3
0
static              Status
EInputQueryVersion(Display * dpy,
		   int *major_version_return, int *minor_version_return)
{
   *major_version_return = XI_2_Major;
   *minor_version_return = XI_2_Minor;

   return XIQueryVersion(dpy, major_version_return, minor_version_return);
}
Exemple #4
0
static void
meta_backend_x11_post_init (MetaBackend *backend)
{
  MetaBackendX11 *x11 = META_BACKEND_X11 (backend);
  MetaBackendX11Private *priv = meta_backend_x11_get_instance_private (x11);
  int major, minor;

  priv->xdisplay = clutter_x11_get_default_display ();

  priv->source = x_event_source_new (backend);

  if (!XSyncQueryExtension (priv->xdisplay, &priv->xsync_event_base, &priv->xsync_error_base) ||
      !XSyncInitialize (priv->xdisplay, &major, &minor))
    meta_fatal ("Could not initialize XSync");

  {
    int major = 2, minor = 3;
    gboolean has_xi = FALSE;

    if (XQueryExtension (priv->xdisplay,
                         "XInputExtension",
                         &priv->xinput_opcode,
                         &priv->xinput_error_base,
                         &priv->xinput_event_base))
      {
        if (XIQueryVersion (priv->xdisplay, &major, &minor) == Success)
          {
            int version = (major * 10) + minor;
            if (version >= 22)
              has_xi = TRUE;
          }
      }

    if (!has_xi)
      meta_fatal ("X server doesn't have the XInput extension, version 2.2 or newer\n");
  }

  take_touch_grab (backend);

  priv->xcb = XGetXCBConnection (priv->xdisplay);
  if (!xkb_x11_setup_xkb_extension (priv->xcb,
                                    XKB_X11_MIN_MAJOR_XKB_VERSION,
                                    XKB_X11_MIN_MINOR_XKB_VERSION,
                                    XKB_X11_SETUP_XKB_EXTENSION_NO_FLAGS,
                                    NULL, NULL,
                                    &priv->xkb_event_base,
                                    &priv->xkb_error_base))
    meta_fatal ("X server doesn't have the XKB extension, version %d.%d or newer\n",
                XKB_X11_MIN_MAJOR_XKB_VERSION, XKB_X11_MIN_MINOR_XKB_VERSION);

  g_signal_connect_object (clutter_device_manager_get_default (), "device-added",
                           G_CALLBACK (on_device_added), backend, 0);

  META_BACKEND_CLASS (meta_backend_x11_parent_class)->post_init (backend);
}
void QXcbConnection::initializeXInput2()
{
    Display *xDisplay = static_cast<Display *>(m_xlib_display);
    if (XQueryExtension(xDisplay, "XInputExtension", &m_xiOpCode, &m_xiEventBase, &m_xiErrorBase)) {
        int xiMajor = 2;
        m_xi2Minor = 2; // try 2.2 first, needed for TouchBegin/Update/End
        if (XIQueryVersion(xDisplay, &xiMajor, &m_xi2Minor) == BadRequest) {
            m_xi2Minor = 0; // for tablet support 2.0 is enough
            m_xi2Enabled = XIQueryVersion(xDisplay, &xiMajor, &m_xi2Minor) != BadRequest;
        } else {
            m_xi2Enabled = true;
        }
        if (m_xi2Enabled) {
#ifndef QT_NO_TABLETEVENT
            // Tablet support: Find the stylus-related devices.
            xi2SetupTabletDevices();
#endif // QT_NO_TABLETEVENT
        }
    }
}
static void
clutter_backend_x11_create_device_manager (ClutterBackendX11 *backend_x11)
{
  ClutterEventTranslator *translator;
  ClutterBackend *backend;

#ifdef HAVE_XINPUT_2
  if (clutter_enable_xinput)
    {
      int event_base, first_event, first_error;

      if (XQueryExtension (backend_x11->xdpy, "XInputExtension",
                           &event_base,
                           &first_event,
                           &first_error))
        {
          int major = 2;
          int minor = 3;

          if (XIQueryVersion (backend_x11->xdpy, &major, &minor) != BadRequest)
            {
              CLUTTER_NOTE (BACKEND, "Creating XI2 device manager");
              backend_x11->has_xinput = TRUE;
              backend_x11->device_manager =
                g_object_new (CLUTTER_TYPE_DEVICE_MANAGER_XI2,
                              "backend", backend_x11,
                              "opcode", event_base,
                              NULL);

              backend_x11->xi_minor = minor;
            }
        }
    }

  if (backend_x11->device_manager == NULL)
#endif /* HAVE_XINPUT_2 */
    {
      CLUTTER_NOTE (BACKEND, "Creating Core device manager");
      backend_x11->has_xinput = FALSE;
      backend_x11->device_manager =
        g_object_new (CLUTTER_TYPE_DEVICE_MANAGER_X11,
                      "backend", backend_x11,
                      NULL);

      backend_x11->xi_minor = -1;
    }

  backend = CLUTTER_BACKEND (backend_x11);
  backend->device_manager = backend_x11->device_manager;

  translator = CLUTTER_EVENT_TRANSLATOR (backend_x11->device_manager);
  _clutter_backend_add_event_translator (backend, translator);
}
int main() {
    /* Connect to the X server */
    Display *display = XOpenDisplay(NULL);
    Window win_root = XDefaultRootWindow(display);

/* XInput Extension available? */
    int opcode, event, error;
    if (!XQueryExtension(display, "XInputExtension", &opcode, &event, &error)) {
        printf("X Input extension not available.\n");
        return -1;
    }

/* Which version of XI2? We support 2.0 */
    int major = 2, minor = 0;
    if (XIQueryVersion(display, &major, &minor) == BadRequest) {
        printf("XI2 not available. Server supports %d.%d\n", major, minor);
        return -1;
    }


    XIDetachSlaveInfo info;
    info.type = XIDetachSlave;
    info.deviceid = 10;

    XIAnyHierarchyChangeInfo any_info;
    any_info.type = XIDetachSlave;
    any_info.detach = info;
    XIChangeHierarchy(display, &any_info, 1);

    printf("Detached slave device 10\n");

    int master_id = get_master_keyboard_id(display);
    if (master_id == -1){
        printf("No master keyboard available.\n");
        return -1;
    }

    std::this_thread::sleep_for(std::chrono::seconds(10));

    XIAttachSlaveInfo attach_info;
    attach_info.type = XIAttachSlave;
    attach_info.deviceid = 10;
    attach_info.new_master = master_id;
    XIAnyHierarchyChangeInfo any_attach_info;
    any_attach_info.type = XIAttachSlave;
    any_attach_info.attach = attach_info;
    XIChangeHierarchy(display, &any_attach_info, 1);

    printf("Attached slave device 10\n");

    XCloseDisplay(display);
}
void extensions_init(void) {
    int event, error;
    if (!XQueryExtension(display, "XInputExtension", &xi_ext_opcode, &event, &error))
        bail("XInput extension is not available.");

    int major_op = 2;
    int minor_op = 2;

    int result = XIQueryVersion(display, &major_op, &minor_op);
    if (result == BadRequest)
        bail("XI2 is not supported in a sufficient version (or at all).");
    else if (result != Success)
        bail("Failed to query XI2 extension.");
}
Exemple #9
0
/* Return 1 if XI2 is available, 0 otherwise */
static int has_xi2(Display *dpy)
{
    int major, minor;
    int rc;

    /* We support XI 2.2 */
    major = 2;
    minor = 2;

    rc = XIQueryVersion(dpy, &major, &minor);
    if (rc == BadRequest) {
    	MLOGE("No XI2 support. Server supports version %d.%d only.\n", major, minor);
    	return 0;
    } 
 
    return 1;
}
Exemple #10
0
GdkDeviceManager *
_gdk_x11_device_manager_new (GdkDisplay *display)
{
  if (!g_getenv ("GDK_CORE_DEVICE_EVENTS"))
    {
#ifdef XINPUT_2
      int opcode, firstevent, firsterror;
      Display *xdisplay;

      xdisplay = GDK_DISPLAY_XDISPLAY (display);

      if (XQueryExtension (xdisplay, "XInputExtension",
                           &opcode, &firstevent, &firsterror))
        {
          int major, minor;

          major = 2;
	  minor = 3;

          if (!_gdk_disable_multidevice &&
              XIQueryVersion (xdisplay, &major, &minor) != BadRequest)
            {
              GdkX11DeviceManagerXI2 *device_manager_xi2;

              GDK_NOTE (INPUT, g_message ("Creating XI2 device manager"));

              device_manager_xi2 = g_object_new (GDK_TYPE_X11_DEVICE_MANAGER_XI2,
                                                 "display", display,
                                                 "opcode", opcode,
                                                 "major", major,
                                                 "minor", minor,
                                                 NULL);

              return GDK_DEVICE_MANAGER (device_manager_xi2);
            }
        }
#endif /* XINPUT_2 */
    }

  GDK_NOTE (INPUT, g_message ("Creating core device manager"));

  return g_object_new (GDK_TYPE_X11_DEVICE_MANAGER_CORE,
                       "display", display,
                       NULL);
}
XLibWindowManagerAdapterPrivate::XLibWindowManagerAdapterPrivate(
                                   XLibWindowManagerAdapter *q)
    :q_ptr(q)
{
    Window root;
    Status status;
    int xi_major = 2;
    int xi_minor = 2;
    m_mods.modifiers = XIAnyModifier;
    m_mods.status = 0;

    m_display = XOpenDisplay(NULL);
    Q_ASSERT_X(m_display, "XLibWindowManagerAdapter",
               "Failed to open connection to X server");

    status = XIQueryVersion(m_display, &xi_major, &xi_minor);
    Q_ASSERT_X(status == Success, "XLibWindowManagerAdapter",
               "Failed to query XInput version");

    if (xi_major < 2 || xi_minor < 2) {
        qFatal("XInput version of the server is too old (%d.%d)" ,
                  xi_major, xi_minor);
    }

    root = XDefaultRootWindow(m_display);
    XSelectInput(m_display, root, PropertyChangeMask);
    XMapWindow(m_display, root);
    XFlush(m_display);

    m_mask.deviceid = XIAllMasterDevices;
    m_mask.mask_len = XIMaskLen(XI_LASTEVENT);
    m_mask.mask = (unsigned char*)calloc(m_mask.mask_len, sizeof(unsigned char));

    XISetMask(m_mask.mask, XI_TouchBegin);
    XISetMask(m_mask.mask, XI_TouchUpdate);
    XISetMask(m_mask.mask, XI_TouchEnd);
    XISetMask(m_mask.mask, XI_TouchOwnership);
    XISetMask(m_mask.mask, XI_HierarchyChanged);

    XIGrabTouchBegin(m_display, XIAllMasterDevices, root, 0,
                     &m_mask, 1, &m_mods);
}
Exemple #12
0
/* Return 1 if XI2 is available, 0 otherwise */
static int has_xi2(Display *dpy)
{
    int major, minor;
    int rc;

    /* We support XI 2.0 */
    major = 2;
    minor = 0;

    rc = XIQueryVersion(dpy, &major, &minor);
    if (rc == BadRequest) {
        printf("No XI2 support. Server supports version %d.%d only.\n", major, minor);
        return 0;
    } else if (rc != Success) {
        fprintf(stderr, "Internal Error! This is a bug in Xlib.\n");
    }

    printf("XI2 supported. Server provides version %d.%d.\n", major, minor);

    return 1;
}
Exemple #13
0
// This function will add zero or more KeyboardMouse objects to devices.
void Init(std::vector<Core::Device*>& devices, void* const hwnd)
{
  Display* dpy = XOpenDisplay(nullptr);

  // xi_opcode is important; it will be used to identify XInput events by
  // the polling loop in UpdateInput.
  int xi_opcode, event, error;

  // verify that the XInput extension is available
  if (!XQueryExtension(dpy, "XInputExtension", &xi_opcode, &event, &error))
    return;

  // verify that the XInput extension is at at least version 2.0
  int major = 2, minor = 0;

  if (XIQueryVersion(dpy, &major, &minor) != Success)
    return;

  // register all master devices with Dolphin

  XIDeviceInfo* all_masters;
  XIDeviceInfo* current_master;
  int num_masters;

  all_masters = XIQueryDevice(dpy, XIAllMasterDevices, &num_masters);

  for (int i = 0; i < num_masters; i++)
  {
    current_master = &all_masters[i];
    if (current_master->use == XIMasterPointer)
      // Since current_master is a master pointer, its attachment must
      // be a master keyboard.
      devices.push_back(new KeyboardMouse((Window)hwnd, xi_opcode, current_master->deviceid,
                                          current_master->attachment));
  }

  XCloseDisplay(dpy);

  XIFreeDeviceInfo(all_masters);
}
Exemple #14
0
bool Output::setup(const int width, const int height)
{
#if 0
  /* Check if the XInput Extension is available */
  int event, error;
  if (!XQueryExtension(display, "XInputExtension", &opcode, &event, &error))
  {
    printf("X Input extension not available.\n");
    return false;
  }
  ROS_INFO_STREAM("XInputExtension available");

  /* Check for XI2 support */
  int major = 2, minor = 0;
  if (XIQueryVersion(display, &major, &minor) == BadRequest)
  {
    printf("XI2 not available. Server supports %d.%d\n", major, minor);
    return false;
  }
  ROS_INFO_STREAM("XI2 available");
#endif

  /*
  bm::setupX(display, win, width, height, opcode);
  gc = XCreateGC(display, win, 0, NULL);
  ximage = XGetImage(display, DefaultRootWindow(display), 0, 0, width, height, AllPlanes, ZPixmap);
  screen = DefaultScreenOfDisplay(display);
  XStoreName(display, win, name.c_str());

  ROS_INFO_STREAM(name << " created window " << CLVAL << display << " "
      << ximage <<CLNRM);

  if (!get_toplevel_parent(display, win, toplevel_parent)) {
    ROS_ERROR_STREAM(name << " couldn't get toplevel parent");
    return false;
  }
  */

  return true;
}
Exemple #15
0
int
main ()
{
	Display *dpy;

	int rc;
	int major = 2;
	int minor = 2;

	dpy = XOpenDisplay(NULL);


	rc = XIQueryVersion(dpy, &major, &minor);
	if (rc == Success)
		printf("XI2 supported. (%d.%d)\n", major, minor);
	else if (rc == BadRequest)
		printf("No XI2 support. (%d.%d only)\n", major, minor);
	else
		printf("Internal error\n");


	return 0;
}
gboolean
supports_xinput2_devices (int *opcode)
{
    int major, minor;

    if (supports_xinput_devices_with_opcode (opcode) == FALSE)
        return FALSE;

    gdk_error_trap_push ();

    major = 2;
    minor = 0;

    if (XIQueryVersion (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), &major, &minor) != Success) {
        gdk_error_trap_pop_ignored ();
        return FALSE;
    }
    gdk_error_trap_pop_ignored ();

    if ((major * 1000 + minor) < (2000))
        return FALSE;

    return TRUE;
}
Exemple #17
0
void
_ecore_x_input_init(void)
{
#ifdef ECORE_XI2
   int event, error;
   int major = 2, minor = 0;

   if (!XQueryExtension(_ecore_x_disp, "XInputExtension",
                        &_ecore_x_xi2_opcode, &event, &error))
     {
        _ecore_x_xi2_opcode = -1;
        return;
     }

   if (XIQueryVersion(_ecore_x_disp, &major, &minor) == BadRequest)
     {
        _ecore_x_xi2_opcode = -1;
        return;
     }

   _ecore_x_xi2_devs = XIQueryDevice(_ecore_x_disp, XIAllDevices,
                                     &_ecore_x_xi2_num);
#endif /* ifdef ECORE_XI2 */
} /* _ecore_x_input_init */
Exemple #18
0
static int xwinitxi2(struct fb *fb)
{
	int major = 2;
	int minor = 2;
	int xi_opcode, event, error;
	XIEventMask evmask[1];
	unsigned char mask[(XI_LASTEVENT + 7)/8] = {0};

	if(!XQueryExtension(fb->hw->display, "XInputExtension", &xi_opcode, &event, &error)) {
		printf("XInputExtension is not available\n");
		return -1;
	}
	if(XIQueryVersion(fb->hw->display, &major, &minor) == BadRequest) {
		printf("XI2 is not supported, server supports version %d.%d only\n", major, minor);
		return -1;
	} 
	XISetMask(mask, XI_RawMotion);
	evmask[0].deviceid = XIAllMasterDevices;
	evmask[0].mask_len = sizeof(mask);
	evmask[0].mask = mask;
	XISelectEvents(fb->hw->display, DefaultRootWindow(fb->hw->display), evmask, 1);
	XFlush(fb->hw->display);
	return 0;
}
Exemple #19
0
void XInputMTInputDevice::start()
{
    Status status;
    SDLDisplayEngine * pEngine = Player::get()->getDisplayEngine();
    glm::vec2 size(pEngine->getSize());
    glm::vec2 windowSize(pEngine->getWindowSize());
    m_DisplayScale.x = size.x/windowSize.x;
    m_DisplayScale.y = size.y/windowSize.y;

    SDL_SysWMinfo info;
    SDL_VERSION(&info.version);
    int rc = SDL_GetWMInfo(&info);
    AVG_ASSERT(rc != -1);
    s_pDisplay = info.info.x11.display;
    m_SDLLockFunc = info.info.x11.lock_func;
    m_SDLUnlockFunc = info.info.x11.unlock_func;

    m_SDLLockFunc();
    // XInput Extension available?
    int event, error;
    bool bOk = XQueryExtension(s_pDisplay, "XInputExtension", &m_XIOpcode, 
            &event, &error);
    if (!bOk) {
        throw Exception(AVG_ERR_MT_INIT, 
                "XInput multitouch event source: X Input extension not available.");
    }

    // Which version of XI2? 
    int major;
    int minor;
    status = XIQueryVersion(s_pDisplay, &major, &minor);
    if (status == BadRequest) {
        throw Exception(AVG_ERR_MT_INIT, 
                "XInput 2.1 multitouch event source: Server does not support XI2");
    }
    if (major < 2 || minor < 1) {
        throw Exception(AVG_ERR_MT_INIT, 
                "XInput multitouch event source: Supported version is "
                +toString(major)+"."+toString(minor)+". At least 2.1 is needed.");
    }
    findMTDevice();

    // SDL grabs the pointer in full screen mode. This breaks touchscreen usage.
    // Can't use SDL_WM_GrabInput(SDL_GRAB_OFF) because it doesn't work in full
    // screen mode. Get the display connection and do it manually.
    XUngrabPointer(info.info.x11.display, CurrentTime);

    XIEventMask mask;
    mask.deviceid = m_DeviceID;
    mask.mask_len = XIMaskLen(XI_LASTEVENT);
    mask.mask = (unsigned char *)calloc(mask.mask_len, sizeof(char));
    memset(mask.mask, 0, mask.mask_len);
    XISetMask(mask.mask, XI_TouchBegin);
    XISetMask(mask.mask, XI_TouchUpdate);
    XISetMask(mask.mask, XI_TouchEnd);

    status = XISelectEvents(s_pDisplay, info.info.x11.window, &mask, 1);
    AVG_ASSERT(status == Success);

    m_SDLUnlockFunc();

    SDL_SetEventFilter(XInputMTInputDevice::filterEvent);
  
    
    XIDetachSlaveInfo detInfo;
    detInfo.type = XIDetachSlave;
    detInfo.deviceid = m_DeviceID;
    XIChangeHierarchy(s_pDisplay, (XIAnyHierarchyChangeInfo *)&detInfo, 1);

    pEngine->setXIMTInputDevice(this);
    MultitouchInputDevice::start();
    AVG_TRACE(Logger::category::CONFIG, Logger::severity::INFO,
            "XInput Multitouch event source created.");
}
Exemple #20
0
// Initialize X11 display and look for supported X11 extensions
//
static GLFWbool initExtensions(void)
{
    _glfw.x11.vidmode.handle = dlopen("libXxf86vm.so.1", RTLD_LAZY | RTLD_GLOBAL);
    if (_glfw.x11.vidmode.handle)
    {
        _glfw.x11.vidmode.QueryExtension = (PFN_XF86VidModeQueryExtension)
            dlsym(_glfw.x11.vidmode.handle, "XF86VidModeQueryExtension");
        _glfw.x11.vidmode.GetGammaRamp = (PFN_XF86VidModeGetGammaRamp)
            dlsym(_glfw.x11.vidmode.handle, "XF86VidModeGetGammaRamp");
        _glfw.x11.vidmode.SetGammaRamp = (PFN_XF86VidModeSetGammaRamp)
            dlsym(_glfw.x11.vidmode.handle, "XF86VidModeSetGammaRamp");
        _glfw.x11.vidmode.GetGammaRampSize = (PFN_XF86VidModeGetGammaRampSize)
            dlsym(_glfw.x11.vidmode.handle, "XF86VidModeGetGammaRampSize");

        _glfw.x11.vidmode.available =
            XF86VidModeQueryExtension(_glfw.x11.display,
                                      &_glfw.x11.vidmode.eventBase,
                                      &_glfw.x11.vidmode.errorBase);
    }

    _glfw.x11.xi.handle = dlopen("libXi.so", RTLD_LAZY | RTLD_GLOBAL);
    if (_glfw.x11.xi.handle)
    {
        _glfw.x11.xi.QueryVersion = (PFN_XIQueryVersion)
            dlsym(_glfw.x11.xi.handle, "XIQueryVersion");
        _glfw.x11.xi.SelectEvents = (PFN_XISelectEvents)
            dlsym(_glfw.x11.xi.handle, "XISelectEvents");

        if (XQueryExtension(_glfw.x11.display,
                            "XInputExtension",
                            &_glfw.x11.xi.majorOpcode,
                            &_glfw.x11.xi.eventBase,
                            &_glfw.x11.xi.errorBase))
        {
            _glfw.x11.xi.major = 2;
            _glfw.x11.xi.minor = 0;

            if (XIQueryVersion(_glfw.x11.display,
                               &_glfw.x11.xi.major,
                               &_glfw.x11.xi.minor) == Success)
            {
                _glfw.x11.xi.available = GLFW_TRUE;
            }
        }
    }

    // Check for RandR extension
    if (XRRQueryExtension(_glfw.x11.display,
                          &_glfw.x11.randr.eventBase,
                          &_glfw.x11.randr.errorBase))
    {
        if (XRRQueryVersion(_glfw.x11.display,
                            &_glfw.x11.randr.major,
                            &_glfw.x11.randr.minor))
        {
            // The GLFW RandR path requires at least version 1.3
            if (_glfw.x11.randr.major > 1 || _glfw.x11.randr.minor >= 3)
                _glfw.x11.randr.available = GLFW_TRUE;
        }
        else
        {
            _glfwInputError(GLFW_PLATFORM_ERROR,
                            "X11: Failed to query RandR version");
        }
    }

    if (_glfw.x11.randr.available)
    {
        XRRScreenResources* sr = XRRGetScreenResourcesCurrent(_glfw.x11.display,
                                                              _glfw.x11.root);

        if (!sr->ncrtc || !XRRGetCrtcGammaSize(_glfw.x11.display, sr->crtcs[0]))
        {
            // This is either a headless system or an older Nvidia binary driver
            // with broken gamma support
            // Flag it as useless and fall back to Xf86VidMode gamma, if
            // available
            _glfwInputError(GLFW_PLATFORM_ERROR,
                            "X11: Detected broken RandR gamma ramp support");
            _glfw.x11.randr.gammaBroken = GLFW_TRUE;
        }

        if (!sr->ncrtc || !sr->noutput || !sr->nmode)
        {
            // This is either a headless system or broken Cygwin/X RandR
            // Flag it as useless and fall back to Xlib display functions
            _glfwInputError(GLFW_PLATFORM_ERROR,
                            "X11: Detected broken RandR monitor support");
            _glfw.x11.randr.monitorBroken = GLFW_TRUE;
        }

        XRRFreeScreenResources(sr);

        XRRSelectInput(_glfw.x11.display, _glfw.x11.root,
                       RROutputChangeNotifyMask);
    }

    if (XineramaQueryExtension(_glfw.x11.display,
                               &_glfw.x11.xinerama.major,
                               &_glfw.x11.xinerama.minor))
    {
        if (XineramaIsActive(_glfw.x11.display))
            _glfw.x11.xinerama.available = GLFW_TRUE;
    }

    // Check if Xkb is supported on this display
    _glfw.x11.xkb.major = 1;
    _glfw.x11.xkb.minor = 0;
    _glfw.x11.xkb.available =
        XkbQueryExtension(_glfw.x11.display,
                          &_glfw.x11.xkb.majorOpcode,
                          &_glfw.x11.xkb.eventBase,
                          &_glfw.x11.xkb.errorBase,
                          &_glfw.x11.xkb.major,
                          &_glfw.x11.xkb.minor);

    if (_glfw.x11.xkb.available)
    {
        Bool supported;

        if (XkbSetDetectableAutoRepeat(_glfw.x11.display, True, &supported))
        {
            if (supported)
                _glfw.x11.xkb.detectable = GLFW_TRUE;
        }
    }

    _glfw.x11.x11xcb.handle = dlopen("libX11-xcb.so.1", RTLD_LAZY | RTLD_GLOBAL);
    if (_glfw.x11.x11xcb.handle)
    {
        _glfw.x11.x11xcb.XGetXCBConnection = (PFN_XGetXCBConnection)
            dlsym(_glfw.x11.x11xcb.handle, "XGetXCBConnection");
    }

    // Update the key code LUT
    // FIXME: We should listen to XkbMapNotify events to track changes to
    // the keyboard mapping.
    createKeyTables();

    // Detect whether an EWMH-conformant window manager is running
    detectEWMH();

    // String format atoms
    _glfw.x11.NULL_ = XInternAtom(_glfw.x11.display, "NULL", False);
    _glfw.x11.UTF8_STRING =
        XInternAtom(_glfw.x11.display, "UTF8_STRING", False);
    _glfw.x11.COMPOUND_STRING =
        XInternAtom(_glfw.x11.display, "COMPOUND_STRING", False);
    _glfw.x11.ATOM_PAIR = XInternAtom(_glfw.x11.display, "ATOM_PAIR", False);

    // Custom selection property atom
    _glfw.x11.GLFW_SELECTION =
        XInternAtom(_glfw.x11.display, "GLFW_SELECTION", False);

    // ICCCM standard clipboard atoms
    _glfw.x11.TARGETS = XInternAtom(_glfw.x11.display, "TARGETS", False);
    _glfw.x11.MULTIPLE = XInternAtom(_glfw.x11.display, "MULTIPLE", False);
    _glfw.x11.CLIPBOARD = XInternAtom(_glfw.x11.display, "CLIPBOARD", False);

    // Clipboard manager atoms
    _glfw.x11.CLIPBOARD_MANAGER =
        XInternAtom(_glfw.x11.display, "CLIPBOARD_MANAGER", False);
    _glfw.x11.SAVE_TARGETS =
        XInternAtom(_glfw.x11.display, "SAVE_TARGETS", False);

    // Xdnd (drag and drop) atoms
    _glfw.x11.XdndAware = XInternAtom(_glfw.x11.display, "XdndAware", False);
    _glfw.x11.XdndEnter = XInternAtom(_glfw.x11.display, "XdndEnter", False);
    _glfw.x11.XdndPosition = XInternAtom(_glfw.x11.display, "XdndPosition", False);
    _glfw.x11.XdndStatus = XInternAtom(_glfw.x11.display, "XdndStatus", False);
    _glfw.x11.XdndActionCopy = XInternAtom(_glfw.x11.display, "XdndActionCopy", False);
    _glfw.x11.XdndDrop = XInternAtom(_glfw.x11.display, "XdndDrop", False);
    _glfw.x11.XdndFinished = XInternAtom(_glfw.x11.display, "XdndFinished", False);
    _glfw.x11.XdndSelection = XInternAtom(_glfw.x11.display, "XdndSelection", False);
    _glfw.x11.XdndTypeList = XInternAtom(_glfw.x11.display, "XdndTypeList", False);
    _glfw.x11.text_uri_list = XInternAtom(_glfw.x11.display, "text/uri-list", False);

    // ICCCM, EWMH and Motif window property atoms
    // These can be set safely even without WM support
    // The EWMH atoms that require WM support are handled in detectEWMH
    _glfw.x11.WM_PROTOCOLS =
        XInternAtom(_glfw.x11.display, "WM_PROTOCOLS", False);
    _glfw.x11.WM_STATE =
        XInternAtom(_glfw.x11.display, "WM_STATE", False);
    _glfw.x11.WM_DELETE_WINDOW =
        XInternAtom(_glfw.x11.display, "WM_DELETE_WINDOW", False);
    _glfw.x11.NET_WM_ICON =
        XInternAtom(_glfw.x11.display, "_NET_WM_ICON", False);
    _glfw.x11.NET_WM_PING =
        XInternAtom(_glfw.x11.display, "_NET_WM_PING", False);
    _glfw.x11.NET_WM_PID =
        XInternAtom(_glfw.x11.display, "_NET_WM_PID", False);
    _glfw.x11.NET_WM_NAME =
        XInternAtom(_glfw.x11.display, "_NET_WM_NAME", False);
    _glfw.x11.NET_WM_ICON_NAME =
        XInternAtom(_glfw.x11.display, "_NET_WM_ICON_NAME", False);
    _glfw.x11.NET_WM_BYPASS_COMPOSITOR =
        XInternAtom(_glfw.x11.display, "_NET_WM_BYPASS_COMPOSITOR", False);
    _glfw.x11.MOTIF_WM_HINTS =
        XInternAtom(_glfw.x11.display, "_MOTIF_WM_HINTS", False);

    return GLFW_TRUE;
}
Exemple #21
0
static void x11_init(void)
{
	memset(keys, 0, KEYMAX);
	memset(mouse, 0, 3);

	display = XOpenDisplay(0);
	screen = DefaultScreen(display);
	xvis = glXChooseVisual(display, screen, xAttrList);
	if(!xvis)
	{
		printf("glXChooseVisual() failed.\n");
		exit(1);
	}
	glx_context = glXCreateContext(display, xvis, 0, GL_TRUE);

	memset(&xwin_attr, 0, sizeof(XSetWindowAttributes));

	xwin_attr.colormap = XCreateColormap(display,
		RootWindow(display, xvis->screen), xvis->visual, AllocNone);
	
	xwin_attr.event_mask = ExposureMask | StructureNotifyMask |
		ButtonPressMask | ButtonReleaseMask | PointerMotionMask |
		KeyPressMask | KeyReleaseMask;

	x11_window();

	static char buf[] = { 0,0,0,0,0,0,0,0 };
	XColor black = { .red=0, .green=0, .blue=0 };
	Pixmap bitmap = XCreateBitmapFromData(display, window, buf, 2, 2);
	cursor_none = XCreatePixmapCursor(display, bitmap, bitmap,
			&black, &black, 0, 0);

	int event, error;
	if (!XQueryExtension(display, "XInputExtension", &opcode, &event, &error))
	{
		printf("X Input extension not available.\n");
		return;
	}
#ifdef ASD
	/* Which version of XI2? We support 2.0 */
	int major = 2, minor = 0;
	if (XIQueryVersion(display, &major, &minor) == BadRequest)
	{
		printf("XI2 not available. Server supports %d.%d\n", major, minor);
		return;
	}

	XIEventMask eventmask;
	unsigned char mask[3] = { 0,0,0 }; /* the actual mask */

	eventmask.deviceid = XIAllDevices;
	eventmask.mask_len = sizeof(mask); /* always in bytes */
	eventmask.mask = mask;
	/* now set the mask */
//	XISetMask(mask, XI_ButtonPress);
//	XISetMask(mask, XI_ButtonRelease);
	XISetMask(mask, XI_RawMotion);
//	XISetMask(mask, XI_KeyPress);

//	mask = mask | KeyReleaseMask | KeyPressMask;
	/* select on the window */
	Window root = DefaultRootWindow(display);
	XISelectEvents(display, root, &eventmask, 1);
//	XSetDeviceMode(display, mouse, Relative);
#endif
}

void print_rawmotion(XIRawEvent *event)
{
    int i;
    double *raw_valuator = event->raw_values,
           *valuator = event->valuators.values;

    for (i = 0; i < event->valuators.mask_len * 8; i++) {
        if (XIMaskIsSet(event->valuators.mask, i)) {
			switch(i) {
			case 0:
				mickey_x += *valuator;
				break;
			case 1:
				mickey_y += *valuator;
				break;
			default:
				break;
			}
            valuator++;
            raw_valuator++;
        }
    }
}
Exemple #22
0
int main (int argc, char** argv) {

	/* Connect to the X server */
	Display *display = XOpenDisplay(NULL);
	int screen_num;

	XGCValues values;
	Colormap colormap;

	/* Check if the XInput Extension is available */
	int opcode, event, error;
	if (!XQueryExtension(display, "XInputExtension", &opcode, &event, &error)) {
		printf("X Input extension not available.\n");
		return -1;
	}

	/* Check for XI2 support */
	int major = 2, minor = 0;
	if (XIQueryVersion(display, &major, &minor) == BadRequest) {
		printf("XI2 not available. Server supports %d.%d\n", major, minor);
		return -1;
	}

	/* Get screen size from display structure macro */
	screen_num = DefaultScreen(display);
	int display_width = DisplayWidth(display, screen_num);
	int display_height = DisplayHeight(display, screen_num);
	printf("screen_num: %d\n", screen_num);
	printf("display_width: %d\n", display_width);
	printf("display_height: %d\n", display_height);

	/* set window dimensions */
	int width = display_width/4*3;
	int height = display_height/4*3;
	int border_width = 3;
	printf("width: %d\n", width);
	printf("height: %d\n", height);

	/* create opaque window */
	Window win = XCreateSimpleWindow(display, DefaultRootWindow(display), 
			0, 0, width, height, border_width, WhitePixel(display,
			screen_num), BlackPixel(display,screen_num));

	printf("win: %d\n", (int)win);

	/* Display window */
	XMapWindow(display, win);
	XSync( display, False );

	/* Set default values for pens (GCs) to draw lines with */
	values.foreground = WhitePixel(display, screen_num);
	values.line_width = 10;
	values.line_style = LineSolid;
	values.cap_style = CapRound;

	/* Create colormap */
	colormap = DefaultColormap(display, screen_num);


	/* Set up MPX events */
	XIEventMask eventmask;
	unsigned char mask[1] = { 0 };

	eventmask.deviceid = XIAllMasterDevices;
	eventmask.mask_len = sizeof(mask);
	eventmask.mask = mask;

	/* Events we want to listen for */
	XISetMask(mask, XI_Motion);
	XISetMask(mask, XI_ButtonPress);
	XISetMask(mask, XI_ButtonRelease);
	XISetMask(mask, XI_KeyPress);
	XISetMask(mask, XI_KeyRelease);

	/* Register events on the window */
	XISelectEvents(display, win, &eventmask, 1);


	/* Maximum pointer count */
	const unsigned int numPointers = 0xFF;
	Pointer pointers[numPointers];

	/* Initialize pointers */
	int i;
	for(i=0; i<numPointers; i++) {
		pointers[i].down = 0;
		pointers[i].p.x = -1;
		pointers[i].p.y = -1;
		pointers[i].lastp.x = -1;
		pointers[i].lastp.y = -1;
	}

	/* Event loop */
	while(1) {

		XEvent ev;
		/* Get next event; blocks until an event occurs */
		XNextEvent(display, &ev);
		if (ev.xcookie.type == GenericEvent &&
		    ev.xcookie.extension == opcode &&
		    XGetEventData(display, &ev.xcookie))
		{
			XIDeviceEvent* evData = (XIDeviceEvent*)(ev.xcookie.data);
			int deviceID = evData->deviceid;
			Pointer *pointer = &pointers[deviceID];

			switch(ev.xcookie.evtype)
			{
			case XI_Motion:
				printf("motion\n");
				if(pointer->down) {
					/* Draw a line from the last point to the next one;
					   multiple lines of these create a stroke */
					XDrawLine(display, win, pointer->gc, pointer->lastp.x,
					          pointer->lastp.y, evData->event_x, evData->event_y);

					// Comment out the following for interesting structures
					pointer->lastp.x = evData->event_x;
					pointer->lastp.y = evData->event_y;
				}
				break;

			case XI_ButtonPress:
				printf("click - ");
				printf("button: %d - ", evData->detail);
				printf("abs X:%f Y:%f - ", evData->root_x, evData->root_y);
				printf("win X:%f Y:%f\n", evData->event_x, evData->event_y);

				/* Create random color for each stroke */
				values.foreground = rand() % 0xFFFFFF;
				pointer->gc = XCreateGC(display, win,
				                        GCForeground|GCLineWidth|GCLineStyle|GCCapStyle,
				                        &values);

				XDrawLine(display, win, pointer->gc, evData->event_x,
					      evData->event_y, evData->event_x, evData->event_y);

				pointer->down = 1;
				pointer->p.x = evData->event_x;
				pointer->p.y = evData->event_y;
				pointer->lastp.x = evData->event_x;
				pointer->lastp.y = evData->event_y;

				break;

			case XI_ButtonRelease:
				printf("unclick\n");
				pointer->down = 0;
				break;

			case XI_KeyPress:
				printf("key down\n");
				break;

			case XI_KeyRelease:
				printf("key up\n");
				break;
			}
		}
		XFreeEventData(display, &ev.xcookie);
	}

	XDestroyWindow(display, win);
	return 0;

}
Exemple #23
0
void X11Extras::x11ResetMouseAccelerationChange()
 {
    //QTextStream out(stdout);

    int xi_opcode, event, error;
    xi_opcode = event = error = 0;
    Display *display = this->display();

    bool result = XQueryExtension(display, "XInputExtension", &xi_opcode, &event, &error);
    if (!result)
    {
        Logger::LogInfo(tr("xinput extension was not found. No mouse acceleration changes will occur."));
        //out << tr("xinput extension was not found. No mouse acceleration changes will occur.") << endl;
    }
    else
    {
        int ximajor = 2, ximinor = 0;
        if (XIQueryVersion(display, &ximajor, &ximinor) != Success)
        {
            Logger::LogInfo(tr("xinput version must be at least 2.0. No mouse acceleration changes will occur."));
            //out << tr("xinput version must be at least 2.0. No mouse acceleration changes will occur.") << endl;
        }
    }

    if (result)
    {
        XIDeviceInfo *all_devices = 0;
        XIDeviceInfo *current_devices = 0;
        XIDeviceInfo *mouse_device = 0;

        int num_devices = 0;
        all_devices = XIQueryDevice(display, XIAllDevices, &num_devices);
        for (int i=0; i < num_devices; i++)
        {
            current_devices = &all_devices[i];
            if (current_devices->use == XISlavePointer && QString::fromUtf8(current_devices->name) == mouseDeviceName)
            {
                Logger::LogInfo(tr("Virtual pointer found with id=%1.").arg(current_devices->deviceid));
                //out << tr("Virtual pointer found with id=%1.").arg(current_devices->deviceid)
                //    << endl;
                mouse_device = current_devices;
            }
        }

        if (mouse_device)
        {
            XDevice *device = XOpenDevice(display, mouse_device->deviceid);

            int num_feedbacks = 0;
            int feedback_id = -1;
            XFeedbackState *feedbacks = XGetFeedbackControl(display, device, &num_feedbacks);
            XFeedbackState *temp = feedbacks;
            for (int i=0; (i < num_feedbacks) && (feedback_id == -1); i++)
            {
                if (temp->c_class == PtrFeedbackClass)
                {
                    feedback_id = temp->id;
                }

                if (i+1 < num_feedbacks)
                {
                    temp = (XFeedbackState*) ((char*) temp + temp->length);
                }
            }

            XFree(feedbacks);
            feedbacks = temp = 0;

            if (feedback_id <= -1)
            {
                Logger::LogInfo(tr("PtrFeedbackClass was not found for virtual pointer."
                                   "No change to mouse acceleration will occur for device with id=%1").arg(device->device_id));
                //out << tr("PtrFeedbackClass was not found for virtual pointer."
                //          "No change to mouse acceleration will occur for device with id=%1").arg(device->device_id)
                //    << endl;
                result = false;
            }
            else
            {
                Logger::LogInfo(tr("Changing mouse acceleration for device with id=%1").arg(device->device_id));
                //out << tr("Changing mouse acceleration for device with id=%1").arg(device->device_id)
                //    << endl;

                XPtrFeedbackControl	feedback;
                feedback.c_class = PtrFeedbackClass;
                feedback.length = sizeof(XPtrFeedbackControl);
                feedback.id = feedback_id;
                feedback.threshold = 0;
                feedback.accelNum = 1;
                feedback.accelDenom = 1;

                XChangeFeedbackControl(display, device, DvAccelNum|DvAccelDenom|DvThreshold,
                           (XFeedbackControl*) &feedback);

                XSync(display, false);
            }

            XCloseDevice(display, device);
        }

        if (all_devices)
        {
            XIFreeDeviceInfo(all_devices);
        }
     }
 }
int main(int argc, char **argv) {

    int doDaemonize = 1;

    int i;
    for (i = 1; i < argc; i++) {
        if (strcmp(argv[i], "--debug") == 0) {
            doDaemonize = 0;
            debugMode = 1;
        }

    }

    if (doDaemonize) {
        daemonize();
    }

    /* Connect to X server */
    if ((display = XOpenDisplay((char *) NULL)) == NULL) {
        fprintf(stderr, "Couldn't connect to X server\n");
        exit(1);
    }

    absXAtom = XInternAtom(display, "Abs X", FALSE);
    absYAtom = XInternAtom(display, "Abs Y", FALSE);
    floatAtom = XInternAtom(display, "FLOAT", FALSE);

    /* Read X data */
    screenNum = DefaultScreen(display);

    root = RootWindow(display, screenNum);

    lastScreenWidth = DisplayWidth(display, screenNum);
    lastScreenHeight = DisplayHeight(display, screenNum);

    /* We have two threads accessing X */
    XInitThreads();


    int opcode, event, error;
    if (!XQueryExtension(display, "RANDR", &opcode, &event,
                         &error)) {
        printf("X RANDR extension not available.\n");
        XCloseDisplay(display);
        exit(1);
    }

    /* Which version of XRandR? We support 1.3 */
    int major = 1, minor = 3;
    if (!XRRQueryVersion(display, &major, &minor)) {
        printf("XRandR version not available.\n");
        XCloseDisplay(display);
        exit(1);
    } else if(!(major>1 || (major == 1 && minor >= 3))) {
        printf("XRandR 1.3 not available. Server supports %d.%d\n", major, minor);
        XCloseDisplay(display);
        exit(1);
    }

    /* XInput Extension available? */
    if (!XQueryExtension(display, "XInputExtension", &opcode, &event,
                         &error)) {
        printf("X Input extension not available.\n");
        XCloseDisplay(display);
        exit(1);
    }

    /* Which version of XI2? We support 2.0 */
    major = 2;
    minor = 0;
    if (XIQueryVersion(display, &major, &minor) == BadRequest) {
        printf("XI2 not available. Server supports %d.%d\n", major, minor);
        XCloseDisplay(display);
        exit(1);
    }



    XRRSelectInput(display, root, RRScreenChangeNotifyMask | RROutputChangeNotifyMask | RROutputPropertyNotifyMask | RRCrtcChangeNotifyMask);

    /* Register for XInput device change events */
    XIEventMask eventmask;
    unsigned char mask[2] = { 0, 0 }; /* the actual mask */

    eventmask.deviceid = XIAllDevices;
    eventmask.mask_len = sizeof(mask); /* always in bytes */
    eventmask.mask = mask;
    /* now set the mask */
    XISetMask(mask, XI_HierarchyChanged);

    /* select on the window */
    XISelectEvents(display, root, &eventmask, 1);

    loadSettings(&profiles, NULL, NULL);

    handleDeviceChange();

    sigemptyset(&signalSet);
    sigaddset(&signalSet, SIGUSR1);
    pthread_sigmask (SIG_BLOCK, &signalSet, NULL);
    if(pthread_create(&signalThread, NULL, signalThreadFunction, NULL)) {
        printf("Couldn't create signal thread.\n");
    }


    xLoop();

    freeSettings(&profiles);

    XCloseDisplay(display);
    return 0;

}
Exemple #25
0
// Initialize X11 display and look for supported X11 extensions
//
static GLboolean initExtensions(void)
{
    Bool supported;

    // Find or create window manager atoms
    _glfw.x11.WM_STATE = XInternAtom(_glfw.x11.display, "WM_STATE", False);
    _glfw.x11.WM_DELETE_WINDOW = XInternAtom(_glfw.x11.display,
                                             "WM_DELETE_WINDOW",
                                             False);
    _glfw.x11.MOTIF_WM_HINTS = XInternAtom(_glfw.x11.display,
                                           "_MOTIF_WM_HINTS",
                                           False);

    // Check for XF86VidMode extension
    _glfw.x11.vidmode.available =
        XF86VidModeQueryExtension(_glfw.x11.display,
                                  &_glfw.x11.vidmode.eventBase,
                                  &_glfw.x11.vidmode.errorBase);

    // Check for RandR extension
    _glfw.x11.randr.available =
        XRRQueryExtension(_glfw.x11.display,
                          &_glfw.x11.randr.eventBase,
                          &_glfw.x11.randr.errorBase);

    if (_glfw.x11.randr.available)
    {
        if (!XRRQueryVersion(_glfw.x11.display,
                             &_glfw.x11.randr.versionMajor,
                             &_glfw.x11.randr.versionMinor))
        {
            _glfwInputError(GLFW_PLATFORM_ERROR,
                            "X11: Failed to query RandR version");
            return GL_FALSE;
        }

        // The GLFW RandR path requires at least version 1.3
        if (_glfw.x11.randr.versionMajor == 1 &&
            _glfw.x11.randr.versionMinor < 3)
        {
            _glfw.x11.randr.available = GL_FALSE;
        }
    }

    if (XQueryExtension(_glfw.x11.display,
                        "XInputExtension",
                        &_glfw.x11.xi.majorOpcode,
                        &_glfw.x11.xi.eventBase,
                        &_glfw.x11.xi.errorBase))
    {
        _glfw.x11.xi.versionMajor = 2;
        _glfw.x11.xi.versionMinor = 0;

        if (XIQueryVersion(_glfw.x11.display,
                           &_glfw.x11.xi.versionMajor,
                           &_glfw.x11.xi.versionMinor) != BadRequest)
        {
            _glfw.x11.xi.available = GL_TRUE;
        }
    }

    // Check if Xkb is supported on this display
    _glfw.x11.xkb.versionMajor = 1;
    _glfw.x11.xkb.versionMinor = 0;
    if (!XkbQueryExtension(_glfw.x11.display,
                           &_glfw.x11.xkb.majorOpcode,
                           &_glfw.x11.xkb.eventBase,
                           &_glfw.x11.xkb.errorBase,
                           &_glfw.x11.xkb.versionMajor,
                           &_glfw.x11.xkb.versionMinor))
    {
        _glfwInputError(GLFW_PLATFORM_ERROR,
                        "X11: The keyboard extension is not available");
        return GL_FALSE;
    }

    if (!XkbSetDetectableAutoRepeat(_glfw.x11.display, True, &supported))
    {
        _glfwInputError(GLFW_PLATFORM_ERROR,
                        "X11: Failed to set detectable key repeat");
        return GL_FALSE;
    }

    if (!supported)
    {
        _glfwInputError(GLFW_PLATFORM_ERROR,
                        "X11: Detectable key repeat is not supported");
        return GL_FALSE;
    }

    // Update the key code LUT
    // FIXME: We should listen to XkbMapNotify events to track changes to
    // the keyboard mapping.
    updateKeyCodeLUT();

    // Detect whether an EWMH-conformant window manager is running
    detectEWMH();

    // Find or create string format atoms
    _glfw.x11.UTF8_STRING =
        XInternAtom(_glfw.x11.display, "UTF8_STRING", False);
    _glfw.x11.COMPOUND_STRING =
        XInternAtom(_glfw.x11.display, "COMPOUND_STRING", False);
    _glfw.x11.ATOM_PAIR = XInternAtom(_glfw.x11.display, "ATOM_PAIR", False);

    // Find or create selection property atom
    _glfw.x11.GLFW_SELECTION =
        XInternAtom(_glfw.x11.display, "GLFW_SELECTION", False);

    // Find or create standard clipboard atoms
    _glfw.x11.TARGETS = XInternAtom(_glfw.x11.display, "TARGETS", False);
    _glfw.x11.MULTIPLE = XInternAtom(_glfw.x11.display, "MULTIPLE", False);
    _glfw.x11.CLIPBOARD = XInternAtom(_glfw.x11.display, "CLIPBOARD", False);

    // Find or create clipboard manager atoms
    _glfw.x11.CLIPBOARD_MANAGER =
        XInternAtom(_glfw.x11.display, "CLIPBOARD_MANAGER", False);
    _glfw.x11.SAVE_TARGETS =
        XInternAtom(_glfw.x11.display, "SAVE_TARGETS", False);

    return GL_TRUE;
}
Exemple #26
0
// Initialize X11 display and look for supported X11 extensions
//
static GLboolean initDisplay(void)
{
    Bool supported;

    _glfw.x11.display = XOpenDisplay(NULL);
    if (!_glfw.x11.display)
    {
        _glfwInputError(GLFW_API_UNAVAILABLE, "X11: Failed to open X display");
        return GL_FALSE;
    }

    // As the API currently doesn't understand multiple display devices, we hard-code
    // this choice and hope for the best
    _glfw.x11.screen = DefaultScreen(_glfw.x11.display);
    _glfw.x11.root = RootWindow(_glfw.x11.display, _glfw.x11.screen);

    // Find or create window manager atoms
    _glfw.x11.WM_STATE = XInternAtom(_glfw.x11.display, "WM_STATE", False);
    _glfw.x11.WM_DELETE_WINDOW = XInternAtom(_glfw.x11.display,
                                             "WM_DELETE_WINDOW",
                                             False);

    // Check for XF86VidMode extension
    _glfw.x11.vidmode.available =
        XF86VidModeQueryExtension(_glfw.x11.display,
                                  &_glfw.x11.vidmode.eventBase,
                                  &_glfw.x11.vidmode.errorBase);

    // Check for RandR extension
    _glfw.x11.randr.available =
        XRRQueryExtension(_glfw.x11.display,
                          &_glfw.x11.randr.eventBase,
                          &_glfw.x11.randr.errorBase);

    if (_glfw.x11.randr.available)
    {
        if (!XRRQueryVersion(_glfw.x11.display,
                             &_glfw.x11.randr.versionMajor,
                             &_glfw.x11.randr.versionMinor))
        {
            _glfwInputError(GLFW_PLATFORM_ERROR,
                            "X11: Failed to query RandR version");
            return GL_FALSE;
        }

        // The GLFW RandR path requires at least version 1.3
        if (_glfw.x11.randr.versionMajor == 1 &&
            _glfw.x11.randr.versionMinor < 3)
        {
            _glfw.x11.randr.available = GL_FALSE;
        }
    }

    if (XQueryExtension(_glfw.x11.display,
                        "XInputExtension",
                        &_glfw.x11.xi2.majorOpcode,
                        &_glfw.x11.xi2.eventBase,
                        &_glfw.x11.xi2.errorBase))
    {
        _glfw.x11.xi2.versionMajor = 2;
        _glfw.x11.xi2.versionMinor = 0;

        if (XIQueryVersion(_glfw.x11.display,
                           &_glfw.x11.xi2.versionMajor,
                           &_glfw.x11.xi2.versionMinor) != BadRequest)
        {
            _glfw.x11.xi2.available = GL_TRUE;
        }
    }

    // Check if Xkb is supported on this display
    _glfw.x11.xkb.versionMajor = 1;
    _glfw.x11.xkb.versionMinor = 0;
    if (!XkbQueryExtension(_glfw.x11.display,
                           &_glfw.x11.xkb.majorOpcode,
                           &_glfw.x11.xkb.eventBase,
                           &_glfw.x11.xkb.errorBase,
                           &_glfw.x11.xkb.versionMajor,
                           &_glfw.x11.xkb.versionMinor))
    {
        _glfwInputError(GLFW_PLATFORM_ERROR,
                        "X11: The keyboard extension is not available");
        return GL_FALSE;
    }

    if (!XkbSetDetectableAutoRepeat(_glfw.x11.display, True, &supported))
    {
        _glfwInputError(GLFW_PLATFORM_ERROR,
                        "X11: Failed to set detectable key repeat");
        return GL_FALSE;
    }

    if (!supported)
    {
        _glfwInputError(GLFW_PLATFORM_ERROR,
                        "X11: Detectable key repeat is not supported");
        return GL_FALSE;
    }

    // Update the key code LUT
    // FIXME: We should listen to XkbMapNotify events to track changes to
    // the keyboard mapping.
    updateKeyCodeLUT();

    // Detect whether an EWMH-conformant window manager is running
    detectEWMH();

    // Find or create string format atoms
    _glfw.x11.UTF8_STRING =
        XInternAtom(_glfw.x11.display, "UTF8_STRING", False);
    _glfw.x11.COMPOUND_STRING =
        XInternAtom(_glfw.x11.display, "COMPOUND_STRING", False);

    // Find or create selection property atom
    _glfw.x11.selection.property =
        XInternAtom(_glfw.x11.display, "GLFW_SELECTION", False);

    // Find or create standard clipboard atoms
    _glfw.x11.TARGETS = XInternAtom(_glfw.x11.display, "TARGETS", False);
    _glfw.x11.CLIPBOARD = XInternAtom(_glfw.x11.display, "CLIPBOARD", False);

    // Find or create selection target atoms
    _glfw.x11.selection.formats[_GLFW_CLIPBOARD_FORMAT_UTF8] =
        _glfw.x11.UTF8_STRING;
    _glfw.x11.selection.formats[_GLFW_CLIPBOARD_FORMAT_COMPOUND] =
        _glfw.x11.COMPOUND_STRING;
    _glfw.x11.selection.formats[_GLFW_CLIPBOARD_FORMAT_STRING] =
        XA_STRING;

    return GL_TRUE;
}
Exemple #27
0
// Look for and initialize supported X11 extensions
//
static GLFWbool initExtensions(void)
{
    _glfw.x11.vidmode.handle = _glfw_dlopen("libXxf86vm.so.1");
    if (_glfw.x11.vidmode.handle)
    {
        _glfw.x11.vidmode.QueryExtension = (PFN_XF86VidModeQueryExtension)
            _glfw_dlsym(_glfw.x11.vidmode.handle, "XF86VidModeQueryExtension");
        _glfw.x11.vidmode.GetGammaRamp = (PFN_XF86VidModeGetGammaRamp)
            _glfw_dlsym(_glfw.x11.vidmode.handle, "XF86VidModeGetGammaRamp");
        _glfw.x11.vidmode.SetGammaRamp = (PFN_XF86VidModeSetGammaRamp)
            _glfw_dlsym(_glfw.x11.vidmode.handle, "XF86VidModeSetGammaRamp");
        _glfw.x11.vidmode.GetGammaRampSize = (PFN_XF86VidModeGetGammaRampSize)
            _glfw_dlsym(_glfw.x11.vidmode.handle, "XF86VidModeGetGammaRampSize");

        _glfw.x11.vidmode.available =
            XF86VidModeQueryExtension(_glfw.x11.display,
                                      &_glfw.x11.vidmode.eventBase,
                                      &_glfw.x11.vidmode.errorBase);
    }

#if defined(__CYGWIN__)
    _glfw.x11.xi.handle = _glfw_dlopen("libXi-6.so");
#else
    _glfw.x11.xi.handle = _glfw_dlopen("libXi.so.6");
#endif
    if (_glfw.x11.xi.handle)
    {
        _glfw.x11.xi.QueryVersion = (PFN_XIQueryVersion)
            _glfw_dlsym(_glfw.x11.xi.handle, "XIQueryVersion");
        _glfw.x11.xi.SelectEvents = (PFN_XISelectEvents)
            _glfw_dlsym(_glfw.x11.xi.handle, "XISelectEvents");

        if (XQueryExtension(_glfw.x11.display,
                            "XInputExtension",
                            &_glfw.x11.xi.majorOpcode,
                            &_glfw.x11.xi.eventBase,
                            &_glfw.x11.xi.errorBase))
        {
            _glfw.x11.xi.major = 2;
            _glfw.x11.xi.minor = 0;

            if (XIQueryVersion(_glfw.x11.display,
                               &_glfw.x11.xi.major,
                               &_glfw.x11.xi.minor) == Success)
            {
                _glfw.x11.xi.available = GLFW_TRUE;
            }
        }
    }

#if defined(__CYGWIN__)
    _glfw.x11.randr.handle = _glfw_dlopen("libXrandr-2.so");
#else
    _glfw.x11.randr.handle = _glfw_dlopen("libXrandr.so.2");
#endif
    if (_glfw.x11.randr.handle)
    {
        _glfw.x11.randr.AllocGamma = (PFN_XRRAllocGamma)
            _glfw_dlsym(_glfw.x11.randr.handle, "XRRAllocGamma");
        _glfw.x11.randr.FreeGamma = (PFN_XRRFreeGamma)
            _glfw_dlsym(_glfw.x11.randr.handle, "XRRFreeGamma");
        _glfw.x11.randr.FreeCrtcInfo = (PFN_XRRFreeCrtcInfo)
            _glfw_dlsym(_glfw.x11.randr.handle, "XRRFreeCrtcInfo");
        _glfw.x11.randr.FreeGamma = (PFN_XRRFreeGamma)
            _glfw_dlsym(_glfw.x11.randr.handle, "XRRFreeGamma");
        _glfw.x11.randr.FreeOutputInfo = (PFN_XRRFreeOutputInfo)
            _glfw_dlsym(_glfw.x11.randr.handle, "XRRFreeOutputInfo");
        _glfw.x11.randr.FreeScreenResources = (PFN_XRRFreeScreenResources)
            _glfw_dlsym(_glfw.x11.randr.handle, "XRRFreeScreenResources");
        _glfw.x11.randr.GetCrtcGamma = (PFN_XRRGetCrtcGamma)
            _glfw_dlsym(_glfw.x11.randr.handle, "XRRGetCrtcGamma");
        _glfw.x11.randr.GetCrtcGammaSize = (PFN_XRRGetCrtcGammaSize)
            _glfw_dlsym(_glfw.x11.randr.handle, "XRRGetCrtcGammaSize");
        _glfw.x11.randr.GetCrtcInfo = (PFN_XRRGetCrtcInfo)
            _glfw_dlsym(_glfw.x11.randr.handle, "XRRGetCrtcInfo");
        _glfw.x11.randr.GetOutputInfo = (PFN_XRRGetOutputInfo)
            _glfw_dlsym(_glfw.x11.randr.handle, "XRRGetOutputInfo");
        _glfw.x11.randr.GetOutputPrimary = (PFN_XRRGetOutputPrimary)
            _glfw_dlsym(_glfw.x11.randr.handle, "XRRGetOutputPrimary");
        _glfw.x11.randr.GetScreenResourcesCurrent = (PFN_XRRGetScreenResourcesCurrent)
            _glfw_dlsym(_glfw.x11.randr.handle, "XRRGetScreenResourcesCurrent");
        _glfw.x11.randr.QueryExtension = (PFN_XRRQueryExtension)
            _glfw_dlsym(_glfw.x11.randr.handle, "XRRQueryExtension");
        _glfw.x11.randr.QueryVersion = (PFN_XRRQueryVersion)
            _glfw_dlsym(_glfw.x11.randr.handle, "XRRQueryVersion");
        _glfw.x11.randr.SelectInput = (PFN_XRRSelectInput)
            _glfw_dlsym(_glfw.x11.randr.handle, "XRRSelectInput");
        _glfw.x11.randr.SetCrtcConfig = (PFN_XRRSetCrtcConfig)
            _glfw_dlsym(_glfw.x11.randr.handle, "XRRSetCrtcConfig");
        _glfw.x11.randr.SetCrtcGamma = (PFN_XRRSetCrtcGamma)
            _glfw_dlsym(_glfw.x11.randr.handle, "XRRSetCrtcGamma");
        _glfw.x11.randr.UpdateConfiguration = (PFN_XRRUpdateConfiguration)
            _glfw_dlsym(_glfw.x11.randr.handle, "XRRUpdateConfiguration");

        if (XRRQueryExtension(_glfw.x11.display,
                              &_glfw.x11.randr.eventBase,
                              &_glfw.x11.randr.errorBase))
        {
            if (XRRQueryVersion(_glfw.x11.display,
                                &_glfw.x11.randr.major,
                                &_glfw.x11.randr.minor))
            {
                // The GLFW RandR path requires at least version 1.3
                if (_glfw.x11.randr.major > 1 || _glfw.x11.randr.minor >= 3)
                    _glfw.x11.randr.available = GLFW_TRUE;
            }
            else
            {
                _glfwInputError(GLFW_PLATFORM_ERROR,
                                "X11: Failed to query RandR version");
            }
        }
    }

    if (_glfw.x11.randr.available)
    {
        XRRScreenResources* sr = XRRGetScreenResourcesCurrent(_glfw.x11.display,
                                                              _glfw.x11.root);

        if (!sr->ncrtc || !XRRGetCrtcGammaSize(_glfw.x11.display, sr->crtcs[0]))
        {
            // This is likely an older Nvidia driver with broken gamma support
            // Flag it as useless and fall back to xf86vm gamma, if available
            _glfw.x11.randr.gammaBroken = GLFW_TRUE;
        }

        if (!sr->ncrtc)
        {
            // A system without CRTCs is likely a system with broken RandR
            // Disable the RandR monitor path and fall back to core functions
            _glfw.x11.randr.monitorBroken = GLFW_TRUE;
        }

        XRRFreeScreenResources(sr);
    }

    if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
    {
        XRRSelectInput(_glfw.x11.display, _glfw.x11.root,
                       RROutputChangeNotifyMask);
    }

#if defined(__CYGWIN__)
    _glfw.x11.xcursor.handle = _glfw_dlopen("libXcursor-1.so");
#else
    _glfw.x11.xcursor.handle = _glfw_dlopen("libXcursor.so.1");
#endif
    if (_glfw.x11.xcursor.handle)
    {
        _glfw.x11.xcursor.ImageCreate = (PFN_XcursorImageCreate)
            _glfw_dlsym(_glfw.x11.xcursor.handle, "XcursorImageCreate");
        _glfw.x11.xcursor.ImageDestroy = (PFN_XcursorImageDestroy)
            _glfw_dlsym(_glfw.x11.xcursor.handle, "XcursorImageDestroy");
        _glfw.x11.xcursor.ImageLoadCursor = (PFN_XcursorImageLoadCursor)
            _glfw_dlsym(_glfw.x11.xcursor.handle, "XcursorImageLoadCursor");
    }

#if defined(__CYGWIN__)
    _glfw.x11.xinerama.handle = _glfw_dlopen("libXinerama-1.so");
#else
    _glfw.x11.xinerama.handle = _glfw_dlopen("libXinerama.so.1");
#endif
    if (_glfw.x11.xinerama.handle)
    {
        _glfw.x11.xinerama.IsActive = (PFN_XineramaIsActive)
            _glfw_dlsym(_glfw.x11.xinerama.handle, "XineramaIsActive");
        _glfw.x11.xinerama.QueryExtension = (PFN_XineramaQueryExtension)
            _glfw_dlsym(_glfw.x11.xinerama.handle, "XineramaQueryExtension");
        _glfw.x11.xinerama.QueryScreens = (PFN_XineramaQueryScreens)
            _glfw_dlsym(_glfw.x11.xinerama.handle, "XineramaQueryScreens");

        if (XineramaQueryExtension(_glfw.x11.display,
                                   &_glfw.x11.xinerama.major,
                                   &_glfw.x11.xinerama.minor))
        {
            if (XineramaIsActive(_glfw.x11.display))
                _glfw.x11.xinerama.available = GLFW_TRUE;
        }
    }

    _glfw.x11.xkb.major = 1;
    _glfw.x11.xkb.minor = 0;
    _glfw.x11.xkb.available =
        XkbQueryExtension(_glfw.x11.display,
                          &_glfw.x11.xkb.majorOpcode,
                          &_glfw.x11.xkb.eventBase,
                          &_glfw.x11.xkb.errorBase,
                          &_glfw.x11.xkb.major,
                          &_glfw.x11.xkb.minor);

    if (_glfw.x11.xkb.available)
    {
        Bool supported;

        if (XkbSetDetectableAutoRepeat(_glfw.x11.display, True, &supported))
        {
            if (supported)
                _glfw.x11.xkb.detectable = GLFW_TRUE;
        }
    }

#if defined(__CYGWIN__)
    _glfw.x11.x11xcb.handle = _glfw_dlopen("libX11-xcb-1.so");
#else
    _glfw.x11.x11xcb.handle = _glfw_dlopen("libX11-xcb.so.1");
#endif
    if (_glfw.x11.x11xcb.handle)
    {
        _glfw.x11.x11xcb.GetXCBConnection = (PFN_XGetXCBConnection)
            _glfw_dlsym(_glfw.x11.x11xcb.handle, "XGetXCBConnection");
    }

#if defined(__CYGWIN__)
    _glfw.x11.xrender.handle = _glfw_dlopen("libXrender-1.so");
#else
    _glfw.x11.xrender.handle = _glfw_dlopen("libXrender.so.1");
#endif
    if (_glfw.x11.xrender.handle)
    {
        _glfw.x11.xrender.QueryExtension = (PFN_XRenderQueryExtension)
            _glfw_dlsym(_glfw.x11.xrender.handle, "XRenderQueryExtension");
        _glfw.x11.xrender.QueryVersion = (PFN_XRenderQueryVersion)
            _glfw_dlsym(_glfw.x11.xrender.handle, "XRenderQueryVersion");
        _glfw.x11.xrender.FindVisualFormat = (PFN_XRenderFindVisualFormat)
            _glfw_dlsym(_glfw.x11.xrender.handle, "XRenderFindVisualFormat");

        if (XRenderQueryExtension(_glfw.x11.display,
                                  &_glfw.x11.xrender.errorBase,
                                  &_glfw.x11.xrender.eventBase))
        {
            if (XRenderQueryVersion(_glfw.x11.display,
                                    &_glfw.x11.xrender.major,
                                    &_glfw.x11.xrender.minor))
            {
                _glfw.x11.xrender.available = GLFW_TRUE;
            }
        }
    }

    // Update the key code LUT
    // FIXME: We should listen to XkbMapNotify events to track changes to
    // the keyboard mapping.
    createKeyTables();

    // Detect whether an EWMH-conformant window manager is running
    detectEWMH();

    // String format atoms
    _glfw.x11.NULL_ = XInternAtom(_glfw.x11.display, "NULL", False);
    _glfw.x11.UTF8_STRING = XInternAtom(_glfw.x11.display, "UTF8_STRING", False);
    _glfw.x11.ATOM_PAIR = XInternAtom(_glfw.x11.display, "ATOM_PAIR", False);

    // Custom selection property atom
    _glfw.x11.GLFW_SELECTION =
        XInternAtom(_glfw.x11.display, "GLFW_SELECTION", False);

    // ICCCM standard clipboard atoms
    _glfw.x11.TARGETS = XInternAtom(_glfw.x11.display, "TARGETS", False);
    _glfw.x11.MULTIPLE = XInternAtom(_glfw.x11.display, "MULTIPLE", False);
    _glfw.x11.PRIMARY = XInternAtom(_glfw.x11.display, "PRIMARY", False);
    _glfw.x11.INCR = XInternAtom(_glfw.x11.display, "INCR", False);
    _glfw.x11.CLIPBOARD = XInternAtom(_glfw.x11.display, "CLIPBOARD", False);

    // Clipboard manager atoms
    _glfw.x11.CLIPBOARD_MANAGER =
        XInternAtom(_glfw.x11.display, "CLIPBOARD_MANAGER", False);
    _glfw.x11.SAVE_TARGETS =
        XInternAtom(_glfw.x11.display, "SAVE_TARGETS", False);

    // Xdnd (drag and drop) atoms
    _glfw.x11.XdndAware = XInternAtom(_glfw.x11.display, "XdndAware", False);
    _glfw.x11.XdndEnter = XInternAtom(_glfw.x11.display, "XdndEnter", False);
    _glfw.x11.XdndPosition = XInternAtom(_glfw.x11.display, "XdndPosition", False);
    _glfw.x11.XdndStatus = XInternAtom(_glfw.x11.display, "XdndStatus", False);
    _glfw.x11.XdndActionCopy = XInternAtom(_glfw.x11.display, "XdndActionCopy", False);
    _glfw.x11.XdndDrop = XInternAtom(_glfw.x11.display, "XdndDrop", False);
    _glfw.x11.XdndFinished = XInternAtom(_glfw.x11.display, "XdndFinished", False);
    _glfw.x11.XdndSelection = XInternAtom(_glfw.x11.display, "XdndSelection", False);
    _glfw.x11.XdndTypeList = XInternAtom(_glfw.x11.display, "XdndTypeList", False);
    _glfw.x11.text_uri_list = XInternAtom(_glfw.x11.display, "text/uri-list", False);

    // ICCCM, EWMH and Motif window property atoms
    // These can be set safely even without WM support
    // The EWMH atoms that require WM support are handled in detectEWMH
    _glfw.x11.WM_PROTOCOLS =
        XInternAtom(_glfw.x11.display, "WM_PROTOCOLS", False);
    _glfw.x11.WM_STATE =
        XInternAtom(_glfw.x11.display, "WM_STATE", False);
    _glfw.x11.WM_DELETE_WINDOW =
        XInternAtom(_glfw.x11.display, "WM_DELETE_WINDOW", False);
    _glfw.x11.NET_WM_ICON =
        XInternAtom(_glfw.x11.display, "_NET_WM_ICON", False);
    _glfw.x11.NET_WM_PING =
        XInternAtom(_glfw.x11.display, "_NET_WM_PING", False);
    _glfw.x11.NET_WM_PID =
        XInternAtom(_glfw.x11.display, "_NET_WM_PID", False);
    _glfw.x11.NET_WM_NAME =
        XInternAtom(_glfw.x11.display, "_NET_WM_NAME", False);
    _glfw.x11.NET_WM_ICON_NAME =
        XInternAtom(_glfw.x11.display, "_NET_WM_ICON_NAME", False);
    _glfw.x11.NET_WM_BYPASS_COMPOSITOR =
        XInternAtom(_glfw.x11.display, "_NET_WM_BYPASS_COMPOSITOR", False);
    _glfw.x11.NET_WM_WINDOW_OPACITY =
        XInternAtom(_glfw.x11.display, "_NET_WM_WINDOW_OPACITY", False);
    _glfw.x11.MOTIF_WM_HINTS =
        XInternAtom(_glfw.x11.display, "_MOTIF_WM_HINTS", False);

    // The compositing manager selection name contains the screen number
    {
        char name[32];
        snprintf(name, sizeof(name), "_NET_WM_CM_S%u", _glfw.x11.screen);
        _glfw.x11.NET_WM_CM_Sx = XInternAtom(_glfw.x11.display, name, False);
    }

    return GLFW_TRUE;
}
/* Main function, contains kernel driver event loop */
int main(int argc, char **argv) {

	char* devname = 0;
	int doDaemonize = 1;
	int doWait = 0;
	int clickMode = 2;

	int i;
	for (i = 1; i < argc; i++) {
		if (strcmp(argv[i], "--debug") == 0) {
			doDaemonize = 0;
			debugMode = 1;
		} else if (strcmp(argv[i], "--wait") == 0) {
			doWait = 1;
		} else if (strcmp(argv[i], "--click=first") == 0) {
			clickMode = 0;
		} else if (strcmp(argv[i], "--click=second") == 0) {
			clickMode = 1;
		} else if (strcmp(argv[i], "--click=center") == 0) {
			clickMode = 2;
		} else {
			devname = argv[i];
		}

	}

	initGestures(clickMode);



	if (doDaemonize) {
		daemonize();
	}

	if (doWait) {
		/* Wait until all necessary things are loaded */
		sleep(10);
	}


	/* Connect to X server */
	if ((display = XOpenDisplay(NULL)) == NULL) {
		fprintf(stderr, "Couldn't connect to X server\n");
		exit(1);
	}

	/* Read X data */
	screenNum = DefaultScreen(display);

	root = RootWindow(display, screenNum);

//	realDisplayWidth = DisplayWidth(display, screenNum);
//	realDisplayHeight = DisplayHeight(display, screenNum);

	WM_CLASS = XInternAtom(display, "WM_CLASS", 0);

	/* Get notified about new windows */
	XSelectInput(display, root, StructureNotifyMask | SubstructureNotifyMask);

	//TODO load blacklist and profiles from file(s)

	/* Device file name */
	if (devname == 0) {
		devname = "/dev/twofingtouch";
	}

	/* Try to read from device file */
	int fileDesc;
	if ((fileDesc = open(devname, O_RDONLY)) < 0) {
		perror("twofing");
		return 1;
	}

	fd_set fileDescSet;
	FD_ZERO(&fileDescSet);

	int eventQueueDesc = XConnectionNumber(display);	

	while (1) {
		/* Perform initialization at beginning and after module has been re-loaded */
		int rd, i;
		struct input_event ev[64];

		char name[256] = "Unknown";

		/* Read device name */
		ioctl(fileDesc, EVIOCGNAME(sizeof(name)), name);
		printf("Input device name: \"%s\"\n", name);

		//TODO activate again?
		//XSetErrorHandler(invalidWindowHandler);


		int opcode, event, error;
		if (!XQueryExtension(display, "RANDR", &opcode, &event,
				&error)) {
			printf("X RANDR extension not available.\n");
			XCloseDisplay(display);
			exit(1);
		}

		/* Which version of XRandR? We support 1.3 */
		int major = 1, minor = 3;
		if (!XRRQueryVersion(display, &major, &minor)) {
			printf("XRandR version not available.\n");
			XCloseDisplay(display);
			exit(1);
		} else if(!(major>1 || (major == 1 && minor >= 3))) {
			printf("XRandR 1.3 not available. Server supports %d.%d\n", major, minor);
			XCloseDisplay(display);
			exit(1);
		}

		/* XInput Extension available? */
		if (!XQueryExtension(display, "XInputExtension", &opcode, &event,
				&error)) {
			printf("X Input extension not available.\n");
			XCloseDisplay(display);
			exit(1);
		}

		/* Which version of XI2? We support 2.1 */
		major = 2; minor = 1;
		if (XIQueryVersion(display, &major, &minor) == BadRequest) {
			printf("XI 2.1 not available. Server supports %d.%d\n", major, minor);
			XCloseDisplay(display);
			exit(1);
		}

		screenWidth = XDisplayWidth(display, screenNum);
		screenHeight = XDisplayHeight(display, screenNum);

		int n;
		XIDeviceInfo *info = XIQueryDevice(display, XIAllDevices, &n);
		if (!info) {
			printf("No XInput devices available\n");
			exit(1);
		}

		/* Go through input devices and look for that with the same name as the given device */
		int devindex;
		for (devindex = 0; devindex < n; devindex++) {
			if (info[devindex].use == XIMasterPointer || info[devindex].use
					== XIMasterKeyboard)
				continue;

			if (strcmp(info[devindex].name, name) == 0) {
				deviceID = info[devindex].deviceid;

				break;
			}

		}
		if (deviceID == -1) {
			printf("Input device not found in XInput device list.\n");
			exit(1);
		}

		XIFreeDeviceInfo(info);

		if(debugMode) printf("XInput device id is %i.\n", deviceID);

		/* Prepare by reading calibration */
		readCalibrationData(1);

		/* Receive device property change events */
		XIEventMask device_mask2;
		unsigned char mask_data2[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
		device_mask2.deviceid = deviceID;
		device_mask2.mask_len = sizeof(mask_data2);
		device_mask2.mask = mask_data2;
		XISetMask(device_mask2.mask, XI_PropertyEvent);
		XISetMask(device_mask2.mask, XI_ButtonPress);
		//XISetMask(device_mask2.mask, XI_TouchBegin);
		//XISetMask(device_mask2.mask, XI_TouchUpdate);
		//XISetMask(device_mask2.mask, XI_TouchEnd);
		XISelectEvents(display, root, &device_mask2, 1);

		/* Recieve events when screen size changes */
		XRRSelectInput(display, root, RRScreenChangeNotifyMask);


		/* Receive touch events */



		/* Needed for XTest to work correctly */
		XTestGrabControl(display, True);


		/* Needed for some reason to receive events */
/*		XGrabPointer(display, root, False, 0, GrabModeAsync, GrabModeAsync,
				None, None, CurrentTime);
		XUngrabPointer(display, CurrentTime);*/

		grab(display, deviceID);		

		printf("Reading input from device ... (interrupt to exit)\n");

		/* We perform raw event reading here as X touch events don't seem too reliable */
		int currentSlot = 0;

		/* If we use the legacy protocol, we collect all data of one finger into tempFingerInfo and set
		   it to the correct slot once MT_SYNC occurs. */
		FingerInfo tempFingerInfo = { .rawX=0, .rawY=0, .rawZ=0, .id = -1, .slotUsed = 0, .setThisTime = 0 };

		while (1) {


			FD_SET(fileDesc, &fileDescSet);
			FD_SET(eventQueueDesc, &fileDescSet);

			select(MAX(fileDesc, eventQueueDesc) + 1, &fileDescSet, NULL, NULL, getEasingStepTimeVal());
			
			checkEasingStep();

			if(FD_ISSET(fileDesc, &fileDescSet))
			{


				rd = read(fileDesc, ev, sizeof(struct input_event) * 64);
				if (rd < (int) sizeof(struct input_event)) {
					printf("Data stream stopped\n");
					break;
				}
				for (i = 0; i < rd / sizeof(struct input_event); i++) {

					if (ev[i].type == EV_SYN) {
						if (0 == ev[i].code) { // Ev_Sync event end
							/* All finger data received, so process now. */

							if(useLegacyProtocol) {
								/* Clear slots not set this time */
								int i;
								for(i = 0; i < 2; i++) {
									if(fingerInfos[i].setThisTime) {
										fingerInfos[i].setThisTime = 0;
									} else {
										/* Clear slot */
										fingerInfos[i].slotUsed = 0;
									}
								}
								tempFingerInfo.slotUsed = 0;
							}

							processFingers();

						} else if (2 == ev[i].code) { // MT_Sync : Multitouch event end

							if(!useLegacyProtocol) {

								/* This messsage indicates we use legacy protocol, so switch */
								useLegacyProtocol = 1;
								currentSlot = -1;
								tempFingerInfo.slotUsed = 0;
								if(debugMode) printf("Switch to legacy protocol.\n");
							} else {
								if(tempFingerInfo.slotUsed) {
									/* Finger info for one finger collected in tempFingerInfo, so save it to fingerInfos. */

									/* Look for slot to put the data into by looking at the tracking ids */
									int index = -1;
									int i;
									for(i = 0; i < 2; i++) {
										if(fingerInfos[i].slotUsed && fingerInfos[i].id == tempFingerInfo.id) {
											index = i;
											break;
										}
									}
							
									if(index == -1) {
										for(i = 0; i < 2; i++) {
											if(!fingerInfos[i].slotUsed) {
												/* "Empty" slot, so we can add it. */
												index = i;
												fingerInfos[i].id = tempFingerInfo.id;
												fingerInfos[i].slotUsed = 1;
												break;
											}
										}
									}

									if(index != -1) {
										/* Copy temporary data to slot */
										fingerInfos[index].setThisTime = 1;
										fingerInfos[index].rawX = tempFingerInfo.rawX;
										fingerInfos[index].rawY = tempFingerInfo.rawY;
										fingerInfos[index].rawZ = tempFingerInfo.rawZ;
									}
								}
							}
						}

					} else if (ev[i].type == EV_MSC && (ev[i].code == MSC_RAW
							|| ev[i].code == MSC_SCAN)) {
					} else if (ev[i].code == 47) {
						currentSlot = ev[i].value;
						if(currentSlot < 0 || currentSlot > 1) currentSlot = -1;
					} else {
						/* Set finger info values for current finger */
						if (ev[i].code == 57) {
							/* ABS_MT_TRACKING_ID */
							if(currentSlot != -1) {
								if(ev[i].value == -1)
								{
									fingerInfos[currentSlot].slotUsed = 0;
								}
								else
								{
									fingerInfos[currentSlot].id = ev[i].value;
									fingerInfos[currentSlot].slotUsed = 1;
								}
							} else if(useLegacyProtocol) {
								tempFingerInfo.id = ev[i].value;
								tempFingerInfo.slotUsed = 1;
							}
						};
						if (ev[i].code == 53) {
							if(currentSlot != -1) {
								fingerInfos[currentSlot].rawX = ev[i].value;
							} else if(useLegacyProtocol) {
								tempFingerInfo.rawX = ev[i].value;
							}
						};
						if (ev[i].code == 54) {
							if(currentSlot != -1) {
								fingerInfos[currentSlot].rawY = ev[i].value;
							} else if(useLegacyProtocol) {
								tempFingerInfo.rawY = ev[i].value;
							}
						};
						if (ev[i].code == 58) {
							if(currentSlot != -1) {
								fingerInfos[currentSlot].rawZ = ev[i].value;
							} else if(useLegacyProtocol) {
								tempFingerInfo.rawZ = ev[i].value;
							}
						};
					}
				}

			}

			if(FD_ISSET(eventQueueDesc, &fileDescSet)) {
				handleXEvent();
			}
		}

		/* Stream stopped, probably because module has been unloaded */
		close(fileDesc);

		/* Clean up */
		releaseButton();
		ungrab(display, deviceID);

		/* Wait until device file is there again */
		while ((fileDesc = open(devname, O_RDONLY)) < 0) {
			sleep(1);
		}

	}

}
Exemple #29
0
// Initialize X11 display and look for supported X11 extensions
//
static GLFWbool initExtensions(void)
{
    // Find or create window manager atoms
    _glfw.x11.WM_PROTOCOLS = XInternAtom(_glfw.x11.display,
                                         "WM_PROTOCOLS",
                                         False);
    _glfw.x11.WM_STATE = XInternAtom(_glfw.x11.display, "WM_STATE", False);
    _glfw.x11.WM_DELETE_WINDOW = XInternAtom(_glfw.x11.display,
                                             "WM_DELETE_WINDOW",
                                             False);
    _glfw.x11.MOTIF_WM_HINTS = XInternAtom(_glfw.x11.display,
                                           "_MOTIF_WM_HINTS",
                                           False);

#if defined(_GLFW_HAS_XF86VM)
    // Check for XF86VidMode extension
    _glfw.x11.vidmode.available =
        XF86VidModeQueryExtension(_glfw.x11.display,
                                  &_glfw.x11.vidmode.eventBase,
                                  &_glfw.x11.vidmode.errorBase);
#endif /*_GLFW_HAS_XF86VM*/

    // Check for RandR extension
    if (XRRQueryExtension(_glfw.x11.display,
                          &_glfw.x11.randr.eventBase,
                          &_glfw.x11.randr.errorBase))
    {
        if (XRRQueryVersion(_glfw.x11.display,
                            &_glfw.x11.randr.major,
                            &_glfw.x11.randr.minor))
        {
            // The GLFW RandR path requires at least version 1.3
            if (_glfw.x11.randr.major > 1 || _glfw.x11.randr.minor >= 3)
                _glfw.x11.randr.available = GLFW_TRUE;
        }
        else
        {
            _glfwInputError(GLFW_PLATFORM_ERROR,
                            "X11: Failed to query RandR version");
        }
    }

    if (_glfw.x11.randr.available)
    {
        XRRScreenResources* sr = XRRGetScreenResources(_glfw.x11.display,
                                                       _glfw.x11.root);

        if (!sr->ncrtc || !XRRGetCrtcGammaSize(_glfw.x11.display, sr->crtcs[0]))
        {
            // This is either a headless system or an older Nvidia binary driver
            // with broken gamma support
            // Flag it as useless and fall back to Xf86VidMode gamma, if
            // available
            _glfwInputError(GLFW_PLATFORM_ERROR,
                            "X11: RandR gamma ramp support seems broken");
            _glfw.x11.randr.gammaBroken = GLFW_TRUE;
        }

        XRRFreeScreenResources(sr);

        XRRSelectInput(_glfw.x11.display, _glfw.x11.root,
                       RROutputChangeNotifyMask);
    }

    if (XineramaQueryExtension(_glfw.x11.display,
                               &_glfw.x11.xinerama.major,
                               &_glfw.x11.xinerama.minor))
    {
        if (XineramaIsActive(_glfw.x11.display))
            _glfw.x11.xinerama.available = GLFW_TRUE;
    }

#if defined(_GLFW_HAS_XINPUT)
    if (XQueryExtension(_glfw.x11.display,
                        "XInputExtension",
                        &_glfw.x11.xi.majorOpcode,
                        &_glfw.x11.xi.eventBase,
                        &_glfw.x11.xi.errorBase))
    {
        _glfw.x11.xi.major = 2;
        _glfw.x11.xi.minor = 0;

        if (XIQueryVersion(_glfw.x11.display,
                           &_glfw.x11.xi.major,
                           &_glfw.x11.xi.minor) != BadRequest)
        {
            _glfw.x11.xi.available = GLFW_TRUE;
        }
    }
#endif /*_GLFW_HAS_XINPUT*/

    // Check if Xkb is supported on this display
    _glfw.x11.xkb.major = 1;
    _glfw.x11.xkb.minor = 0;
    _glfw.x11.xkb.available =
        XkbQueryExtension(_glfw.x11.display,
                          &_glfw.x11.xkb.majorOpcode,
                          &_glfw.x11.xkb.eventBase,
                          &_glfw.x11.xkb.errorBase,
                          &_glfw.x11.xkb.major,
                          &_glfw.x11.xkb.minor);

    if (_glfw.x11.xkb.available)
    {
        Bool supported;

        if (XkbSetDetectableAutoRepeat(_glfw.x11.display, True, &supported))
        {
            if (supported)
                _glfw.x11.xkb.detectable = GLFW_TRUE;
        }
    }

    // Update the key code LUT
    // FIXME: We should listen to XkbMapNotify events to track changes to
    // the keyboard mapping.
    createKeyTables();

    // Detect whether an EWMH-conformant window manager is running
    detectEWMH();

    // Find or create string format atoms
    _glfw.x11.NULL_ = XInternAtom(_glfw.x11.display, "NULL", False);
    _glfw.x11.UTF8_STRING =
        XInternAtom(_glfw.x11.display, "UTF8_STRING", False);
    _glfw.x11.COMPOUND_STRING =
        XInternAtom(_glfw.x11.display, "COMPOUND_STRING", False);
    _glfw.x11.ATOM_PAIR = XInternAtom(_glfw.x11.display, "ATOM_PAIR", False);

    // Find or create selection property atom
    _glfw.x11.GLFW_SELECTION =
        XInternAtom(_glfw.x11.display, "GLFW_SELECTION", False);

    // Find or create standard clipboard atoms
    _glfw.x11.TARGETS = XInternAtom(_glfw.x11.display, "TARGETS", False);
    _glfw.x11.MULTIPLE = XInternAtom(_glfw.x11.display, "MULTIPLE", False);
    _glfw.x11.CLIPBOARD = XInternAtom(_glfw.x11.display, "CLIPBOARD", False);

    // Find or create clipboard manager atoms
    _glfw.x11.CLIPBOARD_MANAGER =
        XInternAtom(_glfw.x11.display, "CLIPBOARD_MANAGER", False);
    _glfw.x11.SAVE_TARGETS =
        XInternAtom(_glfw.x11.display, "SAVE_TARGETS", False);

    // Find Xdnd (drag and drop) atoms, if available
    _glfw.x11.XdndAware = XInternAtom(_glfw.x11.display, "XdndAware", True);
    _glfw.x11.XdndEnter = XInternAtom(_glfw.x11.display, "XdndEnter", True);
    _glfw.x11.XdndPosition = XInternAtom(_glfw.x11.display, "XdndPosition", True);
    _glfw.x11.XdndStatus = XInternAtom(_glfw.x11.display, "XdndStatus", True);
    _glfw.x11.XdndActionCopy = XInternAtom(_glfw.x11.display, "XdndActionCopy", True);
    _glfw.x11.XdndDrop = XInternAtom(_glfw.x11.display, "XdndDrop", True);
    _glfw.x11.XdndLeave = XInternAtom(_glfw.x11.display, "XdndLeave", True);
    _glfw.x11.XdndFinished = XInternAtom(_glfw.x11.display, "XdndFinished", True);
    _glfw.x11.XdndSelection = XInternAtom(_glfw.x11.display, "XdndSelection", True);

    return GLFW_TRUE;
}
GlobalShortcutX::GlobalShortcutX() {
	bRunning=false;

	display = NULL;

#ifdef Q_OS_LINUX
	QString dir = QLatin1String("/dev/input");
	QFileSystemWatcher *fsw = new QFileSystemWatcher(QStringList(dir), this);
	connect(fsw, SIGNAL(directoryChanged(const QString &)), this, SLOT(directoryChanged(const QString &)));
	directoryChanged(dir);

	if (qsKeyboards.isEmpty()) {
		foreach(QFile *f, qmInputDevices)
			delete f;
		qmInputDevices.clear();

		delete fsw;
		qWarning("GlobalShortcutX: Unable to open any keyboard input devices under /dev/input, falling back to XInput");
	} else {
		return;
	}
#endif

	display = XOpenDisplay(NULL);

	if (! display) {
		qWarning("GlobalShortcutX: Unable to open dedicated display connection.");
		return;
	}

	for (int i=0; i < ScreenCount(display); ++i)
		qsRootWindows.insert(RootWindow(display, i));

#ifndef NO_XINPUT2
	int evt, error;

	if (XQueryExtension(display, "XInputExtension", &iXIopcode, &evt, &error)) {
		int major = 2;
		int minor = 0;
		int rc = XIQueryVersion(display, &major, &minor);
		if (rc != BadRequest) {
			qWarning("GlobalShortcutX: Using XI2 %d.%d", major, minor);

			queryXIMasterList();

			XIEventMask evmask;
			unsigned char mask[(XI_LASTEVENT + 7)/8];

			memset(&evmask, 0, sizeof(evmask));
			memset(mask, 0, sizeof(mask));

			XISetMask(mask, XI_RawButtonPress);
			XISetMask(mask, XI_RawButtonRelease);
			XISetMask(mask, XI_RawKeyPress);
			XISetMask(mask, XI_RawKeyRelease);
			XISetMask(mask, XI_HierarchyChanged);

			evmask.deviceid = XIAllDevices;
			evmask.mask_len = sizeof(mask);
			evmask.mask = mask;

			foreach(Window w, qsRootWindows)
				XISelectEvents(display, w, &evmask, 1);
			XFlush(display);

			connect(new QSocketNotifier(ConnectionNumber(display), QSocketNotifier::Read, this), SIGNAL(activated(int)), this, SLOT(displayReadyRead(int)));

			return;
		}