Correct backtrace() array size argument
[forms.git] / src / F_Linux_Console_Display.C
blob08f57477c7d5fd131aaea4108db13b522855b675
2  /*
3   *   Copyright (C) 2007, Harbour, All rights reserved.
4   */
6 #include <F_Linux_Console_Display.H>
7 #include <list>
9 using namespace F;
10 using namespace std;
12 // ËÏÐÉÒÕÅÍ Ó ÜËÒÁÎÁ
13 void F_Linux_Console_Display::get_line(coord_t x, coord_t y, dim_t len, F_Text_Symbol *dest)
15   fseek(vcsa_, 2 * (x + y * w()) + 4, SEEK_SET);
16   unsigned char buf[len * 2];
17   if (fread(buf, 2 * len, 1, vcsa_) != 1)
18     trace_bug();
19   for (register dim_t i = 0; i < (2 * len); i += 2)
20     *(dest++) = F_Text_Symbol(buf[i], buf[i + 1] & 0xF, buf[i + 1] >> 4); 
23 // ÒÉÓÕÅÍ ÎÁ ÜËÒÁÎÅ
24 void F_Linux_Console_Display::put_line(coord_t x, coord_t y, dim_t len, F_Text_Symbol *src)
26   fseek(vcsa_, 2 * (x + y * w()) + 4, SEEK_SET);
27   unsigned char buf[len * 2];
28   for (register dim_t i = 0; i < (2 * len); i += 2, src++) {
29     buf[i] = src->ch_;
30     buf[i + 1] = (src->fg() & 0xF) | (src->bg() << 4);
31  }
32   if (fwrite(buf, 2 * len, 1, vcsa_) != 1)
33     trace_bug();
34   fflush(vcsa_);
37 void F_Linux_Console_Display::cursor(coord_t x, coord_t y)
39  fseek(vcsa_, 2, SEEK_SET);
40  unsigned char cur[2] = { x, y };
41  cursor_x = x;
42  cursor_y = y;
43  if (fwrite(&cur, 2, 1, vcsa_) != 1)
44    trace_bug();
47 void F_Linux_Console_Display::cursor(coord_t *x, coord_t *y)
49  fseek(vcsa_, 2, SEEK_SET);
50  unsigned char cur[2];
51  if (fread(&cur, 2, 1, vcsa_) != 1)
52    trace_bug();
53  cursor_x = *x = cur[0];
54  cursor_y = *y = cur[1];
57 #include <sys/ioctl.h>
58 #include <errno.h>
60 // ÏÂÒÁÂÁÔÙ×ÁÅÔ ÓÏÂÙÔÉÑ ÓÐÅÃÉÆÉÞÅÓËÉÅ ÄÌÑ ËÏÎÓÏÌÉ - ÍÙÛØ, ÔÁÍ É ÐÒÏÞÅÅ
62 // ×ÓÅ ÏËÎÁ ÐÏÌÕÞÁÀÔ F_ENTER/F_LEAVE event'Ù
63 // ÏËÎÏ, ËÏÔÏÒÏÅ × ÆÏËÕÓÅ ÐÏÌÕÞÁÅÔ ×ÓÅ ÏÓÔÁÌØÎÙÅ event'Ù
65 bool F_Linux_Console_Display::handle(F_Event_t &ev)
67  F_Event_Type_t t;
68  switch (ev.dev) {
69    case F_DISPLAY:
70      if (ev.type != F_DISPLAY_FLUSH) {
71        debug("display event %d, wid - %d", ev.type, ev.display.window->id());
72 //       sync(ev.display.window);
73     } else {
74         debug("display flush event %d", ev.type);
75         sync();
76     }
77      // store new mouse pointer
78      if ((mouse_x != F_MAX_COORD_T) && (mouse_y != F_MAX_COORD_T))
79        get_line(mouse_x, mouse_y, 1, &symbol_under_mouse_);   
80      draw_mouse_pointer();
81      break;
82    case F_KEYBOARD:
83      debug("key is pressed - 0x%x (%c), modifiers - 0x%x", ev.kbd.key,
84        ((ev.kbd.key > 31) && (ev.kbd.key < 256)) ? ev.kbd.key : '?',
85        ev.kbd.modifiers);
86      // change FOCUS
87      if (ev.kbd.key == F_Tab) {
88        if (ev.kbd.modifiers & F_ALT) { // send FOCUS to next window
89          F_Window *w = 0;
90          if (!window_in_focus()) {
91            if (!windows.size()) // no windows
92              break;
93            else // pick up first window
94              w = windows[0];
95         } else {
96           if (windows.size() == 1) // only one window
97             break;
98           if (window_in_focus()->modal() && window_in_focus()->visible())
99             return window_in_focus()->handle(ev);
100           if (ev.kbd.modifiers & F_SHIFT)
101             w = windows.prev_id(window_in_focus());
102           else
103             w = windows.next_id(window_in_focus());
104         }
105          if (!w)
106            break;
107          if (!w->visible()) // TODO: fix this crap
108            break;
109          take_focus(w);
110          top(w);
111          ev.type = F_FOCUS;
112          w->handle(ev);
113       }
114     } // F_Tab
115      if (window_in_focus())
116        return window_in_focus()->handle(ev);
117      break;
118    case F_POINTER:
119      // ÍÏÖÎÏ ÄÏÂÁ×ÉÔØ ÐÏÌÅ "ÎÁÐÒÁ×ÌÅÎÉÅ" - ËÏÏÒÄÉÎÁÔÙ ÍÏÇÕÔ ÎÅ ÍÅÎÑÔÓÑ, ÎÏ
120      // ÍÙÛØ Ä×ÉÇÁÅÔÓÑ (× ÓÌÕÞÁÅ ÕÔÙËÁÎÉÑ × ËÒÁÊ ÜËÒÁÎÁ for ex.)
121      if (ev.mouse.x < 0)
122        ev.mouse.x = 0;
123      if (ev.mouse.y < 0)
124        ev.mouse.y = 0;
125      if (ev.mouse.x > (w() - 1))
126        ev.mouse.x = w() - 1;
127      if (ev.mouse.y > (h() - 1))
128        ev.mouse.y = h() - 1;
129      mouse_x = ev.mouse.x;
130      mouse_y = ev.mouse.y;
131      mouse_ev_c = ev.mouse.ev_c;
132      t = ev.type;
133      if ((ev.type == F_POINTER_DRAG) || (ev.type == F_POINTER_MOVE)) {
134        if (ev.type == F_POINTER_DRAG)
135          debug("dragging to new coordinates x - %d, y - %d, with buttons - 0x%x",
136          ev.mouse.x, ev.mouse.y, ev.mouse.buttons);
137        else if (ev.type == F_POINTER_MOVE)
138          debug("moved to new coordinates x - %d, y - %d", ev.mouse.x, ev.mouse.y);
139        mouse_ev_t = ev.type;
140        mouse_cursor(1);
141        draw_mouse_pointer();
142        // check for F_ENTER/F_LEAVE events
143        for (unsigned int i = 0; i < windows.size(); i++) {
144          if (windows[i]->visible()) {
145 //           debug("processing wid %d, bm - %d, wid_side - %d", (*w)->id(), window_belowmouse() ?
146 //             window_belowmouse()->id() : 0, (*w)->inside(F_Point(mouse_x, mouse_y)));
147            if ((window_belowmouse() == windows[i]) && !windows[i]->moving() &&
148              !windows[i]->inside(F_Point(mouse_x, mouse_y))) {
149 //               debug("not inside wid - %d", windows[i]->id());
150                ev.type = F_LEAVE;
151                window_belowmouse()->handle(ev);
152                ev.type = t;
153                window_belowmouse(0);
154                continue;
155           }
156            if (windows[i]->inside(F_Point(mouse_x, mouse_y))) {
157              if (window_belowmouse() == windows[i])
158                return window_belowmouse()->handle(ev);
159              else if (window_belowmouse() != windows[i]) {
160                  window_belowmouse(windows[i]);
161 //                 debug("wid %d side - %d", window_belowmouse()->id(), window_belowmouse()->inside(F_Point(mouse_x, mouse_y)));
162                  ev.type = F_ENTER;
163                  return window_belowmouse()->handle(ev);
164            }
165           }
166            // propagate F_POINTER_MOVE event
167            if ((window_belowmouse() == windows[i]) && (window_in_focus() == windows[i]))
168              return window_belowmouse()->handle(ev);
169         } // if (visible())
170        } // for
171          break;
172      } else if ((ev.type == F_POINTER_PRESS) || (ev.type == F_POINTER_RELEASE))
173        debug("button 0x%x is %s", ev.mouse.buttons,
174        (ev.type == F_POINTER_PRESS) ? "pressed" : "released");
175      else if ((ev.type == F_POINTER_WHEEL_INCR) || (ev.type == F_POINTER_WHEEL_DECR))
176        debug("mouse wheel is rolling");
177      if ((ev.type == F_POINTER_PRESS) && (ev.mouse.buttons & F_BUTTON2)) {
178        char c = 3;
179        if (ioctl(fileno(stdin), TIOCLINUX, &c) < 0)
180          debug("TIOCLINUX(3) ioctl error - %s", strerror(errno));
181     }
182      if (window_in_focus() != window_belowmouse()) { // ÓÍÅÎÁ ÆÏËÕÓÁ
183        if (window_in_focus()) {
184          if (window_in_focus()->modal() && window_in_focus()->visible())
185            break;
186          ev.type = F_UNFOCUS;
187          window_in_focus()->handle(ev);
188          ev.type = t;
189          take_focus(0);
190       }
191        if (window_belowmouse()) {
192          take_focus(window_belowmouse());
193          top(window_belowmouse());
194          ev.type = F_FOCUS;
195          window_belowmouse()->handle(ev);
196          ev.type = t;
197       }
198     }
199      if ((mouse_ev_t == F_POINTER_DRAG) && (ev.type == F_POINTER_RELEASE) &&
200        window_in_focus()) {
201          ev.type = mouse_ev_t = F_POINTER_DROP;
202          window_in_focus()->handle(ev);
203      } else {
204        mouse_ev_t = ev.type;
205        if (window_belowmouse())
206          window_belowmouse()->handle(ev);
207     }
208      return true;
209    default:
210      debug("unknown event dev %d, type %d received", ev.dev, ev.type);
211      trace_bug();
212      return false;
214   return F_Text_Display::handle(ev);