Fixed height display in SDL with new vehicle modules
[navit-package] / src / gui / sdl / gui_sdl_window.cpp
1 #include "glib.h"
2 #include <stdio.h>
3
4 //  FIXME temporary fix for enum
5 #include "projection.h"
6
7 #include "item.h"
8 #include "navit.h"
9 #include "vehicle.h"    
10 #include "profile.h"
11 #include "transform.h"
12 #include "gui.h"
13 #include "coord.h"
14 #include "plugin.h"
15 #include "callback.h"
16 #include "point.h"
17 #include "graphics.h"
18 #include "gui_sdl.h"
19 #include "navigation.h"
20 #include "debug.h"
21 #include "attr.h"
22 #include "track.h"
23 #include "menu.h"
24 #include "map.h"
25
26
27 #include "CEGUI.h"
28
29 // FIXME This is for 3d fonts. Needs QuesoGLC. Could probably (and should) be moved to graphics instead
30 // since fonts here are handled by CEGUI
31 #include "GL/glc.h"
32
33 #include "sdl_events.h"
34 #include "cegui_keyboard.h"
35 #include "wmcontrol.h"
36
37 #define VM_2D 0
38 #define VM_3D 1
39
40 bool VIEW_MODE=VM_3D;
41
42 GLdouble eyeX=400;
43 GLdouble eyeY=900;
44 GLdouble eyeZ=-800;
45 GLdouble centerX=400;
46 GLdouble centerY=300;
47 GLdouble centerZ=0;
48 GLdouble upX=0;
49 GLdouble upY=-1;
50 GLdouble upZ=0;
51
52 struct navit *sdl_gui_navit;
53
54 #include <CEGUI/RendererModules/OpenGLGUIRenderer/openglrenderer.h>
55 #include "CEGUIDefaultResourceProvider.h"
56 CEGUI::OpenGLRenderer* renderer;
57
58 #undef profile
59 #define profile(x,y)
60
61 CEGUI::Window* myRoot;
62
63 #define MODULE "gui_sdl"
64 GLuint * DLid;
65
66 #define _(STRING)    gettext(STRING)
67
68 char  media_window_title[255], media_cmd[255];
69
70 struct bookmark{
71         char * name;
72         struct callback *cb;
73         struct bookmark *next;
74 } *bookmarks;
75
76 struct former_dest{
77         char * name;
78         struct callback *cb;
79         struct former_dest *next;
80 } *former_dests;
81
82 static int
83 gui_sdl_set_graphics(struct gui_priv *this_, struct graphics *gra)
84 {
85         dbg(1,"setting up the graphics\n");
86
87         DLid=(GLuint *)graphics_get_data(gra, "opengl_displaylist");
88         if (!DLid) 
89                 return 1;
90         return 0;
91 }
92
93 static void
94 sdl_update_roadbook(struct navigation *nav)
95 {
96
97         using namespace CEGUI;
98         
99         struct navigation_list *list;   
100         list=navigation_list_new(nav);
101
102         // First, ensure the navigation tip is visible. quick workaround for when resuming a destination
103         WindowManager::getSingleton().getWindow("Navit/Routing/Tips")->show();
104
105         // update the 'Navigation Tip' on the main window
106         try {
107                 struct attr attr;
108                 item_attr_get(navigation_list_get_item(list), attr_navigation_speech, &attr);
109                 WindowManager::getSingleton().getWindow("Navit/Routing/Tips")->setText((CEGUI::utf8*)(attr.u.str));
110         }
111         catch (CEGUI::Exception& e)
112         {
113                 fprintf(stderr,"CEGUI Exception occured: \n%s\n", e.getMessage().c_str());
114                 printf("Missing control!...\n");
115         }
116
117         // Then, update the whole roadbook      
118         try {
119
120                 /* Currently we use the 'Navit' text to display the roadbook, until Mineque design a button for that            
121                 if(! WindowManager::getSingleton().getWindow("OSD/RoadbookButton")->isVisible()){
122                         WindowManager::getSingleton().getWindow("OSD/RoadbookButton")->show();
123                 }
124                 */
125
126                 MultiColumnList* mcl = static_cast<MultiColumnList*>(WindowManager::getSingleton().getWindow("Roadbook"));
127                 mcl->resetList();
128
129                 item *item;
130                 struct attr attr;
131
132                 list=navigation_list_new(nav);  
133                 while ((item=navigation_list_get_item(list))) {
134                         mcl->addRow();
135                         item_attr_get(item, attr_navigation_short, &attr);
136                         ListboxTextItem* itemListbox = new ListboxTextItem(attr.u.str);
137                         itemListbox->setSelectionBrushImage("TaharezLook", "MultiListSelectionBrush");
138                         mcl->setItem(itemListbox, 0, mcl->getRowCount()-1);
139                 }
140                 navigation_list_destroy(list);
141         }
142         catch (CEGUI::Exception& e)
143         {
144                 dbg(0,"CEGUI Exception occured: \n%s\n", e.getMessage().c_str());
145                 dbg(0,"Missing control!\n");
146         }
147
148 }
149
150 static void show_road_name(){
151         struct tracking *tracking;
152         struct attr road_name_attr;
153         tracking=navit_get_tracking(sdl_gui_navit);
154
155         using namespace CEGUI;
156
157
158         if (tracking && tracking_get_current_attr(tracking, attr_label, &road_name_attr) ) {
159                 WindowManager::getSingleton().getWindow("Navit/Routing/CurrentRoadName")->setText((CEGUI::utf8*)(road_name_attr.u.str));
160         }
161
162 }
163
164 static gboolean gui_timeout_cb(gpointer data)
165 {
166         return TRUE;
167 }
168
169 static int gui_run_main_loop(struct gui_priv *this_)
170 {
171         GSource *timeout;
172         using namespace CEGUI;
173         dbg(0,"Entering main loop\n");
174
175         bool must_quit = false;
176
177         // get "run-time" in seconds
178         double last_time_pulse = static_cast<double>(SDL_GetTicks());
179
180         int frames=0;
181         char fps [12];
182
183         struct map_selection sel;
184
185         memset(&sel, 0, sizeof(sel));
186         sel.u.c_rect.rl.x=800;
187         sel.u.c_rect.rl.y=600;
188         
189         transform_set_screen_selection(navit_get_trans(this_->nav), &sel);
190         navit_draw(this_->nav);
191
192         bool enable_timer=0;
193
194         struct navigation *navig;
195         navig=navit_get_navigation(sdl_gui_navit);
196
197         navigation_register_callback(navig,
198                 attr_navigation_long,
199                 callback_new_0((void (*)())sdl_update_roadbook)
200         );
201
202         timeout = g_timeout_source_new(100);
203         g_source_set_callback(timeout, gui_timeout_cb, NULL, NULL);
204         g_source_attach(timeout, NULL);
205         while (!must_quit)
206         {
207                 if(enable_timer)
208                         profile(0,NULL);
209                 glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT);
210
211                 glMatrixMode(GL_MODELVIEW);
212                 glLoadIdentity();
213
214                 if(VIEW_MODE==VM_3D){
215                         gluLookAt(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ);
216                 }
217
218                 // FIXME This is to draw a ground. This is ugly and need to be fixed.
219                 // Without it, we see the color of sky under the roads.
220                 glColor4f(0.0f,0.7f,0.35f,1.0f);
221                 glBegin(GL_POLYGON);
222                         glVertex3f( -800,-600*3, 0.0f);
223                         glVertex3f( -800,600*2, 0.0f);
224                         glVertex3f( 1600,600*2, 0.0f);  
225                         glVertex3f( 1600,-600*3, 0.0f); 
226                 glEnd();
227
228
229                 if(enable_timer)
230                         profile(0,"graphics_redraw");
231 //              if (!g_main_context_iteration (NULL, FALSE))
232  //                     sleep(1);
233                 g_main_context_iteration (NULL, TRUE);
234                 //      sleep(1);
235                 if(enable_timer)
236                         profile(0,"main context");
237
238                 show_road_name();
239
240                 navit_draw_displaylist(sdl_gui_navit);
241
242                 inject_input(must_quit);
243                 if(enable_timer)
244                         profile(0,"inputs");
245
246                 // Render the cursor.
247                 int x=400;
248                 int y=480;
249                 float cursor_size=15.0f;
250                 glColor4f(0.0f,1.0f,0.0f,0.75f);
251                 glEnable(GL_BLEND);
252                 glBegin(GL_TRIANGLES);
253                         glVertex3f( x, y-cursor_size, 0.0f);
254                         glVertex3f(x-cursor_size,y+cursor_size, 0.0f);
255                         glVertex3f( x+cursor_size,y+cursor_size, 0.0f); 
256                 glEnd();
257                 glDisable(GL_BLEND);
258                 if(enable_timer)
259                         profile(0,"cursor");
260
261                 frames++;
262                 if(SDL_GetTicks()-last_time_pulse>1000){
263                         sprintf(fps,"%i fps",frames); // /(SDL_GetTicks()/1000));
264                         frames=0;
265                         last_time_pulse = SDL_GetTicks();
266                 }
267                 WindowManager::getSingleton().getWindow("OSD/Satellites")->setText(fps);
268
269                 if(enable_timer)
270                         profile(0,"fps");
271
272                 CEGUI::System::getSingleton().renderGUI();
273                 if(enable_timer)
274                         profile(0,"GUI");
275
276                 SDL_GL_SwapBuffers();
277         }
278         g_source_destroy(timeout);
279
280 }
281
282 static struct menu_priv *
283 add_menu(struct menu_priv *menu, struct menu_methods *meth, char *name, enum menu_type type, struct callback *cb);
284
285 static struct menu_methods menu_methods = {
286         add_menu,
287 };
288
289 struct menu_priv {
290         char *path;     
291 //      GtkAction *action;
292         struct gui_priv *gui;
293         enum menu_type type;
294         struct callback *cb;
295         struct menu_priv *child;
296         struct menu_priv *sibling;
297         gulong handler_id;
298         guint merge_id;
299 };
300
301 #define MENU_BOOKMARK 2
302 #define MENU_FORMER_DEST 3
303
304 static struct menu_priv *
305 add_menu(struct menu_priv *menu, struct menu_methods *meth, char *name, enum menu_type type, struct callback *cb)
306 {
307         using namespace CEGUI;
308         *meth=menu_methods;
309         dbg(0,"callback : %s\n",name);
310
311         if(menu==(struct menu_priv *)(MENU_BOOKMARK)){
312                 dbg(0,"Item is a bookmark\n");
313                 MultiColumnList* mcl = static_cast<MultiColumnList*>(WindowManager::getSingleton().getWindow("Bookmarks/Listbox"));
314
315                 ListboxTextItem* itemListbox = new ListboxTextItem((CEGUI::utf8*)(name));
316                 itemListbox->setSelectionBrushImage("TaharezLook", "MultiListSelectionBrush");
317                 mcl->addRow(itemListbox,0);
318
319                 struct bookmark *newB = g_new0(struct bookmark, 1);
320                 newB->name=g_strdup(name);
321                 newB->cb=cb;
322                 if (newB) {
323                         newB->next = bookmarks;
324                         bookmarks = newB;
325                 }
326
327         }
328
329         if(menu==(struct menu_priv *)(MENU_FORMER_DEST)){
330                 dbg(0,"Item is a former destination\n");
331                 MultiColumnList* mcl = static_cast<MultiColumnList*>(WindowManager::getSingleton().getWindow("FormerDests/Listbox"));
332
333                 ListboxTextItem* itemListbox = new ListboxTextItem((CEGUI::utf8*)(name));
334                 itemListbox->setSelectionBrushImage("TaharezLook", "MultiListSelectionBrush");
335                 mcl->addRow(itemListbox,0);
336
337                 struct former_dest *newB = g_new0(struct former_dest, 1);
338                 newB->name=g_strdup(name);
339                 newB->cb=cb;
340                 if (newB) {
341                         newB->next = former_dests;
342                         former_dests = newB;
343                 }
344
345         }
346
347         if(!strcmp(name,"Bookmarks")){
348                 dbg(0,"Menu is the bookmark menu!\n");
349                 return (struct menu_priv *)MENU_BOOKMARK;
350         } else if(!strcmp(name,"Former Destinations")){
351                 dbg(0,"Menu is the Former Destinations menu!\n");
352                 return (struct menu_priv *)MENU_FORMER_DEST;
353         } else {
354                 return (struct menu_priv *)1;
355         }
356 }
357
358 bool BookmarkGo(const char * name)
359 {
360         dbg(0,"searching for bookmark %s\n",name);
361         bookmark * bookmark_search=bookmarks;
362         while ( bookmark_search ){
363                 dbg(0,"-> %s\n",bookmark_search->name);
364                 if(!strcmp(bookmark_search->name,name)){
365                         dbg(0,"Got it :)\n");
366                          callback_call_0(bookmark_search->cb);
367                 }
368                 bookmark_search=bookmark_search->next;
369         }
370
371 }
372
373 bool FormerDestGo(const char * name)
374 {
375         dbg(0,"searching for former_dest %s\n",name);
376         former_dest * former_dest_search=former_dests;
377         while ( former_dest_search ){
378                 dbg(0,"-> %s\n",former_dest_search->name);
379                 if(!strcmp(former_dest_search->name,name)){
380                         dbg(0,"Got it :)\n");
381                         callback_call_0(former_dest_search->cb);
382                 }
383                 former_dest_search=former_dest_search->next;
384         }
385
386 }
387 static struct menu_priv *
388 gui_sdl_toolbar_new(struct gui_priv *this_, struct menu_methods *meth)
389 {
390         return NULL; //gui_gtk_ui_new(this_, meth, "/ui/ToolBar", nav, 0);
391 }
392
393 static struct statusbar_priv *
394 gui_sdl_statusbar_new(struct gui_priv *gui, struct statusbar_methods *meth)
395 {
396         return NULL; //gui_gtk_ui_new(this_, meth, "/ui/ToolBar", nav, 0);
397 }
398
399 static struct menu_priv *
400 gui_sdl_menubar_new(struct gui_priv *this_, struct menu_methods *meth)
401 {
402         *meth=menu_methods;
403         return (struct menu_priv *) 1; //gui_gtk_ui_new(this_, meth, "/ui/MenuBar", nav, 0);
404 }
405
406 static struct menu_priv *
407 gui_sdl_popup_new(struct gui_priv *this_, struct menu_methods *meth)
408 {
409         return NULL; //gui_gtk_ui_new(this_, meth, "/ui/PopUp", nav, 1);
410 }
411
412 struct gui_methods gui_sdl_methods = {
413         gui_sdl_menubar_new,
414         gui_sdl_toolbar_new,
415         gui_sdl_statusbar_new,
416         gui_sdl_popup_new,
417         gui_sdl_set_graphics,
418         gui_run_main_loop,
419 };
420
421
422 int init_GL() {
423
424         // Blue sky
425         glClearColor(0.3,0.7,1.0,0);
426
427         if(VIEW_MODE==VM_2D){
428                 glMatrixMode( GL_PROJECTION );
429                 glLoadIdentity();
430         
431                 glOrtho( 0, XRES, YRES, 0, -1, 1 );
432         
433                 glMatrixMode(GL_MODELVIEW);
434                 glLoadIdentity();
435                 CEGUI::WindowManager::getSingleton().getWindow("OSD/ViewMode")->setText("2D");
436         } else {
437
438                 // Dimensions de la fenetre de rendu 
439                 glViewport(0, 0, XRES, YRES);
440                 // Initialisation de la matrice de projection 
441                 glMatrixMode(GL_PROJECTION);
442                 glLoadIdentity();
443                 gluPerspective(45, 1.0, 0.1, 2800.0);
444                 // Rendu avec lissage de Gouraud 
445 //              glShadeModel(GL_SMOOTH);
446         //      glEnable(GL_DEPTH_TEST);
447
448
449                 glMatrixMode(GL_MODELVIEW);
450                 glLoadIdentity();
451 //              gluLookAt(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ);
452                 CEGUI::WindowManager::getSingleton().getWindow("OSD/ViewMode")->setText("3D");
453         }
454
455         //Display list code
456         //      GLuint glGenLists(GLsizei numberOfIDsRequired);
457         // linesDL = glGenLists(1);
458
459         if( glGetError() != GL_NO_ERROR ) {
460                 return 0;
461         }
462         return 1;
463 }
464
465 bool ToggleView(const CEGUI::EventArgs& event)
466 {
467         VIEW_MODE=!VIEW_MODE;
468         init_GL();
469 }
470
471 bool MoveCamera(const CEGUI::EventArgs& event){
472         
473         CEGUI::Scrollbar * sb = static_cast<const CEGUI::Scrollbar *>(CEGUI::WindowManager::getSingleton().getWindow("OSD/Scrollbar1"));
474         dbg(0,"moving : %f\n",sb->getScrollPosition());
475         eyeZ=-sb->getScrollPosition();
476         if (eyeZ>-100){
477                 eyeZ=-100;
478         }
479 }
480
481
482
483 static void init_sdlgui(char * skin_layout,int fullscreen,int tilt)
484 {
485         SDL_Surface * screen;
486 //      atexit (SDL_Quit);
487         SDL_Init (SDL_INIT_VIDEO);
488         int videoFlags;
489         const SDL_VideoInfo *videoInfo;
490         videoInfo = SDL_GetVideoInfo( );
491
492         if ( !videoInfo )
493         {
494             fprintf( stderr, "Video query failed: %s\n",
495                      SDL_GetError( ) );
496         }
497
498         /* the flags to pass to SDL_SetVideoMode */
499         videoFlags  = SDL_OPENGL;          /* Enable OpenGL in SDL */
500         videoFlags |= SDL_GL_DOUBLEBUFFER; /* Enable double buffering */
501         videoFlags |= SDL_HWPALETTE;       /* Store the palette in hardware */
502         videoFlags |= SDL_RESIZABLE;       /* Enable window resizing */
503         
504         /* This checks to see if surfaces can be stored in memory */
505         if ( videoInfo->hw_available )
506                 videoFlags |= SDL_HWSURFACE;
507         else
508                 videoFlags |= SDL_SWSURFACE;
509         
510         /* This checks if hardware blits can be done */
511         if ( videoInfo->blit_hw )
512                 videoFlags |= SDL_HWACCEL;
513         
514         /* Sets up OpenGL double buffering */
515         SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
516
517         SDL_WM_SetCaption("NavIt - The OpenSource vector based navigation engine", NULL);
518
519         /* get a SDL surface */
520         screen = SDL_SetVideoMode( XRES, YRES, 32,
521                                         videoFlags );
522
523         if (screen == NULL) {
524                 fprintf (stderr, "Can't set SDL: %s\n", SDL_GetError ());
525                 exit (1);
526         }
527         if(fullscreen){
528                 SDL_WM_ToggleFullScreen(screen);
529         }
530         SDL_ShowCursor (SDL_ENABLE);
531         SDL_EnableUNICODE (1);
532         SDL_EnableKeyRepeat (SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
533
534 //      init_GL();
535         
536         try
537         {
538                 renderer = new CEGUI::OpenGLRenderer(0,XRES,YRES);
539                 new CEGUI::System(renderer);
540
541                 using namespace CEGUI;
542
543                 SDL_ShowCursor(SDL_ENABLE);
544                 SDL_EnableUNICODE(1);
545                 SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
546                 
547                 CEGUI::DefaultResourceProvider* rp = static_cast<CEGUI::DefaultResourceProvider*>
548                 (System::getSingleton().getResourceProvider());
549                 
550
551                 // FIXME This should maybe move to navit.xml
552                 static char *datafiles_path[]={
553                         "./gui/sdl/datafiles",
554                         "/usr/share/navit/datafiles",
555                         "/usr/local/share/navit/datafiles",
556                         NULL,
557                 };
558
559                 char **filename=datafiles_path;
560
561                 while (*filename) {     
562                         if (FILE * file = fopen(*filename, "r"))
563                         {
564                                 fclose(file);
565                                 break;
566                         }
567                         filename++;
568                 }
569
570                 if(*filename==NULL){
571                         // FIXME Elaborate the possible solutions
572                         printf("Can't find the datafiles directory for CEGUI files. Navit will probably crash :)\n");
573                 } else {
574                         printf("Loading SDL datafiles from %s\n",*filename);
575                 }
576
577                 rp->setResourceGroupDirectory("schemes", g_strdup_printf("%s/schemes/",*filename));
578                 rp->setResourceGroupDirectory("imagesets", g_strdup_printf("%s/imagesets/",*filename));
579                 rp->setResourceGroupDirectory("fonts", g_strdup_printf("%s/fonts/",*filename));
580                 rp->setResourceGroupDirectory("layouts", g_strdup_printf("%s/layouts/",*filename));
581                 rp->setResourceGroupDirectory("looknfeels", g_strdup_printf("%s/looknfeel/",*filename));
582                 rp->setResourceGroupDirectory("lua_scripts", g_strdup_printf("%s/lua_scripts/",*filename));
583
584
585                 CEGUI::Imageset::setDefaultResourceGroup("imagesets");
586                 CEGUI::Font::setDefaultResourceGroup("fonts");
587                 CEGUI::Scheme::setDefaultResourceGroup("schemes");
588                 CEGUI::WidgetLookManager::setDefaultResourceGroup("looknfeels");
589                 CEGUI::WindowManager::setDefaultResourceGroup("layouts");
590                 CEGUI::ScriptModule::setDefaultResourceGroup("lua_scripts");
591
592                 char buffer [50];
593                 sprintf (buffer, "%s.scheme", skin_layout);
594                 dbg(1,"Loading scheme : %s\n",buffer);
595
596                 CEGUI::SchemeManager::getSingleton().loadScheme(buffer);
597
598                 CEGUI::FontManager::getSingleton().createFont("DejaVuSans-10.font");
599                 CEGUI::FontManager::getSingleton().createFont("DejaVuSans-14.font");
600
601                 CEGUI::System::getSingleton().setDefaultFont("DejaVuSans-10");
602
603                 CEGUI::WindowManager& wmgr = CEGUI::WindowManager::getSingleton();
604
605                 dbg(1,"Loading layout : %s\n",buffer);
606
607                 sprintf (buffer, "%s.layout", skin_layout);
608
609                 myRoot = CEGUI::WindowManager::getSingleton().loadWindowLayout(buffer);
610
611                 CEGUI::System::getSingleton().setGUISheet(myRoot);
612
613                 try {
614
615                 CEGUI::WindowManager::getSingleton().getWindow("OSD/Quit")->subscribeEvent(PushButton::EventClicked, Event::Subscriber(ButtonQuit));
616 //              CEGUI::WindowManager::getSingleton().getWindow("OSD/Quit")->setText(_("Quit"));
617
618                 CEGUI::WindowManager::getSingleton().getWindow("ZoomInButton")->subscribeEvent(PushButton::EventClicked, Event::Subscriber(ZoomIn));
619 //              CEGUI::WindowManager::getSingleton().getWindow("ZoomInButton")->setText(_("ZoomIn"));
620
621                 CEGUI::WindowManager::getSingleton().getWindow("ZoomOutButton")->subscribeEvent(PushButton::EventClicked, Event::Subscriber(ZoomOut));
622 //              CEGUI::WindowManager::getSingleton().getWindow("ZoomOutButton")->setText(_("ZoomOut"));
623
624                 CEGUI::WindowManager::getSingleton().getWindow("AdressSearch/CountryEditbox")->subscribeEvent(Window::EventKeyUp, Event::Subscriber(DestinationEntryChange));
625                 CEGUI::WindowManager::getSingleton().getWindow("AdressSearch/CountryEditbox")->subscribeEvent(Window::EventMouseButtonDown, Event::Subscriber(handleMouseEnters));
626                 CEGUI::WindowManager::getSingleton().getWindow("AdressSearch/TownEditbox")->subscribeEvent(Window::EventKeyUp, Event::Subscriber(DestinationEntryChange));
627                 CEGUI::WindowManager::getSingleton().getWindow("AdressSearch/TownEditbox")->subscribeEvent(Window::EventMouseButtonDown, Event::Subscriber(handleMouseEnters));
628                 CEGUI::WindowManager::getSingleton().getWindow("AdressSearch/StreetEditbox")->subscribeEvent(Window::EventKeyUp, Event::Subscriber(DestinationEntryChange));
629                 CEGUI::WindowManager::getSingleton().getWindow("AdressSearch/StreetEditbox")->subscribeEvent(Window::EventMouseButtonDown, Event::Subscriber(handleMouseEnters));
630
631                 CEGUI::WindowManager::getSingleton().getWindow("DestinationButton")->subscribeEvent(PushButton::EventClicked, Event::Subscriber(DestinationWindowSwitch));
632                 CEGUI::WindowManager::getSingleton().getWindow("DestinationWindow/Address")->subscribeEvent(PushButton::EventClicked, Event::Subscriber(AddressSearchSwitch));
633                 CEGUI::WindowManager::getSingleton().getWindow("DestinationWindow/Bookmark")->subscribeEvent(PushButton::EventClicked, Event::Subscriber(BookmarkSelectionSwitch));
634                 CEGUI::WindowManager::getSingleton().getWindow("DestinationWindow/FormerDest")->subscribeEvent(PushButton::EventClicked, Event::Subscriber(FormerDestSelectionSwitch));
635
636
637                 CEGUI::WindowManager::getSingleton().getWindow("OSD/ViewMode")->subscribeEvent(PushButton::EventClicked, Event::Subscriber(ToggleView));
638
639                 CEGUI::WindowManager::getSingleton().getWindow("AdressSearch/GO")->subscribeEvent(PushButton::EventClicked, Event::Subscriber(ButtonGo));
640                 CEGUI::WindowManager::getSingleton().getWindow("AdressSearch/KB")->subscribeEvent(PushButton::EventClicked, Event::Subscriber(ShowKeyboard));
641
642                 CEGUI::WindowManager::getSingleton().getWindow("AdressSearch/Listbox")->subscribeEvent(MultiColumnList::EventSelectionChanged, Event::Subscriber(ItemSelect));
643                 CEGUI::WindowManager::getSingleton().getWindow("Bookmarks/Listbox")->subscribeEvent(MultiColumnList::EventSelectionChanged, Event::Subscriber(BookmarkSelect));
644                 CEGUI::WindowManager::getSingleton().getWindow("FormerDests/Listbox")->subscribeEvent(MultiColumnList::EventSelectionChanged, Event::Subscriber(FormerDestSelect));
645
646
647                 // Translation for StaticTexts (labels)
648                 CEGUI::WindowManager::getSingleton().getWindow("AdressSearch/Country")->setText(_("Country"));
649                 CEGUI::WindowManager::getSingleton().getWindow("AdressSearch/Town")->setText(_("City"));
650                 CEGUI::WindowManager::getSingleton().getWindow("AdressSearch/Street")->setText(_("Street"));
651
652
653                 MultiColumnList* mcl = static_cast<MultiColumnList*>(WindowManager::getSingleton().getWindow("AdressSearch/Listbox"));
654
655                 mcl->setSelectionMode(MultiColumnList::RowSingle) ;
656                 mcl->addColumn("Value", 0, cegui_absdim(200.0));
657                 mcl->addColumn("ID", 1, cegui_absdim(70.0));
658                 mcl->addColumn("Assoc", 2, cegui_absdim(70.0));
659                 mcl->addColumn("x", 3, cegui_absdim(70.0));
660                 mcl->addColumn("y", 4, cegui_absdim(70.0));
661
662                 MultiColumnList* mcl2 = static_cast<MultiColumnList*>(WindowManager::getSingleton().getWindow("Roadbook"));
663
664                 mcl2->setSelectionMode(MultiColumnList::RowSingle) ;
665                 mcl2->addColumn("Instructions", 0, cegui_absdim(700.0));
666
667                 MultiColumnList* mcl3 = static_cast<MultiColumnList*>(WindowManager::getSingleton().getWindow("Bookmarks/Listbox"));
668
669                 mcl3->setSelectionMode(MultiColumnList::RowSingle) ;
670                 mcl3->addColumn("Name", 0, cegui_absdim(700.0));
671
672                 MultiColumnList* mcl4 = static_cast<MultiColumnList*>(WindowManager::getSingleton().getWindow("FormerDests/Listbox"));
673
674                 mcl4->setSelectionMode(MultiColumnList::RowSingle) ;
675                 mcl4->addColumn("Name", 0, cegui_absdim(700.0));
676
677                 BuildKeyboard();
678
679                 CEGUI::WindowManager::getSingleton().getWindow("OSD/Scrollbar1")->subscribeEvent(Scrollbar::EventScrollPositionChanged, Event::Subscriber(MoveCamera));
680
681                 // FIXME : char (conf) -> int (init) -> char (property) = bad
682                 char buffer[4];
683                 sprintf (buffer,"%i",tilt);
684                 CEGUI::WindowManager::getSingleton().getWindow("OSD/Scrollbar1")->setProperty("ScrollPosition",buffer);
685                 eyeZ=-tilt;
686
687                 CEGUI::WindowManager::getSingleton().getWindow("OSD/RoadbookButton")->subscribeEvent(PushButton::EventClicked, Event::Subscriber(RoadBookSwitch));
688                 CEGUI::WindowManager::getSingleton().getWindow("OSD/RoadbookButton")->setText(_("RoadBook"));
689
690                 CEGUI::WindowManager::getSingleton().getWindow("OSD/nGhostButton")->subscribeEvent(PushButton::EventClicked, Event::Subscriber(Switch_to_nGhost));
691                 // this one is maybe not needed anymore
692                 CEGUI::WindowManager::getSingleton().getWindow("OSD/RoadbookButton2")->subscribeEvent(PushButton::EventClicked, Event::Subscriber(RoadBookSwitch));
693
694                 }
695                 catch (CEGUI::Exception& e)
696                 {
697                         fprintf(stderr,"CEGUI Exception occured: \n%s\n", e.getMessage().c_str());
698                         printf("Missing control!...\n");
699                 }
700
701         }
702         catch (CEGUI::Exception& e)
703         {
704                 fprintf(stderr,"CEGUI Exception occured: \n%s\n", e.getMessage().c_str());
705                 printf("quiting...\n");
706                 exit(1);
707         }
708         init_GL();
709         // Force centering view on cursor
710 //      navit_toggle_cursor(gui->nav);
711         // Force refresh on gps update
712 //      navit_toggle_tracking(gui->nav);
713         
714 }
715
716 static void vehicle_callback_handler( struct navit *nav, struct vehicle *v){
717         char buffer [50];
718         struct attr attr;
719         int sats=0, sats_used=0;
720
721         if (vehicle_position_attr_get(v, attr_position_speed, &attr))
722                 sprintf (buffer, "%02.02f km/h", *attr.u.numd);
723         else
724                 strcpy (buffer, "N/A");
725         CEGUI::WindowManager::getSingleton().getWindow("OSD/SpeedoMeter")->setText(buffer);
726
727         if (vehicle_position_attr_get(v, attr_position_height, &attr))
728                 sprintf (buffer, "%.f m", *attr.u.numd);
729         else
730                 strcpy (buffer, "N/A");
731         CEGUI::WindowManager::getSingleton().getWindow("OSD/Altimeter")->setText(buffer);
732
733         if (vehicle_position_attr_get(v, attr_position_sats, &attr))
734                 sats=attr.u.num;
735         if (vehicle_position_attr_get(v, attr_position_sats_used, &attr))
736                 sats_used=attr.u.num;
737 //      printf(" sats : %i, used %i: \n",sats,sats_used);
738         // Sat image hardcoded for now. may break the TaharezSkin
739         // setProperty("Image", CEGUI::PropertyHelper::imageToString( yourImageSet->getImage( "yourImageName" ) ) );
740
741         try {
742                 if(sats_used>1){
743                         CEGUI::WindowManager::getSingleton().getWindow("SateliteStrenghBar1")->setProperty("Image","set:Mineque-Black image:SateliteStrenghBarOn");
744                 } else {
745                         CEGUI::WindowManager::getSingleton().getWindow("SateliteStrenghBar1")->setProperty("Image","set:Mineque-Black image:SateliteStrenghBarOff");
746                 }
747         
748                 if(sats_used>3){
749                         CEGUI::WindowManager::getSingleton().getWindow("SateliteStrenghBar2")->setProperty("Image","set:Mineque-Black image:SateliteStrenghBarOn");
750                 } else {
751                         CEGUI::WindowManager::getSingleton().getWindow("SateliteStrenghBar2")->setProperty("Image","set:Mineque-Black image:SateliteStrenghBarOff");
752                 }
753         
754                 if(sats_used>5){
755                         CEGUI::WindowManager::getSingleton().getWindow("SateliteStrenghBar3")->setProperty("Image","set:Mineque-Black image:SateliteStrenghBarOn");
756                 } else {
757                         CEGUI::WindowManager::getSingleton().getWindow("SateliteStrenghBar3")->setProperty("Image","set:Mineque-Black image:SateliteStrenghBarOff");
758                 }
759         
760                 if(sats_used>7){
761                         CEGUI::WindowManager::getSingleton().getWindow("SateliteStrenghBar4")->setProperty("Image","set:Mineque-Black image:SateliteStrenghBarOn");
762                 } else {
763                         CEGUI::WindowManager::getSingleton().getWindow("SateliteStrenghBar4")->setProperty("Image","set:Mineque-Black image:SateliteStrenghBarOff");
764                 }
765         
766                 if(sats_used>8){
767                         CEGUI::WindowManager::getSingleton().getWindow("SateliteStrenghBar5")->setProperty("Image","set:Mineque-Black image:SateliteStrenghBarOn");
768                 } else {
769                         CEGUI::WindowManager::getSingleton().getWindow("SateliteStrenghBar5")->setProperty("Image","set:Mineque-Black image:SateliteStrenghBarOff");
770                 }
771         }
772         catch (CEGUI::Exception& e)
773         {
774                 dbg(1,"Warning : you skin doesn't have the satellitebars. You should use Mineque's skin.\n");
775         }
776
777 }
778
779 static struct gui_priv *
780 gui_sdl_new(struct navit *nav, struct gui_methods *meth, struct attr **attrs) 
781 {
782         dbg(1,"Begin SDL init\n");
783         struct gui_priv *this_;
784         sdl_gui_navit=nav;
785         
786         if(sdl_gui_navit){      
787                 dbg(1,"VALID navit instance in gui\n");
788         } else {
789                 dbg(1,"Invalid navit instance in gui\n");
790         }
791         if(nav){        
792                 dbg(1,"VALID source navit instance in gui\n");
793         } else {
794                 dbg(1,"Invalid source navit instance in gui\n");
795         }
796         
797         *meth=gui_sdl_methods;
798
799         this_=g_new0(struct gui_priv, 1);
800         int fullscreen=0;
801
802         struct attr *fullscreen_setting=attr_search(attrs, NULL, attr_fullscreen);
803         //FIXME currently, we only check if fullscreen is declared, but not its value
804         if(fullscreen_setting){
805                 fullscreen=1;
806                 printf("fullscreen\n");
807         } else {
808                 fullscreen=0;
809                 printf("Normal screen\n");
810         }
811
812         int tilt=400;
813         struct attr *tilt_setting=attr_search(attrs, NULL, attr_tilt);
814         if(tilt_setting){
815                 if(sscanf(tilt_setting->u.str,"%i",&tilt)){
816                         dbg(0,"tilt set to %i\n",tilt);
817                 } else {
818                         dbg(0,"title was not recognized : %s\n",tilt_setting->u.str);
819                 }
820         } else {
821                 dbg(0,"tilt is not set\n");
822         }
823         
824         struct attr *view_mode_setting=attr_search(attrs, NULL, attr_view_mode);
825         if(view_mode_setting){
826                 if(!strcmp(view_mode_setting->u.str,"2D")){
827                         dbg(0,"View mode is 2D\n");
828                         VIEW_MODE=VM_2D;
829                 } else {
830                         dbg(0,"view mode is something else : %s\n",view_mode_setting->u.str);
831                 }
832                 
833         } else {
834                 dbg(0,"view_mode is not set\n");
835         }
836
837         struct attr *media_cmd_setting=attr_search(attrs, NULL, attr_media_cmd);
838         if(media_cmd_setting){
839                 dbg(0,"setting media_cmd to %s\n",media_cmd_setting->u.str);
840                 strcpy(media_cmd,media_cmd_setting->u.str);
841         } else {
842 //              strcpy(media_cmd_setting->u.str,media_window_title);
843         }
844
845         struct attr *media_window_title_setting=attr_search(attrs, NULL, attr_media_window_title);
846         if(media_window_title_setting){
847                 strcpy(media_window_title,media_window_title_setting->u.str);
848         } else {
849 //              strcpy(media_cmd_setting->u.str,media_window_title);
850         }
851
852         struct attr *skin_setting=attr_search(attrs, NULL, attr_skin);
853         if(skin_setting){
854                 init_sdlgui(skin_setting->u.str,fullscreen,tilt);
855         } else {
856                 g_warning("Warning, no skin set for <sdl> in navit.xml. Using default one");
857                 init_sdlgui("TaharezLook",fullscreen,tilt);
858         }
859         
860
861         dbg(1,"End SDL init\n");
862
863         //gui_sdl_window.cpp:710: error: invalid conversion from 'void (*)(vehicle*)' to 'void (*)()'
864         struct callback *cb=callback_new_0(callback_cast(vehicle_callback_handler));
865
866         navit_add_vehicle_cb(nav,cb);
867         this_->nav=nav;
868         
869         return this_;
870 }
871
872 void
873 plugin_init(void)
874 {
875         dbg(1,"registering sdl plugin\n");
876         plugin_register_gui_type("sdl", gui_sdl_new);
877 }