3 * Copyright (C) 2007, Harbour, All rights reserved.
14 static int (*Gpm_Open_)(Gpm_Connect *, int);
15 static int (*Gpm_Close_)(void);
16 static int (*Gpm_GetEvent_)(Gpm_Event *);
17 static int *gpm_zerobased_;
18 static int *gpm_visiblepointer_;
19 static Gpm_Connect gc;
29 gpm_so = dlopen("libgpm.so", RTLD_NOW);
31 debug("Error opening libgpm.so: %s", dlerror());
32 Gpm_GetEvent_ = (int (*)(Gpm_Event*)) dlsym(gpm_so, "Gpm_GetEvent");
35 Gpm_Close_ = (int (*)()) dlsym(gpm_so, "Gpm_Close");
38 Gpm_Open_ = (int (*)(Gpm_Connect*, int)) dlsym(gpm_so, "Gpm_Open");
41 gpm_zerobased_ = (int *) dlsym(gpm_so, "gpm_zerobased");
44 gpm_visiblepointer_ = (int *) dlsym(gpm_so, "gpm_visiblepointer");
48 Gpm_GetEvent_ = Gpm_GetEvent;
49 Gpm_Close_ = Gpm_Close;
51 gpm_zerobased_ = &gpm_zerobased;
52 gpm_visiblepointer_ = &gpm_visiblepointer;
58 *gpm_zerobased_ = *gpm_visiblepointer_ = 1;
59 gpm_fd_ = Gpm_Open_(&gc, 0);
62 // ÐÅÒÅ×ÏÄÉÍ gpm × non-blocking mode
63 modes = fcntl(gpm_fd_, F_GETFL);
66 if (fcntl(gpm_fd_, F_SETFL, modes | O_NONBLOCK) < 0)
69 enabled_ = true; // enable mouse by default
70 log("gpm", CHAT_LEVEL, "Found and enabled.");
79 bug_on(Gpm_Close_()); // only one connection is planned
85 static void map_event(Gpm_Event &ge, F_Event_t &event)
87 event.dev = F::F_POINTER;
88 event.type = F::F_EVENT_NONE;
89 // mouse can be clicked, moved or dragged
90 if (ge.type & GPM_MOVE)
91 event.type = F::F_POINTER_MOVE;
92 else if (ge.type & (GPM_MFLAG | GPM_DRAG))
93 event.type = F::F_POINTER_DRAG;
94 else if (ge.type & GPM_DOWN)
95 event.type = F::F_POINTER_PRESS;
96 // GPM_UP ÐÅÒÅËÒÙ×ÁÅÔ (GPM_MFLAG | GPM_DRAG) - ÐÏÌÅÚÎÏ ÄÌÑ F_DROP
98 event.type = F::F_POINTER_RELEASE;
99 if (ge.type & GPM_SINGLE)
100 event.mouse.click = F::F_POINTER_SINGLE_CLICK;
101 if (ge.type & GPM_DOUBLE)
102 event.mouse.click = F::F_POINTER_DOUBLE_CLICK;
103 if (ge.type & GPM_TRIPLE)
104 event.mouse.click = F::F_POINTER_TRIPPLE_CLICK;
105 // set new coordinates
106 event.mouse.x = ge.x;
107 event.mouse.y = ge.y;
108 event.mouse.buttons = ((ge.buttons & GPM_B_LEFT) ? F_BUTTON1 : 0);
109 event.mouse.buttons |= ((ge.buttons & GPM_B_MIDDLE) ?
111 event.mouse.buttons |= ((ge.buttons & GPM_B_RIGHT) ?
115 // TODO: support gpm server restarts
117 bool F_Gpm::check_for_events(F_Event_t *event)
119 if (!good_) // was unrecoverable error, may be need reconnecting to gpm
123 switch ((res = Gpm_GetEvent_(&ge))) {
124 case 0: // connection is closed
128 map_event(ge, *event);
132 if (errno == EAGAIN) // signal or non-blocking read incomplete
134 debug("error (%d) in Gpm_GetEvent [%d:%s], disabling mouse ...", res, errno, strerror(errno));
141 void F_Gpm::redraw(bool v)
143 if (v != visible_) { // change pointer state
145 // if (ioctl(0, TIOCLINUX, &con_mou.tioc))
146 // log(WARNING_LEVEL, "ioctl: %s", strerror(errno));