Logo Search packages:      
Sourcecode: blender version File versions

MultiTest.c

/**
 * $Id: MultiTest.c,v 1.5 2003/05/01 19:52:17 sirdude Exp $
 * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
 *
 * 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. The Blender
 * Foundation also sells licenses for use in proprietary software under
 * the Blender License.  See http://www.blender.org/BL/ for information
 * about this.
 *
 * 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.
 *
 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
 * All rights reserved.
 *
 * The Original Code is: all of this file.
 *
 * Contributor(s): none yet.
 *
 * ***** END GPL/BL DUAL LICENSE BLOCK *****
 */
#define FALSE 0

#ifdef WIN32

#pragma warning(disable: 4244 4305)
#endif

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <math.h>

#include "GL.h"

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include "MEM_guardedalloc.h"

#include "GHOST_C-api.h"
#include "BMF_Api.h"

#include "Util.h"
#include "Basic.h"
#include "ScrollBar.h"
#include "EventToBuf.h"

#include "WindowData.h"

/***/

typedef struct _MultiTestApp MultiTestApp;
typedef struct _LoggerWindow LoggerWindow;

void loggerwindow_log(LoggerWindow *lw, char *line);

void multitestapp_toggle_extra_window(MultiTestApp *app);
void multitestapp_free_extrawindow(MultiTestApp *app);
LoggerWindow *multitestapp_get_logger(MultiTestApp *app);
GHOST_SystemHandle multitestapp_get_system(MultiTestApp *app);
void multitestapp_exit(MultiTestApp *app);

/**/

void rect_bevel_side(int rect[2][2], int side, float *lt, float *dk, float *col, int width) {
      int ltidx= (side/2)%4;
      int dkidx= (ltidx + 1 + (side&1))%4;
      int i, corner;
      
      glBegin(GL_LINES);
      for (i=0; i<width; i++) {
            float ltf= pow(lt[i], 1.0/2.2), dkf= pow(dk[i], 1.0/2.2);
            float stf= (dkidx>ltidx)?dkf:ltf;
            int lx= rect[1][0]-i-1;
            int ly= rect[0][1]+i;
            
            glColor3f(col[0]*stf, col[1]*stf, col[2]*stf);
            for (corner=0; corner<4; corner++) {
                  int x= (corner==0 || corner==1)?(rect[0][0]+i):(rect[1][0]-i-1);
                  int y= (corner==0 || corner==3)?(rect[0][1]+i):(rect[1][1]-i-1);

                  if (ltidx==corner)
                        glColor3f(col[0]*ltf, col[1]*ltf, col[2]*ltf);
                  if (dkidx==corner)
                        glColor3f(col[0]*dkf, col[1]*dkf, col[2]*dkf);

                  glVertex2i(lx, ly);
                  glVertex2i(lx= x, ly= y);
            }
      }
      glEnd();
      
      glColor3fv(col);
      glRecti(rect[0][0]+width, rect[0][1]+width, rect[1][0]-width, rect[1][1]-width);
}

void rect_bevel_smooth(int rect[2][2], int width) {
      float *lt= malloc(sizeof(*lt)*width);
      float *dk= malloc(sizeof(*dk)*width);
      float col[4];
      int i;
      
      for (i=0; i<width; i++) {
            float v= width-1?((float) i/(width-1)):0;
            lt[i]= 1.2 + (1.0-1.2)*v;
            dk[i]= 0.2 + (1.0-0.2)*v;
      }
      
      glGetFloatv(GL_CURRENT_COLOR, col);
      
      rect_bevel_side(rect, 3, lt, dk, col, width);
      
      free(lt);
      free(dk);
}

      /*
       * MainWindow
       */

typedef struct {
      MultiTestApp            *app;

      GHOST_WindowHandle      win;
      
      int         size[2];
      
      int         lmouse[2], lmbut[3];
      
      int         tmouse[2];
} MainWindow;

static void mainwindow_log(MainWindow *mw, char *str) {
      loggerwindow_log(multitestapp_get_logger(mw->app), str);
}

static void mainwindow_do_draw(MainWindow *mw) {
      GHOST_ActivateWindowDrawingContext(mw->win);
      
      if (mw->lmbut[0]) {
            glClearColor(0.5, 0.5, 0.5, 1);
      } else {
            glClearColor(1, 1, 1, 1);
      }           
      glClear(GL_COLOR_BUFFER_BIT);
      
      glColor3f(0.5, 0.6, 0.8);
      glRecti(mw->tmouse[0]-5, mw->tmouse[1]-5, mw->tmouse[0]+5, mw->tmouse[1]+5);
      
      GHOST_SwapWindowBuffers(mw->win);
}

static void mainwindow_do_reshape(MainWindow *mw) {
      GHOST_RectangleHandle bounds= GHOST_GetClientBounds(mw->win);

      GHOST_ActivateWindowDrawingContext(mw->win);

      mw->size[0]= GHOST_GetWidthRectangle(bounds);
      mw->size[1]= GHOST_GetHeightRectangle(bounds);
      
      glViewport(0, 0, mw->size[0], mw->size[1]);

      glMatrixMode(GL_PROJECTION);
      glLoadIdentity();
      glOrtho(0, mw->size[0], 0, mw->size[1], -1, 1);
      glTranslatef(0.375, 0.375, 0.0);

      glMatrixMode(GL_MODELVIEW);
      glLoadIdentity();
}

static void mainwindow_do_key(MainWindow *mw, GHOST_TKey key, int press) {
      switch(key) {
      case GHOST_kKeyC:
            if (press)
                  GHOST_SetCursorShape(mw->win, (GHOST_TStandardCursor) (rand()%(GHOST_kStandardCursorNumCursors)));
            break;
      case GHOST_kKeyLeftBracket:
            if (press)
                  GHOST_SetCursorVisibility(mw->win, 0);
            break;
      case GHOST_kKeyRightBracket:
            if (press)
                  GHOST_SetCursorVisibility(mw->win, 1);
            break;
      case GHOST_kKeyE:
            if (press)
                  multitestapp_toggle_extra_window(mw->app);
            break;
      case GHOST_kKeyQ:
            if (press)
                  multitestapp_exit(mw->app);
            break;
      case GHOST_kKeyT:
            if (press)
                  mainwindow_log(mw, "TextTest~|`hello`\"world\",<>/");
            break;
      case GHOST_kKeyR:
            if (press) {
                  int i;
                  
                  mainwindow_log(mw, "Invalidating window 10 times");
                  for (i=0; i<10; i++)
                        GHOST_InvalidateWindow(mw->win);
            }
            break;
      case GHOST_kKeyF11:
            if (press) {
                  GHOST_SetWindowOrder(mw->win, GHOST_kWindowOrderBottom);
            }
            break;
      }
}

static void mainwindow_do_move(MainWindow *mw, int x, int y) {
      mw->lmouse[0]= x, mw->lmouse[1]= y;
      
      if (mw->lmbut[0]) {
            mw->tmouse[0]= x, mw->tmouse[1]= y;
            GHOST_InvalidateWindow(mw->win);
      }
}

static void mainwindow_do_button(MainWindow *mw, int which, int press) {
      if (which==GHOST_kButtonMaskLeft) {
            mw->lmbut[0]= press;
            mw->tmouse[0]= mw->lmouse[0], mw->tmouse[1]= mw->lmouse[1];
            GHOST_InvalidateWindow(mw->win);
      } else if (which==GHOST_kButtonMaskLeft) {
            mw->lmbut[1]= press;
      } else if (which==GHOST_kButtonMaskLeft) {
            mw->lmbut[2]= press;
      }
}

static void mainwindow_handle(void *priv, GHOST_EventHandle evt) {
      MainWindow *mw= priv;
      GHOST_TEventType type= GHOST_GetEventType(evt);
      char buf[256];
      
      event_to_buf(evt, buf);
      mainwindow_log(mw, buf);
      
      switch (type) {
      case GHOST_kEventCursorMove: {
            GHOST_TEventCursorData *cd= GHOST_GetEventData(evt);
            int x, y;
            GHOST_ScreenToClient(mw->win, cd->x, cd->y, &x, &y);
            mainwindow_do_move(mw, x, mw->size[1]-y-1);
            break;
      }
      case GHOST_kEventButtonDown:
      case GHOST_kEventButtonUp: {
            GHOST_TEventButtonData *bd= GHOST_GetEventData(evt);
            mainwindow_do_button(mw, bd->button, (type == GHOST_kEventButtonDown));
            break;
      }
      case GHOST_kEventKeyDown:
      case GHOST_kEventKeyUp: {
            GHOST_TEventKeyData *kd= GHOST_GetEventData(evt);
            mainwindow_do_key(mw, kd->key, (type == GHOST_kEventKeyDown));
            break;
      }

      case GHOST_kEventWindowUpdate:
            mainwindow_do_draw(mw);
            break;
      case GHOST_kEventWindowSize:
            mainwindow_do_reshape(mw);
            break;
      }
}

/**/

static void mainwindow_timer_proc(GHOST_TimerTaskHandle task, GHOST_TUns64 time) {
      MainWindow *mw= GHOST_GetTimerTaskUserData(task);
      char buf[64];
      
      sprintf(buf, "timer: %6.2f", (double) ((GHOST_TInt64) time)/1000);
      mainwindow_log(mw, buf);
}

MainWindow *mainwindow_new(MultiTestApp *app) {
      GHOST_SystemHandle sys= multitestapp_get_system(app);
      GHOST_WindowHandle win;
      
      win= GHOST_CreateWindow(sys, "MultiTest:Main", 40, 40, 400, 400, 
            GHOST_kWindowStateNormal, GHOST_kDrawingContextTypeOpenGL, 
            FALSE);
      
      if (win) {
            MainWindow *mw= MEM_callocN(sizeof(*mw), "mainwindow_new");
            mw->app= app;
            mw->win= win;
            
            GHOST_SetWindowUserData(mw->win, windowdata_new(mw, mainwindow_handle));
            
            GHOST_InstallTimer(sys, 1000, 10000, mainwindow_timer_proc, mw);
            
            return mw;
      } else {
            return NULL;
      }
}

void mainwindow_free(MainWindow *mw) {
      GHOST_SystemHandle sys= multitestapp_get_system(mw->app);

      windowdata_free(GHOST_GetWindowUserData(mw->win));
      GHOST_DisposeWindow(sys, mw->win);
      MEM_freeN(mw);
}

      /*
       * LoggerWindow
       */

struct _LoggerWindow {
      MultiTestApp            *app;

      GHOST_WindowHandle      win;
      
      BMF_Font    *font;
      int               fonttexid;
      int               fontheight;
      
      int               size[2];
      
      int               ndisplines;
      int               textarea[2][2];
      ScrollBar   *scroll;
      
      char        **loglines;
      int               nloglines, logsize;
      
      int               lmbut[3];
      int               lmouse[2];
};

#define SCROLLBAR_PAD 2
#define SCROLLBAR_WIDTH 14
#define TEXTAREA_PAD 2
static void loggerwindow_recalc_regions(LoggerWindow *lw) {
      int nscroll[2][2];
      
      nscroll[0][0]= SCROLLBAR_PAD;
      nscroll[0][1]= SCROLLBAR_PAD;
      nscroll[1][0]= nscroll[0][0] + SCROLLBAR_WIDTH;
      nscroll[1][1]= lw->size[1] - SCROLLBAR_PAD - 1;

      lw->textarea[0][0]= nscroll[1][0] + TEXTAREA_PAD;
      lw->textarea[0][1]= TEXTAREA_PAD;
      lw->textarea[1][0]= lw->size[0] - TEXTAREA_PAD - 1;
      lw->textarea[1][1]= lw->size[1] - TEXTAREA_PAD - 1;

      lw->ndisplines= (lw->textarea[1][1]-lw->textarea[0][1])/lw->fontheight;

      scrollbar_set_thumbpct(lw->scroll, (float) lw->ndisplines/lw->nloglines);
      scrollbar_set_rect(lw->scroll, nscroll);
}

static void loggerwindow_setup_window_gl(LoggerWindow *lw) {
      glViewport(0, 0, lw->size[0], lw->size[1]);

      glMatrixMode(GL_PROJECTION);
      glLoadIdentity();
      glOrtho(0, lw->size[0], 0, lw->size[1], -1, 1);
      glTranslatef(0.375, 0.375, 0.0);

      glMatrixMode(GL_MODELVIEW);
      glLoadIdentity();
}

static void loggerwindow_do_reshape(LoggerWindow *lw) {
      GHOST_RectangleHandle bounds= GHOST_GetClientBounds(lw->win);

      GHOST_ActivateWindowDrawingContext(lw->win);
      
      lw->size[0]= GHOST_GetWidthRectangle(bounds);
      lw->size[1]= GHOST_GetHeightRectangle(bounds);
      
      loggerwindow_recalc_regions(lw);
      loggerwindow_setup_window_gl(lw);
}

static void loggerwindow_do_draw(LoggerWindow *lw) {
      int i, ndisplines, startline;
      int sb_rect[2][2], sb_thumb[2][2];
            
      GHOST_ActivateWindowDrawingContext(lw->win);
      
      glClearColor(1, 1, 1, 1);
      glClear(GL_COLOR_BUFFER_BIT);

      glColor3f(0.8, 0.8, 0.8);
      rect_bevel_smooth(lw->textarea, 4);
      
      scrollbar_get_rect(lw->scroll, sb_rect);
      scrollbar_get_thumb(lw->scroll, sb_thumb);
      
      glColor3f(0.6, 0.6, 0.6);
      rect_bevel_smooth(sb_rect, 1);
      
      if (scrollbar_is_scrolling(lw->scroll)) {
            glColor3f(0.6, 0.7, 0.5);
      } else {
            glColor3f(0.9, 0.9, 0.92);
      }
      rect_bevel_smooth(sb_thumb, 1);
      
      startline= scrollbar_get_thumbpos(lw->scroll)*(lw->nloglines-1);
      ndisplines= min_i(lw->ndisplines, lw->nloglines-startline);

      if (lw->fonttexid!=-1) {
            glBindTexture(GL_TEXTURE_2D, lw->fonttexid);
            
            glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
            glEnable(GL_BLEND);
            glEnable(GL_TEXTURE_2D);            
      }
      glColor3f(0, 0, 0);
      for (i=0; i<ndisplines; i++) {
                  /* stored in reverse order */
            char *line= lw->loglines[(lw->nloglines-1)-(i+startline)];
            int x_pos= lw->textarea[0][0] + 4;
            int y_pos= lw->textarea[0][1] + 4 + i*lw->fontheight;
            
            if (lw->fonttexid==-1) {
                  glRasterPos2i(x_pos, y_pos);
                  BMF_DrawString(lw->font, line);
            } else {
                  BMF_DrawStringTexture(lw->font, line, x_pos, y_pos, 0.0);
            }
      }
      if (lw->fonttexid!=-1) {
            glDisable(GL_TEXTURE_2D);           
            glDisable(GL_BLEND);
      }

      GHOST_SwapWindowBuffers(lw->win);
}

static void loggerwindow_do_move(LoggerWindow *lw, int x, int y) {
      lw->lmouse[0]= x, lw->lmouse[1]= y;
      
      if (scrollbar_is_scrolling(lw->scroll)) {
            scrollbar_keep_scrolling(lw->scroll, y);
            GHOST_InvalidateWindow(lw->win);
      }
}

static void loggerwindow_do_button(LoggerWindow *lw, int which, int press) {
      if (which==GHOST_kButtonMaskLeft) {
            lw->lmbut[0]= press;
            
            if (press) {
                  if (scrollbar_contains_pt(lw->scroll, lw->lmouse)) {
                        scrollbar_start_scrolling(lw->scroll, lw->lmouse[1]);                   
                        GHOST_SetCursorShape(lw->win, GHOST_kStandardCursorUpDown);
                        GHOST_InvalidateWindow(lw->win);
                  }
            } else {
                  if (scrollbar_is_scrolling(lw->scroll)) {
                        scrollbar_stop_scrolling(lw->scroll);
                        GHOST_SetCursorShape(lw->win, GHOST_kStandardCursorDefault);
                        GHOST_InvalidateWindow(lw->win);
                  }
            }
      } else if (which==GHOST_kButtonMaskMiddle) {
            lw->lmbut[1]= press;
      } else if (which==GHOST_kButtonMaskRight) {
            lw->lmbut[2]= press;
      }
}

static void loggerwindow_do_key(LoggerWindow *lw, GHOST_TKey key, int press) {
      switch (key) {
      case GHOST_kKeyQ:
            if (press)
                  multitestapp_exit(lw->app);
            break;
      }
}

static void loggerwindow_handle(void *priv, GHOST_EventHandle evt) {
      LoggerWindow *lw= priv;
      GHOST_TEventType type= GHOST_GetEventType(evt);
      
      switch(type) {
      case GHOST_kEventCursorMove: {
            GHOST_TEventCursorData *cd= GHOST_GetEventData(evt);
            int x, y;
            GHOST_ScreenToClient(lw->win, cd->x, cd->y, &x, &y);
            loggerwindow_do_move(lw, x, lw->size[1]-y-1);
            break;
      }
      case GHOST_kEventButtonDown:
      case GHOST_kEventButtonUp: {
            GHOST_TEventButtonData *bd= GHOST_GetEventData(evt);
            loggerwindow_do_button(lw, bd->button, (type == GHOST_kEventButtonDown));
            break;
      }
      case GHOST_kEventKeyDown:
      case GHOST_kEventKeyUp: {
            GHOST_TEventKeyData *kd= GHOST_GetEventData(evt);
            loggerwindow_do_key(lw, kd->key, (type == GHOST_kEventKeyDown));
            break;
      }
            
      case GHOST_kEventWindowUpdate:
            loggerwindow_do_draw(lw);
            break;
      case GHOST_kEventWindowSize:
            loggerwindow_do_reshape(lw);
            break;
      }
}

/**/

LoggerWindow *loggerwindow_new(MultiTestApp *app) {
      GHOST_SystemHandle sys= multitestapp_get_system(app);
      GHOST_TUns32 screensize[2];
      GHOST_WindowHandle win;
      
      GHOST_GetMainDisplayDimensions(sys, &screensize[0], &screensize[1]);
      win= GHOST_CreateWindow(sys, "MultiTest:Logger", 40, screensize[1]-432,
            800, 300, GHOST_kWindowStateNormal, 
            GHOST_kDrawingContextTypeOpenGL, FALSE);
      
      if (win) {
            LoggerWindow *lw= MEM_callocN(sizeof(*lw), "loggerwindow_new");
            int bbox[2][2];
            lw->app= app;
            lw->win= win;
            
            lw->font= BMF_GetFont(BMF_kScreen12);
            lw->fonttexid= BMF_GetFontTexture(lw->font);

            BMF_GetBoundingBox(lw->font, &bbox[0][0], &bbox[0][1], &bbox[1][0], &bbox[1][1]);
            lw->fontheight= rect_height(bbox);
            
            lw->nloglines= lw->logsize= 0;
            lw->loglines= MEM_mallocN(sizeof(*lw->loglines)*lw->nloglines, "loglines");
            
            lw->scroll= scrollbar_new(2, 40);
            
            GHOST_SetWindowUserData(lw->win, windowdata_new(lw, loggerwindow_handle));

            loggerwindow_do_reshape(lw);

            return lw;
      } else {
            return NULL;
      }
}

void loggerwindow_log(LoggerWindow *lw, char *line) {
      if (lw->nloglines==lw->logsize) {
            lw->loglines= memdbl(lw->loglines, &lw->logsize, sizeof(*lw->loglines));
      }
      
      lw->loglines[lw->nloglines++]= string_dup(line);
      scrollbar_set_thumbpct(lw->scroll, (float) lw->ndisplines/lw->nloglines);
      
      GHOST_InvalidateWindow(lw->win);
}

void loggerwindow_free(LoggerWindow *lw) {
      GHOST_SystemHandle sys= multitestapp_get_system(lw->app);
      int i;

      for (i=0; i<lw->nloglines; i++) {
            MEM_freeN(lw->loglines[i]);
      }
      MEM_freeN(lw->loglines);
      
      windowdata_free(GHOST_GetWindowUserData(lw->win));
      GHOST_DisposeWindow(sys, lw->win);
      MEM_freeN(lw);
}

      /*
       * ExtraWindow
       */


typedef struct {
      MultiTestApp            *app;

      GHOST_WindowHandle      win;
      
      int         size[2];
} ExtraWindow;

static void extrawindow_do_draw(ExtraWindow *ew) {
      GHOST_ActivateWindowDrawingContext(ew->win);

      glClearColor(1, 1, 1, 1);
      glClear(GL_COLOR_BUFFER_BIT);
      
      glColor3f(0.8, 0.8, 0.8);
      glRecti(10, 10, ew->size[0]-10, ew->size[1]-10);
      
      GHOST_SwapWindowBuffers(ew->win);
}

static void extrawindow_do_reshape(ExtraWindow *ew) {
      GHOST_RectangleHandle bounds= GHOST_GetClientBounds(ew->win);

      GHOST_ActivateWindowDrawingContext(ew->win);

      ew->size[0]= GHOST_GetWidthRectangle(bounds);
      ew->size[1]= GHOST_GetHeightRectangle(bounds);
      
      glViewport(0, 0, ew->size[0], ew->size[1]);

      glMatrixMode(GL_PROJECTION);
      glLoadIdentity();
      glOrtho(0, ew->size[0], 0, ew->size[1], -1, 1);
      glTranslatef(0.375, 0.375, 0.0);

      glMatrixMode(GL_MODELVIEW);
      glLoadIdentity();
}

static void extrawindow_do_key(ExtraWindow *ew, GHOST_TKey key, int press) {
      switch (key) {
      case GHOST_kKeyE:
            if (press)
                  multitestapp_toggle_extra_window(ew->app);
            break;
      }
}

static void extrawindow_spin_cursor(ExtraWindow *ew, GHOST_TUns64 time) {
      GHOST_TUns8 bitmap[16][2];
      GHOST_TUns8 mask[16][2];
      double ftime= (double) ((GHOST_TInt64) time)/1000;
      float angle= fmod(ftime, 1.0) * 3.1415*2;
      int i;
      
      memset(&bitmap, 0, sizeof(bitmap));
      memset(&mask, 0, sizeof(mask));
      
      bitmap[0][0] |= mask[0][0] |= 0xF;
      bitmap[1][0] |= mask[1][0] |= 0xF;
      bitmap[2][0] |= mask[2][0] |= 0xF;
      bitmap[3][0] |= mask[3][0] |= 0xF;
      
      for (i=0; i<7; i++) {
            int x = 7 + cos(angle)*i;
            int y = 7 + sin(angle)*i;
            
            mask[y][x/8] |= (1 << (x%8));
      }
      for (i=0; i<64; i++) {
            float v= (i/63.0) * 3.1415*2;
            int x = 7 + cos(v)*7;
            int y = 7 + sin(v)*7;
            
            mask[y][x/8] |= (1 << (x%8));
      }
      
      GHOST_SetCustomCursorShape(ew->win, bitmap, mask, 0, 0);
}

static void extrawindow_handle(void *priv, GHOST_EventHandle evt) {
      ExtraWindow *ew= priv;
      GHOST_TEventType type= GHOST_GetEventType(evt);
      char buf[256];
      
      event_to_buf(evt, buf);
      loggerwindow_log(multitestapp_get_logger(ew->app), buf);
      
      switch (type) {
      case GHOST_kEventKeyDown:
      case GHOST_kEventKeyUp: {
            GHOST_TEventKeyData *kd= GHOST_GetEventData(evt);
            extrawindow_do_key(ew, kd->key, (type == GHOST_kEventKeyDown));
            break;
      }

      case GHOST_kEventCursorMove: {
            extrawindow_spin_cursor(ew, GHOST_GetEventTime(evt));
            break;
      }
      
      case GHOST_kEventWindowClose:
            multitestapp_free_extrawindow(ew->app);
            break;
      case GHOST_kEventWindowUpdate:
            extrawindow_do_draw(ew);
            break;
      case GHOST_kEventWindowSize:
            extrawindow_do_reshape(ew);
            break;
      }
}

/**/

ExtraWindow *extrawindow_new(MultiTestApp *app) {
      GHOST_SystemHandle sys= multitestapp_get_system(app);
      GHOST_WindowHandle win;
      
      win= GHOST_CreateWindow(sys, "MultiTest:Extra", 500, 40, 400, 400, 
            GHOST_kWindowStateNormal, GHOST_kDrawingContextTypeOpenGL,
            FALSE);
      
      if (win) {
            ExtraWindow *ew= MEM_callocN(sizeof(*ew), "mainwindow_new");
            ew->app= app;
            ew->win= win;
            
            GHOST_SetWindowUserData(ew->win, windowdata_new(ew, extrawindow_handle));
            
            return ew;
      } else {
            return NULL;
      }
}

void extrawindow_free(ExtraWindow *ew) {
      GHOST_SystemHandle sys= multitestapp_get_system(ew->app);

      windowdata_free(GHOST_GetWindowUserData(ew->win));
      GHOST_DisposeWindow(sys, ew->win);
      MEM_freeN(ew);
}

      /*
       * MultiTestApp
       */
      
struct _MultiTestApp {
      GHOST_SystemHandle      sys;
      MainWindow              *main;
      LoggerWindow            *logger;
      ExtraWindow             *extra;
      
      int                           exit;
};

static int multitest_event_handler(GHOST_EventHandle evt, GHOST_TUserDataPtr data) {
      MultiTestApp *app= data;
      GHOST_WindowHandle win;
      
      win= GHOST_GetEventWindow(evt);
      if (win && !GHOST_ValidWindow(app->sys, win)) {
            loggerwindow_log(app->logger, "WARNING: bad event, non-valid window\n");
            return 1;
      }
            
      if (win) {
            WindowData *wb= GHOST_GetWindowUserData(win);
            
            windowdata_handle(wb, evt);
      } else {
            GHOST_TEventType type= GHOST_GetEventType(evt);
            
                  /* GHOST_kEventQuit are the only 'system' events,
                   * that is, events without a window.
                   */
            switch(type) {
            case GHOST_kEventQuit:
                  app->exit= 1;
                  break;
                  
            default:
                  fatal("Unhandled system event: %d (%s)\n", type, eventtype_to_string(type));
                  break;
            }
      }
      
      return 1;
}

/**/

MultiTestApp *multitestapp_new(void) {
      MultiTestApp *app= MEM_mallocN(sizeof(*app), "multitestapp_new");
      GHOST_EventConsumerHandle consumer= GHOST_CreateEventConsumer(multitest_event_handler, app);
      
      app->sys= GHOST_CreateSystem();
      if (!app->sys)
            fatal("Unable to create ghost system");

      if (!GHOST_AddEventConsumer(app->sys, consumer))      
            fatal("Unable to add multitest event consumer ");
            
      app->main= mainwindow_new(app);
      if (!app->main) 
            fatal("Unable to create main window");
            
      app->logger= loggerwindow_new(app);
      if (!app->logger)
            fatal("Unable to create logger window");

      app->extra= NULL;       
      app->exit= 0;
      
      return app;
}

LoggerWindow *multitestapp_get_logger(MultiTestApp *app) {
      return app->logger;     
}

GHOST_SystemHandle multitestapp_get_system(MultiTestApp *app) {
      return app->sys;
}

void multitestapp_free_extrawindow(MultiTestApp *app) {
      extrawindow_free(app->extra);
      app->extra= NULL;
}

void multitestapp_toggle_extra_window(MultiTestApp *app) {
      if (app->extra) {
            multitestapp_free_extrawindow(app);
      } else {
            app->extra= extrawindow_new(app);
      }
}

void multitestapp_exit(MultiTestApp *app) {
      app->exit= 1;
}

void multitestapp_run(MultiTestApp *app) {
      while (!app->exit) {
            GHOST_ProcessEvents(app->sys, 1);
            GHOST_DispatchEvents(app->sys);
      }
}

void multitestapp_free(MultiTestApp *app) {
      mainwindow_free(app->main);
      loggerwindow_free(app->logger);
      GHOST_DisposeSystem(app->sys);
      MEM_freeN(app);
}

      /***/
      
int main(int argc, char **argv) {
      MultiTestApp *app= multitestapp_new();
      
      multitestapp_run(app);
      multitestapp_free(app);
      
      return 0;
}

Generated by  Doxygen 1.6.0   Back to index