Пример #1
0
func (rw *RegionWrapper) UseTool(x, z int) {
	gdk.ThreadsLeave()
	defer gdk.ThreadsEnter()

	if !rw.toolsEnabled {
		return
	}

	if rw.tool.IsSlow() {
		rw.toolsEnabled = false
		rw.guicbs.setBusy(true)

		go func() {
			rw.tool.Do(rw.bio, rw, x, z)
			rw.guicbs.setBusy(false)
			rw.toolsEnabled = true

			gdk.ThreadsEnter()
			rw.redraw()
			gdk.ThreadsLeave()
		}()
	} else {
		rw.tool.Do(rw.bio, rw, x, z)
	}
}
Пример #2
0
func RenderHtml(html, baseuri string) string {
	result := ""

	fmt.Printf("Starting load\n")
	//go func() {
	gdk.ThreadsEnter()
	webview.GetMainFrame().LoadString(html, "text/html", "UTF-8", baseuri)
	//webview.LoadUri("http://google.com")
	gdk.ThreadsLeave()
	fmt.Printf("Ending load\n")
	//}()

	//for gtk.EventsPending() {
	//    fmt.Printf("Iteration\n")
	//    gtk.MainIteration()
	//}

	timeout := make(chan bool, 1)
	go func() {
		time.Sleep(4 * time.Second)
		timeout <- true
	}()

	select {
	case <-c:
		fmt.Printf("read from channel\n")
	case <-timeout:
		fmt.Printf("timeout\n")
	}
	//gdk.ThreadsEnter()
	result = getHtml(webview)
	//gdk.ThreadsLeave()
	return result
}
Пример #3
0
// KeyboardHandler handle events from keyboard
func KeyboardHandler(event chan *KeyPressEvent, terminal vte3.Terminal) {
	for {
		kpe := <-event
		log.Printf("[DEBUG] KeyPressEvent : %#v", kpe)
		gdk.ThreadsEnter()
		switch kpe.KeyVal {
		case gdk.KEY_plus:
			if kpe.GetModifier() == CTRL {
				log.Printf("[DEBUG] +")
			}
			break
		case gdk.KEY_minus:
			if kpe.GetModifier() == CTRL {
				log.Printf("[DEBUG] -")
			}
			break
		case gdk.KEY_equal:
			if kpe.GetModifier() == CTRL {
				log.Printf("[DEBUG] =")
			}
			break
		case gdk.KEY_exclam:
			if kpe.GetModifier() == CTRL {
				log.Printf("[DEBUG] About")
			}
			break
		}
		gdk.ThreadsLeave()
	}
}
Пример #4
0
// KeyboardHandler handle events from keyboard
func KeyboardHandler(event chan *keyhandler.KeyPressEvent, window *gtk.Window,
	repl *gtk.Entry, URLEntry *gtk.Entry, notebook *gtk.Notebook) {
	for {
		kpe := <-event
		log.Printf("[DEBUG] KeyPressEvent : %v", kpe)
		gdk.ThreadsEnter()
		switch kpe.KeyVal {
		case gdk.KEY_Escape:
			repl.SetVisible(false)
			break
		case gdk.KEY_colon:
			if !repl.IsFocus() && !URLEntry.IsFocus() {
				repl.SetVisible(true)
				repl.GrabFocus()
				repl.SetText(":")
				repl.SetPosition(1)
			}
			break
		case gdk.KEY_Return:
			if repl.IsFocus() {
				text := repl.GetText()
				log.Printf("Repl text : %s", text)
				if len(text) > 0 {
					command.Run(text, window, "")
				}
				repl.SetText("")
			}
			break
		// case gdk.KEY_w:
		// 	if kpe.GetModifier() == keyhandler.CTRL {
		// 		log.Printf("[DEBUG] nb : %d", notebook.GetNPages())
		// 		notebook.RemovePage(notebook.GetCurrentPage())
		// 		log.Printf("[DEBUG] nb : %d", notebook.GetNPages())
		// 	}
		// 	break
		case gdk.KEY_t:
			if kpe.GetModifier() == keyhandler.CTRL {
				log.Printf("[DEBUG] New tab")
				log.Printf("[DEBUG] nb : %d", notebook.GetNPages())
				log.Printf("[DEBUG] current : %d",
					notebook.GetCurrentPage())
				tab := ui.NewBrowser("")
				page := gtk.NewFrame("")
				//fmt.Sprintf("%d", notebook.GetNPages()+1))
				notebook.AppendPage(page, gtk.NewLabel("New tab"))
				page.Add(tab.VBox)
				log.Printf("[DEBUG] nb : %d", notebook.GetNPages())
				notebook.ShowAll()
			}
			break
		case gdk.KEY_q:
			if kpe.GetModifier() == keyhandler.CTRL {
				gtk.MainQuit()
			}
			break
		}
		gdk.ThreadsLeave()
	}
}
Пример #5
0
func (w *GhSyncWindow) pulsate(progressBar *gtk.GtkProgressBar) {
	for w.isSyncing {
		gdk.ThreadsEnter()
		progressBar.Pulse()
		gdk.ThreadsLeave()
		time.Sleep(time.Duration(100) * time.Millisecond)
	}
}
Пример #6
0
func InitWebKit() {
	gtk.Init(nil)
	gdk.ThreadsInit()
	c = make(chan bool, 2)
	gdk.ThreadsEnter()
	webview = CreateWebView(func() {
		fmt.Printf("HEEEERLoad Finished\n")
		c <- true
	})
	gdk.ThreadsLeave()

	go func() {
		gdk.ThreadsEnter()
		gtk.Main()
		gdk.ThreadsLeave()
	}()
}
Пример #7
0
func (rw *RegionWrapper) tileUpdater() {
	for _ = range rw.tileUpdates {
		todelete := make(map[XZPos]bool)

		for pos := range rw.Maptiles {
			if (pos.X < rw.startX) || (pos.Z < rw.startZ) || (pos.X >= rw.endX) || (pos.Z >= rw.endZ) {
				todelete[pos] = true
			}
		}

		gdk.ThreadsEnter()
		for pos := range todelete {
			if tile, ok := rw.Maptiles[pos]; ok {
				tile.Unref()
				delete(rw.Maptiles, pos)
			}

			if tile, ok := rw.Biotiles[pos]; ok {
				tile.Unref()
				delete(rw.Biotiles, pos)
			}

			if _, ok := rw.bioCache[pos]; ok {
				delete(rw.bioCache, pos)
			}
		}

		if rw.region != nil {
			for z := rw.startZ; z < rw.endZ; z++ {
			scanX:
				for x := rw.startX; x < rw.endX; x++ {
					pos := XZPos{x, z}

					if _, ok := rw.Biotiles[pos]; ok {
						continue scanX
					}

					chunk, err := rw.region.Chunk(x, z)
					switch err {
					case nil:
					case mcmap.NotAvailable:
						continue scanX
					default:
						rw.guicbs.reportFail(fmt.Sprintf("Could not get chunk %d, %d: %s", x, z, err))
						return
					}

					rw.Maptiles[pos], rw.Biotiles[pos], rw.bioCache[pos] = rw.renderTile(chunk)
					chunk.MarkUnused()

					rw.redraw()
				}
			}
		}

		gdk.ThreadsLeave()
	}
}
Пример #8
0
func tabby_server() {
	var focus_line int
	buf := make([]byte, 1024)

	for {
		c, _ := listener.Accept()
		if nil != c {
			nread, err := c.Read(buf)
			if 0 >= nread {
				tabby_log("server: read from unix socket: " + err.Error())
				c.Close()
				continue
			}

			// At this point buf contains '\n' separated file names preceeded by focus
			// line number. Double '\n' at the end of list.

			gdk.ThreadsEnter()

			opened_cnt := 0
			s := buf[:]
			for cnt := 0; ; cnt++ {
				en := strings.Index(string(s), "\n")
				if 0 == en {
					break
				}
				if 0 == cnt {
					focus_line, _ = strconv.Atoi(string(s[:en]))
				} else {
					if open_file_from_args(string(s[:en]), focus_line) {
						opened_cnt++
					}
				}
				s = s[en+1:]
			}
			if opened_cnt > 0 {
				main_window.Present()
				file_tree_store()
				new_file := file_stack_pop()
				file_save_current()
				file_switch_to(new_file)
			}

			gdk.ThreadsLeave()

			c.Close()
		} else {
			// Dirty hack! There is no way to distinguish two cases:
			// 1) Accept returns error because socket was closed on tabby exit.
			// 2) Real error occured.
			// Commenting this line out to avoid misleading error messages on exit.
			//tabby_log(e.String())
			return
		}
	}
}
Пример #9
0
func (g *GuiController) Write(dmxUniverse *dmx.DMXUniverse) error {
	gdk.ThreadsEnter()
	for i := 0; i < 3*8; i += 3 {

		c := gdk.NewColorRGB(dmxUniverse.Channels[i], dmxUniverse.Channels[i+1], dmxUniverse.Channels[i+2])

		g.buttons[i/3].ModifyBG(gtk.STATE_NORMAL, c)
	}

	gdk.ThreadsLeave()

	return nil
}
Пример #10
0
func main() {
	glib.ThreadInit(nil)
	gdk.ThreadsInit()
	gdk.ThreadsEnter()
	gtk.Init(nil)

	gui := new(GUI)
	gui.Init()
	gui.Show()

	gtk.Main()
	gdk.ThreadsLeave()
}
Пример #11
0
func main() {
	runtime.GOMAXPROCS(10)
	glib.ThreadInit(nil)
	gdk.ThreadsInit()
	gdk.ThreadsEnter()
	gtk.Init(nil)
	window := gtk.NewWindow(gtk.WINDOW_TOPLEVEL)
	window.Connect("destroy", gtk.MainQuit)

	vbox := gtk.NewVBox(false, 1)

	label1 := gtk.NewLabel("")
	vbox.Add(label1)
	label2 := gtk.NewLabel("")
	vbox.Add(label2)

	window.Add(vbox)

	window.SetSizeRequest(100, 100)
	window.ShowAll()
	time.Sleep(1000 * 1000 * 100)
	go (func() {
		for i := 0; i < 300000; i++ {
			gdk.ThreadsEnter()
			label1.SetLabel(strconv.Itoa(i))
			gdk.ThreadsLeave()
		}
		gtk.MainQuit()
	})()
	go (func() {
		for i := 300000; i >= 0; i-- {
			gdk.ThreadsEnter()
			label2.SetLabel(strconv.Itoa(i))
			gdk.ThreadsLeave()
		}
		gtk.MainQuit()
	})()
	gtk.Main()
}
Пример #12
0
func (rw *RegionWrapper) SetBiomeAt(x, z int, bio mcmap.Biome) {
	cx, cz, bx, bz := mcmap.BlockToChunk(x, z)
	pos := XZPos{cx, cz}

	chunk, err := rw.region.Chunk(cx, cz)
	switch err {
	case nil:
	case mcmap.NotAvailable:
		return
	default:
		rw.guicbs.reportFail(fmt.Sprintf("Error while getting chunk %d, %d: %s", cx, cz, err))
		return
	}

	chunk.SetBiome(bx, bz, bio)

	var newcol *gdk.Color
	if rw.fixSnowIce {
		newcol = rw.fixWeather(bio, bx, bz, chunk)
	}

	chunk.MarkModified()

	// Update cache
	if bc, ok := rw.bioCache[pos]; ok {
		bc[bz*mcmap.ChunkSizeXZ+bx] = bio
	}

	// Update tile
	if biotile, ok := rw.Biotiles[pos]; ok {
		gdk.ThreadsEnter()

		drawable := biotile.GetDrawable()
		gc := gdk.NewGC(drawable)
		gc.SetRgbFgColor(rw.bioLookup.Color(bio))
		drawable.DrawRectangle(gc, true, bx*zoom, bz*zoom, zoom, zoom)

		if newcol != nil {
			drawable = rw.Maptiles[pos].GetDrawable()
			gc = gdk.NewGC(drawable)
			gc.SetRgbFgColor(newcol)
			drawable.DrawRectangle(gc, true, bx*zoom, bz*zoom, zoom, zoom)
		}

		gdk.ThreadsLeave()
	}
}
Пример #13
0
func unlinked_main() {
	devices := SearchValid()
	for _, x := range devices {
		MainGui.appendItem("/dev/hidraw"+strconv.FormatUint(x.SeqNum(), 10), x.SysAttrValue("product"))
	}
	/////////// THIS IS JUST FOR DEBUG PURPOSE //////////////
	//MainGui.appendItem("prova1", "prova 123")
	//MainGui.appendItem("prova2", "Prova 123")
	//MainGui.appendItem("prova3", "prova 123")
	//MainGui.appendItem("prova4", "prova 1234")
	///////////////////////////////////////////////////////
	gdk.ThreadsEnter()
	MainGui.SplashWindow.Hide()
	//ctx := MainGui.Status.GetContextId("prova 123")
	MainGui.Status.Push(0, "ready for operate")
	MainGui.MainWindow.ShowAll()
	gdk.ThreadsLeave()
}
Пример #14
0
func inotify_observe() {
	buf := make([]byte, event_size*NEVENTS)
	for {
		collect := inotify_observe_collect(buf)
		if 0 == len(collect) {
			continue
		}
		gdk.ThreadsEnter()
		file_save_current()
		reload := inotify_dialog(collect)
		for name, _ := range collect {
			rec, rec_found := file_map[name]
			if false == rec_found {
				tabby_log("inotify_observe: " + name + " not found in file_map")
				continue
			}
			if reload {
				// Reload file content.
				read_ok, buf := open_file_read_to_buf(name, true)
				if read_ok {
					rec.buf = buf
					rec.modified = false
					inotify_rm_watch(name)
					inotify_add_watch(name)
				} else {
					rec.modified = true
				}
			} else {
				// Keep file as is.
				rec.modified = true
			}
		}
		file_tree_store()
		// So as to renew current TextBuffer it is required to switch to cur_file.
		file_switch_to(cur_file)
		gdk.ThreadsLeave()
	}
}
Пример #15
0
func (mw *MapWidget) buttonChanged(ctx *glib.CallbackContext) {
	arg := ctx.Args(0)
	bev := *(**gdk.EventButton)(unsafe.Pointer(&arg))

	switch gdk.EventType(bev.Type) {
	case gdk.BUTTON_RELEASE:
		if mw.panning {
			mw.panning = false

			mw.updateChunkBounds()

			gdk.ThreadsLeave()
			mw.regWrap.UpdateTiles()
			gdk.ThreadsEnter()
		}

		mw.continueTool = false
	case gdk.BUTTON_PRESS:
		switch bev.Button {
		case 1:
			if !mw.regWrap.RegionLoaded() {
				return
			}
			x := (mw.offX + int(bev.X)) / zoom
			z := (mw.offZ + int(bev.Y)) / zoom
			mw.regWrap.UseTool(x, z)

			mw.updateGUI()

			if !mw.regWrap.ToolSingleClick() {
				mw.continueTool = true
			}
		case 2:
			mw.panning = true
		}
	}
}
Пример #16
0
func main() {
	gtk.Init(&os.Args)
	gdk.ThreadsInit()
	window := gtk.NewWindow(gtk.WINDOW_TOPLEVEL)
	window.SetTitle("Twitter!")
	window.Connect("destroy", gtk.MainQuit)

	vbox := gtk.NewVBox(false, 1)

	scrolledwin := gtk.NewScrolledWindow(nil, nil)
	textview := gtk.NewTextView()
	textview.SetEditable(false)
	textview.SetCursorVisible(false)
	scrolledwin.Add(textview)
	vbox.Add(scrolledwin)

	buffer := textview.GetBuffer()

	tag := buffer.CreateTag("blue", map[string]string{
		"foreground": "#0000FF", "weight": "700"})
	button := gtk.NewButtonWithLabel("Update Timeline")
	button.SetTooltipMarkup("update <b>public timeline</b>")
	button.Clicked(func() {
		b, err := ioutil.ReadFile("settings.json")
		if err != nil {
			fmt.Println(`"settings.json" not found: `, err)
			return
		}
		var config map[string]string
		err = json.Unmarshal(b, &config)
		if err != nil {
			fmt.Println(`can't read "settings.json": `, err)
			return
		}
		client := &oauth.Client{
			Credentials: oauth.Credentials{
				config["ClientToken"], config["ClientSecret"]}}
		cred := &oauth.Credentials{
			config["AccessToken"], config["AccessSecret"]}

		gdk.ThreadsEnter()
		button.SetSensitive(false)
		gdk.ThreadsLeave()
		go func() {
			ts, err := twitterstream.Open(client, cred,
				"https://stream.twitter.com/1/statuses/filter.json",
				url.Values{"track": {"picplz,instagr"}})
			if err != nil {
				println(err.Error())
				return
			}
			for ts.Err() == nil {
				t := tweet{}
				if err := ts.UnmarshalNext(&t); err != nil {
					fmt.Println("error reading tweet: ", err)
					continue
				}
				var iter gtk.TextIter
				pixbufbytes, resp := readURL(t.User.ProfileImageUrl)
				gdk.ThreadsEnter()
				buffer.GetStartIter(&iter)
				if resp != nil {
					buffer.InsertPixbuf(&iter, bytes2pixbuf(pixbufbytes, resp.Header.Get("Content-Type")))
				}
				gdk.ThreadsLeave()
				gdk.ThreadsEnter()
				buffer.Insert(&iter, " ")
				buffer.InsertWithTag(&iter, t.User.ScreenName, tag)
				buffer.Insert(&iter, ":"+t.Text+"\n")
				gtk.MainIterationDo(false)
				gdk.ThreadsLeave()
			}
		}()
	})
	vbox.PackEnd(button, false, false, 0)

	window.Add(vbox)
	window.SetSizeRequest(800, 500)
	window.ShowAll()
	gdk.ThreadsEnter()
	gtk.Main()
	gdk.ThreadsLeave()
}
Пример #17
0
func main() {
	gdk.ThreadsInit()
	gtk.Init(&os.Args)
	window := gtk.Window(gtk.GTK_WINDOW_TOPLEVEL)
	window.SetTitle("Twitter!")
	window.Connect("destroy", gtk.MainQuit)

	vbox := gtk.VBox(false, 1)

	scrolledwin := gtk.ScrolledWindow(nil, nil)
	textview := gtk.TextView()
	textview.SetEditable(false)
	textview.SetCursorVisible(false)
	scrolledwin.Add(textview)
	vbox.Add(scrolledwin)

	buffer := textview.GetBuffer()

	tag := buffer.CreateTag("blue", map[string]string{
		"foreground": "#0000FF", "weight": "700"})
	button := gtk.ButtonWithLabel("Update Timeline")
	button.SetTooltipMarkup("update <b>public timeline</b>")
	button.Clicked(func() {
		go func() {
			gdk.ThreadsEnter()
			button.SetSensitive(false)
			gdk.ThreadsLeave()
			r, err := http.Get("http://twitter.com/statuses/public_timeline.json")
			if err == nil {
				var b []byte
				if r.ContentLength == -1 {
					b, err = ioutil.ReadAll(r.Body)
				} else {
					b = make([]byte, r.ContentLength)
					_, err = io.ReadFull(r.Body, b)
				}
				if err != nil {
					println(err.String())
					return
				}
				var j interface{}
				json.NewDecoder(bytes.NewBuffer(b)).Decode(&j)
				arr := j.([]interface{})
				for i := 0; i < len(arr); i++ {
					data := arr[i].(map[string]interface{})
					icon := data["user"].(map[string]interface{})["profile_image_url"].(string)
					var iter gtk.GtkTextIter
					gdk.ThreadsEnter()
					buffer.GetStartIter(&iter)
					buffer.InsertPixbuf(&iter, url2pixbuf(icon))
					gdk.ThreadsLeave()
					name := data["user"].(map[string]interface{})["screen_name"].(string)
					text := data["text"].(string)
					gdk.ThreadsEnter()
					buffer.Insert(&iter, " ")
					buffer.InsertWithTag(&iter, name, tag)
					buffer.Insert(&iter, ":"+text+"\n")
					gtk.MainIterationDo(false)
					gdk.ThreadsLeave()
				}
			}
			button.SetSensitive(true)
		}()
	})
	vbox.PackEnd(button, false, false, 0)

	window.Add(vbox)
	window.SetSizeRequest(800, 500)
	window.ShowAll()
	gdk.ThreadsEnter()
	gtk.Main()
	gdk.ThreadsLeave()
}
Пример #18
0
func Gui() {
	//--------------------------------------------------------
	// Setting up the GTK-Foo
	//--------------------------------------------------------
	gdk.ThreadsInit()
	gtk.Init(&os.Args)
	window := gtk.Window(gtk.GTK_WINDOW_TOPLEVEL)
	window.SetTitle("Zwitscher!")
	window.Connect("destroy", func() {
		gtk.MainQuit()
	})

	vbox := gtk.VBox(false, 1)
	notebook := gtk.Notebook()

	//--------------------------------------------------------
	// Home View
	//--------------------------------------------------------
	vboxHome := gtk.VBox(false, 1)
	scrolledWinHome := gtk.ScrolledWindow(nil, nil)
	//Disable hscrollbar, enable vscrollbar
	scrolledWinHome.SetPolicy(gtk.GTK_POLICY_NEVER, gtk.GTK_POLICY_ALWAYS)
	vboxHome.Add(scrolledWinHome)
	vboxScrolledWinHome := gtk.VBox(false, 1)
	scrolledWinHome.AddWithViewPort(vboxScrolledWinHome)

	tweetwidgets := []*gtk.GtkFrame{}
	buttonUpdateTimeline := gtk.ButtonWithLabel("Update Timeline")
	buttonUpdateTimeline.Clicked(func() {
		var tweet gotter.Tweet
		tweets, err := gotter.GetTweets(accounts.Credentials, "https://api.twitter.com/1/statuses/home_timeline.json", map[string]string{})
		if err != nil {
			println("failed to get tweets:", err.String())
			return
		}
		for i := len(tweets) - 1; i >= 0; i-- {
			tweet = tweets[i]
			id, _ := strconv.Atoi64(tweet.Identifier)
			if accounts.Maxreadid < id {
				if len(tweetwidgets) > 20 {
					tweetwidgets[0].Destroy()
					tweetwidgets = tweetwidgets[1:]
				}
				tweetwidget := TweetWidget(tweet)
				vboxScrolledWinHome.PackEnd(tweetwidget, false, false, 0)
				tweetwidget.ShowAll()
				tweetwidgets = append(tweetwidgets, tweetwidget)
				accounts.Maxreadid = id
			}
		}
	})
	vboxHome.PackEnd(buttonUpdateTimeline, false, false, 0)
	notebook.AppendPage(vboxHome, gtk.Label("Home"))

	//--------------------------------------------------------
	// Mentions View
	//--------------------------------------------------------
	scrolledwin := gtk.ScrolledWindow(nil, nil)
	notebook.AppendPage(scrolledwin, gtk.Label("Mentions"))

	//--------------------------------------------------------
	// Messages View
	//--------------------------------------------------------
	scrolledwin = gtk.ScrolledWindow(nil, nil)
	notebook.AppendPage(scrolledwin, gtk.Label("Messages"))

	vbox.Add(notebook)

	//--------------------------------------------------------
	// Fild for Tweets
	//--------------------------------------------------------
	hbox := gtk.HBox(false, 1)

	dir, _ := filepath.Split(os.Args[0])
	imagefile := filepath.Join(dir, "Awesome Smiley Original.jpg")
	image := gtk.ImageFromFile(imagefile)
	hbox.PackStart(image, false, false, 0)

	buttonZwitscher := gtk.ButtonWithLabel("Zwitscher!")
	newTweetTextField := gtk.Entry()
	charCounterLabel := gtk.Label("140")

	buttonZwitscher.SetTooltipMarkup("Tweet")

	buttonZwitscher.Clicked(func() {
		charCounterLabel.SetLabel("140")
		SendTweet(newTweetTextField.GetText())
		newTweetTextField.SetText("")
	})

	newTweetTextField.Connect("key-release-event", func() {
		length := utf8.RuneCountInString(newTweetTextField.GetText())
		charCounterLabel.SetLabel((string)(strconv.Itoa(140 - length)))
	})

	newTweetTextField.Connect("activate", func() {
		if newTweetTextField.GetText() != "" { //pressed enter, and text is not empty
			charCounterLabel.SetLabel("140")
			SendTweet(newTweetTextField.GetText())
			newTweetTextField.SetText("")
		}
	})
	hbox.PackStartDefaults(newTweetTextField)
	hbox.PackStart(charCounterLabel, false, false, 0)
	hbox.PackEnd(buttonZwitscher, false, false, 0)

	vbox.PackEnd(hbox, false, false, 0)

	//--------------------------------------------------------
	// Event
	//--------------------------------------------------------
	window.Add(vbox)
	window.SetSizeRequest(400, 550)
	window.ShowAll()

	gdk.ThreadsEnter()
	gtk.Main()
	gdk.ThreadsLeave()
}
Пример #19
0
func main() {
	runtime.LockOSThread()
	gtk.Init(&os.Args)
	gdk.ThreadsInit()

	window := gtk.NewWindow(gtk.WINDOW_TOPLEVEL)
	window.SetTitle("DMS GUI")
	window.Connect("destroy", gtk.MainQuit)

	vbox := gtk.NewVBox(false, 0)
	window.Add(vbox)

	hbox := gtk.NewHBox(false, 0)
	vbox.PackStart(hbox, false, true, 0)

	hbox.PackStart(gtk.NewLabel("Shared directory: "), false, true, 0)

	dialog := gtk.NewFileChooserDialog(
		"Select directory to share", window, gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER,
		gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
		gtk.STOCK_OK, gtk.RESPONSE_ACCEPT)

	button := gtk.NewFileChooserButtonWithDialog(dialog)
	hbox.Add(button)

	logView := gtk.NewTextView()
	logView.SetEditable(false)
	logView.ModifyFontEasy("monospace")
	logView.SetWrapMode(gtk.WRAP_WORD_CHAR)
	logViewScroller := gtk.NewScrolledWindow(nil, nil)
	logViewScroller.Add(logView)
	logViewScroller.SetPolicy(gtk.POLICY_AUTOMATIC, gtk.POLICY_ALWAYS)
	vbox.PackEnd(logViewScroller, true, true, 0)

	getPath := func() string {
		return button.GetFilename()
	}

	window.ShowAll()
	if dialog.Run() != gtk.RESPONSE_ACCEPT {
		return
	}
	go func() {
		dmsServer := dms.Server{
			RootObjectPath: getPath(),
		}
		if err := dmsServer.Serve(); err != nil {
			log.Fatalln(err)
		}
		defer dmsServer.Close()
		runtime.LockOSThread()
		gdk.ThreadsEnter()
		button.Connect("selection-changed", func() {
			dmsServer.RootObjectPath = getPath()
		})
		gdk.ThreadsLeave()
		runtime.UnlockOSThread()
		dmsServer.Serve()
	}()
	gtk.Main()
	runtime.UnlockOSThread()
}
Пример #20
0
func guiMain(confglobal string, conflocal string) {
	var CallID string
	ch := make(chan string, 100)
	Config := ReadConfig(confglobal)
	Configlocal := ReadConfiglocal(conflocal)
	owner := Configlocal.Main.Owner

	//prepare config for XSI
	var xsiConfig xsi.ConfigT
	xsiConfig.Main.User = Configlocal.Main.Owner
	xsiConfig.Main.Password = Configlocal.Main.Password
	xsiConfig.Main.Host = Config.Main.Host
	xsiConfig.Main.HTTPHost = Config.Main.HTTPHost
	xsiConfig.Main.HTTPPort = Config.Main.HTTPPort
	def := xsi.MakeDef(xsiConfig)

	//start main client
	go clientMain(ch, Config)

	//prepare config for OCI
	var ociConfig ocip.ConfigT
	ociConfig.Main.User = Configlocal.Main.Owner
	ociConfig.Main.Password = Configlocal.Main.Password
	ociConfig.Main.Host = Config.Main.Host
	ociConfig.Main.OCIPPort = Config.Main.OCIPPort
	//set unavailable at start app
	ocip.OCIPsend(ociConfig, "UserCallCenterModifyRequest19", ConcatStr("", "userId=", owner), "agentACDState=Unavailable")
	//prepare timer
	timer := time.NewTimer(time.Second)
	timer.Stop()

	//init gthreads
	glib.ThreadInit(nil)
	gdk.ThreadsInit()
	gdk.ThreadsEnter()
	gtk.Init(nil)

	//names
	names := make(map[string]string)
	for iter, target := range Config.Main.TargetID {
		names[target] = Config.Main.Name[iter]
	}

	//icons to pixbuf map
	pix := make(map[string]*gdkpixbuf.Pixbuf)
	im_call := gtk.NewImageFromFile("ico/Call-Ringing-48.ico")
	pix["call"] = im_call.GetPixbuf()
	im_blank := gtk.NewImageFromFile("ico/Empty-48.ico")
	pix["blank"] = im_blank.GetPixbuf()
	im_green := gtk.NewImageFromFile("ico/Green-ball-48.ico")
	pix["green"] = im_green.GetPixbuf()
	im_grey := gtk.NewImageFromFile("ico/Grey-ball-48.ico")
	pix["grey"] = im_grey.GetPixbuf()
	im_yellow := gtk.NewImageFromFile("ico/Yellow-ball-48.ico")
	pix["yellow"] = im_yellow.GetPixbuf()

	window := gtk.NewWindow(gtk.WINDOW_TOPLEVEL)
	window.SetTitle("Call Center")
	window.SetIcon(pix["call"])
	window.SetPosition(gtk.WIN_POS_CENTER)
	window.SetSizeRequest(350, 500)
	window.SetDecorated(false)
	window.SetResizable(true)
	window.Connect("destroy", gtk.MainQuit)

	swin := gtk.NewScrolledWindow(nil, nil)
	swin.SetPolicy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
	swin.SetShadowType(gtk.SHADOW_IN)

	//owner
	owner1 := gtk.NewLabel(names[owner])
	owner2 := gtk.NewLabel("")
	owner3 := gtk.NewImage()

	//qstatus
	qlabel1 := gtk.NewLabel("В очереди:")
	qlabel2 := gtk.NewLabel("")

	//buttons
	b_av := gtk.NewButtonWithLabel("Доступен")
	b_av.SetCanFocus(false)
	b_av.Connect("clicked", func() {
		ocip.OCIPsend(ociConfig, "UserCallCenterModifyRequest19", ConcatStr("", "userId=", owner), "agentACDState=Available")
	})
	b_un := gtk.NewButtonWithLabel("Недоступен")
	b_un.SetCanFocus(false)
	b_un.Connect("clicked", func() {
		ocip.OCIPsend(ociConfig, "UserCallCenterModifyRequest19", ConcatStr("", "userId=", owner), "agentACDState=Unavailable")
	})
	b_wr := gtk.NewButtonWithLabel("Дообработка")
	b_wr.SetCanFocus(false)
	b_wr.Connect("clicked", func() {
		ocip.OCIPsend(ociConfig, "UserCallCenterModifyRequest19", ConcatStr("", "userId=", owner), "agentACDState=Wrap-Up")
	})

	//main table
	table := gtk.NewTable(3, 3, false)
	table.Attach(owner1, 0, 1, 0, 1, gtk.FILL, gtk.FILL, 1, 1)
	table.Attach(owner3, 1, 2, 0, 1, gtk.FILL, gtk.FILL, 1, 1)
	table.Attach(owner2, 2, 3, 0, 1, gtk.FILL, gtk.FILL, 1, 1)
	table.Attach(b_av, 0, 1, 1, 2, gtk.FILL, gtk.FILL, 1, 1)
	table.Attach(b_un, 1, 2, 1, 2, gtk.FILL, gtk.FILL, 1, 1)
	table.Attach(b_wr, 2, 3, 1, 2, gtk.FILL, gtk.FILL, 1, 1)
	table.Attach(qlabel1, 0, 1, 2, 3, gtk.FILL, gtk.FILL, 1, 1)
	table.Attach(qlabel2, 1, 2, 2, 3, gtk.FILL, gtk.FILL, 1, 1)

	//menu buttons
	btnclose := gtk.NewToolButtonFromStock(gtk.STOCK_STOP)
	btnclose.SetCanFocus(false)
	btnclose.OnClicked(gtk.MainQuit)

	btnhide := gtk.NewToolButtonFromStock(gtk.STOCK_REMOVE)
	btnhide.SetCanFocus(false)
	btnhide.OnClicked(window.Iconify)

	//move window
	var p2, p1 point
	var gdkwin *gdk.Window
	p1.x = -1
	p2.y = -1
	var x int = 0
	var y int = 0
	var diffx int = 0
	var diffy int = 0
	px := &x
	py := &y
	movearea := gtk.NewDrawingArea()
	movearea.Connect("motion-notify-event", func(ctx *glib.CallbackContext) {
		if gdkwin == nil {
			gdkwin = movearea.GetWindow()
		}
		arg := ctx.Args(0)
		mev := *(**gdk.EventMotion)(unsafe.Pointer(&arg))
		var mt gdk.ModifierType
		if mev.IsHint != 0 {
			gdkwin.GetPointer(&p2.x, &p2.y, &mt)
		}
		if (gdk.EventMask(mt) & gdk.BUTTON_PRESS_MASK) != 0 {
			if p1.x != -1 && p1.y != -1 {
				window.GetPosition(px, py)
				diffx = p2.x - p1.x
				diffy = p2.y - p1.y
				window.Move(x+diffx, y+diffy)
			}
			p1.x = p2.x - diffx
			p1.y = p2.y - diffy
		} else {
			p1.x = -1
			p2.y = -1
		}
	})
	movearea.SetEvents(int(gdk.POINTER_MOTION_MASK | gdk.POINTER_MOTION_HINT_MASK | gdk.BUTTON_PRESS_MASK))

	//resize window
	var p2r, p1r point
	var gdkwinr *gdk.Window
	p1r.x = -1
	p2r.y = -1
	var xr int = 0
	var yr int = 0
	var diffxr int = 0
	var diffyr int = 0
	pxr := &xr
	pyr := &yr

	resizearea := gtk.NewDrawingArea()
	resizearea.SetSizeRequest(10, 10)
	resizearea.Connect("motion-notify-event", func(ctx *glib.CallbackContext) {
		if gdkwinr == nil {
			gdkwinr = resizearea.GetWindow()
		}
		argr := ctx.Args(0)
		mevr := *(**gdk.EventMotion)(unsafe.Pointer(&argr))
		var mtr gdk.ModifierType
		if mevr.IsHint != 0 {
			gdkwinr.GetPointer(&p2r.x, &p2r.y, &mtr)
		}
		if (gdk.EventMask(mtr) & gdk.BUTTON_PRESS_MASK) != 0 {
			if p1r.x != -1 && p1r.y != -1 {
				diffxr = p2r.x - p1r.x
				diffyr = p2r.y - p1r.y
				window.GetSize(pxr, pyr)
				window.Resize(xr+diffxr, yr+diffyr)
			}
		}
		p1r = p2r
	})
	resizearea.SetEvents(int(gdk.POINTER_MOTION_MASK | gdk.POINTER_MOTION_HINT_MASK | gdk.BUTTON_PRESS_MASK))

	//menu
	menutable := gtk.NewTable(1, 8, true)
	menutable.Attach(movearea, 0, 6, 0, 1, gtk.FILL, gtk.FILL, 0, 0)
	menutable.Attach(btnhide, 6, 7, 0, 1, gtk.EXPAND, gtk.EXPAND, 0, 0)
	menutable.Attach(btnclose, 7, 8, 0, 1, gtk.EXPAND, gtk.EXPAND, 0, 0)

	//agents
	dlabel1 := make(map[string]*gtk.Label)
	dlabel2 := make(map[string]*gtk.Image)
	dlabel3 := make(map[string]*gtk.Image)
	b_tr := make(map[string]*gtk.Button)

	var count uint = 0
	for _, target := range Config.Main.TargetID {
		if target != owner {
			count = count + 1
			dlabel1[target] = gtk.NewLabel(names[target])
			dlabel2[target] = gtk.NewImage()
			dlabel3[target] = gtk.NewImage()
			tmp := gtk.NewButtonWithLabel("Перевод")
			tmp.SetCanFocus(false)
			tmptarget := target
			tmp.Connect("clicked", func() {
				xsi.XSITransfer(xsiConfig, def, owner, CallID, tmptarget)
			})
			b_tr[target] = tmp
		}
	}

	table_ag := gtk.NewTable(4, count+1, false)
	var place uint = 0
	for _, target := range Config.Main.TargetID {
		if target != owner {
			place = place + 1
			table_ag.Attach(dlabel1[target], 0, 1, place, place+1, gtk.FILL, gtk.FILL, 1, 1)
			table_ag.Attach(dlabel3[target], 2, 3, place, place+1, gtk.FILL, gtk.FILL, 1, 1)
			table_ag.Attach(dlabel2[target], 1, 2, place, place+1, gtk.FILL, gtk.FILL, 1, 1)
			table_ag.Attach(b_tr[target], 3, 4, place, place+1, gtk.FILL, gtk.FILL, 1, 1)
		}
	}

	//calls
	table_cl := gtk.NewTable(2, 15, false)
	dlabel4 := make(map[uint]*gtk.Label)
	dlabel5 := make(map[uint]*gtk.Label)
	var i uint
	for i = 0; i < 15; i++ {
		dlabel4[i] = gtk.NewLabel("")
		table_cl.Attach(dlabel4[i], 0, 1, i, i+1, gtk.FILL, gtk.FILL, 1, 1)
		dlabel5[i] = gtk.NewLabel("")
		table_cl.Attach(dlabel5[i], 1, 2, i, i+1, gtk.FILL, gtk.FILL, 1, 1)
	}

	//tabs
	notebook := gtk.NewNotebook()
	notebook.AppendPage(table_ag, gtk.NewLabel("Агенты"))
	notebook.AppendPage(table_cl, gtk.NewLabel("Звонки"))

	//add all to window
	vbox := gtk.NewVBox(false, 1)
	vbox.Add(menutable)
	vbox.Add(table)
	vbox.Add(notebook)
	vbox.Add(resizearea)

	swin.AddWithViewPort(vbox)
	window.Add(swin)
	window.ShowAll()

	//main func for update
	go func() {
		for {
			select {
			case data := <-ch:
				cinfo := strings.Split(strings.Trim(data, "\n"), ";")
				//owner
				if cinfo[0] == owner && cinfo[1] == "state" {
					if cinfo[4] != "" {
						CallID = cinfo[5]
						gdk.ThreadsEnter()
						owner2.SetLabel(strings.Trim(cinfo[4], "tel:"))
						gdk.ThreadsLeave()
					} else {
						CallID = ""
						gdk.ThreadsEnter()
						owner2.SetLabel("")
						gdk.ThreadsLeave()
					}
					if cinfo[3] == "Available" {
						gdk.ThreadsEnter()
						owner3.SetFromPixbuf(pix["green"])
						gdk.ThreadsLeave()
					} else if cinfo[3] == "Wrap-Up" {
						gdk.ThreadsEnter()
						owner3.SetFromPixbuf(pix["yellow"])
						gdk.ThreadsLeave()
						timer.Reset(time.Second * Config.Main.Wraptime)
					} else {
						gdk.ThreadsEnter()
						owner3.SetFromPixbuf(pix["grey"])
						gdk.ThreadsLeave()
					}
				}
				//CC q
				if cinfo[0] == Config.Main.CCID && cinfo[1] == "state" {
					if cinfo[6] != "" {
						gdk.ThreadsEnter()
						qlabel2.SetLabel(cinfo[6])
						gdk.ThreadsLeave()
					}
				}
				//CC calls
				if cinfo[0] == Config.Main.CCID && cinfo[1] == "calls" {
					if cinfo[3] != "" {
						var i, j uint
						j = 2
						for i = 0; i < 15; i++ {
							if cinfo[j] != "" {
								date, _ := strconv.Atoi(cinfo[j])
								date = date / 1000
								j++
								Addr := strings.Trim(cinfo[j], "tel:")
								j++
								Time := time.Unix(int64(date), 0)
								gdk.ThreadsEnter()
								tmp4 := dlabel4[i]
								tmp4.SetLabel(Time.Format(time.Stamp))
								tmp5 := dlabel5[i]
								tmp5.SetLabel(Addr)
								dlabel4[i] = tmp4
								dlabel5[i] = tmp5
								gdk.ThreadsLeave()
							}
						}
					}
				}
				//Targets
				if cinfo[0] != owner && cinfo[0] != Config.Main.CCID && cinfo[1] == "state" {
					if cinfo[2] == "On-Hook" {
						gdk.ThreadsEnter()
						tmp := dlabel3[cinfo[0]]
						tmp.SetFromPixbuf(pix["blank"])
						dlabel3[cinfo[0]] = tmp
						gdk.ThreadsLeave()
					}
					if cinfo[2] == "Off-Hook" {
						gdk.ThreadsEnter()
						tmp := dlabel3[cinfo[0]]
						tmp.SetFromPixbuf(pix["call"])
						dlabel3[cinfo[0]] = tmp
						gdk.ThreadsLeave()
					}
					if cinfo[3] == "Available" {
						gdk.ThreadsEnter()
						tmp := dlabel2[cinfo[0]]
						tmp.SetFromPixbuf(pix["green"])
						dlabel2[cinfo[0]] = tmp
						gdk.ThreadsLeave()
					} else if cinfo[3] == "Wrap-Up" {
						gdk.ThreadsEnter()
						tmp := dlabel2[cinfo[0]]
						tmp.SetFromPixbuf(pix["yellow"])
						dlabel2[cinfo[0]] = tmp
						gdk.ThreadsLeave()
					} else {
						gdk.ThreadsEnter()
						tmp := dlabel2[cinfo[0]]
						tmp.SetFromPixbuf(pix["grey"])
						dlabel2[cinfo[0]] = tmp
						gdk.ThreadsLeave()
					}
				}
				//timer for wrap-up
			case <-timer.C:
				ocip.OCIPsend(ociConfig, "UserCallCenterModifyRequest19", ConcatStr("", "userId=", owner), "agentACDState=Available")
			}
		}
	}()
	gtk.Main()
}
Пример #21
0
func main() {
	hostAPI := flag.String("api", "http://mycel:9000", "mycel host (api)")
	hostWS := flag.String("ws", "ws://mycel:9001", "mycel host (ws)")
	flag.Parse()

	// Get the Mac-address of client
	eth0, err := ioutil.ReadFile("/sys/class/net/eth0/address")
	if err != nil {
		log.Fatal(err)
	}
	MAC := strings.TrimSpace(string(eth0))

	// Identify the client
	var client *Client
	for {
		client, err = identify(*hostAPI, MAC)
		if err != nil {
			if err.Error() == "404 Not Found" {
				log.Fatal("client MAC address not found in mycel DB: ", MAC)
			}
			log.Println("Couldn't reach Mycel server. Trying again in 1 seconds...")
			time.Sleep(1 * time.Second)
			continue
		}
		break
	}

	// Do local modifications to the client's environment

	// 1. Screen Resolution
	if client.ScreenRes != "auto" {
		xrandr, err := exec.Command("/usr/bin/xrandr").Output()
		if err != nil {
			log.Println("failed to run xrandr", err)
		}
		rgx := regexp.MustCompile(`([\w]+)\sconnected`)
		display := rgx.FindSubmatch(xrandr)[1]
		cmd := exec.Command("/bin/sh", "-c", "/usr/bin/xrandr --output "+string(display)+" --mode "+client.ScreenRes)
		output, err := cmd.CombinedOutput()
		if err != nil {
			log.Println("failed to set screen resolution: ", string(output))
		}
	}

	// 2. Firefox homepage
	if client.Options.Homepage != nil {
		escHomepage := strings.Replace(*client.Options.Homepage, `/`, `\/`, -1)

		sed := `/bin/sed -i 's/user_pref("browser.startup.homepage",.*/user_pref("browser.startup.homepage","` +
			escHomepage + `");/' $HOME/.mozilla/firefox/*.default/prefs.js`
		cmd := exec.Command("/bin/sh", "-c", sed)
		output, err := cmd.CombinedOutput()
		if err != nil {
			log.Println("failed to set Firefox startpage: ", string(output))
		}
	}

	// 3. Printer address
	if client.Options.Printer != nil {
		cmd := exec.Command("/bin/sh", "-c", "/usr/bin/sudo -n /usr/sbin/lpadmin -p publikumsskriver -v "+*client.Options.Printer)
		output, err := cmd.CombinedOutput()
		if err != nil {
			log.Println("failed to set network printer address:", string(output))
		}
	}

	// Get today's closing time from client API response
	var hm string
	now := time.Now()
	switch now.Weekday() {
	case time.Monday:
		hm = *client.Options.Hours.MonCl
	case time.Tuesday:
		hm = *client.Options.Hours.TueCl
	case time.Wednesday:
		hm = *client.Options.Hours.WedCl
	case time.Thursday:
		hm = *client.Options.Hours.ThuCl
	case time.Friday:
		hm = *client.Options.Hours.FriCl
	case time.Saturday:
		hm = *client.Options.Hours.SatCl
	case time.Sunday:
		hm = *client.Options.Hours.SunCl
	}

	// Convert closing time to datetime
	hour, _ := strconv.Atoi(hm[0:2])
	min, _ := strconv.Atoi(hm[3:])
	closingTime := time.Date(now.Year(), now.Month(), now.Day(), hour, min-*client.Options.Hours.Min, 0, 0, time.Local)

	// Show login screen
	gtk.Init(nil)
	var user, userType string
	var userMinutes, extraMinutes int
	if client.ShortTime {
		userMinutes = *client.Options.ShortTimeLimit
		extraMinutes = 0
		user = window.ShortTime(client.Name, userMinutes)
	} else {
		extraMinutes = *client.Options.Minutes - DefaultMinutes
		user, userMinutes, userType = window.Login(*hostAPI, client.Name, extraMinutes, *client.Options.AgeL, *client.Options.AgeH)
		if userType == "G" {
			// If guest user, minutes is user.minutes left or the minutes limit on the client
			tempMinutes := int(math.Min(float64(userMinutes), float64(*client.Options.Minutes)))
			extraMinutes = tempMinutes - userMinutes
		}
	}

	// Calculate how long until closing time.
	// Adjust minutes acording to closing hours, so that maximum minutes does
	// not exceed available minutes until closing
	untilClose := int(closingTime.Sub(now).Minutes())
	if userMinutes+extraMinutes > untilClose {
		extraMinutes = untilClose - userMinutes
	}

	// Show status window
	conn := connect(*hostWS, user, client.Id)
	gdk.ThreadsInit()
	status := new(window.Status)

	status.Init(client.Name, user, userMinutes+extraMinutes)
	status.Show()
	status.Move()

	// goroutine to check for websocket messages and update status window
	// with number of minutes left
	go func() {
		var msg message
		for {
			err := websocket.JSON.Receive(conn, &msg)
			if err != nil {
				if err == io.EOF {
					println("ws disconnected")
					// reconnect
					conn = connect(*hostWS, user, client.Id)
				}
				continue
			}

			if msg.Status == "ping" {
				if msg.User.Minutes+extraMinutes <= 0 {
					gtk.MainQuit()
				}
				gdk.ThreadsEnter()
				status.SetMinutes(msg.User.Minutes + extraMinutes)
				gdk.ThreadsLeave()
			}
		}
	}()

	// This blocks until the 'logg out' button is clicked, or until the user
	// has spent all minutes
	gtk.Main()

	// Send log-out message to server
	logOffMsg := logOnOffMessage{Action: "log-off", Client: client.Id, User: user}
	err = websocket.JSON.Send(conn, logOffMsg)
	if err != nil {
		// Don't bother to resend. Server will log off user anyway, when the
		// connection is closed
	}

	// Force session restart
	cmd := exec.Command("/bin/sh", "-c", "/usr/bin/killall /usr/bin/lxsession")
	err = cmd.Run()
}
Пример #22
0
func gthread(f func()) {
	gdk.ThreadsEnter()
	defer gdk.ThreadsLeave()
	f()
}