/** * Waits for the response on a specific transaction. On success, the output parameters are * filled with buffers containing the data. */ bool g_ui::receive(g_ui_transaction_id transaction, uint8_t** out_data, uint32_t* out_length) { // does map even exist? if (transaction_map == 0) { return false; } // does transaction exist? if (transaction_map->count(transaction) < 1) { return false; } // take data g_ui_transaction_data* data = transaction_map->at(transaction); // block until received g_atomic_block(&data->waiting); // set out parameters *out_data = data->data; *out_length = data->length; // remove entry transaction_map->erase(transaction); delete data; return true; }
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; } }
g_key_info gui_screen_t::readInput() { if (waitingInput.size() == 0) { g_atomic_block(&noInputAvailable); } waitingInputLock.lock(); g_key_info result = waitingInput.front(); waitingInput.pop_front(); if (waitingInput.size() == 0) { noInputAvailable = true; } waitingInputLock.unlock(); return result; }
void g_ui::event_dispatch_thread() { while (true) { // wait for events g_atomic_block(&event_dispatch_events_empty); // lock g_atomic_lock(&event_dispatch_locked); // call listener g_ui_event_dispatch_data& e = event_dispatch_queue.back(); event_dispatch_queue.pop_back(); e.listener->event_received(e.data, e.length); // check if empty if (event_dispatch_queue.empty()) { event_dispatch_events_empty = true; } // unlock event_dispatch_locked = false; } }
int main(int argc, char** argv) { g_ui_open_status open_stat = g_ui::open(); if (open_stat == G_UI_OPEN_STATUS_SUCCESSFUL) { g_window* window = g_window::create(); window->setTitle("Calculator"); window->setResizable(false); display = g_textfield::create(); display->setTitle("0"); display->setBounds(g_rectangle(10, 10, 150, 30)); window->addChild(display); #define PLACE_BUTTON_T(num, text, x, y) \ but##num = g_button::create(); \ but##num->setTitle(text); \ but##num->setBounds(g_rectangle(x, y, 30, 30)); \ window->addChild(but##num); #define PLACE_BUTTON(num, x, y) PLACE_BUTTON_T(num, #num, x, y); int grid1 = 10; int grid2 = 50; int grid3 = 90; int grid4 = 130; int grid5 = 170; int dispOff = 40; PLACE_BUTTON_T(Clear, "C", grid1, grid1 + dispOff); butClear->setActionListener(new command_press_action_listener_t(COM_CLEAR)); PLACE_BUTTON(1, grid1, grid2 + dispOff); but1->setActionListener(new num_press_action_listener_t(1)); PLACE_BUTTON(2, grid2, grid2 + dispOff); but2->setActionListener(new num_press_action_listener_t(2)); PLACE_BUTTON(3, grid3, grid2 + dispOff); but3->setActionListener(new num_press_action_listener_t(3)); PLACE_BUTTON(4, grid1, grid3 + dispOff); but4->setActionListener(new num_press_action_listener_t(4)); PLACE_BUTTON(5, grid2, grid3 + dispOff); but5->setActionListener(new num_press_action_listener_t(5)); PLACE_BUTTON(6, grid3, grid3 + dispOff); but6->setActionListener(new num_press_action_listener_t(6)); PLACE_BUTTON(7, grid1, grid4 + dispOff); but7->setActionListener(new num_press_action_listener_t(7)); PLACE_BUTTON(8, grid2, grid4 + dispOff); but8->setActionListener(new num_press_action_listener_t(8)); PLACE_BUTTON(9, grid3, grid4 + dispOff); but9->setActionListener(new num_press_action_listener_t(9)); PLACE_BUTTON(0, grid1, grid5 + dispOff); but0->setActionListener(new num_press_action_listener_t(0)); PLACE_BUTTON_T(Plus, "+", grid4, grid1 + dispOff); butPlus->setActionListener(new command_press_action_listener_t(COM_PLUS)); PLACE_BUTTON_T(Minus, "-", grid4, grid2 + dispOff); butMinus->setActionListener(new command_press_action_listener_t(COM_MINUS)); PLACE_BUTTON_T(Mult, "*", grid4, grid3 + dispOff); butMult->setActionListener(new command_press_action_listener_t(COM_MULT)); PLACE_BUTTON_T(Div, "/", grid4, grid4 + dispOff); butDiv->setActionListener(new command_press_action_listener_t(COM_DIV)); PLACE_BUTTON_T(Eq, "=", grid4, grid5 + dispOff); butEq->setActionListener(new command_press_action_listener_t(COM_EQ)); window->setBounds(g_rectangle(70, 70, 190, 320)); window->setVisible(true); uint8_t blocker = true; g_atomic_block(&blocker); } }
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); } }