OSDN Git Service

[BUILD] Set SOVERSION and GIT hash automatically.
[csp-qt/common_source_project-fm7.git] / source / src / qt / osd_wrapper.cpp
index e70b673..f40eaa0 100644 (file)
@@ -7,6 +7,25 @@
        [ VM/OSD Wrapper ]
 */
 
+#include <string>
+
+#include <QObject>
+#include <QWidget>
+
+#include <QMutex>
+#include <QSemaphore>
+#include <QPainter>
+#include <QElapsedTimer>
+#include <QQueue>
+
+#include <QDateTime>
+#include <QDate>
+#include <QTime>
+#include <QString>
+#include <QObject>
+#include <QThread>
+#include <QMutex>
+
 #include <QImage>
 #include <QPainter>
 #include <QColor>
 
 #include "osd.h"
 #include "../vm/vm.h"
+#include "../vm/device.h"
+#include "../common.h"
+
 #include "emu.h"
 
 #include "emu_thread.h"
 #include "draw_thread.h"
-
+#if defined(USE_MOVIE_PLAYER) || defined(USE_VIDEO_CAPTURE)
+#include "avio/movie_loader.h"
+#endif
+#if defined(USE_SOUND_FILES)
+#include "avio/sound_loader.h"
+#endif
 #include "qt_gldraw.h"
-#include "agar_logger.h"
+#include "csp_logger.h"
+
+const _TCHAR *OSD::get_lib_common_vm_version()
+{
+       if(vm->first_device != NULL) {
+               return vm->first_device->get_lib_common_vm_version();
+       } else {
+               return (const _TCHAR *)"\0";
+       }
+}
+
+const _TCHAR *OSD::get_lib_common_vm_git_version()
+{
+       return vm->get_vm_git_version();
+}
+
+const _TCHAR *OSD::get_lib_osd_version()
+{
+       const _TCHAR *p = (const _TCHAR *)"\0";
+#if defined(__LIBOSD_VERSION)
+       p = (const _TCHAR *)__LIBOSD_VERSION;
+#endif
+       return p;         
+}
+
 
 void OSD::vm_draw_screen(void)
 {
@@ -43,7 +94,82 @@ Sint16* OSD::create_sound(int *extra_frames)
        return (Sint16 *)vm->create_sound(extra_frames);
 }
 
+#ifdef USE_SOUND_FILES
+void OSD::load_sound_file(int id, const _TCHAR *name, int16_t **data, int *dst_size)
+{
+       int i = 0;
+       if(data != NULL) *data = NULL;
+       if(dst_size != NULL) *dst_size = 0;
+       if(id <= 0) return;
+
+       for(i = 0; i < USE_SOUND_FILES; i++) {
+               SOUND_LOADER *p = sound_file_obj[i];
+               if(p != NULL) {
+                       if(p->get_id() == id) break;
+               }
+       }
+       
+       if(i >= USE_SOUND_FILES) {
+               for(i = 0; i < USE_SOUND_FILES; i++) {
+                       SOUND_LOADER *p = sound_file_obj[i];
+                       if(p != NULL) {
+                               if(p->get_id() < 0) {
+                                       p->set_id(id);
+                                       break;
+                               }
+                       }
+               }
+       }
+       if(i >= USE_SOUND_FILES) return;
+       SOUND_LOADER *p = sound_file_obj[i];
+       if(p != NULL) {
+               p->free_sound_buffer(NULL);
+               p->set_sound_rate(this->get_sound_rate());
+               if(p->open(id, QString::fromUtf8(name))) {
+                       p->do_decode_frames();
+                       p->close();
+                       if(data != NULL) *data = (int16_t *)(p->get_sound_buffer());
+                       if(dst_size != NULL) *dst_size = p->get_dst_size();
+               }
+       }
+}
+
+void OSD::free_sound_file(int id, int16_t **data)
+{
+       if(data == NULL) return;
+       for(int i = 0; i < USE_SOUND_FILES; i++) {
+               SOUND_LOADER *p = sound_file_obj[i];
+               if(p != NULL) {
+                       if(p->get_id() == id) {
+                               p->free_sound_buffer(*data);
+                               *data = NULL;
+                               break;
+                       }
+               }
+       }
+}
 
+void OSD::init_sound_files()
+{
+       for(int i = 0; i < USE_SOUND_FILES; i++) {
+               sound_file_obj[i] = NULL;
+               SOUND_LOADER *p = new SOUND_LOADER((void *)tail_sound_file, p_logger);
+               if(p != NULL) {
+                       sound_file_obj[i] = p;
+               }
+               tail_sound_file = p;
+       }
+}
+
+void OSD::release_sound_files()
+{
+       for(int i = 0; i < USE_SOUND_FILES; i++) {
+               SOUND_LOADER *p = sound_file_obj[i];
+               if(p != NULL) delete p;
+               sound_file_obj[i] = NULL;
+       }
+}
+#endif
 bool OSD::get_use_socket(void)
 {
 #ifdef USE_SOCKET
@@ -52,6 +178,7 @@ bool OSD::get_use_socket(void)
        return false;
 #endif
 }
+
 bool OSD::get_support_variable_timing(void)
 {
 #ifdef SUPPORT_VARIABLE_TIMING
@@ -162,12 +289,16 @@ bool OSD::get_use_video_capture(void)
 
 void OSD::vm_key_down(int code, bool flag)
 {
+#ifdef NOTIFY_KEY_DOWN
        vm->key_down(code, flag);
+#endif
 }
 
 void OSD::vm_key_up(int code)
 {
+#ifdef NOTIFY_KEY_DOWN
        vm->key_up(code);
+#endif
 }
 
 void OSD::vm_reset(void)
@@ -185,7 +316,7 @@ int OSD::get_vm_buttons_code(int num)
 #endif
 }      
 
-void OSD::update_buttons(void)
+void OSD::update_buttons(bool press_flag, bool release_flag)
 {
 #if defined(MAX_BUTTONS)
        if(!press_flag && !release_flag) {
@@ -231,20 +362,24 @@ int OSD::get_screen_height(void)
 void OSD::lock_vm(void)
 {
        locked_vm = true;
-       if(parent_thread != NULL) { 
-               if(!parent_thread->now_debugging()) VMSemaphore->acquire(1);
-       } else {
-               VMSemaphore->acquire(1);
-       }
+       vm_mutex->lock();
+       //if(parent_thread != NULL) { 
+               //if(!parent_thread->now_debugging()) VMSemaphore->acquire(1);
+               //VMSemaphore->acquire(1);
+       //} else {
+       //      VMSemaphore->acquire(1);
+       //}
 }
 
 void OSD::unlock_vm(void)
 {
-       if(parent_thread != NULL) { 
-               if(!parent_thread->now_debugging()) VMSemaphore->release(1);
-       } else {
-               VMSemaphore->release(1);
-       }
+       vm_mutex->unlock();
+       //if(parent_thread != NULL) { 
+       //      //if(!parent_thread->now_debugging()) VMSemaphore->release(1);
+       //      VMSemaphore->release(1);
+       //} else {
+       //      VMSemaphore->release(1);
+       //}
        locked_vm = false;
 }
 
@@ -256,24 +391,21 @@ bool OSD::is_vm_locked(void)
 
 void OSD::force_unlock_vm(void)
 {
-       if(parent_thread == NULL) {
-               while(VMSemaphore->available() < 1) VMSemaphore->release(1);
-               return;
-       }
-       if(parent_thread->now_debugging()) return;
-       while(VMSemaphore->available() < 1) VMSemaphore->release(1);
+       vm_mutex->unlock();
+       locked_vm = false;
 }
 
 void OSD::set_draw_thread(DrawThreadClass *handler)
 {
-       this->moveToThread(handler);
+       //this->moveToThread(handler);
        connect(this, SIGNAL(sig_update_screen(bitmap_t *)), handler, SLOT(do_update_screen(bitmap_t *)));
        connect(this, SIGNAL(sig_save_screen(const char *)), glv, SLOT(do_save_frame_screen(const char *)));
        connect(this, SIGNAL(sig_resize_vm_screen(QImage *, int, int)), glv, SLOT(do_set_texture_size(QImage *, int, int)));
+       connect(this, SIGNAL(sig_resize_vm_lines(int)), glv, SLOT(do_set_horiz_lines(int)));
        connect(parent_thread, SIGNAL(sig_debugger_input(QString)), this, SLOT(do_set_input_string(QString)));
        connect(parent_thread, SIGNAL(sig_quit_debugger()), this, SLOT(do_close_debugger_thread()));
+       connect(this, SIGNAL(sig_move_mouse_to_center()), glv, SLOT(do_move_mouse_to_center()));
        connect(this, SIGNAL(sig_close_window()), parent_thread, SLOT(doExit()));
-       connect(this, SIGNAL(sig_console_input_string(QString)), parent_thread, SLOT(do_call_debugger_command(QString)));
 }
 
 void OSD::initialize_screen()
@@ -290,15 +422,12 @@ void OSD::initialize_screen()
        vm_window_height_aspect = WINDOW_HEIGHT_ASPECT;
        
        QColor col(0, 0, 0, 255);
-       //memset(&vm_screen_buffer, 0, sizeof(bitmap_t));
+
        vm_screen_buffer.width = SCREEN_WIDTH;
        vm_screen_buffer.height = SCREEN_HEIGHT;
        vm_screen_buffer.pImage = QImage(SCREEN_WIDTH, SCREEN_HEIGHT, QImage::Format_ARGB32);
        vm_screen_buffer.pImage.fill(col);
        now_record_video = false;
-       //pAVIStream = NULL;
-       //pAVICompressed = NULL;
-       //pAVIFile = NULL;
        
        first_draw_screen = false;
        first_invalidate = true;
@@ -308,28 +437,519 @@ void OSD::initialize_screen()
 void OSD::release_screen()
 {
        stop_record_video();
-       
-       //release_d3d9();
-       //if(vm_screen_buffer.pImage != NULL) delete vm_screen_buffer.pImage;
        release_screen_buffer(&vm_screen_buffer);
 }
 
 int OSD::get_window_mode_width(int mode)
 {
        if(get_use_screen_rotate()) {
-               if(config.rotate_type == 1 || config.rotate_type == 3) {
-                       return (config.window_stretch_type == 0 ? vm_window_height : vm_window_height_aspect) * (mode + WINDOW_MODE_BASE);
+               if(p_config->rotate_type == 1 || p_config->rotate_type == 3) {
+                       return (p_config->window_stretch_type == 0 ? vm_window_height : vm_window_height_aspect) * (mode + WINDOW_MODE_BASE);
                }
        }
-       return (config.window_stretch_type == 0 ? vm_window_width : vm_window_width_aspect) * (mode + WINDOW_MODE_BASE);
+       return (p_config->window_stretch_type == 0 ? vm_window_width : vm_window_width_aspect) * (mode + WINDOW_MODE_BASE);
 }
 
 int OSD::get_window_mode_height(int mode)
 {
        if(get_use_screen_rotate()) {
-               if(config.rotate_type == 1 || config.rotate_type == 3) {
-                       return (config.window_stretch_type == 0 ? vm_window_width : vm_window_width_aspect) * (mode + WINDOW_MODE_BASE);
+               if(p_config->rotate_type == 1 || p_config->rotate_type == 3) {
+                       return (p_config->window_stretch_type == 0 ? vm_window_width : vm_window_width_aspect) * (mode + WINDOW_MODE_BASE);
+               }
+       }
+       return (p_config->window_stretch_type == 0 ? vm_window_height : vm_window_height_aspect) * (mode + WINDOW_MODE_BASE);
+}
+
+void OSD::initialize_video()
+{
+       movie_loader = NULL;
+#if defined(USE_MOVIE_PLAYER) || defined(USE_VIDEO_CAPTURE)
+       movie_loader = new MOVIE_LOADER(this, &config);
+       //connect(movie_loader, SIGNAL(sig_send_audio_frame(uint8_t *, long)), this, SLOT(do_run_movie_audio_callback2(uint8_t *, long)));
+       connect(movie_loader, SIGNAL(sig_movie_end(bool)), this, SLOT(do_video_movie_end(bool)));
+       connect(this, SIGNAL(sig_movie_play(void)), movie_loader, SLOT(do_play()));
+       connect(this, SIGNAL(sig_movie_stop(void)), movie_loader, SLOT(do_stop()));
+       connect(this, SIGNAL(sig_movie_pause(bool)), movie_loader, SLOT(do_pause(bool)));
+       connect(this, SIGNAL(sig_movie_seek_frame(bool, int)), movie_loader, SLOT(do_seek_frame(bool, int)));
+       //connect(this, SIGNAL(sig_movie_mute(bool, bool)), movie_loader, SLOT(do_mute(bool, bool)));
+       connect(movie_loader, SIGNAL(sig_decoding_error(int)), this, SLOT(do_video_decoding_error(int)));
+#endif 
+}
+
+void OSD::release_video()
+{
+#if defined(USE_MOVIE_PLAYER) || defined(USE_VIDEO_CAPTURE)
+       delete movie_loader;
+#endif 
+       movie_loader = NULL;
+}
+
+
+bool OSD::open_movie_file(const _TCHAR* file_path)
+{
+       bool ret = false;
+       if(file_path == NULL) return ret;
+#if defined(USE_MOVIE_PLAYER) || defined(USE_VIDEO_CAPTURE)
+       if(movie_loader != NULL) {
+               ret = movie_loader->open(QString::fromUtf8(file_path));
+       }
+#endif 
+       return ret;
+}
+
+void OSD::close_movie_file()
+{
+#if defined(USE_MOVIE_PLAYER) || defined(USE_VIDEO_CAPTURE)
+       if(movie_loader != NULL) {
+               movie_loader->close();
+       }
+#endif
+       now_movie_play = false;
+       now_movie_pause = false;
+}
+
+#include <limits.h>
+uint32_t OSD::get_cur_movie_frame()
+{
+#if defined(USE_MOVIE_PLAYER) || defined(USE_VIDEO_CAPTURE)
+       if(movie_loader != NULL) {
+               uint64_t pos;
+               pos = movie_loader->get_current_frame();
+               if(pos > UINT_MAX) {
+                       return UINT_MAX;
+               }
+               return (uint32_t)pos;
+       }
+#endif 
+       return 0;
+}
+
+void OSD::do_run_movie_audio_callback(uint8_t *data, long len)
+{
+       if(data == NULL) return;
+#if defined(USE_MOVIE_PLAYER) || defined(USE_VIDEO_CAPTURE)
+#if defined(_PX7)
+       {
+               lock_vm();
+               this->vm->movie_sound_callback(data, len);
+               unlock_vm();
+       }
+#endif
+#endif
+       free(data);
+}
+
+void OSD::do_decode_movie(int frames)
+{
+#if defined(USE_MOVIE_PLAYER) || defined(USE_VIDEO_CAPTURE)
+       //movie_loader->do_decode_frames(frames, SCREEN_WIDTH, SCREEN_HEIGHT);
+       movie_loader->do_decode_frames(frames, vm_window_width_aspect, vm_window_height_aspect);
+#endif 
+}
+
+void OSD::get_video_buffer()
+{
+#if defined(USE_MOVIE_PLAYER) || defined(USE_VIDEO_CAPTURE)
+       //movie_loader->do_decode_frames(1, this->get_vm_window_width(), this->get_vm_window_height());
+       movie_loader->get_video_frame();
+       //printf("**\n");
+#endif
+}
+
+int OSD::get_movie_sound_rate()
+{
+#if defined(USE_MOVIE_PLAYER) || defined(USE_VIDEO_CAPTURE)
+       return movie_loader->get_movie_sound_rate();
+#endif
+       return 44100;
+}
+
+void OSD::reset_vm_node()
+{
+       device_node_t sp;
+       device_node_list.clear();
+       p_logger->reset();
+       max_vm_nodes = 0;
+       for(DEVICE *p = vm->first_device; p != NULL; p = p->next_device) {
+               sp.id = p->this_device_id;
+               sp.name = p->this_device_name;
+               p_logger->set_device_name(sp.id, sp.name);
+               p_logger->debug_log(CSP_LOG_DEBUG, CSP_LOG_TYPE_GENERAL,  "Device %d :%s", sp.id, sp.name);
+               device_node_list.append(sp);
+               if(max_vm_nodes <= p->this_device_id) max_vm_nodes = p->this_device_id + 1;
+       }
+       for(DEVICE *p = vm->first_device; p != NULL; p = p->next_device) {
+               emit sig_update_device_node_name(p->this_device_id, p->this_device_name);
+       }
+}
+
+#if defined(USE_SOCKET)
+#include <QHostAddress>
+#include "osd_socket.h"
+#endif
+// Socket
+void OSD::initialize_socket()
+{
+       for(int i = 0; i < SOCKET_MAX; i++) {
+               tcp_socket[i] = NULL;
+               udp_socket[i] = NULL;
+               is_tcp[i] = false;
+               socket_delay[i] = 0;
+               host_mode[i] = false;
+       }
+}
+
+void OSD::release_socket()
+{
+       // release sockets
+#ifdef USE_SOCKET
+       for(int i = 0; i < SOCKET_MAX; i++) {
+               if(tcp_socket[i] != NULL) {
+                       if(tcp_socket[i]->isOpen()) tcp_socket[i]->close();
+                       delete tcp_socket[i];
+                       tcp_socket[i] = NULL;
+               }
+               if(udp_socket[i] != NULL) {
+                       if(udp_socket[i]->isOpen()) udp_socket[i]->close();
+                       delete udp_socket[i];
+                       udp_socket[i] = NULL;
                }
        }
-       return (config.window_stretch_type == 0 ? vm_window_height : vm_window_height_aspect) * (mode + WINDOW_MODE_BASE);
+#endif 
 }
+
+
+void OSD::notify_socket_connected(int ch)
+{
+       do_notify_socket_connected(ch);
+}
+
+void OSD::do_notify_socket_connected(int ch)
+{
+#ifdef USE_SOCKET
+       vm->notify_socket_connected(ch);
+#endif 
+}
+
+
+void OSD::notify_socket_disconnected(int ch)
+{
+       do_notify_socket_disconnected(ch);
+}
+
+
+void OSD::do_notify_socket_disconnected(int ch)
+{
+       if(!socket_delay[ch]) {
+               socket_delay[ch] = 1;//56;
+       }
+}
+
+// Called per 1 frame.
+void OSD::update_socket()
+{
+#ifdef USE_SOCKET
+       qint64 bytes;
+       for(int i = 0; i < SOCKET_MAX; i++) {
+               QIODevice *p = NULL;
+               if(is_tcp[i]) {
+                       if(tcp_socket[i] != NULL) {
+                               if(tcp_socket[i]->isOpen()) {
+                                       p = tcp_socket[i];
+                               }
+                       }
+               } else {
+                       if(udp_socket[i] != NULL) {
+                               if(udp_socket[i]->isOpen()) {
+                                       p = udp_socket[i];
+                               }
+                       }
+               }
+               if(p != NULL) { 
+                       // recv
+                       bytes = p->bytesAvailable();
+                       if(bytes > 0) {
+                               int size0, size1;
+                               uint8_t* buf0 = vm->get_socket_recv_buffer0(i, &size0, &size1);
+                               uint8_t* buf1 = vm->get_socket_recv_buffer1(i);
+                               qint64 size;
+                               
+                               if(bytes > (qint64)(size0 + size1)) {
+                                       bytes = (qint64)(size0 + size1);
+                               }
+                               QByteArray src = p->read(bytes);
+
+                               size = src.size();
+                               uint8_t *pp = (uint8_t *)(src.constData());
+                               if(size <= (qint64)size0) {
+                                       memcpy(buf0, pp, size);
+                               } else {
+                                       memcpy(buf0, pp, size0);
+                                       memcpy(buf1, pp + size0, (int)size - size0);
+                               }
+                               vm->inc_socket_recv_buffer_ptr(i, (int)size);
+                       } else if(socket_delay[i] != 0) {
+                               if(--socket_delay[i] == 0) {
+                                       vm->notify_socket_disconnected(i);
+                               }
+                       }
+               }
+       }
+#endif 
+}
+
+bool OSD::initialize_socket_tcp(int ch)
+{
+#ifdef USE_SOCKET
+       if(udp_socket[ch] != NULL) {
+               if(udp_socket[ch]->isOpen()) {
+                       udp_socket[ch]->close();
+               }
+               delete udp_socket[ch];
+               udp_socket[ch] = NULL;
+       }
+       if(tcp_socket[ch] != NULL) {
+               if(tcp_socket[ch]->isOpen()) tcp_socket[ch]->close();
+               delete tcp_socket[ch];
+       }
+       is_tcp[ch] = true;
+       tcp_socket[ch] = new QTcpSocket2(ch);
+       if(tcp_socket[ch] == NULL) return false;
+       tcp_socket[ch]->setChannel(ch);
+       connect(tcp_socket[ch], SIGNAL(connected()), tcp_socket[ch], SLOT(do_connected()));
+       connect(tcp_socket[ch], SIGNAL(sig_connected(int)), this, SLOT(do_notify_socket_connected(int)));
+       connect(tcp_socket[ch], SIGNAL(disconnected()), tcp_socket[ch], SLOT(do_disconnected()));
+       connect(tcp_socket[ch], SIGNAL(sig_disconnected(int)), this, SLOT(do_notify_socket_disconnected(int)));
+#endif 
+       return true;
+}
+
+bool OSD::initialize_socket_udp(int ch)
+{
+#ifdef USE_SOCKET
+       if(tcp_socket[ch] != NULL) {
+               if(tcp_socket[ch]->isOpen()) {
+                       tcp_socket[ch]->close();
+               }
+               delete tcp_socket[ch];
+               tcp_socket[ch] = NULL;
+       }
+       if(udp_socket[ch] != NULL) {
+               if(udp_socket[ch]->isOpen()) udp_socket[ch]->close();
+               delete udp_socket[ch];
+       }
+       is_tcp[ch] = false;
+       udp_socket[ch] = new QUdpSocket2(ch);
+       if(udp_socket[ch] == NULL) return false;
+       connect(udp_socket[ch], SIGNAL(connected()), udp_socket[ch], SLOT(do_connected()));
+       connect(udp_socket[ch], SIGNAL(sig_connected(int)), this, SLOT(do_notify_socket_connected(int)));
+       connect(udp_socket[ch], SIGNAL(disconnected()), udp_socket[ch], SLOT(do_disconnected()));
+       connect(udp_socket[ch], SIGNAL(sig_disconnected(int)), this, SLOT(do_notify_socket_disconnected(int)));
+#endif 
+       return true;
+}
+
+bool OSD::connect_socket(int ch, uint32_t ipaddr, int port)
+{
+#ifdef USE_SOCKET
+       QHostAddress addr = QHostAddress((quint32)ipaddr);
+       if(is_tcp[ch]) {
+               if(tcp_socket[ch] != NULL) {
+                       tcp_socket[ch]->connectToHost(addr, (quint16)port);
+               } else {
+                       return false;
+               }
+       } else {
+               if(udp_socket[ch] != NULL) {
+                       udp_socket[ch]->connectToHost(addr, (quint16)port);
+               } else {
+                       return false;
+               }
+       }
+       host_mode[ch] = false;
+#endif
+       return true;
+}
+
+void OSD::disconnect_socket(int ch)
+{
+//     soc[ch] = -1;
+#ifdef USE_SOCKET
+       if(host_mode[ch]) {
+               if(is_tcp[ch]) {
+                       if(tcp_socket[ch] != NULL) {
+                               if(tcp_socket[ch]->isOpen()) tcp_socket[ch]->close();
+                       }
+               } else {
+                       if(udp_socket[ch] != NULL) {
+                               if(udp_socket[ch]->isOpen()) udp_socket[ch]->close();
+                       }
+               }
+       } else {
+               if(is_tcp[ch]) {
+                       if(tcp_socket[ch] != NULL) {
+                               udp_socket[ch]->disconnectFromHost();
+                       }
+               } else {
+                       if(udp_socket[ch] != NULL) {
+                               udp_socket[ch]->disconnectFromHost();
+                       }
+               }
+       }               
+       vm->notify_socket_disconnected(ch);
+#endif 
+}
+
+bool OSD::listen_socket(int ch)
+{
+#ifdef USE_SOCKET
+       //QHostAddress addr = QHostAddress(QHostAddress::AnyIPv4); // OK?
+       // This unit is dummy?
+       //connect(udp_socket[ch], SIGNAL(connected()), udp_socket[ch], SLOT(do_connected()));
+       //connect(udp_socket[ch], SIGNAL(sig_connected(int)), this, SLOT(do_notify_socket_connected(int)));
+       //connect(udp_socket[ch], SIGNAL(disconnected()), udp_socket[ch], SLOT(do_disconnected()));
+       //connect(udp_socket[ch], SIGNAL(sig_disconnected(int)), this, SLOT(do_notify_socket_disconnected(int)));
+#endif 
+       return false;
+}
+
+void OSD::send_socket_data_tcp(int ch)
+{
+#ifdef USE_SOCKET
+       if(is_tcp[ch]) {
+               while(1) {
+                       int size;
+                       uint8_t *buf = vm->get_socket_send_buffer(ch, &size);
+                       if(size <= 0) {
+                               return;
+                       }
+                       qint64 size2 = 0;
+                       if(tcp_socket[ch] != NULL) {
+                               if(tcp_socket[ch]->isWritable()) {
+                                       size2 = tcp_socket[ch]->write((const char *)buf, (qint64)size);
+                                       if(size2 < 0) {
+                                               disconnect_socket(ch);
+                                               notify_socket_disconnected(ch);
+                                               return;
+                                       }
+                               }
+                       } else {
+                               return;
+                       }
+                       vm->inc_socket_send_buffer_ptr(ch, (int)size2);
+               }
+       }
+#endif 
+}
+
+void OSD::send_socket_data_udp(int ch, uint32_t ipaddr, int port)
+{
+#ifdef USE_SOCKET
+       QHostAddress addr = QHostAddress((quint32)ipaddr);
+       if(!is_tcp[ch]) {
+               while(1) {
+                       int size;
+                       uint8_t *buf = vm->get_socket_send_buffer(ch, &size);
+                       if(size <= 0) {
+                               return;
+                       }
+                       qint64 size2 = 0;
+                       
+                       if(udp_socket[ch] != NULL) {
+                               size2 = udp_socket[ch]->writeDatagram((const char *)buf, (qint64)size, addr, (quint16)port);
+                               if(size2 < 0) {
+                                       disconnect_socket(ch);
+                                       notify_socket_disconnected(ch);
+                                       return;
+                               }
+                       } else {
+                               return;
+                       }
+                       vm->inc_socket_send_buffer_ptr(ch, (int)size2);
+               }
+       }
+#endif 
+}
+
+void OSD::send_socket_data(int ch)
+{
+       // This is dummy.
+}
+
+void OSD::recv_socket_data(int ch)
+{
+       // This is dummy.
+}
+
+int OSD::get_socket(int ch)
+{
+#ifdef USE_SOCKET
+       if(is_tcp[ch]) {
+               if(tcp_socket[ch] == NULL) return -1;
+       } else {
+               if(udp_socket[ch] == NULL) return -1;
+       }
+#endif 
+       return ch;
+}
+
+//
+#if defined(USE_SOCKET)
+QTcpSocket2::QTcpSocket2(int channel, QObject *parent) : QTcpSocket(parent)
+{
+       ch = channel;
+}
+
+QTcpSocket2::~QTcpSocket2()
+{
+}
+
+void QTcpSocket2::do_connected(void)
+{
+       emit sig_connected(ch);
+}
+
+void QTcpSocket2::do_disconnected(void)
+{
+       emit sig_disconnected(ch);
+}
+
+void QTcpSocket2::setChannel(int channel)
+{
+       ch = channel;
+}
+
+int QTcpSocket2::getChannel(void)
+{
+       return ch;
+}
+
+QUdpSocket2::QUdpSocket2(int channel, QObject *parent) : QUdpSocket(parent)
+{
+       ch = channel;
+}
+
+QUdpSocket2::~QUdpSocket2()
+{
+}
+
+void QUdpSocket2::do_connected(void)
+{
+       emit sig_connected(ch);
+}
+
+void QUdpSocket2::do_disconnected(void)
+{
+       emit sig_disconnected(ch);
+}
+
+void QUdpSocket2::setChannel(int channel)
+{
+       ch = channel;
+}
+
+int QUdpSocket2::getChannel(void)
+{
+       return ch;
+}
+#endif