mirror of
git://projects.qi-hardware.com/gmenu2x.git
synced 2025-04-21 12:27:27 +03:00
initial commit - needs clean-up
Signed-off-by: Mirko Lindner <mirko@sharism.cc>
This commit is contained in:
2108
src/FastDelegate.h
Normal file
2108
src/FastDelegate.h
Normal file
File diff suppressed because it is too large
Load Diff
15
src/Makefile.am
Normal file
15
src/Makefile.am
Normal file
@@ -0,0 +1,15 @@
|
||||
bin_PROGRAMS = gmenu2x
|
||||
#
|
||||
gmenu2x_SOURCES = asfont.cpp button.cpp cpu.cpp dirdialog.cpp filedialog.cpp filelister.cpp gmenu2x.cpp iconbutton.cpp imagedialog.cpp inputdialog.cpp inputmanager.cpp linkaction.cpp linkapp.cpp link.cpp listviewitem.cpp menu.cpp menusettingbool.cpp menusetting.cpp menusettingdir.cpp menusettingfile.cpp menusettingimage.cpp menusettingint.cpp menusettingmultistring.cpp menusettingrgba.cpp menusettingstring.cpp messagebox.cpp pxml.cpp selector.cpp selectordetector.cpp settingsdialog.cpp sfontplus.cpp surfacecollection.cpp surface.cpp textdialog.cpp textmanualdialog.cpp touchscreen.cpp translator.cpp utilities.cpp wallpaperdialog.cpp listview.cpp tinyxml/tinystr.cpp tinyxml/tinyxml.cpp tinyxml/tinyxmlerror.cpp tinyxml/tinyxmlparser.cpp
|
||||
|
||||
noinst_HEADERS = asfont.h button.h cpu.h dirdialog.h FastDelegate.h filedialog.h filelister.h gmenu2x.h gp2x.h iconbutton.h imagedialog.h inputdialog.h inputmanager.h jz4740.h linkaction.h linkapp.h link.h listview.h listviewitem.h menu.h menusettingbool.h menusettingdir.h menusettingfile.h menusetting.h menusettingimage.h menusettingint.h menusettingmultistring.h menusettingrgba.h menusettingstring.h messagebox.h pxml.h selectordetector.h selector.h settingsdialog.h sfontplus.h surfacecollection.h surface.h textdialog.h textmanualdialog.h touchscreen.h translator.h utilities.h wallpaperdialog.h tinyxml/tinystr.h tinyxml/tinyxml.h
|
||||
|
||||
AM_CFLAGS= @CFLAGS@ @SDL_CFLAGS@
|
||||
|
||||
AM_CXXFLAGS = @CXXFLAGS@ @SDL_CFLAGS@
|
||||
|
||||
gmenu2x_LDADD = @LIBS@ @SDL_LIBS@
|
||||
|
||||
gmenu2x_LDFLAGS = -L/home/vegyraupe/work/qi/NanoNote/Ben/sw/tinyxml
|
||||
|
||||
gmenu2x_LIBS = @LIBS@ @SDL_LIBS@ -L./sparsehash/ -I./obj/gp2x/tinyxml/
|
||||
124
src/asfont.cpp
Normal file
124
src/asfont.cpp
Normal file
@@ -0,0 +1,124 @@
|
||||
#include "asfont.h"
|
||||
#include "surface.h"
|
||||
#include "utilities.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
ASFont::ASFont(SDL_Surface* font) {
|
||||
this->font.initFont(font);
|
||||
halfHeight = getHeight()/2;
|
||||
halfLineHeight = getLineHeight()/2;
|
||||
}
|
||||
|
||||
ASFont::ASFont(Surface* font) {
|
||||
this->font.initFont(font->raw);
|
||||
halfHeight = getHeight()/2;
|
||||
halfLineHeight = getLineHeight()/2;
|
||||
}
|
||||
|
||||
ASFont::ASFont(string font) {
|
||||
this->font.initFont(font);
|
||||
halfHeight = getHeight()/2;
|
||||
halfLineHeight = getLineHeight()/2;
|
||||
}
|
||||
|
||||
ASFont::~ASFont() {
|
||||
font.freeFont();
|
||||
}
|
||||
|
||||
bool ASFont::utf8Code(unsigned char c) {
|
||||
return font.utf8Code(c);
|
||||
}
|
||||
|
||||
void ASFont::write(SDL_Surface* surface, const char* text, int x, int y) {
|
||||
font.write(surface, text, x, y);
|
||||
}
|
||||
|
||||
void ASFont::write(SDL_Surface* surface, const std::string& text, int x, int y, const unsigned short halign, const unsigned short valign) {
|
||||
switch (halign) {
|
||||
case SFontHAlignCenter:
|
||||
x -= getTextWidth(text)/2;
|
||||
break;
|
||||
case SFontHAlignRight:
|
||||
x -= getTextWidth(text);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (valign) {
|
||||
case SFontVAlignMiddle:
|
||||
y -= getHalfHeight();
|
||||
break;
|
||||
case SFontVAlignBottom:
|
||||
y -= getHeight();
|
||||
break;
|
||||
}
|
||||
|
||||
font.write(surface, text, x, y);
|
||||
}
|
||||
void ASFont::write(SDL_Surface* surface, vector<string> *text, int x, int y, const unsigned short halign, const unsigned short valign) {
|
||||
switch (valign) {
|
||||
case SFontVAlignMiddle:
|
||||
y -= getHalfHeight()*text->size();
|
||||
break;
|
||||
case SFontVAlignBottom:
|
||||
y -= getHeight()*text->size();
|
||||
break;
|
||||
}
|
||||
|
||||
for (uint i=0; i<text->size(); i++) {
|
||||
int ix = x;
|
||||
switch (halign) {
|
||||
case SFontHAlignCenter:
|
||||
ix -= getTextWidth(text->at(i))/2;
|
||||
break;
|
||||
case SFontHAlignRight:
|
||||
ix -= getTextWidth(text->at(i));
|
||||
break;
|
||||
}
|
||||
|
||||
font.write(surface, text->at(i), x, y+getHeight()*i);
|
||||
}
|
||||
}
|
||||
|
||||
void ASFont::write(Surface* surface, const std::string& text, int x, int y, const unsigned short halign, const unsigned short valign) {
|
||||
if (text.find("\n",0)!=string::npos) {
|
||||
vector<string> textArr;
|
||||
split(textArr,text,"\n");
|
||||
write(surface->raw, &textArr, x, y, halign, valign);
|
||||
} else
|
||||
write(surface->raw, text, x, y, halign, valign);
|
||||
}
|
||||
|
||||
int ASFont::getHeight() {
|
||||
return font.getHeight();
|
||||
}
|
||||
int ASFont::getHalfHeight() {
|
||||
return halfHeight;
|
||||
}
|
||||
|
||||
int ASFont::getLineHeight() {
|
||||
return font.getLineHeight();
|
||||
}
|
||||
int ASFont::getHalfLineHeight() {
|
||||
return halfLineHeight;
|
||||
}
|
||||
|
||||
int ASFont::getTextWidth(const char* text) {
|
||||
return font.getTextWidth(text);
|
||||
}
|
||||
int ASFont::getTextWidth(const std::string& text) {
|
||||
if (text.find("\n",0)!=string::npos) {
|
||||
vector<string> textArr;
|
||||
split(textArr,text,"\n");
|
||||
return getTextWidth(&textArr);
|
||||
} else
|
||||
return getTextWidth(text.c_str());
|
||||
}
|
||||
int ASFont::getTextWidth(vector<string> *text) {
|
||||
int w = 0;
|
||||
for (uint i=0; i<text->size(); i++)
|
||||
w = max( getTextWidth(text->at(i).c_str()), w );
|
||||
return w;
|
||||
}
|
||||
49
src/asfont.h
Normal file
49
src/asfont.h
Normal file
@@ -0,0 +1,49 @@
|
||||
//Advanced SFont by Massimiliano Torromeo (cpp wrapper around SFont)
|
||||
|
||||
#ifndef ASFONT_H
|
||||
#define ASFONT_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <SDL.h>
|
||||
#include "sfontplus.h"
|
||||
|
||||
using std::string;
|
||||
using std::vector;
|
||||
|
||||
const unsigned short SFontHAlignLeft = 0;
|
||||
const unsigned short SFontHAlignRight = 1;
|
||||
const unsigned short SFontHAlignCenter = 2;
|
||||
const unsigned short SFontVAlignTop = 0;
|
||||
const unsigned short SFontVAlignBottom = 1;
|
||||
const unsigned short SFontVAlignMiddle = 2;
|
||||
|
||||
class Surface;
|
||||
|
||||
class ASFont {
|
||||
public:
|
||||
ASFont(SDL_Surface* font);
|
||||
ASFont(Surface* font);
|
||||
ASFont(string font);
|
||||
~ASFont();
|
||||
|
||||
bool utf8Code(unsigned char c);
|
||||
|
||||
int getHeight();
|
||||
int getHalfHeight();
|
||||
int getLineHeight();
|
||||
int getHalfLineHeight();
|
||||
int getTextWidth(const char* text);
|
||||
int getTextWidth(const string& text);
|
||||
int getTextWidth(vector<string> *text);
|
||||
void write(SDL_Surface* surface, const char* text, int x, int y);
|
||||
void write(SDL_Surface* surface, const std::string& text, int x, int y, const unsigned short halign = 0, const unsigned short valign = 0);
|
||||
void write(SDL_Surface* surface, vector<string> *text, int x, int y, const unsigned short halign = 0, const unsigned short valign = 0);
|
||||
void write(Surface* surface, const std::string& text, int x, int y, const unsigned short halign = 0, const unsigned short valign = 0);
|
||||
|
||||
private:
|
||||
SFontPlus font;
|
||||
int halfHeight, halfLineHeight;
|
||||
};
|
||||
|
||||
#endif /* ASFONT_H */
|
||||
71
src/button.cpp
Normal file
71
src/button.cpp
Normal file
@@ -0,0 +1,71 @@
|
||||
#include "button.h"
|
||||
#include "gmenu2x.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace fastdelegate;
|
||||
|
||||
Button::Button(GMenu2X * gmenu2x, bool doubleClick) {
|
||||
this->gmenu2x = gmenu2x;
|
||||
this->doubleClick = doubleClick;
|
||||
lastTick = 0;
|
||||
action = MakeDelegate(this, &Button::voidAction);
|
||||
rect.x = 0;
|
||||
rect.y = 0;
|
||||
rect.w = 0;
|
||||
rect.h = 0;
|
||||
}
|
||||
|
||||
void Button::paint() {
|
||||
if (gmenu2x->ts.inRect(rect))
|
||||
if (!paintHover()) return;
|
||||
}
|
||||
|
||||
bool Button::paintHover() {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Button::isPressed() {
|
||||
return gmenu2x->ts.pressed() && gmenu2x->ts.inRect(rect);
|
||||
}
|
||||
|
||||
bool Button::isReleased() {
|
||||
return gmenu2x->ts.released() && gmenu2x->ts.inRect(rect);
|
||||
}
|
||||
|
||||
bool Button::handleTS() {
|
||||
if (isReleased()) {
|
||||
if (doubleClick) {
|
||||
int tickNow = SDL_GetTicks();
|
||||
if (tickNow - lastTick < 400)
|
||||
exec();
|
||||
lastTick = tickNow;
|
||||
} else {
|
||||
exec();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Button::exec() {
|
||||
gmenu2x->ts.setHandled();
|
||||
action();
|
||||
}
|
||||
|
||||
SDL_Rect Button::getRect() {
|
||||
return rect;
|
||||
}
|
||||
|
||||
void Button::setSize(int w, int h) {
|
||||
rect.w = w;
|
||||
rect.h = h;
|
||||
}
|
||||
|
||||
void Button::setPosition(int x, int y) {
|
||||
rect.x = x;
|
||||
rect.y = y;
|
||||
}
|
||||
|
||||
void Button::setAction(ButtonAction action) {
|
||||
this->action = action;
|
||||
}
|
||||
62
src/button.h
Normal file
62
src/button.h
Normal file
@@ -0,0 +1,62 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2006 by Massimiliano Torromeo *
|
||||
* massimiliano.torromeo@gmail.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef BUTTON_H_
|
||||
#define BUTTON_H_
|
||||
|
||||
#include <string>
|
||||
#include <SDL.h>
|
||||
#include "FastDelegate.h"
|
||||
|
||||
using std::string;
|
||||
using fastdelegate::FastDelegate0;
|
||||
|
||||
typedef FastDelegate0<> ButtonAction;
|
||||
class GMenu2X;
|
||||
|
||||
class Button {
|
||||
protected:
|
||||
GMenu2X *gmenu2x;
|
||||
ButtonAction action;
|
||||
SDL_Rect rect;
|
||||
bool doubleClick;
|
||||
int lastTick;
|
||||
|
||||
public:
|
||||
string path;
|
||||
Button(GMenu2X *gmenu2x, bool doubleClick = false);
|
||||
virtual ~Button() {};
|
||||
|
||||
SDL_Rect getRect();
|
||||
void setSize(int w, int h);
|
||||
void setPosition(int x, int y);
|
||||
|
||||
virtual void paint();
|
||||
virtual bool paintHover();
|
||||
|
||||
bool isPressed();
|
||||
bool isReleased();
|
||||
bool handleTS();
|
||||
void exec();
|
||||
void voidAction() {};
|
||||
void setAction(ButtonAction action);
|
||||
};
|
||||
|
||||
#endif /*BUTTON_H_*/
|
||||
98
src/cpu.cpp
Normal file
98
src/cpu.cpp
Normal file
@@ -0,0 +1,98 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/mman.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include "jz4740.h"
|
||||
#include "cpu.h"
|
||||
|
||||
inline int sdram_convert(unsigned int pllin,unsigned int *sdram_freq)
|
||||
{
|
||||
register unsigned int ns, tmp;
|
||||
|
||||
ns = 1000000000 / pllin;
|
||||
/* Set refresh registers */
|
||||
tmp = SDRAM_TREF/ns;
|
||||
tmp = tmp/64 + 1;
|
||||
if (tmp > 0xff) tmp = 0xff;
|
||||
*sdram_freq = tmp;
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
void pll_init(unsigned int clock)
|
||||
{
|
||||
register unsigned int cfcr, plcr1;
|
||||
unsigned int sdramclock = 0;
|
||||
int n2FR[33] = {
|
||||
0, 0, 1, 2, 3, 0, 4, 0, 5, 0, 0, 0, 6, 0, 0, 0,
|
||||
7, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0,
|
||||
9
|
||||
};
|
||||
//int div[5] = {1, 4, 4, 4, 4}; /* divisors of I:S:P:L:M */
|
||||
int div[5] = {1, 3, 3, 3, 3}; /* divisors of I:S:P:L:M */
|
||||
int nf, pllout2;
|
||||
|
||||
cfcr = CPM_CPCCR_CLKOEN |
|
||||
(n2FR[div[0]] << CPM_CPCCR_CDIV_BIT) |
|
||||
(n2FR[div[1]] << CPM_CPCCR_HDIV_BIT) |
|
||||
(n2FR[div[2]] << CPM_CPCCR_PDIV_BIT) |
|
||||
(n2FR[div[3]] << CPM_CPCCR_MDIV_BIT) |
|
||||
(n2FR[div[4]] << CPM_CPCCR_LDIV_BIT);
|
||||
|
||||
pllout2 = (cfcr & CPM_CPCCR_PCS) ? clock : (clock / 2);
|
||||
|
||||
/* Init UHC clock */
|
||||
// REG_CPM_UHCCDR = pllout2 / 48000000 - 1;
|
||||
jz_cpmregl[0x6C>>2] = pllout2 / 48000000 - 1;
|
||||
|
||||
nf = clock * 2 / CFG_EXTAL;
|
||||
plcr1 = ((nf - 2) << CPM_CPPCR_PLLM_BIT) | /* FD */
|
||||
(0 << CPM_CPPCR_PLLN_BIT) | /* RD=0, NR=2 */
|
||||
(0 << CPM_CPPCR_PLLOD_BIT) | /* OD=0, NO=1 */
|
||||
(0x20 << CPM_CPPCR_PLLST_BIT) | /* PLL stable time */
|
||||
CPM_CPPCR_PLLEN; /* enable PLL */
|
||||
|
||||
/* init PLL */
|
||||
// REG_CPM_CPCCR = cfcr;
|
||||
// REG_CPM_CPPCR = plcr1;
|
||||
jz_cpmregl[0] = cfcr;
|
||||
jz_cpmregl[0x10>>2] = plcr1;
|
||||
|
||||
sdram_convert(clock,&sdramclock);
|
||||
if(sdramclock > 0)
|
||||
{
|
||||
// REG_EMC_RTCOR = sdramclock;
|
||||
// REG_EMC_RTCNT = sdramclock;
|
||||
jz_emcregs[0x8C>>1] = sdramclock;
|
||||
jz_emcregs[0x88>>1] = sdramclock;
|
||||
|
||||
}else
|
||||
{
|
||||
printf("sdram init fail!\n");
|
||||
while(1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void jz_cpuspeed(unsigned clockspeed)
|
||||
{
|
||||
if (clockspeed >= 200 && clockspeed <= 430)
|
||||
{
|
||||
jz_dev = open("/dev/mem", O_RDWR);
|
||||
if(jz_dev)
|
||||
{
|
||||
jz_cpmregl=(unsigned long *)mmap(0, 0x80, PROT_READ|PROT_WRITE, MAP_SHARED, jz_dev, 0x10000000);
|
||||
jz_emcregl=(unsigned long *)mmap(0, 0x90, PROT_READ|PROT_WRITE, MAP_SHARED, jz_dev, 0x13010000);
|
||||
jz_emcregs=(unsigned short *)jz_emcregl;
|
||||
pll_init(clockspeed*1000000);
|
||||
munmap((void *)jz_cpmregl, 0x80);
|
||||
munmap((void *)jz_emcregl, 0x90);
|
||||
close(jz_dev);
|
||||
}
|
||||
else
|
||||
printf("failed opening /dev/mem \n");
|
||||
}
|
||||
}
|
||||
24
src/cpu.h
Normal file
24
src/cpu.h
Normal file
@@ -0,0 +1,24 @@
|
||||
#ifndef CPU_H
|
||||
#define CPU_H
|
||||
|
||||
/* Define this to the CPU frequency */
|
||||
#define CPU_FREQ 336000000 /* CPU clock: 336 MHz */
|
||||
#define CFG_EXTAL 12000000 /* EXT clock: 12 Mhz */
|
||||
|
||||
// SDRAM Timings, unit: ns
|
||||
#define SDRAM_TRAS 45 /* RAS# Active Time */
|
||||
#define SDRAM_RCD 20 /* RAS# to CAS# Delay */
|
||||
#define SDRAM_TPC 20 /* RAS# Precharge Time */
|
||||
#define SDRAM_TRWL 7 /* Write Latency Time */
|
||||
#define SDRAM_TREF 15625 /* Refresh period: 4096 refresh cycles/64ms */
|
||||
//#define SDRAM_TREF 7812 /* Refresh period: 8192 refresh cycles/64ms */
|
||||
|
||||
static unsigned long jz_dev;
|
||||
static volatile unsigned long *jz_cpmregl, *jz_emcregl;
|
||||
volatile unsigned short *jz_emcregs;
|
||||
|
||||
void jz_cpuspeed(unsigned clockspeed);
|
||||
void pll_init(unsigned int clock);
|
||||
inline int sdram_convert(unsigned int pllin,unsigned int *sdram_freq);
|
||||
|
||||
#endif
|
||||
202
src/dirdialog.cpp
Normal file
202
src/dirdialog.cpp
Normal file
@@ -0,0 +1,202 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2006 by Massimiliano Torromeo *
|
||||
* massimiliano.torromeo@gmail.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#include <SDL.h>
|
||||
#include <SDL_gfxPrimitives.h>
|
||||
|
||||
//for browsing the filesystem
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
|
||||
#include "dirdialog.h"
|
||||
#include "filelister.h"
|
||||
#include "FastDelegate.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace fastdelegate;
|
||||
|
||||
DirDialog::DirDialog(GMenu2X *gmenu2x, string text, string dir) {
|
||||
this->gmenu2x = gmenu2x;
|
||||
this->text = text;
|
||||
selRow = 0;
|
||||
if (dir.empty())
|
||||
path = "/card";
|
||||
else
|
||||
path = dir;
|
||||
|
||||
//Delegates
|
||||
ButtonAction actionUp = MakeDelegate(this, &DirDialog::up);
|
||||
ButtonAction actionEnter = MakeDelegate(this, &DirDialog::enter);
|
||||
ButtonAction actionConfirm = MakeDelegate(this, &DirDialog::confirm);
|
||||
|
||||
btnUp = new IconButton(gmenu2x, "skin:imgs/buttons/x.png", gmenu2x->tr["Up one folder"]);
|
||||
btnUp->setAction(actionUp);
|
||||
|
||||
btnEnter = new IconButton(gmenu2x, "skin:imgs/buttons/b.png", gmenu2x->tr["Enter folder"]);
|
||||
btnEnter->setAction(actionEnter);
|
||||
|
||||
btnConfirm = new IconButton(gmenu2x, "skin:imgs/buttons/start.png", gmenu2x->tr["Confirm"]);
|
||||
btnConfirm->setAction(actionConfirm);
|
||||
}
|
||||
|
||||
bool DirDialog::exec() {
|
||||
bool ts_pressed = false;
|
||||
uint i, firstElement = 0, iY, action;
|
||||
|
||||
if (!fileExists(path))
|
||||
path = "/card";
|
||||
|
||||
fl = new FileLister(path,true,false);
|
||||
fl->browse();
|
||||
|
||||
selected = 0;
|
||||
close = false;
|
||||
result = true;
|
||||
|
||||
uint rowHeight = gmenu2x->font->getHeight()+1; // gp2x=15+1 / pandora=19+1
|
||||
uint numRows = (gmenu2x->resY-gmenu2x->skinConfInt["topBarHeight"]-20)/rowHeight;
|
||||
SDL_Rect clipRect = {0, gmenu2x->skinConfInt["topBarHeight"]+1, gmenu2x->resX-9, gmenu2x->resY-gmenu2x->skinConfInt["topBarHeight"]-25};
|
||||
SDL_Rect touchRect = {2, gmenu2x->skinConfInt["topBarHeight"]+4, gmenu2x->resX-12, clipRect.h};
|
||||
while (!close) {
|
||||
action = DirDialog::ACT_NONE;
|
||||
if (gmenu2x->f200) gmenu2x->ts.poll();
|
||||
|
||||
gmenu2x->bg->blit(gmenu2x->s,0,0);
|
||||
gmenu2x->drawTitleIcon("icons/explorer.png",true);
|
||||
gmenu2x->writeTitle("Directory Browser");
|
||||
gmenu2x->writeSubTitle(text);
|
||||
|
||||
gmenu2x->drawButton(btnConfirm,
|
||||
gmenu2x->drawButton(btnUp,
|
||||
gmenu2x->drawButton(btnEnter, 5)));
|
||||
|
||||
if (selected>firstElement+numRows-1) firstElement=selected-numRows+1;
|
||||
if (selected<firstElement) firstElement=selected;
|
||||
|
||||
//Selection
|
||||
iY = selected-firstElement;
|
||||
iY = gmenu2x->skinConfInt["topBarHeight"]+1+(iY*rowHeight);
|
||||
gmenu2x->s->box(2, iY, gmenu2x->resX-12, rowHeight-1, gmenu2x->skinConfColors["selectionBg"]);
|
||||
|
||||
//Directories
|
||||
gmenu2x->s->setClipRect(clipRect);
|
||||
if (ts_pressed && !gmenu2x->ts.pressed()) {
|
||||
action = DirDialog::ACT_SELECT;
|
||||
ts_pressed = false;
|
||||
}
|
||||
if (gmenu2x->f200 && gmenu2x->ts.pressed() && !gmenu2x->ts.inRect(touchRect)) ts_pressed = false;
|
||||
for (i=firstElement; i<fl->size() && i<firstElement+numRows; i++) {
|
||||
iY = i-firstElement;
|
||||
gmenu2x->sc.skinRes("imgs/folder.png")->blit(gmenu2x->s, 5, gmenu2x->skinConfInt["topBarHeight"]+1+(iY*rowHeight));
|
||||
gmenu2x->s->write(gmenu2x->font, fl->at(i), 24, gmenu2x->skinConfInt["topBarHeight"]+9+(iY*rowHeight), SFontHAlignLeft, SFontVAlignMiddle);
|
||||
if (gmenu2x->f200 && gmenu2x->ts.pressed() && gmenu2x->ts.inRect(touchRect.x, touchRect.y+(iY*rowHeight), touchRect.w, rowHeight)) {
|
||||
ts_pressed = true;
|
||||
selected = i;
|
||||
}
|
||||
}
|
||||
gmenu2x->s->clearClipRect();
|
||||
|
||||
gmenu2x->drawScrollBar(numRows,fl->size(),firstElement,clipRect.y,clipRect.h);
|
||||
gmenu2x->s->flip();
|
||||
|
||||
btnConfirm->handleTS();
|
||||
btnUp->handleTS();
|
||||
btnEnter->handleTS();
|
||||
gmenu2x->input.update();
|
||||
if ( gmenu2x->input[ACTION_SELECT] ) action = DirDialog::ACT_CLOSE;
|
||||
if ( gmenu2x->input[ACTION_UP ] ) action = DirDialog::ACT_UP;
|
||||
if ( gmenu2x->input[ACTION_L ] ) action = DirDialog::ACT_SCROLLUP;
|
||||
if ( gmenu2x->input[ACTION_DOWN ] ) action = DirDialog::ACT_DOWN;
|
||||
if ( gmenu2x->input[ACTION_R ] ) action = DirDialog::ACT_SCROLLDOWN;
|
||||
if ( gmenu2x->input[ACTION_X] || gmenu2x->input[ACTION_LEFT] ) action = DirDialog::ACT_GOUP;
|
||||
if ( gmenu2x->input[ACTION_B ] ) action = DirDialog::ACT_SELECT;
|
||||
if ( gmenu2x->input[ACTION_START ] ) action = DirDialog::ACT_CONFIRM;
|
||||
|
||||
if (action == DirDialog::ACT_SELECT && fl->at(selected)=="..") action = DirDialog::ACT_GOUP;
|
||||
switch (action) {
|
||||
case DirDialog::ACT_CLOSE: {
|
||||
close = true;
|
||||
result = false;
|
||||
} break;
|
||||
case DirDialog::ACT_UP: {
|
||||
if (selected==0)
|
||||
selected = fl->size()-1;
|
||||
else
|
||||
selected -= 1;
|
||||
} break;
|
||||
case DirDialog::ACT_SCROLLUP: {
|
||||
if ((int)(selected-(numRows-2))<0) {
|
||||
selected = 0;
|
||||
} else {
|
||||
selected -= numRows-2;
|
||||
}
|
||||
} break;
|
||||
case DirDialog::ACT_DOWN: {
|
||||
if (selected+1>=fl->size())
|
||||
selected = 0;
|
||||
else
|
||||
selected += 1;
|
||||
} break;
|
||||
case DirDialog::ACT_SCROLLDOWN: {
|
||||
if (selected+(numRows-2)>=fl->size()) {
|
||||
selected = fl->size()-1;
|
||||
} else {
|
||||
selected += numRows-2;
|
||||
}
|
||||
} break;
|
||||
case DirDialog::ACT_GOUP: {
|
||||
up();
|
||||
} break;
|
||||
case DirDialog::ACT_SELECT: {
|
||||
enter();
|
||||
} break;
|
||||
case DirDialog::ACT_CONFIRM: {
|
||||
confirm();
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
delete(fl);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void DirDialog::up() {
|
||||
string::size_type p = path.rfind("/");
|
||||
if (p==string::npos || path.substr(0,11)!="/card" || p<4) {
|
||||
close = true;
|
||||
result = false;
|
||||
} else {
|
||||
path = path.substr(0,p);
|
||||
selected = 0;
|
||||
fl->setPath(path);
|
||||
}
|
||||
}
|
||||
|
||||
void DirDialog::enter() {
|
||||
path += "/"+fl->at(selected);
|
||||
selected = 0;
|
||||
fl->setPath(path);
|
||||
}
|
||||
|
||||
void DirDialog::confirm() {
|
||||
close = true;
|
||||
}
|
||||
64
src/dirdialog.h
Normal file
64
src/dirdialog.h
Normal file
@@ -0,0 +1,64 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2006 by Massimiliano Torromeo *
|
||||
* massimiliano.torromeo@gmail.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef DIRDIALOG_H_
|
||||
#define DIRDIALOG_H_
|
||||
|
||||
#include <string>
|
||||
#include "gmenu2x.h"
|
||||
|
||||
class FileLister;
|
||||
|
||||
using std::string;
|
||||
using std::vector;
|
||||
|
||||
class DirDialog {
|
||||
protected:
|
||||
static const uint ACT_NONE = 0;
|
||||
static const uint ACT_SELECT = 1;
|
||||
static const uint ACT_CLOSE = 2;
|
||||
static const uint ACT_UP = 3;
|
||||
static const uint ACT_DOWN = 4;
|
||||
static const uint ACT_SCROLLUP = 5;
|
||||
static const uint ACT_SCROLLDOWN = 6;
|
||||
static const uint ACT_GOUP = 7;
|
||||
static const uint ACT_CONFIRM = 8;
|
||||
|
||||
private:
|
||||
int selRow;
|
||||
uint selected;
|
||||
bool close, result;
|
||||
FileLister *fl;
|
||||
string text;
|
||||
IconButton *btnUp, *btnEnter, *btnConfirm;
|
||||
GMenu2X *gmenu2x;
|
||||
|
||||
void up();
|
||||
void enter();
|
||||
void confirm();
|
||||
|
||||
public:
|
||||
string path;
|
||||
DirDialog(GMenu2X *gmenu2x, string text, string dir="");
|
||||
|
||||
bool exec();
|
||||
};
|
||||
|
||||
#endif /*INPUTDIALOG_H_*/
|
||||
187
src/filedialog.cpp
Normal file
187
src/filedialog.cpp
Normal file
@@ -0,0 +1,187 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2006 by Massimiliano Torromeo *
|
||||
* massimiliano.torromeo@gmail.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#include <SDL.h>
|
||||
#include <SDL_gfxPrimitives.h>
|
||||
|
||||
//for browsing the filesystem
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
|
||||
#include "filedialog.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
FileDialog::FileDialog(GMenu2X *gmenu2x, string text, string filter, string file) {
|
||||
this->gmenu2x = gmenu2x;
|
||||
this->text = text;
|
||||
this->filter = filter;
|
||||
this->file = "";
|
||||
setPath("/card");
|
||||
title = "File Browser";
|
||||
if (!file.empty()) {
|
||||
string::size_type pos = file.rfind("/");
|
||||
if (pos != string::npos) {
|
||||
setPath( file.substr(0, pos) );
|
||||
this->file = file.substr(pos+1,file.length());
|
||||
}
|
||||
}
|
||||
selRow = 0;
|
||||
}
|
||||
|
||||
bool FileDialog::exec() {
|
||||
bool close = false, result = true, ts_pressed = false;
|
||||
if (!fileExists(path()))
|
||||
setPath("/card");
|
||||
|
||||
fl.setFilter(filter);
|
||||
fl.browse();
|
||||
|
||||
uint i, firstElement = 0, iY, action;
|
||||
uint rowHeight = gmenu2x->font->getHeight()+1; // gp2x=15+1 / pandora=19+1
|
||||
uint numRows = (gmenu2x->resY-gmenu2x->skinConfInt["topBarHeight"]-20)/rowHeight;
|
||||
SDL_Rect clipRect = {0, gmenu2x->skinConfInt["topBarHeight"]+1, gmenu2x->resX-9, gmenu2x->resY-gmenu2x->skinConfInt["topBarHeight"]-25};
|
||||
SDL_Rect touchRect = {2, gmenu2x->skinConfInt["topBarHeight"]+4, gmenu2x->resX-12, clipRect.h};
|
||||
|
||||
selected = 0;
|
||||
while (!close) {
|
||||
action = FD_NO_ACTION;
|
||||
if (gmenu2x->f200) gmenu2x->ts.poll();
|
||||
|
||||
gmenu2x->bg->blit(gmenu2x->s,0,0);
|
||||
gmenu2x->drawTitleIcon("icons/explorer.png",true);
|
||||
gmenu2x->writeTitle(title);
|
||||
gmenu2x->writeSubTitle(text);
|
||||
|
||||
gmenu2x->drawButton(gmenu2x->s, "x", gmenu2x->tr["Up one folder"],
|
||||
gmenu2x->drawButton(gmenu2x->s, "b", gmenu2x->tr["Enter folder/Confirm"], 5));
|
||||
|
||||
if (selected>firstElement+numRows-1) firstElement=selected-numRows+1;
|
||||
if (selected<firstElement) firstElement=selected;
|
||||
|
||||
//Selection
|
||||
iY = selected-firstElement;
|
||||
iY = gmenu2x->skinConfInt["topBarHeight"]+1+(iY*rowHeight);
|
||||
gmenu2x->s->box(2, iY, gmenu2x->resX-12, rowHeight-1, gmenu2x->skinConfColors["selectionBg"]);
|
||||
|
||||
beforeFileList();
|
||||
|
||||
//Files & Directories
|
||||
gmenu2x->s->setClipRect(clipRect);
|
||||
if (ts_pressed && !gmenu2x->ts.pressed()) {
|
||||
action = FD_ACTION_SELECT;
|
||||
ts_pressed = false;
|
||||
}
|
||||
if (gmenu2x->f200 && gmenu2x->ts.pressed() && !gmenu2x->ts.inRect(touchRect)) ts_pressed = false;
|
||||
for (i=firstElement; i<fl.size() && i<firstElement+numRows; i++) {
|
||||
iY = i-firstElement;
|
||||
if (fl.isDirectory(i)) {
|
||||
if (fl[i]=="..")
|
||||
gmenu2x->sc.skinRes("imgs/go-up.png")->blit(gmenu2x->s, 5, gmenu2x->skinConfInt["topBarHeight"]+1+(iY*rowHeight));
|
||||
else
|
||||
gmenu2x->sc.skinRes("imgs/folder.png")->blit(gmenu2x->s, 5, gmenu2x->skinConfInt["topBarHeight"]+1+(iY*rowHeight));
|
||||
} else {
|
||||
gmenu2x->sc.skinRes("imgs/file.png")->blit(gmenu2x->s, 5, gmenu2x->skinConfInt["topBarHeight"]+1+(iY*rowHeight));
|
||||
}
|
||||
gmenu2x->s->write(gmenu2x->font, fl[i], 24, gmenu2x->skinConfInt["topBarHeight"]+9+(iY*rowHeight), SFontHAlignLeft, SFontVAlignMiddle);
|
||||
if (gmenu2x->f200 && gmenu2x->ts.pressed() && gmenu2x->ts.inRect(touchRect.x, touchRect.y+(iY*rowHeight), touchRect.w, rowHeight)) {
|
||||
ts_pressed = true;
|
||||
selected = i;
|
||||
}
|
||||
}
|
||||
gmenu2x->s->clearClipRect();
|
||||
|
||||
gmenu2x->drawScrollBar(numRows,fl.size(),firstElement,clipRect.y,clipRect.h);
|
||||
gmenu2x->s->flip();
|
||||
|
||||
gmenu2x->input.update();
|
||||
if ( gmenu2x->input[ACTION_SELECT] ) action = FD_ACTION_CLOSE;
|
||||
if ( gmenu2x->input[ACTION_UP ] ) action = FD_ACTION_UP;
|
||||
if ( gmenu2x->input[ACTION_L ] ) action = FD_ACTION_SCROLLUP;
|
||||
if ( gmenu2x->input[ACTION_DOWN ] ) action = FD_ACTION_DOWN;
|
||||
if ( gmenu2x->input[ACTION_R ] ) action = FD_ACTION_SCROLLDOWN;
|
||||
if ( gmenu2x->input[ACTION_X] || gmenu2x->input[ACTION_LEFT] ) action = FD_ACTION_GOUP;
|
||||
if ( gmenu2x->input[ACTION_B ] ) action = FD_ACTION_SELECT;
|
||||
|
||||
if (action == FD_ACTION_SELECT && fl[selected]=="..") action = FD_ACTION_GOUP;
|
||||
switch (action) {
|
||||
case FD_ACTION_CLOSE: {
|
||||
close = true;
|
||||
result = false;
|
||||
} break;
|
||||
case FD_ACTION_UP: {
|
||||
if (selected==0)
|
||||
selected = fl.size()-1;
|
||||
else
|
||||
selected -= 1;
|
||||
} break;
|
||||
case FD_ACTION_SCROLLUP: {
|
||||
if ((int)(selected-(numRows-2))<0) {
|
||||
selected = 0;
|
||||
} else {
|
||||
selected -= numRows-2;
|
||||
}
|
||||
} break;
|
||||
case FD_ACTION_DOWN: {
|
||||
if (selected+1>=fl.size())
|
||||
selected = 0;
|
||||
else
|
||||
selected += 1;
|
||||
} break;
|
||||
case FD_ACTION_SCROLLDOWN: {
|
||||
if (selected+(numRows-2)>=fl.size()) {
|
||||
selected = fl.size()-1;
|
||||
} else {
|
||||
selected += numRows-2;
|
||||
}
|
||||
} break;
|
||||
case FD_ACTION_GOUP: {
|
||||
string::size_type p = path().rfind("/");
|
||||
if (p==string::npos || path().substr(0,11)!="/card" || p<4)
|
||||
return false;
|
||||
else
|
||||
setPath( path().substr(0,p) );
|
||||
} break;
|
||||
case FD_ACTION_SELECT: {
|
||||
if (fl.isDirectory(selected)) {
|
||||
setPath( path()+"/"+fl[selected] );
|
||||
} else {
|
||||
if (fl.isFile(selected)) {
|
||||
file = fl[selected];
|
||||
close = true;
|
||||
}
|
||||
}
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void FileDialog::setPath(string path) {
|
||||
path_v = path;
|
||||
fl.setPath(path);
|
||||
selected = 0;
|
||||
onChangeDir();
|
||||
}
|
||||
|
||||
void FileDialog::beforeFileList() {}
|
||||
void FileDialog::onChangeDir() {}
|
||||
65
src/filedialog.h
Normal file
65
src/filedialog.h
Normal file
@@ -0,0 +1,65 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2006 by Massimiliano Torromeo *
|
||||
* massimiliano.torromeo@gmail.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef FILEDIALOG_H_
|
||||
#define FILEDIALOG_H_
|
||||
|
||||
#include <string>
|
||||
#include "filelister.h"
|
||||
#include "gmenu2x.h"
|
||||
|
||||
#define FD_NO_ACTION 0
|
||||
#define FD_ACTION_CLOSE 1
|
||||
#define FD_ACTION_UP 2
|
||||
#define FD_ACTION_DOWN 3
|
||||
#define FD_ACTION_LEFT 4
|
||||
#define FD_ACTION_RIGHT 5
|
||||
#define FD_ACTION_SCROLLDOWN 6
|
||||
#define FD_ACTION_SCROLLUP 7
|
||||
#define FD_ACTION_GOUP 8
|
||||
#define FD_ACTION_SELECT 9
|
||||
|
||||
using std::string;
|
||||
using std::vector;
|
||||
|
||||
class FileDialog {
|
||||
protected:
|
||||
int selRow;
|
||||
string text, title;
|
||||
GMenu2X *gmenu2x;
|
||||
string filter;
|
||||
FileLister fl;
|
||||
uint selected;
|
||||
string path_v;
|
||||
|
||||
public:
|
||||
string file;
|
||||
FileDialog(GMenu2X *gmenu2x, string text, string filter="", string file="");
|
||||
virtual ~FileDialog() {};
|
||||
|
||||
virtual string path() { return path_v; };
|
||||
virtual void setPath(string path);
|
||||
|
||||
inline virtual void beforeFileList();
|
||||
inline virtual void onChangeDir();
|
||||
bool exec();
|
||||
};
|
||||
|
||||
#endif /*INPUTDIALOG_H_*/
|
||||
136
src/filelister.cpp
Normal file
136
src/filelister.cpp
Normal file
@@ -0,0 +1,136 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2006 by Massimiliano Torromeo *
|
||||
* massimiliano.torromeo@gmail.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
//for browsing the filesystem
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <iostream>
|
||||
|
||||
#include "filelister.h"
|
||||
#include "utilities.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
FileLister::FileLister(string startPath, bool showDirectories, bool showFiles) {
|
||||
this->showDirectories = showDirectories;
|
||||
this->showFiles = showFiles;
|
||||
setPath(startPath,false);
|
||||
}
|
||||
|
||||
string FileLister::getPath() {
|
||||
return path;
|
||||
}
|
||||
void FileLister::setPath(string path, bool doBrowse) {
|
||||
if (path[path.length()-1]!='/') path += "/";
|
||||
this->path = path;
|
||||
if (doBrowse)
|
||||
browse();
|
||||
}
|
||||
|
||||
string FileLister::getFilter() {
|
||||
return filter;
|
||||
}
|
||||
void FileLister::setFilter(string filter) {
|
||||
this->filter = filter;
|
||||
}
|
||||
|
||||
void FileLister::browse() {
|
||||
directories.clear();
|
||||
files.clear();
|
||||
|
||||
if (showDirectories || showFiles) {
|
||||
DIR *dirp;
|
||||
if ((dirp = opendir(path.c_str())) == NULL) {
|
||||
cout << "Error: opendir(" << path << ")" << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
vector<string> vfilter;
|
||||
split(vfilter,getFilter(),",");
|
||||
|
||||
string filepath, file;
|
||||
struct stat st;
|
||||
struct dirent *dptr;
|
||||
|
||||
while ((dptr = readdir(dirp))) {
|
||||
file = dptr->d_name;
|
||||
if (file[0]=='.' && file!="..") continue;
|
||||
filepath = path+file;
|
||||
int statRet = stat(filepath.c_str(), &st);
|
||||
if (statRet == -1) {
|
||||
cout << "\033[0;34mGMENU2X:\033[0;31m stat failed on '" << filepath << "' with error '" << strerror(errno) << "'\033[0m" << endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (find(exclude.begin(), exclude.end(), file) != exclude.end())
|
||||
continue;
|
||||
|
||||
if (S_ISDIR(st.st_mode)) {
|
||||
if (!showDirectories) continue;
|
||||
#ifdef TARGET_GP2X
|
||||
// if (!(path=="/card/" && (file!="sd" && file!="ext" && file!="nand")))
|
||||
#endif
|
||||
directories.push_back(file);
|
||||
} else {
|
||||
if (!showFiles) continue;
|
||||
bool filterOk = false;
|
||||
for (uint i = 0; i<vfilter.size() && !filterOk; i++)
|
||||
if (vfilter[i].length()<=file.length())
|
||||
filterOk = file.substr(file.length()-vfilter[i].length(),vfilter[i].length())==vfilter[i];
|
||||
if (filterOk) files.push_back(file);
|
||||
}
|
||||
}
|
||||
|
||||
closedir(dirp);
|
||||
sort(files.begin(),files.end(),case_less());
|
||||
sort(directories.begin(),directories.end(),case_less());
|
||||
}
|
||||
}
|
||||
|
||||
uint FileLister::size() {
|
||||
return files.size()+directories.size();
|
||||
}
|
||||
uint FileLister::dirCount() {
|
||||
return directories.size();
|
||||
}
|
||||
uint FileLister::fileCount() {
|
||||
return files.size();
|
||||
}
|
||||
|
||||
string FileLister::operator[](uint x) {
|
||||
return at(x);
|
||||
}
|
||||
|
||||
string FileLister::at(uint x) {
|
||||
if (x<directories.size())
|
||||
return directories[x];
|
||||
else
|
||||
return files[x-directories.size()];
|
||||
}
|
||||
|
||||
bool FileLister::isFile(uint x) {
|
||||
return x>=directories.size() && x<size();
|
||||
}
|
||||
|
||||
bool FileLister::isDirectory(uint x) {
|
||||
return x<directories.size();
|
||||
}
|
||||
54
src/filelister.h
Normal file
54
src/filelister.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2006 by Massimiliano Torromeo *
|
||||
* massimiliano.torromeo@gmail.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef FILELISTER_H_
|
||||
#define FILELISTER_H_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
using std::string;
|
||||
using std::vector;
|
||||
|
||||
class FileLister {
|
||||
private:
|
||||
string path, filter;
|
||||
bool showDirectories, showFiles;
|
||||
|
||||
public:
|
||||
FileLister(string startPath = "/boot/local", bool showDirectories = true, bool showFiles = true);
|
||||
void browse();
|
||||
|
||||
vector<string> directories, files, exclude;
|
||||
uint size();
|
||||
uint dirCount();
|
||||
uint fileCount();
|
||||
string operator[](uint);
|
||||
string at(uint);
|
||||
bool isFile(uint);
|
||||
bool isDirectory(uint);
|
||||
|
||||
string getPath();
|
||||
void setPath(string path, bool doBrowse=true);
|
||||
string getFilter();
|
||||
void setFilter(string filter);
|
||||
};
|
||||
|
||||
#endif /*FILELISTER_H_*/
|
||||
BIN
src/font-14.xcf
Normal file
BIN
src/font-14.xcf
Normal file
Binary file not shown.
BIN
src/font.xcf
Normal file
BIN
src/font.xcf
Normal file
Binary file not shown.
1979
src/gmenu2x.cpp
Normal file
1979
src/gmenu2x.cpp
Normal file
File diff suppressed because it is too large
Load Diff
242
src/gmenu2x.h
Normal file
242
src/gmenu2x.h
Normal file
@@ -0,0 +1,242 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2006 by Massimiliano Torromeo *
|
||||
* massimiliano.torromeo@gmail.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef GMENU2X_H
|
||||
#define GMENU2X_H
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <google/dense_hash_map>
|
||||
|
||||
#include "surfacecollection.h"
|
||||
#include "iconbutton.h"
|
||||
#include "translator.h"
|
||||
#include "FastDelegate.h"
|
||||
#include "utilities.h"
|
||||
#include "touchscreen.h"
|
||||
#include "inputmanager.h"
|
||||
|
||||
const int MAX_VOLUME_SCALE_FACTOR = 200;
|
||||
// Default values - going to add settings adjustment, saving, loading and such
|
||||
const int VOLUME_SCALER_MUTE = 0;
|
||||
const int VOLUME_SCALER_PHONES = 65;
|
||||
const int VOLUME_SCALER_NORMAL = 100;
|
||||
const int VOLUME_MODE_MUTE = 0;
|
||||
const int VOLUME_MODE_PHONES = 1;
|
||||
const int VOLUME_MODE_NORMAL = 2;
|
||||
const int BATTERY_READS = 10;
|
||||
|
||||
const int LOOP_DELAY=30000;
|
||||
|
||||
extern void jz_cpuspeed(unsigned clockspeed);
|
||||
|
||||
using std::string;
|
||||
using fastdelegate::FastDelegate0;
|
||||
using google::dense_hash_map;
|
||||
|
||||
typedef FastDelegate0<> MenuAction;
|
||||
typedef dense_hash_map<string, string, hash<string> > ConfStrHash;
|
||||
typedef dense_hash_map<string, int, hash<string> > ConfIntHash;
|
||||
typedef dense_hash_map<string, RGBAColor, hash<string> > ConfRGBAHash;
|
||||
|
||||
typedef struct {
|
||||
unsigned short batt;
|
||||
unsigned short remocon;
|
||||
} MMSP2ADC;
|
||||
|
||||
struct MenuOption {
|
||||
string text;
|
||||
MenuAction action;
|
||||
};
|
||||
|
||||
class Menu;
|
||||
|
||||
class GMenu2X {
|
||||
private:
|
||||
string path; //!< Contains the working directory of GMenu2X
|
||||
/*!
|
||||
Retrieves the free disk space on the sd
|
||||
@return String containing a human readable representation of the free disk space
|
||||
*/
|
||||
string getDiskFree();
|
||||
unsigned short cpuX; //!< Offset for displaying cpu clock information
|
||||
unsigned short volumeX; //!< Offset for displaying volume level
|
||||
unsigned short manualX; //!< Offset for displaying the manual indicator in the taskbar
|
||||
/*!
|
||||
Reads the current battery state and returns a number representing it's level of charge
|
||||
@return A number representing battery charge. 0 means fully discharged. 5 means fully charged. 6 represents a gp2x using AC power.
|
||||
*/
|
||||
unsigned short getBatteryLevel();
|
||||
FILE* batteryHandle, *backlightHandle, *usbHandle, *acHandle;
|
||||
void browsePath(string path, vector<string>* directories, vector<string>* files);
|
||||
/*!
|
||||
Starts the scanning of the nand and sd filesystems, searching for dge and gpu files and creating the links in 2 dedicated sections.
|
||||
*/
|
||||
void scanner();
|
||||
/*!
|
||||
Performs the actual scan in the given path and populates the files vector with the results. The creation of the links is not performed here.
|
||||
@see scanner
|
||||
*/
|
||||
void scanPath(string path, vector<string> *files);
|
||||
|
||||
/*!
|
||||
Displays a selector and launches the specified executable file
|
||||
*/
|
||||
void explorer();
|
||||
|
||||
bool inet, //!< Represents the configuration of the basic network services. @see readCommonIni @see usbnet @see samba @see web
|
||||
usbnet,
|
||||
samba,
|
||||
web;
|
||||
string ip, defaultgw, lastSelectorDir;
|
||||
int lastSelectorElement;
|
||||
void readConfig();
|
||||
void readConfigOpen2x();
|
||||
void readTmp();
|
||||
void readCommonIni();
|
||||
void writeCommonIni();
|
||||
|
||||
void initServices();
|
||||
void initFont();
|
||||
void initMenu();
|
||||
|
||||
#ifdef TARGET_GP2X
|
||||
unsigned long gp2x_mem;
|
||||
unsigned short *gp2x_memregs;
|
||||
volatile unsigned short *MEM_REG;
|
||||
int cx25874; //tv-out
|
||||
#endif
|
||||
void gp2x_tvout_on(bool pal);
|
||||
void gp2x_tvout_off();
|
||||
void gp2x_init();
|
||||
void gp2x_deinit();
|
||||
void toggleTvOut();
|
||||
|
||||
public:
|
||||
GMenu2X(int argc, char *argv[]);
|
||||
~GMenu2X();
|
||||
void quit();
|
||||
|
||||
/*
|
||||
* Variables needed for elements disposition
|
||||
*/
|
||||
uint resX, resY, halfX, halfY;
|
||||
uint bottomBarIconY, bottomBarTextY, linkColumns, linkRows;
|
||||
|
||||
/*!
|
||||
Retrieves the parent directory of GMenu2X.
|
||||
This functions is used to initialize the "path" variable.
|
||||
@see path
|
||||
@return String containing the parent directory
|
||||
*/
|
||||
string getExePath();
|
||||
|
||||
InputManager input;
|
||||
Touchscreen ts;
|
||||
|
||||
//Configuration hashes
|
||||
ConfStrHash confStr, skinConfStr;
|
||||
ConfIntHash confInt, skinConfInt;
|
||||
ConfRGBAHash skinConfColors;
|
||||
|
||||
//Configuration settings
|
||||
bool useSelectionPng;
|
||||
void setSkin(string skin, bool setWallpaper = true);
|
||||
//firmware type and version
|
||||
string fwType, fwVersion;
|
||||
//gp2x type
|
||||
bool f200;
|
||||
|
||||
// Open2x settings ---------------------------------------------------------
|
||||
bool o2x_usb_net_on_boot, o2x_ftp_on_boot, o2x_telnet_on_boot, o2x_gp2xjoy_on_boot, o2x_usb_host_on_boot, o2x_usb_hid_on_boot, o2x_usb_storage_on_boot;
|
||||
string o2x_usb_net_ip;
|
||||
int volumeMode, savedVolumeMode; // just use the const int scale values at top of source
|
||||
|
||||
// Volume scaling values to store from config files
|
||||
int volumeScalerPhones;
|
||||
int volumeScalerNormal;
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
SurfaceCollection sc;
|
||||
Translator tr;
|
||||
Surface *s, *bg;
|
||||
ASFont *font;
|
||||
|
||||
//Status functions
|
||||
int main();
|
||||
void options();
|
||||
void settingsOpen2x();
|
||||
void skinMenu();
|
||||
void activateSdUsb();
|
||||
void activateNandUsb();
|
||||
void activateRootUsb();
|
||||
void about();
|
||||
void viewLog();
|
||||
void contextMenu();
|
||||
void changeWallpaper();
|
||||
void saveScreenshot();
|
||||
|
||||
void applyRamTimings();
|
||||
void applyDefaultTimings();
|
||||
|
||||
void setClock(unsigned mhz);
|
||||
void setGamma(int gamma);
|
||||
|
||||
void setVolume(int vol);
|
||||
int getVolume();
|
||||
void setVolumeScaler(int scaler);
|
||||
int getVolumeScaler();
|
||||
|
||||
void setBacklight(int val);
|
||||
int getBackLight();
|
||||
|
||||
void setInputSpeed();
|
||||
|
||||
void writeConfig();
|
||||
void writeConfigOpen2x();
|
||||
void writeSkinConfig();
|
||||
void writeTmp(int selelem=-1, string selectordir="");
|
||||
|
||||
void ledOn();
|
||||
void ledOff();
|
||||
|
||||
void addLink();
|
||||
void editLink();
|
||||
void deleteLink();
|
||||
void addSection();
|
||||
void renameSection();
|
||||
void deleteSection();
|
||||
|
||||
void initBG();
|
||||
int drawButton(IconButton *btn, int x=5, int y=-10);
|
||||
int drawButton(Surface *s, string btn, string text, int x=5, int y=-10);
|
||||
int drawButtonRight(Surface *s, string btn, string text, int x=5, int y=-10);
|
||||
void drawScrollBar(uint pagesize, uint totalsize, uint pagepos, uint top, uint height);
|
||||
|
||||
void drawTitleIcon(string icon, bool skinRes=true, Surface *s=NULL);
|
||||
void writeTitle(string title, Surface *s=NULL);
|
||||
void writeSubTitle(string subtitle, Surface *s=NULL);
|
||||
void drawTopBar(Surface *s=NULL);
|
||||
void drawBottomBar(Surface *s=NULL);
|
||||
|
||||
Menu* menu;
|
||||
};
|
||||
|
||||
#endif
|
||||
53
src/gp2x.h
Normal file
53
src/gp2x.h
Normal file
@@ -0,0 +1,53 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2006 by Massimiliano Torromeo *
|
||||
* massimiliano.torromeo@gmail.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
#define GP2X_CLK_FREQ 7372800
|
||||
|
||||
#define GP2X_BUTTON_UP (0)
|
||||
#define GP2X_BUTTON_DOWN (4)
|
||||
#define GP2X_BUTTON_LEFT (2)
|
||||
#define GP2X_BUTTON_RIGHT (6)
|
||||
#define GP2X_BUTTON_UPLEFT (1)
|
||||
#define GP2X_BUTTON_UPRIGHT (7)
|
||||
#define GP2X_BUTTON_DOWNLEFT (3)
|
||||
#define GP2X_BUTTON_DOWNRIGHT (5)
|
||||
#define GP2X_BUTTON_CLICK (18)
|
||||
#define GP2X_BUTTON_A (12)
|
||||
#define GP2X_BUTTON_B (13)
|
||||
#define GP2X_BUTTON_START (8)
|
||||
#define GP2X_BUTTON_SELECT (9)
|
||||
#define GP2X_BUTTON_VOLUP (16)
|
||||
#define GP2X_BUTTON_VOLDOWN (17)
|
||||
|
||||
#ifdef GP2X_OLDSDL_FIX
|
||||
#define GP2X_BUTTON_X (15)
|
||||
#define GP2X_BUTTON_Y (14)
|
||||
#define GP2X_BUTTON_L (11)
|
||||
#define GP2X_BUTTON_R (10)
|
||||
#else
|
||||
#define GP2X_BUTTON_X (14)
|
||||
#define GP2X_BUTTON_Y (15)
|
||||
#define GP2X_BUTTON_L (10)
|
||||
#define GP2X_BUTTON_R (11)
|
||||
#endif
|
||||
|
||||
#define FBMMSP2CTRL 0x4619
|
||||
121
src/iconbutton.cpp
Normal file
121
src/iconbutton.cpp
Normal file
@@ -0,0 +1,121 @@
|
||||
#include "iconbutton.h"
|
||||
#include "gmenu2x.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace fastdelegate;
|
||||
|
||||
IconButton::IconButton(GMenu2X *gmenu2x, string icon, string label) : Button(gmenu2x) {
|
||||
this->gmenu2x = gmenu2x;
|
||||
this->icon = icon;
|
||||
labelPosition = IconButton::DISP_RIGHT;
|
||||
labelMargin = 2;
|
||||
this->setLabel(label);
|
||||
}
|
||||
|
||||
void IconButton::setPosition(int x, int y) {
|
||||
if (rect.x != x && rect.y != y) {
|
||||
Button::setPosition(x,y);
|
||||
recalcSize();
|
||||
}
|
||||
}
|
||||
|
||||
void IconButton::paint() {
|
||||
uint margin = labelMargin;
|
||||
if (gmenu2x->sc[icon] == NULL || label == "")
|
||||
margin = 0;
|
||||
if (gmenu2x->sc[icon] != NULL)
|
||||
gmenu2x->sc[icon]->blit(gmenu2x->s,iconRect);
|
||||
if (label != "")
|
||||
gmenu2x->s->write(gmenu2x->font, label, labelRect.x, labelRect.y, labelHAlign, labelVAlign);
|
||||
}
|
||||
|
||||
bool IconButton::paintHover() {
|
||||
return true;
|
||||
}
|
||||
|
||||
void IconButton::recalcSize() {
|
||||
uint h = 0, w = 0;
|
||||
uint margin = labelMargin;
|
||||
|
||||
if (gmenu2x->sc[icon] == NULL || label == "")
|
||||
margin = 0;
|
||||
|
||||
if (gmenu2x->sc[icon] != NULL) {
|
||||
w += gmenu2x->sc[icon]->raw->w;
|
||||
h += gmenu2x->sc[icon]->raw->h;
|
||||
iconRect.w = w;
|
||||
iconRect.h = h;
|
||||
iconRect.x = rect.x;
|
||||
iconRect.y = rect.y;
|
||||
} else {
|
||||
iconRect.x = 0;
|
||||
iconRect.y = 0;
|
||||
iconRect.w = 0;
|
||||
iconRect.h = 0;
|
||||
}
|
||||
|
||||
if (label != "") {
|
||||
labelRect.w = gmenu2x->font->getTextWidth(label);
|
||||
labelRect.h = gmenu2x->font->getHeight();
|
||||
if (labelPosition == IconButton::DISP_LEFT || labelPosition == IconButton::DISP_RIGHT) {
|
||||
w += margin + labelRect.w;
|
||||
//if (labelRect.h > h) h = labelRect.h;
|
||||
labelHAlign = SFontHAlignLeft;
|
||||
labelVAlign = SFontVAlignMiddle;
|
||||
} else {
|
||||
h += margin + labelRect.h;
|
||||
//if (labelRect.w > w) w = labelRect.w;
|
||||
labelHAlign = SFontHAlignCenter;
|
||||
labelVAlign = SFontVAlignTop;
|
||||
}
|
||||
|
||||
switch (labelPosition) {
|
||||
case IconButton::DISP_BOTTOM:
|
||||
labelRect.x = iconRect.x + iconRect.w/2;
|
||||
labelRect.y = iconRect.y + iconRect.h + margin;
|
||||
break;
|
||||
case IconButton::DISP_TOP:
|
||||
labelRect.x = iconRect.x + iconRect.w/2;
|
||||
labelRect.y = rect.y;
|
||||
iconRect.y += labelRect.h + margin;
|
||||
break;
|
||||
case IconButton::DISP_LEFT:
|
||||
labelRect.x = rect.x;
|
||||
labelRect.y = rect.y+h/2;
|
||||
iconRect.x += labelRect.w + margin;
|
||||
break;
|
||||
default:
|
||||
labelRect.x = iconRect.x + iconRect.w + margin;
|
||||
labelRect.y = rect.y+h/2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
setSize(w, h);
|
||||
}
|
||||
|
||||
string IconButton::getLabel() {
|
||||
return label;
|
||||
}
|
||||
|
||||
void IconButton::setLabel(string label) {
|
||||
this->label = label;
|
||||
}
|
||||
|
||||
void IconButton::setLabelPosition(int pos, int margin) {
|
||||
labelPosition = pos;
|
||||
labelMargin = margin;
|
||||
recalcSize();
|
||||
}
|
||||
|
||||
string IconButton::getIcon() {
|
||||
return icon;
|
||||
}
|
||||
|
||||
void IconButton::setIcon(string icon) {
|
||||
this->icon = icon;
|
||||
recalcSize();
|
||||
}
|
||||
|
||||
void IconButton::setAction(ButtonAction action) {
|
||||
this->action = action;
|
||||
}
|
||||
43
src/iconbutton.h
Normal file
43
src/iconbutton.h
Normal file
@@ -0,0 +1,43 @@
|
||||
#ifndef ICONBUTTON_H
|
||||
#define ICONBUTTON_H
|
||||
|
||||
#include <string>
|
||||
#include "button.h"
|
||||
|
||||
using std::string;
|
||||
|
||||
class GMenu2X;
|
||||
|
||||
class IconButton : public Button {
|
||||
protected:
|
||||
string icon, label;
|
||||
int labelPosition, labelMargin;
|
||||
unsigned short labelHAlign, labelVAlign;
|
||||
void recalcSize();
|
||||
SDL_Rect iconRect, labelRect;
|
||||
|
||||
public:
|
||||
static const int DISP_RIGHT = 0;
|
||||
static const int DISP_LEFT = 1;
|
||||
static const int DISP_TOP = 2;
|
||||
static const int DISP_BOTTOM = 3;
|
||||
|
||||
IconButton(GMenu2X *gmenu2x, string icon, string label="");
|
||||
virtual ~IconButton() {};
|
||||
|
||||
virtual void paint();
|
||||
virtual bool paintHover();
|
||||
|
||||
void setPosition(int x, int y);
|
||||
|
||||
string getLabel();
|
||||
void setLabel(string label);
|
||||
void setLabelPosition(int pos, int margin);
|
||||
|
||||
string getIcon();
|
||||
void setIcon(string icon);
|
||||
|
||||
void setAction(ButtonAction action);
|
||||
};
|
||||
|
||||
#endif
|
||||
64
src/imagedialog.cpp
Normal file
64
src/imagedialog.cpp
Normal file
@@ -0,0 +1,64 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2006 by Massimiliano Torromeo *
|
||||
* massimiliano.torromeo@gmail.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#include <SDL.h>
|
||||
#include <SDL_gfxPrimitives.h>
|
||||
|
||||
//for browsing the filesystem
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
|
||||
#include "imagedialog.h"
|
||||
#include "filelister.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
ImageDialog::ImageDialog(GMenu2X *gmenu2x, string text, string filter, string file) : FileDialog(gmenu2x, text, filter, file) {
|
||||
this->gmenu2x = gmenu2x;
|
||||
this->text = text;
|
||||
this->filter = filter;
|
||||
this->file = "";
|
||||
setPath("/card");
|
||||
title = "Image Browser";
|
||||
if (!file.empty()) {
|
||||
file = strreplace(file,"skin:",gmenu2x->getExePath()+"skins/"+gmenu2x->confStr["skin"]+"/");
|
||||
string::size_type pos = file.rfind("/");
|
||||
if (pos != string::npos) {
|
||||
setPath( file.substr(0, pos) );
|
||||
cout << "ib: " << path() << endl;
|
||||
this->file = file.substr(pos+1,file.length());
|
||||
}
|
||||
}
|
||||
selRow = 0;
|
||||
}
|
||||
|
||||
ImageDialog::~ImageDialog() {
|
||||
previews.clear();
|
||||
}
|
||||
|
||||
void ImageDialog::beforeFileList() {
|
||||
if (fl.isFile(selected) && fileExists(path()+"/"+fl[selected]))
|
||||
previews[path()+"/"+fl[selected]]->blitRight(gmenu2x->s, 310, 43);
|
||||
}
|
||||
|
||||
void ImageDialog::onChangeDir() {
|
||||
previews.clear();
|
||||
}
|
||||
40
src/imagedialog.h
Normal file
40
src/imagedialog.h
Normal file
@@ -0,0 +1,40 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2006 by Massimiliano Torromeo *
|
||||
* massimiliano.torromeo@gmail.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef IMAGEDIALOG_H_
|
||||
#define IMAGEDIALOG_H_
|
||||
|
||||
#include <string>
|
||||
#include "filedialog.h"
|
||||
|
||||
using std::string;
|
||||
using std::vector;
|
||||
|
||||
class ImageDialog : public FileDialog {
|
||||
protected:
|
||||
SurfaceCollection previews;
|
||||
public:
|
||||
ImageDialog(GMenu2X *gmenu2x, string text, string filter="", string file="");
|
||||
virtual ~ImageDialog();
|
||||
inline virtual void beforeFileList();
|
||||
inline virtual void onChangeDir();
|
||||
};
|
||||
|
||||
#endif /*IMAGEDIALOG_H_*/
|
||||
302
src/inputdialog.cpp
Normal file
302
src/inputdialog.cpp
Normal file
@@ -0,0 +1,302 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2006 by Massimiliano Torromeo *
|
||||
* massimiliano.torromeo@gmail.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#include <SDL.h>
|
||||
#include <SDL_gfxPrimitives.h>
|
||||
|
||||
#include "inputdialog.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace fastdelegate;
|
||||
|
||||
InputDialog::InputDialog(GMenu2X *gmenu2x, string text, string startvalue, string title, string icon) {
|
||||
this->gmenu2x = gmenu2x;
|
||||
if (title=="") {
|
||||
this->title = text;
|
||||
this->text = "";
|
||||
} else {
|
||||
this->title = title;
|
||||
this->text = text;
|
||||
}
|
||||
this->icon = "";
|
||||
if (icon!="" && gmenu2x->sc[icon] != NULL)
|
||||
this->icon = icon;
|
||||
|
||||
input = startvalue;
|
||||
selCol = 0;
|
||||
selRow = 0;
|
||||
keyboard.resize(7);
|
||||
|
||||
keyboard[0].push_back("abcdefghijklm");
|
||||
keyboard[0].push_back("nopqrstuvwxyz");
|
||||
keyboard[0].push_back("0123456789. ");
|
||||
|
||||
keyboard[1].push_back("ABCDEFGHIJKLM");
|
||||
keyboard[1].push_back("NOPQRSTUVWXYZ");
|
||||
keyboard[1].push_back("_\"'`.,:;!? ");
|
||||
|
||||
|
||||
keyboard[2].push_back("¡¿*+-/\\&<=>|");
|
||||
keyboard[2].push_back("()[]{}@#$%^~");
|
||||
keyboard[2].push_back("_\"'`.,:;!? ");
|
||||
|
||||
|
||||
keyboard[3].push_back("àáèéìíòóùúýäõ");
|
||||
keyboard[3].push_back("ëïöüÿâêîôûåãñ");
|
||||
keyboard[3].push_back("čďěľĺňôřŕšťůž");
|
||||
keyboard[3].push_back("ąćęłńśżź ");
|
||||
|
||||
keyboard[4].push_back("ÀÁÈÉÌÍÒÓÙÚÝÄÕ");
|
||||
keyboard[4].push_back("ËÏÖÜŸÂÊÎÔÛÅÃÑ");
|
||||
keyboard[4].push_back("ČĎĚĽĹŇÔŘŔŠŤŮŽ");
|
||||
keyboard[4].push_back("ĄĆĘŁŃŚŻŹ ");
|
||||
|
||||
|
||||
keyboard[5].push_back("æçабвгдеёжзий ");
|
||||
keyboard[5].push_back("клмнопрстуфхцч");
|
||||
keyboard[5].push_back("шщъыьэюяøðßÐÞþ");
|
||||
|
||||
keyboard[6].push_back("ÆÇАБВГДЕЁЖЗИЙ ");
|
||||
keyboard[6].push_back("КЛМНОПРСТУФХЦЧ");
|
||||
keyboard[6].push_back("ШЩЪЫЬЭЮЯØðßÐÞþ");
|
||||
|
||||
setKeyboard(0);
|
||||
|
||||
ButtonAction actBackspace = MakeDelegate(this, &InputDialog::backspace);
|
||||
|
||||
btnBackspaceX = new IconButton(gmenu2x, "skin:imgs/buttons/x.png");
|
||||
btnBackspaceX->setAction(actBackspace);
|
||||
|
||||
btnBackspaceL = new IconButton(gmenu2x, "skin:imgs/buttons/l.png", gmenu2x->tr["Backspace"]);
|
||||
btnBackspaceL->setAction(actBackspace);
|
||||
|
||||
btnSpace = new IconButton(gmenu2x, "skin:imgs/buttons/r.png", gmenu2x->tr["Space"]);
|
||||
btnSpace->setAction(MakeDelegate(this, &InputDialog::space));
|
||||
|
||||
btnConfirm = new IconButton(gmenu2x, "skin:imgs/buttons/b.png", gmenu2x->tr["Confirm"]);
|
||||
btnConfirm->setAction(MakeDelegate(this, &InputDialog::confirm));
|
||||
|
||||
btnChangeKeys = new IconButton(gmenu2x, "skin:imgs/buttons/y.png", gmenu2x->tr["Change keys"]);
|
||||
btnChangeKeys->setAction(MakeDelegate(this, &InputDialog::changeKeys));
|
||||
}
|
||||
|
||||
void InputDialog::setKeyboard(int kb) {
|
||||
kb = constrain(kb,0,keyboard.size()-1);
|
||||
curKeyboard = kb;
|
||||
this->kb = &(keyboard[kb]);
|
||||
kbLength = this->kb->at(0).length();
|
||||
for (int x = 0, l = kbLength; x<l; x++)
|
||||
if (gmenu2x->font->utf8Code(this->kb->at(0)[x])) {
|
||||
kbLength--;
|
||||
x++;
|
||||
}
|
||||
|
||||
kbLeft = 160 - kbLength*KEY_WIDTH/2;
|
||||
kbWidth = kbLength*KEY_WIDTH+3;
|
||||
kbHeight = (this->kb->size()+1)*KEY_HEIGHT+3;
|
||||
|
||||
kbRect.x = kbLeft-3;
|
||||
kbRect.y = KB_TOP-2;
|
||||
kbRect.w = kbWidth;
|
||||
kbRect.h = kbHeight;
|
||||
}
|
||||
|
||||
bool InputDialog::exec() {
|
||||
SDL_Rect box = {0, 60, 0, gmenu2x->font->getHeight()+4};
|
||||
|
||||
Uint32 caretTick = 0, curTick;
|
||||
bool caretOn = true;
|
||||
|
||||
uint action;
|
||||
close = false;
|
||||
ok = true;
|
||||
while (!close) {
|
||||
gmenu2x->bg->blit(gmenu2x->s,0,0);
|
||||
gmenu2x->writeTitle(title);
|
||||
gmenu2x->writeSubTitle(text);
|
||||
gmenu2x->drawTitleIcon(icon);
|
||||
|
||||
gmenu2x->drawButton(gmenu2x->s, "y", gmenu2x->tr["Change keys"],
|
||||
gmenu2x->drawButton(gmenu2x->s, "b", gmenu2x->tr["Confirm"],
|
||||
gmenu2x->drawButton(gmenu2x->s, "r", gmenu2x->tr["Space"],
|
||||
gmenu2x->drawButton(btnBackspaceL,
|
||||
gmenu2x->drawButton(btnBackspaceX)-6))));
|
||||
|
||||
box.w = gmenu2x->font->getTextWidth(input)+18;
|
||||
box.x = 160-box.w/2;
|
||||
gmenu2x->s->box(box.x, box.y, box.w, box.h, gmenu2x->skinConfColors["selectionBg"]);
|
||||
gmenu2x->s->rectangle(box.x, box.y, box.w, box.h, gmenu2x->skinConfColors["selectionBg"]);
|
||||
|
||||
gmenu2x->s->write(gmenu2x->font, input, box.x+5, box.y+box.h-2, SFontHAlignLeft, SFontVAlignBottom);
|
||||
|
||||
curTick = SDL_GetTicks();
|
||||
if (curTick-caretTick>=600) {
|
||||
caretOn = !caretOn;
|
||||
caretTick = curTick;
|
||||
}
|
||||
|
||||
if (caretOn) gmenu2x->s->box(box.x+box.w-12, box.y+3, 8, box.h-6, gmenu2x->skinConfColors["selectionBg"]);
|
||||
|
||||
if (gmenu2x->f200) gmenu2x->ts.poll();
|
||||
action = drawVirtualKeyboard();
|
||||
gmenu2x->s->flip();
|
||||
|
||||
gmenu2x->input.update();
|
||||
if ( gmenu2x->input[ACTION_START] ) action = ID_ACTION_CLOSE;
|
||||
if ( gmenu2x->input[ACTION_UP ] ) action = ID_ACTION_UP;
|
||||
if ( gmenu2x->input[ACTION_DOWN ] ) action = ID_ACTION_DOWN;
|
||||
if ( gmenu2x->input[ACTION_LEFT ] ) action = ID_ACTION_LEFT;
|
||||
if ( gmenu2x->input[ACTION_RIGHT] ) action = ID_ACTION_RIGHT;
|
||||
if ( gmenu2x->input[ACTION_B] ) action = ID_ACTION_SELECT;
|
||||
if ( gmenu2x->input[ACTION_Y] ) action = ID_ACTION_KB_CHANGE;
|
||||
if ( gmenu2x->input[ACTION_X] || gmenu2x->input[ACTION_L] ) action = ID_ACTION_BACKSPACE;
|
||||
if ( gmenu2x->input[ACTION_R ] ) action = ID_ACTION_SPACE;
|
||||
|
||||
switch (action) {
|
||||
case ID_ACTION_CLOSE: {
|
||||
ok = false;
|
||||
close = true;
|
||||
} break;
|
||||
case ID_ACTION_UP: {
|
||||
selRow--;
|
||||
} break;
|
||||
case ID_ACTION_DOWN: {
|
||||
selRow++;
|
||||
if (selRow==(int)kb->size()) selCol = selCol<8 ? 0 : 1;
|
||||
} break;
|
||||
case ID_ACTION_LEFT: {
|
||||
selCol--;
|
||||
} break;
|
||||
case ID_ACTION_RIGHT: {
|
||||
selCol++;
|
||||
} break;
|
||||
case ID_ACTION_BACKSPACE: backspace(); break;
|
||||
case ID_ACTION_SPACE: space(); break;
|
||||
case ID_ACTION_KB_CHANGE: changeKeys(); break;
|
||||
case ID_ACTION_SELECT: confirm(); break;
|
||||
}
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
void InputDialog::backspace() {
|
||||
// check for utf8 characters
|
||||
input = input.substr(0,input.length()-( gmenu2x->font->utf8Code(input[input.length()-2]) ? 2 : 1 ));
|
||||
}
|
||||
|
||||
void InputDialog::space() {
|
||||
// check for utf8 characters
|
||||
input += " ";
|
||||
}
|
||||
|
||||
void InputDialog::confirm() {
|
||||
if (selRow==(int)kb->size()) {
|
||||
if (selCol==0)
|
||||
ok = false;
|
||||
close = true;
|
||||
} else {
|
||||
bool utf8;
|
||||
int xc=0;
|
||||
for (uint x=0; x<kb->at(selRow).length(); x++) {
|
||||
utf8 = gmenu2x->font->utf8Code(kb->at(selRow)[x]);
|
||||
if (xc==selCol) input += kb->at(selRow).substr(x, utf8 ? 2 : 1);
|
||||
if (utf8) x++;
|
||||
xc++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void InputDialog::changeKeys() {
|
||||
if (curKeyboard==6)
|
||||
setKeyboard(0);
|
||||
else
|
||||
setKeyboard(curKeyboard+1);
|
||||
}
|
||||
|
||||
int InputDialog::drawVirtualKeyboard() {
|
||||
int action = ID_NO_ACTION;
|
||||
|
||||
//keyboard border
|
||||
gmenu2x->s->rectangle(kbRect, gmenu2x->skinConfColors["selectionBg"]);
|
||||
|
||||
if (selCol<0) selCol = selRow==(int)kb->size() ? 1 : kbLength-1;
|
||||
if (selCol>=(int)kbLength) selCol = 0;
|
||||
if (selRow<0) selRow = kb->size()-1;
|
||||
if (selRow>(int)kb->size()) selRow = 0;
|
||||
|
||||
//selection
|
||||
if (selRow<(int)kb->size())
|
||||
gmenu2x->s->box(kbLeft+selCol*KEY_WIDTH-1, KB_TOP+selRow*KEY_HEIGHT, KEY_WIDTH-1, KEY_HEIGHT-2, gmenu2x->skinConfColors["selectionBg"]);
|
||||
else {
|
||||
if (selCol>1) selCol = 0;
|
||||
if (selCol<0) selCol = 1;
|
||||
gmenu2x->s->box(kbLeft+selCol*kbLength*KEY_WIDTH/2-1, KB_TOP+kb->size()*KEY_HEIGHT, kbLength*KEY_WIDTH/2-1, KEY_HEIGHT-1, gmenu2x->skinConfColors["selectionBg"]);
|
||||
}
|
||||
|
||||
//keys
|
||||
for (uint l=0; l<kb->size(); l++) {
|
||||
string line = kb->at(l);
|
||||
for (uint x=0, xc=0; x<line.length(); x++) {
|
||||
string charX;
|
||||
//utf8 characters
|
||||
if (gmenu2x->font->utf8Code(line[x])) {
|
||||
charX = line.substr(x,2);
|
||||
x++;
|
||||
} else
|
||||
charX = line[x];
|
||||
|
||||
SDL_Rect re = {kbLeft+xc*KEY_WIDTH-1, KB_TOP+l*KEY_HEIGHT, KEY_WIDTH-1, KEY_HEIGHT-2};
|
||||
|
||||
//if ts on rect, change selection
|
||||
if (gmenu2x->f200 && gmenu2x->ts.pressed() && gmenu2x->ts.inRect(re)) {
|
||||
selCol = xc;
|
||||
selRow = l;
|
||||
}
|
||||
|
||||
gmenu2x->s->rectangle(re, gmenu2x->skinConfColors["selectionBg"]);
|
||||
gmenu2x->s->write(gmenu2x->font, charX, kbLeft+xc*KEY_WIDTH+KEY_WIDTH/2-1, KB_TOP+l*KEY_HEIGHT+KEY_HEIGHT/2, SFontHAlignCenter, SFontVAlignMiddle);
|
||||
xc++;
|
||||
}
|
||||
}
|
||||
|
||||
//Ok/Cancel
|
||||
SDL_Rect re = {kbLeft-1, KB_TOP+kb->size()*KEY_HEIGHT, kbLength*KEY_WIDTH/2-1, KEY_HEIGHT-1};
|
||||
gmenu2x->s->rectangle(re, gmenu2x->skinConfColors["selectionBg"]);
|
||||
if (gmenu2x->f200 && gmenu2x->ts.pressed() && gmenu2x->ts.inRect(re)) {
|
||||
selCol = 0;
|
||||
selRow = kb->size();
|
||||
}
|
||||
gmenu2x->s->write(gmenu2x->font, gmenu2x->tr["Cancel"], (int)(160-kbLength*KEY_WIDTH/4), KB_TOP+kb->size()*KEY_HEIGHT+KEY_HEIGHT/2, SFontHAlignCenter, SFontVAlignMiddle);
|
||||
|
||||
re.x = kbLeft+kbLength*KEY_WIDTH/2-1;
|
||||
gmenu2x->s->rectangle(re, gmenu2x->skinConfColors["selectionBg"]);
|
||||
if (gmenu2x->f200 && gmenu2x->ts.pressed() && gmenu2x->ts.inRect(re)) {
|
||||
selCol = 1;
|
||||
selRow = kb->size();
|
||||
}
|
||||
gmenu2x->s->write(gmenu2x->font, gmenu2x->tr["OK"], (int)(160+kbLength*KEY_WIDTH/4), KB_TOP+kb->size()*KEY_HEIGHT+KEY_HEIGHT/2, SFontHAlignCenter, SFontVAlignMiddle);
|
||||
|
||||
//if ts released
|
||||
if (gmenu2x->f200 && gmenu2x->ts.wasPressed && !gmenu2x->ts.pressed() && gmenu2x->ts.inRect(kbRect))
|
||||
action = ID_ACTION_SELECT;
|
||||
|
||||
return action;
|
||||
}
|
||||
76
src/inputdialog.h
Normal file
76
src/inputdialog.h
Normal file
@@ -0,0 +1,76 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2006 by Massimiliano Torromeo *
|
||||
* massimiliano.torromeo@gmail.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef INPUTDIALOG_H_
|
||||
#define INPUTDIALOG_H_
|
||||
|
||||
#define KEY_WIDTH 20
|
||||
#define KEY_HEIGHT 20
|
||||
#define KB_TOP 90
|
||||
|
||||
#define ID_NO_ACTION 0
|
||||
#define ID_ACTION_CLOSE 1
|
||||
#define ID_ACTION_UP 2
|
||||
#define ID_ACTION_DOWN 3
|
||||
#define ID_ACTION_LEFT 4
|
||||
#define ID_ACTION_RIGHT 5
|
||||
#define ID_ACTION_BACKSPACE 6
|
||||
#define ID_ACTION_SPACE 7
|
||||
#define ID_ACTION_GOUP 8
|
||||
#define ID_ACTION_SELECT 9
|
||||
#define ID_ACTION_KB_CHANGE 10
|
||||
|
||||
#include <string>
|
||||
#include "gmenu2x.h"
|
||||
|
||||
using std::string;
|
||||
using std::vector;
|
||||
|
||||
typedef vector<string> stringlist;
|
||||
|
||||
class InputDialog {
|
||||
private:
|
||||
int selRow, selCol;
|
||||
bool close, ok;
|
||||
string title, text, icon;
|
||||
GMenu2X *gmenu2x;
|
||||
short curKeyboard;
|
||||
vector<stringlist> keyboard;
|
||||
stringlist *kb;
|
||||
int kbLength, kbWidth, kbHeight, kbLeft;
|
||||
SDL_Rect kbRect;
|
||||
IconButton *btnBackspaceX, *btnBackspaceL, *btnSpace, *btnConfirm, *btnChangeKeys;
|
||||
|
||||
void backspace();
|
||||
void space();
|
||||
void confirm();
|
||||
void changeKeys();
|
||||
|
||||
int drawVirtualKeyboard();
|
||||
void setKeyboard(int);
|
||||
|
||||
public:
|
||||
InputDialog(GMenu2X *gmenu2x, string text, string startvalue="", string title="", string icon="");
|
||||
|
||||
string input;
|
||||
bool exec();
|
||||
};
|
||||
|
||||
#endif /*INPUTDIALOG_H_*/
|
||||
198
src/inputmanager.cpp
Normal file
198
src/inputmanager.cpp
Normal file
@@ -0,0 +1,198 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2006 by Massimiliano Torromeo *
|
||||
* massimiliano.torromeo@gmail.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
#include "inputmanager.h"
|
||||
#include "utilities.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
InputManager::InputManager() {}
|
||||
|
||||
InputManager::~InputManager() {
|
||||
for (uint x=0; x<joysticks.size(); x++)
|
||||
if(SDL_JoystickOpened(x))
|
||||
SDL_JoystickClose(joysticks[x]);
|
||||
}
|
||||
|
||||
void InputManager::init(string conffile) {
|
||||
SDL_JoystickEventState(SDL_IGNORE);
|
||||
|
||||
int numJoy = SDL_NumJoysticks();
|
||||
for (int x=0; x<numJoy; x++) {
|
||||
SDL_Joystick *joy = SDL_JoystickOpen(x);
|
||||
if (joy) {
|
||||
#ifdef DEBUG
|
||||
cout << "Initialized joystick: " << SDL_JoystickName(x) << endl;
|
||||
#endif
|
||||
joysticks.push_back(joy);
|
||||
}
|
||||
#ifdef DEBUG
|
||||
else cout << "Failed to initialize joystick: " << x << endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
setActionsCount(14);
|
||||
|
||||
if (fileExists(conffile)) {
|
||||
ifstream inf(conffile.c_str(), ios_base::in);
|
||||
if (inf.is_open()) {
|
||||
string line, name, value;
|
||||
stringstream ss;
|
||||
string::size_type pos;
|
||||
vector<string> values;
|
||||
|
||||
while (getline(inf, line, '\n')) {
|
||||
pos = line.find("=");
|
||||
name = trim(line.substr(0,pos));
|
||||
value = trim(line.substr(pos+1,line.length()));
|
||||
int action = -1;
|
||||
|
||||
if (name=="up") action = ACTION_UP;
|
||||
else if (name=="down") action = ACTION_DOWN;
|
||||
else if (name=="left") action = ACTION_LEFT;
|
||||
else if (name=="right") action = ACTION_RIGHT;
|
||||
else if (name=="a") action = ACTION_A;
|
||||
else if (name=="b") action = ACTION_B;
|
||||
else if (name=="x") action = ACTION_X;
|
||||
else if (name=="y") action = ACTION_Y;
|
||||
else if (name=="l") action = ACTION_L;
|
||||
else if (name=="r") action = ACTION_R;
|
||||
else if (name=="start") action = ACTION_START;
|
||||
else if (name=="select") action = ACTION_SELECT;
|
||||
else if (name=="volup") action = ACTION_VOLUP;
|
||||
else if (name=="voldown") action = ACTION_VOLDOWN;
|
||||
|
||||
if (action >= 0) {
|
||||
split(values, value, ",");
|
||||
if (values.size() >= 2) {
|
||||
|
||||
if (values[0] == "joystickbutton" && values.size()==3) {
|
||||
InputMap map;
|
||||
map.type = InputManager::MAPPING_TYPE_BUTTON;
|
||||
map.num = atoi(values[1].c_str());
|
||||
map.value = atoi(values[2].c_str());
|
||||
map.treshold = 0;
|
||||
mappings[action].push_back(map);
|
||||
} else if (values[0] == "joystickaxys" && values.size()==4) {
|
||||
InputMap map;
|
||||
map.type = InputManager::MAPPING_TYPE_AXYS;
|
||||
map.num = atoi(values[1].c_str());
|
||||
map.value = atoi(values[2].c_str());
|
||||
map.treshold = atoi(values[3].c_str());
|
||||
mappings[action].push_back(map);
|
||||
} else if (values[0] == "keyboard") {
|
||||
InputMap map;
|
||||
map.type = InputManager::MAPPING_TYPE_KEYPRESS;
|
||||
map.value = atoi(values[1].c_str());
|
||||
mappings[action].push_back(map);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
inf.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void InputManager::setActionsCount(int count) {
|
||||
actions.clear();
|
||||
actionTick.clear();
|
||||
interval.clear();
|
||||
for (int x=0; x<count; x++) {
|
||||
actions.push_back(false);
|
||||
actionTick.push_back(0);
|
||||
interval.push_back(0);
|
||||
MappingList maplist;
|
||||
mappings.push_back(maplist);
|
||||
}
|
||||
}
|
||||
|
||||
void InputManager::update() {
|
||||
SDL_JoystickUpdate();
|
||||
|
||||
events.clear();
|
||||
SDL_Event event;
|
||||
while (SDL_PollEvent(&event)) {
|
||||
SDL_Event evcopy = event;
|
||||
events.push_back(evcopy);
|
||||
}
|
||||
|
||||
Uint32 tick = SDL_GetTicks();
|
||||
for (uint x=0; x<actions.size(); x++) {
|
||||
actions[x] = false;
|
||||
if (isActive(x)) {
|
||||
if (tick-actionTick[x]>interval[x]) {
|
||||
actions[x] = true;
|
||||
actionTick[x] = tick;
|
||||
}
|
||||
} else {
|
||||
actionTick[x] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int InputManager::count() {
|
||||
return actions.size();
|
||||
}
|
||||
|
||||
void InputManager::setInterval(int ms, int action) {
|
||||
if (action<0)
|
||||
for (uint x=0; x<interval.size(); x++)
|
||||
interval[x] = ms;
|
||||
else if ((uint)action < interval.size())
|
||||
interval[action] = ms;
|
||||
}
|
||||
|
||||
bool InputManager::operator[](int action) {
|
||||
if (action<0 || (uint)action>=actions.size()) return false;
|
||||
return actions[action];
|
||||
}
|
||||
|
||||
bool InputManager::isActive(int action) {
|
||||
for (uint x=0; x<mappings[action].size(); x++) {
|
||||
InputMap map = mappings[action][x];
|
||||
|
||||
switch (map.type) {
|
||||
case InputManager::MAPPING_TYPE_BUTTON:
|
||||
if (map.num < joysticks.size() && SDL_JoystickGetButton(joysticks[map.num], map.value))
|
||||
return true;
|
||||
break;
|
||||
case InputManager::MAPPING_TYPE_AXYS:
|
||||
if (map.num < joysticks.size()) {
|
||||
int axyspos = SDL_JoystickGetAxis(joysticks[map.num], map.value);
|
||||
if (map.treshold<0 && axyspos < map.treshold) return true;
|
||||
if (map.treshold>0 && axyspos > map.treshold) return true;
|
||||
}
|
||||
break;
|
||||
case InputManager::MAPPING_TYPE_KEYPRESS:
|
||||
for (uint ex=0; ex<events.size(); ex++) {
|
||||
if (events[ex].type == SDL_KEYDOWN && events[ex].key.keysym.sym == map.value)
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
89
src/inputmanager.h
Normal file
89
src/inputmanager.h
Normal file
@@ -0,0 +1,89 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2006 by Massimiliano Torromeo *
|
||||
* massimiliano.torromeo@gmail.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
#ifndef INPUTMANAGER_H
|
||||
#define INPUTMANAGER_H
|
||||
|
||||
#define ACTION_UP 0
|
||||
#define ACTION_DOWN 1
|
||||
#define ACTION_LEFT 2
|
||||
#define ACTION_RIGHT 3
|
||||
#define ACTION_A 4
|
||||
#define ACTION_B 5
|
||||
#define ACTION_X 6
|
||||
#define ACTION_Y 7
|
||||
#define ACTION_L 8
|
||||
#define ACTION_R 9
|
||||
#define ACTION_START 10
|
||||
#define ACTION_SELECT 11
|
||||
#define ACTION_VOLUP 12
|
||||
#define ACTION_VOLDOWN 13
|
||||
|
||||
#include <SDL.h>
|
||||
#include <SDL_image.h>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
using std::vector;
|
||||
using std::string;
|
||||
|
||||
typedef struct {
|
||||
int type;
|
||||
uint num;
|
||||
int value;
|
||||
int treshold;
|
||||
} InputMap;
|
||||
|
||||
typedef vector<InputMap> MappingList;
|
||||
typedef vector<SDL_Event> SDLEventList;
|
||||
|
||||
/**
|
||||
Manages all input peripherals
|
||||
@author Massimiliano Torromeo <massimiliano.torromeo@gmail.com>
|
||||
*/
|
||||
class InputManager {
|
||||
private:
|
||||
InputMap getInputMapping(int action);
|
||||
vector<Uint32> actionTick;
|
||||
vector<Uint32> interval;
|
||||
SDLEventList events;
|
||||
|
||||
public:
|
||||
static const int MAPPING_TYPE_UNDEFINED = -1;
|
||||
static const int MAPPING_TYPE_BUTTON = 0;
|
||||
static const int MAPPING_TYPE_AXYS = 1;
|
||||
static const int MAPPING_TYPE_KEYPRESS = 2;
|
||||
|
||||
InputManager();
|
||||
~InputManager();
|
||||
void init(string conffile = "input.conf");
|
||||
|
||||
vector <SDL_Joystick*> joysticks;
|
||||
vector<bool> actions;
|
||||
vector<MappingList> mappings;
|
||||
|
||||
void update();
|
||||
int count();
|
||||
void setActionsCount(int count);
|
||||
void setInterval(int ms, int action = -1);
|
||||
bool operator[](int action);
|
||||
bool isActive(int action);
|
||||
};
|
||||
|
||||
#endif
|
||||
5212
src/jz4740.h
Normal file
5212
src/jz4740.h
Normal file
File diff suppressed because it is too large
Load Diff
124
src/link.cpp
Normal file
124
src/link.cpp
Normal file
@@ -0,0 +1,124 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2006 by Massimiliano Torromeo *
|
||||
* massimiliano.torromeo@gmail.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include "link.h"
|
||||
#include "menu.h"
|
||||
#include "selector.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace fastdelegate;
|
||||
|
||||
Link::Link(GMenu2X *gmenu2x) : Button(gmenu2x, true) {
|
||||
this->gmenu2x = gmenu2x;
|
||||
action = MakeDelegate(this, &Link::run);
|
||||
edited = false;
|
||||
iconPath = gmenu2x->sc.getSkinFilePath("icons/generic.png");
|
||||
iconX = 0;
|
||||
padding = 0;
|
||||
}
|
||||
|
||||
void Link::run() {}
|
||||
|
||||
void Link::paint() {
|
||||
gmenu2x->sc[getIconPath()]->blit(gmenu2x->s, iconX, rect.y+padding, 32,32);
|
||||
gmenu2x->s->write( gmenu2x->font, getTitle(), iconX+16, rect.y+gmenu2x->skinConfInt["linkHeight"]-padding, SFontHAlignCenter, SFontVAlignBottom );
|
||||
}
|
||||
|
||||
bool Link::paintHover() {
|
||||
if (gmenu2x->useSelectionPng)
|
||||
gmenu2x->sc["imgs/selection.png"]->blit(gmenu2x->s,rect,SFontHAlignCenter,SFontVAlignMiddle);
|
||||
else
|
||||
gmenu2x->s->box(rect.x, rect.y, rect.w, rect.h, gmenu2x->skinConfColors["selectionBg"]);
|
||||
return true;
|
||||
}
|
||||
|
||||
string Link::getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
void Link::setTitle(string title) {
|
||||
this->title = title;
|
||||
edited = true;
|
||||
}
|
||||
|
||||
string Link::getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
void Link::setDescription(string description) {
|
||||
this->description = description;
|
||||
edited = true;
|
||||
}
|
||||
|
||||
string Link::getIcon() {
|
||||
return icon;
|
||||
}
|
||||
|
||||
void Link::setIcon(string icon) {
|
||||
string skinpath = gmenu2x->getExePath()+"skins/"+gmenu2x->confStr["skin"];
|
||||
if (icon.substr(0,skinpath.length()) == skinpath) {
|
||||
string tempIcon = icon.substr(skinpath.length(), icon.length());
|
||||
string::size_type pos = tempIcon.find("/");
|
||||
if (pos != string::npos)
|
||||
icon = "skin:"+tempIcon.substr(pos+1,icon.length());
|
||||
}
|
||||
|
||||
iconPath = strreplace(icon,"skin:",skinpath+"/");
|
||||
if (iconPath.empty() || !fileExists(iconPath)) {
|
||||
iconPath = strreplace(icon,"skin:",gmenu2x->getExePath()+"skins/Default/");
|
||||
if (!fileExists(iconPath)) searchIcon();
|
||||
}
|
||||
|
||||
this->icon = icon;
|
||||
edited = true;
|
||||
}
|
||||
|
||||
string Link::searchIcon() {
|
||||
iconPath = gmenu2x->sc.getSkinFilePath("icons/generic.png");
|
||||
return iconPath;
|
||||
}
|
||||
|
||||
string Link::getIconPath() {
|
||||
if (iconPath.empty()) searchIcon();
|
||||
return iconPath;
|
||||
}
|
||||
|
||||
void Link::setIconPath(string icon) {
|
||||
if (fileExists(icon))
|
||||
iconPath = icon;
|
||||
else
|
||||
iconPath = gmenu2x->sc.getSkinFilePath("icons/generic.png");
|
||||
}
|
||||
|
||||
void Link::setSize(int w, int h) {
|
||||
Button::setSize(w,h);
|
||||
recalcCoordinates();
|
||||
}
|
||||
|
||||
void Link::setPosition(int x, int y) {
|
||||
Button::setPosition(x,y);
|
||||
recalcCoordinates();
|
||||
}
|
||||
|
||||
void Link::recalcCoordinates() {
|
||||
iconX = rect.x+(rect.w-32)/2;
|
||||
padding = (gmenu2x->skinConfInt["linkHeight"] - 32 - gmenu2x->font->getLineHeight()) / 3;
|
||||
}
|
||||
70
src/link.h
Normal file
70
src/link.h
Normal file
@@ -0,0 +1,70 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2006 by Massimiliano Torromeo *
|
||||
* massimiliano.torromeo@gmail.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
#ifndef LINK_H
|
||||
#define LINK_H
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
#include "button.h"
|
||||
|
||||
using std::string;
|
||||
|
||||
class GMenu2X;
|
||||
|
||||
/**
|
||||
Base class that represents a link on screen.
|
||||
|
||||
@author Massimiliano Torromeo <massimiliano.torromeo@gmail.com>
|
||||
*/
|
||||
class Link : public Button {
|
||||
private:
|
||||
uint iconX, padding;
|
||||
|
||||
protected:
|
||||
bool edited;
|
||||
string title, description, icon, iconPath;
|
||||
|
||||
void recalcCoordinates();
|
||||
|
||||
public:
|
||||
Link(GMenu2X *gmenu2x);
|
||||
virtual ~Link() {};
|
||||
|
||||
virtual void paint();
|
||||
virtual bool paintHover();
|
||||
|
||||
void setSize(int w, int h);
|
||||
void setPosition(int x, int y);
|
||||
|
||||
string getTitle();
|
||||
void setTitle(string title);
|
||||
string getDescription();
|
||||
void setDescription(string description);
|
||||
string getIcon();
|
||||
void setIcon(string icon);
|
||||
virtual string searchIcon();
|
||||
string getIconPath();
|
||||
void setIconPath(string icon);
|
||||
|
||||
virtual void run();
|
||||
};
|
||||
|
||||
#endif
|
||||
34
src/linkaction.cpp
Normal file
34
src/linkaction.cpp
Normal file
@@ -0,0 +1,34 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2006 by Massimiliano Torromeo *
|
||||
* massimiliano.torromeo@gmail.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include "linkaction.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
LinkAction::LinkAction(GMenu2X *gmenu2x, LinkRunAction act)
|
||||
: Link(gmenu2x) {
|
||||
this->gmenu2x = gmenu2x;
|
||||
this->action = act;
|
||||
}
|
||||
|
||||
void LinkAction::run() {
|
||||
this->action();
|
||||
}
|
||||
50
src/linkaction.h
Normal file
50
src/linkaction.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2006 by Massimiliano Torromeo *
|
||||
* massimiliano.torromeo@gmail.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
#ifndef LINKACTION_H
|
||||
#define LINKACTION_H
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
#include "FastDelegate.h"
|
||||
#include "link.h"
|
||||
|
||||
using std::string;
|
||||
using fastdelegate::FastDelegate0;
|
||||
|
||||
typedef FastDelegate0<> LinkRunAction;
|
||||
|
||||
class GMenu2X;
|
||||
|
||||
/**
|
||||
Executes an action when launched.
|
||||
|
||||
@author Massimiliano Torromeo <massimiliano.torromeo@gmail.com>
|
||||
*/
|
||||
class LinkAction : public Link {
|
||||
private:
|
||||
LinkRunAction action;
|
||||
public:
|
||||
LinkAction(GMenu2X *gmenu2x, LinkRunAction act);
|
||||
virtual ~LinkAction() {};
|
||||
virtual void run();
|
||||
};
|
||||
|
||||
#endif
|
||||
574
src/linkapp.cpp
Normal file
574
src/linkapp.cpp
Normal file
@@ -0,0 +1,574 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2006 by Massimiliano Torromeo *
|
||||
* massimiliano.torromeo@gmail.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include "linkapp.h"
|
||||
#include "menu.h"
|
||||
#include "selector.h"
|
||||
#include "textmanualdialog.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
LinkApp::LinkApp(GMenu2X *gmenu2x, const char* linkfile)
|
||||
: Link(gmenu2x) {
|
||||
this->gmenu2x = gmenu2x;
|
||||
manual = "";
|
||||
file = linkfile;
|
||||
wrapper = false;
|
||||
dontleave = false;
|
||||
setClock(336);
|
||||
setVolume(-1);
|
||||
//G
|
||||
//setGamma(0);
|
||||
setBacklight(100);
|
||||
selectordir = "";
|
||||
selectorfilter = "";
|
||||
icon = iconPath = "";
|
||||
selectorbrowser = false;
|
||||
useRamTimings = false;
|
||||
|
||||
string line;
|
||||
ifstream infile (linkfile, ios_base::in);
|
||||
while (getline(infile, line, '\n')) {
|
||||
line = trim(line);
|
||||
if (line=="") continue;
|
||||
if (line[0]=='#') continue;
|
||||
|
||||
string::size_type position = line.find("=");
|
||||
string name = trim(line.substr(0,position));
|
||||
string value = trim(line.substr(position+1));
|
||||
if (name == "title") {
|
||||
title = value;
|
||||
} else if (name == "description") {
|
||||
description = value;
|
||||
} else if (name == "icon") {
|
||||
setIcon(value);
|
||||
} else if (name == "exec") {
|
||||
exec = value;
|
||||
} else if (name == "params") {
|
||||
params = value;
|
||||
} else if (name == "workdir") {
|
||||
workdir = value;
|
||||
} else if (name == "manual") {
|
||||
manual = value;
|
||||
} else if (name == "wrapper") {
|
||||
if (value=="true") wrapper = true;
|
||||
} else if (name == "dontleave") {
|
||||
if (value=="true") dontleave = true;
|
||||
} else if (name == "clock") {
|
||||
setClock( atoi(value.c_str()) );
|
||||
//G
|
||||
} else if (name == "gamma") {
|
||||
setGamma( atoi(value.c_str()) );
|
||||
} else if (name == "backlight") {
|
||||
setBacklight( atoi(value.c_str()) );
|
||||
} else if (name == "volume") {
|
||||
setVolume( atoi(value.c_str()) );
|
||||
} else if (name == "selectordir") {
|
||||
setSelectorDir( value );
|
||||
} else if (name == "selectorbrowser") {
|
||||
if (value=="true") selectorbrowser = true;
|
||||
} else if (name == "useramtimings") {
|
||||
if (value=="true") useRamTimings = true;
|
||||
} else if (name == "selectorfilter") {
|
||||
setSelectorFilter( value );
|
||||
} else if (name == "selectorscreens") {
|
||||
setSelectorScreens( value );
|
||||
} else if (name == "selectoraliases") {
|
||||
setAliasFile( value );
|
||||
} else {
|
||||
cout << "Unrecognized option: " << name << endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
infile.close();
|
||||
|
||||
if (iconPath.empty()) searchIcon();
|
||||
|
||||
edited = false;
|
||||
}
|
||||
|
||||
string LinkApp::searchIcon() {
|
||||
string execicon = exec;
|
||||
string::size_type pos = exec.rfind(".");
|
||||
if (pos != string::npos) execicon = exec.substr(0,pos);
|
||||
execicon += ".png";
|
||||
string exectitle = execicon;
|
||||
pos = execicon.rfind("/");
|
||||
if (pos != string::npos)
|
||||
string exectitle = execicon.substr(pos+1,execicon.length());
|
||||
|
||||
if (!gmenu2x->sc.getSkinFilePath("icons/"+exectitle).empty())
|
||||
iconPath = gmenu2x->sc.getSkinFilePath("icons/"+exectitle);
|
||||
else if (fileExists(execicon))
|
||||
iconPath = execicon;
|
||||
else
|
||||
iconPath = gmenu2x->sc.getSkinFilePath("icons/generic.png");
|
||||
|
||||
return iconPath;
|
||||
}
|
||||
|
||||
int LinkApp::clock() {
|
||||
return iclock;
|
||||
}
|
||||
|
||||
string LinkApp::clockStr(int maxClock) {
|
||||
if (iclock>maxClock) setClock(maxClock);
|
||||
return sclock;
|
||||
}
|
||||
|
||||
void LinkApp::setClock(int mhz) {
|
||||
iclock = constrain(mhz,200,430);
|
||||
stringstream ss;
|
||||
sclock = "";
|
||||
ss << iclock << "Mhz";
|
||||
ss >> sclock;
|
||||
|
||||
edited = true;
|
||||
}
|
||||
|
||||
int LinkApp::volume() {
|
||||
return ivolume;
|
||||
}
|
||||
|
||||
string LinkApp::volumeStr() {
|
||||
return svolume;
|
||||
}
|
||||
|
||||
void LinkApp::setVolume(int vol) {
|
||||
ivolume = constrain(vol,-1,100);
|
||||
stringstream ss;
|
||||
svolume = "";
|
||||
if (ivolume<0)
|
||||
ss << gmenu2x->confInt["globalVolume"];
|
||||
else
|
||||
ss << ivolume;
|
||||
ss >> svolume;
|
||||
|
||||
edited = true;
|
||||
}
|
||||
|
||||
int LinkApp::backlight()
|
||||
{
|
||||
return ibacklight;
|
||||
}
|
||||
|
||||
string LinkApp::backlightStr()
|
||||
{
|
||||
return sbacklight;
|
||||
}
|
||||
|
||||
void LinkApp::setBacklight(int val)
|
||||
{
|
||||
ibacklight = constrain(val,5,100);
|
||||
stringstream ss;
|
||||
sbacklight = "";
|
||||
ss << ibacklight;
|
||||
ss >> sbacklight;
|
||||
|
||||
edited = true;
|
||||
}
|
||||
//G
|
||||
int LinkApp::gamma() {
|
||||
return igamma;
|
||||
}
|
||||
|
||||
string LinkApp::gammaStr() {
|
||||
return sgamma;
|
||||
}
|
||||
|
||||
void LinkApp::setGamma(int gamma) {
|
||||
igamma = constrain(gamma,0,100);
|
||||
stringstream ss;
|
||||
sgamma = "";
|
||||
ss << igamma;
|
||||
ss >> sgamma;
|
||||
|
||||
edited = true;
|
||||
}
|
||||
// /G
|
||||
|
||||
bool LinkApp::targetExists() {
|
||||
#ifndef TARGET_GP2X
|
||||
return true; //For displaying elements during testing on pc
|
||||
#endif
|
||||
|
||||
string target = exec;
|
||||
if (!exec.empty() && exec[0]!='/' && !workdir.empty())
|
||||
target = workdir + "/" + exec;
|
||||
|
||||
return fileExists(target);
|
||||
}
|
||||
|
||||
bool LinkApp::save() {
|
||||
if (!edited) return false;
|
||||
|
||||
ofstream f(file.c_str());
|
||||
if (f.is_open()) {
|
||||
if (title!="" ) f << "title=" << title << endl;
|
||||
if (description!="" ) f << "description=" << description << endl;
|
||||
if (icon!="" ) f << "icon=" << icon << endl;
|
||||
if (exec!="" ) f << "exec=" << exec << endl;
|
||||
if (params!="" ) f << "params=" << params << endl;
|
||||
if (workdir!="" ) f << "workdir=" << workdir << endl;
|
||||
if (manual!="" ) f << "manual=" << manual << endl;
|
||||
if (iclock!=0 ) f << "clock=" << iclock << endl;
|
||||
if (useRamTimings ) f << "useramtimings=true" << endl;
|
||||
if (ivolume>0 ) f << "volume=" << ivolume << endl;
|
||||
//G
|
||||
if (igamma!=0 ) f << "gamma=" << igamma << endl;
|
||||
if (ibacklight!=0 ) f << "backlight=" << ibacklight << endl;
|
||||
if (selectordir!="" ) f << "selectordir=" << selectordir << endl;
|
||||
if (selectorbrowser ) f << "selectorbrowser=true" << endl;
|
||||
if (selectorfilter!="" ) f << "selectorfilter=" << selectorfilter << endl;
|
||||
if (selectorscreens!="") f << "selectorscreens=" << selectorscreens << endl;
|
||||
if (aliasfile!="" ) f << "selectoraliases=" << aliasfile << endl;
|
||||
if (wrapper ) f << "wrapper=true" << endl;
|
||||
if (dontleave ) f << "dontleave=true" << endl;
|
||||
f.close();
|
||||
sync();
|
||||
return true;
|
||||
} else
|
||||
cout << "\033[0;34mGMENU2X:\033[0;31m Error while opening the file '" << file << "' for write\033[0m" << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
void LinkApp::drawRun() {
|
||||
//Darkened background
|
||||
gmenu2x->s->box(0, 0, gmenu2x->resX, gmenu2x->resY, 0,0,0,150);
|
||||
|
||||
string text = gmenu2x->tr.translate("Launching $1",getTitle().c_str(),NULL);
|
||||
int textW = gmenu2x->font->getTextWidth(text);
|
||||
int boxW = 62+textW;
|
||||
int halfBoxW = boxW/2;
|
||||
|
||||
//outer box
|
||||
gmenu2x->s->box(gmenu2x->halfX-2-halfBoxW, gmenu2x->halfY-23, halfBoxW*2+5, 47, gmenu2x->skinConfColors["messageBoxBg"]);
|
||||
//inner rectangle
|
||||
gmenu2x->s->rectangle(gmenu2x->halfX-halfBoxW, gmenu2x->halfY-21, boxW, 42, gmenu2x->skinConfColors["messageBoxBorder"]);
|
||||
|
||||
int x = gmenu2x->halfX+10-halfBoxW;
|
||||
/*if (getIcon()!="")
|
||||
gmenu2x->sc[getIcon()]->blit(gmenu2x->s,x,104);
|
||||
else
|
||||
gmenu2x->sc["icons/generic.png"]->blit(gmenu2x->s,x,104);*/
|
||||
gmenu2x->sc[getIconPath()]->blit(gmenu2x->s,x,gmenu2x->halfY-16);
|
||||
gmenu2x->s->write( gmenu2x->font, text, x+42, gmenu2x->halfY+1, SFontHAlignLeft, SFontVAlignMiddle );
|
||||
gmenu2x->s->flip();
|
||||
}
|
||||
|
||||
void LinkApp::run() {
|
||||
if (selectordir!="")
|
||||
selector();
|
||||
else
|
||||
launch();
|
||||
}
|
||||
|
||||
void LinkApp::showManual() {
|
||||
if (manual=="" || !fileExists(manual)) return;
|
||||
|
||||
// Png manuals
|
||||
string ext8 = manual.substr(manual.size()-8,8);
|
||||
if (ext8==".man.png" || ext8==".man.bmp" || ext8==".man.jpg" || manual.substr(manual.size()-9,9)==".man.jpeg") {
|
||||
//Raise the clock to speed-up the loading of the manual
|
||||
gmenu2x->setClock(336);
|
||||
|
||||
Surface pngman(manual);
|
||||
Surface bg(gmenu2x->confStr["wallpaper"],false);
|
||||
stringstream ss;
|
||||
string pageStatus;
|
||||
|
||||
bool close = false, repaint = true;
|
||||
int page=0, pagecount=pngman.raw->w/320;
|
||||
|
||||
ss << pagecount;
|
||||
string spagecount;
|
||||
ss >> spagecount;
|
||||
|
||||
//Lower the clock
|
||||
gmenu2x->setClock(gmenu2x->confInt["menuClock"]);
|
||||
|
||||
while (!close) {
|
||||
if (repaint) {
|
||||
bg.blit(gmenu2x->s, 0, 0);
|
||||
pngman.blit(gmenu2x->s, -page*320, 0);
|
||||
|
||||
gmenu2x->drawBottomBar();
|
||||
gmenu2x->drawButton(gmenu2x->s, "x", gmenu2x->tr["Exit"],
|
||||
gmenu2x->drawButton(gmenu2x->s, "right", gmenu2x->tr["Change page"],
|
||||
gmenu2x->drawButton(gmenu2x->s, "left", "", 5)-10));
|
||||
|
||||
ss.clear();
|
||||
ss << page+1;
|
||||
ss >> pageStatus;
|
||||
pageStatus = gmenu2x->tr["Page"]+": "+pageStatus+"/"+spagecount;
|
||||
gmenu2x->s->write(gmenu2x->font, pageStatus, 310, 230, SFontHAlignRight, SFontVAlignMiddle);
|
||||
|
||||
gmenu2x->s->flip();
|
||||
repaint = false;
|
||||
}
|
||||
|
||||
gmenu2x->input.update();
|
||||
if ( gmenu2x->input[ACTION_Y] || gmenu2x->input[ACTION_X] || gmenu2x->input[ACTION_START] ) close = true;
|
||||
if ( gmenu2x->input[ACTION_LEFT] && page>0 ) { page--; repaint=true; }
|
||||
if ( gmenu2x->input[ACTION_RIGHT] && page<pagecount-1 ) { page++; repaint=true; }
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Txt manuals
|
||||
if (manual.substr(manual.size()-8,8)==".man.txt") {
|
||||
vector<string> txtman;
|
||||
|
||||
string line;
|
||||
ifstream infile(manual.c_str(), ios_base::in);
|
||||
if (infile.is_open()) {
|
||||
gmenu2x->setClock(336);
|
||||
while (getline(infile, line, '\n')) txtman.push_back(line);
|
||||
infile.close();
|
||||
|
||||
TextManualDialog tmd(gmenu2x, getTitle(), getIconPath(), &txtman);
|
||||
gmenu2x->setClock(gmenu2x->confInt["menuClock"]);
|
||||
tmd.exec();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//Readmes
|
||||
vector<string> readme;
|
||||
|
||||
string line;
|
||||
ifstream infile(manual.c_str(), ios_base::in);
|
||||
if (infile.is_open()) {
|
||||
gmenu2x->setClock(336);
|
||||
while (getline(infile, line, '\n')) readme.push_back(line);
|
||||
infile.close();
|
||||
|
||||
TextDialog td(gmenu2x, getTitle(), "ReadMe", getIconPath(), &readme);
|
||||
gmenu2x->setClock(gmenu2x->confInt["menuClock"]);
|
||||
td.exec();
|
||||
}
|
||||
}
|
||||
|
||||
void LinkApp::selector(int startSelection, string selectorDir) {
|
||||
//Run selector interface
|
||||
Selector sel(gmenu2x, this, selectorDir);
|
||||
int selection = sel.exec(startSelection);
|
||||
if (selection!=-1) {
|
||||
gmenu2x->writeTmp(selection,sel.dir);
|
||||
launch(sel.file, sel.dir);
|
||||
}
|
||||
}
|
||||
|
||||
void LinkApp::launch(string selectedFile, string selectedDir) {
|
||||
drawRun();
|
||||
save();
|
||||
#ifndef TARGET_GP2X
|
||||
//delay for testing
|
||||
SDL_Delay(1000);
|
||||
#endif
|
||||
|
||||
//Set correct working directory
|
||||
string wd = workdir;
|
||||
if (wd=="") {
|
||||
string::size_type pos = exec.rfind("/");
|
||||
if (pos!=string::npos)
|
||||
wd = exec.substr(0,pos);
|
||||
}
|
||||
if (!wd.empty()) {
|
||||
if (wd[0]!='/') wd = gmenu2x->getExePath() + wd;
|
||||
chdir(wd.c_str());
|
||||
}
|
||||
|
||||
//selectedFile
|
||||
if (selectedFile!="") {
|
||||
string selectedFileExtension;
|
||||
string::size_type i = selectedFile.rfind(".");
|
||||
if (i != string::npos) {
|
||||
selectedFileExtension = selectedFile.substr(i,selectedFile.length());
|
||||
selectedFile = selectedFile.substr(0,i);
|
||||
}
|
||||
|
||||
if (selectedDir=="")
|
||||
selectedDir = getSelectorDir();
|
||||
if (params=="") {
|
||||
params = cmdclean(selectedDir+selectedFile+selectedFileExtension);
|
||||
} else {
|
||||
string origParams = params;
|
||||
params = strreplace(params,"[selFullPath]",cmdclean(selectedDir+selectedFile+selectedFileExtension));
|
||||
params = strreplace(params,"[selPath]",cmdclean(selectedDir));
|
||||
params = strreplace(params,"[selFile]",cmdclean(selectedFile));
|
||||
params = strreplace(params,"[selExt]",cmdclean(selectedFileExtension));
|
||||
if (params == origParams) params += " " + cmdclean(selectedDir+selectedFile+selectedFileExtension);
|
||||
}
|
||||
}
|
||||
|
||||
if (useRamTimings)
|
||||
gmenu2x->applyRamTimings();
|
||||
if (volume()>=0)
|
||||
gmenu2x->setVolume(volume());
|
||||
|
||||
#ifdef DEBUG
|
||||
cout << "\033[0;34mGMENU2X:\033[0m Executing '" << title << "' (" << exec << " " << params << ")" << endl;
|
||||
#endif
|
||||
|
||||
//check if we have to quit
|
||||
string command = cmdclean(exec);
|
||||
|
||||
// Check to see if permissions are desirable
|
||||
struct stat fstat;
|
||||
if( stat( command.c_str(), &fstat ) == 0 ) {
|
||||
struct stat newstat = fstat;
|
||||
if( S_IRUSR != ( fstat.st_mode & S_IRUSR ) )
|
||||
newstat.st_mode |= S_IRUSR;
|
||||
if( S_IXUSR != ( fstat.st_mode & S_IXUSR ) )
|
||||
newstat.st_mode |= S_IXUSR;
|
||||
if( fstat.st_mode != newstat.st_mode )
|
||||
chmod( command.c_str(), newstat.st_mode );
|
||||
} // else, well.. we are no worse off :)
|
||||
|
||||
if (params!="") command += " " + params;
|
||||
if (gmenu2x->confInt["outputLogs"]) command += " &> " + cmdclean(gmenu2x->getExePath()) + "/log.txt";
|
||||
if (wrapper) command += "; sync & cd "+cmdclean(gmenu2x->getExePath())+"; exec ./gmenu2x";
|
||||
if (dontleave) {
|
||||
system(command.c_str());
|
||||
} else {
|
||||
if (gmenu2x->confInt["saveSelection"] && (gmenu2x->confInt["section"]!=gmenu2x->menu->selSectionIndex() || gmenu2x->confInt["link"]!=gmenu2x->menu->selLinkIndex()))
|
||||
gmenu2x->writeConfig();
|
||||
if (gmenu2x->fwType == "open2x" && gmenu2x->savedVolumeMode != gmenu2x->volumeMode)
|
||||
gmenu2x->writeConfigOpen2x();
|
||||
if (selectedFile=="")
|
||||
gmenu2x->writeTmp();
|
||||
gmenu2x->quit();
|
||||
if (clock()!=gmenu2x->confInt["menuClock"])
|
||||
gmenu2x->setClock(clock());
|
||||
//if (gamma()!=0 && gamma()!=gmenu2x->confInt["gamma"])
|
||||
// gmenu2x->setGamma(gamma());
|
||||
if((backlight() != 0) && (backlight() != gmenu2x->confInt["backlight"]))
|
||||
gmenu2x->setBacklight(backlight());
|
||||
|
||||
execlp("/bin/sh","/bin/sh","-c",command.c_str(),NULL);
|
||||
//if execution continues then something went wrong and as we already called SDL_Quit we cannot continue
|
||||
//try relaunching gmenu2x
|
||||
chdir(gmenu2x->getExePath().c_str());
|
||||
execlp("./gmenu2x", "./gmenu2x", NULL);
|
||||
}
|
||||
|
||||
|
||||
chdir(gmenu2x->getExePath().c_str());
|
||||
}
|
||||
|
||||
string LinkApp::getExec() {
|
||||
return exec;
|
||||
}
|
||||
|
||||
void LinkApp::setExec(string exec) {
|
||||
this->exec = exec;
|
||||
edited = true;
|
||||
}
|
||||
|
||||
string LinkApp::getParams() {
|
||||
return params;
|
||||
}
|
||||
|
||||
void LinkApp::setParams(string params) {
|
||||
this->params = params;
|
||||
edited = true;
|
||||
}
|
||||
|
||||
string LinkApp::getWorkdir() {
|
||||
return workdir;
|
||||
}
|
||||
|
||||
void LinkApp::setWorkdir(string workdir) {
|
||||
this->workdir = workdir;
|
||||
edited = true;
|
||||
}
|
||||
|
||||
string LinkApp::getManual() {
|
||||
return manual;
|
||||
}
|
||||
|
||||
void LinkApp::setManual(string manual) {
|
||||
this->manual = manual;
|
||||
edited = true;
|
||||
}
|
||||
|
||||
string LinkApp::getSelectorDir() {
|
||||
return selectordir;
|
||||
}
|
||||
|
||||
void LinkApp::setSelectorDir(string selectordir) {
|
||||
if (selectordir!="" && selectordir[selectordir.length()-1]!='/') selectordir += "/";
|
||||
this->selectordir = selectordir;
|
||||
edited = true;
|
||||
}
|
||||
|
||||
bool LinkApp::getSelectorBrowser() {
|
||||
return selectorbrowser;
|
||||
}
|
||||
|
||||
void LinkApp::setSelectorBrowser(bool value) {
|
||||
selectorbrowser = value;
|
||||
edited = true;
|
||||
}
|
||||
|
||||
bool LinkApp::getUseRamTimings() {
|
||||
return useRamTimings;
|
||||
}
|
||||
|
||||
void LinkApp::setUseRamTimings(bool value) {
|
||||
useRamTimings = value;
|
||||
edited = true;
|
||||
}
|
||||
|
||||
string LinkApp::getSelectorFilter() {
|
||||
return selectorfilter;
|
||||
}
|
||||
|
||||
void LinkApp::setSelectorFilter(string selectorfilter) {
|
||||
this->selectorfilter = selectorfilter;
|
||||
edited = true;
|
||||
}
|
||||
|
||||
string LinkApp::getSelectorScreens() {
|
||||
return selectorscreens;
|
||||
}
|
||||
|
||||
void LinkApp::setSelectorScreens(string selectorscreens) {
|
||||
this->selectorscreens = selectorscreens;
|
||||
edited = true;
|
||||
}
|
||||
|
||||
string LinkApp::getAliasFile() {
|
||||
return aliasfile;
|
||||
}
|
||||
|
||||
void LinkApp::setAliasFile(string aliasfile) {
|
||||
if (fileExists(aliasfile)) {
|
||||
this->aliasfile = aliasfile;
|
||||
edited = true;
|
||||
}
|
||||
}
|
||||
109
src/linkapp.h
Normal file
109
src/linkapp.h
Normal file
@@ -0,0 +1,109 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2006 by Massimiliano Torromeo *
|
||||
* massimiliano.torromeo@gmail.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
#ifndef LINKAPP_H
|
||||
#define LINKAPP_H
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
#include "link.h"
|
||||
|
||||
using std::string;
|
||||
|
||||
class GMenu2X;
|
||||
|
||||
/**
|
||||
Parses links files.
|
||||
|
||||
@author Massimiliano Torromeo <massimiliano.torromeo@gmail.com>
|
||||
*/
|
||||
class LinkApp : public Link {
|
||||
private:
|
||||
string sclock, svolume;
|
||||
int iclock, ivolume;
|
||||
//G
|
||||
string sgamma;
|
||||
string sbacklight;
|
||||
//G
|
||||
int igamma;
|
||||
int ibacklight;
|
||||
string exec, params, workdir, manual, selectordir, selectorfilter, selectorscreens;
|
||||
bool selectorbrowser, useRamTimings;
|
||||
void drawRun();
|
||||
|
||||
string aliasfile;
|
||||
|
||||
public:
|
||||
LinkApp(GMenu2X *gmenu2x, const char* linkfile);
|
||||
virtual string searchIcon();
|
||||
|
||||
string getExec();
|
||||
void setExec(string exec);
|
||||
string getParams();
|
||||
void setParams(string params);
|
||||
string getWorkdir();
|
||||
void setWorkdir(string workdir);
|
||||
string getManual();
|
||||
void setManual(string manual);
|
||||
string getSelectorDir();
|
||||
void setSelectorDir(string selectordir);
|
||||
bool getSelectorBrowser();
|
||||
void setSelectorBrowser(bool value);
|
||||
bool getUseRamTimings();
|
||||
void setUseRamTimings(bool value);
|
||||
string getSelectorScreens();
|
||||
void setSelectorScreens(string selectorscreens);
|
||||
string getSelectorFilter();
|
||||
void setSelectorFilter(string selectorfilter);
|
||||
string getAliasFile();
|
||||
void setAliasFile(string aliasfile);
|
||||
|
||||
string file;
|
||||
|
||||
int clock();
|
||||
string clockStr(int maxClock);
|
||||
void setClock(int mhz);
|
||||
|
||||
int volume();
|
||||
string volumeStr();
|
||||
void setVolume(int vol);
|
||||
|
||||
//G
|
||||
int gamma();
|
||||
string gammaStr();
|
||||
void setGamma(int gamma);
|
||||
|
||||
int backlight();
|
||||
string backlightStr();
|
||||
void setBacklight(int val);
|
||||
// /G
|
||||
|
||||
bool wrapper;
|
||||
bool dontleave;
|
||||
|
||||
bool save();
|
||||
void run();
|
||||
void showManual();
|
||||
void selector(int startSelection=0, string selectorDir="");
|
||||
void launch(string selectedFile="", string selectedDir="");
|
||||
bool targetExists();
|
||||
};
|
||||
|
||||
#endif
|
||||
78
src/listview.cpp
Normal file
78
src/listview.cpp
Normal file
@@ -0,0 +1,78 @@
|
||||
#include "listview.h"
|
||||
|
||||
ListView::ListView(GMenu2X *gmenu2x) {
|
||||
this->gmenu2x = gmenu2x;
|
||||
firstDisplayItem = selectedItem = 0;
|
||||
itemsPerPage = 11;
|
||||
}
|
||||
|
||||
ListView::~ ListView() {}
|
||||
|
||||
ListViewItem * ListView::add(ListViewItem *item) {
|
||||
items.push_back(item);
|
||||
return item;
|
||||
}
|
||||
|
||||
ListViewItem * ListView::add(string text) {
|
||||
ListViewItem *item = new ListViewItem(this,text);
|
||||
return add(item);
|
||||
}
|
||||
|
||||
void ListView::del(ListViewItem * item) {
|
||||
vector<ListViewItem*>::iterator p = find(items.begin(), items.end(), item);
|
||||
if (p != items.end())
|
||||
items.erase(p);
|
||||
}
|
||||
|
||||
void ListView::del(int itemIndex) {
|
||||
items.erase(items.begin()+itemIndex);
|
||||
}
|
||||
|
||||
void ListView::clear() {
|
||||
items.clear();
|
||||
}
|
||||
|
||||
ListViewItem * ListView::operator [](int index) {
|
||||
return items[index];
|
||||
}
|
||||
|
||||
void ListView::setPosition(int x, int y) {
|
||||
rect.x = x;
|
||||
rect.y = y;
|
||||
}
|
||||
|
||||
void ListView::setSize(int w, int h) {
|
||||
rect.w = w;
|
||||
rect.h = h;
|
||||
}
|
||||
|
||||
void ListView::paint() {
|
||||
gmenu2x->s->setClipRect(rect);
|
||||
|
||||
//Selection
|
||||
int iY = selectedItem-firstDisplayItem;
|
||||
iY = rect.y+(iY*16);
|
||||
if (selectedItem<(int)items.size())
|
||||
gmenu2x->s->box(1, iY, 309, 14, gmenu2x->skinConfColors["selectionBg"]);
|
||||
|
||||
//Items
|
||||
iY = rect.y;
|
||||
for (int i=firstDisplayItem; i<(int)items.size() && i<firstDisplayItem+itemsPerPage; i++) {
|
||||
items[i]->setPosition(4,iY);
|
||||
items[i]->paint();
|
||||
iY += items[i]->getHeight();
|
||||
}
|
||||
|
||||
gmenu2x->drawScrollBar(itemsPerPage, items.size(), firstDisplayItem, 42,175);
|
||||
|
||||
gmenu2x->s->clearClipRect();
|
||||
}
|
||||
|
||||
void ListView::handleInput() {
|
||||
for (int i=firstDisplayItem; i<(int)items.size() && i<firstDisplayItem+itemsPerPage; i++)
|
||||
items[i]->handleTS();
|
||||
}
|
||||
|
||||
int ListView::getWidth() {
|
||||
return rect.w;
|
||||
}
|
||||
59
src/listview.h
Normal file
59
src/listview.h
Normal file
@@ -0,0 +1,59 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2006 by Massimiliano Torromeo *
|
||||
* massimiliano.torromeo@gmail.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
#ifndef LISTVIEW_H_
|
||||
#define LISTVIEW_H_
|
||||
|
||||
#include "gmenu2x.h"
|
||||
#include "listviewitem.h"
|
||||
|
||||
using std::vector;
|
||||
|
||||
class ListView {
|
||||
private:
|
||||
int firstDisplayItem, selectedItem;
|
||||
int itemsPerPage;
|
||||
|
||||
protected:
|
||||
vector<ListViewItem*> items;
|
||||
SDL_Rect rect;
|
||||
|
||||
public:
|
||||
ListView(GMenu2X *gmenu2x);
|
||||
virtual ~ListView();
|
||||
|
||||
GMenu2X *gmenu2x;
|
||||
|
||||
ListViewItem *add(ListViewItem *item);
|
||||
ListViewItem *add(string text);
|
||||
void del(ListViewItem *item);
|
||||
void del(int itemIndex);
|
||||
void clear();
|
||||
|
||||
void setPosition(int x, int y);
|
||||
void setSize(int w, int h);
|
||||
int getWidth();
|
||||
|
||||
virtual void paint();
|
||||
virtual void handleInput();
|
||||
|
||||
ListViewItem *operator[](int);
|
||||
};
|
||||
|
||||
#endif
|
||||
30
src/listviewitem.cpp
Normal file
30
src/listviewitem.cpp
Normal file
@@ -0,0 +1,30 @@
|
||||
#include "listview.h"
|
||||
#include "listviewitem.h"
|
||||
|
||||
ListViewItem::ListViewItem(ListView * parent, string text) {
|
||||
this->parent = parent;
|
||||
rect.h = 16;
|
||||
rect.w = parent->getWidth();
|
||||
}
|
||||
|
||||
ListViewItem::~ ListViewItem() {}
|
||||
|
||||
void ListViewItem::setPosition(int x, int y) {
|
||||
rect.x = x;
|
||||
rect.y = y;
|
||||
}
|
||||
|
||||
void ListViewItem::paint() {
|
||||
parent->gmenu2x->s->write(parent->gmenu2x->font, text, rect.x, rect.y, SFontHAlignLeft, SFontVAlignMiddle);
|
||||
}
|
||||
|
||||
int ListViewItem::getHeight() {
|
||||
return rect.h;
|
||||
}
|
||||
|
||||
void ListViewItem::handleTS() {
|
||||
if (parent->gmenu2x->ts.inRect(rect))
|
||||
onClick();
|
||||
}
|
||||
|
||||
void ListViewItem::onClick() {}
|
||||
48
src/listviewitem.h
Normal file
48
src/listviewitem.h
Normal file
@@ -0,0 +1,48 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2006 by Massimiliano Torromeo *
|
||||
* massimiliano.torromeo@gmail.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
#ifndef LISTVIEWITEM_H_
|
||||
#define LISTVIEWITEM_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
using std::string;
|
||||
|
||||
class ListView;
|
||||
|
||||
class ListViewItem {
|
||||
protected:
|
||||
ListView *parent;
|
||||
SDL_Rect rect;
|
||||
|
||||
public:
|
||||
ListViewItem(ListView *parent, string text);
|
||||
virtual ~ListViewItem();
|
||||
|
||||
string text;
|
||||
|
||||
void setPosition(int x, int y);
|
||||
int getHeight();
|
||||
|
||||
virtual void paint();
|
||||
virtual void handleTS();
|
||||
virtual void onClick();
|
||||
};
|
||||
|
||||
#endif
|
||||
BIN
src/lr.xcf
Normal file
BIN
src/lr.xcf
Normal file
Binary file not shown.
457
src/menu.cpp
Normal file
457
src/menu.cpp
Normal file
@@ -0,0 +1,457 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2006 by Massimiliano Torromeo *
|
||||
* massimiliano.torromeo@gmail.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#include <sstream>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
#include <algorithm>
|
||||
#include <math.h>
|
||||
|
||||
#include "gmenu2x.h"
|
||||
#include "linkapp.h"
|
||||
#include "menu.h"
|
||||
#include "filelister.h"
|
||||
#include "utilities.h"
|
||||
#include "pxml.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
Menu::Menu(GMenu2X *gmenu2x) {
|
||||
this->gmenu2x = gmenu2x;
|
||||
iFirstDispSection = 0;
|
||||
|
||||
DIR *dirp;
|
||||
struct stat st;
|
||||
struct dirent *dptr;
|
||||
string filepath;
|
||||
|
||||
if ((dirp = opendir("sections")) == NULL) return;
|
||||
|
||||
while ((dptr = readdir(dirp))) {
|
||||
if (dptr->d_name[0]=='.') continue;
|
||||
filepath = (string)"sections/"+dptr->d_name;
|
||||
int statRet = stat(filepath.c_str(), &st);
|
||||
if (!S_ISDIR(st.st_mode)) continue;
|
||||
if (statRet != -1) {
|
||||
sections.push_back((string)dptr->d_name);
|
||||
linklist ll;
|
||||
links.push_back(ll);
|
||||
}
|
||||
}
|
||||
|
||||
closedir(dirp);
|
||||
sort(sections.begin(),sections.end(),case_less());
|
||||
setSectionIndex(0);
|
||||
readLinks();
|
||||
}
|
||||
|
||||
Menu::~Menu() {
|
||||
freeLinks();
|
||||
}
|
||||
|
||||
uint Menu::firstDispRow() {
|
||||
return iFirstDispRow;
|
||||
}
|
||||
|
||||
void Menu::loadIcons() {
|
||||
//reload section icons
|
||||
for (uint i=0; i<sections.size(); i++) {
|
||||
string sectionIcon = "sections/"+sections[i]+".png";
|
||||
if (!gmenu2x->sc.getSkinFilePath(sectionIcon).empty())
|
||||
gmenu2x->sc.add("skin:"+sectionIcon);
|
||||
|
||||
//check link's icons
|
||||
string linkIcon;
|
||||
for (uint x=0; x<sectionLinks(i)->size(); x++) {
|
||||
linkIcon = sectionLinks(i)->at(x)->getIcon();
|
||||
LinkApp *linkapp = dynamic_cast<LinkApp*>(sectionLinks(i)->at(x));
|
||||
|
||||
if (linkIcon.substr(0,5)=="skin:") {
|
||||
linkIcon = gmenu2x->sc.getSkinFilePath(linkIcon.substr(5,linkIcon.length()));
|
||||
if (linkapp != NULL && !fileExists(linkIcon))
|
||||
linkapp->searchIcon();
|
||||
else
|
||||
sectionLinks(i)->at(x)->setIconPath(linkIcon);
|
||||
|
||||
} else if (!fileExists(linkIcon)) {
|
||||
if (linkapp != NULL) linkapp->searchIcon();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*====================================
|
||||
SECTION MANAGEMENT
|
||||
====================================*/
|
||||
void Menu::freeLinks() {
|
||||
for (vector<linklist>::iterator section = links.begin(); section<links.end(); section++)
|
||||
for (linklist::iterator link = section->begin(); link<section->end(); link++)
|
||||
free(*link);
|
||||
}
|
||||
|
||||
linklist *Menu::sectionLinks(int i) {
|
||||
if (i<0 || i>(int)links.size())
|
||||
i = selSectionIndex();
|
||||
|
||||
if (i<0 || i>(int)links.size())
|
||||
return NULL;
|
||||
|
||||
return &links[i];
|
||||
}
|
||||
|
||||
void Menu::decSectionIndex() {
|
||||
setSectionIndex(iSection-1);
|
||||
}
|
||||
|
||||
void Menu::incSectionIndex() {
|
||||
setSectionIndex(iSection+1);
|
||||
}
|
||||
|
||||
uint Menu::firstDispSection() {
|
||||
return iFirstDispSection;
|
||||
}
|
||||
|
||||
int Menu::selSectionIndex() {
|
||||
return iSection;
|
||||
}
|
||||
|
||||
string Menu::selSection() {
|
||||
return sections[iSection];
|
||||
}
|
||||
|
||||
void Menu::setSectionIndex(int i) {
|
||||
if (i<0)
|
||||
i=sections.size()-1;
|
||||
else if (i>=(int)sections.size())
|
||||
i=0;
|
||||
iSection = i;
|
||||
|
||||
if (i>(int)iFirstDispSection+4)
|
||||
iFirstDispSection = i-4;
|
||||
else if (i<(int)iFirstDispSection)
|
||||
iFirstDispSection = i;
|
||||
|
||||
iLink = 0;
|
||||
iFirstDispRow = 0;
|
||||
}
|
||||
|
||||
string Menu::sectionPath(int section) {
|
||||
if (section<0 || section>(int)sections.size()) section = iSection;
|
||||
return "sections/"+sections[section]+"/";
|
||||
}
|
||||
|
||||
/*====================================
|
||||
LINKS MANAGEMENT
|
||||
====================================*/
|
||||
bool Menu::addActionLink(uint section, string title, LinkRunAction action, string description, string icon) {
|
||||
if (section>=sections.size()) return false;
|
||||
|
||||
LinkAction *linkact = new LinkAction(gmenu2x,action);
|
||||
linkact->setSize(gmenu2x->skinConfInt["linkWidth"],gmenu2x->skinConfInt["linkHeight"]);
|
||||
linkact->setTitle(title);
|
||||
linkact->setDescription(description);
|
||||
if (gmenu2x->sc.exists(icon) || (icon.substr(0,5)=="skin:" && !gmenu2x->sc.getSkinFilePath(icon.substr(5,icon.length())).empty()) || fileExists(icon))
|
||||
linkact->setIcon(icon);
|
||||
|
||||
sectionLinks(section)->push_back(linkact);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Menu::addLink(string path, string file, string section) {
|
||||
if (section=="")
|
||||
section = selSection();
|
||||
else if (find(sections.begin(),sections.end(),section)==sections.end()) {
|
||||
//section directory doesn't exists
|
||||
if (!addSection(section))
|
||||
return false;
|
||||
}
|
||||
if (path[path.length()-1]!='/') path += "/";
|
||||
|
||||
//if the extension is not equal to gpu or dge then enable the wrapepr by default
|
||||
bool wrapper = false, pxml = false;
|
||||
|
||||
//strip the extension from the filename
|
||||
string title = file;
|
||||
string::size_type pos = title.rfind(".");
|
||||
if (pos!=string::npos && pos>0) {
|
||||
string ext = title.substr(pos, title.length());
|
||||
transform(ext.begin(), ext.end(), ext.begin(), (int(*)(int)) tolower);
|
||||
if (ext == ".gpu" || ext == ".dge") wrapper = false;
|
||||
else if (ext == ".pxml") pxml = true;
|
||||
title = title.substr(0, pos);
|
||||
}
|
||||
|
||||
string linkpath = "sections/"+section+"/"+title;
|
||||
int x=2;
|
||||
while (fileExists(linkpath)) {
|
||||
stringstream ss;
|
||||
linkpath = "";
|
||||
ss << x;
|
||||
ss >> linkpath;
|
||||
linkpath = "sections/"+section+"/"+title+linkpath;
|
||||
x++;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
cout << "\033[0;34mGMENU2X:\033[0m Adding link: " << linkpath << endl;
|
||||
#endif
|
||||
|
||||
//search for a manual
|
||||
pos = file.rfind(".");
|
||||
string exename = path+file.substr(0,pos);
|
||||
string manual = "";
|
||||
if (fileExists(exename+".man.png")) {
|
||||
manual = exename+".man.png";
|
||||
} else if (fileExists(exename+".man.jpg")) {
|
||||
manual = exename+".man.jpg";
|
||||
} else if (fileExists(exename+".man.jpeg")) {
|
||||
manual = exename+".man.jpeg";
|
||||
} else if (fileExists(exename+".man.bmp")) {
|
||||
manual = exename+".man.bmp";
|
||||
} else if (fileExists(exename+".man.txt")) {
|
||||
manual = exename+".man.txt";
|
||||
} else {
|
||||
//scan directory for a file like *readme*
|
||||
FileLister fl(path, false);
|
||||
fl.setFilter(".txt");
|
||||
fl.browse();
|
||||
bool found = false;
|
||||
for (uint x=0; x<fl.size() && !found; x++) {
|
||||
string lcfilename = fl[x];
|
||||
|
||||
if (lcfilename.find("readme") != string::npos) {
|
||||
found = true;
|
||||
manual = path+fl.files[x];
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef DEBUG
|
||||
cout << "\033[0;34mGMENU2X:\033[0m Manual: " << manual << endl;
|
||||
#endif
|
||||
|
||||
// Read pxml
|
||||
string shorttitle="", description="", exec="", icon="";
|
||||
if (pxml) {
|
||||
PXml pxmlDoc(path+file);
|
||||
if (pxmlDoc.isValid()) {
|
||||
shorttitle = pxmlDoc.getTitle();
|
||||
description = pxmlDoc.getDescription();
|
||||
exec = pxmlDoc.getExec();
|
||||
if (!exec.empty() && exec[0]!='/')
|
||||
exec = path+exec;
|
||||
icon = pxmlDoc.getIcon();
|
||||
if (!icon.empty() && icon[0]!='/')
|
||||
icon = path+icon;
|
||||
} else {
|
||||
#ifdef DEBUG
|
||||
cout << "\033[0;34mGMENU2X:\033[0m Error loading pxml " << file << ": " << pxmlDoc.getError() << endl;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
shorttitle = title;
|
||||
exec = path+file;
|
||||
}
|
||||
|
||||
//Reduce title lenght to fit the link width
|
||||
if (gmenu2x->font->getTextWidth(shorttitle)>gmenu2x->skinConfInt["linkWidth"]) {
|
||||
while (gmenu2x->font->getTextWidth(shorttitle+"..")>gmenu2x->skinConfInt["linkWidth"])
|
||||
shorttitle = shorttitle.substr(0,shorttitle.length()-1);
|
||||
shorttitle += "..";
|
||||
}
|
||||
|
||||
ofstream f(linkpath.c_str());
|
||||
if (f.is_open()) {
|
||||
f << "title=" << shorttitle << endl;
|
||||
f << "exec=" << exec << endl;
|
||||
if (!description.empty()) f << "description=" << description << endl;
|
||||
if (!icon.empty()) f << "icon=" << icon << endl;
|
||||
if (!manual.empty()) f << "manual=" << manual << endl;
|
||||
if (wrapper) f << "wrapper=true" << endl;
|
||||
f.close();
|
||||
sync();
|
||||
int isection = find(sections.begin(),sections.end(),section) - sections.begin();
|
||||
if (isection>=0 && isection<(int)sections.size()) {
|
||||
#ifdef DEBUG
|
||||
cout << "\033[0;34mGMENU2X:\033[0m Section: " << sections[isection] << "(" << isection << ")" << endl;
|
||||
#endif
|
||||
LinkApp* link = new LinkApp(gmenu2x, linkpath.c_str());
|
||||
link->setSize(gmenu2x->skinConfInt["linkWidth"],gmenu2x->skinConfInt["linkHeight"]);
|
||||
links[isection].push_back( link );
|
||||
}
|
||||
} else {
|
||||
#ifdef DEBUG
|
||||
cout << "\033[0;34mGMENU2X:\033[0;31m Error while opening the file '" << linkpath << "' for write\033[0m" << endl;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Menu::addSection(string sectionName) {
|
||||
string sectiondir = "sections/"+sectionName;
|
||||
if (mkdir(sectiondir.c_str(),0777)==0) {
|
||||
sections.push_back(sectionName);
|
||||
linklist ll;
|
||||
links.push_back(ll);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Menu::deleteSelectedLink() {
|
||||
#ifdef DEBUG
|
||||
cout << "\033[0;34mGMENU2X:\033[0m Deleting link " << selLink()->getTitle() << endl;
|
||||
#endif
|
||||
if (selLinkApp()!=NULL)
|
||||
unlink(selLinkApp()->file.c_str());
|
||||
gmenu2x->sc.del(selLink()->getIconPath());
|
||||
sectionLinks()->erase( sectionLinks()->begin() + selLinkIndex() );
|
||||
setLinkIndex(selLinkIndex());
|
||||
}
|
||||
|
||||
void Menu::deleteSelectedSection() {
|
||||
#ifdef DEBUG
|
||||
cout << "\033[0;34mGMENU2X:\033[0m Deleting section " << selSection() << endl;
|
||||
#endif
|
||||
gmenu2x->sc.del("sections/"+selSection()+".png");
|
||||
links.erase( links.begin()+selSectionIndex() );
|
||||
sections.erase( sections.begin()+selSectionIndex() );
|
||||
setSectionIndex(0); //reload sections
|
||||
}
|
||||
|
||||
bool Menu::linkChangeSection(uint linkIndex, uint oldSectionIndex, uint newSectionIndex) {
|
||||
if (oldSectionIndex<sections.size() && newSectionIndex<sections.size() && linkIndex<sectionLinks(oldSectionIndex)->size()) {
|
||||
sectionLinks(newSectionIndex)->push_back( sectionLinks(oldSectionIndex)->at(linkIndex) );
|
||||
sectionLinks(oldSectionIndex)->erase( sectionLinks(oldSectionIndex)->begin()+linkIndex );
|
||||
//Select the same link in the new position
|
||||
setSectionIndex(newSectionIndex);
|
||||
setLinkIndex(sectionLinks(newSectionIndex)->size()-1);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Menu::linkLeft() {
|
||||
if (iLink%gmenu2x->linkColumns == 0)
|
||||
setLinkIndex( sectionLinks()->size()>iLink+gmenu2x->linkColumns-1 ? iLink+gmenu2x->linkColumns-1 : sectionLinks()->size()-1 );
|
||||
else
|
||||
setLinkIndex(iLink-1);
|
||||
}
|
||||
|
||||
void Menu::linkRight() {
|
||||
if (iLink%gmenu2x->linkColumns == (gmenu2x->linkColumns-1) || iLink == (int)sectionLinks()->size()-1)
|
||||
setLinkIndex(iLink-iLink%gmenu2x->linkColumns);
|
||||
else
|
||||
setLinkIndex(iLink+1);
|
||||
}
|
||||
|
||||
void Menu::linkUp() {
|
||||
int l = iLink-gmenu2x->linkColumns;
|
||||
if (l<0) {
|
||||
uint rows = (uint)ceil(sectionLinks()->size()/(double)gmenu2x->linkColumns);
|
||||
l = (rows*gmenu2x->linkColumns)+l;
|
||||
if (l >= (int)sectionLinks()->size())
|
||||
l -= gmenu2x->linkColumns;
|
||||
}
|
||||
setLinkIndex(l);
|
||||
}
|
||||
|
||||
void Menu::linkDown() {
|
||||
uint l = iLink+gmenu2x->linkColumns;
|
||||
if (l >= sectionLinks()->size()) {
|
||||
uint rows = (uint)ceil(sectionLinks()->size()/(double)gmenu2x->linkColumns);
|
||||
uint curCol = (uint)ceil((iLink+1)/(double)gmenu2x->linkColumns);
|
||||
if (rows > curCol)
|
||||
l = sectionLinks()->size()-1;
|
||||
else
|
||||
l %= gmenu2x->linkColumns;
|
||||
}
|
||||
setLinkIndex(l);
|
||||
}
|
||||
|
||||
int Menu::selLinkIndex() {
|
||||
return iLink;
|
||||
}
|
||||
|
||||
Link *Menu::selLink() {
|
||||
if (sectionLinks()->size()==0) return NULL;
|
||||
return sectionLinks()->at(iLink);
|
||||
}
|
||||
|
||||
LinkApp *Menu::selLinkApp() {
|
||||
return dynamic_cast<LinkApp*>(selLink());
|
||||
}
|
||||
|
||||
void Menu::setLinkIndex(int i) {
|
||||
if (i<0)
|
||||
i=sectionLinks()->size()-1;
|
||||
else if (i>=(int)sectionLinks()->size())
|
||||
i=0;
|
||||
|
||||
if (i>=(int)(iFirstDispRow*gmenu2x->linkColumns+gmenu2x->linkColumns*gmenu2x->linkRows))
|
||||
iFirstDispRow = i/gmenu2x->linkColumns-gmenu2x->linkRows+1;
|
||||
else if (i<(int)(iFirstDispRow*gmenu2x->linkColumns))
|
||||
iFirstDispRow = i/gmenu2x->linkColumns;
|
||||
|
||||
iLink = i;
|
||||
}
|
||||
|
||||
void Menu::readLinks() {
|
||||
vector<string> linkfiles;
|
||||
|
||||
iLink = 0;
|
||||
iFirstDispRow = 0;
|
||||
|
||||
DIR *dirp;
|
||||
struct stat st;
|
||||
struct dirent *dptr;
|
||||
string filepath;
|
||||
|
||||
for (uint i=0; i<links.size(); i++) {
|
||||
links[i].clear();
|
||||
linkfiles.clear();
|
||||
|
||||
if ((dirp = opendir(sectionPath(i).c_str())) == NULL) continue;
|
||||
|
||||
while ((dptr = readdir(dirp))) {
|
||||
if (dptr->d_name[0]=='.') continue;
|
||||
filepath = sectionPath(i)+dptr->d_name;
|
||||
int statRet = stat(filepath.c_str(), &st);
|
||||
if (S_ISDIR(st.st_mode)) continue;
|
||||
if (statRet != -1) {
|
||||
linkfiles.push_back(filepath);
|
||||
}
|
||||
}
|
||||
|
||||
sort(linkfiles.begin(), linkfiles.end(),case_less());
|
||||
for (uint x=0; x<linkfiles.size(); x++) {
|
||||
LinkApp *link = new LinkApp(gmenu2x, linkfiles[x].c_str());
|
||||
link->setSize(gmenu2x->skinConfInt["linkWidth"],gmenu2x->skinConfInt["linkHeight"]);
|
||||
if (link->targetExists())
|
||||
links[i].push_back( link );
|
||||
else
|
||||
free(link);
|
||||
}
|
||||
|
||||
closedir(dirp);
|
||||
}
|
||||
}
|
||||
85
src/menu.h
Normal file
85
src/menu.h
Normal file
@@ -0,0 +1,85 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2006 by Massimiliano Torromeo *
|
||||
* massimiliano.torromeo@gmail.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
#ifndef MENU_H
|
||||
#define MENU_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "linkaction.h"
|
||||
|
||||
using std::string;
|
||||
using std::vector;
|
||||
|
||||
class LinkApp;
|
||||
class GMenu2X;
|
||||
|
||||
typedef vector<Link*> linklist;
|
||||
|
||||
/**
|
||||
Handles the menu structure
|
||||
|
||||
@author Massimiliano Torromeo <massimiliano.torromeo@gmail.com>
|
||||
*/
|
||||
class Menu {
|
||||
private:
|
||||
GMenu2X *gmenu2x;
|
||||
int iSection, iLink;
|
||||
uint iFirstDispSection, iFirstDispRow;
|
||||
void readLinks();
|
||||
void freeLinks();
|
||||
|
||||
public:
|
||||
Menu(GMenu2X *gmenu2x);
|
||||
~Menu();
|
||||
|
||||
vector<string> sections;
|
||||
vector<linklist> links;
|
||||
linklist *sectionLinks(int i = -1);
|
||||
|
||||
int selSectionIndex();
|
||||
string selSection();
|
||||
void decSectionIndex();
|
||||
void incSectionIndex();
|
||||
void setSectionIndex(int i);
|
||||
uint firstDispSection();
|
||||
uint firstDispRow();
|
||||
|
||||
bool addActionLink(uint section, string title, LinkRunAction action, string description="", string icon="");
|
||||
bool addLink(string path, string file, string section="");
|
||||
bool addSection(string sectionName);
|
||||
void deleteSelectedLink();
|
||||
void deleteSelectedSection();
|
||||
|
||||
void loadIcons();
|
||||
bool linkChangeSection(uint linkIndex, uint oldSectionIndex, uint newSectionIndex);
|
||||
|
||||
int selLinkIndex();
|
||||
Link *selLink();
|
||||
LinkApp *selLinkApp();
|
||||
void linkLeft();
|
||||
void linkRight();
|
||||
void linkUp();
|
||||
void linkDown();
|
||||
void setLinkIndex(int i);
|
||||
|
||||
string sectionPath(int section = -1);
|
||||
};
|
||||
|
||||
#endif
|
||||
36
src/menusetting.cpp
Normal file
36
src/menusetting.cpp
Normal file
@@ -0,0 +1,36 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2006 by Massimiliano Torromeo *
|
||||
* massimiliano.torromeo@gmail.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
#include "menusetting.h"
|
||||
|
||||
MenuSetting::MenuSetting(GMenu2X *gmenu2x, string name, string description) {
|
||||
this->gmenu2x = gmenu2x;
|
||||
this->name = name;
|
||||
this->description = description;
|
||||
}
|
||||
|
||||
void MenuSetting::draw(int y) {
|
||||
gmenu2x->s->write( gmenu2x->font, name, 5, y+gmenu2x->font->getHalfHeight(), SFontHAlignLeft, SFontVAlignMiddle );
|
||||
}
|
||||
|
||||
void MenuSetting::handleTS() {}
|
||||
void MenuSetting::manageInput() {}
|
||||
void MenuSetting::adjustInput() {}
|
||||
void MenuSetting::drawSelected(int) {}
|
||||
bool MenuSetting::edited() { return true; }
|
||||
54
src/menusetting.h
Normal file
54
src/menusetting.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2006 by Massimiliano Torromeo *
|
||||
* massimiliano.torromeo@gmail.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
#ifndef MENUSETTING_H
|
||||
#define MENUSETTING_H
|
||||
|
||||
#ifdef TARGET_GP2X
|
||||
#include "inputmanager.h"
|
||||
#endif
|
||||
|
||||
#include "gmenu2x.h"
|
||||
|
||||
using std::string;
|
||||
|
||||
/**
|
||||
Base class for different kind of option
|
||||
|
||||
@author Massimiliano Torromeo <massimiliano.torromeo@gmail.com>
|
||||
*/
|
||||
class MenuSetting {
|
||||
private:
|
||||
GMenu2X *gmenu2x;
|
||||
|
||||
public:
|
||||
MenuSetting(GMenu2X *gmenu2x, string name, string description);
|
||||
virtual ~MenuSetting() {};
|
||||
|
||||
virtual void draw(int y);
|
||||
virtual void handleTS();
|
||||
virtual void manageInput();
|
||||
virtual void adjustInput();
|
||||
virtual void drawSelected(int y);
|
||||
virtual bool edited();
|
||||
|
||||
string name, description;
|
||||
};
|
||||
|
||||
#endif
|
||||
95
src/menusettingbool.cpp
Normal file
95
src/menusettingbool.cpp
Normal file
@@ -0,0 +1,95 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2006 by Massimiliano Torromeo *
|
||||
* massimiliano.torromeo@gmail.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
#include "menusettingbool.h"
|
||||
#include "utilities.h"
|
||||
#include <sstream>
|
||||
|
||||
using namespace std;
|
||||
using namespace fastdelegate;
|
||||
|
||||
MenuSettingBool::MenuSettingBool(GMenu2X *gmenu2x, string name, string description, int *value)
|
||||
: MenuSetting(gmenu2x,name,description) {
|
||||
this->gmenu2x = gmenu2x;
|
||||
_ivalue = value;
|
||||
_value = NULL;
|
||||
originalValue = *value != 0;
|
||||
setValue(this->value());
|
||||
|
||||
btnToggle = new IconButton(gmenu2x, "skin:imgs/buttons/b.png", gmenu2x->tr["Switch"]);
|
||||
btnToggle->setAction(MakeDelegate(this, &MenuSettingBool::toggle));
|
||||
}
|
||||
|
||||
MenuSettingBool::MenuSettingBool(GMenu2X *gmenu2x, string name, string description, bool *value)
|
||||
: MenuSetting(gmenu2x,name,description) {
|
||||
this->gmenu2x = gmenu2x;
|
||||
_value = value;
|
||||
_ivalue = NULL;
|
||||
originalValue = *value;
|
||||
setValue(this->value());
|
||||
|
||||
btnToggle = new IconButton(gmenu2x, "skin:imgs/buttons/b.png", gmenu2x->tr["Switch"]);
|
||||
btnToggle->setAction(MakeDelegate(this, &MenuSettingBool::toggle));
|
||||
}
|
||||
|
||||
void MenuSettingBool::draw(int y) {
|
||||
MenuSetting::draw(y);
|
||||
gmenu2x->s->write( gmenu2x->font, strvalue, 155, y+gmenu2x->font->getHalfHeight(), SFontHAlignLeft, SFontVAlignMiddle );
|
||||
}
|
||||
|
||||
void MenuSettingBool::handleTS() {
|
||||
btnToggle->handleTS();
|
||||
}
|
||||
|
||||
void MenuSettingBool::manageInput() {
|
||||
if ( gmenu2x->input[ACTION_B] ) toggle();
|
||||
}
|
||||
|
||||
void MenuSettingBool::toggle() {
|
||||
setValue(!value());
|
||||
}
|
||||
|
||||
void MenuSettingBool::setValue(int value) {
|
||||
setValue(value != 0);
|
||||
}
|
||||
|
||||
void MenuSettingBool::setValue(bool value) {
|
||||
if (_value == NULL)
|
||||
*_ivalue = value;
|
||||
else
|
||||
*_value = value;
|
||||
strvalue = value ? "ON" : "OFF";
|
||||
}
|
||||
|
||||
bool MenuSettingBool::value() {
|
||||
if (_value == NULL)
|
||||
return *_ivalue != 0;
|
||||
else
|
||||
return *_value;
|
||||
}
|
||||
|
||||
void MenuSettingBool::adjustInput() {}
|
||||
|
||||
void MenuSettingBool::drawSelected(int) {
|
||||
gmenu2x->drawButton(btnToggle);
|
||||
}
|
||||
|
||||
bool MenuSettingBool::edited() {
|
||||
return originalValue != value();
|
||||
}
|
||||
57
src/menusettingbool.h
Normal file
57
src/menusettingbool.h
Normal file
@@ -0,0 +1,57 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2006 by Massimiliano Torromeo *
|
||||
* massimiliano.torromeo@gmail.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
#ifndef MENUSETTINGBOOL_H
|
||||
#define MENUSETTINGBOOL_H
|
||||
|
||||
#include "iconbutton.h"
|
||||
#include "menusetting.h"
|
||||
|
||||
using std::string;
|
||||
class GMenu2X;
|
||||
|
||||
class MenuSettingBool : public MenuSetting {
|
||||
private:
|
||||
bool originalValue;
|
||||
bool *_value;
|
||||
int *_ivalue;
|
||||
string strvalue;
|
||||
GMenu2X *gmenu2x;
|
||||
IconButton *btnToggle;
|
||||
|
||||
void toggle();
|
||||
|
||||
public:
|
||||
MenuSettingBool(GMenu2X *gmenu2x, string name, string description, bool *value);
|
||||
MenuSettingBool(GMenu2X *gmenu2x, string name, string description, int *value);
|
||||
virtual ~MenuSettingBool() {};
|
||||
|
||||
virtual void draw(int y);
|
||||
virtual void handleTS();
|
||||
virtual void manageInput();
|
||||
virtual void adjustInput();
|
||||
virtual void drawSelected(int y);
|
||||
virtual bool edited();
|
||||
|
||||
void setValue(int value);
|
||||
void setValue(bool value);
|
||||
bool value();
|
||||
};
|
||||
|
||||
#endif
|
||||
81
src/menusettingdir.cpp
Normal file
81
src/menusettingdir.cpp
Normal file
@@ -0,0 +1,81 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2006 by Massimiliano Torromeo *
|
||||
* massimiliano.torromeo@gmail.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
#include "menusettingdir.h"
|
||||
#include "dirdialog.h"
|
||||
#include "utilities.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace fastdelegate;
|
||||
|
||||
MenuSettingDir::MenuSettingDir(GMenu2X *gmenu2x, string name, string description, string *value)
|
||||
: MenuSetting(gmenu2x,name,description) {
|
||||
this->gmenu2x = gmenu2x;
|
||||
_value = value;
|
||||
originalValue = *value;
|
||||
|
||||
btnClear = new IconButton(gmenu2x, "skin:imgs/buttons/x.png", gmenu2x->tr["Clear"]);
|
||||
btnClear->setAction(MakeDelegate(this, &MenuSettingDir::clear));
|
||||
|
||||
btnSelect = new IconButton(gmenu2x, "skin:imgs/buttons/b.png", gmenu2x->tr["Select a directory"]);
|
||||
btnSelect->setAction(MakeDelegate(this, &MenuSettingDir::select));
|
||||
}
|
||||
|
||||
void MenuSettingDir::draw(int y) {
|
||||
MenuSetting::draw(y);
|
||||
gmenu2x->s->write( gmenu2x->font, value(), 155, y+gmenu2x->font->getHalfHeight(), SFontHAlignLeft, SFontVAlignMiddle );
|
||||
}
|
||||
|
||||
void MenuSettingDir::handleTS() {
|
||||
btnSelect->handleTS();
|
||||
btnClear->handleTS();
|
||||
}
|
||||
|
||||
void MenuSettingDir::manageInput() {
|
||||
if ( gmenu2x->input[ACTION_X] ) setValue("");
|
||||
if ( gmenu2x->input[ACTION_B] ) select();
|
||||
}
|
||||
|
||||
void MenuSettingDir::clear() {
|
||||
setValue("");
|
||||
}
|
||||
|
||||
void MenuSettingDir::select() {
|
||||
DirDialog dd(gmenu2x, description, value());
|
||||
if (dd.exec()) setValue( dd.path );
|
||||
}
|
||||
|
||||
void MenuSettingDir::setValue(string value) {
|
||||
*_value = value;
|
||||
}
|
||||
|
||||
string MenuSettingDir::value() {
|
||||
return *_value;
|
||||
}
|
||||
|
||||
void MenuSettingDir::adjustInput() {}
|
||||
|
||||
void MenuSettingDir::drawSelected(int) {
|
||||
gmenu2x->drawButton(btnClear,
|
||||
gmenu2x->drawButton(btnSelect));
|
||||
}
|
||||
|
||||
bool MenuSettingDir::edited() {
|
||||
return originalValue != value();
|
||||
}
|
||||
53
src/menusettingdir.h
Normal file
53
src/menusettingdir.h
Normal file
@@ -0,0 +1,53 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2006 by Massimiliano Torromeo *
|
||||
* massimiliano.torromeo@gmail.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
#ifndef MENUSETTINGDIR_H
|
||||
#define MENUSETTINGDIR_H
|
||||
|
||||
#include "gmenu2x.h"
|
||||
#include "menusetting.h"
|
||||
|
||||
using std::string;
|
||||
|
||||
class MenuSettingDir : public MenuSetting {
|
||||
private:
|
||||
string originalValue;
|
||||
string *_value;
|
||||
GMenu2X *gmenu2x;
|
||||
IconButton *btnClear, *btnSelect;
|
||||
|
||||
void select();
|
||||
void clear();
|
||||
|
||||
public:
|
||||
MenuSettingDir(GMenu2X *gmenu2x, string name, string description, string *value);
|
||||
virtual ~MenuSettingDir() {};
|
||||
|
||||
virtual void draw(int y);
|
||||
virtual void handleTS();
|
||||
virtual void manageInput();
|
||||
virtual void adjustInput();
|
||||
virtual void drawSelected(int y);
|
||||
virtual bool edited();
|
||||
|
||||
void setValue(string value);
|
||||
string value();
|
||||
};
|
||||
|
||||
#endif
|
||||
82
src/menusettingfile.cpp
Normal file
82
src/menusettingfile.cpp
Normal file
@@ -0,0 +1,82 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2006 by Massimiliano Torromeo *
|
||||
* massimiliano.torromeo@gmail.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
#include "menusettingfile.h"
|
||||
#include "filedialog.h"
|
||||
#include "utilities.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace fastdelegate;
|
||||
|
||||
MenuSettingFile::MenuSettingFile(GMenu2X *gmenu2x, string name, string description, string *value, string filter)
|
||||
: MenuSetting(gmenu2x,name,description) {
|
||||
this->gmenu2x = gmenu2x;
|
||||
this->filter = filter;
|
||||
_value = value;
|
||||
originalValue = *value;
|
||||
|
||||
btnClear = new IconButton(gmenu2x, "skin:imgs/buttons/x.png", gmenu2x->tr["Clear"]);
|
||||
btnClear->setAction(MakeDelegate(this, &MenuSettingFile::clear));
|
||||
|
||||
btnSelect = new IconButton(gmenu2x, "skin:imgs/buttons/b.png", gmenu2x->tr["Select a file"]);
|
||||
btnSelect->setAction(MakeDelegate(this, &MenuSettingFile::select));
|
||||
}
|
||||
|
||||
void MenuSettingFile::draw(int y) {
|
||||
MenuSetting::draw(y);
|
||||
gmenu2x->s->write( gmenu2x->font, value(), 155, y+gmenu2x->font->getHalfHeight(), SFontHAlignLeft, SFontVAlignMiddle );
|
||||
}
|
||||
|
||||
void MenuSettingFile::handleTS() {
|
||||
btnSelect->handleTS();
|
||||
btnClear->handleTS();
|
||||
}
|
||||
|
||||
void MenuSettingFile::manageInput() {
|
||||
if ( gmenu2x->input[ACTION_X] ) setValue("");
|
||||
if ( gmenu2x->input[ACTION_B] ) select();
|
||||
}
|
||||
|
||||
void MenuSettingFile::clear() {
|
||||
setValue("");
|
||||
}
|
||||
|
||||
void MenuSettingFile::select() {
|
||||
FileDialog fd(gmenu2x, description, filter, value());
|
||||
if (fd.exec()) setValue( fd.path()+"/"+fd.file );
|
||||
}
|
||||
|
||||
void MenuSettingFile::setValue(string value) {
|
||||
*_value = value;
|
||||
}
|
||||
|
||||
string MenuSettingFile::value() {
|
||||
return *_value;
|
||||
}
|
||||
|
||||
void MenuSettingFile::adjustInput() {}
|
||||
|
||||
void MenuSettingFile::drawSelected(int) {
|
||||
gmenu2x->drawButton(btnClear,
|
||||
gmenu2x->drawButton(btnSelect));
|
||||
}
|
||||
|
||||
bool MenuSettingFile::edited() {
|
||||
return originalValue != value();
|
||||
}
|
||||
54
src/menusettingfile.h
Normal file
54
src/menusettingfile.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2006 by Massimiliano Torromeo *
|
||||
* massimiliano.torromeo@gmail.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
#ifndef MENUSETTINGFILE_H
|
||||
#define MENUSETTINGFILE_H
|
||||
|
||||
#include "gmenu2x.h"
|
||||
#include "menusetting.h"
|
||||
|
||||
using std::string;
|
||||
|
||||
class MenuSettingFile : public MenuSetting {
|
||||
protected:
|
||||
string originalValue;
|
||||
string *_value;
|
||||
string filter;
|
||||
GMenu2X *gmenu2x;
|
||||
IconButton *btnClear, *btnSelect;
|
||||
|
||||
void select();
|
||||
void clear();
|
||||
|
||||
public:
|
||||
MenuSettingFile(GMenu2X *gmenu2x, string name, string description, string *value, string filter="");
|
||||
virtual ~MenuSettingFile() {};
|
||||
|
||||
virtual void draw(int y);
|
||||
virtual void handleTS();
|
||||
virtual void manageInput();
|
||||
virtual void adjustInput();
|
||||
virtual void drawSelected(int y);
|
||||
virtual bool edited();
|
||||
|
||||
virtual void setValue(string value);
|
||||
string value();
|
||||
};
|
||||
|
||||
#endif
|
||||
56
src/menusettingimage.cpp
Normal file
56
src/menusettingimage.cpp
Normal file
@@ -0,0 +1,56 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2006 by Massimiliano Torromeo *
|
||||
* massimiliano.torromeo@gmail.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
#include "menusettingimage.h"
|
||||
#include "imagedialog.h"
|
||||
#include "utilities.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
MenuSettingImage::MenuSettingImage(GMenu2X *gmenu2x, string name, string description, string *value, string filter)
|
||||
: MenuSettingFile(gmenu2x,name,description,value,filter) {
|
||||
this->gmenu2x = gmenu2x;
|
||||
this->filter = filter;
|
||||
_value = value;
|
||||
originalValue = *value;
|
||||
}
|
||||
|
||||
void MenuSettingImage::manageInput() {
|
||||
if ( gmenu2x->input[ACTION_X] ) setValue("");
|
||||
if ( gmenu2x->input[ACTION_B] ) {
|
||||
ImageDialog id(gmenu2x, description, filter, value());
|
||||
if (id.exec()) setValue( id.path()+"/"+id.file );
|
||||
}
|
||||
}
|
||||
|
||||
void MenuSettingImage::setValue(string value) {
|
||||
string skinpath = gmenu2x->getExePath()+"skins/"+gmenu2x->confStr["skin"];
|
||||
bool inSkinDir = value.substr(0,skinpath.length()) == skinpath;
|
||||
if (!inSkinDir && gmenu2x->confStr["skin"] != "Default") {
|
||||
skinpath = gmenu2x->getExePath()+"skins/Default";
|
||||
inSkinDir = value.substr(0,skinpath.length()) == skinpath;
|
||||
}
|
||||
if (inSkinDir) {
|
||||
string tempIcon = value.substr(skinpath.length(), value.length());
|
||||
string::size_type pos = tempIcon.find("/");
|
||||
if (pos != string::npos)
|
||||
value = "skin:"+tempIcon.substr(pos+1,value.length());
|
||||
}
|
||||
*_value = value;
|
||||
}
|
||||
37
src/menusettingimage.h
Normal file
37
src/menusettingimage.h
Normal file
@@ -0,0 +1,37 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2006 by Massimiliano Torromeo *
|
||||
* massimiliano.torromeo@gmail.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
#ifndef MENUSETTINGIMAGE_H
|
||||
#define MENUSETTINGIMAGE_H
|
||||
|
||||
#include "gmenu2x.h"
|
||||
#include "menusettingfile.h"
|
||||
|
||||
using std::string;
|
||||
|
||||
class MenuSettingImage : public MenuSettingFile {
|
||||
public:
|
||||
MenuSettingImage(GMenu2X *gmenu2x, string name, string description, string *value, string filter="");
|
||||
virtual ~MenuSettingImage() {};
|
||||
|
||||
virtual void manageInput();
|
||||
virtual void setValue(string value);
|
||||
};
|
||||
|
||||
#endif
|
||||
106
src/menusettingint.cpp
Normal file
106
src/menusettingint.cpp
Normal file
@@ -0,0 +1,106 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2006 by Massimiliano Torromeo *
|
||||
* massimiliano.torromeo@gmail.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
#include "menusettingint.h"
|
||||
#include "utilities.h"
|
||||
#include <sstream>
|
||||
|
||||
using namespace std;
|
||||
using namespace fastdelegate;
|
||||
|
||||
MenuSettingInt::MenuSettingInt(GMenu2X *gmenu2x, string name, string description, int *value, int min, int max)
|
||||
: MenuSetting(gmenu2x,name,description) {
|
||||
this->gmenu2x = gmenu2x;
|
||||
_value = value;
|
||||
originalValue = *value;
|
||||
this->min = min;
|
||||
this->max = max;
|
||||
setValue(this->value());
|
||||
|
||||
//Delegates
|
||||
ButtonAction actionInc = MakeDelegate(this, &MenuSettingInt::inc);
|
||||
ButtonAction actionDec = MakeDelegate(this, &MenuSettingInt::dec);
|
||||
|
||||
btnInc = new IconButton(gmenu2x, "skin:imgs/buttons/y.png", gmenu2x->tr["Increase value"]);
|
||||
btnInc->setAction(actionInc);
|
||||
|
||||
btnDec = new IconButton(gmenu2x, "skin:imgs/buttons/x.png", gmenu2x->tr["Decrease value"]);
|
||||
btnDec->setAction(actionDec);
|
||||
|
||||
btnInc2 = new IconButton(gmenu2x, "skin:imgs/buttons/right.png");
|
||||
btnInc2->setAction(actionInc);
|
||||
|
||||
btnDec2 = new IconButton(gmenu2x, "skin:imgs/buttons/left.png");
|
||||
btnDec2->setAction(actionDec);
|
||||
}
|
||||
|
||||
void MenuSettingInt::draw(int y) {
|
||||
MenuSetting::draw(y);
|
||||
gmenu2x->s->write( gmenu2x->font, strvalue, 155, y+gmenu2x->font->getHalfHeight(), SFontHAlignLeft, SFontVAlignMiddle );
|
||||
}
|
||||
|
||||
void MenuSettingInt::handleTS() {
|
||||
btnInc->handleTS();
|
||||
btnDec->handleTS();
|
||||
btnInc2->handleTS();
|
||||
btnDec2->handleTS();
|
||||
}
|
||||
|
||||
void MenuSettingInt::manageInput() {
|
||||
if ( gmenu2x->input[ACTION_LEFT ] || gmenu2x->input[ACTION_X] ) dec();
|
||||
if ( gmenu2x->input[ACTION_RIGHT] || gmenu2x->input[ACTION_Y] ) inc();
|
||||
}
|
||||
|
||||
void MenuSettingInt::inc() {
|
||||
setValue(value()+1);
|
||||
}
|
||||
|
||||
void MenuSettingInt::dec() {
|
||||
setValue(value()-1);
|
||||
}
|
||||
|
||||
void MenuSettingInt::setValue(int value) {
|
||||
*_value = constrain(value,min,max);
|
||||
stringstream ss;
|
||||
ss << *_value;
|
||||
strvalue = "";
|
||||
ss >> strvalue;
|
||||
}
|
||||
|
||||
int MenuSettingInt::value() {
|
||||
return *_value;
|
||||
}
|
||||
|
||||
void MenuSettingInt::adjustInput() {
|
||||
#ifdef TARGET_GP2X
|
||||
gmenu2x->input.setInterval(30, ACTION_LEFT );
|
||||
gmenu2x->input.setInterval(30, ACTION_RIGHT);
|
||||
#endif
|
||||
}
|
||||
|
||||
void MenuSettingInt::drawSelected(int) {
|
||||
gmenu2x->drawButton(btnInc,
|
||||
gmenu2x->drawButton(btnInc2,
|
||||
gmenu2x->drawButton(btnDec,
|
||||
gmenu2x->drawButton(btnDec2)-10))-10);
|
||||
}
|
||||
|
||||
bool MenuSettingInt::edited() {
|
||||
return originalValue != value();
|
||||
}
|
||||
57
src/menusettingint.h
Normal file
57
src/menusettingint.h
Normal file
@@ -0,0 +1,57 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2006 by Massimiliano Torromeo *
|
||||
* massimiliano.torromeo@gmail.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
#ifndef MENUSETTINGINT_H
|
||||
#define MENUSETTINGINT_H
|
||||
|
||||
#include "iconbutton.h"
|
||||
#include "menusetting.h"
|
||||
#include "FastDelegate.h"
|
||||
|
||||
using std::string;
|
||||
class GMenu2X;
|
||||
|
||||
class MenuSettingInt : public MenuSetting {
|
||||
private:
|
||||
int originalValue;
|
||||
int *_value;
|
||||
string strvalue;
|
||||
IconButton *btnInc, *btnDec, *btnInc2, *btnDec2;
|
||||
GMenu2X *gmenu2x;
|
||||
|
||||
void inc();
|
||||
void dec();
|
||||
|
||||
public:
|
||||
MenuSettingInt(GMenu2X *gmenu2x, string name, string description, int *value, int min, int max);
|
||||
virtual ~MenuSettingInt() {};
|
||||
|
||||
virtual void draw(int y);
|
||||
virtual void handleTS();
|
||||
virtual void manageInput();
|
||||
virtual void adjustInput();
|
||||
virtual void drawSelected(int y);
|
||||
virtual bool edited();
|
||||
|
||||
int min, max;
|
||||
virtual void setValue(int value);
|
||||
int value();
|
||||
};
|
||||
|
||||
#endif
|
||||
80
src/menusettingmultistring.cpp
Normal file
80
src/menusettingmultistring.cpp
Normal file
@@ -0,0 +1,80 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2006 by Massimiliano Torromeo *
|
||||
* massimiliano.torromeo@gmail.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
#include "menusettingmultistring.h"
|
||||
#include "utilities.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace fastdelegate;
|
||||
|
||||
MenuSettingMultiString::MenuSettingMultiString(GMenu2X *gmenu2x, string name, string description, string *value, vector<string> *choices)
|
||||
: MenuSetting(gmenu2x,name,description) {
|
||||
this->gmenu2x = gmenu2x;
|
||||
this->choices = choices;
|
||||
this->value = value;
|
||||
originalValue = *value;
|
||||
setSel( find(choices->begin(),choices->end(),*value)-choices->begin() );
|
||||
|
||||
btnDec = new IconButton(gmenu2x, "skin:imgs/buttons/left.png");
|
||||
btnDec->setAction(MakeDelegate(this, &MenuSettingMultiString::decSel));
|
||||
|
||||
btnInc = new IconButton(gmenu2x, "skin:imgs/buttons/right.png", gmenu2x->tr["Change value"]);
|
||||
btnInc->setAction(MakeDelegate(this, &MenuSettingMultiString::incSel));
|
||||
}
|
||||
|
||||
void MenuSettingMultiString::draw(int y) {
|
||||
MenuSetting::draw(y);
|
||||
gmenu2x->s->write( gmenu2x->font, *value, 155, y+gmenu2x->font->getHalfHeight(), SFontHAlignLeft, SFontVAlignMiddle );
|
||||
}
|
||||
|
||||
void MenuSettingMultiString::handleTS() {
|
||||
btnDec->handleTS();
|
||||
btnInc->handleTS();
|
||||
}
|
||||
|
||||
void MenuSettingMultiString::manageInput() {
|
||||
if ( gmenu2x->input[ACTION_LEFT ] ) decSel();
|
||||
if ( gmenu2x->input[ACTION_RIGHT] ) incSel();
|
||||
}
|
||||
|
||||
void MenuSettingMultiString::incSel() {
|
||||
setSel(selected+1);
|
||||
}
|
||||
|
||||
void MenuSettingMultiString::decSel() {
|
||||
setSel(selected-1);
|
||||
}
|
||||
|
||||
void MenuSettingMultiString::setSel(int sel) {
|
||||
if (sel<0) sel = choices->size()-1;
|
||||
else if (sel>=(int)choices->size()) sel = 0;
|
||||
selected = sel;
|
||||
*value = (*choices)[sel];
|
||||
}
|
||||
|
||||
void MenuSettingMultiString::adjustInput() {}
|
||||
|
||||
void MenuSettingMultiString::drawSelected(int) {
|
||||
gmenu2x->drawButton(btnInc,
|
||||
gmenu2x->drawButton(btnDec)-6);
|
||||
}
|
||||
|
||||
bool MenuSettingMultiString::edited() {
|
||||
return originalValue != *value;
|
||||
}
|
||||
53
src/menusettingmultistring.h
Normal file
53
src/menusettingmultistring.h
Normal file
@@ -0,0 +1,53 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2006 by Massimiliano Torromeo *
|
||||
* massimiliano.torromeo@gmail.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
#ifndef MENUSETTINGMULTISTRING_H
|
||||
#define MENUSETTINGMULTISTRING_H
|
||||
|
||||
#include "gmenu2x.h"
|
||||
#include "menusetting.h"
|
||||
|
||||
using std::string;
|
||||
|
||||
class MenuSettingMultiString : public MenuSetting {
|
||||
private:
|
||||
uint selected;
|
||||
string *value;
|
||||
string originalValue;
|
||||
vector<string> *choices;
|
||||
GMenu2X *gmenu2x;
|
||||
IconButton *btnDec, *btnInc;
|
||||
|
||||
void incSel();
|
||||
void decSel();
|
||||
void setSel(int);
|
||||
|
||||
public:
|
||||
MenuSettingMultiString(GMenu2X *gmenu2x, string name, string description, string *value, vector<string> *choices);
|
||||
virtual ~MenuSettingMultiString() {};
|
||||
|
||||
virtual void draw(int y);
|
||||
virtual void handleTS();
|
||||
virtual void manageInput();
|
||||
virtual void adjustInput();
|
||||
virtual void drawSelected(int y);
|
||||
virtual bool edited();
|
||||
};
|
||||
|
||||
#endif
|
||||
168
src/menusettingrgba.cpp
Normal file
168
src/menusettingrgba.cpp
Normal file
@@ -0,0 +1,168 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2006 by Massimiliano Torromeo *
|
||||
* massimiliano.torromeo@gmail.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
#include "menusettingrgba.h"
|
||||
#include <sstream>
|
||||
|
||||
using namespace std;
|
||||
using namespace fastdelegate;
|
||||
|
||||
MenuSettingRGBA::MenuSettingRGBA(GMenu2X *gmenu2x, string name, string description, RGBAColor *value)
|
||||
: MenuSetting(gmenu2x,name,description) {
|
||||
selPart = 0;
|
||||
this->gmenu2x = gmenu2x;
|
||||
_value = value;
|
||||
originalValue = *value;
|
||||
this->setR(this->value().r);
|
||||
this->setG(this->value().g);
|
||||
this->setB(this->value().b);
|
||||
this->setA(this->value().a);
|
||||
|
||||
btnDec = new IconButton(gmenu2x, "skin:imgs/buttons/x.png", gmenu2x->tr["Decrease"]);
|
||||
btnDec->setAction(MakeDelegate(this, &MenuSettingRGBA::dec));
|
||||
|
||||
btnInc = new IconButton(gmenu2x, "skin:imgs/buttons/y.png", gmenu2x->tr["Increase"]);
|
||||
btnInc->setAction(MakeDelegate(this, &MenuSettingRGBA::inc));
|
||||
|
||||
btnLeftComponent = new IconButton(gmenu2x, "skin:imgs/buttons/left.png");
|
||||
btnLeftComponent->setAction(MakeDelegate(this, &MenuSettingRGBA::leftComponent));
|
||||
|
||||
btnRightComponent = new IconButton(gmenu2x, "skin:imgs/buttons/right.png", gmenu2x->tr["Change color component"]);
|
||||
btnRightComponent->setAction(MakeDelegate(this, &MenuSettingRGBA::rightComponent));
|
||||
}
|
||||
|
||||
void MenuSettingRGBA::draw(int y) {
|
||||
this->y = y;
|
||||
MenuSetting::draw(y);
|
||||
gmenu2x->s->rectangle( 153, y+1, 11, 11, 0,0,0,255 );
|
||||
gmenu2x->s->box( 154, y+2, 9, 9, value() );
|
||||
gmenu2x->s->write( gmenu2x->font, "R: "+strR, 169, y+gmenu2x->font->getHalfHeight(), SFontHAlignLeft, SFontVAlignMiddle );
|
||||
gmenu2x->s->write( gmenu2x->font, "G: "+strG, 205, y+gmenu2x->font->getHalfHeight(), SFontHAlignLeft, SFontVAlignMiddle );
|
||||
gmenu2x->s->write( gmenu2x->font, "B: "+strB, 241, y+gmenu2x->font->getHalfHeight(), SFontHAlignLeft, SFontVAlignMiddle );
|
||||
gmenu2x->s->write( gmenu2x->font, "A: "+strA, 277, y+gmenu2x->font->getHalfHeight(), SFontHAlignLeft, SFontVAlignMiddle );
|
||||
}
|
||||
|
||||
void MenuSettingRGBA::handleTS() {
|
||||
if (gmenu2x->ts.pressed())
|
||||
for (int i=0; i<4; i++)
|
||||
if (i!=selPart && gmenu2x->ts.inRect(166+i*36,y,36,14)) {
|
||||
selPart = i;
|
||||
i = 4;
|
||||
}
|
||||
|
||||
btnDec->handleTS();
|
||||
btnInc->handleTS();
|
||||
btnLeftComponent->handleTS();
|
||||
btnRightComponent->handleTS();
|
||||
}
|
||||
|
||||
void MenuSettingRGBA::manageInput() {
|
||||
if ( gmenu2x->input[ACTION_Y ]) inc();
|
||||
if ( gmenu2x->input[ACTION_X ]) dec();
|
||||
if ( gmenu2x->input[ACTION_LEFT ]) leftComponent();
|
||||
if ( gmenu2x->input[ACTION_RIGHT]) rightComponent();
|
||||
}
|
||||
|
||||
void MenuSettingRGBA::dec() {
|
||||
setSelPart( constrain(getSelPart()-1,0,255) );
|
||||
}
|
||||
|
||||
void MenuSettingRGBA::inc() {
|
||||
setSelPart( constrain(getSelPart()+1,0,255) );
|
||||
}
|
||||
|
||||
void MenuSettingRGBA::leftComponent() {
|
||||
selPart = constrain(selPart-1,0,3);
|
||||
}
|
||||
|
||||
void MenuSettingRGBA::rightComponent() {
|
||||
selPart = constrain(selPart+1,0,3);
|
||||
}
|
||||
|
||||
void MenuSettingRGBA::setR(unsigned short r) {
|
||||
_value->r = r;
|
||||
stringstream ss;
|
||||
ss << r;
|
||||
ss >> strR;
|
||||
}
|
||||
|
||||
void MenuSettingRGBA::setG(unsigned short g) {
|
||||
_value->g = g;
|
||||
stringstream ss;
|
||||
ss << g;
|
||||
ss >> strG;
|
||||
}
|
||||
|
||||
void MenuSettingRGBA::setB(unsigned short b) {
|
||||
_value->b = b;
|
||||
stringstream ss;
|
||||
ss << b;
|
||||
ss >> strB;
|
||||
}
|
||||
|
||||
void MenuSettingRGBA::setA(unsigned short a) {
|
||||
_value->a = a;
|
||||
stringstream ss;
|
||||
ss << a;
|
||||
ss >> strA;
|
||||
}
|
||||
|
||||
void MenuSettingRGBA::setSelPart(unsigned short value) {
|
||||
switch (selPart) {
|
||||
default: case 0: setR(value); break;
|
||||
case 1: setG(value); break;
|
||||
case 2: setB(value); break;
|
||||
case 3: setA(value); break;
|
||||
}
|
||||
}
|
||||
|
||||
RGBAColor MenuSettingRGBA::value() {
|
||||
return *_value;
|
||||
}
|
||||
|
||||
unsigned short MenuSettingRGBA::getSelPart() {
|
||||
switch (selPart) {
|
||||
default: case 0: return value().r;
|
||||
case 1: return value().g;
|
||||
case 2: return value().b;
|
||||
case 3: return value().a;
|
||||
}
|
||||
}
|
||||
|
||||
void MenuSettingRGBA::adjustInput() {
|
||||
#ifdef TARGET_GP2X
|
||||
gmenu2x->input.setInterval(30, ACTION_Y );
|
||||
gmenu2x->input.setInterval(30, ACTION_X );
|
||||
gmenu2x->input.setInterval(30, ACTION_L );
|
||||
#endif
|
||||
}
|
||||
|
||||
void MenuSettingRGBA::drawSelected(int y) {
|
||||
int x = 166+selPart*36;
|
||||
gmenu2x->s->box( x, y, 36, 14, gmenu2x->skinConfColors["selectionBg"] );
|
||||
|
||||
gmenu2x->drawButton(btnDec,
|
||||
gmenu2x->drawButton(btnInc,
|
||||
gmenu2x->drawButton(btnRightComponent,
|
||||
gmenu2x->drawButton(btnLeftComponent)-6)));
|
||||
}
|
||||
|
||||
bool MenuSettingRGBA::edited() {
|
||||
return originalValue.r != value().r || originalValue.g != value().g || originalValue.b != value().b || originalValue.a != value().a;
|
||||
}
|
||||
64
src/menusettingrgba.h
Normal file
64
src/menusettingrgba.h
Normal file
@@ -0,0 +1,64 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2006 by Massimiliano Torromeo *
|
||||
* massimiliano.torromeo@gmail.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
#ifndef MENUSETTINGRGBA_H
|
||||
#define MENUSETTINGRGBA_H
|
||||
|
||||
#include "gmenu2x.h"
|
||||
#include "menusetting.h"
|
||||
#include "utilities.h"
|
||||
|
||||
using std::string;
|
||||
|
||||
class MenuSettingRGBA : public MenuSetting {
|
||||
private:
|
||||
unsigned short selPart;
|
||||
int y;
|
||||
string strR, strG, strB, strA;
|
||||
RGBAColor originalValue;
|
||||
RGBAColor *_value;
|
||||
GMenu2X *gmenu2x;
|
||||
IconButton *btnDec, *btnInc, *btnLeftComponent, *btnRightComponent;
|
||||
|
||||
void dec();
|
||||
void inc();
|
||||
void leftComponent();
|
||||
void rightComponent();
|
||||
|
||||
public:
|
||||
MenuSettingRGBA(GMenu2X *gmenu2x, string name, string description, RGBAColor *value);
|
||||
virtual ~MenuSettingRGBA() {};
|
||||
|
||||
virtual void draw(int y);
|
||||
virtual void handleTS();
|
||||
virtual void manageInput();
|
||||
virtual void adjustInput();
|
||||
virtual void drawSelected(int y);
|
||||
virtual bool edited();
|
||||
|
||||
void setSelPart(unsigned short value);
|
||||
void setR(unsigned short r);
|
||||
void setG(unsigned short g);
|
||||
void setB(unsigned short b);
|
||||
void setA(unsigned short a);
|
||||
unsigned short getSelPart();
|
||||
RGBAColor value();
|
||||
};
|
||||
|
||||
#endif
|
||||
82
src/menusettingstring.cpp
Normal file
82
src/menusettingstring.cpp
Normal file
@@ -0,0 +1,82 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2006 by Massimiliano Torromeo *
|
||||
* massimiliano.torromeo@gmail.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
#include "menusettingstring.h"
|
||||
#include "inputdialog.h"
|
||||
#include "utilities.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace fastdelegate;
|
||||
|
||||
MenuSettingString::MenuSettingString(GMenu2X *gmenu2x, string name, string description, string *value, string diagTitle, string diagIcon)
|
||||
: MenuSetting(gmenu2x,name,description) {
|
||||
this->gmenu2x = gmenu2x;
|
||||
_value = value;
|
||||
originalValue = *value;
|
||||
this->diagTitle = diagTitle;
|
||||
this->diagIcon = diagIcon;
|
||||
|
||||
btnClear = new IconButton(gmenu2x, "skin:imgs/buttons/x.png", gmenu2x->tr["Clear"]);
|
||||
btnClear->setAction(MakeDelegate(this, &MenuSettingString::clear));
|
||||
|
||||
btnEdit = new IconButton(gmenu2x, "skin:imgs/buttons/b.png", gmenu2x->tr["Edit"]);
|
||||
btnEdit->setAction(MakeDelegate(this, &MenuSettingString::edit));
|
||||
}
|
||||
|
||||
void MenuSettingString::draw(int y) {
|
||||
MenuSetting::draw(y);
|
||||
gmenu2x->s->write( gmenu2x->font, value(), 155, y+gmenu2x->font->getHalfHeight(), SFontHAlignLeft, SFontVAlignMiddle );
|
||||
}
|
||||
|
||||
void MenuSettingString::handleTS() {
|
||||
btnEdit->handleTS();
|
||||
}
|
||||
|
||||
void MenuSettingString::manageInput() {
|
||||
if ( gmenu2x->input[ACTION_X] ) clear();
|
||||
if ( gmenu2x->input[ACTION_B] ) edit();
|
||||
}
|
||||
|
||||
void MenuSettingString::setValue(string value) {
|
||||
*_value = value;
|
||||
}
|
||||
|
||||
string MenuSettingString::value() {
|
||||
return *_value;
|
||||
}
|
||||
|
||||
void MenuSettingString::adjustInput() {}
|
||||
|
||||
void MenuSettingString::clear() {
|
||||
setValue("");
|
||||
}
|
||||
|
||||
void MenuSettingString::edit() {
|
||||
InputDialog id(gmenu2x,description,value(), diagTitle,diagIcon);
|
||||
if (id.exec()) setValue(id.input);
|
||||
}
|
||||
|
||||
void MenuSettingString::drawSelected(int) {
|
||||
gmenu2x->drawButton(btnClear,
|
||||
gmenu2x->drawButton(btnEdit));
|
||||
}
|
||||
|
||||
bool MenuSettingString::edited() {
|
||||
return originalValue != value();
|
||||
}
|
||||
53
src/menusettingstring.h
Normal file
53
src/menusettingstring.h
Normal file
@@ -0,0 +1,53 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2006 by Massimiliano Torromeo *
|
||||
* massimiliano.torromeo@gmail.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
#ifndef MENUSETTINGSTRING_H
|
||||
#define MENUSETTINGSTRING_H
|
||||
|
||||
#include "gmenu2x.h"
|
||||
#include "menusetting.h"
|
||||
|
||||
using std::string;
|
||||
|
||||
class MenuSettingString : public MenuSetting {
|
||||
private:
|
||||
string originalValue, diagTitle, diagIcon;
|
||||
string *_value;
|
||||
GMenu2X *gmenu2x;
|
||||
IconButton *btnClear, *btnEdit;
|
||||
|
||||
void edit();
|
||||
void clear();
|
||||
|
||||
public:
|
||||
MenuSettingString(GMenu2X *gmenu2x, string name, string description, string *value, string diagTitle="", string diagIcon="");
|
||||
virtual ~MenuSettingString() {};
|
||||
|
||||
virtual void draw(int y);
|
||||
virtual void handleTS();
|
||||
virtual void manageInput();
|
||||
virtual void adjustInput();
|
||||
virtual void drawSelected(int y);
|
||||
virtual bool edited();
|
||||
|
||||
void setValue(string value);
|
||||
string value();
|
||||
};
|
||||
|
||||
#endif
|
||||
120
src/messagebox.cpp
Normal file
120
src/messagebox.cpp
Normal file
@@ -0,0 +1,120 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2006 by Massimiliano Torromeo *
|
||||
* massimiliano.torromeo@gmail.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#include <SDL.h>
|
||||
#include <SDL_gfxPrimitives.h>
|
||||
|
||||
#include "messagebox.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
MessageBox::MessageBox(GMenu2X *gmenu2x, string text, string icon) {
|
||||
this->gmenu2x = gmenu2x;
|
||||
this->text = text;
|
||||
this->icon = icon;
|
||||
|
||||
buttons.resize(19);
|
||||
buttonLabels.resize(19);
|
||||
buttonPositions.resize(19);
|
||||
for (uint x=0; x<buttons.size(); x++) {
|
||||
buttons[x] = "";
|
||||
buttonLabels[x] = "";
|
||||
buttonPositions[x].h = gmenu2x->font->getHeight();
|
||||
}
|
||||
|
||||
//Default enabled button
|
||||
buttons[ACTION_B] = "OK";
|
||||
|
||||
//Default labels
|
||||
buttonLabels[ACTION_UP] = "up";
|
||||
buttonLabels[ACTION_DOWN] = "down";
|
||||
buttonLabels[ACTION_LEFT] = "left";
|
||||
buttonLabels[ACTION_RIGHT] = "right";
|
||||
buttonLabels[ACTION_A] = "a";
|
||||
buttonLabels[ACTION_B] = "b";
|
||||
buttonLabels[ACTION_X] = "x";
|
||||
buttonLabels[ACTION_Y] = "y";
|
||||
buttonLabels[ACTION_L] = "l";
|
||||
buttonLabels[ACTION_R] = "r";
|
||||
buttonLabels[ACTION_START] = "start";
|
||||
buttonLabels[ACTION_SELECT] = "select";
|
||||
buttonLabels[ACTION_VOLUP] = "vol+";
|
||||
buttonLabels[ACTION_VOLDOWN] = "vol-";
|
||||
}
|
||||
|
||||
int MessageBox::exec() {
|
||||
int result = -1;
|
||||
|
||||
Surface bg(gmenu2x->s);
|
||||
//Darken background
|
||||
bg.box(0, 0, gmenu2x->resX, gmenu2x->resY, 0,0,0,200);
|
||||
|
||||
SDL_Rect box;
|
||||
box.h = gmenu2x->font->getHeight()*3 +4;
|
||||
box.w = gmenu2x->font->getTextWidth(text) + 24 + (gmenu2x->sc[icon] != NULL ? 37 : 0);
|
||||
box.x = gmenu2x->halfX - box.w/2 -2;
|
||||
box.y = gmenu2x->halfY - box.h/2 -2;
|
||||
|
||||
//outer box
|
||||
bg.box(box, gmenu2x->skinConfColors["messageBoxBg"]);
|
||||
//draw inner rectangle
|
||||
bg.rectangle(box.x+2, box.y+2, box.w-4, box.h-gmenu2x->font->getHeight(), gmenu2x->skinConfColors["messageBoxBorder"]);
|
||||
//icon+text
|
||||
if (gmenu2x->sc[icon] != NULL)
|
||||
gmenu2x->sc[icon]->blitCenter( &bg, box.x+25, box.y+gmenu2x->font->getHeight()+3 );
|
||||
bg.write( gmenu2x->font, text, box.x+(gmenu2x->sc[icon] != NULL ? 47 : 10), box.y+gmenu2x->font->getHeight()+3, SFontHAlignLeft, SFontVAlignMiddle );
|
||||
|
||||
int btnX = gmenu2x->halfX+box.w/2-6;
|
||||
for (uint i=0; i<buttons.size(); i++) {
|
||||
if (buttons[i] != "") {
|
||||
buttonPositions[i].y = box.y+box.h-4;
|
||||
buttonPositions[i].w = btnX;
|
||||
|
||||
btnX = gmenu2x->drawButtonRight(&bg, buttonLabels[i], buttons[i], btnX, buttonPositions[i].y);
|
||||
|
||||
buttonPositions[i].x = btnX;
|
||||
buttonPositions[i].w = buttonPositions[i].x-btnX-6;
|
||||
}
|
||||
}
|
||||
|
||||
bg.blit(gmenu2x->s,0,0);
|
||||
gmenu2x->s->flip();
|
||||
|
||||
while (result<0) {
|
||||
//touchscreen
|
||||
if (gmenu2x->f200) {
|
||||
if (gmenu2x->ts.poll()) {
|
||||
for (uint i=0; i<buttons.size(); i++)
|
||||
if (buttons[i]!="" && gmenu2x->ts.inRect(buttonPositions[i])) {
|
||||
result = i;
|
||||
i = buttons.size();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gmenu2x->input.update();
|
||||
for (uint i=0; i<buttons.size(); i++)
|
||||
if (buttons[i]!="" && gmenu2x->input[i]) result = i;
|
||||
|
||||
usleep(LOOP_DELAY);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
48
src/messagebox.h
Normal file
48
src/messagebox.h
Normal file
@@ -0,0 +1,48 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2006 by Massimiliano Torromeo *
|
||||
* massimiliano.torromeo@gmail.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef MESSAGEBOX_H_
|
||||
#define MESSAGEBOX_H_
|
||||
|
||||
#define MB_BTN_B 0
|
||||
#define MB_BTN_X 1
|
||||
#define MB_BTN_START 2
|
||||
#define MB_BTN_SELECT 3
|
||||
|
||||
#include <string>
|
||||
#include "gmenu2x.h"
|
||||
|
||||
using std::string;
|
||||
using std::vector;
|
||||
|
||||
class MessageBox {
|
||||
private:
|
||||
string text, icon;
|
||||
GMenu2X *gmenu2x;
|
||||
|
||||
public:
|
||||
MessageBox(GMenu2X *gmenu2x, string text, string icon="");
|
||||
vector<string> buttons;
|
||||
vector<string> buttonLabels;
|
||||
vector<SDL_Rect> buttonPositions;
|
||||
int exec();
|
||||
};
|
||||
|
||||
#endif /*MESSAGEBOX_H_*/
|
||||
127
src/pxml.cpp
Normal file
127
src/pxml.cpp
Normal file
@@ -0,0 +1,127 @@
|
||||
#include "pxml.h"
|
||||
#include "tinyxml/tinyxml.h"
|
||||
#include <sstream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
PXml::PXml(string file) {
|
||||
valid = false;
|
||||
error = title = description = authorName = authorWebsite = category = exec = icon = "";
|
||||
version = osVersion = (SoftwareVersion){0,0,0,0};
|
||||
|
||||
TiXmlDocument doc(file.c_str());
|
||||
if (doc.LoadFile()) {
|
||||
TiXmlHandle hDoc(&doc);
|
||||
TiXmlElement* pElem;
|
||||
|
||||
pElem = hDoc.FirstChildElement().Element();
|
||||
TiXmlHandle hPXML(pElem);
|
||||
if (pElem) pElem = hPXML.FirstChildElement( "title" ).Element();
|
||||
if (pElem) {
|
||||
title = pElem->GetText();
|
||||
pElem = hPXML.FirstChildElement( "description" ).Element();
|
||||
}
|
||||
if (pElem) {
|
||||
description = pElem->GetText();
|
||||
pElem = hPXML.FirstChildElement( "author" ).Element();
|
||||
}
|
||||
if (pElem) {
|
||||
authorName = pElem->Attribute("name");
|
||||
authorWebsite = pElem->Attribute("website");
|
||||
|
||||
pElem = hPXML.FirstChildElement( "version" ).Element();
|
||||
}
|
||||
if (pElem) {
|
||||
pElem->QueryIntAttribute("major", &version.major);
|
||||
pElem->QueryIntAttribute("minor", &version.minor);
|
||||
pElem->QueryIntAttribute("release", &version.release);
|
||||
pElem->QueryIntAttribute("build", &version.build);
|
||||
|
||||
pElem = hPXML.FirstChildElement( "exec" ).Element();
|
||||
}
|
||||
if (pElem) {
|
||||
exec = pElem->GetText();
|
||||
|
||||
pElem = hPXML.FirstChildElement( "category" ).Element();
|
||||
}
|
||||
if (pElem) {
|
||||
category = pElem->GetText();
|
||||
|
||||
valid = true;
|
||||
|
||||
//All required fields have been found, parsing optional fields
|
||||
pElem = hPXML.FirstChildElement("icon").Element();
|
||||
if (pElem) icon = pElem->GetText();
|
||||
|
||||
pElem = hPXML.FirstChildElement( "osversion" ).Element();
|
||||
if (pElem) {
|
||||
pElem->QueryIntAttribute("major", &osVersion.major);
|
||||
pElem->QueryIntAttribute("minor", &osVersion.minor);
|
||||
pElem->QueryIntAttribute("release", &osVersion.release);
|
||||
pElem->QueryIntAttribute("build", &osVersion.build);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
error = doc.ErrorDesc();
|
||||
}
|
||||
}
|
||||
|
||||
bool PXml::isValid() {
|
||||
return valid;
|
||||
}
|
||||
|
||||
string PXml::getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
string PXml::getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
string PXml::getAuthorName() {
|
||||
return authorName;
|
||||
}
|
||||
|
||||
string PXml::getAuthorWebsite() {
|
||||
return authorWebsite;
|
||||
}
|
||||
|
||||
string PXml::getCategory() {
|
||||
return category;
|
||||
}
|
||||
|
||||
string PXml::getExec() {
|
||||
return exec;
|
||||
}
|
||||
|
||||
string PXml::getIcon() {
|
||||
return icon;
|
||||
}
|
||||
|
||||
SoftwareVersion PXml::getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
string PXml::getVersionString() {
|
||||
string versionString = "";
|
||||
stringstream ss;
|
||||
ss << version.major << "." << version.minor << "." << version.release << "." << version.build;
|
||||
ss >> versionString;
|
||||
return versionString;
|
||||
}
|
||||
|
||||
SoftwareVersion PXml::getOsVersion() {
|
||||
return osVersion;
|
||||
}
|
||||
|
||||
string PXml::getOsVersionString() {
|
||||
string versionString = "";
|
||||
stringstream ss;
|
||||
ss << osVersion.major << "." << osVersion.minor << "." << osVersion.release << "." << osVersion.build;
|
||||
ss >> versionString;
|
||||
return versionString;
|
||||
}
|
||||
|
||||
string PXml::getError() {
|
||||
return error;
|
||||
}
|
||||
59
src/pxml.h
Normal file
59
src/pxml.h
Normal file
@@ -0,0 +1,59 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2006 by Massimiliano Torromeo *
|
||||
* massimiliano.torromeo@gmail.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef PXML_H_
|
||||
#define PXML_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
using std::string;
|
||||
|
||||
struct SoftwareVersion {
|
||||
int major, minor, release, build;
|
||||
};
|
||||
|
||||
class PXml {
|
||||
private:
|
||||
bool valid;
|
||||
string title, description, error, authorName, authorWebsite, category, exec, icon;
|
||||
SoftwareVersion version, osVersion;
|
||||
|
||||
public:
|
||||
PXml(string file);
|
||||
|
||||
bool isValid();
|
||||
|
||||
string getTitle();
|
||||
string getDescription();
|
||||
string getAuthorName();
|
||||
string getAuthorWebsite();
|
||||
string getCategory();
|
||||
string getExec();
|
||||
string getIcon();
|
||||
|
||||
SoftwareVersion getVersion();
|
||||
string getVersionString();
|
||||
SoftwareVersion getOsVersion();
|
||||
string getOsVersionString();
|
||||
|
||||
string getError();
|
||||
};
|
||||
|
||||
#endif /*PXML_H_*/
|
||||
244
src/selector.cpp
Normal file
244
src/selector.cpp
Normal file
@@ -0,0 +1,244 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2006 by Massimiliano Torromeo *
|
||||
* massimiliano.torromeo@gmail.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#include <SDL.h>
|
||||
#include <SDL_gfxPrimitives.h>
|
||||
|
||||
//for browsing the filesystem
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
|
||||
#include "menu.h"
|
||||
#include "linkapp.h"
|
||||
#include "selector.h"
|
||||
#include "filelister.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
Selector::Selector(GMenu2X *gmenu2x, LinkApp *link, string selectorDir) {
|
||||
this->gmenu2x = gmenu2x;
|
||||
this->link = link;
|
||||
loadAliases();
|
||||
selRow = 0;
|
||||
if (selectorDir=="")
|
||||
dir = link->getSelectorDir();
|
||||
else
|
||||
dir = selectorDir;
|
||||
if (dir[dir.length()-1]!='/') dir += "/";
|
||||
}
|
||||
|
||||
int Selector::exec(int startSelection) {
|
||||
bool close = false, result = true;
|
||||
vector<string> screens, titles;
|
||||
|
||||
FileLister fl(dir, link->getSelectorBrowser());
|
||||
fl.setFilter(link->getSelectorFilter());
|
||||
fl.browse();
|
||||
|
||||
Surface bg(gmenu2x->bg);
|
||||
gmenu2x->drawTitleIcon(link->getIconPath(),true,&bg);
|
||||
gmenu2x->writeTitle(link->getTitle(),&bg);
|
||||
gmenu2x->writeSubTitle(link->getDescription(),&bg);
|
||||
|
||||
if (link->getSelectorBrowser()) {
|
||||
gmenu2x->drawButton(&bg, "start", gmenu2x->tr["Exit"],
|
||||
gmenu2x->drawButton(&bg, "b", gmenu2x->tr["Select a file"],
|
||||
gmenu2x->drawButton(&bg, "x", gmenu2x->tr["Up one folder"], 5)));
|
||||
} else {
|
||||
gmenu2x->drawButton(&bg, "x", gmenu2x->tr["Exit"],
|
||||
gmenu2x->drawButton(&bg, "b", gmenu2x->tr["Select a file"], 5));
|
||||
}
|
||||
|
||||
Uint32 selTick = SDL_GetTicks(), curTick;
|
||||
uint i, firstElement = 0, iY;
|
||||
|
||||
prepare(&fl,&screens,&titles);
|
||||
uint selected = constrain(startSelection,0,fl.size()-1);
|
||||
|
||||
//Add the folder icon manually to be sure to load it with alpha support since we are going to disable it for screenshots
|
||||
if (gmenu2x->sc.skinRes("imgs/folder.png")==NULL)
|
||||
gmenu2x->sc.addSkinRes("imgs/folder.png");
|
||||
gmenu2x->sc.defaultAlpha = false;
|
||||
while (!close) {
|
||||
bg.blit(gmenu2x->s,0,0);
|
||||
|
||||
if (selected>=firstElement+SELECTOR_ELEMENTS) firstElement=selected-SELECTOR_ELEMENTS+1;
|
||||
if (selected<firstElement) firstElement=selected;
|
||||
|
||||
//Selection
|
||||
iY = selected-firstElement;
|
||||
iY = 42+(iY*16);
|
||||
if (selected<fl.size())
|
||||
gmenu2x->s->box(1, iY, 309, 14, gmenu2x->skinConfColors["selectionBg"]);
|
||||
|
||||
//Screenshot
|
||||
if (selected-fl.dirCount()<screens.size() && screens[selected-fl.dirCount()]!="") {
|
||||
curTick = SDL_GetTicks();
|
||||
if (curTick-selTick>200)
|
||||
gmenu2x->sc[screens[selected-fl.dirCount()]]->blitRight(gmenu2x->s, 311, 42, 160, 160, min((curTick-selTick-200)/3,255));
|
||||
}
|
||||
|
||||
//Files & Dirs
|
||||
gmenu2x->s->setClipRect(0,41,311,179);
|
||||
for (i=firstElement; i<fl.size() && i<firstElement+SELECTOR_ELEMENTS; i++) {
|
||||
iY = i-firstElement;
|
||||
if (fl.isDirectory(i)) {
|
||||
gmenu2x->sc["imgs/folder.png"]->blit(gmenu2x->s, 4, 42+(iY*16));
|
||||
gmenu2x->s->write(gmenu2x->font, fl[i], 21, 49+(iY*16), SFontHAlignLeft, SFontVAlignMiddle);
|
||||
} else
|
||||
gmenu2x->s->write(gmenu2x->font, titles[i-fl.dirCount()], 4, 49+(iY*16), SFontHAlignLeft, SFontVAlignMiddle);
|
||||
}
|
||||
gmenu2x->s->clearClipRect();
|
||||
|
||||
gmenu2x->drawScrollBar(SELECTOR_ELEMENTS,fl.size(),firstElement,42,175);
|
||||
gmenu2x->s->flip();
|
||||
|
||||
|
||||
gmenu2x->input.update();
|
||||
if ( gmenu2x->input[ACTION_START] ) { close = true; result = false; }
|
||||
if ( gmenu2x->input[ACTION_UP] ) {
|
||||
if (selected==0) {
|
||||
selected = fl.size()-1;
|
||||
} else {
|
||||
selected -= 1;
|
||||
}
|
||||
selTick = SDL_GetTicks();
|
||||
}
|
||||
if ( gmenu2x->input[ACTION_L] ) {
|
||||
if ((int)(selected-SELECTOR_ELEMENTS+1)<0) {
|
||||
selected = 0;
|
||||
} else {
|
||||
selected -= SELECTOR_ELEMENTS-1;
|
||||
}
|
||||
selTick = SDL_GetTicks();
|
||||
}
|
||||
if ( gmenu2x->input[ACTION_DOWN] ) {
|
||||
if (selected+1>=fl.size()) {
|
||||
selected = 0;
|
||||
} else {
|
||||
selected += 1;
|
||||
}
|
||||
selTick = SDL_GetTicks();
|
||||
}
|
||||
if ( gmenu2x->input[ACTION_R] ) {
|
||||
if (selected+SELECTOR_ELEMENTS-1>=fl.size()) {
|
||||
selected = fl.size()-1;
|
||||
} else {
|
||||
selected += SELECTOR_ELEMENTS-1;
|
||||
}
|
||||
selTick = SDL_GetTicks();
|
||||
}
|
||||
if ( gmenu2x->input[ACTION_X] ) {
|
||||
if (link->getSelectorBrowser()) {
|
||||
string::size_type p = dir.rfind("/", dir.size()-2);
|
||||
if (p==string::npos || dir.substr(0,4)!="/card" || p<4) {
|
||||
close = true;
|
||||
result = false;
|
||||
} else {
|
||||
dir = dir.substr(0,p+1);
|
||||
cout << dir << endl;
|
||||
selected = 0;
|
||||
firstElement = 0;
|
||||
prepare(&fl,&screens,&titles);
|
||||
}
|
||||
} else {
|
||||
close = true;
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
if ( gmenu2x->input[ACTION_B] ) {
|
||||
if (fl.isFile(selected)) {
|
||||
file = fl[selected];
|
||||
close = true;
|
||||
} else {
|
||||
dir = dir+fl[selected]+"/";
|
||||
selected = 0;
|
||||
firstElement = 0;
|
||||
prepare(&fl,&screens,&titles);
|
||||
}
|
||||
}
|
||||
}
|
||||
gmenu2x->sc.defaultAlpha = true;
|
||||
freeScreenshots(&screens);
|
||||
|
||||
return result ? (int)selected : -1;
|
||||
}
|
||||
|
||||
void Selector::prepare(FileLister *fl, vector<string> *screens, vector<string> *titles) {
|
||||
fl->setPath(dir);
|
||||
freeScreenshots(screens);
|
||||
screens->resize(fl->files.size());
|
||||
titles->resize(fl->files.size());
|
||||
|
||||
string screendir = link->getSelectorScreens();
|
||||
if (screendir != "" && screendir[screendir.length()-1]!='/') screendir += "/";
|
||||
|
||||
string noext;
|
||||
string::size_type pos;
|
||||
for (uint i=0; i<fl->files.size(); i++) {
|
||||
noext = fl->files[i];
|
||||
pos = noext.rfind(".");
|
||||
if (pos!=string::npos && pos>0)
|
||||
noext = noext.substr(0, pos);
|
||||
titles->at(i) = getAlias(noext);
|
||||
if (titles->at(i)=="")
|
||||
titles->at(i) = noext;
|
||||
#ifdef DEBUG
|
||||
cout << "\033[0;34mGMENU2X:\033[0m Searching for screen " << screendir << noext << ".png" << endl;
|
||||
#endif
|
||||
if (fileExists(screendir+noext+".png"))
|
||||
screens->at(i) = screendir+noext+".png";
|
||||
else if (fileExists(screendir+noext+".jpg"))
|
||||
screens->at(i) = screendir+noext+".jpg";
|
||||
else
|
||||
screens->at(i) = "";
|
||||
}
|
||||
}
|
||||
|
||||
void Selector::freeScreenshots(vector<string> *screens) {
|
||||
for (uint i=0; i<screens->size(); i++) {
|
||||
if (screens->at(i) != "")
|
||||
gmenu2x->sc.del(screens->at(i));
|
||||
}
|
||||
}
|
||||
|
||||
void Selector::loadAliases() {
|
||||
aliases.clear();
|
||||
if (fileExists(link->getAliasFile())) {
|
||||
string line;
|
||||
ifstream infile (link->getAliasFile().c_str(), ios_base::in);
|
||||
while (getline(infile, line, '\n')) {
|
||||
string::size_type position = line.find("=");
|
||||
string name = trim(line.substr(0,position));
|
||||
string value = trim(line.substr(position+1));
|
||||
aliases[name] = value;
|
||||
}
|
||||
infile.close();
|
||||
}
|
||||
}
|
||||
|
||||
string Selector::getAlias(string key) {
|
||||
hash_map<string, string>::iterator i = aliases.find(key);
|
||||
if (i == aliases.end())
|
||||
return "";
|
||||
else
|
||||
return i->second;
|
||||
}
|
||||
55
src/selector.h
Normal file
55
src/selector.h
Normal file
@@ -0,0 +1,55 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2006 by Massimiliano Torromeo *
|
||||
* massimiliano.torromeo@gmail.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef SELECTOR_H_
|
||||
#define SELECTOR_H_
|
||||
|
||||
#include <string>
|
||||
#include "gmenu2x.h"
|
||||
#include "utilities.h"
|
||||
|
||||
#define SELECTOR_ELEMENTS 11
|
||||
|
||||
class LinkApp;
|
||||
class FileLister;
|
||||
|
||||
using std::string;
|
||||
using std::vector;
|
||||
|
||||
class Selector {
|
||||
private:
|
||||
int selRow;
|
||||
GMenu2X *gmenu2x;
|
||||
LinkApp *link;
|
||||
|
||||
hash_map<string, string> aliases;
|
||||
void loadAliases();
|
||||
string getAlias(string key);
|
||||
void prepare(FileLister *fl, vector<string> *screens, vector<string> *titles);
|
||||
void freeScreenshots(vector<string> *screens);
|
||||
|
||||
public:
|
||||
string file, dir;
|
||||
Selector(GMenu2X *gmenu2x, LinkApp *link, string selectorDir="");
|
||||
|
||||
int exec(int startSelection=0);
|
||||
};
|
||||
|
||||
#endif /*SELECTOR_H_*/
|
||||
47
src/selectordetector.cpp
Normal file
47
src/selectordetector.cpp
Normal file
@@ -0,0 +1,47 @@
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
#include "selectordetector.h"
|
||||
#include "utilities.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
SelectorDetector::SelectorDetector() {
|
||||
//ctor
|
||||
useSelectorBackground = false;
|
||||
}
|
||||
|
||||
SelectorDetector::SelectorDetector(string config) {
|
||||
useSelectorBackground = false;
|
||||
readSelectorConfig(config);
|
||||
}
|
||||
|
||||
SelectorDetector::~SelectorDetector() {
|
||||
//dtor
|
||||
}
|
||||
|
||||
bool SelectorDetector::readSelectorConfig(string config) {
|
||||
if (fileExists(config)) {
|
||||
ifstream inf(config.c_str(), ios_base::in);
|
||||
if (inf.is_open()) {
|
||||
string line;
|
||||
while (getline(inf, line, '\n')) {
|
||||
string::size_type pos = line.find("=");
|
||||
string name = trim(line.substr(0,pos));
|
||||
string value = trim(line.substr(pos+1,line.length()));
|
||||
|
||||
if (name=="cmdLine") application = value;
|
||||
else if (name=="baseDir") filePath = value;
|
||||
else if (name=="fileFilter"){
|
||||
if(filters.empty())
|
||||
filters = value;
|
||||
else
|
||||
filters += ("," + value);
|
||||
}
|
||||
}
|
||||
inf.close();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
58
src/selectordetector.h
Normal file
58
src/selectordetector.h
Normal file
@@ -0,0 +1,58 @@
|
||||
#ifndef SELECTORDETECTOR_H
|
||||
#define SELECTORDETECTOR_H
|
||||
|
||||
/* This class is for handling applications that use Kounch's Selector, to correctly import their settings to GMenu
|
||||
* It provides interfaces to examine the dge file to detect Selector and from there, parse the config files.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
#Selector configuration file
|
||||
#Version 1.0
|
||||
|
||||
#selector-language english (and it doesn't work, crap)
|
||||
langCode=EN // ignore
|
||||
layoutCode=0 // ignore
|
||||
|
||||
selectRectangle=2 // ignore
|
||||
|
||||
#Full path to skin files
|
||||
skinPath=./ // use possibly
|
||||
|
||||
#command line
|
||||
cmdLine=./race // USE
|
||||
|
||||
#path to base directory for file explorer
|
||||
baseDir=/boot/local/gmenu2x/roms/ngpc/ // USE
|
||||
|
||||
#File filters // USE
|
||||
fileFilter=ngp
|
||||
fileFilter=ngc
|
||||
fileFilter=npc
|
||||
*/
|
||||
#include <string>
|
||||
|
||||
using std::string;
|
||||
class SelectorDetector
|
||||
{
|
||||
public:
|
||||
SelectorDetector();
|
||||
SelectorDetector(string config);
|
||||
~SelectorDetector();
|
||||
|
||||
bool readSelectorConfig(string config);
|
||||
|
||||
string getApplication(){return application;}
|
||||
string getFilePath(){return filePath;}
|
||||
string getFilters(){return filters;}
|
||||
|
||||
private:
|
||||
bool useSelectorBackground;
|
||||
string application;
|
||||
string filePath;
|
||||
string filters;
|
||||
//bool isSelectorGPE(string gpe);
|
||||
//string getSelectorConfig(string gpe); // Looks in the GPE for the location of the selectorconfig
|
||||
};
|
||||
|
||||
#endif // SELECTORDETECTOR_H
|
||||
140
src/settingsdialog.cpp
Normal file
140
src/settingsdialog.cpp
Normal file
@@ -0,0 +1,140 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2006 by Massimiliano Torromeo *
|
||||
* massimiliano.torromeo@gmail.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#include <SDL.h>
|
||||
#include <SDL_gfxPrimitives.h>
|
||||
|
||||
#include "settingsdialog.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
SettingsDialog::SettingsDialog(GMenu2X *gmenu2x, string text, string icon) {
|
||||
this->gmenu2x = gmenu2x;
|
||||
this->text = text;
|
||||
|
||||
if (icon!="" && gmenu2x->sc[icon] != NULL)
|
||||
this->icon = icon;
|
||||
else
|
||||
this->icon = "icons/generic.png";
|
||||
}
|
||||
|
||||
SettingsDialog::~SettingsDialog() {
|
||||
for (uint i=0; i<voices.size(); i++)
|
||||
free(voices[i]);
|
||||
}
|
||||
|
||||
bool SettingsDialog::exec() {
|
||||
//Surface bg (gmenu2x->confStr["wallpaper"],false);
|
||||
Surface bg(gmenu2x->bg);
|
||||
|
||||
bool close = false, ts_pressed = false;
|
||||
uint i, sel = 0, iY, firstElement = 0, action;
|
||||
voices[sel]->adjustInput();
|
||||
|
||||
SDL_Rect clipRect = {0, gmenu2x->skinConfInt["topBarHeight"]+1, gmenu2x->resX-9, gmenu2x->resY-gmenu2x->skinConfInt["topBarHeight"]-25};
|
||||
SDL_Rect touchRect = {2, gmenu2x->skinConfInt["topBarHeight"]+4, gmenu2x->resX-12, clipRect.h};
|
||||
uint rowHeight = gmenu2x->font->getHeight()+1; // gp2x=15+1 / pandora=19+1
|
||||
uint numRows = (gmenu2x->resY-gmenu2x->skinConfInt["topBarHeight"]-20)/rowHeight;
|
||||
|
||||
while (!close) {
|
||||
action = SD_NO_ACTION;
|
||||
if (gmenu2x->f200) gmenu2x->ts.poll();
|
||||
|
||||
bg.blit(gmenu2x->s,0,0);
|
||||
|
||||
gmenu2x->drawTopBar(gmenu2x->s);
|
||||
//link icon
|
||||
gmenu2x->drawTitleIcon(icon);
|
||||
gmenu2x->writeTitle(text);
|
||||
gmenu2x->drawBottomBar(gmenu2x->s);
|
||||
|
||||
if (sel>firstElement+numRows-1) firstElement=sel-numRows+1;
|
||||
if (sel<firstElement) firstElement=sel;
|
||||
|
||||
//selection
|
||||
iY = sel-firstElement;
|
||||
iY = gmenu2x->skinConfInt["topBarHeight"]+2+(iY*rowHeight);
|
||||
gmenu2x->s->setClipRect(clipRect);
|
||||
if (sel<voices.size())
|
||||
gmenu2x->s->box(1, iY, 148, rowHeight-2, gmenu2x->skinConfColors["selectionBg"]);
|
||||
gmenu2x->s->clearClipRect();
|
||||
|
||||
//selected option
|
||||
voices[sel]->drawSelected(iY);
|
||||
|
||||
gmenu2x->s->setClipRect(clipRect);
|
||||
if (ts_pressed && !gmenu2x->ts.pressed()) ts_pressed = false;
|
||||
if (gmenu2x->f200 && gmenu2x->ts.pressed() && !gmenu2x->ts.inRect(touchRect)) ts_pressed = false;
|
||||
for (i=firstElement; i<voices.size() && i<firstElement+numRows; i++) {
|
||||
iY = i-firstElement;
|
||||
voices[i]->draw(iY*rowHeight+gmenu2x->skinConfInt["topBarHeight"]+2);
|
||||
if (gmenu2x->f200 && gmenu2x->ts.pressed() && gmenu2x->ts.inRect(touchRect.x, touchRect.y+(iY*rowHeight), touchRect.w, rowHeight)) {
|
||||
ts_pressed = true;
|
||||
sel = i;
|
||||
}
|
||||
}
|
||||
gmenu2x->s->clearClipRect();
|
||||
|
||||
gmenu2x->drawScrollBar(numRows,voices.size(),firstElement,clipRect.y+1,clipRect.h);
|
||||
|
||||
//description
|
||||
gmenu2x->writeSubTitle(voices[sel]->description);
|
||||
|
||||
gmenu2x->s->flip();
|
||||
voices[sel]->handleTS();
|
||||
|
||||
gmenu2x->input.update();
|
||||
if ( gmenu2x->input[ACTION_START] ) action = SD_ACTION_CLOSE;
|
||||
if ( gmenu2x->input[ACTION_UP ] ) action = SD_ACTION_UP;
|
||||
if ( gmenu2x->input[ACTION_DOWN ] ) action = SD_ACTION_DOWN;
|
||||
voices[sel]->manageInput();
|
||||
|
||||
switch (action) {
|
||||
case SD_ACTION_CLOSE: close = true; break;
|
||||
case SD_ACTION_UP: {
|
||||
if (sel==0)
|
||||
sel = voices.size()-1;
|
||||
else
|
||||
sel -= 1;
|
||||
gmenu2x->setInputSpeed();
|
||||
voices[sel]->adjustInput();
|
||||
} break;
|
||||
case SD_ACTION_DOWN: {
|
||||
sel += 1;
|
||||
if (sel>=voices.size()) sel = 0;
|
||||
gmenu2x->setInputSpeed();
|
||||
voices[sel]->adjustInput();
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
gmenu2x->setInputSpeed();
|
||||
return true;
|
||||
}
|
||||
|
||||
void SettingsDialog::addSetting(MenuSetting* set) {
|
||||
voices.push_back(set);
|
||||
}
|
||||
|
||||
bool SettingsDialog::edited() {
|
||||
for (uint i=0; i<voices.size(); i++)
|
||||
if (voices[i]->edited()) return true;
|
||||
return false;
|
||||
}
|
||||
51
src/settingsdialog.h
Normal file
51
src/settingsdialog.h
Normal file
@@ -0,0 +1,51 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2006 by Massimiliano Torromeo *
|
||||
* massimiliano.torromeo@gmail.com *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef SETTINGSDIALOG_H_
|
||||
#define SETTINGSDIALOG_H_
|
||||
|
||||
#define SD_NO_ACTION 0
|
||||
#define SD_ACTION_CLOSE 1
|
||||
#define SD_ACTION_UP 2
|
||||
#define SD_ACTION_DOWN 3
|
||||
|
||||
#include <string>
|
||||
#include "gmenu2x.h"
|
||||
#include "menusetting.h"
|
||||
|
||||
using std::string;
|
||||
using std::vector;
|
||||
|
||||
class SettingsDialog {
|
||||
private:
|
||||
vector<MenuSetting *> voices;
|
||||
string text, icon;
|
||||
GMenu2X *gmenu2x;
|
||||
|
||||
public:
|
||||
SettingsDialog(GMenu2X *gmenu2x, string text, string icon="skin:sections/settings.png");
|
||||
~SettingsDialog();
|
||||
|
||||
bool edited();
|
||||
bool exec();
|
||||
void addSetting(MenuSetting* set);
|
||||
};
|
||||
|
||||
#endif /*INPUTDIALOG_H_*/
|
||||
196
src/sfontplus.cpp
Normal file
196
src/sfontplus.cpp
Normal file
@@ -0,0 +1,196 @@
|
||||
#include "sfontplus.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <SDL_image.h>
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
Uint32 SFontPlus::getPixel(Sint32 x, Sint32 y) {
|
||||
assert(x>=0);
|
||||
assert(x<surface->w);
|
||||
|
||||
Uint32 Bpp = surface->format->BytesPerPixel;
|
||||
|
||||
// Get the pixel
|
||||
switch(Bpp) {
|
||||
case 1:
|
||||
return *((Uint8 *)surface->pixels + y * surface->pitch + x);
|
||||
break;
|
||||
case 2:
|
||||
return *((Uint16 *)surface->pixels + y * surface->pitch/2 + x);
|
||||
break;
|
||||
case 3: { // Format/endian independent
|
||||
Uint8 *bits = ((Uint8 *)surface->pixels)+y*surface->pitch+x*Bpp;
|
||||
Uint8 r, g, b;
|
||||
r = *((bits)+surface->format->Rshift/8);
|
||||
g = *((bits)+surface->format->Gshift/8);
|
||||
b = *((bits)+surface->format->Bshift/8);
|
||||
return SDL_MapRGB(surface->format, r, g, b);
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
return *((Uint32 *)surface->pixels + y * surface->pitch/4 + x);
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
SFontPlus::SFontPlus() {
|
||||
surface = NULL;
|
||||
}
|
||||
|
||||
SFontPlus::SFontPlus(SDL_Surface* font) {
|
||||
surface = NULL;
|
||||
initFont(font);
|
||||
}
|
||||
|
||||
SFontPlus::SFontPlus(string font) {
|
||||
surface = NULL;
|
||||
initFont(font);
|
||||
}
|
||||
|
||||
SFontPlus::~SFontPlus() {
|
||||
freeFont();
|
||||
}
|
||||
|
||||
bool SFontPlus::utf8Code(unsigned char c) {
|
||||
return (c>=194 && c<=198) || c==208 || c==209;
|
||||
//return c>=194;
|
||||
}
|
||||
|
||||
void SFontPlus::initFont(string font, string characters) {
|
||||
SDL_Surface *buf = IMG_Load(font.c_str());
|
||||
if (buf!=NULL) {
|
||||
initFont( SDL_DisplayFormatAlpha(buf), characters );
|
||||
SDL_FreeSurface(buf);
|
||||
}
|
||||
}
|
||||
|
||||
void SFontPlus::initFont(SDL_Surface *font, string characters) {
|
||||
freeFont();
|
||||
this->characters = characters;
|
||||
if (font==NULL) return;
|
||||
|
||||
surface = font;
|
||||
Uint32 pink = SDL_MapRGB(surface->format, 255,0,255);
|
||||
|
||||
#ifdef _DEBUG
|
||||
bool utf8 = false;
|
||||
for (uint x=0; x<characters.length(); x++) {
|
||||
if (!utf8) utf8 = (unsigned char)characters[x]>128;
|
||||
if (utf8) printf("%d\n", (unsigned char)characters[x]);
|
||||
}
|
||||
#endif
|
||||
|
||||
uint c = 0;
|
||||
|
||||
SDL_LockSurface(surface);
|
||||
for (uint x=0; x<(uint)surface->w && c<characters.length(); x++) {
|
||||
if (getPixel(x,0) == pink) {
|
||||
uint startx = x;
|
||||
charpos.push_back(x);
|
||||
|
||||
x++;
|
||||
while (x<(uint)surface->w && getPixel(x,0) == pink) x++;
|
||||
charpos.push_back(x);
|
||||
|
||||
//utf8 characters
|
||||
if (c>0 && utf8Code(characters[c-1])) {
|
||||
charpos.push_back(startx);
|
||||
charpos.push_back(x);
|
||||
c++;
|
||||
}
|
||||
|
||||
c++;
|
||||
}
|
||||
}
|
||||
SDL_UnlockSurface(surface);
|
||||
Uint32 colKey = getPixel(0,surface->h-1);
|
||||
SDL_SetColorKey(surface, SDL_SRCCOLORKEY, colKey);
|
||||
|
||||
string::size_type pos = characters.find("0")*2;
|
||||
SDL_Rect srcrect = {charpos[pos], 1, charpos[pos+2] - charpos[pos], surface->h-1};
|
||||
uint y = srcrect.h+1;
|
||||
bool nonKeyFound = false;
|
||||
while (y-->0 && !nonKeyFound) {
|
||||
uint x = srcrect.w+1;
|
||||
while (x-->0 && !nonKeyFound)
|
||||
nonKeyFound = getPixel(x+srcrect.x,y+srcrect.y) != colKey;
|
||||
}
|
||||
lineHeight = y+1;
|
||||
}
|
||||
|
||||
void SFontPlus::freeFont() {
|
||||
if (surface!=NULL) {
|
||||
SDL_FreeSurface(surface);
|
||||
surface = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void SFontPlus::write(SDL_Surface *s, string text, int x, int y) {
|
||||
if (text.empty()) return;
|
||||
|
||||
string::size_type pos;
|
||||
SDL_Rect srcrect, dstrect;
|
||||
|
||||
// these values won't change in the loop
|
||||
srcrect.y = 1;
|
||||
dstrect.y = y;
|
||||
srcrect.h = dstrect.h = surface->h-1;
|
||||
|
||||
for(uint i=0; i<text.length() && x<surface->w; i++) {
|
||||
//Utf8 characters
|
||||
if (utf8Code(text[i]) && i+1<text.length()) {
|
||||
pos = characters.find(text.substr(i,2));
|
||||
i++;
|
||||
} else
|
||||
pos = characters.find(text[i]);
|
||||
if (pos == string::npos) {
|
||||
x += charpos[2]-charpos[1];
|
||||
continue;
|
||||
}
|
||||
|
||||
pos *= 2;
|
||||
|
||||
srcrect.x = charpos[pos];
|
||||
srcrect.w = charpos[pos+2] - charpos[pos];
|
||||
dstrect.x = x - charpos[pos+1] + charpos[pos];
|
||||
|
||||
SDL_BlitSurface(surface, &srcrect, s, &dstrect);
|
||||
|
||||
x += charpos[pos+2] - charpos[pos+1];
|
||||
}
|
||||
}
|
||||
|
||||
uint SFontPlus::getTextWidth(string text) {
|
||||
string::size_type pos;
|
||||
int width = 0;
|
||||
|
||||
for(uint x=0; x<text.length(); x++) {
|
||||
//Utf8 characters
|
||||
if (utf8Code(text[x]) && x+1<text.length()) {
|
||||
pos = characters.find(text.substr(x,2));
|
||||
x++;
|
||||
} else
|
||||
pos = characters.find(text[x]);
|
||||
if (pos == string::npos) {
|
||||
width += charpos[2]-charpos[1];
|
||||
continue;
|
||||
}
|
||||
|
||||
pos *= 2;
|
||||
width += charpos[pos+2] - charpos[pos+1];
|
||||
}
|
||||
|
||||
return width;
|
||||
}
|
||||
|
||||
uint SFontPlus::getHeight() {
|
||||
return surface->h - 1;
|
||||
}
|
||||
|
||||
uint SFontPlus::getLineHeight() {
|
||||
return lineHeight;
|
||||
}
|
||||
43
src/sfontplus.h
Normal file
43
src/sfontplus.h
Normal file
@@ -0,0 +1,43 @@
|
||||
#ifndef SFONTPLUS_H
|
||||
#define SFONTPLUS_H
|
||||
|
||||
#include <SDL.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#define SFONTPLUS_CHARSET "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~¡¿ÀÁÈÉÌÍÒÓÙÚÝÄËÏÖÜŸÂÊÎÔÛÅÃÕÑÆÇČĎĚĽĹŇÔŘŔŠŤŮŽàáèéìíòóùúýäëïöüÿâêîôûåãõñæçčďěľĺňôřŕšťžůðßÐÞþАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдеёжзийклмнопрстуфхцчшщъыьэюяØøąćęłńśżźĄĆĘŁŃŚŻŹ"
|
||||
#ifdef _WIN32
|
||||
typedef unsigned int uint;
|
||||
#endif
|
||||
using std::vector;
|
||||
using std::string;
|
||||
|
||||
class SFontPlus {
|
||||
private:
|
||||
Uint32 getPixel(Sint32 x, Sint32 y);
|
||||
|
||||
SDL_Surface *surface;
|
||||
vector<uint> charpos;
|
||||
string characters;
|
||||
uint height, lineHeight;
|
||||
|
||||
public:
|
||||
SFontPlus();
|
||||
SFontPlus(SDL_Surface *font);
|
||||
SFontPlus(string font);
|
||||
~SFontPlus();
|
||||
|
||||
bool utf8Code(unsigned char c);
|
||||
|
||||
void initFont(SDL_Surface *font, string characters = SFONTPLUS_CHARSET);
|
||||
void initFont(string font, string characters = SFONTPLUS_CHARSET);
|
||||
void freeFont();
|
||||
|
||||
void write(SDL_Surface *s, string text, int x, int y);
|
||||
|
||||
uint getTextWidth(string text);
|
||||
uint getHeight();
|
||||
uint getLineHeight();
|
||||
};
|
||||
|
||||
#endif /* SFONTPLUS_H */
|
||||
2
src/sparsehash-1.6/AUTHORS
Normal file
2
src/sparsehash-1.6/AUTHORS
Normal file
@@ -0,0 +1,2 @@
|
||||
opensource@google.com
|
||||
|
||||
28
src/sparsehash-1.6/COPYING
Normal file
28
src/sparsehash-1.6/COPYING
Normal file
@@ -0,0 +1,28 @@
|
||||
Copyright (c) 2005, Google Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of Google Inc. nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
182
src/sparsehash-1.6/ChangeLog
Normal file
182
src/sparsehash-1.6/ChangeLog
Normal file
@@ -0,0 +1,182 @@
|
||||
Fri Jan 8 14:47:55 2010 Google Inc. <opensource@google.com>
|
||||
|
||||
* sparsehash: version 1.6 release
|
||||
* New accessor methods for deleted_key, empty_key (sjackman)
|
||||
* Use explicit hash functions in sparsehash tests (csilvers)
|
||||
* BUGFIX: Cast resize to fix SUNWspro bug (csilvers)
|
||||
* Check for sz overflow in min_size (csilvers)
|
||||
* Speed up clear() for dense and sparse hashtables (jeff)
|
||||
* Avoid shrinking in all cases when min-load is 0 (shaunj, csilvers)
|
||||
* Improve densehashtable code for the deleted key (gpike)
|
||||
* BUGFIX: Fix operator= when the 2 empty-keys differ (andreidam)
|
||||
* BUGFIX: Fix ht copying when empty-key isn't set (andreidam)
|
||||
* PORTING: Use TmpFile() instead of /tmp on MinGW (csilvers)
|
||||
* PORTING: Use filenames that work with Stratus VOS.
|
||||
|
||||
Tue May 12 14:16:38 2009 Google Inc. <opensource@google.com>
|
||||
|
||||
* sparsehash: version 1.5.2 release
|
||||
* Fix compile error: not initializing set_key in all constructors
|
||||
|
||||
Fri May 8 15:23:44 2009 Google Inc. <opensource@google.com>
|
||||
|
||||
* sparsehash: version 1.5.1 release
|
||||
* Fix broken equal_range() for all the hash-classes (csilvers)
|
||||
|
||||
Wed May 6 11:28:49 2009 Google Inc. <opensource@google.com>
|
||||
|
||||
* sparsehash: version 1.5 release
|
||||
* Support the tr1 unordered_map (and unordered_set) API (csilvers)
|
||||
* Store only key for delkey; reduces need for 0-arg c-tor (csilvers)
|
||||
* Prefer unordered_map to hash_map for the timing test (csilvers)
|
||||
* PORTING: update the resource use for 64-bit machines (csilvers)
|
||||
* PORTING: fix MIN/MAX collisions by un-#including windows.h (csilvers)
|
||||
* Updated autoconf version to 2.61 and libtool version to 1.5.26
|
||||
|
||||
Wed Jan 28 17:11:31 2009 Google Inc. <opensource@google.com>
|
||||
|
||||
* sparsehash: version 1.4 release
|
||||
* Allow hashtables to be <32 buckets (csilvers)
|
||||
* Fix initial-sizing bug: was sizing tables too small (csilvers)
|
||||
* Add asserts that clients don't abuse deleted/empty key (csilvers)
|
||||
* Improve determination of 32/64 bit for C code (csilvers)
|
||||
* Small fix for doc files in rpm (csilvers)
|
||||
|
||||
Thu Nov 6 15:06:09 2008 Google Inc. <opensource@google.com>
|
||||
|
||||
* sparsehash: version 1.3 release
|
||||
* Add an interface to change the parameters for resizing (myl)
|
||||
* Document another potentially good hash function (csilvers)
|
||||
|
||||
Thu Sep 18 13:53:20 2008 Google Inc. <opensource@google.com>
|
||||
|
||||
* sparsehash: version 1.2 release
|
||||
* Augment documentation to better describe namespace issues (csilvers)
|
||||
* BUG FIX: replace hash<> with SPARSEHASH_HASH, for windows (csilvers)
|
||||
* Add timing test to unittest to test repeated add+delete (csilvers)
|
||||
* Do better picking a new size when resizing (csilvers)
|
||||
* Use ::google instead of google as a namespace (csilvers)
|
||||
* Improve threading test at config time (csilvers)
|
||||
|
||||
Mon Feb 11 16:30:11 2008 Google Inc. <opensource@google.com>
|
||||
|
||||
* sparsehash: version 1.1 release
|
||||
* Fix brown-paper-bag bug in some constructors (rafferty)
|
||||
* Fix problem with variables shadowing member vars, add -Wshadow
|
||||
|
||||
Thu Nov 29 11:44:38 2007 Google Inc. <opensource@google.com>
|
||||
|
||||
* sparsehash: version 1.0.2 release
|
||||
* Fix a final reference to hash<> to use SPARSEHASH_HASH<> instead.
|
||||
|
||||
Wed Nov 14 08:47:48 2007 Google Inc. <opensource@google.com>
|
||||
|
||||
* sparsehash: version 1.0.1 release :-(
|
||||
* Remove an unnecessary (harmful) "#define hash" in windows' config.h
|
||||
|
||||
Tue Nov 13 15:15:46 2007 Google Inc. <opensource@google.com>
|
||||
|
||||
* sparsehash: version 1.0 release! We are now out of beta.
|
||||
* Clean up Makefile awk script to be more readable (csilvers)
|
||||
* Namespace fixes: use fewer #defines, move typedefs into namespace
|
||||
|
||||
Fri Oct 12 12:35:24 2007 Google Inc. <opensource@google.com>
|
||||
|
||||
* sparsehash: version 0.9.1 release
|
||||
* Fix Makefile awk script to work on more architectures (csilvers)
|
||||
* Add test to test code in more 'real life' situations (csilvers)
|
||||
|
||||
Tue Oct 9 14:15:21 2007 Google Inc. <opensource@google.com>
|
||||
|
||||
* sparsehash: version 0.9 release
|
||||
* More type-hygiene improvements, especially for 64-bit (csilvers)
|
||||
* Some configure improvements to improve portability, utility (austern)
|
||||
* Small bugfix for operator== for dense_hash_map (jeff)
|
||||
|
||||
Tue Jul 3 12:55:04 2007 Google Inc. <opensource@google.com>
|
||||
|
||||
* sparsehash: version 0.8 release
|
||||
* Minor type-hygiene improvements: size_t for int, etc. (csilvers)
|
||||
* Porting improvements: tests pass on OS X, FreeBSD, Solaris (csilvers)
|
||||
* Full windows port! VS solution provided for all unittests (csilvers)
|
||||
|
||||
Mon Jun 11 11:33:41 2007 Google Inc. <opensource@google.com>
|
||||
|
||||
* sparsehash: version 0.7 release
|
||||
* Syntax fixes to better support gcc 4.3 and VC++ 7 (mec, csilvers)
|
||||
* Improved windows/VC++ support (see README.windows) (csilvers)
|
||||
* Config improvements: better tcmalloc support and config.h (csilvers)
|
||||
* More robust with missing hash_map + nix 'trampoline' .h's (csilvers)
|
||||
* Support for STLport's hash_map/hash_fun locations (csilvers)
|
||||
* Add .m4 files to distribution; now all source is there (csilvers)
|
||||
* Tiny modification of shrink-threshhold to allow never-shrinking (amc)
|
||||
* Protect timing tests against aggressive optimizers (csilvers)
|
||||
* Extend time_hash_map to test bigger objects (csilvers)
|
||||
* Extend type-trait support to work with const objects (csilvers)
|
||||
* USER VISIBLE: speed up all code by replacing memmove with memcpy
|
||||
(csilvers)
|
||||
|
||||
Tue Mar 20 17:29:34 2007 Google Inc. <opensource@google.com>
|
||||
|
||||
* sparsehash: version 0.6 release
|
||||
* Some improvement to type-traits (jyasskin)
|
||||
* Better timing results when google-perftools is installed (sanjay)
|
||||
* Updates and fixes to html documentation and README (csilvers)
|
||||
* A bit more careful about #includes (csilvers)
|
||||
* Fix for typo that broken compilation on some systems (csilvers)
|
||||
* USER VISIBLE: New clear_no_resize() method added to dense_hash_map
|
||||
(uszkoreit)
|
||||
|
||||
Sat Oct 21 13:47:47 2006 Google Inc. <opensource@google.com>
|
||||
|
||||
* sparsehash: version 0.5 release
|
||||
* Support uint16_t (SunOS) in addition to u_int16_t (BSD) (csilvers)
|
||||
* Get rid of UNDERSTANDS_ITERATOR_TAGS; everyone understands (csilvers)
|
||||
* Test that empty-key and deleted-key differ (rbayardo)
|
||||
* Fix example docs: strcmp needs to test for NULL (csilvers)
|
||||
|
||||
Sun Apr 23 22:42:35 2006 Google Inc. <opensource@google.com>
|
||||
|
||||
* sparsehash: version 0.4 release
|
||||
* Remove POD requirement for keys and values! (austern)
|
||||
* Add tr1-compatible type-traits system to speed up POD ops. (austern)
|
||||
* Fixed const-iterator bug where postfix ++ didn't compile. (csilvers)
|
||||
* Fixed iterator comparison bugs where <= was incorrect. (csilvers)
|
||||
* Clean up config.h to keep its #defines from conflicting. (csilvers)
|
||||
* Big documentation sweep and cleanup. (csilvers)
|
||||
* Update documentation to talk more about good hash fns. (csilvers)
|
||||
* Fixes to compile on MSVC (working around some MSVC bugs). (rennie)
|
||||
* Avoid resizing hashtable on operator[] lookups (austern)
|
||||
|
||||
Thu Nov 3 20:12:31 2005 Google Inc. <opensource@google.com>
|
||||
|
||||
* sparsehash: version 0.3 release
|
||||
* Quiet compiler warnings on some compilers. (csilvers)
|
||||
* Some documentation fixes: example code for dense_hash_map. (csilvers)
|
||||
* Fix a bug where swap() wasn't swapping delete_key(). (csilvers)
|
||||
* set_deleted_key() and set_empty_key() now take a key only,
|
||||
allowing hash-map values to be forward-declared. (csilvers)
|
||||
* support for std::insert_iterator (and std::inserter). (csilvers)
|
||||
|
||||
Mon May 2 07:04:46 2005 Google Inc. <opensource@google.com>
|
||||
|
||||
* sparsehash: version 0.2 release
|
||||
* Preliminary support for msvc++ compilation. (csilvers)
|
||||
* Documentation fixes -- some example code was incomplete! (csilvers)
|
||||
* Minimize size of config.h to avoid other-package conflicts (csilvers)
|
||||
* Contribute a C-based version of sparsehash that served as the
|
||||
inspiration for this code. One day, I hope to clean it up and
|
||||
support it, but for now it's just in experimental/, for playing
|
||||
around with. (csilvers)
|
||||
* Change default namespace from std to google. (csilvers)
|
||||
|
||||
Fri Jan 14 16:53:32 2005 Google Inc. <opensource@google.com>
|
||||
|
||||
* sparsehash: initial release:
|
||||
The sparsehash package contains several hash-map implementations,
|
||||
similar in API to SGI's hash_map class, but with different
|
||||
performance characteristics. sparse_hash_map uses very little
|
||||
space overhead: 1-2 bits per entry. dense_hash_map is typically
|
||||
faster than the default SGI STL implementation. This package
|
||||
also includes hash-set analogues of these classes.
|
||||
|
||||
236
src/sparsehash-1.6/INSTALL
Normal file
236
src/sparsehash-1.6/INSTALL
Normal file
@@ -0,0 +1,236 @@
|
||||
Installation Instructions
|
||||
*************************
|
||||
|
||||
Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005 Free
|
||||
Software Foundation, Inc.
|
||||
|
||||
This file is free documentation; the Free Software Foundation gives
|
||||
unlimited permission to copy, distribute and modify it.
|
||||
|
||||
Basic Installation
|
||||
==================
|
||||
|
||||
These are generic installation instructions.
|
||||
|
||||
The `configure' shell script attempts to guess correct values for
|
||||
various system-dependent variables used during compilation. It uses
|
||||
those values to create a `Makefile' in each directory of the package.
|
||||
It may also create one or more `.h' files containing system-dependent
|
||||
definitions. Finally, it creates a shell script `config.status' that
|
||||
you can run in the future to recreate the current configuration, and a
|
||||
file `config.log' containing compiler output (useful mainly for
|
||||
debugging `configure').
|
||||
|
||||
It can also use an optional file (typically called `config.cache'
|
||||
and enabled with `--cache-file=config.cache' or simply `-C') that saves
|
||||
the results of its tests to speed up reconfiguring. (Caching is
|
||||
disabled by default to prevent problems with accidental use of stale
|
||||
cache files.)
|
||||
|
||||
If you need to do unusual things to compile the package, please try
|
||||
to figure out how `configure' could check whether to do them, and mail
|
||||
diffs or instructions to the address given in the `README' so they can
|
||||
be considered for the next release. If you are using the cache, and at
|
||||
some point `config.cache' contains results you don't want to keep, you
|
||||
may remove or edit it.
|
||||
|
||||
The file `configure.ac' (or `configure.in') is used to create
|
||||
`configure' by a program called `autoconf'. You only need
|
||||
`configure.ac' if you want to change it or regenerate `configure' using
|
||||
a newer version of `autoconf'.
|
||||
|
||||
The simplest way to compile this package is:
|
||||
|
||||
1. `cd' to the directory containing the package's source code and type
|
||||
`./configure' to configure the package for your system. If you're
|
||||
using `csh' on an old version of System V, you might need to type
|
||||
`sh ./configure' instead to prevent `csh' from trying to execute
|
||||
`configure' itself.
|
||||
|
||||
Running `configure' takes awhile. While running, it prints some
|
||||
messages telling which features it is checking for.
|
||||
|
||||
2. Type `make' to compile the package.
|
||||
|
||||
3. Optionally, type `make check' to run any self-tests that come with
|
||||
the package.
|
||||
|
||||
4. Type `make install' to install the programs and any data files and
|
||||
documentation.
|
||||
|
||||
5. You can remove the program binaries and object files from the
|
||||
source code directory by typing `make clean'. To also remove the
|
||||
files that `configure' created (so you can compile the package for
|
||||
a different kind of computer), type `make distclean'. There is
|
||||
also a `make maintainer-clean' target, but that is intended mainly
|
||||
for the package's developers. If you use it, you may have to get
|
||||
all sorts of other programs in order to regenerate files that came
|
||||
with the distribution.
|
||||
|
||||
Compilers and Options
|
||||
=====================
|
||||
|
||||
Some systems require unusual options for compilation or linking that the
|
||||
`configure' script does not know about. Run `./configure --help' for
|
||||
details on some of the pertinent environment variables.
|
||||
|
||||
You can give `configure' initial values for configuration parameters
|
||||
by setting variables in the command line or in the environment. Here
|
||||
is an example:
|
||||
|
||||
./configure CC=c89 CFLAGS=-O2 LIBS=-lposix
|
||||
|
||||
*Note Defining Variables::, for more details.
|
||||
|
||||
Compiling For Multiple Architectures
|
||||
====================================
|
||||
|
||||
You can compile the package for more than one kind of computer at the
|
||||
same time, by placing the object files for each architecture in their
|
||||
own directory. To do this, you must use a version of `make' that
|
||||
supports the `VPATH' variable, such as GNU `make'. `cd' to the
|
||||
directory where you want the object files and executables to go and run
|
||||
the `configure' script. `configure' automatically checks for the
|
||||
source code in the directory that `configure' is in and in `..'.
|
||||
|
||||
If you have to use a `make' that does not support the `VPATH'
|
||||
variable, you have to compile the package for one architecture at a
|
||||
time in the source code directory. After you have installed the
|
||||
package for one architecture, use `make distclean' before reconfiguring
|
||||
for another architecture.
|
||||
|
||||
Installation Names
|
||||
==================
|
||||
|
||||
By default, `make install' installs the package's commands under
|
||||
`/usr/local/bin', include files under `/usr/local/include', etc. You
|
||||
can specify an installation prefix other than `/usr/local' by giving
|
||||
`configure' the option `--prefix=PREFIX'.
|
||||
|
||||
You can specify separate installation prefixes for
|
||||
architecture-specific files and architecture-independent files. If you
|
||||
pass the option `--exec-prefix=PREFIX' to `configure', the package uses
|
||||
PREFIX as the prefix for installing programs and libraries.
|
||||
Documentation and other data files still use the regular prefix.
|
||||
|
||||
In addition, if you use an unusual directory layout you can give
|
||||
options like `--bindir=DIR' to specify different values for particular
|
||||
kinds of files. Run `configure --help' for a list of the directories
|
||||
you can set and what kinds of files go in them.
|
||||
|
||||
If the package supports it, you can cause programs to be installed
|
||||
with an extra prefix or suffix on their names by giving `configure' the
|
||||
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
|
||||
|
||||
Optional Features
|
||||
=================
|
||||
|
||||
Some packages pay attention to `--enable-FEATURE' options to
|
||||
`configure', where FEATURE indicates an optional part of the package.
|
||||
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
|
||||
is something like `gnu-as' or `x' (for the X Window System). The
|
||||
`README' should mention any `--enable-' and `--with-' options that the
|
||||
package recognizes.
|
||||
|
||||
For packages that use the X Window System, `configure' can usually
|
||||
find the X include and library files automatically, but if it doesn't,
|
||||
you can use the `configure' options `--x-includes=DIR' and
|
||||
`--x-libraries=DIR' to specify their locations.
|
||||
|
||||
Specifying the System Type
|
||||
==========================
|
||||
|
||||
There may be some features `configure' cannot figure out automatically,
|
||||
but needs to determine by the type of machine the package will run on.
|
||||
Usually, assuming the package is built to be run on the _same_
|
||||
architectures, `configure' can figure that out, but if it prints a
|
||||
message saying it cannot guess the machine type, give it the
|
||||
`--build=TYPE' option. TYPE can either be a short name for the system
|
||||
type, such as `sun4', or a canonical name which has the form:
|
||||
|
||||
CPU-COMPANY-SYSTEM
|
||||
|
||||
where SYSTEM can have one of these forms:
|
||||
|
||||
OS KERNEL-OS
|
||||
|
||||
See the file `config.sub' for the possible values of each field. If
|
||||
`config.sub' isn't included in this package, then this package doesn't
|
||||
need to know the machine type.
|
||||
|
||||
If you are _building_ compiler tools for cross-compiling, you should
|
||||
use the option `--target=TYPE' to select the type of system they will
|
||||
produce code for.
|
||||
|
||||
If you want to _use_ a cross compiler, that generates code for a
|
||||
platform different from the build platform, you should specify the
|
||||
"host" platform (i.e., that on which the generated programs will
|
||||
eventually be run) with `--host=TYPE'.
|
||||
|
||||
Sharing Defaults
|
||||
================
|
||||
|
||||
If you want to set default values for `configure' scripts to share, you
|
||||
can create a site shell script called `config.site' that gives default
|
||||
values for variables like `CC', `cache_file', and `prefix'.
|
||||
`configure' looks for `PREFIX/share/config.site' if it exists, then
|
||||
`PREFIX/etc/config.site' if it exists. Or, you can set the
|
||||
`CONFIG_SITE' environment variable to the location of the site script.
|
||||
A warning: not all `configure' scripts look for a site script.
|
||||
|
||||
Defining Variables
|
||||
==================
|
||||
|
||||
Variables not defined in a site shell script can be set in the
|
||||
environment passed to `configure'. However, some packages may run
|
||||
configure again during the build, and the customized values of these
|
||||
variables may be lost. In order to avoid this problem, you should set
|
||||
them in the `configure' command line, using `VAR=value'. For example:
|
||||
|
||||
./configure CC=/usr/local2/bin/gcc
|
||||
|
||||
causes the specified `gcc' to be used as the C compiler (unless it is
|
||||
overridden in the site shell script). Here is a another example:
|
||||
|
||||
/bin/bash ./configure CONFIG_SHELL=/bin/bash
|
||||
|
||||
Here the `CONFIG_SHELL=/bin/bash' operand causes subsequent
|
||||
configuration-related scripts to be executed by `/bin/bash'.
|
||||
|
||||
`configure' Invocation
|
||||
======================
|
||||
|
||||
`configure' recognizes the following options to control how it operates.
|
||||
|
||||
`--help'
|
||||
`-h'
|
||||
Print a summary of the options to `configure', and exit.
|
||||
|
||||
`--version'
|
||||
`-V'
|
||||
Print the version of Autoconf used to generate the `configure'
|
||||
script, and exit.
|
||||
|
||||
`--cache-file=FILE'
|
||||
Enable the cache: use and save the results of the tests in FILE,
|
||||
traditionally `config.cache'. FILE defaults to `/dev/null' to
|
||||
disable caching.
|
||||
|
||||
`--config-cache'
|
||||
`-C'
|
||||
Alias for `--cache-file=config.cache'.
|
||||
|
||||
`--quiet'
|
||||
`--silent'
|
||||
`-q'
|
||||
Do not print messages saying which checks are being made. To
|
||||
suppress all normal output, redirect it to `/dev/null' (any error
|
||||
messages will still be shown).
|
||||
|
||||
`--srcdir=DIR'
|
||||
Look for the package's source code in directory DIR. Usually
|
||||
`configure' can determine that directory automatically.
|
||||
|
||||
`configure' also accepts some other, not widely useful, options. Run
|
||||
`configure --help' for more details.
|
||||
|
||||
157
src/sparsehash-1.6/Makefile.am
Normal file
157
src/sparsehash-1.6/Makefile.am
Normal file
@@ -0,0 +1,157 @@
|
||||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
# Make sure that when we re-make ./configure, we get the macros we need
|
||||
ACLOCAL_AMFLAGS = -I m4
|
||||
|
||||
# This is so we can #include <google/foo>
|
||||
AM_CPPFLAGS = -I$(top_srcdir)/src
|
||||
|
||||
# These are good warnings to turn on by default
|
||||
if GCC
|
||||
AM_CXXFLAGS = -Wall -Wwrite-strings -Woverloaded-virtual -Wno-sign-compare -Wshadow
|
||||
endif
|
||||
|
||||
googleincludedir = $(includedir)/google
|
||||
## The .h files you want to install (that is, .h files that people
|
||||
## who install this package can include in their own applications.)
|
||||
googleinclude_HEADERS = \
|
||||
src/google/dense_hash_map \
|
||||
src/google/dense_hash_set \
|
||||
src/google/sparse_hash_map \
|
||||
src/google/sparse_hash_set \
|
||||
src/google/sparsetable \
|
||||
src/google/type_traits.h
|
||||
|
||||
docdir = $(prefix)/share/doc/$(PACKAGE)-$(VERSION)
|
||||
## This is for HTML and other documentation you want to install.
|
||||
## Add your documentation files (in doc/) in addition to these boilerplate
|
||||
## Also add a TODO file if you have one
|
||||
dist_doc_DATA = AUTHORS COPYING ChangeLog INSTALL NEWS README README.windows \
|
||||
TODO \
|
||||
doc/dense_hash_map.html \
|
||||
doc/dense_hash_set.html \
|
||||
doc/sparse_hash_map.html \
|
||||
doc/sparse_hash_set.html \
|
||||
doc/sparsetable.html \
|
||||
doc/implementation.html \
|
||||
doc/performance.html \
|
||||
doc/index.html \
|
||||
doc/designstyle.css
|
||||
|
||||
## The libraries (.so's) you want to install
|
||||
lib_LTLIBRARIES =
|
||||
## The location of the windows project file for each binary we make
|
||||
WINDOWS_PROJECTS = google-sparsehash.sln
|
||||
|
||||
## unittests you want to run when people type 'make check'.
|
||||
## TESTS is for binary unittests, check_SCRIPTS for script-based unittests.
|
||||
## TESTS_ENVIRONMENT sets environment variables for when you run unittest,
|
||||
## but it only seems to take effect for *binary* unittests (argh!)
|
||||
TESTS = type_traits_unittest sparsetable_unittest hashtable_unittest \
|
||||
simple_test
|
||||
# TODO(csilvers): get simple_test working on windows
|
||||
WINDOWS_PROJECTS += vsprojects/type_traits_unittest/type_traits_unittest.vcproj \
|
||||
vsprojects/sparsetable_unittest/sparsetable_unittest.vcproj \
|
||||
vsprojects/hashtable_unittest/hashtable_unittest.vcproj
|
||||
check_SCRIPTS =
|
||||
TESTS_ENVIRONMENT =
|
||||
|
||||
## This should always include $(TESTS), but may also include other
|
||||
## binaries that you compile but don't want automatically installed.
|
||||
noinst_PROGRAMS = $(TESTS) time_hash_map
|
||||
WINDOWS_PROJECTS += vsprojects/time_hash_map/time_hash_map.vcproj
|
||||
|
||||
|
||||
## vvvv RULES TO MAKE THE LIBRARIES, BINARIES, AND UNITTESTS
|
||||
|
||||
# All our .h files need to read the config information in config.h. The
|
||||
# autoheader config.h has too much info, including PACKAGENAME, that
|
||||
# might conflict with other config.h's an application might #include.
|
||||
# Thus, we create a "minimal" config.h, called sparseconfig.h, that
|
||||
# includes only the #defines we really need, and that are unlikely to
|
||||
# change from system to system. NOTE: The awk command is equivalent to
|
||||
# fgrep -B2 -f- $(top_builddir)/src/config.h \
|
||||
# fgrep -vx -e -- > _sparsehash_config
|
||||
# For correctness, it depends on the fact config.h.include does not have
|
||||
# any lines starting with #.
|
||||
src/google/sparsehash/sparseconfig.h: $(top_builddir)/src/config.h \
|
||||
$(top_srcdir)/src/config.h.include
|
||||
[ -d $(@D) ] || mkdir -p $(@D)
|
||||
echo "/*" > $(@D)/_sparsehash_config
|
||||
echo " * NOTE: This file is for internal use only." >> $(@D)/_sparsehash_config
|
||||
echo " * Do not use these #defines in your own program!" >> $(@D)/_sparsehash_config
|
||||
echo " */" >> $(@D)/_sparsehash_config
|
||||
$(AWK) '{prevline=currline; currline=$$0;} \
|
||||
/^#/ {in_second_file = 1;} \
|
||||
!in_second_file {if (currline !~ /^ *$$/) {inc[currline]=0}}; \
|
||||
in_second_file { for (i in inc) { \
|
||||
if (index(currline, i) != 0) { \
|
||||
print "\n"prevline"\n"currline; \
|
||||
delete inc[i]; \
|
||||
} \
|
||||
} }' \
|
||||
$(top_srcdir)/src/config.h.include $(top_builddir)/src/config.h \
|
||||
>> $(@D)/_sparsehash_config
|
||||
mv -f $(@D)/_sparsehash_config $@
|
||||
# This is how we tell automake about auto-generated .h files
|
||||
BUILT_SOURCES = src/google/sparsehash/sparseconfig.h
|
||||
CLEANFILES = src/google/sparsehash/sparseconfig.h
|
||||
|
||||
sparsehashincludedir = $(googleincludedir)/sparsehash
|
||||
sparsehashinclude_HEADERS = \
|
||||
src/google/sparsehash/densehashtable.h \
|
||||
src/google/sparsehash/sparsehashtable.h
|
||||
nodist_sparsehashinclude_HEADERS = src/google/sparsehash/sparseconfig.h
|
||||
|
||||
type_traits_unittest_SOURCES = \
|
||||
src/type_traits_unittest.cc \
|
||||
$(sparsehashinclude_HEADERS) \
|
||||
src/google/type_traits.h
|
||||
nodist_type_traits_unittest_SOURCES = $(nodist_sparsehashinclude_HEADERS)
|
||||
|
||||
sparsetable_unittest_SOURCES = \
|
||||
src/sparsetable_unittest.cc \
|
||||
$(sparsehashinclude_HEADERS) \
|
||||
src/google/sparsetable
|
||||
nodist_sparsetable_unittest_SOURCES = $(nodist_sparsehashinclude_HEADERS)
|
||||
|
||||
hashtable_unittest_SOURCES = \
|
||||
src/hashtable_unittest.cc \
|
||||
$(googleinclude_HEADERS) \
|
||||
$(sparsehashinclude_HEADERS) \
|
||||
src/words
|
||||
nodist_hashtable_unittest_SOURCES = $(nodist_sparsehashinclude_HEADERS)
|
||||
|
||||
simple_test_SOURCES = \
|
||||
src/simple_test.cc \
|
||||
$(sparsehashinclude_HEADERS)
|
||||
nodist_simple_test_SOURCES = $(nodist_sparsehashinclude_HEADERS)
|
||||
|
||||
time_hash_map_SOURCES = \
|
||||
src/time_hash_map.cc \
|
||||
$(sparsehashinclude_HEADERS) \
|
||||
$(googleinclude_HEADERS)
|
||||
nodist_time_hash_map_SOURCES = $(nodist_sparsehashinclude_HEADERS)
|
||||
|
||||
# If tcmalloc is installed, use it with time_hash_map; it gives us
|
||||
# heap-usage statistics for the hash_map routines, which is very nice
|
||||
time_hash_map_CXXFLAGS = @tcmalloc_flags@ $(AM_CXXFLAGS)
|
||||
time_hash_map_LDFLAGS = @tcmalloc_flags@
|
||||
time_hash_map_LDADD = @tcmalloc_libs@
|
||||
|
||||
## ^^^^ END OF RULES TO MAKE THE LIBRARIES, BINARIES, AND UNITTESTS
|
||||
|
||||
|
||||
rpm: dist-gzip packages/rpm.sh packages/rpm/rpm.spec
|
||||
@cd packages && ./rpm.sh ${PACKAGE} ${VERSION}
|
||||
|
||||
deb: dist-gzip packages/deb.sh packages/deb/*
|
||||
@cd packages && ./deb.sh ${PACKAGE} ${VERSION}
|
||||
|
||||
# Windows wants write permission to .vcproj files and maybe even sln files.
|
||||
dist-hook:
|
||||
test -e "$(distdir)/vsprojects" \
|
||||
&& chmod -R u+w $(distdir)/*.sln $(distdir)/vsprojects/
|
||||
|
||||
EXTRA_DIST = packages/rpm.sh packages/rpm/rpm.spec packages/deb.sh packages/deb \
|
||||
src/config.h.include src/windows $(WINDOWS_PROJECTS) experimental
|
||||
0
src/sparsehash-1.6/NEWS
Normal file
0
src/sparsehash-1.6/NEWS
Normal file
149
src/sparsehash-1.6/README
Normal file
149
src/sparsehash-1.6/README
Normal file
@@ -0,0 +1,149 @@
|
||||
This directory contains several hash-map implementations, similar in
|
||||
API to SGI's hash_map class, but with different performance
|
||||
characteristics. sparse_hash_map uses very little space overhead, 1-2
|
||||
bits per entry. dense_hash_map is very fast, particulary on lookup.
|
||||
(sparse_hash_set and dense_hash_set are the set versions of these
|
||||
routines.) On the other hand, these classes have requirements that
|
||||
may not make them appropriate for all applications.
|
||||
|
||||
All these implementation use a hashtable with internal quadratic
|
||||
probing. This method is space-efficient -- there is no pointer
|
||||
overhead -- and time-efficient for good hash functions.
|
||||
|
||||
COMPILING
|
||||
---------
|
||||
To compile test applications with these classes, run ./configure
|
||||
followed by make. To install these header files on your system, run
|
||||
'make install'. (On Windows, the instructions are different; see
|
||||
README.windows.) See INSTALL for more details.
|
||||
|
||||
This code should work on any modern C++ system. It has been tested on
|
||||
Linux (Ubuntu, Fedora, RedHat, Debian), Solaris 10 x86, FreeBSD 6.0,
|
||||
OS X 10.3 and 10.4, and Windows under both VC++7 and VC++8.
|
||||
|
||||
USING
|
||||
-----
|
||||
See the html files in the doc directory for small example programs
|
||||
that use these classes. It's enough to just include the header file:
|
||||
|
||||
#include <google/sparse_hash_map> // or sparse_hash_set, dense_hash_map, ...
|
||||
google::sparse_hash_set<int, int> number_mapper;
|
||||
|
||||
and use the class the way you would other hash-map implementations.
|
||||
(Though see "API" below for caveats.)
|
||||
|
||||
By default (you can change it via a flag to ./configure), these hash
|
||||
implementations are defined in the google namespace.
|
||||
|
||||
API
|
||||
---
|
||||
The API for sparse_hash_map, dense_hash_map, sparse_hash_set, and
|
||||
dense_hash_set, are a superset of the API of SGI's hash_map class.
|
||||
See doc/sparse_hash_map.html, et al., for more information about the
|
||||
API.
|
||||
|
||||
The usage of these classes differ from SGI's hash_map, and other
|
||||
hashtable implementations, in the following major ways:
|
||||
|
||||
1) dense_hash_map requires you to set aside one key value as the
|
||||
'empty bucket' value, set via the set_empty_key() method. This
|
||||
*MUST* be called before you can use the dense_hash_map. It is
|
||||
illegal to insert any elements into a dense_hash_map whose key is
|
||||
equal to the empty-key.
|
||||
|
||||
2) For both dense_hash_map and sparse_hash_map, if you wish to delete
|
||||
elements from the hashtable, you must set aside a key value as the
|
||||
'deleted bucket' value, set via the set_deleted_key() method. If
|
||||
your hash-map is insert-only, there is no need to call this
|
||||
method. If you call set_deleted_key(), it is illegal to insert any
|
||||
elements into a dense_hash_map or sparse_hash_map whose key is
|
||||
equal to the deleted-key.
|
||||
|
||||
3) These hash-map implementation support I/O. See below.
|
||||
|
||||
There are also some smaller differences:
|
||||
|
||||
1) The constructor takes an optional argument that specifies the
|
||||
number of elements you expect to insert into the hashtable. This
|
||||
differs from SGI's hash_map implementation, which takes an optional
|
||||
number of buckets.
|
||||
|
||||
2) erase() does not immediately reclaim memory. As a consequence,
|
||||
erase() does not invalidate any iterators, making loops like this
|
||||
correct:
|
||||
for (it = ht.begin(); it != ht.end(); ++it)
|
||||
if (...) ht.erase(it);
|
||||
As another consequence, a series of erase() calls can leave your
|
||||
hashtable using more memory than it needs to. The hashtable will
|
||||
automatically compact() at the next call to insert(), but to
|
||||
manually compact a hashtable, you can call
|
||||
ht.resize(0)
|
||||
|
||||
3) While sparse_hash_map et al. accept an Allocator template argument,
|
||||
they ignore it. They use malloc() and free() for all memory
|
||||
allocations.
|
||||
|
||||
4) sparse_hash_map et al. do not use exceptions.
|
||||
|
||||
I/O
|
||||
---
|
||||
In addition to the normal hash-map operations, sparse_hash_map can
|
||||
read and write hashtables to disk. (dense_hash_map also has the API,
|
||||
but it has not yet been implemented, and writes will always fail.)
|
||||
|
||||
In the simplest case, writing a hashtable is as easy as calling two
|
||||
methods on the hashtable:
|
||||
ht.write_metadata(fp);
|
||||
ht.write_nopointer_data(fp);
|
||||
|
||||
Reading in this data is equally simple:
|
||||
google::sparse_hash_map<...> ht;
|
||||
ht.read_metadata(fp);
|
||||
ht.read_nopointer_data(fp);
|
||||
|
||||
The above is sufficient if the key and value do not contain any
|
||||
pointers: they are basic C types or agglomorations of basic C types.
|
||||
If the key and/or value do contain pointers, you can still store the
|
||||
hashtable by replacing write_nopointer_data() with a custom writing
|
||||
routine. See sparse_hash_map.html et al. for more information.
|
||||
|
||||
SPARSETABLE
|
||||
-----------
|
||||
In addition to the hash-map and hash-set classes, this package also
|
||||
provides sparsetable.h, an array implementation that uses space
|
||||
proportional to the number of elements in the array, rather than the
|
||||
maximum element index. It uses very little space overhead: 1 bit per
|
||||
entry. See doc/sparsetable.html for the API.
|
||||
|
||||
RESOURCE USAGE
|
||||
--------------
|
||||
* sparse_hash_map has memory overhead of about 2 bits per hash-map
|
||||
entry.
|
||||
* dense_hash_map has a factor of 2-3 memory overhead: if your
|
||||
hashtable data takes X bytes, dense_hash_map will use 3X-4X memory
|
||||
total.
|
||||
|
||||
Hashtables tend to double in size when resizing, creating an
|
||||
additional 50% space overhead. dense_hash_map does in fact have a
|
||||
significant "high water mark" memory use requirement.
|
||||
sparse_hash_map, however, is written to need very little space
|
||||
overhead when resizing: only a few bits per hashtable entry.
|
||||
|
||||
PERFORMANCE
|
||||
-----------
|
||||
You can compile and run the included file time_hash_map.cc to examine
|
||||
the performance of sparse_hash_map, dense_hash_map, and your native
|
||||
hash_map implementation on your system. One test against the
|
||||
SGI hash_map implementation gave the following timing information for
|
||||
a simple find() call:
|
||||
SGI hash_map: 22 ns
|
||||
dense_hash_map: 13 ns
|
||||
sparse_hash_map: 117 ns
|
||||
SGI map: 113 ns
|
||||
|
||||
See doc/performance.html for more detailed charts on resource usage
|
||||
and performance data.
|
||||
|
||||
---
|
||||
16 March 2005
|
||||
(Last updated: 20 March 2007)
|
||||
28
src/sparsehash-1.6/TODO
Normal file
28
src/sparsehash-1.6/TODO
Normal file
@@ -0,0 +1,28 @@
|
||||
1) TODO: I/O implementation in densehashtable.h
|
||||
|
||||
2) TODO: document SPARSEHASH_STAT_UPDATE macro, and also macros that
|
||||
tweak performance. Perhaps add support to these to the API?
|
||||
|
||||
3) TODO: support exceptions?
|
||||
|
||||
4) BUG: sparsetable's operator[] doesn't work well with printf: you
|
||||
need to explicitly cast the result to value_type to print it. (It
|
||||
works fine with streams.)
|
||||
|
||||
5) TODO: consider rewriting dense_hash_map to use a 'groups' scheme,
|
||||
like sparsetable, but without the sparse-allocation within a
|
||||
group. This makes resizing have better memory-use properties. The
|
||||
downside is that probes across groups might take longer since
|
||||
groups are not contiguous in memory. Making groups the same size
|
||||
as a cache-line, and ensuring they're loaded on cache-line
|
||||
boundaries, might help. Needs careful testing to make sure it
|
||||
doesn't hurt performance.
|
||||
|
||||
6) TODO: Get the C-only version of sparsehash in experimental/ ready
|
||||
for prime-time.
|
||||
|
||||
7) TODO: use cmake (www.cmake.org) to make it easy to isntall this on
|
||||
a windows system.
|
||||
|
||||
---
|
||||
28 February 2007
|
||||
868
src/sparsehash-1.6/aclocal.m4
vendored
Normal file
868
src/sparsehash-1.6/aclocal.m4
vendored
Normal file
@@ -0,0 +1,868 @@
|
||||
# generated automatically by aclocal 1.9.6 -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
|
||||
# 2005 Free Software Foundation, Inc.
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE.
|
||||
|
||||
# Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# AM_AUTOMAKE_VERSION(VERSION)
|
||||
# ----------------------------
|
||||
# Automake X.Y traces this macro to ensure aclocal.m4 has been
|
||||
# generated from the m4 files accompanying Automake X.Y.
|
||||
AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version="1.9"])
|
||||
|
||||
# AM_SET_CURRENT_AUTOMAKE_VERSION
|
||||
# -------------------------------
|
||||
# Call AM_AUTOMAKE_VERSION so it can be traced.
|
||||
# This function is AC_REQUIREd by AC_INIT_AUTOMAKE.
|
||||
AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
|
||||
[AM_AUTOMAKE_VERSION([1.9.6])])
|
||||
|
||||
# AM_AUX_DIR_EXPAND -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
|
||||
# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to
|
||||
# `$srcdir', `$srcdir/..', or `$srcdir/../..'.
|
||||
#
|
||||
# Of course, Automake must honor this variable whenever it calls a
|
||||
# tool from the auxiliary directory. The problem is that $srcdir (and
|
||||
# therefore $ac_aux_dir as well) can be either absolute or relative,
|
||||
# depending on how configure is run. This is pretty annoying, since
|
||||
# it makes $ac_aux_dir quite unusable in subdirectories: in the top
|
||||
# source directory, any form will work fine, but in subdirectories a
|
||||
# relative path needs to be adjusted first.
|
||||
#
|
||||
# $ac_aux_dir/missing
|
||||
# fails when called from a subdirectory if $ac_aux_dir is relative
|
||||
# $top_srcdir/$ac_aux_dir/missing
|
||||
# fails if $ac_aux_dir is absolute,
|
||||
# fails when called from a subdirectory in a VPATH build with
|
||||
# a relative $ac_aux_dir
|
||||
#
|
||||
# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
|
||||
# are both prefixed by $srcdir. In an in-source build this is usually
|
||||
# harmless because $srcdir is `.', but things will broke when you
|
||||
# start a VPATH build or use an absolute $srcdir.
|
||||
#
|
||||
# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
|
||||
# iff we strip the leading $srcdir from $ac_aux_dir. That would be:
|
||||
# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
|
||||
# and then we would define $MISSING as
|
||||
# MISSING="\${SHELL} $am_aux_dir/missing"
|
||||
# This will work as long as MISSING is not called from configure, because
|
||||
# unfortunately $(top_srcdir) has no meaning in configure.
|
||||
# However there are other variables, like CC, which are often used in
|
||||
# configure, and could therefore not use this "fixed" $ac_aux_dir.
|
||||
#
|
||||
# Another solution, used here, is to always expand $ac_aux_dir to an
|
||||
# absolute PATH. The drawback is that using absolute paths prevent a
|
||||
# configured tree to be moved without reconfiguration.
|
||||
|
||||
AC_DEFUN([AM_AUX_DIR_EXPAND],
|
||||
[dnl Rely on autoconf to set up CDPATH properly.
|
||||
AC_PREREQ([2.50])dnl
|
||||
# expand $ac_aux_dir to an absolute path
|
||||
am_aux_dir=`cd $ac_aux_dir && pwd`
|
||||
])
|
||||
|
||||
# AM_CONDITIONAL -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005
|
||||
# Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# serial 7
|
||||
|
||||
# AM_CONDITIONAL(NAME, SHELL-CONDITION)
|
||||
# -------------------------------------
|
||||
# Define a conditional.
|
||||
AC_DEFUN([AM_CONDITIONAL],
|
||||
[AC_PREREQ(2.52)dnl
|
||||
ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])],
|
||||
[$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
|
||||
AC_SUBST([$1_TRUE])
|
||||
AC_SUBST([$1_FALSE])
|
||||
if $2; then
|
||||
$1_TRUE=
|
||||
$1_FALSE='#'
|
||||
else
|
||||
$1_TRUE='#'
|
||||
$1_FALSE=
|
||||
fi
|
||||
AC_CONFIG_COMMANDS_PRE(
|
||||
[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
|
||||
AC_MSG_ERROR([[conditional "$1" was never defined.
|
||||
Usually this means the macro was only invoked conditionally.]])
|
||||
fi])])
|
||||
|
||||
|
||||
# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||
# Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# serial 8
|
||||
|
||||
# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
|
||||
# written in clear, in which case automake, when reading aclocal.m4,
|
||||
# will think it sees a *use*, and therefore will trigger all it's
|
||||
# C support machinery. Also note that it means that autoscan, seeing
|
||||
# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
|
||||
|
||||
|
||||
# _AM_DEPENDENCIES(NAME)
|
||||
# ----------------------
|
||||
# See how the compiler implements dependency checking.
|
||||
# NAME is "CC", "CXX", "GCJ", or "OBJC".
|
||||
# We try a few techniques and use that to set a single cache variable.
|
||||
#
|
||||
# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was
|
||||
# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular
|
||||
# dependency, and given that the user is not expected to run this macro,
|
||||
# just rely on AC_PROG_CC.
|
||||
AC_DEFUN([_AM_DEPENDENCIES],
|
||||
[AC_REQUIRE([AM_SET_DEPDIR])dnl
|
||||
AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl
|
||||
AC_REQUIRE([AM_MAKE_INCLUDE])dnl
|
||||
AC_REQUIRE([AM_DEP_TRACK])dnl
|
||||
|
||||
ifelse([$1], CC, [depcc="$CC" am_compiler_list=],
|
||||
[$1], CXX, [depcc="$CXX" am_compiler_list=],
|
||||
[$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
|
||||
[$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'],
|
||||
[depcc="$$1" am_compiler_list=])
|
||||
|
||||
AC_CACHE_CHECK([dependency style of $depcc],
|
||||
[am_cv_$1_dependencies_compiler_type],
|
||||
[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
|
||||
# We make a subdir and do the tests there. Otherwise we can end up
|
||||
# making bogus files that we don't know about and never remove. For
|
||||
# instance it was reported that on HP-UX the gcc test will end up
|
||||
# making a dummy file named `D' -- because `-MD' means `put the output
|
||||
# in D'.
|
||||
mkdir conftest.dir
|
||||
# Copy depcomp to subdir because otherwise we won't find it if we're
|
||||
# using a relative directory.
|
||||
cp "$am_depcomp" conftest.dir
|
||||
cd conftest.dir
|
||||
# We will build objects and dependencies in a subdirectory because
|
||||
# it helps to detect inapplicable dependency modes. For instance
|
||||
# both Tru64's cc and ICC support -MD to output dependencies as a
|
||||
# side effect of compilation, but ICC will put the dependencies in
|
||||
# the current directory while Tru64 will put them in the object
|
||||
# directory.
|
||||
mkdir sub
|
||||
|
||||
am_cv_$1_dependencies_compiler_type=none
|
||||
if test "$am_compiler_list" = ""; then
|
||||
am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp`
|
||||
fi
|
||||
for depmode in $am_compiler_list; do
|
||||
# Setup a source with many dependencies, because some compilers
|
||||
# like to wrap large dependency lists on column 80 (with \), and
|
||||
# we should not choose a depcomp mode which is confused by this.
|
||||
#
|
||||
# We need to recreate these files for each test, as the compiler may
|
||||
# overwrite some of them when testing with obscure command lines.
|
||||
# This happens at least with the AIX C compiler.
|
||||
: > sub/conftest.c
|
||||
for i in 1 2 3 4 5 6; do
|
||||
echo '#include "conftst'$i'.h"' >> sub/conftest.c
|
||||
# Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
|
||||
# Solaris 8's {/usr,}/bin/sh.
|
||||
touch sub/conftst$i.h
|
||||
done
|
||||
echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
|
||||
|
||||
case $depmode in
|
||||
nosideeffect)
|
||||
# after this tag, mechanisms are not by side-effect, so they'll
|
||||
# only be used when explicitly requested
|
||||
if test "x$enable_dependency_tracking" = xyes; then
|
||||
continue
|
||||
else
|
||||
break
|
||||
fi
|
||||
;;
|
||||
none) break ;;
|
||||
esac
|
||||
# We check with `-c' and `-o' for the sake of the "dashmstdout"
|
||||
# mode. It turns out that the SunPro C++ compiler does not properly
|
||||
# handle `-M -o', and we need to detect this.
|
||||
if depmode=$depmode \
|
||||
source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \
|
||||
depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
|
||||
$SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \
|
||||
>/dev/null 2>conftest.err &&
|
||||
grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
|
||||
grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 &&
|
||||
${MAKE-make} -s -f confmf > /dev/null 2>&1; then
|
||||
# icc doesn't choke on unknown options, it will just issue warnings
|
||||
# or remarks (even with -Werror). So we grep stderr for any message
|
||||
# that says an option was ignored or not supported.
|
||||
# When given -MP, icc 7.0 and 7.1 complain thusly:
|
||||
# icc: Command line warning: ignoring option '-M'; no argument required
|
||||
# The diagnosis changed in icc 8.0:
|
||||
# icc: Command line remark: option '-MP' not supported
|
||||
if (grep 'ignoring option' conftest.err ||
|
||||
grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
|
||||
am_cv_$1_dependencies_compiler_type=$depmode
|
||||
break
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
cd ..
|
||||
rm -rf conftest.dir
|
||||
else
|
||||
am_cv_$1_dependencies_compiler_type=none
|
||||
fi
|
||||
])
|
||||
AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type])
|
||||
AM_CONDITIONAL([am__fastdep$1], [
|
||||
test "x$enable_dependency_tracking" != xno \
|
||||
&& test "$am_cv_$1_dependencies_compiler_type" = gcc3])
|
||||
])
|
||||
|
||||
|
||||
# AM_SET_DEPDIR
|
||||
# -------------
|
||||
# Choose a directory name for dependency files.
|
||||
# This macro is AC_REQUIREd in _AM_DEPENDENCIES
|
||||
AC_DEFUN([AM_SET_DEPDIR],
|
||||
[AC_REQUIRE([AM_SET_LEADING_DOT])dnl
|
||||
AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl
|
||||
])
|
||||
|
||||
|
||||
# AM_DEP_TRACK
|
||||
# ------------
|
||||
AC_DEFUN([AM_DEP_TRACK],
|
||||
[AC_ARG_ENABLE(dependency-tracking,
|
||||
[ --disable-dependency-tracking speeds up one-time build
|
||||
--enable-dependency-tracking do not reject slow dependency extractors])
|
||||
if test "x$enable_dependency_tracking" != xno; then
|
||||
am_depcomp="$ac_aux_dir/depcomp"
|
||||
AMDEPBACKSLASH='\'
|
||||
fi
|
||||
AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
|
||||
AC_SUBST([AMDEPBACKSLASH])
|
||||
])
|
||||
|
||||
# Generate code to set up dependency tracking. -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||
# Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
#serial 3
|
||||
|
||||
# _AM_OUTPUT_DEPENDENCY_COMMANDS
|
||||
# ------------------------------
|
||||
AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
|
||||
[for mf in $CONFIG_FILES; do
|
||||
# Strip MF so we end up with the name of the file.
|
||||
mf=`echo "$mf" | sed -e 's/:.*$//'`
|
||||
# Check whether this is an Automake generated Makefile or not.
|
||||
# We used to match only the files named `Makefile.in', but
|
||||
# some people rename them; so instead we look at the file content.
|
||||
# Grep'ing the first line is not enough: some people post-process
|
||||
# each Makefile.in and add a new line on top of each file to say so.
|
||||
# So let's grep whole file.
|
||||
if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then
|
||||
dirpart=`AS_DIRNAME("$mf")`
|
||||
else
|
||||
continue
|
||||
fi
|
||||
# Extract the definition of DEPDIR, am__include, and am__quote
|
||||
# from the Makefile without running `make'.
|
||||
DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
|
||||
test -z "$DEPDIR" && continue
|
||||
am__include=`sed -n 's/^am__include = //p' < "$mf"`
|
||||
test -z "am__include" && continue
|
||||
am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
|
||||
# When using ansi2knr, U may be empty or an underscore; expand it
|
||||
U=`sed -n 's/^U = //p' < "$mf"`
|
||||
# Find all dependency output files, they are included files with
|
||||
# $(DEPDIR) in their names. We invoke sed twice because it is the
|
||||
# simplest approach to changing $(DEPDIR) to its actual value in the
|
||||
# expansion.
|
||||
for file in `sed -n "
|
||||
s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
|
||||
sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
|
||||
# Make sure the directory exists.
|
||||
test -f "$dirpart/$file" && continue
|
||||
fdir=`AS_DIRNAME(["$file"])`
|
||||
AS_MKDIR_P([$dirpart/$fdir])
|
||||
# echo "creating $dirpart/$file"
|
||||
echo '# dummy' > "$dirpart/$file"
|
||||
done
|
||||
done
|
||||
])# _AM_OUTPUT_DEPENDENCY_COMMANDS
|
||||
|
||||
|
||||
# AM_OUTPUT_DEPENDENCY_COMMANDS
|
||||
# -----------------------------
|
||||
# This macro should only be invoked once -- use via AC_REQUIRE.
|
||||
#
|
||||
# This code is only required when automatic dependency tracking
|
||||
# is enabled. FIXME. This creates each `.P' file that we will
|
||||
# need in order to bootstrap the dependency handling code.
|
||||
AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
|
||||
[AC_CONFIG_COMMANDS([depfiles],
|
||||
[test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
|
||||
[AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
|
||||
])
|
||||
|
||||
# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005
|
||||
# Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# serial 8
|
||||
|
||||
# AM_CONFIG_HEADER is obsolete. It has been replaced by AC_CONFIG_HEADERS.
|
||||
AU_DEFUN([AM_CONFIG_HEADER], [AC_CONFIG_HEADERS($@)])
|
||||
|
||||
# Do all the work for Automake. -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||
# Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# serial 12
|
||||
|
||||
# This macro actually does too much. Some checks are only needed if
|
||||
# your package does certain things. But this isn't really a big deal.
|
||||
|
||||
# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
|
||||
# AM_INIT_AUTOMAKE([OPTIONS])
|
||||
# -----------------------------------------------
|
||||
# The call with PACKAGE and VERSION arguments is the old style
|
||||
# call (pre autoconf-2.50), which is being phased out. PACKAGE
|
||||
# and VERSION should now be passed to AC_INIT and removed from
|
||||
# the call to AM_INIT_AUTOMAKE.
|
||||
# We support both call styles for the transition. After
|
||||
# the next Automake release, Autoconf can make the AC_INIT
|
||||
# arguments mandatory, and then we can depend on a new Autoconf
|
||||
# release and drop the old call support.
|
||||
AC_DEFUN([AM_INIT_AUTOMAKE],
|
||||
[AC_PREREQ([2.58])dnl
|
||||
dnl Autoconf wants to disallow AM_ names. We explicitly allow
|
||||
dnl the ones we care about.
|
||||
m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
|
||||
AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
|
||||
AC_REQUIRE([AC_PROG_INSTALL])dnl
|
||||
# test to see if srcdir already configured
|
||||
if test "`cd $srcdir && pwd`" != "`pwd`" &&
|
||||
test -f $srcdir/config.status; then
|
||||
AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
|
||||
fi
|
||||
|
||||
# test whether we have cygpath
|
||||
if test -z "$CYGPATH_W"; then
|
||||
if (cygpath --version) >/dev/null 2>/dev/null; then
|
||||
CYGPATH_W='cygpath -w'
|
||||
else
|
||||
CYGPATH_W=echo
|
||||
fi
|
||||
fi
|
||||
AC_SUBST([CYGPATH_W])
|
||||
|
||||
# Define the identity of the package.
|
||||
dnl Distinguish between old-style and new-style calls.
|
||||
m4_ifval([$2],
|
||||
[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
|
||||
AC_SUBST([PACKAGE], [$1])dnl
|
||||
AC_SUBST([VERSION], [$2])],
|
||||
[_AM_SET_OPTIONS([$1])dnl
|
||||
AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
|
||||
AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
|
||||
|
||||
_AM_IF_OPTION([no-define],,
|
||||
[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
|
||||
AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl
|
||||
|
||||
# Some tools Automake needs.
|
||||
AC_REQUIRE([AM_SANITY_CHECK])dnl
|
||||
AC_REQUIRE([AC_ARG_PROGRAM])dnl
|
||||
AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version})
|
||||
AM_MISSING_PROG(AUTOCONF, autoconf)
|
||||
AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version})
|
||||
AM_MISSING_PROG(AUTOHEADER, autoheader)
|
||||
AM_MISSING_PROG(MAKEINFO, makeinfo)
|
||||
AM_PROG_INSTALL_SH
|
||||
AM_PROG_INSTALL_STRIP
|
||||
AC_REQUIRE([AM_PROG_MKDIR_P])dnl
|
||||
# We need awk for the "check" target. The system "awk" is bad on
|
||||
# some platforms.
|
||||
AC_REQUIRE([AC_PROG_AWK])dnl
|
||||
AC_REQUIRE([AC_PROG_MAKE_SET])dnl
|
||||
AC_REQUIRE([AM_SET_LEADING_DOT])dnl
|
||||
_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])],
|
||||
[_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])],
|
||||
[_AM_PROG_TAR([v7])])])
|
||||
_AM_IF_OPTION([no-dependencies],,
|
||||
[AC_PROVIDE_IFELSE([AC_PROG_CC],
|
||||
[_AM_DEPENDENCIES(CC)],
|
||||
[define([AC_PROG_CC],
|
||||
defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl
|
||||
AC_PROVIDE_IFELSE([AC_PROG_CXX],
|
||||
[_AM_DEPENDENCIES(CXX)],
|
||||
[define([AC_PROG_CXX],
|
||||
defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl
|
||||
])
|
||||
])
|
||||
|
||||
|
||||
# When config.status generates a header, we must update the stamp-h file.
|
||||
# This file resides in the same directory as the config header
|
||||
# that is generated. The stamp files are numbered to have different names.
|
||||
|
||||
# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
|
||||
# loop where config.status creates the headers, so we can generate
|
||||
# our stamp files there.
|
||||
AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
|
||||
[# Compute $1's index in $config_headers.
|
||||
_am_stamp_count=1
|
||||
for _am_header in $config_headers :; do
|
||||
case $_am_header in
|
||||
$1 | $1:* )
|
||||
break ;;
|
||||
* )
|
||||
_am_stamp_count=`expr $_am_stamp_count + 1` ;;
|
||||
esac
|
||||
done
|
||||
echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count])
|
||||
|
||||
# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# AM_PROG_INSTALL_SH
|
||||
# ------------------
|
||||
# Define $install_sh.
|
||||
AC_DEFUN([AM_PROG_INSTALL_SH],
|
||||
[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
|
||||
install_sh=${install_sh-"$am_aux_dir/install-sh"}
|
||||
AC_SUBST(install_sh)])
|
||||
|
||||
# Copyright (C) 2003, 2005 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# serial 2
|
||||
|
||||
# Check whether the underlying file-system supports filenames
|
||||
# with a leading dot. For instance MS-DOS doesn't.
|
||||
AC_DEFUN([AM_SET_LEADING_DOT],
|
||||
[rm -rf .tst 2>/dev/null
|
||||
mkdir .tst 2>/dev/null
|
||||
if test -d .tst; then
|
||||
am__leading_dot=.
|
||||
else
|
||||
am__leading_dot=_
|
||||
fi
|
||||
rmdir .tst 2>/dev/null
|
||||
AC_SUBST([am__leading_dot])])
|
||||
|
||||
# Check to see how 'make' treats includes. -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# serial 3
|
||||
|
||||
# AM_MAKE_INCLUDE()
|
||||
# -----------------
|
||||
# Check to see how make treats includes.
|
||||
AC_DEFUN([AM_MAKE_INCLUDE],
|
||||
[am_make=${MAKE-make}
|
||||
cat > confinc << 'END'
|
||||
am__doit:
|
||||
@echo done
|
||||
.PHONY: am__doit
|
||||
END
|
||||
# If we don't find an include directive, just comment out the code.
|
||||
AC_MSG_CHECKING([for style of include used by $am_make])
|
||||
am__include="#"
|
||||
am__quote=
|
||||
_am_result=none
|
||||
# First try GNU make style include.
|
||||
echo "include confinc" > confmf
|
||||
# We grep out `Entering directory' and `Leaving directory'
|
||||
# messages which can occur if `w' ends up in MAKEFLAGS.
|
||||
# In particular we don't look at `^make:' because GNU make might
|
||||
# be invoked under some other name (usually "gmake"), in which
|
||||
# case it prints its new name instead of `make'.
|
||||
if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then
|
||||
am__include=include
|
||||
am__quote=
|
||||
_am_result=GNU
|
||||
fi
|
||||
# Now try BSD make style include.
|
||||
if test "$am__include" = "#"; then
|
||||
echo '.include "confinc"' > confmf
|
||||
if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then
|
||||
am__include=.include
|
||||
am__quote="\""
|
||||
_am_result=BSD
|
||||
fi
|
||||
fi
|
||||
AC_SUBST([am__include])
|
||||
AC_SUBST([am__quote])
|
||||
AC_MSG_RESULT([$_am_result])
|
||||
rm -f confinc confmf
|
||||
])
|
||||
|
||||
# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2005
|
||||
# Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# serial 4
|
||||
|
||||
# AM_MISSING_PROG(NAME, PROGRAM)
|
||||
# ------------------------------
|
||||
AC_DEFUN([AM_MISSING_PROG],
|
||||
[AC_REQUIRE([AM_MISSING_HAS_RUN])
|
||||
$1=${$1-"${am_missing_run}$2"}
|
||||
AC_SUBST($1)])
|
||||
|
||||
|
||||
# AM_MISSING_HAS_RUN
|
||||
# ------------------
|
||||
# Define MISSING if not defined so far and test if it supports --run.
|
||||
# If it does, set am_missing_run to use it, otherwise, to nothing.
|
||||
AC_DEFUN([AM_MISSING_HAS_RUN],
|
||||
[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
|
||||
test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing"
|
||||
# Use eval to expand $SHELL
|
||||
if eval "$MISSING --run true"; then
|
||||
am_missing_run="$MISSING --run "
|
||||
else
|
||||
am_missing_run=
|
||||
AC_MSG_WARN([`missing' script is too old or missing])
|
||||
fi
|
||||
])
|
||||
|
||||
# Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# AM_PROG_MKDIR_P
|
||||
# ---------------
|
||||
# Check whether `mkdir -p' is supported, fallback to mkinstalldirs otherwise.
|
||||
#
|
||||
# Automake 1.8 used `mkdir -m 0755 -p --' to ensure that directories
|
||||
# created by `make install' are always world readable, even if the
|
||||
# installer happens to have an overly restrictive umask (e.g. 077).
|
||||
# This was a mistake. There are at least two reasons why we must not
|
||||
# use `-m 0755':
|
||||
# - it causes special bits like SGID to be ignored,
|
||||
# - it may be too restrictive (some setups expect 775 directories).
|
||||
#
|
||||
# Do not use -m 0755 and let people choose whatever they expect by
|
||||
# setting umask.
|
||||
#
|
||||
# We cannot accept any implementation of `mkdir' that recognizes `-p'.
|
||||
# Some implementations (such as Solaris 8's) are not thread-safe: if a
|
||||
# parallel make tries to run `mkdir -p a/b' and `mkdir -p a/c'
|
||||
# concurrently, both version can detect that a/ is missing, but only
|
||||
# one can create it and the other will error out. Consequently we
|
||||
# restrict ourselves to GNU make (using the --version option ensures
|
||||
# this.)
|
||||
AC_DEFUN([AM_PROG_MKDIR_P],
|
||||
[if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then
|
||||
# We used to keeping the `.' as first argument, in order to
|
||||
# allow $(mkdir_p) to be used without argument. As in
|
||||
# $(mkdir_p) $(somedir)
|
||||
# where $(somedir) is conditionally defined. However this is wrong
|
||||
# for two reasons:
|
||||
# 1. if the package is installed by a user who cannot write `.'
|
||||
# make install will fail,
|
||||
# 2. the above comment should most certainly read
|
||||
# $(mkdir_p) $(DESTDIR)$(somedir)
|
||||
# so it does not work when $(somedir) is undefined and
|
||||
# $(DESTDIR) is not.
|
||||
# To support the latter case, we have to write
|
||||
# test -z "$(somedir)" || $(mkdir_p) $(DESTDIR)$(somedir),
|
||||
# so the `.' trick is pointless.
|
||||
mkdir_p='mkdir -p --'
|
||||
else
|
||||
# On NextStep and OpenStep, the `mkdir' command does not
|
||||
# recognize any option. It will interpret all options as
|
||||
# directories to create, and then abort because `.' already
|
||||
# exists.
|
||||
for d in ./-p ./--version;
|
||||
do
|
||||
test -d $d && rmdir $d
|
||||
done
|
||||
# $(mkinstalldirs) is defined by Automake if mkinstalldirs exists.
|
||||
if test -f "$ac_aux_dir/mkinstalldirs"; then
|
||||
mkdir_p='$(mkinstalldirs)'
|
||||
else
|
||||
mkdir_p='$(install_sh) -d'
|
||||
fi
|
||||
fi
|
||||
AC_SUBST([mkdir_p])])
|
||||
|
||||
# Helper functions for option handling. -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# serial 3
|
||||
|
||||
# _AM_MANGLE_OPTION(NAME)
|
||||
# -----------------------
|
||||
AC_DEFUN([_AM_MANGLE_OPTION],
|
||||
[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
|
||||
|
||||
# _AM_SET_OPTION(NAME)
|
||||
# ------------------------------
|
||||
# Set option NAME. Presently that only means defining a flag for this option.
|
||||
AC_DEFUN([_AM_SET_OPTION],
|
||||
[m4_define(_AM_MANGLE_OPTION([$1]), 1)])
|
||||
|
||||
# _AM_SET_OPTIONS(OPTIONS)
|
||||
# ----------------------------------
|
||||
# OPTIONS is a space-separated list of Automake options.
|
||||
AC_DEFUN([_AM_SET_OPTIONS],
|
||||
[AC_FOREACH([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
|
||||
|
||||
# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
|
||||
# -------------------------------------------
|
||||
# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
|
||||
AC_DEFUN([_AM_IF_OPTION],
|
||||
[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
|
||||
|
||||
# Check to make sure that the build environment is sane. -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005
|
||||
# Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# serial 4
|
||||
|
||||
# AM_SANITY_CHECK
|
||||
# ---------------
|
||||
AC_DEFUN([AM_SANITY_CHECK],
|
||||
[AC_MSG_CHECKING([whether build environment is sane])
|
||||
# Just in case
|
||||
sleep 1
|
||||
echo timestamp > conftest.file
|
||||
# Do `set' in a subshell so we don't clobber the current shell's
|
||||
# arguments. Must try -L first in case configure is actually a
|
||||
# symlink; some systems play weird games with the mod time of symlinks
|
||||
# (eg FreeBSD returns the mod time of the symlink's containing
|
||||
# directory).
|
||||
if (
|
||||
set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null`
|
||||
if test "$[*]" = "X"; then
|
||||
# -L didn't work.
|
||||
set X `ls -t $srcdir/configure conftest.file`
|
||||
fi
|
||||
rm -f conftest.file
|
||||
if test "$[*]" != "X $srcdir/configure conftest.file" \
|
||||
&& test "$[*]" != "X conftest.file $srcdir/configure"; then
|
||||
|
||||
# If neither matched, then we have a broken ls. This can happen
|
||||
# if, for instance, CONFIG_SHELL is bash and it inherits a
|
||||
# broken ls alias from the environment. This has actually
|
||||
# happened. Such a system could not be considered "sane".
|
||||
AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
|
||||
alias in your environment])
|
||||
fi
|
||||
|
||||
test "$[2]" = conftest.file
|
||||
)
|
||||
then
|
||||
# Ok.
|
||||
:
|
||||
else
|
||||
AC_MSG_ERROR([newly created file is older than distributed files!
|
||||
Check your system clock])
|
||||
fi
|
||||
AC_MSG_RESULT(yes)])
|
||||
|
||||
# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# AM_PROG_INSTALL_STRIP
|
||||
# ---------------------
|
||||
# One issue with vendor `install' (even GNU) is that you can't
|
||||
# specify the program used to strip binaries. This is especially
|
||||
# annoying in cross-compiling environments, where the build's strip
|
||||
# is unlikely to handle the host's binaries.
|
||||
# Fortunately install-sh will honor a STRIPPROG variable, so we
|
||||
# always use install-sh in `make install-strip', and initialize
|
||||
# STRIPPROG with the value of the STRIP variable (set by the user).
|
||||
AC_DEFUN([AM_PROG_INSTALL_STRIP],
|
||||
[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
|
||||
# Installed binaries are usually stripped using `strip' when the user
|
||||
# run `make install-strip'. However `strip' might not be the right
|
||||
# tool to use in cross-compilation environments, therefore Automake
|
||||
# will honor the `STRIP' environment variable to overrule this program.
|
||||
dnl Don't test for $cross_compiling = yes, because it might be `maybe'.
|
||||
if test "$cross_compiling" != no; then
|
||||
AC_CHECK_TOOL([STRIP], [strip], :)
|
||||
fi
|
||||
INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s"
|
||||
AC_SUBST([INSTALL_STRIP_PROGRAM])])
|
||||
|
||||
# Check how to create a tarball. -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 2004, 2005 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# serial 2
|
||||
|
||||
# _AM_PROG_TAR(FORMAT)
|
||||
# --------------------
|
||||
# Check how to create a tarball in format FORMAT.
|
||||
# FORMAT should be one of `v7', `ustar', or `pax'.
|
||||
#
|
||||
# Substitute a variable $(am__tar) that is a command
|
||||
# writing to stdout a FORMAT-tarball containing the directory
|
||||
# $tardir.
|
||||
# tardir=directory && $(am__tar) > result.tar
|
||||
#
|
||||
# Substitute a variable $(am__untar) that extract such
|
||||
# a tarball read from stdin.
|
||||
# $(am__untar) < result.tar
|
||||
AC_DEFUN([_AM_PROG_TAR],
|
||||
[# Always define AMTAR for backward compatibility.
|
||||
AM_MISSING_PROG([AMTAR], [tar])
|
||||
m4_if([$1], [v7],
|
||||
[am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'],
|
||||
[m4_case([$1], [ustar],, [pax],,
|
||||
[m4_fatal([Unknown tar format])])
|
||||
AC_MSG_CHECKING([how to create a $1 tar archive])
|
||||
# Loop over all known methods to create a tar archive until one works.
|
||||
_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
|
||||
_am_tools=${am_cv_prog_tar_$1-$_am_tools}
|
||||
# Do not fold the above two line into one, because Tru64 sh and
|
||||
# Solaris sh will not grok spaces in the rhs of `-'.
|
||||
for _am_tool in $_am_tools
|
||||
do
|
||||
case $_am_tool in
|
||||
gnutar)
|
||||
for _am_tar in tar gnutar gtar;
|
||||
do
|
||||
AM_RUN_LOG([$_am_tar --version]) && break
|
||||
done
|
||||
am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
|
||||
am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
|
||||
am__untar="$_am_tar -xf -"
|
||||
;;
|
||||
plaintar)
|
||||
# Must skip GNU tar: if it does not support --format= it doesn't create
|
||||
# ustar tarball either.
|
||||
(tar --version) >/dev/null 2>&1 && continue
|
||||
am__tar='tar chf - "$$tardir"'
|
||||
am__tar_='tar chf - "$tardir"'
|
||||
am__untar='tar xf -'
|
||||
;;
|
||||
pax)
|
||||
am__tar='pax -L -x $1 -w "$$tardir"'
|
||||
am__tar_='pax -L -x $1 -w "$tardir"'
|
||||
am__untar='pax -r'
|
||||
;;
|
||||
cpio)
|
||||
am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
|
||||
am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
|
||||
am__untar='cpio -i -H $1 -d'
|
||||
;;
|
||||
none)
|
||||
am__tar=false
|
||||
am__tar_=false
|
||||
am__untar=false
|
||||
;;
|
||||
esac
|
||||
|
||||
# If the value was cached, stop now. We just wanted to have am__tar
|
||||
# and am__untar set.
|
||||
test -n "${am_cv_prog_tar_$1}" && break
|
||||
|
||||
# tar/untar a dummy directory, and stop if the command works
|
||||
rm -rf conftest.dir
|
||||
mkdir conftest.dir
|
||||
echo GrepMe > conftest.dir/file
|
||||
AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
|
||||
rm -rf conftest.dir
|
||||
if test -s conftest.tar; then
|
||||
AM_RUN_LOG([$am__untar <conftest.tar])
|
||||
grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
|
||||
fi
|
||||
done
|
||||
rm -rf conftest.dir
|
||||
|
||||
AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
|
||||
AC_MSG_RESULT([$am_cv_prog_tar_$1])])
|
||||
AC_SUBST([am__tar])
|
||||
AC_SUBST([am__untar])
|
||||
]) # _AM_PROG_TAR
|
||||
|
||||
m4_include([m4/acx_pthread.m4])
|
||||
m4_include([m4/google_namespace.m4])
|
||||
m4_include([m4/namespaces.m4])
|
||||
m4_include([m4/stl_hash.m4])
|
||||
m4_include([m4/stl_hash_fun.m4])
|
||||
m4_include([m4/stl_namespace.m4])
|
||||
74
src/sparsehash-1.6/configure.ac
Normal file
74
src/sparsehash-1.6/configure.ac
Normal file
@@ -0,0 +1,74 @@
|
||||
## Process this file with autoconf to produce configure.
|
||||
## In general, the safest way to proceed is to run ./autogen.sh
|
||||
|
||||
# make sure we're interpreted by some minimal autoconf
|
||||
AC_PREREQ(2.57)
|
||||
|
||||
AC_INIT(sparsehash, 1.6, opensource@google.com)
|
||||
# The argument here is just something that should be in the current directory
|
||||
# (for sanity checking)
|
||||
AC_CONFIG_SRCDIR(README)
|
||||
AM_INIT_AUTOMAKE([dist-zip])
|
||||
AM_CONFIG_HEADER(src/config.h)
|
||||
|
||||
# Checks for programs.
|
||||
AC_PROG_CC
|
||||
AC_PROG_CPP
|
||||
AC_PROG_CXX
|
||||
AM_CONDITIONAL(GCC, test "$GCC" = yes) # let the Makefile know if we're gcc
|
||||
|
||||
# Check whether some low-level functions/files are available
|
||||
AC_HEADER_STDC
|
||||
AC_CHECK_FUNCS(memcpy memmove)
|
||||
AC_CHECK_TYPES([uint16_t]) # defined in C99 systems
|
||||
AC_CHECK_TYPES([u_int16_t]) # defined in BSD-derived systems, and gnu
|
||||
AC_CHECK_TYPES([__uint16]) # defined in some windows systems (vc7)
|
||||
AC_CHECK_TYPES([long long]) # probably defined everywhere, but...
|
||||
|
||||
# These are 'only' needed for unittests
|
||||
AC_CHECK_HEADERS(sys/resource.h unistd.h sys/time.h sys/utsname.h)
|
||||
|
||||
# If you have google-perftools installed, we can do a bit more testing.
|
||||
# We not only want to set HAVE_MALLOC_EXTENSION_H, we also want to set
|
||||
# a variable to let the Makefile to know to link in tcmalloc.
|
||||
AC_LANG([C++])
|
||||
AC_CHECK_HEADERS(google/malloc_extension.h,
|
||||
tcmalloc_libs=-ltcmalloc,
|
||||
tcmalloc_libs=)
|
||||
# On some systems, when linking in tcmalloc you also need to link in
|
||||
# pthread. That's a bug somewhere, but we'll work around it for now.
|
||||
tcmalloc_flags=""
|
||||
if test -n "$tcmalloc_libs"; then
|
||||
ACX_PTHREAD
|
||||
tcmalloc_flags="\$(PTHREAD_CFLAGS)"
|
||||
tcmalloc_libs="$tcmalloc_libs \$(PTHREAD_LIBS)"
|
||||
fi
|
||||
AC_SUBST(tcmalloc_flags)
|
||||
AC_SUBST(tcmalloc_libs)
|
||||
|
||||
# Figure out where hash_map lives and also hash_fun.h (or stl_hash_fun.h).
|
||||
# This also tells us what namespace hash code lives in.
|
||||
AC_CXX_STL_HASH
|
||||
AC_CXX_STL_HASH_FUN
|
||||
|
||||
# Find out what namespace 'normal' STL code lives in, and also what namespace
|
||||
# the user wants our classes to be defined in
|
||||
AC_CXX_STL_NAMESPACE
|
||||
AC_DEFINE_GOOGLE_NAMESPACE(google)
|
||||
|
||||
# In unix-based systems, hash is always defined as hash<> (in namespace.
|
||||
# HASH_NAMESPACE.) So we can use a simple AC_DEFINE here. On
|
||||
# windows, and possibly on future unix STL implementations, this
|
||||
# macro will evaluate to something different.)
|
||||
AC_DEFINE(SPARSEHASH_HASH_NO_NAMESPACE, hash,
|
||||
[The system-provided hash function, in namespace HASH_NAMESPACE.])
|
||||
|
||||
# Do *not* define this in terms of SPARSEHASH_HASH_NO_NAMESPACE, because
|
||||
# SPARSEHASH_HASH is exported to sparseconfig.h, but S_H_NO_NAMESPACE isn't.
|
||||
AC_DEFINE(SPARSEHASH_HASH, HASH_NAMESPACE::hash,
|
||||
[The system-provided hash function including the namespace.])
|
||||
|
||||
|
||||
# Write generated configuration file
|
||||
AC_CONFIG_FILES([Makefile])
|
||||
AC_OUTPUT
|
||||
1591
src/sparsehash-1.6/doc/dense_hash_map.html
Normal file
1591
src/sparsehash-1.6/doc/dense_hash_map.html
Normal file
File diff suppressed because it is too large
Load Diff
1445
src/sparsehash-1.6/doc/dense_hash_set.html
Normal file
1445
src/sparsehash-1.6/doc/dense_hash_set.html
Normal file
File diff suppressed because it is too large
Load Diff
115
src/sparsehash-1.6/doc/designstyle.css
Normal file
115
src/sparsehash-1.6/doc/designstyle.css
Normal file
@@ -0,0 +1,115 @@
|
||||
body {
|
||||
background-color: #ffffff;
|
||||
color: black;
|
||||
margin-right: 1in;
|
||||
margin-left: 1in;
|
||||
}
|
||||
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
color: #3366ff;
|
||||
font-family: sans-serif;
|
||||
}
|
||||
@media print {
|
||||
/* Darker version for printing */
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
color: #000080;
|
||||
font-family: helvetica, sans-serif;
|
||||
}
|
||||
}
|
||||
|
||||
h1 {
|
||||
text-align: center;
|
||||
font-size: 18pt;
|
||||
}
|
||||
h2 {
|
||||
margin-left: -0.5in;
|
||||
}
|
||||
h3 {
|
||||
margin-left: -0.25in;
|
||||
}
|
||||
h4 {
|
||||
margin-left: -0.125in;
|
||||
}
|
||||
hr {
|
||||
margin-left: -1in;
|
||||
}
|
||||
|
||||
/* Definition lists: definition term bold */
|
||||
dt {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
address {
|
||||
text-align: right;
|
||||
}
|
||||
/* Use the <code> tag for bits of code and <var> for variables and objects. */
|
||||
code,pre,samp,var {
|
||||
color: #006000;
|
||||
}
|
||||
/* Use the <file> tag for file and directory paths and names. */
|
||||
file {
|
||||
color: #905050;
|
||||
font-family: monospace;
|
||||
}
|
||||
/* Use the <kbd> tag for stuff the user should type. */
|
||||
kbd {
|
||||
color: #600000;
|
||||
}
|
||||
div.note p {
|
||||
float: right;
|
||||
width: 3in;
|
||||
margin-right: 0%;
|
||||
padding: 1px;
|
||||
border: 2px solid #6060a0;
|
||||
background-color: #fffff0;
|
||||
}
|
||||
|
||||
UL.nobullets {
|
||||
list-style-type: none;
|
||||
list-style-image: none;
|
||||
margin-left: -1em;
|
||||
}
|
||||
|
||||
/*
|
||||
body:after {
|
||||
content: "Google Confidential";
|
||||
}
|
||||
*/
|
||||
|
||||
/* pretty printing styles. See prettify.js */
|
||||
.str { color: #080; }
|
||||
.kwd { color: #008; }
|
||||
.com { color: #800; }
|
||||
.typ { color: #606; }
|
||||
.lit { color: #066; }
|
||||
.pun { color: #660; }
|
||||
.pln { color: #000; }
|
||||
.tag { color: #008; }
|
||||
.atn { color: #606; }
|
||||
.atv { color: #080; }
|
||||
pre.prettyprint { padding: 2px; border: 1px solid #888; }
|
||||
|
||||
.embsrc { background: #eee; }
|
||||
|
||||
@media print {
|
||||
.str { color: #060; }
|
||||
.kwd { color: #006; font-weight: bold; }
|
||||
.com { color: #600; font-style: italic; }
|
||||
.typ { color: #404; font-weight: bold; }
|
||||
.lit { color: #044; }
|
||||
.pun { color: #440; }
|
||||
.pln { color: #000; }
|
||||
.tag { color: #006; font-weight: bold; }
|
||||
.atn { color: #404; }
|
||||
.atv { color: #060; }
|
||||
}
|
||||
|
||||
/* Table Column Headers */
|
||||
.hdr {
|
||||
color: #006;
|
||||
font-weight: bold;
|
||||
background-color: #dddddd; }
|
||||
.hdr2 {
|
||||
color: #006;
|
||||
background-color: #eeeeee; }
|
||||
371
src/sparsehash-1.6/doc/implementation.html
Normal file
371
src/sparsehash-1.6/doc/implementation.html
Normal file
@@ -0,0 +1,371 @@
|
||||
<HTML>
|
||||
|
||||
<HEAD>
|
||||
<title>Implementation notes: sparse_hash, dense_hash, sparsetable</title>
|
||||
</HEAD>
|
||||
|
||||
<BODY>
|
||||
|
||||
<h1>Implementation of sparse_hash_map, dense_hash_map, and
|
||||
sparsetable</h1>
|
||||
|
||||
This document contains a few notes on how the data structures in this
|
||||
package are implemented. This discussion refers at several points to
|
||||
the classic text in this area: Knuth, <i>The Art of Computer
|
||||
Programming</i>, Vol 3, Hashing.
|
||||
|
||||
|
||||
<hr>
|
||||
<h2><tt>sparsetable</tt></h2>
|
||||
|
||||
<p>For specificity, consider the declaration </p>
|
||||
|
||||
<pre>
|
||||
sparsetable<Foo> t(100); // a sparse array with 100 elements
|
||||
</pre>
|
||||
|
||||
<p>A sparsetable is a random container that implements a sparse array,
|
||||
that is, an array that uses very little memory to store unassigned
|
||||
indices (in this case, between 1-2 bits per unassigned index). For
|
||||
instance, if you allocate an array of size 5 and assign a[2] = [big
|
||||
struct], then a[2] will take up a lot of memory but a[0], a[1], a[3],
|
||||
and a[4] will not. Array elements that have a value are called
|
||||
"assigned". Array elements that have no value yet, or have had their
|
||||
value cleared using erase() or clear(), are called "unassigned".
|
||||
For assigned elements, lookups return the assigned value; for
|
||||
unassigned elements, they return the default value, which for t is
|
||||
Foo().</p>
|
||||
|
||||
<p>sparsetable is implemented as an array of "groups". Each group is
|
||||
responsible for M array indices. The first group knows about
|
||||
t[0]..t[M-1], the second about t[M]..t[2M-1], and so forth. (M is 48
|
||||
by default.) At construct time, t creates an array of (99/M + 1)
|
||||
groups. From this point on, all operations -- insert, delete, lookup
|
||||
-- are passed to the appropriate group. In particular, any operation
|
||||
on t[i] is actually performed on (t.group[i / M])[i % M].</p>
|
||||
|
||||
<p>Each group contains of a vector, which holds assigned values, and a
|
||||
bitmap of size M, which indicates which indices are assigned. A
|
||||
lookup works as follows: the group is asked to look up index i, where
|
||||
i < M. The group looks at bitmap[i]. If it's 0, the lookup fails.
|
||||
If it's 1, then the group has to find the appropriate value in the
|
||||
vector.</p>
|
||||
|
||||
<h3><tt>find()</tt></h3>
|
||||
|
||||
<p>Finding the appropriate vector element is the most expensive part of
|
||||
the lookup. The code counts all bitmap entries <= i that are set to
|
||||
1. (There's at least 1 of them, since bitmap[i] is 1.) Suppose there
|
||||
are 4 such entries. Then the right value to return is the 4th element
|
||||
of the vector: vector[3]. This takes time O(M), which is a constant
|
||||
since M is a constant.</p>
|
||||
|
||||
<h3><tt>insert()</tt></h3>
|
||||
|
||||
<p>Insert starts with a lookup. If the lookup succeeds, the code merely
|
||||
replaces vector[3] with the new value. If the lookup fails, then the
|
||||
code must insert a new entry into the middle of the vector. Again, to
|
||||
insert at position i, the code must count all the bitmap entries <= i
|
||||
that are set to i. This indicates the position to insert into the
|
||||
vector. All vector entries above that position must be moved to make
|
||||
room for the new entry. This takes time, but still constant time
|
||||
since the vector has size at most M.</p>
|
||||
|
||||
<p>(Inserts could be made faster by using a list instead of a vector to
|
||||
hold group values, but this would use much more memory, since each
|
||||
list element requires a full pointer of overhead.)</p>
|
||||
|
||||
<p>The only metadata that needs to be updated, after the actual value is
|
||||
inserted, is to set bitmap[i] to 1. No other counts must be
|
||||
maintained.</p>
|
||||
|
||||
<h3><tt>delete()</tt></h3>
|
||||
|
||||
<p>Deletes are similar to inserts. They start with a lookup. If it
|
||||
fails, the delete is a noop. Otherwise, the appropriate entry is
|
||||
removed from the vector, all the vector elements above it are moved
|
||||
down one, and bitmap[i] is set to 0.</p>
|
||||
|
||||
<h3>iterators</h3>
|
||||
|
||||
<p>Sparsetable iterators pose a special burden. They must iterate over
|
||||
unassigned array values, but the act of iterating should not cause an
|
||||
assignment to happen -- otherwise, iterating over a sparsetable would
|
||||
cause it to take up much more room. For const iterators, the matter
|
||||
is simple: the iterator is merely programmed to return the default
|
||||
value -- Foo() -- when dereferenced while pointing to an unassigned
|
||||
entry.</p>
|
||||
|
||||
<p>For non-const iterators, such simple techniques fail. Instead,
|
||||
dereferencing a sparsetable_iterator returns an opaque object that
|
||||
acts like a Foo in almost all situations, but isn't actually a Foo.
|
||||
(It does this by defining operator=(), operator value_type(), and,
|
||||
most sneakily, operator&().) This works in almost all cases. If it
|
||||
doesn't, an explicit cast to value_type will solve the problem:</p>
|
||||
|
||||
<pre>
|
||||
printf("%d", static_cast<Foo>(*t.find(0)));
|
||||
</pre>
|
||||
|
||||
<p>To avoid such problems, consider using get() and set() instead of an
|
||||
iterator:</p>
|
||||
|
||||
<pre>
|
||||
for (int i = 0; i < t.size(); ++i)
|
||||
if (t.get(i) == ...) t.set(i, ...);
|
||||
</pre>
|
||||
|
||||
<p>Sparsetable also has a special class of iterator, besides normal and
|
||||
const: nonempty_iterator. This only iterates over array values that
|
||||
are assigned. This is particularly fast given the sparsetable
|
||||
implementation, since it can ignore the bitmaps entirely and just
|
||||
iterate over the various group vectors.</p>
|
||||
|
||||
<h3>Resource use</h3>
|
||||
|
||||
<p>The space overhead for an sparsetable of size N is N + 48N/M bits.
|
||||
For the default value of M, this is exactly 2 bits per array entry.
|
||||
(That's for 32-bit pointers; for machines with 64-bit pointers, it's N
|
||||
+ 80N/M bits, or 2.67 bits per entry.)
|
||||
A larger M would use less overhead -- approaching 1 bit per array
|
||||
entry -- but take longer for inserts, deletes, and lookups. A smaller
|
||||
M would use more overhead but make operations somewhat faster.</p>
|
||||
|
||||
<p>You can also look at some specific <A
|
||||
HREF="performance.html">performance numbers</A>.</p>
|
||||
|
||||
|
||||
<hr>
|
||||
<h2><tt>sparse_hash_set</tt></h2>
|
||||
|
||||
<p>For specificity, consider the declaration </p>
|
||||
|
||||
<pre>
|
||||
sparse_hash_set<Foo> t;
|
||||
</pre>
|
||||
|
||||
<p>sparse_hash_set is a hashtable. For more information on hashtables,
|
||||
see Knuth. Hashtables are basically arrays with complicated logic on
|
||||
top of them. sparse_hash_set uses a sparsetable to implement the
|
||||
underlying array.</p>
|
||||
|
||||
<p>In particular, sparse_hash_set stores its data in a sparsetable using
|
||||
quadratic internal probing (see Knuth). Many hashtable
|
||||
implementations use external probing, so each table element is
|
||||
actually a pointer chain, holding many hashtable values.
|
||||
sparse_hash_set, on the other hand, always stores at most one value in
|
||||
each table location. If the hashtable wants to store a second value
|
||||
at a given table location, it can't; it's forced to look somewhere
|
||||
else.</p>
|
||||
|
||||
<h3><tt>insert()</tt></h3>
|
||||
|
||||
<p>As a specific example, suppose t is a new sparse_hash_set. It then
|
||||
holds a sparsetable of size 32. The code for t.insert(foo) works as
|
||||
follows:</p>
|
||||
|
||||
<p>
|
||||
1) Call hash<Foo>(foo) to convert foo into an integer i. (hash<Foo> is
|
||||
the default hash function; you can specify a different one in the
|
||||
template arguments.)
|
||||
|
||||
</p><p>
|
||||
2a) Look at t.sparsetable[i % 32]. If it's unassigned, assign it to
|
||||
foo. foo is now in the hashtable.
|
||||
|
||||
</p><p>
|
||||
2b) If t.sparsetable[i % 32] is assigned, and its value is foo, then
|
||||
do nothing: foo was already in t and the insert is a noop.
|
||||
|
||||
</p><p>
|
||||
2c) If t.sparsetable[i % 32] is assigned, but to a value other than
|
||||
foo, look at t.sparsetable[(i+1) % 32]. If that also fails, try
|
||||
t.sparsetable[(i+3) % 32], then t.sparsetable[(i+6) % 32]. In
|
||||
general, keep trying the next triangular number.
|
||||
|
||||
</p><p>
|
||||
3) If the table is now "too full" -- say, 25 of the 32 table entries
|
||||
are now assigned -- grow the table by creating a new sparsetable
|
||||
that's twice as big, and rehashing every single element from the
|
||||
old table into the new one. This keeps the table from ever filling
|
||||
up.
|
||||
|
||||
</p><p>
|
||||
4) If the table is now "too empty" -- say, only 3 of the 32 table
|
||||
entries are now assigned -- shrink the table by creating a new
|
||||
sparsetable that's half as big, and rehashing every element as in
|
||||
the growing case. This keeps the table overhead proportional to
|
||||
the number of elements in the table.
|
||||
</p>
|
||||
|
||||
<p>Instead of using triangular numbers as offsets, one could just use
|
||||
regular integers: try i, then i+1, then i+2, then i+3. This has bad
|
||||
'clumping' behavior, as explored in Knuth. Quadratic probing, using
|
||||
the triangular numbers, avoids the clumping while keeping cache
|
||||
coherency in the common case. As long as the table size is a power of
|
||||
2, the quadratic-probing method described above will explore every
|
||||
table element if necessary, to find a good place to insert.</p>
|
||||
|
||||
<p>(As a side note, using a table size that's a power of two has several
|
||||
advantages, including the speed of calculating (i % table_size). On
|
||||
the other hand, power-of-two tables are not very forgiving of a poor
|
||||
hash function. Make sure your hash function is a good one! There are
|
||||
plenty of dos and don'ts on the web (and in Knuth), for writing hash
|
||||
functions.)</p>
|
||||
|
||||
<p>The "too full" value, also called the "maximum occupancy", determines
|
||||
a time-space tradeoff: in general, the higher it is, the less space is
|
||||
wasted but the more probes must be performed for each insert.
|
||||
sparse_hash_set uses a high maximum occupancy, since space is more
|
||||
important than speed for this data structure.</p>
|
||||
|
||||
<p>The "too empty" value is not necessary for performance but helps with
|
||||
space use. It's rare for hashtable implementations to check this
|
||||
value at insert() time -- after all, how will inserting cause a
|
||||
hashtable to get too small? However, the sparse_hash_set
|
||||
implementation never resizes on erase(); it's nice to have an erase()
|
||||
that does not invalidate iterators. Thus, the first insert() after a
|
||||
long string of erase()s could well trigger a hashtable shrink.</p>
|
||||
|
||||
<h3><tt>find()</tt></h3>
|
||||
|
||||
<p>find() works similarly to insert. The only difference is in step
|
||||
(2a): if the value is unassigned, then the lookup fails immediately.</p>
|
||||
|
||||
<h3><tt>delete()</tt></h3>
|
||||
|
||||
<p>delete() is tricky in an internal-probing scheme. The obvious
|
||||
implementation of just "unassigning" the relevant table entry doesn't
|
||||
work. Consider the following scenario:</p>
|
||||
|
||||
<pre>
|
||||
t.insert(foo1); // foo1 hashes to 4, is put in table[4]
|
||||
t.insert(foo2); // foo2 hashes to 4, is put in table[5]
|
||||
t.erase(foo1); // table[4] is now 'unassigned'
|
||||
t.lookup(foo2); // fails since table[hash(foo2)] is unassigned
|
||||
</pre>
|
||||
|
||||
<p>To avoid these failure situations, delete(foo1) is actually
|
||||
implemented by replacing foo1 by a special 'delete' value in the
|
||||
hashtable. This 'delete' value causes the table entry to be
|
||||
considered unassigned for the purposes of insertion -- if foo3 hashes
|
||||
to 4 as well, it can go into table[4] no problem -- but assigned for
|
||||
the purposes of lookup.</p>
|
||||
|
||||
<p>What is this special 'delete' value? The delete value has to be an
|
||||
element of type Foo, since the table can't hold anything else. It
|
||||
obviously must be an element the client would never want to insert on
|
||||
its own, or else the code couldn't distinguish deleted entries from
|
||||
'real' entries with the same value. There's no way to determine a
|
||||
good value automatically. The client has to specify it explicitly.
|
||||
This is what the set_deleted_key() method does.</p>
|
||||
|
||||
<p>Note that set_deleted_key() is only necessary if the client actually
|
||||
wants to call t.erase(). For insert-only hash-sets, set_deleted_key()
|
||||
is unnecessary.</p>
|
||||
|
||||
<p>When copying the hashtable, either to grow it or shrink it, the
|
||||
special 'delete' values are <b>not</b> copied into the new table. The
|
||||
copy-time rehash makes them unnecessary.</p>
|
||||
|
||||
<h3>Resource use</h3>
|
||||
|
||||
<p>The data is stored in a sparsetable, so space use is the same as
|
||||
for sparsetable. However, by default the sparse_hash_set
|
||||
implementation tries to keep about half the table buckets empty, to
|
||||
keep lookup-chains short. Since sparsehashmap has about 2 bits
|
||||
overhead per bucket (or 2.5 bits on 64-bit systems), sparse_hash_map
|
||||
has about 4-5 bits overhead per hashtable item.</p>
|
||||
|
||||
<p>Time use is also determined in large part by the sparsetable
|
||||
implementation. However, there is also an extra probing cost in
|
||||
hashtables, which depends in large part on the "too full" value. It
|
||||
should be rare to need more than 4-5 probes per lookup, and usually
|
||||
significantly less will suffice.</p>
|
||||
|
||||
<p>A note on growing and shrinking the hashtable: all hashtable
|
||||
implementations use the most memory when growing a hashtable, since
|
||||
they must have room for both the old table and the new table at the
|
||||
same time. sparse_hash_set is careful to delete entries from the old
|
||||
hashtable as soon as they're copied into the new one, to minimize this
|
||||
space overhead. (It does this efficiently by using its knowledge of
|
||||
the sparsetable class and copying one sparsetable group at a time.)</p>
|
||||
|
||||
<p>You can also look at some specific <A
|
||||
HREF="performance.html">performance numbers</A>.</p>
|
||||
|
||||
|
||||
<hr>
|
||||
<h2><tt>sparse_hash_map</tt></h2>
|
||||
|
||||
<p>sparse_hash_map is implemented identically to sparse_hash_set. The
|
||||
only difference is instead of storing just Foo in each table entry,
|
||||
the data structure stores pair<Foo, Value>.</p>
|
||||
|
||||
|
||||
<hr>
|
||||
<h2><tt>dense_hash_set</tt></h2>
|
||||
|
||||
<p>The hashtable aspects of dense_hash_set are identical to
|
||||
sparse_hash_set: it uses quadratic internal probing, and resizes
|
||||
hashtables in exactly the same way. The difference is in the
|
||||
underlying array: instead of using a sparsetable, dense_hash_set uses
|
||||
a C array. This means much more space is used, especially if Foo is
|
||||
big. However, it makes all operations faster, since sparsetable has
|
||||
memory management overhead that C arrays do not.</p>
|
||||
|
||||
<p>The use of C arrays instead of sparsetables points to one immediate
|
||||
complication dense_hash_set has that sparse_hash_set does not: the
|
||||
need to distinguish assigned from unassigned entries. In a
|
||||
sparsetable, this is accomplished by a bitmap. dense_hash_set, on the
|
||||
other hand, uses a dedicated value to specify unassigned entries.
|
||||
Thus, dense_hash_set has two special values: one to indicate deleted
|
||||
table entries, and one to indicated unassigned table entries. At
|
||||
construct time, all table entries are initialized to 'unassigned'.</p>
|
||||
|
||||
<p>dense_hash_set provides the method set_empty_key() to indicate the
|
||||
value that should be used for unassigned entries. Like
|
||||
set_deleted_key(), set_empty_key() requires a value that will not be
|
||||
used by the client for any legitimate purpose. Unlike
|
||||
set_deleted_key(), set_empty_key() is always required, no matter what
|
||||
hashtable operations the client wishes to perform.</p>
|
||||
|
||||
<h3>Resource use</h3>
|
||||
|
||||
<p>This implementation is fast because even though dense_hash_set may not
|
||||
be space efficient, most lookups are localized: a single lookup may
|
||||
need to access table[i], and maybe table[i+1] and table[i+3], but
|
||||
nothing other than that. For all but the biggest data structures,
|
||||
these will frequently be in a single cache line.</p>
|
||||
|
||||
<p>This implementation takes, for every unused bucket, space as big as
|
||||
the key-type. Usually between half and two-thirds of the buckets are
|
||||
empty.</p>
|
||||
|
||||
<p>The doubling method used by dense_hash_set tends to work poorly
|
||||
with most memory allocators. This is because memory allocators tend
|
||||
to have memory 'buckets' which are a power of two. Since each
|
||||
doubling of a dense_hash_set doubles the memory use, a single
|
||||
hashtable doubling will require a new memory 'bucket' from the memory
|
||||
allocator, leaving the old bucket stranded as fragmented memory.
|
||||
Hence, it's not recommended this data structure be used with many
|
||||
inserts in memory-constrained situations.</p>
|
||||
|
||||
<p>You can also look at some specific <A
|
||||
HREF="performance.html">performance numbers</A>.</p>
|
||||
|
||||
|
||||
<hr>
|
||||
<h2><tt>dense_hash_map</tt></h2>
|
||||
|
||||
<p>dense_hash_map is identical to dense_hash_set except for what values
|
||||
are stored in each table entry.</p>
|
||||
|
||||
<hr>
|
||||
<author>
|
||||
Craig Silverstein<br>
|
||||
Thu Jan 6 20:15:42 PST 2005
|
||||
</author>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
69
src/sparsehash-1.6/doc/index.html
Normal file
69
src/sparsehash-1.6/doc/index.html
Normal file
@@ -0,0 +1,69 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>Google Sparsehash Package</title>
|
||||
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<link href="http://www.google.com/favicon.ico" type="image/x-icon"
|
||||
rel="shortcut icon">
|
||||
<link href="designstyle.css" type="text/css" rel="stylesheet">
|
||||
<style>
|
||||
<!--
|
||||
ol.bluelist li {
|
||||
color: #3366ff;
|
||||
font-family: sans-serif;
|
||||
}
|
||||
ol.bluelist li p {
|
||||
color: #000;
|
||||
font-family: "Times Roman", times, serif;
|
||||
}
|
||||
ul.blacklist li {
|
||||
color: #000;
|
||||
font-family: "Times Roman", times, serif;
|
||||
}
|
||||
//-->
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1> <a name="Google_Sparsehash_Package"></a>Google Sparsehash Package </h1>
|
||||
<br>
|
||||
|
||||
<p>The Google sparsehash package consists of two hashtable
|
||||
implementations: <i>sparse</i>, which is designed to be very space
|
||||
efficient, and <i>dense</i>, which is designed to be very time
|
||||
efficient. For each one, the package provides both a hash-map and a
|
||||
hash-set, to mirror the classes in the common STL implementation.</p>
|
||||
|
||||
<p>Documentation on how to use these classes:</p>
|
||||
<ul>
|
||||
<li> <A HREF="sparse_hash_map.html">sparse_hash_map</A>
|
||||
<li> <A HREF="sparse_hash_set.html">sparse_hash_set</A>
|
||||
<li> <A HREF="dense_hash_map.html">dense_hash_map</A>
|
||||
<li> <A HREF="dense_hash_set.html">dense_hash_set</A>
|
||||
</ul>
|
||||
|
||||
<p>In addition to the hash-map (and hash-set) classes, there's also a
|
||||
lower-level class that implements a "sparse" array. This class can be
|
||||
useful in its own right; consider using it when you'd normally use a
|
||||
<code>sparse_hash_map</code>, but your keys are all small-ish
|
||||
integers.</p>
|
||||
<ul>
|
||||
<li> <A HREF="sparsetable.html">sparsetable</A>
|
||||
</ul>
|
||||
|
||||
<p>There is also a doc explaining the <A
|
||||
HREF="implementation.html">implementation details</A> of these
|
||||
classes, for those who are curious. And finally, you can see some
|
||||
<A HREF="performance.html">performance comparisons</A>, both between
|
||||
the various classes here, but also between these implementations and
|
||||
other standard hashtable implementations.</p>
|
||||
|
||||
<hr>
|
||||
<address>
|
||||
Craig Silverstein<br>
|
||||
Last modified: Thu Jan 25 17:58:02 PST 2007
|
||||
</address>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
96
src/sparsehash-1.6/doc/performance.html
Normal file
96
src/sparsehash-1.6/doc/performance.html
Normal file
@@ -0,0 +1,96 @@
|
||||
<HTML>
|
||||
|
||||
<HEAD>
|
||||
<title>Performance notes: sparse_hash, dense_hash, sparsetable</title>
|
||||
</HEAD>
|
||||
|
||||
<BODY>
|
||||
|
||||
<H2>Performance Numbers</H2>
|
||||
|
||||
<p>Here are some performance numbers from an example desktop machine,
|
||||
taken from a version of time_hash_map that was instrumented to also
|
||||
report memory allocation information (this modification is not
|
||||
included by default because it required a big hack to do, including
|
||||
modifying the STL code to not try to do its own freelist management).</p>
|
||||
|
||||
<p>Note there are lots of caveats on these numbers: they may differ from
|
||||
machine to machine and compiler to compiler, and they only test a very
|
||||
particular usage pattern that may not match how you use hashtables --
|
||||
for instance, they test hashtables with very small keys. However,
|
||||
they're still useful for a baseline comparison of the various
|
||||
hashtable implementations.</p>
|
||||
|
||||
<p>These figures are from a 2.80GHz Pentium 4 with 2G of memory. The
|
||||
'standard' hash_map and map implementations are the SGI STL code
|
||||
included with <tt>gcc2</tt>. Compiled with <tt>gcc2.95.3 -g
|
||||
-O2</tt></p>
|
||||
|
||||
<pre>
|
||||
======
|
||||
Average over 10000000 iterations
|
||||
Wed Dec 8 14:56:38 PST 2004
|
||||
|
||||
SPARSE_HASH_MAP:
|
||||
map_grow 665 ns
|
||||
map_predict/grow 303 ns
|
||||
map_replace 177 ns
|
||||
map_fetch 117 ns
|
||||
map_remove 192 ns
|
||||
memory used in map_grow 84.3956 Mbytes
|
||||
|
||||
DENSE_HASH_MAP:
|
||||
map_grow 84 ns
|
||||
map_predict/grow 22 ns
|
||||
map_replace 18 ns
|
||||
map_fetch 13 ns
|
||||
map_remove 23 ns
|
||||
memory used in map_grow 256.0000 Mbytes
|
||||
|
||||
STANDARD HASH_MAP:
|
||||
map_grow 162 ns
|
||||
map_predict/grow 107 ns
|
||||
map_replace 44 ns
|
||||
map_fetch 22 ns
|
||||
map_remove 124 ns
|
||||
memory used in map_grow 204.1643 Mbytes
|
||||
|
||||
STANDARD MAP:
|
||||
map_grow 297 ns
|
||||
map_predict/grow 282 ns
|
||||
map_replace 113 ns
|
||||
map_fetch 113 ns
|
||||
map_remove 238 ns
|
||||
memory used in map_grow 236.8081 Mbytes
|
||||
</pre>
|
||||
|
||||
|
||||
<H2><A name="hashfn">A Note on Hash Functions</A></H2>
|
||||
|
||||
<p>For good performance, the Google hash routines depend on a good
|
||||
hash function: one that distributes data evenly. Many hashtable
|
||||
implementations come with sub-optimal hash functions that can degrade
|
||||
performance. For instance, the hash function given in Knuth's _Art of
|
||||
Computer Programming_, and the default string hash function in SGI's
|
||||
STL implementation, both distribute certain data sets unevenly,
|
||||
leading to poor performance.</p>
|
||||
|
||||
<p>As an example, in one test of the default SGI STL string hash
|
||||
function against the Hsieh hash function (see below), for a particular
|
||||
set of string keys, the Hsieh function resulted in hashtable lookups
|
||||
that were 20 times as fast as the STLPort hash function. The string
|
||||
keys were chosen to be "hard" to hash well, so these results may not
|
||||
be typical, but they are suggestive.</p>
|
||||
|
||||
<p>There has been much research over the years into good hash
|
||||
functions. Here are some hash functions of note.</p>
|
||||
|
||||
<ul>
|
||||
<li> Bob Jenkins: <A HREF="http://burtleburtle.net/bob/hash/">http://burtleburtle.net/bob/hash/</A>
|
||||
<li> Paul Hsieh: <A HREF="http://www.azillionmonkeys.com/qed/hash.html">http://www.azillionmonkeys.com/qed/hash.html</A>
|
||||
<li> Fowler/Noll/Vo (FNV): <A HREF="http://www.isthe.com/chongo/tech/comp/fnv/">http://www.isthe.com/chongo/tech/comp/fnv/</A>
|
||||
<li> MurmurHash: <A HREF="http://murmurhash.googlepages.com/">http://murmurhash.googlepages.com/</A>
|
||||
</ul>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
1527
src/sparsehash-1.6/doc/sparse_hash_map.html
Normal file
1527
src/sparsehash-1.6/doc/sparse_hash_map.html
Normal file
File diff suppressed because it is too large
Load Diff
1376
src/sparsehash-1.6/doc/sparse_hash_set.html
Normal file
1376
src/sparsehash-1.6/doc/sparse_hash_set.html
Normal file
File diff suppressed because it is too large
Load Diff
1393
src/sparsehash-1.6/doc/sparsetable.html
Normal file
1393
src/sparsehash-1.6/doc/sparsetable.html
Normal file
File diff suppressed because it is too large
Load Diff
9
src/sparsehash-1.6/experimental/Makefile
Normal file
9
src/sparsehash-1.6/experimental/Makefile
Normal file
@@ -0,0 +1,9 @@
|
||||
example: example.o libchash.o
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^
|
||||
|
||||
.SUFFIXES: .c .o .h
|
||||
.c.o:
|
||||
$(CC) -c $(CPPFLAGS) $(CFLAGS) -o $@ $<
|
||||
|
||||
example.o: example.c libchash.h
|
||||
libchash.o: libchash.c libchash.h
|
||||
14
src/sparsehash-1.6/experimental/README
Normal file
14
src/sparsehash-1.6/experimental/README
Normal file
@@ -0,0 +1,14 @@
|
||||
This is a C version of sparsehash (and also, maybe, densehash) that I
|
||||
wrote way back when, and served as the inspiration for the C++
|
||||
version. The API for the C version is much uglier than the C++,
|
||||
because of the lack of template support. I believe the class works,
|
||||
but I'm not convinced it's really flexible or easy enough to use.
|
||||
|
||||
It would be nice to rework this C class to follow the C++ API as
|
||||
closely as possible (eg have a set_deleted_key() instead of using a
|
||||
#define like this code does now). I believe the code compiles and
|
||||
runs, if anybody is interested in using it now, but it's subject to
|
||||
major change in the future, as people work on it.
|
||||
|
||||
Craig Silverstein
|
||||
20 March 2005
|
||||
54
src/sparsehash-1.6/experimental/example.c
Normal file
54
src/sparsehash-1.6/experimental/example.c
Normal file
@@ -0,0 +1,54 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include "libchash.h"
|
||||
|
||||
static void TestInsert() {
|
||||
struct HashTable* ht;
|
||||
HTItem* bck;
|
||||
|
||||
ht = AllocateHashTable(1, 0); /* value is 1 byte, 0: don't copy keys */
|
||||
|
||||
HashInsert(ht, PTR_KEY(ht, "January"), 31); /* 0: don't overwrite old val */
|
||||
bck = HashInsert(ht, PTR_KEY(ht, "February"), 28);
|
||||
bck = HashInsert(ht, PTR_KEY(ht, "March"), 31);
|
||||
|
||||
bck = HashFind(ht, PTR_KEY(ht, "February"));
|
||||
assert(bck);
|
||||
assert(bck->data == 28);
|
||||
|
||||
FreeHashTable(ht);
|
||||
}
|
||||
|
||||
static void TestFindOrInsert() {
|
||||
struct HashTable* ht;
|
||||
int i;
|
||||
int iterations = 1000000;
|
||||
int range = 30; /* random number between 1 and 30 */
|
||||
|
||||
ht = AllocateHashTable(4, 0); /* value is 4 bytes, 0: don't copy keys */
|
||||
|
||||
/* We'll test how good rand() is as a random number generator */
|
||||
for (i = 0; i < iterations; ++i) {
|
||||
int key = rand() % range;
|
||||
HTItem* bck = HashFindOrInsert(ht, key, 0); /* initialize to 0 */
|
||||
bck->data++; /* found one more of them */
|
||||
}
|
||||
|
||||
for (i = 0; i < range; ++i) {
|
||||
HTItem* bck = HashFind(ht, i);
|
||||
if (bck) {
|
||||
printf("%3d: %d\n", bck->key, bck->data);
|
||||
} else {
|
||||
printf("%3d: 0\n", i);
|
||||
}
|
||||
}
|
||||
|
||||
FreeHashTable(ht);
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
TestInsert();
|
||||
TestFindOrInsert();
|
||||
return 0;
|
||||
}
|
||||
1537
src/sparsehash-1.6/experimental/libchash.c
Normal file
1537
src/sparsehash-1.6/experimental/libchash.c
Normal file
File diff suppressed because it is too large
Load Diff
252
src/sparsehash-1.6/experimental/libchash.h
Normal file
252
src/sparsehash-1.6/experimental/libchash.h
Normal file
@@ -0,0 +1,252 @@
|
||||
/* Copyright (c) 1998 - 2005, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* ---
|
||||
* Author: Craig Silverstein
|
||||
*
|
||||
* This library is intended to be used for in-memory hash tables,
|
||||
* though it provides rudimentary permanent-storage capabilities.
|
||||
* It attempts to be fast, portable, and small. The best algorithm
|
||||
* to fulfill these goals is an internal probing hashing algorithm,
|
||||
* as in Knuth, _Art of Computer Programming_, vol III. Unlike
|
||||
* chained (open) hashing, it doesn't require a pointer for every
|
||||
* item, yet it is still constant time lookup in practice.
|
||||
*
|
||||
* Also to save space, we let the contents (both data and key) that
|
||||
* you insert be a union: if the key/data is small, we store it
|
||||
* directly in the hashtable, otherwise we store a pointer to it.
|
||||
* To keep you from having to figure out which, use KEY_PTR and
|
||||
* PTR_KEY to convert between the arguments to these functions and
|
||||
* a pointer to the real data. For instance:
|
||||
* char key[] = "ab", *key2;
|
||||
* HTItem *bck; HashTable *ht;
|
||||
* HashInsert(ht, PTR_KEY(ht, key), 0);
|
||||
* bck = HashFind(ht, PTR_KEY(ht, "ab"));
|
||||
* key2 = KEY_PTR(ht, bck->key);
|
||||
*
|
||||
* There are a rich set of operations supported:
|
||||
* AllocateHashTable() -- Allocates a hashtable structure and
|
||||
* returns it.
|
||||
* cchKey: if it's a positive number, then each key is a
|
||||
* fixed-length record of that length. If it's 0,
|
||||
* the key is assumed to be a \0-terminated string.
|
||||
* fSaveKey: normally, you are responsible for allocating
|
||||
* space for the key. If this is 1, we make a
|
||||
* copy of the key for you.
|
||||
* ClearHashTable() -- Removes everything from a hashtable
|
||||
* FreeHashTable() -- Frees memory used by a hashtable
|
||||
*
|
||||
* HashFind() -- takes a key (use PTR_KEY) and returns the
|
||||
* HTItem containing that key, or NULL if the
|
||||
* key is not in the hashtable.
|
||||
* HashFindLast() -- returns the item found by last HashFind()
|
||||
* HashFindOrInsert() -- inserts the key/data pair if the key
|
||||
* is not already in the hashtable, or
|
||||
* returns the appropraite HTItem if it is.
|
||||
* HashFindOrInsertItem() -- takes key/data as an HTItem.
|
||||
* HashInsert() -- adds a key/data pair to the hashtable. What
|
||||
* it does if the key is already in the table
|
||||
* depends on the value of SAMEKEY_OVERWRITE.
|
||||
* HashInsertItem() -- takes key/data as an HTItem.
|
||||
* HashDelete() -- removes a key/data pair from the hashtable,
|
||||
* if it's there. RETURNS 1 if it was there,
|
||||
* 0 else.
|
||||
* If you use sparse tables and never delete, the full data
|
||||
* space is available. Otherwise we steal -2 (maybe -3),
|
||||
* so you can't have data fields with those values.
|
||||
* HashDeleteLast() -- deletes the item returned by the last Find().
|
||||
*
|
||||
* HashFirstBucket() -- used to iterate over the buckets in a
|
||||
* hashtable. DON'T INSERT OR DELETE WHILE
|
||||
* ITERATING! You can't nest iterations.
|
||||
* HashNextBucket() -- RETURNS NULL at the end of iterating.
|
||||
*
|
||||
* HashSetDeltaGoalSize() -- if you're going to insert 1000 items
|
||||
* at once, call this fn with arg 1000.
|
||||
* It grows the table more intelligently.
|
||||
*
|
||||
* HashSave() -- saves the hashtable to a file. It saves keys ok,
|
||||
* but it doesn't know how to interpret the data field,
|
||||
* so if the data field is a pointer to some complex
|
||||
* structure, you must send a function that takes a
|
||||
* file pointer and a pointer to the structure, and
|
||||
* write whatever you want to write. It should return
|
||||
* the number of bytes written. If the file is NULL,
|
||||
* it should just return the number of bytes it would
|
||||
* write, without writing anything.
|
||||
* If your data field is just an integer, not a
|
||||
* pointer, just send NULL for the function.
|
||||
* HashLoad() -- loads a hashtable. It needs a function that takes
|
||||
* a file and the size of the structure, and expects
|
||||
* you to read in the structure and return a pointer
|
||||
* to it. You must do memory allocation, etc. If
|
||||
* the data is just a number, send NULL.
|
||||
* HashLoadKeys() -- unlike HashLoad(), doesn't load the data off disk
|
||||
* until needed. This saves memory, but if you look
|
||||
* up the same key a lot, it does a disk access each
|
||||
* time.
|
||||
* You can't do Insert() or Delete() on hashtables that were loaded
|
||||
* from disk.
|
||||
*/
|
||||
|
||||
#include <sys/types.h> /* includes definition of "ulong", we hope */
|
||||
#define ulong u_long
|
||||
|
||||
#define MAGIC_KEY "CHsh" /* when we save the file */
|
||||
|
||||
#ifndef LOG_WORD_SIZE /* 5 for 32 bit words, 6 for 64 */
|
||||
#if defined (__LP64__) || defined (_LP64)
|
||||
#define LOG_WORD_SIZE 6 /* log_2(sizeof(ulong)) [in bits] */
|
||||
#else
|
||||
#define LOG_WORD_SIZE 5 /* log_2(sizeof(ulong)) [in bits] */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* The following gives a speed/time tradeoff: how many buckets are *
|
||||
* in each bin. 0 gives 32 buckets/bin, which is a good number. */
|
||||
#ifndef LOG_BM_WORDS
|
||||
#define LOG_BM_WORDS 0 /* each group has 2^L_B_W * 32 buckets */
|
||||
#endif
|
||||
|
||||
/* The following are all parameters that affect performance. */
|
||||
#ifndef JUMP
|
||||
#define JUMP(key, offset) ( ++(offset) ) /* ( 1 ) for linear hashing */
|
||||
#endif
|
||||
#ifndef Table
|
||||
#define Table(x) Sparse##x /* Dense##x for dense tables */
|
||||
#endif
|
||||
#ifndef FAST_DELETE
|
||||
#define FAST_DELETE 0 /* if it's 1, we never shrink the ht */
|
||||
#endif
|
||||
#ifndef SAMEKEY_OVERWRITE
|
||||
#define SAMEKEY_OVERWRITE 1 /* overwrite item with our key on insert? */
|
||||
#endif
|
||||
#ifndef OCCUPANCY_PCT
|
||||
#define OCCUPANCY_PCT 0.5 /* large PCT means smaller and slower */
|
||||
#endif
|
||||
#ifndef MIN_HASH_SIZE
|
||||
#define MIN_HASH_SIZE 512 /* ht size when first created */
|
||||
#endif
|
||||
/* When deleting a bucket, we can't just empty it (future hashes *
|
||||
* may fail); instead we set the data field to DELETED. Thus you *
|
||||
* should set DELETED to a data value you never use. Better yet, *
|
||||
* if you don't need to delete, define INSERT_ONLY. */
|
||||
#ifndef INSERT_ONLY
|
||||
#define DELETED -2UL
|
||||
#define IS_BCK_DELETED(bck) ( (bck) && (bck)->data == DELETED )
|
||||
#define SET_BCK_DELETED(ht, bck) do { (bck)->data = DELETED; \
|
||||
FREE_KEY(ht, (bck)->key); } while ( 0 )
|
||||
#else
|
||||
#define IS_BCK_DELETED(bck) 0
|
||||
#define SET_BCK_DELETED(ht, bck) \
|
||||
do { fprintf(stderr, "Deletion not supported for insert-only hashtable\n");\
|
||||
exit(2); } while ( 0 )
|
||||
#endif
|
||||
|
||||
/* We need the following only for dense buckets (Dense##x above). *
|
||||
* If you need to, set this to a value you'll never use for data. */
|
||||
#define EMPTY -3UL /* steal more of the bck->data space */
|
||||
|
||||
|
||||
/* This is what an item is. Either can be cast to a pointer. */
|
||||
typedef struct {
|
||||
ulong data; /* 4 bytes for data: either a pointer or an integer */
|
||||
ulong key; /* 4 bytes for the key: either a pointer or an int */
|
||||
} HTItem;
|
||||
|
||||
struct Table(Bin); /* defined in chash.c, I hope */
|
||||
struct Table(Iterator);
|
||||
typedef struct Table(Bin) Table; /* Expands to SparseBin, etc */
|
||||
typedef struct Table(Iterator) TableIterator;
|
||||
|
||||
/* for STORES_PTR to work ok, cchKey MUST BE DEFINED 1st, cItems 2nd! */
|
||||
typedef struct HashTable {
|
||||
ulong cchKey; /* the length of the key, or if it's \0 terminated */
|
||||
ulong cItems; /* number of items currently in the hashtable */
|
||||
ulong cDeletedItems; /* # of buckets holding DELETE in the hashtable */
|
||||
ulong cBuckets; /* size of the table */
|
||||
Table *table; /* The actual contents of the hashtable */
|
||||
int fSaveKeys; /* 1 if we copy keys locally; 2 if keys in one block */
|
||||
int cDeltaGoalSize; /* # of coming inserts (or deletes, if <0) we expect */
|
||||
HTItem *posLastFind; /* position of last Find() command */
|
||||
TableIterator *iter; /* used in First/NextBucket */
|
||||
|
||||
FILE *fpData; /* if non-NULL, what item->data points into */
|
||||
char * (*dataRead)(FILE *, int); /* how to load data from disk */
|
||||
HTItem bckData; /* holds data after being loaded from disk */
|
||||
} HashTable;
|
||||
|
||||
/* Small keys are stored and passed directly, but large keys are
|
||||
* stored and passed as pointers. To make it easier to remember
|
||||
* what to pass, we provide two functions:
|
||||
* PTR_KEY: give it a pointer to your data, and it returns
|
||||
* something appropriate to send to Hash() functions or
|
||||
* be stored in a data field.
|
||||
* KEY_PTR: give it something returned by a Hash() routine, and
|
||||
* it returns a (char *) pointer to the actual data.
|
||||
*/
|
||||
#define HashKeySize(ht) ( ((ulong *)(ht))[0] ) /* this is how we inline */
|
||||
#define HashSize(ht) ( ((ulong *)(ht))[1] ) /* ...a la C++ :-) */
|
||||
|
||||
#define STORES_PTR(ht) ( HashKeySize(ht) == 0 || \
|
||||
HashKeySize(ht) > sizeof(ulong) )
|
||||
#define KEY_PTR(ht, key) ( STORES_PTR(ht) ? (char *)(key) : (char *)&(key) )
|
||||
#ifdef DONT_HAVE_TO_WORRY_ABOUT_BUS_ERRORS
|
||||
#define PTR_KEY(ht, ptr) ( STORES_PTR(ht) ? (ulong)(ptr) : *(ulong *)(ptr) )
|
||||
#else
|
||||
#define PTR_KEY(ht, ptr) ( STORES_PTR(ht) ? (ulong)(ptr) : HTcopy((char *)ptr))
|
||||
#endif
|
||||
|
||||
|
||||
/* Function prototypes */
|
||||
unsigned long HTcopy(char *pul); /* for PTR_KEY, not for users */
|
||||
|
||||
struct HashTable *AllocateHashTable(int cchKey, int fSaveKeys);
|
||||
void ClearHashTable(struct HashTable *ht);
|
||||
void FreeHashTable(struct HashTable *ht);
|
||||
|
||||
HTItem *HashFind(struct HashTable *ht, ulong key);
|
||||
HTItem *HashFindLast(struct HashTable *ht);
|
||||
HTItem *HashFindOrInsert(struct HashTable *ht, ulong key, ulong dataInsert);
|
||||
HTItem *HashFindOrInsertItem(struct HashTable *ht, HTItem *pItem);
|
||||
|
||||
HTItem *HashInsert(struct HashTable *ht, ulong key, ulong data);
|
||||
HTItem *HashInsertItem(struct HashTable *ht, HTItem *pItem);
|
||||
|
||||
int HashDelete(struct HashTable *ht, ulong key);
|
||||
int HashDeleteLast(struct HashTable *ht);
|
||||
|
||||
HTItem *HashFirstBucket(struct HashTable *ht);
|
||||
HTItem *HashNextBucket(struct HashTable *ht);
|
||||
|
||||
int HashSetDeltaGoalSize(struct HashTable *ht, int delta);
|
||||
|
||||
void HashSave(FILE *fp, struct HashTable *ht, int (*write)(FILE *, char *));
|
||||
struct HashTable *HashLoad(FILE *fp, char * (*read)(FILE *, int));
|
||||
struct HashTable *HashLoadKeys(FILE *fp, char * (*read)(FILE *, int));
|
||||
47
src/sparsehash-1.6/google-sparsehash.sln
Executable file
47
src/sparsehash-1.6/google-sparsehash.sln
Executable file
@@ -0,0 +1,47 @@
|
||||
Microsoft Visual Studio Solution File, Format Version 8.00
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "type_traits_unittest", "vsprojects\type_traits_unittest\type_traits_unittest.vcproj", "{008CCFED-7D7B-46F8-8E13-03837A2258B3}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sparsetable_unittest", "vsprojects\sparsetable_unittest\sparsetable_unittest.vcproj", "{E420867B-8BFA-4739-99EC-E008AB762FF9}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hashtable_unittest", "vsprojects\hashtable_unittest\hashtable_unittest.vcproj", "{FCDB3718-F01C-4DE4-B9F5-E10F2C5C0535}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "time_hash_map", "vsprojects\time_hash_map\time_hash_map.vcproj", "{A74E5DB8-5295-487A-AB1D-23859F536F45}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfiguration) = preSolution
|
||||
Debug = Debug
|
||||
Release = Release
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectDependencies) = postSolution
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfiguration) = postSolution
|
||||
{008CCFED-7D7B-46F8-8E13-03837A2258B3}.Debug.ActiveCfg = Debug|Win32
|
||||
{008CCFED-7D7B-46F8-8E13-03837A2258B3}.Debug.Build.0 = Debug|Win32
|
||||
{008CCFED-7D7B-46F8-8E13-03837A2258B3}.Release.ActiveCfg = Release|Win32
|
||||
{008CCFED-7D7B-46F8-8E13-03837A2258B3}.Release.Build.0 = Release|Win32
|
||||
{E420867B-8BFA-4739-99EC-E008AB762FF9}.Debug.ActiveCfg = Debug|Win32
|
||||
{E420867B-8BFA-4739-99EC-E008AB762FF9}.Debug.Build.0 = Debug|Win32
|
||||
{E420867B-8BFA-4739-99EC-E008AB762FF9}.Release.ActiveCfg = Release|Win32
|
||||
{E420867B-8BFA-4739-99EC-E008AB762FF9}.Release.Build.0 = Release|Win32
|
||||
{FCDB3718-F01C-4DE4-B9F5-E10F2C5C0535}.Debug.ActiveCfg = Debug|Win32
|
||||
{FCDB3718-F01C-4DE4-B9F5-E10F2C5C0535}.Debug.Build.0 = Debug|Win32
|
||||
{FCDB3718-F01C-4DE4-B9F5-E10F2C5C0535}.Release.ActiveCfg = Release|Win32
|
||||
{FCDB3718-F01C-4DE4-B9F5-E10F2C5C0535}.Release.Build.0 = Release|Win32
|
||||
{A74E5DB8-5295-487A-AB1D-23859F536F45}.Debug.ActiveCfg = Debug|Win32
|
||||
{A74E5DB8-5295-487A-AB1D-23859F536F45}.Debug.Build.0 = Debug|Win32
|
||||
{A74E5DB8-5295-487A-AB1D-23859F536F45}.Release.ActiveCfg = Release|Win32
|
||||
{A74E5DB8-5295-487A-AB1D-23859F536F45}.Release.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityAddIns) = postSolution
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
BIN
src/sparsehash-1.6/hashtable_unittest
Executable file
BIN
src/sparsehash-1.6/hashtable_unittest
Executable file
Binary file not shown.
363
src/sparsehash-1.6/m4/acx_pthread.m4
Normal file
363
src/sparsehash-1.6/m4/acx_pthread.m4
Normal file
@@ -0,0 +1,363 @@
|
||||
# This was retrieved from
|
||||
# http://svn.0pointer.de/viewvc/trunk/common/acx_pthread.m4?revision=1277&root=avahi
|
||||
# See also (perhaps for new versions?)
|
||||
# http://svn.0pointer.de/viewvc/trunk/common/acx_pthread.m4?root=avahi
|
||||
#
|
||||
# We've rewritten the inconsistency check code (from avahi), to work
|
||||
# more broadly. In particular, it no longer assumes ld accepts -zdefs.
|
||||
# This caused a restructing of the code, but the functionality has only
|
||||
# changed a little.
|
||||
|
||||
dnl @synopsis ACX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
|
||||
dnl
|
||||
dnl @summary figure out how to build C programs using POSIX threads
|
||||
dnl
|
||||
dnl This macro figures out how to build C programs using POSIX threads.
|
||||
dnl It sets the PTHREAD_LIBS output variable to the threads library and
|
||||
dnl linker flags, and the PTHREAD_CFLAGS output variable to any special
|
||||
dnl C compiler flags that are needed. (The user can also force certain
|
||||
dnl compiler flags/libs to be tested by setting these environment
|
||||
dnl variables.)
|
||||
dnl
|
||||
dnl Also sets PTHREAD_CC to any special C compiler that is needed for
|
||||
dnl multi-threaded programs (defaults to the value of CC otherwise).
|
||||
dnl (This is necessary on AIX to use the special cc_r compiler alias.)
|
||||
dnl
|
||||
dnl NOTE: You are assumed to not only compile your program with these
|
||||
dnl flags, but also link it with them as well. e.g. you should link
|
||||
dnl with $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS
|
||||
dnl $LIBS
|
||||
dnl
|
||||
dnl If you are only building threads programs, you may wish to use
|
||||
dnl these variables in your default LIBS, CFLAGS, and CC:
|
||||
dnl
|
||||
dnl LIBS="$PTHREAD_LIBS $LIBS"
|
||||
dnl CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
|
||||
dnl CC="$PTHREAD_CC"
|
||||
dnl
|
||||
dnl In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute
|
||||
dnl constant has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to
|
||||
dnl that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX).
|
||||
dnl
|
||||
dnl ACTION-IF-FOUND is a list of shell commands to run if a threads
|
||||
dnl library is found, and ACTION-IF-NOT-FOUND is a list of commands to
|
||||
dnl run it if it is not found. If ACTION-IF-FOUND is not specified, the
|
||||
dnl default action will define HAVE_PTHREAD.
|
||||
dnl
|
||||
dnl Please let the authors know if this macro fails on any platform, or
|
||||
dnl if you have any other suggestions or comments. This macro was based
|
||||
dnl on work by SGJ on autoconf scripts for FFTW (www.fftw.org) (with
|
||||
dnl help from M. Frigo), as well as ac_pthread and hb_pthread macros
|
||||
dnl posted by Alejandro Forero Cuervo to the autoconf macro repository.
|
||||
dnl We are also grateful for the helpful feedback of numerous users.
|
||||
dnl
|
||||
dnl @category InstalledPackages
|
||||
dnl @author Steven G. Johnson <stevenj@alum.mit.edu>
|
||||
dnl @version 2006-05-29
|
||||
dnl @license GPLWithACException
|
||||
dnl
|
||||
dnl Checks for GCC shared/pthread inconsistency based on work by
|
||||
dnl Marcin Owsiany <marcin@owsiany.pl>
|
||||
|
||||
|
||||
AC_DEFUN([ACX_PTHREAD], [
|
||||
AC_REQUIRE([AC_CANONICAL_HOST])
|
||||
AC_LANG_SAVE
|
||||
AC_LANG_C
|
||||
acx_pthread_ok=no
|
||||
|
||||
# We used to check for pthread.h first, but this fails if pthread.h
|
||||
# requires special compiler flags (e.g. on True64 or Sequent).
|
||||
# It gets checked for in the link test anyway.
|
||||
|
||||
# First of all, check if the user has set any of the PTHREAD_LIBS,
|
||||
# etcetera environment variables, and if threads linking works using
|
||||
# them:
|
||||
if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
|
||||
save_CFLAGS="$CFLAGS"
|
||||
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
|
||||
save_LIBS="$LIBS"
|
||||
LIBS="$PTHREAD_LIBS $LIBS"
|
||||
AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS])
|
||||
AC_TRY_LINK_FUNC(pthread_join, acx_pthread_ok=yes)
|
||||
AC_MSG_RESULT($acx_pthread_ok)
|
||||
if test x"$acx_pthread_ok" = xno; then
|
||||
PTHREAD_LIBS=""
|
||||
PTHREAD_CFLAGS=""
|
||||
fi
|
||||
LIBS="$save_LIBS"
|
||||
CFLAGS="$save_CFLAGS"
|
||||
fi
|
||||
|
||||
# We must check for the threads library under a number of different
|
||||
# names; the ordering is very important because some systems
|
||||
# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
|
||||
# libraries is broken (non-POSIX).
|
||||
|
||||
# Create a list of thread flags to try. Items starting with a "-" are
|
||||
# C compiler flags, and other items are library names, except for "none"
|
||||
# which indicates that we try without any flags at all, and "pthread-config"
|
||||
# which is a program returning the flags for the Pth emulation library.
|
||||
|
||||
acx_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
|
||||
|
||||
# The ordering *is* (sometimes) important. Some notes on the
|
||||
# individual items follow:
|
||||
|
||||
# pthreads: AIX (must check this before -lpthread)
|
||||
# none: in case threads are in libc; should be tried before -Kthread and
|
||||
# other compiler flags to prevent continual compiler warnings
|
||||
# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
|
||||
# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
|
||||
# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
|
||||
# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads)
|
||||
# -pthreads: Solaris/gcc
|
||||
# -mthreads: Mingw32/gcc, Lynx/gcc
|
||||
# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
|
||||
# doesn't hurt to check since this sometimes defines pthreads too;
|
||||
# also defines -D_REENTRANT)
|
||||
# ... -mt is also the pthreads flag for HP/aCC
|
||||
# pthread: Linux, etcetera
|
||||
# --thread-safe: KAI C++
|
||||
# pthread-config: use pthread-config program (for GNU Pth library)
|
||||
|
||||
case "${host_cpu}-${host_os}" in
|
||||
*solaris*)
|
||||
|
||||
# On Solaris (at least, for some versions), libc contains stubbed
|
||||
# (non-functional) versions of the pthreads routines, so link-based
|
||||
# tests will erroneously succeed. (We need to link with -pthreads/-mt/
|
||||
# -lpthread.) (The stubs are missing pthread_cleanup_push, or rather
|
||||
# a function called by this macro, so we could check for that, but
|
||||
# who knows whether they'll stub that too in a future libc.) So,
|
||||
# we'll just look for -pthreads and -lpthread first:
|
||||
|
||||
acx_pthread_flags="-pthreads pthread -mt -pthread $acx_pthread_flags"
|
||||
;;
|
||||
esac
|
||||
|
||||
if test x"$acx_pthread_ok" = xno; then
|
||||
for flag in $acx_pthread_flags; do
|
||||
|
||||
case $flag in
|
||||
none)
|
||||
AC_MSG_CHECKING([whether pthreads work without any flags])
|
||||
;;
|
||||
|
||||
-*)
|
||||
AC_MSG_CHECKING([whether pthreads work with $flag])
|
||||
PTHREAD_CFLAGS="$flag"
|
||||
;;
|
||||
|
||||
pthread-config)
|
||||
AC_CHECK_PROG(acx_pthread_config, pthread-config, yes, no)
|
||||
if test x"$acx_pthread_config" = xno; then continue; fi
|
||||
PTHREAD_CFLAGS="`pthread-config --cflags`"
|
||||
PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
|
||||
;;
|
||||
|
||||
*)
|
||||
AC_MSG_CHECKING([for the pthreads library -l$flag])
|
||||
PTHREAD_LIBS="-l$flag"
|
||||
;;
|
||||
esac
|
||||
|
||||
save_LIBS="$LIBS"
|
||||
save_CFLAGS="$CFLAGS"
|
||||
LIBS="$PTHREAD_LIBS $LIBS"
|
||||
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
|
||||
|
||||
# Check for various functions. We must include pthread.h,
|
||||
# since some functions may be macros. (On the Sequent, we
|
||||
# need a special flag -Kthread to make this header compile.)
|
||||
# We check for pthread_join because it is in -lpthread on IRIX
|
||||
# while pthread_create is in libc. We check for pthread_attr_init
|
||||
# due to DEC craziness with -lpthreads. We check for
|
||||
# pthread_cleanup_push because it is one of the few pthread
|
||||
# functions on Solaris that doesn't have a non-functional libc stub.
|
||||
# We try pthread_create on general principles.
|
||||
AC_TRY_LINK([#include <pthread.h>],
|
||||
[pthread_t th; pthread_join(th, 0);
|
||||
pthread_attr_init(0); pthread_cleanup_push(0, 0);
|
||||
pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
|
||||
[acx_pthread_ok=yes])
|
||||
|
||||
LIBS="$save_LIBS"
|
||||
CFLAGS="$save_CFLAGS"
|
||||
|
||||
AC_MSG_RESULT($acx_pthread_ok)
|
||||
if test "x$acx_pthread_ok" = xyes; then
|
||||
break;
|
||||
fi
|
||||
|
||||
PTHREAD_LIBS=""
|
||||
PTHREAD_CFLAGS=""
|
||||
done
|
||||
fi
|
||||
|
||||
# Various other checks:
|
||||
if test "x$acx_pthread_ok" = xyes; then
|
||||
save_LIBS="$LIBS"
|
||||
LIBS="$PTHREAD_LIBS $LIBS"
|
||||
save_CFLAGS="$CFLAGS"
|
||||
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
|
||||
|
||||
# Detect AIX lossage: JOINABLE attribute is called UNDETACHED.
|
||||
AC_MSG_CHECKING([for joinable pthread attribute])
|
||||
attr_name=unknown
|
||||
for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
|
||||
AC_TRY_LINK([#include <pthread.h>], [int attr=$attr; return attr;],
|
||||
[attr_name=$attr; break])
|
||||
done
|
||||
AC_MSG_RESULT($attr_name)
|
||||
if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then
|
||||
AC_DEFINE_UNQUOTED(PTHREAD_CREATE_JOINABLE, $attr_name,
|
||||
[Define to necessary symbol if this constant
|
||||
uses a non-standard name on your system.])
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING([if more special flags are required for pthreads])
|
||||
flag=no
|
||||
case "${host_cpu}-${host_os}" in
|
||||
*-aix* | *-freebsd* | *-darwin*) flag="-D_THREAD_SAFE";;
|
||||
*solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";;
|
||||
esac
|
||||
AC_MSG_RESULT(${flag})
|
||||
if test "x$flag" != xno; then
|
||||
PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS"
|
||||
fi
|
||||
|
||||
LIBS="$save_LIBS"
|
||||
CFLAGS="$save_CFLAGS"
|
||||
# More AIX lossage: must compile with xlc_r or cc_r
|
||||
if test x"$GCC" != xyes; then
|
||||
AC_CHECK_PROGS(PTHREAD_CC, xlc_r cc_r, ${CC})
|
||||
else
|
||||
PTHREAD_CC=$CC
|
||||
fi
|
||||
|
||||
# The next part tries to detect GCC inconsistency with -shared on some
|
||||
# architectures and systems. The problem is that in certain
|
||||
# configurations, when -shared is specified, GCC "forgets" to
|
||||
# internally use various flags which are still necessary.
|
||||
|
||||
#
|
||||
# Prepare the flags
|
||||
#
|
||||
save_CFLAGS="$CFLAGS"
|
||||
save_LIBS="$LIBS"
|
||||
save_CC="$CC"
|
||||
|
||||
# Try with the flags determined by the earlier checks.
|
||||
#
|
||||
# -Wl,-z,defs forces link-time symbol resolution, so that the
|
||||
# linking checks with -shared actually have any value
|
||||
#
|
||||
# FIXME: -fPIC is required for -shared on many architectures,
|
||||
# so we specify it here, but the right way would probably be to
|
||||
# properly detect whether it is actually required.
|
||||
CFLAGS="-shared -fPIC -Wl,-z,defs $CFLAGS $PTHREAD_CFLAGS"
|
||||
LIBS="$PTHREAD_LIBS $LIBS"
|
||||
CC="$PTHREAD_CC"
|
||||
|
||||
# In order not to create several levels of indentation, we test
|
||||
# the value of "$done" until we find the cure or run out of ideas.
|
||||
done="no"
|
||||
|
||||
# First, make sure the CFLAGS we added are actually accepted by our
|
||||
# compiler. If not (and OS X's ld, for instance, does not accept -z),
|
||||
# then we can't do this test.
|
||||
if test x"$done" = xno; then
|
||||
AC_MSG_CHECKING([whether to check for GCC pthread/shared inconsistencies])
|
||||
AC_TRY_LINK(,, , [done=yes])
|
||||
|
||||
if test "x$done" = xyes ; then
|
||||
AC_MSG_RESULT([no])
|
||||
else
|
||||
AC_MSG_RESULT([yes])
|
||||
fi
|
||||
fi
|
||||
|
||||
if test x"$done" = xno; then
|
||||
AC_MSG_CHECKING([whether -pthread is sufficient with -shared])
|
||||
AC_TRY_LINK([#include <pthread.h>],
|
||||
[pthread_t th; pthread_join(th, 0);
|
||||
pthread_attr_init(0); pthread_cleanup_push(0, 0);
|
||||
pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
|
||||
[done=yes])
|
||||
|
||||
if test "x$done" = xyes; then
|
||||
AC_MSG_RESULT([yes])
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
fi
|
||||
fi
|
||||
|
||||
#
|
||||
# Linux gcc on some architectures such as mips/mipsel forgets
|
||||
# about -lpthread
|
||||
#
|
||||
if test x"$done" = xno; then
|
||||
AC_MSG_CHECKING([whether -lpthread fixes that])
|
||||
LIBS="-lpthread $PTHREAD_LIBS $save_LIBS"
|
||||
AC_TRY_LINK([#include <pthread.h>],
|
||||
[pthread_t th; pthread_join(th, 0);
|
||||
pthread_attr_init(0); pthread_cleanup_push(0, 0);
|
||||
pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
|
||||
[done=yes])
|
||||
|
||||
if test "x$done" = xyes; then
|
||||
AC_MSG_RESULT([yes])
|
||||
PTHREAD_LIBS="-lpthread $PTHREAD_LIBS"
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
fi
|
||||
fi
|
||||
#
|
||||
# FreeBSD 4.10 gcc forgets to use -lc_r instead of -lc
|
||||
#
|
||||
if test x"$done" = xno; then
|
||||
AC_MSG_CHECKING([whether -lc_r fixes that])
|
||||
LIBS="-lc_r $PTHREAD_LIBS $save_LIBS"
|
||||
AC_TRY_LINK([#include <pthread.h>],
|
||||
[pthread_t th; pthread_join(th, 0);
|
||||
pthread_attr_init(0); pthread_cleanup_push(0, 0);
|
||||
pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
|
||||
[done=yes])
|
||||
|
||||
if test "x$done" = xyes; then
|
||||
AC_MSG_RESULT([yes])
|
||||
PTHREAD_LIBS="-lc_r $PTHREAD_LIBS"
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
fi
|
||||
fi
|
||||
if test x"$done" = xno; then
|
||||
# OK, we have run out of ideas
|
||||
AC_MSG_WARN([Impossible to determine how to use pthreads with shared libraries])
|
||||
|
||||
# so it's not safe to assume that we may use pthreads
|
||||
acx_pthread_ok=no
|
||||
fi
|
||||
|
||||
CFLAGS="$save_CFLAGS"
|
||||
LIBS="$save_LIBS"
|
||||
CC="$save_CC"
|
||||
else
|
||||
PTHREAD_CC="$CC"
|
||||
fi
|
||||
|
||||
AC_SUBST(PTHREAD_LIBS)
|
||||
AC_SUBST(PTHREAD_CFLAGS)
|
||||
AC_SUBST(PTHREAD_CC)
|
||||
|
||||
# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
|
||||
if test x"$acx_pthread_ok" = xyes; then
|
||||
ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1])
|
||||
:
|
||||
else
|
||||
acx_pthread_ok=no
|
||||
$2
|
||||
fi
|
||||
AC_LANG_RESTORE
|
||||
])dnl ACX_PTHREAD
|
||||
42
src/sparsehash-1.6/m4/google_namespace.m4
Normal file
42
src/sparsehash-1.6/m4/google_namespace.m4
Normal file
@@ -0,0 +1,42 @@
|
||||
# Allow users to override the namespace we define our application's classes in
|
||||
# Arg $1 is the default namespace to use if --enable-namespace isn't present.
|
||||
|
||||
# In general, $1 should be 'google', so we put all our exported symbols in a
|
||||
# unique namespace that is not likely to conflict with anyone else. However,
|
||||
# when it makes sense -- for instance, when publishing stl-like code -- you
|
||||
# may want to go with a different default, like 'std'.
|
||||
|
||||
# We guarantee the invariant that GOOGLE_NAMESPACE starts with ::,
|
||||
# unless it's the empty string. Thus, it's always safe to do
|
||||
# GOOGLE_NAMESPACE::foo and be sure you're getting the foo that's
|
||||
# actually in the google namespace, and not some other namespace that
|
||||
# the namespace rules might kick in.
|
||||
|
||||
AC_DEFUN([AC_DEFINE_GOOGLE_NAMESPACE],
|
||||
[google_namespace_default=[$1]
|
||||
AC_ARG_ENABLE(namespace, [ --enable-namespace=FOO to define these Google
|
||||
classes in the FOO namespace. --disable-namespace
|
||||
to define them in the global namespace. Default
|
||||
is to define them in namespace $1.],
|
||||
[case "$enableval" in
|
||||
yes) google_namespace="$google_namespace_default" ;;
|
||||
no) google_namespace="" ;;
|
||||
*) google_namespace="$enableval" ;;
|
||||
esac],
|
||||
[google_namespace="$google_namespace_default"])
|
||||
if test -n "$google_namespace"; then
|
||||
ac_google_namespace="::$google_namespace"
|
||||
ac_google_start_namespace="namespace $google_namespace {"
|
||||
ac_google_end_namespace="}"
|
||||
else
|
||||
ac_google_namespace=""
|
||||
ac_google_start_namespace=""
|
||||
ac_google_end_namespace=""
|
||||
fi
|
||||
AC_DEFINE_UNQUOTED(GOOGLE_NAMESPACE, $ac_google_namespace,
|
||||
Namespace for Google classes)
|
||||
AC_DEFINE_UNQUOTED(_START_GOOGLE_NAMESPACE_, $ac_google_start_namespace,
|
||||
Puts following code inside the Google namespace)
|
||||
AC_DEFINE_UNQUOTED(_END_GOOGLE_NAMESPACE_, $ac_google_end_namespace,
|
||||
Stops putting the code inside the Google namespace)
|
||||
])
|
||||
15
src/sparsehash-1.6/m4/namespaces.m4
Normal file
15
src/sparsehash-1.6/m4/namespaces.m4
Normal file
@@ -0,0 +1,15 @@
|
||||
# Checks whether the compiler implements namespaces
|
||||
AC_DEFUN([AC_CXX_NAMESPACES],
|
||||
[AC_CACHE_CHECK(whether the compiler implements namespaces,
|
||||
ac_cv_cxx_namespaces,
|
||||
[AC_LANG_SAVE
|
||||
AC_LANG_CPLUSPLUS
|
||||
AC_TRY_COMPILE([namespace Outer {
|
||||
namespace Inner { int i = 0; }}],
|
||||
[using namespace Outer::Inner; return i;],
|
||||
ac_cv_cxx_namespaces=yes,
|
||||
ac_cv_cxx_namespaces=no)
|
||||
AC_LANG_RESTORE])
|
||||
if test "$ac_cv_cxx_namespaces" = yes; then
|
||||
AC_DEFINE(HAVE_NAMESPACES, 1, [define if the compiler implements namespaces])
|
||||
fi])
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user