]> git.itanic.dy.fi Git - maemo-mapper/blob - src/input.c
Added ability to disable the recording of your track (closes #2311).
[maemo-mapper] / src / input.c
1 /*
2  * Copyright (C) 2006, 2007 John Costigan.
3  *
4  * POI and GPS-Info code originally written by Cezary Jackiewicz.
5  *
6  * Default map data provided by http://www.openstreetmap.org/
7  *
8  * This file is part of Maemo Mapper.
9  *
10  * Maemo Mapper is free software: you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation, either version 3 of the License, or
13  * (at your option) any later version.
14  *
15  * Maemo Mapper is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Maemo Mapper.  If not, see <http://www.gnu.org/licenses/>.
22  */
23
24 #ifdef HAVE_CONFIG_H
25 #    include "config.h"
26 #endif
27
28 #define _GNU_SOURCE
29
30 #include <math.h>
31 #include <gdk/gdkkeysyms.h>
32
33 #ifndef LEGACY
34 #    include <hildon/hildon-defines.h>
35 #    include <hildon/hildon-banner.h>
36 #else
37 #    include <hildon-widgets/hildon-defines.h>
38 #    include <hildon-widgets/hildon-banner.h>
39 #endif
40
41 #include "types.h"
42 #include "data.h"
43 #include "defines.h"
44
45 #include "display.h"
46 #include "gdk-pixbuf-rotate.h"
47 #include "gps.h"
48 #include "input.h"
49 #include "maps.h"
50 #include "path.h"
51 #include "poi.h"
52 #include "util.h"
53
54 static gint _key_zoom_is_down = FALSE;
55 static gint _key_zoom_new = -1;
56 static gint _key_zoom_timeout_sid = 0;
57 static gint _key_pan_is_down = FALSE;
58 static gfloat _key_pan_incr_devx = 0;
59 static gfloat _key_pan_incr_devy = 0;
60 static gint _key_pan_timeout_sid = 0;
61
62 static gboolean
63 key_pan_timeout(CustomAction action)
64 {
65     printf("%s()\n", __PRETTY_FUNCTION__);
66     if(_key_pan_is_down)
67     {
68         /* The pan key is still down.  Continue panning. */
69         _map_offset_devx += -_key_pan_incr_devx;
70         _map_offset_devy += -_key_pan_incr_devy;
71         MACRO_QUEUE_DRAW_AREA();
72         vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
73         return TRUE;
74     }
75     else
76     {
77         gfloat panx_adj, pany_adj;
78         /* Time is up for further action - execute the pan. */
79         /* Adjust for rotate angle. */
80         gdk_pixbuf_rotate_vector(&panx_adj, &pany_adj, _map_reverse_matrix,
81                 _map_offset_devx, _map_offset_devy);
82         map_pan(-pixel2unit((gint)(panx_adj + 0.5f)),
83                     -pixel2unit((gint)(pany_adj + 0.5f)));
84         _key_pan_timeout_sid = 0;
85         vprintf("%s(): return FALSE\n", __PRETTY_FUNCTION__);
86         return FALSE;
87     }
88 }
89
90 static gboolean
91 key_zoom_timeout(CustomAction action)
92 {
93     printf("%s()\n", __PRETTY_FUNCTION__);
94     if(_key_zoom_is_down)
95     {
96         /* The zoom key is still down.  Continue zooming. */
97         if(action == CUSTOM_ACTION_ZOOM_IN)
98         {
99             /* We're currently zooming in (_zoom is decreasing). */
100             gint test = _key_zoom_new - _curr_repo->view_zoom_steps;
101             if(test >= 0)
102                 /* We can zoom some more.  Hurray! */
103                 _key_zoom_new = test;
104         }
105         else
106         {
107             /* We're currently zooming out (_zoom is increasing). */
108             gint test = _key_zoom_new + _curr_repo->view_zoom_steps;
109             if(test <= MAX_ZOOM)
110                 /* We can zoom some more.  Hurray! */
111                 _key_zoom_new = test;
112         }
113         /* Tell them where they're about to zoom. */
114         {
115             gchar buffer[32];
116             snprintf(buffer, sizeof(buffer),
117                     "%s %d", _("Zoom to Level"), _key_zoom_new);
118             MACRO_BANNER_SHOW_INFO(_window, buffer);
119         }
120         vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
121         return TRUE;
122     }
123     else
124     {
125         /* Time is up for further action - execute. */
126         if(_key_zoom_new != _zoom)
127             map_set_zoom(_key_zoom_new);
128         _key_pan_timeout_sid = 0;
129         _key_zoom_new = -1;
130         vprintf("%s(): return FALSE\n", __PRETTY_FUNCTION__);
131         return FALSE;
132     }
133
134 }
135
136 static CustomKey
137 get_custom_key_from_keyval(gint keyval)
138 {
139     CustomKey custom_key;
140     printf("%s(%d)\n", __PRETTY_FUNCTION__, keyval);
141
142     switch(keyval)
143     {
144         case HILDON_HARDKEY_UP:
145             custom_key = CUSTOM_KEY_UP;
146             break;
147         case HILDON_HARDKEY_DOWN:
148             custom_key = CUSTOM_KEY_DOWN;
149             break;
150         case HILDON_HARDKEY_LEFT:
151             custom_key = CUSTOM_KEY_LEFT;
152             break;
153         case HILDON_HARDKEY_RIGHT:
154             custom_key = CUSTOM_KEY_RIGHT;
155             break;
156         case HILDON_HARDKEY_SELECT:
157             custom_key = CUSTOM_KEY_SELECT;
158             break;
159         case HILDON_HARDKEY_INCREASE:
160             custom_key = CUSTOM_KEY_INCREASE;
161             break;
162         case HILDON_HARDKEY_DECREASE:
163             custom_key = CUSTOM_KEY_DECREASE;
164             break;
165         case HILDON_HARDKEY_FULLSCREEN:
166             custom_key = CUSTOM_KEY_FULLSCREEN;
167             break;
168         case HILDON_HARDKEY_ESC:
169             custom_key = CUSTOM_KEY_ESC;
170             break;
171         default:
172             custom_key = -1;
173     }
174
175     vprintf("%s(): return %d\n", __PRETTY_FUNCTION__, custom_key);
176     return custom_key;
177 }
178
179 gboolean
180 window_cb_key_press(GtkWidget* widget, GdkEventKey *event)
181 {
182     CustomKey custom_key;
183     printf("%s()\n", __PRETTY_FUNCTION__);
184
185     custom_key = get_custom_key_from_keyval(event->keyval);
186     if(custom_key == -1)
187         return FALSE; /* Not our event. */
188
189     switch(_action[custom_key])
190     {
191         case CUSTOM_ACTION_PAN_NORTH:
192         case CUSTOM_ACTION_PAN_SOUTH:
193         case CUSTOM_ACTION_PAN_EAST:
194         case CUSTOM_ACTION_PAN_WEST:
195         case CUSTOM_ACTION_PAN_UP:
196         case CUSTOM_ACTION_PAN_DOWN:
197         case CUSTOM_ACTION_PAN_LEFT:
198         case CUSTOM_ACTION_PAN_RIGHT:
199             if(!_key_pan_is_down)
200             {
201                 _key_pan_is_down = TRUE;
202                 if(_center_mode > 0)
203                     gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(
204                                 _menu_view_ac_none_item), FALSE);
205                 if(_key_pan_timeout_sid)
206                 {
207                     g_source_remove(_key_pan_timeout_sid);
208                     _key_pan_timeout_sid = 0;
209                 }
210                 /* Figure out new pan. */
211                 switch(_action[custom_key])
212                 {
213                     case CUSTOM_ACTION_PAN_UP:
214                     case CUSTOM_ACTION_PAN_NORTH:
215                         _key_pan_incr_devy = -PAN_PIXELS;
216                         break;
217                     case CUSTOM_ACTION_PAN_SOUTH:
218                     case CUSTOM_ACTION_PAN_DOWN:
219                         _key_pan_incr_devy = PAN_PIXELS;
220                         break;
221                     case CUSTOM_ACTION_PAN_EAST:
222                     case CUSTOM_ACTION_PAN_RIGHT:
223                         _key_pan_incr_devx = PAN_PIXELS;
224                         break;
225                     case CUSTOM_ACTION_PAN_WEST:
226                     case CUSTOM_ACTION_PAN_LEFT:
227                         _key_pan_incr_devx = -PAN_PIXELS;
228                         break;
229                     default:
230                         g_printerr("Invalid action in key_pan_timeout(): %d\n",
231                                 _action[custom_key]);
232                 }
233                 switch(_action[custom_key])
234                 {
235                     case CUSTOM_ACTION_PAN_NORTH:
236                     case CUSTOM_ACTION_PAN_SOUTH:
237                     case CUSTOM_ACTION_PAN_EAST:
238                     case CUSTOM_ACTION_PAN_WEST:
239                         /* Adjust for rotate angle. */
240                         gdk_pixbuf_rotate_vector(&_key_pan_incr_devx,
241                                 &_key_pan_incr_devy, _map_rotate_matrix,
242                                 _key_pan_incr_devx, _key_pan_incr_devy);
243                     default:
244                         ;
245                 }
246                 key_pan_timeout(_action[custom_key]);
247                 _key_pan_timeout_sid = g_timeout_add_full(G_PRIORITY_HIGH_IDLE,
248                         250, (GSourceFunc)key_pan_timeout,
249                         (gpointer)(_action[custom_key]), NULL);
250             }
251             break;
252
253         case CUSTOM_ACTION_RESET_VIEW_ANGLE:
254             map_rotate(-_next_map_rotate_angle);
255             break;
256
257         case CUSTOM_ACTION_ROTATE_CLOCKWISE:
258         {
259             map_rotate(-ROTATE_DEGREES);
260             break;
261         }
262
263         case CUSTOM_ACTION_ROTATE_COUNTERCLOCKWISE:
264         {
265             map_rotate(ROTATE_DEGREES);
266             break;
267         }
268
269         case CUSTOM_ACTION_TOGGLE_AUTOROTATE:
270             gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(
271                         _menu_view_rotate_auto_item), !_center_rotate);
272             break;
273
274         case CUSTOM_ACTION_TOGGLE_AUTOCENTER:
275             switch(_center_mode)
276             {
277                 case CENTER_LATLON:
278                 case CENTER_WAS_LEAD:
279                     gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(
280                                 _menu_view_ac_lead_item), TRUE);
281                     break;
282                 case CENTER_LEAD:
283                 case CENTER_WAS_LATLON:
284                     gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(
285                                 _menu_view_ac_latlon_item), TRUE);
286                     break;
287             }
288             break;
289
290         case CUSTOM_ACTION_ZOOM_IN:
291         case CUSTOM_ACTION_ZOOM_OUT:
292             if(!_key_zoom_is_down)
293             {
294                 _key_zoom_is_down = TRUE;
295                 if(_key_zoom_timeout_sid)
296                 {
297                     g_source_remove(_key_zoom_timeout_sid);
298                     _key_zoom_timeout_sid = 0;
299                 }
300                 if(_key_zoom_new == -1)
301                     _key_zoom_new = _next_zoom;
302                 _key_zoom_new = _key_zoom_new
303                     + (_action[custom_key] == CUSTOM_ACTION_ZOOM_IN
304                             ? -_curr_repo->view_zoom_steps
305                             : _curr_repo->view_zoom_steps);
306                 BOUND(_key_zoom_new, 0, MAX_ZOOM);
307                 {
308                     gchar buffer[80];
309                     snprintf(buffer, sizeof(buffer),"%s %d",
310                             _("Zoom to Level"), _key_zoom_new);
311                     MACRO_BANNER_SHOW_INFO(_window, buffer);
312                 }
313                 _key_zoom_timeout_sid =g_timeout_add_full(G_PRIORITY_HIGH_IDLE,
314                         500, (GSourceFunc)key_zoom_timeout,
315                         (gpointer)(_action[custom_key]), NULL);
316             }
317             break;
318
319         case CUSTOM_ACTION_TOGGLE_FULLSCREEN:
320             gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(
321                         _menu_view_fullscreen_item), !_fullscreen);
322             break;
323
324         case CUSTOM_ACTION_TOGGLE_TRACKS:
325             switch(_show_paths)
326             {
327                 case 0:
328                     /* Nothing shown, nothing saved; just set both. */
329                     _show_paths = TRACKS_MASK | ROUTES_MASK;
330                     break;
331                 case TRACKS_MASK << 16:
332                 case ROUTES_MASK << 16:
333                 case (ROUTES_MASK | TRACKS_MASK) << 16:
334                     /* Something was saved and nothing changed since.
335                      * Restore saved. */
336                     _show_paths = _show_paths >> 16;
337                     break;
338                 default:
339                     /* There is no history, or they changed something
340                      * since the last historical change. Save and
341                      * clear. */
342                     _show_paths = _show_paths << 16;
343             }
344             gtk_check_menu_item_set_active(
345                     GTK_CHECK_MENU_ITEM(_menu_view_show_routes_item),
346                     _show_paths & ROUTES_MASK);
347
348             gtk_check_menu_item_set_active(
349                     GTK_CHECK_MENU_ITEM(_menu_view_show_tracks_item),
350                     _show_paths & TRACKS_MASK);
351
352         case CUSTOM_ACTION_TOGGLE_SCALE:
353             gtk_check_menu_item_set_active(
354                     GTK_CHECK_MENU_ITEM(_menu_view_show_scale_item),
355                     !_show_scale);
356             break;
357
358         case CUSTOM_ACTION_TOGGLE_POI:
359             gtk_check_menu_item_set_active(
360                     GTK_CHECK_MENU_ITEM(_menu_view_show_poi_item),
361                     !_show_poi);
362             break;
363         case CUSTOM_ACTION_CHANGE_REPO: {
364             GList *curr = g_list_find(_repo_list, _curr_repo);
365             if(!curr)
366                 break;
367
368             /* Loop until we reach a next-able repo, or until we get
369              * back to the current repo. */
370             while((curr = (curr->next ? curr->next : _repo_list))
371                     && !((RepoData*)curr->data)->nextable
372                     && curr->data != _curr_repo) { }
373
374             if(curr->data != _curr_repo)
375             {
376                 repo_set_curr(curr->data);
377                 gtk_check_menu_item_set_active(
378                         GTK_CHECK_MENU_ITEM(_curr_repo->menu_item),
379                         TRUE);
380             }
381             else
382             {
383                 popup_error(_window,
384                     _("There are no other next-able repositories."));
385             }
386             break;
387         }
388
389         case CUSTOM_ACTION_RESET_BLUETOOTH:
390             reset_bluetooth();
391             break;
392
393         case CUSTOM_ACTION_ROUTE_DISTNEXT:
394             route_show_distance_to_next();
395             break;
396
397         case CUSTOM_ACTION_ROUTE_DISTLAST:
398             route_show_distance_to_last();
399             break;
400
401         case CUSTOM_ACTION_TRACK_BREAK:
402             track_insert_break(TRUE);
403             break;
404
405         case CUSTOM_ACTION_TRACK_CLEAR:
406             track_clear();
407             break;
408
409         case CUSTOM_ACTION_TRACK_DISTLAST:
410             track_show_distance_from_last();
411             break;
412
413         case CUSTOM_ACTION_TRACK_DISTFIRST:
414             track_show_distance_from_first();
415             break;
416
417         case CUSTOM_ACTION_TOGGLE_GPS:
418             gtk_check_menu_item_set_active(
419                     GTK_CHECK_MENU_ITEM(_menu_gps_enable_item),
420                     !_enable_gps);
421             break;
422
423         case CUSTOM_ACTION_TOGGLE_GPSINFO:
424             gtk_check_menu_item_set_active(
425                     GTK_CHECK_MENU_ITEM(_menu_gps_show_info_item),
426                     !_gps_info);
427             break;
428
429         case CUSTOM_ACTION_TOGGLE_SPEEDLIMIT:
430             _speed_limit_on ^= 1;
431             break;
432
433         default:
434             vprintf("%s(): return FALSE\n", __PRETTY_FUNCTION__);
435             return FALSE;
436     }
437
438     return TRUE;
439     vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
440 }
441
442 gboolean
443 window_cb_key_release(GtkWidget* widget, GdkEventKey *event)
444 {
445     CustomKey custom_key;
446     printf("%s()\n", __PRETTY_FUNCTION__);
447
448     custom_key = get_custom_key_from_keyval(event->keyval);
449     if(custom_key < 0)
450         return FALSE; /* Not our event. */
451
452     switch(_action[custom_key])
453     {
454         case CUSTOM_ACTION_ZOOM_IN:
455         case CUSTOM_ACTION_ZOOM_OUT:
456             if(_key_zoom_timeout_sid)
457             {
458                 g_source_remove(_key_zoom_timeout_sid);
459                 _key_zoom_timeout_sid = 0;
460                 _key_zoom_timeout_sid =g_timeout_add_full(G_PRIORITY_HIGH_IDLE,
461                         500, (GSourceFunc)key_zoom_timeout, NULL, NULL);
462             }
463             _key_zoom_is_down = FALSE;
464             return TRUE;
465
466         case CUSTOM_ACTION_PAN_NORTH:
467         case CUSTOM_ACTION_PAN_SOUTH:
468         case CUSTOM_ACTION_PAN_EAST:
469         case CUSTOM_ACTION_PAN_WEST:
470         case CUSTOM_ACTION_PAN_UP:
471         case CUSTOM_ACTION_PAN_DOWN:
472         case CUSTOM_ACTION_PAN_LEFT:
473         case CUSTOM_ACTION_PAN_RIGHT:
474             if(_key_pan_timeout_sid)
475             {
476                 g_source_remove(_key_pan_timeout_sid);
477                 _key_pan_timeout_sid = g_timeout_add_full(G_PRIORITY_HIGH_IDLE,
478                         500, (GSourceFunc)key_pan_timeout, NULL, NULL);
479             }
480             _key_pan_is_down = FALSE;
481             _key_pan_incr_devx = 0;
482             _key_pan_incr_devy = 0;
483             return TRUE;
484
485         default:
486             return FALSE;
487     }
488     vprintf("%s(): return\n", __PRETTY_FUNCTION__);
489 }
490
491 gboolean
492 map_cb_motion_notify(GtkWidget *widget, GdkEventMotion *event)
493 {
494     gint x, y;
495     GdkModifierType state;
496     printf("%s()\n", __PRETTY_FUNCTION__);
497
498     if(!_mouse_is_down)
499         return FALSE;
500
501     if(event->is_hint)
502         gdk_window_get_pointer(event->window, &x, &y, &state);
503     else
504     {
505         x = event->x;
506         y = event->y;
507         state = event->state;
508     }
509
510     if(_mouse_is_dragging)
511     {
512         /* Already in the process of dragging.  Set the offset. */
513         _map_offset_devx = x - _cmenu_position_x;
514         _map_offset_devy = y - _cmenu_position_y;
515         MACRO_QUEUE_DRAW_AREA();
516     }
517     else
518     {
519         gint diffx = x - _cmenu_position_x - _map_offset_devx;
520         gint diffy = y - _cmenu_position_y - _map_offset_devy;
521         if(diffx * diffx + diffy + diffy > 100)
522         {
523             _mouse_is_dragging = TRUE;
524         }
525     }
526
527     /* Return FALSE to allow context menu to work. */
528     vprintf("%s(): return FALSE\n", __PRETTY_FUNCTION__);
529     return TRUE;
530 }
531
532 gboolean
533 map_cb_button_press(GtkWidget *widget, GdkEventButton *event)
534 {
535     printf("%s()\n", __PRETTY_FUNCTION__);
536
537     if(!_mouse_is_down)
538     {
539         _cmenu_position_x = event->x + 0.5 - _map_offset_devx;
540         _cmenu_position_y = event->y + 0.5 - _map_offset_devy;
541         g_mutex_lock(_mouse_mutex);
542         _mouse_is_down = TRUE;
543     }
544
545     /* Return FALSE to allow context menu to work. */
546     vprintf("%s(): return FALSE\n", __PRETTY_FUNCTION__);
547     return FALSE;
548 }
549
550 gboolean
551 map_cb_button_release(GtkWidget *widget, GdkEventButton *event)
552 {
553     printf("%s()\n", __PRETTY_FUNCTION__);
554
555     if(!_mouse_is_down)
556     {
557         /* We didn't know about it anyway.  Return FALSE. */
558         vprintf("%s(): return FALSE\n", __PRETTY_FUNCTION__);
559         return FALSE;
560     }
561
562     _mouse_is_down = FALSE;
563
564 #ifdef DEBUG
565     if(event->button != 1)
566     {   
567         screen2unit((gint)(event->x + 0.5), (gint)(event->y + 0.5),
568                 _pos.unitx, _pos.unity);
569         unit2latlon(_pos.unitx, _pos.unity, _gps.lat, _gps.lon);
570         /* Test unit-to-lat/lon conversion. */
571         latlon2unit(_gps.lat, _gps.lon, _pos.unitx, _pos.unity);
572         _gps.speed = ((gint)(_gps.speed + 5) % 60);
573         _gps.heading = ((gint)(_gps.heading + 5) % 360);
574         if(track_add(time(NULL), FALSE))
575         {
576             /* Move mark to new location. */
577             map_refresh_mark(FALSE);
578         }
579         else
580         {
581             map_move_mark();
582         }
583     }
584     else
585 #endif
586     if(_mouse_is_dragging)
587     {
588         Point clkpt;
589
590         _mouse_is_dragging = FALSE;
591
592         screen2unit(_view_halfwidth_pixels, _view_halfheight_pixels,
593                 clkpt.unitx, clkpt.unity);
594
595         if(_center_mode > 0)
596         {
597             gfloat matrix[4];
598             gint mvpt_unitx, mvpt_unity;
599             gfloat new_offset_unitx, new_offset_unity;
600             /* If auto-center is enabled (meaning that panning will cause the
601              * view the rotate according to the heading), rotate the new
602              * unitx/unity around the mvpt, by any changes in _gps.heading
603              * since the last time _map_rotate_angle was updated.  The end
604              * result is that the point the user is moving stays in the same
605              * relative point, even if the heading has since changed. */
606             gdk_pixbuf_rotate_matrix_fill_for_rotation(matrix,
607                     deg2rad(_gps.heading - _next_map_rotate_angle));
608             buf2unit(_cmenu_position_x, _cmenu_position_y,
609                     mvpt_unitx, mvpt_unity);
610             gdk_pixbuf_rotate_vector(&new_offset_unitx, &new_offset_unity,
611                     matrix,
612                     (gint)(clkpt.unitx - mvpt_unitx),
613                     (gint)(clkpt.unity -mvpt_unity));
614             clkpt.unitx = mvpt_unitx + new_offset_unitx;
615             clkpt.unity = mvpt_unity + new_offset_unity;
616         }
617
618         if(_center_mode > 0)
619             gtk_check_menu_item_set_active(
620                     GTK_CHECK_MENU_ITEM(_menu_view_ac_none_item), TRUE);
621
622         map_center_unit(clkpt);
623     }
624     else
625     {
626         gboolean selected_point = FALSE;
627         Point clkpt;
628         screen2unit(event->x, event->y, clkpt.unitx, clkpt.unity);
629
630         if(_show_poi && (_poi_zoom > _zoom))
631         {
632             PoiInfo poi;
633             selected_point = select_poi(
634                     clkpt.unitx, clkpt.unity, &poi, TRUE);
635             if(selected_point)
636             {
637                 gchar *banner;
638                 banner = g_strdup_printf("%s (%s)", poi.label, poi.clabel);
639                 MACRO_BANNER_SHOW_INFO(_window, banner);
640                 g_free(banner);
641                 g_free(poi.label);
642                 g_free(poi.desc);
643                 g_free(poi.clabel);
644             }
645         }
646         if(!selected_point && (_show_paths & ROUTES_MASK)
647                 && _route.whead <= _route.wtail)
648         {
649             WayPoint *way = find_nearest_waypoint(
650                     clkpt.unitx, clkpt.unity);
651             if(way)
652             {
653                 selected_point = TRUE;
654                 MACRO_BANNER_SHOW_INFO(_window, way->desc);
655             }
656         }
657         if(!selected_point)
658         {
659             if(_center_mode > 0)
660                 gtk_check_menu_item_set_active(
661                         GTK_CHECK_MENU_ITEM(_menu_view_ac_none_item), TRUE);
662             map_center_unit_full(clkpt, _next_zoom,
663                     _center_mode > 0 && _center_rotate
664                     ? _gps.heading : _next_map_rotate_angle);
665         }
666     }
667
668     g_mutex_unlock(_mouse_mutex);
669
670     /* Return FALSE to avoid context menu (if it hasn't popped up already). */
671     vprintf("%s(): return FALSE\n", __PRETTY_FUNCTION__);
672     return FALSE;
673 }
674
675 void
676 input_init()
677 {
678     printf("%s():\n", __PRETTY_FUNCTION__);
679
680     g_signal_connect(G_OBJECT(_window), "key_press_event",
681             G_CALLBACK(window_cb_key_press), NULL);
682
683     g_signal_connect(G_OBJECT(_window), "key_release_event",
684             G_CALLBACK(window_cb_key_release), NULL);
685
686     g_signal_connect(G_OBJECT(_map_widget), "motion_notify_event",
687             G_CALLBACK(map_cb_motion_notify), NULL);
688
689     g_signal_connect(G_OBJECT(_map_widget), "button_press_event",
690             G_CALLBACK(map_cb_button_press), NULL);
691
692     g_signal_connect(G_OBJECT(_map_widget), "button_release_event",
693             G_CALLBACK(map_cb_button_release), NULL);
694
695     gtk_widget_add_events(_map_widget,
696             GDK_EXPOSURE_MASK
697             | GDK_POINTER_MOTION_MASK
698             | GDK_POINTER_MOTION_HINT_MASK
699             | GDK_BUTTON_PRESS_MASK
700             | GDK_BUTTON_RELEASE_MASK);
701
702     vprintf("%s(): return\n", __PRETTY_FUNCTION__);
703 }