diff options
author | Eamon Walsh <ewalsh@tycho.nsa.gov> | 2011-08-01 17:26:55 -0400 |
---|---|---|
committer | Eamon Walsh <ewalsh@tycho.nsa.gov> | 2011-08-01 17:33:16 -0400 |
commit | a3fd6e88dba7f05dcb201560385acd95cef395b8 (patch) | |
tree | 2f1ca06ad8a54c66fe8169f838b9ed65529e3548 /src | |
parent | 1ea4b95e9ff47f29a05ba729edacb1410c73a4ac (diff) |
Add event notification to the server.
This is an improvement over the simple exclamation mark that was used
to indicate guest startup and shutdown. A series of event types has
been defined in the track protocol and the support has been added to
set and clear event bits on individual displays or in a global set.
The server sets an event on a buffer display when it is created. A
global event is set when a display goes away (disconnect). Events on
a display are cleared when that display is visited or the display
disconnects. Global events are cleared when the switcher is shown.
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/common.h | 4 | ||||
-rw-r--r-- | src/display.c | 19 | ||||
-rw-r--r-- | src/display.h | 2 | ||||
-rw-r--r-- | src/icon.c | 141 | ||||
-rw-r--r-- | src/icon.h | 47 | ||||
-rw-r--r-- | src/track.h | 16 |
7 files changed, 222 insertions, 9 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index c8ffb1f..18d3aab 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -9,7 +9,7 @@ linpicker_monitor_LDADD = -lxenlight -lxenguest -lxenctrl -lxenstore \ -luuid -lblktapctl -lutil linpicker_server_SOURCES = server.c fd.c local.c input.c comm.c \ - view.c buffer.c client.c display.c \ + view.c buffer.c client.c display.c icon.c \ sclient.c dclient.c bclient.c sak.c \ xen_backend.c xen_server.c xenfb_server.c linpicker_server_LDADD = ../libvchan/libvchan.la \ diff --git a/src/common.h b/src/common.h index d807ec9..e561cc5 100644 --- a/src/common.h +++ b/src/common.h @@ -25,12 +25,16 @@ #define FONT_FILE PKGDATADIR "/decker.ttf" #define SERVER_BG_FILE PKGDATADIR "/serverbg.rgb" #define DESKTOP_BG_FILE PKGDATADIR "/desktopbg.rgb" +#define ICON_FILE_FORMAT PKGDATADIR "/event%03d.rgb" #define BFONT_HEIGHT 18 #define SFONT_HEIGHT 14 #define SECLABEL_HEIGHT (BFONT_HEIGHT + 6) #define MOUSELABEL_HEIGHT (SFONT_HEIGHT + 8) #define MOUSELABEL_WIDTH MOUSELABEL_HEIGHT #define MOUSELABEL_OFFSET 0 +#define ICON_HEIGHT 16 +#define ICON_WIDTH 16 +#define ICON_PAD 16 #define MAX_THUMBS 5 #define THUMB_SCALE 6 #define THUMB_PAD 25 diff --git a/src/display.c b/src/display.c index 511430e..9ba1602 100644 --- a/src/display.c +++ b/src/display.c @@ -56,6 +56,7 @@ #include "input.h" #include "sak.h" #include "sclient.h" +#include "icon.h" struct display *server_display; /* display for the server itself */ struct display *desktop_display; /* display for the combined desktop */ @@ -66,7 +67,6 @@ static struct display_cirq displays = CIRCLEQ_HEAD_INITIALIZER(displays); static int num_displays; static int is_switcher; /* we are in switcher mode */ -static int attention_indicator; static int screen_width, screen_height; static int guest_width, guest_height; @@ -95,8 +95,6 @@ display_update_seclabel(struct display *d) surf->SetColor(surf, l1->fg.r, l1->fg.g, l1->fg.b, 0xff); surf->SetFont(surf, bfont); surf->DrawString(surf, l1->label, -1, screen_width / (l2 ? 4 : 2), 0, DSTF_TOPCENTER); - if (attention_indicator) - surf->DrawString(surf, "!", -1, 0, 0, DSTF_TOPLEFT); if (l2) { surf->SetColor(surf, l2->bg.r, l2->bg.g, l2->bg.b, 0xff); @@ -105,6 +103,8 @@ display_update_seclabel(struct display *d) surf->DrawString(surf, l2->label, -1, screen_width * 3 / 4, 0, DSTF_TOPCENTER); } + icon_draw_icons(surf); + surf->Flip(surf, NULL, DSFLIP_ONSYNC); surf->Release(surf); } @@ -276,10 +276,10 @@ display_secure_enter(int keycode) { switch (keycode) { case LINPICK_SWITCH_SAK: + icon_clear(NULL); server_display->focus_client = active_display->client; display_update_seclabel(server_display); display_update_mouselabel(NULL, NULL); - attention_indicator = 0; is_switcher = 1; show_switcher(); break; @@ -304,6 +304,7 @@ display_secure_leave(void) is_switcher = 0; hide_switcher(); server_display->focus_client = NULL; + icon_clear(active_display); display_update_seclabel(active_display); display_update_mouselabel(active_display, active_display->mouse_client); } @@ -466,7 +467,7 @@ display_buffer_new(struct buffer *b) CIRCLEQ_INSERT_TAIL(&displays, d, display_next); num_displays++; - attention_indicator = 1; + icon_server_set(d, LINPICKER_EVENT_BUF_NEW, 1); } display_view_insert(b->bg_view, d); @@ -489,6 +490,7 @@ display_buffer_remove(struct buffer *b) if (b->flags) return; + icon_clear(d); CIRCLEQ_REMOVE(&displays, d, display_next); num_displays--; @@ -500,7 +502,7 @@ display_buffer_remove(struct buffer *b) if (is_switcher) show_switcher(); else { - attention_indicator = 1; + icon_server_set(NULL, LINPICKER_EVENT_BUF_GONE, 1); display_update_seclabel(active_display); } @@ -559,8 +561,8 @@ display_initialize(int *argc, char ***argv) { DFBWindowDescription wdesc; - /* Set up graphics */ - if (init_graphics(argc, argv) < 0) + /* Set up graphics and load icons */ + if (init_graphics(argc, argv) < 0 || icon_init() < 0) goto err; guest_width = screen_width; @@ -644,6 +646,7 @@ err: void display_shutdown(void) { client_remove_all(); + icon_shutdown(); if (switcher) { switcher->Destroy(switcher); diff --git a/src/display.h b/src/display.h index 4574ba7..453ffbd 100644 --- a/src/display.h +++ b/src/display.h @@ -30,6 +30,7 @@ #include <directfb.h> #include "common.h" +#include "track.h" #include "fd.h" #include "view.h" #include "buffer.h" @@ -61,6 +62,7 @@ struct display { key_func send_key; /* keyboard function */ mouse_func send_mouse; /* mouse function */ position_func update_position; /* track mouse position */ + char events[LINPICKER_NUM_EVENTS]; /* events signaled on display */ }; CIRCLEQ_HEAD(display_cirq, display); diff --git a/src/icon.c b/src/icon.c new file mode 100644 index 0000000..617d2d9 --- /dev/null +++ b/src/icon.c @@ -0,0 +1,141 @@ +/** + * @file + * @section AUTHORS + * + * Authors: + * Eamon Walsh <ewalsh@tycho.nsa.gov> + * + * @section LICENSE + * + * This file is in the public domain. + * + * @section DESCRIPTION + * + * This is the code that handles event notification icons in the security + * label bar. + */ + +#include <sys/types.h> +#include <stdint.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include <directfb.h> + +#include "common.h" +#include "display.h" +#include "sclient.h" +#include "icon.h" + +static unsigned int events[NUM_EVENTS]; +static unsigned char global_events[NUM_EVENTS]; + +static IDirectFBSurface *icons[NUM_EVENTS]; +static unsigned char icon_data[NUM_EVENTS][ICON_WIDTH * ICON_HEIGHT]; + +int +icon_set(struct display *d, unsigned icon_id, int set) +{ + if (icon_id >= CLIENT_EVENTS) + return -1; + + /* XXX check the client's permission to set the event */ + + if (d == active_display) + return 0; + + if (set && !d->events[icon_id]) { + d->events[icon_id] = 1; + events[icon_id]++; + } + if (!set && d->events[icon_id]) { + d->events[icon_id] = 0; + events[icon_id]--; + } + + return 0; +} + +void +icon_server_set(struct display *d, unsigned icon_id, int set) +{ + if (d) { + d->events[icon_id] = set; + events[icon_id] += set ? 1 : -1; + } else { + global_events[icon_id] = set; + events[icon_id] = set; + } +} + +void +icon_clear(struct display *d) +{ + int i; + + if (d) { + for (i = 0; i < LINPICKER_NUM_EVENTS; i++) + if (d->events[i]) { + d->events[i] = 0; + events[i]--; + } + } else { + for (i = 0; i < LINPICKER_NUM_EVENTS; i++) + if (global_events[i]) { + global_events[i] = 0; + events[i] = 0; + } + } +} + +void +icon_draw_icons(IDirectFBSurface *surf) +{ + int i, x, y; + + y = (SECLABEL_HEIGHT - ICON_HEIGHT) / 2; + + for (i = 0; i < LINPICKER_NUM_EVENTS; i++) + if (events[i]) { + x = ICON_PAD + i * (ICON_WIDTH + ICON_PAD); + surf->Blit(surf, icons[i], NULL, x, y); + } +} + +int +icon_init(void) +{ + int i; + DFBSurfaceDescription sdesc; + char filename[sizeof(ICON_FILE_FORMAT)]; + + for (i = 0; i < LINPICKER_NUM_EVENTS; i++) { + snprintf(filename, sizeof(filename), ICON_FILE_FORMAT, i); + sclient_load_image(filename, icon_data[i], ICON_WIDTH, ICON_HEIGHT); + + /* Set up preallocated DirectFB surface with the data */ + memset(&sdesc, 0, sizeof(sdesc)); + sdesc.flags = DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_CAPS | DSDESC_PIXELFORMAT | DSDESC_PREALLOCATED; + sdesc.width = ICON_WIDTH; + sdesc.height = ICON_HEIGHT; + sdesc.pixelformat = DSPF_RGB332; + sdesc.preallocated[0].data = icon_data[i]; + sdesc.preallocated[0].pitch = ICON_WIDTH; + + /* create DirectFB surface */ + if (dfb->CreateSurface(dfb, &sdesc, &icons[i]) != DFB_OK) + return -1; + } + + return 0; +} + +void +icon_shutdown(void) +{ + int i; + + for (i = 0; i < LINPICKER_NUM_EVENTS; i++) + icons[i]->Release(icons[i]); +} diff --git a/src/icon.h b/src/icon.h new file mode 100644 index 0000000..32d8686 --- /dev/null +++ b/src/icon.h @@ -0,0 +1,47 @@ +/** + * @file + * @section AUTHORS + * + * Authors: + * Eamon Walsh <ewalsh@tycho.nsa.gov> + * + * @section LICENSE + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; under version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef _LINPICKER_ICON_H_ +#define _LINPICKER_ICON_H_ + +#include <directfb.h> + +int +icon_set(struct display *d, unsigned icon_id, int set); + +void +icon_server_set(struct display *d, unsigned icon_id, int set); + +void +icon_clear(struct display *d); + +void +icon_draw_icons(IDirectFBSurface *surf); + +int +icon_init(void); + +void +icon_shutdown(void); + +#endif /* _LINPICKER_ICON_H_ */ diff --git a/src/track.h b/src/track.h index 94a07b6..de9dda5 100644 --- a/src/track.h +++ b/src/track.h @@ -50,6 +50,22 @@ #define LINPICKER_FLAG_HIDDEN 32 #define LINPICKER_FLAG_SHOWN 64 +/* Notification events */ +#define LINPICKER_EVENT_MAIL 0 +#define LINPICKER_EVENT_CHAT 1 +/* Server-only notification events */ +#define LINPICKER_EVENT_BUF_NEW 2 +#define LINPICKER_EVENT_BUF_GONE 3 +/* Event counts */ +#define LINPICKER_CLIENT_EVENTS 2 +#define LINPICKER_NUM_EVENTS 4 + +/* Event counts */ +#define CLIENT_EVENTS 2 +#define SERVER_EVENTS 2 +#define NUM_EVENTS (CLIENT_EVENTS + SERVER_EVENTS) + + struct lin_message { uint32_t type; uint32_t view; |