// Copyright 2017-2025 WIT.COM Inc. All rights reserved. // Use of this source code is governed by the GPL 3.0 package main // An app to submit patches for the 30 GO GUI repos import ( "os" "strings" "time" "go.wit.com/gui" "go.wit.com/lib/gadgets" "go.wit.com/lib/gui/shell" "go.wit.com/lib/protobuf/virtpb" "go.wit.com/log" ) func debug() { for { time.Sleep(10 * time.Second) // log.Info("TODO: use this debug loop for something?") } } // adds a new drive to the dropdown menu and protobuf func addDrive(devname string, displayDesc string) *Block { if blkpb := me.pb.FindByName(devname); blkpb != nil { return blkpb } s := log.Sprintf("%-12s %-8s", devname, displayDesc) log.Info(s) me.dd.AddText(s) blkpb := me.pb.InsertByName(devname) return blkpb } // show the output of parted print func showPartitions(blk *Block) { if blk == nil { return } log.Info("check if", blk.Name, "is in use") result, err := shell.RunVerbose([]string{"parted", blk.Name, "print"}) log.Info("result =", result.Stdout, "err =", err) out := strings.Join(result.Stdout, "\n") if err != nil { out += log.Sprintf("err = %v", err) } me.driveInfoBox.SetText(out) } func switchDrive(blk *Block) { var inUse bool = false me.currentDev = blk if isBlockDeviceInUse(blk.Name) { log.Info("Is in use?", blk.Name) me.parted.SetText("Partition " + blk.Name + " (in use)") me.parted.Disable() inUse = true } else { log.Info("Is probably not in use?", blk.Name) me.parted.SetText("Partition " + blk.Name + " as gpt boot disk") me.parted.Enable() } log.Info("check if", me.currentDev.Name, "is in use") result, err := shell.RunVerbose([]string{"parted", me.currentDev.Name, "print"}) log.Info("result =", result.Stdout, "err =", err) out := strings.Join(result.Stdout, "\n") if err != nil { out += log.Sprintf("err = %v", err) } me.driveInfoBox.SetText(out) if inUse { // if the drive is in use already, you can just stop here return } if ok, err := hasPartitionTable(blk.Name); err != nil { out := log.Sprintf("Error checking partition table: %s\n", err) log.Warn(out) me.parted.Disable() me.driveInfoBox.SetText(out) } else { if !ok { log.Printf("%s has no partition table safe for gdisk\n", blk.Name) } else { log.Printf("%s already has a partition table\n", blk.Name) me.parted.SetText("Partition " + blk.Name + " (has partitions)") me.parted.Disable() } } } func doGui() { me.myGui = gui.New() me.myGui.InitEmbed(resources) me.myGui.Default() mainWindow := gadgets.NewGenericWindow("RiscV Imager", "Show Drives") mainWindow.Custom = func() { log.Warn("Main window close") os.Exit(0) } drawWindow(mainWindow) // sits here forever debug() } func drawWindow(win *gadgets.GenericWindow) { grid := win.Group.RawGrid() me.dd = grid.NewDropdown() // me.dd.AddText("/dev/blah") me.dd.Custom = func() { fields := strings.Fields(me.dd.String()) log.Info("changed to", fields) if len(fields) < 1 { return } if blkpb := me.pb.FindByName(fields[0]); blkpb != nil { switchDrive(blkpb) } else { log.Info("couldn't find in protobuf:", fields) } } grid.NextRow() // a button to format or blank a drive me.parted = grid.NewButton("select drive", func() { if me.currentDev == nil { log.Info("You must select a drive first") return } log.Info("If you got here, gdisk should be safe to run on", me.currentDev.Name) if err := makeDefaultGPT(me.currentDev.Name); err != nil { log.Info("PARTITIONING FAILED on", me.currentDev.Name, "with", err) return } showPartitions(me.currentDev) }) grid.NextRow() grid.NewButton("doDrives()", func() { doDrives() }) grid.NewButton("show blkpb", func() { for blk := range me.pb.IterAll() { log.Printf("found %-12s %s\n", blk.Name, virtpb.HumanFormatBytes(int64(blk.SizeBytes))) } }) grid.NextRow() grid = win.Middle.RawGrid() me.driveInfoBox = grid.NewLabel("") doDrives2() doDrives() }