OSDN Git Service

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