/******************************************************************************\ Disconnect a client from the server. \******************************************************************************/ void N_drop_client(int client) { /* If we're not the server just disconnect */ if (n_client_id != N_HOST_CLIENT_ID) { C_assert(client == N_SERVER_ID); N_disconnect(); return; } C_assert(client >= 0 && client < N_CLIENTS_MAX); if (!n_clients[client].connected) { C_warning("Tried to drop unconnected client %d", client); return; } n_clients[client].connected = FALSE; n_clients[client].buffer_len = 0; n_clients_num--; /* The server kicked itself */ if (client == n_client_id) { N_disconnect(); C_debug("Server dropped itself"); return; } n_server_func(client, N_EV_DISCONNECTED); closesocket(n_clients[client].socket); C_debug("Dropped client %d", client); }
/******************************************************************************\ Adds a button to a toolbar widget. The window opened by the icon button is initialized with [init_func]. This function should set the window's size as the root window does not pack child windows. The window's origin is controlled by the toolbar. Returns the new button's index. \******************************************************************************/ int I_toolbar_add_button(i_toolbar_t *toolbar, const char *icon, i_callback_f init_func) { i_button_t *button; i_window_t *window; C_assert(toolbar->children < I_TOOLBAR_BUTTONS); /* Pad the previous button */ if (toolbar->children) { button = toolbar->buttons + toolbar->children - 1; button->widget.margin_rear = 0.5f; } /* Add a new button */ button = toolbar->buttons + toolbar->children; I_button_init(button, icon, NULL, I_BT_SQUARE); button->on_click = (i_callback_f)toolbar_button_click; button->data = toolbar; I_widget_add(&toolbar->window.widget, &button->widget); /* Initialize the window */ window = toolbar->windows + toolbar->children; init_func(window); window->widget.shown = FALSE; window->auto_hide = TRUE; window->hanger_align = &button->widget; I_widget_add(&i_root, &window->widget); return toolbar->children++; }
/******************************************************************************\ Read the cargo contents to the message receive buffer. If [ignore_prices] is TRUE, price settings will not be overwritten. \******************************************************************************/ void G_store_receive(g_store_t *store, bool ignore_prices) { int i, modified; C_assert(N_CLIENTS_MAX <= 32); modified = N_receive_int(); if (!modified) return; for (i = 0; i < G_CARGO_TYPES; i++) { g_cargo_t *cargo; if (!(modified & (1 << i))) continue; cargo = store->cargo + i; cargo->amount = N_receive_short(); if (ignore_prices) { N_receive_short(); N_receive_short(); N_receive_short(); N_receive_short(); continue; } cargo->buy_price = N_receive_short(); cargo->sell_price = N_receive_short(); cargo->auto_buy = cargo->buy_price >= 0; cargo->auto_sell = cargo->sell_price >= 0; cargo->minimum = N_receive_short(); cargo->maximum = N_receive_short(); } G_store_space(store); }
//-- Probe focus for each widget, till some get it (forward scan) void FormWidget::CycleFocus( int mode ) { if (!!_cycler && !_dont_cycle ) { if ( mode==NEXT || mode==PREVIOUS ) { Widget *begin = _cycler->Who(); bool accepted = false; int loops=2;//W/A @todo int dbg_iterations = 0; int dbg_n_visible = 0; do { switch (mode) { case NEXT: loops -= !_cycler->CycleForward(); break; case PREVIOUS: loops -= !_cycler->CycleBack(); break; } if ( !loops ) { break; } if ( !_cycler->Who() ) { loops=0; break; }// Break if cycler is not valid if ( _cycler->Who()->IsRealyVisible() ) // Widget must be visible { Widget *next = _cycler->Who(); if ( &next->GetEnvironment()->GetForm() == this ) accepted = next->Accept( InputFocus() ); ++dbg_n_visible; } ++dbg_iterations; } while ( !accepted && begin!=_cycler->Who() && loops>0 ); if ( accepted ) { C_assert( _actual_focus == _cycler->Who()); } else { if (!loops) { CycleParentForm( mode ); } else { assert( begin==_cycler->Who() ); if ( begin->IsRealyVisible() && begin!=this ) { accepted = begin->Accept( InputFocus() ); } else { FocusRelease(); } } } }// end if (mode==NEXT || mode==PREVIOUS) } }
/******************************************************************************\ Initializes a widget name field with a unique name that includes the widget's class. \******************************************************************************/ void I_widget_init(i_widget_t *widget, const char *class_name) { C_assert(widget); C_zero(widget); snprintf(widget->name, sizeof (widget->name), "widget #%u (%s)", widgets++, class_name); if (c_mem_check.value.n && i_debug.value.n) C_trace("Initialized %s", widget->name); widget->shown = TRUE; }
/******************************************************************************\ Configure a specific player. \******************************************************************************/ void I_configure_player(int index, const char *name, i_color_t color, bool host) { C_assert(index >= 0 && index < PLAYERS); configure_player(index, name, color, host); I_widget_event(&players[index].box.widget, I_EV_CONFIGURE); /* Window may need repacking */ I_widget_event(I_widget_top_level(&players[index].box.widget), I_EV_CONFIGURE); }
//-- Mark given widget as focussed void FormWidget::SetFocussed( Widget *widget ) { C_assert( &widget->GetEnvironment()->GetForm() == this ); //C_assert( _actual_focus != widget); _dont_cycle = true; Widget *previous = _actual_focus; if ( _cycler->Set(widget) && GetEnvironment() && widget!=_actual_focus ) { if ( !HasFocus() ) { Form &parent_form= GetEnvironment()->GetForm(); parent_form.SetFocussed(this); } _actual_focus = _cycler->Who(); _actual_focus->OnFocus.Send(); C_assert( _actual_focus != previous); if ( previous ) { previous->OffFocus.Send(); } } _dont_cycle = false; }
/******************************************************************************\ Add a button to the ring. \******************************************************************************/ void I_add_to_ring(i_ring_icon_t icon, int enabled, const char *title, const char *sub) { C_assert(icon >= 0 && icon < I_RING_ICONS); /* Show the button */ if (!button_widgets[icon].widget.shown) { I_widget_event(&button_widgets[icon].widget, I_EV_SHOW); buttons++; } button_widgets[icon].widget.state = enabled ? I_WS_READY : I_WS_DISABLED; /* Save the detail information */ C_strncpy_buf(details[icon], title); C_strncpy_buf(detail_subs[icon], sub); }
/******************************************************************************\ Add the cargo contents to the current network message. Note that this call does not actually send the information, you must finish and send the message yourself with N_send(NULL). If [force] is TRUE, modified status is ignored and unchanged after this call. \******************************************************************************/ void G_store_send(g_store_t *store, bool force) { int i; C_assert(N_CLIENTS_MAX <= 32); N_send_int(force ? -1 : store->modified); for (i = 0; i < G_CARGO_TYPES; i++) { g_cargo_t *cargo; if (!force && !(store->modified & (1 << i))) continue; cargo = store->cargo + i; N_send_short(cargo->amount); N_send_short(cargo->auto_buy ? cargo->buy_price : -1); N_send_short(cargo->auto_sell ? cargo->sell_price : -1); N_send_short(cargo->minimum); N_send_short(cargo->maximum); } if (!force) store->modified = 0; }
//-- Assign focus to any widget //-- This action is being taken when this Form gains focus void FormWidget::AssignFocus() { assert( _form_enabled ); if ( _actual_focus && !_actual_focus->IsRealyVisible()) { InvalidateFocus(_actual_focus); } if ( !_actual_focus && !_dont_cycle ) { if ( !_cycler || !_stored_focus ) { if ( !_default_focus || !_default_focus->Accept(InputFocus()) ) { _cycler = new WidgetCycler(this); CycleFocus( NEXT ); } else { C_assert( _default_focus == _cycler->Who() ); } } else if ( _stored_focus ) // check if stored ptr is valid { _cycler = new WidgetCycler(this); do if ( _cycler->Who()==_stored_focus ) { SetFocussed(_stored_focus); break; } while ( _cycler->CycleForward()); _stored_focus=NULL; } } }
/******************************************************************************\ Add or subtract cargo from a store. Returns the amount actually added or subtracted. \******************************************************************************/ int G_store_add(g_store_t *store, g_cargo_type_t cargo, int amount) { int excess; /* Store is already overflowing */ if (store->space_used > store->capacity) return 0; store->modified |= 1 << cargo; /* Don't take more than what's there */ if (amount < -store->cargo[cargo].amount) amount = -store->cargo[cargo].amount; /* Don't put in more than it can hold */ store->cargo[cargo].amount += amount; if ((excess = G_store_space(store) - store->capacity) > 0) { store->cargo[cargo].amount -= (int)(excess / cargo_space(cargo)); store->space_used = store->capacity; } C_assert(store->cargo[cargo].amount >= 0); return amount; }
/******************************************************************************\ Popup zoom button was clicked. \******************************************************************************/ static void popup_zoom(void) { C_assert(popup_messages[0].has_goto_pos); R_rotate_cam_to(popup_messages[0].goto_pos); }