1 /******************************************************************************
2  *  Warmux is a convivial mass murder game.
3  *  Copyright (C) 2010-2011 Warmux Team.
4  *
5  *  This program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2 of the License, or
8  *  (at your option) any later version.
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with this program; if not, write to the Free Software
17  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
18  ******************************************************************************
19  * Maemo
20  *****************************************************************************/
21 
22 #include <iostream>
23 #include <glib.h>
24 #include <glib-object.h>
25 #include <libosso.h>
26 #include <SDL/SDL.h>
27 #include "sound/jukebox.h"
28 #include "game/game_time.h"
29 #include "interface/mouse.h"
30 
31 namespace {
32 
33   static void init_timer(void);
34   static void remove_timer(void);
35 
36 
37   GMainContext* maincontext = NULL;
38   GMainLoop* mainloop = NULL;
39   osso_context_t* osso_context = NULL;
40   bool display_off = false;
41   SDL_TimerID timer_id = 0;
42 
display_off_loop(gpointer data)43   static gboolean display_off_loop(gpointer data) {
44     remove_timer();
45     SDL_QuitSubSystem(SDL_INIT_TIMER);
46     GameTime::GetInstance()->SetWaitingForUser(true);
47     JukeBox::GetInstance()->CloseDevice();
48 
49     while(display_off) {
50       MSG_DEBUG("display", "display_off loop");
51       g_main_context_iteration(maincontext, true);
52     }
53 
54     if (Mouse::GetInstance()->HasFocus()) {
55       JukeBox::GetInstance()->OpenDevice();
56       JukeBox::GetInstance()->NextMusic();
57       GameTime::GetInstance()->SetWaitingForUser(false);
58     }
59 
60     SDL_InitSubSystem(SDL_INIT_TIMER);
61     init_timer();
62 
63     return false;
64   }
65 
osso_display_event_callback(osso_display_state_t state,gpointer data)66   static void osso_display_event_callback(osso_display_state_t state, gpointer data) {
67     switch(state) {
68     case OSSO_DISPLAY_ON:
69       MSG_DEBUG("display", "DISPLAY ON");
70       display_off = false;
71       break;
72     case OSSO_DISPLAY_OFF:
73       MSG_DEBUG("display", "DISPLAY OFF");
74       display_off = true;
75       g_idle_add(display_off_loop, NULL);
76       break;
77     case OSSO_DISPLAY_DIMMED:
78       MSG_DEBUG("display", "DISPLAY DIMMED");
79       break;
80     }
81   }
82 
send_null_event(Uint32 interval,void * param)83   Uint32 send_null_event(Uint32 interval, void *param) {
84     SDL_Event event;
85     SDL_UserEvent userevent;
86 
87     userevent.type = SDL_USEREVENT;
88     userevent.code = 0;
89     userevent.data1 = NULL;
90     userevent.data2 = NULL;
91 
92     event.type = SDL_USEREVENT;
93     event.user = userevent;
94 
95     SDL_PushEvent(&event);
96     return(interval);
97   }
98 
99   /* Send SDL events regularly to guarantee Glib event processing when stuck with SDL_WaitEvent */
init_timer()100   static void init_timer() {
101     if (timer_id == 0)
102       timer_id = SDL_AddTimer(2000, send_null_event, NULL);
103   }
104 
remove_timer()105   static void remove_timer() {
106     if (timer_id != 0) {
107       SDL_RemoveTimer(timer_id);
108       timer_id = 0;
109     }
110   }
111 }
112 
113 namespace Osso {
114 
Init()115   int Init() {
116     g_type_init();
117     maincontext = g_main_context_default();
118     mainloop = g_main_loop_new(maincontext, false);
119     osso_context = osso_initialize("org.warmux.game", "1.0", 0, maincontext);
120 
121     if(!osso_context) {
122       std::cerr << "could not initialize libosso\n";
123       return -1;
124     }
125 
126     osso_return_t ret;
127     ret = osso_hw_set_display_event_cb(osso_context, osso_display_event_callback, NULL);
128     if(ret != OSSO_OK) {
129       std::cerr << "could not register osso display event callback\n";
130       return -1;
131     }
132 
133     init_timer();
134 
135     return 0;
136   }
137 
Process()138   void Process() {
139     if (maincontext == NULL || osso_context == NULL)
140       return;
141 
142     while(g_main_context_pending(maincontext)) {
143       g_main_context_iteration(maincontext, false);
144     }
145   }
146 
147 }
148 
149