Change focus from panel

This commit is contained in:
Kevin Lange 2014-04-20 01:24:10 -07:00
parent 140f5a71e0
commit 30a79e8ac6
4 changed files with 132 additions and 11 deletions

View File

@ -10,6 +10,7 @@
#include <math.h>
#include <assert.h>
#include <getopt.h>
#include <errno.h>
#include <sys/stat.h>
#include <cairo.h>
@ -35,6 +36,7 @@ struct {
.nest_height = 0
};
static int usage(char * argv[]) {
fprintf(stderr,
"Yutani - Window Compositor\n"
@ -113,6 +115,28 @@ static void spin_unlock(int volatile * lock) {
__sync_lock_release(lock);
}
static void * _malloc(size_t bytes) {
/*
* Workaround an issue in newlib malloc that just happens despise the particular sizes
* of things the terminal happens to allocate.
* TODO: Replace newlib malloc with our malloc... again...
*/
static volatile int lock = 0;
spin_lock(&lock);
errno = 0xABAD1DEA;
void * out = NULL;
int failures = 0;
do {
if (failures > 5) {
spin_unlock(&lock);
return NULL;
}
out = malloc(bytes);
} while (out == NULL && errno == 0xABAD1DEA);
spin_unlock(&lock);
return out;
}
static int next_buf_id(void) {
static int _next = 1;
return _next++;
@ -280,7 +304,7 @@ int best_z_option(yutani_globals_t * yg) {
static yutani_server_window_t * server_window_create(yutani_globals_t * yg, int width, int height, uint32_t owner) {
yutani_server_window_t * win = malloc(sizeof(yutani_server_window_t));
yutani_server_window_t * win = _malloc(sizeof(yutani_server_window_t));
win->wid = next_wid();
win->owner = owner;
@ -430,7 +454,7 @@ static char * precache_shmfont(char * ident, char * name) {
fseek(f, 0, SEEK_SET);
size_t shm_size = s;
char * font = (char *)syscall_shm_obtain(ident, &shm_size); //malloc(s);
char * font = (char *)syscall_shm_obtain(ident, &shm_size); //_malloc(s);
assert((shm_size >= s) && "shm_obtain returned too little memory to load a font into!");
fread(font, s, 1, f);
@ -763,7 +787,7 @@ void yutani_cairo_init(yutani_globals_t * yg) {
yg->real_surface = cairo_image_surface_create_for_data(
yg->backend_ctx->buffer, CAIRO_FORMAT_ARGB32, yg->width, yg->height, stride);
yg->select_framebuffer = malloc(YUTANI_BYTE_DEPTH * yg->width * yg->height);
yg->select_framebuffer = _malloc(YUTANI_BYTE_DEPTH * yg->width * yg->height);
yg->selectbuffer_surface = cairo_image_surface_create_for_data(
yg->select_framebuffer, CAIRO_FORMAT_ARGB32, yg->width, yg->height, stride);
@ -797,7 +821,7 @@ void * redraw(void * in) {
}
static void mark_window(yutani_globals_t * yg, yutani_server_window_t * window) {
yutani_damage_rect_t * rect = malloc(sizeof(yutani_damage_rect_t));
yutani_damage_rect_t * rect = _malloc(sizeof(yutani_damage_rect_t));
if (window->rotation == 0) {
rect->x = window->x;
@ -835,7 +859,7 @@ static void mark_window(yutani_globals_t * yg, yutani_server_window_t * window)
}
static void mark_window_relative(yutani_globals_t * yg, yutani_server_window_t * window, int32_t x, int32_t y, int32_t width, int32_t height) {
yutani_damage_rect_t * rect = malloc(sizeof(yutani_damage_rect_t));
yutani_damage_rect_t * rect = _malloc(sizeof(yutani_damage_rect_t));
if (window->rotation == 0) {
rect->x = window->x + x;
@ -874,7 +898,7 @@ static void mark_window_relative(yutani_globals_t * yg, yutani_server_window_t *
static void mark_region(yutani_globals_t * yg, int x, int y, int width, int height) {
yutani_damage_rect_t * rect = malloc(sizeof(yutani_damage_rect_t));
yutani_damage_rect_t * rect = _malloc(sizeof(yutani_damage_rect_t));
rect->x = x;
rect->y = y;
rect->width = width;
@ -1098,7 +1122,7 @@ int main(int argc, char * argv[]) {
int results = parse_args(argc, argv, &argx);
if (results) return results;
yutani_globals_t * yg = malloc(sizeof(yutani_globals_t));
yutani_globals_t * yg = _malloc(sizeof(yutani_globals_t));
memset(yg, 0x00, sizeof(yutani_globals_t));
yg->backend_ctx = init_graphics_fullscreen_double_buffer();
@ -1348,7 +1372,7 @@ int main(int argc, char * argv[]) {
if (wa->size == 0) {
w->name = NULL;
} else {
char * t = malloc(wa->size+1);
char * t = _malloc(wa->size+1);
memcpy(t, wa->name, wa->size+1);
w->name = t;
}
@ -1372,6 +1396,14 @@ int main(int argc, char * argv[]) {
}
}
break;
case YUTANI_MSG_WINDOW_FOCUS:
{
struct yutani_msg_window_focus * wa = (void *)m->data;
yutani_server_window_t * w = hashmap_get(yg->wids_to_windows, (void *)wa->wid);
if (w) {
set_focused_window(yg, w);
}
}
default:
{
fprintf(stderr, "[yutani-server] Unknown type!\n");

View File

@ -71,23 +71,62 @@ void init_sprite_png(int i, char * filename) {
load_sprite_png(sprites[i], filename);
}
void redraw(void);
#define FONT_SIZE 14
#define TIME_LEFT 108
#define DATE_WIDTH 70
volatile int _continue = 1;
/* honestly no way we're gonna fit more at the moment... */
int icon_lefts[20] = {0};
int icon_wids[20] = {0};
int focused_app = -1;
void sig_int(int sig) {
printf("Received shutdown signal in panel!\n");
_continue = 0;
}
void set_focused(int i) {
if (focused_app != i) {
focused_app = i;
redraw();
}
}
void panel_check_click(struct yutani_msg_window_mouse_event * evt) {
if (evt->command == YUTANI_MOUSE_EVENT_CLICK) {
printf("Click!\n");
if (evt->new_x >= width - 24 ) {
yutani_session_end(yctx);
_continue = 0;
} else {
for (int i = 0; i < 18; ++i) {
if (evt->new_x >= icon_lefts[i] && evt->new_x < icon_lefts[i+1]) {
if (icon_wids[i]) {
yutani_focus_window(yctx, icon_wids[i]);
}
break;
}
}
}
} else if (evt->command == YUTANI_MOUSE_EVENT_MOVE) {
if (evt->new_y < PANEL_HEIGHT) {
for (int i = 0; i < 18; ++i) {
if (icon_lefts[i] == 0) {
set_focused(-1);
break;
}
if (evt->new_x >= icon_lefts[i] && evt->new_x < icon_lefts[i+1]) {
set_focused(i);
break;
}
}
} else {
set_focused(-1);
}
}
}
@ -131,7 +170,7 @@ void redraw(void) {
set_font_size(14);
draw_string(ctx, 10, 18, txt_color, "Applications");
int i = 0;
int i = 0, j = 0;
spin_lock(&lock);
if (window_list) {
foreach(node, window_list) {
@ -139,9 +178,21 @@ void redraw(void) {
set_font_face(FONT_SANS_SERIF);
set_font_size(14);
draw_string(ctx, 140 + i, 18, txt_color, s);
if (j == focused_app) {
draw_string(ctx, 140 + i, 18, rgb(142,216,255), s);
} else {
draw_string(ctx, 140 + i, 18, txt_color, s);
}
if (j < 18) {
icon_lefts[j] = 140 + i;
j++;
}
i += draw_string_width(s) + 20;
}
if (j < 19) {
icon_lefts[j] = 140 + i;
icon_lefts[j+1] = 0;
}
}
spin_unlock(&lock);
@ -152,11 +203,14 @@ void redraw(void) {
spin_unlock(&drawlock);
}
void update_window_list(void) {
yutani_query_windows(yctx);
list_t * new_window_list = list_create();
int i = 0;
while (1) {
yutani_msg_t * m = yutani_wait_for(yctx, YUTANI_MSG_WINDOW_ADVERTISE);
struct yutani_msg_window_advertise * wa = (void*)m->data;
@ -171,8 +225,15 @@ void update_window_list(void) {
char * s = malloc(wa->size + 1);
memcpy(s, wa->name, wa->size + 1);
if (i < 19) {
icon_wids[i] = wa->wid;
icon_wids[i+1] = 0;
}
list_insert(new_window_list, s);
free(m);
i++;
}
spin_lock(&lock);
@ -187,7 +248,6 @@ void update_window_list(void) {
redraw();
}
void * clock_thread(void * garbage) {
while (_continue) {
redraw();

View File

@ -373,6 +373,21 @@ yutani_msg_t * yutani_msg_build_session_end(void) {
return msg;
}
yutani_msg_t * yutani_msg_build_window_focus(yutani_wid_t wid) {
size_t s = sizeof(struct yutani_message) + sizeof(struct yutani_msg_window_focus);
yutani_msg_t * msg = malloc(s);
msg->magic = YUTANI_MSG__MAGIC;
msg->type = YUTANI_MSG_WINDOW_FOCUS;
msg->size = s;
struct yutani_msg_window_focus * mw = (void *)msg->data;
mw->wid = wid;
return msg;
}
int yutani_msg_send(yutani_t * y, yutani_msg_t * msg) {
return pex_reply(y->sock, msg->size, (char *)msg);
}
@ -553,6 +568,12 @@ void yutani_session_end(yutani_t * y) {
free(m);
}
void yutani_focus_window(yutani_t * yctx, yutani_wid_t wid) {
yutani_msg_t * m = yutani_msg_build_window_focus(wid);
int result = yutani_msg_send(yctx, m);
free(m);
}
gfx_context_t * init_graphics_yutani(yutani_window_t * window) {
gfx_context_t * out = malloc(sizeof(gfx_context_t));
out->width = window->width;

View File

@ -118,6 +118,10 @@ struct yutani_msg_window_advertise {
char name[];
};
struct yutani_msg_window_focus {
yutani_wid_t wid;
};
typedef struct yutani_window {
yutani_wid_t wid;
@ -156,11 +160,13 @@ typedef struct yutani_window {
#define YUTANI_MSG_RESIZE_BUFID 0x00000013
#define YUTANI_MSG_RESIZE_DONE 0x00000014
/* Some session management / de stuff */
#define YUTANI_MSG_WINDOW_ADVERTISE 0x00000020
#define YUTANI_MSG_SUBSCRIBE 0x00000021
#define YUTANI_MSG_UNSUBSCRIBE 0x00000022
#define YUTANI_MSG_NOTIFY 0x00000023
#define YUTANI_MSG_QUERY_WINDOWS 0x00000024
#define YUTANI_MSG_WINDOW_FOCUS 0x00000025
#define YUTANI_MSG_SESSION_END 0x00000030
@ -219,6 +225,7 @@ yutani_msg_t * yutani_msg_build_unsubscribe(void);
yutani_msg_t * yutani_msg_build_query(void);
yutani_msg_t * yutani_msg_build_notify(void);
yutani_msg_t * yutani_msg_build_session_end(void);
yutani_msg_t * yutani_msg_build_window_focus(yutani_wid_t wid);
int yutani_msg_send(yutani_t * y, yutani_msg_t * msg);
@ -239,6 +246,7 @@ void yutani_subscribe_windows(yutani_t * y);
void yutani_unsubscribe_windows(yutani_t * y);
void yutani_query_windows(yutani_t * y);
void yutani_session_end(yutani_t * y);
void yutani_focus_window(yutani_t * y, yutani_wid_t wid);
gfx_context_t * init_graphics_yutani(yutani_window_t * window);