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