=== modified file 'sikuli-script/src/main/java/org/sikuli/script/App.java' --- sikuli-script/src/main/java/org/sikuli/script/App.java 2010-12-20 21:52:13 +0000 +++ sikuli-script/src/main/java/org/sikuli/script/App.java 2011-04-21 09:08:03 +0000 @@ -64,7 +64,7 @@ } public App open() { - if(Env.isWindows()){ + if(Env.isWindows() || Env.isLinux()){ int pid = _osUtil.openApp(_appName); _pid = pid; Debug.history("App.open " + this.toString()); === modified file 'sikuli-script/src/main/java/org/sikuli/script/LinuxUtil.java' --- sikuli-script/src/main/java/org/sikuli/script/LinuxUtil.java 2011-02-09 22:32:21 +0000 +++ sikuli-script/src/main/java/org/sikuli/script/LinuxUtil.java 2011-04-23 03:42:02 +0000 @@ -15,6 +15,7 @@ return p.exitValue(); } catch(Exception e){ + Debug.error("switchApp: " + e.toString()); return -1; } } @@ -26,13 +27,21 @@ public int openApp(String appName){ try{ Debug.history("openApp: " + appName); - String cmd[] = {"sh", "-c", appName + " &"}; + String cmd[] = {"sh", "-c", "("+ appName + ") &\necho -n $!"}; Process p = Runtime.getRuntime().exec(cmd); + + InputStream in = p.getInputStream(); + byte pidBytes[]=new byte[64]; + int len=in.read(pidBytes); + String pidStr=new String(pidBytes,0,len); + int pid=Integer.parseInt(new String(pidStr)); p.waitFor(); - return p.exitValue(); + return pid; + //return p.exitValue(); } catch(Exception e){ - return -1; + Debug.error("openApp, crash: " + e.toString()); + return 0; } } @@ -46,37 +55,156 @@ return p.exitValue(); } catch(Exception e){ + Debug.error("closeApp: " + e.toString()); return -1; } } + private enum SearchType { + APP_NAME, + WINDOW_ID, + PID + }; public Region getFocusedWindow(){ - //FIXME - return null; + String cmd[] = {"xdotool", "getactivewindow"}; + try { + Process p = Runtime.getRuntime().exec(cmd); + InputStream in = p.getInputStream(); + BufferedReader bufin = new BufferedReader(new InputStreamReader(in)); + String str = bufin.readLine(); + long id=Integer.parseInt(str); + String hexid=String.format("0x%08x",id); + return findRegion(hexid,0,SearchType.WINDOW_ID); + } catch(IOException e) { + System.err.println("xdotool Error:"+e.toString()); + return null; + } } public Region getWindow(String appName){ return getWindow(appName, 0); } + private Region findRegion(String appName, int winNum,SearchType type){ + String winLine[]=findWindow(appName,winNum,type); + return new Region( + Integer.parseInt(winLine[3]), + Integer.parseInt(winLine[4]), + Integer.parseInt(winLine[5]), + Integer.parseInt(winLine[6]) + ); + } + + private String[] findWindow(String appName, int winNum,SearchType type){ + String found[]=null; + int numFound=0; + try { + String cmd[] = {"wmctrl", "-lpGx"}; + Process p = Runtime.getRuntime().exec(cmd); + InputStream in = p.getInputStream(); + BufferedReader bufin = new BufferedReader(new InputStreamReader(in)); + String str; + + int slash=appName.lastIndexOf("/"); + if(slash>=0) { + // remove path: /usr/bin/.... + appName=appName.substring(slash+1); + } + + if(type==SearchType.APP_NAME) { + appName=appName.toLowerCase(); + } + while ((str = bufin.readLine()) !=null) { + String winLine[]=str.split("\\s+"); + boolean ok=false; + + if(type==SearchType.WINDOW_ID) { + if(appName.equals(winLine[0])) { + ok=true; + } + } else if(type==SearchType.PID) { + if(appName.equals(winLine[2])) { + ok=true; + } + } else if(type==SearchType.APP_NAME) { + String pidFile="/proc/"+winLine[2]+"/status"; + char buf[]=new char[1024]; + FileReader pidReader=null; + try { + pidReader = new FileReader(pidFile); + pidReader.read(buf); + String pidName=new String(buf); + String nameLine[]=pidName.split("[:\n]"); + String name=nameLine[1].trim(); + if(name.equals(appName)) { + ok=true; + } + + } catch(FileNotFoundException e) { + // pid killed before we could read /proc/ + } finally { + if(pidReader!=null) pidReader.close(); + } + + if(!ok && winLine[7].toLowerCase().indexOf(appName)>=0) { + ok=true; + } + } + + if(ok) { + if(numFound>=winNum) { + found=winLine; + break; + } + numFound++; + } + } + in.close(); + p.waitFor(); + } catch(Exception e){ + Debug.error("findWindow Error:"+e.toString()); + return null; + } + return found; + } + public Region getWindow(String appName, int winNum){ - //FIXME - return null; + return findRegion(appName,winNum,SearchType.APP_NAME); } public Region getWindow(int pid){ - return null; + return getWindow(pid,0); } public Region getWindow(int pid, int winNum){ - return null; + return findRegion(""+pid,winNum,SearchType.PID); } public int closeApp(int pid){ - return -1; + String winLine[]=findWindow(""+pid,0,SearchType.PID); + if(winLine==null) return -1; + String cmd[] = {"wmctrl", "-ic", winLine[0]}; + try { + Process p = Runtime.getRuntime().exec(cmd); + p.waitFor(); + return p.exitValue(); + } catch(Exception e) { + Debug.error("closeApp Error:"+e.toString()); + return -1; + } } public int switchApp(int pid, int num){ - return -1; + String winLine[]=findWindow(""+pid,num,SearchType.PID); + if(winLine==null) return -1; + String cmd[] = {"wmctrl", "-ia", winLine[0]}; + try { + Process p = Runtime.getRuntime().exec(cmd); + p.waitFor(); + return p.exitValue(); + } catch(Exception e) { + Debug.error("closeApp Error:"+e.toString()); + return -1; + } } public void setWindowOpacity(JWindow win, float alpha){