Correct backtrace() array size argument
[forms.git] / src / F_Gpm.C
blob58398610d0856a5d4f8be789a73b8592b5cbd239
2  /*
3   *   Copyright (C) 2007, Harbour, All rights reserved.
4   */
6 #include <F_Gpm.H>
7 #include <F_Log.H>
8 #include <gpm.h>
9 #include <dlfcn.h>
10 #include <errno.h>
12 using namespace F;
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;
20 static int gpm_fd_;
22 //#define DYNAMIC_GPM
24 F_Gpm::F_Gpm()
26  gpm_fd_ = -1;
27  int modes;
28 #ifdef DYNAMIC_GPM
29  gpm_so = dlopen("libgpm.so", RTLD_NOW);
30  if (!gpm_so)
31    debug("Error opening libgpm.so: %s", dlerror());
32  Gpm_GetEvent_ = (int (*)(Gpm_Event*)) dlsym(gpm_so, "Gpm_GetEvent");
33  if (dlerror())
34    goto no_gpm;
35  Gpm_Close_ = (int (*)()) dlsym(gpm_so, "Gpm_Close");
36  if (dlerror())
37    goto no_gpm;
38  Gpm_Open_ = (int (*)(Gpm_Connect*, int)) dlsym(gpm_so, "Gpm_Open");
39  if (dlerror())
40   goto no_gpm;
41  gpm_zerobased_ = (int *) dlsym(gpm_so, "gpm_zerobased");
42  if (dlerror())
43   goto no_gpm;
44  gpm_visiblepointer_ = (int *) dlsym(gpm_so, "gpm_visiblepointer");
45  if (dlerror())
46   goto no_gpm;
47 #else
48  Gpm_GetEvent_ = Gpm_GetEvent;
49  Gpm_Close_ = Gpm_Close;
50  Gpm_Open_ = Gpm_Open;
51  gpm_zerobased_ = &gpm_zerobased;
52  gpm_visiblepointer_ = &gpm_visiblepointer;
53 #endif
54  gc.minMod = 0;
55  gc.maxMod = ~0;
56  gc.defaultMask = 0;
57  gc.eventMask = ~0;
58  *gpm_zerobased_ = *gpm_visiblepointer_ = 1;
59  gpm_fd_ = Gpm_Open_(&gc, 0);
60  if (gpm_fd_ < 0)
61    goto no_gpm;
62  // ÐÅÒÅ×ÏÄÉÍ gpm × non-blocking mode
63  modes = fcntl(gpm_fd_, F_GETFL);
64  if (modes < 0)
65    goto no_gpm;
66  if (fcntl(gpm_fd_, F_SETFL, modes | O_NONBLOCK) < 0)
67    goto no_gpm;
68  good_ = true;
69  enabled_ = true; // enable mouse by default
70  log("gpm", CHAT_LEVEL, "Found and enabled.");
71  return;
72 no_gpm:
73  good_ = false;
76 F_Gpm::~F_Gpm()
78  if (gpm_fd_ > 0)
79   bug_on(Gpm_Close_()); // only one connection is planned
80  if (gpm_so)
81    dlclose(gpm_so);
82  gpm_so = 0;
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
97  if (ge.type & GPM_UP)
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) ?
110    F_BUTTON2 : 0);
111  event.mouse.buttons |= ((ge.buttons & GPM_B_RIGHT) ?
112    F_BUTTON3 : 0);
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
120    return false;
121  Gpm_Event ge;
122  int res;
123  switch ((res = Gpm_GetEvent_(&ge))) {
124    case 0: // connection is closed
125      good_ = false;
126      break;
127    case 1: // got event
128      map_event(ge, *event);
129      return true;
130      break;
131    default:
132      if (errno == EAGAIN) // signal or non-blocking read incomplete
133        return false;
134      debug("error (%d) in Gpm_GetEvent [%d:%s], disabling mouse ...", res, errno, strerror(errno));
135      good_ = false;
136      break;
138  return good_;
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));