dslinux/user/pixil/sys/pixilwm Makefile applets.c applets.h apps.c apps.h categories.c categories.h clients.c config.c config.h container.c exec.c hardcodedimage.h home.c icons.c inputs.c ipc.c keyb.c main.c nanowm.h powerman.c powerman.h pwroff.h root.c screensaver.c screensaver.h scrib.c sys_menu.c sys_menu.h themes.c themes.h themesconfig.c themetags.h utils.c utils.h wlist.c
amadeus
dslinux_amadeus at user.in-berlin.de
Tue Oct 3 13:27:13 CEST 2006
Update of /cvsroot/dslinux/dslinux/user/pixil/sys/pixilwm
In directory antilope:/tmp/cvs-serv11916/sys/pixilwm
Added Files:
Makefile applets.c applets.h apps.c apps.h categories.c
categories.h clients.c config.c config.h container.c exec.c
hardcodedimage.h home.c icons.c inputs.c ipc.c keyb.c main.c
nanowm.h powerman.c powerman.h pwroff.h root.c screensaver.c
screensaver.h scrib.c sys_menu.c sys_menu.h themes.c themes.h
themesconfig.c themetags.h utils.c utils.h wlist.c
Log Message:
adding pristine copy of pixil to HEAD so I can branch from it
--- NEW FILE: screensaver.h ---
/*
* Copyright (c) 2003 Century Software, Inc. All Rights Reserved.
*
* This file is part of the PIXIL Operating Environment
*
* The use, copying and distribution of this file is governed by one
* of two licenses, the PIXIL Commercial License, or the GNU General
* Public License, version 2.
*
* Licensees holding a valid PIXIL Commercial License may use this file
* in accordance with the PIXIL Commercial License Agreement provided
* with the Software. Others are governed under the terms of the GNU
* General Public License version 2.
*
* This file may be distributed and/or modified under the terms of the
* GNU General Public License version 2 as published by the Free
* Software Foundation and appearing in the file LICENSE.GPL included
* in the packaging of this file.
*
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING
* THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE.
*
* RESTRICTED RIGHTS LEGEND
*
* Use, duplication, or disclosure by the government is subject to
* restriction as set forth in paragraph (b)(3)(b) of the Rights in
* Technical Data and Computer Software clause in DAR 7-104.9(a).
*
* See http://www.pixil.org/gpl/ for GPL licensing
* information.
*
* See http://www.pixil.org/license.html or
* email cetsales at centurysoftware.com for information about the PIXIL
* Commercial License Agreement, or if any conditions of this licensing
* are not clear to you.
*/
#ifndef SCREENSAVER_H
#define SCREENSAVER_H
void screensaver_init(void);
int screensaver_active(void);
void screensaver_frame(void);
void screensaver_enable(void);
void screensaver_disable(void);
#endif
--- NEW FILE: config.h ---
/*
* Copyright (c) 2003 Century Software, Inc. All Rights Reserved.
*
* This file is part of the PIXIL Operating Environment
*
* The use, copying and distribution of this file is governed by one
* of two licenses, the PIXIL Commercial License, or the GNU General
* Public License, version 2.
*
* Licensees holding a valid PIXIL Commercial License may use this file
* in accordance with the PIXIL Commercial License Agreement provided
* with the Software. Others are governed under the terms of the GNU
* General Public License version 2.
*
* This file may be distributed and/or modified under the terms of the
* GNU General Public License version 2 as published by the Free
* Software Foundation and appearing in the file LICENSE.GPL included
* in the packaging of this file.
*
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING
* THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE.
*
* RESTRICTED RIGHTS LEGEND
*
* Use, duplication, or disclosure by the government is subject to
* restriction as set forth in paragraph (b)(3)(b) of the Rights in
* Technical Data and Computer Software clause in DAR 7-104.9(a).
*
* See http://www.pixil.org/gpl/ for GPL licensing
* information.
*
* See http://www.pixil.org/license.html or
* email cetsales at centurysoftware.com for information about the PIXIL
* Commercial License Agreement, or if any conditions of this licensing
* are not clear to you.
*/
#ifndef SETTINGS_H
#define SETTINGS_H
#include "nano-X.h"
/* These are the default settings */
/* Change them as you see fit */
#define DEFAULT_WALLPAPER "cenlogo.gif"
#define DEFAULT_BGCOLOR COLOR_DESKTOP
#define DEFAULT_ICONCOLOR COLOR_DESKTOP
#define DEFAULT_ICONTEXT COLOR_ICONTEXT
#define WALLPAPER_NONE 0x00
#define WALLPAPER_TILED 0x01
#define WALLPAPER_CENTERED 0x02
#define WALLPAPER_FULLSCREEN 0x04
#define WALLPAPER_BOTTOM 0x05
#define WM_BGCOLOR 0
#define WM_ICONCOLOR 1
#define WM_ICONTEXT 2
#define WM_TASKBAR 3
#define WM_DIALOG 5
#define WM_COLOR_SIZE 6
#define DESKTOP_PREFIX 0
#define DESKTOP_IMAGEDIR 1
#define DESKTOP_NXAPPDIR 2
#define DESKTOP_SOUNDDIR 3
#define DESKTOP_THEMEDIR 4
#define WM_DIR_SIZE 5
/* These are functions to get the various window manager settings */
void wm_setColor(int color, GR_COLOR value);
GR_COLOR wm_getColor(int color);
void wm_setDir(int dir, char *value);
const char *wm_getDir(int dir);
int wm_getWallpaper(GR_IMAGE_ID * iid, int *flags);
#endif
--- NEW FILE: config.c ---
/*
* Copyright (c) 2003 Century Software, Inc. All Rights Reserved.
*
* This file is part of the PIXIL Operating Environment
*
* The use, copying and distribution of this file is governed by one
* of two licenses, the PIXIL Commercial License, or the GNU General
* Public License, version 2.
*
* Licensees holding a valid PIXIL Commercial License may use this file
* in accordance with the PIXIL Commercial License Agreement provided
* with the Software. Others are governed under the terms of the GNU
* General Public License version 2.
*
* This file may be distributed and/or modified under the terms of the
* GNU General Public License version 2 as published by the Free
* Software Foundation and appearing in the file LICENSE.GPL included
* in the packaging of this file.
*
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING
* THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE.
*
* RESTRICTED RIGHTS LEGEND
*
* Use, duplication, or disclosure by the government is subject to
* restriction as set forth in paragraph (b)(3)(b) of the Rights in
* Technical Data and Computer Software clause in DAR 7-104.9(a).
*
* See http://www.pixil.org/gpl/ for GPL licensing
* information.
*
* See http://www.pixil.org/license.html or
* email cetsales at centurysoftware.com for information about the PIXIL
* Commercial License Agreement, or if any conditions of this licensing
* are not clear to you.
*/
/* For now we try to play nicely with the rest of the system */
/* API that has been established */
#include <pixil_config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <ctype.h>
#include <par/par.h>
#include <nano-X.h>
#include "nanowm.h"
#include "apps.h"
#include "categories.h"
#include "config.h"
#ifdef CONFIG_PIXILWM_THEMES
#include "themes.h"
#endif
#include "applets.h"
/* This local structure maintains our current settings */
static struct
{
/* Wallpaper settings */
struct
{
GR_IMAGE_ID bgImage;
int flags;
}
wallpaper;
/* Colors */
GR_COLOR colorArray[WM_COLOR_SIZE];
char *dirArray[WM_DIR_SIZE];
char *theme;
}
wmSettings;
/* These are a series of "default" values */
static const char *defaultDirs[WM_DIR_SIZE] =
{ ".", "./images", "./bin", "./sounds", "./themes" };
static void
strToLower(char *str)
{
int i;
for (i = 0; i < strlen(str); i++)
tolower(str[i]);
}
void
wm_setColor(int color, GR_COLOR value)
{
wmSettings.colorArray[color] = value;
}
GR_COLOR
wm_getColor(int color)
{
return (wmSettings.colorArray[color]);
}
void
wm_setDir(int dir, char *value)
{
if (wmSettings.dirArray[dir]) {
if (strcmp(wmSettings.dirArray[dir], value) == 0)
return;
free(wmSettings.dirArray[dir]);
wmSettings.dirArray[dir] = 0;
}
wmSettings.dirArray[dir] = strdup(value);
}
inline const char *
wm_getDir(int dir)
{
if (!wmSettings.dirArray[dir])
return (defaultDirs[dir]);
return (wmSettings.dirArray[dir]);
}
int
wm_getWallpaper(GR_IMAGE_ID * iid, int *flags)
{
if (!wmSettings.wallpaper.bgImage ||
wmSettings.wallpaper.flags == WALLPAPER_NONE)
return (0);
*iid = wmSettings.wallpaper.bgImage;
*flags = wmSettings.wallpaper.flags;
return (1);
}
static int
nxLoadDefaults(void)
{
wmSettings.wallpaper.flags = WALLPAPER_NONE;
/* NOTE: The GrGetSysColor here is not freeing its nxAllocReq */
wm_setColor(WM_BGCOLOR, COLOR_DESKTOP);
wm_setColor(WM_ICONCOLOR, COLOR_DESKTOP);
wm_setColor(WM_ICONTEXT, COLOR_ICONTEXT);
wm_setColor(WM_TASKBAR, COLOR_TASKBAR);
wm_setColor(WM_DIALOG, COLOR_TASKBAR);
return (0);
}
static void
getColor(db_handle * db, int index, char *keyword)
{
int val;
char *name = alloca(strlen("colors") + strlen(keyword) + 2);
sprintf(name, "colors.%s", keyword);
if (par_getScreentopSetting(db, name, &val, sizeof(val)) <= 0) {
error("Couldn't get the color '%s' from the database.\n", keyword);
return;
}
wm_setColor(index,
GR_RGB((val >> 16) & 0xFF, (val >> 8) & 0xFF, (val) & 0xFF));
}
static void
getDirectory(db_handle * db, int index, char *keyword)
{
char str[512];
int size = par_getScreentopDir(db, keyword, str, sizeof(str));
if (size > 0)
wm_setDir(index, str);
else
error("Couldn't get the directory '%s' from the database.\n",
keyword);
}
static void
nxLoadApplets(db_handle *db) {
itemlist_t *list;
int i;
if (par_getList(db, "screentop.settings.applets", &list) <= 0) {
printf("screentop.settings.applets doesn't exist\n");
return;
}
for(i = 0; i < list->count; i++) {
char plugin[128];
char name[64];
sprintf(name, "screentop.settings.applets.%s", list->list[i]);
if (db_findNode(db, name, plugin, sizeof(plugin), 0) < 0)
continue;
wm_applet_load(plugin);
}
par_freeItemList(list);
}
static int
nxLoadSettings(db_handle * db)
{
char in_string[512];
int style, size;
/* First get the directories */
getDirectory(db, DESKTOP_THEMEDIR, "themedir");
getDirectory(db, DESKTOP_NXAPPDIR, "bindir");
getDirectory(db, DESKTOP_IMAGEDIR, "icondir");
/*--- Get the background image and style ---*/
size =
par_getScreentopSetting(db, "bgimage", in_string, sizeof(in_string));
if (size > 0) {
wmSettings.wallpaper.bgImage = loadIconImage(in_string, 0, 0);
if (wmSettings.wallpaper.bgImage) {
style = WALLPAPER_CENTERED;
size = par_getScreentopSetting(db, "bgstyle", in_string,
sizeof(in_string));
if (size > 0) {
strToLower(in_string);
if (!strcmp(in_string, "bottom"))
style = WALLPAPER_BOTTOM;
else if (!strcmp(in_string, "tiled"))
style = WALLPAPER_TILED;
else if (!strcmp(in_string, "fullscreen"))
style = WALLPAPER_FULLSCREEN;
}
} else
style = WALLPAPER_NONE;
wmSettings.wallpaper.flags = style;
}
/*--- Now load the color settings ---*/
getColor(db, WM_BGCOLOR, "bgcolor");
getColor(db, WM_ICONCOLOR, "iconbgcolor");
getColor(db, WM_ICONTEXT, "iconfgcolor");
getColor(db, WM_TASKBAR, "taskbar");
getColor(db, WM_DIALOG, "dialog");
/* Get the theme information */
#ifdef CONFIG_PIXILWM_THEMES
if (wm_getDir(DESKTOP_THEMEDIR)) {
const char *dir = wm_getDir(DESKTOP_THEMEDIR);
set_activeTheme(createTheme(dir));
}
#endif
/* Lastly, load the taskbar applets */
nxLoadApplets(db);
return (0);
}
/* Fixme: How can we handle reloading settings? */
int
nxLoadConfig(void)
{
db_handle *db = 0;
/* Load any defaults */
bzero(&wmSettings, sizeof(wmSettings));
nxLoadDefaults();
/* Now, open the PAR and get ready to read! */
db = db_openDB(db_getDefaultDB(), PAR_DB_MODE_RDONLY);
if (!db) {
error("PAR database open returned error %d\n", pardb_errno);
return (-1);
}
/* Now load in steps. First the settings */
nxLoadSettings(db);
/* Next, get the categories and applications */
nxLoadCategories(db);
/* Finally, load the input tools */
nxLoadInputs(db);
/* We're done, go ahead and close the database */
db_closeDB(db);
return (0);
}
--- NEW FILE: applets.c ---
/*
* Copyright (c) 2003 Century Software, Inc. All Rights Reserved.
*
* This file is part of the PIXIL Operating Environment
*
* The use, copying and distribution of this file is governed by one
* of two licenses, the PIXIL Commercial License, or the GNU General
* Public License, version 2.
*
* Licensees holding a valid PIXIL Commercial License may use this file
* in accordance with the PIXIL Commercial License Agreement provided
* with the Software. Others are governed under the terms of the GNU
* General Public License version 2.
*
* This file may be distributed and/or modified under the terms of the
* GNU General Public License version 2 as published by the Free
* Software Foundation and appearing in the file LICENSE.GPL included
* in the packaging of this file.
*
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING
* THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE.
*
* RESTRICTED RIGHTS LEGEND
*
* Use, duplication, or disclosure by the government is subject to
* restriction as set forth in paragraph (b)(3)(b) of the Rights in
* Technical Data and Computer Software clause in DAR 7-104.9(a).
*
* See http://www.pixil.org/gpl/ for GPL licensing
* information.
*
* See http://www.pixil.org/license.html or
* email cetsales at centurysoftware.com for information about the PIXIL
* Commercial License Agreement, or if any conditions of this licensing
* are not clear to you.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dlfcn.h>
#include <errno.h>
#include "nanowm.h"
#include "config.h"
#include "applets.h"
static int g_applet_id = 0;
static int g_timer_id = 0;
static int applet_x, applet_y, applet_h;
static applet_t *applet_list = 0;
static applet_events_t *applet_events = 0;
static icon_applet_t *icon_applets = 0;
static applet_timer_t *applet_timers = 0;
void wm_init_applets(void) {
GR_SCREEN_INFO si;
GrGetScreenInfo(&si);
applet_x = 5;
applet_y = si.ws_height + 4;
applet_h = 13;
}
void wm_applet_handle_event(GR_EVENT *event) {
GR_WINDOW_ID wid = ((GR_EVENT_GENERAL *) event)->wid;
applet_events_t *e = applet_events;
for( ; e; e = e->next) {
if (e->wid != wid) continue;
if (e->events & GR_EVENTMASK(event->type)) {
if (e->cb) e->cb(wid, event);
break;
}
}
}
unsigned long wm_applet_handle_timer(unsigned long elapsed) {
applet_timer_t *timer = applet_timers;
applet_timer_t *prev = 0, *newhead = 0, *newtail = 0;
if (!timer) return 0;
while(timer) {
applet_timer_t *next = timer->next;
timer->remain -= elapsed;
if (timer->remain <= 0) {
if (timer->callback) timer->callback(); /* Fire the callback */
/* Remove this item from the list */
if (!prev) applet_timers = timer->next;
else prev->next = timer->next;
/* If this item is periodic, then add it to the bottom */
/* of the new list */
/* Otherwise, get rid of the record */
if (timer->type == APPLET_TIMER_PERIODIC) {
timer->remain = timer->period;
timer->next = 0;
if (!newhead) newhead = newtail = timer;
else {
newtail->next = timer;
newtail = timer;
}
}
else free(timer);
} else prev = timer;
timer = next;
}
if (!applet_timers) applet_timers = newhead;
else prev->next = newhead;
if (applet_timers) return applet_timers->remain;
return 0;
}
unsigned long wm_applet_get_timeout(void) {
return applet_timers ? applet_timers->remain : 0;
}
void wm_applet_del_timer(int applet_id, int timer_id) {
applet_timer_t *t = applet_timers;
applet_timer_t *p = 0;
while(t) {
applet_timer_t *n = t->next;
/* Delete the timer, or all the timers for this applet if timer_id is zero */
if ( (timer_id && t->id == timer_id) || (!timer_id && t->applet_id == applet_id)) {
if (!p) applet_timers = t->next;
else p->next = t->next;
free(t);
if (timer_id) return;
} else p = t;
t = n;
}
}
int wm_applet_add_timer(int applet_id, int type, unsigned long length, applet_timeout_callback cb) {
applet_timer_t *timer = (applet_timer_t *) calloc(1, sizeof(applet_timer_t));
timer->applet_id = applet_id;
timer->period = timer->remain = length;
timer->type = type;
timer->id = g_timer_id++;
timer->callback = cb;
if (!applet_timers) applet_timers = timer;
else {
applet_timer_t *t = applet_timers;
for( ; t->next; t = t->next);
t->next = timer;
}
return timer->id;
}
/* This is a call for a applet to register its window ID plus a list
of events that it cares about
*/
int wm_applet_register(int applet_id, GR_WINDOW_ID id, unsigned long events,
applet_event_callback cb) {
applet_events_t *e = applet_events;
applet_events_t *p = 0;
for( ; e; e = e->next) {
if (e->wid != id) continue;
/* if the bit mask is zero, then erase this record */
if (events == 0) {
if (!p) applet_events = e->next;
else p->next = e->next;
free(e);
return 0;
}
/* Otherwise, change the events to reflect the new list */
e->events = events;
GrSelectEvents(id, events);
return 0;
}
/* Don't let us add a zero event record */
if (!events) return 0;
/* No record was found, so add one */
e = (applet_events_t *) calloc(1, sizeof(applet_events_t));
if (!e) return -1;
e->wid = id;
e->applet_id = applet_id;
e->cb = cb;
e->events = events;
if (!applet_events) applet_events = e;
else {
applet_events_t *t = applet_events;
for( ; t->next; t = t->next);
t->next = e;
}
GrSelectEvents(id, events);
return 0;
}
void wm_applet_unregister(int applet_id, GR_WINDOW_ID gid) {
wm_applet_register(applet_id, gid, 0, 0);
}
int wm_applet_load(char *filename) {
applet_t *applet = 0;
if (!filename) return -1;
applet = (applet_t *) calloc(1, sizeof(applet_t));
if (!applet) return -1;
applet->handle = dlopen(filename, RTLD_LAZY | RTLD_GLOBAL);
if (!applet->handle) {
printf("Unable to load applet [%s] [%s]\n", filename, dlerror());
goto load_error;
}
/* Get the hooks for the applet */
applet->init = (int (*)(int, int *, int, int))
dlsym(applet->handle, "applet_init");
applet->close = (int (*)(void))
dlsym(applet->handle, "applet_close");
/* Set the applet id */
applet->applet_id = g_applet_id++;
/* Initalize the applet */
if (applet->init(applet->applet_id, &applet_x, applet_y, applet_h))
goto load_error;
/* Insert some padding */
applet_x += 5;
/* Finally, insert it into the list of applets */
if (!applet_list) applet_list = applet;
else {
applet_t *a = applet_list;
for( ; a->next; a = a->next);
a->next = applet;
}
return 0;
load_error:
printf("Error loading the plugin [%s], bailing!\n", filename);
if (applet->handle) dlclose(applet->handle);
free(applet);
return -1;
}
/*** Utility functions ***/
/* These are common functions that can be defined once and used many times */
/* This creates a icon applet (ie, a picture that gets pressed) */
/* and calls a callback when the icon is pressed */
static void icon_applet_draw(icon_applet_t *icon) {
GR_GC_ID gc = GrNewGC();
GrDrawImageToFit(icon->wid, gc, 0, 0, -1, -1, icon->image);
GrDestroyGC(gc);
}
void icon_applet_callback(GR_WINDOW_ID wid, GR_EVENT *event) {
icon_applet_t *i = icon_applets;
for( ; i; i = i->next) {
if (i->wid != wid) continue;
if (event->type == GR_EVENT_TYPE_BUTTON_DOWN) {
if (i->callback) i->callback();
}
else if (event->type == GR_EVENT_TYPE_EXPOSURE) {
icon_applet_draw(i);
}
return;
}
}
GR_WINDOW_ID wm_create_icon_applet(int id, int x, int y, int w, int h, char *filename,
void (*callback)(void)) {
icon_applet_t *icon = (icon_applet_t *) calloc(1, sizeof(icon_applet_t));
if (!icon) return 0;
if (!icon->image) icon->image = loadIconImage(filename, 0, 0);
if (!icon->image) goto exit_icon;
icon->applet_id = id;
icon->callback = callback;
icon->wid = GrNewWindowEx(GR_WM_PROPS_NODECORATE, 0, GR_ROOT_WINDOW_ID,
x, y, w, h, 0xFFFFFF);
if (!icon->wid) goto exit_icon;
if (!icon_applets) icon_applets = icon;
else {
icon_applet_t *i = icon_applets;
for( ; i->next; i = i->next);
i->next = icon;
}
wm_applet_register(id, icon->wid, GR_EVENT_MASK_BUTTON_DOWN | GR_EVENT_MASK_EXPOSURE,
icon_applet_callback);
GrMapWindow(icon->wid);
return(icon->wid);
exit_icon:
if (icon->image) GrFreeImage(icon->image);
free(icon);
return 0;
}
void wm_close_icon_applet(int id) {
icon_applet_t *i = icon_applets;
icon_applet_t *p = 0;
while(i) {
icon_applet_t *n = i->next;
if (i->applet_id == id) {
if (!p) icon_applets = i->next;
else p->next = i->next;
if (i->image) GrFreeImage(i->image);
if (i->wid) GrDestroyWindow(i->wid);
free(i);
}
else p = i;
i = n;
}
}
--- NEW FILE: applets.h ---
#ifndef APPLET_H_
#define APPLET_H_
#include <nano-X.h>
#include "config.h"
typedef void (*applet_event_callback)(GR_WINDOW_ID, GR_EVENT *);
typedef void (*applet_timeout_callback)(void);
#define APPLET_TIMER_ONESHOT 0
#define APPLET_TIMER_PERIODIC 1
typedef struct applet_timer {
int id;
int applet_id;
signed long remain;
unsigned long period;
applet_timeout_callback callback;
int type;
struct applet_timer *next;
} applet_timer_t;
typedef struct applet_event {
int applet_id;
GR_WINDOW_ID wid;
unsigned long events;
applet_event_callback cb;
struct applet_event *next;
} applet_events_t;
typedef struct icon_applet {
unsigned long applet_id;
GR_WINDOW_ID wid;
GR_IMAGE_ID image;
void (*callback) (void);
struct icon_applet *next;
} icon_applet_t;
typedef struct applet {
int applet_id;
void *handle;
int (*init)(int, int *, int, int);
int (*close)(void);
struct applet *next;
} applet_t;
int wm_applet_add_timer(int applet_id, int type, unsigned long length, applet_timeout_callback cb);
unsigned long wm_applet_get_timeout(void);
void wm_applet_handle_event(GR_EVENT *event);
unsigned long wm_applet_handle_timer(unsigned long elapsed);
int wm_applet_load(char *filename);
int wm_applet_register(int applet_id, GR_WINDOW_ID id, unsigned long events,
applet_event_callback cb);
void wm_applet_del_timer(int applet_id, int timer_id);
#endif
--- NEW FILE: hardcodedimage.h ---
/*
* Copyright (c) 2003 Century Software, Inc. All Rights Reserved.
*
* This file is part of the PIXIL Operating Environment
*
* The use, copying and distribution of this file is governed by one
* of two licenses, the PIXIL Commercial License, or the GNU General
* Public License, version 2.
*
* Licensees holding a valid PIXIL Commercial License may use this file
* in accordance with the PIXIL Commercial License Agreement provided
* with the Software. Others are governed under the terms of the GNU
* General Public License version 2.
*
* This file may be distributed and/or modified under the terms of the
* GNU General Public License version 2 as published by the Free
* Software Foundation and appearing in the file LICENSE.GPL included
* in the packaging of this file.
*
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING
* THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE.
*
* RESTRICTED RIGHTS LEGEND
*
* Use, duplication, or disclosure by the government is subject to
* restriction as set forth in paragraph (b)(3)(b) of the Rights in
* Technical Data and Computer Software clause in DAR 7-104.9(a).
*
* See http://www.pixil.org/gpl/ for GPL licensing
* information.
*
* See http://www.pixil.org/license.html or
* email cetsales at centurysoftware.com for information about the PIXIL
* Commercial License Agreement, or if any conditions of this licensing
* are not clear to you.
*/
#ifndef HARDCODEDIMAGE_INCLUDED
#define HARDCODEDIMAGE_INCLUDED 1
#include "device.h"
#ifdef DEFAULT_WALLPAPER
#undef DEFAULT_WALLPAPER
#define DEFAULT_WALLPAPER "default.gif"
#endif
static MWUCHAR hardcodedimage[] =
{ 0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0xf0, 0x0, 0x3c, 0x0, 0x84, 0x0,
0x0, 0xdf, 0xea, 0xf7, 0x0, 0x5a, 0xbf, 0x10, 0x64, 0xc3, 0x20, 0x6f,
0xc7, 0x30, 0x79, 0xcb, 0x40,
0x83, 0xcf, 0x50, 0x8e, 0xd3, 0x60, 0x98, 0xd7, 0x70, 0xa2, 0xdb, 0x80,
0xad, 0xdf, 0x8f, 0xb7,
0xe3, 0x9f, 0xc1, 0xe7, 0xaf, 0xcb, 0xeb, 0xbf, 0xd6, 0xef, 0xcf, 0xe0,
0xf3, 0xef, 0xf5, 0xfb,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff,
0x21, 0xf9, 0x4, 0x1, 0xa, 0x0, 0x1f, 0x0, 0x2c, 0x0, 0x0, 0x0, 0x0, 0xf0,
0x0, 0x3c, 0x0, 0x0, 0x5,
0xfe, 0xe0, 0x27, 0x8e, 0x64, 0x69, 0x9e, 0x68, 0xaa, 0xae, 0x6c, 0xeb,
0xbe, 0x70, 0x2c, 0xcf,
0x74, 0x6d, 0xdf, 0x78, 0xae, 0xef, 0x7c, 0xef, 0xff, 0xc0, 0xa0, 0x70,
0x48, 0x2c, 0x1a, 0x8f,
0xc8, 0xa4, 0x72, 0xc9, 0x6c, 0x3a, 0x9f, 0xd0, 0xa8, 0x74, 0x4a, 0xad,
0x5a, 0xaf, 0xd8, 0xac,
0x76, 0xcb, 0xed, 0x7a, 0x49, 0x5, 0x0, 0xe0, 0xf0, 0x2d, 0x9b, 0x97, 0x6,
0x88, 0x1a, 0x32, 0x6,
0x16, 0x12, 0x8a, 0x46, 0x83, 0x91, 0x38, 0x10, 0x72, 0x7, 0xc5, 0x79,
0xef, 0x33, 0x34, 0xe, 0x5,
0xd, 0x6b, 0x6c, 0x5, 0x3b, 0x5, 0xc, 0x83, 0x89, 0x10, 0xf, 0xb, 0x77,
0x23, 0x5, 0x8a, 0x8a, 0x85,
0x23, 0x9, 0x10, 0x64, 0x2f, 0x82, 0x93, 0x95, 0x91, 0x9c, 0x10, 0xd,
0x94, 0x6a, 0x9, 0x2f, 0x6a,
0x93, 0x8f, 0x9d, 0xf, 0xd, 0x8, 0x25, 0xb, 0x6b, 0xc, 0x2b, 0x3, 0x6a,
0x0, 0x55, 0x88, 0xb1, 0x5,
0x81, 0x83, 0xd, 0xa5, 0x35, 0xb4, 0x10, 0xb, 0x6, 0x3, 0x8f, 0xa, 0xf,
0x6b, 0x8e, 0x1f, 0x90,
0x8b, 0x72, 0xc9, 0xca, 0xc5, 0x1f, 0x9b, 0x97, 0x2d, 0x99, 0x22, 0x7,
0xca, 0xc9, 0x6b, 0xd4, 0x72,
0x7a, 0x22, 0x9b, 0xa2, 0x2e, 0xa4, 0x25, 0xc7, 0xa8, 0xd, 0x71, 0xd,
0xc3, 0x6a, 0xf, 0xcf, 0x3,
0xe5, 0x10, 0xc0, 0x29, 0xac, 0x10, 0x6, 0x53, 0x80, 0xb7, 0xd6, 0xb6,
0x82, 0xf4, 0x34, 0x4, 0xe,
0x6a, 0xe, 0xcc, 0x24, 0x3, 0x82, 0xf, 0xc0, 0xa8, 0xf9, 0xd4, 0x62, 0xd3,
0x83, 0x7e, 0x29, 0xa2,
0xa5, 0x58, 0xb3, 0x62, 0xdb, 0x28, 0x8, 0xba, 0x8c, 0xd, 0x34, 0x61,
0x40, 0x9f, 0x37, 0x11, 0x8,
0xd6, 0x2c, 0x48, 0x1, 0xb, 0x82, 0xab, 0x28, 0xff, 0x6, 0xd6, 0xc3, 0x55,
0xc0, 0x0, 0x0, 0x92,
0x31, 0xfe, 0xd2, 0xed, 0x63, 0xc1, 0x80, 0xa0, 0x88, 0x63, 0x2e, 0x1b,
0xae, 0x39, 0x8, 0xd, 0xa2,
0xa, 0x86, 0x2a, 0x1c, 0x76, 0xb3, 0x29, 0xd0, 0x13, 0xa, 0x8b, 0x1f,
0x45, 0x58, 0x5c, 0x87, 0x82,
0xd5, 0x3, 0x76, 0x50, 0x4c, 0xe, 0x5a, 0x30, 0x40, 0x29, 0xbd, 0x3, 0x27,
0x5b, 0x21, 0x65, 0x61,
0x31, 0x60, 0xc1, 0x9e, 0x31, 0x73, 0xe, 0x3a, 0xca, 0x42, 0x21, 0xa,
0x9c, 0x29, 0x74, 0xb6, 0xb8,
0x68, 0xca, 0xe7, 0x89, 0x34, 0x6a, 0x7a, 0xf6, 0x42, 0x31, 0x8c, 0xdb,
0x13, 0x5, 0x6d, 0xa0, 0x2e,
0x1d, 0x20, 0x57, 0x6a, 0x5d, 0x35, 0x4c, 0x59, 0x6c, 0xb2, 0x34, 0x3,
0xa6, 0x8b, 0xbd, 0x2b, 0x57,
0x78, 0x3d, 0x1, 0x16, 0x85, 0x58, 0x16, 0x64, 0x5f, 0x4e, 0xfc, 0x9a,
0x96, 0x4, 0xaf, 0xa9, 0xda,
0xd8, 0x44, 0x19, 0x1a, 0x57, 0x5d, 0x2f, 0xba, 0x51, 0xf1, 0x62, 0x9e,
0xab, 0xa2, 0x9c, 0xac,
0xbe, 0x8b, 0xf5, 0x7a, 0x54, 0xe7, 0x40, 0x30, 0x4f, 0xc6, 0x10, 0x64,
0x42, 0x70, 0x8b, 0xf8,
0xb4, 0x62, 0xb3, 0x84, 0x1b, 0x8f, 0x50, 0xb9, 0xb6, 0xc4, 0xb0, 0x88,
0x4b, 0x86, 0xae, 0x71,
0x50, 0x28, 0x81, 0xe5, 0x8d, 0x77, 0x7b, 0x11, 0xf0, 0xbd, 0x14, 0xc5,
0x31, 0x8, 0xd9, 0x64, 0xf8,
0x2d, 0xb8, 0x9a, 0x0, 0x69, 0x15, 0x83, 0x4d, 0x14, 0x3e, 0x71, 0x78,
0x45, 0x62, 0x89, 0xb0, 0xa5,
0x2f, 0x32, 0xb1, 0x57, 0x97, 0x82, 0xec, 0x4c, 0x74, 0x27, 0xca, 0xd5,
0x4c, 0xdd, 0x83, 0x4, 0x3,
0x88, 0x6b, 0x1c, 0x5e, 0x2e, 0x68, 0x89, 0xbd, 0xf0, 0x40, 0x83, 0xf,
0xbb, 0xfa, 0x83, 0xf3, 0xdd,
0x9, 0x5d, 0x6b, 0x4f, 0xad, 0xb5, 0xfe, 0xce, 0x88, 0xcb, 0x99, 0x90,
0x51, 0x6d, 0x25, 0x44, 0xe5,
0x52, 0x47, 0x90, 0x29, 0xfe, 0x61, 0x4f, 0x27, 0x9e, 0xf4, 0x66, 0x1e,
0x7a, 0xea, 0x2d, 0x2, 0x61,
0x7c, 0x27, 0x2c, 0x98, 0xa0, 0xb, 0x1, 0xca, 0xc4, 0xcd, 0x7d, 0x6a,
0xb8, 0x47, 0x42, 0x74, 0x25,
0x4c, 0xc7, 0x5d, 0x28, 0xf, 0x1, 0x18, 0x1a, 0x9, 0xf7, 0x71, 0x65, 0xc2,
0x71, 0x97, 0xb0, 0xc2,
0xda, 0x12, 0x80, 0x31, 0xe8, 0x11, 0x30, 0x80, 0x9d, 0x97, 0x9e, 0x3a,
0x2f, 0x9a, 0x30, 0x54, 0xd,
0xc7, 0xf0, 0x66, 0xcb, 0x8f, 0xb6, 0x40, 0x56, 0x89, 0x5b, 0x1c, 0x12,
0xf8, 0xa1, 0x7e, 0x21,
0xca, 0x66, 0x18, 0x89, 0xff, 0x7d, 0x73, 0xa2, 0x7d, 0xee, 0xd0, 0x84,
0x2, 0x2d, 0x1, 0x41, 0x62,
0x55, 0x13, 0x4, 0xc8, 0x18, 0x9, 0x53, 0x3, 0xb8, 0x63, 0x8e, 0x2a, 0x9,
0x0, 0x50, 0x8, 0x3, 0xa5,
0xa1, 0xc6, 0x9f, 0x7c, 0x9d, 0xbc, 0x38, 0x24, 0x8a, 0xea, 0x6c, 0x54,
0x2, 0x88, 0x24, 0x88, 0xf8,
0x1e, 0x93, 0x63, 0xe9, 0x77, 0xc, 0x0, 0x9, 0x24, 0xb0, 0x40, 0x3, 0x99,
0xe5, 0xc5, 0x51, 0x7b,
0xfa, 0x3c, 0xc3, 0xc4, 0x82, 0x5a, 0x26, 0xc2, 0xa5, 0x97, 0x92, 0x7d,
0x60, 0x40, 0x39, 0x39,
0x8a, 0x30, 0x8, 0x8f, 0xb1, 0xe4, 0x29, 0xa9, 0xa4, 0x11, 0xad, 0xc9,
0xa6, 0x46, 0x6f, 0x22, 0x19,
0xa7, 0x92, 0xd4, 0xd1, 0xd9, 0x9a, 0x89, 0x91, 0xa4, 0x72, 0xe1, 0x88,
0xf8, 0x39, 0x91, 0x65,
0xa1, 0x9c, 0x9c, 0xf7, 0x41, 0x97, 0x10, 0xf0, 0xf3, 0x1, 0x2f, 0x6a,
0x5c, 0xf8, 0x28, 0xd, 0x19,
0x6a, 0x95, 0x63, 0x91, 0x6e, 0x8a, 0x0, 0xe7, 0x8, 0x72, 0x92, 0x50,
0xdd, 0x4d, 0x44, 0x61, 0xf5,
0x81, 0x97, 0x59, 0xad, 0x90, 0x19, 0x6e, 0x49, 0x7c, 0x87, 0xea, 0x3e,
0x79, 0x2e, 0xa8, 0x2a,
0x30, 0x8b, 0x2a, 0x92, 0xeb, 0xa6, 0x9c, 0xfe, 0xc2, 0x50, 0x2b, 0x7d,
0x8d, 0x1e, 0x50, 0x9c,
0xae, 0x9a, 0xf2, 0x5a, 0xed, 0x9c, 0xfe, 0xd5, 0xb9, 0xe2, 0x62, 0x43,
0x35, 0x6a, 0x5c, 0xaf,
0x48, 0x64, 0xa6, 0xa5, 0xab, 0xb3, 0x59, 0x4, 0xc0, 0x1d, 0x88, 0x6e,
0x75, 0xc2, 0x8e, 0xb4, 0x3e,
0x89, 0x2d, 0xa, 0xda, 0x62, 0xfa, 0xc1, 0xae, 0x8e, 0x7e, 0xeb, 0x2b,
0x5e, 0xf, 0x8d, 0xb, 0x9b,
0x3a, 0x82, 0x5a, 0xe7, 0x2f, 0x12, 0xcb, 0x96, 0x69, 0x42, 0x3, 0xa2,
0x84, 0xc1, 0x20, 0x85, 0x23,
0x78, 0x9, 0xb1, 0xb5, 0xf6, 0x2e, 0x69, 0xee, 0x7, 0xf9, 0x2, 0xcc, 0xef,
0x7, 0xe8, 0x46, 0x36,
0xdf, 0xb9, 0x67, 0x96, 0xe5, 0xd2, 0xa9, 0x8b, 0x20, 0x84, 0x1a, 0x14,
0xcb, 0x9a, 0x3c, 0x82,
0xb2, 0xc, 0x26, 0x37, 0x42, 0xc6, 0xd3, 0x52, 0xfc, 0x71, 0xa7, 0x17,
0x37, 0xb3, 0xd4, 0xc6, 0x1d,
0x63, 0xf7, 0x19, 0xb, 0x69, 0x28, 0x2c, 0x32, 0x9, 0x19, 0xef, 0x6c,
0x70, 0xc8, 0x4c, 0xa0, 0xea,
0xb3, 0x9, 0xf1, 0x72, 0x52, 0xec, 0x7, 0xe5, 0x5c, 0x19, 0xc3, 0xb5,
0x16, 0xaf, 0x90, 0x34, 0xb2,
0xde, 0x12, 0x6d, 0x42, 0x47, 0xc1, 0xae, 0xf0, 0x5d, 0xcc, 0xd8, 0x65,
0x45, 0x6c, 0x9d, 0x56,
0x2b, 0x81, 0x6a, 0xcd, 0x31, 0xa6, 0x7a, 0x2, 0xcb, 0x35, 0xa7, 0x0,
0x35, 0xcd, 0x2c, 0xc4, 0x4b,
0x75, 0xbf, 0x61, 0x17, 0xe8, 0x69, 0xa, 0xc3, 0x14, 0xdc, 0xb5, 0x8e,
0xfa, 0x2, 0x1b, 0x37, 0xc2,
0x85, 0xd6, 0x3c, 0xa0, 0x96, 0x6c, 0xad, 0x31, 0xb1, 0x71, 0xc2, 0x32,
0x97, 0xb6, 0x8, 0xb0, 0xbe,
0xcd, 0xf1, 0xc1, 0x23, 0xc, 0xa8, 0x22, 0x7d, 0x42, 0xff, 0x6c, 0x2,
0xc1, 0x43, 0xa3, 0x5c, 0xe8,
0xd2, 0x2b, 0xa3, 0x8a, 0x2, 0x87, 0xf, 0x28, 0xfe, 0x81, 0x30, 0xfe,
0x85, 0x8b, 0x76, 0xb8, 0x50,
0x6b, 0x28, 0x9e, 0xb3, 0x8, 0x51, 0x39, 0x30, 0x2a, 0xc6, 0x6a, 0xd8,
0x7d, 0xb7, 0x9, 0x24, 0x77,
0xb, 0x37, 0x14, 0x84, 0x2a, 0xbd, 0x3a, 0xd3, 0x9a, 0x6f, 0x8e, 0x23,
0xa, 0x8, 0xc, 0x13, 0x53,
0x8f, 0x40, 0x6, 0x3f, 0x95, 0xa5, 0x2d, 0x58, 0x64, 0x3a, 0xe3, 0x23,
0x70, 0x9e, 0xe3, 0x21, 0x0,
0x9f, 0xb0, 0xf6, 0xdf, 0x8f, 0xef, 0x7, 0x45, 0xd9, 0x5b, 0xa9, 0x92,
0x47, 0x51, 0x46, 0xab, 0x30,
0x0, 0xac, 0x74, 0x48, 0xba, 0x20, 0x0, 0x10, 0x1f, 0x97, 0xe6, 0xbf,
0xa3, 0x8f, 0x70, 0x9b, 0xde,
0x2e, 0x10, 0xa0, 0xae, 0x1c, 0x7b, 0x66, 0x76, 0xf1, 0xda, 0xaf, 0x96,
0x1a, 0xdb, 0xde, 0x47,
0xc4, 0x3e, 0xde, 0x0, 0x4, 0xd8, 0xc3, 0x75, 0xd2, 0x9d, 0x78, 0x78,
0xc2, 0x0, 0xa, 0x10, 0x8f,
0x39, 0x18, 0x60, 0xb7, 0xfc, 0x5d, 0x83, 0x1a, 0x82, 0x9a, 0x86, 0xeb,
0x52, 0xe0, 0x1c, 0xc5,
0x25, 0x3, 0x6, 0x7, 0x80, 0xd5, 0x1a, 0x0, 0xa0, 0x80, 0xdb, 0x19, 0xd0,
0x65, 0x26, 0x68, 0x89,
0x1c, 0x54, 0x51, 0x21, 0x39, 0x44, 0xa1, 0x76, 0x8b, 0x50, 0x5, 0xfe,
0xbe, 0xa7, 0x0, 0x5b, 0xc0,
0x65, 0x59, 0x10, 0xe0, 0x20, 0x86, 0x80, 0x74, 0xbb, 0x22, 0xb4, 0xd0,
0x6, 0x3, 0x0, 0x12, 0x1f,
0x72, 0x20, 0x3e, 0x4f, 0xc4, 0xf0, 0x24, 0x4c, 0x99, 0x7, 0xa, 0x13,
0xf1, 0xc2, 0x19, 0xfa, 0x70,
0xa, 0x54, 0x12, 0xa1, 0x65, 0x1a, 0xa6, 0x2e, 0x14, 0x72, 0xed, 0x87,
0x48, 0xbc, 0x2, 0x2a, 0x9a,
0x82, 0xa7, 0x1b, 0xcd, 0x44, 0x14, 0xc1, 0x41, 0xd5, 0x85, 0x6a, 0xb8,
0xc3, 0x2a, 0x5a, 0xf1,
0x8a, 0x58, 0xcc, 0xa2, 0x16, 0xe9, 0x87, 0x4, 0x60, 0xf0, 0xc2, 0x46,
0x11, 0x52, 0xfe, 0x55, 0x14,
0x19, 0xf4, 0xbe, 0xe0, 0x99, 0xf1, 0x8c, 0x68, 0x4c, 0xa3, 0x1a, 0xd7,
0xc8, 0xc6, 0x36, 0xba,
0xf1, 0x8d, 0x70, 0x8c, 0xa3, 0x2d, 0xa4, 0x70, 0x80, 0x4, 0x10, 0x0,
0x51, 0x6d, 0x40, 0x94, 0xaa,
0x22, 0xd4, 0x89, 0xa3, 0x25, 0xf1, 0x8f, 0x54, 0x8, 0xc9, 0x22, 0xe,
0xc0, 0xaa, 0x9, 0x12, 0x52,
0x8f, 0x64, 0xe0, 0x63, 0x22, 0xfc, 0x8, 0xc8, 0x46, 0x42, 0xa1, 0x90,
0xb1, 0x20, 0x24, 0xac, 0xc6,
0x0, 0x49, 0x36, 0x24, 0xd2, 0x32, 0xb1, 0x68, 0xe1, 0x2, 0x0, 0xe0, 0x80,
0x5, 0x4e, 0xe3, 0x1,
0x0, 0x60, 0xc0, 0xe0, 0x74, 0x95, 0x8c, 0x82, 0x4d, 0xe3, 0x81, 0x24,
0x40, 0x80, 0xa, 0x1b, 0xc0,
0x8e, 0x3a, 0x3a, 0x8f, 0x3c, 0x67, 0x4b, 0x6, 0x6, 0x45, 0x60, 0x40,
0x39, 0xa8, 0xcc, 0x38, 0xc,
0x0, 0x0, 0x2a, 0x16, 0xd8, 0xc, 0x41, 0x0, 0xa0, 0x11, 0x27, 0xc8, 0x5f,
0xf8, 0xfe, 0x0, 0x12,
0x3c, 0x2, 0x82, 0x50, 0xe0, 0xab, 0x64, 0x1e, 0x7, 0xc1, 0xc8, 0x12,
0x20, 0xa0, 0x34, 0x59, 0x4a,
0xd0, 0x2, 0x1c, 0x10, 0x9f, 0x3, 0x30, 0x82, 0x30, 0x3f, 0x82, 0x4c, 0xc,
0x1d, 0xb0, 0x0, 0x0,
0x7d, 0x46, 0x5b, 0x1c, 0x4, 0x5f, 0x85, 0x1c, 0x80, 0xb9, 0x54, 0xd4,
0xa3, 0x58, 0x5, 0xf0, 0x91,
0xe7, 0xde, 0x73, 0xe, 0x11, 0x54, 0xc4, 0x7f, 0x1f, 0x20, 0xa7, 0x23,
0x7a, 0x67, 0xb7, 0x2, 0x80,
0xf2, 0x48, 0xe5, 0x2b, 0x42, 0xfe, 0x6, 0x31, 0x6, 0x1d, 0x36, 0xc8,
0x9f, 0x94, 0x64, 0xc5, 0x11,
0x5, 0x4, 0x80, 0x51, 0x59, 0xb3, 0x4, 0xe9, 0x40, 0x8, 0x17, 0x19, 0x76,
0x2, 0x71, 0x6a, 0xd0,
0x18, 0x91, 0x7b, 0x49, 0x40, 0x3a, 0x57, 0xa1, 0x49, 0x40, 0x62, 0x45,
0x98, 0x53, 0x41, 0xfe,
0x96, 0xfa, 0x81, 0x9b, 0x38, 0x7c, 0xc3, 0x69, 0x2f, 0x91, 0xc3, 0x25,
0xec, 0xe9, 0x80, 0x7c,
0x1a, 0xc1, 0x9f, 0x3e, 0x22, 0x54, 0x2e, 0xfc, 0xd9, 0x80, 0x5b, 0x52,
0x47, 0xc, 0x39, 0x82, 0xc3,
0xc2, 0x72, 0xe4, 0x9, 0x91, 0x56, 0xa8, 0x51, 0x8, 0x70, 0x5, 0x4, 0xb2,
0x34, 0xac, 0x46, 0x31,
0x34, 0x1, 0x4b, 0xcb, 0x5, 0x1, 0xe, 0x40, 0xce, 0x15, 0x85, 0xa3, 0xa5,
0x2e, 0x98, 0x6, 0x34,
0x68, 0xa, 0xa0, 0x5c, 0x7c, 0xe6, 0xf, 0xc, 0xb5, 0x2, 0x4b, 0x6d, 0xb1,
0xbe, 0x91, 0x78, 0xa4,
0x2f, 0x14, 0x4d, 0xa5, 0x1f, 0xc5, 0x19, 0x22, 0xc1, 0x98, 0x6b, 0x35,
0xa5, 0x61, 0x40, 0x46,
0x12, 0x4, 0x9, 0x72, 0xea, 0x3, 0x37, 0xb9, 0xd0, 0xd6, 0x11, 0x3, 0xa1,
0x1c, 0x90, 0x4e, 0x9,
0x83, 0xb0, 0x80, 0xc, 0x5b, 0xff, 0x10, 0x86, 0x7d, 0x99, 0x34, 0x9,
0x53, 0xd, 0x4e, 0x4b, 0x4b,
0x12, 0x3, 0x3a, 0xa0, 0xe, 0x37, 0xd7, 0x8c, 0x18, 0x23, 0x17, 0x6a,
0xae, 0x5, 0x3c, 0xc0, 0x7a,
0xf, 0x80, 0x67, 0x54, 0x7b, 0xb9, 0xb0, 0x42, 0x4, 0xf0, 0x95, 0xda,
0x33, 0x19, 0x37, 0x7d, 0xe5,
0x3f, 0x48, 0x8, 0x6a, 0xb2, 0xdf, 0xf8, 0x44, 0x18, 0x88, 0xb9, 0x58,
0x2c, 0xe8, 0xb5, 0x0, 0x77,
0x99, 0x65, 0xb, 0xec, 0xc9, 0x27, 0x46, 0xe6, 0xf, 0x0, 0x72, 0x8, 0xac,
0x74, 0xbc, 0x7a, 0x2e,
0x76, 0xbc, 0xc3, 0xa8, 0xb6, 0x89, 0x8, 0x2c, 0xe7, 0x60, 0xd4, 0x64,
0x20, 0x4, 0xa8, 0x45, 0x9,
0x7, 0x6a, 0x4d, 0x16, 0x6, 0x72, 0x92, 0x43, 0xb4, 0x6c, 0xdd, 0xd7,
0x53, 0xef, 0xca, 0x84, 0xe0,
0x30, 0x65, 0x1a, 0xeb, 0x54, 0x41, 0x1, 0x5c, 0x1a, 0x43, 0xc5, 0x79,
0x8e, 0x0, 0xab, 0x2b, 0x5,
0xb2, 0x47, 0xf0, 0x57, 0x2, 0xe8, 0x56, 0x17, 0xc, 0xce, 0xfb, 0xd1,
0xff, 0x5c, 0x1a, 0xa4, 0x15,
0x10, 0x60, 0x8e, 0xc, 0x14, 0xc1, 0x0, 0xd8, 0x61, 0x5d, 0x2f, 0x4, 0xc7,
0xa5, 0x8e, 0x4c, 0xaf,
0xf, 0xad, 0xc9, 0x2e, 0xf5, 0xba, 0xf7, 0xbd, 0xf0, 0x8d, 0xaf, 0x7c,
0xe7, 0x4b, 0xdf, 0xfa, 0xda,
0xf7, 0xbe, 0xf8, 0xcd, 0xaf, 0x7e, 0xf7, 0xcb, 0xdf, 0xfe, 0xfa, 0xf7,
0xbf, 0x0, 0xe, 0xb0, 0x80,
0x7, 0xdc, 0x84, 0x10, 0x0, 0x0, 0x3b
};
#define SIZE_hardcodedimage 1987
#endif /* ! HARDCODEDIMAGE_INCLUDED */
--- NEW FILE: screensaver.c ---
/*
* Copyright (c) 2003 Century Software, Inc. All Rights Reserved.
*
* This file is part of the PIXIL Operating Environment
*
* The use, copying and distribution of this file is governed by one
* of two licenses, the PIXIL Commercial License, or the GNU General
* Public License, version 2.
*
* Licensees holding a valid PIXIL Commercial License may use this file
* in accordance with the PIXIL Commercial License Agreement provided
* with the Software. Others are governed under the terms of the GNU
* General Public License version 2.
*
* This file may be distributed and/or modified under the terms of the
* GNU General Public License version 2 as published by the Free
* Software Foundation and appearing in the file LICENSE.GPL included
* in the packaging of this file.
*
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING
* THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE.
*
* RESTRICTED RIGHTS LEGEND
*
* Use, duplication, or disclosure by the government is subject to
* restriction as set forth in paragraph (b)(3)(b) of the Rights in
* Technical Data and Computer Software clause in DAR 7-104.9(a).
*
* See http://www.pixil.org/gpl/ for GPL licensing
* information.
*
* See http://www.pixil.org/license.html or
* email cetsales at centurysoftware.com for information about the PIXIL
* Commercial License Agreement, or if any conditions of this licensing
* are not clear to you.
*/
#include <pixil_config.h>
#include <stdio.h>
#include <nano-X.h>
#include <nxcolors.h>
#include "powerman.h"
static int g_active = 0;
static GR_WINDOW_ID swindow = 0;
static void draw_screensaver(void) {
GR_SCREEN_INFO si;
GR_GC_ID gc = GrNewGC();
GrGetScreenInfo(&si);
GrSetGCForeground(gc, GR_COLOR_BLACK);
GrFillRect(swindow, gc, 0, 0, si.cols, si.rows);
GrDestroyGC(gc);
}
static int handle_screensaver(void) {
GR_EVENT event;
GrGetNextEvent(&event);
switch(event.type) {
case GR_EVENT_TYPE_EXPOSURE:
if (event.exposure.wid == swindow) draw_screensaver();
break;
case GR_EVENT_TYPE_SCREENSAVER:
if (!event.screensaver.activate) return 1;
}
return 0;
}
/* Why make a window and raise it - it was either that or copy off
the root window, suspend all updates, and blank it. I just think
this was an easier way to go about it.
*/
static void do_screensaver(void) {
GR_SCREEN_INFO si;
GrGetScreenInfo(&si);
if (!swindow)
swindow = GrNewWindowEx(GR_WM_PROPS_NODECORATE, 0,
GR_ROOT_WINDOW_ID, 0, 0, si.cols, si.rows,
GR_COLOR_BLACK);
GrSelectEvents(swindow, GR_EVENT_MASK_EXPOSURE | GR_EVENT_MASK_SCREENSAVER);
/* Turn off the backlight if we can */
pm_backlight(0);
GrRaiseWindow(swindow); /* Raise it to the top */
GrMapWindow(swindow);
while(!handle_screensaver());
GrUnmapWindow(swindow);
/* Turn back on the backlight */
pm_backlight(1);
}
void screensaver_init(void) {
#ifdef CONFIG_PIXILWM_PM
pm_init(); /* Do the power management bit */
#else
GrSetScreenSaverTimeout(30); /* Set the screensaver timeout */
#endif
}
int screensaver_active(void) { return g_active; }
void screensaver_enable(void) {
if (g_active) return;
#ifdef CONFIG_PIXILWM_PM
pm_bltimer_off();
g_active = 1;
#else
do_screensaver();
#endif
}
void screensaver_disable(void) {
if (!g_active) return;
#ifdef CONFIG_PIXILWM_PM
pm_bltimer_on();
g_active = 0;
#endif
}
/* Ugly, I know - but this is the best way to do this, I think */
#ifndef CONFIG_PIXILWM_PM
#include <pixlib/pixlib.h>
void pm_backlight(int mode) {
/* FIXME: We need a get current level */
int max = pix_bl_getmxval();
if (max == -1) return;
if (mode)
pix_bl_ctrl(mode, 0);
else
pix_bl_ctrl(mode, max);
}
#endif
--- NEW FILE: Makefile ---
#nanox/pixilwm/Makefile
CFLAGS ?=
CFLAGS += -DVIRTUAL_WINDOWS
INCLUDES += -I$(BASE_DIR)/sys/pixilwm
INSTALL_SODIR=$(INSTALL_DIR)/share/pixilwm
TARGET=pixilwm
# These are extra targets that are defined locally
TARGET_EXTRAS += applets/date.so
ifeq ($(CONFIG_PIXILWM_PM),y)
TARGET_EXTRAS += applets/backlight.so
TARGET_EXTRAS += applets/battery.so
endif
INSTALL_EXTRAS=inst_applets
ifeq ($(CONFIG_PIXILWM_THEMES),y)
INSTALL_EXTRAS += inst_themes
endif
OBJS-y = applets.o main.o wlist.o config.o clients.o container.o
OBJS-y += inputs.o apps.o home.o root.o categories.o exec.o
OBJS-y += icons.o screensaver.o
OBJS-$(CONFIG_COLOSSEUM) += ipc.o
OBJS-$(CONFIG_PIXILWM_PM) += powerman.o
OBJS-$(CONFIG_PIXILWM_THEMES) += themes.o themesconfig.o
OBJS-$(CONFIG_PIXILWM_MENUS) += sys_menu.o
OBJS := $(OBJS-y)
LIBS+= -lwm -lpixil -lnano-X
ifeq ($(CONFIG_PIXILWM_THEMES),y)
LIBS += -lxml
endif
ifeq ($(CONFIG_COLOSSEUM),y)
LIBS+=-lipc
endif
ifeq ($(CONFIG_PAR), y)
LIBS+=-lpar
endif
LIBS+=-ldl
BUILD_CFLAGS=-rdynamic
CLEAN_EXTRAS=clean_themes
include $(BASE_DIR)/Rules.make
clean_themes:
rm -rf applets/*.o
rm -rf applets/*.so
inst_themes:
mkdir -p $(INSTALL_DIR)/share/themes
cp -r themes/pixil $(INSTALL_DIR)/share/themes
inst_applets:
mkdir -p $(INSTALL_DIR)/share/pixilwm
cp applets/*.so $(INSTALL_DIR)/share/pixilwm
applets/backlight.so: applets/backlight.o
$(CC) -shared -o $@ $<
applets/battery.so: applets/battery.o
$(CC) -shared -o $@ $<
applets/date.so: applets/date.o
$(CC) -shared -o $@ $<
--- NEW FILE: keyb.c ---
/*
* Copyright (c) 2003 Century Software, Inc. All Rights Reserved.
*
* This file is part of the PIXIL Operating Environment
*
* The use, copying and distribution of this file is governed by one
* of two licenses, the PIXIL Commercial License, or the GNU General
* Public License, version 2.
*
* Licensees holding a valid PIXIL Commercial License may use this file
* in accordance with the PIXIL Commercial License Agreement provided
* with the Software. Others are governed under the terms of the GNU
* General Public License version 2.
*
* This file may be distributed and/or modified under the terms of the
* GNU General Public License version 2 as published by the Free
* Software Foundation and appearing in the file LICENSE.GPL included
* in the packaging of this file.
*
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING
* THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE.
*
* RESTRICTED RIGHTS LEGEND
*
* Use, duplication, or disclosure by the government is subject to
* restriction as set forth in paragraph (b)(3)(b) of the Rights in
* Technical Data and Computer Software clause in DAR 7-104.9(a).
*
* See http://www.pixil.org/gpl/ for GPL licensing
* information.
*
* See http://www.pixil.org/license.html or
* email cetsales at centurysoftware.com for information about the PIXIL
* Commercial License Agreement, or if any conditions of this licensing
* are not clear to you.
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include "nano-X.h"
#include "apps.h"
#include "nanowm.h"
#define APPICON "nxkbd.gif"
static GR_IMAGE_ID imageid;
static GR_BOOL appvisible = 0;
static void keyboard_wndproc(win * window, GR_EVENT * ep);
void
keyboard_create()
{
GR_WINDOW_ID wid;
APP *p;
GR_SCREEN_INFO si;
GrGetScreenInfo(&si);
wid = GrNewWindowEx(GR_WM_PROPS_NODECORATE, NULL, GR_ROOT_WINDOW_ID,
si.ws_width - 40, si.ws_height + 2, 20, 20,
COLOR_TASKBAR);
add_window(wid, GR_ROOT_WINDOW_ID, 0, keyboard_wndproc);
p = find_app_flags(FL_KEYBOARD);
if (p)
p->m_icon_wid = wid;
GrSelectEvents(wid, GR_EVENT_MASK_BUTTON_DOWN | GR_EVENT_MASK_EXPOSURE);
GrMapWindow(wid);
}
static void
keyboard_exposure(win * window, GR_EVENT_EXPOSURE * ep)
{
GR_GC_ID gc = GrNewGC();
if (!imageid) {
char path[256];
sprintf(path, "%s/%s", get_desktop_config(DESKTOP_IMAGEDIR), APPICON);
imageid = GrLoadImageFromFile(path, 0);
}
GrDrawImageToFit(ep->wid, gc, 0, 0, -1, -1, imageid);
GrDestroyGC(gc);
}
static void
keyboard_buttondown(win * window, GR_EVENT_BUTTON * ep)
{
APP *p = find_app_flags(FL_KEYBOARD);
if (!p) {
printf("Unable to find the scribble app!\n");
return;
}
if (is_app_running(p)) {
if (appvisible) {
hide_application(p);
appvisible = 0;
} else {
show_application(p);
appvisible = 1;
}
} else {
launch_application(p);
appvisible = 1;
}
}
#ifdef NOTUSED
static void
keyboard_buttondown(win * window, GR_EVENT_BUTTON * ep)
{
char *kbdArgv[4] = { 0 }; /* Arg vector */
static char kymap[256] = { 0 }, /* Path to the keymap files */
kyword[32] =
{
0}; /* Keyboard keyword */
APP *p = find_app_flags(FL_KEYBOARD);
GR_SCREEN_INFO si; /* Screen info */
GrGetScreenInfo(&si);
if (!p)
return;
if (p->m_process_id && p->m_container_wid) {
appvisible = !appvisible;
if (appvisible) {
GrMapWindow(p->m_container_wid);
GrRaiseWindow(p->m_container_wid);
} else {
GrUnmapWindow(p->m_container_wid);
}
} else if (!(p->m_process_id = fork())) {
printf("execing %s\n", p->m_exec);
/* Set up the keyboard environment for execvp */
if (!kymap[0] && !kyword[0]) {
char cfgpath[255] = { '\0' }; /* Config path */
sprintf(cfgpath, "%s", nxGetConfigFile(NX_CONFIG_MAIN));
/* Get the path to the keymap files */
IniGetString("nxkeyboard", "kymap", "", kymap, sizeof(kymap),
cfgpath);
IniGetString("nxkeyboard", "kybsize", "", kyword, sizeof(kyword),
cfgpath);
if (kymap[0] > ' ') {
memset(cfgpath, 0, sizeof(cfgpath));
desktop_expand_path(kymap, cfgpath, sizeof(cfgpath));
memcpy(kymap, cfgpath, strlen(cfgpath));
} /* end of if */
else {
/* Get the default path */
sprintf(kymap, "%s", get_desktop_config(DESKTOP_NXAPPDIR));
printf("set kymap to %s\n", kymap);
} /* end of else */
/* Get the mapset/size variable from the config */
if (kyword[0] < ' ') {
printf("kyword not found\n");
/* Use the defaults */
printf("Cols=%d Rows=%d\n", si.cols, si.rows);
if (si.rows <= 240)
sprintf(kyword, "sml");
else if (si.rows <= 480)
sprintf(kyword, "mid");
else
sprintf(kyword, "big");
printf("kyword set to %s\n", kyword);
} /* end of if */
}
/* end of if */
/* Put the name of the executable in kbdArgv[0] */
if ((kbdArgv[0] =
(char *) calloc(sizeof(char), strlen(p->m_exec) + 1)) == NULL
|| memcpy(kbdArgv[0], p->m_exec, strlen(p->m_exec)) == NULL) {
printf("Error allocating memory for %s\n", p->m_exec);
} /* end of if */
else if ((kbdArgv[1] =
(char *) calloc(sizeof(char),
strlen(kymap) + 1 + 3)) == NULL
|| !sprintf(kbdArgv[1], "-d%s", kymap)) {
printf("Error allocating memory for %s %s\n", p->m_exec, kymap);
} /* end of else-if */
else if ((kbdArgv[2] =
(char *) calloc(sizeof(char),
strlen(kyword) + 1 + 3)) == NULL
|| !sprintf(kbdArgv[2], "-m%s", kyword)) {
printf("Error allocating memory for %s %s -k %s\n", p->m_exec,
kymap, kyword);
} /* end of else-if */
else {
int i = 0;
while (kbdArgv[i]) {
printf("kbdArgv[%d]=%s\n", i, kbdArgv[i]);
i++;
} /* end of while */
execvp(p->m_exec, kbdArgv);
} /* end of else */
exit(0);
} else {
g_last_window = p->m_icon_wid;
LastLaunchedApp = p;
appvisible = 1;
}
}
#endif
static void
keyboard_wndproc(win * window, GR_EVENT * ep)
{
switch (ep->type) {
case GR_EVENT_TYPE_EXPOSURE:
keyboard_exposure(window, &ep->exposure);
break;
case GR_EVENT_TYPE_BUTTON_DOWN:
keyboard_buttondown(window, &ep->button);
break;
}
}
--- NEW FILE: exec.c ---
/*
* Copyright (c) 2003 Century Software, Inc. All Rights Reserved.
*
* This file is part of the PIXIL Operating Environment
*
* The use, copying and distribution of this file is governed by one
* of two licenses, the PIXIL Commercial License, or the GNU General
* Public License, version 2.
*
* Licensees holding a valid PIXIL Commercial License may use this file
* in accordance with the PIXIL Commercial License Agreement provided
* with the Software. Others are governed under the terms of the GNU
* General Public License version 2.
*
* This file may be distributed and/or modified under the terms of the
* GNU General Public License version 2 as published by the Free
* Software Foundation and appearing in the file LICENSE.GPL included
* in the packaging of this file.
*
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING
* THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE.
*
* RESTRICTED RIGHTS LEGEND
*
* Use, duplication, or disclosure by the government is subject to
* restriction as set forth in paragraph (b)(3)(b) of the Rights in
* Technical Data and Computer Software clause in DAR 7-104.9(a).
*
* See http://www.pixil.org/gpl/ for GPL licensing
* information.
*
* See http://www.pixil.org/license.html or
* email cetsales at centurysoftware.com for information about the PIXIL
* Commercial License Agreement, or if any conditions of this licensing
* are not clear to you.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <signal.h>
#include <sys/wait.h>
#include <sys/types.h>
#include "apps.h"
#include "nanowm.h"
#define ASSOC_FILE "config.magic"
NXLISTHEAD active_list;
static PROCESS *
find_process(int pid)
{
PNXLIST p = active_list.head;
for (; p; p = p->next) {
PROCESS *process = nxItemAddr(p, PROCESS, next);
if (process->pid == pid)
return (process);
}
return NULL;
}
void
kill_running_processes()
{
PNXLIST p = active_list.head;
while (p) {
PNXLIST n = p->next;
PROCESS *process = nxItemAddr(p, PROCESS, next);
warning("Terminating process %d\n", process->pid);
kill(process->pid, SIGTERM);
p = n;
}
}
static int
local_parseArgs(char *name, char *argstr, char ***argv)
{
char **argvptr = 0;
char *h = argstr;
char *t = 0;
int argc = 1;
int index = 0;
/* If there are arguments, then count them */
if (argstr) {
while ((t = strchr(h, ' '))) {
/* Skip to the next empty space */
for (; *t == ' ' && *t != 0; t++);
if (*t == 0)
break;
argc++;
h = t;
}
}
/* Now, allocate the required room */
*argv = (char **) malloc((argc + 2) * sizeof(char *));
if (!*argv)
return (0);
argvptr = *argv;
/* First step, add the program name */
argvptr[0] = (char *) calloc(1, strlen(name) + 1);
strcpy(argvptr[0], name);
if (!argstr || !strlen(argstr)) {
argvptr[1] = (char *) 0;
return (1);
}
/* Now add any args (if they exist) */
h = argstr;
while (index < argc) {
int slen = 0;
t = strchr(h, ' ');
if (t)
slen = (int) (t - h);
else
slen = strlen(argstr) - (int) (h - argstr);
argvptr[++index] = (char *) calloc(1, slen + 1);
/* If there was an error, skip to the next one */
if (!argvptr[index]) {
index--;
if (!t)
break;
/* Skip to the next word */
for (; *t == ' ' && *t != 0; t++);
if (*t == 0)
break;
h = t;
continue;
}
if (t)
strncpy(argvptr[index], h, slen);
else
strcpy(argvptr[index], h);
if (!t)
break;
/* Skip to the next word */
for (; *t == ' ' && *t != 0; t++);
if (*t == 0)
break;
h = t;
continue;
}
/* Add a null pointer to the end */
argvptr[++index] = (char *) 0;
return (index);
}
static void
local_freeArgs(int argc, char **argv)
{
int i;
for (i = 0; i < argc; i++)
free(argv[i]);
free(argv);
}
void
application_handler(int id)
{
int status;
int ret;
while (1) {
ret = waitpid(-1, &status, WNOHANG);
if (ret == -1 || ret == 0)
break;
else {
PROCESS *proc = find_process(ret);
warning("Process %d died with status %d\n", ret, status);
if (!proc)
return;
if (proc->app) {
proc->app->m_process_id = 0;
proc->app->m_container_wid = 0;
if (proc->app->m_flags & FL_INPUT)
killInput(proc->app);
}
/* Remove it from the active list */
nxListRemove(&active_list, &proc->next);
}
}
}
static int
local_spawn(char *exec, char *argstr, char *workdir)
{
char **argv = 0;
int pid;
int argc = local_parseArgs(exec, argstr, &argv);
if (!argc)
return (-1);
if (!(pid = fork())) {
if (strlen(workdir))
if (chdir(workdir))
error("Unable to switch to working directory '%s'.\n",
workdir);
execvp(exec, argv);
exit(0);
}
local_freeArgs(argc, argv);
if (pid == -1)
error("Unable to fork app: %s\n", strerror(errno));
return (pid);
}
static int
show_window(APP * app)
{
g_last_app = app;
container_activate(app->m_container_wid);
if (isInputVisible() == 0)
inputResetWorkspace();
return (0);
}
int
launch_application(APP * app)
{
int pid;
/* Check to see if we have a container wid */
if (app->m_container_wid)
return (show_window(app));
/* Don't worry about the process list if we are using ipcActive() */
if (ipcActive()) {
pid = ipcSpawnApp(app->m_name, 0);
if (pid < 0) {
error("Problem while spawning '%s' (error code = %d).\n",
app->m_name, pid);
return (-1);
}
app->m_process_id = pid;
} else {
PROCESS *proc = nxItemNew(PROCESS);
pid = local_spawn(app->m_exec, app->m_args, app->m_workdir);
if (pid < 0) {
error("Problem while spawning '%s'.\n", app->m_name, pid);
free(proc);
return (-1);
}
proc->pid = pid;
proc->app = app;
app->m_process_id = pid;
nxListAdd(&active_list, &proc->next);
}
return (0);
}
inline void
hide_application(APP * app)
{
container_hide(app->m_container_wid);
}
void
show_application(APP * app)
{
if (!app || !app->m_container_wid)
return;
container_activate(app->m_container_wid);
}
inline int
is_app_running(APP * app)
{
return (app->m_process_id || app->m_container_wid);
}
/* File association stuff that may be used in the future? */
#ifdef NOTUSED
#define FILE_ASSOC_COUNT 3
typedef struct
{
int active;
int age;
char application[512];
char args[256];
}
file_assoc_cache_t;
file_assoc_cache_t file_assoc_cache[FILE_ASSOC_COUNT];
static int
get_new_cache_entry()
{
int i = 0;
int use_slot = -1;
int oldest_slot = -1;
int oldest_age = 0;
/* Determine a cache location for this entry. */
/* Look for an empty entry and age the other entries at the same time */
for (i = 0; i < FILE_ASSOC_COUNT; i++) {
if (!file_assoc_cache[i].active) {
if (use_slot == -1)
use_slot = i;
} else {
if (++file_assoc_cache[i].age > oldest_age) {
oldest_age = file_assoc_cache[i].age;
oldest_slot = i;
}
}
}
if (use_slot == -1)
use_slot = oldest_slot;
return (use_slot);
}
/* get_file_association()
Search the associations file to see if
an application has been specified for this file
*/
static void
assoc_callback(char *key, char *value, int data)
{
if (!strcmp(key, "app")) {
strcpy(file_assoc_cache[data].application, value);
return;
}
if (!strcmp(key, "args")) {
strcpy(file_assoc_cache[data].args, value);
return;
}
}
/* Stuff for the future? */
int
get_file_association(char *filename, char *type, app_info_t * ainfo)
{
char buf[4096];
int slot;
char *afile;
/* Search for the global configuration file and store the location */
nxLoadConfigFile(ASSOC_FILE, NX_CONFIG_ASSOC);
afile = nxGetConfigFile(NX_CONFIG_ASSOC);
if (!afile) {
printf("Unable to read the file %s\n");
return (-1);
}
slot = get_new_cache_entry();
bzero(&file_assoc_cache[slot], sizeof(file_assoc_cache_t));
file_assoc_cache[slot].active = 1;
if (IniGetString(type, NULL, "", buf, sizeof(buf), afile)) {
IniEnumKeyValues(buf, assoc_callback, slot);
/* Now, construct the app info */
strcpy(ainfo->path, file_assoc_cache[slot].application);
str_replace_variable("$file", filename, file_assoc_cache[slot].args,
ainfo->args, sizeof(ainfo->args));
return (0);
}
return (-1);
}
#endif
--- NEW FILE: categories.h ---
/*
* Copyright (c) 2003 Century Software, Inc. All Rights Reserved.
*
* This file is part of the PIXIL Operating Environment
*
* The use, copying and distribution of this file is governed by one
* of two licenses, the PIXIL Commercial License, or the GNU General
* Public License, version 2.
*
* Licensees holding a valid PIXIL Commercial License may use this file
* in accordance with the PIXIL Commercial License Agreement provided
* with the Software. Others are governed under the terms of the GNU
* General Public License version 2.
*
* This file may be distributed and/or modified under the terms of the
* GNU General Public License version 2 as published by the Free
* Software Foundation and appearing in the file LICENSE.GPL included
* in the packaging of this file.
*
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING
* THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE.
*
* RESTRICTED RIGHTS LEGEND
*
* Use, duplication, or disclosure by the government is subject to
* restriction as set forth in paragraph (b)(3)(b) of the Rights in
* Technical Data and Computer Software clause in DAR 7-104.9(a).
*
* See http://www.pixil.org/gpl/ for GPL licensing
* information.
*
* See http://www.pixil.org/license.html or
* email cetsales at centurysoftware.com for information about the PIXIL
* Commercial License Agreement, or if any conditions of this licensing
* are not clear to you.
*/
#ifndef CATAGORIES_H
#define CATAGORIES_H
typedef struct category_struct
{
char *title;
int index;
int count;
APP **apps;
struct category_struct *next;
struct category_struct *prev;
}
category_t;
/* categories.c */
void nxFreeCategories(void);
int nxLoadCategories(db_handle * db);
int category_getCurrentWin(void);
int category_getCount();
int switchCategory(int index);
category_t *category_getCurrent(void);
int category_setCurrent(int index);
void create_categoryBrowser(void);
void draw_categoryBrowser(GR_REGION_ID r);
#endif
--- NEW FILE: nanowm.h ---
/*
* Copyright (c) 2003 Century Software, Inc. All Rights Reserved.
*
* This file is part of the PIXIL Operating Environment
*
* The use, copying and distribution of this file is governed by one
* of two licenses, the PIXIL Commercial License, or the GNU General
* Public License, version 2.
*
* Licensees holding a valid PIXIL Commercial License may use this file
* in accordance with the PIXIL Commercial License Agreement provided
* with the Software. Others are governed under the terms of the GNU
* General Public License version 2.
*
* This file may be distributed and/or modified under the terms of the
* GNU General Public License version 2 as published by the Free
* Software Foundation and appearing in the file LICENSE.GPL included
* in the packaging of this file.
*
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING
* THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE.
*
* RESTRICTED RIGHTS LEGEND
*
* Use, duplication, or disclosure by the government is subject to
* restriction as set forth in paragraph (b)(3)(b) of the Rights in
* Technical Data and Computer Software clause in DAR 7-104.9(a).
*
* See http://www.pixil.org/gpl/ for GPL licensing
* information.
*
* See http://www.pixil.org/license.html or
* email cetsales at centurysoftware.com for information about the PIXIL
* Commercial License Agreement, or if any conditions of this licensing
* are not clear to you.
*/
/* Portions Copyright (C) 2000 Alex Holden <alex at linuxhacker.org> */
#ifndef _NANOWM_H_
#define _NANOWM_H_
#include "apps.h"
#include "categories.h"
#include "sys_menu.h"
#ifdef DEBUG
#define Dprintf printf
#else
#define Dprintf(ignore...)
#endif
#include <par/pardb.h>
typedef struct windowlist *winptr;
typedef void (*wndproc) (struct windowlist * window, GR_EVENT * ep);
struct pos_size
{
GR_COORD xoff;
GR_COORD yoff;
GR_COORD xorig;
GR_COORD yorig;
GR_SIZE width;
GR_SIZE height;
};
/* all root-mapped windows are kept track of with this structure*/
struct windowlist
{
GR_WINDOW_ID wid; /* The ID of this window */
GR_WINDOW_ID pid; /* The ID of this window's parent */
GR_WINDOW_ID clientid; /* clientid for container window */
GR_BOOL mousedn; /* TRUE when mouse is down in window */
GR_COORD x; /* mouse down coordinates */
GR_COORD y;
wndproc proc; /* callback associated with window */
struct windowlist *next; /* The next window in the list */
int sizing; /* used during resize handling */
struct pos_size pos; /* used during resize/move handling */
struct
{
struct windowlist *next;
struct windowlist *prev;
}
zorder;
};
typedef struct windowlist win;
/* LOGGING MACROS */
#define LOG_ERROR 1
#define LOG_WARNING 2
#define LOG_DEBUG 3
void scrtop_log_message(int level, char *fmt, ...);
#define debug(fmt, args...) scrtop_log_message(LOG_DEBUG, fmt, ## args)
#define warning(fmt, args...) scrtop_log_message(LOG_WARNING, fmt, ## args)
#define error(fmt, args...) scrtop_log_message(LOG_ERROR, fmt, ## args)
/* wlist.c*/
win *find_window(GR_WINDOW_ID wid);
win *add_window(GR_WINDOW_ID wid, GR_WINDOW_ID pid, GR_WINDOW_ID clid,
wndproc proc);
int remove_window(win * window);
int remove_window_and_children(win * window);
void resize_windows(int width, int height);
int zorder_push(GR_WINDOW_ID id);
GR_WINDOW_ID zorder_peek_top(void);
void zorder_remove(GR_WINDOW_ID id);
void zorder_raise(GR_WINDOW_ID id);
/* main.c*/
typedef void (*scrtop_timer_cb)(void);
void scrtop_register_timer(GR_TIMER_ID id, void (*callback)(void));
void scrtop_unregister_timer(GR_TIMER_ID id);
void timeout_setproc(wndproc proc, win * window);
/* categories.c */
wm_menu_t *create_categoryMenu(int index, char *name);
/* container.c*/
void container_wndproc(win * window, GR_EVENT * ep);
void container_activate(GR_WINDOW_ID wid);
void container_hide(GR_WINDOW_ID wid);
/* clients.c*/
int client_updatemap_new(GR_WINDOW_ID wid);
void setWorkspace(int width, int height);
void getWorkspace(int *width, int *height);
/* apps.c */
void apps_free_memory();
/* root.c */
void root_free_memory();
inline void redraw_root_window();
/* icons.c */
void hide_icon_list(void);
void draw_current_iconlist(GR_REGION_ID r);
GR_WINDOW_ID create_icon_window();
GR_IMAGE_ID loadIconImage(char *filename, char *app, int useDefault);
/* inputs.c */
int nxLoadInputs(db_handle * db);
void createInputButton(void);
/* settings.c */
int nxLoadConfig(void);
/* ipc.c */
void startIPC(void);
void handleIPC(GR_EVENT_FDINPUT * e);
int ipcSpawnApp(char *app, char *str);
int ipcActive(void);
int ipcGetAppName(int processid, char *name, int size);
/* input.c */
void inputResetWorkspace(void);
void hideInputs(void);
int isInputVisible(void);
#endif
--- NEW FILE: clients.c ---
/*
* Copyright (c) 2003 Century Software, Inc. All Rights Reserved.
*
* This file is part of the PIXIL Operating Environment
*
* The use, copying and distribution of this file is governed by one
* of two licenses, the PIXIL Commercial License, or the GNU General
* Public License, version 2.
*
* Licensees holding a valid PIXIL Commercial License may use this file
* in accordance with the PIXIL Commercial License Agreement provided
* with the Software. Others are governed under the terms of the GNU
* General Public License version 2.
*
* This file may be distributed and/or modified under the terms of the
* GNU General Public License version 2 as published by the Free
* Software Foundation and appearing in the file LICENSE.GPL included
* in the packaging of this file.
*
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING
* THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE.
*
* RESTRICTED RIGHTS LEGEND
*
* Use, duplication, or disclosure by the government is subject to
* restriction as set forth in paragraph (b)(3)(b) of the Rights in
* Technical Data and Computer Software clause in DAR 7-104.9(a).
*
* See http://www.pixil.org/gpl/ for GPL licensing
* information.
*
* See http://www.pixil.org/license.html or
* email cetsales at centurysoftware.com for information about the PIXIL
* Commercial License Agreement, or if any conditions of this licensing
* are not clear to you.
*/
/* Portions copyright (C) 2000 Alex Holden <alex at linuxhacker.org> */
#include <pixil_config.h>
#include <stdio.h>
#include <stdlib.h>
#define MWINCLUDECOLORS
#include <nano-X.h>
#include <wm/nxlib.h>
#include "nxdraw.h"
#include "nanowm.h"
#include "apps.h"
#include "categories.h"
#include "themes.h"
/* Where to place the first window on the screen */
#define FIRST_WINDOW_LOCATION 2
/* The distance to leave between windows when deciding where to place */
#define WINDOW_STEP 20
static GR_COORD lastx = FIRST_WINDOW_LOCATION;
static GR_COORD lasty = FIRST_WINDOW_LOCATION;
/* JHC 08/08/01 - Instead of using the previously provided */
/* workspace, we are going to go ahead and use our own variables */
/* so we can increase and shrink it at random */
static int workspaceWidth = 0;
static int workspaceHeight = 0;
void
setWorkspace(int width, int height)
{
workspaceWidth = width;
workspaceHeight = height;
/* Now resize any windows that may be affected */
resize_windows(workspaceWidth, workspaceHeight);
}
void
getWorkspace(int *width, int *height)
{
if (width)
*width = workspaceWidth;
if (height)
*height = workspaceHeight;
}
static void client_wndproc(win * window, GR_EVENT * ep);
/*
* A new client window has been mapped, so we need to reparent and decorate it.
* Returns -1 on failure or 0 on success.
*/
int
client_updatemap_new(GR_WINDOW_ID wid)
{
APP *lapp = 0;
GR_WINDOW_ID pid;
GR_COORD x, y, width, height, xoffset, yoffset;
GR_SIZE w, h;
GR_WM_PROPS style;
GR_WINDOW_INFO winfo;
GR_WM_PROPERTIES props;
static GR_SCREEN_INFO si;
/* get screen/workspace information */
if (!si.rows)
GrGetScreenInfo(&si);
/* get client window information */
GrGetWindowInfo(wid, &winfo);
style = winfo.props;
/* if not redecorating or not child of root window, return */
if (winfo.parent != GR_ROOT_WINDOW_ID || (style & GR_WM_PROPS_NODECORATE))
return 0;
/* deal with replacing borders with window decorations */
if (winfo.bordersize) {
/*
* For complex reasons, it's easier to unmap,
* remove the borders, and then map again,
* rather than try to recalculate the window
* position in the server w/o borders. By
* the time we get this event, the window has
* already been painted with borders...
* This currently causes a screen flicker as
* the window is painted twice. The workaround
* is to create the window without borders in
* the first place.
*/
GrUnmapWindow(wid);
/* remove client borders, if any */
props.flags = style | GR_WM_FLAGS_BORDERSIZE;
props.bordersize = 0;
GrSetWMProperties(wid, &props);
/* remap the window without borders, call this routine again */
GrMapWindow(wid);
return 0;
}
/* if default decoration style asked for, set real draw bits */
if ((style & GR_WM_PROPS_APPMASK) == GR_WM_PROPS_APPWINDOW) {
GR_WM_PROPERTIES pr;
style = (style & ~GR_WM_PROPS_APPMASK) | nxGetDefaultWindowStyle();
/* A quick hack - if NOAUTORESIZE is enabled */
/* then clear the NOMOVE flag */
if (style & GR_WM_PROPS_NOAUTORESIZE)
style &= ~GR_WM_PROPS_NOMOVE;
pr.flags = GR_WM_FLAGS_PROPS;
pr.props = style;
GrSetWMProperties(wid, &pr);
}
#ifdef CONFIG_PIXILWM_THEMES
if (get_activeTheme())
themeContainerSize(get_activeTheme(),
style, winfo.width, winfo.height,
&xoffset, &yoffset, &width, &height);
else
#endif
/* determine container size and client child window offsets */
nxCalcNCSize(style, winfo.width, winfo.height, &xoffset, &yoffset,
&width, &height);
/* determine x,y window location and width,height size */
if ((style & (GR_WM_PROPS_NOAUTORESIZE | GR_WM_PROPS_MAXIMIZE)) ==
GR_WM_PROPS_MAXIMIZE) {
/* force to maximized position */
x = 0;
y = 0;
width = workspaceWidth;
height = workspaceHeight;
} else if (style & GR_WM_PROPS_NOAUTOMOVE) {
x = winfo.x;
y = winfo.y;
} else {
/* We could probably use a more intelligent algorithm here */
x = lastx + WINDOW_STEP;
if ((x + width) > si.ws_width)
x = FIRST_WINDOW_LOCATION;
lastx = x;
y = lasty + WINDOW_STEP;
if ((y + height) > si.ws_height)
y = FIRST_WINDOW_LOCATION;
lasty = y;
}
/* create container window */
pid = GrNewWindow(GR_ROOT_WINDOW_ID, x, y, width, height,
0, LTGRAY, BLACK);
add_window(pid, GR_ROOT_WINDOW_ID, wid, container_wndproc);
/* don't erase background of container window */
props.flags = GR_WM_FLAGS_PROPS;
props.props = style | GR_WM_PROPS_NOBACKGROUND;
GrSetWMProperties(pid, &props);
debug("New client window %d container %d\n", wid, pid);
GrSelectEvents(pid, GR_EVENT_MASK_CHLD_UPDATE | GR_EVENT_MASK_UPDATE
| GR_EVENT_MASK_BUTTON_UP | GR_EVENT_MASK_BUTTON_DOWN
| GR_EVENT_MASK_MOUSE_POSITION | GR_EVENT_MASK_EXPOSURE);
/* reparent client to container window */
/* must map before reparent (nano-X bug) */
GrMapWindow(pid);
GrReparentWindow(wid, pid, xoffset, yoffset);
/* resize client window to container */
#ifdef CONFIG_PIXILWM_THEMES
if (get_activeTheme())
themeClientSize(get_activeTheme(), style, width, height, &w, &h);
else
#endif
nxCalcClientSize(style, width, height, NULL, NULL, &w, &h);
if (w != winfo.width || h != winfo.height)
GrResizeWindow(wid, w, h);
/* Get the application record for the new app */
if (winfo.processid) {
lapp = find_app_pid(winfo.processid);
if (!lapp) {
char name[32] = { 0 };
if (ipcActive()
&& ipcGetAppName(winfo.processid, name, sizeof(name)) == 0)
lapp = find_app_name(name);
}
}
if (lapp) {
lapp->m_container_wid = pid;
if (lapp->m_flags & FL_INPUT)
inputResizeWorkspace(lapp);
lapp->m_virtual_wid = category_getCurrentWin();
/* Record this for future HOME actions */
g_last_app = lapp;
}
#ifdef NOTUSED
if (LastLaunchedApp) {
LastLaunchedApp->m_container_wid = pid;
if (LastLaunchedApp->m_flags & FL_INPUT)
inputResizeWorkspace(LastLaunchedApp);
LastLaunchedApp->m_virtual_wid = category_getCurrentWin();
LastLaunchedApp = NULL;
}
#endif
/*GrMapWindow(pid); */
GrSetFocus(wid); /* force fixed focus */
/* add client window */
add_window(wid, pid, 0, client_wndproc);
/* Push this container window to the very top */
zorder_push(pid);
#ifdef VIRTUAL_WINDOWS
/* Redraw the virtual window switcher to handle the missing window */
/* virtswitch_redraw(); */
#endif
return 0;
}
/*
* We've just received an event notifying us that a client window has been
* unmapped, so we need to destroy all of the decorations.
*/
static void
client_destroy(win * window)
{
APP *app;
win *pwin;
GR_WINDOW_ID pid, zwid;
debug("Client window %d has been destroyed\n", window->wid);
if (!(pwin = find_window(window->pid))) {
error("Couldn't find the parent of window %d.\n", window->wid);
return;
}
pid = pwin->wid;
/* The client just went away, see if we can clear */
/* the outstanding values */
app = find_app_container(pid);
/* If the app exists, then clear the values */
if (app) {
app->m_container_wid = 0;
app->m_process_id = 0;
} else
error("No application was associated with container %d.\n", pid);
/* Remove this window from the zorder */
zorder_remove(pid);
/* Activate the next window in the list */
if ((zwid = zorder_peek_top()))
container_activate(zwid);
/* Remove the entire window from the window list */
remove_window_and_children(pwin);
debug("Destroying container %d\n", pid);
GrDestroyWindow(pid);
}
static void
client_update(win * window, GR_EVENT_UPDATE * ep)
{
switch (ep->utype) {
case GR_UPDATE_DESTROY:
client_destroy(window);
break;
}
}
static void
client_wndproc(win * window, GR_EVENT * ep)
{
switch (ep->type) {
case GR_EVENT_TYPE_CHLD_UPDATE:
client_update(window, &ep->update);
break;
}
}
--- NEW FILE: home.c ---
/*
* Copyright (c) 2003 Century Software, Inc. All Rights Reserved.
*
* This file is part of the PIXIL Operating Environment
*
* The use, copying and distribution of this file is governed by one
* of two licenses, the PIXIL Commercial License, or the GNU General
* Public License, version 2.
*
* Licensees holding a valid PIXIL Commercial License may use this file
* in accordance with the PIXIL Commercial License Agreement provided
* with the Software. Others are governed under the terms of the GNU
* General Public License version 2.
*
* This file may be distributed and/or modified under the terms of the
* GNU General Public License version 2 as published by the Free
* Software Foundation and appearing in the file LICENSE.GPL included
* in the packaging of this file.
*
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING
* THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE.
*
* RESTRICTED RIGHTS LEGEND
*
* Use, duplication, or disclosure by the government is subject to
* restriction as set forth in paragraph (b)(3)(b) of the Rights in
* Technical Data and Computer Software clause in DAR 7-104.9(a).
*
* See http://www.pixil.org/gpl/ for GPL licensing
* information.
*
* See http://www.pixil.org/license.html or
* email cetsales at centurysoftware.com for information about the PIXIL
* Commercial License Agreement, or if any conditions of this licensing
* are not clear to you.
*/
#include <stdio.h>
#include "nano-X.h"
#include "apps.h"
#include "nanowm.h"
#include "categories.h"
#include "config.h"
#define HOMEICON "home.gif"
static GR_BOOL g_clear_window = 0;
static GR_IMAGE_ID imageid;
static void home_wndproc(win * window, GR_EVENT * ep);
void
home_create(void)
{
GR_WINDOW_ID wid;
GR_SCREEN_INFO si;
GrGetScreenInfo(&si);
wid = GrNewWindowEx(GR_WM_PROPS_NODECORATE, NULL, GR_ROOT_WINDOW_ID,
si.ws_width - 62, si.ws_height + 4, 13, 14,
wm_getColor(WM_TASKBAR));
add_window(wid, GR_ROOT_WINDOW_ID, 0, home_wndproc);
GrSelectEvents(wid, GR_EVENT_MASK_BUTTON_DOWN | GR_EVENT_MASK_EXPOSURE);
GrMapWindow(wid);
}
static void
home_exposure(win * window, GR_EVENT_EXPOSURE * ep)
{
GR_GC_ID gc = GrNewGC();
if (!imageid)
imageid = loadIconImage(HOMEICON, 0, 0);
GrDrawImageToFit(ep->wid, gc, 0, 0, -1, -1, imageid);
GrDestroyGC(gc);
}
static void
home_buttondown(win * window, GR_EVENT_BUTTON * ep)
{
if (g_clear_window && g_last_app) {
if (!g_last_app->m_container_wid)
return;
container_activate(g_last_app->m_container_wid);
g_clear_window = 0;
/* Reset the workspace. This is a major hack, but the best we can do */
inputResetWorkspace();
return;
}
/* Make sure we hide all the inputs */
hideInputs();
#ifdef VIRTUAL_WINDOWS
app_hide_windows(category_getCurrentWin());
#else
app_hide_windows();
#endif
g_clear_window = 1;
}
static void
home_wndproc(win * window, GR_EVENT * ep)
{
switch (ep->type) {
case GR_EVENT_TYPE_EXPOSURE:
home_exposure(window, &ep->exposure);
break;
case GR_EVENT_TYPE_BUTTON_DOWN:
home_buttondown(window, &ep->button);
break;
}
}
--- NEW FILE: pwroff.h ---
/*
* Copyright (c) 2003 Century Software, Inc. All Rights Reserved.
*
* This file is part of the PIXIL Operating Environment
*
* The use, copying and distribution of this file is governed by one
* of two licenses, the PIXIL Commercial License, or the GNU General
* Public License, version 2.
*
* Licensees holding a valid PIXIL Commercial License may use this file
* in accordance with the PIXIL Commercial License Agreement provided
* with the Software. Others are governed under the terms of the GNU
* General Public License version 2.
*
* This file may be distributed and/or modified under the terms of the
* GNU General Public License version 2 as published by the Free
* Software Foundation and appearing in the file LICENSE.GPL included
* in the packaging of this file.
*
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING
* THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE.
*
* RESTRICTED RIGHTS LEGEND
*
* Use, duplication, or disclosure by the government is subject to
* restriction as set forth in paragraph (b)(3)(b) of the Rights in
* Technical Data and Computer Software clause in DAR 7-104.9(a).
*
* See http://www.pixil.org/gpl/ for GPL licensing
* information.
*
* See http://www.pixil.org/license.html or
* email cetsales at centurysoftware.com for information about the PIXIL
* Commercial License Agreement, or if any conditions of this licensing
* are not clear to you.
*/
#ifndef _PWROFF_H_
#define _PWROFF_H_
#include <nano-X.h>
#include <pixlib/pixlib.h>
#include <par/par.h>
#define DISABLED 0x00
#define AC_ON 0x01
#define BAT_ON 0x02
#define BL_OFF 0X00
#define BL_ON 0x01
extern void change_bl_state(int final_result);
void suspend_nxscrtop(int id);
void resume_nxscrtop(int id);
/* Power Backlight timer prototypes */
void startBlTimer(void);
void controlBl(int state);
void suspendPwr(void);
void stopPwrTimer(void);
#endif /* _PWROFF_H_ */
--- NEW FILE: scrib.c ---
/*
* Copyright (c) 2003 Century Software, Inc. All Rights Reserved.
*
* This file is part of the PIXIL Operating Environment
*
* The use, copying and distribution of this file is governed by one
* of two licenses, the PIXIL Commercial License, or the GNU General
* Public License, version 2.
*
* Licensees holding a valid PIXIL Commercial License may use this file
* in accordance with the PIXIL Commercial License Agreement provided
* with the Software. Others are governed under the terms of the GNU
* General Public License version 2.
*
* This file may be distributed and/or modified under the terms of the
* GNU General Public License version 2 as published by the Free
* Software Foundation and appearing in the file LICENSE.GPL included
* in the packaging of this file.
*
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING
* THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE.
*
* RESTRICTED RIGHTS LEGEND
*
* Use, duplication, or disclosure by the government is subject to
* restriction as set forth in paragraph (b)(3)(b) of the Rights in
* Technical Data and Computer Software clause in DAR 7-104.9(a).
*
* See http://www.pixil.org/gpl/ for GPL licensing
* information.
*
* See http://www.pixil.org/license.html or
* email cetsales at centurysoftware.com for information about the PIXIL
* Commercial License Agreement, or if any conditions of this licensing
* are not clear to you.
*/
#include <stdio.h>
#include <unistd.h>
#include "nano-X.h"
#include "apps.h"
#include "nanowm.h"
#define APPICON "nxscribble.gif"
static GR_IMAGE_ID imageid;
static int appvisible = 0;
static void scribble_wndproc(win * window, GR_EVENT * ep);
void
scribble_create(void)
{
GR_WINDOW_ID wid;
APP *p;
GR_SCREEN_INFO si;
GrGetScreenInfo(&si);
wid = GrNewWindowEx(GR_WM_PROPS_NODECORATE, NULL, GR_ROOT_WINDOW_ID,
si.ws_width - 20, si.ws_height + 2, 20, 20,
COLOR_TASKBAR);
add_window(wid, GR_ROOT_WINDOW_ID, 0, scribble_wndproc);
p = find_app_flags(FL_SCRIBBLE);
if (p)
p->m_icon_wid = wid;
GrSelectEvents(wid, GR_EVENT_MASK_BUTTON_DOWN | GR_EVENT_MASK_EXPOSURE);
GrMapWindow(wid);
}
static void
scribble_exposure(win * window, GR_EVENT_EXPOSURE * ep)
{
GR_GC_ID gc = GrNewGC();
if (!imageid) {
char path[256];
sprintf(path, "%s/%s", get_desktop_config(DESKTOP_IMAGEDIR), APPICON);
imageid = GrLoadImageFromFile(path, 0);
}
GrDrawImageToFit(ep->wid, gc, 0, 0, -1, -1, imageid);
GrDestroyGC(gc);
}
static void
scribble_buttondown(win * window, GR_EVENT_BUTTON * ep)
{
APP *p = find_app_flags(FL_SCRIBBLE);
if (!p) {
printf("Unable to find the scribble app!\n");
return;
}
if (is_app_running(p)) {
if (appvisible) {
hide_application(p);
appvisible = 0;
} else {
show_application(p);
appvisible = 1;
}
} else {
launch_application(p);
appvisible = 1;
}
#ifdef NOTUSED
if (p->m_process_id && p->m_container_wid) {
appvisible = !appvisible;
if (appvisible) {
GrMapWindow(p->m_container_wid);
GrRaiseWindow(p->m_container_wid);
} else {
GrUnmapWindow(p->m_container_wid);
}
} else if (!(p->m_process_id = fork())) {
printf("execing %s\n", p->m_exec);
execlp(p->m_exec, p->m_exec, 0);
exit(0);
} else {
g_last_window = p->m_icon_wid;
LastLaunchedApp = p;
appvisible = 1;
}
#endif
}
static void
scribble_wndproc(win * window, GR_EVENT * ep)
{
switch (ep->type) {
case GR_EVENT_TYPE_EXPOSURE:
scribble_exposure(window, &ep->exposure);
break;
case GR_EVENT_TYPE_BUTTON_DOWN:
scribble_buttondown(window, &ep->button);
break;
}
}
--- NEW FILE: categories.c ---
/*
* Copyright (c) 2003 Century Software, Inc. All Rights Reserved.
*
* This file is part of the PIXIL Operating Environment
*
* The use, copying and distribution of this file is governed by one
* of two licenses, the PIXIL Commercial License, or the GNU General
* Public License, version 2.
*
* Licensees holding a valid PIXIL Commercial License may use this file
* in accordance with the PIXIL Commercial License Agreement provided
* with the Software. Others are governed under the terms of the GNU
* General Public License version 2.
*
* This file may be distributed and/or modified under the terms of the
* GNU General Public License version 2 as published by the Free
* Software Foundation and appearing in the file LICENSE.GPL included
* in the packaging of this file.
*
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING
* THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE.
*
* RESTRICTED RIGHTS LEGEND
*
* Use, duplication, or disclosure by the government is subject to
* restriction as set forth in paragraph (b)(3)(b) of the Rights in
* Technical Data and Computer Software clause in DAR 7-104.9(a).
*
* See http://www.pixil.org/gpl/ for GPL licensing
* information.
*
* See http://www.pixil.org/license.html or
* email cetsales at centurysoftware.com for information about the PIXIL
* Commercial License Agreement, or if any conditions of this licensing
* are not clear to you.
*/
#include <pixil_config.h>
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#define MWINCLUDECOLORS
#include <nano-X.h>
#include <par/par.h>
#include "apps.h"
#include "nanowm.h"
#include "categories.h"
#include "config.h"
#include "sys_menu.h"
/* A linked list of categories */
static category_t *categoryList = 0;
/* A pointer to the current list of categories */
static category_t *currentCategory = 0;
static GR_WINDOW_ID cbWindow = 0;
static GR_WINDOW_ID cbPixmap = 0;
int
category_getCount()
{
int count = 0;
category_t *ptr = categoryList;
while (ptr) {
count++;
ptr = ptr->next;
}
return (count);
}
inline category_t *
category_getCurrent(void)
{
return (currentCategory);
}
/* Each virtual window is defined by a index */
category_t *
category_getByIndex(int index)
{
category_t *head = categoryList;
while (head) {
if (head->index == index)
return (head);
head = head->next;
}
return (0);
}
inline int
category_getCurrentWin(void)
{
if (currentCategory)
return (currentCategory->index);
return (0);
}
category_t *
category_getNext(category_t * cur)
{
if (!cur)
return (0);
if (!cur->next)
return (categoryList);
else
return (cur->next);
}
category_t *
category_getPrev(category_t * cur)
{
category_t *head = 0;
if (!cur)
return (0);
if (cur->prev)
return (cur->prev);
/* We need to find the tail. A somewhat expensive operation */
/* But easier than storing the tail */
head = cur;
while (head) {
if (!head->next)
return (head);
head = head->next;
}
return (0);
}
/* This just simply sets the current category to the specified index */
int
category_setCurrent(int index)
{
category_t *head = categoryList;
while (head) {
if (head->index == index) {
currentCategory = head;
return (0);
}
head = head->next;
}
return (-1);
}
/* What is this used for? */
/*
Given a name, return the index associated with that catagory
*/
#ifdef NOTUSED
int
get_catagory_index(char *name)
{
PNXLIST p = catagory_list.head;
char *dupname, /* For strdup() of name */
*dupcat; /* For strdup() of cat->name */
for (; p; p = p->next) {
CATAGORY *cat = nxItemAddr(p, CATAGORY, next);
if ((dupname = strdup(name)) != NULL &&
(dupcat = strdup(cat->name)) != NULL) {
/* Make all characters lower case */
string_tolower(strlen(dupname), dupname);
string_tolower(strlen(dupcat), dupcat);
if (!strcmp(dupname, dupcat))
return (cat->index);
free(dupname);
free(dupcat);
} /* end of if */
else {
if (!strcmp(name, cat->name))
return (cat->index);
} /* end of else */
}
return (-1);
}
#endif
/* switch_catagory()
This switches the current catagory to the one specified by index
Unlike set_current_catagory, this function switches the icon lists,
hides windows, and redraws the root window
*/
int
switchCategory(int index)
{
category_t *new = category_getByIndex(index);
category_t *old = category_getCurrent();
if (!new)
return (-1);
if (new == old)
return (0);
/* First, hide all of the running apps */
if (old)
hide_icon_list();
category_setCurrent(new->index);
/* Redraw the root window */
/* This will automatically redraw the new icons */
redraw_root_window();
return (0);
}
/* This finds an application in the database, and loads it into memory */
/* Storing the resulting app pointer into the category */
static int
loadApplication(db_handle * db, category_t * category, char *app)
{
/* The database structure */
app_info_t ainfo;
if (par_getAppTitle(db, app, ainfo.title, sizeof(ainfo.title)) < 0)
return (-1);
if (par_getAppPath(db, app, ainfo.path, sizeof(ainfo.path)) < 0)
return (-1);
/* These are not required, but they are nice to have */
par_getAppIcon(db, app, ainfo.icon, sizeof(ainfo.icon));
par_getAppWorkDir(db, app, ainfo.workdir, sizeof(ainfo.workdir));
par_getAppArgs(db, app, ainfo.args, sizeof(ainfo.args));
/* No flags, this is a normal application */
ainfo.flags = 0;
/* Now, add the application */
if (!apps_add_application(app, &ainfo, &category->apps[category->count])) {
category->count++;
return (0);
} else {
category->apps[category->count] = 0;
return (-1);
}
}
/* Load a category from the database */
static int
loadCategory(db_handle * db, char *category, int index)
{
char *app;
char *applist;
int appcount;
category_t *ptr = 0;
/* First, allocate a new category structure */
if (!categoryList) {
ptr = categoryList = (category_t *) calloc(sizeof(category_t), 1);
} else {
category_t *n = categoryList;
while (n->next)
n = n->next;
ptr = n->next = (category_t *) calloc(sizeof(category_t), 1);
ptr->prev = n;
}
par_getScreentopCategory(db, category, &ptr->title, &applist);
if (!applist)
return (0);
ptr->index = index;
/* First, get a count of the number of applications in the list */
app = applist;
appcount = par_getStringListCount(applist, ' ');
/* Allocate enough room for the applications */
ptr->apps = (APP **) malloc(appcount * sizeof(APP *));
while (app) {
char *head = par_parseStringList(&app, ' ');
if (!head)
break;
loadApplication(db, ptr, head);
}
/* Clean up after ourselves */
free(applist);
return (0);
}
/* Given a database handle, load all of the categories into memory */
int
nxLoadCategories(db_handle * db)
{
int count, i;
itemlist_t *categories;
count = par_getScreentopCatList(db, &categories);
if (count <= 0)
return (-1);
for (i = 0; i < count; i++) {
char cat[25];
int size = sizeof(cat);
bzero(cat, sizeof(cat));
par_getListItem(categories, i, cat, &size);
loadCategory(db, cat, i);
}
par_freeItemList(categories);
return (0);
}
void
nxFreeCategories(void)
{
category_t *head = categoryList;
while (head) {
category_t *ptr = head->next;
/* Free the title */
if (head->title)
free(head->title);
/* The apps will be freed elsewhere */
/* Free the app list */
if (head->apps)
free(head->apps);
free(head);
head = ptr;
}
categoryList = 0;
currentCategory = 0;
}
/* This is where we draw the category browser */
void
draw_categoryBrowser(GR_REGION_ID r)
{
GR_WINDOW_INFO winfo;
GR_GC_ID gc;
/* Draw as much as we need from the pixmap */
GrGetWindowInfo(cbWindow, &winfo);
gc = GrNewGC();
/* Set the clip region */
GrSetGCRegion(gc, r);
GrCopyArea(GR_ROOT_WINDOW_ID, gc,
winfo.x, winfo.y, winfo.width, winfo.height,
cbPixmap, 0, 0, MWROP_SRCCOPY);
/* Now, draw the appropriate category name centered within the box */
if (currentCategory) {
int x, y;
int width, height, baseline;
GR_FONT_ID font = GrCreateFont(GR_FONT_GUI_VAR, 0, NULL);
GrSetGCForeground(gc, WHITE);
GrSetGCUseBackground(gc, GR_FALSE);
GrSetGCFont(gc, font);
GrGetGCTextSize(gc, currentCategory->title, -1,
GR_TFASCII | GR_TFTOP, &width, &height, &baseline);
x = (winfo.width - width) / 2;
y = (winfo.height - height) / 2;
GrText(GR_ROOT_WINDOW_ID, gc,
winfo.x + x, winfo.y + y, currentCategory->title,
-1, GR_TFASCII | GR_TFTOP);
GrDestroyFont(font);
}
GrDestroyGC(gc);
}
static void
cbProc(win * window, GR_EVENT * ep)
{
GR_WINDOW_INFO winfo;
category_t *curcat = category_getCurrent();
category_t *newcat = 0;
switch (ep->type) {
case GR_EVENT_TYPE_BUTTON_DOWN:
GrGetWindowInfo(ep->button.wid, &winfo);
/* Changed this so if the pointer is on the right half of the window it
** will fetch the next catagory, and if on the left half of the window it
** will fetch the previous catagory --- j webb (01/19/01)
*/
if (ep->button.x <= (winfo.width / 2))
newcat = category_getPrev(curcat);
else if (ep->button.x > (winfo.width / 2))
newcat = category_getNext(curcat);
switchCategory(newcat->index);
break;
}
}
void
create_categoryBrowser(void)
{
char file[256];
GR_SCREEN_INFO si;
GR_IMAGE_ID bImage = 0;
GR_GC_ID gc;
int bWidth = 0, bHeight = 0;
sprintf(file, "%s/catbrowser.gif", wm_getDir(DESKTOP_IMAGEDIR));
if (access(file, F_OK) == 0) {
bImage = GrLoadImageFromFile(file, 0);
if (bImage) {
GR_IMAGE_INFO info;
GrGetImageInfo(bImage, &info);
bWidth = info.width;
bHeight = info.height;
}
}
if (!bImage) {
bWidth = 80;
bHeight = 20;
}
GrGetScreenInfo(&si);
/* create an input window */
cbWindow = GrNewInputWindow(GR_ROOT_WINDOW_ID,
(si.ws_width - bWidth) / 2, 0,
bWidth, bHeight);
cbPixmap = GrNewPixmap(bWidth, bHeight, 0);
gc = GrNewGC();
if (bImage) {
GrSetGCForeground(gc, wm_getColor(WM_BGCOLOR));
GrFillRect(cbPixmap, gc, 0, 0, bWidth, bHeight);
/* Now draw the category browser image or (ack!) drawing */
GrDrawImageToFit(cbPixmap, gc, 0, 0, -1, -1, bImage);
GrFreeImage(bImage);
} else {
GR_POINT points[3];
GrSetGCForeground(gc, LTGRAY);
GrFillRect(cbPixmap, gc, 0, 0, bWidth, bHeight);
GrSetGCForeground(gc, BLACK);
GrRect(cbPixmap, gc, 0, 0, bWidth, bHeight);
points[0].x = 1;
points[0].y = bHeight / 2;
points[1].x = 10;
points[1].y = 1;
points[2].x = 10;
points[2].y = bHeight - 2;
GrFillPoly(cbPixmap, gc, 3, points);
points[0].x = bWidth - 2;
points[0].y = bHeight / 2;
points[1].x = bWidth - 10;
points[1].y = 1;
points[2].x = bWidth - 10;
points[2].y = bHeight - 2;
GrFillPoly(cbPixmap, gc, 3, points);
}
GrDestroyGC(gc);
/* Finally, set up the input window and leave */
GrSelectEvents(cbWindow,
GR_EVENT_MASK_BUTTON_DOWN | GR_EVENT_MASK_BUTTON_UP);
add_window(cbWindow, GR_ROOT_WINDOW_ID, 0, cbProc);
GrMapWindow(cbWindow);
}
#ifdef CONFIG_PIXILWM_MENUS
wm_menu_t *
create_categoryMenu(int index, char *name)
{
int i;
wm_menu_t *ptr;
category_t *cat = category_getByIndex(index);
if (!cat)
return (0);
ptr = create_system_menu(cat->count + 1);
if (!ptr)
return (0);
for (i = 0; i < cat->count; i++) {
APP *p = cat->apps[i];
if (!p)
continue;
ADD_SYS_MENU_APP(&ptr[i], p->m_icontitle, p->m_exec, p->m_icon_iid);
}
ADD_SYS_MENU_END(&ptr[i]);
strcpy(name, cat->title);
return (ptr);
}
#endif
--- NEW FILE: wlist.c ---
/*
* Copyright (c) 2003 Century Software, Inc. All Rights Reserved.
*
* This file is part of the PIXIL Operating Environment
*
* The use, copying and distribution of this file is governed by one
* of two licenses, the PIXIL Commercial License, or the GNU General
* Public License, version 2.
*
* Licensees holding a valid PIXIL Commercial License may use this file
* in accordance with the PIXIL Commercial License Agreement provided
* with the Software. Others are governed under the terms of the GNU
* General Public License version 2.
*
* This file may be distributed and/or modified under the terms of the
* GNU General Public License version 2 as published by the Free
* Software Foundation and appearing in the file LICENSE.GPL included
* in the packaging of this file.
*
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING
* THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE.
*
* RESTRICTED RIGHTS LEGEND
*
* Use, duplication, or disclosure by the government is subject to
* restriction as set forth in paragraph (b)(3)(b) of the Rights in
* Technical Data and Computer Software clause in DAR 7-104.9(a).
*
* See http://www.pixil.org/gpl/ for GPL licensing
* information.
*
* See http://www.pixil.org/license.html or
* email cetsales at centurysoftware.com for information about the PIXIL
* Commercial License Agreement, or if any conditions of this licensing
* are not clear to you.
*/
/* Portions Copyright (C) 2000 Alex Holden <alex at linuxhacker.org> */
#include <stdio.h>
#include <stdlib.h>
#include "nano-X.h"
#include "nanowm.h"
static win *windows = NULL;
static win *zHead = NULL;
/*
* Find the windowlist entry for the specified window ID and return a pointer
* to it, or NULL if it isn't in the list.
*/
win *
find_window(GR_WINDOW_ID wid)
{
win *w = windows;
debug("Looking for window %d...\n", wid);
while (w) {
if (w->wid == wid) {
debug("found it!\n");
return w;
}
w = w->next;
}
debug("Nope, %d is not in the list\n", wid);
return NULL;
}
/*
* Add a new entry to the front of the windowlist.
* Returns -1 on failure or 0 on success.
*/
win *
add_window(GR_WINDOW_ID wid, GR_WINDOW_ID pid, GR_WINDOW_ID clid,
wndproc proc)
{
win *w;
debug("Adding window %d\n", wid);
if (!(w = calloc(sizeof(win), 1)))
return NULL;
w->pos.xorig = -1;
w->pos.yorig = -1;
w->wid = wid;
w->pid = pid;
w->clientid = clid;
w->proc = proc;
w->mousedn = GR_FALSE;
w->zorder.next = 0;
w->zorder.prev = 0;
w->next = windows;
windows = w;
return w;
}
/* This will resize any maximized windows to the specified width and height */
/* I didn't know where else to put this function */
void
resize_windows(int width, int height)
{
win *w = windows;
for (w = windows; w; w = w->next) {
GR_WM_PROPERTIES props;
/* Only resize the containers */
if (!w->wid || !w->clientid)
continue;
GrGetWMProperties(w->wid, &props);
if ((props.props & GR_WM_PROPS_NOAUTORESIZE) ==
GR_WM_PROPS_NOAUTORESIZE)
continue;
if ((props.props & GR_WM_PROPS_MAXIMIZE) == GR_WM_PROPS_MAXIMIZE)
GrResizeWindow(w->wid, width, height);
}
}
/*
* Remove an entry from the windowlist.
* We must search through the list for it so that we can find the previous
* entry in the list and fix the next pointer. The alternative is to add a
* prev pointer to the structure which would increase the memory usage.
* Returns -1 on failure or 0 on success.
*/
int
remove_window(win * window)
{
win *w = windows;
win *prev = NULL;
while (w) {
if (w == window) {
if (!prev)
windows = w->next;
else
prev->next = w->next;
/* Set the zorder */
if (w->zorder.prev)
w->zorder.prev->zorder.next = w->zorder.next;
if (w->zorder.next)
w->zorder.next->zorder.prev = w->zorder.prev;
if (w == zHead)
zHead = w->zorder.next;
free(w);
return 0;
}
prev = w;
w = w->next;
}
return -1;
}
/*
* Remove an entry and all it's children from the windowlist.
* Returns -1 on failure or 0 on success.
*/
int
remove_window_and_children(win * window)
{
win *t, *w = windows;
win *prev = NULL;
GR_WINDOW_ID pid = window->wid;
debug("Removing window %d and children\n", window->wid);
while (w) {
if ((w->pid == pid) || (w == window)) {
if (prev)
prev->next = w->next;
else
windows = w->next;
t = w->next;
/* Set the zorder */
if (w->zorder.prev)
w->zorder.prev->zorder.next = w->zorder.next;
if (w->zorder.next)
w->zorder.next->zorder.prev = w->zorder.prev;
if (w == zHead)
zHead = w->zorder.next;
free(w);
w = t;
continue;
}
prev = w;
w = w->next;
}
return -1;
}
#ifdef ZDEBUG
static void
zorder_print()
{
win *win = zHead;
fprintf(stderr, "---- Z-Order List ----\n");
if (!zHead) {
fprintf(stderr, "<none>\n");
} else {
while (win) {
fprintf(stderr, "%p <-- %d --> %p\n",
win->zorder.prev, win->wid, win->zorder.next);
win = win->zorder.next;
}
}
fprintf(stderr, "-------------\n");
}
#endif
/* Push this window to the top of the zorder */
int
zorder_push(GR_WINDOW_ID id)
{
win *w = find_window(id);
if (!w)
return (-1);
if (!zHead) {
zHead = w;
w->zorder.prev = w->zorder.next = 0;
}
else {
w->zorder.next = zHead;
w->zorder.prev = 0;
zHead->zorder.prev = w;
zHead = w;
}
#ifdef ZDEBUG
zorder_print();
#endif
return (0);
}
/* Get the top window from the zorder */
GR_WINDOW_ID
zorder_peek_top(void)
{
if (zHead)
return (zHead->wid);
else
return (0);
}
/* Remove an abitrary window from the linked list */
void
zorder_remove(GR_WINDOW_ID id)
{
win *w = find_window(id);
if (!w)
return;
if (w->zorder.prev)
w->zorder.prev->zorder.next = w->zorder.next;
if (w->zorder.next)
w->zorder.next->zorder.prev = w->zorder.prev;
if (w == zHead)
zHead = w->zorder.next;
w->zorder.prev = w->zorder.next = 0;
#ifdef ZDEBUG
zorder_print();
#endif
}
void
zorder_raise(GR_WINDOW_ID id)
{
win *w = find_window(id);
if (!w)
return;
if (w == zHead)
return;
/* First, pull it out of the list */
if (w->zorder.prev)
w->zorder.prev->zorder.next = w->zorder.next;
if (w->zorder.next)
w->zorder.next->zorder.prev = w->zorder.prev;
/* Now, push it on top */
w->zorder.next = w->zorder.prev = 0;
w->zorder.next = zHead;
zHead->zorder.prev = w;
zHead = w;
#ifdef ZDEBUG
zorder_print();
#endif
}
#ifdef NOTUSED
/* Pop the top window from the zorder */
/* And return the new top window */
GR_WINDOW_ID
zorder_pop(void)
{
GR_WINDOW_ID ret = 0;
win *ptr = zHead;
if (!ptr)
return (0);
ret = ptr->wid;
next = ptr->zorder.next;
if (next)
next->zorder.prev = 0;
zHead = ptr->zorder.next;
ptr->zorder.next = 0;
ptr->zorder.prev = 0;
return (ret);
}
#endif
--- NEW FILE: inputs.c ---
/*
* Copyright (c) 2003 Century Software, Inc. All Rights Reserved.
*
* This file is part of the PIXIL Operating Environment
*
* The use, copying and distribution of this file is governed by one
* of two licenses, the PIXIL Commercial License, or the GNU General
* Public License, version 2.
*
* Licensees holding a valid PIXIL Commercial License may use this file
* in accordance with the PIXIL Commercial License Agreement provided
* with the Software. Others are governed under the terms of the GNU
* General Public License version 2.
*
* This file may be distributed and/or modified under the terms of the
* GNU General Public License version 2 as published by the Free
* Software Foundation and appearing in the file LICENSE.GPL included
* in the packaging of this file.
*
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING
* THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE.
*
* RESTRICTED RIGHTS LEGEND
*
* Use, duplication, or disclosure by the government is subject to
* restriction as set forth in paragraph (b)(3)(b) of the Rights in
* Technical Data and Computer Software clause in DAR 7-104.9(a).
*
* See http://www.pixil.org/gpl/ for GPL licensing
* information.
*
* See http://www.pixil.org/license.html or
* email cetsales at centurysoftware.com for information about the PIXIL
* Commercial License Agreement, or if any conditions of this licensing
* are not clear to you.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <par/par.h>
#define MWINCLUDECOLORS
#include <nano-X.h>
#include "apps.h"
#include "nanowm.h"
#include "config.h"
typedef struct input_struct
{
char *title;
int visible;
APP *app;
struct input_struct *next;
}
input_t;
static input_t *inputList = 0;
static input_t *defaultInput = 0;
static GR_WINDOW_ID defaultWid;
static GR_WINDOW_ID menuWid;
static GR_WINDOW_ID menubarWid;
static int menubarVisible = 0;
/* This may be a very stupid idea */
static int defaultWidth = 0;
static int defaultHeight = 0;
static void inputProc(win * window, GR_EVENT * ep);
#ifdef NOTUSED
static input_t *
input_findByWindow(GR_WINDOW_ID wid)
{
input_t *input = inputList;
while (input) {
if (input->wid == wid)
return (input);
input = input->next;
}
return (0);
}
#endif
static int
loadInput(db_handle * db, char *input)
{
par_input_t istruct;
app_info_t ainfo;
input_t *ptr;
bzero(&istruct, sizeof(par_input_t));
bzero(&ainfo, sizeof(app_info_t));
par_getScreentopInput(db, input, &istruct);
/* These are absolutely required */
if (par_getAppTitle(db, istruct.app, ainfo.title, sizeof(ainfo.title)) <
0) {
error("Couldn't find input '%s'.\n", istruct.app);
return (-1);
}
if (par_getAppPath(db, istruct.app, ainfo.path, sizeof(ainfo.path)) < 0) {
error("Couldn't get a path for input '%s'.\n", istruct.app);
return (-1);
}
/* These are not required, but they are nice to have */
par_getAppIcon(db, istruct.app, ainfo.icon, sizeof(ainfo.icon));
par_getAppWorkDir(db, istruct.app, ainfo.workdir, sizeof(ainfo.workdir));
par_getAppArgs(db, istruct.app, ainfo.args, sizeof(ainfo.args));
ainfo.flags = FL_INPUT;
if (!inputList) {
ptr = inputList = (input_t *) calloc(sizeof(input_t), 1);
} else {
input_t *head = inputList;
while (head->next)
head = head->next;
ptr = head->next = (input_t *) calloc(sizeof(input_t), 1);
}
if (!ptr)
return (-1);
ptr->next = 0;
/* Add the application to the list */
if (apps_add_application(istruct.app, &ainfo, &ptr->app) != 0)
return (-1);
if (!ptr->app)
return (-1);
/* Set up the icon */
if (strlen(ainfo.icon)) {
ptr->app->m_icon_iid = loadIconImage(ainfo.icon, ainfo.path, 1);
} else {
ptr->app->m_icon_iid = loadIconImage(istruct.icon, ainfo.path, 1);
}
if (!defaultInput)
defaultInput = ptr;
return (0);
}
int
nxLoadInputs(db_handle * db)
{
int i;
int count;
itemlist_t *inputs;
count = par_getScreentopInputList(db, &inputs);
if (count <= 0)
return (-1);
for (i = 0; i < count; i++) {
char input[25];
int size = sizeof(input);
bzero(input, sizeof(input));
par_getListItem(inputs, i, input, &size);
if (loadInput(db, input) == -1) {
}
}
par_freeItemList(inputs);
return (0);
}
void
nxFreeInputs(void)
{
input_t *head = inputList;
while (head) {
input_t *next = head->next;
if (head->title)
free(head->title);
free(head);
head = next;
}
}
static void
drawDefaultButton(GR_WINDOW_ID wid)
{
int xpos, ypos;
GR_WINDOW_INFO info;
GR_IMAGE_INFO iinfo;
GR_GC_ID gc = GrNewGC();
GrGetWindowInfo(wid, &info);
GrSetGCForeground(gc, wm_getColor(WM_TASKBAR));
GrFillRect(wid, gc, 0, 0, info.width, info.height);
/* Draw the default image in here */
if (!defaultInput)
return;
if (!defaultInput->app || !defaultInput->app->m_icon_iid)
return;
GrGetImageInfo(defaultInput->app->m_icon_iid, &iinfo);
xpos = (info.width - iinfo.width) / 2;
ypos = (info.height - iinfo.height) / 2;
GrDrawImageToFit(wid, gc, xpos, ypos, -1, -1,
defaultInput->app->m_icon_iid);
/* Draw a black border around it for looks */
GrSetGCForeground(gc, wm_getColor(WM_BGCOLOR));
GrRect(wid, gc, 0, 0, info.width, info.height - 2);
GrDestroyGC(gc);
}
static void
drawMenuButton(win * window, GR_EVENT_EXPOSURE * e)
{
GR_POINT points[3];
GR_WINDOW_INFO info;
GR_GC_ID gc = GrNewGC();
GrGetWindowInfo(e->wid, &info);
/* This will eventually be an image, but for now, just put a caret.. :) */
GrSetGCBackground(gc, wm_getColor(WM_TASKBAR));
GrSetGCForeground(gc, wm_getColor(WM_BGCOLOR));
points[0].x = 3;
points[0].y = 11;
points[1].x = 7;
points[1].y = 6;
points[2].x = 12;
points[2].y = 11;
GrFillPoly(e->wid, gc, 3, points);
GrRect(e->wid, gc, 0, 0, info.width, info.height - 2);
GrDestroyGC(gc);
}
static void
drawMenu(win * window, GR_EVENT_EXPOSURE * e)
{
input_t *head = inputList;
int x = 0, y = 0;
GR_WINDOW_INFO info;
GR_IMAGE_INFO iinfo;
GR_GC_ID gc = GrNewGC();
GrGetWindowInfo(e->wid, &info);
GrSetGCForeground(gc, wm_getColor(WM_BGCOLOR));
while (head) {
int ypos = 0;
if (!head->app || !head->app->m_icon_iid) {
head = head->next;
continue;
}
GrGetImageInfo(head->app->m_icon_iid, &iinfo);
x = (info.width - iinfo.width) / 2;
ypos = y + (20 - iinfo.height) / 2;
GrDrawImageToFit(e->wid, gc, x, ypos, -1, -1, head->app->m_icon_iid);
/* GrRect(e->wid, gc, 0, y, info.width, 20); */
y += 19;
head = head->next;
}
/* GrRect(e->wid, gc, 0, 0, info.width, info.height); */
GrDestroyGC(gc);
}
void
inputResizeWorkspace(APP * app)
{
GR_WINDOW_INFO info;
if (!app)
return;
/* Figure out the size of the window */
GrGetWindowInfo(app->m_container_wid, &info);
setWorkspace(defaultWidth, defaultHeight - info.height + 1);
}
void
inputResetWorkspace(void)
{
int cw, ch;
getWorkspace(&cw, &ch);
if ((defaultWidth == cw) && (defaultHeight == ch))
return;
setWorkspace(defaultWidth, defaultHeight);
}
int
isInputVisible(void)
{
input_t *input = inputList;
while (input) {
if (input->visible)
return (1);
input = input->next;
}
return (0);
}
static void
fireInput(input_t * input)
{
APP *p = 0;
if (!input)
return;
p = input->app;
if (!p)
return;
if (is_app_running(p)) {
if (input->visible) {
hide_application(p);
input->visible = 0;
} else {
show_application(p);
input->visible = 1;
}
} else {
launch_application(p);
input->visible = 1;
}
if (input->visible)
inputResizeWorkspace(input->app);
else
setWorkspace(defaultWidth, defaultHeight);
}
static void
launchDefault(win * window, GR_EVENT_BUTTON * e)
{
fireInput(defaultInput);
}
static void
launchInput(win * window, GR_EVENT_BUTTON * e)
{
input_t *head = inputList;
int index = e->y / 20;
int i;
for (i = 0; i < (index); i++) {
if (!head)
return;
head = head->next;
}
if (head != defaultInput && defaultInput) {
if (defaultInput->visible)
hide_application(defaultInput->app);
defaultInput->visible = 0;
}
/* This is the new default! */
fireInput(head);
defaultInput = head;
drawDefaultButton(defaultWid);
}
/* Called when an input is killed */
void
killInput(APP * app)
{
int state = 0;
input_t *head = inputList;
/* Try to figure out which input this was for */
while (head) {
if (head->app == app) {
if (head->visible)
head->visible = 0;
} else if (head->visible)
state = 1;
head = head->next;
}
if (!state)
setWorkspace(defaultWidth, defaultHeight);
}
/* Hide all the inputs */
void
hideInputs(void)
{
input_t *head = inputList;
while (head) {
if (!head->app) {
head = head->next;
continue;
}
if (head->visible)
hide_application(head->app);
head->visible = 0;
head = head->next;
}
}
/* New fangled way to set things up. We have two buttons - One with */
/* the most current input and one that will bring up the menu */
void
createInputButton(void)
{
int count = 0;
input_t *head = inputList;
GR_SCREEN_INFO si;
int x, y;
GrGetScreenInfo(&si);
getWorkspace(&defaultWidth, &defaultHeight);
x = si.ws_width - 46;
y = si.ws_height + 2;
while (head) {
count++;
head = head->next;
}
if (!count) {
return;
}
/* Make the two buttons */
defaultWid = GrNewWindowEx(GR_WM_PROPS_NODECORATE, NULL,
GR_ROOT_WINDOW_ID,
x, y, 32, 20, wm_getColor(WM_TASKBAR));
menuWid = GrNewWindowEx(GR_WM_PROPS_NODECORATE, NULL,
GR_ROOT_WINDOW_ID,
x + 33, y, 13, 20, wm_getColor(WM_TASKBAR));
menubarWid = GrNewWindowEx(GR_WM_PROPS_NODECORATE, NULL,
GR_ROOT_WINDOW_ID,
x + 20, si.ws_height - (20 * count),
25, (20 * count) - 1, wm_getColor(WM_TASKBAR));
GrSelectEvents(menuWid,
GR_EVENT_MASK_EXPOSURE | GR_EVENT_MASK_BUTTON_DOWN);
GrSelectEvents(defaultWid,
GR_EVENT_MASK_EXPOSURE | GR_EVENT_MASK_BUTTON_DOWN);
GrSelectEvents(menubarWid,
GR_EVENT_MASK_EXPOSURE | GR_EVENT_MASK_BUTTON_DOWN);
add_window(defaultWid, GR_ROOT_WINDOW_ID, 0, inputProc);
add_window(menuWid, GR_ROOT_WINDOW_ID, 0, inputProc);
add_window(menubarWid, GR_ROOT_WINDOW_ID, 0, inputProc);
GrMapWindow(defaultWid);
GrMapWindow(menuWid);
}
#ifdef NOTUSED
/* Currently, the inputs are added as they are found */
/* from right to left (of course this may change) */
int
createInputs(int start)
{
int x, y;
GR_SCREEN_INFO si;
input_t *head = inputList;
GrGetScreenInfo(&si);
x = start;
y = si.ws_height + 2;
while (head) {
if (!head->app || !head->app->m_icon_iid) {
head = head->next;
continue;
}
head->wid = GrNewWindowEx(GR_WM_PROPS_NODECORATE, NULL,
GR_ROOT_WINDOW_ID,
x, y, 30, 15, wm_getColor(WM_TASKBAR));
add_window(head->wid, GR_ROOT_WINDOW_ID, 0, input_wndproc);
GrSelectEvents(head->wid,
GR_EVENT_MASK_BUTTON_DOWN | GR_EVENT_MASK_EXPOSURE);
GrMapWindow(head->wid);
x -= 20;
head = head->next;
}
return (x);
}
static void
input_exposure(win * window, GR_EVENT_EXPOSURE * ep)
{
GR_GC_ID gc;
input_t *input = input_findByWindow(ep->wid);
if (!input)
return;
if (!input->app || !input->app->m_icon_iid)
return;
gc = GrNewGC();
GrDrawImageToFit(ep->wid, gc, 0, 0, -1, -1, input->app->m_icon_iid);
GrDestroyGC(gc);
}
static void
input_buttondown(win * window, GR_EVENT_BUTTON * ep)
{
APP *p = 0;
input_t *input = input_findByWindow(ep->wid);
if (!input)
return;
p = input->app;
if (!p) {
return;
}
if (is_app_running(p)) {
if (input->visible) {
hide_application(p);
input->visible = 0;
} else {
show_application(p);
input->visible = 1;
}
} else {
launch_application(p);
input->visible = 1;
}
}
#endif
static void
inputProc(win * window, GR_EVENT * ep)
{
switch (ep->type) {
case GR_EVENT_TYPE_EXPOSURE:
if (ep->exposure.wid == defaultWid)
drawDefaultButton(ep->exposure.wid);
if (ep->exposure.wid == menuWid)
drawMenuButton(window, &ep->exposure);
if (ep->exposure.wid == menubarWid)
drawMenu(window, &ep->exposure);
break;
case GR_EVENT_TYPE_BUTTON_DOWN:
if (ep->button.wid == menuWid) {
if (menubarVisible) {
GrUnmapWindow(menubarWid);
menubarVisible = 0;
} else {
GrMapWindow(menubarWid);
GrRaiseWindow(menubarWid);
menubarVisible = 1;
}
}
if (ep->button.wid == defaultWid) {
launchDefault(window, &ep->button);
if (menubarVisible) {
GrUnmapWindow(menubarWid);
menubarVisible = 0;
}
}
if (ep->button.wid == menubarWid) {
launchInput(window, &ep->button);
menubarVisible = 0;
GrUnmapWindow(menubarWid);
}
break;
}
}
--- NEW FILE: main.c ---
/*
* Copyright (c) 2003 Century Software, Inc. All Rights Reserved.
*
* This file is part of the PIXIL Operating Environment
*
* The use, copying and distribution of this file is governed by one
* of two licenses, the PIXIL Commercial License, or the GNU General
* Public License, version 2.
*
* Licensees holding a valid PIXIL Commercial License may use this file
* in accordance with the PIXIL Commercial License Agreement provided
* with the Software. Others are governed under the terms of the GNU
* General Public License version 2.
*
* This file may be distributed and/or modified under the terms of the
* GNU General Public License version 2 as published by the Free
* Software Foundation and appearing in the file LICENSE.GPL included
* in the packaging of this file.
*
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING
* THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE.
*
* RESTRICTED RIGHTS LEGEND
*
* Use, duplication, or disc1losure by the government is subject to
* restriction as set forth in paragraph (b)(3)(b) of the Rights in
* Technical Data and Computer Software clause in DAR 7-104.9(a).
*
* See http://www.pixil.org/gpl/ for GPL licensing
* information.
*
* See http://www.pixil.org/license.html or
* email cetsales at centurysoftware.com for information about the PIXIL
* Commercial License Agreement, or if any conditions of this licensing
* are not clear to you.
*/
#include <pixil_config.h>
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <signal.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <nano-X.h>
#include "nanowm.h"
#include "apps.h"
#include "categories.h"
#include "applets.h"
#ifdef CONFIG_PIXILWM_MENUS
#include "sys_menu.h"
#endif
#ifdef CONFIG_PIXILWM_PM
#include "powerman.h"
#endif
#include "screensaver.h"
static scrtop_fire_timer(GR_TIMER_ID id);
static void mainloop(void);
GR_TIMER_ID pwr_timer_id = 0;
char *path = "/tmp/nxscrtop.pid";
/*
* This the universal, get-outta here function that closes everything down and bails.
*/
void
close_nxscrtop(int id)
{
win *window;
warning("The screentop has been closed. Freeing resources....\n");
/* Step 1. Kill off any outstanding applications that are still running */
kill_running_processes();
/* Step 2. Remove all the windows */
window = find_window(GR_ROOT_WINDOW_ID);
remove_window_and_children(window);
/* Step 3. Free all the outstanding memory */
apps_free_memory();
root_free_memory();
nxFreeCategories();
unlink(path);
exit(0);
}
int
main(int argc, char *argv[])
{
pid_t pid = 0;
int pathfd_;
char buf[512];
int ret;
extern void application_handler(int id);
/* These are death signals, that indicate that we should close up shop */
signal(SIGINT, close_nxscrtop);
signal(SIGTERM, close_nxscrtop);
signal(SIGHUP, close_nxscrtop);
memset(buf, 0, sizeof(buf));
pid = getpid();
if (!access(path, F_OK)) {
printf("Warnning - found a stale lockfile. Deleting it...\n");
unlink(path);
}
pathfd_ = open(path, O_RDWR | O_TRUNC | O_CREAT);
if (pathfd_ == -1) {
perror("open(): /tmp/nxscrtop.pid");
exit(errno);
}
sprintf(buf, "%d", pid);
ret = write(pathfd_, buf, strlen(buf));
if (-1 == ret) {
perror("write(): pid");
exit(errno);
}
close(pathfd_);
/* This is the sigchild handler, useful for when our children die */
signal(SIGCHLD, application_handler);
if (GrOpen() < 0) {
error("Couldn't connect to Nano-X server!\n");
unlink(path);
exit(-1);
}
GrReqShmCmds(65536L);
startIPC();
wm_init_applets();
nxLoadConfig();
/* pass errors through main loop, don't exit */
GrSetErrorHandler(NULL);
root_create();
/* Start the screen saver / power management */
screensaver_init();
mainloop();
unlink(path);
return 0;
}
static void
mainloop(void)
{
unsigned long timeout = wm_applet_get_timeout();
GR_EVENT event;
win *window;
while (1) {
unsigned long elapsed = 0;
struct timeval b, a;
gettimeofday(&b, 0);
GrGetNextEventTimeout(&event, timeout);
gettimeofday(&a, 0);
switch (event.type) {
/* all these events share their wid member location */
case GR_EVENT_TYPE_BUTTON_DOWN:
case GR_EVENT_TYPE_BUTTON_UP:
case GR_EVENT_TYPE_KEY_DOWN:
case GR_EVENT_TYPE_KEY_UP:
case GR_EVENT_TYPE_EXPOSURE:
case GR_EVENT_TYPE_UPDATE:
case GR_EVENT_TYPE_MOUSE_POSITION:
case GR_EVENT_TYPE_MOUSE_ENTER:
case GR_EVENT_TYPE_MOUSE_EXIT:
case GR_EVENT_TYPE_FOCUS_IN:
case GR_EVENT_TYPE_FOCUS_OUT:
#ifdef MICROWIN_PRE8
case GR_EVENT_TYPE_BUTTON_LONG_CLICK:
#endif
window = find_window(((GR_EVENT_GENERAL *) & event)->wid);
#ifdef CONFIG_PIXILWM_MENUS
if (system_menu_active() == GR_TRUE) {
if (handle_system_menu(&event) == 1)
break;
}
#endif
if (window && window->proc)
window->proc(window, &event);
wm_applet_handle_event(&event);
break;
case GR_EVENT_TYPE_FDINPUT:
/* We got a FD input, thats probably a colosseum thing */
handleIPC(&event.fdinput);
break;
case GR_EVENT_TYPE_CHLD_UPDATE:
window = find_window(((GR_EVENT_UPDATE *) & event)->subwid);
/*
* Add unknown newly mapped window to window manager
* internal data structures. This will also create
* a new parent container window.
*/
if (!window && event.update.utype == GR_UPDATE_MAP) {
client_updatemap_new(((GR_EVENT_UPDATE *) & event)->subwid);
}
if (window && window->proc)
window->proc(window, &event);
break;
case GR_EVENT_TYPE_TIMER:
if (event.timer.tid) scrtop_fire_timer(event.timer.tid);
break;
case GR_EVENT_TYPE_TIMEOUT:
/* Handled elsewhere */
break;
case GR_EVENT_TYPE_SCREENSAVER:
/* Backlight */
if (event.screensaver.activate == GR_TRUE)
screensaver_enable();
else
screensaver_disable();
break;
case GR_EVENT_TYPE_ERROR:
error("GrError (%s)", event.error.name);
error(nxErrorStrings[event.error.code], event.error.id);
break;
default:
warning("Got unexpected event %d\n", event.type);
break;
}
/* Get the number of elapsed milliseconds for the timer */
elapsed = 0;
if (b.tv_usec > a.tv_usec) {
if ((a.tv_sec - b.tv_sec) > 0)
elapsed = ((a.tv_sec - b.tv_sec) - 1) * 1000;
elapsed += ((1000000 - b.tv_usec) + a.tv_usec) / 1000;
}
else {
elapsed = (a.tv_sec - b.tv_sec) * 1000;
elapsed += (a.tv_usec - b.tv_usec) / 1000;
}
timeout = wm_applet_handle_timer(elapsed);
}
}
struct timer_list {
GR_TIMER_ID id;
scrtop_timer_cb callback;
struct timer_list *next;
};
static struct timer_list *scrtop_timer_list = 0;
void scrtop_register_timer(GR_TIMER_ID id, scrtop_timer_cb callback) {
struct timer_list *a = 0, *p = 0, *i = 0;
for(a = scrtop_timer_list; a; p = a, a = a->next)
if (a->id == id) return;
i = (struct timer_list *) calloc(1, sizeof(struct timer_list));
i->id = id;
i->callback = callback;
if (!p) scrtop_timer_list = i;
else p->next = i;
return;
}
void scrtop_unregister_timer(GR_TIMER_ID id) {
struct timer_list *a = 0, *p = 0;
for(a = scrtop_timer_list; a; p = a, a = a->next)
if (a->id == id) {
if (p) p->next = a->next;
else scrtop_timer_list = a->next;
free(a);
return;
}
}
static scrtop_fire_timer(GR_TIMER_ID id) {
struct timer_list *a = 0, *p = 0;
for(a = scrtop_timer_list; a; p = a, a = a->next)
if (a->id == id) {
scrtop_timer_cb ptr = a->callback;
if (p) p->next = a->next;
else scrtop_timer_list = a->next;
free(a);
if (ptr) ptr();
return;
}
}
static unsigned char cur_log_level = LOG_WARNING;
void
scrtop_log_message(int level, char *fmt, ...)
{
va_list ap;
if (level > cur_log_level)
return;
switch (level) {
case LOG_DEBUG:
printf("debug: ");
break;
case LOG_WARNING:
printf("Warning: ");
break;
case LOG_ERROR:
printf("Error: ");
break;
}
printf("nxscrtop -- ");
va_start(ap, fmt);
vprintf(fmt, ap);
va_end(ap);
}
--- NEW FILE: ipc.c ---
/*
* Copyright (c) 2003 Century Software, Inc. All Rights Reserved.
*
* This file is part of the PIXIL Operating Environment
*
* The use, copying and distribution of this file is governed by one
* of two licenses, the PIXIL Commercial License, or the GNU General
* Public License, version 2.
*
* Licensees holding a valid PIXIL Commercial License may use this file
* in accordance with the PIXIL Commercial License Agreement provided
* with the Software. Others are governed under the terms of the GNU
* General Public License version 2.
*
* This file may be distributed and/or modified under the terms of the
* GNU General Public License version 2 as published by the Free
* Software Foundation and appearing in the file LICENSE.GPL included
* in the packaging of this file.
*
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING
* THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE.
*
* RESTRICTED RIGHTS LEGEND
*
* Use, duplication, or disclosure by the government is subject to
* restriction as set forth in paragraph (b)(3)(b) of the Rights in
* Technical Data and Computer Software clause in DAR 7-104.9(a).
*
* See http://www.pixil.org/gpl/ for GPL licensing
* information.
*
* See http://www.pixil.org/license.html or
* email cetsales at centurysoftware.com for information about the PIXIL
* Commercial License Agreement, or if any conditions of this licensing
* are not clear to you.
*/
#include <pixil_config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef CONFIG_COLOSSEUM
#include <ipc/colosseum.h>
#endif
#include <nano-X.h>
#include "nanowm.h"
#include "apps.h"
#include <wm/scrtoplib.h>
#ifdef CONFIG_PIXILWM_PM
#include "powerman.h"
#endif
//extern int check_par_tz_flag;
static int cl_fd = 0;
int
ipcActive(void)
{
return ((cl_fd > 0) ? 1 : 0);
}
void
startIPC(void)
{
#ifdef CONFIG_COLOSSEUM
int cl_flags;
cl_fd = ClRegister("nxscrtop", &cl_flags);
if (cl_fd <= 0)
warning("Unable to locate the Colosseum server.\n");
else
GrRegisterInput(cl_fd);
#endif
}
int
ipcGetAppName(int processid, char *name, int size)
{
#ifndef CONFIG_COLOSSEUM
return -1;
#else
cl_app_info info;
info.flags = CL_APP_INFO_PID;
info.processid = processid;
if (clGetAppInfo(&info) == -1) {
error("Unable to get information for process '%d'.\n", processid);
return (-1);
}
strncpy(name, info.name, size);
return (0);
#endif
}
static void
handleAction(scrtop_action * action)
{
APP *app = find_app_name(action->app);
win *window;
if (!app) {
error("Couldn't locate application '%s'.\n", action->app);
return;
}
if (!app->m_container_wid)
return;
window = find_window(app->m_container_wid);
if (!window) {
error("Unable to find the window for container %d.\n",
app->m_container_wid);
return;
}
switch (action->type) {
case ACTION_SHOW:
container_activate(app->m_container_wid);
break;
case ACTION_HIDE:
container_hide(app->m_container_wid);
break;
case ACTION_CLOSE:
window = find_window(app->m_container_wid);
if (!window || !window->clientid)
break;
GrCloseWindow(window->clientid);
break;
default:
warning("Unknown IPC command %d\n", action->type);
break;
}
}
void
handleNAAction(scrtop_action * action)
{
/*
** This function handles the "Non-Application" related actions, i.e. things
** that pertain to the screen top only
*/
switch (action->type) {
#ifdef CONFIG_PIXILWM_PM
case NA_ACTION_BLON:
pm_backlight(1);
break;
case NA_ACTION_BLOFF:
pm_backlight(0);
break;
#endif
default:
warning("Unknown NA_ACTION IPC command %d\n", action->type);
break;
} /* end of switch */
} /* end of handleNAAction() */
void
handleTextIpc(scrtop_message * msg)
{
char *t_msg;
char *c = 0;
t_msg = (char *) malloc(CL_MAX_MSG_LEN);
if (t_msg == 0)
return;
memcpy(t_msg, msg, sizeof(scrtop_message));
c = strchr(t_msg, '^');
if (c != 0)
*c++ = 0;
#ifdef CONFIG_PIXILWM_PM
if (!(strcmp(t_msg, "sc_power")))
pm_reload();
if (!(strcmp(t_msg, "sc_backlite")))
pm_reload();
#endif
if (!(strcmp(t_msg, "sc_clock"))) {
/*
** The user has changed the system time/date (possibly changed the
** timezone, etc, get values from par and set time accordingly
*/
//check_par_tz_flag = 1;
}
/* end of if */
free(t_msg);
}
void
handleIPC(GR_EVENT_FDINPUT * e)
{
#ifdef CONFIG_COLOSSEUM
scrtop_message msg;
int size = sizeof(msg);
int ack = 0;
unsigned short src = 0;
/* We have a message waiting for us, lets grab it and do some stuff */
ack = ClGetMessage(&msg, &size, &src);
if (ack < 0)
return;
if (ack == CL_CLIENT_BROADCAST) {
handleTextIpc(&msg);
return;
}
switch (GET_CATEGORY(msg.type)) {
case CATEGORY_ACTION:
handleAction(&msg.action);
break;
case CATEGORY_NA_ACTION:
handleNAAction(&msg.action);
break;
default:
warning("Unknown IPC message category %d.\n", GET_CATEGORY(msg.type));
break;
}
#endif
}
/* Send off an application for the IPC to spawn */
int
ipcSpawnApp(char *app, char *str)
{
#ifdef CONFIG_COLOSSEUM
if (!cl_fd)
return (-1);
return (ClSpawnApp(app, str));
#endif
}
--- NEW FILE: container.c ---
/*
* Copyright (c) 2003 Century Software, Inc. All Rights Reserved.
*
* This file is part of the PIXIL Operating Environment
*
* The use, copying and distribution of this file is governed by one
* of two licenses, the PIXIL Commercial License, or the GNU General
* Public License, version 2.
*
* Licensees holding a valid PIXIL Commercial License may use this file
* in accordance with the PIXIL Commercial License Agreement provided
* with the Software. Others are governed under the terms of the GNU
* General Public License version 2.
*
* This file may be distributed and/or modified under the terms of the
* GNU General Public License version 2 as published by the Free
* Software Foundation and appearing in the file LICENSE.GPL included
* in the packaging of this file.
*
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING
* THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE.
*
* RESTRICTED RIGHTS LEGEND
*
* Use, duplication, or disclosure by the government is subject to
* restriction as set forth in paragraph (b)(3)(b) of the Rights in
* Technical Data and Computer Software clause in DAR 7-104.9(a).
*
* See http://www.pixil.org/gpl/ for GPL licensing
* information.
*
* See http://www.pixil.org/license.html or
* email cetsales at centurysoftware.com for information about the PIXIL
* Commercial License Agreement, or if any conditions of this licensing
* are not clear to you.
*/
/* Portions Copyright (C) 2000 Alex Holden <alex at linuxhacker.org> */
#include <pixil_config.h>
#include <stdio.h>
#include <stdlib.h>
#define MWINCLUDECOLORS
#include "nano-X.h"
#include "nxdraw.h"
#include "nanowm.h"
#include "apps.h"
#include "themes.h"
//#define OUTLINE_MOVE 1
//#define OUTLINE_RESIZE 1
static void
container_redraw(win * window)
{
GR_WINDOW_INFO info;
GR_WM_PROPERTIES props;
GR_BOOL active;
debug("container_exposure window %d\n", window->wid);
GrGetWindowInfo(window->wid, &info);
GrGetWMProperties(window->clientid, &props);
/* Check for invalid window */
if (props.flags == 0)
return;
active = (window->clientid == GrGetFocus());
#ifdef CONFIG_PIXILWM_THEMES
if (get_activeTheme())
themeDrawContainer(window->wid, info.width, info.height, props.title,
active, props.props, get_activeTheme());
else
#endif
nxPaintNCArea(window->wid, info.width, info.height, props.title,
active, props.props);
/* Ack, this was malloced, and it is our responsibility to free it */
if (props.title)
free(props.title);
}
static void
container_exposure(win * window, GR_EVENT_EXPOSURE * event)
{
debug("container_exposure window %d\n", window->wid);
container_redraw(window);
}
static GR_BOOL
PtInRect(GR_RECT * prc, GR_SIZE x, GR_SIZE y)
{
return (x >= prc->x && x < (prc->x + prc->width) &&
y >= prc->y && y < (prc->y + prc->height));
}
/* NOTE: This is the non-themed closebox handler */
static int
check_closebox(GR_WINDOW_INFO * info, int ex, int ey)
{
int cxborder = 0, cyborder = 0;
GR_RECT r;
if (info->props & GR_WM_PROPS_BORDER) {
cxborder = 1;
cyborder = 1;
}
if (info->props & GR_WM_PROPS_APPFRAME) {
cxborder = CXBORDER;
cyborder = CYBORDER;
}
r.x = info->width - CXCLOSEBOX - cxborder - 2;
r.y = cyborder + 2;
r.width = CXCLOSEBOX;
r.height = CYCLOSEBOX;
/* Check mousedn in close box */
return (PtInRect(&r, ex, ey));
}
static int
check_titlebar(GR_WINDOW_INFO * info, int ex, int ey)
{
GR_RECT r;
int cxborder = 0, cyborder = 0;
if (info->props & GR_WM_PROPS_BORDER) {
cxborder = 1;
cyborder = 1;
}
if (info->props & GR_WM_PROPS_APPFRAME) {
cxborder = CXBORDER;
cyborder = CYBORDER;
}
r.x = cxborder;
r.y = cyborder;
r.width = info->width - cxborder * 2;
r.height = CYCAPTION;
/* Check for mousedn in caption box */
return (PtInRect(&r, ex, ey));
}
static void
container_buttondown(win * window, GR_EVENT_BUTTON * event)
{
GR_RECT r;
int ret;
GR_WINDOW_INFO info;
struct pos_size *pos = &window->pos;
debug("container_buttondown window %d\n", window->wid);
if (window->mousedn)
return;
GrGetWindowInfo(window->wid, &info);
/* Check for close box press */
if ((info.props & (GR_WM_PROPS_CAPTION | GR_WM_PROPS_CLOSEBOX)) ==
(GR_WM_PROPS_CAPTION | GR_WM_PROPS_CLOSEBOX)) {
#ifdef CONFIG_PIXILWM_THEMES
if (get_activeTheme())
ret = widgetCheckBounds(get_activeTheme(),
info.props, TITLEBAR_WIDGET_CLOSEBUTTON,
event->x, event->y,
info.width, info.height);
else
#endif
ret = check_closebox(&info, event->x, event->y);
if (ret) {
GrCloseWindow(window->clientid);
return;
}
}
/* Set focus on button down */
GrSetFocus(window->clientid);
/* check for corner resize */
r.x = info.width - 5;
r.y = info.height - 5;
r.width = 5;
r.height = 5;
if ((info.props & GR_WM_PROPS_APPFRAME)
&& PtInRect(&r, event->x, event->y)) {
window->sizing = GR_TRUE;
pos = &window->pos;
// save off the width/height offset from the window manager
GrGetWindowInfo(window->clientid, &info);
pos->xoff = -info.width;
pos->yoff = -info.height;
GrGetWindowInfo(window->wid, &info);
pos->xoff += info.width;
pos->yoff += info.height;
#ifdef OUTLINE_RESIZE
// let mouse move know that we havn't drawn the rect yet
pos->width = -1;
pos->height = -1;
#endif
window->mousedn = GR_TRUE;
return;
}
/* if not in caption, return (FIXME, not calc'd exactly) */
if (!(info.props & GR_WM_PROPS_CAPTION))
return;
/* Check the bounds of the whole shooting titlebar */
#ifdef CONFIG_PIXILWM_THEMES
if (get_activeTheme())
ret = themeCheckBounds(get_activeTheme(),
info.props, COMPONENT_TITLEBAR,
event->x, event->y, info.width, info.height);
#endif
else
ret = check_titlebar(&info, event->x, event->y);
if (!ret)
return;
/* Raise window if mouse down and allowed */
if (!(info.props & GR_WM_PROPS_NORAISE)) {
GrRaiseWindow(window->wid);
zorder_raise(window->wid);
}
/* Don't allow window move if NOMOVE property set */
if (info.props & GR_WM_PROPS_NOMOVE)
return;
window->x = event->x;
window->y = event->y;
pos->xoff = event->x;
pos->yoff = event->y;
#ifdef OUTLINE_MOVE
pos->xorig = -1;
pos->yorig = -1;
pos->width = info.width;
pos->height = info.height;
#endif
window->mousedn = GR_TRUE;
}
static void
container_buttonup(win * window, GR_EVENT_BUTTON * event)
{
#if OUTLINE_RESIZE | OUTLINE_MOVE
GR_GC_ID gc;
#endif
struct pos_size *pos = &window->pos;
debug("container_buttonup window %d\n", window->wid);
if (window->mousedn && !window->sizing &&
pos->xorig != -1 && pos->yorig != -1) {
#ifdef OUTLINE_MOVE
gc = GrNewGC();
GrSetGCMode(gc, GR_MODE_XOR | GR_MODE_EXCLUDECHILDREN);
GrRect(GR_ROOT_WINDOW_ID, gc, pos->xorig, pos->yorig,
pos->width, pos->height);
GrMoveWindow(window->wid, pos->xorig, pos->yorig);
#endif
} else if (window->sizing && pos->width != -1 && pos->height != -1) {
GR_WINDOW_INFO info;
GrGetWindowInfo(window->wid, &info);
#ifdef OUTLINE_RESIZE
gc = GrNewGC();
GrSetGCMode(gc, GR_MODE_XOR | GR_MODE_EXCLUDECHILDREN);
GrRect(GR_ROOT_WINDOW_ID, gc, info.x, info.y, pos->width,
pos->height);
GrDestroyGC(gc);
#endif
GrResizeWindow(window->wid, event->rootx - info.x,
event->rooty - info.y);
}
window->sizing = GR_FALSE;
window->mousedn = GR_FALSE;
}
static void
container_mousemoved(win * window, GR_EVENT_MOUSE * event)
{
GR_WINDOW_INFO info;
struct pos_size *pos;
#if OUTLINE_RESIZE | OUTLINE_MOVE
GR_GC_ID gc;
#endif
debug("container_mousemoved window %d\n", window->wid);
if (!window->mousedn)
return;
pos = (struct pos_size *) &window->pos;
if (window->sizing) {
GrGetWindowInfo(window->wid, &info);
#ifdef OUTLINE_RESIZE
gc = GrNewGC();
GrSetGCMode(gc, GR_MODE_XOR | GR_MODE_EXCLUDECHILDREN);
// erase old rectangle if necessary
if (pos->width != -1 && pos->height != -1)
GrRect(GR_ROOT_WINDOW_ID, gc, info.x, info.y, pos->width,
pos->height);
// draw new one
GrRect(GR_ROOT_WINDOW_ID, gc, info.x, info.y,
event->rootx - info.x, event->rooty - info.y);
GrDestroyGC(gc);
// save this new rectangle's width, height
// I know, this shouldn't be stored in x/y, but...
pos->width = event->rootx - info.x;
pos->height = event->rooty - info.y;
#else
GrResizeWindow(window->wid, event->rootx - info.x,
event->rooty - info.y);
#endif
return;
}
#ifdef OUTLINE_MOVE
gc = GrNewGC();
GrSetGCMode(gc, GR_MODE_XOR | GR_MODE_EXCLUDECHILDREN);
if (pos->xorig != -1 && pos->yorig != -1)
GrRect(GR_ROOT_WINDOW_ID, gc, pos->xorig, pos->yorig,
pos->width, pos->height);
GrRect(GR_ROOT_WINDOW_ID, gc, event->rootx - pos->xoff,
event->rooty - pos->yoff, pos->width, pos->height);
pos->xorig = event->rootx - pos->xoff;
pos->yorig = event->rooty - pos->yoff;
GrDestroyGC(gc);
#else
GrMoveWindow(window->wid, event->rootx - pos->xoff,
event->rooty - pos->yoff);
#endif
#ifdef VIRTUAL_WINDOWS
/* Redraw the window box so it knows whats up */
/* virtswitch_redraw(); */
#endif
}
static void
container_child_update(win * window, GR_EVENT_UPDATE * ep)
{
switch (ep->utype) {
case GR_UPDATE_ACTIVATE:
container_redraw(window);
break;
}
}
static void
container_resize(win * window, GR_EVENT_UPDATE * ep)
{
int w, h;
GR_WINDOW_INFO info;
GrGetWindowInfo(window->wid, &info);
// calculate new size for the client window
#ifdef CONFIG_PIXILWM_THEMES
if (get_activeTheme())
themeClientSize(get_activeTheme(), info.props, ep->width, ep->height,
&w, &h);
else
#endif
nxCalcClientSize(info.props, ep->width, ep->height, NULL, NULL, &w,
&h);
// resize client window
GrResizeWindow(window->clientid, w, h);
}
static void
container_update(win * window, GR_EVENT_UPDATE * ep)
{
switch (ep->utype) {
case GR_UPDATE_SIZE:
container_resize(window, ep);
break;
}
}
void
container_wndproc(win * window, GR_EVENT * ep)
{
switch (ep->type) {
case GR_EVENT_TYPE_EXPOSURE:
container_exposure(window, &ep->exposure);
break;
case GR_EVENT_TYPE_BUTTON_DOWN:
container_buttondown(window, &ep->button);
break;
case GR_EVENT_TYPE_BUTTON_UP:
container_buttonup(window, &ep->button);
break;
case GR_EVENT_TYPE_UPDATE:
container_update(window, &ep->update);
break;
case GR_EVENT_TYPE_MOUSE_POSITION:
container_mousemoved(window, &ep->mouse);
break;
case GR_EVENT_TYPE_CHLD_UPDATE:
container_child_update(window, &ep->update);
break;
}
}
/* GLOBAL CONTAINER MANAGMENT */
/* This is an effort to consolidate the various container functions */
/* (map, unmap, etc...) */
/* This activates the given container */
/* By mapping it, raising it and giving it focus */
void
container_activate(GR_WINDOW_ID wid)
{
GR_WINDOW_INFO info;
win *window;
if (wid == 0) {
debug("Passed 0 to container_set_focus()\n");
return;
}
if (!(window = find_window(wid))) {
error("Couldn't find window '%d' in the window list\n", wid);
return;
}
GrGetWindowInfo(wid, &info);
if (!info.mapped) {
zorder_push(wid);
GrMapWindow(wid);
} else {
zorder_raise(wid);
GrRaiseWindow(wid);
}
if (info.props & GR_WM_PROPS_NOFOCUS)
return;
GrSetFocus(window->clientid);
}
/* This hides the specified container */
void
container_hide(GR_WINDOW_ID wid)
{
if (!wid)
return;
/* Pull it out of the visible zorder */
zorder_remove(wid);
/* And unmap it */
GrUnmapWindow(wid);
}
--- NEW FILE: themes.h ---
/*
* Copyright (c) 2003 Century Software, Inc. All Rights Reserved.
*
* This file is part of the PIXIL Operating Environment
*
* The use, copying and distribution of this file is governed by one
* of two licenses, the PIXIL Commercial License, or the GNU General
* Public License, version 2.
*
* Licensees holding a valid PIXIL Commercial License may use this file
* in accordance with the PIXIL Commercial License Agreement provided
* with the Software. Others are governed under the terms of the GNU
* General Public License version 2.
*
* This file may be distributed and/or modified under the terms of the
* GNU General Public License version 2 as published by the Free
* Software Foundation and appearing in the file LICENSE.GPL included
* in the packaging of this file.
*
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING
* THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE.
*
* RESTRICTED RIGHTS LEGEND
*
* Use, duplication, or disclosure by the government is subject to
* restriction as set forth in paragraph (b)(3)(b) of the Rights in
* Technical Data and Computer Software clause in DAR 7-104.9(a).
*
* See http://www.pixil.org/gpl/ for GPL licensing
* information.
*
* See http://www.pixil.org/license.html or
* email cetsales at centurysoftware.com for information about the PIXIL
* Commercial License Agreement, or if any conditions of this licensing
* are not clear to you.
*/
#ifndef _THEMES_H_
#define _THEMES_H_
/* A macro to calculate the correct widget number */
#define COMPONENT_WIDGET(comp, index) ((comp & 0xFF) << 8 | (index & 0xFF))
#define GET_COMPONENT(item) ((item >> 8) & 0xFF)
#define GET_WIDGET(item) (item & 0xFF)
/* The available components */
#define COMPONENT_TITLEBAR 0
#define COMPONENT_LEFT 1
#define COMPONENT_RIGHT 2
#define COMPONENT_BOTTOM 3
#define COMPONENT_TOP 4
#define THEME_COMPONENT_COUNT 5
/* Titlebar widgets */
#define TITLEBAR_WIDGET_CAPTION COMPONENT_WIDGET(COMPONENT_TITLEBAR, 0)
#define TITLEBAR_WIDGET_CLOSEBUTTON COMPONENT_WIDGET(COMPONENT_TITLEBAR, 1)
#define TITLEBAR_WIDGET_TITLEBAR COMPONENT_WIDGET(COMPONENT_TITLEBAR, 2)
#define TITLEBAR_WIDGET_COUNT 3
#define BORDER_WIDGET_COUNT 1
#define STATE_ACTIVE 0
#define STATE_INACTIVE 1
typedef struct
{
int flags;
char *image;
GR_COLOR fgcolor;
GR_COLOR bgcolor;
GR_WINDOW_ID imageid;
int imageWidth;
int imageHeight;
}
widget_state_t;
typedef struct
{
struct
{
int x;
int y;
int w;
int h;
}
hotspot;
struct
{
int min;
int max;
}
width;
struct
{
int min;
int max;
}
height;
widget_state_t states[2];
}
widget_t;
typedef struct
{
int type;
int widgetCount;
widget_t **widgets;
}
component_t;
typedef struct
{
/* A component is some part of the screen that is made up of different images */
component_t components[THEME_COMPONENT_COUNT];
/* This defines how the client is offset from the container */
struct
{
int left;
int right;
int top;
int bottom;
}
client;
GR_FONT_ID font;
}
theme_t;
theme_t *createTheme(const char *directory);
void set_activeTheme(theme_t * theme);
theme_t *get_activeTheme(void);
void themeDrawContainer(GR_DRAW_ID, int, int, GR_CHAR *, GR_BOOL, GR_WM_PROPS,
theme_t *);
void themeContainerSize(theme_t *, GR_WM_PROPS, int, int, int *, int *, int *,
int *);
void themeClientSize(theme_t *, GR_WM_PROPS style, int, int, int *clientw,
int *);
int widgetCheckBounds(theme_t * theme, GR_WM_PROPS style, int index, int x,
int y, int w, int h);
int themeCheckBounds(theme_t * theme, GR_WM_PROPS style, int index, int x,
int y, int w, int h);
#endif
--- NEW FILE: utils.h ---
/*
* Copyright (c) 2003 Century Software, Inc. All Rights Reserved.
*
* This file is part of the PIXIL Operating Environment
*
* The use, copying and distribution of this file is governed by one
* of two licenses, the PIXIL Commercial License, or the GNU General
* Public License, version 2.
*
* Licensees holding a valid PIXIL Commercial License may use this file
* in accordance with the PIXIL Commercial License Agreement provided
* with the Software. Others are governed under the terms of the GNU
* General Public License version 2.
*
* This file may be distributed and/or modified under the terms of the
* GNU General Public License version 2 as published by the Free
* Software Foundation and appearing in the file LICENSE.GPL included
* in the packaging of this file.
*
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING
* THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE.
*
* RESTRICTED RIGHTS LEGEND
*
* Use, duplication, or disclosure by the government is subject to
* restriction as set forth in paragraph (b)(3)(b) of the Rights in
* Technical Data and Computer Software clause in DAR 7-104.9(a).
*
* See http://www.pixil.org/gpl/ for GPL licensing
* information.
*
* See http://www.pixil.org/license.html or
* email cetsales at centurysoftware.com for information about the PIXIL
* Commercial License Agreement, or if any conditions of this licensing
* are not clear to you.
*/
#ifndef _UTILS_H_
#define _UTILS_H_
/* dbl linked list data structure*/
typedef struct _nxlist
{ /* LIST must be first decl in struct */
struct _nxlist *next; /* next item */
struct _nxlist *prev; /* previous item */
}
NXLIST, *PNXLIST;
/* dbl linked list head data structure*/
typedef struct _nxlisthead
{
struct _nxlist *head; /* first item */
struct _nxlist *tail; /* last item */
}
NXLISTHEAD, *PNXLISTHEAD;
void *nxItemAlloc(unsigned int size);
void nxListAdd(PNXLISTHEAD pHead, PNXLIST pItem);
void nxListInsert(PNXLISTHEAD pHead, PNXLIST pItem);
void nxListInsertAfter(PNXLISTHEAD pHead, PNXLIST pItem, PNXLIST pPrev);
void nxListRemove(PNXLISTHEAD pHead, PNXLIST pItem);
#define nxItemNew(type) ((type *)nxItemAlloc(sizeof(type)))
#define nxItemFree(ptr) free((void *)ptr)
/* field offset*/
#define NXITEM_OFFSET(type, field) ((long)&(((type *)0)->field))
/* return base item address from list ptr*/
#define nxItemAddr(p,type,list) ((type *)((long)p - NXITEM_OFFSET(type,list)))
/* calculate container size from client style/size*/
void nxCalcNCSize(GR_WM_PROPS style, GR_SIZE wClient,
GR_SIZE hClient, GR_COORD * xCliOffset,
GR_COORD * yCliOffset, GR_SIZE * wContainer,
GR_SIZE * hContainer);
/* calculate client size from container style/size*/
void nxCalcClientSize(GR_WM_PROPS style, GR_SIZE wContainer,
GR_SIZE hContainer, GR_COORD * xCliOffset,
GR_COORD * yCliOffset, GR_SIZE * wClient,
GR_SIZE * hClient);
/* utility routines*/
void strzcpy(char *dst, char *src, int count);
#endif
--- NEW FILE: apps.c ---
/*
* Copyright (c) 2003 Century Software, Inc. All Rights Reserved.
*
* This file is part of the PIXIL Operating Environment
*
* The use, copying and distribution of this file is governed by one
* of two licenses, the PIXIL Commercial License, or the GNU General
* Public License, version 2.
*
* Licensees holding a valid PIXIL Commercial License may use this file
* in accordance with the PIXIL Commercial License Agreement provided
* with the Software. Others are governed under the terms of the GNU
* General Public License version 2.
*
* This file may be distributed and/or modified under the terms of the
* GNU General Public License version 2 as published by the Free
* Software Foundation and appearing in the file LICENSE.GPL included
* in the packaging of this file.
*
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING
* THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE.
*
* RESTRICTED RIGHTS LEGEND
*
* Use, duplication, or disclosure by the government is subject to
* restriction as set forth in paragraph (b)(3)(b) of the Rights in
* Technical Data and Computer Software clause in DAR 7-104.9(a).
*
* See http://www.pixil.org/gpl/ for GPL licensing
* information.
*
* See http://www.pixil.org/license.html or
* email cetsales at centurysoftware.com for information about the PIXIL
* Commercial License Agreement, or if any conditions of this licensing
* are not clear to you.
*/
#include <pixil_config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <sys/stat.h>
#include <unistd.h>
#include "apps.h"
#include "nanowm.h"
#include "categories.h"
#include "config.h"
#ifdef CONFIG_PIXILWM_MENUS
#include "sys_menu.h"
#endif
/* Globals */
APP *g_last_app; /* The last known application that was started */
/* A local list of applications */
static NXLISTHEAD apphead;
static int
searchPath(char *in, char *out, int size, int flags)
{
char *path;
char *p, *temp;
int csize;
if (!in || !out)
return (-1);
if (in[0] == '/') {
/* Check to see if the file exists */
if (access(in, flags) != 0)
return (-1);
bzero(out, size);
csize = (strlen(in) > size ? size : strlen(in));
strncpy(out, in, csize);
return (csize);
}
if (!(temp = getenv("PATH")))
return (-1);
p = path = alloca(strlen(temp) + 1);
strcpy(path, temp);
while (p) {
char *n = strchr(p, ':');
char *f;
if (n)
*n = 0;
f = alloca(strlen(p) + strlen(in) + 2);
if (!f)
continue;
sprintf(f, "%s/%s", p, in);
if (access(f, flags) == 0) {
bzero(out, size);
csize = (strlen(in) > size ? size : strlen(f));
strncpy(out, f, csize);
return (csize);
}
if (n)
p = n + 1;
else
p = 0;
}
return (-1);
}
/* This function takes the passed information and turns it into */
/* something useful We maintain the legacy APP list to avoid */
/* borking the old launch system. */
int
apps_add_application(char *name, app_info_t * app_info, APP ** application)
{
char filename[512];
APP *app;
char *p;
if (!strlen(app_info->path))
return (1);
/* Hmmm... is this really an error, or an annoying warning? */
if (searchPath(app_info->path, filename, sizeof(filename), X_OK) == -1) {
//error("Application '%s' does not exist\n", app_info->path);
return (-1);
}
app = nxItemNew(APP);
if (!app) {
error("Unable to allocate enough memory\n");
return (-1);
}
strzcpy(app->m_name, name, sizeof(app->m_name));
/* set application flags */
app->m_flags = app_info->flags;
/* Check for virtual window flags */
app->m_virtual_flags = 0;
/* set executable path */
strzcpy(app->m_exec, filename, sizeof(app->m_exec));
strzcpy(app->m_workdir, app_info->workdir, sizeof(app->m_workdir));
/* If no working directory was specified, try to develop one from the path */
if (strlen(app->m_workdir) == 0) {
char *p = strrchr(filename, '/');
if (p) {
strzcpy(app->m_workdir, filename, (int) (p - filename));
} else
app->m_workdir[0] = 0;
}
/* We used to parse the arguments, but that we before we had */
/* colosseum do most of the heavy lifting */
/* We still keep the legacy code around for backup purposes */
/* but to avoid allocating unused memory, we will parse the */
/* argc, argv list as each app is executed (see exec.c) */
strzcpy(app->m_args, app_info->args, sizeof(app->m_args));
if (app_info->flags & FL_INPUT) {
/* Add this application to the main list */
nxListAdd(&apphead, &app->link);
/* Save the link for the calling function */
if (application)
*application = app;
return (0);
}
if (strlen(app_info->title))
strzcpy(app->m_icontitle, app_info->title, sizeof(app->m_icontitle));
else {
/* use basename if no title override */
p = strrchr(app_info->path, '/');
strzcpy(app->m_icontitle, p ? p + 1 : app_info->path,
sizeof(app->m_icontitle));
}
/* user passed icon, path.gif or default */
/* This will soon be attacked with some fury */
app->m_icon_iid = loadIconImage(app_info->icon, filename, 1);
if (!app->m_icon_iid) {
warning("Unable to find an icon for '%s'. Skipping...\n", filename);
free(app);
return (-1); /* Error */
}
app->m_process_id = 0;
app->m_container_wid = 0;
app->m_icon_wid = create_icon_window();
/* Add this application to the main list */
nxListAdd(&apphead, &app->link);
/* Pass the newly created application back to the calling app */
if (application)
*application = app;
return (0);
}
void
apps_buttondown(GR_WINDOW_ID id)
{
APP *app;
if (!(app = find_app_icon(id)))
return;
launch_application(app);
}
#ifdef NOTUSED
/*
* This hides all of the windows for the given virtual window
*/
void
app_hide_windows(int virt)
{
PNXLIST p;
for (p = apphead.head; p; p = p->next) {
APP *app = nxItemAddr(p, APP, link);
if (app->m_container_wid && app->m_virtual_wid == virt)
if (!(app->m_virtual_flags & VW_STICKY)) /* Check for stickyness */
container_hide(app->m_container_wid);
}
}
/*
* This will map all the active windows for a given virtual
* window.
* FIXME: We need a flag to indicate those apps that have been
* minimized or otherwise hidden
*/
void
app_show_windows(int virt, int focus)
{
PNXLIST p;
for (p = apphead.head; p; p = p->next) {
APP *app = nxItemAddr(p, APP, link);
if (app->m_container_wid && app->m_virtual_wid == virt) {
if (!(app->m_virtual_flags & VW_STICKY))
GrMapWindow(app->m_container_wid);
/* If the new window has a stored focus, set it back again */
#ifdef NOTUSED
if (focus) {
win *window = find_window(app->m_container_wid);
if (window)
if (window->clientid == focus)
GrSetFocus(window->clientid);
}
#endif
}
}
}
#else /* VIRTUAL_WINDOWS */
void
app_hide_windows()
{
PNXLIST p;
for (p = apphead.head; p; p = p->next) {
APP *app = nxItemAddr(p, APP, link);
if (app->m_container_wid)
container_hide(app->m_container_wid);
}
}
#endif /* VIRTUAL_WINDOWS */
APP *
find_app_pid(int pid)
{
PNXLIST p = apphead.head;
for (; p; p = p->next) {
APP *app = nxItemAddr(p, APP, link);
if (app->m_process_id == pid)
return app;
}
return NULL;
}
APP *
find_app_path(char *path)
{
PNXLIST p = apphead.head;
for (; p; p = p->next) {
APP *app = nxItemAddr(p, APP, link);
if (!strcmp(path, app->m_exec))
return app;
}
return NULL;
}
APP *
find_app_flags(int flags)
{
PNXLIST p = apphead.head;
for (; p; p = p->next) {
APP *app = nxItemAddr(p, APP, link);
if (app->m_flags & flags)
return app;
}
return NULL;
}
APP *
find_app_icon(GR_WINDOW_ID id)
{
PNXLIST p = apphead.head;
for (; p; p = p->next) {
APP *app = nxItemAddr(p, APP, link);
if (app->m_icon_wid == id) {
return app;
}
}
return NULL;
}
APP *
find_app_container(GR_WINDOW_ID id)
{
PNXLIST p = apphead.head;
for (; p; p = p->next) {
APP *app = nxItemAddr(p, APP, link);
if (app->m_container_wid == id) {
return app;
}
}
return NULL;
}
APP *
find_app_name(char *name)
{
PNXLIST p = apphead.head;
for (; p; p = p->next) {
APP *app = nxItemAddr(p, APP, link);
if (strcmp(app->m_name, name) == 0) {
return app;
}
}
return NULL;
}
/* JHC 11/14 - Added this to allow apps that aren't registered in the normal */
/* manner to run. */
APP *
apps_add_onetime(char *path)
{
char *name;
app_info_t ainfo;
bzero(&ainfo, sizeof(ainfo));
strcpy(ainfo.path, path);
ainfo.flags = FL_NOICON | FL_ONETIME;
name = strrchr(path, '/');
if (!name)
name = path;
else
name = name + 1;
if (apps_add_application(name, &ainfo, 0) == -1)
return (0);
return (find_app_path(path));
}
void
apps_free_memory()
{
/* Only called when we are going down. */
/* Free all the memory we have allocated */
PNXLIST p = apphead.head;
PNXLIST t;
while (p) {
APP *app = nxItemAddr(p, APP, link);
t = p->next;
nxListRemove(&apphead, &app->link);
free(app);
p = t;
}
}
#ifdef CONFIG_PIXILWM_MENUS
int
create_apps_menu(wm_menu_t ** data)
{
int i, index = 0;
int count = category_getCount();
wm_menu_t *ptr;
count++;
*data = create_system_menu(count);
if (!*data)
return (0);
else
ptr = *data;
for (i = 0; i < count; i++) {
char name[25];
wm_menu_t *cmenu = create_categoryMenu(i, name);
if (cmenu)
ADD_SYS_MENU_CMENU(&ptr[index++], name, cmenu);
}
ADD_SYS_MENU_END(&ptr[index++]);
return (index);
}
#endif
--- NEW FILE: themetags.h ---
/*
* Copyright (c) 2003 Century Software, Inc. All Rights Reserved.
*
* This file is part of the PIXIL Operating Environment
*
* The use, copying and distribution of this file is governed by one
* of two licenses, the PIXIL Commercial License, or the GNU General
* Public License, version 2.
*
* Licensees holding a valid PIXIL Commercial License may use this file
* in accordance with the PIXIL Commercial License Agreement provided
* with the Software. Others are governed under the terms of the GNU
* General Public License version 2.
*
* This file may be distributed and/or modified under the terms of the
* GNU General Public License version 2 as published by the Free
* Software Foundation and appearing in the file LICENSE.GPL included
* in the packaging of this file.
*
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING
* THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE.
*
* RESTRICTED RIGHTS LEGEND
*
* Use, duplication, or disclosure by the government is subject to
* restriction as set forth in paragraph (b)(3)(b) of the Rights in
* Technical Data and Computer Software clause in DAR 7-104.9(a).
*
* See http://www.pixil.org/gpl/ for GPL licensing
* information.
*
* See http://www.pixil.org/license.html or
* email cetsales at centurysoftware.com for information about the PIXIL
* Commercial License Agreement, or if any conditions of this licensing
* are not clear to you.
*/
static xml_tag tagsState[] = {
{"image", 0, 0, data_image, 0},
{"fgcolor", 0, 0, data_fgcolor, 0},
{"bgcolor", 0, 0, data_bgcolor, 0}
};
static xml_tag tagsStates[] = {
{"active", tagsState, active_state_init, 0, 0},
{"inactive", tagsState, inactive_state_init, 0, 0},
};
static xml_tag tagsComponent[] = {
{"hotspot", 0, 0, data_hotspot, 0},
{"width", 0, 0, data_width, 0},
{"height", 0, 0, data_height, 0},
{"states", tagsStates, 0, 0, 0}
};
static xml_tag tagsWidget[] = {
{"widget", tagsComponent, widget_init, 0, 0}
};
static xml_tag tagsClient[] = {
{"padding", 0, 0, data_padding, 0}
};
static xml_tag themeToplevel[] = {
{"titlebar", tagsWidget, titlebar_init, 0, 0},
{"border_left", tagsWidget, border_init, 0, 0},
{"border_right", tagsWidget, border_init, 0, 0},
{"border_bottom", tagsWidget, border_init, 0, 0},
{"border_top", tagsWidget, border_init, 0, 0},
{"client", tagsClient, 0, 0, 0},
};
--- NEW FILE: themesconfig.c ---
/*
* Copyright (c) 2003 Century Software, Inc. All Rights Reserved.
*
* This file is part of the PIXIL Operating Environment
*
* The use, copying and distribution of this file is governed by one
* of two licenses, the PIXIL Commercial License, or the GNU General
* Public License, version 2.
*
* Licensees holding a valid PIXIL Commercial License may use this file
* in accordance with the PIXIL Commercial License Agreement provided
* with the Software. Others are governed under the terms of the GNU
* General Public License version 2.
*
* This file may be distributed and/or modified under the terms of the
* GNU General Public License version 2 as published by the Free
* Software Foundation and appearing in the file LICENSE.GPL included
* in the packaging of this file.
*
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING
* THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE.
*
* RESTRICTED RIGHTS LEGEND
*
* Use, duplication, or disclosure by the government is subject to
* restriction as set forth in paragraph (b)(3)(b) of the Rights in
* Technical Data and Computer Software clause in DAR 7-104.9(a).
*
* See http://www.pixil.org/gpl/ for GPL licensing
* information.
*
* See http://www.pixil.org/license.html or
* email cetsales at centurysoftware.com for information about the PIXIL
* Commercial License Agreement, or if any conditions of this licensing
* are not clear to you.
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <xml/xml.h>
#include <nano-X.h>
#include "nanowm.h"
#include "themes.h"
/* This is a list of widgets that are accepted by each component */
/* this gives us the change to be a little more flexable with the */
/* script */
char *titlebarList[] = { "caption", "closebutton", "titlebar", "" };
char *borderList[] = { "border" };
char **widgetList[] = {
titlebarList,
borderList,
borderList,
borderList,
borderList
};
/* XML callback functions */
static void *data_image(xml_token * tag, void *data, char *text, int size);
static void *data_fgcolor(xml_token * tag, void *data, char *text, int size);
static void *data_bgcolor(xml_token * tag, void *data, char *text, int size);
static void *data_hotspot(xml_token * tag, void *data, char *text, int size);
static void *data_width(xml_token * tag, void *data, char *text, int size);
static void *data_height(xml_token * tag, void *data, char *text, int size);
static void *data_padding(xml_token * tag, void *data, char *text, int size);
static void *active_state_init(xml_token * tag, void *in);
static void *inactive_state_init(xml_token * tag, void *in);
static void *widget_init(xml_token * tag, void *in);
static void *titlebar_init(xml_token * tag, void *in);
static void *border_init(xml_token * tag, void *in);
#include "themetags.h"
static void *
data_image(xml_token * tag, void *data, char *text, int size)
{
widget_state_t *state = (widget_state_t *) data;
state->image = (char *) calloc(size + 1, 1);
strncpy(state->image, text, size);
return ((void *) state);
}
static void *
data_fgcolor(xml_token * tag, void *data, char *text, int size)
{
unsigned long val;
widget_state_t *state = (widget_state_t *) data;
xml_parseColor(text, &val, size);
state->fgcolor = GR_RGB((val >> 16) & 0xFF,
(val >> 8) & 0xFF, (val & 0xFF));
return ((void *) state);
}
static void *
data_bgcolor(xml_token * tag, void *data, char *text, int size)
{
unsigned long val;
widget_state_t *state = (widget_state_t *) data;
xml_parseColor(text, &val, size);
state->bgcolor = GR_RGB((val >> 16) & 0xFF,
(val >> 8) & 0xFF, (val & 0xFF));
return ((void *) state);
}
static void *
active_state_init(xml_token * tag, void *in)
{
widget_t *widget = (widget_t *) in;
widget->states[STATE_ACTIVE].flags = 1;
return (&widget->states[STATE_ACTIVE]);
}
static void *
inactive_state_init(xml_token * tag, void *in)
{
widget_t *widget = (widget_t *) in;
widget->states[STATE_INACTIVE].flags = 1;
return (&widget->states[STATE_INACTIVE]);
}
static void *
data_hotspot(xml_token * tag, void *data, char *text, int size)
{
widget_t *widget = (widget_t *) data;
char *p = text;
char *tmp;
/* Figure out where the text ends (hint, its either a < or a \0) */
while (*p != '<' && *p != 0)
p++;
tmp = alloca((int) (p - text) + 2);
bzero(tmp, (int) (p - text) + 2);
strncpy(tmp, text, (int) (p - text));
sscanf(tmp, "%i %i %i %i",
&widget->hotspot.x, &widget->hotspot.y,
&widget->hotspot.w, &widget->hotspot.h);
return (data);
}
static void *
data_width(xml_token * tag, void *data, char *text, int size)
{
widget_t *widget = (widget_t *) data;
char *p = text;
char *tmp;
if (!widget)
return (0);
/* Figure out where the text ends (hint, its either a < or a \0) */
while (*p != '<' && *p != 0)
p++;
tmp = alloca((int) (p - text) + 2);
bzero(tmp, (int) (p - text) + 2);
strncpy(tmp, text, (int) (p - text));
/* Parse the string, it should be two integers */
sscanf(tmp, "%i %i", &widget->width.min, &widget->width.max);
return (data);
}
static void *
data_height(xml_token * tag, void *data, char *text, int size)
{
widget_t *widget = (widget_t *) data;
char *p = text;
char *tmp;
if (!widget)
return (0);
/* Figure out where the text ends (hint, its either a < or a \0) */
while (*p != '<' && *p != 0)
p++;
tmp = alloca((int) (p - text) + 2);
bzero(tmp, (int) (p - text) + 2);
strncpy(tmp, text, (int) (p - text));
/* Parse the string, it should be two integers */
sscanf(tmp, "%i %i", &widget->height.min, &widget->height.max);
return (data);
}
static void *
data_padding(xml_token * tag, void *data, char *text, int size)
{
theme_t *theme = (theme_t *) data;
char *p = text;
char *tmp;
/* Figure out where the text ends (hint, its either a < or a \0) */
if (!theme)
return (0);
while (*p != '<' && *p != 0)
p++;
tmp = alloca((int) (p - text) + 2);
bzero(tmp, (int) (p - text) + 2);
strncpy(tmp, text, (int) (p - text));
sscanf(tmp, "%i %i %i %i",
&theme->client.left, &theme->client.right,
&theme->client.top, &theme->client.bottom);
return (data);
}
static void *
widget_init(xml_token * tag, void *in)
{
component_t *comp = (component_t *) in;
char **widget_names = widgetList[comp->type];
xml_prop *prop;
char *lname = 0;
int index = 0;
for (prop = tag->props; prop; prop = prop->next) {
if (strcmp(prop->keyword, "name") == 0) {
lname = prop->value;
break;
}
}
if (!lname)
return (0);
while (strlen(widget_names[index])) {
if (strcmp(widget_names[index], lname) == 0)
break;
index++;
}
if (!strlen(widget_names[index]))
return (0);
/* Actually make the widget */
comp->widgets[index] = (widget_t *) calloc(sizeof(widget_t), 1);
/* Init a few of the items */
comp->widgets[index]->width.min = 0;
comp->widgets[index]->width.max = -1;
comp->widgets[index]->height.min = 0;
comp->widgets[index]->height.max = -1;
return ((void *) comp->widgets[index]);
}
static void *
titlebar_init(xml_token * tag, void *in)
{
theme_t *data = (theme_t *) in;
component_t *comp = &data->components[COMPONENT_TITLEBAR];
/* Set up the correct number of widgets */
comp->widgetCount = TITLEBAR_WIDGET_COUNT;
comp->widgets =
(widget_t **) calloc(comp->widgetCount * sizeof(widget_t *), 1);
comp->type = COMPONENT_TITLEBAR;
return ((void *) comp);
}
static void *
border_init(xml_token * tag, void *in)
{
component_t *comp;
theme_t *data = (theme_t *) in;
int index;
if (strcmp(tag->tag, "border_left") == 0)
index = COMPONENT_LEFT;
else if (strcmp(tag->tag, "border_right") == 0)
index = COMPONENT_RIGHT;
else if (strcmp(tag->tag, "border_bottom") == 0)
index = COMPONENT_BOTTOM;
else if (strcmp(tag->tag, "border_top") == 0)
index = COMPONENT_TOP;
else {
error("Unknown tag <%s> while parsing the theme file\n", tag->tag);
return (0);
}
comp = &data->components[index];
/* Set up the correct number of widgets */
comp->widgetCount = BORDER_WIDGET_COUNT;
comp->widgets =
(widget_t **) calloc(comp->widgetCount * sizeof(widget_t *), 1);
comp->type = index;
return ((void *) comp);
}
void
freeTheme(theme_t * theme)
{
int i, w, s;
/* Go through and check each component */
for (i = 0; i < THEME_COMPONENT_COUNT; i++) {
component_t *comp = &theme->components[i];
if (comp->widgets) {
for (w = 0; w < comp->widgetCount; w++)
if (comp->widgets[w]) {
widget_t *widget = comp->widgets[w];
for (s = 0; s < 2; s++) {
if (widget->states[s].image)
free(widget->states[s].image);
if (widget->states[s].imageid)
GrDestroyWindow(widget->states[s].imageid);
}
free(widget);
comp->widgets[w] = 0;
}
free(comp->widgets);
}
}
if (theme->font)
GrDestroyFont(theme->font);
free(theme);
}
/* Main theme function */
theme_t *
createTheme(const char *directory)
{
xml_parser engine;
theme_t *theme;
int ret;
char *xmlfile;
if (!directory)
return (0);
xmlfile = alloca(strlen(directory) + strlen("/theme.xml") + 1);
sprintf(xmlfile, "%s/theme.xml", directory);
/* Check that we can get to the theme XML file */
if (access(xmlfile, R_OK)) {
error("Unable to open the theme definition file '%s'.\n", xmlfile);
return (0);
}
/* Create the theme structure */
theme = (theme_t *) calloc(sizeof(theme_t), 1);
if (!theme)
return (0);
engine.tags = themeToplevel;
/* Now, start the parser */
ret = xml_parseFile(&engine, xmlfile, (void *) theme);
if (ret) {
error("Error %d while loading theme '%s'.\n", directory);
freeTheme(theme);
return (0);
}
theme->font = GrCreateFont(GR_FONT_GUI_VAR, 12, 0);
return (theme);
}
--- NEW FILE: apps.h ---
/*
* Copyright (c) 2003 Century Software, Inc. All Rights Reserved.
*
* This file is part of the PIXIL Operating Environment
*
* The use, copying and distribution of this file is governed by one
* of two licenses, the PIXIL Commercial License, or the GNU General
* Public License, version 2.
*
* Licensees holding a valid PIXIL Commercial License may use this file
* in accordance with the PIXIL Commercial License Agreement provided
* with the Software. Others are governed under the terms of the GNU
* General Public License version 2.
*
* This file may be distributed and/or modified under the terms of the
* GNU General Public License version 2 as published by the Free
* Software Foundation and appearing in the file LICENSE.GPL included
* in the packaging of this file.
*
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING
* THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE.
*
* RESTRICTED RIGHTS LEGEND
*
* Use, duplication, or disclosure by the government is subject to
* restriction as set forth in paragraph (b)(3)(b) of the Rights in
* Technical Data and Computer Software clause in DAR 7-104.9(a).
*
* See http://www.pixil.org/gpl/ for GPL licensing
* information.
*
* See http://www.pixil.org/license.html or
* email cetsales at centurysoftware.com for information about the PIXIL
* Commercial License Agreement, or if any conditions of this licensing
* are not clear to you.
*/
#ifndef _APPS_H_
#define _APPS_H_
#include <nano-X.h>
#include <par/par.h>
#include <wm/nxlib.h>
#define ICONWIDTH 48
#define ICONHEIGHT 48
#define ICONTEXTHEIGHT 13
#define COLOR_TASKBAR GrGetSysColor(GR_COLOR_3DLIGHT)
#define COLOR_TASKBARHILIGHT GrGetSysColor(GR_COLOR_BTNHIGHLIGHT)
#define COLOR_ICONTEXT GrGetSysColor(GR_COLOR_ACTIVECAPTIONTEXT)
#define COLOR_DESKTOP GrGetSysColor(GR_COLOR_DESKTOP)
#define COLOR_REALDESKTOP GR_RGB(1,1,1)
void root_create(void);
void load_applications(char *);
void apps_buttondown(GR_WINDOW_ID id);
void home_create(void);
void date_create(void);
void backlight_create(void);
void scribble_create(void);
void keyboard_create(void);
void battery_create(void);
#ifdef VIRTUAL_WINDOWS
void cat_switch_create(void);
#endif
#define FL_INPUT 0x001
#define FL_NOICON 0x004 /* don't create icon or icon window */
#define FL_ONETIME 0x008 /* Only run once */
#ifdef VIRTUAL_WINDOWS
#define FL_STICKY 0x010
#endif
#ifdef VIRTUAL_WINDOWS
#define VW_STICKY 0x01
#endif
/* desktop and taskbar applications kept here*/
typedef struct
{
NXLIST link;
char m_name[30];
char m_exec[64]; /* executable filename */
char m_icontitle[64]; /* displayed icon title */
char m_workdir[64];
char m_args[64];
int m_flags; /* application flags */
int m_icon_wid; /* icon input window id */
int m_icon_iid; /* icon image id */
int m_container_wid; /* container window id */
int m_process_id; /* linux process id of running app */
#ifdef VIRTUAL_WINDOWS
int m_virtual_wid; /* The current virtual window that this app is associated with */
int m_virtual_flags; /* Virtual window flags */
#endif
}
APP;
typedef struct
{
NXLIST next;
int pid;
APP *app;
}
PROCESS;
typedef struct app_info_struct
{
int flags;
char title[25];
char path[128];
char workdir[128];
char icon[64];
char args[64];
}
app_info_t;
extern NXLISTHEAD apphead;
extern APP *g_last_app;
/* Search functions */
APP *find_app_flags(int flags);
APP *find_app_path(char *path); /* Find a app based on the path */
APP *find_app_pid(int pid);
APP *find_app_name(char *name);
APP *find_app_icon(GR_WINDOW_ID id);
APP *find_app_container(GR_WINDOW_ID id);
/* Old style process handlers */
void application_handler(int id);
APP *apps_add_onetime(char *path);
/* Application list managment */
int apps_add_application(char *, app_info_t * app_info, APP ** application);
int launch_application(APP * app);
void hide_application(APP * app);
void show_application(APP * app);
int is_app_running(APP * app);
/* Window managment */
void app_show_windows(int, int);
void app_hide_windows();
/* Process management */
void kill_running_processes();
/* input.c */
void killInput(APP * app);
void inputResizeWorkspace(APP * app);
#endif
--- NEW FILE: utils.c ---
/*
* Copyright (c) 2003 Century Software, Inc. All Rights Reserved.
*
* This file is part of the PIXIL Operating Environment
*
* The use, copying and distribution of this file is governed by one
* of two licenses, the PIXIL Commercial License, or the GNU General
* Public License, version 2.
*
* Licensees holding a valid PIXIL Commercial License may use this file
* in accordance with the PIXIL Commercial License Agreement provided
* with the Software. Others are governed under the terms of the GNU
* General Public License version 2.
*
* This file may be distributed and/or modified under the terms of the
* GNU General Public License version 2 as published by the Free
* Software Foundation and appearing in the file LICENSE.GPL included
* in the packaging of this file.
*
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING
* THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE.
*
* RESTRICTED RIGHTS LEGEND
*
* Use, duplication, or disclosure by the government is subject to
* restriction as set forth in paragraph (b)(3)(b) of the Rights in
* Technical Data and Computer Software clause in DAR 7-104.9(a).
*
* See http://www.pixil.org/gpl/ for GPL licensing
* information.
*
* See http://www.pixil.org/license.html or
* email cetsales at centurysoftware.com for information about the PIXIL
* Commercial License Agreement, or if any conditions of this licensing
* are not clear to you.
*/
/* These are functions that were previously in nxlib that */
/* were pulled over here to help with size considerations */
#include <stdio.h>
#include <stdlib.h>
#include <nano-X.h>
#include <nxdraw.h>
#include "utils.h"
/*
* Calculate container size and client window offsets from
* passed client window size and style.
*/
void
nxCalcNCSize(GR_WM_PROPS style, GR_SIZE wClient, GR_SIZE hClient,
GR_COORD * xCliOffset, GR_COORD * yCliOffset,
GR_SIZE * wContainer, GR_SIZE * hContainer)
{
GR_SIZE width, height;
GR_SIZE xoffset, yoffset;
/* determine container size and client child window offsets */
if (style & GR_WM_PROPS_APPFRAME) {
width = wClient + CXFRAME;
height = hClient + CYFRAME;
xoffset = CXBORDER;
yoffset = CYBORDER;
} else if (style & GR_WM_PROPS_BORDER) {
width = wClient + 2;
height = hClient + 2;
xoffset = 1;
yoffset = 1;
} else {
width = wClient;
height = hClient;
xoffset = 0;
yoffset = 0;
}
if (style & GR_WM_PROPS_CAPTION) {
height += CYCAPTION;
yoffset += CYCAPTION;
if (style & GR_WM_PROPS_APPFRAME) {
/* extra line under caption with appframe */
++height;
++yoffset;
}
}
if (xCliOffset)
*xCliOffset = xoffset;
if (yCliOffset)
*yCliOffset = yoffset;
if (wContainer)
*wContainer = width;
if (hContainer)
*hContainer = height;
}
/*
* Calculate client size window offsets from
* passed container window size and style.
*/
void
nxCalcClientSize(GR_WM_PROPS style, GR_SIZE wContainer, GR_SIZE hContainer,
GR_COORD * xCliOffset, GR_COORD * yCliOffset,
GR_SIZE * wClient, GR_SIZE * hClient)
{
GR_SIZE width, height;
GR_SIZE xoffset, yoffset;
/* determine client size and window offsets */
if (style & GR_WM_PROPS_APPFRAME) {
width = wContainer - CXFRAME;
height = hContainer - CYFRAME;
xoffset = CXBORDER;
yoffset = CYBORDER;
} else if (style & GR_WM_PROPS_BORDER) {
width = wContainer - 2;
height = hContainer - 2;
xoffset = 1;
yoffset = 1;
} else {
width = wContainer;
height = hContainer;
xoffset = 0;
yoffset = 0;
}
if (style & GR_WM_PROPS_CAPTION) {
height -= CYCAPTION;
yoffset += CYCAPTION;
if (style & GR_WM_PROPS_APPFRAME) {
/* extra line under caption with appframe */
--height;
++yoffset;
}
}
if (xCliOffset)
*xCliOffset = xoffset;
if (yCliOffset)
*yCliOffset = yoffset;
if (wClient)
*wClient = width;
if (hClient)
*hClient = height;
}
/******** List Functions ************/
void *
nxItemAlloc(unsigned int size)
{
return (void *) calloc(size, 1);
}
/* insert at tail of list*/
void
nxListAdd(PNXLISTHEAD pHead, PNXLIST pItem)
{
if (pHead->tail) {
pItem->prev = pHead->tail;
pHead->tail->next = pItem;
} else
pItem->prev = NULL;
pItem->next = NULL;
pHead->tail = pItem;
if (!pHead->head)
pHead->head = pItem;
}
/* insert at head of list*/
void
nxListInsert(PNXLISTHEAD pHead, PNXLIST pItem)
{
if (pHead->head) {
pItem->next = pHead->head;
pHead->head->prev = pItem;
} else
pItem->next = NULL;
pItem->prev = NULL;
pHead->head = pItem;
if (!pHead->head)
pHead->head = pItem;
}
void
nxListRemove(PNXLISTHEAD pHead, PNXLIST pItem)
{
if (pItem->next)
pItem->next->prev = pItem->prev;
if (pItem->prev)
pItem->prev->next = pItem->next;
if (pHead->head == pItem)
pHead->head = pItem->next;
if (pHead->tail == pItem)
pHead->tail = pItem->prev;
pItem->next = pItem->prev = NULL;
}
--- NEW FILE: themes.c ---
/*
* Copyright (c) 2003 Century Software, Inc. All Rights Reserved.
*
* This file is part of the PIXIL Operating Environment
*
* The use, copying and distribution of this file is governed by one
* of two licenses, the PIXIL Commercial License, or the GNU General
* Public License, version 2.
*
* Licensees holding a valid PIXIL Commercial License may use this file
* in accordance with the PIXIL Commercial License Agreement provided
* with the Software. Others are governed under the terms of the GNU
* General Public License version 2.
*
* This file may be distributed and/or modified under the terms of the
* GNU General Public License version 2 as published by the Free
* Software Foundation and appearing in the file LICENSE.GPL included
* in the packaging of this file.
*
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING
* THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE.
*
* RESTRICTED RIGHTS LEGEND
*
* Use, duplication, or disclosure by the government is subject to
* restriction as set forth in paragraph (b)(3)(b) of the Rights in
* Technical Data and Computer Software clause in DAR 7-104.9(a).
*
* See http://www.pixil.org/gpl/ for GPL licensing
* information.
*
* See http://www.pixil.org/license.html or
* email cetsales at centurysoftware.com for information about the PIXIL
* Commercial License Agreement, or if any conditions of this licensing
* are not clear to you.
*/
/* VERY SUPER SECRET */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <nano-X.h>
#include "nanowm.h"
#include "themes.h"
#include "config.h"
static theme_t *activeTheme = 0;
static void
getWidgetWidth(theme_t * theme, int item, int state, int *minw, int *maxw)
{
component_t *component = &theme->components[GET_COMPONENT(item)];
widget_t *widget = component->widgets[GET_WIDGET(item)];
if (minw)
*minw = widget->width.min;
if (maxw)
*maxw = widget->width.max;
}
static void
getWidgetHeight(theme_t * theme, int item, int state, int *minh, int *maxh)
{
component_t *component = &theme->components[GET_COMPONENT(item)];
widget_t *widget = component->widgets[GET_WIDGET(item)];
if (minh)
*minh = widget->height.min;
if (maxh)
*maxh = widget->height.max;
}
static void
getWidgetColor(theme_t * theme, int item, int s,
GR_COLOR * fgcolor, GR_COLOR * bgcolor)
{
component_t *component = &theme->components[GET_COMPONENT(item)];
widget_t *widget = component->widgets[GET_WIDGET(item)];
widget_state_t *state = &widget->states[s];
/* If the state isn't set, then default to active (active must exist) */
if (!state->flags)
state = &widget->states[STATE_ACTIVE];
if (bgcolor)
*bgcolor = state->bgcolor;
if (fgcolor)
*fgcolor = state->fgcolor;
}
static void
drawWidget(GR_WINDOW_ID id, GR_GC_ID gc,
theme_t * theme, int item, int s, int x, int y, int w, int h)
{
component_t *component;
widget_t *widget;
widget_state_t *state;
if (!theme) {
error("Invalid theme specified to drawWidget()\n");
return;
}
if (GET_COMPONENT(item) >= THEME_COMPONENT_COUNT) {
warning("Component %d does not exist in the current theme\n",
GET_COMPONENT(item));
return;
}
component = &theme->components[GET_COMPONENT(item)];
if (!component->widgets) {
warning("The current theme has no active widgets\n",
GET_COMPONENT(item));
return;
}
widget = component->widgets[GET_WIDGET(item)];
if (!widget) {
warning("Widget %d does not exist in the current theme\n", item);
return;
}
state = &widget->states[s];
/* If the state isn't set, then default to active (active must exist) */
if (!state->flags)
state = &widget->states[STATE_ACTIVE];
if (state->image && !state->imageid) {
GR_IMAGE_ID image;
GR_IMAGE_INFO info;
char *filename =
alloca(strlen(wm_getDir(DESKTOP_THEMEDIR)) +
strlen(state->image) + 2);
sprintf(filename, "%s/%s", wm_getDir(DESKTOP_THEMEDIR), state->image);
image = GrLoadImageFromFile(filename, 0);
if (image) {
GrGetImageInfo(image, &info);
state->imageWidth = info.width;
state->imageHeight = info.height;
state->imageid =
GrNewPixmap(state->imageWidth, state->imageHeight, 0);
if (state->imageid) {
GR_GC_ID pgc = GrNewGC();
GrDrawImageToFit(state->imageid, pgc, 0, 0, -1, -1, image);
GrDestroyGC(pgc);
GrFreeImage(image);
}
}
}
if (!state->imageid) {
if (w == -1)
w = widget->width.min;
if (h == -1)
h = widget->height.min;
} else {
if (w == -1)
w = state->imageWidth;
if (h == -1)
h = state->imageHeight;
}
/* If no image is available, go for the default colors */
if (!state->imageid) {
GrSetGCForeground(gc, state->bgcolor);
GrFillRect(id, gc, x, y, w, h);
} else {
int xpos = x, ypos = y;
int left = w;
/* FIXME: Handle both horizontal and vertical tiling */
while (left) {
int cwidth;
if (left < state->imageWidth)
cwidth = left;
else
cwidth = state->imageWidth;
GrCopyArea(id, gc, xpos, ypos, cwidth, h, state->imageid, 0, 0,
MWROP_SRCCOPY);
xpos += cwidth;
left -= cwidth;
}
}
}
/* GLOBAL FUNCTIONS */
void
set_activeTheme(theme_t * theme)
{
activeTheme = theme;
}
inline theme_t *
get_activeTheme(void)
{
return (activeTheme);
}
static void
drawTitlebar(theme_t * theme, GR_DRAW_ID id, GR_GC_ID gc, int w, int h,
GR_CHAR * title, GR_BOOL active, GR_WM_PROPS props)
{
int themeState = active ? STATE_ACTIVE : STATE_INACTIVE;
int x = 0, y = 0;
int captionWidth = 0;
int closeWidth = 0;
int paddingWidth = 0;
/* Calculate the various sizes */
if (title != 0) {
int strw, strh, strb;
int minw, maxw;
getWidgetWidth(theme, TITLEBAR_WIDGET_CAPTION, themeState, &minw,
&maxw);
GrSetGCFont(gc, theme->font);
GrGetGCTextSize(gc, title, -1, GR_TFTOP, &strw, &strh, &strb);
/* Now, figure out the size */
if (strw < minw)
captionWidth = minw;
else if (strw > maxw)
captionWidth = maxw;
else
captionWidth = strw + 5; /* Padding */
}
/* Close box */
if ((props & GR_WM_PROPS_CLOSEBOX) == GR_WM_PROPS_CLOSEBOX) {
int minw, maxw;
getWidgetWidth(theme, TITLEBAR_WIDGET_CLOSEBUTTON, themeState, &minw,
&maxw);
closeWidth = minw;
}
paddingWidth = w - (captionWidth + closeWidth);
if (title != 0) {
GR_COLOR fgcolor;
getWidgetColor(theme, TITLEBAR_WIDGET_CAPTION, themeState, &fgcolor,
0);
drawWidget(id, gc, theme, TITLEBAR_WIDGET_CAPTION, themeState, x, y,
captionWidth, -1);
GrSetGCForeground(gc, fgcolor);
GrSetGCUseBackground(gc, GR_FALSE);
/* FIXME: Text pos should be configurable */
GrText(id, gc, x + 4, y, title, -1, GR_TFASCII | GR_TFTOP);
}
if (props & GR_WM_PROPS_CLOSEBOX)
drawWidget(id, gc, theme, TITLEBAR_WIDGET_CLOSEBUTTON, themeState,
x + w - closeWidth, y, closeWidth, -1);
if (paddingWidth)
drawWidget(id, gc, theme, TITLEBAR_WIDGET_TITLEBAR, themeState,
x + captionWidth, y, paddingWidth, -1);
}
static void
drawBorder(theme_t * theme, GR_DRAW_ID id, GR_GC_ID gc, int cw, int ch,
GR_BOOL active, GR_WM_PROPS style, int item)
{
int themeState = active ? STATE_ACTIVE : STATE_INACTIVE;
int x, y, w, h;
int tbarh;
int widget = COMPONENT_WIDGET(item, 0);
if ((style & GR_WM_PROPS_CAPTION) == GR_WM_PROPS_CAPTION)
getWidgetHeight(theme, TITLEBAR_WIDGET_CAPTION, 0, 0, &tbarh);
else
tbarh = 0;
switch (item) {
case COMPONENT_TOP:
x = 0;
y = 0;
w = cw - (theme->client.left - theme->client.right);
h = theme->client.top;
break;
case COMPONENT_LEFT:
x = 0;
y = tbarh;
w = theme->client.left;
h = ch - tbarh;
break;
case COMPONENT_RIGHT:
x = cw - theme->client.right;
y = tbarh;
w = theme->client.right;
h = ch - tbarh;
break;
case COMPONENT_BOTTOM:
x = theme->client.left;
y = ch - theme->client.right;
w = cw - (theme->client.left - theme->client.right);
h = theme->client.bottom;
break;
}
drawWidget(id, gc, theme, widget, themeState, x, y, w, h);
}
void
themeDrawContainer(GR_DRAW_ID id, int w, int h, GR_CHAR * title,
GR_BOOL active, GR_WM_PROPS props, theme_t * theme)
{
GR_GC_ID gc;
gc = GrNewGC();
/* first draw the titlebar (if we have it) */
if ((props & GR_WM_PROPS_CAPTION) == GR_WM_PROPS_CAPTION) {
drawTitlebar(theme, id, gc, w, h, title, active, props);
} else {
drawBorder(theme, id, gc, w, h, active, props, COMPONENT_TOP);
}
/* Now draw the other three borders */
if ((props & GR_WM_PROPS_BORDER) == GR_WM_PROPS_BORDER) {
drawBorder(theme, id, gc, w, h, active, props, COMPONENT_LEFT);
drawBorder(theme, id, gc, w, h, active, props, COMPONENT_RIGHT);
drawBorder(theme, id, gc, w, h, active, props, COMPONENT_BOTTOM);
}
GrDestroyGC(gc);
}
void
themeContainerSize(theme_t * theme,
GR_WM_PROPS style, int clientw, int clienth,
int *xoff, int *yoff, int *containerw, int *containerh)
{
int tbarh;
if ((style & GR_WM_PROPS_CAPTION) == GR_WM_PROPS_CAPTION)
getWidgetHeight(theme, TITLEBAR_WIDGET_CAPTION, 0, 0, &tbarh);
else
tbarh = theme->client.top;
if ((style & GR_WM_PROPS_BORDER) == GR_WM_PROPS_BORDER) {
*containerw = clientw + theme->client.left + theme->client.right;
*containerh = clienth + tbarh + theme->client.bottom;
*xoff = theme->client.left;
} else {
*containerw = clientw;
*containerh = clienth + tbarh;
*xoff = 0;
}
*yoff = tbarh;
}
void
themeClientSize(theme_t * theme, GR_WM_PROPS style, int containerw,
int containerh, int *clientw, int *clienth)
{
int tbarh;
if ((style & GR_WM_PROPS_CAPTION) == GR_WM_PROPS_CAPTION)
getWidgetHeight(theme, TITLEBAR_WIDGET_CAPTION, 0, 0, &tbarh);
else
tbarh = theme->client.top;
if ((style & GR_WM_PROPS_BORDER) == GR_WM_PROPS_BORDER) {
*clientw = containerw - (theme->client.left + theme->client.right);
*clienth = containerh - (tbarh + theme->client.bottom);
} else {
*clientw = containerw;
*clienth = containerh - tbarh;
}
}
static void
themeGetWidgetOffset(theme_t * theme, GR_WM_PROPS style,
int index, int w, int h, int *x, int *y)
{
int cl, cr, ct, cb;
component_t *component = &theme->components[GET_COMPONENT(index)];
widget_t *widget = component->widgets[GET_WIDGET(index)];
if ((style & GR_WM_PROPS_BORDER) == GR_WM_PROPS_BORDER) {
cr = w - theme->client.right;
cl = theme->client.left;
if ((style & GR_WM_PROPS_CAPTION) == GR_WM_PROPS_CAPTION)
ct = 0;
else
ct = theme->client.top;
cb = h - theme->client.bottom;
} else {
cl = 0;
cr = w;
ct = 0;
cb = h;
}
switch (index) {
case TITLEBAR_WIDGET_CLOSEBUTTON:
*x = cr - widget->width.min;
*y = ct;
break;
}
}
static GR_BOOL
PtInRect(GR_RECT * prc, GR_SIZE x, GR_SIZE y)
{
return (x >= prc->x && x < (prc->x + prc->width) &&
y >= prc->y && y < (prc->y + prc->height));
}
int
widgetCheckBounds(theme_t * theme, GR_WM_PROPS style, int index, int x, int y,
int w, int h)
{
component_t *component = &theme->components[GET_COMPONENT(index)];
widget_t *widget = component->widgets[GET_WIDGET(index)];
int xpos, ypos;
themeGetWidgetOffset(theme, style, index, w, h, &xpos, &ypos);
if (widget->hotspot.w || widget->hotspot.h) {
GR_RECT r;
r.x = xpos + widget->hotspot.x;
r.y = ypos + widget->hotspot.y;
r.width = widget->hotspot.w;
r.height = widget->hotspot.h;
return (PtInRect(&r, x, y));
}
return (0);
}
int
themeCheckBounds(theme_t * theme, GR_WM_PROPS style, int index, int x, int y,
int w, int h)
{
GR_RECT r;
int th;
switch (index) {
case COMPONENT_TITLEBAR:
getWidgetHeight(theme, TITLEBAR_WIDGET_CAPTION, 0, 0, &th);
r.x = 0;
r.y = 0;
r.width = w;
r.height = th;
break;
default:
return (0);
}
return (PtInRect(&r, x, y));
}
--- NEW FILE: sys_menu.h ---
/*
* Copyright (c) 2003 Century Software, Inc. All Rights Reserved.
*
* This file is part of the PIXIL Operating Environment
*
* The use, copying and distribution of this file is governed by one
* of two licenses, the PIXIL Commercial License, or the GNU General
* Public License, version 2.
*
* Licensees holding a valid PIXIL Commercial License may use this file
* in accordance with the PIXIL Commercial License Agreement provided
* with the Software. Others are governed under the terms of the GNU
* General Public License version 2.
*
* This file may be distributed and/or modified under the terms of the
* GNU General Public License version 2 as published by the Free
* Software Foundation and appearing in the file LICENSE.GPL included
* in the packaging of this file.
*
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING
* THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE.
*
* RESTRICTED RIGHTS LEGEND
*
* Use, duplication, or disclosure by the government is subject to
* restriction as set forth in paragraph (b)(3)(b) of the Rights in
* Technical Data and Computer Software clause in DAR 7-104.9(a).
*
* See http://www.pixil.org/gpl/ for GPL licensing
* information.
*
* See http://www.pixil.org/license.html or
* email cetsales at centurysoftware.com for information about the PIXIL
* Commercial License Agreement, or if any conditions of this licensing
* are not clear to you.
*/
#ifndef SYS_MENU_H
#define SYS_MENU_H
#include <nano-X.h>
#define MENU_DIR_DOWN 0x01
#define MENU_DIR_UP 0x02
#define MENU_DIR_BEST 0x03
#define MENU_TYPE_REGULAR 0x00
#define MENU_TYPE_SEP 0x01
#define MENU_TYPE_CHECK 0x02
#define MENU_TYPE_APP 0x03
#define MENU_TYPE_CMENU 0x04
#define MENU_TYPE_END 0x05
typedef void (MENU_CALLBACK) (void *);
typedef struct
{
char value[24];
int type;
void *action;
void *cbdata;
GR_BOOL checked;
GR_IMAGE_ID icon;
}
wm_menu_t;
GR_BOOL system_menu_active();
int handle_system_menu(GR_EVENT * ep);
int open_system_menu(GR_WINDOW_ID parent, int x, int y,
int dir, wm_menu_t * menudata);
wm_menu_t *create_system_menu(int);
void destroy_system_menu(wm_menu_t *);
inline void sys_menu_add_item(wm_menu_t *, int, char *,
void *, void *, int, GR_IMAGE_ID iid);
/* Defined in virtwin.c */
wm_menu_t *create_catagory_menu(int index, char *name);
/* Defined in apps.c */
int create_apps_menu(wm_menu_t **);
/* Macros that abstract creating menu items */
#define ADD_SYS_MENU_REGULAR(ptr, value, action, data, icon) \
(sys_menu_add_item(ptr, MENU_TYPE_REGULAR, (char *) value, (void *) action, (void *) data, 0, icon))
#define ADD_SYS_MENU_SEP(ptr) (sys_menu_add_item(ptr, MENU_TYPE_SEP, 0, 0, 0, 0, 0))
#define ADD_SYS_MENU_CHECK(ptr, value, action, data, checked) \
(sys_menu_add_item(ptr, MENU_TYPE_CHECK, (char *) value, (void *) action, (void *) data, checked, 0))
#define ADD_SYS_MENU_APP(ptr, value, path, icon) \
(sys_menu_add_item(ptr, MENU_TYPE_APP, (char *) value, (void *) path, 0, 0, icon))
#define ADD_SYS_MENU_CMENU(ptr, value, menu) \
(sys_menu_add_item(ptr, MENU_TYPE_CMENU, (char *) value, (void *) menu, 0, 0, 0))
#define ADD_SYS_MENU_END(ptr) (sys_menu_add_item(ptr, MENU_TYPE_END, 0, 0, 0, 0,0))
#endif
--- NEW FILE: powerman.c ---
/*
* Copyright (c) 2003 Century Software, Inc. All Rights Reserved.
*
* This file is part of the PIXIL Operating Environment
*
* The use, copying and distribution of this file is governed by one
* of two licenses, the PIXIL Commercial License, or the GNU General
* Public License, version 2.
*
* Licensees holding a valid PIXIL Commercial License may use this file
* in accordance with the PIXIL Commercial License Agreement provided
* with the Software. Others are governed under the terms of the GNU
* General Public License version 2.
*
* This file may be distributed and/or modified under the terms of the
* GNU General Public License version 2 as published by the Free
* Software Foundation and appearing in the file LICENSE.GPL included
* in the packaging of this file.
*
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING
* THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE.
*
* RESTRICTED RIGHTS LEGEND
*
* Use, duplication, or disclosure by the government is subject to
* restriction as set forth in paragraph (b)(3)(b) of the Rights in
* Technical Data and Computer Software clause in DAR 7-104.9(a).
*
* See http://www.pixil.org/gpl/ for GPL licensing
* information.
*
* See http://www.pixil.org/license.html or
* email cetsales at centurysoftware.com for information about the PIXIL
* Commercial License Agreement, or if any conditions of this licensing
* are not clear to you.
*/
#include <pixil_config.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <nano-X.h>
#include <pixlib/pixlib.h>
#ifdef CONFIG_PAR
#include <par/par.h>
#endif
#include "powerman.h"
static GR_TIMER_ID pm_timer_id = 0;
struct {
struct {
int power;
int bl_timeout;
int bl_level;
int bl_set;
int power_timeout;
} ac, bat;
} settings;
static int pm_bl_state = 1;
static void pm_do_callback(int type, void *data);
GR_TIMER_ID pm_get_timer_id(void) { return pm_timer_id; }
static void set_pm_timer(int timeout) {
if (pm_timer_id) return;
pm_timer_id = GrCreateTimer(1, timeout);
scrtop_register_timer(pm_timer_id, pm_suspend);
}
static void stop_bl_timer(void) {
GrSetScreenSaverTimeout(0);
}
/* We have two levels of timers. The first level is the backlight,
triggered after N seconds of inactivity (aka the SCREENSAVER)
The second is the power managment timer, which is started after
the screensaver fires. The interesting here is if the
*/
static void pm_first_timer(void) {
int state = pix_pwr_onBattery();
int timeout = 0;
if (state == AC_ON) {
if (settings.ac.bl_timeout > 0)
timeout = settings.ac.bl_timeout;
else if (settings.ac.power && settings.ac.power_timeout > 0)
timeout = settings.ac.power_timeout;
}
else if (state == BAT_ON) {
if (settings.ac.bl_timeout > 0)
timeout = settings.bat.bl_timeout;
else if (settings.bat.power && settings.bat.power_timeout > 0)
timeout = settings.bat.power_timeout;
}
GrSetScreenSaverTimeout(timeout);
}
static void pm_second_timer(void) {
int state = pix_pwr_onBattery();
int timeout = -1;
if (pm_timer_id) return;
if (state == AC_ON) {
if (settings.ac.power && settings.ac.power_timeout > 0) {
timeout = settings.ac.power_timeout;
timeout -= (settings.ac.bl_timeout > 0) ? settings.ac.bl_timeout : 0;
}
}
else if (state == BAT_ON) {
if (settings.bat.power && settings.bat.power_timeout > 0) {
timeout = settings.bat.power_timeout;
timeout -= (settings.bat.bl_timeout > 0) ? settings.bat.bl_timeout : 0;
}
}
/* If no timeout, then don't bother */
/* If the timeout is zero, then suspend immediately */
/* Otherwise, set the timer to fire at the appropriate time */
if (timeout == -1) return;
else if (timeout == 0)
pm_suspend();
else
pm_timer_id = GrCreateTimer(1, timeout);
}
static void pm_stop_timer(void) {
if (pm_timer_id) GrDestroyTimer(pm_timer_id);
scrtop_unregister_timer(pm_timer_id);
pm_timer_id = 0;
GrSetScreenSaverTimeout(0);
}
static void
pm_read_settings(void) {
db_handle *db;
db = db_openDB(db_getDefaultDB(), PAR_DB_MODE_RDONLY);
if (!db) return;
memset(&settings, 0, sizeof(settings));
par_getGlobalPref(db, "power", "ac_off", PAR_BOOL,
&settings.ac.power, sizeof(settings.ac.power));
par_getGlobalPref(db, "power", "ac_offval", PAR_INT,
&settings.ac.power_timeout, sizeof(settings.ac.power_timeout));
par_getGlobalPref(db, "backlight", "ac_wakeup", PAR_BOOL,
&settings.ac.bl_set, sizeof(settings.ac.bl_set));
par_getGlobalPref(db, "backlight", "ac_timeout", PAR_INT,
&settings.ac.bl_timeout, sizeof(settings.ac.bl_timeout));
par_getGlobalPref(db, "backlight", "ac_level", PAR_INT,
&settings.ac.bl_level, sizeof(settings.ac.bl_level));
par_getGlobalPref(db, "power", "bat_off", PAR_BOOL,
&settings.bat.power, sizeof(settings.bat.power));
par_getGlobalPref(db, "power", "bat_offval", PAR_INT,
&settings.bat.power_timeout, sizeof(settings.bat.power_timeout));
par_getGlobalPref(db, "backlight", "bat_wakeup", PAR_BOOL,
&settings.bat.bl_set, sizeof(settings.bat.bl_set));
par_getGlobalPref(db, "backlight", "bat_timeout", PAR_INT,
&settings.bat.bl_timeout, sizeof(settings.bat.bl_timeout));
par_getGlobalPref(db, "backlight", "bat_level", PAR_INT,
&settings.bat.bl_level, sizeof(settings.bat.bl_level));
db_closeDB(db);
}
/* Called to reload the settings and restart the timers */
void pm_reload(void) {
pm_stop_timer(); /* Stop both timers */
pm_read_settings();
pm_first_timer(); /* Set up the first tier timer */
}
void
pm_init(void) {
pm_read_settings();
pm_first_timer(); /* Set up the first tier timer */
/* Start off in the default state */
pm_backlight(pm_bl_state);
}
void
pm_suspend(void) {
int state = pix_pwr_onBattery();
printf("Suspending the screentop - see you on the flip side\n");
pm_stop_timer(); /* Stop both timers */
pix_pwr_suspend(); /* At this point the power should be suspended */
pm_first_timer(); /* Start the first tier timer again */
}
void pm_backlight(int mode) {
int state = pix_pwr_onBattery();
int level, blto, max, val;
switch(state) {
case AC_ON:
level = settings.ac.bl_level;
blto = settings.ac.bl_timeout;
break;
case BAT_ON:
level = settings.bat.bl_level;
blto = settings.ac.bl_timeout;
break;
default: /* No APM or error */
goto do_callback;
}
max = pix_bl_getmxval();
val = (((level * max) << 4) / 100) >> 4;
if (mode == BL_ON) {
if (blto > 0) pm_first_timer();
}
else if (mode == BL_OFF) {
stop_bl_timer();
}
/* Set the value */
pix_bl_ctrl(mode, val);
do_callback:
pm_bl_state = mode;
pm_do_callback(PM_CALLBACK_BL, (void *) mode);
}
void pm_bl_toggle(void) {
pm_backlight(!pm_bl_state);
}
int pm_get_bl_state(void) { return pm_bl_state; }
/* Fired when the screen saver timer expires */
void pm_bltimer_off(void) {
int state = pix_pwr_onBattery();
if (state == -1) return;
if (state == AC_ON && settings.ac.bl_timeout <= 0)
return;
if (state == BAT_ON && settings.bat.bl_timeout <= 0)
return;
pm_backlight(0); /* Turn off the backlight */
pm_second_timer(); /* Set up the second tier timer */
}
/* Fired when the screen saver timer returns */
void pm_bltimer_on(void) {
int state = pix_pwr_onBattery();
/* Stop the second tier timer */
if (pm_timer_id) {
GrDestroyTimer(pm_timer_id);
scrtop_unregister_timer(pm_timer_id);
pm_timer_id = 0;
}
if (state == -1) return;
if (pm_get_bl_state()) return; /* Its already on */
if (state == AC_ON && !settings.ac.bl_set)
return;
if (state == AC_ON && !settings.bat.bl_set)
return;
pm_backlight(1); /* Turn it back on */
}
struct pm_cb_list {
pm_callback cb;
struct pm_cb_list *next;
};
struct pm_cb_list *cblist[1] = {0};
/* Set up a function to be called when a particular power management event happens */
void pm_register_callback(int type, pm_callback cb) {
struct pm_cb_list *l = (struct pm_cb_list *) calloc(1, sizeof(struct pm_cb_list));
l->cb = cb;
if (!cblist[type])
cblist[type] = l;
else {
struct pm_cb_list *a = cblist[type];
for(; a->next; a=a->next);
a->next = l;
}
}
void pm_unregister_callback(int type, pm_callback cb) {
struct pm_cb_list *l = cblist[type];
struct pm_cb_list *prev = 0;
for(; l; l = l->next) {
if (l->cb == cb) {
if (prev) prev->next = l->next;
else cblist[type] = l->next;
free(l);
return;
}
prev = l;
}
}
/* Actually do the callbacks based on the given type and the given data */
static void pm_do_callback(int type, void *data) {
struct pm_cb_list *l = cblist[type];
for(; l; l = l->next)
if (l->cb) l->cb(type, data);
}
--- NEW FILE: root.c ---
/*
* Copyright (c) 2003 Century Software, Inc. All Rights Reserved.
*
* This file is part of the PIXIL Operating Environment
*
* The use, copying and distribution of this file is governed by one
* of two licenses, the PIXIL Commercial License, or the GNU General
* Public License, version 2.
*
* Licensees holding a valid PIXIL Commercial License may use this file
* in accordance with the PIXIL Commercial License Agreement provided
* with the Software. Others are governed under the terms of the GNU
* General Public License version 2.
*
* This file may be distributed and/or modified under the terms of the
* GNU General Public License version 2 as published by the Free
* Software Foundation and appearing in the file LICENSE.GPL included
* in the packaging of this file.
*
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING
* THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE.
*
* RESTRICTED RIGHTS LEGEND
*
* Use, duplication, or disclosure by the government is subject to
* restriction as set forth in paragraph (b)(3)(b) of the Rights in
* Technical Data and Computer Software clause in DAR 7-104.9(a).
*
* See http://www.pixil.org/gpl/ for GPL licensing
* information.
*
* See http://www.pixil.org/license.html or
* email cetsales at centurysoftware.com for information about the PIXIL
* Commercial License Agreement, or if any conditions of this licensing
* are not clear to you.
*/
#include <pixil_config.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pixlib/pixlib.h>
#include "nano-X.h"
#include "apps.h"
#include "nanowm.h"
#include "config.h"
#include "categories.h"
#ifdef CONFIG_PIXILWM_MENUS
#include "sys_menu.h"
#endif
/* External functions called from within */
static GR_SCREEN_INFO si;
static void root_wndproc(win * window, GR_EVENT * ep);
static void root_prepare_background(void);
static void root_redraw();
#ifdef CONFIG_PIXILWM_MENUS
static void
root_reset(void *foo)
{
/* wm_load_config_settings(); */
root_prepare_background();
root_redraw();
}
static wm_menu_t *root_sys_menu = 0;
static wm_menu_t *apps_sys_menu = 0;
void close_nxscrtop(int);
static void
shutdown_cb(void *foo)
{
close_nxscrtop(0);
}
#endif
void
root_create(void)
{
GR_SCREEN_INFO si;
GR_WM_PROPERTIES props;
#ifdef CONFIG_PIXILWM_MENUS
int i = 0;
#endif
/* add root window */
add_window(GR_ROOT_WINDOW_ID, GR_ROOT_WINDOW_ID, 0, root_wndproc);
/*
* update and child update events must be set to hook
* top level window mappings
*/
GrSelectEvents(GR_ROOT_WINDOW_ID, GR_EVENT_MASK_CHLD_UPDATE |
GR_EVENT_MASK_EXPOSURE | GR_EVENT_MASK_BUTTON_DOWN |
GR_EVENT_MASK_FDINPUT |
GR_EVENT_MASK_SCREENSAVER | GR_EVENT_MASK_TIMER |
GR_EVENT_MASK_KEY_DOWN | GR_EVENT_MASK_KEY_UP);
/* Platform specfic stuff */
/* Ipaq: Grab the "power button" */
#ifdef CONFIG_PLATFORM_IPAQ
GrGrabKey(GR_ROOT_WINDOW_ID, MWKEY_SUSPEND, GR_GRAB_HOTKEY_EXCLUSIVE);
#endif
/* Zaurus: Grab the Cancel button */
#ifdef CONFIG_PLATFORM_ZAURUS
GrGrabKey(GR_ROOT_WINDOW_ID, MWKEY_ESCAPE, GR_GRAB_HOTKEY_EXCLUSIVE);
#endif
/* Cache the background for speed */
root_prepare_background();
GrGetScreenInfo(&si);
/* Step 1 - Get inital variables for the workspace width and height */
setWorkspace(si.ws_width, si.ws_height);
/* Step 2 - Make the input button */
createInputButton();
/* Step 3 - create the home button which aleways exists */
home_create();
#ifdef NOTUSED
date_create();
#ifdef CONFIG_PIXILWM_PM
backlight_create();
#endif
/* JHC - quick hack - we only bring up the battery if
APM is available
*/
#ifdef CONFIG_PIXILWM_PM
if (!access("/proc/apm", R_OK))
battery_create();
#endif
#endif
/* Step 4 - Create the category browser */
category_setCurrent(0);
#ifdef VIRTUAL_WINDOWS
create_categoryBrowser();
#endif
/* Step 5 - Set up the root window and get ready to draw! */
props.flags = GR_WM_FLAGS_BACKGROUND;
props.background = wm_getColor(WM_BGCOLOR);
GrSetWMProperties(GR_ROOT_WINDOW_ID, &props);
root_redraw();
#ifdef CONFIG_PIXILWM_MENUS
/* Step 6 - Create the system menu (if applicable) */
root_sys_menu = create_system_menu(6);
if (create_apps_menu(&apps_sys_menu)) {
ADD_SYS_MENU_CMENU(&root_sys_menu[0], "Quick Run...", apps_sys_menu);
ADD_SYS_MENU_SEP(&root_sys_menu[1]);
i = 2;
} else {
i = 0;
}
ADD_SYS_MENU_REGULAR(&root_sys_menu[i++], "Reset ScreenTop", root_reset,
0, 0);
ADD_SYS_MENU_REGULAR(&root_sys_menu[i++], "About...", 0, 0, 0);
ADD_SYS_MENU_REGULAR(&root_sys_menu[i++], "Shutdown", shutdown_cb, 0, 0);
ADD_SYS_MENU_END(&root_sys_menu[i++]);
#endif
/* Step 7 - There is no step 7 :) */
}
/* The following are special caching */
/* routines to make the background image */
/* rendering run faster */
static GR_IMAGE_ID lastBGImage = 0;
static GR_WINDOW_ID lastBGPixmap = 0;
static int lastBGWidth = 0;
static int lastBGHeight = 0;
static void
root_prepare_background(void)
{
GR_GC_ID gc = GrNewGC();
GR_IMAGE_INFO iinfo;
GR_IMAGE_ID iid;
int style = 0;
int wpactive = wm_getWallpaper(&iid, &style);
int xpos, ypos, wi, hi;
if (!si.rows)
GrGetScreenInfo(&si);
if (!wpactive || lastBGImage == iid)
return;
GrGetImageInfo(iid, &iinfo);
/* Remove the last cached BG */
if (lastBGPixmap)
GrDestroyWindow(lastBGPixmap);
/* Figure out the size of the cached pixmap */
if (style == WALLPAPER_TILED || style == WALLPAPER_FULLSCREEN) {
lastBGPixmap = GrNewPixmap(si.ws_width, si.ws_height, NULL);
lastBGWidth = si.ws_width;
lastBGHeight = si.ws_height;
} else { /* CENTERED */
lastBGPixmap = GrNewPixmap(iinfo.width, iinfo.height, NULL);
lastBGWidth = iinfo.width;
lastBGHeight = iinfo.height;
}
GrSetGCForeground(gc, wm_getColor(WM_BGCOLOR));
GrFillRect(lastBGPixmap, gc, 0, 0, lastBGWidth, lastBGHeight);
lastBGImage = iid;
/* Now draw into the pixmap. If it is fullscreen or centered,
thats trival. Tiled is a little more bad */
switch (style) {
case WALLPAPER_TILED:
for (ypos = 0; ypos < si.ws_height; ypos += iinfo.width)
for (xpos = 0; xpos < si.ws_width; xpos += iinfo.height) {
if (si.ws_width - xpos < iinfo.width)
wi = si.ws_width - xpos;
else
wi = iinfo.width;
if (si.ws_height - ypos < iinfo.height)
hi = si.ws_height - ypos;
else
hi = iinfo.height;
GrDrawImageToFit(lastBGPixmap, gc, xpos, ypos, wi, hi, iid);
}
break;
case WALLPAPER_FULLSCREEN:
case WALLPAPER_CENTERED:
default:
GrDrawImageToFit(lastBGPixmap, gc, 0, 0, -1, -1, iid);
break;
}
GrDestroyGC(gc);
}
static void
root_draw_background(GR_WINDOW_ID wid, GR_REGION_ID r)
{
GR_GC_ID gc = GrNewGC();
GR_IMAGE_ID iid;
int style = 0;
int wpactive = wm_getWallpaper(&iid, &style);
/* Set the clip region */
GrSetGCRegion(gc, r);
if (!si.rows)
GrGetScreenInfo(&si);
/* First, draw the background (if it is visible) */
if (!wpactive || style == WALLPAPER_BOTTOM || style == WALLPAPER_CENTERED
|| !lastBGPixmap) {
GrSetGCForeground(gc, wm_getColor(WM_BGCOLOR));
GrFillRect(wid, gc, 0, 0, si.ws_width, si.ws_height);
}
/* Now draw the wall paper */
if (wpactive && lastBGPixmap) {
int xpos, ypos, wi, hi;
switch (style) {
case WALLPAPER_TILED:
case WALLPAPER_FULLSCREEN:
GrCopyArea(wid, gc, 0, 0, si.ws_width, si.ws_height,
lastBGPixmap, 0, 0, MWROP_SRCCOPY);
break;
case WALLPAPER_BOTTOM:
xpos = (si.ws_width - lastBGWidth) / 2;
ypos = (si.ws_height - lastBGHeight);
wi = lastBGWidth;
hi = lastBGHeight;
GrCopyArea(wid, gc, xpos, ypos, wi, hi,
lastBGPixmap, 0, 0, MWROP_SRCCOPY);
break;
case WALLPAPER_CENTERED:
default:
xpos = (si.ws_width - lastBGWidth) / 2;
ypos = (si.ws_height - lastBGHeight) / 2;
wi = lastBGWidth;
hi = lastBGHeight;
GrCopyArea(wid, gc, xpos, ypos, wi, hi,
lastBGPixmap, 0, 0, MWROP_SRCCOPY);
break;
}
}
GrDestroyGC(gc);
}
static void
root_exposure(win * window, GR_EVENT_EXPOSURE * ep)
{
GR_GC_ID gc = GrNewGC();
GR_REGION_ID r;
GR_RECT rc;
if (!si.rows)
GrGetScreenInfo(&si);
/*
* Create clip region based on exposed rectangle.
* This keeps flicker way down.
*/
r = GrNewRegion();
rc.x = ep->x;
rc.y = ep->y;
rc.width = ep->width;
rc.height = ep->height;
GrUnionRectWithRegion(r, &rc);
GrSetGCRegion(gc, r);
/* draw taskbar */
GrSetGCForeground(gc, wm_getColor(WM_TASKBAR));
GrFillRect(ep->wid, gc, 0, si.ws_height, si.ws_width,
si.vs_height - si.ws_height);
/* draw background (but only the rectangle) */
root_draw_background(ep->wid, r);
/* Draw the current list of icons */
draw_current_iconlist(r);
/* Draw the category browser */
draw_categoryBrowser(r);
GrDestroyGC(gc);
GrDestroyRegion(r);
}
static void
root_redraw()
{
GR_EVENT_EXPOSURE expose;
GR_WINDOW_INFO info;
/* dummy full area expose event */
GrGetWindowInfo(GR_ROOT_WINDOW_ID, &info);
expose.type = GR_EVENT_TYPE_EXPOSURE;
expose.wid = GR_ROOT_WINDOW_ID;
expose.x = 0;
expose.y = 0;
expose.width = info.width;
expose.height = info.height;
root_exposure(0, &expose);
}
inline void
redraw_root_window()
{
root_redraw();
}
#ifdef CONFIG_PLATFORM_ZAURUS
static GR_TIMER_ID suspend_timer_id = 0;
static void handle_zaurus_suspend(void) {
suspend_timer_id = 0;
pm_suspend();
}
#endif
static void
root_wndproc(win * window, GR_EVENT * ep)
{
switch (ep->type) {
case GR_EVENT_TYPE_EXPOSURE:
root_exposure(window, &ep->exposure);
break;
case GR_EVENT_TYPE_KEY_DOWN:
#ifdef CONFIG_PLATFORM_ZAURUS
if (ep->keystroke.ch == MWKEY_ESCAPE) {
/* The key must be pressed for 4 seconds before the suspend happens */
suspend_timer_id = GrCreateTimer(GR_ROOT_WINDOW_ID, 4000);
if (suspend_timer_id)
scrtop_register_timer(suspend_timer_id, handle_zaurus_suspend);
}
#endif
break;
case GR_EVENT_TYPE_KEY_UP:
#ifdef CONFIG_PLATFORM_ZAURUS
/* If the key is released before the timer, then get rid of the timer */
if (ep->keystroke.ch == MWKEY_ESCAPE) {
if (suspend_timer_id) {
GrDestroyTimer(suspend_timer_id);
scrtop_unregister_timer(suspend_timer_id);
suspend_timer_id = 0;
}
}
#endif
#ifdef CONFIG_PLATFORM_IPAQ
if (ep->keystroke.ch == MWKEY_SUSPEND)
pm_suspend();
#endif
break;
#ifdef CONFIG_PIXILWM_MENUS
#ifdef NOTUSED
case GR_EVENT_TYPE_BUTTON_LONG_CLICK:
#endif
case GR_EVENT_TYPE_BUTTON_DOWN:
if (ep->button.buttons & GR_BUTTON_R) {
open_system_menu(GR_ROOT_WINDOW_ID,
ep->button.x, ep->button.y, MENU_DIR_BEST,
root_sys_menu);
}
break;
#endif
}
}
void
root_free_memory()
{
#ifdef CONFIG_PIXILWM_MENUS
destroy_system_menu(root_sys_menu);
#endif
}
--- NEW FILE: sys_menu.c ---
/*
* Copyright (c) 2003 Century Software, Inc. All Rights Reserved.
*
* This file is part of the PIXIL Operating Environment
*
* The use, copying and distribution of this file is governed by one
* of two licenses, the PIXIL Commercial License, or the GNU General
* Public License, version 2.
*
* Licensees holding a valid PIXIL Commercial License may use this file
* in accordance with the PIXIL Commercial License Agreement provided
* with the Software. Others are governed under the terms of the GNU
* General Public License version 2.
*
* This file may be distributed and/or modified under the terms of the
* GNU General Public License version 2 as published by the Free
* Software Foundation and appearing in the file LICENSE.GPL included
* in the packaging of this file.
*
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING
* THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE.
*
* RESTRICTED RIGHTS LEGEND
*
* Use, duplication, or disclosure by the government is subject to
* restriction as set forth in paragraph (b)(3)(b) of the Rights in
* Technical Data and Computer Software clause in DAR 7-104.9(a).
*
* See http://www.pixil.org/gpl/ for GPL licensing
* information.
*
* See http://www.pixil.org/license.html or
* email cetsales at centurysoftware.com for information about the PIXIL
* Commercial License Agreement, or if any conditions of this licensing
* are not clear to you.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MWINCLUDECOLORS
#include <nano-X.h>
#include "nanowm.h"
#include "apps.h"
#include "sys_menu.h"
/* Drawing defines */
#define XPADDING 3
typedef struct wm_menu_st
{
GR_WINDOW_ID wid;
GR_WINDOW_ID pid;
GR_COLOR bcolor;
GR_COLOR tcolor;
wm_menu_t *data;
struct wm_menu_st *next;
unsigned char selected;
unsigned char btndown;
unsigned char icon_align;
}
wm_menu_struct;
static wm_menu_struct *wm_menu_head = 0;
static wm_menu_struct *wm_menu_active = 0;
static GR_FONT_ID sys_fontid = 0;
static int YITEMSIZE = 0;
/* Forward declarations */
void menu_wndproc(win *, GR_EVENT *);
static void close_menu(wm_menu_struct *);
static wm_menu_struct *
create_new_menu(GR_WINDOW_ID parent, wm_menu_t * data,
int x, int y, int dir, GR_COLOR bcolor, GR_COLOR tcolor)
{
int use_icon = 0;
int count = 0;
int xsize = 0, ysize = 0;
win *window;
GR_WINDOW_INFO winfo;
GR_GC_ID gc;
wm_menu_struct *ptr;
if (!data)
return (0);
GrGetWindowInfo(parent, &winfo);
/* Ok, first of all determine the size of the window */
gc = GrNewGC();
GrSetGCFont(gc, sys_fontid);
for (count = 0; data[count].type != MENU_TYPE_END; count++) {
int wi, hi, ba;
if (data[count].icon)
use_icon = 1;
if (data[count].type == MENU_TYPE_SEP)
ysize += 6;
else {
ysize += YITEMSIZE + 2;
GrGetGCTextSize(gc, (void *) data[count].value,
strlen(data[count].value), 0, &wi, &hi, &ba);
if (data[count].icon)
wi += YITEMSIZE;
if (wi > xsize) {
switch (data[count].type) {
case MENU_TYPE_CHECK:
case MENU_TYPE_CMENU:
xsize = wi + 10 + XPADDING;
break;
default:
xsize = wi + (XPADDING * 2);
if (data[count].icon)
xsize += YITEMSIZE;
break;
}
}
}
}
/* Put some padding around it */
xsize += 4;
if (ysize > winfo.height)
return (0);
GrDestroyGC(gc);
/* Now, figure out which direction the sucker should point */
if (dir == MENU_DIR_BEST) {
/* We would prefer to go down, but if there is no room */
if ((winfo.height - y) < ysize)
dir = MENU_DIR_UP;
else
dir = MENU_DIR_DOWN;
}
/* Adjust the X and Y to fit into the screen */
if ((winfo.width - x) < xsize)
x = winfo.width - xsize;
/* Reposition the menu if needed to fit it in the window */
if (dir == MENU_DIR_DOWN) {
if ((winfo.height - y) < ysize)
y = winfo.height - ysize;
} else {
if ((y < ysize))
y = 0;
else
y = y - ysize;
}
/* Ok, lets start allocating some room, eh? */
ptr = (wm_menu_struct *) malloc(sizeof(wm_menu_struct));
if (!ptr)
return (0);
ptr->data = data;
ptr->selected = -1;
ptr->btndown = 0;
ptr->bcolor = bcolor;
ptr->tcolor = tcolor;
ptr->next = 0;
ptr->pid = parent;
ptr->icon_align = use_icon;
/* Now, do the window stuff */
ptr->wid = GrNewWindowEx(GR_WM_PROPS_NODECORATE,
NULL, parent, x, y, xsize, ysize, bcolor);
GrSelectEvents(ptr->wid,
GR_EVENT_MASK_EXPOSURE | GR_EVENT_MASK_BUTTON_DOWN |
GR_EVENT_MASK_BUTTON_UP);
window = add_window(ptr->wid, parent, 0, menu_wndproc);
GrMapWindow(ptr->wid);
return (ptr);
}
/*
* This is the routine that actually handles the drawing for a given
* menu and wid
*/
static void
draw_menu(GR_WINDOW_ID wid, wm_menu_t * data, int selected,
GR_COLOR back, GR_COLOR text, int icon_align)
{
GR_GC_ID gc = GrNewGC();
GR_WINDOW_INFO winfo;
int i, ypos, xpos;
int menu_width;
GrGetWindowInfo(wid, &winfo);
GrRaiseWindow(wid); /* Always raise system menus to the top */
menu_width = winfo.width - 2;
ypos = 0;
/* The main loop */
for (i = 0; data[i].type != MENU_TYPE_END; i++) {
GrSetGCBackground(gc, back);
GrSetGCForeground(gc, text);
/* Now, based on each menu type, do the drawing */
switch (data[i].type) {
case MENU_TYPE_SEP:
/* Seperator line 2 pixels thick spanning entire window */
/* FIXME: This should come out of PAR */
GrSetGCForeground(gc, MWRGB(0x00, 0x66, 0xCC));
GrLine(wid, gc, 2, ypos + 2, winfo.width - 4, ypos + 2);
GrLine(wid, gc, 2, ypos + 4, winfo.width - 4, ypos + 4);
GrSetGCForeground(gc, text);
GrLine(wid, gc, 2, ypos + 3, winfo.width - 4, ypos + 3);
ypos += 6;
break;
case MENU_TYPE_CHECK:
/* Check box with a indicator before the text */
#ifdef NOTUSED
if (data[i].checked == GR_TRUE)
GrFillEllipse(wid, gc, 5, ypos + (YITEMSIZE / 2), 3, 3); /* Filled */
else
GrEllipse(wid, gc, 5, ypos + (YITEMSIZE / 2), 3, 3); /* Empty */
#endif
if (data[i].checked == GR_TRUE)
GrFillRect(wid, gc, 4, ypos + 6, 4, 4);
#ifdef NOTUSED
else
GrRect(wid, gc, 4, ypos + 6, 4, 4);
#endif
GrSetGCFont(gc, sys_fontid);
GrText(wid, gc, 10, ypos + 1, data[i].value, -1, GR_TFTOP);
ypos += YITEMSIZE + 2;
break;
case MENU_TYPE_CMENU:
{
GR_POINT points[] = {
{winfo.width - 10, ypos + 2}
,
{winfo.width - 3, ypos + (YITEMSIZE / 2)}
,
{winfo.width - 10, ypos + YITEMSIZE - 1}
};
/* The parent of a cascading menu. Arrow after the text */
GrSetGCFont(gc, sys_fontid);
GrText(wid, gc, 1 + XPADDING, ypos + 1,
data[i].value, -1, GR_TFTOP);
GrSetGCForeground(gc, text);
GrFillPoly(wid, gc, 3, points);
GrSetGCForeground(gc, GRAY);
GrPoly(wid, gc, 3, points);
ypos += YITEMSIZE + 2;
break;
}
case MENU_TYPE_APP:
case MENU_TYPE_REGULAR: /* These differ only by callback */
if (i == selected) {
GrFillRect(wid, gc, 1, ypos, winfo.width - 2, YITEMSIZE + 1);
GrSetGCForeground(gc, back);
GrSetGCBackground(gc, text);
}
if (icon_align)
xpos = YITEMSIZE + XPADDING;
else
xpos = 1 + XPADDING;
if (data[i].icon)
GrDrawImageToFit(wid, gc, 1, ypos + 1, YITEMSIZE,
YITEMSIZE, data[i].icon);
GrSetGCFont(gc, sys_fontid);
GrText(wid, gc, xpos, ypos + 1, data[i].value, -1, GR_TFTOP);
ypos += YITEMSIZE + 2;
break;
}
}
/* Finally, draw a border around the window */
GrSetGCForeground(gc, text);
GrRect(wid, gc, 0, 0, winfo.width, winfo.height);
GrDestroyGC(gc);
}
static int
get_item_pos(wm_menu_t * data, int selected)
{
int ypos = 0;
int i;
for (i = 0; data[i].type != MENU_TYPE_END; i++) {
if (i == selected)
return (ypos);
switch (data[i].type) {
case MENU_TYPE_SEP:
ypos += 6;
break;
default:
ypos += YITEMSIZE + 2;
}
}
return (0);
}
static int
check_mouse_pos(wm_menu_t * data, int x, int y)
{
int i;
int ypos = 0;
for (i = 0; data[i].type != MENU_TYPE_END; i++)
switch (data[i].type) {
case MENU_TYPE_SEP:
/* Ignore seperators */
ypos += 6;
break;
case MENU_TYPE_CMENU:
case MENU_TYPE_APP:
case MENU_TYPE_REGULAR:
case MENU_TYPE_CHECK:
/* All these have the same ysize */
if (y >= ypos && y <= ypos + YITEMSIZE)
return (i);
ypos += YITEMSIZE + 2;
break;
}
return (-1);
}
static void
expose_menu(GR_WINDOW_ID wid)
{
wm_menu_struct *menu_ptr;
if (!wm_menu_head)
return;
menu_ptr = wm_menu_head;
/* Now go through and draw all of the active menus */
while (menu_ptr) {
/* Only draw those menus that require it */
if (menu_ptr->wid == wid)
draw_menu(menu_ptr->wid, menu_ptr->data, menu_ptr->selected,
menu_ptr->bcolor, menu_ptr->tcolor,
menu_ptr->icon_align);
menu_ptr = menu_ptr->next;
}
}
static int
menu_buttonup(GR_EVENT_BUTTON * ep)
{
int i;
void *data;
GR_WINDOW_INFO winfo;
MENU_CALLBACK *cb;
int ypos;
if (!wm_menu_active)
return (0);
if (!wm_menu_active->btndown)
return (0);
/* Reset the buttondown flag */
wm_menu_active->btndown = 0;
/* Get the current menu selection */
i = wm_menu_active->selected;
#ifdef SYSTEM_SOUNDS
if (wm_menu_active->data[i].type != MENU_TYPE_SEP)
play_sound(SOUND_CLICKED);
#endif
switch (wm_menu_active->data[i].type) {
case MENU_TYPE_REGULAR:
case MENU_TYPE_CHECK:
/* Do a callback */
cb = (MENU_CALLBACK *) wm_menu_active->data[i].action;
data = wm_menu_active->data[i].cbdata;
/* Close the menu before we do the callback, just to be safe */
close_menu(wm_menu_head);
if (cb)
cb(data);
return (1);
case MENU_TYPE_APP:
/* Do an app */
if (wm_menu_active->data[i].action) {
APP *app;
/* Editorial: I don't like this, but it seems to be the best way */
if (!
(app =
find_app_path((char *) wm_menu_active->data[i].action)))
app =
apps_add_onetime((char *) wm_menu_active->data[i].action);
if (app)
launch_application(app);
}
close_menu(wm_menu_head);
return (1);
case MENU_TYPE_CMENU:
/* Do a new child menu */
/* Get some stats */
GrGetWindowInfo(wm_menu_active->wid, &winfo);
ypos = get_item_pos(wm_menu_active->data, wm_menu_active->selected);
/* Make a new menu! */
wm_menu_active->next =
create_new_menu(wm_menu_active->pid,
(wm_menu_t *) wm_menu_active->data[i].action,
winfo.x + winfo.width + 2, winfo.y + ypos,
MENU_DIR_BEST, WHITE, MWRGB(0x00, 0x66, 0xCC));
if (wm_menu_active->next)
wm_menu_active = wm_menu_active->next;
return (1);
}
return (0);
}
static int
menu_buttondown(GR_EVENT_BUTTON * ep)
{
int ret;
int backtrack = 0;
if (!wm_menu_active)
return (0);
if (ep->wid != wm_menu_active->wid) {
wm_menu_struct *ptr = wm_menu_head;
/* Look to see if the click was anywhere in the tree */
while (ptr) {
if (ptr->wid == ep->wid) {
close_menu(ptr->next);
wm_menu_active = ptr;
backtrack = 1;
break;
}
ptr = ptr->next;
}
if (!ptr) {
/* Close all of the menus */
close_menu(wm_menu_head);
return (1);
}
}
ret = check_mouse_pos(wm_menu_active->data, ep->x, ep->y);
if (ret != -1 && !backtrack) {
wm_menu_active->selected = ret;
wm_menu_active->btndown = 1;
expose_menu(wm_menu_active->wid);
}
return (1);
}
static void
close_menu(wm_menu_struct * ptr)
{
wm_menu_struct *mptr = wm_menu_head;
wm_menu_struct *pptr = 0;
if (!ptr && !wm_menu_head)
return;
mptr = wm_menu_head;
while (mptr && mptr != ptr) {
pptr = mptr;
mptr = mptr->next;
}
if (!mptr) /* Couldn't find it! */
return;
if (pptr) {
pptr->next = 0;
wm_menu_active = pptr;
} else {
wm_menu_head = 0;
wm_menu_active = 0;
}
while (mptr) {
win *window;
/* If we didn't allocate it, why do we try to free it? */
/* if (mptr->data)
free(mptr->data);
*/
window = find_window(mptr->wid);
remove_window(window);
GrDestroyWindow(mptr->wid);
pptr = mptr;
mptr = mptr->next;
free(pptr);
}
}
int
handle_system_menu(GR_EVENT * ep)
{
switch (ep->type) {
case GR_EVENT_TYPE_EXPOSURE:
expose_menu(ep->exposure.wid);
return (0);
case GR_EVENT_TYPE_BUTTON_DOWN:
return (menu_buttondown(&ep->button));
case GR_EVENT_TYPE_BUTTON_UP:
return (menu_buttonup(&ep->button));
}
return (0);
}
void
menu_wndproc(win * window, GR_EVENT * ep)
{
handle_system_menu(ep);
}
GR_BOOL
system_menu_active()
{
if (wm_menu_active)
return (1);
else
return (0);
}
int
open_system_menu(GR_WINDOW_ID parent, int x, int y,
int dir, wm_menu_t * menudata)
{
GR_FONT_INFO finfo;
if (wm_menu_head) {
printf("Only one menu at a time!\n");
return (0);
}
/* Allocate the font if not already done */
if (!sys_fontid) {
sys_fontid = GrCreateFont(GR_FONT_GUI_VAR, 0, 0);
GrGetFontInfo(sys_fontid, &finfo);
YITEMSIZE = finfo.height + 2;
}
wm_menu_head = create_new_menu(parent,
(wm_menu_t *) menudata,
x, y, dir, WHITE, MWRGB(0x00, 0x66, 0xCC));
#ifdef SYSTEM_SOUNDS
play_sound(SOUND_MENU_OPENED);
#endif
if (!wm_menu_head)
return (0);
else {
wm_menu_active = wm_menu_head;
return (1);
}
}
void
destroy_system_menu(wm_menu_t * menu)
{
int i;
if (!menu)
return;
/* Go through and free as much as possible */
for (i = 0; menu[i].type != MENU_TYPE_END; i++) {
if (menu[i].type == MENU_TYPE_CMENU)
if (menu[i].action)
destroy_system_menu(menu[i].action);
}
free(menu);
}
wm_menu_t *
create_system_menu(int size)
{
return ((wm_menu_t *) malloc(size * sizeof(wm_menu_t)));
}
/* This is a simple utility function that will fill in a particular entry */
/* in the wm_menu_t structure. This is defined inline for speed */
/* There are macros in sys_menu.h that abstract this for each menu type */
inline void
sys_menu_add_item(wm_menu_t * ptr, int tp, char *value, void *action,
void *data, int checked, GR_IMAGE_ID iid)
{
ptr->type = tp;
if (value) {
strncpy(ptr->value, value, 24);
if (strlen(value) > 24)
ptr->value[24] = 0;
} else
ptr->value[0] = 0;
ptr->action = action;
ptr->cbdata = data;
ptr->checked = checked;
ptr->icon = iid;
}
--- NEW FILE: icons.c ---
/*
* Copyright (c) 2003 Century Software, Inc. All Rights Reserved.
*
* This file is part of the PIXIL Operating Environment
*
* The use, copying and distribution of this file is governed by one
* of two licenses, the PIXIL Commercial License, or the GNU General
* Public License, version 2.
*
* Licensees holding a valid PIXIL Commercial License may use this file
* in accordance with the PIXIL Commercial License Agreement provided
* with the Software. Others are governed under the terms of the GNU
* General Public License version 2.
*
* This file may be distributed and/or modified under the terms of the
* GNU General Public License version 2 as published by the Free
* Software Foundation and appearing in the file LICENSE.GPL included
* in the packaging of this file.
*
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING
* THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE.
*
* RESTRICTED RIGHTS LEGEND
*
* Use, duplication, or disclosure by the government is subject to
* restriction as set forth in paragraph (b)(3)(b) of the Rights in
* Technical Data and Computer Software clause in DAR 7-104.9(a).
*
* See http://www.pixil.org/gpl/ for GPL licensing
* information.
*
* See http://www.pixil.org/license.html or
* email cetsales at centurysoftware.com for information about the PIXIL
* Commercial License Agreement, or if any conditions of this licensing
* are not clear to you.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "apps.h"
#include "nanowm.h"
#include "categories.h"
#include "config.h"
#define XOFFSET 20
#define YOFFSET 30
#define XSPACING (ICONWIDTH+20)
#define YSPACING (ICONHEIGHT+ICONTEXTHEIGHT+20)
#define DEFAULT_ICON "generic_app.gif"
GR_IMAGE_ID
loadIconImage(char *filename, char *app, int useDefault)
{
GR_IMAGE_ID ret;
char *f = 0;
char *d = 0;
char *basename = 0;
if (filename && filename[0] != 0x0) {
/* Append the path if nessesary */
if (filename[0] != '/') {
f = alloca(strlen(wm_getDir(DESKTOP_IMAGEDIR)) +
strlen(filename) + 2);
if (!f)
return (0);
sprintf(f, "%s/%s", wm_getDir(DESKTOP_IMAGEDIR), filename);
/* Check if the file exists */
if (access(f, F_OK) != 0) {
warning("image '%s' does not exist.\n", f);
goto useDefault;
}
ret = GrLoadImageFromFile(f, 0);
if (ret == 0)
goto useDefault;
return ret;
}
if (access(filename, F_OK) != 0) {
warning("image '%s' does not exist.\n", filename);
goto useDefault;
}
/* Use the absolute path that was passed in */
error("returning GrLoadImageFromFile() 2\n");
ret = GrLoadImageFromFile(filename, 0);
if (ret == 0)
goto useDefault;
return ret;
}
/* Otherwise, we will use the basename of the application */
if (!app)
return (0);
basename = strrchr(app, '/');
if (!basename)
basename = app;
else
basename = basename + 1;
f = alloca(strlen(wm_getDir(DESKTOP_IMAGEDIR)) + strlen(basename) + 2);
if (!f)
return (0);
sprintf(f, "%s/%s", wm_getDir(DESKTOP_IMAGEDIR), basename);
if (access(f, F_OK) == 0)
return (GrLoadImageFromFile(f, 0));
warning("image '%s' does not exist.\n", filename);
useDefault:
if (!useDefault)
return (0);
/* If we get this far, then we need use the default icon */
d = alloca(strlen(wm_getDir(DESKTOP_IMAGEDIR)) + strlen(DEFAULT_ICON) +
2);
if (!d)
return (0);
sprintf(d, "%s/%s", wm_getDir(DESKTOP_IMAGEDIR), DEFAULT_ICON);
ret = GrLoadImageFromFile(d, 0);
if (!ret)
error("Unable to load a default icon for app '%s'.\n", app);
return (ret);
}
void
hide_icon_list(void)
{
int i;
category_t *cat = (category_t *) category_getCurrent();
if (!cat)
return;
for (i = 0; i < cat->count; i++)
GrUnmapWindow(cat->apps[i]->m_icon_wid);
}
/* Where size is the maximum width of the label (in pixels) */
void
drawLabel(GR_GC_ID gc, char *label, int x, int y, int icon)
{
int dy = y;
int size = icon + 20;
char *p = alloca(strlen(label) + 1);
if (!p)
return;
strcpy(p, label);
while (1) {
int w, h, b;
char *n;
GrGetGCTextSize(gc, p, -1, GR_TFASCII | GR_TFTOP, &w, &h, &b);
/* if it fits, then go with it */
if (w <= size) {
int dx = x + ((icon - w) / 2);
GrText(GR_ROOT_WINDOW_ID, gc, dx, dy, p, -1,
GR_TFASCII | GR_TFTOP);
return;
}
/* Look for a break in the text */
n = strchr(p, ' ');
if (n)
*n = 0;
GrGetGCTextSize(gc, p, -1, GR_TFASCII | GR_TFTOP, &w, &h, &b);
if (w < size) {
int dx = x + ((icon - w) / 2);
GrText(GR_ROOT_WINDOW_ID, gc, dx, dy, p, -1,
GR_TFASCII | GR_TFTOP);
dy += h;
p = n + 1;
} else { /* Truncate it */
int avg = w / strlen(p);
int delta = (w - size) / avg;
int pos = strlen(p) - (delta + 4);
int dx, i;
/* We need to cut off delta + 4 chars */
for (i = pos; i < pos + 3; i++)
p[i] = '.';
p[i] = 0;
GrGetGCTextSize(gc, p, -1, GR_TFASCII | GR_TFTOP, &w, &h, &b);
dx = x + ((icon - w) / 2);
GrText(GR_ROOT_WINDOW_ID, gc, dx, dy, p, -1,
GR_TFASCII | GR_TFTOP);
return;
}
}
}
/* The passed GC is appropriately clipped */
void
draw_current_iconlist(GR_REGION_ID r)
{
int i;
GR_GC_ID gc;
GR_IMAGE_INFO iinfo;
int xpos = XOFFSET;
int ypos = YOFFSET;
GR_FONT_ID fnt = GrCreateFont(GR_FONT_GUI_VAR, 0, NULL);
GR_SCREEN_INFO si;
category_t *cat = (category_t *) category_getCurrent();
if (!cat)
return;
gc = GrNewGC();
GrGetScreenInfo(&si);
/* Set the clip region */
GrSetGCRegion(gc, r);
GrSetGCForeground(gc, wm_getColor(WM_ICONTEXT));
/* If we have a background color for the icon, then use it, otherwise */
/* don't use the background */
if (wm_getColor(WM_ICONCOLOR) >= 0)
GrSetGCBackground(gc, wm_getColor(WM_ICONCOLOR));
else
GrSetGCUseBackground(gc, 0);
GrSetGCFont(gc, fnt);
for (i = 0; i < cat->count; i++) {
APP *cur = cat->apps[i];
if (!cur->m_icon_iid)
continue;
if (cur->m_flags & FL_INPUT)
continue;
GrMoveWindow(cur->m_icon_wid, xpos, ypos);
GrMapWindow(cur->m_icon_wid);
GrGetImageInfo(cur->m_icon_iid, &iinfo);
if ((iinfo.width > ICONWIDTH) || (iinfo.height > ICONHEIGHT)) {
GrDrawImageToFit(GR_ROOT_WINDOW_ID, gc, xpos, ypos,
ICONWIDTH, ICONHEIGHT, cur->m_icon_iid);
} else {
GrDrawImageToFit(GR_ROOT_WINDOW_ID, gc,
// xpos, ypos,
xpos + ((ICONWIDTH - iinfo.width) / 2),
ypos + (ICONHEIGHT - iinfo.height),
// ICONWIDTH, ICONHEIGHT,
iinfo.width, iinfo.width, cur->m_icon_iid);
}
drawLabel(gc, cur->m_icontitle, xpos, ypos + ICONHEIGHT + 5,
ICONWIDTH);
if (xpos + XSPACING + XSPACING > si.ws_width) {
xpos = 20;
ypos += YSPACING;
} else
xpos += XSPACING;
}
GrDestroyFont(fnt);
GrDestroyGC(gc);
}
static void
icon_handler(win * window, GR_EVENT * ep)
{
switch (ep->type) {
case GR_EVENT_TYPE_BUTTON_DOWN:
apps_buttondown(window->wid);
break;
}
}
GR_WINDOW_ID
create_icon_window()
{
GR_WINDOW_ID wid = GrNewInputWindow(GR_ROOT_WINDOW_ID, 20, 20,
ICONWIDTH,
ICONHEIGHT + ICONTEXTHEIGHT);
add_window(wid, GR_ROOT_WINDOW_ID, 0, icon_handler);
GrSelectEvents(wid, GR_EVENT_MASK_BUTTON_DOWN | GR_EVENT_MASK_BUTTON_UP);
return (wid);
}
--- NEW FILE: powerman.h ---
/*
* Copyright (c) 2003 Century Software, Inc. All Rights Reserved.
*
* This file is part of the PIXIL Operating Environment
*
* The use, copying and distribution of this file is governed by one
* of two licenses, the PIXIL Commercial License, or the GNU General
* Public License, version 2.
*
* Licensees holding a valid PIXIL Commercial License may use this file
* in accordance with the PIXIL Commercial License Agreement provided
* with the Software. Others are governed under the terms of the GNU
* General Public License version 2.
*
* This file may be distributed and/or modified under the terms of the
* GNU General Public License version 2 as published by the Free
* Software Foundation and appearing in the file LICENSE.GPL included
* in the packaging of this file.
*
* This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING
* THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE.
*
* RESTRICTED RIGHTS LEGEND
*
* Use, duplication, or disclosure by the government is subject to
* restriction as set forth in paragraph (b)(3)(b) of the Rights in
* Technical Data and Computer Software clause in DAR 7-104.9(a).
*
* See http://www.pixil.org/gpl/ for GPL licensing
* information.
*
* See http://www.pixil.org/license.html or
* email cetsales at centurysoftware.com for information about the PIXIL
* Commercial License Agreement, or if any conditions of this licensing
* are not clear to you.
*/
#ifndef POWERMAN_H_
#define POWERMAN_H_
#define BL_OFF 0
#define BL_ON 1
#define DISABLED -1
#define AC_ON 0
#define BAT_ON 1
/* General functions */
void pm_init(void);
void pm_reload(void);
/* Callback functions */
#define PM_CALLBACK_BL 0x0
typedef void (*pm_callback)(int, void *);
void pm_register_callback(int type, pm_callback cb);
void pm_unregister_callback(int type, pm_callback cb);
/* APM functions */
GR_TIMER_ID pm_get_timer_id(void);
void pm_suspend(void);
/* Backlight functions */
void pm_backlight(int mode);
void pm_bltimer_on(void);
void pm_bltimer_off(void);
int pm_get_bl_status(void);
void pm_bl_toggle(void);
#endif
More information about the dslinux-commit
mailing list