OPTION MEMSTREAM TRUE
SETENVIRON "LANG", "C"
TRAP LOCAL
RECORD Menu_Icon[50]
LOCAL sPath$ TYPE STRING
LOCAL sDescription$ TYPE STRING
LOCAL iMenuID TYPE int
END RECORD
CONST MaxCnt = 50
GLOBAL iCurrentMenu TYPE int
GLOBAL iMaxMenus TYPE int
GLOBAL iEntries TYPE int
GLOBAL iMaxEntries TYPE int
GLOBAL mudatafile$
GLOBAL muidx, mucnt TYPE int
GLOBAL puptray_pid TYPE int
GLOBAL old_puptray_pid TYPE int
GLOBAL NUL TYPE STRING
CONST GDK_INTERP_NEAREST = 0
CONST GDK_INTERP_BILINEAR = 2
IMPORT "gtk_status_icon_set_tooltip(long,char*)" FROM "libgtk-x11-2.0.so" TYPE void
IMPORT "gtk_status_icon_set_visible(long,int)" FROM "libgtk-x11-2.0.so" TYPE void
IMPORT "gtk_status_icon_position_menu(long,int*,int*,int*,long)" FROM "libgtk-x11-2.0.so" TYPE void
IMPORT "g_signal_connect_data(long,char*,void*,long,long,int)" FROM "libgobject-2.0.so" TYPE void
IMPORT "gtk_main" FROM "libgtk-x11-2.0.so" TYPE void
IMPORT "gtk_init(int*,void*)" FROM "libgtk-x11-2.0.so" TYPE void
IMPORT "gtk_menu_new" FROM "libgtk-x11-2.0.so" TYPE long
IMPORT "gtk_menu_popup(long,long,long,void*,long,int,int)" FROM "libgtk-x11-2.0.so" TYPE void
IMPORT "gtk_menu_item_new_with_label(char*)" FROM "libgtk-x11-2.0.so" TYPE long
IMPORT "gtk_widget_show_all(long)" FROM "libgtk-x11-2.0.so" TYPE void
IMPORT "gtk_main_quit" FROM "libgtk-x11-2.0.so" TYPE void
IMPORT "gtk_status_icon_set_blinking(long,int)" FROM "libgtk-x11-2.0.so" TYPE void
IMPORT "gtk_menu_shell_append(long,long)" FROM "libgtk-x11-2.0.so" TYPE void
IMPORT "gtk_status_icon_new_from_stock(char*)" FROM "libgtk-x11-2.0.so" TYPE long
IMPORT "gtk_separator_menu_item_new" FROM "libgtk-x11-2.0.so" TYPE long
IMPORT "gtk_status_icon_new_from_file(char*)" FROM "libgtk-x11-2.0.so" TYPE long
IMPORT "gtk_widget_destroy(long)" FROM "libgtk-x11-2.0.so" TYPE void
IMPORT "gtk_dialog_run(long)" FROM "libgtk-x11-2.0.so" TYPE int
IMPORT "gtk_window_set_title(long,char*)" FROM "libgtk-x11-2.0.so" TYPE void
IMPORT "gtk_message_dialog_new(long,int,int,int,char*,...)" FROM "libgtk-x11-2.0.so" TYPE long
IMPORT "gtk_window_set_position(long,int)" FROM "libgtk-x11-2.0.so" TYPE void
IMPORT "gtk_image_set_from_file(long,char*)" FROM "libgtk-x11-2.0.so" TYPE void
IMPORT "gtk_image_new_from_file(char*)" FROM "libgtk-x11-2.0.so" TYPE long
IMPORT "gtk_container_add(long,long)" FROM "libgtk-x11-2.0.so" TYPE void
IMPORT "gtk_image_menu_item_new_with_label(char*)" FROM "libgtk-x11-2.0.so" TYPE long
IMPORT "gtk_image_new_from_stock(char*,int)" FROM "libgtk-x11-2.0.so" TYPE long
IMPORT "gtk_image_menu_item_set_image(long,long)" FROM "libgtk-x11-2.0.so" TYPE void
IMPORT "gtk_image_new_from_icon_name(char*,int)" FROM "libgtk-x11-2.0.so" TYPE long
IMPORT "g_object_set(long,char*,...)" FROM "libgobject-2.0.so" TYPE void
IMPORT "gdk_pixbuf_new_from_file(char*,void*)" FROM "libgdk_pixbuf-2.0.so.0" TYPE long
IMPORT "gdk_pixbuf_scale_simple(long,int,int,int)" FROM "libgdk_pixbuf-2.0.so.0" TYPE long
IMPORT "gtk_image_new_from_pixbuf(long)" FROM "libgtk-x11-2.0.so" TYPE long
DECLARE my_menu, status_icon
DEF FN MSGBOX_OK(t,m) = MsgBox(t,m,0,1)
SUB MY_STATUS_MESSAGE(STRING my_message_text$)
LOCAL my_preamble$
my_preamble$ = " -bg red -fg white -title 'Pup-Tray: Status ' -center "
SYSTEM CONCAT$("gxmessage ", my_preamble$, my_message_text$)
END SUB
SUB CHECK_PIDS()
LOCAL mypids$, my_response$
myprog$ = ARGUMENT$
SPLIT myprog$ BY " " TO myprog_array$ SIZE argcount
myprog_clean$ = MID$(myprog_array$[0], INSTRREV(myprog_array$[0], "/") + 1)
mypids$ = CHOP$(EXEC$(CONCAT$("pidof ", myprog_clean$)))
SPLIT mypids$ BY " " TO pid_array$ SIZE pidcount
IF pidcount > 2 THEN
my_response$ = CONCAT$("Sorry, ", myprog_clean$, " is already running...")
MY_STATUS_MESSAGE(CONCAT$(" -timeout 2 ", CHR$(13), "' '", my_response$))
PRINT my_response$
END
ELSE
PRINT "Starting ", myprog_clean$, " ..."
END IF
END SUB
FUNCTION Tally(STRING Main$,STRING Match$)
LOCAL i,j,k,mlen,matchlen TYPE int
mlen = LEN(Main$)
matchlen = LEN(Match$)
i = 1 : j = 0 : k = 0
IF (mlen EQ 0) OR (matchlen EQ 0) THEN
RETURN j
END IF
WHILE 1 DO
IF EQUAL(MID$(Main$,i,matchlen),Match$) THEN
j = j + 1
END IF
i = i + matchlen
IF i > mlen THEN
BREAK
END IF
WEND
RETURN j
END FUNCTION
FUNCTION MsgBox(STRING title$,STRING Msg$,NUMBER typ,NUMBER but)
LOCAL hDlg,rv, pixbuf, errmsg
hDlg = gtk_message_dialog_new (0, 0, typ, but, Msg$)
gtk_window_set_position(hDlg, 1)
gtk_window_set_title(hDlg, title$)
rv = gtk_dialog_run (hDlg)
gtk_widget_destroy (hDlg)
RETURN rv
END FUNCTION
FUNCTION IdxCount(char* fname)
LOCAL filelen, buffer
filelen = FILELEN(fname)
buffer = MEMORY(filelen)
OPEN fname FOR READING AS fh
GETBYTE buffer FROM fh SIZE filelen
CLOSE FILE fh
OPEN buffer FOR MEMORY AS str$
iMaxEntries = Tally(str$,NL$)
CLOSE MEMORY str$
FREE buffer
RETURN iMaxEntries
END FUNCTION
SUB destroy(NUMBER widget, void* data)
gtk_main_quit
END SUB
SUB on_menu_click(NUMBER widget, void* data)
LOCAL click
click = (long)data
SYSTEM CONCAT$(Menu_Icon[click].sPath$, " &")
END SUB
SUB help()
LOCAL msg$, title$
title$ = "PupTray Help"
msg$ = "PupTray is a small application that resides in the system\n"
msg$ = CONCAT$(msg$, "tray and provides a way for you to quickly launch your favorite programs.")
msg$ = CONCAT$(msg$, "There's even a menu item to quickly edit your configuration file built in.")
msg$ = CONCAT$(msg$, "To use just place the PupTray binary file in your startup folder so it runs ")
msg$ = CONCAT$(msg$, "on startup.\n\n")
msg$ = CONCAT$(msg$, "Config file format: Name=Application [app parameters]\n\n")
msg$ = CONCAT$(msg$, "Example:",NL$,NL$)
msg$ = CONCAT$(msg$, "Geany=geany ","[\"some text file\"]",NL$)
msg$ = CONCAT$(msg$, "Browser=seamonkey ","[\"some url\"]",NL$,NL$)
msg$ = CONCAT$(msg$, "Anywhere you want a menu seperator, just add ",CHR$(34),"+++",CHR$(34),NL$,NL$)
msg$ = CONCAT$(msg$, "Have Fun!\n")
MSGBOX_OK(title$,msg$)
END SUB
FUNCTION find_icon$(STRING iconame$)
LOCAL tmpname$ TYPE STRING
LOCAL dirname$[5]
LOCAL i
dirname$[0] = "/usr/local/PupTray/icons/"
dirname$[1] = "/usr/share/pixmaps/"
dirname$[2] = "/usr/local/lib/X11/mini-icons/"
dirname$[3] = "/usr/local/lib/X11/pixmaps/"
dirname$[4] = "/usr/share/icons/hicolor/16x16/apps/"
IF EQUAL(LEFT$(iconame$, 7), "default") THEN
OPEN CONCAT$("/usr/local/bin/",iconame$) FOR READING AS FP1
WHILE NOT(ENDFILE(FP1)) DO
READLN szInput$ FROM FP1
szInput$ = CHOP$(szInput$)
IF NOT(ENDFILE(FP1)) THEN
IF EQUAL(LEFT$(szInput$, 4), "exec") THEN
SPLIT szInput$ BY " " TO array$ SIZE dim
iconame$ = array$[1]
END IF
ENDIF
WEND
CLOSE FILE FP1
END IF
FOR i = 0 TO 4
tmpname$ = CONCAT$(dirname$[i],iconame$,".png")
IF FILEEXISTS(tmpname$) THEN RETURN tmpname$
tmpname$ = CONCAT$(dirname$[i],iconame$,".xpm")
IF FILEEXISTS(tmpname$) THEN RETURN tmpname$
NEXT i
tmpname$ = "/usr/local/PupTray/icons/default.png"
IF FILEEXISTS(tmpname$) THEN RETURN tmpname$
RETURN ""
END FUNCTION
SUB popup(NUMBER status_icon, int button, int activate_time, void* user_data)
LOCAL item, i
my_menu = 0
CALL fillarray ()
IF NOT(my_menu) THEN
my_menu = gtk_menu_new()
FOR i = 0 TO mucnt-1
IF INSTR(Menu_Icon[i].sDescription$, "+++") > 0 THEN
item = gtk_separator_menu_item_new()
ELSE
item = gtk_image_menu_item_new_with_label(Menu_Icon[i].sDescription$)
Menu_Icon[i].sPath$ = CONCAT$(Menu_Icon[i].sPath$," ")
pos = INSTR(Menu_Icon[i].sPath$," ")
icon$ = find_icon$(CHOP$(LEFT$(Menu_Icon[i].sPath$, pos)))
gdk = gdk_pixbuf_new_from_file(icon$, NUL)
scaled_gdk = gdk_pixbuf_scale_simple(gdk, 16, 16, GDK_INTERP_BILINEAR)
stock = gtk_image_new_from_pixbuf(scaled_gdk)
gtk_image_menu_item_set_image(item, stock)
g_object_set(item, "always-show-image", TRUE, 0)
END IF
gtk_menu_shell_append(my_menu, item)
g_signal_connect_data(item, "activate", on_menu_click, Menu_Icon[i].iMenuID, 0, 0)
NEXT i
item = gtk_separator_menu_item_new()
gtk_menu_shell_append(my_menu, item)
item = gtk_image_menu_item_new_with_label("Help")
stock = gtk_image_new_from_stock("gtk-help", 1)
gtk_image_menu_item_set_image(item, stock)
g_object_set(item, "always-show-image", TRUE, 0)
gtk_menu_shell_append(my_menu, item)
g_signal_connect_data(item, "activate", help, 0, 0, 0)
item = gtk_image_menu_item_new_with_label("Quit")
stock = gtk_image_new_from_stock("gtk-quit", 1)
gtk_image_menu_item_set_image(item, stock)
g_object_set(item, "always-show-image", TRUE, 0)
gtk_menu_shell_append(my_menu, item)
g_signal_connect_data(item, "activate", destroy, 0, 0, 0)
END IF
gtk_widget_show_all(my_menu)
gtk_menu_popup(my_menu, 0, 0, gtk_status_icon_position_menu, status_icon, button, activate_time)
END SUB
SUB fillarray()
mudatafile$ = CONCAT$(GETENVIRON$("HOME"), "/.puptray.cfg")
muidx = 0
mucnt = IdxCount(mudatafile$)
IF FILEEXISTS(mudatafile$) THEN
OPEN mudatafile$ FOR READING AS myfile
WHILE NOT(ENDFILE(myfile)) DO
READLN txt$ FROM myfile
txt$ = CHOP$(txt$)
IF INSTR(txt$, "=") > 0 THEN
SPLIT txt$ BY "=" TO array$ SIZE dim
WITH Menu_Icon[muidx]
.sPath$ = array$[1]
.sDescription$ = array$[0]
.iMenuID = muidx
END WITH
INCR muidx
END IF
IF INSTR(txt$, "+++") > 0 THEN
WITH Menu_Icon[muidx]
.sPath$ = ""
.sDescription$ = CHOP$(txt$)
.iMenuID = muidx
END WITH
INCR muidx
END IF
WEND
CLOSE FILE myfile
END IF
END SUB
CHECK_PIDS
gtk_init(0, 0)
IF NOT(FILEEXISTS(CONCAT$(GETENVIRON$("HOME"), "/.puptray.cfg"))) THEN
OPEN CONCAT$(GETENVIRON$("HOME"), "/.puptray.cfg") FOR WRITING AS settings
WRITELN "BaCon Website=firefox ",CHR$(34),"http://www.basic-converter.org/",CHR$(34) TO settings
WRITELN "+++" TO settings
WRITELN "Edit Configuration=", "gedit ",CHR$(34), GETENVIRON$("HOME"), "/.puptray.cfg",CHR$(34) TO settings
WRITELN "+++" TO settings
CLOSE FILE settings
END IF
status_icon = gtk_status_icon_new_from_file("/usr/share/pixmaps/puptray.png")
gtk_status_icon_set_visible(status_icon, TRUE)
gtk_status_icon_set_tooltip(status_icon, "Puppy Linux Quick Launcher\n\tright click for menu")
g_signal_connect_data(status_icon, "popup-menu", popup, 0, 0, 0)
gtk_main