/** * Opens a connection to the window server. */ g_ui_open_status g_ui::open() { // check if already open if (g_ui_initialized) { return G_UI_OPEN_STATUS_EXISTING; } // get window managers id g_tid window_mgr = g_task_get_id(G_UI_REGISTRATION_THREAD_IDENTIFIER); if (window_mgr == -1) { klog("failed to retrieve task id of window server with identifier '%s'", G_UI_REGISTRATION_THREAD_IDENTIFIER); return G_UI_OPEN_STATUS_COMMUNICATION_FAILED; } // start event dispatcher g_ui_event_dispatcher_tid = g_create_thread((void*) &event_dispatch_thread); // send initialization request g_message_transaction init_tx = g_get_message_tx_id(); g_ui_initialize_request request; request.header.id = G_UI_PROTOCOL_INITIALIZATION; g_send_message_t(window_mgr, &request, sizeof(g_ui_initialize_request), init_tx); // receive initialization response uint32_t response_buffer_size = sizeof(g_message_header) + sizeof(g_ui_initialize_response); g_local<uint8_t> response_buffer(new uint8_t[response_buffer_size]); if (g_receive_message_t(response_buffer(), response_buffer_size, init_tx) != G_MESSAGE_RECEIVE_STATUS_SUCCESSFUL) { klog("failed to communicate with the window server"); return G_UI_OPEN_STATUS_COMMUNICATION_FAILED; } // check response g_ui_initialize_response* response = (g_ui_initialize_response*) G_MESSAGE_CONTENT(response_buffer()); if (response->status != G_UI_PROTOCOL_SUCCESS) { klog("failed to open UI"); return G_UI_OPEN_STATUS_FAILED; } // mark UI as ready g_ui_initialized = true; g_ui_delegate_tid = response->window_server_delegate_thread; return G_UI_OPEN_STATUS_SUCCESSFUL; }
void gui_screen_t::initialize() { window = g_window::create(); window->setTitle("Terminal"); window->setLayout(G_UI_LAYOUT_MANAGER_GRID); canvas = g_canvas::create(); window->addChild(canvas); g_rectangle windowBounds = g_rectangle(200, 200, 400, 250); window->setBounds(windowBounds); window->setVisible(true); canvas->setBounds(g_rectangle(0, 0, windowBounds.width, windowBounds.height)); canvas->setListener(G_UI_COMPONENT_EVENT_TYPE_KEY, new input_key_listener_t()); canvas->setBufferListener(new canvas_buffer_listener_t()); window->setListener(G_UI_COMPONENT_EVENT_TYPE_FOCUS, new terminal_focus_listener_t()); font = g_font_loader::get("consolas"); viewModel = g_text_layouter::getInstance()->initializeBuffer(); g_create_thread((void*) &paint_entry); }
void register_operation_mode() { g_logger::log("starting poll thread"); g_create_thread((void*) polling_thread); }
void RequestHandler::handling_thread(g_message* _request) { // wrap in local for auto-delete g_local < g_message > request(_request); // read parameters g_pid requester_pid = g_get_pid_for_tid(request()->sender); g_fd requesters_output = request()->parameterA; g_fd requesters_input = request()->parameterB; g_pid my_pid = g_get_pid(); // register a name std::stringstream namestr; namestr << "windowserver:handler@"; namestr << requester_pid; g_task_register_id(namestr.str().c_str()); // clone pipe ends g_fs_clonefd_status clone_input_status; g_fd requester_out = g_clone_fd_s(requesters_input, requester_pid, my_pid, &clone_input_status); if (clone_input_status != G_FS_CLONEFD_SUCCESSFUL) { g_logger::log("unable to clone input file descriptor (%i in process %i) on open request (status: %i)", requesters_input, requester_pid, clone_input_status); return; } g_fs_clonefd_status clone_output_status; g_fd requester_in = g_clone_fd_s(requesters_output, requester_pid, my_pid, &clone_output_status); if (clone_output_status != G_FS_CLONEFD_SUCCESSFUL) { g_logger::log("unable to clone output file descriptor (%i in process %i) on open request (status: %i)", requesters_input, requester_pid, clone_output_status); return; } // send response g_message_empty (response); response.type = G_UI_COMMAND_OPEN_RESPONSE; response.topic = request()->topic; g_send_msg(request()->sender, &response); // add process add_process(requester_pid, requester_out, requester_in); // start event dispatch thread g_create_thread((void*) &event_dispatch_thread); while (true) { // read transaction id uint32_t idlen = sizeof(g_ui_transaction_id); uint8_t id[idlen]; g_read(requester_in, id, idlen); g_ui_transaction_id transaction = *((g_ui_transaction_id*) id); // read length uint32_t lenlen = sizeof(uint32_t); uint8_t len[lenlen]; g_read(requester_in, len, lenlen); uint32_t length = *((uint32_t*) len); // read data // TODO limit data uint8_t* data = new uint8_t[length]; int32_t rd = 0; while (rd < length) { rd += g_read(requester_in, &data[rd], length - rd); } g_value_placer data_reader(data); // handle command g_ui_protocol_command_id command = data_reader.get<g_ui_protocol_command_id>(); if (command == G_UI_PROTOCOL_CREATE_WINDOW) { uint32_t window_id; g_ui_protocol_status status = createWindow(&window_id); // write response uint32_t response_len = G_UI_PROTOCOL_HEADER_LENGTH + G_UI_PROTOCOL_CREATE_WINDOW_RESPONSE_LENGTH; g_local < uint8_t > response(new uint8_t[response_len]); g_value_placer response_writer(response()); response_writer.put(G_UI_PROTOCOL_CREATE_WINDOW); response_writer.put(status); response_writer.put(window_id); send(requester_out, transaction, response(), response_len); } else if (command == G_UI_PROTOCOL_SET_VISIBLE) { uint32_t component_id = data_reader.get<uint32_t>(); bool visible = data_reader.get<uint8_t>(); // handle command g_ui_protocol_status status = setVisible(component_id, visible); // write response uint32_t response_len = G_UI_PROTOCOL_HEADER_LENGTH + G_UI_PROTOCOL_SET_VISIBLE_RESPONSE_LENGTH; g_local < uint8_t > response(new uint8_t[response_len]); g_value_placer response_writer(response()); response_writer.put(G_UI_PROTOCOL_SET_VISIBLE); response_writer.put(status); send(requester_out, transaction, response(), response_len); } else if (command == G_UI_PROTOCOL_CREATE_COMPONENT) { uint32_t component_type = data_reader.get<uint32_t>(); // handle command uint32_t component_id; g_ui_protocol_status status = createComponent(component_type, &component_id); // write response uint32_t response_length = G_UI_PROTOCOL_HEADER_LENGTH + G_UI_PROTOCOL_CREATE_COMPONENT_RESPONSE_LENGTH; g_local < uint8_t > response(new uint8_t[response_length]); g_value_placer response_writer(response()); response_writer.put(G_UI_PROTOCOL_CREATE_COMPONENT); response_writer.put(status); response_writer.put(component_id); send(requester_out, transaction, response(), response_length); } else if (command == G_UI_PROTOCOL_ADD_COMPONENT) { uint32_t parent_id = data_reader.get<uint32_t>(); uint32_t child_id = data_reader.get<uint32_t>(); // handle command g_ui_protocol_status status = addComponent(parent_id, child_id); // write response uint32_t response_length = G_UI_PROTOCOL_HEADER_LENGTH + G_UI_PROTOCOL_ADD_COMPONENT_RESPONSE_LENGTH; g_local < uint8_t > response(new uint8_t[response_length]); g_value_placer response_writer(response()); response_writer.put(G_UI_PROTOCOL_ADD_COMPONENT); response_writer.put(status); send(requester_out, transaction, response(), response_length); } else if (command == G_UI_PROTOCOL_SET_TITLE) { uint32_t component_id = data_reader.get<uint32_t>(); uint32_t title_length = data_reader.get<uint32_t>(); g_local<char> title(new char[title_length]); data_reader.get((uint8_t*) title(), title_length); // handle command g_ui_protocol_status status = setTitle(component_id, title()); // write response uint32_t response_length = G_UI_PROTOCOL_HEADER_LENGTH + G_UI_PROTOCOL_SET_TITLE_RESPONSE_LENGTH; g_local < uint8_t > response(new uint8_t[response_length]); g_value_placer response_writer(response()); response_writer.put(G_UI_PROTOCOL_SET_TITLE); response_writer.put(status); send(requester_out, transaction, response(), response_length); } else if (command == G_UI_PROTOCOL_GET_TITLE) { uint32_t component_id = data_reader.get<uint32_t>(); // handle command std::string title; g_ui_protocol_status status = getTitle(component_id, title); int title_length = title.length() + 1; // write response uint32_t response_length = G_UI_PROTOCOL_HEADER_LENGTH + G_UI_PROTOCOL_GET_TITLE_RESPONSE_LENGTH + title_length; g_local < uint8_t > response(new uint8_t[response_length]); g_value_placer response_writer(response()); response_writer.put(G_UI_PROTOCOL_GET_TITLE); response_writer.put(status); response_writer.put(title_length); response_writer.put((uint8_t*) title.c_str(), title_length); send(requester_out, transaction, response(), response_length); } else if (command == G_UI_PROTOCOL_SET_BOUNDS) { uint32_t component_id = data_reader.get<uint32_t>(); int32_t x = data_reader.get<int32_t>(); int32_t y = data_reader.get<int32_t>(); int32_t width = data_reader.get<int32_t>(); int32_t height = data_reader.get<int32_t>(); // handle command g_ui_protocol_status status = setBounds(component_id, x, y, width, height); // write response uint32_t response_length = G_UI_PROTOCOL_HEADER_LENGTH + G_UI_PROTOCOL_SET_BOUNDS_RESPONSE_LENGTH; g_local < uint8_t > response(new uint8_t[response_length]); g_value_placer response_writer(response()); response_writer.put(G_UI_PROTOCOL_SET_BOUNDS); response_writer.put(status); send(requester_out, transaction, response(), response_length); } else if (command == G_UI_PROTOCOL_SET_ACTION_LISTENER) { uint32_t component_id = data_reader.get<uint32_t>(); // handle command uint32_t listener_id; g_ui_protocol_status status = setActionListener(requester_pid, component_id, &listener_id); // write response uint32_t response_length = G_UI_PROTOCOL_HEADER_LENGTH + G_UI_PROTOCOL_SET_ACTION_LISTENER; g_local < uint8_t > response(new uint8_t[response_length]); g_value_placer response_writer(response()); response_writer.put<g_ui_protocol_command_id>(G_UI_PROTOCOL_SET_ACTION_LISTENER); response_writer.put<g_ui_protocol_status>(status); response_writer.put<uint32_t>(listener_id); send(requester_out, transaction, response(), response_length); } } // TODO close all windows // TODO remove listeners remove_process(requester_pid); }
/** * Opens a connection to the window server. */ g_ui_open_status g_ui::open() { // check if already open if (g_ui_ready) { return G_UI_OPEN_STATUS_EXISTING; } // get window managers id g_tid window_mgr = g_task_get_id(G_WINDOW_MANAGER_IDENTIFIER); if (window_mgr == -1) { g_logger::log("failed to retrieve task id of window server"); return G_UI_OPEN_STATUS_COMMUNICATION_FAILED; } // open in/out pipes g_fs_pipe_status status; g_fd g_ui_channel_out_read; g_pipe_s(&g_ui_channel_out, &g_ui_channel_out_read, &status); g_fd g_ui_channel_in_write; g_pipe_s(&g_ui_channel_in_write, &g_ui_channel_in, &status); if (status == G_FS_PIPE_ERROR) { g_logger::log("failed to open UI communication pipe"); return G_UI_OPEN_STATUS_COMMUNICATION_FAILED; } // tell window manager to open uint32_t topic = g_ipc_next_topic(); g_message_empty(open_request); open_request.type = G_UI_COMMAND_OPEN_REQUEST; open_request.topic = topic; open_request.parameterA = g_ui_channel_out_read; open_request.parameterB = g_ui_channel_in_write; auto request_status = g_send_msg(window_mgr, &open_request); if (request_status != G_MESSAGE_SEND_STATUS_SUCCESSFUL) { g_logger::log("failed to send UI-open request to window server"); return G_UI_OPEN_STATUS_COMMUNICATION_FAILED; } // wait for response g_message_empty(open_response); auto response_status = g_recv_topic_msg(g_get_tid(), topic, &open_response); if (response_status != G_MESSAGE_RECEIVE_STATUS_SUCCESSFUL) { g_logger::log("failed to receive UI-open response from window server"); return G_UI_OPEN_STATUS_COMMUNICATION_FAILED; } // check response message if (open_response.type != G_UI_COMMAND_OPEN_RESPONSE) { g_logger::log("window servers UI-open response was not a proper 'opened'-response"); return G_UI_OPEN_STATUS_COMMUNICATION_FAILED; } // start asynchronous receiver g_create_thread((void*) &asynchronous_receiver_thread); g_create_thread((void*) &event_dispatch_thread); // mark UI as ready g_logger::log("successfully opened UI in window server"); g_ui_ready = true; return G_UI_OPEN_STATUS_SUCCESSFUL; }
void gui_screen_t::paint() { g_create_thread((void*) blinkCursorThread); int padding = 5; while (true) { auto windowBounds = window->getBounds(); canvas->setBounds(g_rectangle(0, 0, windowBounds.width, windowBounds.height)); auto cr = getGraphics(); if (cr == 0) { g_sleep(100); continue; } // clear cairo_save(cr); cairo_set_source_rgba(cr, 0, 0, 0, 1); cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); cairo_paint(cr); cairo_restore(cr); // relayout text g_text_layouter::getInstance()->layout(cr, output.c_str(), font, 14, g_rectangle(padding, padding, windowBounds.width - 2 * padding - 20, windowBounds.height - 2 * padding), g_text_alignment::LEFT, viewModel, true); // check which is the lowest-down-the-screen character int highesty = 0; for (g_positioned_glyph& g : viewModel->positions) { int ypos = g.position.y - g.glyph->y; if (ypos > highesty) { highesty = ypos; } } // calculate limit int yLimit = windowBounds.height - 60; int yOffset = 0; if (highesty > yLimit) { yOffset = yLimit - highesty; } // paint characters g_point last; cairo_set_source_rgba(cr, 1, 1, 1, 1); for (g_positioned_glyph& g : viewModel->positions) { last = g.position; cairo_save(cr); cairo_translate(cr, g.position.x - g.glyph->x, yOffset + g.position.y - g.glyph->y); cairo_glyph_path(cr, g.glyph, g.glyph_count); cairo_fill(cr); cairo_restore(cr); } // paint cursor if (focused) { if ((g_millis() - lastInput < 300) || cursorBlink) { cairo_save(cr); cairo_set_source_rgba(cr, 1, 1, 1, 1); cairo_rectangle(cr, last.x + 10, yOffset + last.y - 12, 8, 14); cairo_fill(cr); cairo_restore(cr); } } canvas->blit(g_rectangle(0, 0, bufferSize.width, bufferSize.height)); paint_uptodate = true; g_atomic_block(&paint_uptodate); } }
void run_test(int argc, char** argv) { g_create_thread((void*) message_test_receiver); message_test_sender(); }