]> git.itanic.dy.fi Git - maemo-mapper/blob - src/input.c
bc48c1f9984324906dcb31ae78138563cdd46f58
[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_TRACKING:
325             gtk_check_menu_item_set_active(
326                     GTK_CHECK_MENU_ITEM(_menu_track_enable_tracking_item),
327                     !_enable_tracking);
328             break;
329
330         case CUSTOM_ACTION_TOGGLE_TRACKS:
331             switch(_show_paths)
332             {
333                 case 0:
334                     /* Nothing shown, nothing saved; just set both. */
335                     _show_paths = TRACKS_MASK | ROUTES_MASK;
336                     break;
337                 case TRACKS_MASK << 16:
338                 case ROUTES_MASK << 16:
339                 case (ROUTES_MASK | TRACKS_MASK) << 16:
340                     /* Something was saved and nothing changed since.
341                      * Restore saved. */
342                     _show_paths = _show_paths >> 16;
343                     break;
344                 default:
345                     /* There is no history, or they changed something
346                      * since the last historical change. Save and
347                      * clear. */
348                     _show_paths = _show_paths << 16;
349             }
350             gtk_check_menu_item_set_active(
351                     GTK_CHECK_MENU_ITEM(_menu_view_show_routes_item),
352                     _show_paths & ROUTES_MASK);
353
354             gtk_check_menu_item_set_active(
355                     GTK_CHECK_MENU_ITEM(_menu_view_show_tracks_item),
356                     _show_paths & TRACKS_MASK);
357
358         case CUSTOM_ACTION_TOGGLE_SCALE:
359             gtk_check_menu_item_set_active(
360                     GTK_CHECK_MENU_ITEM(_menu_view_show_scale_item),
361                     !_show_scale);
362             break;
363
364         case CUSTOM_ACTION_TOGGLE_POI:
365             gtk_check_menu_item_set_active(
366                     GTK_CHECK_MENU_ITEM(_menu_view_show_poi_item),
367                     !_show_poi);
368             break;
369         case CUSTOM_ACTION_CHANGE_REPO: {
370             GList *curr = g_list_find(_repo_list, _curr_repo);
371             if(!curr)
372                 break;
373
374             /* Loop until we reach a next-able repo, or until we get
375              * back to the current repo. */
376             while((curr = (curr->next ? curr->next : _repo_list))
377                     && !((RepoData*)curr->data)->nextable
378                     && curr->data != _curr_repo) { }
379
380             if(curr->data != _curr_repo)
381             {
382                 repo_set_curr(curr->data);
383                 gtk_check_menu_item_set_active(
384                         GTK_CHECK_MENU_ITEM(_curr_repo->menu_item),
385                         TRUE);
386             }
387             else
388             {
389                 popup_error(_window,
390                     _("There are no other next-able repositories."));
391             }
392             break;
393         }
394
395         case CUSTOM_ACTION_RESET_BLUETOOTH:
396             reset_bluetooth();
397             break;
398
399         case CUSTOM_ACTION_ROUTE_DISTNEXT:
400             route_show_distance_to_next();
401             break;
402
403         case CUSTOM_ACTION_ROUTE_DISTLAST:
404             route_show_distance_to_last();
405             break;
406
407         case CUSTOM_ACTION_TRACK_BREAK:
408             track_insert_break(TRUE);
409             break;
410
411         case CUSTOM_ACTION_TRACK_CLEAR:
412             track_clear();
413             break;
414
415         case CUSTOM_ACTION_TRACK_DISTLAST:
416             track_show_distance_from_last();
417             break;
418
419         case CUSTOM_ACTION_TRACK_DISTFIRST:
420             track_show_distance_from_first();
421             break;
422
423         case CUSTOM_ACTION_TOGGLE_GPS:
424             gtk_check_menu_item_set_active(
425                     GTK_CHECK_MENU_ITEM(_menu_gps_enable_item),
426                     !_enable_gps);
427             break;
428
429         case CUSTOM_ACTION_TOGGLE_GPSINFO:
430             gtk_check_menu_item_set_active(
431                     GTK_CHECK_MENU_ITEM(_menu_gps_show_info_item),
432                     !_gps_info);
433             break;
434
435         case CUSTOM_ACTION_TOGGLE_SPEEDLIMIT:
436             _speed_limit_on ^= 1;
437             break;
438
439         case CUSTOM_ACTION_TOGGLE_LAYERS:
440             maps_toggle_visible_layers ();
441             break;
442
443         default:
444             vprintf("%s(): return FALSE\n", __PRETTY_FUNCTION__);
445             return FALSE;
446     }
447
448     return TRUE;
449     vprintf("%s(): return TRUE\n", __PRETTY_FUNCTION__);
450 }
451
452 gboolean
453 window_cb_key_release(GtkWidget* widget, GdkEventKey *event)
454 {
455     CustomKey custom_key;
456     printf("%s()\n", __PRETTY_FUNCTION__);
457
458     custom_key = get_custom_key_from_keyval(event->keyval);
459     if(custom_key < 0)
460         return FALSE; /* Not our event. */
461
462     switch(_action[custom_key])
463     {
464         case CUSTOM_ACTION_ZOOM_IN:
465         case CUSTOM_ACTION_ZOOM_OUT:
466             if(_key_zoom_timeout_sid)
467             {
468                 g_source_remove(_key_zoom_timeout_sid);
469                 _key_zoom_timeout_sid = 0;
470                 _key_zoom_timeout_sid =g_timeout_add_full(G_PRIORITY_HIGH_IDLE,
471                         500, (GSourceFunc)key_zoom_timeout, NULL, NULL);
472             }
473             _key_zoom_is_down = FALSE;
474             return TRUE;
475
476         case CUSTOM_ACTION_PAN_NORTH:
477         case CUSTOM_ACTION_PAN_SOUTH:
478         case CUSTOM_ACTION_PAN_EAST:
479         case CUSTOM_ACTION_PAN_WEST:
480         case CUSTOM_ACTION_PAN_UP:
481         case CUSTOM_ACTION_PAN_DOWN:
482         case CUSTOM_ACTION_PAN_LEFT:
483         case CUSTOM_ACTION_PAN_RIGHT:
484             if(_key_pan_timeout_sid)
485             {
486                 g_source_remove(_key_pan_timeout_sid);
487                 _key_pan_timeout_sid = g_timeout_add_full(G_PRIORITY_HIGH_IDLE,
488                         500, (GSourceFunc)key_pan_timeout, NULL, NULL);
489             }
490             _key_pan_is_down = FALSE;
491             _key_pan_incr_devx = 0;
492             _key_pan_incr_devy = 0;
493             return TRUE;
494
495         default:
496             return FALSE;
497     }
498     vprintf("%s(): return\n", __PRETTY_FUNCTION__);
499 }
500
501 gboolean
502 map_cb_motion_notify(GtkWidget *widget, GdkEventMotion *event)
503 {
504     gint x, y;
505     GdkModifierType state;
506     printf("%s()\n", __PRETTY_FUNCTION__);
507
508     if(!_mouse_is_down)
509         return FALSE;
510
511     if(event->is_hint)
512         gdk_window_get_pointer(event->window, &x, &y, &state);
513     else
514     {
515         x = event->x;
516         y = event->y;
517         state = event->state;
518     }
519
520     if(_mouse_is_dragging)
521     {
522         /* Already in the process of dragging.  Set the offset. */
523         _map_offset_devx = x - _cmenu_position_x;
524         _map_offset_devy = y - _cmenu_position_y;
525         MACRO_QUEUE_DRAW_AREA();
526     }
527     else
528     {
529         gint diffx = x - _cmenu_position_x - _map_offset_devx;
530         gint diffy = y - _cmenu_position_y - _map_offset_devy;
531         if(diffx * diffx + diffy + diffy > 100)
532         {
533             _mouse_is_dragging = TRUE;
534         }
535     }
536
537     /* Return FALSE to allow context menu to work. */
538     vprintf("%s(): return FALSE\n", __PRETTY_FUNCTION__);
539     return TRUE;
540 }
541
542 gboolean
543 map_cb_button_press(GtkWidget *widget, GdkEventButton *event)
544 {
545     printf("%s()\n", __PRETTY_FUNCTION__);
546
547     if(!_mouse_is_down)
548     {
549         _cmenu_position_x = event->x + 0.5 - _map_offset_devx;
550         _cmenu_position_y = event->y + 0.5 - _map_offset_devy;
551         g_mutex_lock(_mouse_mutex);
552         _mouse_is_down = TRUE;
553     }
554
555     /* Return FALSE to allow context menu to work. */
556     vprintf("%s(): return FALSE\n", __PRETTY_FUNCTION__);
557     return FALSE;
558 }
559
560 gboolean
561 map_cb_button_release(GtkWidget *widget, GdkEventButton *event)
562 {
563     printf("%s()\n", __PRETTY_FUNCTION__);
564
565     if(!_mouse_is_down)
566     {
567         /* We didn't know about it anyway.  Return FALSE. */
568         vprintf("%s(): return FALSE\n", __PRETTY_FUNCTION__);
569         return FALSE;
570     }
571
572     _mouse_is_down = FALSE;
573
574     if(event->button == 3) /* right-click */
575     {   
576         gtk_menu_popup(_map_cmenu, NULL, NULL, NULL, NULL,
577                        event->button, event->time);
578     }
579     else
580 #ifdef DEBUG
581     if(event->button == 2) /* middle-click */
582     {   
583         screen2unit((gint)(event->x + 0.5), (gint)(event->y + 0.5),
584                 _pos.unitx, _pos.unity);
585         unit2latlon(_pos.unitx, _pos.unity, _gps.lat, _gps.lon);
586         /* Test unit-to-lat/lon conversion. */
587         latlon2unit(_gps.lat, _gps.lon, _pos.unitx, _pos.unity);
588         _gps.speed = ((gint)(_gps.speed + 5) % 60);
589         _gps.heading = ((gint)(_gps.heading + 5) % 360);
590         if(track_add(time(NULL), FALSE))
591         {
592             /* Move mark to new location. */
593             map_refresh_mark(FALSE);
594         }
595         else
596         {
597             map_move_mark();
598         }
599     }
600     else
601 #endif
602     if(_mouse_is_dragging)
603     {
604         Point clkpt;
605
606         _mouse_is_dragging = FALSE;
607
608         screen2unit(_view_halfwidth_pixels, _view_halfheight_pixels,
609                 clkpt.unitx, clkpt.unity);
610
611         if(_center_mode > 0)
612         {
613             gfloat matrix[4];
614             gint mvpt_unitx, mvpt_unity;
615             gfloat new_offset_unitx, new_offset_unity;
616             /* If auto-center is enabled (meaning that panning will cause the
617              * view the rotate according to the heading), rotate the new
618              * unitx/unity around the mvpt, by any changes in _gps.heading
619              * since the last time _map_rotate_angle was updated.  The end
620              * result is that the point the user is moving stays in the same
621              * relative point, even if the heading has since changed. */
622             gdk_pixbuf_rotate_matrix_fill_for_rotation(matrix,
623                     deg2rad(_gps.heading - _next_map_rotate_angle));
624             buf2unit(_cmenu_position_x, _cmenu_position_y,
625                     mvpt_unitx, mvpt_unity);
626             gdk_pixbuf_rotate_vector(&new_offset_unitx, &new_offset_unity,
627                     matrix,
628                     (gint)(clkpt.unitx - mvpt_unitx),
629                     (gint)(clkpt.unity -mvpt_unity));
630             clkpt.unitx = mvpt_unitx + new_offset_unitx;
631             clkpt.unity = mvpt_unity + new_offset_unity;
632         }
633
634         if(_center_mode > 0)
635             gtk_check_menu_item_set_active(
636                     GTK_CHECK_MENU_ITEM(_menu_view_ac_none_item), TRUE);
637
638         map_center_unit(clkpt);
639     }
640     else
641     {
642         gboolean selected_point = FALSE;
643         Point clkpt;
644         screen2unit(event->x, event->y, clkpt.unitx, clkpt.unity);
645
646         if(_show_poi && (_poi_zoom > _zoom))
647         {
648             PoiInfo poi;
649             selected_point = select_poi(
650                     clkpt.unitx, clkpt.unity, &poi, TRUE);
651             if(selected_point)
652             {
653                 gchar *banner;
654                 banner = g_strdup_printf("%s (%s)", poi.label, poi.clabel);
655                 MACRO_BANNER_SHOW_INFO(_window, banner);
656                 g_free(banner);
657                 g_free(poi.label);
658                 g_free(poi.desc);
659                 g_free(poi.clabel);
660             }
661         }
662         if(!selected_point && (_show_paths & ROUTES_MASK)
663                 && _route.whead <= _route.wtail)
664         {
665             WayPoint *way = find_nearest_waypoint(
666                     clkpt.unitx, clkpt.unity);
667             if(way)
668             {
669                 selected_point = TRUE;
670                 MACRO_BANNER_SHOW_INFO(_window, way->desc);
671             }
672         }
673         if(!selected_point)
674         {
675             if(_center_mode > 0)
676                 gtk_check_menu_item_set_active(
677                         GTK_CHECK_MENU_ITEM(_menu_view_ac_none_item), TRUE);
678             map_center_unit_full(clkpt, _next_zoom,
679                     _center_mode > 0 && _center_rotate
680                     ? _gps.heading : _next_map_rotate_angle);
681         }
682     }
683
684     g_mutex_unlock(_mouse_mutex);
685
686     /* Return FALSE to avoid context menu (if it hasn't popped up already). */
687     vprintf("%s(): return FALSE\n", __PRETTY_FUNCTION__);
688     return FALSE;
689 }
690
691 void
692 input_init()
693 {
694     printf("%s():\n", __PRETTY_FUNCTION__);
695
696     g_signal_connect(G_OBJECT(_window), "key_press_event",
697             G_CALLBACK(window_cb_key_press), NULL);
698
699     g_signal_connect(G_OBJECT(_window), "key_release_event",
700             G_CALLBACK(window_cb_key_release), NULL);
701
702     g_signal_connect(G_OBJECT(_map_widget), "motion_notify_event",
703             G_CALLBACK(map_cb_motion_notify), NULL);
704
705     g_signal_connect(G_OBJECT(_map_widget), "button_press_event",
706             G_CALLBACK(map_cb_button_press), NULL);
707
708     g_signal_connect(G_OBJECT(_map_widget), "button_release_event",
709             G_CALLBACK(map_cb_button_release), NULL);
710
711     gtk_widget_add_events(_map_widget,
712             GDK_EXPOSURE_MASK
713             | GDK_POINTER_MOTION_MASK
714             | GDK_POINTER_MOTION_HINT_MASK
715             | GDK_BUTTON_PRESS_MASK
716             | GDK_BUTTON_RELEASE_MASK);
717
718     vprintf("%s(): return\n", __PRETTY_FUNCTION__);
719 }