summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEamon Walsh <ewalsh@tycho.nsa.gov>2011-08-01 17:26:55 -0400
committerEamon Walsh <ewalsh@tycho.nsa.gov>2011-08-01 17:33:16 -0400
commita3fd6e88dba7f05dcb201560385acd95cef395b8 (patch)
tree2f1ca06ad8a54c66fe8169f838b9ed65529e3548
parent1ea4b95e9ff47f29a05ba729edacb1410c73a4ac (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.
-rw-r--r--src/Makefile.am2
-rw-r--r--src/common.h4
-rw-r--r--src/display.c19
-rw-r--r--src/display.h2
-rw-r--r--src/icon.c141
-rw-r--r--src/icon.h47
-rw-r--r--src/track.h16
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;