Back to index

im-sdk  12.3.91
IMState.cpp
Go to the documentation of this file.
00001 #include <config.h>
00002 #include <stdio.h>
00003 #include "IMState.hh"
00004 #include "ICState.hh"
00005 #include "IMProtocol.hh"
00006 #include "IMLog.hh"
00007 #include "IIIMP_hotkey_profile.hh"
00008 
00009 const CARD16BIT void_im_id = 0xFFFF;
00010 const CARD16BIT void_ic_id = 0xFFFF;
00011 const int ic_id_max = 0xFFFE;
00012 
00013 IMState::IMState(
00014        CARD16BIT x_im_id,
00015        IMProtocol *x_pimp,
00016        IMHandler *x_pimh,
00017        int x_protocol_version
00018        )
00019 {
00020   pshared = new IMShared();
00021   pshared->im_id = x_im_id;
00022   pshared->pimp = x_pimp;
00023   pshared->pimh = x_pimh;
00024   pshared->hotkey_profile = new IIIMP_hotkey_profile();
00025   pshared->register_hotkey_flag = false;
00026   protocol_version = x_protocol_version;
00027   pproc_state = NULL;
00028   pbase_state = this;
00029 }
00030 
00031 IMState::~IMState()
00032 {
00033   if (!substatep()) {
00034     cleanup_ic();
00035     delete pshared->hotkey_profile;
00036     if (pshared && pshared->pimh) pshared->pimh->destroy();
00037     delete pshared;
00038     if (pproc_state) delete pproc_state;
00039   }
00040 }
00041 
00042 IMAccept* 
00043 IMState::get_imaccept()
00044 {
00045     return get_improtocol()->pimaccept;
00046 }
00047 
00048 void
00049 IMState::add_icstate(
00050     ICState *pics
00051 )
00052 {
00053     CARD16BIT ic_id = pics->get_ic_id();
00054     ICStateMap& icmap = pshared->icmap;
00055     ASSERT(icmap.find(ic_id) == icmap.end());
00056     icmap[ic_id] = pics;
00057 }
00058 
00059 void
00060 IMState::remove_icstate(
00061     ICState *pics
00062 )
00063 {
00064     pshared->icmap.erase(pics->get_ic_id());
00065 }
00066 
00067 
00068 void
00069 IMState::cleanup_ic()
00070 {
00071     ICStateMap::iterator it, it2;
00072     ICStateMap& icmap = pshared->icmap;
00073     for (it = icmap.begin(); it != icmap.end();) {
00074        it2 = it;
00075        it++;
00076        // this operation may invalidate it2.
00077        it2->second->destroy();
00078     }
00079 }
00080 
00081 void
00082 IMState::destroy()
00083 {
00084     if (!substatep()) pshared->pimp->remove_imstate(this);
00085     delete this;
00086 }
00087 
00088 bool
00089 IMState::dispatch(
00090     CARD16BIT im_id,
00091     CARD16BIT ic_id,
00092     void *message
00093 )
00094 {
00095     if ((im_id != void_im_id) && (im_id != get_im_id())) {
00096        LOG_ERROR("Invalid im_id(%d).  This must be %d.",
00097                 (int) im_id, (int) get_im_id());
00098        return false;
00099     }
00100     if (ic_id != void_ic_id) {
00101        ICStateMap::iterator it;
00102 
00103        it = pshared->icmap.find(ic_id);
00104        if (it != pshared->icmap.end()) {
00105            it->second->deliver(message);
00106            return true;
00107        } else {
00108            LOG_ERROR("Invalid ic_id(%d).  This ic_id is never issued.",
00109                     (int) ic_id);
00110        }
00111     } else {
00112        deliver(message);
00113        return true;
00114     }
00115     LOG_ERROR("Invalid im_id and ic_id (%d, %d)",
00116              (int) im_id, (int) ic_id);
00117     return false;
00118 }
00119 
00120 bool
00121 IMState::new_ic_id(CARD16BIT &newid) const
00122 {
00123     int tid, size;
00124     ICStateMap *pmap = &pshared->icmap;
00125 
00126     size = pmap->size();
00127     for (tid = size + 1; ; ) {
00128        if (pmap->find(tid) == pmap->end()) {
00129            newid = tid;
00130            return true;
00131        }
00132        tid++;
00133        if (tid > ic_id_max) {
00134            tid = 1;
00135        }
00136        if (tid == size) {
00137            LOG_ERROR("Could not allocate new input context.");
00138            return false;
00139        }
00140     }
00141 // not reached
00142     return false;
00143 }
00144 
00145 /* Local Variables: */
00146 /* c-file-style: "iiim-project" */
00147 /* End: */