BPython - first step for better integration of Python in Blender:
[blender.git] / source / blender / src / toets.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version. The Blender
10  * Foundation also sells licenses for use in proprietary software under
11  * the Blender License.  See http://www.blender.org/BL/ for information
12  * about this.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22  *
23  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24  * All rights reserved.
25  *
26  * The Original Code is: all of this file.
27  *
28  * Contributor(s): none yet.
29  *
30  * ***** END GPL/BL DUAL LICENSE BLOCK *****
31
32  *
33  *
34  * General blender hot keys (toets = dutch), special hotkeys are in space.c
35  *
36  */
37
38 #include <string.h>
39 #include <math.h>
40
41 #ifdef HAVE_CONFIG_H
42 #include <config.h>
43 #endif
44
45 #ifdef WIN32
46 #include "BLI_winstuff.h"
47 #endif
48
49 #include "MEM_guardedalloc.h"
50
51 #include "PIL_time.h"
52
53 #include "nla.h"        /* Only for the #ifdef flag - To be removed later */
54
55 #include "BLI_blenlib.h"
56 #include "BLI_arithb.h"
57
58 #include "DNA_object_types.h"
59 #include "DNA_screen_types.h"
60 #include "DNA_space_types.h"
61 #include "DNA_view3d_types.h"
62
63 #include "BKE_utildefines.h"
64 #include "BKE_global.h"
65 #include "BKE_anim.h"
66 #include "BKE_scene.h"
67 #include "BKE_ipo.h"
68 #include "BKE_action.h"
69 #include "BKE_ika.h"
70 #include "BKE_key.h"
71
72 #include "BIF_interface.h"
73 #include "BIF_screen.h"
74 #include "BIF_space.h"
75 #include "BIF_butspace.h"
76 #include "BIF_renderwin.h"
77 #include "BIF_toolbox.h"
78 #include "BIF_toets.h"
79 #include "BIF_editseq.h"
80 #include "BIF_editsound.h"
81 #include "BIF_poseobject.h"
82 #include "BIF_usiblender.h"
83
84 #include "BDR_vpaint.h"
85 #include "BDR_editobject.h"
86 #include "BDR_editface.h"
87
88 #include "BSE_filesel.h"        /* For activate_fileselect */
89 #include "BSE_drawview.h"       /* For play_anim */
90 #include "BSE_view.h"
91 #include "BSE_edit.h"
92 #include "BSE_editipo.h"
93 #include "BSE_headerbuttons.h"
94
95 #include "blendef.h"
96 #include "render.h"
97
98 #include "IMB_imbuf.h"
99 #include "IMB_imbuf_types.h"
100
101 #include "mydevice.h"
102
103 #include "BIF_poseobject.h"
104
105 /* only used in toets.c */
106 /* this function doesn't really belong here */
107 /* ripped from render module */
108 void schrijfplaatje(char *name);
109
110
111 void write_imag(char *name)
112 {
113         /* from file select */
114         char str[256];
115
116         strcpy(str, name);
117         BLI_convertstringcode(str, G.sce, G.scene->r.cfra);
118
119         if(saveover(str)) {
120                 if(BLI_testextensie(str,".blend")) {
121                         error("Wrong filename");
122                         return;
123                 }
124                 waitcursor(1); /* from screen.c */
125                 schrijfplaatje(str);
126                 strcpy(G.ima, name);
127                 waitcursor(0);
128         }
129 }
130
131
132 /* From matrix.h: it's really a [4][4]! */
133 /* originally in initrender... maybe add fileControl thingy? */
134
135 /* should be called write_image(char *name) :-) */
136 void schrijfplaatje(char *name)
137 {
138         struct ImBuf *ibuf=0;
139         unsigned int *temprect=0;
140         char str[FILE_MAXDIR+FILE_MAXFILE];
141
142         /* has RGBA been set? If so: use alpha channel for color zero */
143         IMB_alpha_to_col0(FALSE);
144
145         if(R.r.planes == 32) {
146                 /* everything with less than 50 % alpha -> col 0 */
147                 if(R.r.alphamode == R_ALPHAKEY) IMB_alpha_to_col0(2);
148                 /* only when 0 alpha -> col 0 */
149                 else IMB_alpha_to_col0(1);
150         }
151
152         /* Seems to me this is also superfluous.... */
153         if (R.r.imtype==R_FTYPE) {
154                 strcpy(str, R.r.ftype);
155                 BLI_convertstringcode(str, G.sce, G.scene->r.cfra);
156
157                 ibuf = IMB_loadiffname(str, IB_test);
158                 if(ibuf) {
159                         ibuf->x = R.rectx;
160                         ibuf->y = R.recty;
161                 }
162                 else {
163                         error("Can't find filetype");
164                         G.afbreek= 1;
165                         return;
166                 }
167                 /* setdither(2); */
168         }
169
170         if(ibuf == 0) {
171                 ibuf= IMB_allocImBuf(R.rectx, R.recty, R.r.planes, 0, 0);
172         }
173
174         if(ibuf) {
175                 ibuf->rect= (unsigned int *) R.rectot;
176
177                 if(R.r.planes == 8) IMB_cspace(ibuf, rgb_to_bw);
178
179                 if(R.r.imtype== R_IRIS) {
180                         ibuf->ftype= IMAGIC;
181                 }
182                 else if(R.r.imtype==R_IRIZ) {
183                         ibuf->ftype= IMAGIC;
184                         if (ibuf->zbuf == 0) {
185                                 if (R.rectz) {
186                                         ibuf->zbuf = (int *)R.rectz;
187                                 }
188                                 else printf("no zbuf\n");
189                         }
190                 }
191                 else if(R.r.imtype==R_PNG) {
192                         ibuf->ftype= PNG;
193                 }
194                 else if((R.r.imtype==R_TARGA) || (R.r.imtype==R_PNG)) {
195                         ibuf->ftype= TGA;
196                 }
197                 else if(R.r.imtype==R_RAWTGA) {
198                         ibuf->ftype= RAWTGA;
199                 }
200                 else if(R.r.imtype==R_HAMX) {
201                         /* make copy */
202                         temprect= MEM_dupallocN(R.rectot);
203                         ibuf->ftype= AN_hamx;
204                 }
205                 else if(ELEM5(R.r.imtype, R_MOVIE, R_AVICODEC, R_AVIRAW, R_AVIJPEG, R_JPEG90)) {
206                         if(R.r.quality < 10) R.r.quality= 90;
207
208                         if(R.r.mode & R_FIELDS) ibuf->ftype= JPG_VID|R.r.quality;
209                         else ibuf->ftype= JPG|R.r.quality;
210                 }
211         
212                 RE_make_existing_file(name);
213
214                 if(IMB_saveiff(ibuf, name, IB_rect | IB_zbuf)==0) {
215                         perror(name);
216                         G.afbreek= 1;
217                 }
218
219                 IMB_freeImBuf(ibuf);
220
221                 if (R.r.imtype==R_HAMX) {
222                         MEM_freeN(R.rectot);
223                         R.rectot= temprect;
224                 }
225         }
226         else {
227                 G.afbreek= 1;
228         }
229 }
230
231
232
233 /* ------------------------------------------------------------------------- */
234
235 static int is_an_active_object(void *ob) {
236         Base *base;
237         
238         for (base= FIRSTBASE; base; base= base->next)
239                 if (base->object == ob)
240                         return 1;
241         
242         return 0;
243 }
244
245 void persptoetsen(unsigned short event)
246 {
247         static Object *oldcamera=0;
248         float phi, si, q1[4], vec[3];
249         static int perspo=1;
250         
251         if(event==PADENTER) {
252                 if (G.qual == LR_SHIFTKEY) {
253                         view3d_set_1_to_1_viewborder(G.vd);
254                 } else {
255                         if (G.vd->persp==2) {
256                                 G.vd->camzoom= 0.0;
257                         } else {
258                                 G.vd->dist= 10.0;
259                         }
260                 }
261         }
262         else if((G.qual & (LR_SHIFTKEY | LR_CTRLKEY)) && (event != PAD0)) {
263                 if(event==PAD0) {
264                         /* G.vd->persp= 3; */
265                 }
266                 else if(event==PAD7) {
267                         G.vd->viewquat[0]= 0.0;
268                         G.vd->viewquat[1]= -1.0;
269                         G.vd->viewquat[2]= 0.0;
270                         G.vd->viewquat[3]= 0.0;
271                         G.vd->view= 7;
272                         if(G.vd->persp>=2) G.vd->persp= perspo;
273                 }
274                 else if(event==PAD1) {
275                         G.vd->viewquat[0]= 0.0;
276                         G.vd->viewquat[1]= 0.0;
277                         G.vd->viewquat[2]= (float)-cos(M_PI/4.0);
278                         G.vd->viewquat[3]= (float)-cos(M_PI/4.0);
279                         G.vd->view=1;
280                         if(G.vd->persp>=2) G.vd->persp= perspo;
281                 }
282                 else if(event==PAD3) {
283                         G.vd->viewquat[0]= 0.5;
284                         G.vd->viewquat[1]= -0.5;
285                         G.vd->viewquat[2]= 0.5;
286                         G.vd->viewquat[3]= 0.5;
287                         G.vd->view=3;
288                         if(G.vd->persp>=2) G.vd->persp= perspo;
289                 }
290                 else if(event==PADMINUS) {
291                         /* this min and max is also in viewmove() */
292                         if(G.vd->persp==2) {
293                                         G.vd->camzoom-= 10;
294                                         if(G.vd->camzoom<-30) G.vd->camzoom= -30;
295                                 }
296                         else if(G.vd->dist<10.0*G.vd->far) G.vd->dist*=1.2f;
297                 }
298                 else if(event==PADPLUSKEY) {
299                         if(G.vd->persp==2) {
300                                         G.vd->camzoom+= 10;
301                                         if(G.vd->camzoom>300) G.vd->camzoom= 300;
302                         }
303                         else if(G.vd->dist> 0.001*G.vd->grid) G.vd->dist*=.83333f;
304                 }
305                 else {
306
307                         initgrabz(0.0, 0.0, 0.0);
308                         
309                         if(event==PAD6) window_to_3d(vec, -32, 0);
310                         else if(event==PAD4) window_to_3d(vec, 32, 0);
311                         else if(event==PAD8) window_to_3d(vec, 0, -25);
312                         else if(event==PAD2) window_to_3d(vec, 0, 25);
313                         G.vd->ofs[0]+= vec[0];
314                         G.vd->ofs[1]+= vec[1];
315                         G.vd->ofs[2]+= vec[2];
316                 }
317         }
318         else {
319
320                 if(event==PAD7) {
321                         G.vd->viewquat[0]= 1.0;
322                         G.vd->viewquat[1]= 0.0;
323                         G.vd->viewquat[2]= 0.0;
324                         G.vd->viewquat[3]= 0.0;
325                         G.vd->view=7;
326                         if(G.vd->persp>=2) G.vd->persp= perspo;
327                 }
328                 else if(event==PAD1) {
329                         G.vd->viewquat[0]= (float)cos(M_PI/4.0);
330                         G.vd->viewquat[1]= (float)-sin(M_PI/4.0);
331                         G.vd->viewquat[2]= 0.0;
332                         G.vd->viewquat[3]= 0.0;
333                         G.vd->view=1;
334                         if(G.vd->persp>=2) G.vd->persp= perspo;
335                 }
336                 else if(event==PAD3) {
337                         G.vd->viewquat[0]= 0.5;
338                         G.vd->viewquat[1]= -0.5;
339                         G.vd->viewquat[2]= -0.5;
340                         G.vd->viewquat[3]= -0.5;
341                         G.vd->view=3;
342                         if(G.vd->persp>=2) G.vd->persp= perspo;
343                 }
344                 else if(event==PADMINUS) {
345                         /* this min and max is also in viewmove() */
346                         if(G.vd->persp==2) {
347                                 G.vd->camzoom= MAX2(-30, G.vd->camzoom-5);
348                         }
349                         else if(G.vd->dist<10.0*G.vd->far) G.vd->dist*=1.2f;
350                 }
351                 else if(event==PADPLUSKEY) {
352                         if(G.vd->persp==2) {
353                                 G.vd->camzoom= MIN2(300, G.vd->camzoom+5);
354                         }
355                         else if(G.vd->dist> 0.001*G.vd->grid) G.vd->dist*=.83333f;
356                 }
357                 else if(event==PAD5) {
358                         if(G.vd->persp==1) G.vd->persp=0;
359                         else G.vd->persp=1;
360                 }
361                 else if(event==PAD0) {
362                         if(G.qual==LR_ALTKEY) {
363                                 if(oldcamera && is_an_active_object(oldcamera)) {
364                                         G.vd->camera= oldcamera;
365                                 }
366                                 
367                                 handle_view3d_lock();
368                         }
369                         else if(BASACT) {
370                                 if(G.qual==LR_CTRLKEY) {
371                                         if(G.vd->camera != OBACT) {
372                                                 if(G.vd->camera && G.vd->camera->type==OB_CAMERA)
373                                                         oldcamera= G.vd->camera;
374                                                 
375                                                 G.vd->camera= OBACT;
376                                                 handle_view3d_lock();
377                                         }
378                                 }
379                                 else if(G.vd->camera==0 && OBACT->type==OB_CAMERA) {
380                                         G.vd->camera= OBACT;
381                                         handle_view3d_lock();
382                                 }
383                         }
384                         if(G.vd->camera==0) {
385                                 G.vd->camera= scene_find_camera(G.scene);
386                                 handle_view3d_lock();
387                         }
388                         
389                         if(G.vd->camera) {
390                                 G.vd->persp= 2;
391                                 G.vd->view= 0;
392                                 if(G.qual & LR_SHIFTKEY) {
393                                         void setcameratoview3d(void);   // view.c
394                                         setcameratoview3d();
395                                 }                               
396                         }
397                 }
398                 else if(event==PAD9) {
399                         countall();
400                         do_all_ipos();
401                         do_all_keys();
402                         do_all_actions();
403                         do_all_ikas();
404
405                         reset_slowparents();    /* editobject.c */
406                 }
407                 else if(G.vd->persp<2) {
408                         if(event==PAD4 || event==PAD6) {
409                                 /* z-axis */
410                                 phi= (float)(M_PI/24.0);
411                                 if(event==PAD6) phi= -phi;
412                                 si= (float)sin(phi);
413                                 q1[0]= (float)cos(phi);
414                                 q1[1]= q1[2]= 0.0;
415                                 q1[3]= si;
416                                 QuatMul(G.vd->viewquat, G.vd->viewquat, q1);
417                                 G.vd->view= 0;
418                         }
419                         if(event==PAD2 || event==PAD8) {
420                                 
421                                 /* horizontal axis */
422                                 VECCOPY(q1+1, G.vd->viewinv[0]);
423                                 
424                                 Normalise(q1+1);
425                                 phi= (float)(M_PI/24.0);
426                                 if(event==PAD2) phi= -phi;
427                                 si= (float)sin(phi);
428                                 q1[0]= (float)cos(phi);
429                                 q1[1]*= si;
430                                 q1[2]*= si;
431                                 q1[3]*= si;
432                                 QuatMul(G.vd->viewquat, G.vd->viewquat, q1);
433                                 G.vd->view= 0;
434                         }
435                 }
436
437                 if(G.vd->persp<2) perspo= G.vd->persp;
438         }
439         scrarea_queue_redraw(curarea);
440 }
441
442 int untitled(char * name)
443 {
444         if (G.save_over == 0 ) {
445                 char * c= BLI_last_slash(name);
446                 
447                 if (c)
448                         strcpy(&c[1], "untitled.blend");
449                 else
450                         strcpy(name, "untitled.blend");
451                         
452                 return(TRUE);
453         }
454         
455         return(FALSE);
456 }
457
458 int save_image_filesel_str(char *str)
459 {
460         switch(G.scene->r.imtype) {
461         case R_PNG:
462                 strcpy(str, "SAVE PNG"); return 1;
463         case R_TARGA:
464                 strcpy(str, "SAVE TARGA"); return 1;
465         case R_RAWTGA:
466                 strcpy(str, "SAVE RAW TARGA"); return 1;
467         case R_IRIS:
468                 strcpy(str, "SAVE IRIS"); return 1;
469         case R_IRIZ:
470                 strcpy(str, "SAVE IRIS"); return 1;
471         case R_HAMX:
472                 strcpy(str, "SAVE HAMX"); return 1;
473         case R_FTYPE:
474                 strcpy(str, "SAVE FTYPE"); return 1;
475         case R_JPEG90:
476                 strcpy(str, "SAVE JPEG"); return 1;
477         default:
478                 strcpy(str, "SAVE IMAGE"); return 0;
479         }       
480 }
481
482 void BIF_save_rendered_image(void)
483 {
484         if(!R.rectot) {
485                 error("No image rendered");
486         } else {
487                 char dir[FILE_MAXDIR * 2], str[FILE_MAXFILE * 2];
488
489                 if(G.ima[0]==0) {
490                         strcpy(dir, G.sce);
491                         BLI_splitdirstring(dir, str);
492                         strcpy(G.ima, dir);
493                 }
494                 
495                 R.r.imtype= G.scene->r.imtype;
496                 R.r.quality= G.scene->r.quality;
497                 R.r.planes= G.scene->r.planes;
498         
499                 if (!save_image_filesel_str(str)) {
500                         error("Select an image type in DisplayButtons(F10)");
501                 } else {
502                         activate_fileselect(FILE_SPECIAL, str, G.ima, write_imag);
503                 }
504         }
505 }
506
507 int blenderqread(unsigned short event, short val)
508 {
509         /* here do the general keys handling (not screen/window/space) */
510         /* return 0: do not pass on to the other queues */
511         extern int textediting;
512         ScrArea *sa;
513         Object *ob;
514         int textspace=0;
515         /* Changed str and dir size to 160, to make sure there is enough
516          * space for filenames. */
517         char dir[FILE_MAXDIR * 2], str[FILE_MAXFILE * 2];
518         
519         if(val==0) return 1;
520         if(event==MOUSEY || event==MOUSEX) return 1;
521         if (G.flags & G_FLAGS_AUTOPLAY) return 1;
522
523         if (curarea && curarea->spacetype==SPACE_TEXT) textspace= 1;
524         else if (curarea && curarea->spacetype==SPACE_SCRIPT) textspace= 1;
525
526         switch(event) {
527
528         case F1KEY:
529                 if(G.qual==0) {
530                         /* this exception because of the '?' button */
531                         if(curarea->spacetype==SPACE_INFO) {
532                                 sa= closest_bigger_area();
533                                 areawinset(sa->win);
534                         }
535                         
536                         activate_fileselect(FILE_BLENDER, "LOAD FILE", G.sce, BIF_read_file);
537                         return 0;
538                 }
539                 else if(G.qual==LR_SHIFTKEY) {
540                         activate_fileselect(FILE_LOADLIB, "LOAD LIBRARY", G.lib, 0);
541                         return 0;
542                 }
543                 break;
544         case F2KEY:
545                 if(G.qual==0) {
546                         strcpy(dir, G.sce);
547                         untitled(dir);
548                         activate_fileselect(FILE_BLENDER, "SAVE FILE", dir, BIF_write_file);
549                         return 0;
550                 }
551                 else if(G.qual==LR_CTRLKEY) {
552                         write_vrml_fs();
553                         return 0;
554                 }
555                 else if(G.qual==LR_SHIFTKEY) {
556                         write_dxf_fs();
557                         return 0;
558                 }
559                 break;
560         case F3KEY:
561                 if(G.qual==0) {
562                         BIF_save_rendered_image();
563                         return 0;
564                 }
565                 else if(G.qual & LR_CTRLKEY) {
566                         /* all alt+ctrl+shift combos are needed here... */
567                         BIF_screendump();
568                 }
569                 break;
570         case F4KEY:
571                 if(G.qual==LR_SHIFTKEY) {
572
573                         memset(str, 0, 16);
574                         ob= OBACT;
575                         if(ob) strcpy(str, ob->id.name);
576
577                         activate_fileselect(FILE_MAIN, "DATA SELECT", str, 0);
578                         return 0;
579                 }
580                 else if(G.qual==0) {
581                         extern_set_butspace(event);
582                 }
583                 break;
584         case F5KEY:
585                 if(G.qual==LR_SHIFTKEY) {
586                         newspace(curarea, SPACE_VIEW3D);
587                         return 0;
588                 }
589                 else if(G.qual==0) {
590                         extern_set_butspace(event);
591                 }
592                 break;
593         case F6KEY:
594                 if(G.qual==LR_SHIFTKEY) {
595                         newspace(curarea, SPACE_IPO);
596                         return 0;
597                 }
598                 else if(G.qual==0) {
599                         extern_set_butspace(event);
600                 }
601                 break;
602         case F7KEY:
603                 if(G.qual==LR_SHIFTKEY) {
604                         newspace(curarea, SPACE_BUTS);
605                         return 0;
606                 }
607                 else if(G.qual==0) {
608                         extern_set_butspace(event);
609                 }
610                 break;
611         case F8KEY:
612                 if(G.qual==LR_SHIFTKEY) {
613                         newspace(curarea, SPACE_SEQ);
614                         return 0;
615                 }
616                 else if(G.qual==0) {
617                         extern_set_butspace(event);
618                 }
619                 break;
620         case F9KEY:
621                 if(G.qual==LR_SHIFTKEY) {
622                         newspace(curarea, SPACE_OOPS);
623                         return 0;
624                 }
625                 else if(G.qual==0) {
626                         extern_set_butspace(event);
627                 }
628                 break;
629         case F10KEY:
630                 if(G.qual==LR_SHIFTKEY) {
631                         newspace(curarea, SPACE_IMAGE);
632                         return 0;
633                 }
634                 else if(G.qual==0) {
635                         extern_set_butspace(event);
636                 }
637                 break;
638         case F11KEY:
639                 if(G.qual==LR_SHIFTKEY) {
640                         newspace(curarea, SPACE_TEXT);
641                         return 0;
642                 }
643                 else if(G.qual==0) {
644                         BIF_toggle_render_display();
645                         return 0;
646                 }
647                 break;
648         case F12KEY:
649                 if(G.qual==LR_SHIFTKEY) {
650                         newspace(curarea, SPACE_ACTION);
651                         return 0;
652                 }
653                 else if (G.qual==(LR_SHIFTKEY|LR_CTRLKEY)) {
654                         newspace(curarea, SPACE_NLA);
655                         return 0;
656                 }
657                 else {
658                         /* ctrl/alt + f12 should render too, for some macs have f12 assigned to cd eject */
659                         BIF_do_render(0);
660                 }
661                 return 0;
662                 break;
663         
664         case LEFTARROWKEY:
665         case DOWNARROWKEY:
666                 if(textediting==0 && textspace==0) {
667
668 #ifdef _WIN32   // FULLSCREEN
669                         if(event==DOWNARROWKEY){
670                                 if (G.qual==LR_ALTKEY)
671                                         mainwindow_toggle_fullscreen(0);
672                                 else if(G.qual==0)
673                                         CFRA-= 10;
674                         }
675 #else
676                         if((event==DOWNARROWKEY)&&(G.qual==0))
677                                 CFRA-= 10;
678 #endif
679                         else if((event==LEFTARROWKEY)&&(G.qual==0))
680                                 CFRA--;
681                         
682                         if(G.qual==LR_SHIFTKEY)
683                                 CFRA= SFRA;
684                         if(CFRA<1) CFRA=1;
685         
686                         update_for_newframe();
687                         return 0;
688                 }
689                 break;
690
691         case RIGHTARROWKEY:
692         case UPARROWKEY:
693                 if(textediting==0 && textspace==0) {
694
695 #ifdef _WIN32   // FULLSCREEN
696                         if(event==UPARROWKEY){ 
697                                 if(G.qual==LR_ALTKEY)
698                                         mainwindow_toggle_fullscreen(1);
699                                 else if(G.qual==0)
700                                         CFRA+= 10;
701                         }
702 #else
703                         if((event==UPARROWKEY)&&(G.qual==0))
704                                 CFRA+= 10;
705 #endif
706                         else if((event==RIGHTARROWKEY)&&(G.qual==0))
707                                 CFRA++;
708
709                         if(G.qual==LR_SHIFTKEY)
710                                 CFRA= EFRA;
711                         
712                         update_for_newframe();
713                 }
714                 break;
715
716         case ESCKEY:
717                 sound_stop_all_sounds();
718                 break;
719         case TABKEY:
720                 if(G.qual==0) {
721                         if(textspace==0) {
722                                 if(curarea->spacetype==SPACE_IPO)
723                                         set_editflag_editipo();
724                                 else if(curarea->spacetype==SPACE_SEQ)
725                                         enter_meta();
726                                 else if(G.vd) {
727                                         /* also when Alt-E */
728                                         if(G.obedit==0)
729                                                 enter_editmode();
730                                         else
731                                                 exit_editmode(1);
732                                 }
733                                 return 0;
734                         }
735                 }
736                 else if(G.qual==LR_CTRLKEY){
737                         if(G.obpose)
738                                 exit_posemode(1);
739                         else
740                                 enter_posemode();
741                         allqueue(REDRAWHEADERS, 0);     
742                         allqueue(REDRAWBUTSALL, 0);     
743                 }
744                 else if(G.qual==LR_SHIFTKEY) {
745                         if(G.obedit)
746                                 exit_editmode(1);
747                         if(G.f & G_FACESELECT)
748                                 set_faceselect();
749                         if(G.f & G_VERTEXPAINT)
750                                 set_vpaint();
751                         if(G.f & G_WEIGHTPAINT)
752                                 set_wpaint();
753                         if(G.obpose)
754                                 exit_posemode(1);
755                 }
756                 break;
757
758         case BACKSPACEKEY:
759                 break;
760
761         case AKEY:
762                 if(textediting==0 && textspace==0) {
763                         if(G.qual==(LR_SHIFTKEY|LR_ALTKEY)){
764                                 play_anim(1);
765                                 return 0;
766                         }
767                         else if(G.qual==LR_ALTKEY) {
768                                 play_anim(0);
769                                 return 0;
770                         }
771                 }
772                 break;
773         case EKEY:
774                 if(G.qual==LR_ALTKEY) {
775                         if(G.vd && textspace==0) {
776                                 if(G.obedit==0)
777                                         enter_editmode();
778                                 else
779                                         exit_editmode(1);
780                                 return 0;
781                         }                       
782                 }
783                 break;
784         case IKEY:
785                 if(textediting==0 && textspace==0 && curarea->spacetype!=SPACE_FILE && curarea->spacetype!=SPACE_IMASEL) {
786                         if(G.qual==0) {
787                                 common_insertkey();
788                                 return 0;
789                         }
790                 }
791                 break;
792         case JKEY:
793                 if(textediting==0 && textspace==0) {
794                         if(R.rectot && G.qual==0) {
795                                 BIF_swap_render_rects();
796                                 return 0;
797                         }
798                 }
799                 break;
800
801         case NKEY:
802                 if(textediting==0 && textspace==0) {
803                         if(G.qual & LR_CTRLKEY);
804                         else if(G.qual==0 || (G.qual & LR_SHIFTKEY)) {
805                                 if(curarea->spacetype==SPACE_VIEW3D);           // is new panel, in view3d queue
806                                 else if(curarea->spacetype==SPACE_IPO);                 // is new panel, in ipo queue
807                                 else {
808                                         clever_numbuts();
809                                         return 0;
810                                 }
811                         }
812                 }
813                 break;
814                 
815         case OKEY:
816                 if(textediting==0) {
817                         if(G.qual==LR_CTRLKEY) {
818                                 /* There seem to be crashes here sometimes.... String
819                                  * bound overwrites? I changed dir and str sizes,
820                                  * let's see if this reoccurs. */
821                                 sprintf(str, "Open file: %s", G.sce);
822                         
823                                 if(okee(str)) {
824                                         strcpy(dir, G.sce);
825                                         BIF_read_file(dir);
826                                 }
827                                 return 0;
828                         }
829                 }
830                 break;
831                 
832         case SKEY:
833                 if(G.obpose==0 && G.obedit==0) {
834                         if(G.qual==LR_CTRLKEY) {
835                                 strcpy(dir, G.sce);
836                                 if (untitled(dir)) {
837                                         activate_fileselect(FILE_BLENDER, "SAVE FILE", dir, BIF_write_file);
838                                 } else {
839                                         BIF_write_file(dir);
840                                         free_filesel_spec(dir);
841                                 }
842                                 return 0;
843                         }
844                 }
845                 break;
846         
847         case TKEY:
848                 if (G.qual==(LR_SHIFTKEY|LR_ALTKEY|LR_CTRLKEY)) {
849                         int a;
850                         double delta, stime;
851
852                         waitcursor(1);
853                         
854                         stime= PIL_check_seconds_timer();
855                         for(a=0; a<100000; a++) {
856                                 scrarea_do_windraw(curarea);
857
858                                 delta= PIL_check_seconds_timer()-stime;
859                                 if (delta>5.0) break;
860                         }
861                         
862                         waitcursor(0);
863                         notice("FPS: %f (%d iterations)", a/delta, a);
864                         return 0;
865                 }
866                 else if(G.qual==(LR_ALTKEY|LR_CTRLKEY)) {
867                         int a;
868                         int event= pupmenu("10 Timer%t|draw|draw+swap");
869                         if(event>0) {
870                                 double stime= PIL_check_seconds_timer();
871                                 char tmpstr[128];
872                                 int time;
873
874                                 printf("start timer\n");
875                                 waitcursor(1);
876                                                                 
877                                 for(a=0; a<10; a++) {
878                                         scrarea_do_windraw(curarea);
879                                         if(event==2) screen_swapbuffers();
880                                 }
881                         
882                                 time= (PIL_check_seconds_timer()-stime)*1000;
883                                 
884                                 if(event==1) sprintf(tmpstr, "draw %%t|%d", time);
885                                 if(event==2) sprintf(tmpstr, "d+sw %%t|%d", time);
886                         
887                                 waitcursor(0);
888                                 pupmenu(tmpstr);
889
890                         }
891                         return 0;
892                 }
893                 break;
894                                 
895         case UKEY:
896                 if(textediting==0) {
897                         if(G.qual==LR_CTRLKEY) {
898                                 if(okee("SAVE USER DEFAULTS")) {
899                                         BIF_write_homefile();
900                                 }
901                                 return 0;
902                         }
903                 }
904                 break;
905                 
906         case WKEY:
907                 if(textediting==0) {
908                         if(G.qual==LR_CTRLKEY) {
909                                 strcpy(dir, G.sce);
910                                 if (untitled(dir)) {
911                                         activate_fileselect(FILE_BLENDER, "SAVE FILE", dir, BIF_write_file);
912                                 } else {
913                                         BIF_write_file(dir);
914                                         free_filesel_spec(dir);
915                                 }
916                                 return 0;
917                         }
918                         else if(G.qual==LR_ALTKEY) {
919                                 write_videoscape_fs();
920                         }
921                 }
922                 break;
923                 
924         case XKEY:
925                 if(textspace==0) {
926                         if(G.qual==LR_CTRLKEY) {
927                                 if(okee("ERASE ALL")) {
928                                         if( BIF_read_homefile()==0) error("No file ~/.B.blend");
929                                 }
930                                 return 0;
931                         }
932                 }
933                 break;
934         }
935         
936         return 1;
937 }
938
939 /* eof */