📄 3ddeskd.cpp
字号:
// ----------------------------------------------------------// 3d Desktop//// Allows you to switch virtual desktops (viewports) in several// 3-dimensional ways.// // I started with a program called "OpenGL cube demo" by Chris// Halsall. It has changed quite dramatically since then but it was// a *huge* help to me. This is my first OpenGL program. It was// coded up starting around Feb/March 2002. Please provide feedback,// fixes, improvements etc. to bard@systemtoolbox.com//// ----------------------------------------------------------//// Copyright (C) 2002 Brad Wasson <bard@systemtoolbox.com>//// This file is part of 3ddesktop.//// 3ddesktop 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, or (at your option)// any later version.//// 3ddesktop 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 3ddesktop; see the file COPYING. If not, write to// the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.//#include <stdio.h>#include <stdlib.h>#include <time.h>#include <string.h>#include <math.h>#include <errno.h>#include <signal.h>#ifndef _GNU_SOURCE#define _GNU_SOURCE#endif#include <getopt.h>#include <sys/types.h>#include <sys/stat.h>#include <syslog.h>#include "3ddesk.h"#include "move.hpp"#include "face.hpp"#include "arrange.hpp"#include "faceset.hpp"#include "xutil.hpp"#include "event.hpp"#include "util.h"#include "win.hpp"#include "message.hpp"// STLusing namespace std;#include <iostream>#include <list>#include <GL/glx.h>#include <GL/gl.h> // OpenGL itself.#include <GL/glu.h> // GLU support library.//#include <GL/glut.h> // GLUT support library.#include <X11/extensions/xf86vmode.h>#include <X11/keysym.h>Config *cfg;typedef unsigned char uchar;// Some global variables.... int do_screenshot = 1;int do_vpswitch = 1;//int goto_face = NO_GOTO;// Our display mode settings.int Light_On = 1;int Blend_On = 0;int Texture_On = 1;int Alpha_Add = 1;int Curr_TexMode = 1;char *TexModesStr[] = {"GL_DECAL","GL_MODULATE","GL_BLEND","GL_REPLACE"};GLint TexModes[] = {GL_DECAL,GL_MODULATE,GL_BLEND,GL_REPLACE};// delay between updates of the movements (in milliseconds)long last_time; // for movement timing// time of last cbrenderscenelong last_renderscene_time = 0;// time of last keypress float last_keypress = 0;// time of next "ghost keypress" when having funfloat next_action = 0;int goto_on_flag = 0;int initiate_destroy = 0; // starts the z offset zoom inVDesktops vdesks;MessageManager msgmgr;// lights// diffuse light//float light_ambient[]= { 1.0f, 1.0f, 1.0f, 1.0f };float light_diffuse[]= { 1.0f, 1.0f, 1.0f, 1.0f }; float light_position[]= { 0.0f, 0.0f, 17.0f, 1.0f };Movement digit_vis;float digit_visibility = 0.0;Movement breathing; // changes the ambient light to look like breathingfloat ambient_value = 2.0;// ambient lightfloat light_ambient2[]= { 1.0f, 1.0f, 1.0f, 1.0f };//float light_diffuse2[]= { 1.0f, 1.0f, 1.0f, 1.0f }; float light_position2[]= { 0.0f, 0.0f, 17.0f, 1.0f };// this contains all the "Face" types and each holds location// information and texture_id. This in turn is manipulated by each// faceset (the coords of each face not the texture_id). This things// lifetime is for the duration of the daemon.FaceSet *face_set = NULL;// this determines the coords of each face in a faceset. it "has-a"// faceset (passed in at creation time). This things lifetime is for// the duration of an arrangement or "mode". Can be deleted and// recreated as another arrangement many times.Arrangement *faces = NULL;// The class that creates the window etc.GLWindow GLWin;// The class that handles events. Manages "Event"'s. EventManager em;Bool end_X_event_loop;enum state_t { STATE_ENTRY, STATE_EXIT, STATE_NORMAL, STATE_GOTO, STATE_SUSPENDED};state_t state = STATE_ENTRY;// prototypes static void goto_face_complete (Event *e);static void switch_desktop_on_exit (Event *e);static void goto_face_begin (Event *e);static void entry_move_start_hook (Event *e);static void exit_move_start_hook (Event *e);static void setup_goto_face(desktop_coords_t goto_coords, desktop_coords_t current_coord, desktop_coords_t current_count);static void calc_fps(void);static void render_scene(void);static void mouse_pressed(unsigned int button);static void key_pressed(KeySym key);static void initialize_arrangements (void);static void set_arrangement (float z_offset_distance);static void begin_exit (void);static desktop_coords_t wait_for_activation(void);static void idle_func(void);static int main_loop(void);static void entry_move_start_hook (Event *e);static void exit_move_start_hook (Event *e);static void gl_init (void);static void initialize_3ddesktop (void);static void load_digits(void);// Some Event hooks// runs when a goto face reaches its destinationstatic void goto_face_complete (Event *e){ //msgout (DEBUG, "-=-=-=-=- goto_face_complete\n"); begin_exit();}// runs when entry movement stopsstatic void goto_face_begin (Event *e){ desktop_coords_t *desktop_to_goto = (desktop_coords_t *)(e->data); state = STATE_GOTO; faces->goto_face (*desktop_to_goto); em.add_event (GOTO_FACE_COMPLETE, goto_face_complete); delete desktop_to_goto;}// runs when exit movement stops if do_vpswitch_early is falsestatic void switch_desktop_on_exit (Event *e){ msgout (DEBUG, "Doing exit VD switch c=%d r=%d\n", faces->get_current_column(), faces->get_current_row() ); vdesks.set_vdesktop (faces->get_current_column(), faces->get_current_row() );}// runs when entry movement startsstatic void entry_move_start_hook (Event *e){ msgout (DEBUG, "################ ENTRY START!\n"); digit_vis.init(&digit_visibility, 0.0, 1.0, 45, Movement::MOVE_TYPE_SMOOTH); faces->entry_movement_start();}// runs when exit movement startsstatic void exit_move_start_hook (Event *e){ msgout (DEBUG, "################ EXIT START!\n"); digit_vis.init(&digit_visibility, 1.0, 0.0, 45, Movement::MOVE_TYPE_SMOOTH); faces->exit_movement_start();}static void setup_goto_face(desktop_coords_t goto_coords, desktop_coords_t current_coord, desktop_coords_t current_count){ msgout (DEBUG, "**** setting up goto = %d x %d\n", goto_coords.column, goto_coords.row); switch (goto_coords.column) { case GOTO_FACE_RIGHT: goto_coords.column = current_coord.column + 1; if (goto_coords.column >= current_count.column) goto_coords.column = 0; break; case GOTO_FACE_LEFT: goto_coords.column = current_coord.column - 1; if (goto_coords.column < 0) goto_coords.column = current_count.column - 1; break; case NO_GOTO: goto_coords.column = current_coord.column; break; default: goto_coords.column--; // change 1 thru max to 0 thru max-1 } switch (goto_coords.row) { case GOTO_FACE_DOWN: goto_coords.row = current_coord.row + 1; if (goto_coords.row >= current_count.row) goto_coords.row = 0; break; case GOTO_FACE_UP: goto_coords.row = current_coord.row - 1; if (goto_coords.row < 0) goto_coords.row = current_count.row - 1; break; case NO_GOTO: goto_coords.row = current_coord.row; break; default: goto_coords.row--; } goto_on_flag = 1; msgout (DEBUG, "**** complete - going with = %d x %d\n", goto_coords.column, goto_coords.row); desktop_coords_t *dc = new desktop_coords_t (goto_coords); if (!dc) { msgout(ERROR, "out of memory\n"); end_program(-1); } em.add_event (ENTRY_MOVEMENT_STOP, goto_face_begin, dc ); } // END setup_goto_facetypedef struct portion_control_s { int inited; int x_segment_size; int y_segment_size; int n_x_seg; int n_y_seg; int current_x_seg; int current_y_seg;} portion_control_t;//#define SCAN_MODE#ifdef SCAN_MODEstatic voidinit_portion_control (portion_control_t *pc){ pc->x_segment_size = 128; pc->y_segment_size = 128; pc->n_x_seg = (int)floor(GLWin.get_screen_width() / pc->x_segment_size); pc->n_y_seg = (int)floor(GLWin.get_screen_height() / pc->y_segment_size); //msgout (DEBUG, "*************** %d x %d\n", pc->n_x_seg, pc->n_y_seg); pc->current_x_seg = 0; pc->current_y_seg = 0; pc->inited = 1;}static voidgrab_portion_of_screen (portion_control_t *pc){ if (!pc->inited) init_portion_control(pc); int x1 = pc->current_x_seg * pc->x_segment_size; int x2 = pc->current_x_seg * pc->x_segment_size + pc->x_segment_size; int y1 = pc->current_y_seg * pc->y_segment_size; int y2 = pc->current_y_seg * pc->y_segment_size + pc->y_segment_size; msgout (DEBUG, "GRABBING segment %d x %d\n", pc->current_x_seg, pc->current_y_seg); GLWin.grab_screenshot_data_portion (x1, y1, x2, y2); pc->current_x_seg++; if (pc->current_x_seg == pc->n_x_seg) { msgout (DEBUG, "reached max X %d\n", pc->n_x_seg); pc->current_x_seg = 0; pc->current_y_seg++; if (pc->current_y_seg == pc->n_y_seg) pc->current_y_seg = 0; } //= get_randomi(0, pc->n_x_seg - 1); //= get_randomi(0, pc->n_y_seg - 1);} // END grab_portion_of_screen #endif // SCAN_MODE // ------// Frames per second (FPS) statistic variables and routine.#define FRAME_RATE_SAMPLES 100int FrameCount = 0;float FrameRate = 0;static void calc_fps(void){ static clock_t last=0; clock_t now; float delta; if (++FrameCount >= FRAME_RATE_SAMPLES) { now = clock(); delta= (now - last) / (float) CLOCKS_PER_SEC; last = now; FrameRate = FRAME_RATE_SAMPLES / delta; FrameCount = 0; }} // END calc_fpsuint digit_texture;static void draw_digits (int r, int c);static void draw_digit (int d);static void draw_digit (int d, float x_trans, float y_trans);static void draw_x (float x_trans, float y_trans);static void set_color (int color, float level);static voidset_color (int color, float level) { switch (color) { case COLOR_RED: glColor4f(level, 0, 0, 0); break; case COLOR_GREEN: glColor4f(0, level, 0, 0); break; case COLOR_BLUE: glColor4f(0, 0, level, 0); break; case COLOR_LIGHTBLUE: glColor4f(0, level, level, 0); break; case COLOR_WHITE: glColor4f(level, level, level, 0); break; case COLOR_GRAY: glColor4f(level/2, level/2, level/2, 0); break; case COLOR_PURPLE: glColor4f(level, 0, level, 0); break; case COLOR_YELLOW: glColor4f(level, level, 0, 0); break; default: // white glColor4f(level, level, level, 0); break; }}static voiddraw_digits (int r, int c){ //draw_digit(r * c); draw_x (GLWin.get_width() / 2, GLWin.get_height() - (cfg->options->digit_size / 2) ); draw_digit (r, GLWin.get_width() / 2 - (cfg->options->digit_size), GLWin.get_height() - (cfg->options->digit_size / 2) ); draw_digit (c, GLWin.get_width() / 2 + (cfg->options->digit_size), GLWin.get_height() - (cfg->options->digit_size / 2) );}static voiddraw_x (float x_trans, float y_trans){ float x1 = .5, y1 = .5, x2 = .75, y2 = .75; float w = cfg->options->digit_size/2.0; // But we like our current view too; so we save it here. glPushMatrix(); // Now we set up a new projection for the text. glLoadIdentity(); glOrtho(0,GLWin.get_width(),0,GLWin.get_height(),-1.0,1.0); glTranslatef(x_trans, y_trans, 0.0f); set_color (cfg->options->digit_color, digit_visibility);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -