int main(int argc, char** argv) { g_task_register_id("init"); // load spawner process g_ramdisk_spawn_status spawner_stat = g_ramdisk_spawn("applications/spawner.bin", G_SECURITY_LEVEL_KERNEL); if (spawner_stat != G_RAMDISK_SPAWN_STATUS_SUCCESSFUL) { g_logger::log("unable to load system spawner process"); yield: asm("hlt"); goto yield; } // wait for spawner to get ready g_tid spawner_id; while ((spawner_id = g_task_get_id(G_SPAWNER_IDENTIFIER)) == -1) { g_yield(); } // let the spawner load the launch service g_pid ls_pid; std::string launch_srv_path = "/applications/launch.bin"; g_spawn_status stat = g_spawn_p(launch_srv_path.c_str(), "/system/launch/init", "/", G_SECURITY_LEVEL_KERNEL, &ls_pid); if (stat == G_SPAWN_STATUS_SUCCESSFUL) { g_logger::log("launch service executed in process %i", ls_pid); } else { g_logger::log("failed to load launch service from '" + launch_srv_path + "' with code %i", stat); } }
int main(int argc, char** argv) { g_task_register_id("launch"); // load init script FILE* init_script = fopen("/system/launch/init", "r"); launchscript_parser_t* parser = new launchscript_parser_t(init_script); ls_document_t* document = parser->document(); // interpret script for (ls_statement_t* stat : document->statements) { std::string command = stat->pairs[0]->key; if (command == "print") { print(stat); } else if (command == "driver") { driver(stat); } else if (command == "application") { application(stat); } else if (command == "wait") { wait(stat); } } return 0; }
void RequestHandler::event_dispatch_thread() { // register a name std::stringstream namestr; namestr << "windowserver:event-dispatcher"; g_task_register_id(namestr.str().c_str()); while (true) { // wait for events g_atomic_block(&event_dispatch_events_empty); // lock g_atomic_lock(&sending_locked); // call listener UIEventDispatchData ldata = event_dispatch_queue.back(); event_dispatch_queue.pop_back(); // write transaction id uint32_t idlen = sizeof(g_ui_transaction_id); uint8_t idbytes[idlen]; *((g_ui_transaction_id*) idbytes) = 0; g_write(ldata.output, idbytes, idlen); // write length uint32_t lenlen = sizeof(uint32_t); uint8_t lenbytes[lenlen]; *((uint32_t*) lenbytes) = ldata.length + 4; g_write(ldata.output, lenbytes, lenlen); // write listener id uint32_t lidlen = sizeof(uint32_t); uint8_t lidbytes[lidlen]; *((uint32_t*) lidbytes) = ldata.listener; g_write(ldata.output, lidbytes, lidlen); // write data uint32_t written = 0; while (written < ldata.length) { written += g_write(ldata.output, &ldata.data[written], ldata.length - written); } // delete the data delete ldata.data; // check if empty if (event_dispatch_queue.empty()) { event_dispatch_events_empty = true; } // unlock sending_locked = false; } }
void RequestHandler::run() { if (!g_task_register_id(G_WINDOW_MANAGER_IDENTIFIER)) { g_logger::log("window manager: could not register with task identifier '%s'", (char*) G_WINDOW_MANAGER_IDENTIFIER); return; } uint32_t tid = g_get_tid(); g_logger::log("window manager: ready for requests"); while (true) { g_message* request = new g_message; g_recv_msg(tid, request); if (request->type == G_UI_COMMAND_OPEN_REQUEST) { g_create_thread_d((void*) handling_thread, (void*) request); } else { g_logger::log("window manager: received unknown command %i from task %i", request->type, request->sender); } } }
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); }