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