1 /* $Id: LobbyClientView.cpp,v 1.13 2003/07/19 18:58:30 nan Exp $ */
2 
3 // Copyright (C) 2001-2003  ���� �ȹ�(Kanna Yoshihiro)
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 #include "ttinc.h"
20 #include "LobbyClient.h"
21 #include "LobbyClientView.h"
22 #include "RCFile.h"
23 #include <time.h>
24 #include <string>
25 
26 extern RCFile *theRC;
27 
28 extern bool isComm;
29 extern long mode;
30 
31 extern void InitGame();
32 extern void StartGame();
33 extern void EndGame();
34 extern bool PollEvent();
35 
36 extern void QuitGame();
37 
38 bool isWaiting = false;		// waiting for opponent player on the internet
39 
40 #ifdef WIN32
41 LONG pEditWndProc;
42 LONG pParentWndProc;
43 
44 HWND pChildHWnd;
45 LobbyClientView *theLobbyClientView;
46 
47 // Copyed from gdkim-win32.c of GTK+-2.2.
48 gchar *
_gdk_ucs2_to_utf8(const wchar_t * src,gint src_len)49 _gdk_ucs2_to_utf8 (const wchar_t *src,
50 		   gint           src_len)
51 {
52   gint len;
53   const wchar_t *wcp;
54   guchar *mbstr, *bp;
55 
56   wcp = src;
57   len = 0;
58   while (wcp < src + src_len)
59     {
60       const wchar_t c = *wcp++;
61 
62       if (c < 0x80)
63 	len += 1;
64       else if (c < 0x800)
65 	len += 2;
66       else
67 	len += 3;
68     }
69 
70   mbstr = (guchar *) g_malloc (len + 1);
71 
72   wcp = src;
73   bp = mbstr;
74   while (wcp < src + src_len)
75     {
76       int first;
77       wchar_t c = *wcp++;
78 
79       if (c < 0x80)
80 	{
81 	  first = 0;
82 	  len = 1;
83 	}
84       else if (c < 0x800)
85 	{
86 	  first = 0xc0;
87 	  len = 2;
88 	}
89       else
90 	{
91 	  first = 0xe0;
92 	  len = 3;
93 	}
94 
95       /* Woo-hoo! */
96       switch (len)
97 	{
98 	case 3: bp[2] = (c & 0x3f) | 0x80; c >>= 6; /* Fall through */
99 	case 2: bp[1] = (c & 0x3f) | 0x80; c >>= 6; /* Fall through */
100 	case 1: bp[0] = c | first;
101 	}
102 
103       bp += len;
104     }
105   *bp = 0;
106 
107   return (gchar *)mbstr;
108 }
109 
110 
111 LRESULT CALLBACK
EditWindowProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam)112 LobbyClientView::EditWindowProc( HWND hwnd, UINT msg,
113 				 WPARAM wparam, LPARAM lparam) {
114   if ( msg == WM_CHAR && wparam == 13 ) {
115     char buf[512], unibuf[2048];
116     GetWindowText( hwnd, buf, 512 );
117 
118     char locale[10];
119     HKL input_locale = GetKeyboardLayout (0);
120     GetLocaleInfo (MAKELCID (LOWORD (input_locale), SORT_DEFAULT),
121 		   LOCALE_IDEFAULTANSICODEPAGE,
122 		   locale, sizeof (locale));
123 
124     int srclen;
125     srclen = MultiByteToWideChar(atoi(locale), 0, buf, 512,
126 				 (LPWSTR)unibuf, 2048 );
127 
128     gtk_entry_set_text( GTK_ENTRY(theLobbyClientView->m_chatinput),
129 			_gdk_ucs2_to_utf8((const wchar_t *)unibuf, srclen) );
130 
131     GdkEventKey event;
132     event.keyval = GDK_Return;
133 
134     LobbyClientView::KeyPress( theLobbyClientView->m_chatinput,
135 			       &event, theLobbyClientView );
136 
137     SetWindowText( hwnd, NULL );
138     return 0;
139   }
140 
141   return CallWindowProc((WNDPROC)pEditWndProc,hwnd,msg,wparam,lparam);
142 }
143 
144 LRESULT CALLBACK
ParentWindowProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam)145 ParentWindowProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam) {
146   if ( msg == WM_SIZE ) {
147     printf( "Resized\n" );
148     MoveWindow( pChildHWnd, 0, 0, lparam&0xFFFF, (lparam>>16)&0xFFFF, TRUE );
149   }
150 
151   return CallWindowProc((WNDPROC)pParentWndProc,hwnd,msg,wparam,lparam);
152 }
153 #endif
154 
155 void
getcurrenttimestr(char * buf)156 getcurrenttimestr( char *buf ) {
157   struct tm *ltime;
158   time_t t;
159 
160   time(&t);
161   ltime = localtime( &t );
162 
163   strftime( buf, 32, "%H:%M:%S ", ltime );
164 }
165 
LobbyClientView()166 LobbyClientView::LobbyClientView() {
167   m_timeout = 0;
168   m_idle = 0;
169   m_chatChannel = 0;
170 }
171 
~LobbyClientView()172 LobbyClientView::~LobbyClientView() {
173   if ( m_timeout > 0 )
174     gtk_timeout_remove( m_timeout );
175   if ( m_idle > 0 )
176     gtk_idle_remove( m_idle );
177 }
178 
179 void
Init(LobbyClient * lobby)180 LobbyClientView::Init( LobbyClient *lobby ) {
181   int i;
182 
183   m_parent = lobby;
184 
185   m_timeout = gtk_timeout_add( 1000, LobbyClient::PollServerMessage,
186 			       m_parent );
187 
188   // display
189   m_window = gtk_dialog_new();
190   gtk_container_border_width (GTK_CONTAINER (m_window), 10);
191 
192 #ifdef WIN32
193   char windowName[32];
194   for ( i = 0 ; i < 31 ; i++ )
195     windowName[i] = 'A'+RAND(26);
196   windowName[31] = 0;
197 
198   gtk_window_set_title( GTK_WINDOW(m_window), windowName);
199 #else
200   gtk_window_set_title( GTK_WINDOW(m_window), _("Cannon Smash"));
201 #endif
202   gtk_widget_realize(m_window);
203   gtk_window_set_modal( (GtkWindow *)m_window, true );
204   gtk_widget_set_usize( m_window, 600, 400 );
205 
206   GtkWidget *scrolled_window;
207   GtkWidget *button;
208 
209   scrolled_window = gtk_scrolled_window_new( NULL, NULL );
210   gtk_container_border_width (GTK_CONTAINER (scrolled_window), 10);
211   gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW(scrolled_window),
212 				  GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS );
213   gtk_box_pack_start( GTK_BOX(GTK_DIALOG(m_window)->vbox), scrolled_window,
214 		      TRUE, TRUE, 0 );
215 
216   GtkTreeViewColumn *column;
217   GtkCellRenderer *renderer;
218   GtkListStore *store;
219 
220   store = gtk_list_store_new( 2, G_TYPE_STRING, G_TYPE_STRING );
221   m_table = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
222 
223   renderer = gtk_cell_renderer_text_new();
224   column = gtk_tree_view_column_new_with_attributes( _("Nickname"), renderer,
225 						     "markup", 0,
226 						     NULL );
227   gtk_tree_view_column_set_resizable( column, TRUE );
228   gtk_tree_view_append_column( GTK_TREE_VIEW(m_table), column );
229 
230   renderer = gtk_cell_renderer_text_new();
231   column = gtk_tree_view_column_new_with_attributes( _("Message"), renderer,
232 						     "markup", 1,
233 						     NULL );
234   gtk_tree_view_column_set_resizable( column, TRUE );
235   gtk_tree_view_append_column( GTK_TREE_VIEW(m_table), column );
236 
237   gtk_scrolled_window_add_with_viewport ( GTK_SCROLLED_WINDOW(scrolled_window),
238 					  m_table );
239   GtkTreeSelection *select =
240     gtk_tree_view_get_selection(GTK_TREE_VIEW(m_table));
241 
242   gtk_tree_selection_set_mode( select, GTK_SELECTION_SINGLE );
243 
244   gtk_tree_selection_set_select_function( select,
245 					  LobbyClientView::checkSelection,
246 					  this,
247 					  NULL);
248 
249   GtkWidget *notebook = gtk_notebook_new();
250   GtkWidget *label;
251   i = 0;
252 
253   m_langID[i] = table[m_parent->GetLang()].langID;
254   if ( m_langID[i] != 0x09 ) {
255     scrolled_window = gtk_scrolled_window_new (NULL, NULL);
256     m_chat[i] = gtk_text_view_new();
257     gtk_text_view_set_editable( GTK_TEXT_VIEW(m_chat[i]), FALSE );
258 
259     gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window),
260 				   GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
261     gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrolled_window),
262 					  m_chat[i] );
263 
264     label = gtk_label_new( _(table[m_parent->GetLang()].langname) );
265     gtk_notebook_append_page(GTK_NOTEBOOK(notebook), scrolled_window, label);
266     i++;
267   }
268 
269   m_langID[i] = 0x09;	// English
270   scrolled_window = gtk_scrolled_window_new (NULL, NULL);
271   m_chat[i] = gtk_text_view_new();
272   gtk_text_view_set_editable( GTK_TEXT_VIEW(m_chat[i]), FALSE );
273 
274   gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW (scrolled_window),
275 				  GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS );
276   gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW(scrolled_window),
277 					 m_chat[i] );
278 
279   label = gtk_label_new( _("English") );
280 
281   gtk_notebook_append_page( GTK_NOTEBOOK(notebook), scrolled_window, label);
282 
283   gtk_box_pack_start( GTK_BOX(GTK_DIALOG(m_window)->vbox), notebook,
284 		      TRUE, TRUE, 0 );
285   gtk_signal_connect (GTK_OBJECT (notebook), "switch-page",
286 		      GTK_SIGNAL_FUNC (LobbyClientView::SwitchChatPage), this);
287 
288   m_chatinput = gtk_entry_new();
289 
290   gtk_box_pack_start( GTK_BOX(GTK_DIALOG(m_window)->vbox), m_chatinput,
291 		      TRUE, TRUE, 10 );
292   gtk_signal_connect (GTK_OBJECT (m_chatinput), "key-press-event",
293 		      GTK_SIGNAL_FUNC (LobbyClientView::KeyPress), this);
294 
295 #ifdef WIN32
296   gtk_widget_show_all(m_window);
297   gtk_widget_show(m_chatinput);
298 
299   HWND hWnd = FindWindow( "gdkWindowTopLevel", windowName );
300   gtk_window_set_title( GTK_WINDOW(m_window), _("Cannon Smash"));
301 
302   HWND cWnd = NULL;
303   cWnd = FindWindowEx( hWnd, NULL, "gdkWindowChild", NULL );
304   cWnd = FindWindowEx( cWnd, NULL, "gdkWindowChild", NULL );
305 
306   pParentWndProc = GetWindowLong(cWnd, GWL_WNDPROC);
307   SetWindowLong(cWnd, GWL_WNDPROC, (LONG)ParentWindowProc);
308 
309   pChildHWnd = CreateWindow( "EDIT", NULL, WS_CHILD|WS_VISIBLE,
310 			     CW_USEDEFAULT, CW_USEDEFAULT,
311 			     200, 30,
312 			     cWnd, NULL, NULL, NULL );
313 
314   pEditWndProc = GetWindowLong(pChildHWnd, GWL_WNDPROC);
315   SetWindowLong(pChildHWnd, GWL_WNDPROC, (LONG)LobbyClientView::EditWindowProc);
316   theLobbyClientView = this;
317 #endif
318 
319   m_connectButton = gtk_button_new_with_label (_("connect"));
320   gtk_signal_connect (GTK_OBJECT (m_connectButton), "clicked",
321 		      GTK_SIGNAL_FUNC (LobbyClient::Connect), m_parent);
322   gtk_widget_set_sensitive (m_connectButton, false);
323   gtk_box_pack_start (GTK_BOX (GTK_DIALOG (m_window)->action_area),
324 		      m_connectButton, TRUE, TRUE, 0);
325 
326   m_warmUpButton = gtk_button_new_with_label (_("warm up"));
327   gtk_signal_connect (GTK_OBJECT (m_warmUpButton), "clicked",
328 		      GTK_SIGNAL_FUNC (LobbyClientView::WarmUp), this);
329   gtk_box_pack_start (GTK_BOX (GTK_DIALOG (m_window)->action_area),
330 		      m_warmUpButton, TRUE, TRUE, 0);
331 
332   button = gtk_button_new_with_label (_("close"));
333   gtk_signal_connect (GTK_OBJECT (button), "clicked",
334 		      GTK_SIGNAL_FUNC (LobbyClientView::Quit), this);
335 
336   GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
337   gtk_box_pack_start (GTK_BOX (GTK_DIALOG (m_window)->action_area),
338 		      button, TRUE, TRUE, 0);
339 
340   gtk_widget_grab_default (button);
341 
342   gtk_widget_show_all(m_window);
343 }
344 
345 void
UpdateTable()346 LobbyClientView::UpdateTable() {
347   GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(m_table));
348 
349   gtk_list_store_clear( GTK_LIST_STORE(model) );
350   gtk_widget_set_sensitive(m_connectButton, false);
351 
352   std::string nickname, message;
353   bool selected = false;
354   for ( int i = 0 ; i < m_parent->m_playerNum ; i++ ) {
355     GtkTreeIter iter;
356     gtk_list_store_append( GTK_LIST_STORE(model), &iter );
357     if ( m_parent->m_player[i].m_playing ||
358 	 (m_parent->GetCanBeServer() == false &&
359 	  m_parent->m_player[i].m_canBeServer == false) ) {
360       nickname = "<span color=\"gray\">";
361       nickname += m_parent->m_player[i].m_nickname;
362       nickname += "</span>";
363       message = "<span color=\"gray\">";
364       message += m_parent->m_player[i].m_message;
365       message += "</span>";
366     } else {
367       nickname = "<span color=\"black\">";
368       nickname += m_parent->m_player[i].m_nickname;
369       nickname += "</span>";
370       message = "<span color=\"black\">";
371       message += m_parent->m_player[i].m_message;
372       message += "</span>";
373     }
374     gtk_list_store_set( GTK_LIST_STORE(model), &iter,
375 			0, nickname.c_str(),
376 			1, message.c_str(),
377 			-1 );
378     if ( m_parent->m_player[i].m_ID == m_parent->m_selected ) {
379       GtkTreeSelection *selection =
380 	gtk_tree_view_get_selection(GTK_TREE_VIEW(m_table));
381       gtk_tree_selection_select_iter( selection, &iter );
382       selected = true;
383     }
384   }
385 
386   if ( selected == false )
387     m_parent->m_selected = -1;
388 }
389 
390 gboolean
checkSelection(GtkTreeSelection * selection,GtkTreeModel * model,GtkTreePath * path,gboolean path_currently_selected,gpointer data)391 LobbyClientView::checkSelection( GtkTreeSelection *selection,
392 				 GtkTreeModel *model,
393 				 GtkTreePath *path,
394 				 gboolean path_currently_selected,
395 				 gpointer data ) {
396   LobbyClientView *lobby = (LobbyClientView *)data;
397 
398   gchar* pathstr = gtk_tree_path_to_string(path);
399   int selected = atoi( pathstr );
400   g_free(pathstr);
401 
402   PlayerInfo selectedPlayer = lobby->m_parent->m_player[selected];
403   if ( selectedPlayer.m_playing ||
404        (lobby->m_parent->GetCanBeServer() == false &&
405 	selectedPlayer.m_canBeServer == false) ) {
406     return FALSE;
407   } else {
408     lobby->m_parent->m_selected = selectedPlayer.m_ID;
409     gtk_widget_set_sensitive(lobby->m_connectButton, true);
410     return TRUE;
411   }
412 }
413 
414 void
WarmUp(GtkWidget * widget,gpointer data)415 LobbyClientView::WarmUp( GtkWidget *widget, gpointer data ) {
416   LobbyClientView *lobby = (LobbyClientView *)data;
417 
418   isWaiting = true;
419   ::InitGame();
420 
421   lobby->m_idle = gtk_idle_add( LobbyClientView::IdleFunc, data );
422 }
423 
424 gboolean
KeyPress(GtkWidget * widget,GdkEventKey * event,gpointer data)425 LobbyClientView::KeyPress( GtkWidget *widget,
426 			   GdkEventKey *event,
427 			   gpointer data) {
428   LobbyClientView *lobby = (LobbyClientView *)data;
429 
430   if ( event->keyval == GDK_Return &&
431        strlen(gtk_entry_get_text(GTK_ENTRY(lobby->m_chatinput))) > 0 ) {
432     lobby->m_parent->SendMS( (char *)gtk_entry_get_text(GTK_ENTRY(lobby->m_chatinput)),
433 			     lobby->m_langID[lobby->m_chatChannel] );
434 
435     char buf[32];
436     getcurrenttimestr(buf);
437 
438     GtkTextBuffer *buffer;
439     buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(lobby->m_chat[lobby->m_chatChannel]));
440 
441     GtkTextIter iter;
442     gtk_text_buffer_get_end_iter( buffer, &iter );
443     gtk_text_buffer_insert( buffer, &iter, buf, -1 );
444     gtk_text_buffer_insert( buffer, &iter, ">", -1 );
445     gtk_text_buffer_insert( buffer, &iter, lobby->m_parent->m_nickname, -1 );
446     gtk_text_buffer_insert( buffer, &iter, "< ", -1 );
447     gtk_text_buffer_insert( buffer, &iter,
448 			    gtk_entry_get_text(GTK_ENTRY(lobby->m_chatinput)),
449 			    -1 );
450     gtk_text_buffer_insert( buffer, &iter, "\n", -1 );
451 
452     GtkWidget* scrolled_window;
453     scrolled_window = gtk_widget_get_parent(lobby->m_chat[lobby->m_chatChannel]);
454     scrolled_window = gtk_widget_get_parent(scrolled_window);
455 
456     GtkAdjustment *adj =
457       gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(scrolled_window));
458     gtk_adjustment_set_value(adj, adj->upper-adj->page_size);
459 
460     gtk_entry_set_text(GTK_ENTRY(lobby->m_chatinput), "");
461   }
462 
463   return FALSE;
464 }
465 
466 void
SwitchChatPage(GtkNotebook * notebook,GtkNotebookPage * page,gint page_num,gpointer data)467 LobbyClientView::SwitchChatPage( GtkNotebook *notebook,
468 				 GtkNotebookPage *page,
469 				 gint page_num,
470 				 gpointer data ) {
471   LobbyClientView *lobby = (LobbyClientView *)data;
472 
473   lobby->m_chatChannel = page_num;
474 }
475 
476 
477 gint
IdleFunc(gpointer data)478 LobbyClientView::IdleFunc( gpointer data ) {
479   if ( !PollEvent() ) {
480     ::EndGame();
481     return 0;
482   }
483 
484   return 1;
485 }
486 
487 void
Quit(GtkWidget * widget,gpointer data)488 LobbyClientView::Quit( GtkWidget *widget, gpointer data ) {
489   LobbyClientView *lobby = (LobbyClientView *)data;
490 
491   lobby->m_parent->SendQT();
492 
493   gtk_widget_destroy( lobby->m_window );
494   gtk_timeout_remove( lobby->m_timeout );
495 
496   delete lobby->m_parent;
497 }
498 
499 void
SetSensitive(bool sensitive)500 LobbyClientView::SetSensitive( bool sensitive ) {
501   gtk_widget_set_sensitive (m_connectButton, sensitive);
502   gtk_widget_set_sensitive (m_warmUpButton, sensitive);
503   gtk_widget_set_sensitive (m_table, sensitive);
504 }
505 
506 void
ShowUpdateDialog(char * version,char * URL)507 LobbyClientView::ShowUpdateDialog( char *version, char *URL ) {
508   GtkWidget *dialog = gtk_dialog_new();
509 
510   char buf[256];
511   sprintf( buf, _("Latest Version %s is already released. \nPlease download the latest version from \n%s\n"), version, URL );
512 
513   GtkWidget *label = gtk_label_new( buf );
514   GtkWidget *button = gtk_button_new_with_label( "OK" );
515 
516   gtk_window_set_modal( (GtkWindow *)dialog, true );
517 
518   gtk_label_set_line_wrap( GTK_LABEL(label), true );
519 
520   gtk_box_pack_start( GTK_BOX(GTK_DIALOG(dialog)->vbox),
521 		      label, TRUE, TRUE, 0 );
522 
523   gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->action_area),
524 		      button, TRUE, TRUE, 0);
525   gtk_signal_connect (GTK_OBJECT (button), "clicked",
526 		      GTK_SIGNAL_FUNC(LobbyClientView::Quit), this);
527   gtk_signal_connect_object(GTK_OBJECT(button), "clicked",
528 			    GTK_SIGNAL_FUNC(gtk_widget_destroy),
529 			    GTK_OBJECT(dialog));
530 
531   gtk_widget_show_all(dialog);
532 }
533 
534 void
AddChatMessage(long channelID,char * message)535 LobbyClientView::AddChatMessage( long channelID, char *message ) {
536   char buf[32];
537   getcurrenttimestr( buf );
538 
539   GtkTextBuffer *buffer;
540   int i;
541 
542   for ( i = 0 ; i < 2 ; i++ ) {
543     if ( m_langID[i] == channelID )
544       break;
545   }
546 
547   if ( i == 2 )
548     return;
549 
550   buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(m_chat[i]));
551 
552   GtkTextIter iter;
553   gtk_text_buffer_get_end_iter( buffer, &iter );
554   gtk_text_buffer_insert( buffer, &iter, buf, -1 );
555   gtk_text_buffer_insert( buffer, &iter, message, -1 );
556   gtk_text_buffer_insert( buffer, &iter, "\n", -1 );
557 
558   GtkWidget* scrolled_window;
559   scrolled_window = gtk_widget_get_parent(m_chat[i]);
560   scrolled_window = gtk_widget_get_parent(scrolled_window);
561 
562   GtkAdjustment *adj =
563     gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(scrolled_window));
564   gtk_adjustment_set_value(adj, adj->upper-adj->page_size);
565 }
566 
PIDialog()567 PIDialog::PIDialog() {
568 }
569 
PIDialog(LobbyClient * parent)570 PIDialog::PIDialog( LobbyClient *parent ) {
571   m_parent = parent;
572 }
573 
~PIDialog()574 PIDialog::~PIDialog() {
575 }
576 
577 void
PopupDialog(long uniqID)578 PIDialog::PopupDialog( long uniqID ) {
579   GtkWidget *label, *button;
580   char buf[256];
581 
582   if ( isWaiting ) {
583     QuitGame();
584   }
585 
586   m_uniqID = uniqID;
587 
588   m_window = gtk_dialog_new();
589   gtk_window_set_title( GTK_WINDOW(m_window), _("Cannon Smash"));
590   gtk_container_border_width (GTK_CONTAINER (m_window), 10);
591   gtk_window_set_modal( (GtkWindow *)m_window, true );
592 
593   PlayerInfo *p = m_parent->GetPlayerInfo();
594 
595   int i;
596   for ( i = 0 ; i < m_parent->GetPlayerNum() ; i++ ) {
597     if ( p[i].m_ID == m_uniqID ) {
598       sprintf( buf, _("\"%s\" (message: %s)want to play with you. OK?\n"),
599 	       p[i].m_nickname, p[i].m_message );
600       break;
601     }
602   }
603 
604   label = gtk_label_new( buf );
605   gtk_label_set_line_wrap( GTK_LABEL(label), true );
606 
607   gtk_box_pack_start( GTK_BOX(GTK_DIALOG(m_window)->vbox), label,
608 		      TRUE, TRUE, 0 );
609 
610   button = gtk_button_new_with_label (_("OK!"));
611   gtk_signal_connect (GTK_OBJECT (button), "clicked",
612 		      GTK_SIGNAL_FUNC (PIDialog::PIOK), this);
613 
614   GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
615   gtk_box_pack_start (GTK_BOX (GTK_DIALOG (m_window)->action_area),
616 		      button, TRUE, TRUE, 0);
617 
618   gtk_widget_grab_default (button);
619 
620   button = gtk_button_new_with_label (_("No!"));
621   gtk_signal_connect (GTK_OBJECT (button), "clicked",
622 		      GTK_SIGNAL_FUNC (PIDialog::PINo), this);
623 
624   gtk_box_pack_start (GTK_BOX (GTK_DIALOG (m_window)->action_area),
625 		      button, TRUE, TRUE, 0);
626 
627   gtk_widget_show_all(m_window);
628 }
629 
630 void
PIOK(GtkWidget * widget,gpointer data)631 PIDialog::PIOK( GtkWidget *widget, gpointer data ) {
632   PIDialog *piDialog = (PIDialog *)data;
633   gtk_widget_destroy( GTK_WIDGET(piDialog->m_window) );
634 
635   isComm = true;
636   mode = MODE_MULTIPLAYSELECT;
637 
638   piDialog->m_parent->SendAP( piDialog->m_uniqID );
639   piDialog->m_parent->SendSP();
640 
641   // If oppenent cannot be a server, I become server.
642   for ( int i = 0 ; i < piDialog->m_parent->m_playerNum ; i++ ) {
643     if ( piDialog->m_parent->m_player[i].m_ID == piDialog->m_uniqID ) {
644       if ( piDialog->m_parent->m_player[i].m_canBeServer == false ) {	// Opponent cannot be server
645 	theRC->serverName[0] = '\0';
646       }
647       break;
648     }
649   }
650 
651   ::StartGame();
652 
653   piDialog->m_parent->SendQP();
654 }
655 
656 void
PINo(GtkWidget * widget,gpointer data)657 PIDialog::PINo( GtkWidget *widget, gpointer data ) {
658   PIDialog *piDialog = (PIDialog *)data;
659   gtk_widget_destroy( GTK_WIDGET(piDialog->m_window) );
660 
661   piDialog->m_parent->SendDP( piDialog->m_uniqID );
662 }
663 
664