OSDN Git Service

[BUILD] Set SOVERSION and GIT hash automatically.
[csp-qt/common_source_project-fm7.git] / source / src / qt / osd_wrapper.cpp
1 /*
2         Skelton for retropc emulator
3
4         Author : K.Ohta <whatisthis.sowhat _at_ gmail.com>
5         Date   : 2015.11.30-
6
7         [ VM/OSD Wrapper ]
8 */
9
10 #include <string>
11
12 #include <QObject>
13 #include <QWidget>
14
15 #include <QMutex>
16 #include <QSemaphore>
17 #include <QPainter>
18 #include <QElapsedTimer>
19 #include <QQueue>
20
21 #include <QDateTime>
22 #include <QDate>
23 #include <QTime>
24 #include <QString>
25 #include <QObject>
26 #include <QThread>
27 #include <QMutex>
28
29 #include <QImage>
30 #include <QPainter>
31 #include <QColor>
32 #include <QPen>
33 #include <QPoint>
34 #include <QTextCodec>
35
36 #include "osd.h"
37 #include "../vm/vm.h"
38 #include "../vm/device.h"
39 #include "../common.h"
40
41 #include "emu.h"
42
43 #include "emu_thread.h"
44 #include "draw_thread.h"
45 #if defined(USE_MOVIE_PLAYER) || defined(USE_VIDEO_CAPTURE)
46 #include "avio/movie_loader.h"
47 #endif
48 #if defined(USE_SOUND_FILES)
49 #include "avio/sound_loader.h"
50 #endif
51 #include "qt_gldraw.h"
52 #include "csp_logger.h"
53
54 const _TCHAR *OSD::get_lib_common_vm_version()
55 {
56         if(vm->first_device != NULL) {
57                 return vm->first_device->get_lib_common_vm_version();
58         } else {
59                 return (const _TCHAR *)"\0";
60         }
61 }
62
63 const _TCHAR *OSD::get_lib_common_vm_git_version()
64 {
65         return vm->get_vm_git_version();
66 }
67
68 const _TCHAR *OSD::get_lib_osd_version()
69 {
70         const _TCHAR *p = (const _TCHAR *)"\0";
71 #if defined(__LIBOSD_VERSION)
72         p = (const _TCHAR *)__LIBOSD_VERSION;
73 #endif
74         return p;         
75 }
76
77
78 void OSD::vm_draw_screen(void)
79 {
80         vm->draw_screen();
81 }
82
83 double OSD::vm_frame_rate(void)
84 {
85 #ifdef SUPPORT_VARIABLE_TIMING
86         return vm->get_frame_rate();
87 #else
88         return FRAMES_PER_SEC;
89 #endif   
90 }
91
92 Sint16* OSD::create_sound(int *extra_frames)
93 {
94         return (Sint16 *)vm->create_sound(extra_frames);
95 }
96
97 #ifdef USE_SOUND_FILES
98 void OSD::load_sound_file(int id, const _TCHAR *name, int16_t **data, int *dst_size)
99 {
100         int i = 0;
101         if(data != NULL) *data = NULL;
102         if(dst_size != NULL) *dst_size = 0;
103         if(id <= 0) return;
104
105         for(i = 0; i < USE_SOUND_FILES; i++) {
106                 SOUND_LOADER *p = sound_file_obj[i];
107                 if(p != NULL) {
108                         if(p->get_id() == id) break;
109                 }
110         }
111         
112         if(i >= USE_SOUND_FILES) {
113                 for(i = 0; i < USE_SOUND_FILES; i++) {
114                         SOUND_LOADER *p = sound_file_obj[i];
115                         if(p != NULL) {
116                                 if(p->get_id() < 0) {
117                                         p->set_id(id);
118                                         break;
119                                 }
120                         }
121                 }
122         }
123         if(i >= USE_SOUND_FILES) return;
124         SOUND_LOADER *p = sound_file_obj[i];
125         if(p != NULL) {
126                 p->free_sound_buffer(NULL);
127                 p->set_sound_rate(this->get_sound_rate());
128                 if(p->open(id, QString::fromUtf8(name))) {
129                         p->do_decode_frames();
130                         p->close();
131                         if(data != NULL) *data = (int16_t *)(p->get_sound_buffer());
132                         if(dst_size != NULL) *dst_size = p->get_dst_size();
133                 }
134         }
135 }
136
137 void OSD::free_sound_file(int id, int16_t **data)
138 {
139         if(data == NULL) return;
140         for(int i = 0; i < USE_SOUND_FILES; i++) {
141                 SOUND_LOADER *p = sound_file_obj[i];
142                 if(p != NULL) {
143                         if(p->get_id() == id) {
144                                 p->free_sound_buffer(*data);
145                                 *data = NULL;
146                                 break;
147                         }
148                 }
149         }
150 }
151
152 void OSD::init_sound_files()
153 {
154         for(int i = 0; i < USE_SOUND_FILES; i++) {
155                 sound_file_obj[i] = NULL;
156                 SOUND_LOADER *p = new SOUND_LOADER((void *)tail_sound_file, p_logger);
157                 if(p != NULL) {
158                         sound_file_obj[i] = p;
159                 }
160                 tail_sound_file = p;
161         }
162 }
163
164 void OSD::release_sound_files()
165 {
166         for(int i = 0; i < USE_SOUND_FILES; i++) {
167                 SOUND_LOADER *p = sound_file_obj[i];
168                 if(p != NULL) delete p;
169                 sound_file_obj[i] = NULL;
170         }
171 }
172 #endif
173 bool OSD::get_use_socket(void)
174 {
175 #ifdef USE_SOCKET
176         return true;
177 #else
178         return false;
179 #endif
180 }
181
182 bool OSD::get_support_variable_timing(void)
183 {
184 #ifdef SUPPORT_VARIABLE_TIMING
185         return true;
186 #else
187         return false;
188 #endif
189 }
190
191 bool OSD::get_notify_key_down(void)
192 {
193 #ifdef NOTIFY_KEY_DOWN
194         return true;
195 #else
196         return false;
197 #endif  
198 }
199
200 bool OSD::get_notify_key_down_lr_shift(void)
201 {
202 #ifdef NOTIFY_KEY_DOWN_LR_SHIFT
203         return true;
204 #else
205         return false;
206 #endif
207 }
208
209 bool OSD::get_notify_key_down_lr_control(void)
210 {
211 #ifdef NOTIFY_KEY_DOWN_LR_CONTROL
212         return true;
213 #else
214         return false;
215 #endif
216 }
217
218 bool OSD::get_notify_key_down_lr_menu(void)
219 {
220 #ifdef NOTIFY_KEY_DOWN_LR_MEHU
221         return true;
222 #else
223         return false;
224 #endif
225 }
226
227 bool OSD::get_use_shift_numpad_key(void)
228 {
229 #ifdef USE_SHIFT_NUMPAD_KEY
230         return true;
231 #else
232         return false;
233 #endif
234 }
235
236 bool OSD::get_use_auto_key(void)
237 {
238 #ifdef USE_AUTO_KEY
239         return true;
240 #else
241         return false;
242 #endif
243 }
244
245 bool OSD::get_dont_keeep_key_pressed(void)
246 {
247 #ifdef DONT_KEEEP_KEY_PRESSED
248         return true;
249 #else
250         return false;
251 #endif
252 }
253
254 bool OSD::get_one_board_micro_computer(void)
255 {
256 #ifdef ONE_BOARD_MICRO_COMPUTER
257         return true;
258 #else
259         return false;
260 #endif
261 }
262
263 bool OSD::get_use_screen_rotate(void)
264 {
265 #ifdef USE_SCREEN_ROTATE
266         return true;
267 #else
268         return false;
269 #endif
270 }
271
272 bool OSD::get_use_movie_player(void)
273 {
274 #ifdef USE_MOVIE_PLAYER
275         return true;
276 #else
277         return false;
278 #endif
279 }
280
281 bool OSD::get_use_video_capture(void)
282 {
283 #ifdef USE_VIDEO_CAPTURE
284         return true;
285 #else
286         return false;
287 #endif
288 }
289
290 void OSD::vm_key_down(int code, bool flag)
291 {
292 #ifdef NOTIFY_KEY_DOWN
293         vm->key_down(code, flag);
294 #endif
295 }
296
297 void OSD::vm_key_up(int code)
298 {
299 #ifdef NOTIFY_KEY_DOWN
300         vm->key_up(code);
301 #endif
302 }
303
304 void OSD::vm_reset(void)
305 {
306         vm->reset();
307 }
308
309 int OSD::get_vm_buttons_code(int num)
310 {
311 #ifdef ONE_BOARD_MICRO_COMPUTER
312         if(num < 0) return 0;
313         return vm_buttons[num].code;
314 #else
315         return 0;
316 #endif
317 }       
318
319 void OSD::update_buttons(bool press_flag, bool release_flag)
320 {
321 #if defined(MAX_BUTTONS)
322         if(!press_flag && !release_flag) {
323                 int ii;
324                 ii = 0;
325                 for(ii = 0; vm_buttons[ii].code != 0x00; ii++) { 
326                         if((mouse_ptrx >= vm_buttons[ii].x) && (mouse_ptrx < (vm_buttons[ii].x + vm_buttons[ii].width))) {
327                                 if((mouse_ptry >= vm_buttons[ii].y) && (mouse_ptry < (vm_buttons[ii].y + vm_buttons[ii].height))) {
328                                         if((key_status[vm_buttons[ii].code] & 0x7f) == 0) this->press_button(ii);
329                                 }
330                         }
331                 }
332                 if((mouse_ptrx >= vm_buttons[ii].x) && (mouse_ptrx < (vm_buttons[ii].x + vm_buttons[ii].width))) {
333                         if((mouse_ptry >= vm_buttons[ii].y) && (mouse_ptry < (vm_buttons[ii].y + vm_buttons[ii].height))) {
334                                 this->press_button(ii);
335                         }
336                 }
337                 mouse_ptrx = mouse_ptry = 0;
338         }
339         //return;
340 #endif                  
341 }       
342
343 QString OSD::get_vm_config_name(void)
344 {
345 #if defined(CONFIG_NAME)
346         return QString::fromUtf8(CONFIG_NAME);
347 #else
348         return QString::fromUtf8(" ");
349 #endif
350 }
351
352 int OSD::get_screen_width(void)
353 {
354         return SCREEN_WIDTH;
355 }
356
357 int OSD::get_screen_height(void)
358 {
359         return SCREEN_HEIGHT;
360 }
361
362 void OSD::lock_vm(void)
363 {
364         locked_vm = true;
365         vm_mutex->lock();
366         //if(parent_thread != NULL) { 
367                 //if(!parent_thread->now_debugging()) VMSemaphore->acquire(1);
368                 //VMSemaphore->acquire(1);
369         //} else {
370         //      VMSemaphore->acquire(1);
371         //}
372 }
373
374 void OSD::unlock_vm(void)
375 {
376         vm_mutex->unlock();
377         //if(parent_thread != NULL) { 
378         //      //if(!parent_thread->now_debugging()) VMSemaphore->release(1);
379         //      VMSemaphore->release(1);
380         //} else {
381         //      VMSemaphore->release(1);
382         //}
383         locked_vm = false;
384 }
385
386
387 bool OSD::is_vm_locked(void)
388 {
389         return locked_vm;
390 }
391
392 void OSD::force_unlock_vm(void)
393 {
394         vm_mutex->unlock();
395         locked_vm = false;
396 }
397
398 void OSD::set_draw_thread(DrawThreadClass *handler)
399 {
400         //this->moveToThread(handler);
401         connect(this, SIGNAL(sig_update_screen(bitmap_t *)), handler, SLOT(do_update_screen(bitmap_t *)));
402         connect(this, SIGNAL(sig_save_screen(const char *)), glv, SLOT(do_save_frame_screen(const char *)));
403         connect(this, SIGNAL(sig_resize_vm_screen(QImage *, int, int)), glv, SLOT(do_set_texture_size(QImage *, int, int)));
404         connect(this, SIGNAL(sig_resize_vm_lines(int)), glv, SLOT(do_set_horiz_lines(int)));
405         connect(parent_thread, SIGNAL(sig_debugger_input(QString)), this, SLOT(do_set_input_string(QString)));
406         connect(parent_thread, SIGNAL(sig_quit_debugger()), this, SLOT(do_close_debugger_thread()));
407         connect(this, SIGNAL(sig_move_mouse_to_center()), glv, SLOT(do_move_mouse_to_center()));
408         connect(this, SIGNAL(sig_close_window()), parent_thread, SLOT(doExit()));
409 }
410
411 void OSD::initialize_screen()
412 {
413         host_window_width = base_window_width = WINDOW_WIDTH;
414         host_window_height = base_window_height = WINDOW_HEIGHT;
415         host_window_mode = true;
416         
417         vm_screen_width = SCREEN_WIDTH;
418         vm_screen_height = SCREEN_HEIGHT;
419         vm_window_width = WINDOW_WIDTH;
420         vm_window_height = WINDOW_HEIGHT;
421         vm_window_width_aspect = WINDOW_WIDTH_ASPECT;
422         vm_window_height_aspect = WINDOW_HEIGHT_ASPECT;
423         
424         QColor col(0, 0, 0, 255);
425
426         vm_screen_buffer.width = SCREEN_WIDTH;
427         vm_screen_buffer.height = SCREEN_HEIGHT;
428         vm_screen_buffer.pImage = QImage(SCREEN_WIDTH, SCREEN_HEIGHT, QImage::Format_ARGB32);
429         vm_screen_buffer.pImage.fill(col);
430         now_record_video = false;
431         
432         first_draw_screen = false;
433         first_invalidate = true;
434         self_invalidate = false;
435 }
436
437 void OSD::release_screen()
438 {
439         stop_record_video();
440         release_screen_buffer(&vm_screen_buffer);
441 }
442
443 int OSD::get_window_mode_width(int mode)
444 {
445         if(get_use_screen_rotate()) {
446                 if(p_config->rotate_type == 1 || p_config->rotate_type == 3) {
447                         return (p_config->window_stretch_type == 0 ? vm_window_height : vm_window_height_aspect) * (mode + WINDOW_MODE_BASE);
448                 }
449         }
450         return (p_config->window_stretch_type == 0 ? vm_window_width : vm_window_width_aspect) * (mode + WINDOW_MODE_BASE);
451 }
452
453 int OSD::get_window_mode_height(int mode)
454 {
455         if(get_use_screen_rotate()) {
456                 if(p_config->rotate_type == 1 || p_config->rotate_type == 3) {
457                         return (p_config->window_stretch_type == 0 ? vm_window_width : vm_window_width_aspect) * (mode + WINDOW_MODE_BASE);
458                 }
459         }
460         return (p_config->window_stretch_type == 0 ? vm_window_height : vm_window_height_aspect) * (mode + WINDOW_MODE_BASE);
461 }
462
463 void OSD::initialize_video()
464 {
465         movie_loader = NULL;
466 #if defined(USE_MOVIE_PLAYER) || defined(USE_VIDEO_CAPTURE)
467         movie_loader = new MOVIE_LOADER(this, &config);
468         //connect(movie_loader, SIGNAL(sig_send_audio_frame(uint8_t *, long)), this, SLOT(do_run_movie_audio_callback2(uint8_t *, long)));
469         connect(movie_loader, SIGNAL(sig_movie_end(bool)), this, SLOT(do_video_movie_end(bool)));
470         connect(this, SIGNAL(sig_movie_play(void)), movie_loader, SLOT(do_play()));
471         connect(this, SIGNAL(sig_movie_stop(void)), movie_loader, SLOT(do_stop()));
472         connect(this, SIGNAL(sig_movie_pause(bool)), movie_loader, SLOT(do_pause(bool)));
473         connect(this, SIGNAL(sig_movie_seek_frame(bool, int)), movie_loader, SLOT(do_seek_frame(bool, int)));
474         //connect(this, SIGNAL(sig_movie_mute(bool, bool)), movie_loader, SLOT(do_mute(bool, bool)));
475         connect(movie_loader, SIGNAL(sig_decoding_error(int)), this, SLOT(do_video_decoding_error(int)));
476 #endif  
477 }
478
479 void OSD::release_video()
480 {
481 #if defined(USE_MOVIE_PLAYER) || defined(USE_VIDEO_CAPTURE)
482         delete movie_loader;
483 #endif  
484         movie_loader = NULL;
485 }
486
487
488 bool OSD::open_movie_file(const _TCHAR* file_path)
489 {
490         bool ret = false;
491         if(file_path == NULL) return ret;
492 #if defined(USE_MOVIE_PLAYER) || defined(USE_VIDEO_CAPTURE)
493         if(movie_loader != NULL) {
494                 ret = movie_loader->open(QString::fromUtf8(file_path));
495         }
496 #endif  
497         return ret;
498 }
499
500 void OSD::close_movie_file()
501 {
502 #if defined(USE_MOVIE_PLAYER) || defined(USE_VIDEO_CAPTURE)
503         if(movie_loader != NULL) {
504                 movie_loader->close();
505         }
506 #endif
507         now_movie_play = false;
508         now_movie_pause = false;
509 }
510
511 #include <limits.h>
512 uint32_t OSD::get_cur_movie_frame()
513 {
514 #if defined(USE_MOVIE_PLAYER) || defined(USE_VIDEO_CAPTURE)
515         if(movie_loader != NULL) {
516                 uint64_t pos;
517                 pos = movie_loader->get_current_frame();
518                 if(pos > UINT_MAX) {
519                         return UINT_MAX;
520                 }
521                 return (uint32_t)pos;
522         }
523 #endif  
524         return 0;
525 }
526
527 void OSD::do_run_movie_audio_callback(uint8_t *data, long len)
528 {
529         if(data == NULL) return;
530 #if defined(USE_MOVIE_PLAYER) || defined(USE_VIDEO_CAPTURE)
531 #if defined(_PX7)
532         {
533                 lock_vm();
534                 this->vm->movie_sound_callback(data, len);
535                 unlock_vm();
536         }
537 #endif
538 #endif
539         free(data);
540 }
541
542 void OSD::do_decode_movie(int frames)
543 {
544 #if defined(USE_MOVIE_PLAYER) || defined(USE_VIDEO_CAPTURE)
545         //movie_loader->do_decode_frames(frames, SCREEN_WIDTH, SCREEN_HEIGHT);
546         movie_loader->do_decode_frames(frames, vm_window_width_aspect, vm_window_height_aspect);
547 #endif  
548 }
549
550 void OSD::get_video_buffer()
551 {
552 #if defined(USE_MOVIE_PLAYER) || defined(USE_VIDEO_CAPTURE)
553         //movie_loader->do_decode_frames(1, this->get_vm_window_width(), this->get_vm_window_height());
554         movie_loader->get_video_frame();
555         //printf("**\n");
556 #endif
557 }
558
559 int OSD::get_movie_sound_rate()
560 {
561 #if defined(USE_MOVIE_PLAYER) || defined(USE_VIDEO_CAPTURE)
562         return movie_loader->get_movie_sound_rate();
563 #endif
564         return 44100;
565 }
566
567 void OSD::reset_vm_node()
568 {
569         device_node_t sp;
570         device_node_list.clear();
571         p_logger->reset();
572         max_vm_nodes = 0;
573         for(DEVICE *p = vm->first_device; p != NULL; p = p->next_device) {
574                 sp.id = p->this_device_id;
575                 sp.name = p->this_device_name;
576                 p_logger->set_device_name(sp.id, sp.name);
577                 p_logger->debug_log(CSP_LOG_DEBUG, CSP_LOG_TYPE_GENERAL,  "Device %d :%s", sp.id, sp.name);
578                 device_node_list.append(sp);
579                 if(max_vm_nodes <= p->this_device_id) max_vm_nodes = p->this_device_id + 1;
580         }
581         for(DEVICE *p = vm->first_device; p != NULL; p = p->next_device) {
582                 emit sig_update_device_node_name(p->this_device_id, p->this_device_name);
583         }
584 }
585
586 #if defined(USE_SOCKET)
587 #include <QHostAddress>
588 #include "osd_socket.h"
589 #endif
590 // Socket
591 void OSD::initialize_socket()
592 {
593         for(int i = 0; i < SOCKET_MAX; i++) {
594                 tcp_socket[i] = NULL;
595                 udp_socket[i] = NULL;
596                 is_tcp[i] = false;
597                 socket_delay[i] = 0;
598                 host_mode[i] = false;
599         }
600 }
601
602 void OSD::release_socket()
603 {
604         // release sockets
605 #ifdef USE_SOCKET
606         for(int i = 0; i < SOCKET_MAX; i++) {
607                 if(tcp_socket[i] != NULL) {
608                         if(tcp_socket[i]->isOpen()) tcp_socket[i]->close();
609                         delete tcp_socket[i];
610                         tcp_socket[i] = NULL;
611                 }
612                 if(udp_socket[i] != NULL) {
613                         if(udp_socket[i]->isOpen()) udp_socket[i]->close();
614                         delete udp_socket[i];
615                         udp_socket[i] = NULL;
616                 }
617         }
618 #endif  
619 }
620
621
622 void OSD::notify_socket_connected(int ch)
623 {
624         do_notify_socket_connected(ch);
625 }
626
627 void OSD::do_notify_socket_connected(int ch)
628 {
629 #ifdef USE_SOCKET
630         vm->notify_socket_connected(ch);
631 #endif  
632 }
633
634
635 void OSD::notify_socket_disconnected(int ch)
636 {
637         do_notify_socket_disconnected(ch);
638 }
639
640
641 void OSD::do_notify_socket_disconnected(int ch)
642 {
643         if(!socket_delay[ch]) {
644                 socket_delay[ch] = 1;//56;
645         }
646 }
647
648 // Called per 1 frame.
649 void OSD::update_socket()
650 {
651 #ifdef USE_SOCKET
652         qint64 bytes;
653         for(int i = 0; i < SOCKET_MAX; i++) {
654                 QIODevice *p = NULL;
655                 if(is_tcp[i]) {
656                         if(tcp_socket[i] != NULL) {
657                                 if(tcp_socket[i]->isOpen()) {
658                                         p = tcp_socket[i];
659                                 }
660                         }
661                 } else {
662                         if(udp_socket[i] != NULL) {
663                                 if(udp_socket[i]->isOpen()) {
664                                         p = udp_socket[i];
665                                 }
666                         }
667                 }
668                 if(p != NULL) { 
669                         // recv
670                         bytes = p->bytesAvailable();
671                         if(bytes > 0) {
672                                 int size0, size1;
673                                 uint8_t* buf0 = vm->get_socket_recv_buffer0(i, &size0, &size1);
674                                 uint8_t* buf1 = vm->get_socket_recv_buffer1(i);
675                                 qint64 size;
676                                 
677                                 if(bytes > (qint64)(size0 + size1)) {
678                                         bytes = (qint64)(size0 + size1);
679                                 }
680                                 QByteArray src = p->read(bytes);
681
682                                 size = src.size();
683                                 uint8_t *pp = (uint8_t *)(src.constData());
684                                 if(size <= (qint64)size0) {
685                                         memcpy(buf0, pp, size);
686                                 } else {
687                                         memcpy(buf0, pp, size0);
688                                         memcpy(buf1, pp + size0, (int)size - size0);
689                                 }
690                                 vm->inc_socket_recv_buffer_ptr(i, (int)size);
691                         } else if(socket_delay[i] != 0) {
692                                 if(--socket_delay[i] == 0) {
693                                         vm->notify_socket_disconnected(i);
694                                 }
695                         }
696                 }
697         }
698 #endif  
699 }
700
701 bool OSD::initialize_socket_tcp(int ch)
702 {
703 #ifdef USE_SOCKET
704         if(udp_socket[ch] != NULL) {
705                 if(udp_socket[ch]->isOpen()) {
706                         udp_socket[ch]->close();
707                 }
708                 delete udp_socket[ch];
709                 udp_socket[ch] = NULL;
710         }
711         if(tcp_socket[ch] != NULL) {
712                 if(tcp_socket[ch]->isOpen()) tcp_socket[ch]->close();
713                 delete tcp_socket[ch];
714         }
715         is_tcp[ch] = true;
716         tcp_socket[ch] = new QTcpSocket2(ch);
717         if(tcp_socket[ch] == NULL) return false;
718         tcp_socket[ch]->setChannel(ch);
719         connect(tcp_socket[ch], SIGNAL(connected()), tcp_socket[ch], SLOT(do_connected()));
720         connect(tcp_socket[ch], SIGNAL(sig_connected(int)), this, SLOT(do_notify_socket_connected(int)));
721         connect(tcp_socket[ch], SIGNAL(disconnected()), tcp_socket[ch], SLOT(do_disconnected()));
722         connect(tcp_socket[ch], SIGNAL(sig_disconnected(int)), this, SLOT(do_notify_socket_disconnected(int)));
723 #endif  
724         return true;
725 }
726
727 bool OSD::initialize_socket_udp(int ch)
728 {
729 #ifdef USE_SOCKET
730         if(tcp_socket[ch] != NULL) {
731                 if(tcp_socket[ch]->isOpen()) {
732                         tcp_socket[ch]->close();
733                 }
734                 delete tcp_socket[ch];
735                 tcp_socket[ch] = NULL;
736         }
737         if(udp_socket[ch] != NULL) {
738                 if(udp_socket[ch]->isOpen()) udp_socket[ch]->close();
739                 delete udp_socket[ch];
740         }
741         is_tcp[ch] = false;
742         udp_socket[ch] = new QUdpSocket2(ch);
743         if(udp_socket[ch] == NULL) return false;
744         connect(udp_socket[ch], SIGNAL(connected()), udp_socket[ch], SLOT(do_connected()));
745         connect(udp_socket[ch], SIGNAL(sig_connected(int)), this, SLOT(do_notify_socket_connected(int)));
746         connect(udp_socket[ch], SIGNAL(disconnected()), udp_socket[ch], SLOT(do_disconnected()));
747         connect(udp_socket[ch], SIGNAL(sig_disconnected(int)), this, SLOT(do_notify_socket_disconnected(int)));
748 #endif  
749         return true;
750 }
751
752 bool OSD::connect_socket(int ch, uint32_t ipaddr, int port)
753 {
754 #ifdef USE_SOCKET
755         QHostAddress addr = QHostAddress((quint32)ipaddr);
756         if(is_tcp[ch]) {
757                 if(tcp_socket[ch] != NULL) {
758                         tcp_socket[ch]->connectToHost(addr, (quint16)port);
759                 } else {
760                         return false;
761                 }
762         } else {
763                 if(udp_socket[ch] != NULL) {
764                         udp_socket[ch]->connectToHost(addr, (quint16)port);
765                 } else {
766                         return false;
767                 }
768         }
769         host_mode[ch] = false;
770 #endif
771         return true;
772 }
773
774 void OSD::disconnect_socket(int ch)
775 {
776 //      soc[ch] = -1;
777 #ifdef USE_SOCKET
778         if(host_mode[ch]) {
779                 if(is_tcp[ch]) {
780                         if(tcp_socket[ch] != NULL) {
781                                 if(tcp_socket[ch]->isOpen()) tcp_socket[ch]->close();
782                         }
783                 } else {
784                         if(udp_socket[ch] != NULL) {
785                                 if(udp_socket[ch]->isOpen()) udp_socket[ch]->close();
786                         }
787                 }
788         } else {
789                 if(is_tcp[ch]) {
790                         if(tcp_socket[ch] != NULL) {
791                                 udp_socket[ch]->disconnectFromHost();
792                         }
793                 } else {
794                         if(udp_socket[ch] != NULL) {
795                                 udp_socket[ch]->disconnectFromHost();
796                         }
797                 }
798         }               
799         vm->notify_socket_disconnected(ch);
800 #endif  
801 }
802
803 bool OSD::listen_socket(int ch)
804 {
805 #ifdef USE_SOCKET
806         //QHostAddress addr = QHostAddress(QHostAddress::AnyIPv4); // OK?
807         // This unit is dummy?
808         //connect(udp_socket[ch], SIGNAL(connected()), udp_socket[ch], SLOT(do_connected()));
809         //connect(udp_socket[ch], SIGNAL(sig_connected(int)), this, SLOT(do_notify_socket_connected(int)));
810         //connect(udp_socket[ch], SIGNAL(disconnected()), udp_socket[ch], SLOT(do_disconnected()));
811         //connect(udp_socket[ch], SIGNAL(sig_disconnected(int)), this, SLOT(do_notify_socket_disconnected(int)));
812 #endif  
813         return false;
814 }
815
816 void OSD::send_socket_data_tcp(int ch)
817 {
818 #ifdef USE_SOCKET
819         if(is_tcp[ch]) {
820                 while(1) {
821                         int size;
822                         uint8_t *buf = vm->get_socket_send_buffer(ch, &size);
823                         if(size <= 0) {
824                                 return;
825                         }
826                         qint64 size2 = 0;
827                         if(tcp_socket[ch] != NULL) {
828                                 if(tcp_socket[ch]->isWritable()) {
829                                         size2 = tcp_socket[ch]->write((const char *)buf, (qint64)size);
830                                         if(size2 < 0) {
831                                                 disconnect_socket(ch);
832                                                 notify_socket_disconnected(ch);
833                                                 return;
834                                         }
835                                 }
836                         } else {
837                                 return;
838                         }
839                         vm->inc_socket_send_buffer_ptr(ch, (int)size2);
840                 }
841         }
842 #endif  
843 }
844
845 void OSD::send_socket_data_udp(int ch, uint32_t ipaddr, int port)
846 {
847 #ifdef USE_SOCKET
848         QHostAddress addr = QHostAddress((quint32)ipaddr);
849         if(!is_tcp[ch]) {
850                 while(1) {
851                         int size;
852                         uint8_t *buf = vm->get_socket_send_buffer(ch, &size);
853                         if(size <= 0) {
854                                 return;
855                         }
856                         qint64 size2 = 0;
857                         
858                         if(udp_socket[ch] != NULL) {
859                                 size2 = udp_socket[ch]->writeDatagram((const char *)buf, (qint64)size, addr, (quint16)port);
860                                 if(size2 < 0) {
861                                         disconnect_socket(ch);
862                                         notify_socket_disconnected(ch);
863                                         return;
864                                 }
865                         } else {
866                                 return;
867                         }
868                         vm->inc_socket_send_buffer_ptr(ch, (int)size2);
869                 }
870         }
871 #endif  
872 }
873
874 void OSD::send_socket_data(int ch)
875 {
876         // This is dummy.
877 }
878
879 void OSD::recv_socket_data(int ch)
880 {
881         // This is dummy.
882 }
883
884 int OSD::get_socket(int ch)
885 {
886 #ifdef USE_SOCKET
887         if(is_tcp[ch]) {
888                 if(tcp_socket[ch] == NULL) return -1;
889         } else {
890                 if(udp_socket[ch] == NULL) return -1;
891         }
892 #endif  
893         return ch;
894 }
895
896 //
897 #if defined(USE_SOCKET)
898 QTcpSocket2::QTcpSocket2(int channel, QObject *parent) : QTcpSocket(parent)
899 {
900         ch = channel;
901 }
902
903 QTcpSocket2::~QTcpSocket2()
904 {
905 }
906
907 void QTcpSocket2::do_connected(void)
908 {
909         emit sig_connected(ch);
910 }
911
912 void QTcpSocket2::do_disconnected(void)
913 {
914         emit sig_disconnected(ch);
915 }
916
917 void QTcpSocket2::setChannel(int channel)
918 {
919         ch = channel;
920 }
921
922 int QTcpSocket2::getChannel(void)
923 {
924         return ch;
925 }
926
927 QUdpSocket2::QUdpSocket2(int channel, QObject *parent) : QUdpSocket(parent)
928 {
929         ch = channel;
930 }
931
932 QUdpSocket2::~QUdpSocket2()
933 {
934 }
935
936 void QUdpSocket2::do_connected(void)
937 {
938         emit sig_connected(ch);
939 }
940
941 void QUdpSocket2::do_disconnected(void)
942 {
943         emit sig_disconnected(ch);
944 }
945
946 void QUdpSocket2::setChannel(int channel)
947 {
948         ch = channel;
949 }
950
951 int QUdpSocket2::getChannel(void)
952 {
953         return ch;
954 }
955 #endif