(no commit message)
[blender-staging.git] / source / blender / src / toets.c
1 /**
2  *
3  * ***** BEGIN GPL LICENSE BLOCK *****
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software Foundation,
17  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18  *
19  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
20  * All rights reserved.
21  *
22  * The Original Code is: all of this file.
23  *
24  * Contributor(s): none yet.
25  *
26  * ***** END GPL LICENSE BLOCK *****
27
28  *
29  *
30  * General blender hot keys (toets = dutch), special hotkeys are in space.c
31  *
32  */
33
34 #include <string.h>
35 #include <math.h>
36
37 #ifdef WIN32
38 #include "BLI_winstuff.h"
39 #endif
40
41 #include "MEM_guardedalloc.h"
42
43 #include "PIL_time.h"
44
45 #include "nla.h"        /* Only for the #ifdef flag - To be removed later */
46
47 #include "BLI_blenlib.h"
48 #include "BLI_arithb.h"
49
50 #include "DNA_object_types.h"
51 #include "DNA_screen_types.h"
52 #include "DNA_scene_types.h"
53 #include "DNA_space_types.h"
54 #include "DNA_view3d_types.h"
55 #include "DNA_userdef_types.h"
56
57 #include "BKE_action.h"
58 #include "BKE_anim.h"
59 #include "BKE_blender.h"
60 #include "BKE_depsgraph.h"
61 #include "BKE_displist.h"
62 #include "BKE_global.h"
63 #include "BKE_image.h"
64 #include "BKE_ipo.h"
65 #include "BKE_key.h"
66 #include "BKE_object.h"
67 #include "BKE_pointcache.h"
68 #include "BKE_scene.h"
69 #include "BKE_utildefines.h"
70
71 #include "BIF_butspace.h"
72 #include "BIF_editseq.h"
73 #include "BIF_editsound.h"
74 #include "BIF_editmesh.h"
75 #include "BIF_imasel.h"
76 #include "BIF_editparticle.h"
77 #include "BIF_interface.h"
78 #include "BIF_keyframing.h"
79 #include "BIF_poseobject.h"
80 #include "BIF_previewrender.h"
81 #include "BIF_renderwin.h"
82 #include "BIF_retopo.h"
83 #include "BIF_screen.h"
84 #include "BIF_space.h"
85 #include "BIF_toets.h"
86 #include "BIF_toolbox.h"
87 #include "BIF_usiblender.h"
88 #include "BIF_writeimage.h"
89
90 #include "BDR_sculptmode.h"
91 #include "BDR_vpaint.h"
92 #include "BDR_editobject.h"
93 #include "BDR_editface.h"
94
95 #include "BSE_filesel.h"        /* For activate_fileselect */
96 #include "BSE_drawview.h"       /* For play_anim */
97 #include "BSE_view.h"
98 #include "BSE_edit.h"
99 #include "BSE_editipo.h"
100 #include "BSE_headerbuttons.h"
101 #include "BSE_seqaudio.h"
102
103 #include "blendef.h"
104
105 #include "IMB_imbuf.h"
106 #include "IMB_imbuf_types.h"
107
108 #include "GPU_draw.h"
109
110 #include "mydevice.h"
111
112 #include "transform.h"
113
114 #define VIEW_ZOOM_OUT_FACTOR (1.15f)
115 #define VIEW_ZOOM_IN_FACTOR (1.0f/VIEW_ZOOM_OUT_FACTOR)
116
117 /* ------------------------------------------------------------------------- */
118
119 static int is_an_active_object(void *ob) {
120         Base *base;
121         
122         for (base= FIRSTBASE; base; base= base->next)
123                 if (base->object == ob)
124                         return 1;
125         
126         return 0;
127 }
128
129 /* run when pressing 1,3 or 7 */
130 static void axis_set_view(float q1, float q2, float q3, float q4, short view, int perspo)
131 {
132         float new_quat[4];
133         new_quat[0]= q1; new_quat[1]= q2;
134         new_quat[2]= q3; new_quat[3]= q4;
135         G.vd->view=0;
136         
137         if (G.vd->persp==V3D_CAMOB && G.vd->camera) {
138                 /* Is this switching from a camera view ? */
139                 float orig_ofs[3];
140                 float orig_lens= G.vd->lens;
141                 VECCOPY(orig_ofs, G.vd->ofs);
142                 view_settings_from_ob(G.vd->camera, G.vd->ofs, G.vd->viewquat, &G.vd->dist, &G.vd->lens);
143                 
144                 if (U.uiflag & USER_AUTOPERSP) G.vd->persp= V3D_ORTHO;
145                 else if(G.vd->persp==V3D_CAMOB) G.vd->persp= perspo;
146                 
147                 smooth_view(G.vd, orig_ofs, new_quat, NULL, &orig_lens);
148         } else {
149                 
150                 if (U.uiflag & USER_AUTOPERSP) G.vd->persp= V3D_ORTHO;
151                 else if(G.vd->persp==V3D_CAMOB) G.vd->persp= perspo;
152                 
153                 smooth_view(G.vd, NULL, new_quat, NULL, NULL);
154         }
155         G.vd->view= view;
156 }
157
158 void persptoetsen(unsigned short event)
159 {
160         static Object *oldcamera=0;
161         float phi, si, q1[4], vec[3];
162         static int perspo=V3D_PERSP;
163         int preview3d_event= 1;
164         short mouseloc[2];
165         
166         float new_dist, orig_ofs[3];
167         
168         /* Use this to test if we started out with a camera */
169         Object *act_cam_orig=NULL;
170         if (G.vd->persp == V3D_CAMOB)
171                 act_cam_orig = G.vd->camera;
172         
173         if(event==PADENTER) {
174                 if (G.qual == LR_SHIFTKEY) {
175                         view3d_set_1_to_1_viewborder(G.vd);
176                 } else {
177                         if (G.vd->persp==V3D_CAMOB) {
178                                 G.vd->camzoom= 0;
179                         } else {
180                                 new_dist = 10.0;
181                                 smooth_view(G.vd, NULL, NULL, &new_dist, NULL);
182                         }
183                 }
184         }
185         else if((G.qual & (LR_SHIFTKEY | LR_CTRLKEY)) && (event != PAD0)) {
186                 
187                 /* Indicate that this view is inverted,
188                  * but only if it actually _was_ inverted (jobbe) */
189                 if (event==PAD7 || event == PAD1 || event == PAD3)
190                         G.vd->flag2 |= V3D_OPP_DIRECTION_NAME;
191                 
192                 if(event==PAD0) {
193                         /* G.vd->persp= 3; */
194                 }
195                 else if(event==PAD7) {
196                         axis_set_view(0.0, -1.0, 0.0, 0.0, 7, perspo);
197                 }
198                 else if(event==PAD1) {
199                         axis_set_view(0.0, 0.0, (float)-cos(M_PI/4.0), (float)-cos(M_PI/4.0), 1, perspo);
200                 }
201                 else if(event==PAD3) {
202                         axis_set_view(0.5, -0.5, 0.5, 0.5, 3, perspo);
203                 }
204                 else if(event==PADMINUS) {
205                         /* this min and max is also in viewmove() */
206                         if(G.vd->persp==V3D_CAMOB) {
207                                 G.vd->camzoom-= 10;
208                                 if(G.vd->camzoom<-30) G.vd->camzoom= -30;
209                         }
210                         else if(G.vd->dist<10.0*G.vd->far) G.vd->dist*=1.2f;
211                 }
212                 else if(event==PADPLUSKEY) {
213                         if(G.vd->persp==V3D_CAMOB) {
214                                 G.vd->camzoom+= 10;
215                                 if(G.vd->camzoom>300) G.vd->camzoom= 300;
216                         }
217                         else if(G.vd->dist> 0.001*G.vd->grid) G.vd->dist*=.83333f;
218                 }
219                 else {
220
221                         initgrabz(0.0, 0.0, 0.0);
222                         
223                         if(event==PAD6) window_to_3d(vec, -32, 0);
224                         else if(event==PAD4) window_to_3d(vec, 32, 0);
225                         else if(event==PAD8) window_to_3d(vec, 0, -25);
226                         else if(event==PAD2) window_to_3d(vec, 0, 25);
227                         G.vd->ofs[0]+= vec[0];
228                         G.vd->ofs[1]+= vec[1];
229                         G.vd->ofs[2]+= vec[2];
230                 }
231         }
232         else {
233                 /* Indicate that this view is not inverted.
234                  * Don't do this for PADMINUS/PADPLUSKEY/PAD5, though. (jobbe)*/
235                 if (! ELEM3(event, PADMINUS, PADPLUSKEY, PAD5) )
236                         G.vd->flag2 &= ~V3D_OPP_DIRECTION_NAME;
237                 
238
239                 if(event==PAD7) {
240                         axis_set_view(1.0, 0.0, 0.0, 0.0, 7, perspo);
241                 }
242                 else if(event==PAD1) {
243                         axis_set_view((float)cos(M_PI/4.0), (float)-sin(M_PI/4.0), 0.0, 0.0, 1, perspo);
244                 }
245                 else if(event==PAD3) {
246                         axis_set_view(0.5, -0.5, -0.5, -0.5, 3, perspo);
247                 }
248                 else if(event==PADMINUS) {
249                         /* this min and max is also in viewmove() */
250                         if(G.vd->persp==V3D_CAMOB) {
251                                 G.vd->camzoom= MAX2(-30, G.vd->camzoom-5);
252                         }
253                         else if(G.vd->dist<10.0*G.vd->far) {
254                                 getmouseco_areawin(mouseloc);
255                                 view_zoom_mouseloc(VIEW_ZOOM_OUT_FACTOR, mouseloc);
256                         }
257                         if(G.vd->persp!=V3D_PERSP) preview3d_event= 0;
258                 }
259                 else if(event==PADPLUSKEY) {
260                         if(G.vd->persp==V3D_CAMOB) {
261                                 G.vd->camzoom= MIN2(300, G.vd->camzoom+5);
262                         }
263                         else if(G.vd->dist> 0.001*G.vd->grid) {
264                                 getmouseco_areawin(mouseloc);
265                                 view_zoom_mouseloc(VIEW_ZOOM_IN_FACTOR, mouseloc);
266                         }
267                         if(G.vd->persp!=V3D_PERSP) preview3d_event= 0;
268                 }
269                 else if(event==PAD5) {
270                         if (U.smooth_viewtx) {
271                                 if(G.vd->persp==V3D_PERSP) { G.vd->persp=V3D_ORTHO;
272                                 } else if (act_cam_orig) {
273                                         /* were from a camera view */
274                                         float orig_dist= G.vd->dist;
275                                         float orig_lens= G.vd->lens;
276                                         VECCOPY(orig_ofs, G.vd->ofs);
277
278                                         G.vd->persp=V3D_PERSP;
279                                         G.vd->dist= 0.0;
280
281                                         view_settings_from_ob(act_cam_orig, G.vd->ofs, NULL, NULL, &G.vd->lens);
282                                         
283                                         smooth_view(G.vd, orig_ofs, NULL, &orig_dist, &orig_lens);
284                                         
285                                 } else {
286                                         G.vd->persp=V3D_PERSP;
287                                 }
288                         } else {
289                                 if(G.vd->persp==V3D_PERSP) G.vd->persp=V3D_ORTHO;
290                                 else G.vd->persp=V3D_PERSP;
291                         }
292                 }
293                 else if(event==PAD0) {
294                         /* lastview -  */
295                         if(G.vd->persp != V3D_CAMOB) {
296                                 /* store settings of current view before allowing overwriting with camera view */
297                                 QUATCOPY(G.vd->lviewquat, G.vd->viewquat);
298                                 G.vd->lview= G.vd->view;
299                                 G.vd->lpersp= G.vd->persp;
300                         }
301                         else {
302                                 /* return to settings of last view */
303                                 axis_set_view(G.vd->lviewquat[0], G.vd->lviewquat[1], G.vd->lviewquat[2], G.vd->lviewquat[3], G.vd->lview, G.vd->lpersp);
304                         }
305                         
306                         if(G.qual==LR_ALTKEY) {
307                                 if(oldcamera && is_an_active_object(oldcamera)) {
308                                         G.vd->camera= oldcamera;
309                                 }
310                                 handle_view3d_lock();
311                         }
312                         else if(BASACT) {
313                                 /* check both G.vd as G.scene cameras */
314                                 if(G.qual==LR_CTRLKEY) {
315                                         if(G.vd->camera != OBACT || G.scene->camera != OBACT) {
316                                                 if(G.vd->camera && G.vd->camera->type==OB_CAMERA)
317                                                         oldcamera= G.vd->camera;
318                                                 
319                                                 G.vd->camera= OBACT;
320                                                 handle_view3d_lock();
321                                         }
322                                 }
323                                 else if((G.vd->camera==NULL || G.scene->camera==NULL) && OBACT->type==OB_CAMERA) {
324                                         G.vd->camera= OBACT;
325                                         handle_view3d_lock();
326                                 }
327                         }
328                         
329                         if(G.vd->camera==0) {
330                                 G.vd->camera= scene_find_camera(G.scene);
331                                 handle_view3d_lock();
332                         }
333                         
334                         if(G.vd->camera && (G.vd->camera != act_cam_orig)) {
335                                 G.vd->persp= V3D_CAMOB;
336                                 G.vd->view= 0;
337                                 
338                                 if(((G.qual & LR_CTRLKEY) && (G.qual & LR_ALTKEY)) || (G.qual & LR_SHIFTKEY)) {
339                                         void setcameratoview3d(void);   // view.c
340                                         setcameratoview3d();
341                                         autokeyframe_ob_cb_func(G.scene->camera, TFM_TRANSLATION|TFM_ROTATION);
342                                         DAG_object_flush_update(G.scene, G.scene->camera, OB_RECALC_OB);
343                                         BIF_undo_push("View to Camera position");
344                                         allqueue(REDRAWVIEW3D, 0);
345                                 
346                                 } else if (U.smooth_viewtx) {
347                                         /* move 3d view to camera view */
348                                         float orig_lens = G.vd->lens;
349                                         VECCOPY(orig_ofs, G.vd->ofs);
350                                         
351                                         if (act_cam_orig)
352                                                 view_settings_from_ob(act_cam_orig, G.vd->ofs, G.vd->viewquat, &G.vd->dist, &G.vd->lens);
353                                         
354                                         smooth_view_to_camera(G.vd);
355                                         VECCOPY(G.vd->ofs, orig_ofs);
356                                         G.vd->lens = orig_lens;
357                                 }
358                         }
359                 }
360                 else if(event==PAD9) {
361                         countall();
362                         update_for_newframe();
363                         
364                         reset_slowparents();    /* editobject.c */
365                 }
366                 else if(G.vd->persp != V3D_CAMOB) {
367                         if(event==PAD4 || event==PAD6) {
368                                 /* z-axis */
369                                 phi= (float)(M_PI/360.0)*U.pad_rot_angle;
370                                 if(event==PAD6) phi= -phi;
371                                 si= (float)sin(phi);
372                                 q1[0]= (float)cos(phi);
373                                 q1[1]= q1[2]= 0.0;
374                                 q1[3]= si;
375                                 QuatMul(G.vd->viewquat, G.vd->viewquat, q1);
376                                 G.vd->view= 0;
377                         }
378                         if(event==PAD2 || event==PAD8) {
379                                 /* horizontal axis */
380                                 VECCOPY(q1+1, G.vd->viewinv[0]);
381                                 
382                                 Normalize(q1+1);
383                                 phi= (float)(M_PI/360.0)*U.pad_rot_angle;
384                                 if(event==PAD2) phi= -phi;
385                                 si= (float)sin(phi);
386                                 q1[0]= (float)cos(phi);
387                                 q1[1]*= si;
388                                 q1[2]*= si;
389                                 q1[3]*= si;
390                                 QuatMul(G.vd->viewquat, G.vd->viewquat, q1);
391                                 G.vd->view= 0;
392                         }
393                 }
394
395                 if(G.vd->persp != V3D_CAMOB) perspo= G.vd->persp;
396         }
397
398         if(G.vd->depths) G.vd->depths->damaged= 1;
399         retopo_queue_updates(G.vd);
400         
401         if(preview3d_event) 
402                 BIF_view3d_previewrender_signal(curarea, PR_DBASE|PR_DISPRECT);
403         else
404                 BIF_view3d_previewrender_signal(curarea, PR_PROJECTED);
405
406         scrarea_queue_redraw(curarea);
407 }
408
409 int untitled(char * name)
410 {
411         if (G.save_over == 0 ) {
412                 char * c= BLI_last_slash(name);
413                 
414                 if (c)
415                         strcpy(&c[1], "untitled.blend");
416                 else
417                         strcpy(name, "untitled.blend");
418                         
419                 return(TRUE);
420         }
421         
422         return(FALSE);
423 }
424
425 char *recent_filelist(void)
426 {
427         struct RecentFile *recent;
428         int event, i, ofs;
429         char pup[2048], *p;
430
431         p= pup + sprintf(pup, "Open Recent%%t");
432         
433         if (G.sce[0]) {
434                 p+= sprintf(p, "|%s %%x%d", G.sce, 1);
435                 ofs = 1;
436         } else ofs = 0;
437
438         for (recent = G.recent_files.first, i=0; (i<U.recent_files) && (recent); recent = recent->next, i++) {
439                 if (strcmp(recent->filename, G.sce)) {
440                         p+= sprintf(p, "|%s %%x%d", recent->filename, i+ofs+1);
441                 }
442         }
443         event= pupmenu(pup);
444         if(event>0) {
445                 if (ofs && (event==1))
446                         return(G.sce);
447                 else
448                         recent = BLI_findlink(&(G.recent_files), event-1-ofs);
449                         if(recent) return(recent->filename);
450         }
451         
452         return(NULL);
453 }
454
455 int blenderqread(unsigned short event, short val)
456 {
457         /* here do the general keys handling (not screen/window/space) */
458         /* return 0: do not pass on to the other queues */
459         extern int textediting;
460         extern void playback_anim();
461         ScrArea *sa;
462         Object *ob;
463         int textspace=0;
464         /* Changed str and dir size to 160, to make sure there is enough
465          * space for filenames. */
466         char dir[FILE_MAXDIR * 2], str[FILE_MAXFILE * 2];
467         char *recentfile;
468         
469         if(val==0) return 1;
470         if(event==MOUSEY || event==MOUSEX) return 1;
471         if (G.flags & G_FILE_AUTOPLAY) return 1;
472
473         if (curarea && curarea->spacetype==SPACE_TEXT) textspace= 1;
474         else if (curarea && curarea->spacetype==SPACE_SCRIPT) textspace= 1;
475
476         switch(event) {
477
478         case F1KEY:
479                 if(G.qual==0) {
480                         /* this exception because of the '?' button */
481                         if(curarea->spacetype==SPACE_INFO) {
482                                 sa= closest_bigger_area();
483                                 areawinset(sa->win);
484                         }
485                         
486                         activate_fileselect(FILE_BLENDER, "Open File", G.sce, BIF_read_file);
487                         return 0;
488                 }
489                 else if(G.qual==LR_SHIFTKEY) {
490                         activate_fileselect(FILE_LOADLIB, "Load Library", G.lib, 0);
491                         return 0;
492                 }
493                 else if(G.qual==LR_CTRLKEY) {
494                         activate_imageselect(FILE_LOADLIB, "Load Library", G.lib, 0);
495                         return 0;
496                 }
497                 break;
498         case F2KEY:
499                 if(G.qual==0) {
500                         strcpy(dir, G.sce);
501                         untitled(dir);
502                         activate_fileselect(FILE_BLENDER, "Save File", dir, BIF_write_file);
503                         return 0;
504                 }
505                 else if(G.qual==LR_CTRLKEY) {
506                         write_vrml_fs();
507                         return 0;
508                 }
509                 else if(G.qual==LR_SHIFTKEY) {
510                         write_dxf_fs();
511                         return 0;
512                 }
513                 break;
514         case F3KEY:
515                 if(G.qual==0) {
516                         BIF_save_rendered_image_fs();
517                         return 0;
518                 }
519                 else if(G.qual==LR_SHIFTKEY) {
520                         newspace(curarea, SPACE_NODE);
521                         return 0;
522                 }
523                 else if(G.qual & LR_CTRLKEY) {
524                         BIF_screendump(0);
525                 }
526                 break;
527         case F4KEY:
528                 if(G.qual==LR_SHIFTKEY) {
529
530                         memset(str, 0, 16);
531                         ob= OBACT;
532                         if(ob) strcpy(str, ob->id.name);
533
534                         activate_fileselect(FILE_MAIN, "Data Select", str, NULL);
535                         return 0;
536                 }
537                 else if(G.qual==LR_CTRLKEY) {
538
539                         memset(str, 0, 16);
540                         ob= OBACT;
541                         if(ob) strcpy(str, ob->id.name);
542
543                         activate_imageselect(FILE_MAIN, "Data Select", str, 0);
544                         return 0;
545                 }
546                 else if(G.qual==0) {
547                         extern_set_butspace(event, 1);
548                 }
549                 break;
550         case F5KEY:
551                 if(G.qual==LR_SHIFTKEY) {
552                         newspace(curarea, SPACE_VIEW3D);
553                         return 0;
554                 }
555                 else if(G.qual==0) {
556                         extern_set_butspace(event, 1);
557                 }
558                 break;
559         case F6KEY:
560                 if(G.qual==LR_SHIFTKEY) {
561                         newspace(curarea, SPACE_IPO);
562                         return 0;
563                 }
564                 else if(G.qual==0) {
565                         extern_set_butspace(event, 1);
566                 }
567                 break;
568         case F7KEY:
569                 if(G.qual==LR_SHIFTKEY) {
570                         newspace(curarea, SPACE_BUTS);
571                         return 0;
572                 }
573                 else if(G.qual==0) {
574                         extern_set_butspace(event, 1);
575                 }
576                 break;
577         case F8KEY:
578                 if(G.qual==LR_SHIFTKEY) {
579                         newspace(curarea, SPACE_SEQ);
580                         return 0;
581                 }
582                 else if(G.qual==0) {
583                         extern_set_butspace(event, 1);
584                 }
585                 break;
586         case F9KEY:
587                 if(G.qual==LR_SHIFTKEY) {
588                         newspace(curarea, SPACE_OOPS);
589                         return 0;
590                 }
591                 else if(G.qual==(LR_SHIFTKEY|LR_ALTKEY)) {
592                         newspace(curarea, SPACE_OOPS+256);
593                         return 0;
594                 }
595                 else if(G.qual==0) {
596                         extern_set_butspace(event, 1);
597                 }
598                 break;
599         case F10KEY:
600                 if(G.qual==LR_SHIFTKEY) {
601                         newspace(curarea, SPACE_IMAGE);
602                         return 0;
603                 }
604                 else if(G.qual==0) {
605                         extern_set_butspace(event, 1);
606                 }
607                 break;
608         case F11KEY:
609                 if(G.qual==LR_SHIFTKEY) {
610                         newspace(curarea, SPACE_TEXT);
611                         return 0;
612                 }
613                 else if (G.qual==LR_CTRLKEY) {
614                         playback_anim();
615                 }
616                 else if(G.qual==0) {
617                         BIF_toggle_render_display();
618                         return 0;
619                 }
620                 break;
621         case F12KEY:
622                 if(G.qual==LR_SHIFTKEY) {
623                         newspace(curarea, SPACE_ACTION);
624                         return 0;
625                 }
626                 else if (G.qual==(LR_SHIFTKEY|LR_CTRLKEY)) {
627                         newspace(curarea, SPACE_NLA);
628                         return 0;
629                 }
630                 else if (G.qual==LR_CTRLKEY) {
631                         BIF_do_render(1);
632                 }
633                 else {
634                         /* ctrl/alt + f12 should render too, for some macs have f12 assigned to cd eject */
635                         BIF_do_render(0);
636                 }
637                 return 0;
638                 break;
639         
640         case WHEELUPMOUSE:
641                 if(G.qual==LR_ALTKEY || G.qual==LR_COMMANDKEY) {
642                         if(CFRA>1) {
643                                 CFRA--;
644                                 update_for_newframe();
645                         }
646                         return 0;
647                 }
648                 break;
649         case WHEELDOWNMOUSE:
650                 if(G.qual==LR_ALTKEY || G.qual==LR_COMMANDKEY) {
651                         CFRA++;
652                         update_for_newframe();
653                         return 0;
654                 }
655                 break;
656                 
657         case LEFTARROWKEY:
658         case DOWNARROWKEY:
659                 if(textediting==0 && textspace==0) {
660
661 #if 0
662 //#ifdef _WIN32 // FULLSCREEN
663                         if(event==DOWNARROWKEY){
664                                 if (G.qual==LR_ALTKEY)
665                                         mainwindow_toggle_fullscreen(0);
666                                 else if(G.qual==0)
667                                         CFRA-= G.scene->jumpframe;
668                         }
669 #else
670                         if((event==DOWNARROWKEY)&&(G.qual==0))
671                                 CFRA-= G.scene->jumpframe;
672 #endif
673                         else if((event==LEFTARROWKEY)&&(G.qual==0))
674                                 CFRA--;
675                         
676                         if(G.qual==LR_SHIFTKEY)
677                                 CFRA= PSFRA;
678                         if(CFRA<1) CFRA=1;
679         
680                         update_for_newframe();
681                         return 0;
682                 }
683                 break;
684
685         case RIGHTARROWKEY:
686         case UPARROWKEY:
687                 if(textediting==0 && textspace==0) {
688
689 #if 0
690 //#ifdef _WIN32 // FULLSCREEN
691                         if(event==UPARROWKEY){ 
692                                 if(G.qual==LR_ALTKEY)
693                                         mainwindow_toggle_fullscreen(1);
694                                 else if(G.qual==0)
695                                         CFRA+= G.scene->jumpframe;
696                         }
697 #else
698                         if((event==UPARROWKEY)&&(G.qual==0))
699                                 CFRA+= G.scene->jumpframe;
700 #endif
701                         else if((event==RIGHTARROWKEY)&&(G.qual==0))
702                                 CFRA++;
703
704                         if(G.qual==LR_SHIFTKEY)
705                                 CFRA= PEFRA;
706                         
707                         update_for_newframe();
708                 }
709                 break;
710
711         case ESCKEY:
712                 sound_stop_all_sounds();        // whats this?
713                 
714                 /* stop playback on ESC always */
715                 rem_screenhandler(G.curscreen, SCREEN_HANDLER_ANIM);
716                 audiostream_stop();
717                 BKE_ptcache_set_continue_physics(0);
718                 allqueue(REDRAWALL, 0);
719                 
720                 break;
721         case TABKEY:
722                 if(G.qual==0) {
723                         if(textspace==0) {
724                                 if(curarea->spacetype==SPACE_IPO)
725                                         set_editflag_editipo();
726                                 else if(curarea->spacetype==SPACE_SEQ)
727                                         enter_meta();
728                                 else if(curarea->spacetype==SPACE_NODE)
729                                         return 1;
730                                 else if(G.vd) {
731                                         /* also when Alt-E */
732                                         if(G.obedit==NULL) {
733                                                 enter_editmode(EM_WAITCURSOR);
734                                                 if(G.obedit) BIF_undo_push("Original"); // here, because all over code enter_editmode is abused
735                                         }
736                                         else
737                                                 exit_editmode(EM_FREEDATA|EM_FREEUNDO|EM_WAITCURSOR); // freedata, and undo
738                                 }
739                                 return 0;
740                         }
741                 }
742                 else if(G.qual==LR_CTRLKEY){
743                         Object *ob= OBACT;
744                         if(ob) {
745                                 if(ob->type==OB_ARMATURE) {
746                                         if(ob->flag & OB_POSEMODE) exit_posemode();
747                                         else enter_posemode();
748                                 }
749                                 else if(ob->type==OB_MESH) {
750                                         if(ob==G.obedit) EM_selectmode_menu();
751                                         else if(G.f & G_PARTICLEEDIT)
752                                                 PE_selectbrush_menu();
753                                         else if(G.f & G_SCULPTMODE)
754                                                 sculptmode_selectbrush_menu();
755                                         else set_wpaint();
756                                 }
757                         }
758                 }
759                 else if(G.qual&LR_CTRLKEY && G.qual&LR_SHIFTKEY){
760                         if(!(G.f & G_PARTICLEEDIT))
761                                 exit_paint_modes();
762                         PE_set_particle_edit();
763                 }
764                 break;
765
766         case BACKSPACEKEY:
767                 break;
768         case SPACEKEY:
769                 if (curarea && curarea->spacetype==SPACE_SEQ) {
770                         SpaceSeq *sseq= curarea->spacedata.first;
771                         if (G.qual==0 && sseq->mainb) {
772                                 play_anim(1);
773                                 return 0;
774                         }
775                 }
776                 break;
777         case AKEY:
778                 if(textediting==0 && textspace==0) {
779                         if ((G.qual==LR_ALTKEY) && (curarea && curarea->spacetype==SPACE_VIEW3D)) {
780                                 play_anim(0);
781                                 return 0;
782                         }
783                         else if ((G.qual==LR_ALTKEY) || (G.qual==(LR_ALTKEY|LR_SHIFTKEY))){
784                                 play_anim(1);
785                                 return 0;
786                         }
787                 }
788                 break;
789         case EKEY:
790                 if(G.qual==LR_ALTKEY) {
791                         if(G.vd && textspace==0) {
792                                 if(G.obedit==0) {
793                                         enter_editmode(EM_WAITCURSOR);
794                                         BIF_undo_push("Original");
795                                 }
796                                 else
797                                         exit_editmode(EM_FREEDATA|EM_FREEUNDO|EM_WAITCURSOR); // freedata, and undo
798                                 return 0;
799                         }                       
800                 }
801                 break;
802         case IKEY:
803                 if(textediting==0 && textspace==0 && !ELEM3(curarea->spacetype, SPACE_FILE, SPACE_IMASEL, SPACE_NODE)) {
804                         ob= OBACT;
805
806                         if(G.f & G_SCULPTMODE) return 1;
807                         else if(G.qual==LR_ALTKEY) {
808                                 common_deletekey();
809                                 return 0;
810                         }
811                         else if(G.qual==0) {
812                                 common_insertkey();
813                                 return 0;
814                         }
815                 }
816                 break;
817         case JKEY:
818                 if(textediting==0 && textspace==0) {
819                         if (G.qual==0) {
820                                 BIF_swap_render_rects();
821                                 return 0;
822                         }
823                 }
824                 break;
825
826         case NKEY:
827                 if(textediting==0 && textspace==0) {
828                         if(G.qual & LR_CTRLKEY);
829                         else if(G.qual==0 || (G.qual & LR_SHIFTKEY)) {
830                                 if(curarea->spacetype==SPACE_VIEW3D);           // is new panel, in view3d queue
831                                 else if(curarea->spacetype==SPACE_IPO);                 // is new panel, in ipo queue
832                                 else if(curarea->spacetype==SPACE_IMAGE);                       // is new panel, in ipo queue
833                                 else if(curarea->spacetype==SPACE_ACTION);                      // is own queue
834                                 else if(curarea->spacetype==SPACE_NLA);                 // is new panel
835                                 else if(curarea->spacetype==SPACE_SEQ);                 // is new panel
836                                 else {
837                                         clever_numbuts();
838                                         return 0;
839                                 }
840                         }
841                 }
842                 break;
843                 
844         case OKEY:
845                 if(textediting==0) {
846                         if(G.qual==LR_CTRLKEY) {
847                                 recentfile = recent_filelist();
848                                 if(recentfile) {
849                                         BIF_read_file(recentfile);
850                                 }
851                                 return 0;
852                         }
853                 }
854                 break;
855                 
856         case SKEY:
857                 if(G.obedit==NULL) {
858                         if(G.qual==LR_CTRLKEY) {
859                                 strcpy(dir, G.sce);
860                                 if (untitled(dir)) {
861                                         activate_fileselect(FILE_BLENDER, "Save File", dir, BIF_write_file);
862                                 } else {
863                                         BIF_write_file(dir);
864                                         free_filesel_spec(dir);
865                                 }
866                                 return 0;
867                         }
868                 }
869                 break;
870         
871         case TKEY:
872                 if (G.qual==(LR_SHIFTKEY|LR_ALTKEY|LR_CTRLKEY)) {
873                         Object *ob = OBACT;
874                         int event = pupmenu(ob?"Time%t|draw|recalc ob|recalc data":"Time%t|draw");
875                         int a;
876                         double delta, stime;
877
878                         if (event < 0) return 0; /* cancelled by user */
879
880                         waitcursor(1);
881                         
882                         stime= PIL_check_seconds_timer();
883                         for(a=0; a<100000; a++) {
884                                 if (event==1) {
885                                         scrarea_do_windraw(curarea);
886                                 } else if (event==2) {
887                                         ob->recalc |= OB_RECALC_OB;
888                                         object_handle_update(ob);
889                                 } else if (event==3) {
890                                         ob->recalc |= OB_RECALC_DATA;
891                                         object_handle_update(ob);
892                                 }
893
894                                 delta= PIL_check_seconds_timer()-stime;
895                                 if (delta>5.0) break;
896                         }
897                         
898                         waitcursor(0);
899                         notice("%8.6f s/op - %6.2f ops/s - %d iterations", delta/a, a/delta, a);
900                         return 0;
901                 }
902                 else if(G.qual==(LR_ALTKEY|LR_CTRLKEY)) {
903                         int a;
904                         int event= pupmenu("10 Timer%t|draw|draw+swap|undo");
905                         if(event>0) {
906                                 double stime= PIL_check_seconds_timer();
907                                 char tmpstr[128];
908                                 int time;
909
910                                 waitcursor(1);
911                                 
912                                 for(a=0; a<10; a++) {
913                                         if (event==1) {
914                                                 scrarea_do_windraw(curarea);
915                                         } else if (event==2) {
916                                                 scrarea_do_windraw(curarea);
917                                                 screen_swapbuffers();
918                                         }
919                                         else if(event==3) {
920                                                 BIF_undo();
921                                                 BIF_redo();
922                                         }
923                                 }
924                         
925                                 time= (int) ((PIL_check_seconds_timer()-stime)*1000);
926                                 
927                                 if(event==1) sprintf(tmpstr, "draw %%t|%d ms", time);
928                                 if(event==2) sprintf(tmpstr, "d+sw %%t|%d ms", time);
929                                 if(event==3) sprintf(tmpstr, "undo %%t|%d ms", time);
930                         
931                                 waitcursor(0);
932                                 pupmenu(tmpstr);
933
934                         }
935                         return 0;
936                 }
937                 break;
938                                 
939         case UKEY:
940                 if(textediting==0) {
941                         if(G.qual==LR_CTRLKEY) {
942                                 if(okee("Save user defaults")) {
943                                         BIF_write_homefile();
944                                 }
945                                 return 0;
946                         }
947                         else if(G.qual==LR_ALTKEY) {
948                                 if(curarea->spacetype!=SPACE_TEXT) {
949                                         BIF_undo_menu();
950                                         return 0;
951                                 }
952                         }
953                 }
954                 break;
955                 
956         case WKEY:
957                 if(textediting==0) {
958                         if(G.qual==LR_CTRLKEY) {
959                                 strcpy(dir, G.sce);
960                                 if (untitled(dir)) {
961                                         activate_fileselect(FILE_BLENDER, "Save File", dir, BIF_write_file);
962                                 } else {
963                                         BIF_write_file(dir);
964                                         free_filesel_spec(dir);
965                                 }
966                                 return 0;
967                         }
968                         /* Python specials? ;)
969                         else if(G.qual==LR_ALTKEY) {
970                                 write_videoscape_fs();
971                                 return 0;
972                         }*/ 
973                 }
974                 break;
975                 
976         case XKEY:
977                 if(textspace==0 && textediting==0) {
978                         if(G.qual==LR_CTRLKEY) {
979                                 if(okee("Erase all")) {
980                                         if( BIF_read_homefile(0)==0) error("No file ~/.B.blend");
981                                         
982                                         /* Reset lights
983                                          * This isn't done when reading userdef, do it now
984                                          *  */
985                                         GPU_default_lights();
986                                 }
987                                 return 0;
988                         }
989                 }
990                 break;
991         case YKEY:      // redo alternative
992                 if(textspace==0) {
993                         if(G.qual==LR_CTRLKEY) {
994                                 BIF_redo(); 
995                                 return 0;
996                         }
997                 }
998                 break;
999         case ZKEY:      // undo
1000                 if(textspace==0) {
1001                         if(G.qual & (LR_CTRLKEY|LR_COMMANDKEY)) { // all combos with ctrl/commandkey are accepted
1002                                 if ELEM(G.qual, LR_CTRLKEY, LR_COMMANDKEY) BIF_undo();
1003                                 else BIF_redo(); // all combos with ctrl is redo
1004                                 return 0;
1005                         }
1006                 }
1007                 break; 
1008         }
1009         
1010         return 1;
1011 }
1012
1013 /* eof */