Changeset 7264 in vbox for trunk/src/VBox/Additions/x11
- Timestamp:
- Mar 4, 2008 9:14:24 AM (17 years ago)
- Location:
- trunk/src/VBox/Additions/x11/xclient
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/x11/xclient/clipboard.cpp
r7118 r7264 48 48 # define LogFlow(a) do {} while (0) 49 49 #endif 50 51 #define TRACE printf("%s: %d\n", __PRETTY_FUNCTION__, __LINE__); Log(("%s: %d\n", __PRETTY_FUNCTION__, __LINE__)) 50 52 51 53 /** The formats which we support in the guest. These can be deactivated in order to test specific code paths. */ … … 1357 1359 1358 1360 AssertReturn(g_ctx.client != 0, (void) 0); 1359 #if 0 1360 /* Currently, disconnecting is not needed, as the new "connect clipboard" ioctl in the Guest Additions kernel 1361 * module disconnects the last connection made automatically. The reason for this change was that currently 1362 * only one clipboard connection is allowed, and that if the client holding that connection was terminated 1363 * too abruptly, the information needed to disconnect that connection was lost. If the subsystem is ever 1364 * changed to allow several connections, this will have to be rethought. 1365 */ 1366 vmmdevInitRequest((VMMDevRequestHeader*)&request, VMMDevReq_HGCMDisconnect); 1367 request.u32ClientID = g_ctx.client; 1368 ioctl(g_ctx.sendDevice, IOCTL_VBOXGUEST_VMMREQUEST, (void*)&request); 1369 #endif 1361 VbglR3ClipboardDisconnect(g_ctx.client); 1370 1362 LogFlowFunc(("returning\n")); 1371 1363 } … … 1476 1468 LogFlowFunc(("\n")); 1477 1469 1470 TRACE; 1478 1471 rc = vboxClipboardCreateWindow(); 1479 1472 if (VBOX_FAILURE(rc)) 1480 1473 return rc; 1481 1474 1475 TRACE; 1482 1476 rc = RTThreadCreate(&g_ctx.thread, vboxClipboardThread, 0, 0, RTTHREADTYPE_IO, 1483 1477 RTTHREADFLAGS_WAITABLE, "SHCLIP"); 1484 1478 AssertRCReturn(rc, rc); 1485 1479 /* Set up a timer to poll the host clipboard */ 1480 TRACE; 1486 1481 XtAppAddTimeOut(g_ctx.appContext, 200 /* ms */, vboxClipboardTimerProc, 0); 1487 1482 1483 TRACE; 1488 1484 XtAppMainLoop(g_ctx.appContext); 1485 TRACE; 1489 1486 g_ctx.formatList.clear(); 1487 TRACE; 1490 1488 XtDestroyApplicationContext(g_ctx.appContext); 1491 1489 /* Set the termination signal. */ 1492 1490 RTSemEventSignal(g_ctx.terminating); 1493 1491 LogFlowFunc(("returning %d\n", rc)); 1492 TRACE; 1494 1493 return rc; 1495 1494 } -
trunk/src/VBox/Additions/x11/xclient/clipboard.h
r6202 r7264 20 20 # define __Additions_linux_clipboard_h 21 21 22 #include "thread.h" /* for VBoxGuestThread */ 23 22 24 extern void vboxClipboardDisconnect (void); 23 25 extern int vboxClipboardConnect (void); 24 26 extern int vboxClipboardMain (void); 25 27 28 /** 29 * Display change request monitor thread function 30 */ 31 class VBoxGuestClipboardThread : public VBoxGuestThreadFunction 32 { 33 private: 34 // Copying or assigning a thread object is not sensible 35 VBoxGuestClipboardThread(const VBoxGuestClipboardThread&); 36 VBoxGuestClipboardThread& operator=(const VBoxGuestClipboardThread&); 37 38 // Private member variables 39 /** Have we been initialised yet? */ 40 bool mInit; 41 /** The thread object running us. */ 42 VBoxGuestThread *mThread; 43 public: 44 VBoxGuestClipboardThread() { mInit = false; } 45 /** 46 * Initialise the class and check that the guest supports dynamic resizing. 47 * @returns iprt status value 48 */ 49 int init(void) 50 { 51 if (mInit) 52 return true; 53 return vboxClipboardConnect(); 54 } 55 /** 56 * The actual thread function. 57 * 58 * @returns iprt status code as thread return value 59 * @param pParent the VBoxGuestThread running this thread function 60 */ 61 virtual int threadFunction(VBoxGuestThread *pThread) 62 { 63 vboxClipboardMain(); 64 return VINF_SUCCESS; 65 } 66 /** 67 * Send a signal to the thread function that it should exit 68 */ 69 virtual void stop(void) { vboxClipboardDisconnect(); } 70 }; 71 72 class VBoxGuestClipboard 73 { 74 private: 75 /** No copying or assignment. */ 76 VBoxGuestClipboard(const VBoxGuestClipboard &); 77 VBoxGuestClipboard& operator=(const VBoxGuestClipboard &); 78 79 /** Our monitor thread function */ 80 VBoxGuestClipboardThread mThreadFunction; 81 /** And the thread for the thread function */ 82 VBoxGuestThread mThread; 83 /** Are we initialised? */ 84 bool mInit; 85 public: 86 /** 87 * Initialise the class. 88 * @returns iprt status value 89 */ 90 int init(void) 91 { 92 int rc = mThreadFunction.init(); 93 if (RT_SUCCESS(rc)) 94 rc = mThread.start(); 95 if (RT_SUCCESS(rc)) 96 mInit = true; 97 return rc; 98 } 99 /** 100 * Uninitialise the class. 101 * @param cMillies how long to wait for the thread to stop 102 */ 103 void uninit(unsigned cMillies = RT_INDEFINITE_WAIT) 104 { 105 if (mInit) 106 mThread.stop(cMillies, NULL); 107 } 108 109 VBoxGuestClipboard() : mThread(&mThreadFunction, 0, RTTHREADTYPE_MSG_PUMP, 110 RTTHREADFLAGS_WAITABLE, "SHCLIP MAIN") 111 { mInit = false; } 112 ~VBoxGuestClipboard() 113 { 114 if (mInit) 115 try { 116 uninit(2000); 117 } catch (...) { } 118 } 119 }; 120 26 121 #endif /* __Additions_linux_clipboard_h not defined */ -
trunk/src/VBox/Additions/x11/xclient/main.cpp
r7008 r7264 22 22 #include <VBox/log.h> 23 23 #include <iprt/initterm.h> 24 #include <iprt/path.h> 24 25 25 26 #include <iostream> 27 #include <cstdio> 26 28 27 29 #include <sys/types.h> 28 30 #include <stdlib.h> /* For exit */ 29 31 #include <unistd.h> 30 #include <getopt.h>31 32 #include <errno.h> 33 #include <signal.h> 32 34 33 35 #include <X11/Xlib.h> … … 43 45 #endif 44 46 45 static bool gbDaemonise = true; 47 #define TRACE printf("%s: %d\n", __PRETTY_FUNCTION__, __LINE__); Log(("%s: %d\n", __PRETTY_FUNCTION__, __LINE__)) 48 46 49 static int (*gpfnOldIOErrorHandler)(Display *) = NULL; 50 51 /* Make these global so that the destructors are called if we make an "emergency exit", 52 i.e. a (handled) signal or an X11 error. */ 53 #ifdef DYNAMIC_RESIZE 54 VBoxGuestDisplayChangeMonitor gDisplayChange; 55 # ifdef SEAMLESS_GUEST 56 /** Our instance of the seamless class. This only makes sense if dynamic resizing 57 is enabled. */ 58 VBoxGuestSeamless gSeamless; 59 # endif /* SEAMLESS_GUEST defined */ 60 #endif /* DYNAMIC_RESIZE */ 61 #ifdef VBOX_X11_CLIPBOARD 62 VBoxGuestClipboard gClipboard; 63 #endif 47 64 48 65 /** … … 90 107 return 0; 91 108 } 92 #ifdef VBOX_X11_CLIPBOARD93 vboxClipboardDisconnect();94 #endif95 109 XGetErrorText(pDisplay, pError->error_code, errorText, sizeof(errorText)); 96 110 LogRel(("VBoxClient: an X Window protocol error occurred: %s (error code %d). Request code: %d, minor code: %d, serial number: %d\n", errorText, pError->error_code, pError->request_code, pError->minor_code, pError->serial)); … … 110 124 } 111 125 126 /** 127 * A standard signal handler which cleans up and exits. Our global static objects will 128 * be cleaned up properly as we exit using "exit". 129 */ 130 void vboxClientSignalHandler(int cSignal) 131 { 132 Log(("VBoxClient: terminated with signal %d\n", cSignal)); 133 /* Our pause() call will now return and exit. */ 134 } 135 136 /** 137 * Reset all standard termination signals to call our signal handler, which cleans up 138 * and exits. 139 */ 140 void vboxClientSetSignalHandlers(void) 141 { 142 struct sigaction sigAction = { { 0 } }; 143 144 sigAction.sa_handler = vboxClientSignalHandler; 145 sigemptyset(&sigAction.sa_mask); 146 sigaction(SIGHUP, &sigAction, NULL); 147 sigaction(SIGINT, &sigAction, NULL); 148 sigaction(SIGQUIT, &sigAction, NULL); 149 sigaction(SIGABRT, &sigAction, NULL); 150 sigaction(SIGPIPE, &sigAction, NULL); 151 sigaction(SIGALRM, &sigAction, NULL); 152 sigaction(SIGTERM, &sigAction, NULL); 153 sigaction(SIGUSR1, &sigAction, NULL); 154 sigaction(SIGUSR2, &sigAction, NULL); 155 } 156 157 /** 158 * Print out a usage message and exit with success. 159 */ 160 void vboxClientUsage(const char *pcszFileName) 161 { 162 /* printf is better for i18n than iostream. */ 163 printf("Usage: %s [-d|--nodaemon]\n", pcszFileName); 164 printf("Start the VirtualBox X Window System guest services.\n\n"); 165 printf("Options:\n"); 166 printf(" -d, --nodaemon do not lower privileges and continue running as a system\n"); 167 printf(" service\n"); 168 exit(0); 169 } 170 171 /** 172 * The main loop for the VBoxClient daemon. 173 */ 112 174 int main(int argc, char *argv[]) 113 175 { 114 176 int rcClipboard, rc = VINF_SUCCESS; 115 #ifdef DYNAMIC_RESIZE 116 VBoxGuestDisplayChangeMonitor displayChange; 117 # ifdef SEAMLESS_GUEST 118 /** Our instance of the seamless class. This only makes sense if dynamic resizing 119 is enabled. */ 120 VBoxGuestSeamless seamless; 121 # endif /* SEAMLESS_GUEST defined */ 122 #endif /* DYNAMIC_RESIZE */ 123 177 const char *pszFileName = RTPathFilename(argv[0]); 178 bool fDaemonise = true; 179 180 if (NULL == pszFileName) 181 pszFileName = "VBoxClient"; 182 183 TRACE; 124 184 /* Parse our option(s) */ 125 /** @todo r=bird: use RTGetOpt */ 126 while (1) 127 { 128 static struct option sOpts[] = 129 { 130 {"nodaemon", 0, 0, 'd'}, 131 {0, 0, 0, 0} 132 }; 133 int cOpt = getopt_long(argc, argv, "", sOpts, 0); 134 if (cOpt == -1) 135 { 136 if (optind < argc) 137 { 138 std::cout << "Unrecognized command line argument: " << argv[argc] << std::endl; 139 exit(1); 140 } 141 break; 142 } 143 switch(cOpt) 144 { 145 case 'd': 146 gbDaemonise = false; 147 break; 148 default: 149 std::cout << "Unrecognized command line option: " << static_cast<char>(cOpt) 150 << std::endl; 151 case '?': 185 /** @todo Use RTGetOpt() if the arguments become more complex. */ 186 for (int i = 1; i < argc; ++i) 187 { 188 if (!strcmp(argv[i], "-d") || !strcmp(argv[i], "--nodaemon")) 189 fDaemonise = false; 190 else if (!strcmp(argv[i], "-h") || strcmp(argv[i], "--help")) 191 { 192 vboxClientUsage(pszFileName); 193 exit(0); 194 } 195 else 196 { 197 /* printf is better than iostream for i18n. */ 198 printf("%s: unrecognized option `%s'\n", pszFileName, argv[i]); 199 printf("Try `%s --help' for more information\n", pszFileName); 152 200 exit(1); 153 201 } 154 202 } 155 if (gbDaemonise) 203 TRACE; 204 if (fDaemonise) 156 205 { 157 206 rc = VbglR3Daemonize(false /* fNoChDir */, false /* fNoClose */); … … 163 212 } 164 213 /* Initialise our runtime before all else. */ 214 TRACE; 165 215 RTR3Init(false); 166 216 if (RT_FAILURE(VbglR3Init())) … … 169 219 return 1; 170 220 } 171 if (RT_FAILURE(vboxClientDropPrivileges())) 221 TRACE; 222 if (fDaemonise && RT_FAILURE(vboxClientDropPrivileges())) 172 223 return 1; 173 224 LogRel(("VBoxClient: starting...\n")); … … 182 233 /* Set an X11 I/O error handler, so that we can shutdown properly on fatal errors. */ 183 234 gpfnOldIOErrorHandler = XSetIOErrorHandler(vboxClientXLibIOErrorHandler); 235 vboxClientSetSignalHandlers(); 236 try 237 { 184 238 #ifdef VBOX_X11_CLIPBOARD 185 /* Connect to the host clipboard. */186 LogRel(("VBoxClient: starting clipboard Guest Additions...\n"));187 rcClipboard = vboxClipboardConnect();188 if (RT_FAILURE(rcClipboard))189 {190 LogRel(("VBoxClient: vboxClipboardConnect failed with rc = %Rrc\n", rc));191 }239 /* Connect to the host clipboard. */ 240 LogRel(("VBoxClient: starting clipboard Guest Additions...\n")); 241 rcClipboard = gClipboard.init(); 242 if (RT_FAILURE(rcClipboard)) 243 { 244 LogRel(("VBoxClient: vboxClipboardConnect failed with rc = %Rrc\n", rc)); 245 } 192 246 #endif /* VBOX_X11_CLIPBOARD defined */ 193 try194 {195 247 #ifdef DYNAMIC_RESIZE 196 248 LogRel(("VBoxClient: starting dynamic guest resizing...\n")); 197 rc = displayChange.init();249 rc = gDisplayChange.init(); 198 250 if (RT_FAILURE(rc)) 199 251 { … … 204 256 { 205 257 LogRel(("VBoxClient: starting seamless Guest Additions...\n")); 206 rc = seamless.init();258 rc = gSeamless.init(); 207 259 if (RT_FAILURE(rc)) 208 260 { … … 215 267 catch (std::exception e) 216 268 { 217 LogRel(("VBoxClient: failed to initialise seamlessAdditions - caught exception: %s\n", e.what()));269 LogRel(("VBoxClient: failed to initialise Guest Additions - caught exception: %s\n", e.what())); 218 270 rc = VERR_UNRESOLVED_ERROR; 219 271 } 220 272 catch (...) 221 273 { 222 LogRel(("VBoxClient: failed to initialise seamlessAdditions - caught unknown exception.\n"));274 LogRel(("VBoxClient: failed to initialise Guest Additions - caught unknown exception.\n")); 223 275 rc = VERR_UNRESOLVED_ERROR; 224 276 } 225 #ifdef VBOX_X11_CLIPBOARD226 if (RT_SUCCESS(rcClipboard))227 {228 LogRel(("VBoxClient: connecting to the shared clipboard service.\n"));229 vboxClipboardMain();230 vboxClipboardDisconnect();231 }232 #else /* VBOX_X11_CLIPBOARD not defined */233 277 LogRel(("VBoxClient: sleeping...\n")); 234 278 pause(); 235 279 LogRel(("VBoxClient: exiting...\n")); 236 #endif /* VBOX_X11_CLIPBOARD not defined */237 280 try 238 281 { 239 282 #ifdef DYNAMIC_RESIZE 240 displayChange.uninit();241 283 # ifdef SEAMLESS_GUEST 242 seamless.uninit(); 284 LogRel(("VBoxClient: shutting down seamless Guest Additions...\n")); 285 gSeamless.uninit(2000); 243 286 # endif /* SEAMLESS_GUEST defined */ 287 LogRel(("VBoxClient: shutting down dynamic guest resizing...\n")); 288 gDisplayChange.uninit(2000); 244 289 #endif /* DYNAMIC_RESIZE defined */ 290 #ifdef VBOX_X11_CLIPBOARD 291 /* Connect to the host clipboard. */ 292 LogRel(("VBoxClient: shutting down clipboard Guest Additions...\n")); 293 gClipboard.uninit(2000); 294 #endif /* VBOX_X11_CLIPBOARD defined */ 245 295 } 246 296 catch (std::exception e) 247 297 { 248 LogRel(("VBoxClient: error shutting down seamlessAdditions - caught exception: %s\n", e.what()));298 LogRel(("VBoxClient: failed to shut down Guest Additions - caught exception: %s\n", e.what())); 249 299 rc = VERR_UNRESOLVED_ERROR; 250 300 } 251 301 catch (...) 252 302 { 253 LogRel(("VBoxClient: error shutting down seamlessAdditions - caught unknown exception.\n"));303 LogRel(("VBoxClient: failed to shut down Guest Additions - caught unknown exception.\n")); 254 304 rc = VERR_UNRESOLVED_ERROR; 255 305 } -
trunk/src/VBox/Additions/x11/xclient/seamless.h
r6959 r7264 168 168 } 169 169 170 void uninit( void)170 void uninit(unsigned cMillies = RT_INDEFINITE_WAIT) 171 171 { 172 172 if (isInitialised) 173 173 { 174 174 mHost.stop(); 175 mGuestThread.stop( RT_INDEFINITE_WAIT, 0);175 mGuestThread.stop(cMillies, 0); 176 176 mGuest.uninit(); 177 177 isInitialised = false;
Note:
See TracChangeset
for help on using the changeset viewer.