int main(int argc, char* argv[]) { signal(SIGPIPE, SIG_IGN); char path[PATH_MAX]; bool foundConfig = false; #ifdef TOOLBAR_ICON bool userConfig = false; #endif // store for later _argc = argc; _argv = argv; /* syslog */ int logOpt = LOG_PID | LOG_CONS | LOG_PERROR; openlog("mmserver", logOpt, LOG_DAEMON); /* parse configuration */ Configuration appConfig; if (argc == 1) { /* look for config file in user or system directory */ if (CheckUserConfig(path, sizeof path)) { foundConfig = true; #ifdef TOOLBAR_ICON userConfig = true; #endif } else if (CheckSystemConfig(path, sizeof path)) { foundConfig = true; } } else if (argc == 2) { /* interpret the argument as the path to a particular config file */ snprintf(path, sizeof path, "%s", argv[1]); foundConfig = true; } else { fprintf(stderr, "Mobile Mouse Server for Linux (%s.%s.%s)\n", MMSERVER_VERSION_MAJOR, MMSERVER_VERSION_MINOR, MMSERVER_VERSION_PATCH); fprintf(stderr, "Website: https://github.com/anoved/mmserver/\n"); fprintf(stderr, "Usage: %s [/path/to/mmserver.conf]\n", argv[0]); return 1; } if (foundConfig) { syslog(LOG_INFO, "reading configuration from %s", path); try { appConfig.Read(path); } catch (const libconfig::FileIOException &err) { syslog(LOG_ERR, "Cannot read configuration from: %s", path); exit(1); } } else { syslog(LOG_INFO, "no configuration file found; using internal defaults"); } if (!appConfig.getKeyboardEnabled()) { syslog(LOG_INFO, "keyboard input ignored"); } syslog(LOG_INFO, "started on port %d", appConfig.getPort()); daemon(1, 1); if (appConfig.getZeroconf()) { StartAvahi(appConfig); } /* bind.. */ struct sockaddr_in serv_addr; bzero((char *)&serv_addr, sizeof serv_addr); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = INADDR_ANY; serv_addr.sin_port = htons(appConfig.getPort()); /* setup network.. */ int sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) { syslog(LOG_ERR, "socket: %s", strerror(errno)); exit(1); } int optval = 1; if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof optval) < 0) { syslog(LOG_ERR, "setsockopt: %s", strerror(errno)); exit(1); } if (bind(sockfd, (struct sockaddr *)&serv_addr, sizeof serv_addr) < 0) { syslog(LOG_ERR, "bind: %s", strerror(errno)); exit(1); } if (listen(sockfd, 1) < 0) { syslog(LOG_ERR, "listen: %s", strerror(errno)); exit(1); } #ifdef TOOLBAR_ICON pthread_t toolbarpid; if (pthread_create(&toolbarpid, 0x0, GTKStartup, (void*)(userConfig ? path : NULL)) == -1) { syslog(LOG_WARNING, "pthread_create failed: %s", strerror(errno)); } #endif /* server loop.. */ while(1) { struct sockaddr_in caddr; int clen = sizeof caddr; /* accept client.. */ int client = accept(sockfd, (struct sockaddr *)&caddr, (socklen_t*)&clen); if (client < 0) { syslog(LOG_WARNING, "accept failed: %s", strerror(errno)); continue; } /* start new session.. */ SessionContext * clientContext = new SessionContext(appConfig, client, inet_ntoa(caddr.sin_addr)); #ifdef TOOLBAR_ICON gtk_status_icon_set_tooltip(tray, std::string(clientContext->m_address + " connected").c_str()); gtk_status_icon_set_from_pixbuf(tray, connected_icon); #endif pthread_t pid; if (pthread_create(&pid, 0x0, MobileMouseSession, (void*)clientContext) == -1) { syslog(LOG_WARNING, "pthread_create failed: %s", strerror(errno)); delete clientContext; close(client); } else pthread_join(pid, 0x0); #ifdef TOOLBAR_ICON gtk_status_icon_set_tooltip(tray, TOOLBAR_LABEL_DEFAULT); gtk_status_icon_set_from_pixbuf(tray, idle_icon); #endif } return 0; }
INT main( INT argc, PCHAR argv[] ) { // Сбрасываем свойства приложения. bzero( &Enhancer, sizeof( ENHANCER ) ); // Определяем приложение в системе. Enhancer.Application = WinInitialize( 0 ); // Если это сделать не удалось - выход. if( Enhancer.Application == NULLHANDLE ) { // Звук - ошибка. WinAlarm( HWND_DESKTOP, WA_ERROR ); // Выход. DosExit( EXIT_PROCESS, 0 ); } // Создаем очередь сообщений. HMQ Message_queue = WinCreateMsgQueue( Enhancer.Application, 0 ); // Если очередь создать не удалось - выход. if( Message_queue == NULLHANDLE ) { // Звук - ошибка. WinAlarm( HWND_DESKTOP, WA_ERROR ); // Выход. WinTerminate( Enhancer.Application ); DosExit( EXIT_PROCESS, 0 ); } // Проверяем системные настройки. CheckSystemConfig(); // Запускаем составляющие приложения. StdLib_Start(); Strings_Start(); Files_Start(); Environment_Start(); EnhancerProperties_Start(); Loader_Start(); Launcher_Start(); // Узнаем, что надо сделать. if( argc == 2 ) { if( stristr( "hide", argv[ 1 ] ) ) Enhancer.Launcher_mode = 1; if( stristr( "mini", argv[ 1 ] ) ) Enhancer.Launcher_mode = 1; if( stristr( "launch", argv[ 1 ] ) ) Enhancer.Launcher_mode = 1; if( stristr( "enhance", argv[ 1 ] ) ) Enhancer.Enhancer_mode = 1; } // Возможно, надо вызвать окно настроек. if( argc == 2 ) { if( strstr( "ControlCenter", argv[ 1 ] ) ) { CHAR Path_to_ControlCenter[ SIZE_OF_PATH ] = ""; GetCurrentPath( Path_to_ControlCenter ); strcat( Path_to_ControlCenter, "\\Nice-eCS.exe" ); Execute( Path_to_ControlCenter, argv[ 1 ] ); WinDestroyMsgQueue( Message_queue ); WinTerminate( Enhancer.Application ); DosExit( EXIT_PROCESS, 0 ); } } // Если действие не распознано - выход. if( !Enhancer.Enhancer_mode && !Enhancer.Launcher_mode ) { WinDestroyMsgQueue( Message_queue ); WinTerminate( Enhancer.Application ); DosExit( EXIT_PROCESS, 0 ); } // Если окно приложения уже есть - выход. { CHAR Semaphore_name[] = "\\SEM32\\NICE-OS2!L"; HMTX hmtxAlreadyRunning = NULLHANDLE; if( Enhancer.Enhancer_mode ) Semaphore_name[ strlen( Semaphore_name ) - 1 ] = 'E'; if( DosOpenMutexSem( Semaphore_name, &hmtxAlreadyRunning ) == NO_ERROR ) { WinDestroyMsgQueue( Message_queue ); WinTerminate( Enhancer.Application ); DosExit( EXIT_PROCESS, 0 ); } else { DosCreateMutexSem( Semaphore_name, &hmtxAlreadyRunning, DC_SEM_SHARED, 1 ); } } // Загрузчик должен запускаться до расширителя. if( Enhancer.Launcher_mode ) { CHAR Semaphore_name[] = "\\SEM32\\NICE-OS2!E"; HMTX hmtxAlreadyRunning = NULLHANDLE; if( DosOpenMutexSem( Semaphore_name, &hmtxAlreadyRunning ) == NO_ERROR ) { WinDestroyMsgQueue( Message_queue ); WinTerminate( Enhancer.Application ); DosExit( EXIT_PROCESS, 0 ); } } // Расширитель должен запускаться после загрузчика if( Enhancer.Enhancer_mode ) { CHAR Semaphore_name[] = "\\SEM32\\NICE-OS2!L"; HMTX hmtxAlreadyRunning = NULLHANDLE; if( DosOpenMutexSem( Semaphore_name, &hmtxAlreadyRunning ) != NO_ERROR ) { WinDestroyMsgQueue( Message_queue ); WinTerminate( Enhancer.Application ); DosExit( EXIT_PROCESS, 0 ); } } // Если надо вызвать загрузчик: if( Enhancer.Launcher_mode ) { // Создаем поток для запуска расширителя. DosCreateThread( &Threads.Launcher, (PFNTHREAD) LauncherThread, 0, 0, STACK_SIZE ); } // Если надо вызвать расширитель: if( Enhancer.Enhancer_mode ) { // Пробуем найти окно загрузчика. HWND Launcher_window = NULLHANDLE; CHAR Launcher_title[] = "Nice-OS2!L"; { // Перебираем окна в окне рабочего стола. HENUM Enumeration = WinBeginEnumWindows( WinQueryDesktopWindow( Enhancer.Application, NULLHANDLE ) ); HWND Window = NULLHANDLE; while( ( Window = WinGetNextWindow( Enumeration ) ) != NULLHANDLE ) { // Узнаем заголовок окна. CHAR Window_title[ SIZE_OF_TITLE ] = ""; WinQueryWindowText( WinWindowFromID( Window, FID_TITLEBAR ), SIZE_OF_TITLE, Window_title ); // Если это окно расширителя - запоминаем его. if( strc( Window_title, Launcher_title ) ) { Launcher_window = Window; break; } } WinEndEnumWindows( Enumeration ); } // Если загрузчика нет - выход. // Вообще-то он должен быть, раз найден семафор, но кто знает... if( !Launcher_window ) { WinTerminate( Enhancer.Application ); DosExit( EXIT_PROCESS, 0 ); } // Создаем потоки, устанавливаем обработчики событий. BYTE Success = NiceLoadEnhancer( Enhancer.Application, 0, Launcher_window ); // Если это сделать не удалось - выход. if( !Success ) { WinTerminate( Enhancer.Application ); DosExit( EXIT_PROCESS, 0 ); } // Читаем настройки и загружаем изображения в расширитель. // Этот метод выполняется внутри Nice-os2.dll, но так как DLL использует // адресное пространство приложения, все данные остаются в этом приложении. NiceReadSettings( 0 ); // Включаем слежение за сообщениями. NiceRunEnhancer(); } // Создаем окно рабочей области. CHAR Class_name[] = "NiceOS2WndClass!L"; if( Enhancer.Enhancer_mode ) Class_name[ strlen( Class_name ) - 1 ] = 'E'; WinRegisterClass( Enhancer.Application, Class_name, (PFNWP) Enhancer_MainWindowProc, 0, 0 ); // Создаем окно рамки. CHAR MainWindow_title[] = "Nice-OS2!L"; if( Enhancer.Enhancer_mode ) Class_name[ strlen( Class_name ) - 1 ] = 'E'; ULONG Creation_flags = FCF_TITLEBAR | FCF_SYSMENU; Enhancer.Frame_window = WinCreateStdWindow( HWND_DESKTOP, CS_FRAME, &Creation_flags, Class_name, MainWindow_title, 0, NULLHANDLE, 0, &Enhancer.Client_window ); WinShowWindow( Enhancer.Frame_window, 0 ); // Выбираем сообщения из очереди. QMSG Message; bzero( &Message, sizeof( QMSG ) ); while( WinGetMsg( Enhancer.Application, &Message, 0, 0, 0 ) ) WinDispatchMsg( Enhancer.Application, &Message ); // Закрываем окна. WinDestroyWindow( Enhancer.Client_window ); WinDestroyWindow( Enhancer.Frame_window ); // Если вызван расширитель: if( Enhancer.Enhancer_mode ) { // Отключаем обработчики событий, завершаем работу потоков. NiceReleaseEnhancer( Enhancer.Application, 0 ); } // Удаляем файлы отладочной версии. DosForceDelete( "_log.txt" ); DosForceDelete( "XTest.exe" ); // Сбрасываем очередь сообщений. WinDestroyMsgQueue( Message_queue ); // Выход. WinTerminate( Enhancer.Application ); DosExit( EXIT_PROCESS, 0 ); }