00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 #include "asterisk.h"
00041 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 97656 $")
00042 #include "asterisk/utils.h"
00043 #include "console_video.h"
00044
00045 #ifdef HAVE_SDL
00046 #include <SDL/SDL.h>
00047
00048
00049 #define FONT_H 20
00050 #define FONT_W 9
00051
00052 struct board {
00053 int kb_output;
00054
00055 SDL_Surface *screen;
00056 SDL_Rect *p_rect;
00057 SDL_Surface *blank;
00058
00059 int v_h;
00060 int v_w;
00061 int p_h;
00062
00063 int p_w;
00064
00065
00066 int cur_col;
00067 int cur_line;
00068
00069
00070
00071 SDL_Surface *font;
00072 SDL_Rect *font_rects;
00073 char *text;
00074
00075
00076
00077
00078
00079 };
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089 struct board *board_setup(SDL_Surface *screen, SDL_Rect *dest,
00090 SDL_Surface *font, SDL_Rect *font_rects);
00091 struct board *board_setup(SDL_Surface *screen, SDL_Rect *dest,
00092 SDL_Surface *font, SDL_Rect *font_rects)
00093 {
00094 struct board *b = ast_calloc(1, sizeof (*b));
00095 SDL_Rect br;
00096
00097 if (b == NULL)
00098 return NULL;
00099
00100 b->font = font;
00101 b->font_rects = font_rects;
00102
00103
00104 b->p_rect = dest;
00105 b->screen = screen;
00106
00107
00108 b->p_h = b->p_rect->h/FONT_H;
00109 b->p_w = b->p_rect->w/FONT_W;
00110
00111
00112 b->v_h = b->p_h * 10;
00113 b->v_w = b->p_w;
00114
00115
00116 br.h = b->p_h * FONT_H;
00117 br.w = b->p_w * FONT_W;
00118 br.x = br.y = 0;
00119
00120
00121 b->text = ast_calloc(b->v_w*b->v_h + 1, 1);
00122 if (b->text == NULL) {
00123 ast_log(LOG_WARNING, "Unable to allocate board history memory.\n");
00124 ast_free(b);
00125 return NULL;
00126 }
00127 memset(b->text, ' ', b->v_w * b->v_h);
00128
00129
00130 b->blank = SDL_CreateRGBSurface(screen->flags, br.w, br.h,
00131 screen->format->BitsPerPixel,
00132 screen->format->Rmask, screen->format->Gmask,
00133 screen->format->Bmask, screen->format->Amask);
00134
00135 if (b->blank == NULL) {
00136 ast_log(LOG_WARNING, "Unable to allocate board virtual screen: %s\n",
00137 SDL_GetError());
00138 ast_free(b->text);
00139 ast_free(b);
00140 return NULL;
00141 }
00142 SDL_BlitSurface(screen, b->p_rect, b->blank, &br);
00143
00144
00145
00146
00147
00148 b->cur_col = 0;
00149 b->cur_line = 0;
00150
00151 ast_log(LOG_WARNING, "Message board %dx%d@%d,%d successfully initialized\n",
00152 b->p_rect->w, b->p_rect->h,
00153 b->p_rect->x, b->p_rect->y);
00154 return b;
00155 }
00156
00157
00158
00159
00160
00161
00162 static void render_board(struct board *b)
00163 {
00164 int first_row = b->v_h - b->p_h - b->cur_line;
00165 int first_char = b->v_w * first_row;
00166 int last_char = first_char + b->p_h * b->v_w;
00167 int i, col;
00168 SDL_Rect dst;
00169
00170
00171 dst.w = FONT_W;
00172 dst.h = FONT_H;
00173 dst.x = b->p_rect->x;
00174 dst.y = b->p_rect->y;
00175
00176
00177
00178 SDL_BlitSurface(b->blank, NULL, b->screen, b->p_rect);
00179
00180
00181 for (i = first_char, col = 0; i < last_char; i++) {
00182 int c = b->text[i] - 32;
00183 if (c < 0)
00184 c = 0;
00185 SDL_BlitSurface(b->font, &b->font_rects[c], b->screen, &dst);
00186
00187 dst.x += dst.w;
00188 col++;
00189 if (col >= b->v_w) {
00190 dst.x = b->p_rect->x;
00191 dst.y += dst.h;
00192 col = 0;
00193 }
00194 }
00195 SDL_UpdateRects(b->screen, 1, b->p_rect);
00196 }
00197
00198 void move_message_board(struct board *b, int dy)
00199 {
00200 int cur = b->cur_line + dy;
00201 if (cur < 0)
00202 cur = 0;
00203 else if (cur >= b->v_h - b->p_h)
00204 cur = b->v_h - b->p_h - 1;
00205 b->cur_line = cur;
00206 render_board(b);
00207 }
00208
00209
00210 const char *read_message(const struct board *b)
00211 {
00212 return b->text;
00213 }
00214
00215 int reset_board(struct board *b)
00216 {
00217 memset(b->text, ' ', b->v_w * b->v_h);
00218 b->cur_col = 0;
00219 b->cur_line = 0;
00220 render_board(b);
00221 return 0;
00222 }
00223
00224
00225
00226
00227 int print_message(struct board *b, const char *s)
00228 {
00229 int i, l, row, col;
00230 char *dst;
00231
00232 if (ast_strlen_zero(s))
00233 return 0;
00234
00235 l = strlen(s);
00236 row = 0;
00237 col = b->cur_col;
00238
00239
00240
00241
00242
00243
00244
00245 for (i = 0; i < l; i++) {
00246 switch (s[i]) {
00247 case '\r':
00248 col = 0;
00249 break;
00250 case '\n':
00251 col = 0;
00252 row++;
00253 break;
00254 case '\b':
00255 if (col > 0)
00256 col--;
00257 break;
00258 default:
00259 if (s[i] < 32)
00260 break;
00261 col++;
00262 if (col >= b->v_w) {
00263 col -= b->v_w;
00264 row++;
00265 }
00266 break;
00267 }
00268 }
00269
00270 if (row > 0) {
00271 memcpy(b->text, b->text + row * b->v_w, b->v_w * (b->v_h - row));
00272
00273 dst = b->text + b->v_w * (b->v_h - row - 1) + b->cur_col;
00274 memset(dst, ' ', b->v_w - b->cur_col + b->v_w * row);
00275 }
00276
00277
00278
00279
00280 dst = b->text + b->v_w * (b->v_h - row - 1);
00281 col = b->cur_col;
00282 for (i = 0; i < l; i++) {
00283 switch (s[i]) {
00284 case '\r':
00285 col = 0;
00286 break;
00287 case '\n':
00288 dst[col] = '\0';
00289 col = 0;
00290 dst += b->v_w;
00291 break;
00292 case '\b':
00293 if (col > 0)
00294 col--;
00295 dst[col] = ' ';
00296 break;
00297 default:
00298 if (s[i] < 32)
00299 break;
00300 dst[col] = s[i];
00301 col++;
00302 if (col >= b->v_w) {
00303 col -= b->v_w;
00304 dst += b->v_w;
00305 }
00306 break;
00307 }
00308 }
00309 dst[col] = '\0';
00310 b->cur_col = col;
00311
00312 render_board(b);
00313 return 1;
00314 }
00315
00316 #if 0
00317
00318
00319 static int scroll_message(...)
00320 {
00321 if moving up, scroll text up;
00322 if (gui->message_board.screen_cur > 0)
00323 gui->message_board.screen_cur--;
00324 otherwise scroll text down.
00325 if ((b->screen_cur + b->p_line) < b->board_next) {
00326 gui->message_board.screen_cur++;
00327 #endif
00328
00329 #endif