/* * Open a connection from a new client to the server. * Returns -1 on failure. */ int GrOpen(void) { #if NONETWORK SERVER_LOCK(); escape_quits = 1; /* Client calls this routine once. We * init everything here */ if (connectcount <= 0) { if(GsInitialize() < 0) { SERVER_UNLOCK(); return -1; } } if (! GsAcceptClientFd(999)) { SERVER_UNLOCK(); return -1; } curclient = root_client; SERVER_UNLOCK(); #endif return 1; }
EXPORT_C #endif void dbus_server_set_new_connection_function (DBusServer *server, DBusNewConnectionFunction function, void *data, DBusFreeFunction free_data_function) { DBusFreeFunction old_free_function; void *old_data; _dbus_return_if_fail (server != NULL); SERVER_LOCK (server); old_free_function = server->new_connection_free_data_function; old_data = server->new_connection_data; server->new_connection_function = function; server->new_connection_data = data; server->new_connection_free_data_function = free_data_function; SERVER_UNLOCK (server); if (old_free_function != NULL) (* old_free_function) (old_data); }
/** * Stores a pointer on a DBusServer, along * with an optional function to be used for freeing * the data when the data is set again, or when * the server is finalized. The slot number * must have been allocated with dbus_server_allocate_data_slot(). * * @param server the server * @param slot the slot number * @param data the data to store * @param free_data_func finalizer function for the data * @returns #TRUE if there was enough memory to store the data */ dbus_bool_t dbus_server_set_data (DBusServer *server, int slot, void *data, DBusFreeFunction free_data_func) { DBusFreeFunction old_free_func; void *old_data; dbus_bool_t retval; _dbus_return_val_if_fail (server != NULL, FALSE); SERVER_LOCK (server); retval = _dbus_data_slot_list_set (&slot_allocator, &server->slot_list, slot, data, free_data_func, &old_free_func, &old_data); SERVER_UNLOCK (server); if (retval) { /* Do the actual free outside the server lock */ if (old_free_func) (* old_free_func) (old_data); } return retval; }
/* * Close the current connection to the server. */ void GrClose(void) { SERVER_LOCK(); GsClose(current_fd); SERVER_UNLOCK(); }
EXPORT_C #endif void dbus_server_unref (DBusServer *server) { dbus_bool_t last_unref; /* keep this in sync with unref_unlocked */ _dbus_return_if_fail (server != NULL); _dbus_return_if_fail (server->refcount.value > 0); #ifdef DBUS_HAVE_ATOMIC_INT last_unref = (_dbus_atomic_dec (&server->refcount) == 1); #else SERVER_LOCK (server); _dbus_assert (server->refcount.value > 0); server->refcount.value -= 1; last_unref = (server->refcount.value == 0); SERVER_UNLOCK (server); #endif if (last_unref) { /* lock not held! */ _dbus_assert (server->disconnected); _dbus_assert (server->vtable->finalize != NULL); (* server->vtable->finalize) (server); } }
void GrBell(void) { SERVER_LOCK(); write(2, "\7", 1); SERVER_UNLOCK(); }
/** * Sets the authentication mechanisms that this server offers to * clients, as a #NULL-terminated array of mechanism names. This * function only affects connections created <em>after</em> it is * called. Pass #NULL instead of an array to use all available * mechanisms (this is the default behavior). * * The D-Bus specification describes some of the supported mechanisms. * * @param server the server * @param mechanisms #NULL-terminated array of mechanisms * @returns #FALSE if no memory */ dbus_bool_t dbus_server_set_auth_mechanisms (DBusServer *server, const char **mechanisms) { char **copy; _dbus_return_val_if_fail (server != NULL, FALSE); SERVER_LOCK (server); if (mechanisms != NULL) { copy = _dbus_dup_string_array (mechanisms); if (copy == NULL) return FALSE; } else copy = NULL; dbus_free_string_array (server->auth_mechanisms); server->auth_mechanisms = copy; SERVER_UNLOCK (server); return TRUE; }
/* * Open a connection from a new client to the server. * Returns -1 on failure. */ int GrOpen(void) { GdPlatformInit(); /* platform-specific initialization*/ #if NONETWORK SERVER_LOCK(); /* Client calls this routine once. We init everything here*/ if (connectcount <= 0) { if(GsInitialize() < 0) { SERVER_UNLOCK(); return -1; } GsAcceptClientFd(999); curclient = root_client; } SERVER_UNLOCK(); #endif /* NONETWORK*/ #if NANOWM wm_init(); /* init built-in window manager*/ #endif return 1; }
void GrRegisterInput(int fd) { SERVER_LOCK(); FD_SET(fd, ®fdset); if (fd >= regfdmax) regfdmax = fd + 1; SERVER_UNLOCK(); }
/* * Handles events after the client has done a select() call. * * Calls the specified callback function is an event has arrived, or if * there is data waiting on an external fd specified by GrRegisterInput(). * * Used by GrMainLoop(). * * @param rfdset Pointer to the file descriptor set containing those file * descriptors that are ready for reading. * @param fncb Pointer to the function to call when an event needs handling. */ void GrServiceSelect(void *rfdset, GR_FNCALLBACKEVENT fncb) { fd_set * rfds = rfdset; GR_EVENT_LIST * elp; GR_EVENT ev; int fd; SERVER_LOCK(); /* If data is present on the mouse fd, service it: */ if(mouse_fd >= 0 && FD_ISSET(mouse_fd, rfds)) while(GsCheckMouseEvent()) continue; /* If data is present on the keyboard fd, service it: */ if( (keyb_fd >= 0 && FD_ISSET(keyb_fd, rfds)) #ifdef MW_FEATURE_TWO_KEYBOARDS || (keyb2_fd >= 0 && FD_ISSET(keyb2_fd, rfds)) #endif ) while(GsCheckKeyboardEvent()) continue; /* Dispatch all queued events */ while((elp = curclient->eventhead) != NULL) { ev = elp->event; /* Remove first event from queue*/ curclient->eventhead = elp->next; if (curclient->eventtail == elp) curclient->eventtail = NULL; elp->next = eventfree; eventfree = elp; fncb(&ev); } /* check for input on registered file descriptors */ for (fd = 0; fd < regfdmax; fd++) { if (!FD_ISSET(fd, ®fdset) || !FD_ISSET(fd, rfds)) continue; ev.type = GR_EVENT_TYPE_FDINPUT; ev.fdinput.fd = fd; fncb(&ev); } SERVER_UNLOCK(); }
EXPORT_C #endif dbus_bool_t dbus_server_set_timeout_functions (DBusServer *server, DBusAddTimeoutFunction add_function, DBusRemoveTimeoutFunction remove_function, DBusTimeoutToggledFunction toggled_function, void *data, DBusFreeFunction free_data_function) { dbus_bool_t result; DBusTimeoutList *timeouts; _dbus_return_val_if_fail (server != NULL, FALSE); SERVER_LOCK (server); timeouts = server->timeouts; server->timeouts = NULL; if (timeouts) { SERVER_UNLOCK (server); result = _dbus_timeout_list_set_functions (timeouts, add_function, remove_function, toggled_function, data, free_data_function); SERVER_LOCK (server); } else { _dbus_warn_check_failed ("Re-entrant call to %s\n", _DBUS_FUNCTION_NAME); result = FALSE; } server->timeouts = timeouts; SERVER_UNLOCK (server); return result; }
EXPORT_C #endif dbus_bool_t dbus_server_set_watch_functions (DBusServer *server, DBusAddWatchFunction add_function, DBusRemoveWatchFunction remove_function, DBusWatchToggledFunction toggled_function, void *data, DBusFreeFunction free_data_function) { dbus_bool_t result; DBusWatchList *watches; _dbus_return_val_if_fail (server != NULL, FALSE); SERVER_LOCK (server); watches = server->watches; server->watches = NULL; if (watches) { SERVER_UNLOCK (server); result = _dbus_watch_list_set_functions (watches, add_function, remove_function, toggled_function, data, free_data_function); SERVER_LOCK (server); } else { _dbus_warn_check_failed ("Re-entrant call to %s\n", _DBUS_FUNCTION_NAME); result = FALSE; } server->watches = watches; SERVER_UNLOCK (server); return result; }
/** * Returns the address of the server, as a newly-allocated * string which must be freed by the caller. * * @param server the server * @returns the address or #NULL if no memory */ char* dbus_server_get_address (DBusServer *server) { char *retval; _dbus_return_val_if_fail (server != NULL, NULL); SERVER_LOCK (server); retval = _dbus_strdup (server->address); SERVER_UNLOCK (server); return retval; }
/** * Returns #TRUE if the server is still listening for new connections. * * @param server the server. */ dbus_bool_t dbus_server_get_is_connected (DBusServer *server) { dbus_bool_t retval; _dbus_return_val_if_fail (server != NULL, FALSE); SERVER_LOCK (server); retval = !server->disconnected; SERVER_UNLOCK (server); return retval; }
/** * Releases the server's address and stops listening for * new clients. If called more than once, only the first * call has an effect. Does not modify the server's * reference count. * * @param server the server. */ void dbus_server_disconnect (DBusServer *server) { _dbus_return_if_fail (server != NULL); dbus_server_ref (server); SERVER_LOCK (server); _dbus_server_disconnect_unlocked (server); SERVER_UNLOCK (server); dbus_server_unref (server); }
/* * Set an error handling routine, which will be called on any errors from * the server (when events are asked for by the client). If zero is given, * then errors will be returned as regular events. * Returns the previous error handler. */ GR_FNCALLBACKEVENT GrSetErrorHandler(GR_FNCALLBACKEVENT fncb) { GR_FNCALLBACKEVENT orig; SERVER_LOCK(); orig = ErrorFunc; ErrorFunc = fncb; SERVER_UNLOCK(); return orig; }
/** * Returns the unique ID of the server, as a newly-allocated * string which must be freed by the caller. This ID is * normally used by clients to tell when two #DBusConnection * would be equivalent (because the server address passed * to dbus_connection_open() will have the same guid in the * two cases). dbus_connection_open() can re-use an existing * connection with the same ID instead of opening a new * connection. * * This is an ID unique to each #DBusServer. Remember that * a #DBusServer represents only one mode of connecting, * so e.g. a bus daemon can listen on multiple addresses * which will mean it has multiple #DBusServer each with * their own ID. * * The ID is not a UUID in the sense of RFC4122; the details * are explained in the D-Bus specification. * * @param server the server * @returns the id of the server or #NULL if no memory */ char* dbus_server_get_id (DBusServer *server) { char *retval; _dbus_return_val_if_fail (server != NULL, NULL); SERVER_LOCK (server); retval = NULL; _dbus_string_copy_data (&server->guid_hex, &retval); SERVER_UNLOCK (server); return retval; }
static dbus_bool_t protected_change_watch (DBusServer *server, DBusWatch *watch, DBusWatchAddFunction add_function, DBusWatchRemoveFunction remove_function, DBusWatchToggleFunction toggle_function, dbus_bool_t enabled) { DBusWatchList *watches; dbus_bool_t retval; HAVE_LOCK_CHECK (server); /* This isn't really safe or reasonable; a better pattern is the "do * everything, then drop lock and call out" one; but it has to be * propagated up through all callers */ watches = server->watches; if (watches) { server->watches = NULL; _dbus_server_ref_unlocked (server); SERVER_UNLOCK (server); if (add_function) retval = (* add_function) (watches, watch); else if (remove_function) { retval = TRUE; (* remove_function) (watches, watch); } else { retval = TRUE; (* toggle_function) (watches, watch, enabled); } SERVER_LOCK (server); server->watches = watches; _dbus_server_unref_unlocked (server); return retval; } else return FALSE; }
static dbus_bool_t protected_change_timeout (DBusServer *server, DBusTimeout *timeout, DBusTimeoutAddFunction add_function, DBusTimeoutRemoveFunction remove_function, DBusTimeoutToggleFunction toggle_function, dbus_bool_t enabled) { DBusTimeoutList *timeouts; dbus_bool_t retval; HAVE_LOCK_CHECK (server); /* This isn't really safe or reasonable; a better pattern is the "do everything, then * drop lock and call out" one; but it has to be propagated up through all callers */ timeouts = server->timeouts; if (timeouts) { server->timeouts = NULL; _dbus_server_ref_unlocked (server); SERVER_UNLOCK (server); if (add_function) retval = (* add_function) (timeouts, timeout); else if (remove_function) { retval = TRUE; (* remove_function) (timeouts, timeout); } else { retval = TRUE; (* toggle_function) (timeouts, timeout, enabled); } SERVER_LOCK (server); server->timeouts = timeouts; _dbus_server_unref_unlocked (server); return retval; } else return FALSE; }
/** * Increments the reference count of a DBusServer. * * @param server the server. * @returns the server */ DBusServer * dbus_server_ref (DBusServer *server) { _dbus_return_val_if_fail (server != NULL, NULL); _dbus_return_val_if_fail (server->refcount.value > 0, NULL); #ifdef DBUS_HAVE_ATOMIC_INT _dbus_atomic_inc (&server->refcount); #else SERVER_LOCK (server); _dbus_assert (server->refcount.value > 0); server->refcount.value += 1; SERVER_UNLOCK (server); #endif return server; }
/** * Retrieves data previously set with dbus_server_set_data(). * The slot must still be allocated (must not have been freed). * * @param server the server * @param slot the slot to get data from * @returns the data, or #NULL if not found */ void* dbus_server_get_data (DBusServer *server, int slot) { void *res; _dbus_return_val_if_fail (server != NULL, NULL); SERVER_LOCK (server); res = _dbus_data_slot_list_get (&slot_allocator, &server->slot_list, slot); SERVER_UNLOCK (server); return res; }
/* * Prepare for the client to call select(). Asks the server to send the next * event but does not wait around for it to arrive. Initializes the * specified fd_set structure with the client/server socket descriptor and any * previously registered external file descriptors. Also compares the current * contents of maxfd, the client/server socket descriptor, and the previously * registered external file descriptors, and returns the highest of them in * maxfd. * * Usually used in conjunction with GrServiceSelect(). * * Note that in a multithreaded client, the application must ensure that * no Nano-X calls are made between the calls to GrPrepareSelect() and * GrServiceSelect(), else there will be race conditions. * * @param maxfd Pointer to a variable which the highest in use fd will be * written to. Must contain a valid value on input - will only * be overwritten if the new value is higher than the old * value. * @param rfdset Pointer to the file descriptor set structure to use. Must * be valid on input - file descriptors will be added to this * set without clearing the previous contents. */ void GrPrepareSelect(int *maxfd, void *rfdset) { fd_set *rfds = (fd_set *) rfdset; int fd; SERVER_LOCK(); /* perform pre-select duties, if any*/ if(rootwp->psd->PreSelect) rootwp->psd->PreSelect(rootwp->psd); if(mouse_fd >= 0) { FD_SET(mouse_fd, rfds); if (mouse_fd > *maxfd) *maxfd = mouse_fd; } if(keyb_fd >= 0) { FD_SET(keyb_fd, rfds); if (keyb_fd > *maxfd) *maxfd = keyb_fd; } #ifdef MW_FEATURE_TWO_KEYBOARDS if(keyb2_fd >= 0) { FD_SET(keyb2_fd, rfds); if (keyb2_fd > *maxfd) *maxfd = keyb2_fd; } #endif /* handle registered input file descriptors*/ for (fd = 0; fd < regfdmax; fd++) { if (!FD_ISSET(fd, ®fdset)) continue; FD_SET(fd, rfds); if (fd > *maxfd) *maxfd = fd; } SERVER_UNLOCK(); }
/** * Releases the server's address and stops listening for * new clients. If called more than once, only the first * call has an effect. Does not modify the server's * reference count. * * @param server the server. */ void dbus_server_disconnect (DBusServer *server) { _dbus_return_if_fail (server != NULL); dbus_server_ref (server); SERVER_LOCK (server); _dbus_assert (server->vtable->disconnect != NULL); if (!server->disconnected) { /* this has to be first so recursive calls to disconnect don't happen */ server->disconnected = TRUE; (* server->vtable->disconnect) (server); } SERVER_UNLOCK (server); dbus_server_unref (server); }
void GrUnregisterInput(int fd) { int i, max; SERVER_LOCK(); /* unregister all inputs if the FD is -1 */ if (fd == -1) { FD_ZERO(®fdset); regfdmax = -1; SERVER_UNLOCK(); return; } FD_CLR(fd, ®fdset); /* recalculate the max file descriptor */ for (i = 0, max = regfdmax, regfdmax = -1; i < max; i++) if (FD_ISSET(i, ®fdset)) regfdmax = i + 1; SERVER_UNLOCK(); }
/* * Initialize the graphics and mouse devices at startup. * Returns nonzero with a message printed if the initialization failed. */ int GsInitialize(void) { GR_WINDOW *wp; /* root window */ PSD psd; GR_CURSOR_ID cid; static MWIMAGEBITS cursorbits[16] = { 0xe000, 0x9800, 0x8600, 0x4180, 0x4060, 0x2018, 0x2004, 0x107c, 0x1020, 0x0910, 0x0988, 0x0544, 0x0522, 0x0211, 0x000a, 0x0004 }; static MWIMAGEBITS cursormask[16] = { 0xe000, 0xf800, 0xfe00, 0x7f80, 0x7fe0, 0x3ff8, 0x3ffc, 0x1ffc, 0x1fe0, 0x0ff0, 0x0ff8, 0x077c, 0x073e, 0x021f, 0x000e, 0x0004 }; /* If needed, initialize the server mutex. */ SERVER_LOCK_INIT(); setbuf(stdout, NULL); setbuf(stderr, NULL); wp = (GR_WINDOW *) malloc(sizeof(GR_WINDOW)); if (wp == NULL) { EPRINTF("Cannot allocate root window\n"); return -1; } startTicks = GsGetTickCount(); #ifndef MW_NOSIGNALS /* catch terminate signal to restore tty state*/ signal(SIGTERM, (void *)GsTerminate); #endif #if MW_FEATURE_TIMERS screensaver_delay = 0; #endif screensaver_active = GR_FALSE; selection_owner.wid = 0; selection_owner.typelist = NULL; #if !NONETWORK #ifndef MW_NOSIGNALS /* ignore pipe signal, sent when clients exit*/ signal(SIGPIPE, SIG_IGN); signal(SIGHUP, SIG_IGN); #endif if (GsOpenSocket() < 0) { EPRINTF("Cannot bind to named socket\n"); free(wp); return -1; } #endif if ((keyb_fd = GdOpenKeyboard()) == -1) { EPRINTF("Cannot initialise keyboard\n"); /*GsCloseSocket();*/ free(wp); return -1; } #ifdef MW_FEATURE_TWO_KEYBOARDS if ((keyb2_fd = GdOpenKeyboard2()) == -1) { EPRINTF("Cannot initialise second keyboard\n"); /*GsCloseSocket();*/ free(wp); return -1; } #endif if ((psd = GdOpenScreen()) == NULL) { EPRINTF("Cannot initialise screen\n"); /*GsCloseSocket();*/ GdCloseKeyboard(); free(wp); return -1; } GdSetPortraitMode(psd, portraitmode); if ((mouse_fd = GdOpenMouse()) == -1) { EPRINTF("Cannot initialise mouse\n"); /*GsCloseSocket();*/ GdCloseScreen(psd); GdCloseKeyboard(); free(wp); return -1; } /* * Create std font. */ #if (HAVE_BIG5_SUPPORT | HAVE_GB2312_SUPPORT | HAVE_JISX0213_SUPPORT | HAVE_KSC5601_SUPPORT) /* system fixed font looks better when mixed with builtin fixed fonts*/ stdfont = GdCreateFont(psd, MWFONT_SYSTEM_FIXED, 0, NULL); #else stdfont = GdCreateFont(psd, MWFONT_SYSTEM_VAR, 0, NULL); #endif /* * Initialize the root window. */ wp->psd = psd; wp->id = GR_ROOT_WINDOW_ID; wp->parent = NULL; /* changed: was = NULL*/ wp->owner = NULL; wp->children = NULL; wp->siblings = NULL; wp->next = NULL; wp->x = 0; wp->y = 0; wp->width = psd->xvirtres; wp->height = psd->yvirtres; wp->bordersize = 0; wp->background = BLACK; wp->bordercolor = wp->background; wp->nopropmask = 0; wp->bgpixmap = NULL; wp->bgpixmapflags = GR_BACKGROUND_TILE; wp->eventclients = NULL; wp->cursorid = 0; wp->mapped = GR_TRUE; wp->realized = GR_TRUE; wp->output = GR_TRUE; wp->props = 0; wp->title = NULL; wp->clipregion = NULL; listpp = NULL; listwp = wp; rootwp = wp; focuswp = wp; mousewp = wp; focusfixed = GR_FALSE; /* * Initialize and position the default cursor. */ curcursor = NULL; cursorx = -1; cursory = -1; GdShowCursor(psd); GsMoveCursor(psd->xvirtres / 2, psd->yvirtres / 2); SERVER_UNLOCK(); cid = GrNewCursor(16, 16, 0, 0, WHITE, BLACK, cursorbits, cursormask); GrSetWindowCursor(GR_ROOT_WINDOW_ID, cid); SERVER_LOCK(); stdcursor = GsFindCursor(cid); #if VTSWITCH MwInitVt(); /* Check for VT change every 50 ms: */ GdAddTimer(50, CheckVtChange, NULL); #endif psd->FillRect(psd, 0, 0, psd->xvirtres-1, psd->yvirtres-1, GdFindColor(psd, wp->background)); /* * Tell the mouse driver some things. */ curbuttons = 0; GdRestrictMouse(0, 0, psd->xvirtres - 1, psd->yvirtres - 1); GdMoveMouse(psd->xvirtres / 2, psd->yvirtres / 2); /* Force root window screen paint*/ GsRedrawScreen(); /* * Force the cursor to appear on the screen at startup. * (not required with above GsRedrawScreen) GdHideCursor(psd); GdShowCursor(psd); */ /* * All done. */ connectcount = 0; return 0; }
static dbus_bool_t socket_handle_watch (DBusWatch *watch, unsigned int flags, void *data) { DBusServer *server = data; DBusServerSocket *socket_server = data; #ifndef DBUS_DISABLE_ASSERT int i; dbus_bool_t found = FALSE; #endif SERVER_LOCK (server); #ifndef DBUS_DISABLE_ASSERT for (i = 0 ; i < socket_server->n_fds ; i++) { if (socket_server->watch[i] == watch) found = TRUE; } _dbus_assert (found); #endif _dbus_verbose ("Handling client connection, flags 0x%x\n", flags); if (flags & DBUS_WATCH_READABLE) { int client_fd; int listen_fd; listen_fd = dbus_watch_get_socket (watch); if (socket_server->noncefile) client_fd = _dbus_accept_with_noncefile (listen_fd, socket_server->noncefile); else client_fd = _dbus_accept (listen_fd); if (client_fd < 0) { /* EINTR handled for us */ if (_dbus_get_is_errno_eagain_or_ewouldblock ()) _dbus_verbose ("No client available to accept after all\n"); else _dbus_verbose ("Failed to accept a client connection: %s\n", _dbus_strerror_from_errno ()); SERVER_UNLOCK (server); } else { if (!handle_new_client_fd_and_unlock (server, client_fd)) _dbus_verbose ("Rejected client connection due to lack of memory\n"); } } if (flags & DBUS_WATCH_ERROR) _dbus_verbose ("Error on server listening socket\n"); if (flags & DBUS_WATCH_HANGUP) _dbus_verbose ("Hangup on server listening socket\n"); return TRUE; }
/** * Creates a new server listening on the given file descriptor. The * file descriptor should be nonblocking (use * _dbus_set_fd_nonblocking() to make it so). The file descriptor * should be listening for connections, that is, listen() should have * been successfully invoked on it. The server will use accept() to * accept new client connections. * * @param fds list of file descriptors. * @param n_fds number of file descriptors * @param address the server's address * @param noncefile to be used for authentication (NULL if not needed) * @returns the new server, or #NULL if no memory. * */ DBusServer* _dbus_server_new_for_socket (int *fds, int n_fds, const DBusString *address, DBusNonceFile *noncefile) { DBusServerSocket *socket_server; DBusServer *server; int i; socket_server = dbus_new0 (DBusServerSocket, 1); if (socket_server == NULL) return NULL; socket_server->noncefile = noncefile; socket_server->fds = dbus_new (int, n_fds); if (!socket_server->fds) goto failed_0; socket_server->watch = dbus_new0 (DBusWatch *, n_fds); if (!socket_server->watch) goto failed_1; for (i = 0 ; i < n_fds ; i++) { DBusWatch *watch; watch = _dbus_watch_new (fds[i], DBUS_WATCH_READABLE, TRUE, socket_handle_watch, socket_server, NULL); if (watch == NULL) goto failed_2; socket_server->n_fds++; socket_server->fds[i] = fds[i]; socket_server->watch[i] = watch; } if (!_dbus_server_init_base (&socket_server->base, &socket_vtable, address)) goto failed_2; server = (DBusServer*)socket_server; SERVER_LOCK (server); for (i = 0 ; i < n_fds ; i++) { if (!_dbus_server_add_watch (&socket_server->base, socket_server->watch[i])) { int j; for (j = 0 ; j < i ; j++) _dbus_server_remove_watch (server, socket_server->watch[j]); SERVER_UNLOCK (server); _dbus_server_finalize_base (&socket_server->base); goto failed_2; } } SERVER_UNLOCK (server); return (DBusServer*) socket_server; failed_2: for (i = 0 ; i < n_fds ; i++) { if (socket_server->watch[i] != NULL) { _dbus_watch_unref (socket_server->watch[i]); socket_server->watch[i] = NULL; } } dbus_free (socket_server->watch); failed_1: dbus_free (socket_server->fds); failed_0: dbus_free (socket_server); return NULL; }
static void server_lock (void *server) { SERVER_LOCK (((DBusServer *) server)); }
void GsSelect(GR_TIMEOUT timeout) { fd_set rfds; int e; int setsize = 0; struct timeval tout; struct timeval *to; #if NONETWORK int fd; #endif #if HAVE_VNCSERVER #if VNCSERVER_PTHREADED int dummy; #else rfbClientIteratorPtr i; rfbClientPtr cl; #endif #endif /* X11/SDL perform single update of aggregate screen update region*/ if (scrdev.PreSelect) { /* returns # pending events*/ if (scrdev.PreSelect(&scrdev)) { /* poll for mouse data and service if found*/ while (GsCheckMouseEvent()) continue; /* poll for keyboard data and service if found*/ while (GsCheckKeyboardEvent()) continue; /* events found, return with no sleep*/ return; } } /* Set up the FDs for use in the main select(): */ FD_ZERO(&rfds); if(mouse_fd >= 0) { FD_SET(mouse_fd, &rfds); if (mouse_fd > setsize) setsize = mouse_fd; } if(keyb_fd >= 0) { FD_SET(keyb_fd, &rfds); if (keyb_fd > setsize) setsize = keyb_fd; } #if MW_FEATURE_TWO_KEYBOARDS if(keyb2_fd >= 0) { FD_SET(keyb2_fd, &rfds); if (keyb2_fd > setsize) setsize = keyb2_fd; } #endif #if NONETWORK /* handle registered input file descriptors*/ for (fd = 0; fd < regfdmax; fd++) { if (!FD_ISSET(fd, ®fdset)) continue; FD_SET(fd, &rfds); if (fd > setsize) setsize = fd; } #else /* !NONETWORK */ /* handle client socket connections*/ FD_SET(un_sock, &rfds); if (un_sock > setsize) setsize = un_sock; curclient = root_client; while(curclient) { if(curclient->waiting_for_event && curclient->eventhead) { curclient->waiting_for_event = FALSE; GrGetNextEventWrapperFinish(curclient->id); return; } FD_SET(curclient->id, &rfds); if(curclient->id > setsize) setsize = curclient->id; curclient = curclient->next; } #endif /* NONETWORK */ #if HAVE_VNCSERVER #if VNCSERVER_PTHREADED /* Add file vnc thread fd. This is useful to force handling of events generated by the VNC thread*/ FD_SET( vnc_thread_fd, &(rfds) ); if ( vnc_thread_fd > setsize ) setsize = vnc_thread_fd; #else /* Add all VNC open sockets to nano-X select set */ FD_SET( rfbScreen->listenSock, &(rfds) ); if ( rfbScreen->listenSock > setsize ) setsize = rfbScreen->listenSock; FD_SET( rfbScreen->httpListenSock, &(rfds) ); if ( rfbScreen->httpListenSock > setsize ) setsize = rfbScreen->httpListenSock; i = rfbGetClientIterator(rfbScreen); cl = rfbClientIteratorNext(i); while ( cl ) { if ( cl->sock >= 0 ) { FD_SET( cl->sock, &(rfds) ); if ( cl->sock > setsize ) setsize = cl->sock; } cl = rfbClientIteratorNext(i); } rfbReleaseClientIterator(i); #endif #endif /* HAVE_VNCSERVER*/ /* setup timeval struct for block or poll in select()*/ tout.tv_sec = tout.tv_usec = 0; /* setup for assumed poll*/ to = &tout; int poll = (timeout == (GR_TIMEOUT) -1L); /* timeout = -1 means just poll*/ if (!poll) { #if MW_FEATURE_TIMERS /* get next timer or use passed timeout and convert to timeval struct*/ if (!GdGetNextTimeout(&tout, timeout)) /* no app timers or VTSWITCH?*/ #else if (timeout) /* setup mwin poll timer*/ { /* convert wait timeout to timeval struct*/ tout.tv_sec = timeout / 1000; tout.tv_usec = (timeout % 1000) * 1000; } else #endif { to = NULL; /* no timers, block*/ } } /* some drivers can't block in select as backend is poll based (SDL)*/ if (scrdev.flags & PSF_CANTBLOCK) { #define WAITTIME 100 /* check if would block permanently or timeout > WAITTIME*/ if (to == NULL || tout.tv_sec != 0 || tout.tv_usec > WAITTIME) { /* override timeouts and wait for max WAITTIME ms*/ to = &tout; tout.tv_sec = 0; tout.tv_usec = WAITTIME; } } /* Wait for some input on any of the fds in the set or a timeout*/ #if NONETWORK SERVER_UNLOCK(); /* allow other threads to run*/ #endif e = select(setsize+1, &rfds, NULL, NULL, to); #if NONETWORK SERVER_LOCK(); #endif if(e > 0) /* input ready*/ { /* service mouse file descriptor*/ if(mouse_fd >= 0 && FD_ISSET(mouse_fd, &rfds)) while(GsCheckMouseEvent()) continue; /* service keyboard file descriptor*/ if( (keyb_fd >= 0 && FD_ISSET(keyb_fd, &rfds)) #if MW_FEATURE_TWO_KEYBOARDS || (keyb2_fd >= 0 && FD_ISSET(keyb2_fd, &rfds)) #endif ) while(GsCheckKeyboardEvent()) continue; #if HAVE_VNCSERVER && VNCSERVER_PTHREADED if(vnc_thread_fd >= 0 && FD_ISSET(vnc_thread_fd, &rfds)) /* Read from vnc pipe */ read( vnc_thread_fd, &dummy, sizeof(int)); #endif #if NONETWORK /* check for input on registered file descriptors */ for (fd = 0; fd < regfdmax; fd++) { GR_EVENT_FDINPUT * gp; if (!FD_ISSET(fd, ®fdset) || !FD_ISSET(fd, &rfds)) continue; gp = (GR_EVENT_FDINPUT *)GsAllocEvent(curclient); if(gp) { gp->type = GR_EVENT_TYPE_FDINPUT; gp->fd = fd; } } #else /* !NONETWORK */ /* If a client is trying to connect, accept it: */ if(FD_ISSET(un_sock, &rfds)) GsAcceptClient(); /* If a client is sending us a command, handle it: */ curclient = root_client; while (curclient) { GR_CLIENT *curclient_next; /* curclient may be freed in GsDropClient*/ curclient_next = curclient->next; if(FD_ISSET(curclient->id, &rfds)) GsHandleClient(curclient->id); curclient = curclient_next; } #if HAVE_VNCSERVER && !VNCSERVER_PTHREADED rfbProcessEvents(rfbScreen, 0); #endif #endif /* NONETWORK */ } else if (e == 0) /* timeout*/ { #if NONETWORK /* * Timeout has occured. Currently return a timeout event * regardless of whether client has selected for it. * Note: this will be changed back to GR_EVENT_TYPE_NONE * for the GrCheckNextEvent/LINK_APP_TO_SERVER case */ #if MW_FEATURE_TIMERS if(GdTimeout()) #endif { GR_EVENT_GENERAL * gp; if ((gp = (GR_EVENT_GENERAL *)GsAllocEvent(curclient)) != NULL) gp->type = GR_EVENT_TYPE_TIMEOUT; } #else /* !NONETWORK */ #if MW_FEATURE_TIMERS /* check for timer timeouts and service if found*/ GdTimeout(); #endif #endif /* NONETWORK */ } else if(errno != EINTR) EPRINTF("Select() call in main failed\n"); }