void DisposeWindowFromThreadID(uint32_t tid) { for (int i = 0; i < captures.size(); i++) { if (captures[i]->ThreadID == tid) { captures.removeAt(i); i--; } } for (int i = 0; i < windows.size(); i++) { guiserver_window* w = windows[i]; if (w->ThreadID == tid) { if (prevWindow == w) prevWindow = NULL; if (activeWindow == w) { activeWindow = NULL; // ActivateWindow(NULL); } if (w->FormBufferHandle != 0) { w->Visible = false; DrawWindow(w); } windows.removeAt(i); MemoryMap::unmap(w->Handle); i--; } } if (activeWindow == NULL) ActivateWindow(GetFrontWindow()); }
bool DisposeWindow(uint32_t handle) { if (prevWindow != NULL && prevWindow->Handle == handle) prevWindow = NULL; if (activeWindow != NULL && activeWindow->Handle == handle) ActivateWindow(NULL); int size_c = captures.size(); for (int i = 0; i < size_c; i++) { if (captures[i]->Handle == handle) { captures.removeAt(i); break; } } int size_w = windows.size(); for (int i = 0; i < size_w; i++) { guiserver_window* w = windows[i]; if (w->Handle == handle) { if (w->__internal2) DestructionEffect(w); windows.removeAt(i); MemoryMap::unmap(handle); if (activeWindow == NULL) ActivateWindow(GetFrontWindow()); return true; } } return false; }
guiserver_window* GetTargetWindow(int x, int y) { int size = captures.size(); if (size > 0) { return captures[size - 1]; } for (int i = windows.size() - 1; i >= 0; i--) { guiserver_window* w = windows[i]; if (w->Parent != 0 || (w->Flags & WINDOWFLAGS_TOPMOST) == 0) continue; if (IsInWindow(w, x, y)) return w; } for (int i = windows.size() - 1; i >= 0; i--) { guiserver_window* w = windows[i]; if (w->Parent != 0 || (w->Flags & WINDOWFLAGS_TOPMOST) != 0 || (w->Flags & WINDOWFLAGS_BOTTOMMOST) != 0) continue; if (IsInWindow(w, x, y)) return w; } for (int i = windows.size() - 1; i >= 0; i--) { guiserver_window* w = windows[i]; if (w->Parent != 0 || (w->Flags & WINDOWFLAGS_TOPMOST) != 0 || (w->Flags & WINDOWFLAGS_BOTTOMMOST) == 0) continue; if (IsInWindow(w, x, y)) return w; } return NULL; }
static void ActivateWindow(guiserver_window* w) { if (activeWindow != NULL) { if (Message::send(activeWindow->ThreadID, MSG_GUISERVER_DEACTIVATE, activeWindow->Handle) != M_OK) { monapi_warn("can't activate window(%x), ignored.", w); if (w != NULL) { DisposeWindow(w->Handle); } return; } } if (w != NULL) { if (Message::send(w->ThreadID, MSG_GUISERVER_ACTIVATED, w->Handle) != M_OK) { DisposeWindow(w->Handle); monapi_warn("can't activate window(%x), ignored. message failed", w); return; } } activeWindow = w; if (w == NULL) return; windows.remove(w); windows.add(w); if (w->Protocol == 0) DrawWindow(w); }
FILE* __mlibc_filelist_get(void *p, int n) { HList<FILE*>* list; if( p == NULL ) p = __mlibc_filelist_initializer(p); list = (HList<FILE*>*)p; if( list->size() <= n ) return NULL; return list->get(n); }
static void registerReceiver(uint32_t tid) { int size = receivers.size(); for (int i = 0; i < size; i++) { if (receivers[i] == tid) return; } receivers.add(tid); }
static void unregisterReceiver(uint32_t tid) { int size = receivers.size(); for (int i = 0; i < size; i++) { if (receivers[i] != tid) continue; receivers.removeAt(i); return; } }
int __mlibc_filelist_remove_by_element(void *p, FILE* f) { HList<FILE*>* list; if( p == NULL ) p = __mlibc_filelist_initializer(p); list = (HList<FILE*>*)p; if( !list->hasElement(f) ) return 0; list->remove(f); return 1; }
int __mlibc_filelist_remove_by_index(void *p, int n) { HList<FILE*>* list; if( p == NULL ) p = __mlibc_filelist_initializer(p); list = (HList<FILE*>*)p; if( list->size() <= n ) return 0; list->removeAt(n); return 1; }
int __mlibc_filelist_add(void *p, FILE* f) { HList<FILE*>* list; if( p == NULL ) p = __mlibc_filelist_initializer(p); list = (HList<FILE*>*)p; if( list->size() >= FOPEN_MAX ) return 0; list->add(f); return 1; }
void sendToClients(MessageInfo* msg) { for (int i = clients_.size() - 1; i >= 0; i--) { if (Message::send(clients_[i], msg) != M_OK) { monapi_warn("send error to pid = %x", clients_[i]); uint32_t temp; clients_.removeAt(i, &temp); } } }
bool DisposeBitmap(uint32_t handle) { int size = bitmaps.size(); for (int i = 0; i < size; i++) { if (bitmaps[i]->Handle == handle) { bitmaps.removeAt(i); MemoryMap::unmap(handle); return true; } } return false; }
static guiserver_window* GetFrontWindow() { for (int i = windows.size() - 1; i >= 0; i--) { guiserver_window* w = windows[i]; if (w->Parent == 0 && (w->Flags & WINDOWFLAGS_BOTTOMMOST) == 0) return w; } for (int i = windows.size() - 1; i >= 0; i--) { guiserver_window* w = windows[i]; if (w->Parent == 0 && (w->Flags & WINDOWFLAGS_BOTTOMMOST) != 0) return w; } return NULL; }
void Monitor::ParseConfig(CString content) { _A<CString> lines = content.split_lines(); FOREACH(CString, line, lines) { if (!line.startsWith("SERVER=")) continue; _A<CString> p = line.split("="); if (p.get_Length() < 2) continue; CString path = p[p.get_Length() - 1]; _A<CString> q = path.split("/"); CString name = q[q.get_Length() - 1]; this->paths.add(path); this->servers.add(name); } END_FOREACH alive = new bool[servers.size()]; return; }
void notifyProcessCreated(uint32_t tid, uint32_t parent, const CString& path) { int i = 0; while (i < receivers.size()) { if (Message::send(receivers[i], MSG_PROCESS_CREATED, tid, parent, 0, path) == M_OK) { i++; } else { _printf("%s: can not connect to %d\n", SVR, receivers[i]); removeProcessInfo(receivers[i]); receivers.removeAt(i); } } }
void notifyProcessTerminated(uint32_t tid, int status) { int i = 0; while (i < receivers.size()) { if (Message::send(receivers[i], MSG_PROCESS_TERMINATED, tid, status) == M_OK) { i++; } else { _printf("%s: can not connect to %d\n", SVR, receivers[i]); removeProcessInfo(receivers[i]); receivers.removeAt(i); } } }
guiserver_bitmap* GetBitmapPointer(uint32_t handle) { int size = bitmaps.size(); for (int i = 0; i < size; i++) { if (bitmaps[i]->Handle == handle) return bitmaps[i]; } return NULL; }
static PEData* GetPEData(const CString& path) { int size = cache.size(); for (int i = 0; i < size; i++) { PEData* pe = cache[i]; if (pe->Path == path) return pe; } return NULL; }
guiserver_window* GetWindowPointer(uint32_t handle) { int size = windows.size(); for (int i = 0; i < size; i++) { guiserver_window* w = windows[i]; if (w->Handle == handle) return w; } return NULL; }
static guiserver_window* GetChild(guiserver_window* parent, int x, int y) { x -= parent->X + parent->OffsetX; y -= parent->Y + parent->OffsetY; for (int i = windows.size() - 1; i >= 0; i--) { guiserver_window* w = windows[i]; if (w->Parent == parent->Handle && IsInWindow(w, x, y)) return GetChild(w, x, y); } return parent; }
void DisposeAllWindow() { for (int i = 0; i < windows.size(); i++) { guiserver_window* w = windows[i]; if (Message::sendReceive(NULL, w->ThreadID, MSG_GUISERVER_DISPOSEWINDOW) != M_OK) { printf("Error %s:%d\n", __FILE__, __LINE__); exit(-1); } syscall_kill_thread(w->ThreadID); } }
static void ProcessMouseInfo(MessageInfo* msg) { guiserver_window* top = GetTargetWindow(msg->arg1, msg->arg2); guiserver_window* target = top; if (target != NULL && target->Protocol == 1 && captures.size() == 0) { target = GetChild(target, msg->arg1, msg->arg2); } if (prevWindow != target) { if (prevWindow != NULL) { if (Message::send(prevWindow->ThreadID, MSG_GUISERVER_MOUSELEAVE, prevWindow->Handle) != M_OK) { monapi_warn("Error %s:%d\n", __FILE__, __LINE__); } } if (target != NULL) { if (Message::send(target->ThreadID, MSG_GUISERVER_MOUSEENTER, target->Handle) != M_OK) { monapi_warn("Error %s:%d\n", __FILE__, __LINE__); } } prevWindow = target; } if (prevButton < msg->arg3 && activeWindow != top) ActivateWindow(top); MessageInfo m = *msg; if (target != NULL) switch (target->Protocol) { case 1: m.arg1 = target->Handle; m.arg2 = MAKE_DWORD(msg->arg1, msg->arg2); if (prevButton == msg->arg3) { m.header = MSG_GUISERVER_MOUSEMOVE; } else if (prevButton < msg->arg3) { m.header = MSG_GUISERVER_MOUSEDOWN; m.arg3 = msg->arg3 - prevButton; } else { m.header = MSG_GUISERVER_MOUSEUP; m.arg3 = prevButton - msg->arg3; } break; } prevButton = msg->arg3; if (target != NULL && Message::send(target->ThreadID, &m) != M_OK) { DisposeWindowFromThreadID(target->ThreadID); } }
void DrawWindow(guiserver_window* w, int wx, int wy, int ww, int wh, bool draw_screen /*= true*/) { if (w == NULL || w->FormBufferHandle == 0) return; if (!w->__internal2) CreationEffect(w); DrawImage(screen_buffer, wallpaper, wx, wy, wx, wy, ww, wh); _R r(wx, wy, ww, wh); int size_w = windows.size(); for (int i = 0; i < size_w; i++) { guiserver_window* w = windows[i]; if (w->Parent != 0 || (w->Flags & WINDOWFLAGS_TOPMOST) != 0 || (w->Flags & WINDOWFLAGS_BOTTOMMOST) == 0) continue; DrawWindowInternal(w, r); } for (int i = 0; i < size_w; i++) { guiserver_window* w = windows[i]; if (w->Parent != 0 || (w->Flags & WINDOWFLAGS_TOPMOST) != 0 || (w->Flags & WINDOWFLAGS_BOTTOMMOST) != 0) continue; DrawWindowInternal(w, r); } for (int i = 0; i < size_w; i++) { guiserver_window* w = windows[i]; if (w->Parent != 0 || (w->Flags & WINDOWFLAGS_TOPMOST) == 0) continue; DrawWindowInternal(w, r); } int size_ov = overlaps.size(); for (int i = 0; i < size_ov; i++) { overlaps[i]->Draw(wx, wy, ww, wh); } if (!draw_screen) return; DrawScreen(wx, wy, ww, wh); }
guiserver_bitmap* CreateBitmap(int width, int height, unsigned int background) { uint32_t handle = MemoryMap::create(sizeof(guiserver_bitmap) + width * height * 4); if (handle == 0) return NULL; guiserver_bitmap* ret = (guiserver_bitmap*)MemoryMap::map(handle, false); if (ret == NULL) return NULL; ret->Handle = handle; ret->Width = width; ret->Height = height; bitmaps.add(ret); FillColor(ret, (unsigned int)background); return ret; }
guiserver_window* CreateWindow() { uint32_t handle = MemoryMap::create(sizeof(guiserver_window)); if (handle == 0) return NULL; guiserver_window* ret = (guiserver_window*)MemoryMap::map(handle, false); if (ret == NULL) return NULL; memset(ret, 0, sizeof(guiserver_window)); ret->Handle = handle; ret->Parent = 0; ret->Owner = 0; ret->ThreadID = 0; ret->X = start_pos; ret->Y = start_pos; ret->Width = DEFAULT_WIDTH; ret->Height = DEFAULT_HEIGHT; ret->OffsetX = 0; ret->OffsetY = 0; ret->Opacity = 255; ret->Visible = false; ret->Focused = false; ret->Flags = 0; ret->TransparencyKey = 0; ret->BufferHandle = ret->FormBufferHandle = 0; ret->__internal1 = NULL; ret->__internal2 = false; ret->Protocol = 0; ret->name[0] = '\0'; windows.add(ret); start_pos += 32; Screen* scr = GetDefaultScreen(); if (start_pos + DEFAULT_WIDTH >= scr->getWidth() && start_pos + DEFAULT_HEIGHT >= scr->getHeight()) { start_pos = 0; } return ret; }
void unRegisterClient(uint32_t id) { clients_.remove(id); }
void registerClient(uint32_t id) { clients_.add(id); }
static void RotateActiveWindow() { if (windows.size() > 1) { ActivateWindow(windows[1]); } }
bool WindowHandler(MessageInfo* msg) { switch (msg->header) { // ウィンドウ生成要求 case MSG_GUISERVER_CREATEWINDOW: { guiserver_window* w = CreateWindow(); w->ThreadID = msg->from; Message::reply(msg, w->Handle); break; } // ウィンドウ破棄要求 case MSG_GUISERVER_DISPOSEWINDOW: DisposeWindow(msg->arg1); Message::reply(msg); break; // ウィンドウ描画要求 case MSG_GUISERVER_DRAWWINDOW: if (msg->arg2 != 0 && msg->arg3 != 0) { // 部分描画 DrawWindow(GetWindowPointer(msg->arg1), GET_X_DWORD(msg->arg2), GET_Y_DWORD(msg->arg2), GET_X_DWORD(msg->arg3), GET_Y_DWORD(msg->arg3), true); } else { DrawWindow(GetWindowPointer(msg->arg1), true); } Message::reply(msg); break; // ウィンドウ移動要求 case MSG_GUISERVER_MOVEWINDOW: MoveWindow(GetWindowPointer(msg->arg1), (int)msg->arg2, (int)msg->arg3); Message::reply(msg); break; // ウィンドウ最前面移動要求 case MSG_GUISERVER_WINDOWTOFRONTMOST: { guiserver_window* w = GetWindowPointer(msg->arg1); windows.remove(w); windows.add(w); if (msg->arg2 != 0) DrawWindow(w); Message::reply(msg); break; } // アクティブ化要求 case MSG_GUISERVER_ACTIVATEWINDOW: ActivateWindow(GetWindowPointer(msg->arg1)); Message::reply(msg); break; // ウィンドウ列挙要求 case MSG_GUISERVER_ENUMWINDOWS: { int size = windows.size(); int max_count = MESSAGE_INFO_MAX_STR_LENGTH / sizeof(uint32_t); // msg.str = 128 bytes int max_loop_count; if (size > max_count) { max_loop_count = max_count; printf("windows size over %d/%d %s:%d\n", max_count, size, __FILE__, __LINE__); } else { max_loop_count = size; } int i; char str[128]; for (i = 0; i < max_loop_count; i++) { guiserver_window* w = windows[i]; *((uint32_t*)(&str[i * sizeof(uint32_t)])) = w->Handle; } Message::reply(msg, max_loop_count, NULL, str); break; } // タイトル情報 case MSG_GUISERVER_GETTITLE: { guiserver_window* w = GetWindowPointer(msg->arg1); Message::reply(msg, NULL, NULL, w->name); break; } // マウス情報 case MSG_MOUSE_INFO: ProcessMouseInfo(msg); break; // キー情報 case MSG_KEY_VIRTUAL_CODE: if (msg->arg1 == MonAPI::Keys::Tab && msg->arg2 & KEY_MODIFIER_ALT) { RotateActiveWindow(); break; } ProcessKeyInfo(msg); break; // キャプチャー要求 case MSG_GUISERVER_MOUSECAPTURE: { guiserver_window* w = GetWindowPointer(msg->arg1); if (w != NULL) { if (msg->arg2 == 0) { captures.remove(w); } else { captures.add(w); } } Message::reply(msg); break; } // 移動領域作成要求 case MSG_GUISERVER_CREATEOVERLAP: { Overlap* ov = new Overlap( (int)msg->arg1, (int)msg->arg2, GET_X_DWORD(msg->arg3), GET_Y_DWORD(msg->arg3)); overlaps.add(ov); Message::reply(msg, (uint32_t)ov); break; } // 移動領域削除要求 case MSG_GUISERVER_DISPOSEOVERLAP: { Overlap* ov = (Overlap*)msg->arg1; overlaps.remove(ov); delete ov; Message::reply(msg); break; } // 移動領域移動要求 case MSG_GUISERVER_MOVEOVERLAP: ((Overlap*)msg->arg1)->Move( GET_X_DWORD(msg->arg2), GET_Y_DWORD(msg->arg2), GET_X_DWORD(msg->arg3), GET_Y_DWORD(msg->arg3)); Message::reply(msg); break; // 拡張効果要求 case MSG_GUISERVER_EXPANSIONEFFECT: ExpansionEffect( GET_X_DWORD(msg->arg1), GET_Y_DWORD(msg->arg1), GET_X_DWORD(msg->arg2), GET_Y_DWORD(msg->arg2), GET_X_DWORD(msg->arg3), GET_Y_DWORD(msg->arg3)); Message::reply(msg); break; // 縮小効果要求 case MSG_GUISERVER_REDUCTIONEFFECT: ReductionEffect( GET_X_DWORD(msg->arg1), GET_Y_DWORD(msg->arg1), GET_X_DWORD(msg->arg2), GET_Y_DWORD(msg->arg2), GET_X_DWORD(msg->arg3), GET_Y_DWORD(msg->arg3)); Message::reply(msg); break; default: return false; } return true; }
/** メインスレッド */ void ImeServer::service() { uintptr_t targetID = MonAPI::Message::lookupMainThread("MONITOR.BIN"); if (targetID == THREAD_UNKNOWN) { printf("IME: Monitor server not found\n"); exit(1); } if (MonAPI::Message::send(targetID, MSG_STARTED, 0, 0, 0, NULL)) { printf("IME: Server start failed\n"); exit(1); } // 辞書が読めなかったときはかな漢字変換はすべて失敗を返す bool dicLoaded = loadDictionary(); MessageInfo info; while (1) { if (!MonAPI::Message::receive(&info)) { switch(info.header) { case MSG_IMESERVER_GETKANJI: { HList<MonAPI::CString> result; int hit = getKanji(info.str, &result); // MSG_IMESERVER_GETKANJI // arg2: ヒット数 if (dicLoaded == true) { MonAPI::Message::reply(&info, hit, 0, NULL); } else { MonAPI::Message::reply(&info, 0, 0, NULL); } if (dicLoaded == true && hit > 0) { // MSG_IMESERVER_STARTKANJI // arg1: ヒット数 MonAPI::Message::sendReceive(&info, info.from, MSG_IMESERVER_STARTKANJI, hit, 0, 0, NULL); for (int i = 0; i < hit; i++) { // MSG_IMESERVER_KANJI // arg1: ヒット数 // arg2: カウンタ // str : よみ→漢字 MonAPI::Message::sendReceive(&info, info.from, MSG_IMESERVER_KANJI, hit, i, 0, (const char*)result.get(i)); //printf("%d: %s\n", i, (const char*)result.get(i)); } // MSG_IMESERVER_ENDKANJI // arg1: ヒット数 MonAPI::Message::sendReceive(&info, info.from, MSG_IMESERVER_ENDKANJI, hit, 0, 0, NULL); } } break; case MSG_IMESERVER_GETYOMI: { // MSG_IMESERVER_GETYOMI // arg2: 0-失敗 1-成功 // str : 漢字→よみ char result[MAX_TEXT_LEN]; if (dicLoaded == true && getYomi(info.str, result) == true) { strncpy(info.str, result, MAX_TEXT_LEN); MonAPI::Message::reply(&info, 1, 0, result); } else { strncpy(info.str, "", MAX_TEXT_LEN); MonAPI::Message::reply(&info, 0, 0, ""); } } break; case MSG_IMESERVER_GETKANA: { // MSG_IMESERVER_GETKANA // arg2: 0-失敗 1-成功 // str : 入力文字→かな char result[MAX_TEXT_LEN]; if (getKana(info.str, result) == true) { strncpy(info.str, result, MAX_TEXT_LEN); MonAPI::Message::reply(&info, 1, 0, result); } else { strncpy(info.str, "", MAX_TEXT_LEN); MonAPI::Message::reply(&info, 0, 0, ""); } } break; case MSG_IMESERVER_GETROMAN: { // MSG_IMESERVER_GETROMAN // arg2: 0-失敗 1-成功 // str : かな→入力文字 char result[MAX_TEXT_LEN]; if (getRoman(info.str, result) == true) { strncpy(info.str, result, MAX_TEXT_LEN); MonAPI::Message::reply(&info, 1, 0, result); } else { strncpy(info.str, "", MAX_TEXT_LEN); MonAPI::Message::reply(&info, 0, 0, ""); } } break; } } } }