diff --git a/src/config.c b/src/config.c index b0c73e0d0..0c6c0e28b 100644 --- a/src/config.c +++ b/src/config.c @@ -1214,6 +1214,11 @@ load_network(void) } else { strcpy(net_cards_conf[c].host_dev_name, "none"); } + + sprintf(temp, "net_%02i_link", c +1); + net_cards_conf[c].link_state = config_get_int(cat, temp, + (NET_LINK_10_HD|NET_LINK_10_FD|NET_LINK_100_HD|NET_LINK_100_FD|NET_LINK_1000_HD|NET_LINK_1000_FD)); + } } @@ -2767,6 +2772,13 @@ save_network(void) /* config_set_string(cat, temp, "none"); */ config_delete_var(cat, temp); } + + sprintf(temp, "net_%02i_link", c + 1); + if (net_cards_conf[c].link_state == (NET_LINK_10_HD|NET_LINK_10_FD|NET_LINK_100_HD|NET_LINK_100_FD|NET_LINK_1000_HD|NET_LINK_1000_FD)) { + config_delete_var(cat, temp); + } else { + config_set_int(cat, temp, net_cards_conf[c].link_state); + } } delete_section_if_empty(cat); diff --git a/src/include/86box/machine_status.h b/src/include/86box/machine_status.h index 2afed078e..6baafeeb0 100644 --- a/src/include/86box/machine_status.h +++ b/src/include/86box/machine_status.h @@ -21,7 +21,7 @@ typedef struct { dev_status_empty_active_t mo[MO_NUM]; dev_status_empty_active_t cassette; dev_status_active_t hdd[HDD_BUS_USB]; - dev_status_active_t net; + dev_status_active_t net[NET_CARD_MAX]; dev_status_empty_t cartridge[2]; } machine_status_t; diff --git a/src/include/86box/network.h b/src/include/86box/network.h index 4f9e6b70e..f294bf500 100644 --- a/src/include/86box/network.h +++ b/src/include/86box/network.h @@ -65,6 +65,17 @@ #define NET_PERIOD_10M 0.8 #define NET_PERIOD_100M 0.08 +enum { + NET_LINK_DOWN = (1 << 1), + NET_LINK_TEMP_DOWN = (1 << 2), + NET_LINK_10_HD = (1 << 3), + NET_LINK_10_FD = (1 << 4), + NET_LINK_100_HD = (1 << 5), + NET_LINK_100_FD = (1 << 6), + NET_LINK_1000_HD = (1 << 7), + NET_LINK_1000_FD = (1 << 8), +}; + /* Supported network cards. */ enum { NONE = 0, @@ -84,14 +95,14 @@ typedef struct { int device_num; int net_type; char host_dev_name[128]; + uint32_t link_state; } netcard_conf_t; extern netcard_conf_t net_cards_conf[NET_CARD_MAX]; extern int net_card_current; typedef int (*NETRXCB)(void *, uint8_t *, int); -typedef int (*NETWAITCB)(void *); -typedef int (*NETSETLINKSTATE)(void *); +typedef int (*NETSETLINKSTATE)(void *, uint32_t link_state); typedef struct netpkt { @@ -121,9 +132,7 @@ struct _netcard_t { const device_t *device; void *card_drv; struct netdrv_t host_drv; - int (*poll)(void *); NETRXCB rx; - NETWAITCB wait; NETSETLINKSTATE set_link_state; netqueue_t queues[3]; netpkt_t queued_pkt; @@ -132,6 +141,9 @@ struct _netcard_t { pc_timer_t timer; int card_num; double byte_period; + uint32_t led_timer; + uint32_t led_state; + uint32_t link_state; }; typedef struct { @@ -152,7 +164,7 @@ extern netdev_t network_devs[NET_HOST_INTF_MAX]; /* Function prototypes. */ extern void network_init(void); -extern netcard_t *network_attach(void *card_drv, uint8_t *mac, NETRXCB rx, NETWAITCB wait, NETSETLINKSTATE set_link_state); +extern netcard_t *network_attach(void *card_drv, uint8_t *mac, NETRXCB rx, NETSETLINKSTATE set_link_state); extern void netcard_close(netcard_t *card); extern void network_close(void); extern void network_reset(void); @@ -161,6 +173,9 @@ extern void network_tx(netcard_t *card, uint8_t *, int); extern int net_pcap_prepare(netdev_t *); +extern void network_connect(int id, int connect); +extern int network_is_connected(int id); +extern int network_dev_available(int); extern int network_dev_to_id(char *); extern int network_card_available(int); extern int network_card_has_config(int); diff --git a/src/machine_status.c b/src/machine_status.c index 258c16821..3031c9ad3 100644 --- a/src/machine_status.c +++ b/src/machine_status.c @@ -19,6 +19,8 @@ #include <86box/zip.h> #include <86box/mo.h> #include <86box/hdd.h> +#include <86box/thread.h> +#include <86box/network.h> #include <86box/machine_status.h> machine_status_t machine_status; @@ -48,5 +50,7 @@ machine_status_init() { machine_status.hdd[i].active = false; } - machine_status.net.active = false; + for (size_t i = 0; i < NET_CARD_MAX; i++) { + machine_status.net[i].active = false; + } } \ No newline at end of file diff --git a/src/network/net_3c503.c b/src/network/net_3c503.c index d54a00593..2e5c97519 100644 --- a/src/network/net_3c503.c +++ b/src/network/net_3c503.c @@ -619,7 +619,7 @@ threec503_nic_init(const device_t *info) dev->regs.gacfr = 0x09; /* Start with RAM mapping enabled. */ /* Attach ourselves to the network module. */ - dev->dp8390->card = network_attach(dev->dp8390, dev->dp8390->physaddr, dp8390_rx, NULL, NULL); + dev->dp8390->card = network_attach(dev->dp8390, dev->dp8390->physaddr, dp8390_rx, NULL); return(dev); } diff --git a/src/network/net_dp8390.c b/src/network/net_dp8390.c index c9908f883..ad4345ae6 100644 --- a/src/network/net_dp8390.c +++ b/src/network/net_dp8390.c @@ -228,7 +228,9 @@ dp8390_write_cr(dp8390_t *dev, uint32_t val) /* Send the packet to the system driver */ dev->CR.tx_packet = 1; - network_tx(dev->card, &dev->mem[(dev->tx_page_start * 256) - dev->mem_start], dev->tx_bytes); + /* TODO: report TX error to the driver ? */ + if (!(dev->card->link_state & NET_LINK_DOWN)) + network_tx(dev->card, &dev->mem[(dev->tx_page_start * 256) - dev->mem_start], dev->tx_bytes); /* some more debug */ #ifdef ENABLE_DP8390_LOG @@ -291,6 +293,8 @@ dp8390_rx_common(void *priv, uint8_t *buf, int io_len) if ((dev->CR.stop != 0) || (dev->page_start == 0)) return 0; + if (dev->card->link_state & NET_LINK_DOWN) + return 0; /* * Add the pkt header + CRC to the length, and work * out how many 256-byte pages the frame would occupy. diff --git a/src/network/net_ne2000.c b/src/network/net_ne2000.c index 960f7cdbf..c7f1a0ccb 100644 --- a/src/network/net_ne2000.c +++ b/src/network/net_ne2000.c @@ -1122,7 +1122,7 @@ nic_init(const device_t *info) nic_reset(dev); /* Attach ourselves to the network module. */ - dev->dp8390->card = network_attach(dev->dp8390, dev->dp8390->physaddr, dp8390_rx, NULL, NULL); + dev->dp8390->card = network_attach(dev->dp8390, dev->dp8390->physaddr, dp8390_rx, NULL); nelog(1, "%s: %s attached IO=0x%X IRQ=%d\n", dev->name, dev->is_pci?"PCI":"ISA", dev->base_address, dev->base_irq); diff --git a/src/network/net_pcnet.c b/src/network/net_pcnet.c index 2b2b22540..340b056d3 100644 --- a/src/network/net_pcnet.c +++ b/src/network/net_pcnet.c @@ -29,6 +29,7 @@ #include #include #include +#include #define HAVE_STDARG_H #include <86box/86box.h> #include <86box/io.h> @@ -1253,6 +1254,10 @@ pcnetReceiveNoSync(void *priv, uint8_t *buf, int size) if (!pcnetIsLinkUp(dev)) return 0; + dev->fMaybeOutOfSpace = !pcnetCanReceive(dev); + if (dev->fMaybeOutOfSpace) + return 0; + pcnetlog(1, "%s: pcnetReceiveNoSync: RX %x:%x:%x:%x:%x:%x > %x:%x:%x:%x:%x:%x len %d\n", dev->name, buf[6], buf[7], buf[8], buf[9], buf[10], buf[11], buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], @@ -2095,12 +2100,13 @@ pcnet_mii_readw(nic_t *dev, uint16_t miiaddr) | 0x0008 /* Able to do auto-negotiation. */ | 0x0004 /* Link up. */ | 0x0001; /* Extended Capability, i.e. registers 4+ valid. */ - if (!dev->fLinkUp || dev->fLinkTempDown || isolate) { + if (!pcnetIsLinkUp(dev) || isolate) { val &= ~(0x0020 | 0x0004); dev->cLinkDownReported++; } if (!autoneg) { /* Auto-negotiation disabled. */ + val &= ~(0x0020 | 0x0008); if (duplex) val &= ~0x2800; /* Full duplex forced. */ else @@ -2131,7 +2137,7 @@ pcnet_mii_readw(nic_t *dev, uint16_t miiaddr) case 5: /* Link partner ability register. */ - if (dev->fLinkUp && !dev->fLinkTempDown && !isolate) { + if (pcnetIsLinkUp(dev) && !isolate) { val = 0x8000 /* Next page bit. */ | 0x4000 /* Link partner acked us. */ | 0x0400 /* Can do flow control. */ @@ -2145,7 +2151,7 @@ pcnet_mii_readw(nic_t *dev, uint16_t miiaddr) case 6: /* Auto negotiation expansion register. */ - if (dev->fLinkUp && !dev->fLinkTempDown && !isolate) { + if (pcnetIsLinkUp(dev) && !isolate) { val = 0x0008 /* Link partner supports npage. */ | 0x0004 /* Enable npage words. */ | 0x0001; /* Can do N-way auto-negotiation. */ @@ -2157,7 +2163,7 @@ pcnet_mii_readw(nic_t *dev, uint16_t miiaddr) case 18: /* Diagnostic Register (FreeBSD pcn/ac101 driver reads this). */ - if (dev->fLinkUp && !dev->fLinkTempDown && !isolate) { + if (pcnetIsLinkUp(dev) && !isolate) { val = 0x1000 /* Receive PLL locked. */ | 0x0200; /* Signal detected. */ @@ -2195,7 +2201,7 @@ pcnet_bcr_readw(nic_t *dev, uint16_t rap) case BCR_LED2: case BCR_LED3: val = dev->aBCR[rap] & ~0x8000; - if (dev->fLinkTempDown || !dev->fLinkUp) { + if (!(pcnetIsLinkUp(dev))) { if (rap == 4) dev->cLinkDownReported++; val &= ~0x40; @@ -2846,40 +2852,28 @@ pcnetCanReceive(nic_t *dev) return rc; } - static int -pcnetWaitReceiveAvail(void *priv) +pcnetSetLinkState(void *priv, uint32_t link_state) { nic_t *dev = (nic_t *) priv; - dev->fMaybeOutOfSpace = !pcnetCanReceive(dev); - - return dev->fMaybeOutOfSpace; -} - -static int -pcnetSetLinkState(void *priv) -{ - nic_t *dev = (nic_t *) priv; - int fLinkUp; - - if (dev->fLinkTempDown) { - pcnetTempLinkDown(dev); - return 1; + if (link_state & NET_LINK_TEMP_DOWN) { + pcnetTempLinkDown(dev); + return 1; } - fLinkUp = (dev->fLinkUp && !dev->fLinkTempDown); - if (dev->fLinkUp != fLinkUp) { - dev->fLinkUp = fLinkUp; - if (fLinkUp) { - dev->fLinkTempDown = 1; - dev->cLinkDownReported = 0; - dev->aCSR[0] |= 0x8000 | 0x2000; /* ERR | CERR (this is probably wrong) */ - timer_set_delay_u64(&dev->timer_restore, (dev->cMsLinkUpDelay * 1000) * TIMER_USEC); - } else { - dev->cLinkDownReported = 0; - dev->aCSR[0] |= 0x8000 | 0x2000; /* ERR | CERR (this is probably wrong) */ - } + bool link_up = !(link_state & NET_LINK_DOWN); + if (dev->fLinkUp != link_up) { + dev->fLinkUp = link_up; + if (link_up) { + dev->fLinkTempDown = 1; + dev->cLinkDownReported = 0; + dev->aCSR[0] |= 0x8000 | 0x2000; + timer_set_delay_u64(&dev->timer_restore, (dev->cMsLinkUpDelay * 1000) * TIMER_USEC); + } else { + dev->cLinkDownReported = 0; + dev->aCSR[0] |= 0x8000 | 0x2000; + } } return 0; @@ -3058,7 +3052,7 @@ pcnet_init(const device_t *info) pcnetHardReset(dev); /* Attach ourselves to the network module. */ - dev->netcard = network_attach(dev, dev->aPROM, pcnetReceiveNoSync, pcnetWaitReceiveAvail, pcnetSetLinkState); + dev->netcard = network_attach(dev, dev->aPROM, pcnetReceiveNoSync, pcnetSetLinkState); dev->netcard->byte_period = (dev->board == DEV_AM79C973) ? NET_PERIOD_100M : NET_PERIOD_10M; timer_add(&dev->timer, pcnetPollTimer, dev, 0); diff --git a/src/network/net_plip.c b/src/network/net_plip.c index cf1a0f9c3..9372e8022 100644 --- a/src/network/net_plip.c +++ b/src/network/net_plip.c @@ -476,7 +476,7 @@ plip_net_init(const device_t *info) } plip_log(1, " (attached to LPT)\n"); - instance->card = network_attach(instance, instance->mac, plip_rx, NULL, NULL); + instance->card = network_attach(instance, instance->mac, plip_rx, NULL); return instance; } diff --git a/src/network/net_wd8003.c b/src/network/net_wd8003.c index be52a11aa..d53f570f0 100644 --- a/src/network/net_wd8003.c +++ b/src/network/net_wd8003.c @@ -788,7 +788,7 @@ wd_init(const device_t *info) mem_mapping_disable(&dev->ram_mapping); /* Attach ourselves to the network module. */ - dev->dp8390->card = network_attach(dev->dp8390, dev->dp8390->physaddr, dp8390_rx, NULL, NULL); + dev->dp8390->card = network_attach(dev->dp8390, dev->dp8390->physaddr, dp8390_rx, NULL); if (!(dev->board_chip & WE_ID_BUS_MCA)) { wdlog("%s: attached IO=0x%X IRQ=%d, RAM addr=0x%06x\n", dev->name, diff --git a/src/network/network.c b/src/network/network.c index a8106afeb..7c6ab0826 100644 --- a/src/network/network.c +++ b/src/network/network.c @@ -346,6 +346,13 @@ network_rx_queue(void *priv) { netcard_t *card = (netcard_t *)priv; + uint32_t new_link_state = net_cards_conf[card->card_num].link_state; + if (new_link_state != card->link_state) { + if (card->set_link_state) + card->set_link_state(card->card_drv, new_link_state); + card->link_state = new_link_state; + } + uint32_t rx_bytes = 0; for (int i = 0; i < NET_QUEUE_LEN; i++) { if (card->queued_pkt.len == 0) { @@ -386,7 +393,13 @@ network_rx_queue(void *priv) timer_on_auto(&card->timer, timer_period); bool activity = rx_bytes || tx_bytes; - ui_sb_update_icon(SB_NETWORK, activity); + bool led_on = card->led_timer & 0x80000000; + if ((activity && !led_on) || (card->led_timer & 0x7fffffff) >= 150000) { + ui_sb_update_icon(SB_NETWORK | card->card_num, activity); + card->led_timer = 0 | (activity << 31); + } + + card->led_timer += timer_period; } @@ -398,13 +411,12 @@ network_rx_queue(void *priv) * modules. */ netcard_t * -network_attach(void *card_drv, uint8_t *mac, NETRXCB rx, NETWAITCB wait, NETSETLINKSTATE set_link_state) +network_attach(void *card_drv, uint8_t *mac, NETRXCB rx, NETSETLINKSTATE set_link_state) { netcard_t *card = calloc(1, sizeof(netcard_t)); card->queued_pkt.data = calloc(1, NET_MAX_FRAME); card->card_drv = card_drv; card->rx = rx; - card->wait = wait; card->set_link_state = set_link_state; card->tx_mutex = thread_create_mutex(); card->rx_mutex = thread_create_mutex(); @@ -496,8 +508,7 @@ network_reset(void) #endif for (i = 0; i < NET_CARD_MAX; i++) { - if (!net_cards_conf[i].device_num || net_cards_conf[i].net_type == NET_TYPE_NONE || - (net_cards_conf[i].net_type == NET_TYPE_PCAP && !strcmp(net_cards_conf[i].host_dev_name, "none"))) { + if (!network_dev_available(i)) { continue; } @@ -564,6 +575,28 @@ int network_rx_put_pkt(netcard_t *card, netpkt_t *pkt) return ret; } +void +network_connect(int id, int connect) +{ + if (id >= NET_CARD_MAX) + return; + + if (connect) { + net_cards_conf[id].link_state &= ~NET_LINK_DOWN; + } else { + net_cards_conf[id].link_state |= NET_LINK_DOWN; + } +} + +int +network_is_connected(int id) +{ + if (id >= NET_CARD_MAX) + return 0; + + return !(net_cards_conf[id].link_state & NET_LINK_DOWN); +} + int network_dev_to_id(char *devname) { @@ -575,19 +608,29 @@ network_dev_to_id(char *devname) } } - /* If no match found, assume "none". */ - return(0); + return(-1); } /* UI */ +int +network_dev_available(int id) +{ + int available = (net_cards_conf[id].device_num > 0) && (net_cards_conf[id].net_type != NET_TYPE_NONE); + + if ((net_cards_conf[id].net_type == NET_TYPE_PCAP && (network_dev_to_id(net_cards_conf[id].host_dev_name) <= 0))) + available = 0; + + return available; +} + int network_available(void) { int available = 0; for (int i = 0; i < NET_CARD_MAX; i ++) { - available |= (net_cards_conf[i].device_num > 0) && (net_cards_conf[i].net_type != NET_TYPE_NONE); + available |= network_dev_available(i); } return available; diff --git a/src/qt/qt_machinestatus.cpp b/src/qt/qt_machinestatus.cpp index a6ea65fd3..c04d6ee5c 100644 --- a/src/qt/qt_machinestatus.cpp +++ b/src/qt/qt_machinestatus.cpp @@ -220,7 +220,9 @@ struct MachineStatus::States { for (auto& h : hdds) { h.pixmaps = &pixmaps.hd; } - net.pixmaps = &pixmaps.net; + for (auto& n : net) { + n.pixmaps = &pixmaps.net; + } } std::array cartridge; @@ -230,7 +232,7 @@ struct MachineStatus::States { std::array zip; std::array mo; std::array hdds; - StateActive net; + std::array net; std::unique_ptr sound; std::unique_ptr text; }; @@ -320,6 +322,14 @@ void MachineStatus::iterateMO(const std::function &cb) { } } +void MachineStatus::iterateNIC(const std::function &cb) { + for (int i = 0; i < NET_CARD_MAX; i++) { + if (network_dev_available(i)) { + cb(i); + } + } +} + static int hdd_count(int bus) { int c = 0; int i; @@ -357,7 +367,9 @@ void MachineStatus::refreshIcons() { d->hdds[i].setActive(machine_status.hdd[i].active); } - d->net.setActive(machine_status.net.active); + for (size_t i = 0; i < NET_CARD_MAX; i++) { + d->net[i].setActive(machine_status.net[i].active); + } for (int i = 0; i < 2; ++i) { d->cartridge[i].setEmpty(machine_status.cartridge[i].empty); @@ -375,7 +387,6 @@ void MachineStatus::refresh(QStatusBar* sbar) { int c_xta = hdd_count(HDD_BUS_XTA); int c_ide = hdd_count(HDD_BUS_IDE); int c_scsi = hdd_count(HDD_BUS_SCSI); - int do_net = network_available(); sbar->removeWidget(d->cassette.label.get()); for (int i = 0; i < 2; ++i) { @@ -396,7 +407,9 @@ void MachineStatus::refresh(QStatusBar* sbar) { for (size_t i = 0; i < HDD_BUS_USB; i++) { sbar->removeWidget(d->hdds[i].label.get()); } - sbar->removeWidget(d->net.label.get()); + for (size_t i = 0; i < NET_CARD_MAX; i++) { + sbar->removeWidget(d->net[i].label.get()); + } sbar->removeWidget(d->sound.get()); if (cassette_enable) { @@ -503,6 +516,17 @@ void MachineStatus::refresh(QStatusBar* sbar) { sbar->addWidget(d->mo[i].label.get()); }); + iterateNIC([this, sbar](int i) { + d->net[i].label = std::make_unique(); + d->net[i].setActive(false); + d->net[i].refresh(); + d->net[i].label->setToolTip(MediaMenu::ptr->netMenus[i]->title()); + connect((ClickableLabel*)d->net[i].label.get(), &ClickableLabel::clicked, [i](QPoint pos) { + MediaMenu::ptr->netMenus[i]->popup(pos - QPoint(0, MediaMenu::ptr->netMenus[i]->sizeHint().height())); + }); + sbar->addWidget(d->net[i].label.get()); + }); + auto hdc_name = QString(hdc_get_internal_name(hdc_current)); if ((has_mfm || hdc_name.left(5) == QStringLiteral("st506")) && c_mfm > 0) { d->hdds[HDD_BUS_MFM].label = std::make_unique(); @@ -541,13 +565,6 @@ void MachineStatus::refresh(QStatusBar* sbar) { sbar->addWidget(d->hdds[HDD_BUS_SCSI].label.get()); } - if (do_net) { - d->net.label = std::make_unique(); - d->net.setActive(false); - d->net.refresh(); - d->net.label->setToolTip(tr("Network")); - sbar->addWidget(d->net.label.get()); - } d->sound = std::make_unique(); d->sound->setPixmap(d->pixmaps.sound); diff --git a/src/qt/qt_machinestatus.hpp b/src/qt/qt_machinestatus.hpp index 8c31dd238..8d085f93a 100644 --- a/src/qt/qt_machinestatus.hpp +++ b/src/qt/qt_machinestatus.hpp @@ -66,6 +66,7 @@ public: static void iterateCDROM(const std::function& cb); static void iterateZIP(const std::function& cb); static void iterateMO(const std::function& cb); + static void iterateNIC(const std::function& cb); QString getMessage(); public slots: diff --git a/src/qt/qt_mediamenu.cpp b/src/qt/qt_mediamenu.cpp index a4fcb5113..90cd80257 100644 --- a/src/qt/qt_mediamenu.cpp +++ b/src/qt/qt_mediamenu.cpp @@ -44,10 +44,14 @@ extern "C" { #include <86box/mo.h> #include <86box/sound.h> #include <86box/ui.h> +#include <86box/thread.h> +#include <86box/network.h> + }; #include "qt_newfloppydialog.hpp" #include "qt_util.hpp" +#include "qt_deviceconfig.hpp" std::shared_ptr MediaMenu::ptr; @@ -156,6 +160,16 @@ void MediaMenu::refresh(QMenu *parentMenu) { moMenus[i] = menu; moUpdateMenu(i); }); + + netMenus.clear(); + MachineStatus::iterateNIC([this, parentMenu](int i) { + auto *menu = parentMenu->addMenu(""); + netDisconnPos = menu->children().count(); + auto *action = menu->addAction(tr("&Disconnected"), [i] { network_connect(i, !network_is_connected(i)); config_save(); }); + action->setCheckable(true); + netMenus[i] = menu; + nicUpdateMenu(i); + }); } void MediaMenu::cassetteNewImage() { @@ -662,6 +676,30 @@ void MediaMenu::moUpdateMenu(int i) { menu->setTitle(QString::asprintf(tr("MO %i (%ls): %ls").toUtf8().constData(), i + 1, busName.toStdU16String().data(), name.isEmpty() ? tr("(empty)").toStdU16String().data() : name.toStdU16String().data())); } +void MediaMenu::nicUpdateMenu(int i) { + if (!netMenus.contains(i)) + return; + + QString netType = tr("None"); + switch (net_cards_conf[i].net_type) { + case NET_TYPE_SLIRP: + netType = "SLiRP"; + break; + case NET_TYPE_PCAP: + netType = "PCAP"; + break; + } + + QString devName = DeviceConfig::DeviceName(network_card_getdevice(net_cards_conf[i].device_num), network_card_get_internal_name(net_cards_conf[i].device_num), 1); + + auto *menu = netMenus[i]; + auto childs = menu->children(); + auto *connectedAction = dynamic_cast(childs[netDisconnPos]); + connectedAction->setChecked(!network_is_connected(i)); + + menu->setTitle(QString::asprintf(tr("NIC %02i (%ls) %ls").toUtf8().constData(), i + 1, netType.toStdU16String().data(), devName.toStdU16String().data())); +} + QString MediaMenu::getMediaOpenDirectory() { QString openDirectory; if (open_dir_usr_path > 0) { diff --git a/src/qt/qt_mediamenu.hpp b/src/qt/qt_mediamenu.hpp index 9b08d3ee3..a5c50a472 100644 --- a/src/qt/qt_mediamenu.hpp +++ b/src/qt/qt_mediamenu.hpp @@ -56,6 +56,8 @@ public: void moEject(int i); void moReload(int i); void moUpdateMenu(int i); + + void nicUpdateMenu(int i); private: QWidget* parentWidget = nullptr; @@ -65,6 +67,7 @@ private: QMap cdromMenus; QMap zipMenus; QMap moMenus; + QMap netMenus; QString getMediaOpenDirectory(); @@ -89,5 +92,7 @@ private: int moEjectPos; int moReloadPos; + int netDisconnPos; + friend class MachineStatus; }; diff --git a/src/qt/qt_ui.cpp b/src/qt/qt_ui.cpp index 7400a4f7a..65a8cec44 100644 --- a/src/qt/qt_ui.cpp +++ b/src/qt/qt_ui.cpp @@ -50,6 +50,8 @@ extern "C" { #include <86box/zip.h> #include <86box/mo.h> #include <86box/hdd.h> +#include <86box/thread.h> +#include <86box/network.h> #include <86box/machine_status.h> void @@ -246,7 +248,7 @@ ui_sb_update_icon(int tag, int active) { machine_status.hdd[item].active = active > 0 ? true : false; break; case SB_NETWORK: - machine_status.net.active = active > 0 ? true : false; + machine_status.net[item].active = active > 0 ? true : false; break; case SB_SOUND: break;