com.jcraft.weirdx.res.XResource.java Source code

Java tutorial

Introduction

Here is the source code for com.jcraft.weirdx.res.XResource.java

Source

/* -*-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.res;

import java.io.*;
import java.util.*;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.jcraft.weirdx.Client;

public class XResource {
    private static Log LOG = LogFactory.getLog(XResource.class);

    protected static Object LOCK = Client.class;
    static final int RC_VANILLA = 0;
    static final int RC_CACHED = 1 << 31;
    public static final int RC_DRAWABLE = 1 << 30;

    static final int SERVER_BIT = 0x20000000;
    static final int SERVER_MINID = 32;
    static final int RESOURCE_ID_MASK = Client.IDMASK;

    static final int CLIENTOFFSET = Client.CLIENTOFFSET;
    protected static final int CLIENTMASK = (((1 << Client.BITSFORCLIENTS) - 1) << Client.BITSFORRESOURCES); // 0x1fc00000

    static final int RC_NEVERRETAIN = 1 << 29;
    static final int RC_LASTPREDEF = RC_NEVERRETAIN;
    static final int RC_ANY = ~0;

    protected static final int RT_WINDOW = 1 | RC_CACHED | RC_DRAWABLE;
    protected static final int RT_PIXMAP = 2 | RC_CACHED | RC_DRAWABLE;
    public static final int RT_GC = 3 | RC_CACHED;
    public static final int RT_FONT = 4;
    protected static final int RT_CURSOR = 5;
    protected static final int RT_COLORMAP = 6;
    protected static final int RT_CMAPENTRY = 7;
    protected static final int RT_OTHERCLIENT = 8 | RC_NEVERRETAIN;
    protected static final int RT_PASSIVEGRAB = 9 | RC_NEVERRETAIN;
    static final int RT_LASTPREDEF = 9;
    protected static final int RT_NONE = 0;

    static ClientResource[] clients = new ClientResource[Client.MAXCLIENTS];

    static int lastResourceType = RT_LASTPREDEF;
    static int lastResourceClass = RC_LASTPREDEF;

    public static synchronized int newType() {
        int next = lastResourceType + 1;
        if ((next & lastResourceClass) != 0)
            return 0;
        lastResourceType = next;
        return next;
    }

    static synchronized int newClss() {
        int next = lastResourceClass >> 1;
        if ((next & lastResourceType) != 0)
            return 0;
        lastResourceClass = next;
        return next;
    }

    public int id;
    int rtype;

    XResource() {
    }

    protected XResource(int id, int rtype) {
        this.id = id;
        this.rtype = rtype;
    }

    public int hashCode() {
        return id;
    }

    public boolean equals(Object o) {
        if (o == null || id != o.hashCode())
            return false;
        if (!(o instanceof XResource))
            return true;
        if (!(o instanceof Key)) {
            return rtype == ((XResource) o).rtype;
        }
        Key key = (Key) o;
        if (key.clss == 0) {
            return rtype == key.rtype;
        } else if (key.clss == RC_ANY) {
            return true;
        } else {
            return (rtype & key.clss) != 0;
        }
    }

    public static void add(XResource r) {
        int client = ((r.id & CLIENTMASK) >> CLIENTOFFSET);
        ClientResource cr = clients[client];
        cr.put(r, r);
    }

    static void RemoveResource(XResource r) {
        int client = ((r.id & CLIENTMASK) >> CLIENTOFFSET);
        ClientResource cr = clients[client];
        RemoveResource(cr, r);
    }

    static void RemoveResource(ClientResource cr, XResource r) {
        synchronized (LOCK) {
            if ((r.rtype & RC_CACHED) != 0) {
                Client.flushCache(r.id);
            }
        }
        cr.remove(r);
    }

    public static void freeResource(int id, int skip) {
        while (true) {
            XResource r = lookupIDByClass(id, RC_ANY);
            if (r == null)
                break;
            RemoveResource(r);
            try {
                if (r.rtype != skip) {
                    deleteit(r);
                }
            } catch (Exception e) {
            }
        }
    }

    static void freeResourceByType(int id, int typ, int skip) {
        XResource r = lookupIDByType(id, typ);
        if (r != null) {
            RemoveResource(r); // should check type
            try {
                if (r.rtype != skip) {
                    deleteit(r);
                }
            } catch (Exception e) {
            }
        }
    }

    public static XResource lookupIDByClass(int id, int clss) {
        int client = ((id & CLIENTMASK) >> CLIENTOFFSET);
        if (clients.length <= client)
            return null;
        ClientResource cr = clients[client];
        if (cr == null)
            return null;

        synchronized (cr) {
            try {
                cr.key.id = id;
                cr.key.clss = clss;
                XResource r = (XResource) cr.get(cr.key);
                return r;
            } catch (Exception e) {
            }
            return null;
        }
    }

    public static XResource lookupIDByType(int id, int rtype) {
        int client = ((id & CLIENTMASK) >> CLIENTOFFSET);
        if (clients.length <= client)
            return null;
        ClientResource cr = clients[client];
        if (cr == null)
            return null;

        synchronized (cr) {
            cr.key.id = id;
            cr.key.clss = 0;
            cr.key.rtype = rtype;
            XResource r = (XResource) cr.get(cr.key);
            return r;
        }
    }

    public static void freeClientNeverResources(Client c) {
        if (c == null)
            return;
        ClientResource cr = clients[c.index];
        synchronized (LOCK) {
            try {
                for (Enumeration<? extends XResource> e = cr.elements(); e.hasMoreElements();) {
                    XResource r = e.nextElement();
                    if ((r.rtype & RC_NEVERRETAIN) != 0) {
                        deleteit(r);
                        //System.out.println("freeclientResource: "+r);
                        RemoveResource(cr, r);
                    }
                }
            } catch (Exception e) {
            }
        }
    }

    public static void freeClientResources(Client c) {
        if (c == null)
            return;
        ClientResource cr = clients[c.index];
        synchronized (LOCK) {
            try {
                for (Enumeration e = cr.elements(); e.hasMoreElements();) {
                    XResource r = (XResource) e.nextElement();
                    deleteit(r);
                    RemoveResource(cr, r);
                }
            } catch (Exception e) {
            }
        }
    }

    static void deleteit(XResource r) {
        try {
            r.delete();
        } catch (Exception ee) {
            //System.out.println("r.delete: exception ->"+ee);
            //System.out.println("r="+r);
        }
    }

    void delete() throws IOException {
    }

    public static Client lookupClient(int rid) {
        XResource res = lookupIDByClass(rid, RC_ANY);
        int clientIndex = ((rid & CLIENTMASK) >> CLIENTOFFSET);
        if (clientIndex != 0 && res != null && clients[clientIndex] != null && (rid & SERVER_BIT) == 0) {
            return Client.clients[clientIndex];
        }
        return null;
    }

    public static void initClientResource(Client c) {
        ClientResource cr = clients[c.index] = new ClientResource();
        cr.fakeID = c.clientAsMask | (c.index != 0 ? SERVER_BIT : SERVER_MINID);
        cr.endFakeID = (cr.fakeID | RESOURCE_ID_MASK) + 1;
        cr.expectID = c.clientAsMask;
    }

    public static int fakeClientId(Client c) {
        int id, maxid;
        id = clients[c.index].fakeID++;
        if (id != clients[c.index].endFakeID) {
            return id;
        }
        //System.out.println("error: fakeClient "+id);
        return id;
    }

    /*
      static void dump(){
        System.out.println("Resource.dump:");
        for(int i=0; i<clients.length; i++){
          if(clients[i]==null) continue;
          ClientResource cr=clients[i];
          int j=0;
          for (Enumeration e=cr.elements() ; e.hasMoreElements();){
          Resource r=(Resource)e.nextElement();
    j++;
          }
          System.out.print("  client="+i+", gone="+Client.clients[i]+
      ", resource="+j);
          if(Client.clients[i]==null)
       System.out.println("");
          else
       System.out.println(", closeDownMode="+
        Client.clients[i].closeDownMode);
        }
      }
      static void dump(){
        System.out.println("Resource.dump:");
        for(int i=0; i<clients.length; i++){
          if(clients[i]==null) continue;
          System.out.println("  client="+i);
          ClientResource cr=clients[i];
          for (Enumeration e=cr.elements() ; e.hasMoreElements();){
    Resource r=(Resource)e.nextElement();
    System.out.println("    resource="+r);
          }
        }
      }
    */
}

class ClientResource extends Hashtable {
    int fakeID;
    int endFakeID;
    int expectID;
    Key key = new Key();
}

class Key extends XResource {
    int clss = 0;

    public int hashCode() {
        return id;
    }

    public boolean equals(Object o) {
        //System.out.println("Key: equals "+o);
        if (o == null)
            return false;
        return id == o.hashCode();
    }
}