/* -*-mode:java; c-basic-offset:2; -*- */ /* WeirdX - Guess. * * Copyright (C) 1999-2004 JCraft, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ package com.jcraft.weirdx; import java.io.*; import java.awt.*; import java.awt.image.*; import java.awt.event.KeyEvent; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; import java.awt.event.KeyListener; import java.awt.event.MouseEvent; import java.awt.event.KeyEvent; import java.awt.event.InputEvent; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; //import com.sun.java.swing.*; import javax.swing.*; class DDXWindow extends JPanel implements MouseListener, MouseMotionListener { private static final byte s=0; // start private static final byte sp=1; // press private static final byte spp=2; // press, press private static final byte sppr=3; // press, press, release private static byte threeBstate=s; private static MouseEvent threeBPressed=null; private static boolean threeButton=false; private static final int InputOnly=2; private static Client serverClient=null; private static DDXWindow ddxwindow=null; static void init(Screen[] scrn, boolean tb){ Window root=scrn[0].root; serverClient=root.client; ddxwindow=root.ddxwindow; threeButton=tb; } Window window; int width, height; int bw; boolean bwc=false; static Event event=new Event(); Image offi=null; Graphics offg=null; static int px, py; Rectangle exposed=new Rectangle(); DDXWindow(){ } void init(Window w){ this.window=w; this.bw=w.borderWidth; bwc=true; setSize(w.width, w.height); addMouseListener(this); addMouseMotionListener(this); //addKeyListener(this); px=0; py=0; enableEvents(AWTEvent.KEY_EVENT_MASK); setVisible(false); //??? setLayout(null); } void setBorder(int bw){ if(this.bw!=bw){ this.bw=bw; bwc=true; } } public void setVisible(boolean b){ if(b){ if(offi==null && window.clss!=InputOnly){ allocImage(); } if(window!=window.screen.root && !isVisible()){ exposed.setBounds(0, 0, 0, 0); } super.setVisible(true); } else{ if(isVisible()){ super.setVisible(false); if(window!=window.screen.root && window.screen.root.width*window.screen.root.height/4<= window.width*window.height){ freeImage(); exposed.setBounds(0, 0, 0, 0); } } } } public void setLocation(int x, int y){ if(getX()==x && getY()==y) return; if(window!=null && window.parent!=null){ int orgx=getX()-window.parent.borderWidth+window.borderWidth; int orgy=getY()-window.parent.borderWidth+window.borderWidth; int bitgrabity=window.attr&(15<<8); if(orgx<0 || orgy<0){ if(orgx<0 && orgx0 && (r.x<=bw || r.y<=bw || (width+bw)<=(r.width+r.x) || (height+bw)<=(r.height+r.y)) ){ if(window.isBorderPixel()){ g.setColor(window.getColormap().getColor(window.border.pixel)); } else{ g.setColor(Color.black); } for(int i=bw-1;0<=i; i--){ g.drawRect(i, i, width+2*bw-i*2-1, height+2*bw-i*2-1); } } if(!window.screen.multimode || window==window.screen.root){ if(LogoImage.logoimage!=null && window.x+r.x<=LogoImage.logoimagewidth && window.y+r.y<=LogoImage.logoimageheight){ g.drawImage(LogoImage.logoimage, 0, 0, LogoImage.logoimagewidth-(window.x-bw), LogoImage.logoimageheight-(window.y-bw), window.x-bw, window.y-bw, LogoImage.logoimagewidth, LogoImage.logoimageheight, this); } else{ } } } public boolean isOpaque(){ if(isVisible()){ if(window.clss==InputOnly){ return false; } return super.isOpaque(); } return false; } private final void expunion(Rectangle r) { int x1=Math.min(exposed.x, r.x); int x2=Math.max(exposed.x+exposed.width, r.x+r.width); int y1=Math.min(exposed.y, r.y); int y2=Math.max(exposed.y+exposed.height, r.y+r.height); exposed.setBounds(x1, y1, x2-x1, y2-y1); } private final boolean expcontains(int X, int Y, int W, int H) { int ww=exposed.width; int hh=exposed.height; if (ww<=0 || hh<=0 || W<=0 || H<=0) { return false; } int xx=exposed.x; int yy=exposed.y; return (X>=xx && Y>=yy && X+W<=xx+ww && Y+H<=yy+hh); } public void update(Graphics g){ System.out.println("update: "); } public void paint(Graphics g){ try{ // ????? super.paint(g); }catch(Exception e){ return; } Client client=window.client; if(client==null || client==serverClient) return; Rectangle r=g.getClip().getBounds(); if(exposed.width==0){ exposed.setBounds(r); } else if(expcontains(r.x, r.y, r.width, r.height)){ return; } else{ expunion(r); } event.mkExpose(window.id, r.x, r.y, r.width, r.height, 0); try{ window.sendEvent(event, 1, null); } catch(Exception ee){} } public void setBorderPixmap(Pixmap p){ } public void mouseClicked(MouseEvent e){ } public void mouseEntered(MouseEvent e){ String str=CopyPaste.getString(); if(!CopyPaste.isOwner() && str!=null){ synchronized(window.screen.root){ Property p=window.screen.root.getProperty(); while(p!=null){ if(p.propertyName==9)break; p=p.next; } if(p!=null){ p.data=str.getBytes(); p.size=(p.data.length<256 ? p.data.length : 256); } } Selection sel=Selection.getSelection(1); // PRIMARY if(sel!=null && sel.client!=null){ int time=(int)System.currentTimeMillis(); Event event=new Event(); event.mkSelectionClear(time, sel.wid, sel.selection); try{ sel.client.sendEvent(event, 1, Event.NoEventMask, Event.NoEventMask, null); } catch(Exception ee){ //System.out.println(ee); }; sel.window=window.screen.root; sel.wid=window.screen.root.id; sel.lastTimeChanged=time; sel.client=null; } CopyPaste.setString(str); } if(window.id==window.screen.rootId){ return; } if(window.isMapped()){ requestFocus(); Window.focus.win=window.id; } int x=e.getX()+window.x; int y=e.getY()+window.y; Window.sprite.hot.x=x; Window.sprite.hot.y=y; int mod=e.getModifiers(); int state=0; if((mod & InputEvent.BUTTON1_MASK)!=0) state|=(1<<8); if((mod & InputEvent.BUTTON2_MASK)!=0) state|=(1<<9); if((mod & InputEvent.BUTTON3_MASK)!=0) state|=(1<<10); if((mod & InputEvent.SHIFT_MASK)!=0) state|=1; if((mod & InputEvent.CTRL_MASK)!=0) state|=4; // alt -> state|=8; Client client=window.client; if(client==null || client==serverClient) return; event.mkEnterNotify(0, // Ancestor window.screen.rootId, window.id, 0, x, y, e.getX(), e.getY(), state, 0, // Normal 0x1|0x02 // focus|same-screen ); try{ Window.sendDeviceEvent(window, event, Window.grab, null, 1); } catch(Exception ee){ } } public void mouseExited(MouseEvent e){ if(window.id==window.screen.rootId){ return; } int x=e.getX()+window.x; int y=e.getY()+window.y; Window.sprite.hot.x=x; Window.sprite.hot.y=y; int mod=e.getModifiers(); int state=0; if((mod & InputEvent.BUTTON1_MASK)!=0) state|=(1<<8); if((mod & InputEvent.BUTTON2_MASK)!=0) state|=(1<<9); if((mod & InputEvent.BUTTON3_MASK)!=0) state|=(1<<10); if((mod & InputEvent.SHIFT_MASK)!=0) state|=1; if((mod & InputEvent.CTRL_MASK)!=0) state|=4; // alt -> state|=8; Client client=window.client; if(client==null || client==serverClient) return; event.mkLeaveNotify(0, // Ancestor window.screen.rootId, window.id, 0, x, y, e.getX(), e.getY(), state, 0, // Normal 0x1|0x02 // focus|same-screen ); try{ Window.sendDeviceEvent(window, event, Window.grab, null, 1); } catch(Exception ee){ } } public void mousePressed(MouseEvent e){ if(threeButton){ if(threeBstate==s){ threeBPressed=e; threeBstate=sp; return; } if(threeBstate==sp // || threeBstate==sppr ){ threeBPressed=null; threeBstate=spp; e=new MouseEvent((Component)e.getSource(), e.getID(), e.getWhen(), (e.getModifiers()&(~(InputEvent.BUTTON1_MASK|InputEvent.BUTTON3_MASK)))|InputEvent.BUTTON2_MASK, e.getX(), e.getY(), e.getClickCount(), e.isPopupTrigger()); } } procPressed(e); } private void procPressed(MouseEvent e){ int x=e.getX()+window.x; int y=e.getY()+window.y; Window.sprite.hot.x=x; Window.sprite.hot.y=y; int mod=e.getModifiers(); if(mod==0){ mod|=InputEvent.BUTTON1_MASK; } // ????? int state=0; int detail=1; if((mod & InputEvent.BUTTON1_MASK)!=0) detail=1; if((mod & InputEvent.BUTTON2_MASK)!=0) detail=2; if((mod & InputEvent.BUTTON3_MASK)!=0) detail=3; if((mod & InputEvent.SHIFT_MASK)!=0) state|=1; if((mod & InputEvent.CTRL_MASK)!=0) state|=4; // alt -> state|=8; Event.filters[Event.MotionNotify]=Event.PointerMotionMask| Event.ButtonMotionMask | ((Event.Button1Mask>>1)< state|=8; Window.sprite.hot.state=state; } public void mouseReleased(MouseEvent e){ if(threeButton){ if(threeBstate==sppr){ threeBPressed=null; threeBstate=s; return; } if(threeBstate==sp){ procPressed(threeBPressed); threeBPressed=null; threeBstate=s; } else if(threeBstate==spp){ threeBPressed=null; threeBstate=sppr; e=new MouseEvent((Component)e.getSource(), e.getID(), e.getWhen(), (e.getModifiers()&(~(InputEvent.BUTTON1_MASK|InputEvent.BUTTON3_MASK)))|InputEvent.BUTTON2_MASK, e.getX(), e.getY(), e.getClickCount(), e.isPopupTrigger()); } } procReleased(e); } private void procReleased(MouseEvent e){ int x=e.getX()+window.x; int y=e.getY()+window.y; Window.sprite.hot.x=x; Window.sprite.hot.y=y; int mod=e.getModifiers(); int state=0; int detail=0; if((mod & InputEvent.BUTTON1_MASK)!=0){ state|=(1<<8); detail=1;} if((mod & InputEvent.BUTTON2_MASK)!=0){ state|=(1<<9); detail=2;} if((mod & InputEvent.BUTTON3_MASK)!=0){ state|=(1<<10); detail=3;} if((mod & InputEvent.SHIFT_MASK)!=0) state|=1; if((mod & InputEvent.CTRL_MASK)!=0) state|=4; // alt -> state|=8; Window.sprite.hot.state=0; // ????? Event.filters[Event.MotionNotify]=Event.PointerMotionMask/*| ((Event.Button1Mask>>1)< 16 // button 2 -> 8 // button 3 -> 4 // shift -> 1 // control -> 2 // alt -> 12 ?? int state=0; int detail=0; if((mod & InputEvent.BUTTON1_MASK)!=0){ state|=(1<<8); detail=1;} if((mod & InputEvent.BUTTON2_MASK)!=0){ state|=(1<<9); detail=2;} if((mod & InputEvent.BUTTON3_MASK)!=0){ state|=(1<<10); detail=3;} if((mod & InputEvent.SHIFT_MASK)!=0) state|=1; if((mod & InputEvent.CTRL_MASK)!=0) state|=4; // alt -> state|=8; Window.sprite.hot.state=state; px=x; py=y; event.mkMotionNotify(1, window.screen.rootId, /*window.id,*/ Window.sprite.win.id, 0, px, py, e.getX(), e.getY(), state, 1); try{ if(!Window.checkMotion(event, window)){ return; } event.mkMotionNotify(1, window.screen.rootId, /*window.id,*/ Window.sprite.win.id, 0, px, py, px-Window.sprite.win.x, py-Window.sprite.win.y, //e.getX(), //e.getY(), state, 1); if(Window.grab!=null) Window.sendGrabbedEvent(event, false, 1); else Window.sendDeviceEvent(Window.sprite.win, event, Window.grab, null, 1); } catch(Exception ee){ } } public void mouseMoved(MouseEvent e){ int x=e.getX()+window.x; int y=e.getY()+window.y; Window.sprite.hot.x=x; Window.sprite.hot.y=y; int mod=e.getModifiers(); int state=0; px=x; py=y; if((mod & InputEvent.BUTTON1_MASK)!=0) state|=(1<<8); if((mod & InputEvent.BUTTON2_MASK)!=0) state|=(1<<9); if((mod & InputEvent.BUTTON3_MASK)!=0) state|=(1<<10); if((mod & InputEvent.SHIFT_MASK)!=0) state|=1; if((mod & InputEvent.CTRL_MASK)!=0) state|=4; // alt -> state|=8; Window.sprite.hot.state=state; event.mkMotionNotify(0, window.screen.rootId, window.id, 0, x, y, x-window.x, y-window.y, state, 1); try{ if(!Window.checkMotion(event, window)){ return; } if(Window.grab!=null) Window.sendGrabbedEvent(event, false, 1); else Window.sendDeviceEvent(window, event, Window.grab, null, 1); } catch(Exception ee){ } } public void processKeyEvent(KeyEvent e){ int id=e.getID(); if(id==KeyEvent.KEY_PRESSED) { keyPressed(e); } else if(id==KeyEvent.KEY_RELEASED) { keyReleased(e); } else if(id==KeyEvent.KEY_TYPED) { keyTyped(e); } e.consume(); // ?? } public void keyPressed(KeyEvent e){ if(!window.isMapped()) return; // Easter Egg... if(window==window.screen.root && 0 "+e); } Image getImage(){ if(offi==null) allocImage(); return offi; } Image getImage(GC gc, int x, int y, int w, int h){ Image i=getImage(); if(gc!=null && gc.clip_mask!=null && gc.clip_mask instanceof ClipPixmap){ TransparentFilter tf=new TransparentFilter(0, 0, (Pixmap)(gc.clip_mask.getMask())); i=Toolkit.getDefaultToolkit(). createImage(new FilteredImageSource(i.getSource(), tf)); } return i; } Graphics getGraphics2(){ if(window.clss==InputOnly){ return getGraphics(); } if(!isVisible()){ return null; } // Graphics g=getGraphics(); if(offg==null) allocImage(); Graphics g=offg; return g; } final Graphics getGraphics(GC gc, int mask){ if(!isVisible()){ return null; } if(offg==null) allocImage(); Graphics graphics=offg; if((mask&GC.GCSubwindowMode)!=0 && (gc.attr&GC.IncludeInferiors)!=0){ graphics=getGraphics(); window.currentGC=null; } else{ if(gc==window.currentGC && gc.time==window.gctime && (mask&~window.gmask)==0){ //System.out.println("DDXWindow skip"); return graphics; } window.gctime=gc.time; window.currentGC=gc; window.gmask=mask; } if(gc.clip_mask!=null && gc.clip_mask instanceof ClipRectangles){ java.awt.Rectangle rec=(Rectangle)(gc.clip_mask.getMask()); if(rec!=null){ graphics=offg; } if(rec==null || (rec.x==0 && rec.y==0 && rec.width==window.width && rec.height==window.height)){ // return graphics; } else{ graphics.setClip(rec.x, rec.y, rec.width, rec.height); } } if((mask&GC.GCFunction)!=0){ Color color=window.getColormap().getColor(gc.fgPixel); if(gc.function==GC.GXxor){ window.gmask&=~GC.GCFunction; graphics.setXORMode(new Color((color.getRGB() ^ graphics.getColor().getRGB())&0xffffff)); } else if(gc.function==GC.GXinvert){ window.gmask&=~GC.GCFunction; graphics.setXORMode(window.screen.defaultColormap.getColor(window.background.pixel)); } else{ graphics.setColor(color); } } if((mask&GC.GCFont)!=0){ Font font=gc.font; graphics.setFont(font.getFont()); } if((mask&GC.GCLineWidth)!=0 || (mask&GC.GCLineStyle)!=0 || (mask&GC.GCCapStyle)!=0 || (mask&GC.GCJoinStyle)!=0 ){ } return graphics; } void drawImage(Clip clip, Image img, int dx, int dy, int w, int h) { if(clip==null || (clip instanceof ClipPixmap)){ drawImage(img, dx, dy, w, h); return; } ClipRectangles rclip=(ClipRectangles)clip; java.awt.Rectangle rec=rclip.masks[0]; if(offg==null) allocImage(); java.awt.Shape tmp=offg.getClip(); if(tmp==null) { tmp=new Rectangle(0, 0, window.width, window.height); } offg.clipRect(rec.x, rec.y, rec.width, rec.height); drawImage(img, dx, dy, w, h); for(int i=1; i